From 6af42d5605df2099dac405cfc16419cde94efbe3 Mon Sep 17 00:00:00 2001
From: Sebastien Binet <sebastien.binet@cern.ch>
Date: Mon, 2 Jul 2012 09:25:52 +0200
Subject: [PATCH] re-enable IO_ascii tests (McParticleTests-00-08-00)

---
 .../McParticleTests/cmt/requirements          |  43 ++
 .../McParticleTests/python/Lib.py             |  94 ++++
 .../McParticleTests/python/__init__.py        |   4 +
 .../McParticleTests/python/tests.py           | 502 ++++++++++++++++++
 .../share/GenEventProd_fragment.py            |  16 +
 .../share/iotest_ReadGenEvent_jobOptions.py   | 117 ++++
 .../iotest_ReadTruthParticles_jobOptions.py   | 112 ++++
 .../share/iotest_WriteGenEvent_jobOptions.py  | 118 ++++
 .../iotest_WriteTruthParticles_jobOptions.py  | 150 ++++++
 .../McParticleTests/share/iotest_genEvent.py  |  90 ++++
 .../share/iotest_truthParticles.py            | 104 ++++
 .../share/rbtest_ReadGenEvent_jobOptions.py   |  90 ++++
 .../McParticleTests/share/rbtest_genEvent.py  | 125 +++++
 .../share/rwtest_ascii_genEvent.py            | 173 ++++++
 .../McParticleTests/share/rwtest_genEvent.py  | 137 +++++
 .../share/rwtest_truthParticles.py            | 156 ++++++
 .../share/symlinkTest_mcAod.py                | 110 ++++
 .../share/symlinkTest_mcAod_jobOptions.py     |  88 +++
 .../McParticleTests/share/test_mcaodfilter.py |  96 ++++
 .../share/test_mcaodfilter_solution.py        | 104 ++++
 .../McParticleTests/src/McAodMcTopAna.cxx     |  87 +++
 .../McParticleTests/src/McAodMcTopAna.h       |  80 +++
 .../src/McAodMcTopAna_solution.cxx            | 312 +++++++++++
 .../src/McAodMcTopAna_solution.h              | 111 ++++
 .../McParticleTests/src/McAodSymLinkTests.cxx | 197 +++++++
 .../McParticleTests/src/McAodSymLinkTests.h   |  97 ++++
 .../components/McParticleTests_entries.cxx    |  19 +
 .../src/components/McParticleTests_load.cxx   |   3 +
 .../McParticleTests/test/McParticleTests.xml  |  95 ++++
 .../test/mc.aod.pysymlinks.ref                |   7 +
 .../McParticleTests/test/mc.aod.symlinks.ref  |  13 +
 31 files changed, 3450 insertions(+)
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/cmt/requirements
 create mode 100644 PhysicsAnalysis/TruthParticleID/McParticleTests/python/Lib.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/python/__init__.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/python/tests.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/share/GenEventProd_fragment.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_ReadGenEvent_jobOptions.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_ReadTruthParticles_jobOptions.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_WriteGenEvent_jobOptions.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_WriteTruthParticles_jobOptions.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_genEvent.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_truthParticles.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/share/rbtest_ReadGenEvent_jobOptions.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/share/rbtest_genEvent.py
 create mode 100644 PhysicsAnalysis/TruthParticleID/McParticleTests/share/rwtest_ascii_genEvent.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/share/rwtest_genEvent.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/share/rwtest_truthParticles.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/share/symlinkTest_mcAod.py
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/share/symlinkTest_mcAod_jobOptions.py
 create mode 100644 PhysicsAnalysis/TruthParticleID/McParticleTests/share/test_mcaodfilter.py
 create mode 100644 PhysicsAnalysis/TruthParticleID/McParticleTests/share/test_mcaodfilter_solution.py
 create mode 100644 PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna.cxx
 create mode 100644 PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna.h
 create mode 100644 PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna_solution.cxx
 create mode 100644 PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna_solution.h
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodSymLinkTests.cxx
 create mode 100644 PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodSymLinkTests.h
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/src/components/McParticleTests_entries.cxx
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/src/components/McParticleTests_load.cxx
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/test/McParticleTests.xml
 create mode 100644 PhysicsAnalysis/TruthParticleID/McParticleTests/test/mc.aod.pysymlinks.ref
 create mode 100755 PhysicsAnalysis/TruthParticleID/McParticleTests/test/mc.aod.symlinks.ref

diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/cmt/requirements b/PhysicsAnalysis/TruthParticleID/McParticleTests/cmt/requirements
new file mode 100755
index 000000000000..8a589ef65ab3
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/cmt/requirements
@@ -0,0 +1,43 @@
+package McParticleTests
+author  Sebastien Binet <binet@cern.ch>
+
+use AtlasPolicy 	AtlasPolicy-*
+
+private
+use GaudiInterface	GaudiInterface-*	External
+use AtlasROOT       AtlasROOT-*         External
+use AtlasCLHEP      AtlasCLHEP-*        External
+use AtlasHepMC      AtlasHepMC-*        External
+
+use StoreGate		StoreGate-*		    Control
+use AthenaPython	AthenaPython-*		Control -no_auto_imports
+use AthenaBaseComps AthenaBaseComps-*   Control
+
+use EventKernel     EventKernel-*       Event
+use NavFourMom		NavFourMom-*		Event
+use GeneratorObjects *                  Generators
+
+use McParticleEvent	McParticleEvent-*	PhysicsAnalysis/TruthParticleID
+use McParticleKernel McParticleKernel-*	PhysicsAnalysis/TruthParticleID
+use McParticleUtils McParticleUtils-*	PhysicsAnalysis/TruthParticleID
+use McParticleAlgs	McParticleAlgs-*	PhysicsAnalysis/TruthParticleID -no_auto_imports
+
+use TestPolicy          TestPolicy-*
+use AtlasOfflineRunTime AtlasOfflineRunTime-*
+
+apply_pattern validate_xml
+end_private
+
+public
+
+branches doc python share test run McParticleTests src src/components
+
+apply_pattern declare_joboptions files="*.py"
+apply_pattern declare_python_modules files="*.py"
+apply_pattern declare_runtime extras="-s=$(McParticleTests_root)/test *.ref"
+
+private
+library McParticleTests *.cxx components/*.cxx
+apply_pattern component_library
+
+end_private
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/python/Lib.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/python/Lib.py
new file mode 100644
index 000000000000..ad7195a7f590
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/python/Lib.py
@@ -0,0 +1,94 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# @file:    McParticleTests/python/Lib.py
+# @purpose: <put some purpose here>
+# @author:  Sebastien Binet <binet@cern.ch>
+
+__doc__     = 'some documentation here'
+__version__ = '$Revision: 1.1 $'
+__author__  = 'Sebastien Binet <binet@cern.ch>'
+
+import AthenaCommon.SystemOfUnits as Units
+import AthenaPython.PyAthena as PyAthena
+from AthenaPython.PyAthena import StatusCode
+
+class PyMcAodSymLinkTests (PyAthena.Alg):
+    """Simple algorithm to test symlinks from python"""
+    def __init__(self, name='PyMcAodSymLinkTests', **kw):
+        ## init base class
+        kw['name'] = name
+        super(PyMcAodSymLinkTests, self).__init__(**kw)
+
+        ## properties and data members
+        self.mcpartsName = kw.get('TruthParticles', 'SpclMC') # default value
+
+        # handle to event store
+        self.sg = None
+
+        # the types we want to retrieve with the above sg-key
+        self._types = [
+            'INavigable4MomentumCollection',
+            'DataVector<IParticle>',
+            'TruthParticleContainer',
+            ]
+        return
+
+    def initialize(self):
+        self.msg.info('==> initialize...')
+        self.sg = PyAthena.py_svc('StoreGateSvc')
+        if not self.sg:
+            self.msg.error('could not retrieve StoreGateSvc')
+            return StatusCode.Failure
+        
+        return StatusCode.Success
+
+    def execute(self):
+        _info = self.msg.info
+        _error= self.msg.error
+        _retrieve = self.sg.retrieve
+        mcparts = []
+        for cont_type in self._types:
+            cont = _retrieve(cont_type, self.mcpartsName)
+            if cont:
+                mcparts += [cont]
+            else:
+                _info('could not retrieve [%s/%s] !',
+                      cont_type, self.mcpartsName)
+                pass
+            pass
+        if not len(mcparts) == len(self._types):
+            _error('could not retrieve all containers !')
+            return StatusCode.Failure
+        
+        if not all([len(c)==len(mcparts[0]) for c in mcparts]):
+            _error('Symlinked containers do not have the same size !!')
+            for i,cont_type in enumerate(self._types):
+                _error(' %-20s: %r', cont_type, len(mcparts[i]))
+            return StatusCode.Failure
+
+        eps = 2.22045e-16
+        allgood = True
+        for i in xrange(len(mcparts[0])):
+            in_ene = mcparts[0][i].e()
+            ip_ene = mcparts[1][i].e()
+            tp_ene = mcparts[2][i].e()
+            if not( (tp_ene - ip_ene) < eps and \
+                    (tp_ene - in_ene) < eps and \
+                    (ip_ene - in_ene) < eps ):
+                _error('symlink FAILS at index [%i]',i)
+                _error(' TruthParticle::e(): %r', tp_ene)
+                _error(' IParticle::e():     %r', tp_ene)
+                _error(' INav4Mom::e():      %r', tp_ene)
+                _error(' epsilon:            %r', eps)
+                allgood=False
+            pass
+        if not allgood:
+            return StatusCode.Failure
+        _info('McAodSymLink tests OK')
+        return StatusCode.Success
+
+    def finalize(self):
+        self.msg.info('==> finalize...')
+        return StatusCode.Success
+
+    # class PyMcAodSymLinkTests
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/python/__init__.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/python/__init__.py
new file mode 100755
index 000000000000..22529f078766
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/python/__init__.py
@@ -0,0 +1,4 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# Hook for the McParticleTests python module
+
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/python/tests.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/python/tests.py
new file mode 100755
index 000000000000..cb03722a24ad
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/python/tests.py
@@ -0,0 +1,502 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+from AthenaCommon.Logging import logging
+
+def makeGenEvents( genName    = "Pythia",
+                   genProcess = "ttbar",
+                   cfgGenName = "EvGen" ):
+    """
+    Little helper method to provide a quick way to produce Mc-events
+    """
+    msg = logging.getLogger( "McParticleTests" )
+    
+    if genName.lower() not in [ "pythia", "herwig" ]:
+        raise RuntimeError, "Unknown GENERATOR [%s]" % str(genName)
+    if genProcess not in ["ttbar", "HiggsTo4Leptons", "Z+j"]:
+        raise RuntimeError, "Unknown PROCESS [%s]" % str(genProcess)
+
+    if genName.lower() == "pythia":
+        try:
+            from Pythia_i.Pythia_iConf import Pythia
+        except ImportError, err:
+            msg.warning( "Could not load module Pythia_iConf" )
+            raise err
+        
+        genAlg = Pythia(cfgGenName)
+        if genProcess == "Z+j":
+            genAlg.PythiaCommand = [ "pysubs msel 13",
+                                     "pysubs ckin 3 18.",
+                                     "pypars mstp 43 2" ]
+        elif genProcess == "ttbar":
+            # semi-leptonic decay of a ttbar pair (lepton=e,mu)
+            genAlg.PythiaCommand = [
+                "pysubs msel 6",
+                "pysubs ckin 3 18.",
+                "pypars mstp 43 2",
+                # Customisation of subprocess generation
+                "pysubs msub 81 1",    # qqbar -> QQbar
+                "pysubs msub 82 1",    # gq -> QQbar
+                "pysubs msub 96 1",    # SemiHard QCD 2 -> 2
+                # top
+                "pydat3 mdme 41 1 0", # gt
+                "pydat3 mdme 42 1 0", # gamma t
+                "pydat3 mdme 43 1 0", # Z0 t
+                "pydat3 mdme 44 1 0", # W+ d
+                "pydat3 mdme 45 1 0", # W+ s
+                "pydat3 mdme 46 1 1", # W+ b
+                "pydat3 mdme 47 1 0", # W+ b'
+                "pydat3 mdme 48 1 0", # h0 t
+                "pydat3 mdme 49 1 0", # H+ b
+                "pydat3 mdme 50 1 0", # ~chi_10 ~t_1
+                "pydat3 mdme 51 1 0", # ~chi_20 ~t_1
+                "pydat3 mdme 52 1 0", # ~chi_30 ~t_1
+                "pydat3 mdme 53 1 0", # ~chi_40 ~t_1
+                "pydat3 mdme 54 1 0", # ~g ~t_1
+                "pydat3 mdme 55 1 0", # ~gravitino ~t_1
+                # W
+                "pydat3 mdme 190 1 2", # dbar u
+                "pydat3 mdme 191 1 2", # dbar c
+                "pydat3 mdme 192 1 2", # dbar t
+                "pydat3 mdme 193 1 0", # dbar t'
+                "pydat3 mdme 194 1 2", # sbar u
+                "pydat3 mdme 195 1 2", # sbar c
+                "pydat3 mdme 196 1 2", # sbar t
+                "pydat3 mdme 197 1 0", # sbar t'
+                "pydat3 mdme 198 1 2", # bbar u
+                "pydat3 mdme 199 1 2", # bbar c
+                "pydat3 mdme 200 1 2", # bbar t
+                "pydat3 mdme 201 1 0", # bbar t'
+                "pydat3 mdme 202 1 0", # b'bar u
+                "pydat3 mdme 203 1 0", # b'bar c
+                "pydat3 mdme 204 1 0", # b'bar t
+                "pydat3 mdme 205 1 0", # b'bar t'
+                "pydat3 mdme 206 1 0", # e+ nu_e
+                "pydat3 mdme 207 1 3", # mu+ nu_mu
+                "pydat3 mdme 208 1 0", # tau+ nu_tau
+                "pydat3 mdme 209 1 0"  # tau'+ nu'_tau
+                ]
+        elif genProcess == "HiggsTo4Leptons":
+            genAlg.PythiaCommand = [
+                # Higgs mass set:
+                "pydat2 pmas 25 1 150.",
+                # Select Higgs production
+                "pysubs msel 16",
+                # Higgs Decays
+                "pydat3 mdme 210 1 0",
+                "pydat3 mdme 211 1 0",
+                "pydat3 mdme 212 1 0",
+                "pydat3 mdme 213 1 0",
+                "pydat3 mdme 214 1 0",
+                "pydat3 mdme 215 1 0",
+                "pydat3 mdme 218 1 0",
+                "pydat3 mdme 219 1 0",
+                "pydat3 mdme 220 1 0",
+                "pydat3 mdme 222 1 0",
+                "pydat3 mdme 223 1 0",
+                "pydat3 mdme 224 1 0",
+                "pydat3 mdme 225 1 1",
+                "pydat3 mdme 226 1 0",
+                
+                # Z Decays
+                "pydat3 mdme 174 1 0",
+                "pydat3 mdme 175 1 0",
+                "pydat3 mdme 176 1 0",
+                "pydat3 mdme 177 1 0",
+                "pydat3 mdme 178 1 0",
+                "pydat3 mdme 179 1 0",
+                "pydat3 mdme 180 1 0",
+                "pydat3 mdme 181 1 0",
+                "pydat3 mdme 182 1 1",
+                "pydat3 mdme 183 1 0",
+                "pydat3 mdme 184 1 1",
+                "pydat3 mdme 185 1 0",
+                "pydat3 mdme 186 1 0",
+                "pydat3 mdme 187 1 0",
+                "pydat3 mdme 188 1 0",
+                "pydat3 mdme 189 1 0"
+                ]
+        else:
+            raise RuntimeError, "Unknown PROCESS [%s]" % str(genProcess)
+
+        # Some ISR,FSR,MultipleInteractions and Hadronization parameters
+        genAlg.PythiaCommand += [
+            "pypars mstp 61 1", # ISR
+            "pypars mstp 71 1", # FSR
+            "pypars mstp 81 1", # MultInt 
+            "pypars mstp 111 1", # Hadronization
+            ]
+        
+        # Pythia listing documentation level (0-1-2)
+        genAlg.PythiaCommand += [ "pypars mstp 125 2" ]
+
+    elif genName.lower() == "herwig":
+        try:
+            from Herwig_i.Herwig_iConf  import Herwig
+        except ImportError, err:
+            msg.warning( "Could not load module Herwig_iConf" )
+            raise err
+        genAlg = Herwig(cfgGenName)
+        if genProcess == "Z+j":
+            genAlg.HerwigCommand = [
+                "iproc 2150",
+                "modpdf 10042",
+                "autpdf HWLHAPDF"
+                ]
+        
+        elif genProcess == "ttbar":
+            genAlg.HerwigCommand = ["iproc 1706","modpdf 10042",
+                                    "autpdf HWLHAPDF" ]
+        else:
+            raise RuntimeError, "Unknown PROCESS [%s]" % str(genProcess)
+        pass
+        
+    else:
+        raise RuntimeError, "Unknown GENERATOR [%s]" % str(genName)
+
+    return genAlg
+
+###------------------------------------------------
+
+def doFloatValidation( refFileName, chkFileName ):
+    """function to check 2 files, taking into account float rounding...
+    """
+    import math, os
+    from TestTools.iobench import ScOutput
+    
+    print "## float validation :"
+    print "## -ref: %s" % refFileName
+    print "## -chk: %s" % chkFileName
+
+    refFile = open( refFileName, "r" )
+    chkFile = open( chkFileName, "r" )
+
+    refFloatPrecision = refFile.readline()
+    chkFloatPrecision = chkFile.readline()
+
+    assert( refFloatPrecision == chkFloatPrecision )
+
+    fltPrecision = float( refFloatPrecision.split( "=" )[1].replace("\n","") )
+    # in a perfect world this should be: 1.19209e-07
+    fltPrecision = [ 1.19209e-06 ] * 3 + [ 1.19209e-02 ] + [ 1.5e2 ]
+    #fltPrecision = [1.5e-2, 1.5e-2, 1.5e-2, 1.5e-2, 1.5e-2]
+    #fltPrecision = [ 1. ] * 5
+    print "## float precision: %r" % fltPrecision
+    
+    out = []
+    nErrors = 0
+    for refLine,chkLine in zip( refFile, chkFile):
+        if refLine.startswith( "#" ) and refLine != chkLine:
+            out += [ "==> ERROR:",
+                     " ref: %r" % refLine,
+                     " chk: %r" % chkLine ]
+            nErrors += 1
+        if not refLine.startswith( "#" ):
+            refFloats = [ float(f.strip()) for f in refLine.split(" ") ]
+            chkFloats = [ float(f.strip()) for f in chkLine.split(" ") ]
+            if len(chkFloats) != len(refFloats):
+                out += [ "==> ERROR:",
+                         " ref: %r" % refFloats,
+                         " chk: %r" % chkFloats ]
+                nErrors += 1
+                continue
+            for i in range(len(refFloats)):
+                refFloat = refFloats[i]
+                chkFloat = chkFloats[i]
+                # delta = math.fabs(refFloat) - math.fabs(chkFloat)
+                delta = (refFloat - chkFloat)/ (float(refFloat) or 1.)
+                # delta = refFloat - chkFloat
+                if math.fabs( delta ) > fltPrecision[i]:
+                    out += ["==> ERROR:",
+                            " ref: %r" % refLine,
+                            " chk: %r" % chkLine,
+                            " del: %r %i" % (delta,i)
+                            ]
+                    nErrors += 1
+                    break
+    if nErrors == 0:
+        sc = 0
+        print "==> (float) Validation [OK]"
+    else:
+        sc = 1
+        print "## Errors during validation:",nErrors
+        print "==> (float) Validation [ERROR]"
+        
+    return ScOutput( sc,os.linesep.join(out) )
+
+
+###------------------------------------------------
+
+def doTupleValidation( refFileName, chkFileName, diffFileName = None ):
+    """function to check 2 tuple files
+    """
+    import math, os
+    from TestTools.iobench import ScOutput
+
+    if not diffFileName:
+        diffFileName = os.path.join( os.path.dirname(refFileName),
+                                     "diff."+os.path.basename(refFileName) )
+
+    print "## tuple validation :"
+    print "## -ref:  %s" % refFileName
+    print "## -chk:  %s" % chkFileName
+    print "## -diff: %s" % diffFileName
+
+    import sys
+    oldArgs = sys.argv
+    sys.argv = sys.argv[:1] + ['-b'] + sys.argv[1:]
+
+    print "## loading ROOT..."
+    import ROOT
+    print "## loading ROOT... [DONE]"
+    sys.argv = oldArgs
+    del oldArgs
+    ROOT.gROOT.SetStyle("Plain")
+    ROOT.gStyle.SetOptStat(111111)
+    
+    print "## opening tuple files..."
+    refFile = ROOT.TFile( refFileName, "READ" )
+    chkFile = ROOT.TFile( chkFileName, "READ" )
+    print "## opening tuple files... [DONE]"
+
+    refTree = refFile.Get( "hepmc" )
+    chkTree = chkFile.Get( "hepmc" )
+    nEntries = refTree.GetEntries()
+    print "## ref tuple [%i] entries" % nEntries
+    print "## chk tuple [%i] entries" % chkTree.GetEntries()
+    assert( nEntries == chkTree.GetEntries() )
+
+    from AthenaCommon.SystemOfUnits import MeV,GeV
+    nBins = 1000
+    xMin  = -2.*GeV
+    xMax  = +2.*GeV
+    histos = {}
+    histos['px'] = ROOT.TH1D( 'diffPx', "[diff] Px",   nBins, xMin, xMax )
+    histos['py'] = ROOT.TH1D( 'diffPy', "[diff] Py",   nBins, xMin, xMax )
+    histos['pz'] = ROOT.TH1D( 'diffPz', "[diff] Pz",   nBins, xMin, xMax )
+    histos['m' ] = ROOT.TH1D( 'diffM',  "[diff] Mass", nBins, xMin, xMax )
+    histos['e' ] = ROOT.TH1D( 'diffEne',"[diff] Ene",  nBins, xMin, xMax )
+    hKeys = histos.keys()
+    hKeys.sort()
+    
+    for iEntry in range(nEntries):
+        refTree.LoadTree(iEntry)
+        nb = refTree.GetEntry(iEntry)
+        if nb <= 0:
+            print "## Could not load [ref] entry [%i] !!" % iEntry
+            continue
+        chkTree.LoadTree(iEntry)
+        nb = chkTree.GetEntry(iEntry)
+        if nb <= 0:
+            print "## Could not load [chk] entry [%i] !!" % iEntry
+            continue
+        nParts = refTree.nParts
+        assert(nParts == chkTree.nParts)
+        diff = { 'px' : 0.,
+                 'py' : 0.,
+                 'pz' : 0.,
+                 'm'  : 0.,
+                 'e'  : 0. }
+        for iPart in range(nParts):
+            diff['px'] += ( refTree.px[iPart] - chkTree.px[iPart] )
+            diff['py'] += ( refTree.py[iPart] - chkTree.py[iPart] )
+            diff['pz'] += ( refTree.pz[iPart] - chkTree.pz[iPart] )
+            diff['m' ] += ( refTree.m[iPart]  - chkTree.m[iPart]  )
+            diff['e' ] += ( refTree.e[iPart]  - chkTree.e[iPart]  )
+        for k in diff.keys():
+            histos[k].Fill( diff[k], 1. )
+                            
+    out = []
+    nErrors = 0
+    c = ROOT.TCanvas('c_diff', 'Differences')
+    c.Divide(2,3); i = 1
+    for k in hKeys:
+        c.cd(i).SetLogy()
+        h = histos[k]
+        h.SetLineColor( ROOT.kRed )
+        h.SetLineWidth( 2 )
+        h.Draw()
+        i += 1
+        data = [ h.GetName(),
+                 h.GetMean(), h.GetRMS(),
+                 h.GetBinContent(0),
+                 h.GetBinContent(h.GetNbinsX()+1) ]
+        if math.fabs(data[1]) > .1*GeV or \
+           math.fabs(data[2]) > 1.*GeV or \
+           data[3] >= 10. or \
+           data[4] >= 10. :
+            nErrors += 1
+        outBeg = len(out)-1
+        out += [ "",
+                 "== [%s] ==" % data[0],
+                 " Mean:   %f MeV" % data[1],
+                 " RMS:    %f" % data[2],
+                 " U-flow: %f" % data[3],
+                 " O-flow: %f" % data[4]
+                 ]
+        print os.linesep.join( out[outBeg+1:len(out)] )
+        pass
+    c.Print( diffFileName.replace(".root", ".pdf"),
+             "Landscape" )
+    
+    diffRootFile = ROOT.TFile( diffFileName, "RECREATE" )
+    diffRootFile.cd()
+    for h in histos.values():
+        h.Write()
+        pass
+    diffRootFile.Close()
+    
+    if nErrors == 0:
+        sc = 0
+        print "==> (tuple) Validation [OK]"
+    else:
+        sc = 1
+        print "## Errors during validation:",nErrors
+        print "==> (tuple) Validation [ERROR]"
+        
+    return ScOutput( sc,os.linesep.join(out) )
+
+###------------------------------------------------
+
+def doMcAodTupleValidation( refFileName, chkFileName, diffFileName = None ):
+    """function to check 2 mcaod tuple files
+    """
+    import math, os
+    from TestTools.iobench import ScOutput
+
+    if not diffFileName:
+        diffFileName = os.path.join( os.path.dirname(refFileName),
+                                     "diff."+os.path.basename(refFileName) )
+
+    print "## tuple validation :"
+    print "## -ref:  %s" % refFileName
+    print "## -chk:  %s" % chkFileName
+    print "## -diff: %s" % diffFileName
+
+    import sys
+    oldArgs = sys.argv
+    sys.argv = sys.argv[:1] + ['-b'] + sys.argv[1:]
+
+    print "## loading ROOT..."
+    import ROOT
+    print "## loading ROOT... [DONE]"
+    sys.argv = oldArgs
+    del oldArgs
+    ROOT.gROOT.SetStyle("Plain")
+    ROOT.gStyle.SetOptStat(111111)
+    
+    print "## opening tuple files..."
+    refFile = ROOT.TFile( refFileName, "READ" )
+    chkFile = ROOT.TFile( chkFileName, "READ" )
+    print "## opening tuple files... [DONE]"
+
+    refTree = refFile.Get( "mcaod" )
+    chkTree = chkFile.Get( "mcaod" )
+    nEntries = refTree.GetEntries()
+    print "## ref tuple [%i] entries" % nEntries
+    print "## chk tuple [%i] entries" % chkTree.GetEntries()
+    assert( nEntries == chkTree.GetEntries() )
+
+    from AthenaCommon.SystemOfUnits import MeV,GeV
+    nBins = 1000
+    xMin  = -0.2*MeV
+    xMax  = +0.2*MeV
+    histos = {}
+    etCones = [ 'etcone%i' % i for i in [10,20,30,40,45,50,60,70] ]
+    for etCone in etCones:
+        histos[etCone] = ROOT.TH1D( etCone, "[diff] %s" % etCone,
+                                    nBins, xMin, xMax )
+    hKeys = histos.keys()
+    hKeys.sort()
+    
+    for iEntry in range(nEntries):
+        refTree.LoadTree(iEntry)
+        nb = refTree.GetEntry(iEntry)
+        if nb <= 0:
+            print "## Could not load [ref] entry [%i] !!" % iEntry
+            continue
+        chkTree.LoadTree(iEntry)
+        nb = chkTree.GetEntry(iEntry)
+        if nb <= 0:
+            print "## Could not load [chk] entry [%i] !!" % iEntry
+            continue
+        nParts = refTree.nParts
+        assert(nParts == chkTree.nParts)
+        diff = { 'etcone10' : 0.,
+                 'etcone20' : 0.,
+                 'etcone30' : 0.,
+                 'etcone40' : 0.,
+                 'etcone45' : 0.,
+                 'etcone50' : 0.,
+                 'etcone60' : 0.,
+                 'etcone70' : 0.,
+                 }
+        for iPart in range(nParts):
+            for k in diff.keys():
+                diff[k] += ( getattr(refTree,k)[iPart] -
+                             getattr(chkTree,k)[iPart] )
+        for k in diff.keys():
+            histos[k].Fill( diff[k], 1. )
+                            
+    out = []
+    nErrors = 0
+    canvas = []
+    for k in hKeys:
+        c = ROOT.TCanvas('c_diff_'+k, 'Differences [%s]' % k )
+        canvas.append( c )
+        c.cd(0)
+        h = histos[k]
+        h.SetLineColor( ROOT.kRed )
+        h.SetLineWidth( 2 )
+        h.Draw()
+        data = [ h.GetName(),
+                 h.GetMean(), h.GetRMS(),
+                 h.GetBinContent(0),
+                 h.GetBinContent(h.GetNbinsX()+1) ]
+        if math.fabs(data[1]) > .01*MeV or \
+           math.fabs(data[2]) > .05*MeV or \
+           data[3] > 1. or \
+           data[4] > 1. :
+            nErrors += 1
+        outBeg = len(out)-1
+        out += [ "",
+                 "== [%s] ==" % data[0],
+                 " Mean:   %f MeV" % data[1],
+                 " RMS:    %f" % data[2],
+                 " U-flow: %f" % data[3],
+                 " O-flow: %f" % data[4]
+                 ]
+        print os.linesep.join( out[outBeg+1:len(out)] )
+        pass
+
+    pdfFileName = diffFileName.replace(".root", '.ps' )
+    pdfOrientation = "Landscape"
+    
+    canvas[0].Print( pdfFileName + "[", pdfOrientation )
+    for c in canvas:
+        c.Print( pdfFileName, pdfOrientation )
+    canvas[0].Print( pdfFileName + "]", pdfOrientation )
+    import commands
+    sc,out = commands.getstatusoutput(
+        "ps2pdf %s %s" % ( pdfFileName,
+                           pdfFileName.replace( ".ps", ".pdf" ) )
+        )
+    if os.path.exists( pdfFileName ): os.remove( pdfFileName )
+    
+    diffRootFile = ROOT.TFile( diffFileName, "RECREATE" )
+    diffRootFile.cd()
+    for h in histos.values():
+        h.Write()
+        pass
+    diffRootFile.Close()
+    
+    if nErrors == 0:
+        sc = 0
+        print "==> (tuple) Validation [OK]"
+    else:
+        sc = 1
+        print "## Errors during validation:",nErrors
+        print "==> (tuple) Validation [ERROR]"
+        
+    return ScOutput( sc,os.linesep.join(out) )
+
+
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/GenEventProd_fragment.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/GenEventProd_fragment.py
new file mode 100755
index 000000000000..47f13e660452
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/GenEventProd_fragment.py
@@ -0,0 +1,16 @@
+#######################################################
+# @file: McParticleTests/GenEventProd_fragment.py
+# @purpose: jobO fragment to generate a process among a list of
+#           available processes (Pythia, Herwig, ttbar, Z+jets)
+# @author: Sebastien Binet <binet@cern.ch>
+# @date: August 2006
+#######################################################
+
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+from McParticleTests.tests import makeGenEvents
+job += makeGenEvents( genName    = GENERATOR,
+                      genProcess = PROCESS,
+                      cfgGenName = "EvGen" )
+
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_ReadGenEvent_jobOptions.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_ReadGenEvent_jobOptions.py
new file mode 100755
index 000000000000..9b7f3a588b99
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_ReadGenEvent_jobOptions.py
@@ -0,0 +1,117 @@
+###############################################################
+#
+# Job options file
+#
+#==============================================================
+import AthenaCommon.AtlasUnixStandardJob
+
+#--------------------------------------------------------------
+# General Application Configuration options
+#--------------------------------------------------------------
+from AthenaCommon.AlgSequence import AlgSequence
+topSequence = AlgSequence()
+
+# get a handle on the ServiceManager
+from AthenaCommon.AppMgr import ServiceMgr as svcMgr
+
+# import message levels (INFO/ERROR/...)
+from AthenaCommon.Constants import *
+from AthenaCommon.AppMgr    import ServiceMgr as svcMgr
+from AthenaCommon.AppMgr    import theApp,AuditorSvc
+
+###############################
+# Load perf service
+###############################
+from PerfMonComps.PerfMonFlags import jobproperties
+jobproperties.PerfMonFlags.doMonitoring = True
+jobproperties.PerfMonFlags.doPersistencyMonitoring = True
+jobproperties.PerfMonFlags.OutputFile = "read.mcevt.perfmon.root"
+from PerfMonComps.JobOptCfg import PerfMonSvc
+svcMgr += PerfMonSvc( "PerfMonSvc", OutputLevel = INFO )
+
+#--------------------------------------------------------------
+# Load POOL support
+#--------------------------------------------------------------
+import AthenaPoolCnvSvc.ReadAthenaPool
+
+#--------------------------------------------------------------
+# Event related parameters
+#--------------------------------------------------------------
+if not 'EVTMAX' in dir():
+    EVTMAX = -1
+    pass
+theApp.EvtMax = EVTMAX
+
+if 'INPUT' not in dir():
+    INPUT = [ "mc.event.pool" ]
+
+svcMgr.EventSelector.InputCollections = INPUT
+
+#--------------------------------------------------------------
+# Private Application Configuration options
+#--------------------------------------------------------------
+# Load "user algorithm"
+#top algorithms to be run, and the libraries that house them
+
+####################
+# Dump the event into an ASCII file for reference comparison
+###################
+if 'DUMP' not in dir():
+    DUMP = False
+    pass
+if DUMP:
+    from McParticleTools.McParticleToolsConf import HepMcFloatWriterTool
+    from McParticleAlgs.McParticleAlgsConf   import GenEventAsciiWriter
+    topSequence += GenEventAsciiWriter(
+        McWriter = HepMcFloatWriterTool(McEvents = "GEN_EVENT",
+                                        Output   = "reaccessed.mc.event.txt"),
+        OutputLevel = INFO
+        )
+    pass
+if 'DUMPTUPLE' not in dir():
+    DUMPTUPLE = False
+    pass
+if DUMPTUPLE:
+    if not hasattr(svcMgr, 'THistSvc'):
+        svcMgr += CfgMgr.THistSvc()
+    theApp.CreateSvc += [ svcMgr.THistSvc.getFullName() ]
+    if not 'TUPLEFILENAME' in dir():
+        TUPLEFILENAME = 'reaccessed.mc.event.root'
+        pass
+    from McParticleTools.McParticleToolsConf import HepMcTupleWriterTool
+    from McParticleAlgs.McParticleAlgsConf   import GenEventTupleWriter
+    topSequence += GenEventTupleWriter(
+        McWriter = HepMcTupleWriterTool( McEvents = "GEN_EVENT",
+                                         Output   = TUPLEFILENAME ),
+        OutputLevel = INFO
+        )
+    pass
+
+#--------------------------------------------------------------
+# Output options
+#--------------------------------------------------------------
+from AthenaPoolCnvSvc.WriteAthenaPool import AthenaPoolOutputStream
+outStream = AthenaPoolOutputStream("StreamEvGen")
+outStream.ItemList  = [ "EventInfo#McEventInfo"]
+outStream.ItemList += [ "McEventCollection#GEN_EVENT" ]
+
+OUTPUT = os.path.join( os.path.dirname(INPUT[0]),
+                       "reaccessed.%s" % os.path.basename(INPUT[0]) )
+import os
+outStream.OutputFile = OUTPUT
+outStream.ForceRead = True  #force read of output data objs
+
+## tweak the default commit interval
+svcMgr.AthenaPoolCnvSvc.CommitInterval = 100
+
+#--------------------------------------------------------------
+# Set output level threshold (2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL )
+#--------------------------------------------------------------
+svcMgr.MessageSvc.defaultLimit = 4000000
+#svcMgr.MessageSvc.OutputLevel  = ERROR
+
+#==============================================================
+#
+# End of job options file
+#
+###############################################################
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_ReadTruthParticles_jobOptions.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_ReadTruthParticles_jobOptions.py
new file mode 100755
index 000000000000..aedf45e6ee1a
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_ReadTruthParticles_jobOptions.py
@@ -0,0 +1,112 @@
+###############################################################
+#
+# Job options file
+#
+#==============================================================
+
+# basic job configuration
+import AthenaCommon.AtlasUnixStandardJob
+
+# get a handle on the job main sequence
+from AthenaCommon.AlgSequence import AlgSequence
+topSequence = AlgSequence()
+
+# import message levels (INFO/ERROR/...)
+from AthenaCommon.Constants import *
+from AthenaCommon.AppMgr    import ServiceMgr as svcMgr
+from AthenaCommon.AppMgr    import theApp
+
+###############################
+# Load perf service
+###############################
+from PerfMonComps.PerfMonFlags import jobproperties
+jobproperties.PerfMonFlags.doMonitoring = True
+jobproperties.PerfMonFlags.doPersistencyMonitoring = True
+jobproperties.PerfMonFlags.OutputFile = "read.mcaod.perfmon.pmon.gz"
+from PerfMonComps.JobOptCfg import PerfMonSvc
+svcMgr += PerfMonSvc( "PerfMonSvc", OutputLevel = INFO )
+
+#--------------------------------------------------------------
+# Load POOL support
+#--------------------------------------------------------------
+import AthenaPoolCnvSvc.ReadAthenaPool
+
+#--------------------------------------------------------------
+# Event related parameters
+#--------------------------------------------------------------
+if not 'EVTMAX' in dir():
+    EVTMAX = -1
+    pass
+theApp.EvtMax = EVTMAX
+
+if not 'INPUT' in dir():
+    INPUT = [ "mc.aod.pool" ]
+svcMgr.EventSelector.InputCollections = INPUT
+
+########
+# Read the TruthParticleContainer
+# Validates some aspects of both TPContainer and McEventCollections
+#
+if 'DUMP' not in dir():
+    DUMP = False
+    pass
+if DUMP:
+    from McParticleTools.McParticleToolsConf import SpclMcValidationTool
+    from McParticleAlgs.McParticleAlgsConf import McAodValidationAlg
+    topSequence += McAodValidationAlg(
+        "McAodValidation",
+        ValidationTools = [ "SpclMcValidationTool/SpclMcValidation" ]
+        )
+    topSequence.McAodValidation += SpclMcValidationTool("SpclMcValidation")
+    topSequence.McAodValidation.SpclMcValidation.McEvents       = "GEN_EVENT"
+    topSequence.McAodValidation.SpclMcValidation.TruthParticles = "SpclMC"
+    topSequence.McAodValidation.SpclMcValidation.OutputLevel    = INFO
+
+if 'DUMPTUPLE' not in dir():
+    DUMPTUPLE = False
+    pass
+if DUMPTUPLE:
+    if not hasattr(svcMgr, 'THistSvc'):
+        svcMgr += CfgMgr.THistSvc()
+    theApp.CreateSvc += [ svcMgr.THistSvc.getFullName() ]
+    if not 'TUPLEFILENAME' in dir():
+        TUPLEFILENAME = 'reaccessed.mc.aod.root'
+        pass
+    from McParticleTools.McParticleToolsConf import McAodTupleWriterTool
+    from McParticleAlgs.McParticleAlgsConf   import McAodTupleWriter
+    topSequence += McAodTupleWriter(
+        McWriter = McAodTupleWriterTool( TruthParticles = "SpclMC",
+                                         Output         = TUPLEFILENAME ),
+        OutputLevel = DEBUG
+        )
+    pass
+   
+#--------------------------------------------------------------
+# Output options
+#--------------------------------------------------------------
+from AthenaPoolCnvSvc.WriteAthenaPool import AthenaPoolOutputStream
+outStream = AthenaPoolOutputStream("StreamAOD")
+import os
+outStream.OutputFile = os.path.join( \
+    os.path.dirname(INPUT[0]),
+    "reaccessed.%s" % os.path.basename(INPUT[0]) )
+outStream.ForceRead = True
+
+outStream.ItemList += [ "EventInfo#McEventInfo" ]
+outStream.ItemList += [ "McEventCollection#GEN_EVENT" ]
+outStream.ItemList += [ "McEventCollection#GEN_AOD" ]
+outStream.ItemList += [ "TruthParticleContainer#SpclMC" ]
+outStream.ItemList += [ "TruthEtIsolationsContainer#TruthEtIsol_GEN_EVENT" ]
+outStream.ItemList += [ "TruthEtIsolationsContainer#TruthEtIsol_GEN_AOD" ]
+
+## tweak the default commit interval
+svcMgr.AthenaPoolCnvSvc.CommitInterval = 100
+
+svcMgr.MessageSvc.defaultLimit = 4000000
+svcMgr.MessageSvc.OutputLevel  = ERROR
+
+#==============================================================
+#
+# End of job options file
+#
+###############################################################
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_WriteGenEvent_jobOptions.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_WriteGenEvent_jobOptions.py
new file mode 100755
index 000000000000..8f91f919591c
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_WriteGenEvent_jobOptions.py
@@ -0,0 +1,118 @@
+###############################################################
+#
+# Job options file
+#
+#==============================================================
+
+#--------------------------------------------------------------
+# General Application Configuration options
+#--------------------------------------------------------------
+import AthenaCommon.AtlasUnixGeneratorJob
+from AthenaCommon.AlgSequence import AlgSequence
+topSequence = AlgSequence()
+
+# import message levels (INFO/ERROR/...)
+from AthenaCommon.Constants import *
+from AthenaCommon.AppMgr    import ServiceMgr as svcMgr
+from AthenaCommon.AppMgr    import theApp,AuditorSvc
+
+#--------------------------------------------------------------
+# Private Application Configuration options
+#--------------------------------------------------------------
+
+###############################
+# Load perf service
+###############################
+from PerfMonComps.PerfMonFlags import jobproperties
+jobproperties.PerfMonFlags.doMonitoring = True
+jobproperties.PerfMonFlags.doPersistencyMonitoring = True
+jobproperties.PerfMonFlags.OutputFile = "mcevt.perfmon.pmon.gz"
+from PerfMonComps.JobOptCfg import PerfMonSvc
+svcMgr += PerfMonSvc( "PerfMonSvc", OutputLevel = INFO )
+
+#--------------------------------------------------------------
+# Event related parameters
+#--------------------------------------------------------------
+if not 'EVTMAX' in dir():
+    EVTMAX = 5
+    pass
+theApp.EvtMax = EVTMAX
+
+from AthenaServices.AthenaServicesConf import AtRndmGenSvc
+svcMgr += AtRndmGenSvc(
+    Seeds = [ "PYTHIA 4789899 989240512", "PYTHIA_INIT 820021 2347532",
+              "JIMMY 390020611 821000366", "JIMMY_INIT 820021 2347532",
+              "HERWIG 390020611 821000366", "HERWIG_INIT 820021 2347532"
+              ]
+    )
+
+####################
+# Generate the event
+####################
+if not 'GENERATOR' in dir():
+    GENERATOR = "Pythia"
+if not 'PROCESS' in dir():
+    PROCESS = "ttbar"
+from McParticleTests.tests import makeGenEvents
+topSequence += makeGenEvents( genName    = GENERATOR,
+                              genProcess = PROCESS,
+                              cfgGenName = "EvGen" )
+
+####################
+# Dump the event into an ASCII file for reference comparison
+###################
+if 'DUMP' not in dir():
+    DUMP = False
+    pass
+if DUMP:
+    from McParticleTools.McParticleToolsConf import HepMcFloatWriterTool
+    from McParticleAlgs.McParticleAlgsConf   import GenEventAsciiWriter
+    topSequence += GenEventAsciiWriter(
+        McWriter = HepMcFloatWriterTool( McEvents = "GEN_EVENT",
+                                         Output   = "mc.event.txt" ),
+        OutputLevel = INFO
+        )
+
+if 'DUMPTUPLE' not in dir():
+    DUMPTUPLE = False
+    pass
+if DUMPTUPLE:
+    if not hasattr(svcMgr, 'THistSvc'):
+        svcMgr += CfgMgr.THistSvc()
+    theApp.CreateSvc += [ svcMgr.THistSvc.getFullName() ]
+    if not 'TUPLEFILENAME' in dir():
+        TUPLEFILENAME = 'mc.event.root'
+        pass
+    from McParticleTools.McParticleToolsConf import HepMcTupleWriterTool
+    from McParticleAlgs.McParticleAlgsConf   import GenEventTupleWriter
+    topSequence += GenEventTupleWriter(
+        McWriter = HepMcTupleWriterTool( McEvents = "GEN_EVENT",
+                                         Output   = TUPLEFILENAME ),
+        OutputLevel = DEBUG
+        )
+    pass
+
+#---------------------------------------------------------------
+# Pool Persistency
+#---------------------------------------------------------------
+from AthenaPoolCnvSvc.WriteAthenaPool import AthenaPoolOutputStream
+outStream = AthenaPoolOutputStream("StreamEvGen")
+outStream.ItemList  = [ "EventInfo#McEventInfo"]
+outStream.ItemList += [ "McEventCollection#GEN_EVENT" ]
+
+if not 'OUTPUT' in dir():
+  OUTPUT = "mc.event.pool"
+  pass
+outStream.OutputFile = OUTPUT
+
+## tweak the default commit interval
+svcMgr.AthenaPoolCnvSvc.CommitInterval = 100
+
+svcMgr.MessageSvc.defaultLimit = 4000000
+svcMgr.MessageSvc.OutputLevel  = INFO
+
+#==============================================================
+#
+# End of job options file
+#
+###############################################################
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_WriteTruthParticles_jobOptions.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_WriteTruthParticles_jobOptions.py
new file mode 100755
index 000000000000..be2d18086f36
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_WriteTruthParticles_jobOptions.py
@@ -0,0 +1,150 @@
+###############################################################
+#
+# Job options file
+#
+#==============================================================
+
+#--------------------------------------------------------------
+# General Application Configuration options
+#--------------------------------------------------------------
+import AthenaCommon.AtlasUnixStandardJob
+
+from AthenaCommon.AlgSequence import AlgSequence
+topSequence = AlgSequence()
+
+# import message levels (INFO/ERROR/...)
+from AthenaCommon.Constants import *
+from AthenaCommon.AppMgr    import ServiceMgr as svcMgr
+from AthenaCommon.AppMgr    import theApp
+
+###############################
+# Load perf service
+###############################
+from PerfMonComps.PerfMonFlags import jobproperties
+jobproperties.PerfMonFlags.doMonitoring = True
+jobproperties.PerfMonFlags.doPersistencyMonitoring = True
+jobproperties.PerfMonFlags.OutputFile = "mcaod.perfmon.pmon.gz"
+from PerfMonComps.JobOptCfg import PerfMonSvc
+svcMgr += PerfMonSvc(
+    "PerfMonSvc",
+    OutputLevel  = INFO
+    )
+
+if not 'EVTMAX' in dir():
+    EVTMAX = 5
+    pass
+theApp.EvtMax = EVTMAX
+
+#--------------------------------------------------------------
+# Load POOL support
+#--------------------------------------------------------------
+import AthenaPoolCnvSvc.ReadAthenaPool
+
+if not 'INPUT' in dir():
+    INPUT = [ "mc.event.pool" ]
+svcMgr.EventSelector.InputCollections = INPUT
+
+#--------------------------------------------------------------
+# Private Application Configuration options
+#--------------------------------------------------------------
+
+#--------------------------------------------------------------
+# Event related parameters
+#--------------------------------------------------------------
+if not 'EVTMAX' in dir():
+    EVTMAX = 5
+    pass
+theApp.EvtMax = EVTMAX
+
+##########################
+# Configure McAod options
+from McParticleAlgs.McAodFlags import jobproperties as jp
+jp.McAodFlags.doTruthEtIsolations = True
+
+########
+# Create the AOD McEventCollection
+#
+from McParticleAlgs.JobOptCfg import McAodBuilder
+from McParticleTools.McParticleToolsConf import NoopFilterTool
+from McParticleTools.McParticleToolsConf import TruthParticleCnvTool
+topSequence += McAodBuilder(
+    "McAodBuilder",
+    OutputLevel = DEBUG,
+    FilterTool = NoopFilterTool(
+                   McEvents = "GEN_EVENT",
+                   DoEtIsolations = jp.McAodFlags.doTruthEtIsolations()
+                   ),
+    CnvTool = TruthParticleCnvTool(
+                   McEvents = "GEN_AOD",
+                   TruthParticlesOutput = "SpclMC",
+                   DoEtIsolations = jp.McAodFlags.doTruthEtIsolations()
+                   )
+    )
+
+########
+# Read the TruthParticleContainer
+# Validates some aspects of both TPContainer and McEventCollections
+#
+if 'DUMP' not in dir():
+    DUMP = False
+    pass
+if DUMP:
+    from McParticleTools.McParticleToolsConf import SpclMcValidationTool
+    from McParticleAlgs.McParticleAlgsConf import McAodValidationAlg
+    topSequence += McAodValidationAlg(
+        "McAodValidation",
+        ValidationTools = [ "SpclMcValidationTool/SpclMcValidation" ]
+        )
+    topSequence.McAodValidation += SpclMcValidationTool("SpclMcValidation")
+    topSequence.McAodValidation.SpclMcValidation.McEvents       = "GEN_AOD"
+    topSequence.McAodValidation.SpclMcValidation.TruthParticles = "SpclMC"
+    topSequence.McAodValidation.SpclMcValidation.OutputLevel    = INFO
+   
+if 'DUMPTUPLE' not in dir():
+    DUMPTUPLE = False
+    pass
+if DUMPTUPLE:
+    if not hasattr(svcMgr, 'THistSvc'):
+        svcMgr += CfgMgr.THistSvc()
+    theApp.CreateSvc += [ svcMgr.THistSvc.getFullName() ]
+    if not 'TUPLEFILENAME' in dir():
+        TUPLEFILENAME = 'mc.aod.root'
+        pass
+    from McParticleTools.McParticleToolsConf import McAodTupleWriterTool
+    from McParticleAlgs.McParticleAlgsConf   import McAodTupleWriter
+    topSequence += McAodTupleWriter(
+        McWriter = McAodTupleWriterTool( TruthParticles = "SpclMC",
+                                         Output         = TUPLEFILENAME ),
+        OutputLevel = DEBUG
+        )
+    pass
+   
+#---------------------------------------------------------------
+# Pool Persistency
+#---------------------------------------------------------------
+from AthenaPoolCnvSvc.WriteAthenaPool import AthenaPoolOutputStream
+outStream = AthenaPoolOutputStream("StreamAOD")
+outStream.ItemList  = [ "EventInfo#McEventInfo" ]
+outStream.ItemList += [ "McEventCollection#GEN_EVENT" ]
+outStream.ItemList += [ "McEventCollection#GEN_AOD" ]
+outStream.ItemList += [ "TruthParticleContainer#SpclMC" ]
+outStream.ItemList += [ "TruthEtIsolationsContainer#TruthEtIsol_GEN_EVENT" ]
+outStream.ItemList += [ "TruthEtIsolationsContainer#TruthEtIsol_GEN_AOD" ]
+
+if 'OUTPUT' not in dir():
+  OUTPUT = "mc.aod.pool"
+  pass
+outStream.OutputFile = OUTPUT
+outStream.ForceRead        = True  #force read of output data objs
+
+## tweak the default commit interval
+svcMgr.AthenaPoolCnvSvc.CommitInterval = 100
+
+svcMgr.MessageSvc.defaultLimit = 4000000
+svcMgr.MessageSvc.OutputLevel  = ERROR
+
+#==============================================================
+#
+# End of job options file
+#
+###############################################################
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_genEvent.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_genEvent.py
new file mode 100755
index 000000000000..12177f5ab32f
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_genEvent.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+
+import user
+import os
+import sys
+from AthenaCommon import ChapPy
+from TestTools import iobench
+
+###-----------------------------------------------------
+## For compatibility with ATN tests
+from TestTools.iobench import workDir
+
+###-----------------------------------------------------
+## Little helper to validate output of jobs
+from TestTools.iobench import doValidation
+from TestTools.iobench import ScOutput
+from TestTools.iobench import BenchSequence
+
+def timeofday():
+    from time import time
+    return int(time())
+
+uuid = "%s_%s" % (os.getpid(),timeofday())
+
+print "#"*80
+print "## testing McEventCollection I/O..."
+print "## Job uuid:",uuid
+benchSequence = BenchSequence( "McEventCollection I/O" )
+
+EVTMAX = 100
+NTIMES = 1
+
+###-----------------------------------------------------
+print "## Testing [writing]..."
+jobOptions = [
+    ChapPy.JobOptionsCmd("OUTPUT=\"%s\"" % workDir("mc.io.event.%s.pool"%uuid)),
+    ChapPy.JobOptionsCmd("DUMP=False"),
+    ChapPy.JobOptions( "McParticleTests/iotest_WriteGenEvent_jobOptions.py" ),
+    ]
+
+athena = ChapPy.Athena( jobOptions = jobOptions,
+                        #logFile = "/dev/stdout",
+                        checkLeak  = False )
+athena.EvtMax = EVTMAX
+
+bench = iobench.AthBench( athena,
+                          nTimes = NTIMES,
+                          logFile = workDir("write.%s.log" %
+                                            os.path.basename(workDir("mc.io.event.%s.pool"%uuid))) )
+
+## print "## bench:"
+## print bench.athena
+bench.run()
+
+#bench.ioStats( [ "McEventCollection#GEN_EVENT" ], "w" )
+bench.save( "iobench-genevent-%ievts.write.%slog" % (athena.EvtMax,uuid) )
+bench.stats()
+
+###-----------------------------------------------------
+
+print "\n\n"
+print "#"*80
+print "## Testing [reading]..."
+jobOptions = [
+    ChapPy.JobOptionsCmd("INPUT=[\"%s\"]"%workDir("mc.io.event.%s.pool"%uuid)),
+    ChapPy.JobOptionsCmd("DUMP=False"),
+    ChapPy.JobOptions( "McParticleTests/iotest_ReadGenEvent_jobOptions.py" ),
+    ]
+athena = ChapPy.Athena( jobOptions = jobOptions,
+                        checkLeak  = False )
+athena.EvtMax = EVTMAX
+
+bench = iobench.AthBench( athena,
+                          nTimes = NTIMES,
+                          logFile = workDir("read.%s.log" %
+                                            os.path.basename(workDir("mc.io.event.%s.pool"%uuid))) )
+#print "## bench:"
+#print bench.athena
+bench.run()
+
+#bench.ioStats( [ "McEventCollection#GEN_EVENT" ], "r" )
+#bench.ioStats( [ "McEventCollection#GEN_EVENT" ], "w" )
+bench.save( "iobench-genevent-%ievts.read.%s.log" % (athena.EvtMax,uuid) )
+bench.stats()
+
+print ""
+print "#"*80
+benchSequence.printStatus()
+print "## Bye."
+print "#"*80
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_truthParticles.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_truthParticles.py
new file mode 100755
index 000000000000..80d65c88c6f7
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/iotest_truthParticles.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+
+import user
+import os, time
+import sys
+from TestTools import iobench
+from AthenaCommon import ChapPy
+
+###-----------------------------------------------------
+## For compatibility with ATN tests
+from TestTools.iobench import workDir
+
+###-----------------------------------------------------
+## Little helper to validate output of jobs
+from TestTools.iobench import doValidation
+from TestTools.iobench import ScOutput
+from TestTools.iobench import BenchSequence
+
+EVTMAX = 100
+NTIMES = 1
+
+def timeofday():
+    from time import time
+    return int(time())
+
+uuid = "%s_%s" % (os.getpid(),timeofday())
+genEventFile = workDir("mc.event.%s.pool"%uuid)
+mcAodFile    = workDir("mc.aod.%s.pool"%uuid)
+
+print "#"*80
+print "## testing TruthParticleContainer I/O..."
+print "## Job uuid:",uuid
+benchSequence = BenchSequence( "TruthParticleContainer I/O" )
+
+###-----------------------------------------------------
+if os.path.exists(genEventFile):
+    print "## Re-using input data..."
+else:
+    print "## Preparing input data..."
+    jobOptions = [
+        ChapPy.JobOptionsCmd( "OUTPUT=\"%s\"" % genEventFile ),
+        ChapPy.JobOptionsCmd( "DUMP=False" ),
+        ChapPy.JobOptions( "McParticleTests/iotest_WriteGenEvent_jobOptions.py" ),
+        ]
+    athena = ChapPy.Athena( jobOptions = jobOptions,
+                            checkLeak  = False )
+    athena.EvtMax = EVTMAX
+    athena.run()
+    pass
+
+###-----------------------------------------------------
+print "\n\n"
+print "#"*80
+print "## Testing [writing]..."
+jobOptions = [
+    ChapPy.JobOptionsCmd( "INPUT=[\"%s\"]" % genEventFile ),
+    ChapPy.JobOptionsCmd( "OUTPUT=\"%s\""  % mcAodFile ),
+    ChapPy.JobOptionsCmd( "DUMP=False" ),
+    ChapPy.JobOptions( "McParticleTests/iotest_WriteTruthParticles_jobOptions.py" ),
+    ]
+
+athena = ChapPy.Athena( jobOptions = jobOptions,
+                        checkLeak  = False )
+athena.EvtMax = EVTMAX
+
+bench = iobench.AthBench( athena, nTimes = NTIMES,
+                          logFile = workDir("write.%s.log" %
+                                            os.path.basename(mcAodFile)) )
+bench.run()
+
+bench.ioStats( [ "McEventCollection#GEN_EVENT" ],   "r" )
+bench.ioStats( [ "TruthParticleContainer#SpclMC" ], "w" )
+bench.save( workDir("iobench-truthparticles-%ievts.write.log"%athena.EvtMax) )
+bench.stats()
+
+###-----------------------------------------------------
+print "\n\n"
+print "#"*80
+print "## Testing [reading]..."
+jobOptions = [
+    ChapPy.JobOptionsCmd( "INPUT=[\"%s\"]" % mcAodFile ),
+    ChapPy.JobOptionsCmd( "DUMP=False" ),
+    ChapPy.JobOptions( "McParticleTests/iotest_ReadTruthParticles_jobOptions.py" ),
+    ]
+athena = ChapPy.Athena( jobOptions = jobOptions,
+                        checkLeak  = False )
+athena.EvtMax = EVTMAX
+
+bench = iobench.AthBench( athena, nTimes = NTIMES,
+                          logFile = workDir("read.%s.log" %
+                                            os.path.basename(mcAodFile))  )
+bench.run()
+
+bench.ioStats( [ "McEventCollection#GEN_EVENT" ],   "r" )
+bench.ioStats( [ "TruthParticleContainer#SpclMC" ], "r" )
+bench.ioStats( [ "TruthParticleContainer#SpclMC" ], "w" )
+bench.save( workDir("iobench-truthparticles-%ievts.read.log"%athena.EvtMax) )
+bench.stats()
+
+print ""
+print "#"*80
+benchSequence.printStatus()
+print "## Bye."
+print "#"*80
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rbtest_ReadGenEvent_jobOptions.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rbtest_ReadGenEvent_jobOptions.py
new file mode 100755
index 000000000000..d80ac95c33ce
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rbtest_ReadGenEvent_jobOptions.py
@@ -0,0 +1,90 @@
+###############################################################
+#
+# Job options file
+#
+#==============================================================
+import AthenaCommon.AtlasUnixStandardJob
+
+#--------------------------------------------------------------
+# General Application Configuration options
+#--------------------------------------------------------------
+from AthenaCommon.AlgSequence import AlgSequence
+topSequence = AlgSequence()
+
+# import message levels (INFO/ERROR/...)
+from AthenaCommon.Constants import *
+from AthenaCommon.AppMgr    import ServiceMgr as svcMgr
+from AthenaCommon.AppMgr    import theApp
+
+#--------------------------------------------------------------
+# Load POOL support
+#--------------------------------------------------------------
+import AthenaPoolCnvSvc.ReadAthenaPool
+
+#--------------------------------------------------------------
+# Event related parameters
+#--------------------------------------------------------------
+if not 'EVTMAX' in dir():
+    EVTMAX = -1
+    pass
+theApp.EvtMax = EVTMAX
+
+if 'INPUT' not in dir():
+    INPUT = [ "mc.event.pool" ]
+
+# get a handle on the ServiceManager
+from AthenaCommon.AppMgr import ServiceMgr as svcMgr
+svcMgr.EventSelector.InputCollections = INPUT
+
+#--------------------------------------------------------------
+# Private Application Configuration options
+#--------------------------------------------------------------
+# Load "user algorithm"
+#top algorithms to be run, and the libraries that house them
+
+####################
+# Dump the event into an ASCII file for reference comparison
+###################
+if 'DUMP' not in dir():
+    DUMP = False
+    pass
+if DUMP:
+    from McParticleTools.McParticleToolsConf import HepMcWriterTool
+    from McParticleAlgs.McParticleAlgsConf   import GenEventAsciiWriter
+    topSequence += GenEventAsciiWriter(
+        McWriter = HepMcWriterTool( McEvents = "GEN_EVENT",
+                                    Output   = "reaccessed.mc.event.txt" ),
+        OutputLevel = INFO
+        )
+    svcMgr += CfgMgr.THistSvc()
+    pass
+
+
+#--------------------------------------------------------------
+# Output options
+#--------------------------------------------------------------
+from AthenaPoolCnvSvc.WriteAthenaPool import AthenaPoolOutputStream
+include( "ParticleBuilderOptions/McAOD_PoolCnv_jobOptions.py")
+
+outStream = AthenaPoolOutputStream("OutStream")
+outStream.ItemList  = [ "EventInfo#*"]
+outStream.ItemList += [ "McEventCollection#*" ]
+
+if 'OUTPUT' not in dir():
+    OUTPUT = os.path.join( os.path.dirname(INPUT[0]),
+                           "reaccessed.%s" % os.path.basename(INPUT[0]) )
+import os
+outStream.OutputFile = OUTPUT
+outStream.ForceRead = True  #force read of output data objs
+
+#--------------------------------------------------------------
+# Set output level threshold (2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL )
+#--------------------------------------------------------------
+svcMgr.MessageSvc.defaultLimit = 4000000
+#svcMgr.MessageSvc.OutputLevel  = ERROR
+
+#==============================================================
+#
+# End of job options file
+#
+###############################################################
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rbtest_genEvent.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rbtest_genEvent.py
new file mode 100755
index 000000000000..01d8db428ca7
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rbtest_genEvent.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python
+
+import user
+import os
+import sys
+import commands
+from AthenaCommon import ChapPy
+
+###-----------------------------------------------------
+## For compatibility with ATN tests
+from TestTools.iobench import workDir
+
+###-----------------------------------------------------
+## Little helper to validate output of jobs
+from TestTools.iobench import doValidation
+from TestTools.iobench import ScOutput
+from TestTools.iobench import BenchSequence
+
+print "#"*80
+print "## testing McEventCollection (read/back) persistency..."
+bench = BenchSequence( "McEventCollection (read/back) persistency" )
+
+###-----------------------------------------------------
+dataFilesDir = "/afs/cern.ch/atlas/offline/data/testfile"
+dataRefDir   = "/afs/cern.ch/atlas/offline/test"
+
+asciiFiles = {
+    'rel_1004'  : { 'ref' : os.path.join(dataRefDir,'mc.event.rel_1004.ref'),
+                    'chk' : workDir('mc.event.rel_1004.txt'),
+                    'in'  : os.path.join(dataFilesDir,
+                                         "q02initialprod.0001.H_2e2mu.q02dig_1004.etacut.0001_extract.pool.root") },
+    'rel_11041' : { 'ref' : os.path.join(dataRefDir,'mc.event.rel_11041.ref'),
+                    'chk' : workDir('mc.event.rel_11041.txt'),
+                    'in'  : os.path.join(dataFilesDir,
+                                         "mc11.004100.T1_McAtNLO_top.digit_test.RDO.v11000401._00001.pool.root") },
+    'rel_1204'  : { 'ref' : os.path.join(dataRefDir,'mc.event.rel_1204.ref'),
+                    'chk' : workDir('mc.event.rel_1204.txt'),
+                    'in'  : os.path.join(dataFilesDir,
+                                         "calib1_csc11.005200.T1_McAtNlo_Jimmy.digit.RDO.v12000301_tid003138._00016_extract_10evt.pool.root") },
+    }
+
+###-----------------------------------------------------
+templateJobO = """
+INPUT=['%(InputFile)s'];
+DUMP = True;
+include( 'McParticleTests/rbtest_ReadGenEvent_jobOptions.py' );
+outStream.OutputFile = '%(OutputFile)s';
+topSequence.GenEventAsciiWriter.McWriter.McEvents = 'TruthEvent';
+topSequence.GenEventAsciiWriter.McWriter.Output = '%(AsciiChk)s';
+"""
+
+if 0:
+    ###-----------------------------------------------------
+    print "\n"
+    print "#"*80
+    print "## Testing [reading 12.0.4 data]..."
+    jobOptions = [
+        ChapPy.JobOptionsCmd( templateJobO % {
+            'InputFile'  : asciiFiles['rel_1204']['in'],
+            'OutputFile' : workDir("reaccessed.mc.events_rel12.pool"),
+            'AsciiChk'   : asciiFiles['rel_1204']['chk'],
+            } )
+        ]
+    athena = ChapPy.Athena( jobOptions = jobOptions,
+                            logFile    = workDir("read.genevent.rel_1204.log"),
+                            checkLeak  = False )
+    athena.EvtMax = 10
+    athena.run()
+
+    ###-----------------------------------------------------
+    print "\n"
+    print "#"*80
+    bench += doValidation(asciiFiles,'rel_1204')
+    pass
+
+print ""
+print "#"*80
+bench.printStatus()
+print "## Bye."
+print "#"*80
+
+# ###-----------------------------------------------------
+# print "\n"
+# print "#"*80
+# print "## Testing [reading 10.0.4 data]..."
+# jobOptions = [
+#     ChapPy.JobOptionsCmd( templateJobO % {
+#     'InputFile'  : asciiFiles['rel_1004']['in'],
+#     'OutputFile' : workDir("reaccessed.mc.events_rel10.pool"),
+#     'AsciiChk'   : asciiFiles['rel_1004']['chk'],
+#     } )
+#     ]
+# athena = ChapPy.Athena( jobOptions = jobOptions,
+#                         logFile    = workDir("read.genevent.rel_1004.log"),
+#                         checkLeak  = False )
+# athena.EvtMax = 10
+# athena.run()
+
+# ###-----------------------------------------------------
+# print "\n"
+# print "#"*80
+# bench += doValidation(asciiFiles,'rel_1004')
+
+# ###-----------------------------------------------------
+# print "\n"
+# print "#"*80
+# print "## Testing [reading 11.0.41 data]..."
+# jobOptions = [
+#     ChapPy.JobOptionsCmd( templateJobO % {
+#     'InputFile'  : asciiFiles['rel_11041']['in'],
+#     'OutputFile' : workDir("reaccessed.mc.events_rel11.pool"),
+#     'AsciiChk'   : asciiFiles['rel_11041']['chk'],
+#     } )
+#     ]
+# athena = ChapPy.Athena( jobOptions = jobOptions,
+#                         logFile    = workDir("read.genevent.rel_11041.log"),
+#                         checkLeak  = False )
+# athena.EvtMax = 10
+# athena.run()
+
+# ###-----------------------------------------------------
+# print "\n"
+# print "#"*80
+# bench += doValidation(asciiFiles,'rel_11041')
+
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rwtest_ascii_genEvent.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rwtest_ascii_genEvent.py
new file mode 100644
index 000000000000..9e23072cba4f
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rwtest_ascii_genEvent.py
@@ -0,0 +1,173 @@
+#!/usr/bin/env python
+
+import user
+import os
+import sys
+import commands
+from AthenaCommon import ChapPy
+
+###-----------------------------------------------------
+## For compatibility with ATN tests
+from TestTools.iobench import workDir
+
+###-----------------------------------------------------
+## Little helper to validate output of jobs
+from TestTools.iobench import ScOutput
+from TestTools.iobench import BenchSequence
+from McParticleTests.tests import doTupleValidation
+
+print "#"*80
+print "## testing McEventCollection (read/write) persistency..."
+print "#"*80
+bench = BenchSequence( "McEventCollection (read/write) ASCII persistency" )
+
+###-----------------------------------------------------
+outFiles = {
+    'gen_pythia' : { 'ref' : workDir("mc.event.pythia.pool"),
+                     'chk' : workDir("reaccessed.mc.event.pythia.pool"), },
+    'gen_herwig' : { 'ref' : workDir("mc.event.herwig.pool"),
+                     'chk' : workDir("reaccessed.mc.event.herwig.pool"), },
+    }
+
+evtMax = 50
+
+def doReadWriteTest( genName = "pythia", evtMax = 100 ):
+    """A simple wrapper around the read/write tests..."""
+    genName = genName.lower()
+    ###-----------------------------------------------------
+    print ""
+    print "#"*80
+    print "## Testing [writing-%s]..." % genName
+    templateJobO = """
+OUTPUT='%(OutputFile)s';
+DUMPTUPLE=True;
+GENERATOR='%(Generator)s';
+TUPLEFILENAME='%(TupleFile)s';
+include( 'McParticleTests/iotest_WriteGenEvent_jobOptions.py' );
+jobproperties.PerfMonFlags.OutputFile = '%(PmonFile)s';
+"""
+    jobOptions = [
+        ChapPy.JobOptionsCmd( templateJobO % {
+        'OutputFile' : workDir("mc.event.%s.pool" % genName),
+        'Generator'  : genName.upper(),
+        'TupleFile'  : outFiles['gen_%s' % genName]['ref']\
+                       .replace(".pool",".tuple.root"),
+        'PmonFile'   : workDir("write.genevent.%s.pmon.gz" % genName),
+        } )
+        ]
+        
+    athena = ChapPy.Athena(jobOptions = jobOptions,
+                           logFile = workDir("write.genevent.%s.log"%genName),
+                           checkLeak  = False )
+    athena.EvtMax = evtMax
+    sc = athena.run()
+    if sc != 0:
+        return ScOutput(sc, "ERROR")
+    else:
+        inFile  = workDir(    "write.genevent.%s.pmon.gz"   % genName)
+        outFile = workDir("out.write.genevent.%s.pmon.root" % genName)
+        print commands.getoutput( "perfmon.py %s -o %s" % ( inFile, outFile ) )
+                                 
+    ###-----------------------------------------------------
+    print ""
+    print "#"*80
+    print "## Testing [ASCII-writing-%s (1)]..." % genName
+    templateJobO = """
+INPUT=%(InputFile)s;
+OUTPUT='%(OutputFile)s';
+DUMPTUPLE=True;
+GENERATOR='%(Generator)s';
+include( 'McParticleAlgs/GenEventAsciiWriter_jobOptions.py' );
+"""
+    jobOptions = [
+        ChapPy.JobOptionsCmd( templateJobO % {
+        'InputFile'  : [workDir("mc.event.%s.pool" % genName),],
+        'OutputFile' : workDir("mc.event.%s.1.ascii" % genName),
+        'Generator'  : genName.upper(),
+        } )
+        ]
+        
+    athena = ChapPy.Athena(jobOptions = jobOptions,
+                           logFile = workDir("write.genevent.ascii.1.%s.log"%genName),
+                           checkLeak  = False )
+    athena.EvtMax = evtMax
+    sc = athena.run()
+    if sc != 0:
+        return ScOutput(sc, "ERROR")
+                                 
+    ###-----------------------------------------------------
+    print ""
+    print "#"*80
+    print "## Testing [ASCII-writing-%s (2)]..." % genName
+    templateJobO = """
+INPUT=%(InputFile)s;
+OUTPUT='%(OutputFile)s';
+DUMPTUPLE=True;
+GENERATOR='%(Generator)s';
+include( 'McParticleAlgs/GenEventAsciiWriter_jobOptions.py' );
+"""
+    jobOptions = [
+        ChapPy.JobOptionsCmd( templateJobO % {
+        'InputFile'  : [workDir("mc.event.%s.pool" % genName),],
+        'OutputFile' : workDir("mc.event.%s.2.ascii" % genName),
+        'Generator'  : genName.upper(),
+        } )
+        ]
+        
+    athena = ChapPy.Athena(jobOptions = jobOptions,
+                           logFile = workDir("write.genevent.ascii.2.%s.log"%genName),
+                           checkLeak  = False )
+    athena.EvtMax = evtMax
+    sc = athena.run()
+    if sc != 0:
+        return ScOutput(sc, "ERROR")
+                                 
+    ###-----------------------------------------------------
+    print "\n"
+    print "#"*80
+    print "## Testing [ASCII-reading-%s]..." % genName
+    templateJobO = """
+INPUT=%(InputFiles)s;
+include( 'McAsciiEventSelector/Example_McAsciiReader_jobOptions.py' );
+"""
+    jobOptions = [
+        ChapPy.JobOptionsCmd( templateJobO % {
+        'InputFiles' : [ workDir("mc.event.%s.1.ascii" % genName),
+                         workDir("mc.event.%s.2.ascii" % genName),],
+        'TupleFile' : outFiles['gen_%s' % genName]['chk']\
+                      .replace(".pool",".tuple.root"),
+        'PmonFile'  : workDir("read.genevent.%s.pmon.gz" % genName),
+        } )
+    ]
+    athena = ChapPy.Athena( jobOptions = jobOptions,
+                            logFile  = workDir("read.genevent.%s.log"%genName),
+                            checkLeak  = False )
+    athena.EvtMax = evtMax
+    sc = athena.run()
+    if sc != 0:
+        return ScOutput(sc, "ERROR")
+
+    ###-----------------------------------------------------
+    print "\n"
+    print "#"*80
+    return ScOutput(0, "OK")
+
+###-----------------------------------------------------
+### perform all the tests
+for genName in [
+    "pythia",
+    "herwig",
+    ]:
+    try:
+        bench += doReadWriteTest( genName, evtMax )
+    except KeyboardInterrupt:
+        print "\n*** user hit Ctrl-C ! ***"
+        print "*** skipping test [%s] ***" % genName
+        continue
+    pass
+
+print ""
+print "#"*80
+bench.printStatus()
+print "## Bye."
+print "#"*80
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rwtest_genEvent.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rwtest_genEvent.py
new file mode 100755
index 000000000000..99a948ba5185
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rwtest_genEvent.py
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+
+import user
+import os
+import sys
+import commands
+from AthenaCommon import ChapPy
+
+###-----------------------------------------------------
+## For compatibility with ATN tests
+from TestTools.iobench import workDir
+
+###-----------------------------------------------------
+## Little helper to validate output of jobs
+from TestTools.iobench import ScOutput
+from TestTools.iobench import BenchSequence
+from McParticleTests.tests import doTupleValidation
+
+def timeofday():
+    from time import time
+    return int(time())
+
+uuid = "%s_%s" % (os.getpid(),timeofday())
+
+print "#"*80
+print "## testing McEventCollection (read/write) persistency..."
+print "## Job uuid:",uuid
+print "#"*80
+bench = BenchSequence( "McEventCollection (read/write) persistency" )
+
+###-----------------------------------------------------
+dataFilesDir = "/afs/cern.ch/atlas/offline/data/testfile"
+dataRefDir   = "/afs/cern.ch/atlas/offline/test"
+
+outFiles = {
+    'gen_pythia' : { 'ref' : workDir("mc.event.pythia.%s.pool"%uuid),
+                     'chk' : workDir("reaccessed.mc.event.pythia.%s.pool"%uuid), },
+    'gen_herwig' : { 'ref' : workDir("mc.event.herwig.%s.pool"%uuid),
+                     'chk' : workDir("reaccessed.mc.event.herwig.%s.pool"%uuid), },
+    }
+
+evtMax = 100
+
+def doReadWriteTest( genName = "pythia", evtMax = 100 ):
+    """A simple wrapper around the read/write tests..."""
+    genName = genName.lower()
+    ###-----------------------------------------------------
+    print ""
+    print "#"*80
+    print "## Testing [writing-%s]..." % genName
+    templateJobO = """
+OUTPUT='%(OutputFile)s';
+DUMPTUPLE=True;
+GENERATOR='%(Generator)s';
+TUPLEFILENAME='%(TupleFile)s';
+include( 'McParticleTests/iotest_WriteGenEvent_jobOptions.py' );
+jobproperties.PerfMonFlags.OutputFile = '%(PmonFile)s';
+"""
+    jobOptions = [
+        ChapPy.JobOptionsCmd( templateJobO % {
+        'OutputFile' : workDir("mc.event.%s.%s.pool" % (genName,uuid)),
+        'Generator'  : genName.upper(),
+        'TupleFile'  : outFiles['gen_%s' % genName]['ref']\
+                       .replace(".pool",".tuple.root"),
+        'PmonFile'   : workDir("write.genevent.%s.%s.pmon.gz"%(genName,uuid)),
+        } )
+        ]
+        
+    athena = ChapPy.Athena(jobOptions = jobOptions,
+                           logFile = workDir("write.genevent.%s.%s.log"%(genName,uuid)),
+                           checkLeak  = False )
+    athena.EvtMax = evtMax
+    sc = athena.run()
+    if sc != 0:
+        return ScOutput(sc, "ERROR")
+    else:
+        inFile  = workDir(    "write.genevent.%s.%s.pmon.gz"   %(genName,uuid))
+        outFile = workDir("out.write.genevent.%s.%s.pmon.root" %(genName,uuid))
+        print commands.getoutput( "perfmon.py %s -o %s" % ( inFile, outFile ) )
+                                 
+    ###-----------------------------------------------------
+    print "\n"
+    print "#"*80
+    print "## Testing [reading-%s]..." % genName
+    templateJobO = """
+INPUT=['%(InputFile)s'];
+DUMPTUPLE=True;
+TUPLEFILENAME='%(TupleFile)s';
+include( 'McParticleTests/iotest_ReadGenEvent_jobOptions.py' );
+jobproperties.PerfMonFlags.OutputFile = '%(PmonFile)s';
+"""
+    jobOptions = [
+        ChapPy.JobOptionsCmd( templateJobO % {
+        'InputFile' : workDir("mc.event.%s.%s.pool" % (genName,uuid)),
+        'TupleFile' : outFiles['gen_%s' % genName]['chk']\
+                      .replace(".pool",".tuple.root"),
+        'PmonFile'  : workDir("read.genevent.%s.%s.pmon.gz" % (genName,uuid)),
+        } )
+    ]
+    athena = ChapPy.Athena( jobOptions = jobOptions,
+                            logFile  = workDir("read.genevent.%s.%s.log"%(genName,uuid)),
+                            checkLeak  = False )
+    athena.EvtMax = evtMax
+    sc = athena.run()
+    if sc != 0:
+        return ScOutput(sc, "ERROR")
+    else:
+        inFile  = workDir(    "read.genevent.%s.%s.pmon.gz"   % (genName,uuid))
+        outFile = workDir("out.read.genevent.%s.%s.pmon.root" % (genName,uuid))
+        print commands.getoutput( "perfmon.py %s -o %s" % ( inFile, outFile ) )
+
+    ###-----------------------------------------------------
+    print "\n"
+    print "#"*80
+    return doTupleValidation(
+        outFiles['gen_%s' % genName]['ref'].replace(".pool", ".tuple.root"),
+        outFiles['gen_%s' % genName]['chk'].replace(".pool", ".tuple.root") )
+
+###-----------------------------------------------------
+### perform all the tests
+for genName in [
+    "pythia",
+    "herwig",
+    ]:
+    try:
+        bench += doReadWriteTest( genName, evtMax )
+    except KeyboardInterrupt:
+        print "\n*** user hit Ctrl-C ! ***"
+        print "*** skipping test [%s] ***" % genName
+        continue
+    pass
+
+print ""
+print "#"*80
+bench.printStatus()
+print "## Bye."
+print "#"*80
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rwtest_truthParticles.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rwtest_truthParticles.py
new file mode 100755
index 000000000000..94131780514b
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/rwtest_truthParticles.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python
+
+import user
+import commands
+import os
+import sys
+from AthenaCommon import ChapPy
+
+###-----------------------------------------------------
+## For compatibility with ATN tests
+from TestTools.iobench import workDir
+
+###-----------------------------------------------------
+## Little helper to validate output of jobs
+from TestTools.iobench import ScOutput
+from TestTools.iobench import BenchSequence
+from McParticleTests.tests import doMcAodTupleValidation
+
+def timeofday():
+    from time import time
+    return int(time())
+
+uuid = "%s_%s" % (os.getpid(),timeofday())
+
+print "#"*80
+print "## testing TruthParticleContainer (read/write) persistency..."
+print "## Job uuid:",uuid
+bench = BenchSequence( "TruthParticleContainer (read/write) persistency" )
+
+###-----------------------------------------------------
+dataFilesDir = "/afs/cern.ch/atlas/offline/data/testfile"
+dataRefDir   = "/afs/cern.ch/atlas/offline/test"
+
+asciiFiles = {
+    'w'    : { 'ref' : os.path.join(dataRefDir,"mc.aod.etisols.rel_13.ref"),
+               'chk' : workDir("mc.aod.txt"), },
+    'r'    : { 'ref' : os.path.join(dataRefDir,
+                                    "reaccessed.mc.aod.etisols.rel_13.ref"),
+               'chk' : workDir("reaccessed.mc.aod.txt"), },
+    }
+
+outFiles = {
+    'ref' : workDir( "mc.aod.%s.pool"%uuid ),
+    'chk' : workDir( "reaccessed.mc.aod.%s.pool"%uuid )
+    }
+
+evtMax = 100
+
+def doReadWriteTest( genName = "TruthParticles", evtMax = 100 ):
+    ###-----------------------------------------------------
+    print "\n"
+    print "#"*80
+    print "## Preparing input data... [%s]" % genName
+    templateJobO = """
+OUTPUT='%(OutputFile)s';
+DUMP=True;
+include( 'McParticleTests/iotest_WriteGenEvent_jobOptions.py' );
+"""
+    jobOptions = [
+        ChapPy.JobOptionsCmd( templateJobO % {
+        'OutputFile' : workDir("mc.event.%s.pool"%uuid),
+        } )
+    ]
+    athena = ChapPy.Athena( jobOptions = jobOptions,
+                            logFile    = workDir("mc.event.%s.pool.log"%uuid),
+                            checkLeak  = False )
+    athena.EvtMax = evtMax
+    sc = athena.run()
+    if sc != 0:
+        return ScOutput(sc, "ERROR")
+
+    ###-----------------------------------------------------
+    print "\n"
+    print "#"*80
+    print "## Testing [writing-%s]..." % genName
+    templateJobO = """
+INPUT=['%(InputFile)s'];
+OUTPUT= '%(OutputFile)s';
+DUMPTUPLE=True;
+TUPLEFILENAME='%(TupleFile)s';
+include( 'McParticleTests/iotest_WriteTruthParticles_jobOptions.py' );
+jobproperties.PerfMonFlags.OutputFile = '%(PmonFile)s';
+"""
+    jobOptions = [
+        ChapPy.JobOptionsCmd( templateJobO % {
+        'InputFile'  : workDir("mc.event.%s.pool"%uuid),
+        'OutputFile' : outFiles['ref'],
+        'TupleFile'  : outFiles['ref'].replace(".pool", ".tuple.root"),
+        'PmonFile'   : workDir("write.mcaod.%s.%s.perfmon.pmon.gz"%(genName,
+                                                                    uuid)),
+        } )
+    ]    
+
+    athena = ChapPy.Athena( jobOptions = jobOptions,
+                            logFile    = outFiles['ref']+".log",
+                            checkLeak  = False )
+    athena.EvtMax = evtMax
+    sc = athena.run()
+    if sc != 0:
+        return ScOutput(sc, "ERROR")
+    else:
+        inFile  = workDir(    "write.mcaod.%s.%s.perfmon.pmon.gz"%(genName,
+                                                                   uuid))
+        outFile = workDir("out.write.mcaod.%s.%s.perfmon.root"    %(genName,
+                                                                    uuid))
+        commands.getoutput( "perfmon.py %s -o %s" % ( inFile, outFile ) )
+
+    ###-----------------------------------------------------
+    print "\n"
+    print "#"*80
+    print "## Testing [reading-%s]..." % genName
+    templateJobO = """
+INPUT=['%(InputFile)s'];
+OUTPUT= '%(OutputFile)s';
+DUMPTUPLE=True;
+TUPLEFILENAME='%(TupleFile)s';
+include( 'McParticleTests/iotest_ReadTruthParticles_jobOptions.py' );
+jobproperties.PerfMonFlags.OutputFile = '%(PmonFile)s';
+"""
+    jobOptions = [
+        ChapPy.JobOptionsCmd( templateJobO % {
+          'InputFile'  : outFiles['ref'],
+          'OutputFile' : outFiles['chk'],
+          'TupleFile'  : outFiles['chk'].replace(".pool", ".tuple.root"),
+          'PmonFile'   : workDir("read.mcaod.%s.%s.perfmon.pmon.gz" %(genName,
+                                                                      uuid)),
+          } )
+    ]    
+    athena = ChapPy.Athena( jobOptions = jobOptions,
+                            logFile    = outFiles['chk']+".log",
+                            checkLeak  = False )
+    athena.EvtMax = evtMax
+    sc = athena.run()
+    if sc != 0:
+        return ScOutput(sc, "ERROR")
+    else:
+        inFile  = workDir(    "read.mcaod.%s.%s.perfmon.pmong.gz"%(genName,
+                                                                   uuid))
+        outFile = workDir("out.read.mcaod.%s.%s.perfmon.root"    %(genName,
+                                                                   uuid))
+        commands.getoutput( "perfmon.py %s -o %s" % ( inFile, outFile ) )
+
+    ###-----------------------------------------------------
+    print "\n"
+    print "#"*80
+    return doMcAodTupleValidation(
+        outFiles['ref'].replace(".pool", ".tuple.root"),
+        outFiles['chk'].replace(".pool", ".tuple.root")
+        )
+
+bench += doReadWriteTest( evtMax = evtMax )
+print ""
+print "#"*80
+bench.printStatus()
+print "## Bye."
+print "#"*80
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/symlinkTest_mcAod.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/symlinkTest_mcAod.py
new file mode 100755
index 000000000000..714737089657
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/symlinkTest_mcAod.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+
+import user
+import os
+import sys
+import commands
+from AthenaCommon import ChapPy
+
+###-----------------------------------------------------
+## For compatibility with ATN tests
+from TestTools.iobench import workDir
+
+###-----------------------------------------------------
+## Little helper to validate output of jobs
+from TestTools.iobench import doPostCheck
+from TestTools.iobench import ScOutput
+from TestTools.iobench import BenchSequence
+    
+###-----------------------------------------------------
+def installRefFiles( fileNames ):
+    for refFile in fileNames:
+        for fileName in [ refFile, workDir(refFile) ]:
+            if os.path.exists(fileName):
+                os.remove(fileName)
+        sc,out = commands.getstatusoutput( "get_files %s" % refFile )
+        if sc != 0:
+            print "## ERROR: could not retrieve [%s]" % refFile
+            print "## reason:\n",out
+            continue
+        if os.path.exists(refFile) and \
+           os.path.exists(workDir(refFile)) and \
+           os.path.samefile( refFile, workDir(refFile) ):
+            print " -%s" % workDir(refFile)
+            continue
+        sc,out = commands.getstatusoutput( "mv %s %s" % ( refFile,
+                                                          workDir(refFile) ) )
+        if sc != 0:
+            print "## ERROR: could not install [%s] into [%s]" %\
+                  ( refFile, workDir(refFile) )
+            print "## reason:\n",out
+            continue
+        else:
+            print " -%s" % workDir(refFile)
+    return
+
+print "#"*80
+print "## testing symlinks for TruthParticleContainer..."
+bench = BenchSequence( "Symlinks for TruthParticleContainer" )
+
+print "## installing reference files..."
+installRefFiles( [
+    "mc.aod.symlinks.ref",
+    "mc.aod.pysymlinks.ref",
+    ] )
+
+evtMax = 5
+
+###-----------------------------------------------------
+print "## Testing [writing]..."
+jobOptions = [
+    ChapPy.JobOptionsCmd( "OUTPUT=\"%s\"" % workDir("mc.aod.symlinks.pool") ),
+    ChapPy.JobOptions( "McParticleTests/symlinkTest_mcAod_jobOptions.py" ),
+    ]
+
+athena = ChapPy.Athena( jobOptions = jobOptions,
+                        logFile = workDir("mc.aod.symlinks.pool.log"),
+                        checkLeak  = False )
+athena.EvtMax = evtMax
+athena.run()
+
+
+###-----------------------------------------------------
+print "\n"
+print "#"*80
+bench += doPostCheck( "McAod symlinks",
+                      workDir("mc.aod.symlinks.ref"),
+                      workDir("mc.aod.symlinks.pool.log"),
+                      "grep \"^McAodSymLinkTests\"" )
+
+
+###-----------------------------------------------------
+print ""
+print "#"*80
+print "## testing py-symlinks for TruthParticleContainer..."
+print "## Testing [writing]..."
+jobOptions = [
+    ChapPy.JobOptionsCmd( "OUTPUT=\"%s\"" % workDir("mc.aod.pysymlinks.pool") ),
+    ChapPy.JobOptionsCmd( "ALGMODE='py'" ),
+    ChapPy.JobOptions( "McParticleTests/symlinkTest_mcAod_jobOptions.py" ),
+    ]
+
+athena = ChapPy.Athena( jobOptions = jobOptions,
+                        logFile = workDir("mc.aod.pysymlinks.pool.log"),
+                        checkLeak  = False )
+athena.EvtMax = evtMax
+athena.run()
+
+
+###-----------------------------------------------------
+print "\n"
+print "#"*80
+bench += doPostCheck( "McAod py-symlinks",
+                      workDir("mc.aod.pysymlinks.ref"),
+                      workDir("mc.aod.pysymlinks.pool.log"),
+                      "grep \"^Py:PyMcAodSymLinkTests\"" )
+print ""
+print "#"*80
+bench.printStatus()
+print "## Bye."
+print "#"*80
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/symlinkTest_mcAod_jobOptions.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/symlinkTest_mcAod_jobOptions.py
new file mode 100755
index 000000000000..0056b2f0294d
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/symlinkTest_mcAod_jobOptions.py
@@ -0,0 +1,88 @@
+###############################################################
+#
+# Job options file
+#
+#==============================================================
+
+#--------------------------------------------------------------
+# General Application Configuration options
+#--------------------------------------------------------------
+import AthenaCommon.AtlasUnixGeneratorJob
+
+from AthenaCommon.AlgSequence import AlgSequence
+topSequence = AlgSequence()
+
+# import message levels (INFO/ERROR/...)
+from AthenaCommon.Constants import *
+from AthenaCommon.AppMgr    import theApp
+from AthenaCommon.AppMgr    import ServiceMgr as svcMgr
+
+#--------------------------------------------------------------
+# Event related parameters
+#--------------------------------------------------------------
+if not 'EVTMAX' in dir():
+    EVTMAX = 5
+    pass
+theApp.EvtMax = EVTMAX
+
+from AthenaServices.AthenaServicesConf import AtRndmGenSvc
+svcMgr += AtRndmGenSvc(
+    Seeds = [ "PYTHIA 4789899 989240512", "PYTHIA_INIT 820021 2347532",
+              "JIMMY 390020611 821000366", "JIMMY_INIT 820021 2347532",
+              "HERWIG 390020611 821000366", "HERWIG_INIT 820021 2347532"
+              ]
+    )
+
+####################
+# Generate the event
+####################
+if not 'GENERATOR' in dir():
+    GENERATOR = "Pythia"
+if not 'PROCESS' in dir():
+    PROCESS = "ttbar"
+from McParticleTests.tests import makeGenEvents
+topSequence += makeGenEvents( genName    = GENERATOR,
+                              genProcess = PROCESS,
+                              cfgGenName = "EvGen" )
+
+########
+# Create the AOD McEventCollection
+#
+from McParticleAlgs.JobOptCfg import McAodBuilder
+topSequence += McAodBuilder()
+topSequence.McAodBuilder.DoFiltering = False
+topSequence.McAodBuilder.CnvTool.McEvents             = "GEN_EVENT"
+topSequence.McAodBuilder.CnvTool.TruthParticlesOutput = "SpclMC"
+
+if not 'ALGMODE' in dir():
+    ALGMODE='cpp'
+    pass
+if ALGMODE=='py':
+    from McParticleTests.Lib import PyMcAodSymLinkTests as McAodSymLinkTests
+else:
+    from McParticleTests.McParticleTestsConf import McAodSymLinkTests
+topSequence += McAodSymLinkTests( OutputLevel = DEBUG )
+
+#---------------------------------------------------------------
+# Pool Persistency
+#---------------------------------------------------------------
+from AthenaPoolCnvSvc.WriteAthenaPool import AthenaPoolOutputStream
+outStream = AthenaPoolOutputStream("OutStream")
+outStream.ItemList  = [ "EventInfo#*"]
+outStream.ItemList += [ "McEventCollection#GEN_EVENT" ]
+outStream.ItemList += [ "TruthParticleContainer#SpclMC" ]
+
+if 'OUTPUT' not in dir():
+  OUTPUT = "mc.aod.symlinktests.pool"
+  pass
+outStream.OutputFile = OUTPUT
+outStream.EvtConversionSvc = "AthenaPoolCnvSvc"
+outStream.ForceRead        = True  #force read of output data objs
+
+svcMgr.MessageSvc.defaultLimit = 4000000
+svcMgr.MessageSvc.OutputLevel  = ERROR
+#==============================================================
+#
+# End of job options file
+#
+###############################################################
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/test_mcaodfilter.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/test_mcaodfilter.py
new file mode 100644
index 000000000000..9fe5d0826810
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/test_mcaodfilter.py
@@ -0,0 +1,96 @@
+###############################################################
+#
+# Job options file
+#
+#==============================================================
+import AthenaCommon.AtlasUnixStandardJob
+
+#--------------------------------------------------------------
+# General Application Configuration options
+#--------------------------------------------------------------
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+# get a handle on the ServiceManager
+from AthenaCommon.AppMgr import ServiceMgr as svcMgr
+
+# import message levels (INFO/ERROR/...)
+from AthenaCommon import Constants as Units
+from AthenaCommon import Constants as Lvl
+from AthenaCommon.AppMgr    import ServiceMgr as svcMgr
+from AthenaCommon.AppMgr    import theApp,AuditorSvc
+
+#--------------------------------------------------------------
+# Load POOL support
+#--------------------------------------------------------------
+import AthenaPoolCnvSvc.ReadAthenaPool
+
+#--------------------------------------------------------------
+# Event related parameters
+#--------------------------------------------------------------
+if not 'EVTMAX' in dir():
+    EVTMAX = -1
+    pass
+theApp.EvtMax = EVTMAX
+
+if 'INPUT' not in dir():
+    INPUT = [ "mc.event.pool" ]
+
+svcMgr.EventSelector.InputCollections = INPUT
+
+#--------------------------------------------------------------
+# Private Application Configuration options
+#--------------------------------------------------------------
+# Load "user algorithm"
+#top algorithms to be run, and the libraries that house them
+
+## schedule our algorithm
+job += CfgMgr.McAod__McTopAna(
+    "mctopana",
+    McEvent = "GEN_EVENT",
+    FilteredMcEvent = "MyGEN_EVENT",
+    OutputLevel=Lvl.INFO,
+    )
+
+## output ntuple configuration
+if not hasattr(svcMgr, 'THistSvc'):
+    svcMgr += CfgMgr.THistSvc()
+    theApp.CreateSvc += [ svcMgr.THistSvc.getFullName() ]
+if not 'TUPLEFILENAME' in dir():
+    TUPLEFILENAME = 'mcaod.ttbar.root'
+    pass
+svcMgr.THistSvc.Output += [
+    "mcaod DATAFILE='%s' OPT='RECREATE'" % TUPLEFILENAME
+    ]
+
+#--------------------------------------------------------------
+# Output options
+#--------------------------------------------------------------
+from AthenaPoolCnvSvc.WriteAthenaPool import AthenaPoolOutputStream
+outStream = AthenaPoolOutputStream("StreamEvGen")
+outStream.ItemList  = [
+    "EventInfo#*",
+    "McEventCollection#MyGEN_EVENT",
+    "TruthParticleContainer#*",
+    ]
+
+OUTPUT = os.path.join( os.path.dirname(INPUT[0]),
+                       "filtered.%s" % os.path.basename(INPUT[0]) )
+import os
+outStream.OutputFile = OUTPUT
+outStream.ForceRead = True  #force read of output data objs
+
+## tweak the default commit interval
+svcMgr.AthenaPoolCnvSvc.CommitInterval = 100
+
+#--------------------------------------------------------------
+# Set output level threshold (2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL )
+#--------------------------------------------------------------
+svcMgr.MessageSvc.defaultLimit = 4000000
+#svcMgr.MessageSvc.OutputLevel  = ERROR
+
+#==============================================================
+#
+# End of job options file
+#
+###############################################################
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/share/test_mcaodfilter_solution.py b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/test_mcaodfilter_solution.py
new file mode 100644
index 000000000000..6fd4926c4318
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/share/test_mcaodfilter_solution.py
@@ -0,0 +1,104 @@
+###############################################################
+#
+# Job options file
+#
+#==============================================================
+import AthenaCommon.AtlasUnixStandardJob
+
+#--------------------------------------------------------------
+# General Application Configuration options
+#--------------------------------------------------------------
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+# get a handle on the ServiceManager
+from AthenaCommon.AppMgr import ServiceMgr as svcMgr
+
+# import message levels (INFO/ERROR/...)
+from AthenaCommon import Constants as Units
+from AthenaCommon import Constants as Lvl
+from AthenaCommon.AppMgr    import ServiceMgr as svcMgr
+from AthenaCommon.AppMgr    import theApp,AuditorSvc
+
+#--------------------------------------------------------------
+# Load POOL support
+#--------------------------------------------------------------
+import AthenaPoolCnvSvc.ReadAthenaPool
+
+#--------------------------------------------------------------
+# Event related parameters
+#--------------------------------------------------------------
+if not 'EVTMAX' in dir():
+    EVTMAX = -1
+    pass
+theApp.EvtMax = EVTMAX
+
+if 'INPUT' not in dir():
+    INPUT = [ "mc.event.pool" ]
+
+svcMgr.EventSelector.InputCollections = INPUT
+
+#--------------------------------------------------------------
+# Private Application Configuration options
+#--------------------------------------------------------------
+# Load "user algorithm"
+#top algorithms to be run, and the libraries that house them
+
+## schedule our algorithm
+cls = CfgMgr.McAod__McTopAna
+if 1:
+    cls = CfgMgr.McAod__McTopAnaSolution
+job += cls(
+    "mctopana",
+    McEvent = "GEN_EVENT",
+    FilteredMcEvent = "MyGEN_EVENT",
+    OutputLevel=Lvl.INFO,
+    )
+# Mc filtering, selects the decay vertices based on this collection of strings
+job.mctopana.FilterTool.DecayPatterns  = [
+    "6 -> 24 + 5",
+    "24 -> 1|2|3|4|5|-1|-2|-3|-4|-5 + 1|2|3|4|5",
+    ]
+
+## output ntuple configuration
+if not hasattr(svcMgr, 'THistSvc'):
+    svcMgr += CfgMgr.THistSvc()
+    theApp.CreateSvc += [ svcMgr.THistSvc.getFullName() ]
+if not 'TUPLEFILENAME' in dir():
+    TUPLEFILENAME = 'mcaod.ttbar.root'
+    pass
+svcMgr.THistSvc.Output += [
+    "mcaod DATAFILE='%s' OPT='RECREATE'" % TUPLEFILENAME
+    ]
+
+#--------------------------------------------------------------
+# Output options
+#--------------------------------------------------------------
+from AthenaPoolCnvSvc.WriteAthenaPool import AthenaPoolOutputStream
+outStream = AthenaPoolOutputStream("StreamEvGen")
+outStream.ItemList  = [
+    "EventInfo#*",
+    "McEventCollection#MyGEN_EVENT",
+    "TruthParticleContainer#*",
+    ]
+
+OUTPUT = os.path.join( os.path.dirname(INPUT[0]),
+                       "filtered.%s" % os.path.basename(INPUT[0]) )
+import os
+outStream.OutputFile = OUTPUT
+outStream.ForceRead = True  #force read of output data objs
+
+## tweak the default commit interval
+svcMgr.AthenaPoolCnvSvc.CommitInterval = 100
+
+#--------------------------------------------------------------
+# Set output level threshold (2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL )
+#--------------------------------------------------------------
+svcMgr.MessageSvc.defaultLimit = 4000000
+#svcMgr.MessageSvc.OutputLevel  = ERROR
+
+#==============================================================
+#
+# End of job options file
+#
+###############################################################
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna.cxx b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna.cxx
new file mode 100644
index 000000000000..63d9838dda23
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna.cxx
@@ -0,0 +1,87 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// McTopAna.cxx 
+// Implementation file for class McTopAna
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+
+// McParticleTests includes
+#include "McAodMcTopAna.h"
+
+// STL includes
+
+// FrameWork includes
+#include "GaudiKernel/Property.h"
+
+namespace McAod {
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+McTopAna::McTopAna( const std::string& name, 
+                    ISvcLocator* pSvcLocator ) : 
+  ::AthAlgorithm( name, pSvcLocator )
+{
+  //
+  // Property declaration
+  // 
+  //declareProperty( "Property", m_nProperty );
+
+}
+
+// Destructor
+///////////////
+McTopAna::~McTopAna()
+{}
+
+// Athena Algorithm's Hooks
+////////////////////////////
+StatusCode McTopAna::initialize()
+{
+  ATH_MSG_INFO ("Initializing " << name() << "...");
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode McTopAna::finalize()
+{
+  ATH_MSG_INFO ("Finalizing " << name() << "...");
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode McTopAna::execute()
+{  
+  ATH_MSG_DEBUG ("Executing " << name() << "...");
+
+  return StatusCode::SUCCESS;
+}
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Protected methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+} //> end namespace McAod
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna.h b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna.h
new file mode 100644
index 000000000000..b57eca08e470
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna.h
@@ -0,0 +1,80 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// McTopAna.h 
+// Header file for class McTopAna
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef MCPARTICLETESTS_MCAOD_MCTOPANA_H
+#define MCPARTICLETESTS_MCAOD_MCTOPANA_H 1
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+
+// fwd declares
+class IMcVtxFilterTool;
+
+namespace McAod {
+
+class McTopAna
+  : public ::AthAlgorithm
+{ 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+ public: 
+
+  // Copy constructor: 
+
+  /// Constructor with parameters: 
+  McTopAna( const std::string& name, ISvcLocator* pSvcLocator );
+
+  /// Destructor: 
+  virtual ~McTopAna(); 
+
+  // Assignment operator: 
+  //McTopAna &operator=(const McTopAna &alg); 
+
+  // Athena algorithm's Hooks
+  virtual StatusCode  initialize();
+  virtual StatusCode  execute();
+  virtual StatusCode  finalize();
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /////////////////////////////////////////////////////////////////// 
+  // Non-const methods: 
+  /////////////////////////////////////////////////////////////////// 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Private data: 
+  /////////////////////////////////////////////////////////////////// 
+ private: 
+
+  /// Default constructor: 
+  McTopAna();
+
+  /// Containers
+  
+
+}; 
+
+// I/O operators
+//////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+
+} //> end namespace McAod
+#endif //> !MCPARTICLETESTS_MCAOD_MCTOPANA_H
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna_solution.cxx b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna_solution.cxx
new file mode 100644
index 000000000000..f6944d67a333
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna_solution.cxx
@@ -0,0 +1,312 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// McTopAna.cxx 
+// Implementation file for class McTopAna
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+
+// McParticleTests includes
+#include "McAodMcTopAna_solution.h"
+
+// STL includes
+
+// FrameWork includes
+#include "GaudiKernel/Property.h"
+#include "GaudiKernel/ITHistSvc.h"
+#include "GaudiKernel/ServiceHandle.h"
+
+// mc tools
+#include "McParticleKernel/IMcVtxFilterTool.h"
+#include "McParticleKernel/ITruthParticleCnvTool.h"
+#include "McParticleEvent/TruthParticle.h"
+#include "McParticleEvent/TruthParticleContainer.h"
+#include "GeneratorObjects/McEventCollection.h"
+#include "HepMC/GenEvent.h"
+#include "HepMC/GenParticle.h"
+#include "HepMC/GenVertex.h"
+#include "McParticleUtils/McVtxFilter.h"
+
+#include "EventKernel/PdtPdg.h"
+
+// units
+#include "CLHEP/Units/SystemOfUnits.h"
+
+// ROOT includes
+#include "TH1F.h"
+
+namespace McAod {
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+McTopAnaSolution::McTopAnaSolution( const std::string& name, 
+                    ISvcLocator* pSvcLocator ) : 
+  ::AthAlgorithm( name, pSvcLocator ),
+  m_vtxFilter("McVtxFilterTool/McVtxFilterTool", this),
+  m_cnvTool("TruthParticleCnvTool/TruthParticleCnvTool", this),
+  m_mcEventsName ("GEN_EVENT"),
+  m_filteredMcEventsName ("MyGEN_EVENT"),
+  m_filteredMcParticlesName ("MyTruthParticles"),
+  m_h_mctop_mass(0),
+  m_h_mcwqq_mass(0),
+  m_h_mcq1_ene(0),
+  m_h_mcq2_ene(0)
+{
+  //
+  // Property declaration
+  // 
+  //declareProperty( "Property", m_nProperty );
+
+  declareProperty("FilterTool", m_vtxFilter, 
+                  "handle to the mc-vtx filter tool");
+
+  declareProperty("CnvTool", m_cnvTool, 
+                  "handle to the truthparticle cnv tool");
+
+  declareProperty("McEvent",
+                  m_mcEventsName,
+                  "input McEventCollection container name");
+
+  declareProperty("FilteredMcEvent",
+                  m_filteredMcEventsName,
+                  "output filtered McEventCollection container name");
+
+  declareProperty("FilteredMcParticles",
+                  m_filteredMcParticlesName,
+                  "output filtered TruthParticles container name");
+}
+
+// Destructor
+///////////////
+McTopAnaSolution::~McTopAnaSolution()
+{}
+
+// Athena Algorithm's Hooks
+////////////////////////////
+StatusCode McTopAnaSolution::initialize()
+{
+  ATH_MSG_INFO ("Initializing " << name() << "...");
+
+  if (!m_vtxFilter.retrieve().isSuccess()) {
+    ATH_MSG_ERROR("could not retrieve vtx filter tool");
+    return StatusCode::FAILURE;
+  } else {
+    m_vtxFilter->displayOptions();
+  }
+
+  if (!m_cnvTool.retrieve().isSuccess()) {
+    ATH_MSG_ERROR("could not retrieve truthparticle cnv tool");
+    return StatusCode::FAILURE;
+  }
+
+  // handle to THistSvc
+  ServiceHandle<ITHistSvc> hsvc("THistSvc", this->name());
+  if (!hsvc.retrieve().isSuccess()) {
+    ATH_MSG_ERROR("could not retrieve histogram svc");
+    return StatusCode::FAILURE;
+  }
+
+  // register mc-top histogram
+  m_h_mctop_mass = new TH1F("mctop_mass", "Mc Top mass",
+                            200, 0.*CLHEP::GeV, 300.*CLHEP::GeV);
+  if (!hsvc->regHist("/mcaod/McTopWb/mctop_mass", m_h_mctop_mass).isSuccess()) {
+    ATH_MSG_ERROR("could not register histogram");
+    return StatusCode::FAILURE;
+  }
+
+  // register mc-w histogram
+  m_h_mcwqq_mass = new TH1F("mcwqq_mass", "Mc W mass",
+                            100, 0.*CLHEP::GeV, 100.*CLHEP::GeV);
+  if (!hsvc->regHist("/mcaod/McTopWb/mcwqq_mass", m_h_mcwqq_mass).isSuccess()) {
+    ATH_MSG_ERROR("could not register histogram");
+    return StatusCode::FAILURE;
+  }
+
+  // register mc-q1 histogram
+  m_h_mcq1_ene = new TH1F("mcq1_ene", "Mc q1 energy",
+                            100, 0.*CLHEP::GeV, 500.*CLHEP::GeV);
+  if (!hsvc->regHist("/mcaod/McTopWb/mcq1_ene", m_h_mcq1_ene).isSuccess()) {
+    ATH_MSG_ERROR("could not register histogram");
+    return StatusCode::FAILURE;
+  }
+
+  // register mc-q2 histogram
+  m_h_mcq2_ene = new TH1F("mcq2_ene", "Mc q2 energy",
+                            100, 0.*CLHEP::GeV, 500.*CLHEP::GeV);
+  if (!hsvc->regHist("/mcaod/McTopWb/mcq2_ene", m_h_mcq2_ene).isSuccess()) {
+    ATH_MSG_ERROR("could not register histogram");
+    return StatusCode::FAILURE;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode McTopAnaSolution::finalize()
+{
+  ATH_MSG_INFO ("Finalizing " << name() << "...");
+
+  // display some stats
+  m_vtxFilter->stats();
+
+  // histo stats
+  ATH_MSG_INFO
+    ("-- McTopMass --" << endmsg
+     << "\tentries= " << m_h_mctop_mass->GetEntries() << endmsg
+     << "\tmean=    " << m_h_mctop_mass->GetMean() / CLHEP::GeV << " GeV/c2" << endmsg
+     << "\tRMS=     " << m_h_mctop_mass->GetRMS()  / CLHEP::GeV << " GeV/c2");
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode McTopAnaSolution::execute()
+{  
+  ATH_MSG_DEBUG ("Executing " << name() << "...");
+
+  if (!doMcTopWb().isSuccess()) {
+    return StatusCode::FAILURE;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode McTopAnaSolution::doMcTopWb()
+{
+  // retrieve input data
+  const McEventCollection *mcevt = 0;
+  if (!evtStore()->retrieve(mcevt, m_mcEventsName).isSuccess() ||
+      0 == mcevt) {
+    ATH_MSG_INFO("could not retrieve mc collection at [" 
+                 << m_mcEventsName << "]!");
+    return StatusCode::FAILURE;
+  }
+
+  if (mcevt->empty()) {
+    ATH_MSG_INFO("mc collection at [" << m_mcEventsName << "] is empty");
+    return StatusCode::SUCCESS;
+  }
+
+  // create filtered container and give ownership to evtstore
+  McEventCollection *filteredMcEvt = new McEventCollection;
+  if (!evtStore()->record(filteredMcEvt, m_filteredMcEventsName).isSuccess()) {
+    ATH_MSG_INFO("could not record filtered mc collection at ["
+                 << m_filteredMcEventsName << "]!");
+    // clean-up...
+    delete filteredMcEvt; filteredMcEvt = 0;
+    return StatusCode::FAILURE;
+  }
+
+  // Tell StoreGate that other algorithms won't be able to change the content of this container
+  if (evtStore()->setConst(filteredMcEvt).isFailure() ) {
+    ATH_MSG_WARNING("Could not lock the McEventCollection at ["
+                    << m_filteredMcEventsName << "] !!"
+                    << endmsg
+                    << "Downstream algorithms will be able to alter it...");
+  }
+
+  // Filter the input collection and fill the output one
+  m_vtxFilter->filterMcEventCollection(mcevt, filteredMcEvt);
+
+  const HepMC::GenEvent * evtAod = filteredMcEvt->front();
+  for ( HepMC::GenEvent::particle_const_iterator itr = evtAod->particles_begin();
+        itr != evtAod->particles_end();
+        ++itr ) {
+    ATH_MSG_DEBUG("Part. id: " << (*itr)->pdg_id() << endmsg
+                  << "E= "        << (*itr)->momentum().e()
+                  << "\tpx= "     << (*itr)->momentum().px());
+
+    // retrieve the decay vertex of the current particle
+    const HepMC::GenVertex * decayVtx = (*itr)->end_vertex();
+
+    if (PDG::t == (*itr)->pdg_id() && //> select top
+        0      !=  decayVtx        && //> check that we have a valid vtx pointer
+        2      <=  decayVtx->particles_out_size() ) { //> isn't necessary, just to exercize the GenVertex interface
+      m_h_mctop_mass->Fill( (*itr)->momentum().m() );
+    }//> top
+  }//> end loop over particles
+
+
+  // create an output TruthParticleContainer
+  TruthParticleContainer *mcparts = new TruthParticleContainer;
+  if (!evtStore()->record(mcparts, m_filteredMcParticlesName).isSuccess()) {
+    ATH_MSG_INFO("could not record filtered truthparticles at ["
+                 << m_filteredMcParticlesName << "]!");
+    // clean-up...
+    delete mcparts; mcparts = 0;
+    return StatusCode::FAILURE;
+  }
+
+  // Tell StoreGate that other algorithms won't be able to change the content of this container
+  if (evtStore()->setConst(mcparts).isFailure() ) {
+    ATH_MSG_WARNING("Could not lock the TruthParticleContainer at ["
+                    << m_filteredMcParticlesName << "] !!"
+                    << endmsg
+                    << "Downstream algorithms will be able to alter it...");
+  }
+  
+  // perform the conversion
+  if (!m_cnvTool->convert(filteredMcEvt, mcparts).isSuccess()) {
+    ATH_MSG_WARNING("could not convert [" << filteredMcEvt << "] collection "
+                    "into a TruthParticleContainer at [" 
+                    << m_filteredMcParticlesName << "] !");
+    return StatusCode::FAILURE;
+  }
+
+  McVtxFilter wqqFilter;
+  wqqFilter.setDecayPattern( "24 -> 1|2|3|4|5|-1|-2|-3|-4|-5 + 1|2|3|4|5" );
+
+  for ( TruthParticleContainer::const_iterator itr = mcparts->begin();
+        itr != mcparts->end();
+        ++itr ) {
+    const TruthParticle* mc = *itr;
+    if ( PDG::W_plus  != mc->pdgId() &&
+         PDG::W_minus != mc->pdgId() ) {
+      // not interested in... Skip it
+      continue;
+    }
+    const HepMC::GenParticle* hepPart = mc->genParticle();
+    const HepMC::GenVertex* vtx = hepPart->end_vertex();
+    // Get the W boson
+    if ( 0 != vtx &&
+         wqqFilter.isAccepted( vtx ) ) {
+      m_h_mcwqq_mass->Fill( mc->m() );
+      const TruthParticle * q1 = mc->child(0);
+      const TruthParticle * q2 = mc->child(1);
+      // note that further treatment should be done
+      // in case of gluons
+      m_h_mcq1_ene->Fill( q1->e() );
+      m_h_mcq2_ene->Fill( q2->e() );
+
+    }//> is a W->qq'
+  }//> end loop over TruthParticles
+
+  return StatusCode::SUCCESS;
+}
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Protected methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+} //> end namespace McAod
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna_solution.h b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna_solution.h
new file mode 100644
index 000000000000..764b8664e22e
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodMcTopAna_solution.h
@@ -0,0 +1,111 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// McTopAna.h 
+// Header file for class McTopAna
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef MCPARTICLETESTS_MCAOD_MCTOPANASOLUTION_H
+#define MCPARTICLETESTS_MCAOD_MCTOPANASOLUTION_H 1
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+
+// fwd declares
+class IMcVtxFilterTool;
+class ITruthParticleCnvTool;
+class TH1F;
+
+namespace McAod {
+
+class McTopAnaSolution
+  : public ::AthAlgorithm
+{ 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+ public: 
+
+  // Copy constructor: 
+
+  /// Constructor with parameters: 
+  McTopAnaSolution( const std::string& name, ISvcLocator* pSvcLocator );
+
+  /// Destructor: 
+  virtual ~McTopAnaSolution(); 
+
+  // Assignment operator: 
+  //McTopAna &operator=(const McTopAna &alg); 
+
+  // Athena algorithm's Hooks
+  virtual StatusCode  initialize();
+  virtual StatusCode  execute();
+  virtual StatusCode  finalize();
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /////////////////////////////////////////////////////////////////// 
+  // Non-const methods: 
+  /////////////////////////////////////////////////////////////////// 
+
+  /// perform the mc t->Wb filtering
+  StatusCode doMcTopWb();
+
+  /////////////////////////////////////////////////////////////////// 
+  // Private data: 
+  /////////////////////////////////////////////////////////////////// 
+ private: 
+
+  /// Default constructor: 
+  McTopAnaSolution();
+
+  // handle to the mc-vtx filter tool
+  ToolHandle<IMcVtxFilterTool> m_vtxFilter;
+
+  // handle to converter tool
+  ToolHandle<ITruthParticleCnvTool> m_cnvTool;
+
+  // Containers
+
+  /// input McEventCollection container name
+  std::string m_mcEventsName;
+
+  /// output filtered McEventCollection container name
+  std::string m_filteredMcEventsName;
+
+  /// output filtered TruthParticleContainer name
+  std::string m_filteredMcParticlesName;
+
+  /// Mc top invariant mass.
+  TH1F *m_h_mctop_mass;
+
+  /// Mc W invariant mass
+  TH1F *m_h_mcwqq_mass;
+
+  /// Mc q1 energy
+  TH1F *m_h_mcq1_ene;
+
+  /// Mc q2 energy
+  TH1F *m_h_mcq2_ene;
+
+}; 
+
+// I/O operators
+//////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+
+} //> end namespace McAod
+#endif //> !MCPARTICLETESTS_MCAOD_MCTOPANASOLUTION_H
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodSymLinkTests.cxx b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodSymLinkTests.cxx
new file mode 100755
index 000000000000..b7c8916619cf
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodSymLinkTests.cxx
@@ -0,0 +1,197 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// McAodSymLinkTests.cxx 
+// Implementation file for class McAodSymLinkTests
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+
+
+// STL includes
+#include <limits>
+
+// FrameWork includes
+#include "GaudiKernel/Property.h"
+
+// StoreGate
+#include "StoreGate/StoreGateSvc.h"
+
+// NavFourMom includes
+#include "NavFourMom/INavigable4MomentumCollection.h"
+#include "NavFourMom/IParticleContainer.h"
+
+// McParticleEvent includes
+#include "McParticleEvent/TruthParticleContainer.h"
+
+// McParticleTests includes
+#include "McAodSymLinkTests.h"
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+McAodSymLinkTests::McAodSymLinkTests( const std::string& name, 
+				      ISvcLocator* pSvcLocator ) : 
+  Algorithm( name, pSvcLocator ),
+  m_storeGate  ( "StoreGateSvc", name ),
+  m_msg        ( msgSvc(),       name )
+{
+  //
+  // Property declaration
+  // 
+  //declareProperty( "Property", m_nProperty );
+
+  std::string descr;
+  descr = "StoreGate location of the TruthParticleContainer we want to test";
+  declareProperty( "TruthParticles",
+		   m_truthParticlesName = "SpclMC",
+		   descr );
+}
+
+// Destructor
+///////////////
+McAodSymLinkTests::~McAodSymLinkTests()
+{ 
+  m_msg << MSG::DEBUG << "Calling destructor" << endreq;
+}
+
+// Athena Algorithm's Hooks
+////////////////////////////
+StatusCode McAodSymLinkTests::initialize()
+{
+  // configure our MsgStream
+  m_msg.setLevel( outputLevel() );
+
+  m_msg << MSG::INFO 
+	<< "Initializing " << name() << "..." 
+	<< endreq;
+
+  // Get pointer to StoreGateSvc and cache it :
+  if ( !m_storeGate.retrieve().isSuccess() ) {
+    m_msg << MSG::ERROR 	
+	  << "Unable to retrieve pointer to StoreGateSvc"
+	  << endreq;
+    return StatusCode::FAILURE;
+  }
+  
+  return StatusCode::SUCCESS;
+}
+
+StatusCode McAodSymLinkTests::finalize()
+{
+  m_msg << MSG::INFO 
+	<< "Finalizing " << name() << "..." 
+	<< endreq;
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode McAodSymLinkTests::execute()
+{  
+  m_msg << MSG::DEBUG << "Executing " << name() << "..." 
+	<< endreq;
+
+  const TruthParticleContainer * mcParts = 0;
+  if ( !m_storeGate->retrieve( mcParts, 
+			       m_truthParticlesName.value() ).isSuccess() ||
+       0 == mcParts ) {
+    m_msg << MSG::ERROR
+	  << "Could not retrieve a TruthParticleContainer at ["
+	  << m_truthParticlesName.value()
+	  << "] !!"
+	  << endreq;
+    return StatusCode::FAILURE;
+  }
+
+  const IParticleContainer* iparts = 0;
+  if ( !m_storeGate->retrieve( iparts, 
+			       m_truthParticlesName.value() ).isSuccess() ||
+       0 == iparts ) {
+    m_msg << MSG::ERROR
+	  << "Could not retrieve an IParticleContainer at ["
+	  << m_truthParticlesName.value()
+	  << "] !!"
+	  << endreq;
+    return StatusCode::FAILURE;
+  }
+  
+  const INavigable4MomentumCollection* inav = 0;
+  if ( !m_storeGate->retrieve( inav, 
+			       m_truthParticlesName.value() ).isSuccess() ||
+       0 == inav ) {
+    m_msg << MSG::ERROR
+	  << "Could not retrieve an INavigable4MomentumCollection at ["
+	  << m_truthParticlesName.value()
+	  << "] !!"
+	  << endreq;
+    return StatusCode::FAILURE;
+  }
+  
+  const std::size_t mcPartsSize = mcParts->size();
+  const std::size_t ipartsSize  = iparts->size();
+  const std::size_t inavSize    = inav->size();
+
+  if ( !( mcPartsSize == ipartsSize  &&
+	  mcPartsSize == inavSize    &&
+	  ipartsSize  == inavSize    ) ) {
+    m_msg << MSG::ERROR
+	  << "Symlinked containers do not have the same size !!" << endreq
+	  << " TruthParticleContainer :        " << mcPartsSize << endreq
+	  << " IParticleContainer :            " << ipartsSize  << endreq
+	  << " INavigable4MomentumCollection : " << inavSize    << endreq;
+    return StatusCode::FAILURE;
+  }
+
+  bool allGood = true;
+  static const double eps = std::numeric_limits<double>::epsilon();
+  for ( std::size_t i = 0; i != mcPartsSize; ++i ) {
+    const double tp_ene = (*mcParts)[i]->e();
+    const double ip_ene = (*iparts)[i]->e();
+    const double in_ene = (*inav)[i]->e();
+    if ( ! ( (tp_ene - ip_ene) < eps &&
+	     (tp_ene - in_ene) < eps &&
+	     (ip_ene - in_ene) < eps ) ) {
+      m_msg << MSG::ERROR
+	    << "symlink FAILS at index [" << i << "]: " << endreq
+	    << " TruthParticle::e(): " << tp_ene << endreq
+	    << " IParticle::e():     " << ip_ene << endreq
+	    << " INav4Mom::e():      " << in_ene << endreq
+	    << " epsilon<double>:    " << eps << endreq;
+      allGood = false;
+    }
+  }
+  if (!allGood) {
+    return StatusCode::FAILURE;
+  }
+
+  // this string is needed for the unit-test
+  m_msg << MSG::INFO << "McAodSymLink tests OK" << endreq;
+
+  return StatusCode::SUCCESS;
+}
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Protected methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodSymLinkTests.h b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodSymLinkTests.h
new file mode 100644
index 000000000000..87ebef64d881
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/McAodSymLinkTests.h
@@ -0,0 +1,97 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// McAodSymLinkTests.h 
+// Header file for class McAodSymLinkTests
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef MCPARTICLETESTS_MCAODSYMLINKTESTS_H 
+#define MCPARTICLETESTS_MCAODSYMLINKTESTS_H 
+
+// STL includes
+#include <string>
+
+// HepMC / CLHEP includes
+
+// FrameWork includes
+#include "GaudiKernel/Algorithm.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/ServiceHandle.h"
+
+// Forward declaration
+class StoreGateSvc;
+class TruthParticleContainer;
+
+class McAodSymLinkTests : public Algorithm
+{ 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+ public: 
+
+  // Copy constructor: 
+
+  /// Constructor with parameters: 
+  McAodSymLinkTests( const std::string& name, ISvcLocator* pSvcLocator );
+
+  /// Destructor: 
+  virtual ~McAodSymLinkTests(); 
+
+  // Assignment operator: 
+  //McAodSymLinkTests &operator=(const McAodSymLinkTests &alg); 
+
+  // Athena algorithm's Hooks
+  virtual StatusCode  initialize();
+  virtual StatusCode  execute();
+  virtual StatusCode  finalize();
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /////////////////////////////////////////////////////////////////// 
+  // Non-const methods: 
+  /////////////////////////////////////////////////////////////////// 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Private methods: 
+  /////////////////////////////////////////////////////////////////// 
+ private: 
+
+  /// Default constructor: 
+  McAodSymLinkTests();
+
+  /// Create a HepMC::GenEvent  and put it into a McEventCollection
+  //StatusCode createGenEvent();
+
+  /////////////////////////////////////////////////////////////////// 
+  // Private data: 
+  /////////////////////////////////////////////////////////////////// 
+ private: 
+
+  typedef ServiceHandle<StoreGateSvc> StoreGateSvc_t;
+  /// Pointer to StoreGate
+  StoreGateSvc_t m_storeGate;
+
+  /// MsgStream instance (a std::cout like with print-out levels)
+  MsgStream m_msg;
+
+  // Containers
+
+  /// Input location of the @c TruthParticleContainer
+  StringProperty m_truthParticlesName;
+
+};
+
+/// I/O operators
+//////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+/// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+
+#endif //> MCPARTICLETESTS_MCAODSYMLINKTESTS_H
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/src/components/McParticleTests_entries.cxx b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/components/McParticleTests_entries.cxx
new file mode 100755
index 000000000000..2fca31bc05c8
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/components/McParticleTests_entries.cxx
@@ -0,0 +1,19 @@
+#include "../McAodSymLinkTests.h"
+#include "../McAodMcTopAna.h"
+#include "../McAodMcTopAna_solution.h"
+
+#include "McParticleKernel/IMcVtxFilterTool.h"
+#include "McParticleKernel/ITruthParticleCnvTool.h"
+
+#include "GaudiKernel/DeclareFactoryEntries.h"
+  
+DECLARE_ALGORITHM_FACTORY( McAodSymLinkTests  )
+using namespace McAod;
+DECLARE_ALGORITHM_FACTORY( McTopAna )
+DECLARE_ALGORITHM_FACTORY( McTopAnaSolution )
+
+DECLARE_FACTORY_ENTRIES( McParticleTests ) {
+  DECLARE_ALGORITHM( McAodSymLinkTests )
+  DECLARE_ALGORITHM( McTopAna )
+  DECLARE_ALGORITHM( McTopAnaSolution )
+}
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/src/components/McParticleTests_load.cxx b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/components/McParticleTests_load.cxx
new file mode 100755
index 000000000000..2b0232bdbe90
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/src/components/McParticleTests_load.cxx
@@ -0,0 +1,3 @@
+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES( McParticleTests )
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/test/McParticleTests.xml b/PhysicsAnalysis/TruthParticleID/McParticleTests/test/McParticleTests.xml
new file mode 100755
index 000000000000..a8e305d5cd4d
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/test/McParticleTests.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0"?>
+<atn>
+
+   <TEST name="rwtest_genEvent" type="script" suite="McTruth">
+      <package_atn>PhysicsAnalysis/TruthParticleID/McParticleTests</package_atn>
+      <options_atn>chappy.py McParticleTests/rwtest_genEvent.py</options_atn>
+      <timelimit>10</timelimit>
+      <author> Sebastien Binet </author>
+      <mailto> binet@cern.ch </mailto>
+      <expectations>
+         <successMessage>All tests SUCCESSFULLY completed</successMessage>
+         <errorMessage>ERROR</errorMessage>
+         <returnValue>0</returnValue>
+      </expectations>
+   </TEST>
+
+   <TEST name="rbtest_genEvent" type="script" suite="McTruth">
+      <package_atn>PhysicsAnalysis/TruthParticleID/McParticleTests</package_atn>
+      <options_atn>chappy.py McParticleTests/rbtest_genEvent.py</options_atn>
+      <timelimit>10</timelimit>
+      <author> Sebastien Binet </author>
+      <mailto> binet@cern.ch </mailto>
+      <expectations>
+         <successMessage>All tests SUCCESSFULLY completed</successMessage>
+         <errorMessage>ERROR</errorMessage>
+         <returnValue>0</returnValue>
+      </expectations>
+   </TEST>
+
+   <TEST name="rwtest_ascii_genEvent" type="script" suite="McTruth">
+      <package_atn>PhysicsAnalysis/TruthParticleID/McParticleTests</package_atn>
+      <options_atn>chappy.py McParticleTests/rwtest_ascii_genEvent.py</options_atn>
+      <timelimit>10</timelimit>
+      <author> Sebastien Binet </author>
+      <mailto> binet@cern.ch </mailto>
+      <expectations>
+         <successMessage>All tests SUCCESSFULLY completed</successMessage>
+         <errorMessage>ERROR</errorMessage>
+         <returnValue>0</returnValue>
+      </expectations>
+   </TEST>
+
+   <TEST name="rwtest_truthParticles" type="script" suite="McTruth">
+      <package_atn>PhysicsAnalysis/TruthParticleID/McParticleTests</package_atn>
+      <options_atn>chappy.py McParticleTests/rwtest_truthParticles.py</options_atn>
+      <timelimit>10</timelimit>
+      <author> Sebastien Binet </author>
+      <mailto> binet@cern.ch </mailto>
+      <expectations>
+         <successMessage>All tests SUCCESSFULLY completed</successMessage>
+         <errorMessage>ERROR</errorMessage>
+         <returnValue>0</returnValue>
+      </expectations>
+   </TEST>
+
+   <TEST name="symlinkTest_mcAod" type="script" suite="McTruth">
+      <package_atn>PhysicsAnalysis/TruthParticleID/McParticleTests</package_atn>
+      <options_atn>chappy.py McParticleTests/symlinkTest_mcAod.py</options_atn>
+      <timelimit>10</timelimit>
+      <author> Sebastien Binet </author>
+      <mailto> binet@cern.ch </mailto>
+      <expectations>
+         <successMessage>All tests SUCCESSFULLY completed</successMessage>
+         <errorMessage>ERROR</errorMessage>
+         <returnValue>0</returnValue>
+      </expectations>
+   </TEST>
+
+   <TEST name="iotest_genEvent" type="script" suite="McTruth">
+      <package_atn>PhysicsAnalysis/TruthParticleID/McParticleTests</package_atn>
+      <options_atn>chappy.py McParticleTests/iotest_genEvent.py</options_atn>
+      <timelimit>10</timelimit>
+      <author> Sebastien Binet </author>
+      <mailto> binet@cern.ch </mailto>
+      <expectations>
+         <successMessage>All tests SUCCESSFULLY completed</successMessage>
+         <errorMessage>ERROR</errorMessage>
+         <returnValue>0</returnValue>
+      </expectations>
+   </TEST>
+
+   <TEST name="iotest_truthParticles" type="script" suite="McTruth">
+      <package_atn>PhysicsAnalysis/TruthParticleID/McParticleTests</package_atn>
+      <options_atn>chappy.py McParticleTests/iotest_truthParticles.py</options_atn>
+      <timelimit>10</timelimit>
+      <author> Sebastien Binet </author>
+      <mailto> binet@cern.ch </mailto>
+      <expectations>
+         <successMessage>All tests SUCCESSFULLY completed</successMessage>
+         <errorMessage>ERROR</errorMessage>
+         <returnValue>0</returnValue>
+      </expectations>
+   </TEST>
+
+</atn>
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/test/mc.aod.pysymlinks.ref b/PhysicsAnalysis/TruthParticleID/McParticleTests/test/mc.aod.pysymlinks.ref
new file mode 100644
index 000000000000..c98dad1c30d9
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/test/mc.aod.pysymlinks.ref
@@ -0,0 +1,7 @@
+Py:PyMcAodSymLinkTests    INFO ==> initialize...
+Py:PyMcAodSymLinkTests    INFO McAodSymLink tests OK
+Py:PyMcAodSymLinkTests    INFO McAodSymLink tests OK
+Py:PyMcAodSymLinkTests    INFO McAodSymLink tests OK
+Py:PyMcAodSymLinkTests    INFO McAodSymLink tests OK
+Py:PyMcAodSymLinkTests    INFO McAodSymLink tests OK
+Py:PyMcAodSymLinkTests    INFO ==> finalize...
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleTests/test/mc.aod.symlinks.ref b/PhysicsAnalysis/TruthParticleID/McParticleTests/test/mc.aod.symlinks.ref
new file mode 100755
index 000000000000..30cc7c309d8e
--- /dev/null
+++ b/PhysicsAnalysis/TruthParticleID/McParticleTests/test/mc.aod.symlinks.ref
@@ -0,0 +1,13 @@
+McAodSymLinkTests    INFO Initializing McAodSymLinkTests...
+McAodSymLinkTests   DEBUG Executing McAodSymLinkTests...
+McAodSymLinkTests    INFO McAodSymLink tests OK
+McAodSymLinkTests   DEBUG Executing McAodSymLinkTests...
+McAodSymLinkTests    INFO McAodSymLink tests OK
+McAodSymLinkTests   DEBUG Executing McAodSymLinkTests...
+McAodSymLinkTests    INFO McAodSymLink tests OK
+McAodSymLinkTests   DEBUG Executing McAodSymLinkTests...
+McAodSymLinkTests    INFO McAodSymLink tests OK
+McAodSymLinkTests   DEBUG Executing McAodSymLinkTests...
+McAodSymLinkTests    INFO McAodSymLink tests OK
+McAodSymLinkTests    INFO Finalizing McAodSymLinkTests...
+McAodSymLinkTests   DEBUG Calling destructor
-- 
GitLab