From ae93afe7fbb42969b2d2f80e20671cea904183d8 Mon Sep 17 00:00:00 2001
From: Sebastien Binet <sebastien.binet@cern.ch>
Date: Fri, 21 Oct 2011 09:24:27 +0200
Subject: [PATCH] use validate_xml (PyAthenaTests-00-00-41)

---
 AtlasTest/PyAthenaTests/cmt/requirements      |  27 +
 AtlasTest/PyAthenaTests/python/Lib.py         | 851 ++++++++++++++++++
 AtlasTest/PyAthenaTests/python/__init__.py    |   7 +
 .../PyAthenaTests/python/my_new_execute.py    |  54 ++
 .../share/ares_clusters_jobOptions.py         |  47 +
 .../share/pyathena_basic_record_retrieve.py   |  41 +
 .../share/pyclusters_jobOptions.py            |  43 +
 .../share/pyevtinfo_jobOptions.py             |  41 +
 .../share/pyfilter_stream_jobOptions.py       |  46 +
 .../share/pythin_basic_jobOptions.py          |  67 ++
 .../PyAthenaTests/share/pythin_jobOptions.py  |  75 ++
 .../share/pythin_mctruth_jobOptions.py        |  69 ++
 .../pythin_multistream_checker_jobOptions.py  |  48 +
 .../share/pythin_multistream_jobOptions.py    | 117 +++
 .../share/pytrigdec_jobOptions.py             |  84 ++
 .../share/utest_thin_cells_release_140100.py  |  38 +
 .../share/utest_thin_eles_release_140100.py   |  31 +
 .../share/utest_thin_jets_release_140100.py   |  35 +
 .../share/utest_thin_muons_release_140100.py  |  31 +
 .../utest_thin_photons_release_140100.py      |  31 +
 .../share/utest_thin_taus_release_140100.py   |  32 +
 .../PyAthenaTests/test/PyAthenaTests.xml      |  76 ++
 .../test/pyathena_basic_record_retrieve.ref   |   8 +
 .../test/pyathena_pyclusters_rel140100.ref    | 234 +++++
 .../pyathena_pyfdr_aodtodpd_rel140100.ref     | 280 ++++++
 ...pyathena_pyfdr_truthslimming_rel140100.ref |  59 ++
 .../test/pyathena_pythinner_atlfast_rel13.ref |  49 +
 .../pyathena_pythinner_atlfast_rel140100.ref  |  46 +
 .../pyathena_pythinner_basic_thinning.ref     |  26 +
 ...hena_pythinner_multistream_check_thin0.ref | 115 +++
 ...hena_pythinner_multistream_check_thin1.ref | 115 +++
 ...hena_pythinner_multistream_check_thin2.ref | 140 +++
 ...yathena_pythinner_multistream_thinning.ref |  52 ++
 ...hena_pythinner_reco-aod_eles_rel140100.ref |  26 +
 ...ena_pythinner_reco-aod_muons_rel140100.ref |  28 +
 ...a_pythinner_reco-aod_photons_rel140100.ref |  27 +
 ...hena_pythinner_reco-aod_taus_rel140100.ref |  26 +
 ...pythinner_reco-esd_calocells_rel140100.ref |  26 +
 .../test/pyathena_trigdectool_rel140100.ref   |  35 +
 .../PyAthenaTests/test/pyathena_utest.py      |  64 ++
 .../PyAthenaTests/test/pyathenatests_base.ref | 157 ++++
 .../test/pyathenatests_histreader.ref         |   8 +
 .../test/pyathenatests_histwriter.ref         |  38 +
 .../PyAthenaTests/test/utest_pyathena_base.py | 202 +++++
 .../test/utest_pyathena_pyclusters.py         | 113 +++
 .../test/utest_pyathena_pyfdr.py              | 118 +++
 .../test/utest_pyathena_pythinner.py          | 601 +++++++++++++
 .../test/utest_pyathena_pytrigdec.py          |  75 ++
 48 files changed, 4559 insertions(+)
 create mode 100644 AtlasTest/PyAthenaTests/cmt/requirements
 create mode 100644 AtlasTest/PyAthenaTests/python/Lib.py
 create mode 100644 AtlasTest/PyAthenaTests/python/__init__.py
 create mode 100644 AtlasTest/PyAthenaTests/python/my_new_execute.py
 create mode 100644 AtlasTest/PyAthenaTests/share/ares_clusters_jobOptions.py
 create mode 100644 AtlasTest/PyAthenaTests/share/pyathena_basic_record_retrieve.py
 create mode 100644 AtlasTest/PyAthenaTests/share/pyclusters_jobOptions.py
 create mode 100644 AtlasTest/PyAthenaTests/share/pyevtinfo_jobOptions.py
 create mode 100644 AtlasTest/PyAthenaTests/share/pyfilter_stream_jobOptions.py
 create mode 100644 AtlasTest/PyAthenaTests/share/pythin_basic_jobOptions.py
 create mode 100644 AtlasTest/PyAthenaTests/share/pythin_jobOptions.py
 create mode 100644 AtlasTest/PyAthenaTests/share/pythin_mctruth_jobOptions.py
 create mode 100644 AtlasTest/PyAthenaTests/share/pythin_multistream_checker_jobOptions.py
 create mode 100644 AtlasTest/PyAthenaTests/share/pythin_multistream_jobOptions.py
 create mode 100644 AtlasTest/PyAthenaTests/share/pytrigdec_jobOptions.py
 create mode 100644 AtlasTest/PyAthenaTests/share/utest_thin_cells_release_140100.py
 create mode 100644 AtlasTest/PyAthenaTests/share/utest_thin_eles_release_140100.py
 create mode 100644 AtlasTest/PyAthenaTests/share/utest_thin_jets_release_140100.py
 create mode 100644 AtlasTest/PyAthenaTests/share/utest_thin_muons_release_140100.py
 create mode 100644 AtlasTest/PyAthenaTests/share/utest_thin_photons_release_140100.py
 create mode 100644 AtlasTest/PyAthenaTests/share/utest_thin_taus_release_140100.py
 create mode 100644 AtlasTest/PyAthenaTests/test/PyAthenaTests.xml
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_basic_record_retrieve.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pyclusters_rel140100.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pyfdr_aodtodpd_rel140100.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pyfdr_truthslimming_rel140100.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pythinner_atlfast_rel13.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pythinner_atlfast_rel140100.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pythinner_basic_thinning.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_check_thin0.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_check_thin1.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_check_thin2.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_thinning.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_eles_rel140100.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_muons_rel140100.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_photons_rel140100.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_taus_rel140100.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-esd_calocells_rel140100.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_trigdectool_rel140100.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathena_utest.py
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathenatests_base.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathenatests_histreader.ref
 create mode 100644 AtlasTest/PyAthenaTests/test/pyathenatests_histwriter.ref
 create mode 100755 AtlasTest/PyAthenaTests/test/utest_pyathena_base.py
 create mode 100755 AtlasTest/PyAthenaTests/test/utest_pyathena_pyclusters.py
 create mode 100755 AtlasTest/PyAthenaTests/test/utest_pyathena_pyfdr.py
 create mode 100755 AtlasTest/PyAthenaTests/test/utest_pyathena_pythinner.py
 create mode 100755 AtlasTest/PyAthenaTests/test/utest_pyathena_pytrigdec.py

diff --git a/AtlasTest/PyAthenaTests/cmt/requirements b/AtlasTest/PyAthenaTests/cmt/requirements
new file mode 100644
index 00000000000..45c1d20a518
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/cmt/requirements
@@ -0,0 +1,27 @@
+package PyAthenaTests
+author  Sebastien Binet <binet@cern.ch>
+
+## For Athena policies: it has to be the first use statement
+use AtlasPolicy 	AtlasPolicy-*
+
+## Put here your package dependencies...
+use AthenaPython 	AthenaPython-*		Control -no_auto_imports 
+use AthExThinning	AthExThinning-*		Control/AthenaExamples -no_auto_imports
+##
+
+branches python share
+
+apply_pattern declare_joboptions files="*.py"
+apply_pattern declare_python_modules files="*.py"
+
+apply_pattern declare_runtime extras="-s=$(PyAthenaTests_root)/test *.ref"
+apply_pattern declare_scripts files="$(PyAthenaTests_root)/test/*.py"
+
+private
+# for unit tests
+use TestPolicy TestPolicy-* 
+
+# automatic xml file validation for tests
+apply_pattern validate_xml
+
+end_private
diff --git a/AtlasTest/PyAthenaTests/python/Lib.py b/AtlasTest/PyAthenaTests/python/Lib.py
new file mode 100644
index 00000000000..f510aca03ee
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/python/Lib.py
@@ -0,0 +1,851 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# @file: PyAthenaTests/python/Lib.py
+# @purpose: a set of Py-components to test pyathena
+# @author: Sebastien Binet <binet@cern.ch>
+
+__version__ = "$Revision: 1.10 $"
+
+import AthenaCommon.SystemOfUnits as Units
+from AthenaPython import PyAthena
+StatusCode = PyAthena.StatusCode
+
+from AthenaPython.Bindings import _clid_typename_aliases
+_clid_typename_aliases['DataVector<AthExParticle>' ] = 'AthExParticles'
+_clid_typename_aliases['DataVector<AthExIParticle>'] = 'AthExIParticles'
+
+def _gen_dv_typedef(elem_type):
+    if not hasattr(PyAthena, '%ss'%elem_type):
+        dv = getattr(PyAthena, 'DataVector< %s >'%elem_type)
+        setattr(PyAthena, '%ss'%elem_type, dv)
+    return getattr(PyAthena, '%ss'%elem_type)
+
+class PyRecord( PyAthena.Alg ):
+    """A simple python algorithm to record data into storegate
+    """
+    def __init__(self, name = "PyRecord", **kw):
+        ## init base class
+        kw['name'] = name
+        super(PyRecord,self).__init__(**kw)
+
+        self.particles   = kw.get('particles',   "Particles")
+        self.decay       = kw.get('decay',       "TwoBodyDecay")
+        self.elephantino = kw.get('elephantino', "PinkElephantino")
+
+        self.sg = None
+        return
+    
+    def initialize(self):
+        _info = self.msg.info
+        
+        _info( "initializing %s", self.name() )
+        ## storegate
+        self.sg = PyAthena.StoreGate.pointer("StoreGateSvc")
+        if not self.sg:
+            self.msg.error("could not retrieve storegatesvc !")
+            return StatusCode.Failure
+
+        ## hack to load clids...
+        from AthenaCommon.AppMgr import theApp
+        theApp.Dlls += ['AthExThinningAlgs',
+                        'AthExThinningEvent',
+                        'AthExThinningPoolCnv']
+
+        ## Datavector stuff
+##         assert _gen_dv_typedef('AthExParticle') is not None
+##         assert _gen_dv_typedef('AthExIParticle') is not None
+
+##         import ctypes
+##         ctypes.cdll.LoadLibrary ('libAthExThinningAlgs.so')
+        return StatusCode.Success
+
+    def execute(self):
+        _info = self.msg.info
+        _err  = self.msg.error
+        _record = self.sg.record
+        _info( "executing %s...", self.name() )
+        allGood = True
+        particles = PyAthena.AthExParticles()
+        ## fill-in particles:
+        for i in xrange(10):
+            particles.push_back( PyAthena.AthExParticle(i,i,i,i) )
+            
+        if _record(particles, self.particles) != StatusCode.Success:
+            _err('could not record particles at [%s]', self.particles)
+            allGood = False
+            pass
+
+        iparticles = PyAthena.AthExIParticles()
+#        self.sg['I%s'%self.particles] = iparticles
+        if _record(iparticles, 'I%s'%self.particles) != StatusCode.Success:
+            _err('could not record iparticles at [I%s]', self.particles)
+            allGood = False
+            pass
+        
+        decay = PyAthena.AthExDecay()
+        if _record(decay, self.decay) != StatusCode.Success:
+            _err('could not record decay at [%s]', self.decay)
+            allGood = False
+            pass
+        
+        ele = PyAthena.AthExElephantino()
+        if _record(ele, self.elephantino) != StatusCode.Success:
+            _err('could not record elephantino at [%s]', self.elephantino)
+            allGood = False
+            pass
+
+        _info('all good: %s', allGood)
+        if allGood:
+            return StatusCode.Success
+        return StatusCode.Failure
+
+    def finalize(self):
+        self.msg.info( "finalizing %s...", self.name() )
+        return StatusCode.Success
+
+    pass # PyRecord
+
+
+class PyRetrieve( PyAthena.Alg ):
+    """A simple python algorithm to retrieve data from storegate
+    """
+    def __init__(self, name = "PyRetrieve", **kw):
+        ## init base class
+        kw['name'] = name
+        super(PyRetrieve,self).__init__(**kw)
+
+        self.particles   = kw.get('particles',   "Particles")
+        self.decay       = kw.get('decay',       "TwoBodyDecay")
+        self.elephantino = kw.get('elephantino', "PinkElephantino")
+
+        ## handle to event store
+        self.sg = None
+        return
+    
+    def initialize(self):
+        self.msg.info( "initializing %s", self.name() )
+        ## storegate
+        self.sg = PyAthena.StoreGate.pointer("StoreGateSvc")
+        if not self.sg:
+            self.msg.error('could not retrieve event store')
+            return StatusCode.Failure
+        
+        ## hack to load clids...
+        from AthenaCommon.AppMgr import theApp
+        theApp.Dlls += ['AthExThinningAlgs',
+                        'AthExThinningEvent',
+                        'AthExThinningPoolCnv']
+        ## Datavector stuff
+##         assert _gen_dv_typedef('AthExParticle') is not None
+##         assert _gen_dv_typedef('AthExIParticle') is not None
+
+        return StatusCode.Success
+
+    def execute(self):
+        _retrieve = self.sg.retrieve
+        _err  = self.msg.error
+        _info = self.msg.info
+        _info( "executing %s...", self.name() )
+        
+        allGood = True
+        particles = _retrieve("AthExParticles", self.particles)
+        if particles is None:
+            _err("Could not fetch particles at [%s] !!", self.particles)
+            allGood = False
+            pass
+        assert len(particles) == 10
+        for idx,p in enumerate(particles):
+            assert p.px() == float(idx)
+            assert p.py() == float(idx)
+            assert p.pz() == float(idx)
+            assert p.e()  == float(idx)
+            
+        iparticles = _retrieve("AthExIParticles", 'I%s'%self.particles)
+        if iparticles is None:
+            _err("Could not fetch iparticles at [I%s] !!", self.particles)
+            allGood = False
+            pass
+        assert len(iparticles) == 0
+        
+        decay = _retrieve("AthExDecay", self.decay)
+        if decay is None:
+            _err("Could not fetch Decay at [%s] !!", self.decay)
+            allGood = False
+            pass
+        
+        elephantino = _retrieve("AthExElephantino", self.elephantino)
+        if elephantino is None:
+            _err("Could not fetch Elephantino at [%s] !!", self.elephantino)
+            allGood = False
+            pass
+
+        _info('all good: %s', allGood)
+        if allGood: return StatusCode.Success
+        return StatusCode.Failure
+
+    def finalize(self):
+        self.msg.info( "finalizing %s...", self.name() )
+        return StatusCode.Success
+
+    pass # PyRetrieve
+
+### ---------------------------------------------------------------------------
+import os
+class TrigDecTestAlg (PyAthena.Alg):
+    'Dummy algorithm testing accessing to HLT informations'
+    def __init__(self, name='TrigDecTestAlg', **kw):
+        ## init base class
+        kw['name'] = name
+        super(TrigDecTestAlg, self).__init__(**kw)
+
+        ## properties and data members
+        self.filename = kw.get('filename', 'trig_passed_evts.ascii')
+        self.trigDec = None
+        return
+
+    def initialize(self):
+        self.msg.info('==> initialize...')
+        self.trigDec = PyAthena.py_tool('Trig::TrigDecisionTool')
+        if not self.trigDec:
+            self.msg.error('could not retrieve TrigDecisionTool !')
+            return StatusCode.Failure
+
+        ## fix-up HLT::Chain
+        def _str_hlt_chain(c):
+            """helper function to make a HLT::Chain printable"""
+            return "Counter = %r success (raw) = %r pass-through = %r "\
+                   "prescaled = %r lastActiveStep = %r \tname = %r" % \
+                   (c.getChainCounter(),
+                    bool(c.chainPassedRaw()),
+                    bool(c.isPassedThrough()),
+                    bool(c.isPrescaled()),
+                    c.getChainStep(),
+                    c.getChainName())
+        PyAthena.HLT.Chain.__str__ = _str_hlt_chain
+        del _str_hlt_chain
+        
+        self.sg = PyAthena.py_svc('StoreGateSvc')
+        if not self.sg:
+            self.msg.error('could not retrieve event store !')
+            return StatusCode.Failure
+
+        self._passed_evts = open(self.filename, 'w')
+        return StatusCode.Success
+
+    def execute(self):
+        _info = self.msg.info
+        _info('==> execute...')
+        self.setFilterPassed(False)
+
+        evid = self.sg.retrieve('EventInfo', 'McEventInfo').event_ID()
+        
+        ef_state = bool(self.trigDec.isPassed("EF_.*"))
+        _info('Pass state EF = %r', ef_state)
+
+        # test L2_e25i ?
+        n = "L2_e25i"
+        passed = bool(self.trigDec.isPassed(n))
+        if not passed:
+            _info("chain %s: passed: %s",n, passed)
+#            _info('== FAILED ==')
+        else:
+            _info("chain %s: passed: %s",n, passed)
+            _info('== SUCCESS ==')
+            # this is mainly for regression test purposes
+            evid = "[%s/%s]" % (evid.run_number(),
+                                evid.event_number())
+            self._passed_evts.write(evid+os.linesep)
+            #_info('filter passed for %s',evid)
+        self.setFilterPassed(passed)
+        return StatusCode.Success
+
+    def finalize(self):
+        self.msg.info('==> finalize...')
+        self._passed_evts.flush()
+        self._passed_evts.close()
+        return StatusCode.Success
+
+    pass # class TrigDecTestAlg
+
+### ---------------------------------------------------------------------------
+class PyFilterAlg (PyAthena.Alg):
+    'Dummy algorithm filtering out one event out of 2'
+    def __init__(self, name='PyFilterAlg', **kw):
+        ## init base class
+        kw['name'] = name
+        super(PyFilterAlg, self).__init__(**kw)
+
+        ## properties and data members
+        self.filename = kw.get('filename', 'evtlist.ascii')
+        self.evtinfo  = kw.get('evtinfo',  'EventInfo')
+        return
+
+    def initialize(self):
+        self.msg.info('==> initialize...')
+        self.sg = PyAthena.py_svc('StoreGateSvc')
+        if not self.sg:
+            self.msg.error('could not retrieve event store !')
+            return StatusCode.Failure
+
+        self._evts = open(self.filename, 'w')
+        self._evtcnt = 0
+        return StatusCode.Success
+
+    def execute(self):
+        self.setFilterPassed(False)
+        _info = self.msg.info
+        _info('==> execute...')
+        evid = self.sg.retrieve('EventInfo', self.evtinfo).event_ID()
+        
+        evid = "[%s/%s]" % (evid.run_number(), evid.event_number())
+        _info('[run/evt]: %s',evid)
+        if self._evtcnt%2 == 0:
+            self._evts.write(evid+os.linesep)
+            self.setFilterPassed(True)
+        self._evtcnt += 1
+        return StatusCode.Success
+
+    def finalize(self):
+        self.msg.info('==> finalize...')
+        self.msg.info('analyzed [%i] events', self._evtcnt)
+        self._evts.flush()
+        self._evts.close()
+        return StatusCode.Success
+
+    pass # class PyFilterAlg
+
+### ---------------------------------------------------------------------------
+class EventInfoDumper (PyAthena.Alg):
+    'Dummy algorithm logging out run_nbr/evt_nbr'
+    def __init__(self, name='EventInfoDumper', **kw):
+        ## init base class
+        kw['name'] = name
+        super(EventInfoDumper, self).__init__(**kw)
+
+        ## properties and data members
+        self.filename = kw.get('filename', 'evtlist.ascii')
+        self.evtinfo  = kw.get('evtinfo',  'EventInfo')
+        return
+
+    def initialize(self):
+        self.msg.info('==> initialize...')
+        self.sg = PyAthena.py_svc('StoreGateSvc')
+        if not self.sg:
+            self.msg.error('could not retrieve event store !')
+            return StatusCode.Failure
+
+        self._evts = open(self.filename, 'w')
+        return StatusCode.Success
+
+    def execute(self):
+        _info = self.msg.info
+        _info('==> execute...')
+        evid = self.sg.retrieve('EventInfo', self.evtinfo).event_ID()
+        
+        evid = "[%s/%s]" % (evid.run_number(), evid.event_number())
+        _info('[run/evt]: %s',evid)
+        self._evts.write(evid+os.linesep)
+        return StatusCode.Success
+
+    def finalize(self):
+        self.msg.info('==> finalize...')
+        self._evts.flush()
+        self._evts.close()
+        return StatusCode.Success
+
+    pass # class EventInfoDumper
+
+### ---------------------------------------------------------------------------
+class McDump(PyAthena.Alg):
+    """A python algorithm to inspect McEventCollections
+    """
+    def __init__(self, name="McDump", **kw):
+        ## init the base class
+        kw['name'] = name
+        super(McDump,self).__init__(**kw)
+
+        ## provide default values for properties
+        self.mcName = kw.get('mcName', 'GEN_EVENT')
+        return
+
+    def initialize(self):
+        self.msg.info('initializing...')
+        self.sg = PyAthena.py_svc('StoreGateSvc')
+        if not self.sg:
+            self.msg.error('Could not retrieve StoreGateSvc !')
+            return StatusCode.Failure
+
+        self.msg.info('Dumping configuration:')
+        self.msg.info('McEventCollection key: %s', self.mcName)
+        return StatusCode.Success
+
+    def execute(self):
+        _info = self.msg.info
+        _info('running execute...')
+        _info('retrieve [%s/%s]', 'McEventCollection', self.mcName)
+        mc = self.sg.retrieve('McEventCollection', self.mcName)
+        if not mc:
+            self.msg.warning(
+                'Could not retrieve McEventCollection at [%s]',
+                self.mcName
+                )
+            return StatusCode.Recoverable
+
+        if len(mc) <= 0:
+            self.msg.info('No GenEvent in "%s"!', self.mcName)
+        _info('number of GenEvents: %i', len(mc))
+        evt = mc[0]
+        _info('number of GenParticles: %i', evt.particles_size())
+        _info('number of GenVertices:  %i', evt.vertices_size())
+
+        return StatusCode.Success
+
+    def finalize(self):
+        self.msg.info('finalizing...')
+        return StatusCode.Success
+
+    pass # class McDump
+
+### ---------------------------------------------------------------------------
+class Thinner(PyAthena.Alg):
+    """A python algorithm to thin containers
+    """
+    def __init__(self, name="Thinner", **kw):
+        ## init the base class
+        kw['name'] = name
+        super(Thinner,self).__init__(**kw)
+
+        ## provide default values for properties
+        self.coll_type = kw.get('coll_type',  'JetCollection')
+        self.coll_name = kw.get('coll_name',  'AtlfastJetContainer')
+        self.filter_fct= kw.get('filter_fct', lambda x: x.e() > 40.*Units.GeV)
+        return
+
+    def initialize(self):
+        self.msg.info('initializing...')
+        self.sg = PyAthena.py_svc('StoreGateSvc')
+        if not self.sg:
+            self.msg.error('Could not retrieve StoreGateSvc !')
+            return StatusCode.Failure
+
+        self.thinSvc = PyAthena.py_svc('ThinningSvc/MyThinningSvc')
+        if not self.thinSvc:
+            self.msg.error('Could not retrieve [ThinningSvc/MyThinningSvc] !')
+            return StatusCode.Failure
+        
+        self.msg.info('Dumping configuration:')
+        self.msg.info('Container type: %s', self.coll_type)
+        self.msg.info('Container key:  %s', self.coll_name)
+        self.msg.info('Filter: %r',         self.filter_fct.__name__)
+        return StatusCode.Success
+
+    def execute(self):
+        _info = self.msg.info
+        _info('running execute...')
+        _info('retrieve [%s/%s]', self.coll_type, self.coll_name)
+        cont = self.sg.retrieve(self.coll_type, self.coll_name)
+        if not cont:
+            self.msg.warning(
+                'Could not retrieve %s at [%s]',
+                self.coll_type,
+                self.coll_name
+                )
+            return StatusCode.Recoverable
+
+        if len(cont) <= 0:
+            self.msg.info('Container "%s/%s" is empty',
+                          self.coll_type, self.coll_name)
+        _info('number of elements before thinning: %i', len(cont))
+
+        predicate = self.filter_fct
+        mask = [ predicate(element) for element in cont ]
+
+        ## apply thinning:
+        if not (self.thinSvc.filter(cont, mask) == StatusCode.Success):
+            self.msg.error("Could not apply thinning !")
+            return StatusCode.Failure
+        
+        _info('number of elements after  thinning: %i',
+              len([m for m in mask if m]))
+        
+        return StatusCode.Success
+
+    def finalize(self):
+        self.msg.info('finalizing...')
+        return StatusCode.Success
+
+    pass # class Thinner
+
+### ---------------------------------------------------------------------------
+class BasicThinner(PyAthena.Alg):
+    """A python algorithm to thin basic containers
+    """
+    def __init__(self, name="BasicThinner", **kw):
+        ## init the base class
+        kw['name'] = name
+        super(BasicThinner,self).__init__(**kw)
+
+        ## provide default values for properties
+        self.coll_type = kw.get('coll_type',  'AthExParticles')
+        self.coll_name = kw.get('coll_name',  'athexparticles')
+        self.filter_fct= kw.get('filter_fct', lambda i,x: i%2==0)
+        ## thinning-svc name
+        self.thinSvc   = kw.get('thinSvc', 'ThinningSvc/MyThinningSvc')
+        return
+
+    def initialize(self):
+        self.msg.info('initializing...')
+        self.sg = PyAthena.py_svc('StoreGateSvc')
+        if not self.sg:
+            self.msg.error('Could not retrieve StoreGateSvc !')
+            return StatusCode.Failure
+
+        self.thinSvc = PyAthena.py_svc(self.thinSvc)
+        if not self.thinSvc:
+            self.msg.error('Could not retrieve thinning service!')
+            return StatusCode.Failure
+        
+        self.msg.info('Dumping configuration:')
+        self.msg.info('Container type: %s', self.coll_type)
+        self.msg.info('Container key:  %s', self.coll_name)
+        self.msg.info('Filter: %r',         self.filter_fct.__name__)
+        return StatusCode.Success
+
+    def execute(self):
+        _info = self.msg.info
+        _info('running execute...')
+
+        _info('retrieve [%s/%s]', self.coll_type, self.coll_name)
+        cont = self.sg.retrieve(self.coll_type, self.coll_name)
+        if not cont:
+            self.msg.warning(
+                'Could not retrieve %s at [%s]',
+                self.coll_type,
+                self.coll_name
+                )
+            return StatusCode.Recoverable
+
+        if len(cont) <= 0:
+            self.msg.info('Container "%s/%s" is empty',
+                          self.coll_type, self.coll_name)
+        _info('number of elements before thinning: %i', len(cont))
+
+        predicate = self.filter_fct
+        mask = [ predicate(idx,element) for idx,element in enumerate(cont) ]
+
+        ## apply thinning:
+        if not (self.thinSvc.filter(cont, mask) == StatusCode.Success):
+            self.msg.error("Could not apply thinning !")
+            return StatusCode.Failure
+        
+        _info('number of elements after  thinning: %i',
+              len([m for m in mask if m]))
+        
+        return StatusCode.Success
+
+    def finalize(self):
+        self.msg.info('finalizing...')
+        return StatusCode.Success
+
+    pass # class BasicThinner
+
+### ---------------------------------------------------------------------------
+class ThinChecker(PyAthena.Alg):
+    """A python algorithm to check the output of maybe thinned basic containers
+    """
+    def __init__(self, name="ThinChecker", **kw):
+        ## init the base class
+        kw['name'] = name
+        super(ThinChecker,self).__init__(**kw)
+
+        ## provide default values for properties
+        self.coll_type = kw.get('coll_type',  'AthExParticles')
+        self.coll_name = kw.get('coll_name',  'athexparticles')
+
+        ## storegate
+        self.sg = None
+        return
+
+    def initialize(self):
+        self.msg.info('initializing...')
+        self.sg = PyAthena.py_svc('StoreGateSvc')
+        if not self.sg:
+            self.msg.error('Could not retrieve StoreGateSvc !')
+            return StatusCode.Failure
+
+        self.msg.info('Dumping configuration:')
+        self.msg.info('Container type: %s', self.coll_type)
+        self.msg.info('Container key:  %s', self.coll_name)
+        return StatusCode.Success
+
+    def execute(self):
+        _info = self.msg.info
+        _info('running execute...')
+
+        _info('retrieve [%s/%s]', self.coll_type, self.coll_name)
+        cont = self.sg.retrieve(self.coll_type, self.coll_name)
+        if not cont:
+            self.msg.warning(
+                'Could not retrieve %s at [%s]',
+                self.coll_type,
+                self.coll_name
+                )
+            return StatusCode.Recoverable
+
+        if len(cont) <= 0:
+            self.msg.info('Container "%s/%s" is empty',
+                          self.coll_type, self.coll_name)
+        _info('number of elements : %i', len(cont))
+
+        for idx,e in enumerate(cont):
+            _info( '[%s][%i]: %f %f %f %f', self.coll_name, idx,
+                   e.e(), e.px(), e.py(), e.pz() )
+            pass
+        return StatusCode.Success
+
+    def finalize(self):
+        self.msg.info('finalizing...')
+        return StatusCode.Success
+
+    pass # class ThinChecker
+
+### ---------------------------------------------------------------------------
+from math import log10
+
+## helper function to turn a pair of (c++) iterators into
+## a valid python iterator (stolen from Scott)
+def toiter(beg,end):
+    while beg != end:
+        yield beg.__deref__()
+        beg.__preinc__()
+    return
+
+## FIXME: 'temporary' patch to work around missing dict.
+## for 'CaloCluster::MomentStoreIter'
+class _patch:
+    @staticmethod
+    def CaloClusterMoments():
+        import ROOT
+        return [
+            ROOT.CaloClusterMoment.FIRST_PHI,
+            ROOT.CaloClusterMoment.FIRST_ETA,
+            ROOT.CaloClusterMoment.SECOND_R,
+            ROOT.CaloClusterMoment.SECOND_LAMBDA,
+            ROOT.CaloClusterMoment.DELTA_PHI,
+            ROOT.CaloClusterMoment.DELTA_THETA,
+            ROOT.CaloClusterMoment.DELTA_ALPHA,
+            ROOT.CaloClusterMoment.CENTER_X,
+            ROOT.CaloClusterMoment.CENTER_Y,
+            ROOT.CaloClusterMoment.CENTER_Z,
+            ROOT.CaloClusterMoment.CENTER_LAMBDA,
+            ROOT.CaloClusterMoment.LATERAL,
+            ROOT.CaloClusterMoment.LONGITUDINAL,
+            ROOT.CaloClusterMoment.ENG_FRAC_EM,
+            ROOT.CaloClusterMoment.ENG_FRAC_MAX,
+            ROOT.CaloClusterMoment.ENG_FRAC_CORE,
+            ROOT.CaloClusterMoment.FIRST_ENG_DENS,
+            ROOT.CaloClusterMoment.SECOND_ENG_DENS,
+            ROOT.CaloClusterMoment.ISOLATION,
+            ]
+            
+class ClusterExAlg(PyAthena.Alg):
+    """example on how to use Calo-stuff in PyAthena
+    """
+    def __init__(self, name='ClusterExAlg', **kw):
+        # base init
+        kw['name'] = name
+        super(ClusterExAlg, self).__init__(**kw)
+
+        # sg key for clusters
+        self.clustersName = kw.get('Clusters', 'CaloCalTopoCluster')
+
+        self.hsvc = None # handle to histo svc
+        self.sg   = None # handle to storegate
+        return
+
+    def initialize(self):
+        _info = self.msg.info
+        _info('==> initialize')
+        self.hsvc = PyAthena.py_svc('THistSvc')
+        if not self.hsvc:
+            self.msg.error('could not retrieve THistSvc')
+            return StatusCode.Failure
+
+        self.sg = PyAthena.py_svc('StoreGateSvc')
+        if not self.sg:
+            self.msg.error('could not retrieve event store')
+            return StatusCode.Failure
+
+        _info('reading clusters from [%r]', self.clustersName)
+
+        # registering histograms
+        import ROOT
+        hsvc = self.hsvc
+        hsvc['/py/clusE']   = ROOT.TH1F('clusE',   'clusE',   100, -4.0, 6.0)
+        hsvc['/py/clusEta'] = ROOT.TH1F('clusEta', 'clusEta', 220, -5.5, 5.5)
+
+        self._evtNbr = -1
+        return StatusCode.Success
+
+    def execute(self):
+        _info = self.msg.info
+        _info('==> execute')
+        self._evtNbr += 1
+        # retrieve clusters
+        clusters = self.sg.retrieve('CaloClusterContainer', self.clustersName)
+        if not clusters:
+            self.msg.warning('could not retrieve clusters at [%r]',
+                             self.clustersName)
+            return StatusCode.Recoverable
+
+        _info('event #%i has %3i clusters', self._evtNbr, len(clusters))
+        _clusE   = self.hsvc['/py/clusE'].Fill
+        _clusEta = self.hsvc['/py/clusEta'].Fill
+
+        from ROOT import CaloClusterMoment
+        from ROOT import Double as RDouble
+        
+        for i,cluster in enumerate(clusters):
+            ene = cluster.e()
+
+            if   ene < -1.: ene = -log10(-ene)
+            elif ene >  1.: ene =  log10( ene)
+            else:           ene = 0.
+            _clusE(ene)
+            _clusEta(cluster.eta())
+
+            if i%100 != 0:
+                continue
+
+            _info('cluster #%3i has energy %8.3f',i, ene)
+            ## FIXME: missing dictionary for 'CaloCluster::MomentStoreIter'
+##             for moment in toiter(cluster.beginMoment(useLink=False),
+##                                  cluster.endMoment  (useLink=False)):
+            
+            for m in _patch.CaloClusterMoments():
+                moment = RDouble(0.)
+                if cluster.retrieveMoment(m, moment, useLink=False):
+                    _info('cluster #%3i has moment #%3i with value %8.3f',
+                          i, m, moment)
+            pass # loop over clusters
+
+        return StatusCode.Success
+
+    def finalize(self):
+        _info = self.msg.info
+        _info('==> finalize')
+        import AthenaCommon.Constants
+        clusE   = self.hsvc['/py/clusE']
+        clusEta = self.hsvc['/py/clusEta']
+
+        _info('=== analyzed [%i] events ===', self._evtNbr)
+        _info(' <cluster ene> = %8.3f MeV', clusE.GetMean())
+        _info('          rms  = %8.3f MeV', clusE.GetRMS() )
+        _info(' <cluster eta> = %8.3f', clusEta.GetMean())
+        _info('          rms  = %8.3f', clusEta.GetRMS ())
+        return StatusCode.Success
+
+    pass # ClusterExAlg
+
+### reading clusters, but with Ares -------------------------------------------
+class AresClusterExAlg(PyAthena.Alg):
+    """an example on how to do calo-stuff in PyAthena/Ares"""
+    def __init__(self, name='AresClusterExAlg', **kw):
+        # base init
+        kw['name'] = name
+        super(AresClusterExAlg, self).__init__(**kw)
+
+        # sg key for clusters
+        self.clustersName = kw.get('Clusters', 'CaloCalTopoCluster')
+
+        self.hsvc = None # handle to histo svc
+        self.sg   = None # handle to storegate
+        self.ares = None # handle to the AresEvtSvc
+        return
+
+    def initialize(self):
+        _info = self.msg.info
+        _info('==> initialize')
+        self.hsvc = PyAthena.py_svc('THistSvc')
+        if not self.hsvc:
+            self.msg.error('could not retrieve THistSvc')
+            return StatusCode.Failure
+
+        self.sg = PyAthena.py_svc('StoreGateSvc')
+        if not self.sg:
+            self.msg.error('could not retrieve event store')
+            return StatusCode.Failure
+
+        _info('reading clusters from [%r]', self.clustersName)
+
+        # registering histograms
+        import ROOT
+        hsvc = self.hsvc
+        hsvc['/py/clusE']   = ROOT.TH1F('clusE',   'clusE',   100, -4.0, 6.0)
+        hsvc['/py/clusEta'] = ROOT.TH1F('clusEta', 'clusEta', 220, -5.5, 5.5)
+
+        self.ares = self.hsvc['/temp/TTreeStream/CollectionTree_trans']
+        
+        self._evtNbr = -1
+        return StatusCode.Success
+
+    def execute(self):
+        _info = self.msg.info
+        _info('==> execute')
+        self._evtNbr += 1
+        # retrieve clusters
+        clusters = getattr(self.ares, self.clustersName)
+        if not clusters:
+            self.msg.warning('could not retrieve clusters at [%r]',
+                             self.clustersName)
+            return StatusCode.Recoverable
+
+        _info('event #%i has %3i clusters', self._evtNbr, len(clusters))
+        _clusE   = self.hsvc['/py/clusE'].Fill
+        _clusEta = self.hsvc['/py/clusEta'].Fill
+
+        from ROOT import CaloClusterMoment
+        from ROOT import Double as RDouble
+        
+        for i,cluster in enumerate(clusters):
+            ene = cluster.e()
+
+            if   ene < -1.: ene = -log10(-ene)
+            elif ene >  1.: ene =  log10( ene)
+            else:           ene = 0.
+            _clusE(ene)
+            _clusEta(cluster.eta())
+
+            if i%100 != 0:
+                continue
+
+            _info('cluster #%3i has energy %8.3f',i, ene)
+            ## FIXME: missing dictionary for 'CaloCluster::MomentStoreIter'
+##             for moment in toiter(cluster.beginMoment(useLink=False),
+##                                  cluster.endMoment  (useLink=False)):
+            
+            for m in _patch.CaloClusterMoments():
+                moment = RDouble(0.)
+                if cluster.retrieveMoment(m, moment, useLink=False):
+                    _info('cluster #%3i has moment #%3i with value %8.3f',
+                          i, m, moment)
+            pass # loop over clusters
+
+        return StatusCode.Success
+
+    def finalize(self):
+        _info = self.msg.info
+        _info('==> finalize')
+        import AthenaCommon.Constants
+        clusE   = self.hsvc['/py/clusE']
+        clusEta = self.hsvc['/py/clusEta']
+
+        _info('=== analyzed [%i] events ===', self._evtNbr)
+        _info(' <cluster ene> = %8.3f MeV', clusE.GetMean())
+        _info('          rms  = %8.3f MeV', clusE.GetRMS() )
+        _info(' <cluster eta> = %8.3f', clusEta.GetMean())
+        _info('          rms  = %8.3f', clusEta.GetRMS ())
+        return StatusCode.Success
+
+    pass # AresClusterExAlg
+
diff --git a/AtlasTest/PyAthenaTests/python/__init__.py b/AtlasTest/PyAthenaTests/python/__init__.py
new file mode 100644
index 00000000000..8a424a0eab3
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/python/__init__.py
@@ -0,0 +1,7 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# hook for the PyAthenaTests py-module
+__doc__ = """PyAthenaTests holds a set of python classes to test the
+functionalities of PyAthena"""
+__author__ = "Sebastien Binet <binet@cern.ch>"
+__version__ = "$Revision: 1.1.1.1 $"
diff --git a/AtlasTest/PyAthenaTests/python/my_new_execute.py b/AtlasTest/PyAthenaTests/python/my_new_execute.py
new file mode 100644
index 00000000000..1daed4ec600
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/python/my_new_execute.py
@@ -0,0 +1,54 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+from math import log10
+from PyAthenaTests.Lib import _patch
+from AthenaPython import PyAthena
+StatusCode = PyAthena.StatusCode
+
+def new_execute(self):
+    """a new execute method, making use of new data members"""
+    ### the old part #########################################
+    _info = self.msg.info
+    _info('==> execute')
+    self._evtNbr += 1
+    # retrieve clusters
+    clusters = self.sg.retrieve('CaloClusterContainer', self.clustersName)
+    if not clusters:
+        self.msg.warning('could not retrieve clusters at [%r]',
+                         self.clustersName)
+        return StatusCode.Recoverable
+
+    _info('event #%i has %3i clusters', self._evtNbr, len(clusters))
+    _clusE   = self.hsvc['/py/clusE'].Fill
+    _clusEta = self.hsvc['/py/clusEta'].Fill
+
+    from ROOT import CaloClusterMoment
+    from ROOT import Double as RDouble
+
+    for i,cluster in enumerate(clusters):
+        ene = cluster.e()
+
+        if   ene < -1.: ene = -log10(-ene)
+        elif ene >  1.: ene =  log10( ene)
+        else:           ene = 0.
+    ######################## NEW PART ########################
+        if ene < self._ene_cut:
+            # skip that cluster
+            continue
+        _clusE(ene, self._ene_weight)
+    ######################## go one with OLD part ############
+        _clusEta(cluster.eta())
+
+        if i%100 != 0:
+            continue
+
+        _info('cluster #%3i has energy %8.3f',i, ene)
+        for m in _patch.CaloClusterMoments():
+            moment = RDouble(0.)
+            if cluster.retrieveMoment(m, moment, useLink=False):
+                _info('cluster #%3i has moment #%3i with value %8.3f',
+                      i, m, moment)
+        pass # loop over clusters
+
+    return StatusCode.Success
+        
diff --git a/AtlasTest/PyAthenaTests/share/ares_clusters_jobOptions.py b/AtlasTest/PyAthenaTests/share/ares_clusters_jobOptions.py
new file mode 100644
index 00000000000..4c91d7c8946
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/ares_clusters_jobOptions.py
@@ -0,0 +1,47 @@
+## job options file to steer the cluster example, using ares
+
+#########################
+if not 'EVTMAX' in dir():
+    EVTMAX=5
+if not 'INPUT' in dir():
+    INPUT = [ # a "reference" file from FCT
+        'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+        '/AllBasicSamples.AOD.pool.root'
+        ]
+    #INPUT = ['AOD.pool.root']
+if not 'TUPLEOUT' in dir():
+    TUPLEOUT = 'ares_pyclusters.root'
+    pass
+#########################
+## 
+from AthenaCommon.AppMgr import theApp, ServiceMgr as svcMgr
+
+## setup application for reading POOL files via Ares
+import AthenaRootComps.ReadAres
+
+svcMgr.EventSelector.InputCollections = INPUT
+svcMgr.EventSelector.TupleName = 'CollectionTree'
+
+## events to process
+theApp.EvtMax = EVTMAX
+
+## setup the histo svc
+##  - register an output stream id 'py'
+##  - associate an output file
+svcMgr += CfgMgr.THistSvc()
+svcMgr.THistSvc.Output = [
+    "py DATAFILE='%s' TYP='ROOT' OPT='RECREATE'" % TUPLEOUT,
+    ]
+
+## alg sequence creation
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+## schedule the algorithm
+from PyAthenaTests.Lib import AresClusterExAlg as ClusterExAlg
+job += ClusterExAlg('ClusterExAlg')
+
+## ease interactive prompt, if any
+##  => a no-op if the event loop is actually a batch-like
+#import AthenaPython.Helpers as IPyAthena
+#IPyAthena.setupIPyAthena()
diff --git a/AtlasTest/PyAthenaTests/share/pyathena_basic_record_retrieve.py b/AtlasTest/PyAthenaTests/share/pyathena_basic_record_retrieve.py
new file mode 100644
index 00000000000..c3ce7a4cd8a
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/pyathena_basic_record_retrieve.py
@@ -0,0 +1,41 @@
+## steer basic test of record/retrieve
+
+######################################
+if not 'EVTMAX' in dir():
+    EVTMAX=1
+if not 'OUTPUT' in dir():
+    OUTPUT = 'my.pydata.pool'
+    pass
+
+######################################
+
+# basic configuration
+import AthenaCommon.Constants as Lvl
+from AthenaCommon.AppMgr import theApp, ServiceMgr as svcMgr
+
+# job sequence
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+from PyAthenaTests.Lib import PyRetrieve, PyRecord
+job += PyRecord   ('record_test')
+job += PyRetrieve ('retrieve_test')
+
+theApp.EvtMax = EVTMAX
+
+# POOL Persistency
+import AthenaPoolCnvSvc.WriteAthenaPool
+
+job += CfgMgr.AthenaOutputStream("OutStream",
+                                  WritingTool="AthenaPoolOutputStreamTool")
+outStream = job.OutStream
+outStream.ItemList = [
+    "EventInfo#*",
+    "AthExParticles#*",
+    "AthExDecay#*",
+    "AthExElephantino#*",
+    ]
+svcMgr.PoolSvc.CheckDictionary = True
+
+# Stream's output file
+outStream.OutputFile = OUTPUT
diff --git a/AtlasTest/PyAthenaTests/share/pyclusters_jobOptions.py b/AtlasTest/PyAthenaTests/share/pyclusters_jobOptions.py
new file mode 100644
index 00000000000..00e9b687da6
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/pyclusters_jobOptions.py
@@ -0,0 +1,43 @@
+## job options file to steer the cluster example
+
+#########################
+if not 'EVTMAX' in dir():
+    EVTMAX=5
+if not 'INPUT' in dir():
+    INPUT = [ # a "reference" file from FCT
+        'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+        '/AllBasicSamples.AOD.pool.root'
+        ]
+    #INPUT = ['AOD.pool.root']
+if not 'TUPLEOUT' in dir():
+    TUPLEOUT = 'pyathena_pyclusters.root'
+    pass
+#########################
+
+## setup application for reading POOL files
+import AthenaPoolCnvSvc.ReadAthenaPool
+svcMgr.EventSelector.InputCollections = INPUT
+
+## events to process
+theApp.EvtMax = EVTMAX
+
+## setup the histo svc
+##  - register an output stream id 'py'
+##  - associate an output file
+svcMgr += CfgMgr.THistSvc()
+svcMgr.THistSvc.Output = [
+    "py DATAFILE='%s' TYP='ROOT' OPT='RECREATE'" % TUPLEOUT,
+    ]
+
+## alg sequence creation
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+## schedule the algorithm
+from PyAthenaTests.Lib import ClusterExAlg
+job += ClusterExAlg()
+
+## ease interactive prompt, if any
+##  => a no-op if the event loop is actually a batch-like
+#import AthenaPython.Helpers as IPyAthena
+#IPyAthena.setupIPyAthena()
diff --git a/AtlasTest/PyAthenaTests/share/pyevtinfo_jobOptions.py b/AtlasTest/PyAthenaTests/share/pyevtinfo_jobOptions.py
new file mode 100644
index 00000000000..cab229359b2
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/pyevtinfo_jobOptions.py
@@ -0,0 +1,41 @@
+## @file PyAthenaTests/share/pyevtinfo_jobOptions.py
+## @purpose read a POOL file and dump/print out run and event numbers
+
+###########################
+if not 'EVTMAX' in dir():
+    EVTMAX=-1
+if not 'INPUT' in dir():
+    INPUT = [
+    'filtered.pool',
+    ]
+if not 'ASCIILOG' in dir():
+    ASCIILOG = 'evtlist.ascii'
+###########################
+    
+## import the SI units
+import AthenaCommon.SystemOfUnits as Units
+
+## setup the Athena application to read-in POOL files
+import AthenaPoolCnvSvc.ReadAthenaPool
+## now the appropriate EventSelector has been added and
+## configured to the list of services
+##  --> tell this service which file to read-in
+svcMgr.EventSelector.InputCollections = INPUT
+
+## get a handle on the sequence of algorithms to be run
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+## import my algorithm and add it to the list of algorithms to be run
+from PyAthenaTests.Lib import EventInfoDumper
+job += EventInfoDumper(OutputLevel = INFO)
+job.EventInfoDumper.evtinfo = 'ByteStreamEventInfo'
+job.EventInfoDumper.filename = ASCIILOG
+
+## get a handle on the application manager
+from AthenaCommon.AppMgr import theApp
+
+## read over all events from the input file(s)
+theApp.EvtMax = EVTMAX
+
+## EOF ##
diff --git a/AtlasTest/PyAthenaTests/share/pyfilter_stream_jobOptions.py b/AtlasTest/PyAthenaTests/share/pyfilter_stream_jobOptions.py
new file mode 100644
index 00000000000..0445f01ddce
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/pyfilter_stream_jobOptions.py
@@ -0,0 +1,46 @@
+## @file PyAthenaTests/share/pyfilter_stream_jobOptions.py
+## @purpose read a POOL file and dump/print out run and event numbers and filter
+##          out one event out of 2
+
+###########################
+if not 'EVTMAX' in dir():
+    EVTMAX=-1
+if not 'INPUT' in dir():
+    INPUT = [ # a RIG "reference" file
+        '/afs/cern.ch/atlas/project/rig/referencefiles/dataStreams_ESD.AOD_50Events/data10_7TeV.00167607.physics_JetTauEtmiss.recon.ESD.f298._lb0087._SFO-4._0001.1_50Events_rel.16.0.3.8_rereco'
+        ]
+    #INPUT = ['filtered.pool',]
+if not 'OUTPUT' in dir():
+    OUTPUT = 'pyathena_basic_filtered.pool'
+if not 'ASCIILOG' in dir():
+    ASCIILOG = 'evtlist.ascii'
+###########################
+
+import AthenaCommon.Constants as Lvl
+from AthenaCommon.AppMgr import theApp, ToolSvc as toolSvc, ServiceMgr as svcMgr
+
+# configure application for reading POOL files
+import AthenaPoolCnvSvc.ReadAthenaPool
+svcMgr.EventSelector.InputCollections = INPUT
+theApp.EvtMax = EVTMAX
+
+# sequence of top algs
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+from PyAthenaTests.Lib import PyFilterAlg
+job += PyFilterAlg(evtinfo='ByteStreamEventInfo')
+job.PyFilterAlg.filename = ASCIILOG
+
+## configure the job to write out POOL files
+import AthenaPoolCnvSvc.WriteAthenaPool
+## create an output stream
+job += CfgMgr.AthenaOutputStream(
+    'OutStream',
+    WritingTool = "AthenaPoolOutputStreamTool"
+    )
+# Copy everything from the input and must force reading of all input
+# objects
+job.OutStream.OutputFile = OUTPUT
+job.OutStream.ItemList   = ['EventInfo#*']
+job.OutStream.AcceptAlgs = [job.PyFilterAlg.getName()]
diff --git a/AtlasTest/PyAthenaTests/share/pythin_basic_jobOptions.py b/AtlasTest/PyAthenaTests/share/pythin_basic_jobOptions.py
new file mode 100644
index 00000000000..fc0701965e0
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/pythin_basic_jobOptions.py
@@ -0,0 +1,67 @@
+## @file PyAthenaTests/share/pythin_basic_jobOptions.py
+## @purpose read a POOL file and thin out some elements
+
+###############################################
+if not 'EVTMAX' in dir():
+    EVTMAX=5
+if not 'INPUT' in dir():
+    INPUT = [
+    'basic_athexparticles.pool',
+    ]
+if not 'OUTPUT' in dir():
+    OUTPUT='thinned.basic_athexparticles.pool'
+###############################################
+    
+## import the SI units
+import AthenaCommon.SystemOfUnits as Units
+
+## setup the Athena application to read-in POOL files
+import AthenaPoolCnvSvc.ReadAthenaPool
+## now the appropriate EventSelector has been added and
+## configured to the list of services
+##  --> tell this service which file to read-in
+svcMgr.EventSelector.InputCollections = INPUT
+
+## get a handle on the application manager
+from AthenaCommon.AppMgr import theApp
+
+## read over all events from the input file(s)
+theApp.EvtMax = EVTMAX
+
+# basic configuration
+import AthenaCommon.Constants as Lvl
+from AthenaCommon.AppMgr import theApp, ServiceMgr as svcMgr
+
+# job sequence
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+## import my algorithm and add it to the list of algorithms to be run
+from PyAthenaTests.Lib import BasicThinner
+job += BasicThinner(name='thinner', OutputLevel = INFO)
+job.thinner.coll_type = 'AthExParticles'
+job.thinner.coll_name = 'athexparticles'
+#job.thinner.filter_fct= lambda idx,p: idx%2==0
+job.thinner.thinSvc = 'ThinningSvc/MyThinningSvc'
+
+theApp.EvtMax = EVTMAX
+
+# POOL Persistency
+import AthenaPoolCnvSvc.WriteAthenaPool
+
+job += CfgMgr.AthenaOutputStream("OutStream",
+                                  WritingTool="AthenaPoolOutputStreamTool")
+outStream = job.OutStream
+outStream.ItemList = [
+     "EventInfo#*",
+     "AthExParticles#*",
+     ]
+svcMgr.PoolSvc.CheckDictionary = True
+
+# Stream's output file
+outStream.OutputFile = OUTPUT
+
+## configure the ThinningSvc
+from AthenaServices.Configurables import ThinningSvc, createThinningSvc
+svcMgr += createThinningSvc(svcName="MyThinningSvc",
+                            outStreams=[job.OutStream])
diff --git a/AtlasTest/PyAthenaTests/share/pythin_jobOptions.py b/AtlasTest/PyAthenaTests/share/pythin_jobOptions.py
new file mode 100644
index 00000000000..1bf111cbcc3
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/pythin_jobOptions.py
@@ -0,0 +1,75 @@
+## @file PyAthenaTests/share/pythin_jobOptions.py
+## @purpose read an AOD POOL file and thin out some elements
+
+if not 'EVTMAX' in dir():
+    EVTMAX=-1
+if not 'INPUT' in dir():
+    INPUT = [
+    '/afs/cern.ch/atlas/offline/test/atlfast.aod.herwig_rel13.pool',
+    ]
+if not 'OUTPUT' in dir():
+    OUTPUT='thinned.data.pool'
+
+import os
+if os.path.exists(OUTPUT):
+    os.unlink(OUTPUT)
+    pass
+
+## import the SI units
+import AthenaCommon.SystemOfUnits as Units
+
+## setup the Athena application to read-in POOL files
+import AthenaPoolCnvSvc.ReadAthenaPool
+## now the appropriate EventSelector has been added and
+## configured to the list of services
+##  --> tell this service which file to read-in
+svcMgr.EventSelector.InputCollections = INPUT
+
+## get a handle on the sequence of algorithms to be run
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+## import my algorithm and add it to the list of algorithms to be run
+from PyAthenaTests.Lib import Thinner
+job += Thinner(OutputLevel = INFO)
+#job.Thinner.filter_fct= lambda x: x.e() > 40.*Units.GeV
+
+## get a handle on the application manager
+from AthenaCommon.AppMgr import theApp
+
+## read over all events from the input file(s)
+theApp.EvtMax = EVTMAX
+
+## configure the job to write out POOL files
+import AthenaPoolCnvSvc.WriteAthenaPool
+## create an output stream
+job += CfgMgr.AthenaOutputStream(
+    'OutStream',
+    WritingTool = "AthenaPoolOutputStreamTool"
+    )
+# Copy everything from the input and must force reading of all input
+# objects
+job.OutStream.TakeItemsFromInput = True
+job.OutStream.ForceRead          = True
+job.OutStream.OutputFile         = OUTPUT
+## configure the ThinningSvc
+from AthenaServices.Configurables import ThinningSvc, createThinningSvc
+svcMgr += createThinningSvc(svcName="MyThinningSvc",
+                            outStreams=[job.OutStream])
+
+## remap some clids/keys to new ones
+try:
+    import JetRec.ParticleJetCompatibility
+except ImportError:
+    include ('JetRec/ParticleJetCompatibility.py')
+    # FIXME: remove when bug #38062 properly fixed
+    _tk=svcMgr.AddressRemappingSvc.TypeKeyOverwriteMaps[:] + [
+        "ParticleJetContainer#AtlfastParticleJetContainer->"\
+        "JetCollection#AtlfastJetContainer"
+        ]
+    svcMgr.AddressRemappingSvc.TypeKeyOverwriteMaps = [
+        i.replace("ParticleJetContainer#", "1118613496#")
+        for i in _tk
+        ]
+    pass
+## EOF ##
diff --git a/AtlasTest/PyAthenaTests/share/pythin_mctruth_jobOptions.py b/AtlasTest/PyAthenaTests/share/pythin_mctruth_jobOptions.py
new file mode 100644
index 00000000000..465624c65b2
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/pythin_mctruth_jobOptions.py
@@ -0,0 +1,69 @@
+## @file PyAthenaTests/share/pythin_mctruth_jobOptions.py
+## @purpose read an AOD POOL file and slim the truth
+
+###################################
+if not 'EVTMAX' in dir():
+    EVTMAX=-1
+if not 'INPUT' in dir():
+    INPUT = [
+        'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+        '/AllBasicSamples.AOD.pool.root'
+        ]
+if not 'OUTPUT' in dir():
+    OUTPUT='slimmed_truth.aod.pool'
+###################################
+
+## import the SI units
+import AthenaCommon.SystemOfUnits as Units
+
+## setup the Athena application to read-in POOL files
+import AthenaPoolCnvSvc.ReadAthenaPool
+## now the appropriate EventSelector has been added and
+## configured to the list of services
+##  --> tell this service which file to read-in
+svcMgr.EventSelector.InputCollections = INPUT
+
+## get a handle on the sequence of algorithms to be run
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+## slim the truth
+from McParticleAlgs.JobOptCfg import createMcAodBuilder as McDpdBuilder
+job += McDpdBuilder(
+    name = 'McDpdBuilder',
+    inMcEvtCollection='GEN_AOD',
+    outMcEvtCollection='GEN_DPD',
+    outTruthParticles ='SpclMC_DPD',
+    doTruthEtIsolations=True,
+    filterTool=CfgMgr.OldSpclMcFilterTool(IncludeSimul=False,
+                                          IncludePartonShowers=False,
+                                          ptGammaMin = 5.*Units.GeV)
+    )
+
+
+# add a few mc-dumpers
+from PyAthenaTests.Lib import McDump
+job += McDump('mc_aod_dumper',mcName='GEN_AOD')
+job += McDump('mc_dpd_dumper',mcName='GEN_DPD')
+
+## get a handle on the application manager
+from AthenaCommon.AppMgr import theApp
+
+## read over some events from the input file(s)
+theApp.EvtMax = EVTMAX
+
+## configure the job to write out POOL files
+import AthenaPoolCnvSvc.WriteAthenaPool
+## create an output stream
+job += CfgMgr.AthenaOutputStream(
+    'OutStream',
+    WritingTool = "AthenaPoolOutputStreamTool"
+    )
+job.OutStream.TakeItemsFromInput = False
+job.OutStream.ForceRead          = True
+job.OutStream.OutputFile         = OUTPUT
+job.OutStream.ItemList = [ 'EventInfo#*',
+                           'McEventCollection#GEN_DPD',
+                           'TruthParticleContainer#SpclMC_DPD', 
+                           "TruthEtIsolationsContainer#TruthEtIsol_GEN_DPD" ]
+## EOF ##
diff --git a/AtlasTest/PyAthenaTests/share/pythin_multistream_checker_jobOptions.py b/AtlasTest/PyAthenaTests/share/pythin_multistream_checker_jobOptions.py
new file mode 100644
index 00000000000..09cbf29ed3d
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/pythin_multistream_checker_jobOptions.py
@@ -0,0 +1,48 @@
+## @file PyAthenaTests/share/pythin_multistream_checker_jobOptions.py
+## @purpose read a POOL file and inspect possibly thinned containers
+
+###############################################
+if not 'EVTMAX' in dir():
+    EVTMAX=5
+if not 'INPUT' in dir():
+    INPUT = [
+    'thinned_0.multistream_athexparticles.pool',
+    ]
+###############################################
+    
+## import the SI units
+import AthenaCommon.SystemOfUnits as Units
+
+## setup the Athena application to read-in POOL files
+import AthenaPoolCnvSvc.ReadAthenaPool
+## now the appropriate EventSelector has been added and
+## configured to the list of services
+##  --> tell this service which file to read-in
+svcMgr.EventSelector.InputCollections = INPUT
+
+## get a handle on the application manager
+from AthenaCommon.AppMgr import theApp
+
+## read over all events from the input file(s)
+theApp.EvtMax = EVTMAX
+
+# basic configuration
+import AthenaCommon.Constants as Lvl
+from AthenaCommon.AppMgr import theApp, ServiceMgr as svcMgr
+
+# job sequence
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+## import my algorithm and add it to the list of algorithms to be run
+from PyAthenaTests.Lib import ThinChecker
+
+## checking containers content
+job += ThinChecker(name='thin_checker_0', OutputLevel = INFO)
+job.thin_checker_0.coll_type = 'AthExParticles'
+job.thin_checker_0.coll_name = 'Particles_0'
+
+job += ThinChecker(name='thin_checker_1', OutputLevel = INFO)
+job.thin_checker_1.coll_type = 'AthExParticles'
+job.thin_checker_1.coll_name = 'Particles_1'
+
diff --git a/AtlasTest/PyAthenaTests/share/pythin_multistream_jobOptions.py b/AtlasTest/PyAthenaTests/share/pythin_multistream_jobOptions.py
new file mode 100644
index 00000000000..c21c4a8b322
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/pythin_multistream_jobOptions.py
@@ -0,0 +1,117 @@
+## @file PyAthenaTests/share/pythin_multistream_jobOptions.py
+## @purpose read a POOL file and thin out some elements
+
+###############################################
+if not 'EVTMAX' in dir():
+    EVTMAX=5
+if not 'INPUT' in dir():
+    INPUT = [
+    'multistream_athexparticles.pool',
+    ]
+if not 'OUTPUT_0' in dir():
+    OUTPUT='thinned_0.multistream_athexparticles.pool'
+if not 'OUTPUT_1' in dir():
+    OUTPUT='thinned_1.multistream_athexparticles.pool'
+if not 'OUTPUT_NOTHINNING' in dir():
+    OUTPUT='not_thinned.multistream_athexparticles.pool'
+###############################################
+    
+## import the SI units
+import AthenaCommon.SystemOfUnits as Units
+
+## setup the Athena application to read-in POOL files
+import AthenaPoolCnvSvc.ReadAthenaPool
+## now the appropriate EventSelector has been added and
+## configured to the list of services
+##  --> tell this service which file to read-in
+svcMgr.EventSelector.InputCollections = INPUT
+
+## get a handle on the application manager
+from AthenaCommon.AppMgr import theApp
+
+## read over all events from the input file(s)
+theApp.EvtMax = EVTMAX
+
+# basic configuration
+import AthenaCommon.Constants as Lvl
+from AthenaCommon.AppMgr import theApp, ServiceMgr as svcMgr
+
+# job sequence
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+## import my algorithm and add it to the list of algorithms to be run
+from PyAthenaTests.Lib import BasicThinner
+
+## thin out odds
+job += BasicThinner(name='thinner_0', OutputLevel = INFO)
+job.thinner_0.coll_type = 'AthExParticles'
+job.thinner_0.coll_name = 'Particles_0'
+job.thinner_0.filter_fct= lambda idx,p: idx%2!=0
+job.thinner_0.thinSvc = 'ThinningSvc/ThinningSvc_0'
+
+## thin out evens
+job += BasicThinner(name='thinner_1', OutputLevel = INFO)
+job.thinner_1.coll_type = 'AthExParticles'
+job.thinner_1.coll_name = 'Particles_1'
+job.thinner_1.filter_fct= lambda idx,p: idx%2==0
+job.thinner_1.thinSvc = 'ThinningSvc/ThinningSvc_1'
+
+
+theApp.EvtMax = EVTMAX
+
+# POOL Persistency
+import AthenaPoolCnvSvc.WriteAthenaPool
+
+###############################################################################
+###------------ output streams ------------------
+
+## thinning of odds elements (1,3,5,...)
+#########################################
+job += CfgMgr.AthenaOutputStream("OutStream_0",
+                                  WritingTool="AthenaPoolOutputStreamTool")
+outStream = job.OutStream_0
+outStream.ItemList = [
+     "EventInfo#*",
+     "AthExParticles#*",
+     ]
+svcMgr.PoolSvc.CheckDictionary = True
+
+# Stream's output file
+outStream.OutputFile = OUTPUT_0
+
+###
+## no-thinning
+#########################################
+job += CfgMgr.AthenaOutputStream("OutStream_nothinning",
+                                  WritingTool="AthenaPoolOutputStreamTool")
+outStream = job.OutStream_nothinning
+outStream.ItemList = [
+     "EventInfo#*",
+     "AthExParticles#*",
+     ]
+svcMgr.PoolSvc.CheckDictionary = True
+
+# Stream's output file
+outStream.OutputFile = OUTPUT_NOTHINNING
+
+## thinning of evens elements (0,2,4,...)
+#########################################
+job += CfgMgr.AthenaOutputStream("OutStream_1",
+                                  WritingTool="AthenaPoolOutputStreamTool")
+outStream = job.OutStream_1
+outStream.ItemList = [
+     "EventInfo#*",
+     "AthExParticles#*",
+     ]
+svcMgr.PoolSvc.CheckDictionary = True
+
+# Stream's output file
+outStream.OutputFile = OUTPUT_1
+
+## configure the ThinningSvc
+from AthenaServices.Configurables import ThinningSvc, createThinningSvc
+svcMgr += createThinningSvc(svcName="ThinningSvc_0",
+                            outStreams=[job.OutStream_0])
+svcMgr += createThinningSvc(svcName="ThinningSvc_1",
+                            outStreams=[job.OutStream_1])
diff --git a/AtlasTest/PyAthenaTests/share/pytrigdec_jobOptions.py b/AtlasTest/PyAthenaTests/share/pytrigdec_jobOptions.py
new file mode 100644
index 00000000000..27dabbc5ddb
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/pytrigdec_jobOptions.py
@@ -0,0 +1,84 @@
+## testing trig-decision tool
+
+##############################
+if not 'INPUT' in dir():
+    INPUT = [ # a "reference" file from FCT
+        'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+        '/AllBasicSamples.AOD.pool.root'
+        ]
+    #INPUT = ['AOD.pool.root']
+if not 'EVTMAX' in dir():
+    EVTMAX=-1
+if not 'OUTPUT' in dir():
+    OUTPUT='trig_filtered.pool'
+if not 'ASCIILOG' in dir():
+    ASCIILOG='trig_passed_evts.ascii'
+##############################
+
+import AthenaCommon.Constants as Lvl
+from AthenaCommon.AppMgr import theApp, ToolSvc as toolSvc, ServiceMgr as svcMgr
+
+## detector description version
+DetDescrVersion="ATLAS-CSC-02-00-00"
+
+# configure application for reading POOL files
+import AthenaPoolCnvSvc.ReadAthenaPool
+svcMgr.EventSelector.InputCollections = INPUT
+theApp.EvtMax = EVTMAX
+
+# sequence of top algs
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+from PyAthenaTests.Lib import TrigDecTestAlg
+job += TrigDecTestAlg(OutputLevel=Lvl.DEBUG)
+job.TrigDecTestAlg.filename = ASCIILOG
+
+## trigger configuration service
+from AthenaCommon.GlobalFlags import GlobalFlags
+GlobalFlags.DetGeo.set_atlas()
+import IOVDbSvc.IOVDb 
+from IOVDbSvc.CondDB import conddb
+conddb.addFolder("TRIGGER","/TRIGGER/HLT/Menu <tag>HEAD</tag>") 
+conddb.addFolder("TRIGGER","/TRIGGER/HLT/HltConfigKeys <tag>HEAD</tag>")
+conddb.addFolder("TRIGGER","/TRIGGER/LVL1/Lvl1ConfigKey <tag>HEAD</tag>")
+conddb.addFolder("TRIGGER","/TRIGGER/LVL1/Menu <tag>HEAD</tag>")
+conddb.addFolder("TRIGGER","/TRIGGER/LVL1/Prescales <tag>HEAD</tag>")
+
+## set up trigger decision tool
+tdt = CfgMgr.Trig__TrigDecisionTool(OutputLevel=Lvl.INFO)
+toolSvc += tdt
+
+from RecExConfig.RecFlags  import rec
+rec.readAOD=True
+
+from TriggerJobOpts.TriggerFlags import TriggerFlags
+TriggerFlags.doTriggerConfigOnly = True
+
+## setup configuration service
+from TrigConfigSvc.TrigConfigSvcConfig import DSConfigSvc, SetupTrigConfigSvc
+dscfg = DSConfigSvc()
+dscfg.OutputLevel=Lvl.VERBOSE
+svcMgr += dscfg
+
+trigcfg = SetupTrigConfigSvc()
+trigcfg.OutputLevel=Lvl.VERBOSE
+trigcfg.SetStates('ds')
+trigcfg.InitialiseSvc()
+#svcMgr += trigcfg
+
+#theApp.ReflexPluginDebugLevel = 1000
+
+
+## configure the job to write out POOL files
+import AthenaPoolCnvSvc.WriteAthenaPool
+## create an output stream
+job += CfgMgr.AthenaOutputStream(
+    'OutStream',
+    WritingTool = "AthenaPoolOutputStreamTool"
+    )
+# Copy everything from the input and must force reading of all input
+# objects
+job.OutStream.OutputFile = OUTPUT
+job.OutStream.ItemList   = ['EventInfo#*']
+job.OutStream.AcceptAlgs = [job.TrigDecTestAlg.getName()]
diff --git a/AtlasTest/PyAthenaTests/share/utest_thin_cells_release_140100.py b/AtlasTest/PyAthenaTests/share/utest_thin_cells_release_140100.py
new file mode 100644
index 00000000000..9e14b2b3720
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/utest_thin_cells_release_140100.py
@@ -0,0 +1,38 @@
+############################
+if not 'INPUT' in dir():
+    INPUT=[
+        'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+        '/AllBasicSamples.ESD.pool.root'
+        ]
+    pass
+if not 'OUTPUT' in dir():
+    OUTPUT = 'thinned-cells.pool'
+    pass
+############################
+
+PoolESDInput = INPUT
+PoolESDOutput= 'dummy.esd.pool'
+
+# ESD reprocessing
+include ('RecExCommon/esdtoesd.py')
+svcMgr.GeoModelSvc.AtlasVersion = 'ATLAS-CSC-05-01-00'
+
+include('PyAthenaTests/pythin_jobOptions.py')
+
+job.Thinner.coll_type='CaloCellContainer'
+job.Thinner.coll_name='AllCalo'
+job.Thinner._filter_cnt = 0
+def filter_fct(x):
+    self = PyAthena.algs.Thinner
+    cnt = self._filter_cnt
+    dec = cnt%2==0
+    self._filter_cnt += 1
+    return dec
+job.Thinner.filter_fct = filter_fct
+
+job.OutStream.TakeItemsFromInput = True
+job.OutStream.ForceRead = True
+
+# make sure our thinned stream is the only one
+del job.StreamESD
+del job.StreamESD_FH
diff --git a/AtlasTest/PyAthenaTests/share/utest_thin_eles_release_140100.py b/AtlasTest/PyAthenaTests/share/utest_thin_eles_release_140100.py
new file mode 100644
index 00000000000..ed7d5e5c099
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/utest_thin_eles_release_140100.py
@@ -0,0 +1,31 @@
+############################
+if not 'INPUT' in dir():
+    INPUT=[
+        'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+        '/AllBasicSamples.AOD.pool.root'
+        ]
+    pass
+if not 'OUTPUT' in dir():
+    OUTPUT = 'thinned-eles.pool'
+    pass
+############################
+
+PoolAODInput = INPUT
+PoolAODOutput= 'dummy.aod.pool'
+
+# AOD reprocessing
+include ('RecExCommon/aodtoaod.py')
+svcMgr.GeoModelSvc.AtlasVersion = 'ATLAS-CSC-05-01-00'
+
+include('PyAthenaTests/pythin_jobOptions.py')
+del job.StreamAOD
+del job.StreamAOD_FH
+del job.Thinner
+
+job.insert(-1, Thinner('thin_eles',
+                        coll_type='ElectronContainer',
+                        coll_name='ElectronAODCollection'))
+job.OutStream.TakeItemsFromInput = False
+job.OutStream.ForceRead = False
+job.OutStream.ItemList = [ 'EventInfo#*',
+                           'ElectronContainer#*',]
diff --git a/AtlasTest/PyAthenaTests/share/utest_thin_jets_release_140100.py b/AtlasTest/PyAthenaTests/share/utest_thin_jets_release_140100.py
new file mode 100644
index 00000000000..44307476589
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/utest_thin_jets_release_140100.py
@@ -0,0 +1,35 @@
+############################
+if not 'INPUT' in dir():
+    INPUT=[
+        'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+        '/AllBasicSamples.AOD.pool.root'
+        ]
+    pass
+if not 'OUTPUT' in dir():
+    OUTPUT = 'thinned-jets.pool'
+    pass
+############################
+
+PoolAODInput = INPUT
+PoolAODOutput= 'dummy.aod.pool'
+
+# AOD reprocessing
+include ('RecExCommon/aodtoaod.py')
+svcMgr.GeoModelSvc.AtlasVersion = 'ATLAS-CSC-05-01-00'
+
+include('PyAthenaTests/pythin_jobOptions.py')
+del job.StreamAOD
+del job.StreamAOD_FH
+del job.Thinner
+
+job.insert(-1, Thinner('thin_jets',
+                       coll_type='JetCollection',
+                       coll_name='Cone4H1TowerJets'))
+job.OutStream.TakeItemsFromInput = False
+job.OutStream.ForceRead = False
+job.OutStream.ItemList = [ 'EventInfo#*',
+                           'JetCollection#*',
+                           'JetKeyDescriptor#*' ]
+
+from DPDUtils.DpdLib import JetSlimmer
+#job.insert(-1, JetSlimmer('jet_slimmer'))
diff --git a/AtlasTest/PyAthenaTests/share/utest_thin_muons_release_140100.py b/AtlasTest/PyAthenaTests/share/utest_thin_muons_release_140100.py
new file mode 100644
index 00000000000..f1c755da7fa
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/utest_thin_muons_release_140100.py
@@ -0,0 +1,31 @@
+############################
+if not 'INPUT' in dir():
+    INPUT=[
+        'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+        '/AllBasicSamples.AOD.pool.root'
+        ]
+    pass
+if not 'OUTPUT' in dir():
+    OUTPUT = 'thinned-muons.pool'
+    pass
+############################
+
+PoolAODInput = INPUT
+PoolAODOutput= 'dummy.aod.pool'
+
+# AOD reprocessing
+include ('RecExCommon/aodtoaod.py')
+svcMgr.GeoModelSvc.AtlasVersion = 'ATLAS-CSC-05-01-00'
+
+include('PyAthenaTests/pythin_jobOptions.py')
+del job.StreamAOD
+del job.StreamAOD_FH
+del job.Thinner
+
+job.insert(-1, Thinner('thin_muons',
+                       coll_type='Analysis::MuonContainer',
+                       coll_name='MuidMuonCollection'))
+job.OutStream.TakeItemsFromInput = False
+job.OutStream.ForceRead = False
+job.OutStream.ItemList = [ 'EventInfo#*',
+                           'Analysis::MuonContainer#*',]
diff --git a/AtlasTest/PyAthenaTests/share/utest_thin_photons_release_140100.py b/AtlasTest/PyAthenaTests/share/utest_thin_photons_release_140100.py
new file mode 100644
index 00000000000..f945e3aa5a6
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/utest_thin_photons_release_140100.py
@@ -0,0 +1,31 @@
+############################
+if not 'INPUT' in dir():
+    INPUT=[
+        'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+        '/AllBasicSamples.AOD.pool.root'
+        ]
+    pass
+if not 'OUTPUT' in dir():
+    OUTPUT = 'thinned-photons.pool'
+    pass
+############################
+
+PoolAODInput = INPUT
+PoolAODOutput= 'dummy.aod.pool'
+
+# AOD reprocessing
+include ('RecExCommon/aodtoaod.py')
+svcMgr.GeoModelSvc.AtlasVersion = 'ATLAS-CSC-05-01-00'
+
+include('PyAthenaTests/pythin_jobOptions.py')
+del job.StreamAOD
+del job.StreamAOD_FH
+del job.Thinner
+
+job.insert(-1, Thinner('thin_photons',
+                       coll_type='PhotonContainer',
+                       coll_name='PhotonAODCollection'))
+job.OutStream.TakeItemsFromInput = False
+job.OutStream.ForceRead = False
+job.OutStream.ItemList = [ 'EventInfo#*',
+                           'PhotonContainer#*',]
diff --git a/AtlasTest/PyAthenaTests/share/utest_thin_taus_release_140100.py b/AtlasTest/PyAthenaTests/share/utest_thin_taus_release_140100.py
new file mode 100644
index 00000000000..c6b1d282856
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/share/utest_thin_taus_release_140100.py
@@ -0,0 +1,32 @@
+############################
+if not 'INPUT' in dir():
+    INPUT=[
+        'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+        '/AllBasicSamples.AOD.pool.root'
+        ]
+    pass
+if not 'OUTPUT' in dir():
+    OUTPUT = 'thinned-taus.pool'
+    pass
+############################
+
+PoolAODInput = INPUT
+PoolAODOutput= 'dummy.aod.pool'
+
+# AOD reprocessing
+include ('RecExCommon/aodtoaod.py')
+svcMgr.GeoModelSvc.AtlasVersion = 'ATLAS-CSC-05-01-00'
+
+include('PyAthenaTests/pythin_jobOptions.py')
+del job.StreamAOD
+del job.StreamAOD_FH
+del job.Thinner
+
+job.insert(-1, Thinner('thin_taus',
+                       coll_type='Analysis::TauJetContainer',
+                       coll_name='TauRecContainer'))
+job.OutStream.TakeItemsFromInput = False
+job.OutStream.ForceRead = False
+job.OutStream.ItemList = [ 'EventInfo#*',
+                           'Analysis::TauJetContainer#*',
+                           "TrackCollection#*",]
diff --git a/AtlasTest/PyAthenaTests/test/PyAthenaTests.xml b/AtlasTest/PyAthenaTests/test/PyAthenaTests.xml
new file mode 100644
index 00000000000..84db819d5f3
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/PyAthenaTests.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<atn>
+
+   <TEST name="test_pyathena_base" type="script" suite="PyAthena">
+      <package_atn>AtlasTest/PyAthenaTests</package_atn>
+      <options_atn>utest_pyathena_base.py</options_atn>
+      <timelimit>10</timelimit>
+      <author> Sebastien Binet </author>
+      <mailto> binet@cern.ch</mailto>
+      <expectations>
+         <successMessage>OK</successMessage>
+         <returnValue>0</returnValue>
+      </expectations>
+   </TEST>
+
+   <!-- <TEST name="test_pyathena_thinner" type="script" suite="PyAthena"> -->
+   <!--    <package_atn>AtlasTest/PyAthenaTests</package_atn> -->
+   <!--    <options_atn>utest_pyathena_pythinner.py</options_atn> -->
+   <!--    <timelimit>40</timelimit> -->
+   <!--    <author> Sebastien Binet </author> -->
+   <!--    <mailto> binet@cern.ch</mailto> -->
+   <!--    <expectations> -->
+   <!--       <successMessage>OK</successMessage> -->
+   <!--       <returnValue>0</returnValue> -->
+   <!--    </expectations> -->
+   <!-- </TEST> -->
+
+   <!-- <TEST name="test_pyathena_trigdec" type="script" suite="PyAthena"> -->
+   <!--    <package_atn>AtlasTest/PyAthenaTests</package_atn> -->
+   <!--    <options_atn>utest_pyathena_pytrigdec.py</options_atn> -->
+   <!--    <timelimit>10</timelimit> -->
+   <!--    <author> Sebastien Binet </author> -->
+   <!--    <mailto> binet@cern.ch</mailto> -->
+   <!--    <expectations> -->
+   <!--       <successMessage>OK</successMessage> -->
+   <!--       <returnValue>0</returnValue> -->
+   <!--    </expectations> -->
+   <!-- </TEST> -->
+
+   <!-- <TEST name="test_pyathena_clusters" type="script" suite="PyAthena"> -->
+   <!--    <package_atn>AtlasTest/PyAthenaTests</package_atn> -->
+   <!--    <options_atn>utest_pyathena_pyclusters.py</options_atn> -->
+   <!--    <timelimit>10</timelimit> -->
+   <!--    <author> Sebastien Binet </author> -->
+   <!--    <mailto> binet@cern.ch</mailto> -->
+   <!--    <expectations> -->
+   <!--       <successMessage>OK</successMessage> -->
+   <!--       <returnValue>0</returnValue> -->
+   <!--    </expectations> -->
+   <!-- </TEST> -->
+
+   <!-- <TEST name="test_pyathena_pyfdr" type="script" suite="PyAthena"> -->
+   <!--    <package_atn>AtlasTest/PyAthenaTests</package_atn> -->
+   <!--    <options_atn>utest_pyathena_pyfdr.py</options_atn> -->
+   <!--    <timelimit>10</timelimit> -->
+   <!--    <author> Sebastien Binet </author> -->
+   <!--    <mailto> binet@cern.ch</mailto> -->
+   <!--    <expectations> -->
+   <!--       <successMessage>OK</successMessage> -->
+   <!--       <returnValue>0</returnValue> -->
+   <!--    </expectations> -->
+   <!-- </TEST> -->
+
+   <!-- <TEST name="pyutils.athfile" type="script" suite="pyutils"> -->
+   <!--    <package_atn>AtlasTest/PyAthenaTests</package_atn> -->
+   <!--    <options_atn>python -c 'import PyUtils.AthFile.tests as af; af.main()'</options_atn> -->
+   <!--    <timelimit>50</timelimit> -->
+   <!--    <author> Sebastien Binet </author> -->
+   <!--    <mailto> binet@cern.ch </mailto> -->
+   <!--    <expectations> -->
+   <!--       <successMessage>OK</successMessage> -->
+   <!--       <returnValue>0</returnValue> -->
+   <!--    </expectations> -->
+   <!-- </TEST> -->
+
+</atn>
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_basic_record_retrieve.ref b/AtlasTest/PyAthenaTests/test/pyathena_basic_record_retrieve.ref
new file mode 100644
index 00000000000..2d606bba43b
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_basic_record_retrieve.ref
@@ -0,0 +1,8 @@
+Py:record_test       INFO initializing record_test
+Py:retrieve_test     INFO initializing retrieve_test
+Py:record_test       INFO executing record_test...
+Py:record_test       INFO all good: True
+Py:retrieve_test     INFO executing retrieve_test...
+Py:retrieve_test     INFO all good: True
+Py:record_test       INFO finalizing record_test...
+Py:retrieve_test     INFO finalizing retrieve_test...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pyclusters_rel140100.ref b/AtlasTest/PyAthenaTests/test/pyathena_pyclusters_rel140100.ref
new file mode 100644
index 00000000000..9ea5ae933d5
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pyclusters_rel140100.ref
@@ -0,0 +1,234 @@
+Py:ClusterExAlg      INFO ==> initialize
+Py:ClusterExAlg      INFO reading clusters from ['CaloCalTopoCluster']
+Py:ClusterExAlg      INFO ==> execute
+Py:ClusterExAlg      INFO event #0 has 475 clusters
+Py:ClusterExAlg      INFO cluster #  0 has energy    6.087
+Py:ClusterExAlg      INFO cluster #  0 has moment #201 with value 1112.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #202 with value 8960.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #501 with value  219.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #601 with value    0.490
+Py:ClusterExAlg      INFO cluster #  0 has moment #602 with value    0.539
+Py:ClusterExAlg      INFO cluster #  0 has moment #702 with value    0.562
+Py:ClusterExAlg      INFO cluster #  0 has moment #804 with value    1.016
+Py:ClusterExAlg      INFO cluster #  0 has moment #806 with value    0.000
+Py:ClusterExAlg      INFO cluster #100 has energy    4.201
+Py:ClusterExAlg      INFO cluster #100 has moment #201 with value 2752.000
+Py:ClusterExAlg      INFO cluster #100 has moment #202 with value 62464.000
+Py:ClusterExAlg      INFO cluster #100 has moment #501 with value  620.000
+Py:ClusterExAlg      INFO cluster #100 has moment #601 with value    0.801
+Py:ClusterExAlg      INFO cluster #100 has moment #602 with value    0.957
+Py:ClusterExAlg      INFO cluster #100 has moment #702 with value    0.165
+Py:ClusterExAlg      INFO cluster #100 has moment #804 with value    0.002
+Py:ClusterExAlg      INFO cluster #100 has moment #806 with value    0.221
+Py:ClusterExAlg      INFO cluster #200 has energy    3.900
+Py:ClusterExAlg      INFO cluster #200 has moment #201 with value 1200.000
+Py:ClusterExAlg      INFO cluster #200 has moment #202 with value 1464.000
+Py:ClusterExAlg      INFO cluster #200 has moment #501 with value  225.000
+Py:ClusterExAlg      INFO cluster #200 has moment #601 with value    0.676
+Py:ClusterExAlg      INFO cluster #200 has moment #602 with value    0.322
+Py:ClusterExAlg      INFO cluster #200 has moment #702 with value    0.158
+Py:ClusterExAlg      INFO cluster #200 has moment #804 with value    0.002
+Py:ClusterExAlg      INFO cluster #200 has moment #806 with value    0.301
+Py:ClusterExAlg      INFO cluster #300 has energy    3.104
+Py:ClusterExAlg      INFO cluster #300 has moment #201 with value  644.000
+Py:ClusterExAlg      INFO cluster #300 has moment #202 with value 38144.000
+Py:ClusterExAlg      INFO cluster #300 has moment #501 with value  296.000
+Py:ClusterExAlg      INFO cluster #300 has moment #601 with value    0.602
+Py:ClusterExAlg      INFO cluster #300 has moment #602 with value    0.395
+Py:ClusterExAlg      INFO cluster #300 has moment #702 with value    0.134
+Py:ClusterExAlg      INFO cluster #300 has moment #804 with value    0.001
+Py:ClusterExAlg      INFO cluster #300 has moment #806 with value    0.746
+Py:ClusterExAlg      INFO cluster #400 has energy    2.676
+Py:ClusterExAlg      INFO cluster #400 has moment #201 with value  724.000
+Py:ClusterExAlg      INFO cluster #400 has moment #202 with value 11584.000
+Py:ClusterExAlg      INFO cluster #400 has moment #501 with value  272.000
+Py:ClusterExAlg      INFO cluster #400 has moment #601 with value    0.543
+Py:ClusterExAlg      INFO cluster #400 has moment #602 with value    0.605
+Py:ClusterExAlg      INFO cluster #400 has moment #702 with value    0.264
+Py:ClusterExAlg      INFO cluster #400 has moment #804 with value    0.001
+Py:ClusterExAlg      INFO cluster #400 has moment #806 with value    0.938
+Py:ClusterExAlg      INFO ==> execute
+Py:ClusterExAlg      INFO event #1 has 431 clusters
+Py:ClusterExAlg      INFO cluster #  0 has energy    4.475
+Py:ClusterExAlg      INFO cluster #  0 has moment #201 with value 5472.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #202 with value 247808.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #501 with value  692.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #601 with value    0.863
+Py:ClusterExAlg      INFO cluster #  0 has moment #602 with value    0.570
+Py:ClusterExAlg      INFO cluster #  0 has moment #702 with value    0.418
+Py:ClusterExAlg      INFO cluster #  0 has moment #804 with value    0.002
+Py:ClusterExAlg      INFO cluster #  0 has moment #806 with value    0.387
+Py:ClusterExAlg      INFO cluster #100 has energy    3.614
+Py:ClusterExAlg      INFO cluster #100 has moment #201 with value 5216.000
+Py:ClusterExAlg      INFO cluster #100 has moment #202 with value 51456.000
+Py:ClusterExAlg      INFO cluster #100 has moment #501 with value  446.000
+Py:ClusterExAlg      INFO cluster #100 has moment #601 with value    0.891
+Py:ClusterExAlg      INFO cluster #100 has moment #602 with value    0.812
+Py:ClusterExAlg      INFO cluster #100 has moment #702 with value    0.109
+Py:ClusterExAlg      INFO cluster #100 has moment #804 with value    0.001
+Py:ClusterExAlg      INFO cluster #100 has moment #806 with value    0.660
+Py:ClusterExAlg      INFO cluster #200 has energy    3.364
+Py:ClusterExAlg      INFO cluster #200 has moment #201 with value 1232.000
+Py:ClusterExAlg      INFO cluster #200 has moment #202 with value 1616.000
+Py:ClusterExAlg      INFO cluster #200 has moment #501 with value  206.000
+Py:ClusterExAlg      INFO cluster #200 has moment #601 with value    0.467
+Py:ClusterExAlg      INFO cluster #200 has moment #602 with value    0.177
+Py:ClusterExAlg      INFO cluster #200 has moment #702 with value    0.629
+Py:ClusterExAlg      INFO cluster #200 has moment #804 with value    0.001
+Py:ClusterExAlg      INFO cluster #200 has moment #806 with value    0.064
+Py:ClusterExAlg      INFO cluster #300 has energy    2.916
+Py:ClusterExAlg      INFO cluster #300 has moment #201 with value  860.000
+Py:ClusterExAlg      INFO cluster #300 has moment #202 with value 8768.000
+Py:ClusterExAlg      INFO cluster #300 has moment #501 with value  165.000
+Py:ClusterExAlg      INFO cluster #300 has moment #601 with value    0.445
+Py:ClusterExAlg      INFO cluster #300 has moment #602 with value    0.342
+Py:ClusterExAlg      INFO cluster #300 has moment #702 with value    0.439
+Py:ClusterExAlg      INFO cluster #300 has moment #804 with value    0.001
+Py:ClusterExAlg      INFO cluster #300 has moment #806 with value    1.000
+Py:ClusterExAlg      INFO cluster #400 has energy    2.145
+Py:ClusterExAlg      INFO cluster #400 has moment #201 with value 1168.000
+Py:ClusterExAlg      INFO cluster #400 has moment #202 with value 8704.000
+Py:ClusterExAlg      INFO cluster #400 has moment #501 with value  113.500
+Py:ClusterExAlg      INFO cluster #400 has moment #601 with value    0.590
+Py:ClusterExAlg      INFO cluster #400 has moment #602 with value    0.455
+Py:ClusterExAlg      INFO cluster #400 has moment #702 with value    0.264
+Py:ClusterExAlg      INFO cluster #400 has moment #804 with value    0.001
+Py:ClusterExAlg      INFO cluster #400 has moment #806 with value    1.000
+Py:ClusterExAlg      INFO ==> execute
+Py:ClusterExAlg      INFO event #2 has 505 clusters
+Py:ClusterExAlg      INFO cluster #  0 has energy    5.016
+Py:ClusterExAlg      INFO cluster #  0 has moment #201 with value 4928.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #202 with value 49664.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #501 with value  229.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #601 with value    0.930
+Py:ClusterExAlg      INFO cluster #  0 has moment #602 with value    0.945
+Py:ClusterExAlg      INFO cluster #  0 has moment #702 with value    0.119
+Py:ClusterExAlg      INFO cluster #  0 has moment #804 with value    0.005
+Py:ClusterExAlg      INFO cluster #  0 has moment #806 with value    0.049
+Py:ClusterExAlg      INFO cluster #100 has energy    3.030
+Py:ClusterExAlg      INFO cluster #100 has moment #201 with value 2064.000
+Py:ClusterExAlg      INFO cluster #100 has moment #202 with value 8896.000
+Py:ClusterExAlg      INFO cluster #100 has moment #501 with value  302.000
+Py:ClusterExAlg      INFO cluster #100 has moment #601 with value    0.660
+Py:ClusterExAlg      INFO cluster #100 has moment #602 with value    0.613
+Py:ClusterExAlg      INFO cluster #100 has moment #702 with value    0.279
+Py:ClusterExAlg      INFO cluster #100 has moment #804 with value    0.000
+Py:ClusterExAlg      INFO cluster #100 has moment #806 with value    1.000
+Py:ClusterExAlg      INFO cluster #200 has energy    2.738
+Py:ClusterExAlg      INFO cluster #200 has moment #201 with value 5280.000
+Py:ClusterExAlg      INFO cluster #200 has moment #202 with value 1168.000
+Py:ClusterExAlg      INFO cluster #200 has moment #501 with value  225.000
+Py:ClusterExAlg      INFO cluster #200 has moment #601 with value    0.000
+Py:ClusterExAlg      INFO cluster #200 has moment #602 with value    0.000
+Py:ClusterExAlg      INFO cluster #200 has moment #702 with value    0.961
+Py:ClusterExAlg      INFO cluster #200 has moment #804 with value    0.001
+Py:ClusterExAlg      INFO cluster #200 has moment #806 with value    0.750
+Py:ClusterExAlg      INFO cluster #300 has energy    3.015
+Py:ClusterExAlg      INFO cluster #300 has moment #201 with value 1176.000
+Py:ClusterExAlg      INFO cluster #300 has moment #202 with value 4800.000
+Py:ClusterExAlg      INFO cluster #300 has moment #501 with value  246.000
+Py:ClusterExAlg      INFO cluster #300 has moment #601 with value    0.648
+Py:ClusterExAlg      INFO cluster #300 has moment #602 with value    0.566
+Py:ClusterExAlg      INFO cluster #300 has moment #702 with value    0.199
+Py:ClusterExAlg      INFO cluster #300 has moment #804 with value    0.000
+Py:ClusterExAlg      INFO cluster #300 has moment #806 with value    0.906
+Py:ClusterExAlg      INFO cluster #400 has energy    2.340
+Py:ClusterExAlg      INFO cluster #400 has moment #201 with value 4544.000
+Py:ClusterExAlg      INFO cluster #400 has moment #202 with value 44288.000
+Py:ClusterExAlg      INFO cluster #400 has moment #501 with value 1024.000
+Py:ClusterExAlg      INFO cluster #400 has moment #601 with value    0.789
+Py:ClusterExAlg      INFO cluster #400 has moment #602 with value    0.283
+Py:ClusterExAlg      INFO cluster #400 has moment #702 with value    0.465
+Py:ClusterExAlg      INFO cluster #400 has moment #804 with value    0.000
+Py:ClusterExAlg      INFO cluster #400 has moment #806 with value    0.766
+Py:ClusterExAlg      INFO cluster #500 has energy   -2.099
+Py:ClusterExAlg      INFO cluster #500 has moment #201 with value 5056.000
+Py:ClusterExAlg      INFO cluster #500 has moment #202 with value 5280.000
+Py:ClusterExAlg      INFO cluster #500 has moment #501 with value   53.000
+Py:ClusterExAlg      INFO cluster #500 has moment #601 with value    0.523
+Py:ClusterExAlg      INFO cluster #500 has moment #602 with value    0.379
+Py:ClusterExAlg      INFO cluster #500 has moment #702 with value    0.586
+Py:ClusterExAlg      INFO cluster #500 has moment #804 with value    0.000
+Py:ClusterExAlg      INFO cluster #500 has moment #806 with value    1.000
+Py:ClusterExAlg      INFO ==> execute
+Py:ClusterExAlg      INFO event #3 has 349 clusters
+Py:ClusterExAlg      INFO cluster #  0 has energy    4.824
+Py:ClusterExAlg      INFO cluster #  0 has moment #201 with value 1416.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #202 with value 12672.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #501 with value  218.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #601 with value    0.559
+Py:ClusterExAlg      INFO cluster #  0 has moment #602 with value    0.637
+Py:ClusterExAlg      INFO cluster #  0 has moment #702 with value    0.346
+Py:ClusterExAlg      INFO cluster #  0 has moment #804 with value    0.030
+Py:ClusterExAlg      INFO cluster #  0 has moment #806 with value    0.879
+Py:ClusterExAlg      INFO cluster #100 has energy    4.052
+Py:ClusterExAlg      INFO cluster #100 has moment #201 with value  820.000
+Py:ClusterExAlg      INFO cluster #100 has moment #202 with value 17792.000
+Py:ClusterExAlg      INFO cluster #100 has moment #501 with value  251.000
+Py:ClusterExAlg      INFO cluster #100 has moment #601 with value    0.471
+Py:ClusterExAlg      INFO cluster #100 has moment #602 with value    0.793
+Py:ClusterExAlg      INFO cluster #100 has moment #702 with value    0.281
+Py:ClusterExAlg      INFO cluster #100 has moment #804 with value    0.003
+Py:ClusterExAlg      INFO cluster #100 has moment #806 with value    0.297
+Py:ClusterExAlg      INFO cluster #200 has energy    3.466
+Py:ClusterExAlg      INFO cluster #200 has moment #201 with value  968.000
+Py:ClusterExAlg      INFO cluster #200 has moment #202 with value 13632.000
+Py:ClusterExAlg      INFO cluster #200 has moment #501 with value 1208.000
+Py:ClusterExAlg      INFO cluster #200 has moment #601 with value    0.586
+Py:ClusterExAlg      INFO cluster #200 has moment #602 with value    0.785
+Py:ClusterExAlg      INFO cluster #200 has moment #702 with value    0.201
+Py:ClusterExAlg      INFO cluster #200 has moment #804 with value    0.001
+Py:ClusterExAlg      INFO cluster #200 has moment #806 with value    0.402
+Py:ClusterExAlg      INFO cluster #300 has energy    3.033
+Py:ClusterExAlg      INFO cluster #300 has moment #201 with value  672.000
+Py:ClusterExAlg      INFO cluster #300 has moment #202 with value 15808.000
+Py:ClusterExAlg      INFO cluster #300 has moment #501 with value  280.000
+Py:ClusterExAlg      INFO cluster #300 has moment #601 with value    0.451
+Py:ClusterExAlg      INFO cluster #300 has moment #602 with value    0.547
+Py:ClusterExAlg      INFO cluster #300 has moment #702 with value    0.285
+Py:ClusterExAlg      INFO cluster #300 has moment #804 with value    0.000
+Py:ClusterExAlg      INFO cluster #300 has moment #806 with value    0.195
+Py:ClusterExAlg      INFO ==> execute
+Py:ClusterExAlg      INFO event #4 has 358 clusters
+Py:ClusterExAlg      INFO cluster #  0 has energy    5.157
+Py:ClusterExAlg      INFO cluster #  0 has moment #201 with value 9344.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #202 with value 236544.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #501 with value  660.000
+Py:ClusterExAlg      INFO cluster #  0 has moment #601 with value    0.957
+Py:ClusterExAlg      INFO cluster #  0 has moment #602 with value    0.785
+Py:ClusterExAlg      INFO cluster #  0 has moment #702 with value    0.196
+Py:ClusterExAlg      INFO cluster #  0 has moment #804 with value    0.007
+Py:ClusterExAlg      INFO cluster #  0 has moment #806 with value    0.738
+Py:ClusterExAlg      INFO cluster #100 has energy    4.261
+Py:ClusterExAlg      INFO cluster #100 has moment #201 with value  306.000
+Py:ClusterExAlg      INFO cluster #100 has moment #202 with value 16640.000
+Py:ClusterExAlg      INFO cluster #100 has moment #501 with value    0.000
+Py:ClusterExAlg      INFO cluster #100 has moment #601 with value    0.271
+Py:ClusterExAlg      INFO cluster #100 has moment #602 with value    0.797
+Py:ClusterExAlg      INFO cluster #100 has moment #702 with value    0.248
+Py:ClusterExAlg      INFO cluster #100 has moment #804 with value    0.028
+Py:ClusterExAlg      INFO cluster #100 has moment #806 with value    0.002
+Py:ClusterExAlg      INFO cluster #200 has energy    3.973
+Py:ClusterExAlg      INFO cluster #200 has moment #201 with value  418.000
+Py:ClusterExAlg      INFO cluster #200 has moment #202 with value 113152.000
+Py:ClusterExAlg      INFO cluster #200 has moment #501 with value  540.000
+Py:ClusterExAlg      INFO cluster #200 has moment #601 with value    0.346
+Py:ClusterExAlg      INFO cluster #200 has moment #602 with value    0.934
+Py:ClusterExAlg      INFO cluster #200 has moment #702 with value    0.208
+Py:ClusterExAlg      INFO cluster #200 has moment #804 with value    0.006
+Py:ClusterExAlg      INFO cluster #200 has moment #806 with value    0.216
+Py:ClusterExAlg      INFO cluster #300 has energy    3.093
+Py:ClusterExAlg      INFO cluster #300 has moment #201 with value 1272.000
+Py:ClusterExAlg      INFO cluster #300 has moment #202 with value 48896.000
+Py:ClusterExAlg      INFO cluster #300 has moment #501 with value  700.000
+Py:ClusterExAlg      INFO cluster #300 has moment #601 with value    0.637
+Py:ClusterExAlg      INFO cluster #300 has moment #602 with value    0.930
+Py:ClusterExAlg      INFO cluster #300 has moment #702 with value    0.203
+Py:ClusterExAlg      INFO cluster #300 has moment #804 with value    0.001
+Py:ClusterExAlg      INFO cluster #300 has moment #806 with value    0.277
+Py:ClusterExAlg      INFO ==> finalize
+Py:ClusterExAlg      INFO === analyzed [4] events ===
+Py:ClusterExAlg      INFO  <cluster ene> =    2.970 MeV
+Py:ClusterExAlg      INFO           rms  =    1.261 MeV
+Py:ClusterExAlg      INFO  <cluster eta> =   -0.058
+Py:ClusterExAlg      INFO           rms  =    2.400
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pyfdr_aodtodpd_rel140100.ref b/AtlasTest/PyAthenaTests/test/pyathena_pyfdr_aodtodpd_rel140100.ref
new file mode 100644
index 00000000000..d55e5a0ff18
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pyfdr_aodtodpd_rel140100.ref
@@ -0,0 +1,280 @@
+Py:MuonRec           INFO Changing default applyResilience = True
+Py:MuonRec           INFO Changing default doTGC_rawdataROD = False
+Py:MuonRec           INFO Changing default useTGCPriorNextBC = False
+Py:MuonRec           INFO Changing default Mode = 'trackNtuple'
+Py:MuonRec           INFO DetFlags.writeRIOPool.MDT_setOn()
+Py:MuonRec           INFO DetFlags.writeRIOPool.RPC_setOn()
+Py:MuonRec           INFO DetFlags.writeRIOPool.CSC_setOn()
+Py:MuonRec           INFO DetFlags.writeRIOPool.TGC_setOn()
+Py:IOVDbSvc.CondDB    INFO Setting up conditions DB access to instance OFLP200
+Py:TileInfoConf.     INFO Adding TileCablingSvc to ServiceMgr
+Py:TileInfoConf.     INFO Adding default TileBadChanTool to ToolSvc
+Py:TileInfoConf.     INFO Adding default TileCondToolOfc to ToolSvc
+Py:TileInfoConf.     INFO Adding default TileCondToolEmscale to ToolSvc
+Py:TileInfoConf.     INFO Adding default TileCondToolNoiseSample to ToolSvc
+Py:TileInfoConf.     INFO Adding default TileCondToolTiming to ToolSvc
+Py:TileInfoConf.     INFO Adding default TileCondToolPulseShape to ToolSvc
+Py:TileConditions_jobOptions.py    INFO Adjusting TileInfo for 7 samples
+Py:TileConditions_jobOptions.py    INFO setting up COOL for TileCal conditions data
+Py:TileInfoConf.     INFO Changing default TileBadChanTool configuration to COOL source
+Py:TileInfoConf.     INFO Changing default TileCondToolEmscale configuration to COOL source
+Py:IOVDbSvc.CondDB    INFO Ignoring additional request for folder /TILE/OFL02/CALIB/CIS/FIT/LIN
+Py:IOVDbSvc.CondDB    INFO Ignoring additional request for folder /TILE/OFL02/CALIB/LAS/LIN
+Py:IOVDbSvc.CondDB    INFO Ignoring additional request for folder /TILE/OFL02/CALIB/CES
+Py:IOVDbSvc.CondDB    INFO Ignoring additional request for folder /TILE/OFL02/CALIB/EMS
+Py:TileInfoConf.     INFO Changing default TileCondToolNoiseSample configuration to COOL source
+Py:TileInfoConf.     INFO Changing default TileCondToolTiming configuration to COOL source
+Py:TileInfoConf.     INFO Changing default TileCondToolPulseShape configuration to COOL source
+Py:TileConditions_jobOptions.py    INFO Adjusting TileInfo to return cell noise for Opt.Filter without iterations
+Py:JobPropertyContainer::    INFO  setting folder /LAR/ElecCalibMC with tag LARElecCalibMC-CSC02-J-QGSP_BERT
+Py:JobPropertyContainer::    INFO  setting folder /LAR/Identifier/OnOffIdAtlas with tag OnOffIdAtlas-012
+Py:JobPropertyContainer::    INFO  setting folder /LAR/Identifier/FebRodAtlas with tag FebRodAtlas-005
+Py:JetGetters        INFO  Building jetgetter for Kt4LCTopoGetter  disabling=False
+Py:JetGetters        INFO  input = LCTopo
+Py:Configured::existingOutput:Kt4LCTopoGetter:    INFO one object not in output JetCollection:
+Py:Configured::existingOutput:Kt4LCTopoGetter:    INFO No output objects already available. Continue.
+Py:Kt4LCTopoGetter::configure :    INFO  Recorded JetKeyDescriptor with key JetKeyMap
+Py:Kt4LCTopoGetter::configure :    INFO  now adding to topSequence
+Py:Kt4LCTopoGetter::configure :    INFO scheduled to output {'JetCollection': 'Kt4LCTopoJets'}
+Py:Configured::__init__:Kt4LCTopoGetter:    INFO Configured/Enabled
+Py:JetGetters        INFO  Building jetgetter for Kt4TruthGetter  disabling=False
+Py:JetGetters        INFO  input = Truth
+Py:Configured::existingOutput:InputTruthJetGetter_AOD:    INFO one object not in output TruthParticleContainer:SpclMC
+Py:Configured::existingOutput:InputTruthJetGetter_AOD:    INFO No output objects already available. Continue.
+Py:InputTruthJetGetter::configure :    INFO scheduled to output {'TruthParticleContainer': 'SpclMC'}
+Py:InputTruthJetGetter::configure :    INFO for AOD
+Py:InputTruthJetGetter::configure :    INFO RDO True
+Py:InputTruthJetGetter::configure :    INFO ESD False
+Py:InputTruthJetGetter::configure :    INFO AOD False
+Py:Configured::__init__:InputTruthJetGetter_AOD:    INFO Configured/Enabled
+Py:Configured::existingOutput:Kt4TruthGetter:    INFO one object not in output JetCollection:
+Py:Configured::existingOutput:Kt4TruthGetter:    INFO No output objects already available. Continue.
+Py:Kt4TruthGetter::configure :    INFO  now adding to topSequence
+Py:Kt4TruthGetter::configure :    INFO scheduled to output {'JetCollection': 'Kt4TruthJets'}
+Py:Configured::__init__:Kt4TruthGetter:    INFO Configured/Enabled
+Py:ttbarFilter       INFO ==> initializing [ttbarFilter]...
+Py:ttbarFilter       INFO Lepton MinEt:   20.0 GeV/c
+Py:ttbarFilter       INFO Lepton MaxEta:  2.5
+Py:ttbarFilter       INFO Jets MinEt:     20.0 GeV/c
+Py:ttbarFilter       INFO Jets MaxEta:    2.5
+Py:ttbarFilter       INFO Min Missing Et: 20.0 GeV/c
+Py:ttbarFilter       INFO Jet match: 33561.772    0.885    1.169 30326.694    0.897    1.166
+Py:ttbarFilter       INFO event passed semileptonic ttbar filter
+Py:ttbarFilter       INFO thinning clusters...
+Py:ttbarFilter       INFO thinning tracks...
+Py:ttbarFilter       INFO completed filtering
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 42751.141   -1.079    2.281 27304.343   -1.137    2.362
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 57827.490   -0.591    0.761 56709.507   -0.611    0.757
+Py:ttbarFilter       INFO Jet match: 44217.774   -0.947   -1.429 42423.044   -0.964   -1.416
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 31942.524    0.818   -1.346 32068.786    0.823   -1.331
+Py:ttbarFilter       INFO event passed semileptonic ttbar filter
+Py:ttbarFilter       INFO thinning clusters...
+Py:ttbarFilter       INFO thinning tracks...
+Py:ttbarFilter       INFO completed filtering
+Py:ttbarFilter       INFO Jet match: 59387.343   -0.986   -0.995 54488.915   -0.995   -0.982
+Py:ttbarFilter       INFO event passed semileptonic ttbar filter
+Py:ttbarFilter       INFO thinning clusters...
+Py:ttbarFilter       INFO thinning tracks...
+Py:ttbarFilter       INFO completed filtering
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 18511.101   -0.933   -1.459 13364.035   -0.942   -1.520
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event passed semileptonic ttbar filter
+Py:ttbarFilter       INFO thinning clusters...
+Py:ttbarFilter       INFO thinning tracks...
+Py:ttbarFilter       INFO completed filtering
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 30097.736   -2.342    0.515 16152.500   -2.408    0.540
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 78207.893    0.135    2.893 78408.174    0.129    2.899
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 59717.217    0.634   -1.906 58913.964    0.642   -1.900
+Py:ttbarFilter       INFO event passed semileptonic ttbar filter
+Py:ttbarFilter       INFO thinning clusters...
+Py:ttbarFilter       INFO thinning tracks...
+Py:ttbarFilter       INFO completed filtering
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 14790.006   -0.479   -1.735 11686.177   -0.475   -1.710
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 53106.939   -1.534    1.741 47229.998   -1.542    1.748
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event passed semileptonic ttbar filter
+Py:ttbarFilter       INFO thinning clusters...
+Py:ttbarFilter       INFO thinning tracks...
+Py:ttbarFilter       INFO completed filtering
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 151470.658   -0.697    2.328 151243.239   -0.698    2.340
+Py:ttbarFilter       INFO event passed semileptonic ttbar filter
+Py:ttbarFilter       INFO thinning clusters...
+Py:ttbarFilter       INFO thinning tracks...
+Py:ttbarFilter       INFO completed filtering
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 8896.505    0.041   -0.601 8922.597    0.089   -0.648
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 104570.707   -0.666    2.732 98406.124   -0.682    2.747
+Py:ttbarFilter       INFO Jet match: 44471.180    0.669    0.040 42744.401    0.649    0.013
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 39616.376   -2.254    1.633 37156.120   -2.268    1.635
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 57834.891   -0.719    2.427 57128.713   -0.737    2.448
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event passed semileptonic ttbar filter
+Py:ttbarFilter       INFO thinning clusters...
+Py:ttbarFilter       INFO thinning tracks...
+Py:ttbarFilter       INFO completed filtering
+Py:ttbarFilter       INFO Jet match: 28373.040   -1.048    2.935 27529.443   -1.051    2.931
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 43574.496   -1.752    1.945 38761.179   -1.746    1.960
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 44448.225    1.629   -2.150 39589.636    1.648   -2.156
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event passed semileptonic ttbar filter
+Py:ttbarFilter       INFO thinning clusters...
+Py:ttbarFilter       INFO thinning tracks...
+Py:ttbarFilter       INFO completed filtering
+Py:ttbarFilter       INFO Jet match: 19875.305    0.513   -0.250 10995.813    0.515   -0.237
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 74490.744    0.970   -0.259 74993.130    0.948   -0.273
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 30599.000   -1.016   -0.739 15422.366   -1.017   -0.755
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event passed semileptonic ttbar filter
+Py:ttbarFilter       INFO thinning clusters...
+Py:ttbarFilter       INFO thinning tracks...
+Py:ttbarFilter       INFO completed filtering
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 52516.203    2.082   -1.724 48875.980    2.079   -1.725
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 61514.531    0.043   -2.497 60913.107    0.034   -2.486
+Py:ttbarFilter       INFO Jet match: 24641.124    0.695   -1.327 20923.247    0.670   -1.391
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 24486.380   -0.903   -0.417 25094.879   -0.835   -0.401
+Py:ttbarFilter       INFO Jet match: 8549.036   -1.918   -0.122 6824.005   -1.832   -0.159
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 81928.865    1.518   -0.728 73917.058    1.509   -0.716
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 25284.025   -0.279    1.921 25010.365   -0.304    1.902
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 44102.869   -0.630   -2.013 43407.325   -0.637   -2.020
+Py:ttbarFilter       INFO Jet match: 44392.339   -1.276    1.338 44916.352   -1.286    1.364
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 16916.502   -2.196    0.219 16186.846   -2.173    0.205
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 19378.467   -1.130   -2.581 18646.990   -1.060   -2.545
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 49510.217    0.269   -1.131 47642.120    0.293   -1.139
+Py:ttbarFilter       INFO Jet match: 28296.564   -0.337   -1.417 22696.710   -0.311   -1.345
+Py:ttbarFilter       INFO Jet match: 15518.713   -0.180    1.328 15445.394   -0.144    1.299
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 48932.272   -0.125   -1.373 45194.812   -0.109   -1.365
+Py:ttbarFilter       INFO Jet match: 34176.411    1.199    1.329 32262.932    1.218    1.314
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 27042.764    0.128    1.077 22934.098    0.110    1.050
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 18887.757    0.202   -2.672 17980.025    0.228   -2.710
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 62220.654   -1.916   -2.917 60428.619   -1.888   -2.941
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 37793.324   -0.359    0.423 37212.773   -0.371    0.420
+Py:ttbarFilter       INFO Jet match: 16136.491   -0.610   -1.936 11644.649   -0.564   -1.998
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 34218.122    1.419   -1.803 27981.975    1.402   -1.790
+Py:ttbarFilter       INFO Jet match: 26811.968   -1.016    0.993 25350.278   -1.045    0.968
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 52019.267   -1.197   -1.048 47860.833   -1.225   -1.072
+Py:ttbarFilter       INFO Jet match: 24230.132   -0.955   -0.258 21412.998   -0.982   -0.255
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 21524.957    0.153   -2.268 14323.796    0.155   -2.328
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 34249.228    1.073    2.299 32376.951    1.082    2.283
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 52401.886   -0.511    2.418 52600.081   -0.495    2.433
+Py:ttbarFilter       INFO Jet match: 43238.464   -0.373   -0.717 38106.337   -0.329   -0.706
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 30724.523   -0.590    1.510 30695.417   -0.593    1.518
+Py:ttbarFilter       INFO Jet match: 22946.164    1.800   -1.528 20399.668    1.797   -1.562
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 48371.154    0.221   -2.520 48140.319    0.197   -2.517
+Py:ttbarFilter       INFO Jet match: 50257.290   -0.133   -0.450 42748.026   -0.145   -0.464
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 54183.530   -1.881   -0.884 53623.403   -1.891   -0.892
+Py:ttbarFilter       INFO Jet match: 41745.558   -2.072    2.508 39815.209   -2.076    2.508
+Py:ttbarFilter       INFO Jet match: 17106.004   -1.036    0.827 15216.870   -1.049    0.845
+Py:ttbarFilter       INFO Jet match: 9769.921   -0.867    2.771 9459.463   -0.881    2.726
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 10471.303   -1.846    0.530 8406.957   -1.845    0.557
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 37123.243   -0.176   -2.781 35629.324   -0.192   -2.784
+Py:ttbarFilter       INFO Jet match: 37194.455    0.066   -0.977 37563.450    0.058   -0.993
+Py:ttbarFilter       INFO Jet match: 13195.065    2.102    1.917 11168.374    2.123    1.940
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 28738.165   -0.497    0.680 28172.183   -0.537    0.671
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 22045.282    2.097   -0.653 21540.628    2.115   -0.651
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 31914.090    0.990    0.379 31919.244    0.982    0.369
+Py:ttbarFilter       INFO Jet match: 22333.595   -0.012    2.487 23013.782   -0.020    2.506
+Py:ttbarFilter       INFO Jet match: 20066.085   -0.419   -2.929 11417.231   -0.447   -2.990
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 57836.716    1.074   -2.498 57485.561    1.039   -2.498
+Py:ttbarFilter       INFO Jet match: 37896.034    1.786    1.441 32388.205    1.756    1.446
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 48442.175   -1.082   -2.189 48924.012   -1.064   -2.190
+Py:ttbarFilter       INFO Jet match: 37325.262   -1.911    1.072 36453.793   -1.909    1.085
+Py:ttbarFilter       INFO Jet match: 26976.527   -1.622    0.571 23707.275   -1.624    0.554
+Py:ttbarFilter       INFO Jet match: 8760.772   -1.172   -1.600 9233.268   -1.160   -1.548
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 51024.341    0.822   -1.773 51347.262    0.847   -1.760
+Py:ttbarFilter       INFO Jet match: 25006.738   -0.859    2.449 25806.636   -0.833    2.433
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 54274.825    0.480   -1.118 54032.101    0.492   -1.104
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 30056.534    1.311   -1.850 27422.151    1.312   -1.837
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 35469.808    0.378    3.109 35527.181    0.396    3.104
+Py:ttbarFilter       INFO Jet match: 46147.842   -0.525    0.063 39896.546   -0.507    0.085
+Py:ttbarFilter       INFO Jet match: 18203.955   -0.194    0.341 18151.014   -0.174    0.362
+Py:ttbarFilter       INFO Jet match: 13752.931    1.115   -2.633 14004.338    1.126   -2.670
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 60326.549   -0.545   -1.599 57729.869   -0.556   -1.595
+Py:ttbarFilter       INFO Jet match: 27685.344   -0.968   -1.385 25918.177   -0.987   -1.371
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 29589.865   -2.246    0.946 29030.329   -2.233    0.936
+Py:ttbarFilter       INFO Jet match: 31127.807   -1.094    0.612 32010.533   -1.069    0.614
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO Jet match: 28564.787   -1.720   -2.495 28641.091   -1.701   -2.496
+Py:ttbarFilter       INFO Jet match: 7614.984   -0.769   -0.198 6878.065   -0.726   -0.167
+Py:ttbarFilter       INFO event failed semileptonic ttbar filter
+Py:ttbarFilter       INFO ==> finalize...
+Py:Athena            INFO leaving with code 0: "successful run"
\ No newline at end of file
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pyfdr_truthslimming_rel140100.ref b/AtlasTest/PyAthenaTests/test/pyathena_pyfdr_truthslimming_rel140100.ref
new file mode 100644
index 00000000000..0a8887fb121
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pyfdr_truthslimming_rel140100.ref
@@ -0,0 +1,59 @@
+Py:mc_aod_dumper     INFO initializing...
+Py:mc_aod_dumper     INFO Dumping configuration:
+Py:mc_aod_dumper     INFO McEventCollection key: GEN_AOD
+Py:mc_dpd_dumper     INFO initializing...
+Py:mc_dpd_dumper     INFO Dumping configuration:
+Py:mc_dpd_dumper     INFO McEventCollection key: GEN_DPD
+Py:mc_aod_dumper     INFO running execute...
+Py:mc_aod_dumper     INFO retrieve [McEventCollection/GEN_AOD]
+Py:mc_aod_dumper     INFO number of GenEvents: 1
+Py:mc_aod_dumper     INFO number of GenParticles: 2704
+Py:mc_aod_dumper     INFO number of GenVertices:  1055
+Py:mc_dpd_dumper     INFO running execute...
+Py:mc_dpd_dumper     INFO retrieve [McEventCollection/GEN_DPD]
+Py:mc_dpd_dumper     INFO number of GenEvents: 1
+Py:mc_dpd_dumper     INFO number of GenParticles: 409
+Py:mc_dpd_dumper     INFO number of GenVertices:  283
+Py:mc_aod_dumper     INFO running execute...
+Py:mc_aod_dumper     INFO retrieve [McEventCollection/GEN_AOD]
+Py:mc_aod_dumper     INFO number of GenEvents: 1
+Py:mc_aod_dumper     INFO number of GenParticles: 2215
+Py:mc_aod_dumper     INFO number of GenVertices:  859
+Py:mc_dpd_dumper     INFO running execute...
+Py:mc_dpd_dumper     INFO retrieve [McEventCollection/GEN_DPD]
+Py:mc_dpd_dumper     INFO number of GenEvents: 1
+Py:mc_dpd_dumper     INFO number of GenParticles: 322
+Py:mc_dpd_dumper     INFO number of GenVertices:  237
+Py:mc_aod_dumper     INFO running execute...
+Py:mc_aod_dumper     INFO retrieve [McEventCollection/GEN_AOD]
+Py:mc_aod_dumper     INFO number of GenEvents: 1
+Py:mc_aod_dumper     INFO number of GenParticles: 2952
+Py:mc_aod_dumper     INFO number of GenVertices:  1149
+Py:mc_dpd_dumper     INFO running execute...
+Py:mc_dpd_dumper     INFO retrieve [McEventCollection/GEN_DPD]
+Py:mc_dpd_dumper     INFO number of GenEvents: 1
+Py:mc_dpd_dumper     INFO number of GenParticles: 359
+Py:mc_dpd_dumper     INFO number of GenVertices:  260
+Py:mc_aod_dumper     INFO running execute...
+Py:mc_aod_dumper     INFO retrieve [McEventCollection/GEN_AOD]
+Py:mc_aod_dumper     INFO number of GenEvents: 1
+Py:mc_aod_dumper     INFO number of GenParticles: 1655
+Py:mc_aod_dumper     INFO number of GenVertices:  693
+Py:mc_dpd_dumper     INFO running execute...
+Py:mc_dpd_dumper     INFO retrieve [McEventCollection/GEN_DPD]
+Py:mc_dpd_dumper     INFO number of GenEvents: 1
+Py:mc_dpd_dumper     INFO number of GenParticles: 287
+Py:mc_dpd_dumper     INFO number of GenVertices:  186
+Py:mc_aod_dumper     INFO running execute...
+Py:mc_aod_dumper     INFO retrieve [McEventCollection/GEN_AOD]
+Py:mc_aod_dumper     INFO number of GenEvents: 1
+Py:mc_aod_dumper     INFO number of GenParticles: 1692
+Py:mc_aod_dumper     INFO number of GenVertices:  704
+Py:mc_dpd_dumper     INFO running execute...
+Py:mc_dpd_dumper     INFO retrieve [McEventCollection/GEN_DPD]
+Py:mc_dpd_dumper     INFO number of GenEvents: 1
+Py:mc_dpd_dumper     INFO number of GenParticles: 250
+Py:mc_dpd_dumper     INFO number of GenVertices:  185
+Py:mc_aod_dumper     INFO finalizing...
+Py:mc_dpd_dumper     INFO finalizing...
+Py:Athena            INFO leaving with code 0: "successful run"
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pythinner_atlfast_rel13.ref b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_atlfast_rel13.ref
new file mode 100644
index 00000000000..b497a0f01cf
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_atlfast_rel13.ref
@@ -0,0 +1,49 @@
+Py:Thinner           INFO initializing...
+Py:Thinner           INFO Dumping configuration:
+Py:Thinner           INFO Container type: JetCollection
+Py:Thinner           INFO Container key:  AtlfastJetContainer
+Py:Thinner           INFO Filter: '<lambda>'
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 2
+Py:Thinner           INFO number of elements after  thinning: 2
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 4
+Py:Thinner           INFO number of elements after  thinning: 4
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO Container "JetCollection/AtlfastJetContainer" is empty
+Py:Thinner           INFO number of elements before thinning: 0
+Py:Thinner           INFO number of elements after  thinning: 0
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO Container "JetCollection/AtlfastJetContainer" is empty
+Py:Thinner           INFO number of elements before thinning: 0
+Py:Thinner           INFO number of elements after  thinning: 0
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 2
+Py:Thinner           INFO number of elements after  thinning: 1
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 6
+Py:Thinner           INFO number of elements after  thinning: 5
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO Container "JetCollection/AtlfastJetContainer" is empty
+Py:Thinner           INFO number of elements before thinning: 0
+Py:Thinner           INFO number of elements after  thinning: 0
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 5
+Py:Thinner           INFO number of elements after  thinning: 2
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 2
+Py:Thinner           INFO number of elements after  thinning: 0
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 1
+Py:Thinner           INFO number of elements after  thinning: 1
+Py:Thinner           INFO finalizing...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pythinner_atlfast_rel140100.ref b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_atlfast_rel140100.ref
new file mode 100644
index 00000000000..be8de235446
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_atlfast_rel140100.ref
@@ -0,0 +1,46 @@
+Py:Thinner           INFO initializing...
+Py:Thinner           INFO Dumping configuration:
+Py:Thinner           INFO Container type: JetCollection
+Py:Thinner           INFO Container key:  AtlfastJetContainer
+Py:Thinner           INFO Filter: '<lambda>'
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 8
+Py:Thinner           INFO number of elements after  thinning: 8
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 7
+Py:Thinner           INFO number of elements after  thinning: 6
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 2
+Py:Thinner           INFO number of elements after  thinning: 2
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 4
+Py:Thinner           INFO number of elements after  thinning: 4
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 4
+Py:Thinner           INFO number of elements after  thinning: 3
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 6
+Py:Thinner           INFO number of elements after  thinning: 5
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 7
+Py:Thinner           INFO number of elements after  thinning: 6
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 6
+Py:Thinner           INFO number of elements after  thinning: 3
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 10
+Py:Thinner           INFO number of elements after  thinning: 10
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [JetCollection/AtlfastJetContainer]
+Py:Thinner           INFO number of elements before thinning: 7
+Py:Thinner           INFO number of elements after  thinning: 6
+Py:Thinner           INFO finalizing...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pythinner_basic_thinning.ref b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_basic_thinning.ref
new file mode 100644
index 00000000000..fa552aa7cb1
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_basic_thinning.ref
@@ -0,0 +1,26 @@
+Py:thinner           INFO initializing...
+Py:thinner           INFO Dumping configuration:
+Py:thinner           INFO Container type: AthExParticles
+Py:thinner           INFO Container key:  Particles_basic
+Py:thinner           INFO Filter: '<lambda>'
+Py:thinner           INFO running execute...
+Py:thinner           INFO retrieve [AthExParticles/Particles_basic]
+Py:thinner           INFO number of elements before thinning: 10
+Py:thinner           INFO number of elements after  thinning: 5
+Py:thinner           INFO running execute...
+Py:thinner           INFO retrieve [AthExParticles/Particles_basic]
+Py:thinner           INFO number of elements before thinning: 10
+Py:thinner           INFO number of elements after  thinning: 5
+Py:thinner           INFO running execute...
+Py:thinner           INFO retrieve [AthExParticles/Particles_basic]
+Py:thinner           INFO number of elements before thinning: 10
+Py:thinner           INFO number of elements after  thinning: 5
+Py:thinner           INFO running execute...
+Py:thinner           INFO retrieve [AthExParticles/Particles_basic]
+Py:thinner           INFO number of elements before thinning: 10
+Py:thinner           INFO number of elements after  thinning: 5
+Py:thinner           INFO running execute...
+Py:thinner           INFO retrieve [AthExParticles/Particles_basic]
+Py:thinner           INFO number of elements before thinning: 10
+Py:thinner           INFO number of elements after  thinning: 5
+Py:thinner           INFO finalizing...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_check_thin0.ref b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_check_thin0.ref
new file mode 100644
index 00000000000..ace9bc8853b
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_check_thin0.ref
@@ -0,0 +1,115 @@
+Py:thin_checker_0    INFO initializing...
+Py:thin_checker_0    INFO Dumping configuration:
+Py:thin_checker_0    INFO Container type: AthExParticles
+Py:thin_checker_0    INFO Container key:  Particles_0
+Py:thin_checker_1    INFO initializing...
+Py:thin_checker_1    INFO Dumping configuration:
+Py:thin_checker_1    INFO Container type: AthExParticles
+Py:thin_checker_1    INFO Container key:  Particles_1
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 5
+Py:thin_checker_0    INFO [Particles_0][0]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 10
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_1    INFO [Particles_1][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_1    INFO [Particles_1][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_1    INFO [Particles_1][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 5
+Py:thin_checker_0    INFO [Particles_0][0]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 10
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_1    INFO [Particles_1][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_1    INFO [Particles_1][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_1    INFO [Particles_1][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 5
+Py:thin_checker_0    INFO [Particles_0][0]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 10
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_1    INFO [Particles_1][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_1    INFO [Particles_1][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_1    INFO [Particles_1][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 5
+Py:thin_checker_0    INFO [Particles_0][0]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 10
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_1    INFO [Particles_1][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_1    INFO [Particles_1][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_1    INFO [Particles_1][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 5
+Py:thin_checker_0    INFO [Particles_0][0]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 10
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_1    INFO [Particles_1][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_1    INFO [Particles_1][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_1    INFO [Particles_1][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_0    INFO finalizing...
+Py:thin_checker_1    INFO finalizing...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_check_thin1.ref b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_check_thin1.ref
new file mode 100644
index 00000000000..691bfe23b53
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_check_thin1.ref
@@ -0,0 +1,115 @@
+Py:thin_checker_0    INFO initializing...
+Py:thin_checker_0    INFO Dumping configuration:
+Py:thin_checker_0    INFO Container type: AthExParticles
+Py:thin_checker_0    INFO Container key:  Particles_0
+Py:thin_checker_1    INFO initializing...
+Py:thin_checker_1    INFO Dumping configuration:
+Py:thin_checker_1    INFO Container type: AthExParticles
+Py:thin_checker_1    INFO Container key:  Particles_1
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 10
+Py:thin_checker_0    INFO [Particles_0][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_0    INFO [Particles_0][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_0    INFO [Particles_0][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO [Particles_0][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 5
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 10
+Py:thin_checker_0    INFO [Particles_0][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_0    INFO [Particles_0][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_0    INFO [Particles_0][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO [Particles_0][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 5
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 10
+Py:thin_checker_0    INFO [Particles_0][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_0    INFO [Particles_0][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_0    INFO [Particles_0][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO [Particles_0][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 5
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 10
+Py:thin_checker_0    INFO [Particles_0][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_0    INFO [Particles_0][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_0    INFO [Particles_0][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO [Particles_0][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 5
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 10
+Py:thin_checker_0    INFO [Particles_0][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_0    INFO [Particles_0][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_0    INFO [Particles_0][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO [Particles_0][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 5
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO finalizing...
+Py:thin_checker_1    INFO finalizing...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_check_thin2.ref b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_check_thin2.ref
new file mode 100644
index 00000000000..5eb6159c13d
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_check_thin2.ref
@@ -0,0 +1,140 @@
+Py:thin_checker_0    INFO initializing...
+Py:thin_checker_0    INFO Dumping configuration:
+Py:thin_checker_0    INFO Container type: AthExParticles
+Py:thin_checker_0    INFO Container key:  Particles_0
+Py:thin_checker_1    INFO initializing...
+Py:thin_checker_1    INFO Dumping configuration:
+Py:thin_checker_1    INFO Container type: AthExParticles
+Py:thin_checker_1    INFO Container key:  Particles_1
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 10
+Py:thin_checker_0    INFO [Particles_0][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_0    INFO [Particles_0][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_0    INFO [Particles_0][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO [Particles_0][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 10
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_1    INFO [Particles_1][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_1    INFO [Particles_1][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_1    INFO [Particles_1][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 10
+Py:thin_checker_0    INFO [Particles_0][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_0    INFO [Particles_0][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_0    INFO [Particles_0][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO [Particles_0][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 10
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_1    INFO [Particles_1][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_1    INFO [Particles_1][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_1    INFO [Particles_1][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 10
+Py:thin_checker_0    INFO [Particles_0][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_0    INFO [Particles_0][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_0    INFO [Particles_0][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO [Particles_0][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 10
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_1    INFO [Particles_1][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_1    INFO [Particles_1][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_1    INFO [Particles_1][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 10
+Py:thin_checker_0    INFO [Particles_0][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_0    INFO [Particles_0][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_0    INFO [Particles_0][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO [Particles_0][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 10
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_1    INFO [Particles_1][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_1    INFO [Particles_1][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_1    INFO [Particles_1][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_0    INFO running execute...
+Py:thin_checker_0    INFO retrieve [AthExParticles/Particles_0]
+Py:thin_checker_0    INFO number of elements : 10
+Py:thin_checker_0    INFO [Particles_0][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_0    INFO [Particles_0][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_0    INFO [Particles_0][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_0    INFO [Particles_0][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_0    INFO [Particles_0][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_0    INFO [Particles_0][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_0    INFO [Particles_0][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_0    INFO [Particles_0][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_0    INFO [Particles_0][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_0    INFO [Particles_0][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_1    INFO running execute...
+Py:thin_checker_1    INFO retrieve [AthExParticles/Particles_1]
+Py:thin_checker_1    INFO number of elements : 10
+Py:thin_checker_1    INFO [Particles_1][0]: 20000.000000 10000.000000 10000.000000 10000.000000
+Py:thin_checker_1    INFO [Particles_1][1]: 30000.000000 20000.000000 20000.000000 20000.000000
+Py:thin_checker_1    INFO [Particles_1][2]: 40000.000000 30000.000000 30000.000000 30000.000000
+Py:thin_checker_1    INFO [Particles_1][3]: 50000.000000 40000.000000 40000.000000 40000.000000
+Py:thin_checker_1    INFO [Particles_1][4]: 60000.000000 50000.000000 50000.000000 50000.000000
+Py:thin_checker_1    INFO [Particles_1][5]: 70000.000000 60000.000000 60000.000000 60000.000000
+Py:thin_checker_1    INFO [Particles_1][6]: 80000.000000 70000.000000 70000.000000 70000.000000
+Py:thin_checker_1    INFO [Particles_1][7]: 90000.000000 80000.000000 80000.000000 80000.000000
+Py:thin_checker_1    INFO [Particles_1][8]: 100000.000000 90000.000000 90000.000000 90000.000000
+Py:thin_checker_1    INFO [Particles_1][9]: 110000.000000 100000.000000 100000.000000 100000.000000
+Py:thin_checker_0    INFO finalizing...
+Py:thin_checker_1    INFO finalizing...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_thinning.ref b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_thinning.ref
new file mode 100644
index 00000000000..93728416a8d
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_multistream_thinning.ref
@@ -0,0 +1,52 @@
+Py:thinner_0         INFO initializing...
+Py:thinner_0         INFO Dumping configuration:
+Py:thinner_0         INFO Container type: AthExParticles
+Py:thinner_0         INFO Container key:  Particles_0
+Py:thinner_0         INFO Filter: '<lambda>'
+Py:thinner_1         INFO initializing...
+Py:thinner_1         INFO Dumping configuration:
+Py:thinner_1         INFO Container type: AthExParticles
+Py:thinner_1         INFO Container key:  Particles_1
+Py:thinner_1         INFO Filter: '<lambda>'
+Py:thinner_0         INFO running execute...
+Py:thinner_0         INFO retrieve [AthExParticles/Particles_0]
+Py:thinner_0         INFO number of elements before thinning: 10
+Py:thinner_0         INFO number of elements after  thinning: 5
+Py:thinner_1         INFO running execute...
+Py:thinner_1         INFO retrieve [AthExParticles/Particles_1]
+Py:thinner_1         INFO number of elements before thinning: 10
+Py:thinner_1         INFO number of elements after  thinning: 5
+Py:thinner_0         INFO running execute...
+Py:thinner_0         INFO retrieve [AthExParticles/Particles_0]
+Py:thinner_0         INFO number of elements before thinning: 10
+Py:thinner_0         INFO number of elements after  thinning: 5
+Py:thinner_1         INFO running execute...
+Py:thinner_1         INFO retrieve [AthExParticles/Particles_1]
+Py:thinner_1         INFO number of elements before thinning: 10
+Py:thinner_1         INFO number of elements after  thinning: 5
+Py:thinner_0         INFO running execute...
+Py:thinner_0         INFO retrieve [AthExParticles/Particles_0]
+Py:thinner_0         INFO number of elements before thinning: 10
+Py:thinner_0         INFO number of elements after  thinning: 5
+Py:thinner_1         INFO running execute...
+Py:thinner_1         INFO retrieve [AthExParticles/Particles_1]
+Py:thinner_1         INFO number of elements before thinning: 10
+Py:thinner_1         INFO number of elements after  thinning: 5
+Py:thinner_0         INFO running execute...
+Py:thinner_0         INFO retrieve [AthExParticles/Particles_0]
+Py:thinner_0         INFO number of elements before thinning: 10
+Py:thinner_0         INFO number of elements after  thinning: 5
+Py:thinner_1         INFO running execute...
+Py:thinner_1         INFO retrieve [AthExParticles/Particles_1]
+Py:thinner_1         INFO number of elements before thinning: 10
+Py:thinner_1         INFO number of elements after  thinning: 5
+Py:thinner_0         INFO running execute...
+Py:thinner_0         INFO retrieve [AthExParticles/Particles_0]
+Py:thinner_0         INFO number of elements before thinning: 10
+Py:thinner_0         INFO number of elements after  thinning: 5
+Py:thinner_1         INFO running execute...
+Py:thinner_1         INFO retrieve [AthExParticles/Particles_1]
+Py:thinner_1         INFO number of elements before thinning: 10
+Py:thinner_1         INFO number of elements after  thinning: 5
+Py:thinner_0         INFO finalizing...
+Py:thinner_1         INFO finalizing...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_eles_rel140100.ref b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_eles_rel140100.ref
new file mode 100644
index 00000000000..a19bfcd4c48
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_eles_rel140100.ref
@@ -0,0 +1,26 @@
+Py:thin_eles         INFO initializing...
+Py:thin_eles         INFO Dumping configuration:
+Py:thin_eles         INFO Container type: ElectronContainer
+Py:thin_eles         INFO Container key:  ElectronAODCollection
+Py:thin_eles         INFO Filter: '<lambda>'
+Py:thin_eles         INFO running execute...
+Py:thin_eles         INFO retrieve [ElectronContainer/ElectronAODCollection]
+Py:thin_eles         INFO number of elements before thinning: 17
+Py:thin_eles         INFO number of elements after  thinning: 4
+Py:thin_eles         INFO running execute...
+Py:thin_eles         INFO retrieve [ElectronContainer/ElectronAODCollection]
+Py:thin_eles         INFO number of elements before thinning: 7
+Py:thin_eles         INFO number of elements after  thinning: 0
+Py:thin_eles         INFO running execute...
+Py:thin_eles         INFO retrieve [ElectronContainer/ElectronAODCollection]
+Py:thin_eles         INFO number of elements before thinning: 8
+Py:thin_eles         INFO number of elements after  thinning: 6
+Py:thin_eles         INFO running execute...
+Py:thin_eles         INFO retrieve [ElectronContainer/ElectronAODCollection]
+Py:thin_eles         INFO number of elements before thinning: 8
+Py:thin_eles         INFO number of elements after  thinning: 2
+Py:thin_eles         INFO running execute...
+Py:thin_eles         INFO retrieve [ElectronContainer/ElectronAODCollection]
+Py:thin_eles         INFO number of elements before thinning: 4
+Py:thin_eles         INFO number of elements after  thinning: 1
+Py:thin_eles         INFO finalizing...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_muons_rel140100.ref b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_muons_rel140100.ref
new file mode 100644
index 00000000000..93877d613a7
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_muons_rel140100.ref
@@ -0,0 +1,28 @@
+Py:thin_muons        INFO initializing...
+Py:thin_muons        INFO Dumping configuration:
+Py:thin_muons        INFO Container type: Analysis::MuonContainer
+Py:thin_muons        INFO Container key:  MuidMuonCollection
+Py:thin_muons        INFO Filter: '<lambda>'
+Py:thin_muons        INFO running execute...
+Py:thin_muons        INFO retrieve [Analysis::MuonContainer/MuidMuonCollection]
+Py:thin_muons        INFO number of elements before thinning: 2
+Py:thin_muons        INFO number of elements after  thinning: 0
+Py:thin_muons        INFO running execute...
+Py:thin_muons        INFO retrieve [Analysis::MuonContainer/MuidMuonCollection]
+Py:thin_muons        INFO Container "Analysis::MuonContainer/MuidMuonCollection" is empty
+Py:thin_muons        INFO number of elements before thinning: 0
+Py:thin_muons        INFO number of elements after  thinning: 0
+Py:thin_muons        INFO running execute...
+Py:thin_muons        INFO retrieve [Analysis::MuonContainer/MuidMuonCollection]
+Py:thin_muons        INFO number of elements before thinning: 1
+Py:thin_muons        INFO number of elements after  thinning: 1
+Py:thin_muons        INFO running execute...
+Py:thin_muons        INFO retrieve [Analysis::MuonContainer/MuidMuonCollection]
+Py:thin_muons        INFO Container "Analysis::MuonContainer/MuidMuonCollection" is empty
+Py:thin_muons        INFO number of elements before thinning: 0
+Py:thin_muons        INFO number of elements after  thinning: 0
+Py:thin_muons        INFO running execute...
+Py:thin_muons        INFO retrieve [Analysis::MuonContainer/MuidMuonCollection]
+Py:thin_muons        INFO number of elements before thinning: 1
+Py:thin_muons        INFO number of elements after  thinning: 0
+Py:thin_muons        INFO finalizing...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_photons_rel140100.ref b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_photons_rel140100.ref
new file mode 100644
index 00000000000..1f784f6b252
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_photons_rel140100.ref
@@ -0,0 +1,27 @@
+Py:thin_photons      INFO initializing...
+Py:thin_photons      INFO Dumping configuration:
+Py:thin_photons      INFO Container type: PhotonContainer
+Py:thin_photons      INFO Container key:  PhotonAODCollection
+Py:thin_photons      INFO Filter: '<lambda>'
+Py:thin_photons      INFO running execute...
+Py:thin_photons      INFO retrieve [PhotonContainer/PhotonAODCollection]
+Py:thin_photons      INFO number of elements before thinning: 2
+Py:thin_photons      INFO number of elements after  thinning: 0
+Py:thin_photons      INFO running execute...
+Py:thin_photons      INFO retrieve [PhotonContainer/PhotonAODCollection]
+Py:thin_photons      INFO number of elements before thinning: 2
+Py:thin_photons      INFO number of elements after  thinning: 0
+Py:thin_photons      INFO running execute...
+Py:thin_photons      INFO retrieve [PhotonContainer/PhotonAODCollection]
+Py:thin_photons      INFO Container "PhotonContainer/PhotonAODCollection" is empty
+Py:thin_photons      INFO number of elements before thinning: 0
+Py:thin_photons      INFO number of elements after  thinning: 0
+Py:thin_photons      INFO running execute...
+Py:thin_photons      INFO retrieve [PhotonContainer/PhotonAODCollection]
+Py:thin_photons      INFO number of elements before thinning: 1
+Py:thin_photons      INFO number of elements after  thinning: 0
+Py:thin_photons      INFO running execute...
+Py:thin_photons      INFO retrieve [PhotonContainer/PhotonAODCollection]
+Py:thin_photons      INFO number of elements before thinning: 2
+Py:thin_photons      INFO number of elements after  thinning: 0
+Py:thin_photons      INFO finalizing...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_taus_rel140100.ref b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_taus_rel140100.ref
new file mode 100644
index 00000000000..690667127ef
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-aod_taus_rel140100.ref
@@ -0,0 +1,26 @@
+Py:thin_taus         INFO initializing...
+Py:thin_taus         INFO Dumping configuration:
+Py:thin_taus         INFO Container type: Analysis::TauJetContainer
+Py:thin_taus         INFO Container key:  TauRecContainer
+Py:thin_taus         INFO Filter: '<lambda>'
+Py:thin_taus         INFO running execute...
+Py:thin_taus         INFO retrieve [Analysis::TauJetContainer/TauRecContainer]
+Py:thin_taus         INFO number of elements before thinning: 8
+Py:thin_taus         INFO number of elements after  thinning: 5
+Py:thin_taus         INFO running execute...
+Py:thin_taus         INFO retrieve [Analysis::TauJetContainer/TauRecContainer]
+Py:thin_taus         INFO number of elements before thinning: 7
+Py:thin_taus         INFO number of elements after  thinning: 5
+Py:thin_taus         INFO running execute...
+Py:thin_taus         INFO retrieve [Analysis::TauJetContainer/TauRecContainer]
+Py:thin_taus         INFO number of elements before thinning: 4
+Py:thin_taus         INFO number of elements after  thinning: 3
+Py:thin_taus         INFO running execute...
+Py:thin_taus         INFO retrieve [Analysis::TauJetContainer/TauRecContainer]
+Py:thin_taus         INFO number of elements before thinning: 5
+Py:thin_taus         INFO number of elements after  thinning: 5
+Py:thin_taus         INFO running execute...
+Py:thin_taus         INFO retrieve [Analysis::TauJetContainer/TauRecContainer]
+Py:thin_taus         INFO number of elements before thinning: 5
+Py:thin_taus         INFO number of elements after  thinning: 4
+Py:thin_taus         INFO finalizing...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-esd_calocells_rel140100.ref b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-esd_calocells_rel140100.ref
new file mode 100644
index 00000000000..5ba8281f43e
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_pythinner_reco-esd_calocells_rel140100.ref
@@ -0,0 +1,26 @@
+Py:Thinner           INFO initializing...
+Py:Thinner           INFO Dumping configuration:
+Py:Thinner           INFO Container type: CaloCellContainer
+Py:Thinner           INFO Container key:  AllCalo
+Py:Thinner           INFO Filter: 'filter_fct'
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [CaloCellContainer/AllCalo]
+Py:Thinner           INFO number of elements before thinning: 187652
+Py:Thinner           INFO number of elements after  thinning: 93826
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [CaloCellContainer/AllCalo]
+Py:Thinner           INFO number of elements before thinning: 187652
+Py:Thinner           INFO number of elements after  thinning: 93826
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [CaloCellContainer/AllCalo]
+Py:Thinner           INFO number of elements before thinning: 187652
+Py:Thinner           INFO number of elements after  thinning: 93826
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [CaloCellContainer/AllCalo]
+Py:Thinner           INFO number of elements before thinning: 187652
+Py:Thinner           INFO number of elements after  thinning: 93826
+Py:Thinner           INFO running execute...
+Py:Thinner           INFO retrieve [CaloCellContainer/AllCalo]
+Py:Thinner           INFO number of elements before thinning: 187652
+Py:Thinner           INFO number of elements after  thinning: 93826
+Py:Thinner           INFO finalizing...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_trigdectool_rel140100.ref b/AtlasTest/PyAthenaTests/test/pyathena_trigdectool_rel140100.ref
new file mode 100644
index 00000000000..ad8956845f9
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_trigdectool_rel140100.ref
@@ -0,0 +1,35 @@
+Py:TrigDecTestAlg    INFO ==> initialize...
+Py:TrigDecTestAlg    INFO ==> execute...
+Py:TrigDecTestAlg    INFO Pass state EF = True
+Py:TrigDecTestAlg    INFO chain L2_e25i: passed: True
+Py:TrigDecTestAlg    INFO == SUCCESS ==
+Py:TrigDecTestAlg    INFO ==> execute...
+Py:TrigDecTestAlg    INFO Pass state EF = True
+Py:TrigDecTestAlg    INFO chain L2_e25i: passed: False
+Py:TrigDecTestAlg    INFO ==> execute...
+Py:TrigDecTestAlg    INFO Pass state EF = True
+Py:TrigDecTestAlg    INFO chain L2_e25i: passed: False
+Py:TrigDecTestAlg    INFO ==> execute...
+Py:TrigDecTestAlg    INFO Pass state EF = True
+Py:TrigDecTestAlg    INFO chain L2_e25i: passed: True
+Py:TrigDecTestAlg    INFO == SUCCESS ==
+Py:TrigDecTestAlg    INFO ==> execute...
+Py:TrigDecTestAlg    INFO Pass state EF = True
+Py:TrigDecTestAlg    INFO chain L2_e25i: passed: False
+Py:TrigDecTestAlg    INFO ==> execute...
+Py:TrigDecTestAlg    INFO Pass state EF = True
+Py:TrigDecTestAlg    INFO chain L2_e25i: passed: False
+Py:TrigDecTestAlg    INFO ==> execute...
+Py:TrigDecTestAlg    INFO Pass state EF = True
+Py:TrigDecTestAlg    INFO chain L2_e25i: passed: True
+Py:TrigDecTestAlg    INFO == SUCCESS ==
+Py:TrigDecTestAlg    INFO ==> execute...
+Py:TrigDecTestAlg    INFO Pass state EF = True
+Py:TrigDecTestAlg    INFO chain L2_e25i: passed: False
+Py:TrigDecTestAlg    INFO ==> execute...
+Py:TrigDecTestAlg    INFO Pass state EF = True
+Py:TrigDecTestAlg    INFO chain L2_e25i: passed: False
+Py:TrigDecTestAlg    INFO ==> execute...
+Py:TrigDecTestAlg    INFO Pass state EF = True
+Py:TrigDecTestAlg    INFO chain L2_e25i: passed: False
+Py:TrigDecTestAlg    INFO ==> finalize...
diff --git a/AtlasTest/PyAthenaTests/test/pyathena_utest.py b/AtlasTest/PyAthenaTests/test/pyathena_utest.py
new file mode 100644
index 00000000000..9619092388c
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathena_utest.py
@@ -0,0 +1,64 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# @purpose gather some helpers...
+import unittest
+import tempfile, os, commands, atexit, shutil
+
+### helper methods ------------------------------------------------------------
+def safe_remove(fname):
+    if os.path.exists(fname) and \
+       (os.path.isfile(fname) or os.path.islink(fname)):
+        atexit.register(os.unlink, fname)
+
+## For compatibility with ATN tests
+from TestTools.iobench import workDir
+def installRefFiles( fileNames, quiet=True ):
+    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) ):
+            if not quiet:
+                print " -%s" % workDir(refFile)
+            continue
+        try:
+            shutil.move(refFile, workDir(refFile))
+            if not quiet:
+                print " -%s" % workDir(refFile)
+        except OSError,err:
+            print "## ERROR: could not install [%s] into [%s]" %\
+                  ( refFile, workDir(refFile) )
+            print "## reason:\n",err
+            continue
+    return
+
+def _make_jobo(job):
+    jobo = tempfile.NamedTemporaryFile(suffix='.py')
+    jobo.writelines([l.strip()+os.linesep for l in job.splitlines()])
+    jobo.flush()
+    return jobo
+
+def _run_jobo(self, job):
+    jobo = _make_jobo(job)
+    cmd = ' '.join([self.app, jobo.name])
+    sc,out = commands.getstatusoutput(cmd)
+    self.failUnless(sc==0, 'problem running jobo:\n%s'%out)
+    jobo.close()
+    return out
+
+### capture the usual setUp/tearDown
+class PyAthenaTestCase (unittest.TestCase):
+    def setUp (self):
+        # base class setUp
+        super(PyAthenaTestCase,self).setUp()
+        sc, self.app = commands.getstatusoutput('which athena.py')
+        self.failUnless(sc==0, 'could not find \'athena.py\' !')
+    _run_jobo = _run_jobo
+    
diff --git a/AtlasTest/PyAthenaTests/test/pyathenatests_base.ref b/AtlasTest/PyAthenaTests/test/pyathenatests_base.ref
new file mode 100644
index 00000000000..0cbbf54df0b
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathenatests_base.ref
@@ -0,0 +1,157 @@
+Py:MySvc             INFO ==> initializing [MySvc]...
+Py:MySvc             INFO cnt: 0
+Py:alg1              INFO ==> initializing [alg1]...
+Py:alg1              INFO eta: 2.5
+Py:alg1              INFO pt:  42.0
+Py:alg1              INFO px:  10000.0
+Py:alg1_mytool       INFO ==> initializing [alg1_mytool]...
+Py:alg1_mytool       INFO cnt: 0
+Py:alg1              INFO tool:1 'alg1_mytool'
+Py:alg2              INFO ==> initializing [alg2]...
+Py:alg2              INFO eta: 5.0999999999999996
+Py:alg2              INFO pt:  20000.0
+Py:alg2              INFO px:  10000.0
+Py:alg2_mytool       INFO ==> initializing [alg2_mytool]...
+Py:alg2_mytool       INFO cnt: 0
+Py:alg2              INFO tool:1 'alg2_mytool'
+Py:alg3              INFO ==> initializing [alg3]...
+Py:alg3              INFO eta: 5.0999999999999996
+Py:alg3              INFO pt:  20000.0
+Py:alg3              INFO px:  10000.0
+Py:alg3_mytool       INFO ==> initializing [alg3_mytool]...
+Py:alg3_mytool       INFO cnt: 0
+Py:alg3              INFO tool:1 'alg3_mytool'
+Py:MyAlg             INFO ==> initializing [MyAlg]...
+Py:MyAlg             INFO eta: 5.2000000000000002
+Py:MyAlg             INFO pt:  40000.0
+Py:MyAlg             INFO px:  20000.0
+Py:MyAlg.mytool      INFO ==> initializing [MyAlg.mytool]...
+Py:MyAlg.mytool      INFO cnt: 30
+Py:MyAlg             INFO tool:31 'MyAlg.mytool'
+Py:seqalg1           INFO ==> initializing [seqalg1]...
+Py:seqalg1           INFO eta: 2.5
+Py:seqalg1           INFO pt:  40000.0
+Py:seqalg1           INFO px:  10000.0
+Py:seqalg1_mytool    INFO ==> initializing [seqalg1_mytool]...
+Py:seqalg1_mytool    INFO cnt: 0
+Py:seqalg1           INFO tool:1 'seqalg1_mytool'
+Py:seqalg2           INFO ==> initializing [seqalg2]...
+Py:seqalg2           INFO eta: 2.5
+Py:seqalg2           INFO pt:  40000.0
+Py:seqalg2           INFO px:  10000.0
+Py:seqalg2_mytool    INFO ==> initializing [seqalg2_mytool]...
+Py:seqalg2_mytool    INFO cnt: 0
+Py:seqalg2           INFO tool:1 'seqalg2_mytool'
+Py:seqalg3           INFO ==> initializing [seqalg3]...
+Py:seqalg3           INFO eta: 2.5
+Py:seqalg3           INFO pt:  40000.0
+Py:seqalg3           INFO px:  10000.0
+Py:seqalg3_mytool    INFO ==> initializing [seqalg3_mytool]...
+Py:seqalg3_mytool    INFO cnt: 0
+Py:seqalg3           INFO tool:1 'seqalg3_mytool'
+Py:sub1alg1          INFO ==> initializing [sub1alg1]...
+Py:sub1alg1          INFO eta: 2.5
+Py:sub1alg1          INFO pt:  40000.0
+Py:sub1alg1          INFO px:  10000.0
+Py:sub1alg1_mytool    INFO ==> initializing [sub1alg1_mytool]...
+Py:sub1alg1_mytool    INFO cnt: 0
+Py:sub1alg1          INFO tool:1 'sub1alg1_mytool'
+Py:sub1alg2          INFO ==> initializing [sub1alg2]...
+Py:sub1alg2          INFO eta: 2.5
+Py:sub1alg2          INFO pt:  40000.0
+Py:sub1alg2          INFO px:  10000.0
+Py:sub1alg2_mytool    INFO ==> initializing [sub1alg2_mytool]...
+Py:sub1alg2_mytool    INFO cnt: 0
+Py:sub1alg2          INFO tool:1 'sub1alg2_mytool'
+Py:sub1alg3          INFO ==> initializing [sub1alg3]...
+Py:sub1alg3          INFO eta: 2.5
+Py:sub1alg3          INFO pt:  40000.0
+Py:sub1alg3          INFO px:  10000.0
+Py:sub1alg3_mytool    INFO ==> initializing [sub1alg3_mytool]...
+Py:sub1alg3_mytool    INFO cnt: 0
+Py:sub1alg3          INFO tool:1 'sub1alg3_mytool'
+Py:sub2alg1          INFO ==> initializing [sub2alg1]...
+Py:sub2alg1          INFO eta: 2.5
+Py:sub2alg1          INFO pt:  40000.0
+Py:sub2alg1          INFO px:  10000.0
+Py:sub2alg1_mytool    INFO ==> initializing [sub2alg1_mytool]...
+Py:sub2alg1_mytool    INFO cnt: 0
+Py:sub2alg1          INFO tool:1 'sub2alg1_mytool'
+Py:sub2alg2          INFO ==> initializing [sub2alg2]...
+Py:sub2alg2          INFO eta: 2.5
+Py:sub2alg2          INFO pt:  40000.0
+Py:sub2alg2          INFO px:  10000.0
+Py:sub2alg2_mytool    INFO ==> initializing [sub2alg2_mytool]...
+Py:sub2alg2_mytool    INFO cnt: 0
+Py:sub2alg2          INFO tool:1 'sub2alg2_mytool'
+Py:sub2alg3          INFO ==> initializing [sub2alg3]...
+Py:sub2alg3          INFO eta: 2.5
+Py:sub2alg3          INFO pt:  40000.0
+Py:sub2alg3          INFO px:  10000.0
+Py:sub2alg3_mytool    INFO ==> initializing [sub2alg3_mytool]...
+Py:sub2alg3_mytool    INFO cnt: 0
+Py:sub2alg3          INFO tool:1 'sub2alg3_mytool'
+Py:alg1              INFO ==> execute...
+Py:alg1              INFO hasattr('_cppHandle'): True
+Py:alg1              INFO has passed filter: True
+Py:alg2              INFO ==> execute...
+Py:alg2              INFO hasattr('_cppHandle'): True
+Py:alg2              INFO has passed filter: True
+Py:alg3              INFO ==> execute...
+Py:alg3              INFO hasattr('_cppHandle'): True
+Py:alg3              INFO has passed filter: True
+Py:MyAlg             INFO ==> execute...
+Py:MyAlg             INFO hasattr('_cppHandle'): True
+Py:MyAlg             INFO has passed filter: True
+Py:seqalg1           INFO ==> execute...
+Py:seqalg1           INFO hasattr('_cppHandle'): True
+Py:seqalg1           INFO has passed filter: True
+Py:seqalg2           INFO ==> execute...
+Py:seqalg2           INFO hasattr('_cppHandle'): True
+Py:seqalg2           INFO has passed filter: False
+Py:sub1alg1          INFO ==> execute...
+Py:sub1alg1          INFO hasattr('_cppHandle'): True
+Py:sub1alg1          INFO has passed filter: True
+Py:sub1alg2          INFO ==> execute...
+Py:sub1alg2          INFO hasattr('_cppHandle'): True
+Py:sub1alg2          INFO has passed filter: False
+Py:alg1              INFO ==> execute...
+Py:alg1              INFO hasattr('_cppHandle'): True
+Py:alg1              INFO has passed filter: True
+Py:alg2              INFO ==> execute...
+Py:alg2              INFO hasattr('_cppHandle'): True
+Py:alg2              INFO has passed filter: True
+Py:alg3              INFO ==> execute...
+Py:alg3              INFO hasattr('_cppHandle'): True
+Py:alg3              INFO has passed filter: True
+Py:MyAlg             INFO ==> execute...
+Py:MyAlg             INFO hasattr('_cppHandle'): True
+Py:MyAlg             INFO has passed filter: True
+Py:seqalg1           INFO ==> execute...
+Py:seqalg1           INFO hasattr('_cppHandle'): True
+Py:seqalg1           INFO has passed filter: True
+Py:seqalg2           INFO ==> execute...
+Py:seqalg2           INFO hasattr('_cppHandle'): True
+Py:seqalg2           INFO has passed filter: False
+Py:sub1alg1          INFO ==> execute...
+Py:sub1alg1          INFO hasattr('_cppHandle'): True
+Py:sub1alg1          INFO has passed filter: True
+Py:sub1alg2          INFO ==> execute...
+Py:sub1alg2          INFO hasattr('_cppHandle'): True
+Py:sub1alg2          INFO has passed filter: False
+Py:alg1              INFO ==> finalize...
+Py:alg2              INFO ==> finalize...
+Py:alg3              INFO ==> finalize...
+Py:MyAlg             INFO ==> finalize...
+Py:seqalg1           INFO ==> finalize...
+Py:seqalg2           INFO ==> finalize...
+Py:seqalg3           INFO ==> finalize...
+Py:sub1alg1          INFO ==> finalize...
+Py:sub1alg2          INFO ==> finalize...
+Py:sub1alg3          INFO ==> finalize...
+Py:sub2alg1          INFO ==> finalize...
+Py:sub2alg2          INFO ==> finalize...
+Py:sub2alg3          INFO ==> finalize...
+Py:MySvc             INFO ==> finalize...
+Py:MySvc             INFO cnt: 0
+Py:Athena            INFO leaving with code 0: "successful run"
diff --git a/AtlasTest/PyAthenaTests/test/pyathenatests_histreader.ref b/AtlasTest/PyAthenaTests/test/pyathenatests_histreader.ref
new file mode 100644
index 00000000000..f20b7b5df7f
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathenatests_histreader.ref
@@ -0,0 +1,8 @@
+Py:PyHistReader      INFO ==> initialize...
+Py:PyHistReader      INFO  -gauss1d             : 20000 <mean>=  -0.010 rms=  14.952
+Py:PyHistReader      INFO  -gauss2d             : 20000 <mean>=   0.066 rms=  14.884
+Py:PyHistReader      INFO  -gauss3d             : 20000 <mean>=  -0.177 rms=  14.905
+Py:PyHistReader      INFO  -profile             : 0 <mean>=   0.000 rms=   0.000
+Py:PyHistReader      INFO  -tree1               : 1000
+Py:PyHistReader      INFO ==> execute...
+Py:PyHistReader      INFO ==> finalize...
diff --git a/AtlasTest/PyAthenaTests/test/pyathenatests_histwriter.ref b/AtlasTest/PyAthenaTests/test/pyathenatests_histwriter.ref
new file mode 100644
index 00000000000..ba045db4cb5
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/pyathenatests_histwriter.ref
@@ -0,0 +1,38 @@
+Py:PyHistWriter      INFO ==> initialize...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> execute...
+Py:PyHistWriter      INFO ==> finalize...
+Py:PyHistWriter      INFO ====================
+Py:PyHistWriter      INFO  - histo ['/temp/h1']
+Py:PyHistWriter      INFO  entries = 20
+Py:PyHistWriter      INFO     mean =   47.263
+Py:PyHistWriter      INFO     rms  =   32.046
+Py:PyHistWriter      INFO ====================
+Py:PyHistWriter      INFO  - histo ['/temp/other/h1a']
+Py:PyHistWriter      INFO  entries = 40
+Py:PyHistWriter      INFO     mean =   47.263
+Py:PyHistWriter      INFO     rms  =   32.046
+Py:PyHistWriter      INFO ====================
+Py:PyHistWriter      INFO  - histo ['/new/hists/h1']
+Py:PyHistWriter      INFO  entries = 60
+Py:PyHistWriter      INFO     mean =   47.263
+Py:PyHistWriter      INFO     rms  =   32.046
+Py:PyHistWriter      INFO ====================
diff --git a/AtlasTest/PyAthenaTests/test/utest_pyathena_base.py b/AtlasTest/PyAthenaTests/test/utest_pyathena_base.py
new file mode 100755
index 00000000000..fbd9eb254ad
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/utest_pyathena_base.py
@@ -0,0 +1,202 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# @author: Sebastien Binet <binet@cern.ch>
+
+"""Unit tests for verifying the proper working of basic functionalities of
+PyAthena"""
+import unittest, sys, atexit, os, commands, tempfile, re, difflib
+
+### data ----------------------------------------------------------------------
+__version__ = "$Revision: 1.10 $"
+__author__  = "Sebastien Binet <binet@cern.cn>"
+
+from pyathena_utest import *
+
+### basic functionalities -----------------------------------------------------
+class PyAthenaBase (PyAthenaTestCase):
+    """basic functionalities"""
+
+    def test1_base_tests (self):
+        """base tests"""
+        installRefFiles( ['pyathenatests_base.ref'] )
+        out = self._run_jobo("""include('AthenaPython/test_pyathena.py')""")
+        out_file = open(workDir('pyathenatests_base.log'), 'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [
+            l.strip() for l in out.splitlines()
+            if re.match('^Py:.', l) and
+            not re.match('^Py:ConfigurableDb.',l) and
+            not re.match('^Py:Athena.*? including file',l) and
+            not re.match('^Py:Athena.*? INFO using release', l) and
+            # disable MyNameAuditor as it captures too many
+            # string and component changes
+            not re.match('^Py:MyNameAuditor.', l) ]
+
+        ref_file = []
+        for l in open(workDir('pyathenatests_base.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(out_file.name)
+        return
+
+    def test2_hist_write (self):
+        """test writing histos and tuples w/ py-THistSvc"""
+        installRefFiles( ['pyathenatests_histwriter.ref'] )
+        out = self._run_jobo("""
+        ## http://docs.python.org/lib/module-random.html
+        ## initialize the pseudo-random numbers generator with a (dummy) seed
+        _seed = 1234567890
+        from random import seed as _init_seed
+        _init_seed(_seed)
+
+        ## real jobo
+        include ('AthenaPython/test_pyhistsvc_write.py')
+        """)
+        out_file = open(workDir('pyathenatests_histwriter.log'), 'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:PyHistWriter.', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathenatests_histwriter.ref'),'r'):
+            ref_file.append(l.strip())
+
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(out_file.name)
+        return
+
+    def test3_hist_read (self):
+        """test reading histos and tuples w/ py-THistSvc"""
+
+        installRefFiles( ['pyathenatests_histreader.ref'] )
+        out = self._run_jobo("""
+        include ('AthenaPython/test_pyhistsvc_read.py')
+        """)
+        out_file = open(workDir('pyathenatests_histreader.log'), 'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:PyHistReader.', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathenatests_histreader.ref'),'r'):
+            ref_file.append(l.strip())
+
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(out_file.name)
+        safe_remove('tuple1.root')
+        safe_remove('tuple2.root')
+        safe_remove('tuple3.root')
+        return
+
+    def test4_basic_record_retrieve (self):
+        """test basic record/retrieve with py-StoreGateSvc"""
+        installRefFiles( ['pyathena_basic_record_retrieve.ref'] )
+        output_pool_file = workDir('basic_record_retrieve.out.pool')
+        out = self._run_jobo("""
+        OUTPUT='%(OUTPUT)s'
+        include ('PyAthenaTests/pyathena_basic_record_retrieve.py')
+        """ % { 'OUTPUT' : output_pool_file }
+        )
+        self.failUnless(os.path.exists(output_pool_file))
+        
+        out_file = open(workDir('pyathena_basic_record_retrieve.log'), 'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:re.', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_basic_record_retrieve.ref'),'r'):
+            ref_file.append(l.strip())
+
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(out_file.name)
+        safe_remove(output_pool_file)
+        return
+        
+    def test5_stream_filter (self):
+        """test that filtering stream works"""
+
+        input_pool = [
+            '/afs/cern.ch/atlas/project/rig/referencefiles/dataStreams_ESD.AOD_50Events/data10_7TeV.00167607.physics_JetTauEtmiss.recon.ESD.f298._lb0087._SFO-4._0001.1_50Events_rel.16.0.3.8_rereco'
+            ]
+        output_pool_file = workDir('pyathena_basic_filtered_rel140100.pool')
+        basic_asciilog = workDir('basic_passed_evts.ascii')
+        out = self._run_jobo("""
+        EVTMAX=-1;
+        INPUT=%(INPUT)s
+        OUTPUT='%(OUTPUT)s'
+        ASCIILOG='%(ASCIILOG)s'
+        include('PyAthenaTests/pyfilter_stream_jobOptions.py')
+        """ % { 'INPUT' :input_pool,
+                'OUTPUT':output_pool_file,
+                'ASCIILOG' : basic_asciilog
+                } )
+
+        self.failUnless(os.path.exists(output_pool_file))
+        self.failUnless(os.path.exists(basic_asciilog))
+        
+        # now run the eventinfo dumper alg
+        input_pool = [ output_pool_file ]
+        asciilog   = workDir('evtlist.ascii')
+        out = self._run_jobo("""
+        EVTMAX=-1
+        INPUT=%(INPUT)s
+        ASCIILOG='%(ASCIILOG)s'
+        include ('PyAthenaTests/pyevtinfo_jobOptions.py')
+        """ % { 'INPUT' : input_pool,
+                'ASCIILOG' : asciilog
+                })
+        self.failUnless(os.path.exists(asciilog))
+        
+        ref_file = [ l.strip() for l in open(basic_asciilog,'r') ]
+        evt_file = [ l.strip() for l in open(asciilog, 'r') ]
+
+        diff = difflib.unified_diff(evt_file, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(output_pool_file)
+        safe_remove(basic_asciilog)
+        safe_remove(asciilog)
+        
+        return
+
+## actual test run
+if __name__ == '__main__':
+   loader = unittest.TestLoader()
+   testSuite = loader.loadTestsFromModule( sys.modules[ __name__ ] )
+
+   runner = unittest.TextTestRunner( verbosity = 2 )
+   result = not runner.run( testSuite ).wasSuccessful()
+
+ # don't want to depend on gaudimodule
+   assert( not 'gaudimodule' in sys.modules )
+
+   sys.exit( result )
diff --git a/AtlasTest/PyAthenaTests/test/utest_pyathena_pyclusters.py b/AtlasTest/PyAthenaTests/test/utest_pyathena_pyclusters.py
new file mode 100755
index 00000000000..4edd4a5c54a
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/utest_pyathena_pyclusters.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# @author: Sebastien Binet <binet@cern.ch>
+
+"""Unit tests for verifying the proper working of inspecting clusters in
+PyAthena"""
+import unittest, sys, atexit, os, commands, tempfile, re, difflib
+
+### data ----------------------------------------------------------------------
+__version__ = "$Revision: 1.5 $"
+__author__  = "Sebastien Binet <binet@cern.cn>"
+
+from pyathena_utest import *
+
+### running over clusters -----------------------------------------------------
+class PyClustersTest (PyAthenaTestCase):
+    """Running over clusters"""
+
+    def test1_batch_clusters_in_release_140100_data (self):
+        """batch clusters in release 14.1.0.x data"""
+        installRefFiles(['pyathena_pyclusters_rel140100.ref'])
+        
+        input_pool = [
+            'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+            '/AllBasicSamples.AOD.pool.root'
+            ]
+        output_root_file = workDir('pyathena_pyclusters_rel140100.pool')
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)s
+        TUPLEOUT='%(OUTPUT)s'
+        include('PyAthenaTests/pyclusters_jobOptions.py')
+        """ % { 'INPUT' :input_pool,
+                'OUTPUT':output_root_file,
+                }
+        )
+        out_file = open(workDir('pyathena_pyclusters_rel140100.log'), 'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:ClusterExAlg .', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pyclusters_rel140100.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(output_root_file)
+        safe_remove(out_file.name)
+        return
+        
+    def test2_ares_batch_clusters_in_release_140100_data (self):
+        """batch clusters in release 14.1.0.x data (via Ares)"""
+        return
+    
+        ## note: same ref-file than for test1
+        installRefFiles(['pyathena_pyclusters_rel140100.ref'])
+
+        input_pool = [
+            'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+            '/AllBasicSamples.AOD.pool.root'
+            ]
+        output_root_file = workDir('ares_pyclusters_rel140100.pool')
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)s
+        TUPLEOUT='%(OUTPUT)s'
+        include('PyAthenaTests/ares_clusters_jobOptions.py')
+        """ % { 'INPUT' :input_pool,
+                'OUTPUT':output_root_file,
+                }
+        )
+        out_file = open(workDir('ares_pyclusters_rel140100.log'), 'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:ClusterExAlg .', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pyclusters_rel140100.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(output_root_file)
+        safe_remove(out_file.name)
+        return
+        
+        
+## actual test run
+if __name__ == '__main__':
+   loader = unittest.TestLoader()
+   testSuite = loader.loadTestsFromModule( sys.modules[ __name__ ] )
+
+   runner = unittest.TextTestRunner( verbosity = 2 )
+   result = not runner.run( testSuite ).wasSuccessful()
+
+ # don't want to depend on gaudimodule
+   assert( not 'gaudimodule' in sys.modules )
+
+   sys.exit( result )
diff --git a/AtlasTest/PyAthenaTests/test/utest_pyathena_pyfdr.py b/AtlasTest/PyAthenaTests/test/utest_pyathena_pyfdr.py
new file mode 100755
index 00000000000..55ab9fbcc2b
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/utest_pyathena_pyfdr.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# @author: Sebastien Binet <binet@cern.ch>
+
+"""Unit tests for verifying the proper working of various FDR jobo examples
+via PyAthena"""
+import unittest, sys, atexit, os, commands, tempfile, re, difflib
+
+### data ----------------------------------------------------------------------
+__version__ = "$Revision: 1.5 $"
+__author__  = "Sebastien Binet <binet@cern.cn>"
+
+from pyathena_utest import *
+
+### basic FDR tests -----------------------------------------------------------
+class PyBasicFdrTests (PyAthenaTestCase):
+    """Basic tests for py-FDR"""
+
+    def test1_pyfdr_aodtodpd_on_release_140100_data (self):
+        """testing aodtodpd jobo on release 14.1.0.x data"""
+
+        installRefFiles( ['pyathena_pyfdr_aodtodpd_rel140100.ref'] )
+
+        input_pool = [
+            'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+            '/AllBasicSamples.AOD.pool.root'
+            ]
+        output_pool_file = workDir('pyathena_pyfdr_aodtodpd_rel140100.pool')
+        out = self._run_jobo(
+        """
+        EVTMAX=-1;
+        OUTPUT='%(OUTPUT)s'
+        include('DPDUtils/aodtodpd.py')
+        svcMgr.EventSelector.InputCollections = %(INPUT)r
+        StreamDPD.OutputFile = OUTPUT
+        svcMgr.GeoModelSvc.AtlasVersion = 'ATLAS-CSC-05-01-00'
+        """ % { 'INPUT' : input_pool,
+                'OUTPUT': output_pool_file,
+                }
+        )
+
+        self.failUnless(os.path.exists(output_pool_file))
+
+        out_file = open(workDir('pyathena_pyfdr_aodtodpd_rel140100.log'), 'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if  re.match('^Py:.', l) and
+                         not re.match('^Py:ConfigurableDb.',l) and
+                         not re.match('^Py:Athena.*? INFO including.', l) ]
+            
+        ref_file = []
+        for l in open(workDir('pyathena_pyfdr_aodtodpd_rel140100.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(output_pool_file)
+        safe_remove(out_file.name)
+        return
+
+    def test2_thin_mctruth_release_140100_data (self):
+        """thinning/slimming of mctruth (release 14.1.0.x data)"""
+
+        installRefFiles( ['pyathena_pyfdr_truthslimming_rel140100.ref'] )
+        input_pool = [
+            'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+            '/AllBasicSamples.AOD.pool.root'
+            ]
+        output_pool_file = workDir('pyathena_pyfdr_truthslimming_rel140100.pool')
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)r
+        OUTPUT='%(OUTPUT)s'
+        include('PyAthenaTests/pythin_mctruth_jobOptions.py')
+        """ % { 'INPUT' : input_pool,
+                'OUTPUT':output_pool_file})
+        out_file = open(workDir('pyathena_pyfdr_truthslimming_rel140100.log'),
+                        'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:mc_.*?_dumper.', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pyfdr_truthslimming_rel140100.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(output_pool_file)
+        safe_remove(out_file.name)
+        return
+
+    pass # PyBasicFdrTests
+
+## actual test run
+if __name__ == '__main__':
+   loader = unittest.TestLoader()
+   testSuite = loader.loadTestsFromModule( sys.modules[ __name__ ] )
+
+   runner = unittest.TextTestRunner( verbosity = 2 )
+   result = not runner.run( testSuite ).wasSuccessful()
+
+ # don't want to depend on gaudimodule
+   assert( not 'gaudimodule' in sys.modules )
+
+   sys.exit( result )
diff --git a/AtlasTest/PyAthenaTests/test/utest_pyathena_pythinner.py b/AtlasTest/PyAthenaTests/test/utest_pyathena_pythinner.py
new file mode 100755
index 00000000000..48965f77582
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/utest_pyathena_pythinner.py
@@ -0,0 +1,601 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# @author: Sebastien Binet <binet@cern.ch>
+
+"""Unit tests for verifying the proper working of thinning via PyAthena"""
+import unittest, sys, atexit, os, commands, tempfile, re, difflib
+
+### data ----------------------------------------------------------------------
+__version__ = "$Revision: 1.13 $"
+__author__  = "Sebastien Binet <binet@cern.cn>"
+
+from pyathena_utest import *
+
+### basic thinning of data ----------------------------------------------------
+class PyBasicThinning (PyAthenaTestCase):
+    """Thinning of basic data"""
+
+    def test1_basic_thinning (self):
+        """test basic thinning of basic data"""
+
+        installRefFiles( ['pyathena_pythinner_basic_thinning.ref'] )
+
+        ## prepare input file
+        output_pool_file = workDir('basic_athexparticles.pool')
+        out = self._run_jobo("""
+        EVTMAX=5;
+        OUTPUT='%(OUTPUT)s'
+        include('AthExThinning/AthExThinning_makeData.py')
+        job = AlgSequence()
+        job.CreateData.TestNames = ['basic']
+        """ % {'OUTPUT':output_pool_file})
+
+        self.failUnless(os.path.exists(output_pool_file))
+
+        ## run basic thinning
+        input_pool_file  = workDir('basic_athexparticles.pool')
+        output_pool_file = workDir('thinned.basic_athexparticles.pool')
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)r
+        OUTPUT='%(OUTPUT)s'
+        include('PyAthenaTests/pythin_basic_jobOptions.py')
+        job = AlgSequence()
+        job.thinner.coll_name = 'Particles_basic'
+
+        ## and append an alg-reader to make sure data and links are not
+        ## corrupted by the ThinningSvc
+        job += CfgMgr.AthExThinning__ReadThinnedData(
+               'ReadThinnedData',
+               Particles   = 'Particles',
+               Decay       = 'TwoBodyDecay',
+               Elephantino = 'PinkElephantino',
+               TestNames   = ['basic'],
+               OutputLevel = DEBUG
+               )
+        """ % {
+                'INPUT' :[input_pool_file],
+                'OUTPUT':output_pool_file
+                }
+            )
+
+        self.failUnless(os.path.exists(output_pool_file))
+
+        out_file = open('pyathena_pythinner_basic_thinning.log', 'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:thinner .', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pythinner_basic_thinning.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(input_pool_file)
+        safe_remove(output_pool_file)
+        safe_remove(out_file.name)
+        return
+        
+    def test2_multistream_thinning (self):
+        """test multistream thinning of basic data"""
+
+        installRefFiles( ['pyathena_pythinner_multistream_thinning.ref',
+                          'pyathena_pythinner_multistream_check_thin0.ref',
+                          'pyathena_pythinner_multistream_check_thin1.ref',
+                          'pyathena_pythinner_multistream_check_thin2.ref'] )
+
+        ## prepare input file
+        output_pool_file = workDir('multistream_athexparticles.pool')
+        out = self._run_jobo("""
+        EVTMAX=5;
+        OUTPUT='%(OUTPUT)s'
+        include('AthExThinning/AthExThinning_makeData.py')
+        job = AlgSequence()
+        job.CreateData.TestNames = ['0', '1']
+
+        ## import my algorithm and add it to the list of algorithms to be run
+        from PyAthenaTests.Lib import ThinChecker
+        ## checking containers content
+        job += ThinChecker(name='thin_checker_0', OutputLevel = INFO)
+        job.thin_checker_0.coll_type = 'AthExParticles'
+        job.thin_checker_0.coll_name = 'Particles_0'
+
+        job += ThinChecker(name='thin_checker_1', OutputLevel = INFO)
+        job.thin_checker_1.coll_type = 'AthExParticles'
+        job.thin_checker_1.coll_name = 'Particles_1'
+        """ % {'OUTPUT':output_pool_file})
+
+        self.failUnless(os.path.exists(output_pool_file))
+
+        ## validating output
+        prod_file = open(workDir('pyathena_pythinner_multistream_makedata.log'),
+                         'w')
+        prod_file.writelines( [l for l in out] )
+        prod_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:thin_checker_[01] .', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pythinner_multistream_check_thin2.ref'),
+                      'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## run multistream thinning
+        input_pool_file  = workDir('multistream_athexparticles.pool')
+        output0_pool_file = workDir('thinned_0.multistream_athexparticles.pool')
+        output1_pool_file = workDir('thinned_1.multistream_athexparticles.pool')
+        output2_pool_file = workDir('not_thinned.multistream_athexparticles.pool')
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)r
+        OUTPUT_0='%(OUTPUT_0)s'
+        OUTPUT_1='%(OUTPUT_1)s'
+        OUTPUT_NOTHINNING='%(OUTPUT_NOTHINNING)s'
+        include('PyAthenaTests/pythin_multistream_jobOptions.py')
+        """ % {
+                'INPUT' :[input_pool_file],
+                'OUTPUT_0':output0_pool_file,
+                'OUTPUT_1':output1_pool_file,
+                'OUTPUT_NOTHINNING':output2_pool_file,
+                }
+            )
+
+        self.failUnless(os.path.exists(output0_pool_file))
+        self.failUnless(os.path.exists(output1_pool_file))
+        self.failUnless(os.path.exists(output2_pool_file))
+
+        out_file = open(workDir('pyathena_pythinner_multistream_thinning.log'),
+                        'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:thinner_[01] .', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pythinner_multistream_thinning.ref'),
+                      'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## run checking algorithms
+
+        # - validating output-0
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)r
+        include('PyAthenaTests/pythin_multistream_checker_jobOptions.py')
+        """ % {
+                'INPUT' :[output0_pool_file],
+                }
+            )
+        
+        chk0_file = open(
+            workDir('pyathena_pythinner_multistream_check_thin0.log'), 'w')
+        chk0_file.writelines( [l for l in out] )
+        chk0_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:thin_checker_[01] .', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pythinner_multistream_check_thin0.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        # - validating output-1
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)r
+        include('PyAthenaTests/pythin_multistream_checker_jobOptions.py')
+        """ % {
+                'INPUT' :[output1_pool_file],
+                }
+            )
+        
+        chk1_file = open(
+            workDir('pyathena_pythinner_multistream_check_thin1.log'), 'w')
+        chk1_file.writelines( [l for l in out] )
+        chk1_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:thin_checker_[01] .', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pythinner_multistream_check_thin1.ref'),
+                      'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        # - validating output-2
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)r
+        include('PyAthenaTests/pythin_multistream_checker_jobOptions.py')
+        """ % {
+                'INPUT' :[output2_pool_file],
+                }
+            )
+        
+        chk2_file = open(
+            workDir('pyathena_pythinner_multistream_check_thin2.log'), 'w')
+        chk2_file.writelines( [l for l in out] )
+        chk2_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:thin_checker_[01] .', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pythinner_multistream_check_thin2.ref'),
+                      'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(input_pool_file)
+        safe_remove(output0_pool_file)
+        safe_remove(output1_pool_file)
+        safe_remove(output2_pool_file)
+        safe_remove(prod_file.name)
+        safe_remove(out_file.name)
+        safe_remove(chk0_file.name)
+        safe_remove(chk1_file.name)
+        safe_remove(chk2_file.name)
+        return
+        
+### thinning of atlfast-aod data ----------------------------------------------
+class PyThinAtlfastAod (PyAthenaTestCase):
+    """Thinning of atlfast-aod data"""
+
+    def test1_thin_release_140100_data (self):
+        """atlfast thinning of release 14.1.0.x data"""
+
+        installRefFiles( ['pyathena_pythinner_atlfast_rel140100.ref'] )
+        input_pool = [
+            'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+            '/AllBasicSamples.AOD.pool.root'
+            ]
+        output_pool_file = workDir('pyathena_pythinner_atlfast_rel140100.pool')
+        out = self._run_jobo(
+        """
+        EVTMAX=10;
+        INPUT=%(INPUT)r
+        OUTPUT='%(OUTPUT)s'
+        include('PyAthenaTests/pythin_jobOptions.py')
+        job.Thinner.coll_type = 'JetCollection'
+        job.Thinner.coll_name = 'AtlfastJetContainer'
+        job.OutStream.TakeItemsFromInput = False
+        job.OutStream.ForceRead = False
+        job.OutStream.ItemList = [ 'EventInfo#*', 'JetCollection#*' ]
+        """ % { 'INPUT' : input_pool,
+                'OUTPUT':output_pool_file})
+        out_file = open(workDir('pyathena_pythinner_atlfast_rel140100.log'),
+                        'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:Thinner .', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pythinner_atlfast_rel140100.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(output_pool_file)
+        safe_remove(out_file.name)
+        return
+    pass # class PyThinAtlfastAod
+
+### thinning of reco-aod data -------------------------------------------------
+class PyThinRecAod (PyAthenaTestCase):
+    """Thinning of reco-aod data"""
+
+    def test1_thin_jets_release_140100_data (self):
+        """reco-aod thinning of jets (release 14.1.0.x data)"""
+
+
+        ##FIXME ### DOES NOT WORK AS OF 2008-05-27
+        return
+    
+        installRefFiles( ['pyathena_pythinner_reco-aod_jets_rel140100.ref'] )
+        input_pool = [
+            'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+            '/AllBasicSamples.AOD.pool.root'
+            ]
+        output_pool_file = workDir('pyathena_pythinner_reco-aod_jets_rel140100.pool')
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)r
+        OUTPUT='%(OUTPUT)s'
+        include('PyAthenaTests/utest_thin_jets_release_140100.py')
+        """ % { 'INPUT' : input_pool,
+                'OUTPUT':output_pool_file})
+        out_file = open(workDir('pyathena_pythinner_reco-aod_jets_rel140100.log'),
+                        'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:thin_.', l) 
+                         or re.match('^Py:jet_slimmer.', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pythinner_reco-aod_jets_rel140100.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(output_pool_file)
+        safe_remove(out_file.name)
+        return
+
+    def test2_thin_eles_release_140100_data (self):
+        """reco-aod thinning of electrons (release 14.1.0.x data)"""
+
+        ##FIXME ### DOES NOT WORK AS OF 2010-08-26
+        return
+
+        installRefFiles( ['pyathena_pythinner_reco-aod_eles_rel140100.ref'] )
+        input_pool = [
+            'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+            '/AllBasicSamples.AOD.pool.root'
+            ]
+        output_pool_file = workDir('pyathena_pythinner_reco-aod_eles_rel140100.pool')
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)r
+        OUTPUT='%(OUTPUT)s'
+        include('PyAthenaTests/utest_thin_eles_release_140100.py')
+        """ % { 'INPUT' : input_pool,
+                'OUTPUT':output_pool_file})
+        out_file = open(workDir('pyathena_pythinner_reco-aod_eles_rel140100.log'),
+                        'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:thin_.', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pythinner_reco-aod_eles_rel140100.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(output_pool_file)
+        safe_remove(out_file.name)
+        return
+
+    def test3_thin_photons_release_140100_data (self):
+        """reco-aod thinning of photons (release 14.1.0.x data)"""
+
+        ##FIXME ### DOES NOT WORK AS OF 2010-08-26
+        return
+
+        installRefFiles( ['pyathena_pythinner_reco-aod_photons_rel140100.ref'] )
+        input_pool = [
+            'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+            '/AllBasicSamples.AOD.pool.root'
+            ]
+        output_pool_file = workDir('pyathena_pythinner_reco-aod_photons_rel140100.pool')
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)r
+        OUTPUT='%(OUTPUT)s'
+        include('PyAthenaTests/utest_thin_photons_release_140100.py')
+        """ % { 'INPUT' : input_pool,
+                'OUTPUT':output_pool_file})
+        out_file = open(workDir('pyathena_pythinner_reco-aod_photons_rel140100.log'),
+                        'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:thin_.', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pythinner_reco-aod_photons_rel140100.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(output_pool_file)
+        safe_remove(out_file.name)
+        return
+
+    def test4_thin_taus_release_140100_data (self):
+        """reco-aod thinning of taus (release 14.1.0.x data)"""
+
+        ##FIXME ### DOES NOT WORK AS OF 2010-08-26
+        return
+
+        
+        installRefFiles( ['pyathena_pythinner_reco-aod_taus_rel140100.ref'] )
+        input_pool = [
+            'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+            '/AllBasicSamples.AOD.pool.root'
+            ]
+        output_pool_file = workDir('pyathena_pythinner_reco-aod_taus_rel140100.pool')
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)r
+        OUTPUT='%(OUTPUT)s'
+        include('PyAthenaTests/utest_thin_taus_release_140100.py')
+        """ % { 'INPUT' : input_pool,
+                'OUTPUT':output_pool_file})
+        out_file = open(workDir('pyathena_pythinner_reco-aod_taus_rel140100.log'),
+                        'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:thin_.', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pythinner_reco-aod_taus_rel140100.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(output_pool_file)
+        safe_remove(out_file.name)
+        return
+
+    def test5_thin_muons_release_140100_data (self):
+        """reco-aod thinning of muons (release 14.1.0.x data)"""
+
+        ##FIXME ### DOES NOT WORK AS OF 2010-08-26
+        return
+
+        installRefFiles( ['pyathena_pythinner_reco-aod_muons_rel140100.ref'] )
+        input_pool = [
+            'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+            '/AllBasicSamples.AOD.pool.root'
+            ]
+        output_pool_file = workDir('pyathena_pythinner_reco-aod_muons_rel140100.pool')
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)r
+        OUTPUT='%(OUTPUT)s'
+        include('PyAthenaTests/utest_thin_muons_release_140100.py')
+        """ % { 'INPUT' : input_pool,
+                'OUTPUT':output_pool_file})
+        out_file = open(workDir('pyathena_pythinner_reco-aod_muons_rel140100.log'),
+                        'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:thin_.', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pythinner_reco-aod_muons_rel140100.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(output_pool_file)
+        safe_remove(out_file.name)
+        return
+
+    pass # class PyThinRecAod
+
+### thinning of reco-esd data -------------------------------------------------
+class PyThinRecEsd (PyAthenaTestCase):
+    """Thinning of reco-esd data"""
+
+    def test1_thin_cells_release_140100_data (self):
+        """reco-esd thinning of calocells (release 14.1.0.x data)"""
+
+        ##FIXME ### DOES NOT WORK AS OF 2010-08-26
+        return
+
+        installRefFiles( ['pyathena_pythinner_reco-esd_calocells_rel140100.ref'] )
+        input_pool = [
+            'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+            '/AllBasicSamples.ESD.pool.root'
+            ]
+        output_pool_file = workDir('pyathena_pythinner_reco-esd_calocells_rel140100.pool')
+
+        out = self._run_jobo(
+        """
+        EVTMAX=5;
+        INPUT=%(INPUT)r
+        OUTPUT='%(OUTPUT)s'
+
+        include('PyAthenaTests/utest_thin_cells_release_140100.py')
+        """ % { 'INPUT' : input_pool,
+                'OUTPUT': output_pool_file,})
+        out_file = open(workDir('pyathena_pythinner_reco-esd_calocells_rel140100.log'),
+                        'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:Thinner .', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_pythinner_reco-esd_calocells_rel140100.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## make sure the StreamESD from reprocessing hasn't been run...
+        self.failUnless(not os.path.exists('dummy.esd.pool'))
+        
+        ## delete files if all good
+        safe_remove(output_pool_file)
+        safe_remove(out_file.name)
+        return
+
+    pass # class PyThinRecEsd
+
+
+## actual test run
+if __name__ == '__main__':
+   loader = unittest.TestLoader()
+   testSuite = loader.loadTestsFromModule( sys.modules[ __name__ ] )
+
+   runner = unittest.TextTestRunner( verbosity = 2 )
+   result = not runner.run( testSuite ).wasSuccessful()
+
+ # don't want to depend on gaudimodule
+   assert( not 'gaudimodule' in sys.modules )
+
+   sys.exit( result )
diff --git a/AtlasTest/PyAthenaTests/test/utest_pyathena_pytrigdec.py b/AtlasTest/PyAthenaTests/test/utest_pyathena_pytrigdec.py
new file mode 100755
index 00000000000..16a1a13738e
--- /dev/null
+++ b/AtlasTest/PyAthenaTests/test/utest_pyathena_pytrigdec.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# @author: Sebastien Binet <binet@cern.ch>
+
+"""Unit tests for verifying the proper working of trigdectool via PyAthena"""
+import unittest, sys, atexit, os, commands, tempfile, re, difflib
+
+### data ----------------------------------------------------------------------
+__version__ = "$Revision: 1.5 $"
+__author__  = "Sebastien Binet <binet@cern.cn>"
+
+from pyathena_utest import *
+
+### running trig decision tool ------------------------------------------------
+class PyTrigDecisionTool (PyAthenaTestCase):
+    """running trigdecision tool from pyathena"""
+
+    def test1_trigdectool_on_release_140100_data (self):
+        """trigdectool on release 14.1.0.x data"""
+
+        installRefFiles( ['pyathena_trigdectool_rel140100.ref'] )
+        input_pool = [
+            'root://eosatlas//eos/atlas/user/b/binet/reffiles/14.1.0.x'\
+            '/AllBasicSamples.AOD.pool.root'
+            ]
+        output_pool_file = 'pyathena_pytrigdectool_rel140100.pool'
+        asciilog = 'trig_passed_evts.ascii'
+        out = self._run_jobo(
+        """
+        EVTMAX=10;
+        INPUT=%(INPUT)s
+        OUTPUT='%(OUTPUT)s'
+        ASCIILOG='%(ASCIILOG)s'
+        include('PyAthenaTests/pytrigdec_jobOptions.py')
+        """ % { 'INPUT' :input_pool,
+                'OUTPUT':output_pool_file,
+                'ASCIILOG': asciilog
+                }
+        )
+        out_file = open(workDir('pyathena_trigdectool_rel140100.log'), 'w')
+        out_file.writelines( [l for l in out] )
+        out_file.flush()
+
+        out_for_diff = [ l.strip() for l in out.splitlines()
+                         if re.match('^Py:TrigDecTestAlg .', l) ]
+        
+        ref_file = []
+        for l in open(workDir('pyathena_trigdectool_rel140100.ref'),'r'):
+            ref_file.append(l.strip())
+            
+        diff = difflib.unified_diff(out_for_diff, ref_file)
+        diff = os.linesep.join( [d for d in diff] )
+        self.failUnless(diff=='', diff)
+
+        ## delete files if all good
+        safe_remove(output_pool_file)
+        safe_remove(out_file.name)
+        safe_remove(asciilog)
+        return
+        
+        
+        
+## actual test run
+if __name__ == '__main__':
+   loader = unittest.TestLoader()
+   testSuite = loader.loadTestsFromModule( sys.modules[ __name__ ] )
+
+   runner = unittest.TextTestRunner( verbosity = 2 )
+   result = not runner.run( testSuite ).wasSuccessful()
+
+ # don't want to depend on gaudimodule
+   assert( not 'gaudimodule' in sys.modules )
+
+   sys.exit( result )
-- 
GitLab