diff --git a/Calorimeter/CaloCellCorrection/src/CaloCellPedestalCorr.cxx b/Calorimeter/CaloCellCorrection/src/CaloCellPedestalCorr.cxx
index 0d6b1e993bb30144e233bbeab702c81f1f98965c..14bf9d2011096ca8726ff8d45e66e3f80ab62983 100755
--- a/Calorimeter/CaloCellCorrection/src/CaloCellPedestalCorr.cxx
+++ b/Calorimeter/CaloCellCorrection/src/CaloCellPedestalCorr.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // ****************************************************************************************
@@ -52,11 +52,9 @@ StatusCode CaloCellPedestalCorr::initialize()
 
   ATH_CHECK(detStore()->retrieve(m_cellId, "CaloCell_ID"));
 
-  if (m_lumi0<0 && !m_isMC) {
-    ATH_CHECK(m_lumiFolderName.initialize());
-  }
+  ATH_CHECK(m_lumiFolderName.initialize(m_lumi0<0 && !m_isMC));
+  ATH_CHECK(m_pedShiftFolder.initialize(!m_isMC));
   if (!m_isMC) {
-    ATH_CHECK(m_pedShiftFolder.initialize());
     ATH_CHECK(m_caloCoolIdTool.retrieve());
   }
 
diff --git a/Calorimeter/CaloClusterCorrection/python/CaloSwPhioff_v5data.py b/Calorimeter/CaloClusterCorrection/python/CaloSwPhioff_v5data.py
index 5b7cbaf6c081731a3a9add76d3a1a7ce41604378..6a11bc7ed176f060299ad65120e58fe5e0f78e45 100755
--- a/Calorimeter/CaloClusterCorrection/python/CaloSwPhioff_v5data.py
+++ b/Calorimeter/CaloClusterCorrection/python/CaloSwPhioff_v5data.py
@@ -1,7 +1,5 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-#
-# $Id: CaloSwPhioff_v5data.py 579457 2014-01-21 21:20:22Z ehill $
 #
 # File: CaloClusterCorrection/python/CaloSwPhioff_v5_data.py
 # Created: Sep 2010, sss
@@ -33,6 +31,7 @@ def _flip_phi (corr):
     
 def _copy_parms (src, dst):
     for (k, v) in src.__dict__.items():
+        if k[0] == '_': continue
         if k == 'correction':
             v = _flip_phi (v)
         setattr (dst, k, v)
diff --git a/Calorimeter/CaloClusterCorrection/python/common.py b/Calorimeter/CaloClusterCorrection/python/common.py
index 814e69783c5b61c70d1f172e5d3a2e387a054ed5..f71b6117e59e99c9fef26ad7c888c1d719576114 100755
--- a/Calorimeter/CaloClusterCorrection/python/common.py
+++ b/Calorimeter/CaloClusterCorrection/python/common.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 #
 # $Id: common.py,v 1.39 2009-05-20 20:48:52 ssnyder Exp $
@@ -1120,7 +1120,7 @@ from AthenaCommon.Configurable import Configurable
 def _calocorr_setup (self):
     save_properties = {}
     try:
-        for (k, v) in self._properties.items():
+        for (k, v) in list(self._properties.items()):
             if self in v.history and len (v.history[self]) >= 1:
                 pass
             else:
diff --git a/Calorimeter/CaloRec/python/CaloRecFlags.py b/Calorimeter/CaloRec/python/CaloRecFlags.py
index bb6f10ecd1022ec247009a4d03861282596929ee..6fa0d33277e133b1ab6e4f14eb93a59fb2276853 100644
--- a/Calorimeter/CaloRec/python/CaloRecFlags.py
+++ b/Calorimeter/CaloRec/python/CaloRecFlags.py
@@ -135,7 +135,7 @@ class doEMDigits(CaloRecFlagsJobProperty):
    """
    statusOn = True
    allowedTypes=['bool']
-   StoredValue=True
+   StoredValue=False
 
 class doFillMBTSBackgroundBit(CaloRecFlagsJobProperty):
     """ swtich to active filling of MBTS bit in the background word of the EventInfo object
diff --git a/Calorimeter/CaloRec/src/CaloClusterCorrDumper.cxx b/Calorimeter/CaloRec/src/CaloClusterCorrDumper.cxx
index bad4ba0d079f5aa1f5264441153a80286122255b..3096077ca993d680531641f7d57d1feb00ed9752 100644
--- a/Calorimeter/CaloRec/src/CaloClusterCorrDumper.cxx
+++ b/Calorimeter/CaloRec/src/CaloClusterCorrDumper.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //-----------------------------------------------------------------------
@@ -9,102 +9,24 @@
 
 
 #include "CaloClusterCorrDumper.h"
-//#include "GaudiKernel/ISvcLocator.h"
-//#include "GaudiKernel/StatusCode.h"
-#include "GaudiKernel/MsgStream.h"
-//#include "GaudiKernel/IToolSvc.h"
-#include "GaudiKernel/ListItem.h"
+#include "StoreGate/ReadCondHandle.h"
 
-//#include "CaloRec/ToolWithConstantsMixin.h"
-#include "CaloConditions/ToolConstants.h"
-
-#include <fstream>
-
-
-//###############################################################################
-CaloClusterCorrDumper::CaloClusterCorrDumper(const std::string& name, 
-                                             ISvcLocator* pSvcLocator) 
-  : AthAlgorithm(name, pSvcLocator)
-{
-  // Name(s) of Cluster Correction Tools
-  declareProperty("ClusterCorrectionTools", m_correctionToolNames,
-		  "List of Tools whose constants should be dumped");
-  declareProperty("FileName",m_fileName="","Name of output text file");
-}
-
-//###############################################################################
-
-CaloClusterCorrDumper::~CaloClusterCorrDumper()
-{ }
-
-//###############################################################################
-
-
-StatusCode CaloClusterCorrDumper::execute() {
-  return StatusCode::SUCCESS;
-}
 
 
 StatusCode CaloClusterCorrDumper::initialize()
 {
-  //Get ToolSvc  
-  IToolSvc*     p_toolSvc;
-  CHECK( service("ToolSvc", p_toolSvc) );
-  
-  // allocate tools derived from ToolsWithConstants
-  std::vector<std::string>::const_iterator firstTool=m_correctionToolNames.begin();
-  std::vector<std::string>::const_iterator lastTool =m_correctionToolNames.end();
-  for ( ; firstTool != lastTool; firstTool++ ) {
-    IAlgTool* algToolPtr;
-    ListItem  clusAlgoTool(*firstTool);
-    StatusCode scTool = p_toolSvc->retrieveTool(clusAlgoTool.type(),
-						clusAlgoTool.name(),
-						algToolPtr,
-						this
-						);
-    if ( scTool.isFailure() ) {
-      REPORT_MESSAGE(MSG::ERROR) << "Cannot find tool for " << *firstTool;
-    }
-    else {
-      REPORT_MESSAGE(MSG::INFO) /*<< m_key << ": "*/
-                                << "Found tool for " << *firstTool;
-      
-      // check for tool type
-      CaloRec::ToolWithConstantsMixin* theTool = 
-	dynamic_cast<CaloRec::ToolWithConstantsMixin*>(algToolPtr);
-      if ( theTool != 0 ) { 
-	m_correctionTools.push_back(theTool);
-      }
-    }
-  }
-  REPORT_MESSAGE(MSG::INFO) /*<< m_key << ": "*/
-                            << "Found " << m_correctionTools.size() <<
-    " tools.";
-
+  ATH_CHECK( m_constants.initialize() );
   return StatusCode::SUCCESS;
 }
 
-StatusCode CaloClusterCorrDumper::finalize() {
-  std::ofstream file;
-  file.open(m_fileName.c_str(),std::ios::app);
-  if (!file.is_open()) {
-    ATH_MSG_FATAL( "Failed to open file named " << m_fileName  );
-    return StatusCode::FAILURE;
-  }
-
 
-
-  std::vector<CaloRec::ToolWithConstantsMixin*>::const_iterator it=m_correctionTools.begin();
-  std::vector<CaloRec::ToolWithConstantsMixin*>::const_iterator it_e=m_correctionTools.end();
-  for (;it!=it_e;++it) {
-    file << "Dump of constants:" << std::endl;
-    (*it)->writeConstants(file,"dumper");
+StatusCode CaloClusterCorrDumper::execute (const EventContext& ctx) const
+{
+  for (const SG::ReadCondHandleKey<CaloRec::ToolConstants>& k : m_constants) {
+    SG::ReadCondHandle<CaloRec::ToolConstants> constant (k, ctx);
+    ATH_MSG_INFO( constant->toString ("dumper") );
   }
-
-
-  file.close();
   return StatusCode::SUCCESS;
 }
 
 
-
diff --git a/Calorimeter/CaloRec/src/CaloClusterCorrDumper.h b/Calorimeter/CaloRec/src/CaloClusterCorrDumper.h
index 07377b06a92ad84bed0eda111fc443b88cd19ba2..8895b7682a25e552dca2852de067ded24a0f3299 100644
--- a/Calorimeter/CaloRec/src/CaloClusterCorrDumper.h
+++ b/Calorimeter/CaloRec/src/CaloClusterCorrDumper.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef CALOREC_CALOCLUSTERCORRDUMPER
@@ -9,48 +9,31 @@
  * @class CaloClusterCorrDumper
  * @author Walter Lampl <walter.lampl@cern.ch>
  * @date March, 28th 2006
+ *   Reworked Jun 2020 sss
  *
- * This algorithm has only an @c initialize() and a @c finalize() method.
- * It instantiates all ClusterCorrection Tools given by jobOptions. The
- * cluster correction constants (@c ToolConstants) are expected to be
- * initialized by job options. In the @c finalize method, this algorithm
- * records these objects to the detector store so that they can be 
- * streamed out to a POOL file. 
+ * Dump out a set of @c ToolConstants objects from the conditions store.
  */
 
 
-
-#include "AthenaBaseComps/AthAlgorithm.h"
-#include "CaloRec/ToolWithConstantsMixin.h"
+#include "CaloConditions/ToolConstants.h"
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "StoreGate/CondHandleKeyArray.h"
 #include <vector>
 #include <string>
 
-class CaloClusterCorrDumper : public AthAlgorithm
-{
-
- public:
-
-  CaloClusterCorrDumper(const std::string& name, ISvcLocator* pSvcLocator);
-  virtual ~CaloClusterCorrDumper();
-  virtual StatusCode initialize();
-  virtual StatusCode execute();
-  virtual StatusCode finalize();
-  
- private:
 
-  //std::string m_inlineFolder;
-
-  /** @brief The list of tool names (jobOptions)*/
-  std::vector<std::string> m_correctionToolNames;
-
-  /** @brief the actual list of tools corresponding to above names */
-  std::vector<CaloRec::ToolWithConstantsMixin*>  m_correctionTools; 
+class CaloClusterCorrDumper : public AthReentrantAlgorithm
+{
+public:
+  using AthReentrantAlgorithm::AthReentrantAlgorithm;
 
+  virtual StatusCode initialize() override;
+  virtual StatusCode execute (const EventContext& ctx) const override;
 
-  /** @brief Name of the text file where to store the constants
-   */
-  std::string m_fileName;
 
+private:
+  SG::ReadCondHandleKeyArray<CaloRec::ToolConstants> m_constants
+  { this, "Constants", {}, "List of constants to dump." };
 };
 
 #endif // CALOREC_CALOCLUSTERCORRDUMPER
diff --git a/Calorimeter/CaloTools/src/CaloNoiseCondAlg.cxx b/Calorimeter/CaloTools/src/CaloNoiseCondAlg.cxx
index 3386d2306b30e634db8322a1824add160af11ff2..e5a5615d28bc05a69ff25cfdcaccf102dda60b16 100644
--- a/Calorimeter/CaloTools/src/CaloNoiseCondAlg.cxx
+++ b/Calorimeter/CaloTools/src/CaloNoiseCondAlg.cxx
@@ -34,12 +34,7 @@ StatusCode CaloNoiseCondAlg::initialize() {
     return StatusCode::FAILURE;
   }
 
-  if ( m_useHVCorr) {
-    if (m_hvCorrKey.initialize().isFailure()) {
-      ATH_MSG_ERROR("useHVCorr set to true but failed to initialize LArHVCorrKey");
-      return StatusCode::FAILURE;
-    }
-  }
+  ATH_CHECK( m_hvCorrKey.initialize(m_useHVCorr) );
 
   if (m_lumi0<0) {
     if (m_lumiFolderKey.initialize().isFailure()) {
diff --git a/Calorimeter/CaloTrackingGeometry/CaloTrackingGeometry/CaloTrackingGeometryBuilderCond.h b/Calorimeter/CaloTrackingGeometry/CaloTrackingGeometry/CaloTrackingGeometryBuilderCond.h
new file mode 100755
index 0000000000000000000000000000000000000000..f13ae7ed2fbe210c0d770efb72bb8f3b405d1209
--- /dev/null
+++ b/Calorimeter/CaloTrackingGeometry/CaloTrackingGeometry/CaloTrackingGeometryBuilderCond.h
@@ -0,0 +1,145 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// CaloTrackingGeometryBuilderCond.hm (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef CALORIMETER_CALOTRACKINGGEOMETRYBUILDERCOND_H
+#define CALORIMETER_CALOTRACKINGGEOMETRYBUILDERCOND_H
+
+#include "CaloIdentifier/CaloCell_ID.h"
+// Gaudi
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+// Trk
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrUtils/GeometrySignature.h"
+#include "TrkDetDescrUtils/LayerIndexSampleMap.h"
+// EnvelopeDefinitionService
+#include "SubDetectorEnvelopes/IEnvelopeDefSvc.h"
+
+// STL
+#include <vector>
+
+namespace Trk {
+  class Material;
+  class Layer;
+  class MagneticFieldProperties;
+  class TrackingGeometry;
+  class ITrackingVolumeBuilder;
+  class ITrackingVolumeCreator;
+  class ITrackingVolumeHelper;
+  class ITrackingVolumeArrayCreator;
+  class IMagneticFieldTool;
+}
+
+class IEnvelopeDefSvc;
+class ICaloSurfaceHelper;
+
+namespace Calo {
+
+  /** @class CaloTrackingGeometryBuilderCond
+     
+    Retrieves the volume builders from Tile and LAr
+    and combines the given volumes to a calorimeter tracking
+    geometry.
+    
+    It also wraps an inner volume if provided though
+    the mehtod interface.
+  
+    @author Andreas.Salzburger@cern.ch
+    */
+   class CaloTrackingGeometryBuilderCond : public AthAlgTool,
+                                       virtual public Trk::IGeometryBuilderCond {
+    
+    
+    public:
+      /** Constructor */
+      CaloTrackingGeometryBuilderCond(const std::string&,const std::string&,const IInterface*);
+      
+      /** Destructor */
+      virtual ~CaloTrackingGeometryBuilderCond();
+        
+      /** AlgTool initailize method.*/
+      StatusCode initialize();
+      
+      /** AlgTool finalize method */
+      StatusCode finalize();
+      
+      /** TrackingGeometry Interface methode */
+      std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const; 
+
+      /** The unique signature */
+      Trk::GeometrySignature geometrySignature() const { return Trk::Calo; }
+    
+    private:
+      ToolHandle<Trk::ITrackingVolumeArrayCreator>  m_trackingVolumeArrayCreator;    //!< Helper Tool to create TrackingVolume Arrays
+
+      ToolHandle<Trk::ITrackingVolumeHelper>        m_trackingVolumeHelper;          //!< Helper Tool to create TrackingVolumes
+      
+      ToolHandle<Trk::ITrackingVolumeCreator>       m_trackingVolumeCreator;         //!< Second helper for volume creation
+
+      ToolHandle<Trk::ITrackingVolumeBuilder>       m_lArVolumeBuilder;              //!< Volume Builder for the Liquid Argon Calorimeter
+
+      ToolHandle<Trk::ITrackingVolumeBuilder>       m_tileVolumeBuilder;             //!< Volume Builder for the Tile Calorimeter
+
+      Trk::Material*                                m_caloMaterial;                  //!< Material properties
+      
+      double                                        m_caloEnvelope;                  //!< Envelope cover for Gap Layers
+      //enclosing endcap/cylindervolume
+      ServiceHandle<IEnvelopeDefSvc>                m_enclosingEnvelopeSvc;
+                                                                                     
+      mutable double                                m_caloDefaultRadius;             //!< the radius if not built from GeoModel
+      mutable double                                m_caloDefaultHalflengthZ;        //!< the halflength in z if not built from GeoModel
+                                                                                     
+      bool                                          m_indexStaticLayers;              //!< forces robust indexing for layers
+      
+      bool                                          m_recordLayerIndexCaloSampleMap;  //!< for deposition methods
+      std::string                                   m_layerIndexCaloSampleMapName;    //!< name to record it
+      
+      bool                                          m_buildMBTS;                      //!< MBTS like detectors
+      //int				                            m_mbstSurfaceShape;		          //!< MBTS like detectors
+      mutable std::vector<double>                   m_mbtsRadii;                      //!< MBTS like detectors
+      std::vector<double>                           m_mbtsRadiusGap;                  //!< MBTS like detectors
+      std::vector<int>                              m_mbtsPhiSegments;                //!< MBTS like detectors
+      std::vector<double>                           m_mbtsPhiGap;			          //!< MBTS like detectors
+      std::vector<double>                           m_mbtsPositionZ;                  //!< MBTS like detectors
+      std::vector<double>		                    m_mbtsStaggeringZ;		          //!< MBTS like detectors
+      
+      std::string                                   m_entryVolume;                    //!< name of the Calo entrance 
+      std::string                                   m_exitVolume;                     //!< name of the Calo container
+
+      mutable RZPairVector                          m_bpCutouts;
+
+      // MBTS layers
+      mutable std::vector<const Trk::Layer*>*       m_mbtsNegLayers;
+      mutable std::vector<const Trk::Layer*>*       m_mbtsPosLayers;  
+      //ToolHandle<ICaloSurfaceHelper>                m_caloSurfaceHelper;
+           
+      /** method to establish a link between the LayerIndex and the CaloCell_ID in an associative container */
+      void registerInLayerIndexCaloSampleMap(Trk::LayerIndexSampleMap& licsMAp,
+                                             std::vector<CaloCell_ID::CaloSample> ccid,
+                                             const Trk::TrackingVolume& vol,
+                                             int side = 1 ) const;
+
+      /** method to build enclosed beam pipe volumes */
+      std::pair<const Trk::TrackingVolume*, const Trk::TrackingVolume*> createBeamPipeVolumes(float ,float, std::string, float&) const;      
+
+      /** cleanup of material */
+      mutable std::map<const Trk::Material*, bool> m_materialGarbage;
+      void throwIntoGarbage(const Trk::Material* mat) const;
+      
+   };
+
+} // end of namespace
+
+
+inline void Calo::CaloTrackingGeometryBuilderCond::throwIntoGarbage(const Trk::Material* mat) const
+{ if (mat) m_materialGarbage[mat] = true; }
+
+#endif // CALORIMETER_CALOTRACKINGGEOMETRYBUILDERCOND_H
+
+
diff --git a/Calorimeter/CaloTrackingGeometry/python/ConfiguredCaloTrackingGeometryBuilderCond.py b/Calorimeter/CaloTrackingGeometry/python/ConfiguredCaloTrackingGeometryBuilderCond.py
new file mode 100644
index 0000000000000000000000000000000000000000..ccc3416c7cb6cab623e4ef6070a47567801a9d7b
--- /dev/null
+++ b/Calorimeter/CaloTrackingGeometry/python/ConfiguredCaloTrackingGeometryBuilderCond.py
@@ -0,0 +1,48 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+######################################################
+# ConfiguredCaloTrackingGeometry module
+#
+# it inherits from CaloTrackingGeometryBuilder and performs 
+# standard configuration
+#
+######################################################
+
+# import the Extrapolator configurable
+from CaloTrackingGeometry.CaloTrackingGeometryConf import Calo__CaloTrackingGeometryBuilderCond
+
+# define the class
+class ConfiguredCaloTrackingGeometryBuilderCond( Calo__CaloTrackingGeometryBuilderCond ):
+    # constructor
+    def __init__(self,name = 'CaloTrackingGeometryBuilderCond'):
+        
+        from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+                
+        from LArTrackingGeometry.ConfiguredLArVolumeBuilder import ConfiguredLArVolumeBuilder
+
+        # import the ToolSvc
+        from AthenaCommon.AppMgr import ToolSvc
+        if 'ToolSvc' not in dir() :
+            ToolSvc = ToolSvc()
+
+        ConfLArVolumeBuilder = ConfiguredLArVolumeBuilder()
+        ToolSvc += ConfLArVolumeBuilder
+
+        from TileTrackingGeometry.ConfiguredTileVolumeBuilder import ConfiguredTileVolumeBuilder
+
+        ConfTileVolumeBuilder = ConfiguredTileVolumeBuilder()
+        ToolSvc += ConfTileVolumeBuilder
+
+        # The volume helper
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__TrackingVolumeHelper
+        CaloTrackingVolumeHelper = Trk__TrackingVolumeHelper(name='TrackingVolumeHelper')
+        ToolSvc += CaloTrackingVolumeHelper         
+        
+        Calo__CaloTrackingGeometryBuilderCond.__init__(self,name,\
+                                                   LArVolumeBuilder = ConfLArVolumeBuilder,\
+                                                   TileVolumeBuilder = ConfTileVolumeBuilder,\
+                                                   TrackingVolumeHelper = CaloTrackingVolumeHelper,\
+                                                   GapLayerEnvelope    = TrkDetFlags.CaloEnvelopeCover(),\
+                                                   EntryVolumeName = TrkDetFlags.CaloEntryVolumeName(),\
+                                                   ExitVolumeName  = TrkDetFlags.CaloContainerName(),
+                                                   MagneticFieldMode = TrkDetFlags.MagneticFieldMode())
diff --git a/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilder.cxx b/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilder.cxx
index b5006daba4fd4ba2d946738016a35ec121055acc..4fc2b86d5bd3033bf9d0e46050af8b6ba1bab8a6 100755
--- a/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilder.cxx
+++ b/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilder.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -319,6 +319,7 @@ const Trk::TrackingGeometry* Calo::CaloTrackingGeometryBuilder::trackingGeometry
   RZPairVector& bpDefs = m_enclosingEnvelopeSvc->getBeamPipeRZValues(0);
   
   ATH_MSG_VERBOSE( "BeamPipe envelope definition retrieved:" );   
+  m_bpCutouts.clear();
   for (unsigned int i=0; i<bpDefs.size(); i++) {
     ATH_MSG_VERBOSE( "Rz pair:"<< i<<":"<< bpDefs[i].first<<","<<bpDefs[i].second );   
     // beam pipe within calo : pick 10. < R < 200;  envEnclosingVolumeHalfZ   =< z  <= msCutouts.back().second;
diff --git a/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilderCond.cxx b/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilderCond.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..b736599facf71367dcaee3d5771fa3cf42d6a2dc
--- /dev/null
+++ b/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilderCond.cxx
@@ -0,0 +1,1698 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// CaloTrackingGeometryBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+// Calo
+#include "CaloTrackingGeometry/CaloTrackingGeometryBuilderCond.h"
+#include "CaloTrackingGeometry/ICaloSurfaceHelper.h"
+// Trk
+#include "TrkDetDescrInterfaces/ITrackingVolumeBuilder.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeCreator.h"
+#include "TrkDetDescrInterfaces/ILayerArrayCreator.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeArrayCreator.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeHelper.h"
+#include "TrkDetDescrInterfaces/IDynamicLayerCreator.h"
+//#include "TrkDetDescrInterfaces/IMaterialEffectsOnTrackProvider.h"
+#include "TrkDetDescrUtils/BinnedArray.h"
+#include "TrkDetDescrUtils/BinnedArray1D1D.h"
+#include "TrkDetDescrUtils/SharedObject.h"
+#include "TrkDetDescrUtils/BinUtility.h"
+#include "TrkDetDescrUtils/GeometryStatics.h"
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkGeometry/TrackingVolume.h"
+#include "TrkGeometry/GlueVolumesDescriptor.h"
+#include "TrkGeometry/Material.h"
+#include "TrkGeometry/BinnedMaterial.h"
+#include "TrkGeometry/MaterialProperties.h"
+#include "TrkGeometry/DiscLayer.h"
+#include "TrkGeometry/HomogeneousLayerMaterial.h"
+#include "TrkGeometry/AlignableTrackingVolume.h"
+#include "TrkVolumes/VolumeBounds.h"
+#include "TrkVolumes/CylinderVolumeBounds.h"
+#include "TrkSurfaces/DiscBounds.h"
+#include "TrkSurfaces/TrapezoidBounds.h"
+#include "TrkSurfaces/DiscSurface.h"
+#include "TrkSurfaces/PlaneSurface.h"
+#include "GaudiKernel/SystemOfUnits.h"
+#include <memory>
+// CLHEP
+//#include "CLHEP/Geometry/Transform3D.h"
+
+//using HepGeom::Transform3D;
+//using HepGeom::Translate3D;
+//using HepGeom::RotateZ3D;
+//using HepGeom::Vector3D;
+//using CLHEP::Hep3Vector;
+//using CLHEP::HepRotation;
+//using CLHEP::mm;
+//using CLHEP::radian;
+
+// constructor
+Calo::CaloTrackingGeometryBuilderCond::CaloTrackingGeometryBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  m_trackingVolumeArrayCreator("Trk::TrackingVolumeArrayCreator/TrackingVolumeArrayCreator"),
+  m_trackingVolumeHelper("Trk::TrackingVolumeHelper/TrackingVolumeHelper"),
+  m_trackingVolumeCreator("Trk::CylinderVolumeCreator/TrackingVolumeCreator"),
+  m_lArVolumeBuilder("LAr::LArVolumeBuilder/LArVolumeBuilder"),
+  m_tileVolumeBuilder("Tile::TileVolumeBuilder/TileVolumeBuilder"),
+  m_caloMaterial(0),
+  m_caloEnvelope(25*Gaudi::Units::mm),
+  m_enclosingEnvelopeSvc("AtlasGeometry_EnvelopeDefSvc", n),
+  m_caloDefaultRadius(4250.),
+  m_caloDefaultHalflengthZ(6500.),
+  m_indexStaticLayers(true),
+  m_recordLayerIndexCaloSampleMap(false),
+  m_layerIndexCaloSampleMapName("LayerIndexCaloSampleMap"),
+  m_buildMBTS(true),
+  //m_mbstSurfaceShape(2),
+  m_entryVolume("Calo::Container::EntryVolume"),
+  m_exitVolume("Calo::Container"),
+  m_mbtsNegLayers(0),
+  m_mbtsPosLayers(0)
+  //m_caloSurfaceHelper("CaloSurfaceHelper/CaloSurfaceHelper")
+{
+  declareInterface<Trk::IGeometryBuilderCond>(this);
+  // declare the properties via Python
+  declareProperty("LArVolumeBuilder",                 m_lArVolumeBuilder);
+  declareProperty("TileVolumeBuilder",                m_tileVolumeBuilder);
+  declareProperty("TrackingVolumeArrayCreator",       m_trackingVolumeArrayCreator);
+  declareProperty("TrackingVolumeHelper",             m_trackingVolumeHelper);
+  declareProperty("TrackingVolumeCreator",            m_trackingVolumeCreator);
+  declareProperty("GapLayerEnvelope",                 m_caloEnvelope);
+  // envelope definition service
+  declareProperty("EnvelopeDefinitionSvc",            m_enclosingEnvelopeSvc );
+  // empty calorimeter to be built
+  declareProperty("CalorimeterRadius",                m_caloDefaultRadius);
+  declareProperty("CalorimeterHalflengthZ",           m_caloDefaultHalflengthZ);
+  // unique layer handling
+  declareProperty("IndexStaticLayers",                m_indexStaticLayers);
+  // for energy deposition
+  declareProperty("RecordLayerIndexCaloSampleMap",    m_recordLayerIndexCaloSampleMap);
+  declareProperty("LayerIndexCaloSampleMapName",      m_layerIndexCaloSampleMapName);
+  // MBTS like detectors 
+  declareProperty("BuildMBTS",                        m_buildMBTS);
+  //declareProperty("MBTS_SurfaceShape",                m_mbstSurfaceShape);
+  //declareProperty("MBTS_Radii",                       m_mbtsRadii);
+  //declareProperty("MBTS_RadiusGap",                   m_mbtsRadiusGap);
+  //declareProperty("MBTS_PhiSegments",                 m_mbtsPhiSegments);
+  //declareProperty("MBTS_PhiGap",                      m_mbtsPhiGap);
+  //declareProperty("MBTS_PositionZ",                   m_mbtsPositionZ);
+  //declareProperty("MBTS_StaggeringZ",                 m_mbtsStaggeringZ);
+  // calo entry volume & exit volume
+  declareProperty("EntryVolumeName",                  m_entryVolume);
+  declareProperty("ExitVolumeName",                   m_exitVolume);
+  
+}
+
+// destructor
+Calo::CaloTrackingGeometryBuilderCond::~CaloTrackingGeometryBuilderCond()
+{
+  delete m_caloMaterial;
+}
+
+// Athena standard methods
+// initialize
+StatusCode Calo::CaloTrackingGeometryBuilderCond::initialize()
+{
+  
+    // retrieve envelope definition service --------------------------------------------------
+    if ( m_enclosingEnvelopeSvc.retrieve().isFailure() ){
+      ATH_MSG_FATAL( "Could not retrieve EnvelopeDefinition service. Abort.");
+      return StatusCode::FAILURE;
+    }
+    
+    // Retrieve the tracking volume array creator   -------------------------------------------------    
+    if (m_trackingVolumeArrayCreator.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeArrayCreator );
+      return StatusCode::FAILURE;
+    } else
+      ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeArrayCreator );
+
+    // Retrieve the tracking volume helper   -------------------------------------------------    
+    if (m_trackingVolumeHelper.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeHelper );
+      return StatusCode::FAILURE;
+    } else
+      ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeHelper );
+
+    // Retrieve the second volume creator
+    if (m_buildMBTS && m_trackingVolumeCreator.retrieve().isFailure()){
+        ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeCreator );
+        return StatusCode::FAILURE;
+    } else
+        ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeCreator );
+
+    // Retrieve the volume builders
+
+    // Retrieve the tracking volume array creator   -------------------------------------------------    
+    if (m_lArVolumeBuilder.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_lArVolumeBuilder );
+      return StatusCode::FAILURE;
+    } else
+      ATH_MSG_INFO( "Retrieved tool " << m_lArVolumeBuilder );
+
+    // Retrieve the tracking volume helper   -------------------------------------------------    
+    if (m_tileVolumeBuilder.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_tileVolumeBuilder );
+      return StatusCode::FAILURE;
+    } else
+      ATH_MSG_INFO( "Retrieved tool " << m_tileVolumeBuilder );
+
+    // Retrieve the calo surface helper (to load MBTS) -------------------------------------------------    
+#if 0
+    if (m_caloSurfaceHelper.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_caloSurfaceHelper );
+      return StatusCode::FAILURE;
+    } else
+      ATH_MSG_INFO( "Retrieved tool " << m_caloSurfaceHelper );
+#endif
+
+    // Dummy MaterialProerties
+    m_caloMaterial = new Trk::Material;
+
+    ATH_MSG_INFO( "initialize() succesful" );
+
+    return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode Calo::CaloTrackingGeometryBuilderCond::finalize()
+{
+  // empty the material garbage 
+  std::map<const Trk::Material*, bool>::iterator garbageIter  = m_materialGarbage.begin();
+  std::map<const Trk::Material*, bool>::iterator garbageEnd   = m_materialGarbage.end();
+  
+  for ( ; garbageIter != garbageEnd; ++garbageIter ){
+    delete (garbageIter->first);
+  }
+
+  ATH_MSG_INFO( "finalize() successful" );
+  return StatusCode::SUCCESS;
+}
+
+std::pair<EventIDRange, const Trk::TrackingGeometry*> Calo::CaloTrackingGeometryBuilderCond::trackingGeometry(const EventContext&, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const
+{
+
+  ATH_MSG_VERBOSE( "Starting to build CaloTrackingGeometry ..." );   
+  
+  // the return TG
+  const Trk::TrackingGeometry* caloTrackingGeometry = 0; 
+  const Trk::TrackingVolume*            calorimeter = 0;                     
+
+  // the key dimensions
+  RZPairVector keyDim; 
+
+  // the enclosed input volume (ID)
+  double enclosedInnerSectorHalflength = 0.;
+  double enclosedInnerSectorRadius = 0.;
+   
+   // dummy objects
+   const Trk::LayerArray* dummyLayers = 0;
+   const Trk::TrackingVolumeArray* dummyVolumes = 0;
+  
+  //TODO/FIXME: just passing on range, no Calo IOV range used
+  EventIDRange range;
+  const Trk::TrackingVolume* innerVol = nullptr;
+  if(tVolPair.second != nullptr){
+    range = tVolPair.first;
+    innerVol = tVolPair.second;
+  }
+  if (innerVol) {  
+    ATH_MSG_VERBOSE( "Got Inner Detector Volume: " << innerVol->volumeName() ); 
+    innerVol->screenDump(msg(MSG::VERBOSE)); 
+
+    // retrieve dimensions
+    const Trk::CylinderVolumeBounds* innerDetectorBounds 
+      = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(innerVol->volumeBounds()));
+    if (!innerDetectorBounds) std::abort();
+    
+    enclosedInnerSectorHalflength = innerDetectorBounds->halflengthZ();
+    enclosedInnerSectorRadius = innerDetectorBounds->outerRadius();
+
+    keyDim.push_back(RZPair(enclosedInnerSectorRadius, enclosedInnerSectorHalflength));
+  }   
+  // get the dimensions from the envelope service
+  RZPairVector& envelopeDefsIn = m_enclosingEnvelopeSvc->getCaloRZValues(0);
+  //RZPairVector& envelopeDefs = m_enclosingEnvelopeSvc->getCaloRZValues(0);
+
+  // find the max,max pair
+  unsigned int ii=0;
+  for (unsigned int i=0; i<envelopeDefsIn.size(); i++) { 
+    if (envelopeDefsIn[i].second>envelopeDefsIn[ii].second) ii=i;
+    else if (envelopeDefsIn[i].second==envelopeDefsIn[ii].second && 
+	     envelopeDefsIn[i].first>envelopeDefsIn[ii].first) ii=i;
+  }  
+
+  // find the sense of rotation
+  int irot=1;
+  unsigned int inext=ii+1;
+  if (inext==envelopeDefsIn.size()) inext=0;
+  if (envelopeDefsIn[inext].second!=envelopeDefsIn[ii].second) {irot=-1; inext = ii>0 ? ii-1:envelopeDefsIn.size()-1 ;}
+  
+  // fill starting with upper low edge, end with upper high edge
+  RZPairVector envelopeDefs;
+  if (irot>0) {
+    for (unsigned int i=inext; i<envelopeDefsIn.size(); i++) envelopeDefs.push_back(envelopeDefsIn[i]); 
+    if (inext>0) for (unsigned int i=0; i<=inext-1; i++) envelopeDefs.push_back(envelopeDefsIn[i]); 
+  } else {
+    int i=inext;  while (i>=0) {envelopeDefs.push_back(envelopeDefsIn[i]); i=i-1;};
+    inext = envelopeDefsIn.size()-1; while (inext>=ii) {envelopeDefs.push_back(envelopeDefsIn[inext]); inext=inext-1;};
+  } 
+
+
+  double envEnclosingVolumeHalfZ = m_caloDefaultHalflengthZ; 
+
+  ATH_MSG_VERBOSE( "Calo envelope definition retrieved:" );  
+  RZPairVector msCutouts; 
+  for (unsigned int i=0; i<envelopeDefs.size(); i++) {
+    ATH_MSG_VERBOSE( "Rz pair:"<< i<<":"<< envelopeDefs[i].first<<","<<envelopeDefs[i].second );   
+    if (fabs(envelopeDefs[i].second) < envEnclosingVolumeHalfZ) envEnclosingVolumeHalfZ = fabs(envelopeDefs[i].second);
+    // ID dimensions : pick 1100 < R < 1200
+    if ( envelopeDefs[i].first > 1100. && envelopeDefs[i].first < 1200. && envelopeDefs[i].second > 0. ) {
+      // check that radial size of ID envelope fits
+      if ( enclosedInnerSectorRadius != envelopeDefs[i].first ) ATH_MSG_INFO( "Enclosed ID volume radius does not match ID envelope, adjusting Calo." );
+      envEnclosingVolumeHalfZ = envelopeDefs[i].second; 
+      if (!innerVol) {
+	enclosedInnerSectorRadius = envelopeDefs[i].first;
+	enclosedInnerSectorHalflength = envelopeDefs[i].second;
+      }
+    }
+    // collect outer cutouts, process those with |z| < 6785.mm ( this cut should be synchronized with MS default size,
+    //  MS builder would crash for a longer input volume ) 
+    if ( envelopeDefs[i].second > 0. && envelopeDefs[i].second < 6785. &&
+	 ( envelopeDefs[i].first > 1200. || envelopeDefs[i].second > envEnclosingVolumeHalfZ ) ) {
+      if ( !msCutouts.size() ) msCutouts.push_back( envelopeDefs[i] );
+      else {
+	RZPairVector::iterator envIter = msCutouts.begin();
+        while (envIter!= msCutouts.end() && (*envIter).second < envelopeDefs[i].second ) envIter++;
+        while (envIter!= msCutouts.end() && (*envIter).second == envelopeDefs[i].second && (*envIter).first  > envelopeDefs[i].first ) envIter++;
+	msCutouts.insert(envIter, envelopeDefs[i]);
+      }
+    }
+    // end outer (MS) cutouts
+  }
+  for (unsigned int i=0; i<msCutouts.size(); i++) ATH_MSG_VERBOSE( "MS cutouts to be processed by Calo:"<< i<<":"<< msCutouts[i].first<<","<<msCutouts[i].second );
+  // first member of msCutouts redefines the default central cylinder dimension     
+  if (msCutouts.size()>0) {
+    m_caloDefaultRadius = msCutouts[0].first;
+    m_caloDefaultHalflengthZ = msCutouts[0].second;
+    ATH_MSG_VERBOSE(" Calo central cylinder dimensions adjusted using EnvelopeSvc:"<<m_caloDefaultRadius<<","<< m_caloDefaultHalflengthZ );
+  }
+
+  // create dummy ID if not built already
+
+  if (!innerVol) {
+   Trk::CylinderVolumeBounds* idBounds = new Trk::CylinderVolumeBounds(enclosedInnerSectorRadius, enclosedInnerSectorHalflength);
+
+   Amg::Transform3D* idTr = new Amg::Transform3D(Trk::s_idTransform);
+
+   innerVol = new Trk::TrackingVolume(idTr, idBounds, *m_caloMaterial,
+				      dummyLayers, dummyVolumes,
+				      "Calo::GapVolumes::DummyID");
+
+   keyDim.push_back(RZPair(enclosedInnerSectorRadius, enclosedInnerSectorHalflength));
+  }
+ 
+  // BEAM PIPE
+  //std::cout <<"envelope svc : number of BeamPipe Volumes:"<< m_enclosingEnvelopeSvc->getBeamPipeNumVols()<< std::endl;  
+  RZPairVector& bpDefs = m_enclosingEnvelopeSvc->getBeamPipeRZValues(0);
+  
+  ATH_MSG_VERBOSE( "BeamPipe envelope definition retrieved:" );   
+  m_bpCutouts.clear();
+  for (unsigned int i=0; i<bpDefs.size(); i++) {
+    ATH_MSG_VERBOSE( "Rz pair:"<< i<<":"<< bpDefs[i].first<<","<<bpDefs[i].second );   
+    // beam pipe within calo : pick 10. < R < 200;  envEnclosingVolumeHalfZ   =< z  <= msCutouts.back().second;
+    if ( bpDefs[i].first > 10. && bpDefs[i].first < 200. && bpDefs[i].second>=envEnclosingVolumeHalfZ  && bpDefs[i].second <= msCutouts.back().second ) {
+      m_bpCutouts.push_back( bpDefs[i] );
+    }
+    if (i>0 && i<4) keyDim.push_back(bpDefs[i]);
+  }
+ 
+  // no beam pipe within ID
+  //if (m_bpCutouts[0].second == envEnclosingVolumeHalfZ && m_bpCutouts[0].first > 0 )  m_bpCutouts[0].first=0.;
+  // last not needed
+  if (m_bpCutouts.size()>1 && m_bpCutouts.back().second==m_bpCutouts[m_bpCutouts.size()-2].second) m_bpCutouts.erase(m_bpCutouts.end()-1);
+  // end beam pipe envelope within Calo
+  for (unsigned int i=0; i<m_bpCutouts.size(); i++) ATH_MSG_VERBOSE( "Beam pipe dimensions to be used by Calo:"<< i<<":"<< m_bpCutouts[i].first<<","<<m_bpCutouts[i].second );
+
+  keyDim.push_back(RZPair(m_caloDefaultRadius,m_caloDefaultHalflengthZ)); 
+
+   // get the dimensions from the envelope service
+   //std::cout <<"envelope svc : number of MS Volumes:"<< m_enclosingEnvelopeSvc->getMuonNumVols()<< std::endl;  
+   //RZPairVector& msDefs = m_enclosingEnvelopeSvc->getMuonRZValues(0);
+
+   //ATH_MSG_VERBOSE( "MS envelope definition retrieved:" );   
+   //for (unsigned int i=0; i<msDefs.size(); i++) ATH_MSG_VERBOSE( "Rz pair:"<< i<<":"<< msDefs[i].first<<","<<msDefs[i].second );   
+
+
+   //////////// ---------------- BUILD FROM GEOMODEL ---------------------------- /////////////////////////////////
+
+    
+  // PART 1 : Liquid Argon Volumes ===========================================================================================
+  // get the Tracking Volumes from the LAr Builder 
+  const std::vector<const Trk::TrackingVolume*>* lArVolumes = m_lArVolumeBuilder->trackingVolumes();
+
+  ATH_MSG_INFO( lArVolumes->size() << " volumes retrieved from " << m_lArVolumeBuilder.name() );   
+  if (msgLvl(MSG::VERBOSE)){
+    ATH_MSG_VERBOSE( "--------------- detailed output ---------------------------------------------------------- " );
+    std::vector<const Trk::TrackingVolume*>::const_iterator lArVolIter    = lArVolumes->begin();
+    std::vector<const Trk::TrackingVolume*>::const_iterator lArVolIterEnd = lArVolumes->end();
+    for ( ; lArVolIter != lArVolIterEnd; ++lArVolIter)
+     if (*lArVolIter) (*lArVolIter)->screenDump(msg(MSG::VERBOSE)) ;
+  }           
+  
+  // LAr Barrel part  
+  const Trk::TrackingVolume* solenoid                   = (*lArVolumes)[0];
+  const Trk::TrackingVolume* solenoidlArPresamplerGap   = (*lArVolumes)[1];
+  const Trk::TrackingVolume* lArBarrelPresampler        = (*lArVolumes)[2];
+  const Trk::TrackingVolume* lArBarrel                  = (*lArVolumes)[3];
+
+  // LAr Positive Endcap part
+  const Trk::TrackingVolume* lArPositiveMBTS            = (*lArVolumes)[4];
+  const Trk::TrackingVolume* lArPositiveEndcap          = (*lArVolumes)[5];
+  const Trk::TrackingVolume* lArPositiveHec             = (*lArVolumes)[6];
+  const Trk::TrackingVolume* lArPositiveFcal            = (*lArVolumes)[7];
+  const Trk::TrackingVolume* lArPositiveHecFcalCover    = (*lArVolumes)[8];
+  // LAr Negative Endcap part
+  const Trk::TrackingVolume* lArNegativeMBTS            = (*lArVolumes)[9];
+  const Trk::TrackingVolume* lArNegativeEndcap          = (*lArVolumes)[10];
+  const Trk::TrackingVolume* lArNegativeHec             = (*lArVolumes)[11];
+  const Trk::TrackingVolume* lArNegativeFcal            = (*lArVolumes)[12];
+  const Trk::TrackingVolume* lArNegativeHecFcalCover    = (*lArVolumes)[13];
+  const Trk::TrackingVolume* lArPosECPresampler         = (*lArVolumes)[14];
+  const Trk::TrackingVolume* lArNegECPresampler         = (*lArVolumes)[15];
+
+
+  // PART 2 : Tile Volumes ===========================================================================================
+  // get the Tracking Volumes from the Tile Builder 
+  const std::vector<const Trk::TrackingVolume*>* tileVolumes = m_tileVolumeBuilder->trackingVolumes();
+
+  ATH_MSG_INFO( tileVolumes->size() << " volumes retrieved from " << m_tileVolumeBuilder.name() );   
+  if (msgLvl(MSG::INFO)){
+    ATH_MSG_INFO( "--------------- detailed output ---------------------------------------------------------- " );
+    std::vector<const Trk::TrackingVolume*>::const_iterator tileVolIter = tileVolumes->begin();
+    std::vector<const Trk::TrackingVolume*>::const_iterator tileVolIterEnd = tileVolumes->end();
+    for ( ; tileVolIter != tileVolIterEnd;  (*tileVolIter)->screenDump(msg(MSG::VERBOSE)), ++tileVolIter)
+      ;
+  }
+    
+  // Tile Barrel part
+  const Trk::TrackingVolume* tileCombined                  = (*tileVolumes)[0];
+  // Tile Positive Extended Part
+  const Trk::TrackingVolume* tilePositiveExtendedBarrel  = (*tileVolumes)[1];
+
+  const Trk::CylinderVolumeBounds* ebBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(tilePositiveExtendedBarrel->volumeBounds()));
+
+  double rTileMin = ebBounds ? ebBounds->innerRadius() : 2288.;
+  double zTileMin = ebBounds ? tilePositiveExtendedBarrel->center().z()-ebBounds->halflengthZ() : 3559.5;
+
+  keyDim.push_back(RZPair(rTileMin,zTileMin));
+  for (unsigned int i=0; i<keyDim.size(); i++) {
+    ATH_MSG_VERBOSE( "key dimensions:"<< i<<":"<< keyDim[i].first<<","<<keyDim[i].second );   
+  }
+  
+  // The Bounds needed for the Gap Volume creation
+  const Trk::CylinderVolumeBounds* solenoidBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(solenoid->volumeBounds()));
+  if (!solenoidBounds) std::abort();
+  const Trk::CylinderVolumeBounds* lArBarrelBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArBarrel->volumeBounds()));
+  if (!lArBarrelBounds) std::abort();
+  const Trk::CylinderVolumeBounds* lArPositiveEndcapBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArPositiveEndcap->volumeBounds()));
+  if (!lArPositiveEndcapBounds) std::abort();
+  const Trk::CylinderVolumeBounds* lArNegativeEndcapBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArNegativeEndcap->volumeBounds()));
+  if (!lArNegativeEndcapBounds) std::abort();
+  const Trk::CylinderVolumeBounds* lArPositiveHecBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArPositiveHec->volumeBounds()));
+  if (!lArPositiveHecBounds) std::abort();
+  const Trk::CylinderVolumeBounds* lArPositiveFcalBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArPositiveFcal->volumeBounds()));
+  if (!lArPositiveFcalBounds) std::abort();
+  const Trk::CylinderVolumeBounds* lArNegativeFcalBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArNegativeFcal->volumeBounds()));
+  if (!lArNegativeFcalBounds) std::abort();
+ 
+  const Trk::CylinderVolumeBounds* tileCombinedBounds 
+       = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(tileCombined->volumeBounds()));
+  if (!tileCombinedBounds) std::abort();
+        
+   // Create the gap volumes ======================================================================
+   const Trk::TrackingVolume* lArTileCentralSectorGap    = 0;
+
+   //const Trk::TrackingVolume* tilePositiveSectorInnerGap = 0;
+   const Trk::TrackingVolume* lArPositiveSectorInnerGap  = 0;
+   //const Trk::TrackingVolume* lArTilePositiveSectorGap   = 0;
+   const Trk::TrackingVolume* lArPositiveSectorOuterGap  = 0;
+   const Trk::TrackingVolume* lArPositiveSectorOuterGap0  = 0;
+   const Trk::TrackingVolume* lArCentralPositiveGap      = 0;
+
+   //const Trk::TrackingVolume* tileNegativeSectorInnerGap = 0;
+   const Trk::TrackingVolume* lArNegativeSectorInnerGap  = 0;
+   //const Trk::TrackingVolume* lArTileNegativeSectorGap   = 0;
+   const Trk::TrackingVolume* lArNegativeSectorOuterGap  = 0;
+   const Trk::TrackingVolume* lArNegativeSectorOuterGap0  = 0;
+   const Trk::TrackingVolume* lArCentralNegativeGap      = 0;
+
+   const Trk::TrackingVolume* trtSolenoidGap         = 0;  
+
+   double caloPositiveOuterBoundary    =  tileCombinedBounds->halflengthZ();
+
+   double lArPositiveOuterBoundary     = lArPositiveFcal->center().z();
+          lArPositiveOuterBoundary    += lArPositiveFcalBounds->halflengthZ();
+
+   double lArNegativeOuterBoundary     = lArNegativeFcal->center().z();
+          lArNegativeOuterBoundary    -= lArNegativeFcalBounds->halflengthZ();
+
+   Trk::Material* mAr = new Trk::Material(140.036, 856.32, 39.948, 18., 0.0014);
+   Trk::Material* mAl = new Trk::Material(88.93, 388.62, 26.98, 13., 0.0027);
+   //Trk::Material* mFe = new Trk::Material(17.58, 169.68, 55.85, 26., 0.0079);
+   Trk::Material* mScint = new Trk::Material(424.35, 707.43, 11.16, 5.61, 0.001);  // from G4 definition
+   const Trk::Material* crackMaterial = new Trk::Material(424.35, 707.43, 11.16, 5.61, 0.001);  // Scintillator/Glue (G4 def.)
+
+   throwIntoGarbage(mAr);
+   throwIntoGarbage(mAl);
+   throwIntoGarbage(mScint);
+   throwIntoGarbage(crackMaterial);
+
+   // No. 1
+   // building dense volume here
+   Trk::Material tilePositiveSectorInnerGapMaterial = Trk::Material(58., 565., 30.7, 14.6, 0.0025);
+
+   // calo sensitive volume outer radius/z extent defined (for example) here
+   float caloVolsOuterRadius = tileCombinedBounds->outerRadius(); 
+   float caloVolsExtendZ = caloPositiveOuterBoundary; 
+
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   //  LAr InnerGap sector + beam pipe
+  
+   Trk::Material lArSectorInnerGapMaterial = Trk::Material(361., 1370., 14.5, 7., 0.0009);  // ???
+
+   // create beam pipe volumes for InnerGap/MBTS and return their outer radius 
+   float rInnerGapBP=0.;
+   std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> innerGapBP = createBeamPipeVolumes(keyDim[0].second, 
+							//lArPositiveEndcap->center().z()-lArPositiveEndcapBounds->halflengthZ(),
+												       keyDim.back().second,
+												       "InnerGap", rInnerGapBP);
+
+   double z = 0.5*(keyDim.back().second+keyDim[0].second);
+
+   if (lArPositiveMBTS && lArNegativeMBTS) {
+     // Disc
+     const Trk::CylinderVolumeBounds* mbtsBounds 
+       = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArPositiveMBTS->volumeBounds()));
+#if 0
+     if (mbtsBounds && m_caloSurfaceHelper) {     // pass ownership
+       Amg::Transform3D* mbtsNeg = new Amg::Transform3D(Amg::Translation3D(lArNegativeMBTS->center()));
+       Amg::Transform3D* mbtsPos = new Amg::Transform3D(Amg::Translation3D(lArPositiveMBTS->center()));
+       m_caloSurfaceHelper->LoadMBTSSurfaces(std::pair<const Trk::Surface*,const Trk::Surface*>
+					     (new Trk::DiscSurface(mbtsNeg,mbtsBounds->innerRadius(),mbtsBounds->outerRadius()),
+					      new Trk::DiscSurface(mbtsPos,mbtsBounds->innerRadius(),mbtsBounds->outerRadius())));
+     }
+#endif
+     if (mbtsBounds && m_buildMBTS) {
+       float rmin = mbtsBounds->innerRadius(); 
+       float rmax = mbtsBounds->outerRadius(); 
+       //float d = mbtsBounds->halflengthZ();
+       Trk::DiscBounds* dibo = new Trk::DiscBounds(rmin,rmax);
+       // MBTS positions
+       Amg::Transform3D* mbtsNegZpos = new Amg::Transform3D(Amg::Translation3D(lArNegativeMBTS->center()));
+       Amg::Transform3D* mbtsPosZpos = new Amg::Transform3D(Amg::Translation3D(lArPositiveMBTS->center()));
+       // create the two Layers ( TODO: add trd surface subarray )
+       Trk::DiscLayer* mbtsNegLayer = new Trk::DiscLayer(mbtsNegZpos,dibo,
+                                                         //mbtsNegLayerSurfArray,
+                                                         Trk::HomogeneousLayerMaterial(Trk::MaterialProperties(*m_caloMaterial,1.),1.),
+                                                         1.);
+       Trk::DiscLayer* mbtsPosLayer = new Trk::DiscLayer(mbtsPosZpos,dibo->clone(),
+                                                         //mbtsPosLayerSurfArray,
+                                                         Trk::HomogeneousLayerMaterial(Trk::MaterialProperties(*m_caloMaterial,1.),1.),
+                                                         1.*Gaudi::Units::mm);
+
+       m_mbtsNegLayers=new std::vector<const Trk::Layer*>;
+       m_mbtsPosLayers=new std::vector<const Trk::Layer*>;
+       m_mbtsNegLayers->push_back(mbtsNegLayer);
+       m_mbtsPosLayers->push_back(mbtsPosLayer);       
+     }
+   }
+      
+   // building inner gap
+   Trk::CylinderVolumeBounds* lArG1Bounds =
+     new Trk::CylinderVolumeBounds( rInnerGapBP,
+				    //lArPositiveEndcapBounds->outerRadius(),
+				    keyDim[0].first,
+				    0.5*(keyDim.back().second-keyDim[0].second));
+   
+   Amg::Transform3D* lArG1P =
+     new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,z)));
+   lArPositiveSectorInnerGap  = new Trk::TrackingVolume(lArG1P,
+							lArG1Bounds,
+							lArSectorInnerGapMaterial, 
+							m_mbtsPosLayers, 
+							"Calo::GapVolumes::LAr::PositiveSectorInnerGap");
+
+   Amg::Transform3D* lArG1N =
+     new  Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-z)));
+   lArNegativeSectorInnerGap  = new Trk::TrackingVolume(lArG1N,
+							lArG1Bounds->clone(),
+							lArSectorInnerGapMaterial, 
+							m_mbtsNegLayers,
+							"Calo::GapVolumes::LAr::NegativeSectorInnerGap");
+
+   // glue InnerGap with beam pipe volumes
+   const Trk::TrackingVolume* positiveInnerGap = 0;
+   if (innerGapBP.first) {
+     std::vector<const Trk::TrackingVolume*> volsInnerGap;
+     volsInnerGap.push_back(innerGapBP.first);
+     volsInnerGap.push_back(lArPositiveSectorInnerGap);
+     positiveInnerGap = m_trackingVolumeCreator->createContainerTrackingVolume(volsInnerGap,
+									       *m_caloMaterial,
+									       "Calo::Container::PositiveInnerGap"); 
+   } else positiveInnerGap = lArPositiveSectorInnerGap;
+
+   const Trk::TrackingVolume* negativeInnerGap = 0;
+   if (innerGapBP.second) {
+     std::vector<const Trk::TrackingVolume*> volsInnerGap;
+     volsInnerGap.push_back(innerGapBP.second);
+     volsInnerGap.push_back(lArNegativeSectorInnerGap);
+     negativeInnerGap = m_trackingVolumeCreator->createContainerTrackingVolume(volsInnerGap,
+									       *m_caloMaterial,
+									       "Calo::Container::NegativeInnerGap"); 
+   } else negativeInnerGap = lArNegativeSectorInnerGap;
+
+   // glue MBTS volumes with ID
+   std::vector<const Trk::TrackingVolume*> inBufferVolumes;
+   inBufferVolumes.push_back(negativeInnerGap);     
+   inBufferVolumes.push_back(innerVol);     
+   inBufferVolumes.push_back(positiveInnerGap);     
+   
+   const Trk::TrackingVolume* inDetEnclosed = m_trackingVolumeCreator->createContainerTrackingVolume(inBufferVolumes,
+												     *m_caloMaterial,
+                                                                           "Calo::Container::EnclosedInnerDetector");
+
+
+   ATH_MSG_DEBUG( " Inner detector enclosed (MBTS volumes)" );   
+
+   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // LAr endcap sector including the beam pipe 
+
+   // create beam pipe volumes for Endcap and return their outer radius 
+   float rEndcapBP=0.;
+   std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> endcapBP = createBeamPipeVolumes( 
+							  keyDim.back().second,
+							  lArPositiveEndcap->center().z()+lArPositiveEndcapBounds->halflengthZ(),
+							  "Endcap", rEndcapBP);
+
+   // build lAr vessel around EC Presampler
+   const Trk::CylinderVolumeBounds* ecpBounds 
+      = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArPosECPresampler->volumeBounds()));
+   if (!ecpBounds) std::abort();
+    
+   float ecpHz = ecpBounds->halflengthZ();
+   float ecpRmin = ecpBounds->innerRadius();
+   float ecpRmax = ecpBounds->outerRadius();
+
+   Amg::Transform3D* ecpPos=new Amg::Transform3D(lArPosECPresampler->transform());
+   Amg::Transform3D* ecpNeg=new Amg::Transform3D(lArNegECPresampler->transform());
+
+   Trk::CylinderVolumeBounds* ecpUpBounds = new Trk::CylinderVolumeBounds(ecpRmax, keyDim.back().first, ecpHz);
+   Trk::CylinderVolumeBounds* ecpDownBounds = new Trk::CylinderVolumeBounds(rEndcapBP, ecpRmin, ecpHz);
+
+   const Trk::TrackingVolume* ecPresamplerCoverPos = new Trk::TrackingVolume(ecpPos,ecpUpBounds, *mAl,
+									     dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::PositiveECPresamplerCover");
+   const Trk::TrackingVolume* ecPresamplerCoverNeg = new Trk::TrackingVolume(ecpNeg,ecpUpBounds->clone(), *mAl,
+									     dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::NegativeECPresamplerCover");
+   const Trk::TrackingVolume* ecPresamplerInnerPos = new Trk::TrackingVolume(new Amg::Transform3D(*ecpPos),ecpDownBounds, *mAl,
+									     dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::PositiveECPresamplerInner");
+   const Trk::TrackingVolume* ecPresamplerInnerNeg = new Trk::TrackingVolume(new Amg::Transform3D(*ecpNeg),ecpDownBounds->clone(),
+									     *mAl, dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::NegativeECPresamplerInner");
+
+   // glue EC presampler radially
+   std::vector<const Trk::TrackingVolume*> volsECP;
+   volsECP.push_back(ecPresamplerInnerPos);
+   volsECP.push_back(lArPosECPresampler);
+   volsECP.push_back(ecPresamplerCoverPos);
+   const Trk::TrackingVolume* positiveECP = m_trackingVolumeCreator->createContainerTrackingVolume(volsECP,
+									       *m_caloMaterial,
+									       "Calo::Container::PositiveECPresamplerR"); 
+   std::vector<const Trk::TrackingVolume*> volsECN;
+   volsECN.push_back(ecPresamplerInnerNeg);
+   volsECN.push_back(lArNegECPresampler);
+   volsECN.push_back(ecPresamplerCoverNeg);
+   const Trk::TrackingVolume* negativeECP = m_trackingVolumeCreator->createContainerTrackingVolume(volsECN,
+									       *m_caloMaterial,
+									       "Calo::Container::NegativeECPresamplerR"); 
+
+   // add surrounding buffers
+   z = lArPosECPresampler->center().z()-ecpHz;
+   float z1 = lArPosECPresampler->center().z()+ecpHz;
+   float z2 = lArPositiveEndcap->center().z()-lArPositiveEndcapBounds->halflengthZ();
+   Amg::Transform3D* ecIPos = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0., 0.5*(z+keyDim.back().second))));
+   Amg::Transform3D* ecINeg = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-0.5*(z+keyDim.back().second))));
+   Trk::CylinderVolumeBounds* ecpIBounds = new Trk::CylinderVolumeBounds(rEndcapBP, keyDim.back().first,0.5*(z-keyDim.back().second));
+   Amg::Transform3D* ecOPos = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0., 0.5*(z1+z2))));
+   Amg::Transform3D* ecONeg = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-0.5*(z1+z2))));
+   Trk::CylinderVolumeBounds* ecpOBounds = new Trk::CylinderVolumeBounds(rEndcapBP, keyDim.back().first,0.5*(z2-z1));
+
+   const Trk::TrackingVolume* ecPresamplerInPos = new Trk::TrackingVolume(ecIPos,ecpIBounds, *mAr,
+									     dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::PositiveECPresamplerIn");
+   const Trk::TrackingVolume* ecPresamplerInNeg = new Trk::TrackingVolume(ecINeg,ecpIBounds->clone(), *mAr,
+									     dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::NegativeECPresamplerIn");
+   const Trk::TrackingVolume* ecPresamplerOutPos = new Trk::TrackingVolume(ecOPos,ecpOBounds, *mAr,
+									     dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::PositiveECPresamplerOut");
+   const Trk::TrackingVolume* ecPresamplerOutNeg = new Trk::TrackingVolume(ecONeg,ecpOBounds->clone(),
+									     *mAr, dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::NegativeECPresamplerOut");
+
+   // glue EC presampler in z
+   std::vector<const Trk::TrackingVolume*> volECP;
+   volECP.push_back(ecPresamplerInPos);
+   volECP.push_back(positiveECP);
+   volECP.push_back(ecPresamplerOutPos);
+   const Trk::TrackingVolume* positiveEP = m_trackingVolumeCreator->createContainerTrackingVolume(volECP,
+									       *m_caloMaterial,
+									       "Calo::Container::PositiveECPresampler"); 
+   std::vector<const Trk::TrackingVolume*> volECN;
+   volECN.push_back(ecPresamplerOutNeg);
+   volECN.push_back(negativeECP);
+   volECN.push_back(ecPresamplerInNeg);
+   const Trk::TrackingVolume* negativeEP = m_trackingVolumeCreator->createContainerTrackingVolume(volECN,
+									       *m_caloMaterial,
+									       "Calo::Container::NegativeECPresampler");
+
+   // build lAr vessel around EMEC
+   ecpHz = lArPositiveEndcapBounds->halflengthZ();
+   ecpRmin = lArPositiveEndcapBounds->innerRadius();
+   ecpRmax = lArPositiveEndcapBounds->outerRadius();
+
+   Amg::Transform3D* ecPos=new Amg::Transform3D(lArPositiveEndcap->transform());
+   Amg::Transform3D* ecNeg=new Amg::Transform3D(lArNegativeEndcap->transform());
+
+   Trk::CylinderVolumeBounds* ecUpBounds = new Trk::CylinderVolumeBounds(ecpRmax, keyDim.back().first, ecpHz);
+   Trk::CylinderVolumeBounds* ecDownBounds = new Trk::CylinderVolumeBounds(rEndcapBP, ecpRmin, ecpHz);
+
+   const Trk::TrackingVolume* ecCoverPos = new Trk::TrackingVolume(ecPos,ecUpBounds, *mAr,
+								   dummyLayers, dummyVolumes,
+								   "Calo::GapVolumes::LAr::PositiveEndcapCover");
+   const Trk::TrackingVolume* ecCoverNeg = new Trk::TrackingVolume(ecNeg,ecUpBounds->clone(), *mAr,
+								   dummyLayers, dummyVolumes,
+								   "Calo::GapVolumes::LAr::NegativeEndcapCover");
+   const Trk::TrackingVolume* ecInnerPos = new Trk::TrackingVolume(new Amg::Transform3D(*ecPos),ecDownBounds, *mAl,
+								   dummyLayers, dummyVolumes,
+								   "Calo::GapVolumes::LAr::PositiveEndcapInner");
+   const Trk::TrackingVolume* ecInnerNeg = new Trk::TrackingVolume(new Amg::Transform3D(*ecNeg),ecDownBounds->clone(),
+								   *mAl, dummyLayers, dummyVolumes,
+								   "Calo::GapVolumes::LAr::NegativeEndcapInner");
+
+   // glue EMEC radially
+   std::vector<const Trk::TrackingVolume*> volsEC;
+   volsEC.push_back(ecInnerPos);
+   volsEC.push_back(lArPositiveEndcap);
+   volsEC.push_back(ecCoverPos);
+   const Trk::TrackingVolume* positiveEC = m_trackingVolumeCreator->createContainerTrackingVolume(volsEC,
+									       *m_caloMaterial,
+									       "Calo::Container::PositiveEndcapR"); 
+   std::vector<const Trk::TrackingVolume*> volsEN;
+   volsEN.push_back(ecInnerNeg);
+   volsEN.push_back(lArNegativeEndcap);
+   volsEN.push_back(ecCoverNeg);
+   const Trk::TrackingVolume* negativeEC = m_trackingVolumeCreator->createContainerTrackingVolume(volsEN,
+									       *m_caloMaterial,
+									       "Calo::Container::NegativeEndcapR"); 
+
+   // glue presampler with EMEC
+   std::vector<const Trk::TrackingVolume*> volEEP;
+   volEEP.push_back(positiveEP);
+   volEEP.push_back(positiveEC);
+   const Trk::TrackingVolume* positiveEEP = m_trackingVolumeCreator->createContainerTrackingVolume(volEEP,
+									       *m_caloMaterial,
+									       "Calo::Container::PositiveEMEC"); 
+   std::vector<const Trk::TrackingVolume*> volEEN;
+   volEEN.push_back(negativeEC);
+   volEEN.push_back(negativeEP);
+   const Trk::TrackingVolume* negativeEEP = m_trackingVolumeCreator->createContainerTrackingVolume(volEEN,
+									       *m_caloMaterial,
+									       "Calo::Container::NegativeEMEC");
+
+   // glue EMEC sector with beam pipe volumes
+
+   std::vector<const Trk::TrackingVolume*> volsEndcapPos;
+   if (endcapBP.first)  volsEndcapPos.push_back(endcapBP.first);
+   volsEndcapPos.push_back(positiveEEP);
+
+   std::unique_ptr<const Trk::TrackingVolume> positiveEndcap
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsEndcapPos,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::PositiveEndcap")); 
+
+   std::vector<const Trk::TrackingVolume*> volsEndcapNeg;
+   if (endcapBP.second)  volsEndcapNeg.push_back(endcapBP.second);
+   volsEndcapNeg.push_back(negativeEEP);
+
+   std::unique_ptr<const Trk::TrackingVolume> negativeEndcap
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsEndcapNeg,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::NegativeEndcap")); 
+
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Hec sector + beam pipe + lAr cover
+
+   // create beam pipe volumes for Hec and return their outer radius 
+   float rHecBP=0.;
+   std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> hecBP = createBeamPipeVolumes( 
+							  lArPositiveHec->center().z()-lArPositiveHecBounds->halflengthZ(),
+							  lArPositiveHec->center().z()+lArPositiveHecBounds->halflengthZ(),
+												       "Hec", rHecBP);
+   // HecInnerGap (new gap volume )
+   Trk::Material lArHecInnerGapMaterial = Trk::Material(390., 1223., 18.,9., 0.0014);
+
+   // create the Bounds
+   Trk::CylinderVolumeBounds* lArHecInnerGapBounds = new Trk::CylinderVolumeBounds(rHecBP,
+										   lArPositiveHecBounds->innerRadius(),
+										   lArPositiveHecBounds->halflengthZ() );
+
+   Amg::Transform3D* lArHecPos = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,lArPositiveHec->center().z())));
+   Amg::Transform3D* lArHecNeg = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,lArNegativeHec->center().z())));
+
+   const Trk::TrackingVolume* lArPositiveHecInnerGap = new Trk::TrackingVolume(lArHecPos,lArHecInnerGapBounds ,
+									       *mAl,
+									       dummyLayers, dummyVolumes,
+									       "Calo::GapVolumes::LAr::PositiveHecInnerGap");
+
+   const Trk::TrackingVolume* lArNegativeHecInnerGap = new Trk::TrackingVolume(lArHecNeg,lArHecInnerGapBounds->clone() ,
+									       *mAl,
+									       dummyLayers, dummyVolumes,
+									       "Calo::GapVolumes::LAr::NegativeHecInnerGap");
+   // create the Bounds
+   Trk::CylinderVolumeBounds* lArHecOuterGapBounds = new Trk::CylinderVolumeBounds(lArPositiveHecBounds->outerRadius(),
+										   keyDim.back().first,
+										   lArPositiveHecBounds->halflengthZ() );
+
+   const Trk::TrackingVolume* lArPositiveHecOuterGap = new Trk::TrackingVolume(new Amg::Transform3D(*lArHecPos),
+									       lArHecOuterGapBounds ,
+									       *mAr,
+									       dummyLayers, dummyVolumes,
+									       "Calo::GapVolumes::LAr::PositiveHecOuterGap");
+
+   const Trk::TrackingVolume* lArNegativeHecOuterGap = new Trk::TrackingVolume(new Amg::Transform3D(*lArHecNeg),
+									       lArHecOuterGapBounds->clone() ,
+									       *mAr,
+									       dummyLayers, dummyVolumes,
+									       "Calo::GapVolumes::LAr::NegativeHecOuterGap");
+
+   // glue Hec sector with beam pipe volumes
+
+   std::vector<const Trk::TrackingVolume*> volsHecPos;
+   if (hecBP.first)  volsHecPos.push_back(hecBP.first);
+   volsHecPos.push_back(lArPositiveHecInnerGap);
+   volsHecPos.push_back(lArPositiveHec);
+   volsHecPos.push_back(lArPositiveHecOuterGap);
+
+   std::unique_ptr<const Trk::TrackingVolume> positiveHec
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsHecPos,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::PositiveHec"));
+
+   std::vector<const Trk::TrackingVolume*> volsHecNeg;
+   if (hecBP.second)  volsHecNeg.push_back(hecBP.second);
+   volsHecNeg.push_back(lArNegativeHecInnerGap);
+   volsHecNeg.push_back(lArNegativeHec);
+   volsHecNeg.push_back(lArNegativeHecOuterGap);
+
+   std::unique_ptr<const Trk::TrackingVolume> negativeHec
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsHecNeg,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::NegativeHec"));
+
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Fcal sector + beam pipe + lAr cover
+
+   // create beam pipe volumes for Fcal and return their outer radius 
+   float rFcalBP=0.;
+   std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> fcalBP = createBeamPipeVolumes( 
+							  lArPositiveFcal->center().z()-lArPositiveFcalBounds->halflengthZ(),
+							  lArPositiveFcal->center().z()+lArPositiveFcalBounds->halflengthZ(),
+												       "Fcal", rFcalBP);
+   // FcalInnerGap (new gap volume )
+   //Trk::Material lArFcalInnerGapMaterial = Trk::Material(390., 1223., 40.,18., 0.0014);
+
+   
+   if ( rFcalBP > lArPositiveFcalBounds->innerRadius()) {
+     ATH_MSG_ERROR("PROBLEM : beam pipe collide with Fcal:"<< rFcalBP <<">" << lArPositiveFcalBounds->innerRadius()<<", abort" );  
+     // create dummy infinite IOV Range 
+     EventIDRange range;
+     return std::pair<EventIDRange, const Trk::TrackingGeometry*>(range,0);
+     
+   }
+
+   // create the Bounds
+   Trk::CylinderVolumeBounds* lArFcalInnerGapBounds = new Trk::CylinderVolumeBounds(rFcalBP,
+										    lArPositiveFcalBounds->innerRadius(),
+										    lArPositiveFcalBounds->halflengthZ() );
+
+   Amg::Transform3D* lArFcalPos = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,lArPositiveFcal->center().z())));
+   Amg::Transform3D* lArFcalNeg = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,lArNegativeFcal->center().z())));
+
+   const Trk::TrackingVolume* lArPositiveFcalInnerGap = new Trk::TrackingVolume(lArFcalPos,lArFcalInnerGapBounds ,
+										*mAl,
+										dummyLayers, dummyVolumes,
+										"Calo::GapVolumes::LAr::PositiveFcalInnerGap");
+
+   const Trk::TrackingVolume* lArNegativeFcalInnerGap = new Trk::TrackingVolume(lArFcalNeg,lArFcalInnerGapBounds->clone() ,
+										*mAl,
+										dummyLayers, dummyVolumes,
+										"Calo::GapVolumes::LAr::NegativeFcalInnerGap");
+
+
+   // create the Bounds
+   Trk::CylinderVolumeBounds* lArFcalOuterGapBounds = new Trk::CylinderVolumeBounds(lArPositiveHecBounds->outerRadius(),
+										    keyDim.back().first,
+										    lArPositiveFcalBounds->halflengthZ() );
+
+   const Trk::TrackingVolume* lArPositiveFcalOuterGap = new Trk::TrackingVolume(new Amg::Transform3D(*lArFcalPos),
+										lArFcalOuterGapBounds ,
+										*mAr,
+										dummyLayers, dummyVolumes,
+										"Calo::GapVolumes::LAr::PositiveFcalOuterGap");
+
+   const Trk::TrackingVolume* lArNegativeFcalOuterGap = new Trk::TrackingVolume(new Amg::Transform3D(*lArFcalNeg),
+										lArFcalOuterGapBounds->clone() ,
+										*mAr,
+										dummyLayers, dummyVolumes,
+										"Calo::GapVolumes::LAr::NegativeFcalOuterGap");
+
+   // glue Fcal sector with beam pipe volumes
+
+   std::vector<const Trk::TrackingVolume*> volsFcalPos;
+   if (fcalBP.first)  volsFcalPos.push_back(fcalBP.first);
+   volsFcalPos.push_back(lArPositiveFcalInnerGap);
+   volsFcalPos.push_back(lArPositiveFcal);
+   volsFcalPos.push_back(lArPositiveHecFcalCover);
+   volsFcalPos.push_back(lArPositiveFcalOuterGap);
+
+   std::unique_ptr<const Trk::TrackingVolume> positiveFcal
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsFcalPos,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::PositiveFcal"));
+
+   std::vector<const Trk::TrackingVolume*> volsFcalNeg;
+   if (fcalBP.second)  volsFcalNeg.push_back(fcalBP.second);
+   volsFcalNeg.push_back(lArNegativeFcalInnerGap);
+   volsFcalNeg.push_back(lArNegativeFcal);
+   volsFcalNeg.push_back(lArNegativeHecFcalCover);
+   volsFcalNeg.push_back(lArNegativeFcalOuterGap);
+
+   std::unique_ptr<const Trk::TrackingVolume> negativeFcal
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsFcalNeg,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::NegativeFcal"));
+
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Outer endcap sector + beam pipe
+
+   // create beam pipe volumes for Outer sector and return their outer radius 
+   float rOutBP=0.;
+   std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> outBP = createBeamPipeVolumes( lArPositiveOuterBoundary, 
+												   caloPositiveOuterBoundary,
+												   "Outer", rOutBP);
+
+   Trk::Material lArSectorOuterGapMat = Trk::Material(20.5, 723., 64., 28., 0.0084);
+   
+   Trk::CylinderVolumeBounds* lArSectorOuterG0Bounds = new Trk::CylinderVolumeBounds( rOutBP, 430.,
+										      //lArPositiveEndcapBounds->outerRadius(),
+							   0.5*(caloPositiveOuterBoundary-lArPositiveOuterBoundary));
+
+   Trk::CylinderVolumeBounds* lArSectorOuterG1Bounds = new Trk::CylinderVolumeBounds( 430., keyDim.back().first,
+										      //lArPositiveEndcapBounds->outerRadius(),
+							   0.5*(caloPositiveOuterBoundary-lArPositiveOuterBoundary));
+   
+   z = 0.5*(caloPositiveOuterBoundary+lArPositiveOuterBoundary);
+
+   Amg::Transform3D* lArSecOutG1P = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,z)));
+   Amg::Transform3D* lArSecOutG0P = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,z)));
+
+   lArPositiveSectorOuterGap0   =  new Trk::TrackingVolume(lArSecOutG0P, lArSectorOuterG0Bounds,
+							  lArSectorOuterGapMat, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LAr::PositiveSectorOuterGap0");
+
+   lArPositiveSectorOuterGap   =  new Trk::TrackingVolume(lArSecOutG1P, lArSectorOuterG1Bounds,
+							  *mAr, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LAr::PositiveSectorOuterGap");
+
+   Amg::Transform3D* lArSecOutG1N = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-z)));
+   Amg::Transform3D* lArSecOutG0N = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-z)));
+
+   lArNegativeSectorOuterGap0   =  new Trk::TrackingVolume(lArSecOutG0N, lArSectorOuterG0Bounds->clone(),
+							  lArSectorOuterGapMat, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LAr::NegativeSectorOuterGap0");
+
+   lArNegativeSectorOuterGap   =  new Trk::TrackingVolume(lArSecOutG1N, lArSectorOuterG1Bounds->clone(),
+							  *mAr, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LAr::NegativeSectorOuterGap");
+
+   // glue OuterGap with beam pipe volumes
+   std::vector<const Trk::TrackingVolume*> volsOuterGapP;
+   if (outBP.first) volsOuterGapP.push_back(outBP.first);
+   volsOuterGapP.push_back(lArPositiveSectorOuterGap0);
+   volsOuterGapP.push_back(lArPositiveSectorOuterGap);
+   std::unique_ptr<const Trk::TrackingVolume> positiveOuterGap
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsOuterGapP,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::PositiveOuterGap"));
+
+   std::vector<const Trk::TrackingVolume*> volsOuterGapN;
+   if (outBP.second) volsOuterGapN.push_back(outBP.second);
+   volsOuterGapN.push_back(lArNegativeSectorOuterGap0);
+   volsOuterGapN.push_back(lArNegativeSectorOuterGap);
+   std::unique_ptr<const Trk::TrackingVolume> negativeOuterGap
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsOuterGapN,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::NegativeOuterGap"));
+
+   ATH_MSG_DEBUG( "Endcap volumes ready" );
+
+   // ++ (ii) lArNegativeSector 
+   const Trk::TrackingVolume* lArNegativeSector           = 0;             
+   // +++ has 4 sub volumes in Z
+   std::vector<const Trk::TrackingVolume*> lArNegativeSectorVolumes;
+   // +++ (A) -> Outer sector 
+   lArNegativeSectorVolumes.push_back(negativeOuterGap.release());
+   // +++ (B) -> Fcal sector
+   lArNegativeSectorVolumes.push_back(negativeFcal.release());
+   // +++ (C) -> Hec sector
+   lArNegativeSectorVolumes.push_back(negativeHec.release());
+   // +++ (D) -> Endcap sector
+   lArNegativeSectorVolumes.push_back(negativeEndcap.release());
+   // +++ all exists : create super volume (ii)
+   lArNegativeSector = m_trackingVolumeCreator->createContainerTrackingVolume( lArNegativeSectorVolumes,
+									       *m_caloMaterial,
+									       "Calo::LAr::Container::NegativeSector");
+
+   // ++ (ii) lArPositiveSector 
+   const Trk::TrackingVolume* lArPositiveSector           = 0;             
+   // +++ has 4 sub volumes in Z
+   std::vector<const Trk::TrackingVolume*> lArPositiveSectorVolumes;
+   // +++ (A) -> Endcap sector
+   lArPositiveSectorVolumes.push_back(positiveEndcap.release());	 
+   // +++ (B) -> Hec sector
+   lArPositiveSectorVolumes.push_back(positiveHec.release());
+   // +++ (C) -> Fcal sector
+   lArPositiveSectorVolumes.push_back(positiveFcal.release());
+   // +++ (D) -> OuterGap
+   lArPositiveSectorVolumes.push_back(positiveOuterGap.release());
+   // +++ all exists : create super volume (ii)
+   lArPositiveSector = m_trackingVolumeCreator->createContainerTrackingVolume( lArPositiveSectorVolumes,
+									       *m_caloMaterial,
+									       "Calo::LAr::Container::PositiveSector");
+   
+   ////////////////////////////////////////////////////////////////////////////////////// 
+   // central LAr barrel
+   //
+   // solenoid gap 
+   Trk::CylinderVolumeBounds* trtSolGapBounds = new Trk::CylinderVolumeBounds(  keyDim[0].first,
+										solenoidBounds->innerRadius(),
+										solenoidBounds->halflengthZ());
+
+   // solenoid gap is not completely empty
+   Trk::Material solGapMat(535.,2871.,18.6,9.1,0.00038);
+   
+   
+   trtSolenoidGap = new Trk::TrackingVolume(0,
+					    trtSolGapBounds,
+					    solGapMat,
+					    dummyLayers, dummyVolumes, 
+					    "Calo::GapVolumes::SolenoidGap");
+
+   Trk::CylinderVolumeBounds* lArTileCentralG1Bounds = new Trk::CylinderVolumeBounds( lArBarrelBounds->outerRadius(),
+										      tileCombinedBounds->innerRadius(),
+										      lArBarrelBounds->halflengthZ());
+                                                 
+   
+
+   lArTileCentralSectorGap      = new Trk::TrackingVolume(0, lArTileCentralG1Bounds,
+							  *mAr, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LArTileCentralSectorGap");
+
+
+   const Trk::TrackingVolume* lArCentralBarrelSector    = 0;
+   // ++ has 6 sub volumes in R
+   std::vector<const Trk::TrackingVolume*> lArCentralBarrelSectorVolumes;
+   // ++++ (a) -> solenoid gap 
+   lArCentralBarrelSectorVolumes.push_back(trtSolenoidGap);
+   // ++++ (b) -> solenoid (exists already)
+   lArCentralBarrelSectorVolumes.push_back(solenoid);
+   // ++++ (c) -> solenoidlArPresamplerGap (exists already)
+   lArCentralBarrelSectorVolumes.push_back(solenoidlArPresamplerGap);
+   // ++++ (d) -> lArBarrelPresampler (exists already)
+   lArCentralBarrelSectorVolumes.push_back(lArBarrelPresampler);
+   // ++++ (e) -> lArBarrel (exists already)
+   lArCentralBarrelSectorVolumes.push_back(lArBarrel);
+   // ++++ (f) -> lArTile gap 
+   lArCentralBarrelSectorVolumes.push_back(lArTileCentralSectorGap);
+   // ++++ all sub volumes exist: build the super volume
+   lArCentralBarrelSector =  m_trackingVolumeCreator->createContainerTrackingVolume(
+										    lArCentralBarrelSectorVolumes,
+										    *m_caloMaterial,
+										    "Calo::Containers::LAr::CentralBarrelSector",
+										    false, true);
+   /////////////////////////////////////////////////////////////////////////////////////
+   // side buffers   
+   // the Tile Crack volume (TileGap3, enum 17) inserted here
+   // binned material for Crack : steering in binEta
+   // TODO turn into 2D binned array
+   std::vector<const Trk::IdentifiedMaterial*> matCrack;
+   // layer material can be adjusted here
+   int baseID = Trk::GeometrySignature(Trk::Calo)*1000 + 17;
+   matCrack.push_back(new std::pair<const Trk::Material*,int>(mScint,baseID));
+   matCrack.push_back(new std::pair<const Trk::Material*,int>(m_caloMaterial,-1));
+   matCrack.push_back(new std::pair<const Trk::Material*,int>(mAl,-1));
+   //
+   Trk::BinUtility* bun = new Trk::BinUtility(3,-1.8,-1.2,Trk::open,Trk::binEta);
+   Trk::BinUtility* bup = new Trk::BinUtility(3, 1.2,1.8,Trk::open,Trk::binEta);
+   // array of indices
+   std::vector<std::vector<size_t> > indexP;  
+   std::vector<std::vector<size_t> > indexN;  
+   // binned material for LAr : layer depth per eta bin
+   std::vector< Trk::BinUtility*> layDN(bun->bins());
+   std::vector< Trk::BinUtility*> layUP(bup->bins());
+   double crackZ1 = 3532.;
+   double crackZ2 = 3540.;
+   // construct bin utilities 
+   std::vector<float> steps;
+   for (unsigned int i=0; i< bup->bins(); i++) {
+     steps.clear();
+     std::vector<size_t> indx; indx.clear();
+     steps.push_back(crackZ1);
+     indx.push_back( i<2 ? 0 : 1);
+     steps.push_back(crackZ2);
+     indx.push_back(2);
+     steps.push_back(keyDim.back().second);
+     Trk::BinUtility* zBU = new Trk::BinUtility(steps, Trk::open, Trk::binZ);
+     layUP[i] = zBU;
+     indexP.push_back(indx);
+   } 
+
+   const Trk::BinnedMaterial* crackBinPos = new Trk::BinnedMaterial(crackMaterial,bup,layUP,indexP,matCrack);
+   
+   Amg::Transform3D* align=0;
+   
+   Trk::CylinderVolumeBounds* crackBoundsPos = new Trk::CylinderVolumeBounds( keyDim[0].first,
+									      tileCombinedBounds->innerRadius(),
+									      0.5*(keyDim.back().second-crackZ1));
+   z = 0.5*(keyDim.back().second+crackZ1);
+   Amg::Transform3D* crackPosTransform = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,z)));
+   
+   const Trk::AlignableTrackingVolume* crackPos = new Trk::AlignableTrackingVolume(crackPosTransform,align,
+										   crackBoundsPos,
+										   crackBinPos,
+										   17,
+										   "Calo::Detectors::Tile::CrackPos");
+
+   for (unsigned int i=0; i< bun->bins(); i++) {
+     steps.clear();
+     std::vector<size_t> indx; indx.clear();
+     steps.push_back(-keyDim.back().second);
+     indx.push_back(2);
+     steps.push_back(-crackZ2);
+     indx.push_back( i>0 ? 0 : 1);
+     steps.push_back(-crackZ1);
+     Trk::BinUtility* zBU = new Trk::BinUtility(steps, Trk::open, Trk::binZ);
+     layDN[i] = zBU;
+     indexN.push_back(indx);
+   } 
+
+   const Trk::BinnedMaterial* crackBinNeg = new Trk::BinnedMaterial(crackMaterial,bun,layDN,indexN,matCrack);
+   
+   align=0;
+   
+   Amg::Transform3D* crackNegTransform = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-z)));
+   
+   const Trk::AlignableTrackingVolume* crackNeg = new Trk::AlignableTrackingVolume(crackNegTransform,align,
+										   crackBoundsPos->clone(),
+										   crackBinNeg,
+										   17,
+										   "Calo::Detectors::Tile::CrackNeg");
+    ////
+  
+   Trk::CylinderVolumeBounds* lArCentralG1Bounds = new Trk::CylinderVolumeBounds( keyDim[0].first,
+										  tileCombinedBounds->innerRadius(),
+										  0.5*(crackZ1-lArBarrelBounds->halflengthZ()));
+
+   z = 0.5*(crackZ1+lArBarrelBounds->halflengthZ());
+   Amg::Transform3D* lArCentralG1P = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,z)));
+
+   
+   lArCentralPositiveGap        = new Trk::TrackingVolume(lArCentralG1P, lArCentralG1Bounds,
+							  *mAr, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LArCentralPositiveGap");
+
+   Amg::Transform3D* lArCentralG1N = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-z)));
+   
+   lArCentralNegativeGap        = new Trk::TrackingVolume(lArCentralG1N, lArCentralG1Bounds->clone(),
+							  *mAr, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LArCentralNegativeGap");
+
+   // glue laterally
+   const Trk::TrackingVolume* lArCentralSector    = 0;
+   // ++ has 5 sub volumes in z
+   std::vector<const Trk::TrackingVolume*> lArCentralSectorVolumes;
+   // ++++ (a) -> negative crack
+   lArCentralSectorVolumes.push_back(crackNeg);
+   // ++++ (b) -> negative gap 
+   lArCentralSectorVolumes.push_back(lArCentralNegativeGap);
+   // ++++ (c) -> central barrel 
+   lArCentralSectorVolumes.push_back(lArCentralBarrelSector);
+   // ++++ (d) -> positive gap 
+   lArCentralSectorVolumes.push_back(lArCentralPositiveGap);
+   // ++++ (e) -> positive crack 
+   lArCentralSectorVolumes.push_back(crackPos);
+   // ++++ all sub volumes exist: build the super volume
+   lArCentralSector =  m_trackingVolumeCreator->createContainerTrackingVolume(
+									     lArCentralSectorVolumes,
+									     *m_caloMaterial,
+									     "Calo::Containers::LAr::CentralSector");
+  
+   // glue with ID sector
+   const Trk::TrackingVolume* caloCentralSector    = 0;
+   // ++ has 2 sub volumes in R
+   std::vector<const Trk::TrackingVolume*> caloCentralSectorVolumes;
+   // ++++ (a) -> ID sector
+   caloCentralSectorVolumes.push_back(inDetEnclosed);
+   // ++++ (b) -> LAr sector 
+   caloCentralSectorVolumes.push_back(lArCentralSector);
+   // ++++ all sub volumes exist: build the super volume
+   caloCentralSector =  m_trackingVolumeCreator->createContainerTrackingVolume(
+									  caloCentralSectorVolumes,
+									  *m_caloMaterial,
+									  "Calo::Containers::CaloCentralSector");
+
+   //std::cout <<"Combined LAr sector ready"<< std::endl;
+   //////////////////////////////////////////////////////////////////////
+
+
+   // glue laterally with endcaps
+   const Trk::TrackingVolume* lArCombined    = 0;
+   // ++ has 3 sub volumes in z
+   std::vector<const Trk::TrackingVolume*> lArCombinedVolumes;
+   // ++++ (a) -> negative endcap 
+   lArCombinedVolumes.push_back(lArNegativeSector);
+   // ++++ (b) -> barrel 
+   lArCombinedVolumes.push_back(caloCentralSector);
+   // ++++ (a) -> positive endcap 
+   lArCombinedVolumes.push_back(lArPositiveSector);
+   // ++++ all sub volumes exist: build the super volume
+   lArCombined =  m_trackingVolumeCreator->createContainerTrackingVolume(
+									 lArCombinedVolumes,
+									 *m_caloMaterial,
+									 "Calo::Containers::LAr::Combined");
+ 
+   //std::cout <<"Combined LAr ready " << std::endl; 
+
+   // glue with LAr sector
+   const Trk::TrackingVolume* caloCombined    = 0;
+   // ++ has 2 sub volumes in R
+   std::vector<const Trk::TrackingVolume*> caloVolumes;
+   // ++++ (a) -> LAr sector
+   caloVolumes.push_back(lArCombined);
+   // ++++ (b) -> Tile sector 
+   caloVolumes.push_back(tileCombined);
+   // ++++ all sub volumes exist: build the super volume
+   caloCombined =  m_trackingVolumeCreator->createContainerTrackingVolume(
+									 caloVolumes,
+									 *m_caloMaterial,
+									 "Calo::Containers::CombinedCalo");
+
+   //std::cout <<"Combined Calo ready"<< std::endl;
+
+   ///////////////////////////////////////////////////////////////////////////////////////////////
+
+   // build the radial buffer volume to synchronize the radial envelope dimensions 
+   const Trk::TrackingVolume* centralBuffer = 0;
+   const Trk::TrackingVolume* ecPosBuffer = 0;
+   const Trk::TrackingVolume* ecNegBuffer = 0;
+    
+   if ( caloVolsOuterRadius >  m_caloDefaultRadius ) {
+     ATH_MSG_VERBOSE( "Calo volumes exceeds envelope radius: adjusting envelope (de-synchronizing...)" );
+     m_caloDefaultRadius = caloVolsOuterRadius;
+   }
+
+   if ( caloVolsOuterRadius <  m_caloDefaultRadius ) {
+     ATH_MSG_VERBOSE( "Build radial buffer to synchronize the boundaries in between R "<< caloVolsOuterRadius<<" and "<< m_caloDefaultRadius );
+     
+     Trk::CylinderVolumeBounds* centralSynBounds = new Trk::CylinderVolumeBounds(caloVolsOuterRadius,
+										 m_caloDefaultRadius,
+										 caloVolsExtendZ);
+     centralBuffer = new Trk::TrackingVolume(0, centralSynBounds,
+					     *m_caloMaterial,
+					     dummyLayers, dummyVolumes,
+					     "Calo::GapVolumes::EnvelopeBuffer");
+   }
+
+   if ( caloVolsExtendZ <  m_caloDefaultHalflengthZ ) {
+     ATH_MSG_VERBOSE( "Build longitudinal buffers to synchronize the boundaries in between Z "<< caloVolsExtendZ<<" and "<< m_caloDefaultHalflengthZ );
+     
+     Trk::CylinderVolumeBounds* endcapSynBounds = new Trk::CylinderVolumeBounds(0., m_caloDefaultRadius,
+										0.5*(m_caloDefaultHalflengthZ-caloVolsExtendZ));
+     // endcap buffers not empty 
+     Trk::Material ecBuffMat(53./0.38, 355./0.38, 20., 10., 0.0053*pow(0.38,3));
+     
+     float zPos = 0.5*(m_caloDefaultHalflengthZ+caloVolsExtendZ);
+     ecPosBuffer = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,zPos))),
+					   endcapSynBounds,
+					   *mAr,
+					   dummyLayers, dummyVolumes,
+					   "Calo::GapVolumes::PosECBuffer");
+
+     ecNegBuffer = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-zPos))),
+					   endcapSynBounds->clone(),
+					   *mAr,
+					   dummyLayers, dummyVolumes,
+					   "Calo::GapVolumes::NegECBuffer");
+   }
+   
+   ATH_MSG_VERBOSE( "All gap volumes for the Calorimeter created. Starting to build Volume Hiearchy." );   
+	
+   /////////////////////////////////////////////////////////////////////////////////////////////////
+   
+   ATH_MSG_VERBOSE( "Resolve MS cutouts:" );   
+   
+   // resolve number of additional cutout volumes
+   int nCutVol = 0;
+   std::vector<float> zCutStep;
+   std::vector<float> rCutStep;
+   if (msCutouts.size()>1) {
+     zCutStep.push_back(msCutouts[0].second); 
+     rCutStep.push_back(msCutouts[0].first); 
+     for (unsigned int i=1; i<msCutouts.size(); i++) {
+       if (msCutouts[i].second == zCutStep.back()) rCutStep.push_back(msCutouts[i].first);
+       else zCutStep.push_back(msCutouts[i].second);
+     }
+     nCutVol = zCutStep.size()-1;
+   }
+   if (nCutVol>0) ATH_MSG_VERBOSE( nCutVol << " MS cutout volume(s) required " );
+
+   std::vector<const Trk::TrackingVolume*> forwardCutoutVols;
+   std::vector<const Trk::TrackingVolume*> backwardCutoutVols;
+
+   // cutout region not empty 
+   std::vector<Trk::Material> cutOutMat;
+   cutOutMat.push_back(Trk::Material(19.9, 213., 50., 23., 0.0065));     // 3.5 Fe + 1 Ar : verify
+   cutOutMat.push_back(*m_caloMaterial);
+   //cutOutMat.push_back(Trk::Material(18.74, 200.9, 52.36, 24.09, 0.0069));
+   
+   if (nCutVol>0) {
+     // loop over zCutStep, rCutStep[0] gives the fixed outer radius, rCutStep[i] the cutout radius for ith volume
+     float rout = rCutStep[0];
+     float zlow = zCutStep[0];
+     for (unsigned int i=1; i<zCutStep.size(); i++) {
+       float zup  = zCutStep[i];
+       float rcut = rCutStep[i];
+       std::stringstream ss;
+       ss << i;
+       // get beam pipe volumes
+       float rCutOutBP = 0.;
+       std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> cutOutBP = createBeamPipeVolumes(zlow,zup,  
+												       "CutOuts"+ss.str(), rCutOutBP);
+
+       // build inner part ( -> Calo )
+       unsigned int mindex = i>1 ? 1 : i;
+       
+       Trk::CylinderVolumeBounds* cutInBounds = new Trk::CylinderVolumeBounds( rCutOutBP,rcut, 0.5*(zup-zlow));
+       const Trk::TrackingVolume* caloInPos = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,0.5*(zup+zlow)))),
+								      cutInBounds,
+								      cutOutMat[mindex],
+								      dummyLayers, dummyVolumes,
+								      "Calo::GapVolumes::CaloPositiveCutIn"+ss.str());
+       const Trk::TrackingVolume* caloInNeg = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-0.5*(zup+zlow)))),
+								      cutInBounds->clone(),
+								      cutOutMat[mindex],
+								      dummyLayers, dummyVolumes,
+								      "Calo::GapVolumes::CaloNegativeCutIn"+ss.str());
+       // build cutout ( -> MS ) : geometry signature needs to be resolved later : follow naming convention 
+       Trk::CylinderVolumeBounds* cutOutBounds = new Trk::CylinderVolumeBounds( rcut, rout, 0.5*(zup-zlow));
+       const Trk::TrackingVolume* caloOutPos = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,0.5*(zup+zlow)))),
+								       cutOutBounds,
+								       *m_caloMaterial,
+								       dummyLayers, dummyVolumes,
+								       "Muon::GapVolumes::CaloPositiveCutOut"+ss.str());
+       const Trk::TrackingVolume* caloOutNeg = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-0.5*(zup+zlow)))),
+								       cutOutBounds->clone(),
+								       *m_caloMaterial,
+								       dummyLayers, dummyVolumes,
+								       "Muon::GapVolumes::CaloNegativeCutOut"+ss.str());
+
+       // sign
+       caloOutPos->sign(Trk::MS);
+       caloOutNeg->sign(Trk::MS);
+   
+       // glue radially and save for final gluing
+       std::vector<const Trk::TrackingVolume*> cvPos;
+       cvPos.push_back(cutOutBP.first);
+       cvPos.push_back(caloInPos);
+       cvPos.push_back(caloOutPos);
+       const Trk::TrackingVolume* cutOutPos = m_trackingVolumeCreator->createContainerTrackingVolume(cvPos,
+												*m_caloMaterial,
+										"Calo::GapVolumes::CaloPositiveCutoutVolume"+ss.str());
+       forwardCutoutVols.push_back(cutOutPos);      
+       //
+       std::vector<const Trk::TrackingVolume*> cvNeg;
+       cvNeg.push_back(cutOutBP.second);
+       cvNeg.push_back(caloInNeg);
+       cvNeg.push_back(caloOutNeg);
+       const Trk::TrackingVolume* cutOutNeg = m_trackingVolumeCreator->createContainerTrackingVolume(cvNeg,
+												*m_caloMaterial,
+										"Calo::GapVolumes::CaloNegativeCutoutVolume"+ss.str());
+       backwardCutoutVols.insert(backwardCutoutVols.begin(),cutOutNeg);      
+  
+       zlow = zup;
+     }
+   }
+
+  /////////////////
+
+ 
+  if (!centralBuffer) {   //(XX)
+    // all volumes exist : create the super volume at top level
+    calorimeter = caloCombined;
+
+  } else {                //(X)
+
+    std::vector<const Trk::TrackingVolume*> envRVols;
+    envRVols.push_back(caloCombined);
+    envRVols.push_back(centralBuffer);
+    
+    // add cutouts - final step
+    if ( forwardCutoutVols.size()>0 || ecNegBuffer ) {
+      
+      const Trk::TrackingVolume* caloRVolume = m_trackingVolumeCreator->createContainerTrackingVolume(envRVols,
+												      *m_caloMaterial,
+												      "Calo::Containers::CombinedRCalo");
+      std::vector<const Trk::TrackingVolume*> envZVols;
+      for (unsigned int i=0; i<backwardCutoutVols.size(); i++) envZVols.push_back(backwardCutoutVols[i]);   
+      if (ecNegBuffer) envZVols.push_back(ecNegBuffer);
+      envZVols.push_back(caloRVolume);  
+      if (ecPosBuffer) envZVols.push_back(ecPosBuffer);
+      for (unsigned int i=0; i<forwardCutoutVols.size(); i++) envZVols.push_back(forwardCutoutVols[i]);
+      
+      calorimeter = m_trackingVolumeCreator->createContainerTrackingVolume(envZVols,
+									   *m_caloMaterial,
+									   m_exitVolume);
+      
+      
+      
+    } else { // if no cutouts or endcap buffers, this is the top calo volume  
+      
+      calorimeter = m_trackingVolumeCreator->createContainerTrackingVolume(envRVols,
+									   *m_caloMaterial,
+									   m_exitVolume);
+    }
+    
+  }
+
+  ATH_MSG_VERBOSE( "TrackingVolume 'Calorimeter' built successfully. Wrap it in TrackingGeometry." );
+
+  delete lArVolumes; lArVolumes = 0;
+  delete tileVolumes; tileVolumes = 0;
+  
+  caloTrackingGeometry = new Trk::TrackingGeometry(calorimeter);
+  
+  if (msgLvl(MSG::VERBOSE) && caloTrackingGeometry) 
+    caloTrackingGeometry->printVolumeHierarchy(msg(MSG::VERBOSE));   
+  
+  if (m_indexStaticLayers && caloTrackingGeometry)
+    caloTrackingGeometry->indexStaticLayers( geometrySignature() );   
+  
+//     /** enumeration of samplings (i.e.layers) separately for various sub calorimeters */
+//     enum CaloSample {
+//       PreSamplerB=0, EMB1, EMB2, EMB3,       // LAr barrel
+//       PreSamplerE, EME1, EME2, EME3,         // LAr EM endcap
+//       HEC0, HEC1, HEC2, HEC3,                // Hadronic end cap cal.
+//       TileBar0, TileBar1, TileBar2,          // Tile barrel
+//       TileGap1, TileGap2, TileGap3,          // Tile gap (ITC & scint)
+//       TileExt0, TileExt1, TileExt2,          // Tile extended barrel
+//       FCAL0, FCAL1, FCAL2,                   // Forward EM endcap
+//       Unknown
+//     };
+  // create dummy infinite IOV Range 
+  // return what you have ...
+  return std::make_pair(range, caloTrackingGeometry);
+}
+
+void Calo::CaloTrackingGeometryBuilderCond::registerInLayerIndexCaloSampleMap(
+                                             Trk::LayerIndexSampleMap& licsMap,
+                                             std::vector<CaloCell_ID::CaloSample> ccid,
+                                             const Trk::TrackingVolume& vol,
+                                             int side) const
+{
+
+  ATH_MSG_VERBOSE( "[+] Registering layers of TrackingVolume '" << vol.volumeName() << "' in LayerIndex/CaloCell_ID map" );   
+
+  // get the confined Layers from the TrackingVolume
+  const Trk::LayerArray* confinedLayers = vol.confinedLayers();
+  if (!confinedLayers) return;
+  
+  const std::vector<const Trk::Layer*>& layerObjects = confinedLayers->arrayObjects();
+  std::vector<const Trk::Layer*>::const_iterator layerObjIter = layerObjects.begin();
+  std::vector<const Trk::Layer*>::const_iterator layerObjEnd  = layerObjects.end();
+  
+  // now pick out the material layers (and skip the navigation ones)
+  std::vector<const Trk::Layer*> materialLayers;
+  for ( ; layerObjIter != layerObjEnd; ++layerObjIter)
+     if ((*layerObjIter)->layerMaterialProperties()) materialLayers.push_back((*layerObjIter));
+  
+  unsigned int matLaySize = materialLayers.size();
+  unsigned int ccidSize   = ccid.size();
+        
+  ATH_MSG_VERBOSE( "[+] Found " << matLaySize << " material layers ( " << ccidSize << " CaloSample ids )" );  
+  if ( matLaySize != ccidSize ) return;
+  
+  // everything's fine for side > 0
+  if (side > 0){
+     // match 1-to-1 
+     std::vector<const Trk::Layer*>::iterator layerIt             = materialLayers.begin();
+     std::vector<const Trk::Layer*>::iterator layerItEnd          = materialLayers.end();
+     std::vector<CaloCell_ID::CaloSample>::iterator ccidIt    = ccid.begin();
+     std::vector<CaloCell_ID::CaloSample>::iterator ccidItEnd = ccid.end();
+          
+     for ( ; layerIt != layerItEnd  && ccidIt != ccidItEnd; ++layerIt, ++ccidIt)
+         licsMap.insert(std::make_pair((*layerIt)->layerIndex(),int(*ccidIt)));
+       
+  } else {  
+    // the order needs to be reversed, because TG has z-ordering positive defined
+    
+     std::vector<CaloCell_ID::CaloSample>::iterator ccidIt    = ccid.begin();
+     std::vector<CaloCell_ID::CaloSample>::iterator ccidItEnd = ccid.end();
+          
+     for ( ;ccidIt != ccidItEnd; ++ccidIt, --matLaySize)
+         licsMap.insert(std::make_pair((materialLayers[matLaySize-1])->layerIndex(),int(*ccidIt)));    
+  
+  }
+  
+}
+
+std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> Calo::CaloTrackingGeometryBuilderCond::createBeamPipeVolumes(float zmin, float zmax, 
+															  std::string name,float& outerRadius ) const
+{
+  outerRadius = 0.;
+
+  // dummy objects
+  const Trk::LayerArray* dummyLayers = 0;
+  const Trk::TrackingVolumeArray* dummyVolumes = 0;
+
+  // beam pipe thickness along the z distance
+  if (!m_bpCutouts.size()) {
+    return std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> (0,0);
+  }
+
+  RZPairVector dim; 
+  dim.push_back(RZPair(m_bpCutouts[0].first,zmin));
+  float rOut = m_bpCutouts[0].first;
+  for (unsigned int i=0; i<m_bpCutouts.size(); i++) {
+    if (m_bpCutouts[i].second<=dim[0].second) dim[0].first=m_bpCutouts[i].first;
+    else if ( m_bpCutouts[i].second<=zmax ) dim.push_back(m_bpCutouts[i]);
+    if ( m_bpCutouts[i].second<=zmax ) rOut = m_bpCutouts[i].first;
+  }
+  
+  if (dim.back().second < zmax) dim.push_back(RZPair(rOut,zmax));
+
+  if (dim.size()==2) {   // simple case
+    
+    outerRadius = dim[0].first;
+    
+    Trk::CylinderVolumeBounds* bpBounds = new Trk::CylinderVolumeBounds( 0., outerRadius,
+									 0.5*(zmax-zmin));
+    
+    Amg::Transform3D* bpPos = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,0.5*(zmin+zmax))));
+    
+    const Trk::TrackingVolume* bpVolPos = new Trk::TrackingVolume(bpPos, bpBounds,
+								  *m_caloMaterial, 
+								  dummyLayers, dummyVolumes, 
+								  "BeamPipe::Positive"+name);
+
+    Amg::Transform3D* bpNeg = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-0.5*(zmin+zmax))));
+    
+    const Trk::TrackingVolume* bpVolNeg = new Trk::TrackingVolume(bpNeg, bpBounds->clone(),
+								  *m_caloMaterial, 
+								  dummyLayers, dummyVolumes, 
+								  "BeamPipe::Negative"+name);
+
+    // geometry signature 
+    bpVolPos->sign(Trk::BeamPipe);
+    bpVolNeg->sign(Trk::BeamPipe);
+    
+    return std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> (bpVolPos,bpVolNeg); 
+
+  }
+
+  // cutout included
+
+  outerRadius = dim[0].first;
+  
+  // find rMax
+  for (unsigned int i=1; i<dim.size(); i++) if (dim[i].first > outerRadius) outerRadius = dim[i].first;
+  
+  // loop over z sections, prepare volumes for gluing
+  std::vector<const Trk::TrackingVolume*> posVols;
+  
+  for (unsigned int i=0; i<dim.size()-1; i++) {
+    
+    if (dim[i].second == dim[i+1].second) continue;
+    
+    // beam pipe volume 
+    Trk::CylinderVolumeBounds* bpBounds = new Trk::CylinderVolumeBounds( 0., dim[i].first,
+									 0.5*(dim[i+1].second - dim[i].second));
+    
+    Amg::Transform3D* bpPos = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,0.5*(dim[i+1].second + dim[i].second))));
+    
+    const Trk::TrackingVolume* bpVolPos = new Trk::TrackingVolume(bpPos, bpBounds,
+								  *m_caloMaterial, 
+								  dummyLayers, dummyVolumes, 
+								  "BeamPipe::Positive"+name);
+    bpVolPos->sign(Trk::BeamPipe);
+    
+    const Trk::TrackingVolume* bpVolGap = 0;
+    if ( dim[i].first < outerRadius ) {
+
+      Trk::CylinderVolumeBounds* bpGB = new Trk::CylinderVolumeBounds( dim[i].first, outerRadius,
+								       0.5*(dim[i+1].second - dim[i].second));
+
+      Amg::Transform3D* bpPB = new Amg::Transform3D(*bpPos);
+
+      bpVolGap = new Trk::TrackingVolume(bpPB, bpGB,
+					 *m_caloMaterial, 
+					 dummyLayers, dummyVolumes, 
+					 "Calo::GapVolumes::Positive"+name); 
+    }
+    
+    const Trk::TrackingVolume* bpSector = bpVolPos;
+    
+    if (bpVolGap) {
+      std::vector<const Trk::TrackingVolume*> gapVols;
+      gapVols.push_back(bpVolPos);
+      gapVols.push_back(bpVolGap); 
+      bpSector = m_trackingVolumeCreator->createContainerTrackingVolume(gapVols,
+									*m_caloMaterial,
+									"Calo::Container::PositiveBPSector"+name);
+    }   
+    posVols.push_back(bpSector);
+  }
+
+  //std::cout <<" processing complex beam pipe sector +: gluing in Z:"<< std::endl;
+  //for (unsigned int i=0; i<posVols.size(); i++) std::cout <<i<<","<<posVols[i]->volumeName()<<","<<posVols[i]->center().z()<< std::endl;
+  
+  const Trk::TrackingVolume* bpPosSector = m_trackingVolumeCreator->createContainerTrackingVolume(posVols,
+												  *m_caloMaterial,
+												  "Calo::Container::PositiveBP"+name);
+
+  //const Trk::CylinderVolumeBounds* testBounds 
+  //    = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(bpPosSector->volumeBounds()));
+  
+  //if (testBounds) std::cout <<"positive BP sector created at z="<<bpPosSector->center().z()<<" and halfZ="<< testBounds->halflengthZ()<< std::endl;
+
+
+  // loop over z sections, prepare volumes for gluing
+  std::vector<const Trk::TrackingVolume*> negVols;
+  
+  for (unsigned int i=0; i<dim.size()-1; i++) {
+    
+    float zmax2 = -1.* (dim[i].second);
+    float zmin2 = -1.* (dim[i+1].second);
+
+    if (zmin2 == zmax2) continue;
+    
+    // beam pipe volume 
+    Trk::CylinderVolumeBounds* bpBounds = new Trk::CylinderVolumeBounds( 0., dim[i].first,
+									 0.5*(zmax2-zmin2));
+    
+    Amg::Transform3D* bpNeg = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,0.5*(zmin2+zmax2))));
+    
+    const Trk::TrackingVolume* bpVolNeg = new Trk::TrackingVolume(bpNeg, bpBounds,
+								  *m_caloMaterial, 
+								  dummyLayers, dummyVolumes, 
+								  "BeamPipe::Negative"+name);
+    bpVolNeg->sign(Trk::BeamPipe);
+    
+    const Trk::TrackingVolume* bpVolGap = dim[i].first < outerRadius ?
+      new Trk::TrackingVolume(new Amg::Transform3D(*bpNeg),
+			      new Trk::CylinderVolumeBounds( dim[i].first, outerRadius,
+							     0.5*(zmax2 - zmin2)),
+			      *m_caloMaterial, 
+			      dummyLayers, dummyVolumes, 
+			      "Calo::GapVolumes::Negative"+name)  : 0 ;
+    
+    const Trk::TrackingVolume* bpSector = bpVolNeg;
+    
+    if (bpVolGap) {
+      std::vector<const Trk::TrackingVolume*> gapVols;
+      gapVols.push_back(bpVolNeg);
+      gapVols.push_back(bpVolGap); 
+      bpSector = m_trackingVolumeCreator->createContainerTrackingVolume(gapVols,
+									*m_caloMaterial,
+									"Calo::Container::NegativeBPSector"+name);
+    }   
+
+    if (!negVols.size()) negVols.push_back(bpSector);
+    else negVols.insert(negVols.begin(),bpSector);
+  }
+  
+  //std::cout <<" processing complex beam pipe sector -: gluing in Z:"<< std::endl;
+  //for (unsigned int i=0; i<negVols.size(); i++) std::cout <<i<<","<<negVols[i]->volumeName()<<","<<negVols[i]->center().z()<< std::endl;
+
+  const Trk::TrackingVolume* bpNegSector = m_trackingVolumeCreator->createContainerTrackingVolume(negVols,
+												  *m_caloMaterial,
+												  "Calo::Container::NegativeBP"+name);
+  
+  //testBounds 
+  //    = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(bpNegSector->volumeBounds()));
+  
+  //if (testBounds) std::cout <<"negative BP sector created at z="<<bpNegSector->center().z()<<" and halfZ="<< testBounds->halflengthZ()<< std::endl;
+  
+  return std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> (bpPosSector,bpNegSector);
+
+}
+
+
+
diff --git a/Calorimeter/CaloTrackingGeometry/src/components/CaloTrackingGeometry_entries.cxx b/Calorimeter/CaloTrackingGeometry/src/components/CaloTrackingGeometry_entries.cxx
index b3f13e36bc0ac0d4ff739664bca0f50786ec9798..ea238193cebd2a47eba02046a4453658a94bed5f 100644
--- a/Calorimeter/CaloTrackingGeometry/src/components/CaloTrackingGeometry_entries.cxx
+++ b/Calorimeter/CaloTrackingGeometry/src/components/CaloTrackingGeometry_entries.cxx
@@ -2,9 +2,12 @@
 #include "CaloTrackingGeometry/CaloSurfaceBuilder.h"
 #include "CaloTrackingGeometry/CaloSurfaceHelper.h"
 
+#include "CaloTrackingGeometry/CaloTrackingGeometryBuilderCond.h"
+
 using namespace Calo;
 
 DECLARE_COMPONENT( CaloTrackingGeometryBuilder )
 DECLARE_COMPONENT( CaloSurfaceBuilder )
 DECLARE_COMPONENT( CaloSurfaceHelper )
 
+DECLARE_COMPONENT( CaloTrackingGeometryBuilderCond )
diff --git a/Control/AthContainers/AthContainers/tools/ElementProxy.icc b/Control/AthContainers/AthContainers/tools/ElementProxy.icc
index c394f225130c270403234922a0ad4975cf1cbad1..c7322bdea6365cd3f975d0313dd73343c8049473 100644
--- a/Control/AthContainers/AthContainers/tools/ElementProxy.icc
+++ b/Control/AthContainers/AthContainers/tools/ElementProxy.icc
@@ -1,8 +1,6 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
-
-// $Id$
 /**
  * @file AthContainers/tools/ElementProxy.icc
  * @author scott snyder <snyder@bnl.gov>
@@ -46,9 +44,11 @@ ElementProxy<DVL>::ElementProxy (typename DVL::BaseContainer::iterator i,
  * @c DataVector/List's, both of which own their elements.
  */
 template <class DVL>
+// cppcheck-suppress operatorEqVarError
 ElementProxy<DVL>& ElementProxy<DVL>::operator= (const ElementProxy& rhs)
 {
   if (*rhs.m_proxied != *m_proxied) {
+    // cppcheck-suppress assertWithSideEffect
     ATHCONTAINERS_ASSERT (! (container()->ownPolicy() == SG::OWN_ELEMENTS &&
                              rhs.container()->ownPolicy() == SG::OWN_ELEMENTS));
     container()->assignBaseElement (m_proxied, *rhs.m_proxied);
diff --git a/Control/AthContainers/test/supportsThinning_test.cxx b/Control/AthContainers/test/supportsThinning_test.cxx
index 858a5b2acd340a0300394b5b757cee4220161e21..1b39f0115eb4850b8b12907e17d0c2de256b1373 100644
--- a/Control/AthContainers/test/supportsThinning_test.cxx
+++ b/Control/AthContainers/test/supportsThinning_test.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 /**
  * @file AthContainers/test/supportsThinning_test.cxx
@@ -21,6 +21,7 @@ struct A {};
 struct B : public DataVector<int> {};
 struct B0 : public DataVector<int> { static bool constexpr supportsThinning = false; };
 struct C : public SG::AuxElement {};
+// cppcheck-suppress duplInheritedMember
 struct C0 : public SG::AuxElement { static bool constexpr supportsThinning = false; };
 struct D : public SG::AuxStoreInternal {};
 struct D0 : public SG::AuxStoreInternal { static bool constexpr supportsThinning = false; };
diff --git a/Control/AthenaBaseComps/src/AthCnvSvc.cxx b/Control/AthenaBaseComps/src/AthCnvSvc.cxx
index 25720dd7759e58fb95082a136e97972110d5f9ac..180c50d10bd67aac374e0bfed721ac6cd756edd5 100644
--- a/Control/AthenaBaseComps/src/AthCnvSvc.cxx
+++ b/Control/AthenaBaseComps/src/AthCnvSvc.cxx
@@ -1,7 +1,7 @@
 ///////////////////////// -*- C++ -*- /////////////////////////////
 
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // AthCnvSvc.cxx 
@@ -194,7 +194,7 @@ AthCnvSvc::setDataProvider(IDataProviderSvc* pDataSvc)
   m_dataSvc->addRef();
   Workers::iterator stop  = m_workers.end();
   Workers::iterator start = m_workers.begin();
-  for(Workers::iterator i=start; i != stop; i++ )    {
+  for(Workers::iterator i=start; i != stop; ++i )    {
     IConverter* cnv = i->second.converter();
     if ( 0 != cnv )   {
       if (cnv->setDataProvider(m_dataSvc).isFailure()) {
@@ -245,7 +245,7 @@ AthCnvSvc::setAddressCreator(IAddressCreator* creator)
   m_addressCreator = creator;
   Workers::iterator stop  = m_workers.end();
   Workers::iterator start = m_workers.begin();
-  for(Workers::iterator i=start; i != stop; i++ )    {
+  for(Workers::iterator i=start; i != stop; ++i )    {
     IConverter* cnv = i->second.converter();
     if ( 0 != cnv )   {
       if (cnv->setAddressCreator(m_addressCreator).isFailure()) {
diff --git a/Control/AthenaCommon/python/CFElements.py b/Control/AthenaCommon/python/CFElements.py
index df7e9e47a92ce2926fcee1756df14b28a6dfcc72..c7996cbdc326d846ad6266a79d7a955e39b5a306 100755
--- a/Control/AthenaCommon/python/CFElements.py
+++ b/Control/AthenaCommon/python/CFElements.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 from __future__ import print_function
 from AthenaConfiguration.ComponentFactory import CompFactory
 from AthenaCommon.Configurable import Configurable
@@ -313,16 +313,20 @@ class TestLegacyCF( unittest.TestCase, TestCF ):
         from AthenaCommon.Configurable import ConfigurablePyAlgorithm
         Configurable.configurableRun3Behavior=0
         top = parOR("top")
-        top += parOR("nest1")
-        nest2 = seqAND("nest2")
-        top += nest2
-        top += ConfigurablePyAlgorithm("SomeAlg0")
-        nest2 += parOR("deep_nest1")
-        nest2 += parOR("deep_nest2")
-
-        nest2 += ConfigurablePyAlgorithm("SomeAlg1")
-        nest2 += ConfigurablePyAlgorithm("SomeAlg2")
-        nest2 += ConfigurablePyAlgorithm("SomeAlg3")
+
+        # Skip initialization if it's already been done... otherwise, we'll
+        # get errors about duplicates.
+        if not top.getChildren():
+            top += parOR("nest1")
+            nest2 = seqAND("nest2")
+            top += nest2
+            top += ConfigurablePyAlgorithm("SomeAlg0")
+            nest2 += parOR("deep_nest1")
+            nest2 += parOR("deep_nest2")
+
+            nest2 += ConfigurablePyAlgorithm("SomeAlg1")
+            nest2 += ConfigurablePyAlgorithm("SomeAlg2")
+            nest2 += ConfigurablePyAlgorithm("SomeAlg3")
         self.top = top
 
 
diff --git a/Control/AthenaCommon/share/CFElementsTest.ref b/Control/AthenaCommon/share/CFElementsTest.ref
new file mode 100644
index 0000000000000000000000000000000000000000..0f9878b530f3b73cafb86cd4bb665a30e749ef00
--- /dev/null
+++ b/Control/AthenaCommon/share/CFElementsTest.ref
@@ -0,0 +1,17 @@
+test_findAlgorithms (AthenaCommon.CFElements.TestConf2CF) ... ok
+test_findDeep (AthenaCommon.CFElements.TestConf2CF) ... ok
+test_findMissing (AthenaCommon.CFElements.TestConf2CF) ... ok
+test_findRespectingScope (AthenaCommon.CFElements.TestConf2CF) ... ok
+test_findTop (AthenaCommon.CFElements.TestConf2CF) ... ok
+test_flatCollectors (AthenaCommon.CFElements.TestConf2CF) ... ok
+test_findAlgorithms (AthenaCommon.CFElements.TestLegacyCF) ... ok
+test_findDeep (AthenaCommon.CFElements.TestLegacyCF) ... ok
+test_findMissing (AthenaCommon.CFElements.TestLegacyCF) ... ok
+test_findRespectingScope (AthenaCommon.CFElements.TestLegacyCF) ... ok
+test_findTop (AthenaCommon.CFElements.TestLegacyCF) ... ok
+test_flatCollectors (AthenaCommon.CFElements.TestLegacyCF) ... ok
+
+----------------------------------------------------------------------
+Ran 12 tests in 0.002s
+
+OK
diff --git a/Control/AthenaConfiguration/python/AtlasSemantics.py b/Control/AthenaConfiguration/python/AtlasSemantics.py
index 083f5f913907df9b535934988b3d95cb5629ab80..6ae78fcf504112c2708c2281625926f1a7dfbe51 100644
--- a/Control/AthenaConfiguration/python/AtlasSemantics.py
+++ b/Control/AthenaConfiguration/python/AtlasSemantics.py
@@ -7,6 +7,15 @@ import re
 import collections
 import copy
 
+# collections.Sequence is deprecated as of python 3.3.
+# As of 3.9, need to get it from collections.abc.
+# But that doesn't exist in py2.
+try:
+    from collections import abc
+    Sequence = abc.Sequence
+except ImportError:
+    Sequence = collections.Sequence
+
 class AppendListSemantics(GaudiConfig2.semantics.SequenceSemantics):
     '''
     Extend the sequence-semantics with a merge-method that appends the lists
@@ -106,7 +115,7 @@ class PublicHandleArraySemantics(GaudiConfig2.semantics.PropertySemantics):
         super(PublicHandleArraySemantics, self).__init__(cpp_type,name)
         
     def store(self, value):
-        if not isinstance(value,collections.Sequence) and not isinstance(value,set):
+        if not isinstance(value,Sequence) and not isinstance(value,set):
             value=[value,]
 
         newValue=[]
@@ -172,7 +181,7 @@ class SubAlgoSemantics(GaudiConfig2.semantics.PropertySemantics):
         super(SubAlgoSemantics, self).__init__(cpp_type,name)
         
     def store(self,value):
-        if not isinstance(value,collections.Sequence):
+        if not isinstance(value,Sequence):
             value=[value,]
         
         for v in value:
diff --git a/Control/AthenaConfiguration/python/ComponentAccumulator.py b/Control/AthenaConfiguration/python/ComponentAccumulator.py
index 25cd773e566f4fdd7e3190f5748b2ba95ff6aeeb..6013dbf569fdf9a9f9cc09999f80620858658553 100644
--- a/Control/AthenaConfiguration/python/ComponentAccumulator.py
+++ b/Control/AthenaConfiguration/python/ComponentAccumulator.py
@@ -819,9 +819,14 @@ def __setProperties( destConfigurableInstance, sourceConf2Instance, indent="" ):
             setattr( destConfigurableInstance, pname, [conf2toConfigurable( tool, __indent( indent ) ) for tool in pvalue] )
             _log.debug( "{}Set the private tools array {} of {}".format( indent, pname,  destConfigurableInstance.name() ) )
         elif "PrivateToolHandle" in propType or "GaudiConfig2.Configurables" in propType or "ServiceHandle" in propType:
-            #_log.info( "{} {}  {}".format( indent, pname, dir(pvalue) ) )
             _log.debug( "{}Set the property {}  that is private tool {} ".format( indent,  pname, destConfigurableInstance.name() ) )
-            setattr( destConfigurableInstance, pname, conf2toConfigurable( pvalue, indent=__indent( indent ) ) )
+            try: #sometimes it is not printable
+                _log.debug("{}Tool: {}".format(indent, pvalue))
+            except Exception:
+                _log.debug("{}Could not print it".format(indent))
+                pass
+            if pvalue is not None:
+                setattr( destConfigurableInstance, pname, conf2toConfigurable( pvalue, indent=__indent( indent ) ) )
         else: # plain data
             if isinstance(pvalue,(GaudiConfig2.semantics._ListHelper,GaudiConfig2.semantics._DictHelper)):
                 pvalue=pvalue.data
@@ -899,7 +904,7 @@ def conf2toConfigurable( comp, indent="" ):
 
 
     def __areSettingsSame( existingConfigurableInstance, newConf2Instance, indent="" ):
-        _log.debug( "{}Checking if setting is the same {}".format( indent, compName(existingConfigurableInstance) ) )
+        _log.debug( "{}Checking if setting is the same {}".format( indent, existingConfigurableInstance.getFullName() ) )
         alreadySetProperties = dict([ (pname, pvalue) for pname,pvalue
                                       in six.iteritems(existingConfigurableInstance.getValuedProperties()) ])
         for pname, pvalue in six.iteritems( newConf2Instance._properties ): # six.iteritems(comp._properties):
@@ -914,15 +919,18 @@ def conf2toConfigurable( comp, indent="" ):
                 for oldC, newC in zip( alreadySetProperties[pname], pvalue):
                     __areSettingsSame( oldC, newC, __indent(indent))
             elif "PrivateToolHandle" in propType or "GaudiConfig2.Configurables" in propType or "ServiceHandle" in propType:
-                #__areSettingsSame( alreadySetProperties[pname], pvalue, __indent(indent))
-                _log.debug( "{} {}".format( indent, dir(pvalue) ) )
-                __areSettingsSame( getattr(existingConfigurableInstance, pname), pvalue, __indent(indent))
+                exisitngVal = getattr(existingConfigurableInstance, pname)
+                if isinstance( pvalue, str ):
+                    _log.warning("{}The handle {} of component {}.{} is just a string {}, skipping deeper checks, configuration may be incorrect".format(indent, propType, newConf2Instance.name, pname, pvalue))
+                else:
+                    _log.debug( "{}Some kind of handle  and, object type {} existing {}".format( indent, type(pvalue), type(exisitngVal) ) )
+                    __areSettingsSame( exisitngVal, pvalue, indent)
             else:
                 if isinstance(pvalue,(GaudiConfig2.semantics._ListHelper,GaudiConfig2.semantics._DictHelper)):
                     pvalue=pvalue.data
 
                 if alreadySetProperties[pname] != pvalue:
-                    _log.info("{}Merging property: {} for {}".format(__indent(indent), pname, newConf2Instance.getName() ))
+                    _log.info("{}Merging property: {} for {}".format(indent, pname, newConf2Instance.getName() ))
                     # create surrogate
                     clone = newConf2Instance.getInstance("Clone")
                     setattr(clone, pname, alreadySetProperties[pname])
@@ -932,15 +940,16 @@ def conf2toConfigurable( comp, indent="" ):
                     setattr(existingConfigurable, pname, updatedPropValue)
                     del clone
                     _log.info("{} invoked GaudiConf2 semantics to merge the {} and the {} to {} for property {} of {}".format(
-                        __indent(indent), alreadySetProperties[pname], pvalue, pname,  updatedPropValue, existingConfigurable.getName()))
+                        indent, alreadySetProperties[pname], pvalue, pname,  updatedPropValue, existingConfigurable.getFullName()))
 
     existingConfigurable = __alreadyConfigured( comp.name )
     if existingConfigurable: # if configurable exists we try to merge with it
+        _log.debug( "{}Pre-existing configurable {} was found, checking if has the same properties".format( indent, comp.getName() ) )
         __areSettingsSame( existingConfigurable, comp )
         _log.debug( "{}Pre-existing configurable was found to have the same properties".format( indent, comp.name ) )
         instance = existingConfigurable
     else: # create new configurable
-        _log.debug( "{}Creating component configurable {}".format( indent, comp.name ) )
+        _log.debug( "{}Creating component configurable {}".format( indent, comp.getFullJobOptName() ) )
         configurableClass = __findConfigurableClass( comp.getFullJobOptName().split( "/" )[0] )
         instance = configurableClass( comp.name )
         __setProperties( instance, comp, __indent( indent ) )
diff --git a/Control/AthenaExamples/AthAsgExUnittest/AthAsgExUnittest/MyPackageDict.h b/Control/AthenaExamples/AthAsgExUnittest/AthAsgExUnittest/MyPackageDict.h
deleted file mode 100644
index 8373e93bb0e1430ae3176bec1671f2cff09c8d52..0000000000000000000000000000000000000000
--- a/Control/AthenaExamples/AthAsgExUnittest/AthAsgExUnittest/MyPackageDict.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef ATHASGEXUNITTEST_MYPACKAGEDICT_H
-#define ATHASGEXUNITTEST_MYPACKAGEDICT_H
-
-#include "AthAsgExUnittest/MyPackageTool.h"
-
-#endif
diff --git a/Control/AthenaExamples/AthAsgExUnittest/AthAsgExUnittest/selection.xml b/Control/AthenaExamples/AthAsgExUnittest/AthAsgExUnittest/selection.xml
deleted file mode 100644
index 1afaa3919dd9f187ed35151851651ff393280ff0..0000000000000000000000000000000000000000
--- a/Control/AthenaExamples/AthAsgExUnittest/AthAsgExUnittest/selection.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<lcgdict>
-   <class name="MyPackageTool" />
-   <class name="IMyPackageTool" />
-</lcgdict>
diff --git a/Control/AthenaExamples/AthAsgExUnittest/CMakeLists.txt b/Control/AthenaExamples/AthAsgExUnittest/CMakeLists.txt
index 0a3ab24abf76c7dd7e745a7f4a2d17b2be162adb..2386195349647cb205a3ca7511773728f788b027 100644
--- a/Control/AthenaExamples/AthAsgExUnittest/CMakeLists.txt
+++ b/Control/AthenaExamples/AthAsgExUnittest/CMakeLists.txt
@@ -1,34 +1,18 @@
-
-#
-#  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-#
-
-################################################################################
-# Package: MyPackage
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( AthAsgExUnittest )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          GaudiKernel
-                          PRIVATE
-			  Control/AthenaBaseComps
-                          Control/AthAnalysisBaseComps
-                          Control/AthToolSupport/AsgTools
-                          Event/xAOD/xAODJet
-                          AtlasTest/GoogleTestTools )
-
 # Libraries in the package:
 atlas_add_library( AthAsgExUnittestLib
                    MyPackage/*.h src/*.cxx
                    Root/*.cxx
-                   PUBLIC_HEADERS AthAsgExUnittest
+                   NO_PUBLIC_HEADERS
                    LINK_LIBRARIES GaudiKernel AsgTools AthAnalysisBaseCompsLib )
+
 atlas_add_component( AthAsgExUnittest
                      src/components/*.cxx
-                     LINK_LIBRARIES GaudiKernel AsgTools AthAsgExUnittestLib )
+                     LINK_LIBRARIES AthAsgExUnittestLib )
 
 # Add tests:
 atlas_add_test( gt_AthAsgExUnittest
@@ -46,5 +30,3 @@ atlas_add_test( gt_MockxAODJet
 atlas_add_test( gt_xAODJet
   SOURCES test/gt_xAODJet.cxx
   LINK_LIBRARIES xAODJet GoogleTestTools )
-
-
diff --git a/Control/AthenaExamples/AthAsgExUnittest/Root/MyPackageTool.cxx b/Control/AthenaExamples/AthAsgExUnittest/Root/MyPackageTool.cxx
index f484eafff3e1d44768e7d9834de3c105fe3ac706..0350e0f3b4c1a07f529d15d28bff44465a64e9e9 100644
--- a/Control/AthenaExamples/AthAsgExUnittest/Root/MyPackageTool.cxx
+++ b/Control/AthenaExamples/AthAsgExUnittest/Root/MyPackageTool.cxx
@@ -1,10 +1,10 @@
 
 //
-//  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+//  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 //
 
 // MyPackage includes
-#include "AthAsgExUnittest/MyPackageTool.h"
+#include "../src/MyPackageTool.h"
 
 MyPackageTool::MyPackageTool( const std::string& name ) : asg::AsgTool( name ) {
   //example property declarations with default values
diff --git a/Control/AthenaExamples/AthAsgExUnittest/AthAsgExUnittest/IMyPackageTool.h b/Control/AthenaExamples/AthAsgExUnittest/src/IMyPackageTool.h
similarity index 100%
rename from Control/AthenaExamples/AthAsgExUnittest/AthAsgExUnittest/IMyPackageTool.h
rename to Control/AthenaExamples/AthAsgExUnittest/src/IMyPackageTool.h
diff --git a/Control/AthenaExamples/AthAsgExUnittest/src/MyPackageAlg.h b/Control/AthenaExamples/AthAsgExUnittest/src/MyPackageAlg.h
index 0c03b35d6fa2c8e4c2d7cb48b6acd585efe44105..e8a9607eb7ed94bdeb8db453068ffbe61325a885 100644
--- a/Control/AthenaExamples/AthAsgExUnittest/src/MyPackageAlg.h
+++ b/Control/AthenaExamples/AthAsgExUnittest/src/MyPackageAlg.h
@@ -12,7 +12,7 @@
 #include "AsgTools/AnaToolHandle.h" //use asg::AnaToolHandle instead of regular ToolHandles for full dual-use experience!
 #endif
 
-#include "AthAsgExUnittest/IMyPackageTool.h"
+#include "IMyPackageTool.h"
 
 
 class MyPackageAlg: public ::AthAnalysisAlgorithm { 
diff --git a/Control/AthenaExamples/AthAsgExUnittest/AthAsgExUnittest/MyPackageTool.h b/Control/AthenaExamples/AthAsgExUnittest/src/MyPackageTool.h
similarity index 86%
rename from Control/AthenaExamples/AthAsgExUnittest/AthAsgExUnittest/MyPackageTool.h
rename to Control/AthenaExamples/AthAsgExUnittest/src/MyPackageTool.h
index 9d902a658e3f389d11ae3984af10e8e7f6332080..ebc1bef9cbf18ea5b3947d48d504e7a4b1d22dc5 100644
--- a/Control/AthenaExamples/AthAsgExUnittest/AthAsgExUnittest/MyPackageTool.h
+++ b/Control/AthenaExamples/AthAsgExUnittest/src/MyPackageTool.h
@@ -1,12 +1,12 @@
 // -*- mode: c++ -*-
 //
-//  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+//  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 //
 #ifndef ATHASGEXUNITTEST_MYPACKAGETOOL_H
 #define ATHASGEXUNITTEST_MYPACKAGETOOL_H 1
 
 #include "AsgTools/AsgTool.h"
-#include "AthAsgExUnittest/IMyPackageTool.h"
+#include "IMyPackageTool.h"
 
 class MyPackageTool: public asg::AsgTool, public virtual IMyPackageTool { 
 public: 
diff --git a/Control/AthenaExamples/AthAsgExUnittest/src/components/AthAsgExUnittest_entries.cxx b/Control/AthenaExamples/AthAsgExUnittest/src/components/AthAsgExUnittest_entries.cxx
index 95117f80988fe24ecc7001dd81259b9f457897df..ef5eb1e88d28c2273a95c33b751286b122b17992 100644
--- a/Control/AthenaExamples/AthAsgExUnittest/src/components/AthAsgExUnittest_entries.cxx
+++ b/Control/AthenaExamples/AthAsgExUnittest/src/components/AthAsgExUnittest_entries.cxx
@@ -3,6 +3,6 @@
 DECLARE_COMPONENT( MyPackageAlg )
 
 
-#include "AthAsgExUnittest/MyPackageTool.h"
+#include "../MyPackageTool.h"
 DECLARE_COMPONENT( MyPackageTool )
 
diff --git a/Control/AthenaExamples/AthAsgExUnittest/test/gt_AthAsgExUnittest.cxx b/Control/AthenaExamples/AthAsgExUnittest/test/gt_AthAsgExUnittest.cxx
index 7f01f18764d2e6b945752fbbfbe700b978499784..d0de4e2dff099bef22ed6f8c9e7bd5cbdbb0392c 100644
--- a/Control/AthenaExamples/AthAsgExUnittest/test/gt_AthAsgExUnittest.cxx
+++ b/Control/AthenaExamples/AthAsgExUnittest/test/gt_AthAsgExUnittest.cxx
@@ -12,9 +12,9 @@
 #include "AsgTools/AnaToolHandle.h"
 #include "AthAnalysisBaseComps/AthAnalysisHelper.h"
 
-#include "../AthAsgExUnittest/IMyPackageTool.h"
+#include "../src/IMyPackageTool.h"
 
-#include "../AthAsgExUnittest/MyPackageTool.h"
+#include "../src/MyPackageTool.h"
 #include "../src/MyPackageAlg.h"
 
 #include <iostream>
diff --git a/Control/AthenaExamples/AthAsgExUnittest/test/gt_AthExUnittest.cxx b/Control/AthenaExamples/AthAsgExUnittest/test/gt_AthExUnittest.cxx
index 142156a288defae4d93b05ebf6107bd64c0213d8..37a3af4ee3f626abb9a2bce800b66586ca7750d0 100644
--- a/Control/AthenaExamples/AthAsgExUnittest/test/gt_AthExUnittest.cxx
+++ b/Control/AthenaExamples/AthAsgExUnittest/test/gt_AthExUnittest.cxx
@@ -12,7 +12,7 @@
 #include "AthenaBaseComps/AthAlgorithm.h"
 #include "AthenaBaseComps/AthService.h"
 
-#include "../AthAsgExUnittest/IMyPackageTool.h"
+#include "../src/IMyPackageTool.h"
 
 #include <string>
 #include <iostream>
diff --git a/Control/AthenaExamples/AthExFortranAlgorithm/AthExFortranAlgorithm/config.h.in b/Control/AthenaExamples/AthExFortranAlgorithm/AthExFortranAlgorithm/config.h.in
deleted file mode 100755
index 61025bcef7b500b4018a9c3b79cc0ab745248ffa..0000000000000000000000000000000000000000
--- a/Control/AthenaExamples/AthExFortranAlgorithm/AthExFortranAlgorithm/config.h.in
+++ /dev/null
@@ -1 +0,0 @@
-/* config.h.in.  Generated automatically from configure.in by autoheader.  */
diff --git a/Control/AthenaExamples/AthExFortranAlgorithm/CMakeLists.txt b/Control/AthenaExamples/AthExFortranAlgorithm/CMakeLists.txt
index 0f53e07a7a873724863f4831314fef9b218eabee..a613c492db04dadafb5812919b74d22219beccb6 100644
--- a/Control/AthenaExamples/AthExFortranAlgorithm/CMakeLists.txt
+++ b/Control/AthenaExamples/AthExFortranAlgorithm/CMakeLists.txt
@@ -1,16 +1,8 @@
-################################################################################
-# Package: AthExFortranAlgorithm
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( AthExFortranAlgorithm )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          Control/AthenaBaseComps
-                          PRIVATE
-                          GaudiKernel )
-
 # Component(s) in the package:
 atlas_add_component( AthExFortranAlgorithm
                      src/*.cxx
@@ -19,8 +11,6 @@ atlas_add_component( AthExFortranAlgorithm
                      LINK_LIBRARIES AthenaBaseComps GaudiKernel )
 
 # Install files from the package:
-atlas_install_headers( AthExFortranAlgorithm )
-atlas_install_joboptions( share/FortranAlgorithmOptions.txt share/FortranAlgorithmOptions.py )
+atlas_install_joboptions( share/FortranAlgorithmOptions.py )
 atlas_install_runtime( share/FortranAlgorithmInput.data )
 atlas_install_scripts( share/preFortAlgEx.sh )
-
diff --git a/Control/AthenaExamples/AthExFortranAlgorithm/share/FortranAlgorithmOptions.txt b/Control/AthenaExamples/AthExFortranAlgorithm/share/FortranAlgorithmOptions.txt
deleted file mode 100755
index 6d81dd2fa1564681f31bb543fa3b64cde080cd06..0000000000000000000000000000000000000000
--- a/Control/AthenaExamples/AthExFortranAlgorithm/share/FortranAlgorithmOptions.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-//##############################################################
-//
-// Job options file
-//
-//==============================================================
-
-//no EventSelector
-ApplicationMgr.DLLs   += { "AthenaServices" };
-ApplicationMgr.EventLoop = "AthenaEventLoopMgr";
-//--------------------------------------------------------------
-// StoreGate services configuration
-//--------------------------------------------------------------
-#include "StoreGate/StoreGate_jobOptions.txt"
-
-ApplicationMgr.ExtSvc += { "EvtPersistencySvc/EventPersistencySvc",
-			   "HistogramSvc/HistogramDataSvc"
-			 };	
-//--------------------------------------------------------------
-// Private Application Configuration options
-//--------------------------------------------------------------
-
-//load relevant libraries
-ApplicationMgr.DLLs += { "AthExFortranAlgorithm" };
-
-//top algorithms to be run
-ApplicationMgr.TopAlg = { "FortranAlgorithm" };
-
-//--------------------------------------------------------------
-// Set output level threshold (2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL )
-//--------------------------------------------------------------
-
-MessageSvc.OutputLevel      = 2;
-MessageSvc.useColors        = true;
-
-//--------------------------------------------------------------
-// Event related parameters
-//--------------------------------------------------------------
-
-// dummy event loop
-ApplicationMgr.EvtSel = "NONE";
-// Number of events to be processed (default is 10)
-ApplicationMgr.EvtMax = 1;
-
-//--------------------------------------------------------------
-// Algorithms Private Options
-//--------------------------------------------------------------
-
-// For the FortranAlgorithm algorithm
-FortranAlgorithm.LUN = 42;
-FortranAlgorithm.fileName = "FortranAlgorithmInput.data";
-
-//==============================================================
-//
-// End of job options file
-//
-//##############################################################
-
diff --git a/Control/AthenaExamples/AthExFortranAlgorithm/src/FortranAlgorithm.cxx b/Control/AthenaExamples/AthExFortranAlgorithm/src/FortranAlgorithm.cxx
index 70fe0e0cd6db2630c99685f301a0833586ff0754..85584df4eceb470d162a6bfae31b35e43f8474e2 100755
--- a/Control/AthenaExamples/AthExFortranAlgorithm/src/FortranAlgorithm.cxx
+++ b/Control/AthenaExamples/AthExFortranAlgorithm/src/FortranAlgorithm.cxx
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-#include "AthExFortranAlgorithm/FortranAlgorithm.h"
+#include "FortranAlgorithm.h"
 
 extern "C" {
   void initialize_(const int& lun, const char*, int);
diff --git a/Control/AthenaExamples/AthExFortranAlgorithm/AthExFortranAlgorithm/FortranAlgorithm.h b/Control/AthenaExamples/AthExFortranAlgorithm/src/FortranAlgorithm.h
similarity index 100%
rename from Control/AthenaExamples/AthExFortranAlgorithm/AthExFortranAlgorithm/FortranAlgorithm.h
rename to Control/AthenaExamples/AthExFortranAlgorithm/src/FortranAlgorithm.h
diff --git a/Control/AthenaExamples/AthExFortranAlgorithm/src/components/FortranAlgorithm_entries.cxx b/Control/AthenaExamples/AthExFortranAlgorithm/src/components/FortranAlgorithm_entries.cxx
index 79f2167acf60da3c21029899bb356b9d74708817..46a80de068fc5f6752d50f2fef1804894efc9c0a 100644
--- a/Control/AthenaExamples/AthExFortranAlgorithm/src/components/FortranAlgorithm_entries.cxx
+++ b/Control/AthenaExamples/AthExFortranAlgorithm/src/components/FortranAlgorithm_entries.cxx
@@ -1,4 +1,4 @@
-#include "AthExFortranAlgorithm/FortranAlgorithm.h"
+#include "../FortranAlgorithm.h"
 
 DECLARE_COMPONENT( FortranAlgorithm )
 
diff --git a/Control/AthenaExamples/AthExHelloWorld/CMakeLists.txt b/Control/AthenaExamples/AthExHelloWorld/CMakeLists.txt
index dbd0e1826a7467a1f7637dd7d73057778f41d1dd..e5663de19125a4e3e9e63d2542d94add98856fbe 100644
--- a/Control/AthenaExamples/AthExHelloWorld/CMakeLists.txt
+++ b/Control/AthenaExamples/AthExHelloWorld/CMakeLists.txt
@@ -1,17 +1,8 @@
-################################################################################
-# Package: AthExHelloWorld
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( AthExHelloWorld )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          GaudiKernel
-                          PRIVATE
-                          Control/AthenaBaseComps
-			                    Control/AthenaConfiguration )
-
 # Component(s) in the package:
 atlas_add_component( AthExHelloWorld
                      src/*.cxx
@@ -19,25 +10,25 @@ atlas_add_component( AthExHelloWorld
                      LINK_LIBRARIES GaudiKernel AthenaBaseComps )
 
 # Install files from the package:
-atlas_install_headers( AthExHelloWorld )
 atlas_install_joboptions( share/*.py )
 atlas_install_python_modules( python/HelloWorldConfig.py 
                               POST_BUILD_CMD ${ATLAS_FLAKE8} )
 
+# Test(s) in the package:
 atlas_add_test( AthExHelloWorld
-    ENVIRONMENT THREADS=0
-		SCRIPT test/test_AthExHelloWorld.sh
-		)
+   ENVIRONMENT THREADS=0
+   SCRIPT test/test_AthExHelloWorld.sh )
 
 atlas_add_test( AthExHelloWorldMT_1
-    ENVIRONMENT THREADS=1
-		SCRIPT test/test_AthExHelloWorld.sh
-		)
+   ENVIRONMENT THREADS=1
+   SCRIPT test/test_AthExHelloWorld.sh )
 
 atlas_add_test( AthExHelloWorldMT_2
-    ENVIRONMENT THREADS=2
-		SCRIPT test/test_AthExHelloWorld.sh
-    LOG_IGNORE_PATTERN "AthenaHiveEventLoopMgr.* processing event|^HelloWorld .*(INFO|WARNING A WARNING|ERROR An ERROR|FATAL A FATAL)|my message to the world" #processing order can change
-		)
-
-atlas_add_test( AthExHelloWorld_CfgTest    SCRIPT python -m AthExHelloWorld.HelloWorldConfig    POST_EXEC_SCRIPT nopost.sh )
+   ENVIRONMENT THREADS=2
+   SCRIPT test/test_AthExHelloWorld.sh
+   LOG_IGNORE_PATTERN "AthenaHiveEventLoopMgr.* processing event|^HelloWorld .*(INFO|WARNING A WARNING|ERROR An ERROR|FATAL A FATAL)|my message to the world" #processing order can change
+   )
+
+atlas_add_test( AthExHelloWorld_CfgTest
+   SCRIPT python -m AthExHelloWorld.HelloWorldConfig
+   POST_EXEC_SCRIPT nopost.sh )
diff --git a/Control/AthenaExamples/AthExHistNtup/CMakeLists.txt b/Control/AthenaExamples/AthExHistNtup/CMakeLists.txt
index a36347ca4948964739b93b01ca5a695aa428abad..daf3ff1524b4d213c463437d953a1c9de5626adb 100644
--- a/Control/AthenaExamples/AthExHistNtup/CMakeLists.txt
+++ b/Control/AthenaExamples/AthExHistNtup/CMakeLists.txt
@@ -1,16 +1,8 @@
-################################################################################
-# Package: AthExHistNtup
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( AthExHistNtup )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PRIVATE
-                          Control/AthenaBaseComps
-                          Event/xAOD/xAODEventInfo
-                          GaudiKernel )
-
 # External dependencies:
 find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
 
@@ -22,5 +14,4 @@ atlas_add_component( AthExHistNtup
                      LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaBaseComps xAODEventInfo GaudiKernel )
 
 # Install files from the package:
-atlas_install_joboptions( share/HistNtupOptions.txt share/HistNtupOptions.py )
-
+atlas_install_joboptions( share/HistNtupOptions.py )
diff --git a/Control/AthenaExamples/AthExHistNtup/share/HistNtupOptions.txt b/Control/AthenaExamples/AthExHistNtup/share/HistNtupOptions.txt
deleted file mode 100755
index b65951289491d3069760b0ee4b14264cc67d66e2..0000000000000000000000000000000000000000
--- a/Control/AthenaExamples/AthExHistNtup/share/HistNtupOptions.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-//##############################################################
-//
-// Job options file
-//
-//==============================================================
-
-#include "AthenaCommon/Atlas_ZebraTDR.UnixStandardJob.txt"
-
-// For  ddcnvsvc
-#include "IdDictDetDescrCnv/IdDictDetDescrCnv_joboptions.txt"
-#include"InDetMgrDetDescrCnv/InDetMgrDetDescrCnv_joboptions.txt"
-#include "LArDetMgrDetDescrCnv/LArDetMgrDetDescrCnv_joboptions.txt"
-//FIXME #include "TileDetMgrDetDescrCnv/TileDetMgrDetDescrCnv_joboptions.txt"
-#include "MuonDetMgrDetDescrCnv/MuonDetMgrDetDescrCnv_joboptions.txt"
-
-// Turn on the reading of the dictionary
-DetDescrCnvSvc.DecodeIdDict = true;
-
-//--------------------------------------------------------------
-// Private Application Configuration options
-//--------------------------------------------------------------
-//load relevant libraries
-ApplicationMgr.DLLs += { "AthExHistNtup" };      
-
-// Select the appropriate shared library
-ApplicationMgr.DLLs += { "HbookCnv" };
-////ApplicationMgr.DLLs += { "RootHistCnv" };
-
-// Select HBOOK or ROOT persistency (HBOOK is default)
-ApplicationMgr.HistogramPersistency = "HBOOK";
-
-ApplicationMgr.TopAlg = { "Hist" };
-ApplicationMgr.TopAlg += { "Ntup" };
-
-//--------------------------------------------------------------
-// For Zebra input: identify your input runs.
-//--------------------------------------------------------------
-
-// Provide a first/last range or a list
-//EventSelector.runs = {1, 100000};
-EventSelector.firstRun = 1;
-EventSelector.lastRun  = 100000;
-//--------------------------------------------------------------
-// Set output level threshold (2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL )
-//--------------------------------------------------------------
-
-Hist.OutputLevel = 2;
-Ntup.OutputLevel = 2;
-MessageSvc.useColors   = true;
-
-//--------------------------------------------------------------
-// Histogram output file 
-//--------------------------------------------------------------
-
-// Specify the appropriate output file type
-HistogramPersistencySvc.OutputFile  = "histo.hbook";
-//HistogramPersistencySvc.OutputFile  = "histo.rt";
-
-//--------------------------------------------------------------
-// Ntuples
-//--------------------------------------------------------------
-
-NTupleSvc.Output     = { "FILE1 DATAFILE='tuple1.hbook' OPT='NEW'" };
-
-//--------------------------------------------------------------
-// Event related parameters
-//--------------------------------------------------------------
-
-// Number of events to be processed (default is 10)
-ApplicationMgr.EvtMax = 10;
-
-//--------------------------------------------------------------
-// Algorithms Private Options
-//--------------------------------------------------------------
-
-//==============================================================
-//
-// End of job options file
-//
-//##############################################################
-
diff --git a/Control/AthenaExamples/AthExHive/CMakeLists.txt b/Control/AthenaExamples/AthExHive/CMakeLists.txt
index 36e4966543212d6b39add94051ee20de2b3c619e..07fd1441b11401c304a0b0fa0b8f18fec2c5eb04 100644
--- a/Control/AthenaExamples/AthExHive/CMakeLists.txt
+++ b/Control/AthenaExamples/AthExHive/CMakeLists.txt
@@ -1,38 +1,30 @@
-################################################################################
-# Package: AthExHive
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( AthExHive )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          Control/AthenaKernel
-                          PRIVATE
-                          Control/AthenaBaseComps
-                          Control/CxxUtils
-                          Control/StoreGate
-                          Event/xAOD/xAODEventInfo
-                          GaudiKernel )
+# External dependencies:
+find_package( Boost )
 
+# Component(s) in the package:
 atlas_add_library( AthExHiveLib
                    AthExHive/*.h
                    INTERFACE
                    PUBLIC_HEADERS AthExHive
                    LINK_LIBRARIES AthenaKernel GaudiKernel)
 
-# Component(s) in the package:
 atlas_add_component( AthExHive
                      src/*.cxx
                      src/condEx/*.cxx
                      src/loopTest/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaKernel AthenaBaseComps xAODEventInfo AthExHiveLib )
+                     LINK_LIBRARIES AthenaKernel AthenaBaseComps StoreGateLib xAODEventInfo AthExHiveLib )
 
 # Install files from the package:
 atlas_install_joboptions( share/*.py )
 atlas_install_runtime( share/condDb.txt )
 
+# Tests in the package:
 atlas_add_test ( AthExHive_test
    SCRIPT test/AthExHive_test.sh
    PROPERTIES TIMEOUT 300
diff --git a/Control/AthenaExamples/AthExJobOptions/CMakeLists.txt b/Control/AthenaExamples/AthExJobOptions/CMakeLists.txt
index c4c11a9058091c4caca280e68527f66478e9b5c0..18a1048dae4de9ed9d6f05a25852f57409b34b98 100644
--- a/Control/AthenaExamples/AthExJobOptions/CMakeLists.txt
+++ b/Control/AthenaExamples/AthExJobOptions/CMakeLists.txt
@@ -1,20 +1,8 @@
-################################################################################
-# Package: AthExJobOptions
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( AthExJobOptions )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          Control/AthenaBaseComps
-                          Control/AthenaKernel
-                          GaudiKernel
-                          PRIVATE
-                          AtlasTest/TestTools
-                          Control/StoreGate
-                          Event/EventInfo )
-
 # Component(s) in the package:
 atlas_add_component( AthExJobOptions
                      src/*.cxx
@@ -22,9 +10,7 @@ atlas_add_component( AthExJobOptions
                      LINK_LIBRARIES AthenaBaseComps AthenaKernel GaudiKernel StoreGateLib SGtests EventInfo )
 
 # Install files from the package:
-atlas_install_headers( AthExJobOptions )
-atlas_install_python_modules( python/*.py 
-                              POST_BUILD_CMD ${ATLAS_FLAKE8} )
+atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
 atlas_install_joboptions( share/*.py )
 
 # Tests in this package:
diff --git a/Control/AthenaExamples/AthExMonitored/CMakeLists.txt b/Control/AthenaExamples/AthExMonitored/CMakeLists.txt
index 9e81614b6749b54261dbe0c4eac6ce6e043d2f70..fdb8f84aee74b7d98573fe47c4af132a59614bb3 100644
--- a/Control/AthenaExamples/AthExMonitored/CMakeLists.txt
+++ b/Control/AthenaExamples/AthExMonitored/CMakeLists.txt
@@ -1,17 +1,8 @@
-################################################################################
-# Package: AthExMonitored
-################################################################################
+# Copyright (C) 20022020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( AthExMonitored )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          GaudiKernel
-                          PRIVATE
-                          Control/AthenaBaseComps
-                          Control/AthenaMonitoringKernel )
-
 # Component(s) in the package:
 atlas_add_component( AthExMonitored
                      src/*.cxx
@@ -20,4 +11,4 @@ atlas_add_component( AthExMonitored
 
 # Install files from the package:
 atlas_install_joboptions( share/*.py )
-atlas_install_python_modules( python/*.py )
+atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
diff --git a/Control/AthenaExamples/AthExRunExamples/CMakeLists.txt b/Control/AthenaExamples/AthExRunExamples/CMakeLists.txt
deleted file mode 100644
index ea0cc987cdf33315acb06715d4419cd905b837a8..0000000000000000000000000000000000000000
--- a/Control/AthenaExamples/AthExRunExamples/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-################################################################################
-# Package: AthExRunExamples
-################################################################################
-
-# Declare the package name:
-atlas_subdir( AthExRunExamples )
-
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          Control/AthenaExamples/AthExFortranAlgorithm
-                          Control/AthenaExamples/AthExHelloWorld
-                          Control/AthenaExamples/AthExHistNtup
-                          Control/AthenaExamples/AthExStoreGateExample
-                          Control/AthenaExamples/ToyConversion
-                          Control/MinimalRunTime )
-
diff --git a/Control/AthenaExamples/AthExRunHelloWorld/CMakeLists.txt b/Control/AthenaExamples/AthExRunHelloWorld/CMakeLists.txt
deleted file mode 100644
index 912845c46ffb452d9ff82206af5af8c4ebf5547a..0000000000000000000000000000000000000000
--- a/Control/AthenaExamples/AthExRunHelloWorld/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-################################################################################
-# Package: AthExRunHelloWorld
-################################################################################
-
-# Declare the package name:
-atlas_subdir( AthExRunHelloWorld )
-
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          Control/AthenaExamples/AthExHelloWorld
-                          Control/MinimalRunTime )
-
diff --git a/Control/AthenaExamples/AthExStoreGateExample/CMakeLists.txt b/Control/AthenaExamples/AthExStoreGateExample/CMakeLists.txt
index 392daf9e3bb4acc4dcfcb0fd6b31babb63494bcd..9cdec175534b6bd79c46b31366e1a9a2066fda2b 100644
--- a/Control/AthenaExamples/AthExStoreGateExample/CMakeLists.txt
+++ b/Control/AthenaExamples/AthExStoreGateExample/CMakeLists.txt
@@ -1,63 +1,35 @@
-################################################################################
-# Package: AthExStoreGateExample
-################################################################################
+# Copyright (C) 20022020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( AthExStoreGateExample )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          Control/AthenaKernel
-                          Control/SGTools
-                          PRIVATE
-                          AtlasTest/TestTools
-                          Control/AthContainers
-                          Control/AthLinks
-                          Control/AthenaBaseComps
-                          Control/CxxUtils
-                          Control/PileUpTools
-                          Control/StoreGate
-                          Event/EventInfo
-                          Event/xAOD/xAODEventInfo
-                          GaudiKernel )
-
-# External dependencies:
-find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
-
 # Component(s) in the package:
 atlas_add_library( SGTutorialLib
                    Tutorial/LinkObj.cxx
                    Tutorial/SGRead.cxx
                    Tutorial/SGWrite.cxx
                    PUBLIC_HEADERS AthExStoreGateExample
-                   PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                   LINK_LIBRARIES AthenaKernel SGTools PileUpToolsLib StoreGateLib SGtests
-                   PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} TestTools AthContainers AthLinks AthenaBaseComps CxxUtils EventInfo xAODEventInfo GaudiKernel )
+                   LINK_LIBRARIES AthenaBaseComps AthenaKernel GaudiKernel StoreGateLib
+                   PRIVATE_LINK_LIBRARIES AthLinks  )
 
-atlas_add_library( SGTutorial
-                   Tutorial/SGTutorial_entries.cxx
-                   PUBLIC_HEADERS AthExStoreGateExample
-                   PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                   LINK_LIBRARIES AthenaKernel SGTools PileUpToolsLib StoreGateLib SGtests SGTutorialLib
-                   PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} TestTools AthContainers AthLinks AthenaBaseComps CxxUtils EventInfo xAODEventInfo GaudiKernel )
+atlas_add_component( SGTutorial
+                     Tutorial/SGTutorial_entries.cxx
+                     LINK_LIBRARIES SGTutorialLib )
 
 atlas_add_component( AthExStoreGateExample
                      src/*.cxx
                      src/components/*.cxx
-                     INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                     LINK_LIBRARIES SGTutorialLib )
+                     LINK_LIBRARIES AthContainers AthLinks AthenaBaseComps EventInfo PileUpToolsLib SGTools SGTutorialLib TestTools )
 
 atlas_add_component( AthExDFlow
                      src_dflow/*.cxx
                      src_dflow/components/*.cxx
-                     INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                     LINK_LIBRARIES SGTutorialLib )
+                     LINK_LIBRARIES AthenaBaseComps GaudiKernel SGTools StoreGateLib xAODEventInfo )
 
 atlas_add_dictionary( AthExStoreGateExampleDict
                       AthExStoreGateExample/AthExStoreGateExampleDict.h
                       AthExStoreGateExample/selection.xml
-                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                      LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaKernel SGTools TestTools AthContainers AthLinks AthenaBaseComps CxxUtils PileUpToolsLib StoreGateLib SGtests EventInfo xAODEventInfo GaudiKernel SGTutorialLib SGTutorial )
+                      LINK_LIBRARIES SGTutorialLib )
 
 # Install files from the package:
 atlas_install_joboptions( share/StoreGateExample_Gen_jobOptions.txt share/StoreGateExample_Gen_jobOptions.py share/StoreGateExample_Del_jobOptions.py share/StoreGateExample_Reentrant_jobOptions.py share/dflow_jobo.py share/StoreGateHiveExample.py share/HandleTest_jobOptions.py )
diff --git a/Control/AthenaExamples/AthExThinning/CMakeLists.txt b/Control/AthenaExamples/AthExThinning/CMakeLists.txt
index d9772fad11e3e81853506f673268f051a46fccf2..23b8c785e64109549caeed3b350b99a14a04949a 100644
--- a/Control/AthenaExamples/AthExThinning/CMakeLists.txt
+++ b/Control/AthenaExamples/AthExThinning/CMakeLists.txt
@@ -1,29 +1,8 @@
-################################################################################
-# Package: AthExThinning
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( AthExThinning )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          Control/AthContainers
-                          Control/AthLinks
-                          Control/AthenaBaseComps
-                          Control/AthenaKernel
-                          Control/AthenaPython
-                          Control/AthenaServices
-                          Control/DataModelAthenaPool
-                          Database/AthenaPOOL/AthenaPoolUtilities
-                          GaudiKernel
-                          PRIVATE
-                          Control/StoreGate
-                          Database/AthenaPOOL/AthenaPoolCnvSvc )
-
-# External dependencies:
-find_package( CLHEP )
-find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
-
 # Component(s) in the package:
 atlas_add_library( AthExThinningEvent
                    src_lib/AthExIParticle.cxx
@@ -38,31 +17,25 @@ atlas_add_library( AthExThinningEvent
                    src_lib/AthExParticles_p1.cxx
                    src_lib/AthExFatObject_p1.cxx
                    PUBLIC_HEADERS AthExThinning
-                   PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
-                   PRIVATE_DEFINITIONS ${CLHEP_DEFINITIONS}
-                   LINK_LIBRARIES AthContainers AthLinks AthenaBaseComps AthenaKernel AthenaPoolUtilities GaudiKernel DataModelAthenaPoolLib StoreGateLib SGtests AthenaPoolCnvSvcLib
-                   PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} )
+                   LINK_LIBRARIES AthContainers AthLinks AthenaBaseComps AthenaKernel DataModelAthenaPoolLib GaudiKernel StoreGateLib )
 
 atlas_add_component( AthExThinningAlgs
                      src_lib/CreateData.cxx
                      src_lib/WriteThinnedData.cxx
                      src_lib/ReadThinnedData.cxx
                      src_lib/components/*.cxx
-                     INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthContainers AthLinks AthenaBaseComps AthenaKernel DataModelAthenaPoolLib AthenaPoolUtilities GaudiKernel StoreGateLib SGtests AthenaPoolCnvSvcLib AthExThinningEvent )
+                     LINK_LIBRARIES AthExThinningEvent )
 
 atlas_add_poolcnv_library( AthExThinningPoolCnv
                            src/*.cxx
                            FILES AthExThinning/AthExParticles.h AthExThinning/AthExIParticles.h AthExThinning/AthExDecay.h AthExThinning/AthExElephantino.h AthExThinning/AthExFatObject.h
-                           INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
-                           LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthContainers AthLinks AthenaBaseComps AthenaKernel DataModelAthenaPoolLib AthenaPoolUtilities GaudiKernel StoreGateLib SGtests AthenaPoolCnvSvcLib AthExThinningEvent )
+                           LINK_LIBRARIES AthExThinningEvent AthenaPoolCnvSvcLib )
 
 atlas_add_dictionary( AthExThinningEventDict
                       AthExThinning/AthExThinningEventDict.h
                       AthExThinning/selection.xml
-                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
-                      LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthContainers AthLinks AthenaBaseComps AthenaKernel DataModelAthenaPoolLib AthenaPoolUtilities GaudiKernel StoreGateLib SGtests AthenaPoolCnvSvcLib AthExThinningEvent
-                      ELEMENT_LINKS  AthExParticles AthExIParticles )
+                      LINK_LIBRARIES AthExThinningEvent
+                      ELEMENT_LINKS AthExParticles AthExIParticles )
 
 # Install files from the package:
 atlas_install_python_modules( python/*.py
diff --git a/Control/AthenaExamples/AthExThinning/src_lib/CreateData.cxx b/Control/AthenaExamples/AthExThinning/src_lib/CreateData.cxx
index ca46b7f5cb5b50f0c04ed123e443382b4abef7f7..dc888c9f957b9b7ff92ad561959ac7b3be36048a 100644
--- a/Control/AthenaExamples/AthExThinning/src_lib/CreateData.cxx
+++ b/Control/AthenaExamples/AthExThinning/src_lib/CreateData.cxx
@@ -1,7 +1,7 @@
 ///////////////////////// -*- C++ -*- /////////////////////////////
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // CreateData.cxx 
@@ -14,9 +14,7 @@
 
 // FrameWork includes
 #include "GaudiKernel/Property.h"
-
-// CLHEP
-#include "CLHEP/Units/SystemOfUnits.h"
+#include "GaudiKernel/SystemOfUnits.h"
 
 // StoreGate
 #include "StoreGate/StoreGateSvc.h"
@@ -133,10 +131,10 @@ StatusCode CreateData::makeData( const std::string& test )
   }
 
   for ( unsigned int i = 0; i != m_nbrParticles.value(); ++i ) {
-    AthExParticle * p = new AthExParticle( (i+1) * 10. * CLHEP::GeV,
-					   (i+1) * 10. * CLHEP::GeV,
-					   (i+1) * 10. * CLHEP::GeV,
-					   (i+2) * 10. * CLHEP::GeV );
+    AthExParticle * p = new AthExParticle( (i+1) * 10. * Gaudi::Units::GeV,
+					   (i+1) * 10. * Gaudi::Units::GeV,
+					   (i+1) * 10. * Gaudi::Units::GeV,
+					   (i+2) * 10. * Gaudi::Units::GeV );
     particles->push_back(p);
   }
 
@@ -174,7 +172,7 @@ StatusCode CreateData::makeData( const std::string& test )
 
   dcy->setDecay( p1, p2, l1, l2 );
 
-  const double igev = 1. / CLHEP::GeV;
+  const double igev = 1. / Gaudi::Units::GeV;
   ATH_MSG_INFO
     ("Created a Decay from :" << endmsg
      << " p1: px= " << dcy->p1()->px() * igev << endmsg
diff --git a/Control/AthenaExamples/AthExThinning/src_lib/ReadThinnedData.cxx b/Control/AthenaExamples/AthExThinning/src_lib/ReadThinnedData.cxx
index 2910d8f7045dcacfb3574136ffbce966961e9630..041cd35a1593b3ae4177cc37d3df23cbcc711736 100644
--- a/Control/AthenaExamples/AthExThinning/src_lib/ReadThinnedData.cxx
+++ b/Control/AthenaExamples/AthExThinning/src_lib/ReadThinnedData.cxx
@@ -1,7 +1,7 @@
 ///////////////////////// -*- C++ -*- /////////////////////////////
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // ReadThinnedData.cxx 
@@ -15,13 +15,11 @@
 // FrameWork includes
 #include "GaudiKernel/MsgStream.h"
 #include "GaudiKernel/Property.h"
+#include "GaudiKernel/SystemOfUnits.h"
 
 // StoreGate
 #include "StoreGate/StoreGateSvc.h"
 
-// CLHEP includes
-#include "CLHEP/Units/SystemOfUnits.h"
-
 // AthExThinning includes
 #include "AthExThinning/AthExParticles.h"
 #include "AthExThinning/AthExDecay.h"
@@ -150,7 +148,7 @@ StatusCode ReadThinnedData::checkTest( const std::string& testName )
     return StatusCode::RECOVERABLE;
   }
 
-  const double igev = 1. / CLHEP::GeV;
+  const double igev = 1. / Gaudi::Units::GeV;
   ATH_MSG_DEBUG 
     ("IN  particles: " <<  particles->size() << endmsg
      << "IN iparticles: " << iparticles->size() << endmsg
diff --git a/Control/AthenaExamples/AthExThinning/src_lib/WriteThinnedData.cxx b/Control/AthenaExamples/AthExThinning/src_lib/WriteThinnedData.cxx
index 4b87c15154e622c3808e9bff760a040f8f084606..fd310189da9dd485893c179befbbeb500eeced74 100644
--- a/Control/AthenaExamples/AthExThinning/src_lib/WriteThinnedData.cxx
+++ b/Control/AthenaExamples/AthExThinning/src_lib/WriteThinnedData.cxx
@@ -1,7 +1,7 @@
 ///////////////////////// -*- C++ -*- /////////////////////////////
 
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // WriteThinnedData.cxx 
@@ -16,9 +16,7 @@
 
 // FrameWork includes
 #include "GaudiKernel/Property.h"
-
-// CLHEP
-#include "CLHEP/Units/SystemOfUnits.h"
+#include "GaudiKernel/SystemOfUnits.h"
 
 // StoreGate
 #include "StoreGate/StoreGateSvc.h"
@@ -160,7 +158,7 @@ StatusCode WriteThinnedData::test( const EventContext& ctx,
   // fetch Elephantino
   SG::ReadHandle<AthExElephantino> elephantino (m_elephantinoKeys[testNum], ctx);
 
-  const double igev = 1. / CLHEP::GeV;
+  const double igev = 1. / Gaudi::Units::GeV;
   ATH_MSG_DEBUG("IN particles: " << particles->size() << endmsg
 		<< "IN decay: " << endmsg
 		<< " p1: px= " << decay->p1()->px() * igev << endmsg
@@ -224,7 +222,7 @@ StatusCode WriteThinnedData::doThinningTest1( const EventContext& ctx,
   SG::ThinningHandle<AthExParticles> particles (particlesKey, ctx);
   std::vector<bool> filter = m_filter.value();
   
-  const double igev = 1. / CLHEP::GeV;
+  const double igev = 1. / Gaudi::Units::GeV;
   msg(MSG::INFO) << "Particles | filter :" << endmsg;
   for ( unsigned int i = 0; i != particles->size(); ++i ) {
     const std::string kr = filter[i] ? "keep" : "remove";
@@ -303,7 +301,7 @@ StatusCode WriteThinnedData::doThinningTest2( const EventContext& ctx,
   SG::ThinningHandle<AthExParticles> particles (particlesKey, ctx);
   std::vector<bool> filter = m_filter.value();
 
-  const double igev = 1. / CLHEP::GeV;
+  const double igev = 1. / Gaudi::Units::GeV;
   msg(MSG::INFO) << "Particles | filter :" << endmsg;
   for ( unsigned int i = 0; i != particles->size(); ++i ) {
     const std::string kr = filter[i] ? "keep" : "remove";
@@ -383,7 +381,7 @@ WriteThinnedData::doThinningTest3( const EventContext& ctx,
   SG::ThinningHandle<AthExIParticles> iparticles (iparticlesKey, ctx);
   std::vector<bool> filter = m_filter.value();
 
-  const double igev = 1. / CLHEP::GeV;
+  const double igev = 1. / Gaudi::Units::GeV;
   msg(MSG::INFO) << "IParticles | filter :" << endmsg;
   for ( unsigned int i = 0; i != iparticles->size(); ++i ) {
     const std::string kr = filter[i] ? "keep" : "remove";
diff --git a/Control/AthenaExamples/AthExUnittest/CMakeLists.txt b/Control/AthenaExamples/AthExUnittest/CMakeLists.txt
index 17e031707b6333b6eca12ec90d4c8d2c2234d329..f6961cf34b356be27279388eab439e27f5ff0c3a 100644
--- a/Control/AthenaExamples/AthExUnittest/CMakeLists.txt
+++ b/Control/AthenaExamples/AthExUnittest/CMakeLists.txt
@@ -1,22 +1,8 @@
-
-#
-#  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-#
-
-################################################################################
-# Package: MyPackage
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( AthExUnittest )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          GaudiKernel
-                          PRIVATE
-			  Control/AthenaBaseComps
-                          AtlasTest/GoogleTestTools )
-
 # The component lib:
 atlas_add_component( AthExUnittest
                      AthExUnittest/*.h src/*.cxx
@@ -28,5 +14,3 @@ atlas_add_component( AthExUnittest
 atlas_add_test( gt_AthExUnittest
   SOURCES test/gt_AthExUnittest.cxx
   LINK_LIBRARIES GaudiKernel GoogleTestTools AthenaBaseComps )
-
-
diff --git a/Control/AthenaExamples/MultiInputExample/CMakeLists.txt b/Control/AthenaExamples/MultiInputExample/CMakeLists.txt
index b128b6b1751901f10608a98abc6f1d871db1f653..e81a67699c0170fc3b489290d91df91f16f18a7c 100644
--- a/Control/AthenaExamples/MultiInputExample/CMakeLists.txt
+++ b/Control/AthenaExamples/MultiInputExample/CMakeLists.txt
@@ -1,27 +1,13 @@
-################################################################################
-# Package: MultiInputExample
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( MultiInputExample )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          Control/AthenaBaseComps
-                          GaudiKernel
-                          PRIVATE
-                          Control/PileUpTools
-                          Control/StoreGate
-                          Database/AthenaPOOL/AthenaPoolExample/AthenaPoolExampleData
-                          Event/EventInfo )
-
 # Component(s) in the package:
 atlas_add_component( MultiInputExample
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaBaseComps GaudiKernel PileUpToolsLib StoreGateLib SGtests AthenaPoolExampleData EventInfo )
+                     LINK_LIBRARIES AthenaBaseComps AthenaPoolExampleData EventInfo GaudiKernel PileUpToolsLib )
 
 # Install files from the package:
-atlas_install_headers( MultiInputExample )
 atlas_install_joboptions( share/MultiInputInit.py )
-
diff --git a/Control/AthenaExamples/MultiInputExample/src/MyAlg.cxx b/Control/AthenaExamples/MultiInputExample/src/MyAlg.cxx
index 157ff28157ea49605fbb22ee189846336f2aa8bd..08516518720e4b412601c7cb1ee76dbd09a2eede 100644
--- a/Control/AthenaExamples/MultiInputExample/src/MyAlg.cxx
+++ b/Control/AthenaExamples/MultiInputExample/src/MyAlg.cxx
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
-#include "MultiInputExample/MyAlg.h"
+#include "MyAlg.h"
 #include "GaudiKernel/MsgStream.h"
 #include "PileUpTools/PileUpMergeSvc.h"
 
diff --git a/Control/AthenaExamples/MultiInputExample/MultiInputExample/MyAlg.h b/Control/AthenaExamples/MultiInputExample/src/MyAlg.h
similarity index 100%
rename from Control/AthenaExamples/MultiInputExample/MultiInputExample/MyAlg.h
rename to Control/AthenaExamples/MultiInputExample/src/MyAlg.h
diff --git a/Control/AthenaExamples/MultiInputExample/src/MyMultiInputAlg.cxx b/Control/AthenaExamples/MultiInputExample/src/MyMultiInputAlg.cxx
index 3d26b089e0588debb8e35f85dd4b6a2008e7a924..4d5a7ec94d29a4ea4071bffb52905876320312bf 100644
--- a/Control/AthenaExamples/MultiInputExample/src/MyMultiInputAlg.cxx
+++ b/Control/AthenaExamples/MultiInputExample/src/MyMultiInputAlg.cxx
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
-#include "MultiInputExample/MyMultiInputAlg.h"
+#include "MyMultiInputAlg.h"
 #include "GaudiKernel/MsgStream.h"
 #include "PileUpTools/PileUpMergeSvc.h"
 
diff --git a/Control/AthenaExamples/MultiInputExample/MultiInputExample/MyMultiInputAlg.h b/Control/AthenaExamples/MultiInputExample/src/MyMultiInputAlg.h
similarity index 100%
rename from Control/AthenaExamples/MultiInputExample/MultiInputExample/MyMultiInputAlg.h
rename to Control/AthenaExamples/MultiInputExample/src/MyMultiInputAlg.h
diff --git a/Control/AthenaExamples/MultiInputExample/src/components/MultiInputExample_entries.cxx b/Control/AthenaExamples/MultiInputExample/src/components/MultiInputExample_entries.cxx
index a5f5eecb394179c35c485b1ebaa71cfeb99d0f25..d6a5ea0486c19018875fc1956fc73d939f2165ac 100644
--- a/Control/AthenaExamples/MultiInputExample/src/components/MultiInputExample_entries.cxx
+++ b/Control/AthenaExamples/MultiInputExample/src/components/MultiInputExample_entries.cxx
@@ -1,4 +1,4 @@
-#include "MultiInputExample/MyMultiInputAlg.h"
+#include "../MyMultiInputAlg.h"
 
 DECLARE_COMPONENT( MyMultiInputAlg )
 
diff --git a/Control/AthenaExamples/ToyConversion/CMakeLists.txt b/Control/AthenaExamples/ToyConversion/CMakeLists.txt
index 328473afacd9a41822d901060993614559d058f2..b77ed8aceabb33dc29502a70ce3d52e47aea1b54 100644
--- a/Control/AthenaExamples/ToyConversion/CMakeLists.txt
+++ b/Control/AthenaExamples/ToyConversion/CMakeLists.txt
@@ -1,15 +1,8 @@
-################################################################################
-# Package: ToyConversion
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( ToyConversion )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          Control/AthenaKernel
-                          GaudiKernel )
-
 # Component(s) in the package:
 atlas_add_library( ToyConversionLib
                    src/*.cxx
@@ -22,4 +15,3 @@ atlas_add_component( ToyConversion
 
 # Install files from the package:
 atlas_install_joboptions( share/ToyConversionOpts.txt share/ToyConversionOpts.py )
-
diff --git a/Control/AthenaKernel/AthenaKernel/AthenaKernelDict.h b/Control/AthenaKernel/AthenaKernel/AthenaKernelDict.h
index c78eeae9f98faaca0d2495c0494749c2e2f6c064..59ff7329823b44bdbcc129e4bb27f71e7c3d623e 100644
--- a/Control/AthenaKernel/AthenaKernel/AthenaKernelDict.h
+++ b/Control/AthenaKernel/AthenaKernel/AthenaKernelDict.h
@@ -27,6 +27,7 @@
 #include "AthenaKernel/tools/AthenaPackageInfo.h"
 #include "AthenaKernel/DataBucketBase.h"
 #include "AthenaKernel/ThinningDecisionBase.h"
+#include "AthenaKernel/CondCont.h"
 
 #include "GaudiKernel/MsgStream.h"
 
diff --git a/Control/AthenaKernel/AthenaKernel/CondCont.h b/Control/AthenaKernel/AthenaKernel/CondCont.h
index 4ad8039cc20e107871bc73caa4706a76de9a0c6c..0585ac969b7e6991c5e203ac6888b9c12abcc3e5 100644
--- a/Control/AthenaKernel/AthenaKernel/CondCont.h
+++ b/Control/AthenaKernel/AthenaKernel/CondCont.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 /**
  * @file AthenaKernel/CondCont.h
@@ -918,6 +918,17 @@ public:
              EventIDRange const** r = nullptr) const;
 
 
+  /** 
+   * @brief Look up a conditions object for a given time.
+   * @param t IOV time to find.
+   *
+   * Returns the found object, or nullptr.
+   *
+   * This variant may be more convenient to call from python.
+   */
+  const T* find (const EventIDBase& t) const;
+
+
 protected:
   /**
    * @brief Internal constructor.
@@ -1227,6 +1238,17 @@ public:
              EventIDRange const** r = nullptr) const;
 
 
+  /**
+   * @brief Look up a conditions object for a given time.
+   * @param t IOV time to find.
+   *
+   * Returns the found object, or nullptr.
+   *
+   * This variant may be more convenient to call from python.
+   */
+  const T* find (const EventIDBase& t) const;
+
+
 protected:
   /** 
    * @brief Internal Constructor.
diff --git a/Control/AthenaKernel/AthenaKernel/CondCont.icc b/Control/AthenaKernel/AthenaKernel/CondCont.icc
index 68745f2b5b2aa658a9602fc2a15a7288f66cb464..76f4cdcf021a3286dc0e290db616b8dec45ac8c1 100644
--- a/Control/AthenaKernel/AthenaKernel/CondCont.icc
+++ b/Control/AthenaKernel/AthenaKernel/CondCont.icc
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 /**
  * @file AthenaKernel/CondCont.icc
@@ -283,6 +283,28 @@ bool CondCont<T>::find (const EventIDBase& t,
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 
+/** 
+ * @brief Look up a conditions object for a given time.
+ * @param t IOV time to find.
+ *
+ * Returns the found object, or nullptr.
+ *
+ * This variant may be more convenient to call from python.
+ */
+template <typename T>
+const T* CondCont<T>::find (const EventIDBase& t) const
+{
+  const T* obj = nullptr;
+  if (this->find (t, obj)) {
+    return obj;
+  }
+  return nullptr;
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
 /**
  * @brief Do pointer conversion for the payload type.
  * @param clid CLID for the desired pointer type.
@@ -448,6 +470,27 @@ bool CondContMixed<T>::find (const EventIDBase& t,
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 
+/** 
+ * @brief Look up a conditions object for a given time.
+ * @param t IOV time to find.
+ *
+ * Returns the found object, or nullptr.
+ *
+ * This variant may be more convenient to call from python.
+ */
+template <typename T>
+const T* CondContMixed<T>::find (const EventIDBase& t) const
+{
+  const T* obj = nullptr;
+  if (this->find (t, obj)) {
+    return obj;
+  }
+  return nullptr;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
 /** 
  * @brief Constructor.
  * @param rcusvc RCU service instance.
diff --git a/Control/AthenaKernel/AthenaKernel/selection.xml b/Control/AthenaKernel/AthenaKernel/selection.xml
index 3de968ea10570f56bfbdbba0633d48247a5b09b5..de4026969fcd33d98752b8859d72351e619423e2 100644
--- a/Control/AthenaKernel/AthenaKernel/selection.xml
+++ b/Control/AthenaKernel/AthenaKernel/selection.xml
@@ -28,4 +28,8 @@
 
    <class name="SG::ThinningDecisionBase"/>
 
+   <class name="CondContBase"/>
+   <class name="CondContSingleBase"/>
+   <class name="CondContMixedBase"/>
+
 </lcgdict>
diff --git a/Control/AthenaKernel/share/CondCont_test.ref b/Control/AthenaKernel/share/CondCont_test.ref
index 71832b0c5472d20d9df502917c5b11586da94551..3f1909bcca877f4e7068e182d7a5929b98894339 100644
--- a/Control/AthenaKernel/share/CondCont_test.ref
+++ b/Control/AthenaKernel/share/CondCont_test.ref
@@ -18,6 +18,7 @@ UNKNOWN_CLASS:c...  ERROR CondContMixedBase::insertMixed: Run+lbn part of new ra
 UNKNOWN_CLASS:c...  ERROR CondContMixedBase::findMixed: No valid timestamp in key used with mixed container.
 UNKNOWN_CLASS:c...  ERROR CondContBase::findBase: Non-Run/LBN key used in Run/LBN container.
 UNKNOWN_CLASS:c...  ERROR CondContMixedBase::findMixed: No valid timestamp in key used with mixed container.
+UNKNOWN_CLASS:c...  ERROR CondContMixedBase::findMixed: No valid timestamp in key used with mixed container.
 UNKNOWN_CLASS:c...  ERROR CondContBase::findBase: Non-Run/LBN key used in Run/LBN container.
 UNKNOWN_CLASS:c...  ERROR CondContMixedBase::erase: erase() is not implemented for mixed containers.
 UNKNOWN_CLASS:c...  ERROR CondContMixedBase::extendLastRange: extendLastRange() is not implemented for mixed containers.
diff --git a/Control/AthenaKernel/test/CondCont_test.cxx b/Control/AthenaKernel/test/CondCont_test.cxx
index d349a96bb82b6563c5cf43f5c519a42d3ae775e6..4ff0fea9694329eeb9e31585ff9bc4f75fcbe2bb 100644
--- a/Control/AthenaKernel/test/CondCont_test.cxx
+++ b/Control/AthenaKernel/test/CondCont_test.cxx
@@ -257,6 +257,7 @@ void checkit (const CondCont<T>& cc_rl,
   const T* t = nullptr;
   assert (cc_rl.find (runlbn (10, 17), t));
   assert (t == ptrs[0]);
+  assert (cc_rl.find (runlbn (10, 17)) == t);
 
   t = nullptr;
   assert (cc_rl.find (runlbn (100, 200), t));
@@ -271,6 +272,7 @@ void checkit (const CondCont<T>& cc_rl,
 
   assert (!cc_rl.find (runlbn (15, 17), t));
   assert (!cc_ts.find (timestamp (999), t));
+  assert (cc_rl.find (runlbn (15, 17)) == nullptr);
 
   assert (cc_rl.range (runlbn (100, 200), r));
   assert (r == r2);
@@ -535,10 +537,12 @@ void test4 (TestRCUSvc& rcusvc)
   const B* obj = nullptr;
   assert (!cc.find (runlbn(1, 10), obj, &range));
   assert (!cc.find (timestamp(110), obj, &range));
+  assert (cc.find (runlbn(1, 10)) == nullptr);
 
   assert (cc.find (mixed(1, 12, 3), obj, &range));
   assert (obj->m_x == 2);
   assert (*range == EventIDRange (mixed(1, 10,   2),   mixed(1, 20,   4.5)));
+  assert (cc.find (mixed(1, 12, 3)) == obj);
 
   assert (cc.find (mixed(1, 35, 25), obj, &range));
   assert (obj->m_x == 3);
diff --git a/Control/AthenaMonitoring/python/AthenaMonitoringCfg.py b/Control/AthenaMonitoring/python/AthenaMonitoringCfg.py
index de779c0d90647464e3ea69513e106b8ee8409560..df758b81ca21c07a17fcfece931949079348c4e2 100644
--- a/Control/AthenaMonitoring/python/AthenaMonitoringCfg.py
+++ b/Control/AthenaMonitoring/python/AthenaMonitoringCfg.py
@@ -82,5 +82,10 @@ def AthenaMonitoringCfg(flags):
         info('Set up AFP monitoring')
         from Run3AFPMonitoring.Run3AFPExampleMonitorAlgorithm import Run3AFPExampleMonitoringConfig
         result.merge(Run3AFPExampleMonitoringConfig(flags))
+
+    if flags.DQ.Steering.doLVL1CaloMon:
+        info('Set up LVL1Calo monitoring')
+        from TrigT1CaloMonitoring.LVL1CaloMonitoringConfig import LVL1CaloMonitoringConfig
+        result.merge(LVL1CaloMonitoringConfig(flags))
         
     return result
diff --git a/Control/AthenaMonitoring/python/DQConfigFlags.py b/Control/AthenaMonitoring/python/DQConfigFlags.py
index 24db04e8f0d51e3bfd92332b2152e905b0575126..bf7157de5b3573bc0c4f0522827401d79a61101b 100644
--- a/Control/AthenaMonitoring/python/DQConfigFlags.py
+++ b/Control/AthenaMonitoring/python/DQConfigFlags.py
@@ -4,7 +4,7 @@
 
 from AthenaConfiguration.AthConfigFlags import AthConfigFlags
 
-_steeringFlags = [ 'doGlobalMon', 'LVL1CaloMon', 'doCTPMon', 'doHLTMon',
+_steeringFlags = [ 'doGlobalMon', 'doLVL1CaloMon', 'doCTPMon', 'doHLTMon',
                    'doPixelMon', 'doSCTMon', 'doTRTMon', 'doInDetMon',
                    'doLArMon', 'doTileMon',
                    'doCaloGlobalMon', 'doMuonMon',
diff --git a/Control/AthenaPython/python/PyAthenaComps.py b/Control/AthenaPython/python/PyAthenaComps.py
index 95e5d4df682a4221f63cc4dae450dd3d2c53744f..60301958e3b0ef1a6175a7235ec0ea569d413cee 100644
--- a/Control/AthenaPython/python/PyAthenaComps.py
+++ b/Control/AthenaPython/python/PyAthenaComps.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # @file: PyAthenaComps.py
 # @purpose: a set of Python classes for PyAthena
@@ -77,6 +77,7 @@ class Alg( CfgPyAlgorithm ):
         super(Alg, self).__init__(name, **kw)
         self._pyath_evtstore = None # handle to the evt store
         self._pyath_detstore = None # handle to the det store
+        self._pyath_condstore = None # handle to the cond store
         self._ctx = None
         self.__component_type__="Algorithm"
         self.__cpp_type__=self.__class__.__name__
@@ -97,6 +98,13 @@ class Alg( CfgPyAlgorithm ):
             self._pyath_detstore = PyAthena.py_svc('StoreGateSvc/DetectorStore')
         return self._pyath_detstore
     
+    @property
+    def condStore(self):
+        if not self._pyath_condstore:
+            import AthenaPython.PyAthena as PyAthena
+            self._pyath_condtstore = PyAthena.py_svc('StoreGateSvc/ConditionStore')
+        return self._pyath_condstore
+    
     def sysInitialize(self):
         self.msg.setLevel(_get_prop_value(self,'OutputLevel'))
         return self.initialize()
@@ -225,6 +233,7 @@ class AlgTool( CfgPyAlgTool ):
         self.__dict__['msg']  = logging.getLogger( self.getJobOptName() )
         self._pyath_evtstore = None # handle to the evt store
         self._pyath_detstore = None # handle to the det store
+        self._pyath_condstore = None # handle to the cond store
         self.__component_type__ = "AlgTool"
         self.__cpp_type__=self.__class__.__name__
         return
@@ -243,6 +252,13 @@ class AlgTool( CfgPyAlgTool ):
             self._pyath_detstore = PyAthena.py_svc('StoreGateSvc/DetectorStore')
         return self._pyath_detstore
     
+    @property
+    def condStore(self):
+        if not self._pyath_condstore:
+            import AthenaPython.PyAthena as PyAthena
+            self._pyath_condstore = PyAthena.py_svc('StoreGateSvc/ConditionStore')
+        return self._pyath_condstore
+    
     def sysInitialize(self):
         self.msg.setLevel(_get_prop_value(self,'OutputLevel'))
         return self.initialize()
diff --git a/Control/AthenaServices/CMakeLists.txt b/Control/AthenaServices/CMakeLists.txt
index 86f3ec34c1496892ed3aa214bfc76bc7f1b462a4..cd9bda4b2242f614a28a37a0274f40e079738da2 100644
--- a/Control/AthenaServices/CMakeLists.txt
+++ b/Control/AthenaServices/CMakeLists.txt
@@ -57,6 +57,8 @@ atlas_add_test( AthenaOutputStream_test
    LINK_LIBRARIES TestTools AsgTools AthenaKernel SGTools StoreGateLib GaudiKernel AthenaBaseComps PersistentDataModel
    LOG_IGNORE_PATTERN "^AthenaRootStrea... +(INFO|DEBUG)|^AthenaSealSvc +DEBUG|^SGAudSvc +(INFO|DEBUG)|of type DataHistory|DEBUG Recorded object|object modifiable when retrieved|^ToolSvc +DEBUG Service base class initialized|^ServiceManager +DEBUG Initializing service|^IncidentSvc *DEBUG Adding .* listener|DecisionSvc +DEBUG|^IoComponentMgr +(INFO|DEBUG)|DBReplicaSvc|^HistogramPersis.*DEBUG|^ItemListSvc +(INFO|DEBUG)|Info File PoolFileCatalog.xml does not exist|DataModelCompatSvc::initialize|^ProxyProviderSvc +DEBUG|^DataModelCompatSvc +DEBUG|^AthenaOutputStreamVERBOSE|^AthenaOutputStream +DEBUG|^TimelineSvc +DEBUG"
    ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" )
+# Avoid spurious ubsan warnings.
+set_target_properties( AthenaServices_AthenaOutputStream_test PROPERTIES ENABLE_EXPORTS True )
 
 atlas_add_test( FPEControlSvc_test
    SOURCES test/FPEControlSvc_test.cxx
diff --git a/Control/AthenaServices/python/Configurables.py b/Control/AthenaServices/python/Configurables.py
index b0b7e99cd1d193fac0d22cfdd40fc2f7027fc4ea..153f18df4af004d1342e6a703501da9776f21b00 100644
--- a/Control/AthenaServices/python/Configurables.py
+++ b/Control/AthenaServices/python/Configurables.py
@@ -130,7 +130,6 @@ class ThinningSvc( _ThinningSvc ):
         ## list of streams we know we will apply thinning on
         outstreams = []
         
-        ## connect @c ThinningOutputTool into the HelperTools slot
         AthenaOutputStream = CfgMgr.AthenaOutputStream
 
         ## first loop over TopAlg (as output stream can be located
@@ -173,27 +172,11 @@ class ThinningSvc( _ThinningSvc ):
         if _lvl == handle.propertyNoValue:
             _lvl = handle.getDefaultProperty('OutputLevel')
             pass
-        ## get and install the ThinningOutputTool configurable
-        from AthenaServices.AthenaServicesConf import ThinningOutputTool
-        toolName = "ThinningTool_%s" % handle.name()
-        tool = ThinningOutputTool (toolName,
-                                   OutputLevel=_lvl,
-                                   ThinningSvc=handle)
-        tool.Proxies = []
-        for o in outstreams:
-            tool.Proxies += _build_proxy_list(o)
-            o.HelperTools.insert(0, tool)
-            ## XXX FIXME XXX
-            ## see https://savannah.cern.ch/bugs/index.php?40823
-            o.HelperTools += [] # just to work-around bug #40823
-        ##
         return
     pass # class ThinningSvc
 
 def createThinningSvc(svcName = "ThinningSvc", outStreams = []):
     """Helper method to create a completely configured ThinningSvc.
-    It will take care of adding the helper ThinningOutputTool to the list of
-    'outStreams' it has been given.
     Note that 'outStreams' elements have to be AthenaOutputStreams !
     """
     from AthenaCommon.Logging import logging
diff --git a/Control/AthenaServices/src/ThinningOutputTool.cxx b/Control/AthenaServices/src/ThinningOutputTool.cxx
deleted file mode 100644
index ca545a70a197c14aef0470ffb3842b57e9fb3619..0000000000000000000000000000000000000000
--- a/Control/AthenaServices/src/ThinningOutputTool.cxx
+++ /dev/null
@@ -1,259 +0,0 @@
-///////////////////////// -*- C++ -*- /////////////////////////////
-
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-// ThinningOutputTool.cxx 
-// Implementation file for class ThinningOutputTool
-// Author: S.Binet<binet@cern.ch>
-/////////////////////////////////////////////////////////////////// 
-
-
-// STL includes
-#include <climits>
-#include <cstdlib> // for atoi
-#include <stdexcept>
-
-// FrameWork includes
-#include "GaudiKernel/IToolSvc.h"
-
-// AthenaKernel
-#include "AthenaKernel/IThinningSvc.h"
-
-// SGTools
-#include "SGTools/DataProxy.h"
-
-// AthenaServices includes
-#include "ThinningOutputTool.h"
-
-/////////////////////////////////////////////////////////////////// 
-// Public methods: 
-/////////////////////////////////////////////////////////////////// 
-
-// Constructors
-////////////////
-ThinningOutputTool::ThinningOutputTool( const std::string& type, 
-					const std::string& name, 
-					const IInterface* parent ) : 
-  AthAlgTool( type, name, parent ),
-  m_thinningSvc ( "ThinningSvc",  name ),
-  m_activeSvc   ( nullptr )
-{
-  //
-  // Property declaration
-  // 
-  //declareProperty( "Property", m_nProperty );
-
-  declareProperty( "ThinningSvc",
-		   m_thinningSvc = ThinningSvc_t( "ThinningSvc", name ),
-		   "Handle to the service which has thinned data" );
-
-  declareProperty( "Proxies",
-		   m_proxies,
-		   "list of pairs (clid,key) the tool will forcingly read "
-		   "from input to ensure a sound thinning state" )
-    ->declareUpdateHandler(&ThinningOutputTool::propertyHandler, this);
-
-   // Declare IAthenaOutputStreamTool interface
-  declareInterface<IAthenaOutputTool>(this);
-
-}
-
-// Destructor
-///////////////
-ThinningOutputTool::~ThinningOutputTool()
-{}
-
-// Athena Algorithm's Hooks
-////////////////////////////
-StatusCode ThinningOutputTool::initialize()
-{
-  ATH_MSG_INFO ("Initializing " << name() << "...");
-
-  // Get pointer to ThinningSvc and cache it :
-  if ( !m_thinningSvc.retrieve().isSuccess() ) {
-    ATH_MSG_ERROR ("Unable to retrieve pointer to ThinningSvc");
-    return StatusCode::FAILURE;
-  }
-  
-  ATH_MSG_INFO("proxies to be forcingly read: " << m_proxies.size());
-  if (msgLvl(MSG::VERBOSE)) {
-    for (std::size_t i = 0, imax = m_proxies.size(); i != imax; ++i) {
-      ATH_MSG_VERBOSE(" clid=[" << m_proxies[i][0] << "] sg_key=["
-		      << m_proxies[i][1] << "]");
-    }
-  }
-  return StatusCode::SUCCESS;
-}
-
-StatusCode ThinningOutputTool::finalize()
-{
-  ATH_MSG_INFO ("Finalizing " << name() << "...");
-  return StatusCode::SUCCESS;
-}
-
-StatusCode ThinningOutputTool::preExecute()
-{
-  bool allGood = true;
-  ATH_MSG_DEBUG ("Calling IThinningSvc::commit()...");
-
-  // retrieve the currently active thinning svc
-  m_activeSvc = IThinningSvc::instance();
-    
-  // set our thinning svc as the active one
-  static const bool override = true;
-  IThinningSvc* svc = IThinningSvc::instance( &*m_thinningSvc, override );
-  if ( svc != &*m_thinningSvc ) {
-    ATH_MSG_ERROR
-      ("Could not set our peer ThinningSvc as the current active one !");
-    // put back the previous one
-    IThinningSvc::instance( m_activeSvc, override );
-    // bail-out
-    return StatusCode::FAILURE;
-  }
-
-  const bool doThinning = m_thinningSvc->thinningOccurred();
-  if (doThinning && m_proxies.size()>0) {
-    typedef std::vector<const SG::DataProxy*> SgProxies_t;
-    SgProxies_t proxies = m_thinningSvc->proxies(); // just in case
-    for ( std::size_t i = 0, imax = m_proxies.size();
-	  i != imax;
-	  ++i ) {
-      const Proxy_t& proxy = m_proxies[i];
-      CLID clid = std::atol(proxy[0].c_str());
-      const std::string& key = proxy[1];
-      ATH_MSG_VERBOSE("loading proxy(" << clid << ", " << key << ")...");
-      if (key != "*") {
-	SG::DataProxy* p = m_thinningSvc->proxy(clid, key);
-	if (!p) {
-	  // this proxy is only accessible *when* back navigation is 'ON'
-	  ATH_MSG_VERBOSE("null pointer to proxy(" <<clid<<"#"<<key<< ")");
-	  continue;
-	}
-	if ( p->isValid() ) {
-	  ATH_MSG_DEBUG 
-	    ("force-loading proxy(clid=[" << p->clID() << "], "
-	     << "key=[" << p->name() << "])...");
-	  if ( nullptr == p->accessData() ) {
-	    ATH_MSG_WARNING
-	      ("Could not accessData(clid=[" << p->clID() << "], "
-	       << "key=[" << p->name() << "]) !" 
-	       << endmsg
-	       << "Thinning might segfault under certain conditions...");
-	  }
-	}
-      } else {
-	// get all proxies with CLID 'clid'
-	ATH_MSG_VERBOSE("requested to load all proxies with clid ["
-			<<clid<<"]...");
-	for (std::size_t j = 0, jmax = proxies.size(); j != jmax; ++j) {
-	  // FIXME: linear search !
-	  if (proxies[j]->clID() != clid) {
-	    continue;
-	  }
-	  // lovely...
-	  SG::DataProxy* p = const_cast<SG::DataProxy*>(proxies[j]);
-	  if (p->isValid()) {
-	    ATH_MSG_DEBUG
-	      ("force-loading proxy(clid=[" << p->clID() << "], "
-	       << "key=[" << p->name() << "])...");
-	    if ( nullptr == p->accessData() ) {
-	      ATH_MSG_WARNING
-		("Could not accessData(clid=[" << p->clID() << "], "
-		 << "key=[" << p->name() << "]) !" 
-		 << endmsg
-		 << "Thinning might segfault under certain conditions...");
-	    }
-	  }
-	}
-      } //> a wildcard was there...
-    } //> loop over my proxy list
-  } //> thinning occured and proxies to load
-
-  // apply thinning only if needed
-  if ( doThinning && !m_thinningSvc->commit().isSuccess() ) {
-    ATH_MSG_ERROR
-      ("IThinningSvc::commit() failed !" << endmsg
-       << "Containers (and ElementLinks pointing to their elements) are "
-       << "most probably in a corrupted state !!");
-    allGood = false;
-  }
-
-  return allGood 
-    ? StatusCode::SUCCESS 
-    : StatusCode::FAILURE
-    ;
-}
-  
-StatusCode ThinningOutputTool::postExecute()
-{
-  bool allGood = true;
-  ATH_MSG_DEBUG ("Calling IThinningSvc::rollback()...");
-
-  const bool doThinning = m_thinningSvc->thinningOccurred();
-  if ( doThinning && !m_thinningSvc->rollback().isSuccess() ) {
-    ATH_MSG_ERROR
-      ("IThinningSvc::rollback() failed !" << endmsg
-       << "Containers (and ElementLinks pointing to their elements) are "
-       << "most probably in a corrupted state !!");
-    allGood = false;
-  }
-
-  // restore old active svc
-  static const bool override = true;
-  IThinningSvc* svc = IThinningSvc::instance( m_activeSvc, override );
-  if ( svc != m_activeSvc ) {
-    ATH_MSG_WARNING
-      ("Could not setup the previous active thinning svc as the "\
-       "current active one !");
-  }
-
-  return allGood 
-    ? StatusCode::SUCCESS 
-    : StatusCode::FAILURE
-    ;
-}
-  
-/////////////////////////////////////////////////////////////////// 
-// Const methods: 
-///////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////// 
-// Non-const methods: 
-/////////////////////////////////////////////////////////////////// 
-
-/////////////////////////////////////////////////////////////////// 
-// Protected methods: 
-/////////////////////////////////////////////////////////////////// 
-
-/////////////////////////////////////////////////////////////////// 
-// Const methods: 
-///////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////// 
-// Non-const methods: 
-/////////////////////////////////////////////////////////////////// 
-
-void
-ThinningOutputTool::propertyHandler(Property& /*m_proxies*/)
-{
-  const Proxies_t& proxies = m_proxies;
-
-  for (Proxies_t::const_iterator i = proxies.begin(), iend = proxies.end();
-       i != iend;
-       ++i) {
-    const Proxy_t& proxy = *i;
-    if (proxy.size() != 2) {
-      ATH_MSG_ERROR("invalid proxy format - need 2 items. got: " << 
-		    proxy.size());
-      throw std::runtime_error("invalid proxy format (need 2 items)");
-    }
-    const long clid = std::atol(proxy[0].c_str());
-    if (clid == LONG_MAX || clid == LONG_MIN || clid <= 0) {
-      ATH_MSG_ERROR("invalid clid number [" << proxy[0] << "] (converts to ["
-		    << clid << "])");
-      throw std::runtime_error("invalid clid number");
-    }
-  }
-}
diff --git a/Control/AthenaServices/src/ThinningOutputTool.h b/Control/AthenaServices/src/ThinningOutputTool.h
deleted file mode 100644
index d83d0e5406bd0830b244bd04d23cb41286c4100e..0000000000000000000000000000000000000000
--- a/Control/AthenaServices/src/ThinningOutputTool.h
+++ /dev/null
@@ -1,120 +0,0 @@
-///////////////////////// -*- C++ -*- /////////////////////////////
-
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-// ThinningOutputTool.h 
-// Header file for class ThinningOutputTool
-// Author: S.Binet<binet@cern.ch>
-/////////////////////////////////////////////////////////////////// 
-#ifndef ATHENASERVICES_THINNINGOUTPUTTOOL_H 
-#define ATHENASERVICES_THINNINGOUTPUTTOOL_H 
-
-// STL includes
-#include <string>
-#include <vector>
-#include <utility> // for std::pair
-
-// FrameWork includes
-#include "AthenaBaseComps/AthAlgTool.h"
-#include "GaudiKernel/ServiceHandle.h"
-
-// AthenaKernel includes
-#include "AthenaKernel/IAthenaOutputTool.h"
-
-// Forward declaration
-class IThinningSvc;
-
-class ThinningOutputTool : virtual public IAthenaOutputTool,
-                                   public AthAlgTool
-{ 
-
-  /////////////////////////////////////////////////////////////////// 
-  // Public methods: 
-  /////////////////////////////////////////////////////////////////// 
- public: 
-
-  // Copy constructor: 
-
-  /// Constructor with parameters: 
-  ThinningOutputTool( const std::string& type,
-		      const std::string& name, 
-		      const IInterface* parent );
-
-  /// Destructor: 
-  virtual ~ThinningOutputTool(); 
-
-  // Athena algorithm's Hooks
-  virtual StatusCode  initialize();
-  virtual StatusCode  finalize();
-
-  /// Called at the beginning of @c AthenaOutputStream::execute()
-  /// This will trigger the 'commit' of the @c IThinningSvc indices
-  StatusCode preExecute();
-  
-  /// Called at the end of @c AthenaOutputStream::execute()
-  /// This will trigger the 'rollback' of the @c IThinningSvc indices
-  StatusCode postExecute();
-
-  /// Called at the end of @c AthenaOutputStream::initialize()
-  /// No-op (for now ?)
-  StatusCode postInitialize() { return StatusCode::SUCCESS; }
-
-  /// Called at the beginning of @c AthenaOutputStream::finalize()
-  /// No-op (for now ?)
-  StatusCode preFinalize() { return StatusCode::SUCCESS; }
-
-  /////////////////////////////////////////////////////////////////// 
-  // Const methods: 
-  ///////////////////////////////////////////////////////////////////
-
-  /////////////////////////////////////////////////////////////////// 
-  // Non-const methods: 
-  /////////////////////////////////////////////////////////////////// 
-
-  /////////////////////////////////////////////////////////////////// 
-  // Private methods: 
-  /////////////////////////////////////////////////////////////////// 
- private: 
-
-  /// Default constructor: 
-  ThinningOutputTool();
-
-  /** property callback to ensure correct format of 'Proxies'
-   */
-  void propertyHandler(Property& p);
-  
-  /////////////////////////////////////////////////////////////////// 
-  // Private data: 
-  /////////////////////////////////////////////////////////////////// 
- private: 
-
-  typedef ServiceHandle<IThinningSvc> ThinningSvc_t;
-  /// Pointer to the @c IThinningSvc service
-  ThinningSvc_t m_thinningSvc;
-
-  /// Pointer to the active @c IThinningSvc service
-  IThinningSvc* m_activeSvc;
-
-  typedef std::vector<std::string> Proxy_t;
-  typedef std::vector<Proxy_t> Proxies_t;
-  /** list of pairs (clid,key) the tool will forcingly read from input
-   *  to ensure a sound thinning state (ie: all element-links will be correctly
-   *  massaged by the thinning machinery)
-   */
-  Proxies_t m_proxies;
-
-  // Containers
-  
-
-}; 
-
-// I/O operators
-//////////////////////
-
-/////////////////////////////////////////////////////////////////// 
-// Inline methods: 
-/////////////////////////////////////////////////////////////////// 
-
-#endif //> ATHENASERVICES_THINNINGOUTPUTTOOL_H
diff --git a/Control/AthenaServices/src/components/AthenaServices_entries.cxx b/Control/AthenaServices/src/components/AthenaServices_entries.cxx
index 50589cdcdb12ff7ea25cb95fd23d23496702b149..465609cb5a923291062cd16d1c6e304ce23a0338 100644
--- a/Control/AthenaServices/src/components/AthenaServices_entries.cxx
+++ b/Control/AthenaServices/src/components/AthenaServices_entries.cxx
@@ -7,7 +7,6 @@
 #include "../SimplePOSIXTimeKeeperSvc.h"
 #include "../MixingEventSelector.h"
 #include "../ThinningSvc.h"
-#include "../ThinningOutputTool.h"
 #include "../ThinningCacheTool.h"
 //#include "../EventDumperSvc.h"
 #include "../MemoryRescueSvc.h"
@@ -68,7 +67,6 @@ DECLARE_COMPONENT( EvtIdModifierSvc )
 DECLARE_COMPONENT( MetaDataSvc )
 DECLARE_COMPONENT( OutputStreamSequencerSvc )
 DECLARE_COMPONENT( AthenaOutputStreamTool )
-DECLARE_COMPONENT( ThinningOutputTool )
 DECLARE_COMPONENT( Athena::ThinningCacheTool )
 DECLARE_COMPONENT( AthenaStopperAlg )
 DECLARE_COMPONENT( AthIncFirerAlg )
diff --git a/Control/CxxUtils/CxxUtils/ones.h b/Control/CxxUtils/CxxUtils/ones.h
index 57a23f878c606e42c25067273ef678573a2af433..41e40e3dd8769585b55d3b514a88248d5436575d 100644
--- a/Control/CxxUtils/CxxUtils/ones.h
+++ b/Control/CxxUtils/CxxUtils/ones.h
@@ -1,10 +1,7 @@
 // This file's extension implies that it's C, but it's really -*- C++ -*-.
-
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
-
-// $Id$
 /**
  * @file CxxUtils/ones.h
  * @author scott snyder <snyder@bnl.gov>
@@ -29,6 +26,7 @@ T ones (unsigned int n)
 {
   if (n >= sizeof(T) * 8)
     return ~static_cast<T>(0);
+  // cppcheck-suppress shiftTooManyBits
   return (static_cast<T>(1) << n) - 1;
 }
 
diff --git a/Control/CxxUtils/test/phihelper_test.cxx b/Control/CxxUtils/test/phihelper_test.cxx
index 648b652be544987b417e55d587d8cfe474550983..1227ff72d6ec9e5b931cc07aada4ac7e8f9b2943 100644
--- a/Control/CxxUtils/test/phihelper_test.cxx
+++ b/Control/CxxUtils/test/phihelper_test.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 /**
  * @file CxxUtils/test/phihelper_test.cxx
@@ -64,6 +64,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_wrap, T, test_types)
   BOOST_TEST(wrapToPi<T>(-40.1 * PI) == wrapToPi<T>(-10.1 * PI));
 }
 
+// cppcheck-suppress unknownMacro
 BOOST_TEST_DECORATOR(TOLERANCE)
 BOOST_AUTO_TEST_CASE_TEMPLATE(test_delta, T, test_types)
 {
diff --git a/Control/IOVSvc/src/IOVSvc.cxx b/Control/IOVSvc/src/IOVSvc.cxx
index 68b837086f3a8209dd550422135d326a58d4a8b8..08e41e5bc94420afe714dd5764a2be00aa51d5ad 100755
--- a/Control/IOVSvc/src/IOVSvc.cxx
+++ b/Control/IOVSvc/src/IOVSvc.cxx
@@ -847,6 +847,16 @@ IOVSvc::createCondObj(CondContBase* ccb, const DataObjID& id,
     dobj = 0;
   }
 
+  // Some data objects may be reference counted by the address.
+  // CondCont will take ownership of the object, but doesn't
+  // do refcounting.  We'll have gotten a reference via the Storable_cast
+  // above, so it should be ok ... unless CondCont deletes
+  // the new object immediately instead of inserting.
+  // In that case, when we delete the address, it will
+  // follow an invalid pointer.  So be sure to delete
+  // the address before the object is added to CondCont.
+  ioa.release();
+
   // DataObject *d2 = static_cast<DataObject*>(v);
   
   ATH_MSG_DEBUG( " SG::Storable_cast to obj: " << v );
diff --git a/Control/RootUtils/RootUtils/PyROOTTFilePythonize.h b/Control/RootUtils/RootUtils/PyROOTTFilePythonize.h
index f65efbb215d05d2f4df6049906437fa74bd8bd43..2fc9d6bad2f765dead326c950b73d60af5a156a1 100644
--- a/Control/RootUtils/RootUtils/PyROOTTFilePythonize.h
+++ b/Control/RootUtils/RootUtils/PyROOTTFilePythonize.h
@@ -1,11 +1,7 @@
 // This file's extension implies that it's C, but it's really -*- C++ -*-.
-
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
-
-// $Id$
-
 /**
  * @file RootUtils/PyROOTTFilePythonize.h
  * @author Sebastien Binet
@@ -54,11 +50,14 @@ public:
 
   /** the buffer of bytes
    */
-  char* buf;
+  std::vector<char> buf;
 
   /** 
+   * After we drop py2, we can simplify the code in PyUtils.RootUtils.py
+   * by just returning a bytes object from here.
    */
-  void* buffer() const { return (void*)buf; }
+  void* buffer() const { return (void*)buf.data(); }
+
 };
 
 /** @brief read `len` bytes from file `f`
diff --git a/Control/RootUtils/RootUtils/RootUtilsPyROOTDict.h b/Control/RootUtils/RootUtils/RootUtilsPyROOTDict.h
index 7cb56d351511104384a8d4972d6d55dd9503c63b..de05a3c5e04096e6742000bc5b2442ef176b3731 100644
--- a/Control/RootUtils/RootUtils/RootUtilsPyROOTDict.h
+++ b/Control/RootUtils/RootUtils/RootUtilsPyROOTDict.h
@@ -1,7 +1,7 @@
 // This file's extension implies that it's C, but it's really -*- C++ -*-.
 
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // $Id: RootUtilsPyROOTDict.h,v 1.5 2008-04-23 19:48:34 ssnyder Exp $
@@ -26,7 +26,7 @@
 // Work around a problem sometimes seen with cling in which `struct timespec'
 // appears to be predeclared without the include guard being defined.
 // This can cause problems, for example, with headers that include Python.h.
-// As a workaroud, force the include guard to be defined when this
+// As a workaround, force the include guard to be defined when this
 // dictionary is loaded.
 #include "TInterpreter.h"
 class RootUtilsInit
diff --git a/Control/RootUtils/src/pyroot/PyROOTTFilePythonize.cxx b/Control/RootUtils/src/pyroot/PyROOTTFilePythonize.cxx
index 0f19e3dbcf380ab97761f03057e6993c0b0023de..c2d80d2132db508ca72c8e88ee2c269598f218ac 100644
--- a/Control/RootUtils/src/pyroot/PyROOTTFilePythonize.cxx
+++ b/Control/RootUtils/src/pyroot/PyROOTTFilePythonize.cxx
@@ -1,8 +1,6 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
-
-// $Id$
 /**
  * @file RootUtils/src/pyroot/PyROOTTFilePythonize.cxx
  * @author Sebastien Binet
@@ -23,26 +21,18 @@ namespace RootUtils {
 
 PyBytes::PyBytes(size_t buf_sz) : 
   sz(buf_sz>0?buf_sz:0), 
-  buf(0)
+  buf(sz)
 {
-  if (this->sz>0) {
-    buf = (char*)malloc(sizeof(char)*this->sz);
-  }
 }
 
 PyBytes::~PyBytes() 
 {
-  free(buf); buf = 0;
 }
 
 PyBytes::PyBytes(const PyBytes& rhs) : 
   sz(rhs.sz), 
-  buf(0)
+  buf(rhs.buf)
 {
-  if (this->sz>0) {
-    buf = (char*)malloc(sizeof(char)*this->sz);     
-    buf = (char*)memcpy(buf, rhs.buf, this->sz);
-  }
 }
 
 PyBytes&
@@ -50,11 +40,7 @@ PyBytes::operator=(const PyBytes& rhs)
 {
   if (this != &rhs) {
     this->sz = rhs.sz;
-    free(this->buf); this->buf = 0;
-    if (this->sz>0) {      
-      this->buf = (char*)malloc(sizeof(char)*this->sz);     
-      this->buf = (char*)memcpy(this->buf, rhs.buf, rhs.sz);
-    }
+    this->buf = rhs.buf;
   }
   return *this;
 }
@@ -85,7 +71,7 @@ _pythonize_read_root_file(TFile* f, Int_t len)
 
   len = (len>remain) ? remain : len;
   PyBytes buf(len);
-  if (f->ReadBuffer((char*)buf.buf, buf.sz)) {
+  if (f->ReadBuffer((char*)buf.buf.data(), buf.sz)) {
     //err
     return PyBytes(0);
   }
diff --git a/Control/SGComps/src/ProxyProviderSvc.cxx b/Control/SGComps/src/ProxyProviderSvc.cxx
index 2b2b938530e8c4d35a30dd8eee44b95f95dbc673..06a4b847fab8b0d08f892b5b054bc99d37d4be2c 100644
--- a/Control/SGComps/src/ProxyProviderSvc.cxx
+++ b/Control/SGComps/src/ProxyProviderSvc.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include <algorithm>
@@ -261,7 +261,7 @@ ProxyProviderSvc::retrieveProxy(const CLID& id, const std::string& key,
     const EventContext& ctx = contextFromStore (store);
     SG::TransientAddress pTAd (id, key);
     pAPiterator iProvider(m_providers.begin()), iEnd(m_providers.end());
-    for (; iProvider != iEnd; iProvider++) {
+    for (; iProvider != iEnd; ++iProvider) {
       if ( ((*iProvider)->updateAddress(store.storeID(),&pTAd,ctx)).isSuccess() ) 
 	{
 	  pTAd.setProvider(*iProvider, store.storeID());
diff --git a/Control/SGComps/src/SGFolder.h b/Control/SGComps/src/SGFolder.h
index 4bd4d02dc08c73ae0626fecfd463e78a2999ffdc..011fdc7a76a9db2bca4c760ea43b9bcba285e84b 100644
--- a/Control/SGComps/src/SGFolder.h
+++ b/Control/SGComps/src/SGFolder.h
@@ -1,7 +1,7 @@
 // -*- c++ -*-
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef SGCOMPS_FOLDER_H
@@ -46,8 +46,8 @@ namespace SG {
   public:
     /// \name structors
     //@{
-    Folder(const std::string& name, 
-	   const std::string& type,
+    Folder(const std::string& type,
+	   const std::string& name,
 	   const IInterface* parent);
     virtual ~Folder() override;
     //@}
diff --git a/Control/SGMon/SGAudSvc/src/SGAudSvc.cxx b/Control/SGMon/SGAudSvc/src/SGAudSvc.cxx
index 133f4c8b63c733800bdc11e78b0daa04f674b2fe..7af1a51b283e41d929c676b0cfae1f1a69bdb346 100644
--- a/Control/SGMon/SGAudSvc/src/SGAudSvc.cxx
+++ b/Control/SGMon/SGAudSvc/src/SGAudSvc.cxx
@@ -1,7 +1,7 @@
 ///////////////////////// -*- C++ -*- /////////////////////////////
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // SGAudSvc.cxx 
@@ -143,12 +143,12 @@ SGAudSvc::finalize() {
   
   f << "Algs: " << m_vAlg.size() << std::endl;
   std::vector<std::string>::iterator i;
-  for (i=m_vAlg.begin();i<m_vAlg.end();i++) {
+  for (i=m_vAlg.begin();i<m_vAlg.end();++i) {
           f << (*i) << std::endl;
   }
   
   f << "Obj: "<< m_vObj.size()<<std::endl;
-  for (i=m_vObj.begin();i<m_vObj.end();i++) {
+  for (i=m_vObj.begin();i<m_vObj.end();++i) {
           f << (*i) << std::endl; 
   }
 
@@ -405,7 +405,7 @@ SGAudSvc::SGGetCurrentAlg(){
   if (name!=m_currAlg){
     std::vector<std::string>::iterator i;
     int index=0;
-    for (i=m_vAlg.begin();i<m_vAlg.end();i++){
+    for (i=m_vAlg.begin();i<m_vAlg.end();++i){
       if (*i==name) {
 	m_nCurrAlg=index;
 	m_currAlg=name;
@@ -427,7 +427,7 @@ void
 SGAudSvc::getNobj(std::string name){
   std::vector<std::string>::iterator i;
   int index=0;
-  for (i=m_vObj.begin();i<m_vObj.end();i++){
+  for (i=m_vObj.begin();i<m_vObj.end();++i){
     if (*i==name) {
       m_nCurrObj=index;
       m_currObj=name;
diff --git a/Control/SGTools/SGTools/exceptions.h b/Control/SGTools/SGTools/exceptions.h
index 2de48a5cab1753d3793d107addd977c2d71a3eb2..e949c2383e3d8554ee24c7dcded4819f118fc6c3 100644
--- a/Control/SGTools/SGTools/exceptions.h
+++ b/Control/SGTools/SGTools/exceptions.h
@@ -1,7 +1,7 @@
 // This file's extension implies that it's C, but it's really -*- C++ -*-.
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // $Id$
@@ -64,6 +64,7 @@ private:
  * @param id CLID of the DataProxy.
  * @param tid Type to which we're trying to convert the object.
  */
+[[noreturn]]
 void throwExcBadDataProxyCast (CLID id, const std::type_info& tid);
 
 
diff --git a/Control/StoreGate/StoreGate/DataHandle.h b/Control/StoreGate/StoreGate/DataHandle.h
index a3c3a93c65330822cdab0ba620069af4475bcba1..ddd4b87fb1d2839fb0426f42927facf2d31bbe48 100644
--- a/Control/StoreGate/StoreGate/DataHandle.h
+++ b/Control/StoreGate/StoreGate/DataHandle.h
@@ -19,17 +19,6 @@
 #include "CxxUtils/checker_macros.h"
 #include <iterator>
 
-template <typename DATA>
-class DataHandle;
-
-template <class DATA>
-bool operator== (const DataHandle<DATA>& h1,
-                 const DataHandle<DATA>& h2);
-
-template <class DATA>
-bool operator!= (const DataHandle<DATA>& h1,
-                 const DataHandle<DATA>& h2);
-
 /** @class DataHandle
  * @brief an iterator over instances of a given type in StoreGateSvc. It d-casts
  * and caches locally the pointed-at object, to speed-up subsequent accesses.
@@ -131,11 +120,19 @@ public:
   virtual CLID clid() const override { return ClassID_traits<DATA>::ID(); }
 
   friend
-  bool operator==<>(const DataHandle<DATA>& h1,
-                    const DataHandle<DATA>& h2); 
+  bool operator== ATLAS_NOT_THREAD_SAFE (const DataHandle<DATA>& h1,
+                                         const DataHandle<DATA>& h2)
+  {
+    return h1.m_proxy == h2.m_proxy;
+  }
+
   friend
-  bool operator!=<>(const DataHandle<DATA>& h1,
-                    const DataHandle<DATA>& h2); 
+  bool operator!= ATLAS_NOT_THREAD_SAFE (const DataHandle<DATA>& h1,
+                                         const DataHandle<DATA>& h2)
+  {
+    return h1.m_proxy != h2.m_proxy;
+  }
+    
 private:
 
   // OK since DataHandle should only be used locally, not shared between threads.
@@ -146,22 +143,6 @@ private:
 
 };
 
-/// \name Comparison ops (compare proxies)
-//@{
-template <class DATA>
-bool operator== ATLAS_NOT_THREAD_SAFE (const DataHandle<DATA>& h1,
-                                       const DataHandle<DATA>& h2)
-{
-  return (h1.m_proxy == h2.m_proxy); 
-}
-template <class DATA>
-bool operator!= ATLAS_NOT_THREAD_SAFE (const DataHandle<DATA>& h1,
-                                       const DataHandle<DATA>& h2)
-{
-  return (h1.m_proxy != h2.m_proxy); 
-}
-//@}
-
 #include "StoreGate/DataHandle.icc"
 
 /* FIXME LEGACY - No dependency on ActiveStoreSvc here, but a number of Muon AtlasEvent packages are 
diff --git a/Control/StoreGate/StoreGate/StoreGate.h b/Control/StoreGate/StoreGate/StoreGate.h
index 52e83e85cfa5c756ce01ee6dbb50264b29bf5683..d0999a5db85b67723cb1e7774c1c74f696d86304 100644
--- a/Control/StoreGate/StoreGate/StoreGate.h
+++ b/Control/StoreGate/StoreGate/StoreGate.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef STOREGATE_STOREGATE_H
@@ -28,11 +28,11 @@ public:
   static ActiveStoreSvc* activeStoreSvc();
   /** multipleton: get a store by name
    * @param sgID name of the StoreGateSvc ptr to be returned */ 
-  static StoreGateSvc* pointer(std::string sgID); 
+  static StoreGateSvc* pointer(const std::string& sgID); 
   /** multipleton: get a store by name
    *  @param sgID name of the StoreGateSvc ptr to be returned 
    *  @throws std::runtime_error if not found*/ 
-  static StoreGateSvc& instance(std::string sgID);
+  static StoreGateSvc& instance(const std::string& sgID);
   
   friend class NullType; //remove compiler warning
 
diff --git a/Control/StoreGate/StoreGate/tools/SGImplSvc.h b/Control/StoreGate/StoreGate/tools/SGImplSvc.h
index eef4075a2ae3aad74ab94d617c13157db16338a5..7b4034c2ab5548be3a99b3cdf5a324ce2ce529bb 100644
--- a/Control/StoreGate/StoreGate/tools/SGImplSvc.h
+++ b/Control/StoreGate/StoreGate/tools/SGImplSvc.h
@@ -247,14 +247,14 @@ public:
   //@{
 
   /// register a callback function(2) with an already registered function(1)
-  StatusCode regFcn (const CallBackID c1,
-                     const CallBackID c2,
+  StatusCode regFcn (const CallBackID& c1,
+                     const CallBackID& c2,
                      const IOVSvcCallBackFcn& fcn,
                      bool trigger = false);
 
   /// register a callback function(2) with an already registered AlgTool
   StatusCode regFcn (const std::string& toolName,
-                     const CallBackID c2,
+                     const CallBackID& c2,
                      const IOVSvcCallBackFcn& fcn,
                      bool trigger = false);
   
@@ -652,7 +652,7 @@ private:
                                      IResetable* ir, SG::DataProxy *&dp);
   bool bindHandleToProxyAndRegister (const CLID& id, const std::string& key,
                                      IResetable* ir, SG::DataProxy *&dp,
-                                     const CallBackID c,
+                                     const CallBackID& c,
                                      const IOVSvcCallBackFcn& fcn,
                                      bool trigger);
 
diff --git a/Control/StoreGate/src/SGImplSvc.cxx b/Control/StoreGate/src/SGImplSvc.cxx
index 555427a54532885e3d409b48adbae8e80760d16b..502702c18f911116616eac11a4dabdfb8c3c7d7f 100644
--- a/Control/StoreGate/src/SGImplSvc.cxx
+++ b/Control/StoreGate/src/SGImplSvc.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include <algorithm>
@@ -559,8 +559,8 @@ bool SGImplSvc::isSymLinked(const CLID& linkID, DataProxy* dp)
 
 
 StatusCode 
-SGImplSvc::regFcn( const CallBackID c1,
-                   const CallBackID c2,
+SGImplSvc::regFcn( const CallBackID& c1,
+                   const CallBackID& c2,
                    const IOVSvcCallBackFcn& fcn,
                    bool trigger)
 {
@@ -571,7 +571,7 @@ SGImplSvc::regFcn( const CallBackID c1,
 
 StatusCode 
 SGImplSvc::regFcn( const std::string& toolName,
-                   const CallBackID c2,
+                   const CallBackID& c2,
                    const IOVSvcCallBackFcn& fcn,
                    bool trigger)
 {
@@ -1449,7 +1449,7 @@ bool SGImplSvc::bindHandleToProxyAndRegister (const CLID& id, const std::string&
 
 bool SGImplSvc::bindHandleToProxyAndRegister (const CLID& id, const std::string& key,
                                               IResetable* ir, SG::DataProxy *&dp,
-                                              const CallBackID c,
+                                              const CallBackID& c,
                                               const IOVSvcCallBackFcn& fcn,
                                               bool trigger)
 {
diff --git a/Control/StoreGate/src/StoreGate.cxx b/Control/StoreGate/src/StoreGate.cxx
index 4d0a1ff90c684b19c4c33efbd0f43980866f9f12..7d3bccb215702adc027ae0d3a404656c4d5688a3 100644
--- a/Control/StoreGate/src/StoreGate.cxx
+++ b/Control/StoreGate/src/StoreGate.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "StoreGate/StoreGate.h"
@@ -88,13 +88,13 @@ StoreGate::activeStoreSvc() {
 }
 
 StoreGateSvc*
-StoreGate::pointer(std::string sgID) {
+StoreGate::pointer(const std::string& sgID) {
   return getStore(sgID);
 }
 
 
 StoreGateSvc& 
-StoreGate::instance(std::string sgID) {
+StoreGate::instance(const std::string& sgID) {
   StoreGateSvc* ptr(pointer(sgID));
   if (0 == ptr) {
     throw std::runtime_error("Could not locate required StoreGate instance");
diff --git a/Control/StoreGate/test/DataHandle_test.cxx b/Control/StoreGate/test/DataHandle_test.cxx
index 2df9fdbab49c74533ec101c7dcebc9b0417d70bb..e87aabcc07e26243d362721b344b84e94ef735c2 100644
--- a/Control/StoreGate/test/DataHandle_test.cxx
+++ b/Control/StoreGate/test/DataHandle_test.cxx
@@ -142,6 +142,7 @@ namespace Athena_test {
 
     ++dh;
     assert (vp[0]->refCount() == 2);
+    // cppcheck-suppress postfixOperator
     dh2++;
     assert (vp[0]->refCount() == 1);
 
@@ -152,6 +153,7 @@ namespace Athena_test {
     assert (vp[0]->refCount() == 2);
     for (int i=1; i < 4; i++)
       assert (vp[i]->refCount() == 0);
+    // cppcheck-suppress postfixOperator
     dh3++;
     assert (vp[0]->refCount() == 1);
     assert (vp[1]->refCount() == 1);
diff --git a/DataQuality/DataQualityTools/python/DQTDetSynchMonAlg.py b/DataQuality/DataQualityTools/python/DQTDetSynchMonAlg.py
index 01e74965b80006817b883f2bb2f7a7ecbb09d050..859b37791fe51dd692336c48894307383cf0db68 100644
--- a/DataQuality/DataQualityTools/python/DQTDetSynchMonAlg.py
+++ b/DataQuality/DataQualityTools/python/DQTDetSynchMonAlg.py
@@ -173,9 +173,9 @@ if __name__ == '__main__':
     # Initialize configuration object, add accumulator, merge, and run.
     from AthenaConfiguration.MainServicesConfig import MainServicesCfg 
     #from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
-    from ByteStreamCnvSvc.ByteStreamConfig import TrigBSReadCfg
+    from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
     cfg = MainServicesCfg(ConfigFlags)
-    cfg.merge(TrigBSReadCfg(ConfigFlags))
+    cfg.merge(ByteStreamReadCfg(ConfigFlags))
     from TrigInDetConfig.InDetConfig import TrigInDetConfig
     cfg.merge(TrigInDetConfig(ConfigFlags))
 
diff --git a/DataQuality/ZLumiScripts/grid/generateDSFile.py b/DataQuality/ZLumiScripts/grid/generateDSFile.py
new file mode 100755
index 0000000000000000000000000000000000000000..502f0ecd7bc3d1320c7ebac9bc04513e22029ba4
--- /dev/null
+++ b/DataQuality/ZLumiScripts/grid/generateDSFile.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+# helper script to generate JSON file of datasets for batch pathena submission
+
+import sys, json
+prefix = sys.argv[1]
+dslist = sys.argv[2:]
+jlist = []
+for ds in dslist:
+    jlist.append({'inDS': ds, 'outDS': prefix + '.' + ds.split(':')[-1]})
+with open('inOutDs.json', 'w') as ofile:
+    json.dump(jlist, ofile)
diff --git a/DataQuality/ZLumiScripts/grid/grl.py b/DataQuality/ZLumiScripts/grid/grl.py
new file mode 100644
index 0000000000000000000000000000000000000000..d37882385badb4c1dd27cfa8c3af770df2d3d3f9
--- /dev/null
+++ b/DataQuality/ZLumiScripts/grid/grl.py
@@ -0,0 +1,18 @@
+#!/us/bin/env python
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+# Postinclude snippet for Reco_tf to bring in a GRL
+
+from __future__ import print_function
+
+from GoodRunsLists.GoodRunsListsConf import GoodRunsListSelectorTool
+from GoodRunsListsUser.GoodRunsListsUserConf import GRLTriggerSelectorAlg
+from AthenaCommon.AlgSequence import AthSequencer
+import os
+if 'GRL' in os.environ:
+    print('Executing GRL code')
+    ToolSvc += GoodRunsListSelectorTool()
+    ToolSvc.GoodRunsListSelectorTool.GoodRunsListVec = [ os.environ['GRL']  ]
+
+    seq = AthSequencer("AthMasterSeq")
+    seq += GRLTriggerSelectorAlg("GRLAlg")
+    seq.GRLAlg.GoodRunsListArray=[ os.environ['GRLNAME'] ]
diff --git a/DataQuality/ZLumiScripts/grid/merge.py b/DataQuality/ZLumiScripts/grid/merge.py
new file mode 100755
index 0000000000000000000000000000000000000000..2d5b11f0a201b25d763cf83664cad2f9f6b11413
--- /dev/null
+++ b/DataQuality/ZLumiScripts/grid/merge.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+# Simple script to invoke DQHistogramMerge for merging Grid output
+
+from __future__ import print_function
+
+import commands, argparse, sys
+parser = argparse.ArgumentParser()
+parser.add_argument('-o', help='outfilename')
+parser.add_argument('infiles', nargs='+', help='infilenames')
+args=parser.parse_args()
+
+with open('merge.txt', 'w') as txtfile:
+    for f in args.infiles:
+        txtfile.write(f + '\n')
+
+status, output = commands.getstatusoutput('DQHistogramMerge.py merge.txt %s' % args.o)
+print(output)
+sys.exit(status)
+
diff --git a/DataQuality/ZLumiScripts/grid/submission.sh b/DataQuality/ZLumiScripts/grid/submission.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8dcc39619265356c36dbe988ac1623fd7940fc31
--- /dev/null
+++ b/DataQuality/ZLumiScripts/grid/submission.sh
@@ -0,0 +1,100 @@
+#!/bin/bash
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+#
+# Submit pathena jobs to make Z counting HIST files for data
+# Adjust DATASETS and LOWMU variables to configure the job
+# Also see below for commented out code that enables using a GRL
+
+#DATASETS=$(rucio ls 'data16_13TeV.00*physics_Main*.AOD*' --filter account=tzero --short)
+#DATASETS=$(rucio list-content data16_13TeV:data16_13TeV.periodG.physics_Main.PhysCont.AOD.repro21_v01 --short)
+#DATASETS="data18_13TeV.00356124.physics_Main.merge.AOD.f1035_m1999 data18_13TeV.00359823.physics_Main.merge.AOD.f1034_m2020 data18_13TeV.00363738.physics_Main.merge.AOD.f1006_m2037 data18_13TeV.00364292.physics_Main.merge.AOD.f1002_m2037 data18_13TeV.00350361.physics_Main.merge.AOD.f934_m1960"
+
+#DATASETS="data17_13TeV:data17_13TeV.00338834.physics_Main.merge.AOD.r10258_p3399_tid13253867_00"
+#LOWMU=0
+
+# 2017 5 TeV low mu
+#DATASETS=$(rucio list-content data17_5TeV:data17_5TeV.periodM.physics_Main.PhysCont.AOD.pro22_v02 --short)
+#LOWMU=1
+
+# 2017 13 TeV low mu
+#DATASETS=$(rucio list-content data17_13TeV:data17_13TeV.periodN.physics_Main.PhysCont.AOD.pro22_v03 --short)
+#LOWMU=1
+
+# 2018 13 TeV low mu period J
+#DATASETS=$(rucio list-content data18_13TeV:data18_13TeV.periodJ.physics_Main.PhysCont.AOD.t0pro22_v01 --short)
+#LOWMU=1
+
+# 2018 13 TeV low mu period G2
+#DATASETS=$(rucio list-content data18_13TeV:data18_13TeV.periodG2.physics_Main.PhysCont.AOD.t0pro22_v01 --short)
+#LOWMU=1
+
+# 2018 13 TeV low mu period G2
+#DATASETS=$(rucio list-content data18_13TeV:data18_13TeV.periodG4.physics_Main.PhysCont.AOD.t0pro22_v01 --short)
+#LOWMU=1
+
+# 2015 13 TeV high mu
+#DATASETS=$(rucio list-content data15_13TeV:data15_13TeV.periodAllYear.physics_Main.PhysCont.AOD.repro21_v03 --short)
+#LOWMU=0
+
+# 2016 13 TeV high mu
+#DATASETS=$(rucio list-content data16_13TeV:data16_13TeV.periodAllYear.physics_Main.PhysCont.AOD.repro21_v03 --short)
+#LOWMU=0
+
+# 2017 13 TeV high mu
+#DATASETS=$(rucio list-content data17_13TeV:data17_13TeV.periodAllYear.physics_Main.PhysCont.AOD.pro22_v03 --short)
+#LOWMU=0
+
+# 2018 13 TeV high mu
+DATASETS=$(rucio list-content data18_13TeV:data18_13TeV.periodB.physics_Main.PhysCont.AOD.t0pro22_v01 data18_13TeV:data18_13TeV.periodC.physics_Main.PhysCont.AOD.t0pro22_v01 data18_13TeV:data18_13TeV.periodD.physics_Main.PhysCont.AOD.t0pro22_v01 data18_13TeV:data18_13TeV.periodE.physics_Main.PhysCont.AOD.t0pro22_v01 data18_13TeV:data18_13TeV.periodF.physics_Main.PhysCont.AOD.t0pro22_v01 data18_13TeV:data18_13TeV.periodH.physics_Main.PhysCont.AOD.t0pro22_v01 data18_13TeV:data18_13TeV.periodI.physics_Main.PhysCont.AOD.t0pro22_v01 data18_13TeV:data18_13TeV.periodJ.physics_Main.PhysCont.AOD.t0pro22_v01 data18_13TeV:data18_13TeV.periodK.physics_Main.PhysCont.AOD.t0pro22_v01 data18_13TeV:data18_13TeV.periodL.physics_Main.PhysCont.AOD.t0pro22_v01 data18_13TeV:data18_13TeV.periodM.physics_Main.PhysCont.AOD.t0pro22_v01 data18_13TeV:data18_13TeV.periodN.physics_Main.PhysCont.AOD.t0pro22_v01 data18_13TeV:data18_13TeV.periodO.physics_Main.PhysCont.AOD.t0pro22_v01 data18_13TeV:data18_13TeV.periodQ.physics_Main.PhysCont.AOD.t0pro22_v01 --short)
+LOWMU=0
+
+PREFIX=user.ponyisi.2020320a2.merge
+./generateDSFile.py $PREFIX ${DATASETS}
+#POSTEXEC="ToolSvc.DQTMuonSelectionTool.MaxEta=0.9;ToolSvc.DQTGlobalWZFinderTool.MuonMaxEta=0.9"
+#POSTEXEC="pass"
+POSTEXEC="ToolSvc.DQTGlobalWZFinderTool.FillBCIDTrees=True"
+if [[ $LOWMU == 1 ]] ; then {
+    POSTEXEC=${POSTEXEC}";\
+ToolSvc.monTrigTransTool.triggerMapping[\"primary_single_ele_iso\"]=\"\";\
+ToolSvc.monTrigTransTool.triggerMapping[\"primary_single_ele\"]=\"HLT_e15_lhloose_nod0_L1EM12\";\
+ToolSvc.monTrigTransTool.triggerMapping[\"monitoring_muonIso\"]=\"\";\
+ToolSvc.monTrigTransTool.triggerMapping[\"monitoring_muonNonIso\"]=\"HLT_mu14\""
+}; elif [[ $DATASETS == data15* ]] ; then {
+    POSTEXEC=${POSTEXEC}";\
+ToolSvc.monTrigTransTool.triggerMapping[\"primary_single_ele_iso\"]=\"\";\
+ToolSvc.monTrigTransTool.triggerMapping[\"primary_single_ele\"]=\"HLT_e24_lhmedium_L1EM20VH,HLT_e60_lhmedium,HLT_e120_lhloose\";\
+ToolSvc.monTrigTransTool.triggerMapping[\"monitoring_muonIso\"]=\"HLT_mu20_iloose_L1MU15\""
+}; else {
+    POSTEXEC=${POSTEXEC}";\
+ToolSvc.monTrigTransTool.triggerMapping[\"primary_single_ele_iso\"]=\"HLT_e26_lhtight_nod0_ivarloose\";\
+ToolSvc.monTrigTransTool.triggerMapping[\"primary_single_ele\"]=\"HLT_e60_lhmedium_nod0,HLT_e140_lhloose_nod0\""
+    }; fi
+
+if [[ $DATASETS == data18* ]] ; then {
+    export GRL=/cvmfs/atlas.cern.ch/repo/sw/database/GroupData/GoodRunsLists/data18_13TeV/20190318/physics_25ns_Triggerno17e33prim.xml
+    export GRLNAME=PHYS_StandardGRL_All_Good_25ns_Triggerno17e33prim
+} ; elif [[ $DATASETS == data17* ]] ; then {
+    export GRL=/cvmfs/atlas.cern.ch/repo/sw/database/GroupData/GoodRunsLists/data17_13TeV/20180619/physics_25ns_Triggerno17e33prim.xml
+    export GRLNAME=PHYS_StandardGRL_All_Good_25ns_Triggerno17e33prim
+} ; elif [[ $DATASETS == data16* ]] ; then {
+    export GRL=/cvmfs/atlas.cern.ch/repo/sw/database/GroupData/GoodRunsLists/data16_13TeV/20180129/physics_25ns_21.0.19.xml
+    export GRLNAME=PHYS_StandardGRL_All_Good_25ns
+} ; elif [[ $DATASETS == data15* ]] ; then {
+    export GRL=/cvmfs/atlas.cern.ch/repo/sw/database/GroupData/GoodRunsLists/data15_13TeV/20170619/physics_25ns_21.0.19.xml
+    export GRLNAME=PHYS_StandardGRL_All_Good_25ns
+} ; else {
+    export GRL=None
+    export GRLNAME=None
+} ; fi
+
+EXCLUDE=""
+# following gives a GRL filter
+#CMD="export GRL=$GRL;export GRLNAME=$GRLNAME;Reco_tf.py --preExec='rec.doApplyAODFix.set_Value_and_Lock(False);DQMonFlags.set_All_Off();DQMonFlags.doGlobalMon.set_Value_and_Lock(True)' --postExec='$POSTEXEC' --inputAODFile=%IN --outputHIST_AODFile=%OUT.HIST_AOD.root --postInclude='grl.py'"
+CMD="Reco_tf.py --preExec='rec.doApplyAODFix.set_Value_and_Lock(False);DQMonFlags.set_All_Off();DQMonFlags.doGlobalMon.set_Value_and_Lock(True)' --postExec='$POSTEXEC' --inputAODFile=%IN --outputHIST_AODFile=%OUT.HIST_AOD.root"
+
+ADDITIONAL="--addNthFieldOfInDSToLFN=2 --mergeOutput --mergeScript='merge.py' --excludedSite=ANALY_GOEGRID,ANALY_GLASGOW_SL7,UKI-SCOTGRID-GLASGOW,ANALY_LANCS_SL7,ANALY_FZU"
+
+echo pathena $EXCLUDE --trf "$CMD" $ADDITIONAL --inOutDsJson inOutDs.json
+pathena $EXCLUDE --trf "$CMD" $ADDITIONAL --inOutDsJson inOutDs.json
+
+rm inOutDs.json
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx
index 081a7b67d03d8814e6e8415cf8dd7e62f5aeab50..43aa3e70f5fdce131a8ce895101661eb0c5920a0 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx
@@ -30,6 +30,7 @@
 
 #include "AuxDiscoverySvc.h"
 
+#include "boost/algorithm/string.hpp"
 #include <algorithm>
 
 //______________________________________________________________________________
@@ -86,7 +87,7 @@ StatusCode AthenaPoolCnvSvc::initialize() {
    }
    // Extracting MaxFileSizes for global default and map by Database name.
    for (std::vector<std::string>::const_iterator iter = m_maxFileSizes.value().begin(),
-	   last = m_maxFileSizes.value().end(); iter != last; iter++) {
+	   last = m_maxFileSizes.value().end(); iter != last; ++iter) {
       if (iter->find('=') != std::string::npos) {
          long long maxFileSize = atoll(iter->substr(iter->find('=') + 1).c_str());
          if (maxFileSize > 15000000000LL) {
@@ -605,7 +606,7 @@ StatusCode AthenaPoolCnvSvc::commitOutput(const std::string& outputConnectionSpe
       ATH_MSG_ERROR("commitOutput FAILED to cleanup converters.");
       return(StatusCode::FAILURE);
    }
-   for (std::map<void*, RootType>::iterator iter = commitCache.begin(), last = commitCache.end(); iter != last; iter++) {
+   for (std::map<void*, RootType>::iterator iter = commitCache.begin(), last = commitCache.end(); iter != last; ++iter) {
       iter->second.Destruct(iter->first);
    }
    // Check FileSize
@@ -963,15 +964,15 @@ StatusCode AthenaPoolCnvSvc::convertAddress(const IOpaqueAddress* pAddress,
 //__________________________________________________________________________
 StatusCode AthenaPoolCnvSvc::decodeOutputSpec(std::string& fileSpec,
 		int& outputTech) const {
-   if (fileSpec.find("oracle") == 0 || fileSpec.find("mysql") == 0) {
+  if (boost::starts_with (fileSpec, "oracle") || boost::starts_with (fileSpec, "mysql")) {
       outputTech = pool::POOL_RDBMS_StorageType.type();
-   } else if (fileSpec.find("ROOTKEY:") == 0) {
+   } else if (boost::starts_with (fileSpec, "ROOTKEY:")) {
       outputTech = pool::ROOTKEY_StorageType.type();
       fileSpec.erase(0, 8);
-   } else if (fileSpec.find("ROOTTREE:") == 0) {
+   } else if (boost::starts_with (fileSpec, "ROOTTREE:")) {
       outputTech = pool::ROOTTREE_StorageType.type();
       fileSpec.erase(0, 9);
-   } else if (fileSpec.find("ROOTTREEINDEX:") == 0) {
+   } else if (boost::starts_with (fileSpec, "ROOTTREEINDEX:")) {
       outputTech = pool::ROOTTREEINDEX_StorageType.type();
       fileSpec.erase(0, 14);
    } else if (outputTech == 0) {
@@ -1165,7 +1166,6 @@ AthenaPoolCnvSvc::AthenaPoolCnvSvc(const std::string& name, ISvcLocator* pSvcLoc
 	::AthCnvSvc(name, pSvcLocator, POOL_StorageType),
 	m_outputStreamingTool(this)
 {
-   declareProperty("InputStreamingTool", m_inputStreamingTool);
    declareProperty("OutputStreamingTool", m_outputStreamingTool);
 }
 //______________________________________________________________________________
@@ -1179,7 +1179,7 @@ void AthenaPoolCnvSvc::extractPoolAttributes(const StringArrayProperty& property
    std::vector<std::string> opt;
    std::string attributeName, containerName, databaseName, valueString;
    for (std::vector<std::string>::const_iterator iter = property.value().begin(),
-           last = property.value().end(); iter != last; iter++) {
+           last = property.value().end(); iter != last; ++iter) {
       opt.clear();
       attributeName.clear();
       containerName.clear();
@@ -1296,7 +1296,7 @@ StatusCode AthenaPoolCnvSvc::processPoolAttributes(std::vector<std::vector<std::
       if (iter->empty()) {
          iter = attr.erase(iter);
       } else {
-         iter++;
+         ++iter;
       }
    }
    return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h
index 8b7e21d4048deaee48ee594976093deb9190e7e3..be992df67047c1e8ead1062046b54195bb8e1a2f 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h
@@ -183,7 +183,7 @@ private: // data
    ServiceHandle<IChronoStatSvc> m_chronoStatSvc{this,"ChronoStatSvc","ChronoStatSvc"};
    ServiceHandle<IClassIDSvc>    m_clidSvc{this,"ClassIDSvc","ClassIDSvc"};
    ServiceHandle<IAthenaSerializeSvc> m_serializeSvc{this,"AthenaRootSerializeSvc","AthenaRootSerializeSvc"};
-   ToolHandle<IAthenaIPCTool>    m_inputStreamingTool{this,"InputStreamingTool"};
+   ToolHandle<IAthenaIPCTool>    m_inputStreamingTool{this,"InputStreamingTool",{}};
    ToolHandleArray<IAthenaIPCTool>    m_outputStreamingTool;
    //The following doesn't work because of Gaudi issue #122
    //ToolHandleArray<IAthenaIPCTool>    m_outputStreamingTool{this,"OutputStreamingTool", {} };
diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/CMakeLists.txt b/Database/AthenaPOOL/EventSelectorAthenaPool/CMakeLists.txt
index a929c62272a130aa2e1453b4496098238ee1bd15..5d9257e6ba333731796b3039042c1d9cb026f21a 100644
--- a/Database/AthenaPOOL/EventSelectorAthenaPool/CMakeLists.txt
+++ b/Database/AthenaPOOL/EventSelectorAthenaPool/CMakeLists.txt
@@ -39,3 +39,8 @@ atlas_add_component( EventSelectorAthenaPool
 atlas_install_python_modules( python/*.py )
 atlas_install_joboptions( share/*.py )
 
+
+atlas_add_test( CondProxyProviderConfig_test
+                SCRIPT python -m EventSelectorAthenaPool.CondProxyProviderConfig
+                LOG_SELECT_PATTERN "ComponentAccumulator|^---|^CondProxyProvider" )
+
diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/python/CondProxyProviderConfig.py b/Database/AthenaPOOL/EventSelectorAthenaPool/python/CondProxyProviderConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..02ecf31fe608ff70409bf3c17dee80b2bf74d82f
--- /dev/null
+++ b/Database/AthenaPOOL/EventSelectorAthenaPool/python/CondProxyProviderConfig.py
@@ -0,0 +1,44 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+# File: EventSelectorAthenaPool/python/CondProxyProviderConfig.py
+# Created: Jun 2020, sss
+# Purpose: Configure CondProxyProvider.
+
+from __future__ import print_function
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+
+
+def CondProxyProviderCfg (flags, poolFiles):
+    if not isinstance (poolFiles, list):
+        poolFiles = [poolFiles]
+
+    result = ComponentAccumulator()
+
+    ProxyProviderSvc = CompFactory.ProxyProviderSvc # SGComps
+    pps = ProxyProviderSvc (ProviderNames = ['CondProxyProvider'])
+    result.addService (pps)
+    
+    CondProxyProvider = CompFactory.CondProxyProvider # EventSelectorAthenaPool
+    cpp = CondProxyProvider (InputCollections = poolFiles)
+    result.addService (cpp)
+
+    return result
+    
+
+if __name__ == "__main__":
+    from AthenaCommon.Configurable import Configurable
+    Configurable.configurableRun3Behavior=1
+    from AthenaConfiguration.AllConfigFlags import ConfigFlags
+    ConfigFlags.loadAllDynamicFlags()
+
+    flags1 = ConfigFlags.clone()
+    flags1.lock()
+    acc1 = ComponentAccumulator()
+    acc1.merge (CondProxyProviderCfg (flags1, 'file1'))
+    acc1.merge (CondProxyProviderCfg (flags1, ['file2', 'file3']))
+    acc1.printConfig (summariseProps=True)
+    print ('CondProxyProvider:', acc1.getService('CondProxyProvider'))
+    acc1.wasMerged()
+
diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/share/CondProxyProviderConfig_test.ref b/Database/AthenaPOOL/EventSelectorAthenaPool/share/CondProxyProviderConfig_test.ref
new file mode 100644
index 0000000000000000000000000000000000000000..494822f7cad636702a71366ad6d9e155fb9ff209
--- /dev/null
+++ b/Database/AthenaPOOL/EventSelectorAthenaPool/share/CondProxyProviderConfig_test.ref
@@ -0,0 +1,16 @@
+Py:Athena            INFO using release [WorkDir-22.0.15] [x86_64-centos7-gcc8-opt] [config.EventSelectorAthenaPool-20200617/24fa4eb1a41] -- built on [2020-06-17T2014]
+Py:ComponentAccumulator    INFO Event Inputs
+Py:ComponentAccumulator    INFO Event Algorithm Sequences
+Py:ComponentAccumulator    INFO Top sequence 0
+Py:ComponentAccumulator    INFO \__ AthAlgSeq (seq: SEQ AND)
+Py:ComponentAccumulator    INFO Condition Algorithms
+Py:ComponentAccumulator    INFO Services
+Py:ComponentAccumulator    INFO ['ProxyProviderSvc', 'CondProxyProvider']
+Py:ComponentAccumulator    INFO Public Tools
+Py:ComponentAccumulator    INFO [
+Py:ComponentAccumulator    INFO ]
+Py:ComponentAccumulator    INFO Private Tools
+Py:ComponentAccumulator    INFO [
+Py:ComponentAccumulator    INFO ]
+Py:ComponentAccumulator    INFO TheApp properties
+CondProxyProvider: CondProxyProvider('CondProxyProvider', InputCollections=['file1', 'file2', 'file3'])
diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.cxx b/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.cxx
index 9e3b2859b48bf9669ec3ecd0d3cd0bab24b5625b..7d761658725d488bf3379c92b3c8f15894df92f1 100755
--- a/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.cxx
+++ b/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 /** @file CondProxyProvider.cxx
@@ -33,7 +33,6 @@ CondProxyProvider::CondProxyProvider(const std::string& name, ISvcLocator* pSvcL
 	m_athenaPoolCnvSvc("AthenaPoolCnvSvc", name),
 	m_poolCollectionConverter(0),
 	m_headerIterator(0) {
-   declareProperty("InputCollections", m_inputCollectionsProp);
 }
 //________________________________________________________________________________
 CondProxyProvider::~CondProxyProvider() {
diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.h b/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.h
index 761bee1d20cf13d80e5e05a9061d32598b266e1b..6f8d5c0726fa1ac6ad29f18a2776f94be3ba9248 100755
--- a/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.h
+++ b/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef CONDPROXYPROVIDER_H
@@ -63,7 +63,8 @@ private: // data
 
 private: // properties
    /// InputCollections, vector with names of the input collections.
-   StringArrayProperty m_inputCollectionsProp;
+   StringArrayProperty m_inputCollectionsProp
+   { this, "InputCollections", {}, "Files to read", "OrderedSet<std::string>" };
    mutable std::vector<std::string>::const_iterator m_inputCollectionsIterator;
 
 private: // internal helper functions
diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx b/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx
index 29be28acd0d43c82442ad5ecbf0d141b6d70d132..b0cb568783b5c90e33660d28ff0d06076f977360 100644
--- a/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx
+++ b/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx
@@ -883,6 +883,10 @@ StatusCode EventSelectorAthenaPool::share(int evtnum) {
 
 //________________________________________________________________________________
 StatusCode EventSelectorAthenaPool::readEvent(int maxevt) {
+   if (m_eventStreamingTool.empty()) {
+      ATH_MSG_ERROR("No AthenaSharedMemoryTool configured for readEvent()");
+      return(StatusCode::FAILURE);
+   }
    ATH_MSG_VERBOSE("Called read Event " << maxevt);
    IEvtSelector::Context* ctxt = new EventContextAthenaPool(this);
    for (int i = 0; i < maxevt || maxevt == -1; ++i) {
@@ -905,11 +909,12 @@ StatusCode EventSelectorAthenaPool::readEvent(int maxevt) {
       while (m_athenaPoolCnvSvc->readData().isSuccess()) {
          ATH_MSG_VERBOSE("Called last readData, while marking last event in readEvent()");
       }
-// Nothing to do right now, trigger alternative (e.g. caching) here? Currently just fast loop.
+      usleep(1000);
       sc = m_eventStreamingTool->putEvent(0, 0, 0, 0);
    }
    if (!sc.isSuccess()) {
       ATH_MSG_ERROR("Cannot put last Event marker to AthenaSharedMemoryTool");
+      return(StatusCode::FAILURE);
    } else {
       sc = m_athenaPoolCnvSvc->readData();
       while (sc.isSuccess() || sc.isRecoverable()) {
diff --git a/DetectorDescription/Identifier/Identifier/Range.h b/DetectorDescription/Identifier/Identifier/Range.h
index dfdbfcb3004c0814a43719bc443aeb82eafc85ac..d9bdc2e4dd1256766e6b6116839e0792d266f946 100644
--- a/DetectorDescription/Identifier/Identifier/Range.h
+++ b/DetectorDescription/Identifier/Identifier/Range.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef IDENTIFIER_RANGE_H
@@ -582,12 +582,13 @@ Range::field::get_value_at (size_type index) const
     // both_bounded if the more frequent case and so comes first.
 
     if (both_bounded == m_mode) {
+        assert (index < (size_type) (m_maximum - m_minimum + 1));
 	return (m_minimum + index); 
 //  	if (index >= (size_type) (m_maximum - m_minimum + 1)) return (0); 
 //  	else return (m_minimum + index); 
     }
     else if (enumerated == m_mode) {
-	return (m_values[index]); 
+        return (m_values.at(index)); 
 //        if (index >= m_values.size ()) return (0); 
 //        else return (m_values[index]); 
     }
diff --git a/DetectorDescription/RegSelLUT/RegSelLUT/IRegionIDLUT_Creator.h b/DetectorDescription/RegSelLUT/RegSelLUT/IRegionIDLUT_Creator.h
index ad345258093eaa2faa1a4a6f0f62195a2afb443e..3bb923907880813c18864ebac55e1978fa0b8d00 100644
--- a/DetectorDescription/RegSelLUT/RegSelLUT/IRegionIDLUT_Creator.h
+++ b/DetectorDescription/RegSelLUT/RegSelLUT/IRegionIDLUT_Creator.h
@@ -34,7 +34,7 @@ public:
   virtual StatusCode finalize()=0;       /// standard AlgTool method
 
   /// abstract base method for retrieving the table
-  virtual RegSelSiLUT* getLUT() const = 0;
+  virtual RegSelSiLUT* getLUT() = 0;
 
 };
 
diff --git a/DetectorDescription/RegionSelector/python/RegSelConfig.py b/DetectorDescription/RegionSelector/python/RegSelConfig.py
index 29984e3bf91c062565f411a85d397963af9003ae..a440fb5b4393ce3c5778f31698e647a8eeea144d 100644
--- a/DetectorDescription/RegionSelector/python/RegSelConfig.py
+++ b/DetectorDescription/RegionSelector/python/RegSelConfig.py
@@ -136,8 +136,8 @@ if __name__ == "__main__":
     #    cfg.merge( PoolReadCfg( ConfigFlags ) )
 
     
-    from ByteStreamCnvSvc.ByteStreamConfig import TrigBSReadCfg
-    cfg.merge(TrigBSReadCfg( ConfigFlags ))
+    from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
+    cfg.merge(ByteStreamReadCfg( ConfigFlags ))
     
     
     acc = regSelCfg( ConfigFlags )
diff --git a/DetectorDescription/RegionSelector/python/RegSelToolConfig.py b/DetectorDescription/RegionSelector/python/RegSelToolConfig.py
index 8c73cbe2dc438c32954f2e71a0ccdddf9bdc63e4..82bbf82c5ae8cd9210c14793f8c2d950ed444606 100644
--- a/DetectorDescription/RegionSelector/python/RegSelToolConfig.py
+++ b/DetectorDescription/RegionSelector/python/RegSelToolConfig.py
@@ -175,9 +175,34 @@ def makeRegSelTool_TILE() :
 
 ##### new JO counterparts
 
-def regSelToolMDTCfg(flags):
+# muon spectrometer
+
+def regSelToolCfg(flags, detector, CondAlg, CablingConfigCfg=0):
     from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
     ca = ComponentAccumulator()
-    ca.setPrivateTools( _createRegSelTool( "MDT", True ) )
-    ca.addCondAlgo( _createRegSelCondAlg( "MDT", CompFactory.MDT_RegSelCondAlg ) )
+    if(CablingConfigCfg != 0):
+        ca.merge(CablingConfigCfg(flags))
+    ca.setPrivateTools(_createRegSelTool(detector, True))
+    ca.addCondAlgo(_createRegSelCondAlg(detector, CondAlg))
     return ca
+
+def regSelTool_MDT_Cfg(flags):
+    from MuonConfig.MuonCablingConfig import MDTCablingConfigCfg
+    return regSelToolCfg(flags, "MDT", CompFactory.MDT_RegSelCondAlg, MDTCablingConfigCfg)
+
+def regSelTool_RPC_Cfg(flags):
+    from MuonConfig.MuonCablingConfig import RPCCablingConfigCfg
+    return regSelToolCfg(flags, "RPC", CompFactory.RPC_RegSelCondAlg, RPCCablingConfigCfg)
+
+def regSelTool_TGC_Cfg(flags):
+    from MuonConfig.MuonCablingConfig import TGCCablingConfigCfg
+    return regSelToolCfg(flags, "TGC", CompFactory.TGC_RegSelCondAlg, TGCCablingConfigCfg)
+
+def regSelTool_CSC_Cfg(flags):
+    return regSelToolCfg(flags, "CSC", CompFactory.CSC_RegSelCondAlg)
+
+def regSelTool_STGC_Cfg(flags):
+    return regSelToolCfg(flags, "STGC", CompFactory.STGC_RegSelCondAlg)
+
+def regSelTool_MM_Cfg(flags):
+    return regSelToolCfg(flags, "MM", CompFactory.MM_RegSelCondAlg)
diff --git a/Event/ByteStreamCnvSvc/ByteStreamCnvSvc/ByteStreamCnvSvc.h b/Event/ByteStreamCnvSvc/ByteStreamCnvSvc/ByteStreamCnvSvc.h
index 3fe4f35c9a7e6985a85c1b6979ae0d42af763921..f8123fe9aaa23c7325f4628a471e3900a628b29a 100644
--- a/Event/ByteStreamCnvSvc/ByteStreamCnvSvc/ByteStreamCnvSvc.h
+++ b/Event/ByteStreamCnvSvc/ByteStreamCnvSvc/ByteStreamCnvSvc.h
@@ -60,7 +60,7 @@ private:
    std::string m_ioSvcName;
 
    /// list of service names
-   Gaudi::Property<std::vector<std::string>> m_ioSvcNameList{ this, "ByteStreamOutputSvcList", {}, "", "Set<T>"};
+   Gaudi::Property<std::vector<std::string>> m_ioSvcNameList{ this, "ByteStreamOutputSvcList", {}, "", "OrderedSet<T>"};
    
    /// Services for writing output
    std::map<std::string, ByteStreamOutputSvc*> m_ioSvcMap;
diff --git a/Event/ByteStreamCnvSvc/python/ByteStreamConfig.py b/Event/ByteStreamCnvSvc/python/ByteStreamConfig.py
index 17fbb7de231d8145d8c5eae3c138e49e6cd08a16..de44b7f9143ca2463b142b824a866d020410ec03 100644
--- a/Event/ByteStreamCnvSvc/python/ByteStreamConfig.py
+++ b/Event/ByteStreamCnvSvc/python/ByteStreamConfig.py
@@ -64,11 +64,6 @@ def ByteStreamReadCfg( inputFlags, typeNames=[] ):
 
     return acc
 
-def TrigBSReadCfg( flags, typeNames=[] ):
-    # TODO: Search and replace all clients to use ByteStreamReadCfg directly, then remove TrigBSReadCfg
-    return ByteStreamReadCfg( flags, typeNames )
-
-
 def ByteStreamWriteCfg( flags, typeNames=[] ):
     acc = ComponentAccumulator("AthOutSeq")
     outputSvc = CompFactory.ByteStreamEventStorageOutputSvc()
@@ -106,6 +101,6 @@ if __name__ == "__main__":
 
     ConfigFlags.Input.Files = defaultTestFiles.RAW
 
-    acc = TrigBSReadCfg( ConfigFlags )
+    acc = ByteStreamReadCfg( ConfigFlags )
     acc.store( open( "test.pkl", "wb" ) )
     print("All OK")
diff --git a/Event/ByteStreamCnvSvc/src/EventSelectorByteStream.cxx b/Event/ByteStreamCnvSvc/src/EventSelectorByteStream.cxx
index 81355fb6fe19d372fc4270ef5559a573635d749f..4c944dc7eaa0038287b99d831b41127542092520 100644
--- a/Event/ByteStreamCnvSvc/src/EventSelectorByteStream.cxx
+++ b/Event/ByteStreamCnvSvc/src/EventSelectorByteStream.cxx
@@ -448,6 +448,19 @@ StatusCode EventSelectorByteStream::next(IEvtSelector::Context& it) const {
          ATH_MSG_DEBUG("Skipping event " << m_NumEvents - 1);
       }
    } // for loop
+   if (!m_eventStreamingTool.empty() && m_eventStreamingTool->isServer()) { // For SharedReader Server, put event into SHM
+      const RawEvent* pre = 0;
+      pre = m_eventSource->currentEvent();
+      StatusCode sc = m_eventStreamingTool->putEvent(m_NumEvents - 1, pre->start(), pre->fragment_size_word() * sizeof(uint32_t), m_eventSource->currentEventStatus());
+      while (sc.isRecoverable()) {
+         usleep(1000);
+         sc = m_eventStreamingTool->putEvent(m_NumEvents - 1, pre->start(), pre->fragment_size_word() * sizeof(uint32_t), m_eventSource->currentEventStatus());
+      }
+      if (!sc.isSuccess()) {
+         ATH_MSG_ERROR("Cannot put Event " << m_NumEvents - 1 << " to AthenaSharedMemoryTool");
+         return(StatusCode::FAILURE);
+      }
+   }
    return(StatusCode::SUCCESS);
 }
 
@@ -868,11 +881,11 @@ StatusCode EventSelectorByteStream::share(int evtNum) {
 //________________________________________________________________________________
 StatusCode EventSelectorByteStream::readEvent(int maxevt) {
    if (m_eventStreamingTool.empty()) {
+      ATH_MSG_ERROR("No AthenaSharedMemoryTool configured for readEvent()");
       return(StatusCode::FAILURE);
    }
    ATH_MSG_VERBOSE("Called read Event " << maxevt);
    for (int i = 0; i < maxevt || maxevt == -1; ++i) {
-      //const RawEvent* pre = m_eventSource->nextEvent();
       const RawEvent* pre = 0;
       if (this->next(*m_beginIter).isSuccess()) {
          pre = m_eventSource->currentEvent();
@@ -884,18 +897,6 @@ StatusCode EventSelectorByteStream::readEvent(int maxevt) {
          ATH_MSG_ERROR("Unable to retrieve next event for " << i << "/" << maxevt);
          return(StatusCode::FAILURE);
       }
-      if (pre == 0) {
-         // End of file, wait for last event to be taken
-         StatusCode sc = m_eventStreamingTool->putEvent(0, 0, 0, 0);
-         while (sc.isRecoverable()) {
-            usleep(1000);
-            sc = m_eventStreamingTool->putEvent(0, 0, 0, 0);
-         }
-         if (!sc.isSuccess()) {
-            ATH_MSG_ERROR("Cannot put last Event marker to AthenaSharedMemoryTool");
-         }
-         return(StatusCode::FAILURE);
-      }
       if (m_eventStreamingTool->isServer()) {
          StatusCode sc = m_eventStreamingTool->putEvent(m_NumEvents - 1, pre->start(), pre->fragment_size_word() * sizeof(uint32_t), m_eventSource->currentEventStatus());
          while (sc.isRecoverable()) {
@@ -908,6 +909,16 @@ StatusCode EventSelectorByteStream::readEvent(int maxevt) {
          }
       }
    }
+   // End of file, wait for last event to be taken
+   StatusCode sc = m_eventStreamingTool->putEvent(0, 0, 0, 0);
+   while (sc.isRecoverable()) {
+      usleep(1000);
+      sc = m_eventStreamingTool->putEvent(0, 0, 0, 0);
+   }
+   if (!sc.isSuccess()) {
+      ATH_MSG_ERROR("Cannot put last Event marker to AthenaSharedMemoryTool");
+      return(StatusCode::FAILURE);
+   }
    return(StatusCode::SUCCESS);
 }
 
diff --git a/Event/FourMom/FourMom/FourMomentumError.icc b/Event/FourMom/FourMom/FourMomentumError.icc
index 1692cd4b7a47e66c0a01600fb466be9616ea4fed..770301b831457ee66ba5716f1c212664c0fa0d78 100644
--- a/Event/FourMom/FourMom/FourMomentumError.icc
+++ b/Event/FourMom/FourMom/FourMomentumError.icc
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "FourMom/ErrorMatrixBase.h"
@@ -65,19 +65,19 @@ FourMomentumError< FourMom>::FourMomentumError( const CLHEP::HepSymMatrix& m,
   m_PtCotThPhiM(nullptr)
 {
   if ( t == PxPyPzE) {
-    m_PxPyPzE = std::make_unique<ErrorMatrixPxPyPzE>( m);
+    m_PxPyPzE.store (std::make_unique<ErrorMatrixPxPyPzE>( m));
     m_originalType = PxPyPzE;
   }
   if ( t == EEtaPhiM) {
-    m_EEtaPhiM = std::make_unique<ErrorMatrixEEtaPhiM>( m);
+    m_EEtaPhiM.store (std::make_unique<ErrorMatrixEEtaPhiM>( m));
     m_originalType = EEtaPhiM;
   }
   if ( t == PtEtaPhiM) {
-    m_PtEtaPhiM = std::make_unique<ErrorMatrixPtEtaPhiM>( m);
+    m_PtEtaPhiM.store (std::make_unique<ErrorMatrixPtEtaPhiM>( m));
     m_originalType = PtEtaPhiM;
   }
   if ( t == PtCotThPhiM) {
-    m_PtCotThPhiM = std::make_unique<ErrorMatrixPtCotThPhiM>( m);
+    m_PtCotThPhiM.store (std::make_unique<ErrorMatrixPtCotThPhiM>( m));
     m_originalType = PtCotThPhiM;
   }
 }
@@ -93,16 +93,16 @@ FourMomentumError< FourMom>::FourMomentumError( const FourMomentumError& other)
   m_originalType( other.originalType())
 {
   if (other.originalType() == PxPyPzE) {
-    m_PxPyPzE = new ErrorMatrixPxPyPzE( *other.pxPyPzEMatrix());
+    m_PxPyPzE.store (std::make_unique<ErrorMatrixPxPyPzE>( *other.pxPyPzEMatrix()));
   }
   else if (other.originalType() == EEtaPhiM) {
-    m_EEtaPhiM = new ErrorMatrixEEtaPhiM(*other.eEtaPhiMMatrix());
+    m_EEtaPhiM.store (std::make_unique<ErrorMatrixEEtaPhiM>(*other.eEtaPhiMMatrix()));
   }
   else if (other.originalType() == PtEtaPhiM) {
-    m_PtEtaPhiM = new ErrorMatrixPtEtaPhiM( *other.ptEtaPhiMMatrix());
+    m_PtEtaPhiM.store (std::make_unique<ErrorMatrixPtEtaPhiM>( *other.ptEtaPhiMMatrix()));
   }
   else if (other.originalType() == PtCotThPhiM) {
-    m_PtCotThPhiM = new ErrorMatrixPtCotThPhiM( *other.ptCotThPhiMMatrix());
+    m_PtCotThPhiM.store (std::make_unique<ErrorMatrixPtCotThPhiM>( *other.ptCotThPhiMMatrix()));
   }
 }
 
@@ -112,23 +112,23 @@ FourMomentumError< FourMom> &FourMomentumError<FourMom>::operator=( const FourMo
 {
   if (this!=&other){
     m_p4( other.m_p4);
-    m_PxPyPzE = std::make_unique<ErrorMatrixPxPyPzE>();
-    m_EEtaPhiM = std::make_unique<ErrorMatrixEEtaPhiM>();
-    m_PtEtaPhiM = std::make_unique<ErrorMatrixPtEtaPhiM>();
-    m_PtCotThPhiM = std::make_unique<ErrorMatrixPtCotThPhiM>();
+    m_PxPyPzE.store (std::make_unique<ErrorMatrixPxPyPzE>());
+    m_EEtaPhiM.store (std::make_unique<ErrorMatrixEEtaPhiM>());
+    m_PtEtaPhiM.store (std::make_unique<ErrorMatrixPtEtaPhiM>());
+    m_PtCotThPhiM.store (std::make_unique<ErrorMatrixPtCotThPhiM>());
     m_originalType = other.originalType();
 
     if (other.originalType() == PxPyPzE) {
-      m_PxPyPzE = new ErrorMatrixPxPyPzE( *other.pxPyPzEMatrix());
+      m_PxPyPzE.store (std::make_unique<ErrorMatrixPxPyPzE>( *other.pxPyPzEMatrix()));
     }
     else if (other.originalType() == EEtaPhiM) {
-      m_EEtaPhiM = new ErrorMatrixEEtaPhiM(*other.eEtaPhiMMatrix());
+      m_EEtaPhiM.store (std::make_unique<ErrorMatrixEEtaPhiM>(*other.eEtaPhiMMatrix()));
     }
     else if (other.originalType() == PtEtaPhiM) {
-      m_PtEtaPhiM = new ErrorMatrixPtEtaPhiM( *other.ptEtaPhiMMatrix());
+      m_PtEtaPhiM.store (std::make_unique<ErrorMatrixPtEtaPhiM>( *other.ptEtaPhiMMatrix()));
     }
     else if (other.originalType() == PtCotThPhiM) {
-      m_PtCotThPhiM = new ErrorMatrixPtCotThPhiM( *other.ptCotThPhiMMatrix());
+      m_PtCotThPhiM.store (std::make_unique<ErrorMatrixPtCotThPhiM>( *other.ptCotThPhiMMatrix()));
     }
   }
   return *this;
diff --git a/Event/xAOD/xAODCore/Root/AuxContainerBase.cxx b/Event/xAOD/xAODCore/Root/AuxContainerBase.cxx
index a2e52012736a1093594a8bcfcd0233021d0cdefb..361aca988a3ce8f065a50be8165216011b1ebf46 100644
--- a/Event/xAOD/xAODCore/Root/AuxContainerBase.cxx
+++ b/Event/xAOD/xAODCore/Root/AuxContainerBase.cxx
@@ -57,6 +57,7 @@ namespace xAOD {
 
       // Unfortunately the dynamic variables can not be copied this easily...
       if( parent.m_store ) {
+         // cppcheck-suppress copyCtorPointerCopying
          m_store = parent.m_store;
          m_ownsStore = false;
          m_storeIO = dynamic_cast< SG::IAuxStoreIO* >( m_store );
diff --git a/Event/xAOD/xAODCore/Root/AuxInfoBase.cxx b/Event/xAOD/xAODCore/Root/AuxInfoBase.cxx
index b935cc7881134b086630738e6ff96d1a5f3263a4..7b436ed8022df0d5550391118a8cb3aa3cb75873 100644
--- a/Event/xAOD/xAODCore/Root/AuxInfoBase.cxx
+++ b/Event/xAOD/xAODCore/Root/AuxInfoBase.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // $Id: AuxInfoBase.cxx 793737 2017-01-24 20:11:10Z ssnyder $
@@ -55,6 +55,7 @@ namespace xAOD {
 
       // Unfortunately the dynamic variables can not be copied this easily...
       if( parent.m_store ) {
+         // cppcheck-suppress copyCtorPointerCopying
          m_store = parent.m_store;
          m_ownsStore = false;
          m_storeIO = dynamic_cast< SG::IAuxStoreIO* >( m_store );
diff --git a/Event/xAOD/xAODTruthCnv/src/HepMCTruthReader.cxx b/Event/xAOD/xAODTruthCnv/src/HepMCTruthReader.cxx
index bb5b253bb65c2eb86278aa17c086998e27db3f4c..f0ddf24c69f14bbb22d9eee138786cdeb9d4625d 100644
--- a/Event/xAOD/xAODTruthCnv/src/HepMCTruthReader.cxx
+++ b/Event/xAOD/xAODTruthCnv/src/HepMCTruthReader.cxx
@@ -74,14 +74,22 @@ StatusCode HepMCTruthReader::execute() {
 void HepMCTruthReader::printEvent(const HepMC::GenEvent* event) {
   cout << "--------------------------------------------------------------------------------\n";
   cout << "GenEvent: #" << "NNN" << "\n";
+#ifdef HEPMC3 
+  cout << " Entries this event: " << event->vertices().size() << " vertices, " << event->particles().size() << " particles.\n";
+#else 
   cout << " Entries this event: " << event->vertices_size() << " vertices, " << event->particles_size() << " particles.\n";
   // Particles and vertices
+#endif
   cout << "                                    GenParticle Legend\n";
   cout << "        Barcode   PDG ID      ( Px,       Py,       Pz,     E ) Stat  DecayVtx\n";
   cout << "--------------------------------------------------------------------------------\n";
+#ifdef HEPMC3
+  for (auto iv: ((HepMC::GenEvent*)event)->vertices()) {  printVertex(iv);  } 
+#else
   for (HepMC::GenEvent::vertex_const_iterator iv = event->vertices_begin(); iv != event->vertices_end(); ++iv) {
     printVertex(*iv);
   }
+#endif
   cout << "--------------------------------------------------------------------------------\n";
 }
 
@@ -130,7 +138,7 @@ void HepMCTruthReader::printVertex(const HepMC::GenVertexPtr vertex) {
     //  print out gives us a unique tag for the particle.
     if (vertex->position().x() != 0.0 && vertex->position().y() != 0.0 && vertex->position().z() != 0.0) {
       cout.width(9);
-      cout << (void*)vertex;
+      cout << HepMC::raw_pointer(vertex);
       cout << " ID:";
       cout.width(5);
       cout << vertex->id();
@@ -154,7 +162,7 @@ void HepMCTruthReader::printVertex(const HepMC::GenVertexPtr vertex) {
       cout << endl;
     } else {
       cout.width(9);
-      cout << (void*)vertex;
+      cout << HepMC::raw_pointer(vertex);
       cout << " ID:";
       cout.width(5);
       cout << vertex->id();
@@ -170,6 +178,24 @@ void HepMCTruthReader::printVertex(const HepMC::GenVertexPtr vertex) {
   //   cout << endl;
   // }
   // Print out all the incoming, then outgoing particles
+#ifdef HEPMC3
+  for (auto  iPIn: vertex->particles_in()) {       
+    if ( iPIn == vertex->particles_in().front() ) {
+      cout << " I: ";
+      cout.width(2);
+      cout << vertex->particles_in().size();
+    } else cout << "      ";
+    printParticle(iPIn);
+  }
+  for (auto iPOut: vertex->particles_out()) {
+    if ( iPOut == vertex->particles_out().front()) {
+      cout << " O: ";
+      cout.width(2);
+      cout << vertex->particles_out().size();
+    } else cout << "      ";
+    printParticle(iPOut);
+  }  
+#else  
   for (HepMC::GenVertex::particles_in_const_iterator iPIn = vertex->particles_in_const_begin();
        iPIn != vertex->particles_in_const_end(); ++iPIn) {       
     if ( iPIn == vertex->particles_in_const_begin() ) {
@@ -189,6 +215,7 @@ void HepMCTruthReader::printVertex(const HepMC::GenVertexPtr vertex) {
     printParticle(*iPOut);
   }
 
+#endif
   cout.flags(f); 
 }
 
diff --git a/Event/xAOD/xAODTruthCnv/src/xAODTruthCnvAlg.cxx b/Event/xAOD/xAODTruthCnv/src/xAODTruthCnvAlg.cxx
index 6a3698116ebbbb21f2f3c51db4daaf87d5774020..a651259d1591ac5a93e84bec59e67bfee291e39e 100644
--- a/Event/xAOD/xAODTruthCnv/src/xAODTruthCnvAlg.cxx
+++ b/Event/xAOD/xAODTruthCnv/src/xAODTruthCnvAlg.cxx
@@ -186,8 +186,13 @@ namespace xAODMaker {
 	    xTruthEventContainer->push_back( xTruthEvent );
 	    // Cross-section
 	    auto crossSection = genEvt->cross_section();
+#ifdef HEPMC3
+	    xTruthEvent->setCrossSection(crossSection ? (float)crossSection->xsec() : -1);
+	    xTruthEvent->setCrossSectionError(crossSection ? (float)crossSection->xsec_err() : -1);
+#else
 	    xTruthEvent->setCrossSection(crossSection ? (float)crossSection->cross_section() : -1);
 	    xTruthEvent->setCrossSectionError(crossSection ? (float)crossSection->cross_section_error() : -1);
+#endif
                     
 	    if (m_writeMetaData) {
 	      //The mcChannelNumber is used as a unique identifier for which truth meta data belongs to
@@ -211,6 +216,22 @@ namespace xAODMaker {
 	    // Heavy ion info
 	    auto const hiInfo = genEvt->heavy_ion();
 	    if (hiInfo) {
+#ifdef HEPMC3
+              /* Please note HepMC3 as well as more recent HePMC2 versions   have more Hi parameters */
+	      xTruthEvent->setHeavyIonParameter(hiInfo->Ncoll_hard, xAOD::TruthEvent::NCOLLHARD);
+	      xTruthEvent->setHeavyIonParameter(hiInfo->Npart_proj, xAOD::TruthEvent::NPARTPROJ);
+	      xTruthEvent->setHeavyIonParameter(hiInfo->Npart_targ, xAOD::TruthEvent::NPARTTARG);
+	      xTruthEvent->setHeavyIonParameter(hiInfo->Ncoll, xAOD::TruthEvent::NCOLL);
+	      xTruthEvent->setHeavyIonParameter(hiInfo->spectator_neutrons, xAOD::TruthEvent::SPECTATORNEUTRONS);
+	      xTruthEvent->setHeavyIonParameter(hiInfo->spectator_protons, xAOD::TruthEvent::SPECTATORPROTONS);
+	      xTruthEvent->setHeavyIonParameter(hiInfo->N_Nwounded_collisions, xAOD::TruthEvent::NNWOUNDEDCOLLISIONS);
+	      xTruthEvent->setHeavyIonParameter(hiInfo->Nwounded_N_collisions, xAOD::TruthEvent::NWOUNDEDNCOLLISIONS);
+	      xTruthEvent->setHeavyIonParameter(hiInfo->Nwounded_Nwounded_collisions, xAOD::TruthEvent::NWOUNDEDNWOUNDEDCOLLISIONS);
+	      xTruthEvent->setHeavyIonParameter((float)hiInfo->impact_parameter, xAOD::TruthEvent::IMPACTPARAMETER);
+	      xTruthEvent->setHeavyIonParameter((float)hiInfo->event_plane_angle, xAOD::TruthEvent::EVENTPLANEANGLE);
+	      xTruthEvent->setHeavyIonParameter((float)hiInfo->eccentricity, xAOD::TruthEvent::ECCENTRICITY);
+	      xTruthEvent->setHeavyIonParameter((float)hiInfo->sigma_inel_NN, xAOD::TruthEvent::SIGMAINELNN);
+#else
 	      xTruthEvent->setHeavyIonParameter(hiInfo->Ncoll_hard(), xAOD::TruthEvent::NCOLLHARD);
 	      xTruthEvent->setHeavyIonParameter(hiInfo->Npart_proj(), xAOD::TruthEvent::NPARTPROJ);
 	      xTruthEvent->setHeavyIonParameter(hiInfo->Npart_targ(), xAOD::TruthEvent::NPARTTARG);
@@ -224,6 +245,7 @@ namespace xAODMaker {
 	      xTruthEvent->setHeavyIonParameter(hiInfo->event_plane_angle(), xAOD::TruthEvent::EVENTPLANEANGLE);
 	      xTruthEvent->setHeavyIonParameter(hiInfo->eccentricity(), xAOD::TruthEvent::ECCENTRICITY);
 	      xTruthEvent->setHeavyIonParameter(hiInfo->sigma_inel_NN(), xAOD::TruthEvent::SIGMAINELNN);
+#endif
 	      // This doesn't yet exist in our version of HepMC
 	      // xTruthEvent->setHeavyIonParameter(hiInfo->centrality(),xAOD::TruthEvent::CENTRALITY);
 	    }
@@ -232,6 +254,18 @@ namespace xAODMaker {
 	    // This will exist 99% of the time, except for e.g. cosmic or particle gun simulation
 	    auto const pdfInfo = genEvt->pdf_info();
 	    if (pdfInfo) {
+#ifdef HEPMC3
+	      xTruthEvent->setPdfInfoParameter(pdfInfo->parton_id[0], xAOD::TruthEvent::PDGID1);
+	      xTruthEvent->setPdfInfoParameter(pdfInfo->parton_id[1], xAOD::TruthEvent::PDGID2);
+	      xTruthEvent->setPdfInfoParameter(pdfInfo->pdf_id[1], xAOD::TruthEvent::PDFID1);
+	      xTruthEvent->setPdfInfoParameter(pdfInfo->pdf_id[1], xAOD::TruthEvent::PDFID2);
+                        
+	      xTruthEvent->setPdfInfoParameter((float)pdfInfo->x[0], xAOD::TruthEvent::X1);
+	      xTruthEvent->setPdfInfoParameter((float)pdfInfo->x[1], xAOD::TruthEvent::X2);
+	      xTruthEvent->setPdfInfoParameter((float)pdfInfo->scale, xAOD::TruthEvent::Q);
+	      xTruthEvent->setPdfInfoParameter((float)pdfInfo->xf[0], xAOD::TruthEvent::XF1);
+	      xTruthEvent->setPdfInfoParameter((float)pdfInfo->xf[1], xAOD::TruthEvent::XF2);
+#else
 	      xTruthEvent->setPdfInfoParameter(pdfInfo->id1(), xAOD::TruthEvent::PDGID1);
 	      xTruthEvent->setPdfInfoParameter(pdfInfo->id2(), xAOD::TruthEvent::PDGID2);
 	      xTruthEvent->setPdfInfoParameter(pdfInfo->pdf_id1(), xAOD::TruthEvent::PDFID1);
@@ -242,6 +276,7 @@ namespace xAODMaker {
 	      xTruthEvent->setPdfInfoParameter((float)pdfInfo->scalePDF(), xAOD::TruthEvent::Q);
 	      xTruthEvent->setPdfInfoParameter((float)pdfInfo->pdf1(), xAOD::TruthEvent::XF1);
 	      xTruthEvent->setPdfInfoParameter((float)pdfInfo->pdf2(), xAOD::TruthEvent::XF2);
+#endif
 	    }
 	  }
 	  if (!isSignalProcess) xTruthPileupEventContainer->push_back( xTruthPileupEvent );
@@ -258,8 +293,13 @@ namespace xAODMaker {
 	  // If this is a disconnected vertex, add it manually or won't be added from the loop over particles below.
 	   auto disconnectedSignalProcessVtx = HepMC::signal_process_vertex((HepMC::GenEvent*)genEvt); // Get the signal process vertex
 	  if (disconnectedSignalProcessVtx) {
+#ifdef HEPMC3
+	    if (disconnectedSignalProcessVtx->particles_in().size() == 0 &&
+		disconnectedSignalProcessVtx->particles_out().size() == 0 ) {
+#else
 	    if (disconnectedSignalProcessVtx->particles_in_size() == 0 &&
 		disconnectedSignalProcessVtx->particles_out_size() == 0 ) {
+#endif
 	      //This is a disconnected vertex, add it manually
 	      vertices.push_back (disconnectedSignalProcessVtx);
 	    }
@@ -270,31 +310,37 @@ namespace xAODMaker {
 	  // Get the beam particles
 	  pair<HepMC::GenParticlePtr,HepMC::GenParticlePtr> beamParticles;
 	  bool genEvt_valid_beam_particles=false;
+#ifdef HEPMC3
+	  auto beamParticles_vec = ((HepMC::GenEvent*)genEvt)->beams();
+	  genEvt_valid_beam_particles=(beamParticles_vec.size()>1);
+	  if (genEvt_valid_beam_particles){beamParticles.first=beamParticles_vec[0]; beamParticles.second=beamParticles_vec[1]; }
+#else	  
           genEvt_valid_beam_particles=genEvt->valid_beam_particles();
 	  if ( genEvt_valid_beam_particles ) beamParticles = genEvt->beam_particles();
-	  for (HepMC::GenEvent::particle_const_iterator pitr=genEvt->particles_begin(); pitr!=genEvt->particles_end(); ++pitr) {
+#endif 
+	  for (auto  part: *((HepMC::GenEvent*)genEvt)) {
 	    // (a) create TruthParticle
 	    xAOD::TruthParticle* xTruthParticle = new xAOD::TruthParticle();
 	    xTruthParticleContainer->push_back( xTruthParticle );
-	    fillParticle(xTruthParticle, *pitr); // (b) Copy HepMC info into the new particle
+	    fillParticle(xTruthParticle, part); // (b) Copy HepMC info into the new particle
 	    // (c) Put particle into container; Build Event<->Particle element link
 	    const ElementLink<xAOD::TruthParticleContainer> eltp(*xTruthParticleContainer, xTruthParticleContainer->size()-1);
 	    if (isSignalProcess) xTruthEvent->addTruthParticleLink(eltp);
 	    if (!isSignalProcess) xTruthPileupEvent->addTruthParticleLink(eltp);
                     
 	    // Create link between HepMC and xAOD truth
-	    if (isSignalProcess) truthLinkVec->push_back(new xAODTruthParticleLink(HepMcParticleLink((*pitr),0,EBC_MAINEVCOLL,HepMcParticleLink::IS_POSITION), eltp));
-	    if (!isSignalProcess) truthLinkVec->push_back(new xAODTruthParticleLink(HepMcParticleLink((*pitr),genEvt->event_number()), eltp));
+	    if (isSignalProcess) truthLinkVec->push_back(new xAODTruthParticleLink(HepMcParticleLink(part,0,EBC_MAINEVCOLL,HepMcParticleLink::IS_POSITION), eltp));
+	    if (!isSignalProcess) truthLinkVec->push_back(new xAODTruthParticleLink(HepMcParticleLink(part,genEvt->event_number()), eltp));
                     
 	    // Is this one of the beam particles?
 	    if (genEvt_valid_beam_particles) {
 	      if (isSignalProcess) {
-		if (*pitr == beamParticles.first) xTruthEvent->setBeamParticle1Link(eltp);
-		if (*pitr == beamParticles.second) xTruthEvent->setBeamParticle2Link(eltp);
+		if (part == beamParticles.first) xTruthEvent->setBeamParticle1Link(eltp);
+		if (part == beamParticles.second) xTruthEvent->setBeamParticle2Link(eltp);
 	      }
 	    }
 	    // (d) Particle's production vertex
-	    auto productionVertex = (*pitr)->production_vertex();
+	    auto productionVertex = part->production_vertex();
 	    if (productionVertex) {
 	      VertexParticles& parts = vertexMap[productionVertex];
 	      if (parts.incoming.empty() && parts.outgoing.empty())
@@ -306,7 +352,7 @@ namespace xAODMaker {
 	    // else maybe want to keep track that this is the production vertex
 	    //
 	    // (e) Particle's decay vertex
-	    auto decayVertex = (*pitr)->end_vertex();
+	    auto decayVertex = part->end_vertex();
 	    if (decayVertex) {
 	      VertexParticles& parts = vertexMap[decayVertex];
 	      if (parts.incoming.empty() && parts.outgoing.empty())
@@ -378,7 +424,7 @@ namespace xAODMaker {
         tp->setBarcode(HepMC::barcode(gp));
         tp->setStatus(gp->status());
         
-        const HepMC::Polarization& pol = gp->polarization();
+        auto pol = HepMC::polarization(gp);
         if (pol.is_defined()) {
             tp->setPolarizationParameter(pol.theta(), xAOD::TruthParticle::polarizationTheta);
             tp->setPolarizationParameter(pol.phi(), xAOD::TruthParticle::polarizationPhi);
@@ -424,6 +470,12 @@ namespace xAODMaker {
         m_tmd->push_back (std::make_unique <xAOD::TruthMetaData>());
         xAOD::TruthMetaData* md = m_tmd->back();
         
+#ifdef HEPMC3
+        ///Here comes the fix. Note that HepMC2.06.11 also contains the fix
+        md->setMcChannelNumber(mcChannelNumber);
+        std::vector<std::string> orderedWeightNameVec=genEvt.weight_names();
+        md->setWeightNames(orderedWeightNameVec);
+#else 
         // FIXME: class member protection violation here.
         // This appears to be because WeightContainer has no public methods
         // to get information about the weight names.
@@ -441,6 +493,7 @@ namespace xAODMaker {
                             
         md->setMcChannelNumber(mcChannelNumber);
         md->setWeightNames( std::move(orderedWeightNameVec) );
+#endif
       }
 
       return StatusCode::SUCCESS;
diff --git a/Event/xAOD/xAODTruthCnv/src/xAODTruthCnvAlg.h b/Event/xAOD/xAODTruthCnv/src/xAODTruthCnvAlg.h
index 79513e702cc8e194d2bc92c808b83ce6b2163abb..7dbd7ab41667eb48444a5b64a6b73fc413ab5ffd 100644
--- a/Event/xAOD/xAODTruthCnv/src/xAODTruthCnvAlg.h
+++ b/Event/xAOD/xAODTruthCnv/src/xAODTruthCnvAlg.h
@@ -7,6 +7,9 @@
 
 #include "AthenaBaseComps/AthReentrantAlgorithm.h"
 
+#ifdef HEPMC3
+// This form of ifdef is kept for convenience
+#else
 // The lines below I don't like. We should fix them when we update the
 // the metadata to handles (ATLASRECTS-4162).
 // Needs changes in HepMC to resolve.
@@ -20,6 +23,7 @@
 #ifdef __clang__
 #pragma clang diagnostic pop
 #endif
+#endif
 
 #include "GeneratorObjects/xAODTruthParticleLink.h"
 #include "GeneratorObjects/McEventCollection.h"
@@ -39,6 +43,8 @@
 #include <unordered_set>
 
 
+#include "AtlasHepMC/WeightContainer.h"
+#include "AtlasHepMC/Polarization.h"
 #include "AtlasHepMC/GenVertex_fwd.h"
 #include "AtlasHepMC/GenParticle_fwd.h"
 
diff --git a/ForwardDetectors/ForwardSimulation/ForwardRegionMgField/CMakeLists.txt b/ForwardDetectors/ForwardSimulation/ForwardRegionMgField/CMakeLists.txt
index cace318da5ffb1225706a018181842e05781ddb1..c8521a440393a8e4054e01b65be4724a72439f5f 100644
--- a/ForwardDetectors/ForwardSimulation/ForwardRegionMgField/CMakeLists.txt
+++ b/ForwardDetectors/ForwardSimulation/ForwardRegionMgField/CMakeLists.txt
@@ -23,7 +23,7 @@ atlas_add_component( ForwardRegionMgField
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${GEANT4_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${GEANT4_LIBRARIES} ${XERCESC_LIBRARIES} ${CLHEP_LIBRARIES} GaudiKernel AthenaBaseComps MagFieldInterfaces PathResolver )
+                     LINK_LIBRARIES ${GEANT4_LIBRARIES} ${XERCESC_LIBRARIES} ${CLHEP_LIBRARIES} GaudiKernel AthenaBaseComps MagFieldInterfaces PathResolver ForwardRegionGeoModelLib )
 
 # Install files from the package:
 atlas_install_runtime( share/*.dat )
diff --git a/ForwardDetectors/ForwardTransportSvc/CMakeLists.txt b/ForwardDetectors/ForwardTransportSvc/CMakeLists.txt
index ce54b1424631e843ecd30a5f1a5abbb1d59737ee..24b09cfe5c3e9065523a92079bf4cb27bcb21dc6 100644
--- a/ForwardDetectors/ForwardTransportSvc/CMakeLists.txt
+++ b/ForwardDetectors/ForwardTransportSvc/CMakeLists.txt
@@ -20,15 +20,21 @@ find_package( Geant4 )
 find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
 find_package( XercesC )
 
+atlas_add_library( ForwardTransportSvcLib
+                   ForwardTransportSvc/*.h
+                   INTERFACE
+                   PUBLIC_HEADERS ForwardTransportSvc
+                   INCLUDE_DIRS ${GEANT4_INCLUDE_DIRS}
+                   LINK_LIBRARIES GaudiKernel AtlasHepMCLib ForwardTracker )
+
 # Component(s) in the package:
 atlas_add_component( ForwardTransportSvc
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${GEANT4_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} 
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${XERCESC_LIBRARIES} ${GEANT4_LIBRARIES} ${CLHEP_LIBRARIES} AtlasHepMCLib ForwardTracker GaudiKernel AthenaBaseComps GeneratorObjects ForwardTracker )
+                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${XERCESC_LIBRARIES} ${GEANT4_LIBRARIES} ${CLHEP_LIBRARIES} ForwardTransportSvcLib AthenaBaseComps GeneratorObjects ForwardTracker )
 
 # Install files from the package:
-atlas_install_headers( ForwardTransportSvc )
 atlas_install_python_modules( python/*.py )
 atlas_install_joboptions( share/*.py )
 
diff --git a/Generators/AtlasHepMC/AtlasHepMC/Flow.h b/Generators/AtlasHepMC/AtlasHepMC/Flow.h
index 9991ae6192d641fe065fac9eb2f1c9864c2f97d9..f741fda7f5ee7d5e30d774b22272969fbf23d864 100644
--- a/Generators/AtlasHepMC/AtlasHepMC/Flow.h
+++ b/Generators/AtlasHepMC/AtlasHepMC/Flow.h
@@ -3,6 +3,30 @@
 */
 #ifndef ATLASHEPMC_FLOW_H
 #define ATLASHEPMC_FLOW_H
+#ifdef HEPMC3
+#include "HepMC3/Attribute.h"
+#include "HepMC3/GenParticle.h"
+namespace HepMC
+{
+typedef std::shared_ptr<HepMC3::VectorIntAttribute> Flow;
+inline int flow(HepMC3::GenParticlePtr p, int i){
+std::shared_ptr<HepMC3::IntAttribute> f=p->attribute<HepMC3::IntAttribute>("flow"+std::to_string(i));  if (f) return f->value(); 
+std::shared_ptr<HepMC3::VectorIntAttribute> vf=p->attribute<HepMC3::VectorIntAttribute>("flow");  if (vf) if (0<i&&i<(int)(vf->value().size())) return vf->value().at(i); 
+return 0;
+}
+inline Flow flow(HepMC3::GenParticlePtr p){
+std::shared_ptr<HepMC3::VectorIntAttribute> vf=p->attribute<HepMC3::VectorIntAttribute>("flow");  
+if (vf)  return vf;
+
+std::vector<int> fl;
+for (int i=1;i<=10;i++)
+{
+std::shared_ptr<HepMC3::IntAttribute> f=p->attribute<HepMC3::IntAttribute>("flow"+std::to_string(i));  if (f) fl.push_back(i); else break;
+}
+return std::make_shared<HepMC3::VectorIntAttribute>(fl);
+}
+}
+#else
 #include "HepMC/Flow.h"
 namespace HepMC
 {
@@ -10,3 +34,4 @@ template <class T> int flow(T a,int i){return a->flow(i);}
 template <class T> Flow flow(T a){return a->flow();}
 }
 #endif
+#endif
diff --git a/Generators/AtlasHepMC/AtlasHepMC/GenEvent.h b/Generators/AtlasHepMC/AtlasHepMC/GenEvent.h
index 27bb413999ee7f89afe8b59f9b5e9334d77f5a85..729e7e5637a65498725b53fe141cade954e0d990 100644
--- a/Generators/AtlasHepMC/AtlasHepMC/GenEvent.h
+++ b/Generators/AtlasHepMC/AtlasHepMC/GenEvent.h
@@ -69,12 +69,6 @@ inline int signal_process_id(const GenEvent* evt) {
 std::shared_ptr<HepMC3::IntAttribute> A_signal_process_id=evt->attribute<HepMC3::IntAttribute>("signal_process_id");
  return A_signal_process_id?(A_signal_process_id->value()):0;
 }
-namespace Print {
-inline void line(std::ostream& os,const GenEvent& e){e.print(os);}
-inline void line(std::ostream& os,const GenEvent* e){e->print(os);}
-}
-inline bool valid_beam_particles(const GenEvent* e){return e->valid_beam_particles();}
-
 inline void set_signal_process_id(GenEvent* e, const int i=0) {     std::shared_ptr<HepMC3::IntAttribute> signal_process_id = std::make_shared<HepMC3::IntAttribute>(i);
                                                                     e->add_attribute("signal_process_id",signal_process_id);  }
 inline void set_random_states(GenEvent* e, std::vector<long int>& a)  { 
diff --git a/Generators/AtlasHepMC/AtlasHepMC/GenVertex.h b/Generators/AtlasHepMC/AtlasHepMC/GenVertex.h
index 2130d84475ecf36d765e87adb11022d78bf7d954..a90b6c53159f7756c41a0aaa8b16a936753b9cee 100644
--- a/Generators/AtlasHepMC/AtlasHepMC/GenVertex.h
+++ b/Generators/AtlasHepMC/AtlasHepMC/GenVertex.h
@@ -46,6 +46,7 @@ inline GenVertexPtr newGenVertexPtr(const HepMC::FourVector &pos = HepMC::FourVe
     return new HepMC::GenVertex(pos,i);
 }
 inline int barcode(ConstGenVertexPtr p){ return p->barcode();}
+inline void* raw_pointer(GenVertexPtr p){ return p;}
 }
 #endif
 #endif
diff --git a/Generators/CavernBkgGenerator/src/MuonBackgroundConverter.cxx b/Generators/CavernBkgGenerator/src/MuonBackgroundConverter.cxx
index e88b5e57ee0c5a3d383842f9189f42efdfcf868b..1c1070e4d81a8e96331a93e2a508667e1de597c1 100644
--- a/Generators/CavernBkgGenerator/src/MuonBackgroundConverter.cxx
+++ b/Generators/CavernBkgGenerator/src/MuonBackgroundConverter.cxx
@@ -201,10 +201,7 @@ StatusCode MuonBackgroundConverter::callGenerator()
              //std::cout  <<  evt  <<  std::endl;
  
              // polarisation 
-             double polX, polY, polZ;
-             polX = polY = polZ = 0.0;
-             HepMC::Polarization pol;
-             pol.set_normal3d( HepGeom::Normal3D<double>( polX, polY, polZ ) );
+             HepMC::Polarization pol(0.0,0.0);
              m_polarization.push_back( pol );
           
              // PDG id, vertex, kinematic variables
diff --git a/Generators/CosmicGenerator/src/CosmicGenerator.cxx b/Generators/CosmicGenerator/src/CosmicGenerator.cxx
index 72a334457c2e5ff1bbecc9ea5e9b22a1e5154d82..a8cd573dbe8fe264ace04008fc23f13bacee1dc8 100644
--- a/Generators/CosmicGenerator/src/CosmicGenerator.cxx
+++ b/Generators/CosmicGenerator/src/CosmicGenerator.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // -------------------------------------------------------------
@@ -303,11 +303,7 @@ StatusCode CosmicGenerator::callGenerator() {
 
           ATH_MSG_VERBOSE( evt );
 
-          double polx = 0;
-          double poly = 0;
-          double polz = 0;
-          HepMC::Polarization thePolarization;
-          thePolarization.set_normal3d(HepGeom::Normal3D<double>(polx,poly,polz));
+          HepMC::Polarization thePolarization(0.0,0.0);
           m_polarization.push_back(thePolarization);
 
           //
@@ -555,26 +551,8 @@ StatusCode CosmicGenerator::callGenerator() {
         m_fourPos.push_back(CLHEP::HepLorentzVector(x,z,y,t));
 
       // Set the polarization.  Realistically, this is going to be zero
-      // for most studies, but you never know...
-      double polx = 0;
-      double poly = 0;
-      double polz = 0;
-      //m_polarization.set_normal3d(HepGeom::Normal3D<double>(polx,poly,polz));
-      HepMC::Polarization thePolarization;
-
-      // Do we need to swap Y- and Z-axis for the PixelEndCap C Cosmic test ?
-      // if not...do nothing...if so, invert position of y- and z- coordinate
-      //
-      // well and don't forget about the direction of the incoming cosmic muon(s) either
-      // that means:  y -> -y
-      //
-      if(!m_swapYZAxis){
-        // thePolarization.set_normal3d(HepGeom::Normal3D<double>(polx,-poly,polz));
-        thePolarization.set_normal3d(HepGeom::Normal3D<double>(polx,poly,polz));
-      }
-      else
-        thePolarization.set_normal3d(HepGeom::Normal3D<double>(polx,polz,-poly));
-
+      // for most studies.
+      HepMC::Polarization thePolarization(0.0);
       m_polarization.push_back(thePolarization);
 
 
@@ -627,10 +605,7 @@ StatusCode CosmicGenerator::callGenerator() {
           << m_fourMom.back().e()  << ")" );
       ATH_MSG_DEBUG(
              "  (theta,phi) = (" << theta << "," << phi << "), "
-          << "polarization(x,y,z) = ("
-          << m_polarization.back().normal3d().x() << ","
-          << m_polarization.back().normal3d().y() << ","
-          << m_polarization.back().normal3d().z() << ")" );
+          << "polarization(theta,phi) = ("<< m_polarization.back().theta() << ","<< m_polarization.back().phi()  << ")" );
     }
   return StatusCode::SUCCESS;
 
diff --git a/Generators/Epos_i/src/Epos.cxx b/Generators/Epos_i/src/Epos.cxx
index e265133b45bb4bef251f87c1191eb59e33ceefcf..7bebdc257acc991904018c0b24776d1c77f1746b 100644
--- a/Generators/Epos_i/src/Epos.cxx
+++ b/Generators/Epos_i/src/Epos.cxx
@@ -226,9 +226,14 @@ StatusCode Epos::genInitialize()
   epos_rndm_stream = "EPOS";
 
     // setup HepMC
+#ifdef HEPMC3
+     /* This ifdef is used for consistency */
+     /* HepMC3 does not need this setup */
+#else    
     HepMC::HEPEVT_Wrapper::set_sizeof_int(sizeof( int ));
     HepMC::HEPEVT_Wrapper::set_sizeof_real( 8 );
     HepMC::HEPEVT_Wrapper::set_max_number_entries(10000);    // as used in crmc-aaa.f!!!
+#endif
 
   m_events = 0;
 
@@ -305,12 +310,16 @@ StatusCode Epos::fillEvt( HepMC::GenEvent* evt )
 
 
   HepMC::HEPEVT_Wrapper::set_event_number(m_events);
+#ifdef HEPMC3
+  HepMC::HEPEVT_Wrapper::HEPEVT_to_GenEvent(evt);
+#else  
   HepMC::IO_HEPEVT hepio;
 
  
   hepio.set_trust_mothers_before_daughters(0);
   hepio.set_print_inconsistency_errors(0);
   hepio.fill_next_event(evt);
+#endif
   // evt->print();
  
 
@@ -321,16 +330,34 @@ StatusCode Epos::fillEvt( HepMC::GenEvent* evt )
   
   std::vector<HepMC::GenParticlePtr> beams;
 
-  for (HepMC::GenEvent::particle_const_iterator p = evt->particles_begin(); p != evt->particles_end(); ++p) {
-    if ((*p)->status() == 4) {
-      beams.push_back(*p);
-    }
-  } 
+  for (auto p: *evt) {
+    if (p->status() == 4) {
+      beams.push_back(p);
+   }
+  }
 
+  if (beams.size()>=2) {
   evt->set_beam_particles(beams[0], beams[1]); 
+  }
 
   // Heavy Ion and Signal ID from Epos to HepMC
 
+#ifdef HEPMC3
+     HepMC::GenHeavyIonPtr ion= std::make_shared<HepMC::GenHeavyIon>();
+                      ion->Ncoll_hard=cevt_.kohevt;
+                      ion->Npart_proj=cevt_.npjevt;
+                      ion->Npart_targ=cevt_.ntgevt;
+                      ion->Ncoll=cevt_.kolevt;
+                      ion->spectator_neutrons=cevt_.npnevt + cevt_.ntnevt;
+                      ion->spectator_protons=cevt_.nppevt + cevt_.ntpevt;
+                      ion->N_Nwounded_collisions=-1;
+                      ion->Nwounded_N_collisions=-1;
+                      ion->Nwounded_Nwounded_collisions=-1;
+                      ion->impact_parameter= cevt_.bimevt;
+                      ion->event_plane_angle=cevt_.phievt;
+                      ion->eccentricity=-1;  //c2evt_.fglevt,  //correct name but not defined
+                      ion->sigma_inel_NN=1e9*hadr5_.sigine;
+#else
      HepMC::HeavyIon ion(cevt_.kohevt,
                       cevt_.npjevt,
                       cevt_.ntgevt,
@@ -344,6 +371,7 @@ StatusCode Epos::fillEvt( HepMC::GenEvent* evt )
                       cevt_.phievt,
                       -1,  //c2evt_.fglevt,  //correct name but not defined
                       1e9*hadr5_.sigine);
+#endif
 
 		      evt->set_heavy_ion(ion);  
 
diff --git a/Generators/EvgenProdTools/CMakeLists.txt b/Generators/EvgenProdTools/CMakeLists.txt
index 4b5d58785d534a73ab4308640a45fc4480bcc347..9fc1f78f57cb2e8a1ab7f3fd54fe05f609f6e2f0 100644
--- a/Generators/EvgenProdTools/CMakeLists.txt
+++ b/Generators/EvgenProdTools/CMakeLists.txt
@@ -26,7 +26,7 @@ atlas_add_library( EvgenProdToolsLib
                    src/*.cxx
                    PUBLIC_HEADERS EvgenProdTools
                    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} 
-                   LINK_LIBRARIES ${ROOT_LIBRARIES} AtlasHepMCLib AthenaBaseComps TruthHelper GeneratorModulesLib
+                   LINK_LIBRARIES ${ROOT_LIBRARIES} AtlasHepMCLib AthenaBaseComps TruthHelper GeneratorModulesLib GenInterfacesLib
                    PRIVATE_LINK_LIBRARIES AthenaKernel EventInfo GaudiKernel TruthUtils )
 
 atlas_add_component( EvgenProdTools
diff --git a/Generators/FlowAfterburner/CMakeLists.txt b/Generators/FlowAfterburner/CMakeLists.txt
index e02dacd8244da2cfda45ab6d2979ca3e5df520e4..0185f2a587c7d75ff6707c639024cf300a289bf5 100644
--- a/Generators/FlowAfterburner/CMakeLists.txt
+++ b/Generators/FlowAfterburner/CMakeLists.txt
@@ -30,12 +30,12 @@ atlas_add_library( FlowAfterburnerLib
                    PRIVATE_INCLUDE_DIRS 
                    DEFINITIONS ${CLHEP_DEFINITIONS}
                    LINK_LIBRARIES ${GSL_LIBRARIES} ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthenaBaseComps AthenaKernel GaudiKernel TruthHelper GeneratorObjects StoreGateLib SGtests
-                   PRIVATE_LINK_LIBRARIES AtlasHepMCLib TruthUtils )
+                   PRIVATE_LINK_LIBRARIES AtlasHepMCLib AtlasHepMCsearchLib TruthUtils )
 
 atlas_add_component( FlowAfterburner
                      src/components/*.cxx
                      INCLUDE_DIRS ${GSL_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS}  ${CLHEP_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${GSL_LIBRARIES} ${ROOT_LIBRARIES} AtlasHepMCLib ${CLHEP_LIBRARIES} AthenaBaseComps AthenaKernel GaudiKernel TruthHelper GeneratorObjects StoreGateLib SGtests TruthUtils FlowAfterburnerLib )
+                     LINK_LIBRARIES ${GSL_LIBRARIES} ${ROOT_LIBRARIES} AtlasHepMCLib  AtlasHepMCsearchLib ${CLHEP_LIBRARIES} AthenaBaseComps AthenaKernel GaudiKernel TruthHelper GeneratorObjects StoreGateLib SGtests TruthUtils FlowAfterburnerLib )
 
 # Install files from the package:
 atlas_install_joboptions( share/*.py )
diff --git a/Generators/GenAnalysisTools/ReweightTools/src/PDFReweightTool.cxx b/Generators/GenAnalysisTools/ReweightTools/src/PDFReweightTool.cxx
index f17cbc21b766e1a5cd21f3ca102224f30a6fabbf..da5c680795dab48d7cc94d2548dd738ce2e47424 100644
--- a/Generators/GenAnalysisTools/ReweightTools/src/PDFReweightTool.cxx
+++ b/Generators/GenAnalysisTools/ReweightTools/src/PDFReweightTool.cxx
@@ -296,6 +296,15 @@ StatusCode PDFReweightTool::Reweight(HepMC::GenEvent* evt) {
 	}
 	
 	//get the event info about x's, flavor's and an event scale
+#ifdef HEPMC3
+	this->SetPDFInputs(
+		pdf_info->x[0],
+		pdf_info->parton_id[0],
+		pdf_info->x[1],
+		pdf_info->parton_id[1],
+		pdf_info->scale
+	);
+#else
 	this->SetPDFInputs(
 		pdf_info->x1(),
 		pdf_info->id1(),
@@ -303,6 +312,7 @@ StatusCode PDFReweightTool::Reweight(HepMC::GenEvent* evt) {
 		pdf_info->id2(),
 		pdf_info->scalePDF()
 	);
+#endif
 
 	//if the initial partons are gluons change their PDG values 
 	//to the right indices of the corresponding PDF values in
@@ -316,8 +326,13 @@ StatusCode PDFReweightTool::Reweight(HepMC::GenEvent* evt) {
 
 	//Retrieve PDF evoluation values for the initial partons.
 	if (!m_GeneratorUse) {
+#ifdef HEPMC3
+		m_used_pdf1 = pdf_info->pdf_id[0];
+		m_used_pdf2 = pdf_info->pdf_id[1];
+#else
 		m_used_pdf1 = pdf_info->pdf1();
 		m_used_pdf2 = pdf_info->pdf2();
+#endif
 	}
 	else {
 		//store the fake values. they will be recalculated later
@@ -456,6 +471,7 @@ StatusCode PDFReweightTool::Reweight(HepMC::GenEvent* evt) {
 			<<" Event weights are going to be re-writed." 
 			<<" This option works properly only for the HERWIG samples "
 			<<endmsg; 
+//TODO: Check if this code behaves correctly for HepMC2.06.10,HepMC2.06.11
 
 			double genWeight = evt->weights()[0];
 			evt->weights().clear();
diff --git a/Generators/GeneratorFilters/src/ATauFilter.cxx b/Generators/GeneratorFilters/src/ATauFilter.cxx
index 1eb9a7ff62e505c766db7ce8b61d0dd754925949..439bc448e8326ee70e0cb45983414747478fc326 100644
--- a/Generators/GeneratorFilters/src/ATauFilter.cxx
+++ b/Generators/GeneratorFilters/src/ATauFilter.cxx
@@ -78,7 +78,11 @@ StatusCode ATauFilter::filterEvent() {
       // Look for the first tau with genstat != 3 which has not a tau as daughter
       fsr = 0;
       if ( part->end_vertex()!= 0 ) {
+#ifdef HEPMC3
+        for ( auto itr = part->end_vertex()->particles_out().begin(); itr != part->end_vertex()->particles_out().end(); itr++ ) {
+#else
         for ( auto itr = part->end_vertex()->particles_out_const_begin(); itr != part->end_vertex()->particles_out_const_end(); itr++ ) {
+#endif
           if ( part->pdg_id() == (*itr)->pdg_id() ) fsr = 1;
         }
       }
diff --git a/Generators/GeneratorFilters/src/BSignalFilter.cxx b/Generators/GeneratorFilters/src/BSignalFilter.cxx
index 0fbf3a9b420de19b4b90f2ccf800297819abf456..0b02b70cf50475551028b469016907612b5af1f5 100644
--- a/Generators/GeneratorFilters/src/BSignalFilter.cxx
+++ b/Generators/GeneratorFilters/src/BSignalFilter.cxx
@@ -203,11 +203,14 @@ StatusCode BSignalFilter::filterEvent()
 		  // ** Reject whole event if any of B-hadrons in the event is not decayed **
 		  if( part->status() == 1 || part->status() == 899 ) { acceptEvent = false; }
 
-		  HepMC::GenVertex::particle_iterator firstParent, lastParent, thisParent;
-		  firstParent = part->production_vertex()->particles_begin(HepMC::parents);
-		  lastParent  = part->production_vertex()->particles_end(HepMC::parents);
-
-		  for( thisParent = firstParent; thisParent != lastParent++; ++thisParent )
+#ifdef HEPMC3
+		  auto  firstParent = part->production_vertex()->particles_in().begin();
+		  auto lastParent  = part->production_vertex()->particles_in().end();
+#else
+		  auto  firstParent = part->production_vertex()->particles_begin(HepMC::parents);
+		  auto lastParent  = part->production_vertex()->particles_end(HepMC::parents);
+#endif
+		  for(auto  thisParent = firstParent; thisParent != lastParent++; ++thisParent )
                     {
 		      int parentID = (*thisParent)->pdg_id();
 		      if (MC::PID::isBottomMeson(parentID) || MC::PID::isBottomBaryon(parentID) ) motherIsB = true;
@@ -426,8 +429,13 @@ void BSignalFilter::FindAllChildren(HepMC::ConstGenParticlePtr mother,std::strin
 	return;
       }
   }
+#ifdef HEPMC3
+ auto firstChild = mother->end_vertex()->particles_out().begin();
+ auto lastChild  = mother->end_vertex()->particles_out().end();
+#else
  auto firstChild = mother->end_vertex()->particles_begin(HepMC::children);
  auto lastChild  = mother->end_vertex()->particles_end(HepMC::children);
+#endif
 
   int childCnt = 0;
   std::string childIDStr;
diff --git a/Generators/GeneratorFilters/src/BSubstruct.cxx b/Generators/GeneratorFilters/src/BSubstruct.cxx
index 1179941b42c765298327e0e7be070b65426538c0..c9be0a7f0e957fe3c8b413de39842dbce32b3ff3 100644
--- a/Generators/GeneratorFilters/src/BSubstruct.cxx
+++ b/Generators/GeneratorFilters/src/BSubstruct.cxx
@@ -98,6 +98,13 @@ inline std::vector<HepMC::ConstGenParticlePtr> BSubstruct::ancestorCBs(HepMC::Co
 
   // If the production vertex is the first one then there's nothing more to do
   if (vtx->id() == 1) return parentBs;
+#ifdef HEPMC3
+  for (auto parent: vtx->particles_in()) {
+    if (hasCBQuark(parent->pdg_id())) parentBs.push_back(parent);
+    std::vector<HepMC::ConstGenParticlePtr> ancestors = ancestorCBs(parent);
+    parentBs.insert(parentBs.end(), ancestors.begin(), ancestors.end());
+  }
+#else
 
   for (HepMC::GenVertex::particles_in_const_iterator parent = vtx->particles_in_const_begin();
        parent != vtx->particles_in_const_end(); ++parent) {
@@ -105,6 +112,7 @@ inline std::vector<HepMC::ConstGenParticlePtr> BSubstruct::ancestorCBs(HepMC::Co
     std::vector<HepMC::ConstGenParticlePtr> ancestors = ancestorCBs(*parent);
     parentBs.insert(parentBs.end(), ancestors.begin(), ancestors.end());
   }
+#endif  
   return parentBs;
 }
 
diff --git a/Generators/GeneratorFilters/src/MultiParticleFilter.cxx b/Generators/GeneratorFilters/src/MultiParticleFilter.cxx
index 7fdb2f94b5c0b4ae804d73e80de9442adc3c3b52..a83db3e30390681909b638e5ec3c94a220b5caaf 100644
--- a/Generators/GeneratorFilters/src/MultiParticleFilter.cxx
+++ b/Generators/GeneratorFilters/src/MultiParticleFilter.cxx
@@ -96,19 +96,14 @@ StatusCode MultiParticleFilter::filterEvent() {
                 
         // Loop over all particles in the event
         const HepMC::GenEvent* genEvt = (*itr);
-        for(HepMC::GenEvent::particle_const_iterator pitr=genEvt->particles_begin(); pitr!=genEvt->particles_end(); ++pitr){
-              
+        for(auto pitr: *genEvt){              
             bool passedPDG = false;
-            bool passedStatus = false;
-            
-            for(unsigned int i=0; i<m_particlePDG.size(); i++) 
-                if(abs((*pitr)->pdg_id()) == m_particlePDG[i]) passedPDG = true;
-              
-            for(unsigned int i=0; i<m_particleStatus.size(); i++)
-                if(abs((*pitr)->status()) == m_particleStatus[i]) passedStatus = true;
+            bool passedStatus = false;            
+            if (find(m_particlePDG.begin(),m_particlePDG.end(),std::abs(pitr->pdg_id()))!=m_particlePDG.end()) passedPDG = true;
+            if (find(m_particleStatus.begin(),m_particleStatus.end(),pitr->status())!=m_particleStatus.end()) passedStatus = true;
               
             if(passedPDG && passedStatus)
-	      if ((*pitr)->momentum().perp() >= m_ptMinParticle && (*pitr)->momentum().perp() <= m_ptMaxParticle && fabs((*pitr)->momentum().eta()) <= m_etaRangeParticle)
+	      if (pitr->momentum().perp() >= m_ptMinParticle && pitr->momentum().perp() <= m_ptMaxParticle && std::abs(pitr->momentum().eta()) <= m_etaRangeParticle)
 		Np++; // Found a particle passing all the cuts.
 
             // Test if we fulfilled all the requirements and return in that case.
diff --git a/Generators/GeneratorFilters/src/WeightedBDtoElectronFilter.cxx b/Generators/GeneratorFilters/src/WeightedBDtoElectronFilter.cxx
index 4895bf0804302529f2667f89fa91cc9a9bceedcf..d92361c11506a3f188da3f73b4e99e0dc9542dd2 100644
--- a/Generators/GeneratorFilters/src/WeightedBDtoElectronFilter.cxx
+++ b/Generators/GeneratorFilters/src/WeightedBDtoElectronFilter.cxx
@@ -66,37 +66,28 @@ StatusCode WeightedBDtoElectronFilter::filterEvent() {
   McEventCollection::const_iterator itr;
   for (itr = events()->begin(); itr!=events()->end(); ++itr) {
     const HepMC::GenEvent* genEvt = (*itr);
-    for (HepMC::GenEvent::particle_const_iterator pitr = genEvt->particles_begin(); pitr != genEvt->particles_end(); ++pitr) {
-      double etaAbs = fabs((*pitr)->momentum().pseudoRapidity());
-      double pt = (*pitr)->momentum().perp();
-
+    for (auto pitr: *genEvt) {
       // check stables only
-      if ( (*pitr)->status() == 1) {
-        // check pdg_id
-        if ( std::abs((*pitr)->pdg_id()) == 11 ) {
-          // check pt
-          if ( pt>=m_PtMin && pt<=m_PtMax) {
-            // check eta
-            if ( etaAbs <=m_EtaRange ) {
-
-              // check parent and ancestors for B hadron
-              auto bParent = FindBParent( (*pitr) );
-              if ( bParent != 0 ) {
-
-                // apply prescale factors
-                if ( PassPrescaleCheck( etaAbs, pt ) ) {
-                  ATH_MSG_VERBOSE(" found good electron (pass prescale): PID = " << (*pitr)->pdg_id() <<
+      if ( pitr->status() != 1)  continue;
+      // check pdg_id
+      if ( std::abs(pitr->pdg_id()) != 11 )  continue;
+      double etaAbs = std::abs(pitr->momentum().pseudoRapidity());
+      double pt = pitr->momentum().perp();
+      // check pt
+      if ( pt<m_PtMin || pt>m_PtMax) continue;
+      // check eta
+      if ( etaAbs > m_EtaRange ) continue;
+      // check parent and ancestors for B hadron
+      auto bParent = FindBParent( pitr );
+      if ( !bParent ) continue;
+      // apply prescale factors
+      if ( ! PassPrescaleCheck( etaAbs, pt ) ) continue;
+      ATH_MSG_VERBOSE(" found good electron (pass prescale): PID = " << pitr->pdg_id() <<
                                   "					   B hadron PID = " << bParent->pdg_id() <<
-                                  "					   electron pt	= " << (*pitr)->momentum().perp()/1000. << " GeV " <<
-                                  "					   electron eta = " << (*pitr)->momentum().pseudoRapidity() <<
+                                  "					   electron pt	= " << pitr->momentum().perp()/1000. << " GeV " <<
+                                  "					   electron eta = " << pitr->momentum().pseudoRapidity() <<
                                   " ===>>> event passed WeightedBDtoElectronFilter ");
-                  return StatusCode::SUCCESS;
-                }
-              } // B parent
-            } // eta range
-          } // pt cut
-        } // pdg id
-      } // stable
+      return StatusCode::SUCCESS;
     } // particle loop
   } // gen events loop
 
diff --git a/Generators/GeneratorFilters/src/XtoVVDecayFilter.cxx b/Generators/GeneratorFilters/src/XtoVVDecayFilter.cxx
index 0360724d7e35da417dc83336f6034048c430d294..9e671c2a090a813d641584ebf58149043c927069 100644
--- a/Generators/GeneratorFilters/src/XtoVVDecayFilter.cxx
+++ b/Generators/GeneratorFilters/src/XtoVVDecayFilter.cxx
@@ -54,22 +54,25 @@ StatusCode XtoVVDecayFilter::filterEvent() {
   for (itr = events()->begin(); itr != events()->end(); ++itr) {
     // Loop over all particles in the event
     const HepMC::GenEvent* genEvt = (*itr);
-    for (HepMC::GenEvent::particle_const_iterator pitr = genEvt->particles_begin(); pitr != genEvt->particles_end(); ++pitr) {
-      if ( abs((*pitr)->pdg_id()) == m_PDGParent && (*pitr)->status() == m_StatusParent) {
-        HepMC::GenVertex::particle_iterator firstMother = (*pitr)->production_vertex()->particles_begin(HepMC::parents);
-        HepMC::GenVertex::particle_iterator endMother = (*pitr)->production_vertex()->particles_end(HepMC::parents);
-        HepMC::GenVertex::particle_iterator thisMother = firstMother;
+    for (auto pitr: *genEvt) {
+      if ( abs(pitr->pdg_id()) != m_PDGParent || pitr->status() != m_StatusParent) continue;
         bool isGrandParentOK = false;
-        for (; thisMother != endMother; ++thisMother) {
-          ATH_MSG_DEBUG(" Parent " << (*pitr)->pdg_id() << " barcode = "   << (*pitr)->barcode() << " status = "  << (*pitr)->status());
-          ATH_MSG_DEBUG(" a Parent mother "  << (*thisMother)->pdg_id()<< " barcode = " << (*thisMother)->barcode());
+#ifdef HEPMC3
+        auto firstMother = pitr->production_vertex()->particles_in().begin();
+        auto endMother = pitr->production_vertex()->particles_in().end();
+#else
+        auto firstMother = pitr->production_vertex()->particles_begin(HepMC::parents);
+        auto endMother = pitr->production_vertex()->particles_end(HepMC::parents);
+#endif
+        for (auto  thisMother=firstMother;thisMother!=endMother;thisMother++) {
+          ATH_MSG_DEBUG(" Parent " << pitr->pdg_id() << " barcode = "   << HepMC::barcode(pitr) << " status = "  << pitr->status());
+          ATH_MSG_DEBUG(" a Parent mother "  << (*thisMother)->pdg_id()<< " barcode = " << HepMC::barcode(*thisMother));
           if ( (*thisMother)->pdg_id() == m_PDGGrandParent ) isGrandParentOK = true;
         }
         ATH_MSG_DEBUG(" Grand Parent is OK? " << isGrandParentOK);
         if (!isGrandParentOK) continue;
         ++nGoodParent;
-        FindAncestor((*pitr)->end_vertex(), m_PDGParent, okPDGChild1, okPDGChild2);
-      }
+        FindAncestor(pitr->end_vertex(), m_PDGParent, okPDGChild1, okPDGChild2);
     }
   }
   ATH_MSG_DEBUG("Result " << nGoodParent << " " << okPDGChild1 << " " << okPDGChild2);
@@ -91,10 +94,14 @@ StatusCode XtoVVDecayFilter::filterEvent() {
 void XtoVVDecayFilter::FindAncestor(const HepMC::GenVertexPtr searchvertex,
                                     int targetPDGID, bool& okPDGChild1, bool& okPDGChild2) {
   if (!searchvertex) return;
+#ifdef HEPMC3
+  auto firstAncestor = searchvertex->particles_out().begin();
+  auto endAncestor = searchvertex->particles_out().end();
+#else
   const HepMC::GenVertex::particles_out_const_iterator firstAncestor = searchvertex->particles_out_const_begin();
   const HepMC::GenVertex::particles_out_const_iterator endAncestor = searchvertex->particles_out_const_end();
-  HepMC::GenVertex::particles_out_const_iterator thisAncestor = firstAncestor;
-  for (; thisAncestor != endAncestor; ++thisAncestor){
+#endif
+  for (  auto thisAncestor = firstAncestor; thisAncestor != endAncestor; ++thisAncestor){
     //ATH_MSG_DEBUG(" child " << (*thisAncestor)->pdg_id());
     if (abs((*thisAncestor)->pdg_id()) == targetPDGID) { //same particle as parent
       FindAncestor((*thisAncestor)->end_vertex(), targetPDGID, okPDGChild1, okPDGChild2);
diff --git a/Generators/Herwig7_i/src/Herwig7.cxx b/Generators/Herwig7_i/src/Herwig7.cxx
index f1a9e256653080163b0b35d69226b10cf709dcdd..1ee1a7173e59d23ef7a6bcf67b8ed6afe71a5814 100644
--- a/Generators/Herwig7_i/src/Herwig7.cxx
+++ b/Generators/Herwig7_i/src/Herwig7.cxx
@@ -215,7 +215,12 @@ StatusCode Herwig7::fillEvt(HepMC::GenEvent* evt) {
   double pdf1 = pdfs.first.xfx(sub->incoming().first ->dataPtr(), scale, x1);
   double pdf2 = pdfs.first.xfx(sub->incoming().second->dataPtr(), scale, x2);
   // Create the PDFinfo object
+#ifdef HEPMC3
+  HepMC3::GenPdfInfoPtr pdfi = std::shared_ptr<HepMC3::GenPdfInfo>();
+  pdfi->set(id1, id2, x1, x2, Q, pdf1, pdf2);
+#else
   HepMC::PdfInfo pdfi(id1, id2, x1, x2, Q, pdf1, pdf2);
+#endif
   evt->set_pdf_info(pdfi);
   ATH_MSG_DEBUG("Added PDF info to HepMC");
 
diff --git a/Generators/HforTool/CMakeLists.txt b/Generators/HforTool/CMakeLists.txt
index 7a875a64ba609d2a919cd9ca0c0b7dba415b9579..79cd889ad38f14debc31c94b19f11b4673730936 100644
--- a/Generators/HforTool/CMakeLists.txt
+++ b/Generators/HforTool/CMakeLists.txt
@@ -26,7 +26,7 @@ atlas_add_component( HforTool
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} 
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} AtlasHepMCLib AthenaBaseComps EventInfo GaudiKernel JetEvent StoreGateLib SGtests GeneratorObjects TruthUtils )
+                     LINK_LIBRARIES ${ROOT_LIBRARIES} AtlasHepMCLib AthenaBaseComps EventInfo GaudiKernel JetEvent StoreGateLib SGtests GeneratorObjects TruthUtils GenInterfacesLib )
 
 # Install files from the package:
 atlas_install_headers( HforTool )
diff --git a/Generators/Hijing_i/src/Hijing.cxx b/Generators/Hijing_i/src/Hijing.cxx
index cfa22100cc07f30429ad29c69fb91923530109ea..346f0e2097af1a79245e921a4a6f3bfb6cc14cea 100644
--- a/Generators/Hijing_i/src/Hijing.cxx
+++ b/Generators/Hijing_i/src/Hijing.cxx
@@ -280,6 +280,22 @@ Hijing::fillEvt(HepMC::GenEvent* evt)
 
     float sigmainel =  m_hiparnt.hint1(12);
  
+ #ifdef HEPMC3
+     HepMC::GenHeavyIonPtr ion= std::make_shared<HepMC::GenHeavyIon>();
+                      ion->Ncoll_hard=static_cast<int>(jatt);
+                      ion->Npart_proj=static_cast<int>(np);
+                      ion->Npart_targ=static_cast<int>(nt);
+                      ion->Ncoll=static_cast<int>(n0+n10+n01+n11);
+                      ion->N_Nwounded_collisions=static_cast<int>(n01);
+                      ion->Nwounded_N_collisions=static_cast<int>(n10);
+                      ion->Nwounded_Nwounded_collisions=static_cast<int>(n11);
+                      ion->spectator_neutrons=-1;
+                      ion->spectator_protons=-1;
+                      ion->impact_parameter= b;
+                      ion->event_plane_angle=bphi;
+                      ion->event_plane_angle=-1;
+                      ion->sigma_inel_NN=sigmainel;
+#else
     HepMC::HeavyIon ion
       (			
        static_cast<int>(jatt), // Ncoll_hard
@@ -298,6 +314,7 @@ Hijing::fillEvt(HepMC::GenEvent* evt)
 
     evt->set_heavy_ion(ion); 
     std::cout << " heavy ion " << evt->heavy_ion() << std::endl;
+#endif
 
     //  Did we keep decay history?
     //
@@ -309,13 +326,9 @@ Hijing::fillEvt(HepMC::GenEvent* evt)
 
     // Vectors that will keep track of where particles originate from and die
     //
-    std::vector<int> partOriginVertex_vec;
-    std::vector<int> partDecayVertex_vec;
-    std::vector<HepMC::GenParticlePtr> particleHepPartPtr_vec;
-
-    partOriginVertex_vec.assign(numHijingPart, 0);
-    partDecayVertex_vec.assign(numHijingPart, -1);
-    particleHepPartPtr_vec.assign(numHijingPart, (HepMC::GenParticle*) 0);
+    std::vector<int> partOriginVertex_vec(numHijingPart, 0);
+    std::vector<int> partDecayVertex_vec(numHijingPart, -1);
+    std::vector<HepMC::GenParticlePtr> particleHepPartPtr_vec(numHijingPart, nullptr);
 
     // Vector that will keep pointers to generated vertices
     //
@@ -476,8 +489,13 @@ Hijing::fillEvt(HepMC::GenEvent* evt)
                     << ", " << vertexPtrVec[parentDecayIndex]->position().z() 
                     << ", associated daughter IDs = ";
               
+#ifdef HEPMC3
+                auto vertexPtrVec_particles_out_const_begin=vertexPtrVec[parentDecayIndex]->particles_out().begin();
+                auto vertexPtrVec_particles_out_const_end=vertexPtrVec[parentDecayIndex]->particles_out().end();
+#else
                 auto vertexPtrVec_particles_out_const_begin=vertexPtrVec[parentDecayIndex]->particles_out_const_begin();
                 auto vertexPtrVec_particles_out_const_end=vertexPtrVec[parentDecayIndex]->particles_out_const_end();
+#endif
                 for (auto iter = vertexPtrVec_particles_out_const_begin; 
                      iter != vertexPtrVec_particles_out_const_end; 
                      iter++)
@@ -768,13 +786,13 @@ Hijing::fillEvt(HepMC::GenEvent* evt)
       //      std::cout <<"random="<<ranz <<std::endl;
       if (ranz < 0.5) {
        //      std::cout <<"flip="<<ranz <<std::endl;
-      for(HepMC::GenEvent::particle_const_iterator pitr= evt->particles_begin(); pitr != evt->particles_end(); ++pitr){
-       tmpmom= (*pitr)->momentum();
+      for(auto  pitr: *evt){
+       tmpmom= pitr->momentum();
        tmpmom.setX(-tmpmom.x());
        tmpmom.setY(-tmpmom.y());
        tmpmom.setZ(-tmpmom.z());
        tmpmom.setT(tmpmom.t());
-       (*pitr)->set_momentum(tmpmom);
+       pitr->set_momentum(tmpmom);
        }
       }
     }
diff --git a/Generators/Photospp_i/CMakeLists.txt b/Generators/Photospp_i/CMakeLists.txt
index 69d10d511288b5a7dfa5c2b67a9729c61222fe63..fa85facc811e14021e8adc743cde305f5c96125e 100644
--- a/Generators/Photospp_i/CMakeLists.txt
+++ b/Generators/Photospp_i/CMakeLists.txt
@@ -16,7 +16,11 @@ atlas_depends_on_subdirs(
 
 # External dependencies:
 find_package( CLHEP )
+if (HEPMC3_USE)
+find_package( Photospp COMPONENTS Photospp PhotosppHepMC3 )
+else()
 find_package( Photospp COMPONENTS Photospp PhotosppHepMC )
+endif()
 
 # Remove the --as-needed linker flags:
 atlas_disable_as_needed()
diff --git a/Generators/Photospp_i/src/Photospp_i.cxx b/Generators/Photospp_i/src/Photospp_i.cxx
index 4daaf6ef4eef6d7275c72ccbb89f652b7fe3c02b..f1879752ba34752229f2462ec17ca6aec0e81262 100644
--- a/Generators/Photospp_i/src/Photospp_i.cxx
+++ b/Generators/Photospp_i/src/Photospp_i.cxx
@@ -7,7 +7,14 @@
 
 #include "Photos/Photos.h"
 
+#ifdef HEPMC3
+#include "Photos/PhotosHepMC3Event.h"
+namespace Photospp {
+using PhotosHepMCEvent=PhotosHepMC3Event;
+}
+#else
 #include "Photos/PhotosHepMCEvent.h"
+#endif
 #include "Photos/Log.h"
 
 #include "GeneratorObjects/McEventCollection.h"
diff --git a/Generators/QGSJet_i/src/QGSJet.cxx b/Generators/QGSJet_i/src/QGSJet.cxx
index 4b2940d1cd874516999cebb846fc403022b0e4fa..0e9fbc10debda57ecca1050a439b468a30e05b6e 100644
--- a/Generators/QGSJet_i/src/QGSJet.cxx
+++ b/Generators/QGSJet_i/src/QGSJet.cxx
@@ -222,9 +222,14 @@ StatusCode QGSJet::genInitialize()
   qgsjet_rndm_stream = "QGSJet";
 
     // setup HepMC
+#ifdef HEPMC3
+   /* This ifdef   is used for consistency */
+   /* HepMC3 Does not need a setup here */
+#else
     HepMC::HEPEVT_Wrapper::set_sizeof_int(sizeof( int ));
     HepMC::HEPEVT_Wrapper::set_sizeof_real( 8 );
     HepMC::HEPEVT_Wrapper::set_max_number_entries(10000);    // as used in crmc-aaa.f!!!
+#endif
 
   m_events = 0;
 
@@ -299,12 +304,16 @@ StatusCode QGSJet::fillEvt( HepMC::GenEvent* evt )
 
 
   HepMC::HEPEVT_Wrapper::set_event_number(m_events);
+#ifdef HEPMC3
+  HepMC::HEPEVT_Wrapper::HEPEVT_to_GenEvent(evt);
+#else 
   HepMC::IO_HEPEVT hepio;
 
  
   hepio.set_trust_mothers_before_daughters(0);
   hepio.set_print_inconsistency_errors(0);
   hepio.fill_next_event(evt);
+#endif
   HepMC::set_random_states(evt, m_seeds );
 
   evt->weights().push_back(1.0); 
@@ -312,13 +321,15 @@ StatusCode QGSJet::fillEvt( HepMC::GenEvent* evt )
   
   std::vector<HepMC::GenParticlePtr> beams;
 
-  for (HepMC::GenEvent::particle_const_iterator p = evt->particles_begin(); p != evt->particles_end(); ++p) {
-    if ((*p)->status() == 4) {
-      beams.push_back(*p);
+  for (auto p: *evt) {
+    if (p->status() == 4) {
+      beams.push_back(p);
     }
   } 
 
+ if (beams.size()>=2){
   evt->set_beam_particles(beams[0], beams[1]); 
+ }
 
    int sig_id = -1;
    switch (int(c2evt_.typevt))
diff --git a/Generators/Tauolapp_i/src/TauolaPP.cxx b/Generators/Tauolapp_i/src/TauolaPP.cxx
index 02c25bf2f516de7e59e3daa8f79d217b17d558aa..535e731b248f450008f7ed24a4f6ce14061bcd42 100644
--- a/Generators/Tauolapp_i/src/TauolaPP.cxx
+++ b/Generators/Tauolapp_i/src/TauolaPP.cxx
@@ -7,7 +7,16 @@
 // Tauola header files
 #include "Tauola/Log.h"
 #include "Tauola/Tauola.h"
+#ifdef HEPMC3
+#include "Tauola/TauolaHepMC3Event.h"
+namespace Tauolapp
+{
+using TauolaHepMCEvent=TauolaHepMC3Event;
+using TauolaHepMCParticle=TauolaHepMC3Particle;
+}
+#else
 #include "Tauola/TauolaHepMCEvent.h"
+#endif
 
 #include "Tauola/f_Variables.h"
 
diff --git a/Generators/TrackRecordGenerator/src/TrackRecordGenerator.cxx b/Generators/TrackRecordGenerator/src/TrackRecordGenerator.cxx
index 1bff952ed34bf1538d1a58176efd9264bdb06770..7cff32d53711289f15e0431672da6f4136b0fc73 100644
--- a/Generators/TrackRecordGenerator/src/TrackRecordGenerator.cxx
+++ b/Generators/TrackRecordGenerator/src/TrackRecordGenerator.cxx
@@ -160,8 +160,7 @@ StatusCode TrackRecordGenerator::callGenerator() {
     m_fourMom.push_back( particle4Momentum );
 
     m_pdgCode.push_back(iterTTR.GetPDGCode());
-    HepMC::Polarization thePolarization;
-    thePolarization.set_normal3d(HepGeom::Normal3D<double>(0,0,0));
+    HepMC::Polarization thePolarization(0.0,0.0);
     m_polarization.push_back(thePolarization);
 
     if (m_stopParticles){
diff --git a/HLT/Event/TrigByteStreamCnvSvc/python/TrigByteStreamCnvSvcConfig.py b/HLT/Event/TrigByteStreamCnvSvc/python/TrigByteStreamCnvSvcConfig.py
index 2490bd67f8e946477d77b6d457826130697f1562..45b6667c8c9f97ee33444419a0959f1a3a8e2e0f 100644
--- a/HLT/Event/TrigByteStreamCnvSvc/python/TrigByteStreamCnvSvcConfig.py
+++ b/HLT/Event/TrigByteStreamCnvSvc/python/TrigByteStreamCnvSvcConfig.py
@@ -20,7 +20,10 @@ class TrigByteStreamInputSvc(_TrigByteStreamInputSvc):
                                      xbins=1, xmin=0, xmax=1)
         self.MonTool.defineHistogram('TIME_getNext', path='EXPERT', type='TH1F',
                                      title='Time of DataCollector::getNext() calls;Time [ms];N calls',
-                                     xbins=100, xmin=0, xmax=100)
+                                     xbins=400, xmin=0, xmax=200)
+        self.MonTool.defineHistogram('TIME_getNext;TIME_getNext_extRange', path='EXPERT', type='TH1F',
+                                     title='Time of DataCollector::getNext() calls;Time [ms];N calls',
+                                     xbins=400, xmin=0, xmax=2000)
         self.MonTool.defineHistogram('getNext_LBN,getNext_noEvent;NoEventFraction', path='EXPERT', type='TProfile',
                                      title='Fraction of getNext calls returning NO_EVENT;Lumi Block;Event fraction',
                                      xbins=100, xmin=0, xmax=100, opt='kCanRebin')
diff --git a/HLT/Event/TrigByteStreamCnvSvc/src/TrigByteStreamCnvSvc.cxx b/HLT/Event/TrigByteStreamCnvSvc/src/TrigByteStreamCnvSvc.cxx
index 862109e6a868a0f9c0ceba7f82120582d6620b9c..facf9426ab10bb390de689c4b922ace6b5b64222 100644
--- a/HLT/Event/TrigByteStreamCnvSvc/src/TrigByteStreamCnvSvc.cxx
+++ b/HLT/Event/TrigByteStreamCnvSvc/src/TrigByteStreamCnvSvc.cxx
@@ -188,8 +188,9 @@ StatusCode TrigByteStreamCnvSvc::commitOutput(const std::string& /*outputFile*/,
     auto startTime = std::chrono::high_resolution_clock::now();
     hltinterface::DataCollector::instance()->eventDone(std::move(rawEventPtr));
     auto endTime = std::chrono::high_resolution_clock::now();
-    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(endTime - startTime);
+    auto duration = std::chrono::duration<float, std::milli>(endTime - startTime);
     m_histEventDoneTime->Fill(static_cast<float>(duration.count()));
+    m_histEventDoneTimeER->Fill(static_cast<float>(duration.count()));
     ATH_MSG_DEBUG("Serialised FullEventFragment with HLT result was returned to DataCollector successfully, "
                   << "the eventDone call took " << duration.count() << " microseconds");
   }
@@ -462,23 +463,27 @@ void TrigByteStreamCnvSvc::bookHistograms() {
   regHist(m_histPebSubDetsFromSubDetList);
 
   m_histResultSizeByModule = new TH2F(
-    "ResultSizeByModule", "HLT result size by module;Module ID;Size [kB]", 10, 0, 10, 100, 0, 1000);
+    "ResultSizeByModule", "HLT result size by module;Module ID;Size [kB]", 10, 0, 10, 200, 0, 2000);
   regHist(m_histResultSizeByModule);
 
   m_histResultSizeByStream = new TH2F(
-    "ResultSizeByStream", "HLT result size by stream;;Size [kB]", 1, 0, 1, 100, 0, 1000);
+    "ResultSizeByStream", "HLT result size by stream;;Size [kB]", 1, 0, 1, 200, 0, 2000);
   m_histResultSizeByStream->SetCanExtend(TH1::kXaxis);
   regHist(m_histResultSizeByStream);
 
   m_histResultSizeTotal = new TH1F(
-    "ResultSizeTotal", "HLT result total size (sum of all modules);Size [kB];Events", 100, 0, 1000);
+    "ResultSizeTotal", "HLT result total size (sum of all modules);Size [kB];Events", 200, 0, 2000);
   regHist(m_histResultSizeTotal);
 
   m_histResultSizeFullEvFrag = new TH1F(
-    "ResultSizeFullEvFrag", "HLT output FullEventFragment size;Size [kB];Events", 100, 0, 1000);
+    "ResultSizeFullEvFrag", "HLT output FullEventFragment size;Size [kB];Events", 200, 0, 2000);
   regHist(m_histResultSizeFullEvFrag);
 
   m_histEventDoneTime = new TH1F(
-    "TIME_EventDoneCall", "Time of DataCollector::eventDone calls;Time [us];Events", 1000, 0, 1000);
+    "TIME_EventDoneCall", "Time of DataCollector::eventDone calls;Time [ms];Events", 400, 0, 2);
   regHist(m_histEventDoneTime);
+
+  m_histEventDoneTimeER = new TH1F(
+    "TIME_EventDoneCall_extRange", "Time of DataCollector::eventDone calls;Time [ms];Events", 400, 0, 200);
+  regHist(m_histEventDoneTimeER);
 }
diff --git a/HLT/Event/TrigByteStreamCnvSvc/src/TrigByteStreamCnvSvc.h b/HLT/Event/TrigByteStreamCnvSvc/src/TrigByteStreamCnvSvc.h
index da9fa1b473f26811e8978d99d5a56f663be0ce01..cedcb95ff6ddfe1c00982eab8d3e3ab7a640e57f 100644
--- a/HLT/Event/TrigByteStreamCnvSvc/src/TrigByteStreamCnvSvc.h
+++ b/HLT/Event/TrigByteStreamCnvSvc/src/TrigByteStreamCnvSvc.h
@@ -74,6 +74,7 @@ private:
   TH1F* m_histResultSizeTotal{nullptr}; //< Histogram of total HLT result size (all modules)
   TH1F* m_histResultSizeFullEvFrag{nullptr}; //< Histogram of the size of FullEventFragment sent from HLT to DataCollector
   TH1F* m_histEventDoneTime{nullptr}; //< Histogram of the time taken by the eventDone call
+  TH1F* m_histEventDoneTimeER{nullptr}; //< Histogram of the time taken by the eventDone call (extended range)
 };
 
 #endif // TRIGBYTESTREAMCNVSVC_H
diff --git a/HLT/Event/TrigByteStreamCnvSvc/src/TrigByteStreamInputSvc.cxx b/HLT/Event/TrigByteStreamCnvSvc/src/TrigByteStreamInputSvc.cxx
index 53621b238b35562c3c4145281ab5e88b27225e45..5c08b1944d85972f07c8a6f8d8dd2fd975ab3454 100644
--- a/HLT/Event/TrigByteStreamCnvSvc/src/TrigByteStreamInputSvc.cxx
+++ b/HLT/Event/TrigByteStreamCnvSvc/src/TrigByteStreamInputSvc.cxx
@@ -98,7 +98,7 @@ const RawEvent* TrigByteStreamInputSvc::nextEvent() {
   auto monLBN = Monitored::Scalar<uint16_t>("getNext_LBN", m_maxLB);
   auto monNoEvent = Monitored::Scalar<bool>("getNext_noEvent", false);
   try {
-    auto t_getNext = Monitored::Timer<std::chrono::milliseconds>("TIME_getNext");
+    auto t_getNext = Monitored::Timer<std::chrono::duration<float, std::milli>>("TIME_getNext");
     status = hltinterface::DataCollector::instance()->getNext(cache->rawData);
     auto mon = Monitored::Group(m_monTool, t_getNext);
   }
diff --git a/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/python/MTCalibPebConfig.py b/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/python/MTCalibPebConfig.py
index fe45172ac3be9c2ece6fb3f6602db9169a14ea17..76366c4fe9d7e58deb4d9de09202d673fc92061b 100644
--- a/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/python/MTCalibPebConfig.py
+++ b/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/python/MTCalibPebConfig.py
@@ -68,18 +68,18 @@ rob_list = [
 ]
 
 rob_access_dict = {
-  '01 :GET:RND20: Retrieve ': rob_list,
-  '02 :GET:RND10: Retrieve ': rob_list,
-  '03 :GET:RND5:  Retrieve ': rob_list,
-  '04 :GET:RND10: Retrieve ': rob_list,
-  '05 :GET:RND20: Retrieve ': rob_list,
-  '06 :GET:RND50: Retrieve ': rob_list,
-  '07 :GET:RND10: Retrieve ': rob_list,
-  '08 :GET:RND5:  Retrieve ': rob_list,
-  '09 :GET:RND20: Retrieve ': rob_list,
-  '10 :GET:RND20: Retrieve ': rob_list,
-  '11 :GET:RND10: Retrieve ': rob_list,
-  '12 :GET:RND10: Retrieve ': rob_list
+  '01 :ADDGET:RND20:': rob_list,  # Prefetch+Retrieve  20 random ROBs from rob_list
+  '02 :GET:RND10:   ': rob_list,  # Retrieve           10 random ROBs from rob_list
+  '03 :GET:RND5:    ': rob_list,  # Retrieve            5 random ROBs from rob_list
+  '04 :ADD:RND10:   ': rob_list,  # Prefetch           10 random ROBs from rob_list
+  '05 :ADD:RND20:   ': rob_list,  # Prefetch           20 random ROBs from rob_list
+  '06 :ADDGET:RND50:': rob_list,  # Prefetch+Retrieve  50 random ROBs from rob_list
+  '07 :ADDGET:RND10:': rob_list,  # Prefetch+Retrieve  10 random ROBs from rob_list
+  '08 :ADDGET:RND5: ': rob_list,  # Prefetch+Retrieve   5 random ROBs from rob_list
+  '09 :GET:RND20:   ': rob_list,  # Retrieve           20 random ROBs from rob_list
+  '10 :ADDGET:RND20:': rob_list,  # Prefetch+Retrieve  20 random ROBs from rob_list
+  '11 :GET:RND10:   ': rob_list,  # Retrieve           10 random ROBs from rob_list
+  '12 :ADDGET:RND10:': rob_list   # Prefetch+Retrieve  10 random ROBs from rob_list
 }
 
 class MTCalibPebHypoOptions:
@@ -314,34 +314,44 @@ def make_hlt_seq(num_chains, concurrent=False):
 
 def write_dummy_menu_json(chains, chain_to_streams):
     import json
+    from collections import OrderedDict as odict
     from TrigConfHLTData.HLTUtils import string2hash
     menu_name = 'MTCalibPeb'
-    menu_dict = {
-        'name': menu_name,
-        'chains': []
-    }
+    menu_dict = odict([ ("filetype", "hltmenu"), ("name", menu_name), ("chains", odict()), ("streams", odict()), ("sequencers", odict()) ])
     counter = 0
     for chain in chains:
-        chain_dict = {}
-
-        # Relevant attributes
-        chain_dict['counter'] = counter
-        chain_dict['name'] = chain
-        chain_dict['streams'] = chain_to_streams[chain]
-        chain_dict['nameHash'] = string2hash(chain)
-
-        # Other attributes not used in MTCalibPeb
-        chain_dict['groups'] = []
-        chain_dict['l1item'] = ''
-        chain_dict['l1thresholds'] = []
+        # Prepare information for stream list and fill separate dictionary
+        chain_streams = []
+        for stream in chain_to_streams[chain]:
+            stream_name = stream['name']
+            chain_streams.append(stream_name)
+            # If not already listed, add stream details to stream dictionary
+            if stream_name not in menu_dict["streams"]:
+                menu_dict["streams"][stream_name] = odict([
+                    ("name", stream_name),
+                    ("type", stream['type']),
+                    ("obeyLB", stream['obeyLB']),
+                    ("forceFullEventBuilding", stream['forceFullEventBuilding'])
+                ])
+
+        # Attributes not filled are not used in MTCalibPeb
+        menu_dict["chains"][chain] = odict([
+            ("counter", counter),
+            ("name", chain),
+            ("nameHash", string2hash(chain)),
+            ("l1item", ''),
+            ("l1thresholds", []),
+            ("groups", []),
+            ("streams", chain_streams),
+            ("sequencers", [] )
+        ])
 
-        menu_dict['chains'].append(chain_dict)
         counter += 1
 
     file_name = 'HLTMenu_{:s}.json'.format(menu_name)
 
     log.info('Writing trigger menu to %s', file_name)
     with open(file_name, 'w') as json_file:
-        json.dump(menu_dict, json_file, indent=4, sort_keys=True)
+        json.dump(menu_dict, json_file, indent=4, sort_keys=False)
 
     return file_name
diff --git a/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/src/MTCalibPebHypoTool.cxx b/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/src/MTCalibPebHypoTool.cxx
index a7442a31b97fdf1c3ed2e7b7be6c5a9c6af9734c..83c6a217465ae114f30247bb0c15ccd9de585282 100644
--- a/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/src/MTCalibPebHypoTool.cxx
+++ b/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/src/MTCalibPebHypoTool.cxx
@@ -200,35 +200,31 @@ StatusCode MTCalibPebHypoTool::decide(const MTCalibPebHypoTool::Input& input) co
     else robs = robVec;
 
     // Execute the ROB requests
-    switch (instr.type) {
-      case ROBRequestInstruction::Type::ADD: {
-        // Prefetch ROBs
-        ATH_MSG_DEBUG("Preloading ROBs: " << idsToString(robs));
-        m_robDataProviderSvc->addROBData(input.eventContext, robs, name()+"-ADD");
-        break;
-      }
-      case ROBRequestInstruction::Type::GET: {
-        // Retrieve ROBs
-        ATH_MSG_DEBUG("Retrieving ROBs: " << idsToString(robs));
-        // VROBFRAG is a typedef for std::vector<const eformat::ROBFragment<const uint32_t*>*>
-        IROBDataProviderSvc::VROBFRAG robFragments;
-        m_robDataProviderSvc->getROBData(input.eventContext, robs, robFragments, name()+"-GET");
-        ATH_MSG_DEBUG("Number of ROBs retrieved: " << robFragments.size());
-        if (!robFragments.empty())
-          ATH_MSG_DEBUG("List of ROBs found: " << std::endl << format(robFragments));
-        break;
-      }
-      case ROBRequestInstruction::Type::COL: {
-        // Event building
-        ATH_MSG_DEBUG("Requesting full event ROBs");
-        int nrobs = m_robDataProviderSvc->collectCompleteEventData(input.eventContext, name()+"-COL");
-        ATH_MSG_DEBUG("Number of ROBs retrieved: " << nrobs);
-        break;
-      }
-      default: {
-        ATH_MSG_ERROR("Invalid ROB request instruction " << instr.toString());
-        return StatusCode::FAILURE;
-      }
+    using ReqType = ROBRequestInstruction::Type;
+    if (instr.type == ReqType::ADD || instr.type == ReqType::ADDGET) {
+      // Prefetch ROBs
+      ATH_MSG_DEBUG("Preloading ROBs: " << idsToString(robs));
+      m_robDataProviderSvc->addROBData(input.eventContext, robs, name()+"-ADD");
+    }
+    if (instr.type == ReqType::GET || instr.type == ReqType::ADDGET) {
+      // Retrieve ROBs
+      ATH_MSG_DEBUG("Retrieving ROBs: " << idsToString(robs));
+      // VROBFRAG is a typedef for std::vector<const eformat::ROBFragment<const uint32_t*>*>
+      IROBDataProviderSvc::VROBFRAG robFragments;
+      m_robDataProviderSvc->getROBData(input.eventContext, robs, robFragments, name()+"-GET");
+      ATH_MSG_DEBUG("Number of ROBs retrieved: " << robFragments.size());
+      if (!robFragments.empty())
+        ATH_MSG_DEBUG("List of ROBs found: " << std::endl << format(robFragments));
+    }
+    if (instr.type == ReqType::COL) {
+      // Event building
+      ATH_MSG_DEBUG("Requesting full event ROBs");
+      int nrobs = m_robDataProviderSvc->collectCompleteEventData(input.eventContext, name()+"-COL");
+      ATH_MSG_DEBUG("Number of ROBs retrieved: " << nrobs);
+    }
+    if (instr.type == ReqType::INVALID) {
+      ATH_MSG_ERROR("Invalid ROB request instruction " << instr.toString());
+      return StatusCode::FAILURE;
     }
 
     // Sleep between ROB requests
@@ -290,6 +286,7 @@ MTCalibPebHypoTool::ROBRequestInstruction::ROBRequestInstruction(std::string_vie
 #endif
   if (str.find(":ADD:")!=std::string_view::npos) type = ROBRequestInstruction::ADD;
   else if (str.find(":GET:")!=std::string_view::npos) type = ROBRequestInstruction::GET;
+  else if (str.find(":ADDGET:")!=std::string_view::npos) type = ROBRequestInstruction::ADDGET;
   else if (str.find(":COL:")!=std::string_view::npos) type = ROBRequestInstruction::COL;
   if (size_t pos=str.find(":RND"); pos!=std::string_view::npos) {
     size_t firstDigit=pos+4;
@@ -307,6 +304,7 @@ const std::string MTCalibPebHypoTool::ROBRequestInstruction::toString() const {
   if (type==INVALID) s+="INVALID";
   else if (type==ADD) s+="ADD";
   else if (type==GET) s+="GET";
+  else if (type==ADDGET) s+="ADDGET";
   else if (type==COL) s+="COL";
   s += ", isRandom=";
   s += isRandom ? "true" : "false";
diff --git a/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/src/MTCalibPebHypoTool.h b/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/src/MTCalibPebHypoTool.h
index a4e13f068bb75a06ce2919aaa9a10646563418a7..58bad04d0e515216b0948781258b1c58a1fa6d75 100644
--- a/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/src/MTCalibPebHypoTool.h
+++ b/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/src/MTCalibPebHypoTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGEXPARTIALEB_MTCALIBPEBHYPOTOOL_H
@@ -52,7 +52,7 @@ private:
     /// String form for debug print-outs
     const std::string toString() const;
     /// Type of instruction
-    enum Type {INVALID, ADD, GET, COL} type = INVALID;
+    enum Type {INVALID, ADD, GET, ADDGET, COL} type = INVALID;
     /// Flag switching requests of a random sub-sample of the ROB list
     bool isRandom = false;
     /// Size of random request
@@ -83,11 +83,11 @@ private:
   Gaudi::Property<std::map<std::string,std::vector<uint32_t> > > m_robAccessDictProp {
     this, "ROBAccessDict", {},
     "Dictionary of prefetch/retrieve operations with given ROB IDs. The value is a vector of ROB IDs. "
-    "The string key has to contain :ADD: (prefetch), :GET: (retrieve), or :COL: (full event building). :ADD: and :GET: "
-    "may be also appended with :RNDX: where X is an integer. In this case, random X ROBs will be prefetched/retrieved "
-    "from the provided list, e.g. :GET:RND10: retrieves 10 random ROBs from the list. Otherwise the full list is used. "
-    "Note std::map is sorted by std::less<std::string>, so starting the key with a number may be needed to enforce "
-    "ordering, e.g. '01 :ADD:RND10:'."
+    "The string key has to contain :ADD: (prefetch), :GET: (retrieve), :ADDGET: (prefetch+retrieve) or :COL: (full "
+    "event building). :ADD:, :GET: and :ADDGET: may be also appended with :RNDX: where X is an integer. In this case, "
+    "random X ROBs will be prefetched/retrieved from the provided list, e.g. :GET:RND10: retrieves 10 random ROBs from "
+    "the list. Otherwise the full list is used. Note std::map is sorted by std::less<std::string>, so starting the key "
+    "with a number may be needed to enforce ordering, e.g. '01 :ADD:RND10:'."
   };
   Gaudi::Property<unsigned int> m_timeBetweenRobReqMillisec {
     this, "TimeBetweenROBReqMillisec", 0,
diff --git a/HLT/Trigger/TrigControl/TrigPSC/src/Psc.cxx b/HLT/Trigger/TrigControl/TrigPSC/src/Psc.cxx
index cd0625d453e6be6625c977eacfbd253358844f19..0d06488d73591f3cf37ca5300414d593a408a2c9 100644
--- a/HLT/Trigger/TrigControl/TrigPSC/src/Psc.cxx
+++ b/HLT/Trigger/TrigControl/TrigPSC/src/Psc.cxx
@@ -44,6 +44,8 @@
 
 #include <boost/property_tree/xml_parser.hpp>
 
+#include "CxxUtils/checker_macros.h"
+
 using namespace boost::property_tree;
 
 namespace
@@ -523,7 +525,20 @@ bool psc::Psc::prepareForRun (const ptree& args)
   }
 
   // bind args to prepareForRun
-  auto prep = [&args](ITrigEventLoopMgr* mgr){return mgr->prepareForRun(args);};
+  auto prep = [&args](ITrigEventLoopMgr* mgr) {
+    // FIXME: ITrigEventLookMgr::prepareForRun is declared NOT_THREAD_SAFE.
+    // Probably this method shoud also be NOT_THREAD_SAFE, but that's
+    // awkward because it implements a tdaq interface from hltinterface.
+    StatusCode ret ATLAS_THREAD_SAFE = mgr->prepareForRun (args);
+
+    // This dance is needed to prevent RV optimization.
+    // Otherwise, the optimizer loses the ATLAS_THREAD_SAFE attribute
+    // on RET before the thread-safety checker gets to see the code.
+    if (ret.isSuccess()) {
+      return StatusCode (StatusCode::SUCCESS);
+    }
+    return ret;
+  };
   if(!callOnEventLoopMgr<ITrigEventLoopMgr>(prep, "prepareForRun").isSuccess())
   {
     ERS_PSC_ERROR("Error preparing the EventLoopMgr");
diff --git a/HLT/Trigger/TrigControl/TrigServices/python/TrigServicesConfig.py b/HLT/Trigger/TrigControl/TrigServices/python/TrigServicesConfig.py
index df658475c82c328cabf001bae5fdaa410fca9fbb..9e363ea071c8e9adf2b69c038c017a6c6e53b3fe 100644
--- a/HLT/Trigger/TrigControl/TrigServices/python/TrigServicesConfig.py
+++ b/HLT/Trigger/TrigControl/TrigServices/python/TrigServicesConfig.py
@@ -105,13 +105,13 @@ class HltROBDataProviderSvc(_HltROBDataProviderSvc):
                          xbins=100, xmin=0, xmax=500),
          defineHistogram('TIME_ROBRequest', path='EXPERT', type='TH1F',
                          title='Time for ROB retrievals;time [mu s]',
-                         xbins=100, xmin=0, xmax=10000),
+                         xbins=400, xmin=0, xmax=200000),
          defineHistogram('NUMBER_ROBRequest', path='EXPERT', type='TH1F',
                          title='Number of retrieved ROBs;number',
                          xbins=100, xmin=0, xmax=1000),
          defineHistogram('TIME_CollectAllROBs', path='EXPERT', type='TH1F',
                          title='Time for retrieving complete event data;time [mu s]',
-                         xbins=100, xmin=0, xmax=10000),
+                         xbins=400, xmin=0, xmax=200000),
          defineHistogram('NUMBER_CollectAllROBs', path='EXPERT', type='TH1F',
                          title='Number of received ROBs for collect call;number',
                          xbins=100, xmin=0, xmax=2500)
@@ -141,5 +141,5 @@ class HltEventLoopMgr(_HltEventLoopMgr):
                                    xbins=200, xmin=0, xmax=10000)
       self.MonTool.defineHistogram('SlotIdleTime', path='EXPERT', type='TH1F',
                                    title='Time between freeing and assigning a scheduler slot;Time [ms];Events',
-                                   xbins=200, xmin=0, xmax=200)
+                                   xbins=400, xmin=0, xmax=400)
       return
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.cxx b/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.cxx
index bb03640d3dcc76319ef3d4c8b6cb31d989e99ee5..20c566df027c05f0c40c032be6a2d6f6a33676e4 100644
--- a/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.cxx
+++ b/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.cxx
@@ -142,6 +142,9 @@ StatusCode HltROBDataProviderSvc::initialize()
     }
   }
 
+  // prefetch all ROBs in a ROS on a first retrieval of ROBs from this ROS
+  ATH_MSG_INFO(" ---> Prefetch all ROBs in a ROS on first retrieval                = " << m_prefetchAllROBsfromROS);
+
   // Setup the slot specific cache
   m_eventsCache = SG::SlotSpecificObj<EventCache>( SG::getNSlots() );
 
@@ -307,6 +310,15 @@ void HltROBDataProviderSvc::setNextEvent(const EventContext& context, const RawE
   ATH_MSG_DEBUG("      current [global id, LVL1 id] = [" << cache->globalEventNumber << "," << cache->currentLvl1ID << "]" );
   ATH_MSG_DEBUG("      number of received ROBs      =  " << rob_fragments.size() );
   ATH_MSG_DEBUG("      size of ROB cache            =  " << cache->robmap.size() );
+
+  //------------------------------+
+  // Initiate whole ROS retrieval |
+  //------------------------------+
+  if ( m_prefetchAllROBsfromROS.value() && m_enabledROBs.value().size() != 0 ) {
+    addROBData( context, m_enabledROBs.value(), "prefetch_HLTROBDataProviderSvc" );
+    ATH_MSG_DEBUG("      ROS prefetch init. size      =  " << m_enabledROBs.value().size() );
+  }
+
   return;
 }
 
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.h b/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.h
index bb033aa73384c769ad6edf0f10588904aa13f110..1a526c415c45479e7984a36e4e39face361bf778 100644
--- a/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.h
+++ b/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 #ifndef TRIGSERVICES_HLTROBDATAPROVIDERSVC_H
 #define TRIGSERVICES_HLTROBDATAPROVIDERSVC_H
@@ -161,6 +161,10 @@ private:
   Gaudi::Property< std::vector<uint32_t> > m_enabledROBs{
     this, "enabledROBs", {} , "Enabled ROBs for retrieval"};
 
+  // prefetch all ROBs from a ROS if ROB data from this ROS are requested
+  Gaudi::Property<bool> m_prefetchAllROBsfromROS{
+    this, "prefetchAllROBsfromROS", false , "When ROBs from a ROS are requested then prefetch all ROBs in this ROS"};
+
   /*------------------------+
    * Methods acting on ROBs |
    *------------------------+ 
diff --git a/InnerDetector/InDetCalibAlgs/InDetBeamSpotFinder/share/AdditionalVertexing.py b/InnerDetector/InDetCalibAlgs/InDetBeamSpotFinder/share/AdditionalVertexing.py
index 556676f766fd8537b2c24a97f96be1a0c70640d4..e7d9c378280d7621f10ca0c9f85deb649df9fc7f 100644
--- a/InnerDetector/InDetCalibAlgs/InDetBeamSpotFinder/share/AdditionalVertexing.py
+++ b/InnerDetector/InDetCalibAlgs/InDetBeamSpotFinder/share/AdditionalVertexing.py
@@ -196,13 +196,9 @@ def GeneralVertexer(system='Combined', setup=None,tracksName=None, suffix=""):
             InDetPriVxFinderTool_vx.maxChi2PerTrack = 15.
     
     elif vxSetup == 'AdaptiveFinding':
+        #
         # --- load adaptive primary vertex finder
         #
-        # from InDetPriVxFinderTool.InDetPriVxFinderToolConf import InDet__InDetAdaptivePriVxFinderTool
-        # InDetPriVxFinderTool_Si = InDet__InDetAdaptivePriVxFinderTool(name             = "InDetAdaptivePriVxFinderTool_Si",
-        #                                                              VertexFitterTool = InDetVxFitterTool,
-        #                                                              TrackSelector    = InDetTrackSelectorTool_Si
-        #                                                              )
         
         from InDetPriVxFinderTool.InDetPriVxFinderToolConf import InDet__InDetIterativePriVxFinderTool
         InDetPriVxFinderTool_vx = InDet__InDetIterativePriVxFinderTool(name             = "InDetIterativePriVxFinderTool_"+system+"_"+vxSetup+suffix,
diff --git a/InnerDetector/InDetCalibAlgs/InDetBeamSpotFinder/share/AdditionalVertexing_old.py b/InnerDetector/InDetCalibAlgs/InDetBeamSpotFinder/share/AdditionalVertexing_old.py
index fbc4b41a2b6abae7658b31fb8f639749ed80f7b2..a3a1034ee2844786e5eaeb5088ca9db6cf04163c 100644
--- a/InnerDetector/InDetCalibAlgs/InDetBeamSpotFinder/share/AdditionalVertexing_old.py
+++ b/InnerDetector/InDetCalibAlgs/InDetBeamSpotFinder/share/AdditionalVertexing_old.py
@@ -80,13 +80,9 @@ if (not (InDetFlags.primaryVertexSetup() == 'AdaptiveFinding') and
       InDetPriVxFinderTool_Pix.maxChi2PerTrack = 15.
     
 elif InDetFlags.primaryVertexSetup() == 'AdaptiveFinding':
+    #
     # --- load adaptive primary vertex finder
     #
-    #from InDetPriVxFinderTool.InDetPriVxFinderToolConf import InDet__InDetAdaptivePriVxFinderTool
-    #InDetPriVxFinderTool_Si = InDet__InDetAdaptivePriVxFinderTool(name             = "InDetAdaptivePriVxFinderTool_Si",
-    #                                                              VertexFitterTool = InDetVxFitterTool,
-    #                                                              TrackSelector    = InDetTrackSelectorTool_Si
-    #                                                              )
 
     from InDetPriVxFinderTool.InDetPriVxFinderToolConf import InDet__InDetIterativePriVxFinderTool
     InDetPriVxFinderTool_Pix = InDet__InDetIterativePriVxFinderTool(name             = "InDetIterativePriVxFinderTool_Pix",
diff --git a/InnerDetector/InDetConditions/PixelConditionsAlgorithms/src/PixeldEdxAlg.cxx b/InnerDetector/InDetConditions/PixelConditionsAlgorithms/src/PixeldEdxAlg.cxx
index def223c797bef3e3e6e6e8808d155e34f14aa7f5..986f74861234fccab0be13b14b69ba6014c1c730 100644
--- a/InnerDetector/InDetConditions/PixelConditionsAlgorithms/src/PixeldEdxAlg.cxx
+++ b/InnerDetector/InDetConditions/PixelConditionsAlgorithms/src/PixeldEdxAlg.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "PixeldEdxAlg.h"
@@ -22,7 +22,7 @@ StatusCode PixeldEdxAlg::initialize() {
 
   ATH_CHECK(m_condSvc.retrieve());
 
-  ATH_CHECK(m_readKey.initialize());
+  ATH_CHECK(m_readKey.initialize(m_readfromcool));
   ATH_CHECK(m_writeKey.initialize());
   if (m_readfromcool) {
     if (m_condSvc->regHandle(this,m_writeKey).isFailure()) {
diff --git a/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..eed4ad1258efaf3086c04465e527ece85975f5f4
--- /dev/null
+++ b/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetConditions/PixelConditionsData
diff --git a/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/PixelClusterOnTrackErrorData.h b/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/PixelClusterOnTrackErrorData.h
index f40cef7ad2d89f039e99bc704ddca7a3b04a519b..bc9ba56fc70e9e554285e91626edf9009b9d3677 100644
--- a/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/PixelClusterOnTrackErrorData.h
+++ b/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/PixelClusterOnTrackErrorData.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -44,24 +44,24 @@ class PixelClusterOnTrackErrorData {
 
 
     // get parametrizations
-    const std::vector<float> getClusterSizeBinsX(){return m_csx;}
-    const std::vector<float> getClusterSizeBinsY(){return m_csy;}
-    const std::vector<float> getEtaBins(){return m_etaref;}
-    const std::vector<float> getIncidenceAngleBins(){return m_phibins;}
+    const std::vector<float> getClusterSizeBinsX() const {return m_csx;}
+    const std::vector<float> getClusterSizeBinsY() const {return m_csy;}
+    const std::vector<float> getEtaBins() const {return m_etaref;}
+    const std::vector<float> getIncidenceAngleBins() const {return m_phibins;}
     // IBL
-    const std::vector<float> getEtaIBLBins(){return m_ibletaref;}
-    const std::vector<float> getIncidenceAngleIBLBins(){return m_iblphibins;}
+    const std::vector<float> getEtaIBLBins() const {return m_ibletaref;}
+    const std::vector<float> getIncidenceAngleIBLBins() const {return m_iblphibins;}
 
 
     // old parametrization (analytical formula)
-    double getPixelBarrelPhiError(double ang, int phiClusterSize); 
+    double getPixelBarrelPhiError(double ang, int phiClusterSize) const; 
 
     // new parametrization (read from DB)
-    float getPixelBarrelEtaError(int ibin);
-    float getPixelBarrelPhiError(int ibin);
+    float getPixelBarrelEtaError(int ibin) const;
+    float getPixelBarrelPhiError(int ibin) const;
     // IBL
-    float getPixelIBLEtaError(int ibin);
-    float getPixelIBLPhiError(int ibin);
+    float getPixelIBLEtaError(int ibin) const;
+    float getPixelIBLPhiError(int ibin) const;
 
     void setParameters(const int ncsx, const int ncsy, const int neta, const int nalpha, 
                        int offset, std::vector<float> constants);
@@ -76,13 +76,13 @@ class PixelClusterOnTrackErrorData {
       m_ibletaerror[ibin] = error; }
 
 
-    int getBarrelBinPhi(double angle, int phiClusterSize);
+    int getBarrelBinPhi(double angle, int phiClusterSize) const;
 
     int getBarrelBinEta(double eta, int etaClusterSize, 
-		      int phiClusterSize);
+		      int phiClusterSize) const;
     // IBL
-    int getIBLBinPhi(double angle, int phiClusterSize);
-    int getIBLBinEta(double eta, int etaClusterSize);
+    int getIBLBinPhi(double angle, int phiClusterSize) const;
+    int getIBLBinEta(double eta, int etaClusterSize) const;
 
     // save constants on text file
     void Print(std::string file) const;
diff --git a/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/PixelOfflineCalibData.h b/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/PixelOfflineCalibData.h
index f6b9af934b565325c1740c3eb1b2ddfc0acd433a..c77c29d0da40c60a520912942a87d110784377ea 100644
--- a/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/PixelOfflineCalibData.h
+++ b/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/PixelOfflineCalibData.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -51,9 +51,12 @@ class PixelOfflineCalibData{
   int size() const;
   
   // get the pointer to pixel cluster error data
-  PixelClusterErrorData* getPixelClusterErrorData() const; 
-  PixelChargeInterpolationParameters* getPixelChargeInterpolationParameters() const; 
-  PixelClusterOnTrackErrorData* getPixelClusterOnTrackErrorData() const;
+  PixelClusterErrorData* getPixelClusterErrorData();
+  PixelChargeInterpolationParameters* getPixelChargeInterpolationParameters();
+  PixelClusterOnTrackErrorData* getPixelClusterOnTrackErrorData();
+  const PixelClusterErrorData* getPixelClusterErrorData() const; 
+  const PixelChargeInterpolationParameters* getPixelChargeInterpolationParameters() const; 
+  const PixelClusterOnTrackErrorData* getPixelClusterOnTrackErrorData() const;
 
   // Get/Set the numerical constants 
   int GetNumberOfConstants() const;
@@ -109,15 +112,28 @@ inline bool PixelOfflineCalibData::update(const PixelClusterOnTrackErrorData& id
   return true;
 }
 
-inline PixelClusterErrorData* PixelOfflineCalibData::getPixelClusterErrorData() const {
+inline PixelClusterErrorData* PixelOfflineCalibData::getPixelClusterErrorData() {
   return m_clustererrordata;
 }
 
-inline PixelChargeInterpolationParameters* PixelOfflineCalibData::getPixelChargeInterpolationParameters() const {
+inline PixelChargeInterpolationParameters* PixelOfflineCalibData::getPixelChargeInterpolationParameters() {
   return m_chargeinterpolationparameters;
 }
 
 inline PixelClusterOnTrackErrorData* 
+    PixelOfflineCalibData::getPixelClusterOnTrackErrorData() {
+  return m_clusterontrackerrordata;
+}
+
+inline const PixelClusterErrorData* PixelOfflineCalibData::getPixelClusterErrorData() const {
+  return m_clustererrordata;
+}
+
+inline const PixelChargeInterpolationParameters* PixelOfflineCalibData::getPixelChargeInterpolationParameters() const {
+  return m_chargeinterpolationparameters;
+}
+
+inline const PixelClusterOnTrackErrorData* 
     PixelOfflineCalibData::getPixelClusterOnTrackErrorData() const {
   return m_clusterontrackerrordata;
 }
diff --git a/InnerDetector/InDetConditions/PixelConditionsData/src/PixelClusterOnTrackErrorData.cxx b/InnerDetector/InDetConditions/PixelConditionsData/src/PixelClusterOnTrackErrorData.cxx
index 569e6aa6886c4f554429addb84c65a7111e9327d..83f75b2a922268743aa272929479c2d14b946764 100644
--- a/InnerDetector/InDetConditions/PixelConditionsData/src/PixelClusterOnTrackErrorData.cxx
+++ b/InnerDetector/InDetConditions/PixelConditionsData/src/PixelClusterOnTrackErrorData.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "PixelConditionsData/PixelClusterOnTrackErrorData.h"
@@ -124,7 +124,7 @@ int PixelClusterOnTrackErrorData::getNumberOfEtaIBLBins() const{
 }
 
 double PixelClusterOnTrackErrorData::getPixelBarrelPhiError(double ang, 
-                                                    int deltax){ 
+                                                    int deltax) const { 
    double errphi=50*CLHEP::micrometer/pow(12,0.5);
    // error on phi coordinate
     if(deltax == 1){
@@ -159,39 +159,35 @@ double PixelClusterOnTrackErrorData::getPixelBarrelPhiError(double ang,
     return errphi; 
 }
 
-float PixelClusterOnTrackErrorData::getPixelBarrelEtaError(int ibin){
+float PixelClusterOnTrackErrorData::getPixelBarrelEtaError(int ibin) const {
   if(ibin < 0) return -1;
   if(static_cast<unsigned int>(ibin) >= m_barreletaerror.size()) return -2;
   return m_barreletaerror[ibin];
 }
 
-float PixelClusterOnTrackErrorData::getPixelBarrelPhiError(int ibin){
+float PixelClusterOnTrackErrorData::getPixelBarrelPhiError(int ibin) const {
   if(ibin < 0){ return -1; }
   if(static_cast<unsigned int>(ibin) >= m_barrelphierror.size()){ return -2;}
   return m_barrelphierror[ibin];
 }
 
-float PixelClusterOnTrackErrorData::getPixelIBLEtaError(int ibin){
+float PixelClusterOnTrackErrorData::getPixelIBLEtaError(int ibin) const {
     if(ibin < 0||m_version>-2) return -1;
     if(static_cast<unsigned int>(ibin) >= m_ibletaerror.size()) return -2;
     return m_ibletaerror[ibin];
 }
 
-float PixelClusterOnTrackErrorData::getPixelIBLPhiError(int ibin){
+float PixelClusterOnTrackErrorData::getPixelIBLPhiError(int ibin) const {
     if(ibin < 0||m_version>-2){ return -1; }
     if(static_cast<unsigned int>(ibin) >= m_iblphierror.size()){ return -2;}
     return m_iblphierror[ibin];
 }
 
 int PixelClusterOnTrackErrorData::getBarrelBinPhi(double angle, 
-                                   int phiClusterSize){
+                                   int phiClusterSize) const {
 
   int iang =0;
   int nang = m_phibins.size();
-  if(nang == 0) {
-    Initialize();
-    nang = m_phibins.size();
-  }
   for(int i=0; i<nang; i++){  
     if(angle > m_phibins[i]) iang=i;  
   } 
@@ -205,14 +201,10 @@ int PixelClusterOnTrackErrorData::getBarrelBinPhi(double angle,
 }
 
 int PixelClusterOnTrackErrorData::getBarrelBinEta(double eta, int etaClusterSize, 
-    int phiClusterSize){
+    int phiClusterSize) const {
 
   int ieta=0;
   int neta = m_etaref.size();
-  if(neta == 0) {
-    Initialize();
-    neta = m_etaref.size();
-  }
   for(int i=0; i<neta; i++){  
     if(eta>m_etaref[i]) ieta=i;  
   } 
@@ -232,7 +224,7 @@ int PixelClusterOnTrackErrorData::getBarrelBinEta(double eta, int etaClusterSize
 }
 
 int PixelClusterOnTrackErrorData::getIBLBinPhi(double angle,
-						    int phiClusterSize){
+						    int phiClusterSize) const {
     if(m_version>-2) return -1;
     int iang =0;
     int nang = m_iblphibins.size();
@@ -246,7 +238,7 @@ int PixelClusterOnTrackErrorData::getIBLBinPhi(double angle,
     return m_csxbinsibl*iang+iphi;
 }
 
-int PixelClusterOnTrackErrorData::getIBLBinEta(double eta, int etaClusterSize){
+int PixelClusterOnTrackErrorData::getIBLBinEta(double eta, int etaClusterSize) const {
 
     if(m_version>-2) return -1;
     int ieta=0;
diff --git a/InnerDetector/InDetConditions/PixelConditionsData/src/SpecialPixelMap.cxx b/InnerDetector/InDetConditions/PixelConditionsData/src/SpecialPixelMap.cxx
index 51aa639ac91ea41d5946cdc47427a4129d9df7b8..c8296aaf9b983076b485f3921ca1142173730a2e 100755
--- a/InnerDetector/InDetConditions/PixelConditionsData/src/SpecialPixelMap.cxx
+++ b/InnerDetector/InDetConditions/PixelConditionsData/src/SpecialPixelMap.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "PixelConditionsData/SpecialPixelMap.h"
@@ -20,7 +20,7 @@
 
 //***** DetectorSpecialPixelMap *****//
 const int nmtype(5);
-static unsigned int columnsPerFEIX[5]={18,80,132,80,132}; // number of columns per FEI3, 4, 50, 51, 52 
+static const unsigned int columnsPerFEIX[5]={18,80,132,80,132}; // number of columns per FEI3, 4, 50, 51, 52 
 //static unsigned int rowsPerFEIX[5]={164, 336, 672, 339, 678}; // number of rows per FEI3, 4, 50, 51, 52
 //static unsigned int rowsRdoPerFEIX[5]={160, 336, 672, 336, 672}; // number of rows readout per FEI3, 4, 50, 51, 52
 
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/share/testReadout.py b/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/share/testReadout.py
index 4da660eb533574b7101b778d547eb9161c15d1c5..b317d7d79635fcdfc2f641d2c2b2dbf6885b89c8 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/share/testReadout.py
+++ b/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/share/testReadout.py
@@ -88,6 +88,7 @@ conddb.addFolderSplitMC("SCT", "/SCT/DAQ/Config/MUR", "/SCT/DAQ/Config/MUR")
 
 from SCT_ConditionsAlgorithms.SCT_ConditionsAlgorithmsConf import SCT_ReadoutTestAlg
 SCT_ReadoutTestAlg = SCT_ReadoutTestAlg()
+SCT_ReadoutTestAlg.SCT_ReadoutTool.SCT_CablingTool = ''
 
 # Module type and link status
 #SCT_ReadoutTestAlg.ModuleId = 143704064   # Endcap (default is barrel)
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/share/testTdaqEnabled.py b/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/share/testTdaqEnabled.py
index 044eafd34f340ae001c69bf371ce5828c658b620..ae84c18198a0b6c6286eb9ff4078b46a3ee8e48d 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/share/testTdaqEnabled.py
+++ b/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/share/testTdaqEnabled.py
@@ -85,6 +85,12 @@ condSeq = AthSequencer("AthCondSeq")
 from xAODEventInfoCnv.xAODEventInfoCreator import xAODMaker__EventInfoCnvAlg
 condSeq+=xAODMaker__EventInfoCnvAlg(OutputLevel=2)
 
+condAlgName = "SCT_CablingCondAlgFromCoraCool"
+if not hasattr(condSeq, condAlgName):
+    from AthenaCommon.CfgGetter import getAlgorithm
+    SCT_CablingCondAlgFromCoraCool = getAlgorithm(condAlgName)
+    condSeq += SCT_CablingCondAlgFromCoraCool
+
 from SCT_ConditionsTools.SCT_TdaqEnabledToolSetup import SCT_TdaqEnabledToolSetup
 sct_TdaqEnabledToolSetup = SCT_TdaqEnabledToolSetup()
 sct_TdaqEnabledToolSetup.setup()
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/src/SCT_DCSConditionsStatCondAlg.cxx b/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/src/SCT_DCSConditionsStatCondAlg.cxx
index 90576ddc47c00ec795074c6db6ed859be699a67a..0d61c20abd1678a77e60c2f9c7686c691082d06e 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/src/SCT_DCSConditionsStatCondAlg.cxx
+++ b/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/src/SCT_DCSConditionsStatCondAlg.cxx
@@ -82,6 +82,8 @@ StatusCode SCT_DCSConditionsStatCondAlg::execute(const EventContext& ctx) const
   std::unique_ptr<SCT_DCSStatCondData> writeCdoState{std::make_unique<SCT_DCSStatCondData>()};
 
   // Read state info
+  // Meaning of state word is found at
+  // https://twiki.cern.ch/twiki/bin/view/Atlas/SctDCSSoftware#Decoding_Status_words
   std::string paramState{"STATE"};
   CondAttrListCollection::const_iterator attrListState{readCdoState->begin()};
   CondAttrListCollection::const_iterator endState{readCdoState->end()};
@@ -92,11 +94,17 @@ StatusCode SCT_DCSConditionsStatCondAlg::execute(const EventContext& ctx) const
     const CondAttrListCollection::AttributeList &payload{attrListState->second};
     if (payload.exists(paramState) and not payload[paramState].isNull()) {
       unsigned int val{payload[paramState].data<unsigned int>()};
-      unsigned int hvstate{val bitand 240};
-      unsigned int lvstate{val bitand 15};
-      if (   ( (m_chanstatCut=="NORM")  and not ((hvstate==16 or hvstate==48)                                and (lvstate==1 or lvstate==3))                             )
-          or ( (m_chanstatCut=="NSTBY") and not ((hvstate==16 or hvstate==48 or hvstate==32)                 and (lvstate==1 or lvstate==3 or lvstate==2))               )
-          or ( (m_chanstatCut=="LOOSE") and not ((hvstate==16 or hvstate==48 or hvstate==32 or hvstate==128) and (lvstate==1 or lvstate==3 or lvstate==2 or lvstate==8)) )) {
+      unsigned int hvstate{(val >> 4) & 0xF};
+      unsigned int lvstate{ val       & 0xF};
+      if (   ((m_chanstatCut=="NORM")  
+              and not ((hvstate==ON or hvstate==MANUAL)
+                       and (lvstate==ON or lvstate==MANUAL)))
+          or ((m_chanstatCut=="NSTBY")
+              and not ((hvstate==ON or hvstate==MANUAL or hvstate==STANDBY)
+                       and (lvstate==ON or lvstate==MANUAL or lvstate==STANDBY)))
+          or ((m_chanstatCut=="LOOSE")
+              and not ((hvstate==ON or hvstate==MANUAL or hvstate==STANDBY or hvstate==RAMPING)
+                       and (lvstate==ON or lvstate==MANUAL or lvstate==STANDBY or lvstate==RAMPING)))) {
         writeCdoState->fill(channelNumber, paramState);
       } else {
         writeCdoState->remove(channelNumber, paramState);
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/src/SCT_DCSConditionsStatCondAlg.h b/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/src/SCT_DCSConditionsStatCondAlg.h
index 9b06603159dee2cea6ddbb2f7a285e2e83dc57cc..1f36dc56b9becc80c811ab0c426c7b0f1f18d7f4 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/src/SCT_DCSConditionsStatCondAlg.h
+++ b/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/src/SCT_DCSConditionsStatCondAlg.h
@@ -1,7 +1,7 @@
 // -*- C++ -*-
 
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */ 
 
 #ifndef SCT_DCSCONDITIONSSTATCONDALG
@@ -30,6 +30,25 @@ class SCT_DCSConditionsStatCondAlg : public AthReentrantAlgorithm
   virtual bool isClonable() const override { return true; }
 
  private:
+  // Meaning of state word is found at
+  // https://twiki.cern.ch/twiki/bin/view/Atlas/SctDCSSoftware#Decoding_Status_words
+  enum StateWord {OFF=0x0,
+                  ON=0x1,
+                  STANDBY=0x2,
+                  MANUAL=0x3,
+                  MASK_OFF=0x4,
+                  MASK_ON=0x5,
+                  HARD_RESET=0x6,
+                  DISABLED=0x7,
+                  RAMPING=0x8,
+                  INTERLOCKED=0x9,
+                  TRIP_HW=0xA,
+                  TRIP_SW=0xB,
+                  LVCARD_LATCH=0xC,
+                  NO_MATCH=0xD,
+                  UNKNOWN=0xE,
+                  ANY=0xF};
+
   SG::ReadCondHandleKey<CondAttrListCollection> m_readKeyHV{this, "ReadKeyHV", "/SCT/DCS/HV", "Key of input (raw) HV conditions folder"};
   SG::ReadCondHandleKey<CondAttrListCollection> m_readKeyState{this, "ReadKeyState", "/SCT/DCS/CHANSTAT", "Key of input (raw) State conditions folder"};
   SG::WriteCondHandleKey<SCT_DCSStatCondData> m_writeKeyState{this, "WriteKeyState", "SCT_DCSStatCondData", "Key of output (derived) State conditions data"};
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsTools/src/SCT_ReadoutTool.cxx b/InnerDetector/InDetConditions/SCT_ConditionsTools/src/SCT_ReadoutTool.cxx
index 0ee1f02af526f36bec2da99f7810ed06472ac144..f9842458af648f9ad2b071926eaac0347066aef4 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsTools/src/SCT_ReadoutTool.cxx
+++ b/InnerDetector/InDetConditions/SCT_ConditionsTools/src/SCT_ReadoutTool.cxx
@@ -21,7 +21,9 @@ SCT_ReadoutTool::SCT_ReadoutTool(const std::string& type, const std::string& nam
 StatusCode SCT_ReadoutTool::initialize() {
   ATH_MSG_DEBUG("Initialize SCT_ReadoutTool");
   // Retrieve cabling
-  ATH_CHECK(m_cablingTool.retrieve());
+  if (!m_cablingTool.empty()) {
+    ATH_CHECK(m_cablingTool.retrieve());
+  }
   // Retrieve SCT helper
   ATH_CHECK(detStore()->retrieve(m_sctId, "SCT_ID"));
   // Get MessageSvc for SCT_ReadoutData
diff --git a/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..3c71a096029e524f8aaf60682992976ce3d4b8a0
--- /dev/null
+++ b/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetConditions/TRT_ConditionsData
diff --git a/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/ExpandedIdentifier.h b/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/ExpandedIdentifier.h
index a4c66f6fb999ed9c4a0ee6ad8523972366a20a15..59e9aa01f8c6ae4806dc4db5b274ca56124a190b 100755
--- a/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/ExpandedIdentifier.h
+++ b/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/ExpandedIdentifier.h
@@ -1,11 +1,12 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRTConditionsData_TRTCondIdentifier_h
 #define TRTConditionsData_TRTCondIdentifier_h
 
 #include <iostream>
+#include <string>
 
 namespace TRTCond
 {
@@ -63,8 +64,8 @@ namespace TRTCond
     size_t level() const { return m_level ; }
     
     /** returns level name */
-    static const char* name(size_t l) { 
-      static const char* names[] = {"detector","barrelec","layer_or_wheel","module","straw_layer","straw"} ;
+    const std::string name(size_t l) const { 
+      static const std::string names[] = {"detector","barrelec","layer_or_wheel","module","straw_layer","straw"} ;
       return names[l] ;
     }
     
diff --git a/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/HWMap.h b/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/HWMap.h
index e35a7ceb070f0800bf315c24595ffcca1ac31378..b53778d1b15fb87d03a665ae769511c23d062336 100644
--- a/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/HWMap.h
+++ b/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/HWMap.h
@@ -26,12 +26,12 @@ namespace TRTCond{
 
   virtual ~HWMap() {}
 
-  std::vector<std::string>* get_Barrel_HV_Names() const {return m_Barrel_HV_CoolChanNames; } 
-  std::vector<std::string>* get_EndcapA_HV_Names() const {return m_EndcapA_HV_CoolChanNames; } 
-  std::vector<std::string>* get_EndcapC_HV_Names() const {return m_EndcapC_HV_CoolChanNames; } 
-  std::vector<int>* get_Barrel_HV_Nums() const {return m_Barrel_HV_CoolChanNums; }
-  std::vector<int>* get_EndcapA_HV_Nums() const {return m_EndcapA_HV_CoolChanNums; }
-  std::vector<int>* get_EndcapC_HV_Nums() const {return m_EndcapC_HV_CoolChanNums; }
+  const std::vector<std::string>* get_Barrel_HV_Names() const {return m_Barrel_HV_CoolChanNames; } 
+  const std::vector<std::string>* get_EndcapA_HV_Names() const {return m_EndcapA_HV_CoolChanNames; } 
+  const std::vector<std::string>* get_EndcapC_HV_Names() const {return m_EndcapC_HV_CoolChanNames; } 
+  const std::vector<int>* get_Barrel_HV_Nums() const {return m_Barrel_HV_CoolChanNums; }
+  const std::vector<int>* get_EndcapA_HV_Nums() const {return m_EndcapA_HV_CoolChanNums; }
+  const std::vector<int>* get_EndcapC_HV_Nums() const {return m_EndcapC_HV_CoolChanNums; }
  
   void setBarrelName(int i, const std::string & name) {
     m_Barrel_HV_CoolChanNames->at(i)=name;
diff --git a/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/NestedContainer.h b/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/NestedContainer.h
index 559102e201601d8df1e0b93108e2370dcc87f380..cdca38a253dc4d3b2b0fd5c8486a9dfd1d6f741d 100755
--- a/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/NestedContainer.h
+++ b/InnerDetector/InDetConditions/TRT_ConditionsData/TRT_ConditionsData/NestedContainer.h
@@ -333,7 +333,8 @@ namespace TRTCond
     }
     void print() const {
       printindent() ;
-      std::cout << "level = " << ExpandedIdentifier::name(NestingLevel) << " (" << NestingLevel << ")"  << std::endl ;
+      ExpandedIdentifier id;
+      std::cout << "level = " << id.name(NestingLevel) << " (" << NestingLevel << ")"  << std::endl ;
       for(unsigned int i=0; i< m_daughters.size(); ++i) {
 	printindent() ;
 	std::cout << "daughter " << i << std::endl ;
diff --git a/InnerDetector/InDetConditions/TRT_ConditionsServices/src/TRT_StrawNeighbourSvc.h b/InnerDetector/InDetConditions/TRT_ConditionsServices/src/TRT_StrawNeighbourSvc.h
index 12a86b8741a40f665bdfb5175aaacc7224924051..7adf571aa02f61ac68ff53db0f34bb1e6d7b786f 100755
--- a/InnerDetector/InDetConditions/TRT_ConditionsServices/src/TRT_StrawNeighbourSvc.h
+++ b/InnerDetector/InDetConditions/TRT_ConditionsServices/src/TRT_StrawNeighbourSvc.h
@@ -19,7 +19,7 @@
 class TRT_ID;
 class StoreGateSvc;
 
-class TRT_StrawNeighbourSvc: public AthService,
+class ATLAS_CHECK_THREAD_SAFETY TRT_StrawNeighbourSvc: public AthService,
   virtual public ITRT_StrawNeighbourSvc
 {
  public:
diff --git a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/IInDetServMatBuilderTool.h b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/IInDetServMatBuilderTool.h
index 5cd2eeb8e3d64c66744d99f1ef4954d0586626da..d3ac8a4d069d5612b64f503b7faca2b8b0fa5aa1 100644
--- a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/IInDetServMatBuilderTool.h
+++ b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/IInDetServMatBuilderTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -24,7 +24,7 @@ class IInDetServMatBuilderTool : virtual public IAlgTool {
 public:
   static const InterfaceID& interfaceID( ) ;
   
-  virtual const std::vector<const InDetDD::ServiceVolume *> & getServices() = 0;  
+  virtual const std::vector<const InDetDD::ServiceVolume *> & getServices() const = 0;  
 };
   
 inline const InterfaceID& IInDetServMatBuilderTool::interfaceID()
diff --git a/InnerDetector/InDetDetDescr/InDetRegionSelector/InDetRegionSelector/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetDetDescr/InDetRegionSelector/InDetRegionSelector/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..4e4a8d827772b75fe8dd42118f0d72db525d8ced
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetRegionSelector/InDetRegionSelector/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetDetDescr/InDetRegionSelector
diff --git a/InnerDetector/InDetDetDescr/InDetRegionSelector/InDetRegionSelector/SiRegionSelectorTable.h b/InnerDetector/InDetDetDescr/InDetRegionSelector/InDetRegionSelector/SiRegionSelectorTable.h
index 4d3b1cbccc2b5f6dc4796fec68eabd881a5a32fb..428cf404c8fdcf65dd896df023f8b74b27726426 100755
--- a/InnerDetector/InDetDetDescr/InDetRegionSelector/InDetRegionSelector/SiRegionSelectorTable.h
+++ b/InnerDetector/InDetDetDescr/InDetRegionSelector/InDetRegionSelector/SiRegionSelectorTable.h
@@ -32,7 +32,7 @@ public:
   StatusCode initialize();
   StatusCode finalize();
   
-  virtual RegSelSiLUT* getLUT() const;
+  virtual RegSelSiLUT* getLUT();
 
 private:
   
diff --git a/InnerDetector/InDetDetDescr/InDetRegionSelector/InDetRegionSelector/TRT_RegionSelectorTable.h b/InnerDetector/InDetDetDescr/InDetRegionSelector/InDetRegionSelector/TRT_RegionSelectorTable.h
index 24218c9ffcb4a433c38e1a76b4a08bb88915ee61..ed5ccaa48bad8674e39f47c8e559116059f10d93 100755
--- a/InnerDetector/InDetDetDescr/InDetRegionSelector/InDetRegionSelector/TRT_RegionSelectorTable.h
+++ b/InnerDetector/InDetDetDescr/InDetRegionSelector/InDetRegionSelector/TRT_RegionSelectorTable.h
@@ -30,7 +30,7 @@ public:
   StatusCode initialize();
   StatusCode execute();
   StatusCode finalize();
-  virtual RegSelSiLUT* getLUT() const;
+  virtual RegSelSiLUT* getLUT();
 
   
 private:
diff --git a/InnerDetector/InDetDetDescr/InDetRegionSelector/src/SiRegionSelectorTable.cxx b/InnerDetector/InDetDetDescr/InDetRegionSelector/src/SiRegionSelectorTable.cxx
index 0e774353f57dcf0c8db1284ac3358f2ef2431594..29528fe28c8940c31ae123affeedd374fb0b9d1a 100755
--- a/InnerDetector/InDetDetDescr/InDetRegionSelector/src/SiRegionSelectorTable.cxx
+++ b/InnerDetector/InDetDetDescr/InDetRegionSelector/src/SiRegionSelectorTable.cxx
@@ -92,7 +92,7 @@ SiRegionSelectorTable::~SiRegionSelectorTable()
 
 
 // Get the lookup table.
-RegSelSiLUT* SiRegionSelectorTable::getLUT() const
+RegSelSiLUT* SiRegionSelectorTable::getLUT()
 {
   return m_regionLUT;
 }
diff --git a/InnerDetector/InDetDetDescr/InDetRegionSelector/src/TRT_RegionSelectorTable.cxx b/InnerDetector/InDetDetDescr/InDetRegionSelector/src/TRT_RegionSelectorTable.cxx
index 27aee9c9cd4bcac7fd41fcd03b13d8240985fdcc..a9d09c864d4599ba48ddade19086eff8b322c192 100755
--- a/InnerDetector/InDetDetDescr/InDetRegionSelector/src/TRT_RegionSelectorTable.cxx
+++ b/InnerDetector/InDetDetDescr/InDetRegionSelector/src/TRT_RegionSelectorTable.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "InDetRegionSelector/TRT_RegionSelectorTable.h"
@@ -94,7 +94,7 @@ TRT_RegionSelectorTable::~TRT_RegionSelectorTable()
 }
 
 // Get the lookup table.
-RegSelSiLUT* TRT_RegionSelectorTable::getLUT() const
+RegSelSiLUT* TRT_RegionSelectorTable::getLUT()
 {
   return m_regionLUT;
 }
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/CMakeLists.txt b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/CMakeLists.txt
index 2f42a3c03c2b2b44473be9411013013e38ba89c0..f8de9f5d402145029c0b46012d6371d2001c638e 100644
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/CMakeLists.txt
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/CMakeLists.txt
@@ -9,6 +9,7 @@ atlas_subdir( InDetServMatGeoModel )
 atlas_depends_on_subdirs( PUBLIC
                           Control/AthenaBaseComps
                           Control/AthenaKernel
+                          Control/CxxUtils
                           Database/RDBAccessSvc
                           DetectorDescription/GeoPrimitives
                           DetectorDescription/GeoModel/GeoModelUtilities
@@ -31,7 +32,7 @@ atlas_add_component( InDetServMatGeoModel
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${CORAL_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${CORAL_LIBRARIES} ${GEOMODELCORE_LIBRARIES} AthenaBaseComps AthenaKernel GeoModelUtilities GaudiKernel InDetGeoModelUtils SGTools StoreGateLib SGtests GeometryDBSvcLib )
+                     LINK_LIBRARIES ${CORAL_LIBRARIES} ${GEOMODELCORE_LIBRARIES} AthenaBaseComps AthenaKernel CxxUtils GeoModelUtilities GaudiKernel InDetGeoModelUtils SGTools StoreGateLib SGtests GeometryDBSvcLib )
 
 # Install files from the package:
 atlas_install_headers( InDetServMatGeoModel )
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/ComputeStaveServices.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/ComputeStaveServices.h
index 4868d8df5ddd12d8d7760f23ccdd6438110a0878..7ef824a5c21b997d18526ffed52fd7ab002ad92c 100644
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/ComputeStaveServices.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/ComputeStaveServices.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef ComputeStaveServices_H
@@ -7,6 +7,7 @@
 
 #include "InDetServMatGeoModel/StaveServices.h"
 #include "AthenaKernel/MsgStreamMember.h"
+#include "CxxUtils/checker_macros.h"
 
 class ComputeStaveServices {
 public:
@@ -21,7 +22,7 @@ public:
  private:
   // the message stream (same for all derived classes)
   MsgStream& msg (MSG::Level lvl) const { return m_msg << lvl; }
-  mutable Athena::MsgStreamMember m_msg;
+  mutable Athena::MsgStreamMember m_msg ATLAS_THREAD_SAFE;
   
 };
 
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/EndPlateFactoryFS.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/EndPlateFactoryFS.h
index 5dcd212f8a150b0a3c9c33bf7fb08d5816fda675..62323975ae37ee873ee55a4f8f84f1cea35185f3 100755
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/EndPlateFactoryFS.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/EndPlateFactoryFS.h
@@ -1,11 +1,12 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef INDETSERVMATGEOMODEL_ENDPLATEFACTORYFS_H
 #define INDETSERVMATGEOMODEL_ENDPLATEFACTORYFS_H
 
 #include "AthenaKernel/MsgStreamMember.h"
+#include "CxxUtils/checker_macros.h"
 #include "GaudiKernel/ServiceHandle.h"
 
 class StoreGateSvc;
@@ -39,7 +40,7 @@ class EndPlateFactoryFS {
   // private data
   StoreGateSvc                   *m_detStore;
   ServiceHandle<IRDBAccessSvc>    m_rdbAccess;
-  mutable Athena::MsgStreamMember m_msg;
+  mutable Athena::MsgStreamMember m_msg ATLAS_THREAD_SAFE;
 };
 
 #endif 
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/HRoute.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/HRoute.h
index 3ac1effba67781a18d68ed6dda11459347a307ae..75d2646365f0ea1793760e095109abe7a777e8df 100644
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/HRoute.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/HRoute.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef HRoute_H
@@ -29,7 +29,7 @@ public:
 
   virtual double exit() const {return zExit();}
 
-  virtual Route* nextRoute() const {return m_next;}
+  virtual Route* nextRoute() {return m_next;}
 
   const VolumeContainer& volumes() const {return m_volumes;}
 
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatAthenaComps.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatAthenaComps.h
index 28076e6b370cb0e931e8e590c26caa4f9d76bdd5..5b4da5326f1c3f2314c082d9b25cdfb9e5ce9729 100644
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatAthenaComps.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatAthenaComps.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef InDetServMatGeoModel_InDetServMatAthenaComps_H
@@ -18,7 +18,7 @@ public:
 
   //Add Builder Tool
   void setBuilderTool(IInDetServMatBuilderTool * builderTool);
-  IInDetServMatBuilderTool *builderTool() const;
+  const IInDetServMatBuilderTool *builderTool() const;
 
 private:
 
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatBuilderToolSLHC.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatBuilderToolSLHC.h
index 1e961306b3a17ae7a3fb4c9c6e577c4e37a561d8..3ee2ecd54af7d7f37d08291900e27ed1e59f0a0b 100644
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatBuilderToolSLHC.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatBuilderToolSLHC.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef InDetServMatBuilderToolSLHC_H
@@ -62,7 +62,7 @@ public:
   virtual StatusCode finalize();  
 
   /// Get the services
-  virtual const std::vector<const InDetDD::ServiceVolume *> & getServices();
+  virtual const std::vector<const InDetDD::ServiceVolume *> & getServices() const;
   
   /// General service adding method.
   void addService(InDetDD::ServiceVolume * param);
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatFactoryDC2.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatFactoryDC2.h
index a75d268b25e50ada7fa747c66b87cd457bc91943..0d243aed661c6208ab04c8fb00e84c1845b431f4 100755
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatFactoryDC2.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatFactoryDC2.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef INDETSERVMATGEOMODEL_INDETSERVMATFACTORYDC2_H
@@ -7,12 +7,13 @@
 
 
 #include "AthenaKernel/MsgStreamMember.h"
-#include "GaudiKernel/ServiceHandle.h"
+#include "CxxUtils/checker_macros.h"
 #include "GeoModelKernel/GeoVDetectorFactory.h"
 //the following needed because the return type of getDetectorManager() is not 
 //the same as the method return type as specified in the baseclass
 #include "InDetServMatGeoModel/InDetServMatManager.h"
 
+#include "GaudiKernel/ServiceHandle.h"
 
 class StoreGateSvc;
 class IRDBAccessSvc;
@@ -45,7 +46,7 @@ class InDetServMatFactoryDC2 : public GeoVDetectorFactory  {
   StoreGateSvc                   *m_detStore;
   ServiceHandle<IRDBAccessSvc>    m_rdbAccess;
   InDetDD::InDetServMatManager   *m_manager;
-  mutable Athena::MsgStreamMember m_msg;
+  mutable Athena::MsgStreamMember m_msg ATLAS_THREAD_SAFE;
 };
 
 #endif //  INDETSERVMATGEOMODEL_INDETSERVMATFACTORYDC2_H
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatFactoryFS.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatFactoryFS.h
index 73ef0ddd0469037ecba4941ed5e68fcf0f4fbd35..a2342a598d723a2fe497ab2aab0ae79d55299c6c 100755
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatFactoryFS.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatFactoryFS.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef INDETSERVMATGEOMODEL_INDETSERVMATFACTORYFS_H
@@ -7,10 +7,12 @@
 
 
 #include "AthenaKernel/MsgStreamMember.h"
-#include "GaudiKernel/ServiceHandle.h"
+#include "CxxUtils/checker_macros.h"
 #include "GeoModelKernel/GeoVDetectorFactory.h"
 #include "InDetServMatGeoModel/InDetServMatManager.h"
 
+#include "GaudiKernel/ServiceHandle.h"
+
 class StoreGateSvc;
 class IRDBAccessSvc;
 
@@ -43,9 +45,7 @@ class InDetServMatFactoryFS : public GeoVDetectorFactory  {
   StoreGateSvc                   *m_detStore;
   ServiceHandle<IRDBAccessSvc>    m_rdbAccess;
   InDetDD::InDetServMatManager   *m_manager;
-  mutable Athena::MsgStreamMember m_msg;
+  mutable Athena::MsgStreamMember m_msg ATLAS_THREAD_SAFE;
 };
 
 #endif
-
-
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatGeometryManager.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatGeometryManager.h
index 0492c528c4602f16d79b8a1b27815b910ccc9109..100f00b8847a7380e37a3ef6f5f45ae6847f4e6a 100644
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatGeometryManager.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/InDetServMatGeometryManager.h
@@ -28,7 +28,7 @@ public:
   const IGeometryDBSvc * db() const {return m_athenaComps->geomDB();}
 
   // Access to material manager 
-  InDetMaterialManager * matMgr() const {return m_matMgr;}
+  InDetMaterialManager * matMgr() {return m_matMgr;}
   
   
   // Access to message stream
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/PixelServMatFactoryDC2.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/PixelServMatFactoryDC2.h
index e7128af38533b53dd3b910211da9fb503fddc02d..03de32713da33d3feaf9b593b0f2feb190a4d3e1 100755
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/PixelServMatFactoryDC2.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/PixelServMatFactoryDC2.h
@@ -1,11 +1,12 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef INDETSERVMATGEOMODEL_PIXELSERVMATFACTORYDC2_H
 #define INDETSERVMATGEOMODEL_PIXELSERVMATFACTORYDC2_H
 
 #include "AthenaKernel/MsgStreamMember.h"
+#include "CxxUtils/checker_macros.h"
 #include "GaudiKernel/ServiceHandle.h"
 
 class StoreGateSvc;
@@ -37,7 +38,7 @@ class PixelServMatFactoryDC2   {
   // private data
   StoreGateSvc                   *m_detStore;
   ServiceHandle<IRDBAccessSvc>    m_rdbAccess;
-  mutable Athena::MsgStreamMember m_msg;
+  mutable Athena::MsgStreamMember m_msg ATLAS_THREAD_SAFE;
 };
 
 #endif //  INDETSERVMATGEOMODEL_PIXELSERVMATFACTORYDC2_H
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/PixelServMatFactoryFS.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/PixelServMatFactoryFS.h
index 79f91d19cdcaba1a0fa03f3dba5bb8636b6bd877..dc8abbbc8c4560909e408064eab645bfcd83cb8c 100755
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/PixelServMatFactoryFS.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/PixelServMatFactoryFS.h
@@ -6,6 +6,7 @@
 #define INDETSERVMATGEOMODEL_PIXELSERVMATFACTORYFS_H
 
 #include "AthenaKernel/MsgStreamMember.h"
+#include "CxxUtils/checker_macros.h"
 #include "GaudiKernel/ServiceHandle.h"
 
 class StoreGateSvc;
@@ -40,7 +41,7 @@ class PixelServMatFactoryFS   {
   StoreGateSvc                    *m_detStore;
   ServiceHandle<IRDBAccessSvc>     m_rdbAccess;
   std::unique_ptr<InDetMaterialManager> m_materialManager;
-  mutable Athena::MsgStreamMember  m_msg;
+  mutable Athena::MsgStreamMember  m_msg ATLAS_THREAD_SAFE;
 
 };
 
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/Route.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/Route.h
index 4477275fbe9041cd13e3f29b7a39e57eaf3b80e4..cfc92db7cadad94d1b2b4bcc4a1aa64cf288dffc 100644
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/Route.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/Route.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef Route_H
@@ -33,7 +33,7 @@ public:
 
   //virtual int direction() = 0;
 
-  virtual Route* nextRoute() const = 0;
+  virtual Route* nextRoute() = 0;
 
   virtual const VolumeContainer& volumes() const = 0;
 
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SCT_ServMatFactoryDC2.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SCT_ServMatFactoryDC2.h
index beb1a0949c8150d764b5fde7104bba6a206e5349..abbdab708e9c6ca2e285fcc3c2bafbce19537875 100755
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SCT_ServMatFactoryDC2.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SCT_ServMatFactoryDC2.h
@@ -1,11 +1,12 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef INDETSERVMATGEOMODEL_SCT_SERVMATFACTORYDC2_H
 #define INDETSERVMATGEOMODEL_SCT_SERVMATFACTORYDC2_H
 
 #include "AthenaKernel/MsgStreamMember.h"
+#include "CxxUtils/checker_macros.h"
 #include "GaudiKernel/ServiceHandle.h"
 
 class StoreGateSvc;
@@ -57,7 +58,7 @@ class SCT_ServMatFactoryDC2   {
   StoreGateSvc                   *m_detStore;
   ServiceHandle<IRDBAccessSvc>    m_rdbAccess;
   const StoredMaterialManager    *m_materialManager;
-  mutable Athena::MsgStreamMember m_msg;
+  mutable Athena::MsgStreamMember m_msg ATLAS_THREAD_SAFE;
 };
 
 #endif //  INDETSERVMATGEOMODEL_SCT_SERVMATFACTORYDC2_H
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SCT_ServMatFactoryFS.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SCT_ServMatFactoryFS.h
index 3a4c3a0a493d2e9f0132650afaca78f53f4c070a..f5f519f807769be7ad64bfe26c65a36e57c0089b 100755
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SCT_ServMatFactoryFS.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SCT_ServMatFactoryFS.h
@@ -6,6 +6,7 @@
 #define INDETSERVMATGEOMODEL_SCT_SERVMATFACTORYFS_H
 
 #include "AthenaKernel/MsgStreamMember.h"
+#include "CxxUtils/checker_macros.h"
 #include "GaudiKernel/ServiceHandle.h"
 
 class StoreGateSvc;
@@ -42,7 +43,7 @@ class SCT_ServMatFactoryFS   {
   StoreGateSvc                    *m_detStore;
   ServiceHandle<IRDBAccessSvc>     m_rdbAccess;
   std::unique_ptr<InDetMaterialManager> m_materialManager;
-  mutable Athena::MsgStreamMember  m_msg;
+  mutable Athena::MsgStreamMember  m_msg ATLAS_THREAD_SAFE;
 
 };
 
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/ServiceVolume.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/ServiceVolume.h
index 68b66819a6e3ce4c0c0962e0d22be0627efaad00..f5f5d14461d8706f2d2b96d5b7c1337cdab26e13 100644
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/ServiceVolume.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/ServiceVolume.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef ServiceVolume_H
@@ -77,7 +77,7 @@ public:
 
   LayerContainer layers() const {return m_layers;}
 
-  ServiceVolume* next() const {return m_next;}
+  ServiceVolume* next() {return m_next;}
 
   void addPrevious( ServiceVolume* prev) { m_previous.push_back(prev);}
 
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SquirrelCageFactoryFS.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SquirrelCageFactoryFS.h
index ddaa209b7ed47f9e94c5f32c32a6d477fac55aa0..991d968647ffe2fe33392f2746f2d84a31b12916 100755
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SquirrelCageFactoryFS.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SquirrelCageFactoryFS.h
@@ -1,11 +1,12 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef INDETSERVMATGEOMODEL_SQUIRRELCAGEFACTORYFS_H
 #define INDETSERVMATGEOMODEL_SQUIRRELCAGEFACTORYFS_H
 
 #include "AthenaKernel/MsgStreamMember.h"
+#include "CxxUtils/checker_macros.h"
 #include "GaudiKernel/ServiceHandle.h"
 
 class StoreGateSvc;
@@ -37,7 +38,7 @@ class SquirrelCageFactoryFS {
   // private data
   StoreGateSvc                   *m_detStore;
   ServiceHandle<IRDBAccessSvc>    m_rdbAccess;
-  mutable Athena::MsgStreamMember m_msg;
+  mutable Athena::MsgStreamMember m_msg ATLAS_THREAD_SAFE;
 };
 
 #endif 
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SupportRailFactoryFS.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SupportRailFactoryFS.h
index 74278e2230e8c74fb413be6a7f63125fb2b8be73..bc8f7ffb0abad50941fac21799f31945d0ee4764 100755
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SupportRailFactoryFS.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/SupportRailFactoryFS.h
@@ -1,11 +1,12 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef INDETSERVMATGEOMODEL_SUPPORTRAILFACTORYFS_H
 #define INDETSERVMATGEOMODEL_SUPPORTRAILFACTORYFS_H
 
 #include "AthenaKernel/MsgStreamMember.h"
+#include "CxxUtils/checker_macros.h"
 #include "GaudiKernel/ServiceHandle.h"
 
 class StoreGateSvc;
@@ -37,7 +38,7 @@ class SupportRailFactoryFS {
   // private data
   StoreGateSvc                    *m_detStore;
   ServiceHandle<IRDBAccessSvc>     m_rdbAccess;
-  mutable Athena::MsgStreamMember  m_msg;
+  mutable Athena::MsgStreamMember  m_msg ATLAS_THREAD_SAFE;
 
 };
 
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/TRT_ServMatFactoryDC2.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/TRT_ServMatFactoryDC2.h
index 4fddb6f6baec5def8807afa7966d4a5dda94112a..3daf7df92fa91e7c75649a4aa2c8ede56296d838 100755
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/TRT_ServMatFactoryDC2.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/TRT_ServMatFactoryDC2.h
@@ -1,10 +1,11 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef INDETSERVMATGEOMODEL_TRT_SERVMATFACTORYDC2_H
 #define INDETSERVMATGEOMODEL_TRT_SERVMATFACTORYDC2_H
 #include "AthenaKernel/MsgStreamMember.h"
+#include "CxxUtils/checker_macros.h"
 #include "GaudiKernel/ServiceHandle.h"
 
 class StoreGateSvc;
@@ -56,7 +57,7 @@ class TRT_ServMatFactoryDC2   {
   StoreGateSvc                   *m_detStore;
   ServiceHandle<IRDBAccessSvc>    m_rdbAccess;
   const StoredMaterialManager    *m_materialManager;
-  mutable Athena::MsgStreamMember m_msg;
+  mutable Athena::MsgStreamMember m_msg ATLAS_THREAD_SAFE;
 };
 
 #endif //  INDETSERVMATGEOMODEL_TRT_SERVMATFACTORYDC2_H
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/TRT_ServMatFactoryFS.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/TRT_ServMatFactoryFS.h
index 34ba811ead0a883d7bdee7d8f96b85d1af34f92c..4f7e28e66fe49abe9dcfcb8e981dc771642703a1 100755
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/TRT_ServMatFactoryFS.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/TRT_ServMatFactoryFS.h
@@ -6,6 +6,7 @@
 #define INDETSERVMATGEOMODEL_TRT_SERVMATFACTORYFS_H
 
 #include "AthenaKernel/MsgStreamMember.h"
+#include "CxxUtils/checker_macros.h"
 #include "GaudiKernel/ServiceHandle.h"
 
 class StoreGateSvc;
@@ -42,7 +43,7 @@ class TRT_ServMatFactoryFS   {
   StoreGateSvc                    *m_detStore;
   ServiceHandle<IRDBAccessSvc>     m_rdbAccess;
   std::unique_ptr<InDetMaterialManager> m_materialManager;
-  mutable Athena::MsgStreamMember  m_msg;
+  mutable Athena::MsgStreamMember  m_msg ATLAS_THREAD_SAFE;
 };
 
 #endif 
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/VRoute.h b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/VRoute.h
index 67d1cb6d18e93c03601eeb6b61791017e937f0fc..c10afdbb6cfad5fa85979e2443deee826f71f0b5 100644
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/VRoute.h
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/InDetServMatGeoModel/VRoute.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef VRoute_H
@@ -29,7 +29,7 @@ public:
 
   virtual double exit() const {return rExit();}
 
-  virtual Route* nextRoute() const {return m_next;}
+  virtual Route* nextRoute() {return m_next;}
 
   virtual const VolumeContainer& volumes() const {return m_volumes;}
 
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/src/InDetServMatAthenaComps.cxx b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/src/InDetServMatAthenaComps.cxx
index a1e85356a64785e00ea3a576f47f5708c96db013..e37a4958a677c53661a88968783ce0e3376b8305 100644
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/src/InDetServMatAthenaComps.cxx
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/src/InDetServMatAthenaComps.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "InDetServMatGeoModel/InDetServMatAthenaComps.h"
@@ -17,8 +17,8 @@ InDetServMatAthenaComps::setBuilderTool(IInDetServMatBuilderTool * builderTool)
   m_builderTool = builderTool;
 }
 
-IInDetServMatBuilderTool * 
-InDetServMatAthenaComps::builderTool() const 
+const IInDetServMatBuilderTool * 
+InDetServMatAthenaComps::builderTool() const
 {
   return m_builderTool;
 }
diff --git a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/src/InDetServMatBuilderToolSLHC.cxx b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/src/InDetServMatBuilderToolSLHC.cxx
index c7e100403a0045865804892e6983ef0f522d31a7..c30a08e87c44f08c4253f55d0dc5d1b1714ef843 100644
--- a/InnerDetector/InDetDetDescr/InDetServMatGeoModel/src/InDetServMatBuilderToolSLHC.cxx
+++ b/InnerDetector/InDetDetDescr/InDetServMatGeoModel/src/InDetServMatBuilderToolSLHC.cxx
@@ -86,6 +86,8 @@ StatusCode InDetServMatBuilderToolSLHC::initialize()
   m_athenaComps->setRDBAccessSvc(&*m_rdbAccessSvc);
   m_athenaComps->setGeometryDBSvc(&*m_geometryDBSvc);
 
+  build();
+
   msg(MSG::INFO) << "initialize() successful in " << name() << endmsg;
   return StatusCode::SUCCESS;
 }
@@ -97,9 +99,8 @@ StatusCode InDetServMatBuilderToolSLHC::finalize()
   return sc;
 }
 	
-const std::vector<const InDetDD::ServiceVolume *> & InDetServMatBuilderToolSLHC::getServices()
+const std::vector<const InDetDD::ServiceVolume *> & InDetServMatBuilderToolSLHC::getServices() const
 {
-  if (!m_init) build();
   return m_services;
 }
 
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/BeamPipeBuilderCond.h b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/BeamPipeBuilderCond.h
new file mode 100755
index 0000000000000000000000000000000000000000..9f4dc6b7b777983634c710d4032195860a151b5c
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/BeamPipeBuilderCond.h
@@ -0,0 +1,119 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// BeamPipeBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef INDETTRACKINGGEOMETRY_BEAMPIPEBUILDERCOND_H
+#define INDETTRACKINGGEOMETRY_BEAMPIPEBUILDERCOND_H
+
+// Athena
+#include "AthenaBaseComps/AthAlgTool.h"
+// Trk
+#include "TrkDetDescrInterfaces/ILayerBuilderCond.h"
+// STL
+#include <vector>
+#include <utility>
+
+namespace Trk {
+  class CylinderLayer;
+  class DiscLayer;
+  class PlaneLayer;
+}
+
+class BeamPipeDetectorManager;
+
+namespace InDet {
+
+  /** @class BeamPipeBuilderCond
+      Simple LayerBuilder for the BeamPipe, 
+      can be configured through jobOptions:
+        - radius
+        - halflength
+        - thickness
+        - MaterialProperties
+        
+      later on the slight shift/rotation of the BeamPipe can be implemented
+      - make a binding to the database afterwards
+       
+      @author Andreas.Salzburger@cern.ch 
+    */
+  class BeamPipeBuilderCond : public AthAlgTool,
+                          virtual public Trk::ILayerBuilderCond {
+    
+                            
+    public:
+      /** AlgTool style constructor */
+      BeamPipeBuilderCond(const std::string&,const std::string&,const IInterface*);
+      /** Destructor */
+      virtual ~BeamPipeBuilderCond();
+      
+      /** AlgTool initialize method */
+      StatusCode initialize();
+      /** AlgTool finalize method */
+      StatusCode finalize();
+       
+      /** LayerBuilder interface method - returning Barrel-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::CylinderLayer* >* > cylindricalLayers(const EventContext& ctx) const; 
+      
+      /** LayerBuilder interface method - returning Endcap-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::DiscLayer* >* >     discLayers(const EventContext& ctx) const; 
+      
+      /** LayerBuilder interface method - returning Planar-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* >    planarLayers(const EventContext& ctx) const; 
+
+      /** Name identification */
+      const std::string& identification() const;      
+          
+    private:
+      
+      bool                                          m_beamPipeFromDb;    //!< steer beam pipe parameters from DataBase
+      const BeamPipeDetectorManager*                m_beamPipeMgr;       //!< the beam pipe manager
+      std::string                                   m_beamPipeMgrName;   //!< the name of the beam pipe manager to be configured
+      double                                        m_beamPipeEnvelope;  //!< radial envelope when taking the Top volume radius
+      
+      double                                        m_beamPipeOffsetX;    //!< beam pipe offset in x
+      double                                        m_beamPipeOffsetY;    //!< beam pipe offset in y        
+      double                                        m_beamPipeRadius;     //!< radius of the beam pipe
+      double                                        m_beamPipeHalflength; //!< halflength of the beampipe
+      double                                        m_beamPipeThickness;  //!< thickness of the beam pipe
+      double                                        m_beamPipeX0;         //!< X0 of the beam pipe
+      double                                        m_beamPipeL0;         //!< X0 of the beam pipe
+      //double                                        m_beamPipedEdX;       //!< dEdX of the beam pipe
+      double                                        m_beamPipeA;          //!< averageA of the beam pipe
+      double                                        m_beamPipeZ;          //!< averageZ of the beam pipe
+      double                                        m_beamPipeRho;        //!< averageRho of the beam pipe
+
+      unsigned int                                  m_beamPipeBinsZ;      //!< number of bins in the beam pipe
+
+      std::string                                   m_identification;     //!< string identification
+      
+      
+  };
+
+ inline std::pair<EventIDRange, const std::vector< const Trk::DiscLayer* >* >  BeamPipeBuilderCond::discLayers(const EventContext&) const
+  {
+  //create dummy infinite range
+    EventIDRange range;
+    return std::pair<EventIDRange, const std::vector< const Trk::DiscLayer* >* >(range,0); 
+  }
+ 
+ inline std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* > BeamPipeBuilderCond::planarLayers(const EventContext&) const
+  {
+  //create dummy infinite range
+    EventIDRange range;
+    return std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* >(range, 0);
+  }
+ 
+ inline const std::string& BeamPipeBuilderCond::identification() const
+ { return m_identification; } 
+ 
+  
+} // end of namespace
+
+
+#endif // INDETTRACKINGGEOMETRY_BEAMPIPEBUILDERCOND_H
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/RobustTrackingGeometryBuilderCond.h b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/RobustTrackingGeometryBuilderCond.h
new file mode 100755
index 0000000000000000000000000000000000000000..e92774b734cc2101ef8c75c2497d67ed795f7fc6
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/RobustTrackingGeometryBuilderCond.h
@@ -0,0 +1,138 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// RobustTrackingGeometryBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef INDETTRACKINGGEOMETRY_ROBUSTTRACKINGGEOMETRYBUILDERCOND_H
+#define INDETTRACKINGGEOMETRY_ROBUSTTRACKINGGEOMETRYBUILDERCOND_H
+
+//Trk
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrUtils/BinningType.h"
+#include "TrkGeometry/TrackingVolumeManipulator.h"
+// Gaudi
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+// STL
+#include <vector>
+#include <string>
+
+#ifndef TRKDETDESCR_TAKESMALLERBIGGER
+#define TRKDETDESCR_TAKESMALLERBIGGER
+#define takeSmaller(current,test) current = current < test ? current : test
+#define takeBigger(current,test)  current = current > test ? current : test
+#define takeSmallerBigger(cSmallest, cBiggest, test) takeSamller(cSmallest, cBiggest, test); takeBigger(cSmallest, cBiggest,test)
+#endif
+
+
+namespace Trk {
+ class TrackingGeometry;
+ class ILayerBuilderCond;
+ class ITrackingVolumeCreator;
+ class ILayerArrayCreator;
+ class IMagneticFieldTool;
+ class Layer;
+ class Material;
+ class MagneticFieldProperties;
+}
+ 
+class IEnvelopeDefSvc; 
+ 
+namespace InDet {
+     
+
+  /** @class RobustTrackingGeometryBuilderCond
+
+      New Geometry builder that adapts to different layer setups
+      
+      Only a few parameters are not automated:
+       - m_outwardsFraction: this defines how much you orient yourself on the next bigger layer
+                             if you wrap an outer volume around an inner 0.5 would lead to a boundary fully in bewteen
+                            1. at the outer boundary, 0. at the inner boundary
+      
+      @author Andreas.Salzburger@cern.ch
+    
+    */
+    
+  class RobustTrackingGeometryBuilderCond : public AthAlgTool, 
+                                        public Trk::TrackingVolumeManipulator,
+                                        virtual public Trk::IGeometryBuilderCond {
+    
+    
+    public:
+      /** Constructor */
+      RobustTrackingGeometryBuilderCond(const std::string&,const std::string&,const IInterface*);
+      
+      /** Destructor */
+      virtual ~RobustTrackingGeometryBuilderCond();
+        
+      /** AlgTool initailize method.*/
+      StatusCode initialize();
+      /** AlgTool finalize method */
+      StatusCode finalize();
+      /** TrackingGeometry Interface methode */
+      std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const; 
+
+      /** The unique signature */
+      Trk::GeometrySignature geometrySignature() const { return Trk::ID; }
+      
+    private:
+        
+      /** Private method, creates and packs a triple containing of NegEndcap-Barrel-PosEndcap layers */
+      const Trk::TrackingVolume* packVolumeTriple(const std::vector<const Trk::Layer*>& negLayers,
+                                                  const std::vector<const Trk::Layer*>& centralLayers,
+                                                  const std::vector<const Trk::Layer*>& posLayers,
+                                                  double rMin, double rMax,
+                                                  double zMin, double zPosCentral,
+                                                  const std::string& baseName="UndefinedVolume",
+                                                  int colorCode = 21,
+                                                  Trk::BinningType bintype=Trk::arbitrary) const;      
+      
+      /** Private method, creates and packs a triple containing of NegEndcap-Barrel-PosEndcap volumes */
+      const Trk::TrackingVolume* packVolumeTriple(const std::vector<const Trk::TrackingVolume*>& negVolumes,
+                                                  const std::vector<const Trk::TrackingVolume*>& centralVolumes,
+                                                  const std::vector<const Trk::TrackingVolume*>& posVolumes,
+                                                  const std::string& baseName="UndefinedVolume") const;
+
+      // helper tools for the geometry building
+      ToolHandle<Trk::ILayerBuilderCond>             m_beamPipeBuilder;          //!< BeamPipe builder (is different from layers)
+      ToolHandleArray<Trk::ILayerBuilderCond>        m_layerBuilders;            //!< Helper Tools for the Layer creation   
+      ToolHandle<Trk::ITrackingVolumeCreator>        m_trackingVolumeCreator;    //!< Helper Tool to create TrackingVolumes
+      ToolHandle<Trk::ILayerArrayCreator>            m_layerArrayCreator;        //!< Helper Tool to create BinnedArrays
+
+      // configurations for the layer builders
+      std::vector<int>                               m_layerBinningType;         //!< binning type for the provided layers      
+      std::vector<int>                               m_colorCodesConfig;         //!< Color codes    
+
+      // enclosing endcap/cylinder layer 
+      ServiceHandle<IEnvelopeDefSvc>                 m_enclosingEnvelopeSvc;                //!< the service to provide the ID envelope size
+      std::vector<double>                            m_enclosingCylinderRadius;             //!< the cylinder layer inside the enclosing volume
+      std::vector<double>                            m_enclosingDiscPositionZ;              //!< the disc position inside the enclosing volume
+      
+      double                                         m_layerEnvelopeCover;       //!< innermost - outermost 
+      bool                                           m_buildBoundaryLayers;      //!< create boundary layers 
+      bool                                           m_replaceJointBoundaries;   //!< run with replacement of all joint boundaries 
+      
+      // magnetic & material field configuration
+      mutable Trk::Material*                         m_materialProperties;       //!< overal material properties of the ID
+      mutable Trk::MagneticFieldProperties*          m_magneticFieldProperties;  //!< overal mag field properties of the ID
+      // outer envelope        
+      double                                         m_outwardsFraction;         //!< defines how much you orient yourself in an outwards way (see above)                                    
+      // robust layer indexing                                                   
+      bool                                           m_indexStaticLayers;        //!< forces robust indexing for layers
+      // naming schema                                                           
+      std::string                                    m_namespace;                //!< identificaton namespace 
+      // ID container                                                            
+      std::string                                    m_exitVolume;                //!< the final ID container             
+      bool                                           m_isSLHC;                   //!< changes volume boundary calculation for SLHC layouts      
+  };
+
+} // end of namespace
+
+#endif //INDETTRACKINGGEOMETRY_ROBUSTTRACKINGGEOMETRYBUILDERCOND_H
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/SiLayerBuilderCond.h b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/SiLayerBuilderCond.h
new file mode 100755
index 0000000000000000000000000000000000000000..62869355d35ca3bf4b1701152a1498c46d5c998f
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/SiLayerBuilderCond.h
@@ -0,0 +1,162 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// SiLayerBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef INDETTRACKINGGEOMETRY_SILAYERBUILDERNCOND_H
+#define INDETTRACKINGGEOMETRY_SILAYERBUILDERNCOND_H
+
+// Athena
+#include "AthenaBaseComps/AthAlgTool.h"
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// Trk
+#include "TrkDetDescrInterfaces/ILayerBuilderCond.h"
+#include "TrkDetDescrUtils/SharedObject.h"
+// STL
+#include <vector>
+#include <utility> //for std::pair
+
+#include "InDetReadoutGeometry/SiDetectorElementCollection.h"
+
+class PixelID;
+class SCT_ID;
+
+#ifndef TRKDETDESCR_TAKESMALLERBIGGER
+#define TRKDETDESCR_TAKESMALLERBIGGER
+#define takeSmaller(current,test) current = current < test ? current : test
+#define takeBigger(current,test)  current = current > test ? current : test
+#define takeSmallerBigger(cSmallest, cBiggest, test) takeSmaller(cSmallest, test); takeBigger(cBiggest, test)
+#endif
+
+namespace InDetDD {
+  class SiDetectorManager;
+}
+
+namespace Trk {
+  class Surface;
+  class CylinderLayer;
+  class DiscLayer;
+  class PlaneLayer;
+  class LayerMaterialProperties;
+  typedef std::pair< SharedObject<const Surface>, Amg::Vector3D > SurfaceOrderPosition;
+}
+
+namespace InDet {
+ 
+  /** @class SiLayerBuilderCond
+  
+     The SiLayerBuilderCond parses the senstive detector elments and orders them onto a
+     Layer surface.
+  
+     It also uses the SiNumerology to construct the BinUtility and then orders the representing
+     detector surfaces on the layers.
+     
+     It performs an automated detector if an equidistant or non-equidistant binning
+     is to be used for the barrel case.
+     
+     There is an option to run in split mode for multiple pixel systems of different 
+     layer / endcap dimensions. In such a case, a cache is filled at the first time 
+     running for the pixel system of greater dimensions and just return in the second pass.
+
+     @author Andreas.Salzburger@cern.ch
+    */
+  class SiLayerBuilderCond : public AthAlgTool, virtual public Trk::ILayerBuilderCond {
+    
+    public:
+    
+      /** AlgTool style constructor */
+      SiLayerBuilderCond(const std::string&,const std::string&,const IInterface*);
+      
+      /** Destructor */
+      virtual ~SiLayerBuilderCond();
+      
+      /** AlgTool initialize method */
+      StatusCode initialize();
+      /** AlgTool finalize method */
+      StatusCode finalize();
+       
+      /** LayerBuilder interface method - returning Barrel-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::CylinderLayer* >* > cylindricalLayers(const EventContext& ctx) const; 
+      
+      /** LayerBuilder interface method - returning Endcap-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::DiscLayer* >* >    discLayers(const EventContext& ctx) const; 
+      
+      /** LayerBuilder interface method - returning Planar-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* >   planarLayers(const EventContext& ctx) const; 
+             
+      /** Name identification */
+      const std::string& identification() const;      
+        
+    private:
+      std::vector< const Trk::CylinderLayer* >* dressCylinderLayers(const std::vector< const Trk::CylinderLayer* >& dLayers) const;
+      
+      /** create the disc layers, if no vector is given, then it's the first pass, else it's the DBM for the Pixels */
+      std::pair<EventIDRange, std::vector< const Trk::DiscLayer* >* > createDiscLayers(const EventContext& ctx, std::vector<const Trk::DiscLayer* >* dLayers = nullptr) const;
+        
+      const Trk::LayerMaterialProperties* barrelLayerMaterial(double r, double hz) const;  //!< helper method to construct barrel material
+      const Trk::LayerMaterialProperties* endcapLayerMaterial(double rMin, double rMax) const; //!< helper method to construct endcap material
+        
+      void registerSurfacesToLayer(const std::vector<const Trk::Surface*>& surfaces, const Trk::Layer& layer) const; //!< layer association
+
+      bool                                           m_pixelCase;                      //!< flag for pixel/sct
+                                                     
+      const InDetDD::SiDetectorManager*              m_siMgr;                          //!< the Si Detector Manager
+      std::string                                    m_siMgrLocation;                  //!< the location of the Pixel Manager
+      const PixelID*                                 m_pixIdHelper;                    //!< pixel Id Helper 
+      const SCT_ID*                                  m_sctIdHelper;                    //!< sct Id Helper
+                                                     
+      bool                                           m_setLayerAssociation;            //!< Set Layer Association
+                                                     
+      // barrel layer section                        
+      std::vector<double>                            m_barrelAdditionalLayerR;         //!< Create an additional layer at these radii
+      std::vector<int>                               m_barrelAdditionalLayerType;      //!< material layer 1 - navigation layer 0 
+      size_t                                         m_barrelLayerBinsZ;               //!< Barrel bins for the material in z 
+      size_t                                         m_barrelLayerBinsPhi;             //!< Barrel bins for the material in phi
+      double                                         m_barrelEnvelope;                 //!< envelope around rMin/rMax
+      double                                         m_barrelEdbTolerance;             //!< tolerance in percent how much the bin sizes can change
+
+      bool                                           m_endcapRingLayout;               //!< will not synchronise the rMin/rMax
+      std::vector<double>                            m_endcapAdditionalLayerPosZ;      //!< Create additional endcaps at these z positions
+      std::vector<int>                               m_endcapAdditionalLayerType;      //!< material layer 1 - navigation layer 0 ( for volume adjustment )
+      size_t                                         m_endcapLayerBinsR;               //!< Barrel bins for the material in r
+      size_t                                         m_endcapLayerBinsPhi;             //!< Barrel bins for the material in phi
+      double                                         m_endcapEnvelope;                 //!< envelope around rMin/rMax
+      bool                                           m_endcapComplexRingBinning;       //!< make std::vector<R> rings, could be different for layers
+                                                     
+      std::string                                    m_identification;                  //!< string identification  
+      
+      int                                            m_splitMode;                       //!< Check for the split mode : -1 | 0 | 1 
+      double                                         m_splitTolerance;                  //!< difference in layer half length to provoke the split
+
+      static double                                  s_splitRadius;                     //!< Split radius for multiple pixel systems
+      static std::vector<const Trk::CylinderLayer*>  s_splitCylinderLayers;             //!< cached SLHC/split cylinder layers for projective layout
+      static std::vector<const Trk::DiscLayer*>      s_splitDiscLayers;                 //!< cached SLHC/split disc layers for projective layout
+      static EventIDRange                            s_splitIOVRange;                      //!< store range of splitLayers
+                                                     
+      bool                                           m_runGeometryValidation;           //!< run the validation of the geometry ( no empty bins)
+      SG::ReadCondHandleKey<InDetDD::SiDetectorElementCollection> m_SCT_ReadKey{this, "SCT_ReadKey", "SCT_DetectorElementCollection", "Key of output SiDetectorElementCollection for SCT"};
+      SG::ReadCondHandleKey<InDetDD::SiDetectorElementCollection> m_PixelReadKey{this, "PixelReadKey", "PixelDetectorElementCollection", "Key of output SiDetectorElementCollection for Pixel"};
+            
+                      
+  };
+
+ inline std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* > SiLayerBuilderCond::planarLayers(const EventContext&) const
+  {
+  //create dummy infinite range
+    EventIDRange range;
+    return std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* >(range, 0);
+  }
+ 
+ inline const std::string& SiLayerBuilderCond::identification() const
+ { return m_identification; }
+   
+} // end of namespace
+
+
+#endif // INDETTRACKINGGEOMETRY_SILAYERBUILDERNCOND_H
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/StagedTrackingGeometryBuilderCond.h b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/StagedTrackingGeometryBuilderCond.h
new file mode 100755
index 0000000000000000000000000000000000000000..7eeddeb3a88f4abc30c5baebf58e350fee928e1a
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/StagedTrackingGeometryBuilderCond.h
@@ -0,0 +1,255 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// StagedTrackingGeometryBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef INDETTRACKINGGEOMETRY_STAGEDTRACKINGGEOMETRYBUILDERCOND_H
+#define INDETTRACKINGGEOMETRY_STAGEDTRACKINGGEOMETRYBUILDERCOND_H
+
+//Trk
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrUtils/BinningType.h"
+#include "TrkGeometry/TrackingVolumeManipulator.h"
+//InDet
+#include "StagedTrackingGeometryBuilder.h"
+// Gaudi
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+// STL
+#include <vector>
+#include <string>
+
+#ifndef TRKDETDESCR_TAKESMALLERBIGGER
+#define TRKDETDESCR_TAKESMALLERBIGGER
+#define takeSmaller(current,test) current = current < test ? current : test
+#define takeBigger(current,test)  current = current > test ? current : test
+#define takeSmallerBigger(cSmallest, cBiggest, test) takeSmaller(cSmallest, test); takeBigger(cBiggest, test)
+#endif
+
+
+namespace Trk {
+ class TrackingGeometry;
+ class ILayerProviderCond;
+ class ITrackingVolumeCreator;
+ class ILayerArrayCreator;
+ class IMagneticFieldTool;
+ class Layer;
+ class Material;
+ class MagneticFieldProperties;
+}
+ 
+class IEnvelopeDefSvc; 
+ 
+namespace InDet {
+     
+  /** @struct LayerSetup 
+       - helps understanding how to pack the layers into a volume compound
+   */
+// implemented in StagedTrackingGeometrybuilder.h (without "Cond")  
+//  struct LayerSetup {
+//
+//    // the layer cache
+//    std::vector<const Trk::Layer*> negativeLayers;
+//    std::vector<const Trk::Layer*> centralLayers;
+//    std::vector<const Trk::Layer*> positiveLayers;
+//        
+//    // center information  
+//    double minRadiusCenter;
+//    double maxRadiusCenter;  
+//    double zExtendCenter;
+//    int    binningCenter;
+//    
+//    // endcap information
+//    bool buildEndcap;
+//    double minRadiusEndcap;
+//    double maxRadiusEndcap;  
+//    double minZextendEndcap;
+//    double maxZextendEndcap;
+//    int binningEndcap;
+//    
+//    // full setup information
+//    double zSector;
+//    double rMin;
+//    double rMax;
+//    double zMax;
+//    
+//    std::string identification;
+//    int         colorCode;
+//    
+//    LayerSetup(const std::string& idName,
+//               int cCode,
+//               const std::vector<const Trk::Layer*>& negLayers,
+//               const std::vector<const Trk::Layer*>& cenLayers,
+//               const std::vector<const Trk::Layer*>& posLayers,
+//               double minRc, double maxRc, double zC, int binC,
+//               bool bec=false, double minRe=0., double maxRe=0., double zMinE=0., double zMaxE=0., int binE = 0) :
+//      negativeLayers(negLayers),
+//      centralLayers(cenLayers),
+//      positiveLayers(posLayers),
+//      minRadiusCenter(minRc),
+//      maxRadiusCenter(maxRc),
+//      zExtendCenter(zC),
+//      binningCenter(binC),
+//      buildEndcap(bec),            
+//      minRadiusEndcap(minRe),   
+//      maxRadiusEndcap(maxRe),
+//      minZextendEndcap(zMinE),
+//      maxZextendEndcap(zMaxE),
+//      binningEndcap(binE),
+//      identification(idName),
+//      colorCode(cCode)
+//    {
+//        rMin     = minRadiusCenter < minRadiusEndcap ? minRadiusCenter : minRadiusEndcap;
+//        rMax     = maxRadiusCenter > maxRadiusEndcap ? maxRadiusCenter : maxRadiusEndcap;
+//        zMax     = zExtendCenter > maxZextendEndcap ? zExtendCenter : maxZextendEndcap;
+//        zSector  = buildEndcap ? 0.5*(zExtendCenter+minZextendEndcap) : zExtendCenter;
+//        
+//    }
+//             
+//  };
+
+
+  /** @class StagedTrackingGeometryBuilderCond
+
+      New Geometry builder that adapts to different layer setups
+      
+      Only a few parameters are not automated:
+       - m_outwardsFraction: this defines how much you orient yourself on the next bigger layer
+                             if you wrap an outer volume around an inner 0.5 would lead to a boundary fully in bewteen
+                            1. at the outer boundary, 0. at the inner boundary
+      
+      @author Andreas.Salzburger@cern.ch
+    
+    */
+    
+  class StagedTrackingGeometryBuilderCond : public AthAlgTool, 
+                                        public Trk::TrackingVolumeManipulator,
+                                        virtual public Trk::IGeometryBuilderCond {
+    
+    
+    public:
+      /** Constructor */
+      StagedTrackingGeometryBuilderCond(const std::string&,const std::string&,const IInterface*);
+      
+      /** Destructor */
+      virtual ~StagedTrackingGeometryBuilderCond();
+        
+      /** AlgTool initailize method.*/
+      StatusCode initialize();
+      /** AlgTool finalize method */
+      StatusCode finalize();
+      /** TrackingGeometry Interface methode */
+      std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const; 
+
+      /** The unique signature */
+      Trk::GeometrySignature geometrySignature() const { return Trk::ID; }
+      
+    private:
+      /** Private helper method, estimates the overal dimensions */
+      LayerSetup estimateLayerSetup(const std::string& idName, size_t ils,
+                                    const std::vector<const Trk::Layer*>& negLayers,
+                                    const std::vector<const Trk::Layer*>& centralLayers,
+                                    const std::vector<const Trk::Layer*>& posLayers,
+                                    double maxR, double maxZ) const;
+                                    
+      /** Private helper method to estimate the layer dimensions */
+      void estimateLayerDimensions(const std::vector<const Trk::Layer*>& layers,
+                                   double& rMin, double& rMax, double& zMin, double& zMax) const;
+                                   
+      /** Private helper method to check if a sector is compatible with the cache */
+      bool setupFitsCache(LayerSetup& layerSetup, std::vector<InDet::LayerSetup>& layerSetupCache) const;
+                                   
+                                   
+      /** Private helper method to flush the cache into the id volumes - return volume is the one to be provided */
+      const Trk::TrackingVolume* createFlushVolume(std::vector<InDet::LayerSetup>& layerSetupCache,
+                                                   double innerRadius, double& outerRadius, double extendZ) const;                                                         
+        
+      /** Private helper method, creates a TrackingVolume - and checks if configured - for Ring Layout 
+            - in case a ring layout is given, it creates the corresponding sub-volumes and updates the radius                                       
+            */
+      const Trk::TrackingVolume* createTrackingVolume(const std::vector<const Trk::Layer*>& layers, 
+                                                      double innerRadius, double& outerRadius,
+                                                      double zMin, double zMax,
+                                                      const std::string& volumeName,
+                                                      Trk::BinningType btype,
+						      bool doAdjustOuterRadius = true) const;                                                  
+        
+      /** Private helper method, creates and packs a triple containing of NegEndcap-Barrel-PosEndcap layers
+          - in case of a ring layout the subvolumes are created and the rMax is adapted                                             
+         */
+      const Trk::TrackingVolume* packVolumeTriple(const LayerSetup& layerSetup,
+                                                  double rMin, double& rMax,
+                                                  double zMin, double zPosCentral) const;      
+      
+      /** Private helper method, creates and packs a triple containing of NegEndcap-Barrel-PosEndcap volumes */
+      const Trk::TrackingVolume* packVolumeTriple(const std::vector<const Trk::TrackingVolume*>& negVolumes,
+                                                  const std::vector<const Trk::TrackingVolume*>& centralVolumes,
+                                                  const std::vector<const Trk::TrackingVolume*>& posVolumes,
+                                                  const std::string& baseName="UndefinedVolume") const;
+                                                  
+      /** Private helper method for detection of Ring layout */
+      bool ringLayout(const std::vector<const Trk::Layer*>& layers, std::vector<double>& rmins, std::vector<double>& rmaxs) const;                                              
+
+      /** helper method needed for the Ring layout */
+      void checkForInsert(std::vector<double>& radii, double radius) const;
+
+      // helper tools for the geometry building
+      ToolHandleArray<Trk::ILayerProviderCond>           m_layerProviders;          //!< Helper Tools for the Layer creation, includes beam pipe builder   
+      ToolHandle<Trk::ITrackingVolumeCreator>        m_trackingVolumeCreator;   //!< Helper Tool to create TrackingVolumes
+      ToolHandle<Trk::ILayerArrayCreator>            m_layerArrayCreator;       //!< Helper Tool to create BinnedArrays
+
+      // configurations for the layer builders
+      std::vector<int>                               m_layerBinningTypeCenter;  //!< binning type for the provided layers      
+      std::vector<int>                               m_layerBinningTypeEndcap;  //!< binning type for the provided layers      
+      std::vector<int>                               m_colorCodesConfig;        //!< Color codes    
+
+      // enclosing endcap/cylinder layer 
+      ServiceHandle<IEnvelopeDefSvc>                 m_enclosingEnvelopeSvc;     //!< the service to provide the ID envelope size
+      std::vector<double>                            m_enclosingCylinderRadius;  //!< the cylinder layer inside the enclosing volume
+      std::vector<double>                            m_enclosingDiscPositionZ;   //!< the disc position inside the enclosing volume
+      
+      double                                         m_layerEnvelopeCover;       //!< innermost - outermost 
+      bool                                           m_buildBoundaryLayers;      //!< create boundary layers 
+      bool                                           m_replaceJointBoundaries;   //!< run with replacement of all joint boundaries 
+      
+      // magnetic & material field configuration
+      mutable Trk::Material*                         m_materialProperties;       //!< overal material properties of the ID
+      mutable Trk::MagneticFieldProperties*          m_magneticFieldProperties;  //!< overal mag field properties of the ID
+                    
+      // robust layer indexing                                                   
+      bool                                           m_indexStaticLayers;        //!< forces robust indexing for layers
+      
+      // check for endcap ring layout
+      bool                                           m_checkForRingLayout;        //!< this is to check for the endcap ring layout
+      double                                         m_ringTolerance;            //!< the ring tolerance 
+      
+      // naming schema                                                           
+      std::string                                    m_namespace;                //!< identificaton namespace 
+      // ID container                                                            
+      std::string                                    m_exitVolume;                //!< the final ID container             
+  };
+
+  inline void StagedTrackingGeometryBuilderCond::checkForInsert(std::vector<double>& radii, double radius) const {
+      bool exists = false;
+      // loop and check
+      for (auto& checkr : radii) {
+          if ( (checkr-radius)*(checkr-radius) < m_ringTolerance*m_ringTolerance ){
+              exists = true; break;
+          }
+      }
+      // insert 
+      if (!exists) radii.push_back(radius);
+      // re-sort
+      std::sort(radii.begin(),radii.end());   
+  }
+
+
+} // end of namespace
+
+#endif //INDETTRACKINGGEOMETRY_STAGEDTRACKINGGEOMETRYBUILDERCOND_H
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/TRT_LayerBuilderCond.h b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/TRT_LayerBuilderCond.h
new file mode 100755
index 0000000000000000000000000000000000000000..19a6395a07235f5c64278730276456dc1adcb290
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/TRT_LayerBuilderCond.h
@@ -0,0 +1,117 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// TRT_LayerBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef INDETTRACKINGGEOMETRY_TRT_LAYERBUILDERCOND_H
+#define INDETTRACKINGGEOMETRY_TRT_LAYERBUILDERCOND_H
+
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// Athena
+#include "AthenaBaseComps/AthAlgTool.h"
+// Trk
+#include "TrkDetDescrInterfaces/ILayerBuilderCond.h"
+#include "TrkDetDescrUtils/SharedObject.h"
+// STL
+#include <vector>
+
+#ifndef TRKDETDESCR_TAKESMALLERBIGGER
+#define TRKDETDESCR_TAKESMALLERBIGGER
+#define takeSmaller(current,test) current = current < test ? current : test
+#define takeBigger(current,test)  current = current > test ? current : test
+#define takeSmallerBigger(cSmallest, cBiggest, test) takeSmaller(cSmallest, test); takeBigger(cBiggest, test)
+#endif
+
+namespace InDetDD {
+  class TRT_DetectorManager;
+}
+
+namespace Trk {
+  class Surface;
+  class Layer;
+  class CylinderLayer;
+  class DiscLayer;
+  class ExtendedMaterialProperties;
+  typedef std::pair< SharedObject<const Surface>, Amg::Vector3D > SurfaceOrderPosition;
+}
+
+namespace InDet {
+ 
+  /** @class TRT_LayerBuilderCond
+     
+     @author Andreas.Salzburger@cern.ch
+    */
+  class TRT_LayerBuilderCond : public AthAlgTool,
+                           virtual public Trk::ILayerBuilderCond {
+    
+    /** Declare the TRT_VolumeBuilder as friend */
+    friend class TRT_VolumeBuilder;
+    
+    public:
+    
+      /** AlgTool style constructor */
+      TRT_LayerBuilderCond(const std::string&,const std::string&,const IInterface*);
+      /** Destructor */
+      virtual ~TRT_LayerBuilderCond();
+      
+      /** AlgTool initialize method */
+      StatusCode initialize();
+      /** AlgTool finalize method */
+      StatusCode finalize();
+       
+      /** LayerBuilderCond interface method - returning Barrel-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::CylinderLayer* >* > cylindricalLayers(const EventContext& ctx) const; 
+      
+      /** LayerBuilderCond interface method - returning Endcap-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::DiscLayer* >* >     discLayers(const EventContext& ctx) const; 
+      
+      /** LayerBuilderCond interface method - returning Planar-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* >    planarLayers(const EventContext& ctx) const; 
+            
+      /** Name identification */
+      const std::string& identification() const;      
+      
+    private:
+      const InDetDD::TRT_DetectorManager*           m_trtMgr;                   //!< the TRT Manager
+      std::string                                   m_trtMgrLocation;           //!< the location of the TRT Manager     
+                   
+      double                                        m_layerStrawRadius;         //!< straw radius                                                                            
+      double                                        m_layerThickness;           //!< modelled layer thickness
+      bool                                          m_modelGeometry;            //!< Build the geometry with model layers      
+      unsigned int                                  m_modelBarrelLayers;        //!< model barrel layers with material
+      unsigned int                                  m_modelEndcapLayers;        //!< model endcap layers with material
+                                                                                
+      unsigned int                                  m_barrelLayerBinsZ;         //!< Bins for the Barrel material - in z
+      unsigned int                                  m_barrelLayerBinsPhi;       //!< Bins for the Barrel material - in phi
+      unsigned int                                  m_endcapLayerBinsR;         //!< Bins for the Endcap material - in r
+      unsigned int                                  m_endcapLayerBinsPhi;       //!< Bins for the Endcap material - in phi
+      bool                                          m_endcapConly;              //!< Only build the endcapC
+                                                                                
+      bool                                          m_registerStraws;           //!< register the straws
+      int                                           m_barrelSectorAtPiBoundary; //!< this is the barrel Sector where +pi/-pi is within
+      
+      std::string                                   m_identification;           //!< string identification                        
+      
+      
+  };
+
+ inline std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* > TRT_LayerBuilderCond::planarLayers(const EventContext&) const
+  {
+  //create dummy infinite range
+    EventIDRange range;
+    return std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* >(range, 0);
+  }
+ 
+ inline const std::string& TRT_LayerBuilderCond::identification() const
+ { return m_identification; }
+   
+} // end of namespace
+
+
+#endif // INDETTRACKINGGEOMETRY_TRT_LAYERBUILDERCOND_H
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredInDetTrackingGeometryBuilderCond.py b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredInDetTrackingGeometryBuilderCond.py
new file mode 100644
index 0000000000000000000000000000000000000000..f592e04e99d870f4af5d73163e294dd0bc89cdaf
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredInDetTrackingGeometryBuilderCond.py
@@ -0,0 +1,201 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+######################################################
+# ConfiguredInDetTrackingGeometry module
+#
+# it inherits from RobustTrackingGeometryBuilderConf and performs 
+# standard configuration
+#
+######################################################
+
+# import the Extrapolator configurable
+from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__RobustTrackingGeometryBuilderCond
+from AthenaCommon.DetFlags import DetFlags
+
+# define the class
+class ConfiguredInDetTrackingGeometryBuilderCond( InDet__RobustTrackingGeometryBuilderCond ):
+    # constructor
+    def __init__(self,name = 'InDetTrackingGeometryBuilderCond',
+                      namePrefix = '',
+                      setLayerAssociation = True,
+                      buildTrtStrawLayers = False):
+
+        # get the ToolSvc
+        from AthenaCommon.AppMgr import ToolSvc, ServiceMgr           
+       
+        # the Detector flags to be imported
+        from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+        
+        # beampipe        
+        from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__BeamPipeBuilderCond
+        BeamPipeBuilder = InDet__BeamPipeBuilderCond(name=namePrefix+'BeamPipeBuilderCond')
+        BeamPipeBuilder.BeamPipeRadius 	        = TrkDetFlags.BeamPipeRadius()
+        BeamPipeBuilder.BeamPipeThickness       = TrkDetFlags.BeamPipeThickness() 
+        BeamPipeBuilder.BeamPipeMaterialBinsZ   = TrkDetFlags.BeamPipeLayerMaterialBinsZ()
+        BeamPipeBuilder.OutputLevel             = TrkDetFlags.InDetBuildingOutputLevel()
+        ToolSvc += BeamPipeBuilder
+                
+        # the layer builders
+        layerbuilders = []
+        binnings      = []
+        colors        = []
+                        
+        # @TODO put DetFlags isOn here, but make sure that this is really when the detector is not built        
+        
+        # PIXEL building
+        if DetFlags.pixel_on():
+          from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__SiLayerBuilderCond
+          PixelLayerBuilder = InDet__SiLayerBuilderCond(name=namePrefix+'PixelLayerBuilderCond')
+          PixelLayerBuilder.PixelCase 	       = True
+          PixelLayerBuilder.Identification       = 'Pixel'
+          PixelLayerBuilder.SiDetManagerLocation = 'Pixel'
+          # additionall layers - handle with care !
+          PixelLayerBuilder.BarrelAdditionalLayerRadii      = [ 130 ]   # The PST
+          PixelLayerBuilder.BarrelAdditionalLayerType       = [ 0 ]     # -- will shift volume boundary to PST
+          PixelLayerBuilder.EndcapAdditionalLayerPositionsZ = [ -1900. , 1900. ] # DBM
+          PixelLayerBuilder.EndcapAdditionalLayerType       = [  1 , 1 ] # DBM
+          # Pixel barrel specifications
+          PixelLayerBuilder.BarrelLayerBinsZ     = TrkDetFlags.PixelBarrelLayerMaterialBinsZ()
+          PixelLayerBuilder.BarrelLayerBinsPhi   = TrkDetFlags.PixelBarrelLayerMaterialBinsPhi()
+          PixelLayerBuilder.EndcapLayerBinsR     = TrkDetFlags.PixelEndcapLayerMaterialBinsR()
+          PixelLayerBuilder.EndcapLayerBinsPhi   = TrkDetFlags.PixelEndcapLayerMaterialBinsPhi()
+          
+          # set the layer association
+          PixelLayerBuilder.SetLayerAssociation  = setLayerAssociation
+          # output level
+          PixelLayerBuilder.OutputLevel         = TrkDetFlags.PixelBuildingOutputLevel()
+          # the binning type of the layers   
+          PixelLayerBinning = 2
+          # add it to tool service
+          ToolSvc += PixelLayerBuilder
+          # put them to the caches
+          layerbuilders += [ PixelLayerBuilder ]
+          binnings      += [ PixelLayerBinning ]
+          colors        += [ 3 ]
+       
+        if DetFlags.SCT_on():
+          # SCT building
+          from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__SiLayerBuilderCond
+          SCT_LayerBuilder = InDet__SiLayerBuilderCond(name=namePrefix+'SCT_LayerBuilderCond')
+          SCT_LayerBuilder.PixelCase                       = False
+          SCT_LayerBuilder.Identification                  = 'SCT'
+          SCT_LayerBuilder.SiDetManagerLocation            = 'SCT'
+          # additionall layers - handle with care !
+          SCT_LayerBuilder.EndcapAdditionalLayerPositionsZ = [ -2850 , 2850 ] 
+          SCT_LayerBuilder.EndcapAdditionalLayerType       = [  0 , 0 ] 
+          # SCT barrel specifications
+          SCT_LayerBuilder.BarrelLayerBinsZ                = TrkDetFlags.SCT_BarrelLayerMaterialBinsZ()
+          SCT_LayerBuilder.BarrelLayerBinsPhi              = TrkDetFlags.SCT_BarrelLayerMaterialBinsPhi()
+          # SCT endcap specifications                          
+          SCT_LayerBuilder.EndcapLayerBinsR                = TrkDetFlags.SCT_EndcapLayerMaterialBinsR()
+          SCT_LayerBuilder.EndcapLayerBinsPhi              = TrkDetFlags.SCT_EndcapLayerMaterialBinsPhi()
+          SCT_LayerBuilder.EndcapComplexRingBinning        = TrkDetFlags.SCT_EndcapLayerDynamicRings()
+          # set the layer association                   
+          SCT_LayerBuilder.SetLayerAssociation             = setLayerAssociation        
+          # output level                                 
+          SCT_LayerBuilder.OutputLevel                     = TrkDetFlags.SCT_BuildingOutputLevel()
+          # the binning type of the layer     
+          SCT_LayerBinning = 2
+          # SCT -> ToolSvc                             
+          ToolSvc += SCT_LayerBuilder                       
+          # put them to the caches
+          layerbuilders += [ SCT_LayerBuilder ]
+          binnings      += [ SCT_LayerBinning ]
+          colors        += [ 4 ]
+        
+        if DetFlags.TRT_on():                                                      
+          from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__TRT_LayerBuilderCond
+          TRT_LayerBuilder = InDet__TRT_LayerBuilderCond(name=namePrefix+'TRT_LayerBuilderCond')
+          # TRT barrel specifications
+          TRT_LayerBuilder.ModelBarrelLayers  = TrkDetFlags.TRT_BarrelModelLayers()
+          TRT_LayerBuilder.BarrelLayerBinsZ   = TrkDetFlags.TRT_BarrelLayerMaterialBinsZ()
+          TRT_LayerBuilder.BarrelLayerBinsPhi = TrkDetFlags.TRT_BarrelLayerMaterialBinsPhi()
+          # SCT endcap specifications                     
+          TRT_LayerBuilder.ModelEndcapLayers  = TrkDetFlags.TRT_EndcapModelLayers()
+          TRT_LayerBuilder.EndcapLayerBinsR   = TrkDetFlags.TRT_EndcapLayerMaterialBinsR()
+          TRT_LayerBuilder.EndcapLayerBinsPhi = TrkDetFlags.TRT_EndcapLayerMaterialBinsPhi()                
+          # set the binning from bi-aequidistant to arbitrary for complex TRT volumes
+          TRT_LayerBinning = 1        
+          if buildTrtStrawLayers or TrkDetFlags.TRT_BuildStrawLayers() :
+             TRT_LayerBinning = 2
+             TRT_LayerBuilder.ModelLayersOnly = False
+          # output level
+          TRT_LayerBuilder.OutputLevel        = TrkDetFlags.TRT_BuildingOutputLevel()
+          # TRT -> ToolSvc                      
+          ToolSvc += TRT_LayerBuilder
+          # put them to the caches
+          layerbuilders += [ TRT_LayerBuilder ]
+          binnings      += [ TRT_LayerBinning ]
+          colors        += [ 5 ]
+        
+        
+        # helpers for the InDetTrackingGeometry Builder : layer array creator
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__LayerArrayCreator
+        InDetLayerArrayCreator = Trk__LayerArrayCreator(name = 'InDetLayerArrayCreator')
+        InDetLayerArrayCreator.EmptyLayerMode           = 2 # deletes empty material layers from arrays
+        InDetLayerArrayCreator.OutputLevel              = TrkDetFlags.InDetBuildingOutputLevel()
+        # add to ToolSvc
+        ToolSvc += InDetLayerArrayCreator
+
+        # helpers for the InDetTrackingGeometry Builder : volume array creator
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__TrackingVolumeArrayCreator
+        InDetTrackingVolumeArrayCreator                       = Trk__TrackingVolumeArrayCreator(name = 'InDetTrackingVolumeArrayCreator')
+        InDetTrackingVolumeArrayCreator.OutputLevel           = TrkDetFlags.InDetBuildingOutputLevel()
+        # add to ToolSvc
+        ToolSvc += InDetTrackingVolumeArrayCreator
+        
+        # helpers for the InDetTrackingGeometry Builder : tracking voluem helper for glueing
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__TrackingVolumeHelper
+        InDetTrackingVolumeHelper                             = Trk__TrackingVolumeHelper(name ='InDetTrackingVolumeHelper')
+        InDetTrackingVolumeHelper.OutputLevel                 = TrkDetFlags.InDetBuildingOutputLevel()
+        # the material bins 
+        InDetTrackingVolumeHelper.BarrelLayerBinsZ            = TrkDetFlags.InDetPassiveLayerMaterialBinsRz()
+        InDetTrackingVolumeHelper.BarrelLayerBinsPhi          = TrkDetFlags.InDetPassiveLayerMaterialBinsPhi() 
+        InDetTrackingVolumeHelper.EndcapLayerBinsR            = TrkDetFlags.InDetPassiveLayerMaterialBinsRz()
+        InDetTrackingVolumeHelper.EndcapLayerBinsPhi          = TrkDetFlags.InDetPassiveLayerMaterialBinsPhi() 
+        # add to ToolSvc
+        ToolSvc += InDetTrackingVolumeHelper
+        
+        # helpers for the InDetTrackingGeometry Builder : cylinder volume creator
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__CylinderVolumeCreator
+        InDetCylinderVolumeCreator = Trk__CylinderVolumeCreator(name = 'InDetCylinderVolumeCreator')
+        # give him the layer array creator
+        InDetCylinderVolumeCreator.LayerArrayCreator          = InDetLayerArrayCreator
+        InDetCylinderVolumeCreator.TrackingVolumeArrayCreator = InDetTrackingVolumeArrayCreator
+        InDetCylinderVolumeCreator.TrackingVolumeHelper       = InDetTrackingVolumeHelper
+        # specifiy the binning, passive layers, entry layers
+        InDetCylinderVolumeCreator.PassiveLayerThickness      = TrkDetFlags.InDetPassiveLayerThickness()  
+        InDetCylinderVolumeCreator.PassiveLayerBinsPhi        = TrkDetFlags.InDetPassiveLayerMaterialBinsPhi()  
+        InDetCylinderVolumeCreator.PassiveLayerBinsRZ         = TrkDetFlags.InDetPassiveLayerMaterialBinsRz()  
+        # output level                                       
+        InDetCylinderVolumeCreator.OutputLevel                = TrkDetFlags.InDetBuildingOutputLevel()        
+        # add to ToolSvc
+        ToolSvc += InDetCylinderVolumeCreator        
+        
+        # the envelope definition service
+        from SubDetectorEnvelopes.SubDetectorEnvelopesConf import DetDescrDBEnvelopeSvc
+        AtlasEnvelopeSvc = DetDescrDBEnvelopeSvc('AtlasEnvelopeSvcDefinitionSvc')
+        # set the output level for the Envelope service
+        AtlasEnvelopeSvc.OutputLevel      = TrkDetFlags.InDetBuildingOutputLevel()  
+        # add to SvcMgr
+        ServiceMgr += AtlasEnvelopeSvc
+        
+        # the tracking geometry builder
+        InDet__RobustTrackingGeometryBuilderCond.__init__(self,namePrefix+name,\
+                                                      BeamPipeBuilder   = BeamPipeBuilder,\
+                                                      LayerBuilders     = layerbuilders,
+                                                      LayerBinningType  = binnings,
+                                                      ColorCodes        = colors,
+                                                      BarrelEntryLayers = [ 2, 2, 2 ],
+                                                      EndcapEntryLayers = [ 1, 0, 1 ],
+                                                      EnvelopeDefinitionSvc = AtlasEnvelopeSvc,
+                                                      VolumeEnclosureDiscPositions = [ 3000., 3450. ],
+                                                      TrackingVolumeCreator     = InDetCylinderVolumeCreator,
+                                                      LayerArrayCreator         = InDetLayerArrayCreator,
+                                                      BuildBoundaryLayers       = TrkDetFlags.InDetBuildMaterialBoundaries(),
+                                                      ReplaceAllJointBoundaries = TrkDetFlags.InDetBuildJointBoundaries(),
+                                                      OutputLevel               = TrkDetFlags.InDetBuildingOutputLevel(),
+                                                      ExitVolumeName            = TrkDetFlags.InDetContainerName(),
+                                                      MagneticFieldMode         = TrkDetFlags.MagneticFieldMode())
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredStagedTrackingGeometryBuilderCond.py b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredStagedTrackingGeometryBuilderCond.py
new file mode 100644
index 0000000000000000000000000000000000000000..07abdcbba39dea1477dab3548a0ab10bb59fabdd
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredStagedTrackingGeometryBuilderCond.py
@@ -0,0 +1,223 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+######################################################
+# ConfiguredStagedTrackingGeometry module
+#
+# it inherits from RobustTrackingGeometryBuilderConf and performs 
+# standard configuration
+#
+######################################################
+
+# import the Extrapolator configurable
+from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__StagedTrackingGeometryBuilderCond
+
+# define the class
+class ConfiguredStagedTrackingGeometryBuilderCond( InDet__StagedTrackingGeometryBuilderCond ):
+    # constructor
+    def __init__(self,name = 'InDetTrackingGeometryBuilderCond',
+                      namePrefix = '',
+                      setLayerAssociation = True,
+                      buildTrtStrawLayers = False):
+
+        # get the ToolSvc
+        from AthenaCommon.AppMgr import ToolSvc, ServiceMgr
+        from AthenaCommon.DetFlags import DetFlags
+       
+        # the Detector flags to be imported
+        from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+        
+        # beampipe
+        from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__BeamPipeBuilderCond
+        BeamPipeBuilder = InDet__BeamPipeBuilderCond(name=namePrefix+'BeamPipeBuilderCond')
+        BeamPipeBuilder.BeamPipeRadius 	        = TrkDetFlags.BeamPipeRadius()
+        BeamPipeBuilder.BeamPipeThickness       = TrkDetFlags.BeamPipeThickness() 
+        BeamPipeBuilder.BeamPipeMaterialBinsZ   = TrkDetFlags.BeamPipeLayerMaterialBinsZ()
+        BeamPipeBuilder.OutputLevel             = TrkDetFlags.BeamPipeBuildingOutputLevel()
+        ToolSvc += BeamPipeBuilder
+
+        # the layer providers
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__LayerProviderCond
+        BeamPipeProvider = Trk__LayerProviderCond(name=namePrefix+'BeamPipeProviderCond')
+        BeamPipeProvider.LayerBuilder = BeamPipeBuilder
+        ToolSvc += BeamPipeProvider
+
+        # binning of the beam pipe
+        BeamPipeBinning = 2
+                
+        # the layer builders
+        layerProviders  = [ BeamPipeProvider ]
+        binningsCenter  = [ BeamPipeBinning ]
+        binningsEndcap  = [ BeamPipeBinning ]
+        colors          = [ 2 ]
+                                
+        # PIXEL building
+        if DetFlags.pixel_on() :
+            from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__SiLayerBuilderCond
+            PixelLayerBuilder = InDet__SiLayerBuilderCond(name=namePrefix+'PixelLayerBuilderCond')
+            PixelLayerBuilder.PixelCase 	       = True
+            PixelLayerBuilder.Identification       = 'Pixel'
+            PixelLayerBuilder.SiDetManagerLocation = 'Pixel'
+            # Pixel barrel specifications
+            PixelLayerBuilder.BarrelLayerBinsZ     = TrkDetFlags.PixelBarrelLayerMaterialBinsZ()
+            PixelLayerBuilder.BarrelLayerBinsPhi   = TrkDetFlags.PixelBarrelLayerMaterialBinsPhi()
+            PixelLayerBuilder.EndcapLayerBinsR     = TrkDetFlags.PixelEndcapLayerMaterialBinsR()
+            PixelLayerBuilder.EndcapLayerBinsPhi   = TrkDetFlags.PixelEndcapLayerMaterialBinsPhi()
+            PixelLayerBuilder.EndcapRingLayout     = TrkDetFlags.PixelRingLayout()
+            # set the layer association
+            PixelLayerBuilder.SetLayerAssociation  = setLayerAssociation
+            # output level
+            PixelLayerBuilder.OutputLevel         = TrkDetFlags.PixelBuildingOutputLevel()
+            # the binning type of the layers   
+            PixelLayerBinning = 2
+            # add it to tool service
+            ToolSvc += PixelLayerBuilder
+            
+            # the layer providers
+            PixelLayerProvider = Trk__LayerProviderCond(name=namePrefix+'PixelLayerProviderCond')
+            PixelLayerProvider.LayerBuilder = PixelLayerBuilder
+            ToolSvc += PixelLayerProvider
+            layerProviders  += [ PixelLayerProvider ]
+            binningsCenter  += [ PixelLayerBinning ]
+            binningsEndcap  += [ PixelLayerBinning ]
+            colors          += [ 3 ]
+        
+        # SCT building
+        if DetFlags.SCT_on() :
+            SCT_LayerBuilder = InDet__SiLayerBuilderCond(name=namePrefix+'SCT_LayerBuilderCond')
+            SCT_LayerBuilder.PixelCase                       = False
+            SCT_LayerBuilder.Identification                  = 'SCT'
+            SCT_LayerBuilder.SiDetManagerLocation            = 'SCT'
+            # additionall layers - handle with care !
+            SCT_LayerBuilder.EndcapAdditionalLayerPositionsZ = [ -2850 , 2850 ] 
+            SCT_LayerBuilder.EndcapAdditionalLayerType       = [  0 , 0 ] 
+            # SCT barrel specifications
+            SCT_LayerBuilder.BarrelLayerBinsZ                = TrkDetFlags.SCT_BarrelLayerMaterialBinsZ()
+            SCT_LayerBuilder.BarrelLayerBinsPhi              = TrkDetFlags.SCT_BarrelLayerMaterialBinsPhi()
+            # SCT endcap specifications                          
+            SCT_LayerBuilder.EndcapLayerBinsR                = TrkDetFlags.SCT_EndcapLayerMaterialBinsR()
+            SCT_LayerBuilder.EndcapLayerBinsPhi              = TrkDetFlags.SCT_EndcapLayerMaterialBinsPhi()
+            SCT_LayerBuilder.EndcapComplexRingBinning        = TrkDetFlags.SCT_EndcapLayerDynamicRings()
+            # set the layer association                   
+            SCT_LayerBuilder.SetLayerAssociation             = setLayerAssociation        
+            # output level                                 
+            SCT_LayerBuilder.OutputLevel                     = TrkDetFlags.SCT_BuildingOutputLevel()
+            # the binning type of the layer     
+            SCT_LayerBinning = 2
+            # SCT -> ToolSvc                             
+            ToolSvc += SCT_LayerBuilder     
+            
+            # the layer providers
+            SCT_LayerProvider = Trk__LayerProviderCond(name=namePrefix+'SCT_LayerProviderCond')
+            SCT_LayerProvider.LayerBuilder = SCT_LayerBuilder
+            ToolSvc += SCT_LayerProvider
+                              
+            # put them to the caches
+            layerProviders  += [ SCT_LayerProvider ]
+            binningsCenter  += [ SCT_LayerBinning ]
+            binningsEndcap  += [ SCT_LayerBinning ]
+            colors          += [ 4 ]
+
+        # TRT building
+        if DetFlags.TRT_on() :
+            from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__TRT_LayerBuilderCond
+            TRT_LayerBuilder = InDet__TRT_LayerBuilderCond(name=namePrefix+'TRT_LayerBuilderCond')
+            # TRT barrel specifications
+            TRT_LayerBuilder.ModelBarrelLayers  = TrkDetFlags.TRT_BarrelModelLayers()
+            TRT_LayerBuilder.BarrelLayerBinsZ   = TrkDetFlags.TRT_BarrelLayerMaterialBinsZ()
+            TRT_LayerBuilder.BarrelLayerBinsPhi = TrkDetFlags.TRT_BarrelLayerMaterialBinsPhi()
+            # SCT endcap specifications                     
+            TRT_LayerBuilder.ModelEndcapLayers  = TrkDetFlags.TRT_EndcapModelLayers()
+            TRT_LayerBuilder.EndcapLayerBinsR   = TrkDetFlags.TRT_EndcapLayerMaterialBinsR()
+            TRT_LayerBuilder.EndcapLayerBinsPhi = TrkDetFlags.TRT_EndcapLayerMaterialBinsPhi()                
+            # set the binning from bi-aequidistant to arbitrary for complex TRT volumes
+            TRT_LayerBinning = 1        
+            if buildTrtStrawLayers or TrkDetFlags.TRT_BuildStrawLayers() :
+               TRT_LayerBinning = 2
+               TRT_LayerBuilder.ModelLayersOnly = False
+            # output level
+            TRT_LayerBuilder.OutputLevel        = TrkDetFlags.TRT_BuildingOutputLevel()
+            # TRT -> ToolSvc
+            ToolSvc += TRT_LayerBuilder
+            
+            
+            # the layer providers
+            TRT_LayerProvider = Trk__LayerProviderCond(name=namePrefix+'TRT_LayerProviderCond')
+            TRT_LayerProvider.LayerBuilder = TRT_LayerBuilder
+            ToolSvc += TRT_LayerProvider
+                              
+            # put them to the caches
+            layerProviders  += [ TRT_LayerProvider ]
+            binningsCenter  += [ TRT_LayerBinning ]
+            binningsEndcap  += [ TRT_LayerBinning ]
+            colors          += [ 5 ]
+        
+        
+        # helpers for the InDetTrackingGeometry Builder : layer array creator
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__LayerArrayCreator
+        InDetLayerArrayCreator = Trk__LayerArrayCreator(name = 'InDetLayerArrayCreator')
+        InDetLayerArrayCreator.EmptyLayerMode           = 2 # deletes empty material layers from arrays
+        InDetLayerArrayCreator.OutputLevel              = TrkDetFlags.InDetBuildingHelperOutputLevel()
+        # add to ToolSvc
+        ToolSvc += InDetLayerArrayCreator
+
+        # helpers for the InDetTrackingGeometry Builder : volume array creator
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__TrackingVolumeArrayCreator
+        InDetTrackingVolumeArrayCreator                       = Trk__TrackingVolumeArrayCreator(name = 'InDetTrackingVolumeArrayCreator')
+        InDetTrackingVolumeArrayCreator.OutputLevel           = TrkDetFlags.InDetBuildingOutputLevel()
+        # add to ToolSvc
+        ToolSvc += InDetTrackingVolumeArrayCreator
+        
+        # helpers for the InDetTrackingGeometry Builder : tracking voluem helper for glueing
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__TrackingVolumeHelper
+        InDetTrackingVolumeHelper                             = Trk__TrackingVolumeHelper(name ='InDetTrackingVolumeHelper')
+        InDetTrackingVolumeHelper.OutputLevel                 = TrkDetFlags.InDetBuildingHelperOutputLevel()
+        # the material bins 
+        InDetTrackingVolumeHelper.BarrelLayerBinsZ            = TrkDetFlags.InDetPassiveLayerMaterialBinsRz()
+        InDetTrackingVolumeHelper.BarrelLayerBinsPhi          = TrkDetFlags.InDetPassiveLayerMaterialBinsPhi() 
+        InDetTrackingVolumeHelper.EndcapLayerBinsR            = TrkDetFlags.InDetPassiveLayerMaterialBinsRz()
+        InDetTrackingVolumeHelper.EndcapLayerBinsPhi          = TrkDetFlags.InDetPassiveLayerMaterialBinsPhi() 
+        # add to ToolSvc
+        ToolSvc += InDetTrackingVolumeHelper
+        
+        # helpers for the InDetTrackingGeometry Builder : cylinder volume creator
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__CylinderVolumeCreator
+        InDetCylinderVolumeCreator = Trk__CylinderVolumeCreator(name = 'InDetCylinderVolumeCreator')
+        # give him the layer array creator
+        InDetCylinderVolumeCreator.LayerArrayCreator          = InDetLayerArrayCreator
+        InDetCylinderVolumeCreator.TrackingVolumeArrayCreator = InDetTrackingVolumeArrayCreator
+        InDetCylinderVolumeCreator.TrackingVolumeHelper       = InDetTrackingVolumeHelper
+        # specifiy the binning, passive layers, entry layers
+        InDetCylinderVolumeCreator.PassiveLayerThickness      = TrkDetFlags.InDetPassiveLayerThickness()  
+        InDetCylinderVolumeCreator.PassiveLayerBinsPhi        = TrkDetFlags.InDetPassiveLayerMaterialBinsPhi()  
+        InDetCylinderVolumeCreator.PassiveLayerBinsRZ         = TrkDetFlags.InDetPassiveLayerMaterialBinsRz()  
+        # output level                                       
+        InDetCylinderVolumeCreator.OutputLevel                = TrkDetFlags.InDetBuildingHelperOutputLevel()        
+        # add to ToolSvc
+        ToolSvc += InDetCylinderVolumeCreator        
+        
+        # the envelope definition service
+        from SubDetectorEnvelopes.SubDetectorEnvelopesConf import DetDescrDBEnvelopeSvc
+        AtlasEnvelopeSvc = DetDescrDBEnvelopeSvc('AtlasEnvelopeSvcDefinitionSvc')
+        # set the output level for the Envelope service
+        AtlasEnvelopeSvc.OutputLevel      = TrkDetFlags.InDetBuildingHelperOutputLevel()  
+        # add to SvcMgr
+        ServiceMgr += AtlasEnvelopeSvc
+        
+        # the tracking geometry builder
+        InDet__StagedTrackingGeometryBuilderCond.__init__(self,namePrefix+name,\
+                                                      LayerBuilders                 = layerProviders,
+                                                      LayerBinningTypeCenter        = binningsCenter,
+                                                      LayerBinningTypeEndcap        = binningsEndcap,
+                                                      ColorCodes                    = colors,
+                                                      EnvelopeDefinitionSvc         = AtlasEnvelopeSvc,
+                                                      VolumeEnclosureDiscPositions  = [ 3000., 3450. ],
+                                                      TrackingVolumeCreator         = InDetCylinderVolumeCreator,
+                                                      LayerArrayCreator             = InDetLayerArrayCreator,
+                                                      CheckForRingLayout            = True,
+                                                      BuildBoundaryLayers           = TrkDetFlags.InDetBuildMaterialBoundaries(),
+                                                      ReplaceAllJointBoundaries     = TrkDetFlags.InDetBuildJointBoundaries(),
+                                                      OutputLevel                   = TrkDetFlags.InDetBuildingOutputLevel(),
+                                                      ExitVolumeName                = TrkDetFlags.InDetContainerName(),
+                                                      MagneticFieldMode             = TrkDetFlags.MagneticFieldMode())
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/BeamPipeBuilderCond.cxx b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/BeamPipeBuilderCond.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..b76e58c252896ef22daa679cb53b6c19db9820c3
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/BeamPipeBuilderCond.cxx
@@ -0,0 +1,170 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// BeamPipeBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#include "InDetTrackingGeometry/BeamPipeBuilderCond.h"
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// Trk inlcude
+#include "TrkDetDescrUtils/GeometryStatics.h"
+#include "TrkDetDescrUtils/BinUtility.h"
+#include "TrkDetDescrGeoModelCnv/GeoShapeConverter.h"
+#include "TrkGeometry/MaterialProperties.h"
+#include "TrkGeometry/LayerMaterialProperties.h"
+#include "TrkGeometry/BinnedLayerMaterial.h"
+#include "TrkGeometry/HomogeneousLayerMaterial.h"
+#include "TrkGeometry/CylinderLayer.h"
+#include "TrkSurfaces/CylinderBounds.h"
+// GeoModel include
+#include "BeamPipeGeoModel/BeamPipeDetectorManager.h"
+#include "GeoModelKernel/GeoTube.h"
+// Gaudi
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/SystemOfUnits.h"
+
+// constructor
+InDet::BeamPipeBuilderCond::BeamPipeBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  m_beamPipeFromDb(true),
+  m_beamPipeMgr(0),
+  m_beamPipeMgrName("BeamPipe"),
+  m_beamPipeEnvelope(1.*Gaudi::Units::mm),
+  m_beamPipeOffsetX(0.*Gaudi::Units::mm),
+  m_beamPipeOffsetY(0.*Gaudi::Units::mm),
+  m_beamPipeRadius(33.1*Gaudi::Units::mm),
+  m_beamPipeHalflength(2.7*Gaudi::Units::m),
+  m_beamPipeThickness(1.*Gaudi::Units::mm),
+  m_beamPipeX0(352.8*Gaudi::Units::mm),
+  m_beamPipeL0(407.*Gaudi::Units::mm),
+  //m_beamPipedEdX(0.2945*Gaudi::Units::MeV/Gaudi::Units::mm),
+  m_beamPipeA(9.012),
+  m_beamPipeZ(4.),
+  m_beamPipeRho(1.848e-3),
+  m_beamPipeBinsZ(1),
+  m_identification("BeamPipe")
+{
+  declareInterface<Trk::ILayerBuilderCond>(this);
+  declareProperty("BeamPipeFromGeoModel" , m_beamPipeFromDb);
+  declareProperty("BeamPipeManager"      , m_beamPipeMgrName);
+  declareProperty("BeamPipeEnvelope"     , m_beamPipeEnvelope);
+  // --------------------- by hand properties of the beam pipe itself -- //
+  declareProperty("BeamPipeOffsetX"      , m_beamPipeOffsetX);
+  declareProperty("BeamPipeOffsetY"      , m_beamPipeOffsetY);
+  declareProperty("BeamPipeRadius"       , m_beamPipeRadius);
+  declareProperty("BeamPipeHalflength"   , m_beamPipeHalflength);
+  declareProperty("BeamPipeThickness"    , m_beamPipeThickness);
+  // --------------------- by hand material properties ---------------- //
+  declareProperty("BeamPipeX0"           , m_beamPipeX0);
+  declareProperty("BeamPipeAverageA"     , m_beamPipeA);
+  declareProperty("BeamPipeAverageZ"     , m_beamPipeZ);
+  declareProperty("BeamPipeAverageRho"   , m_beamPipeRho);
+  // Material bins 
+  declareProperty("BeamPipeMaterialBinsZ", m_beamPipeBinsZ);
+  // identification 
+  declareProperty("Identification"       , m_identification);
+}
+
+// destructor
+InDet::BeamPipeBuilderCond::~BeamPipeBuilderCond()
+{}
+
+// Athena standard methods
+// initialize
+StatusCode InDet::BeamPipeBuilderCond::initialize()
+{
+  if (m_beamPipeFromDb && detStore()->retrieve(m_beamPipeMgr,m_beamPipeMgrName).isFailure()){
+      ATH_MSG_ERROR("Could not retrieve BeamPipe detector manager '" << m_beamPipeMgrName << "'." );
+      return StatusCode::FAILURE;
+  } else if (m_beamPipeFromDb)
+      ATH_MSG_DEBUG("Successfully retrieved BeamPipe detector manager '" << m_beamPipeMgrName << "'." );
+  
+  ATH_MSG_DEBUG( "initialize()" );
+  return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode InDet::BeamPipeBuilderCond::finalize()
+{
+    ATH_MSG_DEBUG( "finalize() successful" );
+    return StatusCode::SUCCESS;
+}
+
+
+/** LayerBuilder interface method - returning Barrel-like layers */
+//TODO: context is not used, beamPipe retrieved from manager. range is infinite
+std::pair<EventIDRange, const std::vector< const Trk::CylinderLayer* >*>  InDet::BeamPipeBuilderCond::cylindricalLayers(const EventContext&) const
+{
+  
+  std::vector<const Trk::CylinderLayer*>* beamPipe = new std::vector<const Trk::CylinderLayer*>;
+  
+  // the geometry
+  Amg::Transform3D* beamPipeTransform =  new Amg::Transform3D;
+  beamPipeTransform->setIdentity();
+
+  double beamPipeRadius = m_beamPipeRadius;
+  
+  if (m_beamPipeMgr){
+        // get the central top volume
+        PVConstLink beamPipeTopVolume =  m_beamPipeMgr->getTreeTop(0);
+        (*beamPipeTransform) = Amg::Translation3D(beamPipeTopVolume->getX().translation().x(),
+                                                  beamPipeTopVolume->getX().translation().y(),
+                                                  beamPipeTopVolume->getX().translation().z());
+        const GeoLogVol* beamPipeLogVolume = beamPipeTopVolume->getLogVol();
+        const GeoTube* beamPipeTube = 0;
+        if (beamPipeLogVolume){
+            // get the geoShape and translate
+            Trk::GeoShapeConverter geoShaper;
+            beamPipeTube = dynamic_cast<const GeoTube*>(beamPipeLogVolume->getShape());
+            if (beamPipeTube)
+                beamPipeRadius = beamPipeTube->getRMax()-m_beamPipeEnvelope;
+        }
+        ATH_MSG_VERBOSE("BeamPipe constructed from Database: translation (yes) - radius "<< ( beamPipeTube ? "(yes)" : "(no)") << " - r = " << beamPipeRadius );        
+  } else 
+      (*beamPipeTransform) = Amg::Translation3D(m_beamPipeOffsetX, m_beamPipeOffsetY, 0.);
+
+  ATH_MSG_VERBOSE("BeamPipe shift estimated as    : " 
+      <<  beamPipeTransform->translation().x() << ", "
+      <<  beamPipeTransform->translation().y() << ","
+      <<  beamPipeTransform->translation().y());
+  
+  Trk::CylinderBounds* beamPipeBounds    = new Trk::CylinderBounds(beamPipeRadius, m_beamPipeHalflength);
+  ATH_MSG_VERBOSE("BeamPipe bounds constructed as : " << (*beamPipeBounds) );
+
+  // the material
+  Trk::MaterialProperties beamPipeMaterial(m_beamPipeThickness,
+					   m_beamPipeX0,
+                                           m_beamPipeL0,
+					   m_beamPipeA,
+					   m_beamPipeZ,
+					   m_beamPipeRho);
+  
+  // binned layer material for the beam pipe possible
+  Trk::LayerMaterialProperties* beamPipeLayerMaterial=0;
+  if (  m_beamPipeBinsZ == 1) 
+     beamPipeLayerMaterial = new Trk::HomogeneousLayerMaterial(beamPipeMaterial, 1.0);
+  else { 
+      Trk::BinUtility layerBinUtility(m_beamPipeBinsZ, -m_beamPipeHalflength, m_beamPipeHalflength, Trk::open, Trk::binZ );
+      beamPipeLayerMaterial = new Trk::BinnedLayerMaterial(layerBinUtility);  
+  }
+  
+  ATH_MSG_DEBUG( "BeamPipe constructed with material-properties: " << beamPipeMaterial ); 
+                                                                                    
+  beamPipe->push_back(new Trk::CylinderLayer(beamPipeTransform,
+                                             beamPipeBounds,
+                                             *beamPipeLayerMaterial,
+                                             m_beamPipeThickness));
+  //delete beamPipeLayerMaterial; 
+  
+  //create dummy infinite range
+  EventIDRange range;
+  return std::make_pair(range,beamPipe);
+  
+} 
+      
+
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/RobustTrackingGeometryBuilderCond.cxx b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/RobustTrackingGeometryBuilderCond.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..42134152779423746004d878c7f3097182be7f83
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/RobustTrackingGeometryBuilderCond.cxx
@@ -0,0 +1,771 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+////////////////////////////////////////////////////////////////////
+// RobustTrackingGeometryBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+// InDet
+#include "InDetTrackingGeometry/RobustTrackingGeometryBuilderCond.h"
+// EnvelopeDefinitionService
+#include "SubDetectorEnvelopes/IEnvelopeDefSvc.h"
+// Trk interfaces
+#include "TrkDetDescrInterfaces/ILayerBuilderCond.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeCreator.h"
+#include "TrkDetDescrInterfaces/ILayerArrayCreator.h"
+// Trk Geometry stuff
+#include "TrkDetDescrUtils/BinnedArray.h"
+#include "TrkVolumes/VolumeBounds.h"
+#include "TrkVolumes/CylinderVolumeBounds.h"
+#include "TrkGeometry/TrackingVolume.h"
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkGeometry/MagneticFieldProperties.h"
+#include "TrkGeometry/Material.h"
+#include "TrkGeometry/Layer.h"
+#include "TrkGeometry/CylinderLayer.h"
+#include "TrkGeometry/DiscLayer.h"
+#include "TrkSurfaces/DiscBounds.h"
+//Gaudi
+#include "GaudiKernel/SystemOfUnits.h"
+#include "GaudiKernel/MsgStream.h"
+
+// constructor
+InDet::RobustTrackingGeometryBuilderCond::RobustTrackingGeometryBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  Trk::TrackingVolumeManipulator(),
+  m_beamPipeBuilder("InDet::BeamPipeBuilder/AtlasBeamPipeBuilder"),
+  m_trackingVolumeCreator("Trk::CylinderVolumeCreator/CylinderVolumeCreator"),  
+  m_layerArrayCreator("Trk::LayerArrayCreator/LayerArrayCreator"),
+  m_enclosingEnvelopeSvc("AtlasEnvelopeDefSvc", n),
+  m_layerEnvelopeCover(2*Gaudi::Units::mm),
+  m_buildBoundaryLayers(true),
+  m_replaceJointBoundaries(true),
+  m_materialProperties(0),
+  m_magneticFieldProperties(0),
+  m_outwardsFraction(0.75),
+  m_indexStaticLayers(true),
+  m_namespace("InDet::"),
+  m_exitVolume("InDet::Containers::InnerDetector")
+{
+  declareInterface<Trk::IGeometryBuilderCond>(this);  
+  // layer builders and their configurations
+  declareProperty("BeamPipeBuilder",                  m_beamPipeBuilder);
+  declareProperty("LayerBuilders",                    m_layerBuilders);
+  declareProperty("LayerBinningType",                 m_layerBinningType);
+  declareProperty("ColorCodes",                       m_colorCodesConfig);  
+  // envelope definition service
+  declareProperty("EnvelopeDefinitionSvc",            m_enclosingEnvelopeSvc );
+  declareProperty("VolumeEnclosureCylinderRadii",     m_enclosingCylinderRadius);
+  declareProperty("VolumeEnclosureDiscPositions",     m_enclosingDiscPositionZ);
+  // helper tools  
+  declareProperty("TrackingVolumeCreator",            m_trackingVolumeCreator);
+  declareProperty("LayerArrayCreator",                m_layerArrayCreator);  
+  // build the Boundary Layers
+  declareProperty("EnvelopeCover",                    m_layerEnvelopeCover);
+  declareProperty("BuildBoundaryLayers",              m_buildBoundaryLayers);
+  declareProperty("ReplaceAllJointBoundaries",        m_replaceJointBoundaries);
+  // outer envelope to
+  declareProperty("OutwardsFraction",                 m_outwardsFraction); 
+  // force robust layer indexing  
+  declareProperty("IndexStaticLayers",                m_indexStaticLayers);
+  // volume namespace & contaienr name
+  declareProperty("VolumeNamespace",                  m_namespace); 
+  declareProperty("ExitVolumeName",                   m_exitVolume);
+  declareProperty("isSLHC",                           m_isSLHC=false);
+}
+
+// destructor
+InDet::RobustTrackingGeometryBuilderCond::~RobustTrackingGeometryBuilderCond()
+{
+  delete m_materialProperties;
+  delete m_magneticFieldProperties;
+}
+
+// Athena standard methods
+// initialize
+StatusCode InDet::RobustTrackingGeometryBuilderCond::initialize()
+{
+  
+   // retrieve envelope definition service --------------------------------------------------
+   if ( m_enclosingEnvelopeSvc.retrieve().isFailure() ){
+     ATH_MSG_FATAL( "Could not retrieve EnvelopeDefinition service. Abort.");
+     return StatusCode::FAILURE;
+   }
+  
+   // Retrieve the beampipe builders --------------------------------------------------------  
+   if (m_beamPipeBuilder.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool(s) " << m_beamPipeBuilder );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_DEBUG( "Retrieved tool " << m_beamPipeBuilder );
+           
+   // Retrieve the layer builders -----------------------------------------------------------
+   if (m_layerBuilders.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool(s) " << m_layerBuilders );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_DEBUG( "Retrieved tool " << m_layerBuilders );
+
+   // Retrieve the tracking volume creator  -------------------------------------------------
+   if (m_trackingVolumeCreator.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeCreator );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_DEBUG( "Retrieved tool " << m_trackingVolumeCreator );
+      
+   // Retrieve the layer array creator  ----------------------------------------------------
+   if (m_layerArrayCreator.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_layerArrayCreator );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_INFO( "Retrieved tool " << m_layerArrayCreator );      
+
+    // Dummy MaterialProerties
+    m_materialProperties = new Trk::Material;
+
+    ATH_MSG_INFO( "initialize() succesful" );
+    
+  return StatusCode::SUCCESS;
+}
+
+
+std::pair<EventIDRange, const Trk::TrackingGeometry*> InDet::RobustTrackingGeometryBuilderCond::trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*>) const
+{
+   // only one assumption: 
+   // layer builders are ordered in increasing r
+   
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////    
+   // The Overall Geometry
+
+   Trk::TrackingGeometry* trackingGeometry = 0;   
+
+   // retrieve all the layers and sort them
+   unsigned int numLayBuilders = m_layerBuilders.size();
+
+   // central sector extend
+   double centralExtendZ  = 0.;
+   // endcap extends
+   double endcapMaxExtend = 0.;
+   double endcapMinExtend = 10e10;  
+   // and the overallExtend(s)
+   double overallExtendZ  = 0.;   
+   double overallRmin     = 10e10;
+   double overallRmax     = 0.;
+      
+   // cylinder layers at growing radii
+   std::vector< std::vector< const Trk::Layer*> > providedCylinderLayers;
+   providedCylinderLayers.reserve(numLayBuilders);
+   std::vector< double > cylinderInnerRadii(numLayBuilders,10e10);
+   std::vector< double > cylinderOuterRadii(numLayBuilders,0.);
+   std::vector< double > cylinderExtendsInZ(numLayBuilders,0.);
+   
+   // negative disc layers and positive disc layers
+   std::vector< std::vector< const Trk::Layer*> > providedDiscLayersNeg;   
+   std::vector< std::vector< const Trk::Layer*> > providedDiscLayersPos;
+   providedDiscLayersNeg.reserve(numLayBuilders);
+   providedDiscLayersPos.reserve(numLayBuilders);   
+   std::vector< double > discInnerRadii(numLayBuilders,10e10);
+   std::vector< double > discOuterRadii(numLayBuilders,0.);
+   std::vector< double > discMinZ(numLayBuilders,10e10);
+   std::vector< double > discMaxZ(numLayBuilders,0.);
+
+   //Start with a range covering 0 - inf, then narrow down
+   EventIDRange range;
+   
+   // (I) PARSE THE LAYERS FOR OVERALL DIMENSIONS -------------------------------------------------------------
+   ATH_MSG_DEBUG( "[ STEP 1 ] : Parse the provided layers for the dimensions." );
+   // fill the layers into the vectors
+   for ( unsigned int ilb = 0; ilb < m_layerBuilders.size(); ++ilb){
+       
+       Trk::BinningType binningType = (m_layerBinningType.size() == m_layerBuilders.size()) ? 
+                                      (Trk::BinningType)m_layerBinningType[ilb] : Trk::arbitrary; 
+       
+       // retrieve the cylinder and disc layers
+       ATH_MSG_DEBUG( "[ LayerBuilder : '" << m_layerBuilders[ilb]->identification() << "' ] being processed. " );
+       // (a) cylinder           
+       std::pair<EventIDRange, const std::vector<const Trk::CylinderLayer*>*> cylinderLayersPair = m_layerBuilders[ilb]->cylindricalLayers(ctx);
+       auto cylinderLayers = cylinderLayersPair.second;
+       // (a)
+       std::vector<const Trk::Layer*> cylinderVolumeLayers;     
+       if (cylinderLayers && cylinderLayers->size()){
+           range=EventIDRange::intersect(range,cylinderLayersPair.first);
+           // screen output
+           ATH_MSG_DEBUG(  "          Processing CylinderLayers : " );         
+           // the ones to be filled into the double-vector
+           for (auto& cylIter : *cylinderLayers){
+               // get the CylinderBounds
+               const Trk::CylinderBounds& cylBounds = (cylIter)->surfaceRepresentation().bounds();               
+               double currentR = cylBounds.r();
+               // rmin/rmax with thicknes in mind
+               double currentRmin = binningType!=Trk::biequidistant ? 
+                   currentR - 0.5*(cylIter)->thickness()-m_layerEnvelopeCover : currentR + 0.5*(cylIter)->thickness()-m_layerEnvelopeCover;               
+               double currentRmax = currentR + 0.5*(cylIter)->thickness() + m_layerEnvelopeCover;
+               // safe  
+               double extendZ  = cylIter->surfaceRepresentation().center().z() < 0. ?
+                                 fabs(cylIter->surfaceRepresentation().center().z() - cylBounds.halflengthZ())-m_layerEnvelopeCover:
+                                 cylIter->surfaceRepresentation().center().z() + cylBounds.halflengthZ() + m_layerEnvelopeCover;
+               // note the dimension
+               takeSmaller(cylinderInnerRadii[ilb],currentRmin); takeBigger(cylinderOuterRadii[ilb],currentRmax);
+               takeBigger(cylinderExtendsInZ[ilb],extendZ);
+               // push it into the vector
+               cylinderVolumeLayers.push_back(cylIter); 
+               // overall dimensions
+               takeSmaller(overallRmin,currentRmin); takeBigger(overallRmax,currentRmax);               
+               takeBigger(centralExtendZ, extendZ);
+               // in case no disc layers are provided
+               takeBigger(overallExtendZ,centralExtendZ);
+           }
+           // special treatment for bi-equidistant binning - a navigation layer will be added before and after the layers
+           if (binningType==Trk::biequidistant){
+               double rStep = (cylinderOuterRadii[ilb]-cylinderInnerRadii[ilb])/(cylinderLayers->size()-1);
+               ATH_MSG_VERBOSE( "           -> bi-equidistant : rStep estimated as " << rStep);
+               cylinderInnerRadii[ilb] -= rStep; cylinderOuterRadii[ilb] += rStep;
+               takeBigger(overallRmax,cylinderOuterRadii[ilb]);
+           }
+           ATH_MSG_VERBOSE(  "           -> yield (rMin/rMax/halflengthZ) = " 
+                 << cylinderInnerRadii[ilb] << " / " << cylinderOuterRadii[ilb] << " / " << cylinderExtendsInZ[ilb] ); 
+             
+       } else 
+         ATH_MSG_DEBUG(  "          No cylindrical layers processed." );        
+ 
+       providedCylinderLayers.push_back(cylinderVolumeLayers);       
+       // if after parsing of cylinder layers the maximal extend of cylinders is bigger than the minmal of discs
+       // reset the disc min extend (tiple will be swallowed)!
+       endcapMinExtend =  ( centralExtendZ > endcapMinExtend) ? 10e10 : endcapMinExtend; 
+       
+       // (b) discs       
+       std::pair<EventIDRange, const std::vector<const Trk::DiscLayer*>*> discLayersPair = m_layerBuilders[ilb]->discLayers(ctx);
+       auto discLayers = discLayersPair.second;
+       std::vector<const Trk::Layer*> discVolumeLayersNeg;
+       std::vector<const Trk::Layer*> discVolumeLayersPos;                        
+       if (discLayers && discLayers->size()){
+         range=EventIDRange::intersect(range,discLayersPair.first);
+         // screen output
+         ATH_MSG_DEBUG(  "          Processing DiscLayers : " );            
+         for (auto& discIter : *discLayers){
+               // get the DiscBounds
+               const Trk::DiscBounds* discBounds = dynamic_cast<const Trk::DiscBounds*>
+                                                               (&(discIter->surfaceRepresentation().bounds()));               
+               // get the current Z min/max
+               double discZ = discIter->surfaceRepresentation().center().z();
+               double currentZmin = binningType!=Trk::biequidistant ? (discZ-0.5*discIter->thickness()) : (discZ+0.5*discIter->thickness());
+               double currentZmax = discZ+0.5*discIter->thickness();
+               // force it to be symmetrized
+               if (currentZmax > 0.){
+                 takeSmaller(discMinZ[ilb],currentZmin); takeBigger(discMaxZ[ilb], currentZmax);
+                 // push it into the vector
+                 discVolumeLayersPos.push_back(discIter);                            
+               } else {
+                // in symmetrized setup only interested in total numbers
+                 double negMinZ = fabs(currentZmax);
+                 double negMaxZ = fabs(currentZmin);
+                 takeSmaller(discMinZ[ilb],negMinZ); takeBigger(discMaxZ[ilb],negMaxZ);
+                 // push it into the vector
+                 discVolumeLayersNeg.push_back(discIter);                            
+               }
+               
+               // radial dimensions               
+               if (discBounds){
+                 double currentRmin = discBounds->rMin();                 
+                 double currentRmax = discBounds->rMax();                   
+                  // note the dimension
+                 takeSmaller(discInnerRadii[ilb], currentRmin); takeBigger(discOuterRadii[ilb],currentRmax);
+                 // overall dimensions
+                 takeSmaller(overallRmin, currentRmin); takeBigger(overallRmax, currentRmax);
+               }
+              // min/max extend of the discs
+              takeSmaller(endcapMinExtend, discMinZ[ilb]); takeBigger(endcapMaxExtend, discMaxZ[ilb]);
+              takeBigger(overallExtendZ, endcapMaxExtend);
+         }       
+         // special treatment for bi-equidistant binning - a navigation layer will be added before and after the layers
+         if (binningType==Trk::biequidistant){
+             double zStep = (discMaxZ[ilb]-discMinZ[ilb])/(discLayers->size()/2-1);
+             discMinZ[ilb] -= zStep;
+             discMaxZ[ilb] += zStep;
+             takeBigger(overallExtendZ,discMaxZ[ilb]);
+         }
+         
+         ATH_MSG_VERBOSE(  "           -> yield (rMin/rMax/zMin/zMax) = "
+                  << discInnerRadii[ilb] << " / " << discOuterRadii[ilb] << " / " << discMinZ[ilb] << " / " << discMaxZ[ilb] ); 
+         
+       } else 
+         ATH_MSG_DEBUG(  "          No disk-like layers processed." );   
+ 
+
+       // fill the layers into the double-vector
+       providedDiscLayersNeg.push_back(discVolumeLayersNeg);
+       providedDiscLayersPos.push_back(discVolumeLayersPos);
+                
+       // memory cleanup
+       delete discLayers;
+       delete cylinderLayers;  
+       
+       if (msgLvl(MSG::VERBOSE)){
+         // summary after this step
+         ATH_MSG_VERBOSE( "[ Summary STEP 1  ---------------------------------------- ]  " );
+         ATH_MSG_VERBOSE( "                      overall minimum r : " << overallRmin      );       
+         ATH_MSG_VERBOSE( "                      overall maximum r : " << overallRmax      );       
+         ATH_MSG_VERBOSE( "                       overall z extend : " << overallExtendZ   );       
+         ATH_MSG_VERBOSE( "                central sector z extend : " << centralExtendZ   );
+         ATH_MSG_VERBOSE( "                maximum endcap z extend : " << endcapMaxExtend  );
+         ATH_MSG_VERBOSE( "                minimum endcap z extend : " << endcapMinExtend  );
+       }
+              
+   }
+  
+    
+   // (II) update the positions ------------------------------------------------------------
+   ATH_MSG_DEBUG( "[ STEP 2 ] : Closing the gaps from the parsed original dimensions." );   
+   // i.e. close the gap
+   double oldCeZ   = centralExtendZ;
+   centralExtendZ  = 0.5*(endcapMinExtend+oldCeZ);
+   endcapMinExtend = centralExtendZ;
+      
+   ATH_MSG_DEBUG( "             central sector extend in z recalculated to be " << centralExtendZ << " (was " << oldCeZ << ")" );
+ 
+   // (III) create the sub volumes -------------------------------------------------------------
+   ATH_MSG_DEBUG( "[ STEP 3 ] : Create the sub volumes." );   
+   
+   std::vector<const Trk::TrackingVolume*> centralSectorVolumes;
+   std::vector<const Trk::TrackingVolume*> negativeSectorVolumes;
+   std::vector<const Trk::TrackingVolume*> positiveSectorVolumes;
+   
+   // --------------------------------------------------------------------------------------------------
+   // first the beampipe volume
+   Trk::TrackingVolume* beamPipeVolume = 0;
+   // the Volume Bounds
+   Trk::CylinderVolumeBounds* beamPipeBounds = new Trk::CylinderVolumeBounds(overallRmin,overallExtendZ); 
+   // BinnedArray needed
+   Trk::BinnedArray<Trk::Layer>* beamPipeLayerArray = 0;
+   std::pair<EventIDRange,const std::vector<const Trk::CylinderLayer*>*> beamPipeVecPair = m_beamPipeBuilder->cylindricalLayers(ctx);
+   auto beamPipeVec = beamPipeVecPair.second;
+   if (beamPipeVec->size()){
+       range=EventIDRange::intersect(range,beamPipeVecPair.first);
+       beamPipeLayerArray = m_layerArrayCreator->cylinderLayerArray(*beamPipeVec,0.,beamPipeBounds->outerRadius(),Trk::arbitrary);
+   }
+   delete beamPipeVec;
+   // create the TrackingVolume
+   beamPipeVolume = new Trk::TrackingVolume(0,
+                                            beamPipeBounds,
+                                            *m_materialProperties,
+                                            beamPipeLayerArray,
+                                            0,
+                                            "InDet::BeamPipe");
+    // set the color code
+    beamPipeVolume->registerColorCode(46);
+   
+   // beampipe + detectors / prepared                                                                   
+   std::vector<const Trk::TrackingVolume*> idVolumes;
+   idVolumes.push_back(beamPipeVolume);     
+   
+   // --------------------------------------------------------------------------------------------------   
+   double lastCentralOuterR    = beamPipeBounds->outerRadius();
+   double lastNegEndcapOuterR  = beamPipeBounds->outerRadius();
+   double lastPosEndcapOuterR  = beamPipeBounds->outerRadius();
+   
+   // loop over double-vectors, access the dimensions from the parsing
+   auto pclIter  = providedCylinderLayers.begin();
+   auto pclEnd   = providedCylinderLayers.end();   
+   auto pndlIter = providedDiscLayersNeg.begin();
+   auto pndlEnd  = providedDiscLayersNeg.end();
+   auto ppdlIter = providedDiscLayersPos.begin();
+   auto ppdlEnd  = providedDiscLayersPos.end();
+   
+   // the number of layer builders
+   unsigned int numLayerBuilders = m_layerBuilders.size();
+   
+   // loop over the prepared volumes
+   for ( unsigned int ilb=0 ; pclIter != pclEnd && pndlIter != pndlEnd && ppdlIter != ppdlEnd; 
+        ++pclIter, ++pndlIter, ++ppdlIter, ++ilb)
+   {          
+       // color code configuration (from jobOptions/declareProperty interface)
+       int colorCode = (m_colorCodesConfig.size() == numLayerBuilders) ? m_colorCodesConfig[ilb] : 21;
+       
+       Trk::BinningType binningType = (m_layerBinningType.size() == numLayerBuilders) ? 
+                                      (Trk::BinningType)m_layerBinningType[ilb] : Trk::arbitrary; 
+       
+       // volume name base
+       std::string baseName = m_layerBuilders[ilb]->identification();
+       ATH_MSG_DEBUG( "[ Volume Creation : '" << baseName << "'] carried out." ); 
+       ATH_MSG_DEBUG( "       + color code                     : " << colorCode        );
+                  
+       // maxmmal z extend for volume set & endcap inner z
+       double currentSetExtendZ    =  ( (*pndlIter).size() || (*ppdlIter).size() ) ? discMaxZ[ilb] : cylinderExtendsInZ[ilb];
+       double currentEndcapInnerZ  =  ( (*pndlIter).size() || (*ppdlIter).size() ) ? discMinZ[ilb] : currentSetExtendZ;
+
+       // radii for the sectors 
+       double currentCentralOuterR  = 0.;
+       double currentEndcapOuterR   = 0.;
+       
+       if (m_isSLHC){
+	       double NextInnerRadii = ((ilb!=cylinderOuterRadii.size()-1) && cylinderInnerRadii[ilb+1]<discInnerRadii[ilb+1]) ? cylinderInnerRadii[ilb+1] : discInnerRadii[ilb+1]; 
+	       currentCentralOuterR = (ilb!=cylinderOuterRadii.size()-1) ? 0.5*(NextInnerRadii+cylinderOuterRadii[ilb]) : overallRmax;
+	       currentEndcapOuterR = (ilb!=discOuterRadii.size()-1) ? 0.5*(NextInnerRadii+discOuterRadii[ilb]) : overallRmax;
+       } else{
+           // we build from inside to outside, don't take middle position, but tend towards outer extend 
+	       currentCentralOuterR = (ilb!=cylinderOuterRadii.size()-1) ? (m_outwardsFraction*cylinderInnerRadii[ilb+1]+(1.-m_outwardsFraction)*cylinderOuterRadii[ilb]) : overallRmax;
+           currentEndcapOuterR = (ilb!=discOuterRadii.size()-1) ? (m_outwardsFraction*discInnerRadii[ilb+1]+(1.-m_outwardsFraction)*discOuterRadii[ilb]) : overallRmax;
+	            
+       }
+
+       ATH_MSG_VERBOSE( "       + checking the sector boundaries : " );        
+       ATH_MSG_VERBOSE( "         central sector ext. z (boundary)  = "  << currentSetExtendZ
+           << " ("  << centralExtendZ << ")" );        
+       ATH_MSG_VERBOSE( "       + current volume radii rMax (c/d)   = "  << currentCentralOuterR       
+           << " / " << currentEndcapOuterR );
+       // estimate the case
+       // cases are :
+       enum PackCase { contained, radial, central, split };  
+       //   0 - both cylinders and disc are contained in the central sector
+       //   1 - radial packing, volumes can't be put in in central / ec sectors
+       //   2 - only central sector exists
+       //   3 - standard ecn / central / ecp sectors split
+       bool endcapsExist =  (*pndlIter).size()  && (*ppdlIter).size() ;
+       // case flag set 
+       PackCase caseFlag = (currentSetExtendZ < centralExtendZ && endcapsExist) ? contained : split;       
+       if (currentSetExtendZ > centralExtendZ && currentEndcapInnerZ < centralExtendZ && endcapsExist) caseFlag = radial;
+       if (!endcapsExist) caseFlag = central;
+       
+       // case 0 and 1 can be handled together : 
+       if ( caseFlag == contained || caseFlag == radial ){
+          // create the volume sizes for the compact volume
+          double currentCentralExtendZ = 0.5*(cylinderExtendsInZ[ilb]+discMinZ[ilb]);
+          double currentExtendZ = contained ? centralExtendZ : overallExtendZ;
+          // in the radial wrapping case : take the smaller radius, assumes that packing is possible               
+          double currentOuterR = currentCentralOuterR < currentEndcapOuterR ? currentCentralOuterR : currentEndcapOuterR;
+          // create the tiple container
+          const Trk::TrackingVolume* tripleContainer = packVolumeTriple((*pndlIter),
+                                                                        (*pclIter),
+                                                                        (*ppdlIter),
+                                                                        lastCentralOuterR, currentOuterR,
+                                                                        currentExtendZ,currentCentralExtendZ,
+                                                                        baseName,
+                                                                        colorCode,
+                                                                        binningType);
+
+
+          // cache the last central / ec outer radius       
+          lastCentralOuterR = currentOuterR;
+          if (contained){                     
+              ATH_MSG_VERBOSE( "       + case I   : provided cylinder and disc layers are entirely contained in central sector." );                                                          
+              // and push the centralSectorVolumes
+              centralSectorVolumes.push_back(tripleContainer);
+           } else {
+              ATH_MSG_VERBOSE( "       + case II  : split into negative - central - positive sectors doesn't work, radial wrapping" ); 
+              // cache the laster endcap radii  (need to be equal since this is radially wrapped)
+              lastNegEndcapOuterR = currentOuterR;
+              lastPosEndcapOuterR = currentOuterR;
+              // the triple goes into the radial packing volumes
+              idVolumes.push_back(tripleContainer);     
+           }
+       // case 2 and 3        
+       } else {       
+          // output for case 3 and 4          
+          if (!endcapsExist)   
+            ATH_MSG_VERBOSE( "       + case III : only central sector." );        
+          else 
+            ATH_MSG_VERBOSE( "       + case IV  : split into negative - central - positive sectors." ); 
+          // build the name
+          std::string volumeBase = m_namespace+"Detectors::"+baseName;          
+          // cylinder layers exist -------------------------------
+          if ((*pclIter).size()){
+            
+            ATH_MSG_VERBOSE( "       -> central sector is being build." ); 
+            // create the cylinder barrel 
+            const Trk::TrackingVolume* barrel    = 
+                m_trackingVolumeCreator->createTrackingVolume((*pclIter),
+                                                              *m_materialProperties,
+                                                              lastCentralOuterR,currentCentralOuterR,
+                                                              -centralExtendZ,centralExtendZ,
+                                                              volumeBase+"::Barrel",
+                                                              binningType);
+            // register the color code
+            barrel->registerColorCode(colorCode);                
+            // cache the last ones
+            lastCentralOuterR = currentCentralOuterR;
+            // and push the centralSectorVolumes
+            centralSectorVolumes.push_back(barrel);          
+          } 
+
+          // negative disc layers exist ------------------------------
+          if ((*pndlIter).size()){
+          
+            ATH_MSG_VERBOSE( "       -> negative endcap is being build." );       
+            // create the cylinder barrel 
+            const Trk::TrackingVolume* negEndcap    = 
+                m_trackingVolumeCreator->createTrackingVolume((*pndlIter),
+                                                              *m_materialProperties,
+                                                              lastNegEndcapOuterR,currentEndcapOuterR,
+                                                              -overallExtendZ, -endcapMinExtend,
+                                                              volumeBase+"::NegativeEndcap",
+                                                              binningType);                
+            // register the color code
+            negEndcap->registerColorCode(colorCode);                
+            // cache the last ones
+            lastNegEndcapOuterR = currentEndcapOuterR;
+            // and push the negativeSectorVolumes
+            negativeSectorVolumes.push_back(negEndcap);                    
+          }
+          // positive disc layers exist --------------------------------
+          if ((*ppdlIter).size()){
+          
+            ATH_MSG_VERBOSE( "       -> positive endcap is being build." );          
+            // create the cylinder barrel 
+            const Trk::TrackingVolume* posEndcap    = 
+                m_trackingVolumeCreator->createTrackingVolume((*ppdlIter),
+                                                              *m_materialProperties,
+                                                              lastPosEndcapOuterR,currentEndcapOuterR,
+                                                              endcapMinExtend,overallExtendZ,
+                                                              volumeBase+"::PositiveEndcap",
+                                                              binningType);                
+            // register the color code
+            posEndcap->registerColorCode(colorCode);                
+            // cache the last ones
+            lastPosEndcapOuterR = currentEndcapOuterR;
+            // and push the positiveSectorVolumes
+            positiveSectorVolumes.push_back(posEndcap);                    
+          }                      
+       }   
+   }      
+   
+   // (IV) create the container ---------------------------------------------------------
+   ATH_MSG_DEBUG( "[ STEP 4 ] : Create the container volume" );   
+   
+   bool enclose = (!m_enclosingEnvelopeSvc.empty());
+ 
+   const Trk::TrackingVolume* detectorContainer = packVolumeTriple(negativeSectorVolumes,
+                                                                   centralSectorVolumes,
+                                                                   positiveSectorVolumes,
+                                                                   "Container");
+                                                                   
+   // get the dimensions from the envelope service 
+   RZPairVector& envelopeDefs = m_enclosingEnvelopeSvc->getInDetRZValues();
+   ATH_MSG_VERBOSE("       -> retrieved Inner Detector envelope definitions at size " << envelopeDefs.size());
+   double enclosingVolumeRadius = envelopeDefs[1].first;
+   double enclosingVolumeHalfZ  = fabs(envelopeDefs[1].second);
+                                                                   
+   // central enclosure volume
+   const Trk::TrackingVolume* centralEnclosure =  enclose ?
+                           m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                           overallRmax, enclosingVolumeRadius,
+                                                                           -overallExtendZ, overallExtendZ,
+                                                                           1, true,
+                                                                           m_namespace+"Gaps::CentralEnclosure") : 0;
+   
+   // push the detector container into the ID volumes                                                              
+   idVolumes.push_back(detectorContainer);
+   if (centralEnclosure) idVolumes.push_back(centralEnclosure);
+   
+   std::string volumeName = enclose ? "InDet::Detectors::BpPixSctTrt" : m_exitVolume;
+
+   ATH_MSG_VERBOSE("       -> inserting beam pipe into detectors." ); 
+
+   const Trk::TrackingVolume* detectorWithBp = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(idVolumes,
+                                                                *m_materialProperties,
+                                                                volumeName,
+                                                                m_buildBoundaryLayers,
+                                                                m_replaceJointBoundaries);
+  
+   // if packing is needed ------------------------------------------------------------------
+   const Trk::TrackingVolume* highestIdVolume = 0;
+   if (enclose){
+    
+     // negative positions
+     std::vector<double> negDiscPositionZ(m_enclosingDiscPositionZ);
+     for (std::vector<double>::iterator posIter = negDiscPositionZ.begin();
+         posIter != negDiscPositionZ.end(); ++posIter) (*posIter) *= -1;
+        
+     
+     const Trk::TrackingVolume* negativeEnclosure =  negDiscPositionZ.size() ?
+                           m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                           0., enclosingVolumeRadius,
+                                                                           -enclosingVolumeHalfZ, -overallExtendZ,
+                                                                           negDiscPositionZ, false,
+                                                                           m_namespace+"Gaps::NegativeEnclosure") :      
+                           m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                            0., enclosingVolumeRadius,
+                                                                            -enclosingVolumeHalfZ, -overallExtendZ,
+                                                                            1, false,
+                                                                            m_namespace+"Gaps::NegativeEnclosure");
+  
+     const Trk::TrackingVolume* positiveEnclosure = m_enclosingDiscPositionZ.size() ? 
+                           m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                           0., enclosingVolumeRadius,
+                                                                           overallExtendZ, enclosingVolumeHalfZ,
+                                                                           m_enclosingDiscPositionZ, false,
+                                                                           m_namespace+"Gaps::PositiveEnclosure") :
+                           m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                            0., enclosingVolumeRadius,
+                                                                            overallExtendZ,enclosingVolumeHalfZ,
+                                                                            1, false,
+                                                                            m_namespace+"Gaps::PositiveEnclosure");
+  
+      std::vector<const Trk::TrackingVolume*> enclosedVolumes;
+        enclosedVolumes.push_back(negativeEnclosure);
+        enclosedVolumes.push_back(detectorWithBp);
+        enclosedVolumes.push_back(positiveEnclosure);
+   
+     const Trk::TrackingVolume* enclosedDetector = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(enclosedVolumes,
+                                                                *m_materialProperties,
+                                                                 m_exitVolume,
+                                                                 m_buildBoundaryLayers,
+                                                                 m_replaceJointBoundaries);
+                                                                          
+      highestIdVolume = enclosedDetector;                                                                       
+    } else  
+      highestIdVolume = detectorWithBp;
+      
+  // (V) create the TrackingGeometry ------------------------------------------------------  
+  trackingGeometry = new Trk::TrackingGeometry(highestIdVolume);
+ 
+ if (m_indexStaticLayers) {
+      ATH_MSG_VERBOSE("Re-index the static layers ...");
+      // ST temporary hack till layer numbering resolved
+      //trackingGeometry->indexStaticLayers(geometrySignature());   
+      trackingGeometry->indexStaticLayers(Trk::Global);   
+   }
+
+
+   return std::make_pair(range, trackingGeometry);
+}
+
+// finalize
+StatusCode InDet::RobustTrackingGeometryBuilderCond::finalize()
+{
+    ATH_MSG_INFO( "finalize() successful" );
+    return StatusCode::SUCCESS;
+}
+
+
+const Trk::TrackingVolume* InDet::RobustTrackingGeometryBuilderCond::packVolumeTriple(
+                                     const std::vector<const Trk::Layer*>& negLayers,
+                                     const std::vector<const Trk::Layer*>& centralLayers,
+                                     const std::vector<const Trk::Layer*>& posLayers,
+                                     double rMin, double rMax,
+                                     double zMax, double zPosCentral,
+                                     const std::string& baseName,
+                                     int colorCode,
+                                     Trk::BinningType bintyp) const
+{
+
+
+  ATH_MSG_VERBOSE( '\t' << '\t'<< "Pack provided Layers from '" << baseName << "' triple into a container volume. " );
+  
+  // create the strings
+  std::string volumeBase = m_namespace+"Detectors::"+baseName;
+  
+  const Trk::TrackingVolume* negativeVolume = 
+       m_trackingVolumeCreator->createTrackingVolume(negLayers,
+                                                     *m_materialProperties,
+                                                     rMin,rMax,
+                                                     -zMax,-zPosCentral,
+                                                     volumeBase+"::NegativeEndcap",
+                                                     bintyp);
+                                                                
+  const Trk::TrackingVolume* centralVolume = 
+         m_trackingVolumeCreator->createTrackingVolume(centralLayers,
+                                                       *m_materialProperties,
+                                                       rMin,rMax,
+                                                       -zPosCentral,zPosCentral,
+                                                       volumeBase+"::Barrel",
+                                                       bintyp);
+                                                       
+   const Trk::TrackingVolume* positiveVolume = 
+         m_trackingVolumeCreator->createTrackingVolume(posLayers,
+                                                       *m_materialProperties,
+                                                       rMin,rMax,
+                                                       zPosCentral,zMax,
+                                                       volumeBase+"::PositiveEndcap",
+                                                       bintyp);
+   
+   // the base volumes have been created
+   ATH_MSG_VERBOSE('\t' << '\t'<< "Volumes have been created, now pack them into a triple.");
+   // registerColorCode                                                   
+   negativeVolume->registerColorCode(colorCode);   
+   centralVolume->registerColorCode(colorCode);
+   positiveVolume->registerColorCode(colorCode);
+                                                         
+   // pack them together
+   std::vector<const Trk::TrackingVolume*> tripleVolumes;
+   tripleVolumes.push_back(negativeVolume);
+   tripleVolumes.push_back(centralVolume);
+   tripleVolumes.push_back(positiveVolume);
+   
+   // create the tiple container
+   const Trk::TrackingVolume* tripleContainer = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(tripleVolumes,
+                                                                *m_materialProperties,
+                                                                volumeBase,
+                                                                m_buildBoundaryLayers,
+                                                                m_replaceJointBoundaries);
+                                                                
+   ATH_MSG_VERBOSE( '\t' << '\t'<< "Created container volume with bounds: " << tripleContainer->volumeBounds() );
+                                                                
+   return tripleContainer;
+}
+
+const Trk::TrackingVolume* InDet::RobustTrackingGeometryBuilderCond::packVolumeTriple(
+                                     const std::vector<const Trk::TrackingVolume*>& negVolumes,
+                                     const std::vector<const Trk::TrackingVolume*>& centralVolumes,
+                                     const std::vector<const Trk::TrackingVolume*>& posVolumes,
+                                     const std::string& baseName) const
+{
+  ATH_MSG_VERBOSE( '\t' << '\t'<< "Pack provided Volumes from '" << baseName << "' triple into a container volume. " );
+
+  unsigned int negVolSize = negVolumes.size();
+  unsigned int cenVolSize = centralVolumes.size();
+  unsigned int posVolSize = posVolumes.size();
+  
+  
+  
+    // create the strings
+  std::string volumeBase = m_namespace+"Containers::"+baseName;
+  
+  const Trk::TrackingVolume* negativeVolume = (negVolSize > 1) ?
+       m_trackingVolumeCreator->createContainerTrackingVolume(negVolumes,
+                                                       *m_materialProperties,
+                                                       volumeBase+"::NegativeSector",
+                                                       m_buildBoundaryLayers,
+                                                       m_replaceJointBoundaries) : 
+                                             (negVolSize ? negVolumes[0] : 0);
+  const Trk::TrackingVolume* centralVolume = (cenVolSize > 1) ?
+         m_trackingVolumeCreator->createContainerTrackingVolume(centralVolumes,
+                                                       *m_materialProperties,
+                                                       volumeBase+"::CentralSector",
+                                                       m_buildBoundaryLayers,
+                                                       m_replaceJointBoundaries) :
+                                              (cenVolSize ? centralVolumes[0] : 0) ;
+                                              
+   const Trk::TrackingVolume* positiveVolume = ( posVolSize > 1) ?
+         m_trackingVolumeCreator->createContainerTrackingVolume(posVolumes,
+                                                       *m_materialProperties,
+                                                       volumeBase+"::PositiveSector",
+                                                       m_buildBoundaryLayers,
+                                                       m_replaceJointBoundaries) : 
+                                               (posVolSize ? posVolumes[0] : 0);
+   
+   if (!negativeVolume && !positiveVolume){
+       ATH_MSG_DEBUG( "No negative/positive sector given - no packing needed, returning central container!" );
+       return centralVolume;
+   }
+   // pack them together
+   std::vector<const Trk::TrackingVolume*> tripleVolumes;
+   if (negativeVolume) tripleVolumes.push_back(negativeVolume);
+   if (centralVolume) tripleVolumes.push_back(centralVolume);
+   if (positiveVolume) tripleVolumes.push_back(positiveVolume);
+   // create the tiple container
+   const Trk::TrackingVolume* tripleContainer = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(tripleVolumes,
+                                                                *m_materialProperties,
+                                                                volumeBase,
+                                                                m_buildBoundaryLayers,
+                                                                m_replaceJointBoundaries);
+   return tripleContainer;
+}
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/SiLayerBuilderCond.cxx b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/SiLayerBuilderCond.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..6aadedafbdf1e905eb55f76c8c0a7e1c017560cb
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/SiLayerBuilderCond.cxx
@@ -0,0 +1,1178 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// SiLayerBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#include "InDetTrackingGeometry/SiLayerBuilderCond.h"
+#include "InDetTrackingGeometry/PixelOverlapDescriptor.h"
+#include "InDetTrackingGeometry/SCT_OverlapDescriptor.h"
+#include "InDetTrackingGeometry/DiscOverlapDescriptor.h"
+//InDet include
+#include "PixelReadoutGeometry/PixelDetectorManager.h"
+#include "SCT_ReadoutGeometry/SCT_DetectorManager.h"
+#include "InDetReadoutGeometry/SiDetectorElement.h"
+#include "InDetReadoutGeometry/SiDetectorElementCollection.h"
+#include "InDetIdentifier/SCT_ID.h" 
+#include "InDetIdentifier/PixelID.h" 
+// Trk inlcude
+#include "TrkDetDescrUtils/BinUtility.h"
+#include "TrkDetDescrUtils/BinnedArray1D1D.h"
+#include "TrkDetDescrUtils/BinnedArray2D.h"
+#include "TrkDetDescrUtils/BinnedArray1D.h"
+#include "TrkDetDescrUtils/GeometryStatics.h"
+#include "TrkGeometry/LayerMaterialProperties.h"
+#include "TrkGeometry/BinnedLayerMaterial.h"
+#include "TrkGeometry/HomogeneousLayerMaterial.h"
+#include "TrkGeometry/MaterialProperties.h"
+#include "TrkGeometry/CylinderLayer.h"
+#include "TrkGeometry/DiscLayer.h"
+#include "TrkGeometry/PlaneLayer.h"
+#include "TrkSurfaces/Surface.h"
+#include "TrkSurfaces/CylinderBounds.h"
+#include "TrkSurfaces/DiscBounds.h"
+// GeoModel
+#include "GeoModelKernel/GeoLogVol.h"
+#include "GeoModelKernel/GeoVFullPhysVol.h"
+#include "GeoModelKernel/GeoMaterial.h"
+// Gaudi
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/SystemOfUnits.h"
+#include "GaudiKernel/SmartDataPtr.h"
+// STL
+#include <map>
+
+std::vector<const Trk::CylinderLayer*> InDet::SiLayerBuilderCond::s_splitCylinderLayers;
+std::vector<const Trk::DiscLayer*>     InDet::SiLayerBuilderCond::s_splitDiscLayers;
+EventIDRange                           InDet::SiLayerBuilderCond::s_splitIOVRange;
+double InDet::SiLayerBuilderCond::s_splitRadius = 0.;
+    
+// constructor
+InDet::SiLayerBuilderCond::SiLayerBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  m_pixelCase(true),
+  m_siMgr(0),
+  m_siMgrLocation("Pixel"),
+  m_pixIdHelper(0),
+  m_sctIdHelper(0),
+  m_setLayerAssociation(true),
+  m_barrelLayerBinsZ(100),
+  m_barrelLayerBinsPhi(1),
+  m_barrelEnvelope(0.1),
+  m_barrelEdbTolerance(0.05),
+  m_endcapRingLayout(false),
+  m_endcapLayerBinsR(100),
+  m_endcapLayerBinsPhi(1),
+  m_endcapEnvelope(0.1),
+  m_endcapComplexRingBinning(true),
+  m_identification("Pixel"),
+  m_splitMode(0),
+  m_splitTolerance(10.),   
+  m_runGeometryValidation(true)
+{
+  declareInterface<Trk::ILayerBuilderCond>(this);
+  // general steering
+  declareProperty("PixelCase"                        , m_pixelCase);
+  declareProperty("SiDetManagerLocation"             , m_siMgrLocation);
+  declareProperty("SetLayerAssociation"              , m_setLayerAssociation);
+  // For the Active Barrel Material
+  declareProperty("BarrelAdditionalLayerRadii"       , m_barrelAdditionalLayerR);
+  declareProperty("BarrelAdditionalLayerType"        , m_barrelAdditionalLayerType);
+  declareProperty("BarrelLayerBinsZ"                 , m_barrelLayerBinsZ);
+  declareProperty("BarrelLayerBinsPhi"               , m_barrelLayerBinsPhi);
+  declareProperty("BarrelEnvelope"                   , m_barrelEnvelope);
+  declareProperty("BarrelEdbTolerance"               , m_barrelEdbTolerance);
+  // For the Active Endcap Material
+  declareProperty("EndcapRingLayout"                 , m_endcapRingLayout);
+  declareProperty("EndcapAdditionalLayerPositionsZ"  , m_endcapAdditionalLayerPosZ);
+  declareProperty("EndcapAdditionalLayerType"        , m_endcapAdditionalLayerType);
+  declareProperty("EndcapLayerBinsR"                 , m_endcapLayerBinsR);
+  declareProperty("EndcapLayerBinsPhi"               , m_endcapLayerBinsPhi);
+  declareProperty("EndcapEnvelope"                   , m_endcapEnvelope);
+  declareProperty("EndcapComplexRingBinning"         , m_endcapComplexRingBinning);
+  // identification
+  declareProperty("Identification"                   , m_identification);
+  // split mode for multiple pixel systems (upgrade)
+  declareProperty("SplitMode"                        , m_splitMode);
+  declareProperty("SplitTolerance"                   , m_splitTolerance);      
+  // Validation
+  declareProperty("GeometryValidation"               , m_runGeometryValidation);
+}
+
+// destructor
+InDet::SiLayerBuilderCond::~SiLayerBuilderCond()
+{}
+
+// Athena standard methods
+// initialize
+StatusCode InDet::SiLayerBuilderCond::initialize()
+{
+
+    ATH_MSG_DEBUG( "initialize()" );
+    // get Pixel Detector Description Manager
+    if (m_pixelCase){
+        const InDetDD::PixelDetectorManager* pixMgr = 0;
+        if ((detStore()->retrieve(pixMgr, m_siMgrLocation)).isFailure()) {
+            ATH_MSG_ERROR( "Could not get PixelDetectorManager '" << m_siMgrLocation << "', no layers for Pixel Detector will be built. " );
+        } else {
+            ATH_MSG_VERBOSE( "PixelDetectorManager retrieved with key '" << m_siMgrLocation <<"'." );
+            // assign the detector manager to the silicon manager
+            m_siMgr = pixMgr;
+            if (detStore()->retrieve(m_pixIdHelper, "PixelID").isFailure())
+                ATH_MSG_ERROR("Could not get Pixel ID helper");
+        }
+        ATH_CHECK(m_PixelReadKey.initialize());
+    } else {
+        const InDetDD::SCT_DetectorManager* sctMgr = 0;
+        if ((detStore()->retrieve(sctMgr, m_siMgrLocation)).isFailure()) {
+            ATH_MSG_ERROR( "Could not get SCT_DetectorManager '" << m_siMgrLocation << "', no layers for SCT Detector will be built. " );
+        } else {
+            ATH_MSG_VERBOSE( "SCT_DetectorManager retrieved with key '" << m_siMgrLocation <<"'." );
+            // assign the detector manager to the silicon manager
+            m_siMgr = sctMgr;
+            if (detStore()->retrieve(m_sctIdHelper, "SCT_ID").isFailure())
+                ATH_MSG_ERROR("Could not get SCT ID helper");
+        }
+        
+        ATH_CHECK(m_SCT_ReadKey.initialize());
+        ATH_CHECK(m_PixelReadKey.initialize());
+
+    }
+    return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode InDet::SiLayerBuilderCond::finalize()
+{
+    ATH_MSG_DEBUG( "finalize() successful" );
+    return StatusCode::SUCCESS;
+}
+
+
+/** LayerBuilder interface method - returning Barrel-like layers */
+std::pair<EventIDRange, const std::vector<const Trk::CylinderLayer*>*> InDet::SiLayerBuilderCond::cylindricalLayers(const EventContext& ctx) const
+{
+
+  // split mode 2nd part return the already built layers 
+  if (m_splitMode && s_splitCylinderLayers.size() ){
+      ATH_MSG_DEBUG( "[ Split mode/ Part 2 ] Returning " << s_splitCylinderLayers.size() << " cylinder layers." );
+      ATH_MSG_VERBOSE( "                       Split radius was set to " << s_splitRadius );
+      std::vector<const Trk::CylinderLayer*>* splitCylinderLayers = dressCylinderLayers(s_splitCylinderLayers);
+      s_splitCylinderLayers.clear();
+      return std::make_pair(s_splitIOVRange, splitCylinderLayers); 
+  } else if (m_splitMode){
+      ATH_MSG_DEBUG( "[ Split mode/ Part 1 ] Initializing." );
+      s_splitRadius = m_splitMode < 0 ? 10e10 : 0.;
+  }
+  
+
+  // sanity check for ID Helper
+  if (!m_pixIdHelper && !m_sctIdHelper){
+    ATH_MSG_ERROR("Neither Pixel nor SCT Detector Manager or ID Helper could be retrieved - giving up.");
+    //create dummy infinite range
+    EventIDRange range;
+    return std::pair<EventIDRange, const std::vector<const Trk::CylinderLayer*>*>(range,nullptr);
+  }
+
+  // take the numerlogoy
+  const InDetDD::SiNumerology& siNumerology = m_siMgr->numerology();     
+    
+  // pre-set parameters for the run
+  size_t barrelLayers = 0;
+  // save way to estimate the number of barrel layers : they can be deactivated hence the useLayer(i) check
+  for (int i = 0; i < siNumerology.numLayers(); i++)
+       if (siNumerology.useLayer(i)) barrelLayers++;
+  
+
+  // screen output
+  ATH_MSG_DEBUG( "Configured to build " << barrelLayers << " (active) barrel layers (out of " << siNumerology.numLayers() << " )" );
+  if (m_barrelAdditionalLayerR.size())
+      ATH_MSG_DEBUG( "Additionally " <<  m_barrelAdditionalLayerR.size() << " material layers will be built.");  
+      
+  // split mode for SLHC setup
+  if (m_splitMode)
+      ATH_MSG_DEBUG( "[ Split mode ] Some layers may be cached." );
+        
+  // for barrels (the statistics for ordering the modules)
+  std::vector<double>                                               layerRadius(barrelLayers,0.);
+  std::vector<double>                                               layerRmin(barrelLayers,10e10);
+  std::vector<double>                                               layerRmax(barrelLayers,0.);
+  std::vector<double>                                               layerThickness(barrelLayers,0.);
+  std::vector<double>                                               layerMinZ(barrelLayers,0.);
+  std::vector<double>                                               layerMaxZ(barrelLayers,0.);
+  std::vector<double>                                               layerHalfLength(barrelLayers,0.);
+  std::vector<double>                                               layerMinPhi(barrelLayers,0.);
+  std::vector<double>                                               layerMaxPhi(barrelLayers,0.);
+  std::vector<size_t>                                               layerPhiSectors(barrelLayers,0);
+  std::vector<size_t>                                               layerZsectors(barrelLayers,0);
+  std::vector< std::vector<float> >                                 layerZboundaries(barrelLayers, std::vector<float>());
+  std::vector< std::vector< Trk::SurfaceOrderPosition > >           layerSurfaces(barrelLayers, std::vector< Trk::SurfaceOrderPosition >());
+ 
+  // cache needed
+  double minHalflengthZ         = 10e10;
+  double maxHalflengthZ         = 0;
+  size_t sumCheckBarrelModules  = 0;
+  size_t barrelModules          = 0;
+ 
+  // [-A-] ------------------------ LOOP over Detector Elements of sensitive layers -----------------------------------
+  // iterate over the detector elements for layer dimension, etc.   
+  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection>* readHandle;
+  if(m_pixelCase){
+    readHandle = new SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> (m_PixelReadKey, ctx);
+  }else{
+    readHandle = new SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> (m_SCT_ReadKey, ctx);
+  }
+  const InDetDD::SiDetectorElementCollection* readCdo{**readHandle};
+  InDetDD::SiDetectorElementCollection::const_iterator sidetIter = readCdo->begin();    
+  for (; sidetIter != readCdo->end(); sidetIter++){
+     // Barrel check
+     if ((*sidetIter) && (*sidetIter)->isBarrel()){
+       // unit test
+       ++barrelModules;
+       // get the identifier
+       Identifier    currentId((*sidetIter)->identify());
+       int currentlayer = m_pixIdHelper ? m_pixIdHelper->layer_disk(currentId) : m_sctIdHelper->layer_disk(currentId);
+       //skip the layer if it is chosen to be switched off
+       if ( !m_siMgr->numerology().useLayer(currentlayer) ) continue;
+       // (A) Determination of phi / eta sectors  ---------------------------------------------------
+       // only do the exercise if it hasn't been done already 
+       if (layerPhiSectors[currentlayer] == 0){                        
+          ATH_MSG_VERBOSE("Pre-processing Elements from Layer (id from idHelper): " << currentlayer );      
+          // set number of phiSectors
+          layerPhiSectors[currentlayer] = m_siMgr->numerology().numPhiModulesForLayer(currentlayer);
+          // set number of etaSectors
+          layerZsectors[currentlayer] = m_siMgr->numerology().numEtaModulesForLayer(currentlayer);
+          // get the HalfLength of the Layer
+          const InDetDD::SiDetectorElement* countPtr = (*sidetIter);
+          // needed for the complex z binning if activated
+          double lastModuleZ = 0.; 
+          std::vector<float> zboundaries; 
+          zboundaries.reserve(layerZsectors[currentlayer]+1);               
+          // walk all along to negative eta
+          while ((countPtr->prevInEta()))
+                 countPtr = countPtr->prevInEta();
+           layerMinZ[currentlayer] = countPtr->center().z() - 0.5*fabs(countPtr->length());
+           zboundaries.push_back(layerMinZ[currentlayer]);
+           lastModuleZ   = countPtr->center().z();
+           // register the layer minZ into the zboundaries         
+           // now walk all along to positive eta
+           while ((countPtr->nextInEta())) {
+                  countPtr = countPtr->nextInEta();
+                  // for complex binning
+                  double currentModuleZ   = countPtr->center().z();
+                  double currentZboundary = 0.5*(lastModuleZ+currentModuleZ);
+                  zboundaries.push_back(currentZboundary);
+                  lastModuleZ   = currentModuleZ;
+           }
+           layerMaxZ[currentlayer] = fabs(countPtr->center().z()) + 0.5*fabs(countPtr->length());
+           zboundaries.push_back(layerMaxZ[currentlayer]);
+           
+           // complex z binning mode
+           layerZboundaries[currentlayer] = zboundaries;
+           // chose which one to register for the split mode (SLHC)
+           layerHalfLength[currentlayer] =  layerMinZ[currentlayer]*layerMinZ[currentlayer] > layerMaxZ[currentlayer]*layerMaxZ[currentlayer] ?
+               fabs(layerMinZ[currentlayer]) : layerMaxZ[currentlayer];
+           // get the haflength of the layer
+           takeSmaller( minHalflengthZ, layerHalfLength[currentlayer]);
+           takeBigger( maxHalflengthZ, layerHalfLength[currentlayer]);
+           ATH_MSG_VERBOSE("      -> Determined Layer z range with  : " << layerMinZ[currentlayer] << " / " << layerMaxZ[currentlayer] );
+           ATH_MSG_VERBOSE("      -> Symmetric half length taken    : " << layerHalfLength[currentlayer]);
+       }
+                    
+       // (B) Determination of the radius ------------------------------------------------
+       // getting inner module
+       const InDetDD::SiDetectorElement* otherSide = (*sidetIter)->otherSide();
+       // take the maximum layer radius 
+       double currentR    = (*sidetIter)->center().perp(); 
+       double currentRmax = (*sidetIter)->rMax();
+       double currentRmin = (*sidetIter)->rMin();
+       layerRadius[currentlayer]  = (currentR > layerRadius[currentlayer]) ? currentR : layerRadius[currentlayer];
+       if (otherSide){
+           takeBigger( currentRmax, (otherSide)->rMax() );
+           takeSmaller( currentRmin, (otherSide)->rMin() );
+       }
+       takeSmaller( layerRmin[currentlayer], currentRmin );
+       takeBigger(  layerRmax[currentlayer], currentRmax );
+
+       // handle the split mode
+       if (m_splitMode > 0) takeBigger(s_splitRadius, layerRadius[currentlayer]);
+       else if (m_splitMode < 0) takeSmaller (s_splitRadius, layerRadius[currentlayer]);
+           
+       // fill the Surface vector
+       Amg::Vector3D orderPosition((*sidetIter)->center());
+       double currentPhi = orderPosition.phi();
+	   takeSmaller( layerMinPhi[currentlayer], currentPhi);
+       takeBigger( layerMaxPhi[currentlayer], currentPhi);
+       
+       // decide which one to register on the Radius: always the one with smaller radius
+       bool takeIt =  (!otherSide || (*sidetIter)->center().perp() < otherSide->center().perp() );
+       const Trk::Surface* moduleSurface = takeIt ? (&((*sidetIter)->surface())) : (&(otherSide->surface()));
+  
+       // register the module surface
+       Trk::SharedObject<const Trk::Surface> sharedSurface(moduleSurface, Trk::do_not_delete<const Trk::Surface>);
+  
+       Trk::SurfaceOrderPosition surfaceOrder(sharedSurface, orderPosition);
+       if (takeIt) (layerSurfaces[currentlayer]).push_back(surfaceOrder);
+     
+     } else if (!(*sidetIter)) // barrel chek and screen output
+        ATH_MSG_WARNING("NULL pointer to Barrel module given by SiDetectorManager! Please check db & dict.xml");
+  
+  } // SiDet Loop
+
+  // --------------------------- enf of LOOP over Detector Elements of sensitive layers ----------------------------------
+   
+  // [-B-] ------------------------ Construction of the layers -----------------------------------          
+  // [-B-1] construct the detection layers
+  std::vector< const Trk::CylinderLayer* > cylinderDetectionLayers;
+  int layerCounter          = 0;
+  double currentLayerExtend = 0.;
+  
+  // construct detection layers
+  for (auto& layerRadiusIter : layerRadius) {
+                  
+      Trk::CylinderLayer* activeLayer   = 0;
+      double currentLayerRadius         = 10e10;
+      bool splitDone                    = false;
+      // non-equidistant binning used ? auto-detection 
+      bool nonEquidistantBinning = false;
+      {
+          // calculate the average bin size
+          const double averageBinSize = (layerMaxZ[layerCounter]-layerMinZ[layerCounter])/(layerZsectors[layerCounter]);
+          const double inv_averageBinSize2 = 1. / (averageBinSize*averageBinSize);
+          // loop over the boundaries and check if theyare outside the tolerance
+          auto bIter  = layerZboundaries[layerCounter].begin();
+          auto bIterE = layerZboundaries[layerCounter].end();
+          for ( ++bIter; bIter != bIterE; ++bIter ){
+              float cZ = (*bIter);
+              float pZ = (*(bIter-1));
+              nonEquidistantBinning =  (cZ-pZ)*(cZ-pZ)*inv_averageBinSize2 < (1.-m_barrelEdbTolerance) *(1.-m_barrelEdbTolerance);
+              if (nonEquidistantBinning){
+                  ATH_MSG_VERBOSE("Non-equidistant binning for (Silicon) Surfaces on this layer with radius " << layerRadiusIter << " detected. ");
+                  ATH_MSG_VERBOSE("Difference " << (cZ-pZ)/averageBinSize << " at a allowed tolerance of : " << m_barrelEdbTolerance );
+                  break;
+              }
+          }
+      }
+      
+      //(1) the detecting layer : sensitive modules --------------------------------------------------------------------
+      // create the BinKeyUtility - the phi binning is identical
+      double halfPhiStep = M_PI/layerPhiSectors[layerCounter];
+      // protection in case phi value was fluctuating around 0 or M_PI in parsing
+      if (fabs(layerMinPhi[layerCounter]+layerMaxPhi[layerCounter])< halfPhiStep && fabs(M_PI+layerMinPhi[layerCounter]) < 0.5*halfPhiStep ){
+          ATH_MSG_VERBOSE("Detected module fluctuation around +/- M_PI, correcting for it.");
+          ATH_MSG_VERBOSE("    min phi / max phi detected  : "  << layerMinPhi[layerCounter] << " / " << layerMaxPhi[layerCounter] );
+          layerMinPhi[layerCounter] += 2*halfPhiStep;
+      } 
+      // now prepare the phi values
+      ATH_MSG_VERBOSE("Preparing the Phi-binning for   : " << layerPhiSectors[layerCounter] << " sectors.");
+      ATH_MSG_VERBOSE("    min phi / max phi detected  : " << layerMinPhi[layerCounter] << " / " << layerMaxPhi[layerCounter] );
+      double minPhiCorrected = layerMinPhi[layerCounter]-halfPhiStep;
+      double maxPhiCorrected = layerMaxPhi[layerCounter]+halfPhiStep;
+      // catch if the minPhi falls below M_PI
+      if (minPhiCorrected < -M_PI){
+          minPhiCorrected += 2*halfPhiStep;
+          maxPhiCorrected += 2*halfPhiStep;
+      }
+      ATH_MSG_VERBOSE("    min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
+       
+      
+      Trk::BinUtility* currentBinUtility   =  new Trk::BinUtility(layerPhiSectors[layerCounter],
+	  						                                      minPhiCorrected,
+	  						                                      maxPhiCorrected,
+	  						                                      Trk::closed, Trk::binPhi);
+      if (nonEquidistantBinning)
+          (*currentBinUtility) += Trk::BinUtility(layerZboundaries[layerCounter],
+                                                  Trk::open,
+                                                  Trk::binZ);
+      else 
+          (*currentBinUtility) += Trk::BinUtility(layerZsectors[layerCounter],
+                                                  layerMinZ[layerCounter],
+                                                  layerMaxZ[layerCounter],
+                                                  Trk::open,
+                                                  Trk::binZ);
+      // creating the binned array output
+      ATH_MSG_VERBOSE("Creating the binned array for the sensitive detector elements with BinUtility :");
+      ATH_MSG_VERBOSE( *currentBinUtility );
+      // the binned array for the senstive surfaces to be built            
+      Trk::BinnedArray<Trk::Surface>* currentBinnedArray = 
+            new Trk::BinnedArray2D<Trk::Surface>(layerSurfaces[layerCounter],currentBinUtility);       
+      // unit test for sub surface ordering
+	  const std::vector<const Trk::Surface*>& arraySurfaces = currentBinnedArray->arrayObjects();          
+
+      if (m_runGeometryValidation){
+         // checking for :
+         //   - empty surface bins
+         //   - doubly filled bins
+         std::map< const Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
+         auto usmIter = uniqueSurfaceMap.end();
+         // ------- iterate  
+         auto asurfIter = arraySurfaces.begin();
+         auto asurfIterEnd = arraySurfaces.end();
+         for ( ; asurfIter != asurfIterEnd; ++asurfIter){
+             if ( (*asurfIter) ) {
+                ++sumCheckBarrelModules;
+                usmIter = uniqueSurfaceMap.find(*asurfIter);
+                if ( usmIter != uniqueSurfaceMap.end() )
+                    ATH_MSG_WARNING("Non-unique surface found with eta/phi = " << (*asurfIter)->center().eta() << " / " << (*asurfIter)->center().phi());
+                else uniqueSurfaceMap[(*asurfIter)] = (*asurfIter)->center();
+	       }
+	       else 
+               ATH_MSG_WARNING("Null surface defined in BinUtility ArraySurfaces vector");
+         }
+      }
+
+      // dynamic layer extend and splitDone check (split mode need the dynamic extend !)
+      currentLayerExtend = layerHalfLength[layerCounter];
+      
+      // check if split has been done
+      // split mode < 0 : compare to maxHalfLength
+      // split mode > 0 : compare to minHalflength
+      double compareHalfLengthZ = m_splitMode < 0 ? maxHalflengthZ : minHalflengthZ;
+      
+      splitDone = m_splitMode && fabs(layerHalfLength[layerCounter]-compareHalfLengthZ) > m_splitTolerance;
+      if (m_splitMode){
+           ATH_MSG_DEBUG( "[ Split mode / part 1 ] Layer Halflength determined as: " << layerHalfLength[layerCounter]);
+           ATH_MSG_DEBUG( "                               while minHalflengthZ is: " << minHalflengthZ );
+           ATH_MSG_DEBUG( "                                     -> consequence is: " << (splitDone ? "store for iteration 2" : "build") );
+       }
+      
+      // dynamic layer extend determined by the sensitive layer dimensions
+      layerRadius[layerCounter] = 0.5*(layerRmax[layerCounter] + layerRmin[layerCounter]);
+      layerThickness[layerCounter] = layerRmax[layerCounter] - layerRmin[layerCounter];
+
+      // create the material
+      const Trk::LayerMaterialProperties* layerMaterial = barrelLayerMaterial(layerRadius[layerCounter], currentLayerExtend);
+      double currentLayerThickness = layerThickness[layerCounter]+m_barrelEnvelope;
+      
+      // screen output
+      ATH_MSG_DEBUG( "Construct BinnedArray for CylinderLayer with "<< (layerSurfaces[layerCounter]).size() << " SubSurfaces." );
+      ATH_MSG_DEBUG( "Building a CylinderLayer with " << layerPhiSectors[layerCounter]
+          << " / " <<   ( nonEquidistantBinning ? layerZboundaries[layerCounter].size() :  layerZsectors[layerCounter] ) << " phi/z bins. "   );
+      ATH_MSG_DEBUG( "  -> With Radius     :  " << layerRadius[layerCounter]    );       
+      ATH_MSG_DEBUG( "  -> With Thickness  :  " << currentLayerThickness << " - includes envelope tolerance : " << m_barrelEnvelope );
+      ATH_MSG_DEBUG( "  -> With Zmin/Zmax  :  " << -currentLayerExtend << " / " << currentLayerExtend );
+      
+      if ( nonEquidistantBinning && layerZboundaries[layerCounter].size() ){
+          // overrule the min bin - with the min radius 
+          // do the output to screen
+          double currentZ = -currentLayerExtend;
+          msg(MSG::DEBUG) <<  "  -> Z binning at      :  ";
+          for (size_t zbin = 0; zbin < layerZboundaries[layerCounter].size(); ++zbin) {
+              currentZ += layerZboundaries[layerCounter][zbin];
+              msg(MSG::DEBUG) << currentZ;
+              if (zbin <  layerZboundaries[layerCounter].size()-1) 
+                 msg(MSG::DEBUG) << ", ";
+          }
+          msg(MSG::DEBUG) << endmsg;           
+      }
+      // prepare the right overlap descriptor       
+      Trk::OverlapDescriptor* olDescriptor = 0;
+      if (m_pixelCase)
+          olDescriptor = new InDet::PixelOverlapDescriptor;
+      else olDescriptor = new  InDet::SCT_OverlapDescriptor;
+      // for eventual use with the passive layer
+      currentLayerRadius = layerRadius[layerCounter];
+
+      // construct the layer (finally)
+      activeLayer = new Trk::CylinderLayer(new Trk::CylinderBounds(layerRadius[layerCounter],currentLayerExtend),
+                                           currentBinnedArray,
+                                           *layerMaterial,
+                                           layerThickness[layerCounter],
+                                           olDescriptor);
+      // cleanup of the layer material --------------------------------------------------------------
+      delete layerMaterial; 
+      // register the layer to the surfaces
+      const std::vector<const Trk::Surface*>& layerSurfaces     = currentBinnedArray->arrayObjects();
+      registerSurfacesToLayer(layerSurfaces,*activeLayer);
+
+      // (3) register the layers --- either in the split vector or in the return vector 
+      if (splitDone) {
+          ATH_MSG_DEBUG( "[ Split mode / Part 1 ] Layer cached for Part 2" );
+          readHandle->range(s_splitIOVRange);
+          if (activeLayer) s_splitCylinderLayers.push_back(activeLayer);   
+          // get the split radius to the smallest one possible
+          if (m_splitMode > 0) takeSmaller( s_splitRadius, currentLayerRadius);
+          ATH_MSG_DEBUG("[ Split mode / part 1 ] Split radius (temproarily) set to : " << s_splitRadius );
+       } else {
+          if (m_splitMode < 0) takeBigger ( s_splitRadius, currentLayerRadius );
+          if (activeLayer) cylinderDetectionLayers.push_back(activeLayer);
+       } 
+       // increase the layer counter --- it is built
+       ++layerCounter;            
+
+  } // layer construction
+  // --------------------------- enf of detection layer construction loop ----------------------------------
+
+  ATH_MSG_DEBUG("Creating the final CylinderLayer collection with (potentially) additional layers.");
+  std::vector< const Trk::CylinderLayer* >* cylinderLayers = dressCylinderLayers(cylinderDetectionLayers);
+  
+  // multiply the check number in case of SCT 
+  sumCheckBarrelModules *= (m_pixelCase) ? 1 : 2; 
+  ATH_MSG_DEBUG( barrelModules << " Barrel Modules parsed for Cylinder Layer dimenstions." );
+  ATH_MSG_DEBUG( sumCheckBarrelModules << " Barrel Modules filled in Cylinder Layer Arrays." );
+  if ( barrelModules-sumCheckBarrelModules )
+     ATH_MSG_WARNING( barrelModules-sumCheckBarrelModules << " Modules not registered properly in binned array." );       
+
+  if (m_splitMode)
+     ATH_MSG_DEBUG("[ Split mode / part 1 ] Split radius determined as : " << s_splitRadius );
+
+  ATH_MSG_DEBUG("Returning " << cylinderLayers->size() << " cylinder layers.");
+  EventIDRange range;
+  readHandle->range(range);
+  delete readHandle;
+  std::pair<EventIDRange, const std::vector<const Trk::CylinderLayer*>*> cylinderLayersPair = std::make_pair(range,cylinderLayers);
+  return cylinderLayersPair;
+} 
+      
+/** LayerBuilder interface method - returning Endcap-like layers */
+std::pair<EventIDRange, const std::vector<const Trk::DiscLayer*>*> InDet::SiLayerBuilderCond::discLayers(const EventContext& ctx) const
+{
+ 
+  // TODO: remove s_splitDiscLayers cache to make threadsafe. ignored for now as is only for ITk
+  // split mode 2nd 
+  if (m_splitMode && s_splitDiscLayers.size() ){
+    ATH_MSG_DEBUG( "[ Split mode/ Part 2 ] Returning " << s_splitDiscLayers.size() << " disc layers." );
+    std::vector<const Trk::DiscLayer*>* splitDiscs = new std::vector<const Trk::DiscLayer*>(s_splitDiscLayers);
+    s_splitDiscLayers.clear();
+    return std::make_pair(s_splitIOVRange, splitDiscs); 
+  }
+  // sanity check for ID Helper
+  if (!m_pixIdHelper && !m_sctIdHelper){
+       ATH_MSG_ERROR("Neither Pixel nor SCT Detector Manager or ID Helper could be retrieved - giving up.");
+    //create dummy infinite range
+    EventIDRange range;
+    return std::pair<EventIDRange, const std::vector<const Trk::DiscLayer*>*>(range,nullptr);
+  } 
+
+  // check for DBMS
+  int nDBMLayers = m_siMgr->numerology().numEndcapsDBM();
+  if (!nDBMLayers) return createDiscLayers(ctx);
+  
+  ATH_MSG_DEBUG( "Found " << m_siMgr->numerology().numEndcapsDBM() << " DBM layers active, building first ECs, then DBMS");
+  std::pair<EventIDRange, std::vector<const Trk::DiscLayer*>*>  ecLayers = createDiscLayers(ctx);
+  if (ecLayers.second) {
+      ATH_MSG_VERBOSE( "Created " << ecLayers.second->size() << " endcap layers w/o  DBM.");
+      ecLayers = createDiscLayers(ctx, ecLayers.second);
+      ATH_MSG_VERBOSE( "Created " << ecLayers.second->size() << " endcap layers with DBM.");
+  }
+  return ecLayers;
+
+}
+
+/** LayerBuilder interface method - returning Endcap-like layers */
+std::pair<EventIDRange, std::vector< const Trk::DiscLayer* >* > InDet::SiLayerBuilderCond::createDiscLayers(const EventContext& ctx, std::vector<const Trk::DiscLayer*>* dLayers) const {
+ 
+  // this is the DBM flag
+  bool isDBM = (dLayers!=NULL);
+  
+  // get general layout
+  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection>* readHandle;
+  if(m_pixelCase){
+    readHandle = new SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> (m_PixelReadKey, ctx);
+  }else{
+    readHandle = new SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> (m_SCT_ReadKey, ctx);
+  }
+  const InDetDD::SiDetectorElementCollection* readCdo{**readHandle};
+  InDetDD::SiDetectorElementCollection::const_iterator sidetIter = readCdo->begin();    
+    
+  // save way to estimate the number of barrels
+  unsigned int endcapLayers = 0;
+  if (isDBM){
+     endcapLayers = m_siMgr->numerology().numDisksDBM();
+     ATH_MSG_DEBUG( "Configured to build " << endcapLayers << "*2 disc-like DBM layers" );
+  } else {           
+      for (int i = 0; i < m_siMgr->numerology().numDisks(); i++)
+          if (m_siMgr->numerology().useDisk(i)) endcapLayers++;
+     ATH_MSG_DEBUG( "Configured to build " << endcapLayers << " *2 disc-like layers  (+ additional support layers)." );
+  }
+ 
+  if (m_splitMode) 
+      ATH_MSG_DEBUG( "[ Split mode ] Some layers may bee cached." );
+
+  // prepare the vectors
+  std::vector<double>                                     discZmin(2*endcapLayers,10e10);
+  std::vector<double>                                     discZmax(2*endcapLayers,-10e10);
+  std::vector<double>                                     discZpos(2*endcapLayers,0.);
+  std::vector<double>                                     discRmin(2*endcapLayers,10e10);
+  std::vector<double>                                     discRmax(2*endcapLayers,0);
+  std::vector<double>                                     discThickness(2*endcapLayers,0.);
+  
+  std::vector< std::vector<Trk::SurfaceOrderPosition> >   discSurfaces;  
+  std::vector< std::vector<int> >                         discPhiSectors;
+  std::vector< std::vector<double> >                      discPhiMin;
+  std::vector< std::vector<double> >                      discPhiMax;
+  std::vector< std::vector<double> >                      discRingMinR;
+  std::vector< std::vector<double> >                      discRingMaxR;  
+    
+  // let's make sure the discs are ordered in z: that's the z / map index
+  std::map< double, int>                                  discZposLayerIndex;  
+    
+  // reserve -- better memory management    
+  discPhiMin.reserve(2*endcapLayers);
+  discPhiMax.reserve(2*endcapLayers);
+  discPhiSectors.reserve(2*endcapLayers);
+  discSurfaces.reserve(2*endcapLayers);
+  discRingMinR.reserve(2*endcapLayers);
+  discRingMaxR.reserve(2*endcapLayers);
+   
+  // initialize for checks (pos/neg discs -> 2 times discs)
+  for (unsigned int endcap=0; endcap<2*endcapLayers; endcap++){
+        discPhiMin.push_back(std::vector<double>());
+        discPhiMax.push_back(std::vector<double>());
+        discPhiSectors.push_back(std::vector<int>());
+        discSurfaces.push_back( std::vector<Trk::SurfaceOrderPosition>() );
+        // auto-detection
+        discRingMinR.push_back(std::vector<double>());
+        discRingMaxR.push_back(std::vector<double>());      
+   } // end of for loop
+   
+  int endcapModules = 0;
+  int sumCheckEndcapModules = 0;
+  unsigned int currentlayer = 0;
+  unsigned int currentdisk  = 0;
+  unsigned int currentring  = 0;
+  
+  // [-A1-] ------------------------ first LOOP over Detector Elements of sensitive layers -------------------------------                 
+  // -- get the missing dimensions by loop over DetElements
+  sidetIter = readCdo->begin();
+  for (; sidetIter != readCdo->end(); sidetIter++){
+     // take it - if 
+     // a) you have a detector element ... protection
+     // b) the detector element is EC (in the non-DBM case)
+     // c) the detector elemet is DBM in the DBM case
+     if ( (*sidetIter) && ( (!isDBM && (*sidetIter)->isEndcap()) || (isDBM && (*sidetIter)->isDBM())) ){
+     
+       // increase the counter of endcap modules
+        endcapModules++;
+        // parse all z positions for the mean value of the discs
+        double currentZ = (*sidetIter)->center().z();
+        // get the identifier & calculate current layer and current disk from it     
+        Identifier    currentId((*sidetIter)->identify());
+        currentdisk  = m_pixIdHelper ? m_pixIdHelper->layer_disk(currentId) : m_sctIdHelper->layer_disk(currentId);
+        currentlayer = currentdisk;
+        currentlayer += currentZ > 0. ? endcapLayers : 0;
+
+        // check the current ring
+        currentring = m_pixIdHelper ? m_pixIdHelper->eta_module(currentId) : m_sctIdHelper->eta_module(currentId);
+
+        takeSmallerBigger(discZmin[currentlayer],discZmax[currentlayer],currentZ);
+
+        // set the disc Rmin / Rmax  
+        double currentRmin = (*sidetIter)->rMin();
+        double currentRmax = (*sidetIter)->rMax();
+
+        // how many rings do we have ?
+        unsigned int diskRings =  isDBM ? 
+            m_siMgr->numerology().numRingsForDiskDBM(currentdisk) : 
+            m_siMgr->numerology().numRingsForDisk(currentdisk);
+               
+        // the current phi 
+        double currentPhi = (*sidetIter)->center().phi();
+        takeSmaller(discRmin[currentlayer],currentRmin);
+        takeBigger( discRmax[currentlayer],currentRmax);
+
+        //fill the number of phi sectors for the different rings
+        if (!discPhiSectors[currentlayer].size()){
+           ATH_MSG_VERBOSE("Pre-processing Elements from Disk/Layer (id from idHelper): " << currentdisk << "/" << currentlayer );
+           // prepare the ring bins, initialise the first one to be something big
+           discPhiMin[currentlayer]      = std::vector<double>(diskRings,100.); 
+           discPhiMax[currentlayer]      = std::vector<double>(diskRings,-100.); 
+           discRingMinR[currentlayer]    = std::vector<double>(diskRings,1e10);
+           discRingMaxR[currentlayer]    = std::vector<double>(diskRings,0);
+           // fill the phi sectors 
+           ATH_MSG_VERBOSE("-> The current disk has " << diskRings << " ring(s)");
+           for (unsigned int iring=0; iring < diskRings; ++iring){
+               unsigned int phiSectorsRing = isDBM ? 
+                   m_siMgr->numerology().numPhiModulesForDiskRingDBM(currentdisk, iring) :
+                   m_siMgr->numerology().numPhiModulesForDiskRing(currentdisk, iring);
+              // get the number of phi sectors
+              ATH_MSG_VERBOSE("--> Ring " << iring << " has " << phiSectorsRing << " phi sectors");
+              discPhiSectors[currentlayer].push_back(phiSectorsRing);
+           }
+        }
+        // we take the phi / r binning only from the closer to IP module 
+        if ( !(*sidetIter)->otherSide() || fabs(currentZ) < fabs((*sidetIter)->otherSide()->center().z())){
+            // take phi-min and phimax
+            takeSmaller(discPhiMin[currentlayer][currentring],currentPhi);
+            takeBigger(discPhiMax[currentlayer][currentring],currentPhi);
+            // record the smalles ring & biggest ring radius
+            takeSmaller(discRingMinR[currentlayer][currentring],currentRmin);
+            takeBigger(discRingMaxR[currentlayer][currentring],currentRmax);
+        }
+     } else if (!(*sidetIter))
+        ATH_MSG_WARNING("NULL pointer to Endcap module given by SCT_DetectorManager! Please check db & dict.xml");
+  } // DetElement loop 
+
+  double minRmin = 10e10;
+  double maxRmax = -10e10;
+  
+  ATH_MSG_VERBOSE("Estimating the average z position and the radius for each disk.");
+  // get the average z-position per layer & estimate thes thickness
+  for (unsigned int iec=0; iec<2*endcapLayers; ++iec){
+       takeSmaller(minRmin,discRmin[iec]); takeBigger(maxRmax,discRmax[iec]);
+       // average it out
+       discZpos[iec]        = 0.5 * (discZmin[iec] + discZmax[iec]);
+       discThickness[iec]   = isDBM ? 1. : fabs(discZmax[iec]-discZmin[iec]);
+       // make the map z / index
+       discZposLayerIndex.insert(std::make_pair(discZpos[iec],iec));
+  }
+
+  // [-A2-] ------------------------ second LOOP over Detector Elements of sensitive layers -------------------------------                 
+  // fill the elements for the layers into the surface arrays
+  sidetIter = readCdo->begin();
+  for (; sidetIter != readCdo->end(); sidetIter++){
+    // Endcap
+    if ( ((*sidetIter) && ((!isDBM && (*sidetIter)->isEndcap()) || (isDBM && (*sidetIter)->isDBM()))) ){     
+        // get the identifier & calculate current layer and current disk from it     
+        Identifier    currentId((*sidetIter)->identify());
+        currentdisk  = m_pixIdHelper ? m_pixIdHelper->layer_disk(currentId) : m_sctIdHelper->layer_disk(currentId);
+        currentlayer = currentdisk;
+        currentlayer += (*sidetIter)->center().z() > 0. ? endcapLayers : 0;
+        // decision which module to take
+        const InDetDD::SiDetectorElement* otherSide = (*sidetIter)->otherSide();    
+        bool takeIt =  (!otherSide || fabs((*sidetIter)->center().z()) < fabs(otherSide->center().z()) );
+        const InDetDD::SiDetectorElement* chosenSide = takeIt ?  (*sidetIter) : otherSide;
+        // get the center position
+        const Amg::Vector3D& orderPosition = chosenSide->center();
+        // register the chosen side in the object array
+        Trk::SharedObject<const Trk::Surface> sharedSurface(&(chosenSide->surface()), [](const Trk::Surface*){});
+        Trk::SurfaceOrderPosition surfaceOrder(sharedSurface, orderPosition);
+        if (takeIt) (discSurfaces[currentlayer]).push_back(surfaceOrder);      
+    }      
+  } //end of filling
+    
+  // [-B-] ------------------------ Construction of the layers -----------------------------------
+  // construct the layers
+  std::vector< const Trk::DiscLayer* >* discLayers = dLayers ? dLayers : new std::vector< const Trk::DiscLayer* >;
+  std::vector<double>::iterator discZposIter = discZpos.begin();
+  int discCounter = 0;
+                                              
+  for ( ; discZposIter != discZpos.end(); ++discZposIter){
+       // the gathered R sectors  
+       size_t discRsectors = (discPhiSectors[discCounter]).size();
+       // dynamic estimation 1: estimate the layer thickness dynamically
+       double thickness = discThickness[discCounter]+m_endcapEnvelope;       
+       // put rMin in and sort the bins
+       std::vector<double> discRingMinRcopy = discRingMinR[discCounter];
+       std::sort(discRingMinRcopy.begin(), discRingMinRcopy.end());
+       bool reverseRsectors = !(discRingMinRcopy == discRingMinR[discCounter]); 
+              
+       // this causes a reverse order for the phi sectors
+       if (reverseRsectors){
+           ATH_MSG_VERBOSE("Auto-detect: rings in R are in " << ( reverseRsectors ? "reversed" : "standard") << " order.");
+           std::reverse(discPhiSectors[discCounter].begin(),discPhiSectors[discCounter].end());
+           std::reverse(discPhiMin[discCounter].begin(),discPhiMin[discCounter].end()); 
+           std::reverse(discPhiMax[discCounter].begin(),discPhiMax[discCounter].end()); 
+           std::reverse(discRingMaxR[discCounter].begin(),discRingMaxR[discCounter].end());
+       }       
+       // preperare the rboundaries
+       std::vector<float> discRboundaries;
+       discRboundaries.push_back(float(*discRingMinRcopy.begin()));
+       for ( std::vector<double>::iterator ringMaxRIter = discRingMaxR[discCounter].begin(); 
+            ringMaxRIter != discRingMaxR[discCounter].end(); ++ringMaxRIter)   
+           discRboundaries.push_back(float(*ringMaxRIter));
+
+       // screen output           
+       ATH_MSG_DEBUG( "Building a DiscLayer with " << discRsectors << " R sectors. " );
+       ATH_MSG_DEBUG( "  -> At Z - Position      :  " << discZpos[discCounter] );
+       ATH_MSG_DEBUG( "  -> With Thickness       :  " << thickness   << " i- ncludes envelope tolerance : " << m_endcapEnvelope );
+       ATH_MSG_DEBUG( "  -> With Rmin/Rmax (est) :  " << discRmin[discCounter] << " / " << discRmax[discCounter] );
+       ATH_MSG_DEBUG( "  -> With Rings           :  " << discRsectors );
+          
+       for (size_t irings=0; irings<discRsectors; ++irings)
+         ATH_MSG_DEBUG( " --> " << irings <<  " R sector has " << discPhiSectors[discCounter][irings] << " phi sectors. " );
+            
+       // prepare the binned array, it can be with one to several rings            
+       Trk::BinnedArray<Trk::Surface>* currentBinnedArray = 0;
+       std::vector<Trk::BinUtility*>* singleBinUtils = new std::vector<Trk::BinUtility*>;
+       bool weOwnSingleBinUtils{true};
+       if (discRsectors==1){
+            double halfPhiStep = M_PI/discPhiSectors[discCounter][0];
+            // protection in case phi value was fluctuating around 0 or M_PI in parsing
+            if (fabs(discPhiMin[discCounter][0]+discPhiMax[discCounter][0])< halfPhiStep && fabs(discPhiMin[discCounter][0]) < 0.5*halfPhiStep ){
+                ATH_MSG_VERBOSE("Detected module fluctuation around +/- M_PI, correcting for it.");
+                ATH_MSG_VERBOSE("    min phi / max phi detected  : "  << discPhiMin[discCounter][0] << " / " <<discPhiMax[discCounter][0] );
+                discPhiMin[discCounter][0] += 2*halfPhiStep;
+            } 
+            // prepare min phi and max phi & eventually a sub stepvalue
+            ATH_MSG_VERBOSE("    min phi / max phi detected  : " << discPhiMin[discCounter][0] << " / " << discPhiMax[discCounter][0] );
+            double minPhiCorrected = discPhiMin[discCounter][0]-halfPhiStep;
+            double maxPhiCorrected = discPhiMax[discCounter][0]+halfPhiStep;
+            // catch if the minPhi falls below M_PI
+            if (minPhiCorrected < -M_PI){
+                minPhiCorrected += 2*halfPhiStep;
+                maxPhiCorrected += 2*halfPhiStep;
+            }
+            ATH_MSG_VERBOSE("    min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
+            
+            ATH_MSG_VERBOSE("Constructing a one-dimensional BinnedArray with phiMin / phiMax (bins) = " 
+                << minPhiCorrected << " / " << maxPhiCorrected
+                << " (" << discPhiSectors[discCounter][0] << ")");
+            // an easier bin utility can be used                 
+            Trk::BinUtility* currentBinUtility = new Trk::BinUtility(discPhiSectors[discCounter][0] ,
+                                                                     minPhiCorrected,
+                                                                     maxPhiCorrected,
+                                                                     Trk::closed,
+                                                                     Trk::binPhi);
+            // a one-dimensional BinnedArray is sufficient
+            currentBinnedArray = new Trk::BinnedArray1D<Trk::Surface>(discSurfaces[discCounter],currentBinUtility);
+        } else {
+            ATH_MSG_VERBOSE("Constructing a two-dimensional BinnedArray.");
+            // get the binning in R first (can still be improved with non-aequidistant binning) 
+            Trk::BinUtility* currentSteerBinUtility = 0;
+            if (m_endcapComplexRingBinning && discRsectors > 1 ){
+                // respecting the actual element boundaires
+                ATH_MSG_VERBOSE("Non-equidistant binning detected.");
+                // now create the bin utility                                                          
+                currentSteerBinUtility = new Trk::BinUtility(discRboundaries,
+                                                                    Trk::open,
+                                                                    Trk::binR);
+             } else 
+                currentSteerBinUtility =  new Trk::BinUtility(discRsectors,
+                                                              discRmin[discCounter],
+                                                              discRmax[discCounter],
+                                                              Trk::open,
+                                                              Trk::binR);
+            ATH_MSG_VERBOSE("Steering bin utility constructed as : " << *currentSteerBinUtility);
+            // the single phi bin utilities
+            //std::vector<Trk::BinUtility*>* singleBinUtils = new std::vector<Trk::BinUtility*>;
+            singleBinUtils->reserve(discRsectors);
+            for (size_t irings=0; irings < discRsectors; ++irings){
+                    double halfPhiStep = M_PI/discPhiSectors[discCounter][irings];
+                    ATH_MSG_VERBOSE("    min phi / max phi detected  : " << discPhiMin[discCounter][irings] << " / " << discPhiMax[discCounter][irings] );
+                    double minPhiCorrected = discPhiMin[discCounter][irings]-halfPhiStep;
+                    double maxPhiCorrected = discPhiMax[discCounter][irings]+halfPhiStep;
+                    // catch if the minPhi falls below M_PI
+                    if (minPhiCorrected < -M_PI){
+                        minPhiCorrected += 2*halfPhiStep;
+                        maxPhiCorrected += 2*halfPhiStep;
+                    }
+                    ATH_MSG_VERBOSE("    min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
+                    ATH_MSG_VERBOSE("Constructing for ring " << irings << " phi utility with phiMin / phiMax (bins) = " 
+                        <<  minPhiCorrected << " / " << maxPhiCorrected << " (" << discPhiSectors[discCounter][irings] << ")") ;
+                    singleBinUtils->push_back(new Trk::BinUtility(discPhiSectors[discCounter][irings],
+                                                                  minPhiCorrected,
+                                                                  maxPhiCorrected,
+                                                                  Trk::closed,
+                                                                  Trk::binPhi));
+            }
+            // a two-dimensional BinnedArray is needed ; takes possession of singleBinUtils and
+            // will delete it on destruction.
+            weOwnSingleBinUtils=false;                                                       
+            currentBinnedArray = new Trk::BinnedArray1D1D<Trk::Surface>(discSurfaces[discCounter],
+                                                                        currentSteerBinUtility,
+                                                                        singleBinUtils);
+        }
+
+
+        int discSurfacesNum = (discSurfaces[discCounter]).size();
+        ATH_MSG_DEBUG( "Constructed BinnedArray for DiscLayer with "<< discSurfacesNum << " SubSurfaces." );
+
+        // always run the geometry validation to catch flaws
+        
+        // checking for :
+        //   - empty surface bins
+        //   - doubly filled bins
+        std::map< const Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
+        std::map< const Trk::Surface*,Amg::Vector3D >::iterator usmIter = uniqueSurfaceMap.end();
+        // check the registered surfaces in the binned array
+        const std::vector<const Trk::Surface*>& arraySurfaces = currentBinnedArray->arrayObjects();
+        size_t dsumCheckSurfaces = 0;
+        double lastPhi = 0.;
+        for (auto& asurfIter : arraySurfaces){
+            if ( asurfIter ) {
+                ++dsumCheckSurfaces;
+                usmIter = uniqueSurfaceMap.find(asurfIter);
+                lastPhi = asurfIter->center().phi();
+                if ( usmIter != uniqueSurfaceMap.end() )
+                    ATH_MSG_WARNING("Non-unique surface found with eta/phi = " << asurfIter->center().eta() << " / " << asurfIter->center().phi());
+                else uniqueSurfaceMap[asurfIter] = asurfIter->center();
+            } else 
+                ATH_MSG_WARNING("Zero-pointer in array detected in this ring, last valid phi value was = " << lastPhi);            
+        }
+        sumCheckEndcapModules +=  dsumCheckSurfaces;   
+           
+        // force same size for material collection - may be refined later
+        double rMin = (m_splitMode || m_endcapRingLayout) ? discRmin[discCounter] : minRmin;
+        double rMax = (m_splitMode || m_endcapRingLayout) ? discRmax[discCounter] : maxRmax;
+       
+        ATH_MSG_DEBUG( "  -> With Rmin/Rmax (corr) :  " << minRmin << " / " << maxRmax );
+       
+       // get the layer material from the helper method
+        const Trk::LayerMaterialProperties* layerMaterial = endcapLayerMaterial(rMin,rMax);
+
+        // position & bounds of the active Layer
+        Amg::Transform3D*  activeLayerTransform = new Amg::Transform3D;
+        bool weOwnActiveLayerTransform=true;
+        (*activeLayerTransform) = Amg::Translation3D(0.,0.,discZpos[discCounter]);
+       
+        Trk::DiscBounds* activeLayerBounds    = new Trk::DiscBounds(rMin,rMax);
+        // prepare the right overlap descriptor       
+        Trk::OverlapDescriptor* olDescriptor = 0;
+        if (m_pixelCase)
+            olDescriptor = new InDet::PixelOverlapDescriptor;
+        //else olDescriptor = new  InDet::SCT_OverlapDescriptor;
+	else {
+	  std::vector<Trk::BinUtility*>* binUtils = new std::vector<Trk::BinUtility*>;
+	  if (singleBinUtils) {
+	    std::vector<Trk::BinUtility*>::iterator binIter = singleBinUtils->begin();
+	    for ( ; binIter != singleBinUtils->end(); ++binIter){
+	      binUtils->push_back((*binIter)->clone());
+	    }
+	  }
+	  //DiscOverlapDescriptor takes possession of binUtils, will delete it on destruction.
+	  // but *does not* manage currentBinnedArray.
+	  olDescriptor = new  InDet::DiscOverlapDescriptor(currentBinnedArray, binUtils);
+	}
+        
+        // layer creation; deletes currentBinnedArray in baseclass 'Layer' upon destruction
+        // activeLayerTransform deleted in 'Surface' baseclass
+        Trk::DiscLayer* activeLayer = new Trk::DiscLayer(activeLayerTransform,
+                                                         activeLayerBounds,
+                                                         currentBinnedArray,
+                                                         *layerMaterial,
+                                                         thickness,
+                                                         olDescriptor);
+        weOwnActiveLayerTransform=false;
+        // cleanup
+        delete layerMaterial;
+        // register the layer to the surfaces --- if necessary to the other sie as well
+        const std::vector<const Trk::Surface*>& layerSurfaces     = currentBinnedArray->arrayObjects();
+        registerSurfacesToLayer(layerSurfaces,*activeLayer);
+        if (m_splitMode){
+            ATH_MSG_DEBUG( "[ Split mode ] Checking if this layer needs to be cached." );
+            if (m_splitMode < 0 && rMin > s_splitRadius){
+                ATH_MSG_VERBOSE( "            Split mode is negative and rMin > splitRadius (" << rMin  << " > " << s_splitRadius << ").");
+                ATH_MSG_VERBOSE( "            -> Caching this disk.");
+                readHandle->range(s_splitIOVRange);
+                s_splitDiscLayers.push_back(activeLayer);
+            }
+            else if (m_splitMode > 0 && rMax < s_splitRadius){
+                ATH_MSG_VERBOSE( "            Split mode is positive and rMax < splitRadius (" << rMax  << " < " << s_splitRadius << ").");
+                ATH_MSG_VERBOSE( "            -> Caching this disk.");
+                readHandle->range(s_splitIOVRange);
+                s_splitDiscLayers.push_back(activeLayer);
+            }
+        } else 
+            discLayers->push_back(activeLayer);
+       // increase the disc counter by one
+       ++discCounter;
+       if (weOwnSingleBinUtils){
+         delete singleBinUtils;
+         singleBinUtils=nullptr;
+       }
+       if (weOwnActiveLayerTransform){
+        delete activeLayerTransform;
+        activeLayerTransform=nullptr;
+       }
+  }  
+
+  // multiply the check modules for SCT case
+  sumCheckEndcapModules *= (m_pixelCase) ? 1 : 2;        
+  ATH_MSG_DEBUG( endcapModules << " Endcap Modules parsed for Disc Layer dimensions." );
+  ATH_MSG_DEBUG( sumCheckEndcapModules << " Endcap Modules filled in Disc Layer Arrays." );
+  if ( endcapModules-sumCheckEndcapModules )
+     ATH_MSG_WARNING( endcapModules-sumCheckEndcapModules << " Modules not registered properly in binned array." );       
+
+ 
+  // sort the vector
+  Trk::DiscLayerSorterZ zSorter;
+  std::vector<const Trk::DiscLayer*>::iterator sortIter = discLayers->begin();
+  std::vector<const Trk::DiscLayer*>::iterator sortEnd   = discLayers->end(); 
+  std::sort(sortIter, sortEnd, zSorter);
+ 
+  // if there are additional layers to be built - never build for the DBM loop
+  if (m_endcapAdditionalLayerPosZ.size() && !isDBM){
+      // sort also the additional layer z positions
+      auto addLayerIter     = m_endcapAdditionalLayerPosZ.begin();
+      auto addLayerIterEnd  = m_endcapAdditionalLayerPosZ.end();
+      auto addLayerTypeIter = m_endcapAdditionalLayerType.begin();
+      // reassign the iterators
+      sortIter = discLayers->begin();
+      sortEnd   = discLayers->end();
+      // get the last rmin / rmax
+      double lastRmin = 0.;
+      double lastRmax = 0.;
+      // build the additional layers -------------------------------------------
+      for ( ; sortIter != sortEnd || addLayerIter != addLayerIterEnd; ){
+          // cache befor last parameters are overwritten 
+          double layerRmin       = lastRmin;
+          double layerRmax       = lastRmax;
+          double layerZposition   = 0.; 
+          // check if the z-position is smaller than the 
+          if ( sortIter != sortEnd){
+              // get the current z position to guarantee a symmetrical setup
+              layerZposition = (*sortIter)->surfaceRepresentation().center().z();
+              // get the bounds for the rMin / rMax setting
+              const Trk::DiscBounds* currentBounds = dynamic_cast<const Trk::DiscBounds*>(&((*sortIter)->surfaceRepresentation().bounds()));
+              lastRmin = currentBounds ? currentBounds->rMin() : 0.;
+              lastRmax = currentBounds ? currentBounds->rMax() : 0.;
+              ++sortIter;           
+          }
+          if ( addLayerIter != addLayerIterEnd){
+              // symmetric setup around 0.
+              double rMin = layerZposition > 0. ? layerRmin : lastRmin;
+              double rMax = layerZposition > 0. ? layerRmax : lastRmax;
+              // the passive layer
+              Trk::DiscLayer* passiveLayer = 0;
+              // passive layer creation
+              Amg::Transform3D* passiveDiscTransf = new Amg::Transform3D;
+              (*passiveDiscTransf) = Amg::Translation3D(0.,0.,*addLayerIter);
+              if (*addLayerTypeIter){
+                  ATH_MSG_DEBUG("Building an additional DiscLayer w/o sensitive modules at");
+                  // create the material and the passive layer
+                  const Trk::LayerMaterialProperties* passiveLayerMaterial = endcapLayerMaterial(rMin,rMax);
+                  passiveLayer = new Trk::DiscLayer(passiveDiscTransf,
+                                                    new Trk::DiscBounds(rMin,rMax),
+                                                    *passiveLayerMaterial,
+                                                    1.*Gaudi::Units::mm);
+              } else
+                  passiveLayer = new Trk::DiscLayer(passiveDiscTransf, new Trk::DiscBounds(rMin,rMax), 0);
+              ATH_MSG_DEBUG( "  -> At Z - Position       :  " << *addLayerIter );
+              ATH_MSG_DEBUG( "  -> With Rmin/Rmax (corr) :  " << rMin << " / " << rMax );
+              
+              // increase the iterator and push back the new layer
+             ++addLayerIter; 
+             discLayers->push_back(passiveLayer);
+          }
+      } // the additional layers are build ------------------------------------
+
+    // another round of sorting needed after adding the passive layers
+    sortIter = discLayers->begin();
+    sortEnd   = discLayers->end(); 
+    std::sort(sortIter, sortEnd, zSorter);
+  }
+ 
+  EventIDRange range;
+  readHandle->range(range);
+  delete readHandle;
+  return std::make_pair(range, discLayers);
+}
+
+
+
+std::vector< const Trk::CylinderLayer* >* InDet::SiLayerBuilderCond::dressCylinderLayers(const std::vector< const Trk::CylinderLayer* >& detectionLayers ) const {
+
+
+    std::vector< const Trk::CylinderLayer* >* cylinderLayers = new std::vector< const Trk::CylinderLayer* >;
+    // --------------------------- start of additional layer construction loop -------------------------------
+    // for the additional layer
+    if (m_barrelAdditionalLayerR.size()){
+        auto cylLayerIter         = detectionLayers.begin();
+        auto cylLayerIterEnd      = detectionLayers.end();
+        auto addLayerIter         = m_barrelAdditionalLayerR.begin();
+        auto addLayerIterEnd      = m_barrelAdditionalLayerR.end();
+        auto addLayerTypeIter     = m_barrelAdditionalLayerType.begin();
+        auto addLayerTypeIterEnd  = m_barrelAdditionalLayerType.end();
+        double cylLayerExtend     = 0;
+        for ( ; addLayerIter != addLayerIterEnd && addLayerTypeIter != addLayerTypeIterEnd; ) {
+            // build the passive layer if it is smaller the current cylLayerIter - or if it is the last one 
+            if ( m_splitMode && s_splitCylinderLayers.size() ){
+                ATH_MSG_DEBUG("Called in split mode with split radius = " << s_splitRadius );
+                ATH_MSG_DEBUG("[- X -] Skipping additional layer " );
+                ATH_MSG_DEBUG( "  -> With Radius     :  " << *addLayerIter   );       
+                // increase the additional layer radii
+                ++addLayerIter; ++addLayerTypeIter; 
+                continue;
+            }
+            if  ( cylLayerIter == cylLayerIterEnd || (*addLayerIter) < (*cylLayerIter)->bounds().r() ){
+              cylLayerExtend = (cylLayerIter == cylLayerIterEnd) ? cylLayerExtend : (*cylLayerIter)->bounds().halflengthZ() ;  
+              if ( (*addLayerTypeIter) ) {
+                    ATH_MSG_DEBUG("[- M -] Building an additional CylinderLayer w/o sensitive modules");
+                    // the material for the passive layer
+                    const Trk::LayerMaterialProperties* passiveLayerMaterial = barrelLayerMaterial(*addLayerIter,cylLayerExtend);
+                    // create the passive layer
+                    cylinderLayers->push_back(new Trk::CylinderLayer(new Trk::CylinderBounds(*addLayerIter,cylLayerExtend),
+                                                                     *passiveLayerMaterial,
+                                                                     1.*Gaudi::Units::mm,
+                                                                     0,0));
+                    // cleanup of the layer material --------------------------------------------------------------
+                    delete passiveLayerMaterial;                                                       
+              } else {
+                  ATH_MSG_DEBUG("[- N -] Building an additional NavigationLayer for volume dimension control");
+                  // create the passive layer
+                  cylinderLayers->push_back(new Trk::CylinderLayer(new Trk::CylinderBounds(*addLayerIter,cylLayerExtend),0));
+              }
+              ATH_MSG_DEBUG( "  -> With Radius     :  " << *addLayerIter   );       
+              // increase the additional layer radii
+              ++addLayerIter; ++addLayerTypeIter; 
+              continue;
+          } 
+          ATH_MSG_DEBUG("[- D -] Registering detection CylinderLayer");
+          ATH_MSG_DEBUG( "  -> With Radius     :  " << (*cylLayerIter)->bounds().r()   );
+          cylinderLayers->push_back(*cylLayerIter);
+          ++cylLayerIter;       
+        }
+    } else 
+        for (auto& cylLayerIter : detectionLayers ) {
+            ATH_MSG_DEBUG("[- D -] Registering detection CylinderLayer");
+            ATH_MSG_DEBUG( "  -> With Radius     :  " << cylLayerIter->bounds().r()   );
+            cylinderLayers->push_back(cylLayerIter);
+        }
+    return cylinderLayers;
+}
+
+const Trk::LayerMaterialProperties* InDet::SiLayerBuilderCond::barrelLayerMaterial(double r, double hz) const
+{
+  Trk::LayerMaterialProperties* layerMaterial = 0;
+  // --------------- material estimation ----------------------------------------------------------------
+  // -- material with 1D binning
+  Trk::BinUtility layerBinUtilityZ(m_barrelLayerBinsZ, -hz, hz, Trk::open, Trk::binZ);
+  if (m_barrelLayerBinsPhi==1){
+      layerMaterial = new Trk::BinnedLayerMaterial(layerBinUtilityZ);
+  } else  { // -- material with 2D binning
+      Trk::BinUtility layerBinUtilityRPhiZ(m_barrelLayerBinsPhi,
+                                                 -r*M_PI, r*M_PI,
+                                                 Trk::closed,
+                                                 Trk::binRPhi);
+      layerBinUtilityRPhiZ += layerBinUtilityZ;                                                       
+      layerMaterial = new Trk::BinnedLayerMaterial(layerBinUtilityRPhiZ);
+  }
+  // --------------- material estimation ----------------------------------------------------------------
+  return layerMaterial;    
+}
+
+const Trk::LayerMaterialProperties* InDet::SiLayerBuilderCond::endcapLayerMaterial(double rMin, double rMax) const
+{
+  Trk::LayerMaterialProperties* layerMaterial = 0;
+  // --------------- material estimation ----------------------------------------------------------------
+
+  Trk::BinUtility layerBinUtilityR(m_endcapLayerBinsR,rMin,rMax,Trk::open, Trk::binR);
+  // -- material with 1D binning
+  if (m_endcapLayerBinsPhi==1){
+      layerMaterial = new Trk::BinnedLayerMaterial(layerBinUtilityR);
+  } else { // -- material with 2D binning
+      Trk::BinUtility layerBinUtilityPhi(m_endcapLayerBinsPhi,-M_PI,M_PI,Trk::closed,Trk::binPhi);
+      layerBinUtilityR += layerBinUtilityPhi;
+      layerMaterial     = new Trk::BinnedLayerMaterial(layerBinUtilityR);
+  }
+  // --------------- material estimation ----------------------------------------------------------------
+  return layerMaterial;    
+}     
+
+void InDet::SiLayerBuilderCond::registerSurfacesToLayer(const std::vector<const Trk::Surface*>& layerSurfaces, const Trk::Layer& lay) const
+{
+    if (!m_setLayerAssociation) return;
+    
+    std::vector<const Trk::Surface*>::const_iterator laySurfIter    = layerSurfaces.begin();
+    std::vector<const Trk::Surface*>::const_iterator laySurfIterEnd = layerSurfaces.end();
+    // register the surfaces to the layer
+    for (; laySurfIter != laySurfIterEnd; ++laySurfIter){
+        if (*laySurfIter) { 
+            // register the current surface --------------------------------------------------------
+            Trk::ILayerBuilderCond::associateLayer(lay, **laySurfIter);
+            const InDetDD::SiDetectorElement* detElement 
+                = dynamic_cast<const InDetDD::SiDetectorElement*>((*laySurfIter)->associatedDetectorElement());             
+            // register the backise if necessary ---------------------------------------------------
+            const InDetDD::SiDetectorElement* otherSideElement = detElement ?  detElement->otherSide() : 0;                 
+            const Trk::Surface* otherSideSurface = otherSideElement ? &(otherSideElement->surface()) : 0;
+            if (otherSideSurface) Trk::ILayerBuilderCond::associateLayer(lay, *otherSideSurface);
+            }
+    }   
+    
+    return;
+}
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/StagedTrackingGeometryBuilderCond.cxx b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/StagedTrackingGeometryBuilderCond.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..9ef48138b05124560174b5b5e52d554cfb1ea173
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/StagedTrackingGeometryBuilderCond.cxx
@@ -0,0 +1,718 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+////////////////////////////////////////////////////////////////////
+// StagedTrackingGeometryBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+// InDet
+#include "InDetTrackingGeometry/StagedTrackingGeometryBuilderCond.h"
+// EnvelopeDefinitionService
+#include "SubDetectorEnvelopes/IEnvelopeDefSvc.h"
+// Trk interfaces
+#include "TrkDetDescrInterfaces/ILayerProviderCond.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeCreator.h"
+#include "TrkDetDescrInterfaces/ILayerArrayCreator.h"
+// Trk Geometry stuff
+#include "TrkDetDescrUtils/BinnedArray.h"
+#include "TrkVolumes/VolumeBounds.h"
+#include "TrkVolumes/CylinderVolumeBounds.h"
+#include "TrkGeometry/TrackingVolume.h"
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkGeometry/MagneticFieldProperties.h"
+#include "TrkGeometry/Material.h"
+#include "TrkGeometry/Layer.h"
+#include "TrkGeometry/CylinderLayer.h"
+#include "TrkGeometry/DiscLayer.h"
+#include "TrkSurfaces/DiscBounds.h"
+//Gaudi
+#include "GaudiKernel/SystemOfUnits.h"
+#include "GaudiKernel/MsgStream.h"
+#include <boost/lexical_cast.hpp>
+
+// constructor
+InDet::StagedTrackingGeometryBuilderCond::StagedTrackingGeometryBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  Trk::TrackingVolumeManipulator(),
+  m_trackingVolumeCreator("Trk::CylinderVolumeCreator/CylinderVolumeCreator"),  
+  m_layerArrayCreator("Trk::LayerArrayCreator/LayerArrayCreator"),
+  m_enclosingEnvelopeSvc("AtlasEnvelopeDefSvc", n),
+  m_layerEnvelopeCover(2*Gaudi::Units::mm),
+  m_buildBoundaryLayers(true),
+  m_replaceJointBoundaries(true),
+  m_materialProperties(0),
+  m_magneticFieldProperties(0),
+  m_indexStaticLayers(true),
+  m_checkForRingLayout(false),
+  m_ringTolerance(10*Gaudi::Units::mm),
+  m_namespace("InDet::"),
+  m_exitVolume("InDet::Containers::InnerDetector")
+{
+  declareInterface<Trk::IGeometryBuilderCond>(this);  
+  // layer builders and their configurations
+  declareProperty("LayerBuilders",                    m_layerProviders);
+  declareProperty("LayerBinningTypeCenter",           m_layerBinningTypeCenter);
+  declareProperty("LayerBinningTypeEndcap",           m_layerBinningTypeEndcap);
+  declareProperty("ColorCodes",                       m_colorCodesConfig);  
+  // envelope definition service
+  declareProperty("EnvelopeDefinitionSvc",            m_enclosingEnvelopeSvc );
+  declareProperty("VolumeEnclosureCylinderRadii",     m_enclosingCylinderRadius);
+  declareProperty("VolumeEnclosureDiscPositions",     m_enclosingDiscPositionZ);
+  // helper tools  
+  declareProperty("TrackingVolumeCreator",            m_trackingVolumeCreator);
+  declareProperty("LayerArrayCreator",                m_layerArrayCreator);  
+  // build the Boundary Layers
+  declareProperty("EnvelopeCover",                    m_layerEnvelopeCover);
+  declareProperty("BuildBoundaryLayers",              m_buildBoundaryLayers);
+  declareProperty("ReplaceAllJointBoundaries",        m_replaceJointBoundaries);
+  // force robust layer indexing  
+  declareProperty("IndexStaticLayers",                m_indexStaticLayers);
+  declareProperty("CheckForRingLayout",               m_checkForRingLayout);
+  // volume namespace & contaienr name
+  declareProperty("VolumeNamespace",                  m_namespace); 
+  declareProperty("ExitVolumeName",                   m_exitVolume);
+}
+
+// destructor
+InDet::StagedTrackingGeometryBuilderCond::~StagedTrackingGeometryBuilderCond()
+{
+  delete m_materialProperties;
+  delete m_magneticFieldProperties;
+}
+
+// Athena standard methods
+// initialize
+StatusCode InDet::StagedTrackingGeometryBuilderCond::initialize()
+{
+  
+   // retrieve envelope definition service --------------------------------------------------
+   if ( m_enclosingEnvelopeSvc.retrieve().isFailure() ){
+     ATH_MSG_FATAL( "Could not retrieve EnvelopeDefinition service. Abort.");
+     return StatusCode::FAILURE;
+   }
+           
+   // Retrieve the layer builders -----------------------------------------------------------
+   if (m_layerProviders.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool(s) " << m_layerProviders );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_DEBUG( "Retrieved tool " << m_layerProviders );
+
+   // Retrieve the tracking volume creator  -------------------------------------------------
+   if (m_trackingVolumeCreator.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeCreator );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_DEBUG( "Retrieved tool " << m_trackingVolumeCreator );
+      
+   // Retrieve the layer array creator  ----------------------------------------------------
+   if (m_layerArrayCreator.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_layerArrayCreator );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_INFO( "Retrieved tool " << m_layerArrayCreator );      
+
+    // Dummy MaterialProerties
+    m_materialProperties = new Trk::Material;
+
+    ATH_MSG_INFO( "initialize() succesful" );
+    
+  return StatusCode::SUCCESS;
+}
+
+//FIXME: ctx, tVolPair not used yet, range not created
+std::pair<EventIDRange, const Trk::TrackingGeometry*> InDet::StagedTrackingGeometryBuilderCond::trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> /*tVolPair*/) const
+{
+   // only one assumption: 
+   // layer builders are ordered in increasing r
+   ATH_MSG_DEBUG( "[ Start building the ID TrackingGeometry. ]"); 
+   ATH_MSG_DEBUG( "[ STEP 0 ] : Getting overal dimensions from DetectorEnvelope service." );
+   
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////    
+   // The Overall Geometry
+   Trk::TrackingGeometry* trackingGeometry = 0;   
+
+   // get the dimensions from the envelope service 
+   RZPairVector& envelopeDefs = m_enclosingEnvelopeSvc->getInDetRZValues();
+   ATH_MSG_VERBOSE("       -> retrieved Inner Detector envelope definitions at size " << envelopeDefs.size());
+   double envelopeVolumeRadius = envelopeDefs[1].first;
+   double envelopeVolumeHalfZ  = fabs(envelopeDefs[1].second);
+   ATH_MSG_VERBOSE("       -> envelope R/Z defined as : " << envelopeVolumeRadius << " / " << envelopeVolumeHalfZ );
+
+   ATH_MSG_DEBUG( "[ STEP 1 ] : Getting overal dimensions from the different layer builders." );
+   size_t ilS = 0;
+   double maximumLayerExtendZ   = 0.;
+   double maximumLayerRadius    = 0.;
+   std::vector<InDet::LayerSetup> layerSetups;
+   EventIDRange range;
+   for ( auto& lProvider : m_layerProviders){
+       // screen output 
+       ATH_MSG_DEBUG( "[ LayerBuilder : '" << lProvider->identification() << "' ] being processed. " );
+       // retrieve the layers
+       std::pair< EventIDRange, std::vector<const Trk::Layer*> > centralLayersPair  = lProvider->centralLayers(ctx);
+       std::pair< EventIDRange, std::vector<const Trk::Layer*> > negativeLayersPair = lProvider->negativeLayers(ctx);
+       std::pair< EventIDRange, std::vector<const Trk::Layer*> > positiveLayersPair = lProvider->positiveLayers(ctx);
+       range=EventIDRange::intersect(range,centralLayersPair.first, negativeLayersPair.first, positiveLayersPair.first);
+       ATH_MSG_VERBOSE("       -> retrieved "  << centralLayersPair.second.size()  << " central layers.");
+       ATH_MSG_VERBOSE("       -> retrieved "  << negativeLayersPair.second.size() << " layers on negative side.");
+       ATH_MSG_VERBOSE("       -> retrieved "  << positiveLayersPair.second.size() << " layers on positive side.");
+       // getting the Layer setup from parsing the builder output
+       InDet::LayerSetup lSetup = estimateLayerSetup(lProvider->identification(), ilS, 
+                                                     negativeLayersPair.second,centralLayersPair.second,positiveLayersPair.second,
+                                                     envelopeVolumeRadius, envelopeVolumeHalfZ);
+       // get the maxima - for R and Z
+       takeBigger(maximumLayerRadius, lSetup.rMax);
+       takeBigger(maximumLayerExtendZ, lSetup.zMax);
+       //layer setups for the second run
+       layerSetups.push_back(lSetup);
+       // increase counter
+       ++ilS;
+   }       
+   ATH_MSG_VERBOSE("       -> layer max R/Z defined as : " << maximumLayerRadius << " / " << maximumLayerExtendZ );
+   
+   // create a volume cache for:
+   // - ID volume, i.e. those that can be stacked into the overall container
+   std::vector<const Trk::TrackingVolume*> idVolumes;
+   
+   // create a layer setup cache for flushing when necessary
+   std::vector<InDet::LayerSetup> layerSetupCache;
+   
+   // we only need to take care of the last flush radius
+   double lastFlushRadius = 0.;
+   
+   // (I) PARSE THE LAYERS FOR OVERALL DIMENSIONS -------------------------------------------------------------
+   ATH_MSG_DEBUG( "[ STEP 2 ] : Looping through the layer setups and flush them into the ID detector volume vector." );
+   for ( auto& lSetup : layerSetups){
+        // screen output
+        ATH_MSG_DEBUG( "[ Layer setup: '" << lSetup.identification << "' ] being processed, current cache size is " << layerSetupCache.size() );
+        ATH_MSG_VERBOSE("       -> estimated dimensions for this layer setup are");
+        ATH_MSG_VERBOSE("       -> central sector rMin / rMax / zMax : " 
+            << lSetup.minRadiusCenter << " / " << lSetup.maxRadiusCenter << " / " << lSetup.zExtendCenter);
+        if (lSetup.buildEndcap)                                                                                                
+           ATH_MSG_VERBOSE("       -> endcap  sector rMin / rMax / zMin / zMax : " 
+               << lSetup.minRadiusEndcap << " / " << lSetup.maxRadiusEndcap << " / " << lSetup.minZextendEndcap << " / " << lSetup.maxZextendEndcap);
+        else 
+           ATH_MSG_VERBOSE("       -> endcap is not being built.");
+        
+        // now check what is in the cache 
+           // [a] nothing in the cache or new setup is compatible (in this case sectorZ are updated in all setups)
+        if (!layerSetupCache.size() || setupFitsCache(lSetup,layerSetupCache) ){
+            ATH_MSG_VERBOSE("       -> cache is empty or new sector fits cache setup - add this one to the cache.");
+        } else {
+            // [b] cache is not empty - let's see what is going on:
+            ATH_MSG_VERBOSE("       -> new sector does not fit the current cache specs -> flushing the cache." );
+            // create the outer boundary
+            double flushRadius = 0.5*(layerSetupCache[layerSetupCache.size()-1].rMax + lSetup.rMin);
+            // create a flush volume - clears the cache
+            const Trk::TrackingVolume* fVolume = createFlushVolume(layerSetupCache,lastFlushRadius,flushRadius,maximumLayerExtendZ);
+            // stuff it into the idVolume
+            idVolumes.push_back(fVolume);
+            // remember the last flush radius                                                                                    
+            lastFlushRadius = flushRadius; 
+        }
+        // in any case, this setup needs to go into the cache
+        layerSetupCache.push_back(lSetup);
+   }
+   
+   // check if the cache is empty
+   if (layerSetupCache.size()){
+       ATH_MSG_DEBUG( "[ STEP 3 ] : Flush the remaining cache into the ID detector volume vector." );
+       // set the maximum radius to the last layer radius    
+       double flushRadius = 0.5*(maximumLayerRadius  + envelopeVolumeRadius);
+       const Trk::TrackingVolume* fVolume = createFlushVolume(layerSetupCache,lastFlushRadius,flushRadius,maximumLayerExtendZ);
+       // push it into the vector
+       idVolumes.push_back(fVolume);
+       lastFlushRadius = flushRadius;
+   }
+   
+   ATH_MSG_DEBUG( "[ STEP 4 ] : Create the ID detector volumes" );
+   // build the central enclosure first
+   const Trk::TrackingVolume* centralEnclosure =  m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                           lastFlushRadius, envelopeVolumeRadius,
+                                                                           -maximumLayerExtendZ, maximumLayerExtendZ,
+                                                                           1, true,
+                                                                           m_namespace+"Gaps::CentralEnclosure");
+   idVolumes.push_back(centralEnclosure);
+   // now lets create the container
+   std::string volumeName = m_namespace+"Detectors::Container";
+   const Trk::TrackingVolume* idContainer = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(idVolumes,
+                                                                *m_materialProperties,
+                                                                volumeName,
+                                                                m_buildBoundaryLayers,
+                                                                m_replaceJointBoundaries);
+   // finally create the two endplates: negative
+   const Trk::TrackingVolume* negativeEnclosure =  m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                                                   0., envelopeVolumeRadius,
+                                                                                                   -envelopeVolumeHalfZ, -maximumLayerExtendZ,
+                                                                                                   1, false,
+                                                                                                   m_namespace+"Gaps::NegativeEnclosure");
+  
+   // finally create the two endplates: positive
+   const Trk::TrackingVolume* positiveEnclosure =  m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                                                   0., envelopeVolumeRadius,
+                                                                                                   maximumLayerExtendZ,envelopeVolumeHalfZ,
+                                                                                                   1, false,
+                                                                                                   m_namespace+"Gaps::PositiveEnclosure");
+   // and the final tracking volume
+   std::vector<const Trk::TrackingVolume*> enclosedVolumes;
+   enclosedVolumes.push_back(negativeEnclosure);
+   enclosedVolumes.push_back(idContainer);
+   enclosedVolumes.push_back(positiveEnclosure);
+   
+   const Trk::TrackingVolume* enclosedDetector = 
+       m_trackingVolumeCreator->createContainerTrackingVolume(enclosedVolumes,
+                                                              *m_materialProperties,
+                                                               m_exitVolume,
+                                                               m_buildBoundaryLayers,
+                                                               m_replaceJointBoundaries);
+
+   //  create the TrackingGeometry ------------------------------------------------------  
+   trackingGeometry = new Trk::TrackingGeometry(enclosedDetector);
+   
+   if (m_indexStaticLayers) {
+      ATH_MSG_VERBOSE("Re-index the static layers ...");
+      trackingGeometry->indexStaticLayers(Trk::Global);   
+   }                       
+
+   return std::make_pair(range, trackingGeometry);
+}
+
+// finalize
+StatusCode InDet::StagedTrackingGeometryBuilderCond::finalize()
+{
+    ATH_MSG_INFO( "finalize() successful" );
+    return StatusCode::SUCCESS;
+}
+
+
+const Trk::TrackingVolume* InDet::StagedTrackingGeometryBuilderCond::packVolumeTriple(const InDet::LayerSetup& layerSetup,
+                                                                                  double rMin, double& rMax,
+                                                                                  double zMax, double zPosCentral) const
+{
+
+
+  ATH_MSG_VERBOSE( '\t' << '\t'<< "Pack provided Layers from '" << layerSetup.identification << "' triple into a container volume. " );
+  
+  // create the strings
+  std::string volumeBase = m_namespace+"Detectors::"+layerSetup.identification;
+  
+  const Trk::TrackingVolume* negativeVolume = createTrackingVolume(layerSetup.negativeLayers, 
+                                                                   rMin,rMax,
+                                                                   -zMax,-zPosCentral,
+                                                                   volumeBase+"::NegativeEndcap",
+                                                                   (Trk::BinningType)layerSetup.binningEndcap,
+								   false);
+
+  const Trk::TrackingVolume* centralVolume = 
+         m_trackingVolumeCreator->createTrackingVolume(layerSetup.centralLayers,
+                                                       *m_materialProperties,
+                                                       rMin,rMax,
+                                                       -zPosCentral,zPosCentral,
+                                                       volumeBase+"::Barrel",
+                                                       (Trk::BinningType)layerSetup.binningCenter);
+                                                       
+   const Trk::TrackingVolume* positiveVolume = createTrackingVolume(layerSetup.positiveLayers,
+                                                                    rMin,rMax,
+                                                                    zPosCentral,zMax,
+                                                                    volumeBase+"::PositiveEndcap",
+                                                                    (Trk::BinningType)layerSetup.binningEndcap,
+								    false);
+   
+   // the base volumes have been created
+   ATH_MSG_VERBOSE('\t' << '\t'<< "Volumes have been created, now pack them into a triple.");
+   // registerColorCode                                                   
+   negativeVolume->registerColorCode(layerSetup.colorCode);   
+   centralVolume->registerColorCode(layerSetup.colorCode);
+   positiveVolume->registerColorCode(layerSetup.colorCode);
+                                                         
+   // pack them together
+   std::vector<const Trk::TrackingVolume*> tripleVolumes;
+   tripleVolumes.push_back(negativeVolume);
+   tripleVolumes.push_back(centralVolume);
+   tripleVolumes.push_back(positiveVolume);
+   
+   // create the tiple container
+   const Trk::TrackingVolume* tripleContainer = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(tripleVolumes,
+                                                                *m_materialProperties,
+                                                                volumeBase,
+                                                                m_buildBoundaryLayers,
+                                                                m_replaceJointBoundaries);
+                                                                
+   ATH_MSG_VERBOSE( '\t' << '\t'<< "Created container volume with bounds: " << tripleContainer->volumeBounds() );
+                                                                
+   return tripleContainer;
+}
+
+
+/** Private helper method, estimates the overal dimensions */
+InDet::LayerSetup InDet::StagedTrackingGeometryBuilderCond::estimateLayerSetup(const std::string& idName, size_t ilS,
+                                                                           const std::vector<const Trk::Layer*>& negLayers,
+                                                                           const std::vector<const Trk::Layer*>& cenLayers,
+                                                                           const std::vector<const Trk::Layer*>& posLayers,
+                                                                           double maxR, double maxZ) const
+{  
+  // prepare the dimensions
+  double cenMinR  = 10e10;
+  double cenMaxR  = 0.;
+  double cenMinZ  = 10e10;
+  double cenMaxZ  = 0.;
+  double posMinR  = 10e10;
+  double posMaxR  = 0.;
+  double posMinZ  = 10e10;
+  double posMaxZ  = 0.;
+  // parse through the central layers first
+  estimateLayerDimensions(cenLayers, cenMinR, cenMaxR, cenMinZ, cenMaxZ);
+  // parse throught the positive layers - we assume a symmetric setup 
+  estimateLayerDimensions(posLayers, posMinR, posMaxR, posMinZ, posMaxZ);
+  // reset to maxZ and and maxR if overs
+  if (posMaxZ > maxZ) {
+      ATH_MSG_WARNING("Estimated z extended of central sector bigger than maximal z extened. Resetting - may lose layers though.");
+      cenMaxZ = maxZ;
+  } else if (posMaxZ > maxZ) {
+      ATH_MSG_WARNING("Estimated z extended of endcap sector bigger than maximal z extened. Resetting - may lose layers though.");
+      posMaxZ = maxZ;
+  }
+  // reset the radial wones.
+  if (cenMaxR > maxR) {
+      ATH_MSG_WARNING("Estimated r extended of central sector bigger than maximal r extened. Resetting - may lose layers though.");
+      cenMaxR = maxR;
+  }
+  if (posMaxR > maxR) {
+      ATH_MSG_WARNING("Estimated r extended of endcap sector bigger than maximal r extened. Resetting - may lose layers though.");
+      posMaxR = maxR;
+  }
+  // create the layer setup class  
+  return InDet::LayerSetup(idName, m_colorCodesConfig[ilS], 
+                           negLayers, cenLayers, posLayers,
+                           cenMinR, cenMaxR, cenMaxZ, m_layerBinningTypeCenter[ilS], 
+                           posLayers.size(), posMinR, posMaxR, posMinZ, posMaxZ, m_layerBinningTypeEndcap[ilS]);
+}
+
+
+/** Private helper method to estimate the layer dimensions */
+void InDet::StagedTrackingGeometryBuilderCond::estimateLayerDimensions(const std::vector<const Trk::Layer*>& layers,
+                                                                   double& rMin, double& rMax, double& zMin, double& zMax) const
+{
+    // parse through the layers and estimate
+      for (auto& layer : layers){
+          // the thickness of the layer needs to be taken into account 
+          double thickness = layer->thickness();
+          // get the center
+          const Amg::Vector3D& center = layer->surfaceRepresentation().center();
+          // check if it is a cylinder layer
+          const Trk::CylinderLayer* cLayer = dynamic_cast<const Trk::CylinderLayer*>(layer);
+          if (cLayer){
+              // now we have access to all the information
+              double rMinC  = cLayer->surfaceRepresentation().bounds().r()-0.5*thickness-m_layerEnvelopeCover;
+              double rMaxC  = cLayer->surfaceRepresentation().bounds().r()+0.5*thickness+m_layerEnvelopeCover;
+              double hZ = cLayer->surfaceRepresentation().bounds().halflengthZ();
+              takeSmaller(rMin,rMinC);
+              takeBigger(rMax,rMaxC);
+              takeSmaller(zMin,center.z()-hZ);
+              takeBigger(zMax,center.z()+hZ);
+          } 
+          // proceed further if it is a Disc layer
+          const Trk::DiscBounds* dBounds = dynamic_cast<const Trk::DiscBounds*>(&(layer->surfaceRepresentation().bounds()));
+          if (dBounds){
+              // now we have access to all the information
+              double rMinD =dBounds->rMin();
+              double rMaxD =dBounds->rMax();
+              double zMinD =  center.z()-0.5*thickness-m_layerEnvelopeCover;
+              double zMaxD =  center.z()+0.5*thickness+m_layerEnvelopeCover;
+              takeSmaller(rMin,rMinD);
+              takeBigger(rMax,rMaxD);
+              takeSmaller(zMin,zMinD);
+              takeBigger(zMax,zMaxD);
+          }
+      }
+}  
+ 
+
+/** Private helper method to check if a sector is compatible with the cache */
+bool InDet::StagedTrackingGeometryBuilderCond::setupFitsCache(LayerSetup& layerSetup, std::vector<InDet::LayerSetup>& layerSetupCache) const
+{
+    // the maximum center and overall extend of the cache
+    double maxCenterCacheZ = 0.; 
+    // the maximum endcap extend of the cache
+    double minEndcapCacheZ = 10e10;
+    // chech if he have a fullSectorSetup
+    bool fullSectorSetup   = false;
+    // 
+    for (auto& lCacheSetup : layerSetupCache){
+        takeBigger(maxCenterCacheZ, lCacheSetup.zExtendCenter);
+        takeSmaller(minEndcapCacheZ, lCacheSetup.minZextendEndcap);
+        // once true always true - otherwise it would have been flushed
+        fullSectorSetup = lCacheSetup.buildEndcap ? true : fullSectorSetup;
+        
+    }    
+    // if we do not have a full sector setup - > flush directly
+    if (!fullSectorSetup) {
+        ATH_MSG_VERBOSE("       -> only central sector being built, flush the cache ... ");
+        return false;
+    }
+    // if the cached minimum z endcap z extend cuts within the new barrel -> flush it 
+    if (minEndcapCacheZ < layerSetup.zExtendCenter){
+        ATH_MSG_VERBOSE("       -> cache endcap extend reaches into new central sector, flush the cache ... ");
+        return false;
+    }
+    // the cache center maximumg exceeds the new endcap minimum -> does not fit
+    if (maxCenterCacheZ < layerSetup.minZextendEndcap ) {
+        ATH_MSG_VERBOSE("       -> sector fully fits into cache! Add it and start synchronising ...");
+        // calculate the new sector gap and synchronise
+        double newCenterMaxZ = maxCenterCacheZ > layerSetup.zExtendCenter ? maxCenterCacheZ : layerSetup.zExtendCenter;
+        double newEndcapMinZ = minEndcapCacheZ < layerSetup.minZextendEndcap ? minEndcapCacheZ : layerSetup.minZextendEndcap;
+        double newSectorZ    = 0.5*(newCenterMaxZ+newEndcapMinZ);
+        // and syncrhonise the boundaries 
+        for (auto& lCacheSetup : layerSetupCache)
+            lCacheSetup.zSector = newSectorZ;
+        layerSetup.zSector = newSectorZ;
+        return true;
+    }
+    // it simply does not fit so return false
+    return false;
+}
+ 
+bool InDet::StagedTrackingGeometryBuilderCond::ringLayout(const std::vector<const Trk::Layer*>& layers, std::vector<double>& rmins, std::vector<double>& rmaxs) const {
+    // get the maximum extent in z
+    ATH_MSG_INFO("Checking for Ring layout ... ");
+    for (auto& ring : layers){
+        // Surface
+        const Trk::Surface&     ringSurface = ring->surfaceRepresentation(); 
+        const Trk::DiscBounds*  ringBounds  = dynamic_cast<const Trk::DiscBounds*>(&(ringSurface.bounds()));
+        if (ringBounds){
+            // get the main parameters
+            double zpos         = ringSurface.center().z();
+            double rMin         = ringBounds->rMin();
+            double rMax         = ringBounds->rMax();
+            // take and check
+            checkForInsert(rmins,rMin);
+            checkForInsert(rmaxs,rMax);
+            ATH_MSG_INFO(" -> Ring at z-position " << zpos << " - with rMin/rMax = " << rMin << "/" << rMax );
+        }
+    }
+    return (rmins.size() > 1 );
+}                                              
+ 
+ 
+
+const Trk::TrackingVolume* InDet::StagedTrackingGeometryBuilderCond::createTrackingVolume(const std::vector<const Trk::Layer*>& layers, 
+                                                                                      double innerRadius, double& outerRadius,
+                                                                                      double zMin, double zMax,
+                                                                                      const std::string& volumeName,
+                                                                                      Trk::BinningType binningType,
+										       bool doAdjustOuterRadius) const
+{
+
+    // first loop - this is for diagnostics for the radii 
+    std::vector<double> ringRmins;
+    std::vector<double> ringRmaxa;
+    if (m_checkForRingLayout && ringLayout(layers,ringRmins, ringRmaxa)){
+        ATH_MSG_INFO("Ring layout is present for volume '" << volumeName << "' dealing with it.");
+        // create the vector for the sub volumes
+        std::vector<const Trk::TrackingVolume* > ringVolumes;
+
+        // now sort the necessary layers --- for the sub volumes
+        std::vector< std::vector< const Trk::Layer*> > groupedDiscs(ringRmins.size(), std::vector< const Trk::Layer*>() );
+        // second loop over the rings
+        for (auto& ring : layers){
+            // Surface
+            const Trk::Surface&     ringSurface = ring->surfaceRepresentation(); 
+            const Trk::DiscBounds*  ringBounds  = dynamic_cast<const Trk::DiscBounds*>(&(ringSurface.bounds()));
+            if (ringBounds){
+                // get the main parameters
+                double rMax         = ringBounds->rMax();
+                size_t rPos         = 0;
+                // fill into the right group
+                for (auto& rm : ringRmaxa){
+                    if (rMax < rm+m_ringTolerance) break;
+                    ++rPos;
+                }
+                // fill it it 
+                const Trk::DiscLayer* dring = dynamic_cast<const Trk::DiscLayer*>(ring);
+                if (dring) groupedDiscs[rPos].push_back(dring);
+            }
+        }
+        // we are now grouped in cylinder rings per volume
+        for (int idset = 0; idset < int(groupedDiscs.size()); idset++){
+            // always keep the boundaries in mind for the radial extend
+            double crmin = idset ? ringRmaxa[idset-1]+m_layerEnvelopeCover : innerRadius;
+            double crmax = ringRmaxa[idset]+m_layerEnvelopeCover;
+	    if(idset==int(groupedDiscs.size())-1 && !doAdjustOuterRadius) crmax = outerRadius; 
+            // now create the sub volume
+            std::string ringVolumeName = volumeName+"Ring"+boost::lexical_cast<std::string>(idset);
+            const Trk::TrackingVolume* ringVolume = m_trackingVolumeCreator->createTrackingVolume(groupedDiscs[idset],
+                                                                                                  *m_materialProperties,
+                                                                                                  crmin,crmax,
+                                                                                                  zMin,zMax,
+                                                                                                  ringVolumeName,
+                                                                                                  binningType);
+             // push back into the 
+             ringVolumes.push_back(ringVolume);
+        }
+        // set the outer radius
+        if(doAdjustOuterRadius) outerRadius = ringRmaxa[ringRmaxa.size()-1]+m_layerEnvelopeCover;
+        //
+        ATH_MSG_INFO("      -> adjusting the outer radius to the last ring at " << outerRadius );
+        ATH_MSG_INFO("      -> created " << ringVolumes.size() << " ring volumes for Volume '" << volumeName << "'.");
+        // create the tiple container
+        return m_trackingVolumeCreator->createContainerTrackingVolume(ringVolumes,
+                                                                      *m_materialProperties,
+                                                                      volumeName,
+                                                                      m_buildBoundaryLayers,
+                                                                      m_replaceJointBoundaries);
+        
+        
+    } else 
+        return m_trackingVolumeCreator->createTrackingVolume(layers,
+                                                             *m_materialProperties,
+                                                             innerRadius,outerRadius,
+                                                             zMin,zMax,
+                                                             volumeName,
+                                                             binningType);
+}     
+ 
+                             
+/** Private helper method to flush the cache into the id volumes - return volume is the one to be provided */
+const Trk::TrackingVolume* InDet::StagedTrackingGeometryBuilderCond::createFlushVolume(std::vector<InDet::LayerSetup>& layerSetupCache,
+                                                                                   double innerRadius, double& outerRadius, double extendZ) const
+{
+  // the return volume 
+  const Trk::TrackingVolume* flushVolume = 0;
+  // 
+  if (layerSetupCache.size() == 1 ){
+    ATH_MSG_VERBOSE("       -> single sector setup - synchronising from inner (" << innerRadius << ") to outer (" << outerRadius << ") radius.");
+    ATH_MSG_VERBOSE("       -> setup identification : " << layerSetupCache[0].identification );
+    // create the new tracking volume - either as a triple or as a single
+        flushVolume = layerSetupCache[0].buildEndcap ? 
+        packVolumeTriple(layerSetupCache[0],
+                         innerRadius, outerRadius,
+                         extendZ,layerSetupCache[0].zSector) :
+        m_trackingVolumeCreator->createTrackingVolume(layerSetupCache[0].centralLayers,
+                                                      *m_materialProperties,
+                                                      innerRadius,outerRadius,
+                                                      -extendZ,extendZ,
+                                                      layerSetupCache[0].identification,
+                                                      (Trk::BinningType)layerSetupCache[0].binningCenter);    
+    
+   } else {
+       ATH_MSG_VERBOSE("       -> setup with " << layerSetupCache.size() << " entries - synchronising from inner (" << innerRadius << ") to outer (" << outerRadius << ") radius.");
+       // prepare the volume vectors & name identification
+       std::vector<const Trk::TrackingVolume*> negVolumes;
+       std::vector<const Trk::TrackingVolume*> centralVolumes;
+       std::vector<const Trk::TrackingVolume*> posVolumes;
+       std::string combinedName;
+       for (size_t ilS = 0; ilS < layerSetupCache.size(); ++ilS){
+           // take the given inner radius for the first one - median otherwise
+           double irE = ilS ? 0.5*(layerSetupCache[ilS].minRadiusEndcap+layerSetupCache[ilS-1].maxRadiusEndcap) : innerRadius;
+           double irC = ilS ? 0.5*(layerSetupCache[ilS].minRadiusCenter+layerSetupCache[ilS-1].maxRadiusCenter) : innerRadius;
+           // take the given outer radius for the last one - median otherwise
+           double orE = ((ilS+1)==layerSetupCache.size()) ? outerRadius : 0.5*(layerSetupCache[ilS+1].minRadiusEndcap+layerSetupCache[ilS].maxRadiusEndcap);
+           double orC = ((ilS+1)==layerSetupCache.size()) ? outerRadius : 0.5*(layerSetupCache[ilS+1].minRadiusCenter+layerSetupCache[ilS].maxRadiusCenter);
+	   // Adjust last volumes in R to the same maximal radial extends!
+	   if(ilS==layerSetupCache.size()-1) {
+	     ATH_MSG_VERBOSE("Processing last volume");
+	     ATH_MSG_VERBOSE("  --> adjust volumes to same extends: orE=" << orE << " orC=" << orC);
+	     if(orE>orC) orC=orE; else orE=orC;
+	   }
+           // create the three volumes
+           const Trk::TrackingVolume* nVolume = createTrackingVolume(layerSetupCache[ilS].negativeLayers,
+                                                                     irE,orE,
+                                                                     -extendZ,-layerSetupCache[ilS].zSector,
+                                                                     layerSetupCache[ilS].identification+"::NegativeEndcap",
+                                                                     (Trk::BinningType)layerSetupCache[ilS].binningEndcap,false);               
+           const Trk::TrackingVolume* cVolume = m_trackingVolumeCreator->createTrackingVolume(layerSetupCache[ilS].centralLayers,
+                                                                                  *m_materialProperties,
+                                                                                  irC,orC,
+                                                                                  -layerSetupCache[ilS].zSector,layerSetupCache[ilS].zSector,
+                                                                                  layerSetupCache[ilS].identification+"::Barrel",
+                                                                                  (Trk::BinningType)layerSetupCache[ilS].binningCenter);
+           const Trk::TrackingVolume* pVolume = createTrackingVolume(layerSetupCache[ilS].positiveLayers,
+                                                                     irE,orE,
+                                                                     layerSetupCache[ilS].zSector,extendZ,
+                                                                     layerSetupCache[ilS].identification+"::PositiveEndcap",
+                                                                     (Trk::BinningType)layerSetupCache[ilS].binningEndcap,false);
+           // register the right color code
+           nVolume->registerColorCode(layerSetupCache[ilS].colorCode);
+           cVolume->registerColorCode(layerSetupCache[ilS].colorCode);
+           pVolume->registerColorCode(layerSetupCache[ilS].colorCode);
+           // push them into the volume containers 
+           negVolumes.push_back(nVolume);
+           centralVolumes.push_back(cVolume);
+           posVolumes.push_back(pVolume);
+           // combined name
+           combinedName += "_"+layerSetupCache[ilS].identification;
+       }
+       ATH_MSG_VERBOSE("       -> setup identification : " << combinedName );
+       flushVolume  = packVolumeTriple(negVolumes,centralVolumes,posVolumes,combinedName);
+   }
+   // clear the cache
+   layerSetupCache.clear();      
+   // return the volume               
+   return flushVolume;
+    
+}  
+
+const Trk::TrackingVolume* InDet::StagedTrackingGeometryBuilderCond::packVolumeTriple(
+                                     const std::vector<const Trk::TrackingVolume*>& negVolumes,
+                                     const std::vector<const Trk::TrackingVolume*>& centralVolumes,
+                                     const std::vector<const Trk::TrackingVolume*>& posVolumes,
+                                     const std::string& baseName) const
+{
+  ATH_MSG_VERBOSE( '\t' << '\t'<< "Pack provided Volumes from '" << baseName << "' triple into a container volume. " );
+
+  unsigned int negVolSize = negVolumes.size();
+  unsigned int cenVolSize = centralVolumes.size();
+  unsigned int posVolSize = posVolumes.size();
+  
+  
+  
+    // create the strings
+  std::string volumeBase = m_namespace+"Containers::"+baseName;
+  
+  const Trk::TrackingVolume* negativeVolume = (negVolSize > 1) ?
+       m_trackingVolumeCreator->createContainerTrackingVolume(negVolumes,
+                                                       *m_materialProperties,
+                                                       volumeBase+"::NegativeSector",
+                                                       m_buildBoundaryLayers,
+                                                       m_replaceJointBoundaries) : 
+                                             (negVolSize ? negVolumes[0] : 0);
+  const Trk::TrackingVolume* centralVolume = (cenVolSize > 1) ?
+         m_trackingVolumeCreator->createContainerTrackingVolume(centralVolumes,
+                                                       *m_materialProperties,
+                                                       volumeBase+"::CentralSector",
+                                                       m_buildBoundaryLayers,
+                                                       m_replaceJointBoundaries) :
+                                              (cenVolSize ? centralVolumes[0] : 0) ;
+                                              
+   const Trk::TrackingVolume* positiveVolume = ( posVolSize > 1) ?
+         m_trackingVolumeCreator->createContainerTrackingVolume(posVolumes,
+                                                       *m_materialProperties,
+                                                       volumeBase+"::PositiveSector",
+                                                       m_buildBoundaryLayers,
+                                                       m_replaceJointBoundaries) : 
+                                               (posVolSize ? posVolumes[0] : 0);
+   
+   if (!negativeVolume && !positiveVolume){
+       ATH_MSG_DEBUG( "No negative/positive sector given - no packing needed, returning central container!" );
+       return centralVolume;
+   }
+   // pack them together
+   std::vector<const Trk::TrackingVolume*> tripleVolumes;
+   if (negativeVolume) tripleVolumes.push_back(negativeVolume);
+   if (centralVolume) tripleVolumes.push_back(centralVolume);
+   if (positiveVolume) tripleVolumes.push_back(positiveVolume);
+   // create the tiple container
+   const Trk::TrackingVolume* tripleContainer = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(tripleVolumes,
+                                                                *m_materialProperties,
+                                                                volumeBase,
+                                                                m_buildBoundaryLayers,
+                                                                m_replaceJointBoundaries);
+   return tripleContainer;
+}
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/TRT_LayerBuilderCond.cxx b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/TRT_LayerBuilderCond.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..90ac1dc3137d848986ae89d920a7a0742230d346
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/TRT_LayerBuilderCond.cxx
@@ -0,0 +1,729 @@
+/*
+ Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// TRT_LayerBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#include "InDetTrackingGeometry/TRT_LayerBuilderCond.h"
+#include "InDetTrackingGeometry/TRT_OverlapDescriptor.h"
+//Trk
+#include "TrkSurfaces/Surface.h"
+#include "TrkSurfaces/RectangleBounds.h"
+#include "TrkSurfaces/DiscBounds.h"
+#include "TrkGeometry/CylinderLayer.h"
+#include "TrkGeometry/PlaneLayer.h"
+#include "TrkGeometry/DiscLayer.h"
+#include "TrkGeometry/BinnedLayerMaterial.h"
+#include "TrkGeometry/ApproachDescriptor.h"
+#include "TrkDetDescrUtils/GeometryStatics.h"
+#include "TrkDetDescrUtils/BinnedArrayArray.h"
+#include "TrkDetDescrUtils/BinnedArray2D.h"
+#include "TrkDetDescrUtils/BinnedArray1D.h"
+#include "TrkDetDescrUtils/BinUtility.h"
+#include "TrkDetDescrUtils/BinUtility.h"
+// GeoPrimitives
+#include "GeoPrimitives/GeoPrimitivesHelpers.h"
+#include "GeoPrimitives/GeoPrimitivesToStringConverter.h"
+// InDetDD
+#include "TRT_ReadoutGeometry/TRT_DetectorManager.h"
+#include "TRT_ReadoutGeometry/TRT_Numerology.h"
+#include "InDetIdentifier/TRT_ID.h"
+// Gaudi
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/SmartDataPtr.h"
+#include "GaudiKernel/SystemOfUnits.h"
+// STL
+#include <map>
+
+namespace {
+  template <class T>
+  class PtrVectorWrapper 
+  {
+  public:
+    PtrVectorWrapper () 
+      : m_ptr(new std::vector<const T *>)
+    {
+    }
+    
+    ~PtrVectorWrapper() {
+      if (m_ptr) {
+	for (const T *elm : *m_ptr ) {
+	  delete elm;
+	}
+	m_ptr->clear();
+      }
+    }
+    std::vector<const T *> &operator*() { return *m_ptr; }
+    const std::vector<const T *> &operator*() const { return *m_ptr; }
+    
+    std::vector<const T *> *operator->() { return m_ptr.get(); }
+    const std::vector<const T *> *operator->() const { return m_ptr.get(); }
+    
+    std::vector<const T *> *release() { return m_ptr.release(); }
+    
+  private:
+    std::unique_ptr<std::vector<const T *> > m_ptr;
+  };
+  
+}
+
+// constructor
+InDet::TRT_LayerBuilderCond::TRT_LayerBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  m_trtMgr(0),
+  m_trtMgrLocation("TRT"),
+  m_layerStrawRadius(2.0*Gaudi::Units::mm),
+  m_layerThickness(0.1*Gaudi::Units::mm),
+  m_modelGeometry(true),
+  m_modelBarrelLayers(7),
+  m_modelEndcapLayers(14),
+  m_barrelLayerBinsZ(25),
+  m_barrelLayerBinsPhi(1),
+  m_endcapLayerBinsR(25),
+  m_endcapLayerBinsPhi(1),
+  m_endcapConly(false),
+  m_registerStraws(false),
+  m_barrelSectorAtPiBoundary(16),
+  m_identification("TRT")
+{
+  declareInterface<Trk::ILayerBuilderCond>(this);
+  // properties from outside
+  declareProperty("TRT_DetManagerLocation",       m_trtMgrLocation);
+  declareProperty("LayerThickness",               m_layerThickness);
+  // material binning
+  declareProperty("BarrelLayerBinsZ"            , m_barrelLayerBinsZ);
+  declareProperty("BarrelLayerBinsPhi"          , m_barrelLayerBinsPhi);
+  declareProperty("EndcapLayerBinsR"            , m_endcapLayerBinsR);
+  declareProperty("EndcapLayerBinsPhi"          , m_endcapLayerBinsPhi);
+  // steering
+  declareProperty("ModelLayersOnly",              m_modelGeometry);
+  declareProperty("ModelBarrelLayers",            m_modelBarrelLayers);
+  declareProperty("ModelEndcapLayers",            m_modelEndcapLayers);
+  declareProperty("EndcapConly",                  m_endcapConly);
+  declareProperty("RegisterStraws",               m_registerStraws);
+  declareProperty("BarrelSectorAtPi",             m_barrelSectorAtPiBoundary);
+  // identification
+  declareProperty("Identification"              , m_identification);
+}
+
+// destructor
+InDet::TRT_LayerBuilderCond::~TRT_LayerBuilderCond()
+{}
+
+// Athena standard methods
+// initialize
+StatusCode InDet::TRT_LayerBuilderCond::initialize()
+{
+   ATH_MSG_INFO( "initialize()" );
+   // get TRT Detector Description Manager
+   if ((detStore()->retrieve(m_trtMgr, m_trtMgrLocation)).isFailure())
+     ATH_MSG_ERROR( "Could not get TRT_DetectorManager, no layers for TRT Detector will be built. " );
+
+   return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode InDet::TRT_LayerBuilderCond::finalize()
+{
+    ATH_MSG_INFO( "finalize() successful" );
+
+    return StatusCode::SUCCESS;
+}
+
+
+/** LayerBuilderCond interface method - returning Barrel-like layers */
+//FIXME: context object is unused, elements are retrieved from m_trtMgr instead of CondSvc
+std::pair<EventIDRange, const std::vector< const Trk::CylinderLayer* >* > InDet::TRT_LayerBuilderCond::cylindricalLayers(const EventContext&) const
+{
+
+  //create dummy infinite range
+  EventIDRange range;
+  if (!m_trtMgr) return std::pair<EventIDRange,const std::vector<const Trk::CylinderLayer* >* >(range,nullptr);
+
+  ATH_MSG_DEBUG( "Building cylindrical layers for the TRT " );
+
+  PtrVectorWrapper<Trk::CylinderLayer> barrelLayers;
+
+  // get Numerology and Id HElper
+  const InDetDD::TRT_Numerology* trtNums = m_trtMgr->getNumerology();
+
+  // get the TRT ID Helper
+  const TRT_ID* trtIdHelper = 0;
+  if (detStore()->retrieve(trtIdHelper, "TRT_ID").isFailure()) {
+     ATH_MSG_ERROR("Could not get TRT ID helper");
+     return std::pair<EventIDRange,const std::vector<const Trk::CylinderLayer* >* >(range,nullptr);
+  }
+
+  int    nBarrelRings  = trtNums->getNBarrelRings();
+  int    nBarrelPhiSectors = trtNums->getNBarrelPhi();
+  double layerPhiStep      = 2*M_PI/nBarrelPhiSectors;
+  
+  int nTotalBarrelLayers = 0;
+
+  // get the overall dimensions
+  double rMin = 10e10;
+  double rMax = 0.;
+
+  double layerZmax = 0.;
+  double layerZmin = 10e10;
+
+  // pre-loop for overall layer numbers & some ordering ---------------------------------------
+  for (int ring=0; ring < nBarrelRings; ring++) {
+     // the number of barrel layers 
+     int nBarrelLayers = trtNums->getNBarrelLayers(ring);
+     nTotalBarrelLayers += nBarrelLayers;
+     // loop over layers
+      for (int layer=0; layer < nBarrelLayers; layer++){
+       for (int phisec=0; phisec <nBarrelPhiSectors; ++phisec)
+       {
+         for (int iposneg=0; iposneg<2; ++iposneg){
+            // get the element
+            const InDetDD::TRT_BarrelElement* trtbar = m_trtMgr->getBarrelElement(iposneg, ring, phisec, layer);
+            
+            // get overall dimensions only one time
+            const Trk::PlaneSurface*    elementSurface = dynamic_cast<const Trk::PlaneSurface*>(&(trtbar->surface()));
+            if (!elementSurface) {
+                ATH_MSG_WARNING( "elementSurface: dynamic_cast to Trk::PlaneSurface failed - skipping ... ring/layer/phisec/iposneg = " << ring << "/" << layer << "/" << phisec << "/" << iposneg );
+                continue;
+            }
+            const Trk::RectangleBounds* elementBounds  = dynamic_cast<const Trk::RectangleBounds*>(&(trtbar->bounds()));
+            if (!elementBounds) {
+                ATH_MSG_WARNING( "elementBounds: dynamic_cast to Trk::RectangleBounds failed - skipping ... ring/layer/phisec/iposneg = " << ring << "/" << layer << "/" << phisec << "/" << iposneg );
+                continue;
+            }
+            double elementZcenter = (elementSurface->center()).z();
+            double elementZmin    = fabs(elementZcenter - elementBounds->halflengthY());
+            double elementZmax    = fabs(elementZcenter + elementBounds->halflengthY());
+            // take what you need
+            takeSmaller(layerZmin, elementZmin); takeBigger(layerZmax, elementZmax);
+            // get the radial dimensions
+            double currentR = trtbar->center().perp();
+            takeSmallerBigger(rMin,rMax,currentR);
+         }
+       }
+    }
+  }
+  
+  if (nTotalBarrelLayers==0) {
+      ATH_MSG_WARNING( "nTotalBarrelLayers = 0 ... aborting and returning 0 !" );
+      return std::pair<EventIDRange,const std::vector<const Trk::CylinderLayer* >* >(range,nullptr);
+  }
+  
+  // calculate delta(R) steps and delta(R)
+  double rDiff           = fabs(rMax-rMin);
+  double rStep           = rDiff/(m_modelBarrelLayers+1);
+  double layerHalflength = layerZmax;
+
+  // prepare the material
+  if ( fabs(rDiff) <= 0.1 ){
+    return std::pair<EventIDRange,const std::vector<const Trk::CylinderLayer* >* >(range,nullptr);
+  }
+
+  // ilay - for accessing the straw layers and for material decission
+  int ilay = 0;
+
+  //  fix the positions where the layers are - these are used for the model geometry and the complex geometry ---------------
+  std::vector<double> layerRadii;
+  layerRadii.reserve(m_modelBarrelLayers);
+  for (unsigned int ilay = 1; ilay <= m_modelBarrelLayers; ++ilay)
+       layerRadii.push_back(rMin+ilay*rStep-0.5*m_layerThickness);
+  // these are the layer iterators
+  auto layerRadiusIter    = layerRadii.begin();
+  auto layerRadiusIterEnd = layerRadii.end();
+
+  // (A) model geometry section
+  if (m_modelGeometry && !m_registerStraws){
+
+      ATH_MSG_VERBOSE( " -> " << layerRadii.size() << " cylindrical barrel layers between " << rMin << " and " << rMax << " ( at step "<< rStep << " )");
+
+     // create the layers
+     for ( ; layerRadiusIter != layerRadiusIterEnd; ++layerRadiusIter ) {
+       // ----- prepare the BinnedLayerMaterial -----------------------------------------------------
+       Trk::BinnedLayerMaterial* layerMaterial = 0;
+       // -- material with 1D binning
+       Trk::BinUtility layerBinUtility1DZ(m_barrelLayerBinsZ,-layerHalflength, layerHalflength, Trk::open, Trk::binZ);
+       if (m_barrelLayerBinsPhi==1){
+         // no binning in phi  
+         layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtility1DZ);
+       } else { // -- material with 2D binning : Rphi*Z optimized for cylinder layer
+         Trk::BinUtility layerBinUtility2DRPhiZ(m_barrelLayerBinsPhi,
+                                                -(*layerRadiusIter)*M_PI,
+                                                (*layerRadiusIter)*M_PI,
+                                                Trk::closed,
+                                                Trk::binRPhi);
+         layerBinUtility2DRPhiZ += layerBinUtility1DZ;                                         
+         layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtility2DRPhiZ);
+       }
+       // Barrel layers are centered around (0,0,0) by definition
+       barrelLayers->push_back(new Trk::CylinderLayer(new Trk::CylinderBounds(*layerRadiusIter,layerHalflength),
+                                                      *layerMaterial,
+                                                      m_layerThickness));
+       ATH_MSG_VERBOSE( " --> Creating a layer at radius : " << *layerRadiusIter );
+       delete layerMaterial;
+     }
+  } else {
+    // (B) complex geometry section
+    
+    int nMaterialLayerStep  = int(nTotalBarrelLayers/m_modelBarrelLayers+1);
+    int cMaterialLayerCount = 0;
+    
+    // loop over rings
+    ATH_MSG_VERBOSE("TRT Barrel has " << nBarrelRings << " rings.");
+    
+    for (int ring=0; ring < nBarrelRings; ring++){
+        
+         int nBarrelLayers = trtNums->getNBarrelLayers(ring);
+         ATH_MSG_VERBOSE("-> Ring " << ring << " has " << nBarrelLayers << " barrel layers.");
+         // loop over layers
+         for (int layer=0; layer < nBarrelLayers; layer++){
+
+             // ----------------------------------------------------------------------------------
+              ATH_MSG_VERBOSE("--> Layer " << layer << " is being built with " << nBarrelPhiSectors << " secors in phi.");
+              ++cMaterialLayerCount;
+
+              // set layer dimensions radius
+              double layerRadius         =  0.;
+              double layerRadiusMin      =  10e10;
+              double layerRadiusMax      =  0.;
+              double layerPhiMin         =  10.;
+              double layerPhiMax         = -10;
+              
+              // per phi sector we make a 2D binnin in phi-z 
+              std::vector< std::pair<Trk::BinnedArray<Trk::Surface>*, Amg::Vector3D >  > layerSectorArrays;
+              Amg::Vector3D layerSectorPosition(0.,0.,0.);
+              
+              // the sector approaching surfaces
+              std::vector< std::pair< Trk::SharedObject<const Trk::ApproachSurfaces>, Amg::Vector3D > > layerApproachSurfaces; 
+
+              // layer sector arrays
+              for (int phisec=0; phisec < nBarrelPhiSectors; phisec++){
+                 // ----------------------------------------------------------------------------------
+                 ATH_MSG_VERBOSE("---> Sector " << phisec << " gahtering the details.");
+                 // -------------- a phi sector (expands in +/- z) -----------------------------------
+                 
+                 // order the straws onto layers
+                 std::vector< Trk::SurfaceOrderPosition > strawsPerPhiSecLayer;
+                 // get the min an max phi, the min and max z
+                 double phiMin       =  10.;
+                 double phiMax       = -10.;  
+                 // sector stuff
+                 int    sectorStraws = 0;
+                 // positive and negative sector      
+                 for (int posneg=0; posneg<2; ++posneg){
+                     // sort the elements
+                     const InDetDD::TRT_BarrelElement* currentElement = m_trtMgr->getBarrelElement(posneg, ring, phisec, layer);
+                     // get overall dimensions only one time
+                     const Trk::PlaneSurface*    elementSurface = dynamic_cast<const Trk::PlaneSurface*>(&(currentElement->surface()));
+                     if (!elementSurface) {
+                         ATH_MSG_WARNING( "elementSurface: dynamic_cast to Trk::PlaneSurface failed - skipping ... ring/layer/phisec/posneg = " << ring << "/" << layer << "/" << phisec << "/" << posneg );
+                         continue;
+                     }
+                     
+                     // create teh approach surfaces --------------------------------------------------------------------------------------------------
+                     // getTransformFromRotTransl(Amg::RotationMatrix3D rot, Amg::Vector3D transl_vec )
+                     Trk::ApproachSurfaces* aSurfaces         = new Trk::ApproachSurfaces;
+                     const Amg::Transform3D& elementTransform = elementSurface->transform();
+                     const Amg::Vector3D&    elementCenter    = elementSurface->center();
+                     const Amg::Vector3D&    elementNormal    = elementSurface->normal();     
+                     Amg::RotationMatrix3D   elementRotation  = elementTransform.rotation();
+                     // outer / inner
+                     Amg::Vector3D outerCenter(elementCenter+(0.5*m_layerThickness+m_layerStrawRadius)*elementNormal);
+                     Amg::Vector3D innerCenter(elementCenter-(0.5*m_layerThickness+m_layerStrawRadius)*elementNormal);
+
+                     // assign the layer sector position for the straw array ordering
+                     layerSectorPosition = elementSurface->center();
+                             
+                     // now register the two surfaces
+                     aSurfaces->push_back(new Trk::PlaneSurface(new Amg::Transform3D(Amg::getTransformFromRotTransl(elementRotation, innerCenter))));
+                     aSurfaces->push_back(new Trk::PlaneSurface(new Amg::Transform3D(Amg::getTransformFromRotTransl(elementRotation, outerCenter))));
+                     
+                     // now register it to for building the array
+                     layerApproachSurfaces.push_back( std::pair< Trk::SharedObject<const Trk::ApproachSurfaces>, Amg::Vector3D >( Trk::SharedObject<const Trk::ApproachSurfaces>(aSurfaces),elementCenter));
+                     // screen output 
+                     ATH_MSG_VERBOSE("---> Sector " << phisec << " - posneg - " << posneg << " - with central phi = " << elementSurface->center().phi() );
+                     // sector phi centers
+                     takeSmallerBigger(layerPhiMin,layerPhiMax,elementSurface->center().phi());
+                     
+                     // loop over straws, fill them and find the phi boundaries
+                     for (unsigned int istraw=0; istraw<currentElement->nStraws(); ++istraw)
+                     {
+                       Identifier strawId = trtIdHelper->straw_id(currentElement->identify(), istraw);
+                       const Trk::Surface* currentStraw = &(currentElement->surface(strawId));
+                       // get the phi values 
+                       double currentPhi = currentStraw->center().phi();
+                       if (phisec == m_barrelSectorAtPiBoundary && currentPhi < 0.){
+                           currentPhi  = M_PI + currentPhi;
+                           currentPhi += M_PI;
+                       }
+                       // the layer radius 
+                       takeSmallerBigger(layerRadiusMin,layerRadiusMax,currentStraw->center().perp());
+                       takeSmallerBigger(phiMin, phiMax, currentPhi);
+                       // make the ordering position
+                       Amg::Vector3D strawOrderPos(currentStraw->center());
+                       //Trk::SharedObject<const Trk::Surface> sharedSurface(currentStraw, true);
+                       /*
+                        * The above line was using the nodel (not delete option for the old shared object
+                        * now that SharedObject is a shared_ptr typeded do the same with empty deleter
+                        */
+                       Trk::SharedObject<const Trk::Surface> sharedSurface(currentStraw, Trk::do_not_delete<const Trk::Surface>);
+                       strawsPerPhiSecLayer.push_back(Trk::SurfaceOrderPosition(sharedSurface, strawOrderPos));
+                       // and record
+                       ++sectorStraws;
+                     } // loop over straws done
+                 }  // loop over posneg done
+                 // show the phiMin/phiMax to the screen
+                 // prepare the 
+                 // fix to CID 24918
+                 if (!sectorStraws) {
+                   return std::pair<EventIDRange,const std::vector<const Trk::CylinderLayer* >* >(range,nullptr);
+                 }
+                 double deltaPhi  = (phiMax-phiMin);
+                 double phiStep   = deltaPhi/(0.5*sectorStraws-1);   
+                 ATH_MSG_VERBOSE("---> Sector " << phisec << " - with " << 0.5*sectorStraws << " straws - straw phiMin/phiMax (step) = " << phiMin << " / " << phiMax << " (" << phiStep << ")");
+                 // phi min / phi max 
+                 phiMin -= 0.5*phiStep;
+                 phiMax += 0.5*phiStep;
+                 // correct for the +pi/-pi module 
+                 // now create the BinUtility
+                 Trk::BinUtility* layerStrawPhiZUtility     = new Trk::BinUtility(sectorStraws/2,phiMin,phiMax,Trk::open, Trk::binPhi);
+                                 (*layerStrawPhiZUtility)  += Trk::BinUtility(2,-layerZmax, layerZmax, Trk::open, Trk::binZ);
+                 // create the 2D BinnedArray
+                 Trk::BinnedArray2D<Trk::Surface>* layerStrawPhiSector = new Trk::BinnedArray2D<Trk::Surface>(strawsPerPhiSecLayer,layerStrawPhiZUtility);
+                 ATH_MSG_VERBOSE("---> Sector " << phisec << " - BinnedArray for straws prepared for " << strawsPerPhiSecLayer.size() << " straws.");
+                 // fill the array                  
+                 layerSectorArrays.push_back(std::pair< Trk::BinnedArray<Trk::Surface>*, Amg::Vector3D >(layerStrawPhiSector, layerSectorPosition));                 
+                // ---------------- enf of phi sector ----------------------------------------------------
+              } // loop over PhiSectors done
+              
+              // build the mean of the layer Radius
+              layerRadius = 0.5*(layerRadiusMin+layerRadiusMax)+0.5*m_layerStrawRadius;
+              
+              bool assignMaterial = false;
+              if (cMaterialLayerCount == nMaterialLayerStep) {
+                  assignMaterial      = true;
+                  cMaterialLayerCount = 0;
+                  ATH_MSG_VERBOSE( "--> Creating a material+straw layer at radius  : " << layerRadius );
+              } else 
+                  ATH_MSG_VERBOSE( "--> Creating a straw          layer at radius  : " << layerRadius );
+              
+              // now order the plane layers to sit on cylindrical layers
+              Trk::CylinderBounds* barrelLayerBounds = new Trk::CylinderBounds(layerRadius, layerHalflength);
+              
+              // ---- correct phi -------------------------------------------------------------------
+              ATH_MSG_VERBOSE("    prepare approach description with " << nBarrelPhiSectors << " barrel sectors.");
+              ATH_MSG_VERBOSE("    min phi / max phi detected  : " << layerPhiMin << " / " << layerPhiMax );
+              double layerPhiMinCorrected = layerPhiMin-0.5*layerPhiStep;
+              double layerPhiMaxCorrected = layerPhiMax+0.5*layerPhiStep;
+              // catch if the minPhi falls below M_PI
+              if (layerPhiMinCorrected < -M_PI){
+                  layerPhiMinCorrected += layerPhiStep;
+                  layerPhiMaxCorrected += layerPhiStep;
+              }
+              ATH_MSG_VERBOSE("    min phi / max phi corrected : " << layerPhiMinCorrected << " / " << layerPhiMaxCorrected );
+              
+              // the sector surfaces
+              Trk::BinUtility* layerSectorBinUtility = new Trk::BinUtility(nBarrelPhiSectors,layerPhiMinCorrected,layerPhiMaxCorrected,Trk::closed,Trk::binPhi);
+              Trk::BinnedArrayArray<Trk::Surface>* strawArray = new Trk::BinnedArrayArray<Trk::Surface>(layerSectorArrays, layerSectorBinUtility );
+              
+              ATH_MSG_VERBOSE("--> Layer " << layer << " has been built with " << strawArray->arrayObjects().size() << " straws.");
+              
+              // ApproachDescriptor
+              // build a BinUtility for the ApproachDescritptor
+              Trk::BinUtility* aDescriptorBinUtility = new Trk::BinUtility(nBarrelPhiSectors,layerPhiMinCorrected,layerPhiMaxCorrected,Trk::closed,Trk::binPhi);
+                           (*aDescriptorBinUtility) += Trk::BinUtility(2,-layerHalflength,layerHalflength,Trk::open, Trk::binZ);
+              Trk::BinnedArray2D<Trk::ApproachSurfaces>* aDescriptorBinnedArray = new Trk::BinnedArray2D<Trk::ApproachSurfaces> (layerApproachSurfaces, aDescriptorBinUtility);             
+              // build an approach surface
+              Trk::CylinderSurface* approachSurface  = new Trk::CylinderSurface(barrelLayerBounds->clone()); 
+              Trk::ApproachDescriptor* aDescritpor   = new Trk::ApproachDescriptor(aDescriptorBinnedArray, approachSurface);
+              
+              // do not give every layer material properties
+              if (assignMaterial) {
+                 // ----- prepare the BinnedLayerMaterial -----------------------------------------------------
+                 Trk::BinnedLayerMaterial* layerMaterial = 0;
+                 // -- material with 1D binning
+                 Trk::BinUtility layerBinUtilityZ(m_barrelLayerBinsZ, -layerHalflength, layerHalflength, Trk::open, Trk::binZ );
+                 if (m_barrelLayerBinsPhi==1){
+                    layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtilityZ);
+                 } else { // -- material with 2D binning: RPhiZ binning
+                    Trk::BinUtility layerBinUtilityRPhiZ(m_barrelLayerBinsPhi,
+                                                               -layerRadius*M_PI, layerRadius*M_PI,
+                                                                Trk::closed,
+                                                                Trk::binRPhi);
+                                                                 layerBinUtilityRPhiZ += layerBinUtilityZ;                       
+                   layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtilityRPhiZ);
+                 }
+              
+                  barrelLayers->push_back(new Trk::CylinderLayer(barrelLayerBounds,
+                                                                 strawArray,
+                                                                 *layerMaterial,
+                                                                 m_layerThickness,
+                                                                 new InDet::TRT_OverlapDescriptor(trtIdHelper),
+                                                                 aDescritpor));
+                   delete layerMaterial;
+              
+              } else
+                  barrelLayers->push_back(new Trk::CylinderLayer(barrelLayerBounds,
+                                                                 strawArray,
+                                                                 m_layerThickness,
+                                                                 new InDet::TRT_OverlapDescriptor(trtIdHelper),
+                                                                 aDescritpor));
+              // increment this layer
+              ++ilay;
+        } // loop over layers
+     } // loop over rings
+   }
+
+  // return what you have
+  return std::make_pair(range,barrelLayers.release());
+}
+
+//TODO: context object is unused, elements are retrieved from m_trtMgr instead of CondSvc
+std::pair<EventIDRange, const std::vector< const Trk::DiscLayer* >* > InDet::TRT_LayerBuilderCond::discLayers(const EventContext&) const
+{
+  ATH_MSG_DEBUG( "Building disc-like layers for the TRT " );
+
+  //create dummy infinite range
+  EventIDRange range;
+
+  const InDetDD::TRT_Numerology* trtNums = m_trtMgr->getNumerology();
+  // get the TRT ID Helper
+  const TRT_ID* trtIdHelper = 0;
+  if (detStore()->retrieve(trtIdHelper, "TRT_ID").isFailure()) {
+     ATH_MSG_ERROR("Could not get TRT ID helper");
+     return std::pair<EventIDRange,const std::vector<const Trk::DiscLayer* >* >(range,nullptr);
+  }
+  unsigned int nEndcapWheels = trtNums->getNEndcapWheels();
+  unsigned int nEndcapPhiSectors = trtNums->getNEndcapPhi();
+
+  // total layer numbers
+  int numTotalLayers = 0;
+
+  // zMin / zMax
+  double zMin = 10e10;
+  double zMax = 0.;
+
+  const Trk::DiscBounds* sectorDiscBounds = 0;
+
+  // preloop for overall numbers
+  for (unsigned int iwheel=0; iwheel<nEndcapWheels; ++iwheel)
+    {
+       unsigned int nEndcapLayers = trtNums->getNEndcapLayers(iwheel);
+       numTotalLayers += nEndcapLayers;
+       for (unsigned int ilayer = 0; ilayer<nEndcapLayers; ++ilayer){
+         const InDetDD::TRT_EndcapElement* sectorDiscElement = m_trtMgr->getEndcapElement(0, iwheel, ilayer, 0);
+
+         // get a reference element for dimensions
+         if (!sectorDiscBounds){
+           const Trk::SurfaceBounds& sectorSurfaceBounds = sectorDiscElement->bounds();
+           sectorDiscBounds = dynamic_cast<const Trk::DiscBounds*>(&sectorSurfaceBounds);
+         }
+
+         double currentZ = fabs(sectorDiscElement->center().z());
+         takeSmallerBigger(zMin,zMax,currentZ);
+       }
+    }
+  if (numTotalLayers==0) {
+      ATH_MSG_WARNING( "numTotalLayers = 0 ... aborting and returning 0 !" );
+      return std::pair<EventIDRange,const std::vector<const Trk::DiscLayer* >* >(range,nullptr);
+  }
+
+  Trk::DiscBounds* fullDiscBounds = sectorDiscBounds ? new Trk::DiscBounds(sectorDiscBounds->rMin(), sectorDiscBounds->rMax()) : 0;
+  if (!fullDiscBounds) {
+      ATH_MSG_WARNING( "fullDiscBounds do not exist ... aborting and returning 0 !" );
+      return std::pair<EventIDRange,const std::vector<const Trk::DiscLayer* >* >(range,nullptr);
+  }
+
+  PtrVectorWrapper<Trk::DiscLayer> endcapLayers;
+
+  // the BinUtility for the material
+  Trk::BinnedLayerMaterial* layerMaterial = 0;
+  // -- material with 1D binning
+  Trk::BinUtility layerBinUtilityR(m_endcapLayerBinsR,
+                                         fullDiscBounds->rMin(),
+                                         fullDiscBounds->rMax(),
+                                         Trk::open,
+                                         Trk::binR);
+  if (m_barrelLayerBinsPhi==1)
+     layerMaterial = new Trk::BinnedLayerMaterial(layerBinUtilityR);
+   else { // -- material with 2D binning
+     Trk::BinUtility layerBinUtilityPhi(m_barrelLayerBinsPhi,
+                                               -M_PI, M_PI,
+                                               Trk::closed,
+                                               Trk::binPhi);
+                            // make it rPhi now
+                       layerBinUtilityR += layerBinUtilityPhi;                   
+     layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtilityR);
+  }
+
+  // global geometry statistics
+  double zDiff      = fabs(zMax-zMin);
+  double zStep      = zDiff/(m_modelEndcapLayers+1);
+
+  // loop for surface ordering
+  int maxendcaps=2;
+  if (m_endcapConly) maxendcaps=1;
+  
+  for (int iposneg=0; iposneg<maxendcaps; ++iposneg){
+
+    // fill the positions of the disc layers
+    std::vector<double> zPositions;
+    zPositions.reserve(m_modelEndcapLayers);
+
+    double stepdir = iposneg ? 1. : -1.;
+    double zStart = stepdir*zMin;
+
+    ATH_MSG_VERBOSE( " -> Creating " << m_modelEndcapLayers << " disc-layers on each side between " 
+                    << zMin << " and " << zMax << " ( at step "<< zStep << " )");
+
+    // take a different modelling for the layers - use these layers for the model geometry and the real geometry
+    for (unsigned int izpos = 1; izpos <= m_modelEndcapLayers; ++izpos){
+       zPositions.push_back(zStart + stepdir * double(izpos) * zStep - 0.5 * m_layerThickness);
+   }
+
+   std::vector<double>::const_iterator zPosIter    = zPositions.begin();
+   std::vector<double>::const_iterator zPosIterEnd = zPositions.end();
+
+   // (a) simplified geometry 
+   if (m_modelGeometry){
+      // build the layers actually
+      for ( ; zPosIter != zPosIterEnd; ++zPosIter){
+         ATH_MSG_VERBOSE( "  --> Creating a layer at z pos    : " << (*zPosIter) );
+         Amg::Transform3D* zPosTrans = new Amg::Transform3D;
+         (*zPosTrans) = Amg::Translation3D(0.,0.,(*zPosIter));
+         endcapLayers->push_back(new Trk::DiscLayer(zPosTrans,
+                                                    fullDiscBounds->clone(),
+                                                    *layerMaterial,
+                                                    m_layerThickness));
+        }
+
+   } else {
+      // (b) complex geometry 
+      int nMaterialLayerStep  = int(numTotalLayers/m_modelEndcapLayers+1);
+      int cMaterialLayerCount = 0;
+      
+      // complex geometry - needs a little bit of joggling
+      int    currentLayerCounter = 0;      
+      for (unsigned int iwheel=0; iwheel<nEndcapWheels; ++iwheel)
+      {
+        // do the loop per side
+        unsigned int nEndcapLayers = trtNums->getNEndcapLayers(iwheel);
+        for (unsigned int ilayer = 0; ilayer < nEndcapLayers; ++ilayer){
+         // increase the layerCounter for material layer decission
+         ++currentLayerCounter;
+         ++cMaterialLayerCount;
+         
+         // count the straws;
+         int numberOfStraws = 0;
+
+         // check if dynamic cast worked
+         if (fullDiscBounds){
+          // get a reference element for dimensions
+           const InDetDD::TRT_EndcapElement* sectorDiscElement = m_trtMgr->getEndcapElement(iposneg, iwheel, ilayer, 0);
+
+           // take the position, but not the rotation (the rotation has to be standard)
+           Amg::Vector3D fullDiscPosition(sectorDiscElement->surface().transform().translation());
+           double discZ = fullDiscPosition.z();
+
+           // check if we need to build a straw layer or not
+           bool assignMaterial = false;
+           if (cMaterialLayerCount == nMaterialLayerStep) {
+               assignMaterial      = true;
+               cMaterialLayerCount = 0;
+               ATH_MSG_VERBOSE( "--> Creating a material+straw layer at z-pos   : " << discZ );
+           } else {
+               ATH_MSG_VERBOSE( "--> Creating a straw          layer at z-pos   : " << discZ );
+           }
+
+           // order the straws onto layers
+           std::vector< Trk::SurfaceOrderPosition > strawPerEndcapLayer;
+
+           // the layer thickness - for approaching surfaces
+           double zMin = 10e10;
+           double zMax = -10e10;
+           
+           for (unsigned int iphisec=0; iphisec<nEndcapPhiSectors; ++iphisec){
+               ATH_MSG_VERBOSE("Building sector " << iphisec << " of endcap wheel " << iwheel );
+                const InDetDD::TRT_EndcapElement* currentElement = m_trtMgr->getEndcapElement(iposneg, iwheel, ilayer, iphisec);
+                unsigned int nstraws = currentElement->nStraws();
+                for (unsigned int istraw=0; istraw<nstraws; istraw++){
+                    Identifier strawId = trtIdHelper->straw_id(currentElement->identify(), istraw);
+                    const Trk::Surface* currentStraw = &(currentElement->surface(strawId));
+                    Amg::Vector3D strawOrderPos(currentStraw->center());
+                    // get the z position
+                    double zPos = currentStraw->center().z();
+                    takeSmaller(zMin,zPos);
+                    takeBigger(zMax,zPos);                    
+                    Trk::SharedObject<const Trk::Surface> sharedSurface(currentStraw, [](const Trk::Surface*){});
+                    strawPerEndcapLayer.push_back(Trk::SurfaceOrderPosition(sharedSurface, strawOrderPos));
+                    ++numberOfStraws;
+                }
+           }
+           // fix to CID 11326
+           if (!numberOfStraws){
+             //fix coverity 118656
+             delete fullDiscBounds;
+             return std::pair<EventIDRange,const std::vector<const Trk::DiscLayer* >* >(range,nullptr);
+           } 
+           Trk::BinUtility* currentBinUtility = new Trk::BinUtility(numberOfStraws, -M_PI, M_PI, Trk::closed, Trk::binPhi);
+           Trk::BinnedArray<Trk::Surface>*  strawArray = new Trk::BinnedArray1D<Trk::Surface>(strawPerEndcapLayer, currentBinUtility);
+           Trk::DiscLayer* currentLayer = 0;
+
+           // redefine the discZ 
+           discZ = 0.5*(zMin+zMax);
+           Amg::Transform3D* fullDiscTransform = new Amg::Transform3D;
+           (*fullDiscTransform) = Amg::Translation3D(0.,0.,discZ);
+
+           ATH_MSG_VERBOSE("TRT Disc being build at z Position " << discZ << " ( from " << zMin << " / " << zMax << " )");
+
+           // create the approach offset
+           Trk::ApproachSurfaces* aSurfaces = new Trk::ApproachSurfaces;
+           // get the position of the approach surfaces
+           const Amg::Vector3D aspPosition(0.,0.,zMin-m_layerStrawRadius);
+           const Amg::Vector3D asnPosition(0.,0.,zMax+m_layerStrawRadius);
+           
+           // create new surfaces
+           Amg::Transform3D* asnTransform = new Amg::Transform3D(Amg::Translation3D(asnPosition));   
+           Amg::Transform3D* aspTransform = new Amg::Transform3D(Amg::Translation3D(aspPosition));   
+           // order in an optimised way for collision direction
+           if (discZ > 0.){
+               aSurfaces->push_back( new Trk::DiscSurface(asnTransform, fullDiscBounds->clone()) );
+               aSurfaces->push_back( new Trk::DiscSurface(aspTransform, fullDiscBounds->clone()) );
+           } else {
+               aSurfaces->push_back( new Trk::DiscSurface(aspTransform, fullDiscBounds->clone()) );
+               aSurfaces->push_back( new Trk::DiscSurface(asnTransform, fullDiscBounds->clone()) );
+           }               
+           // approach descriptor
+           Trk::ApproachDescriptor* aDescriptor = new Trk::ApproachDescriptor(aSurfaces,false);
+           
+           // do not give every layer material properties
+           if (assignMaterial)
+              currentLayer = new Trk::DiscLayer(fullDiscTransform,
+                                                fullDiscBounds->clone(),
+                                                strawArray,
+                                                *layerMaterial,
+                                                m_layerThickness,
+                                                new InDet::TRT_OverlapDescriptor(trtIdHelper),
+                                                aDescriptor);
+           else if (!m_modelGeometry)
+              currentLayer = new Trk::DiscLayer(fullDiscTransform,
+                                                fullDiscBounds->clone(),
+                                                strawArray,
+                                                m_layerThickness,
+                                                new InDet::TRT_OverlapDescriptor(trtIdHelper),
+                                                aDescriptor);
+
+          if (currentLayer) endcapLayers->push_back(currentLayer);
+       } // end of sectorDiscBounds if
+      } // end of layer loop
+     } // end of wheel loop
+    } // model/real geometry
+  } // end of posneg loop
+
+  delete layerMaterial; layerMaterial = 0;
+  delete fullDiscBounds; fullDiscBounds = 0;
+
+  return std::make_pair(range,endcapLayers.release());
+}
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/components/InDetTrackingGeometry_entries.cxx b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/components/InDetTrackingGeometry_entries.cxx
index 53bdacb2e505429c30dccb0e72669a9a029ac420..65ae2778d121b102a3191862d27a5b8d664e7554 100644
--- a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/components/InDetTrackingGeometry_entries.cxx
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/components/InDetTrackingGeometry_entries.cxx
@@ -4,6 +4,12 @@
 #include "InDetTrackingGeometry/RobustTrackingGeometryBuilder.h"
 #include "InDetTrackingGeometry/StagedTrackingGeometryBuilder.h"
 
+#include "InDetTrackingGeometry/BeamPipeBuilderCond.h"
+#include "InDetTrackingGeometry/SiLayerBuilderCond.h"
+#include "InDetTrackingGeometry/TRT_LayerBuilderCond.h"
+#include "InDetTrackingGeometry/RobustTrackingGeometryBuilderCond.h"
+#include "InDetTrackingGeometry/StagedTrackingGeometryBuilderCond.h"
+
 using namespace InDet;
 
 DECLARE_COMPONENT( BeamPipeBuilder )
@@ -12,3 +18,9 @@ DECLARE_COMPONENT( TRT_LayerBuilder )
 DECLARE_COMPONENT( RobustTrackingGeometryBuilder )
 DECLARE_COMPONENT( StagedTrackingGeometryBuilder )
 
+DECLARE_COMPONENT( BeamPipeBuilderCond )
+DECLARE_COMPONENT( SiLayerBuilderCond )
+DECLARE_COMPONENT( TRT_LayerBuilderCond )
+DECLARE_COMPONENT( RobustTrackingGeometryBuilderCond )
+DECLARE_COMPONENT( StagedTrackingGeometryBuilderCond )
+
diff --git a/InnerDetector/InDetDetDescr/PixelReadoutGeometry/PixelReadoutGeometry/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetDetDescr/PixelReadoutGeometry/PixelReadoutGeometry/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..679fd77dbe7b03b1e6794438a788e23408c834e8
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/PixelReadoutGeometry/PixelReadoutGeometry/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetDetDescr/PixelReadoutGeometry
diff --git a/InnerDetector/InDetDetDescr/SCT_Cabling/python/TestSCT_CablingCfg.py b/InnerDetector/InDetDetDescr/SCT_Cabling/python/TestSCT_CablingCfg.py
index d6ddb08d6f9d52b36ac315fcadeda21b273f0cb8..79c28131ebd0fa7fe60da5cb0bb7f95cd4eaf6ff 100644
--- a/InnerDetector/InDetDetDescr/SCT_Cabling/python/TestSCT_CablingCfg.py
+++ b/InnerDetector/InDetDetDescr/SCT_Cabling/python/TestSCT_CablingCfg.py
@@ -17,8 +17,7 @@ def SCT_TestCablingAlgCfg(configFlags):
     cfg.merge(geoCfg)
 
     from AthenaCommon.Constants import INFO
-    from AthenaCommon.CfgGetter import getPrivateTool
-    SCT_CablingTool = getPrivateTool("SCT_CablingTool")
+    SCT_CablingTool = CompFactory.SCT_CablingTool()
     SCT_CablingTool.DataSource = "COOLVECTOR"
     SCT_CablingTool.OutputLevel = INFO
 
diff --git a/InnerDetector/InDetDetDescr/SCT_ReadoutGeometry/SCT_ReadoutGeometry/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetDetDescr/SCT_ReadoutGeometry/SCT_ReadoutGeometry/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..a7dad220e72f384af312288075078d3585768935
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/SCT_ReadoutGeometry/SCT_ReadoutGeometry/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetDetDescr/SCT_ReadoutGeometry
diff --git a/InnerDetector/InDetDetDescr/TRT_ReadoutGeometry/TRT_ReadoutGeometry/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetDetDescr/TRT_ReadoutGeometry/TRT_ReadoutGeometry/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..e600f0fc551954f13f3706e245a5901775827644
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/TRT_ReadoutGeometry/TRT_ReadoutGeometry/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetDetDescr/TRT_ReadoutGeometry
diff --git a/InnerDetector/InDetDetDescrCnv/InDetIdCnv/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetDetDescrCnv/InDetIdCnv/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..882243e2cd9bcae3aedc14320b0eb85847f1f6ec
--- /dev/null
+++ b/InnerDetector/InDetDetDescrCnv/InDetIdCnv/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetDetDescrCnv/InDetIdCnv
diff --git a/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/PixelIDDetDescrCnv.cxx b/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/PixelIDDetDescrCnv.cxx
index 0937c86e3f730ae5d9e06b48a3791b79adf6a0e9..f3add41451da418bac8cf05f9b36c796960589a3 100644
--- a/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/PixelIDDetDescrCnv.cxx
+++ b/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/PixelIDDetDescrCnv.cxx
@@ -121,7 +121,7 @@ PixelIDDetDescrCnv::createObj(IOpaqueAddress* pAddr, DataObject*& pObj)
     } else {}
  
     // Get the dictionary manager from the detector store
-    const DataHandle<IdDictManager> idDictMgr;
+    const IdDictManager* idDictMgr;
     status = detStore->retrieve(idDictMgr, "IdDict");
     if (status.isFailure()) {
 	log << MSG::FATAL << "Could not get IdDictManager !" << endmsg;
diff --git a/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/SCT_IDDetDescrCnv.cxx b/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/SCT_IDDetDescrCnv.cxx
index 800757616629e0a944b5fa7a05e56d00db8c9acd..7f49d1839237992daf2cad76530e7f0c2eb73bda 100644
--- a/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/SCT_IDDetDescrCnv.cxx
+++ b/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/SCT_IDDetDescrCnv.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 /***************************************************************************
@@ -122,7 +122,7 @@ SCT_IDDetDescrCnv::createObj(IOpaqueAddress* pAddr, DataObject*& pObj)
     } else {}
  
     // Get the dictionary manager from the detector store
-    const DataHandle<IdDictManager> idDictMgr;
+    const IdDictManager* idDictMgr;
     status = detStore->retrieve(idDictMgr, "IdDict");
     if (status.isFailure()) {
 	log << MSG::FATAL << "Could not get IdDictManager !" << endmsg;
diff --git a/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/SiliconIDDetDescrCnv.cxx b/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/SiliconIDDetDescrCnv.cxx
index f7a9302786f8fa83d99d433e29658c02fb7dc8b7..8655441e63528e2adf558157d0f4c4fe801c4c6f 100644
--- a/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/SiliconIDDetDescrCnv.cxx
+++ b/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/SiliconIDDetDescrCnv.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 /***************************************************************************
@@ -124,7 +124,7 @@ SiliconIDDetDescrCnv::createObj(IOpaqueAddress* pAddr, DataObject*& pObj)
     } else {}
  
     // Get the dictionary manager from the detector store
-    const DataHandle<IdDictManager> idDictMgr;
+    const IdDictManager* idDictMgr;
     status = detStore->retrieve(idDictMgr, "IdDict");
     if (status.isFailure()) {
 	log << MSG::FATAL << "Could not get IdDictManager !" << endmsg;
diff --git a/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/TRT_IDDetDescrCnv.cxx b/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/TRT_IDDetDescrCnv.cxx
index 8804f39781c8557bde44e2382d16b60b17f1c2fa..6477047a37044944fea13963af3e5e73fcd15ba1 100644
--- a/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/TRT_IDDetDescrCnv.cxx
+++ b/InnerDetector/InDetDetDescrCnv/InDetIdCnv/src/TRT_IDDetDescrCnv.cxx
@@ -122,7 +122,7 @@ TRT_IDDetDescrCnv::createObj(IOpaqueAddress* pAddr, DataObject*& pObj)
     } else {}
  
     // Get the dictionary manager from the detector store
-    const DataHandle<IdDictManager> idDictMgr;
+    const IdDictManager* idDictMgr;
     status = detStore->retrieve(idDictMgr, "IdDict");
     if (status.isFailure()) {
 	log << MSG::FATAL << "Could not get IdDictManager !" << endmsg;
diff --git a/InnerDetector/InDetDigitization/BCM_Digitization/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetDigitization/BCM_Digitization/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..c86a858a06b5fed3ddaf70ec43ddc40309adf22f
--- /dev/null
+++ b/InnerDetector/InDetDigitization/BCM_Digitization/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetDigitization/BCM_Digitization
diff --git a/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_DigitizationTool.cxx b/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_DigitizationTool.cxx
index 40821739be5fa40d80d9100024cec72854d55967..6f65b86848d6175e63440697fdf30b4b1ec68bbf 100644
--- a/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_DigitizationTool.cxx
+++ b/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_DigitizationTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "BCM_DigitizationTool.h"
@@ -440,12 +440,12 @@ void BCM_DigitizationTool::fillRDO(unsigned int chan, int p1x, int p1w, int p2x,
   BCM_RDO_Collection *RDOColl = 0;
   // Check if collection for this channel already exists
   bool collExists = false;
-  BCM_RDO_Container::const_iterator it_coll = m_rdoContainer->begin();
-  BCM_RDO_Container::const_iterator it_collE= m_rdoContainer->end();
+  BCM_RDO_Container::iterator it_coll = m_rdoContainer->begin();
+  BCM_RDO_Container::iterator it_collE= m_rdoContainer->end();
   for (; it_coll!=it_collE; ++it_coll) {
     if ((*it_coll)->getChannel()==chan) {
       collExists = true;
-      RDOColl = const_cast<BCM_RDO_Collection*>(&**it_coll);
+      RDOColl = *it_coll;
     }
   }
   // Create the RDO collection if needed
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..4301ca91b9879a99e6091b3942079818eeef7987
--- /dev/null
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetDigitization/FastSiDigitization
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/PixelFastDigitizationTool.h b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/PixelFastDigitizationTool.h
index d96b8a98dc7f8b98c139721b764ee853b0e7fb5e..63214264860233f719517491322be27c97e0bf2f 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/PixelFastDigitizationTool.h
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/PixelFastDigitizationTool.h
@@ -122,8 +122,6 @@ private:
   bool                                  m_pixEmulateSurfaceCharge;  //!< emulate the surface charge
   double                                m_pixSmearPathLength;       //!< the 2. model parameter: smear the path
   bool                                  m_pixSmearLandau;           //!< if true : landau else: gauss
-  mutable int                           m_siDeltaPhiCut;
-  mutable int                           m_siDeltaEtaCut;
   double                                m_pixMinimalPathCut;        //!< the 1. model parameter: minimal 3D path in pixel
   double                                m_pixPathLengthTotConv;     //!< from path length to tot
   bool                                  m_pixModuleDistortion;       //!< simulationn of module bowing
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/SiSmearedDigitizationTool.h b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/SiSmearedDigitizationTool.h
index de8b59c63c5b850c9c50e8d0565a08a6813df629..995d8006de5524049b6736af17bc32be525cd56e 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/SiSmearedDigitizationTool.h
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/SiSmearedDigitizationTool.h
@@ -127,8 +127,8 @@ public:
   CLHEP::HepRandomEngine*           m_randomEngine;
   std::string                m_randomEngineName;         //!< Name of the random number stream
 
-  mutable float m_pitch_X;
-  mutable float m_pitch_Y;
+  float m_pitch_X;
+  float m_pitch_Y;
 
   bool m_merge;
   double m_nSigma;
@@ -215,7 +215,7 @@ public:
   double           m_Err_y_SCT;
 
   ServiceHandle<Trk::ITrackingGeometrySvc>     m_trackingGeometrySvc;        //!< Service handle for retrieving the TrackingGeometry
-  mutable const Trk::TrackingGeometry*              m_trackingGeometry;           //!< The TrackingGeometry to be retrieved
+  const Trk::TrackingGeometry*              m_trackingGeometry;           //!< The TrackingGeometry to be retrieved
   std::string                                  m_trackingGeometryName;       //!< The Name of the TrackingGeometry
 
   bool m_useCustomGeometry;
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/src/PixelFastDigitizationTool.cxx b/InnerDetector/InDetDigitization/FastSiDigitization/src/PixelFastDigitizationTool.cxx
index 972379c352bdd24ed8b1ebc3b95c7f90790cd9ac..108651dbdb1e38d6ff4eed2895b686094d3c1cbb 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/src/PixelFastDigitizationTool.cxx
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/src/PixelFastDigitizationTool.cxx
@@ -93,8 +93,6 @@ PixelFastDigitizationTool::PixelFastDigitizationTool(const std::string &type, co
   m_pixEmulateSurfaceCharge(true),
   m_pixSmearPathLength(0.01),
   m_pixSmearLandau(true),
-  m_siDeltaPhiCut(0),
-  m_siDeltaEtaCut(0),
   m_pixMinimalPathCut(0.06),// Optimized choice of threshold (old 0.02)
   m_pixPathLengthTotConv(125.),
   m_pixModuleDistortion(true), // default: false
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/src/SCT_FastDigitization.cxx b/InnerDetector/InDetDigitization/FastSiDigitization/src/SCT_FastDigitization.cxx
index b63d9133c93803d95596b734db35d847060a4c5d..8c2c0bf60bd44c9afc23857153ea1d5976c74eda 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/src/SCT_FastDigitization.cxx
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/src/SCT_FastDigitization.cxx
@@ -11,7 +11,6 @@
 SCT_FastDigitization::SCT_FastDigitization(const std::string &name, ISvcLocator *pSvcLocator) :
     AthAlgorithm(name, pSvcLocator)
 {
-  declareProperty("DigitizationTool", m_digTool, "AthAlgTool which performs the SCT digitization");
 }
 
 //----------------------------------------------------------------------
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/src/SiSmearedDigitizationTool.cxx b/InnerDetector/InDetDigitization/FastSiDigitization/src/SiSmearedDigitizationTool.cxx
index c2de5e1952742b9bf873f4ba6ee9b7bc939cc3be..703d09ab7ac6086611cdddecaa1d93dfc4c34e99 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/src/SiSmearedDigitizationTool.cxx
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/src/SiSmearedDigitizationTool.cxx
@@ -1448,9 +1448,9 @@ StatusCode SiSmearedDigitizationTool::digitize(const EventContext& ctx)
 
         if (!m_useCustomGeometry) {
           // Pixel Design needed -------------------------------------------------------------
-          InDetDD::SCT_ModuleSideDesign* design_sct;
+          const InDetDD::SCT_ModuleSideDesign* design_sct;
 
-          design_sct = (InDetDD::SCT_ModuleSideDesign*)&hitSiDetElement->design();
+          design_sct = dynamic_cast<const InDetDD::SCT_ModuleSideDesign*>(&hitSiDetElement->design());
 
           if (!design_sct) {
             ATH_MSG_INFO ( "Could not get design"<< design_sct) ;
diff --git a/InnerDetector/InDetEventCnv/BCM_RawDataByteStreamCnv/BCM_RawDataByteStreamCnv/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetEventCnv/BCM_RawDataByteStreamCnv/BCM_RawDataByteStreamCnv/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..e88208d3e141de1b1396f8d25624011777e7b0a2
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/BCM_RawDataByteStreamCnv/BCM_RawDataByteStreamCnv/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetEventCnv/BCM_RawDataByteStreamCnv
diff --git a/InnerDetector/InDetEventCnv/BCM_RawDataByteStreamCnv/BCM_RawDataByteStreamCnv/BCM_RawContByteStreamCnv.h b/InnerDetector/InDetEventCnv/BCM_RawDataByteStreamCnv/BCM_RawDataByteStreamCnv/BCM_RawContByteStreamCnv.h
index efe5d5b84a4bed4bf76714b157d47d1d4d980480..0940abe8624a1a367bcc4a716736bba901ffd60c 100644
--- a/InnerDetector/InDetEventCnv/BCM_RawDataByteStreamCnv/BCM_RawDataByteStreamCnv/BCM_RawContByteStreamCnv.h
+++ b/InnerDetector/InDetEventCnv/BCM_RawDataByteStreamCnv/BCM_RawDataByteStreamCnv/BCM_RawContByteStreamCnv.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -23,6 +23,7 @@
 
 //including the Message Stream Member
 #include "AthenaKernel/MsgStreamMember.h"
+#include "CxxUtils/checker_macros.h"
 
 class BCM_RawContByteStreamTool;
 class IByteStreamEventAccess;
@@ -59,7 +60,7 @@ private:
 
 
   //Declaring private message stream member.
-  mutable Athena::MsgStreamMember m_msg;
+  mutable Athena::MsgStreamMember m_msg ATLAS_THREAD_SAFE;
 
 };
 #endif
diff --git a/InnerDetector/InDetEventCnv/BCM_RawDataByteStreamCnv/CMakeLists.txt b/InnerDetector/InDetEventCnv/BCM_RawDataByteStreamCnv/CMakeLists.txt
index ab2e76c10e6b64a8d8770b173a8efa5a6c88b300..90a48c2b3fd5a9b7bf697b2d80e827b4562d421b 100644
--- a/InnerDetector/InDetEventCnv/BCM_RawDataByteStreamCnv/CMakeLists.txt
+++ b/InnerDetector/InDetEventCnv/BCM_RawDataByteStreamCnv/CMakeLists.txt
@@ -9,6 +9,7 @@ atlas_subdir( BCM_RawDataByteStreamCnv )
 atlas_depends_on_subdirs( PUBLIC
                           Control/AthenaBaseComps
                           Control/AthenaKernel
+                          Control/CxxUtils
                           Event/ByteStreamCnvSvcBase
                           Event/ByteStreamData
                           GaudiKernel
@@ -24,7 +25,7 @@ atlas_add_component( BCM_RawDataByteStreamCnv
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${TDAQ-COMMON_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${TDAQ-COMMON_LIBRARIES} AthenaBaseComps AthenaKernel ByteStreamCnvSvcBaseLib ByteStreamData ByteStreamData_test GaudiKernel InDetBCM_RawData StoreGateLib SGtests )
+                     LINK_LIBRARIES ${TDAQ-COMMON_LIBRARIES} AthenaBaseComps AthenaKernel CxxUtils ByteStreamCnvSvcBaseLib ByteStreamData ByteStreamData_test GaudiKernel InDetBCM_RawData StoreGateLib SGtests )
 
 # Install files from the package:
 atlas_install_headers( BCM_RawDataByteStreamCnv )
diff --git a/InnerDetector/InDetEventCnv/InDetEventAthenaPool/CMakeLists.txt b/InnerDetector/InDetEventCnv/InDetEventAthenaPool/CMakeLists.txt
index 8f3e63f96d16469556043e84310c8911394b5fd5..20f9493414f8aa5153d05ffec31f3b23d8ac7e8e 100644
--- a/InnerDetector/InDetEventCnv/InDetEventAthenaPool/CMakeLists.txt
+++ b/InnerDetector/InDetEventCnv/InDetEventAthenaPool/CMakeLists.txt
@@ -58,7 +58,7 @@ foreach( name
 
    atlas_add_test( ${name}
       SOURCES test/${name}.cxx
-      LINK_LIBRARIES ${GEOMODELCORE_LIBRARIES}
+      LINK_LIBRARIES
       AtlasHepMCLib IdDict IdDictParser InDetEventAthenaPool TestTools
       ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share"
       PROPERTIES TIMEOUT 300 )
diff --git a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/share/testSCTDecode.py b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/share/testSCTDecode.py
index 9547557cb61ae1dc9b3593864c387bf64864216f..cd5a176d56a08beca4d1ea1c0c5a4d5d3ff11c30 100644
--- a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/share/testSCTDecode.py
+++ b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/share/testSCTDecode.py
@@ -124,6 +124,7 @@ InDetClusterMakerTool = InDet__ClusterMakerTool(name = "InDetClusterMakerTool",
                                                 PixelCablingSvc = None,
                                                 PixelModuleData = "",
                                                 PixelChargeCalibCondData = "",
+                                                PixelOfflineCalibData = '',
                                                 PixelLorentzAngleTool = None,
                                                 SCTLorentzAngleTool = sctLorentzAngleToolSetup.SCTLorentzAngleTool)
 # SCT conditions setups
diff --git a/InnerDetector/InDetG4/TRT_G4_SD/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetG4/TRT_G4_SD/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..72be774972ffba17ee4d3636b8c29e48d0e316fc
--- /dev/null
+++ b/InnerDetector/InDetG4/TRT_G4_SD/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetG4/TRT_G4_SD
diff --git a/InnerDetector/InDetG4/TRT_G4_SD/src/TRTPrintingOfHits.h b/InnerDetector/InDetG4/TRT_G4_SD/src/TRTPrintingOfHits.h
index ab6c44a22c31096ce24cb92ceba1951e05c03370..02c6169617e23501062d5a2846d12d31b16d9694 100644
--- a/InnerDetector/InDetG4/TRT_G4_SD/src/TRTPrintingOfHits.h
+++ b/InnerDetector/InDetG4/TRT_G4_SD/src/TRTPrintingOfHits.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRT_G4_SD_TRTPrintingOfHits_hh
@@ -7,6 +7,8 @@
 
 #include "AthenaKernel/MsgStreamMember.h"
 
+#include "CxxUtils/checker_macros.h"
+
 class TRTUncompressedHit;
 class TRTOutputFile;
 
@@ -29,7 +31,7 @@ class TRTPrintingOfHits
 
     TRTOutputFile* m_pOutputFile;
 
-    mutable Athena::MsgStreamMember m_msg;
+    mutable Athena::MsgStreamMember m_msg ATLAS_THREAD_SAFE;
 
 };
 
diff --git a/InnerDetector/InDetG4/TRT_G4_SD/src/TRTProcessingOfBarrelHits.cxx b/InnerDetector/InDetG4/TRT_G4_SD/src/TRTProcessingOfBarrelHits.cxx
index dfaaef0e73dc570b2ad1a84776160409a270a152..73d3b085de0d49fab56496427cfd64e6b0b107c4 100644
--- a/InnerDetector/InDetG4/TRT_G4_SD/src/TRTProcessingOfBarrelHits.cxx
+++ b/InnerDetector/InDetG4/TRT_G4_SD/src/TRTProcessingOfBarrelHits.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // Class header
@@ -144,8 +144,8 @@ bool TRTProcessingOfBarrelHits::ProcessHit(G4Step* pStep)
   G4ThreeVector globalPostStepPoint = pPostStepPoint->GetPosition();
 
 
-  G4TouchableHistory* pTouchableHistory =
-    (G4TouchableHistory*) pPreStepPoint->GetTouchable();
+  const G4TouchableHistory* pTouchableHistory =
+    dynamic_cast<const G4TouchableHistory*>(pPreStepPoint->GetTouchable());
 
   const G4AffineTransform& topTransform = pTouchableHistory->GetHistory()->
     GetTopTransform();
diff --git a/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/InDetSimpleVisual/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/InDetSimpleVisual/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..e6868d0b898300bfb3303a6310c0a6af5347d04b
--- /dev/null
+++ b/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/InDetSimpleVisual/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual
diff --git a/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/InDetSimpleVisual/GetDetectorLocalFrames.h b/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/InDetSimpleVisual/GetDetectorLocalFrames.h
index a3fddfa19ea6244fd48c1cd8f9eb280cf345bbbe..7d9cd541ab7cee2980119d5173ba1aaa4e3c2dc5 100644
--- a/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/InDetSimpleVisual/GetDetectorLocalFrames.h
+++ b/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/InDetSimpleVisual/GetDetectorLocalFrames.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 /** 
@@ -71,7 +71,7 @@ class GetDetectorLocalFrames:public AthAlgorithm {
     const TRT_ID *m_TRTHelper;
     const InDetDD::TRT_DetectorManager *m_TRTDetectorManager;
     
-    
-    
+    /** Counter */
+    int m_eventCount{-1};
     
 };
diff --git a/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/InDetSimpleVisual/GetDetectorPositions.h b/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/InDetSimpleVisual/GetDetectorPositions.h
index cd9711d54f901d98e34c003a0781102fe547702d..bdf0ce1264ae206505a92d327594a86bd0bf65aa 100644
--- a/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/InDetSimpleVisual/GetDetectorPositions.h
+++ b/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/InDetSimpleVisual/GetDetectorPositions.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 /** 
@@ -71,7 +71,7 @@ class GetDetectorPositions:public AthAlgorithm {
     const TRT_ID *m_TRTHelper;
     const InDetDD::TRT_DetectorManager *m_TRTDetectorManager;
     
-    
-    
+    /** Counter */
+    int m_eventCount{-1};
     
 };
diff --git a/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/src/GetDetectorLocalFrames.cxx b/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/src/GetDetectorLocalFrames.cxx
index 6062ff84e2a06baa234082a5fd1c23d6a0396c51..9e59af2253e874972924d5350209d46aad1de250 100644
--- a/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/src/GetDetectorLocalFrames.cxx
+++ b/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/src/GetDetectorLocalFrames.cxx
@@ -91,10 +91,10 @@ StatusCode GetDetectorLocalFrames::execute() {
   if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "execute() check global position" << endmsg;
   
     StatusCode sc = StatusCode::SUCCESS;
-    static int eventCount(-1); eventCount++;
+    m_eventCount++;
     
     /** run only for one event */
-    if (eventCount!=0) 
+    if (m_eventCount!=0) 
       return sc; 
     
     std::cout << "========================================================================================" <<std::endl;
diff --git a/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/src/GetDetectorPositions.cxx b/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/src/GetDetectorPositions.cxx
index b87ca822eee7bef8d6f4bd6f539bc01113753419..0a59e59857f850f93943682eede477e9a62a3e42 100644
--- a/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/src/GetDetectorPositions.cxx
+++ b/InnerDetector/InDetGraphics/InDetAlignVisual/InDetSimpleVisual/src/GetDetectorPositions.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 /** 
@@ -101,10 +101,10 @@ StatusCode GetDetectorPositions::execute() {
   if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "execute() check global position" << endmsg;
   
   //StatusCode sc = StatusCode::SUCCESS;
-    static int eventCount(-1); eventCount++;
+  m_eventCount++;
     
     /** run only for one event */
-    if (eventCount!=0) 
+    if (m_eventCount!=0) 
       return StatusCode::SUCCESS; 
     
     std::cout << "========================================================================================" <<std::endl;
diff --git a/InnerDetector/InDetMonitoring/InDetGlobalMonitoringRun3Test/InDetGlobalMonitoringRun3Test/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetMonitoring/InDetGlobalMonitoringRun3Test/InDetGlobalMonitoringRun3Test/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..a826341212b8aac524a3432c0b2b264f56e218e0
--- /dev/null
+++ b/InnerDetector/InDetMonitoring/InDetGlobalMonitoringRun3Test/InDetGlobalMonitoringRun3Test/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetMonitoring/InDetGlobalMonitoringRun3Test
diff --git a/InnerDetector/InDetMonitoring/PixelMonitoring/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetMonitoring/PixelMonitoring/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..682942c9a6b85ec50ae4889442df677551e3fa19
--- /dev/null
+++ b/InnerDetector/InDetMonitoring/PixelMonitoring/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetMonitoring/PixelMonitoring
diff --git a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..7f595a2ceff7eb505ae42e23ab8594b99ba3ac62
--- /dev/null
+++ b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetMonitoring/TRTMonitoringRun3
diff --git a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/TRTMonitoringRun3ESD_Alg.h b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/TRTMonitoringRun3ESD_Alg.h
index 2d262b435df7fb1a9f920530390d4b0e80cc686c..75479033532b46249f48f799e4eaeaa25857535c 100644
--- a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/TRTMonitoringRun3ESD_Alg.h
+++ b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/TRTMonitoringRun3ESD_Alg.h
@@ -65,7 +65,7 @@ public:
     virtual StatusCode initialize() override;
     virtual StatusCode fillHistograms( const EventContext& ctx ) const override;
 private:
-    bool m_ArgonXenonSplitter;
+    BooleanProperty m_ArgonXenonSplitter{this, "doArgonXenonSeparation", true};
     enum GasType{ Xe = 0, Ar = 1, Kr = 2 };
 
     const AtlasDetectorID * m_idHelper;
diff --git a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/TRTMonitoringRun3RAW_Alg.h b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/TRTMonitoringRun3RAW_Alg.h
index f16252aa690b27fbb425956374a3b465ffae2e5b..022fe8908b4aa438063e7f8da063a15fbbec5774 100644
--- a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/TRTMonitoringRun3RAW_Alg.h
+++ b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/TRTMonitoringRun3RAW_Alg.h
@@ -78,7 +78,7 @@ private:
     bool m_doHitsMon;
     float m_DistToStraw;
     
-    bool m_ArgonXenonSplitter;
+    BooleanProperty m_ArgonXenonSplitter{this, "doArgonXenonSeparation", true};
     
     int m_totalEvents;
     float m_longToTCut;
diff --git a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/src/TRTMonitoringRun3ESD_Alg.cxx b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/src/TRTMonitoringRun3ESD_Alg.cxx
index efb53011b17c92cb32bb680cc40f48fa33e2aa46..fa2b8a9121fe7f34005f38e1f3048b986f50329a 100644
--- a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/src/TRTMonitoringRun3ESD_Alg.cxx
+++ b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/src/TRTMonitoringRun3ESD_Alg.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TRTMonitoringRun3/TRTMonitoringRun3ESD_Alg.h"
@@ -1115,7 +1115,6 @@ for (; p_trk != trackCollection.end(); ++p_trk) {
 }
 
 
-int maxtimestamp = 0.;
 //----------------------------------------------------------------------------------//
 StatusCode TRTMonitoringRun3ESD_Alg::fillTRTHighThreshold(const xAOD::TrackParticleContainer& trackCollection,
                                                      const xAOD::EventInfo& eventInfo) const {
@@ -1131,12 +1130,6 @@ StatusCode TRTMonitoringRun3ESD_Alg::fillTRTHighThreshold(const xAOD::TrackParti
     const Trk::Perigee *perigee = NULL;
     const DataVector<const Trk::TrackParameters> *AllTrkPar(0);
     DataVector<const Trk::TrackParameters>::const_iterator p_trkpariter;
-    int timeStamp;
-    timeStamp = eventInfo.timeStamp();
-
-    if (timeStamp > maxtimestamp) {
-        maxtimestamp = timeStamp;
-    }
 
     int runNumber;
     runNumber = eventInfo.runNumber();
diff --git a/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/SiSPSeededTrackFinder/SiSPSeededTrackFinder.h b/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/SiSPSeededTrackFinder/SiSPSeededTrackFinder.h
index 7045eabac514bf253f14053457e735bb010f894d..4b9d96b0e3e4e44b6b4c4b6bb234bf3823dd27f0 100644
--- a/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/SiSPSeededTrackFinder/SiSPSeededTrackFinder.h
+++ b/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/SiSPSeededTrackFinder/SiSPSeededTrackFinder.h
@@ -140,10 +140,10 @@ namespace InDet {
     //@{
     mutable Counter_t m_counterTotal ATLAS_THREAD_SAFE {};
 
-    mutable std::atomic_int m_neventsTotal{0}; //!< Number events
-    mutable std::atomic_int m_neventsTotalV{0}; //!< Number events
-    mutable std::atomic_int m_problemsTotal{0}; //!< Number events with number seeds > maxNumber
-    mutable std::atomic_int m_problemsTotalV{0}; //!< Number events with number seeds > maxNumber
+    mutable std::atomic_int m_neventsTotal{0}; ///< Number events
+    mutable std::atomic_int m_neventsTotalV{0}; ///< Number events
+    mutable std::atomic_int m_problemsTotal{0}; ///< Number events with number seeds > maxNumber
+    mutable std::atomic_int m_problemsTotalV{0}; ///< Number events with number seeds > maxNumber
     //@}
 
     ///////////////////////////////////////////////////////////////////
@@ -157,21 +157,61 @@ namespace InDet {
     MsgStream& dumpevent(MsgStream& out, const SiSPSeededTrackFinder::Counter_t& counter) const;
     //@}
 
-    bool isGoodEvent(const EventContext& ctx) const; //!< EventContext is used to specify which event
-    double trackQuality(const Trk::Track*) const;
-    void filterSharedTracks(std::multimap<double, Trk::Track*>&) const;
+    // check event quality - mainly used for HI events 
+    bool isGoodEvent(const EventContext& ctx) const; ///< EventContext is used to specify which event
+
+    /** \brief assign a quality score to track candidates. 
+    * 
+    * The score is increased for each hit, depending on the 
+    * technology (pix/sct) and the chi2 of the hit. 
+    * A hit will never *reduce* the total score compared to having no hit at all. 
+    * @param [in] track Track to evaluate the quality of 
+    **/ 
+    double trackQuality(const Trk::Track* track) const;
+
+    /** \brief cleans up the collection of quality filtered tracks. 
+    * 
+    * Candidates which share most of their hits (steered by m_freeCut) 
+    * with higher quality candidates are erased from the multimap 
+    * @param [in,out] scoredTracks: Track candidates, sorted by by score, best scored first (implemented by assigning negative sign to scores)
+    **/ 
+    void filterSharedTracks(std::multimap<double, Trk::Track*>& scoredTracks) const;
+
+    /** fills three z0 histograms (non-weighted, weighted by z, and weighted by pt) 
+    * with the track z at the beam line estimated using the innermost measurement. 
+    * the first two parameters are input, the other three output. 
+    * @param [in] Tr Track candidate to fill 
+    * @param [in] beamlinePerigee Perigee surface corresponding to the beam spot 
+    * @param [out] numberWeightedhistogram vector representing a histogram in z, counting the tracks per bin 
+    * @param [out] zWeightedHistogram vector representing a histogram in z, counting the tracks per bin weighted by their z values 
+    * @param [out] ptWeightedHistogram vector representing a histogram in z, counting the tracks per bin weighted by their pt values
+    **/ 
     void fillZHistogram(const Trk::Track* Tr,
-                        Trk::PerigeeSurface& per,
-                        std::vector<int>& nhistogram,
-                        std::vector<double>& zhistogram,
-                        std::vector<double>& phistogram) const;
-    void findZvertex(std::list<Trk::Vertex>& ZV,
-                     double* ZB,
-                     std::vector<int>& nhistogram,
-                     std::vector<double>& zhistogram,
-                     std::vector<double>& phistogram) const;
-    StatusCode oldStrategy(const EventContext& ctx) const; //!< EventContext is used to specify which event
-    StatusCode newStrategy(const EventContext& ctx) const; //!< EventContext is used to specify which event
+                        const Trk::PerigeeSurface& beamlinePerigee,
+                        std::vector<int>& numberWeightedhistogram,
+                        std::vector<double>& zWeightedHistogram,
+                        std::vector<double>& ptWeightedHistogram) const;
+
+    /** estimates a set of vertex positions and a z interval for the second 
+    * track finding pass using the input histograms populated using fillZHistogram. 
+    * the first two arguments serve as output, while the three histograms are input. 
+    * @param [out] vertexList - will be populated with vertex candidates if m_useNewStrategy is set
+    * @param [out] zBoundaries - will be populated with edges of a z interval corresponding to the estimated vertex locations 
+    * @param [in] numberWeightedhistogram vector representing a histogram in z, counting the tracks per bin 
+    * @param [in] zWeightedHistogram vector representing a histogram in z, counting the tracks per bin weighted by their z values 
+    * @param [in] ptWeightedHistogram vector representing a histogram in z, counting the tracks per bin weighted by their pt values
+    **/ 
+    void findZvertex(std::list<Trk::Vertex>& vertexList,
+                     std::pair<double, double> & zBoundaries,
+                     const std::vector<int>& numberWeightedhistogram,
+                     const std::vector<double>& zWeightedHistogram,
+                     const std::vector<double>& ptWeightedHistogram) const;
+
+    /// this method performs the track finding using the old strategy
+    StatusCode oldStrategy(const EventContext& ctx) const; ///< EventContext is used to specify which event
+    
+    /// this method performs the track finding using the new strategy
+    StatusCode newStrategy(const EventContext& ctx) const; ///< EventContext is used to specify which event
     void magneticFieldInit();
 
   };
diff --git a/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/share/SiSPSeededTracksStandalone.py b/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/share/SiSPSeededTracksStandalone.py
index 9e15f052297dd87b4cbe232fcda9a3fadeb0101c..6339fa7e3376a8cbda8c2485ad058f33e5d5faf1 100644
--- a/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/share/SiSPSeededTracksStandalone.py
+++ b/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/share/SiSPSeededTracksStandalone.py
@@ -453,6 +453,7 @@ else:
     InDetClusterMakerTool.PixelModuleData = ""
     InDetClusterMakerTool.PixelChargeCalibCondData = ""
     InDetClusterMakerTool.PixelLorentzAngleTool = None
+    InDetClusterMakerTool.PixelOfflineCalibData = ""
 
 # Set up Pixel neutral network tools
 clusterSplitProbTool = None
diff --git a/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/share/SiSPSeededTracksStandaloneFromESD.py b/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/share/SiSPSeededTracksStandaloneFromESD.py
index 7d41f64e1579ee364d47f521dbd86daa8a3ba5d3..a7503299a0a444b8c08b6ac90dde0fb5e5feb2e8 100644
--- a/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/share/SiSPSeededTracksStandaloneFromESD.py
+++ b/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/share/SiSPSeededTracksStandaloneFromESD.py
@@ -271,7 +271,8 @@ if doPixel:
 
     if not hasattr(condSeq, "PixelTDAQCondAlg"):
         from PixelConditionsAlgorithms.PixelConditionsAlgorithmsConf import PixelTDAQCondAlg
-        condSeq += PixelTDAQCondAlg(name="PixelTDAQCondAlg")
+        condSeq += PixelTDAQCondAlg(name="PixelTDAQCondAlg",
+                                    ReadKey = '')
 
     #####################
     # Calibration Setup #
@@ -316,6 +317,7 @@ if doPixel:
     if not hasattr(condSeq, 'PixelCablingCondAlg'):
         from PixelConditionsAlgorithms.PixelConditionsAlgorithmsConf import PixelCablingCondAlg
         condSeq += PixelCablingCondAlg(name="PixelCablingCondAlg",
+                                       ReadKey='',
                                        MappingFile=IdMappingDat,
                                        RodIDForSingleLink40=rodIDForSingleLink40)
 
diff --git a/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/src/SiSPSeededTrackFinder.cxx b/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/src/SiSPSeededTrackFinder.cxx
index ecb5f351240d460a8ca07cb95abb9264e16a6a1d..5aa4a2a13ccb2e0e08ae5bf78909f25495d2004f 100644
--- a/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/src/SiSPSeededTrackFinder.cxx
+++ b/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/src/SiSPSeededTrackFinder.cxx
@@ -12,7 +12,7 @@
 #include <set>
 
 ///////////////////////////////////////////////////////////////////
-// Constructor
+/// Constructor
 ///////////////////////////////////////////////////////////////////
 
 InDet::SiSPSeededTrackFinder::SiSPSeededTrackFinder
@@ -21,7 +21,7 @@ InDet::SiSPSeededTrackFinder::SiSPSeededTrackFinder
 }
 
 ///////////////////////////////////////////////////////////////////
-// Initialisation
+/// Initialisation
 ///////////////////////////////////////////////////////////////////
 
 StatusCode InDet::SiSPSeededTrackFinder::initialize() 
@@ -35,16 +35,14 @@ StatusCode InDet::SiSPSeededTrackFinder::initialize()
   }
   ATH_CHECK(m_outputTracksKey.initialize());
 
-  // optional PRD to track association map
+  /// optional PRD to track association map
   ATH_CHECK( m_prdToTrackMap.initialize( !m_prdToTrackMap.key().empty() ) );
 
-  // Get tool for space points seed maker
-  //
+  /// Get tool for space points seed maker
   ATH_CHECK( m_seedsmaker.retrieve() );
   ATH_CHECK( m_zvertexmaker.retrieve( DisableTool{ not m_useZvertexTool } ));
 
-  // Get track-finding tool
-  //
+  /// Get track-finding tool
   ATH_CHECK( m_trackmaker.retrieve());
 
   ATH_CHECK( m_trackSummaryTool.retrieve( DisableTool{ m_trackSummaryTool.name().empty()} ));
@@ -58,16 +56,13 @@ StatusCode InDet::SiSPSeededTrackFinder::initialize()
 
     if (not m_beamSpotKey.key().empty()) {
       ATH_CHECK(m_beamSpotKey.initialize());
-      // Get RungeKutta propagator tool
-      //
+      /// Get RungeKutta propagator tool
       ATH_CHECK( m_proptool.retrieve() );
 
-      // Setup for magnetic field
-      //
+      /// Setup for magnetic field
       magneticFieldInit();
       
-      // Setup for Z-histograms
-      //  
+      /// Setup for Z-histograms
       if (m_histsize < 100) m_histsize = 100;
       m_zstep = static_cast<double>(m_histsize)/(2.*m_zcut);
     } else {
@@ -79,8 +74,7 @@ StatusCode InDet::SiSPSeededTrackFinder::initialize()
     m_proptool.disable();
   }
 
-  // Get output print level
-  //
+  /// Get output print level
   if (msgLvl(MSG::DEBUG)) {
     dump(MSG::DEBUG, nullptr);
   }
@@ -92,11 +86,15 @@ StatusCode InDet::SiSPSeededTrackFinder::initialize()
 }
 
 ///////////////////////////////////////////////////////////////////
-// Execute
+/// Execute
 ///////////////////////////////////////////////////////////////////
 
 StatusCode InDet::SiSPSeededTrackFinder::execute(const EventContext& ctx) const
 { 
+  /** Note that !m_useNewStrategy alone is NOT sufficient to trigger the oldStrategy call here! 
+  * For example, run-3 central offline Si tracking has m_useNewStrategy=false, 
+  * but m_useZBoundaryFinding true --> newStrategy
+  **/
   if (not m_useNewStrategy and not m_useZBoundaryFinding and not m_ITKGeometry) {
     return oldStrategy(ctx);
   }
@@ -104,7 +102,7 @@ StatusCode InDet::SiSPSeededTrackFinder::execute(const EventContext& ctx) const
 }
 
 ///////////////////////////////////////////////////////////////////
-// Execute with old strategy
+/// Execute with old strategy
 ///////////////////////////////////////////////////////////////////
 
 namespace InDet {
@@ -128,8 +126,7 @@ StatusCode InDet::SiSPSeededTrackFinder::oldStrategy(const EventContext& ctx) co
 {
   SG::WriteHandle<TrackCollection> outputTracks{m_outputTracksKey, ctx};
   ATH_CHECK(outputTracks.record(std::make_unique<TrackCollection>()));
-  // For HI events we can use MBTS information from calorimeter
-  //
+  /// For HI events we can use MBTS information from calorimeter
   if (not isGoodEvent(ctx)) {
     return StatusCode::SUCCESS;
   }
@@ -142,8 +139,8 @@ StatusCode InDet::SiSPSeededTrackFinder::oldStrategy(const EventContext& ctx) co
     m_seedsmaker->find3Sp(ctx, seedEventData, vertices);
   } else {
     m_seedsmaker->newEvent(ctx, seedEventData, -1);
-    std::list<Trk::Vertex> VZ;
-    m_seedsmaker->find3Sp(ctx, seedEventData, VZ);
+    std::list<Trk::Vertex> vertexList;
+    m_seedsmaker->find3Sp(ctx, seedEventData, vertexList);
   }
 
   const bool PIX = true;
@@ -154,14 +151,14 @@ StatusCode InDet::SiSPSeededTrackFinder::oldStrategy(const EventContext& ctx) co
   bool ERR = false;
   Counter_t counter{};
   const InDet::SiSpacePointsSeed* seed = nullptr;
-  std::multimap<double, Trk::Track*> qualityTrack;
+  std::multimap<double, Trk::Track*> qualitySortedTrackCandidates;
   // Loop through all seed and reconsrtucted tracks collection preparation
   //
   while ((seed = m_seedsmaker->next(ctx, seedEventData))) {
     ++counter[kNSeeds];
     std::list<Trk::Track*> trackList = m_trackmaker->getTracks(ctx, trackEventData, seed->spacePoints());
     for (Trk::Track* t: trackList) {
-      qualityTrack.insert(std::make_pair(-trackQuality(t), t));
+      qualitySortedTrackCandidates.insert(std::make_pair(-trackQuality(t), t));
     }
     if (not ZVE and (counter[kNSeeds] >= m_maxNumberSeeds)) {
       ERR = true;
@@ -173,18 +170,18 @@ StatusCode InDet::SiSPSeededTrackFinder::oldStrategy(const EventContext& ctx) co
 
   // Remove shared tracks with worse quality
   //
-  filterSharedTracks(qualityTrack);
+  filterSharedTracks(qualitySortedTrackCandidates);
 
   // Save good tracks in track collection
   //
-  for (std::pair<double, Trk::Track*> q: qualityTrack) {
+  for (const std::pair<double, Trk::Track*> & qualityAndTrack: qualitySortedTrackCandidates) {
     ++counter[kNTracks];
     if (m_trackSummaryTool.isEnabled()) {
-       m_trackSummaryTool->computeAndReplaceTrackSummary(*(q.second),
+       m_trackSummaryTool->computeAndReplaceTrackSummary(*(qualityAndTrack.second),
                                                          trackEventData.combinatorialData().PRDtoTrackMap(),
                                                          false /* DO NOT suppress hole search*/);
     }
-    outputTracks->push_back(q.second);
+    outputTracks->push_back(qualityAndTrack.second);
   }
 
   m_counterTotal[kNSeeds] += counter[kNSeeds];
@@ -215,47 +212,69 @@ StatusCode InDet::SiSPSeededTrackFinder::newStrategy(const EventContext& ctx) co
 {
   SG::WriteHandle<TrackCollection> outputTracks{m_outputTracksKey, ctx};
   ATH_CHECK(outputTracks.record(std::make_unique<TrackCollection>()));
-  // For HI events we can use MBTS information from calorimeter
-  //
+  /// For HI events we can use MBTS information from calorimeter
   if (not isGoodEvent(ctx)) {
     return StatusCode::SUCCESS;
   }
 
-  // Get beam information and preparation for z -histogramming
-  //
+  /// Get beam information and preparation for z -histogramming
   SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle{m_beamSpotKey, ctx};
-  Trk::PerigeeSurface per(beamSpotHandle->beamPos());
+  Trk::PerigeeSurface beamPosPerigee(beamSpotHandle->beamPos());
 
   SiSpacePointsSeedMakerEventData seedEventData;
- 
+  
+  /** 
+   * We run two passes of seeding & track finding. 
+   * 
+   * First, we use strip seeds, perform finding with them and obtain an 
+   * estimate of the beam spot region from the found tracks. 
+   * 
+   * Then, we run PPP-seeded tracking within the resulting z interval. 
+   **/ 
+
+  /**
+   * Set up the first pass (strip seeds), and prepare to 
+   * obtain a vertex Z estimate from the candidates we find 
+   **/ 
+
+  /// set up the seed maker for first pass 
   m_seedsmaker->newEvent(ctx, seedEventData, 0);
-  std::list<Trk::Vertex> VZ;
-  m_seedsmaker->find3Sp(ctx, seedEventData, VZ);
+  std::list<Trk::Vertex> vertexList;
+  /// and run seeding - starting with an empty list of vertices for the first pass
+  m_seedsmaker->find3Sp(ctx, seedEventData, vertexList);
 
   const bool PIX = true ;
   const bool SCT = true ;
   InDet::ExtendedSiTrackMakerEventData_xk trackEventData(m_prdToTrackMap);
+  /// set up the track maker 
   m_trackmaker->newEvent(ctx, trackEventData, PIX, SCT);
 
-  std::vector<int> nhistogram(m_histsize, 0);
-  std::vector<double> zhistogram(m_histsize, 0.);
-  std::vector<double> phistogram(m_histsize, 0.);
+  /// initialize empty histograms for the vertex estimate
+  std::vector<int> numberHistogram(m_histsize, 0);
+  std::vector<double> zWeightedHistogram(m_histsize, 0.);
+  std::vector<double> ptWeightedHistogram(m_histsize, 0.);
 
   bool ERR = false;
   Counter_t counter{};
   const InDet::SiSpacePointsSeed* seed = nullptr;
-  std::multimap<double, Trk::Track*> qualityTrack;
-  // Loop through all seed and reconsrtucted tracks collection preparation
-  //
+
+  /// prepare a collection for the quality-sorted track canddiates
+  std::multimap<double, Trk::Track*> qualitySortedTrackCandidates;
+
+  /// Loop through all seeds from the first pass and attempt to form track candidates
   while ((seed = m_seedsmaker->next(ctx, seedEventData))) {
     ++counter[kNSeeds];
+    /// we only want to fill the Z histo with the first candidate for each seed. 
     bool firstTrack{true};
+    /// combinatorial track finding for one given seed 
     std::list<Trk::Track*> trackList = m_trackmaker->getTracks(ctx, trackEventData, seed->spacePoints());
-    for (Trk::Track* t: trackList) {
-      qualityTrack.insert(std::make_pair(-trackQuality(t), t));
 
+    /// record found candidates
+    for (Trk::Track* t: trackList) {
+      qualitySortedTrackCandidates.insert(std::make_pair(-trackQuality(t), t));
+      /// For the first (highest quality) track from each seed, populate the vertex finding histograms 
       if (firstTrack and not m_ITKGeometry) {
-        fillZHistogram(t, per, nhistogram, zhistogram, phistogram);
+        fillZHistogram(t, beamPosPerigee, numberHistogram, zWeightedHistogram, ptWeightedHistogram);
       }
       firstTrack = false;
     }
@@ -266,22 +285,30 @@ StatusCode InDet::SiSPSeededTrackFinder::newStrategy(const EventContext& ctx) co
     }
   }
 
+  /** Now set up the second seeding pass, using pixel seeds
+  * The seed maker will internally reconfigure itself based on
+  * the "1" argument for the "iteration" argument in this call. 
+  **/ 
   m_seedsmaker->newEvent(ctx, seedEventData, 1);
 
-  double ZB[2];
+  /// perform vertex Z estimation and run second seeding pass
+  std::pair<double,double> zBoundaries;
   if (not m_ITKGeometry) {
-    findZvertex(VZ, ZB, nhistogram, zhistogram, phistogram);
-    m_seedsmaker->find3Sp(ctx, seedEventData, VZ, ZB);
+    /// Estimate a Z vertex interval and, if running the new strategy, also a list of the HS candidates 
+    findZvertex(vertexList, zBoundaries, numberHistogram, zWeightedHistogram, ptWeightedHistogram);
+    /// pass the Z boundary pair c-array-style to satisfy existing interfaces of the seeds maker family. 
+    /// Trigger second seed finding pass (PPP) 
+    m_seedsmaker->find3Sp(ctx, seedEventData, vertexList, &(zBoundaries.first));
   } else {
-    m_seedsmaker->find3Sp(ctx, seedEventData, VZ);
+    m_seedsmaker->find3Sp(ctx, seedEventData, vertexList);
   }
 
-  // Loop through all seed and reconsrtucted tracks collection preparation
-  //
+  /// Again, loop over the newly found seeds and attempt to form track candidates
   while ((seed = m_seedsmaker->next(ctx, seedEventData))) {
     ++counter[kNSeeds];
+    /// insert the new tracks into the quality-sorted list
     for (Trk::Track* t: m_trackmaker->getTracks(ctx, trackEventData, seed->spacePoints())) {
-      qualityTrack.insert(std::make_pair(-trackQuality(t), t));
+      qualitySortedTrackCandidates.insert(std::make_pair(-trackQuality(t), t));
     }
     if (counter[kNSeeds] >= m_maxNumberSeeds) {
       ERR = true;
@@ -291,20 +318,20 @@ StatusCode InDet::SiSPSeededTrackFinder::newStrategy(const EventContext& ctx) co
   }
   m_trackmaker->endEvent(trackEventData);
 
-  // Remove shared tracks with worse quality
-  //
-  filterSharedTracks(qualityTrack);
+  /// Remove shared tracks with worse quality
+  filterSharedTracks(qualitySortedTrackCandidates);
 
-  // Save good tracks in track collection
-  //
-  for (std::pair<double, Trk::Track*> q: qualityTrack) {
+  /// Save good tracks in track collection
+  for (const std::pair<double, Trk::Track*> & qualityAndTrack: qualitySortedTrackCandidates) {
     ++counter[kNTracks];
     if (m_trackSummaryTool.isEnabled()) {
-       m_trackSummaryTool->computeAndReplaceTrackSummary(*q.second,
+      /// Note that for run-3 the tool here is configured to not perform a hole search,
+      /// regardless of the 'false' argument below
+       m_trackSummaryTool->computeAndReplaceTrackSummary(*qualityAndTrack.second,
                                                          trackEventData.combinatorialData().PRDtoTrackMap(),
                                                          false /* DO NOT suppress hole search*/);
     }
-    outputTracks->push_back(q.second);
+    outputTracks->push_back(qualityAndTrack.second);
   }
 
   m_counterTotal[kNSeeds] += counter[kNSeeds] ;
@@ -484,23 +511,26 @@ bool InDet::SiSPSeededTrackFinder::isGoodEvent(const EventContext& ctx) const {
 double InDet::SiSPSeededTrackFinder::trackQuality(const Trk::Track* Tr) const
 {
  double quality = 0. ;
- double W       = 17.;
+ double baseScorePerHit       = 17.;
 
+  /// check all hits on the track
  for (const Trk::TrackStateOnSurface* m: *(Tr->trackStateOnSurfaces())) {
-
+   /// exclude anything which is not an actual hit 
    if (not m->type(Trk::TrackStateOnSurface::Measurement)) continue;
-
+  /// retrieve the fit quality for a given hit
    const Trk::FitQualityOnSurface* fq = m->fitQualityOnSurface();
    if (fq==nullptr) continue;
-
+  
    double x2 = fq->chiSquared();
-   double q;
-   if (fq->numberDoF() == 2) q = (1.2*(W-x2*.5)); 
-   else                      q =      (W-x2    );
-   if (q < 0.) q = 0.;
-   quality += q;
+   double hitQualityScore;
+   /// score the hit based on the technology (pixels get higher score) and 
+   /// the local chi2 for the hit 
+   if (fq->numberDoF() == 2) hitQualityScore = (1.2*(baseScorePerHit-x2*.5));   // pix
+   else                      hitQualityScore =      (baseScorePerHit-x2    );   // sct
+   if (hitQualityScore < 0.) hitQualityScore = 0.;    // do not allow a bad hit to decrement the overall score 
+   quality += hitQualityScore;
  }
-
+  /// penalise brem tracks 
  if (Tr->info().trackProperties(Trk::TrackInfo::BremFit)) quality *= 0.7;
 
  return quality;
@@ -510,37 +540,47 @@ double InDet::SiSPSeededTrackFinder::trackQuality(const Trk::Track* Tr) const
 // Filer shared tracks
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSPSeededTrackFinder::filterSharedTracks(std::multimap<double, Trk::Track*>& QT) const
+void InDet::SiSPSeededTrackFinder::filterSharedTracks(std::multimap<double, Trk::Track*>& qualitySortedTracks) const
 {
   std::set<const Trk::PrepRawData*> clusters;
   
-  const Trk::PrepRawData* prd[100]; 
+  std::vector<const Trk::PrepRawData*> freeClusters;
+  freeClusters.reserve(15);    
   
-  std::multimap<double, Trk::Track*>::iterator q = QT.begin();
-  while (q!=QT.end()) {
+  std::multimap<double, Trk::Track*>::iterator it_qualityAndTrack = qualitySortedTracks.begin();
 
-    std::set<const Trk::PrepRawData*>::iterator fe = clusters.end();
+  /// loop over all track candidates, sorted by quality
+  while (it_qualityAndTrack!=qualitySortedTracks.end()) {
+    freeClusters.clear();
 
-    int nf = 0;
-    int nc = 0; 
+    std::set<const Trk::PrepRawData*>::iterator it_clustersEnd = clusters.end();
 
-    for (const Trk::MeasurementBase* m: *((*q).second->measurementsOnTrack())) {
+    int nClusters = 0; 
+    /// loop over measurements on the track candidate 
+    for (const Trk::MeasurementBase* m: *((*it_qualityAndTrack).second->measurementsOnTrack())) {
+      /// get the PRD from the measurement
       const Trk::PrepRawData* pr = (static_cast<const Trk::RIO_OnTrack*>(m))->prepRawData();
       if (pr) {
-	++nc;
-        if (clusters.find(pr)==fe) {
-          prd[nf++]=pr;
-          if (nf==100) break;
+        /// increase cluster count
+	      ++nClusters;
+        /// and check if the cluster was already used in a previous ( = higher quality) track 
+        if (clusters.find(pr)==it_clustersEnd) {
+          /// if not, record as a free (not prevously used) cluster 
+          freeClusters.push_back(pr); 
         }
       }
     }
-
-    if (nf >= m_nfreeCut or nf==nc) {
-      for (int n=0; n<nf; ++n) clusters.insert(prd[n]);
-      ++q;
+    /// check if the track has the minimum number of free clusters or if it has no shared clusters 
+    int nFreeClusters = static_cast<int>(freeClusters.size()); 
+    if (nFreeClusters >= m_nfreeCut || nFreeClusters==nClusters) {
+      /// if this is fulfilled, we keep the candidate 
+      /// add the free clusters to our cluster set 
+      clusters.insert(freeClusters.begin(), freeClusters.end());
+      ++it_qualityAndTrack;
     } else {
-      delete (*q).second;
-      QT.erase(q++);
+      /// if we do not keep the track, clean up candidate 
+      delete (*it_qualityAndTrack).second;
+      qualitySortedTracks.erase(it_qualityAndTrack++);
     }
   }
 }
@@ -550,37 +590,44 @@ void InDet::SiSPSeededTrackFinder::filterSharedTracks(std::multimap<double, Trk:
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSPSeededTrackFinder::fillZHistogram(const Trk::Track* Tr,
-                                                  Trk::PerigeeSurface& per,
-                                                  std::vector<int>& nhistogram,
-                                                  std::vector<double>& zhistogram,
-                                                  std::vector<double>& phistogram) const
+                                                  const Trk::PerigeeSurface& beamPosPerigee,
+                                                  std::vector<int>& numberHistogram,
+                                                  std::vector<double>& zWeightedHistogram,
+                                                  std::vector<double>& ptWeightedHistogram) const
 {
   
   if (Tr->measurementsOnTrack()->size() < 10) return;
 	
-  DataVector<const Trk::TrackStateOnSurface>::const_iterator m = Tr->trackStateOnSurfaces()->begin();
-  const Trk::TrackParameters* P = (*m)->trackParameters();
-  Amg::Vector3D              gf = P->position()          ;
-  Amg::Vector3D              gm = P->momentum()          ;
-      
-  if (gf.x()*gf.x()+gf.y()*gf.y() >= 3600.) return;
+  const Trk::TrackParameters* paramsAtFirstSurface = Tr->trackStateOnSurfaces()->front()->trackParameters();
+  Amg::Vector3D              position = paramsAtFirstSurface->position()          ;
+  Amg::Vector3D              momentum = paramsAtFirstSurface->momentum()          ;
+  
+  /// only take into accounts tracks with a hit inside r < 60mm 
+  constexpr double rSquare_max_forZHisto = 60.*60.; 
+  if (position.x()*position.x()+position.y()*position.y() >= rSquare_max_forZHisto) return;
 
-  double pT = sqrt(gm.x()*gm.x()+gm.y()*gm.y());
+  double pT = sqrt(momentum.x()*momentum.x()+momentum.y()*momentum.y());
   if (pT < m_pTcut) return;
 
   Trk::PatternTrackParameters TP;
-  if (not TP.production(P)) return;
+  if (not TP.production(paramsAtFirstSurface)) return;
 	  
   double step;
-  if (not m_proptool->propagate(TP, per, TP, Trk::anyDirection, m_fieldprop, step, Trk::pion)) return;
+  /// propagate from innermost hit to beam spot
+  if (not m_proptool->propagate(TP, beamPosPerigee, TP, Trk::anyDirection, m_fieldprop, step, Trk::pion)) return;
 	      
-  const double* par = TP.par();
-  if (fabs(par[0]) > m_imcut) return;
-  int z = static_cast<int>((par[1]+m_zcut)*m_zstep);
+  const double* parsAtBeamSpot = TP.par();
+  if (std::abs(parsAtBeamSpot[0]) > m_imcut) return;
+  /// determine bin number - m_zstep is the inverse bin width, where the histo axis extends from -m_zcut to +m_zcut
+  int z = static_cast<int>((parsAtBeamSpot[1]+m_zcut)*m_zstep);
+  /// fill histograms if we are not in the over/underflow
   if (z >=0 and z < m_histsize) {
-    ++nhistogram[z];
-    zhistogram[z] += par[1];
-    phistogram[z] += pT;
+    /// simple z histogram, counting tracks per z 
+    ++numberHistogram[z];
+    /// z weighted histogram binned in z - used for vertex z calculation
+    zWeightedHistogram[z] += parsAtBeamSpot[1];
+    /// pt weighted histogram binned in z - used for vertex sumpt calculation 
+    ptWeightedHistogram[z] += pT;
   }
   
 }
@@ -589,64 +636,72 @@ void InDet::SiSPSeededTrackFinder::fillZHistogram(const Trk::Track* Tr,
 // Find verteex  z coordinates
 ///////////////////////////////////////////////////////////////////
 
-void  InDet::SiSPSeededTrackFinder::findZvertex(std::list<Trk::Vertex>& ZV,
-                                                double* ZB,
-                                                std::vector<int>& nhistogram,
-                                                std::vector<double>& zhistogram,
-                                                std::vector<double>& phistogram) const
+void  InDet::SiSPSeededTrackFinder::findZvertex(std::list<Trk::Vertex>& vertexZList,
+                                                std::pair<double, double> & zBoundaries,
+                                                const std::vector<int>& numberHistogram,
+                                                const std::vector<double>& zWeightedHistogram,
+                                                const std::vector<double>& ptWeightedHistogram) const
 {
-  ZB[0] = 1000.;
-  ZB[1] =-1000.;
+  zBoundaries = {1000., -1000};
 
-  std::multimap<int   ,double> vern;
-  std::multimap<double,double> verp;
+  std::multimap<int   ,double> vertexZ_sortedByNtracks;
+  std::multimap<double,double> vertexZ_sortedBySumPt;
 
-  int imax = m_histsize-1;
-  int nmin = 3;
+  int lastBin = m_histsize-1;
+  int minBinContentSum = 3;
 
-  for (int i=1; i<imax; ++i) { 
+  /// loop over the bins in z. Start with the second, end with the second to last, as we investigate triplets of bins
+  for (int binIndex=1; binIndex<lastBin; ++binIndex) { 
 
-    int n = nhistogram[i-1]+nhistogram[i]+nhistogram[i+1];
+    /// total entries in the three neighbouring bins 
+    int vertexNtracks = numberHistogram.at(binIndex-1)+numberHistogram.at(binIndex)+numberHistogram.at(binIndex+1);
 
-    if (n>=nmin and (nhistogram[i] >= nhistogram[i-1] and nhistogram[i] >= nhistogram[i+1])) {
-  
-      double z = (zhistogram[i-1]+zhistogram[i]+zhistogram[i+1])/static_cast<double>(n);
+    /// if we have at least 3 tracks in this z0 interval with the peak of the local triplet in the central bin,
+    /// add a vertex candidate
+    if (vertexNtracks>=minBinContentSum and (numberHistogram.at(binIndex) >= numberHistogram.at(binIndex-1) and numberHistogram.at(binIndex) >= numberHistogram.at(binIndex+1))) {
+      /// vertex z estimate as the mean z0 of the tracks in the three bins
+      double vertexZestimate = (zWeightedHistogram.at(binIndex-1)+zWeightedHistogram.at(binIndex)+zWeightedHistogram.at(binIndex+1))/static_cast<double>(vertexNtracks);
 
-      if (z < ZB[0]) ZB[0] = z;
-      if (z > ZB[1]) ZB[1] = z;
+      /// if this vertex is to the left of the lower edge or the right of the upper edge, broaden the z interval accordingly 
+      /// to include this vertex. 
+      if (vertexZestimate < zBoundaries.first) zBoundaries.first = vertexZestimate;
+      if (vertexZestimate > zBoundaries.second) zBoundaries.second = vertexZestimate;
  
       if (m_useNewStrategy) { 
-	double p = phistogram[i-1]+phistogram[i]+phistogram[i+1];
-	vern.insert(std::make_pair(-n, z));
-	verp.insert(std::make_pair(-p, z));
+        /// also get the sum(pt) of the vertex candidate
+        double vertexSumPt = ptWeightedHistogram.at(binIndex-1)+ptWeightedHistogram.at(binIndex)+ptWeightedHistogram.at(binIndex+1);
+        vertexZ_sortedByNtracks.insert(std::make_pair(-vertexNtracks, vertexZestimate));
+        vertexZ_sortedBySumPt.insert(std::make_pair(-vertexSumPt, vertexZestimate));
       }
     }
   }
 
   if (m_useNewStrategy) {
 
-    std::set<double> vertex;
+    std::set<double> leadingVertices;
     int n = 0;
-    std::multimap<double, double>::iterator pz = verp.begin();
-    for (std::pair<int, double> nz: vern) {
+    std::multimap<double, double>::iterator vertex_pt_and_z = vertexZ_sortedBySumPt.begin();
+    for (std::pair<int, double> nTrackAndZ: vertexZ_sortedByNtracks) {
+      /// stop when we have collected the requested number of leading vertices
       if (n++ >= m_nvertex) break; 
-      vertex.insert(nz.second);
-      vertex.insert((*pz++).second);
+      /// insert one vertex from the ntracks-sorted list and one from the pt-sorted list. 
+      /// If both are the same, only one insertion is performed
+      leadingVertices.insert(nTrackAndZ.second);
+      leadingVertices.insert((*vertex_pt_and_z++).second);
     }
 
-    for (double v: vertex) {
-      Amg::Vector3D Vp(0., 0., v);
-      Trk::Vertex Ver(Vp);
-      ZV.push_back(Ver);
+    for (double v: leadingVertices) {
+      vertexZList.emplace_back(Amg::Vector3D{0.,0.,v});
     }
   }
-
-  if (ZB[0] > ZB[1]) {
-    ZB[0] = -1000.;
-    ZB[1] = +1000.;
+  /// if we did not find any PV candidates, assume a very wide interval
+  if (zBoundaries.first > zBoundaries.second) {
+    zBoundaries.first = -1000.;
+    zBoundaries.second = +1000.;
   } else {
-    ZB[0] -= 20.;
-    ZB[1] += 20.;
+    /// otherwise, add a reasonable bit of space on each side of the first / last vertex candidate
+    zBoundaries.first -= 20.;
+    zBoundaries.second += 20.;
   }
 } 
 
diff --git a/InnerDetector/InDetRecAlgs/SiSpacePointFormation/SiSpacePointFormation/SiTrackerSpacePointFinder.h b/InnerDetector/InDetRecAlgs/SiSpacePointFormation/SiSpacePointFormation/SiTrackerSpacePointFinder.h
index 88a38ac85da89705881cbb02d2f95d644d3deaa8..5b08e6df375b14470f06f07c6991f7582b985604 100755
--- a/InnerDetector/InDetRecAlgs/SiSpacePointFormation/SiSpacePointFormation/SiTrackerSpacePointFinder.h
+++ b/InnerDetector/InDetRecAlgs/SiSpacePointFormation/SiSpacePointFormation/SiTrackerSpacePointFinder.h
@@ -1,7 +1,7 @@
 // -*- C++ -*-
 
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef SiSpacePointFormation_SI_POINT_FINDER_H
@@ -151,8 +151,6 @@ namespace InDet {
     SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey { this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot" };
     /// To get SCT neighbours
     SG::ReadCondHandleKey<InDet::SiElementPropertiesTable> m_SCTPropertiesKey{this, "SCTPropertiesKey", "SCT_ElementPropertiesTable", "Key of input SiElementPropertiesTable for SCT"};
-    /// For Pixel alignment
-    SG::ReadCondHandleKey<InDetDD::SiDetectorElementCollection> m_pixelDetEleCollKey{this, "PixelDetEleCollKey", "PixelDetectorElementCollection", "Key of SiDetectorElementCollection for Pixel"};
     /// For SCT alignment
     SG::ReadCondHandleKey<InDetDD::SiDetectorElementCollection> m_SCTDetEleCollKey{this, "SCTDetEleCollKey", "SCT_DetectorElementCollection", "Key of SiDetectorElementCollection for SCT"};
     //@}
diff --git a/InnerDetector/InDetRecAlgs/SiSpacePointFormation/src/SiTrackerSpacePointFinder.cxx b/InnerDetector/InDetRecAlgs/SiSpacePointFormation/src/SiTrackerSpacePointFinder.cxx
index 882c26a2835d96863cb384878a3013f9dea42f9d..0409f5acca3962696bfa95a631f92e627ef54d42 100755
--- a/InnerDetector/InDetRecAlgs/SiSpacePointFormation/src/SiTrackerSpacePointFinder.cxx
+++ b/InnerDetector/InDetRecAlgs/SiSpacePointFormation/src/SiTrackerSpacePointFinder.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 /***************************************************************************
@@ -94,7 +94,6 @@ StatusCode SiTrackerSpacePointFinder::initialize()
   // create containers (requires the Identifier Helpers)
   if (m_selectPixels){
     ATH_CHECK(detStore()->retrieve(m_idHelperPixel,"PixelID"));
-    ATH_CHECK(m_pixelDetEleCollKey.initialize());
   }
 
   if (m_selectSCTs) {
diff --git a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiSpacePointsSeedMakerEventData.h b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiSpacePointsSeedMakerEventData.h
index b8fb41f524a6b587fa5e18af5eb01ef5a60d9560..1e9d2967de13842498d900e6005becf5afc18513 100644
--- a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiSpacePointsSeedMakerEventData.h
+++ b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiSpacePointsSeedMakerEventData.h
@@ -37,37 +37,42 @@ namespace InDet {
   public:
     /// enums to specify which SiSpacePointsSeedMaker owns the object.
     enum ToolType {
-      ATLxk, //!< SiSpacePointsSeedMaker_ATLxk
-      BeamGas, //!< SiSpacePointsSeedMaker_BeamGas
-      Cosmic, //!< SiSpacePointsSeedMaker_Cosmic
-      HeavyIon, //!< SiSpacePointsSeedMaker_HeavyIon
-      ITK, //!< SiSpacePointsSeedMaker_ITK
-      LowMomentum, //!< SiSpacePointsSeedMaker_LowMomentum
-      Trigger ///!< SiSpacePointsSeedMaker_Trigger
+      ATLxk, ///< SiSpacePointsSeedMaker_ATLxk
+      BeamGas, ///< SiSpacePointsSeedMaker_BeamGas
+      Cosmic, ///< SiSpacePointsSeedMaker_Cosmic
+      HeavyIon, ///< SiSpacePointsSeedMaker_HeavyIon
+      ITK, ///< SiSpacePointsSeedMaker_ITK
+      LowMomentum, ///< SiSpacePointsSeedMaker_LowMomentum
+      Trigger ////< SiSpacePointsSeedMaker_Trigger
     };
 
-    bool initialized{false};
-    bool trigger{false};
+    bool initialized{false};    ///< has the data object been initialized?  
+    bool trigger{false};        ///< are we running in trigger mode? 
     bool izvertex{false};
-    bool endlist{true};
-    bool isvertex{false};
-    bool checketa{false};
-
-    int iteration{0};
+    /**  indicate if we are done with the seed search for an event. 
+    * Is set to false if we have to abort the current seed finding pass 
+    * (for example due to reaching max seed capacity) and need to 
+    * continue after returning a few seeds to the user first. 
+    **/ 
+    bool endlist{true};    
+    bool isvertex{false};   ///< whether or not we contain a non-empty vertex list
+    bool checketa{false};   ///< whether to apply eta cuts
+
+    int iteration{0};   ///< iteration currently being run 
     int iteration0{0};
-    int r_first{0};
-    int ns{0};
-    int nsaz{0};
+    int r_first{0}; ///< points to the index of the highest occupied radius bin 
+    int ns{0};      ///< total number of SP that we sorted into our r-binned vector
+    int nsaz{0};      ///< number of SP in the Phi-Z 2D binning
     int nsazv{0};
-    int nr{0};
+    int nr{0};        ///< this keeps track of the number of occupied radial bins (so it is typically less than the total number of r bins
     int nrf{0};
-    int nrfz{0};
+    int nrfz{0};     ///< also number of SP in the phi-Z 2D binning??
     int nrfzv{0};
-    int state{0};
-    int nspoint{2};
-    int mode{0};
+    int state{0};     ///< state info - 0 seems to mean cuts aren ot configured
+    int nspoint{2};   ///< number of required SP
+    int mode{0};      ///< operation mode (SP per seed etc) 
     int nlist{0};
-    int fNmin{0};
+    int fNmin{0};     ///< starting phi bin for looping
     int fvNmin{0};
     int zMin{0};
     int nOneSeeds{0};
@@ -75,19 +80,19 @@ namespace InDet {
     int nprint{0};
     int nseeds{0};
 
-    float K{0.};
-    float dzdrmin{0.};
-    float dzdrmax{0.};
-    float ipt2C{0.};
-    float ipt2K{0.};
-    float COFK{0.};
+    float K{0.};      ///< conversion from pT in MeV to twice the circle radius in the transverse plane in mm 
+    float dzdrmin{0.};    //<! store eta cuts interpreted as dz/dr 
+    float dzdrmax{0.};    //<! store eta cuts interpreted as dz/dr 
+    float ipt2C{0.};  ///< inverse of 90% of the pt cut, squared, multiplied by a magic conversion factor 
+    float ipt2K{0.};  ///< 1 / (K * 0.9 * pt cut)², allows us to directly apply our pt cut on the (2R)² estimate we obtain from the seed
+    float COFK{0.};   ///< a magic number 
     float zminU{0.};
     float zmaxU{0.};
     float zminB{0.};
     float zmaxB{0.};
     float ftrig{0.};
     float ftrigW{0.};
-    float umax{0.};    
+    float maxScore{0.};    
 
     /**
      * @name Beam geometry
@@ -95,17 +100,17 @@ namespace InDet {
      * which is called by newEvent and newRegion
      */
     //@{
-    float xbeam[4]{0., 1., 0., 0.}; //!< x,ax,ay,az - center and x-axis direction
-    float ybeam[4]{0., 0., 1., 0.}; //!< y,ax,ay,az - center and y-axis direction
-    float zbeam[4]{0., 0., 0., 1.}; //!< z,ax,ay,az - center and z-axis direction
+    float xbeam[4]{0., 1., 0., 0.}; ///< x,ax,ay,az - center and x-axis direction
+    float ybeam[4]{0., 0., 1., 0.}; ///< y,ax,ay,az - center and y-axis direction
+    float zbeam[4]{0., 0., 0., 1.}; ///< z,ax,ay,az - center and z-axis direction
     //@}
 
     std::vector<int> r_index;
     std::vector<int> r_map;
     std::vector<int> rf_index;
     std::vector<int> rf_map;
-    std::vector<int> rfz_index;
-    std::vector<int> rfz_map;
+    std::vector<int> rfz_index;  ///< 2D index in the 2D phi-z map of each SP in the r-sored vector
+    std::vector<int> rfz_map;    ///< number of SP in each bin of the 2D phi-z map 
     std::vector<int> rfzv_index;
     std::vector<int> rfzv_map;
 
@@ -116,13 +121,15 @@ namespace InDet {
      * Updated in many mthods
      */
     //@{
-    std::vector<InDet::SiSpacePointForSeed*> SP;
+    std::vector<InDet::SiSpacePointForSeed*> SP;    ///< space points to consider for the current seed candidate
     std::vector<InDet::SiSpacePointForSeedITK*> SP_ITK;
-    std::vector<float> Zo;
-    std::vector<float> Tz;
-    std::vector<float> R;
-    std::vector<float> U;
-    std::vector<float> V;
+    
+    /// The following are parameters characterising individual space points within a seed (relative to the central point)
+    std::vector<float> Zo;    ///< z0 estimate from 2 points
+    std::vector<float> Tz;    ///< 1/sintheta estimate from 2 points
+    std::vector<float> R;     ///< inverse distance to the central space point 
+    std::vector<float> U;     ///< transformed U coordinate (x/(x²+y²)) in frame around central SP 
+    std::vector<float> V;     ///< transformed V coordinate (y/(x²+y²)) in frame around central SP 
     std::vector<float> X;
     std::vector<float> Y;
     std::vector<float> Er;
@@ -137,9 +144,9 @@ namespace InDet {
     std::vector<std::pair<float,InDet::SiSpacePointForSeed*>> CmSp;
     std::vector<std::pair<float,InDet::SiSpacePointForSeedITK*>> CmSp_ITK;
 
-    std::vector<std::vector<InDet::SiSpacePointForSeed*>> r_Sorted;
+    std::vector<std::vector<InDet::SiSpacePointForSeed*>> r_Sorted;     ///< vector of space points in each bin of the 1D radial binning 
     std::vector<std::vector<InDet::SiSpacePointForSeed*>> rf_Sorted;
-    std::vector<std::vector<InDet::SiSpacePointForSeed*>> rfz_Sorted;
+    std::vector<std::vector<InDet::SiSpacePointForSeed*>> rfz_Sorted;   ///< vector of space points in each bin of the 2D phi-z binning
     std::vector<std::vector<InDet::SiSpacePointForSeed*>> rfzv_Sorted;
     std::vector<std::list<InDet::SiSpacePointForSeedITK*>> r_Sorted_ITK;
     std::vector<std::list<InDet::SiSpacePointForSeedITK*>> rfz_Sorted_ITK;
@@ -147,16 +154,16 @@ namespace InDet {
 
     std::vector<InDet::SiSpacePointsSeed> seeds;
 
-    std::list<InDet::SiSpacePointForSeed> l_spforseed;
-    std::list<InDet::SiSpacePointForSeed>::iterator i_spforseed;
+    std::list<InDet::SiSpacePointForSeed> l_spforseed;      //<! list of all space points considered for seed building. This has ownership over the pointers stored in the binned vectors ("histograms") above
+    std::list<InDet::SiSpacePointForSeed>::iterator i_spforseed;    //<! keep track of an iterator over the seed list. Frequently used to keep track of where to add the next SP
     std::list<InDet::SiSpacePointForSeedITK> l_spforseed_ITK;
     std::list<InDet::SiSpacePointForSeedITK>::iterator i_spforseed_ITK;
 
     std::list<InDet::SiSpacePointsSeed> l_seeds;
     std::list<InDet::SiSpacePointsSeed>::iterator i_seed;
     std::list<InDet::SiSpacePointsSeed>::iterator i_seede;
-    std::list<InDet::SiSpacePointsProSeed> l_seeds_Pro;
-    std::list<InDet::SiSpacePointsProSeed>::iterator i_seed_Pro;
+    std::list<InDet::SiSpacePointsProSeed> l_seeds_Pro;       //<! lists of output seeds 
+    std::list<InDet::SiSpacePointsProSeed>::iterator i_seed_Pro;       //<! iterators over the said list 
     std::list<InDet::SiSpacePointsProSeed>::iterator i_seede_Pro;
     std::list<InDet::SiSpacePointsProSeedITK> l_seeds_ITK;
     std::list<InDet::SiSpacePointsProSeedITK>::iterator i_seed_ITK;
diff --git a/InnerDetector/InDetRecEvent/SiSpacePoint/SiSpacePoint/PixelSpacePoint.h b/InnerDetector/InDetRecEvent/SiSpacePoint/SiSpacePoint/PixelSpacePoint.h
index bc44ec7611c85a98a192410405266f61f5713785..733c0a9ddf206b6b96833891f525df79feadfd3a 100755
--- a/InnerDetector/InDetRecEvent/SiSpacePoint/SiSpacePoint/PixelSpacePoint.h
+++ b/InnerDetector/InDetRecEvent/SiSpacePoint/SiSpacePoint/PixelSpacePoint.h
@@ -46,16 +46,6 @@ namespace InDet
     PixelSpacePoint( IdentifierHash elementId, 
                      const Trk::PrepRawData* clus);
     
-    /** Parametrised constructor with Covariance Matrix pointer so for L2 at the moment */
-    PixelSpacePoint( IdentifierHash elementId,  
-                     const Trk::PrepRawData* clus, 
-                     const Amg::MatrixX* globcov);
-    
-    /** Parametrised constructor with Covariance Matrix reference so for L2 at the moment */
-    PixelSpacePoint( IdentifierHash elementId,  
-                     const Trk::PrepRawData* clus, 
-                     const Amg::MatrixX& globcov);
-    
     /** add Covariance Matrix and global position directly */
     PixelSpacePoint( IdentifierHash elementId,
                      const Trk::PrepRawData* clus,
diff --git a/InnerDetector/InDetRecEvent/SiSpacePoint/src/PixelSpacePoint.cxx b/InnerDetector/InDetRecEvent/SiSpacePoint/src/PixelSpacePoint.cxx
index 17e86a1bdccad16dc28e3130e85239ac9b5cff2b..8b03b009acad859ef30d071098117d60fbbc4b3c 100755
--- a/InnerDetector/InDetRecEvent/SiSpacePoint/src/PixelSpacePoint.cxx
+++ b/InnerDetector/InDetRecEvent/SiSpacePoint/src/PixelSpacePoint.cxx
@@ -9,6 +9,7 @@
 #include "EventPrimitives/EventPrimitivesToStringConverter.h"
 #include "GeoPrimitives/GeoPrimitivesToStringConverter.h"
 
+#include <memory>
 
 namespace InDet
 {
@@ -31,10 +32,9 @@ namespace InDet
     Trk::MeasurementBase::m_localParams = Trk::LocalParameters(clus->localPosition());
     Trk::MeasurementBase::m_localCovariance = clus->localCovariance();
 
-    const  Amg::Vector3D* tmpPos = clus->detectorElement()->surface().localToGlobal(clus->localPosition()) ;
-    assert (tmpPos!=nullptr) ;
+    std::unique_ptr<const Amg::Vector3D> tmpPos{clus->detectorElement()->surface().localToGlobal(clus->localPosition())};
+    assert (tmpPos) ;
     m_position = *tmpPos;
-    delete tmpPos;
 
     m_clusList = new std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>(clus,nullptr);
     m_elemIdList.first = elementId ;
@@ -44,51 +44,6 @@ namespace InDet
   
   //------------ -------------------------------------------------
   
-  /** Constructor with globCovariance */
-  PixelSpacePoint::PixelSpacePoint( IdentifierHash elementId, 
-                                    const Trk::PrepRawData* clus, 
-                                    const Amg::MatrixX* globcov ) 
-    :
-    SpacePoint()
-  {
-    assert (clus!=nullptr);
-    m_globalCovariance = *globcov;
-    Trk::MeasurementBase::m_localParams = Trk::LocalParameters(clus->localPosition());
-    Trk::MeasurementBase::m_localCovariance = clus->localCovariance();
-    delete globcov;
-
-    const Amg::Vector3D* tmpPos = clus->detectorElement()->surface().localToGlobal(clus->localPosition()) ;
-    assert (tmpPos!=nullptr) ;
-    m_position = *tmpPos;
-    delete tmpPos ;
-
-    m_clusList = new std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>(clus,nullptr);
-    m_elemIdList.first = elementId ;
-    m_elemIdList.second = 0 ;
-  }
-  
-  /** Constructor with globCovariance */
-  PixelSpacePoint::PixelSpacePoint( IdentifierHash elementId, 
-                                    const Trk::PrepRawData* clus, 
-                                    const Amg::MatrixX& globcov ) 
-    :
-    SpacePoint()
-  {
-    assert (clus!=nullptr);
-    m_globalCovariance = globcov;
-    Trk::MeasurementBase::m_localParams = Trk::LocalParameters(clus->localPosition());
-    Trk::MeasurementBase::m_localCovariance = clus->localCovariance();
-
-    const Amg::Vector3D* tmpPos = clus->detectorElement()->surface().localToGlobal(clus->localPosition()) ;
-    assert (tmpPos!=nullptr) ;
-    m_position = *tmpPos;
-    delete tmpPos ;
-
-    m_clusList = new std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>(clus,nullptr);
-    m_elemIdList.first = elementId ;
-    m_elemIdList.second = 0 ;
-  }
-  
   /** Constructor with globPosition and globCovariance */
   PixelSpacePoint::PixelSpacePoint( IdentifierHash elementId,
                                     const Trk::PrepRawData* clus,
diff --git a/InnerDetector/InDetRecTools/InDetEtaDependentCuts/CMakeLists.txt b/InnerDetector/InDetRecTools/InDetEtaDependentCuts/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..dc60da07323b97681a23c1fe29b8b6628a105a2b
--- /dev/null
+++ b/InnerDetector/InDetRecTools/InDetEtaDependentCuts/CMakeLists.txt
@@ -0,0 +1,32 @@
+################################################################################
+# Package: InDetEtaDependentCuts
+################################################################################
+
+# Declare the package name:
+atlas_subdir( InDetEtaDependentCuts )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs(  )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs( PUBLIC
+                          Control/AthenaBaseComps
+                          Control/AthenaKernel
+                          GaudiKernel )
+
+# External dependencies:
+find_package( CLHEP )
+find_package( Eigen )
+find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
+
+# tag rootMathLibs was not recognized in automatic conversion in cmt2cmake
+
+# Component(s) in the package:
+atlas_add_component( InDetEtaDependentCuts
+                     src/*.cxx
+                     src/components/*.cxx
+                     INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS}
+                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} AthenaBaseComps AthenaKernel GaudiKernel InDetRecToolInterfaces )
+
+# Install files from the package:
+atlas_install_headers( InDetEtaDependentCuts )
diff --git a/InnerDetector/InDetRecTools/InDetEtaDependentCuts/InDetEtaDependentCuts/InDetEtaDependentCutsSvc.h b/InnerDetector/InDetRecTools/InDetEtaDependentCuts/InDetEtaDependentCuts/InDetEtaDependentCutsSvc.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd628f66ab0a1baf0c6720b78cc75e2b14ef341c
--- /dev/null
+++ b/InnerDetector/InDetRecTools/InDetEtaDependentCuts/InDetEtaDependentCuts/InDetEtaDependentCutsSvc.h
@@ -0,0 +1,100 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+#ifndef INDETETADEPENDENTCUTS_INDETETADEPENDENTCUTSSVC_H
+#define INDETETADEPENDENTCUTS_INDETETADEPENDENTCUTSSVC_H
+
+// STL includes
+#include <string>
+#include <vector>
+
+
+// FrameWork includes
+#include "AthenaBaseComps/AthService.h"
+
+// InDetRecInterfaces includes
+#include "InDetRecToolInterfaces/IInDetEtaDependentCutsSvc.h"
+
+#include "GaudiKernel/ISvcLocator.h"
+
+namespace InDet {
+  class InDetEtaDependentCutsSvc: virtual public IInDetEtaDependentCutsSvc,
+                                  public AthService {
+
+    /////////////////////////////////////////////////////////////////// 
+    // Public methods: 
+    /////////////////////////////////////////////////////////////////// 
+    public:
+      
+      /// Constructor with parameters: 
+      InDetEtaDependentCutsSvc(const std::string& name, ISvcLocator* sl); 
+      
+      /// Destructor: 
+      virtual ~InDetEtaDependentCutsSvc(); 
+      
+      virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvIF); 
+      
+      StatusCode  initialize();
+      StatusCode  finalize();
+      
+      void getValue(const InDet::CutName cutName, std::vector < double >& cut);
+      void getValue(const InDet::CutName cutName,    std::vector < int >& cut);
+      
+      template <class T>
+      T getValueAtEta(const std::vector< T > cuts, const double eta) const;
+    
+      template <class T>    
+      void getValue(const InDet::CutName cutName, T& cut, const double eta);
+      
+      double  getMaxEta() const;
+      double  getMinPtAtEta           (const double eta) const;
+      double  getMaxZImpactAtEta      (const double eta) const;
+      double  getMaxPrimaryImpactAtEta(const double eta) const;
+      int     getMinSiHitsAtEta       (const double eta) const;
+      int     getMinSiNotSharedAtEta  (const double eta) const;
+      int     getMaxSharedAtEta       (const double eta) const;
+      int     getMinPixelHitsAtEta    (const double eta) const;
+      int     getMaxSiHolesAtEta      (const double eta) const;
+      int     getMaxPixelHolesAtEta   (const double eta) const;
+      int     getMaxSctHolesAtEta     (const double eta) const;
+      int     getMaxDoubleHolesAtEta  (const double eta) const;
+      
+      
+    /////////////////////////////////////////////////////////////////// 
+    // Private data: 
+    /////////////////////////////////////////////////////////////////// 
+    private: 
+      
+      int getIndexByEta(const double eta) const;
+      
+      DoubleArrayProperty   m_etaBins              {this, "etaBins"             , {0.0, 4.0}, "eta bins (highest eta is maxEta)"         };
+      DoubleArrayProperty   m_minPT                {this, "minPT"               , {900.0}   , "min pT [MeV]"                             };
+      DoubleArrayProperty   m_maxPrimaryImpact     {this, "maxPrimaryImpact"    , {2.0}     , "max Rphi IP (primaries) [mm]"             };
+      DoubleArrayProperty   m_maxZImpact           {this, "maxZImpact"          , {200.0}   , "max Z IP [mm]"                            };
+      DoubleArrayProperty   m_maxdImpactSSSSeeds   {this, "maxdImpactSSSSeeds"  , {20.0}    , "max impact on seeds SSS [mm]"             };
+      DoubleArrayProperty   m_etaWidthBrem         {this, "etaWidthBrem"        , {0.2}     , "eta Width of road for brem (cut for brem)"};
+      DoubleArrayProperty   m_phiWidthBrem         {this, "phiWidthBrem"        , {0.3}     , "phi Width of road for brem (cut for brem)"};
+      DoubleArrayProperty   m_minPTBrem            {this, "minPTBrem"           , {1000.0}  , "min pT for brem reocvery [MeV]"           };
+      DoubleArrayProperty   m_Xi2max               {this, "Xi2max"              , {9.0}     , "Xi2 max"                                  };
+      DoubleArrayProperty   m_Xi2maxNoAdd          {this, "Xi2maxNoAdd"         , {25.0}    , "Xi2 max no add"                           };
+      IntegerArrayProperty  m_minClusters          {this, "minClusters"         , {9}       , "min number of (Si) clusters (Si hits)"    };
+      IntegerArrayProperty  m_minPixelHits         {this, "minPixelHits"        , {1}       , "min number of pixel hits"                 };
+      IntegerArrayProperty  m_minSiNotShared       {this, "minSiNotShared"      , {7}       , "min number of NOT shared"                 };
+      IntegerArrayProperty  m_maxShared            {this, "maxShared"           , {2}       , "max number of shared"                     };
+      IntegerArrayProperty  m_maxHoles             {this, "maxHoles"            , {2}       , "max number of Si holes"                   };
+      IntegerArrayProperty  m_maxPixelHoles        {this, "maxPixelHoles"       , {1}       , "max number of Pixel holes"                };
+      IntegerArrayProperty  m_maxSctHoles          {this, "maxSctHoles"         , {2}       , "max number of SCT holes"                  };
+      IntegerArrayProperty  m_maxDoubleHoles       {this, "maxDoubleHoles"      , {1}       , "max number of double holes"               };
+      IntegerArrayProperty  m_maxHolesPattern      {this, "maxHolesPattern"     , {2}       , "max holes in pattern"                     };
+      IntegerArrayProperty  m_maxHolesGapPattern   {this, "maxHolesGapPattern"  , {2}       , "max holes gap in pattern"                 };
+      IntegerArrayProperty  m_nWeightedClustersMin {this, "nWeightedClustersMin", {6}       , "min number of weigthed clusters"          };
+      
+      
+    }; 
+
+    
+}   // end namespace
+
+
+
+#endif //> !INDETETADEPENDENTCUTS_INDETETADEPENDENTCUTSSVC_H
diff --git a/InnerDetector/InDetRecTools/InDetEtaDependentCuts/src/InDetEtaDependentCutsSvc.cxx b/InnerDetector/InDetRecTools/InDetEtaDependentCuts/src/InDetEtaDependentCutsSvc.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..941bc8d3fcd51ea4428767fd9d1380b4e3b319c7
--- /dev/null
+++ b/InnerDetector/InDetRecTools/InDetEtaDependentCuts/src/InDetEtaDependentCutsSvc.cxx
@@ -0,0 +1,329 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+// InDetEtaDependentCutsSvc includes
+#include "InDetEtaDependentCuts/InDetEtaDependentCutsSvc.h"
+
+#include <cmath>
+#include <functional>
+#include <variant>
+
+namespace InDet {
+  
+  ////////////////
+  // Constructors
+  ////////////////
+  InDetEtaDependentCutsSvc::InDetEtaDependentCutsSvc(const std::string& name, 
+                                                     ISvcLocator* sl):
+    AthService(name, sl)
+    {}
+
+    ///////////////
+    // Destructor
+    ///////////////
+    InDetEtaDependentCutsSvc::~InDetEtaDependentCutsSvc() {}
+    
+    
+    ///////////////
+    // queryInterface
+    ///////////////
+    StatusCode InDetEtaDependentCutsSvc::queryInterface(const InterfaceID& riid, void** ppvIF) {
+      if( IID_IInDetEtaDependentCutsSvc == riid ) {
+        *ppvIF = dynamic_cast< IInDetEtaDependentCutsSvc* >(this); 
+      } else{ 
+        return AthService::queryInterface(riid, ppvIF); 
+      }
+      addRef();
+      return StatusCode::SUCCESS; 
+    }
+
+    ///////////////
+    // Initialize
+    ///////////////
+    StatusCode InDetEtaDependentCutsSvc::initialize() {
+      
+      ATH_MSG_INFO ("Initializing " << name() << "...");
+      
+      if ((m_etaBins.size()-1) <= 0) {
+        ATH_MSG_ERROR( "Wrong inizialisation of eta bins. Check the eta bin values in " << name() );
+        return StatusCode::FAILURE;
+      }
+      
+      // expecting eta bins in ascending order
+      if (not std::is_sorted(m_etaBins.value().begin(), m_etaBins.value().end())) {
+        ATH_MSG_ERROR( "Wrong inizialisation of eta bins in " << name() << ". Values are not sorted!" );
+        return StatusCode::FAILURE;
+      }          
+      
+      using setOfCuts = std::variant< std::reference_wrapper<std::vector <double>>, std::reference_wrapper<std::vector <int>> >;
+      
+      std::vector < setOfCuts > allCuts = { m_etaWidthBrem.value()        , 
+                                            m_maxdImpactSSSSeeds.value()  ,
+                                            m_maxPrimaryImpact.value()    ,
+                                            m_maxZImpact.value()          ,
+                                            m_minPT.value()               ,
+                                            m_minPTBrem.value()           ,
+                                            m_phiWidthBrem.value()        ,
+                                            m_Xi2max.value()              ,
+                                            m_Xi2maxNoAdd.value()         ,
+                                            m_maxDoubleHoles.value()      ,
+                                            m_maxHoles.value()            ,
+                                            m_maxPixelHoles.value()       ,
+                                            m_maxSctHoles.value()         ,
+                                            m_maxShared.value()           ,
+                                            m_minClusters.value()         ,
+                                            m_minPixelHits.value()        ,
+                                            m_minSiNotShared.value()      ,
+                                            m_maxHolesGapPattern.value()  ,
+                                            m_maxHolesPattern.value()     ,
+                                            m_nWeightedClustersMin.value()};
+      
+      // checking if the set of cuts makes sense
+      size_t noOfEtaBins = m_etaBins.size()-1;
+                                            
+      for (setOfCuts& cuts : allCuts) {
+        auto sCode = std::visit([noOfEtaBins] (auto & testingCuts) -> StatusCode { 
+         
+          if (testingCuts.get().size() == noOfEtaBins) 
+            return StatusCode::SUCCESS;
+                                 
+          if (testingCuts.get().size() > noOfEtaBins)
+            return StatusCode::FAILURE;
+          
+          if (testingCuts.get().size() < noOfEtaBins)
+            testingCuts.get().resize(noOfEtaBins, testingCuts.get().back());
+                    
+          return StatusCode::SUCCESS;
+        } , cuts);
+        
+        if (sCode.isFailure()) {
+          ATH_MSG_ERROR( "No. of cut values bigger than eta bins");
+          return sCode;
+        }
+      }
+      
+      // printing all the cuts
+      ATH_MSG_DEBUG ("--- Dynamic cuts ---");
+      ATH_MSG_DEBUG ("Eta bins (size=" << (m_etaBins.size()-1) << "): " << m_etaBins);
+      ATH_MSG_DEBUG ("etaWidthBrem: " << m_etaWidthBrem);
+      ATH_MSG_DEBUG ("maxdImpactSSSSeeds: " << m_maxdImpactSSSSeeds);
+      ATH_MSG_DEBUG ("maxDoubleHoles: " << m_maxDoubleHoles);
+      ATH_MSG_DEBUG ("maxHoles: " << m_maxHoles);
+      ATH_MSG_DEBUG ("maxPixelHoles: " << m_maxPixelHoles);
+      ATH_MSG_DEBUG ("maxPrimaryImpact: " << m_maxPrimaryImpact);
+      ATH_MSG_DEBUG ("maxSctHoles: " << m_maxSctHoles);
+      ATH_MSG_DEBUG ("maxShared: " << m_maxShared);
+      ATH_MSG_DEBUG ("maxZImpact: " << m_maxZImpact);
+      ATH_MSG_DEBUG ("minClusters: " << m_minClusters);
+      ATH_MSG_DEBUG ("minPixelHits: " << m_minPixelHits);
+      ATH_MSG_DEBUG ("minPT: " << m_minPT);
+      ATH_MSG_DEBUG ("minPTBrem: " << m_minPTBrem);
+      ATH_MSG_DEBUG ("minSiNotShared: " << m_minSiNotShared);
+      ATH_MSG_DEBUG ("nHolesGapMax: " << m_maxHolesGapPattern);
+      ATH_MSG_DEBUG ("nHolesMax: " << m_maxHolesPattern);
+      ATH_MSG_DEBUG ("nWeightedClustersMin: " << m_nWeightedClustersMin);
+      ATH_MSG_DEBUG ("phiWidthBrem: " << m_phiWidthBrem);
+      ATH_MSG_DEBUG ("Xi2max: " << m_Xi2max);
+      ATH_MSG_DEBUG ("Xi2maxNoAdd: " << m_Xi2maxNoAdd);   
+
+      return StatusCode::SUCCESS;
+    }
+    
+    ///////////////
+    // Finalize
+    ///////////////
+    StatusCode InDetEtaDependentCutsSvc::finalize() {
+      ATH_MSG_INFO ("Finalizing " << name() << "...");
+      return StatusCode::SUCCESS;
+    }
+
+    int InDetEtaDependentCutsSvc::getIndexByEta(const double eta) const {
+      double absEta = std::abs(eta);
+      if (absEta > m_etaBins.value().back()) {
+        ATH_MSG_ERROR("Requesting cut value for eta outside expected range!! ");
+        return -1;
+      }
+      
+      auto pVal =  std::lower_bound(m_etaBins.value().begin(), m_etaBins.value().end(), absEta);
+      int bin = std::distance(m_etaBins.value().begin(), pVal) - 1;
+      ATH_MSG_DEBUG("Checking (abs(eta)/bin) = (" << absEta << "," << bin << ")");
+      return bin;
+    }
+
+
+    void InDetEtaDependentCutsSvc::getValue(const InDet::CutName cutName, std::vector < double >& cuts) {
+      // getting the number of eta bins
+      size_t noOfEtaBins = m_etaBins.size()-1;
+      
+      // resize the cuts vector before setting it
+      cuts.resize(noOfEtaBins);
+      
+      switch (cutName) {
+        case InDet::CutName::etaBins:
+          cuts = m_etaBins;
+          break;
+        
+        case InDet::CutName::minPT:
+          cuts = m_minPT;
+          break;
+          
+        case InDet::CutName::maxPrimaryImpact:
+          cuts = m_maxPrimaryImpact;
+          break;
+          
+        case InDet::CutName::maxZImpact:
+          cuts = m_maxZImpact;
+          
+          break;
+        case InDet::CutName::Xi2max:
+          cuts = m_Xi2max;
+          break;
+          
+        case InDet::CutName::Xi2maxNoAdd:
+          cuts = m_Xi2maxNoAdd;
+          break;
+          
+        case InDet::CutName::maxdImpactSSSSeeds:
+          cuts = m_maxdImpactSSSSeeds;
+          break;
+        
+        case InDet::CutName::minPTBrem:
+          cuts = m_minPTBrem;
+          break;
+          
+        case InDet::CutName::etaWidthBrem:
+          cuts = m_etaWidthBrem;
+          break;
+          
+        case InDet::CutName::phiWidthBrem:
+          cuts = m_phiWidthBrem;
+          break;
+        
+        default:
+          ATH_MSG_ERROR("CutName not recognized. Cuts will remain unchanged.");
+          break;
+      }
+    }
+    
+    void InDetEtaDependentCutsSvc::getValue(const InDet::CutName cutName,    std::vector < int >& cuts) {
+
+      // getting the number of eta bins
+      size_t noOfEtaBins = m_etaBins.size()-1;
+      
+      // resize the cuts vector before setting it
+      cuts.resize(noOfEtaBins);
+
+      switch (cutName) {
+        case InDet::CutName::minClusters:
+          cuts = m_minClusters;
+          break;
+        
+        case InDet::CutName::minSiNotShared:
+          cuts = m_minSiNotShared;
+          break;
+          
+        case InDet::CutName::maxShared:
+          cuts = m_maxShared;
+          break;
+          
+        case InDet::CutName::minPixelHits:
+          cuts = m_minPixelHits;
+          
+          break;
+        case InDet::CutName::maxHoles:
+          cuts = m_maxHoles;
+          break;
+          
+        case InDet::CutName::maxPixelHoles:
+          cuts = m_maxPixelHoles;
+          break;
+          
+        case InDet::CutName::maxSctHoles:
+          cuts = m_maxSctHoles;
+          break;
+        
+        case InDet::CutName::maxDoubleHoles:
+          cuts = m_maxDoubleHoles;
+          break;
+          
+        case InDet::CutName::maxHolesPattern:
+          cuts = m_maxHolesPattern;
+          break;
+          
+        case InDet::CutName::maxHolesGapPattern:
+          cuts = m_maxHolesGapPattern;
+          break;
+          
+        case InDet::CutName::nWeightedClustersMin:
+          cuts = m_nWeightedClustersMin;
+          break;
+        
+        default:
+          ATH_MSG_ERROR("CutName not recognized. Cuts will remain unchanged.");
+          break;
+      }
+    }
+  
+    template <class T>
+    T InDetEtaDependentCutsSvc::getValueAtEta(const std::vector< T > cuts, const double eta) const {
+     return cuts.at(getIndexByEta(eta));
+    }
+    
+    template <class T>
+    void InDetEtaDependentCutsSvc::getValue(InDet::CutName cutName, T& cut, double eta) {
+      std::vector < T > cuts; 
+      getValue(cutName, cuts);
+      cut = getValueAtEta< T >(cuts, eta);
+    }
+    
+    double  InDetEtaDependentCutsSvc::getMaxEta() const {
+      return m_etaBins.value().back();
+    }
+    
+    double InDetEtaDependentCutsSvc::getMinPtAtEta(const double eta) const {
+      return getValueAtEta<double>(m_minPT,eta);
+    }
+    
+    double  InDetEtaDependentCutsSvc::getMaxZImpactAtEta      (const double eta) const {
+      return getValueAtEta<double>(m_maxZImpact, eta);
+    }
+    
+    double  InDetEtaDependentCutsSvc::getMaxPrimaryImpactAtEta(const double eta) const {
+      return getValueAtEta<double>(m_maxPrimaryImpact, eta);
+    }
+      
+    int     InDetEtaDependentCutsSvc::getMinSiHitsAtEta       (const double eta) const {
+      return getValueAtEta<int>(m_minClusters, eta);
+    }
+    
+    int     InDetEtaDependentCutsSvc::getMinPixelHitsAtEta    (const double eta) const {
+      return getValueAtEta<int>(m_minPixelHits, eta);
+    }
+    
+    int     InDetEtaDependentCutsSvc::getMaxSiHolesAtEta      (const double eta) const {
+      return getValueAtEta<int>(m_maxHoles, eta);
+    }
+    
+    int     InDetEtaDependentCutsSvc::getMaxPixelHolesAtEta   (const double eta) const {
+      return getValueAtEta<int>(m_maxPixelHoles, eta);
+    }
+    
+    int     InDetEtaDependentCutsSvc::getMaxSctHolesAtEta     (const double eta) const {
+      return getValueAtEta<int>(m_maxSctHoles, eta);
+    }
+    
+    int     InDetEtaDependentCutsSvc::getMaxDoubleHolesAtEta  (const double eta) const {
+      return getValueAtEta<int>(m_maxDoubleHoles, eta);
+    }
+    
+    int     InDetEtaDependentCutsSvc::getMinSiNotSharedAtEta  (const double eta) const {
+      return getValueAtEta<int>(m_minSiNotShared, eta);
+    }
+    
+    int     InDetEtaDependentCutsSvc::getMaxSharedAtEta  (const double eta) const {
+      return getValueAtEta<int>(m_maxShared, eta);
+    }
+      
+}   // end namespace
diff --git a/InnerDetector/InDetRecTools/InDetEtaDependentCuts/src/components/InDetEtaDependentCuts_entries.cxx b/InnerDetector/InDetRecTools/InDetEtaDependentCuts/src/components/InDetEtaDependentCuts_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0c548727a78ae45cf100e8828dcd8e65c3fbcf8a
--- /dev/null
+++ b/InnerDetector/InDetRecTools/InDetEtaDependentCuts/src/components/InDetEtaDependentCuts_entries.cxx
@@ -0,0 +1,3 @@
+#include "InDetEtaDependentCuts/InDetEtaDependentCutsSvc.h"
+
+DECLARE_COMPONENT( InDet::InDetEtaDependentCutsSvc )
diff --git a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/InDetPriVxFinderTool/InDetAdaptiveMultiPriVxFinderTool.h b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/InDetPriVxFinderTool/InDetAdaptiveMultiPriVxFinderTool.h
index 4b210fd05f60a9c0a932d48d32beb363692c0f81..054694ac30d3923283c6474fbb89e12ad0ad1394 100755
--- a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/InDetPriVxFinderTool/InDetAdaptiveMultiPriVxFinderTool.h
+++ b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/InDetPriVxFinderTool/InDetAdaptiveMultiPriVxFinderTool.h
@@ -83,28 +83,31 @@
 #define INDETPRIVXFINDERTOOL_INDETADAPTIVEMULTIPRIVXFINDERTOOL_H
 
 #include "AthenaBaseComps/AthAlgTool.h"
-#include "CxxUtils/checker_macros.h"
-#include "GaudiKernel/ServiceHandle.h"
 #include "GaudiKernel/ToolHandle.h"
-#include "InDetRecToolInterfaces/IVertexFinder.h"
+#include "GaudiKernel/EventContext.h"
 #include "TrkParameters/TrackParameters.h"
 #include "TrkParticleBase/TrackParticleBaseCollection.h"
 #include "TrkTrack/TrackCollection.h" // type def ...
-#include <utility>
+
+#include "BeamSpotConditionsData/BeamSpotData.h"
+#include "InDetRecToolInterfaces/IVertexFinder.h"
+#include "TrkVertexFitters/AdaptiveMultiVertexFitter.h"
+#include "InDetTrackSelectionTool/IInDetTrackSelectionTool.h"
+#include "TrkVertexFitterInterfaces/IVertexAnalyticSeedFinder.h"
+#include "TrkVertexFitterInterfaces/ITrackToVertexIPEstimator.h"
 /**
  * Forward declarations
  */
-#include "BeamSpotConditionsData/BeamSpotData.h"
-#include "TrkVertexFitterInterfaces/ITrackToVertexIPEstimator.h"
 #include "xAODTracking/TrackParticleContainerFwd.h"
 #include "xAODTracking/TrackParticleFwd.h"
 #include "xAODTracking/VertexContainerFwd.h"
 #include "xAODTracking/VertexFwd.h"
+
+#include <utility>
+
 class TrackToVtxLinkContainer;
 
 namespace Trk {
-class IVertexAnalyticSeedFinder;
-class AdaptiveMultiVertexFitter;
 class Track;
 class ITrackLink;
 class TrkQuality;
@@ -112,7 +115,6 @@ class IVxCandidateXAODVertex;
 }
 
 namespace InDet {
-class IInDetTrackSelectionTool;
 
 class InDetAdaptiveMultiPriVxFinderTool
   : public AthAlgTool
@@ -123,7 +125,8 @@ public:
   InDetAdaptiveMultiPriVxFinderTool(const std::string& t,
                                     const std::string& n,
                                     const IInterface* p);
-  virtual ~InDetAdaptiveMultiPriVxFinderTool();
+
+  virtual ~InDetAdaptiveMultiPriVxFinderTool() = default;
 
   virtual StatusCode initialize() override;
 
@@ -140,23 +143,51 @@ public:
   using IVertexFinder::findVertex;
 
   virtual std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
-  findVertex(const TrackCollection* trackTES) const override;
+  findVertex(const EventContext& ctx,
+             const TrackCollection* trackTES) const override;
 
   virtual std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
-  findVertex(const xAOD::TrackParticleContainer* trackParticles) const override;
+  findVertex(const EventContext& ctx,
+             const xAOD::TrackParticleContainer* trackParticles) const override;
 
   virtual StatusCode finalize() override;
 
 private:
   std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*> findVertex(
+    const EventContext& ctx,
     const std::vector<const Trk::ITrackLink*>& trackVector) const;
 
   void SGError(const std::string& errService);
-  virtual void printParameterSettings();
+  void printParameterSettings();
+ 
+  ToolHandle<Trk::AdaptiveMultiVertexFitter> m_MultiVertexFitter{
+    this,
+    "VertexFitterTool",
+    "Trk::AdaptiveMultiVertexFitter",
+    "Multi Vertex Fitter"
+  };
+  ToolHandle<Trk::IVertexAnalyticSeedFinder> m_analyticSeedFinder{
+    this,
+    "SeedFinder",
+    "Trk::TrackDensitySeedFinder",
+    " Seed Finder"
+  };
+  ToolHandle<InDet::IInDetTrackSelectionTool> m_trkFilter{
+    this,
+    "TrackSelector",
+    "InDet::InDetTrackSelection",
+    "Track Selection Tool"
+  };
 
-  ToolHandle<Trk::AdaptiveMultiVertexFitter> m_MultiVertexFitter;
-  ToolHandle<Trk::IVertexAnalyticSeedFinder> m_analyticSeedFinder;
-  ToolHandle<InDet::IInDetTrackSelectionTool> m_trkFilter;
+  /*
+   * Impact parameter estimator used to calculate significance
+   */
+  ToolHandle<Trk::ITrackToVertexIPEstimator> m_ipEstimator{
+    this,
+    "IPEstimator",
+    "Trk::TrackToVertexIPEstimator",
+    "IP estimator"
+  };
 
   SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey{
     this,
@@ -257,13 +288,6 @@ private:
 
   double m_minweight;
 
-  /*
-   * Impact parameter estimator used to calculate significance
-   */
-  ToolHandle<Trk::ITrackToVertexIPEstimator> m_ipEstimator{
-    "Trk::TrackToVertexIPEstimator"
-  };
-
   /*
    * Maximum amount of iterations allowed for vertex finding.
    *
diff --git a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/InDetPriVxFinderTool/InDetAdaptivePriVxFinderTool.h b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/InDetPriVxFinderTool/InDetAdaptivePriVxFinderTool.h
deleted file mode 100755
index 3284422e7b3c2e1ba59daaf70c922597f4f90b3e..0000000000000000000000000000000000000000
--- a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/InDetPriVxFinderTool/InDetAdaptivePriVxFinderTool.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-*/
-
-/**
- *
- * @class InDet::InDetAdaptivePriVxFinderTool
- *
- * @author Giacinto Piacquadio (Freiburg University)
- *
- *
- * This class provides an implementation for a primary
- * vertex finding tool, which uses the Adaptive Vertex
- * Fitter to reject outliers not belonging to the primary
- * vertex interaction.
- *
- * The steps done are simply;
- * - Tracks are selected according to the specified cuts
- * - The Adaptive Vertex Finder is used to fit them
- *
- * Contrary to the InDetPriVxFinderTool, the outlier
- * rejection is done by the fitter and not by the finder.
- *
- * One only vertex can be fit, so it is not suited (as a
- * finder) when many minimum bias vertices can be expected.
- * In this case please use the <i>InDetPriVxFinderTool</i>.
- *
- *
- * (this is a modified verson of InDetPriVxFinderTool.h of A. Wildauer & F.
- *Akesson) changes : 06/12/2006   Kirill.Prokofiev@cern.ch EDM cleanup and
- *switching to the FitQuality use
- *
- *      2016-04-26   David Shope <david.richard.shope@cern.ch>
- *      EDM Migration to xAOD - from Trk::VxCandidate to xAOD::Vertex
- *
- *        findVertex will now always return an xAOD::VertexContainer,
- *        even when using a TrackCollection or a TrackParticleBaseCollection
- *        as input.
- *
- ***************************************************************************/
-
-// implemented using as template the InDetPriVxFinderTool class of A. Wildauer
-// and F. Akesson
-
-#ifndef INDETPRIVXFINDERTOOL_INDETADAPTIVEPRIVXFINDERTOOL_H
-#define INDETPRIVXFINDERTOOL_INDETADAPTIVEPRIVXFINDERTOOL_H
-
-#include "AthenaBaseComps/AthAlgTool.h"
-#include "GaudiKernel/ServiceHandle.h"
-#include "GaudiKernel/ToolHandle.h"
-#include "InDetRecToolInterfaces/IVertexFinder.h"
-#include "TrkParameters/TrackParameters.h"
-#include "TrkParticleBase/TrackParticleBaseCollection.h" // type def ...
-#include "TrkTrack/TrackCollection.h"                    // type def ...
-/**
- * Forward declarations
- */
-
-#include "BeamSpotConditionsData/BeamSpotData.h"
-#include "xAODTracking/TrackParticleContainerFwd.h"
-#include "xAODTracking/TrackParticleFwd.h"
-#include "xAODTracking/VertexContainerFwd.h"
-#include "xAODTracking/VertexFwd.h"
-
-namespace Trk {
-class IVertexFitter;
-class Track;
-class TrackParticleBase;
-class IVxCandidateXAODVertex;
-}
-
-namespace InDet {
-class IInDetTrackSelectionTool;
-
-class InDetAdaptivePriVxFinderTool
-  : public AthAlgTool
-  , virtual public IVertexFinder
-{
-
-public:
-  /**
-   * Constructor
-   */
-
-  InDetAdaptivePriVxFinderTool(const std::string& t,
-                               const std::string& n,
-                               const IInterface* p);
-
-  /**
-   * Destructor
-   */
-
-  virtual ~InDetAdaptivePriVxFinderTool();
-
-  virtual StatusCode initialize() override;
-
-  /**
-   * Finding method.
-   * Has as input a track collection and as output
-   * a VxContainer.
-   */
-
-  using IVertexFinder::findVertex;
-
-  virtual std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*> findVertex(
-    const TrackCollection* trackTES) const override;
- 
-  virtual std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*> findVertex(
-    const xAOD::TrackParticleContainer* trackParticles) const override;
-
-  virtual StatusCode finalize() override;
-
-private:
-  /** the common finding code (regardless of Track or TrackParticle(Base) is
-   * here */
-  std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*> findVertex(
-    std::vector<const Trk::TrackParameters*>& origParameters) const;
-
-  ToolHandle<Trk::IVertexFitter> m_iVertexFitter;
-  ToolHandle<InDet::IInDetTrackSelectionTool> m_trkFilter;
-
-  SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey{
-    this,
-    "BeamSpotKey",
-    "BeamSpotData",
-    "SG key for beam spot"
-  };
-
-  void SGError(const std::string& errService);
-
-  /**
-   * Internal method to print the parameters setting
-   */
-
-  virtual void printParameterSettings();
-
-}; // end of class definitions
-} // end of namespace definitions
-#endif
-
diff --git a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetAdaptiveMultiPriVxFinderTool.cxx b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetAdaptiveMultiPriVxFinderTool.cxx
index baab3314d2cd8b98af40233983f19cb2c91c3382..5701911d59a10ed1c35a92fe7bef6ba4e85656cc 100755
--- a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetAdaptiveMultiPriVxFinderTool.cxx
+++ b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetAdaptiveMultiPriVxFinderTool.cxx
@@ -21,27 +21,20 @@
                           (trial working point for high luminosities)
 
 ***************************************************************************/
+#include "InDetPriVxFinderTool/InDetAdaptiveMultiPriVxFinderTool.h"
 #include "VxVertex/RecVertex.h"
 #include "VxVertex/Vertex.h"
-#include "InDetPriVxFinderTool/InDetAdaptiveMultiPriVxFinderTool.h"
 #include "TrkTrack/Track.h"
 #include "TrkParameters/TrackParameters.h"
-#include <map>
-#include <vector>
-
 #include "EventPrimitives/EventPrimitives.h"
 #include "EventPrimitives/EventPrimitivesHelpers.h"
 #include "GeoPrimitives/GeoPrimitives.h"
 
-#include "InDetTrackSelectionTool/IInDetTrackSelectionTool.h"
-
 #include "VxMultiVertex/MvfFitInfo.h"
 #include "VxMultiVertex/MVFVxTrackAtVertex.h"
 #include "VxMultiVertex/TrackToVtxLink.h"
 #include "AthContainers/DataVector.h"
 #include "TrkEventPrimitives/ParamDefs.h"
-#include "TrkVertexFitters/AdaptiveMultiVertexFitter.h"
-#include "TrkVertexFitterInterfaces/IVertexAnalyticSeedFinder.h"
 #include "TrkTrack/LinkToTrack.h"
 #include "TrkLinks/LinkToXAODTrackParticle.h"
 
@@ -53,66 +46,60 @@
 #include "xAODTracking/TrackParticleAuxContainer.h"
 
 #include <cmath>
+#include <map>
+#include <vector>
 
 namespace InDet
 {
-  InDetAdaptiveMultiPriVxFinderTool::InDetAdaptiveMultiPriVxFinderTool(const std::string& t, const std::string& n,
-                                                                       const IInterface* p)
-    : AthAlgTool(t, n, p),
-    m_MultiVertexFitter("Trk::AdaptiveMultiVertexFitter"),
-    m_analyticSeedFinder("Trk::TrackDensitySeedFinder"),
-    m_trkFilter("InDet::InDetTrackSelection"),
-    m_useBeamConstraint(true),
-    m_TracksMaxZinterval(1.),
-    m_maxVertexChi2(18.42),
-    m_realMultiVertex(true),
-    m_useFastCompatibility(true),
-    m_selectiontype(0),
-    m_finalCutMaxVertexChi2(18.42),
-    m_cutVertexDependence(3.),
-    m_minweight(0.0001),
-    m_maxIterations(100),
-    m_addSingleTrackVertices(false),
-    m_do3dSplitting(false),
-    m_zBfieldApprox(0.60407),
-    m_maximumVertexContamination(0.5),
-    m_tracksMaxSignificance(5.),
-    m_useSeedConstraint(true)
-  {
-    declareInterface<IVertexFinder>(this);//by GP: changed from InDetMultiAdaptivePriVxFinderTool to IPriVxFinderTool
-    /* Retrieve StoreGate container and tool names from job options */
-    declareProperty("SeedFinder", m_analyticSeedFinder);
-    declareProperty("VertexFitterTool", m_MultiVertexFitter);
-    declareProperty("TrackSelector", m_trkFilter);
-
-    //finder options
-    declareProperty("TracksMaxZinterval", m_TracksMaxZinterval);
-    declareProperty("maxVertexChi2", m_maxVertexChi2);
-    declareProperty("finalCutMaxVertexChi2", m_finalCutMaxVertexChi2);
-    declareProperty("cutVertexDependence", m_cutVertexDependence);
-    declareProperty("MinWeight", m_minweight);
-    declareProperty("realMultiVertex", m_realMultiVertex);
-    declareProperty("useFastCompatibility", m_useFastCompatibility);
-    declareProperty("useBeamConstraint", m_useBeamConstraint);
-    declareProperty("addSingleTrackVertices", m_addSingleTrackVertices);
-    declareProperty("tracksMaxSignificance",m_tracksMaxSignificance);
-    declareProperty("m_useSeedConstraint",m_useSeedConstraint);
-    //********* signal vertex selection (for pile up) ****
-    declareProperty("selectiontype", m_selectiontype);
-    //==0 for sum p_t^2
-    //==1 for NN
-    //==2 for min bias compatibility estimation (in the future)
-    declareProperty("maxIterations", m_maxIterations);
-    declareProperty("do3dSplitting", m_do3dSplitting);
-    declareProperty("zBfieldApprox", m_zBfieldApprox);
-    declareProperty("maximumVertexContamination", m_maximumVertexContamination);
-    declareProperty( "IPEstimator", m_ipEstimator );
+InDetAdaptiveMultiPriVxFinderTool::InDetAdaptiveMultiPriVxFinderTool(
+  const std::string& t,
+  const std::string& n,
+  const IInterface* p)
+  : AthAlgTool(t, n, p)
+  , m_useBeamConstraint(true)
+  , m_TracksMaxZinterval(1.)
+  , m_maxVertexChi2(18.42)
+  , m_realMultiVertex(true)
+  , m_useFastCompatibility(true)
+  , m_selectiontype(0)
+  , m_finalCutMaxVertexChi2(18.42)
+  , m_cutVertexDependence(3.)
+  , m_minweight(0.0001)
+  , m_maxIterations(100)
+  , m_addSingleTrackVertices(false)
+  , m_do3dSplitting(false)
+  , m_zBfieldApprox(0.60407)
+  , m_maximumVertexContamination(0.5)
+  , m_tracksMaxSignificance(5.)
+  , m_useSeedConstraint(true)
+{
+  declareInterface<IVertexFinder>(
+    this); // by GP: changed from InDetMultiAdaptivePriVxFinderTool to
+           // IPriVxFinderTool
+  // finder options
+  declareProperty("TracksMaxZinterval", m_TracksMaxZinterval);
+  declareProperty("maxVertexChi2", m_maxVertexChi2);
+  declareProperty("finalCutMaxVertexChi2", m_finalCutMaxVertexChi2);
+  declareProperty("cutVertexDependence", m_cutVertexDependence);
+  declareProperty("MinWeight", m_minweight);
+  declareProperty("realMultiVertex", m_realMultiVertex);
+  declareProperty("useFastCompatibility", m_useFastCompatibility);
+  declareProperty("useBeamConstraint", m_useBeamConstraint);
+  declareProperty("addSingleTrackVertices", m_addSingleTrackVertices);
+  declareProperty("tracksMaxSignificance", m_tracksMaxSignificance);
+  declareProperty("m_useSeedConstraint", m_useSeedConstraint);
+  //********* signal vertex selection (for pile up) ****
+  declareProperty("selectiontype", m_selectiontype);
+  //==0 for sum p_t^2
+  //==1 for NN
+  //==2 for min bias compatibility estimation (in the future)
+  declareProperty("maxIterations", m_maxIterations);
+  declareProperty("do3dSplitting", m_do3dSplitting);
+  declareProperty("zBfieldApprox", m_zBfieldApprox);
+  declareProperty("maximumVertexContamination", m_maximumVertexContamination);
 
   }
 
-  InDetAdaptiveMultiPriVxFinderTool::~InDetAdaptiveMultiPriVxFinderTool()
-  {}
-
   StatusCode
   InDetAdaptiveMultiPriVxFinderTool::initialize() {
     /* Get the right vertex fitting tool */
@@ -146,8 +133,12 @@ namespace InDet
   } //anonymous namespace
 
   std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
-  InDetAdaptiveMultiPriVxFinderTool::findVertex(const TrackCollection* trackTES) const{
-    SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
+  InDetAdaptiveMultiPriVxFinderTool::findVertex(
+    const EventContext& ctx,
+    const TrackCollection* trackTES) const
+  {
+    SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle{ m_beamSpotKey,
+                                                            ctx };
     const Trk::RecVertex &beamposition(beamSpotHandle->beamVtx());
 
     std::vector<const Trk::ITrackLink*> selectedTracks;
@@ -174,7 +165,8 @@ namespace InDet
     ATH_MSG_DEBUG("Of " << trackTES->size() << " tracks "
                         << selectedTracks.size() << " survived the preselection.");
 
-    std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*> returnContainers = findVertex(selectedTracks);
+    std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
+      returnContainers = findVertex(ctx, selectedTracks);
 
     std::vector<const Trk::ITrackLink*>::iterator ibegin = selectedTracks.begin();
     std::vector<const Trk::ITrackLink*>::iterator iend = selectedTracks.end();
@@ -189,11 +181,14 @@ namespace InDet
     return returnContainers;
   }
 
-
   std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
-  InDetAdaptiveMultiPriVxFinderTool::findVertex(const xAOD::TrackParticleContainer* trackParticles) const {
+  InDetAdaptiveMultiPriVxFinderTool::findVertex(
+    const EventContext& ctx,
+    const xAOD::TrackParticleContainer* trackParticles) const
+  {
     std::vector<const Trk::ITrackLink*> selectedTracks;
-    SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
+    SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle{ m_beamSpotKey,
+                                                            ctx };
     xAOD::Vertex beamposition;
     beamposition.makePrivateStore();
     beamposition.setPosition(beamSpotHandle->beamVtx().position());
@@ -227,7 +222,8 @@ namespace InDet
     ATH_MSG_DEBUG(
       "Of " << trackParticles->size() << " tracks " << selectedTracks.size() << " survived the preselection.");
 
-    std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*> returnContainers = findVertex(selectedTracks);
+    std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
+      returnContainers = findVertex(ctx, selectedTracks);
 
     std::vector<const Trk::ITrackLink*>::iterator ibegin = selectedTracks.begin();
     std::vector<const Trk::ITrackLink*>::iterator iend = selectedTracks.end();
@@ -244,13 +240,17 @@ namespace InDet
   }
 
   std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
-  InDetAdaptiveMultiPriVxFinderTool::findVertex(const std::vector<const Trk::ITrackLink*>& trackVector) const {
-    // TODO: put this in a better place
+  InDetAdaptiveMultiPriVxFinderTool::findVertex(
+    const EventContext& ctx,
+    const std::vector<const Trk::ITrackLink*>& trackVector) const
+  {
     // Prepare objects holding the decoration of xAOD::Vertex with MVF auxdata
     // For optimization of access speed
-    xAOD::Vertex::Decorator< Trk::MvfFitInfo* > MvfFitInfo("MvfFitInfo");
-    xAOD::Vertex::Decorator< bool > isInitialized("isInitialized");
-    xAOD::Vertex::Decorator< std::vector< Trk::VxTrackAtVertex* > > VTAV("VTAV");
+    static const xAOD::Vertex::Decorator<Trk::MvfFitInfo*> MvfFitInfo(
+      "MvfFitInfo");
+    static const xAOD::Vertex::Decorator<bool> isInitialized("isInitialized");
+    static const xAOD::Vertex::Decorator<std::vector<Trk::VxTrackAtVertex*>>
+      VTAV("VTAV");
 
     if (m_selectiontype == 1) {
       ATH_MSG_WARNING("Only Selection Type 0 supported for MT");
@@ -271,19 +271,15 @@ namespace InDet
 
     Amg::Vector3D actualVertex;
 
-
     std::map<const Trk::ITrackLink*, Trk::TrackToVtxLink*> TrackLinkOf;
-
     //create a map between ITrackLink* and TrackToVtxLink*
     std::vector<const Trk::ITrackLink*>::const_iterator trkbegin = origTracks.begin();
     std::vector<const Trk::ITrackLink*>::const_iterator trkend = origTracks.end();
 
 
     for (std::vector<const Trk::ITrackLink*>::const_iterator trkiter = trkbegin; trkiter != trkend; ++trkiter) {
-      Trk::TrackToVtxLink* newTrkToVtxLink(new Trk::TrackToVtxLink(new std::vector<xAOD::Vertex*>)); // makePrivateStore()
-                                                                                                     // is called for
-                                                                                                     // each vertex to
-                                                                                                     // add in iteration
+      Trk::TrackToVtxLink* newTrkToVtxLink(new Trk::TrackToVtxLink(new std::vector<xAOD::Vertex*>));
+      // makePrivateStore() is called for each vertex to add in iteration
       TrackLinkOf[*trkiter] = newTrkToVtxLink;
       myTrackToVtxLinks.push_back(newTrkToVtxLink);
     }
@@ -292,7 +288,8 @@ namespace InDet
     //prepare iterators for tracks only necessary for seeding
     std::vector<const Trk::ITrackLink*>::iterator seedtrkbegin = seedTracks.begin();
     std::vector<const Trk::ITrackLink*>::iterator seedtrkend = seedTracks.end();
-    SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
+    SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle{ m_beamSpotKey,
+                                                            ctx };
     int iteration = 0;
 
   int nNoCompatibleTracks(0);
@@ -358,8 +355,9 @@ namespace InDet
       //new xAOD::Vertex with this
       xAOD::Vertex* actualcandidate = new xAOD::Vertex;
       actualcandidate->makePrivateStore();
-      actualcandidate->setVertexType(xAOD::VxType::NotSpecified); // to mimic the initialization present in the old EDM                                                          // constructor
-      // now add decorations!
+      actualcandidate->setVertexType(xAOD::VxType::NotSpecified);
+      // to mimic the initialization present in the old EDM
+      // constructor now add decorations!
       MvfFitInfo(*actualcandidate) = new Trk::MvfFitInfo(constraintVertex,
                                                          new Amg::Vector3D(actualVertex),
                                                          new Amg::Vector3D(actualVertex));
@@ -411,9 +409,12 @@ namespace InDet
           actualVertex = Amg::Vector3D(0., 0., newz);
           actualcandidate = new xAOD::Vertex();
           actualcandidate->makePrivateStore();
-          actualcandidate->setVertexType(xAOD::VxType::NotSpecified); // to mimic the initialization present in the old
-                                                                      // EDM constructor
-          // TODO: Think about where everything is deleted! Does Trk::MvfFitInfo destructor and do MVFVxTrackAtVertex
+          actualcandidate->setVertexType(xAOD::VxType::NotSpecified);
+          // to mimic the initialization present in the old
+          // EDM constructor
+
+          // TODO: Think about where everything is deleted! Does Trk::MvfFitInfo
+          // destructor and do MVFVxTrackAtVertex
           // destructors get called when actualcandidate gets deleted?
           // now add decorations!
           MvfFitInfo(*actualcandidate) = new Trk::MvfFitInfo(new xAOD::Vertex(*constraintVertex),
@@ -623,7 +624,6 @@ namespace InDet
         }
       }
 
-
       ///////////////
       //now break the cycle if you didn't diminish the number of seeds...
       ATH_MSG_DEBUG("Remaining seeds: " << seedTracks.size() << " previous round " << seedtracknumber);
@@ -731,27 +731,34 @@ namespace InDet
   ATH_MSG_DEBUG("Vertices deleted for contamination cut: " << nContamintationCut);
   ATH_MSG_DEBUG("Vertices deleted for proximity to previous: " << nWithin3sigma);
 
-    ATH_MSG_DEBUG("Primary vertex finding complete with " << iteration <<
-                  " iterations and " << myxAODVertices.size() << " vertices found.");
-
-    //correction of a bug: you can estimate the probability of being
-    //the primary interaction vertex only after the whole multivertexfit
-    //is finished!!! (the first is influenced by the fit of the second and so
-    //on...)
-    std::vector<xAODVertex_pair>::iterator vtxBegin = myxAODVertices.begin();
-    std::vector<xAODVertex_pair>::iterator vtxEnd = myxAODVertices.end();
-    // To make sure that the right tracks are in the std::vector<Trk::VxTrackAtVertex> of each vertex - up until now,
-    // they are kept in the VTAV decoration
-    for (std::vector<xAODVertex_pair>::iterator vtxIter = vtxBegin; vtxIter != vtxEnd; ++vtxIter) {
-      xAOD::Vertex* cand = vtxIter->second;
-      std::vector<Trk::VxTrackAtVertex>* tracksOfVertex = &(cand->vxTrackAtVertex());
-      tracksOfVertex->clear();
-      std::vector<Trk::VxTrackAtVertex*>::iterator MVFtrkBegin = VTAV(*cand).begin();
-      std::vector<Trk::VxTrackAtVertex*>::iterator MVFtrkEnd = VTAV(*cand).end();
-      for (std::vector<Trk::VxTrackAtVertex*>::iterator MVFtrkIter = MVFtrkBegin; MVFtrkIter != MVFtrkEnd;
-           ++MVFtrkIter) {
-        tracksOfVertex->push_back(**MVFtrkIter);
-      }
+  ATH_MSG_DEBUG("Primary vertex finding complete with "
+                << iteration << " iterations and " << myxAODVertices.size()
+                << " vertices found.");
+
+  // correction of a bug: you can estimate the probability of being
+  // the primary interaction vertex only after the whole multivertexfit
+  // is finished!!! (the first is influenced by the fit of the second and so
+  // on...)
+  std::vector<xAODVertex_pair>::iterator vtxBegin = myxAODVertices.begin();
+  std::vector<xAODVertex_pair>::iterator vtxEnd = myxAODVertices.end();
+  // To make sure that the right tracks are in the
+  // std::vector<Trk::VxTrackAtVertex> of each vertex - up until now, they are
+  // kept in the VTAV decoration
+  for (std::vector<xAODVertex_pair>::iterator vtxIter = vtxBegin;
+       vtxIter != vtxEnd;
+       ++vtxIter) {
+    xAOD::Vertex* cand = vtxIter->second;
+    std::vector<Trk::VxTrackAtVertex>* tracksOfVertex =
+      &(cand->vxTrackAtVertex());
+    tracksOfVertex->clear();
+    std::vector<Trk::VxTrackAtVertex*>::iterator MVFtrkBegin =
+      VTAV(*cand).begin();
+    std::vector<Trk::VxTrackAtVertex*>::iterator MVFtrkEnd = VTAV(*cand).end();
+    for (std::vector<Trk::VxTrackAtVertex*>::iterator MVFtrkIter = MVFtrkBegin;
+         MVFtrkIter != MVFtrkEnd;
+         ++MVFtrkIter) {
+      tracksOfVertex->push_back(**MVFtrkIter);
+    }
     }
     //before filling the container, you have to decide what is your most probable signal vertex
     for (std::vector<xAODVertex_pair>::iterator vtxIter = vtxBegin; vtxIter != vtxEnd; ++vtxIter) {
@@ -876,7 +883,8 @@ namespace InDet
     // TODO: put this in a better place
     // Prepare objects holding the decoration of xAOD::Vertex with MVF auxdata
     // For optimization of access speed
-    xAOD::Vertex::Decorator< std::vector<Trk::VxTrackAtVertex*> > VTAV("VTAV");
+    static const xAOD::Vertex::Decorator<std::vector<Trk::VxTrackAtVertex*>>
+      VTAV("VTAV");
 
     std::vector<Trk::VxTrackAtVertex*>::iterator begintracks = VTAV(*mycand).begin();
     std::vector<Trk::VxTrackAtVertex*>::iterator endtracks = VTAV(*mycand).end();
@@ -998,7 +1006,8 @@ namespace InDet
     {  
       if ( ipas->sigmad0 > 0 && ipas->sigmaz0 > 0)
       {
-  significance = std::sqrt( std::pow(ipas->IPd0/ipas->sigmad0,2) + std::pow(ipas->IPz0/ipas->sigmaz0,2) );
+        significance = std::sqrt(std::pow(ipas->IPd0 / ipas->sigmad0, 2) +
+                                 std::pow(ipas->IPz0 / ipas->sigmaz0, 2));
       }
       delete ipas;
     }
@@ -1010,8 +1019,8 @@ namespace InDet
     if (candidate == nullptr) return;
 
     // decorators
-    xAOD::Vertex::Decorator< Trk::MvfFitInfo* > MvfFitInfo("MvfFitInfo");
-    xAOD::Vertex::Decorator< std::vector< Trk::VxTrackAtVertex* > > VTAV("VTAV");
+    static const xAOD::Vertex::Decorator< Trk::MvfFitInfo* > MvfFitInfo("MvfFitInfo");
+    static const xAOD::Vertex::Decorator< std::vector< Trk::VxTrackAtVertex* > > VTAV("VTAV");
 
     if (VTAV.isAvailable(*candidate)) {
       for (auto tav : VTAV(*candidate)) {
diff --git a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetAdaptivePriVxFinderTool.cxx b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetAdaptivePriVxFinderTool.cxx
deleted file mode 100755
index 0a6b08589c31be28d413e599a22102e5ba128237..0000000000000000000000000000000000000000
--- a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetAdaptivePriVxFinderTool.cxx
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
-   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
- */
-
-/***************************************************************************
-                         InDetAdaptivePriVxFinderTool.cxx  -  Description
-                             -------------------
-    begin   : 28-01-2004
-    authors : Giacinto Piacquadio (Freiburg Univ),
-              this is a modified version of the primary vertex finder of Andreas Wildauer (CERN PH-ATC), Fredrik Akesson
-                (CERN PH-ATC)
-    changes :
-          06/12/2006   Kirill.Prokofiev@cern.ch
-          EDM cleanup and switching to the FitQuality use
-
-              2016-04-26   David Shope <david.richard.shope@cern.ch>
-              EDM Migration to xAOD - from Trk::VxCandidate to xAOD::Vertex
-
-                findVertex will now always return an xAOD::VertexContainer,
-                even when using a TrackCollection or a TrackParticleBaseCollection
-                as input.
-
-***************************************************************************/
-#include "InDetPriVxFinderTool/InDetAdaptivePriVxFinderTool.h"
-#include "TrkTrack/Track.h"
-#include "TrkEventPrimitives/FitQuality.h"
-#include "TrkTrackSummary/TrackSummary.h"
-#include "TrkParticleBase/TrackParticleBase.h"
-#include "TrkParameters/TrackParameters.h"
-#include <map>
-#include <vector>
-#include <utility>
-#include "EventPrimitives/EventPrimitives.h"
-#include "EventPrimitives/EventPrimitivesHelpers.h"
-#include "GeoPrimitives/GeoPrimitives.h"
-
-#include "InDetTrackSelectionTool/IInDetTrackSelectionTool.h"
-
-//#include "VxVertex/VxContainer.h"
-#include "VxVertex/RecVertex.h"
-#include "VxVertex/VxTrackAtVertex.h"
-#include "AthContainers/DataVector.h"
-#include "TrkEventPrimitives/ParamDefs.h"
-#include "TrkVertexFitterInterfaces/IVertexFitter.h"
-
-#include "TrkTrackLink/ITrackLink.h"
-#include "TrkTrack/LinkToTrack.h"
-#include "TrkLinks/LinkToXAODTrackParticle.h"
-#include "TrkParticleBase/LinkToTrackParticleBase.h"
-//#define INDETADAPTIVEPRIVXFINDERTOOL_DEBUG
-
-#include "xAODTracking/Vertex.h"
-#include "xAODTracking/TrackParticle.h"
-#include "xAODTracking/VertexContainer.h"
-#include "xAODTracking/VertexAuxContainer.h"
-#include "xAODTracking/TrackParticleContainer.h"
-#include "xAODTracking/TrackParticleAuxContainer.h"
-
-namespace InDet
-{
-#if 0
-  namespace {
-    void
-    deleteMeasuredPerigeeIf(bool IsToDelete, const Trk::TrackParameters*& WhatToDelete) {
-      if (IsToDelete) {
-        delete WhatToDelete;
-        WhatToDelete = 0;
-      }
-    }
-  }
-#endif
-
-  InDetAdaptivePriVxFinderTool::InDetAdaptivePriVxFinderTool(const std::string& t, const std::string& n,
-                                                             const IInterface* p)
-    : AthAlgTool(t, n, p),
-    m_iVertexFitter("Trk::AdaptiveVertexFitter"),
-    m_trkFilter("InDet::InDetTrackSelection")
-  {
-    declareInterface<IVertexFinder>(this);//by GP: changed from InDetAdaptivePriVxFinderTool to IPriVxFinderTool
-    /* Retrieve StoreGate container and tool names from job options */
-    declareProperty("VertexFitterTool", m_iVertexFitter);
-    declareProperty("TrackSelector", m_trkFilter);
-    /* Cuts for track preselection */
-  }
-
-  InDetAdaptivePriVxFinderTool::~InDetAdaptivePriVxFinderTool()
-  {}
-
-  StatusCode
-  InDetAdaptivePriVxFinderTool::initialize() {
-    StatusCode sc;
-
-    /* Get the right vertex fitting tool from ToolSvc */
-    if (m_iVertexFitter.retrieve().isFailure()) {
-      msg(MSG::FATAL) << "Failed to retrieve tool " << m_iVertexFitter << endmsg;
-      return StatusCode::FAILURE;
-    }
-
-    ATH_CHECK(m_beamSpotKey.initialize());
-
-    if (m_trkFilter.retrieve().isFailure()) {
-      msg(MSG::ERROR) << " Unable to retrieve " << m_trkFilter << endmsg;
-      return StatusCode::FAILURE;
-    }
-
-    // since some parameters special to an inherited class this method
-    // will be overloaded by the inherited class
-    printParameterSettings();
-
-    msg(MSG::INFO) << "Initialization successful" << endmsg;
-    return StatusCode::SUCCESS;
-  }
-
-  std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
-  InDetAdaptivePriVxFinderTool::findVertex(
-    const TrackCollection* trackTES) const
-  {
-    // TODO: change trkFilter to allow for this replacement
-    /*
-       xAOD::Vertex beamposition;
-       beamposition.makePrivateStore();
-       beamposition.setPosition(beamSpotHandle->beamVtx().position());
-       beamposition.setCovariancePosition(beamSpotHandle->beamVtx().covariancePosition());
-     */
-    SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
-    const Trk::RecVertex &beamposition(beamSpotHandle->beamVtx());
-
-    //---- Start of preselection of tracks ---------------//
-    std::vector<const Trk::TrackParameters*> origParameters;
-    origParameters.clear();
-    for (TrackCollection::const_iterator itr = trackTES->begin(); itr != trackTES->end(); itr++) {
-      if (!static_cast<bool>(m_trkFilter->accept(**itr, &beamposition))) continue;
-      origParameters.push_back((*itr)->perigeeParameters());
-    }
-    if (msgLvl(MSG::DEBUG)) msg() << "Of " << trackTES->size() << " tracks " << origParameters.size() <<
-        " survived the preselection." << endmsg;
-
-    //---- do the actual vertex finding on TrackParameters obejcts ---------------//
-    std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*> returnContainers = findVertex(origParameters);
-
-    //---- validate the element links ---------------//
-    for (xAOD::VertexContainer::iterator vxContItr = returnContainers.first->begin();
-         vxContItr != returnContainers.first->end(); vxContItr++) {
-      std::vector<Trk::VxTrackAtVertex>* tmpVxTAVtx = &(*vxContItr)->vxTrackAtVertex();
-      for (std::vector<Trk::VxTrackAtVertex>::iterator itr = tmpVxTAVtx->begin(); itr != tmpVxTAVtx->end(); itr++) {
-        const Trk::TrackParameters* initialPerigee = (*itr).initialPerigee();
-        const Trk::Track* correspondingTrack(nullptr);
-        // find the track to that perigee ...
-        for (TrackCollection::const_iterator itr1 = trackTES->begin(); itr1 != trackTES->end(); itr1++) {
-          if (initialPerigee == (*itr1)->perigeeParameters()) {
-            correspondingTrack = (*itr1);
-            continue;
-          }
-        }
-
-        // validate the track link
-        if (correspondingTrack != nullptr) {
-          Trk::LinkToTrack* link = new Trk::LinkToTrack;
-          link->setStorableObject(*trackTES);
-          link->setElement(correspondingTrack);
-          (*itr).setOrigTrack(link);
-        } else msg(MSG::WARNING) <<
-          "No corresponding track found for this initial perigee! Vertex will have no link to the track." << endmsg;
-        // TODO: also mention that links stored directly in xAOD::Vertices are not set because a TrackCollection was
-        // given as input
-      }
-    }
-
-    return returnContainers;
-  }
-
-  std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
-  InDetAdaptivePriVxFinderTool::findVertex(
-    const xAOD::TrackParticleContainer* trackParticles) const
-  {
-    ATH_MSG_DEBUG(" Number of input tracks before track selection: " << trackParticles->size());
-    SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
-
-
-    xAOD::Vertex beamposition;
-    beamposition.makePrivateStore();
-    beamposition.setPosition(beamSpotHandle->beamVtx().position());
-    beamposition.setCovariancePosition(beamSpotHandle->beamVtx().covariancePosition());
-
-    //---- Start of preselection of tracks ---------------//
-    std::vector<const Trk::TrackParameters*> origParameters;
-    origParameters.clear();
-
-    typedef DataVector<xAOD::TrackParticle>::const_iterator TrackParticleDataVecIter;
-    for (TrackParticleDataVecIter itr = trackParticles->begin(); itr != trackParticles->end(); ++itr) {
-      if (!static_cast<bool>(m_trkFilter->accept(**itr, &beamposition))) continue;
-      origParameters.push_back(&(*itr)->perigeeParameters());
-      ATH_MSG_DEBUG("originalPerigee at " << &(*itr)->perigeeParameters());
-    }
-
-    //beamposition.releasePrivateStore(); //TODO: should I add this here? it was in InDetPriVxFinderTool method
-
-    ATH_MSG_DEBUG(
-      "Of " << trackParticles->size() << " tracks " << origParameters.size() << " survived the preselection.");
-
-    std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*> returnContainers = findVertex(origParameters);
-
-    for (xAOD::VertexContainer::iterator vxContItr = returnContainers.first->begin();
-    vxContItr != returnContainers.first->end(); ++vxContItr) {
-      std::vector<Trk::VxTrackAtVertex>* tmpVxTAVtx = &(*vxContItr)->vxTrackAtVertex();
-
-      //assigning the input tracks to the fitted vertices through VxTrackAtVertices
-      for (std::vector<Trk::VxTrackAtVertex>::iterator itr = tmpVxTAVtx->begin(); itr != tmpVxTAVtx->end(); itr++) {
-        const Trk::TrackParameters* initialPerigee = (*itr).initialPerigee();
-        const xAOD::TrackParticle* correspondingTrack(nullptr);
-        // find the track to that perigee ...
-        for (TrackParticleDataVecIter itr1 = trackParticles->begin(); itr1 != trackParticles->end(); ++itr1) {
-          if (initialPerigee == &((*itr1)->perigeeParameters())) {
-            correspondingTrack = (*itr1);
-            continue;
-          }
-        }
-        if (correspondingTrack != nullptr) {
-          Trk::LinkToXAODTrackParticle* link = new Trk::LinkToXAODTrackParticle;
-          link->setStorableObject(*trackParticles);
-          link->setElement(correspondingTrack);
-          (*itr).setOrigTrack(link);
-        } else ATH_MSG_WARNING("No corresponding track found for this initial perigee! Vertex will have no link to the track.");
-      } //end of loop over vxTrackAtVertices to assign links
-
-      //now set links to xAOD::TrackParticles directly in xAOD::Vertices
-      unsigned int VTAVsize = (*vxContItr)->vxTrackAtVertex().size();
-      for (unsigned int i = 0; i < VTAVsize; ++i) {
-        Trk::VxTrackAtVertex* VTAV = &((*vxContItr)->vxTrackAtVertex().at(i));
-        //TODO: Will this pointer really hold 0 if no VxTrackAtVertex is found?
-        if (not VTAV) {
-          ATH_MSG_WARNING(" Trying to set link to xAOD::TrackParticle. The VxTrackAtVertex is not found");
-          continue;
-        }
-
-        Trk::ITrackLink* trklink = VTAV->trackOrParticleLink();
-
-        // See if the trklink is to an xAOD::TrackParticle
-        Trk::LinkToXAODTrackParticle* linkToXAODTP = dynamic_cast<Trk::LinkToXAODTrackParticle*>(trklink);
-        if (linkToXAODTP) {
-          //Now set the new link to the xAOD vertex
-          (*vxContItr)->addTrackAtVertex(*linkToXAODTP, VTAV->weight());
-        } else {
-          ATH_MSG_WARNING("Skipping track. Trying to set link to something else than xAOD::TrackParticle. Neutrals not supported.");
-        }
-      } //end of loop for setting links to xAOD::TrackParticles directly in xAOD::Vertices
-    } //end loop over fitted vertices
-
-    return returnContainers;
-  }
-
-  std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
-  InDetAdaptivePriVxFinderTool::findVertex(std::vector<const Trk::TrackParameters*>& origParameters) const{
-    std::vector<Trk::VxTrackAtVertex>* trkAtVtx;
-
-    double vertexPt = 0.;
-    xAOD::VertexContainer* theVertexContainer = new xAOD::VertexContainer;
-    xAOD::VertexAuxContainer* theVertexAuxContainer = new xAOD::VertexAuxContainer;
-    theVertexContainer->setStore(theVertexAuxContainer);
-
-    xAOD::Vertex* myxAODVertex = nullptr;
-
-    //---- Start of fitting section ------------------------------------------------------//
-    if (!origParameters.empty()) {
-      SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
-      xAOD::Vertex beamposition;
-      beamposition.makePrivateStore();
-      beamposition.setPosition(beamSpotHandle->beamVtx().position());
-      beamposition.setCovariancePosition(beamSpotHandle->beamVtx().covariancePosition());
-      beamposition.setFitQuality(beamSpotHandle->beamVtx().fitQuality().chiSquared(), beamSpotHandle->beamVtx().fitQuality().doubleNumberDoF());
-      myxAODVertex = m_iVertexFitter->fit(origParameters, beamposition);
-      /* @TODO? The fit tool does not return tracks chi2 ordered anymore
-                We have to do it */
-    } else if (msgLvl(MSG::DEBUG)) msg() << "Less than two tracks or fitting without constraint - drop candidate vertex." << endmsg;
-    // end if preselection for first iteration
-
-    if (!origParameters.empty()) {
-      /* Store the primary vertex */
-      trkAtVtx = &(myxAODVertex->vxTrackAtVertex());
-      // do a loop through the element links to tracks in myVxCandidate.vxTrackAtVertex[]
-      // if ELEMENTLINKS are used
-      vertexPt = 0.;
-      for (unsigned int i = 0; i < trkAtVtx->size(); ++i) {
-        const Trk::TrackParameters* tmpTP = dynamic_cast<const Trk::TrackParameters*> ((*(trkAtVtx)) [i].initialPerigee());
-        //Second step: calculating the sunm of the pt's
-        if (tmpTP) vertexPt += tmpTP->pT();
-      }
-    } else {
-      if (myxAODVertex != nullptr) {
-        delete myxAODVertex;
-        myxAODVertex = nullptr;
-      }
-    }
-
-
-    if (myxAODVertex != nullptr) {
-      theVertexContainer->push_back(myxAODVertex);
-      if (msgLvl(MSG::DEBUG)) { /* Print info only if requested */
-        double xVtxError = Amg::error(myxAODVertex->covariancePosition(), 0);
-        double yVtxError = Amg::error(myxAODVertex->covariancePosition(), 1);
-        double zVtxError = Amg::error(myxAODVertex->covariancePosition(), 2);
-        msg() << "PVtx at ("
-              << myxAODVertex->position()[0] << "+/-" << xVtxError << ", "
-              << myxAODVertex->position()[1] << "+/-" << yVtxError << ", "
-              << myxAODVertex->position()[2] << "+/-" << zVtxError << ") with chi2 = "
-              << myxAODVertex->chiSquared() << " ("
-              << myxAODVertex->vxTrackAtVertex().size() << " tracks)" << endmsg;
-      }
-    }
-
-    //---- add dummy vertex at the end ------------------------------------------------------//
-    //---- if one or more vertices are already there: let dummy have same position as primary vertex
-    if (!theVertexContainer->empty()) {
-      xAOD::Vertex* primaryVtx = theVertexContainer->front();
-      if (!primaryVtx->vxTrackAtVertex().empty()) {
-        primaryVtx->setVertexType(xAOD::VxType::PriVtx);
-        xAOD::Vertex* dummyxAODVertex = new xAOD::Vertex;
-        theVertexContainer->push_back(dummyxAODVertex); // have to add vertex to container here first so it can use its
-                                                        // aux store
-        dummyxAODVertex->setPosition(primaryVtx->position());
-        dummyxAODVertex->setCovariancePosition(primaryVtx->covariancePosition());
-        dummyxAODVertex->vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
-        dummyxAODVertex->setVertexType(xAOD::VxType::NoVtx);
-      } else {
-        primaryVtx->setVertexType((xAOD::VxType::VertexType) Trk::NoVtx);
-      }
-    }
-    //---- if no vertex is there let dummy be at beam spot
-    else if (theVertexContainer->empty()) {
-      SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
-      xAOD::Vertex* dummyxAODVertex = new xAOD::Vertex;
-      theVertexContainer->push_back(dummyxAODVertex); // have to add vertex to container here first so it can use its
-                                                      // aux store
-      dummyxAODVertex->setPosition(beamSpotHandle->beamVtx().position());
-      dummyxAODVertex->setCovariancePosition(beamSpotHandle->beamVtx().covariancePosition());
-      dummyxAODVertex->vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
-      dummyxAODVertex->setVertexType(xAOD::VxType::NoVtx);
-    }
-
-    // loop over the pile up to set it as pile up (EXCLUDE first and last vertex: loop from 1 to size-1)
-    for (unsigned int i = 1; i < theVertexContainer->size() - 1; i++) {
-      (*theVertexContainer)[i]->setVertexType(xAOD::VxType::PileUp);
-    }
-
-    return std::make_pair(theVertexContainer, theVertexAuxContainer);
-  }
-
-  StatusCode
-  InDetAdaptivePriVxFinderTool::finalize() {
-    return StatusCode::SUCCESS;
-  }
-
-  void
-  InDetAdaptivePriVxFinderTool::printParameterSettings() {
-    msg(MSG::INFO) << "VxPrimary initialize(): Parametersettings " << endmsg;
-    msg(MSG::INFO) << "VertexFitter " << m_iVertexFitter << endmsg;
-    msg(MSG::INFO) << endmsg;
-  }
-
-  void
-  InDetAdaptivePriVxFinderTool::SGError(const std::string& errService) {
-    msg(MSG::FATAL) << errService << " not found. Exiting !" << endmsg;
- }
-} // end namespace InDet
diff --git a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetIterativePriVxFinderTool.cxx b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetIterativePriVxFinderTool.cxx
index ff11c0cc818724c7e0be1b4dfe288d4168390d5d..911eba162a5f8424d255496671b8c771833a7eb1 100755
--- a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetIterativePriVxFinderTool.cxx
+++ b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetIterativePriVxFinderTool.cxx
@@ -94,7 +94,7 @@ namespace InDet
 }
 
 InDetIterativePriVxFinderTool::~InDetIterativePriVxFinderTool()
-{}
+= default;
 
 StatusCode InDetIterativePriVxFinderTool::initialize()
 {
diff --git a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetMultiPriVxFinderTool.cxx b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetMultiPriVxFinderTool.cxx
index cc9217335afc78f4e474e81631e25b430816a081..17ba30ffc95a6cbe630c5b0f707240ca406947fb 100755
--- a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetMultiPriVxFinderTool.cxx
+++ b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetMultiPriVxFinderTool.cxx
@@ -92,7 +92,7 @@ namespace InDet
   }
 
   InDetMultiPriVxFinderTool::~InDetMultiPriVxFinderTool()
-  {}
+  = default;
 
   StatusCode
   InDetMultiPriVxFinderTool::initialize() {
diff --git a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetPriVxFinderTool.cxx b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetPriVxFinderTool.cxx
index 2f26ea76e42fff47a4a6d3df5aaff82112591492..9ac1e16b78b51c75313606e41d317134d2ff3e4b 100755
--- a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetPriVxFinderTool.cxx
+++ b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/InDetPriVxFinderTool.cxx
@@ -91,7 +91,7 @@ namespace InDet
   }
 
   InDetPriVxFinderTool::~InDetPriVxFinderTool()
-  {}
+  = default;
 
   StatusCode
   InDetPriVxFinderTool::initialize() {
diff --git a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/components/InDetPriVxFinderTool_entries.cxx b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/components/InDetPriVxFinderTool_entries.cxx
index 98dc68e9410e1d03c73efae61061070bad025dbf..222a629eb832f7afce977e2e79ae6489d07854c0 100644
--- a/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/components/InDetPriVxFinderTool_entries.cxx
+++ b/InnerDetector/InDetRecTools/InDetPriVxFinderTool/src/components/InDetPriVxFinderTool_entries.cxx
@@ -1,5 +1,4 @@
 #include "InDetPriVxFinderTool/InDetPriVxFinderTool.h"
-#include "InDetPriVxFinderTool/InDetAdaptivePriVxFinderTool.h"
 #include "InDetPriVxFinderTool/InDetIterativePriVxFinderTool.h"
 #include "InDetPriVxFinderTool/InDetAdaptiveMultiPriVxFinderTool.h"
 #include "InDetPriVxFinderTool/InDetMultiPriVxFinderTool.h"
@@ -9,7 +8,6 @@
 using namespace InDet;
 
 DECLARE_COMPONENT( InDetPriVxFinderTool )
-DECLARE_COMPONENT( InDetAdaptivePriVxFinderTool )
 DECLARE_COMPONENT( InDetIterativePriVxFinderTool )
 DECLARE_COMPONENT( InDetAdaptiveMultiPriVxFinderTool )
 DECLARE_COMPONENT( InDetMultiPriVxFinderTool )
diff --git a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/IInDetEtaDependentCutsSvc.h b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/IInDetEtaDependentCutsSvc.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b94a175475e87525547407f8b6570e3c25b9a8d
--- /dev/null
+++ b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/IInDetEtaDependentCutsSvc.h
@@ -0,0 +1,66 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef IINDETETADEPENDENTCUTSSVC_H
+#define IINDETETADEPENDENTCUTSSVC_H
+
+#include "GaudiKernel/IInterface.h"
+
+namespace InDet {
+  
+  static const InterfaceID IID_IInDetEtaDependentCutsSvc("IInDetEtaDependentCutsSvc", 1, 0);
+
+  enum CutName {  
+    etaBins, etaWidthBrem, maxdImpactSSSSeeds, maxDoubleHoles,
+    maxHoles, maxPixelHoles, maxPrimaryImpact, maxSctHoles, 
+    maxShared, maxZImpact, minClusters, minPixelHits, minPT,
+    minPTBrem, minSiNotShared, maxHolesGapPattern, maxHolesPattern,
+    nWeightedClustersMin, phiWidthBrem, Xi2max, Xi2maxNoAdd
+  };
+  
+  class IInDetEtaDependentCutsSvc : virtual public IInterface {
+    
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+  public: 
+    
+    virtual ~IInDetEtaDependentCutsSvc() {};
+    
+    static const InterfaceID& interfaceID();
+    
+    virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvIF)=0;
+    
+    virtual void getValue(const InDet::CutName cutName, std::vector < double >& cut) = 0;
+    virtual void getValue(const InDet::CutName cutName,    std::vector < int >& cut) = 0;
+
+    template <class T>    
+    void getValue(const InDet::CutName cutName, T& cut, const double eta) {}
+    
+    virtual double  getMaxEta() const                         = 0;
+    virtual double  getMinPtAtEta           (const double eta) const = 0;
+    virtual double  getMaxZImpactAtEta      (const double eta) const = 0;
+    virtual double  getMaxPrimaryImpactAtEta(const double eta) const = 0;
+    virtual int     getMinSiHitsAtEta       (const double eta) const = 0;
+    virtual int     getMinSiNotSharedAtEta  (const double eta) const = 0;
+    virtual int     getMaxSharedAtEta       (const double eta) const = 0;
+    virtual int     getMinPixelHitsAtEta    (const double eta) const = 0;
+    virtual int     getMaxSiHolesAtEta      (const double eta) const = 0;
+    virtual int     getMaxPixelHolesAtEta   (const double eta) const = 0;
+    virtual int     getMaxSctHolesAtEta     (const double eta) const = 0;
+    virtual int     getMaxDoubleHolesAtEta  (const double eta) const = 0;
+      
+  };
+  
+  /////////////////////////////////////////////////////////////////// 
+  /// Inline methods: 
+  /////////////////////////////////////////////////////////////////// 
+  inline const InterfaceID& IInDetEtaDependentCutsSvc::interfaceID() 
+  { 
+    return IID_IInDetEtaDependentCutsSvc; 
+  }
+
+}// end namespace
+
+#endif //> !IINDETETADEPENDENTCUTSSVC_H
diff --git a/InnerDetector/InDetRecTools/InDetTestBLayer/InDetTestBLayer/ATLAS_CHECK_THREAD_SAFETY b/InnerDetector/InDetRecTools/InDetTestBLayer/InDetTestBLayer/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..173704c8932c937406e0482c1a2615811ce43b6c
--- /dev/null
+++ b/InnerDetector/InDetRecTools/InDetTestBLayer/InDetTestBLayer/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+InnerDetector/InDetRecTools/InDetTestBLayer
diff --git a/InnerDetector/InDetRecTools/InDetTestBLayer/InDetTestBLayer/InDetTestBLayerTool.h b/InnerDetector/InDetRecTools/InDetTestBLayer/InDetTestBLayer/InDetTestBLayerTool.h
index eb3843a345c084f3eddf13572f7f6a49549c5f3f..9369c7c7c4c5ff77633e16912d07abeab73d91ee 100644
--- a/InnerDetector/InDetRecTools/InDetTestBLayer/InDetTestBLayer/InDetTestBLayerTool.h
+++ b/InnerDetector/InDetRecTools/InDetTestBLayer/InDetTestBLayer/InDetTestBLayerTool.h
@@ -165,7 +165,7 @@ namespace InDet {
     double m_etaRegionSize;
     double m_goodFracCut;
     bool m_checkAtLeastNearestNeighbors;
-    static const char *s_layerNames[2];
+    static const std::string s_layerNames[2];
   };
   
   
diff --git a/InnerDetector/InDetRecTools/InDetTestBLayer/src/InDetTestBLayerTool.cxx b/InnerDetector/InDetRecTools/InDetTestBLayer/src/InDetTestBLayerTool.cxx
index 6eee5fffd426b013cc3023252d240e153b3cd2de..180dde76a47b1025d7b011fcffd73e7dbd842bc4 100644
--- a/InnerDetector/InDetRecTools/InDetTestBLayer/src/InDetTestBLayerTool.cxx
+++ b/InnerDetector/InDetRecTools/InDetTestBLayer/src/InDetTestBLayerTool.cxx
@@ -30,7 +30,7 @@ using Amg::Transform3D;
 // don't want to include TrackSummary in the header
 // therefore anonymous "static" definition in the implementation file
 //namespace {
-  Trk::SummaryType s_layerSummaryTypeExpectHit[2] {
+  static const Trk::SummaryType s_layerSummaryTypeExpectHit[2] {
     Trk::expectInnermostPixelLayerHit,
     Trk::expectNextToInnermostPixelLayerHit
   };
@@ -38,7 +38,7 @@ using Amg::Transform3D;
 
 
 namespace InDet {
-  const char *InDetTestBLayerTool::s_layerNames[2] {
+  const std::string InDetTestBLayerTool::s_layerNames[2] {
     "innermost pixel layer",
     "next to innermost pixel layer"
   };
@@ -346,7 +346,7 @@ namespace InDet {
   bool InDet::InDetTestBLayerTool::expectHitInPixelLayer(const Trk::TrackParameters* trackpar,int layer) const
   {
     assert( layer >=0 && layer<=1);
-    const char *layer_name=s_layerNames[layer];
+    const std::string layer_name=s_layerNames[layer];
 
     if(!m_configured){
       ATH_MSG_WARNING("Unconfigured tool, unable to compute expected hit in the " << layer_name << ".");
diff --git a/InnerDetector/InDetRecTools/InDetTrackHoleSearch/CMakeLists.txt b/InnerDetector/InDetRecTools/InDetTrackHoleSearch/CMakeLists.txt
index 42ec25daa38c10d4047de13ad2e0200f9e329d81..eaf25ab3a11e2663a5548c99a230148d087a190c 100644
--- a/InnerDetector/InDetRecTools/InDetTrackHoleSearch/CMakeLists.txt
+++ b/InnerDetector/InDetRecTools/InDetTrackHoleSearch/CMakeLists.txt
@@ -33,7 +33,7 @@ atlas_depends_on_subdirs( PUBLIC
 atlas_add_component( InDetTrackHoleSearch
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaBaseComps GaudiKernel TrkEventPrimitives TrkParameters TrkToolInterfaces AtlasDetDescr Identifier InDetReadoutGeometry InDetRecToolInterfaces TrkDetDescrUtils TrkGeometry TrkVolumes TrkEventUtils TrkMeasurementBase TrkTrack TrkTrackSummary TrkExInterfaces )
+                     LINK_LIBRARIES AthenaBaseComps GaudiKernel TrkEventPrimitives TrkParameters TrkToolInterfaces AtlasDetDescr Identifier InDetReadoutGeometry InDetRecToolInterfaces TrkDetDescrUtils TrkGeometry TrkVolumes TrkEventUtils TrkMeasurementBase TrkTrack TrkTrackSummary TrkExInterfaces InDetConditionsSummaryService )
 
 # Install files from the package:
 atlas_install_headers( InDetTrackHoleSearch )
diff --git a/InnerDetector/InDetRecTools/InDetTrackScoringTools/InDetTrackScoringTools/InDetAmbiScoringTool.h b/InnerDetector/InDetRecTools/InDetTrackScoringTools/InDetTrackScoringTools/InDetAmbiScoringTool.h
index 3534b80f36fc19550a37c76b71c02629a3c03039..2a920e5fc17cb7218ee9f0db2ba2a0d5b6b9f5df 100755
--- a/InnerDetector/InDetRecTools/InDetTrackScoringTools/InDetTrackScoringTools/InDetAmbiScoringTool.h
+++ b/InnerDetector/InDetRecTools/InDetTrackScoringTools/InDetTrackScoringTools/InDetAmbiScoringTool.h
@@ -66,10 +66,10 @@ class InDetAmbiScoringTool : virtual public Trk::ITrackScoringTool,
   
   //these are used for ScoreModifiers 
   int m_maxDblHoles, m_maxPixHoles, m_maxSCT_Holes,  m_maxHits, m_maxSigmaChi2, m_maxTrtRatio, m_maxTrtFittedRatio,
-    m_maxB_LayerHits, m_maxPixelHits, m_maxPixLay, m_maxLogProb, m_maxGangedFakes;
+    m_maxB_LayerHits, m_maxPixelHits, m_maxPixLay,  m_maxGangedFakes;
   std::vector<double> m_factorDblHoles, m_factorPixHoles, m_factorSCT_Holes,  m_factorHits,
-    m_factorSigmaChi2, m_factorB_LayerHits, m_factorPixelHits, m_factorPixLay, m_factorLogProb, m_factorHoles, m_factorGangedFakes;
-  std::vector<double> m_boundsSigmaChi2, m_boundsLogProb, m_boundsHits,
+    m_factorSigmaChi2, m_factorB_LayerHits, m_factorPixelHits, m_factorPixLay, m_factorHoles, m_factorGangedFakes;
+  std::vector<double> m_boundsSigmaChi2, m_boundsHits,
     m_boundsTrtRatio, m_factorTrtRatio, m_boundsTrtFittedRatio, m_factorTrtFittedRatio;
   
   /**\todo make this const, once createSummary method is const*/
@@ -92,15 +92,12 @@ class InDetAmbiScoringTool : virtual public Trk::ITrackScoringTool,
   /** use the scoring tuned to Ambiguity processing or not */
   bool m_useAmbigFcn;
   bool m_useTRT_AmbigFcn;
-  bool m_useLogProbBins;
   bool m_useSigmaChi2;
   
   bool m_usePixel;
   bool m_useSCT;
 
   /** cuts for selecting good tracks*/
-  int    m_minNDF;        //!< minimal number of degrees of freedom cut
-  //bool   m_fieldOn;       //!< do we have field on ?
   double m_minPt;         //!< minimal Pt cut
   double m_maxEta;        //!< maximal Eta cut
   double m_maxRPhiImp;    //!< maximal RPhi impact parameter cut
diff --git a/InnerDetector/InDetRecTools/InDetTrackScoringTools/InDetTrackScoringTools/InDetTrtTrackScoringTool.h b/InnerDetector/InDetRecTools/InDetTrackScoringTools/InDetTrackScoringTools/InDetTrtTrackScoringTool.h
index 3656ca2f99adfa76826004815ffc3456dce800b6..a22ee1476410466ac7571e8cf612d534e9f147c8 100755
--- a/InnerDetector/InDetRecTools/InDetTrackScoringTools/InDetTrackScoringTools/InDetTrtTrackScoringTool.h
+++ b/InnerDetector/InDetRecTools/InDetTrackScoringTools/InDetTrackScoringTools/InDetTrtTrackScoringTool.h
@@ -58,16 +58,15 @@ private:
   const TRT_ID* m_trtId;
   
   //these are used for ScoreModifiers 
-  int m_maxSigmaChi2, m_maxLogProb, m_maxTrtRatio, m_maxTrtFittedRatio;
+  int m_maxSigmaChi2, m_maxTrtRatio, m_maxTrtFittedRatio;
   
-  std::vector<double> m_factorSigmaChi2, m_factorLogProb, m_factorTrtRatio, m_factorTrtFittedRatio;
+  std::vector<double> m_factorSigmaChi2, m_factorTrtRatio, m_factorTrtFittedRatio;
   
-  std::vector<double> m_boundsSigmaChi2, m_boundsLogProb, m_boundsTrtRatio, m_boundsTrtFittedRatio;
+  std::vector<double> m_boundsSigmaChi2, m_boundsTrtRatio, m_boundsTrtFittedRatio;
 
   
   /** use the scoring tuned to Ambiguity processing or not */
   bool m_useAmbigFcn;
-  bool m_useLogProbBins;
   bool m_useSigmaChi2;
   
   /**holds the scores assigned to each Trk::SummaryType from the track's Trk::TrackSummary*/
diff --git a/InnerDetector/InDetRecTools/InDetTrackScoringTools/src/InDetAmbiScoringTool.cxx b/InnerDetector/InDetRecTools/InDetTrackScoringTools/src/InDetAmbiScoringTool.cxx
index 1d0f450574e929fc3b13ec5cb8fc3c49229ce1f9..faf950d263797fcf36db44cca7437fc59f30e7d9 100755
--- a/InnerDetector/InDetRecTools/InDetTrackScoringTools/src/InDetAmbiScoringTool.cxx
+++ b/InnerDetector/InDetRecTools/InDetTrackScoringTools/src/InDetAmbiScoringTool.cxx
@@ -14,8 +14,6 @@
 #include "TrkParameters/TrackParameters.h"
 #include "TrkExInterfaces/IExtrapolator.h"
 #include "CLHEP/GenericFunctions/CumulativeChiSquare.hh"
-#include "TMath.h"
-#include <vector>
 #include "GeoPrimitives/GeoPrimitives.h"
 #include "TrkCaloClusterROI/CaloClusterROI.h"
 #include "TrkCaloClusterROI/CaloClusterROI_Collection.h"
@@ -40,7 +38,6 @@ InDet::InDetAmbiScoringTool::InDetAmbiScoringTool(const std::string& t,
   m_maxB_LayerHits(-1),
   m_maxPixelHits(-1),
   m_maxPixLay(-1),
-  m_maxLogProb(-1),
   m_maxGangedFakes(-1),
   m_trkSummaryTool("Trk::TrackSummaryTool", this),
   m_selectortool("InDet::InDetTrtDriftCircleCutTool", this),
@@ -50,7 +47,6 @@ InDet::InDetAmbiScoringTool::InDetAmbiScoringTool(const std::string& t,
   declareInterface<Trk::ITrackScoringTool>(this);
   
   // declare properties
-  declareProperty("minNDF",            m_minNDF             = 0);
   declareProperty("minPt",             m_minPt              = 500.);
   declareProperty("maxEta",            m_maxEta             = 2.7);
   declareProperty("maxRPhiImp",        m_maxRPhiImp         = 10.);
@@ -73,7 +69,6 @@ InDet::InDetAmbiScoringTool::InDetAmbiScoringTool(const std::string& t,
   // switches and tools
   declareProperty("useAmbigFcn",       m_useAmbigFcn        = true);
   declareProperty("useTRT_AmbigFcn",   m_useTRT_AmbigFcn    = false);
-  declareProperty("useLogProbBins",    m_useLogProbBins     = false);
   declareProperty("useSigmaChi2",      m_useSigmaChi2       = false);
 
   // tools
@@ -227,10 +222,6 @@ Trk::TrackScore InDet::InDetAmbiScoringTool::simpleScore( const Trk::Track& trac
     // NdF cut :
     if (track.fitQuality()) {
       ATH_MSG_DEBUG ("numberDoF = "<<track.fitQuality()->numberDoF());
-      if (track.fitQuality()->numberDoF() < m_minNDF) {
-        ATH_MSG_DEBUG ("track numberDoF < "<<m_minNDF<<", reject it");
-        return Trk::TrackScore(0);
-      }
     }
     // Number of double Holes
     if (numSCTDoubleHoles>=0) {
@@ -553,7 +544,7 @@ Trk::TrackScore InDet::InDetAmbiScoringTool::ambigScore( const Trk::Track& track
   // 
   // --- non binned Chi2
   //
-  if (!ispatterntrack && !m_useLogProbBins) {
+  if (!ispatterntrack) {
     if (track.fitQuality()!=0 && track.fitQuality()->chiSquared()>0 && track.fitQuality()->numberDoF()>0 ) {
       int    indf  = track.fitQuality()->numberDoF();
       double chi2  = track.fitQuality()->chiSquared();
@@ -567,40 +558,11 @@ Trk::TrackScore InDet::InDetAmbiScoringTool::ambigScore( const Trk::Track& track
   //
   // --- fit quality prob
   //
-  if ( !ispatterntrack && (m_useLogProbBins || m_useSigmaChi2) && track.fitQuality() ) {
+  if ( !ispatterntrack && (m_useSigmaChi2) && track.fitQuality() ) {
 
     int    ndf  = track.fitQuality()->numberDoF();
     double chi2 = track.fitQuality()->chiSquared();
     if (ndf > 0) {
-
-      //
-      // --- first the chi2 prob
-      //
-      if (m_useLogProbBins) {
-        double p = TMath::Prob(chi2,ndf);
-        if (p > 0.) {
-          p = log(p);
-          if ( m_boundsLogProb[0] < p  && p <= m_boundsLogProb[m_maxLogProb] ) {
-            for (int ii=0; ii<m_maxLogProb; ++ii) {
-              if ( m_boundsLogProb[ii]<p && p<=m_boundsLogProb[ii+1] ) {
-          prob *= m_factorLogProb[ii];
-          ATH_MSG_DEBUG ("Modifier for " << p << " prob.-log.: "<< m_factorLogProb[ii]
-                   << "  New score now: " << prob);
-          break;
-              }
-            }
-          } else if ( p < m_boundsLogProb[0] ) { 
-            prob *= m_factorLogProb[0];
-            ATH_MSG_DEBUG ("Modifier for " << p << " prob.-log.: "<< m_factorLogProb[0]
-               << "  New score now: " << prob);
-          } else {
-            prob *= m_factorLogProb[m_maxLogProb-1];
-            ATH_MSG_DEBUG ("Modifier for " << p << " prob.-log.: "<< m_factorLogProb[m_maxLogProb-1]
-               << "  New score now: " << prob);
-          }
-        }
-      }
-
       //
       // --- special variable for bad chi2 distribution
       //
@@ -797,34 +759,6 @@ void InDet::InDetAmbiScoringTool::setupScoreModifiers()
   for (int i=0; i<m_maxTrtFittedRatio; ++i) m_factorTrtFittedRatio.push_back(goodTrtFittedRatio[i]/fakeTrtFittedRatio[i]);
   for (int i=0; i<=m_maxTrtFittedRatio; ++i) m_boundsTrtFittedRatio.push_back(TrtFittedRatioBounds[i]);
 
-  //
-  // --- chi2 prob
-  //
-  if (!m_useLogProbBins) {
-    m_maxLogProb = -1 ;
-  } else {
-    if (!m_useTRT_AmbigFcn) {
-      // --- NewTracking
-      const int maxLogProb = 10;
-      const double LogProbBounds[maxLogProb+1] = {-10., -9., -8., -7., -6., -5., -4., -3., -2., -1., 0.};
-      const double goodLogProb[maxLogProb] = {0.01, 0.01, 0.015, 0.02, 0.025, 0.045, 0.08, 0.11 , 0.21, 0.45};
-      const double fakeLogProb[maxLogProb] = {0.04, 0.04, 0.05 , 0.06, 0.06 , 0.07 , 0.09, 0.115, 0.15, 0.18};
-      // put it into the private members
-      m_maxLogProb = maxLogProb;
-      for (int i=0; i<m_maxLogProb; ++i) m_factorLogProb.push_back(goodLogProb[i]/fakeLogProb[i]);
-      for (int i=0; i<=m_maxLogProb; ++i) m_boundsLogProb.push_back(LogProbBounds[i]);
-    } else {
-      // --- BackTracking
-      const int maxLogProb = 12;
-      const double LogProbBounds[maxLogProb+1] = {-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0};
-      const double goodLogProb[maxLogProb] = {0.002, 0.002, 0.004, 0.007, 0.008, 0.012, 0.020, 0.033, 0.051, 0.104, 0.219, 0.531};
-      const double fakeLogProb[maxLogProb] = {0.020, 0.025, 0.032, 0.030, 0.042, 0.051, 0.063, 0.071, 0.080, 0.112, 0.156, 0.216};
-      // put it into the private members
-      m_maxLogProb = maxLogProb;
-      for (int i=0; i<m_maxLogProb; ++i) m_factorLogProb.push_back(goodLogProb[i]/fakeLogProb[i]);
-      for (int i=0; i<=m_maxLogProb; ++i) m_boundsLogProb.push_back(LogProbBounds[i]);
-    }
-  }
 
   //
   // --- sigma chi2
@@ -880,10 +814,6 @@ void InDet::InDetAmbiScoringTool::setupScoreModifiers()
       msg(MSG::VERBOSE) << "Modifier for " << m_boundsTrtFittedRatio[i] << " < TRT fitted ratio  < "
       << m_boundsTrtFittedRatio[i+1] <<"  : " <<m_factorTrtFittedRatio[i] <<endmsg;
     
-    // only if used
-    for (int i=0; i<m_maxLogProb; ++i)
-      msg(MSG::VERBOSE) << "Modifier for " << m_boundsLogProb[i] << " < log(P)  < "
-      << m_boundsLogProb[i+1] <<"  : " <<m_factorLogProb[i] <<endmsg;
     
     // only if used
     for (int i=0; i<m_maxSigmaChi2; ++i)
diff --git a/InnerDetector/InDetRecTools/InDetTrackScoringTools/src/InDetTrtTrackScoringTool.cxx b/InnerDetector/InDetRecTools/InDetTrackScoringTools/src/InDetTrtTrackScoringTool.cxx
index 30c9ce8c606e89bb330232856f7d3cf3cc7d8158..5a127b3b71d582c1ee99336d8b3e93d3d00e21e5 100755
--- a/InnerDetector/InDetRecTools/InDetTrackScoringTools/src/InDetTrtTrackScoringTool.cxx
+++ b/InnerDetector/InDetRecTools/InDetTrackScoringTools/src/InDetTrtTrackScoringTool.cxx
@@ -12,8 +12,7 @@
 #include "TrkParameters/TrackParameters.h"
 #include "CLHEP/GenericFunctions/CumulativeChiSquare.hh"
 #include "InDetIdentifier/TRT_ID.h"
-#include "TMath.h"
-#include <vector>
+
 
 //---------------------------------------------------------------------------------------------------------------------
 
@@ -25,7 +24,6 @@ InDet::InDetTrtTrackScoringTool::InDetTrtTrackScoringTool(const std::string& t,
   m_trtId(nullptr),
   // Initialization of ScoreModifiers variables
   m_maxSigmaChi2(-1), 
-  m_maxLogProb(-1),
   m_maxTrtRatio(-1),
   m_maxTrtFittedRatio(-1),
   m_summaryTypeScore(Trk::numberOfTrackSummaryTypes),
@@ -41,7 +39,6 @@ InDet::InDetTrtTrackScoringTool::InDetTrtTrackScoringTool(const std::string& t,
   declareProperty("DriftCircleCutTool",      m_selectortool   );
   declareProperty("useAmbigFcn",             m_useAmbigFcn    = true );
   declareProperty("useSigmaChi2",            m_useSigmaChi2   = false);
-  declareProperty("useLogProbBins",          m_useLogProbBins = false);
   declareProperty("minTRTonTrk",             m_minTRTonTrk    = 15 );
   declareProperty("maxEta",                  m_maxEta         = 2.1);
   declareProperty("PtMin",                   m_ptmin          = 1.0); //pt min cut
@@ -264,52 +261,27 @@ Trk::TrackScore InDet::InDetTrtTrackScoringTool::TRT_ambigScore( const Trk::Trac
 
   // 
   // --- non binned Chi2
-  if (!m_useLogProbBins) {
-    if (track.fitQuality()!=0 && track.fitQuality()->chiSquared()>0 && track.fitQuality()->numberDoF()>0 ) {
-      int    indf  = track.fitQuality()->numberDoF();
-      double chi2  = track.fitQuality()->chiSquared();
-      double fac   = 1. / log10 (10. + 10. * chi2 / indf); // very soft chi2 
-      prob        *= fac;
-      ATH_MSG_VERBOSE( "Modifier for chi2 = " << chi2 << " and NDF = " << indf
-						            << " is : "<< fac << "  New score now: " << prob );	    
+  
+  if (track.fitQuality()!=0 && track.fitQuality()->chiSquared()>0 && track.fitQuality()->numberDoF()>0 ) {
+    int    indf  = track.fitQuality()->numberDoF();
+    double chi2  = track.fitQuality()->chiSquared();
+    double fac   = 1. / log10 (10. + 10. * chi2 / indf); // very soft chi2 
+    prob        *= fac;
+    ATH_MSG_VERBOSE( "Modifier for chi2 = " << chi2 << " and NDF = " << indf
+                      << " is : "<< fac << "  New score now: " << prob );	    
 
-    }
   }
+  
   //
   // --- do we use the binned prob for chi2/NDF or sigma chi2 ?
   //
-  if ( (m_useLogProbBins || m_useSigmaChi2) && track.fitQuality() ) {
+  if ( (m_useSigmaChi2) && track.fitQuality() ) {
 
     int    indf  = track.fitQuality()->numberDoF();
     double ichi2 = track.fitQuality()->chiSquared();
     if (indf>0) {
 
-      //
-      // --- binned chi2/NDF score
-      //
-      if (m_useLogProbBins) {
-        double p = TMath::Prob(ichi2,indf);
-        if (p>0.) {
-          p=log(p); 
-          if ( m_boundsLogProb[0]<p && p<=m_boundsLogProb[m_maxLogProb] ) {
-            for (int ii=0; ii<m_maxLogProb; ++ii) {
-              if ( m_boundsLogProb[ii]<p && p<=m_boundsLogProb[ii+1] ) {
-          prob *= m_factorLogProb[ii];
-          ATH_MSG_VERBOSE( "Modifier for WITHIN BOUNDS " << p << " prob.-log.: "<< m_factorLogProb[ii]
-                            << "  New score now: " << prob );	    
-              }
-            }
-          } else if ( p < m_boundsLogProb[0] ) {
-            prob *= m_factorLogProb[0];
-            ATH_MSG_VERBOSE( "Modifier for LOW BOUND " << p << " prob.-log.: "<< m_factorLogProb[0]
-                             << "  New score now: " << prob );	    
-          } else {
-            prob *= m_factorLogProb[m_maxLogProb-1];
-            ATH_MSG_VERBOSE( "Modifier for HIGH BOUND " << p << " prob.-log.: "<< m_factorLogProb[m_maxLogProb-1]
-                              << "  New score now: " << prob );	    
-          }
-        }
-      }
+      
       
       //
       // --- binned sigma chi2 score
@@ -348,21 +320,6 @@ Trk::TrackScore InDet::InDetTrtTrackScoringTool::TRT_ambigScore( const Trk::Trac
 //-----------------------------------------------------------------------------------------------------------
 void InDet::InDetTrtTrackScoringTool::setupTRT_ScoreModifiers()
 {
-  /*
-  //
-  // --- expected number of TRT hits vs eta (a function)
-  //
-  const int maxTrtEtaBins = 5;
-  // binning for expected number of TRT hits
-  const double TrtEtaBin[maxTrtEtaBins+1] = {0., 0.65,      0.85,     1.25,     1.80,     2.10};
-  // A and B factors for: Nexp(n,eta) = A + B*(eta- TrtEtaBin[n])
-  const double TrtA[maxTrtEtaBins]        = {     29.,       31.,      20.,      36.,     34.,};
-  const double TrtB[maxTrtEtaBins]        = { 2./0.65, -11./0.20, 16./0.40, -2./0.55, -24./0.3};
-  // put it into the private members
-  m_maxTrtEtaBins = maxTrtEtaBins;
-  for (int i=0; i<m_maxTrtEtaBins;  ++i) { m_TrtA.push_back(TrtA[i]); m_TrtB.push_back(TrtB[i]); }
-  for (int i=0; i<=m_maxTrtEtaBins; ++i) m_boundsTrtEtaBin.push_back(TrtEtaBin[i]);
-  */
 
   //
   // --- ratio of TRT hits over expected
@@ -390,22 +347,7 @@ void InDet::InDetTrtTrackScoringTool::setupTRT_ScoreModifiers()
   for (int i=0; i<m_maxTrtFittedRatio; ++i) m_factorTrtFittedRatio.push_back(goodTrtFittedRatio[i]/fakeTrtFittedRatio[i]);
   for (int i=0; i<=m_maxTrtFittedRatio; ++i) m_boundsTrtFittedRatio.push_back(TrtFittedRatioBounds[i]);
 
-  //
-  // --- chi2 prob
-  //
-  if (!m_useLogProbBins) {
-    // do not use it !
-    m_maxLogProb = -1 ;
-  } else {
-    const int maxLogProb = 12;
-    const double LogProbBounds[maxLogProb+1] = {-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0};
-    const double modiLogProb[maxLogProb] = {0.002, 0.002, 0.004, 0.007, 0.008, 0.012, 0.020, 0.033, 0.051, 0.104, 0.219, 0.531};
-    const double vetoLogProb[maxLogProb] = {0.020, 0.025, 0.032, 0.030, 0.042, 0.051, 0.063, 0.071, 0.080, 0.112, 0.156, 0.216};
-    // put it into the private members
-    m_maxLogProb = maxLogProb;
-    for (int i=0; i<m_maxLogProb; ++i) m_factorLogProb.push_back(modiLogProb[i]/vetoLogProb[i]);
-    for (int i=0; i<=m_maxLogProb; ++i) m_boundsLogProb.push_back(LogProbBounds[i]);
-  }
+  
   //
   // --- sigma chi2
   //
@@ -443,9 +385,6 @@ void InDet::InDetTrtTrackScoringTool::setupTRT_ScoreModifiers()
       ATH_MSG_VERBOSE( "Modifier for " << m_boundsTrtFittedRatio[i] << " < TRT fitted ratio  < " << m_boundsTrtFittedRatio[i+1]
                         << "  : " <<m_factorTrtFittedRatio[i] );
 
-    // only if used !
-    for (int i=0; i<m_maxLogProb; ++i)
-      ATH_MSG_VERBOSE( "Modifier for " << m_boundsLogProb[i] << " LogProb: " << m_factorLogProb[i] );
   
     // only if used !
     for (int i=0; i<m_maxSigmaChi2; ++i)
diff --git a/InnerDetector/InDetRecTools/SiCombinatorialTrackFinderTool_xk/src/SiCombinatorialTrackFinder_xk.cxx b/InnerDetector/InDetRecTools/SiCombinatorialTrackFinderTool_xk/src/SiCombinatorialTrackFinder_xk.cxx
index f9d6a701cfd1eb37a5a5b5c271e057f8126c5e71..ce6e4f5dae799547bb83efe2854c3258673d2669 100644
--- a/InnerDetector/InDetRecTools/SiCombinatorialTrackFinderTool_xk/src/SiCombinatorialTrackFinder_xk.cxx
+++ b/InnerDetector/InDetRecTools/SiCombinatorialTrackFinderTool_xk/src/SiCombinatorialTrackFinder_xk.cxx
@@ -103,15 +103,12 @@ StatusCode InDet::SiCombinatorialTrackFinder_xk::initialize ATLAS_NOT_THREAD_SAF
   //
   m_outputlevel = msg().level()-MSG::DEBUG;
 
-  if (m_usePIX) {
-    ATH_CHECK( m_pixcontainerkey.initialize() );
-    ATH_CHECK( m_boundaryPixelKey.initialize() );
-  }
-  if (m_useSCT) {
-    ATH_CHECK( m_sctcontainerkey.initialize() );
-    ATH_CHECK( m_boundarySCTKey.initialize() );
-    ATH_CHECK( m_SCTDetEleCollKey.initialize() );
-  }
+  ATH_CHECK( m_pixcontainerkey.initialize (m_usePIX) );
+  ATH_CHECK( m_boundaryPixelKey.initialize (m_usePIX) );
+
+  ATH_CHECK( m_sctcontainerkey.initialize (m_useSCT) );
+  ATH_CHECK( m_boundarySCTKey.initialize (m_useSCT) );
+  ATH_CHECK( m_SCTDetEleCollKey.initialize (m_useSCT) );
 
   // initialize conditions object key for field cache
   //
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ATLxk.h b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ATLxk.h
index addfdb5985a6f7ff33c437992e331ac745990040..a0e802ff8b68ba0c9b87fc4233f69534fb9a73ec 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ATLxk.h
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ATLxk.h
@@ -107,6 +107,14 @@ namespace InDet {
     /// produced accordingly methods find    
     ///////////////////////////////////////////////////////////////////
     //@{
+    /** This method will update the data.seedOutput member to be the next seed pointed at by 
+    * the data.i_seed_Pro iterator over the data.l_seeds_Pro list. 
+    * Some poor quality PPS seeds will be skipped, this cut is implemented within the SiSpacePointsSeed::set3 method. 
+    * If we run out of seeds after having previously reached a premature abort condition, 
+    * seed finding will automatically be continued until all seeds have been found. 
+    * @param[in] ctx: Event contex
+    * @param[in,out] data Event data, updated and used to obtain the next seed to return 
+    **/ 
     virtual const SiSpacePointsSeed* next(const EventContext& ctx, EventData& data) const override;
     //@}
       
@@ -119,17 +127,21 @@ namespace InDet {
 
   private:
     /// enum for array sizes
-    enum Size {SizeRF=53,
-               SizeZ=11,
-               SizeRFZ=SizeRF*SizeZ,
-               SizeI=9,
-               SizeRFV=100,
-               SizeZV=3,
-               SizeRFZV=SizeRFV*SizeZV,
-               SizeIV=6};
-
+    /// Note that this stores the maximum capacities, the actual binnings 
+    /// do not always use the full size. See data members below for the 
+    /// actual binning paramaters, which are determined in buildFramework. 
+    //@{
+    enum Size {arraySizePhi=53,     ///< capacity of the 1D phi arrays 
+               arraySizeZ=11,       ///< capacity of the 1D z arrays
+               arraySizePhiZ=arraySizePhi*arraySizeZ,   ///< capacity for the 2D phi-z arrays 
+               arraySizeNeighbourBins=9,  ///< array size to store neighbouring phi-z-regions in the seed finding
+               arraySizePhiV=100,         ///< array size in phi for vertexing 
+               arraySizeZV=3,             ///< array size in z for vertexing
+               arraySizePhiZV=arraySizePhiV*arraySizeZV,      ///< array size in phi-Z 2D for the vertexing
+               arraySizeNeighbourBinsVertex=6};       ///< array size to store neighbouring phi-z regions for the vertexing
+    //@} 
     ///////////////////////////////////////////////////////////////////
-    // Private data and methods
+    /// Private data and methods
     ///////////////////////////////////////////////////////////////////
 
     /// @name Data handles
@@ -139,7 +151,7 @@ namespace InDet {
     SG::ReadHandleKey<SpacePointOverlapCollection> m_spacepointsOverlap{this, "SpacePointsOverlapName", "OverlapSpacePoints"};
     SG::ReadHandleKey<Trk::PRDtoTrackMap> m_prdToTrackMap{this,"PRDtoTrackMap","","option PRD-to-track association"};
     SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey{this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot"};
-    // Read handle for conditions object to get the field cache
+    /// Read handle for conditions object to get the field cache
     SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
                                                                           "Name of the Magnetic Field conditions object key"};
     //@}
@@ -169,12 +181,12 @@ namespace InDet {
     //@{
     FloatProperty m_etamin{this, "etaMin", 0.};
     FloatProperty m_r_rmax{this, "radMax", 600.};
-    FloatProperty m_r_rstep{this, "radStep", 2.};
-    FloatProperty m_r3max{this, "maxRadius3", 600.}; //!< This is always overwritten by m_r_rmax.
+    FloatProperty m_binSizeR{this, "radStep", 2.};
+    FloatProperty m_r3max{this, "maxRadius3", 600.}; ///< This is always overwritten by m_r_rmax.
     FloatProperty m_drmin{this, "mindRadius", 5.};
-    FloatProperty m_diver{this, "maxdImpact", 10.};
-    FloatProperty m_diversss{this, "maxdImpactSSS", 50.};
-    FloatProperty m_divermax{this, "maxdImpactForDecays", 20.};
+    FloatProperty m_maxdImpact{this, "maxdImpact", 10.};
+    FloatProperty m_maxdImpactSSS{this, "maxdImpactSSS", 50.};
+    FloatProperty m_maxdImpactDecays{this, "maxdImpactForDecays", 20.};
     FloatProperty m_ptmin{this, "pTmin", 500.};
     //@}
 
@@ -192,7 +204,7 @@ namespace InDet {
     FloatProperty m_r2max{this, "maxRadius2", 600.};
     FloatProperty m_r3min{this, "minRadius3", 0.};
     FloatProperty m_rapcut{this, "RapidityCut", 2.7};
-    FloatProperty m_diverpps{this, "maxdImpactPPS", 1.7};
+    FloatProperty m_maxdImpactPPS{this, "maxdImpactPPS", 1.7};
     //@}
 
     /// @name Data member, which is not updated at all.
@@ -202,22 +214,30 @@ namespace InDet {
 
     /// @name Data members, which are updated only in buildFrameWork in initialize
     //@{
-    float m_dzdrmin0{0.};
-    float m_dzdrmax0{0.};
-    float m_ipt{0.};
-    float m_ipt2{0.};
-    float m_COF{0.};
-    int m_r_size{0};
-    int m_fNmax{0};
-    int m_fvNmax{0};
-    int m_rfz_b[SizeRFZ];
-    int m_rfz_t[SizeRFZ];
-    int m_rfz_ib[SizeRFZ][SizeI];
-    int m_rfz_it[SizeRFZ][SizeI];
-    int m_rfzv_n[SizeRFZV];
-    int m_rfzv_i[SizeRFZV][SizeIV];
-    float m_sF{0};
-    float m_sFv{0};
+    /// conversion factors and cached cut values
+    float m_dzdrmin0{0.};   ///< implicitly store eta cut
+    float m_dzdrmax0{0.};   ///< implicitly store eta cut
+    float m_ipt{0.};    ///< inverse of 90% of the ptmin cut 
+    float m_ipt2{0.};   ///< inverse square of 90% of the pt min cut 
+    static constexpr float m_COF{134*.05*9};    ///< conversion factor. A very magic number indeed. 
+
+    /// @name Binning parameters 
+    ///@{
+    int m_nBinsR{0};              ///<  number of bins in the radial coordinate 
+    int m_maxPhiBin{0};           ///<  number of bins in phi 
+    int m_maxBinPhiVertex{0};     ///<  number of bins in phi for vertices 
+    float m_inverseBinSizePhi{0};   ///<  cache the inverse bin size in phi which we use - needed to evaluate phi bin locations
+    float m_inverseBinSizePhiVertex{0};///<  as above but for vertex
+    ///@}
+
+    /// arrays associating bins to each other for SP formation
+    std::array<int,arraySizePhiZ> m_nNeighbourCellsBottom;  ///< number of neighbouring phi-z bins to consider when looking for "bottom SP" candidates for each phi-z bin
+    std::array<int,arraySizePhiZ> m_nNeighbourCellsTop;  ///< number of neighbouring phi-z bins to consider when looking for "top SP" candidates for each phi-z bin
+    std::array<std::array<int, arraySizeNeighbourBins>, arraySizePhiZ> m_neighbourCellsBottom; ///< mapping of neighbour cells in the 2D phi-z binning to consider  for the "bottom SP" search for central SPs in each phi-z bin. Number of valid entries stored in m_nNeighboursPhiZbottom
+    std::array<std::array<int, arraySizeNeighbourBins>, arraySizePhiZ> m_neighbourCellsTop; ///< mapping of neighbour cells in the 2D phi-z binning to consider  for the "top SP" search for central SPs in each phi-z bin. Number of valid entries stored in m_nNeighboursPhiZtop
+
+    std::array<int,arraySizePhiZV> m_nNeighboursVertexPhiZ;
+    std::array<std::array<int, arraySizeNeighbourBinsVertex>, arraySizePhiZ> m_neighboursVertexPhiZ;
     //@}
 
     ///////////////////////////////////////////////////////////////////
@@ -234,43 +254,144 @@ namespace InDet {
     MsgStream& dumpConditions(EventData& data, MsgStream& out) const;
     MsgStream& dumpEvent     (EventData& data, MsgStream& out) const;
 
+    /// prepare several data members with cached cut values,
+    /// conversion factors, binnings, etc 
     void buildFrameWork();
+    /* updates the beam spot information stored in the event data
+    * object. 
+    * @param[out] data: Event data, receives update to the x/y/zbeam members 
+    **/
     void buildBeamFrameWork(EventData& data) const;
 
+    /** Create a SiSpacePointForSeed from the space point. 
+    * This will also add the point to the data object's
+    * l_spforseed list and update its i_spforseed iterator 
+    * to point to the entry after the new SP 
+    * for further additions.
+    * Returns a nullptr if the SP fails the eta cut, 
+    * should we apply one 
+    * @param[in,out] data: Provides beam spot location, receives updates to the l_spforseed and i_spforseed members 
+    * @param[in] sp: Input space point. 
+    **/
     SiSpacePointForSeed* newSpacePoint(EventData& data, const Trk::SpacePoint*const& sp) const;
+
     void newSeed(EventData& data, SiSpacePointForSeed*& p1, SiSpacePointForSeed*& p2, float z) const;
 
+    /** This inserts a seed into the set of saved seeds. 
+    * It internally respects the user-configured max number of seeds per central 
+    * space point. Once this is exceeded, the new seed will replace worse-quality 
+    * seeds if there are any, otherwise it will not insert anything. 
+    * @param[in,out] data Event data - update OneSeeds_Pro and mapOneSeeds_Pro members 
+    * @param[in] p1 First space point for this seed
+    * @param[in] p2 Second space point for this seed
+    * @param[in] p3 Third space point for this seed
+    * @param[in] z z0 IP estimate
+    * @param[in] q quality estimate (based on d0, plus modifiers) 
+    **/ 
     void newOneSeed(EventData& data,
                     SiSpacePointForSeed*& p1, SiSpacePointForSeed*& p2,
                     SiSpacePointForSeed*& p3, float z, float q) const;
 
+    /** This creates all possible seeds with the passed central and bottom SP, using all top SP 
+    * candidates which are stored in the data.CmSp member.  Seeds are scored by a quality score 
+    * seeded by abs(d0), and modified if there is a second-seed confirmation or in case of PPP/SSS 
+    * topologies. Then, they are written out via the newOneSeed method.
+    * @param[in,out] data Event data, used to read top SP candidates and write out found seeds (see newOneSeed). 
+    * @param[in] SPb Bottom Space point for the seed creation
+    * @param[in] SP0 Central Space point for the seed creation
+    * @param[in] Zob z0 estimate 
+    **/ 
     void newOneSeedWithCurvaturesComparison
     (EventData& data, SiSpacePointForSeed*& SPb, SiSpacePointForSeed*& SP0, float Zob) const;
 
+    /// fills the seeds from the mapOneSeeds_Pro member into the l_seeds_Pro member of the data object, applying some more 
+    /// quality requirements on the way. 
+    /// @param[in,out] data Event data which is modified
     void fillSeeds(EventData& data) const;
+
+    /** this method populates the data object's "histograms" (implemented as nested vectors). 
+    * using the list of r-binned space points in the object assumed to have been previously
+    * set (for example via the newEvent method of this class). 
+    * @param[in,out] data: Event data which will be updated. 
+    **/ 
     void fillLists(EventData& data) const;
     void erase(EventData& data) const;
     void production2Sp(EventData& data) const;
+
+
+    /** Top-level method for 3-SP seed production. 
+    * This method loops over each eta-Z region, and in each region 
+    * calls the extended production3Sp method below to do the actual work. 
+    * @param[in,out] data Event data which will be updated
+    **/
     void production3Sp(EventData& data) const;
+
+    /** \brief: Seed production from space points. 
+    * 
+    * This method will try to find 3-SP combinations within a 
+    * local phi-z region in the detector. 
+    * 
+    * The central SP of the seed will be taken from this region
+    * (technically via the first entry of the bottom candidate array, 
+    * which always points to the phi-z bin of interest itself). 
+    * 
+    * The top SP is allowed to come from the same or one of several close-by
+    * phi-Z bins, as is the bottom SP. 
+    * 
+    * All SP collections are expected to be internally sorted in the radial coordinate.
+    * 
+    * @param[in,out] data: Event data
+    * @param[in,out] iter_bottomCands: collection of iterators over SP collections for up to 9 phi-z cells to consider for the bottom space-point search 
+    * @param[in,out] iter_endBottomCands: collection of end-iterators over the 
+    * SP collections  for up to 9 phi-z cells to consider for the bottom space-point search 
+    * @param[in,out] iter_topCands: collection of iterators over SP collections for up to 9 phi-z cells to consider for the top space-point search 
+    * @param[in,out] iter_endTopCands: collection of end-iterators over the 
+    * SP collections  for up to 9 phi-z cells to consider for the top space-point search 
+    * @param[in] numberBottomCells: Number of bottom cells to consider. Determines how many entries in iter_(end)bottomCands are expected to be valid. 
+    * @param[in] numberTopCells: Number of top cells to consider.Determines how many entries in iter_(end)topCands are expected to be valid. 
+    * @param[out] nseed: Number of seeds found 
+    **/ 
     void production3Sp
     (EventData& data,
-     std::vector<InDet::SiSpacePointForSeed*>::iterator* rb,
-     std::vector<InDet::SiSpacePointForSeed*>::iterator* rbe,
-     std::vector<InDet::SiSpacePointForSeed*>::iterator* rt,
-     std::vector<InDet::SiSpacePointForSeed*>::iterator* rte,
-     const int NB, const int NT, int& nseed) const;
+     std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_bottomCands,
+     std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_endBottomCands,
+     std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_topCands,
+     std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_endTopCands,
+     const int numberBottomCells, const int numberTopCells, int& nseed) const;
+
+    /// as above, but for the trigger 
     void production3SpTrigger
     (EventData& data,
-     std::vector<InDet::SiSpacePointForSeed*>::iterator* rb,
-     std::vector<InDet::SiSpacePointForSeed*>::iterator* rbe,
-     std::vector<InDet::SiSpacePointForSeed*>::iterator* rt,
-     std::vector<InDet::SiSpacePointForSeed*>::iterator* rte,
-     const int NB, const int NT, int& nseed) const;
+     std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & rb,
+     std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & rbe,
+     std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & rt,
+     std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & rte,
+     const int numberBottomCells, const int numberTopCells, int& nseed) const;
  
+    /** This method updates the EventData based on the passed list of vertices. 
+    * The list may be empty. 
+    * Updates the isvertex, l_vertex, zminU and zmaxU members of the data object.
+    * Always returns false.  
+    * @param[in,out] data  Event data to update 
+    * @param[in] lV possibly empty list of vertices
+    **/
     bool newVertices(EventData& data, const std::list<Trk::Vertex>& lV) const;
+    /** This method is called within next() when we are out of vertices. 
+     * It will internally trigger a re-run of production3Sp if we are out of seeds 
+     * and data.endlist is not set (indicating the search is not finished). 
+    **/ 
     void findNext(EventData& data) const;
     bool isZCompatible(EventData& data, const float& Zv, const float& R, const float& T) const;
-    void convertToBeamFrameWork(EventData& data, const Trk::SpacePoint*const& sp, float* r) const;
+
+    /** This method popualtes the r array 
+    * with the space point's coordinates 
+    * relative to the beam spot. 
+    * @param[in] data Event data 
+    * @param[in] sp: Space point to take the global position from 
+    * @param[out] r: 3-array, will be populated with the relative coordinates 
+    **/
+    void convertToBeamFrameWork(EventData& data, const Trk::SpacePoint*const& sp, std::array<float,3> & r) const;
+
     bool isUsed(const Trk::SpacePoint* sp, const Trk::PRDtoTrackMap &prd_to_track_map) const;
 
     void initializeEventData(EventData& data) const;
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ATLxk.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ATLxk.cxx
index 70aea30a74f19b8bb675501a19f5bd7d8585d966..27b3950693bcacf6f6a6f4983b132381f2b09eab 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ATLxk.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ATLxk.cxx
@@ -20,7 +20,7 @@
 #include <ostream>
 
 ///////////////////////////////////////////////////////////////////
-// Constructor
+/// Constructor
 ///////////////////////////////////////////////////////////////////
 
 InDet::SiSpacePointsSeedMaker_ATLxk::SiSpacePointsSeedMaker_ATLxk
@@ -30,7 +30,7 @@ InDet::SiSpacePointsSeedMaker_ATLxk::SiSpacePointsSeedMaker_ATLxk
 }
 
 ///////////////////////////////////////////////////////////////////
-// Initialisation
+/// Initialisation
 ///////////////////////////////////////////////////////////////////
 
 StatusCode InDet::SiSpacePointsSeedMaker_ATLxk::initialize()
@@ -41,19 +41,18 @@ StatusCode InDet::SiSpacePointsSeedMaker_ATLxk::initialize()
   ATH_CHECK(m_spacepointsSCT.initialize(m_sct));
   ATH_CHECK(m_spacepointsOverlap.initialize(m_useOverlap));
 
-  // Get beam geometry
-  //
+  /// Get beam geometry
   if (not m_beamSpotKey.empty()) {
     ATH_CHECK(m_beamSpotKey.initialize());
   }
 
   ATH_CHECK( m_fieldCondObjInputKey.initialize() );
 
-  // PRD-to-track association (optional)
+  /// PRD-to-track association (optional)
   ATH_CHECK( m_prdToTrackMap.initialize( !m_prdToTrackMap.key().empty()));
   
-  // Build framework
-  //
+  /// Build framework. Will set up internal variables 
+  /// *not* related to the event data object 
   buildFrameWork();
 
   if (msgLvl(MSG::DEBUG)) { 
@@ -67,7 +66,7 @@ StatusCode InDet::SiSpacePointsSeedMaker_ATLxk::initialize()
 }
 
 ///////////////////////////////////////////////////////////////////
-// Finalize
+/// Finalize
 ///////////////////////////////////////////////////////////////////
 
 StatusCode InDet::SiSpacePointsSeedMaker_ATLxk::finalize()
@@ -76,31 +75,38 @@ StatusCode InDet::SiSpacePointsSeedMaker_ATLxk::finalize()
 }
 
 ///////////////////////////////////////////////////////////////////
-// Initialize tool for new event 
+/// Initialize tool for new event 
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(const EventContext& ctx, EventData& data, int iteration) const
 {
+  /// if not done so, book the arrays etc inside the event data object
   if (not data.initialized) initializeEventData(data);
 
   data.trigger = false;
   if (!m_pixel && !m_sct) return;
 
+  /// pass the iteration info into our data object
   data.iteration = iteration;
   if (iteration <=0) data.iteration = 0;
+  /// Erase any existing entries in the data object 
   erase(data);
   data.dzdrmin = m_dzdrmin0;
   data.dzdrmax = m_dzdrmax0;
-  data.umax = 100.;
-  if (!data.iteration) {
+  data.maxScore = 100.;     ///< max score, where low scores are "better". 
+
+  /// in the first iteration, initialise the beam framework - beam spot position and direction
+  if (data.iteration == 0) {
     if (not m_beamSpotKey.empty()) {
       buildBeamFrameWork(data);
     }
 
-    double f[3], gP[3] ={10.,10.,0.};
+    /// Read the field information 
+    double magField[3]{0,0,0};
+    double globalPos[3] ={10.,10.,0.};
 
     MagField::AtlasFieldCache    fieldCache;
-    // Get field cache object
+    /// Get field cache object
     SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
     const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
     if (fieldCondObj == nullptr) {
@@ -110,28 +116,56 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(const EventContext& ctx, Even
     fieldCondObj->getInitializedCache (fieldCache);
 
     if (fieldCache.solenoidOn()) {
-      fieldCache.getFieldZR(gP,f);
-
-      data.K = 2./(300.*f[2]);
+      /// retrieve field
+      fieldCache.getFieldZR(globalPos,magField);
+      /** 
+      * Knowing the field (note that the field cache returns the field in units of kiloTesla!) 
+      * allows to set the circle-radius to pT conversion factor.
+      * 
+      * See for example ATLAS-CONF-2010-072 
+      * R[mm] =pT[GeV] / (3·10−4×B[T]) =  pT[MeV] / (300 *Bz[kT])
+      * 
+      * We actually estimate the circle diameter, 2R, in the seeding. 
+      * So what we want is: 2R = pT[MeV] x 2  / (300 x Bz) = K x pT[MeV]. 
+      **/
+      data.K = 2./(300.*magField[2]);
     } else {
       data.K = 2./(300.* 5. );
     }
-
+    /** helper variables allowing us to directly apply our pt cut on the variables
+    * available at seed level. 
+    * ipt2K is 1 / (K * 0.9 * pt cut)² 
+    **/ 
     data.ipt2K = m_ipt2/(data.K*data.K);
+    /// related to the mysterious magic number, m_COF{134*.05*9}
     data.ipt2C = m_ipt2*m_COF;
     data.COFK = m_COF*(data.K*data.K);
+
+    /// set the spacepoint iterator to the beginning of the space-point list  
     data.i_spforseed = data.l_spforseed.begin();
-  } else {
-    data.r_first = 0;
+  } ///< end if-statement for iteration 0 
+  else {  /// for the second iteration (PPP pass), don't redo the full init required the first time 
+    data.r_first = 0;     ///< reset the first radial bin 
+    /// call fillLists to repopulate the candidate space points and exit 
     fillLists(data);
     return;
   }
 
+  /// the following will only happen in the first iteration 
+
   data.checketa = data.dzdrmin > 1.;
   if (m_dbm) data.checketa = false;
 
-  float irstep = 1./m_r_rstep;
-  int   irmax  = m_r_size-1;
+  /// build the r-binning. 
+  float oneOverBinSizeR = 1./m_binSizeR;
+  int   maxBinR  = m_nBinsR-1;
+
+  /** This cleans up remaining entries in the data object. 
+  * In standard execution, we only run this in the first 
+  * iterations on a newly created data object, 
+  * in which case this loop will not ever be entered. 
+  * Leaving it in place for nonstandard use cases. 
+  **/ 
   for (int i=0; i<data.nr; ++i) {
     int n = data.r_index[i];
     data.r_map[n] = 0;
@@ -139,6 +173,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(const EventContext& ctx, Even
   }
   data.ns = data.nr = 0;
 
+  /// read the prd to track map, in case we want to use it. 
   SG::ReadHandle<Trk::PRDtoTrackMap>  prd_to_track_map;
   const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
   if (!m_prdToTrackMap.key().empty()) {
@@ -149,43 +184,64 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(const EventContext& ctx, Even
     prd_to_track_map_cptr = prd_to_track_map.cptr();
   }
 
+  /////////////////////////////
+  /// Now, we will populate the space point list in the event data object once. 
+  /////////////////////////////
+
+  /// reset the first r index 
   data.r_first = 0;
-  // Get pixels space points containers from store gate 
-  //
+
+  /// Get pixels space points containers from store gate 
   if (!m_dbm && m_pixel) {
 
     SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
-
+      /// loop over the pixel space points 
       for (const SpacePointCollection* spc: *spacepointsPixel) {
         for (const Trk::SpacePoint* sp: *spc) {
-
+          
+          /// if we use the PRD to track map and this SP has already been used in a track, bail out 
+          /// also skip any SP outside the r binning 
           if ((prd_to_track_map_cptr &&  isUsed(sp,*prd_to_track_map_cptr)) || sp->r() > m_r_rmax) continue;
 
-          // Remove DBM space points
-          //
+          /// Remove DBM space points
+          ///
           const InDetDD::SiDetectorElement* de= 
             static_cast<const InDetDD::SiDetectorElement*>(sp->clusterList().first->detectorElement());
           if (!de || de->isDBM()) continue;
 
+          /** create a SiSpacePointForSeed from the space point. 
+          * This will also add the point to the l_spforseed list and update 
+          * the i_spforseed iterator
+          **/ 
           InDet::SiSpacePointForSeed* sps = newSpacePoint(data, sp);
+          /// this can occur if we fail the eta cut 
           if (!sps) continue;
 
-          int ir = static_cast<int>(sps->radius()*irstep);
-          if (ir>irmax) ir = irmax;
-          data.r_Sorted[ir].push_back(sps);
-          ++data.r_map[ir];
-          if (data.r_map[ir]==1) data.r_index[data.nr++] = ir;
-          if (ir > data.r_first) data.r_first = ir;
+          /// determine the r-bin of this SP. 
+          /// done by dividing the radius by the bin size. 
+          int radiusBin = static_cast<int>(sps->radius()*oneOverBinSizeR);
+          /// catch outliers
+          if (radiusBin>maxBinR) radiusBin = maxBinR;
+
+          /// now add the SP to the r-binned vector 
+          data.r_Sorted[radiusBin].push_back(sps);
+          /// increment the counter for this bin 
+          ++data.r_map[radiusBin];
+          /// if this is the first time we see this bin in use, we update the index map for this bin 
+          /// to the radius bin index 
+          if (data.r_map[radiusBin]==1) data.r_index[data.nr++] = radiusBin;
+          /// if this is the highest bin we saw so far, update the r_first member of the data object to this bin
+          if (radiusBin > data.r_first) data.r_first = radiusBin;
+          /// update the space point counter
           ++data.ns;
-        }
-      }
-    }
-    ++data.r_first;
-  }
+        } ///< end loop over space points in collection
+      }///< end loop over pixel SP collections
+    } ///< end if-statement on valid pixel SP container 
+    ++data.r_first; ///< increment r_first past the last occupied bin we saw
+  } ///< end pixel case
   
-  // Get sct space points containers from store gate 
-  //
+  /// Get sct space points containers from store gate 
   if (!m_dbm && m_sct) {
 
     SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
@@ -193,49 +249,61 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(const EventContext& ctx, Even
 
       for (const SpacePointCollection* spc: *spacepointsSCT) {
         for (const Trk::SpacePoint* sp: *spc) {
-
+          /// as for the pixel, veto already used SP if we are using the PRD to track map in later passes of track finding. 
+          /// Also, veto SP outside the maximum radius 
           if ((prd_to_track_map_cptr &&  isUsed(sp,*prd_to_track_map_cptr)) || sp->r() > m_r_rmax) continue;
 
+          /// create a space point and write it into the data object's list of points 
           InDet::SiSpacePointForSeed* sps = newSpacePoint(data, sp);
           if (!sps) continue;
 
-          int ir = static_cast<int>(sps->radius()*irstep);
-          if (ir>irmax) ir = irmax;
-          data.r_Sorted[ir].push_back(sps);
-          ++data.r_map[ir];
-          if (data.r_map[ir]==1) data.r_index[data.nr++] = ir;
+          /// as for PIX, determine the radial bin.
+          /// Note that for the SCT we do not update data.r_first. 
+          int radiusBin = static_cast<int>(sps->radius()*oneOverBinSizeR);
+          if (radiusBin>maxBinR) radiusBin = maxBinR;
+          /// again store the SP in the r-binned vectors 
+          data.r_Sorted[radiusBin].push_back(sps);
+          /// update the count of SP in the given bin 
+          ++data.r_map[radiusBin];
+          /// update the r_index map and data.nr if needed 
+          if (data.r_map[radiusBin]==1) data.r_index[data.nr++] = radiusBin;
+          /// and increment the SP count too. 
           ++data.ns;
         }
       }
     }
 
-    // Get sct overlap space points containers from store gate 
-    //
+    /// Get sct overlap space points containers from store gate 
     if (m_useOverlap && !data.checketa) {
 
       SG::ReadHandle<SpacePointOverlapCollection> spacepointsOverlap{m_spacepointsOverlap, ctx};
       if (spacepointsOverlap.isValid()) {
   
         for (const Trk::SpacePoint* sp: *spacepointsOverlap) {
-
+          /// usual rejection of SP used in previous track finding passes if we run with the PRT to track map + check of the max radius 
           if ((prd_to_track_map_cptr &&  isUsed(sp, *prd_to_track_map_cptr)) || sp->r() > m_r_rmax) continue;
 
+          /// SP creation, entry into list of the data object 
           InDet::SiSpacePointForSeed* sps = newSpacePoint(data, sp);
           if (!sps) continue;
 
-          int ir = static_cast<int>(sps->radius()*irstep);
-          if (ir>irmax) ir = irmax;
-          data.r_Sorted[ir].push_back(sps);
-          ++data.r_map[ir];
-          if (data.r_map[ir]==1) data.r_index[data.nr++] = ir;
+          /// radial bin determination 
+          int radiusBin = static_cast<int>(sps->radius()*oneOverBinSizeR);
+          if (radiusBin>maxBinR) radiusBin = maxBinR;
+          /// insert into the "histogram" vector
+          data.r_Sorted[radiusBin].push_back(sps);
+          /// update the counter for each bin content
+          ++data.r_map[radiusBin];
+          /// update the bin index list and occupied bin counter
+          if (data.r_map[radiusBin]==1) data.r_index[data.nr++] = radiusBin;
+          /// and the total SP count too.
           ++data.ns;
         }
       }
     }
   }
   
-  // Get pixels space points containers from store gate for DBM reconstruction
-  //
+  /// Get pixels space points containers from store gate for DBM reconstruction
   if (m_dbm) {
 
     SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
@@ -244,35 +312,42 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(const EventContext& ctx, Even
       for (const SpacePointCollection* spc: *spacepointsPixel) {
         for (const Trk::SpacePoint* sp: *spc) {
 
-          // Keep only DBM space points
-          //
+          /// Keep only DBM space points
           const InDetDD::SiDetectorElement* de= 
             static_cast<const InDetDD::SiDetectorElement*>(sp->clusterList().first->detectorElement());
           if (!de || !de->isDBM() || sp->r() > m_r_rmax) continue;
 
+          /// the following logic follows what is done above for the other species, 
+          /// please see there for detailed explanation 
           InDet::SiSpacePointForSeed* sps = newSpacePoint(data, sp);
           if (!sps) continue;
 
-          int ir = static_cast<int>(sps->radius()*irstep);
-          if (ir>irmax) ir = irmax;
-          data.r_Sorted[ir].push_back(sps);
-          ++data.r_map[ir];
-          if (data.r_map[ir]==1) data.r_index[data.nr++] = ir;
-          if (ir > data.r_first) data.r_first = ir;
+
+          int radiusBin = static_cast<int>(sps->radius()*oneOverBinSizeR);
+          if (radiusBin>maxBinR) radiusBin = maxBinR;
+          data.r_Sorted[radiusBin].push_back(sps);
+          ++data.r_map[radiusBin];
+          if (data.r_map[radiusBin]==1) data.r_index[data.nr++] = radiusBin;
+          if (radiusBin > data.r_first) data.r_first = radiusBin;
           ++data.ns;
         }
       }
     }
     ++data.r_first;
   }
+  /// negative iterations are not used in the current run-3 reco
   if (iteration < 0) data.r_first = 0;
+
+  /// populates the phi-z sorted histograms using the spacepoint lists and r-binning.
+  /// after this call, we have a 3D binning
   fillLists(data);
 }
 
 ///////////////////////////////////////////////////////////////////
-// Initialize tool for new region
+/// Initialize tool for new region
 ///////////////////////////////////////////////////////////////////
 
+/// not used in offline reco (trigger specific)
 void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
 (const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const
@@ -286,13 +361,14 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
 
   data.dzdrmin = m_dzdrmin0;
   data.dzdrmax = m_dzdrmax0;
-  data.umax = 100.;
+  data.maxScore = 100.;
 
   if (not m_beamSpotKey.empty()) {
     buildBeamFrameWork(data);
   }
 
-  double f[3], gP[3] ={10.,10.,0.};
+  double magField[3]{0,0,0};
+  double globalPos[3] ={10.,10.,0.};
 
   MagField::AtlasFieldCache    fieldCache;
   // Get field cache object
@@ -305,10 +381,11 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
   }
   fieldCondObj->getInitializedCache (fieldCache);
 
+  // initialise pt cuts and conversion factors 
   if (fieldCache.solenoidOn()) {
-    fieldCache.getFieldZR(gP,f);
+    fieldCache.getFieldZR(globalPos,magField);
 
-    data.K = 2./(300.*f[2]);
+    data.K = 2./(300.*magField[2]);
   } else {
     data.K = 2./(300.* 5. );
   }
@@ -319,8 +396,8 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
 
   data.i_spforseed = data.l_spforseed.begin();
 
-  float irstep = 1./m_r_rstep;
-  int   irmax  = m_r_size-1;
+  float oneOverBinSizeR = 1./m_binSizeR;
+  int   maxBinR  = m_nBinsR-1;
 
   data.r_first = 0;
   data.checketa = false;
@@ -338,19 +415,18 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
 
     SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if ( spacepointsPixel.isValid() ) {
-      SpacePointContainer::const_iterator spce = spacepointsPixel->end();
 
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vPixel) {
-        SpacePointContainer::const_iterator w = spacepointsPixel->indexFind(l);
-        if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+        auto w = spacepointsPixel->indexFindPtr(l);
+        if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
           float r = sp->r();
           if (r > m_r_rmax) continue;
           InDet::SiSpacePointForSeed* sps = newSpacePoint(data, sp);
-          int ir = static_cast<int>(sps->radius()*irstep);
-          if (ir>irmax) ir = irmax;
+          int ir = static_cast<int>(sps->radius()*oneOverBinSizeR);
+          if (ir>maxBinR) ir = maxBinR;
           data.r_Sorted[ir].push_back(sps);
           ++data.r_map[ir];
           if (data.r_map[ir]==1) data.r_index[data.nr++] = ir;
@@ -366,19 +442,18 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
 
     SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
-      SpacePointContainer::const_iterator spce = spacepointsSCT->end();
 
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vSCT) {
-        SpacePointContainer::const_iterator w = spacepointsSCT->indexFind(l);
-        if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+        auto w = spacepointsSCT->indexFindPtr(l);
+        if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
           float r = sp->r();
           if (r > m_r_rmax) continue;
           InDet::SiSpacePointForSeed* sps = newSpacePoint(data, sp);
-          int ir = static_cast<int>(sps->radius()*irstep);
-          if (ir>irmax) ir = irmax;
+          int ir = static_cast<int>(sps->radius()*oneOverBinSizeR);
+          if (ir>maxBinR) ir = maxBinR;
           data.r_Sorted[ir].push_back(sps);
           ++data.r_map[ir];
           if (data.r_map[ir]==1) data.r_index[data.nr++] = ir;
@@ -391,7 +466,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
 }
 
 ///////////////////////////////////////////////////////////////////
-// Initialize tool for new region
+/// Initialize tool for new region
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
@@ -399,15 +474,15 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
  const IRoiDescriptor& IRD) const
 {
-  constexpr float pi2 = 2.*M_PI;
+  constexpr float twoPi = 2.*M_PI;
 
   if (not data.initialized) initializeEventData(data);
 
   newRegion(ctx, data, vPixel, vSCT);
   data.trigger = true;
 
-  double dzdrmin = 1./tan(2.*atan(exp(-IRD.etaMinus())));
-  double dzdrmax = 1./tan(2.*atan(exp(-IRD.etaPlus ())));
+  double dzdrmin = 1./std::tan(2.*std::atan(std::exp(-IRD.etaMinus())));
+  double dzdrmax = 1./std::tan(2.*std::atan(std::exp(-IRD.etaPlus ())));
  
   data.zminB = IRD.zedMinus()-data.zbeam[0]; // min bottom Z
   data.zmaxB = IRD.zedPlus ()-data.zbeam[0]; // max bottom Z
@@ -415,14 +490,14 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
   data.zmaxU = data.zmaxB+550.*dzdrmax;
   double fmax    = IRD.phiPlus ();
   double fmin    = IRD.phiMinus();
-  if (fmin > fmax) fmin -= pi2;
+  if (fmin > fmax) fmin -= twoPi;
   data.ftrig  = (fmin+fmax)*.5;
   data.ftrigW = (fmax-fmin)*.5;
 }
 
 ///////////////////////////////////////////////////////////////////
-// Methods to initilize different strategies of seeds production
-// with two space points with or without vertex constraint
+/// Methods to initilize different strategies of seeds production
+/// with two space points with or without vertex constraint
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::find2Sp(EventData& data, const std::list<Trk::Vertex>& lv) const
@@ -458,21 +533,26 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::find2Sp(EventData& data, const std::li
 }
 
 ///////////////////////////////////////////////////////////////////
-// Methods to initilize different strategies of seeds production
-// with three space points with or without vertex constraint
+/// Methods to initilize different strategies of seeds production
+/// with three space points with or without vertex constraint
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
+  /// reset the Z interval stored in the data object
   data.zminU = m_zmin;
   data.zmaxU = m_zmax;
-
+  /// mode 2 if we have no vertices in the list, otherwise mode 3 
   int mode = 2;
   if (lv.begin()!=lv.end()) mode = 3;
+  /** copy the vertices into the data object, if we have any.
+  *   Note that by construction, newv will ALWAYS be false, also if we 
+  *   pass vertices. 
+  **/
   bool newv = newVertices(data, lv);
-
+  /// update the data object's config 
   if (newv || !data.state || data.nspoint!=3 || data.mode!=mode || data.nlist) {
     data.i_seede_Pro = data.l_seeds_Pro.begin();
     data.state = 1;
@@ -483,8 +563,10 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(const EventContext&, EventData
     data.fvNmin = 0;
     data.fNmin = 0;
     data.zMin = 0;
-    production3Sp(data);
+    production3Sp(data); ///< This performs the actual seed finding
   }
+  /// reset the i_seed_Pro iterator - this is used to return the seeds to the 
+  /// consumer when they call next()
   data.i_seed_Pro = data.l_seeds_Pro.begin();
 
   
@@ -495,23 +577,30 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(const EventContext&, EventData
 }
 
 ///////////////////////////////////////////////////////////////////
-// Methods to initilize different strategies of seeds production
-// with three space points with or without vertex constraint
+/// Methods to initilize different strategies of seeds production
+/// with three space points with or without vertex constraint
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv, const double* ZVertex) const
 {
   if (not data.initialized) initializeEventData(data);
 
+  /// Update the data object's Z interval based on the interval passed as arg to this 
+  /// function. 
   data.zminU = ZVertex[0];
-  if (data.zminU < m_zmin) data.zminU = m_zmin;
+  if (data.zminU < m_zmin) data.zminU = m_zmin; ///< don't go beyond user-specified intervals
   data.zmaxU = ZVertex[1];
-  if (data.zmaxU > m_zmax) data.zmaxU = m_zmax;
+  if (data.zmaxU > m_zmax) data.zmaxU = m_zmax; ///< don't go beyond user-specified intervals
 
+  /// mode 2 when working with the Z constraint
   int mode = 2;
   if (lv.begin()!=lv.end()) mode = 3;
+  /** copy the vertices into the data object, if we have any.
+  *   Note that by construction, newv will ALWAYS be false, also if we 
+  *   pass vertices. 
+  **/
   bool newv = newVertices(data, lv);
-
+  /// update the data object's config 
   if (newv || !data.state || data.nspoint!=3 || data.mode!=mode || data.nlist) {
     data.i_seede_Pro = data.l_seeds_Pro.begin();
     data.state = 1;
@@ -522,8 +611,10 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(const EventContext&, EventData
     data.fvNmin = 0;
     data.fNmin = 0;
     data.zMin = 0;
-    production3Sp(data);
+    production3Sp(data); ///< This performs the actual seed finding
   }
+  /// reset the i_seed_Pro iterator - this is used to return the seeds to the 
+  /// consumer when they call next()
   data.i_seed_Pro = data.l_seeds_Pro.begin();
 
   if (msgLvl(MSG::DEBUG)) {  
@@ -533,9 +624,9 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(const EventContext&, EventData
 }
 
 ///////////////////////////////////////////////////////////////////
-// Methods to initilize different strategies of seeds production
-// with variable number space points with or without vertex constraint
-// Variable means (2,3,4,....) any number space points
+/// Methods to initilize different strategies of seeds production
+/// with variable number space points with or without vertex constraint
+/// Variable means (2,3,4,....) any number space points
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::findVSp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
@@ -570,7 +661,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::findVSp(const EventContext&, EventData
 }
 
 ///////////////////////////////////////////////////////////////////
-// Dumps relevant information into the MsgStream
+/// Dumps relevant information into the MsgStream
 ///////////////////////////////////////////////////////////////////
 
 MsgStream& InDet::SiSpacePointsSeedMaker_ATLxk::dump(EventData& data, MsgStream& out) const
@@ -582,7 +673,7 @@ MsgStream& InDet::SiSpacePointsSeedMaker_ATLxk::dump(EventData& data, MsgStream&
 }
 
 ///////////////////////////////////////////////////////////////////
-// Dumps conditions information into the MsgStream
+/// Dumps conditions information into the MsgStream
 ///////////////////////////////////////////////////////////////////
 
 MsgStream& InDet::SiSpacePointsSeedMaker_ATLxk::dumpConditions(EventData &data, MsgStream& out) const
@@ -636,7 +727,7 @@ MsgStream& InDet::SiSpacePointsSeedMaker_ATLxk::dumpConditions(EventData &data,
      <<std::setw(12)<<std::setprecision(5)<<m_r_rmax 
      <<"                              |"<<endmsg;
   out<<"| radius step             | "
-     <<std::setw(12)<<std::setprecision(5)<<m_r_rstep
+     <<std::setw(12)<<std::setprecision(5)<<m_binSizeR
      <<"                              |"<<endmsg;
   out<<"| min Z-vertex position   | "
      <<std::setw(12)<<std::setprecision(5)<<m_zmin
@@ -687,13 +778,13 @@ MsgStream& InDet::SiSpacePointsSeedMaker_ATLxk::dumpConditions(EventData &data,
      <<std::setw(12)<<std::setprecision(5)<<m_dzdrver 
      <<"                              |"<<endmsg;
   out<<"| max       impact        | "
-     <<std::setw(12)<<std::setprecision(5)<<m_diver
+     <<std::setw(12)<<std::setprecision(5)<<m_maxdImpact
      <<"                              |"<<endmsg;
   out<<"| max       impact pps    | "
-     <<std::setw(12)<<std::setprecision(5)<<m_diverpps
+     <<std::setw(12)<<std::setprecision(5)<<m_maxdImpactPPS
      <<"                              |"<<endmsg;
   out<<"| max       impact sss    | "
-     <<std::setw(12)<<std::setprecision(5)<<m_diversss
+     <<std::setw(12)<<std::setprecision(5)<<m_maxdImpactSSS
      <<"                              |"<<endmsg;
   out<<"|---------------------------------------------------------------------|"
      <<endmsg;
@@ -727,7 +818,7 @@ MsgStream& InDet::SiSpacePointsSeedMaker_ATLxk::dumpConditions(EventData &data,
 }
 
 ///////////////////////////////////////////////////////////////////
-// Dumps event information into the MsgStream
+/// Dumps event information into the MsgStream
 ///////////////////////////////////////////////////////////////////
 
 MsgStream& InDet::SiSpacePointsSeedMaker_ATLxk::dumpEvent(EventData& data, MsgStream& out) const
@@ -752,7 +843,7 @@ MsgStream& InDet::SiSpacePointsSeedMaker_ATLxk::dumpEvent(EventData& data, MsgSt
 }
 
 ///////////////////////////////////////////////////////////////////
-// Find next set space points
+/// Find next set space points
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::findNext(EventData& data) const
@@ -770,7 +861,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::findNext(EventData& data) const
 }                       
 
 ///////////////////////////////////////////////////////////////////
-// New and old list vertices comparison
+/// New and old list vertices comparison
 ///////////////////////////////////////////////////////////////////
 
 bool InDet::SiSpacePointsSeedMaker_ATLxk::newVertices(EventData& data, const std::list<Trk::Vertex>& lV) const
@@ -778,22 +869,32 @@ bool InDet::SiSpacePointsSeedMaker_ATLxk::newVertices(EventData& data, const std
   unsigned int s1 = data.l_vertex.size();
   unsigned int s2 = lV.size();
 
+  /// reset the isvertex flag
   data.isvertex = false;
+  /// if we had no vertices before and have none now,
+  /// we can exit right away 
   if (s1==0 && s2==0) return false;
 
+  /// clean up the vertex list 
   data.l_vertex.clear();
+  /// if we have no vertices now, we can exit 
   if (s2 == 0) return false;
 
+  /// otherwise, update the data with the new vertices
   data.isvertex = true;
   for (const Trk::Vertex& v: lV) {
     data.l_vertex.insert(static_cast<float>(v.position().z()));
   }
 
+  /// and also update the z interval, adding 20mm before/after the first/last vertex in z 
+  /// make sure not to extend the interval beyond the user-configured z interval. 
   data.zminU = (*data.l_vertex. begin())-20.;
   if (data.zminU < m_zmin) data.zminU = m_zmin;
   data.zmaxU = (*data.l_vertex.rbegin())+20.;
   if (data.zmaxU > m_zmax) data.zmaxU = m_zmax;
 
+  /// Ich bin der Geist, der stets verneint!
+  /// are we sure this is not a bug?
   return false;
 }
 
@@ -803,209 +904,280 @@ bool InDet::SiSpacePointsSeedMaker_ATLxk::newVertices(EventData& data, const std
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::buildFrameWork() 
 {
-  m_ptmin = fabs(m_ptmin);
+  m_ptmin = std::abs(m_ptmin);
   
-  // For DBM reconstruction we use new parameters
-  //
+  /// For DBM reconstruction we use new parameters
   if (m_dbm) {
     m_r_rmax  = 150.;
-    m_r_rstep = .5;
+    m_binSizeR = .5;
     m_drmin = 2.;
     m_ptmin = 10.;
-    m_diver = 150.;
+    m_maxdImpact = 150.;
   } else if (m_ptmin < 100.) {
     m_ptmin = 100.;
   }
-  if (m_diversss < m_diver   ) m_diversss = m_diver;
-  if (m_divermax < m_diversss) m_divermax = m_diversss;
-
-  if (fabs(m_etamin) < .1) m_etamin = -m_etamax;
-  m_dzdrmax0  = 1./tan(2.*atan(exp(-m_etamax)));
-  m_dzdrmin0  = 1./tan(2.*atan(exp(-m_etamin)));
+  /// ensure consistency in the transverse IP cuts 
+  if (m_maxdImpactSSS < m_maxdImpact   ) m_maxdImpactSSS = m_maxdImpact;
+  if (m_maxdImpactDecays < m_maxdImpactSSS) m_maxdImpactDecays = m_maxdImpactSSS;
+
+  /// symmetrise eta cut if eta min not explicitly set 
+  if (std::abs(m_etamin) < .1) m_etamin = -m_etamax;
+  /// set dz/dr cut values based on eta cuts
+  m_dzdrmax0  = 1./std::tan(2.*std::atan(std::exp(-m_etamax)));
+  m_dzdrmin0  = 1./std::tan(2.*std::atan(std::exp(-m_etamin)));
   
   m_r3max     = m_r_rmax;
-  m_COF       = 134*.05*9.;
-  m_ipt       = 1./fabs(.9*m_ptmin);
+  /// cache inverse pt cuts 
+  m_ipt       = 1./std::abs(.9*m_ptmin);
   m_ipt2      = m_ipt*m_ipt;
 
-  // Build radius sorted containers
-  //
-  m_r_size = static_cast<int>((m_r_rmax+.1)/m_r_rstep);
+  /// Build radius sorted containers
+  m_nBinsR = static_cast<int>((m_r_rmax+.1)/m_binSizeR);
 
-  // Build radius-azimuthal sorted containers
-  //
-  constexpr float pi2 = 2.*M_PI;
-  const int   NFmax = SizeRF;
-  const float sFmax = static_cast<float>(NFmax)/pi2;
-  const float sFmin = 100./60.;
+  /** 
+   * Now we construct the radius-azimuthal sorted containers.
+   * Binning is determined semi-dynamically based on the tool config 
+  **/
+
+  /// determine the phi binning 
+  constexpr float twoPi = 2.*M_PI;
 
+  /// The max Nb. of bins possible is given by the binning enum 
+  const int   nPhiBinsMax = arraySizePhi;
+  const float inverseSizePhiMax = static_cast<float>(nPhiBinsMax)/twoPi; ///< for run-3: 53 : 6.28 ~ 8.43, bin size 0.118
+
+  /// the minumum allowed granularity is given by a magic number. 
+  /// best guess: 100 MeV min track pt? 
+  const float inverseSizePhiMin = 100./60.;     ///< 1.67, bin size 0.6
+
+  /// minimum expected pt. 
   float ptm = 400.;
+  /// if we cut below 400 MeV, adapt the ptm 
   if (!m_dbm && m_ptmin < ptm) ptm = m_ptmin;
 
-  m_sF = ptm /60.;
-  if      (m_sF > sFmax) m_sF = sFmax;
-  else if (m_sF < sFmin) m_sF = sFmin;
-  m_fNmax = static_cast<int>(pi2*m_sF);
-  if (m_fNmax >=NFmax) m_fNmax = NFmax-1;
+  /// binning driven by the min pt we expect  
+  /// likely driven by the phi rotation we expect between 2 SP at miminum pt (max curvature) 
+  m_inverseBinSizePhi = ptm /60.;
+  /// for example 400. / 60 = 6.67, bin size 0.15
 
-  // Build radius-azimuthal-Z sorted containers for Z-vertices
-  //
-  const int   NFtmax  = SizeRFV;
-  const float sFvmax = static_cast<float>(NFtmax)/pi2;
-  m_sFv = m_ptmin/120.;
-  if (m_sFv > sFvmax) m_sFv = sFvmax;
-  m_fvNmax = static_cast<int>(pi2*m_sFv);
-  if (m_fvNmax>=NFtmax) m_fvNmax = NFtmax-1;
-
-  // Build maps for radius-azimuthal-Z sorted collections 
-  //
-  for (int f=0; f<=m_fNmax; ++f) {
+  /// truncate the bin size to fall within our thresholds
+  if      (m_inverseBinSizePhi > inverseSizePhiMax) m_inverseBinSizePhi = inverseSizePhiMax;
+  else if (m_inverseBinSizePhi < inverseSizePhiMin) m_inverseBinSizePhi = inverseSizePhiMin;
+
+  /// now we can determine the number of bins by dividing the interval by the bin size 
+  m_maxPhiBin = static_cast<int>(twoPi*m_inverseBinSizePhi);
+  /// additional protection against too many bins. Should not happen given constraints above 
+  if (m_maxPhiBin >=nPhiBinsMax) m_maxPhiBin = nPhiBinsMax-1;
+
+  /// Build radius-azimuthal-Z sorted containers for Z-vertices
+  /// same logic as for the space points above 
+  const int   nPhiBinsVertexMax  = arraySizePhiV;
+  const float inverseBinSizePhiVertexMax = static_cast<float>(nPhiBinsVertexMax)/twoPi;
+  m_inverseBinSizePhiVertex = m_ptmin/120.;
+  if (m_inverseBinSizePhiVertex > inverseBinSizePhiVertexMax) m_inverseBinSizePhiVertex = inverseBinSizePhiVertexMax;
+  m_maxBinPhiVertex = static_cast<int>(twoPi*m_inverseBinSizePhiVertex);
+  if (m_maxBinPhiVertex>=nPhiBinsVertexMax) m_maxBinPhiVertex = nPhiBinsVertexMax-1;
+
+
+  /// Build maps for radius-azimuthal-Z sorted collections. 
+  /// Here, we associate which bins are 'connected' to a given phi-Z bin 
+  /// for the seeding 
+
+  for (int phiBin=0; phiBin<=m_maxPhiBin; ++phiBin) {
 
-    int fb = f-1;
-    if (fb<0) fb=m_fNmax;
-    int ft = f+1;
-    if (ft>m_fNmax) ft=0;
+    int phiBelow = phiBin-1;
+    if (phiBelow<0) phiBelow=m_maxPhiBin; ///< loop around at edges of range
+
+    int phiAbove = phiBin+1;
+    if (phiAbove>m_maxPhiBin) phiAbove=0; ///< loop around at edges of range
     
-    // For each azimuthal region loop through all Z regions
-    //
-    for (int z=0; z<SizeZ; ++z) {
+    /// For each azimuthal region loop through all Z regions
+    for (int z=0; z<arraySizeZ; ++z) {
+
+      /// we always include the two neighbouring phi bins for the top / bottom 
+      /// space point search 
  
-      int a        = f *SizeZ+z;
-      int b        = fb*SizeZ+z;
-      int c        = ft*SizeZ+z;
-      m_rfz_b [a]    = 3; m_rfz_t [a]    = 3;
-      m_rfz_ib[a][0] = a; m_rfz_it[a][0] = a;
-      m_rfz_ib[a][1] = b; m_rfz_it[a][1] = b;
-      m_rfz_ib[a][2] = c; m_rfz_it[a][2] = c;
+      int twoDbinSamePhi        = phiBin * arraySizeZ+z;
+      int twoDbinLowerPhi        = phiBelow*arraySizeZ+z;
+      int twoDbinHigherPhi        = phiAbove*  arraySizeZ+z;
+
+      m_nNeighbourCellsBottom [twoDbinSamePhi]    = 3; 
+      m_nNeighbourCellsTop [twoDbinSamePhi]    = 3;
+
+      m_neighbourCellsBottom[twoDbinSamePhi][0] = twoDbinSamePhi; 
+      m_neighbourCellsTop[twoDbinSamePhi][0] = twoDbinSamePhi;
+
+      m_neighbourCellsBottom[twoDbinSamePhi][1] = twoDbinLowerPhi; 
+      m_neighbourCellsTop[twoDbinSamePhi][1] = twoDbinLowerPhi;
+
+      m_neighbourCellsBottom[twoDbinSamePhi][2] = twoDbinHigherPhi; 
+      m_neighbourCellsTop[twoDbinSamePhi][2] = twoDbinHigherPhi;
+
+      /** in addition, we usually add at least one neighbouring slice 
+      * in Z. This depends on where we are in the detector. 
+      * Guide for the following: 
+      * z == 5: central z region, |z|<250mm
+      * 0  1  2  3  4    5    6  7  8  9  10  z bin index
+      * --------------------------------------> Z[mm]
+      *  Z=-2500       IP,Z=0            Z=+2500
+      **/
       if (z==5) {
-
-        m_rfz_t [a]    = 9;
-        m_rfz_it[a][3] = a+1;
-        m_rfz_it[a][4] = b+1;
-        m_rfz_it[a][5] = c+1;
-        m_rfz_it[a][6] = a-1;
-        m_rfz_it[a][7] = b-1;
-        m_rfz_it[a][8] = c-1;
-      } else if (z> 5) {
-
-        m_rfz_b [a]    = 6;
-        m_rfz_ib[a][3] = a-1;
-        m_rfz_ib[a][4] = b-1;
-        m_rfz_ib[a][5] = c-1;
+        m_nNeighbourCellsTop [twoDbinSamePhi]    = 9;
+        // in the central z region, we include the two neighbouring 
+        // z slices for the top neighbour search   
+
+        m_neighbourCellsTop[twoDbinSamePhi][3] = twoDbinSamePhi+1;
+        m_neighbourCellsTop[twoDbinSamePhi][4] = twoDbinLowerPhi+1;
+        m_neighbourCellsTop[twoDbinSamePhi][5] = twoDbinHigherPhi+1;
+        m_neighbourCellsTop[twoDbinSamePhi][6] = twoDbinSamePhi-1;
+        m_neighbourCellsTop[twoDbinSamePhi][7] = twoDbinLowerPhi-1;
+        m_neighbourCellsTop[twoDbinSamePhi][8] = twoDbinHigherPhi-1;
+      } 
+      // z > 5: positive z values, |z| > 250mm 
+      else if (z> 5) {
+        // for the bottom SP search in positive non-central z, we include the 
+        // neighbouring Z region on the left (towards the IP) in the bottom 
+        // neighbour search 
+        m_nNeighbourCellsBottom [twoDbinSamePhi]    = 6;
+        m_neighbourCellsBottom[twoDbinSamePhi][3] = twoDbinSamePhi-1;
+        m_neighbourCellsBottom[twoDbinSamePhi][4] = twoDbinLowerPhi-1;
+        m_neighbourCellsBottom[twoDbinSamePhi][5] = twoDbinHigherPhi-1;
 
         if (z<10) {
-
-          m_rfz_t [a]    = 6;
-          m_rfz_it[a][3] = a+1;
-          m_rfz_it[a][4] = b+1;
-          m_rfz_it[a][5] = c+1;
+        /** for the top SP search in positive z, 
+        * if we are not in the outermost z region, 
+        * we include the neighbouring Z region on the right (away from the IP). 
+        * In z = 10, the most forward, we do not have such a 'right side' neighbour we can add
+        **/
+          m_nNeighbourCellsTop [twoDbinSamePhi]    = 6;
+          m_neighbourCellsTop[twoDbinSamePhi][3] = twoDbinSamePhi+1;
+          m_neighbourCellsTop[twoDbinSamePhi][4] = twoDbinLowerPhi+1;
+          m_neighbourCellsTop[twoDbinSamePhi][5] = twoDbinHigherPhi+1;
         }
-      } else {
-
-        m_rfz_b [a]    = 6;
-        m_rfz_ib[a][3] = a+1;
-        m_rfz_ib[a][4] = b+1;
-        m_rfz_ib[a][5] = c+1;
+      } 
+      // z < 5: negative z values, |z| > 250mm 
+      else {
+        /** for the bottom SP in negative non-central z, we include 
+        * the neighbouring z region on the right (towards the IP) in the 
+        * bottom neighbour search 
+        **/
+        m_nNeighbourCellsBottom [twoDbinSamePhi]    = 6;
+        m_neighbourCellsBottom[twoDbinSamePhi][3] = twoDbinSamePhi+1;
+        m_neighbourCellsBottom[twoDbinSamePhi][4] = twoDbinLowerPhi+1;
+        m_neighbourCellsBottom[twoDbinSamePhi][5] = twoDbinHigherPhi+1;
 
         if (z>0) {
-
-          m_rfz_t [a]    = 6;
-          m_rfz_it[a][3] = a-1;
-          m_rfz_it[a][4] = b-1;
-          m_rfz_it[a][5] = c-1;
+          // if there is a z region on the left (away from the IP), we include it in the top
+          // neighbour search 
+          m_nNeighbourCellsTop [twoDbinSamePhi]    = 6;
+          m_neighbourCellsTop[twoDbinSamePhi][3] = twoDbinSamePhi-1;
+          m_neighbourCellsTop[twoDbinSamePhi][4] = twoDbinLowerPhi-1;
+          m_neighbourCellsTop[twoDbinSamePhi][5] = twoDbinHigherPhi-1;
         }
       }
 
+      /** 
+      * z bins 3 / 7: 450mm < |z| < 925mm.: 
+      * also include the central z region in the bottom SP search.  
+      * likely for PPP seeds with hits in pixel barrel + endcaps
+      **/
       if (z==3) {
-        m_rfz_b[a]      = 9;
-        m_rfz_ib[a][6] = a+2;
-        m_rfz_ib[a][7] = b+2;
-        m_rfz_ib[a][8] = c+2;
+        m_nNeighbourCellsBottom[twoDbinSamePhi]      = 9;
+        m_neighbourCellsBottom[twoDbinSamePhi][6] = twoDbinSamePhi+2;
+        m_neighbourCellsBottom[twoDbinSamePhi][7] = twoDbinLowerPhi+2;
+        m_neighbourCellsBottom[twoDbinSamePhi][8] = twoDbinHigherPhi+2;
       } else if (z==7) {
-        m_rfz_b[a]      = 9;
-        m_rfz_ib[a][6] = a-2;
-        m_rfz_ib[a][7] = b-2;
-        m_rfz_ib[a][8] = c-2;
+        m_nNeighbourCellsBottom[twoDbinSamePhi]      = 9;
+        m_neighbourCellsBottom[twoDbinSamePhi][6] = twoDbinSamePhi-2;
+        m_neighbourCellsBottom[twoDbinSamePhi][7] = twoDbinLowerPhi-2;
+        m_neighbourCellsBottom[twoDbinSamePhi][8] = twoDbinHigherPhi-2;
       }
     }
   }
 
-  // Build maps for radius-azimuthal-Z sorted collections for Z
-  //
-  for (int f=0; f<=m_fvNmax; ++f) {
+  /// Build maps for radius-azimuthal-Z sorted collections for Z
+  /// Similar logic to the above, just simplified as only 3 
+  /// regions in z exist!
+  for (int phiBin=0; phiBin<=m_maxBinPhiVertex; ++phiBin) {
+
+    int phiBinBelow = phiBin-1;
+    if (phiBinBelow<0) phiBinBelow=m_maxBinPhiVertex;
 
-    int fb = f-1;
-    if (fb<0) fb=m_fvNmax;
-    int ft = f+1;
-    if (ft>m_fvNmax) ft=0;
+    int phiBinTop = phiBin+1;
+    if (phiBinTop>m_maxBinPhiVertex) phiBinTop=0;
     
-    // For each azimuthal region loop through central Z regions
-    //
-    for (int z=0; z<SizeZV; ++z) {
+    /// For each azimuthal region loop through central Z regions
+    for (int zbin=0; zbin<arraySizeZV; ++zbin) {
       
-      int a  = f *SizeZV+z;
-      int b  = fb*SizeZV+z;
-      int c  = ft*SizeZV+z;
-      m_rfzv_n[a]    = 3;
-      m_rfzv_i[a][0] = a;
-      m_rfzv_i[a][1] = b;
-      m_rfzv_i[a][2] = c;
-      if (z>1) {
-        m_rfzv_n[a]    = 6;
-        m_rfzv_i[a][3] = a-1;
-        m_rfzv_i[a][4] = b-1;
-        m_rfzv_i[a][5] = c-1;
-      } else if (z<1) {
-        m_rfzv_n[a]    = 6;
-        m_rfzv_i[a][3] = a+1;
-        m_rfzv_i[a][4] = b+1;
-        m_rfzv_i[a][5] = c+1;
+      int twoDbinSamePhi  = phiBin *arraySizeZV+zbin;
+      int twoDbinLowePhi  = phiBinBelow*arraySizeZV+zbin;
+      int twoDbinHigherPhi  = phiBinTop*arraySizeZV+zbin;
+
+      /// always include the two neighbour bins in phi
+      m_nNeighboursVertexPhiZ[twoDbinSamePhi]    = 3;
+      m_neighboursVertexPhiZ[twoDbinSamePhi][0] = twoDbinSamePhi;
+      m_neighboursVertexPhiZ[twoDbinSamePhi][1] = twoDbinLowePhi;
+      m_neighboursVertexPhiZ[twoDbinSamePhi][2] = twoDbinHigherPhi;
+
+      /// for the positive z bin, include the central z slice as well 
+      if (zbin>1) {
+        m_nNeighboursVertexPhiZ[twoDbinSamePhi]    = 6;
+        m_neighboursVertexPhiZ[twoDbinSamePhi][3] = twoDbinSamePhi-1;
+        m_neighboursVertexPhiZ[twoDbinSamePhi][4] = twoDbinLowePhi-1;
+        m_neighboursVertexPhiZ[twoDbinSamePhi][5] = twoDbinHigherPhi-1;
+      } 
+      /// for the negative z bin, include the central z slice as well 
+      else if (zbin<1) {
+        m_nNeighboursVertexPhiZ[twoDbinSamePhi]    = 6;
+        m_neighboursVertexPhiZ[twoDbinSamePhi][3] = twoDbinSamePhi+1;
+        m_neighboursVertexPhiZ[twoDbinSamePhi][4] = twoDbinLowePhi+1;
+        m_neighboursVertexPhiZ[twoDbinSamePhi][5] = twoDbinHigherPhi+1;
       }
     }
   }
 }
 
 ///////////////////////////////////////////////////////////////////
-// Initiate beam frame work for seed generator
+/// Initiate beam frame work for seed generator
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::buildBeamFrameWork(EventData& data) const
 { 
   SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
 
-  const Amg::Vector3D &cb = beamSpotHandle->beamPos();
-  double     tx = tan(beamSpotHandle->beamTilt(0));
-  double     ty = tan(beamSpotHandle->beamTilt(1));
+  const Amg::Vector3D &bsCentre = beamSpotHandle->beamPos();
+  double     tx = std::tan(beamSpotHandle->beamTilt(0));
+  double     ty = std::tan(beamSpotHandle->beamTilt(1));
 
-  double ph   = atan2(ty,tx);
-  double th   = acos(1./sqrt(1.+tx*tx+ty*ty));
-  double sint = sin(th);
-  double cost = cos(th);
-  double sinp = sin(ph);
-  double cosp = cos(ph);
+  double phi   = std::atan2(ty,tx);
+  double theta   = std::acos(1./std::sqrt(1.+tx*tx+ty*ty));
+  double sinTheta = std::sin(theta);
+  double cosTheta = std::cos(theta);
+  double sinPhi = std::sin(phi);
+  double cosPhi = std::cos(phi);
   
-  data.xbeam[0] = static_cast<float>(cb.x());
-  data.xbeam[1] = static_cast<float>(cost*cosp*cosp+sinp*sinp);
-  data.xbeam[2] = static_cast<float>(cost*sinp*cosp-sinp*cosp);
-  data.xbeam[3] =-static_cast<float>(sint*cosp               );
-
-  data.ybeam[0] = static_cast<float>(cb.y());
-  data.ybeam[1] = static_cast<float>(cost*cosp*sinp-sinp*cosp);
-  data.ybeam[2] = static_cast<float>(cost*sinp*sinp+cosp*cosp);
-  data.ybeam[3] =-static_cast<float>(sint*sinp               );
+  data.xbeam[0] = static_cast<float>(bsCentre.x());
+  data.xbeam[1] = static_cast<float>(cosTheta*cosPhi*cosPhi+sinPhi*sinPhi);
+  data.xbeam[2] = static_cast<float>(cosTheta*sinPhi*cosPhi-sinPhi*cosPhi);
+  data.xbeam[3] =-static_cast<float>(sinTheta*cosPhi               );
+
+  data.ybeam[0] = static_cast<float>(bsCentre.y());
+  data.ybeam[1] = static_cast<float>(cosTheta*cosPhi*sinPhi-sinPhi*cosPhi);
+  data.ybeam[2] = static_cast<float>(cosTheta*sinPhi*sinPhi+cosPhi*cosPhi);
+  data.ybeam[3] =-static_cast<float>(sinTheta*sinPhi               );
   
-  data.zbeam[0] = static_cast<float>(cb.z());
-  data.zbeam[1] = static_cast<float>(sint*cosp);
-  data.zbeam[2] = static_cast<float>(sint*sinp);
-  data.zbeam[3] = static_cast<float>(cost);
+  data.zbeam[0] = static_cast<float>(bsCentre.z());
+  data.zbeam[1] = static_cast<float>(sinTheta*cosPhi);
+  data.zbeam[2] = static_cast<float>(sinTheta*sinPhi);
+  data.zbeam[3] = static_cast<float>(cosTheta);
 }
 
 ///////////////////////////////////////////////////////////////////
-// Initiate beam frame work for seed generator
+/// Initiate beam frame work for seed generator
 ///////////////////////////////////////////////////////////////////
 
 void  InDet::SiSpacePointsSeedMaker_ATLxk::convertToBeamFrameWork
-(EventData& data, const Trk::SpacePoint*const& sp, float* r) const
+(EventData& data, const Trk::SpacePoint*const& sp, std::array<float,3> & r) const
 {
   r[0] = static_cast<float>(sp->globalPosition().x())-data.xbeam[0];
   r[1] = static_cast<float>(sp->globalPosition().y())-data.ybeam[0];
@@ -1013,67 +1185,123 @@ void  InDet::SiSpacePointsSeedMaker_ATLxk::convertToBeamFrameWork
 }
    
 ///////////////////////////////////////////////////////////////////
-// Initiate space points seed maker
+/// Initiate space points seed maker
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::fillLists(EventData& data) const
 {
-  constexpr float pi2 = 2.*M_PI;
-  std::vector<InDet::SiSpacePointForSeed*>::iterator r, re;
+  constexpr float twoPi = 2.*M_PI;
 
-  int  ir0 =     0;
+  int  firstRadialBin =     0;
   bool ibl = false;
+
+  /** 
+  * The following is done separately for each iteration. 
+  * We sort the hits in our radially sorted lists into the 
+  * z-phi binning, keeping only those we want to consider to reduce 
+  * combinatorics
+  *
+  * Note that the use of r_first to start the loop is what ensures that 
+  * the first iteration is a pure SSS pass. 
+  * In newEvent, r_first is set to the bin after the last 
+  * radial bin containing Pixel space points. 
+  * For the second iteration, we reset it to zero and thus start in the pixels. 
+  **/ 
   
-  for (int i=data.r_first; i<m_r_size;  ++i) {
+  for (int radialBin=data.r_first; radialBin<m_nBinsR;  ++radialBin) {
 
-    if (!data.r_map[i]) continue;
-    r = data.r_Sorted[i].begin();
-    re = data.r_Sorted[i].end();
-    
-    if (!ir0) ir0 = i;
+    /// skip empty radial bins
+    if (!data.r_map[radialBin]) continue;
+    /// remember the first non-empty bin we encounter 
+    if (firstRadialBin == 0) firstRadialBin = radialBin;
 
+    /// if we are in the second iteration (PPP pass), we have some special exit conditions. 
     if (data.iteration) {
-      if (!(*r)->spacepoint->clusterList().second) {
-        if (i < 20) ibl = true;
-      } else if (ibl) {
+      /** 
+       * if we are dealing with a pixel hit 
+      * and the radial bin index is below 20, we are in the IBL. 
+      * this seems to be based on the default radial step of 2mm / bin, 
+      * where this is equivalent to 40mm. 
+      **/
+      if (!data.r_Sorted[radialBin].front()->spacepoint->clusterList().second) {
+        if (radialBin < 20) ibl = true;
+      } 
+
+      /// if we reach a *strip* hit in the PPP pass, we have two conditions for bailing out: 
+
+      /// a) if we saw IBL hits in the past, we stop as soon as we see the first strip hit - pure PPP
+      else if (ibl) {
         break;
-      } else if (i > 175) {
+      } 
+      /** b) in case we did not see any IBL hits, we stop after bin index 175.
+      * using the default r bin size of 2mm, this is equivalent to 350mm. 
+      * So the idea seems to be to include the first strip layer at 299mm before we stop. 
+      * This implies that for the non-IBL running, we include PPS seeds in this pass. 
+      **/
+      else if (radialBin > 175) {
         break;
       }
     }
-
-    for (; r!=re; ++r) {
+    // loop over the space points in the r-bin and sort them into the 2d phi-z binning 
+    for (InDet::SiSpacePointForSeed* SP : data.r_Sorted[radialBin]) {
       
-      // Azimuthal angle sort
-      //
-      float F = (*r)->phi();
-      if (F<0.) F+=pi2;
-
-      int f = static_cast<int>(F*m_sF);
-      if (f < 0) {
-        f = m_fNmax;
-      } else if (f > m_fNmax) {
-        f = 0;
+      /// Azimuthal angle sort
+      /// find the bin by dividing phi in 0...2pi by the bin size 
+      float Phi = SP->phi();
+      if (Phi<0.) Phi+=twoPi; // phi is defined in [0..2pi] for the binning 
+      int phiBin = static_cast<int>(Phi*m_inverseBinSizePhi);
+      /// handle overflows
+      if (phiBin < 0) {
+        phiBin = m_maxPhiBin;
+      } else if (phiBin > m_maxPhiBin) {
+        phiBin = 0;
       }
 
-      float Z = (*r)->z();
-      int z;
-      // Azimuthal angle and Z-coordinate sort
-      //
-      if (Z>0.) {
-        Z< 250.?z=5:Z< 450.?z=6:Z< 925.?z=7:Z< 1400.?z=8:Z< 2500.?z=9:z=10;
-      } else {
-        Z>-250.?z=5:Z>-450.?z=4:Z>-925.?z=3:Z>-1400.?z=2:Z>-2500.?z=1:z= 0;
+      float Z = SP->z();
+      /** z-coordinate sort. 
+      * Here, we have a variable bin size. 
+      * Use a map to replace 5 levels of nested ternaries 
+      * for a somewhat more readable notation while retaining
+      * a logN lookup speed 
+      **/
+      int zBin{0};
+      const std::map<float, int> ztoBin{
+        {-2500.    ,0},
+        {-1400.    ,1},
+        {-925.     ,2},
+        {-450.     ,3},
+        {-250      ,4},
+        { 250      ,5},
+        { 450      ,6},
+        { 925      ,7},
+        { 1400     ,8},
+        { 2500     ,9},
+        { 100000   ,10},  ///< if we encounter Si hits at z > +100m, we are probably not in ATLAS anymore...
+      };
+      auto bound = ztoBin.lower_bound(Z); 
+      /// some protection in case things go REALLY wrong
+      if (bound == ztoBin.end()){
+        --bound;  ///< z beyond the max: return last bin 
       }
+      zBin=bound->second;
 
-      int n = f*SizeZ+z;
+      /// 2D bin index - computed from the 1D using standard 2D array bin arithmetics  
+      int twoDbin = phiBin*arraySizeZ+zBin;
+      /// increment total counter of space points. 
+      /// This is not reset between iterations. 
       ++data.nsaz;
-      data.rfz_Sorted[n].push_back(*r);
-      if (!data.rfz_map[n]++) data.rfz_index[data.nrfz++] = n;
+      // push our space point into the 2D binned array
+      data.rfz_Sorted[twoDbin].push_back(SP);
+      /// the conditional seems to always be true. The rfz_index vector stores 
+      /// the 2D bin for each SP in the radius-sorted map. This way, 
+      /// we obtain effectively a *3D binning* in r(via the r-sorted vector), phi and z (via the 2D index)
+      if (!data.rfz_map[twoDbin]++) data.rfz_index[data.nrfz++] = twoDbin;
     }
   }
-  if (!m_sct && ir0 && static_cast<float>(ir0)*m_r_rstep < 43.) {
-    data.umax = -200.;
+  /// if we do not use the SCT, and did see some hits somewhere below 43mm (meaning we have the IBL installed), 
+  /// apply stricter requirements on the seed score later on 
+  if (!m_sct && firstRadialBin && static_cast<float>(firstRadialBin)*m_binSizeR < 43.) {
+    data.maxScore = -200.;
   }
 
   data.state = 0;
@@ -1122,15 +1350,15 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production2Sp(EventData& data) const
 
   // Loop thorugh all azimuthal regions
   //
-  for (int f=data.fvNmin; f<=m_fvNmax; ++f) {
+  for (int f=data.fvNmin; f<=m_maxBinPhiVertex; ++f) {
 
     // For each azimuthal region loop through Z regions
     //
     int z = 0;
     if (!data.endlist) z = data.zMin;
-    for (; z<SizeZV; ++z) {
+    for (; z<arraySizeZV; ++z) {
       
-      int a = f*SizeZV+z;
+      int a = f*arraySizeZV+z;
       if (!data.rfzv_map[a]) continue;
       r0  = data.rfzv_Sorted[a].begin();
       r0e = data.rfzv_Sorted[a].end  ();
@@ -1155,10 +1383,10 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production2Sp(EventData& data) const
 
         // Bottom links production
         //
-        int NB = m_rfzv_n[a];
-        for (int i=0; i<NB; ++i) {
+        int numberBottomCells = m_nNeighboursVertexPhiZ[a];
+        for (int i=0; i<numberBottomCells; ++i) {
     
-          int an = m_rfzv_i[a][i];
+          int an = m_neighboursVertexPhiZ[a][i];
           if (!data.rfzv_map[an]) continue;
 
           r  = data.rfzv_Sorted[an].begin();
@@ -1196,7 +1424,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production2Sp(EventData& data) const
             if (UR == 0.) continue;
             float A  = Vt*R/UR;
             float B  = Vt-A*Ut;
-            if (fabs(B*data.K) > m_ipt*sqrt(1.+A*A)) continue;
+            if (std::abs(B*data.K) > m_ipt*std::sqrt(1.+A*A)) continue;
             ++nseed;
             newSeed(data, (*r), (*r0), Zo);
           }
@@ -1219,246 +1447,425 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production2Sp(EventData& data) const
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp(EventData& data) const
 {
+
+  /// we need at least 3 SP in our phi-z binning, otherwise can't build 3-SP seeds
   if (data.nsaz<3) return;
 
-  const int   ZI[SizeZ]= {5,6,7,8,9,10,4,3,2,1,0};
-  std::vector<InDet::SiSpacePointForSeed*>::iterator rt[9],rte[9],rb[9],rbe[9];
+  /**
+   *  This method will run a separate seed formation round
+   *  for each phi-Z region, taking the central SP from there
+   *  and allowing the top/bottom SP to come from either the same
+   *  or certain neighbouring bins. 
+   *  
+   *  The search in each region is performed in the overload of this 
+   *  method with the extended signature below. 
+   *  Here, we implement the loop over the 2D regions
+   **/
+
+
+  /** 
+  * Order how we walk across z. 
+  * 0-4 are negative z, 5 is central z, 6-10 are positive z.
+  * 0  1  2  3  4    5    6  7  8  9  10  z bin index
+  * --------------------------------------> Z[mm]
+  *  Z=-2500       IP,Z=0            Z=+2500
+  * So we first go from the IP to the right, then from the IP to the left, 
+  * each time working our way outward
+  **/ 
+  const std::array<int,arraySizeZ> zBinIndex {5,6,7,8,9,10,4,3,2,1,0};
+
+  /// prepare arrays to store the iterators over the SP containers for all 
+  /// neighbouring cells we wish to consider in the seed formation
+  std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator,arraySizeNeighbourBins> iter_topCands;
+  std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator,arraySizeNeighbourBins> iter_endTopCands;
+  std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator,arraySizeNeighbourBins> iter_bottomCands;
+  std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator,arraySizeNeighbourBins> iter_endBottomCands;
+  
+  /// counter for the found
   int    nseed =    0;
+  /// prevent another pass from being run when we run out of Seeds
   data.endlist = true;
 
-  // Loop thorugh all azimuthal regions
-  //
-  for (int f=data.fNmin; f<=m_fNmax; ++f) {
+  /// Loop thorugh all azimuthal regions
+  for (int phiBin=data.fNmin; phiBin<=m_maxPhiBin; ++phiBin) {
     
-    // For each azimuthal region loop through all Z regions
-    //
+    /// For each azimuthal region loop through all Z regions
     int z = 0;
+    /// If we had to abort a previous run, continue where we left off 
     if (!data.endlist) z = data.zMin;
 
-    for (; z<SizeZ; ++z) {
+    /// note that this loop follows the order within 'zBinIndex',
+    /// not the ascending order of z regions. We start in the centre, 
+    /// not at -2500 mm, and then move outward. 
+    for (; z<arraySizeZ; ++z) {
+      
+      int phiZbin  = phiBin *arraySizeZ+zBinIndex[z];
+
+      /// can skip the rest if this particular 2D bin is empty 
+      if (!data.rfz_map[phiZbin]) continue;
 
-      int a  = f *SizeZ+ZI[z];
-      if (!data.rfz_map[a]) continue;
-      int NB = 0, NT = 0;
-      for (int i=0; i<m_rfz_b[a]; ++i) {
+      /// count how many non-emtpy cells should be searched for the 
+      /// top and bottom neighbour 
+      int numberBottomCells = 0;
+      int numberTopCells = 0;
+
+      /// walk through the cells in phi-z we wish to consider for the bottom SP search. 
+      /// Typically, this will be 3 adjacent phi bins (including the one of the central SP) 
+      /// and possibly neighbours in z on side towards the IP or on both sides, 
+      /// depdending on the z region we are in
+      for (int neighbourCellNumber=0; neighbourCellNumber<m_nNeighbourCellsBottom[phiZbin]; ++neighbourCellNumber) {
   
-        int an =  m_rfz_ib[a][i];
-        if (!data.rfz_map[an]) continue;
-        rb [NB] = data.rfz_Sorted[an].begin();
-        rbe[NB++] = data.rfz_Sorted[an].end();
+        int theNeighbourCell =  m_neighbourCellsBottom[phiZbin][neighbourCellNumber];
+        /// only do something if this cell is populated 
+        if (!data.rfz_map[theNeighbourCell]) continue;
+        /// plug the begin and end iterators to the SP in the cell into our array 
+        iter_bottomCands [numberBottomCells] = data.rfz_Sorted[theNeighbourCell].begin();
+        iter_endBottomCands[numberBottomCells++] = data.rfz_Sorted[theNeighbourCell].end();
       } 
-      for (int i=0; i<m_rfz_t[a]; ++i) {
-  
-        int an =  m_rfz_it[a][i];
-        if (!data.rfz_map[an]) continue;
-        rt [NT] = data.rfz_Sorted[an].begin();
-        rte[NT++] = data.rfz_Sorted[an].end();
+
+      /// walk through the cells in phi-z we wish to consider for the top SP search. 
+      /// Typically, this will be 3 adjacent phi bins (including the one of the central SP) 
+      /// and possibly neighbours in z on the side opposed to the IP or on both sides, 
+      /// depdending on the z region we are in
+      for (int neighbourCellNumber=0; neighbourCellNumber<m_nNeighbourCellsTop[phiZbin]; ++neighbourCellNumber) {
+
+        int theNeighbourCell =  m_neighbourCellsTop[phiZbin][neighbourCellNumber];
+        /// only do something if this cell is populated 
+        if (!data.rfz_map[theNeighbourCell]) continue;
+        /// plug the begin and end iterators to the SP in the cell into our array 
+        iter_topCands [numberTopCells] = data.rfz_Sorted[theNeighbourCell].begin();
+        iter_endTopCands[numberTopCells++] = data.rfz_Sorted[theNeighbourCell].end();
       } 
-      if (!data.trigger) production3Sp       (data, rb, rbe, rt, rte, NB, NT, nseed);
-      else               production3SpTrigger(data, rb, rbe, rt, rte, NB, NT, nseed);
+
+      /// now run the seed search for the current phi-z bin.
+      if (!data.trigger) production3Sp       (data, iter_bottomCands, iter_endBottomCands, iter_topCands, iter_endTopCands, numberBottomCells, numberTopCells, nseed);
+      else               production3SpTrigger(data, iter_bottomCands, iter_endBottomCands, iter_topCands, iter_endTopCands, numberBottomCells, numberTopCells, nseed);
     }
+
+    /** If we exceed the seed capacity, we stop here. 
+     * Save where we were in z and phi, and set endlist to false. 
+     * This will trigger another run of production3Sp when 
+     * The client calls next() after processing all vertices seen 
+     * so far (freeing up capacity). 
+     **/ 
     if (nseed>=m_maxsize) {
       data.endlist=false;
-      data.fNmin  =  f+1;
+      data.fNmin  =  phiBin+1;
       return;
     }
   }
+  /// Processed all seeds there are without aborting - no re-run needed!
   data.endlist = true;
 }
 
 ///////////////////////////////////////////////////////////////////
-// Production 3 space points seeds for full scan
+/// Production 3 space points seeds for full scan
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp
 (EventData& data,
- std::vector<InDet::SiSpacePointForSeed*>::iterator* rb ,
- std::vector<InDet::SiSpacePointForSeed*>::iterator* rbe,
- std::vector<InDet::SiSpacePointForSeed*>::iterator* rt ,
- std::vector<InDet::SiSpacePointForSeed*>::iterator* rte,
- const int NB, const int NT, int& nseed) const
+ std::array <std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_bottomCands ,
+ std::array <std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_endBottomCands,
+ std::array <std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_topCands ,
+ std::array <std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_endTopCands,
+ const int numberBottomCells, const int numberTopCells, int& nseed) const
 {
-  std::vector<InDet::SiSpacePointForSeed*>::iterator r0=rb[0],r;
-
+  /** 
+   * This methid implements the seed search for a single phi-Z region of the detector. 
+   * The central SP is taken from the region, while the top and bottom SP are allowed 
+   * to come from either the same or a range of neighbouring cells. 
+   **/ 
+
+  /// iterator across the candidates for the central space point. 
+  std::vector<InDet::SiSpacePointForSeed*>::iterator iter_centralSP=iter_bottomCands[0];
+  std::vector<InDet::SiSpacePointForSeed*>::iterator iter_otherSP;  ///< will be used for iterating over top/bottom SP
+
+  /// radial interval for the central SP.
+  /// For the PPP (PPS) pass, take Pixel layers 1,2,3
   float rmin =  40.;
   float rmax = 140.;
-  if((*r0)->spacepoint->clusterList().second) {
+  /// for strip seed formation, allow most of the strip volume
+  if((*iter_centralSP)->spacepoint->clusterList().second) {
     rmin = 280.;
     rmax = 540.;
   }
 
-  for(; r0!=rbe[0]; ++r0) {if((*r0)->radius() > rmin) break;}
-  rt[0] = r0; ++rt[0];
+  /// find the first central SP candidate above the minimum radius. 
+  for(; iter_centralSP!=iter_endBottomCands[0]; ++iter_centralSP) {
+    if((*iter_centralSP)->radius() > rmin) break;
+  }
+
+  /// for the top candidates in the central phi-Z bin, we do not need to start at a smaller
+  /// radius than the lowest-r valid central SP candidate  
+  iter_topCands[0] = iter_centralSP; 
+  ++iter_topCands[0];
 
+  /// prepare cut values 
   const float& ipt2K = data.ipt2K;
   const float& ipt2C = data.ipt2C;
   const float& COFK  = data.COFK;
-  const float& imaxp = m_diver;
-  const float& imaxs = m_divermax;
+  const float& maxd0cut = m_maxdImpact;
+  const float& maxd0cutstrips = m_maxdImpactDecays;
   const float& zmin  = data.zminU;
   const float& zmax  = data.zmaxU;
   const float& dzdrmax = data.dzdrmax;
   const float& dzdrmin = data.dzdrmin;
   data.CmSp.clear();
 
-  // Loop through all trigger space points
-  //
-  for (; r0!=rbe[0]; ++r0) {
+  /// Loop through all central space point candidates
+  for (; iter_centralSP!=iter_endBottomCands[0]; ++iter_centralSP) {
 
-    const float& R  = (*r0)->radius();
-    if(R > rmax) break;
+    const float& R  = (*iter_centralSP)->radius();
+    if(R > rmax) break; ///< stop if we have moved outside our radial region of interest. 
 
-    const float&        X    = (*r0)->x();
-    const float&        Y    = (*r0)->y();
-    const float&        Z    = (*r0)->z();
-    int                 Nb   = 0;
+    /// global coordinates of the central SP
+    const float&        X    = (*iter_centralSP)->x();
+    const float&        Y    = (*iter_centralSP)->y();
+    const float&        Z    = (*iter_centralSP)->z();
 
-    // Bottom links production
-    //
-    for (int i=0; i<NB; ++i) {
+    /// initialise a counter for found bottom links
+    /// This also serves as an index in the data.SP vector
+    int                 Nb   = 0;
 
-      for (r=rb[i]; r!=rbe[i]; ++r) {
-  
-        const float& Rb =(*r)->radius();
+    /// Bottom links production
+    /// Loop over all the cells where we expect to find such SP 
+    bool abortBottomLoop=false;
+    for (int cell=0; !abortBottomLoop && cell<numberBottomCells; ++cell) {
+      /// in each cell, loop over the space points
+      for (iter_otherSP=iter_bottomCands[cell]; iter_otherSP!=iter_endBottomCands[cell]; ++iter_otherSP) {
+        
+        /// evaluate the radial distance between the central and bottom SP
+        const float& Rb =(*iter_otherSP)->radius();
         float dR = R-Rb;
 
+        /// if the bottom SP is too far, remember this for future iterations and 
+        /// don't bother starting from the beginning again 
         if (dR > m_drmax) {
-          rb[i]=r;
+          iter_bottomCands[cell]=iter_otherSP;
           continue;
         }
-
-        if (dR < m_drmin || (data.iteration && (*r)->spacepoint->clusterList().second)) break;
-
-        const float Tz = (Z-(*r)->z())/dR;
-        const float aTz = std::abs(Tz);
-        if (aTz < dzdrmin or aTz > dzdrmax) continue;
+        /// if the points are too close in r, abort (future ones will be even closer). 
+        /// If we are in the second pass (PPP) and starting to reach strip spacepoints, also time to stop! 
+        if (dR < m_drmin || (data.iteration && (*iter_otherSP)->spacepoint->clusterList().second)) break;
+
+        /// dZ/dR
+        const float dZdR = (Z-(*iter_otherSP)->z())/dR;
+        /// and abs value 
+        const float absdZdR = std::abs(dZdR);
+        if (absdZdR < dzdrmin or absdZdR > dzdrmax) continue;
   
-        // Comparison with vertices Z coordinates
-        //
-        const float Zo = Z-R*Tz;
-	if(Zo > zmax || Zo < zmin) continue;
-        //if (!isZCompatible(data, Zo, Rb, Tz)) continue;
-        data.SP[Nb] = (*r);
-        if (++Nb==m_maxsizeSP) goto breakb;
-      }
-    }
-  breakb:
+        /// Comparison with vertices Z coordinates
+        /// straight line extrapolation to r=0 
+        const float z0 = Z-R*dZdR;
+	      if(z0 > zmax || z0 < zmin) continue;
+        /// found a bottom SP candidate, write it into the data object
+        data.SP[Nb] = (*iter_otherSP);
+        /// abort if we exceed the capacity for saving space points
+        if (++Nb==m_maxsizeSP) abortBottomLoop=true;
+      } ///< end of loop over SP in bottom candidate cell
+    } ///< end of loop over bottom candidate cells
+
+    /// if we did not find ANY bottom SP, or if we exceed the storage capacity, we abort this seed candidate. 
     if (!Nb || Nb==m_maxsizeSP) continue;
+
+    /// now continue with the top SP search. 
+    /// Make the counter start at Nb, as this serves as a running 
+    /// index in the SP list for this seed. 
     int Nt = Nb;
     
-    // Top   links production
-    //
-    for (int i=0; i<NT; ++i) {
-      
-      for (r=rt[i]; r!=rte[i]; ++r) {
+    /// Top links production
+    bool abortTopLoop=false;
+
+    /// again, loop over cells of interest, this time for the top SP candidate
+    for (int cell=0; !abortTopLoop && cell<numberTopCells; ++cell) {
+      /// loop over each SP in each cell 
+      for (iter_otherSP=iter_topCands[cell]; iter_otherSP!=iter_endTopCands[cell]; ++iter_otherSP) {
   
-        float Rt =(*r)->radius();
+        /// evaluate the radial distance, 
+        float Rt =(*iter_otherSP)->radius();
         float dR = Rt-R;
-  
+
+        /// and continue if we are too close 
         if (dR<m_drmin) {
-          rt[i]=r;
+          iter_topCands[cell]=iter_otherSP;
           continue;
         }
+        /// if we are to far, the next ones will be even farther, so abort 
         if (dR>m_drmax) break;
 
-
-        float Tz = ((*r)->z()-Z)/dR;
-        float aTz = std::abs(Tz);
-	if (aTz < dzdrmin or aTz > dzdrmax) continue;
-
-        // Comparison with vertices Z coordinates
-        //
-        float Zo = Z-R*Tz;
- 	if(Zo > zmax || Zo < zmin) continue;
-	//if (!isZCompatible(data, Zo, R, Tz)) continue;
-        data.SP[Nt] = (*r);
-        if (++Nt==m_maxsizeSP) goto breakt;
-      }
-    }
+        /// evaluate (and cut on) dZ/dR
+        float dZdR = ((*iter_otherSP)->z()-Z)/dR;
+        float absdZdR = std::abs(dZdR);
+	      if (absdZdR < dzdrmin or absdZdR > dzdrmax) continue;
+
+        /// Comparison with vertices Z coordinates
+        /// via straight line extrapolation to r=0 
+        float z0 = Z-R*dZdR;
+ 	      if(z0 > zmax || z0 < zmin) continue;
+        /// add SP to the list
+        data.SP[Nt] = (*iter_otherSP);
+        /// check capacity exceeding abort condition
+        if (++Nt==m_maxsizeSP) abortTopLoop=true;
+      } ///< end of loop over SP within top candidate cell
+    } ///< end of loop over top candidate cells
     
-  breakt:
+    /// if we found no top candidates (remember, Nt starts counting at Nb), abort 
     if (!(Nt-Nb)) continue;
-    float covr0 = (*r0)->covr ();
-    float covz0 = (*r0)->covz ();
+
+    /// get covariance on r and z for the central SP
+    float covr0 = (*iter_centralSP)->covr ();
+    float covz0 = (*iter_centralSP)->covz ();
+
+    /// build a unit direction vector pointing from the IP to the central SP
     float ax    = X/R;
     float ay    = Y/R;
 
+    /// check all SP candidates we found during our loop and 
+    /// compute geometrical variables w.r.t the central point. 
     for (int i=0; i<Nt; ++i) {
 
       InDet::SiSpacePointForSeed* sp = data.SP[i];
 
+      /// transform the space point coordinates into a frame centered around the middle SP,
+      /// where the x axis points away from the detector frame origin 
       float dx  = sp->x()-X;
       float dy  = sp->y()-Y;
       float dz  = sp->z()-Z;
       float x   = dx*ax+dy*ay;
       float y   = dy*ax-dx*ay;
+
+      /// inverse square distance of the candidate space point to the central point 
       float r2  = 1./(x*x+y*y);
+      /// inverse distance of the candidate space point to the central point 
       float dr  = sqrt(r2);
+      /// estimate slope in z - distance traveled in transverse plane vs z direction. 
+      /// rough estimate of 1/sin theta from 2 points
       float tz  = dz*dr;
+
+      /// if we are looking at a bottom SP candidate, flip the sign to account for 
+      /// different direction of flight (from bottom to central) 
       if (i < Nb) tz = -tz;
 
-      data.Tz[i]   = tz;
-      data.Zo[i]   = Z-R*tz;
-      data.R [i]   = dr;
-      data.U [i]   = x*r2;
-      data.V [i]   = y*r2;
-      data.Er[i]   = ((covz0+sp->covz())+(tz*tz)*(covr0+sp->covr()))*r2;
+      /// save this into our data object
+      data.Tz[i]   = tz;      ///< 1/ sin theta
+      data.Zo[i]   = Z-R*tz;  ///< z0 estimate. 
+      data.R [i]   = dr;      ///< inverse distance to central SP
+      data.U [i]   = x*r2;    ///< transformed U coordinate  
+      data.V [i]   = y*r2;    ///< transformed V coordinate 
+      data.Er[i]   = ((covz0+sp->covz())+(tz*tz)*(covr0+sp->covr()))*r2;    ///< 1/r² (cov(z)) + 1/r²sin²theta cov(r)
     }
+
+    /// tweak covariance matrix elements
     covr0      *= .5;
     covz0      *= 2.;
 
     data.nOneSeeds = 0;
     data.mapOneSeeds_Pro.clear();
 
-    // Three space points comparison
-    //
+    /// Three space points comparison
+    /// first, loop over the bottom point candidates
     for (int b=0; b<Nb; ++b) {
-    
-      float  Zob  = data.Zo[b];
-      float  Tzb  = data.Tz[b];
-      float  Rb2r = data.R [b]*covr0;
-      float  Rb2z = data.R [b]*covz0;
-      float  Erb  = data.Er[b];
-      float  Vb   = data.V [b];
-      float  Ub   = data.U [b];
-      float  Tzb2 = (1.+Tzb*Tzb);
-      float sTzb2 = sqrt(Tzb2);
-      float  CSA  = Tzb2*COFK;
-      float ICSA  = Tzb2*ipt2C;
-      float imax  = imaxp;
-      if (data.SP[b]->spacepoint->clusterList().second) imax = imaxs;
-  
+      
+      /// retrieve the geometrical paranmeters w.r.t the central SP for this candidate
+      float  Zob  = data.Zo[b];       ///< z0 estimate from central+bottom SP
+      float  Tzb  = data.Tz[b];       ///< 1/sintheta estimate from central+bottom SP
+      float  Rb2r = data.R [b]*covr0; ///< inverse distance times covariance on r coordinate
+      float  Rb2z = data.R [b]*covz0; ///< inverse distance times covariance on z coordinate
+      float  Erb  = data.Er[b];       ///< 1/r² (cov(z)) + 1/r²sin²theta cov(r)
+      float  Vb   = data.V [b];       ///< v-coordinate of bottom SP  
+      float  Ub   = data.U [b];       ///< u-coordinate of bottom SP
+      float  Tzb2 = (1.+Tzb*Tzb);     ///< 1+1/sin²theta 
+      float sTzb2 = sqrt(Tzb2);       ///< sqrt (1+1/sin²theta)
+      float  CSA  = Tzb2*COFK;        ///< magic number x (1+1+sin²theta) 
+      float ICSA  = Tzb2*ipt2C;       ///< magic number x inverse of 90% of the pt cut, squared x (1+1+sin²theta) 
+      /// max IP
+      float d0max  = maxd0cut;
+      /// for strips, apply the strip version of the IP cut 
+      if (data.SP[b]->spacepoint->clusterList().second) d0max = maxd0cutstrips;
+
+      /// inner loop over the top point candidates
       for (int t=Nb;  t<Nt; ++t) {
-  
-        float dT  = ((Tzb-data.Tz[t])*(Tzb-data.Tz[t])-data.R[t]*Rb2z-(Erb+data.Er[t]))-(data.R[t]*Rb2r)*((Tzb+data.Tz[t])*(Tzb+data.Tz[t]));
-        if (dT > ICSA) continue;
-
-        float dU  = data.U[t]-Ub;
-        if (dU == 0.) continue;
-        float A   = (data.V[t]-Vb)/dU;
-        float S2  = 1.+A*A;
-        float B   = Vb-A*Ub;
-        float B2  = B*B;
-        if (B2  > ipt2K*S2 || dT*S2 > B2*CSA) continue;
-
-        float Im  = fabs((A-B*R)*R);
 
-        if (Im <= imax) {
+        /// this appears to be an eta-compatibility cut between the two segments 
+        float dT  = ((Tzb-data.Tz[t])*(Tzb-data.Tz[t])-data.R[t]*Rb2z-(Erb+data.Er[t]))
+                  -(data.R[t]*Rb2r)*((Tzb+data.Tz[t])*(Tzb+data.Tz[t]));
+        if (dT > ICSA) continue;    
+
+        /** 
+        * The following exploits the transformation u:=x/(x²+y²); v:=y/(x²+y²); 
+        * This is applied on the x,y coordinates in the frame described above, where the 
+        * origin is put in the central SP and the x axis defined to point directly away from the IP.
+        * 
+        * In this transformed u,v frame, what would be our circle in x-y space takes the form of  
+        * a linear function V = (-x0/y0) x U + 1/(2y0) =: A x U + B.
+        * Here, x0 and y0 describe the center point of the circle in the x-y frame. 
+        * As the origin of the x-y frame (the middle space point of our seed) is on the circle, 
+        * we have x0²+y0²=R² with circle radius R. 
+        * 
+        * For our seed, we can experimentally obtain A as the slope of the linear function, 
+        * delta V / delta U, 
+        * estimated using the delta U and delta V between the top and bottom space point. 
+        * 
+        * B is then obtained by inserting the obtained A into the 
+        * linear equation for the bottom SP, A x U + B = V --> B = V - A x U 
+        * 
+        * With x0²+y0²=R², and x0=-A/2B and y0=1/2B, the radius of the circle is 
+        * then obtained as (2R)²=(1+A²)/B². 
+        **/ 
+        float deltaU  = data.U[t]-Ub;
+        if (deltaU == 0.) continue;       ///< delta U = 0 blocks the evaluation of A. 
+        float A   = (data.V[t]-Vb)/deltaU;  ///< A parameter, slope of the seed point distribution in the U,V plane 
+        float B   = Vb-A*Ub;            ///< B parameter, V axis intercept of the seed point distribution in the U,V plane 
+        float onePlusAsquare  = 1.+A*A;
+        float BSquare  = B*B;
+        /** With this radius (and pT) estimate, we can apply our pt cut. 
+         * Reminder, ipt2K is 1 / (K x 0.9 x pt-cut)², where K translates pt into 2R. 
+         * So here we can apply the pt cut directly on the (2R)² estimate without
+         * the extra overhead of conversion / division
+         **/ 
+        if (BSquare  > ipt2K*onePlusAsquare || dT*onePlusAsquare > BSquare*CSA) continue;
+
+        /** This is an estimate of the transverse impact parameter. 
+        * The reasoning is that, in the x-y frame with the central SP as origin and 
+        * the x axis pointing away from the IP, we have for the distance between
+        * the IP and the middle of the circle: 
+        * (x0 - r_central)²+y0² = (R + d0)², 
+        * with R being the circle radius and r_central 
+        * the radial location of the central SP, placing the IP at IP at (-r_central, 0). 
+        * 
+        * First simplify using R² =x0²+y0², then apply the approximation d0²/R² ~ 0. 
+        * 
+        * Finally, consider that locally close to the central SP, the circle is parallel to the x axis, 
+        * so A = 0 --> expand (2R)²=(1+A²)/B² around this point to obtain 
+        * d0 = r_central x (r_central x B - A). 
+        * Note that below, the variable R is the radial coordinate fo the central SP, 
+        * corresponding to r_central in the notation above. 
+        **/
+        float d0  = std::abs((A-B*R)*R);
+
+        /// apply d0 cut to seed 
+        if (d0 <= d0max) {
+          /// evaluate distance the two closest-by SP in this seed candidate 
           float dr = data.R[b];
           if (data.R[t] < data.R[b]) dr = data.R[t];
-          Im+=fabs((Tzb-data.Tz[t])/(dr*sTzb2));
-          data.CmSp.emplace_back(std::make_pair(B/sqrt(S2), data.SP[t]));
-          data.SP[t]->setParam(Im);
+          /// update the d0 estimate
+          d0+=std::abs((Tzb-data.Tz[t])/(dr*sTzb2));
+          /// record one possible seed candidate, sort by the curvature 
+          data.CmSp.emplace_back(std::make_pair(B/std::sqrt(onePlusAsquare), data.SP[t]));
+          /// store the transverse IP, will later be used as a quality estimator 
+          data.SP[t]->setParam(d0);
 
         }
-      }
+      }   ///< end loop over top space point candidates
+      /// now apply further cleaning on the seed candidates for this central+bottom pair. 
       if (!data.CmSp.empty()) {
-        newOneSeedWithCurvaturesComparison(data, data.SP[b], (*r0), Zob);
+        newOneSeedWithCurvaturesComparison(data, data.SP[b], (*iter_centralSP), Zob);
       }
-    }
+    } ///< end loop over bottom space points
+    ///record seeds found in this run  
     fillSeeds(data);
     nseed += data.fillOneSeeds;
-  }
+  } ///< end loop over central SP 
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -1467,13 +1874,13 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::production3SpTrigger
 (EventData& data,
- std::vector<InDet::SiSpacePointForSeed*>::iterator* rb ,
- std::vector<InDet::SiSpacePointForSeed*>::iterator* rbe,
- std::vector<InDet::SiSpacePointForSeed*>::iterator* rt ,
- std::vector<InDet::SiSpacePointForSeed*>::iterator* rte,
- const int NB, const int NT, int& nseed) const
+ std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & rb ,
+ std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & rbe,
+ std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & rt ,
+ std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & rte,
+ const int numberBottomCells, const int numberTopCells, int& nseed) const
 {
-  constexpr float pi2 = 2.*M_PI;
+  constexpr float twoPi = 2.*M_PI;
 
   std::vector<InDet::SiSpacePointForSeed*>::iterator r0=rb[0],r;
 
@@ -1490,8 +1897,8 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3SpTrigger
   float ipt2K = data.ipt2K;
   float ipt2C = data.ipt2C;
   float COFK  = data.COFK;
-  float imaxp = m_diver;
-  float imaxs = m_diversss;
+  float maxd0cut = m_maxdImpact;
+  float maxd0cutstrips = m_maxdImpactSSS;
 
   data.CmSp.clear();
 
@@ -1513,7 +1920,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3SpTrigger
 
     // Bottom links production
     //
-    for (int i=0; i<NB; ++i) {
+    for (int i=0; i<numberBottomCells; ++i) {
 
       for (r=rb[i]; r!=rbe[i]; ++r) {
   
@@ -1545,7 +1952,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3SpTrigger
     
     // Top   links production
     //
-    for (int i=0; i<NT; ++i) {
+    for (int i=0; i<numberTopCells; ++i) {
       
       for (r=rt[i]; r!=rte[i]; ++r) {
   
@@ -1617,33 +2024,33 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3SpTrigger
       float  Tzb2 = (1.+Tzb*Tzb);
       float  CSA  = Tzb2*COFK;
       float ICSA  = Tzb2*ipt2C;
-      float imax  = imaxp;
-      if (data.SP[b]->spacepoint->clusterList().second) imax = imaxs;
+      float d0max  = maxd0cut;
+      if (data.SP[b]->spacepoint->clusterList().second) d0max = maxd0cutstrips;
       
       for (int t=Nb;  t<Nt; ++t) {
   
         float dT  = ((Tzb-data.Tz[t])*(Tzb-data.Tz[t])-data.R[t]*Rb2z-(Erb+data.Er[t]))-(data.R[t]*Rb2r)*((Tzb+data.Tz[t])*(Tzb+data.Tz[t]));
         if ( dT > ICSA) continue;
 
-        float dU  = data.U[t]-Ub;
-        if (dU == 0.) continue;
-        float A   = (data.V[t]-Vb)/dU;
-        float S2  = 1.+A*A;
+        float deltaU  = data.U[t]-Ub;
+        if (deltaU == 0.) continue;
+        float A   = (data.V[t]-Vb)/deltaU;
+        float onePlusAsquare  = 1.+A*A;
         float B   = Vb-A*Ub;
-        float B2  = B*B;
-        if (B2  > ipt2K*S2 || dT*S2 > B2*CSA) continue;
+        float BSquare  = B*B;
+        if (BSquare  > ipt2K*onePlusAsquare || dT*onePlusAsquare > BSquare*CSA) continue;
 
-        float Im  = fabs((A-B*R)*R);
-        if (Im > imax) continue;
+        float Im  = std::abs((A-B*R)*R);
+        if (Im > d0max) continue;
 
         // Azimuthal angle test
         //
         float y  = 1.;
         float x  = 2.*B*R-A;
-        float df = fabs(atan2(ay*y-ax*x,ax*y+ay*x)-data.ftrig);
-        if (df > M_PI) df = pi2-df;
+        float df = std::abs(std::atan2(ay*y-ax*x,ax*y+ay*x)-data.ftrig);
+        if (df > M_PI) df = twoPi-df;
         if (df > data.ftrigW) continue;
-        data.CmSp.emplace_back(std::make_pair(B/sqrt(S2), data.SP[t]));
+        data.CmSp.emplace_back(std::make_pair(B/std::sqrt(onePlusAsquare), data.SP[t]));
         data.SP[t]->setParam(Im);
       }
       if (!data.CmSp.empty()) {
@@ -1664,23 +2071,31 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newOneSeed
  InDet::SiSpacePointForSeed*& p1, InDet::SiSpacePointForSeed*& p2,
  InDet::SiSpacePointForSeed*& p3, float z, float q) const
 {
+  /// If we have not yet reached the maximum number of allowed seeds per central SP, 
+  /// add this one to the list 
   if (data.nOneSeeds < m_maxOneSize) {
 
     data.OneSeeds_Pro[data.nOneSeeds].set(p1,p2,p3,z);
     data.mapOneSeeds_Pro.insert(std::make_pair(q, &data.OneSeeds_Pro[data.nOneSeeds]));
     ++data.nOneSeeds;
-  } else {
+  } 
+  /// otherwise, we check if there is a poorer-quality seed that we can kick out
+  else {
+    /// get the worst seed so far 
     std::multimap<float,InDet::SiSpacePointsProSeed*>::reverse_iterator 
       l = data.mapOneSeeds_Pro.rbegin();
-
+    /// if the worst so far is better than what we have on hand, our new candidate
+    /// is unlucky and gets skipped
     if ((*l).first <= q) return;
     
+    /// otherwise, we overwrite the worst seed so far with our new friend 
     InDet::SiSpacePointsProSeed* s = (*l).second;
     s->set(p1,p2,p3,z);
 
+    /// re-insert it with its proper quality to make sure it ends up in the right place 
     std::multimap<float,InDet::SiSpacePointsProSeed*>::iterator 
       i = data.mapOneSeeds_Pro.insert(std::make_pair(q,s));
-  
+    /// and remove the entry with the old quality, which has been kicked out. 
     for (++i; i!=data.mapOneSeeds_Pro.end(); ++i) {
       if ((*i).second==s) {
         data.mapOneSeeds_Pro.erase(i);
@@ -1697,108 +2112,162 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newOneSeed
 void InDet::SiSpacePointsSeedMaker_ATLxk::newOneSeedWithCurvaturesComparison
 (EventData& data, SiSpacePointForSeed*& SPb, SiSpacePointForSeed*& SP0, float Zob) const
 {
-  static const float dC = .00003;
+  static const float curvatureInterval = .00003;
 
-  bool  pixb = !SPb->spacepoint->clusterList().second;
-  float ub   = SPb->quality();
-  float u0   = SP0->quality();
+  bool  bottomSPisPixel = !SPb->spacepoint->clusterList().second;
+  float bottomSPQuality   = SPb->quality();
+  float centralSPQuality   = SP0->quality();
 
+  /// sort common SP by curvature 
   if(data.CmSp.size() > 2) std::sort(data.CmSp.begin(), data.CmSp.end(), comCurvature());
 
-  std::vector<std::pair<float,InDet::SiSpacePointForSeed*>>::iterator j,jn,i = data.CmSp.begin(), ie = data.CmSp.end();
-  jn=i;
+  std::vector<std::pair<float,InDet::SiSpacePointForSeed*>>::iterator it_otherSP;
+  std::vector<std::pair<float,InDet::SiSpacePointForSeed*>>::iterator it_commonTopSP = data.CmSp.begin(), ie = data.CmSp.end();
+  std::vector<std::pair<float,InDet::SiSpacePointForSeed*>>::iterator it_startInnerLoop=it_commonTopSP;
 
-  for (; i!=ie; ++i) {
+  /// check all possible common top SP
+  for (; it_commonTopSP!=ie; ++it_commonTopSP) {
 
-    float u    = (*i).second->param();
-    float Im   = (*i).second->param();
+    /// the seed quality is set to d0 initially 
+    float seedQuality    = (*it_commonTopSP).second->param();
+    float originalSeedQuality   = (*it_commonTopSP).second->param();
 
-    bool                pixt = !(*i).second->spacepoint->clusterList().second;
+    bool                topSPisPixel = !(*it_commonTopSP).second->spacepoint->clusterList().second;
     
-    const Trk::Surface* Sui  = (*i).second->sur   ();
-    float               Ri   = (*i).second->radius();
-    float               Ci1  =(*i).first-dC;
-    float               Ci2  =(*i).first+dC;
+    /// check the surface the hit is on 
+    const Trk::Surface* surfaceTopSP  = (*it_commonTopSP).second->sur   ();
+    float               radiusTopSP   = (*it_commonTopSP).second->radius();
+    /// form a curvature interval cut
+    float               minCurvature  =(*it_commonTopSP).first-curvatureInterval;
+    float               maxCurvature  =(*it_commonTopSP).first+curvatureInterval;
     
-    if      (!pixb) u-=400.;
-    else if ( pixt) u-=200.;
-
-    for (j=jn;  j!=ie; ++j) {
-      
-      if (       j == i           ) continue;
-      if ( (*j).first < Ci1       ) {jn=j; ++jn; continue;}
-      if ( (*j).first > Ci2       ) break;
-      if ( (*j).second->sur()==Sui) continue;
-      
-      float Rj = (*j).second->radius();
-      if (fabs(Rj-Ri) < m_drmin) continue;
-      u -= 200.;
+    /** Note: The score modifiers used here have the purpose of separating the candidates into
+     *        classes / groups disjoint from each other. 
+     *        So the score increment (200 by default) should exceed the maximum 
+     *        |d0| (base score) we expect to encounter to avoid overlap. 
+     *        For LRT, we may want to tune this! 
+     **/  
+
+    /// if we have a SSS seed, boost the quality score by 400 
+    if      (!bottomSPisPixel) seedQuality-=400.;
+    /// if we have a PPP, boost the quality by 200 
+    else if ( topSPisPixel) seedQuality-=200.;
+
+
+    /** 
+    * Now we look at the other SP candidates and try to find a confirmation seed,
+    * including the same centre/lower SP and giving a compatible curvature,
+    * but with the top SP in a different layer 
+    **/ 
+
+    for (it_otherSP=it_startInnerLoop;  it_otherSP!=ie; ++it_otherSP) {
+      /// if we are looking at the same SP, skip it 
+      if (       it_otherSP == it_commonTopSP           ) continue;
+      /// if we have a lower curvature than the minimum, skip - and remember to 
+      /// not bother with this candidate again later, as the vectors are curvature-sorted
+      if ( (*it_otherSP).first < minCurvature       ) {
+        it_startInnerLoop=it_otherSP; 
+        ++it_startInnerLoop; 
+        continue;
+      }
+      /// abort once the the curvature gets too large
+      if ( (*it_otherSP).first > maxCurvature       ) break;
+      /// if both SP are on the surface, skip it 
+      if ( (*it_otherSP).second->sur()==surfaceTopSP) continue;
+      /// if the other SP is too close to the current top one, skip 
+      float radiusOtherSP = (*it_otherSP).second->radius();
+      if (std::abs(radiusOtherSP-radiusTopSP) < m_drmin) continue;
+      /// if we have a confirmation seed, we improve the score of the seed. 
+      seedQuality -= 200.;
+      /// only look for one confirmation seed! 
       break;
     }
-
-    if (u > data.umax) continue;
+    /// kick this seed candidate if the score is too high (lower values = better) 
+    if (seedQuality > data.maxScore) continue;
     
-    if (pixb!=pixt) {
-      if (u > 0. || (u > ub && u > u0 && u > (*i).second->quality()) ) continue;
+    /// if we have PPS seeds and no confirmation SP exists (which would give the -200 bonus)
+    /// or the seed quality is worse than the quality of the individual SP, skip this seed
+    if (bottomSPisPixel!=topSPisPixel) {
+      if (seedQuality > 0. || 
+        (seedQuality > bottomSPQuality && seedQuality > centralSPQuality && seedQuality > (*it_commonTopSP).second->quality()) 
+      ) continue;
     }
-    if (!pixb && Im > m_diversss && u > Im-500.) continue;
-
-    newOneSeed(data, SPb, SP0, (*i).second, Zob, u);
-  }
+    /// if we have a SSS seed, apply the d0 cut. 
+    /// Exception: If the SSS seed has a confirmation seed (-400 from SSS and -200 from confirmation), 
+    /// then we skip the d0 cut  
+    if (!bottomSPisPixel && originalSeedQuality > m_maxdImpactSSS && seedQuality > originalSeedQuality-500.) continue;
+    /// this is a good seed, save it (unless we have too many seeds per SP)
+    newOneSeed(data, SPb, SP0, (*it_commonTopSP).second, Zob, seedQuality);
+  } ///< end of loop over top SP candidates
   data.CmSp.clear();
 }
 
 ///////////////////////////////////////////////////////////////////
-// Fill seeds
+/// Fill seeds
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::fillSeeds(EventData& data) const
 {
   data.fillOneSeeds = 0;
 
-  std::multimap<float,InDet::SiSpacePointsProSeed*>::iterator 
-    lf = data.mapOneSeeds_Pro.begin(),
-    l  = data.mapOneSeeds_Pro.begin(),
-    le = data.mapOneSeeds_Pro.end();
+  std::multimap<float,InDet::SiSpacePointsProSeed*>::iterator it_firstSeedCandidate = data.mapOneSeeds_Pro.begin();
+  std::multimap<float,InDet::SiSpacePointsProSeed*>::iterator it_seedCandidate  = data.mapOneSeeds_Pro.begin();
+  std::multimap<float,InDet::SiSpacePointsProSeed*>::iterator it_endSeedCandidates = data.mapOneSeeds_Pro.end();
   
-  if (l==le) return;
-
-  SiSpacePointsProSeed* s;
+  /// no seeds - nothing to do. 
+  if (it_seedCandidate==it_endSeedCandidates) return;
 
-  for (; l!=le; ++l) {
+  SiSpacePointsProSeed* theSeed{nullptr};
 
-    float w = (*l).first;
+  /// loop over the seed candidates we have stored in the event data
+  for (; it_seedCandidate!=it_endSeedCandidates; ++it_seedCandidate) {
 
-    s       = (*l).second;
-    if (l!=lf && s->spacepoint0()->radius() < 43. && w > -200.) continue;
-    if (!s->setQuality(w)) continue;
+    /// quality score of the seed, lower = better, list is sorted by quality 
+    float quality = (*it_seedCandidate).first;
+    theSeed       = (*it_seedCandidate).second;
+    /// if this is not the highest-quality seed in the list and we have the first hit in the IBL, require a confirmation seed (score is then boosted by -200 for PPP + -200 for confirmation --> below -200)
+    if (it_seedCandidate!=it_firstSeedCandidate && theSeed->spacepoint0()->radius() < 43. && quality > -200.) continue;
+    /// this will return false for strip seeds if the quality of the seed is worse than the one of all of the space points on the seed. 
+    if (!theSeed->setQuality(quality)) continue;
     
+    /// if we have space, write the seed directly into an existing slot 
     if (data.i_seede_Pro!=data.l_seeds_Pro.end()) {
-      s  = &(*data.i_seede_Pro++);
-      *s = *(*l).second;
+      theSeed  = &(*data.i_seede_Pro++);
+      *theSeed = *(*it_seedCandidate).second;
     } else {
-      data.l_seeds_Pro.emplace_back(SiSpacePointsProSeed(*(*l).second));
-      s = &(data.l_seeds_Pro.back());
+      /// otherwise, extend the seed list and update the iterators 
+      data.l_seeds_Pro.emplace_back(SiSpacePointsProSeed(*(*it_seedCandidate).second));
+      theSeed = &(data.l_seeds_Pro.back());
       data.i_seede_Pro = data.l_seeds_Pro.end();
     }
     
    ++data.fillOneSeeds;
-  }
+  } ///< end loop over seed candidates 
 }
 
 const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_ATLxk::next(const EventContext&, EventData& data) const
 {
+  /// This only holds if we call next() without manually calling newEvent/find3Sp
   if (not data.initialized) initializeEventData(data);
-
+  
   if (data.nspoint==3) {
     do {
+      /// If we are out of seeds, call findNext to see if we can find more. 
       if (data.i_seed_Pro==data.i_seede_Pro) {
+        /// findNext will call production3Sp again IF data.endlist is false, 
+        /// which is only the case if the last run of production3Sp did not run to the end
+        /// or if we did not run seed finding before 
+        /// For run-3 offline, this will not do anything. 
         findNext(data);
+        /// if no new seeds were found, exit  
         if (data.i_seed_Pro==data.i_seede_Pro) return nullptr;
       }
+      /// iterate until we find a valid seed satisfying certain quality cuts in set3 
     } while (!(*data.i_seed_Pro++).set3(data.seedOutput));
+    /// then return this next seed candidate 
     return &data.seedOutput;
   } else {
+    /// same as above for 2SP
     if (data.i_seed_Pro==data.i_seede_Pro) {
       findNext(data);
       if (data.i_seed_Pro==data.i_seede_Pro) return nullptr;
@@ -1818,7 +2287,7 @@ bool InDet::SiSpacePointsSeedMaker_ATLxk::isZCompatible
 
   float dZmin = std::numeric_limits<float>::max();
   for (const float& v: data.l_vertex) {
-    float dZ = fabs(v-Zv);
+    float dZ = std::abs(v-Zv);
     if (dZ >= dZmin) break;
     dZmin = dZ;
   }
@@ -1829,7 +2298,7 @@ bool InDet::SiSpacePointsSeedMaker_ATLxk::isZCompatible
 }
 
 ///////////////////////////////////////////////////////////////////
-// New space point for seeds 
+/// New space point for seeds 
 ///////////////////////////////////////////////////////////////////
 
 InDet::SiSpacePointForSeed* InDet::SiSpacePointsSeedMaker_ATLxk::newSpacePoint
@@ -1837,22 +2306,33 @@ InDet::SiSpacePointForSeed* InDet::SiSpacePointsSeedMaker_ATLxk::newSpacePoint
 {
   InDet::SiSpacePointForSeed* sps = nullptr;
 
-  float r[3];
+  /// r will store the coordinates of the space point relative 
+  /// to the beam spot 
+  std::array<float,3> r{0,0,0};
   convertToBeamFrameWork(data, sp, r);
 
+  /// if needed, apply eta criterion 
   if (data.checketa) {
-    float z = (fabs(r[2])+m_zmax);
+    float z = (std::abs(r[2])+m_zmax); 
     float x = r[0]*data.dzdrmin;
     float y = r[1]*data.dzdrmin;
     if ((z*z )<(x*x+y*y)) return sps;
   }
-
+  /// If we have previously populated the list and just reset 
+  /// the iterator when re-initialising the data object,
+  /// then we re-use existing entries 
   if (data.i_spforseed!=data.l_spforseed.end()) {
+    /// re-use existing entry at the current location 
     sps = &(*data.i_spforseed++);
-    sps->set(sp,r);
+    /// and then update the existing entry with the new SP and location.
+    /// Unfortunately, set still relies on C-arrays... 
+    sps->set(sp,&(r[0]));
   } else {
-    data.l_spforseed.emplace_back(InDet::SiSpacePointForSeed(sp, r));
+    /// otherwise, the list needs to grow
+    data.l_spforseed.emplace_back(InDet::SiSpacePointForSeed(sp, &(r[0])));
+    /// set our return pointer 
     sps = &(data.l_spforseed.back());
+    /// and make sure to update the iterator 
     data.i_spforseed = data.l_spforseed.end();
   }
       
@@ -1881,10 +2361,10 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::initializeEventData(EventData& data) c
   data.initialize(EventData::ATLxk,
                   m_maxsizeSP,
                   m_maxOneSize,
-                  0, // maxsize not used
-                  m_r_size,
-                  0, // sizeRF not used
-                  SizeRFZ,
-                  SizeRFZV,
+                  0, /// maxsize not used
+                  m_nBinsR,
+                  0, /// sizeRF not used
+                  arraySizePhiZ,
+                  arraySizePhiZV,
                   m_checketa);
 }
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_BeamGas.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_BeamGas.cxx
index abd0d2c58d5d72b439e3bd25061fbfd664250ea4..2c7400366b8640c148bfd0a2b9bfc6a89e1d75c4 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_BeamGas.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_BeamGas.cxx
@@ -253,14 +253,13 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newRegion
 
     SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
-      SpacePointContainer::const_iterator spce = spacepointsPixel->end();
 
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vPixel) {
-	SpacePointContainer::const_iterator w = spacepointsPixel->indexFind(l);
-	if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+	auto w = spacepointsPixel->indexFindPtr(l);
+	if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
 	  float r = sp->r();
           if (r<0. || r>=m_r_rmax) continue;
 	  if (prd_to_track_map_cptr && isUsed(sp, *prd_to_track_map_cptr)) continue;
@@ -281,14 +280,12 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newRegion
 
     SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
-      SpacePointContainer::const_iterator spce = spacepointsSCT->end();
-
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vPixel) {
-	SpacePointContainer::const_iterator w = spacepointsSCT->indexFind(l);
-	if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+	auto w = spacepointsSCT->indexFindPtr(l);
+	if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
 	  float r = sp->r();
           if (r<0. || r>=m_r_rmax) continue;
 	  if (prd_to_track_map_cptr && isUsed(sp,*prd_to_track_map_cptr)) continue;
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Cosmic.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Cosmic.cxx
index e0572aad3cf5a5c03d247d8598de1e8960d6ff25..bbfc2e54f2528a1547fd12462d1a121ff6416b98 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Cosmic.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Cosmic.cxx
@@ -207,14 +207,12 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::newRegion
 
     SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
-      SpacePointContainer::const_iterator spce = spacepointsPixel->end();
-
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vPixel) {
-	SpacePointContainer::const_iterator w = spacepointsPixel->indexFind(l);
-	if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+	auto w = spacepointsPixel->indexFindPtr(l);
+	if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
 	  float r = sp->r();
           if (r<0. || r>=m_r_rmax) continue;
 	  if (prd_to_track_map_cptr && isUsed(sp,*prd_to_track_map_cptr)) continue;
@@ -236,14 +234,13 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::newRegion
 
     SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
-      SpacePointContainer::const_iterator spce = spacepointsSCT->end();
 
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vSCT) {
-	SpacePointContainer::const_iterator w = spacepointsSCT->indexFind(l);
-	if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+	auto w = spacepointsSCT->indexFindPtr(l);
+	if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
 	  float r = sp->r();
           if (r<0. || r>=m_r_rmax) continue;
 	  if (prd_to_track_map_cptr && isUsed(sp,*prd_to_track_map_cptr)) continue;
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_HeavyIon.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_HeavyIon.cxx
index 02777545edfc2acf061cde31d621e6f00d7887dc..423b40ddfde67c2e3daebc184356c9adcdddd03c 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_HeavyIon.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_HeavyIon.cxx
@@ -208,14 +208,13 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::newRegion
 
     SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
-      SpacePointContainer::const_iterator spce = spacepointsPixel->end();
 
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vPixel) {
-	SpacePointContainer::const_iterator w = spacepointsPixel->indexFind(l);
-	if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+	auto w = spacepointsPixel->indexFindPtr(l);
+	if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
 	  float r = sp->r();
           if (r<0. || r>=m_r_rmax) continue;
 	  InDet::SiSpacePointForSeed* sps = newSpacePoint(data, sp);
@@ -236,14 +235,13 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::newRegion
 
     SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
-      SpacePointContainer::const_iterator spce = spacepointsSCT->end();
 
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vSCT) {
-	SpacePointContainer::const_iterator w = spacepointsSCT->indexFind(l);
-	if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+	auto w = spacepointsSCT->indexFindPtr(l);
+	if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
 	  float r = sp->r();
           if (r<0. || r>=m_r_rmax) continue;
 	  InDet::SiSpacePointForSeed* sps = newSpacePoint(data, sp);
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ITK.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ITK.cxx
index eff676328de360bb4183d4247c0611b745fbc68d..acc9bb73cea63d1b0ced23e61bf19f2ecd54dd1b 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ITK.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ITK.cxx
@@ -302,14 +302,13 @@ void InDet::SiSpacePointsSeedMaker_ITK::newRegion
 
     SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
-      SpacePointContainer::const_iterator spce = spacepointsPixel->end();
 
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vPixel) {
-	SpacePointContainer::const_iterator w = spacepointsPixel->indexFind(l);
-	if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+	auto w = spacepointsPixel->indexFindPtr(l);
+	if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
 	  float r = sp->r();
           if (r > m_r_rmax || r < m_r_rmin) continue;
 	  InDet::SiSpacePointForSeedITK* sps = newSpacePoint(data, sp);
@@ -330,14 +329,13 @@ void InDet::SiSpacePointsSeedMaker_ITK::newRegion
 
     SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
-      SpacePointContainer::const_iterator spce = spacepointsSCT->end();
 
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vSCT) {
-	SpacePointContainer::const_iterator w = spacepointsSCT->indexFind(l);
-	if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+	auto w = spacepointsSCT->indexFindPtr(l);
+	if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
 	  float r = sp->r();
           if (r > m_r_rmax || r < m_r_rmin) continue;
 	  InDet::SiSpacePointForSeedITK* sps = newSpacePoint(data, sp);
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_LowMomentum.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_LowMomentum.cxx
index 942b6e1bb578ec78ff7d307fdf231d05ad331c31..d85bfc747981a6ea71e96053793d72c13cf2a43d 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_LowMomentum.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_LowMomentum.cxx
@@ -199,9 +199,9 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::newRegion
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vPixel) {
-        SpacePointContainer::const_iterator w = spacepointsPixel->indexFind(l);
-        if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+        auto w = spacepointsPixel->indexFindPtr(l);
+        if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
           float r = sp->r();
           if (r<0. || r>=m_r_rmax) continue;
           if (prd_to_track_map_cptr && isUsed(sp,*prd_to_track_map_cptr)) continue;
@@ -231,9 +231,9 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::newRegion
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vSCT) {
-        SpacePointContainer::const_iterator w = spacepointsSCT->indexFind(l);
-        if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+        auto w = spacepointsSCT->indexFindPtr(l);
+        if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
           float r = sp->r();
           if (r<0. || r>=m_r_rmax) continue;
           if (prd_to_track_map_cptr && isUsed(sp,*prd_to_track_map_cptr)) continue;
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Trigger.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Trigger.cxx
index 35bf26575177d3d98ebe2a0a4130d31af326b62f..61db8694e7a55ebb3f8a1c656487686e2ce2e99c 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Trigger.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Trigger.cxx
@@ -237,14 +237,13 @@ void InDet::SiSpacePointsSeedMaker_Trigger::newRegion
 
     SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
-      SpacePointContainer::const_iterator spce = spacepointsPixel->end();
 
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vPixel) {
-        SpacePointContainer::const_iterator  w =  spacepointsPixel->indexFind(l);
-        if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+        auto w =  spacepointsPixel->indexFindPtr(l);
+        if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
           float r = sp->r();
           if (r<0. || r>=m_r_rmax) continue;
           InDet::SiSpacePointForSeed* sps = newSpacePoint(data, sp);
@@ -265,14 +264,13 @@ void InDet::SiSpacePointsSeedMaker_Trigger::newRegion
 
     SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
-      SpacePointContainer::const_iterator spce = spacepointsSCT->end();
 
       // Loop through all trigger collections
       //
       for (const IdentifierHash& l: vSCT) {
-        SpacePointContainer::const_iterator w = spacepointsSCT->indexFind(l);
-        if (w==spce) continue;
-        for (const Trk::SpacePoint* sp: **w) {
+        auto w = spacepointsSCT->indexFindPtr(l);
+        if (w==nullptr) continue;
+        for (const Trk::SpacePoint* sp: *w) {
           float r = sp->r();
           if (r<0. || r>=m_r_rmax) continue;
           InDet::SiSpacePointForSeed* sps = newSpacePoint(data, sp);
diff --git a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_ATLxk.cxx b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_ATLxk.cxx
index 22fa30885a8d473018cd7a97e2830ee645798ac5..1559bbc9f07147a35d861eb2bc4763c00c8dfd45 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_ATLxk.cxx
+++ b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_ATLxk.cxx
@@ -273,11 +273,11 @@ InDet::TRT_TrackSegmentsMaker_ATLxk::newRegion
   int n = 0;
   for(; d!=de; ++d) {
 
-    InDet::TRT_DriftCircleContainer::const_iterator w = trtcontainer->indexFind((*d));
+    auto w = trtcontainer->indexFindPtr((*d));
 
-    if(w!=we) {
+    if(w!=nullptr) {
 
-      Identifier ID = (*w)->identify();
+      Identifier ID = w->identify();
       int be = m_trtid->barrel_ec     (ID);
       int lw = m_trtid->layer_or_wheel(ID);
       int sl = m_trtid->straw_layer   (ID);
@@ -289,7 +289,7 @@ InDet::TRT_TrackSegmentsMaker_ATLxk::newRegion
       unsigned int ad  = 1000*b+l;
 
       InDet::TRT_DriftCircleCollection::const_iterator 
-	c  = (*w)->begin(), ce = (*w)->end();
+	c  = w->begin(), ce = w->end();
 
       for(; c!=ce; ++c) {
 
diff --git a/InnerDetector/InDetSimUtils/TRT_TR_Process/CMakeLists.txt b/InnerDetector/InDetSimUtils/TRT_TR_Process/CMakeLists.txt
index e9bfd7aa1677290042a7b43c627d23259b75aae8..1bd1d7f7eb4f8bc560361b990049155473cdb8d0 100644
--- a/InnerDetector/InDetSimUtils/TRT_TR_Process/CMakeLists.txt
+++ b/InnerDetector/InDetSimUtils/TRT_TR_Process/CMakeLists.txt
@@ -11,6 +11,7 @@ atlas_depends_on_subdirs( PUBLIC
                           PRIVATE
                           Control/AthenaBaseComps
                           Control/AthenaKernel
+                          Control/CxxUtils
                           Control/StoreGate
                           DetectorDescription/GeoModel/GeoModelInterfaces
                           DetectorDescription/IdDictDetDescr
@@ -29,7 +30,7 @@ atlas_add_component( TRT_TR_Process
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${GEANT4_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${Boost_LIBRARIES} ${XERCESC_LIBRARIES} ${GEANT4_LIBRARIES} ${CLHEP_LIBRARIES} GaudiKernel AthenaBaseComps AthenaKernel StoreGateLib SGtests IdDictDetDescr G4AtlasInterfaces GeoMaterial2G4 GeoModelInterfaces PathResolver )
+                     LINK_LIBRARIES ${Boost_LIBRARIES} ${XERCESC_LIBRARIES} ${GEANT4_LIBRARIES} ${CLHEP_LIBRARIES} GaudiKernel AthenaBaseComps AthenaKernel CxxUtils StoreGateLib SGtests IdDictDetDescr G4AtlasInterfaces GeoMaterial2G4 GeoModelInterfaces PathResolver )
 
 # Install files from the package:
 atlas_install_python_modules( python/*.py )
diff --git a/InnerDetector/InDetSimUtils/TRT_TR_Process/src/TRRegionXMLHandler.h b/InnerDetector/InDetSimUtils/TRT_TR_Process/src/TRRegionXMLHandler.h
index 16ef0967c6000650f4789161ff3f445c70e2494b..49e31cc5944baaf2a7369514a837033d5ede8692 100644
--- a/InnerDetector/InDetSimUtils/TRT_TR_Process/src/TRRegionXMLHandler.h
+++ b/InnerDetector/InDetSimUtils/TRT_TR_Process/src/TRRegionXMLHandler.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRREGIONXMLHANDLER_H
@@ -8,6 +8,7 @@
 #include <string>
 #include "StoreGate/StoreGateSvc.h"
 #include "AthenaKernel/MsgStreamMember.h"
+#include "CxxUtils/checker_macros.h"
 
 class TRTTransitionRadiation;
 
@@ -22,7 +23,7 @@ private:
   TRTTransitionRadiation * m_theProcess;
   StoreGateSvc* m_storeGate;
   bool m_initialLayoutIdDict;
-  mutable Athena::MsgStreamMember m_msg;
+  mutable Athena::MsgStreamMember m_msg ATLAS_THREAD_SAFE;
 };
 
 #endif
diff --git a/InnerDetector/InDetSimUtils/TRT_TR_Process/src/TRTRadiatorParameters.h b/InnerDetector/InDetSimUtils/TRT_TR_Process/src/TRTRadiatorParameters.h
index c571ce7542f04ed0b6663b67e2ef5dd574abe284..03d964267cbf20279bed227573a6b01635fbcf31 100644
--- a/InnerDetector/InDetSimUtils/TRT_TR_Process/src/TRTRadiatorParameters.h
+++ b/InnerDetector/InDetSimUtils/TRT_TR_Process/src/TRTRadiatorParameters.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRTRADIATORPARAMETERS_H
@@ -20,7 +20,7 @@ public:
     m_GasThickness(dGas),
     m_BEflg(beflag) {}
 
-  G4LogicalVolume * GetLogicalVolume() const { return m_aLogicalVolume; }
+  const G4LogicalVolume * GetLogicalVolume() const { return m_aLogicalVolume; }
   G4double          GetFoilThickness() const { return m_FoilThickness; }
   G4double          GetGasThickness()  const { return m_GasThickness; }
   BEflag            GetBEflag()        const { return m_BEflg; }
diff --git a/InnerDetector/InDetSimUtils/TRT_TR_Process/src/TRTTransitionRadiation.h b/InnerDetector/InDetSimUtils/TRT_TR_Process/src/TRTTransitionRadiation.h
index 18c17bb7e841e34f0bc54df5c92fc729ab366b9e..96735c7c06565a852bc28f6c461f4cf57d160f41 100644
--- a/InnerDetector/InDetSimUtils/TRT_TR_Process/src/TRTTransitionRadiation.h
+++ b/InnerDetector/InDetSimUtils/TRT_TR_Process/src/TRTTransitionRadiation.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRTTRANSITIONRADIATION_H
@@ -14,9 +14,11 @@
 #include "G4Step.hh"
 #include "G4Track.hh"
 
+#include "AthenaKernel/MsgStreamMember.h"
+#include "CxxUtils/checker_macros.h"
+
 #include <vector>
 #include <iostream>
-#include "AthenaKernel/MsgStreamMember.h"
 
 //using namespace std;
 
@@ -106,7 +108,7 @@ private:
   G4double* m_sigmaGas;
   G4double* m_sigmaFoil;
 
-  mutable Athena::MsgStreamMember m_msg;
+  mutable Athena::MsgStreamMember m_msg ATLAS_THREAD_SAFE;
 
 };
 
diff --git a/InnerDetector/InDetTrigRecAlgs/InDetTrigParticleCreation/src/TrigParticleCreator.cxx b/InnerDetector/InDetTrigRecAlgs/InDetTrigParticleCreation/src/TrigParticleCreator.cxx
index cd171e94eb0f4fdb297ca268b42e58c6c2945c59..41d54cb5daabbbba0b5f1c0000013179d2617e27 100755
--- a/InnerDetector/InDetTrigRecAlgs/InDetTrigParticleCreation/src/TrigParticleCreator.cxx
+++ b/InnerDetector/InDetTrigRecAlgs/InDetTrigParticleCreation/src/TrigParticleCreator.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "GaudiKernel/ITHistSvc.h"
@@ -14,7 +14,6 @@
 #include "Particle/TrackParticleContainer.h"
 #include "TrkToolInterfaces/IPRD_AssociationTool.h"
 #include "TrigSteeringEvent/TrigRoiDescriptor.h"
-#include "IRegionSelector/IRegSelSvc.h"
 #include "TrkTrackSummary/TrackSummary.h"
 
 #include <cmath>
diff --git a/InnerDetector/InDetTrigRecAlgs/InDetTrigParticleCreation/src/TrigTrackingxAODCnv.cxx b/InnerDetector/InDetTrigRecAlgs/InDetTrigParticleCreation/src/TrigTrackingxAODCnv.cxx
index 626fd69222d4c4268f039c136961926128c652bd..b9723a7c846e8a43775f2d146a9fff8f2c7a12e9 100644
--- a/InnerDetector/InDetTrigRecAlgs/InDetTrigParticleCreation/src/TrigTrackingxAODCnv.cxx
+++ b/InnerDetector/InDetTrigRecAlgs/InDetTrigParticleCreation/src/TrigTrackingxAODCnv.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "GaudiKernel/ITHistSvc.h"
@@ -17,7 +17,6 @@
 #include "Particle/TrackParticleContainer.h"
 #include "TrkToolInterfaces/IPRD_AssociationTool.h"
 #include "TrigSteeringEvent/TrigRoiDescriptor.h"
-#include "IRegionSelector/IRegSelSvc.h"
 #include "TrkTrackSummary/TrackSummary.h"
 
 #include "Identifier/Identifier.h"
diff --git a/InnerDetector/InDetTrigRecAlgs/InDetTrigVxSecondary/src/TrigVxSecondary.cxx b/InnerDetector/InDetTrigRecAlgs/InDetTrigVxSecondary/src/TrigVxSecondary.cxx
index 5763e49b3a38f801345d5d538f70006f57decdd0..3770590294e23e7e7a7c8a8be1296e27510eaf1e 100644
--- a/InnerDetector/InDetTrigRecAlgs/InDetTrigVxSecondary/src/TrigVxSecondary.cxx
+++ b/InnerDetector/InDetTrigRecAlgs/InDetTrigVxSecondary/src/TrigVxSecondary.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "InDetTrigVxSecondary/TrigVxSecondary.h"
@@ -11,7 +11,6 @@
 #include "InDetBeamSpotService/IBeamCondSvc.h"
 #include "TrigInDetEvent/TrigVertexCollection.h"
 #include "TrigSteeringEvent/TrigRoiDescriptor.h"
-#include "IRegionSelector/IRegSelSvc.h"
 #include <sstream>
 #include <TLorentzVector.h>
 #include "xAODBase/IParticle.h"
diff --git a/InnerDetector/InDetTrigRecAlgs/InDetTrigVxSecondary/src/TrigVxSecondaryCombo.cxx b/InnerDetector/InDetTrigRecAlgs/InDetTrigVxSecondary/src/TrigVxSecondaryCombo.cxx
index 8d406973cc6c4c04e0a990f521a4cc4ef5e15ffb..a5216ec2559c0aa1a096762b06c3321e4b8ebc22 100644
--- a/InnerDetector/InDetTrigRecAlgs/InDetTrigVxSecondary/src/TrigVxSecondaryCombo.cxx
+++ b/InnerDetector/InDetTrigRecAlgs/InDetTrigVxSecondary/src/TrigVxSecondaryCombo.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "InDetTrigVxSecondary/TrigVxSecondaryCombo.h"
@@ -12,7 +12,6 @@
 #include "InDetBeamSpotService/IBeamCondSvc.h"
 #include "TrigInDetEvent/TrigVertexCollection.h"
 #include "TrigSteeringEvent/TrigRoiDescriptor.h"
-#include "IRegionSelector/IRegSelSvc.h"
 #include <sstream>
 #include <TLorentzVector.h>
 #include "xAODBase/IParticle.h"
diff --git a/InnerDetector/InDetValidation/InDetPhysValMonitoring/python/InDetPhysValMonitoringTool.py b/InnerDetector/InDetValidation/InDetPhysValMonitoring/python/InDetPhysValMonitoringTool.py
index aba39091c3fe345817fd45747918f56ff27b352d..d118812ac402994bfec581b8a6c4ec40f9bd8b60 100644
--- a/InnerDetector/InDetValidation/InDetPhysValMonitoring/python/InDetPhysValMonitoringTool.py
+++ b/InnerDetector/InDetValidation/InDetPhysValMonitoring/python/InDetPhysValMonitoringTool.py
@@ -8,7 +8,7 @@ import InDetPhysValMonitoring.InDetPhysValMonitoringConf
 
 def removePhysValExample() :
    print ('DEBUG no AntiKt4EMTopoJets in input file.')
-   from InDetPhysValDecoration import findMonMan
+   from InDetPhysValMonitoring.InDetPhysValDecoration import findMonMan
    mon_index = findMonMan()
    if mon_index is not None :
      import re
diff --git a/InnerDetector/InDetValidation/InDetPhysValMonitoring/src/DummyTrackSlimmingTool.cxx b/InnerDetector/InDetValidation/InDetPhysValMonitoring/src/DummyTrackSlimmingTool.cxx
index 002c3d8a98afc988ff7c4b750e13255b08652409..7b925ee01d549aec0021df431824def3b9dad6ce 100644
--- a/InnerDetector/InDetValidation/InDetPhysValMonitoring/src/DummyTrackSlimmingTool.cxx
+++ b/InnerDetector/InDetValidation/InDetPhysValMonitoring/src/DummyTrackSlimmingTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "DummyTrackSlimmingTool.h"
@@ -26,4 +26,10 @@ DummyTrackSlimmingTool::slimCopy(const Trk::Track& track) const{
   return std::make_unique<Trk::Track>(track);
 }
 
+void
+DummyTrackSlimmingTool::slimTrack(Trk::Track&) const{
+}
+
+
+
 
diff --git a/InnerDetector/InDetValidation/InDetPhysValMonitoring/src/DummyTrackSlimmingTool.h b/InnerDetector/InDetValidation/InDetPhysValMonitoring/src/DummyTrackSlimmingTool.h
index d750ab9f90d713b9156b18f4e566a699675d61ae..de43273aec9d94b2face80c093098a58e3bcfb2f 100644
--- a/InnerDetector/InDetValidation/InDetPhysValMonitoring/src/DummyTrackSlimmingTool.h
+++ b/InnerDetector/InDetValidation/InDetPhysValMonitoring/src/DummyTrackSlimmingTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 /* Dear emacs, this is -*-c++-*- */
@@ -37,6 +37,7 @@ public:
    */
   virtual Trk::Track* slim(const Trk::Track& track) const override;
   virtual std::unique_ptr<Trk::Track> slimCopy(const Trk::Track& track) const override;
+  virtual void slimTrack(Trk::Track&) const override;
 
 private:
 };
diff --git a/LArCalorimeter/LArBadChannelTool/LArBadChannelTool/LArBadChannelCondAlg.h b/LArCalorimeter/LArBadChannelTool/LArBadChannelTool/LArBadChannelCondAlg.h
index 41059798aa0c99f2e4395666510e26569dd48d77..4cd9956e9fae4f793e311d9b8e199c409462de1c 100644
--- a/LArCalorimeter/LArBadChannelTool/LArBadChannelTool/LArBadChannelCondAlg.h
+++ b/LArCalorimeter/LArBadChannelTool/LArBadChannelTool/LArBadChannelCondAlg.h
@@ -20,11 +20,11 @@ class LArBadChannelCondAlg: public AthAlgorithm {
   //Delegate to base-class ctor
   using AthAlgorithm::AthAlgorithm;
 
-  ~LArBadChannelCondAlg()=default;
+  virtual ~LArBadChannelCondAlg()=default;
 
-  StatusCode initialize() override;
-  StatusCode execute() override;
-  StatusCode finalize() {return StatusCode::SUCCESS;}
+  virtual StatusCode initialize() override;
+  virtual StatusCode execute() override;
+  virtual StatusCode finalize() override {return StatusCode::SUCCESS;}
 
  private:
   SG::ReadCondHandleKey<CondAttrListCollection> m_BCInputKey{this,"ReadKey","/LAR/BadChannelsOfl/BadChannels",
diff --git a/LArCalorimeter/LArBadChannelTool/LArBadChannelTool/LArBadFebCondAlg.h b/LArCalorimeter/LArBadChannelTool/LArBadChannelTool/LArBadFebCondAlg.h
index 17f82e86b2792305bf5dd4f8c14da1724281bb98..1f46d844dc07b1226d51dd611c7d46e41979c753 100644
--- a/LArCalorimeter/LArBadChannelTool/LArBadChannelTool/LArBadFebCondAlg.h
+++ b/LArCalorimeter/LArBadChannelTool/LArBadChannelTool/LArBadFebCondAlg.h
@@ -1,7 +1,7 @@
 //Dear emacs, this is -*- c++ -*-
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef LARBADFEBCONDALG_H
@@ -18,11 +18,11 @@ class LArBadFebCondAlg: public AthAlgorithm {
  public:
   //Delegate to base-class ctor
   using AthAlgorithm::AthAlgorithm;
-  ~LArBadFebCondAlg()=default;
+  virtual ~LArBadFebCondAlg()=default;
 
-  StatusCode initialize() override;
-  StatusCode execute() override;
-  StatusCode finalize() {return StatusCode::SUCCESS;}
+  virtual StatusCode initialize() override;
+  virtual StatusCode execute() override;
+  virtual StatusCode finalize() override {return StatusCode::SUCCESS;}
 
  private:
   SG::ReadCondHandleKey<AthenaAttributeList> m_BCInputKey{this,"ReadKey","/LAR/BadFebsOfl/BadFebs",
diff --git a/LArCalorimeter/LArCabling/LArCabling/LArCablingDict.h b/LArCalorimeter/LArCabling/LArCabling/LArCablingDict.h
index 337d916b84aa7513f1ecc864cd8d771c603dc8a9..1fa52e9482f3860eb15e06e7f1aae362d241e21f 100644
--- a/LArCalorimeter/LArCabling/LArCabling/LArCablingDict.h
+++ b/LArCalorimeter/LArCabling/LArCabling/LArCablingDict.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 /**
@@ -15,5 +15,6 @@
 # define LARCABLING_LARCABLINGDICT_H
 
 #include "LArCabling/LArCablingLegacyService.h"
+#include "LArCabling/LArOnOffIdMapping.h"
 
 #endif // LARCABLING_LARCABLINGDICT_H
diff --git a/LArCalorimeter/LArCabling/LArCabling/selection.xml b/LArCalorimeter/LArCabling/LArCabling/selection.xml
index bb1f63778fcc3aba16631b5b768cdec94c605a78..dc60cf54e10dfd562d6e7b27b683322ade94946b 100755
--- a/LArCalorimeter/LArCabling/LArCabling/selection.xml
+++ b/LArCalorimeter/LArCabling/LArCabling/selection.xml
@@ -2,6 +2,8 @@
 
   <class name="LArCablingLegacyService" />
   <class name="LArCablingBase" />
+  <class name="LArOnOffIdMapping" />
+  <class name="CondCont<LArOnOffIdMapping>" />
 
 </lcgdict>
 
diff --git a/LArCalorimeter/LArCafJobs/LArCafJobs/LArReadCells.h b/LArCalorimeter/LArCafJobs/LArCafJobs/LArReadCells.h
index f1dfb7ee16e208e44d3678215a4b962fab0d832f..da9eece21c0784ce178707cbb4bc7f3b60114656 100644
--- a/LArCalorimeter/LArCafJobs/LArCafJobs/LArReadCells.h
+++ b/LArCalorimeter/LArCafJobs/LArCafJobs/LArReadCells.h
@@ -41,16 +41,16 @@ class LArReadCells: public ::AthAlgorithm {
    int m_bcid; 
    int m_error;
    int m_ncells;
-   float m_ECell[250000];
-   float m_TCell[250000];
-   float m_EtaCell[250000];
-   float m_PhiCell[250000];
-   int   m_LayerCell[250000];
-   int   m_ProvCell[250000];
-   int   m_QuaCell[250000];
-   int   m_GainCell[250000];
-   int   m_HwidCell[250000];
-   int   m_ADC[250000][32];
+   std::vector<float> m_ECell     { 250000 };
+   std::vector<float> m_TCell     { 250000 };
+   std::vector<float> m_EtaCell   { 250000 };
+   std::vector<float> m_PhiCell   { 250000 };
+   std::vector<int>   m_LayerCell { 250000 };
+   std::vector<int>   m_ProvCell  { 250000 };
+   std::vector<int>   m_QuaCell   { 250000 };
+   std::vector<int>   m_GainCell  { 250000 };
+   std::vector<int>   m_HwidCell  { 250000 };
+   std::vector<int[32]> m_ADC     { 250000 };
 
     SG::ReadCondHandleKey<LArOnOffIdMapping> m_cablingKey{this,"CablingKey","LArOnOffIdMap","SG Key of LArOnOffIdMapping object"};
     SG::ReadCondHandleKey<ILArPedestal> m_pedestalKey{this,"PedestalKey","LArPedestal","SG Key of Pedestal conditions object"};
diff --git a/LArCalorimeter/LArCafJobs/src/LArReadCells.cxx b/LArCalorimeter/LArCafJobs/src/LArReadCells.cxx
index 2a3f4f35c7eff7a7c696467794dd0f45980fa7a4..fdd5ab522719956a8bfaa572f9bdf619f6d1e888 100644
--- a/LArCalorimeter/LArCafJobs/src/LArReadCells.cxx
+++ b/LArCalorimeter/LArCafJobs/src/LArReadCells.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2028 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "LArCafJobs/LArReadCells.h"
@@ -44,16 +44,16 @@ StatusCode LArReadCells::initialize() {
   m_tree->Branch("BCID",&m_bcid,"BCID/I");
   m_tree->Branch("LArError",&m_error,"LArError/I");
   m_tree->Branch("ncells",&m_ncells,"ncells/I");
-  m_tree->Branch("ECell",m_ECell,"eCell[ncells]/F");
-  m_tree->Branch("TCell",m_TCell,"tCell[ncells]/F");
-  m_tree->Branch("EtaCell",m_EtaCell,"etaCell[ncells]/F");
-  m_tree->Branch("PhiCell",m_PhiCell,"phiCell[ncells]/F");
-  m_tree->Branch("LayerCell",m_LayerCell,"layerCell[ncells]/I");
-  m_tree->Branch("ProvCell", m_ProvCell,"provCell[ncells]/I");
-  m_tree->Branch("QuaCell", m_QuaCell,"quaCell[ncells]/I");
-  m_tree->Branch("GainCell", m_GainCell,"gainCell[ncells]/I");
-  m_tree->Branch("HwidCell", m_HwidCell,"hwidCell[ncells]/I");
-  m_tree->Branch("ADC",m_ADC,"ADC[ncells][32]/I");
+  m_tree->Branch("ECell",m_ECell.data(),"eCell[ncells]/F");
+  m_tree->Branch("TCell",m_TCell.data(),"tCell[ncells]/F");
+  m_tree->Branch("EtaCell",m_EtaCell.data(),"etaCell[ncells]/F");
+  m_tree->Branch("PhiCell",m_PhiCell.data(),"phiCell[ncells]/F");
+  m_tree->Branch("LayerCell",m_LayerCell.data(),"layerCell[ncells]/I");
+  m_tree->Branch("ProvCell", m_ProvCell.data(),"provCell[ncells]/I");
+  m_tree->Branch("QuaCell", m_QuaCell.data(),"quaCell[ncells]/I");
+  m_tree->Branch("GainCell", m_GainCell.data(),"gainCell[ncells]/I");
+  m_tree->Branch("HwidCell", m_HwidCell.data(),"hwidCell[ncells]/I");
+  m_tree->Branch("ADC",m_ADC.data(),"ADC[ncells][32]/I");
 
   ATH_CHECK(detStore()->retrieve(m_caloIdMgr));
   m_calo_id      = m_caloIdMgr->getCaloCell_ID();
diff --git a/LArCalorimeter/LArClusterRec/share/LArCluster_jobOptions.py b/LArCalorimeter/LArClusterRec/share/LArCluster_jobOptions.py
index f0ce8954e4d4b45380650b745e2b4e6a05a223a1..4fc7ef9a91ca54d8e8c6d769e2ba2fc933a550c1 100755
--- a/LArCalorimeter/LArClusterRec/share/LArCluster_jobOptions.py
+++ b/LArCalorimeter/LArClusterRec/share/LArCluster_jobOptions.py
@@ -10,4 +10,5 @@ from LArClusterRec.LArClusterSwGetters import *
 LArClusterSwEle35Getter()
 
 # 7x11 clusters with no corrections.
-LArClusterSw711GetterNocorr()
+# not built by default
+#LArClusterSw711GetterNocorr()
diff --git a/LArCalorimeter/LArG4/LArG4ShowerLibSvc/CMakeLists.txt b/LArCalorimeter/LArG4/LArG4ShowerLibSvc/CMakeLists.txt
index d24e7c490fbb880ba0293f614998583dfea54b1a..ef9f5753b1f8211ce8d92600042f6834928ca103 100644
--- a/LArCalorimeter/LArG4/LArG4ShowerLibSvc/CMakeLists.txt
+++ b/LArCalorimeter/LArG4/LArG4ShowerLibSvc/CMakeLists.txt
@@ -21,15 +21,20 @@ find_package( Geant4 )
 find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
 find_package( XercesC )
 
+atlas_add_library( LArG4ShowerLibSvcLib
+                   LArG4ShowerLibSvc/*.h
+                   INTERFACE
+                   PUBLIC_HEADERS LArG4ShowerLibSvc
+                   LINK_LIBRARIES GaudiKernel LArG4Code AthenaBaseComps )
+
 # Component(s) in the package:
 atlas_add_component( LArG4ShowerLibSvc
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${GEANT4_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${XERCESC_LIBRARIES} ${GEANT4_LIBRARIES} ${CLHEP_LIBRARIES} AthenaBaseComps GaudiKernel LArG4Code AthenaKernel LArG4ShowerLib PathResolver )
+                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${XERCESC_LIBRARIES} ${GEANT4_LIBRARIES} ${CLHEP_LIBRARIES}  LArG4ShowerLibSvcLib AthenaKernel LArG4ShowerLib PathResolver )
 
 # Install files from the package:
-atlas_install_headers( LArG4ShowerLibSvc )
 atlas_install_python_modules( python/*.py )
 atlas_install_scripts( share/*.py )
 
diff --git a/LArCalorimeter/LArMonitoring/python/LArCoverageAlg.py b/LArCalorimeter/LArMonitoring/python/LArCoverageAlg.py
index e5451342d76b36cc31115fcd8ea6512137c35126..74fbb3a77a185498b4ece6bf2e1e43fd312170ef 100644
--- a/LArCalorimeter/LArMonitoring/python/LArCoverageAlg.py
+++ b/LArCalorimeter/LArMonitoring/python/LArCoverageAlg.py
@@ -11,14 +11,8 @@ def LArCoverageConfigOld(inputFlags):
     from AthenaMonitoring import AthMonitorCfgHelperOld
     from LArMonitoring.LArMonitoringConf import LArCoverageAlg
 
-    from LArBadChannelTool.LArBadChannelToolConf import LArBadChannelMasker
-    theLArRCBMasker=LArBadChannelMasker("BadLArRawChannelMask")
-    theLArRCBMasker.DoMasking=True
-    theLArRCBMasker.ProblemsToMask=["deadReadout","deadPhys","highNoiseHG","highNoiseMG","highNoiseLG"]
-
     helper = AthMonitorCfgHelperOld(inputFlags, 'LArCoverageAlgOldCfg')
     LArCoverageConfigCore(helper,LArCoverageAlg,inputFlags)
-    helper.monSeq.LArCoverageAlg.LArBadChannelMask=theLArRCBMasker
 
     return helper.result()
 
@@ -33,14 +27,6 @@ def LArCoverageConfig(inputFlags):
     from AthenaConfiguration.ComponentFactory import CompFactory
     LArCoverageConfigCore(helper, CompFactory.LArCoverageAlg,inputFlags)
 
-    # adding BadChan masker private tool
-    from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
-    cfg=ComponentAccumulator()
-    from LArBadChannelTool.LArBadChannelConfig import LArBadChannelMaskerCfg#,LArBadChannelCfg
-    acc= LArBadChannelMaskerCfg(inputFlags,problemsToMask=["highNoiseHG","highNoiseMG","highNoiseLG","deadReadout","deadPhys"],ToolName="BadLArRawChannelMask")
-    CompFactory.LArCoverageAlg.LArBadChannelMask=acc.popPrivateTools()
-    cfg.merge(acc)
-
     cfg.merge(helper.result())
     return cfg
 
@@ -48,6 +34,21 @@ def LArCoverageConfigCore(helper, algoinstance,inputFlags):
 
     larCoverageAlg = helper.addAlgorithm(algoinstance,'LArCoverageAlg')
 
+    # adding BadChan masker private tool
+    from AthenaConfiguration.ComponentFactory import isRun3Cfg
+    if isRun3Cfg():
+       from LArBadChannelTool.LArBadChannelConfig import LArBadChannelMaskerCfg#,LArBadChannelCfg
+       acc= LArBadChannelMaskerCfg(inputFlags,problemsToMask=["highNoiseHG","highNoiseMG","highNoiseLG","deadReadout","deadPhys"],ToolName="BadLArRawChannelMask")
+       larCoverageAlg.LArBadChannelMask=acc.popPrivateTools()
+       helper.resobj.merge(acc)
+    else:   
+       from LArBadChannelTool.LArBadChannelToolConf import LArBadChannelMasker
+       theLArRCBMasker=LArBadChannelMasker("BadLArRawChannelMask")
+       theLArRCBMasker.DoMasking=True
+       theLArRCBMasker.ProblemsToMask=["deadReadout","deadPhys","highNoiseHG","highNoiseMG","highNoiseLG"]
+       larCoverageAlg.LArBadChannelMask=theLArRCBMasker
+
+
     from LArMonitoring.GlobalVariables import lArDQGlobals
 
     #define the group names here, as you'll use them multiple times
diff --git a/LArCalorimeter/LArMonitoring/python/LArHVDBConfig.py b/LArCalorimeter/LArMonitoring/python/LArHVDBConfig.py
index a35f1155c2f70328a306878c3cceb76fdd94ed47..e34f4a3f6ac61acd0a8fb2475999e9967ce55215 100644
--- a/LArCalorimeter/LArMonitoring/python/LArHVDBConfig.py
+++ b/LArCalorimeter/LArMonitoring/python/LArHVDBConfig.py
@@ -49,8 +49,8 @@ if __name__=="__main__":
     ConfigFlags.lock()
 
     cfg=ComponentAccumulator()
-    from ByteStreamCnvSvc.ByteStreamConfig import TrigBSReadCfg
-    cfg.merge( TrigBSReadCfg(ConfigFlags) )
+    from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
+    cfg.merge( ByteStreamReadCfg(ConfigFlags) )
 
     from LArGeoAlgsNV.LArGMConfig import LArGMCfg
     cfg.merge(LArGMCfg(ConfigFlags))
diff --git a/LArCalorimeter/LArMonitoring/python/LArRODMonAlg.py b/LArCalorimeter/LArMonitoring/python/LArRODMonAlg.py
index db9f96b31a37975617c92ebdc56c3c3024fdf978..7cafe8d3f5f45c3489497feb575cd0547f52c974 100644
--- a/LArCalorimeter/LArMonitoring/python/LArRODMonAlg.py
+++ b/LArCalorimeter/LArMonitoring/python/LArRODMonAlg.py
@@ -133,7 +133,7 @@ def LArRODMonConfigCore(helper, algoinstance,inputFlags, cellDebug=False, dspDeb
     #Infos histos (vs. LB)
     info_hist_path='Infos/'
     cut = "#delta ADC>"+str(larRODMonAlg.ADCthreshold)+" and |t_offline| < "+str(larRODMonAlg.peakTimeCut)+" ns"
-    Group.defineHistogram('LBN,partition:EErrorsPerLB',
+    Group.defineHistogram('LBN,partitionI;EErrorsPerLB',
                                   title='Nb of errors in E per LB - ' +cut+':Luminosity Block:Partition',
                                   type='TH2I',
                                   weight='numE',
@@ -142,7 +142,7 @@ def LArRODMonConfigCore(helper, algoinstance,inputFlags, cellDebug=False, dspDeb
                                   ybins=lArDQGlobals.N_Partitions, ymin=-0.5, ymax=lArDQGlobals.N_Partitions-0.5,
                                   ylabels = lArDQGlobals.Partitions
           )
-    Group.defineHistogram('LBN,partition:TErrorsPerLB',
+    Group.defineHistogram('LBN,partitionI;TErrorsPerLB',
                                   title='Nb of errors in T per LB - ' +cut+':Luminosity Block:Partition',
                                   type='TH2I',
                                   weight='numT',
@@ -151,7 +151,7 @@ def LArRODMonConfigCore(helper, algoinstance,inputFlags, cellDebug=False, dspDeb
                                   ybins=lArDQGlobals.N_Partitions, ymin=-0.5, ymax=lArDQGlobals.N_Partitions-0.5,
                                   ylabels = lArDQGlobals.Partitions
           )
-    Group.defineHistogram('LBN,partition:QErrorsPerLB',
+    Group.defineHistogram('LBN,partitionI;QErrorsPerLB',
                                   title='Nb of errors in Q per LB - ' +cut+':Luminosity Block:Partition',
                                   type='TH2I',
                                   weight='numQ',
@@ -163,22 +163,21 @@ def LArRODMonConfigCore(helper, algoinstance,inputFlags, cellDebug=False, dspDeb
 
     #DQMD histos
     dqmd_hist_path='/LAr/DSPMonitoringNewAlg/DQMD/'
-    darray = helper.addArray([lArDQGlobals.Partitions+['all']],larRODMonAlg,"RODMon")
+    darray = helper.addArray([lArDQGlobals.Partitions],larRODMonAlg,"RODMon")
     darray.defineHistogram('Ediff,Erange;DE_ranges', title='EOnline - E_offline for all ranges : E_offline - E_online (MeV) : Energy range',#'E_online - E_offline for all ranges : E_offline - E_online (MeV) : Energy range',
                            type='TH2F', path=dqmd_hist_path,
                            xbins=lArDQGlobals.DSP1Energy_Bins, xmin=lArDQGlobals.DSP1Energy_Min, xmax=lArDQGlobals.DSP1Energy_Max,
                            ybins=lArDQGlobals.DSPRanges_Bins, ymin=lArDQGlobals.DSPRanges_Min, ymax=lArDQGlobals.DSPRanges_Max,
                            ylabels=lArDQGlobals.DSPRanges 
           )
-    dqmd_hist_path='/LAr/DSPMonitoringNewAlg/DQMD/'
-    darray = helper.addArray([lArDQGlobals.Partitions+['all']],larRODMonAlg,"RODMon")
-    darray.defineHistogram('Ediff,Erange;DE_ranges', title='E_online - E_offline for all ranges : E_offline - E_online (MeV) : Energy range',
+    Group.defineHistogram('Ediff,Erange;E_ranges_all', title='E_online - E_offline for all ranges : E_offline - E_online (MeV) : Energy range',
                            type='TH2F', path=dqmd_hist_path,
                            xbins=lArDQGlobals.DSP1Energy_Bins, xmin=lArDQGlobals.DSP1Energy_Min, xmax=lArDQGlobals.DSP1Energy_Max,
                            ybins=lArDQGlobals.DSPRanges_Bins, ymin=lArDQGlobals.DSPRanges_Min, ymax=lArDQGlobals.DSPRanges_Max,
                            ylabels=lArDQGlobals.DSPRanges
           )
 
+
     #per partition, currently in one dir only
     part_hist_path='/LAr/DSPMonitoringNewAlg/perPartition/'
     darray.defineHistogram('Ediff;DE', title='E_offline - E_online:E_offline - E_online',
diff --git a/LArCalorimeter/LArMonitoring/src/LArRODMonAlg.cxx b/LArCalorimeter/LArMonitoring/src/LArRODMonAlg.cxx
index 4eb8d69477fafbf1d90e47eadc95b5c38dd1d3a3..0d6634bb15ad700d3454e83f9fd0c408cda86d66 100755
--- a/LArCalorimeter/LArMonitoring/src/LArRODMonAlg.cxx
+++ b/LArCalorimeter/LArMonitoring/src/LArRODMonAlg.cxx
@@ -146,6 +146,7 @@ StatusCode LArRODMonAlg::fillHistograms(const EventContext& ctx) const {
   auto numT = Monitored::Scalar<int>("numT",1.);
   auto gain = Monitored::Scalar<int>("gain",-1);
   auto partition = Monitored::Scalar<int>("partition",-1);
+  auto partitionI = Monitored::Scalar<int>("partitionI",-1);
   auto lb = Monitored::Scalar<int>("LBN",0);
   auto sweetc = Monitored::Scalar<float>("Sweetc",1.);
 
@@ -397,10 +398,10 @@ StatusCode LArRODMonAlg::fillHistograms(const EventContext& ctx) const {
     unsigned allErrsPartE=0;
     unsigned allErrsPartT=0;
     unsigned allErrsPartQ=0;
+    partition = p;
     for (unsigned g=0;g<3;++g) {
       
       gain = g;
-      partition = p;
       weight_e = (float)errcounters[p].errors_E[g];
       weight_q = (float)errcounters[p].errors_Q[g];
       weight_t = (float)errcounters[p].errors_T[g];
@@ -411,10 +412,11 @@ StatusCode LArRODMonAlg::fillHistograms(const EventContext& ctx) const {
       allErrsPartT+=errcounters[p].errors_T[g];
       allErrsPartQ+=errcounters[p].errors_Q[g];
     }
+    partitionI = p;
     numE = (float)allErrsPartE;
     numT = (float)allErrsPartT;
     numQ = (float)allErrsPartQ;
-    fill(m_MonGroupName, lb, partition, numE, numT, numQ); 
+    fill(m_MonGroupName, lb, partitionI, numE, numT, numQ); 
   }
 
   for(int str = 0; str < nStreams + 1; str++) {
diff --git a/LArCalorimeter/LArRecUtils/src/LArSymConditionsAlg.h b/LArCalorimeter/LArRecUtils/src/LArSymConditionsAlg.h
index 8d5881192ed66ad3c53bfbcb3d1898df48c8c7d8..e864ee1b89900a4bdaa6faf0e1bec0713d3cd93e 100644
--- a/LArCalorimeter/LArRecUtils/src/LArSymConditionsAlg.h
+++ b/LArCalorimeter/LArRecUtils/src/LArSymConditionsAlg.h
@@ -21,11 +21,11 @@ class LArSymConditionsAlg: public AthAlgorithm {
   //delegate to base-class ctor
   using AthAlgorithm::AthAlgorithm;
 
-  ~LArSymConditionsAlg()=default;
+  virtual ~LArSymConditionsAlg()=default;
 
-  StatusCode initialize() override;
-  StatusCode execute() override;
-  StatusCode finalize() {return StatusCode::SUCCESS;}
+  virtual StatusCode initialize() override;
+  virtual StatusCode execute() override;
+  virtual StatusCode finalize() override {return StatusCode::SUCCESS;}
 
  private:
   SG::ReadCondHandleKey<LArMCSym> m_mcSymKey{this,"LArMCSym","LArMCSym","Key of the LArMCSym symmetry table CDO"};
diff --git a/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldSvc.h b/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldSvc.h
index 529398741971db19801ce924c1aca473573ffcc7..15a5e27d213e78880aa0f3adc08a4ef38892ac0c 100644
--- a/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldSvc.h
+++ b/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldSvc.h
@@ -41,27 +41,27 @@ namespace MagField {
       @author Elmar.Ritsch -at- cern.ch
     */
 
-  class AtlasFieldSvc : public extends<AthService, IMagFieldSvc, IIncidentListener> {
+  class ATLAS_NOT_THREAD_SAFE AtlasFieldSvc : public extends<AthService, IMagFieldSvc, IIncidentListener> {
     public:
 
       //** Constructor with parameters */
-      AtlasFieldSvc( const std::string& name, ISvcLocator* pSvcLocator )  ATLAS_CTORDTOR_NOT_THREAD_SAFE;
+      AtlasFieldSvc( const std::string& name, ISvcLocator* pSvcLocator );
 
       /** Destructor */
-      virtual ~AtlasFieldSvc()  ATLAS_CTORDTOR_NOT_THREAD_SAFE ;
+      virtual ~AtlasFieldSvc();
 
       /** Athena algorithm's interface methods */
-      virtual StatusCode  initialize  ATLAS_NOT_THREAD_SAFE () override;
+      virtual StatusCode  initialize() override;
       virtual StatusCode  finalize() override;
 
       /** Read **/
       virtual void handle(const Incident& runIncident) override;
 
       /** Call back for possible magnet current update **/
-      StatusCode updateCurrent ATLAS_NOT_THREAD_SAFE (IOVSVC_CALLBACK_ARGS);
+      StatusCode updateCurrent(IOVSVC_CALLBACK_ARGS);
 
       /** Call back for possible magnet filename update **/
-      StatusCode updateMapFilenames ATLAS_NOT_THREAD_SAFE (IOVSVC_CALLBACK_ARGS);
+      StatusCode updateMapFilenames(IOVSVC_CALLBACK_ARGS);
 
       /** get B field value at given position */
       /** xyz[3] is in mm, bxyz[3] is in kT */
diff --git a/MagneticField/MagFieldServices/src/AtlasFieldCacheCondAlg.cxx b/MagneticField/MagFieldServices/src/AtlasFieldCacheCondAlg.cxx
index 932fd88b12a263c7fadba9c93578ef280b0e840a..f246e474820c2990639aaa6bb2bc3a61644f6c21 100644
--- a/MagneticField/MagFieldServices/src/AtlasFieldCacheCondAlg.cxx
+++ b/MagneticField/MagFieldServices/src/AtlasFieldCacheCondAlg.cxx
@@ -40,7 +40,7 @@ MagField::AtlasFieldCacheCondAlg::initialize() {
     ATH_CHECK( m_condSvc.retrieve() );
 
     // Read Handle for the current
-    ATH_CHECK( m_currInputKey.initialize() );
+    ATH_CHECK( m_currInputKey.initialize (m_useDCS) );
 
     // Read handle for the field map cond object
     ATH_CHECK( m_mapCondObjInputKey.initialize() );
diff --git a/MagneticField/MagFieldServices/src/AtlasFieldSvc.cxx b/MagneticField/MagFieldServices/src/AtlasFieldSvc.cxx
index 91e2a91d46cbeb33557279199e364c44c4854b7f..9bb04bfd1092cd6a71a3129b8aaf49f4442808b5 100644
--- a/MagneticField/MagFieldServices/src/AtlasFieldSvc.cxx
+++ b/MagneticField/MagFieldServices/src/AtlasFieldSvc.cxx
@@ -90,7 +90,7 @@ MagField::AtlasFieldSvc::~AtlasFieldSvc()
 }
 
 /** framework methods */
-StatusCode MagField::AtlasFieldSvc::initialize ATLAS_NOT_THREAD_SAFE ( )
+StatusCode MagField::AtlasFieldSvc::initialize( )
 {
     ATH_MSG_INFO( "initialize() ..." );
 
@@ -211,7 +211,7 @@ StatusCode MagField::AtlasFieldSvc::importCurrents(AtlasFieldSvcTLS &tls)
 }
 
 /** callback for possible magnet current update **/
-StatusCode MagField::AtlasFieldSvc::updateCurrent ATLAS_NOT_THREAD_SAFE (IOVSVC_CALLBACK_ARGS)
+StatusCode MagField::AtlasFieldSvc::updateCurrent(IOVSVC_CALLBACK_ARGS)
 {
     // get magnet currents from DCS
     double solcur(0.);
@@ -304,7 +304,7 @@ StatusCode MagField::AtlasFieldSvc::updateCurrent ATLAS_NOT_THREAD_SAFE (IOVSVC_
 }
 
 /** callback for possible field map filenames update **/
-StatusCode MagField::AtlasFieldSvc::updateMapFilenames ATLAS_NOT_THREAD_SAFE (IOVSVC_CALLBACK_ARGS)
+StatusCode MagField::AtlasFieldSvc::updateMapFilenames(IOVSVC_CALLBACK_ARGS)
 {
     ATH_MSG_INFO( "reading magnetic field map filenames from COOL" );
 
diff --git a/MuonSpectrometer/MuonCablings/MuonMDT_Cabling/CMakeLists.txt b/MuonSpectrometer/MuonCablings/MuonMDT_Cabling/CMakeLists.txt
index d6f439143e0fa6dfe4b0ed0cddfba947ac57d0d7..930171f83994ce248f603551a8bf590617537ac4 100644
--- a/MuonSpectrometer/MuonCablings/MuonMDT_Cabling/CMakeLists.txt
+++ b/MuonSpectrometer/MuonCablings/MuonMDT_Cabling/CMakeLists.txt
@@ -34,6 +34,3 @@ atlas_add_component( MuonMDT_Cabling
                      src/components/*.cxx
                      LINK_LIBRARIES GaudiKernel MuonMDT_CablingLib )
 
-# Install files from the package:
-atlas_install_python_modules( python/*.py )
-
diff --git a/MuonSpectrometer/MuonCablings/MuonMDT_Cabling/python/__init__.py b/MuonSpectrometer/MuonCablings/MuonMDT_Cabling/python/__init__.py
deleted file mode 100644
index ae1ceb1157d018a36168194d12f016e5525d3802..0000000000000000000000000000000000000000
--- a/MuonSpectrometer/MuonCablings/MuonMDT_Cabling/python/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
-# template __init__.py defined in the GaudiPolicy package.
-
diff --git a/MuonSpectrometer/MuonCablings/RPCcablingInterface/CMakeLists.txt b/MuonSpectrometer/MuonCablings/RPCcablingInterface/CMakeLists.txt
index 1e0c62080b5031218a78b7e57acb2ed29d8e2fa1..91a09a6c576a858155aaf32e1740bf3c4da56f11 100644
--- a/MuonSpectrometer/MuonCablings/RPCcablingInterface/CMakeLists.txt
+++ b/MuonSpectrometer/MuonCablings/RPCcablingInterface/CMakeLists.txt
@@ -22,6 +22,3 @@ atlas_add_library( RPCcablingInterfaceLib
                    PUBLIC_HEADERS RPCcablingInterface
                    LINK_LIBRARIES AthenaKernel Identifier GaudiKernel MuonCablingTools CablingTools MuonIdHelpersLib StoreGateLib SGtests RPC_CondCablingLib)
 
-# Install files from the package:
-atlas_install_python_modules( python/__init__.py )
-
diff --git a/MuonSpectrometer/MuonCablings/RPCcablingInterface/python/__init__.py b/MuonSpectrometer/MuonCablings/RPCcablingInterface/python/__init__.py
deleted file mode 100644
index 34b61e621e792e0edf14ea5c955185179f151b6d..0000000000000000000000000000000000000000
--- a/MuonSpectrometer/MuonCablings/RPCcablingInterface/python/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
-# File: RPCcablingConfigInterface/__init__.py
-
-__version__ = '1.0.0'
-__author__  = 'alessandro.dimattia@roma1.infn.it'
-
-
-
diff --git a/MuonSpectrometer/MuonCablings/TGCcablingInterface/CMakeLists.txt b/MuonSpectrometer/MuonCablings/TGCcablingInterface/CMakeLists.txt
index 020c753db864d93752ebfd3863da8b16872a31eb..017b50b4757b3c349b2c5baf36060fce509019c6 100644
--- a/MuonSpectrometer/MuonCablings/TGCcablingInterface/CMakeLists.txt
+++ b/MuonSpectrometer/MuonCablings/TGCcablingInterface/CMakeLists.txt
@@ -17,6 +17,3 @@ atlas_add_library( TGCcablingInterfaceLib
                    PUBLIC_HEADERS TGCcablingInterface
                    LINK_LIBRARIES AthenaBaseComps AthenaKernel GaudiKernel )
 
-# Install files from the package:
-atlas_install_python_modules( python/__init__.py )
-
diff --git a/MuonSpectrometer/MuonCablings/TGCcablingInterface/python/__init__.py b/MuonSpectrometer/MuonCablings/TGCcablingInterface/python/__init__.py
deleted file mode 100755
index 282de68311cc55af31ac12e7d30f9f062f14acbb..0000000000000000000000000000000000000000
--- a/MuonSpectrometer/MuonCablings/TGCcablingInterface/python/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
-# File: TGCcablingConfigInterface/__init__.py
-
-__version__ = '1.0.0'
-__author__  = 'HisayaKurashige@cern.ch'
diff --git a/MuonSpectrometer/MuonCnv/MuonEventTPCnv/MuonEventTPCnv/MuonPrepRawData/MMPrepData_p1.h b/MuonSpectrometer/MuonCnv/MuonEventTPCnv/MuonEventTPCnv/MuonPrepRawData/MMPrepData_p1.h
index f6382d41025b08df4a146eaf362f014168509acb..9e9faa0037fd0b21fe491408893b01e90f0ad277 100644
--- a/MuonSpectrometer/MuonCnv/MuonEventTPCnv/MuonEventTPCnv/MuonPrepRawData/MMPrepData_p1.h
+++ b/MuonSpectrometer/MuonCnv/MuonEventTPCnv/MuonEventTPCnv/MuonPrepRawData/MMPrepData_p1.h
@@ -43,7 +43,7 @@ namespace Muon
 	std::vector<float>        m_stripDriftDist;
 	std::vector<Amg::MatrixX> m_stripDriftErrors;
 
-  int m_author; // contains the info about which cluster builder tool produced the PRD
+  int m_author = 0; // contains the info about which cluster builder tool produced the PRD
         
         //@}
         
diff --git a/MuonSpectrometer/MuonCnv/MuonEventTPCnv/src/MuonPrepRawData/MMPrepDataCnv_p1.cxx b/MuonSpectrometer/MuonCnv/MuonEventTPCnv/src/MuonPrepRawData/MMPrepDataCnv_p1.cxx
index 9afba6d518f4fb308b31fff05e12bb8762f61323..da3beb2151df3838d5a4d8fd3bee7cd48938b4fd 100644
--- a/MuonSpectrometer/MuonCnv/MuonEventTPCnv/src/MuonPrepRawData/MMPrepDataCnv_p1.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonEventTPCnv/src/MuonPrepRawData/MMPrepDataCnv_p1.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "MuonPrepRawData/MMPrepData.h"
@@ -58,6 +58,7 @@ persToTrans( const Muon::MMPrepData_p1 *persObj, Muon::MMPrepData *transObj,MsgS
 				transObj->identify(),
                                 transObj->detectorElement(),
                                 log);
+  transObj->setAuthor(static_cast<Muon::MMPrepData::Author>(persObj->m_author));
 }
 
 void MMPrepDataCnv_p1::
diff --git a/MuonSpectrometer/MuonCnv/MuonEventTPCnv/test/MMPrepDataCnv_p1_test.cxx b/MuonSpectrometer/MuonCnv/MuonEventTPCnv/test/MMPrepDataCnv_p1_test.cxx
index bd2f4670d611597afa73154ed4950eb780d40ef3..edd4baa0eb175f6d0e1dfb3f97ab85a8fa13900e 100644
--- a/MuonSpectrometer/MuonCnv/MuonEventTPCnv/test/MMPrepDataCnv_p1_test.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonEventTPCnv/test/MMPrepDataCnv_p1_test.cxx
@@ -1,8 +1,6 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
-
-// $Id$
 /**
  * @file MuonEventTPCnv/test/MMPrepDataCnv_p1_test.cxx
  * @author scott snyder <snyder@bnl.gov>
@@ -41,6 +39,7 @@ void compare (const Muon::MuonCluster& p1,
 void compare (const Muon::MMPrepData& p1,
               const Muon::MMPrepData& p2)
 {
+  assert (p1.author() == p2.author());
   compare (static_cast<const Muon::MuonCluster&>(p1),
            static_cast<const Muon::MuonCluster&>(p2));
   assert (p1.detectorElement() == p2.detectorElement());
@@ -80,6 +79,7 @@ void test1()
                            rdoList,
                            new Amg::MatrixX(cov),
                            nullptr);
+  trans1.setAuthor (Muon::MMPrepData::ConstraintuTPCClusterBuilder);
                           
   testit (trans1);
 }
diff --git a/MuonSpectrometer/MuonCnv/MuonEventTPCnv/test/MMPrepDataContainerCnv_p1_test.cxx b/MuonSpectrometer/MuonCnv/MuonEventTPCnv/test/MMPrepDataContainerCnv_p1_test.cxx
index 3dbbe5d65df9a8b70109d07621d565ed70a6d6a6..5f4a64b2b19eeee1880c6ccc77db6ec87171444c 100644
--- a/MuonSpectrometer/MuonCnv/MuonEventTPCnv/test/MMPrepDataContainerCnv_p1_test.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonEventTPCnv/test/MMPrepDataContainerCnv_p1_test.cxx
@@ -42,6 +42,7 @@ void compare (const Muon::MuonCluster& p1,
 void compare (const Muon::MMPrepData& p1,
               const Muon::MMPrepData& p2)
 {
+  assert (p1.author() == p2.author());
   assert (p1.identify() == p2.identify());
   compare (static_cast<const Muon::MuonCluster&>(p1),
            static_cast<const Muon::MuonCluster&>(p2));
@@ -117,6 +118,7 @@ makeclusts (const MuonGM::MuonDetectorManager& muo_dd)
          rdoList,
          new Amg::MatrixX(cov),
          muo_dd.getMMReadoutElement (clusId));
+      cl->setAuthor (Muon::MMPrepData::ProjectionClusterBuilder);
       coll->push_back (std::move (cl));
     }
     assert(cont->addCollection (coll.release(), hash));
diff --git a/MuonSpectrometer/MuonCnv/MuonSTGC_CnvTools/src/sTgcRdoToPrepDataTool.cxx b/MuonSpectrometer/MuonCnv/MuonSTGC_CnvTools/src/sTgcRdoToPrepDataTool.cxx
index 42ffd08feaec314090775c851eba1926e1ead9cb..fab1e0957ad765e5cbe24aa956723b7c2dab6061 100644
--- a/MuonSpectrometer/MuonCnv/MuonSTGC_CnvTools/src/sTgcRdoToPrepDataTool.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonSTGC_CnvTools/src/sTgcRdoToPrepDataTool.cxx
@@ -11,8 +11,8 @@
 
 
 Muon::sTgcRdoToPrepDataTool::sTgcRdoToPrepDataTool(const std::string& t,
-						   const std::string& n,
-						   const IInterface*  p )
+               const std::string& n,
+               const IInterface*  p )
   :
   AthAlgTool(t,n,p),
   sTgcRdoToPrepDataToolCore(t,n,p)
diff --git a/MuonSpectrometer/MuonCnv/MuonSTGC_CnvTools/src/sTgcRdoToPrepDataToolCore.cxx b/MuonSpectrometer/MuonCnv/MuonSTGC_CnvTools/src/sTgcRdoToPrepDataToolCore.cxx
index e653acafb4468a9bbf72340efdf6cf45f1e72a9a..110f7863e258eee52738bc740680f8401eaf0086 100644
--- a/MuonSpectrometer/MuonCnv/MuonSTGC_CnvTools/src/sTgcRdoToPrepDataToolCore.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonSTGC_CnvTools/src/sTgcRdoToPrepDataToolCore.cxx
@@ -223,6 +223,7 @@ StatusCode Muon::sTgcRdoToPrepDataToolCore::processCollection(const STGC_RawData
     // merge the eta and phi prds that fire closeby strips or wires
     std::vector<Muon::sTgcPrepData*> sTgcStripClusters;
     std::vector<Muon::sTgcPrepData*> sTgcWireClusters;
+    std::vector<Muon::sTgcPrepData*> sTgcPadClusters;
     //
     // Clusterize strips
     //
@@ -231,6 +232,9 @@ StatusCode Muon::sTgcRdoToPrepDataToolCore::processCollection(const STGC_RawData
     // Clusterize wires
     //
     ATH_CHECK(m_clusterBuilderTool->getClusters(sTgcWirePrds,sTgcWireClusters));
+    // Clusterize pads
+    //
+    ATH_CHECK(m_clusterBuilderTool->getClusters(sTgcPadPrds,sTgcPadClusters));
     //
     // Add the clusters to the event store ( do not clusterize wires for now )
     //
@@ -241,7 +245,11 @@ StatusCode Muon::sTgcRdoToPrepDataToolCore::processCollection(const STGC_RawData
     for ( auto it : sTgcWireClusters ) {
       it->setHashAndIndex(prdColl->identifyHash(), prdColl->size());
       prdColl->push_back(it);
-    } 
+    }
+    for ( auto it : sTgcPadClusters ) {
+      it->setHashAndIndex(prdColl->identifyHash(), prdColl->size());
+      prdColl->push_back(it);
+    }
   }
 
 
diff --git a/MuonSpectrometer/MuonConditions/MuonCondCabling/RPC_CondCabling/CMakeLists.txt b/MuonSpectrometer/MuonConditions/MuonCondCabling/RPC_CondCabling/CMakeLists.txt
index 06e2e03dc6fa3055aa5a2aa15fb13ea1f38417bf..ba336aad3115bff4595d51d59c0804285e2deb47 100644
--- a/MuonSpectrometer/MuonConditions/MuonCondCabling/RPC_CondCabling/CMakeLists.txt
+++ b/MuonSpectrometer/MuonConditions/MuonCondCabling/RPC_CondCabling/CMakeLists.txt
@@ -30,9 +30,6 @@ atlas_add_library( RPC_CondCablingLib
                    LINK_LIBRARIES ${CORAL_LIBRARIES} AthenaBaseComps GaudiKernel MuonCondInterface MuonCablingTools SGTools StoreGateLib SGtests AthenaPoolUtilities Identifier MuonIdHelpersLib PathResolver )
 
 atlas_add_component( RPC_CondCabling
-                     src/RPCCablingDbTool.cxx
-                     src/RPCTriggerDbTool.cxx
-                     src/RpcCablingCondAlg.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${CORAL_INCLUDE_DIRS}
                      LINK_LIBRARIES ${CORAL_LIBRARIES}  RPC_CondCablingLib)
diff --git a/MuonSpectrometer/MuonConfig/python/MuonBytestreamDecodeConfig.py b/MuonSpectrometer/MuonConfig/python/MuonBytestreamDecodeConfig.py
index ac542423ddc94bd48cc0df26a2f733ea7dfa7135..8f58c38694b5270dead7455c2c90f23628ec5902 100644
--- a/MuonSpectrometer/MuonConfig/python/MuonBytestreamDecodeConfig.py
+++ b/MuonSpectrometer/MuonConfig/python/MuonBytestreamDecodeConfig.py
@@ -228,8 +228,8 @@ if __name__=="__main__":
     cfg=ComponentAccumulator()
     
     # Seem to need this to read BS properly
-    from ByteStreamCnvSvc.ByteStreamConfig import TrigBSReadCfg
-    cfg.merge(TrigBSReadCfg(ConfigFlags ))
+    from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
+    cfg.merge(ByteStreamReadCfg(ConfigFlags ))
 
     # Schedule Rpc data decoding
     rpcdecodingAcc = RpcBytestreamDecodeCfg( ConfigFlags ) 
diff --git a/MuonSpectrometer/MuonConfig/python/MuonRdoDecodeConfig.py b/MuonSpectrometer/MuonConfig/python/MuonRdoDecodeConfig.py
index 0932823f79f26b3be6ddd1113bebc8ca8e263511..1175a9040f0ef0b834b22ad86920a119d6000a4c 100644
--- a/MuonSpectrometer/MuonConfig/python/MuonRdoDecodeConfig.py
+++ b/MuonSpectrometer/MuonConfig/python/MuonRdoDecodeConfig.py
@@ -137,8 +137,8 @@ def MdtRDODecodeCfg(flags, forTrigger=False):
                                               DecodingTool  = MdtRdoToMdtPrepDataTool,
                                               PrintPrepData = False )
     # add RegSelTool
-    from RegionSelector.RegSelToolConfig import regSelToolMDTCfg
-    MdtRdoToMdtPrepData.RegSel_MDT = acc.popToolsAndMerge( regSelToolMDTCfg( flags ) )
+    from RegionSelector.RegSelToolConfig import regSelTool_MDT_Cfg
+    MdtRdoToMdtPrepData.RegSel_MDT = acc.popToolsAndMerge( regSelTool_MDT_Cfg( flags ) )
 
     if forTrigger:
         # Set the algorithm to RoI mode
@@ -224,8 +224,8 @@ def muonRdoDecodeTestData( forTrigger = False ):
     cfg=ComponentAccumulator()
 
     # Seem to need this to read BS properly
-    from ByteStreamCnvSvc.ByteStreamConfig import TrigBSReadCfg
-    cfg.merge(TrigBSReadCfg(ConfigFlags ))
+    from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
+    cfg.merge(ByteStreamReadCfg(ConfigFlags ))
 
     # Add the MuonCache to ComponentAccumulator for trigger/RoI testing mode
     if forTrigger:
diff --git a/MuonSpectrometer/MuonConfig/python/MuonTrackBuildingConfig.py b/MuonSpectrometer/MuonConfig/python/MuonTrackBuildingConfig.py
index 262bdcda5800ab537c856e2ad362bbc71f09fa2f..c97cebdcf75c5756fe36ef920b41d5316c2ea8d4 100644
--- a/MuonSpectrometer/MuonConfig/python/MuonTrackBuildingConfig.py
+++ b/MuonSpectrometer/MuonConfig/python/MuonTrackBuildingConfig.py
@@ -286,14 +286,44 @@ def MuonSegmentRegionRecoveryToolCfg(flags, name="MuonSegmentRegionRecoveryTool"
 
     # Not bothering to handle IDHelper or EDMHelper or HitSummaryTool. Default is okay.
     
-    from RegionSelector.RegSelConfig import regSelCfg
-    acc = regSelCfg(flags)
+    from RegionSelector.RegSelToolConfig import regSelTool_MDT_Cfg, regSelTool_RPC_Cfg, regSelTool_TGC_Cfg
+    acc = regSelTool_MDT_Cfg(flags)
+    kwargs.setdefault("MDTRegionSelector", acc.popPrivateTools())
     result.merge(acc)
-    # FIXME - the following doesn't currently work (the region selector doesn't set a primary service)
-    # this should be revisited once the rewrite of the region selector is done (can use the default until then)
-    #kwargs.setdefault("RegionSelector", acc.getService())
-    
-    
+
+    acc = regSelTool_TGC_Cfg(flags)
+    kwargs.setdefault("TGCRegionSelector", acc.popPrivateTools())
+    result.merge(acc)
+
+    acc = regSelTool_RPC_Cfg(flags)
+    kwargs.setdefault("RPCRegionSelector", acc.popPrivateTools())
+    result.merge(acc)
+
+    if flags.Detector.GeometryCSC:
+        from RegionSelector.RegSelToolConfig import regSelTool_CSC_Cfg
+        acc = regSelTool_CSC_Cfg(flags)
+        kwargs.setdefault("CSCRegionSelector", acc.popPrivateTools())
+        result.merge(acc)
+    else:
+        kwargs.setdefault("CSCRegionSelector", "")
+
+    if flags.Detector.GeometrysTGC:
+        from RegionSelector.RegSelToolConfig import regSelTool_STGC_Cfg
+        acc = regSelTool_STGC_Cfg(flags)
+        kwargs.setdefault("STGCRegionSelector", acc.popPrivateTools())
+        result.merge(acc)
+    else:
+        kwargs.setdefault("STGCRegionSelector", "")
+
+    if flags.Detector.GeometryMM:
+        from RegionSelector.RegSelToolConfig import regSelTool_MM_Cfg
+        acc = regSelTool_MM_Cfg(flags)
+        kwargs.setdefault("MMRegionSelector", acc.popPrivateTools())
+        result.merge(acc)
+    else:
+        kwargs.setdefault("MMRegionSelector", "")
+
+
     acc = MuonTrackSummaryToolCfg(flags)
     kwargs.setdefault("TrackSummaryTool", acc.getPrimary())
     result.merge(acc)
diff --git a/MuonSpectrometer/MuonDetDescr/MuonAGDD/MuonAGDD/MuonAGDDTool.h b/MuonSpectrometer/MuonDetDescr/MuonAGDD/MuonAGDD/MuonAGDDTool.h
index f9b1e323f6967700f530930fd3c48d00cc3a6e04..b0032c8eda77fd050eb7434f8cdaafffda920093 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonAGDD/MuonAGDD/MuonAGDDTool.h
+++ b/MuonSpectrometer/MuonDetDescr/MuonAGDD/MuonAGDD/MuonAGDDTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef MuonAGDDTool_H
@@ -20,8 +20,7 @@ class IToolSvc;
 class MuonAGDDTool: public AGDDToolBase
 {
 public:
-	MuonAGDDTool(const std::string& type, const std::string& name, 
-				 const IInterface* parent);
+	MuonAGDDTool(const std::string& type, const std::string& name, const IInterface* parent);
 	virtual StatusCode construct();
 	
 	virtual StatusCode initialize();
@@ -32,6 +31,8 @@ private:
 	std::vector<std::string> m_structuresFromFlags;
 	std::string m_outFileType;
 	std::string m_outPREsqlName;
+	std::string m_DBFileName;
+	std::string m_agdd2GeoSvcName;
 
 	bool m_readAGDD;
 	bool m_dumpAGDD;
diff --git a/MuonSpectrometer/MuonDetDescr/MuonAGDD/MuonAGDD/NSWAGDDTool.h b/MuonSpectrometer/MuonDetDescr/MuonAGDD/MuonAGDD/NSWAGDDTool.h
index f91c9ed8f8c3a66b18c63a47e8688b6c0baf307e..afd6fa7e2896231508258ace41b15525b80f1e26 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonAGDD/MuonAGDD/NSWAGDDTool.h
+++ b/MuonSpectrometer/MuonDetDescr/MuonAGDD/MuonAGDD/NSWAGDDTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef NSWAGDDTool_H
@@ -17,8 +17,7 @@ namespace MuonGM
 class NSWAGDDTool: public AGDDToolBase
 {
 public:
-	NSWAGDDTool(const std::string& type, const std::string& name, 
-				 const IInterface* parent);
+	NSWAGDDTool(const std::string& type, const std::string& name, const IInterface* parent);
 	virtual StatusCode construct();
 	
 	virtual StatusCode initialize();
@@ -36,6 +35,8 @@ private:
 
 	std::string m_outFileType;
 	std::string m_outPREsqlName;
+	std::string m_DBFileName;
+	std::string m_agdd2GeoSvcName;
 
 	bool m_readAGDD;
 	bool m_dumpAGDD;
diff --git a/MuonSpectrometer/MuonDetDescr/MuonAGDD/share/MuonAGDD_BlobCheck.py b/MuonSpectrometer/MuonDetDescr/MuonAGDD/share/MuonAGDD_BlobCheck.py
index d7fd2c2c71660ed79190d5ee303f4ff17316d1a6..0e86cd5eddf02bca401956132c9118a8cf3d24a5 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonAGDD/share/MuonAGDD_BlobCheck.py
+++ b/MuonSpectrometer/MuonDetDescr/MuonAGDD/share/MuonAGDD_BlobCheck.py
@@ -1,13 +1,20 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+#
+# Create MuonAGDDTool from local amdb file (input_amdb_simrec) containing AGDD xml block
+#
 from MuonAGDD.MuonAGDDConfig import MuonAGDDTool
 MuonAGDDDumperFromAMDBFile = MuonAGDDTool(name="AGDDDumperFromAMDBFile")
-MuonAGDDDumperFromAMDBFile.WriteAGDDFile=True
+MuonAGDDDumperFromAMDBFile.WriteAGDDFile=True # creates Out.AmdcOracle.AM.AGDDtemp.data and Out.AmdcOracle.AM.AGDD.PREsql
 MuonAGDDDumperFromAMDBFile.BuildNSW=False
 MuonAGDDDumperFromAMDBFile.Locked=True
 
-# write blob from DB in Generated_AMDB_pool.txt
+#
+# Create MuonAGDDTool reading AGDD from database
+#
 from MuonAGDD.MuonAGDDConfig import MuonAGDDTool
 MuonAGDDDumperFromDB = MuonAGDDTool(name="AGDDDumperFromDB")
-MuonAGDDDumperFromDB.DumpAGDD=True
+MuonAGDDDumperFromDB.DumpAGDD=True # write blob from DB in Generated_AGDD_pool.txt
 MuonAGDDDumperFromDB.BuildNSW=False
 MuonAGDDDumperFromDB.Locked=True
 
@@ -17,4 +24,3 @@ AGDD2Geo.Builders += [MuonAGDDDumperFromAMDBFile]
 AGDD2Geo.Builders += [MuonAGDDDumperFromDB]
 theApp.CreateSvc += ["AGDDtoGeoSvc"]
 ServiceMgr += AGDD2Geo
-
diff --git a/MuonSpectrometer/MuonDetDescr/MuonAGDD/share/NSWAGDD_BlobCheck.py b/MuonSpectrometer/MuonDetDescr/MuonAGDD/share/NSWAGDD_BlobCheck.py
index f58485fd5ec0957f76dc6956d2d4dca0420ec17b..3f918344636f661ae2c43904411c23354cfbf632 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonAGDD/share/NSWAGDD_BlobCheck.py
+++ b/MuonSpectrometer/MuonDetDescr/MuonAGDD/share/NSWAGDD_BlobCheck.py
@@ -1,27 +1,23 @@
-from MuonAGDD.MuonAGDDConfig import NSWAGDDTool
-NSWAGDDDumperFromFile = NSWAGDDTool(name="NSWAGDDDumperFromFile")
-NSWAGDDDumperFromFile.WriteAGDDFile=True
-NSWAGDDDumperFromFile.Locked=False
-# turn off reading from data base (true means read from DB)
-NSWAGDDDumperFromFile.ReadAGDD=False
-NSWAGDDDumperFromFile.XMLFiles=[input_nsw_xml]
-# for the NSWAGDDTool volumes must always be given ("NewSmallWheel" usually includes everything)
-NSWAGDDDumperFromFile.Volumes=["NewSmallWheel"]
-NSWAGDDDumperFromFile.DefaultDetector="Muon"
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-# write blob from DB in Generated_NSWD_pool.txt
+#
+# Create NSWAGDDTool reading xml from database
+#
 from MuonAGDD.MuonAGDDConfig import NSWAGDDTool
 NSWAGDDDumperFromDB = NSWAGDDTool(name="NSWAGDDDumperFromDB")
 NSWAGDDDumperFromDB.ReadAGDD=True
-NSWAGDDDumperFromDB.DumpAGDD=True
+NSWAGDDDumperFromDB.DumpAGDD=True # write blob from DB in Generated_NSWD_pool.txt
 NSWAGDDDumperFromDB.Locked=False
-# for the NSWAGDDTool volumes must always be given ("NewSmallWheel" usually includes everything)
-NSWAGDDDumperFromDB.Volumes=["NewSmallWheel"]
+NSWAGDDDumperFromDB.Volumes=["NewSmallWheel"] # for the NSWAGDDTool volumes must always be given ("NewSmallWheel" usually includes everything)
 NSWAGDDDumperFromDB.DefaultDetector="Muon"
 
 from AGDD2GeoSvc.AGDD2GeoSvcConf import AGDDtoGeoSvc
+from AthenaCommon.AppMgr import ServiceMgr, theApp
+
+#
+# Create AGDDtoGeoSvc for NSWAGDDTool reading from database
+#
 AGDD2Geo = AGDDtoGeoSvc()
-AGDD2Geo.Builders += [NSWAGDDDumperFromFile]
 AGDD2Geo.Builders += [NSWAGDDDumperFromDB]
 theApp.CreateSvc += ["AGDDtoGeoSvc"]
 ServiceMgr += AGDD2Geo
diff --git a/MuonSpectrometer/MuonDetDescr/MuonAGDD/share/NSWAGDD_BlobProduction.py b/MuonSpectrometer/MuonDetDescr/MuonAGDD/share/NSWAGDD_BlobProduction.py
index 699e8fe4dd9d404de842f854db9f86d3c1f50ac0..fe429325a2c26880c1ed9cd790f8870bbec2bcf0 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonAGDD/share/NSWAGDD_BlobProduction.py
+++ b/MuonSpectrometer/MuonDetDescr/MuonAGDD/share/NSWAGDD_BlobProduction.py
@@ -1,22 +1,13 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
 from MuonAGDD.MuonAGDDConfig import NSWAGDDTool
 NSWAGDDDumper = NSWAGDDTool(name="NSWAGDDDumper")
-NSWAGDDDumper.WriteAGDDFile=True
+NSWAGDDDumper.WriteAGDDFile=True # creates Out.AmdcOracle.AM.AGDDtemp.data and Out.AmdcOracle.AM.AGDD.PREsql
 NSWAGDDDumper.Locked=False
-# turn off reading from data base (true means read from DB)
-NSWAGDDDumper.ReadAGDD=False
+NSWAGDDDumper.ReadAGDD=False # turn off reading from data base (true means read from DB)
 NSWAGDDDumper.XMLFiles=[input_nsw_xml]
-# for the NSWAGDDTool volumes must always be given ("NewSmallWheel" usually includes everything)
-NSWAGDDDumper.Volumes=["NewSmallWheel"]
+NSWAGDDDumper.Volumes=["NewSmallWheel"] # for the NSWAGDDTool volumes must always be given ("NewSmallWheel" usually includes everything)
 NSWAGDDDumper.DefaultDetector="Muon"
-# setting of not automatically generated rows in database table
-# NSWAGDDDumper.OutputFileACTVERS  = 0         # active version number
-# NSWAGDDDumper.OutputFileACTVNAME = ""        # active version string
-# NSWAGDDDumper.OutputFileALGVERS  = 0         # alignment version number
-# NSWAGDDDumper.OutputFileALGVNAME = ""        # alignment version string
-# NSWAGDDDumper.OutputFilePASVERS  = 0         # passive structure version number
-# NSWAGDDDumper.OutputFilePASVNAME = ""        # passive structure version string
-# NSWAGDDDumper.OutputFileFORMAT   = "AGDDXML" # format of output file
-# NSWAGDDDumper.OutputFileType     = "NSWD"    # name for database table
 
 from AGDD2GeoSvc.AGDD2GeoSvcConf import AGDDtoGeoSvc
 AGDD2Geo = AGDDtoGeoSvc()
diff --git a/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/MuonAGDDTool.cxx b/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/MuonAGDDTool.cxx
index 8cc4c830566ab8a9c11daefcde9705659c58f050..66f9790e635d17919ff51bd1673003d0b80bf939 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/MuonAGDDTool.cxx
+++ b/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/MuonAGDDTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "MuonAGDD/MuonAGDDTool.h"
@@ -16,19 +16,23 @@
 
 using namespace MuonGM;
 
-MuonAGDDTool::MuonAGDDTool(const std::string& type, const std::string& name, 
-				 const IInterface* parent):AGDDToolBase(type,name,parent),
-					m_overrideConfiguration(false),m_buildNSW(true)
+MuonAGDDTool::MuonAGDDTool(const std::string& type, const std::string& name, const IInterface* parent) :
+    AGDDToolBase(type,name,parent),
+    m_outPREsqlName(""),
+    m_overrideConfiguration(false),
+    m_buildNSW(true)
 #ifndef SIMULATIONBASE
 					, p_AmdcsimrecAthenaSvc ( "AmdcsimrecAthenaSvc",name )
 #endif
 {
   	declareProperty( "Structures" ,     m_structuresToBuild);
 	declareProperty( "ReadAGDD",   		m_readAGDD = true);
-	declareProperty( "DumpAGDD",		m_dumpAGDD = false);
+	declareProperty( "DumpAGDD",		m_dumpAGDD = false, "write blob from DB into text file");
 	declareProperty( "OverrideConfiguration",m_overrideConfiguration = false);
 	declareProperty( "BuildNSW",		m_buildNSW = true);
 	declareProperty( "OutputFileType",	m_outFileType = "AGDD", "Name for database table");
+	declareProperty( "OutputFileName",	m_DBFileName = "", "specify name for DB text file");
+	declareProperty( "AGDDtoGeoSvcName", m_agdd2GeoSvcName = "AGDDtoGeoSvc", "specify name of AGDDtoGeoSvc");
 }
 
 StatusCode MuonAGDDTool::initialize()
@@ -39,6 +43,10 @@ StatusCode MuonAGDDTool::initialize()
 
 	ATH_CHECK(AGDDToolBase::initialize());
 
+	if (m_DBFileName.empty()) {
+		m_DBFileName = "Generated_" + m_outFileType + "_pool.txt";
+	}
+
 	// please see more details on regarding the dependency on AMDB on ATLASSIM-3636
 	// and the CMakeLists.txt . the NSWAGDDTool avoids the dependency already
 #ifndef SIMULATIONBASE
@@ -48,6 +56,7 @@ StatusCode MuonAGDDTool::initialize()
 	if (m_buildNSW) 
 	{
 		MuonAGDDToolHelper theHelper;
+		theHelper.setAGDDtoGeoSvcName(m_agdd2GeoSvcName);
 		theHelper.SetNSWComponents();
 	}
 	
@@ -58,7 +67,8 @@ StatusCode MuonAGDDTool::initialize()
 StatusCode MuonAGDDTool::construct() 
 {
 	MuonAGDDToolHelper theHelper;
-		
+	theHelper.setAGDDtoGeoSvcName(m_agdd2GeoSvcName);
+
 	m_controller->UseGeoModelDetector("Muon");
 	
 	if (!m_locked)
@@ -81,8 +91,8 @@ StatusCode MuonAGDDTool::construct()
 	}
 	
 	ATH_MSG_INFO(" now reading AGDD blob ");
-	
-	std::string AGDDfile=theHelper.GetAGDD(m_dumpAGDD, m_outFileType);
+
+	std::string AGDDfile=theHelper.GetAGDD(m_dumpAGDD, m_outFileType, m_DBFileName);
 #ifndef SIMULATIONBASE
 	if(m_writeDBfile) AGDDfile = p_AmdcsimrecAthenaSvc->GetAgddString();
 #endif
diff --git a/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/MuonAGDDToolHelper.cxx b/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/MuonAGDDToolHelper.cxx
index abdf632b9556e5b0709caf5ee051cc3d62980940..4312348750caffd6a8457aebaba493b3e49a498b 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/MuonAGDDToolHelper.cxx
+++ b/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/MuonAGDDToolHelper.cxx
@@ -38,12 +38,15 @@
 #include "MuonAGDDBase/mmSpacer_TechHandler.h"
 #include "MuonAGDDBase/mm_readoutHandler.h"
 
+#include <TString.h> // for Form
 #include <fstream>
 
 using namespace MuonGM;
 
-MuonAGDDToolHelper::MuonAGDDToolHelper()
-{
+MuonAGDDToolHelper::MuonAGDDToolHelper() :
+    p_RDBAccessSvc(nullptr),
+    p_GeoModelSvc(nullptr),
+    m_svcName("AGDDtoGeoSvc") {
 	StatusCode result;
 	
 	result=Gaudi::svcLocator()->service("GeoModelSvc",p_GeoModelSvc);
@@ -64,10 +67,8 @@ std::vector<std::string>& MuonAGDDToolHelper::ReadAGDDFlags()
 	structuresFromFlags.clear();
    std::string agdd2geoVersion = p_RDBAccessSvc->getChildTag("AGDD2GeoSwitches",p_GeoModelSvc->muonVersion(),"MuonSpectrometer");
 
-//   m_AGDD2GeoSwitches.clear();
    if(!agdd2geoVersion.empty()) 
    {
-//     m_AGDD2GeoSwitchesStamp = m_AGDD2GeoSwitchesStamp + 1;
      std::string TheKEYNAME;
      int TheKEYVALUE;
      IRDBRecordset_ptr pIRDBRecordset = p_RDBAccessSvc->getRecordsetPtr("AGDD2GeoSwitches",p_GeoModelSvc->muonVersion(),"MuonSpectrometer");
@@ -78,8 +79,6 @@ std::vector<std::string>& MuonAGDDToolHelper::ReadAGDDFlags()
        TheKEYVALUE = record->getInt("KEYVALUE");
        if ( TheKEYVALUE == 1 )
        {
-//        std::cout<<"  Add to m_AGDD2GeoSwitches " << TheKEYNAME <<std::endl;
-//		 if (aliases->IsAliased(TheKEYNAME))
          structuresFromFlags.push_back(TheKEYNAME);
        }
      }
@@ -92,7 +91,7 @@ std::vector<std::string>& MuonAGDDToolHelper::ReadAGDDFlags()
 }
 
 
-std::string MuonAGDDToolHelper::GetAGDD(bool dumpIt, std::string tableName)
+std::string MuonAGDDToolHelper::GetAGDD(const bool dumpIt, const std::string& tableName, const std::string& outFileName)
 {
 
    const IGeoModelSvc * geoModel=p_GeoModelSvc;
@@ -124,13 +123,9 @@ std::string MuonAGDDToolHelper::GetAGDD(bool dumpIt, std::string tableName)
    std::ofstream  GeneratedFile;
    if (dumpIt) 
    {
-	 	std::ofstream  GeneratedFile;
-		std::string fileName;
-		fileName.append("Generated_");
-		fileName.append(tableName);
-		fileName.append("_pool.txt");
-	 	GeneratedFile.open(fileName);
-		GeneratedFile<<AgddString<<std::endl;
+	 	std::ofstream GeneratedFile;
+	 	GeneratedFile.open(outFileName);
+		GeneratedFile<<AgddString;
 		GeneratedFile.close();
    }
 
@@ -140,45 +135,20 @@ std::string MuonAGDDToolHelper::GetAGDD(bool dumpIt, std::string tableName)
 
 bool MuonAGDDToolHelper::BuildMScomponents() const
 {
-
-//  ATH_MSG_INFO("BuildMScomponents - start");
-
-  StoreGateSvc* pDetStore=0;
+  StoreGateSvc* pDetStore=nullptr;
   ISvcLocator* svcLocator = Gaudi::svcLocator();
-  StatusCode sc=svcLocator->service("DetectorStore",pDetStore);
-  if (sc.isFailure()) 
-    {
-//      ATH_MSG_ERROR("AGDDController could not get at the detector store!");
-    }
-  MuonGM::MuonDetectorManager*	muonMgr;
-  sc = pDetStore->retrieve( muonMgr );
-  if ( sc.isFailure() ) {
-//   ATH_MSG_ERROR(" Cannot retrieve MuonDetectorManager " );
-   return false;
-  }
-
+  if (svcLocator->service("DetectorStore",pDetStore).isFailure()) return false;
+  MuonGM::MuonDetectorManager* muonMgr=nullptr;
+  if (pDetStore->retrieve(muonMgr).isFailure()) return false;
   bool readoutGeoDone =  BuildReadoutGeometry(muonMgr/*, GetMSdetectors*/);
-  if (!readoutGeoDone) {
-//   ATH_MSG_INFO(" Problems met while building the ReadoutGeometry " );
-   return false;
-  }
-//  else ATH_MSG_INFO( "ReadoutGeometry created" );
-//  ATH_MSG_INFO("In BuildMScomponents - done");
-
+  if (!readoutGeoDone) return false;
   return true;
 }
 
 bool MuonAGDDToolHelper::BuildReadoutGeometry(MuonGM::MuonDetectorManager* mgr/*, std::map<GeoFullPhysVol*, std::string>* vec*/) const
 {
   bool geoBuilt = true;  
-//  ATH_MSG_INFO("In BuildReadoutGeometry - start");
 
-  //std::map<std::string, GeoFullPhysVol*>* myMap =  NULL;
-  //myMap = GetMSdetectors();
-  //log<<MSG::INFO<<"In AGDD2GeoSvc::BuildReadoutGeometry - size of the detector map = "<<myMap->size()<<endmsg;
-
-  //std::map<std::string, GeoFullPhysVol*>::const_iterator it;
-  
   detectorList& dList=AGDDDetectorStore::GetDetectorStore()->GetDetectorList();
   detectorList::const_iterator it;
   for (it=dList.begin(); it!=dList.end(); ++it)
@@ -188,7 +158,6 @@ bool MuonAGDDToolHelper::BuildReadoutGeometry(MuonGM::MuonDetectorManager* mgr/*
       {
       std::string chTag = dPos[i]->ID.detectorAddress;
       GeoFullPhysVol* vol = dPos[i]->theVolume;
-//      ATH_MSG_INFO("Building RE for component named <"<<chTag<<">");
       
       std::string stName = chTag.substr(0,4);
       
@@ -205,20 +174,10 @@ bool MuonAGDDToolHelper::BuildReadoutGeometry(MuonGM::MuonDetectorManager* mgr/*
       phiIndex = atoi((chTag.substr(12,1)).c_str());
       mLayer = atoi((chTag.substr(7,1)).c_str());
       
-      //MuonReadoutElement* re = NULL;
       if (chTag.substr(0,3)=="sMD")
 	  {
 	  MMReadoutElement* re = new MMReadoutElement((GeoVFullPhysVol*)vol, stName, etaIndex, phiIndex, mLayer, false, mgr);
 	  std::string myVolName = (chTag.substr(0,8)).c_str();
-	  /* AGDDParameterBagMM* MMparaBag = dynamic_cast<AGDDParameterBagMM*> (AGDDParameterStore::GetParameterStore()->GetParameterBag(myVolName));
-	  if(!MMparaBag) {
-	    std::cout << " not possible to retrieve parameters for <" << myVolName << ": quitting! >" << std::endl;
-		return false;
-	  }
-	  double pitch;
-	  if(iLS==1) pitch = MMparaBag->TechParameters->pitchSS; //small
-	  else pitch = MMparaBag->TechParameters->pitchLS; //large
-	  re->initDesign(MMparaBag->largeX, MMparaBag->smallX, MMparaBag->lengthY, pitch, MMparaBag->TechParameters->thickness); */
 	  re->initDesign(-999., -999., -999., -999., -999.);
 	  re->fillCache();
 	  mgr->addMMReadoutElement_withIdFields(re, iLS, etaIndex, phiIndex, mLayer);
@@ -228,43 +187,23 @@ bool MuonAGDDToolHelper::BuildReadoutGeometry(MuonGM::MuonDetectorManager* mgr/*
 	  {
 	  sTgcReadoutElement* re = new sTgcReadoutElement((GeoVFullPhysVol*)vol, stName, etaIndex, phiIndex, mLayer, false, mgr);	  
 	  std::string myVolName = (chTag.substr(0,8)).c_str();
-	  /*
-	  AGDDParameterBagsTGC* sTGCparaBag = dynamic_cast<AGDDParameterBagsTGC*> (AGDDParameterStore::GetParameterStore()->GetParameterBag(myVolName));
-	  if(!sTGCparaBag) {
-	    std::cout << " not possible to retrieve parameters for <" << myVolName << ": quitting! >" << std::endl;
-		return false;
-	  }
-	  re->initDesign(sTGCparaBag->largeX, sTGCparaBag->smallX, sTGCparaBag->lengthY, sTGCparaBag->TechParameters->stripPitch,
-			 sTGCparaBag->TechParameters->wirePitch, sTGCparaBag->TechParameters->stripWidth, sTGCparaBag->TechParameters->wireWidth,
-			 sTGCparaBag->TechParameters->thickness);
-	  
-	  since the concept of Parameter Bag is dismissed things get hardcoded
-	  initDesign for sTGCReadoutElement only uses stripPitch, strip Width and thickness - all other dimensions (here -999.) are (hard)coded there again
-	  */
 	  re->initDesign(-999., -999., -999., 3.2, -999., 2.7, -999., 2.6);
 	  re->fillCache();
 	  mgr->addsTgcReadoutElement_withIdFields(re, iLS, etaIndex, phiIndex, mLayer);
     re->setDelta(mgr);
 	  }
 	  }
-
-      //aggdContainer->push_back(*it);
   }
-  //std::cout<<"Size of the NSWdetectors = <"<<vec->size()<<"> "<<aggdContainer->size()<<std::cout;
-  //sc=pDetStore->record( aggdContainer ,"NSWdetectors");
   return geoBuilt;
 
 }
 
 void MuonAGDDToolHelper::SetNSWComponents()
 {
-	IAGDDtoGeoSvc* agddsvc;
-	StatusCode result;
-	result=Gaudi::svcLocator()->service("AGDDtoGeoSvc",agddsvc);
-	if (result.isFailure())
-    {
-    	std::cout<<"could not initialize AGDDtoGeoSvc!!! "<<std::endl;
-    }
+	IAGDDtoGeoSvc* agddsvc = nullptr;
+	if (Gaudi::svcLocator()->service(m_svcName,agddsvc).isFailure()) {
+    throw std::runtime_error(Form("File: %s, Line: %d\nMuonAGDDToolHelper::SetNSWComponents() - Could not retrieve %s from ServiceLocator", __FILE__, __LINE__, m_svcName.c_str()));
+  }
 	
 	agddsvc->addHandler(new micromegasHandler("micromegas"));
 	agddsvc->addHandler(new mm_TechHandler("mm_Tech"));
@@ -275,3 +214,7 @@ void MuonAGDDToolHelper::SetNSWComponents()
 	agddsvc->addHandler(new mmSpacer_TechHandler("mmSpacer_Tech"));
 	agddsvc->addHandler(new mm_readoutHandler("mm_readout"));
 }	
+
+void MuonAGDDToolHelper::setAGDDtoGeoSvcName(const std::string& name) {
+  m_svcName = name;
+}
\ No newline at end of file
diff --git a/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/MuonAGDDToolHelper.h b/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/MuonAGDDToolHelper.h
index 4a88db9124efc92b2885138ae437ca149334f43a..7b65dbaea9728ae2936d9608893f72b76f49a4ce 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/MuonAGDDToolHelper.h
+++ b/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/MuonAGDDToolHelper.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef MUONAGDD_MUONAGDDTOOLHELPER_H
@@ -25,15 +25,18 @@ public:
 	
 	void SetNSWComponents();
 	
-	std::string GetAGDD(bool dumpIt, std::string tableName);
+	std::string GetAGDD(const bool dumpIt, const std::string& tableName, const std::string& outFileName);
 	
 	bool BuildMScomponents() const;
 	bool BuildReadoutGeometry(MuonGM::MuonDetectorManager* mgr) const;
 
+	void setAGDDtoGeoSvcName(const std::string& name);
+
 private:
 
 	IRDBAccessSvc* p_RDBAccessSvc;
 	IGeoModelSvc* p_GeoModelSvc;
+	std::string m_svcName;
 	
 };
 
diff --git a/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/NSWAGDDTool.cxx b/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/NSWAGDDTool.cxx
index 3eef8bc23151d8f7f7d641e199bf8195a5fc20fb..4ae838e48938fb840830a22eeff38f6764fedb45 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/NSWAGDDTool.cxx
+++ b/MuonSpectrometer/MuonDetDescr/MuonAGDD/src/NSWAGDDTool.cxx
@@ -1,22 +1,24 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "MuonAGDD/NSWAGDDTool.h"
+
 #include "MuonAGDDToolHelper.h"
 #include "AGDDControl/AGDDController.h"
 #include "AGDDControl/AGDD2GeoModelBuilder.h"
 #include "AGDD2GeoSvc/IAGDD2GeoSvc.h"
-
 #include "AGDDModel/AGDDParameterStore.h"
 #include "AGDDKernel/AGDDDetector.h"
 #include "AGDDKernel/AGDDDetectorStore.h"
+
 #include <fstream>
 
 using namespace MuonGM;
 
-NSWAGDDTool::NSWAGDDTool(const std::string& type, const std::string& name, 
-				 const IInterface* parent):AGDDToolBase(type,name,parent)
+NSWAGDDTool::NSWAGDDTool(const std::string& type, const std::string& name, const IInterface* parent) :
+    AGDDToolBase(type,name,parent),
+    m_outPREsqlName("")
 {
 	declareProperty( "ReadAGDD",   		m_readAGDD    = true,           "read description from DB");
 	declareProperty( "DumpAGDD",		m_dumpAGDD    = false,          "write out parsed XML");
@@ -28,6 +30,8 @@ NSWAGDDTool::NSWAGDDTool(const std::string& type, const std::string& name,
 	declareProperty( "OutputFilePASVNAME",	m_outFilePasN = "",		"passive structure version string");
 	declareProperty( "OutputFileFORMAT",	m_outFileForm = "AGDDXML",	"format of output file");
 	declareProperty( "OutputFileType",	m_outFileType = "NSWD", 	"name for database table");
+	declareProperty( "OutputFileName",	m_DBFileName = "", "specify name for DB text file");
+	declareProperty( "AGDDtoGeoSvcName", m_agdd2GeoSvcName = "AGDDtoGeoSvc", "specify name of AGDDtoGeoSvc");
 }
 
 StatusCode NSWAGDDTool::initialize()
@@ -44,7 +48,11 @@ StatusCode NSWAGDDTool::initialize()
 	m_outFileName = "Out.AmdcOracle.AM." + m_outFileType + "temp.data";
 	m_outPREsqlName = "Out.AmdcOracle.AM." + m_outFileType + ".PREsql";
 
-        ATH_CHECK(AGDDToolBase::initialize());
+    ATH_CHECK(AGDDToolBase::initialize());
+
+	if (m_DBFileName.empty()) {
+		m_DBFileName = "Generated_" + m_outFileType + "_pool.txt";
+	}
 	
 	static int iEntries=0;
 	
@@ -52,6 +60,7 @@ StatusCode NSWAGDDTool::initialize()
 	{
 		iEntries=1;
 		MuonAGDDToolHelper theHelper;
+		theHelper.setAGDDtoGeoSvcName(m_agdd2GeoSvcName);
 		theHelper.SetNSWComponents();
 	}
 
@@ -65,6 +74,7 @@ StatusCode NSWAGDDTool::construct()
 	ATH_MSG_INFO(" Name = "<<name());
 	
 	MuonAGDDToolHelper theHelper;
+	theHelper.setAGDDtoGeoSvcName(m_agdd2GeoSvcName);
 	if (!m_readAGDD)
 	{
 		ATH_MSG_INFO(" trying to parse files ");
@@ -73,7 +83,7 @@ StatusCode NSWAGDDTool::construct()
 	else
 	{
 		ATH_MSG_INFO(" trying to parse data base content ");
-		std::string AGDDfile = theHelper.GetAGDD(m_dumpAGDD, m_outFileType);
+		std::string AGDDfile = theHelper.GetAGDD(m_dumpAGDD, m_outFileType, m_DBFileName);
 		m_controller->ParseString(AGDDfile);
 	}
 	
@@ -100,7 +110,6 @@ StatusCode NSWAGDDTool::construct()
 	if(m_writeDBfile)
 	{
 		// build model before writing blob - if Athena crashes the XML is not good and should not become a blob
-		//((AGDD2GeoModelBuilder*)m_controller->GetBuilder())->BuildAllVolumes();
 		ATH_MSG_INFO("\t-- attempting to write output to "<< m_outFileName );
 		if( !m_outFileName.empty() )
 		{
diff --git a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/ATLAS_CHECK_THREAD_SAFETY b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..535e432293a6e2d3baaeaa107b02c41182c101aa
--- /dev/null
+++ b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+MuonSpectrometer/MuonDetDescr/MuonRegionSelector
diff --git a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/CSC_RegionSelectorTable.h b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/CSC_RegionSelectorTable.h
index 15fec9aeebaf11a53997d4bd8aedb4ac4f039115..13b4cef202b36429b100de3e001daed6579064fd 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/CSC_RegionSelectorTable.h
+++ b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/CSC_RegionSelectorTable.h
@@ -1,6 +1,6 @@
 // emacs: this is -*- c++ -*-
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 //
 //   @file    CSC_RegionSelectorTable.h        
@@ -45,7 +45,7 @@ public:
   StatusCode initialize();
   StatusCode finalize();
   
-  virtual RegSelSiLUT* getLUT() const;
+  virtual RegSelSiLUT* getLUT();
 
 private:
   
diff --git a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/MDT_RegionSelectorTable.h b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/MDT_RegionSelectorTable.h
index 1dcf3c64d455fcea7558f86bb0271ef62d268af4..f3fc4b0c1513443dc55e1a2f9399b79227f47e42 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/MDT_RegionSelectorTable.h
+++ b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/MDT_RegionSelectorTable.h
@@ -1,6 +1,6 @@
 // emacs: this is -*- c++ -*-
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 //
 //   @file    MDT_RegionSelectorTable.h        
@@ -45,7 +45,7 @@ public:
   StatusCode initialize();
   StatusCode finalize();
   
-  virtual RegSelSiLUT* getLUT() const;
+  virtual RegSelSiLUT* getLUT();
 
 private:
   
diff --git a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/MM_RegionSelectorTable.h b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/MM_RegionSelectorTable.h
index c2b5496f434407a799d8a4509920c685985003e7..8b953d44fde5ed2891a2a66c4e847acf5c08ad2a 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/MM_RegionSelectorTable.h
+++ b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/MM_RegionSelectorTable.h
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 // emacs: this is -*- c++ -*-
 //
@@ -48,7 +48,7 @@ public:
   StatusCode initialize();
   StatusCode finalize();
   
-  virtual RegSelSiLUT* getLUT() const;
+  virtual RegSelSiLUT* getLUT();
 
 private:
   
diff --git a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/RPC_RegionSelectorTable.h b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/RPC_RegionSelectorTable.h
index 31d7d0cea6df1a16d52bf7aa55956dd21919d17b..091d41fe32fbf5cf4b1825ad59d3322ebe3ba295 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/RPC_RegionSelectorTable.h
+++ b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/RPC_RegionSelectorTable.h
@@ -1,6 +1,6 @@
 // emacs: this is -*- C++ -*-
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 //
 //   @file    RPC_RegionSelectorTable.h        
@@ -38,7 +38,7 @@ public:
   StatusCode initialize();
   StatusCode finalize();
   
-  virtual RegSelSiLUT* getLUT() const;
+  virtual RegSelSiLUT* getLUT();
 
 private:
   
diff --git a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/TGC_RegionSelectorTable.h b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/TGC_RegionSelectorTable.h
index 8252775f83f33fe9ba2bb457947fa82c385fd622..d4041f0579d089de2dd3d95bbd3f23c20b1f5058 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/TGC_RegionSelectorTable.h
+++ b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/TGC_RegionSelectorTable.h
@@ -1,6 +1,6 @@
 // emacs: this is -*- c++ -*-
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 //
 //   @file    TGC_RegionSelectorTable.h        
@@ -46,7 +46,7 @@ public:
   StatusCode initialize();
   StatusCode finalize();
   
-  virtual RegSelSiLUT* getLUT() const;
+  virtual RegSelSiLUT* getLUT();
 
 private:
   
diff --git a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/sTGC_RegionSelectorTable.h b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/sTGC_RegionSelectorTable.h
index f651d48e9db9db6e2665b652c1196a15b912a307..e5aee9a63987939f4bc3c6541f743dfc7e66dc57 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/sTGC_RegionSelectorTable.h
+++ b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/MuonRegionSelector/sTGC_RegionSelectorTable.h
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 // emacs: this is -*- c++ -*-
 //
@@ -46,7 +46,7 @@ public:
   StatusCode initialize();
   StatusCode finalize();
   
-  virtual RegSelSiLUT* getLUT() const;
+  virtual RegSelSiLUT* getLUT();
 
 private:
   
diff --git a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/CSC_RegionSelectorTable.cxx b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/CSC_RegionSelectorTable.cxx
index f11328c755d72e4102967f6ebfbaff2ab01d8fc3..9019b39bc1908b2138bd9cf6b9fca00b342c88e3 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/CSC_RegionSelectorTable.cxx
+++ b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/CSC_RegionSelectorTable.cxx
@@ -50,7 +50,7 @@ StatusCode CSC_RegionSelectorTable::finalize() {
 }
 
 
-RegSelSiLUT* CSC_RegionSelectorTable::getLUT() const {
+RegSelSiLUT* CSC_RegionSelectorTable::getLUT() {
   return m_regionLUT;
 } 
 
diff --git a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/MDT_RegionSelectorTable.cxx b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/MDT_RegionSelectorTable.cxx
index ca8610c7c5f8f358e1a53e3278af51ac3d91ea47..f1586dae8b31365675ae38a41ccd8a5f262db923 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/MDT_RegionSelectorTable.cxx
+++ b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/MDT_RegionSelectorTable.cxx
@@ -56,7 +56,7 @@ StatusCode MDT_RegionSelectorTable::finalize() {
 }
 
 
-RegSelSiLUT* MDT_RegionSelectorTable::getLUT() const {
+RegSelSiLUT* MDT_RegionSelectorTable::getLUT() {
   return m_regionLUT;
 } 
 
diff --git a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/MM_RegionSelectorTable.cxx b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/MM_RegionSelectorTable.cxx
index 83e88740a8ee99df8833dc8108665ee9e482ec7c..3e5567f828f1838d8c099b9f728a9974f8803128 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/MM_RegionSelectorTable.cxx
+++ b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/MM_RegionSelectorTable.cxx
@@ -60,7 +60,7 @@ StatusCode MM_RegionSelectorTable::finalize() {
 }
 
 
-RegSelSiLUT* MM_RegionSelectorTable::getLUT() const {
+RegSelSiLUT* MM_RegionSelectorTable::getLUT() {
   return m_regionLUT;
 } 
 
diff --git a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/RPC_RegionSelectorTable.cxx b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/RPC_RegionSelectorTable.cxx
index 340119d40ed3ccf0665378bb9abdcbd9414388f6..78254517b1b460059c851af20f005925be9360b1 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/RPC_RegionSelectorTable.cxx
+++ b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/RPC_RegionSelectorTable.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 //
 //   @file    RPC_RegionSelectorTable.cxx         
@@ -81,7 +81,7 @@ StatusCode RPC_RegionSelectorTable::finalize() {
 }
 
 
-RegSelSiLUT* RPC_RegionSelectorTable::getLUT() const {
+RegSelSiLUT* RPC_RegionSelectorTable::getLUT() {
   return m_regionLUT;
 } 
 
diff --git a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/TGC_RegionSelectorTable.cxx b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/TGC_RegionSelectorTable.cxx
index 88bf46b5971ab0fc6a7259a5b8e151f0c2b5aa8d..0bdbfe59bb1d924a970df774925323db8d980bbf 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/TGC_RegionSelectorTable.cxx
+++ b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/TGC_RegionSelectorTable.cxx
@@ -64,7 +64,7 @@ StatusCode TGC_RegionSelectorTable::finalize() {
 }
 
 
-RegSelSiLUT* TGC_RegionSelectorTable::getLUT() const {
+RegSelSiLUT* TGC_RegionSelectorTable::getLUT() {
   return m_regionLUT;
 } 
 
diff --git a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/sTGC_RegionSelectorTable.cxx b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/sTGC_RegionSelectorTable.cxx
index ec2e95ac94c7f1f2b141b94a147faf639f9cee8a..7c6f9604d8dc966c687753ad74b16764bad1fda5 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/sTGC_RegionSelectorTable.cxx
+++ b/MuonSpectrometer/MuonDetDescr/MuonRegionSelector/src/sTGC_RegionSelectorTable.cxx
@@ -64,7 +64,7 @@ StatusCode sTGC_RegionSelectorTable::finalize() {
 }
 
 
-RegSelSiLUT* sTGC_RegionSelectorTable::getLUT() const {
+RegSelSiLUT* sTGC_RegionSelectorTable::getLUT() {
   return m_regionLUT;
 } 
 
diff --git a/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/MuonTrackingGeometry/MuonTrackingGeometryBuilderCond.h b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/MuonTrackingGeometry/MuonTrackingGeometryBuilderCond.h
new file mode 100644
index 0000000000000000000000000000000000000000..40f179309c487ea17ca658c7687b6d55823803e2
--- /dev/null
+++ b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/MuonTrackingGeometry/MuonTrackingGeometryBuilderCond.h
@@ -0,0 +1,190 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// MuonTrackingGeometryBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef MUONTRACKINGGEOMETRY_MUONTRACKINGGEOMETRYBUILDERCOND_H
+#define MUONTRACKINGGEOMETRY_MUONTRACKINGGEOMETRYBUILDERCOND_H
+
+//Trk
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrUtils/GeometrySignature.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeArrayCreator.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeHelper.h"
+// Gaudi
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/IChronoStatSvc.h"
+#include "MuonTrackingGeometry/MuonStationBuilder.h"
+#include "MuonTrackingGeometry/MuonInertMaterialBuilder.h"
+// EnvelopeDefinitionService
+#include "SubDetectorEnvelopes/RZPair.h"
+#include "SubDetectorEnvelopes/IEnvelopeDefSvc.h"
+
+namespace Trk {
+ class TrackingGeometry;
+ class Material; 
+ class VolumeBounds;
+ class ITrackingVolumeBuilder;
+
+ typedef std::pair< SharedObject<const TrackingVolume>, Amg::Vector3D> TrackingVolumeOrderPosition;
+ typedef std::pair< SharedObject<const TrackingVolume>, const Amg::Transform3D*> TrackingVolumeNavOrder;
+
+}
+
+namespace Muon {
+
+  typedef std::vector<double> Span;
+     
+  /** @class MuonTrackingGeometryBuilderCond
+  
+      The Muon::MuonTrackingGeometryBuilderCond retrieves MuonStationBuilder and MuonInertMaterialBuilder
+      for the Muon Detector sub detectors and combines the given Volumes to a full Trk::TrackingGeometry.
+      
+      Inheriting directly from IGeometryBuilderCond it can use the protected member functions of the IGeometryBuilderCond
+      to glue Volumes together and exchange BoundarySurfaces
+      
+      @author Sarka.Todorova@cern.ch
+    */
+    
+  class MuonTrackingGeometryBuilderCond : public AthAlgTool,
+                               virtual public Trk::IGeometryBuilderCond {
+  public:
+      /** Constructor */
+      MuonTrackingGeometryBuilderCond(const std::string&,const std::string&,const IInterface*);
+      /** Destructor */
+      virtual ~MuonTrackingGeometryBuilderCond() = default;
+      /** AlgTool initailize method.*/
+      StatusCode initialize();
+      /** AlgTool finalize method */
+      StatusCode finalize();
+      /** TrackingGeometry Interface method */
+      std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair ) const; 
+
+      /** The unique signature */
+      Trk::GeometrySignature geometrySignature() const { return Trk::MS; }
+      
+    private:
+      /** Private struct to contain local variables we dont want to be global in this class*/
+      struct LocalVariablesContainer {
+	double m_innerBarrelRadius;
+	double m_outerBarrelRadius;
+	double m_innerEndcapZ;
+	double m_outerEndcapZ;
+	bool m_adjustStatic;
+	bool m_static3d;
+	std::vector<double> m_zPartitions;
+	std::vector<int>       m_zPartitionsType;
+	std::vector<float>    m_adjustedPhi;
+	std::vector<int>       m_adjustedPhiType;
+	std::vector<const Span*>                      m_spans;             // for clearing
+	std::vector<std::vector<std::vector<std::vector<std::pair<int,float> > > > >  m_hPartitions;
+	std::vector<double>                              m_shieldZPart;
+	std::vector<std::vector<std::pair<int,float> > >   m_shieldHPart;
+	std::map<const Trk::DetachedTrackingVolume*,std::vector<const Trk::TrackingVolume*>* > m_blendMap;
+	std::vector<const Trk::DetachedTrackingVolume*> m_blendVols;
+	const std::vector<std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Span*> >* >* m_stationSpan; 
+	const std::vector<std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Span*> >* >* m_inertSpan; 
+	RZPairVector     m_msCutoutsIn;
+	RZPairVector     m_msCutoutsOut;
+	Trk::Material  m_muonMaterial;               //!< the (empty) material
+	Trk::TrackingVolume*        m_standaloneTrackingVolume;   // muon standalone tracking volume
+      };
+
+      /** Private method to find z/phi span of detached volumes */
+      const Span* findVolumeSpan(const Trk::VolumeBounds* volBounds, Amg::Transform3D transf, double zTol, double phiTol, LocalVariablesContainer &aLVC) const;
+      const std::vector<std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Span*> >* >* findVolumesSpan(const std::vector<const Trk::DetachedTrackingVolume*>* objs, double zTol, double phiTol, LocalVariablesContainer &aLVC) const;
+      /** Private methods to define subvolumes and fill them with detached volumes */
+      const Trk::TrackingVolume* processVolume( const Trk::Volume*, int, int, std::string, LocalVariablesContainer &aLVC) const; 
+      const Trk::TrackingVolume* processVolume( const Trk::Volume*, int, std::string, LocalVariablesContainer &aLVC) const; 
+      const Trk::TrackingVolume* processShield( const Trk::Volume*, int, std::string, LocalVariablesContainer &aLVC) const; 
+      /** Private method to check volume properties */
+      void checkVolume(const Trk::TrackingVolume*) const;
+      /** Private method to find detached volumes */
+      std::vector<const Trk::DetachedTrackingVolume*>* getDetachedObjects(const Trk::Volume*, std::vector<const Trk::DetachedTrackingVolume*>&, LocalVariablesContainer &aLVC ,int mode=0) const;
+      /** Private method to check if constituent enclosed */
+      bool enclosed(const Trk::Volume*, const Muon::Span*, LocalVariablesContainer &aLVC) const;
+      /** Private method to retrieve z partition */
+      void getZParts(LocalVariablesContainer &aLVC) const;
+      /** Private method to retrieve phi partition */
+      void getPhiParts(int, LocalVariablesContainer &aLVC) const;
+      /** Private method to retrieve h partition */
+      void getHParts(LocalVariablesContainer &aLVC) const;
+      /** Private method to retrieve shield partition */
+      void getShieldParts(LocalVariablesContainer & aLVC) const; 
+      /** Private method to calculate volume */
+      double calculateVolume(const Trk::Volume*) const;
+      /** Private method to blend the inert material */
+      void blendMaterial(LocalVariablesContainer &aLVC) const;
+     
+      ToolHandle<Trk::IDetachedTrackingVolumeBuilder>      m_stationBuilder{this,"MuonStationBuilder","Muon::MuonStationBuilder/MuonStationBuilder"};                //!< A Tool for station type creation
+
+      ToolHandle<Trk::IDetachedTrackingVolumeBuilder>      m_inertBuilder{this,"InertMaterialBuilder","Muon::MuonInertMaterialBuilder/MuonInertMaterialBuilder"};      //!< A Tool for inert object  creation
+      
+      ToolHandle<Trk::ITrackingVolumeArrayCreator>         m_trackingVolumeArrayCreator{this,"TrackingVolumeArrayCreator","Trk::TrackingVolumeArrayCreator/TrackingVolumeArrayCreator"};    //!< Helper Tool to create TrackingVolume Arrays
+
+      ToolHandle<Trk::ITrackingVolumeHelper>               m_trackingVolumeHelper{this,"TrackingVolumeHelper","Trk::TrackingVolumeHelper/TrackingVolumeHelper"};          //!< Helper Tool to create TrackingVolumes
+
+      ServiceHandle<IEnvelopeDefSvc>                       m_enclosingEnvelopeSvc{this,"EnvelopeDefinitionSvc","AtlasEnvelopeDefSvc","n"};   //!< service to provide input volume size
+   
+      Gaudi::Property<bool>                                m_muonSimple{this,"SimpleMuonGeometry",false};
+      Gaudi::Property<bool>                                m_loadMSentry{this,"LoadMSEntry",false};
+      Gaudi::Property<bool>                                m_muonActive{this,"BuildActiveMaterial",true};
+      Gaudi::Property<bool>                                m_muonInert{this,"BuildInertMaterial",true};
+
+      // Overall Dimensions
+      Gaudi::Property<double>        m_innerBarrelRadius{this,"InnerBarrelRadius",4255.};    //!< minimal extend in radial dimension of the muon barrel
+      Gaudi::Property<double>        m_outerBarrelRadius{this,"OuterBarrelRadius",13910.}; //!< maximal extend in radial dimension of the muon barrel
+      Gaudi::Property<double>        m_barrelZ{this,"BarrelZ",6785.};                                              //!< maximal extend in z of the muon barrel
+      Gaudi::Property<double>        m_innerEndcapZ{this,"InnerEndcapZ",12900.};              //!< maximal extend in z of the inner part of muon endcap 
+      Gaudi::Property<double>        m_outerEndcapZ{this,"OuterEndcapZ",26046.};             //!< maximal extend in z of the outer part of muon endcap
+      double                              m_bigWheel;                 //!< maximal extend in z of the big wheel
+      double                              m_outerWheel;               //!< minimal extend in z of the outer wheel (EO)
+      double                              m_ectZ;                     //!< minimal extent in z of the ECT
+      double                              m_beamPipeRadius;
+      double                              m_innerShieldRadius;
+      double                              m_outerShieldRadius;
+      double                              m_diskShieldZ;
+
+      Gaudi::Property<int>                m_barrelEtaPartition{this,"EtaBarrelPartitions",9};
+      Gaudi::Property<int>                m_innerEndcapEtaPartition{this,"EtaInnerEndcapPartitions",3};
+      Gaudi::Property<int>                m_outerEndcapEtaPartition{this,"EtaOuterEndcapPartitions",3};
+      Gaudi::Property<int>                m_phiPartition{this,"PhiPartitions",16};
+
+      Gaudi::Property<bool>              m_adjustStatic{this,"AdjustStatic",true};
+      Gaudi::Property<bool>              m_static3d{this,"StaticPartition3D",true};
+
+      Gaudi::Property<bool>               m_blendInertMaterial{this,"BlendInertMaterial",false}; 
+      Gaudi::Property<bool>               m_removeBlended{this,"RemoveBlendedMaterialObjects",false};
+      mutable std::atomic_uint            m_inertPerm{0};                  // number of perm objects
+      Gaudi::Property<double>           m_alignTolerance{this,"AlignmentPositionTolerance",0.};
+      Gaudi::Property<int>                m_colorCode{this,"ColorCode",0};
+      Gaudi::Property<int>                  m_activeAdjustLevel{this,"ActiveAdjustLevel",2};
+      Gaudi::Property<int>                  m_inertAdjustLevel{this,"InertAdjustLevel",1};
+
+      mutable std::atomic_uint            m_frameNum{0};      
+      mutable std::atomic_uint            m_frameStat{0};      
+
+      Gaudi::Property<std::string>        m_entryVolume{this,"EntryVolumeName","MuonSpectrometerEntrance"};
+      Gaudi::Property<std::string>        m_exitVolume{this,"ExitVolumeName","All::Container::CompleteDetector"};
+
+      
+      const std::vector<const Trk::DetachedTrackingVolume*>*   m_stations;    // muon chambers 
+      const std::vector<const Trk::DetachedTrackingVolume*>*   m_inertObjs;   // muon inert material 
+      //mutable std::vector<std::pair<std::string,std::pair<double, unsigned int> > >   m_dilFact;
+      //mutable std::vector<Trk::MaterialProperties>               m_matProp;
+      typedef ServiceHandle<IChronoStatSvc> IChronoStatSvc_t;
+      IChronoStatSvc_t m_chronoStatSvc{this,"ChronoStatSvc","ChronoStatSvc","n"};      
+ };
+
+
+} // end of namespace
+
+
+#endif //MUONTRACKINGGEOMETRY_MUONTRACKINGGEOMETRYBUILDER_H
+
+
diff --git a/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryBuilderCond.py b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryBuilderCond.py
new file mode 100644
index 0000000000000000000000000000000000000000..0bbf301939a392bfeaa5a5b18d92eeb21f53a342
--- /dev/null
+++ b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryBuilderCond.py
@@ -0,0 +1,44 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+#####################################################
+# ConfiguredMuonTrackingGeometry module
+#
+# it inherits from MuonTrackingGeometryBuilder and performs 
+# standard configuration
+#
+######################################################
+# import the include statement
+from AthenaCommon.Include import Include, IncludeError, include
+ 
+# import the configurable
+from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonTrackingGeometryBuilderCond
+
+# define the class
+class ConfiguredMuonTrackingGeometryBuilderCond( Muon__MuonTrackingGeometryBuilderCond ):
+    # constructor
+    def __init__(self,name = 'MuonTrackingGeometryBuilderCond'):
+ 
+        from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+
+        # import the ToolSvc
+        from AthenaCommon.AppMgr import ToolSvc
+        if 'ToolSvc' not in dir() :
+            ToolSvc = ToolSvc()
+
+        from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonStationTypeBuilder
+        MuonStationTypeBuilder= Muon__MuonStationTypeBuilder(name = 'MuonStationTypeBuilder')
+
+        ToolSvc += MuonStationTypeBuilder
+
+        # muon active/passive geometry setup
+        from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonStationBuilder
+        MuonStationBuilder= Muon__MuonStationBuilder(name = 'MuonStationBuilder' )
+        ToolSvc += MuonStationBuilder
+
+        from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonInertMaterialBuilder
+        MuonInertMaterialBuilder= Muon__MuonInertMaterialBuilder(name = 'MuonInertMaterialBuilder')
+        ToolSvc += MuonInertMaterialBuilder 
+
+        Muon__MuonTrackingGeometryBuilderCond.__init__(self,name,\
+                                                   EntryVolumeName=TrkDetFlags.MuonSystemEntryVolumeName(),\
+                                                   ExitVolumeName  = TrkDetFlags.MuonSystemContainerName())
diff --git a/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryCond.py b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryCond.py
new file mode 100644
index 0000000000000000000000000000000000000000..c3df82191aa00719e9b081a4629adbcb82e9a3fc
--- /dev/null
+++ b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryCond.py
@@ -0,0 +1,30 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+
+from AthenaCommon.AppMgr import ToolSvc
+
+from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+
+from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonStationTypeBuilder
+MuonStationTypeBuilder= Muon__MuonStationTypeBuilder(name = 'MuonStationTypeBuilder')
+ToolSvc += MuonStationTypeBuilder
+
+# muon active/passive geometry setup
+from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonStationBuilder
+MuonStationBuilder= Muon__MuonStationBuilder(name = 'MuonStationBuilder')
+MuonStationBuilder.StationTypeBuilder = MuonStationTypeBuilder
+ToolSvc += MuonStationBuilder
+
+from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonInertMaterialBuilder
+MuonInertMaterialBuilder= Muon__MuonInertMaterialBuilder(name = 'MuonInertMaterialBuilder')
+ToolSvc += MuonInertMaterialBuilder 
+
+# muon tracking geometry builder
+from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonTrackingGeometryBuilderCond
+MuonTrackingGeometryBuilderCond= Muon__MuonTrackingGeometryBuilderCond(name = 'MuonTrackingGeometryBuilderCond')
+MuonTrackingGeometryBuilderCond.EntryVolumeName = TrkDetFlags.MuonSystemEntryVolumeName()
+MuonTrackingGeometryBuilderCond.ExitVolumeName  = TrkDetFlags.MuonSystemContainerName()
+MuonTrackingGeometryBuilderCond.OutputLevel     = TrkDetFlags.MuonBuildingOutputLevel()
+ToolSvc += MuonTrackingGeometryBuilderCond
+
+#print MuonTrackingGeometryBuilder
diff --git a/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/MuonTrackingGeometryBuilderCond.cxx b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/MuonTrackingGeometryBuilderCond.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4b4dfeb861e7da1ea92326c8a4a702d308468c99
--- /dev/null
+++ b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/MuonTrackingGeometryBuilderCond.cxx
@@ -0,0 +1,2655 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+//////////////////////////////////////////////////////////////////
+// MuonTrackingGeometryBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+// Muon
+#include "MuonTrackingGeometry/MuonTrackingGeometryBuilderCond.h"
+#include "MuonReadoutGeometry/GlobalUtilities.h" 
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// Units
+#include "GaudiKernel/SystemOfUnits.h"
+// Trk
+#include "TrkDetDescrUtils/BinUtility.h"
+#include "TrkDetDescrUtils/BinnedArray.h"
+#include "TrkDetDescrUtils/BinnedArray1D.h"
+#include "TrkDetDescrUtils/BinnedArray2D.h"
+#include "TrkDetDescrUtils/BinnedArray1D1D1D.h"
+#include "TrkDetDescrUtils/GeometryStatics.h"
+#include "TrkDetDescrUtils/SharedObject.h"
+#include "TrkVolumes/CylinderVolumeBounds.h"
+#include "TrkVolumes/TrapezoidVolumeBounds.h"
+#include "TrkVolumes/DoubleTrapezoidVolumeBounds.h"
+#include "TrkVolumes/BevelledCylinderVolumeBounds.h"
+#include "TrkVolumes/CuboidVolumeBounds.h"
+#include "TrkVolumes/SubtractedVolumeBounds.h"
+#include "TrkVolumes/CombinedVolumeBounds.h"
+#include "TrkVolumes/SimplePolygonBrepVolumeBounds.h"
+#include "TrkVolumes/PrismVolumeBounds.h"
+#include "TrkVolumes/BoundarySurface.h"
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkGeometry/TrackingVolume.h"
+#include "TrkGeometry/GlueVolumesDescriptor.h"
+#include "TrkGeometry/Material.h"
+#include<fstream>
+
+// STD
+#include <map>
+
+
+// constructor
+Muon::MuonTrackingGeometryBuilderCond::MuonTrackingGeometryBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  m_bigWheel(15600.),
+  m_outerWheel(21000.),
+  m_ectZ(7920.),
+  m_beamPipeRadius(70.),
+  m_innerShieldRadius(850.),
+  m_outerShieldRadius(1500.),
+  m_diskShieldZ(6915.),
+  m_stations(0),
+  m_inertObjs(0)
+{
+  declareInterface<Trk::IGeometryBuilderCond>(this);
+}
+
+// Athena standard methods
+// initialize
+
+StatusCode Muon::MuonTrackingGeometryBuilderCond::initialize()
+{
+ 
+  // Retrieve the tracking volume helper   -------------------------------------------------    
+  if (m_trackingVolumeHelper.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeHelper );
+      return StatusCode::FAILURE;
+    } else
+    ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeHelper );
+  
+  // Retrieve the tracking volume array creator   -------------------------------------------    
+  if (m_trackingVolumeArrayCreator.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeArrayCreator );
+      return StatusCode::FAILURE;
+    } else
+    ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeArrayCreator );
+  
+  // Retrieve the station builder (if configured) -------------------------------------------    
+  if (m_muonActive) { 
+    
+    if (m_stationBuilder.retrieve().isFailure())
+      {
+	ATH_MSG_ERROR( "Failed to retrieve tool " << m_stationBuilder <<" Creation of stations might fail." );
+      } else
+      ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeArrayCreator );
+  } else {
+    m_activeAdjustLevel = 0;                // no active material to consider
+  }
+  
+  // Retrieve the inert material builder builder (if configured) -------------------------------------------    
+  
+  if (m_muonInert || m_blendInertMaterial) {
+    
+    if (m_inertBuilder.retrieve().isFailure())
+      {
+	ATH_MSG_ERROR( "Failed to retrieve tool " << m_inertBuilder <<"Creation of inert material objects might fail." );
+      } else
+      ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeArrayCreator );
+  }
+  
+  if ( !m_muonInert ) m_inertAdjustLevel = 0;
+  
+  if (m_loadMSentry ) {
+    // retrieve envelope definition service --------------------------------------------------
+    if ( m_enclosingEnvelopeSvc.retrieve().isFailure() ){
+      ATH_MSG_WARNING( "Could not retrieve EnvelopeDefinition service. Using default definition.");
+      m_loadMSentry = false;
+    }
+  }
+
+  // process muon material objects
+  if (m_muonActive && m_stationBuilder && !m_stations) m_stations = m_stationBuilder->buildDetachedTrackingVolumes();
+  if (m_muonInert && m_inertBuilder && !m_inertObjs) m_inertObjs = m_inertBuilder->buildDetachedTrackingVolumes(m_blendInertMaterial);
+
+  if (m_chronoStatSvc.retrieve().isFailure()) {
+    ATH_MSG_WARNING( "Could not retrieve Tool " << m_chronoStatSvc << ". Exiting.");
+  }
+  
+
+  ATH_MSG_INFO( name() <<" initialize() successful" );    
+    
+  return StatusCode::SUCCESS;
+}
+
+
+std::pair<EventIDRange, const Trk::TrackingGeometry*> Muon::MuonTrackingGeometryBuilderCond::trackingGeometry(const EventContext& /*ctx*/, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const
+{
+  ATH_MSG_INFO( name() <<" building tracking geometry" );    
+  m_chronoStatSvc->chronoStart("MS::build-up");
+  //start with range from encapsulated TrackingGeometry if it exists, otherwise infinite range
+  //TODO/FIXME: this range must be intersected with IOV range of the Muon Tracking Geometry
+  EventIDRange range;
+  const Trk::TrackingVolume* tvol = nullptr;
+  if (tVolPair.second != nullptr){
+    range = tVolPair.first;
+    tvol = tVolPair.second;
+  }
+  //load local variables to container
+  LocalVariablesContainer aLVC;
+  aLVC.m_innerBarrelRadius = m_innerBarrelRadius;
+  aLVC.m_outerBarrelRadius = m_outerBarrelRadius;
+  aLVC.m_innerEndcapZ = m_innerEndcapZ;
+  aLVC.m_outerEndcapZ = m_outerEndcapZ;
+  aLVC.m_adjustStatic = m_adjustStatic;
+  aLVC.m_static3d = m_static3d;
+  aLVC.m_blendMap.clear();
+  aLVC.m_blendVols.clear(); 
+  aLVC.m_stationSpan = 0;
+  aLVC.m_inertSpan = 0;
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  // check setup
+  if (m_muonInert && m_blendInertMaterial) {
+    if (!aLVC.m_adjustStatic || !aLVC.m_static3d) {
+      ATH_MSG_INFO( name() <<" diluted inert material hardcoded for 3D volume frame, adjusting setup" );
+      aLVC.m_adjustStatic = true;
+      aLVC.m_static3d = true;
+    }
+  }
+
+  if (m_inertObjs && m_blendInertMaterial && m_removeBlended) {
+    while ( m_inertPerm<m_inertObjs->size() 
+	    && (*m_inertObjs)[m_inertPerm]->name().substr((*m_inertObjs)[m_inertPerm]->name().size()-4,4)=="PERM") m_inertPerm++;
+  }
+  
+  // find object's span with tolerance for the alignment 
+  if (!aLVC.m_stationSpan) aLVC.m_stationSpan = findVolumesSpan(m_stations, 100.*m_alignTolerance, m_alignTolerance*Gaudi::Units::deg,aLVC);
+  if (!aLVC.m_inertSpan)   aLVC.m_inertSpan = findVolumesSpan(m_inertObjs,0.,0.,aLVC);
+ 
+  // 0) Preparation //////////////////////////////////////////////////////////////////////////////////////
+  
+  aLVC.m_muonMaterial = Trk::Material(10e10,10e10,0.,0.,0.);      // default material properties
+    
+  // dummy substructures
+  const Trk::LayerArray* dummyLayers = 0;
+  const Trk::TrackingVolumeArray* dummyVolumes = 0;
+
+
+  ////////////////////////////////////////////////////////////////////////////////////////////////////////
+  //   Envelope definition (cutouts)
+  ////////////////////////////////////////////////////////////////////////////////////////////////////////
+  RZPairVector envelopeDefs;
+  if (m_enclosingEnvelopeSvc) {
+    // get the dimensions from the envelope service
+    RZPairVector& envelopeDefsIn = m_enclosingEnvelopeSvc->getMuonRZValues();
+
+    // find the max,max pair
+    unsigned int ii=0;
+    for (unsigned int i=0; i<envelopeDefsIn.size(); i++) { 
+      if (envelopeDefsIn[i].second>envelopeDefsIn[ii].second) ii=i;
+      else if (envelopeDefsIn[i].second==envelopeDefsIn[ii].second && 
+	       envelopeDefsIn[i].first>envelopeDefsIn[ii].first) ii=i;
+    }  
+
+    // find the sense of rotation
+    int irot=1;
+    unsigned int inext=ii+1;
+    if (inext==envelopeDefsIn.size()) inext=0;
+    if (envelopeDefsIn[inext].second!=envelopeDefsIn[ii].second) {irot=-1; inext = ii>0 ? ii-1:envelopeDefsIn.size()-1 ;}
+    
+    // fill starting with upper low edge, end with upper high edge
+    if (irot>0) {
+      for (unsigned int i=inext; i<envelopeDefsIn.size(); i++) envelopeDefs.push_back(envelopeDefsIn[i]); 
+      if (inext>0) for (unsigned int i=0; i<=inext-1; i++) envelopeDefs.push_back(envelopeDefsIn[i]); 
+    } else {
+      int i=inext;  while (i>=0) {envelopeDefs.push_back(envelopeDefsIn[i]); i=i-1;};
+      inext = envelopeDefsIn.size()-1; while (inext>=ii) {envelopeDefs.push_back(envelopeDefsIn[inext]); inext=inext-1;};
+    } 
+
+    // find maximal z,R extent
+    float maxR = 0.; 
+    for (unsigned int i=0; i<envelopeDefs.size(); i++) {
+      if (envelopeDefs[i].first > maxR )  maxR = envelopeDefs[i].first; 
+    } 
+    
+    aLVC.m_outerBarrelRadius = maxR;
+    aLVC.m_outerEndcapZ      = envelopeDefs[0].second;
+
+    ATH_MSG_VERBOSE( "Muon envelope definition retrieved: outer R,Z:"<<aLVC.m_outerBarrelRadius<<","<< aLVC.m_outerEndcapZ );  
+
+    // construct inner and outer envelope
+    
+    for (unsigned int i=0; i<envelopeDefs.size(); i++) {
+      ATH_MSG_VERBOSE( "Rz pair:"<< i<<":"<< envelopeDefs[i].first<<","<<envelopeDefs[i].second );   
+    }
+
+  }
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+  
+  if (m_muonSimple) {             
+    Trk::VolumeBounds* globalBounds = new Trk::CylinderVolumeBounds(aLVC.m_outerBarrelRadius,
+								    aLVC.m_outerEndcapZ);
+    Trk::TrackingVolume* topVolume = new Trk::TrackingVolume(0,
+							     globalBounds,
+							     aLVC.m_muonMaterial,
+							     dummyLayers,dummyVolumes,
+							     "GlobalVolume");
+    aLVC.m_standaloneTrackingVolume = topVolume;
+    return std::make_pair(range, new Trk::TrackingGeometry(topVolume));
+  }     
+  
+  ATH_MSG_INFO( name() <<"building barrel+innerEndcap+outerEndcap" );    
+  
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MuonSpectrometer contains:
+//       - Barrel
+//       - Endcaps inner/outer
+  const Trk::TrackingVolume* muonBarrel = 0;
+  Trk::CylinderVolumeBounds* barrelBounds = 0;
+  const Trk::TrackingVolume* negativeMuonOuterWheel = 0;
+  Trk::CylinderVolumeBounds* negativeOuterWheelBounds = 0;
+  const Trk::TrackingVolume* negativeMuonBigWheel = 0;
+  Trk::CylinderVolumeBounds* negativeBigWheelBounds = 0;
+  const Trk::TrackingVolume* negativeMuonOuterBuffer = 0;
+  Trk::CylinderVolumeBounds* negativeOuterBufferBounds = 0;
+  const Trk::TrackingVolume* positiveMuonOuterWheel = 0;
+  const Trk::TrackingVolume* negativeMuonSmallWheel = 0;
+  const Trk::TrackingVolume* positiveMuonSmallWheel = 0;
+  Trk::CylinderVolumeBounds* negativeSmallWheelBounds = 0;
+  const Trk::TrackingVolume* negativeECT = 0;
+  const Trk::TrackingVolume* positiveECT = 0;
+  Trk::CylinderVolumeBounds* negativeECTBounds = 0;
+  const Trk::TrackingVolume* positiveMuonBigWheel = 0;
+  const Trk::TrackingVolume* positiveMuonOuterBuffer = 0;
+// volumes needed to close the geometry
+  const Trk::TrackingVolume* negBeamPipe = 0;
+  const Trk::TrackingVolume* posBeamPipe = 0;
+  Trk::CylinderVolumeBounds* negBeamPipeBounds = 0;
+  Trk::CylinderVolumeBounds* posBeamPipeBounds = 0;
+  const Trk::TrackingVolume* enclosed = 0;
+  Trk::CylinderVolumeBounds* enclosedBounds = 0;
+  const Trk::TrackingVolume* negDiskShield = 0;
+  Trk::CylinderVolumeBounds* negDiskShieldBounds = 0;
+  const Trk::TrackingVolume* posDiskShield = 0;
+  Trk::CylinderVolumeBounds* posDiskShieldBounds = 0;
+  const Trk::TrackingVolume* negInnerShield = 0;
+  const Trk::TrackingVolume* posInnerShield = 0;
+  Trk::CylinderVolumeBounds* negInnerShieldBounds = 0;
+  Trk::CylinderVolumeBounds* posInnerShieldBounds = 0;
+  const Trk::TrackingVolume* negOuterShield = 0;
+  const Trk::TrackingVolume* posOuterShield = 0;
+  Trk::CylinderVolumeBounds* negOuterShieldBounds = 0;
+  Trk::CylinderVolumeBounds* posOuterShieldBounds = 0;
+// if input, redefine dimensions to fit expected MS entry 
+  if (tvol){
+    bool msEntryDefined = false;
+    if ( tvol->volumeName() == m_entryVolume ) msEntryDefined = true; 
+    // get dimensions
+    ATH_MSG_DEBUG(" msEntryDefined " << msEntryDefined);
+    const Trk::CylinderVolumeBounds* enclosedDetectorBounds 
+      = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(tvol->volumeBounds()));
+    if (!enclosedDetectorBounds) {    
+      ATH_MSG_ERROR(" dynamic cast of enclosed volume to the cylinder bounds failed, aborting MTG build-up ");
+      return std::pair<EventIDRange, const Trk::TrackingGeometry*>(range, nullptr);
+    }
+    double enclosedDetectorHalfZ = enclosedDetectorBounds->halflengthZ();
+    double enclosedDetectorOuterRadius = enclosedDetectorBounds->outerRadius();
+    // get subvolumes at navigation level and check THEIR dimensions      
+    const Trk::GlueVolumesDescriptor& enclosedDetGlueVolumes = tvol->glueVolumesDescriptor();
+    std::vector<const Trk::TrackingVolume*> enclosedCentralFaceVolumes = enclosedDetGlueVolumes.glueVolumes(Trk::cylinderCover);
+    std::vector<const Trk::TrackingVolume*> enclosedNegativeFaceVolumes = enclosedDetGlueVolumes.glueVolumes(Trk::negativeFaceXY);
+    std::vector<const Trk::TrackingVolume*> enclosedPositiveFaceVolumes = enclosedDetGlueVolumes.glueVolumes(Trk::positiveFaceXY);
+    if (enclosedCentralFaceVolumes.size()) {
+      const Trk::CylinderVolumeBounds* cylR = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(enclosedCentralFaceVolumes[0]->volumeBounds()));
+      if (cylR && cylR->outerRadius() != enclosedDetectorOuterRadius ) {
+        enclosedDetectorOuterRadius = cylR->outerRadius();
+        ATH_MSG_WARNING(name() << " enclosed volume envelope outer radius does not correspond to radius of glue volumes : adjusted " );
+      }
+    }
+    if (enclosedNegativeFaceVolumes.size() && enclosedPositiveFaceVolumes.size()) {
+      double negZ = -enclosedDetectorHalfZ;
+      double posZ =  enclosedDetectorHalfZ;
+      const Trk::CylinderVolumeBounds* cylN = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(enclosedNegativeFaceVolumes[0]->volumeBounds()));
+      if (cylN) negZ = enclosedNegativeFaceVolumes[0]->center()[2]-cylN->halflengthZ();
+      const Trk::CylinderVolumeBounds* cylP = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(enclosedPositiveFaceVolumes[0]->volumeBounds()));
+      if (cylP) posZ = enclosedPositiveFaceVolumes[0]->center()[2]+cylP->halflengthZ();
+      if ( fabs(negZ+enclosedDetectorHalfZ)>0.001 ||  fabs(posZ-enclosedDetectorHalfZ)>0.001 ) {
+	ATH_MSG_WARNING( name() << " enclosed volume envelope z dimension does not correspond to that of glue volumes " );
+        if ( fabs(negZ+posZ)<0.001) {
+          enclosedDetectorHalfZ = posZ;
+          ATH_MSG_WARNING( name() << " z adjusted " );
+	} else {
+	  ATH_MSG_ERROR( name() << "assymetric Z dimensions - cannot recover "<< negZ <<","<< posZ );
+          return std::pair<EventIDRange, const Trk::TrackingGeometry*>(range, nullptr);
+	}
+     }
+    }
+    //
+    
+
+    // 
+    ATH_MSG_INFO( name() <<" dimensions of enclosed detectors (halfZ,outerR):"
+	<<  enclosedDetectorHalfZ<<","<< enclosedDetectorOuterRadius );    
+    // check if input makes sense - gives warning if cuts into muon envelope
+    // adjust radius
+    const Trk::TrackingVolume* barrelR = 0;
+    if ( enclosedDetectorOuterRadius > aLVC.m_innerBarrelRadius ) {
+      ATH_MSG_WARNING( name() <<" enclosed volume too wide, cuts into muon envelope, abandon :R:" <<enclosedDetectorOuterRadius );
+      return std::pair<EventIDRange, const Trk::TrackingGeometry*>(range, nullptr);   
+    } else { 
+      aLVC.m_innerBarrelRadius = enclosedDetectorOuterRadius;
+      barrelR = tvol;      
+    }
+    // adjust z
+    if ( enclosedDetectorHalfZ > m_barrelZ ) {
+      ATH_MSG_WARNING( name() <<" enclosed volume too long, cuts into muon envelope, abandon :Z:"<< enclosedDetectorHalfZ );    
+      return std::pair<EventIDRange, const Trk::TrackingGeometry*>(range, nullptr);
+    } else {    
+      if ( enclosedDetectorHalfZ < m_barrelZ ) {
+	Trk::CylinderVolumeBounds* barrelZPBounds = new Trk::CylinderVolumeBounds(aLVC.m_innerBarrelRadius,
+										 0.5*(m_barrelZ - enclosedDetectorHalfZ) );
+	Trk::CylinderVolumeBounds* barrelZMBounds = new Trk::CylinderVolumeBounds(aLVC.m_innerBarrelRadius,
+										 0.5*(m_barrelZ - enclosedDetectorHalfZ) );
+	double zbShift =  0.5*(m_barrelZ + enclosedDetectorHalfZ);
+	const Trk::TrackingVolume* barrelZPBuffer = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,zbShift))),
+									    barrelZPBounds,
+									    aLVC.m_muonMaterial,
+									    dummyLayers,dummyVolumes,
+									    "BarrelRZPosBuffer");
+	const Trk::TrackingVolume* barrelZMBuffer = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-zbShift))),
+									    barrelZMBounds,
+									    aLVC.m_muonMaterial,
+									    dummyLayers,dummyVolumes,
+									    "BarrelRZNegBuffer");
+	
+	ATH_MSG_INFO( name() << "glue barrel R  + barrel Z buffer" );
+	const Trk::TrackingVolume* barrelZP = m_trackingVolumeHelper->glueTrackingVolumeArrays(*barrelR, Trk::positiveFaceXY,
+											       *barrelZPBuffer,Trk::negativeFaceXY, 
+											       "All::Gaps::BarrelZP");    
+        // set name
+	std::string nameEncl = msEntryDefined ? "All::Gaps::Barrel" : m_entryVolume ;
+        ATH_MSG_DEBUG( " nameEncl " << nameEncl);
+	enclosed = m_trackingVolumeHelper->glueTrackingVolumeArrays(*barrelZP, Trk::negativeFaceXY,
+								    *barrelZMBuffer,Trk::positiveFaceXY, 
+								    nameEncl);    
+ 
+      } else enclosed = barrelR;
+      // ST the following simplification forces MuonSpectrometerEntrance to coincide with Calo::Container
+      //m_barrelZ = enclosedDetectorHalfZ;
+      //enclosed = barrelR;      
+    }
+    
+  } else {     // no input, create the enclosed volume
+    if (m_loadMSentry && m_enclosingEnvelopeSvc ) {
+      RZPairVector& envelopeDefs = m_enclosingEnvelopeSvc->getCaloRZValues();
+      // to be implemented in detail - for the moment, take just maximal extent
+      ATH_MSG_DEBUG( " m_loadMSentry " << m_loadMSentry << " m_enclosingEnvelopeSvc " << m_enclosingEnvelopeSvc );
+      double rmax = 0.; double zmax = 0.;
+      for (unsigned int i=0; i<envelopeDefs.size(); i++) { 
+	if ( envelopeDefs[i].first>rmax ) rmax= envelopeDefs[i].first;
+	if ( fabs(envelopeDefs[i].second)>zmax ) zmax= fabs(envelopeDefs[i].second);
+      }
+      if (envelopeDefs.size()) {
+        if ( rmax>0. && rmax <= aLVC.m_innerBarrelRadius && zmax>0. && zmax <= m_barrelZ ) {
+	  enclosedBounds = new Trk::CylinderVolumeBounds(rmax,zmax);
+	} else {
+	  ATH_MSG_INFO( name() << " input MSEntrance size (R,Z:"<< rmax <<","<<zmax<<") clashes with MS material, switch to default values (R,Z:" << aLVC.m_innerBarrelRadius <<","<< m_barrelZ << ")" );
+	}
+      }
+    }
+    
+    if (!enclosedBounds) enclosedBounds = new Trk::CylinderVolumeBounds(aLVC.m_innerBarrelRadius,
+									m_barrelZ);
+    enclosed = new Trk::TrackingVolume(0,
+				       enclosedBounds,
+				       aLVC.m_muonMaterial,
+				       dummyLayers,dummyVolumes,
+				       m_entryVolume);
+    enclosed->registerColorCode(0); 
+    ATH_MSG_DEBUG( " register Barrel m_entryVolume " << m_entryVolume);
+  }
+
+  // construct inner and outer envelope
+    
+  for (unsigned int i=0; i<envelopeDefs.size(); i++) {
+    //ATH_MSG_VERBOSE( "Rz pair:"<< i<<":"<< envelopeDefs[i].first<<","<<envelopeDefs[i].second );   
+    if (aLVC.m_msCutoutsIn.size() && aLVC.m_msCutoutsIn.back().second== -aLVC.m_outerEndcapZ) break;
+    if ( !aLVC.m_msCutoutsIn.size() || fabs(aLVC.m_msCutoutsIn.back().second) > m_barrelZ
+	 || fabs(envelopeDefs[i].second)> m_barrelZ ) aLVC.m_msCutoutsIn.push_back(envelopeDefs[i]); 
+    else if (aLVC.m_msCutoutsIn.size() && aLVC.m_msCutoutsIn.back().second==m_barrelZ && aLVC.m_msCutoutsIn.back().first!=aLVC.m_innerBarrelRadius) {
+      aLVC.m_msCutoutsIn.push_back(RZPair(aLVC.m_innerBarrelRadius,m_barrelZ));
+      aLVC.m_msCutoutsIn.push_back(RZPair(aLVC.m_innerBarrelRadius,-m_barrelZ));
+      aLVC.m_msCutoutsIn.push_back(RZPair(aLVC.m_msCutoutsIn[aLVC.m_msCutoutsIn.size()-3].first,-m_barrelZ));
+    }
+  }
+
+  unsigned int il=1; 
+  while (envelopeDefs[il-1].second!=-aLVC.m_outerEndcapZ) il++;
+  for ( ; il<envelopeDefs.size(); il++)  aLVC.m_msCutoutsOut.push_back(envelopeDefs[il]); 
+
+  for (unsigned int i=0; i<aLVC.m_msCutoutsIn.size(); i++) {
+    ATH_MSG_VERBOSE( "Rz pair for inner MS envelope:"<< i<<":"<< aLVC.m_msCutoutsIn[i].first<<","<<aLVC.m_msCutoutsIn[i].second );   
+  }
+  for (unsigned int i=0; i<aLVC.m_msCutoutsOut.size(); i++) {
+    ATH_MSG_VERBOSE( "Rz pair for outer MS envelope:"<< i<<":"<< aLVC.m_msCutoutsOut[i].first<<","<<aLVC.m_msCutoutsOut[i].second );   
+  }
+
+  if ( aLVC.m_msCutoutsIn[5].second != aLVC.m_innerEndcapZ) {
+    aLVC.m_innerEndcapZ = aLVC.m_msCutoutsIn[5].second;
+  }
+  ATH_MSG_VERBOSE( "inner endcap Z set to:"<< aLVC.m_innerEndcapZ );   
+  
+  // create central volume ("enclosed" + disk shields ) - this is to allow safe gluing with 3D MS binning
+  getShieldParts(aLVC);
+  
+  negDiskShieldBounds = new Trk::CylinderVolumeBounds(aLVC.m_innerBarrelRadius,
+						      0.5*(m_diskShieldZ - m_barrelZ) );
+  Amg::Vector3D negDiskShieldPosition(0.,0.,-0.5*(m_diskShieldZ+m_barrelZ));
+  Trk::Volume negDiskVol(new Amg::Transform3D(Amg::Translation3D(negDiskShieldPosition)),negDiskShieldBounds);
+  negDiskShield = processShield(&negDiskVol,2,"Muons::Detectors::NegativeDiskShield",aLVC);
+
+  posDiskShieldBounds = new Trk::CylinderVolumeBounds(aLVC.m_innerBarrelRadius,
+						      0.5*(m_diskShieldZ - m_barrelZ) );
+  Amg::Vector3D posDiskShieldPosition(0.,0., 0.5*(m_diskShieldZ+m_barrelZ));
+  Trk::Volume posDiskVol(new Amg::Transform3D(Amg::Translation3D(posDiskShieldPosition)),posDiskShieldBounds);
+  posDiskShield = processShield(&posDiskVol,2,"Muons::Detectors::PositiveDiskShield",aLVC);
+	   
+  ATH_MSG_INFO( name() << "glue enclosed  + disk shields" );
+  const Trk::TrackingVolume* centralP = m_trackingVolumeHelper->glueTrackingVolumeArrays(*enclosed, Trk::positiveFaceXY,
+											 *posDiskShield,Trk::negativeFaceXY, 
+											 "Muon::Container::CentralP");    
+  const Trk::TrackingVolume* central  = m_trackingVolumeHelper->glueTrackingVolumeArrays(*centralP, Trk::negativeFaceXY,
+											 *negDiskShield,Trk::positiveFaceXY, 
+											 "Muon::Container::Central");    
+  
+// define basic volumes
+  if (aLVC.m_adjustStatic) { getZParts(aLVC); getHParts(aLVC);}
+
+// muon barrel
+  barrelBounds = new Trk::CylinderVolumeBounds(aLVC.m_innerBarrelRadius,
+					       aLVC.m_outerBarrelRadius,
+					       m_diskShieldZ);
+  Trk::Volume barrelVol(0,barrelBounds);
+// process volume
+// barrel
+  if (aLVC.m_adjustStatic && aLVC.m_static3d) muonBarrel = processVolume( &barrelVol,0,"Muon::Detectors::Barrel",aLVC); 
+  else if (aLVC.m_adjustStatic) muonBarrel = processVolume( &barrelVol,-1,"Muon::Detectors::Barrel",aLVC); 
+  else muonBarrel = processVolume( &barrelVol,m_barrelEtaPartition,m_phiPartition,"Muon::Detectors::Barrel",aLVC); 
+// inner Endcap
+// build as smallWheel+ECT
+// small wheel
+   double smallWheelZHalfSize = 0.5*(m_ectZ - m_diskShieldZ);
+   negativeSmallWheelBounds = new Trk::CylinderVolumeBounds(m_innerShieldRadius,
+							    aLVC.m_outerBarrelRadius,
+							    smallWheelZHalfSize);
+   Amg::Vector3D negSmallWheelPosition(0.,0.,-m_ectZ+smallWheelZHalfSize);
+   Amg::Transform3D* negSmallWheelTransf = new Amg::Transform3D(Amg::Translation3D(negSmallWheelPosition));
+   Trk::Volume negSWVol(negSmallWheelTransf,negativeSmallWheelBounds);
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) negativeMuonSmallWheel = processVolume( &negSWVol,1,"Muon::Detectors::NegativeSmallWheel",aLVC ); 
+   else if (aLVC.m_adjustStatic) negativeMuonSmallWheel = processVolume( &negSWVol,-1,"Muon::Detectors::NegativeSmallWheel" ,aLVC); 
+   else negativeMuonSmallWheel = processVolume( &negSWVol,m_innerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::NegativeSmallWheel" ,aLVC); 
+   //checkVolume(negativeMuonSmallWheel);
+   //
+   Amg::Vector3D posSmallWheelShift(0.,0.,2*(m_ectZ-smallWheelZHalfSize));
+   Trk::Volume posSWVol(negSWVol,Amg::Transform3D(Amg::Translation3D(posSmallWheelShift)));
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) positiveMuonSmallWheel = processVolume( &posSWVol,1,"Muon::Detectors::PositiveSmallWheel" ,aLVC); 
+   else if (aLVC.m_adjustStatic) positiveMuonSmallWheel = processVolume( &posSWVol,-1,"Muon::Detectors::PositiveSmallWheel" ,aLVC); 
+   else positiveMuonSmallWheel = processVolume( &posSWVol,m_innerEndcapEtaPartition,m_phiPartition,
+						 "Muon::Detectors::PositiveSmallWheel" ,aLVC); 
+   //checkVolume(positiveMuonSmallWheel);
+// ECT
+   double ectZHalfSize = 0.5*(aLVC.m_innerEndcapZ - m_ectZ);
+   negativeECTBounds = new Trk::CylinderVolumeBounds(m_innerShieldRadius,
+						     aLVC.m_outerBarrelRadius,
+						     ectZHalfSize);
+   Amg::Vector3D negECTPosition(0.,0.,-m_ectZ-ectZHalfSize);
+   Amg::Transform3D* negECTTransf = new Amg::Transform3D(Amg::Translation3D(negECTPosition));
+   Trk::Volume negECTVol(negECTTransf,negativeECTBounds);
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) negativeECT = processVolume( &negECTVol,2,"Muon::Detectors::NegativeECT" ,aLVC); 
+   else if (aLVC.m_adjustStatic) negativeECT = processVolume( &negECTVol,-1,"Muon::Detectors::NegativeECT" ,aLVC); 
+   else negativeECT = processVolume( &negECTVol,m_innerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::NegativeECT" ,aLVC); 
+   //checkVolume(negativeECT);
+   //
+   Amg::Vector3D posECTShift(0.,0.,2*(m_ectZ+ectZHalfSize));
+   Trk::Volume posECTVol(negECTVol,Amg::Transform3D(Amg::Translation3D(posECTShift)));
+   if (aLVC.m_adjustStatic && m_static3d) positiveECT = processVolume( &posECTVol,2,"Muon::Detectors::PositiveECT" ,aLVC); 
+   else if (aLVC.m_adjustStatic) positiveECT = processVolume( &posECTVol,-1,"Muon::Detectors::PositiveECT" ,aLVC); 
+   else positiveECT = processVolume( &posECTVol,m_innerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::PositiveECT" ,aLVC); 
+   //checkVolume(positiveECT);
+   // glue
+   const Trk::TrackingVolume* negativeMuonInnerEndcap =
+     m_trackingVolumeHelper->glueTrackingVolumeArrays(*negativeECT, Trk::positiveFaceXY,
+						      *negativeMuonSmallWheel, Trk::negativeFaceXY, 
+						      "Muon::Container::NegInnerEndcap");  
+   const Trk::TrackingVolume* positiveMuonInnerEndcap = 
+     m_trackingVolumeHelper->glueTrackingVolumeArrays(*positiveMuonSmallWheel, Trk::positiveFaceXY,
+						      *positiveECT, Trk::negativeFaceXY,
+						      "Muon::Container::PosInnerEndcap");  
+   
+// inner shields   
+   double innerEndcapZHalfSize = 0.5*(aLVC.m_innerEndcapZ - m_diskShieldZ);
+   negInnerShieldBounds = new Trk::CylinderVolumeBounds(m_beamPipeRadius,
+							m_innerShieldRadius,
+							innerEndcapZHalfSize);
+   Amg::Vector3D negInnerEndcapPosition(0.,0.,-m_diskShieldZ-innerEndcapZHalfSize);
+   Trk::Volume negisVol(new Amg::Transform3D(Amg::Translation3D(negInnerEndcapPosition)),negInnerShieldBounds);
+   negInnerShield = processShield(&negisVol,1,"Muons::Detectors::NegativeInnerShield",aLVC);
+
+   posInnerShieldBounds = new Trk::CylinderVolumeBounds(m_beamPipeRadius,
+							m_innerShieldRadius,
+							innerEndcapZHalfSize);
+   Amg::Vector3D posInnerEndcapPosition(0.,0.,m_diskShieldZ+innerEndcapZHalfSize);
+   Trk::Volume posisVol(new Amg::Transform3D(Amg::Translation3D(posInnerEndcapPosition)),posInnerShieldBounds);
+   posInnerShield = processShield(&posisVol,1,"Muons::Detectors::PositiveInnerShield",aLVC);
+
+// outer Endcap
+// build as bigWheel+buffer+outerWheel
+// outer wheel
+   double outerWheelZHalfSize = 0.5*(aLVC.m_outerEndcapZ - m_outerWheel);
+   negativeOuterWheelBounds = new Trk::CylinderVolumeBounds(m_outerShieldRadius,
+							    aLVC.m_outerBarrelRadius,
+							    outerWheelZHalfSize);
+   Amg::Vector3D negOuterWheelPosition(0.,0.,-aLVC.m_outerEndcapZ+outerWheelZHalfSize);
+   Amg::Transform3D* negOuterWheelTransf = new Amg::Transform3D(Amg::Translation3D(negOuterWheelPosition));
+   Trk::Volume negOWVol(negOuterWheelTransf,negativeOuterWheelBounds);
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) negativeMuonOuterWheel = processVolume( &negOWVol,3,"Muon::Detectors::NegativeOuterWheel" ,aLVC); 
+   else if (aLVC.m_adjustStatic) negativeMuonOuterWheel = processVolume( &negOWVol,-1,"Muon::Detectors::NegativeOuterWheel" ,aLVC); 
+   else negativeMuonOuterWheel = processVolume( &negOWVol,m_outerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::NegativeOuterWheel" ,aLVC); 
+   //
+   Amg::Vector3D posOuterWheelShift(0.,0.,2*(aLVC.m_outerEndcapZ-outerWheelZHalfSize));
+   Trk::Volume posOWVol(negOWVol,Amg::Transform3D(Amg::Translation3D(posOuterWheelShift)));
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) positiveMuonOuterWheel = processVolume( &posOWVol,3,"Muon::Detectors::PositiveOuterWheel" ,aLVC); 
+   else if (aLVC.m_adjustStatic) positiveMuonOuterWheel = processVolume( &posOWVol,-1,"Muon::Detectors::PositiveOuterWheel" ,aLVC); 
+   else positiveMuonOuterWheel = processVolume( &posOWVol,m_outerEndcapEtaPartition,m_phiPartition,
+						 "Muon::Detectors::PositiveOuterWheel" ,aLVC); 
+// outer buffer
+   double outerBufferZHalfSize = 0.5*(m_outerWheel - m_bigWheel);
+   negativeOuterBufferBounds = new Trk::CylinderVolumeBounds(m_outerShieldRadius,
+							     aLVC.m_outerBarrelRadius,
+							     outerBufferZHalfSize);
+   Amg::Vector3D negOuterBufferPosition(0.,0.,-m_bigWheel-outerBufferZHalfSize);
+   Amg::Transform3D* negOuterBufferTransf = new Amg::Transform3D(Amg::Translation3D(negOuterBufferPosition));
+   Trk::Volume negBuffVol(negOuterBufferTransf,negativeOuterBufferBounds);
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) negativeMuonOuterBuffer = processVolume( &negBuffVol,3,"Muon::Detectors::NegativeOuterBuffer" ,aLVC); 
+   else if (aLVC.m_adjustStatic) negativeMuonOuterBuffer = processVolume( &negBuffVol,-1,"Muon::Detectors::NegativeOuterBuffer" ,aLVC); 
+   else negativeMuonOuterBuffer = processVolume( &negBuffVol,m_outerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::NegativeOuterBuffer" ,aLVC); 
+   //
+   Amg::Vector3D posOuterBufferShift(0.,0.,2*(m_bigWheel+outerBufferZHalfSize));
+   Trk::Volume posBuffVol(negBuffVol,Amg::Transform3D(Amg::Translation3D(posOuterBufferShift)));
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) positiveMuonOuterBuffer = processVolume( &posBuffVol,3,"Muon::Detectors::PositiveOuterBuffer" ,aLVC); 
+   else if (aLVC.m_adjustStatic) positiveMuonOuterBuffer = processVolume( &posBuffVol,-1,"Muon::Detectors::PositiveOuterBuffer" ,aLVC); 
+   else positiveMuonOuterBuffer = processVolume( &posBuffVol,m_outerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::PositiveOuterBuffer" ,aLVC); 
+// big wheel
+   double bigWheelZHalfSize = 0.5*(m_bigWheel - aLVC.m_innerEndcapZ);
+   negativeBigWheelBounds = new Trk::CylinderVolumeBounds(m_outerShieldRadius,
+							  aLVC.m_outerBarrelRadius,
+							  bigWheelZHalfSize);
+   Amg::Vector3D negBigWheelPosition(0.,0.,-aLVC.m_innerEndcapZ-bigWheelZHalfSize);
+   Amg::Transform3D* negBigWheelTransf = new Amg::Transform3D(Amg::Translation3D(negBigWheelPosition));
+   Trk::Volume negBWVol(negBigWheelTransf,negativeBigWheelBounds);
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) negativeMuonBigWheel = processVolume( &negBWVol,3,"Muon::Detectors::NegativeBigWheel" ,aLVC); 
+   else if (aLVC.m_adjustStatic) negativeMuonBigWheel = processVolume( &negBWVol,-1,"Muon::Detectors::NegativeBigWheel" ,aLVC); 
+   else negativeMuonBigWheel = processVolume( &negBWVol,m_outerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::NegativeBigWheel" ,aLVC); 
+   //
+   Amg::Vector3D posBigWheelShift(0.,0.,2*(aLVC.m_innerEndcapZ+bigWheelZHalfSize));
+   Trk::Volume posBWVol(negBWVol,Amg::Transform3D(Amg::Translation3D(posBigWheelShift)));
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) positiveMuonBigWheel = processVolume( &posBWVol,3,"Muon::Detectors::PositiveBigWheel" ,aLVC); 
+   else if (aLVC.m_adjustStatic) positiveMuonBigWheel = processVolume( &posBWVol,-1,"Muon::Detectors::PositiveBigWheel" ,aLVC); 
+   else positiveMuonBigWheel = processVolume( &posBWVol,m_outerEndcapEtaPartition,m_phiPartition,
+						 "Muon::Detectors::PositiveBigWheel" ,aLVC); 
+// glue
+   const Trk::TrackingVolume* negNavOEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*negativeMuonOuterWheel, Trk::positiveFaceXY,
+											       *negativeMuonOuterBuffer, Trk::negativeFaceXY, 
+											       "Muon::Container::NegOEndcap");  
+   const Trk::TrackingVolume* posNavOEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*positiveMuonOuterBuffer, Trk::positiveFaceXY,
+											       *positiveMuonOuterWheel, Trk::negativeFaceXY,
+											       "Muon::Container::PosOEndcap");  
+   const Trk::TrackingVolume* negativeMuonOuterEndcap =
+     m_trackingVolumeHelper->glueTrackingVolumeArrays(*negNavOEndcap, Trk::positiveFaceXY,
+						      *negativeMuonBigWheel, Trk::negativeFaceXY, 
+						      "Muon::Container::NegOuterEndcap");  
+   const Trk::TrackingVolume* positiveMuonOuterEndcap =
+     m_trackingVolumeHelper->glueTrackingVolumeArrays(*positiveMuonBigWheel, Trk::positiveFaceXY, 
+						      *posNavOEndcap, Trk::negativeFaceXY,
+						      "Muon::Container::PosOuterEndcap");  
+
+// outer shields   
+   double outerEndcapZHalfSize = 0.5*(aLVC.m_outerEndcapZ-aLVC.m_innerEndcapZ);
+   double outerEndcapPosition  = 0.5*(aLVC.m_outerEndcapZ+aLVC.m_innerEndcapZ);
+   Amg::Vector3D negOuterShieldPosition(0.,0.,-outerEndcapPosition);
+   negOuterShieldBounds = new Trk::CylinderVolumeBounds(m_beamPipeRadius,
+							m_outerShieldRadius,
+							outerEndcapZHalfSize);
+   Trk::Volume negosVol(new Amg::Transform3D(Amg::Translation3D(negOuterShieldPosition)),negOuterShieldBounds);
+   negOuterShield = processShield(&negosVol,0,"Muons::Detectors::NegativeOuterShield",aLVC);
+
+   posOuterShieldBounds = new Trk::CylinderVolumeBounds(m_beamPipeRadius,
+							m_outerShieldRadius,
+							outerEndcapZHalfSize);
+   Amg::Vector3D posOuterShieldPosition(0.,0.,outerEndcapPosition);
+   Trk::Volume pososVol(new Amg::Transform3D(Amg::Translation3D(posOuterShieldPosition)),posOuterShieldBounds);
+   posOuterShield = processShield(&pososVol,0,"Muons::Detectors::PositiveOuterShield",aLVC);
+
+// beamPipe
+   negBeamPipeBounds = new Trk::CylinderVolumeBounds(m_beamPipeRadius,
+                                                  outerEndcapZHalfSize+innerEndcapZHalfSize);
+   posBeamPipeBounds = new Trk::CylinderVolumeBounds(m_beamPipeRadius,
+                                                  outerEndcapZHalfSize+innerEndcapZHalfSize);
+   Amg::Vector3D posBeamPipePosition(0.,0., aLVC.m_outerEndcapZ-innerEndcapZHalfSize-outerEndcapZHalfSize);
+   Amg::Vector3D negBeamPipePosition(0.,0.,-aLVC.m_outerEndcapZ+innerEndcapZHalfSize+outerEndcapZHalfSize);
+   Trk::Volume negbpVol(new Amg::Transform3D(Amg::Translation3D(negBeamPipePosition)),negBeamPipeBounds);
+   negBeamPipe = processVolume(&negbpVol,1,1,"Muons::Gaps::NegativeBeamPipe",aLVC);
+   Trk::Volume posbpVol(new Amg::Transform3D(Amg::Translation3D(posBeamPipePosition)),posBeamPipeBounds);
+   posBeamPipe = processVolume(&posbpVol,1,1,"Muons::Gaps::PositiveBeamPipe",aLVC);
+
+   negBeamPipe->registerColorCode(0); 
+   posBeamPipe->registerColorCode(0); 
+
+   ATH_MSG_INFO( name() <<" volumes defined " );    
+//
+// glue volumes at navigation level, create enveloping volume 
+// radially
+// central + barrel
+   ATH_MSG_INFO( name() << "glue barrel+enclosed volumes" );
+   const Trk::TrackingVolume* barrel = m_trackingVolumeHelper->glueTrackingVolumeArrays(*muonBarrel,Trk::tubeInnerCover,
+											*central, Trk::cylinderCover, 
+                                                                                        "All::Container::Barrel");
+   //checkVolume(barrel);
+// shield+outerEndcap
+   ATH_MSG_INFO( name() << "glue shield+outerEndcap" );
+   const Trk::TrackingVolume* negOuterEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*negativeMuonOuterEndcap, Trk::tubeInnerCover,
+												*negOuterShield, Trk::tubeOuterCover,
+												"Muon::Container::NegativeOuterEndcap");
+   //checkVolume(negOuterEndcap);
+   const Trk::TrackingVolume* posOuterEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*positiveMuonOuterEndcap, Trk::tubeInnerCover,
+												*posOuterShield,Trk::tubeOuterCover,
+												"Muon::Container::PositiveOuterEndcap");
+   //checkVolume(posOuterEndcap);
+// shield+innerEndcap
+   ATH_MSG_INFO( name() << "glue shield+innerEndcap" );
+   const Trk::TrackingVolume* negInnerEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*negativeMuonInnerEndcap, Trk::tubeInnerCover,
+												*negInnerShield, Trk::tubeOuterCover,
+												"Muon::Container::NegativeInnerEndcap");
+   //checkVolume(negInnerEndcap);
+   const Trk::TrackingVolume* posInnerEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*positiveMuonInnerEndcap, Trk::tubeInnerCover,
+												*posInnerShield,Trk::tubeOuterCover,
+												"Muon::Container::PositiveInnerEndcap");
+   //checkVolume(posInnerEndcap);
+// inner+outerEndcap
+   ATH_MSG_INFO( name() << "glue inner+outerEndcap" );
+   const Trk::TrackingVolume* negNavEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*negOuterEndcap, Trk::positiveFaceXY,
+											      *negInnerEndcap, Trk::negativeFaceXY, 
+											      "Muon::Container::NegativeEndcap");  
+   const Trk::TrackingVolume* posNavEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*posInnerEndcap, Trk::positiveFaceXY,
+											      *posOuterEndcap, Trk::negativeFaceXY,
+											      "Muon::Container::PositiveEndcap");  
+   //checkVolume(negNavEndcap);
+   //checkVolume(posNavEndcap);
+// beam pipe + endcaps
+   ATH_MSG_INFO( name() << "glue beamPipe+endcaps" );
+   const Trk::TrackingVolume* negEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*negNavEndcap, Trk::tubeInnerCover,
+											   *negBeamPipe, Trk::cylinderCover,
+										           "All::Container::NegativeEndcap");  
+   const Trk::TrackingVolume* posEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*posNavEndcap, Trk::tubeInnerCover,
+											   *posBeamPipe, Trk::cylinderCover,
+										           "All::Container::PositiveEndcap");  
+   //checkVolume(negEndcap);
+   //checkVolume(posEndcap);
+// barrel + endcaps
+   ATH_MSG_INFO( name() << "glue barrel+endcaps" );
+
+   const Trk::TrackingVolume* negDet = m_trackingVolumeHelper->glueTrackingVolumeArrays(*negEndcap, Trk::positiveFaceXY,
+                                                                                        *barrel, Trk::negativeFaceXY, 
+									                "All::Container::NegDet");  
+   const Trk::TrackingVolume* detector = m_trackingVolumeHelper->glueTrackingVolumeArrays(*posEndcap, Trk::negativeFaceXY, 
+											  *negDet, Trk::positiveFaceXY,
+											  m_exitVolume);
+// blend material
+   if (m_blendInertMaterial) blendMaterial(aLVC);
+
+// tracking geometry 
+   Trk::TrackingGeometry* trackingGeometry = new Trk::TrackingGeometry(detector,Trk::globalSearch);
+
+// clean-up
+   if (aLVC.m_stationSpan) {
+     for (size_t i = 0; i < aLVC.m_stationSpan->size(); i++)
+       delete (*aLVC.m_stationSpan)[i];
+     delete aLVC.m_stationSpan; aLVC.m_stationSpan = 0;
+   }
+   if (aLVC.m_inertSpan) {
+     for (size_t i = 0; i < aLVC.m_inertSpan->size(); i++)
+       delete (*aLVC.m_inertSpan)[i];
+     delete aLVC.m_inertSpan; aLVC.m_inertSpan = 0;
+   }
+   
+   for (size_t i = 0; i < aLVC.m_spans.size(); i++) delete aLVC.m_spans[i];
+   
+   for (std::map<const Trk::DetachedTrackingVolume*,std::vector<const Trk::TrackingVolume*>* >::iterator it = aLVC.m_blendMap.begin();
+	it != aLVC.m_blendMap.end();
+	++it)
+     {
+       delete it->second;
+     }   
+
+   m_chronoStatSvc->chronoStop("MS::build-up");
+
+   ATH_MSG_INFO( name() <<" returning tracking geometry " );    
+   ATH_MSG_INFO( name() <<" with "<< m_frameNum<<" subvolumes at navigation level" );    
+   ATH_MSG_INFO( name() <<"( mean number of enclosed detached volumes:"<< float(m_frameStat)/m_frameNum<<")" );    
+   return std::make_pair(range, trackingGeometry);  
+}
+
+// finalize
+StatusCode Muon::MuonTrackingGeometryBuilderCond::finalize()
+{
+    if (m_stations) {
+      for (size_t i = 0; i < m_stations->size(); i++) {
+	if ((*m_stations)[i]) delete (*m_stations)[i];
+        else ATH_MSG_DEBUG( name() << " station pointer corrupted ! " ); 
+      }
+      delete m_stations; m_stations = 0;
+    } 
+    if (m_inertObjs) {
+      unsigned int inLim = (m_blendInertMaterial && m_removeBlended) ? (unsigned int)m_inertPerm : m_inertObjs->size();
+      for (size_t i = 0; i < inLim; i++) {
+	if ((*m_inertObjs)[i])	delete (*m_inertObjs)[i];
+        else ATH_MSG_DEBUG( name() << " inert object pointer corrupted ! " ); 
+      }
+      delete m_inertObjs; m_inertObjs = 0;
+    } 
+
+    m_chronoStatSvc->chronoPrint("MS::build-up");
+
+    ATH_MSG_INFO( name() <<" finalize() successful" );
+    return StatusCode::SUCCESS;
+}
+const Muon::Span* Muon::MuonTrackingGeometryBuilderCond::findVolumeSpan(const Trk::VolumeBounds* volBounds, Amg::Transform3D transform, double zTol, double phiTol, LocalVariablesContainer &aLVC) const
+{
+  if (!volBounds) return 0;
+  // volume shape
+  const Trk::CuboidVolumeBounds* box = dynamic_cast<const Trk::CuboidVolumeBounds*> (volBounds);
+  const Trk::TrapezoidVolumeBounds* trd = dynamic_cast<const Trk::TrapezoidVolumeBounds*> (volBounds);
+  const Trk::DoubleTrapezoidVolumeBounds* dtrd = dynamic_cast<const Trk::DoubleTrapezoidVolumeBounds*> (volBounds);
+  const Trk::BevelledCylinderVolumeBounds* bcyl = dynamic_cast<const Trk::BevelledCylinderVolumeBounds*> (volBounds);
+  const Trk::CylinderVolumeBounds* cyl = dynamic_cast<const Trk::CylinderVolumeBounds*> (volBounds);
+  const Trk::SubtractedVolumeBounds* sub = dynamic_cast<const Trk::SubtractedVolumeBounds*> (volBounds);
+  const Trk::CombinedVolumeBounds* comb = dynamic_cast<const Trk::CombinedVolumeBounds*> (volBounds);
+  const Trk::SimplePolygonBrepVolumeBounds* spb = dynamic_cast<const Trk::SimplePolygonBrepVolumeBounds*> (volBounds);
+  const Trk::PrismVolumeBounds* prism = dynamic_cast<const Trk::PrismVolumeBounds*> (volBounds);
+
+  if(box)  ATH_MSG_VERBOSE(" findVolumeSpan box " );
+  if(trd)  ATH_MSG_VERBOSE(" findVolumeSpan trd " );
+  if(dtrd) ATH_MSG_VERBOSE( " findVolumeSpan dtrd " );
+  if(bcyl) ATH_MSG_VERBOSE(" findVolumeSpan bcyl " );
+  if(cyl)  ATH_MSG_VERBOSE(" findVolumeSpan cyl " );
+  if(sub)  ATH_MSG_VERBOSE(" findVolumeSpan sub " );
+  if(comb) ATH_MSG_VERBOSE(" findVolumeSpan comb " );
+  if(spb)  ATH_MSG_VERBOSE(" findVolumeSpan spb " );
+  if(prism) ATH_MSG_VERBOSE(" findVolumeSpan prism " );
+
+  if (sub) return findVolumeSpan(&(sub->outer()->volumeBounds()),transform*sub->outer()->transform(),zTol,phiTol,aLVC);
+
+  if (comb) {
+    const Muon::Span* s1 = findVolumeSpan(&(comb->first()->volumeBounds()),transform*comb->first()->transform(),zTol,phiTol,aLVC);     
+    const Muon::Span* s2 = findVolumeSpan(&(comb->second()->volumeBounds()),transform*comb->second()->transform(),zTol,phiTol,aLVC);     
+
+    ATH_MSG_VERBOSE( "Combined span1:"<<name()<< ","<<(*s1)[0]<<","<< (*s1)[1]<<","<<(*s1)[2]<<"," << (*s1)[3]<<","<< (*s1)[4]<<","<< (*s1)[5]);
+    ATH_MSG_VERBOSE( "Combined span2:"<<name()<< ","<<(*s2)[0]<<","<< (*s2)[1]<<","<<(*s2)[2]<<"," << (*s2)[3]<<","<< (*s2)[4]<<","<< (*s2)[5]);
+
+    Muon::Span scomb;
+    scomb.reserve(6); 
+    scomb.push_back(fmin((*s1)[0],(*s2)[0]));
+    scomb.push_back(fmax((*s1)[1],(*s2)[1]));
+    scomb.push_back(fmin((*s1)[2],(*s2)[2]));
+    scomb.push_back(fmax((*s1)[3],(*s2)[3]));
+    scomb.push_back(fmin((*s1)[4],(*s2)[4]));
+    scomb.push_back(fmax((*s1)[5],(*s2)[5]));
+    return new Muon::Span(scomb);
+  }
+
+  // loop over edges ...
+  double minZ = aLVC.m_outerEndcapZ ; double maxZ = - aLVC.m_outerEndcapZ;
+  double minPhi = 2*M_PI; double maxPhi = 0.;
+  double minR = aLVC.m_outerBarrelRadius; double maxR = 0.;
+  std::vector<Amg::Vector3D> edges;
+  edges.reserve(16);
+  Muon::Span span;  
+  span.reserve(6); 
+  
+  double cylZcorr = 0.; 
+  if (box) {
+    edges.push_back( Amg::Vector3D(box->halflengthX(),box->halflengthY(),box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-box->halflengthX(),box->halflengthY(),box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(box->halflengthX(),-box->halflengthY(),box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-box->halflengthX(),-box->halflengthY(),box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(box->halflengthX(),box->halflengthY(),-box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-box->halflengthX(),box->halflengthY(),-box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(box->halflengthX(),-box->halflengthY(),-box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-box->halflengthX(),-box->halflengthY(),-box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,0.,-box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,0., box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-box->halflengthX(),0.,0.) );
+    edges.push_back( Amg::Vector3D( box->halflengthX(),0.,0.) );
+    edges.push_back( Amg::Vector3D(0.,-box->halflengthY(),0.) );
+    edges.push_back( Amg::Vector3D(0., box->halflengthY(),0.) );
+  }
+  if (trd) {
+//     std::cout <<  " Trapezoid minHalflengthX " << trd->minHalflengthX() << " maxHalflengthX() " << trd->maxHalflengthX() << " halflengthY() " << trd->halflengthY() << " halflengthZ " << trd->halflengthZ() << std::endl;
+  
+    edges.push_back( Amg::Vector3D(trd->maxHalflengthX(),trd->halflengthY(),trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-trd->maxHalflengthX(),trd->halflengthY(),trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(trd->minHalflengthX(),-trd->halflengthY(),trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-trd->minHalflengthX(),-trd->halflengthY(),trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(trd->maxHalflengthX(),trd->halflengthY(),-trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-trd->maxHalflengthX(),trd->halflengthY(),-trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(trd->minHalflengthX(),-trd->halflengthY(),-trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-trd->minHalflengthX(),-trd->halflengthY(),-trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,0.,-trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,0., trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-0.5*(trd->minHalflengthX()-trd->maxHalflengthX()),0.,0.) );
+    edges.push_back( Amg::Vector3D( 0.5*(trd->minHalflengthX()-trd->maxHalflengthX()),0.,0.) );
+    edges.push_back( Amg::Vector3D(0.,-trd->halflengthY(),0.) );
+    edges.push_back( Amg::Vector3D(0., trd->halflengthY(),0.) );
+  }
+  if (dtrd) {
+    edges.push_back( Amg::Vector3D( dtrd->maxHalflengthX(),2*dtrd->halflengthY2(),dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-dtrd->maxHalflengthX(),2*dtrd->halflengthY2(),dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D( dtrd->medHalflengthX(),0.,dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-dtrd->medHalflengthX(),0.,dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D( dtrd->minHalflengthX(),-2*dtrd->halflengthY1(),dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-dtrd->minHalflengthX(),-2*dtrd->halflengthY1(),dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D( dtrd->maxHalflengthX(),2*dtrd->halflengthY2(),-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-dtrd->maxHalflengthX(),2*dtrd->halflengthY2(),-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D( dtrd->medHalflengthX(),0.,-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-dtrd->medHalflengthX(),0.,-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D( dtrd->minHalflengthX(),-2*dtrd->halflengthY1(),-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-dtrd->minHalflengthX(),-2*dtrd->halflengthY1(),-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,0.,-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,0., dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,-2*dtrd->halflengthY1(),0.) );
+    edges.push_back( Amg::Vector3D(0., 2*dtrd->halflengthY2(),0.) );
+  }
+  if (bcyl) {
+    edges.push_back( Amg::Vector3D(0.,0.,bcyl->halflengthZ()));
+    edges.push_back( Amg::Vector3D(0.,0.,-bcyl->halflengthZ()));
+  }
+  if (cyl) {
+    edges.push_back( Amg::Vector3D(0.,0.,cyl->halflengthZ()));
+    edges.push_back( Amg::Vector3D(0.,0.,-cyl->halflengthZ()));
+  }
+  if (spb) {
+#ifdef TRKDETDESCR_USEFLOATPRECISON
+#define double float
+#endif      
+    const std::vector<std::pair<double, double> > vtcs = spb->xyVertices();
+#ifdef TRKDETDESCR_USEFLOATPRECISON
+#undef double
+#endif      
+    for (unsigned int i=0;i<vtcs.size();i++) {
+      edges.push_back( Amg::Vector3D(vtcs[i].first,vtcs[i].second, spb->halflengthZ()) );
+      edges.push_back( Amg::Vector3D(vtcs[i].first,vtcs[i].second, -spb->halflengthZ()) );
+    }
+// center
+    edges.push_back( Amg::Vector3D(0.,0.,spb->halflengthZ()));
+    edges.push_back( Amg::Vector3D(0.,0.,-spb->halflengthZ()));
+
+  }
+  if (prism) {
+#ifdef TRKDETDESCR_USEFLOATPRECISON
+#define double float
+#endif  
+    const std::vector<std::pair<double, double> > vtcs = prism->xyVertices();
+#ifdef TRKDETDESCR_USEFLOATPRECISON
+#undef double
+#endif      
+    for (unsigned int i=0;i<vtcs.size();i++) {
+      edges.push_back( Amg::Vector3D(vtcs[i].first,vtcs[i].second, prism->halflengthZ()) );
+      edges.push_back( Amg::Vector3D(vtcs[i].first,vtcs[i].second, -prism->halflengthZ()) );
+    }
+    edges.push_back( Amg::Vector3D(0.,0.,prism->halflengthZ()));
+    edges.push_back( Amg::Vector3D(0.,0.,-prism->halflengthZ()));
+
+  }
+  // apply transform and get span
+  double minP0=M_PI; double maxP0 = 0.; double minP1=2*M_PI; double maxP1=M_PI;
+  // determine phiStep for prism and spb
+  double phiStep = 0.;
+  for (unsigned int ie=0; ie < edges.size() ; ie++) {
+    Amg::Vector3D gp = transform*edges[ie];
+    double phi = gp.phi()+M_PI; 
+
+    ATH_MSG_VERBOSE( " local edges:"<< ie<<" x "<< edges[ie].x() << " y " << edges[ie].y() << " z " << edges[ie].z() << " phi "<< edges[ie].phi());
+    ATH_MSG_VERBOSE( " Global edges:"<< ie<<" x "<< gp.x() << " y " << gp.y() << " z " << gp.z() << " phi position + pi "<< phi);
+
+    if(ie>0&&phiStep<0.001) {
+       double phin = (transform*edges[ie-1]).phi() - M_PI;
+       double cph = cos(phi)*cos(phin) + sin(phi)*sin(phin);
+       phiStep = fabs(cph)<=1 ? acos(cph) : M_PI;     // TODO check this logic  
+       ATH_MSG_VERBOSE( " "<< ie<<" phiStep  "<< phiStep );
+    }
+    double rad = gp.perp();
+    if (cyl || bcyl) {
+      double radius = 0.; double hz = 0.;
+      Amg::Vector3D dir = (transform*Amg::Vector3D(0.,0.,1.));
+      double thAx = dir.theta();
+      if (cyl) { radius = cyl->outerRadius(); hz = cyl->halflengthZ();}
+      if (bcyl) { radius = bcyl->outerRadius(); hz = bcyl->halflengthZ();}
+      if ( gp[2]-radius*sin(thAx) <minZ ) minZ = gp[2]-radius*sin(thAx);
+      if ( gp[2]+radius*sin(thAx) >maxZ ) maxZ = gp[2]+radius*sin(thAx);
+      if ( rad-radius*fabs(cos(thAx)) < minR )  minR = rad>radius ? rad-radius*fabs(cos(thAx)): 0;
+      if ( rad+radius*fabs(cos(thAx)) > maxR )  maxR = rad+radius*fabs(cos(thAx));
+      // distance of cylinder axis and global axis
+      if (dir.perp()>0.001) {
+        // distance to minimal approach
+        double dMA = fabs(dir[0]*gp[0]+dir[1]*gp[1])/dir.perp()/dir.perp();
+        double dMD = sqrt (fmax(0.,gp.perp()*gp.perp()-dMA*dMA));
+        if (dMA<2*hz && dMD-radius < minR ) minR = fmax(0.,dMD-radius); 
+      } 
+      double dph = rad>0.001 ? atan(radius/rad) : M_PI;
+      if ( phi-dph <M_PI && phi-dph < minP0 ) minP0 = phi-dph;
+      if ( phi+dph <M_PI && phi+dph > maxP0 ) maxP0 = phi+dph;
+      if ( phi-dph >M_PI && phi-dph < minP1 ) minP1 = phi-dph;
+      if ( phi+dph >M_PI && phi+dph > maxP1 ) maxP1 = phi+dph;      
+    } else {
+      if ( gp[2]<minZ ) minZ = gp[2];
+      if ( gp[2]>maxZ ) maxZ = gp[2];
+      if ( phi<M_PI && phi < minP0 ) minP0 = phi; 
+      if ( phi<M_PI && phi > maxP0 ) maxP0 = phi; 
+      if ( phi>M_PI && phi < minP1 ) minP1 = phi; 
+      if ( phi>M_PI && phi > maxP1 ) maxP1 = phi; 
+      //if ( phi < minPhi ) minPhi = phi; 
+      //if ( phi > maxPhi ) maxPhi = phi; 
+      if ( rad < minR ) minR = rad; 
+      if ( rad > maxR ) maxR = rad;
+    } 
+  }
+  if (maxPhi<minPhi) {
+    if (maxP0>=minP0 && maxP1<minP1) { minPhi = minP0; maxPhi = maxP0; }
+    else if ( maxP1>=minP1 && maxP0<minP0) { minPhi = minP1; maxPhi = maxP1; }
+    else if ( maxP1 - minP0 < (maxP0 - minP1+2*M_PI) ) { minPhi = minP0; maxPhi = maxP1; }
+    else { minPhi = minP1 ; maxPhi = maxP0; }  
+    if (maxPhi<0.001 && minPhi>2*M_PI-0.001) {minPhi=0; maxPhi=2*M_PI;}
+  }
+//
+// correct edges for spb or prism
+//
+  if(spb||prism) {
+    if(minP0<phiStep&&2*M_PI-maxP1<phiStep) {
+      minPhi = 0.;
+      maxPhi = 2*M_PI;
+    }
+  }
+
+  if ( box || trd || dtrd || spb ) {
+    span.push_back( minZ - zTol );  
+    span.push_back( maxZ + zTol );  
+    span.push_back( minPhi - phiTol );  
+    span.push_back( maxPhi + phiTol );  
+    span.push_back( fmax(m_beamPipeRadius+0.001, minR - zTol) );  
+    span.push_back( maxR + zTol );  
+  } else if (bcyl || cyl ) {
+    span.push_back( minZ - cylZcorr -zTol );
+    span.push_back( maxZ + cylZcorr +zTol );
+    span.push_back( minPhi - phiTol );
+    span.push_back( maxPhi + phiTol );
+    span.push_back( fmax(m_beamPipeRadius+0.001, minR - zTol) );  
+    span.push_back( maxR + zTol );  
+  } else {
+    ATH_MSG_ERROR( name() <<" volume shape not recognized: ");
+    for (int i=0; i<6; i++) span.push_back(0.);
+  }
+  const Muon::Span* newSpan=new Muon::Span(span);
+  return newSpan;
+}
+
+const std::vector<std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Muon::Span*> >* >* Muon::MuonTrackingGeometryBuilderCond::findVolumesSpan(const std::vector<const Trk::DetachedTrackingVolume*>* objs, double zTol, double phiTol, LocalVariablesContainer &aLVC) const
+{
+
+  if (!objs || !objs->size()) return 0;
+  std::vector<std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Span*> >* >* spans =
+   new std::vector<std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Span*> >* >(9);
+  // split MS into 9 blocks to speed up the build-up of geometry
+  for (unsigned int i=0;i<9;i++) (*spans)[i] = new std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Span*> >; 
+  for (unsigned int iobj=0; iobj<objs->size(); iobj++) {
+    Amg::Transform3D  transform = (*objs)[iobj]->trackingVolume()->transform();
+    const Muon::Span* span = findVolumeSpan(&((*objs)[iobj]->trackingVolume()->volumeBounds()), transform, zTol, phiTol, aLVC);
+    double x0 = (*objs)[iobj]->trackingVolume()->X0;
+    double intX0 = fabs((*span)[0]-(*span)[1])/(x0+0.000000001);
+    double l0 = (*objs)[iobj]->trackingVolume()->L0;
+    ATH_MSG_DEBUG( "span:"<<(*objs)[iobj]->name()<< ","<<(*span)[0]<<","<< (*span)[1]<<","<<(*span)[2]<<","
+     << (*span)[3]<<","<< (*span)[4]<<","<< (*span)[5] << " X0 " << x0 << " L0 "<< l0 << " intX0 for span0 span1 " << intX0 );
+
+    int nspans = 0;
+    // negative outer wheel
+    if ( (*span)[0] < -m_bigWheel ) {
+        (*spans)[0]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // negative big wheel
+    if ( (*span)[0] < -aLVC.m_innerEndcapZ && (*span)[1]>-m_bigWheel ) {
+        (*spans)[1]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // neg.ect
+    if ( (*span)[0] < -m_ectZ && (*span)[1]>-aLVC.m_innerEndcapZ ) {
+        (*spans)[2]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // neg.small wheel
+    if ( (*span)[0] < -m_diskShieldZ && (*span)[1]>-m_ectZ ) {
+        (*spans)[3]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // barrel  
+    if ( (*span)[0] <  m_diskShieldZ && (*span)[1]> -m_diskShieldZ ) {
+//	 && ((*span)[5]> m_innerBarrelRadius || (*span)[0]<-m_barrelZ || (*span)[1]>m_barrelZ)  ) {
+        (*spans)[4]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // pos.small wheel
+    if ( (*span)[0] < m_ectZ && (*span)[1]> m_diskShieldZ ) {
+        (*spans)[5]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // pos.ect
+    if ( (*span)[0] < aLVC.m_innerEndcapZ && (*span)[1]> m_ectZ ) {
+        (*spans)[6]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // positive big wheel
+    if ( (*span)[0] < m_bigWheel && (*span)[1]> aLVC.m_innerEndcapZ ) {
+        (*spans)[7]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // positive outer wheel
+    if ( (*span)[1] >  m_bigWheel ) {
+        (*spans)[8]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+
+    if(nspans == 0) ATH_MSG_WARNING( " object not selected in span regions " << (*objs)[iobj]->name() );
+    if(nspans > 1) ATH_MSG_VERBOSE( " object selected in " << nspans << " span regions " << (*objs)[iobj]->name() );
+
+    aLVC.m_spans.push_back(span);                 // keep track of things to delete
+  }
+
+  return spans;
+}
+
+
+const Trk::TrackingVolume* Muon::MuonTrackingGeometryBuilderCond::processVolume(const Trk::Volume* vol, int etaN , int phiN, std::string volumeName, LocalVariablesContainer& aLVC) const
+{
+
+  const Trk::TrackingVolume* tVol = 0;
+
+  unsigned int colorCode = m_colorCode;
+
+  std::vector<const Trk::DetachedTrackingVolume*> blendVols; 
+
+  // partitions ? include protection against wrong setup
+  if (etaN < 1 || phiN < 1) {
+    ATH_MSG_ERROR( name() << "wrong partition setup" );
+    etaN = 1;
+    phiN = 1;
+  }
+  if ( etaN * phiN > 1 ) {  // partition
+    const Trk::CylinderVolumeBounds* cyl=dynamic_cast<const Trk::CylinderVolumeBounds*> (&(vol->volumeBounds()));
+    if (!cyl) {
+      ATH_MSG_ERROR( " process volume: volume cylinder boundaries not retrieved, return 0 " );
+      return 0; 
+    }
+    // subvolume boundaries
+    Trk::CylinderVolumeBounds* subBds = 0;
+
+    double phiSect = M_PI/phiN;
+    double etaSect = (cyl->halflengthZ())/etaN;
+
+    subBds = new Trk::CylinderVolumeBounds(cyl->innerRadius(), cyl->outerRadius(), phiSect,etaSect);
+    const Trk::Volume* protVol= new Trk::Volume(0, subBds);     
+
+    // create subvolumes & BinnedArray
+    std::vector<Trk::TrackingVolumeOrderPosition> subVolumes;
+    std::vector<const Trk::TrackingVolume*> sVols;                // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsNeg;             // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsPos;             // for gluing
+    for (int eta = 0; eta < etaN; eta++) {
+      if (colorCode>0) colorCode = 26 - colorCode;
+      // reference point for the check of envelope
+      double posZ = (vol->center())[2]+ etaSect * (2.*eta+1.-etaN) ;
+      double posR = 0.5*(cyl->innerRadius()+cyl->outerRadius());
+      int geoSignature = 4;
+      // loop over inner cutouts
+      for (unsigned int in=1; in<aLVC.m_msCutoutsIn.size(); in++) {
+        if (posZ>=aLVC.m_msCutoutsIn[in].second && posZ<=aLVC.m_msCutoutsIn[in-1].second) {
+          if (posR < aLVC.m_msCutoutsIn[in].first) geoSignature=2;
+          break;
+	}
+      }
+      if (geoSignature == 4) {
+	// loop over outer cutouts
+	for (unsigned int io=1; io<aLVC.m_msCutoutsOut.size(); io++) {
+	  if (posZ>=aLVC.m_msCutoutsOut[io-1].second && posZ<=aLVC.m_msCutoutsOut[io].second) {
+	    if (posR > aLVC.m_msCutoutsOut[io].first) geoSignature=5;
+	    break;
+	  }
+	}
+      }
+      for (int phi = 0; phi < phiN; phi++) {
+	if (colorCode>0) colorCode = 26 - colorCode;
+        // define subvolume
+        Amg::Transform3D  transf(Amg::AngleAxis3D(phiSect*(2*phi+1), Amg::Vector3D(0.,0.,1.))*Amg::Translation3D(Amg::Vector3D(0.,0.,posZ)));
+        const Trk::Volume* subVol= new Trk::Volume(*protVol, transf);     
+        // enclosed muon objects ?   
+	std::string volName = volumeName +MuonGM::buildString(eta,2) +MuonGM::buildString(phi,2) ; 
+        blendVols.clear();
+        std::vector<const Trk::DetachedTrackingVolume*>* detVols= getDetachedObjects( subVol, blendVols,aLVC);
+        const Trk::TrackingVolume* sVol = new Trk::TrackingVolume( *subVol,
+								   aLVC.m_muonMaterial,
+								   detVols,
+								   volName );
+        // statistics
+        m_frameNum++ ; if (detVols) m_frameStat += detVols->size();  
+        // prepare blending
+        if (m_blendInertMaterial && blendVols.size()) {
+          for (unsigned int id=0;id<blendVols.size();id++) {
+	    if (!aLVC.m_blendMap[blendVols[id]]) {
+	      aLVC.m_blendMap[blendVols[id]] = new std::vector<const Trk::TrackingVolume*>;
+              aLVC.m_blendVols.push_back(blendVols[id]);
+	    }
+	    aLVC.m_blendMap[blendVols[id]]->push_back(sVol);
+	  }
+	}  
+        //
+        if (geoSignature == 2) sVol->sign(Trk::BeamPipe);
+        if (geoSignature == 5) sVol->sign(Trk::Cavern);
+        sVol->registerColorCode(colorCode); 
+	// reference position 
+	Amg::Vector3D gp(subBds->outerRadius(),0.,0.);
+	//subVolumes.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol, true),
+  //                                                           Amg::Vector3D(transf*gp)));
+  /* The above was passing a SharedObject with the ndel == True
+   * now that SharedObject is a typeded to std::shared_ptr , pass a no-op deleter
+   */
+  subVolumes.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol, Trk::do_not_delete<const Trk::TrackingVolume>),
+                                                        Amg::Vector3D(transf*gp)));
+       //glue subVolumes
+        sVols.push_back(sVol); 
+        if (eta==0)      sVolsNeg.push_back(sVol); 
+        if (eta==etaN-1) sVolsPos.push_back(sVol); 
+        // in phi        
+        if ( phiN>1 && phi>0) {
+          m_trackingVolumeHelper->glueTrackingVolumes(*sVol, Trk::tubeSectorNegativePhi,
+						      *(sVols[eta*phiN+phi-1]), Trk::tubeSectorPositivePhi);
+          if ( phi==phiN-1 )  m_trackingVolumeHelper->glueTrackingVolumes(*(sVols[eta*phiN]), Trk::tubeSectorNegativePhi,
+                                                                          *sVol, Trk::tubeSectorPositivePhi);
+	}
+        // in eta
+        if ( etaN>1 && eta>0) m_trackingVolumeHelper->glueTrackingVolumes(*sVol, Trk::negativeFaceXY,
+						      *(sVols[(eta-1)*phiN+phi]), Trk::positiveFaceXY);        
+        //
+	delete subVol; //shouldn't need this any more
+      }
+    }
+
+    //Trk::BinUtility2DPhiZ* volBinUtil=new Trk::BinUtility2DPhiZ(phiN,etaN,subBds->outerRadius(),cyl->halflengthZ(),M_PI, new Amg::Transform3D(vol->transform()));
+    Trk::BinUtility buPhi( phiN, -M_PI, M_PI, Trk::closed, Trk::binPhi ); 
+    const Trk::BinUtility   buZ( etaN, vol->transform().translation()[2]-cyl->halflengthZ(), 
+                                        vol->transform().translation()[2]+cyl->halflengthZ(), Trk::open, Trk::binZ ); 
+    buPhi += buZ; 
+
+    Trk::BinUtility* volBinUtil=new Trk::BinUtility(buPhi);        // TODO verify ordering PhiZ vs. ZPhi 
+
+    delete protVol;
+    Trk::BinnedArray2D<Trk::TrackingVolume>* subVols=new Trk::BinnedArray2D<Trk::TrackingVolume>(subVolumes,volBinUtil);
+
+    tVol = new Trk::TrackingVolume( *vol,
+                                    aLVC.m_muonMaterial,
+				    0,subVols,
+				    volumeName);
+    // register glue volumes
+    const Trk::GlueVolumesDescriptor& volGlueVolumes = tVol->glueVolumesDescriptor();
+    volGlueVolumes.registerGlueVolumes(Trk::tubeInnerCover,sVols);
+    volGlueVolumes.registerGlueVolumes(Trk::tubeOuterCover,sVols);
+    volGlueVolumes.registerGlueVolumes(Trk::negativeFaceXY,sVolsNeg);
+    volGlueVolumes.registerGlueVolumes(Trk::positiveFaceXY,sVolsPos);
+
+  } else {
+    // enclosed muon objects ? 
+    blendVols.clear();
+    std::vector<const Trk::DetachedTrackingVolume*>* muonObjs = getDetachedObjects( vol, blendVols,aLVC);
+
+    tVol = new Trk::TrackingVolume( *vol,
+                                    aLVC.m_muonMaterial,
+				    muonObjs,
+				    volumeName);
+    // statistics
+    m_frameNum++ ; if (muonObjs) m_frameStat += muonObjs->size();  
+    // prepare blending
+    if (m_blendInertMaterial && blendVols.size()) {
+      for (unsigned int id=0;id<blendVols.size();id++) {
+	if (!aLVC.m_blendMap[blendVols[id]]) {
+	  aLVC.m_blendMap[blendVols[id]] = new std::vector<const Trk::TrackingVolume*>;
+	  aLVC.m_blendVols.push_back(blendVols[id]);
+	}
+	aLVC.m_blendMap[blendVols[id]]->push_back(tVol);
+      }
+    }  
+  }
+
+  return tVol;
+} 
+
+const Trk::TrackingVolume* Muon::MuonTrackingGeometryBuilderCond::processVolume(const Trk::Volume* vol, int mode , std::string volumeName, LocalVariablesContainer& aLVC) const
+{
+  ATH_MSG_VERBOSE( name() << "processing volume in mode:"<< mode );
+
+  // mode : -1 ( adjusted z/phi partition )
+  //         0 ( -"- plus barrel H binning )            
+  //         0 ( -"- plus inner endcap H binning )            
+  //         0 ( -"- plus outer endcap H binning )            
+
+  const Trk::TrackingVolume* tVol = 0;
+
+  unsigned int colorCode = m_colorCode;
+
+  std::vector<const Trk::DetachedTrackingVolume* > blendVols;
+
+  //getPartitionFromMaterial(vol);
+
+  // retrieve cylinder
+  const Trk::CylinderVolumeBounds* cyl=dynamic_cast<const Trk::CylinderVolumeBounds*> (&(vol->volumeBounds()));
+  if (!cyl) {
+    ATH_MSG_ERROR( " process volume: volume cylinder boundaries not retrieved, return 0 " );
+    return 0; 
+  }
+  // create vector of zSteps for this volume
+  std::vector<float> zSteps;
+  std::vector<int> zTypes;
+  zSteps.clear(); zTypes.clear();
+  double zPos = vol->center()[2];
+  double hz = cyl->halflengthZ();
+  double z1 = zPos-hz;  double z2 = zPos+hz ;
+  zSteps.push_back(z1);
+  for (unsigned int iz=0;iz<aLVC.m_zPartitions.size();iz++) {
+    if ( aLVC.m_zPartitions[iz]==zSteps.front()) zTypes.push_back(aLVC.m_zPartitionsType[iz]);
+    if ( aLVC.m_zPartitions[iz]> z1 && aLVC.m_zPartitions[iz] < z2 ) {
+      zSteps.push_back(aLVC.m_zPartitions[iz]);
+      if (!zTypes.size()) { 
+	if (iz==0) zTypes.push_back(0);
+        else zTypes.push_back(aLVC.m_zPartitionsType[iz-1]);
+      }
+      zTypes.push_back(aLVC.m_zPartitionsType[iz]);
+      z1 = aLVC.m_zPartitions[iz];
+    }
+  }
+  zSteps.push_back(z2);
+
+  for (unsigned int iz=0;iz<zSteps.size(); iz++) ATH_MSG_DEBUG( "z partition in volume:"<<volumeName<<":"<<iz<<":"<<zSteps[iz]); 
+
+  // phi binning
+  if (fabs(zPos)> m_barrelZ && cyl->outerRadius()<aLVC.m_outerBarrelRadius) getPhiParts(0,aLVC);
+  else if (fabs(zPos)<= m_ectZ) getPhiParts(2,aLVC);
+  else if (fabs(zPos)<= aLVC.m_innerEndcapZ) getPhiParts(3,aLVC);
+  else if (fabs(zPos)> m_outerWheel && cyl->outerRadius()> m_outerShieldRadius ) getPhiParts(1,aLVC);
+  else if (fabs(zPos)> aLVC.m_innerEndcapZ && fabs(zPos)<m_bigWheel && cyl->outerRadius()> m_outerShieldRadius ) getPhiParts(1,aLVC);
+  else getPhiParts(0,aLVC);
+
+  // R/H binning ?
+  unsigned int etaN = zSteps.size()-1;
+  unsigned int phiN = aLVC.m_adjustedPhi.size();
+   
+  int phiTypeMax = 0;                // count different partitions
+
+  if ( mode > -1 ) {
+    // create z,phi bin utilities
+    //Trk::BinUtility1DZZ* zBinUtil = new Trk::BinUtility1DZZ(zSteps);
+    //Trk::BinUtility1DF* pBinUtil = new Trk::BinUtility1DF(m_adjustedPhi);
+    Trk::BinUtility* zBinUtil = new Trk::BinUtility(zSteps, Trk::open, Trk::binZ );
+    Trk::BinUtility* pBinUtil = new Trk::BinUtility(aLVC.m_adjustedPhi,  Trk::closed, Trk::binPhi ); 
+    std::vector<std::vector<Trk::BinUtility*> >*  hBinUtil=new std::vector<std::vector<Trk::BinUtility*> >;
+    for (unsigned iz=0;iz < zSteps.size()-1; iz++) {
+      std::vector<Trk::BinUtility*> phBinUtil; 
+      for (unsigned ip=0;ip < aLVC.m_adjustedPhi.size(); ip++) {
+        // retrieve reference phi
+	float phiRef = 0.5*aLVC.m_adjustedPhi[ip];
+        if (ip<aLVC.m_adjustedPhi.size()-1) phiRef += 0.5*aLVC.m_adjustedPhi[ip+1] ;
+	else phiRef += 0.5*aLVC.m_adjustedPhi[0]+M_PI ;
+
+        if (aLVC.m_adjustedPhiType[ip]>phiTypeMax) phiTypeMax = aLVC.m_adjustedPhiType[ip];
+        for (std::pair<int,float> i: aLVC.m_hPartitions[mode][zTypes[iz]][aLVC.m_adjustedPhiType[ip]]) {
+          ATH_MSG_VERBOSE( " mode " << mode << " phiRef " << phiRef << " zTypes[iz] " << zTypes[iz] << " m_adjustedPhiType[ip] " << aLVC.m_adjustedPhiType[ip] << " hPartitions " << i.second );
+        }
+        phBinUtil.push_back(new Trk::BinUtility(phiRef,aLVC.m_hPartitions[mode][zTypes[iz]][aLVC.m_adjustedPhiType[ip]]));
+      }
+      hBinUtil->push_back(phBinUtil);
+    }
+
+    // create subvolumes & BinnedArray
+    std::vector<Trk::TrackingVolumeOrderPosition>  subVolumesVect;
+    std::vector<std::vector<std::vector<const Trk::TrackingVolume*> > > subVolumes;
+    std::vector<std::vector<Trk::SharedObject<Trk::BinnedArray<Trk::TrackingVolume> > > > hBins;
+    std::vector<const Trk::TrackingVolume*> sVolsInn;             // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsOut;             // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsNeg;             // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsPos;             // for gluing
+    for (unsigned int eta = 0; eta < zSteps.size()-1; eta++) {
+      if (colorCode>0) colorCode = 6 -colorCode;
+      double posZ = 0.5*(zSteps[eta] + zSteps[eta+1]) ;
+      double   hZ = 0.5*fabs(zSteps[eta+1] - zSteps[eta]) ;
+      std::vector<std::vector<const Trk::TrackingVolume*> > phiSubs;
+      std::vector<Trk::SharedObject<Trk::BinnedArray<Trk::TrackingVolume> > >  phBins;
+      std::vector<int> phiType(phiTypeMax+1,-1);        // indication of first phi/R partition built for a given type (for cloning)
+      std::vector<std::vector<Trk::Volume*> > garbVol(phiTypeMax+1);
+      unsigned int pCode = 1; 
+      for (unsigned int phi = 0; phi < phiN; phi++) {
+	pCode = (colorCode>0) ? 3-pCode : 0;
+	double posPhi = 0.5*aLVC.m_adjustedPhi[phi];
+	double phiSect = 0.;
+        if (phi<phiN-1) {
+	  posPhi += 0.5*aLVC.m_adjustedPhi[phi+1] ;
+          phiSect = 0.5*fabs(aLVC.m_adjustedPhi[phi+1]-aLVC.m_adjustedPhi[phi]);
+	} else {
+	  posPhi += 0.5*aLVC.m_adjustedPhi[0]+M_PI ;
+          phiSect = 0.5*fabs(aLVC.m_adjustedPhi[0]+2*M_PI-aLVC.m_adjustedPhi[phi]);
+	}
+	std::vector<std::pair<int,float> > hSteps =  aLVC.m_hPartitions[mode][zTypes[eta]][aLVC.m_adjustedPhiType[phi]];
+	std::vector<const Trk::TrackingVolume*> hSubs;
+	std::vector<Trk::TrackingVolumeOrderPosition> hSubsTr;
+        int phiP = phiType[aLVC.m_adjustedPhiType[phi]]; 
+
+        unsigned int hCode = 1; 
+        for (unsigned int h = 0; h < hSteps.size()-1; h++) {
+	  hCode = colorCode>0 ? 1 - hCode : 0; 
+          // similar volume may exist already
+	  Trk::Volume* subVol=0;
+	  Amg::Transform3D* transf = new Amg::Transform3D(Amg::AngleAxis3D(posPhi,Amg::Vector3D(0.,0.,1.))*Amg::Translation3D(Amg::Vector3D(0.,0.,posZ)));
+          //
+          int volType = 0;     // cylinder 
+          if ( hSteps[h].first == 1 && hSteps[h+1].first == 0 ) volType = 1;  
+          if ( hSteps[h].first == 0 && hSteps[h+1].first == 1 ) volType = 2;  
+          if ( hSteps[h].first == 1 && hSteps[h+1].first == 1 ) volType = 3;  
+	  // define subvolume
+          if (phiP>-1 ) {
+            subVol = new Trk::Volume(*(phiSubs[phiP][h]),(*transf)*phiSubs[phiP][h]->transform().inverse());
+	  } else if ( phiSect<0.5*M_PI) {
+	    Trk::BevelledCylinderVolumeBounds* subBds = new Trk::BevelledCylinderVolumeBounds(hSteps[h].second,
+							   hSteps[h+1].second,
+							   phiSect, 
+							   hZ,
+							   volType);
+	    subVol = new Trk::Volume(transf, subBds);
+	  } else {
+	    Trk::CylinderVolumeBounds* subBds = new Trk::CylinderVolumeBounds(hSteps[h].second,
+						   hSteps[h+1].second,
+						   phiSect, 
+						   hZ);
+	    subVol = new Trk::Volume(transf, subBds);
+	  }
+       
+	  // enclosed muon objects ? also adjusts material properties in case of material blend  
+	  std::string volName = volumeName +MuonGM::buildString(eta,2) +MuonGM::buildString(phi,2) +MuonGM::buildString(h,2) ; 
+          blendVols.clear(); 
+	  std::vector<const Trk::DetachedTrackingVolume*>* detVols= getDetachedObjects( subVol, blendVols,aLVC);
+
+	  const Trk::TrackingVolume* sVol = new Trk::TrackingVolume( *subVol,
+								     aLVC.m_muonMaterial,
+								     detVols,
+								     volName );                                                                  
+     
+	  // statistics
+	  m_frameNum++ ; if (detVols) m_frameStat += detVols->size();  
+	  // prepare blending
+	  if (m_blendInertMaterial && blendVols.size()) {
+	    for (unsigned int id=0;id<blendVols.size();id++) {
+	      if (!aLVC.m_blendMap[blendVols[id]]) {
+		aLVC.m_blendMap[blendVols[id]] = new std::vector<const Trk::TrackingVolume*>;
+                aLVC.m_blendVols.push_back(blendVols[id]);
+	      }
+	      aLVC.m_blendMap[blendVols[id]]->push_back(sVol);
+	    }
+	  }  
+	  // reference point for the check of envelope
+	  double posR = 0.5*(hSteps[h].second+hSteps[h+1].second);
+	  // loop over inner cutouts
+	  for (unsigned int in=1; in<aLVC.m_msCutoutsIn.size(); in++) {
+	    if (posZ>=aLVC.m_msCutoutsIn[in].second && posZ<=aLVC.m_msCutoutsIn[in-1].second) {
+	      if (posR < aLVC.m_msCutoutsIn[in].first) sVol->sign(Trk::BeamPipe);
+	      break;
+	    }
+	  }
+	  // loop over outer cutouts
+	  for (unsigned int io=1; io<aLVC.m_msCutoutsOut.size(); io++) {
+	    if (posZ>=aLVC.m_msCutoutsOut[io-1].second && posZ<=aLVC.m_msCutoutsOut[io].second) {
+	      if (posR > aLVC.m_msCutoutsOut[io].first) sVol->sign(Trk::Cavern);
+	      break;
+	    }
+	  }
+	  //
+          sVol->registerColorCode(colorCode+pCode+hCode);
+	  // reference position 
+	  Amg::Vector3D gp(0.5*(hSteps[h].second+hSteps[h+1].second),0.,0.);
+	  subVolumesVect.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol),
+	                                                       Amg::Vector3D((*transf)*gp)));
+	  hSubsTr.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol, Trk::do_not_delete<const Trk::TrackingVolume>),
+	                                                       Amg::Vector3D((*transf)*gp)));
+	  hSubs.push_back(sVol);
+
+          // cleanup 
+          if (phiP>-1) {delete transf; delete subVol;}
+          else garbVol[aLVC.m_adjustedPhiType[phi]].push_back(subVol);       // don't delete before cloned
+
+	  //glue subVolume
+	  if (h==0)                sVolsInn.push_back(sVol); 
+	  if (h==hSteps.size()-2)  sVolsOut.push_back(sVol); 
+	  if (eta==0)      sVolsNeg.push_back(sVol); 
+	  if (eta==etaN-1) sVolsPos.push_back(sVol); 
+          // in R/H
+          if (h>0) { // glue 'manually'
+            if (volType == 1 || volType == 3 ) {  // plane surface
+	      m_trackingVolumeHelper->setOutsideTrackingVolume(*sVol, Trk::tubeSectorInnerCover,hSubs[h-1]); 
+	      m_trackingVolumeHelper->setOutsideTrackingVolume(*(hSubs[h-1]), Trk::tubeSectorOuterCover,sVol); 
+            } else {  // cylinder surface
+	      m_trackingVolumeHelper->setInsideTrackingVolume(*sVol, Trk::tubeSectorInnerCover,hSubs[h-1]); 
+	      m_trackingVolumeHelper->setOutsideTrackingVolume(*(hSubs[h-1]), Trk::tubeSectorOuterCover,sVol);
+	    } 
+          }
+	  // in phi        
+	  if ( phiN>1 && phi>0) {
+	    m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*sVol, Trk::tubeSectorNegativePhi,phBins[phi-1]);
+	    if ( phi==phiN-1 )  m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*sVol, Trk::tubeSectorPositivePhi, phBins[0]);
+	  }
+	  // in eta
+	  if ( etaN>1 && eta>0) m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*sVol, Trk::negativeFaceXY, hBins[eta-1][phi]);     
+	  //
+	}
+        phiSubs.push_back(hSubs); 
+	Trk::BinnedArray1D<Trk::TrackingVolume>* volBinArray = new Trk::BinnedArray1D<Trk::TrackingVolume>(hSubsTr,(*hBinUtil)[eta][phi]->clone());
+        phBins.push_back(Trk::SharedObject<Trk::BinnedArray<Trk::TrackingVolume> >(volBinArray));
+        // save link to current partition for cloning 
+        if (phiP<0) phiType[aLVC.m_adjustedPhiType[phi]] = phi;    
+
+        // finish phi gluing
+        if (phiN>1 && phi>0) {
+	  for (unsigned int j=0; j<phiSubs[phi-1].size(); j++) {
+	    m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*(phiSubs[phi-1][j]), Trk::tubeSectorPositivePhi,phBins[phi]);
+	  }
+	}
+        if (phiN>1 && phi==phiN-1) {
+	  for (unsigned int j=0; j<phiSubs[0].size(); j++) {
+	    m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*(phiSubs[0][j]), Trk::tubeSectorNegativePhi,phBins[phi]);
+	  }
+	}
+        // finish eta gluing
+        if ( etaN>1 && eta>0) {
+	  for (unsigned int j=0; j<subVolumes[eta-1][phi].size(); j++) {
+	    m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*(subVolumes[eta-1][phi][j]), Trk::positiveFaceXY,phBins[phi]);
+	  }
+	}
+      }
+      subVolumes.push_back(phiSubs);
+      hBins.push_back(phBins);
+      // get rid of the garbage
+      for (unsigned int j=0;j<garbVol.size();j++)
+	for (unsigned int jj=0;jj<garbVol[j].size();jj++) delete garbVol[j][jj];
+    }
+
+    //Trk::BinUtility3DZFH* volBinUtil=new Trk::BinUtility3DZFH(zBinUtil,pBinUtil,hBinUtil,new Amg::Transform3D(vol->transform()));
+  
+    Trk::BinnedArray1D1D1D<Trk::TrackingVolume>* subVols=new Trk::BinnedArray1D1D1D<Trk::TrackingVolume>(subVolumesVect,zBinUtil,pBinUtil,hBinUtil);
+
+    tVol = new Trk::TrackingVolume( *vol,
+                                    aLVC.m_muonMaterial,
+				    0,subVols,
+				    volumeName);
+    // register glue volumes
+    const Trk::GlueVolumesDescriptor& volGlueVolumes = tVol->glueVolumesDescriptor();
+    volGlueVolumes.registerGlueVolumes(Trk::tubeInnerCover,sVolsInn);
+    volGlueVolumes.registerGlueVolumes(Trk::tubeOuterCover,sVolsOut);
+    volGlueVolumes.registerGlueVolumes(Trk::negativeFaceXY,sVolsNeg);
+    volGlueVolumes.registerGlueVolumes(Trk::positiveFaceXY,sVolsPos);
+  
+    return tVol;
+  } 
+
+  // proceed with 2D z/phi binning
+  // partitions ? include protection against wrong setup
+  if (phiN < 1) {
+    ATH_MSG_ERROR( name() << "wrong partition setup" );
+    phiN = 1;
+  } else {
+    ATH_MSG_VERBOSE( name() << "partition setup:(z,phi):"<<etaN<<","<<phiN );
+  }
+
+  if ( etaN * phiN > 1 ) {  // partition
+    // subvolume boundaries
+    Trk::CylinderVolumeBounds* subBds=0;
+
+    // create subvolumes & BinnedArray
+    std::vector<Trk::TrackingVolumeOrderPosition> subVolumes(etaN*phiN);
+    std::vector<const Trk::TrackingVolume*> sVols(etaN*phiN);                // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsNeg(phiN);             // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsPos(phiN);             // for gluing
+    for (unsigned int eta = 0; eta < zSteps.size()-1; eta++) {
+      double posZ = 0.5*(zSteps[eta] + zSteps[eta+1]) ;
+      double   hZ = 0.5*fabs(zSteps[eta+1] - zSteps[eta]) ;
+      colorCode = 26 -colorCode;
+      for (unsigned int phi = 0; phi < phiN; phi++) {
+	colorCode = 26 -colorCode;
+	double posPhi = 0.5*aLVC.m_adjustedPhi[phi];
+	double phiSect = 0.;
+        if (phi<phiN-1) {
+	  posPhi += 0.5*aLVC.m_adjustedPhi[phi+1] ;
+          phiSect = 0.5*fabs(aLVC.m_adjustedPhi[phi+1]-aLVC.m_adjustedPhi[phi]);
+	} else {
+	  posPhi += 0.5*aLVC.m_adjustedPhi[0]+M_PI ;
+          phiSect = 0.5*fabs(aLVC.m_adjustedPhi[0]+2*M_PI-aLVC.m_adjustedPhi[phi]);
+	}
+	// define subvolume
+	subBds = new Trk::CylinderVolumeBounds(cyl->innerRadius(),
+					       cyl->outerRadius(),
+					       phiSect, 
+					       hZ);
+        Amg::Transform3D* transf = new Amg::Transform3D(Amg::AngleAxis3D(posPhi,Amg::Vector3D(0.,0.,1.))*Amg::Translation3D(Amg::Vector3D(0.,0.,posZ)));
+        Trk::Volume subVol(transf, subBds);     
+        // enclosed muon objects ?   
+	std::string volName = volumeName +MuonGM::buildString(eta,2) +MuonGM::buildString(phi,2) ; 
+
+	Trk::Material mat=aLVC.m_muonMaterial;
+        blendVols.clear();
+        std::vector<const Trk::DetachedTrackingVolume*>* detVols= getDetachedObjects( &subVol, blendVols,aLVC);
+        const Trk::TrackingVolume* sVol = new Trk::TrackingVolume( subVol,
+								   aLVC.m_muonMaterial,
+								   detVols,
+								   volName );
+        // statistics
+        m_frameNum++ ; if (detVols) m_frameStat += detVols->size();  
+        // prepare blending
+        if (m_blendInertMaterial && blendVols.size()) {
+          for (unsigned int id=0;id<blendVols.size();id++) {
+	    if (!aLVC.m_blendMap[blendVols[id]]) {
+	      aLVC.m_blendMap[blendVols[id]] = new std::vector<const Trk::TrackingVolume*>;
+              aLVC.m_blendVols.push_back(blendVols[id]);
+	    }
+	    aLVC.m_blendMap[blendVols[id]]->push_back(sVol);
+	  }
+	}  
+	// reference point for the check of envelope
+	double posR = 0.5*(cyl->innerRadius()+cyl->outerRadius());
+	// loop over inner cutouts
+	for (unsigned int in=1; in<aLVC.m_msCutoutsIn.size(); in++) {
+	  if (posZ>=aLVC.m_msCutoutsIn[in].second && posZ<=aLVC.m_msCutoutsIn[in-1].second) {
+	    if (posR < aLVC.m_msCutoutsIn[in].first) sVol->sign(Trk::BeamPipe);
+	    break;
+	  }
+	}
+	// loop over outer cutouts
+	for (unsigned int io=1; io<aLVC.m_msCutoutsOut.size(); io++) {
+	  if (posZ>=aLVC.m_msCutoutsOut[io-1].second && posZ<=aLVC.m_msCutoutsOut[io].second) {
+	    if (posR > aLVC.m_msCutoutsOut[io].first) sVol->sign(Trk::Cavern);
+	    break;
+	  }
+	}
+        //delete subVol;
+        sVol->registerColorCode(colorCode); 
+        // reference position 
+	Amg::Vector3D gp(subBds->outerRadius(),0.,0.);
+	//subVolumes.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol, true),
+        //                                                     Amg::Vector3D((*transf)*gp)));
+	subVolumes[phi*etaN+eta] = Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol),
+                                                             Amg::Vector3D((*transf)*gp));
+        //glue subVolumes
+        //sVols[phi*etaN+eta] = sVol; 
+        sVols[phiN*eta+phi] = sVol; 
+        if (eta==0)      sVolsNeg[phi]=sVol; 
+        if (eta==etaN-1) sVolsPos[phi]=sVol; 
+        // in phi        
+        if ( phiN>1 && phi>0) {
+          m_trackingVolumeHelper->glueTrackingVolumes(*sVol, Trk::tubeSectorNegativePhi,
+						      *(sVols[eta*phiN+phi-1]), Trk::tubeSectorPositivePhi);
+          if ( phi==phiN-1 )  m_trackingVolumeHelper->glueTrackingVolumes(*(sVols[eta*phiN]), Trk::tubeSectorNegativePhi,
+                                                                          *sVol, Trk::tubeSectorPositivePhi);
+	}
+        // in eta
+        if ( etaN>1 && eta>0) m_trackingVolumeHelper->glueTrackingVolumes(*sVol, Trk::negativeFaceXY,
+						      *(sVols[(eta-1)*phiN+phi]), Trk::positiveFaceXY);        
+        //
+      }
+    }
+
+    //Trk::BinUtility2DZF* volBinUtil=new Trk::BinUtility2DZF(zSteps,m_adjustedPhi,new Amg::Transform3D(vol->transform()));
+    Trk::BinUtility zBinUtil(zSteps, Trk::BinningOption::open, Trk::BinningValue::binZ );
+    const Trk::BinUtility pBinUtil(aLVC.m_adjustedPhi,  Trk::BinningOption::closed, Trk::BinningValue::binPhi ); 
+
+    zBinUtil += pBinUtil; 
+
+    Trk::BinUtility* volBinUtil=new Trk::BinUtility(zBinUtil);        // TODO verify ordering PhiZ vs. ZPhi 
+
+    Trk::BinnedArray2D<Trk::TrackingVolume>* subVols=new Trk::BinnedArray2D<Trk::TrackingVolume>(subVolumes,volBinUtil);
+
+    tVol = new Trk::TrackingVolume( *vol,
+                                    aLVC.m_muonMaterial,
+				    0,subVols,
+				    volumeName);
+    // register glue volumes
+    const Trk::GlueVolumesDescriptor& volGlueVolumes = tVol->glueVolumesDescriptor();
+    volGlueVolumes.registerGlueVolumes(Trk::tubeInnerCover,sVols);
+    volGlueVolumes.registerGlueVolumes(Trk::tubeOuterCover,sVols);
+    volGlueVolumes.registerGlueVolumes(Trk::negativeFaceXY,sVolsNeg);
+    volGlueVolumes.registerGlueVolumes(Trk::positiveFaceXY,sVolsPos);
+
+  } else {
+    // enclosed muon objects ? 
+    blendVols.clear();
+    std::vector<const Trk::DetachedTrackingVolume*>* muonObjs = getDetachedObjects( vol, blendVols,aLVC);
+
+    tVol = new Trk::TrackingVolume( *vol,
+                                    aLVC.m_muonMaterial,
+				    muonObjs,
+				    volumeName);
+    // statistics
+    m_frameNum++ ; if (muonObjs) m_frameStat += muonObjs->size();  
+    // prepare blending
+    if (m_blendInertMaterial && blendVols.size()) {
+      for (unsigned int id=0;id<blendVols.size();id++) {
+	if (!aLVC.m_blendMap[blendVols[id]]) {
+	  aLVC.m_blendMap[blendVols[id]] = new std::vector<const Trk::TrackingVolume*>;
+	  aLVC.m_blendVols.push_back(blendVols[id]);
+	}
+	aLVC.m_blendMap[blendVols[id]]->push_back(tVol);
+      }
+    }  
+  }
+
+  return tVol;
+} 
+
+const Trk::TrackingVolume* Muon::MuonTrackingGeometryBuilderCond::processShield(const Trk::Volume* vol, int type,std::string volumeName, LocalVariablesContainer &aLVC) const
+{
+  ATH_MSG_VERBOSE( name() << "processing shield volume "<< volumeName<<"  in mode:"<< type );
+
+  const Trk::TrackingVolume* tVol = 0;
+
+  unsigned int colorCode = m_colorCode;
+
+  std::vector<const Trk::DetachedTrackingVolume*> blendVols;
+
+  //getPartitionFromMaterial(vol);
+
+  // retrieve cylinder
+  const Trk::CylinderVolumeBounds* cyl=dynamic_cast<const Trk::CylinderVolumeBounds*> (&(vol->volumeBounds()));
+  if (!cyl) {
+    ATH_MSG_ERROR( " process volume: volume cylinder boundaries not retrieved, return 0 " );
+    return 0; 
+  }
+  // create vector of zSteps for this volume
+  std::vector<float> zSteps;
+  zSteps.clear();
+  double zPos = vol->center()[2];
+  double hz = cyl->halflengthZ();
+  double z1 = zPos-hz;  double z2 = zPos+hz ;
+  zSteps.push_back(z1);
+  for (unsigned int iz=0;iz<aLVC.m_shieldZPart.size();iz++) {
+    if ( aLVC.m_shieldZPart[iz]> z1 && aLVC.m_shieldZPart[iz] < z2 ) {
+      zSteps.push_back(aLVC.m_shieldZPart[iz]);
+      z1 = aLVC.m_shieldZPart[iz];
+    }
+  }
+  zSteps.push_back(z2);
+
+  // phi binning trivial
+  aLVC.m_adjustedPhi.clear();
+  aLVC.m_adjustedPhi.push_back(0.);
+
+  unsigned int etaN = zSteps.size()-1;
+
+  // create z,h bin utilities
+  //Trk::BinUtility1DZZ* zBinUtil = new Trk::BinUtility1DZZ(zSteps);
+  //Trk::BinUtility1DF* pBinUtil = new Trk::BinUtility1DF(m_adjustedPhi);
+  Trk::BinUtility* zBinUtil = new Trk::BinUtility(zSteps, Trk::BinningOption::open, Trk::BinningValue::binZ );
+  //Trk::BinUtility* pBinUtil = new Trk::BinUtility(m_adjustedPhi,  Trk::BinningOption::closed, Trk::BinningValue::binPhi );
+  Trk::BinUtility* pBinUtil = new Trk::BinUtility( 1, -M_PI, M_PI, Trk::BinningOption::closed, Trk::BinningValue::binPhi ); 
+  std::vector<std::vector<Trk::BinUtility*> >*  hBinUtil=new std::vector<std::vector<Trk::BinUtility*> >;
+  float phiRef = 0.;
+  for (unsigned iz=0;iz < zSteps.size()-1; iz++) {
+    std::vector<Trk::BinUtility*> phBinUtil;
+    phBinUtil.push_back(new Trk::BinUtility(phiRef,aLVC.m_shieldHPart[type]) );
+    hBinUtil->push_back(phBinUtil);
+  }
+
+  // subvolume boundaries
+  Trk::CylinderVolumeBounds* subBds=0;
+
+  // create subvolumes & BinnedArray
+  std::vector<Trk::TrackingVolumeOrderPosition>  subVolumesVect;
+  std::vector<std::vector<std::vector<const Trk::TrackingVolume*> > > subVolumes;
+  std::vector<std::vector<Trk::SharedObject<Trk::BinnedArray<Trk::TrackingVolume> > > > hBins;
+  std::vector<const Trk::TrackingVolume*> sVolsInn;             // for gluing
+  std::vector<const Trk::TrackingVolume*> sVolsOut;             // for gluing
+  std::vector<const Trk::TrackingVolume*> sVolsNeg;             // for gluing
+  std::vector<const Trk::TrackingVolume*> sVolsPos;             // for gluing
+  for (unsigned int eta = 0; eta < zSteps.size()-1; eta++) {
+    if (colorCode>0) colorCode = 26 -colorCode;
+    double posZ = 0.5*(zSteps[eta] + zSteps[eta+1]) ;
+    double   hZ = 0.5*fabs(zSteps[eta+1] - zSteps[eta]) ;
+    std::vector<std::vector<const Trk::TrackingVolume*> > phiSubs;
+    std::vector<Trk::SharedObject<Trk::BinnedArray<Trk::TrackingVolume> > >  phBins;
+    int phi = 0;
+    double posPhi = 0.;
+    double phiSect = M_PI;
+    std::vector<std::pair<int,float> > hSteps =  aLVC.m_shieldHPart[type];
+    std::vector<const Trk::TrackingVolume*> hSubs;
+    std::vector<Trk::TrackingVolumeOrderPosition> hSubsTr;
+    unsigned int hCode = 1; 
+    for (unsigned int h = 0; h < hSteps.size()-1; h++) {
+      hCode = (colorCode>0) ? 1 - hCode : 0; 
+      // define subvolume
+      subBds = new Trk::CylinderVolumeBounds(hSteps[h].second,
+					     hSteps[h+1].second,
+					     phiSect, 
+					     hZ);
+      Amg::Transform3D* transf = new Amg::Transform3D(Amg::AngleAxis3D(posPhi,Amg::Vector3D(0.,0.,1.))*Amg::Translation3D(Amg::Vector3D(0.,0.,posZ)));
+      Trk::Volume subVol(transf, subBds);
+      
+      // enclosed muon objects ? also adjusts material properties in case of material blend  
+      std::string volName = volumeName +MuonGM::buildString(eta,2) +MuonGM::buildString(phi,2) +MuonGM::buildString(h,2) ; 
+      blendVols.clear();
+      std::vector<const Trk::DetachedTrackingVolume*>* detVols= getDetachedObjects( &subVol, blendVols,aLVC);
+      
+      const Trk::TrackingVolume* sVol = new Trk::TrackingVolume( subVol,
+								 aLVC.m_muonMaterial,
+								 detVols,
+								 volName );
+      
+      // statistics
+      m_frameNum++ ; if (detVols) m_frameStat += detVols->size();  
+      // prepare blending
+      if (m_blendInertMaterial && blendVols.size()) {
+	for (unsigned int id=0;id<blendVols.size();id++) {
+	  if (!aLVC.m_blendMap[blendVols[id]]) {
+	    aLVC.m_blendMap[blendVols[id]] = new std::vector<const Trk::TrackingVolume*>;
+	    aLVC.m_blendVols.push_back(blendVols[id]);
+	  }
+	  aLVC.m_blendMap[blendVols[id]]->push_back(sVol);
+	}
+      }  
+      // reference point for the check of envelope
+      double posR = 0.5*(hSteps[h].second+hSteps[h+1].second);
+      // loop over inner cutouts
+      for (unsigned int in=1; in<aLVC.m_msCutoutsIn.size(); in++) {
+	if (posZ>=aLVC.m_msCutoutsIn[in].second && posZ<=aLVC.m_msCutoutsIn[in-1].second) {
+	  if (posR < aLVC.m_msCutoutsIn[in].first) sVol->sign(Trk::BeamPipe);
+	  break;
+	}
+      }
+      //
+      sVol->registerColorCode(colorCode+hCode);
+      // reference position 
+      Amg::Vector3D gp(subBds->mediumRadius(),0.,0.);
+      subVolumesVect.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol),
+								Amg::Vector3D((*transf)*gp)));
+      hSubsTr.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol, Trk::do_not_delete<const Trk::TrackingVolume>),
+                                                         Amg::Vector3D((*transf)*gp)));
+      hSubs.push_back(sVol);
+      
+      //glue subVolume
+      if (h==0)                sVolsInn.push_back(sVol); 
+      if (h==hSteps.size()-2)  sVolsOut.push_back(sVol); 
+      if (eta==0)      sVolsNeg.push_back(sVol); 
+      if (eta==etaN-1) sVolsPos.push_back(sVol); 
+      // in R/H
+      if (h>0) { // glue 'manually'
+	m_trackingVolumeHelper->setInsideTrackingVolume(*sVol, Trk::tubeSectorInnerCover,hSubs[h-1]); 
+	m_trackingVolumeHelper->setOutsideTrackingVolume(*(hSubs[h-1]), Trk::tubeSectorOuterCover,sVol);
+      }
+      // in eta
+      if ( etaN>1 && eta>0) m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*sVol, Trk::negativeFaceXY, hBins[eta-1][phi]);     
+    }	
+    phiSubs.push_back(hSubs); 
+    Trk::BinnedArray1D<Trk::TrackingVolume>* volBinArray = new Trk::BinnedArray1D<Trk::TrackingVolume>(hSubsTr,(*hBinUtil)[eta][phi]->clone());
+    phBins.push_back(Trk::SharedObject<Trk::BinnedArray<Trk::TrackingVolume> >(volBinArray));
+
+    // finish eta gluing
+    if ( etaN>1 && eta>0) {
+      for (unsigned int j=0; j<subVolumes[eta-1][phi].size(); j++) {
+	m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*(subVolumes[eta-1][phi][j]), Trk::positiveFaceXY,phBins[phi]);
+      }
+    }
+    subVolumes.push_back(phiSubs);
+    hBins.push_back(phBins);
+  }
+    
+  //Trk::BinUtility3DZFH* volBinUtil=new Trk::BinUtility3DZFH(zBinUtil,pBinUtil,hBinUtil,new Amg::Transform3D(vol->transform()));
+
+  Trk::BinnedArray1D1D1D<Trk::TrackingVolume>* subVols=new Trk::BinnedArray1D1D1D<Trk::TrackingVolume>(subVolumesVect,zBinUtil,pBinUtil,hBinUtil);
+  
+  tVol = new Trk::TrackingVolume( *vol,
+				  aLVC.m_muonMaterial,
+				  0,subVols,
+				  volumeName);
+  // register glue volumes
+  const Trk::GlueVolumesDescriptor& volGlueVolumes = tVol->glueVolumesDescriptor();
+  volGlueVolumes.registerGlueVolumes(Trk::tubeInnerCover,sVolsInn);
+  volGlueVolumes.registerGlueVolumes(Trk::tubeOuterCover,sVolsOut);
+  volGlueVolumes.registerGlueVolumes(Trk::negativeFaceXY,sVolsNeg);
+  volGlueVolumes.registerGlueVolumes(Trk::positiveFaceXY,sVolsPos);
+  
+  return tVol;
+} 
+
+std::vector<const Trk::DetachedTrackingVolume*>* Muon::MuonTrackingGeometryBuilderCond::getDetachedObjects(const Trk::Volume* vol, std::vector<const Trk::DetachedTrackingVolume*>& blendVols, LocalVariablesContainer &aLVC, int mode ) const
+{
+  // mode : 0 all, 1 active only, 2 inert only
+
+  std::vector<const Trk::DetachedTrackingVolume*>* detTVs = 0;
+
+  if (!m_stations && !m_inertObjs) return detTVs;
+  
+  // get min/max Z/Phi from volume (allways a cylinder/bevelled cylinder volume )  
+  const Trk::CylinderVolumeBounds* cyl = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(vol->volumeBounds()));
+  const Trk::BevelledCylinderVolumeBounds* bcyl = dynamic_cast<const Trk::BevelledCylinderVolumeBounds*> (&(vol->volumeBounds()));
+   
+  double rmed = 0.; double dphi = 0.; double hz = 0.; double rMin = 0.; double rMax = 0.; double rMaxc = 0.; int type = 0;
+  if (cyl) {
+    rmed = cyl->mediumRadius();
+    dphi = cyl->halfPhiSector();
+    hz = cyl->halflengthZ();
+    rMin = cyl->innerRadius();
+    rMax = cyl->outerRadius();
+    rMaxc = rMax;
+  } else if (bcyl) {
+    rmed = bcyl->mediumRadius();
+    dphi = bcyl->halfPhiSector();
+    hz = bcyl->halflengthZ();
+    rMin = bcyl->innerRadius();
+    rMax = bcyl->outerRadius();    
+    rMaxc = rMax;    
+    type = bcyl->type();
+    if (type>1) rMaxc *=1./cos(dphi);
+  } else return 0;
+ 
+  Amg::Vector3D center(rmed,0.,0.);
+  center = vol->transform() * center;
+
+  double zMin = center[2] - hz; 
+  double zMax = center[2] + hz;
+  double pMin = 0.;
+  double pMax = +2*M_PI;
+  bool phiLim = false;
+  if (dphi < M_PI) { 
+    pMin = center.phi() - dphi + M_PI; 
+    pMax = center.phi() + dphi + M_PI;
+    phiLim = true;
+  } 
+
+  ATH_MSG_VERBOSE( " zMin "<< zMin <<" zMax " <<zMax << " rMin "<< rMin <<" rMax "<<rMax << " rMaxc " << rMaxc << " phi limits "<< pMin <<" phiMax "<<pMax <<  " phiLim " << phiLim);
+
+  // define detector region : can extend over several
+  int gMin = (zMax <= -m_bigWheel) ? 0 : 1;
+  if ( zMin >= m_bigWheel ) gMin = 8;
+  else if ( zMin >= aLVC.m_innerEndcapZ ) gMin = 7;
+  else if ( zMin >= m_ectZ )         gMin = 6;
+  else if ( zMin >= m_diskShieldZ )      gMin = 5;
+  else if ( zMin >=-m_diskShieldZ )      gMin = 4;
+  else if ( zMin >=-m_ectZ )         gMin = 3;
+  else if ( zMin >=-aLVC.m_innerEndcapZ ) gMin = 2;
+  int gMax = (zMax >= m_bigWheel) ? 8 : 7;
+  if ( zMax <= -m_bigWheel ) gMax = 0;
+  else if ( zMax <= -aLVC.m_innerEndcapZ ) gMax = 1;
+  else if ( zMax <= -m_ectZ )         gMax = 2;
+  else if ( zMax <= -m_diskShieldZ )      gMax = 3;
+  else if ( zMax <= m_diskShieldZ )      gMax = 4;
+  else if ( zMax <= m_ectZ )         gMax = 5;
+  else if ( zMax <= aLVC.m_innerEndcapZ ) gMax = 6;
+
+  ATH_MSG_VERBOSE( " active volumes gMin "<< gMin<<" gMax "<<gMax);
+   
+  std::list<const Trk::DetachedTrackingVolume*> detached;
+  // active, use corrected rMax
+  if (mode <2 && aLVC.m_stationSpan) {
+    for (int gMode=gMin; gMode<=gMax; gMode++) {
+      for (unsigned int i=0; i<(*aLVC.m_stationSpan)[gMode]->size() ; i++) {
+	const Muon::Span* s = (*((*aLVC.m_stationSpan)[gMode]))[i].second;          // span
+	const Trk::DetachedTrackingVolume* station = (*((*aLVC.m_stationSpan)[gMode]))[i].first;   // station
+	bool rLimit = !aLVC.m_static3d || ( (*s)[4] <= rMaxc && (*s)[5] >= rMin );
+// Check meanZ for BME stations
+        bool meanZOK = false;
+        if(station->name()=="BME1_Station"||station->name()=="BME2_Station") {
+            if( ((*s)[0]+(*s)[1])/2.< zMax&&((*s)[0]+(*s)[1])/2.> zMin ) meanZOK = true;
+            if( ((*s)[2]+(*s)[3])/2 <pMin&&phiLim) meanZOK = false;
+            if( ((*s)[2]+(*s)[3])/2 <pMin&&phiLim) meanZOK = false;
+        }
+        if ( rLimit && (((*s)[0] < zMax && (*s)[1] > zMin)||meanZOK) ) {
+          bool accepted = false;
+          if (phiLim) {
+              if (pMin>=0 && pMax<=2*M_PI) {
+                if ( (*s)[2]<=(*s)[3] && (*s)[2] <= pMax && (*s)[3] >= pMin )  accepted = true;
+                if ( (*s)[2]>(*s)[3] && ((*s)[2] <= pMax || (*s)[3] >= pMin) ) accepted = true;
+              } else if (pMin < 0) {
+                if ( (*s)[2]<=(*s)[3] && ((*s)[2] <= pMax || (*s)[3] >= pMin+2*M_PI) ) accepted = true;
+                if ( (*s)[2]>(*s)[3]  ) accepted = true;
+              } else if (pMax > 2*M_PI) {
+                if ( (*s)[2]<=(*s)[3] && ((*s)[2] <= pMax-2*M_PI || (*s)[3] >= pMin) ) accepted = true;
+                if ( (*s)[2]>(*s)[3]  ) accepted = true;
+              }
+          } else  accepted = true;
+          if(meanZOK) accepted = true;
+          if (accepted) {
+              detached.push_back(station);
+              ATH_MSG_VERBOSE(" active volume accepted by rLimit " <<  station->name() << " zMin " << zMin << " zMax " << zMax << " rMin " << rMin << " rMax " << rMax << " PhiMin " << pMin  << " PhiMax " << pMax);
+          }
+        } else {
+//            ATH_MSG_VERBOSE( " active volume rejected by rLimit " <<  station->name() );
+	} 
+      }
+    }
+  }
+  // passive 
+  if (mode !=1 && aLVC.m_inertSpan) {
+    for (int gMode=gMin; gMode<=gMax; gMode++) {
+      for (unsigned int i=0; i<(*aLVC.m_inertSpan)[gMode]->size() ; i++) {
+	const Muon::Span* s = (*((*aLVC.m_inertSpan)[gMode]))[i].second;
+	const Trk::DetachedTrackingVolume* inert = (*((*aLVC.m_inertSpan)[gMode]))[i].first;
+	//bool rail = ( (*m_inertObjs)[i]->name() == "Rail" ) ? true : false; 
+	bool rLimit = (!aLVC.m_static3d || ( (*s)[4] <= rMaxc && (*s)[5] >= rMin ) ); 
+	if ( rLimit && (*s)[0] < zMax && (*s)[1] > zMin ) {
+	  bool accepted = false;
+	  if (phiLim) {
+	    if (pMin>=0 && pMax<=2*M_PI) {
+	      if ( (*s)[2]<=(*s)[3] && (*s)[2] <= pMax && (*s)[3] >= pMin )  accepted = true;
+	      if ( (*s)[2]>(*s)[3] && ((*s)[2] <= pMax || (*s)[3] >= pMin) ) accepted = true;
+	    } else if (pMin < 0) {
+	      if ( (*s)[2]<=(*s)[3] && ((*s)[2] <= pMax || (*s)[3] >= pMin+2*M_PI) ) accepted = true;
+	      if ( (*s)[2]>(*s)[3]  ) accepted = true;
+	    } else if (pMax > 2*M_PI) {
+	      if ( (*s)[2]<=(*s)[3] && ((*s)[2] <= pMax-2*M_PI || (*s)[3] >= pMin) ) accepted = true;
+	      if ( (*s)[2]>(*s)[3]  ) accepted = true;
+	    }
+	  } else  accepted = true;
+	  if (accepted) {
+	    bool perm = inert->name().substr(inert->name().size()-4,4)=="PERM";
+	    if ( !m_blendInertMaterial || !m_removeBlended || perm ) detached.push_back(inert);
+	    if ( m_blendInertMaterial && !perm ) blendVols.push_back(inert);
+            ATH_MSG_VERBOSE( " Inert volume accepted by rLimit " <<  inert->name() << " zMin " << zMin << " zMax " << zMax << " rMin " << rMin << " rMax " << rMax << " PhiMin " << pMin  << " PhiMax " << pMax);
+	  }
+	}
+      } 
+    }
+  }
+  if (!detached.empty()) detTVs = new std::vector<const Trk::DetachedTrackingVolume*>(detached.begin(), detached.end()); 
+  return detTVs;
+}
+
+bool Muon::MuonTrackingGeometryBuilderCond::enclosed(const Trk::Volume* vol, const Muon::Span* s, LocalVariablesContainer &aLVC) const
+{
+  bool encl = false;
+  double tol = 1.;
+  double ptol = 0.11;     // 0.08 for BT, 0.11 feet
+  
+  // get min/max Z/Phi from volume (allways a cylinder/bevelled cylinder volume )  
+  const Trk::CylinderVolumeBounds* cyl = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(vol->volumeBounds()));
+  const Trk::BevelledCylinderVolumeBounds* bcyl = dynamic_cast<const Trk::BevelledCylinderVolumeBounds*> (&(vol->volumeBounds()));
+   
+  double rmed = 0.; double dphi = 0.; double hz = 0.; double rMin = 0.; double rMax = 0.; double rMaxc = 0.; int type = 0;
+  if (cyl) {
+    rmed = cyl->mediumRadius();
+    dphi = cyl->halfPhiSector();
+    hz = cyl->halflengthZ();
+    rMin = cyl->innerRadius();
+    rMax = cyl->outerRadius();
+    rMaxc = rMax;
+  } else if (bcyl) {
+    rmed = bcyl->mediumRadius();
+    dphi = bcyl->halfPhiSector();
+    hz = bcyl->halflengthZ();
+    rMin = bcyl->innerRadius();
+    rMax = bcyl->outerRadius();    
+    rMaxc = rMax;    
+    type = bcyl->type();
+    if (type>1) rMaxc *=1./cos(dphi);
+  } else return 0;
+ 
+  Amg::Vector3D center(rmed,0.,0.);
+  center = vol->transform() * center;
+
+  double zMin = center[2] - hz; 
+  double zMax = center[2] + hz;
+  double pMin = 0.;
+  double pMax = +2*M_PI;
+  bool phiLim = false;
+  if (dphi < M_PI) { 
+    pMin = center.phi() - dphi + M_PI; 
+    pMax = center.phi() + dphi + M_PI;
+    phiLim = true;
+  } 
+  //
+  //const Muon::Span* s = findVolumeSpan(&(cs->volumeBounds()), cs->transform(), 0.,0.) ;
+  //std::auto_ptr<const Muon::Span> s (findVolumeSpan(&(cs->volumeBounds()), cs->transform(), 0.,0.) );
+  ATH_MSG_VERBOSE( "enclosing volume:z:"<< zMin<<","<<zMax<<":r:"<< rMin<<","<<rMax<<":phi:"<<pMin<<","<<pMax);
+  //
+  bool rLimit = (!aLVC.m_static3d || ( (*s)[4] < rMax-tol && (*s)[5] > rMin+tol ) ); 
+  if ( rLimit && (*s)[0] < zMax-tol && (*s)[1] > zMin+tol ) {
+    if (phiLim) {
+      if (pMin>=0 && pMax<=2*M_PI) {
+	if ( (*s)[2]<=(*s)[3] && (*s)[2] < pMax+ptol && (*s)[3] > pMin-ptol )  return true;
+	if ( (*s)[2]>(*s)[3] && ((*s)[2] < pMax-ptol || (*s)[3] > pMin+ptol) ) return true;
+      } else if (pMin < 0) {
+	if ( (*s)[2]<=(*s)[3] && ((*s)[2] < pMax+ptol || (*s)[3] > pMin-ptol+2*M_PI) ) return true;
+	if ( (*s)[2]>(*s)[3]  ) return true;
+      } else if (pMax > 2*M_PI) {
+	if ( (*s)[2]<=(*s)[3] && ((*s)[2] < pMax+ptol-2*M_PI || (*s)[3] > pMin-ptol) ) return true;
+	if ( (*s)[2]>(*s)[3]  ) return true;
+      }
+    } else {
+      return true;
+    }
+  }
+  return encl;
+}
+
+void Muon::MuonTrackingGeometryBuilderCond::checkVolume(const Trk::TrackingVolume* vol ) const
+{
+
+  std::cout << "MuonTrackingGeometryBuilderCond::checkVolume: " << vol->volumeName() << std::endl;
+
+  const Trk::CylinderVolumeBounds* cyl = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(vol->volumeBounds()));
+  if (!cyl) {
+    std::cout << "MuonTrackingGeometryBuilderCond::checkVolume:not a cylinder, return" << std::endl;
+    return;
+  }
+  std::cout << "cylinder dimensions:innerR,outerR,halfZ,halfPhi:" << cyl->innerRadius() << "," << cyl->outerRadius()
+	    << cyl->halflengthZ() << "," << cyl->halfPhiSector() << std::endl;
+
+  const Trk::GlueVolumesDescriptor& glueDescr = vol->glueVolumesDescriptor();
+  std::cout << "glue volumes:neg,pos,inn,outer" << (glueDescr.glueVolumes(Trk::negativeFaceXY)).size()<<"," 
+                                                << (glueDescr.glueVolumes(Trk::positiveFaceXY)).size()<<","
+                                                << (glueDescr.glueVolumes(Trk::tubeInnerCover)).size()<<","
+	                                        << (glueDescr.glueVolumes(Trk::tubeOuterCover)).size()<<std::endl;
+}
+
+void Muon::MuonTrackingGeometryBuilderCond::getZParts(LocalVariablesContainer& aLVC) const
+{
+  // activeAdjustLevel:  1: separate MDT stations
+  //                        +(inertLevel=0) barrel Z partition
+  //                     2: split TGC
+  //                        +(inertLevel=0) barrel R partition
+  //                     3: split TGC supports
+  // inertAdjustLevel:   1: BT,ECT     
+ 
+  // hardcode for the moment
+  aLVC.m_zPartitions.clear();
+  aLVC.m_zPartitionsType.clear();
+  aLVC.m_zPartitions.reserve(120);
+  aLVC.m_zPartitionsType.reserve(120);
+
+  // outer endcap
+  aLVC.m_zPartitions.push_back(-aLVC.m_outerEndcapZ);  aLVC.m_zPartitionsType.push_back(1);   // EO
+  aLVC.m_zPartitions.push_back(-23001.);  aLVC.m_zPartitionsType.push_back(1);   // oute envelope change
+  //if (m_activeAdjustLevel>0) { m_zPartitions.push_back(-21630.);  m_zPartitionsType.push_back(1); }   // EOL
+  aLVC.m_zPartitions.push_back(-22030.);  aLVC.m_zPartitionsType.push_back(1);   // EOL
+  aLVC.m_zPartitions.push_back(-m_outerWheel);    aLVC.m_zPartitionsType.push_back(0);   // Octogon
+  // m_zPartitions.push_back(-17990.);          m_zPartitionsType.push_back(0);   // buffer
+  aLVC.m_zPartitions.push_back(-18650.);          aLVC.m_zPartitionsType.push_back(0);   // buffer
+  aLVC.m_zPartitions.push_back(-m_bigWheel);      aLVC.m_zPartitionsType.push_back(1);   // TGC3 
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-15225.);  aLVC.m_zPartitionsType.push_back(1);}    
+  if (m_activeAdjustLevel>1) { aLVC.m_zPartitions.push_back(-15172.);  aLVC.m_zPartitionsType.push_back(1);}   // end supp 
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-15128.);  aLVC.m_zPartitionsType.push_back(1);}   // supp 
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-15070.);  aLVC.m_zPartitionsType.push_back(1);}    
+  if (m_activeAdjustLevel>0) { aLVC.m_zPartitions.push_back(-14940.);  aLVC.m_zPartitionsType.push_back(1); }  //
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-14805.);  aLVC.m_zPartitionsType.push_back(1);}    
+  if (m_activeAdjustLevel>1) { aLVC.m_zPartitions.push_back(-14733.);  aLVC.m_zPartitionsType.push_back(1);}   // end supp.
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-14708.);  aLVC.m_zPartitionsType.push_back(1);}   // supp.   
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-14650.);  aLVC.m_zPartitionsType.push_back(1);}   //    
+  if (m_activeAdjustLevel>0) { aLVC.m_zPartitions.push_back(-14560.);  aLVC.m_zPartitionsType.push_back(1); }   // EML 
+  if (m_activeAdjustLevel>0) { aLVC.m_zPartitions.push_back(-14080.);  aLVC.m_zPartitionsType.push_back(1); }   // EMS
+  if (m_activeAdjustLevel>0) { aLVC.m_zPartitions.push_back(-13620.);  aLVC.m_zPartitionsType.push_back(1); }   // TGC
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-13525.);  aLVC.m_zPartitionsType.push_back(1); }   // TGC
+  if (m_activeAdjustLevel>1) { aLVC.m_zPartitions.push_back(-13448.5); aLVC.m_zPartitionsType.push_back(1); }   // end supp.
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-13421.5); aLVC.m_zPartitionsType.push_back(1); }   // supp.
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-13346);   aLVC.m_zPartitionsType.push_back(1); }   // TGC
+
+  // inner endcap
+  aLVC.m_zPartitions.push_back(-aLVC.m_innerEndcapZ);     aLVC.m_zPartitionsType.push_back(0);   // 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-12790);  aLVC.m_zPartitionsType.push_back(0); }   // ECT 
+  if (m_inertAdjustLevel>1) { aLVC.m_zPartitions.push_back(-12100.); aLVC.m_zPartitionsType.push_back(0); }   // 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-12000.); aLVC.m_zPartitionsType.push_back(0); }   // 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-11210.); aLVC.m_zPartitionsType.push_back(1); }   // BT 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-10480.); aLVC.m_zPartitionsType.push_back(0); }   // 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-9700.);  aLVC.m_zPartitionsType.push_back(0); }   // 
+  if (m_inertAdjustLevel>1) { aLVC.m_zPartitions.push_back(-9300.);  aLVC.m_zPartitionsType.push_back(0); }   // rib
+  if (m_inertAdjustLevel>1) { aLVC.m_zPartitions.push_back(-8800.);  aLVC.m_zPartitionsType.push_back(0); }   // ect
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-8610.);  aLVC.m_zPartitionsType.push_back(1); }   // BT
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-8000.);  aLVC.m_zPartitionsType.push_back(1); }   // BT
+  aLVC.m_zPartitions.push_back(-m_ectZ);  aLVC.m_zPartitionsType.push_back(0);              // ECT/small wheel
+  if (m_activeAdjustLevel>0) { aLVC.m_zPartitions.push_back(-7450.); aLVC.m_zPartitionsType.push_back(0); }   // EIS 
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-7364.); aLVC.m_zPartitionsType.push_back(0); }   // EIS 
+  if (m_activeAdjustLevel>0 || m_inertAdjustLevel>0) {aLVC.m_zPartitions.push_back(-7170.); aLVC.m_zPartitionsType.push_back(0);}   // cone assembly,TGC 
+  if (m_activeAdjustLevel>0) { aLVC.m_zPartitions.push_back(-7030.); aLVC.m_zPartitionsType.push_back(0); }   // TGC
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-6978.); aLVC.m_zPartitionsType.push_back(0); }   // TGC
+
+  // barrel
+  aLVC.m_zPartitions.push_back(-m_diskShieldZ);   aLVC.m_zPartitionsType.push_back(0);   // disk 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-6829.);  aLVC.m_zPartitionsType.push_back(0); }   // back disk 
+  //if (m_inertAdjustLevel>1) { (*m_zPartitions).push_back(-6600.);  m_zPartitionsType.push_back(0); }   // 
+  aLVC.m_zPartitions.push_back(-6550.); aLVC.m_zPartitionsType.push_back(0);          // outer envelope change
+  if (m_activeAdjustLevel>0){ aLVC.m_zPartitions.push_back(-6100.);  aLVC.m_zPartitionsType.push_back(0); }  
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-5503.);  aLVC.m_zPartitionsType.push_back(1); }   // BT 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-4772.);  aLVC.m_zPartitionsType.push_back(0); }   //  
+  if (m_activeAdjustLevel>0){ aLVC.m_zPartitions.push_back(-4300.);  aLVC.m_zPartitionsType.push_back(0); }  //  
+  aLVC.m_zPartitions.push_back(-4000.); aLVC.m_zPartitionsType.push_back(0);          // outer envelope change
+  if (m_inertAdjustLevel>1) { aLVC.m_zPartitions.push_back(-3700.);  aLVC.m_zPartitionsType.push_back(0); }   //  
+  if (m_inertAdjustLevel>1) { aLVC.m_zPartitions.push_back(-3300.);  aLVC.m_zPartitionsType.push_back(0); }   //  
+  if (m_activeAdjustLevel>0){ aLVC.m_zPartitions.push_back(-2600.);  aLVC.m_zPartitionsType.push_back(0); }   //  
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-2078.);  aLVC.m_zPartitionsType.push_back(1); }   // BT  
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-1347.);  aLVC.m_zPartitionsType.push_back(1); }   //  cryoring 
+  if (m_activeAdjustLevel>0){ aLVC.m_zPartitions.push_back(-800.);   aLVC.m_zPartitionsType.push_back(1); }  //  cryoring 
+  if (m_inertAdjustLevel>1) { aLVC.m_zPartitions.push_back(-300.);   aLVC.m_zPartitionsType.push_back(0); }   //   
+  if (static_cast<int>(m_inertAdjustLevel)+static_cast<int>(m_activeAdjustLevel)<1) { aLVC.m_zPartitions.push_back(-0.7*m_diskShieldZ);   aLVC.m_zPartitionsType.push_back(0); }   //
+
+  unsigned int zSiz = aLVC.m_zPartitions.size();
+  for (unsigned int i = 0; i<zSiz ; i++) {
+    aLVC.m_zPartitions.push_back(- aLVC.m_zPartitions[zSiz-1-i]);  
+    if (i<zSiz-1) aLVC.m_zPartitionsType.push_back(aLVC.m_zPartitionsType[zSiz-2-i]);  
+  } 
+  
+  return;
+}
+
+void Muon::MuonTrackingGeometryBuilderCond::getPhiParts(int mode, LocalVariablesContainer &aLVC) const
+{
+  if (mode==0) {             // trivial
+    aLVC.m_adjustedPhi.clear();
+    aLVC.m_adjustedPhiType.clear();
+    aLVC.m_adjustedPhi.push_back(0.);
+    aLVC.m_adjustedPhiType.push_back(0);
+
+  } else if (mode==1) {  
+    int phiNum = 1;
+    if ( m_activeAdjustLevel>0 ) phiNum = m_phiPartition;
+    aLVC.m_adjustedPhi.resize(phiNum);
+    aLVC.m_adjustedPhiType.resize(phiNum);
+    aLVC.m_adjustedPhi[0] = 0.;
+    aLVC.m_adjustedPhiType[0] = 0;
+    int ic = 0;
+    while (ic < phiNum-1 ) {
+      ic++; 
+      aLVC.m_adjustedPhi[ic]= aLVC.m_adjustedPhi[ic-1] + 2.*M_PI/phiNum ;
+      aLVC.m_adjustedPhiType[ic]= 0;
+    }
+
+  } else if (mode==2) {        // barrel(BT)
+    // hardcode for the moment
+    aLVC.m_adjustedPhi.resize(16);
+    aLVC.m_adjustedPhiType.resize(16);
+    
+    double phiSect[2];
+    phiSect[0] = ( M_PI/8 - 0.105 ); 
+    phiSect[1] = 0.105 ; 
+    
+    aLVC.m_adjustedPhi[0]= - phiSect[0];
+    aLVC.m_adjustedPhiType[0]= 0;
+    int ic = 0; int is = 1;
+
+    while (ic < 15 ) {
+      ic++; is = 1 - is;
+      aLVC.m_adjustedPhi[ic]= aLVC.m_adjustedPhi[ic-1] + 2*phiSect[is] ;
+      aLVC.m_adjustedPhiType[ic]= 1-is;
+    }
+
+  } else if (mode==3) {      // ECT(+BT)
+    // hardcode for the moment
+    aLVC.m_adjustedPhi.resize(32);
+    aLVC.m_adjustedPhiType.resize(32);
+    
+    double phiSect[3];
+    phiSect[0] = 0.126;
+    phiSect[2] = 0.105;
+    phiSect[1] = 0.5*( M_PI/8. - phiSect[0]-phiSect[2] ); 
+    
+    aLVC.m_adjustedPhi[0]= - phiSect[0];
+    aLVC.m_adjustedPhiType[0]= 0;
+    aLVC.m_adjustedPhi[1]= aLVC.m_adjustedPhi[0]+2*phiSect[0];
+    aLVC.m_adjustedPhiType[1]= 1;
+    int ic = 1; int is = 0;
+
+    while (ic < 31 ) {
+      ic++; is = 2 - is;
+      aLVC.m_adjustedPhi[ic]= aLVC.m_adjustedPhi[ic-1] + 2*phiSect[1] ;
+      aLVC.m_adjustedPhiType[ic]= is;
+      ic++;
+      aLVC.m_adjustedPhi[ic]= aLVC.m_adjustedPhi[ic-1] + 2*phiSect[is] ;
+      aLVC.m_adjustedPhiType[ic]= 1;
+    }
+    //for (unsigned int ic=0;ic<m_adjustedPhi.size();ic++) std::cout<<"adjustedPhi:"<<ic<<","<<m_adjustedPhi[ic]<<","<<m_adjustedPhiType[ic]<< std::endl;
+  }
+
+  return;
+}
+
+void Muon::MuonTrackingGeometryBuilderCond::getHParts(LocalVariablesContainer &aLVC) const
+{
+  // hardcode for the moment
+  aLVC.m_hPartitions.clear();              // barrel, inner endcap, outer endcap
+
+  // 0: barrel 2x2
+  // non BT sector
+  std::vector<std::pair<int,float> >  barrelZ0F0;
+  barrelZ0F0.push_back( std::pair<int,float>(0,aLVC.m_innerBarrelRadius) );
+  if (m_activeAdjustLevel>0) {
+    barrelZ0F0.push_back( std::pair<int,float>(0,4450.) );                // for DiskShieldingBackDisk
+    barrelZ0F0.push_back( std::pair<int,float>(0,6500.) );                // BI/BM
+    barrelZ0F0.push_back( std::pair<int,float>(0,8900.) );                // BM/BO
+    barrelZ0F0.push_back( std::pair<int,float>(0,13000.) );               // outer envelope
+  }
+  barrelZ0F0.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::pair<int,float> >  barrelZ0F1;
+  barrelZ0F1.push_back( std::pair<int,float>(0,aLVC.m_innerBarrelRadius) );
+  if (m_inertAdjustLevel>0) {
+    barrelZ0F1.push_back( std::pair<int,float>(1,4500.) );
+    barrelZ0F1.push_back( std::pair<int,float>(1,5900.) );
+  } else if (m_activeAdjustLevel>0) barrelZ0F1.push_back( std::pair<int,float>(0,4450.) );                
+  if (m_activeAdjustLevel>0) barrelZ0F1.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0)  barrelZ0F1.push_back( std::pair<int,float>(1,8900.) );
+  else if (m_activeAdjustLevel>0)  barrelZ0F1.push_back( std::pair<int,float>(0,8900.) );
+  if (m_inertAdjustLevel>0)  barrelZ0F1.push_back( std::pair<int,float>(1,10100.) );
+  barrelZ0F1.push_back( std::pair<int,float>(0,13000.) );               // outer envelope
+  barrelZ0F1.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // BT sector
+  std::vector<std::pair<int,float> >  barrelZ1F0;
+  barrelZ1F0.push_back( std::pair<int,float>(0,aLVC.m_innerBarrelRadius) );
+  if (static_cast<int>(m_activeAdjustLevel)+static_cast<int>(m_inertAdjustLevel)>0) barrelZ1F0.push_back( std::pair<int,float>(0,4450.) );                
+  if (m_inertAdjustLevel>0) {
+    barrelZ1F0.push_back( std::pair<int,float>(1,5800.) );
+    barrelZ1F0.push_back( std::pair<int,float>(1,6500.) );
+  } else if (m_activeAdjustLevel>0) barrelZ1F0.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0) {
+    barrelZ1F0.push_back( std::pair<int,float>(1,6750.) );
+    barrelZ1F0.push_back( std::pair<int,float>(1,8400.) );
+  }
+  if (m_activeAdjustLevel>0) barrelZ1F0.push_back( std::pair<int,float>(0,8770.) );  // adapted for cryoring (from 8900)
+  if (m_inertAdjustLevel>0) barrelZ1F0.push_back( std::pair<int,float>(1,9850.) );   // adapted for cryoring (from 9600)
+  barrelZ1F0.push_back( std::pair<int,float>(0,13000.) );               // outer envelope
+  barrelZ1F0.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::pair<int,float> >  barrelZ1F1;
+  barrelZ1F1.push_back( std::pair<int,float>(0,aLVC.m_innerBarrelRadius) );
+  if (m_inertAdjustLevel>0) {
+    barrelZ1F1.push_back( std::pair<int,float>(1,4500.) );
+    barrelZ1F1.push_back( std::pair<int,float>(1,6000.) );
+  } else if (m_activeAdjustLevel>0) barrelZ1F1.push_back( std::pair<int,float>(0,4450.) );
+  if (m_activeAdjustLevel>0) barrelZ1F1.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0) barrelZ1F1.push_back( std::pair<int,float>(1,6800.) );
+  if (m_inertAdjustLevel>0) {
+    barrelZ1F1.push_back( std::pair<int,float>(1,8900.) );
+    barrelZ1F1.push_back( std::pair<int,float>(1,10100.) );
+  } else if (m_activeAdjustLevel>0) barrelZ1F1.push_back( std::pair<int,float>(0,8900.) );
+  barrelZ1F1.push_back( std::pair<int,float>(0,13000.) );               // outer envelope
+  barrelZ1F1.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::vector<std::vector<std::pair<int,float> > > >  barrelZF(2);
+  barrelZF[0].push_back(barrelZ0F0);
+  barrelZF[0].push_back(barrelZ0F1);
+  barrelZF[1].push_back(barrelZ1F0);
+  barrelZF[1].push_back(barrelZ1F1);
+
+  // small wheel 1x2 ( no z BT sector) 
+  // non BT sector
+  std::vector<std::pair<int,float> >  swZ0F0;
+  swZ0F0.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_activeAdjustLevel>1) {
+    swZ0F0.push_back( std::pair<int,float>(0,2700.) );                
+  }
+  if (static_cast<int>(m_activeAdjustLevel)+static_cast<int>(m_inertAdjustLevel)>0) swZ0F0.push_back( std::pair<int,float>(0,4450.) );                
+  if (m_activeAdjustLevel>0) {
+    swZ0F0.push_back( std::pair<int,float>(0,6560.) );                // BI/BM
+    swZ0F0.push_back( std::pair<int,float>(0,8900.) );                // BM/BO
+  }
+  swZ0F0.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // phi BT sector
+  std::vector<std::pair<int,float> >  swZ0F1;
+  swZ0F1.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_activeAdjustLevel>1) swZ0F1.push_back( std::pair<int,float>(0,2700.) );               
+  if (static_cast<int>(m_inertAdjustLevel)+static_cast<int>(m_activeAdjustLevel)>0) swZ0F1.push_back( std::pair<int,float>(0,4450.) );
+  if (m_inertAdjustLevel>0) swZ0F1.push_back( std::pair<int,float>(1,5900.) );
+  if (m_activeAdjustLevel>0) swZ0F1.push_back( std::pair<int,float>(0,6560.) );
+  if (m_inertAdjustLevel>0) {
+    swZ0F1.push_back( std::pair<int,float>(1,8900.) );
+    swZ0F1.push_back( std::pair<int,float>(1,10100.) );
+  } else if (m_activeAdjustLevel>0) swZ0F1.push_back( std::pair<int,float>(0,8900.) );
+  swZ0F1.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::vector<std::vector<std::pair<int,float> > > >  swZF(1);
+  swZF[0].push_back(swZ0F0);
+  swZF[0].push_back(swZ0F1);
+
+  // inner endcap/ECT 2x3
+  // ect coil, non-BT z
+  std::vector<std::pair<int,float> >  innerZ0F0;
+  innerZ0F0.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_inertAdjustLevel>0) innerZ0F0.push_back( std::pair<int,float>(0,1100.) );
+  if (m_inertAdjustLevel>1) innerZ0F0.push_back( std::pair<int,float>(1,5150.) );
+  if (m_inertAdjustLevel>0) innerZ0F0.push_back( std::pair<int,float>(1,5300.) );
+  if (m_activeAdjustLevel>0) {
+    innerZ0F0.push_back( std::pair<int,float>(0,6500.) );
+    innerZ0F0.push_back( std::pair<int,float>(0,8900.) );
+  }
+  innerZ0F0.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // coil gap, non-BT z
+  std::vector<std::pair<int,float> >  innerZ0F1;
+  innerZ0F1.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_inertAdjustLevel>0) innerZ0F1.push_back( std::pair<int,float>(0,1100.) );
+  if (m_inertAdjustLevel>1) {
+    innerZ0F1.push_back( std::pair<int,float>(1,1400.) );
+    innerZ0F1.push_back( std::pair<int,float>(1,1685.) );
+  }
+  if (m_inertAdjustLevel>0) {
+    innerZ0F1.push_back( std::pair<int,float>(1,4700.) );
+    innerZ0F1.push_back( std::pair<int,float>(1,5900.) );
+  }
+  if (m_activeAdjustLevel>0) {
+    innerZ0F1.push_back( std::pair<int,float>(0,6500.) );
+    innerZ0F1.push_back( std::pair<int,float>(0,8900.) );
+  }
+  innerZ0F1.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // BT coil, no-BT z 
+  std::vector<std::pair<int,float> >  innerZ0F2;
+  innerZ0F2.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_inertAdjustLevel>0) innerZ0F2.push_back( std::pair<int,float>(0,1100.) );
+  if (m_inertAdjustLevel>1) {
+    innerZ0F2.push_back( std::pair<int,float>(1,1400.) );
+    innerZ0F2.push_back( std::pair<int,float>(1,1685.) );
+  }
+  if (m_inertAdjustLevel>0) {
+    innerZ0F2.push_back( std::pair<int,float>(1,4450.) );
+    innerZ0F2.push_back( std::pair<int,float>(1,5900.) );
+  }
+  if (m_activeAdjustLevel>0) innerZ0F2.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0) {
+    innerZ0F2.push_back( std::pair<int,float>(1,8900.) );
+    innerZ0F2.push_back( std::pair<int,float>(1,10100.) );
+  } else if (m_activeAdjustLevel>0) innerZ0F2.push_back( std::pair<int,float>(0,8900.) );
+  innerZ0F2.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // ect coil, z BT sector
+  std::vector<std::pair<int,float> >  innerZ1F0;
+  innerZ1F0.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_inertAdjustLevel>0) innerZ1F0.push_back( std::pair<int,float>(0,1100.) );
+  if (m_inertAdjustLevel>1) innerZ1F0.push_back( std::pair<int,float>(1,5150.) );
+  if (m_inertAdjustLevel>0) innerZ1F0.push_back( std::pair<int,float>(1,5300.) );
+  if (m_inertAdjustLevel>0) innerZ1F0.push_back( std::pair<int,float>(1,5800.) );
+  if (m_inertAdjustLevel>0) innerZ1F0.push_back( std::pair<int,float>(1,6750.) );
+  else if (m_activeAdjustLevel>0) innerZ1F0.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0) {
+    innerZ1F0.push_back( std::pair<int,float>(1,8400.) );
+    innerZ1F0.push_back( std::pair<int,float>(1,9600.) );
+  } else if (m_activeAdjustLevel>0) innerZ1F0.push_back( std::pair<int,float>(0,8900.) );
+  innerZ1F0.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // coil gap, BT z sector
+  std::vector<std::pair<int,float> >  innerZ1F1;
+  innerZ1F1.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_inertAdjustLevel>0)  innerZ1F1.push_back( std::pair<int,float>(0,1100.) );
+  if (m_inertAdjustLevel>1) {
+    innerZ1F1.push_back( std::pair<int,float>(1,1400.) );
+    innerZ1F1.push_back( std::pair<int,float>(1,1685.) );
+  }
+  if (m_inertAdjustLevel>0) {
+    innerZ1F1.push_back( std::pair<int,float>(1,4700.) );
+    innerZ1F1.push_back( std::pair<int,float>(1,5800.) );
+    innerZ1F1.push_back( std::pair<int,float>(1,6750.) );
+  } else if (m_activeAdjustLevel>0) innerZ1F1.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0) {
+    innerZ1F1.push_back( std::pair<int,float>(1,8400.) );
+    innerZ1F1.push_back( std::pair<int,float>(1,9600.) );
+  } else if (m_activeAdjustLevel>0) innerZ1F1.push_back( std::pair<int,float>(0,8900.) );
+  innerZ1F1.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // BT coil, BT z sector
+  std::vector<std::pair<int,float> >  innerZ1F2;
+  innerZ1F2.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_inertAdjustLevel>0) innerZ1F2.push_back( std::pair<int,float>(0,1100.) );
+  if (m_inertAdjustLevel>1) {
+    innerZ1F2.push_back( std::pair<int,float>(1,1400.) );
+    innerZ1F2.push_back( std::pair<int,float>(1,1685.) );
+  }
+  innerZ1F2.push_back( std::pair<int,float>(0,4150.) );
+  if (m_inertAdjustLevel>0) {
+    innerZ1F2.push_back( std::pair<int,float>(1,4700.) );
+    innerZ1F2.push_back( std::pair<int,float>(1,5900.) );
+    innerZ1F2.push_back( std::pair<int,float>(1,6800.) );
+  } else if (m_activeAdjustLevel>0) innerZ1F2.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0) {
+    innerZ1F2.push_back( std::pair<int,float>(1,8900.) );
+    innerZ1F2.push_back( std::pair<int,float>(1,10100.) );
+  } else if (m_activeAdjustLevel>0) innerZ1F2.push_back( std::pair<int,float>(0,8900.) );
+  innerZ1F2.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::vector<std::vector<std::pair<int,float> > > >  innerZF(2);
+  innerZF[0].push_back(innerZ0F0);
+  innerZF[0].push_back(innerZ0F1);
+  innerZF[0].push_back(innerZ0F2);
+  innerZF[1].push_back(innerZ1F0);
+  innerZF[1].push_back(innerZ1F1);
+  innerZF[1].push_back(innerZ1F2);
+
+  // outer 1x1
+  std::vector<std::pair<int,float> >  outerZ0F0;
+  outerZ0F0.push_back( std::pair<int,float>(0,m_outerShieldRadius) );
+  outerZ0F0.push_back( std::pair<int,float>(0,2750.) );       // outer envelope 
+  outerZ0F0.push_back( std::pair<int,float>(0,12650.) );      // outer envelope
+  outerZ0F0.push_back( std::pair<int,float>(0,13400.) );      // outer envelope
+  outerZ0F0.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::pair<int,float> >  outerZ0F1;
+  outerZ0F1.push_back( std::pair<int,float>(0,m_outerShieldRadius) );
+  outerZ0F1.push_back( std::pair<int,float>(0,2750.) );      // outer envelope
+  if ( m_activeAdjustLevel>0 ) {
+    outerZ0F1.push_back( std::pair<int,float>(0,3600.) );
+    outerZ0F1.push_back( std::pair<int,float>(0,5300.) );
+    outerZ0F1.push_back( std::pair<int,float>(0,7000.) );
+    outerZ0F1.push_back( std::pair<int,float>(0,8500.) );
+    outerZ0F1.push_back( std::pair<int,float>(0,10000.) );
+    outerZ0F1.push_back( std::pair<int,float>(0,12000.) );
+  }
+  outerZ0F1.push_back( std::pair<int,float>(0,12650.) );      // outer envelope
+  outerZ0F1.push_back( std::pair<int,float>(0,13400.) );      // outer envelope
+  outerZ0F1.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::vector<std::vector<std::pair<int,float> > > >  outerZF(2);
+  outerZF[0].push_back(outerZ0F0);
+  outerZF[0].push_back(outerZ0F0);
+  outerZF[0].push_back(outerZ0F0);
+  outerZF[1].push_back(outerZ0F1);
+  outerZF[1].push_back(outerZ0F1);
+  outerZF[1].push_back(outerZ0F1);
+
+  // collect everything
+  aLVC.m_hPartitions.push_back(barrelZF);
+  aLVC.m_hPartitions.push_back(swZF);
+  aLVC.m_hPartitions.push_back(innerZF);
+  aLVC.m_hPartitions.push_back(outerZF);
+   
+  return;
+}
+
+void Muon::MuonTrackingGeometryBuilderCond::getShieldParts(LocalVariablesContainer& aLVC) const
+{
+  aLVC.m_shieldZPart.resize(18);
+
+  aLVC.m_shieldZPart[0]=-21900.;      // elm2
+  aLVC.m_shieldZPart[1]=-21500.;      // elm1
+  aLVC.m_shieldZPart[2]=-21000.;      // octogon
+  aLVC.m_shieldZPart[3]=-18000.;      // tube
+  aLVC.m_shieldZPart[4]=-12882.;      // ect
+  aLVC.m_shieldZPart[5]= -7930.;      // ect
+  aLVC.m_shieldZPart[6]= -7914.;      // cone
+  aLVC.m_shieldZPart[7]= -6941.;      // disk
+  aLVC.m_shieldZPart[8]= -6783.;       //
+  for (unsigned int i = 9; i<18 ; i++) aLVC.m_shieldZPart[i] = - aLVC.m_shieldZPart[17-i];  
+
+  aLVC.m_shieldHPart.clear();
+
+  std::vector<std::pair<int,float> >  outerShield;
+  outerShield.push_back(std::pair<int,float>(0,m_beamPipeRadius));
+  outerShield.push_back(std::pair<int,float>(0,279.));    // outer envelope
+  outerShield.push_back(std::pair<int,float>(0,436.7));   // outer envelope
+  outerShield.push_back(std::pair<int,float>(0,1050.));   // outer envelope 
+  outerShield.push_back(std::pair<int,float>(0,m_outerShieldRadius));
+  aLVC.m_shieldHPart.push_back(outerShield);
+
+  std::vector<std::pair<int,float> >  innerShield;
+  innerShield.push_back(std::pair<int,float>(0,m_beamPipeRadius));
+  innerShield.push_back(std::pair<int,float>(0,530.));
+  innerShield.push_back(std::pair<int,float>(0,m_innerShieldRadius));
+  aLVC.m_shieldHPart.push_back(innerShield);
+
+  std::vector<std::pair<int,float> >  diskShield;
+  diskShield.push_back(std::pair<int,float>(0,0.));
+  diskShield.push_back(std::pair<int,float>(0,540.));
+  diskShield.push_back(std::pair<int,float>(0,750.));
+  diskShield.push_back(std::pair<int,float>(0,2700.));
+  diskShield.push_back(std::pair<int,float>(0,4255.));
+  aLVC.m_shieldHPart.push_back(diskShield);
+
+  return;
+}
+
+double  Muon::MuonTrackingGeometryBuilderCond::calculateVolume( const Trk::Volume* envelope) const
+{
+  double envVol = 0.;
+  
+  if (!envelope) return 0.;
+  
+  const Trk::CylinderVolumeBounds*  cyl = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::CuboidVolumeBounds*    box = dynamic_cast<const Trk::CuboidVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::TrapezoidVolumeBounds* trd = dynamic_cast<const Trk::TrapezoidVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::BevelledCylinderVolumeBounds*  bcyl = dynamic_cast<const Trk::BevelledCylinderVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::PrismVolumeBounds* prism = dynamic_cast<const Trk::PrismVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::SimplePolygonBrepVolumeBounds* spb = dynamic_cast<const Trk::SimplePolygonBrepVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::CombinedVolumeBounds*  comb = dynamic_cast<const Trk::CombinedVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::SubtractedVolumeBounds*  sub = dynamic_cast<const Trk::SubtractedVolumeBounds*> (&(envelope->volumeBounds()));  
+
+  if ( cyl ) envVol = 2*cyl->halfPhiSector()*(cyl->outerRadius()*cyl->outerRadius()-cyl->innerRadius()*cyl->innerRadius())*cyl->halflengthZ();
+  if ( box ) envVol = (8*box->halflengthX()*box->halflengthY()*box->halflengthZ());
+  if ( trd ) envVol = (4*(trd->minHalflengthX()+trd->maxHalflengthX())*trd->halflengthY()*trd->halflengthZ());
+  if ( bcyl ) {
+    int type = bcyl->type();
+    if ( type<1 ) envVol = 2*bcyl->halfPhiSector()*(bcyl->outerRadius()*bcyl->outerRadius()-bcyl->innerRadius()*bcyl->innerRadius())*bcyl->halflengthZ(); 
+    if ( type==1 ) envVol = 2*bcyl->halflengthZ()*( bcyl->halfPhiSector()*bcyl->outerRadius()*bcyl->outerRadius()
+						    -bcyl->innerRadius()*bcyl->innerRadius()*tan(bcyl->halfPhiSector()) ); 
+    if ( type==2 ) envVol = 2*bcyl->halflengthZ()*( -bcyl->halfPhiSector()*bcyl->innerRadius()*bcyl->innerRadius()
+						    +bcyl->outerRadius()*bcyl->outerRadius()*tan(bcyl->halfPhiSector()) ); 
+    if ( type==3 ) envVol = 2*bcyl->halflengthZ()*tan(bcyl->halfPhiSector())*( bcyl->outerRadius()*bcyl->outerRadius() 
+									       -bcyl->innerRadius()*bcyl->innerRadius()); 
+  }
+  if ( prism ) {
+#ifdef TRKDETDESCR_USEFLOATPRECISON
+#define double float
+#endif    
+    std::vector<std::pair<double,double> > v=prism->xyVertices();
+#ifdef TRKDETDESCR_USEFLOATPRECISON
+#undef double
+#endif      
+    double a2 = v[1].first*v[1].first+v[1].second*v[1].second
+               +v[0].first*v[0].first+v[0].second*v[0].second
+	    -2*(v[0].first*v[1].first+v[0].second*v[1].second);
+    double c2 = v[2].first*v[2].first+v[2].second*v[2].second
+               +v[0].first*v[0].first+v[0].second*v[0].second
+	    -2*(v[0].first*v[2].first+v[0].second*v[2].second);
+    double ca = v[1].first*v[2].first+v[1].second*v[2].second
+               +v[0].first*v[0].first+v[0].second*v[0].second
+	       -v[0].first*v[1].first-v[0].second*v[1].second
+	       -v[0].first*v[2].first-v[0].second*v[2].second;
+    double vv = sqrt(c2-ca*ca/a2);
+    envVol = vv*sqrt(a2)*prism->halflengthZ();
+  }
+  if ( spb ) {
+    envVol = calculateVolume(spb->combinedVolume());    // exceptional use of combined volume (no intersections)
+  }   
+  if ( comb ) {
+    envVol = calculateVolume(comb->first()) + calculateVolume(comb->second());
+  }
+  if ( sub ) {
+    return -1;
+  }
+
+  return envVol;
+}
+
+void Muon::MuonTrackingGeometryBuilderCond::blendMaterial(LocalVariablesContainer& aLVC) const
+{
+  // loop over map
+  //std::map<const Trk::DetachedTrackingVolume*,std::vector<const Trk::TrackingVolume*>* >::iterator mIter = m_blendMap.begin();
+  std::vector<const Trk::DetachedTrackingVolume*>::iterator viter = aLVC.m_blendVols.begin();
+
+  const std::vector<std::pair<const Trk::Volume*,float> >* cs = 0;
+  
+  //  for ( ; mIter!= m_blendMap.end(); mIter++) {
+  //  cs = (*mIter).first->constituents();     
+  for (;viter!= aLVC.m_blendVols.end();++viter) {
+    cs = (*viter)->constituents();
+    if (!cs) continue;
+    // find material source
+    //const Trk::Material* detMat = (*mIter).first->trackingVolume();
+    const Trk::Material* detMat = (*viter)->trackingVolume();
+    //if ( (*mIter).first->trackingVolume()->confinedDenseVolumes()) detMat = (*(*mIter).first->trackingVolume()->confinedDenseVolumes())[0];
+    if ( (*viter)->trackingVolume()->confinedDenseVolumes()) detMat = (*(*viter)->trackingVolume()->confinedDenseVolumes())[0];
+    for (unsigned int ic=0; ic<cs->size(); ic++) {
+      //const Trk::Volume* nCs = new Trk::Volume(*((*cs)[ic].first),(*mIter).first->trackingVolume()->transform());
+      const Trk::Volume* nCs = new Trk::Volume(*((*cs)[ic].first),(*viter)->trackingVolume()->transform());
+      double fraction = (*cs)[ic].second;
+      double csVol = fraction*calculateVolume(nCs);      
+      const Muon::Span* s = findVolumeSpan(&(nCs->volumeBounds()), nCs->transform(), 0.,0.,aLVC) ;
+      if (s) {
+	ATH_MSG_VERBOSE("constituent:"<<ic<<":z:"<< (*s)[0]<<","<<(*s)[1]<<":r:"<< (*s)[4]<<","<<(*s)[5]
+			<<":phi:"<<(*s)[2]<<","<<(*s)[3]);      
+	double enVol = 0.;
+	// loop over frame volumes, check if confined
+	//std::vector<const Trk::TrackingVolume*>::iterator fIter = (*mIter).second->begin(); 
+	std::vector<const Trk::TrackingVolume*>* vv =aLVC.m_blendMap[*viter]; 
+	std::vector<const Trk::TrackingVolume*>::iterator fIter=vv->begin(); 
+	std::vector<bool> fEncl; 
+	fEncl.clear();
+	// blending factors can be saved, and not recalculated for each clone
+	//for ( ; fIter!=(*mIter).second->end(); fIter++) {
+	for ( ; fIter!=vv->end(); fIter++) {
+	  fEncl.push_back(enclosed(*fIter,s,aLVC));
+	  if ( fEncl.back() ) enVol += calculateVolume(*fIter);
+	}
+	// diluting factor
+	double dil =  enVol>0. ?  csVol/enVol : 0.;
+	//std::cout << "const:dil:"<< ic<<","<<dil<< std::endl;
+	if (dil>0.) { 
+	  //for ( fIter=(*mIter).second->begin(); fIter!=(*mIter).second->end(); fIter++) { 
+	  for ( fIter=vv->begin(); fIter!=vv->end(); fIter++) { 
+	    //if (fEncl[fIter-(*mIter).second->begin()]) { (*fIter)->addMaterial(*detMat,dil); if (m_colorCode==0) (*fIter)->registerColorCode(12) ; 
+	    if (fEncl[fIter-vv->begin()]) { (*fIter)->addMaterial(*detMat,dil); if (m_colorCode==0) (*fIter)->registerColorCode(12) ; 
+	      //ATH_MSG_VERBOSE((*fIter)->volumeName()<<" acquires material from "<<  (*mIter).first->name());  }
+	      ATH_MSG_VERBOSE((*fIter)->volumeName()<<" acquires material from "<<  (*viter)->name());  }
+	  }
+	  ATH_MSG_VERBOSE("diluting factor:"<< dil<<" for "<< (*viter)->name()<<","<<ic);
+	} else {
+	  ATH_MSG_VERBOSE("diluting factor:"<< dil<<" for "<< (*viter)->name()<<","<<ic);
+	}
+      }
+      delete nCs; delete s;
+    }
+    if ( m_removeBlended ) {  ATH_MSG_VERBOSE("deleting "<< (*viter)->name()); delete *viter; }
+  }
+}
diff --git a/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/components/MuonTrackingGeometry_entries.cxx b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/components/MuonTrackingGeometry_entries.cxx
index 923aa7eaa8e27ea9247f44d44d5ac13c888a45ee..576b652ff9dd5e51a6c5e0dff49ef5e8077c2c8a 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/components/MuonTrackingGeometry_entries.cxx
+++ b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/components/MuonTrackingGeometry_entries.cxx
@@ -3,6 +3,7 @@
 #include "MuonTrackingGeometry/MuonStationTypeBuilder.h"
 #include "MuonTrackingGeometry/MuonInertMaterialBuilder.h"
 
+#include "MuonTrackingGeometry/MuonTrackingGeometryBuilderCond.h"
 
 using namespace Muon;
 
@@ -11,3 +12,4 @@ DECLARE_COMPONENT( MuonStationBuilder )
 DECLARE_COMPONENT( MuonStationTypeBuilder )
 DECLARE_COMPONENT( MuonInertMaterialBuilder )
 
+DECLARE_COMPONENT( MuonTrackingGeometryBuilderCond )
diff --git a/MuonSpectrometer/MuonG4/MuonG4SD/CMakeLists.txt b/MuonSpectrometer/MuonG4/MuonG4SD/CMakeLists.txt
index 6b5fc4af3475f49dcb71df8b23244868218d9c25..4d89fe082969240448a350404b418b8dd889a038 100644
--- a/MuonSpectrometer/MuonG4/MuonG4SD/CMakeLists.txt
+++ b/MuonSpectrometer/MuonG4/MuonG4SD/CMakeLists.txt
@@ -22,19 +22,18 @@ find_package( Geant4 )
 find_package( XercesC )
 find_package( GTest )
 
-# Component(s) in the package:
-atlas_add_component( MuonG4SD
-                     src/*.cxx
-                     src/components/*.cxx
-                     INCLUDE_DIRS ${GEANT4_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${GEANT4_LIBRARIES} ${XERCESC_LIBRARIES} ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} StoreGateLib SGtests GeoPrimitives GaudiKernel MuonSimEvent G4AtlasToolsLib MCTruth )
-
 atlas_add_library( MuonG4SDLib
                    src/*.cxx
                    NO_PUBLIC_HEADERS MuonG4SD
                    INCLUDE_DIRS ${GEANT4_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS}
                    LINK_LIBRARIES ${GEANT4_LIBRARIES} ${XERCESC_LIBRARIES} ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} StoreGateLib SGtests GeoPrimitives GaudiKernel MuonSimEvent G4AtlasToolsLib MCTruth )
 
+# Component(s) in the package:
+atlas_add_component( MuonG4SD
+                     src/components/*.cxx
+                     INCLUDE_DIRS ${GEANT4_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS}
+                     LINK_LIBRARIES ${GEANT4_LIBRARIES} ${XERCESC_LIBRARIES} ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} MuonG4SDLib StoreGateLib SGtests GeoPrimitives GaudiKernel MuonSimEvent G4AtlasToolsLib MCTruth )
+
 atlas_add_test( CSCSensitiveDetector_gtest
                 SOURCES test/CSCSensitiveDetector_gtest.cxx
                 INCLUDE_DIRS ${GEANT4_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS}
diff --git a/MuonSpectrometer/MuonGeoModel/share/MuonGeoModel_MinimalSetup.py b/MuonSpectrometer/MuonGeoModel/share/MuonGeoModel_MinimalSetup.py
index d36058e1789cc467f62dea9b17a2d067c8de3e48..eabe426bea76a0ffca0eb34bb479b4097000a9fa 100644
--- a/MuonSpectrometer/MuonGeoModel/share/MuonGeoModel_MinimalSetup.py
+++ b/MuonSpectrometer/MuonGeoModel/share/MuonGeoModel_MinimalSetup.py
@@ -5,9 +5,7 @@ from AtlasGeoModel import GeoModelInit
 from GeoModelSvc.GeoModelSvcConf import GeoModelSvc
 GeoModelSvc = GeoModelSvc()
 from MuonGeoModel.MuonGeoModelConf import MuonDetectorTool
-GeoModelSvc.DetectorTools += [ MuonDetectorTool() ]
-GeoModelSvc.DetectorTools[ "MuonDetectorTool" ].UseConditionDb = 0
-GeoModelSvc.DetectorTools[ "MuonDetectorTool" ].UseAsciiConditionData = 0
+GeoModelSvc.DetectorTools += [ MuonDetectorTool(HasSTgc=False, HasMM=False, UseConditionDb=0, UseAsciiConditionData=0) ]
 GeoModelSvc.SupportedGeometry=21
 GeoModelSvc.AtlasVersion='ATLAS-R2-2016-01-00-01'
 GeoModelSvc.MuonVersionOverride=database_layout
diff --git a/MuonSpectrometer/MuonGeoModel/src/RpcLayer.cxx b/MuonSpectrometer/MuonGeoModel/src/RpcLayer.cxx
index 51c83b18fd84bae765dbce5593f7659208622a58..123910170f791d82f914c056fd4d9bd6ad2ba0d9 100755
--- a/MuonSpectrometer/MuonGeoModel/src/RpcLayer.cxx
+++ b/MuonSpectrometer/MuonGeoModel/src/RpcLayer.cxx
@@ -196,8 +196,8 @@ GeoVPhysVol* RpcLayer::build(int cutoutson, std::vector<Cutout*> vcutdef)
   double gasLength   = ggLength - 2.*r->bakeliteframesize;
   double gasWidth    = ggWidth- 2.*r->bakeliteframesize;
 
-  double y_translation;
-  double z_translation;
+  double y_translation = 0;
+  double z_translation = 0;
   if (m->nGasGaps()==3) { // for BIS RPCs
     if (name == "RPC26" ) { //big RPC7
       gasLength   = ggLength - 93.25; // ggLength - deadframesizeEta
diff --git a/MuonSpectrometer/MuonReconstruction/MuonDataPrep/STgcClusterization/src/SimpleSTgcClusterBuilderTool.cxx b/MuonSpectrometer/MuonReconstruction/MuonDataPrep/STgcClusterization/src/SimpleSTgcClusterBuilderTool.cxx
index 3268b5fe18a633c6c56584ef2926597e3c076a93..64a9a593d97b41d8d9d0f3532f42cb0733712ad8 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonDataPrep/STgcClusterization/src/SimpleSTgcClusterBuilderTool.cxx
+++ b/MuonSpectrometer/MuonReconstruction/MuonDataPrep/STgcClusterization/src/SimpleSTgcClusterBuilderTool.cxx
@@ -15,6 +15,7 @@ Muon::SimpleSTgcClusterBuilderTool::SimpleSTgcClusterBuilderTool(const std::stri
 {
   declareProperty("ChargeCut", m_chargeCut=0.0);
   declareProperty("maxHoleSize",m_maxHoleSize=1);
+  declareProperty("addError",m_addError=0);
 }
 
 StatusCode Muon::SimpleSTgcClusterBuilderTool::initialize()
@@ -37,12 +38,13 @@ StatusCode Muon::SimpleSTgcClusterBuilderTool::getClusters(std::vector<Muon::sTg
   IdentifierHash hash;
 
   double resolution=0.;
-  bool isWire = false;
+  bool isStrip = false;
   if ( stripsVect.size()>0 ) {
     resolution = stripsVect.at(0).localCovariance()(0,0);
     Identifier chanId = stripsVect.at(0).identify();
-    if ( m_idHelperSvc->stgcIdHelper().channelType(chanId)==2 ) isWire = true;
-    ATH_MSG_DEBUG("isWire: " << isWire << "Single channel resolution: " << resolution);
+    if ( m_idHelperSvc->stgcIdHelper().channelType(chanId)==1 ) isStrip = true;
+    ATH_MSG_DEBUG(" channelType " << m_idHelperSvc->stgcIdHelper().channelType(chanId));
+    ATH_MSG_DEBUG("isStrip: " << isStrip << "Single channel resolution: " << resolution);
   }
   else {
     ATH_MSG_DEBUG("Size of the channel vectors is zero");
@@ -91,8 +93,8 @@ StatusCode Muon::SimpleSTgcClusterBuilderTool::getClusters(std::vector<Muon::sTg
           elementsChannel.push_back(m_idHelperSvc->stgcIdHelper().channel(it.identify()));
           elementsTime.push_back(it.time());
           double weight = 0.0;
-          isWire ? weight = 1.0 : weight = it.charge(); 
-          ATH_MSG_DEBUG("isWire: " << isWire << " weight: " << weight);
+          isStrip ? weight = it.charge() : weight = 1.0; 
+          ATH_MSG_DEBUG("isStrip: " << isStrip << " weight: " << weight);
           weightedPosX += it.localPosition().x()*weight;
           totalCharge += weight;
           ATH_MSG_DEBUG("Channel local position and charge: " << it.localPosition().x() << " " 
@@ -100,11 +102,11 @@ StatusCode Muon::SimpleSTgcClusterBuilderTool::getClusters(std::vector<Muon::sTg
           //
           // Set the cluster identifier to the max charge strip
           //
-          if ( isWire ) {
+          if ( isStrip && it.charge()>maxCharge ) {
+            maxCharge = it.charge();
             clusterId = it.identify();
           }
-          if ( !isWire && it.charge()>maxCharge ) {
-            maxCharge = it.charge();
+          if ( !isStrip) {
             clusterId = it.identify();
           } 
         } 
@@ -118,8 +120,8 @@ StatusCode Muon::SimpleSTgcClusterBuilderTool::getClusters(std::vector<Muon::sTg
         if ( cluster.size() > 1 ) {
           double weight = 0.0;
           for ( auto it : cluster ) {
-            isWire ? weight = 1.0 : weight = it.charge(); 
-            ATH_MSG_DEBUG("isWire: " << isWire << " weight: " << weight);
+            isStrip ? weight = it.charge() : weight = 1.0; 
+            ATH_MSG_DEBUG("isStrip: " << isStrip << " weight: " << weight);
             //sigmaSq += weight*(it.localPosition().x()-weightedPosX)*(it.localPosition().x()-weightedPosX);
             sigmaSq += weight*weight*resolution;
             ATH_MSG_DEBUG(">>>> posX: " << it.localPosition().x() << " weightedPosX: " << weightedPosX); 
@@ -131,11 +133,13 @@ StatusCode Muon::SimpleSTgcClusterBuilderTool::getClusters(std::vector<Muon::sTg
         sigmaSq = sigmaSq/(totalCharge*totalCharge*12);
         ATH_MSG_DEBUG("Uncertainty on cluster position is: " << sqrt(sigmaSq));         
         Amg::MatrixX* covN = new Amg::MatrixX(1,1);
-        (*covN)(0,0) = sigmaSq;
+        (*covN)(0,0) = sigmaSq + m_addError*m_addError;
 
         //
         // memory allocated dynamically for the PrepRawData is managed by Event Store in the converters
         //
+        ATH_MSG_INFO("error on cluster " << sqrt((*covN)(0,0)) << " added error " <<  m_addError); 
+        
         sTgcPrepData* prdN = new sTgcPrepData(clusterId,hash,localPosition,
             rdoList, covN, cluster.at(0).detectorElement(),
             std::accumulate(elementsCharge.begin(),elementsCharge.end(),0),(short int)0,(uint16_t) 0,elementsChannel,elementsTime,elementsCharge);
diff --git a/MuonSpectrometer/MuonReconstruction/MuonDataPrep/STgcClusterization/src/SimpleSTgcClusterBuilderTool.h b/MuonSpectrometer/MuonReconstruction/MuonDataPrep/STgcClusterization/src/SimpleSTgcClusterBuilderTool.h
index 5539c325754ad3d1d70b17812f92fda348567a41..381542227c5cbaba9626bb15b76987306196a3b8 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonDataPrep/STgcClusterization/src/SimpleSTgcClusterBuilderTool.h
+++ b/MuonSpectrometer/MuonReconstruction/MuonDataPrep/STgcClusterization/src/SimpleSTgcClusterBuilderTool.h
@@ -42,6 +42,7 @@ namespace Muon
 
     double m_chargeCut;
     unsigned int m_maxHoleSize;
+    double m_addError;
 
     ServiceHandle<Muon::IMuonIdHelperSvc> m_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"};
 
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonPrepRawData/src/MMPrepData.cxx b/MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonPrepRawData/src/MMPrepData.cxx
index 67a2a0f867ba3a8b00c5a209e89a3fa3a1637382..9083f4d7abe22850d4759c254d7b870ab197973d 100755
--- a/MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonPrepRawData/src/MMPrepData.cxx
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonPrepRawData/src/MMPrepData.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "MuonPrepRawData/MMPrepData.h"
@@ -31,7 +31,8 @@ namespace Muon
     m_stripTimes(stripTimes),
     m_stripCharges(stripCharges),
     m_stripDriftDist(),
-    m_stripDriftErrors()
+    m_stripDriftErrors(),
+    m_author (SimpleClusterBuilder)
   { }
 
   MMPrepData::MMPrepData( const Identifier& RDOId,
@@ -51,7 +52,8 @@ namespace Muon
     m_chisqProb(0.0),
     m_stripNumbers(),
     m_stripTimes(),
-    m_stripCharges()
+    m_stripCharges(),
+    m_author (SimpleClusterBuilder)
   { }
 
   MMPrepData::MMPrepData( const Identifier& RDOId,
@@ -72,7 +74,8 @@ namespace Muon
     m_chisqProb(0.0),
     m_stripNumbers(),
     m_stripTimes(),
-    m_stripCharges()
+    m_stripCharges(),
+    m_author (SimpleClusterBuilder)
   { }
 
   MMPrepData::MMPrepData( const Identifier& RDOId,
@@ -92,7 +95,8 @@ namespace Muon
     m_stripTimes(),
     m_stripCharges(),
     m_stripDriftDist(),
-    m_stripDriftErrors()
+    m_stripDriftErrors(),
+    m_author (SimpleClusterBuilder)
   { }
 
   // Destructor:
@@ -114,7 +118,8 @@ namespace Muon
     m_stripTimes(),
     m_stripCharges(),
     m_stripDriftDist(),
-    m_stripDriftErrors()    
+    m_stripDriftErrors(),
+    m_author (SimpleClusterBuilder)
   { }
 
   //copy constructor:
@@ -130,7 +135,8 @@ namespace Muon
     m_stripTimes(RIO.m_stripTimes),
     m_stripCharges(RIO.m_stripCharges),
     m_stripDriftDist(RIO.m_stripDriftDist),
-    m_stripDriftErrors(RIO.m_stripDriftErrors)
+    m_stripDriftErrors(RIO.m_stripDriftErrors),
+    m_author(RIO.m_author)
   { }
 
   //move constructor:
@@ -146,7 +152,8 @@ namespace Muon
     m_stripTimes(RIO.m_stripTimes),
     m_stripCharges(RIO.m_stripCharges),
     m_stripDriftDist(RIO.m_stripDriftDist),
-    m_stripDriftErrors(RIO.m_stripDriftErrors)
+    m_stripDriftErrors(RIO.m_stripDriftErrors),
+    m_author(RIO.m_author)
   { }
 
   /// set the micro-tpc quantities
@@ -185,6 +192,7 @@ namespace Muon
 	m_stripCharges = RIO.m_stripCharges;
 	m_stripDriftDist = RIO.m_stripDriftDist;
 	m_stripDriftErrors = RIO.m_stripDriftErrors;
+	m_author = RIO.m_author;
       }
     return *this;
 
@@ -207,6 +215,7 @@ namespace Muon
 	m_stripCharges = RIO.m_stripCharges;
 	m_stripDriftDist = RIO.m_stripDriftDist;
 	m_stripDriftErrors = RIO.m_stripDriftErrors;
+	m_author = RIO.m_author;
       }
     return *this;
 
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MooreTools.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MooreTools.py
index dc60454c09e787f4951d93974da1dc759dcaf75f..f4426e2f13f3da6ca939a782aa7c42ae6307b7a4 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MooreTools.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MooreTools.py
@@ -442,14 +442,30 @@ class MuonSegmentRegionRecoveryTool(CfgMgr.Muon__MuonSegmentRegionRecoveryTool,C
       #MDT conditions information not available online
       if(athenaCommonFlags.isOnline):
           kwargs.setdefault("MdtCondKey","")
+      from RegionSelector.RegSelToolConfig import makeRegSelTool_MDT, makeRegSelTool_RPC, makeRegSelTool_TGC
+      kwargs.setdefault("MDTRegionSelector", makeRegSelTool_MDT())
+      kwargs.setdefault("RPCRegionSelector", makeRegSelTool_RPC())
+      kwargs.setdefault("TGCRegionSelector", makeRegSelTool_TGC())
+      if MuonGeometryFlags.hasCSC():
+          from RegionSelector.RegSelToolConfig import makeRegSelTool_CSC
+          kwargs.setdefault("CSCRegionSelector", makeRegSelTool_CSC())
+      else:
+          kwargs.setdefault("CSCRegionSelector", "")
+      if MuonGeometryFlags.hasSTGC():
+          from RegionSelector.RegSelToolConfig import makeRegSelTool_sTGC
+          kwargs.setdefault("STGCRegionSelector", makeRegSelTool_sTGC())
+      else:
+          kwargs.setdefault("STGCRegionSelector", "")
+      if MuonGeometryFlags.hasMM():
+          from RegionSelector.RegSelToolConfig import makeRegSelTool_MM
+          kwargs.setdefault("MMRegionSelector", makeRegSelTool_MM())
+      else:
+          kwargs.setdefault("MMRegionSelector", "")
+
       self.applyUserDefaults(kwargs,name)
       super(MuonSegmentRegionRecoveryTool,self).__init__(name,**kwargs)
-      global ServiceMgr
-      from RegionSelector.RegSelSvcDefault import RegSelSvcDefault
-      SegRecoveryRegSelSvc = RegSelSvcDefault()
-      SegRecoveryRegSelSvc.enableMuon = True
-      ServiceMgr += SegRecoveryRegSelSvc
-#     self.RegionSelector = SegRecoveryRegSelSvc
+
+
 
 MuonSegmentRegionRecoveryTool.setDefaultProperties (
     Fitter = "MCTBFitter",
@@ -530,7 +546,6 @@ if not MuonGeometryFlags.hasCSC():
     mCHRT.CscPrepDataContainer = ""
 getPublicTool("MuonTrackSelectorTool")
 getPublicTool("MuonTrackExtrapolationTool")
-getPublicTool("MuonSegmentRegionRecoveryTool")
 getPublicTool("MuonTrackCleaner")
 getPublicTool("FixedErrorMuonClusterOnTrackCreator")
 getPublicTool("MuonSegmentSelectionTool")
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonStandalone.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonStandalone.py
index d6b35a152cd9e248042f457678be0133438eb472..4973cdd69fd064b5da8f423e16b011acc7d27f97 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonStandalone.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonStandalone.py
@@ -172,6 +172,7 @@ class MuonStandalone(ConfiguredMuonRec):
                 Cleaner.Fitter = getPublicTool("MCTBSLFitterMaterialFromTrack")
                 Cleaner.PullCut = 3
                 Cleaner.PullCutPhi = 3
+                Cleaner.UseSLFit = True
                 SegmentFinder.TrackCleaner = Cleaner
             # for test purposes allow parallel running of truth segment finding and new segment finder
                 MuonSegmentFinderAlg = CfgMgr.MuonSegmentFinderAlg( "MuonSegmentMaker",SegmentCollectionName=SegmentLocation, 
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/share/MuonRec_myTopOptions.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/share/MuonRec_myTopOptions.py
index 9e2fa8f727b997d67be0de2f2c9d874b24a4b9fc..1d302bc779470817728960542d506a621f0bfbcc 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/share/MuonRec_myTopOptions.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/share/MuonRec_myTopOptions.py
@@ -1,5 +1,7 @@
 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
+from __future__ import print_function
+
 from MuonRecExample.MuonRecFlags import muonRecFlags
 from RecExConfig.RecFlags import rec
 from RecExConfig.RecAlgsFlags import recAlgs
@@ -78,7 +80,6 @@ try:
 except:
     # print the stacktrace (saving could fail, and would then obscure the real problem)
     import traceback
-    from __future__ import print_function
     print ('INFO: MuonRec_myTopOptions.py - stack trace:')
     print (traceback.format_exc().rstrip())
     
diff --git a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonSegmentRegionRecoveryTool.cxx b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonSegmentRegionRecoveryTool.cxx
index ba2b5664b77cdd1265973e76f93461e7caaae84b..ea830fb8022abbfbb6d71eb45ea01e267727b2a6 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonSegmentRegionRecoveryTool.cxx
+++ b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonSegmentRegionRecoveryTool.cxx
@@ -80,7 +80,12 @@ StatusCode MuonSegmentRegionRecoveryTool::initialize()
   ATH_CHECK( m_fitter.retrieve() );
   ATH_CHECK( m_idHelperSvc.retrieve() );
   ATH_CHECK( m_hitSummaryTool.retrieve() );
-  ATH_CHECK( m_regionSelector.retrieve() );
+  ATH_CHECK( m_regsel_mdt.retrieve() );
+  if(!m_regsel_csc.empty()) ATH_CHECK( m_regsel_csc.retrieve() );
+  ATH_CHECK( m_regsel_rpc.retrieve() );
+  ATH_CHECK( m_regsel_tgc.retrieve() );
+  if(!m_regsel_stgc.empty()) ATH_CHECK( m_regsel_stgc.retrieve() );
+  if(!m_regsel_mm.empty()) ATH_CHECK( m_regsel_mm.retrieve() );
   ATH_CHECK( m_trackSummaryTool.retrieve() );
 
   if(!m_condKey.empty()) ATH_CHECK(m_condKey.initialize());
@@ -191,7 +196,12 @@ void MuonSegmentRegionRecoveryTool::addHashes( DETID type, const IRoiDescriptor&
 
   std::vector<IdentifierHash> crossed;
 
-  m_regionSelector->DetHashIDList(type, roi, crossed );
+  if(type == MDT) m_regsel_mdt->HashIDList(roi, crossed );
+  if(type == CSC) m_regsel_csc->HashIDList(roi, crossed );
+  if(type == RPC) m_regsel_rpc->HashIDList(roi, crossed );
+  if(type == TGC) m_regsel_tgc->HashIDList(roi, crossed );
+  if(type == STGC) m_regsel_stgc->HashIDList(roi, crossed );
+  if(type == MM) m_regsel_mm->HashIDList(roi, crossed );
 
   for ( std::vector<IdentifierHash>::iterator it = crossed.begin(); it != crossed.end(); ++it ) {
     if ( !exclusion.count(*it) && !hashes.count(*it) ) {
diff --git a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonSegmentRegionRecoveryTool.h b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonSegmentRegionRecoveryTool.h
index ca572ed383f257ebaa6af9bd42cb3f22096bb34b..01c81aba57843c0ec3e87395b4852dc607f6fca6 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonSegmentRegionRecoveryTool.h
+++ b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonSegmentRegionRecoveryTool.h
@@ -30,7 +30,7 @@
 #include "MuonChamberHoleRecoveryTool.h"
 #include "MuonRecToolInterfaces/IMuonSeededSegmentFinder.h"
 #include "MuonChamberHoleRecoveryTool.h"
-#include "IRegionSelector/IRegSelSvc.h"
+#include "IRegionSelector/IRegSelTool.h"
 
 #include "AthenaBaseComps/AthAlgTool.h"
 #include "GaudiKernel/ToolHandle.h"
@@ -162,8 +162,18 @@ namespace Muon {
     ServiceHandle<Muon::IMuonIdHelperSvc> m_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"};
     ToolHandle<IMuonHitSummaryTool>        m_hitSummaryTool
       {this, "HitSummaryTool", "Muon::MuonHitSummaryTool/MuonHitSummaryTool"};            //!< hit summary tool
-    ServiceHandle<IRegSelSvc>         m_regionSelector
-      {this, "RegionSelector", "RegSelSvc"};            //!< The region selector      
+    ToolHandle<IRegSelTool>         m_regsel_mdt
+      {this, "MDTRegionSelector", "RegSelTool/RegSelTool_MDT"};            //!< The region selector tool for MDT      
+    ToolHandle<IRegSelTool>         m_regsel_csc
+      {this, "CSCRegionSelector", "RegSelTool/RegSelTool_CSC"};            //!< The region selector tool for CSC      
+    ToolHandle<IRegSelTool>         m_regsel_rpc
+      {this, "RPCRegionSelector", "RegSelTool/RegSelTool_RPC"};            //!< The region selector tool for RPC      
+    ToolHandle<IRegSelTool>         m_regsel_tgc
+      {this, "TGCRegionSelector", "RegSelTool/RegSelTool_TGC"};            //!< The region selector tool for TGC      
+    ToolHandle<IRegSelTool>         m_regsel_stgc
+      {this, "STGCRegionSelector", "RegSelTool/RegSelTool_STGC"};            //!< The region selector tool for STGC      
+    ToolHandle<IRegSelTool>         m_regsel_mm
+      {this, "MMRegionSelector", "RegSelTool/RegSelTool_MM"};            //!< The region selector tool for MM      
     ServiceHandle<IMuonEDMHelperSvc>           m_edmHelperSvc {this, "edmHelper", 
       "Muon::MuonEDMHelperSvc/MuonEDMHelperSvc", 
       "Handle to the service providing the IMuonEDMHelperSvc interface" };           //!< EDM Helper tool
diff --git a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonTrackCleaner.cxx b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonTrackCleaner.cxx
index 76adc4d7dc62f35b7e4153b71c0a7dc8f8c3cb06..6d28a71a675570ec11144928866bcdd3fbdb7571 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonTrackCleaner.cxx
+++ b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonTrackCleaner.cxx
@@ -52,6 +52,7 @@ namespace Muon {
     ATH_CHECK( m_edmHelperSvc.retrieve() );
     ATH_CHECK( m_printer.retrieve() );
     ATH_CHECK( m_extrapolator.retrieve() );
+    ATH_CHECK( m_slextrapolator.retrieve() );
     ATH_CHECK( m_pullCalculator.retrieve() );
     ATH_CHECK( m_mdtRotCreator.retrieve() );
     ATH_CHECK( m_compRotCreator.retrieve() );
@@ -897,6 +898,7 @@ namespace Muon {
     fieldCondObj->getInitializedCache (fieldCache);
     
     state.slFit =  !fieldCache.toroidOn() || m_edmHelperSvc->isSLTrack( track );
+    if(m_use_slFit) state.slFit = true;
 
     // loop over track and calculate residuals
     const DataVector<const Trk::TrackStateOnSurface>* states = track.trackStateOnSurfaces();
@@ -1194,7 +1196,8 @@ namespace Muon {
 	ATH_MSG_DEBUG("updated competing ROT");
 	info.cleanedCompROT = std::move(updatedCompRot);
 	if( info.cleanedCompROT->associatedSurface() != meas->associatedSurface() ){
-	  const Trk::TrackParameters* exPars=m_extrapolator->extrapolate(*pars,info.cleanedCompROT->associatedSurface(),Trk::anyDirection,false,Trk::muon);
+	  const Trk::TrackParameters* exPars= state.slFit ? m_slextrapolator->extrapolate(*pars,info.cleanedCompROT->associatedSurface(),Trk::anyDirection,false,Trk::muon) :
+                                                      m_extrapolator->extrapolate(*pars,info.cleanedCompROT->associatedSurface(),Trk::anyDirection,false,Trk::muon);
 	  if( !exPars ){
 	    ATH_MSG_WARNING("Update of comp rot parameters failed, keeping old ones" );
 	    info.cleanedCompROT.reset();
@@ -1332,7 +1335,7 @@ namespace Muon {
     }
 
     // update sl fit configuration if track has ID hits or vertex constraint
-    if( state.slFit && (state.hasVertexConstraint || state.nIdHits > 0 ) && fieldCache.solenoidOn() ) {
+    if( !m_use_slFit && state.slFit && (state.hasVertexConstraint || state.nIdHits > 0 ) && fieldCache.solenoidOn() ) {
       state.slFit = false;
     }
 
diff --git a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonTrackCleaner.h b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonTrackCleaner.h
index f06d4927d2c7cdbcd4410c722a54f493a1d795e1..2c9ca258f273e3f80e4f9272b1ff4b3eb8cabdb7 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonTrackCleaner.h
+++ b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonTrackCleaner.h
@@ -291,6 +291,7 @@ namespace Muon {
     ToolHandle<Muon::MuonEDMPrinterTool>             m_printer           {this, "Printer", "Muon::MuonEDMPrinterTool/MuonEDMPrinterTool"};
     ServiceHandle<Muon::IMuonIdHelperSvc> m_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"};
     ToolHandle<Trk::IExtrapolator>                   m_extrapolator      {this, "Extrapolator", "Trk::Extrapolator/AtlasExtrapolator"};
+    ToolHandle<Trk::IExtrapolator>                   m_slextrapolator      {this, "SlExtrapolator", "Trk::Extrapolator/MuonStraightLineExtrapolator"};
     // Read handle for conditions object to get the field cache
     SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCacheCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
                                                                                "Name of the Magnetic Field conditions object key"};
@@ -309,6 +310,8 @@ namespace Muon {
     Gaudi::Property<bool> m_onlyUseHitErrorInRecovery {this, "OnlyUseHitErrorInRecovery", true};
     Gaudi::Property<double> m_adcCut                  {this, "AdcCut", 50.};
     Gaudi::Property<bool> m_iterate                   {this, "Iterate", 0.7};
+    Gaudi::Property<bool> m_use_slFit                 {this, "UseSLFit", false};
+    
 
     /** helper function to extract chambers that are to be removed */
     bool extractChambersToBeRemoved( CleaningState& state, std::set<Identifier>& chambersToBeRemovedSet, bool usePhi=false ) const;
diff --git a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonTrackScoringTool.cxx b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonTrackScoringTool.cxx
index d3071039a8f3dd03278810ab50dd0195e8e2bf0a..94fa65cf2246f67d1f16f710cfef85f03d59b985 100755
--- a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonTrackScoringTool.cxx
+++ b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackFinderTools/src/MuonTrackScoringTool.cxx
@@ -84,12 +84,15 @@ namespace Muon {
 
   Trk::TrackScore MuonTrackScoringTool::score( const Trk::Track& track, const bool /*suppressHoleSearch*/ ) const
   {
-
+    Trk::TrackScore score;
     const Trk::TrackSummary* summary = track.trackSummary();
-    if (!summary) { throw std::logic_error("Summary requested for a non mutable track without a track summary."); }
-
-    //log <<MSG::DEBUG<<"Track has TrackSummary "<<*summary<<endmsg;
-    Trk::TrackScore score = Trk::TrackScore( simpleScore(track, *summary) );
+    if (summary) { 
+      score =  simpleScore(track, *summary);
+    } else {
+      // This is potentially slow, so might need revisiting.
+      std::unique_ptr<Trk::TrackSummary> tmpSummary  = m_trkSummaryTool->summaryNoHoleSearch(track);
+      score =  simpleScore(track, *tmpSummary);
+    } 
     return score;
   }
 
diff --git a/MuonSpectrometer/MuonValidation/MuonGeomValidation/MuonGeomRTT/test/test_checkgeo_agdd.sh b/MuonSpectrometer/MuonValidation/MuonGeomValidation/MuonGeomRTT/test/test_checkgeo_agdd.sh
index 4094583d1c6ac534e67918401703c60af5f47c7c..5ddb7b1896823b8f355add287565fe0cb6ad8a78 100755
--- a/MuonSpectrometer/MuonValidation/MuonGeomValidation/MuonGeomRTT/test/test_checkgeo_agdd.sh
+++ b/MuonSpectrometer/MuonValidation/MuonGeomValidation/MuonGeomRTT/test/test_checkgeo_agdd.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# art-description: Check SQL files of muon spectrometer description, just AGDD part from amdc_simrec (for NSW, using NSW layout)
+# art-description: Check SQL files of muon spectrometer description, just AGDD part from amdc_simrec (only passive materials)
 #
 # art-type: grid
 # art-include: master/Athena
@@ -12,7 +12,24 @@ art.py createpoolfile
 
 set -x
 
+# download an amdb file to test
 wget http://atlas.web.cern.ch/Atlas/GROUPS/MUON/AMDB/amdb_simrec.r.08.01
+# run CheckAGDDBlob which will create Out.AmdcOracle.AM.AGDDtemp.data from the AGDD part of the amdb file, and Generated_AGDD_pool.txt from the AGDD blob in the DB
 athena.py AmdcAth/AmdcAth_GeometryTasks.py -c "input_amdb_simrec='amdb_simrec.r.08.01';database_layout='MuonSpectrometer-R.08.01-NSW';CheckAGDDBlob=True;"
 
+exit_code=$?
+echo  "art-result: ${exit_code} AmdcAth_GeometryTasks.py"
+if [ ${exit_code} -ne 0 ]
+then
+    exit ${exit_code}
+fi
+
+# now, compare the output of AGDD from the local file with the blob from the db
+diff Generated_AGDD_pool.txt Out.AmdcOracle.AM.AGDDtemp.data
+echo  "art-result: ${exit_code} diff-check"
+if [ ${exit_code} -ne 0 ]
+then
+    exit ${exit_code}
+fi
+
 echo "art-result: $?"
diff --git a/MuonSpectrometer/MuonValidation/MuonGeomValidation/MuonGeomRTT/test/test_checkgeo_nswd.sh b/MuonSpectrometer/MuonValidation/MuonGeomValidation/MuonGeomRTT/test/test_checkgeo_nswd.sh
index dd0efcf83562c2043e60a9a29f281f9fcef0f771..07087c7c89249e1b85f43b1fa996e949b1d8c5a8 100755
--- a/MuonSpectrometer/MuonValidation/MuonGeomValidation/MuonGeomRTT/test/test_checkgeo_nswd.sh
+++ b/MuonSpectrometer/MuonValidation/MuonGeomValidation/MuonGeomRTT/test/test_checkgeo_nswd.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# art-description: Check SQL files of muon spectrometer description, just AGDD part from amdc_simrec (for NSW, using NSW layout)
+# art-description: Check SQL files of muon spectrometer (NSW) description, just AGDD part from NSW
 #
 # art-type: grid
 # art-include: master/Athena
@@ -12,8 +12,35 @@ art.py createpoolfile
 
 set -x
 
+# get the NSW AGDD xml file
+get_files stations.v2.07.xml
 
-get_files stations.v2.06.xml
-athena.py AmdcAth/AmdcAth_GeometryTasks.py -c "input_nsw_xml='stations.v2.06.xml';database_layout='MuonSpectrometer-R.09.00.NSW';CheckNSWDBlob=True;"
+# run DoNSWDBlob which will create Out.AmdcOracle.AM.NSWDtemp.data and Out.AmdcOracle.AM.NSWD.PREsql from the NSW AGDD file
+athena.py AmdcAth/AmdcAth_GeometryTasks.py -c "input_nsw_xml='stations.v2.07.xml';database_layout='MuonSpectrometer-R.09.02.NSW';DoNSWDBlob=True;"
 
-echo "art-result: $?"
\ No newline at end of file
+exit_code=$?
+echo  "art-result: ${exit_code} AmdcAth_GeometryTasks.py-DoNSWDBlob"
+if [ ${exit_code} -ne 0 ]
+then
+    exit ${exit_code}
+fi
+
+# run CheckNSWDBlob which will create Generated_NSWD_pool.txt from the AGDD blob in the DB
+athena.py AmdcAth/AmdcAth_GeometryTasks.py -c "input_nsw_xml='stations.v2.07.xml';database_layout='MuonSpectrometer-R.09.02.NSW';CheckNSWDBlob=True;"
+
+exit_code=$?
+echo  "art-result: ${exit_code} AmdcAth_GeometryTasks.py-CheckNSWDBlob"
+if [ ${exit_code} -ne 0 ]
+then
+    exit ${exit_code}
+fi
+
+# now, compare the output of AGDD from the local file with the blob from the db
+diff Generated_NSWD_pool.txt Out.AmdcOracle.AM.NSWDtemp.data
+echo  "art-result: ${exit_code} diff-check"
+if [ ${exit_code} -ne 0 ]
+then
+    exit ${exit_code}
+fi
+
+echo "art-result: $?"
diff --git a/MuonSpectrometer/MuonValidation/MuonPRDTest/src/EDM_object.cxx b/MuonSpectrometer/MuonValidation/MuonPRDTest/src/EDM_object.cxx
index 73694f6d0eac9de31a2f34839a1004c2151d4ec7..82f2aeac955d8d0915d3b00107f94f078e9649f4 100644
--- a/MuonSpectrometer/MuonValidation/MuonPRDTest/src/EDM_object.cxx
+++ b/MuonSpectrometer/MuonValidation/MuonPRDTest/src/EDM_object.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include <vector>
@@ -108,8 +108,11 @@ void EDM_object::update_efficiency ( int maximum_difference ) {
 	uint nMatches = 0;
 	size_t n_obj = size();
 	m_total += n_obj;
+	bool isMatched;
 	for (uint i = 0; i < n_obj; ++i) {
-		nMatches += abs( m_channel->at(i) - m_matchedchannel->at(i) ) <= maximum_difference;
+		// default matched channel value is -10. If not set to any other value, it is always a mismatch
+		isMatched = m_matchedchannel->at(i) < 0 || abs( m_channel->at(i) - m_matchedchannel->at(i) ) <= maximum_difference;
+		nMatches += isMatched;
 	}
 	m_mismatches += (n_obj - nMatches);
 }
diff --git a/MuonSpectrometer/MuonValidation/MuonPRDTest/src/NSWPRDValAlg.cxx b/MuonSpectrometer/MuonValidation/MuonPRDTest/src/NSWPRDValAlg.cxx
index c5150dfd476ab81579e367146a882dc139550a83..a8cbecd3af7f23362522f80298b11f1f91af2cba 100644
--- a/MuonSpectrometer/MuonValidation/MuonPRDTest/src/NSWPRDValAlg.cxx
+++ b/MuonSpectrometer/MuonValidation/MuonPRDTest/src/NSWPRDValAlg.cxx
@@ -485,7 +485,7 @@ StatusCode NSWPRDValAlg::NSWMatchingAlg (EDM_object data0, EDM_object data1) {
               warningPrinted = true;
             }
           } else {
-            ATH_MSG_WARNING("No match found!");
+            ATH_MSG_DEBUG("No match found!");
           }
         }
      }
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/CMakeLists.txt b/PhysicsAnalysis/AnalysisCommon/PMGTools/CMakeLists.txt
index 6fa17a167933302bfb7c23e2ecbff2d9a07f30b0..389be61f89bffe56d007ea7a0f760ce04a17c3c0 100644
--- a/PhysicsAnalysis/AnalysisCommon/PMGTools/CMakeLists.txt
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/CMakeLists.txt
@@ -1,4 +1,3 @@
-# $Id: CMakeLists.txt 782436 2016-11-04 15:35:58Z krasznaa $
 #################################################################################
 # Package: PMGTools
 #################################################################################
@@ -7,38 +6,56 @@
 atlas_subdir( PMGTools )
 
 # Extra dependencies based on the build environment:
-set( extra_deps )
+set( extra_private_deps )
+# ... for AnalysisBase
 if( XAOD_STANDALONE )
-   set( extra_deps Control/xAODRootAccess )
+   set( extra_private_deps Control/xAODRootAccess )
+# ... for AthAnalysisBase/Athena
 else()
-   set( extra_deps Control/AthAnalysisBaseComps PhysicsAnalysis/POOLRootAccess
-      GaudiKernel )
+   set( extra_private_deps Control/AthAnalysisBaseComps PhysicsAnalysis/POOLRootAccess GaudiKernel Event/EventInfo)
 endif()
 
+# Extra libraries based on the build environment:
+set( xaod_access_lib )
+set( extra_private_libs )
+# ... for AnalysisBase
+if( XAOD_STANDALONE )
+   set( xaod_access_lib xAODRootAccess )
+# ... for AthAnalysisBase (Athena calls this POOLRootAccess)
+else()
+   set( xaod_access_lib POOLRootAccessLib )
+   set( extra_private_libs EventInfo )
+endif()
+
+
 # Declare the package's dependencies:
 atlas_depends_on_subdirs(
    PUBLIC
    Control/AthToolSupport/AsgTools
+   Event/xAOD/xAODTruth
+   PhysicsAnalysis/AnalysisCommon/PATCore
    PhysicsAnalysis/AnalysisCommon/PATInterfaces
+   PhysicsAnalysis/Interfaces/PMGAnalysisInterfaces
    PRIVATE
    Event/FourMomUtils
    Event/xAOD/xAODEventInfo
    Event/xAOD/xAODJet
-   Event/xAOD/xAODTruth
+   Event/xAOD/xAODMetaData
+   PhysicsAnalysis/D3PDTools/RootCoreUtils
    Tools/PathResolver
-   ${extra_deps} )
+   ${extra_private_deps} )
 
 # External(s) used by the package:
 find_package( ROOT COMPONENTS Core Hist RIO )
+find_package( Boost )
 
 # Libraries in the package:
 atlas_add_library( PMGToolsLib
    PMGTools/*.h Root/*.cxx
    PUBLIC_HEADERS PMGTools
    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-   LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools PATInterfaces
-   PRIVATE_LINK_LIBRARIES FourMomUtils xAODEventInfo xAODJet xAODTruth
-   PathResolver )
+   LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools PATCoreLib PATInterfaces xAODTruth
+   PRIVATE_LINK_LIBRARIES FourMomUtils PathResolver RootCoreUtils xAODEventInfo xAODJet xAODMetaData ${extra_private_libs})
 
 if( NOT XAOD_STANDALONE )
    atlas_add_component( PMGTools
@@ -52,28 +69,36 @@ atlas_add_dictionary( PMGToolsDict
    LINK_LIBRARIES PMGToolsLib )
 
 # Executable(s) in the package:
+#
+# ... for Athena/AthAnalysis
 if( NOT XAOD_STANDALONE )
    atlas_add_executable( MyPMGApp
       test/MyPMGApp.cxx
       INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-      LINK_LIBRARIES ${ROOT_LIBRARIES} AthAnalysisBaseCompsLib POOLRootAccess
-      AsgTools xAODJet xAODTruth FourMomUtils PATInterfaces )
+      LINK_LIBRARIES ${ROOT_LIBRARIES} AthAnalysisBaseCompsLib ${xaod_access_lib}
+      AsgTools xAODJet xAODTruth FourMomUtils PATInterfaces PMGToolsLib )
 endif()
 
 # Test(s) in the package:
+#
+# ... for AnalysisBase
 if( XAOD_STANDALONE )
    atlas_add_test( ut_PMGSherpa22VJetsWeightTool_test
       SOURCES test/ut_PMGSherpa22VJetsWeightTool_test.cxx
       INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-      LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools xAODRootAccess PATInterfaces
-      PMGToolsLib )
+      LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools PATInterfaces PMGToolsLib ${xaod_access_lib} )
 
    atlas_add_test( ut_PMGSherpaVjetsSysTool_test
       SOURCES test/ut_PMGSherpaVjetsSysTool_test.cxx
       INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-      LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools xAODRootAccess PATInterfaces
-      PMGToolsLib )
+      LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools PATInterfaces PMGToolsLib ${xaod_access_lib} )
 endif()
+# ... AthAnalysis/AnalysisBase
+atlas_add_test( ut_PMGTruthWeightTool_test
+   SOURCES test/ut_PMGTruthWeightTool_test.cxx
+   INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
+   LINK_LIBRARIES ${ROOT_LIBRARIES} PMGToolsLib ${xaod_access_lib} )
+
 
 # Install files from the package:
 atlas_install_data( data/*.txt share/*.txt )
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGCrossSectionTool.h b/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGCrossSectionTool.h
index e475076a9963fe04a9aa65ba6b934f35324dc008..f9af041e40f19e31b6108bcca5e3656dddde263e 100644
--- a/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGCrossSectionTool.h
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGCrossSectionTool.h
@@ -8,13 +8,14 @@
 #define PMGTOOLS_PMGCROSSSECTIONTOOL_H
 
 // System include(s):
-#include <array>
+#include <map>
+#include <string>
 
 // Infrastructure include(s):
 #include "AsgTools/AsgTool.h"
 
 // Interface include(s):
-#include "PMGTools/IPMGCrossSectionTool.h"
+#include "PMGAnalysisInterfaces/IPMGCrossSectionTool.h"
 
 /// Tool providing sample cross-sections and k-factors etc
 ///
@@ -51,9 +52,21 @@ namespace PMGTools {
     std::string getSampleName(const int dsid) const;
     
     /// return the AMI cross-section for DSID
-    double getGeneratorXsection(const int dsid) const;
-    
+    double getAMIXsection(const int dsid) const;
+
+    /// return the cross-section uncertainty for DSID
+    double getXsectionUncertainty(const int dsid) const;
+
+    /// return the cross-section uncertainty for DSID
+    double getXsectionUncertaintyUP(const int dsid) const;
+
+    /// return the cross-section uncertainty for DSID
+    double getXsectionUncertaintyDOWN(const int dsid) const;
     
+    // :: below is for future use?
+    /// return the branching ratio for DSID
+    //double getBR(const int dsid) const;
+
     /// return the k-factor for DSID
     double getKfactor(const int dsid) const;
    
@@ -66,7 +79,7 @@ namespace PMGTools {
   private:
       
     // store vector of structures, each structure contains full info for DSID
-    std::map<int,PMGTools::AllSampleInfo> m_storeSampleInfo;
+    std::map<unsigned, PMGTools::AllSampleInfo> m_fStoreSampleInfo;
     std::string m_InputFileName;
     
   }; // class PMGCrossSectionTool
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGDecayProductsSelectionTool.h b/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGDecayProductsSelectionTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..13ada8706d38281c9895c011299fcb33fdfe64b3
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGDecayProductsSelectionTool.h
@@ -0,0 +1,91 @@
+/*
+ Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+ */
+
+/// @author Tadej Novak
+
+
+
+#ifndef PMG_TOOLS__PMG_DECAY_PRODUCTS_SELECTION_TOOL_H
+#define PMG_TOOLS__PMG_DECAY_PRODUCTS_SELECTION_TOOL_H
+
+#include <AsgTools/AsgTool.h>
+#include <PATCore/IAsgSelectionTool.h>
+#include <xAODTruth/TruthParticle.h>
+#include <xAODTruth/TruthParticleContainer.h>
+
+
+namespace PMGTools
+{
+  /// \brief an \ref IAsgSelectionTool that select particles
+  /// based on the allowed decay chain
+
+  class PMGDecayProductsSelectionTool final
+    : public asg::AsgTool, virtual public IAsgSelectionTool
+  {
+    // Create a proper constructor for Athena
+    ASG_TOOL_CLASS (PMGDecayProductsSelectionTool, IAsgSelectionTool)
+
+
+    /// \brief standard constructor
+  public:
+    PMGDecayProductsSelectionTool (const std::string& name);
+
+
+
+
+    //
+    // inherited interface
+    //
+
+    virtual StatusCode initialize () override;
+
+    virtual const asg::AcceptInfo& getAcceptInfo () const override;
+
+    virtual asg::AcceptData accept (const xAOD::IParticle* /*part*/) const override;
+
+
+
+    //
+    // private interface
+    //
+
+    /// \brief Helper function to check for required parent particles
+  private:
+    asg::AcceptData hasRequiredInitialParent (const xAOD::TruthParticle *truthParticle, asg::AcceptData& acceptData) const;
+
+    /// \brief Helper function to get the number of parent particles
+  private:
+    size_t getNParents (const xAOD::TruthParticle *truthParticle) const;
+
+    /// \brief Helper function get a parent by index
+  private:
+    const xAOD::TruthParticle* getParent (const xAOD::TruthParticle *truthParticle,
+                                          size_t index) const;
+
+    /// tool properties
+    /// \{
+
+  private:
+    std::vector<int> m_requiredParentPDGIDs;
+    std::vector<int> m_allowedIntermediatePDGIDs;
+
+    /// \}
+
+  private:
+    /// \brief Index for the truth particle link
+    int m_truthParticleIndex{ -1 };
+    /// \brief Index for the required parent particles
+    int m_requiredParentIndex{ -1 };
+
+    /// \brief the \ref AcceptInfo we are using
+  private:
+    asg::AcceptInfo m_accept;
+
+    /// \brief common parents accessor
+  private:
+    std::unique_ptr<const SG::AuxElement::Accessor<std::vector<ElementLink<xAOD::TruthParticleContainer>>>> m_parentsAccessor{};
+  };
+}
+
+#endif
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGSherpaVjetsSysTool.h b/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGSherpaVjetsSysTool.h
index 086e21e0b3e149f659b002df8363d0b723f65c1d..7bef3eb60c11125e4b60eae8dd1466bb3a97ff98 100644
--- a/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGSherpaVjetsSysTool.h
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGSherpaVjetsSysTool.h
@@ -21,7 +21,7 @@
 #include "AsgTools/AsgTool.h"
 
 // Interface include(s):
-#include "PMGTools/IPMGSherpaVjetsSysTool.h"
+#include "PMGAnalysisInterfaces/IPMGSherpaVjetsSysTool.h"
 
 // System include(s):
 #include <map>
@@ -29,8 +29,10 @@
 #include <memory>
 
 // ROOT include(s):
-#include <TH2F.h>
-#include <TFile.h>
+#include "TFile.h"
+
+// Forward declaration
+class TH2F;
 
 namespace PMGTools {
 
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGToolsDict.h b/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGToolsDict.h
index 2c833517ea242af8968d435ee1e956fc4b823df0..5066d2443fe33c4049bf2691302086a69439887f 100644
--- a/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGToolsDict.h
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGToolsDict.h
@@ -9,7 +9,9 @@
 #define PMGTOOLS_PMGTOOLSDICT_H
 
 // Local include(s):
-#include "PMGTools/PMGSherpa22VJetsWeightTool.h"
 #include "PMGTools/PMGCrossSectionTool.h"
+#include "PMGTools/PMGDecayProductsSelectionTool.h"
+#include "PMGTools/PMGSherpa22VJetsWeightTool.h"
+#include "PMGTools/PMGTruthWeightTool.h"
 
 #endif // PMGTOOLS_PMGTOOLSDICT_H
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGTruthWeightTool.h b/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGTruthWeightTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..935571ad6e8edc2f9b9f02d831c044dd8d4a6bf3
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/PMGTruthWeightTool.h
@@ -0,0 +1,150 @@
+/*
+   Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef PMGTOOLS_PMGTRUTHWEIGHTTOOL_H
+#define PMGTOOLS_PMGTRUTHWEIGHTTOOL_H
+
+// EDM include(s):
+#include "AsgTools/AsgMetadataTool.h"
+#include "xAODTruth/TruthEventContainer.h"
+#include "xAODTruth/TruthMetaData.h"
+#include "xAODTruth/TruthMetaDataContainer.h"
+
+// Interface include(s):
+#include "PMGAnalysisInterfaces/IPMGTruthWeightTool.h"
+
+
+namespace PMGTools
+{
+  /// \brief the systematics prefix for generator weights
+  constexpr char generatorSystematicsPrefix[] {"GEN_"};
+
+  /// Implementation for the xAOD truth meta data weight tool
+  ///
+  /// @author James Robinson <james.robinson@cern.ch>
+  ///
+  class PMGTruthWeightTool : public virtual IPMGTruthWeightTool, public asg::AsgMetadataTool
+  {
+    /// Create a proper constructor for Athena
+    ASG_TOOL_CLASS(PMGTruthWeightTool, PMGTools::IPMGTruthWeightTool)
+
+  public:
+    /// Create a constructor for standalone usage
+    PMGTruthWeightTool(const std::string& name);
+
+    /// @name Function(s) implementing the asg::IAsgTool interface
+    /// @{
+
+    /// Function initialising the tool
+    virtual StatusCode initialize() override;
+
+    /// @}
+
+    /// @name Function(s) implementing the IPMGTruthWeightTool interface
+    /// @{
+
+    /// Implements interface from IPMGTruthWeightTool
+    virtual const std::vector<std::string>& getWeightNames() const override;
+
+    /// Implements interface from IPMGTruthWeightTool
+    virtual float getWeight(const std::string& weightName) const override;
+
+    /// Implements interface from IPMGTruthWeightTool
+    virtual bool hasWeight(const std::string& weightName) const override;
+
+    /// Implements interface from IPMGTruthWeightTool
+    virtual float getSysWeight() const override;
+
+    /// Implements interface from IPMGTruthWeightTool
+    virtual size_t getSysWeightIndex() const override;
+
+    /// @}
+
+    /// @name Function(s) implementing the ISystematicsTool interface
+    /// @{
+
+    /// Implements interface from ISystematicsTool
+    virtual bool isAffectedBySystematic(const CP::SystematicVariation& systematic) const override;
+
+    /// Implements interface from ISystematicsTool
+    virtual CP::SystematicSet affectingSystematics() const override;
+
+    /// Implements interface from ISystematicsTool
+    virtual CP::SystematicSet recommendedSystematics() const override;
+
+    /// Implements interface from ISystematicsTool
+    virtual CP::SystematicCode applySystematicVariation(const CP::SystematicSet& systConfig) override;
+
+    /// @}
+
+  protected:
+    /// @name Callback function(s) from AsgMetadataTool
+    /// @{
+
+    /// Function called when a new input file is opened
+    virtual StatusCode beginInputFile() override;
+
+    /// Function called when a new event is loaded
+    virtual StatusCode beginEvent() override;
+
+    /// @}
+
+    /// Loads weight information from xAOD::TruthMetaDataContainer
+    StatusCode loadMetaData();
+
+    /// Loads weight information from POOL using HepMCWeightNames
+    StatusCode loadPOOLMetaData();
+
+    /// Validate weight caches
+    StatusCode validateWeightLocationCaches();
+
+    /// Clear caches
+    void clearWeightLocationCaches();
+
+    /// Process the weight name to be used for systematics
+    std::string weightNameToSys(const std::string &name) const;
+
+    /// Stores the meta data record name
+    std::string m_metaName;
+
+    /// Current MC channel number
+    uint32_t m_mcChannelNumber{};
+
+    /// Systematics set of the weight systematics
+    CP::SystematicSet m_systematicsSet;
+
+    /// Ptr to the meta data container for this file
+    const xAOD::TruthMetaDataContainer* m_metaDataContainer{nullptr};
+
+    /// Flag to indicate whether the xAOD::TruthMetaData objects have incorrect McChannelNumber
+    bool m_useChannelZeroInMetaData{false};
+
+    /// Available weight names for this file
+    std::vector<std::string> m_weightNames;
+
+    /// Indices of available weights in this file
+    std::unordered_map<std::string, size_t> m_weightIndices;
+
+    /// Indices of available weights in this file
+    std::unordered_map<std::string, size_t> m_weightIndicesSys;
+
+    /// Values of weights in this event
+    std::vector<float> m_weights;
+
+    /// Weight data cache helper struct
+    struct WeightData
+    {
+      float weight;
+      std::size_t index;
+    };
+
+    /// Systematics cache of available weights in this file
+    std::unordered_map<CP::SystematicSet, WeightData> m_weightData;
+
+    /// Current systematics weight
+    WeightData *m_currentWeightData {nullptr};
+  };
+} // namespace PMGTools
+
+#endif // PMGTOOLS_PMGTRUTHWEIGHTTOOL_H
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/selection.xml b/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/selection.xml
index 624d061a6320169f0c03caa98151870bde4ebf64..7141c2b611a64d6824a1bae5f8cc9c336eb40daa 100644
--- a/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/selection.xml
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/PMGTools/selection.xml
@@ -1,9 +1,10 @@
 <!-- $Id: selection.xml 772287 2016-09-08 13:53:24Z tripiana $ -->
 <lcgdict>
 
-  <class name="PMGTools::PMGSherpa22VJetsWeightTool" />
   <class name="PMGTools::PMGCrossSectionTool" />
+  <class name="PMGTools::PMGDecayProductsSelectionTool" />
+  <class name="PMGTools::PMGSherpa22VJetsWeightTool" />
   <class name="PMGTools::PMGSherpaVjetsSysTool" />
-  <class name="PMGTools::IPMGSherpaVjetsSysTool" />
+  <class name="PMGTools::PMGTruthWeightTool" />
 
 </lcgdict>
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGCrossSectionTool.cxx b/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGCrossSectionTool.cxx
index 19d5c0a402e18b66db0dbf5abafa876b4dd08d3e..aaa346dbd3c2e52b2d1f20cf5b8d8e008a880aa5 100644
--- a/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGCrossSectionTool.cxx
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGCrossSectionTool.cxx
@@ -2,195 +2,216 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: PMGCrossSectionTool.cxx 810599 2017-09-22 15:50:07Z cohm $
+// $Id: PMGCrossSectionTool.cxx 764400 2016-07-26 17:47:39Z tripiana $
 
 #include <fstream>
 #include <sstream>
 #include <string>
 #include <TSystem.h>
 #include <TString.h>
-#include <TTree.h>
-#include <iostream>
 #include <stdlib.h>
+#include <limits>
 
 // Local include(s):
 #include "PMGTools/PMGCrossSectionTool.h"
 
 namespace PMGTools {
-  
-  PMGCrossSectionTool::
-  PMGCrossSectionTool( const std::string& name ) : asg::AsgTool( name )
-  {
-    
-  }
-  
-  StatusCode PMGCrossSectionTool::initialize() {
-    
-    // Tell the user what's happening:
-    ATH_MSG_INFO( "Initializing " << name() << "..." );
-    //ATH_MSG_INFO( "Read in all Xsec Info ..." );
 
-    //readInfosFromDir(inputDir.c_str());
+PMGCrossSectionTool::
+PMGCrossSectionTool(const std::string& name) : asg::AsgTool(name) { }
 
-    // Return gracefully:
-    return StatusCode::SUCCESS;
-  }
 
-  bool PMGCrossSectionTool::readInfosFromFiles(std::vector<std::string> InputFiles)
-  {
-    for (const auto& currentFileName : InputFiles) {
-
-      std::ifstream currentFile;
-      currentFile.open(currentFileName.c_str());
-
-      // use the TTree functionality for reading in text files - easy way to remove
-      // dependency on specific order of the columns in the text file
-      TTree* xsecTree = new TTree();
-      xsecTree->ReadFile(currentFileName.c_str());
-      
-      // one branch per variable we care about of the existing ones: DSID/I:DSName/C:GenXsec/D:BR:FilterEff:Xsec:Kfactor:TotSampleXsec
-      int dsid(0);
-      double genXsec(0);      
-      double filterEff(0);
-      double kFactor(0);
-      TBranch* dsidBranch = xsecTree->GetBranch("DSID");
-      dsidBranch->SetAddress(&dsid);
-      TBranch* genXsecBranch = xsecTree->GetBranch("crossSection");
-      genXsecBranch->SetAddress(&genXsec);
-      TBranch* filterEffBranch = xsecTree->GetBranch("genFiltEff");
-      filterEffBranch->SetAddress(&filterEff);
-      TBranch* kFactorBranch = xsecTree->GetBranch("kFactor");
-      kFactorBranch->SetAddress(&kFactor);
-
-      auto nEntries = xsecTree->GetEntries();
-      for (Long64_t i = 0; i < nEntries; i++) {
-	xsecTree->GetEntry(i);
-	AllSampleInfo sample;
-	sample.dsid = dsid;
-	sample.genXsec = genXsec;
-	sample.filterEff = filterEff;
-	sample.kFactor = kFactor;
-	//sample.containerName = containerName;
-	m_storeSampleInfo[sample.dsid] = sample;
-      }
-
-      delete xsecTree;
-    }
-    
-    return true;
-  }
+StatusCode PMGCrossSectionTool::initialize() {
 
-  bool PMGCrossSectionTool::readInfosFromDir(const std::string& inputDir)
-  {
+  // Tell the user what's happening:
+  ATH_MSG_INFO( "Initializing " << name() << "..." );
+  //ATH_MSG_INFO( "Read in all Xsec Info ..." );
 
-    TString mydir = inputDir;
-    gSystem->ExpandPathName (mydir);
-    void *dirp = 0;
-  
-    std::vector<std::string> inFiles={};
-  
-    try
-      {
-	dirp = gSystem->OpenDirectory (mydir.Data());
-	const char *file = 0;
-	while ((file = gSystem->GetDirEntry (dirp)))
-	  {
-	    std::string myfile = inputDir + "/" + file;
-	    if (myfile.size() > 4 && myfile.substr (myfile.size()-4) == ".txt")
-	      inFiles.push_back(myfile);
-	  }
-	gSystem->FreeDirectory (dirp);
-      }
-    catch (...)
-      {
-	gSystem->FreeDirectory (dirp);
-	//throw;
-	return false;
-      }
-  
-    readInfosFromFiles(inFiles);
-    return true;
-  }
+  //readInfosFromDir(inputDir.c_str());
 
+  // Return gracefully:
+  return StatusCode::SUCCESS;
+}
 
-  double PMGCrossSectionTool::getFilterEff(const int dsid) const
-  {
-  
-    for (const auto& info : m_storeSampleInfo){
-      if(dsid == info.second.dsid)
-	return info.second.filterEff;
+
+bool PMGCrossSectionTool::readInfosFromFiles(std::vector<std::string> InputFiles)
+{
+
+  for (const auto& currentFileName : InputFiles) {
+
+    std::ifstream currentFile(currentFileName);
+    if (not currentFile.is_open()) {
+      ATH_MSG_WARNING("cannot open file " << currentFileName);
+      continue;
     }
-  
-    std::cout << "ERROR::getFilterEff --> Sample with DSID " << dsid << " has no info stored!!! ---> EXIT." << std::endl;
-  
-    return -1;
-  
+
+    // skip first line
+    currentFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+
+    int nfound = 0;  // for this file
+    for (std::string line; std::getline(currentFile, line); ) {
+      std::stringstream input_line(line);
+      AllSampleInfo help;
+
+      input_line >> help.dsid;
+      input_line >> help.containerName;
+      input_line >> help.amiXSec;
+      input_line >> help.filterEff;
+      input_line >> help.kFactor;
+      input_line >> help.XSecUncUP;
+      input_line >> help.XSecUncDOWN;
+      // :: below is for future use?
+      //input_line >> help.br;
+      //input_line >> help.higherOrderXsecTotal;
+      //input_line >> help.higherOrderXsecSample; // this is hoXsec * filter eff
+
+      if (input_line.fail()) { ATH_MSG_ERROR("cannot parse line '" << line << "' from file " << currentFileName); continue; }
+
+      m_fStoreSampleInfo[help.dsid] = help;
+      ++nfound;
+    }
+
+    if (nfound == 0) { ATH_MSG_WARNING("no sample read from file " << currentFileName); }
   }
 
+  if (m_fStoreSampleInfo.empty()) {
+    ATH_MSG_ERROR("list of sample is empty");
+    return false;
+  }
 
-  std::string PMGCrossSectionTool::getSampleName(const int dsid) const
+  return true;
+}
+
+
+bool PMGCrossSectionTool::readInfosFromDir(const std::string& inputDir)
+{
+
+  TString mydir = inputDir;
+  gSystem->ExpandPathName (mydir);
+  void *dirp = 0;
+
+  std::vector<std::string> inFiles = {};
+
+  try
   {
-  
-    for (const auto& info : m_storeSampleInfo){
-      if(dsid == info.second.dsid)
-	return info.second.containerName;
+    dirp = gSystem->OpenDirectory (mydir.Data());
+    const char *file = 0;
+    while ((file = gSystem->GetDirEntry (dirp)))
+    {
+      std::string myfile = inputDir + "/" + file;
+      if (myfile.size() > 4 && myfile.substr (myfile.size() - 4) == ".txt")
+        inFiles.push_back(myfile);
     }
-  
-    std::cout << "ERROR::getSampleName --> Sample with DSID " << dsid << " has no info stored!!! ---> EXIT." << std::endl;
-    
-    return "";
-    
+    gSystem->FreeDirectory (dirp);
+  }
+  catch (...)
+  {
+    gSystem->FreeDirectory (dirp);
+    //throw;
+    return false;
   }
 
+  readInfosFromFiles(inFiles);
+  return true;
+}
 
-  double PMGCrossSectionTool::getGeneratorXsection(const int dsid) const
-  {
 
-    for (const auto& info : m_storeSampleInfo){
-      if(dsid == info.second.dsid)
-	return info.second.genXsec;
-    }
+double PMGCrossSectionTool::getFilterEff(const int dsid) const
+{
+  const auto it = m_fStoreSampleInfo.find(dsid);
+  if (it != m_fStoreSampleInfo.end()) { return it->second.filterEff; }
 
-    std::cout << "ERROR::getGeneratorXsection --> Sample with DSID " << dsid << " has no info stored!!! ---> EXIT." << std::endl;
-  
-    return -1;
+  ATH_MSG_ERROR("Sample with DSID " << dsid << " has no info stored!!!");
+  return -1;
+}
 
-  } 
 
-  double PMGCrossSectionTool::getKfactor(const int dsid) const
-  {
+std::string PMGCrossSectionTool::getSampleName(const int dsid) const
+{
+  const auto it = m_fStoreSampleInfo.find(dsid);
+  if (it != m_fStoreSampleInfo.end()) { return it->second.containerName; }
 
-    for (const auto& info : m_storeSampleInfo){
-      if(dsid == info.second.dsid)
-	return info.second.kFactor;
-    }
+  ATH_MSG_ERROR("Sample with DSID " << dsid << " has no info stored!!!");
+  return std::string("");
+}
 
-    std::cout << "ERROR::getKfactor --> Sample with DSID " << dsid << " has no info stored!!! ---> EXIT." << std::endl;
 
-    return -1;
+double PMGCrossSectionTool::getAMIXsection(const int dsid) const
+{
+  const auto it = m_fStoreSampleInfo.find(dsid);
+  if (it != m_fStoreSampleInfo.end()) { return it->second.amiXSec; }
 
-  }
+  ATH_MSG_ERROR("Sample with DSID " << dsid << " has no info stored!!!");
+  return -1;
+}
 
-  double PMGCrossSectionTool::getSampleXsection(const int dsid) const
-  {
 
-    for (const auto& info : m_storeSampleInfo){
-      if(dsid == info.second.dsid)
-	return info.second.genXsec * info.second.kFactor * info.second.filterEff;
-    }
+// :: below is for future use?
+/*double PMGCrossSectionTool::getBR(const int dsid) const
+{
+  const auto it = m_fStoreSampleInfo.find(dsid);
+  if (it != m_fStoreSampleInfo.end()) { return it->second.br; }
 
-    std::cout << "ERROR::getSampleXsection --> Sample with DSID " << dsid << " has no info stored!!! ---> EXIT." << std::endl;
+  ATH_MSG_ERROR("Sample with DSID " << dsid << " has no info stored!!!");
+  return -1;
 
-    return -1;
+}*/
 
-  }
 
-  std::vector<int> PMGCrossSectionTool::getLoadedDSIDs() const {
-    std::vector<int> dsids;
-    for (const auto& info : m_storeSampleInfo){
-      dsids.push_back(info.second.dsid);
-    }
-    return dsids;
-  }
+double PMGCrossSectionTool::getXsectionUncertaintyUP(const int dsid) const
+{
+  const auto it = m_fStoreSampleInfo.find(dsid);
+  if (it != m_fStoreSampleInfo.end()) { return it->second.XSecUncUP; }
 
+  ATH_MSG_ERROR("Sample with DSID " << dsid << " has no info stored!!!");
+  return -1;
 }
+
+double PMGCrossSectionTool::getXsectionUncertaintyDOWN(const int dsid) const
+{
+  const auto it = m_fStoreSampleInfo.find(dsid);
+  if (it != m_fStoreSampleInfo.end()) { return it->second.XSecUncDOWN; }
+  
+  ATH_MSG_ERROR("Sample with DSID " << dsid << " has no info stored!!!");
+  return -1;
+}
+
+double PMGCrossSectionTool::getXsectionUncertainty(const int dsid) const
+{
+  //symmetrize the up and down variations
+  return 0.5*( fabs(getXsectionUncertaintyDOWN(dsid)) + fabs(getXsectionUncertaintyUP(dsid)) );
+}
+
+double PMGCrossSectionTool::getKfactor(const int dsid) const
+{
+  const auto it = m_fStoreSampleInfo.find(dsid);
+  if (it != m_fStoreSampleInfo.end()) { return it->second.kFactor; }
+
+  ATH_MSG_ERROR("Sample with DSID " << dsid << " has no info stored!!!");
+  return -1;
+}
+
+
+// :: below is for future use?
+double PMGCrossSectionTool::getSampleXsection(const int dsid) const
+{
+  const auto it = m_fStoreSampleInfo.find(dsid);
+  if (it != m_fStoreSampleInfo.end()) { return it->second.amiXSec * it->second.kFactor * it->second.filterEff; }
+    // :: below is for future use?
+    //return info.higherOrderXsecSample;
+
+  ATH_MSG_ERROR("Sample with DSID " << dsid << " has no info stored!!!");
+  return -1;
+}
+
+
+std::vector<int> PMGCrossSectionTool::getLoadedDSIDs() const {
+  std::vector<int> dsids;
+  dsids.reserve(m_fStoreSampleInfo.size());
+  for (const std::pair<unsigned, AllSampleInfo>& key_info : m_fStoreSampleInfo) {
+    dsids.push_back(key_info.second.dsid);
+  }
+  return dsids;
+}
+
+} // end namespace
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGDecayProductsSelectionTool.cxx b/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGDecayProductsSelectionTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b737b0446db6c5a4d76685278c0a465930273ecb
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGDecayProductsSelectionTool.cxx
@@ -0,0 +1,177 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+/// @author Tadej Novak
+
+
+
+//
+// includes
+//
+
+#include <PMGTools/PMGDecayProductsSelectionTool.h>
+
+#include <xAODTruth/xAODTruthHelpers.h>
+#include <xAODBase/IParticle.h>
+
+#include <sstream>
+
+//
+// method implementations
+//
+
+namespace PMGTools
+{
+  PMGDecayProductsSelectionTool :: 
+  PMGDecayProductsSelectionTool (const std::string& name)
+    : AsgTool (name)
+  {
+    declareProperty ("requiredParentPDGIDs", m_requiredParentPDGIDs, "required parent particle PDG IDs (positive only)");
+    declareProperty ("allowedIntermediatePDGIDs", m_allowedIntermediatePDGIDs, "allowed intermediate particles PDG IDs (positive only)");
+  }
+
+
+
+  StatusCode PMGDecayProductsSelectionTool ::
+  initialize ()
+  {
+    if (m_requiredParentPDGIDs.empty())
+    {
+      ATH_MSG_ERROR ("required parent particles need to be set");
+      return StatusCode::FAILURE;
+    }
+
+    m_truthParticleIndex = m_accept.addCut ("truthParticle", "has truth particle cut");
+
+    std::ostringstream particles;
+    for (int pdgId : m_requiredParentPDGIDs)
+    {
+      particles << " " << pdgId;
+    }
+    ATH_MSG_DEBUG ("Performing required parent particle selection with parent PDG IDs:" << particles.str());
+    m_requiredParentIndex = m_accept.addCut ("requiredParents", "required parent particles cut");
+
+    if (!m_allowedIntermediatePDGIDs.empty())
+    {
+      std::ostringstream particles;
+      for (int pdgId : m_allowedIntermediatePDGIDs)
+      {
+        particles << " " << pdgId;
+      }
+      ATH_MSG_DEBUG ("Performing allowed intermediate particle selection with allowed PDG IDs:" << particles.str());
+    }
+
+    m_parentsAccessor = std::make_unique<const SG::AuxElement::Accessor<std::vector<ElementLink<xAOD::TruthParticleContainer>>>>("parentLinks");
+
+    return StatusCode::SUCCESS;
+  }
+
+
+
+  const asg::AcceptInfo& PMGDecayProductsSelectionTool ::
+  getAcceptInfo () const
+  {
+    return m_accept;
+  }
+
+
+
+  asg::AcceptData PMGDecayProductsSelectionTool ::
+  accept (const xAOD::IParticle *particle) const
+  {
+    asg::AcceptData acceptData (&m_accept);
+
+    // Check if xAOD::TruthParticle or if not if it has the TruthParticleLink
+    const xAOD::TruthParticle *truthParticle
+      = dynamic_cast<const xAOD::TruthParticle *> (particle);
+    if (truthParticle == nullptr)
+    {
+      // need to find the truth particle
+      truthParticle = xAOD::TruthHelpers::getTruthParticle(*particle);
+      if (truthParticle == nullptr)
+      {
+        acceptData.setCutResult (m_truthParticleIndex, false);
+        return acceptData;
+      }
+    }
+    acceptData.setCutResult (m_truthParticleIndex, true);
+
+    return hasRequiredInitialParent(truthParticle, acceptData);
+  }
+
+
+
+  asg::AcceptData PMGDecayProductsSelectionTool ::
+  hasRequiredInitialParent (const xAOD::TruthParticle *truthParticle, asg::AcceptData& acceptData) const
+  {
+    size_t nParents = getNParents (truthParticle);
+    for (size_t i = 0; i < nParents; i++)
+    {
+      const xAOD::TruthParticle *parent = getParent(truthParticle, i);
+      if (parent)
+      {
+        if (std::find(m_requiredParentPDGIDs.begin(), m_requiredParentPDGIDs.end(), std::abs(parent->pdgId())) != m_requiredParentPDGIDs.end())
+        {
+          acceptData.setCutResult (m_requiredParentIndex, true);
+          return acceptData;
+        }
+        else if (m_allowedIntermediatePDGIDs.empty() || std::find(m_allowedIntermediatePDGIDs.begin(), m_allowedIntermediatePDGIDs.end(), std::abs(parent->pdgId())) != m_allowedIntermediatePDGIDs.end())
+        {
+          return hasRequiredInitialParent(parent, acceptData);
+        }
+        else
+        {
+          ATH_MSG_VERBOSE("Removing particle as parent is not allowed: " << parent->pdgId());
+          return acceptData;
+        }
+      }
+      else
+      {
+        ATH_MSG_WARNING("Particle parent is not valid");
+        return acceptData;
+      }
+    }
+
+    if (std::find(m_requiredParentPDGIDs.begin(), m_requiredParentPDGIDs.end(), std::abs(truthParticle->pdgId())) != m_requiredParentPDGIDs.end())
+    {
+      acceptData.setCutResult (m_requiredParentIndex, true);
+      return acceptData;
+    }
+
+    return acceptData;
+  }
+
+
+
+  size_t PMGDecayProductsSelectionTool ::
+  getNParents (const xAOD::TruthParticle *truthParticle) const
+  {
+    if (m_parentsAccessor->isAvailable (*truthParticle))
+    {
+      return (*m_parentsAccessor)(*truthParticle).size();
+    }
+    else
+    {
+      return truthParticle->nParents();
+    }
+  }
+
+
+
+  const xAOD::TruthParticle* PMGDecayProductsSelectionTool ::
+  getParent (const xAOD::TruthParticle *truthParticle,
+              size_t index) const
+  {
+    if (m_parentsAccessor->isAvailable (*truthParticle))
+    {
+      ElementLink<xAOD::TruthParticleContainer> parentElementLink
+        = (*m_parentsAccessor)(*truthParticle).at(index);
+      return parentElementLink.isValid() ? *parentElementLink : nullptr;
+    }
+    else
+    {
+      return truthParticle->parent(index);
+    }
+  }
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGSherpaVjetsSysTool.cxx b/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGSherpaVjetsSysTool.cxx
index 08e3c65b0995496dd14dac4bdae6b329d9a59009..73781d56a9401ad4cca43c08a429cd1de9a09a9a 100644
--- a/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGSherpaVjetsSysTool.cxx
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGSherpaVjetsSysTool.cxx
@@ -5,8 +5,9 @@
 // $Id: PMGSherpaVjetsSysTool.cxx.cxx 2016-07-12 tripiana $
 
 // ROOT include(s):
-#include <TKey.h>
-#include <TIterator.h>
+#include "TKey.h"
+#include "TIterator.h"
+#include "TH2F.h"
 
 // EDM include(s):
 #include "xAODEventInfo/EventInfo.h"
@@ -326,6 +327,64 @@ namespace PMGTools {
     if( MCID>=361054 && MCID<361057 ){ pType=SysParType::GammaJets;   return 6; }    
     if( MCID>=361057 && MCID<361061 ){ pType=SysParType::GammaJets;   return 7; }    
 
+
+    //Check Znunu 2.2.1 samples
+    if( MCID>=364142 && MCID<364145 ){ pType=SysParType::Znunu;   return 1; }
+    if( MCID>=364145 && MCID<364148 ){ pType=SysParType::Znunu;   return 2; }    
+    if( MCID>=364148 && MCID<364151 ){ pType=SysParType::Znunu;   return 3; }    
+    if( MCID>=364151 && MCID<364154 ){ pType=SysParType::Znunu;   return 4; }    
+    if( MCID==364154  ){ pType=SysParType::Znunu;   return 5; }    
+    if( MCID==364155  ){ pType=SysParType::Znunu;   return 7; }    
+
+    //Check Zee 2.2.1 samples
+    if( MCID>=364114 && MCID<364117 ){ pType=SysParType::Zll;   return 1; }
+    if( MCID>=364117 && MCID<364120 ){ pType=SysParType::Zll;   return 2; }    
+    if( MCID>=364120 && MCID<364123 ){ pType=SysParType::Zll;   return 3; }    
+    if( MCID>=364123 && MCID<364126 ){ pType=SysParType::Zll;   return 4; }    
+    if( MCID==364126 ){ pType=SysParType::Zll;   return 5; }    
+    if( MCID==364127 ){ pType=SysParType::Zll;   return 7; }    
+
+    //Check Zmumu 2.2.1 samples
+    if( MCID>=364100 && MCID<364103 ){ pType=SysParType::Zll;   return 1; }
+    if( MCID>=364103 && MCID<364106 ){ pType=SysParType::Zll;   return 2; }    
+    if( MCID>=364106 && MCID<364109 ){ pType=SysParType::Zll;   return 3; }    
+    if( MCID>=364109 && MCID<364112 ){ pType=SysParType::Zll;   return 4; }    
+    if( MCID==364112 ){ pType=SysParType::Zll;   return 5; }    
+    if( MCID==364113 ){ pType=SysParType::Zll;   return 7; }    
+
+    //Check Ztautau 2.2.1 samples
+    if( MCID>=364128 && MCID<364131 ){ pType=SysParType::Zll;   return 1; }
+    if( MCID>=364131 && MCID<364134 ){ pType=SysParType::Zll;   return 2; }    
+    if( MCID>=364134 && MCID<364137 ){ pType=SysParType::Zll;   return 3; }    
+    if( MCID>=364137 && MCID<364140 ){ pType=SysParType::Zll;   return 4; }    
+    if( MCID==364140 ){ pType=SysParType::Zll;   return 5; }    
+    if( MCID==364141 ){ pType=SysParType::Zll;   return 7; }    
+
+    //Check Wenu 2.2.1 samples
+    if( MCID>=364170 && MCID<364173 ){ pType=SysParType::Wlnu;   return 1; }
+    if( MCID>=364173 && MCID<364176 ){ pType=SysParType::Wlnu;   return 2; }    
+    if( MCID>=364176 && MCID<364179 ){ pType=SysParType::Wlnu;   return 3; }    
+    if( MCID>=364179 && MCID<364182 ){ pType=SysParType::Wlnu;   return 4; }    
+    if( MCID==364182 ){ pType=SysParType::Wlnu;   return 5; }    
+    if( MCID==364183 ){ pType=SysParType::Wlnu;   return 7; }    
+
+    //Check Wmunu 2.2.1 samples
+    if( MCID>=364156 && MCID<364159 ){ pType=SysParType::Wlnu;   return 1; }
+    if( MCID>=364159 && MCID<364162 ){ pType=SysParType::Wlnu;   return 2; }    
+    if( MCID>=364162 && MCID<364165 ){ pType=SysParType::Wlnu;   return 3; }    
+    if( MCID>=364165 && MCID<364168 ){ pType=SysParType::Wlnu;   return 4; }    
+    if( MCID==364168  ){ pType=SysParType::Wlnu;   return 5; }    
+    if( MCID==364169  ){ pType=SysParType::Wlnu;   return 7; }    
+
+    //Check Wtaunu 2.2.1 samples
+    if( MCID>=364184 && MCID<364187 ){ pType=SysParType::Wlnu;   return 1; }
+    if( MCID>=364187 && MCID<364190 ){ pType=SysParType::Wlnu;   return 2; }    
+    if( MCID>=364190 && MCID<364193 ){ pType=SysParType::Wlnu;   return 3; }    
+    if( MCID>=364193 && MCID<364196 ){ pType=SysParType::Wlnu;   return 4; }    
+    if( MCID==364196  ){ pType=SysParType::Wlnu;   return 5; }    
+    if( MCID==364197  ){ pType=SysParType::Wlnu;   return 7; }    
+
+
     return -1;
   }
 
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGTruthWeightTool.cxx b/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGTruthWeightTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fc1f8fccc374d93c89f8ab3785bf064c886e8a89
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/Root/PMGTruthWeightTool.cxx
@@ -0,0 +1,397 @@
+/*
+   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+// EDM include(s):
+#ifndef XAOD_STANDALONE
+  #include "AthAnalysisBaseComps/AthAnalysisHelper.h"
+  #include "EventInfo/EventInfo.h"
+  #include "EventInfo/EventType.h"
+#endif
+
+// Local include(s):
+#include <CxxUtils/StringUtils.h>
+#include <RootCoreUtils/StringUtil.h>
+
+#include <PATInterfaces/SystematicRegistry.h>
+#include <xAODEventInfo/EventInfo.h>
+#include <xAODMetaData/FileMetaData.h>
+
+#include <PMGTools/PMGTruthWeightTool.h>
+
+// For replacing substrings
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
+
+namespace PMGTools
+{
+  PMGTruthWeightTool::PMGTruthWeightTool(const std::string& name)
+    : asg::AsgMetadataTool(name)
+  {
+    declareProperty("MetaObjectName", m_metaName = "TruthMetaData");
+  }
+
+
+  StatusCode PMGTruthWeightTool::initialize()
+  {
+    ATH_MSG_DEBUG("Initialising...");
+
+    ATH_MSG_INFO("Attempting to retrieve truth meta data from the first file...");
+
+    // Clear cached weights
+    clearWeightLocationCaches();
+
+    // Set the MC channel number to an impossible number (max-uint) to force meta data updating
+    m_mcChannelNumber = uint32_t(-1);
+
+    // Try to load MC channel number from file metadata
+    ATH_MSG_INFO("Attempting to retrieve MC channel number...");
+    const xAOD::FileMetaData *fmd = nullptr;
+    if (inputMetaStore()->contains<xAOD::FileMetaData>("FileMetaData")) {
+      ATH_CHECK(inputMetaStore()->retrieve(fmd, "FileMetaData"));
+      float fltChannelNumber(-1);
+      if (fmd->value(xAOD::FileMetaData::mcProcID, fltChannelNumber)) {
+        m_mcChannelNumber = uint32_t(fltChannelNumber);
+      }
+    }
+    if (m_mcChannelNumber == uint32_t(-1)) {
+      ATH_MSG_WARNING("... MC channel number could not be loaded");
+    } else {
+      ATH_MSG_INFO("... MC channel number identified as " << m_mcChannelNumber);
+    }
+
+    // Start by trying to load metadata from the store
+    m_metaDataContainer = nullptr;
+    if (inputMetaStore()->contains<xAOD::TruthMetaDataContainer>(m_metaName)) {
+      ATH_CHECK(inputMetaStore()->retrieve(m_metaDataContainer, m_metaName));
+      ATH_MSG_INFO("Loaded xAOD::TruthMetaDataContainer");
+
+      // Check for incorrectly stored McChannelNumber
+      m_useChannelZeroInMetaData = true;
+      for (auto truthMetaData : *m_metaDataContainer) {
+        if (truthMetaData->mcChannelNumber() != 0) { m_useChannelZeroInMetaData = false; }
+      }
+      // If we only have one metadata item take MC channel from there if needed
+      if (m_mcChannelNumber == uint32_t(-1) && m_metaDataContainer->size() == 1) {
+        m_mcChannelNumber = m_metaDataContainer->at(0)->mcChannelNumber();
+        ATH_MSG_WARNING("... MC channel number taken from the metadata as " << m_mcChannelNumber);
+      }
+      if (m_useChannelZeroInMetaData) { ATH_MSG_WARNING("MC channel number in TruthMetaData is invalid - assuming that channel 0 has the correct information."); }
+
+      // Load metadata from TruthMetaDataContainer if we have a valid channel number or if we're going to use 0 anyway
+      // ... otherwise wait until we can load a channel number from EventInfo
+      if (m_mcChannelNumber != uint32_t(-1) || m_useChannelZeroInMetaData) {
+        if (loadMetaData().isFailure()) {
+          ATH_MSG_ERROR("Could not load metadata for MC channel number " << m_mcChannelNumber);
+          return StatusCode::FAILURE;
+        }
+      }
+    } else {
+      // ... now try to load the weight container using the POOL metadata (not possible in AnalysisBase)
+      // see https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/AthAnalysisBase#How_to_read_the_truth_weight_nam
+      if (loadPOOLMetaData().isFailure()) {
+        ATH_MSG_ERROR("Could not load POOL HepMCWeightNames");
+        return StatusCode::FAILURE;
+      }
+    }
+
+    // Add the affecting systematics to the global registry
+    CP::SystematicRegistry& registry = CP::SystematicRegistry::getInstance();
+    if (!registry.registerSystematics(*this)) {
+      ATH_MSG_ERROR("unable to register the systematics");
+      return StatusCode::FAILURE;
+    }
+
+    ATH_MSG_DEBUG("Successfully initialized!");
+
+    return StatusCode::SUCCESS;
+  }
+
+
+  const std::vector<std::string>& PMGTruthWeightTool::getWeightNames() const {
+    return m_weightNames;
+  }
+
+
+  float PMGTruthWeightTool::getWeight(const std::string& weightName) const {
+    // Check that we have loaded event weights
+    if (m_weights.size() == 0) {
+      ATH_MSG_FATAL("No MC weights found!");
+      throw std::runtime_error(name() + ": No MC weights found!");
+    }
+
+    // Return appropriate weight from EventInfo: this should be identical to the TruthEvent
+    try {
+      return m_weights.at(m_weightIndices.at(weightName));
+    } catch (const std::out_of_range& e) {
+      // Before throwing an exception, try to recover with bad naming conventions
+      std::string strippedName = boost::algorithm::to_lower_copy(boost::replace_all_copy(weightName, " ", ""));
+      for (const auto & weight:m_weightNames){
+        if (strippedName==boost::algorithm::to_lower_copy(boost::replace_all_copy(weight," ", ""))){
+          ATH_MSG_WARNING("Using weight name \"" << weight << "\" instead of requested \"" << weightName << "\"");
+          return getWeight(weight);
+        }
+      }
+      ATH_MSG_FATAL("Weight \"" + weightName + "\" could not be found");
+      throw std::runtime_error(name() + ": Weight \"" + weightName + "\" could not be found");
+    }
+  }
+
+
+  bool PMGTruthWeightTool::hasWeight(const std::string& weightName) const {
+    return (m_weightIndices.count(weightName) > 0);
+  }
+
+
+  float PMGTruthWeightTool::getSysWeight() const
+  {
+    return m_currentWeightData->weight;
+  }
+
+
+  size_t PMGTruthWeightTool::getSysWeightIndex() const
+  {
+    return m_currentWeightData->index;
+  }
+
+
+  bool PMGTruthWeightTool::isAffectedBySystematic(const CP::SystematicVariation& systematic) const
+  {
+    return m_systematicsSet.find( systematic ) != m_systematicsSet.end();
+  }
+
+
+  CP::SystematicSet PMGTruthWeightTool::affectingSystematics() const
+  {
+    return m_systematicsSet;
+  }
+
+
+  CP::SystematicSet PMGTruthWeightTool::recommendedSystematics() const
+  {
+    return affectingSystematics();
+  }
+
+
+  CP::SystematicCode PMGTruthWeightTool::applySystematicVariation(const CP::SystematicSet& systConfig)
+  {
+    auto iter = m_weightData.find (systConfig);
+    if (iter != m_weightData.end())
+    {
+      m_currentWeightData = &iter->second;
+      return CP::SystematicCode::Ok;
+    }
+
+    CP::SystematicSet currentSys;
+    ANA_CHECK_SET_TYPE (CP::SystematicCode);
+    ANA_CHECK (CP::SystematicSet::filterForAffectingSystematics (systConfig, m_systematicsSet, currentSys));
+
+    WeightData currentWeight{};
+    currentWeight.index = m_weightIndicesSys.at(currentSys.name());
+    if (!m_weights.empty())
+    {
+      currentWeight.weight = m_weights.at(currentWeight.index);
+    }
+
+    auto insert = m_weightData.emplace(systConfig, std::move(currentWeight));
+    m_currentWeightData = &insert.first->second;
+
+    return CP::SystematicCode::Ok;
+  }
+
+
+  StatusCode PMGTruthWeightTool::beginInputFile()
+  {
+    // Detect possible MC channel number change
+    uint32_t mcChannelNumber(-1);
+
+    // Try to load MC channel number from file metadata
+    ATH_MSG_DEBUG("Attempting to retrieve MC channel number...");
+    const xAOD::FileMetaData *fmd = nullptr;
+    if (inputMetaStore()->contains<xAOD::FileMetaData>("FileMetaData")) {
+      ATH_CHECK(inputMetaStore()->retrieve(fmd, "FileMetaData"));
+      float fltChannelNumber(-1);
+      if (fmd->value(xAOD::FileMetaData::mcProcID, fltChannelNumber)) {
+        mcChannelNumber = uint32_t(fltChannelNumber);
+      }
+    }
+    if (m_mcChannelNumber != uint32_t(-1) && mcChannelNumber != uint32_t(-1) && mcChannelNumber != m_mcChannelNumber) {
+      ATH_MSG_ERROR("MC channel number from a new file does not match the previously processed files.");
+      return StatusCode::FAILURE;
+    }
+
+    return StatusCode::SUCCESS;
+  }
+
+
+  StatusCode PMGTruthWeightTool::beginEvent() {
+    // Clear weights and channel number from previous event
+    m_weights.clear();
+    m_weightData.clear();
+
+    // Try to read information about weights and channel number from EventInfo
+    // 1. try the xAOD::EventInfo object
+    if (evtStore()->contains<xAOD::EventInfo>("EventInfo")) {
+      const xAOD::EventInfo* evtInfo;
+      ATH_CHECK(evtStore()->retrieve(evtInfo, "EventInfo"));
+      m_weights = evtInfo->mcEventWeights();
+
+    // 2. otherwise, if we're not in AnalysisBase, see if there's an EventInfo object
+#ifndef XAOD_STANDALONE
+    } else if (evtStore()->contains<EventInfo>("McEventInfo")) {
+      const EventInfo* evtInfo;
+      ATH_CHECK(evtStore()->retrieve(evtInfo, "McEventInfo"));
+      for (unsigned int idx = 0; idx < evtInfo->event_type()->n_mc_event_weights(); ++idx) {
+        m_weights.push_back(evtInfo->event_type()->mc_event_weight(idx));
+      }
+#endif // not XAOD_STANDALONE
+
+    // 3. otherwise let's bail here
+    } else {
+      ATH_MSG_ERROR("No event information is available in this file!");
+      return StatusCode::FAILURE;
+    }
+
+    // Validate weight caches against event information
+    if (m_weightNames.size() != m_weights.size()) {
+      // Special case to allow nominal weight to be used when this is the only weight in the event
+      if ((m_weightNames.size() == 0) && (m_weights.size() == 1)) {
+        ATH_MSG_WARNING("No weight names were available in this sample! Proceeding under the assumption that the single available weight should be 'nominal'");
+        m_weightNames.push_back("nominal");
+        m_weightIndices["nominal"] = 0;
+        m_weightIndicesSys[""] = 0;
+      } else {
+        ATH_MSG_ERROR("Expected " << m_weightNames.size() << " weights from the metadata but found " << m_weights.size() << " in this event");
+        ATH_MSG_ERROR("Perhaps this sample was made using a release which did not correctly propagate the event weights.");
+      }
+    }
+
+    // Apply nominal systematics by default
+    ANA_CHECK (applySystematicVariation (CP::SystematicSet()));
+
+    return StatusCode::SUCCESS;
+  }
+
+
+  StatusCode PMGTruthWeightTool::loadMetaData() {
+    // Clear cached weight names and positions
+    this->clearWeightLocationCaches();
+
+    // Find the correct truth meta data object
+    uint32_t targetChannelNumber = (m_useChannelZeroInMetaData ? 0 : m_mcChannelNumber);
+    ATH_MSG_INFO("Attempting to load weight meta data from xAOD TruthMetaData for channel " << targetChannelNumber);
+    auto itTruthMetaDataPtr = std::find_if(m_metaDataContainer->begin(), m_metaDataContainer->end(),
+      [targetChannelNumber] (const auto& it) { return it->mcChannelNumber() == targetChannelNumber; }
+    );
+
+    // If no such object is found then return
+    if (itTruthMetaDataPtr == m_metaDataContainer->end()) {
+      ATH_MSG_ERROR("Could not load weight meta data!");
+      return StatusCode::FAILURE;
+    }
+
+    // Update cached weight data
+    const std::vector<std::string> &truthWeightNames = (*itTruthMetaDataPtr)->weightNames();
+    for(std::size_t idx = 0; idx < truthWeightNames.size(); ++idx ) {
+      ANA_MSG_VERBOSE("    " << truthWeightNames.at(idx));
+      m_weightNames.push_back(truthWeightNames.at(idx));
+      m_weightIndices[truthWeightNames.at(idx)] = idx;
+
+      std::string sysName = weightNameToSys(truthWeightNames.at(idx));
+      if (!sysName.empty()) {
+        m_systematicsSet.insert(CP::SystematicVariation(sysName));
+      }
+      m_weightIndicesSys[sysName] = idx;
+    }
+    return this->validateWeightLocationCaches();
+  }
+
+
+  StatusCode PMGTruthWeightTool::loadPOOLMetaData() {
+    // AnalysisBase can only use the xAOD::TruthMetaDataContainer, so skip this
+#ifdef XAOD_STANDALONE
+    return StatusCode::SUCCESS;
+#else
+    ATH_MSG_INFO("Looking for POOL HepMC IOVMetaData...");
+    std::map<std::string, int> hepMCWeightNamesMap;
+    if (AAH::retrieveMetadata("/Generation/Parameters", "HepMCWeightNames", hepMCWeightNamesMap, inputMetaStore()).isFailure()) {
+      ATH_MSG_FATAL("Cannot access metadata " << m_metaName << " and failed to get names from IOVMetadata");
+      return StatusCode::FAILURE;
+    }
+
+    // Clear cached weight names and positions
+    this->clearWeightLocationCaches();
+
+    // Use input map to fill the index map and the weight names
+    ATH_MSG_INFO("Attempting to load weight meta data from HepMC IOVMetaData container");
+    for (auto& kv : hepMCWeightNamesMap) {
+      ANA_MSG_VERBOSE("    " << kv.first);
+      m_weightNames.push_back(kv.first);
+      m_weightIndices[kv.first] = kv.second;
+
+      std::string sysName = weightNameToSys(kv.first);
+      if (!sysName.empty()) {
+        m_systematicsSet.insert(CP::SystematicVariation(sysName));
+      }
+      m_weightIndicesSys[sysName] = kv.second;
+    }
+    return this->validateWeightLocationCaches();
+#endif // XAOD_STANDALONE
+  }
+
+
+  StatusCode PMGTruthWeightTool::validateWeightLocationCaches() {
+    // Validate weight caches against one another
+    if (m_weightNames.size() != m_weightIndices.size()) {
+      ATH_MSG_ERROR("Found " << m_weightNames.size() << " but " << m_weightIndices.size() << " weight indices!");
+      return StatusCode::FAILURE;
+    }
+    // Check if we can work with systematics
+    auto it = m_weightIndicesSys.find("");
+    if (it == m_weightIndicesSys.end()) {
+      ATH_MSG_WARNING("Could not detect nominal weight automatically. The first weight will also be considered nominal.");
+      m_weightIndicesSys[""] = 0;
+    }
+
+    ATH_MSG_INFO("Successfully loaded information about " << m_weightNames.size() << " weights");
+    return StatusCode::SUCCESS;
+  }
+
+
+  void PMGTruthWeightTool::clearWeightLocationCaches() {
+    m_weightNames.clear();
+    m_weightIndices.clear();
+    m_weightIndicesSys.clear();
+    m_systematicsSet.clear();
+  }
+
+
+  std::string PMGTruthWeightTool::weightNameToSys (const std::string &name) const
+  {
+    if (name.empty()) // empty weight is nominal
+    {
+      return "";
+    }
+
+    // Trim trailing whitespace
+    std::string sys = CxxUtils::StringUtils::trim (name);
+    if (sys == "nominal" // Powheg calls it "nominal"
+      || sys == "Weight") // Sherpa names the nominal weight just "Weight"
+    {
+      return "";
+    }
+
+    sys = RCU::substitute (sys, " set = ", "_"); // Powheg
+    sys = RCU::substitute (sys, " = ", "_"); // Powheg
+    sys = RCU::substitute (sys, "=", "");
+    sys = RCU::substitute (sys, ",", "");
+    sys = RCU::substitute (sys, ".", "");
+    sys = RCU::substitute (sys, ":", "");
+    sys = RCU::substitute (sys, " ", "_");
+    sys = RCU::substitute (sys, "#", "num");
+    sys = RCU::substitute (sys, "\n", "_");
+    sys = RCU::substitute (sys, "/", "over"); // MadGraph
+
+    return generatorSystematicsPrefix + sys;
+  }
+} // namespace PMGTools
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/python/test_PMGCrossSectionTool.py b/PhysicsAnalysis/AnalysisCommon/PMGTools/python/test_PMGCrossSectionTool.py
index 5de2f5f4e487ee0c049cc8d7ad6e66fa2c6847d0..3b4b493acf491115fe49df4962b4bf5e51278df1 100644
--- a/PhysicsAnalysis/AnalysisCommon/PMGTools/python/test_PMGCrossSectionTool.py
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/python/test_PMGCrossSectionTool.py
@@ -1,24 +1,34 @@
 #!/bin/env python
 
 # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-import ROOT, os
+import ROOT
 
-#def main(filename, **args):
-def main(**args):
+def main():
+    from PathResolver import PathResolver
 
     tool = ROOT.PMGTools.PMGCrossSectionTool('MyXSectionTool')
 
-    tool.readInfosFromDir(os.getenv('ROOTCOREBIN')+'/data/PMGTools/')
-    
-    #take a ttbar sample as example ( user should get this from the EventInfo of course )
+    fn = '/eos/atlas/atlascerngroupdisk/asg-calib/dev/PMGTools/PMGxsecDB_mc16.txt'
+    fn = PathResolver.FindCalibFile(fn)
+    vv = ROOT.std.vector('std::string')()
+    vv.push_back(fn)
+
+    tool.readInfosFromFiles(vv)
+
+    # take a ttbar sample as example ( users should get this from the EventInfo )
     sample_id = 410000
 
+    print '%d sample loaded' % tool.getLoadedDSIDs().size()
     print
-    print 'sample name     = ',tool.getSampleName(sample_id)
-    print 'xsection [pb]   = ',tool.getSampleXsection(sample_id)
-    print 'filter eff      = ',tool.getFilterEff(sample_id)
-    print 'branching ratio = ',tool.getBR(sample_id)
-    print 'k factor        = ',tool.getKfactor(sample_id)
+    print 'Sample dsid               = ', sample_id
+    print 'Sample name               = ', tool.getSampleName(sample_id)
+    print 'xsection [pb]             = ', tool.getSampleXsection(sample_id)
+    print 'filter eff                = ', tool.getFilterEff(sample_id)
+    print 'k factor                  = ', tool.getKfactor(sample_id)
+    print 'xsection uncertainty      = ', tool.getXsectionUncertainty(sample_id)
+    print 'xsection uncertainty up   = ', tool.getXsectionUncertaintyUP(sample_id)
+    print 'xsection uncertainty down = ', tool.getXsectionUncertaintyDOWN(sample_id)
+       
     print
 
 if __name__ == '__main__':
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/src/components/PMGTools_entries.cxx b/PhysicsAnalysis/AnalysisCommon/PMGTools/src/components/PMGTools_entries.cxx
index 11d64b3b214502c0077ce62006ec844809e3dda0..f7ce363ba052d72156fb7efeb01ffe06453cb1d8 100644
--- a/PhysicsAnalysis/AnalysisCommon/PMGTools/src/components/PMGTools_entries.cxx
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/src/components/PMGTools_entries.cxx
@@ -1,10 +1,14 @@
+
+#include "PMGTools/PMGCrossSectionTool.h"
+#include "PMGTools/PMGDecayProductsSelectionTool.h"
 #include "PMGTools/PMGSherpa22VJetsWeightTool.h"
 #include "PMGTools/PMGSherpaVjetsSysTool.h"
-#include "PMGTools/PMGCrossSectionTool.h"
+#include "PMGTools/PMGTruthWeightTool.h"
 
 using namespace PMGTools;
 
+DECLARE_COMPONENT( PMGCrossSectionTool )
+DECLARE_COMPONENT( PMGDecayProductsSelectionTool )
 DECLARE_COMPONENT( PMGSherpa22VJetsWeightTool )
 DECLARE_COMPONENT( PMGSherpaVjetsSysTool )
-DECLARE_COMPONENT( PMGCrossSectionTool )
-
+DECLARE_COMPONENT( PMGTruthWeightTool )
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/src/components/PMGTools_load.cxx b/PhysicsAnalysis/AnalysisCommon/PMGTools/src/components/PMGTools_load.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..cec1175f2c6a4fa2044b0eb24c6aa440c489386b
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/src/components/PMGTools_load.cxx
@@ -0,0 +1,3 @@
+ 
+#include "GaudiKernel/LoadFactoryEntries.h"
+LOAD_FACTORY_ENTRIES( PMGTools )
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/test/MyPMGApp.cxx b/PhysicsAnalysis/AnalysisCommon/PMGTools/test/MyPMGApp.cxx
index bcd170a2b58f05945351b142a31583cc88ce36bf..7398015984b708c78e708ffe948ed2c8bd41cbf9 100644
--- a/PhysicsAnalysis/AnalysisCommon/PMGTools/test/MyPMGApp.cxx
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/test/MyPMGApp.cxx
@@ -2,183 +2,175 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-#ifndef MYPACKAGE_MYAPP_H
-#define MYPACKAGE_MYAPP_H
-#ifndef ROOTCORE
+/// Example standalone executable using POOL to read an xAOD
+/// Tests several tools, showing example usage
 
-#include "AthAnalysisBaseComps/AthAnalysisHelper.h" //tool creation and configuration
+#ifndef PMGTOOLS_MYPMGAPP_H
+#define PMGTOOLS_MYPMGAPP_H
 
-
-#include "POOLRootAccess/TEvent.h" //event looping
-#include "GaudiKernel/ToolHandle.h" //for better working with tools
-
-// Tool include(s):
+// EDM includes
 #include "AsgTools/AnaToolHandle.h"
-
-#include "AsgTools/MessageCheck.h" //messaging
-using namespace asg::msgUserCode;  //messaging
-
-// added for truth studies
-#include "xAODJet/JetContainer.h"
-
+#include "AsgTools/MessageCheck.h"  // for messaging
+#include "POOLRootAccess/TEvent.h"  // event looping
+#include "xAODJet/JetContainer.h"   // for jet studies
+#include "GaudiKernel/ToolHandle.h" // for better working with tools
 #include "PATInterfaces/IWeightTool.h"
-#include "../Root/PMGSherpa22VJetsWeightTool.cxx"
-//#PMGSherpa22VJetsWeightTooll
 
-//ROOT includes
+// ROOT includes
 #include "TString.h"
 #include "TSystem.h"
 #include "TH1F.h"
 #include "TFile.h"
 
-int main( int argc, char* argv[] ) {
+// Local includes
+#include "PMGTools/PMGSherpa22VJetsWeightTool.h"
+#include "PMGTools/PMGTruthWeightTool.h"
+
+// For convenience messaging macros
+using namespace asg::msgUserCode;
 
 
+int main(int argc, char *argv[])
+{
+  ANA_CHECK_SET_TYPE (int); // makes ANA_CHECK return ints if exiting function
+
   // for access to everything including EVNT
-  IAppMgrUI* app = POOL::Init(); //important to do this first!
-  // just for xAOD file type access - improved performance due to 
+  IAppMgrUI *app = POOL::Init(); // important to do this first!
+  // just for xAOD file type access - improved performance due to
   // fast xAOD reading mechanism rather than generic POOL reading mechanism
-  //IAppMgrUI* app = POOL::Init("POOLRootAccess/basixAOD.opts");
-
-         
-   ANA_MSG_INFO("Making the tool");
-
-   // test the interface
-   asg::AnaToolHandle< IWeightTool > pmgTool( "PMGSherpa22VJetsWeightTool" );
-   ANA_CHECK( pmgTool.setProperty( "TruthJetContainer", "AntiKt4TruthWZJets" ) );  // default
-   ANA_CHECK( pmgTool.initialize() ); 
-
-   // can make the subtool directly or via this cast                                                                       
-   ANA_MSG_INFO("Making the sub tool");
-   //   PMGTools::PMGSherpa22VJetsWeightTool sherpatool;
-   //sherpatool.initialize();        
-   PMGTools::PMGSherpa22VJetsWeightTool* sherpatool = dynamic_cast<PMGTools::PMGSherpa22VJetsWeightTool*>(&*pmgTool);
-   // PMGCrossSectionTool*        xsectool   = dynamic_cast<PMGCrossSectionTool*>(&*pmgXsecTool);
-
-   // Open the input file:
-   TString fileName = "$ASG_TEST_FILE_MC";
-   if( argc < 2 ) {
-      ANA_MSG_WARNING( "No file name received, using $ASG_TEST_FILE_MC" );
-   } else {
-      fileName = argv[1]; //use the user provided file
-   }
-
-   ANA_MSG_INFO("Opening file: " << gSystem->ExpandPathName(fileName.Data()) );
-
-
-   //loop over input file with POOL 
-   POOL::TEvent evt;
-   evt.readFrom( fileName );
-
-   ANA_MSG_INFO("Opening file: " << evt.getEntries() );
-
-   // book some histograms
-   TH1F* h_njetTruth = new TH1F("jetmult_AntiKt4TruthJets","jetmult_AntiKt4TruthJets",10,-0.5,9.5);
-   TH1F* h_njetTruthWZ = new TH1F("jetmult_AntiKt4TruthWZJets","jetmult_AntiKt4TruthWZJets",10,-0.5,9.5);
-
-   //
-   TH1F* h_njetTruth_Tool = new TH1F("jetmult_AntiKt4TruthJets_Tool","jetmult_AntiKt4TruthJets_Tool",10,-0.5,9.5);
-   TH1F* h_njetTruthWZ_Tool = new TH1F("jetmult_AntiKt4TruthWZJets_Tool","jetmult_AntiKt4TruthWZJets_Tool",10,-0.5,9.5);
-
-
-   TFile* histfile=TFile::Open("hists.root","RECREATE");
-
-   bool debug=false;
-
-   for(int i=0;i < evt.getEntries(); i++) {
-   //   for(int i=0;i < 200; i++) {
-      if( evt.getEntry(i) < 0) { ANA_MSG_ERROR("Failed to read event " << i); continue; }
-
-      const xAOD::JetContainer* truthWZJets=0;
-      evt.retrieve(truthWZJets, "AntiKt4TruthWZJets" );
-
-      int nTruthWZJets20 = 0;
-      int nTruthWZJets30 = 0;
-      //loop over all AntiKtTruthWZ jets
-      for (unsigned i=0; i!=truthWZJets->size(); i++) {
-	const xAOD::Jet* truthjet = (*truthWZJets)[i];
-	//if(m_debug) {std::cout<<"Index "<<i<<" truthjet pointer = "<<truthjet<<std::endl;}
-	double Pt=truthjet->pt();
-	double AbsEta=fabs(truthjet->eta());
-	if (Pt>20000.0 && AbsEta<4.5) {nTruthWZJets20++;}
-	if (Pt>30000.0 && AbsEta<4.5) {nTruthWZJets30++;}
-      }//end loop over truth jets
-      if (debug) {
-	std::cout<<"nTruthWZJets20="<<nTruthWZJets20<<std::endl;
-	std::cout<<"nTruthWZJets30="<<nTruthWZJets30<<std::endl;
-      }
-      h_njetTruthWZ->Fill(nTruthWZJets20);
-
-      // same for AntiKt4TruthJets
-      const xAOD::JetContainer* truthJets=0;
-      evt.retrieve(truthJets, "AntiKt4TruthJets" );
-
-      int nTruthJets20 = 0;
-      //loop over all truth jets
-      for (unsigned i=0; i!=truthJets->size(); i++) {
-	const xAOD::Jet* truthjet = (*truthJets)[i];
-	double Pt=truthjet->pt();
-	double AbsEta=fabs(truthjet->eta());
-	if (Pt>20000.0 && AbsEta<4.5) {nTruthJets20++;}
-      }//end loop over truth jets
-      h_njetTruth->Fill(nTruthJets20);
-
-      // Now use the PMG tool directly over AntiKt4TruthWZJets
-      int njet=sherpatool->getSherpa22VJets_NJet("AntiKt4TruthWZJets"); 
-
-      if(debug)
-	std::cout<<"njets TruthWZJets "<< njet << std::endl;
-
-      h_njetTruthWZ_Tool->Fill(njet);
-
-      double reweight(0);
- 
-      int nuse=njet;
-      reweight=sherpatool->getSherpa22VJets_NJetCorrection(nuse) ;
-      if (debug)
-	std::cout<<"correction with njet input(check) "<< nuse << " " << reweight  << std::endl;
-
-      // check
-      reweight=sherpatool->getSherpa22VJets_NJetCorrection("AntiKt4TruthWZJets"); 
-      if (debug)
-	std::cout<<"correction with string "<< reweight << std::endl;
-
-
-      // and do again for TruthJets
-      njet=sherpatool->getSherpa22VJets_NJet("AntiKt4TruthJets"); 
-      if (debug)
-	std::cout<<"njets (TruthJets) "<< njet << std::endl;
-
-      h_njetTruth_Tool->Fill(njet);
-
-      nuse=njet;
-      reweight=sherpatool->getSherpa22VJets_NJetCorrection(nuse) ;
-      if(debug)
-	std::cout<<"correction with njet input (TruthJets) (check) "<< nuse << " " << reweight  << std::endl;
-
-      // check
-      reweight=sherpatool->getSherpa22VJets_NJetCorrection("AntiKt4TruthJets"); 
-      if(debug)
-	std::cout<<"correction with string (TruthJets) "<< reweight << std::endl;
-
-      // and test the interface itself
-      reweight=sherpatool->getWeight(); 
-      if(debug)
-	std::cout<<"correction from Interface" << reweight << std::endl;
-
-   }
-
-   app->finalize(); //trigger finalization of all services and tools created by the Gaudi Application
-
-   histfile->cd();
-   h_njetTruthWZ->Write(); 
-   h_njetTruthWZ_Tool->Write(); 
-   h_njetTruth->Write(); 
-   h_njetTruth_Tool->Write(); 
-   histfile->Close();
-
-   return 0;
+  // IAppMgrUI* app = POOL::Init("POOLRootAccess/basixAOD.opts");
+
+  // test the interface
+  ANA_MSG_INFO("Creating the PMGSherpa22VJetsWeightTool...");
+  asg::AnaToolHandle< IWeightTool > pmgTool("PMGTools::PMGSherpa22VJetsWeightTool/PMGSherpa22VJetsWeightTool");
+  ANA_CHECK(pmgTool.setProperty("TruthJetContainer", "AntiKt4TruthWZJets"));  // default
+  ANA_CHECK(pmgTool.initialize());
+  // can make the subtool directly or via this cast
+  ANA_MSG_INFO("Casting to PMGSherpa22VJetsWeightTool...");
+  PMGTools::PMGSherpa22VJetsWeightTool* sherpaTool = dynamic_cast<PMGTools::PMGSherpa22VJetsWeightTool*>(&*pmgTool);
+
+  // Create the truth weight tool:
+  // ... could create directly with
+  // ANA_MSG_INFO("Creating the PMGTruthWeightTool...");
+  // PMGTools::PMGTruthWeightTool truthWeightTool("PMGTruthWeightTool");
+  // ANA_CHECK(truthWeightTool.setProperty("OutputLevel", MSG::INFO));
+  // ANA_CHECK(truthWeightTool.sysInitialize()); // must call sysInitialize to get the callbacks registered properly for an AsgMetadataTool
+  // ... but better to do this through a ToolHandle
+  asg::AnaToolHandle< PMGTools::IPMGTruthWeightTool > truthWeightTool("PMGTools::PMGTruthWeightTool/PMGTruthWeightTool");
+  ANA_CHECK(truthWeightTool.initialize());
+
+  // Open the input file:
+  TString fileName = "$ASG_TEST_FILE_MC";
+  if (argc < 2) {
+    ANA_MSG_WARNING("No file name received, using $ASG_TEST_FILE_MC");
+  } else {
+    fileName = argv[1]; // use the user provided file
+  }
+  ANA_MSG_INFO("Opening file: " << gSystem->ExpandPathName(fileName.Data()));
+
+
+  // loop over input file with POOL
+  POOL::TEvent evt;
+  ANA_CHECK(evt.readFrom(fileName));
+  ANA_MSG_INFO("... with " << evt.getEntries() << " entries");
+
+  // book some histograms
+  TH1F *h_njetTruth = new TH1F("jetmult_AntiKt4TruthJets", "jetmult_AntiKt4TruthJets", 10, -0.5, 9.5);
+  TH1F *h_njetTruthWZ = new TH1F("jetmult_AntiKt4TruthWZJets", "jetmult_AntiKt4TruthWZJets", 10, -0.5, 9.5);
+  TH1F *h_njetTruth_Tool = new TH1F("jetmult_AntiKt4TruthJets_Tool", "jetmult_AntiKt4TruthJets_Tool", 10, -0.5, 9.5);
+  TH1F *h_njetTruthWZ_Tool = new TH1F("jetmult_AntiKt4TruthWZJets_Tool", "jetmult_AntiKt4TruthWZJets_Tool", 10, -0.5, 9.5);
+  TFile *histfile = TFile::Open("hists.root", "RECREATE");
+
+  bool debug = false;
+
+  for (int i = 0; i < evt.getEntries(); i++) {
+    if (evt.getEntry(i) < 0) { ANA_MSG_ERROR("Failed to read event " << i); continue; }
+
+    const xAOD::JetContainer *truthWZJets = 0;
+    ANA_CHECK(evt.retrieve(truthWZJets, "AntiKt4TruthWZJets"));
+    int nTruthWZJets20 = 0;
+    int nTruthWZJets30 = 0;
+
+    // loop over all AntiKtTruthWZ jets
+    for (unsigned i = 0; i != truthWZJets->size(); i++) {
+      const xAOD::Jet *truthjet = (*truthWZJets)[i];
+      // if(m_debug) { std::cout << "Index " << i << " truthjet pointer = " << truthjet << std::endl; }
+      double Pt = truthjet->pt();
+      double AbsEta = fabs(truthjet->eta());
+
+      if (Pt > 20000.0 && AbsEta < 4.5) {nTruthWZJets20++;}
+      if (Pt > 30000.0 && AbsEta < 4.5) {nTruthWZJets30++;}
+    } //end loop over truth jets
+
+    if (debug) {
+      std::cout << "nTruthWZJets20=" << nTruthWZJets20 << std::endl;
+      std::cout << "nTruthWZJets30=" << nTruthWZJets30 << std::endl;
+    }
+    h_njetTruthWZ->Fill(nTruthWZJets20);
+
+    // same for AntiKt4TruthJets
+    const xAOD::JetContainer *truthJets = 0;
+    ANA_CHECK(evt.retrieve(truthJets, "AntiKt4TruthJets"));
+    int nTruthJets20 = 0;
+
+    // loop over all truth jets
+    for (unsigned i = 0; i != truthJets->size(); i++) {
+      const xAOD::Jet *truthjet = (*truthJets)[i];
+      double Pt = truthjet->pt();
+      double AbsEta = fabs(truthjet->eta());
+
+      if (Pt > 20000.0 && AbsEta < 4.5) {nTruthJets20++;}
+    } // end loop over truth jets
+    h_njetTruth->Fill(nTruthJets20);
+
+    // Now use the PMG tool directly over AntiKt4TruthWZJets
+    int njet = sherpaTool->getSherpa22VJets_NJet("AntiKt4TruthWZJets");
+    if (debug) { std::cout << "njets TruthWZJets " << njet << std::endl; }
+    h_njetTruthWZ_Tool->Fill(njet);
+
+    double reweight(0);
+    int nuse = njet;
+    reweight = sherpaTool->getSherpa22VJets_NJetCorrection(nuse);
+    if (debug) { std::cout << "correction with njet input(check) " << nuse << " " << reweight  << std::endl; }
+
+    // check
+    reweight = sherpaTool->getSherpa22VJets_NJetCorrection("AntiKt4TruthWZJets");
+    if (debug) { std::cout << "correction with string " << reweight << std::endl; }
+
+    // and do again for TruthJets
+    njet = sherpaTool->getSherpa22VJets_NJet("AntiKt4TruthJets");
+    if (debug) { std::cout << "njets (TruthJets) " << njet << std::endl; }
+    h_njetTruth_Tool->Fill(njet);
+
+    nuse = njet;
+    reweight = sherpaTool->getSherpa22VJets_NJetCorrection(nuse) ;
+    if (debug) { std::cout << "correction with njet input (TruthJets) (check) " << nuse << " " << reweight  << std::endl; }
+
+    // check
+    reweight = sherpaTool->getSherpa22VJets_NJetCorrection("AntiKt4TruthJets");
+
+    if (debug) { std::cout << "correction with string (TruthJets) " << reweight << std::endl; }
+
+    // and test the interface itself
+    reweight = sherpaTool->getWeight();
+    if (debug) { std::cout << "correction from Interface" << reweight << std::endl; }
+
+    // Test the PMGTruthWeightTool interface
+    auto weightNames = truthWeightTool->getWeightNames();
+    ANA_MSG_INFO("Event #" << i << ": found " << weightNames.size() << " weights for this event");
+
+  }
+
+  ANA_CHECK(app->finalize()); // trigger finalization of all services and tools created by the Gaudi Application
+
+  histfile->cd();
+  h_njetTruthWZ->Write();
+  h_njetTruthWZ_Tool->Write();
+  h_njetTruth->Write();
+  h_njetTruth_Tool->Write();
+  histfile->Close();
+
+  return 0;
 }
 
-#endif // ROOTCORE  
-#endif //> !MYPACKAGE_MYAPP_H
+#endif //> !PMGTOOLS_MYPMGAPP_H
diff --git a/PhysicsAnalysis/AnalysisCommon/PMGTools/test/ut_PMGTruthWeightTool_test.cxx b/PhysicsAnalysis/AnalysisCommon/PMGTools/test/ut_PMGTruthWeightTool_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a4bfec7a5ca437e7596170ea065b1ed51408de9e
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/PMGTools/test/ut_PMGTruthWeightTool_test.cxx
@@ -0,0 +1,160 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+/// Example standalone executable using TEvent (from POOL or xAODRootAccess) to read an xAOD
+/// Tests the PMGTruthWeightTool, showing example usage
+
+/// @author: James Robinson
+
+// EDM include(s):
+#include "AsgTools/MessageCheck.h"
+#include "AsgTools/AnaToolHandle.h"
+
+// Project dependent include(s)
+#ifdef XAOD_STANDALONE
+#include "xAODRootAccess/Init.h"
+#include "xAODRootAccess/TEvent.h"
+#else
+#include "POOLRootAccess/TEvent.h"
+#endif
+
+// Local include(s):
+#include "PMGTools/PMGTruthWeightTool.h"
+#include "PMGTools/PMGSherpaVjetsSysTool.h"
+
+// ROOT include(s):
+#include "TFile.h"
+#include <chrono>
+
+using namespace asg::msgUserCode;  // messaging
+
+
+// Check for exceptions matching known text
+#define EXPECT_THROW(x,text) \
+{ std::string internalTestMessage; \
+  try { \
+    x; internalTestMessage = std::string ("expected statement ") + #x " to throw, but it didn't"; \
+  } catch (std::exception& e) { \
+    if (std::string(e.what()).find(std::string(text)) == std::string::npos) { \
+      internalTestMessage = std::string ("expected statement ") + #x " to throw message matching " + (text) + ", but actual message didn't match: " + e.what(); \
+    } \
+  } catch (...) { \
+    internalTestMessage = std::string ("statement ") + #x " threw an exception that didn't derive from std::exception"; \
+  } \
+  if (internalTestMessage.empty()) { ANA_MSG_INFO("Success!"); \
+  } else { ANA_MSG_FATAL(internalTestMessage); return -1; } \
+}
+
+// Check for functions returning false
+#define EXPECT_FALSE(x) \
+{ if (x == false) { ANA_MSG_INFO("Success!"); \
+  } else { ANA_MSG_FATAL("Expected " << #x << " to return false"); return -1; } \
+}
+
+
+int main(int argc, char *argv[])
+{
+  ANA_CHECK_SET_TYPE (int); // makes ANA_CHECK return ints if exiting function
+
+  // Initialise the application:
+#ifdef XAOD_STANDALONE
+  StatusCode::enableFailure();
+  ANA_CHECK(xAOD::Init());
+#else
+  IAppMgrUI *app = POOL::Init();
+#endif
+
+  // Use a default MC file for testing if none is provided
+  TString fileName = "$ASG_TEST_FILE_MC";
+  if (argc < 2) {
+    ANA_MSG_WARNING("No file name received, using ASG_TEST_FILE_MC");
+  } else {
+    fileName = argv[1]; // use the user provided file
+  }
+
+  // Initialise TEvent reading
+#ifdef XAOD_STANDALONE
+  std::unique_ptr<TFile> ptrFile(TFile::Open(fileName, "READ"));
+  xAOD::TEvent event(xAOD::TEvent::kClassAccess);
+  ANA_CHECK(event.readFrom(ptrFile.get()));
+#else
+  POOL::TEvent event(POOL::TEvent::kClassAccess);
+  ANA_CHECK(event.readFrom(fileName));
+#endif
+  ANA_MSG_INFO("Opened file: " << fileName);
+
+  // Hack to load the file
+  event.getEntries();
+
+  // Create the truth weight tool:
+  ANA_MSG_INFO("Creating PMGTruthWeightTool...");
+#ifdef XAOD_STANDALONE
+  asg::AnaToolHandle< PMGTools::IPMGTruthWeightTool > weightTool;
+  ASG_SET_ANA_TOOL_TYPE(weightTool, PMGTools::PMGTruthWeightTool);
+  weightTool.setName("PMGTruthWeightTool");
+  ANA_CHECK(weightTool.initialize());
+#else
+  asg::AnaToolHandle< PMGTools::IPMGTruthWeightTool > weightTool("PMGTools::PMGTruthWeightTool/PMGTruthWeightTool");
+  ANA_CHECK(weightTool.retrieve());
+#endif
+
+  // Loop over a few events:
+  ANA_MSG_INFO("Preparing to loop over events...");
+  const Long64_t nEntries = 5;
+  // double retrievalTimeNanoSeconds = 0;
+  for(Long64_t entry = 0; entry < nEntries; ++entry) {
+    if (event.getEntry(entry) < 0) { ANA_MSG_ERROR("Failed to read event " << entry); continue; }
+
+    auto weightNames = weightTool->getWeightNames();
+    ANA_MSG_INFO("Event #" << entry << ": found " << weightNames.size() << " weights for this event");
+
+    // Print out the first weight for every event
+    if (weightNames.size() > 1) {
+      static std::string weight_name_to_test = weightNames.at(1);
+      ANA_MSG_INFO("Event #" << entry << ": weight called '" << weight_name_to_test << "' = " << weightTool->getWeight(weight_name_to_test));
+    }
+
+    // Full print out for some of the events
+    if ((entry + 1) % 5 == 0) {
+      // Print out all weights and names
+      ANA_MSG_INFO("Printing all " << weightNames.size() << " weights for this event...");
+      unsigned int idx(0);
+      for (auto weight : weightNames) {
+        ANA_MSG_INFO("... weight " << idx++ << " has name \"" << weight << "\" and value " << weightTool->getWeight(weight));
+      }
+
+      // Give feedback about where we are
+      ANA_MSG_INFO("Processed " << entry + 1 << " / " << nEntries << " events");
+    }
+
+    // Check retrieval speed
+    ANA_MSG_INFO("Check average time taken to retrieve a weight");
+    if (entry == nEntries - 1) {
+      int nWeightCalls = 1000000;
+      static std::string weight_name_to_test = weightNames.back();
+      auto start = std::chrono::steady_clock::now();
+      for (int i = 0; i < nWeightCalls; ++i) {
+        weightTool->getWeight(weight_name_to_test);
+      }
+      auto elapsed = std::chrono::steady_clock::now() - start;
+      double retrievalTimeNanoSeconds = std::chrono::duration <double, std::nano> (elapsed).count() / nWeightCalls;
+      ANA_MSG_INFO("Retrieving " << nWeightCalls << " weights took " << retrievalTimeNanoSeconds << " ns per call");
+    }
+
+    // Check that retrieving a non-existent weight throws an exception
+    ANA_MSG_INFO("Check that retrieving a non-existent weight throws an exception");
+    EXPECT_THROW(weightTool->getWeight("non-existent-name"), "Weight \"non-existent-name\" could not be found");
+
+    // Check that asking for a non-existent weight returns false
+    ANA_MSG_INFO("Check that asking for a non-existent weight returns false");
+    EXPECT_FALSE(weightTool->hasWeight("non-existent-name"));
+  }
+
+  // trigger finalization of all services and tools created by the Gaudi Application
+#ifndef XAOD_STANDALONE
+  ANA_CHECK(app->finalize());
+#endif
+
+  return 0;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/PileupReweighting/CMakeLists.txt b/PhysicsAnalysis/AnalysisCommon/PileupReweighting/CMakeLists.txt
index 1ff87d1c910f88e2fdbf07f469e6240a6a36c20b..ac6b468dc9761671aacd68a30696dc7b890b4b9c 100644
--- a/PhysicsAnalysis/AnalysisCommon/PileupReweighting/CMakeLists.txt
+++ b/PhysicsAnalysis/AnalysisCommon/PileupReweighting/CMakeLists.txt
@@ -77,7 +77,5 @@ atlas_add_test( ut_PRWExample_test
    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
    LINK_LIBRARIES ${ROOT_LIBRARIES} PileupReweightingLib )
 
-# Install files from the package:
-atlas_install_python_modules( python/*.py )
 atlas_install_joboptions( share/*.py )
 atlas_install_data( share/*.root )
diff --git a/PhysicsAnalysis/AnalysisCommon/PileupReweighting/python/__init__.py b/PhysicsAnalysis/AnalysisCommon/PileupReweighting/python/__init__.py
deleted file mode 100644
index 74583d364ec2ca794156596c7254d9b234a940c6..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/AnalysisCommon/PileupReweighting/python/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
diff --git a/PhysicsAnalysis/AraTool/CMakeLists.txt b/PhysicsAnalysis/AraTool/CMakeLists.txt
index 036827f33bd9538d1b7cde465d900feea6bdf1f1..f16f0fc392c3691f8cb4c21d6d821b1736342c2b 100644
--- a/PhysicsAnalysis/AraTool/CMakeLists.txt
+++ b/PhysicsAnalysis/AraTool/CMakeLists.txt
@@ -20,6 +20,3 @@ atlas_add_library( AraTool
                    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
                    LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaBaseComps GaudiKernel )
 
-# Install files from the package:
-atlas_install_python_modules( python/*.py )
-
diff --git a/PhysicsAnalysis/AraTool/python/__init__.py b/PhysicsAnalysis/AraTool/python/__init__.py
deleted file mode 100644
index a03d63eb468f7d9b1439c6e7efa8ae3ce9b5665e..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/AraTool/python/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
-## @file __init__.py
-## Hook for the AraTool py-module
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkCore/python/SlimmingHelper.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkCore/python/SlimmingHelper.py
index 2a8ab150271ae87619d9fd492a82fe21d3b04084..c8948aa0df317c4fc4d9ce057cde7d7850e91522 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkCore/python/SlimmingHelper.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkCore/python/SlimmingHelper.py
@@ -414,10 +414,10 @@ class SlimmingHelper:
                         items.extend(AntiKt10TruthTrimmedPtFrac5SmallR20JetsCPContent)
                 elif collectionName=="AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets":
                         from DerivationFrameworkJetEtMiss.AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsCPContent import AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsCPContent
-                        if "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets" not in self:
+                        if "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets" not in self.AppendToDictionary:
                                 self.AppendToDictionary["AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets"]='xAOD::JetContainer'
                                 self.AppendToDictionary["AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsAux"]='xAOD::JetAuxContainer'
-                        if "AntiKt10TruthTrimmedPtFrac5SmallR20Jets" not in self:
+                        if "AntiKt10TruthTrimmedPtFrac5SmallR20Jets" not in self.AppendToDictionary:
                                 self.AppendToDictionary["AntiKt10TruthTrimmedPtFrac5SmallR20Jets"]="xAOD::JetContainer"
                                 self.AppendToDictionary["AntiKt10TruthTrimmedPtFrac5SmallR20JetsAux"]='xAOD::JetAuxContainer'
                         items.extend(AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsCPContent)
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkExamples/CMakeLists.txt b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkExamples/CMakeLists.txt
index 9b9132e667ce12b826fa2ce01b9990ea01490af7..a04d15570bf17eda7307bbfaf53bd7f291199882 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkExamples/CMakeLists.txt
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkExamples/CMakeLists.txt
@@ -27,6 +27,5 @@ atlas_add_component( DerivationFrameworkExamples
                      LINK_LIBRARIES AthenaBaseComps xAODMuon GaudiKernel AthenaKernel xAODTracking DerivationFrameworkExamplesLib )
 
 # Install files from the package:
-atlas_install_python_modules( python/*.py )
 atlas_install_joboptions( share/*.py )
 
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkExamples/python/__init__.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkExamples/python/__init__.py
deleted file mode 100644
index 74583d364ec2ca794156596c7254d9b234a940c6..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkExamples/python/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/CMakeLists.txt b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/CMakeLists.txt
index 6e67ef5583b301f3dfea4e7801fb00fd253e1f97..f63656e5bce85f9440f0b6fd4ef6a46b603fa5ee 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/CMakeLists.txt
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/CMakeLists.txt
@@ -18,11 +18,18 @@ atlas_depends_on_subdirs( PUBLIC
                           Event/xAOD/xAODTrigger
                           Event/xAOD/xAODTruth
                           Event/xAOD/xAODCaloEvent
+			  InnerDetector/InDetRecTools/InDetTrackSelectionTool
+			  InnerDetector/InDetRecTools/TrackVertexAssociationTool
+			  PhysicsAnalysis/AnalysisCommon/ParticleJetTools
                           PhysicsAnalysis/DerivationFramework/DerivationFrameworkInterfaces
-                          PhysicsAnalysis/JetTagging/JetTagPerformanceCalibration/xAODBTaggingEfficiency
+			  PhysicsAnalysis/Interfaces/JetAnalysisInterfaces
+			  PhysicsAnalysis/Interfaces/FTagAnalysisInterfaces
                           Reconstruction/Jet/JetInterface
-                          Reconstruction/PFlow/PFlowUtils
-                          Tools/PathResolver )
+			  Reconstruction/Jet/JetMomentTools
+			  Reconstruction/Jet/JetJvtEfficiency
+			  Reconstruction/PFlow/PFlowUtils
+                          Tools/PathResolver 
+			  Trigger/TrigAnalysis/TrigAnalysisInterfaces )
 
 # External dependencies:
 find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
@@ -33,12 +40,12 @@ atlas_add_library( DerivationFrameworkJetEtMissLib
                    NO_PUBLIC_HEADERS
                    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
                    LINK_LIBRARIES ${ROOT_LIBRARIES} GaudiKernel
-                   PRIVATE_LINK_LIBRARIES AthenaBaseComps xAODCore xAODJet xAODPFlow xAODTracking xAODTrigger xAODTruth JetInterface PathResolver PFlowUtilsLib xAODBTaggingEfficiencyLib )
+                   PRIVATE_LINK_LIBRARIES AthenaBaseComps xAODCore xAODJet xAODPFlow xAODTracking xAODTrigger xAODTruth JetInterface PathResolver PFlowUtilsLib ParticleJetToolsLib FTagAnalysisInterfacesLib JetAnalysisInterfacesLib JetMomentToolsLib InDetTrackSelectionToolLib TrackVertexAssociationToolLib JetJvtEfficiencyLib)
 
 atlas_add_component( DerivationFrameworkJetEtMiss
                      src/components/*.cxx
                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} GaudiKernel AthenaBaseComps xAODCore xAODJet xAODPFlow xAODTracking xAODTrigger xAODTruth JetInterface PathResolver PFlowUtilsLib DerivationFrameworkJetEtMissLib )
+                     LINK_LIBRARIES ${ROOT_LIBRARIES} GaudiKernel AthenaBaseComps xAODCore xAODJet xAODPFlow xAODTracking xAODTrigger xAODTruth JetInterface PathResolver PFlowUtilsLib DerivationFrameworkJetEtMissLib JetJvtEfficiencyLib)
 
 # Install files from the package:
 atlas_install_python_modules( python/*.py )
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10EMPFlowTrimmedPtFrac5SmallR20JetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10EMPFlowTrimmedPtFrac5SmallR20JetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..75733a6ec109b0974693adb2a8d1e94893777ddc
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10EMPFlowTrimmedPtFrac5SmallR20JetsCPContent.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10EMPFlowTrimmedPtFrac5SmallR20JetsCPContent = [
+"AntiKt10EMPFlowTrimmedPtFrac5SmallR20Jets",
+"AntiKt10EMPFlowTrimmedPtFrac5SmallR20JetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10EMPFlowTrimmedPtFrac5SmallR20JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10EMPFlowTrimmedPtFrac5SmallR20JetsAux.NTrimSubjets.Parent.DetectorEta.DetectorY",
+"AntiKt10EMPFlowTrimmedPtFrac5SmallR20JetsAux.R10TruthLabel_R21Consolidated",
+"AntiKt10EMPFlowJets",
+"AntiKt10EMPFlowJetsAux.NumTrkPt500",
+"AntiKt10TruthTrimmedPtFrac5SmallR20Jets.pt.eta.phi.m.ECF1.ECF2.ECF3.Tau2_wta.Tau3_wta.Qw.GhostBHadronsFinalCount",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10LCTopoCSSKSoftDropBeta100Zcut10JetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10LCTopoCSSKSoftDropBeta100Zcut10JetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..71891ba2dbd580616c99eca5963d51d0484b5817
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10LCTopoCSSKSoftDropBeta100Zcut10JetsCPContent.py
@@ -0,0 +1,9 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10LCTopoCSSKSoftDropBeta100Zcut10JetsCPContent = [
+"AntiKt10LCTopoCSSKSoftDropBeta100Zcut10Jets",
+"AntiKt10LCTopoCSSKSoftDropBeta100Zcut10JetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10LCTopoCSSKSoftDropBeta100Zcut10JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10LCTopoCSSKSoftDropBeta100Zcut10JetsAux.Parent.DetectorEta.DetectorY",
+"AntiKt10LCTopoCSSKSoftDropBeta100Zcut10JetsAux.R10TruthLabel_R21Consolidated",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10LCTopoJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10LCTopoJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..eda16b9657ee3c4a6e65b936403d0958eff2dc7b
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10LCTopoJetsCPContent.py
@@ -0,0 +1,10 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10LCTopoJetsCPContent = [
+"AntiKt10LCTopoJets",
+"AntiKt10LCTopoJetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10LCTopoJetsAux.PartonTruthLabelID.DetectorEta.DetectorY",
+"AntiKt10LCTopoJetsAux.GhostBHadronsFinalCount.GhostHBosonsCount.GhostTQuarksFinalCount.GhostTrack.GhostWBosonsCount.GhostZBosonsCount",
+"AntiKt10LCTopoJetsAux.GhostVR30Rmax4Rmin02TrackJet.GhostVR30Rmax4Rmin02TrackJetGhostTag.GhostVR30Rmax4Rmin02TrackJet_BTagging201810.GhostVR30Rmax4Rmin02TrackJet_BTagging201810GhostTag.GhostVR30Rmax4Rmin02TrackJet_BTagging201903",
+"AntiKt10LCTopoJetsAux.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.NumTrkPt500.SumPtTrkPt500",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsCPContent.py
index d343d282ffe51bd2477ece73320355291a6735f8..2a768d3aacf55aa120e181cc61063174bc24749b 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsCPContent.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsCPContent.py
@@ -1,9 +1,13 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsCPContent = [
 "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets",
-"AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsAux.pt.eta.phi.m.constituentLinks.ConstituentScale.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.InputType.AlgorithmType.SizeParameter.TransformType.RClus.PtFrac.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.NTrimSubjets.Parent.GhostAntiKt2TrackJet.TrackSumPt.TrackSumMass",
+"AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsAux.NTrimSubjets.Parent.TrackSumPt.TrackSumMass.DetectorEta.DetectorY",
+"AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsAux.GhostAntiKt2TrackJet.GhostBHadronsFinalCount",
+"AntiKt10LCTopoTrimmedPtFrac5SmallR20JetsAux.R10TruthLabel_R21Consolidated",
 "AntiKt10LCTopoJets",
-"AntiKt10LCTopoJetsAux.GhostAntiKt2TrackJet",
-"AntiKt10TruthTrimmedPtFrac5SmallR20Jets.pt.eta.phi.m.ECF1.ECF2.ECF3.Tau2_wta.Tau3_wta"
+"AntiKt10LCTopoJetsAux.GhostAntiKt2TrackJet.GhostVR30Rmax4Rmin02TrackJet.GhostVR30Rmax4Rmin02TrackJetGhostTag.GhostVR30Rmax4Rmin02TrackJet_BTagging201810.GhostVR30Rmax4Rmin02TrackJet_BTagging201810GhostTag.GhostVR30Rmax4Rmin02TrackJet_BTagging201903.NumTrkPt500",
+"AntiKt10TruthTrimmedPtFrac5SmallR20Jets.pt.eta.phi.m.ECF1.ECF2.ECF3.Tau2_wta.Tau3_wta.Qw.GhostBHadronsFinalCount",
 ]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TrackCaloClusterJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TrackCaloClusterJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..f4a03191ba443eee97e62b497d0b4b0942d05f49
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TrackCaloClusterJetsCPContent.py
@@ -0,0 +1,10 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10TrackCaloClusterJetsCPContent = [
+"AntiKt10TrackCaloClusterJets",
+"AntiKt10TrackCaloClusterJetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10TrackCaloClusterJetsAux.DetectorEta.DetectorY",
+"AntiKt10TrackCaloClusterJetsAux.GhostBHadronsFinalCount.GhostHBosonsCount.GhostTQuarksFinalCount.GhostTrack.GhostWBosonsCount.GhostZBosonsCount",
+"AntiKt10TrackCaloClusterJetsAux.GhostVR30Rmax4Rmin02TrackJet.GhostVR30Rmax4Rmin02TrackJetGhostTag.GhostVR30Rmax4Rmin02TrackJet_BTagging201810.GhostVR30Rmax4Rmin02TrackJet_BTagging201810GhostTag.GhostVR30Rmax4Rmin02TrackJet_BTagging201903",
+"AntiKt10TrackCaloClusterJetsAux.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.NumTrkPt500.SumPtTrkPt500",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20JetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20JetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..fbcfe42a53fbf4c6676537c000a61416de27115c
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20JetsCPContent.py
@@ -0,0 +1,13 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20JetsCPContent = [
+"AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20Jets",
+"AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20JetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20JetsAux.NTrimSubjets.Parent.DetectorEta.DetectorY",
+"AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20JetsAux.GhostAntiKt2TrackJet.GhostBHadronsFinalCount",
+"AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20JetsAux.R10TruthLabel_R21Consolidated",
+"AntiKt10TrackCaloClusterJets",
+"AntiKt10TrackCaloClusterJetsAux.GhostAntiKt2TrackJet.GhostVR30Rmax4Rmin02TrackJet.NumTrkPt500",
+"AntiKt10TruthTrimmedPtFrac5SmallR20Jets.pt.eta.phi.m.ECF1.ECF2.ECF3.Tau2_wta.Tau3_wta.Qw.GhostBHadronsFinalCount",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthBottomUpSoftDropBeta100Zcut5JetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthBottomUpSoftDropBeta100Zcut5JetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..0e7aacd46df216c56a781fd165f5a52c8d1219af
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthBottomUpSoftDropBeta100Zcut5JetsCPContent.py
@@ -0,0 +1,9 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10TruthBottomUpSoftDropBeta100Zcut5JetsCPContent = [
+"AntiKt10TruthBottomUpSoftDropBeta100Zcut5Jets",
+"AntiKt10TruthBottomUpSoftDropBeta100Zcut5JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10TruthBottomUpSoftDropBeta100Zcut5JetsAux.Parent.GhostBHadronsFinalCount",
+"AntiKt10TruthJets",
+"AntiKt10TruthJetsAux.GhostBHadronsFinalCount",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..698abaf7c970b02d9943422d2c542c555b404b75
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthJetsCPContent.py
@@ -0,0 +1,8 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10TruthJetsCPContent = [
+"AntiKt10TruthJets",
+"AntiKt10TruthJetsAux.PartonTruthLabelID",
+"AntiKt10TruthJetsAux.GhostBHadronsFinal.GhostBHadronsFinalCount.GhostTQuarksFinal.GhostTQuarksFinalCount",
+"AntiKt10TruthJetsAux.GhostHBosons.GhostHBosonsCount.GhostWBosons.GhostWBosonsCount.GhostZBosons.GhostZBosonsCount",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthRecursiveSoftDropBeta100Zcut5NinfJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthRecursiveSoftDropBeta100Zcut5NinfJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..6fe73478b928accebdf31556cae73b45c78ed28f
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthRecursiveSoftDropBeta100Zcut5NinfJetsCPContent.py
@@ -0,0 +1,9 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10TruthRecursiveSoftDropBeta100Zcut5NinfJetsCPContent = [
+"AntiKt10TruthRecursiveSoftDropBeta100Zcut5NinfJets",
+"AntiKt10TruthRecursiveSoftDropBeta100Zcut5NinfJetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10TruthRecursiveSoftDropBeta100Zcut5NinfJetsAux.Parent.GhostBHadronsFinalCount",
+"AntiKt10TruthJets",
+"AntiKt10TruthJetsAux.GhostBHadronsFinalCount",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthSoftDropBeta100Zcut10JetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthSoftDropBeta100Zcut10JetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..a91eebe6127ec3dd202a5fbb4d983df1b0540ba8
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthSoftDropBeta100Zcut10JetsCPContent.py
@@ -0,0 +1,9 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10TruthSoftDropBeta100Zcut10JetsCPContent = [
+"AntiKt10TruthSoftDropBeta100Zcut10Jets",
+"AntiKt10TruthSoftDropBeta100Zcut10JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10TruthSoftDropBeta100Zcut10JetsAux.Parent.GhostBHadronsFinalCount",
+"AntiKt10TruthJets",
+"AntiKt10TruthJetsAux.GhostBHadronsFinalCount",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthTrimmedPtFrac5SmallR20JetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthTrimmedPtFrac5SmallR20JetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..c406b0dcd13f41c876592de9ece069174e7079be
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthTrimmedPtFrac5SmallR20JetsCPContent.py
@@ -0,0 +1,10 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10TruthTrimmedPtFrac5SmallR20JetsCPContent = [
+"AntiKt10TruthTrimmedPtFrac5SmallR20Jets",
+"AntiKt10TruthTrimmedPtFrac5SmallR20JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10TruthTrimmedPtFrac5SmallR20JetsAux.NTrimSubjets.Parent.GhostBHadronsFinalCount",
+"AntiKt10TruthTrimmedPtFrac5SmallR20JetsAux.R10TruthLabel_R21Consolidated",
+"AntiKt10TruthJets",
+"AntiKt10TruthJetsAux.GhostBHadronsFinalCount",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthWZJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthWZJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..f7aaaf3bf56c349af3e460ade984f20f80553d6d
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10TruthWZJetsCPContent.py
@@ -0,0 +1,7 @@
+# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10TruthWZJetsCPContent = [
+"AntiKt10TruthWZJets",
+"AntiKt10TruthWZJetsAux.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor"
+]
+
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCHSJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCHSJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..72c8f9bff136ed3b6a3e880f7931342318937534
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCHSJetsCPContent.py
@@ -0,0 +1,10 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10UFOCHSJetsCPContent = [
+"AntiKt10UFOCHSJets",
+"AntiKt10UFOCHSJetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10UFOCHSJetsAux.PartonTruthLabelID.DetectorEta.DetectorY",
+"AntiKt10UFOCHSJetsAux.GhostBHadronsFinalCount.GhostHBosonsCount.GhostTQuarksFinalCount.GhostTrack.GhostWBosonsCount.GhostZBosonsCount",
+"AntiKt10UFOCHSJetsAux.GhostVR30Rmax4Rmin02TrackJet.GhostVR30Rmax4Rmin02TrackJetGhostTag.GhostVR30Rmax4Rmin02TrackJet_BTagging201810.GhostVR30Rmax4Rmin02TrackJet_BTagging201810GhostTag.GhostVR30Rmax4Rmin02TrackJet_BTagging201903",
+"AntiKt10UFOCHSJetsAux.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.NumTrkPt500.SumPtTrkPt500",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCHSSoftDropBeta100Zcut10JetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCHSSoftDropBeta100Zcut10JetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..fffec50d0a8b3a79015aa5e4e757bd2bb00588e6
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCHSSoftDropBeta100Zcut10JetsCPContent.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10UFOCHSSoftDropBeta100Zcut10JetsCPContent = [
+"AntiKt10UFOCHSSoftDropBeta100Zcut10Jets",
+"AntiKt10UFOCHSSoftDropBeta100Zcut10JetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10UFOCHSSoftDropBeta100Zcut10JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10UFOCHSSoftDropBeta100Zcut10JetsAux.Parent.DetectorEta.DetectorY",
+"AntiKt10UFOCHSSoftDropBeta100Zcut10JetsAux.R10TruthLabel_R21Consolidated",
+"AntiKt10UFOCHSJets",
+"AntiKt10UFOCHSJetsAux.NumTrkPt500",
+"AntiKt10TruthSoftDropBeta100Zcut10Jets.pt.eta.phi.m.ECF1.ECF2.ECF3.Tau2_wta.Tau3_wta.Qw.GhostBHadronsFinalCount",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCHSTrimmedPtFrac5SmallR20JetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCHSTrimmedPtFrac5SmallR20JetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..d1f9a68e357f20eefa342c2f7e66b77102e793bd
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCHSTrimmedPtFrac5SmallR20JetsCPContent.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10UFOCHSTrimmedPtFrac5SmallR20JetsCPContent = [
+"AntiKt10UFOCHSTrimmedPtFrac5SmallR20Jets",
+"AntiKt10UFOCHSTrimmedPtFrac5SmallR20JetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10UFOCHSTrimmedPtFrac5SmallR20JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10UFOCHSTrimmedPtFrac5SmallR20JetsAux.NTrimSubjets.Parent.DetectorEta.DetectorY",
+"AntiKt10UFOCHSTrimmedPtFrac5SmallR20JetsAux.R10TruthLabel_R21Consolidated",
+"AntiKt10UFOCHSJets",
+"AntiKt10UFOCHSJetsAux.NumTrkPt500",
+"AntiKt10TruthTrimmedPtFrac5SmallR20Jets.pt.eta.phi.m.ECF1.ECF2.ECF3.Tau2_wta.Tau3_wta.Qw.GhostBHadronsFinalCount",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5JetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5JetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..027cd8ee0cc52645aa09b0b71e90de1b3c8ceb96
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5JetsCPContent.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5JetsCPContent = [
+"AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5Jets",
+"AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5JetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5JetsAux.Parent.DetectorEta.DetectorY",
+"AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5JetsAux.R10TruthLabel_R21Consolidated",
+"AntiKt10UFOCSSKJets",
+"AntiKt10UFOCSSKJetsAux.NumTrkPt500",
+"AntiKt10TruthBottomUpSoftDropBeta100Zcut5Jets.pt.eta.phi.m.ECF1.ECF2.ECF3.Tau2_wta.Tau3_wta.Qw.GhostBHadronsFinalCount",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..1cb9c1ad2e1b229177b16a21863eae03b72241d2
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKJetsCPContent.py
@@ -0,0 +1,10 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10UFOCSSKJetsCPContent = [
+"AntiKt10UFOCSSKJets",
+"AntiKt10UFOCSSKJetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10UFOCSSKJetsAux.PartonTruthLabelID.DetectorEta.DetectorY",
+"AntiKt10UFOCSSKJetsAux.GhostBHadronsFinalCount.GhostHBosonsCount.GhostTQuarksFinalCount.GhostTrack.GhostWBosonsCount.GhostZBosonsCount",
+"AntiKt10UFOCSSKJetsAux.GhostVR30Rmax4Rmin02TrackJet.GhostVR30Rmax4Rmin02TrackJetGhostTag.GhostVR30Rmax4Rmin02TrackJet_BTagging201810.GhostVR30Rmax4Rmin02TrackJet_BTagging201810GhostTag.GhostVR30Rmax4Rmin02TrackJet_BTagging201903",
+"AntiKt10UFOCSSKJetsAux.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.NumTrkPt500.SumPtTrkPt500",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..05af8c71cd1670c770038dd91c81d348f854bee8
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJetsCPContent.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJetsCPContent = [
+"AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJets",
+"AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJetsAux.Parent.DetectorEta.DetectorY",
+"AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJetsAux.R10TruthLabel_R21Consolidated",
+"AntiKt10UFOCSSKJets",
+"AntiKt10UFOCSSKJetsAux.NumTrkPt500",
+"AntiKt10TruthRecursiveSoftDropBeta100Zcut5NinfJets.pt.eta.phi.m.ECF1.ECF2.ECF3.Tau2_wta.Tau3_wta.Qw.GhostBHadronsFinalCount",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..fe124c35e316f50bb6dfd9d90d4aba5b0242a95b
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsCPContent.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsCPContent = [
+"AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets",
+"AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsAux.Parent.DetectorEta.DetectorY",
+"AntiKt10UFOCSSKSoftDropBeta100Zcut10JetsAux.R10TruthLabel_R21Consolidated",
+"AntiKt10UFOCSSKJets",
+"AntiKt10UFOCSSKJetsAux.NumTrkPt500",
+"AntiKt10TruthSoftDropBeta100Zcut10Jets.pt.eta.phi.m.ECF1.ECF2.ECF3.Tau2_wta.Tau3_wta.Qw.GhostBHadronsFinalCount",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKTrimmedPtFrac5SmallR20JetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKTrimmedPtFrac5SmallR20JetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..fe78c2a57b489fd9d2e90a467682811607fa44e7
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt10UFOCSSKTrimmedPtFrac5SmallR20JetsCPContent.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+AntiKt10UFOCSSKTrimmedPtFrac5SmallR20JetsCPContent = [
+"AntiKt10UFOCSSKTrimmedPtFrac5SmallR20Jets",
+"AntiKt10UFOCSSKTrimmedPtFrac5SmallR20JetsAux.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m",
+"AntiKt10UFOCSSKTrimmedPtFrac5SmallR20JetsAux.ECF1.ECF2.ECF3.Tau1_wta.Tau2_wta.Tau3_wta.Split12.Split23.Qw.PlanarFlow.FoxWolfram2.FoxWolfram0.Angularity.Aplanarity.KtDR.ZCut12",
+"AntiKt10UFOCSSKTrimmedPtFrac5SmallR20JetsAux.NTrimSubjets.Parent.DetectorEta.DetectorY",
+"AntiKt10UFOCSSKTrimmedPtFrac5SmallR20JetsAux.R10TruthLabel_R21Consolidated",
+"AntiKt10UFOCSSKJets",
+"AntiKt10UFOCSSKJetsAux.NumTrkPt500",
+"AntiKt10TruthTrimmedPtFrac5SmallR20Jets.pt.eta.phi.m.ECF1.ECF2.ECF3.Tau2_wta.Tau3_wta.Qw.GhostBHadronsFinalCount",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt2LCTopoJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt2LCTopoJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..0cfdc2899869749953553a9c21741bd4fb7e112e
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt2LCTopoJetsCPContent.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt2LCTopoJetsCPContent = [
+"Kt4LCTopoOriginEventShape",
+"Kt4LCTopoOriginEventShapeAux.Density",
+"AntiKt2LCTopoJets",
+"AntiKt2LCTopoJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.NumTrkPt500.SumPtTrkPt500.EnergyPerSampling.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.DetectorEta.DetectorY.FracSamplingMax.FracSamplingMaxIndex.GhostTrack.Jvt.JVFCorr.JvtRpt.NumTrkPt1000.TrackWidthPt1000.GhostMuonSegmentCount.PartonTruthLabelID.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor.Timing",
+"MET_Track",
+"MET_TrackAux.name.mpx.mpy",
+"PrimaryVertices",
+"PrimaryVerticesAux.vertexType"
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt2TruthJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt2TruthJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..68a6e7236bef65ffb77944ff6e417533911895e8
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt2TruthJetsCPContent.py
@@ -0,0 +1,7 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt2TruthJetsCPContent = [
+"AntiKt2TruthJets",
+"AntiKt2TruthJetsAux.pt.eta.phi.m.PartonTruthLabelID.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor"
+]
+
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt3LCTopoJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt3LCTopoJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..83dc6f81de641353ca6fb897ddddfa2c461f2bea
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt3LCTopoJetsCPContent.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt3LCTopoJetsCPContent = [
+"Kt4LCTopoOriginEventShape",
+"Kt4LCTopoOriginEventShapeAux.Density",
+"AntiKt3LCTopoJets",
+"AntiKt3LCTopoJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.NumTrkPt500.SumPtTrkPt500.EnergyPerSampling.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.DetectorEta.DetectorY.FracSamplingMax.FracSamplingMaxIndex.GhostTrack.Jvt.JVFCorr.JvtRpt.NumTrkPt1000.TrackWidthPt1000.GhostMuonSegmentCount.PartonTruthLabelID.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor.Timing",
+"MET_Track",
+"MET_TrackAux.name.mpx.mpy",
+"PrimaryVertices",
+"PrimaryVerticesAux.vertexType"
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4EMPFlowJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4EMPFlowJetsCPContent.py
index 5f62fae4d0356e3653dcbedbb8843bf6dc3be304..0da5fdcb3a28c4fa26366eaf5f1cd91c68d2aacf 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4EMPFlowJetsCPContent.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4EMPFlowJetsCPContent.py
@@ -4,11 +4,9 @@ AntiKt4EMPFlowJetsCPContent = [
 "Kt4EMPFlowEventShape",
 "Kt4EMPFlowEventShapeAux.Density",
 "AntiKt4EMPFlowJets",
-"AntiKt4EMPFlowJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.NumTrkPt500.SumPtTrkPt500.NumChargedPFOPt500.SumPtChargedPFOPt500.EnergyPerSampling.EMFrac.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.AverageLArQF.DetectorEta.FracSamplingMax.FracSamplingMaxIndex.GhostTrack.HECFrac.HECQuality.JetPileupScaleMomentum_eta.JetPileupScaleMomentum_m.JetPileupScaleMomentum_phi.JetPileupScaleMomentum_pt.Jvt.JVFCorr.JvtRpt.LArQuality.NegativeE.NumTrkPt1000.NumChargedPFOPt1000.OriginCorrected.PileupCorrected.TrackWidthPt1000.ChargedPFOWidthPt1000.GhostMuonSegment.GhostMuonSegmentCount.JetOriginConstitScaleMomentum_eta.JetOriginConstitScaleMomentum_m.JetOriginConstitScaleMomentum_phi.JetOriginConstitScaleMomentum_pt",
+"AntiKt4EMPFlowJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.NumTrkPt500.SumPtTrkPt500.NumChargedPFOPt500.SumPtChargedPFOPt500.EnergyPerSampling.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.DetectorEta.DetectorY.FracSamplingMax.FracSamplingMaxIndex.GhostTrack.Jvt.JVFCorr.JvtRpt.NumTrkPt1000.NumChargedPFOPt1000.TrackWidthPt1000.ChargedPFOWidthPt1000.GhostMuonSegmentCount.PartonTruthLabelID.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor.Timing.DFCommonJets_fJvt",
 "MET_Track",
 "MET_TrackAux.name.mpx.mpy",
-"MuonSegments",
-"MuonSegmentsAux.",
 "PrimaryVertices",
 "PrimaryVerticesAux.vertexType" 
 ]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4EMTopoJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4EMTopoJetsCPContent.py
index 8afc08bf1d07492b48abf29d46fa5ed79601dcee..ab944beb88551fd15d4bcb4a2d4bf20e2eeb2789 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4EMTopoJetsCPContent.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4EMTopoJetsCPContent.py
@@ -1,14 +1,14 @@
 # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 
+AntiKt4EMTopoJetsCPContentAux = "AntiKt4EMTopoJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.NumTrkPt500.SumPtTrkPt500.EnergyPerSampling.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.DetectorEta.DetectorY.FracSamplingMax.FracSamplingMaxIndex.GhostTrack.Jvt.JVFCorr.JvtRpt.NumTrkPt1000.TrackWidthPt1000.GhostMuonSegmentCount.PartonTruthLabelID.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor.DFCommonJets_jetClean_LooseBad.DFCommonJets_jetClean_TightBad.Timing.DFCommonJets_MVfJVT"
+
 AntiKt4EMTopoJetsCPContent = [
 "Kt4EMTopoOriginEventShape",
 "Kt4EMTopoOriginEventShapeAux.Density",
 "AntiKt4EMTopoJets",
-"AntiKt4EMTopoJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.NumTrkPt500.SumPtTrkPt500.EnergyPerSampling.EMFrac.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.AverageLArQF.DetectorEta.FracSamplingMax.FracSamplingMaxIndex.GhostTrack.HECFrac.HECQuality.JetPileupScaleMomentum_eta.JetPileupScaleMomentum_m.JetPileupScaleMomentum_phi.JetPileupScaleMomentum_pt.Jvt.JVFCorr.JvtRpt.LArQuality.NegativeE.NumTrkPt1000.OriginCorrected.PileupCorrected.TrackWidthPt1000.GhostMuonSegment.GhostMuonSegmentCount.JetOriginConstitScaleMomentum_eta.JetOriginConstitScaleMomentum_m.JetOriginConstitScaleMomentum_phi.JetOriginConstitScaleMomentum_pt",
+AntiKt4EMTopoJetsCPContentAux,
 "MET_Track",
 "MET_TrackAux.name.mpx.mpy",
-"MuonSegments",
-"MuonSegmentsAux.",
 "PrimaryVertices",
 "PrimaryVerticesAux.vertexType"
 ]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4LCTopoJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4LCTopoJetsCPContent.py
index 1cbdc3c0794f848d11b27064df32d1f105a030d9..b93530571bf03d802250d76e572d8acb1ba070ca 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4LCTopoJetsCPContent.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4LCTopoJetsCPContent.py
@@ -4,11 +4,9 @@ AntiKt4LCTopoJetsCPContent = [
 "Kt4LCTopoOriginEventShape",
 "Kt4LCTopoOriginEventShapeAux.Density",
 "AntiKt4LCTopoJets",
-"AntiKt4LCTopoJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.NumTrkPt500.SumPtTrkPt500.EnergyPerSampling.EMFrac.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.AverageLArQF.DetectorEta.FracSamplingMax.FracSamplingMaxIndex.GhostTrack.HECFrac.HECQuality.JetPileupScaleMomentum_eta.JetPileupScaleMomentum_m.JetPileupScaleMomentum_phi.JetPileupScaleMomentum_pt.Jvt.JVFCorr.JvtRpt.LArQuality.NegativeE.NumTrkPt1000.OriginCorrected.PileupCorrected.TrackWidthPt1000.GhostMuonSegment.GhostMuonSegmentCount.JetOriginConstitScaleMomentum_eta.JetOriginConstitScaleMomentum_m.JetOriginConstitScaleMomentum_phi.JetOriginConstitScaleMomentum_pt",
+"AntiKt4LCTopoJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.NumTrkPt500.SumPtTrkPt500.EnergyPerSampling.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.DetectorEta.DetectorY.FracSamplingMax.FracSamplingMaxIndex.GhostTrack.Jvt.JVFCorr.JvtRpt.NumTrkPt1000.TrackWidthPt1000.GhostMuonSegmentCount.PartonTruthLabelID.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor.Timing",
 "MET_Track",
 "MET_TrackAux.name.mpx.mpy",
-"MuonSegments",
-"MuonSegmentsAux.",
 "PrimaryVertices",
 "PrimaryVerticesAux.vertexType"
 ]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4TruthDressedWZJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4TruthDressedWZJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..9531c437c4d1b9d923016ce96630167ad7072c65
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4TruthDressedWZJetsCPContent.py
@@ -0,0 +1,7 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt4TruthDressedWZJetsCPContent = [
+"AntiKt4TruthDressedWZJets",
+"AntiKt4TruthDressedWZJetsAux.pt.eta.phi.m.PartonTruthLabelID.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor.GhostBHadronsFinalCount.GhostBHadronsFinal"
+]
+
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4TruthJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4TruthJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..5ce6ea129344b77c8cf9681a160d83237db4da12
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4TruthJetsCPContent.py
@@ -0,0 +1,7 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt4TruthJetsCPContent = [
+"AntiKt4TruthJets",
+"AntiKt4TruthJetsAux.pt.eta.phi.m.PartonTruthLabelID.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor"
+]
+
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4TruthWZJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4TruthWZJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..ac42966e07979211cd62cd1be885d938f2247044
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt4TruthWZJetsCPContent.py
@@ -0,0 +1,7 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt4TruthWZJetsCPContent = [
+"AntiKt4TruthWZJets",
+"AntiKt4TruthWZJetsAux.pt.eta.phi.m.PartonTruthLabelID.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor.GhostBHadronsFinalCount.GhostBHadronsFinal"
+]
+
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt5LCTopoJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt5LCTopoJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..57d4e1159c72ac1c00a20171518d0c6a72da81d5
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt5LCTopoJetsCPContent.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt5LCTopoJetsCPContent = [
+"Kt4LCTopoOriginEventShape",
+"Kt4LCTopoOriginEventShapeAux.Density",
+"AntiKt5LCTopoJets",
+"AntiKt5LCTopoJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.NumTrkPt500.SumPtTrkPt500.EnergyPerSampling.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.DetectorEta.DetectorY.FracSamplingMax.FracSamplingMaxIndex.GhostTrack.Jvt.JVFCorr.JvtRpt.NumTrkPt1000.TrackWidthPt1000.GhostMuonSegmentCount.PartonTruthLabelID.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor.Timing",
+"MET_Track",
+"MET_TrackAux.name.mpx.mpy",
+"PrimaryVertices",
+"PrimaryVerticesAux.vertexType"
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt6LCTopoJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt6LCTopoJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..c88b609afbe6629269b1636751d0ea0476694fd9
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt6LCTopoJetsCPContent.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt6LCTopoJetsCPContent = [
+"Kt4LCTopoOriginEventShape",
+"Kt4LCTopoOriginEventShapeAux.Density",
+"AntiKt6LCTopoJets",
+"AntiKt6LCTopoJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.NumTrkPt500.SumPtTrkPt500.EnergyPerSampling.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.DetectorEta.DetectorY.FracSamplingMax.FracSamplingMaxIndex.GhostTrack.Jvt.JVFCorr.JvtRpt.NumTrkPt1000.TrackWidthPt1000.GhostMuonSegmentCount.PartonTruthLabelID.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor.Timing",
+"MET_Track",
+"MET_TrackAux.name.mpx.mpy",
+"PrimaryVertices",
+"PrimaryVerticesAux.vertexType"
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt7LCTopoJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt7LCTopoJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..b7160ed89058677e2dad45b1500d0c6deb083c15
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt7LCTopoJetsCPContent.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt7LCTopoJetsCPContent = [
+"Kt4LCTopoOriginEventShape",
+"Kt4LCTopoOriginEventShapeAux.Density",
+"AntiKt7LCTopoJets",
+"AntiKt7LCTopoJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.NumTrkPt500.SumPtTrkPt500.EnergyPerSampling.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.DetectorEta.DetectorY.FracSamplingMax.FracSamplingMaxIndex.GhostTrack.Jvt.JVFCorr.JvtRpt.NumTrkPt1000.TrackWidthPt1000.GhostMuonSegmentCount.PartonTruthLabelID.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor.Timing",
+"MET_Track",
+"MET_TrackAux.name.mpx.mpy",
+"PrimaryVertices",
+"PrimaryVerticesAux.vertexType"
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowExKt2GASubJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowExKt2GASubJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..43bee234718b3e08d764f0dbfead2701cb6ad999
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowExKt2GASubJetsCPContent.py
@@ -0,0 +1,6 @@
+# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+
+AntiKt8EMPFlowExKt2GASubJetsCPContent = [
+"AntiKt8EMPFlowExKt2GASubJets",
+"AntiKt8EMPFlowExKt2GASubJetsAux.pt.eta.phi.m",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowExKt2SubJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowExKt2SubJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..2144e99039121209812d97e5442bc5059ed8af17
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowExKt2SubJetsCPContent.py
@@ -0,0 +1,6 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt8EMPFlowExKt2SubJetsCPContent = [
+"AntiKt8EMPFlowExKt2SubJets",
+"AntiKt8EMPFlowExKt2SubJetsAux.pt.eta.phi.m",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowExKt3GASubJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowExKt3GASubJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..16e8ad9de2806d504926a48319a59ae26e52e5e0
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowExKt3GASubJetsCPContent.py
@@ -0,0 +1,6 @@
+# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+
+AntiKt8EMPFlowExKt3GASubJetsCPContent = [
+"AntiKt8EMPFlowExKt3GASubJets",
+"AntiKt8EMPFlowExKt3GASubJetsAux.pt.eta.phi.m",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowExKt3SubJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowExKt3SubJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..eb3a376c11c7e8086f68edf5b43b12b1f2c87973
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowExKt3SubJetsCPContent.py
@@ -0,0 +1,6 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt8EMPFlowExKt3SubJetsCPContent = [
+"AntiKt8EMPFlowExKt3SubJets",
+"AntiKt8EMPFlowExKt3SubJetsAux.pt.eta.phi.m",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..085000ec2a04709f1629d3b68c21a03bc686f67b
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMPFlowJetsCPContent.py
@@ -0,0 +1,6 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt8EMPFlowJetsCPContent = [
+"AntiKt8EMPFlowJets",
+"AntiKt8EMPFlowJetsAux.pt.eta.phi.m.GhostTrack.ExKt2SubJets.ExKt3SubJets.ExKt2GASubJets.ExKt3GASubJets.constituentLinks.Parent",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMTopoExKt2SubJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMTopoExKt2SubJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..431526d5074ce8954dfa2be5c2f22031eb019386
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMTopoExKt2SubJetsCPContent.py
@@ -0,0 +1,6 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt8EMTopoExKt2SubJetsCPContent = [
+"AntiKt8EMTopoExKt2SubJets",
+"AntiKt8EMTopoExKt2SubJetsAux.pt.eta.phi.m",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMTopoExKt3SubJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMTopoExKt3SubJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..45eb8d5a70d4005a2c981dc28a354cb303b71193
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMTopoExKt3SubJetsCPContent.py
@@ -0,0 +1,6 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt8EMTopoExKt3SubJetsCPContent = [
+"AntiKt8EMTopoExKt3SubJets",
+"AntiKt8EMTopoExKt3SubJetsAux.pt.eta.phi.m",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMTopoJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMTopoJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..c203201a33e758c5a395a09e2238bae90634ee9f
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8EMTopoJetsCPContent.py
@@ -0,0 +1,6 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt8EMTopoJetsCPContent = [
+"AntiKt8EMTopoJets",
+"AntiKt8EMTopoJetsAux.pt.eta.phi.m.GhostTrack.ExKt2SubJets.ExKt3SubJets",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8LCTopoJetsCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8LCTopoJetsCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..25cb857d52b8de133e313e11ac3228f12fdcf963
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/AntiKt8LCTopoJetsCPContent.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+AntiKt8LCTopoJetsCPContent = [
+"Kt4LCTopoOriginEventShape",
+"Kt4LCTopoOriginEventShapeAux.Density",
+"AntiKt8LCTopoJets",
+"AntiKt8LCTopoJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.NumTrkPt500.SumPtTrkPt500.EnergyPerSampling.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.DetectorEta.DetectorY.FracSamplingMax.FracSamplingMaxIndex.GhostTrack.Jvt.JVFCorr.JvtRpt.NumTrkPt1000.TrackWidthPt1000.GhostMuonSegmentCount.PartonTruthLabelID.ConeTruthLabelID.HadronConeExclExtendedTruthLabelID.HadronConeExclTruthLabelID.TrueFlavor.Timing",
+"MET_Track",
+"MET_TrackAux.name.mpx.mpy",
+"PrimaryVertices",
+"PrimaryVerticesAux.vertexType"
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/ExtendedJetCommon.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/ExtendedJetCommon.py
index ba0c393d802f2a5d464fa6d9ef0692944206e3c9..e205b87b638aadb378e9f0fec5ba9a8b2bec5627 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/ExtendedJetCommon.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/ExtendedJetCommon.py
@@ -8,19 +8,57 @@
 from DerivationFrameworkCore.DerivationFrameworkMaster import *
 from DerivationFrameworkJetEtMiss.JetCommon import *
 from JetRec.JetRecFlags import jetFlags
+from JetJvtEfficiency.JetJvtEfficiencyToolConfig import (getJvtEffTool, getJvtEffToolName)
 
 from AthenaCommon import Logging
 extjetlog = Logging.logging.getLogger('ExtendedJetCommon')
 
+def nameJetsFromAlg(alg):
+    """ Name a jet collection from its algorithm
+        
+        The jet code likes to pass around the algorithm name (e.g.
+        AntiKt4EMTopo) rather than the jet collection. This was previously fine
+        as all that was needed to do was to append 'Jets' to the name, however
+        now that we have date-stamped b-tagging containers, this simple rule is
+        not so simple...
+    """
+    if "_BTagging" in alg:
+        return alg.replace("_BTagging", "Jets_BTagging")
+    else:
+        return alg+"Jets"
+
+
+##################################################################
+# Jet helpers for large-radius groomed jets
 ##################################################################
 
 def addDefaultTrimmedJets(sequence,outputlist,dotruth=True,writeUngroomed=False):
     if DerivationFrameworkIsMonteCarlo and dotruth:
-        addTrimmedJets('AntiKt', 1.0, 'Truth', rclus=0.2, ptfrac=0.05, algseq=sequence, outputGroup=outputlist, writeUngroomed=writeUngroomed)
-    addTrimmedJets('AntiKt', 1.0, 'LCTopo', rclus=0.2, ptfrac=0.05, algseq=sequence, outputGroup=outputlist, writeUngroomed=writeUngroomed)
+        addTrimmedJets('AntiKt', 1.0, 'Truth', rclus=0.2, ptfrac=0.05, mods="truth_groomed",
+                       algseq=sequence, outputGroup=outputlist, writeUngroomed=writeUngroomed)
+    addTrimmedJets('AntiKt', 1.0, 'LCTopo', rclus=0.2, ptfrac=0.05, mods="lctopo_groomed",
+                   algseq=sequence, outputGroup=outputlist, writeUngroomed=writeUngroomed)
+
+def addTCCTrimmedJets(sequence,outputlist,dotruth=True,writeUngroomed=False):
+    addTrimmedJets('AntiKt', 1.0, 'TrackCaloCluster', rclus=0.2, ptfrac=0.05, mods="tcc_groomed",
+                   algseq=sequence, outputGroup=outputlist, writeUngroomed=writeUngroomed)
+
+def addCSSKSoftDropJets(sequence, seq_name, logger=extjetlog):
+    vrJetName, vrGhostLabel = buildVRJets(
+        sequence, do_ghost=True, logger=logger)
+
+    addVRJets(sequence, do_ghost=True, logger=logger)
+
+    addConstModJets("AntiKt", 1.0, "LCTopo", ["CS", "SK"], sequence, seq_name,
+                    ptmin=40000, ptminFilter=50000, mods="lctopo_ungroomed",
+                    addGetters=[vrGhostLabel.lower()])
+    addSoftDropJets("AntiKt", 1.0, "LCTopo", beta=1.0, zcut=0.1,
+                    algseq=sequence, outputGroup=seq_name,
+                    writeUngroomed=True, mods="lctopo_groomed",
+                    constmods=["CS", "SK"])
 
 ##################################################################              
-# Add AntiKt jets                                                               
+# Jet helpers for ungroomed jets (removed in xAOD reduction)
 ##################################################################              
 
 from BTagging.BTaggingFlags import BTaggingFlags
@@ -37,17 +75,20 @@ def addAntiKt10LCTopoJets(sequence, outputlist):
     addStandardJets("AntiKt", 1.0, "LCTopo", ptmin=40000, ptminFilter=50000, mods="lctopo_ungroomed", algseq=sequence, outputGroup=outputlist)
 
 def addAntiKt2PV0TrackJets(sequence, outputlist):
-    btag_akt2trk = ConfInst.setupJetBTaggerTool(ToolSvc, JetCollection="AntiKt2Track", AddToToolSvc=True,
-                                                Verbose=True,
-                                                options={"name"         : "btagging_antikt2track",
-                                                         "BTagName"     : "BTagging_AntiKt2Track",
-                                                         "BTagJFVtxName": "JFVtx",
-                                                         "BTagSVName"   : "SecVtx",
-                                                         },
-                                                SetupScheme = "",
-                                                TaggerList = ['IP2D', 'IP3D', 'MultiSVbb1',  'MultiSVbb2', 'SV1', 'JetFitterNN', 'SoftMu', 'MV2c10', 'MV2c10mu', 'MV2c10rnn', 'JetVertexCharge', 'MV2cl100' , 'MVb', 'DL1', 'DL1rnn', 'DL1mu', 'RNNIP', 'MV2c10Flip']
-                                                )
-    jtm.modifiersMap["akt2track"] = jtm.modifiersMap["track_ungroomed"] + [btag_akt2trk]
+    
+    #To be fixed by FTAG
+    #btag_akt2trk = ConfInst.setupJetBTaggerTool(ToolSvc, JetCollection="AntiKt2Track", AddToToolSvc=True,
+    #                                            Verbose=True,
+    #                                            options={"name"         : "btagging_antikt2track",
+    #                                                     "BTagName"     : "BTagging_AntiKt2Track",
+    #                                                     "BTagJFVtxName": "JFVtx",
+    #                                                     "BTagSVName"   : "SecVtx",
+    #                                                     },
+    #                                            SetupScheme = "",
+    #                                            TaggerList = ['IP2D', 'IP3D', 'MultiSVbb1',  'MultiSVbb2', 'SV1', 'JetFitterNN', 'SoftMu', 'MV2c10', 'MV2c10mu', 'MV2c10rnn', 'JetVertexCharge', 'MV2cl100' , 'MVb', 'DL1', 'DL1rnn', 'DL1mu', 'RNNIP', 'MV2c10Flip']
+    #)
+    #jtm.modifiersMap["akt2track"] = jtm.modifiersMap["track_ungroomed"] + [btag_akt2trk]
+    jtm.modifiersMap["akt2track"] = jtm.modifiersMap["track_ungroomed"]
     addStandardJets("AntiKt", 0.2, "PV0Track", ptmin=2000, mods="akt2track",
                     algseq=sequence, outputGroup=outputlist)
 
@@ -57,6 +98,10 @@ def addAntiKt4PV0TrackJets(sequence, outputlist):
 def addAntiKt10PV0TrackJets(sequence, outputlist):
     addStandardJets("AntiKt", 1.0, "PV0Track", ptmin=2000, ptminFilter=40000, mods="track_ungroomed", algseq=sequence, outputGroup=outputlist)
 
+def addAntiKt2TruthJets(sequence,outputlist):
+    if DerivationFrameworkIsMonteCarlo:
+        addStandardJets("AntiKt", 0.2, "Truth", ptmin=5000, mods="truth_ungroomed", algseq=sequence, outputGroup=outputlist)
+
 def addAntiKt4TruthJets(sequence,outputlist):
     if DerivationFrameworkIsMonteCarlo:
         addStandardJets("AntiKt", 0.4, "Truth", ptmin=5000, mods="truth_ungroomed", algseq=sequence, outputGroup=outputlist)
@@ -65,6 +110,10 @@ def addAntiKt4TruthWZJets(sequence,outputlist):
     if DerivationFrameworkIsMonteCarlo:
         addStandardJets("AntiKt", 0.4, "TruthWZ", ptmin=5000, mods="truth_ungroomed", algseq=sequence, outputGroup=outputlist)
 
+def addAntiKt4TruthDressedWZJets(sequence,outputlist):
+    if DerivationFrameworkIsMonteCarlo:
+        addStandardJets("AntiKt", 0.4, "TruthDressedWZ", ptmin=5000, mods="truth_ungroomed", algseq=sequence, outputGroup=outputlist)
+
 def addAntiKt10TruthJets(sequence,outputlist):
     if DerivationFrameworkIsMonteCarlo:
         addStandardJets("AntiKt", 1.0, "Truth", ptmin=40000, mods="truth_ungroomed", algseq=sequence, outputGroup=outputlist)
@@ -73,6 +122,8 @@ def addAntiKt10TruthWZJets(sequence,outputlist):
     if DerivationFrameworkIsMonteCarlo:
         addStandardJets("AntiKt", 1.0, "TruthWZ", ptmin=40000, mods="truth_ungroomed", algseq=sequence, outputGroup=outputlist)
 
+##################################################################  
+
 def replaceAODReducedJets(jetlist,sequence,outputlist):
     extjetlog.info( "Replacing AOD-reduced jet collections: {0}".format(",".join(jetlist)))
     if "AntiKt2PV0TrackJets" in jetlist:
@@ -81,6 +132,8 @@ def replaceAODReducedJets(jetlist,sequence,outputlist):
         addAntiKt4PV0TrackJets(sequence,outputlist)
     if "AntiKt10PV0TrackJets" in jetlist:
         addAntiKt10PV0TrackJets(sequence,outputlist)
+    if "AntiKt2TruthJets" in jetlist:
+        addAntiKt2TruthJets(sequence,outputlist)
     if "AntiKt4TruthJets" in jetlist:
         addAntiKt4TruthJets(sequence,outputlist)
     if "AntiKt4TruthWZJets" in jetlist:
@@ -89,9 +142,38 @@ def replaceAODReducedJets(jetlist,sequence,outputlist):
         addAntiKt10TruthJets(sequence,outputlist)
     if "AntiKt10TruthWZJets" in jetlist:
         addAntiKt10TruthWZJets(sequence,outputlist)
+    if "AntiKt2LCTopoJets" in jetlist:
+        addAntiKt2LCTopoJets(sequence,outputlist)
     if "AntiKt10LCTopoJets" in jetlist:
         addAntiKt10LCTopoJets(sequence,outputlist)
 
+##################################################################
+# Jet helpers for adding low-pt jets needed for calibration 
+##################################################################
+
+# 2 GeV cut after pileup suppression for in-situ Z
+def addAntiKt4LowPtJets(sequence,outputlist):
+    addStandardJets("AntiKt", 0.4, "EMTopo",  namesuffix="LowPt", ptmin=2000, ptminFilter=2000,
+                    mods="emtopo_ungroomed", algseq=sequence, outputGroup=outputlist,calibOpt="ar")
+    addStandardJets("AntiKt", 0.4, "LCTopo",  namesuffix="LowPt", ptmin=2000, ptminFilter=2000,
+                    mods="lctopo_ungroomed", algseq=sequence, outputGroup=outputlist,calibOpt="ar")
+
+    addCHSPFlowObjects()
+    addStandardJets("AntiKt", 0.4, "EMPFlow", namesuffix="LowPt", ptmin=2000, ptminFilter=2000,
+                    mods="pflow_ungroomed", algseq=sequence, outputGroup=outputlist,calibOpt="ar:pflow")
+
+################################################################## 
+
+# 1 MeV cut at constituent level for MCJES
+def addAntiKt4NoPtCutJets(sequence,outputlist):
+    addStandardJets("AntiKt", 0.4, "EMTopo",  namesuffix="NoPtCut", ptmin=0, ptminFilter=1,
+                    mods="emtopo_ungroomed", algseq=sequence, outputGroup=outputlist,calibOpt="none")
+    addStandardJets("AntiKt", 0.4, "LCTopo",  namesuffix="NoPtCut", ptmin=0, ptminFilter=1,
+                    mods="lctopo_ungroomed", algseq=sequence, outputGroup=outputlist,calibOpt="none")
+    addCHSPFlowObjects()
+    addStandardJets("AntiKt", 0.4, "EMPFlow", namesuffix="NoPtCut", ptmin=0, ptminFilter=1,
+                    mods="pflow_ungroomed", algseq=sequence, outputGroup=outputlist,calibOpt="none")
+
 ##################################################################
 
 def applyJetAugmentation(jetalg,algname,sequence,jetaugtool):
@@ -104,19 +186,24 @@ def applyJetAugmentation(jetalg,algname,sequence,jetaugtool):
     if not jetaugtool in jetaug.AugmentationTools:
         jetaug.AugmentationTools.append(jetaugtool)
 
-def getJetAugmentationTool(jetalg):
-    jetaugtoolname = 'DFJetAug_'+jetalg
+def getJetAugmentationTool(jetalg, suffix=''):
+    jetaugtoolname = 'DFJetAug_'+jetalg+suffix
     jetaugtool = None
     from AthenaCommon.AppMgr import ToolSvc
     if hasattr(ToolSvc,jetaugtoolname):
         jetaugtool = getattr(ToolSvc,jetaugtoolname)
     else:
+        inJets = jetalg+'Jets'
+        if '_BTagging' in jetalg:
+          inJets = jetalg.replace('_BTagging','Jets_BTagging')
         jetaugtool = CfgMgr.DerivationFramework__JetAugmentationTool(jetaugtoolname,
-                                                                     InputJets=jetalg+'Jets')
+                                                                     InputJets=inJets)
         ToolSvc += jetaugtool
 
     return jetaugtool
 
+##################################################################
+
 def getJetExternalAssocTool(jetalg, extjetalg, **options):
     jetassoctoolname = 'DFJetExternalAssoc_%s_From_%s' % (jetalg, extjetalg)
     jetassoctool = None
@@ -124,49 +211,89 @@ def getJetExternalAssocTool(jetalg, extjetalg, **options):
     if hasattr(ToolSvc,jetassoctoolname):
         jetassoctool = getattr(ToolSvc,jetassoctoolname)
     else:
+        extjetname = extjetalg + 'Jets' if 'BTagging' not in extjetalg else extjetalg.replace('_BTagging','Jets_BTagging')
         jetassoctool = CfgMgr.DerivationFramework__JetExternalAssocTool(jetassoctoolname,
                                                                         InputJets=jetalg+'Jets',
-                                                                        ExternalJetCollectionName = extjetalg+'Jets',
+                                                                        ExternalJetCollectionName = extjetname,
                                                                         **options)
         ToolSvc += jetassoctool
 
     return jetassoctool
 
-def applyJetCalibration(jetalg,algname,sequence):
+##################################################################
+# Calibration related functions 
+##################################################################
+
+def applyJetCalibration(jetalg,algname,sequence,largeRjetconfig = 'comb', suffix = ''):
+
     calibtoolname = 'DFJetCalib_'+jetalg
-    jetaugtool = getJetAugmentationTool(jetalg)
+    jetaugtool = getJetAugmentationTool(jetalg, suffix)
+
+    rhoKey = 'auto'
+    if '_BTagging' in jetalg:
+        jetalg_basename = jetalg[:jetalg.find('_BTagging')]
+    elif 'PFlowCustomVtx' in jetalg:
+        jetalg_basename = 'AntiKt4EMPFlow'
+        rhoKey = 'Kt4PFlowCustomVtxEventShape'
+    else:
+        jetalg_basename = jetalg
 
     from AthenaCommon.AppMgr import ToolSvc
+
+    from LumiBlockComps.LumiBlockMuWriterDefault import LumiBlockMuWriterDefault
+    LumiBlockMuWriterDefault()
+
     if hasattr(ToolSvc,calibtoolname):
         jetaugtool.JetCalibTool = getattr(ToolSvc,calibtoolname)
     else:
         isdata=False
 
+        #largeRconfig selects config file for AntiKt10LCTopoTrimmedPtFrac5SmallR20, default is JES_MC16recommendation_FatJet_JMS_comb_19Jan2018.config
+        if not largeRjetconfig in ['comb','calo','TA']:
+            extjetlog.warning('*** Wrong value for fatjetconfig!  Only \'comb\' (default), \'calo\' or \'TA\' can be used. ***')
+
+        #Warning: these are quite outdated ... leaving for validation purposes for now
         configdict = {'AntiKt4EMTopo':('JES_data2016_data2015_Recommendation_Dec2016_rel21.config',
                                        'JetArea_Residual_EtaJES_GSC'),
                       'AntiKt4LCTopo':('JES_data2016_data2015_Recommendation_Dec2016_rel21.config',
                                        'JetArea_Residual_EtaJES_GSC'),
-                      'AntiKt4EMPFlow':('JES_MC15Prerecommendation_PFlow_Aug2016.config',
-                                        'JetArea_Residual_EtaJES_GSC'),
+                      'AntiKt4EMPFlow':('JES_MC16Recommendation_Consolidated_PFlow_Apr2019_Rel21.config',
+                                        'JetArea_Residual_EtaJES_GSC_Smear'),
                       'AntiKt10LCTopoTrimmedPtFrac5SmallR20':('JES_MC15recommendation_FatJet_Nov2016_QCDCombinationUncorrelatedWeights.config',
                                                               'EtaJES_JMS'),
+                      'AntiKt2LCTopo':('JES_2015_2016_data_Rscan2LC_18Dec2018_R21.config',
+                                       'JetArea_Residual_EtaJES_GSC'),
                       }
+
+        if largeRjetconfig=='calo': #Choose JES_MC16recommendation_FatJet_JMS_calo_29Nov2017.config for AntiKt10LCTopoTrimmedPtFrac5SmallR20
+            configdict.update({'AntiKt10LCTopoTrimmedPtFrac5SmallR20':('JES_MC16recommendation_FatJet_JMS_calo_29Nov2017.config',
+                                                                       'EtaJES_JMS')
+                              })
+        if largeRjetconfig=='TA': #Choose JES_MC16recommendation_FatJet_JMS_TA_29Nov2017.config for AntiKt10LCTopoTrimmedPtFrac5SmallR20
+            configdict.update({'AntiKt10LCTopoTrimmedPtFrac5SmallR20':('JES_MC16recommendation_FatJet_JMS_TA_29Nov2017.config',
+                                                                       'EtaJES_JMS')
+                              })
         isMC = DerivationFrameworkIsMonteCarlo
         isAF2 = False
         if isMC:
             isAF2 = 'ATLFASTII' in inputFileSummary['metadata']['/Simulation/Parameters']['SimulationFlavour'].upper()
         if isMC and isAF2:
+            ## Warning: these are quite outdated ... leaving for validation purposes for now
             configdict['AntiKt4EMTopo'] = ('JES_MC15Prerecommendation_AFII_June2015.config',
                                            'JetArea_Residual_EtaJES_GSC')
+            configdict['AntiKt4EMPFlow'] = ('JES_MC16Recommendation_AFII_PFlow_Apr2019_Rel21.config',
+                                            'JetArea_Residual_EtaJES_GSC_Smear')
+
+        config,calibseq = configdict[jetalg_basename]
 
-        config,calibseq = configdict[jetalg]
-        if (not isMC) and jetalg in ['AntiKt4EMTopo','AntiKt4LCTopo']:
-            calibseq+='_Insitu'
+        if (not isMC) and jetalg_basename in ['AntiKt4EMTopo','AntiKt4LCTopo','AntiKt4EMPFlow']:
             isdata=True
+            if not jetalg_basename=='AntiKt4LCTopo': calibseq = calibseq[:-6]+'_Insitu'
 
         calibtool = CfgMgr.JetCalibrationTool(
             calibtoolname,
-            JetCollection=jetalg,
+            JetCollection=jetalg_basename,
+            RhoKey=rhoKey,
             ConfigFile=config,
             CalibSequence=calibseq,
             IsData=isdata
@@ -177,50 +304,147 @@ def applyJetCalibration(jetalg,algname,sequence):
     extjetlog.info('Applying calibration to jet collection: '+jetalg+'Jets')
     applyJetAugmentation(jetalg,algname,sequence,jetaugtool)
 
+##################################################################
+
 def applyJetCalibration_xAODColl(jetalg='AntiKt4EMTopo',sequence=DerivationFrameworkJob):
-    supportedJets = ['AntiKt4EMTopo','AntiKt4LCTopo','AntiKt4EMPFlow']
+    supportedJets = ['AntiKt4EMTopo','AntiKt4LCTopo','AntiKt4EMPFlow','AntiKt4EMTopo_BTagging201810','AntiKt4EMPFlow_BTagging201810']
     if not jetalg in supportedJets:
         extjetlog.warning('*** Calibration requested for unsupported jet collection '+jetalg+'! ***')
         return
     else:
-        applyJetCalibration(jetalg,'JetCommonKernel_xAODJets',sequence)
+        applyJetCalibration(jetalg,'JetCommonKernel_{0}'.format(jetalg),sequence)
+
+##################################################################
 
 def applyJetCalibration_CustomColl(jetalg='AntiKt10LCTopoTrimmedPtFrac5SmallR20',sequence=None):
-    supportedJets = ['AntiKt10LCTopoTrimmedPtFrac5SmallR20']
+    supportedJets = ['AntiKt10LCTopoTrimmedPtFrac5SmallR20','AntiKt2LCTopo']
     if not jetalg in supportedJets:
         extjetlog.warning('*** Calibration requested for unsupported jet collection! ***')
         extjetlog.warning('Supported custom jets: '+supportedJets)
         return
     else:
-        applyJetCalibration(jetalg,'JetCommonKernel_OTFJets',sequence)
+        applyJetCalibration(jetalg,'JetCommonKernel_{0}'.format(jetalg),sequence)
 
-def updateJVT(jetalg,algname,sequence):
-    jetaugtool = getJetAugmentationTool(jetalg)
+##################################################################
+# JVT
+##################################################################
+
+def updateJVT(jetalg,algname,sequence, suffix = '',customVxColl = 'PrimaryVertices'):
+    jetaugtool = getJetAugmentationTool(jetalg, suffix)
     if(jetaugtool==None or jetaugtool.JetCalibTool==''):
         extjetlog.warning('*** JVT update called but corresponding augmentation tool does not exist! ***')
         extjetlog.warning('*** You must apply jet calibration before scheduling JVT! ***')
 
     jvttoolname = 'DFJetJvt_'+jetalg
+
+    pvxName = customVxColl
+
+    if '_BTagging' in jetalg:
+        jetalg_basename = jetalg[:jetalg.find('_BTagging')]
+    elif 'PFlowCustomVtx' in jetalg:
+        jetalg_basename = 'AntiKt4EMPFlow'
+    else:
+        jetalg_basename = jetalg
+
+    #use the standard name defined by the config helper
+    jvtefftoolname = getJvtEffToolName(jetalg_basename)
+
     from AthenaCommon.AppMgr import ToolSvc
+
+    #setup the jvt updating tools if not already done
     if hasattr(ToolSvc,jvttoolname):
         jetaugtool.JetJvtTool = getattr(ToolSvc,jvttoolname)
     else:
-        jvttool = CfgMgr.JetVertexTaggerTool()
+        jvttool = CfgMgr.JetVertexTaggerTool(jvttoolname,JetContainer=jetalg_basename+'Jets',VertexContainer=pvxName)
         ToolSvc += jvttool
         jetaugtool.JetJvtTool = jvttool
 
+    #now do the same for the efftool, but this has an auto-config function                                                                                                                                 
+    
+    if hasattr(ToolSvc,jvtefftoolname):
+        jetaugtool.JetJvtEffTool = getattr(ToolSvc,jvtefftoolname)
+        extjetlog.info('Setup the jvt eff tool {}'.format(jvtefftoolname))
+    else:
+        extjetlog.info('Setting up the jvt eff tool {}'.format(jvtefftoolname))
+        jvtefftool = getJvtEffTool(jetalg_basename)
+        ToolSvc += jvtefftool
+        jetaugtool.JetJvtEffTool = jvtefftool
+
     extjetlog.info('ExtendedJetCommon: Updating JVT for jet collection: '+jetalg+'Jets')
     applyJetAugmentation(jetalg,algname,sequence,jetaugtool)
 
+################################################################## 
+
 def updateJVT_xAODColl(jetalg='AntiKt4EMTopo',sequence=DerivationFrameworkJob):
-    supportedJets = ['AntiKt4EMTopo']
+    supportedJets = ['AntiKt4EMTopo','AntiKt4EMPFlow','AntiKt4EMTopo_BTagging201810','AntiKt4EMPFlow_BTagging201810']
     if not jetalg in supportedJets:
-        extjetlog.warning('*** JVT update requested for unsupported jet collection! ***')
+        extjetlog.warning('*** JVT update requested for unsupported jet collection {}! ***'.format(jetalg))
         return
     else:
-        updateJVT(jetalg,'JetCommonKernel_xAODJets',sequence)
+        updateJVT(jetalg,'JetCommonKernel_{0}'.format(jetalg),sequence)
+
+##################################################################
+
+def addJetPtAssociation(jetalg, truthjetalg, sequence, algname):
+    jetaugtool = getJetAugmentationTool(jetalg, '_PtAssoc')
+    if(jetaugtool==None):
+        extjetlog.warning('*** addJetPtAssociation called but corresponding augmentation tool does not exist! ***')
+
+    jetptassociationtoolname = 'DFJetPtAssociation_'+truthjetalg
+    from AthenaCommon.AppMgr import ToolSvc
+    if hasattr(ToolSvc,jetptassociationtoolname):
+        jetaugtool.JetPtAssociationTool = getattr(ToolSvc,jetptassociationtoolname)
+    else:
+        jetptassociationtool = CfgMgr.JetPtAssociationTool(jetptassociationtoolname, InputContainer=truthjetalg, AssociationName="GhostTruth")
+        ToolSvc += jetptassociationtool
+        jetaugtool.JetPtAssociationTool = jetptassociationtool
+
+    extjetlog.info('ExtendedJetCommon: Adding JetPtAssociationTool for jet collection: '+jetalg+'Jets')
+    applyJetAugmentation(jetalg,algname,sequence,jetaugtool)
+
+##################################################################
+
+def addJetTruthLabel(jetalg,algname,labelname,sequence):
+    supportedLabelNames = ['R10TruthLabel_R21Consolidated']
+    supportedTruthJets = ['AntiKt10TruthTrimmedPtFrac5SmallR20']
+    supportedRecoJets = ['AntiKt10LCTopoTrimmedPtFrac5SmallR20','AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20','AntiKt10UFOCSSKTrimmedPtFrac5SmallR20','AntiKt10UFOCSSKSoftDropBeta100Zcut10','AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5','AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5Ninf','AntiKt10UFOCHSTrimmedPtFrac5SmallR20']
+    supportedJets = supportedRecoJets + supportedTruthJets
+    if not jetalg in supportedJets:
+        extjetlog.warning('*** JetTruthLabeling augmentation requested for unsupported jet collection {}! ***'.format(jetalg))
+        return
+    elif not labelname in supportedLabelNames:
+        extjetlog.warning('*** JetTruthLabeling augmentation requested for unsupported label definition {}! ***'.format(labelname))
+        return
+    else:
+        isTruthJet = False
+        if jetalg in supportedTruthJets:
+            isTruthJet = True
+
+        jetaugtool = getJetAugmentationTool(jetalg)
+
+        if(jetaugtool==None):
+            extjetlog.warning('*** addJetTruthLabel called but corresponding augmentation tool does not exist! ***')
+            return
+
+        jettruthlabeltoolname = 'DFJetTruthLabel_'+jetalg+'_'+labelname
+
+        from AthenaCommon.AppMgr import ToolSvc
+
+        if hasattr(ToolSvc,jettruthlabeltoolname):
+            jetaugtool.JetTruthLabelingTool = getattr(ToolSvc,jettruthlabeltoolname)
+        else:
+            jettruthlabeltool = CfgMgr.JetTruthLabelingTool(jettruthlabeltoolname,IsTruthJetCollection=isTruthJet,TruthLabelName=labelname)
+            ToolSvc += jettruthlabeltool
+            jetaugtool.JetTruthLabelingTool = jettruthlabeltool
 
-def applyBTaggingAugmentation(jetalg,algname='JetCommonKernel_xAODJets',sequence=DerivationFrameworkJob,btagtooldict={}):
+        extjetlog.info('ExtendedJetCommon: Applying JetTruthLabel augmentation to jet collection: ' + jetalg + 'Jets' + ' using ' + labelname +' definition')
+        applyJetAugmentation(jetalg,algname,sequence,jetaugtool)
+
+################################################################## 
+
+def applyBTaggingAugmentation(jetalg,algname='default',sequence=DerivationFrameworkJob,btagtooldict={}):
+    if algname == 'default':
+      algname = 'JetCommonKernel_{0}'.format(jetalg)
     jetaugtool = getJetAugmentationTool(jetalg)
 
     if(jetaugtool==None or jetaugtool.JetCalibTool=='' or jetaugtool.JetJvtTool==''):
@@ -235,9 +459,67 @@ def applyBTaggingAugmentation(jetalg,algname='JetCommonKernel_xAODJets',sequence
     jetaugtool.JetBtagTools = btagtools
     jetaugtool.JetBtagWPs = btagWPs
 
-    extjetlog.info('ExtendedJetCommon: Applying b-tagging working points for jet collection: '+jetalg+'Jets')
+    inJets = jetalg+'Jets'
+    if '_BTagging' in jetalg:
+      inJets = jetalg.replace('_BTagging','Jets_BTagging')
+    extjetlog.info('ExtendedJetCommon: Applying b-tagging working points for jet collection: '+inJets)
     applyJetAugmentation(jetalg,algname,sequence,jetaugtool)
 
+#################################################################
+### Schedule Q/G-tagging decorations ### QGTaggerTool ##### 
+#################################################################
+def addQGTaggerTool(jetalg, sequence, algname, truthjetalg=None ):
+    jetaugtool = getJetAugmentationTool(jetalg,'_qgTag')
+    if(jetaugtool==None):
+        extjetlog.warning('*** addQGTaggerTool called but corresponding augmentation tool does not exist! ***')
+
+    from AthenaCommon.AppMgr import ToolSvc
+
+    if truthjetalg!=None:
+        jetptassociationtoolname = 'DFJetPtAssociation_'+truthjetalg+'_'+jetalg
+        if hasattr(ToolSvc,jetptassociationtoolname):
+            jetaugtool.JetPtAssociationTool = getattr(ToolSvc,jetptassociationtoolname)
+        else:
+            jetptassociationtool = CfgMgr.JetPtAssociationTool(jetptassociationtoolname, InputContainer=truthjetalg, AssociationName="GhostTruth")
+            ToolSvc += jetptassociationtool
+            jetaugtool.JetPtAssociationTool = jetptassociationtool
+
+    #Track selection tool
+    TrackSelectionToolName = 'DFQGTaggerTool' + '_InDetTrackSelectionTool_' + jetalg
+    if hasattr(ToolSvc, TrackSelectionToolName):
+        jetaugtool.TrackSelectionTool = getattr(ToolSvc, TrackSelectionToolName)
+    else:
+        trackselectiontool = CfgMgr.InDet__InDetTrackSelectionTool( TrackSelectionToolName )
+        trackselectiontool.CutLevel = "Loose"
+        ToolSvc += trackselectiontool
+        jetaugtool.TrackSelectionTool = trackselectiontool
+    
+    #Track-vertex association tool
+    TrackVertexAssociationToolName = 'DFQGTaggerTool' + '_InDetTrackVertexAssosciationTool_' + jetalg
+    if hasattr(ToolSvc, TrackVertexAssociationToolName):
+        jetaugtool.TrackVertexAssociationTool = getattr(ToolSvc, TrackVertexAssociationToolName)
+    else:
+        trackvertexassoctool = CfgMgr.CP__TrackVertexAssociationTool(TrackVertexAssociationToolName)
+        trackvertexassoctool.WorkingPoint = "Loose"
+        ToolSvc += trackvertexassoctool
+        jetaugtool.TrackVertexAssociationTool = trackvertexassoctool
+
+    QGTaggerToolName = 'DFQGTaggerTool_' + jetalg
+    pvxName = "PrimaryVertices"
+
+    #calculate variables for q/g tagging
+    if hasattr(ToolSvc,QGTaggerToolName):
+        jetaugtool.JetQGTaggerTool = getattr(ToolSvc,QGTaggerToolName)
+    else:
+        qgtool = CfgMgr.JetQGTaggerVariableTool(QGTaggerToolName,JetContainer=jetalg+'Jets',VertexContainer=pvxName,TVATool=trackvertexassoctool,TrkSelTool=trackselectiontool)
+        ToolSvc += qgtool
+        jetaugtool.JetQGTaggerTool = qgtool
+
+    extjetlog.info('ExtendedJetCommon: Adding QGTaggerTool for jet collection: '+jetalg)
+    applyJetAugmentation(jetalg, algname, sequence, jetaugtool)
+
+################################################################## 
+
 def applyOverlapRemoval(sequence=DerivationFrameworkJob):
     from AssociationUtils.config import recommended_tools
     from AssociationUtils.AssociationUtilsConf import OverlapRemovalGenUseAlg
@@ -258,4 +540,180 @@ def applyOverlapRemoval(sequence=DerivationFrameworkJob):
     DFCommonMuonJetTools.append(MuonJetDrTool)
     sequence += CfgMgr.DerivationFramework__CommonAugmentation("DFCommonMuonsKernel2",AugmentationTools = DFCommonMuonJetTools)
 
+################################################################## 
+# Jet cleaning tool
+################################################################## 
+
+def getJetCleaningTool(cleaningLevel):
+    jetcleaningtoolname = 'JetCleaningTool_'+cleaningLevel
+    jetcleaningtool = None
+    from AthenaCommon.AppMgr import ToolSvc
+    if hasattr(ToolSvc,jetcleaningtoolname):
+        jetcleaningtool = getattr(ToolSvc,jetcleaningtoolname)
+    else:
+        jetcleaningtool = CfgMgr.JetCleaningTool(jetcleaningtoolname,CutLevel=cleaningLevel)
+        jetcleaningtool.UseDecorations = False
+        ToolSvc += jetcleaningtool
+
+    return jetcleaningtool
+
+##################################################################
+# Event cleaning variables
+################################################################## 
+def eventCleanLoose_xAODColl(jetalg='AntiKt4EMTopo',sequence=DerivationFrameworkJob):
+    from JetSelectorTools.JetSelectorToolsConf import ECUtils__EventCleaningTool as EventCleaningTool
+    from JetSelectorTools.JetSelectorToolsConf import EventCleaningTestAlg
+    jetcleaningtoolname = "EventCleaningTool_Loose"
+    prefix = "DFCommonJets_"
+    ecToolLoose = EventCleaningTool('EventCleaningTool_Loose',CleaningLevel='LooseBad')
+    ecToolLoose.JetCleanPrefix = prefix
+    ecToolLoose.JetCleaningTool = getJetCleaningTool("LooseBad")
+    algCleanLoose = EventCleaningTestAlg('EventCleaningTestAlg_Loose',
+                            EventCleaningTool=ecToolLoose,
+                            JetCollectionName="AntiKt4EMTopoJets",
+                            EventCleanPrefix=prefix)
+    sequence += algCleanLoose
+
+##################################################################  
+
+def eventCleanTight_xAODColl(jetalg='AntiKt4EMTopo',sequence=DerivationFrameworkJob):
+    from JetSelectorTools.JetSelectorToolsConf import ECUtils__EventCleaningTool as EventCleaningTool
+    from JetSelectorTools.JetSelectorToolsConf import EventCleaningTestAlg
+    jetcleaningtoolname = "EventCleaningTool_Tight"
+    prefix = "DFCommonJets_"
+    ecToolTight = EventCleaningTool('EventCleaningTool_Tight',CleaningLevel='TightBad')
+    ecToolTight.JetCleanPrefix = prefix
+    ecToolTight.JetCleaningTool = getJetCleaningTool("TightBad")
+    algCleanTight = EventCleaningTestAlg('EventCleaningTestAlg_Tight',
+                            EventCleaningTool=ecToolTight,
+                            JetCollectionName="AntiKt4EMTopoJets",
+                            EventCleanPrefix=prefix,
+                            CleaningLevel="TightBad",
+                            doEvent=False)
+    sequence += algCleanTight
+
+##################################################################  
+
+def eventCleanLooseLLP_xAODColl(jetalg='AntiKt4EMTopo',sequence=DerivationFrameworkJob):
+    from JetSelectorTools.JetSelectorToolsConf import ECUtils__EventCleaningTool as EventCleaningTool
+    from JetSelectorTools.JetSelectorToolsConf import EventCleaningTestAlg
+    jetcleaningtoolname = "EventCleaningTool_LooseLLP"
+    prefix = "DFCommonJets_"
+    ecToolLooseLLP = EventCleaningTool('EventCleaningTool_LooseLLP',CleaningLevel='LooseBadLLP')
+    ecToolLooseLLP.JetCleanPrefix = prefix
+    ecToolLooseLLP.JetCleaningTool = getJetCleaningTool("LooseBadLLP")
+    algCleanLooseLLP = EventCleaningTestAlg('EventCleaningTestAlg_LooseLLP',
+                            EventCleaningTool=ecToolLooseLLP,
+                            JetCollectionName="AntiKt4EMTopoJets",
+                            EventCleanPrefix=prefix,
+                            CleaningLevel="LooseBadLLP",
+                            doEvent=True) #Save the event level decoration
+    sequence += algCleanLooseLLP
+
+##################################################################  
+
+def eventCleanVeryLooseLLP_xAODColl(jetalg='AntiKt4EMTopo',sequence=DerivationFrameworkJob):
+    from JetSelectorTools.JetSelectorToolsConf import ECUtils__EventCleaningTool as EventCleaningTool
+    from JetSelectorTools.JetSelectorToolsConf import EventCleaningTestAlg
+    jetcleaningtoolname = "EventCleaningTool_VeryLooseLLP"
+    prefix = "DFCommonJets_"
+    #Do not save decorations, which are anyway not listed in AntiKt4EMTopoJetsCPContent.py
+    ecToolVeryLooseLLP = EventCleaningTool('EventCleaningTool_VeryLooseLLP',CleaningLevel='VeryLooseBadLLP')
+    ecToolVeryLooseLLP.JetCleanPrefix = prefix
+    ecToolVeryLooseLLP.JetCleaningTool = getJetCleaningTool("VeryLooseBadLLP")
+    algCleanVeryLooseLLP = EventCleaningTestAlg('EventCleaningTestAlg_VeryLooseLLP',
+                            EventCleaningTool=ecToolVeryLooseLLP,
+                            JetCollectionName="AntiKt4EMTopoJets",
+                EventCleanPrefix=prefix,
+                CleaningLevel="VeryLooseBadLLP",
+                doEvent=False) #Save the event level decoration
+    sequence += algCleanVeryLooseLLP
+
+################################################################## 
+
+def eventCleanSuperLooseLLP_xAODColl(jetalg='AntiKt4EMTopo',sequence=DerivationFrameworkJob):
+    from JetSelectorTools.JetSelectorToolsConf import ECUtils__EventCleaningTool as EventCleaningTool
+    from JetSelectorTools.JetSelectorToolsConf import EventCleaningTestAlg
+    jetcleaningtoolname = "EventCleaningTool_SuperLooseLLP"
+    prefix = "DFCommonJets_"
+    #Do not save decorations, which are anyway not listed in AntiKt4EMTopoJetsCPContent.py
+    ecToolSuperLooseLLP = EventCleaningTool('EventCleaningTool_SuperLooseLLP',CleaningLevel='SuperLooseBadLLP')
+    ecToolSuperLooseLLP.JetCleanPrefix = prefix
+    ecToolSuperLooseLLP.JetCleaningTool = getJetCleaningTool("SuperLooseBadLLP")
+    algCleanSuperLooseLLP = EventCleaningTestAlg('EventCleaningTestAlg_SuperLooseLLP',
+                            EventCleaningTool=ecToolSuperLooseLLP,
+                            JetCollectionName="AntiKt4EMTopoJets",
+                EventCleanPrefix=prefix,
+                CleaningLevel="SuperLooseBadLLP",
+                doEvent=False) #Save the event level decoration
+    sequence += algCleanSuperLooseLLP
+
+################################################################## 
+
+def addRscanJets(jetalg,radius,inputtype,sequence,outputlist):
+    jetname = "{0}{1}{2}Jets".format(jetalg,int(radius*10),inputtype)
+    algname = "jetalg"+jetname
+
+    if not hasattr(sequence,algname):
+        if inputtype == "Truth":
+            addStandardJets(jetalg, radius, "Truth", mods="truth_ungroomed", ptmin=5000, algseq=sequence, outputGroup=outputlist)
+        if inputtype == "TruthWZ":
+            addStandardJets(jetalg, radius, "TruthWZ", mods="truth_ungroomed", ptmin=5000, algseq=sequence, outputGroup=outputlist)
+        elif inputtype == "LCTopo":
+            addStandardJets(jetalg, radius, "LCTopo", mods="lctopo_ungroomed",
+                            ghostArea=0.01, ptmin=2000, ptminFilter=7000, calibOpt="none", algseq=sequence, outputGroup=outputlist)
+
+##################################################################
+# Helper to add origin corrected clusters 
+##################################################################
+def addOriginCorrectedClusters(slimhelper,writeLC=False,writeEM=False):
+
+    slimhelper.ExtraVariables.append('CaloCalTopoClusters.calE.calEta.calPhi.calM')
+
+    if writeLC:
+        if not slimhelper.AppendToDictionary.has_key("LCOriginTopoClusters"):
+            slimhelper.AppendToDictionary["LCOriginTopoClusters"]='xAOD::CaloClusterContainer'
+            slimhelper.AppendToDictionary["LCOriginTopoClustersAux"]='xAOD::ShallowAuxContainer'
+            slimhelper.ExtraVariables.append('LCOriginTopoClusters.calEta.calPhi')
+
+    if writeEM:
+        if not slimhelper.AppendToDictionary.has_key("EMOriginTopoClusters"):
+            slimhelper.AppendToDictionary["EMOriginTopoClusters"]='xAOD::CaloClusterContainer'
+            slimhelper.AppendToDictionary["EMOriginTopoClustersAux"]='xAOD::ShallowAuxContainer'
+            slimhelper.ExtraVariables.append('EMOriginTopoClusters.calE.calEta.calPhi')
+
+##################################################################   
+# Helper to manually schedule PFO constituent modifications
+# Only use this while the automatic addition in JetAlgorithm.py
+# is disabled
+##################################################################   
+def addCHSPFlowObjects():
+    # Only act if the collection does not already exist
+    from RecExConfig.AutoConfiguration import IsInInputFile
+    if not IsInInputFile("xAOD::PFOContainer","CHSParticleFlowObjects"):
+        # Check that an alg doing this has not already been inserted
+        from AthenaCommon.AlgSequence import AlgSequence
+        job = AlgSequence()
+        from JetRec.JetRecStandard import jtm
+        if not hasattr(job,"jetalgCHSPFlow") and not hasattr(jtm,"jetconstitCHSPFlow"):
+            from JetRec.JetRecConf import JetToolRunner
+            jtm += JetToolRunner("jetconstitCHSPFlow",
+                                 EventShapeTools=[],
+                                 Tools=[jtm.JetConstitSeq_PFlowCHS])
+            # Add this tool runner to the JetAlgorithm instance "jetalg"
+            # which runs all preparatory tools
+            # This was added by JetCommon
+            job.jetalg.Tools.append(jtm.jetconstitCHSPFlow)
+            extjetlog.info("Added CHS PFlow sequence to \'jetalg\'")
+            extjetlog.info(job.jetalg.Tools)
 ##################################################################
+applyJetCalibration_xAODColl("AntiKt4EMTopo")
+updateJVT_xAODColl("AntiKt4EMTopo")
+
+# Need DFCommonElectronsLHLoose for these to work
+#applyOverlapRemoval()
+#eventCleanLoose_xAODColl("AntiKt4EMTopo")
+#eventCleanTight_xAODColl("AntiKt4EMTopo")
+#eventCleanLooseLLP_xAODColl("AntiKt4EMTopo")
+#eventCleanSuperLooseLLP_xAODColl("AntiKt4EMTopo")
+#eventCleanVeryLooseLLP_xAODColl("AntiKt4EMTopo")
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/JetCommon.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/JetCommon.py
index 12c597b5fa801c1397ea0be7cf2ce4ac9f8ff2a9..cc2dd97d61949111caf1928968077e239e908de3 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/JetCommon.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/JetCommon.py
@@ -25,6 +25,34 @@ addJetRecoToAlgSequence(DerivationFrameworkJob,eventShapeTools=None)
 
 DFJetAlgs = {}
 
+##################################################################
+# Schedule the augmentation of a flag to label events with large
+# EMEC-IW Noise based on the presence of many bad quality clusters 
+##################################################################
+
+if hasattr(DerivationFrameworkJob,"BadBatmanAugmentation"):
+    dfjetlog.warning( "BadBatmanAugmentation: BadBatmanAugmentation already scheduled on sequence "+DerivationFrameworkJob.name )
+else:
+    # Check if we have clusters.  If we don't then this cannot run
+    from RecExConfig.ObjKeyStore import objKeyStore
+    if objKeyStore.isInInput( "xAOD::CaloClusterContainer", "CaloCalTopoClusters" ):
+        # schedule it
+        batmanaug = CfgMgr.DerivationFramework__CommonAugmentation("BadBatmanAugmentation")
+        DerivationFrameworkJob += batmanaug
+        batmanaugtool = None
+        from AthenaCommon.AppMgr import ToolSvc
+        # create and add the tool to the alg if needed                                                                                                                                                      
+        if hasattr(ToolSvc,"BadBatmanAugmentationTool"):
+            batmanaugtool = getattr(ToolSvc,"BadBatmanAugmentationTool")
+        else:
+            batmanaugtool = CfgMgr.DerivationFramework__BadBatmanAugmentationTool("BadBatmanAugmentationTool")
+            ToolSvc += batmanaugtool
+        if not batmanaugtool in batmanaug.AugmentationTools:
+            batmanaug.AugmentationTools.append(batmanaugtool)
+    else:
+        if not objKeyStore.isInInput( "McEventCollection", "GEN_EVENT" ):
+            dfjetlog.warning('Could not schedule BadBatmanAugmentation (fine if running on EVNT)')
+
 ##################################################################
 #                  Definitions of helper functions 
 ##################################################################
@@ -72,7 +100,7 @@ def addGhostAssociation(DerivationFrameworkJob):
 
 ##################################################################
 
-def reCreatePseudoJets(jetalg, rsize, inputtype, variableRMassScale=-1.0, variableRMinRadius=-1.0):
+def reCreatePseudoJets(jetalg, rsize, inputtype, variableRMassScale=-1.0, variableRMinRadius=-1.0, algseq=None):
     """Return a list of tools (possibly empty) to be run in a jetalg. These tools will make sure PseudoJets will be associated
     to the container specified by the input arguments.    
     """
@@ -139,6 +167,12 @@ def reCreatePseudoJets(jetalg, rsize, inputtype, variableRMassScale=-1.0, variab
     # map the input to the jtm code for PseudoJetGetter
     getterMap = dict( LCTopo = 'lctopo', EMTopo = 'emtopo', EMPFlow = 'empflow', EMCPFlow = 'emcpflow', Truth='truth', TruthWZ='truthwz', PV0Track='pv0track')
     # create the finder for the temporary collection.
+
+    for getter in jtm.gettersMap[getterMap[inputtype]]:
+        if getter not in jtm.allGetters:
+            algseq += getter
+            jtm.allGetters += getter
+
     tmpFinderTool= jtm.addJetFinder(tmpName, jetalg, rsize, getterMap[inputtype] ,
                                     **finderArgs   # pass the prepared arguments
                                     )
@@ -170,14 +204,16 @@ def buildGenericGroomAlg(jetalg, rsize, inputtype, groomedName, jetToolBuilder,
     from JetRec.JetRecConf import JetAlgorithm
     # return if the alg is already scheduled here :
     if hasattr(algseq,ungroomedalgname):
+        finderalg = getattr(algseq, ungroomedalgname)
         dfjetlog.warning( "Algsequence "+algseq.name()+" already has an instance of "+ungroomedalgname )
     elif ungroomedalgname in DFJetAlgs:
         dfjetlog.info( "Added jet finder"+ ungroomedalgname+" to sequence"+ algseq.name() )
+        finderalg = DFJetAlgs[ungroomedalgname]
         algseq += DFJetAlgs[ungroomedalgname]
     else:
         # 1. make sure we have pseudo-jet in our original container
         # this returns a list of the needed tools to do so.
-        jetalgTools = reCreatePseudoJets(jetalg, rsize, inputtype, variableRMassScale, variableRMinRadius)
+        jetalgTools = reCreatePseudoJets(jetalg, rsize, inputtype, variableRMassScale, variableRMinRadius, algseq)
         if includePreTools:
             # enable track ghost association and JVF
             jetalgTools =  [jtm.tracksel, jtm.tvassoc] + jetalgTools 
@@ -189,7 +225,10 @@ def buildGenericGroomAlg(jetalg, rsize, inputtype, groomedName, jetToolBuilder,
 
     # 2nd step run the trimming alg. We can re-use the original largeR jet since we reassociated the PseudoJet already.
     fatjet_groom = jetToolBuilder(groomedName, ungroomedName)
-
+    fatjet_rectool = [t for t in finderalg.Tools if t.name() == ungroomedName][0]
+    fatjet_groom.InputPseudoJets = fatjet_rectool.InputPseudoJets # recopy the InputPseudoJets so tools know how to map fastjet constituents with xAOD constituents
+    
+    
     dfjetlog.info( "Added jet groomer "+algname+" to sequence "+algseq.name() )
     groomeralg = JetAlgorithm(algname, Tools = [fatjet_groom])
     DFJetAlgs[algname] = groomeralg;
@@ -260,8 +299,10 @@ def addFilteredJets(jetalg, rsize, inputtype, mumax=1.0, ymin=0.15, mods="groome
 
 def addStandardJets(jetalg, rsize, inputtype, ptmin=0., ptminFilter=0.,
                     mods="default", calibOpt="none", ghostArea=0.01,
-                    algseq=None, outputGroup="CustomJets"):
-    jetnamebase = "{0}{1}{2}".format(jetalg,int(rsize*10),inputtype)
+                    algseq=None, namesuffix="",
+                    outputGroup="CustomJets"):
+
+    jetnamebase = "{0}{1}{2}{3}".format(jetalg,int(rsize*10),inputtype,namesuffix)
     jetname = jetnamebase+"Jets"
     algname = "jetalg"+jetnamebase
     OutputJets.setdefault(outputGroup , [] ).append(jetname)
@@ -308,6 +349,12 @@ def addStandardJets(jetalg, rsize, inputtype, ptmin=0., ptminFilter=0.,
         # map the input to the jtm code for PseudoJetGetter
         getterMap = dict( LCTopo = 'lctopo', EMTopo = 'emtopo', EMPFlow = 'empflow', EMCPFlow = 'emcpflow', Truth='truth', TruthWZ='truthwz', PV0Track='pv0track')
         # create the finder for the temporary collection.
+
+        for getter in jtm.gettersMap[getterMap[inputtype]]:
+            if getter not in jtm.allGetters:
+                algseq += getter
+                jtm.allGetters += getter
+
         finderTool= jtm.addJetFinder(jetname, jetalg, rsize, getterMap[inputtype] ,
                                      **finderArgs   # pass the prepared arguments
                                      )
@@ -318,6 +365,40 @@ def addStandardJets(jetalg, rsize, inputtype, ptmin=0., ptminFilter=0.,
         algseq += alg
         DFJetAlgs[algname] = alg;
 
+################################################################## 
+# Schedule the adding of BCID info
+################################################################## 
+def addDistanceInTrain(sequence=DerivationFrameworkJob):
+    # simple set up -- either the alg exists and contains the tool, in which case we exit
+    if hasattr(sequence,"DistanceInTrainAugmentation"):
+        dfjetlog.warning( "DistanceInTrainAugmentation: DistanceInTrainAugmentation already scheduled on sequence"+sequence.name )
+        return
+    else:
+        isMC = False
+        if globalflags.DataSource() == 'geant4':
+          isMC = True
+
+        distanceintrainaug = CfgMgr.DerivationFramework__CommonAugmentation("DistanceInTrainAugmentation")
+        sequence += distanceintrainaug
+
+        distanceintrainaugtool = None
+        from AthenaCommon.AppMgr import ToolSvc
+        # create and add the tool to the alg if needed                                                                                                                                                      
+        if hasattr(ToolSvc,"DistanceInTrainAugmentationTool"):
+            distanceintrainaugtool = getattr(ToolSvc,"DistanceInTrainAugmentationTool")
+        else:
+            distanceintrainaugtool = CfgMgr.DerivationFramework__DistanceInTrainAugmentationTool("DistanceInTrainAugmentationTool")
+            from TrigBunchCrossingTool.BunchCrossingTool import BunchCrossingTool
+            if isMC:
+                ToolSvc += BunchCrossingTool( "MC" )
+                distanceintrainaugtool.BCTool = "Trig::MCBunchCrossingTool/BunchCrossingTool"
+            else:
+                ToolSvc += BunchCrossingTool( "LHC" )
+                distanceintrainaugtool.BCTool = "Trig::LHCBunchCrossingTool/BunchCrossingTool"
+            ToolSvc += distanceintrainaugtool
+        if not distanceintrainaugtool in distanceintrainaug.AugmentationTools:
+            distanceintrainaug.AugmentationTools.append(distanceintrainaugtool)
+
 ##################################################################
 #       Set up helpers for adding jets to the output streams
 ##################################################################
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/MET_Baseline_AntiKt4EMPFlowCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/MET_Baseline_AntiKt4EMPFlowCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..5a178382203135b380b8d580d733f50c5a1bcdf7
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/MET_Baseline_AntiKt4EMPFlowCPContent.py
@@ -0,0 +1,18 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+MET_Baseline_AntiKt4EMPFlowCPContent  = [
+"AntiKt4EMPFlowJets",
+"AntiKt4EMPFlowJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.GhostTrack.NumTrkPt500.SumPtTrkPt500.Width.EMFrac.EnergyPerSampling.PSFrac",
+"Electrons",
+"InDetTrackParticles",
+"METAssoc_AntiKt4EMPFlow",
+"METAssoc_AntiKt4EMPFlowAux.",
+"MET_Core_AntiKt4EMPFlow",
+"MET_Core_AntiKt4EMPFlowAux.name.mpx.mpy.sumet.source",
+"MET_Truth",
+"MET_TruthAux.name.mpx.mpy.sumet.source",
+"Muons",
+"MuonsAux.EnergyLoss.energyLossType.muonType",
+"Photons",
+"TauJets",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/MET_Baseline_AntiKt4EMTopoCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/MET_Baseline_AntiKt4EMTopoCPContent.py
new file mode 100644
index 0000000000000000000000000000000000000000..e6361def02c793c1523d5d9ee65a70cc8d15a5a6
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/MET_Baseline_AntiKt4EMTopoCPContent.py
@@ -0,0 +1,18 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+MET_Baseline_AntiKt4EMTopoCPContent  = [
+"AntiKt4EMTopoJets",
+"AntiKt4EMTopoJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.GhostTrack.NumTrkPt500.SumPtTrkPt500.Width.EMFrac.EnergyPerSampling",
+"Electrons",
+"InDetTrackParticles",
+"METAssoc_AntiKt4EMTopo",
+"METAssoc_AntiKt4EMTopoAux.",
+"MET_Core_AntiKt4EMTopo",
+"MET_Core_AntiKt4EMTopoAux.name.mpx.mpy.sumet.source",
+"MET_Truth",
+"MET_TruthAux.name.mpx.mpy.sumet.source",
+"Muons",
+"MuonsAux.EnergyLoss.energyLossType.muonType",
+"Photons",
+"TauJets",
+]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/MET_Reference_AntiKt4EMTopoCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/MET_Reference_AntiKt4EMTopoCPContent.py
index 63a7eb9eb064ba1f7e7a378cf0f4a9108fd0021d..d7e9ede32acf8162621927e6ee938ae7a191dccb 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/MET_Reference_AntiKt4EMTopoCPContent.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/python/MET_Reference_AntiKt4EMTopoCPContent.py
@@ -2,7 +2,7 @@
 
 MET_Reference_AntiKt4EMTopoCPContent  = [
 "AntiKt4EMTopoJets",
-"AntiKt4EMTopoJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.GhostTrack.JetLCScaleMomentum_pt.JetLCScaleMomentum_eta.JetLCScaleMomentum_phi.JetLCScaleMomentum_m.NumTrkPt500.SumPtTrkPt500.Width.EMFrac.EnergyPerSampling",
+"AntiKt4EMTopoJetsAux.pt.eta.phi.m.JetConstitScaleMomentum_pt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_m.GhostTrack.NumTrkPt500.SumPtTrkPt500.Width.EMFrac.EnergyPerSampling",
 "Electrons",
 "InDetTrackParticles",
 "METAssoc_AntiKt4EMTopo",
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM1.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM1.py
index 59b9db20f5438c18c4d6b02600bf13d6d1ec1e8c..bce4f64e4c828cd4b2cd2d86f190f3e90abf1394 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM1.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM1.py
@@ -1,37 +1,59 @@
 #====================================================================
-# JETM1.py 
-# reductionConf flag JETM1 in Reco_tf.py   
+# JETM1.py
+# reductionConf flag JETM1 in Reco_tf.py
 #====================================================================
 
 from DerivationFrameworkCore.DerivationFrameworkMaster import *
 from DerivationFrameworkJetEtMiss.JetCommon import *
 from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
-#from DerivationFrameworkJetEtMiss.METCommon import *
+from DerivationFrameworkInDet.InDetCommon import *
+
+# Include TRUTH3 containers
+if DerivationFrameworkIsMonteCarlo:
+    from DerivationFrameworkMCTruth.MCTruthCommon import addStandardTruthContents
+    addStandardTruthContents()
 
 #====================================================================
-# SKIMMING TOOL 
+# SKIMMING TOOL
 #====================================================================
-from DerivationFrameworkJetEtMiss.TriggerLists import *
-triggers = jetTriggers
+from DerivationFrameworkJetEtMiss import TriggerLists
+triggers = TriggerLists.jetTrig()
 
 # NOTE: need to be able to OR isSimulated as an OR with the trigger
-orstr =' || '
-trigger = '('+orstr.join(triggers)+')'
-expression = trigger+' || (EventInfo.eventTypeBitmask==1)'
+expression = ' (EventInfo.eventTypeBitmask==1) || HLT_xe120_pufit_L1XE50'
+
+from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__TriggerSkimmingTool
+JETM1TrigSkimmingTool = DerivationFramework__TriggerSkimmingTool(   name                    = "JETM1TrigSkimmingTool1",
+                                                                TriggerListOR          = triggers )
+ToolSvc += JETM1TrigSkimmingTool
+
 
 from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__xAODStringSkimmingTool
-JETM1SkimmingTool = DerivationFramework__xAODStringSkimmingTool(name = "JETM1SkimmingTool1",
+JETM1OfflineSkimmingTool = DerivationFramework__xAODStringSkimmingTool(name = "JETM1OfflineSkimmingTool1",
                                                                     expression = expression)
-ToolSvc += JETM1SkimmingTool
+ToolSvc += JETM1OfflineSkimmingTool
+
+# OR of the above two selections
+from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__FilterCombinationOR
+JETM1ORTool = DerivationFramework__FilterCombinationOR(name="JETM1ORTool", FilterList=[JETM1TrigSkimmingTool,JETM1OfflineSkimmingTool] )
+ToolSvc+=JETM1ORTool
+
+#=======================================
+# CREATE PRIVATE SEQUENCE
+#=======================================
+
+jetm1Seq = CfgMgr.AthSequencer("JETM1Sequence")
+DerivationFrameworkJob += jetm1Seq
 
 #====================================================================
-# SET UP STREAM   
+# SET UP STREAM
 #====================================================================
 streamName = derivationFlags.WriteDAOD_JETM1Stream.StreamName
 fileName   = buildFileName( derivationFlags.WriteDAOD_JETM1Stream )
 JETM1Stream = MSMgr.NewPoolRootStream( streamName, fileName )
 JETM1Stream.AcceptAlgs(["JETM1Kernel"])
 
+
 #=======================================
 # ESTABLISH THE THINNING HELPER
 #=======================================
@@ -40,7 +62,7 @@ JETM1ThinningHelper = ThinningHelper( "JETM1ThinningHelper" )
 JETM1ThinningHelper.AppendToStream( JETM1Stream )
 
 #====================================================================
-# THINNING TOOLS 
+# THINNING TOOLS
 #====================================================================
 thinningTools = []
 
@@ -62,51 +84,94 @@ JETM1ElectronTPThinningTool = DerivationFramework__EgammaTrackParticleThinning(n
 ToolSvc += JETM1ElectronTPThinningTool
 thinningTools.append(JETM1ElectronTPThinningTool)
 
-# Truth particle thinning
-doTruthThinning = True
-preserveAllDescendants = False
-from AthenaCommon.GlobalFlags import globalflags
-if doTruthThinning and DerivationFrameworkIsMonteCarlo:
-    truth_cond_WZH    = "((abs(TruthParticles.pdgId) >= 23) && (abs(TruthParticles.pdgId) <= 25))"           # W, Z and Higgs
-    truth_cond_Lepton = "((abs(TruthParticles.pdgId) >= 11) && (abs(TruthParticles.pdgId) <= 16) && (TruthParticles.barcode < 200000))"           # Leptons
-    truth_cond_Quark  = "((abs(TruthParticles.pdgId) <=  5  && (TruthParticles.pt > 10000.)) || (abs(TruthParticles.pdgId) == 6))" # Quarks
-    truth_cond_Gluon  = "((abs(TruthParticles.pdgId) == 21) && (TruthParticles.pt > 10000.))"                # Gluons
-    truth_cond_Photon = "((abs(TruthParticles.pdgId) == 22) && (TruthParticles.pt > 10000.) && (TruthParticles.barcode < 200000))"                # Photon
-    truth_expression = '('+truth_cond_WZH+' || '+truth_cond_Lepton +' || '+truth_cond_Quark+'||'+truth_cond_Gluon+' || '+truth_cond_Photon+')'
-    
-    from DerivationFrameworkMCTruth.DerivationFrameworkMCTruthConf import DerivationFramework__GenericTruthThinning
-    JETM1TruthThinningTool = DerivationFramework__GenericTruthThinning( name = "JETM1TruthThinningTool",
-                                                                        StreamName              = streamName,
-                                                                        ParticlesKey = "TruthParticles",
-                                                                        VerticesKey = "TruthVertices",
-                                                                        ParticleSelectionString = truth_expression,
-                                                                        PreserveDescendants     = preserveAllDescendants,
-                                                                        PreserveGeneratorDescendants = not preserveAllDescendants,
-                                                                        PreserveAncestors = True)
-    
-    ToolSvc += JETM1TruthThinningTool
-    thinningTools.append(JETM1TruthThinningTool)
+# TrackParticles associated with small-R jets
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__JetTrackParticleThinning
+JETM1Akt4JetTPThinningTool = DerivationFramework__JetTrackParticleThinning( name          = "JETM1Akt4JetTPThinningTool",
+                                                                            StreamName              = streamName,
+                                                                            JetKey                  = "AntiKt4EMTopoJets",
+                                                                            SelectionString         = "AntiKt4EMTopoJets.pt > 18*GeV",
+                                                                            InDetTrackParticlesKey  = "InDetTrackParticles",
+                                                                            ApplyAnd                = False)
+ToolSvc += JETM1Akt4JetTPThinningTool
+thinningTools.append(JETM1Akt4JetTPThinningTool)
+
+JETM1Akt4PFlowJetTPThinningTool = DerivationFramework__JetTrackParticleThinning( name          = "JETM1Akt4PFlowJetTPThinningTool",
+                                                                                 StreamName              = streamName,
+                                                                                 JetKey                  = "AntiKt4EMPFlowJets",
+                                                                                 SelectionString         = "AntiKt4EMPFlowJets.pt > 18*GeV",
+                                                                                 InDetTrackParticlesKey  = "InDetTrackParticles",
+                                                                                 ApplyAnd                = False)
+ToolSvc += JETM1Akt4PFlowJetTPThinningTool
+thinningTools.append(JETM1Akt4PFlowJetTPThinningTool)
+
+thinning_expression = "InDetTrackParticles.JETM1DFLoose && ( abs(InDetTrackParticles.d0) < 3.0 ) && ( abs(DFCommonInDetTrackZ0AtPV*sin(InDetTrackParticles.theta)) < 4.0 )"
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TrackParticleThinning
+JETM1TPThinningTool = DerivationFramework__TrackParticleThinning( name                = "JETM1TPThinningTool",
+                                                                  StreamName              = streamName,
+                                                                  SelectionString         = thinning_expression,
+                                                                  InDetTrackParticlesKey  = "InDetTrackParticles",
+                                                                  ApplyAnd        = True)
+ToolSvc += JETM1TPThinningTool
+thinningTools.append(JETM1TPThinningTool)
 
 #=======================================
-# CREATE PRIVATE SEQUENCE
+# Augmentation tools
 #=======================================
 
-jetm1Seq = CfgMgr.AthSequencer("JETM1Sequence")
-DerivationFrameworkJob += jetm1Seq
+augmentationTools = []
+
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__InDetTrackSelectionToolWrapper
+JETM1TrackSelectionTool = DerivationFramework__InDetTrackSelectionToolWrapper(name = "JETM1TrackSelectionTool",
+                                                                              ContainerName = "InDetTrackParticles",
+                                                                              DecorationName = "JETM1DFLoose" )
+
+JETM1TrackSelectionTool.TrackSelectionTool.CutLevel = "Loose"
+ToolSvc += JETM1TrackSelectionTool
+augmentationTools.append(JETM1TrackSelectionTool)
+
 
 #=======================================
-# CREATE THE DERIVATION KERNEL ALGORITHM   
+# CREATE THE DERIVATION KERNEL ALGORITHM
 #=======================================
 
 from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
 jetm1Seq += CfgMgr.DerivationFramework__DerivationKernel("JETM1Kernel" ,
-                                                         SkimmingTools = [JETM1SkimmingTool],
+                                                         AugmentationTools = augmentationTools,
+                                                         SkimmingTools = [JETM1ORTool],
                                                          ThinningTools = thinningTools)
 
 #====================================================================
 # Special jets
 #====================================================================
 
+from TrackCaloClusterRecTools.TrackCaloClusterConfig import runUFOReconstruction
+emufoAlg = runUFOReconstruction(jetm1Seq,ToolSvc, PFOPrefix="CHS")
+emcsskufoAlg = runUFOReconstruction(jetm1Seq,ToolSvc, PFOPrefix="CSSK")
+
+from JetRec.JetRecConf import PseudoJetGetter
+
+csskufopjgetter = PseudoJetGetter("csskufoPJGetter", InputContainer="CSSKUFO", OutputContainer="CSSKUFOPJ", Label="UFO", SkipNegativeEnergy=True)
+jtm+=csskufopjgetter
+
+ufopjgetter     = PseudoJetGetter("ufoPJGetter",     InputContainer="CHSUFO",     OutputContainer="CHSUFOPJ",     Label="UFO", SkipNegativeEnergy=True)
+jtm+=ufopjgetter
+
+# Augment AntiKt4 jets with QG tagging variables
+from DerivationFrameworkJetEtMiss.ExtendedJetCommon import addQGTaggerTool
+addQGTaggerTool(jetalg="AntiKt4EMTopo",sequence=jetm1Seq,algname="QGTaggerToolAlg")
+addQGTaggerTool(jetalg="AntiKt4EMPFlow",sequence=jetm1Seq,algname="QGTaggerToolPFAlg")
+
+# Add alternative rho definitions
+from DerivationFrameworkJetEtMiss.ExtendedJetCommon import addCHSPFlowObjects
+addCHSPFlowObjects()
+from DerivationFrameworkJetEtMiss.JetCommon import defineEDAlg
+jetm1Seq += defineEDAlg(R=0.4, inputtype="EMPFlowPUSB")
+jetm1Seq += defineEDAlg(R=0.4, inputtype="EMPFlowNeut")
+
+#SCHEDULE BTAGGING FOR PFLOW JETS
+from DerivationFrameworkFlavourTag.FlavourTagCommon import FlavorTagInit
+FlavorTagInit(JetCollections=['AntiKt4EMPFlowJets'], Sequencer=jetm1Seq)
+
 OutputJets["JETM1"] = []
 
 #=======================================
@@ -117,82 +182,143 @@ reducedJetList = ["AntiKt2PV0TrackJets",
                   "AntiKt4TruthJets"]
 replaceAODReducedJets(reducedJetList,jetm1Seq,"JETM1")
 
+
+#############################################################################################################################################
+addCHSPFlowObjects()
+addConstModJets("AntiKt", 1.0, "EMPFlow", ["CS", "SK"], jetm1Seq, "JETM1", ptmin=40000, ptminFilter=50000)
+csskufogetters = [csskufopjgetter]+list(jtm.gettersMap["tcc"])[1:]
+chsufogetters = [ufopjgetter]+list(jtm.gettersMap["tcc"])[1:]
+addStandardJets("AntiKt", 1.0, "UFOCSSK", ptmin=40000, ptminFilter=50000, algseq=jetm1Seq, outputGroup="JETM1", customGetters = csskufogetters, constmods=["CSSK"])
+addStandardJets("AntiKt", 1.0, "UFOCHS", ptmin=40000, ptminFilter=50000, algseq=jetm1Seq, outputGroup="JETM1", customGetters = chsufogetters, constmods=["CHS"])
+
 # AntiKt10*PtFrac5Rclus20
 addDefaultTrimmedJets(jetm1Seq,"JETM1")
+addTrimmedJets("AntiKt", 1.0, "EMPFlow", rclus=0.2, ptfrac=0.05, algseq=jetm1Seq, outputGroup="JETM1", writeUngroomed=False, mods="pflow_groomed")
+addTrimmedJets("AntiKt", 1.0, "UFOCHS", rclus=0.2, ptfrac=0.05, algseq=jetm1Seq, outputGroup="JETM1", writeUngroomed=False, mods="tcc_groomed")
+addTrimmedJets("AntiKt", 1.0, "UFOCSSK", rclus=0.2, ptfrac=0.05, algseq=jetm1Seq, outputGroup="JETM1", writeUngroomed=False, mods="tcc_groomed")
+
+if DerivationFrameworkIsMonteCarlo:
+  addSoftDropJets('AntiKt', 1.0, 'Truth', beta=1.0, zcut=0.1, mods="truth_groomed", algseq=jetm1Seq, outputGroup="JETM1", writeUngroomed=True)
+  addRecursiveSoftDropJets('AntiKt', 1.0, 'Truth', beta=1.0, zcut=0.05, N=-1,  mods="truth_groomed", algseq=jetm1Seq, outputGroup="JETM1", writeUngroomed=True)
+  addBottomUpSoftDropJets('AntiKt', 1.0, 'Truth', beta=1.0, zcut=0.05, mods="truth_groomed", algseq=jetm1Seq, outputGroup="JETM1", writeUngroomed=True)
+
+
+
+addSoftDropJets("AntiKt", 1.0, "UFOCHS", beta=1.0, zcut=0.1, algseq=jetm1Seq, outputGroup="JETM1", writeUngroomed=False, mods="tcc_groomed")
+addSoftDropJets("AntiKt", 1.0, "UFOCSSK", beta=1.0, zcut=0.1, algseq=jetm1Seq, outputGroup="JETM1", writeUngroomed=False, mods="tcc_groomed")
+addRecursiveSoftDropJets('AntiKt', 1.0, 'UFOCSSK', beta=1.0, zcut=0.05, N=-1,  mods="tcc_groomed", algseq=jetm1Seq, outputGroup="JETM1", writeUngroomed=False)
+addBottomUpSoftDropJets('AntiKt', 1.0, 'UFOCSSK', beta=1.0, zcut=0.05, mods="tcc_groomed", algseq=jetm1Seq, outputGroup="JETM1", writeUngroomed=False)
+
+
+#############################################################################################################################################
+
+# Add jets with constituent-level pileup suppression
+addConstModJets("AntiKt",0.4,"EMTopo",["CS","SK"],jetm1Seq,"JETM1",
+                ptmin=2000,ptminFilter=2000)
+addConstModJets("AntiKt",0.4,"EMPFlow",["CS","SK"],jetm1Seq,"JETM1",
+                ptmin=2000,ptminFilter=2000)
+
+# Add the BCID info
+addDistanceInTrain(jetm1Seq)
+
+#add pFlow fJVT and MVfJVT for EMTopo
+applyMVfJvtAugmentation(jetalg='AntiKt4EMTopo',sequence=jetm1Seq, algname='JetForwardJvtToolBDTAlg')
+getPFlowfJVT(jetalg='AntiKt4EMPFlow',sequence=jetm1Seq, algname='JetForwardPFlowJvtToolAlg')
 
 #=======================================
 # SCHEDULE SMALL-R JETS WITH LOW PT CUT
 #=======================================
 
 if DerivationFrameworkIsMonteCarlo:
-   from JetRec.JetRecStandard import jtm
-   #EMTopo
-   lowptjetalg = None
-   if "jetalgAntiKt4EMTopoLowPtJets" in DFJetAlgs.keys():
-       lowptjetalg = DFJetAlgs["jetalgAntiKt4EMTopoLowPtJets"]
-   else:
-       jtm.addJetFinder("AntiKt4EMTopoLowPtJets", "AntiKt", 0.4, "emtopo", "emtopo_ungroomed", ghostArea=0.01, ptmin= 2000, ptminFilter= 2000, calibOpt="ar")
-       lowptjetalg = CfgMgr.JetAlgorithm("jetalgAntiKt4EMTopoLowPtJets", Tools = [jtm.AntiKt4EMTopoLowPtJets])
-       DFJetAlgs["jetalgAntiKt4EMTopoLowPtJets"] = lowptjetalg;
-   jetm1Seq += lowptjetalg
-   OutputJets["JETM1"].append("AntiKt4EMTopoLowPtJets")
-   #LCTopo
-   if "jetalgAntiKt4LCTopoLowPtJets" in DFJetAlgs.keys():
-       lowptjetalg = DFJetAlgs["jetalgAntiKt4LCTopoLowPtJets"]
-   else:
-       jtm.addJetFinder("AntiKt4LCTopoLowPtJets", "AntiKt", 0.4, "lctopo", "lctopo_ungroomed", ghostArea=0.01, ptmin= 2000, ptminFilter= 2000, calibOpt="ar")
-       lowptjetalg = CfgMgr.JetAlgorithm("jetalgAntiKt4LCTopoLowPtJets", Tools = [jtm.AntiKt4LCTopoLowPtJets])
-       DFJetAlgs["jetalgAntiKt4LCTopoLowPtJets"] = lowptjetalg;
-   jetm1Seq += lowptjetalg
-   OutputJets["JETM1"].append("AntiKt4LCTopoLowPtJets")
-   #EMPFlow
-   if "jetalgAntiKt4EMPFlowLowPtJets" in DFJetAlgs.keys():
-       lowptjetalg = DFJetAlgs["jetalgAntiKt4EMPFlowLowPtJets"]
-   else:
-       jtm.addJetFinder("AntiKt4EMPFlowLowPtJets", "AntiKt", 0.4, "empflow", "pflow_ungroomed", ghostArea=0.01, ptmin= 2000, ptminFilter= 2000, calibOpt="ar:pflow")
-       lowptjetalg = CfgMgr.JetAlgorithm("jetalgAntiKt4EMPFlowLowPtJets", Tools = [jtm.AntiKt4EMPFlowLowPtJets])
-       DFJetAlgs["jetalgAntiKt4EMPFlowLowPtJets"] = lowptjetalg;
-   jetm1Seq += lowptjetalg
-   OutputJets["JETM1"].append("AntiKt4EMPFlowLowPtJets")
-
-if jetFlags.useTruth:
-    # CamKt R=1.2 jets
-    #addFilteredJets("CamKt", 1.2, "Truth", mumax=1.0, ymin=0.15, algseq=jetm1Seq, outputGroup="JETM1")
-    #addFilteredJets("CamKt", 1.2, "Truth", mumax=1.0, ymin=0.04, algseq=jetm1Seq, outputGroup="JETM1")
-    pass
-
-# CamKt R=1.2 jets
-#addFilteredJets("CamKt", 1.2, "LCTopo", mumax=1.0, ymin=0.15, algseq=jetm1Seq, outputGroup="JETM1")
-#addFilteredJets("CamKt", 1.2, "LCTopo", mumax=1.0, ymin=0.04, algseq=jetm1Seq, outputGroup="JETM1")
+    addAntiKt4NoPtCutJets(jetm1Seq,"JETM1")
+    ## Add GhostTruthAssociation information ##
+    addJetPtAssociation(jetalg="AntiKt4EMTopo",  truthjetalg="AntiKt4TruthJets", sequence=jetm1Seq, algname="JetPtAssociationAlg")
+    addJetPtAssociation(jetalg="AntiKt4LCTopo",  truthjetalg="AntiKt4TruthJets", sequence=jetm1Seq, algname="JetPtAssociationAlg")
+    addJetPtAssociation(jetalg="AntiKt4EMPFlow", truthjetalg="AntiKt4TruthJets", sequence=jetm1Seq, algname="JetPtAssociationAlg")
+    addJetPtAssociation(jetalg="AntiKt4EMTopoNoPtCut",  truthjetalg="AntiKt4TruthJets", sequence=jetm1Seq, algname="JetPtAssociationAlgNoPtCut")
+    #Commenting for now as if disabled the building of this jet container in addAntiKt4NoPtCutJets, working on the reoptimisation of LCW at the moment
+    #addJetPtAssociation(jetalg="AntiKt4LCTopoNoPtCut",  truthjetalg="AntiKt4TruthJets", sequence=jetm1Seq, algname="JetPtAssociationAlgNoPtCut")
+    addJetPtAssociation(jetalg="AntiKt4EMPFlowNoPtCut", truthjetalg="AntiKt4TruthJets", sequence=jetm1Seq, algname="JetPtAssociationAlgNoPtCut")
+    addJetPtAssociation(jetalg="AntiKt4EMTopoCSSK",  truthjetalg="AntiKt4TruthJets", sequence=jetm1Seq, algname="JetPtAssociationAlgCSSK")
+    addJetPtAssociation(jetalg="AntiKt4EMPFlowCSSK", truthjetalg="AntiKt4TruthJets", sequence=jetm1Seq, algname="JetPtAssociationAlgCSSK")
 
 #====================================================================
 # Add the containers to the output stream - slimming done here
 #====================================================================
 from DerivationFrameworkCore.SlimmingHelper import SlimmingHelper
 JETM1SlimmingHelper = SlimmingHelper("JETM1SlimmingHelper")
+JETM1SlimmingHelper.AppendToDictionary = {
+    "Kt4EMPFlowPUSBEventShape": "xAOD::EventShape"    ,
+    "Kt4EMPFlowPUSBEventShapeAux": "xAOD::AuxInfoBase"    ,
+    "Kt4EMPFlowNeutEventShape": "xAOD::EventShape"    ,
+    "Kt4EMPFlowNeutEventShapeAux": "xAOD::AuxInfoBase"    ,
+
+}
+
 JETM1SlimmingHelper.SmartCollections = ["Electrons", "Photons", "Muons", "PrimaryVertices",
                                         "AntiKt4EMTopoJets","AntiKt4LCTopoJets","AntiKt4EMPFlowJets",
+                                        "AntiKt10UFOCSSKJets",
+                                        "AntiKt10UFOCHSJets",
                                         "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets",
-                                        "BTagging_AntiKt4EMTopo",
-                                        "BTagging_AntiKt2Track",
+                                        "AntiKt10EMPFlowTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10UFOCHSTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10UFOCSSKTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10UFOCHSSoftDropBeta100Zcut10Jets",
+                                        "AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets",
+                                        "AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5Jets",
+                                        "AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJets",
+                                        "AntiKt4EMPFlowJets_BTagging201810",
+                                        "AntiKt4EMPFlowJets_BTagging201903",
+                                        "AntiKt4EMTopoJets_BTagging201810",
+                                        "BTagging_AntiKt4EMPFlow_201810",
+                                        "BTagging_AntiKt4EMPFlow_201903",
+                                        "BTagging_AntiKt4EMTopo_201810",
                                         ]
-JETM1SlimmingHelper.AllVariables = [ "MuonTruthParticles", "egammaTruthParticles",
-                                     "TruthParticles", "TruthEvents", "TruthVertices",
-                                     "MuonSegments",
-                                     "Kt4EMTopoOriginEventShape","Kt4LCTopoOriginEventShape","Kt4EMPFlowEventShape",
-                                     ]
-#JETM1SlimmingHelper.ExtraVariables = []
+
+# Add QG tagger variables
+JETM1SlimmingHelper.ExtraVariables  += ["AntiKt4EMTopoJets.DFCommonJets_QGTagger_NTracks.DFCommonJets_QGTagger_TracksWidth.DFCommonJets_QGTagger_TracksC1",
+                                        "AntiKt4EMPFlowJets.DFCommonJets_QGTagger_NTracks.DFCommonJets_QGTagger_TracksWidth.DFCommonJets_QGTagger_TracksC1"]
+JETM1SlimmingHelper.ExtraVariables  += ["InDetTrackParticles.truthMatchProbability"]
+
+JETM1SlimmingHelper.ExtraVariables += ["AntiKt10UFOCSSKTrimmedPtFrac5SmallR20Jets.zg.rg.NumTrkPt1000.TrackWidthPt1000.GhostMuonSegmentCount.EnergyPerSampling.GhostTrack",
+                                       "AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJets.zg.rg.NumTrkPt1000.TrackWidthPt1000.GhostMuonSegmentCount.EnergyPerSampling.GhostTrack",
+                                       "AntiKt10UFOCHSTrimmedPtFrac5SmallR20Jets.zg.rg",
+                                       "AntiKt10EMPFlowTrimmedPtFrac5SmallR20Jets.zg.rg",
+                                       "AntiKt10UFOCHSSoftDropBeta100Zcut10Jets.zg.rg",
+                                       "AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets.zg.rg.NumTrkPt1000.TrackWidthPt1000.GhostMuonSegmentCount.EnergyPerSampling.GhostTrack",
+                                       "AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5Jets.zg.rg.NumTrkPt1000.TrackWidthPt1000.GhostMuonSegmentCount.EnergyPerSampling.GhostTrack",
+                                       "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets.zg.rg",
+                                       "AntiKt10UFOCSSKJets.NumTrkPt1000.TrackWidthPt1000.GhostMuonSegmentCount.EnergyPerSampling.GhostTrack"]
+
+JETM1SlimmingHelper.AllVariables = [ "MuonSegments", "TruthVertices",
+                                     "Kt4EMTopoOriginEventShape","Kt4LCTopoOriginEventShape","Kt4EMPFlowEventShape","Kt4EMPFlowPUSBEventShape","Kt4EMPFlowNeutEventShape"]
 
 # Trigger content
 JETM1SlimmingHelper.IncludeJetTriggerContent = True
 
 # Add the jet containers to the stream
-addJetOutputs(JETM1SlimmingHelper,["SmallR","JETM1"],[], # smart list
+addJetOutputs(JETM1SlimmingHelper,["SmallR","JETM1"],["AntiKt10UFOCSSKJets",
+                                                      "AntiKt10UFOCHSJets",
+                                                      "AntiKt10EMPFlowTrimmedPtFrac5SmallR20Jets",
+                                                      "AntiKt10UFOCHSTrimmedPtFrac5SmallR20Jets",
+                                                      "AntiKt10UFOCSSKTrimmedPtFrac5SmallR20Jets",
+                                                      "AntiKt10UFOCHSSoftDropBeta100Zcut10Jets",
+                                                      "AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets",
+                                                      "AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5Jets",
+                                                      "AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJets",
+                                                     ], # smart list
               [
-               "AntiKt4TruthWZJets",
-               ]# veto list
+               "AntiKt4TruthWZJets", "AntiKt10EMPFlowJets", "AntiKt10EMPFlowCSSKJets"
+               ]# veto list,
               )
 
+if DerivationFrameworkIsMonteCarlo:
+    JETM1SlimmingHelper.AllVariables += ["TruthMuons", "TruthElectrons", "TruthPhotons"]
+    for truthc in ["TruthTop", "TruthBoson"]:
+        JETM1SlimmingHelper.StaticContent.append("xAOD::TruthParticleContainer#"+truthc)
+        JETM1SlimmingHelper.StaticContent.append("xAOD::TruthParticleAuxContainer#"+truthc+"Aux.")
+
+
 JETM1SlimmingHelper.AppendContentToStream(JETM1Stream)
 JETM1Stream.RemoveItem("xAOD::TrigNavigation#*")
 JETM1Stream.RemoveItem("xAOD::TrigNavigationAuxInfo#*")
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM10.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM10.py
index 077de8c1ca5dc74b161401fb067300a8fb25e5ad..a26e1625ddd2d31bb152fbb30e18436ebfc52c6a 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM10.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM10.py
@@ -6,27 +6,16 @@ from DerivationFrameworkCore.DerivationFrameworkMaster import *
 from DerivationFrameworkJetEtMiss.JetCommon import *
 from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
 from DerivationFrameworkJetEtMiss.METCommon import *
+from DerivationFrameworkJetEtMiss.METTriggerDerivationContent import METTriggerDerivationContentManager
 
 #======================================================================================================================
 # SKIMMING TOOL
 #======================================================================================================================
 from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__TriggerSkimmingTool
 JETM10SkimmingTool = DerivationFramework__TriggerSkimmingTool(  name                   = "JETM10SkimmingTool",
-                                                                TriggerListOR          = ["HLT_noalg_L1XE30", "HLT_noalg_L1XE40", "HLT_noalg_L1XE45"] )
+                                                                TriggerListOR          = ["HLT_noalg_L1XE.*"] )
 ToolSvc += JETM10SkimmingTool
 
-#======================================================================================================================
-# AUGMENTATION  TOOL
-#======================================================================================================================
-from DerivationFrameworkJetEtMiss.DerivationFrameworkJetEtMissConf import DerivationFramework__METTriggerAugmentationTool
-JETM10KFData15AugmentationTool = DerivationFramework__METTriggerAugmentationTool(name = "JETM10KFData15AugmentationTool", #NB: data15 refers to the dataset used to form the look up table, not the intended target
-                                                                                 OutputName = "LVL1EnergySumRoI_KFMETData15",
-                                                                                 LUTFile = "LUT_data15.root")
-ToolSvc += JETM10KFData15AugmentationTool
-JETM10KFmc12AugmentationTool = DerivationFramework__METTriggerAugmentationTool(name = "JETM10KFmc12AugmentationTool", #NB: mc12 refers to the dataset used to form the look up table, not the intended target
-                                                                                 OutputName = "LVL1EnergySumRoI_KFMETmc12",
-                                                                                 LUTFile = "LUT_mc12.root")
-ToolSvc += JETM10KFmc12AugmentationTool
 
 #======================================================================================================================
 # SET UP STREAM
@@ -36,66 +25,8 @@ fileName = buildFileName( derivationFlags.WriteDAOD_JETM10Stream )
 JETM10Stream = MSMgr.NewPoolRootStream( streamName, fileName )
 JETM10Stream.AcceptAlgs(['JETM10Kernel'])
 
-#=======================================
-# ESTABLISH THE THINNING HELPER
-#=======================================
-from DerivationFrameworkCore.ThinningHelper import ThinningHelper
-JETM10ThinningHelper = ThinningHelper( "JETM10ThinningHelper" )
-# JETM10ThinningHelper.TriggerChains = ('L1_XE.*|L1_XS.*|L1_TE.*|HLT_xe.*|HLT_xs.*|HLT_te.*|'
-#                                       'HLT_e26_lhvloose_L1EM20VH.*|HLT_e\\d\\d_(lhvloose|vloose)|'
-#                                       'HLT_mu20_iloose.*|HLT_mu50|HLT_e24_lhmedium_iloose_L1_EM20VH|'
-#                                       'HLT_e60_lhmedium|L1_J.*XE.*|HLT_j.*xe.*')
-JETM10ThinningHelper.AppendToStream( JETM10Stream )
-
-#======================================================================================================================
-# THINNING TOOLS
-#======================================================================================================================
-thinningTools = []
-
-# TrackParticles directly
-from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TrackParticleThinning
-JETM10TPThinningTool = DerivationFramework__TrackParticleThinning(name = "JETM10TPThinningTool",
-                                                                       StreamName              = streamName,
-                                                                       SelectionString         = "InDetTrackParticles.pt > 10*GeV",
-                                                                       InDetTrackParticlesKey  = "InDetTrackParticles") 
-ToolSvc += JETM10TPThinningTool
-thinningTools.append(JETM10TPThinningTool)
-  
-# TrackParticles associated with Muons
-from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__MuonTrackParticleThinning
-JETM10MuonTPThinningTool = DerivationFramework__MuonTrackParticleThinning(name                    = "JETM10MuonTPThinningTool",
-                                                                               StreamName              = streamName,
-                                                                               MuonKey                 = "Muons",
-                                                                               InDetTrackParticlesKey  = "InDetTrackParticles")
-ToolSvc += JETM10MuonTPThinningTool
-thinningTools.append(JETM10MuonTPThinningTool)
-
-# TrackParticles associated with electrons
-from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__EgammaTrackParticleThinning
-JETM10ElectronTPThinningTool = DerivationFramework__EgammaTrackParticleThinning(name                     = "JETM10ElectronTPThinningTool",
-                                                                                     StreamName              = streamName,
-                                                                                     SGKey                    = "Electrons",
-                                                                                     InDetTrackParticlesKey   = "InDetTrackParticles")
-ToolSvc += JETM10ElectronTPThinningTool
-thinningTools.append(JETM10ElectronTPThinningTool)
-
-# TrackParticles associated with photons
-from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__EgammaTrackParticleThinning
-JETM10PhotonTPThinningTool = DerivationFramework__EgammaTrackParticleThinning(name                        = "JETM10PhotonTPThinningTool",
-                                                                                   StreamName              = streamName,
-                                                                                   SGKey                       = "Photons",
-                                                                                   InDetTrackParticlesKey      = "InDetTrackParticles")
-ToolSvc += JETM10PhotonTPThinningTool
-thinningTools.append(JETM10PhotonTPThinningTool)
-
-# TrackParticles associated with taus
-from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TauTrackParticleThinning
-JETM10TauTPThinningTool = DerivationFramework__TauTrackParticleThinning( name                    = "JETM10TauTPThinningTool",
-                                                                              StreamName              = streamName,
-                                                                              TauKey                  = "TauJets",
-                                                                              InDetTrackParticlesKey  = "InDetTrackParticles")
-ToolSvc += JETM10TauTPThinningTool
-thinningTools.append(JETM10TauTPThinningTool)
+content_manager = METTriggerDerivationContentManager.make_loose_manager(
+        "JETM10", JETM10Stream)
 
 #======================================================================================================================
 # CREATE PRIVATE SEQUENCE
@@ -106,37 +37,5 @@ DerivationFrameworkJob += jetm10Seq
 #=======================================
 # CREATE THE DERIVATION KERNEL ALGORITHM   
 #=======================================
-from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
-jetm10Seq += CfgMgr.DerivationFramework__DerivationKernel('JETM10Kernel',
-                                                          SkimmingTools = [JETM10SkimmingTool],
-                                                          AugmentationTools = [JETM10KFData15AugmentationTool, JETM10KFmc12AugmentationTool],
-                                                          ThinningTools = thinningTools)
-
-#======================================================================================================================
-# Content list for slimming
-#======================================================================================================================
-from DerivationFrameworkCore.SlimmingHelper import SlimmingHelper
-JETM10SlimmingHelper = SlimmingHelper('JETM10SlimmingHelper')
-JETM10SlimmingHelper.SmartCollections = ["Electrons", "Muons", "Photons", "TauJets",
-                                         "AntiKt4EMTopoJets", "PrimaryVertices", "BTagging_AntiKt4EMTopo"]
-JETM10SlimmingHelper.AllVariables =     ["HLT_xAOD__TrigMissingETContainer_TrigEFMissingET_topocl_PS",
-                                         "HLT_xAOD__TrigMissingETContainer_TrigEFMissingET_mht",
-                                         "HLT_xAOD__TrigMissingETContainer_TrigEFMissingET_topocl_PUC",
-                                         "HLT_xAOD__TrigMissingETContainer_TrigEFMissingET_topocl",
-                                         "HLT_xAOD__TrigMissingETContainer_TrigEFMissingET",
-                                         "HLT_xAOD__JetContainer_a4tclcwsubjesFS",
-                                         "LVL1JetRoIs",
-                                         "LVL1JetEtRoI",
-                                         "LVL1EnergySumRoI_KFMETData15", 
-                                         "LVL1EnergySumRoI_KFMETmc12",
-                                         "MET_Core_AntiKt4EMTopo",
-                                         "METAssoc_AntiKt4EMTopo"]
-JETM10SlimmingHelper.IncludeJetTriggerContent = True
-JETM10SlimmingHelper.IncludeEtMissTriggerContent = True
-JETM10SlimmingHelper.AppendContentToStream(JETM10Stream)
-
-#======================================================================================================================
-# Content Definition
-#======================================================================================================================
-#JETM10Stream.AddItem("std::vector<float>#JETM10KFEx");
-#JETM10Stream.AddItem("std::vector<float>#JETM10KFEy");
+jetm10Seq += content_manager.make_kernel(JETM10SkimmingTool)
+content_manager.slimming_helper.AppendContentToStream(JETM10Stream)
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM11.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM11.py
index f462f769330b749908cbc1f0e8b33882f6a70004..fd2b32de69acb8bd2377b2c860b545c56c866f19 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM11.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM11.py
@@ -6,8 +6,10 @@ from DerivationFrameworkCore.DerivationFrameworkMaster import *
 from DerivationFrameworkJetEtMiss.JetCommon import *
 from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
 from DerivationFrameworkJetEtMiss.METCommon import *
+from DerivationFrameworkJetEtMiss import TriggerLists
 from DerivationFrameworkEGamma.EGammaCommon import*
 from DerivationFrameworkMuons.MuonsCommon import*
+from DerivationFrameworkJetEtMiss.METTriggerDerivationContent import METTriggerDerivationContentManager
 
 #======================================================================================================================
 # SET UP STREAM
@@ -17,91 +19,27 @@ fileName = buildFileName( derivationFlags.WriteDAOD_JETM11Stream )
 JETM11Stream = MSMgr.NewPoolRootStream( streamName, fileName )
 JETM11Stream.AcceptAlgs(['JETM11Kernel'])
 
-
 #======================================================================================================================
 # SKIMMING TOOL
 #======================================================================================================================
-cutExpression = ("(count(Electrons.DFCommonElectronsLHLoose && Electrons.pt > (10*GeV) && abs(Electrons.eta) < 2.47) + " +
-                 "count(Muons.DFCommonMuonsPreselection && Muons.pt > (10*GeV) && abs(Muons.eta) < 2.47)) >=1")
 from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__xAODStringSkimmingTool
-JETM11StringSkimmingTool = DerivationFramework__xAODStringSkimmingTool(name = "JETM11StringSkimmingTool",
-                                                                       expression = cutExpression)
+from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__TriggerSkimmingTool
+# cutExpression = "(count(Electrons.DFCommonElectronsLHLoose && Electrons.DFCommonElectrons_pt > (20 * GeV) && abs(Electrons.DFCommonElectrons_eta) < 2.47) + count(Muons.DFCommonMuonsPreselection && Muons.pt > (20*GeV) && abs(Muon.eta) < 2.47) ) >= 1"
+singleElTriggers = TriggerLists.single_el_Trig()
+singleMuTriggers = TriggerLists.single_mu_Trig()
+cutExpression = "(count(Electrons.DFCommonElectronsLHLoose && Electrons.pt > (24 * GeV) && abs(Electrons.eta) < 2.47) + count(Muons.DFCommonMuonsPreselection && Muons.pt > (24*GeV) && abs(Muons.eta) < 2.47) ) >= 1"
+JETM11StringSkimmingTool = DerivationFramework__xAODStringSkimmingTool(
+    name       = "JETM11StringSkimmingTool",
+    expression = cutExpression)
+JETM11TriggerSkimmingTool = DerivationFramework__TriggerSkimmingTool(
+    name          = "JETM11TriggerSkimmingTool",
+    TriggerListOR = singleElTriggers + singleMuTriggers)
 ToolSvc += JETM11StringSkimmingTool
-printfunc (JETM11StringSkimmingTool)
-
-#======================================================================================================================
-# AUGMENTATION TOOL
-#======================================================================================================================
-from DerivationFrameworkJetEtMiss.DerivationFrameworkJetEtMissConf import DerivationFramework__METTriggerAugmentationTool
-JETM11KFData15AugmentationTool = DerivationFramework__METTriggerAugmentationTool(name = "JETM11KFData15AugmentationTool", #NB: data15 refers to the dataset used to form the look up table, not the intended target
-                                                                                 OutputName = "LVL1EnergySumRoI_KFMETData15",
-                                                                                 LUTFile = "LUT_data15.root")
-ToolSvc += JETM11KFData15AugmentationTool
-JETM11KFmc12AugmentationTool = DerivationFramework__METTriggerAugmentationTool(name = "JETM11KFmc12AugmentationTool", #NB: mc12 refers to the dataset used to form the look up table, not the intended target
-                                                                                 OutputName = "LVL1EnergySumRoI_KFMETmc12",
-                                                                                 LUTFile = "LUT_mc12.root")
-ToolSvc += JETM11KFmc12AugmentationTool
-
-#=======================================
-# ESTABLISH THE THINNING HELPER
-#=======================================
-from DerivationFrameworkCore.ThinningHelper import ThinningHelper
-JETM11ThinningHelper = ThinningHelper( "JETM11ThinningHelper" )
-# JETM11ThinningHelper.TriggerChains = ('L1_XE.*|L1_XS.*|L1_TE.*|HLT_xe.*|HLT_xs.*|HLT_te.*|'
-#                                       'HLT_e26_lhvloose_L1EM20VH.*|HLT_e\\d\\d_(lhvloose|vloose)|'
-#                                       'HLT_mu20_iloose.*|HLT_mu50|HLT_e24_lhmedium_iloose_L1_EM20VH|'
-#                                       'HLT_e60_lhmedium|L1_J.*XE.*|HLT_j.*xe.*')
-JETM11ThinningHelper.AppendToStream( JETM11Stream )
-
-#======================================================================================================================
-# THINNING TOOLS
-#======================================================================================================================
-thinningTools = []
-
-# TrackParticles directly
-from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TrackParticleThinning
-JETM11TPThinningTool = DerivationFramework__TrackParticleThinning(name = "JETM11TPThinningTool",
-                                                                  StreamName              = streamName,
-                                                                  SelectionString         = "InDetTrackParticles.pt > 10*GeV",
-                                                                  InDetTrackParticlesKey  = "InDetTrackParticles") 
-ToolSvc += JETM11TPThinningTool
-thinningTools.append(JETM11TPThinningTool)
-  
-# TrackParticles associated with Muons
-from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__MuonTrackParticleThinning
-JETM11MuonTPThinningTool = DerivationFramework__MuonTrackParticleThinning(name                    = "JETM11MuonTPThinningTool",
-                                                                          StreamName              = streamName,
-                                                                          MuonKey                 = "Muons",
-                                                                          InDetTrackParticlesKey  = "InDetTrackParticles")
-ToolSvc += JETM11MuonTPThinningTool
-thinningTools.append(JETM11MuonTPThinningTool)
-
-# TrackParticles associated with electrons
-from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__EgammaTrackParticleThinning
-JETM11ElectronTPThinningTool = DerivationFramework__EgammaTrackParticleThinning(name                     = "JETM11ElectronTPThinningTool",
-                                                                                StreamName              = streamName,
-                                                                                SGKey                    = "Electrons",
-                                                                                InDetTrackParticlesKey   = "InDetTrackParticles")
-ToolSvc += JETM11ElectronTPThinningTool
-thinningTools.append(JETM11ElectronTPThinningTool)
+ToolSvc += JETM11TriggerSkimmingTool
 
-# TrackParticles associated with photons
-from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__EgammaTrackParticleThinning
-JETM11PhotonTPThinningTool = DerivationFramework__EgammaTrackParticleThinning(name                        = "JETM11PhotonTPThinningTool",
-                                                                              StreamName              = streamName,
-                                                                              SGKey                       = "Photons",
-                                                                              InDetTrackParticlesKey      = "InDetTrackParticles")
-ToolSvc += JETM11PhotonTPThinningTool
-thinningTools.append(JETM11PhotonTPThinningTool)
 
-# TrackParticles associated with taus
-from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TauTrackParticleThinning
-JETM11TauTPThinningTool = DerivationFramework__TauTrackParticleThinning( name                    = "JETM11TauTPThinningTool",
-                                                                         StreamName              = streamName,
-                                                                         TauKey                  = "TauJets",
-                                                                         InDetTrackParticlesKey  = "InDetTrackParticles")
-ToolSvc += JETM11TauTPThinningTool
-thinningTools.append(JETM11TauTPThinningTool)
+content_manager = METTriggerDerivationContentManager.make_tight_manager(
+        "JETM11", JETM11Stream)
 
 #======================================================================================================================
 # CREATE PRIVATE SEQUENCE
@@ -112,38 +50,6 @@ DerivationFrameworkJob += jetm11Seq
 #=======================================
 # CREATE THE DERIVATION KERNEL ALGORITHM   
 #=======================================
-from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
-jetm11Seq += CfgMgr.DerivationFramework__DerivationKernel('JETM11Kernel',
-                                                          SkimmingTools = [JETM11StringSkimmingTool],
-                                                          AugmentationTools = [JETM11KFData15AugmentationTool, JETM11KFmc12AugmentationTool],
-                                                          ThinningTools = thinningTools)
+jetm11Seq += content_manager.make_kernel(JETM11StringSkimmingTool, JETM11TriggerSkimmingTool)
 
-#======================================================================================================================
-# Content list for slimming
-#======================================================================================================================
-from DerivationFrameworkCore.SlimmingHelper import SlimmingHelper
-JETM11SlimmingHelper = SlimmingHelper('JETM11SlimmingHelper')
-JETM11SlimmingHelper.SmartCollections = ["Electrons", "Muons", "Photons", "TauJets",
-                                         "AntiKt4EMTopoJets", "PrimaryVertices", "BTagging_AntiKt4EMTopo"]
-JETM11SlimmingHelper.AllVariables =     ["HLT_xAOD__TrigMissingETContainer_TrigEFMissingET_topocl_PS",
-                                         "HLT_xAOD__TrigMissingETContainer_TrigEFMissingET_mht",
-                                         "HLT_xAOD__TrigMissingETContainer_TrigEFMissingET_topocl_PUC",
-                                         "HLT_xAOD__TrigMissingETContainer_TrigEFMissingET_topocl",
-                                         "HLT_xAOD__TrigMissingETContainer_TrigEFMissingET",
-                                         "HLT_xAOD__JetContainer_a4tclcwsubjesFS",
-                                         "LVL1JetRoIs",
-                                         "LVL1JetEtRoI",
-                                         "LVL1EnergySumRoI_KFMETData15", 
-                                         "LVL1EnergySumRoI_KFMETmc12",
-                                         "MET_Core_AntiKt4EMTopo",
-                                         "METAssoc_AntiKt4EMTopo"]
-JETM11SlimmingHelper.IncludeJetTriggerContent = True
-JETM11SlimmingHelper.IncludeEtMissTriggerContent = True
-JETM11SlimmingHelper.AppendContentToStream(JETM11Stream)
-
-
-#======================================================================================================================
-# Content Definition
-#======================================================================================================================
-# JETM11Stream.AddItem("std::vector<float>#JETM11KFEx");
-# JETM11Stream.AddItem("std::vector<float>#JETM11KFEy");
+content_manager.slimming_helper.AppendContentToStream(JETM11Stream)
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM12.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM12.py
new file mode 100644
index 0000000000000000000000000000000000000000..c83d0322e54e348bd244ef99fc5215e2e6c6a886
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM12.py
@@ -0,0 +1,241 @@
+#====================================================================
+# JETM12.py 
+# reductionConf flag JETM12 in Reco_tf.py   
+#====================================================================
+
+from DerivationFrameworkCore.DerivationFrameworkMaster import *
+from DerivationFrameworkInDet.InDetCommon import *
+from DerivationFrameworkJetEtMiss.JetCommon import *
+from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
+from DerivationFrameworkEGamma.EGammaCommon import *
+from DerivationFrameworkMuons.MuonsCommon import *
+from DerivationFrameworkJetEtMiss.METCommon import *
+#
+
+#====================================================================
+# SKIMMING TOOL 
+#====================================================================
+
+from DerivationFrameworkJetEtMiss import TriggerLists
+metTriggers = TriggerLists.MET_Trig()
+muTriggers = TriggerLists.single_mu_Trig()
+orstr  = ' || '
+andstr = ' && '
+trackRequirements = '(InDetTrackParticles.pt > 10.*GeV && InDetTrackParticles.TrkIsoPt1000_ptcone20 < 0.12*InDetTrackParticles.pt && InDetTrackParticles.DFCommonTightPrimary && abs(DFCommonInDetTrackZ0AtPV) < 3.0*mm )'
+trackRequirementsMu = '(InDetTrackParticles.pt > 70.*GeV && InDetTrackParticles.TrkIsoPt1000_ptcone20 < 0.12*InDetTrackParticles.pt && InDetTrackParticles.DFCommonTightPrimary && abs(DFCommonInDetTrackZ0AtPV) < 3.0*mm )'
+trackRequirementsTtbar = '(InDetTrackParticles.pt > 25.*GeV && InDetTrackParticles.TrkIsoPt1000_ptcone20 < 0.12*InDetTrackParticles.pt && InDetTrackParticles.DFCommonTightPrimary && abs(DFCommonInDetTrackZ0AtPV) < 3.0*mm )'
+jetRequirementsTtbar = '( AntiKt4EMTopoJets.DFCommonJets_Calib_pt > 20*GeV && BTagging_AntiKt4EMTopo_201810.MV2c10_discriminant > 0.11 )'
+expressionW = '( (' + orstr.join(metTriggers) + ' )' + andstr + '( count('+trackRequirements+') >=1 ) )'
+expressionMu = '( (' + orstr.join(muTriggers) + ' )' + andstr + '( count('+trackRequirementsMu+') >=1 ) )'
+expressionTtbar = '( (' + orstr.join(muTriggers) + ' )' + andstr + '( count('+trackRequirementsTtbar+') >=1 )' + andstr + '( count('+trackRequirements+') >=2 )' + andstr + '( count('+jetRequirementsTtbar+') >=1 ) )'
+expression = '( '+expressionW+' || '+expressionMu+' || '+expressionTtbar+' )'
+
+from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__xAODStringSkimmingTool
+JETM12SkimmingTool = DerivationFramework__xAODStringSkimmingTool( name = "JETM12SkimmingTool1",
+                                                                    expression = expression)
+ToolSvc += JETM12SkimmingTool
+
+#====================================================================
+# SET UP STREAM   
+#====================================================================
+streamName = derivationFlags.WriteDAOD_JETM12Stream.StreamName
+fileName   = buildFileName( derivationFlags.WriteDAOD_JETM12Stream )
+JETM12Stream = MSMgr.NewPoolRootStream( streamName, fileName )
+JETM12Stream.AcceptAlgs(["JETM12Kernel"])
+
+#=======================================
+# ESTABLISH THE THINNING HELPER
+#=======================================
+
+from DerivationFrameworkCore.ThinningHelper import ThinningHelper
+JETM12ThinningHelper = ThinningHelper( "JETM12ThinningHelper" )
+JETM12ThinningHelper.AppendToStream( JETM12Stream )
+
+thinningTools = []
+AugmentationToolsSkim   = []
+AugmentationTools   = []
+
+#====================================================================
+# ISOLATION TOOL 
+#====================================================================
+#Track selection
+from IsolationTool.IsolationToolConf import xAOD__TrackIsolationTool
+TrackIsoTool = xAOD__TrackIsolationTool("TrackIsoTool")
+TrackIsoTool.TrackSelectionTool.maxZ0SinTheta= 3.
+TrackIsoTool.TrackSelectionTool.minPt= 1000.
+TrackIsoTool.TrackSelectionTool.CutLevel= "Loose"
+ToolSvc += TrackIsoTool
+
+TrackIsoTool500 = xAOD__TrackIsolationTool("TrackIsoTool500")
+TrackIsoTool500.TrackSelectionTool.maxZ0SinTheta= 3.
+TrackIsoTool500.TrackSelectionTool.minPt= 500.
+TrackIsoTool500.TrackSelectionTool.CutLevel= "Loose"
+ToolSvc += TrackIsoTool500
+
+from DerivationFrameworkSUSY.DerivationFrameworkSUSYConf import DerivationFramework__trackIsolationDecorator
+import ROOT, cppyy
+cppyy.loadDictionary('xAODCoreRflxDict')
+cppyy.loadDictionary('xAODPrimitivesDict')
+isoPar = ROOT.xAOD.Iso
+Pt1000IsoTrackDecorator = DerivationFramework__trackIsolationDecorator(name = "Pt1000IsoTrackDecorator",
+                                                                TrackIsolationTool = TrackIsoTool,
+                                                                TargetContainer = "InDetTrackParticles",
+                                                                ptcones = [isoPar.ptcone40,isoPar.ptcone30,isoPar.ptcone20],
+                                                                Prefix = 'TrkIsoPt1000_'
+                                                               )
+Pt500IsoTrackDecorator = DerivationFramework__trackIsolationDecorator(name = "Pt500IsoTrackDecorator",
+                                                                TrackIsolationTool = TrackIsoTool500,
+                                                                TargetContainer = "InDetTrackParticles",
+                                                                ptcones = [isoPar.ptcone40,isoPar.ptcone30,isoPar.ptcone20],
+                                                                Prefix = 'TrkIsoPt500_'
+                                                               )
+ToolSvc += Pt1000IsoTrackDecorator
+ToolSvc += Pt500IsoTrackDecorator
+
+AugmentationToolsSkim.append(Pt1000IsoTrackDecorator)
+AugmentationTools.append(Pt500IsoTrackDecorator)
+
+#====================================================================
+# THINNING TOOLS 
+#====================================================================
+# TrackParticles directly
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TrackParticleThinning
+JETM12TPThinningTool = DerivationFramework__TrackParticleThinning(name = "JETM12TPThinningTool",
+                                                                 StreamName              = streamName,
+                                                                 SelectionString         = "( InDetTrackParticles.pt > 10*GeV && InDetTrackParticles.DFCommonTightPrimary && abs(DFCommonInDetTrackZ0AtPV) < 3.0*mm )",
+                                                                 InDetTrackParticlesKey  = "InDetTrackParticles")
+ToolSvc += JETM12TPThinningTool
+thinningTools.append(JETM12TPThinningTool)
+
+# TrackParticles associated with Muons
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__MuonTrackParticleThinning
+JETM12MuonTPThinningTool = DerivationFramework__MuonTrackParticleThinning(name     = "JETM12MuonTPThinningTool",
+                                                                    StreamName              = streamName,
+                                                                    MuonKey                 = "Muons",
+                                                                    InDetTrackParticlesKey  = "InDetTrackParticles")
+ToolSvc += JETM12MuonTPThinningTool
+thinningTools.append(JETM12MuonTPThinningTool)
+
+# TrackParticles associated with electrons
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__EgammaTrackParticleThinning
+JETM12ElectronTPThinningTool = DerivationFramework__EgammaTrackParticleThinning(name                    = "JETM12ElectronTPThinningTool",
+                                                                               StreamName              = streamName,
+                                                                               SGKey                   = "Electrons",
+                                                                               InDetTrackParticlesKey  = "InDetTrackParticles")
+ToolSvc += JETM12ElectronTPThinningTool
+thinningTools.append(JETM12ElectronTPThinningTool)
+
+# TrackParticles associated with photons
+JETM12PhotonTPThinningTool = DerivationFramework__EgammaTrackParticleThinning(name                    = "JETM12PhotonTPThinningTool",
+                                                                             StreamName              = streamName,
+                                                                             SGKey                   = "Photons",
+                                                                             InDetTrackParticlesKey  = "InDetTrackParticles")
+ToolSvc += JETM12PhotonTPThinningTool
+thinningTools.append(JETM12PhotonTPThinningTool)
+
+# TrackParticles associated with taus
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TauTrackParticleThinning
+JETM12TauTPThinningTool = DerivationFramework__TauTrackParticleThinning( name            = "JETM12TauTPThinningTool",
+                                                                        StreamName      = streamName,
+                                                                        TauKey          = "TauJets",
+                                                                        InDetTrackParticlesKey  = "InDetTrackParticles")
+ToolSvc += JETM12TauTPThinningTool
+thinningTools.append(JETM12TauTPThinningTool)
+
+##################################
+# CaloCalTopoCluster thinning
+from DerivationFrameworkCalo.DerivationFrameworkCaloConf import DerivationFramework__CaloClusterThinning
+JETM12CaloClusterThinning  = DerivationFramework__CaloClusterThinning(name                  = "JETM12CaloClusterThinning",
+                                                                       StreamName            = streamName,
+                                                                       SGKey                 = "InDetTrackParticles",
+                                                                       TopoClCollectionSGKey = "CaloCalTopoClusters",
+                                                                       SelectionString = "( InDetTrackParticles.pt > 10*GeV && InDetTrackParticles.DFCommonTightPrimary && abs(DFCommonInDetTrackZ0AtPV) < 3.0*mm )",
+                                                                       ConeSize = 0.6,
+                                                                       )
+ToolSvc += JETM12CaloClusterThinning
+thinningTools.append(JETM12CaloClusterThinning)
+###################################
+
+# Truth particle thinning
+doTruthThinning = True
+from AthenaCommon.GlobalFlags import globalflags
+if doTruthThinning and DerivationFrameworkIsMonteCarlo:
+    truth_cond_status    = "( (TruthParticles.status == 1) && (TruthParticles.barcode < 200000) && (TruthParticles.pt > 8*GeV) )"            # high pt pions for E/p
+    truth_cond_Lepton = "((abs(TruthParticles.pdgId) >= 11) && (abs(TruthParticles.pdgId) <= 16) && (TruthParticles.barcode < 200000))" # Leptons
+    truth_expression = '('+truth_cond_status+' || '+truth_cond_Lepton +')'
+  
+    from DerivationFrameworkMCTruth.DerivationFrameworkMCTruthConf import DerivationFramework__GenericTruthThinning
+    JETM12TruthThinningTool = DerivationFramework__GenericTruthThinning( name = "JETM12TruthThinningTool",
+                                                                        StreamName              = streamName,
+                                                                        ParticleSelectionString = truth_expression,
+                                                                        PreserveDescendants     = False,
+                                                                        PreserveGeneratorDescendants = True,
+                                                                        PreserveAncestors = False)
+  
+    ToolSvc += JETM12TruthThinningTool
+    thinningTools.append(JETM12TruthThinningTool)
+
+#=======================================
+# CREATE PRIVATE SEQUENCE
+#=======================================
+
+jetm12Seq = CfgMgr.AthSequencer("JETM12Sequence")
+DerivationFrameworkJob += jetm12Seq
+
+#=======================================
+# CREATE THE DERIVATION KERNEL ALGORITHM   
+#=======================================
+from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
+jetm12Seq += CfgMgr.DerivationFramework__DerivationKernel("JETM12KernelSkim",
+                                                         SkimmingTools = [JETM12SkimmingTool],
+                                                         AugmentationTools = AugmentationToolsSkim)
+jetm12Seq += CfgMgr.DerivationFramework__DerivationKernel("JETM12Kernel",
+                                                         ThinningTools = thinningTools,
+                                                         AugmentationTools = AugmentationTools)
+
+#=======================================
+# Re-tag PFlow jets so they have b-tagging info.
+#=======================================
+from DerivationFrameworkFlavourTag.FlavourTagCommon import *
+FlavorTagInit(JetCollections = ['AntiKt4EMPFlowJets'], Sequencer = jetm12Seq)
+
+#=======================================
+# SCHEDULE SMALL-R JETS WITH LOW PT CUT
+#=======================================
+
+OutputJets["JETM12"] = []
+
+#=======================================
+# RESTORE AOD-REDUCED JET COLLECTIONS
+# SCHEDULE CUSTOM MET RECONSTRUCTION
+#=======================================
+
+if DerivationFrameworkIsMonteCarlo:
+  from DerivationFrameworkMCTruth.MCTruthCommon import addStandardTruthContents
+  addStandardTruthContents()
+
+#====================================================================
+# Add the containers to the output stream - slimming done here
+#====================================================================
+from DerivationFrameworkCore.SlimmingHelper import SlimmingHelper
+JETM12SlimmingHelper = SlimmingHelper("JETM12SlimmingHelper")
+JETM12SlimmingHelper.SmartCollections = ["Electrons", "Photons", "Muons", "TauJets",
+                                        "InDetTrackParticles", "PrimaryVertices",
+                                        "MET_Reference_AntiKt4EMTopo",
+                                        "MET_Reference_AntiKt4EMPFlow",
+                                        "AntiKt4EMTopoJets","AntiKt4EMPFlowJets","AntiKt4TruthJets",
+                                        "AntiKt4EMPFlowJets_BTagging201810",
+                                        "AntiKt4EMPFlowJets_BTagging201903",
+                                        "AntiKt4EMTopoJets_BTagging201810",
+                                        "BTagging_AntiKt4EMPFlow_201810",
+                                        "BTagging_AntiKt4EMPFlow_201903",
+                                        "BTagging_AntiKt4EMTopo_201810",
+                                        ]
+JETM12SlimmingHelper.AllVariables = ["MuonTruthParticles","TruthParticles", "TruthVertices",
+                                    "MuonSegments","InDetTrackParticles",
+                                    "Kt4EMTopoOriginEventShape","Kt4LCTopoOriginEventShape","Kt4EMPFlowEventShape","MET_Truth","CaloCalTopoClusters",
+                                    "TruthMuons","TruthElectrons","TruthPhotons","TruthTaus","TruthNeutrinos",
+                                    ]
+JETM12SlimmingHelper.ExtraVariables = ["InDetTrackParticles.TrkIsoPt1000_ptcone40.TrkIsoPt1000_ptcone30.TrkIsoPt1000_ptcone20.TrkIsoPt500_ptcone40.TrkIsoPt500_ptcone30.TrkIsoPt500_ptcone20"]
+
+JETM12SlimmingHelper.AppendContentToStream(JETM12Stream)
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM13.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM13.py
new file mode 100644
index 0000000000000000000000000000000000000000..f4f8fd176d894ea602b3b9af0a52d67d442b33fe
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM13.py
@@ -0,0 +1,168 @@
+#====================================================================
+# JETM13.py
+# reductionConf flag JETM13 in Reco_tf.py
+#====================================================================
+
+from DerivationFrameworkCore.DerivationFrameworkMaster import *
+from DerivationFrameworkJetEtMiss.JetCommon import *
+from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
+from DerivationFrameworkJetEtMiss.METCommon import *
+from DerivationFrameworkEGamma.EGammaCommon import *
+from DerivationFrameworkMuons.MuonsCommon import *
+
+#
+if DerivationFrameworkIsMonteCarlo:
+  from DerivationFrameworkMCTruth import MCTruthCommon
+  MCTruthCommon.addStandardTruthContents()
+  MCTruthCommon.addBosonsAndDownstreamParticles(generations=4,rejectHadronChildren=True)
+  MCTruthCommon.addTopQuarkAndDownstreamParticles(generations=4,rejectHadronChildren=True)
+
+#====================================================================
+# SET UP STREAM
+#====================================================================
+streamName = derivationFlags.WriteDAOD_JETM13Stream.StreamName
+fileName   = buildFileName( derivationFlags.WriteDAOD_JETM13Stream )
+JETM13Stream = MSMgr.NewPoolRootStream( streamName, fileName )
+JETM13Stream.AcceptAlgs(["JETM13MainKernel"])
+augStream = MSMgr.GetStream( streamName )
+evtStream = augStream.GetEventStream()
+
+#====================================================================
+# SKIMMING TOOL
+#====================================================================
+# None for the moment
+
+#====================================================================
+# THINNING TOOLS
+#====================================================================
+# Retain only stable truth particles, remove G4
+# We want to keep all truth jet constituents
+# Also keep the first 10 particles mainly for the HS truth vertex
+jetm13thin = []
+if DerivationFrameworkIsMonteCarlo:
+
+  from DerivationFrameworkCore.ThinningHelper import ThinningHelper
+  JETM13ThinningHelper = ThinningHelper( "JETM13ThinningHelper" )
+  JETM13ThinningHelper.AppendToStream( JETM13Stream )
+  from DerivationFrameworkMCTruth.DerivationFrameworkMCTruthConf import DerivationFramework__MenuTruthThinning
+  TruthThinningTool = DerivationFramework__MenuTruthThinning(name               = "JETM13TruthThinning",
+                                                             StreamName         = streamName,
+                                                             WriteAllStable     = True,
+                                                             # Disable the flags that have been annoyingly
+                                                             # defaulted to True
+                                                             WritePartons       = False,
+                                                             WriteHadrons       = False,
+                                                             WriteBHadrons      = True,
+                                                             WriteCHadrons      = False,
+                                                             WriteGeant         = False,
+                                                             WriteFirstN        = 10)
+  ToolSvc += TruthThinningTool
+  jetm13thin.append(TruthThinningTool)
+
+#=======================================
+# CREATE PRIVATE SEQUENCE
+#=======================================
+# Here we run custom reconstruction
+
+jetm13Seq = CfgMgr.AthSequencer("JETM13Sequence")
+DerivationFrameworkJob += jetm13Seq
+
+
+from TrackCaloClusterRecTools.TrackCaloClusterConfig import runTCCReconstruction
+runTCCReconstruction(jetm13Seq,ToolSvc, "LCOriginTopoClusters", outputTCCName="TrackCaloClustersCombinedAndNeutral")
+
+
+# Add the necessary constituents for UFOs
+from JetRecTools.ConstModHelpers import getConstModSeq, xAOD
+addCHSPFlowObjects()
+pflowCSSKSeq = getConstModSeq(["CS","SK"], "EMPFlow")
+
+# add the pflow cssk sequence to the main jetalg if not already there :
+if pflowCSSKSeq.getFullName() not in [t.getFullName() for t in DerivationFrameworkJob.jetalg.Tools]:
+  DerivationFrameworkJob.jetalg.Tools += [pflowCSSKSeq]
+
+# Finally we can run the UFO building taking our unified PFlow container as input
+from TrackCaloClusterRecTools.TrackCaloClusterConfig import runUFOReconstruction
+emufoAlg = runUFOReconstruction(jetm13Seq,ToolSvc, PFOPrefix="CHS",caloClusterName="LCOriginTopoClusters")
+emcsskufoAlg = runUFOReconstruction(jetm13Seq,ToolSvc, PFOPrefix="CSSK",caloClusterName="LCOriginTopoClusters")
+
+
+#=======================================
+# RESTORE AOD-REDUCED JET COLLECTIONS
+#=======================================
+OutputJets["JETM13"] = []
+reducedJetList = ["AntiKt4TruthJets","AntiKt10TruthJets",]
+replaceAODReducedJets(reducedJetList,jetm13Seq,"JETM13")
+
+jetm13Seq += CfgMgr.DerivationFramework__DerivationKernel( name = "JETM13MainKernel",
+                                                          SkimmingTools = [],
+                                                          ThinningTools = jetm13thin)
+
+#====================================================================
+# Add the containers to the output stream - slimming done here
+#====================================================================
+from DerivationFrameworkCore.SlimmingHelper import SlimmingHelper
+JETM13SlimmingHelper = SlimmingHelper("JETM13SlimmingHelper")
+JETM13SlimmingHelper.SmartCollections = ["Electrons", "Photons", "Muons", "TauJets",
+                                        "InDetTrackParticles", "PrimaryVertices",
+                                        "MET_Reference_AntiKt4EMTopo",
+                                        "MET_Reference_AntiKt4EMPFlow",
+                                        "AntiKt4EMTopoJets","AntiKt4EMPFlowJets",
+                                        ]
+JETM13SlimmingHelper.AllVariables = ["CaloCalTopoClusters",
+                                     "TrackCaloClustersCombinedAndNeutral",
+                                     "JetETMissChargedParticleFlowObjects",
+                                     "JetETMissNeutralParticleFlowObjects",
+                                     "Kt4EMTopoOriginEventShape","Kt4EMPFlowEventShape",
+                                     "TruthParticles",
+                                     "TruthVertices",
+                                     "TruthEvents",
+                                     ]
+JETM13SlimmingHelper.ExtraVariables = [
+  "InDetTrackParticles.particleHypothesis.vx.vy.vz",
+  "GSFTrackParticles.particleHypothesis.vx.vy.vz",
+  "PrimaryVertices.x.y.z",
+  "TauJets.clusterLinks",
+  "Muons.energyLossType.EnergyLoss.ParamEnergyLoss.MeasEnergyLoss.EnergyLossSigma.MeasEnergyLossSigma.ParamEnergyLossSigmaPlus.ParamEnergyLossSigmaMinus.clusterLinks.FSR_CandidateEnergy",
+  "MuonSegments.x.y.z.px.py.pz",
+  "AntiKt4LCTopoJets.pt.eta.phi.m",
+  ]
+
+
+JETM13SlimmingHelper.AppendToDictionary["CHSUFO"] = 'xAOD::TrackCaloClusterContainer'
+JETM13SlimmingHelper.AppendToDictionary['CHSUFOAux'] = 'xAOD::TrackCaloClusterAuxContainer'
+JETM13SlimmingHelper.ExtraVariables +=[ 'CHSUFO.pt.eta.phi.m.taste' ]
+
+JETM13SlimmingHelper.AppendToDictionary["CSSKUFO"] = 'xAOD::TrackCaloClusterContainer'
+JETM13SlimmingHelper.AppendToDictionary['CSSKUFOAux'] = 'xAOD::TrackCaloClusterAuxContainer'
+JETM13SlimmingHelper.ExtraVariables +=[ 'CSSKUFO.pt.eta.phi.m.taste' ]
+
+
+for truthc in [
+  "TruthMuons",
+  "TruthElectrons",
+  "TruthPhotons",
+  "TruthTaus",
+  "TruthNeutrinos",
+  ]:
+  JETM13SlimmingHelper.StaticContent.append("xAOD::TruthParticleContainer#"+truthc)
+  JETM13SlimmingHelper.StaticContent.append("xAOD::TruthParticleAuxContainer#"+truthc+"Aux.")
+
+for truthc in [
+  "TruthTopQuark",
+  "TruthBosons"
+  ]:
+  JETM13SlimmingHelper.StaticContent.append("xAOD::TruthParticleContainer#"+truthc+"WithDecayParticles")
+  JETM13SlimmingHelper.StaticContent.append("xAOD::TruthParticleAuxContainer#"+truthc+"WithDecayParticlesAux.")
+  JETM13SlimmingHelper.StaticContent.append("xAOD::TruthVertexContainer#"+truthc+"WithDecayVertices")
+  JETM13SlimmingHelper.StaticContent.append("xAOD::TruthVertexAuxContainer#"+truthc+"WithDecayVerticesAux.")
+      
+
+# Add the jet containers to the stream
+addJetOutputs(JETM13SlimmingHelper,["JETM13"])
+# Add the MET containers to the stream
+addMETOutputs(JETM13SlimmingHelper,["Track"])
+
+JETM13SlimmingHelper.AppendContentToStream(JETM13Stream)
+JETM13Stream.RemoveItem("xAOD::TrigNavigation#*")
+JETM13Stream.RemoveItem("xAOD::TrigNavigationAuxInfo#*")
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM14.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM14.py
new file mode 100644
index 0000000000000000000000000000000000000000..0d7e60d63616fb5747ba7c4ade48811e884ebc60
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM14.py
@@ -0,0 +1,52 @@
+#====================================================================
+# JETM14.py 
+# reductionConf flag JETM14 in Reco_tf.py   
+#====================================================================
+from DerivationFrameworkCore.DerivationFrameworkMaster import *
+from DerivationFrameworkJetEtMiss.JetCommon import *
+from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
+from DerivationFrameworkJetEtMiss.METCommon import *
+from DerivationFrameworkJetEtMiss import TriggerLists
+from DerivationFrameworkEGamma.EGammaCommon import*
+from DerivationFrameworkMuons.MuonsCommon import*
+from DerivationFrameworkJetEtMiss.METTriggerDerivationContent import METTriggerDerivationContentManager
+
+#======================================================================================================================
+# SKIMMING TOOL
+#======================================================================================================================
+from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__xAODStringSkimmingTool
+from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__TriggerSkimmingTool
+singleMuTriggers = TriggerLists.single_mu_Trig()
+cutExpression = "(count(Muons.DFCommonMuonsPreselection && Muons.pt > (20*GeV) && abs(Muons.eta) < 2.7) ) >= 2"
+JETM14StringSkimmingTool = DerivationFramework__xAODStringSkimmingTool(
+    name       = "JETM14StringSkimmingTool",
+    expression = cutExpression)
+JETM14TriggerSkimmingTool = DerivationFramework__TriggerSkimmingTool(
+    name          = "JETM14TriggerSkimmingTool",
+    TriggerListOR = singleMuTriggers)
+ToolSvc += JETM14StringSkimmingTool
+ToolSvc += JETM14TriggerSkimmingTool
+
+
+#======================================================================================================================
+# SET UP STREAM
+#======================================================================================================================
+streamName = derivationFlags.WriteDAOD_JETM14Stream.StreamName
+fileName = buildFileName( derivationFlags.WriteDAOD_JETM14Stream )
+JETM14Stream = MSMgr.NewPoolRootStream( streamName, fileName )
+JETM14Stream.AcceptAlgs(['JETM14Kernel'])
+
+content_manager = METTriggerDerivationContentManager.make_loose_manager(
+        "JETM14", JETM14Stream)
+
+#======================================================================================================================
+# CREATE PRIVATE SEQUENCE
+#======================================================================================================================
+jetm14Seq = CfgMgr.AthSequencer("jetm14Seq")
+DerivationFrameworkJob += jetm14Seq
+
+#=======================================
+# CREATE THE DERIVATION KERNEL ALGORITHM   
+#=======================================
+jetm14Seq += content_manager.make_kernel(JETM14StringSkimmingTool, JETM14TriggerSkimmingTool)
+content_manager.slimming_helper.AppendContentToStream(JETM14Stream)
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM15.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM15.py
new file mode 100644
index 0000000000000000000000000000000000000000..944ff38146d9507456e02776bcd08faeb14543c9
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM15.py
@@ -0,0 +1,492 @@
+#====================================================================
+# JETM15.py
+# reductionConf flag JETM15 in Reco_tf.py
+#====================================================================
+
+from DerivationFrameworkCore.DerivationFrameworkMaster import *
+from DerivationFrameworkJetEtMiss.JetCommon import *
+from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
+from DerivationFrameworkEGamma.EGammaCommon import *
+from DerivationFrameworkMuons.MuonsCommon import *
+from DerivationFrameworkJetEtMiss.METCommon import *
+from DerivationFrameworkFlavourTag.HbbCommon import *
+#
+if DerivationFrameworkIsMonteCarlo:
+  from DerivationFrameworkMCTruth.MCTruthCommon import addStandardTruthContents
+  addStandardTruthContents()
+  # We probably don't need this since we aren't doing real systematics?
+  #import DerivationFrameworkCore.WeightMetadata
+  #import DerivationFrameworkCore.LHE3WeightMetadata
+
+  from DerivationFrameworkMCTruth import MCTruthCommon
+  MCTruthCommon.addStandardTruthContents()
+  MCTruthCommon.addBosonsAndDownstreamParticles(generations=4,rejectHadronChildren=True)
+  MCTruthCommon.addTopQuarkAndDownstreamParticles(generations=4,rejectHadronChildren=True)
+
+
+#====================================================================
+# SKIMMING TOOL
+#====================================================================
+
+from DerivationFrameworkJetEtMiss import TriggerLists
+muonTriggers = TriggerLists.single_mu_Trig()
+jetTriggers = TriggerLists.jetTrig()
+
+# Applying a pT cut of 300 GeV on ungroomed jets, which should be sufficient for the grooming scan studies
+jetSelection = '((count( AntiKt10LCTopoJets.pt > 300.*GeV && abs(AntiKt10LCTopoJets.eta) < 2.5 ) >=1) ||  \
+                 (count( AntiKt10LCTopoCSSKJets.pt > 300.*GeV && abs(AntiKt10LCTopoCSSKJets.eta) < 2.5 ) >=1) ||  \
+                 (count( AntiKt10EMPFlowCSSKJets.pt > 300.*GeV && abs(AntiKt10EMPFlowCSSKJets.eta) < 2.5 ) >=1)  ||  \
+                 (count( AntiKt10TrackCaloClusterJets.pt > 300.*GeV && abs(AntiKt10TrackCaloClusterJets.eta) < 2.5 ) >=1) || \
+                 (count( AntiKt10UFOCHSJets.pt > 300.*GeV && abs(AntiKt10UFOCHSJets.eta) < 2.5 ) >=1) || \
+                 (count( AntiKt10UFOCSSKJets.pt > 300.*GeV && abs(AntiKt10UFOCSSKJets.eta) < 2.5 ) >=1) \
+                )' 
+
+orstr  = ' || '
+andstr = ' && '
+
+mutrigsel = '(EventInfo.eventTypeBitmask==1) || '+orstr.join(muonTriggers)
+muofflinesel = andstr.join(['count((Muons.pt > 20*GeV) && (Muons.DFCommonMuonsPreselection)) >= 1',
+                            jetSelection])
+muonSelection = ' ( (' + mutrigsel + ') && (' + muofflinesel + ') ) '
+
+from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__TriggerSkimmingTool
+JETM15TrigSkimmingTool = DerivationFramework__TriggerSkimmingTool(   name           = "JETM15TrigSkimmingTool",
+                                                                    TriggerListOR  = jetTriggers+muonTriggers )
+ToolSvc += JETM15TrigSkimmingTool
+
+from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__xAODStringSkimmingTool
+JETM15OfflineSkimmingTool = DerivationFramework__xAODStringSkimmingTool( name = "JETM15OfflineSkimmingTool",
+                                                                        expression = jetSelection + ' || ' +muonSelection)
+ToolSvc += JETM15OfflineSkimmingTool
+
+#Trigger matching decorations
+from DerivationFrameworkCore.TriggerMatchingAugmentation import applyTriggerMatching
+TrigMatchAug, NewTrigVars = applyTriggerMatching(ToolNamePrefix="JETM15",
+                                   ElectronTriggers=[],
+                                   MuonTriggers=muonTriggers,
+                                   PhotonTriggers=[])
+
+#====================================================================
+# THINNING TOOLS
+#====================================================================
+thinningTools = []
+
+#Track particles associated to any of the large-R jet collections
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__JetTrackParticleThinning
+JETM15Akt10JetTPThinningTool = DerivationFramework__JetTrackParticleThinning( name          = "JETM15Akt10JetLCTopoTPThinningTool",
+                                                                        StreamName              = streamName,
+                                                                        JetKey                  = "AntiKt10LCTopoJets",
+                                                                        InDetTrackParticlesKey  = "InDetTrackParticles",
+                                                                        ApplyAnd                = False)
+ToolSvc += JETM15Akt10JetTPThinningTool
+thinningTools.append(JETM15Akt10JetTPThinningTool)
+
+JETM15Akt10JetTPThinningToolCSSK = DerivationFramework__JetTrackParticleThinning( name          = "JETM15Akt10CSSKLCTopoJetTPThinningTool",
+                                                                        StreamName              = streamName,
+                                                                        JetKey                  = "AntiKt10LCTopoCSSKJets",
+                                                                        InDetTrackParticlesKey  = "InDetTrackParticles",
+                                                                        ApplyAnd                = False)
+ToolSvc += JETM15Akt10JetTPThinningToolCSSK
+thinningTools.append(JETM15Akt10JetTPThinningToolCSSK)
+
+JETM15Akt10JetTPThinningToolPFO = DerivationFramework__JetTrackParticleThinning( name          = "JETM15Akt10CSSKPFOJetTPThinningTool",
+                                                                        StreamName              = streamName,
+                                                                        JetKey                  = "AntiKt10EMPFlowCSSKJets",
+                                                                        InDetTrackParticlesKey  = "InDetTrackParticles",
+                                                                        ApplyAnd                = False)
+ToolSvc += JETM15Akt10JetTPThinningToolPFO
+thinningTools.append(JETM15Akt10JetTPThinningToolPFO)
+
+JETM15Akt10JetTPThinningToolTCC = DerivationFramework__JetTrackParticleThinning( name          = "JETM15Akt10TCCJetTPThinningTool",
+                                                                        StreamName              = streamName,
+                                                                        JetKey                  = "AntiKt10TrackCaloClusterJets",
+                                                                        InDetTrackParticlesKey  = "InDetTrackParticles",
+                                                                        ApplyAnd                = False)
+ToolSvc += JETM15Akt10JetTPThinningToolTCC
+thinningTools.append(JETM15Akt10JetTPThinningToolTCC)
+
+JETM15Akt10JetEMUFOThinningToolTCC = DerivationFramework__JetTrackParticleThinning( name          = "JETM15Akt10JetCHSUFOThinningTool",
+                                                                        StreamName              = streamName,
+                                                                        JetKey                  = "AntiKt10UFOCHSJets",
+                                                                        InDetTrackParticlesKey  = "InDetTrackParticles",
+                                                                        ApplyAnd                = False)
+ToolSvc += JETM15Akt10JetEMUFOThinningToolTCC
+thinningTools.append(JETM15Akt10JetEMUFOThinningToolTCC)
+
+JETM15Akt10JetCSSKUFOThinningToolTCC = DerivationFramework__JetTrackParticleThinning( name          = "JETM15Akt10JetCSSKUFOThinningTool",
+                                                                        StreamName              = streamName,
+                                                                        JetKey                  = "AntiKt10UFOCSSKJets",
+                                                                        InDetTrackParticlesKey  = "InDetTrackParticles",
+                                                                        ApplyAnd                = False)
+ToolSvc += JETM15Akt10JetCSSKUFOThinningToolTCC
+thinningTools.append(JETM15Akt10JetCSSKUFOThinningToolTCC)
+
+# TrackParticles associated with Muons
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__MuonTrackParticleThinning
+JETM15MuonTPThinningTool = DerivationFramework__MuonTrackParticleThinning(name     = "JETM15MuonTPThinningTool",
+                                                                         StreamName              = streamName,
+                                                                         MuonKey                 = "Muons",
+                                                                         InDetTrackParticlesKey  = "InDetTrackParticles")
+ToolSvc += JETM15MuonTPThinningTool
+thinningTools.append(JETM15MuonTPThinningTool)
+
+# TrackParticles associated with electrons
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__EgammaTrackParticleThinning
+JETM15ElectronTPThinningTool = DerivationFramework__EgammaTrackParticleThinning(name                    = "JETM15ElectronTPThinningTool",
+                                                                               StreamName              = streamName,
+                                                                               SGKey                   = "Electrons",
+                                                                               InDetTrackParticlesKey  = "InDetTrackParticles")
+ToolSvc += JETM15ElectronTPThinningTool
+thinningTools.append(JETM15ElectronTPThinningTool)
+
+
+from DerivationFrameworkCalo.DerivationFrameworkCaloConf import DerivationFramework__JetCaloClusterThinning
+
+JETM15AKt10CSThinningTool = DerivationFramework__JetCaloClusterThinning(name                = "JETM15AKt10CSThinningTool",
+                                                                      StreamName            = streamName,
+                                                                      SGKey                 = "AntiKt10LCTopoCSSKJets",
+                                                                      TopoClCollectionSGKey = "CaloCalTopoClusters",
+                                                                      SelectionString       = "AntiKt10LCTopoCSSKJets.pt > 300*GeV && abs(AntiKt10LCTopoCSSKJets.eta) < 2.8",
+                                                                      AdditionalClustersKey = ["LCOriginTopoClusters", "LCOriginCSSKTopoClusters"],
+                                                                      ApplyAnd                = False)
+ToolSvc += JETM15AKt10CSThinningTool
+thinningTools.append(JETM15AKt10CSThinningTool)
+
+JETM15AKt10CCThinningTool = DerivationFramework__JetCaloClusterThinning(name                = "JETM15AKt10CCThinningTool",
+                                                                      StreamName             = streamName,
+                                                                      SGKey                 = "AntiKt10LCTopoJets",
+                                                                      TopoClCollectionSGKey = "CaloCalTopoClusters",
+                                                                      SelectionString       = "(AntiKt10LCTopoJets.pt > 300*GeV && abs(AntiKt10LCTopoJets.eta) < 2.8)",
+                                                                      AdditionalClustersKey = ["LCOriginTopoClusters", "LCOriginCSSKTopoClusters"],
+                                                                      ApplyAnd                = False)
+ToolSvc += JETM15AKt10CCThinningTool
+thinningTools.append(JETM15AKt10CCThinningTool)
+
+
+# Tracks and CaloClusters associated with TCCs
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TCCTrackParticleThinning
+JETM15TCCTPThinningTool = DerivationFramework__TCCTrackParticleThinning(name                         = "JETM15TCCTPThinningTool",
+                                                                       StreamName                   = streamName,
+                                                                       JetKey                       = "AntiKt10TrackCaloClusterJets",
+                                                                       TCCKey                       = "TrackCaloClustersCombinedAndNeutral",
+                                                                       InDetTrackParticlesKey       = "InDetTrackParticles",
+                                                                       CaloCalTopoClustersKey       = "CaloCalTopoClusters",
+                                                                       ThinOriginCorrectedClusters  = True,
+                                                                       OriginCaloCalTopoClustersKey = "LCOriginTopoClusters")
+ToolSvc += JETM15TCCTPThinningTool
+thinningTools.append(JETM15TCCTPThinningTool)
+
+
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TCCTrackParticleThinning
+JETM15TCCTPThinningToolCSSK = DerivationFramework__TCCTrackParticleThinning(name                         = "JETM15TCCTPThinningToolCSSK",
+                                                                       StreamName                   = streamName,
+                                                                       JetKey                       = "AntiKt10TrackCaloClusterJets",
+                                                                       TCCKey                       = "TrackCaloClustersCombinedAndNeutral",
+                                                                       InDetTrackParticlesKey       = "InDetTrackParticles",
+                                                                       CaloCalTopoClustersKey       = "CaloCalTopoClusters",
+                                                                       ThinOriginCorrectedClusters  = True,
+                                                                       OriginCaloCalTopoClustersKey = "LCOriginCSSKTopoClusters")
+ToolSvc += JETM15TCCTPThinningToolCSSK
+thinningTools.append(JETM15TCCTPThinningToolCSSK)
+
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__UFOTrackParticleThinning
+
+JETM15EMUFOTPThinningTool = DerivationFramework__UFOTrackParticleThinning(name                      = "JETM15EMUFOTPThinningTool",
+                                                                       StreamName                   = streamName,
+                                                                       JetKey                       = "AntiKt10UFOCHSJets",
+                                                                       UFOKey                       = "CHSUFO",
+                                                                       InDetTrackParticlesKey       = "InDetTrackParticles",
+                                                                       PFOCollectionSGKey       = "JetETMiss",
+                                                                        AdditionalPFOKey  = ["CSSK", "CHS"])
+ToolSvc += JETM15EMUFOTPThinningTool
+thinningTools.append(JETM15EMUFOTPThinningTool)
+
+JETM15EMCSSKUFOTPThinningTool = DerivationFramework__UFOTrackParticleThinning(name                  = "JETM15CSSKUFOTPThinningTool",
+                                                                       StreamName                   = streamName,
+                                                                       JetKey                       = "AntiKt10UFOCSSKJets",
+                                                                       UFOKey                       = "CSSKUFO",
+                                                                       InDetTrackParticlesKey       = "InDetTrackParticles",
+                                                                       PFOCollectionSGKey       = "JetETMiss",
+                                                                        AdditionalPFOKey  = ["CSSK", "CHS"])
+ToolSvc += JETM15EMCSSKUFOTPThinningTool
+thinningTools.append(JETM15EMCSSKUFOTPThinningTool)
+
+
+
+from DerivationFrameworkCalo.DerivationFrameworkCaloConf import DerivationFramework__JetPFlowThinning
+JETM15AKt10PFOThinningTool = DerivationFramework__JetPFlowThinning(name                = "JETM15Ak10PFlowThinningTool",
+                                                                      StreamName            = streamName,
+                                                                      SGKey                 = "AntiKt10EMPFlowCSSKJets",
+                                                                      PFOCollectionSGKey    = "JetETMiss",
+                                                                      SelectionString       = "AntiKt10EMPFlowCSSKJets.pt > 300*GeV && abs(AntiKt10EMPFlowCSSKJets.eta) < 2.8",
+                                                                      AdditionalPFOKey      = ["CSSK", "CHS"],
+                                                                      )
+ToolSvc += JETM15AKt10PFOThinningTool
+thinningTools.append(JETM15AKt10PFOThinningTool)
+
+
+#=======================================
+# CREATE PRIVATE SEQUENCE
+#=======================================
+
+jetm15Seq = CfgMgr.AthSequencer("JETM15Sequence")
+DerivationFrameworkJob += jetm15Seq
+
+#=======================================
+# CREATE THE DERIVATION KERNEL ALGORITHM
+#=======================================
+
+from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
+jetm15Seq += CfgMgr.DerivationFramework__DerivationKernel(	name = "JETM15TrigSkimKernel",
+                                                            AugmentationTools = [] ,
+                                                            SkimmingTools = [JETM15TrigSkimmingTool],
+                                                            ThinningTools = [])
+
+
+#====================================================================
+# Special jets
+#====================================================================
+
+# Add alternative rho definitions
+from DerivationFrameworkJetEtMiss.ExtendedJetCommon import addCHSPFlowObjects
+addCHSPFlowObjects()
+
+from DerivationFrameworkJetEtMiss.JetCommon import defineEDAlg
+jetm15Seq += defineEDAlg(R=0.4, inputtype="EMPFlowPUSB")
+jetm15Seq += defineEDAlg(R=0.4, inputtype="EMPFlowNeut")
+
+#SCHEDULE BTAGGING FOR PFLOW JETS
+from DerivationFrameworkFlavourTag.FlavourTagCommon import FlavorTagInit
+FlavorTagInit(JetCollections=['AntiKt4EMPFlowJets'], Sequencer=jetm15Seq)
+
+#=======================================
+# RESTORE AOD-REDUCED JET COLLECTIONS
+#=======================================
+reducedJetList = ["AntiKt2PV0TrackJets",
+                  "AntiKt4PV0TrackJets",
+                  "AntiKt4TruthJets",
+                  "AntiKt10TruthJets",
+                  "AntiKt10LCTopoJets"]
+
+replaceAODReducedJets(reducedJetList,jetm15Seq,"JETM15")
+
+addDefaultTrimmedJets(jetm15Seq,"JETM15")
+
+addConstModJets("AntiKt", 1.0, "LCTopo", ["CS", "SK"], jetm15Seq, "JETM15", ptmin=40000, 
+                    ptminFilter=50000, mods="lctopo_ungroomed", addGetters=[])
+
+addConstModJets("AntiKt", 1.0, "EMPFlow", ["CS", "SK"], jetm15Seq, "JETM15", ptmin=40000, 
+                    ptminFilter=50000)
+
+# add VR jets
+addVRJets(jetm15Seq)
+addVRJets(jetm15Seq,training='201903')
+
+
+
+
+# Now we can run the UFO building taking our unified PFlow container as input
+from TrackCaloClusterRecTools.TrackCaloClusterConfig import runUFOReconstruction
+emufoAlg = runUFOReconstruction(jetm15Seq,ToolSvc, PFOPrefix="CHS",caloClusterName="LCOriginTopoClusters")
+emcsskufoAlg = runUFOReconstruction(jetm15Seq,ToolSvc, PFOPrefix="CSSK", caloClusterName='LCOriginTopoClusters')
+
+from JetRec.JetRecConf import PseudoJetGetter
+
+csskufopjgetter = PseudoJetGetter("csskufoPJGetter", InputContainer="CSSKUFO", OutputContainer="CSSKUFOPJ", Label="UFO", SkipNegativeEnergy=True)
+jtm+=csskufopjgetter
+ufopjgetter     = PseudoJetGetter("ufoPJGetter",     InputContainer="CHSUFO",     OutputContainer="CHSUFOPJ",     Label="UFO", SkipNegativeEnergy=True)
+jtm+=ufopjgetter
+
+# These lines make sure that we also retrieve all of the other getters, like track association
+# addConstModJets doesn't have a good way of dealing with UFOs at the moment unfortunately
+csskufogetters = [csskufopjgetter]+list(jtm.gettersMap["tcc"])[1:]
+chsufogetters = [ufopjgetter]+list(jtm.gettersMap["tcc"])[1:]
+addStandardJets("AntiKt", 1.0, "UFOCSSK", ptmin=40000, ptminFilter=50000, algseq=jetm15Seq, outputGroup="JETM15", customGetters = csskufogetters, constmods=["CSSK"])
+addStandardJets("AntiKt", 1.0, "UFOCHS", ptmin=40000, ptminFilter=50000, algseq=jetm15Seq, outputGroup="JETM15", customGetters = chsufogetters, constmods=["CHS"])
+
+# Create TCC objects
+from TrackCaloClusterRecTools.TrackCaloClusterConfig import runTCCReconstruction
+# Set up geometry and BField
+import AthenaCommon.AtlasUnixStandardJob
+include("RecExCond/AllDet_detDescr.py")
+runTCCReconstruction(jetm15Seq, ToolSvc, "LCOriginTopoClusters", "InDetTrackParticles",outputTCCName="TrackCaloClustersCombinedAndNeutral")
+addTCCTrimmedJets(jetm15Seq,"JETM15")
+
+
+
+from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
+jetm15Seq += CfgMgr.DerivationFramework__DerivationKernel( name = "JETM15MainKernel",
+                                                          AugmentationTools = [TrigMatchAug] ,
+                                                          SkimmingTools = [JETM15OfflineSkimmingTool],
+                                                          ThinningTools = thinningTools)
+
+#====================================================================
+# SET UP STREAM
+#====================================================================
+streamName = derivationFlags.WriteDAOD_JETM15Stream.StreamName
+fileName   = buildFileName( derivationFlags.WriteDAOD_JETM15Stream )
+JETM15Stream = MSMgr.NewPoolRootStream( streamName, fileName )
+JETM15Stream.AcceptAlgs(["JETM15MainKernel"])
+augStream = MSMgr.GetStream( streamName )
+evtStream = augStream.GetEventStream()
+
+# Truth particle thinning
+doTruthThinning = True
+preserveAllDescendants = False
+
+if DerivationFrameworkIsMonteCarlo:
+
+  from DerivationFrameworkCore.ThinningHelper import ThinningHelper
+  JETM15ThinningHelper = ThinningHelper( "JETM15ThinningHelper" )
+  JETM15ThinningHelper.AppendToStream( JETM15Stream )
+  from DerivationFrameworkMCTruth.DerivationFrameworkMCTruthConf import DerivationFramework__MenuTruthThinning
+  TruthThinningTool = DerivationFramework__MenuTruthThinning(name               = "JETM15TruthThinning",
+                                                             StreamName         = streamName,
+                                                             WriteAllStable     = True,
+                                                             WritePartons       = False,
+                                                             WriteHadrons       = False,
+                                                             WriteBHadrons      = True,
+                                                             WriteCHadrons      = False,
+                                                             WriteGeant         = False,
+                                                             WriteFirstN        = -1)
+  ToolSvc += TruthThinningTool
+  thinningTools.append(TruthThinningTool)
+
+#====================================================================
+# Add the containers to the output stream - slimming done here
+#====================================================================
+from DerivationFrameworkCore.SlimmingHelper import SlimmingHelper
+
+JETM15SlimmingHelper = SlimmingHelper("JETM15SlimmingHelper")
+JETM15SlimmingHelper.AppendToDictionary = {
+  "Kt4EMPFlowNeutEventShape": "xAOD::EventShape",
+  "Kt4EMPFlowNeutEventShapeAux": "xAOD::AuxInfoBase",
+  "Kt4EMPFlowPUSBEventShape": "xAOD::EventShape",
+  "Kt4EMPFlowPUSBEventShapeAux": "xAOD::AuxInfoBase",
+  "AntiKt10LCTopoCSSKJets"   :   "xAOD::JetContainer"        ,
+  "AntiKt10LCTopoCSSKJetsAux.":   "xAOD::JetAuxContainer"        ,
+  "AntiKt10LCTopoJets"   :   "xAOD::JetContainer"        ,
+  "AntiKt10LCTopoJetsAux.":   "xAOD::JetAuxContainer"        
+}
+
+JETM15SlimmingHelper.SmartCollections = [
+  "Electrons", 
+  "Muons",
+  "InDetTrackParticles",
+  "PrimaryVertices",
+  "MET_Reference_AntiKt4EMTopo",
+  "MET_Reference_AntiKt4EMPFlow",
+  "AntiKt4EMTopoJets",
+  "AntiKt4EMPFlowJets",
+  "AntiKt4EMPFlowJets_BTagging201810",
+  "AntiKt4EMPFlowJets_BTagging201903",
+  "AntiKt4EMTopoJets_BTagging201810",
+  "BTagging_AntiKt4EMPFlow_201810",
+  "BTagging_AntiKt4EMPFlow_201903",
+  "BTagging_AntiKt4EMTopo_201810",                                         
+  "BTagging_AntiKtVR30Rmax4Rmin02Track_201810",
+  "BTagging_AntiKtVR30Rmax4Rmin02Track_201903",
+  "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets"
+]
+
+JETM15SlimmingHelper.AllVariables = [
+  "Kt4EMTopoOriginEventShape",
+  "Kt4LCTopoOriginEventShape",
+  "Kt4EMPFlowEventShape", 
+  "Kt4EMPFlowPUSBEventShape",
+  "Kt4EMPFlowNeutEventShape",
+  "TruthParticles", 
+  "TruthEvents", 
+  "TruthVertices",
+]
+
+#Do we need small-R truth jets?
+if DerivationFrameworkIsMonteCarlo:
+  JETM15SlimmingHelper.AppendToDictionary["AntiKt10TruthJets"]="xAOD::JetContainer"
+  JETM15SlimmingHelper.AppendToDictionary["AntiKt10TruthJetsAux"]="xAOD::JetAuxContainer"
+  JETM15SlimmingHelper.AllVariables  += ["AntiKt10TruthJets"]
+  
+addOriginCorrectedClusters(JETM15SlimmingHelper,writeLC=True,writeEM=True)
+
+JETM15SlimmingHelper.AppendToDictionary["CaloCalTopoClusters"]='xAOD::CaloClusterContainer'
+JETM15SlimmingHelper.AppendToDictionary["CaloCalTopoClustersAux"]='xAOD::CaloClusterAuxContainer'
+JETM15SlimmingHelper.ExtraVariables.append('CaloCalTopoClusters.calEta.calPhi.calE.calM.rawEta.rawPhi.rawE.rawM')
+
+JETM15SlimmingHelper.AppendToDictionary["LCOriginTopoClusters"]='xAOD::CaloClusterContainer'
+JETM15SlimmingHelper.AppendToDictionary["LCOriginTopoClustersAux"]='xAOD::ShallowAuxContainer'
+
+JETM15SlimmingHelper.AppendToDictionary["LCOriginCSSKTopoClusters"]='xAOD::CaloClusterContainer'
+JETM15SlimmingHelper.AppendToDictionary["LCOriginCSSKTopoClustersAux"]='xAOD::ShallowAuxContainer'
+
+JETM15SlimmingHelper.AppendToDictionary["JetETMissNeutralParticleFlowObjects"]='xAOD::PFOContainer'
+JETM15SlimmingHelper.AppendToDictionary["JetETMissNeutralParticleFlowObjectsAux"]='xAOD::PFOAuxContainer'
+JETM15SlimmingHelper.ExtraVariables.append('JetETMissNeutralParticleFlowObjects.pt.eta.phi.m.e.charge')
+
+JETM15SlimmingHelper.AppendToDictionary["JetETMissChargedParticleFlowObjects"]='xAOD::PFOContainer'
+JETM15SlimmingHelper.AppendToDictionary["JetETMissChargedParticleFlowObjectsAux"]='xAOD::PFOAuxContainer'
+JETM15SlimmingHelper.ExtraVariables.append('JetETMissChargedParticleFlowObjects.pt.eta.phi.m.e.charge.matchedToPV')
+
+JETM15SlimmingHelper.AppendToDictionary["CSSKUFO"] = 'xAOD::TrackCaloClusterContainer'
+JETM15SlimmingHelper.AppendToDictionary['CSSKUFOAux'] = 'xAOD::TrackCaloClusterAuxContainer'
+JETM15SlimmingHelper.ExtraVariables +=[ 'CSSKUFO.pt.eta.phi.m.taste' ]
+
+JETM15SlimmingHelper.AppendToDictionary["CHSUFO"] = 'xAOD::TrackCaloClusterContainer'
+JETM15SlimmingHelper.AppendToDictionary['CHSUFOAux'] = 'xAOD::TrackCaloClusterAuxContainer'
+JETM15SlimmingHelper.ExtraVariables +=[ 'CHSUFO.pt.eta.phi.m.taste' ]
+
+
+JETM15SlimmingHelper.AppendToDictionary["CSSKChargedParticleFlowObjects"]='xAOD::PFOContainer'
+JETM15SlimmingHelper.AppendToDictionary["CSSKChargedParticleFlowObjectsAux"]='xAOD::ShallowAuxContainer'
+JETM15SlimmingHelper.ExtraVariables.append('CSSKChargedParticleFlowObjects.pt.eta.phi.m.e.charge.matchedToPV')
+
+JETM15SlimmingHelper.AppendToDictionary["CSSKNeutralParticleFlowObjects"]='xAOD::PFOContainer'
+JETM15SlimmingHelper.AppendToDictionary["CSSKNeutralParticleFlowObjectsAux"]='xAOD::ShallowAuxContainer'
+JETM15SlimmingHelper.ExtraVariables.append('CSSKNeutralParticleFlowObjects.pt.eta.phi.m.e.charge')
+
+JETM15SlimmingHelper.AppendToDictionary["CHSChargedParticleFlowObjects"]='xAOD::PFOContainer'
+JETM15SlimmingHelper.AppendToDictionary["CHSChargedParticleFlowObjectsAux"]='xAOD::ShallowAuxContainer'
+JETM15SlimmingHelper.ExtraVariables.append('CHSChargedParticleFlowObjects.pt.eta.phi.m.e.charge.matchedToPV')
+
+JETM15SlimmingHelper.AppendToDictionary["CHSNeutralParticleFlowObjects"]='xAOD::PFOContainer'
+JETM15SlimmingHelper.AppendToDictionary["CHSNeutralParticleFlowObjectsAux"]='xAOD::ShallowAuxContainer'
+JETM15SlimmingHelper.ExtraVariables.append('CHSNeutralParticleFlowObjects.pt.eta.phi.m.e.charge')
+
+JETM15SlimmingHelper.AllVariables  += ["LCOriginTopoClusters", "LCOriginCSSKTopoClusters", "CSSKNeutralParticleFlowObjects", "CSSKChargedParticleFlowObjects", "TrackCaloClustersCombinedAndNeutral", "CHSChargedParticleFlowObjects", "CHSNeutralParticleFlowObjects"]
+JETM15SlimmingHelper.ExtraVariables.append("AntiKt4EMTopoJets.btaggingLink")
+JETM15SlimmingHelper.ExtraVariables.append("BTagging_AntiKt4EMTopo.MSV_N2Tpair.MSV_badTracksIP.MSV_energyTrkInJet.MSV_normdist.MSV_nvsec.MSV_vertices.MV1_discriminant.MV2c00_discriminant.MV2c100_discriminant.MV2c10_discriminant.MV2c20_discriminant.MV2m_pb.MV2m_pc.MV2m_pu.MultiSVbb1_discriminant.MultiSVbb2_discriminant.SV0_N2Tpair.SV1_pb.SV1_pc.SV1_pu.IP3D_pb.IP3D_pc.IP3D_pu.DL1_pb.DL1_pc.DL1_pu.DL1mu_pb.DL1mu_pc.DL1mu_pu.DL1rnn_pb.DL1rnn_pc.DL1rnn_pu.JetVertexCharge_discriminant")
+
+# Check if we need truth muon collection
+for truthc in [
+  "TruthElectrons",
+  "TruthMuons",
+  ]:
+  JETM15SlimmingHelper.StaticContent.append("xAOD::TruthParticleContainer#"+truthc)
+  JETM15SlimmingHelper.StaticContent.append("xAOD::TruthParticleAuxContainer#"+truthc+"Aux.")
+
+for truthc in [
+  "TruthTopQuark",
+  "TruthBosons"
+  ]:
+  JETM15SlimmingHelper.StaticContent.append("xAOD::TruthParticleContainer#"+truthc+"WithDecayParticles")
+  JETM15SlimmingHelper.StaticContent.append("xAOD::TruthParticleAuxContainer#"+truthc+"WithDecayParticlesAux.")
+  JETM15SlimmingHelper.StaticContent.append("xAOD::TruthVertexContainer#"+truthc+"WithDecayVertices")
+  JETM15SlimmingHelper.StaticContent.append("xAOD::TruthVertexAuxContainer#"+truthc+"WithDecayVerticesAux.")
+
+# Add the jet containers to the stream
+# explicitely add the container we want :
+addJetOutputs(JETM15SlimmingHelper,[
+        "AntiKt10LCTopoJets",    "AntiKt10LCTopoCSSKJets",  "AntiKt10EMPFlowCSSKJets",  "AntiKt10TrackCaloClusterJets", "AntiKt10UFOCHSJets", "AntiKt10UFOCSSKJets",
+        "JETM15", # jets defined in this file
+        ])
+
+
+JETM15SlimmingHelper.ExtraVariables += [
+    NewTrigVars["Muons"][0],
+    ]
+
+JETM15SlimmingHelper.AppendContentToStream(JETM15Stream)
+
+JETM15Stream.RemoveItem("xAOD::TrigNavigation#*")
+JETM15Stream.RemoveItem("xAOD::TrigNavigationAuxInfo#*")
+
+
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM2.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM2.py
index a055bf17b77dfa411ead480ec9138b1d1a4d89e0..7c48fa50439b426ab5bdeea5719708f5d86415c9 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM2.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM2.py
@@ -6,23 +6,23 @@
 from DerivationFrameworkCore.DerivationFrameworkMaster import *
 from DerivationFrameworkInDet.InDetCommon import *
 from DerivationFrameworkJetEtMiss.JetCommon import *
-#from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
+from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
 from DerivationFrameworkEGamma.EGammaCommon import *
 from DerivationFrameworkMuons.MuonsCommon import *
 #
 from DerivationFrameworkJetEtMiss.METCommon import *
 #
 if DerivationFrameworkIsMonteCarlo:
-    from DerivationFrameworkMCTruth.MCTruthCommon import *
-    from DerivationFrameworkTau.TauTruthCommon import *
+  from DerivationFrameworkMCTruth.MCTruthCommon import addStandardTruthContents
+  addStandardTruthContents()
 
 #====================================================================
 # SKIMMING TOOL 
 #====================================================================
 
-from DerivationFrameworkJetEtMiss.TriggerLists import *
-electronTriggers = singleElTriggers
-muonTriggers = singleMuTriggers
+from DerivationFrameworkJetEtMiss import TriggerLists
+electronTriggers = TriggerLists.single_el_Trig()
+muonTriggers = TriggerLists.single_mu_Trig()
 
 orstr  = ' || '
 andstr = ' && '
@@ -41,6 +41,11 @@ JETM2SkimmingTool = DerivationFramework__xAODStringSkimmingTool( name = "JETM2Sk
                                                                     expression = expression)
 ToolSvc += JETM2SkimmingTool
 
+#Trigger matching decorations
+from DerivationFrameworkCore.TriggerMatchingAugmentation import applyTriggerMatching
+TrigMatchAug, NewTrigVars = applyTriggerMatching(ToolNamePrefix="JETM2",
+                                                 ElectronTriggers=electronTriggers,MuonTriggers=muonTriggers)
+
 #====================================================================
 # SET UP STREAM   
 #====================================================================
@@ -92,7 +97,7 @@ thinningTools.append(JETM2PhotonTPThinningTool)
 # TrackParticles associated with taus
 from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TauTrackParticleThinning
 JETM2TauTPThinningTool = DerivationFramework__TauTrackParticleThinning( name            = "JETM2TauTPThinningTool",
-                                                                        StreamName              = streamName,
+                                                                        StreamName      = streamName,
                                                                         TauKey          = "TauJets",
                                                                         InDetTrackParticlesKey  = "InDetTrackParticles")
 ToolSvc += JETM2TauTPThinningTool
@@ -137,7 +142,29 @@ DerivationFrameworkJob += jetm2Seq
 from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
 jetm2Seq += CfgMgr.DerivationFramework__DerivationKernel("JETM2Kernel",
                                                          SkimmingTools = [JETM2SkimmingTool],
-                                                         ThinningTools = thinningTools)
+                                                         ThinningTools = thinningTools,
+                                                         AugmentationTools = [TrigMatchAug])
+
+#=======================================
+# SCHEDULE SMALL-R JETS WITH LOW PT CUT
+#=======================================
+
+OutputJets["JETM2"] = []
+
+#=======================================
+# RESTORE AOD-REDUCED JET COLLECTIONS
+#=======================================
+reducedJetList = ["AntiKt2PV0TrackJets",
+                  "AntiKt4PV0TrackJets",
+                  "AntiKt4TruthJets"]
+replaceAODReducedJets(reducedJetList,jetm2Seq,"JETM2")
+
+
+#======================================= 
+# SCHEDUKE BTAGGING FOR PFLOW JETS
+#======================================= 
+from DerivationFrameworkFlavourTag.FlavourTagCommon import FlavorTagInit
+FlavorTagInit(JetCollections=['AntiKt4EMPFlowJets'], Sequencer=jetm2Seq)
 
 #=======================================
 # SCHEDULE CUSTOM MET RECONSTRUCTION
@@ -161,15 +188,22 @@ JETM2SlimmingHelper.SmartCollections = ["Electrons", "Photons", "Muons", "TauJet
                                         "MET_Reference_AntiKt4LCTopo",
                                         "MET_Reference_AntiKt4EMPFlow",
                                         "AntiKt4EMTopoJets","AntiKt4LCTopoJets","AntiKt4EMPFlowJets",
-                                        "BTagging_AntiKt4EMTopo",
+                                        "AntiKt4EMPFlowJets_BTagging201810",
+                                        "AntiKt4EMPFlowJets_BTagging201903",
+                                        "AntiKt4EMTopoJets_BTagging201810",
+                                        "BTagging_AntiKt4EMPFlow_201810",
+                                        "BTagging_AntiKt4EMPFlow_201903",
+                                        "BTagging_AntiKt4EMTopo_201810",
                                         ]
 JETM2SlimmingHelper.AllVariables = ["MuonTruthParticles", "egammaTruthParticles",
                                     "TruthParticles", "TruthEvents", "TruthVertices",
                                     "MuonSegments",
                                     "Kt4EMTopoOriginEventShape","Kt4LCTopoOriginEventShape","Kt4EMPFlowEventShape",
                                     ]
-JETM2SlimmingHelper.ExtraVariables = ["Muons.energyLossType.EnergyLoss.ParamEnergyLoss.MeasEnergyLoss.EnergyLossSigma.MeasEnergyLossSigma.ParamEnergyLossSigmaPlus.ParamEnergyLossSigmaMinus",
+JETM2SlimmingHelper.ExtraVariables = ["Electrons."+NewTrigVars["Electrons"],
+                                      "Muons.energyLossType.EnergyLoss.ParamEnergyLoss.MeasEnergyLoss.EnergyLossSigma.MeasEnergyLossSigma.ParamEnergyLossSigmaPlus.ParamEnergyLossSigmaMinus."+NewTrigVars["Muons"],
                                       "TauJets.IsTruthMatched.truthParticleLink.truthJetLink"]
+
 for truthc in [
     "TruthMuons",
     "TruthElectrons",
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM3.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM3.py
index 09c86d4ad4de3d7409460b39fc55f972303a91a7..e2be155c79b931d4914b192a0953a480139e6ccc 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM3.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM3.py
@@ -1,6 +1,6 @@
-m#====================================================================
-# JETM3.py 
-# reductionConf flag JETM3 in Reco_tf.py   
+#====================================================================
+# JETM3.py
+# reductionConf flag JETM3 in Reco_tf.py
 #====================================================================
 
 from DerivationFrameworkCore.DerivationFrameworkMaster import *
@@ -14,17 +14,17 @@ from DerivationFrameworkMuons.MuonsCommon import *
 from DerivationFrameworkJetEtMiss.METCommon import *
 #
 if DerivationFrameworkIsMonteCarlo:
-    from DerivationFrameworkMCTruth.MCTruthCommon import *
-    from DerivationFrameworkTau.TauTruthCommon import *
+  from DerivationFrameworkMCTruth.MCTruthCommon import addStandardTruthContents
+  addStandardTruthContents()
 
 #
 #====================================================================
-# SKIMMING TOOL 
+# SKIMMING TOOL
 #====================================================================
 
-from DerivationFrameworkJetEtMiss.TriggerLists import *
-electronTriggers = singleElTriggers
-muonTriggers = singleMuTriggers
+from DerivationFrameworkJetEtMiss import TriggerLists
+electronTriggers = TriggerLists.single_el_Trig()
+muonTriggers = TriggerLists.single_mu_Trig()
 
 orstr  = ' || '
 andstr = ' && '
@@ -42,8 +42,13 @@ JETM3SkimmingTool = DerivationFramework__xAODStringSkimmingTool( name = "JETM3Sk
                                                                     expression = expression)
 ToolSvc += JETM3SkimmingTool
 
+#Trigger matching decorations
+from DerivationFrameworkCore.TriggerMatchingAugmentation import applyTriggerMatching
+TrigMatchAug, NewTrigVars = applyTriggerMatching(ToolNamePrefix="JETM3",
+                                                 ElectronTriggers=electronTriggers,MuonTriggers=muonTriggers)
+
 #====================================================================
-# SET UP STREAM   
+# SET UP STREAM
 #====================================================================
 streamName = derivationFlags.WriteDAOD_JETM3Stream.StreamName
 fileName   = buildFileName( derivationFlags.WriteDAOD_JETM3Stream )
@@ -60,7 +65,7 @@ JETM3ThinningHelper = ThinningHelper( "JETM3ThinningHelper" )
 JETM3ThinningHelper.AppendToStream( JETM3Stream )
 
 #====================================================================
-# THINNING TOOLS 
+# THINNING TOOLS
 #====================================================================
 thinningTools = []
 
@@ -119,9 +124,9 @@ if doTruthThinning and DerivationFrameworkIsMonteCarlo:
     truth_cond_Quark  = "((abs(TruthParticles.pdgId) <=  5 && (TruthParticles.pt > 10000.)) || (abs(TruthParticles.pdgId) == 6))"                 # Quarks
     truth_cond_Gluon  = "((abs(TruthParticles.pdgId) == 21) && (TruthParticles.pt > 10000.))"                                                # Gluons
     truth_cond_Photon = "((abs(TruthParticles.pdgId) == 22) && (TruthParticles.pt > 10000.) && (TruthParticles.barcode < 200000))"                 # Photon
-    
+
     truth_expression = '('+truth_cond_WZH+' || '+truth_cond_Lepton +' || '+truth_cond_Quark+'||'+truth_cond_Gluon+' || '+truth_cond_Photon+')'
-    
+
     from DerivationFrameworkMCTruth.DerivationFrameworkMCTruthConf import DerivationFramework__GenericTruthThinning
     JETM3TruthThinningTool = DerivationFramework__GenericTruthThinning( name = "JETM3TruthThinningTool",
                                                                         StreamName              = streamName,
@@ -129,9 +134,9 @@ if doTruthThinning and DerivationFrameworkIsMonteCarlo:
                                                                         PreserveDescendants     = preserveAllDescendants,
                                                                         PreserveGeneratorDescendants = not preserveAllDescendants,
                                                                         PreserveAncestors = True)
-    
+
     ToolSvc += JETM3TruthThinningTool
-    thinningTools.append(JETM3TruthThinningTool)    
+    thinningTools.append(JETM3TruthThinningTool)
 
 #=======================================
 # CREATE PRIVATE SEQUENCE
@@ -141,59 +146,77 @@ jetm3Seq = CfgMgr.AthSequencer("JETM3Sequence")
 DerivationFrameworkJob += jetm3Seq
 
 #=======================================
-# CREATE THE DERIVATION KERNEL ALGORITHM   
+# CREATE THE DERIVATION KERNEL ALGORITHM
 #=======================================
 
 from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
 jetm3Seq += CfgMgr.DerivationFramework__DerivationKernel(	name = "JETM3Kernel",
                                                                 SkimmingTools = [JETM3SkimmingTool],
-                                                                ThinningTools = thinningTools)
-# PFlow augmentation
-applyPFOAugmentation(jetm3Seq)
+                                                                ThinningTools = thinningTools,
+                                                                AugmentationTools = [TrigMatchAug])
+
+OutputJets["JETM3"] = []
 
 #=======================================
-# SCHEDULE SMALL-R JETS WITH LOW PT CUT
+# BUILD UFO INPUTS
 #=======================================
 
-OutputJets["JETM3"] = []
+# Add PFlow constituents
+from JetRecTools.ConstModHelpers import getConstModSeq, xAOD
+pflowCSSKSeq = getConstModSeq(["CS","SK"], "EMPFlow")
+
+# add the pflow cssk sequence to the main jetalg if not already there :
+if pflowCSSKSeq.getFullName() not in [t.getFullName() for t in DerivationFrameworkJob.jetalg.Tools]:
+    DerivationFrameworkJob.jetalg.Tools += [pflowCSSKSeq]
+
+# Add UFO constituents
+from TrackCaloClusterRecTools.TrackCaloClusterConfig import runUFOReconstruction
+emufoAlg = runUFOReconstruction(jetm3Seq,ToolSvc, PFOPrefix="CHS")
+emcsskufoAlg = runUFOReconstruction(jetm3Seq, ToolSvc, PFOPrefix="CSSK")
 
 #=======================================
 # RESTORE AOD-REDUCED JET COLLECTIONS
 #=======================================
 reducedJetList = ["AntiKt2PV0TrackJets",
                   "AntiKt4PV0TrackJets",
-                  "AntiKt4TruthJets"]
+                  "AntiKt4TruthJets",
+                  "AntiKt10TruthJets",
+                  "AntiKt10UFOCSSKJets",
+                  "AntiKt10UFOCHSJets",
+                  ]
 replaceAODReducedJets(reducedJetList,jetm3Seq,"JETM3")
 
-from JetRec.JetRecStandard import jtm
-#EMTopo
-lowptjetalg = None
-if "jetalgAntiKt4EMTopoLowPtJets" in DFJetAlgs.keys():
-    lowptjetalg = DFJetAlgs["jetalgAntiKt4EMTopoLowPtJets"]
-else:
-    jtm.addJetFinder("AntiKt4EMTopoLowPtJets", "AntiKt", 0.4, "emtopo", "emtopo_ungroomed", ghostArea=0.01, ptmin= 2000, ptminFilter= 2000, calibOpt="ar")
-    lowptjetalg = CfgMgr.JetAlgorithm("jetalgAntiKt4EMTopoLowPtJets", Tools = [jtm.AntiKt4EMTopoLowPtJets])
-    DFJetAlgs["jetalgAntiKt4EMTopoLowPtJets"] = lowptjetalg;
-jetm3Seq += lowptjetalg
-OutputJets["JETM3"].append("AntiKt4EMTopoLowPtJets")
-#LCTopo
-if "jetalgAntiKt4LCTopoLowPtJets" in DFJetAlgs.keys():
-    lowptjetalg = DFJetAlgs["jetalgAntiKt4LCTopoLowPtJets"]
-else:
-    jtm.addJetFinder("AntiKt4LCTopoLowPtJets", "AntiKt", 0.4, "lctopo", "lctopo_ungroomed", ghostArea=0.01, ptmin= 2000, ptminFilter= 2000, calibOpt="ar")
-    lowptjetalg = CfgMgr.JetAlgorithm("jetalgAntiKt4LCTopoLowPtJets", Tools = [jtm.AntiKt4LCTopoLowPtJets])
-    DFJetAlgs["jetalgAntiKt4LCTopoLowPtJets"] = lowptjetalg;
-jetm3Seq += lowptjetalg
-OutputJets["JETM3"].append("AntiKt4LCTopoLowPtJets")
-#EMPFlow
-if "jetalgAntiKt4EMPFlowLowPtJets" in DFJetAlgs.keys():
-    lowptjetalg = DFJetAlgs["jetalgAntiKt4EMPFlowLowPtJets"]
-else:
-    jtm.addJetFinder("AntiKt4EMPFlowLowPtJets", "AntiKt", 0.4, "empflow", "pflow_ungroomed", ghostArea=0.01, ptmin= 2000, ptminFilter= 2000, calibOpt="ar:pflow")
-    lowptjetalg = CfgMgr.JetAlgorithm("jetalgAntiKt4EMPFlowLowPtJets", Tools = [jtm.AntiKt4EMPFlowLowPtJets])
-    DFJetAlgs["jetalgAntiKt4EMPFlowLowPtJets"] = lowptjetalg;
-jetm3Seq += lowptjetalg
-OutputJets["JETM3"].append("AntiKt4EMPFlowLowPtJets")
+addDefaultTrimmedJets(jetm3Seq,"JETM3")
+# UFO Trimmed jets
+addTrimmedJets("AntiKt", 1.0, "UFOCSSK", rclus=0.2, ptfrac=0.05, algseq=jetm3Seq, outputGroup="JETM3", writeUngroomed=False, mods="tcc_groomed")
+addTrimmedJets("AntiKt", 1.0, "UFOCHS", rclus=0.2, ptfrac=0.05, algseq=jetm3Seq, outputGroup="JETM3", writeUngroomed=False, mods="tcc_groomed")
+# CSSK UFO SoftDrop jets
+addSoftDropJets("AntiKt", 1.0, "UFOCSSK", beta=1.0, zcut=0.1, algseq=jetm3Seq, outputGroup="JETM3", writeUngroomed=False, mods="tcc_groomed")
+addRecursiveSoftDropJets('AntiKt', 1.0, 'UFOCSSK', beta=1.0, zcut=0.05, N=-1,  mods="tcc_groomed", algseq=jetm3Seq, outputGroup="JETM3", writeUngroomed=False)
+addBottomUpSoftDropJets('AntiKt', 1.0, 'UFOCSSK', beta=1.0, zcut=0.05, mods="tcc_groomed", algseq=jetm3Seq, outputGroup="JETM3", writeUngroomed=False)
+
+if DerivationFrameworkIsMonteCarlo:
+  addSoftDropJets('AntiKt', 1.0, 'Truth', beta=1.0, zcut=0.1, mods="truth_groomed", algseq=jetm3Seq, outputGroup="JETM3", writeUngroomed=False)
+  addRecursiveSoftDropJets('AntiKt', 1.0, 'Truth', beta=1.0, zcut=0.05, N=-1,  mods="truth_groomed", algseq=jetm3Seq, outputGroup="JETM3", writeUngroomed=False)
+  addBottomUpSoftDropJets('AntiKt', 1.0, 'Truth', beta=1.0, zcut=0.05, mods="truth_groomed", algseq=jetm3Seq, outputGroup="JETM3", writeUngroomed=False)
+
+# Add the BCID info
+addDistanceInTrain(jetm3Seq)
+
+#=======================================
+# SCHEDULE SMALL-R JETS WITH LOW PT CUT
+#=======================================
+
+addAntiKt4LowPtJets(jetm3Seq,"JETM3")
+
+#====================================================================
+#Jets for R-scan
+#====================================================================
+for radius in [0.2, 0.6]:
+    if jetFlags.useTruth:
+        addRscanJets("AntiKt",radius,"Truth",jetm3Seq,"JETM3")
+        addRscanJets("AntiKt",radius,"TruthWZ",jetm3Seq,"JETM3")
+    addRscanJets("AntiKt",radius,"LCTopo",jetm3Seq,"JETM3")
 
 #=======================================
 # SCHEDULE CUSTOM MET RECONSTRUCTION
@@ -203,6 +226,34 @@ if DerivationFrameworkIsMonteCarlo:
     addMETTruthMap('AntiKt4LCTopo',"JETMX")
     addMETTruthMap('AntiKt4EMPFlow',"JETMX")
     scheduleMETAssocAlg(jetm3Seq,"JETMX")
+    ## Add GhostTruthAssociation information ##
+    addJetPtAssociation(jetalg="AntiKt4EMTopo",  truthjetalg="AntiKt4TruthJets", sequence=jetm3Seq, algname="JetPtAssociationAlg")
+    addJetPtAssociation(jetalg="AntiKt4LCTopo",  truthjetalg="AntiKt4TruthJets", sequence=jetm3Seq, algname="JetPtAssociationAlg")
+    addJetPtAssociation(jetalg="AntiKt4EMPFlow", truthjetalg="AntiKt4TruthJets", sequence=jetm3Seq, algname="JetPtAssociationAlg")
+    addJetPtAssociation(jetalg="AntiKt4EMTopoLowPt",  truthjetalg="AntiKt4TruthJets", sequence=jetm3Seq, algname="JetPtAssociationAlgLowPt")
+    addJetPtAssociation(jetalg="AntiKt4LCTopoLowPt",  truthjetalg="AntiKt4TruthJets", sequence=jetm3Seq, algname="JetPtAssociationAlgLowPt")
+
+#====================================================================
+# ADD PFLOW AUG INFORMATION 
+#====================================================================
+from DerivationFrameworkJetEtMiss.PFlowCommon import applyPFOAugmentation
+applyPFOAugmentation(DerivationFrameworkJob)
+
+#=======================================
+# BTAGGING INFO FOR PFLOW JET
+#=======================================
+from DerivationFrameworkFlavourTag.FlavourTagCommon import FlavorTagInit
+FlavorTagInit(JetCollections = ['AntiKt4EMPFlowJets'],Sequencer = jetm3Seq)
+
+# QGTaggerTool ###
+addQGTaggerTool(jetalg="AntiKt4EMTopo", sequence=jetm3Seq, algname="QGTaggerToolAlg")
+addQGTaggerTool(jetalg="AntiKt4EMPFlow", sequence=jetm3Seq, algname="QGTaggerToolAlg")
+
+# MVfJvt #
+applyMVfJvtAugmentation(jetalg='AntiKt4EMTopo',sequence=jetm3Seq, algname='JetForwardJvtToolBDTAlg')
+
+# PFlow fJvt #
+getPFlowfJVT(jetalg='AntiKt4EMPFlow',sequence=jetm3Seq, algname='JetForwardPFlowJvtToolAlg')
 
 #====================================================================
 # Add the containers to the output stream - slimming done here
@@ -214,18 +265,43 @@ JETM3SlimmingHelper.SmartCollections = ["Electrons", "Photons", "Muons", "TauJet
                                         "MET_Reference_AntiKt4EMTopo",
                                         "MET_Reference_AntiKt4LCTopo",
                                         "MET_Reference_AntiKt4EMPFlow",
-                                        "AntiKt4EMTopoJets","AntiKt4LCTopoJets","AntiKt4EMPFlowJets",
-                                        "BTagging_AntiKt4EMTopo",
+                                        "AntiKt2LCTopoJets", "AntiKt6LCTopoJets",
+                                        "AntiKt4TruthWZJets",
+                                        "AntiKt10TruthJets",
+                                        "AntiKt10UFOCSSKJets",
+                                        "AntiKt10UFOCHSJets",
+                                        "AntiKt10TruthTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10TruthSoftDropBeta100Zcut10Jets",
+                                        "AntiKt10TruthBottomUpSoftDropBeta100Zcut5Jets",
+                                        "AntiKt10TruthRecursiveSoftDropBeta100Zcut5NinfJets",
+                                        "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10UFOCHSTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10UFOCSSKTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets",
+                                        "AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5Jets",
+                                        "AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJets",
+                                        "AntiKt4EMPFlowJets_BTagging201810",
+                                        "AntiKt4EMPFlowJets_BTagging201903",
+                                        "AntiKt4EMTopoJets_BTagging201810",
+                                        "BTagging_AntiKt4EMPFlow_201810",
+                                        "BTagging_AntiKt4EMPFlow_201903",
+                                        "BTagging_AntiKt4EMTopo_201810",
 					]
 JETM3SlimmingHelper.AllVariables = ["CaloCalTopoClusters",
                                     "MuonTruthParticles", "egammaTruthParticles",
                                     "TruthParticles", "TruthEvents", "TruthVertices",
                                     "MuonSegments",
+                                    "LVL1JetRoIs",
                                     "JetETMissChargedParticleFlowObjects",
                                     "JetETMissNeutralParticleFlowObjects",
                                     "Kt4EMTopoOriginEventShape","Kt4LCTopoOriginEventShape","Kt4EMPFlowEventShape",
                                     ]
-JETM3SlimmingHelper.ExtraVariables = ["Muons.energyLossType.EnergyLoss.ParamEnergyLoss.MeasEnergyLoss.EnergyLossSigma.MeasEnergyLossSigma.ParamEnergyLossSigmaPlus.ParamEnergyLossSigmaMinus"]
+JETM3SlimmingHelper.ExtraVariables = [
+  'HLT_xAOD__JetContainer_a4tcemsubjesFS.ActiveArea.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.AlgorithmType.AverageLArQF.BchCorrCell.CentroidR.ConstituentScale.DetectorEta.EMFrac.EnergyPerSampling.FracSamplingMax.FracSamplingMaxIndex.HECFrac.HECQuality.InputType.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_m.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_pt.JetEMScaleMomentum_eta.JetEMScaleMomentum_m.JetEMScaleMomentum_phi.JetEMScaleMomentum_pt.JetEtaJESScaleMomentum_eta.JetEtaJESScaleMomentum_m.JetEtaJESScaleMomentum_phi.JetEtaJESScaleMomentum_pt.JetPileupScaleMomentum_eta.JetPileupScaleMomentum_m.JetPileupScaleMomentum_phi.JetPileupScaleMomentum_pt.LArQuality.N90Constituents.NegativeE.OriginCorrected.PileupCorrected.SizeParameter.Timing.eta.kinematics.m.phi.pt',
+  'HLT_xAOD__JetContainer_a4tcemsubjesISFS.ActiveArea.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.AlgorithmType.AverageLArQF.BchCorrCell.CentroidR.ConstituentScale.DetectorEta.EMFrac.EnergyPerSampling.FracSamplingMax.FracSamplingMaxIndex.HECFrac.HECQuality.InputType.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_m.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_pt.JetEMScaleMomentum_eta.JetEMScaleMomentum_m.JetEMScaleMomentum_phi.JetEMScaleMomentum_pt.JetEtaJESScaleMomentum_eta.JetEtaJESScaleMomentum_m.JetEtaJESScaleMomentum_phi.JetEtaJESScaleMomentum_pt.JetPileupScaleMomentum_eta.JetPileupScaleMomentum_m.JetPileupScaleMomentum_phi.JetPileupScaleMomentum_pt.LArQuality.N90Constituents.NegativeE.OriginCorrected.PileupCorrected.SizeParameter.Timing.eta.kinematics.m.phi.pt',
+  "Electrons."+NewTrigVars["Electrons"],
+  "Muons.energyLossType.EnergyLoss.ParamEnergyLoss.MeasEnergyLoss.EnergyLossSigma.MeasEnergyLossSigma.ParamEnergyLossSigmaPlus.ParamEnergyLossSigmaMinus."+NewTrigVars["Muons"],
+  "AntiKt4TruthWZJets.pt","AntiKt4TruthWZJets.eta", "AntiKt4TruthWZJets.phi", "AntiKt4TruthWZJets.m"]
 for truthc in [
     "TruthMuons",
     "TruthElectrons",
@@ -241,7 +317,12 @@ JETM3SlimmingHelper.IncludeMuonTriggerContent = True
 JETM3SlimmingHelper.IncludeEGammaTriggerContent = True
 
 # Add the jet containers to the stream
-addJetOutputs(JETM3SlimmingHelper,["SmallR","JETM3"])
+addJetOutputs(
+    slimhelper = JETM3SlimmingHelper,
+    contentlist = ["SmallR","JETM3"],
+    smartlist = JETM3SlimmingHelper.SmartCollections
+    )
+
 # Add the MET containers to the stream
 addMETOutputs(JETM3SlimmingHelper,["Diagnostic","Assocs","TruthAssocs","Track","JETM3"])
 
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM4.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM4.py
index df0b8dd591e91742888c91a1aa64dd9d154ebe49..3039e4f247b7cf5831f9ebe5e03ae1de0e5aba80 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM4.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM4.py
@@ -1,6 +1,6 @@
 #====================================================================
-# JETM4.py 
-# reductionConf flag JETM4 in Reco_tf.py   
+# JETM4.py
+# reductionConf flag JETM4 in Reco_tf.py
 #====================================================================
 
 from DerivationFrameworkCore.DerivationFrameworkMaster import *
@@ -11,16 +11,16 @@ from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
 from DerivationFrameworkJetEtMiss.METCommon import *
 #
 if DerivationFrameworkIsMonteCarlo:
-    from DerivationFrameworkMCTruth.MCTruthCommon import *
-    from DerivationFrameworkTau.TauTruthCommon import *
+  from DerivationFrameworkMCTruth.MCTruthCommon import addStandardTruthContents
+  addStandardTruthContents()
 
 #====================================================================
-# SKIMMING TOOL 
+# SKIMMING TOOL
 #====================================================================
 # NOTE: need to add isSimulation as OR with trigger
 
-from DerivationFrameworkJetEtMiss.TriggerLists import *
-triggerlist = singlePhotonTriggers
+from DerivationFrameworkJetEtMiss import TriggerLists
+triggerlist = TriggerLists.single_photon_Trig()
 
 triggers = '||'.join(triggerlist)
 expression = '( (EventInfo.eventTypeBitmask==1) || ('+triggers+') )'
@@ -30,8 +30,13 @@ JETM4SkimmingTool = DerivationFramework__xAODStringSkimmingTool( name = "JETM4Sk
                                                                     expression = expression)
 ToolSvc += JETM4SkimmingTool
 
+#Trigger matching decorations
+from DerivationFrameworkCore.TriggerMatchingAugmentation import applyTriggerMatching
+TrigMatchAug, NewTrigVars = applyTriggerMatching(ToolNamePrefix="JETM4",
+                                                 PhotonTriggers=TriggerLists.single_photon_Trig())
+
 #====================================================================
-# SET UP STREAM   
+# SET UP STREAM
 #====================================================================
 streamName = derivationFlags.WriteDAOD_JETM4Stream.StreamName
 fileName   = buildFileName( derivationFlags.WriteDAOD_JETM4Stream )
@@ -48,7 +53,7 @@ JETM4ThinningHelper = ThinningHelper( "JETM4ThinningHelper" )
 JETM4ThinningHelper.AppendToStream( JETM4Stream )
 
 #====================================================================
-# THINNING TOOLS 
+# THINNING TOOLS
 #====================================================================
 thinningTools = []
 
@@ -90,7 +95,7 @@ thinningTools.append(JETM4TPThinningTool)
 # TrackParticles associated with taus
 from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TauTrackParticleThinning
 JETM4TauTPThinningTool = DerivationFramework__TauTrackParticleThinning( name            = "JETM4TauTPThinningTool",
-                                                                        StreamName              = streamName,
+                                                                        StreamName      = streamName,
                                                                         TauKey          = "TauJets",
                                                                         InDetTrackParticlesKey  = "InDetTrackParticles")
 ToolSvc += JETM4TauTPThinningTool
@@ -106,9 +111,9 @@ if doTruthThinning and DerivationFrameworkIsMonteCarlo:
     truth_cond_Quark  = "((abs(TruthParticles.pdgId) <=  5  && (TruthParticles.pt > 10000.)) || (abs(TruthParticles.pdgId) == 6))"                 # Quarks
     truth_cond_Gluon  = "((abs(TruthParticles.pdgId) == 21) && (TruthParticles.pt > 10000.))"                                                # Gluons
     truth_cond_Photon = "((abs(TruthParticles.pdgId) == 22) && (TruthParticles.pt > 10000.) && (TruthParticles.barcode < 200000))"                 # Photon
-    
+
     truth_expression = '('+truth_cond_WZH+' || '+truth_cond_Lepton +' || '+truth_cond_Quark+'||'+truth_cond_Gluon+' || '+truth_cond_Photon+')'
-    
+
     from DerivationFrameworkMCTruth.DerivationFrameworkMCTruthConf import DerivationFramework__GenericTruthThinning
     JETM4TruthThinningTool = DerivationFramework__GenericTruthThinning( name = "JETM4TruthThinningTool",
                                                                         StreamName              = streamName,
@@ -116,9 +121,9 @@ if doTruthThinning and DerivationFrameworkIsMonteCarlo:
                                                                         PreserveDescendants     = preserveAllDescendants,
                                                                         PreserveGeneratorDescendants = not preserveAllDescendants,
                                                                         PreserveAncestors = True)
-    
+
     ToolSvc += JETM4TruthThinningTool
-    thinningTools.append(JETM4TruthThinningTool)    
+    thinningTools.append(JETM4TruthThinningTool)
 
 #=======================================
 # CREATE PRIVATE SEQUENCE
@@ -128,19 +133,35 @@ jetm4Seq = CfgMgr.AthSequencer("JETM4Sequence")
 DerivationFrameworkJob += jetm4Seq
 
 #=======================================
-# CREATE THE DERIVATION KERNEL ALGORITHM   
+# CREATE THE DERIVATION KERNEL ALGORITHM
 #=======================================
 
 from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
 jetm4Seq += CfgMgr.DerivationFramework__DerivationKernel("JETM4Kernel" ,
                                                          SkimmingTools = [JETM4SkimmingTool],
-                                                         ThinningTools = thinningTools)
+                                                         ThinningTools = thinningTools,
+                                                         AugmentationTools = [TrigMatchAug])
 #====================================================================
 # Special jets
 #====================================================================
 
 OutputJets["JETM4"] = []
 
+#==================================================================== 
+# BUILD UFO INPUTS
+#==================================================================== 
+
+from JetRecTools.ConstModHelpers import getConstModSeq
+pflowCSSKSeq = getConstModSeq(["CS","SK"], "EMPFlow")
+
+# add the pflow cssk sequence to the main jetalg if not already there :
+if pflowCSSKSeq.getFullName() not in [t.getFullName() for t in DerivationFrameworkJob.jetalg.Tools]:
+    DerivationFrameworkJob.jetalg.Tools += [pflowCSSKSeq]
+
+from TrackCaloClusterRecTools.TrackCaloClusterConfig import runUFOReconstruction 
+emufoAlg = runUFOReconstruction(jetm4Seq,ToolSvc, PFOPrefix="CHS")
+runUFOReconstruction(jetm4Seq, ToolSvc, PFOPrefix="CSSK")
+
 #=======================================
 # RESTORE AOD-REDUCED JET COLLECTIONS
 #=======================================
@@ -148,12 +169,30 @@ reducedJetList = ["AntiKt2PV0TrackJets",
                   "AntiKt4PV0TrackJets",
                   "AntiKt10PV0TrackJets",
                   "AntiKt4TruthJets",
-                  "AntiKt10TruthJets"]
+                  "AntiKt10TruthJets",
+                  "AntiKt10LCTopoJets",
+                  "AntiKt10TruthJets",
+                  "AntiKt10UFOCSSKJets",
+                  "AntiKt10UFOCHSJets"]
 replaceAODReducedJets(reducedJetList,jetm4Seq,"JETM4")
 
 # AntiKt10*PtFrac5Rclus20
 addDefaultTrimmedJets(jetm4Seq,"JETM4")
 
+# UFO Trimmed jets
+addTrimmedJets("AntiKt", 1.0, "UFOCSSK", rclus=0.2, ptfrac=0.05, algseq=jetm4Seq, outputGroup="JETM4", writeUngroomed=False, mods="tcc_groomed")
+addTrimmedJets("AntiKt", 1.0, "UFOCHS", rclus=0.2, ptfrac=0.05, algseq=jetm4Seq, outputGroup="JETM4", writeUngroomed=False, mods="tcc_groomed")
+# CSSK UFO SoftDrop jets
+addSoftDropJets("AntiKt", 1.0, "UFOCSSK", beta=1.0, zcut=0.1, algseq=jetm4Seq, outputGroup="JETM4", writeUngroomed=False, mods="tcc_groomed")
+addRecursiveSoftDropJets('AntiKt', 1.0, 'UFOCSSK', beta=1.0, zcut=0.05, N=-1,  mods="tcc_groomed", algseq=jetm4Seq, outputGroup="JETM4", writeUngroomed=False)
+addBottomUpSoftDropJets('AntiKt', 1.0, 'UFOCSSK', beta=1.0, zcut=0.05, mods="tcc_groomed", algseq=jetm4Seq, outputGroup="JETM4", writeUngroomed=False)
+
+#====================================================================
+# ADD PFLOW AUG INFORMATION 
+#====================================================================
+from DerivationFrameworkJetEtMiss.PFlowCommon import applyPFOAugmentation
+applyPFOAugmentation(DerivationFrameworkJob)
+
 #=======================================
 # SCHEDULE CUSTOM MET RECONSTRUCTION
 #=======================================
@@ -163,6 +202,44 @@ if DerivationFrameworkIsMonteCarlo:
     addMETTruthMap('AntiKt4LCTopo',"JETMX")
     addMETTruthMap('AntiKt4EMPFlow',"JETMX")
     scheduleMETAssocAlg(jetm4Seq,"JETMX")
+    addJetPtAssociation(jetalg="AntiKt4EMTopo",  truthjetalg="AntiKt4TruthJets", sequence=jetm4Seq, algname="JetPtAssociationAlg")
+    addJetPtAssociation(jetalg="AntiKt4LCTopo",  truthjetalg="AntiKt4TruthJets", sequence=jetm4Seq, algname="JetPtAssociationAlg")
+    addJetPtAssociation(jetalg="AntiKt4EMPFlow", truthjetalg="AntiKt4TruthJets", sequence=jetm4Seq, algname="JetPtAssociationAlg")
+
+
+#===================================================
+#add variable-R track jets for b-tagging
+#===================================================
+
+largeRJetCollections = [
+    "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets",
+    "AntiKt10UFOCSSKTrimmedPtFrac5SmallR20Jets",
+    "AntiKt10UFOCHSTrimmedPtFrac5SmallR20Jets",
+    "AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets",
+    "AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5Jets",
+    "AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJets",
+    ]
+
+from DerivationFrameworkFlavourTag.HbbCommon import addVRJets
+addVRJets(jetm4Seq,largeRColls=largeRJetCollections)
+addVRJets(jetm4Seq,largeRColls=largeRJetCollections, training='201903')
+
+from BTagging.BTaggingFlags import BTaggingFlags
+BTaggingFlags.CalibrationChannelAliases += ["AntiKtVR30Rmax4Rmin02Track->AntiKtVR30Rmax4Rmin02Track,AntiKt4EMTopo"]
+
+#=======================================
+# Re-tag PFlow jets so they have b-tagging info
+#=======================================
+
+from DerivationFrameworkFlavourTag.FlavourTagCommon import FlavorTagInit
+FlavorTagInit(JetCollections = ['AntiKt4EMPFlowJets'], Sequencer = jetm4Seq)
+
+#===============================
+# add xbb taggers
+#===============================
+from DerivationFrameworkFlavourTag.HbbCommon import addRecommendedXbbTaggers
+addRecommendedXbbTaggers(jetm4Seq, ToolSvc)
+
 
 #====================================================================
 # Add the containers to the output stream - slimming done here
@@ -174,16 +251,43 @@ JETM4SlimmingHelper.SmartCollections = ["Electrons", "Photons", "Muons", "TauJet
                                         "MET_Reference_AntiKt4EMTopo",
                                         "MET_Reference_AntiKt4LCTopo",
                                         "MET_Reference_AntiKt4EMPFlow",
-                                        "AntiKt4EMTopoJets","AntiKt4LCTopoJets","AntiKt4EMPFlowJets",
+                                        "AntiKt10TruthJets",
+                                        "AntiKt10LCTopoJets",
+                                        "AntiKt10UFOCSSKJets",
+                                        "AntiKt10UFOCHSJets",
+                                        "AntiKt10TruthTrimmedPtFrac5SmallR20Jets",
                                         "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets",
-                                        "BTagging_AntiKt4EMTopo"]
+                                        "AntiKt10UFOCHSTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10UFOCSSKTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets",
+                                        "AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5Jets",
+                                        "AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJets",
+                                        "AntiKtVR30Rmax4Rmin02TrackJets_BTagging201810",
+                                        "AntiKtVR30Rmax4Rmin02TrackJets_BTagging201903",
+                                        "AntiKt4EMPFlowJets_BTagging201810",
+                                        "AntiKt4EMPFlowJets_BTagging201903",
+                                        "AntiKt4EMTopoJets_BTagging201810",
+                                        "BTagging_AntiKt4EMPFlow_201810",
+                                        "BTagging_AntiKt4EMPFlow_201903",
+                                        "BTagging_AntiKt4EMTopo_201810",
+                                        "BTagging_AntiKtVR30Rmax4Rmin02Track_201810",
+                                        "BTagging_AntiKtVR30Rmax4Rmin02Track_201903"
+                                        ]
+
 JETM4SlimmingHelper.AllVariables = [# "CaloCalTopoClusters",
                                     "MuonTruthParticles", "egammaTruthParticles",
                                     "TruthParticles", "TruthEvents", "TruthVertices",
                                     "MuonSegments",
-                                    "Kt4EMTopoOriginEventShape","Kt4LCTopoOriginEventShape","Kt4EMPFlowEventShape",
-                                    ]
-#JETM4SlimmingHelper.ExtraVariables = []
+                                    "Kt4EMTopoOriginEventShape","Kt4LCTopoOriginEventShape","Kt4EMPFlowEventShape"]
+
+JETM4SlimmingHelper.ExtraVariables = ["CaloCalTopoClusters.calE.calEta.calPhi.calM.rawE.rawEta.rawPhi.rawM","Photons."+NewTrigVars["Photons"],"JetETMissNeutralParticleFlowObjects.m.mEM.eflowRec_TIMING.eflowRec_AVG_LAR_Q.eflowRec_CENTER_LAMBDA.pt.ptEM.phi.eta",
+"JetETMissChargedParticleFlowObjects.pt.eta.phi.m.eflowRec_tracksExpectedEnergyDeposit.charge.eflowRec_isInDenseEnvironment.pfo_TrackLinks.DFCommonPFlow_z0.DFCommonPFlow_vz.DFCommonPFlow_d0.DFCommonPFlow_theta.DFCommonPFlow_envWeight",
+"TauJets.truthJetLink.truthParticleLink.IsTruthMatched"]
+
+# XbbScore variables
+from DerivationFrameworkFlavourTag.HbbCommon import xbbTaggerExtraVariables
+JETM4SlimmingHelper.ExtraVariables += xbbTaggerExtraVariables
+
 for truthc in [
     "TruthMuons",
     "TruthElectrons",
@@ -198,11 +302,15 @@ for truthc in [
 JETM4SlimmingHelper.IncludeEGammaTriggerContent = True
 
 # Add the jet containers to the stream
-addJetOutputs(JETM4SlimmingHelper,["SmallR",
-                                   #"AntiKt4TruthWZJets",
-                                   "AntiKt10LCTopoJets",
-                                   "AntiKt10TruthJets",
-                                   "JETM4"])
+addJetOutputs(
+    slimhelper = JETM4SlimmingHelper,
+    contentlist = [
+      "SmallR",
+      "JETM4"
+      ],
+    smartlist = JETM4SlimmingHelper.SmartCollections,
+    )
+
 # Add the MET containers to the stream
 addMETOutputs(JETM4SlimmingHelper,["Diagnostic","Assocs","TruthAssocs","Track",])
 
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM5.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM5.py
index b072db9d135c6ed3e142c72d8afdbef424ff29b7..742701a41f39de0a5f780241bad50fac5776bb93 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM5.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM5.py
@@ -5,13 +5,8 @@
 
 from DerivationFrameworkCore.DerivationFrameworkMaster import *
 from DerivationFrameworkJetEtMiss.JetCommon import *
-#from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
-#
+from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
 from DerivationFrameworkJetEtMiss.METCommon import *
-#
-if DerivationFrameworkIsMonteCarlo:
-    from DerivationFrameworkMCTruth.MCTruthCommon import *
-    from DerivationFrameworkTau.TauTruthCommon import *
 
 #====================================================================
 # SET UP STREAM   
@@ -23,6 +18,16 @@ JETM5Stream.AcceptAlgs(["JETM5Kernel"])
 augStream = MSMgr.GetStream( streamName )
 evtStream = augStream.GetEventStream()
 
+if DerivationFrameworkIsMonteCarlo:
+  from DerivationFrameworkMCTruth.MCTruthCommon import addStandardTruthContents
+  addStandardTruthContents()
+
+#====================================================================
+# ADD PFLOW AUG INFORMATION 
+#====================================================================
+from DerivationFrameworkJetEtMiss.PFlowCommon import applyPFOAugmentation
+applyPFOAugmentation(DerivationFrameworkJob)
+
 #====================================================================
 # SKIMMING TOOL 
 #====================================================================
@@ -96,14 +101,38 @@ if doTruthThinning and DerivationFrameworkIsMonteCarlo:
     ToolSvc += JETM5TruthThinningTool
     thinningTools.append(JETM5TruthThinningTool)    
 
+#=======================================
+# CREATE PRIVATE SEQUENCE
+#=======================================
+
+jetm5Seq = CfgMgr.AthSequencer("JETM5Sequence")
+DerivationFrameworkJob += jetm5Seq
+
 #=======================================
 # CREATE THE DERIVATION KERNEL ALGORITHM   
 #=======================================
 
 from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
-DerivationFrameworkJob += CfgMgr.DerivationFramework__DerivationKernel(	name = "JETM5Kernel",
-									SkimmingTools = [JETM5SkimmingTool],
-									ThinningTools = thinningTools)
+jetm5Seq += CfgMgr.DerivationFramework__DerivationKernel(	name = "JETM5Kernel",
+                                                                SkimmingTools = [JETM5SkimmingTool],
+                                                                ThinningTools = thinningTools)
+
+#====================================================================
+# BTAGGING INFO FOR PFLOW JET
+#====================================================================
+from DerivationFrameworkFlavourTag.FlavourTagCommon import FlavorTagInit
+FlavorTagInit(JetCollections = ['AntiKt4EMPFlowJets'],Sequencer = jetm5Seq)
+
+# QGTaggerTool ###
+addQGTaggerTool(jetalg="AntiKt4EMTopo", sequence=jetm5Seq, algname="QGTaggerToolAlg")
+addQGTaggerTool(jetalg="AntiKt4EMPFlow", sequence=jetm5Seq, algname="QGTaggerToolAlg")
+
+# MVfJvt #
+applyMVfJvtAugmentation(jetalg='AntiKt4EMTopo',sequence=jetm5Seq, algname='JetForwardJvtToolBDTAlg')
+
+# PFlow fJvt #
+getPFlowfJVT(jetalg='AntiKt4EMPFlow',sequence=jetm5Seq, algname='JetForwardPFlowJvtToolAlg',includePV=False)
+getPFlowfJVT(jetalg='AntiKt4EMPFlow',sequence=jetm5Seq, algname='JetForwardPFlowJvtToolAlgNew',outLabel="fJvtWithPV",includePV=True)
 
 #====================================================================
 # Add the containers to the output stream - slimming done here
@@ -116,14 +145,26 @@ JETM5SlimmingHelper.SmartCollections = ["Electrons", "Photons", "Muons", "TauJet
                                         "MET_Reference_AntiKt4LCTopo",
                                         "MET_Reference_AntiKt4EMPFlow",
                                         "AntiKt4EMTopoJets","AntiKt4LCTopoJets","AntiKt4EMPFlowJets",
-                                        "BTagging_AntiKt4EMTopo", ]
+                                        "AntiKt4EMPFlowJets_BTagging201810",
+                                        "AntiKt4EMPFlowJets_BTagging201903",
+                                        "AntiKt4EMTopoJets_BTagging201810",
+                                        "BTagging_AntiKt4EMPFlow_201810",
+                                        "BTagging_AntiKt4EMPFlow_201903",
+                                        "BTagging_AntiKt4EMTopo_201810"]
 JETM5SlimmingHelper.AllVariables = ["CaloCalTopoClusters",
                                     "MuonTruthParticles", "egammaTruthParticles",
                                     "TruthParticles", "TruthEvents", "TruthVertices",
                                     "MuonSegments",
                                     "Kt4EMTopoOriginEventShape","Kt4LCTopoOriginEventShape","Kt4EMPFlowEventShape",
                                     ]
-#JETM5SlimmingHelper.ExtraVariables = []
+JETM5SlimmingHelper.ExtraVariables = ["JetETMissNeutralParticleFlowObjects.m.mEM.pfo_TrackLinks.eflowRec_ISOLATION.pfo_ClusterLinks.eflowRec_TIMING.eflowRec_AVG_LAR_Q.eflowRec_EM_PROBABILITY.eflowRec_CENTER_LAMBDA.centerMag.pt.ptEM.phi.eta",
+"JetETMissChargedParticleFlowObjects.pt.eta.phi.m.eflowRec_tracksExpectedEnergyDeposit.pfo_vertex.charge.eflowRec_isInDenseEnvironment.pfo_TrackLinks.DFCommonPFlow_z0.DFCommonPFlow_vz.DFCommonPFlow_d0.DFCommonPFlow_theta.DFCommonPFlow_envWeight",]
+
+
+# Add QG tagger variables
+JETM5SlimmingHelper.ExtraVariables  += ["AntiKt4EMTopoJets.DFCommonJets_QGTagger_NTracks.DFCommonJets_QGTagger_TracksWidth.DFCommonJets_QGTagger_TracksC1",
+                                        "AntiKt4EMPFlowJets.DFCommonJets_QGTagger_NTracks.DFCommonJets_QGTagger_TracksWidth.DFCommonJets_QGTagger_TracksC1.DFCommonJets_fJvtWithPV"]
+
 for truthc in [
     "TruthMuons",
     "TruthElectrons",
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM6.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM6.py
index 7d923532d173bf8aa909831087757a1bd98df6a5..64dd2e7ef538a86a000bd356b9e94b065d652f87 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM6.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM6.py
@@ -1,6 +1,6 @@
 #====================================================================
-# JETM6.py 
-# reductionConf flag JETM6 in Reco_tf.py   
+# JETM6.py
+# reductionConf flag JETM6 in Reco_tf.py
 #====================================================================
 
 from DerivationFrameworkCore.DerivationFrameworkMaster import *
@@ -10,11 +10,11 @@ from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
 from DerivationFrameworkEGamma.EGammaCommon import *
 from DerivationFrameworkMuons.MuonsCommon import *
 
+from DerivationFrameworkFlavourTag.HbbCommon import *
+
 from DerivationFrameworkJetEtMiss.METCommon import *
-#
-if DerivationFrameworkIsMonteCarlo:
-    from DerivationFrameworkMCTruth.MCTruthCommon import *
-    from DerivationFrameworkTau.TauTruthCommon import *
+
+from DerivationFrameworkInDet.InDetCommon import *
 
 #====================================================================
 # SET UP STREAM   
@@ -27,32 +27,36 @@ augStream = MSMgr.GetStream( streamName )
 evtStream = augStream.GetEventStream()
 
 #====================================================================
-# SKIMMING TOOL 
+# SKIMMING TOOL
 #====================================================================
 
-from DerivationFrameworkJetEtMiss.TriggerLists import *
-electronTriggers = singleElTriggers
-muonTriggers = singleMuTriggers
-photonTriggers = singlePhotonTriggers
+from DerivationFrameworkJetEtMiss import TriggerLists
+electronTriggers = TriggerLists.single_el_Trig()
+muonTriggers = TriggerLists.single_mu_Trig()
+photonTriggers = TriggerLists.single_photon_Trig()
+jetTriggers = TriggerLists.jetTrig()
 
 # For first data
-jetSelection = '(count( AntiKt10LCTopoJets.pt > 180.*GeV && abs(AntiKt10LCTopoJets.eta) < 2.5 ) >=1)'
-#jetSelection = '(count( CamKt12LCTopoJets.pt > 150.*GeV ) >=1)'
+jetSelection = '(count( AntiKt10LCTopoJets.pt > 400.*GeV && abs(AntiKt10LCTopoJets.eta) < 2.5 ) >=1 || count( AntiKt10UFOCSSKJets.pt > 400.*GeV && abs(AntiKt10UFOCSSKJets.eta) < 2.5 ) >= 1)'
+if DerivationFrameworkIsMonteCarlo:
+  jetSelection = '(count( AntiKt10LCTopoJets.pt > 180.*GeV && abs(AntiKt10LCTopoJets.eta) < 2.5 ) >=1 || count( AntiKt10UFOCSSKJets.pt > 180.*GeV && abs(AntiKt10UFOCSSKJets.eta) < 2.5 ) >= 1)'
 
 orstr  = ' || '
 andstr = ' && '
 eltrigsel = '(EventInfo.eventTypeBitmask==1) || '+orstr.join(electronTriggers)
-elofflinesel = andstr.join(['count((Electrons.pt > 20*GeV) && (Electrons.DFCommonElectronsLHMedium)) == 1',
-                            'count(AntiKt10LCTopoJets.pt > 150*GeV && abs(AntiKt10LCTopoJets.eta) < 2.5) >=1'])
+elofflinesel = andstr.join(['count((Electrons.pt > 20*GeV) && (Electrons.DFCommonElectronsLHLoose)) >= 1',
+                            '(count(AntiKt10LCTopoJets.pt > 150*GeV && abs(AntiKt10LCTopoJets.eta) < 2.5) >=1 || count(AntiKt10UFOCSSKJets.pt > 150*GeV && abs(AntiKt10UFOCSSKJets.eta) < 2.5) >=1)'])
 electronSelection = '( (' + eltrigsel + ') && (' + elofflinesel + ') )'
 
 mutrigsel = '(EventInfo.eventTypeBitmask==1) || '+orstr.join(muonTriggers)
-muofflinesel = andstr.join(['count((Muons.pt > 20*GeV) && (Muons.DFCommonMuonsPreselection)) == 1',
-                            'count(AntiKt10LCTopoJets.pt > 150*GeV && abs(AntiKt10LCTopoJets.eta) < 2.5) >=1'])
+muofflinesel = andstr.join(['count((Muons.pt > 20*GeV) && (Muons.DFCommonMuonsPreselection)) >= 1',
+                            '(count(AntiKt10LCTopoJets.pt > 150*GeV && abs(AntiKt10LCTopoJets.eta) < 2.5) >=1 || count(AntiKt10UFOCSSKJets.pt > 150*GeV && abs(AntiKt10UFOCSSKJets.eta) < 2.5) >=1 )'])
 muonSelection = ' ( (' + mutrigsel + ') && (' + muofflinesel + ') ) '
-# MET filter wanted? : MET_Reference_AntiKt4LCTopo > 20*GeV # should use a different container
+gammatrigsel = '(EventInfo.eventTypeBitmask==1) || '+orstr.join(photonTriggers)
+gammaofflinesel = '(count(Photons.pt > 150*GeV) >= 1 && (count(AntiKt10LCTopoJets.pt > 150*GeV && abs(AntiKt10LCTopoJets.eta) < 2.5) >=1 || count(AntiKt10UFOCSSKJets.pt > 150*GeV && abs(AntiKt10UFOCSSKJets.eta) < 2.5) >=1 ))'
+photonSelection = ' ( (' + gammatrigsel + ') && (' + gammaofflinesel + ') ) '
 
-lepSelection = '( ' + electronSelection + ' || ' + muonSelection + ' )'
+lepSelection = '( ' + electronSelection + ' || ' + muonSelection + ' || ' + photonSelection + ' )'
 
 
 expression = jetSelection + ' || '+ lepSelection
@@ -70,37 +74,123 @@ JETM6OfflineSkimmingTool = DerivationFramework__xAODStringSkimmingTool( name = "
 ToolSvc += JETM6OfflineSkimmingTool
 
 #====================================================================
-# THINNING TOOLS 
+# CREATE PRIVATE SEQUENCE
 #====================================================================
-thinningTools = []
 
-# thinning_expression = "InDetTrackParticles.pt > 0.5*GeV"
+jetm6Seq = CfgMgr.AthSequencer("JETM6Sequence")
+DerivationFrameworkJob += jetm6Seq
+
+#====================================================================
+# Trigger matching decorations
+#====================================================================
+photonTriggers_matching = ['HLT_g60_loose', 'HLT_g140_loose', 'HLT_g160_loose']
+
+from DerivationFrameworkCore.TriggerMatchingAugmentation import applyTriggerMatching
+TrigMatchAug, NewTrigVars = applyTriggerMatching(ToolNamePrefix="JETM6",
+                                   ElectronTriggers=electronTriggers,
+                                   MuonTriggers=muonTriggers,
+                                   PhotonTriggers=photonTriggers_matching)
+
+#====================================================================
+# TRIGGER THINNING TOOL
+#====================================================================
+
+from DerivationFrameworkCore.ThinningHelper import ThinningHelper
+JETM6ThinningHelper = ThinningHelper( "JETM6ThinningHelper" )
+JETM6ThinningHelper.TriggerChains = ''
+
+JETM6ThinningHelper.TriggerChains += "|".join(electronTriggers)
+JETM6ThinningHelper.TriggerChains += "|".join(muonTriggers)
+JETM6ThinningHelper.TriggerChains += "|".join(photonTriggers)
+JETM6ThinningHelper.TriggerChains += "|".join(jetTriggers)
+
+JETM6ThinningHelper.AppendToStream( JETM6Stream )
+
+#====================================================================
+# THINNING TOOLS
+#====================================================================
+thinningTools = []
 
-# from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__JetTrackParticleThinning
-# JETM6JetTPThinningTool = DerivationFramework__JetTrackParticleThinning( name          = "JETM6Akt4JetTPThinningTool",
-#                                                                         StreamName              = streamName,
-#                                                                         JetKey                  = "AntiKt4EMTopoJets",
-#                                                                         InDetTrackParticlesKey  = "InDetTrackParticles",
-#                                                                         TrackSelectionString    = thinning_expression)
-# ToolSvc += JETM6JetTPThinningTool
-# thinningTools.append(JETM6JetTPThinningTool)
+#########################################
+# Tracks associated with akt2 jets
+#########################################
+# It is necessary to apply the akt2-based track thinning before other track
+# thinning tools due to the faulty logic of the thinning tools
+from ThinningUtils.ThinningUtilsConf import DeltaRThinningTool
+# Applying only DeltaR thinning and not EleLink thinning is fine as long as ConeSize
+# is sufficiently large compared to the jet size.  If it is reduced to something close
+# to the size of the jet, there is no guarantee that all ghost-associated tracks will
+# be picked up
+
+JETM6BaselineTrack = "(InDetTrackParticles.JETM6DFLoose) && (InDetTrackParticles.pt > 0.5*GeV) && (abs(DFCommonInDetTrackZ0AtPV)*sin(InDetTrackParticles.theta) < 3.0*mm) && (InDetTrackParticles.d0 < 2.0*mm)"
+
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TrackParticleThinning
+JETM6TrackParticleThinningTool = DerivationFramework__TrackParticleThinning(name            = "JETM6TrackParticleThinningTool",
+                                                                            StreamName      = streamName,
+                                                                            SelectionString = JETM6BaselineTrack,
+                                                                            InDetTrackParticlesKey = "InDetTrackParticles",
+                                                                            ApplyAnd        = True)
+
+ToolSvc += JETM6TrackParticleThinningTool
+thinningTools.append(JETM6TrackParticleThinningTool)
+
+JETM6ak2DeltaRTrackThinningTool = DeltaRThinningTool(name            = "JETM6ak2DeltaRTrackThinningTool",
+                                                     StreamName      = streamName,
+                                                     SGKey           = "InDetTrackParticles",
+                                                     ConeSize        = 0.33,
+                                                     ApplyAnd        = True)
+
+ToolSvc += JETM6ak2DeltaRTrackThinningTool
+
+from ThinningUtils.ThinningUtilsConf import ThinAssociatedObjectsTool
+JETM6ak2TrackThinningTool = ThinAssociatedObjectsTool(name               = "JETM6ak2TrackThinningTool",
+                                                      StreamName         = streamName,
+                                                      SGKey              = "AntiKt2LCTopoJets",
+                                                      ChildThinningTools = [JETM6ak2DeltaRTrackThinningTool])
+
+ToolSvc += JETM6ak2TrackThinningTool
+thinningTools.append(JETM6ak2TrackThinningTool)
+
+#########################################
+# Tracks associated with other jets
+#########################################
 
 from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__JetTrackParticleThinning
 JETM6Akt4JetTPThinningTool = DerivationFramework__JetTrackParticleThinning( name          = "JETM6Akt4JetTPThinningTool",
-                                                                        StreamName              = streamName,
-                                                                        JetKey                  = "AntiKt4EMTopoJets",
-                                                                        InDetTrackParticlesKey  = "InDetTrackParticles")
+                                                                            StreamName              = streamName,
+                                                                            JetKey                  = "AntiKt4EMTopoJets",
+                                                                            InDetTrackParticlesKey  = "InDetTrackParticles",
+                                                                            ApplyAnd                = False)
 ToolSvc += JETM6Akt4JetTPThinningTool
 thinningTools.append(JETM6Akt4JetTPThinningTool)
 
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__JetTrackParticleThinning
+JETM6Akt4PFlowJetTPThinningTool = DerivationFramework__JetTrackParticleThinning( name          = "JETM6Akt4PFlowJetTPThinningTool",
+                                                                                 StreamName              = streamName,
+                                                                                 JetKey                  = "AntiKt4EMPFlowJets",
+                                                                                 InDetTrackParticlesKey  = "InDetTrackParticles",
+                                                                                 ApplyAnd                = False)
+ToolSvc += JETM6Akt4PFlowJetTPThinningTool
+thinningTools.append(JETM6Akt4PFlowJetTPThinningTool)
+
 from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__JetTrackParticleThinning
 JETM6Akt10JetTPThinningTool = DerivationFramework__JetTrackParticleThinning( name          = "JETM6Akt10JetTPThinningTool",
-                                                                        StreamName              = streamName,
-                                                                        JetKey                  = "AntiKt10LCTopoJets",
-                                                                        InDetTrackParticlesKey  = "InDetTrackParticles")
+                                                                             StreamName              = streamName,
+                                                                             JetKey                  = "AntiKt10LCTopoJets",
+                                                                             InDetTrackParticlesKey  = "InDetTrackParticles",
+                                                                             ApplyAnd                = False)
 ToolSvc += JETM6Akt10JetTPThinningTool
 thinningTools.append(JETM6Akt10JetTPThinningTool)
 
+JETM6Akt10JetCSSKUFOThinningTool = DerivationFramework__JetTrackParticleThinning( name          = "JETM6Akt10JetCSSKUFOThinningTool",
+                                                                                  StreamName              = streamName,
+                                                                                  JetKey                  = "AntiKt10UFOCSSKJets",
+                                                                                  InDetTrackParticlesKey  = "InDetTrackParticles",
+                                                                                  ApplyAnd                = False)
+ToolSvc += JETM6Akt10JetCSSKUFOThinningTool
+thinningTools.append(JETM6Akt10JetCSSKUFOThinningTool)
+
+
 # TrackParticles associated with Muons
 from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__MuonTrackParticleThinning
 JETM6MuonTPThinningTool = DerivationFramework__MuonTrackParticleThinning(name     = "JETM6MuonTPThinningTool",
@@ -130,83 +220,148 @@ thinningTools.append(JETM6PhotonTPThinningTool)
 # TrackParticles associated with taus
 from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TauTrackParticleThinning
 JETM6TauTPThinningTool = DerivationFramework__TauTrackParticleThinning( name            = "JETM6TauTPThinningTool",
-                                                                        StreamName              = streamName,
+                                                                        StreamName      = streamName,
                                                                         TauKey          = "TauJets",
                                                                         InDetTrackParticlesKey  = "InDetTrackParticles")
 ToolSvc += JETM6TauTPThinningTool
 thinningTools.append(JETM6TauTPThinningTool)
 
-# Truth particle thinning
-doTruthThinning = True
-preserveAllDescendants = False
-from AthenaCommon.GlobalFlags import globalflags
-if doTruthThinning and DerivationFrameworkIsMonteCarlo:
-    truth_cond_WZH    = "((abs(TruthParticles.pdgId) >= 23) && (abs(TruthParticles.pdgId) <= 25))"            # W, Z and Higgs
-    truth_cond_Lepton = "((abs(TruthParticles.pdgId) >= 11) && (abs(TruthParticles.pdgId) <= 16) && (TruthParticles.barcode < 200000))"            # Leptons
-    truth_cond_Quark  = "((abs(TruthParticles.pdgId) <=  5  && (TruthParticles.pt > 10000.)) || (abs(TruthParticles.pdgId) == 6))"                 # Quarks
-    truth_cond_Gluon  = "((abs(TruthParticles.pdgId) == 21) && (TruthParticles.pt > 10000.))"                                                # Gluons
-    truth_cond_Photon = "((abs(TruthParticles.pdgId) == 22) && (TruthParticles.pt > 10000.) && (TruthParticles.barcode < 200000))"                 # Photon
-    
-    truth_expression = '('+truth_cond_WZH+' || '+truth_cond_Lepton +' || '+truth_cond_Quark+' || '+truth_cond_Gluon+' || '+truth_cond_Photon+')'
-    
-    from DerivationFrameworkMCTruth.DerivationFrameworkMCTruthConf import DerivationFramework__GenericTruthThinning
-    JETM6TruthThinningTool = DerivationFramework__GenericTruthThinning( name = "JETM6TruthThinningTool",
-                                                                        StreamName              = streamName,
-                                                                        ParticleSelectionString = truth_expression,
-                                                                        #PreserveDescendants     = preserveAllDescendants,
-                                                                        PreserveDescendants     = False,
-                                                                        PreserveGeneratorDescendants = not preserveAllDescendants,
-                                                                        #PreserveGeneratorDescendants = False,
-                                                                        PreserveAncestors = True)
-
-
-    
-    ToolSvc += JETM6TruthThinningTool
-    thinningTools.append(JETM6TruthThinningTool)    
+#====================================================================
+# AUGMENTATION TOOLS
+#====================================================================
+augmentationTools = []
+augmentationTools.append(TrigMatchAug)
+
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__InDetTrackSelectionToolWrapper
+JETM6TrackSelectionTool = DerivationFramework__InDetTrackSelectionToolWrapper(name = "JETM6TrackSelectionTool",
+                                                                              ContainerName = "InDetTrackParticles",
+                                                                              DecorationName = "JETM6DFLoose" )
+
+JETM6TrackSelectionTool.TrackSelectionTool.CutLevel = "Loose"
+ToolSvc += JETM6TrackSelectionTool
+augmentationTools.append(JETM6TrackSelectionTool)
+
 
 #=======================================
-# CREATE PRIVATE SEQUENCE
+# CREATE THE DERIVATION KERNEL ALGORITHM
 #=======================================
 
-jetm6Seq = CfgMgr.AthSequencer("JETM6Sequence")
-DerivationFrameworkJob += jetm6Seq
+from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
+jetm6Seq += CfgMgr.DerivationFramework__DerivationKernel(name = "JETM6TrigSkimKernel",
+                                                         AugmentationTools = [] ,
+                                                         SkimmingTools = [JETM6TrigSkimmingTool],
+                                                         ThinningTools = [])
+
 
 #=======================================
-# CREATE THE DERIVATION KERNEL ALGORITHM   
+# BUILD UFO INPUTS
 #=======================================
 
-from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
-jetm6Seq += CfgMgr.DerivationFramework__DerivationKernel(	name = "JETM6TrigSkimKernel",
-                                                            AugmentationTools = [] , 
-                                                            SkimmingTools = [JETM6TrigSkimmingTool],
-                                                            ThinningTools = [])
+## Add PFlow constituents
+from JetRecTools.ConstModHelpers import getConstModSeq, xAOD
+pflowCSSKSeq = getConstModSeq(["CS","SK"], "EMPFlow")
+
+# add the pflow cssk sequence to the main jetalg if not already there :
+if pflowCSSKSeq.getFullName() not in [t.getFullName() for t in DerivationFrameworkJob.jetalg.Tools]:
+  DerivationFrameworkJob.jetalg.Tools += [pflowCSSKSeq]
+
+# Add UFO constituents
+from TrackCaloClusterRecTools.TrackCaloClusterConfig import runUFOReconstruction
+emufoAlg = runUFOReconstruction(jetm6Seq, ToolSvc, PFOPrefix="CHS")
+emcsskufoAlg = runUFOReconstruction(jetm6Seq, ToolSvc, PFOPrefix="CSSK")
 
 #=======================================
 # RESTORE AOD-REDUCED JET COLLECTIONS
 #=======================================
+
 reducedJetList = ["AntiKt2PV0TrackJets",
                   "AntiKt4PV0TrackJets",
+                  "AntiKt2TruthJets",
+                  "AntiKt2LCTopoJets",
                   "AntiKt4TruthJets",
                   "AntiKt10TruthJets",
-                  "AntiKt10LCTopoJets"]
+                  "AntiKt10LCTopoJets",
+                  "AntiKt10UFOCSSKJets",
+                  "AntiKt10UFOCHSJets"
+                  ]
+
 replaceAODReducedJets(reducedJetList,jetm6Seq,"JETM6")
 
 from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
 jetm6Seq += CfgMgr.DerivationFramework__DerivationKernel( name = "JETM6MainKernel",
-                                                          AugmentationTools = [] , 
+                                                          AugmentationTools = augmentationTools,
                                                           SkimmingTools = [JETM6OfflineSkimmingTool],
                                                           ThinningTools = thinningTools)
 
 #====================================================================
-# Special jets
+# GROOMED LARGE-R JETS
 #====================================================================
 
 OutputJets["JETM6"] = []
 
-# AntiKt10*PtFrac5Rclus20
 addDefaultTrimmedJets(jetm6Seq,"JETM6")
 
-addTrimmedJets("AntiKt", 1.0, "PV0Track", rclus=0.2, ptfrac=0.05, algseq=jetm6Seq, outputGroup="JETM6")
+if DerivationFrameworkIsMonteCarlo:
+  addSoftDropJets('AntiKt', 1.0, 'Truth', beta=1.0, zcut=0.1, mods="truth_groomed", algseq=jetm6Seq, outputGroup="JETM6", writeUngroomed=False)
+  addRecursiveSoftDropJets('AntiKt', 1.0, 'Truth', beta=1.0, zcut=0.05, N=-1,  mods="truth_groomed", algseq=jetm6Seq, outputGroup="JETM6", writeUngroomed=False)
+  addBottomUpSoftDropJets('AntiKt', 1.0, 'Truth', beta=1.0, zcut=0.05, mods="truth_groomed", algseq=jetm6Seq, outputGroup="JETM6", writeUngroomed=False)
+
+addTrimmedJets("AntiKt", 1.0, "UFOCHS", rclus=0.2, ptfrac=0.05, algseq=jetm6Seq, outputGroup="JETM6", writeUngroomed=False, mods="tcc_groomed")
+addTrimmedJets("AntiKt", 1.0, "UFOCSSK", rclus=0.2, ptfrac=0.05, algseq=jetm6Seq, outputGroup="JETM6", writeUngroomed=False, mods="tcc_groomed")
+addSoftDropJets("AntiKt", 1.0, "UFOCSSK", beta=1.0, zcut=0.1, algseq=jetm6Seq, outputGroup="JETM6", writeUngroomed=False, mods="tcc_groomed")
+addRecursiveSoftDropJets('AntiKt', 1.0, 'UFOCSSK', beta=1.0, zcut=0.05, N=-1,  mods="tcc_groomed", algseq=jetm6Seq, outputGroup="JETM6", writeUngroomed=False)
+addBottomUpSoftDropJets('AntiKt', 1.0, 'UFOCSSK', beta=1.0, zcut=0.05, mods="tcc_groomed", algseq=jetm6Seq, outputGroup="JETM6", writeUngroomed=False)
+
+#====================================================================
+# BTAGGING INFO FOR PFLOW JETS
+#====================================================================
+
+from DerivationFrameworkFlavourTag.FlavourTagCommon import FlavorTagInit
+FlavorTagInit(JetCollections = ['AntiKt4EMPFlowJets'],Sequencer = jetm6Seq)
+
+#====================================================================
+# VR track-jets (b-tagging)
+#====================================================================
+
+largeRJetAlgs = [
+    "AntiKt10LCTopoTrimmedPtFrac5SmallR20",
+    "AntiKt10UFOCHSTrimmedPtFrac5SmallR20",
+    "AntiKt10UFOCSSKTrimmedPtFrac5SmallR20",
+    "AntiKt10UFOCSSKSoftDropBeta100Zcut10",
+    "AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5",
+    "AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5Ninf",
+    ]
+
+largeRJetCollections = []
+for alg in largeRJetAlgs:
+  largeRJetCollections.append(alg+"Jets")
+
+if DerivationFrameworkIsMonteCarlo:
+  for alg in largeRJetAlgs:
+    addJetTruthLabel(jetalg=alg,sequence=jetm6Seq,algname="JetTruthLabelingAlg",labelname="R10TruthLabel_R21Consolidated")
+
+addVRJets(jetm6Seq, largeRColls = largeRJetCollections)
+addVRJets(jetm6Seq, largeRColls = largeRJetCollections, training='201903')
+
+#====================================================================
+# add xbb taggers
+#====================================================================
+
+from DerivationFrameworkFlavourTag.HbbCommon import addRecommendedXbbTaggers
+addRecommendedXbbTaggers(jetm6Seq, ToolSvc)
+
+#====================================================================
+# TRUTH3
+#====================================================================
+
+if DerivationFrameworkIsMonteCarlo:
+  from DerivationFrameworkMCTruth.MCTruthCommon import addStandardTruthContents,addTopQuarkAndDownstreamParticles,addHFAndDownstreamParticles,addTruthCollectionNavigationDecorations
+  addStandardTruthContents()
+  addTopQuarkAndDownstreamParticles()
+  addHFAndDownstreamParticles(addB=True, addC=False, generations=0)
+  addTruthCollectionNavigationDecorations(TruthCollections=["TruthTopQuarkWithDecayParticles","TruthBosonsWithDecayParticles"],prefix='Top')
+  import DerivationFrameworkCore.WeightMetadata
+  import DerivationFrameworkCore.LHE3WeightMetadata
 
 #====================================================================
 # Add the containers to the output stream - slimming done here
@@ -219,68 +374,83 @@ JETM6SlimmingHelper.SmartCollections = ["Electrons",
                                         "TauJets",
                                         "InDetTrackParticles",
                                         "PrimaryVertices",
-                                        #
                                         "MET_Reference_AntiKt4EMTopo",
-                                        "MET_Reference_AntiKt4LCTopo",
                                         "MET_Reference_AntiKt4EMPFlow",
-                                        "AntiKt4EMTopoJets","AntiKt4LCTopoJets","AntiKt4EMPFlowJets",
-                                        "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets"
+                                        "AntiKt2TruthJets",
+                                        "AntiKt2LCTopoJets",
+                                        "AntiKt4EMTopoJets","AntiKt4EMPFlowJets","AntiKt4TruthJets",
+                                        "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10UFOCHSTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10UFOCSSKTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets",
+                                        "AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5Jets",
+                                        "AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJets",
+                                        "AntiKtVR30Rmax4Rmin02TrackJets_BTagging201810",
+                                        "AntiKtVR30Rmax4Rmin02TrackJets_BTagging201903",
+                                        "AntiKt4EMPFlowJets_BTagging201810",
+                                        "AntiKt4EMPFlowJets_BTagging201903",
+                                        "AntiKt4EMTopoJets_BTagging201810",
+                                        "BTagging_AntiKtVR30Rmax4Rmin02Track_201810",
+                                        "BTagging_AntiKtVR30Rmax4Rmin02Track_201903",
+                                        "BTagging_AntiKt4EMPFlow_201810",
+                                        "BTagging_AntiKt4EMPFlow_201903",
+                                        "BTagging_AntiKt4EMTopo_201810",
                                         ]
 JETM6SlimmingHelper.AllVariables = [
-    "TruthParticles",  "TruthEvents", "TruthVertices",
-    "MuonTruthParticles", "egammaTruthParticles",
-    #"JetETMissChargedParticleFlowObjects", "JetETMissNeutralParticleFlowObjects"
-    "Kt4EMTopoOriginEventShape","Kt4LCTopoOriginEventShape","Kt4EMPFlowEventShape",
-    ]
+  "TruthEvents",
+  "Kt4EMTopoOriginEventShape","Kt4EMPFlowEventShape",
+  ]
 
-JETM6SlimmingHelper.ExtraVariables = [
-    'CaloCalTopoClusters.calE.calEta.calM.calPhi.CENTER_MAG',
-    'BTagging_AntiKt2Track.MSV_N2Tpair.MSV_badTracksIP.MSV_energyTrkInJet.MSV_normdist.MSV_nvsec.MSV_vertices.MV1_discriminant.MV2c00_discriminant.MV2c100_discriminant.MV2c10_discriminant.MV2c20_discriminant.MV2m_pb.MV2m_pc.MV2m_pu.MultiSVbb1_discriminant.MultiSVbb2_discriminant.SV0_N2Tpair.SV1_pb.SV1_pc.SV1_pu.IP3D_pb.IP3D_pc.IP3D_pu',
-    'BTagging_AntiKt4EMTopo.MSV_N2Tpair.MSV_badTracksIP.MSV_energyTrkInJet.MSV_normdist.MSV_nvsec.MSV_vertices.MV1_discriminant.MV2c00_discriminant.MV2c100_discriminant.MV2c10_discriminant.MV2c20_discriminant.MV2m_pb.MV2m_pc.MV2m_pu.MultiSVbb1_discriminant.MultiSVbb2_discriminant.SV0_N2Tpair.SV1_pb.SV1_pc.SV1_pu.IP3D_pb.IP3D_pc.IP3D_pu'
+JETM6SlimmingHelper.ExtraVariables  = ['CaloCalTopoClusters.calE.calEta.calM.calPhi.CENTER_MAG']
+JETM6SlimmingHelper.ExtraVariables += ['Electrons.'+NewTrigVars["Electrons"],'Muons.'+NewTrigVars["Muons"],'Photons.'+NewTrigVars["Photons"]]
+JETM6SlimmingHelper.ExtraVariables += [
+    'HLT_xAOD__JetContainer_a4tcemsubjesFS.ActiveArea.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.AverageLArQF.BchCorrCell.CentroidR.DetectorEta.EMFrac.EnergyPerSampling.FracSamplingMax.FracSamplingMaxIndex.HECFrac.HECQuality.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_m.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_pt.JetEtaJESScaleMomentum_eta.JetEtaJESScaleMomentum_m.JetEtaJESScaleMomentum_phi.JetEtaJESScaleMomentum_pt.JetPileupScaleMomentum_eta.JetPileupScaleMomentum_m.JetPileupScaleMomentum_phi.JetPileupScaleMomentum_pt.LArQuality.N90Constituents.NegativeE.Timing.eta.kinematics.m.phi.pt',
+    'HLT_xAOD__JetContainer_a4tcemsubjesISFS.ActiveArea.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.AverageLArQF.BchCorrCell.CentroidR.DetectorEta.EMFrac.EnergyPerSampling.FracSamplingMax.FracSamplingMaxIndex.HECFrac.HECQuality.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_m.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_pt.JetEtaJESScaleMomentum_eta.JetEtaJESScaleMomentum_m.JetEtaJESScaleMomentum_phi.JetEtaJESScaleMomentum_pt.JetPileupScaleMomentum_eta.JetPileupScaleMomentum_m.JetPileupScaleMomentum_phi.JetPileupScaleMomentum_pt.LArQuality.N90Constituents.NegativeE.Timing.eta.kinematics.m.phi.pt',
+    'HLT_xAOD__JetContainer_a10tclcwsubjesFS.ActiveArea.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.AverageLArQF.BchCorrCell.CentroidR.DetectorEta.EMFrac.EnergyPerSampling.FracSamplingMax.FracSamplingMaxIndex.HECFrac.HECQuality.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_m.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_pt.JetEMScaleMomentum_eta.JetEMScaleMomentum_m.JetEMScaleMomentum_phi.JetEMScaleMomentum_pt.JetEtaJESScaleMomentum_eta.JetEtaJESScaleMomentum_m.JetEtaJESScaleMomentum_phi.JetEtaJESScaleMomentum_pt.JetPileupScaleMomentum_eta.JetPileupScaleMomentum_m.JetPileupScaleMomentum_phi.JetPileupScaleMomentum_pt.LArQuality.N90Constituents.NegativeE.Timing.eta.kinematics.m.phi.pt',
     ]
 
-#JETM6SlimmingHelper.ExtraVariables = []
+for truthc in [
+  "TruthTopQuark",
+  "TruthBosons",
+  "TruthHF"
+  ]:
+  JETM6SlimmingHelper.StaticContent.append("xAOD::TruthParticleContainer#"+truthc+"WithDecayParticles")
+  JETM6SlimmingHelper.StaticContent.append("xAOD::TruthParticleAuxContainer#"+truthc+"WithDecayParticlesAux.")
+  JETM6SlimmingHelper.StaticContent.append("xAOD::TruthVertexContainer#"+truthc+"WithDecayVertices")
+  JETM6SlimmingHelper.StaticContent.append("xAOD::TruthVertexAuxContainer#"+truthc+"WithDecayVerticesAux.")
+
 for truthc in [
     "TruthMuons",
     "TruthElectrons",
     "TruthPhotons",
-    "TruthTaus",
-    "TruthNeutrinos"
+    "TruthBottom"
     ]:
     JETM6SlimmingHelper.StaticContent.append("xAOD::TruthParticleContainer#"+truthc)
     JETM6SlimmingHelper.StaticContent.append("xAOD::TruthParticleAuxContainer#"+truthc+"Aux.")
 
-## # Trigger content
-## from DerivationFrameworkCore.JetTriggerContent import JetTriggerContent
+#====================================================================
+# ORIGIN CORRECTED CLUSTERS
+#====================================================================
+
+addOriginCorrectedClusters(JETM6SlimmingHelper,writeLC=True,writeEM=True)
+
+#====================================================================
+# TRIGGER CONTENT
+#====================================================================
+ 
 JETM6SlimmingHelper.IncludeJetTriggerContent = True
 JETM6SlimmingHelper.IncludeMuonTriggerContent = True
 JETM6SlimmingHelper.IncludeEGammaTriggerContent = True
-# We actually set the precise variable content  in ExtraVariables
-
-# Add the jet containers to the stream 
-# explicitely add the container we want :
-addJetOutputs(JETM6SlimmingHelper,[
-        "AntiKt10LCTopoJets",    "AntiKt10TruthJets",
-        "JETM6", # jets defined in this file
-        ])
-# for other containers, w set the precise variable content  in ExtraVariables
-
-topoJetVars = 'ActiveArea.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.AlgorithmType.AverageLArQF.BchCorrCell.Charge.ConeExclBHadronsFinal.ConeExclCHadronsFinal.ConeExclTausFinal.ConeTruthLabelID.ConstituentScale.DetectorEta.EMFrac.EnergyPerSampling.FracSamplingMax.FracSamplingMaxIndex.HECFrac.HECQuality.HadronConeExclTruthLabelID.HighestJVFVtx.InputType.IsoDelta2SumPt.IsoDelta3SumPt.JVF.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_m.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_pt.JetOriginConstitScaleMomentum_eta.JetOriginConstitScaleMomentum_m.JetOriginConstitScaleMomentum_phi.JetOriginConstitScaleMomentum_pt.JetPileupScaleMomentum_eta.JetPileupScaleMomentum_m.JetPileupScaleMomentum_phi.JetPileupScaleMomentum_pt.Jvt.JvtJvfcorr.JvtRpt.LArBadHVEnergyFrac.LArBadHVNCell.LArQuality.LeadingClusterCenterLambda.LeadingClusterSecondLambda.LeadingClusterSecondR.Mu12.N90Constituents.NegativeE.NumTrkPt1000.NumTrkPt500.OotFracClusters10.OotFracClusters5.OriginCorrected.OriginVertex.PartonTruthLabelID.PileupCorrected.SizeParameter.SumPtTrkPt1000.SumPtTrkPt500.TrackWidthPt1000.TrackWidthPt500.Width.btaggingLink.eta.pt.phi.m.GhostMuonSegmentCount.CentroidR.Timing'
 
-JETM6SlimmingHelper.ExtraVariables += [
-    'AntiKt4LCTopoJets.'+topoJetVars ,
-    'AntiKt4EMTopoJets.'+topoJetVars , 
-    'AntiKt4TruthJets.AlgorithmType.Angularity.Aplanarity.ConeExclBHadronsFinal.ConeExclCHadronsFinal.ConeExclTausFinal.ConeTruthLabelID.ConstituentScale.HadronConeExclTruthLabelID.InputType.IsoDelta2SumPt.IsoDelta3SumPt.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_m.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_pt.Mu12.PartonTruthLabelID.SizeParameter.Width.eta.pt.phi.m',
-    "AntiKt2PV0TrackJets.AlgorithmType.ConstituentScale.Width.eta.pt.phi.m.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_m.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_pt.OriginVertex.SizeParameter",
-    'HLT_xAOD__JetContainer_a4tcemsubjesFS.ActiveArea.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.AlgorithmType.AverageLArQF.BchCorrCell.CentroidR.ConstituentScale.DetectorEta.EMFrac.EnergyPerSampling.FracSamplingMax.FracSamplingMaxIndex.HECFrac.HECQuality.InputType.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_m.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_pt.JetEMScaleMomentum_eta.JetEMScaleMomentum_m.JetEMScaleMomentum_phi.JetEMScaleMomentum_pt.JetEtaJESScaleMomentum_eta.JetEtaJESScaleMomentum_m.JetEtaJESScaleMomentum_phi.JetEtaJESScaleMomentum_pt.JetPileupScaleMomentum_eta.JetPileupScaleMomentum_m.JetPileupScaleMomentum_phi.JetPileupScaleMomentum_pt.LArQuality.N90Constituents.NegativeE.OriginCorrected.PileupCorrected.SizeParameter.Timing.eta.kinematics.m.phi.pt',
-    'HLT_xAOD__JetContainer_a10tcemsubjesFS.ActiveArea.ActiveArea4vec_eta.ActiveArea4vec_m.ActiveArea4vec_phi.ActiveArea4vec_pt.AlgorithmType.AverageLArQF.BchCorrCell.CentroidR.ConstituentScale.DetectorEta.EMFrac.EnergyPerSampling.FracSamplingMax.FracSamplingMaxIndex.HECFrac.HECQuality.InputType.JetConstitScaleMomentum_eta.JetConstitScaleMomentum_m.JetConstitScaleMomentum_phi.JetConstitScaleMomentum_pt.JetEMScaleMomentum_eta.JetEMScaleMomentum_m.JetEMScaleMomentum_phi.JetEMScaleMomentum_pt.JetEtaJESScaleMomentum_eta.JetEtaJESScaleMomentum_m.JetEtaJESScaleMomentum_phi.JetEtaJESScaleMomentum_pt.JetPileupScaleMomentum_eta.JetPileupScaleMomentum_m.JetPileupScaleMomentum_phi.JetPileupScaleMomentum_pt.LArQuality.N90Constituents.NegativeE.OriginCorrected.PileupCorrected.SizeParameter.Timing.eta.kinematics.m.phi.pt',
-    ]
-
-#JETM6SlimmingHelper.StaticContent.append("xAOD::JetContainer#CamKt15LCTopoJets")
-#JETM6SlimmingHelper.StaticContent.append("xAOD::JetAuxContainer#CamKt15LCTopoJetsAux.eta.pt.phi")
+# Add the jet containers to the stream
+addJetOutputs(JETM6SlimmingHelper,
+              ["JETM6","AntiKt10LCTopoJets","AntiKt10TruthJets","AntiKt10UFOCSSKJets","AntiKt10UFOCHSJets"],
+              ["AntiKt10LCTopoJets","AntiKt10TruthJets","AntiKt10UFOCSSKJets","AntiKt10UFOCHSJets"], #smart slimming
+              ["AntiKt10EMPFlowCSSKJets"] #veto jets
+              )
 
 # Add the MET containers to the stream
-addMETOutputs(JETM6SlimmingHelper,["Diagnostic","AntiKt4LCTopo","AntiKt4EMPFlow","Track"])
+addMETOutputs(JETM6SlimmingHelper,["Diagnostic","AntiKt4EMPFlow","Track"])
 
 JETM6SlimmingHelper.AppendContentToStream(JETM6Stream)
 #JETM6Stream.RemoveItem("xAOD::TrigNavigation#*")
@@ -306,8 +476,8 @@ def removeVars(coll, vars):
             continue
         cleanedV.append(v)
     newS = '.'.join(cleanedV)
-    JETM6Stream.RemoveItem( origS ) 
-    JETM6Stream.AddItem( newS ) 
-    
+    JETM6Stream.RemoveItem( origS )
+    JETM6Stream.AddItem( newS )
+
 #removeVars('InDetTrackParticles', ['definingParametersCovMatrix',])
-         
+
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM7.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM7.py
index 902b51bfc4efa5118a3c395ed2a45fa46943c3ae..f37bd78e6e14a02fd383566c6a7688464b0b2d22 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM7.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM7.py
@@ -14,37 +14,43 @@ from DerivationFrameworkJetEtMiss.METCommon import *
 
 #
 if DerivationFrameworkIsMonteCarlo:
-    from DerivationFrameworkMCTruth.MCTruthCommon import *
-    from DerivationFrameworkTau.TauTruthCommon import *
+  from DerivationFrameworkMCTruth.MCTruthCommon import addStandardTruthContents
+  addStandardTruthContents()
 
 #====================================================================
 # SKIMMING TOOL 
 #====================================================================
 
-from DerivationFrameworkJetEtMiss.TriggerLists import *
-electronTriggers = singleElTriggers
-muonTriggers = singleMuTriggers
+from DerivationFrameworkJetEtMiss import TriggerLists
+electronTriggers = TriggerLists.single_el_Trig()
+muonTriggers = TriggerLists.single_mu_Trig()
 
 orstr  = ' || '
 andstr = ' && '
 eltrigsel = '(EventInfo.eventTypeBitmask==1) || '+orstr.join(electronTriggers)
 elofflinesel = andstr.join(['count((Electrons.pt > 25*GeV) && (Electrons.DFCommonElectronsLHMedium)) >= 1',
-                            'count(AntiKt4EMTopoJets.DFCommonJets_Calib_pt>20*GeV && AntiKt4EMTopoJets.DFCommonJets_FixedCutBEff_77) >= 1'
+                            'count(AntiKt4EMTopoJets.DFCommonJets_Calib_pt>20*GeV &&  AntiKt4EMTopoJets_BTagging201810.DFCommonJets_FixedCutBEff_77_MV2c10) >= 1'
                             ])
 electronSelection = '( (' + eltrigsel + ') && (' + elofflinesel + ') )'
 
 mutrigsel = '(EventInfo.eventTypeBitmask==1) || '+orstr.join(muonTriggers)
 muofflinesel = andstr.join(['count((Muons.pt > 25*GeV) && (Muons.DFCommonMuonsPreselection)) >= 1',
-                            'count(AntiKt4EMTopoJets.DFCommonJets_Calib_pt>20*GeV && AntiKt4EMTopoJets.DFCommonJets_FixedCutBEff_77) >= 1'
+                            'count(AntiKt4EMTopoJets.DFCommonJets_Calib_pt>20*GeV &&  AntiKt4EMTopoJets_BTagging201810.DFCommonJets_FixedCutBEff_77_MV2c10) >= 1'
                             ])
 muonSelection = ' ( (' + mutrigsel + ') && (' + muofflinesel + ') )'
 expression = '( ' + electronSelection + ' || ' + muonSelection + ' )'
-
+for i in expression:
+	print "ISHAN " + i
 from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__xAODStringSkimmingTool
 JETM7SkimmingTool = DerivationFramework__xAODStringSkimmingTool( name = "JETM7SkimmingTool1",
                                                                  expression = expression)
 ToolSvc += JETM7SkimmingTool
 
+#Trigger matching decorations
+from DerivationFrameworkCore.TriggerMatchingAugmentation import applyTriggerMatching
+TrigMatchAug, NewTrigVars = applyTriggerMatching(ToolNamePrefix="JETM7",
+                                                 ElectronTriggers=electronTriggers,MuonTriggers=muonTriggers)
+
 #====================================================================
 # SET UP STREAM   
 #====================================================================
@@ -61,7 +67,9 @@ applyJetCalibration_xAODColl("AntiKt4EMTopo") # adds this to DerivationFramework
 updateJVT_xAODColl("AntiKt4EMTopo") # adds this to DerivationFrameworkJob by default
 
 from DerivationFrameworkFlavourTag.FlavourTagCommon import applyBTagging_xAODColl
-applyBTagging_xAODColl("AntiKt4EMTopo")
+applyJetCalibration_xAODColl("AntiKt4EMTopo_BTagging201810")
+updateJVT_xAODColl('AntiKt4EMTopo_BTagging201810')
+applyBTagging_xAODColl('AntiKt4EMTopo_BTagging201810')
 
 #=======================================
 # ESTABLISH THE THINNING HELPER
@@ -106,7 +114,7 @@ thinningTools.append(JETM7PhotonTPThinningTool)
 # TrackParticles associated with taus
 from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TauTrackParticleThinning
 JETM7TauTPThinningTool = DerivationFramework__TauTrackParticleThinning( name            = "JETM7TauTPThinningTool",
-                                                                        StreamName              = streamName,
+                                                                        StreamName      = streamName,
                                                                         TauKey          = "TauJets",
                                                                         InDetTrackParticlesKey  = "InDetTrackParticles")
 ToolSvc += JETM7TauTPThinningTool
@@ -166,16 +174,19 @@ reducedJetList = ["AntiKt2PV0TrackJets",
                   "AntiKt4TruthWZJets"]
 replaceAODReducedJets(reducedJetList,jetm7Seq,"JETM7")
 
+#=======================================
+# BTAGGING INFO FOR PFLOW JET
+#=======================================
+from DerivationFrameworkFlavourTag.FlavourTagCommon import FlavorTagInit
+FlavorTagInit(JetCollections = ['AntiKt4EMPFlowJets'],Sequencer = jetm7Seq)
+
 #==============================================================================
-# SUSY background generator filters
+# background generator filters
 #==============================================================================
-augmentationTools = []
+augmentationTools = [TrigMatchAug]
 if globalflags.DataSource() == 'geant4':
-  ToolSvc += CfgMgr.DerivationFramework__SUSYGenFilterTool(
-    "JETM7GenFilt",
-    SimBarcodeOffset = DerivationFrameworkSimBarcodeOffset
-  )
-  augmentationTools.append(ToolSvc.JETM7GenFilt)
+    from DerivationFrameworkMCTruth.GenFilterToolSetup import *
+    augmentationTools.append(ToolSvc.DFCommonTruthGenFilt)
 
 from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
 jetm7Seq += CfgMgr.DerivationFramework__DerivationKernel( name = "JETM7Kernel",
@@ -204,14 +215,20 @@ JETM7SlimmingHelper.SmartCollections = ["Electrons", "Photons", "Muons", "TauJet
                                         "MET_Reference_AntiKt4LCTopo",
                                         "MET_Reference_AntiKt4EMPFlow",
                                         "AntiKt4EMTopoJets","AntiKt4LCTopoJets","AntiKt4EMPFlowJets",
-                                        "BTagging_AntiKt4EMTopo",]
+                                        "AntiKt4EMPFlowJets_BTagging201810",
+                                        "AntiKt4EMPFlowJets_BTagging201903",
+                                        "AntiKt4EMTopoJets_BTagging201810",
+                                        "BTagging_AntiKt4EMPFlow_201810",
+                                        "BTagging_AntiKt4EMPFlow_201903",
+                                        "BTagging_AntiKt4EMTopo_201810"]
 JETM7SlimmingHelper.AllVariables = [# "CaloCalTopoClusters",
                                     "MuonTruthParticles", "egammaTruthParticles",
                                     "TruthParticles", "TruthEvents", "TruthVertices",
                                     "MuonSegments",
                                     "Kt4EMTopoOriginEventShape","Kt4LCTopoOriginEventShape","Kt4EMPFlowEventShape",
                                     ]
-JETM7SlimmingHelper.ExtraVariables = ["Muons.energyLossType.EnergyLoss.ParamEnergyLoss.MeasEnergyLoss.EnergyLossSigma.MeasEnergyLossSigma.ParamEnergyLossSigmaPlus.ParamEnergyLossSigmaMinus"]
+JETM7SlimmingHelper.ExtraVariables = ["Electrons."+NewTrigVars["Electrons"],
+                                      "Muons.energyLossType.EnergyLoss.ParamEnergyLoss.MeasEnergyLoss.EnergyLossSigma.MeasEnergyLossSigma.ParamEnergyLossSigmaPlus.ParamEnergyLossSigmaMinus."+NewTrigVars["Muons"]]
 for truthc in [
     "TruthMuons",
     "TruthElectrons",
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM8.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM8.py
index 011ad466d7565fd85a5bd8d22304715735585588..db856c075f4858737a44bd758ba179060b8116ad 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM8.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM8.py
@@ -6,96 +6,111 @@
 from DerivationFrameworkCore.DerivationFrameworkMaster import *
 from DerivationFrameworkJetEtMiss.JetCommon import *
 from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
-from DerivationFrameworkJetEtMiss.METCommon import *
-from DerivationFrameworkEGamma.EGammaCommon import *
-from DerivationFrameworkMuons.MuonsCommon import *
-
-#
-if DerivationFrameworkIsMonteCarlo:
-    from DerivationFrameworkMCTruth.MCTruthCommon import *
-    from DerivationFrameworkTau.TauTruthCommon import *
+from DerivationFrameworkFlavourTag.HbbCommon import *
+from DerivationFrameworkFlavourTag.FlavourTagCommon import *
 
 #====================================================================
 # SKIMMING TOOL 
 #====================================================================
-# this recopying the latest JETM6
 
-from DerivationFrameworkJetEtMiss.TriggerLists import *
-electronTriggers = singleElTriggers
-muonTriggers = singleMuTriggers
+from DerivationFrameworkJetEtMiss import TriggerLists
+jetTriggers = TriggerLists.jetTrig()
 
 # For first data
-jetSelection = '(count( AntiKt10LCTopoJets.pt > 100.*GeV ) >=1)'
-#jetSelection = '(count( CamKt12LCTopoJets.pt > 150.*GeV ) >=1)'
-
-orstr  = ' || '
-andstr = ' && '
-eltrigsel = '(EventInfo.eventTypeBitmask==1) || '+orstr.join(electronTriggers)
-elofflinesel = andstr.join(['count((Electrons.pt > 20*GeV) && (Electrons.DFCommonElectronsLHMedium)) == 1',
-                            'count(AntiKt10LCTopoJets.pt > 75*GeV) >=1'])
-electronSelection = '( (' + eltrigsel + ') && (' + elofflinesel + ') )'
-
-mutrigsel = '(EventInfo.eventTypeBitmask==1) || '+orstr.join(muonTriggers)
-muofflinesel = andstr.join(['count((Muons.pt > 20*GeV) && (Muons.DFCommonMuonsPreselection)) == 1',
-                            'count(AntiKt10LCTopoJets.pt > 75*GeV) >=1'])
-muonSelection = ' ( (' + mutrigsel + ') && (' + muofflinesel + ') ) '
-# MET filter wanted? : MET_Reference_AntiKt4LCTopo > 20*GeV # should use a different container
-
-lepSelection = '( ' + electronSelection + ' || ' + muonSelection + ' )'
-
-
-expression = jetSelection + ' || '+ lepSelection
-
+jetSelection = '(count( AntiKt10LCTopoJets.pt > 150.*GeV && abs(AntiKt10LCTopoJets.eta) < 2.5 ) >=1)'
+jetSelection += '||(count( AntiKt10TrackCaloClusterJets.pt > 150.*GeV && abs(AntiKt10TrackCaloClusterJets.eta) < 2.5 ) >=1)'
+jetSelection += '||(count( AntiKt10UFOCSSKJets.pt > 150.*GeV && abs(AntiKt10UFOCSSKJets.eta) < 2.5 ) >=1)'
 
 from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__TriggerSkimmingTool
 JETM8TrigSkimmingTool = DerivationFramework__TriggerSkimmingTool(   name           = "JETM8TrigSkimmingTool",
-                                                                    TriggerListOR  = jetTriggers+electronTriggers+muonTriggers )
-                                                                    #TriggerListOR  = triggers )
+                                                                    TriggerListOR  = jetTriggers )
 ToolSvc += JETM8TrigSkimmingTool
 
 from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__xAODStringSkimmingTool
 JETM8OfflineSkimmingTool = DerivationFramework__xAODStringSkimmingTool( name = "JETM8OfflineSkimmingTool",
-                                                                        expression = expression)
+                                                                        expression = jetSelection)
 ToolSvc += JETM8OfflineSkimmingTool
 
 #====================================================================
 # THINNING TOOLS 
 #====================================================================
+
 thinningTools = []
 
-# Truth particle thinning
-doTruthThinning = True
-preserveAllDescendants = False
-from AthenaCommon.GlobalFlags import globalflags
-if doTruthThinning and DerivationFrameworkIsMonteCarlo:
-    truth_cond_WZH    = "((abs(TruthParticles.pdgId) >= 23) && (abs(TruthParticles.pdgId) <= 25))"            # W, Z and Higgs
-    truth_cond_Lepton = "((abs(TruthParticles.pdgId) >= 11) && (abs(TruthParticles.pdgId) <= 16) && (TruthParticles.barcode < 200000))"            # Leptons
-    truth_cond_Quark  = "((abs(TruthParticles.pdgId) <=  5  && (TruthParticles.pt > 10000.)) || (abs(TruthParticles.pdgId) == 6))"                 # Quarks
-    truth_cond_Gluon  = "((abs(TruthParticles.pdgId) == 21) && (TruthParticles.pt > 10000.))"                                                # Gluons
-    truth_cond_Photon = "((abs(TruthParticles.pdgId) == 22) && (TruthParticles.pt > 10000.) && (TruthParticles.barcode < 200000))"                 # Photon
-    
-    truth_expression = '('+truth_cond_WZH+' || '+truth_cond_Lepton +' || '+truth_cond_Quark+' || '+truth_cond_Gluon+' || '+truth_cond_Photon+')'
-    
-    from DerivationFrameworkMCTruth.DerivationFrameworkMCTruthConf import DerivationFramework__GenericTruthThinning
-    JETM8TruthThinningTool = DerivationFramework__GenericTruthThinning( name = "JETM8TruthThinningTool",
-                                                                        StreamName              = streamName,
-                                                                        ParticleSelectionString = truth_expression,
-                                                                        PreserveDescendants     = preserveAllDescendants,
-                                                                        PreserveGeneratorDescendants = not preserveAllDescendants,
-                                                                        PreserveAncestors = True)
-    
-    ToolSvc += JETM8TruthThinningTool
-    thinningTools.append(JETM8TruthThinningTool)    
-
-
-    from DerivationFrameworkJetEtMiss.DerivationFrameworkJetEtMissConf import DerivationFramework__ViewContainerThinning
-    JETM8TruthJetInputThin = DerivationFramework__ViewContainerThinning( name = "JETM8ViewContThinning",
-                                                                         StreamName              = streamName,
-                                                                         TruthParticleKey = "TruthParticles",
-                                                                         TruthParticleViewKey = "JetInputTruthParticles")
-
-    ToolSvc += JETM8TruthJetInputThin
-    thinningTools.append(JETM8TruthJetInputThin)    
+#====================================================================
+# Thin TruthParticles for truth jet constituents
+#====================================================================
+
+if DerivationFrameworkIsMonteCarlo:
+  from DerivationFrameworkJetEtMiss.DerivationFrameworkJetEtMissConf import DerivationFramework__ViewContainerThinning
+  JETM8TruthJetInputThin = DerivationFramework__ViewContainerThinning( name = "JETM8ViewContThinning",
+                                                                       StreamName = streamName,
+                                                                       TruthParticleKey = "TruthParticles",
+                                                                       TruthParticleViewKey = "JetInputTruthParticles")
+
+  ToolSvc += JETM8TruthJetInputThin
+  thinningTools.append(JETM8TruthJetInputThin)
+
+#====================================================================
+# Thin jet inputs for jet constituents
+#====================================================================
+
+# Calo clusters
+from DerivationFrameworkCalo.DerivationFrameworkCaloConf import DerivationFramework__JetCaloClusterThinning
+JETM8AKt10CCThinningTool = DerivationFramework__JetCaloClusterThinning(name                  = "JETM8AKt10CCThinningTool",
+                                                                       StreamName            = streamName,
+                                                                       SGKey                 = "AntiKt10LCTopoJets",
+                                                                       SelectionString       = "(AntiKt10LCTopoJets.pt > 150*GeV && abs(AntiKt10LCTopoJets.eta) < 2.8)",
+                                                                       TopoClCollectionSGKey = "CaloCalTopoClusters",
+                                                                       AdditionalClustersKey = ["LCOriginTopoClusters"],
+                                                                       ApplyAnd              = False)
+ToolSvc += JETM8AKt10CCThinningTool
+thinningTools.append(JETM8AKt10CCThinningTool)
+
+# Tracks and CaloClusters associated with TCCs
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TCCTrackParticleThinning
+JETM8TCCTPThinningTool = DerivationFramework__TCCTrackParticleThinning(name                         = "JETM8TCCTPThinningTool",
+                                                                       StreamName                   = streamName,
+                                                                       JetKey                       = "AntiKt10TrackCaloClusterJets",
+                                                                       SelectionString              = "(AntiKt10TrackCaloClusterJets.pt > 150*GeV && abs(AntiKt10TrackCaloClusterJets.eta) < 2.8)",
+                                                                       TCCKey                       = "TrackCaloClustersCombinedAndNeutral",
+                                                                       InDetTrackParticlesKey       = "InDetTrackParticles",
+                                                                       CaloCalTopoClustersKey       = "CaloCalTopoClusters",
+                                                                       ThinOriginCorrectedClusters  = True,
+                                                                       OriginCaloCalTopoClustersKey = "LCOriginTopoClusters")
+
+ToolSvc += JETM8TCCTPThinningTool
+thinningTools.append(JETM8TCCTPThinningTool)
+
+# Tracks and CaloClusters associated with UFOs
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__UFOTrackParticleThinning
+JETM8EMCSSKUFOTPThinningTool = DerivationFramework__UFOTrackParticleThinning(name                   = "JETM8CSSKUFOTPThinningTool",
+                                                                             StreamName             = streamName,
+                                                                             JetKey                 = "AntiKt10UFOCSSKJets",
+                                                                             UFOKey                 = "CSSKUFO",
+                                                                             InDetTrackParticlesKey = "InDetTrackParticles",
+                                                                             PFOCollectionSGKey     = "JetETMiss",
+                                                                             AdditionalPFOKey       = ["CSSK"])
+
+ToolSvc += JETM8EMCSSKUFOTPThinningTool
+thinningTools.append(JETM8EMCSSKUFOTPThinningTool)
+
+#====================================================================
+# Thin tracks
+#====================================================================
+
+JETM8BaselineTrack = "(InDetTrackParticles.pt > 0.0)"
+
+# This is necessary to keep tracks that would otherwise be removed by TCC and UFO thinning
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TrackParticleThinning
+JETM8TrackParticleThinningTool = DerivationFramework__TrackParticleThinning(name            = "JETM8TrackParticleThinningTool",
+                                                                            StreamName      = streamName,
+                                                                            SelectionString = JETM8BaselineTrack,
+                                                                            InDetTrackParticlesKey = "InDetTrackParticles",
+                                                                            ApplyAnd        = False)
+
+ToolSvc += JETM8TrackParticleThinningTool
+thinningTools.append(JETM8TrackParticleThinningTool)
 
 #=======================================
 # CREATE PRIVATE SEQUENCE
@@ -103,7 +118,6 @@ if doTruthThinning and DerivationFrameworkIsMonteCarlo:
 
 jetm8Seq = CfgMgr.AthSequencer("JETM8Sequence")
 DerivationFrameworkJob += jetm8Seq
-#jetm8Seq = DerivationFrameworkJob
 
 #=======================================
 # CREATE THE DERIVATION KERNEL ALGORITHM   
@@ -114,112 +128,119 @@ jetm8Seq += CfgMgr.DerivationFramework__DerivationKernel(	name = "JETM8TrigKerne
 									SkimmingTools = [JETM8TrigSkimmingTool],
 									ThinningTools = [])
 
+#=======================================
+# BUILD TCC INPUTS
+#=======================================
+
+# Add TCC constituents
+from TrackCaloClusterRecTools.TrackCaloClusterConfig import runTCCReconstruction
+import AthenaCommon.AtlasUnixStandardJob
+include("RecExCond/AllDet_detDescr.py")
+runTCCReconstruction(jetm8Seq, ToolSvc, "LCOriginTopoClusters", "InDetTrackParticles", outputTCCName="TrackCaloClustersCombinedAndNeutral")
+
+#=======================================
+# BUILD UFO INPUTS
+#=======================================
+
+## Add PFlow constituents
+from JetRecTools.ConstModHelpers import getConstModSeq, xAOD
+pflowCSSKSeq = getConstModSeq(["CS","SK"], "EMPFlow")
+
+# add the pflow cssk sequence to the main jetalg if not already there :
+if pflowCSSKSeq.getFullName() not in [t.getFullName() for t in DerivationFrameworkJob.jetalg.Tools]:
+  DerivationFrameworkJob.jetalg.Tools += [pflowCSSKSeq]
+
+# Add UFO constituents
+from TrackCaloClusterRecTools.TrackCaloClusterConfig import runUFOReconstruction
+emcsskufoAlg = runUFOReconstruction(jetm8Seq, ToolSvc, PFOPrefix="CSSK",caloClusterName="LCOriginTopoClusters")
+
 #=======================================
 # RESTORE AOD-REDUCED JET COLLECTIONS
 #=======================================
 reducedJetList = ["AntiKt2PV0TrackJets",
                   "AntiKt4PV0TrackJets",
+                  "AntiKt2LCTopoJets",
+                  "AntiKt2TruthJets",
                   "AntiKt4TruthJets",
+                  "AntiKt4TruthWZJets",
                   "AntiKt10TruthJets",
-                  "AntiKt10LCTopoJets"]
+                  "AntiKt10LCTopoJets",
+                  "AntiKt10TrackCaloClusterJets",
+                  "AntiKt10UFOCSSKJets"]
 replaceAODReducedJets(reducedJetList,jetm8Seq,"JETM8")
 
-jetm8Seq += CfgMgr.DerivationFramework__DerivationKernel( name = "JETM8MainKernel", 
+jetm8Seq += CfgMgr.DerivationFramework__DerivationKernel( name = "JETM8MainKernel",
                                                           SkimmingTools = [JETM8OfflineSkimmingTool],
                                                           ThinningTools = thinningTools)
 
 #====================================================================
-# Special jets
+# Jets for tagging
 #====================================================================
 
 OutputJets["JETM8"] = []
 
-from JetRecTools.JetRecToolsConfig import ctm
-from JetRecTools.JetRecToolsConf import CaloClusterConstituentsOrigin, ConstituentSubtractorTool, VoronoiWeightTool
-
-ctm.add( VoronoiWeightTool("JetConstit_Voronoi",
-         doSpread=True, nSigma=0),
-         alias = 'voronoi' )
-
-ctm.add( VoronoiWeightTool("JetConstit_VoronoiSupp",
-         doSpread=False, nSigma=0),
-         alias = 'voronoiSupp' )
-
-ctm.add( ConstituentSubtractorTool("JetConstit_ConstSub"),
-         alias = 'constsub' )
-
-clustOrigSeq = ctm.buildConstitModifSequence( 'ConstitOrigSeq',
-                                              OutputContainer = 'OrigTopoClusters',
-                                              InputContainer= 'CaloCalTopoClusters',
-                                              modList = [  'lc_origin'] )
-
-clustSKSeq = ctm.buildConstitModifSequence( 'ConstitOrigSKSeq',
-                                            OutputContainer = 'OrigSKTopoClusters',
-                                            InputContainer= 'OrigTopoClusters',
-                                            modList = [  'softkiller'] , InputType="CaloCluster")
-
-clustVorSeq = ctm.buildConstitModifSequence( 'ConstitOrigVorSeq',
-                                            OutputContainer = 'OrigVorTopoClusters',
-                                            InputContainer= 'OrigTopoClusters',
-                                            modList = [  'voronoi'] , InputType="CaloCluster")
-
-clustVorSuppSeq = ctm.buildConstitModifSequence( 'ConstitOrigVorSuppSeq',
-                                                 OutputContainer = 'OrigVorSuppTopoClusters',
-                                                 InputContainer= 'OrigTopoClusters',
-                                                 modList = [  'voronoiSupp'] , InputType="CaloCluster")
-
-clustVorSKSeq = ctm.buildConstitModifSequence( 'ConstitOrigVorSKSeq',
-                                            OutputContainer = 'OrigVorSuppSKTopoClusters',
-                                            InputContainer= 'OrigVorSuppTopoClusters',
-                                            modList = [  'softkiller'] , InputType="CaloCluster")
-
-clustCSSeq = ctm.buildConstitModifSequence( 'ConstitOrigCSSeq',
-                                            OutputContainer = 'OrigCSTopoClusters',
-                                            InputContainer= 'OrigTopoClusters',
-                                            modList = [  'constsub'] , InputType="CaloCluster")
-
-clustCSSKSeq = ctm.buildConstitModifSequence( 'ConstitOrigCSSKSeq',
-                                            OutputContainer = 'OrigCSSKTopoClusters',
-                                            InputContainer= 'OrigCSTopoClusters',
-                                            modList = [  'softkiller'] , InputType="CaloCluster")
+# AntiKt10*PtFrac5Rclus20
+addDefaultTrimmedJets(jetm8Seq,"JETM8")
 
-correctedClusters = [ "OrigTopoClusters", "OrigSKTopoClusters", "OrigCSTopoClusters", "OrigCSSKTopoClusters", "OrigVorSuppSKTopoClusters", "OrigVorTopoClusters", "OrigVorSuppTopoClusters" ]
+addTCCTrimmedJets(jetm8Seq,"JETM8")
 
-from JetRec.JetRecConf import JetAlgorithm
-clustSeqAlg = JetAlgorithm("ClusterModifiers", Tools = [clustOrigSeq, clustSKSeq, clustCSSeq, clustCSSKSeq, clustVorSeq, clustVorSuppSeq, clustVorSKSeq])
-jetm8Seq += clustSeqAlg
+if DerivationFrameworkIsMonteCarlo:
+  addSoftDropJets('AntiKt', 1.0, 'Truth', beta=1.0, zcut=0.1, mods="truth_groomed", algseq=jetm8Seq, outputGroup="JETM8", writeUngroomed=False)
+  addRecursiveSoftDropJets('AntiKt', 1.0, 'Truth', beta=1.0, zcut=0.05, N=-1,  mods="truth_groomed", algseq=jetm8Seq, outputGroup="JETM8", writeUngroomed=False)
+  addBottomUpSoftDropJets('AntiKt', 1.0, 'Truth', beta=1.0, zcut=0.05, mods="truth_groomed", algseq=jetm8Seq, outputGroup="JETM8", writeUngroomed=False)
+
+addTrimmedJets("AntiKt", 1.0, "UFOCSSK", rclus=0.2, ptfrac=0.05, algseq=jetm8Seq, outputGroup="JETM8", writeUngroomed=False, mods="tcc_groomed")
+addSoftDropJets("AntiKt", 1.0, "UFOCSSK", beta=1.0, zcut=0.1, algseq=jetm8Seq, outputGroup="JETM8", writeUngroomed=False, mods="tcc_groomed")
+addRecursiveSoftDropJets('AntiKt', 1.0, 'UFOCSSK', beta=1.0, zcut=0.05, N=-1,  mods="tcc_groomed", algseq=jetm8Seq, outputGroup="JETM8", writeUngroomed=False)
+addBottomUpSoftDropJets('AntiKt', 1.0, 'UFOCSSK', beta=1.0, zcut=0.05, mods="tcc_groomed", algseq=jetm8Seq, outputGroup="JETM8", writeUngroomed=False)
+
+largeRJetAlgs = [
+    "AntiKt10LCTopoTrimmedPtFrac5SmallR20",
+    "AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20",
+    "AntiKt10UFOCSSKTrimmedPtFrac5SmallR20",
+    "AntiKt10UFOCSSKSoftDropBeta100Zcut10",
+    "AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5",
+    "AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5Ninf",
+    ]
+
+largeRJetCollections = []
+for alg in largeRJetAlgs:
+  largeRJetCollections.append(alg+"Jets")
 
-if jetFlags.useTruth:
-    addStandardJets("CamKt", 1.5, "Truth", ptmin=40000, algseq=jetm8Seq, outputGroup="JETM8")
+if DerivationFrameworkIsMonteCarlo:
+  for alg in largeRJetAlgs:
+    addJetTruthLabel(jetalg=alg,sequence=jetm8Seq,algname="JetTruthLabelingAlg",labelname="R10TruthLabel_R21Consolidated")
 
-# CamKt15LCTopo
-addStandardJets("CamKt", 1.5, "LCTopo", mods="lctopo_ungroomed", calibOpt="none", ghostArea=0.01, ptmin=2000, ptminFilter=50000,
-                algseq=jetm8Seq, outputGroup="JETM8")
+# Add VR track jets for b-tagging
+addVRJets(jetm8Seq, largeRJetCollections)
+addVRJets(jetm8Seq, largeRJetCollections, do_ghost=True)
+addVRJets(jetm8Seq, largeRJetCollections, training='201903')
 
-# AntiKt10Track
-addTrimmedJets("AntiKt", 1.0, "PV0Track", rclus=0.2, ptfrac=0.05, algseq=jetm8Seq, outputGroup="JETM8")
+#====================================================================
+# Set up b-tagging
+#====================================================================
 
-# PFlow fat jets
-#addTrimmedJets("AntiKt", 1.0, "EMCPFlow", rclus=0.2, ptfrac=0.05, algseq=jetm8Seq, outputGroup="JETM8")
-addTrimmedJets("AntiKt", 1.0, "EMPFlow", rclus=0.2, ptfrac=0.05, algseq=jetm8Seq, outputGroup="JETM8")
+# use alias for VR jets
+from BTagging.BTaggingFlags import BTaggingFlags
+BTaggingFlags.CalibrationChannelAliases += ["AntiKtVR30Rmax4Rmin02Track->AntiKtVR30Rmax4Rmin02Track,AntiKt4EMTopo"]
 
-# AntiKt10*PtFrac5Rclus20
-addDefaultTrimmedJets(jetm8Seq,"JETM8")
+#tag pFlow jets
+FlavorTagInit(scheduleFlipped = False, JetCollections  = ['AntiKt4EMPFlowJets'], Sequencer = jetm8Seq)
 
-#AntiKt4PV0TrackJets
-addAntiKt2PV0TrackJets(jetm8Seq, "JETM8")
-addAntiKt4PV0TrackJets(jetm8Seq, "JETM8")
+#====================================================================
+# Add truth information
+#====================================================================
 
 if DerivationFrameworkIsMonteCarlo:
-     addAntiKt4TruthJets(jetm8Seq, "JETM8")
-     addAntiKt10TruthJets(jetm8Seq, "JETM8")
-
-#=======================================
-# SCHEDULE REPLACEMENT B-TAG COLLECTIONS
-#=======================================
+  from DerivationFrameworkMCTruth.MCTruthCommon import addStandardTruthContents
+  from DerivationFrameworkMCTruth.MCTruthCommon import addTopQuarkAndDownstreamParticles
+  from DerivationFrameworkMCTruth.MCTruthCommon import addHFAndDownstreamParticles
+  from DerivationFrameworkMCTruth.MCTruthCommon import addTruthCollectionNavigationDecorations
+  addStandardTruthContents()
+  addTopQuarkAndDownstreamParticles()
+  addHFAndDownstreamParticles(addB=True, addC=False, generations=0)
+  addTruthCollectionNavigationDecorations(TruthCollections=["TruthTopQuarkWithDecayParticles","TruthBosonsWithDecayParticles"],prefix='Top')
 
-from DerivationFrameworkFlavourTag.FlavourTagCommon import FlavorTagInit
-FlavorTagInit(JetCollections  = ['AntiKt2PV0TrackJets'], Sequencer = jetm8Seq)
 
 #====================================================================
 # SET UP STREAM   
@@ -236,53 +257,111 @@ evtStream = augStream.GetEventStream()
 #====================================================================
 from DerivationFrameworkCore.SlimmingHelper import SlimmingHelper
 JETM8SlimmingHelper = SlimmingHelper("JETM8SlimmingHelper")
-JETM8SlimmingHelper.SmartCollections = ["Electrons", "Photons", "Muons", "TauJets",
+JETM8SlimmingHelper.SmartCollections = ["Electrons", "Photons", "Muons",
                                         "InDetTrackParticles", "PrimaryVertices",
-                                        "MET_Reference_AntiKt4EMTopo",
-                                        "MET_Reference_AntiKt4LCTopo",
-                                        "MET_Reference_AntiKt4EMPFlow",
-                                        "AntiKt4EMTopoJets","AntiKt4LCTopoJets","AntiKt4EMPFlowJets",
+                                        "AntiKt2TruthJets",
+                                        "AntiKt2LCTopoJets",
+                                        "AntiKt4TruthJets",
+                                        "AntiKt4TruthWZJets",
+                                        "AntiKt4EMPFlowJets",
+                                        "AntiKt4EMPFlowJets_BTagging201810",
+                                        "AntiKt4EMPFlowJets_BTagging201903",
+                                        "AntiKt10TruthJets",
+                                        "AntiKt10TruthWZJets",
+                                        "AntiKt10TruthTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10TruthSoftDropBeta100Zcut10Jets",
+                                        "AntiKt10TruthBottomUpSoftDropBeta100Zcut5Jets",
+                                        "AntiKt10TruthRecursiveSoftDropBeta100Zcut5NinfJets",
+                                        "AntiKt10LCTopoJets",
                                         "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets",
-                                        "BTagging_AntiKt4EMTopo", "BTagging_AntiKt2Track",
-                                        ] #+ correctedClusters
-JETM8SlimmingHelper.AllVariables = ["CaloCalTopoClusters", 
-                                    "MuonTruthParticles", "egammaTruthParticles",
-                                    "TruthParticles", "TruthEvents", "TruthVertices",
-                                    "JetETMissChargedParticleFlowObjects", "JetETMissNeutralParticleFlowObjects",
-                                    "Kt4EMTopoOriginEventShape","Kt4LCTopoOriginEventShape","Kt4EMPFlowEventShape"]
-JETM8SlimmingHelper.ExtraVariables = []
+                                        "AntiKt10TrackCaloClusterJets",
+                                        "AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10UFOCSSKJets",
+                                        "AntiKt10UFOCSSKTrimmedPtFrac5SmallR20Jets",
+                                        "AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets",
+                                        "AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5Jets",
+                                        "AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJets",
+                                        "AntiKtVR30Rmax4Rmin02TrackJets_BTagging201810",
+                                        "AntiKtVR30Rmax4Rmin02TrackJets_BTagging201903",
+                                        "BTagging_AntiKt4EMPFlow_201810",
+                                        "BTagging_AntiKt4EMPFlow_201903",
+                                        "BTagging_AntiKtVR30Rmax4Rmin02Track_201810",
+                                        "BTagging_AntiKtVR30Rmax4Rmin02Track_201903",
+                                        ]
+JETM8SlimmingHelper.AllVariables = ["CaloCalTopoClusters",
+                                    "TrackCaloClustersCombinedAndNeutral",
+                                    "CSSKUFO",
+                                    "TruthParticles",
+                                    "Kt4EMPFlowEventShape"]
+
+JETM8SlimmingHelper.AppendToDictionary["CSSKUFO"] = "xAOD::TrackCaloClusterContainer"
+JETM8SlimmingHelper.AppendToDictionary["CSSKUFOAux"] = "xAOD::TrackCaloClusterAuxContainer"
+
+JETM8SlimmingHelper.ExtraVariables += ["CSSKUFO.pt.eta.phi.taste"]
+JETM8SlimmingHelper.ExtraVariables += ['AntiKt10LCTopoJets.SizeParameter',
+                                       'AntiKt10TruthJets.SizeParameter',
+                                       'AntiKt10TrackCaloClusterJets.SizeParameter',
+                                       'AntiKt10UFOCSSKJets.SizeParameter',
+                                       'AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets.SizeParameter',
+                                       'AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20Jets.SizeParameter',
+                                       'AntiKt10UFOCSSKTrimmedPtFrac5SmallR20Jets.SizeParameter',
+                                       'AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets.SizeParameter',
+                                       'AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5Jets.SizeParameter',
+                                       'AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJets.SizeParameter',
+                                       'AntiKt10TruthTrimmedPtFrac5SmallR20Jets.SizeParameter',
+                                       'AntiKt10TruthSoftDropBeta100Zcut10Jets.SizeParameter',
+                                       'AntiKt10TruthBottomUpSoftDropBeta100Zcut5Jets.SizeParameter',
+                                       'AntiKt10TruthRecursiveSoftDropBeta100Zcut5NinfJets.SizeParameter',
+                                       'AntiKt10LCTopoJets.GhostTrack',
+                                       'AntiKt10TrackCaloClusterJets.GhostTrack',
+                                       'AntiKt10UFOCSSKJets.GhostTrack',
+                                       'AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets.GhostTrack',
+                                       'AntiKt10TrackCaloClusterTrimmedPtFrac5SmallR20Jets.GhostTrack',
+                                       'AntiKt10UFOCSSKTrimmedPtFrac5SmallR20Jets.GhostTrack',
+                                       'AntiKt10UFOCSSKSoftDropBeta100Zcut10Jets.GhostTrack',
+                                       'AntiKt10UFOCSSKBottomUpSoftDropBeta100Zcut5Jets.GhostTrack',
+                                       'AntiKt10UFOCSSKRecursiveSoftDropBeta100Zcut5NinfJets.GhostTrack',
+                                       ]
+
+# Add origin corrected clusters to keep LCTopo constituents
+addOriginCorrectedClusters(JETM8SlimmingHelper, writeLC=True, writeEM=False)
 
-for truthc in [
-    "TruthMuons",
-    "TruthElectrons",
-    "TruthPhotons",
-    "TruthTaus",
-#    "TruthNeutrinos"
-    ]:
-    JETM8SlimmingHelper.StaticContent.append("xAOD::TruthParticleContainer#"+truthc)
-    JETM8SlimmingHelper.StaticContent.append("xAOD::TruthParticleAuxContainer#"+truthc+"Aux.")
-
-for caloc in correctedClusters:
-    JETM8SlimmingHelper.AppendToDictionary.update({caloc:"xAOD::CaloClusterContainer",
-                                                   caloc+"Aux":"xAOD::ShallowAuxContainer"})
-    JETM8SlimmingHelper.ExtraVariables +=[
-        caloc+'.calE.calEta.calM.calPhi']
+# Add the jet containers to the stream
+addJetOutputs(
+    slimhelper = JETM8SlimmingHelper,
+    contentlist = [
+      "LargeR",
+      "AntiKt4EMPFlowJets",
+      "AntiKt4TruthJets",
+      "AntiKt4TruthWZJets",
+      "AntiKt2LCTopoJets",
+      "AntiKt2TruthJets",
+      "JETM8"
+      ],
+    smartlist = JETM8SlimmingHelper.SmartCollections
+    )
 
-printfunc (JETM8SlimmingHelper.AppendToDictionary)
+for truthc in [
+  "TruthTopQuark",
+  "TruthBosons",
+  "TruthHF",
+  ]:
+  JETM8SlimmingHelper.StaticContent.append("xAOD::TruthParticleContainer#"+truthc+"WithDecayParticles")
+  JETM8SlimmingHelper.StaticContent.append("xAOD::TruthParticleAuxContainer#"+truthc+"WithDecayParticlesAux.")
+  JETM8SlimmingHelper.StaticContent.append("xAOD::TruthVertexContainer#"+truthc+"WithDecayVertices")
+  JETM8SlimmingHelper.StaticContent.append("xAOD::TruthVertexAuxContainer#"+truthc+"WithDecayVerticesAux.")
 
-# Trigger content
-from DerivationFrameworkCore.JetTriggerContent import JetTriggerContent
-for trig in JetTriggerContent:
-    if 'HLT' in trig and not 'Aux' in trig:
-        JETM8SlimmingHelper.AllVariables.append(trig)
-JETM8SlimmingHelper.IncludeJetTriggerContent = True
+for truthc in [
+  "TruthMuons",
+  "TruthElectrons",
+  "TruthPhotons",
+  "TruthBottom",
+  "TruthBSM",
+  ]:
+  JETM8SlimmingHelper.StaticContent.append("xAOD::TruthParticleContainer#"+truthc)
+  JETM8SlimmingHelper.StaticContent.append("xAOD::TruthParticleAuxContainer#"+truthc+"Aux.")
 
-# Add the jet containers to the stream
-addJetOutputs(JETM8SlimmingHelper,["SmallR",
-                                   "LargeR",
-                                   "JETM8","AntiKt10EMPFlowJets"])
-# Add the MET containers to the stream
-addMETOutputs(JETM8SlimmingHelper,["Diagnostic","AntiKt4LCTopo","AntiKt4EMPFlow","Track"])
+printfunc (JETM8SlimmingHelper.AppendToDictionary)
 
 JETM8SlimmingHelper.AppendContentToStream(JETM8Stream)
 JETM8Stream.RemoveItem("xAOD::TrigNavigation#*")
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM9.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM9.py
index 5fe5ca553b4ff87cd0828fd8ebaae0f377e297d1..ee8b7e5dfc3f587e85dad100e26099d232aff493 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM9.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/JETM9.py
@@ -11,18 +11,29 @@ from DerivationFrameworkJetEtMiss.ExtendedJetCommon import *
 #====================================================================
 # SKIMMING TOOL 
 #====================================================================
-from DerivationFrameworkJetEtMiss.TriggerLists import *
-triggers = jetTriggers
+from DerivationFrameworkJetEtMiss import TriggerLists
+triggers = TriggerLists.jetTrig()
 
 # NOTE: need to be able to OR isSimulated as an OR with the trigger
-orstr =' || '
-trigger = '('+orstr.join(triggers)+')'
-expression = trigger+' || (EventInfo.eventTypeBitmask==1)'
+#orstr =' || '
+#trigger = '('+orstr.join(triggers)+')'
+expression = 'EventInfo.eventTypeBitmask==1'
+
+
+from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__TriggerSkimmingTool
+JETM9TrigSkimmingTool = DerivationFramework__TriggerSkimmingTool(   name                    = "JETM9TrigSkimmingTool1",
+                                                                TriggerListOR          = triggers )
+ToolSvc += JETM9TrigSkimmingTool
 
 from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__xAODStringSkimmingTool
-JETM9SkimmingTool = DerivationFramework__xAODStringSkimmingTool(name = "JETM9SkimmingTool1",
+JETM9OfflineSkimmingTool = DerivationFramework__xAODStringSkimmingTool(name = "JETM9OfflineSkimmingTool1",
                                                                     expression = expression)
-ToolSvc += JETM9SkimmingTool
+ToolSvc += JETM9OfflineSkimmingTool
+
+# OR of the above two selections
+from DerivationFrameworkTools.DerivationFrameworkToolsConf import DerivationFramework__FilterCombinationOR
+JETM9ORTool = DerivationFramework__FilterCombinationOR(name="JETM9ORTool", FilterList=[JETM9TrigSkimmingTool,JETM9OfflineSkimmingTool] )
+ToolSvc+=JETM9ORTool
 
 #=======================================
 # CREATE PRIVATE SEQUENCE
@@ -32,15 +43,6 @@ jetm9Seq = CfgMgr.AthSequencer("JETM9Sequence")
 DerivationFrameworkJob += jetm9Seq
 #jetm9Seq = DerivationFrameworkJob
 
-#====================================================================
-# SET UP STREAM   
-#====================================================================
-streamName = derivationFlags.WriteDAOD_JETM9Stream.StreamName
-fileName   = buildFileName( derivationFlags.WriteDAOD_JETM9Stream )
-JETM9Stream = MSMgr.NewPoolRootStream( streamName, fileName )
-JETM9Stream.AcceptAlgs(["JETM9Kernel"])
-augStream = MSMgr.GetStream( streamName )
-evtStream = augStream.GetEventStream()
 
 # Truth particle thinning
 thinningTools = []
@@ -54,21 +56,12 @@ if DerivationFrameworkIsMonteCarlo:
                                                                 WriteFirstN                = 10)
     # from DerivationFrameworkMCTruth.DerivationFrameworkMCTruthConf import DerivationFramework__GenericTruthThinning
     # JETM9TruthParticleThinning = DerivationFramework__GenericTruthThinning(name                    = "JETM9TruthThinning",
-    #                                                                        StreamName              = streamName,
+    #                                                                        StreamName                 = streamName,
     #                                                                        ParticlesKey            = "TruthParticles",  
     #                                                                        ParticleSelectionString = "")
     ToolSvc += JETM9TruthThinning
     thinningTools.append(JETM9TruthThinning)
 
-#=======================================
-# CREATE THE DERIVATION KERNEL ALGORITHM   
-#=======================================
-
-from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
-jetm9Seq += CfgMgr.DerivationFramework__DerivationKernel(	name = "JETM9Kernel", 
-                                                                SkimmingTools = [JETM9SkimmingTool],
-                                                                ThinningTools = thinningTools)
-
 #====================================================================
 # Special jets
 #====================================================================
@@ -83,39 +76,40 @@ reducedJetList = ["AntiKt2PV0TrackJets",
 replaceAODReducedJets(reducedJetList,jetm9Seq,"JETM9")
 
 OutputJets["JETM9"] = ["AntiKt4EMTopoJets","AntiKt4LCTopoJets",
-                       "AntiKt4TruthJets","AntiKt4TruthWZJets"]
+                       "AntiKt4TruthJets","AntiKt4TruthWZJets","AntiKt2PV0TrackJets"]
+
+from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__DerivationKernel
+jetm9Seq += CfgMgr.DerivationFramework__DerivationKernel(       name = "JETM9Kernel",
+                                                                SkimmingTools = [JETM9ORTool],
+                                                                ThinningTools = thinningTools)
 
 #====================================================================
-# Jets for R-scan 
+# SET UP STREAM   
 #====================================================================
-from JetRec.JetRecStandard import jtm
-from JetRec.JetRecConf import JetAlgorithm
-
-def addRscanJets(jetalg,radius,inputtype,sequence,outputlist):
-    jetname = "{0}{1}{2}Jets".format(jetalg,int(radius*10),inputtype)
-    algname = "jetalg"+jetname
-
-    if not hasattr(sequence,algname):
-        if inputtype == "Truth":
-            addStandardJets(jetalg, radius, "Truth", mods="truth_ungroomed", ptmin=5000, algseq=sequence, outputGroup=outputlist)
-        if inputtype == "TruthWZ":
-            addStandardJets(jetalg, radius, "TruthWZ", mods="truth_ungroomed", ptmin=5000, algseq=sequence, outputGroup=outputlist)
-        elif inputtype == "LCTopo":
-            addStandardJets(jetalg, radius, "LCTopo", mods="lctopo_ungroomed",
-                            ghostArea=0.01, ptmin=2000, ptminFilter=7000, calibOpt="none", algseq=sequence, outputGroup=outputlist)
+streamName = derivationFlags.WriteDAOD_JETM9Stream.StreamName
+fileName   = buildFileName( derivationFlags.WriteDAOD_JETM9Stream )
+JETM9Stream = MSMgr.NewPoolRootStream( streamName, fileName )
+JETM9Stream.AcceptAlgs(["JETM9Kernel"])
+augStream = MSMgr.GetStream( streamName )
+evtStream = augStream.GetEventStream()
 
+#====================================================================
+# Jets for R-scan 
+#====================================================================
 for radius in [0.2, 0.3, 0.5, 0.6, 0.7, 0.8]:
     if jetFlags.useTruth:
         addRscanJets("AntiKt",radius,"Truth",jetm9Seq,"JETM9")
         addRscanJets("AntiKt",radius,"TruthWZ",jetm9Seq,"JETM9")
     addRscanJets("AntiKt",radius,"LCTopo",jetm9Seq,"JETM9")
 
+
+
 #====================================================================
 # Add the containers to the output stream - slimming done here
 #====================================================================
 from DerivationFrameworkCore.SlimmingHelper import SlimmingHelper
 JETM9SlimmingHelper = SlimmingHelper("JETM9SlimmingHelper")
-JETM9SlimmingHelper.SmartCollections = ["AntiKt4EMTopoJets","AntiKt4LCTopoJets","PrimaryVertices"]
+JETM9SlimmingHelper.SmartCollections = ["AntiKt4EMTopoJets","AntiKt2LCTopoJets","AntiKt3LCTopoJets","AntiKt4LCTopoJets","AntiKt5LCTopoJets","AntiKt6LCTopoJets","AntiKt7LCTopoJets","AntiKt8LCTopoJets","PrimaryVertices"]
 JETM9SlimmingHelper.AllVariables = ["TruthEvents","MuonSegments","Kt4EMTopoOriginEventShape","Kt4LCTopoOriginEventShape","Kt4EMPFlowEventShape"]
 JETM9SlimmingHelper.ExtraVariables = ["TruthVertices.z"]
 
@@ -123,7 +117,15 @@ JETM9SlimmingHelper.ExtraVariables = ["TruthVertices.z"]
 JETM9SlimmingHelper.IncludeJetTriggerContent = True
 
 # Add the jet containers to the stream
-addJetOutputs(JETM9SlimmingHelper,["JETM9"])
+SmartListJets = [
+    "AntiKt2LCTopoJets",
+    "AntiKt3LCTopoJets",
+    "AntiKt5LCTopoJets",
+    "AntiKt6LCTopoJets",
+    "AntiKt7LCTopoJets",
+    "AntiKt8LCTopoJets"
+    ]
+addJetOutputs(JETM9SlimmingHelper,["JETM9"],SmartListJets)
 JETM9SlimmingHelper.AppendContentToStream(JETM9Stream)
 JETM9Stream.RemoveItem("xAOD::TrigNavigation#*")
 JETM9Stream.RemoveItem("xAOD::TrigNavigationAuxInfo#*")
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/LUT_data15.root b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/LUT_data15.root
deleted file mode 100755
index a2fd4fe574f84649d8e023c50fd130496f67efdf..0000000000000000000000000000000000000000
Binary files a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/LUT_data15.root and /dev/null differ
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/LUT_mc12.root b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/LUT_mc12.root
deleted file mode 100644
index 0b7e56fd2e79716162028fd474fed5a39242e6aa..0000000000000000000000000000000000000000
Binary files a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/share/LUT_mc12.root and /dev/null differ
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/BadBatmanAugmentationTool.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/BadBatmanAugmentationTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..40131aceee9d845e84a523c184854481efbb5d9d
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/BadBatmanAugmentationTool.cxx
@@ -0,0 +1,92 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// BatBatmanAugmentationTool.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+// Author: Chris Young (christopher.young@cern.ch)
+///////////////////////////////////////////////////////////////////
+// This code is designed to augment EventInfo with a flag which
+// labels events which are likely to suffer from excess noise
+// in the EMEC-IW induced by saturation between trains. This is
+// based on counting the number of clusters in this |eta| region
+// of significant pT and bad LAr Quality.
+///////////////////////////////////////////////////////////////////
+#include "BadBatmanAugmentationTool.h"
+
+#include "StoreGate/WriteDecorHandle.h"
+
+namespace DerivationFramework {
+
+  BadBatmanAugmentationTool::BadBatmanAugmentationTool(const std::string& t,
+					       const std::string& n,
+					       const IInterface* p) : 
+    AthAlgTool(t,n,p)
+  {
+    declareInterface<DerivationFramework::IAugmentationTool>(this);
+  }
+
+  StatusCode BadBatmanAugmentationTool::initialize()
+  {
+
+    ATH_MSG_INFO("Init BadBatmanAugmentationTool");
+
+    ATH_CHECK(m_eventInfo_key.initialize());
+    ATH_CHECK(m_clusterContainer_key.initialize());
+    ATH_CHECK(m_isBadBatmanKey.initialize());
+
+    
+    return StatusCode::SUCCESS;
+  }
+
+  StatusCode BadBatmanAugmentationTool::finalize()
+  {
+
+    ATH_MSG_INFO("Finalize BadBatmanAugmentationTool");
+
+    return StatusCode::SUCCESS;
+  }
+
+  StatusCode BadBatmanAugmentationTool::addBranches() const
+  {
+    //Running BadBatmanAugmentationTool
+
+    //Set the name of the variable to augment
+
+    SG::WriteDecorHandle<xAOD::EventInfo,char> dec_isBadBatman(m_isBadBatmanKey);
+
+    auto eventInfo = SG::makeHandle (m_eventInfo_key);
+    if (!eventInfo.isValid()){
+      ATH_MSG_WARNING("Invalid  xAOD::EventInfo datahandle"
+		      << m_eventInfo_key.key()); 
+      return StatusCode::FAILURE;
+    }
+    auto ei = eventInfo.cptr();
+
+    auto clusterContainer = SG::makeHandle (m_clusterContainer_key);
+    if(!clusterContainer.isValid()){
+      ATH_MSG_WARNING("Invalid  xAOD::CaloClusterContainer datahandle"
+		      << m_clusterContainer_key.key());
+      return StatusCode::FAILURE;
+    }
+    auto clusters = clusterContainer.cptr();
+
+    //We will now loop over the cluster container counting the number of clusters which pass the criteria
+    bool isBatman=false;
+    size_t nBatman=0;
+    const static SG::AuxElement::ConstAccessor<float>  acc_AVGLARQ("AVG_LAR_Q");
+    for ( auto ipart : *clusters ) {
+      if (std::fabs(ipart->rawEta())<=2.5) continue;
+      if (std::fabs(ipart->rawEta())>=3.2) continue;
+      if (ipart->rawE()/cosh(ipart->rawEta())<500.) continue;
+      if (acc_AVGLARQ(*ipart)/65535.<=0.2) continue;
+      nBatman++;
+    }
+    //If we found more than 20 clusters then mark the event as bad
+    if (nBatman>20) isBatman=true;
+    dec_isBadBatman(*ei) = isBatman;
+
+    return StatusCode::SUCCESS;
+  }
+}
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/BadBatmanAugmentationTool.h b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/BadBatmanAugmentationTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..90b122f455d9eb1cc5d288fdf080c45b3aa8ce6e
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/BadBatmanAugmentationTool.h
@@ -0,0 +1,50 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// BatBatmanAugmentationTool.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+// Author: Chris Young (christopher.young@cern.ch)
+///////////////////////////////////////////////////////////////////
+
+#ifndef DERIVATIONFRAMEWORK_BADBATMANAUGMENTATIONTOOL_H
+#define DERIVATIONFRAMEWORK_BADBATMANAUGMENTATIONTOOL_H
+
+#include <string>
+#include <vector>
+
+#include "xAODEventInfo/EventInfo.h"
+#include "xAODCaloEvent/CaloCluster.h"
+#include "xAODCaloEvent/CaloClusterContainer.h"
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "StoreGate/ReadDecorHandleKey.h"
+#include "StoreGate/WriteDecorHandleKey.h"
+
+namespace DerivationFramework {
+
+  class BadBatmanAugmentationTool : public AthAlgTool, public IAugmentationTool {
+  public: 
+    BadBatmanAugmentationTool(const std::string& t, const std::string& n, const IInterface* p);
+
+    StatusCode initialize();
+    StatusCode finalize();
+    virtual StatusCode addBranches() const;
+
+  private:
+
+    SG::ReadHandleKey<xAOD::EventInfo> m_eventInfo_key{this, "EventInfo", "EventInfo", "Input event information"};
+    SG::ReadHandleKey<xAOD::CaloClusterContainer> m_clusterContainer_key{this, "CaloCalTopoClusters", "CaloCalTopoClusters", "Input cluster container"};
+
+    SG::WriteDecorHandleKey<xAOD::EventInfo> m_isBadBatmanKey {this
+	,"IsBadBatmanKey"
+	,"EventInfo.DFCommonJets_isBadBatman"
+	,"Decoration for isBadBatman flag"};
+
+  }; 
+}
+
+#endif // DERIVATIONFRAMEWORK_PFLOWAUGMENTATIONTOOL_H
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/DistanceInTrainAugmentationTool.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/DistanceInTrainAugmentationTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c266941c61ccae8ad3d904c860702a73a689071b
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/DistanceInTrainAugmentationTool.cxx
@@ -0,0 +1,98 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// DistanceInTrainAugmentationTool.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+// Author: Chris Young (christopher.young@cern.ch)
+///////////////////////////////////////////////////////////////////
+// This code is designed to augment EventInfo with a variety
+// of variables to describe where in the bunch train structure 
+// a given event lies. Care is taken to ensure that new trains
+// are not defined at the abort gap or 4 non-colliding crossings
+// in the 8b4e scheme.
+///////////////////////////////////////////////////////////////////
+#include "DistanceInTrainAugmentationTool.h"
+
+#include "StoreGate/WriteDecorHandle.h"
+
+
+DerivationFramework::DistanceInTrainAugmentationTool::DistanceInTrainAugmentationTool(const std::string& t,
+                                                            const std::string& n,
+                                                            const IInterface* p) :
+  AthAlgTool(t, n, p),
+  m_bcTool( "Trig::LHCBunchCrossingTool/BunchCrossingTool" )
+{
+
+  declareInterface<DerivationFramework::IAugmentationTool>(this);
+
+  declareProperty( "BCTool",        m_bcTool );
+}
+
+DerivationFramework::DistanceInTrainAugmentationTool::~DistanceInTrainAugmentationTool() {
+}
+
+StatusCode DerivationFramework::DistanceInTrainAugmentationTool::initialize()
+{
+
+  ATH_CHECK(m_eventInfo_key.initialize());
+  ATH_CHECK(m_BCIDDistanceFrontKey.initialize());
+  ATH_CHECK(m_BCIDDistanceTailKey.initialize());
+  ATH_CHECK(m_BCIDGapBeforeTrainKey.initialize());
+  ATH_CHECK(m_BCIDGapAfterTrainKey.initialize());
+  ATH_CHECK(m_BCIDTypeKey.initialize());
+  ATH_CHECK(m_BCIDGapBeforeTrainMinus12Key.initialize());
+  ATH_CHECK(m_BCIDGapAfterTrainMinus12Key.initialize());
+  ATH_CHECK(m_BCIDTypeMinus12Key.initialize());
+
+  ATH_MSG_VERBOSE("initialize() ..");
+  ATH_CHECK( m_bcTool.retrieve() );
+  ATH_MSG_INFO("Retrieved tool: " << m_bcTool);
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode DerivationFramework::DistanceInTrainAugmentationTool::finalize()
+{
+  ATH_MSG_VERBOSE("finalize() ...");
+  return StatusCode::SUCCESS;
+}
+
+StatusCode DerivationFramework::DistanceInTrainAugmentationTool::addBranches() const {
+
+  auto eventInfo = SG::makeHandle (m_eventInfo_key);
+  if (!eventInfo.isValid()){
+    ATH_MSG_WARNING("Invalid  xAOD::EventInfo datahandle"
+		    << m_eventInfo_key.key());
+    return StatusCode::FAILURE;
+  }
+  auto ei = eventInfo.cptr();
+
+  SG::WriteDecorHandle<xAOD::EventInfo,int> dec_BCIDDistanceFront(m_BCIDDistanceFrontKey);
+  SG::WriteDecorHandle<xAOD::EventInfo,int> dec_BCIDDistanceTail(m_BCIDDistanceTailKey);
+  SG::WriteDecorHandle<xAOD::EventInfo,int> dec_BCIDGapBeforeTrain(m_BCIDGapBeforeTrainKey);
+  SG::WriteDecorHandle<xAOD::EventInfo,int> dec_BCIDGapAfterTrain(m_BCIDGapAfterTrainKey);
+  SG::WriteDecorHandle<xAOD::EventInfo,int> dec_BCIDType(m_BCIDTypeKey);
+  SG::WriteDecorHandle<xAOD::EventInfo,int> dec_BCIDGapBeforeTrainMinus12(m_BCIDGapBeforeTrainMinus12Key);
+  SG::WriteDecorHandle<xAOD::EventInfo,int> dec_BCIDGapAfterTrainMinus12(m_BCIDGapAfterTrainMinus12Key);
+  SG::WriteDecorHandle<xAOD::EventInfo,int> dec_BCIDTypeMinus12(m_BCIDTypeMinus12Key);
+
+  dec_BCIDDistanceFront(*ei) = m_bcTool->distanceFromFront(ei->bcid(), Trig::IBunchCrossingTool::BunchCrossings);
+  dec_BCIDDistanceTail(*ei)  = m_bcTool->distanceFromTail(ei->bcid(), Trig::IBunchCrossingTool::BunchCrossings);
+  dec_BCIDGapBeforeTrain(*ei) = m_bcTool->gapBeforeTrain(ei->bcid(), Trig::IBunchCrossingTool::BunchCrossings);
+  dec_BCIDGapAfterTrain(*ei) = m_bcTool->gapAfterTrain(ei->bcid(), Trig::IBunchCrossingTool::BunchCrossings);
+  dec_BCIDType(*ei) = m_bcTool->bcType(ei->bcid());
+  if (ei->bcid()>=12){
+    dec_BCIDTypeMinus12(*ei) = m_bcTool->bcType(ei->bcid()-12);
+    dec_BCIDGapBeforeTrainMinus12(*ei) = m_bcTool->gapBeforeTrain(ei->bcid()-12, Trig::IBunchCrossingTool::BunchCrossings);
+    dec_BCIDGapAfterTrainMinus12(*ei) = m_bcTool->gapAfterTrain(ei->bcid()-12, Trig::IBunchCrossingTool::BunchCrossings);
+  }else{
+    dec_BCIDTypeMinus12(*ei) = -1;
+    dec_BCIDGapBeforeTrainMinus12(*ei) = 0;
+    dec_BCIDGapAfterTrainMinus12(*ei) = 0;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/DistanceInTrainAugmentationTool.h b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/DistanceInTrainAugmentationTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..b48185385cb32cee6625b5889682bc60c1d6a83b
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/DistanceInTrainAugmentationTool.h
@@ -0,0 +1,57 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// DistanceInTrainAugmentationTool.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+// Author: Chris Young (christopher.young@cern.ch)
+///////////////////////////////////////////////////////////////////
+#ifndef DERIVATIONFRAMEWORK_BCDISTANCEAUGMENTATIONTOOL_H
+#define DERIVATIONFRAMEWORK_BCDISTANCEAUGMENTATIONTOOL_H
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "StoreGate/WriteDecorHandleKey.h"
+#include "StoreGate/ReadDecorHandleKey.h"
+
+#include "xAODEventInfo/EventInfo.h"
+
+#include "TrigAnalysisInterfaces/IBunchCrossingTool.h"
+
+namespace DerivationFramework {
+
+  class DistanceInTrainAugmentationTool : public AthAlgTool, public IAugmentationTool {
+
+    public: 
+      DistanceInTrainAugmentationTool( const std::string& t, const std::string& n, const IInterface* p );
+
+      ~DistanceInTrainAugmentationTool();
+
+      StatusCode  initialize();
+      StatusCode  finalize();
+
+      virtual StatusCode addBranches() const;
+
+    private:
+
+      ToolHandle<Trig::IBunchCrossingTool> m_bcTool;
+
+      SG::ReadHandleKey<xAOD::EventInfo> m_eventInfo_key{this, "EventInfo", "EventInfo", "Input event information"};
+      
+      SG::WriteDecorHandleKey<xAOD::EventInfo> m_BCIDDistanceFrontKey {this, "BCIDDistanceFrontKey", "EventInfo.DFCommonJets_BCIDDistanceFromFront", "Decoration for BCID distance from front"};
+      SG::WriteDecorHandleKey<xAOD::EventInfo> m_BCIDDistanceTailKey {this, "BCIDDistanceTailKey", "EventInfo.DFCommonJets_BCIDDistanceTail" , "Decoration for BCID distance from tail"};
+      SG::WriteDecorHandleKey<xAOD::EventInfo> m_BCIDGapBeforeTrainKey {this, "BCIDGapBeforeTrainKey", "EventInfo.DFCommonJets_BCIDGapBeforeTrain", "Decoration for BCID gap before train"};
+      SG::WriteDecorHandleKey<xAOD::EventInfo> m_BCIDGapAfterTrainKey {this, "BCIDGapAfterTrainKey", "EventInfo.DFCommonJets_BCIDGapAfterTrain", "Decoration for BCID gap after train"};
+      SG::WriteDecorHandleKey<xAOD::EventInfo> m_BCIDTypeKey {this, "BCIDTypeKey", "EventInfo.DFCommonJets_BCIDType", "Decoration for BCID type"};
+      SG::WriteDecorHandleKey<xAOD::EventInfo> m_BCIDGapBeforeTrainMinus12Key {this, "BCIDGapBeforeTrainMinus12Key", "EventInfo.DFCommonJets_BCIDGapBeforeTrainMinus12", "Decoration for BCID gap before train minus 12 BCIDs"};
+      SG::WriteDecorHandleKey<xAOD::EventInfo> m_BCIDGapAfterTrainMinus12Key {this, "BCIDGapAfterTrainMinus12Key", "EventInfo.DFCommonJets_BCIDGapAfterTrainMinus12", "Decoration for BCID gap after train minus 12 BCIDs"};
+      SG::WriteDecorHandleKey<xAOD::EventInfo> m_BCIDTypeMinus12Key {this, "BCIDTypeMinus12Key", "EventInfo.DFCommonJets_BCIDTypeMinus12", "Decoration for BCID type minus 12 BCIDs"};
+
+  }; 
+
+}
+
+#endif
+
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/JetAugmentationTool.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/JetAugmentationTool.cxx
index a87a47322f8ff5c5f10972bfa156308803a78642..7eadb5433a9da527a16cd4b3851fe500dd6ed8ae 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/JetAugmentationTool.cxx
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/JetAugmentationTool.cxx
@@ -17,18 +17,22 @@ namespace DerivationFramework {
       const std::string& n,
       const IInterface* p) : 
     AthAlgTool(t,n,p),
-    m_dec_calibpt(0),
-    m_dec_calibeta(0),
-    m_dec_calibphi(0),
-    m_dec_calibm(0),
     m_jetCalibTool(""),
     m_docalib(false),
-    m_dec_jvt(0),
     m_jvtTool(""),
+    m_jetJvtEfficiencyTool(""),
     m_dojvt(false),
     m_dobtag(false),
     m_jetTrackSumMomentsTool(""),
-    m_decoratetracksum(false)
+    m_decoratetracksum(false),
+    m_jetPtAssociationTool(""),
+    m_decorateptassociation(false),
+    m_trkSelectionTool(""),
+    m_trkVtxAssociationTool(""),
+    m_qgTool(""),
+    m_decorateQGVariables(false),
+    m_jetTruthLabelingTool(""),
+    m_decoratetruthlabel(false)
   {
     declareInterface<DerivationFramework::IAugmentationTool>(this);
     declareProperty("MomentPrefix",   m_momentPrefix = "DFCommonJets_");
@@ -38,9 +42,15 @@ namespace DerivationFramework {
     declareProperty("JetCalibTool",   m_jetCalibTool);
     declareProperty("JvtMomentKey",   m_jvtMomentKey = "Jvt");
     declareProperty("JetJvtTool",     m_jvtTool);
+    declareProperty("JetJvtEffTool",  m_jetJvtEfficiencyTool);
     declareProperty("JetBtagTools",   m_btagSelTools);
     declareProperty("JetBtagWPs",     m_btagWP);
     declareProperty("JetTrackSumMomentsTool", m_jetTrackSumMomentsTool);
+    declareProperty("JetPtAssociationTool", m_jetPtAssociationTool);
+    declareProperty("TrackSelectionTool", m_trkSelectionTool);
+    declareProperty("TrackVertexAssociationTool", m_trkVtxAssociationTool);
+    declareProperty("JetTruthLabelingTool", m_jetTruthLabelingTool);
+    declareProperty("JetQGTaggerTool", m_qgTool);
   }
 
   StatusCode JetAugmentationTool::initialize()
@@ -50,19 +60,21 @@ namespace DerivationFramework {
     if(!m_jetCalibTool.empty()) {
       CHECK(m_jetCalibTool.retrieve());
       ATH_MSG_INFO("Augmenting jets with calibration \"" << m_momentPrefix+m_calibMomentKey << "\"");
+
       m_docalib = true;
 
-      m_dec_calibpt  = new SG::AuxElement::Decorator<float>(m_momentPrefix+m_calibMomentKey+"_pt");
-      m_dec_calibeta = new SG::AuxElement::Decorator<float>(m_momentPrefix+m_calibMomentKey+"_eta");
-      m_dec_calibphi = new SG::AuxElement::Decorator<float>(m_momentPrefix+m_calibMomentKey+"_phi");
-      m_dec_calibm   = new SG::AuxElement::Decorator<float>(m_momentPrefix+m_calibMomentKey+"_m");
+      m_dec_calibpt  = std::make_unique< SG::AuxElement::Decorator<float> >(m_momentPrefix+m_calibMomentKey+"_pt");
+      m_dec_calibeta = std::make_unique< SG::AuxElement::Decorator<float> >(m_momentPrefix+m_calibMomentKey+"_eta");
+      m_dec_calibphi = std::make_unique< SG::AuxElement::Decorator<float> >(m_momentPrefix+m_calibMomentKey+"_phi");
+      m_dec_calibm   = std::make_unique< SG::AuxElement::Decorator<float> >(m_momentPrefix+m_calibMomentKey+"_m");
 
       if(!m_jvtTool.empty()) {
 	CHECK(m_jvtTool.retrieve());
 	ATH_MSG_INFO("Augmenting jets with updated JVT \"" << m_momentPrefix+m_jvtMomentKey << "\"");
 	m_dojvt = true;
 
-	m_dec_jvt  = new SG::AuxElement::Decorator<float>(m_momentPrefix+m_jvtMomentKey);
+	m_dec_jvt  = std::make_unique< SG::AuxElement::Decorator<float> >(m_momentPrefix+m_jvtMomentKey);
+        m_dec_passJvt  = std::make_unique< SG::AuxElement::Decorator<char> >(m_momentPrefix+"pass"+m_jvtMomentKey);
 
 	if(!m_btagSelTools.empty()) {
 	  size_t ibtag(0);
@@ -77,12 +89,58 @@ namespace DerivationFramework {
       }
     }
 
+    if(!m_jetJvtEfficiencyTool.empty()) {
+      CHECK(m_jetJvtEfficiencyTool.retrieve());
+      ATH_MSG_INFO("Jvt efficiency tool initialized \"" << m_momentPrefix+"pass"+m_jvtMomentKey << "\"");
+    }
+
     if(!m_jetTrackSumMomentsTool.empty()) {
       CHECK(m_jetTrackSumMomentsTool.retrieve());
       ATH_MSG_INFO("Augmenting jets with track sum moments \"" << m_momentPrefix << "TrackSumMass,Pt\"");
       m_decoratetracksum = true;
-      m_dec_tracksummass = new SG::AuxElement::Decorator<float>(m_momentPrefix+"TrackSumMass");
-      m_dec_tracksumpt   = new SG::AuxElement::Decorator<float>(m_momentPrefix+"TrackSumPt");
+      m_dec_tracksummass = std::make_unique< SG::AuxElement::Decorator<float> >(m_momentPrefix+"TrackSumMass");
+      m_dec_tracksumpt   = std::make_unique< SG::AuxElement::Decorator<float> >(m_momentPrefix+"TrackSumPt");
+    }
+
+    // This tool creates the GhostTruthAssociation decorations recommended for truth matching //
+    if(!m_jetPtAssociationTool.empty()){
+      CHECK(m_jetPtAssociationTool.retrieve());
+      ATH_MSG_INFO("Augmenting jets with GhostTruthAssociation moments Link and Fraction");
+      m_decorateptassociation = true;
+      m_dec_GhostTruthAssociationFraction = std::make_unique< SG::AuxElement::Decorator<float> >("GhostTruthAssociationFraction");
+      m_dec_GhostTruthAssociationLink     = std::make_unique< SG::AuxElement::Decorator< ElementLink<xAOD::JetContainer> > >("GhostTruthAssociationLink");
+    }
+
+    if(!m_trkSelectionTool.empty()) {
+      CHECK( m_trkSelectionTool.retrieve() );
+      if(!m_trkVtxAssociationTool.empty()){
+	CHECK( m_trkVtxAssociationTool.retrieve() );
+
+	if(!m_qgTool.empty()){
+	  CHECK(m_qgTool.retrieve());
+	  m_decorateQGVariables = true;
+	  m_dec_AssociatedNTracks     = std::make_unique< SG::AuxElement::Decorator<int> >(m_momentPrefix + "QGTagger_NTracks");
+	  m_dec_AssociatedTracksWidth = std::make_unique< SG::AuxElement::Decorator<float> >(m_momentPrefix + "QGTagger_TracksWidth");
+	  m_dec_AssociatedTracksC1    = std::make_unique< SG::AuxElement::Decorator<float> >(m_momentPrefix + "QGTagger_TracksC1");
+	  m_dec_Associated_truthjet_nCharged = std::make_unique< SG::AuxElement::Decorator<int> >(m_momentPrefix + "QGTagger_truthjet_nCharged");
+	  m_dec_Associated_truthjet_pt       = std::make_unique< SG::AuxElement::Decorator<float> >(m_momentPrefix + "QGTagger_truthjet_pt");
+	  m_dec_Associated_truthjet_eta      = std::make_unique< SG::AuxElement::Decorator<float> >(m_momentPrefix + "QGTagger_truthjet_eta");
+	}
+      }
+    }
+    
+    if(!m_jetTruthLabelingTool.empty()) {
+      CHECK(m_jetTruthLabelingTool.retrieve());
+      ATH_MSG_INFO("Augmenting jets with truthlabeling");
+      m_decoratetruthlabel = true;
+      m_truthLabelName = m_jetTruthLabelingTool->getLargeRJetTruthLabelName();
+      m_dec_Label = std::make_unique< SG::AuxElement::Decorator<int> >(m_truthLabelName);
+      m_dec_dRW = std::make_unique< SG::AuxElement::Decorator<float> >(m_truthLabelName+"_dR_W");
+      m_dec_dRZ = std::make_unique< SG::AuxElement::Decorator<float> >(m_truthLabelName+"_dR_Z");
+      m_dec_dRTop = std::make_unique< SG::AuxElement::Decorator<float> >(m_truthLabelName+"_dR_Top");
+      m_dec_dRH = std::make_unique< SG::AuxElement::Decorator<float> >(m_truthLabelName+"_dR_H");
+      m_dec_NB = std::make_unique< SG::AuxElement::Decorator<int> >(m_truthLabelName+"_NB");
+      m_dec_TruthJetMass = std::make_unique< SG::AuxElement::Decorator<float> >(m_truthLabelName+"_TruthJetMass");
     }
 
     return StatusCode::SUCCESS;
@@ -91,26 +149,10 @@ namespace DerivationFramework {
   StatusCode JetAugmentationTool::finalize()
   {
 
-    if(m_docalib) {
-      delete m_dec_calibpt;
-      delete m_dec_calibeta;
-      delete m_dec_calibphi;
-      delete m_dec_calibm;
-    }
-
-    if(m_dojvt) {
-      delete m_dec_jvt;
-    }
-
     if(m_dobtag) {
       for(const auto& pdec : m_dec_btag) delete pdec;
     }
 
-    if(m_decoratetracksum){
-      delete m_dec_tracksummass;
-      delete m_dec_tracksumpt;
-    }
-
     return StatusCode::SUCCESS;
   }
 
@@ -130,18 +172,48 @@ namespace DerivationFramework {
 
       // if we have a calibration tool, apply the calibration
     if(m_docalib) {
-      if(m_jetCalibTool->modify(*jets_copy) ) {
+      if((m_jetCalibTool->modify(*jets_copy)).isFailure()) {
 	ATH_MSG_WARNING("Problem applying jet calibration");
 	return StatusCode::FAILURE;
       }
     }
 
     if(m_decoratetracksum){
-      if(m_jetTrackSumMomentsTool->modify(*jets_copy) )
-      {
-        ATH_MSG_WARNING("Problems calculating TrackSumMass and TrackSumPt");
-        return StatusCode::FAILURE;
-      }
+      if((m_jetTrackSumMomentsTool->modify(*jets_copy)).isFailure())
+	{
+	  ATH_MSG_WARNING("Problems calculating TrackSumMass and TrackSumPt");
+	  return StatusCode::FAILURE;
+	}
+    }
+
+    // Check if GhostTruthAssociation decorations already exist for first jet, and if so skip them
+    bool isMissingPtAssociation = true;
+    if( !m_decorateptassociation || jets_copy->size() == 0 || m_dec_GhostTruthAssociationFraction->isAvailable(*jets_copy->at(0)) ) {
+      isMissingPtAssociation = false;
+    }
+
+    if(m_decorateptassociation && isMissingPtAssociation){
+      if((m_jetPtAssociationTool->modify(*jets_copy)).isFailure())
+	{
+	  ATH_MSG_ERROR("Problem running the JetPtAssociationTool");
+	  return StatusCode::FAILURE;
+	}
+    }
+
+    if(m_decoratetruthlabel){
+      if((m_jetTruthLabelingTool->modify(*jets_copy)).isFailure() )
+	{
+          ATH_MSG_ERROR("Problems applying large-R jet truth labels");
+          return StatusCode::FAILURE;
+        }
+    }
+
+    if(m_decorateQGVariables){
+      if((m_qgTool->decorate(*jets_copy)).isFailure() )
+	{
+	  ATH_MSG_ERROR("Problems applying the q/g tagging label");
+	  return StatusCode::FAILURE;
+	}
     }
 
     // loop over the copies
@@ -150,6 +222,7 @@ namespace DerivationFramework {
       const xAOD::Jet& jet_orig( *(*jets)[jet->index()] );
 
       if(m_docalib) {
+
 	// generate static decorators to avoid multiple lookups	
 	(*m_dec_calibpt)(jet_orig)  = jet->pt();
 	(*m_dec_calibeta)(jet_orig) = jet->eta();
@@ -159,8 +232,12 @@ namespace DerivationFramework {
 	ATH_MSG_VERBOSE("Calibrated jet pt: " << (*m_dec_calibpt)(jet_orig) );
 
 	if(m_dojvt) {
+
 	  (*m_dec_jvt)(jet_orig) = m_jvtTool->updateJvt(*jet);
 	  ATH_MSG_VERBOSE("Calibrated JVT: " << (*m_dec_jvt)(jet_orig) );
+	  
+	  bool passJVT_tool = m_jetJvtEfficiencyTool->passesJvtCut(jet_orig);
+	  (*m_dec_passJvt)(jet_orig) = passJVT_tool;
 
 	  if(m_dobtag) {
 	    bool passJVT = jet->pt()>50e3 || fabs(jet->eta())>2.4 || (*m_dec_jvt)(jet_orig)>0.64;
@@ -180,6 +257,37 @@ namespace DerivationFramework {
 	ATH_MSG_VERBOSE("TrackSumMass: " << (*m_dec_tracksummass)(jet_orig) );
 	ATH_MSG_VERBOSE("TrackSumPt: "   << (*m_dec_tracksummass)(jet_orig) );
       }
+
+      if(m_decorateptassociation && isMissingPtAssociation){
+        if(m_dec_GhostTruthAssociationFraction->isAvailable(*jet)){
+	  (*m_dec_GhostTruthAssociationFraction)(jet_orig) = jet->getAttribute<float>("GhostTruthAssociationFraction");
+	  ATH_MSG_VERBOSE("GhostTruthAssociationFraction: " << (*m_dec_GhostTruthAssociationFraction)(jet_orig) );
+	}
+	if(m_dec_GhostTruthAssociationLink->isAvailable(*jet)){
+	  (*m_dec_GhostTruthAssociationLink)(jet_orig) = jet->getAttribute< ElementLink<xAOD::JetContainer> >("GhostTruthAssociationLink");
+	  ATH_MSG_VERBOSE("GhostTruthAssociationLink: " << (*m_dec_GhostTruthAssociationLink)(jet_orig) );
+	}
+      }
+      
+      if(m_decoratetruthlabel){
+        if(m_dec_Label->isAvailable(*jet)) (*m_dec_Label)(jet_orig)  = (*m_dec_Label)(*jet);
+        if(m_dec_dRW->isAvailable(*jet)) (*m_dec_dRW)(jet_orig)  = (*m_dec_dRW)(*jet);
+        if(m_dec_dRZ->isAvailable(*jet)) (*m_dec_dRZ)(jet_orig)  = (*m_dec_dRZ)(*jet);
+        if(m_dec_dRTop->isAvailable(*jet)) (*m_dec_dRTop)(jet_orig)  = (*m_dec_dRTop)(*jet);
+        if(m_dec_dRH->isAvailable(*jet)) (*m_dec_dRH)(jet_orig)  = (*m_dec_dRH)(*jet);
+        if(m_dec_NB->isAvailable(*jet)) (*m_dec_NB)(jet_orig)  = (*m_dec_NB)(*jet);
+        if(m_dec_TruthJetMass->isAvailable(*jet)) (*m_dec_TruthJetMass)(jet_orig)  = (*m_dec_TruthJetMass)(*jet);
+      }
+
+      if(m_decorateQGVariables){
+	if(m_dec_AssociatedNTracks->isAvailable(*jet)) (*m_dec_AssociatedNTracks)(jet_orig) = (*m_dec_AssociatedNTracks)(*jet);
+	if(m_dec_AssociatedTracksWidth->isAvailable(*jet)) (*m_dec_AssociatedTracksWidth)(jet_orig) = (*m_dec_AssociatedTracksWidth)(*jet);
+	if(m_dec_AssociatedTracksC1->isAvailable(*jet)) (*m_dec_AssociatedTracksC1)(jet_orig) = (*m_dec_AssociatedTracksC1)(*jet);
+	if(m_dec_Associated_truthjet_nCharged->isAvailable(*jet)) (*m_dec_Associated_truthjet_nCharged)(jet_orig) = (*m_dec_Associated_truthjet_nCharged)(*jet);
+	if(m_dec_Associated_truthjet_pt->isAvailable(*jet)) (*m_dec_Associated_truthjet_pt)(jet_orig) = (*m_dec_Associated_truthjet_pt)(*jet);
+	if(m_dec_Associated_truthjet_eta->isAvailable(*jet)) (*m_dec_Associated_truthjet_eta)(jet_orig) = (*m_dec_Associated_truthjet_eta)(*jet);
+      }
+
     }
 
     return StatusCode::SUCCESS;
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/JetAugmentationTool.h b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/JetAugmentationTool.h
index b6e723fc9bf8eee692b76c5e52d2daf9b89324b5..f4bc5557f3e873273aad89cea9d48e913e763100 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/JetAugmentationTool.h
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/JetAugmentationTool.h
@@ -1,7 +1,7 @@
 ////////////////////-*- C++ -*-////////////////////////////////////
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // JetAugmentationTool.h, (c) ATLAS Detector software
@@ -19,9 +19,16 @@
 
 #include "JetInterface/IJetModifier.h"
 #include "JetInterface/IJetUpdateJvt.h"
+#include "JetInterface/IJetDecorator.h"
+#include "JetAnalysisInterfaces/IJetJvtEfficiency.h"
 #include "FTagAnalysisInterfaces/IBTaggingSelectionTool.h"
 #include "xAODJet/JetContainer.h"
 
+#include "InDetTrackSelectionTool/IInDetTrackSelectionTool.h"
+#include "TrackVertexAssociationTool/ITrackVertexAssociationTool.h"
+
+#include "ParticleJetTools/JetTruthLabelingTool.h"
+
 namespace DerivationFramework {
 
   class JetAugmentationTool : public AthAlgTool, public IAugmentationTool {
@@ -39,20 +46,27 @@ namespace DerivationFramework {
     // implement augmentations explicitly to avoid need to parse lists of moments to copy
     //
     // calibration
-    SG::AuxElement::Decorator<float>* m_dec_calibpt;
-    SG::AuxElement::Decorator<float>* m_dec_calibeta;
-    SG::AuxElement::Decorator<float>* m_dec_calibphi;
-    SG::AuxElement::Decorator<float>* m_dec_calibm;
+
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_calibpt;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_calibeta;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_calibphi;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_calibm;
     ToolHandle<IJetModifier> m_jetCalibTool;
     std::string m_calibMomentKey;
     bool m_docalib;
 
     // JVT
-    SG::AuxElement::Decorator<float>* m_dec_jvt;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_jvt;
+    std::unique_ptr< SG::AuxElement::Decorator<char> > m_dec_passJvt;
     ToolHandle<IJetUpdateJvt> m_jvtTool;
+    ToolHandle<CP::IJetJvtEfficiency> m_jetJvtEfficiencyTool;
     std::string m_jvtMomentKey;
     bool m_dojvt;
 
+    //PFlow fJVT
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_fjvt;
+    std::string m_fjvtMomentKey;
+
     // b-tagging       @author tripiana@cern.ch
     std::vector<SG::AuxElement::Decorator<float>*> m_dec_btag;
     std::vector<std::string> m_btagWP;
@@ -64,8 +78,39 @@ namespace DerivationFramework {
     //@author: nurfikri.bin.norjoharuddeen@cern.ch
     ToolHandle<IJetModifier> m_jetTrackSumMomentsTool;
     bool m_decoratetracksum;
-    SG::AuxElement::Decorator<float>* m_dec_tracksummass;
-    SG::AuxElement::Decorator<float>* m_dec_tracksumpt;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_tracksummass;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_tracksumpt;
+
+    // GhostTruthAssociation for derivations, @author jeff.dandoy@cern.ch
+    ToolHandle<IJetModifier> m_jetPtAssociationTool;
+    bool m_decorateptassociation;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_GhostTruthAssociationFraction;
+    std::unique_ptr< SG::AuxElement::Decorator< ElementLink<xAOD::JetContainer> > > m_dec_GhostTruthAssociationLink;
+
+    // Ntracks for QGTaggerTool --- 
+    ToolHandle<InDet::IInDetTrackSelectionTool> m_trkSelectionTool;
+    ToolHandle<CP::ITrackVertexAssociationTool> m_trkVtxAssociationTool;
+    ToolHandle<IJetDecorator> m_qgTool;
+    bool m_decorateQGVariables;
+    std::unique_ptr< SG::AuxElement::Decorator<int> > m_dec_AssociatedNTracks;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_AssociatedTracksWidth;
+    std::unique_ptr< SG::AuxElement::Decorator<float>  >m_dec_AssociatedTracksC1;
+    std::unique_ptr< SG::AuxElement::Decorator<int> > m_dec_Associated_truthjet_nCharged;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_Associated_truthjet_pt;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_Associated_truthjet_eta;
+
+    //// Large-R jet truth labeling @author jveatch@cern.ch and tnobe@cern.ch
+    ToolHandle<JetTruthLabelingTool> m_jetTruthLabelingTool;
+    bool m_decoratetruthlabel;
+    std::unique_ptr< SG::AuxElement::Decorator<int> > m_dec_Label;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_dRW;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_dRZ;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_dRH;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_dRTop;
+    std::unique_ptr< SG::AuxElement::Decorator<int> > m_dec_NB;
+    std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_TruthJetMass;
+    std::string m_truthLabelName;
+
   }; 
 }
 
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/PFlowAugmentationTool.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/PFlowAugmentationTool.cxx
index a784d88025ea902a29963647f46564d9f17c8473..7a26592f7c1436de4cf109a94c88101d2c3ead45 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/PFlowAugmentationTool.cxx
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/PFlowAugmentationTool.cxx
@@ -5,20 +5,18 @@
 ///////////////////////////////////////////////////////////////////
 // PFlowAugmentationTool.cxx, (c) ATLAS Detector software
 ///////////////////////////////////////////////////////////////////
-// Author: Fabrice Balli (fabrice.balli@cern.ch)
+// Author: Fabrice Balli (fabrice.balli@cern.ch), Chris Young (christopher.young@cern.ch)
 //
 
 #include "PFlowAugmentationTool.h"
-#include "xAODTracking/VertexContainer.h"
 
-namespace DerivationFramework {
+#include "StoreGate/WriteDecorHandle.h"
 
-const static SG::AuxElement::Decorator<char> dec_PVmatched("DFCommonPFlow_PVMatched");
-const static SG::AuxElement::Decorator<float> dec_corrP4_pt("DFCommonPFlow_CaloCorrectedPt");
+namespace DerivationFramework {
 
   PFlowAugmentationTool::PFlowAugmentationTool(const std::string& t,
-					       const std::string& n,
-					       const IInterface* p) : 
+                 const std::string& n,
+                 const IInterface* p) : 
     AthAlgTool(t,n,p),
     m_weightPFOTool("CP::WeightPFOTool/WeightPFOTool")
   {
@@ -31,6 +29,16 @@ const static SG::AuxElement::Decorator<float> dec_corrP4_pt("DFCommonPFlow_CaloC
   StatusCode PFlowAugmentationTool::initialize()
   {
 
+    ATH_CHECK(m_vertexContainer_key.initialize());
+    ATH_CHECK(m_pfoContainer_key.initialize());
+    ATH_CHECK(m_PVmatchedKey.initialize());
+    ATH_CHECK(m_corrP4_ptKey.initialize());
+    ATH_CHECK(m_z0Key.initialize());
+    ATH_CHECK(m_vzKey.initialize());
+    ATH_CHECK(m_d0Key.initialize());
+    ATH_CHECK(m_thetaKey.initialize());
+    ATH_CHECK(m_envWeightKey.initialize());
+
     return StatusCode::SUCCESS;
   }
 
@@ -43,17 +51,23 @@ const static SG::AuxElement::Decorator<float> dec_corrP4_pt("DFCommonPFlow_CaloC
   {
 
     // Get the vertex.
-    const xAOD::VertexContainer* pvcont(0);
     const xAOD::Vertex* pv(0);
-    ATH_CHECK(evtStore()->retrieve(pvcont, "PrimaryVertices"));
+
+    auto vertexContainer = SG::makeHandle (m_vertexContainer_key);
+    if (!vertexContainer.isValid()){
+      ATH_MSG_WARNING("Invalid  xAOD::VertexContainer datahandle"
+		      << m_vertexContainer_key.key()); 
+      return StatusCode::FAILURE;
+    }
+    auto pvcont = vertexContainer.cptr();
     if ( pvcont == 0 || pvcont->size()==0 ) {
       ATH_MSG_WARNING(" Failed to retrieve PrimaryVertices collection" );
       return StatusCode::FAILURE;
     }
     for (const auto& vx : *pvcont) {
       if (vx->vertexType() == xAOD::VxType::PriVtx) {
-	pv = vx;
-	break;
+        pv = vx;
+        break;
       }//If we have a vertex of type primary vertex
     }//iterate over the vertices and check their type
 
@@ -62,50 +76,71 @@ const static SG::AuxElement::Decorator<float> dec_corrP4_pt("DFCommonPFlow_CaloC
     if (pv == nullptr) {
       ATH_MSG_DEBUG("Could not find a primary vertex in this event" );
       for (auto theVertex : *pvcont) {
-	if (xAOD::VxType::NoVtx == theVertex->vertexType() ) {
-	  pv = theVertex;
-	  break;
-	}
+        if (xAOD::VxType::NoVtx == theVertex->vertexType() ) {
+          pv = theVertex;
+          break;
+        }
       }
       if (nullptr == pv) {
-	ATH_MSG_WARNING("Found neither PriVtx nor NoVtx in this event" );
+        ATH_MSG_WARNING("Found neither PriVtx nor NoVtx in this event" );
       }
     }
 
-    const xAOD::PFOContainer* cpfos = evtStore()->retrieve< const xAOD::PFOContainer >("JetETMissChargedParticleFlowObjects");
+    SG::WriteDecorHandle<xAOD::PFOContainer,char> dec_PVmatched(m_PVmatchedKey);
+    SG::WriteDecorHandle<xAOD::PFOContainer,float> dec_corrP4_pt(m_corrP4_ptKey);
+    SG::WriteDecorHandle<xAOD::PFOContainer,float> dec_z0(m_z0Key);
+    SG::WriteDecorHandle<xAOD::PFOContainer,float> dec_vz(m_vzKey);
+    SG::WriteDecorHandle<xAOD::PFOContainer,float> dec_d0(m_d0Key);
+    SG::WriteDecorHandle<xAOD::PFOContainer,float> dec_theta(m_thetaKey);
+    SG::WriteDecorHandle<xAOD::PFOContainer,float> dec_envWeight(m_envWeightKey);
+
+    auto pfoContainer = SG::makeHandle (m_pfoContainer_key);
+    if (!pfoContainer.isValid()){
+      ATH_MSG_WARNING("Invalid  xAOD::PFOContainer datahandle"
+                      << m_pfoContainer_key.key());
+      return StatusCode::FAILURE;
+    }
+    auto cpfos = pfoContainer.cptr();
+
     for ( const xAOD::PFO* cpfo : *cpfos ) {
       if ( cpfo == 0 ) {
-	ATH_MSG_WARNING("Have NULL pointer to charged PFO");
-	continue;
+        ATH_MSG_WARNING("Have NULL pointer to charged PFO");
+        continue;
       }
       const xAOD::TrackParticle* ptrk = cpfo->track(0);
       if ( ptrk == 0 ) {
-	ATH_MSG_WARNING("Skipping charged PFO with null track pointer.");
-	continue;
+        ATH_MSG_WARNING("Skipping charged PFO with null track pointer.");
+        continue;
       }
 
-      float weight = 1.0;
+      // decorate the track properties	
+      dec_z0(*cpfo) = ptrk->z0();
+      dec_vz(*cpfo) = ptrk->vz();
+      dec_d0(*cpfo) = ptrk->d0();
+      dec_theta(*cpfo) = ptrk->theta();
 
       bool matchedToPrimaryVertex = false;
       //vtz.z() provides z of that vertex w.r.t the center of the beamspot (z = 0). Thus we correct the track z0 to be w.r.t z = 0
       float z0 = ptrk->z0() + ptrk->vz();
       if (pv) {
-	z0 = z0 - pv->z();
-	float theta = ptrk->theta();
-	if ( fabs(z0*sin(theta)) < m_z0sinthcut ) {
-	  matchedToPrimaryVertex = true;
-	}
+        z0 = z0 - pv->z();
+        float theta = ptrk->theta();
+        if ( fabs(z0*sin(theta)) < m_z0sinthcut ) {
+          matchedToPrimaryVertex = true;
+        }
       }// if pv available
 
+      //find the weights from the tool
       int isInDenseEnvironment = false;
-      bool gotVariable = cpfo->attribute(xAOD::PFODetails::PFOAttributes::eflowRec_isInDenseEnvironment,isInDenseEnvironment);
-      if(gotVariable && isInDenseEnvironment){
+      float weight = 1.0;
+      if(cpfo->attribute(xAOD::PFODetails::PFOAttributes::eflowRec_isInDenseEnvironment,isInDenseEnvironment)){
 	ATH_CHECK( m_weightPFOTool->fillWeight( *cpfo, weight ) );
       }
 
-      // generate static decorators to avoid multiple lookups	
+      // decorate the computed variables	
       dec_PVmatched(*cpfo) = matchedToPrimaryVertex;
       dec_corrP4_pt(*cpfo) = weight*cpfo->pt();
+      dec_envWeight(*cpfo) = weight;
     }
 
     return StatusCode::SUCCESS;
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/PFlowAugmentationTool.h b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/PFlowAugmentationTool.h
index 825ee87348a626b3dbb35afd33d4d8bea21f21e1..5d65ad1528aa18ad4f14368cd62ff429a7380e46 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/PFlowAugmentationTool.h
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/PFlowAugmentationTool.h
@@ -17,6 +17,10 @@
 #include "DerivationFrameworkInterfaces/IAugmentationTool.h"
 #include "GaudiKernel/ToolHandle.h"
 
+#include "StoreGate/WriteDecorHandleKey.h"
+
+#include "xAODTracking/Vertex.h"
+#include "xAODTracking/VertexContainer.h"
 #include <xAODPFlow/PFOContainer.h>
 #include <PFlowUtils/IWeightPFOTool.h>
 
@@ -36,6 +40,17 @@ namespace DerivationFramework {
 
     ToolHandle<CP::IWeightPFOTool> m_weightPFOTool;    /// Retrieval tool
     bool m_useChargedWeights; //If true, them we make use of the charged PFO weighting scheme
+
+    SG::ReadHandleKey<xAOD::VertexContainer> m_vertexContainer_key{this, "VertexContainer", "PrimaryVertices", "Input vertex container"};
+    SG::ReadHandleKey<xAOD::PFOContainer> m_pfoContainer_key{this, "JetETMissChargedParticleFlowObjects", "JetETMissChargedParticleFlowObjects", "Input charged PFO"};
+
+    SG::WriteDecorHandleKey<xAOD::PFOContainer> m_PVmatchedKey {this, "PVmatchedKey", "JetETMissChargedParticleFlowObjects.DFCommonPFlow_PVMatched", "Boolean indicating if PFO was matched to PV "};
+    SG::WriteDecorHandleKey<xAOD::PFOContainer> m_corrP4_ptKey {this, "m_corrP4_ptKey", "JetETMissChargedParticleFlowObjects.DFCommonPFlow_CaloCorrectedPt", "Decoration for weighted charged PFO pt"};
+    SG::WriteDecorHandleKey<xAOD::PFOContainer> m_z0Key {this, "m_z0Key", "JetETMissChargedParticleFlowObjects.DFCommonPFlow_z0", "Decoration for track z0"};
+    SG::WriteDecorHandleKey<xAOD::PFOContainer> m_vzKey{this, "m_vzKey","JetETMissChargedParticleFlowObjects.DFCommonPFlow_vz", "Decoration for track vz"};
+    SG::WriteDecorHandleKey<xAOD::PFOContainer> m_d0Key{this, "m_d0Key","JetETMissChargedParticleFlowObjects.DFCommonPFlow_d0", "Decoration for track d0"};
+    SG::WriteDecorHandleKey<xAOD::PFOContainer> m_thetaKey{this, "m_thetaKey","JetETMissChargedParticleFlowObjects.DFCommonPFlow_theta", "Decoration for track theta"};
+    SG::WriteDecorHandleKey<xAOD::PFOContainer> m_envWeightKey{this, "m_envWeightKey","JetETMissChargedParticleFlowObjects.DFCommonPFlow_envWeight", "Decoration for weight for dense environments"};
     
   }; 
 }
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/TVAAugmentationTool.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/TVAAugmentationTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8793166274dfad6f83daf2376634205c1f73467c
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/TVAAugmentationTool.cxx
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+ */
+
+#include "TVAAugmentationTool.h"
+#include "xAODTracking/TrackParticleContainer.h"
+
+namespace DerivationFramework {
+
+  TVAAugmentationTool::TVAAugmentationTool(
+      const std::string& t,
+      const std::string& n,
+      const IInterface* p):
+    AthAlgTool(t, n, p)
+  {
+    declareInterface<IAugmentationTool>(this);
+    declareProperty("LinkName", m_linkName, "The name of the output links");
+    declareProperty("TrackName", m_trackName="InDetTrackParticles");
+    declareProperty("VertexName", m_vertexName="PrimaryVertices");
+    declareProperty("TVATool", m_tool);
+  }
+
+  StatusCode TVAAugmentationTool::initialize()
+  {
+    ATH_MSG_INFO("Initialising TVAAugmentationTool " << name() );
+    ATH_CHECK( m_tool.retrieve() );
+
+    m_vtxDec = std::make_unique<SG::AuxElement::Decorator<vtxLink_t>>(m_linkName);
+    return StatusCode::SUCCESS;
+  }
+
+  StatusCode TVAAugmentationTool::addBranches() const
+  {
+    const xAOD::VertexContainer* vertices = nullptr;
+    ATH_CHECK(evtStore()->retrieve(vertices, m_vertexName) );
+    const xAOD::TrackParticleContainer* tracks = nullptr;
+    ATH_CHECK(evtStore()->retrieve(tracks, m_trackName) );
+
+    xAOD::TrackVertexAssociationMap matchMap = m_tool->getMatchMap(*tracks, *vertices);
+
+    for (const xAOD::Vertex* ivtx : *vertices)
+      for (const xAOD::TrackParticle* itrk : matchMap[ivtx])
+        (*m_vtxDec)(*itrk).toContainedElement(*vertices, ivtx);
+
+    return StatusCode::SUCCESS;
+  }
+} //> end namespace DerivationFramework
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/TVAAugmentationTool.h b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/TVAAugmentationTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b2680b5ca9d6e186e6cdabacf6eba507988f390
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/TVAAugmentationTool.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+ */
+
+#ifndef DERIVATIONFRAMEWORK_TVAAUGMENTATIONTOOL_H
+#define DERIVATIONFRAMEWORK_TVAAUGMENTATIONTOOL_H
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
+#include "AsgTools/ToolHandle.h"
+#include "TrackVertexAssociationTool/ITrackVertexAssociationTool.h"
+#include "AthLinks/ElementLink.h"
+#include "xAODTracking/VertexContainer.h"
+#include <memory>
+
+namespace DerivationFramework {
+  class TVAAugmentationTool : public AthAlgTool, virtual public IAugmentationTool
+  {
+    public:
+      TVAAugmentationTool(const std::string& t, const std::string& n, const IInterface* p);
+
+      virtual StatusCode initialize();
+      virtual StatusCode addBranches() const;
+    private:
+      // Properties
+      std::string m_linkName;
+      std::string m_trackName;
+      std::string m_vertexName;
+      ToolHandle<CP::ITrackVertexAssociationTool> m_tool;
+      // Internals
+      using vtxLink_t = ElementLink<xAOD::VertexContainer>;
+      std::unique_ptr<SG::AuxElement::Decorator<vtxLink_t>> m_vtxDec;
+  }; //> end class TVAAugmentationTool
+} //> end namespace DerivationFramework
+
+#endif //> !DERIVATIONFRAMEWORK_TVAAUGMENTATIONTOOL_H
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/components/DerivationFrameworkJetEtMiss_entries.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/components/DerivationFrameworkJetEtMiss_entries.cxx
index 26b4c0dc8ca75711c89e293e514000dff1524a50..2eb23410166ba3313b5a12f8c6ef9c2dd3ec4621 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/components/DerivationFrameworkJetEtMiss_entries.cxx
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkJetEtMiss/src/components/DerivationFrameworkJetEtMiss_entries.cxx
@@ -4,6 +4,9 @@
 #include "../METTriggerAugmentationTool.h"
 #include "../ViewContainerThinning.h"
 #include "../JetExternalAssocTool.h"
+#include "../BadBatmanAugmentationTool.h"
+#include "../DistanceInTrainAugmentationTool.h"
+#include "../TVAAugmentationTool.h"
 
 using namespace DerivationFramework;
  
@@ -13,4 +16,6 @@ DECLARE_COMPONENT( PFlowAugmentationTool )
 DECLARE_COMPONENT( METTriggerAugmentationTool )
 DECLARE_COMPONENT( ViewContainerThinning )
 DECLARE_COMPONENT( JetExternalAssocTool )
-
+DECLARE_COMPONENT( BadBatmanAugmentationTool )
+DECLARE_COMPONENT( DistanceInTrainAugmentationTool )
+DECLARE_COMPONENT( TVAAugmentationTool )
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkL1Calo/CMakeLists.txt b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkL1Calo/CMakeLists.txt
index bc90e82d58322c6b382564a15c794caec0122ee9..a1e0aeebc760ecfee386df5a1b09d368c2a86cb5 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkL1Calo/CMakeLists.txt
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkL1Calo/CMakeLists.txt
@@ -30,6 +30,5 @@ atlas_add_component( DerivationFrameworkL1Calo
                      LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaBaseComps xAODTrigL1Calo GaudiKernel DerivationFrameworkL1CaloLib )
 
 # Install files from the package:
-atlas_install_python_modules( python/*.py )
 atlas_install_joboptions( share/*.py )
 
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkL1Calo/python/__init__.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkL1Calo/python/__init__.py
deleted file mode 100644
index 74583d364ec2ca794156596c7254d9b234a940c6..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkL1Calo/python/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkPhys/share/PHYS.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkPhys/share/PHYS.py
index ea86d9cdce3d23fb9511562760afb7fb219f4979..6aa324cd3280e6d376fa62a2584a0a1a5ab5bab3 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkPhys/share/PHYS.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkPhys/share/PHYS.py
@@ -172,16 +172,16 @@ reducedJetList = ["AntiKt2PV0TrackJets","AntiKt4PV0TrackJets"]
 if (DerivationFrameworkIsMonteCarlo):
    OutputJets["PHYS"].append("AntiKt10TruthTrimmedPtFrac5SmallR20Jets")
 
-# replaceAODReducedJets(reducedJetList,SeqPHYS,"PHYS")
-# add_largeR_truth_jets = DerivationFrameworkIsMonteCarlo and not hasattr(SeqPHYS,'jetalgAntiKt10TruthTrimmedPtFrac5SmallR20')
-# addDefaultTrimmedJets(SeqPHYS,"PHYS",dotruth=add_largeR_truth_jets)
+replaceAODReducedJets(reducedJetList,SeqPHYS,"PHYS")
+add_largeR_truth_jets = DerivationFrameworkIsMonteCarlo and not hasattr(SeqPHYS,'jetalgAntiKt10TruthTrimmedPtFrac5SmallR20')
+addDefaultTrimmedJets(SeqPHYS,"PHYS",dotruth=add_largeR_truth_jets)
 
 # Add large-R jet truth labeling
-# if (DerivationFrameworkIsMonteCarlo):
-#   addJetTruthLabel(jetalg="AntiKt10LCTopoTrimmedPtFrac5SmallR20",sequence=SeqPHYS,algname="JetTruthLabelingAlg",labelname="R10TruthLabel_R21Consolidated")
+if (DerivationFrameworkIsMonteCarlo):
+   addJetTruthLabel(jetalg="AntiKt10LCTopoTrimmedPtFrac5SmallR20",sequence=SeqPHYS,algname="JetTruthLabelingAlg",labelname="R10TruthLabel_R21Consolidated")
 
-# addQGTaggerTool(jetalg="AntiKt4EMTopo",sequence=SeqPHYS,algname="QGTaggerToolAlg")
-# addQGTaggerTool(jetalg="AntiKt4EMPFlow",sequence=SeqPHYS,algname="QGTaggerToolPFAlg")
+addQGTaggerTool(jetalg="AntiKt4EMTopo",sequence=SeqPHYS,algname="QGTaggerToolAlg")
+addQGTaggerTool(jetalg="AntiKt4EMPFlow",sequence=SeqPHYS,algname="QGTaggerToolPFAlg")
 
 # fJVT
 # getPFlowfJVT(jetalg='AntiKt4EMPFlow',sequence=SeqPHYS, algname='PHYSJetForwardPFlowJvtToolAlg')
@@ -274,7 +274,7 @@ PHYSSlimmingHelper.SmartCollections = ["Electrons",
                                        "TauJets",
                                        "DiTauJets",
                                        #"DiTauJetsLowPt",
-                                       #"AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets",
+                                       "AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets",
                                        #"AntiKtVR30Rmax4Rmin02TrackJets_BTagging201903",
                                        #"BTagging_AntiKtVR30Rmax4Rmin02Track_201903"
                                       ]
diff --git a/PhysicsAnalysis/Interfaces/JetAnalysisInterfaces/JetAnalysisInterfaces/IJetJvtEfficiency.h b/PhysicsAnalysis/Interfaces/JetAnalysisInterfaces/JetAnalysisInterfaces/IJetJvtEfficiency.h
index cc12cce119faacc7e6eba9d3b39abcd97e023570..45fba3de3fdb680449166d84f6a9113d00b00893 100644
--- a/PhysicsAnalysis/Interfaces/JetAnalysisInterfaces/JetAnalysisInterfaces/IJetJvtEfficiency.h
+++ b/PhysicsAnalysis/Interfaces/JetAnalysisInterfaces/JetAnalysisInterfaces/IJetJvtEfficiency.h
@@ -54,10 +54,10 @@ public:
 
     //Checks if the jet passes the jvt cut threshold. 
     //Uses maximum validity range by default, but there is a configurable parameter
-    virtual bool passesJvtCut(const xAOD::Jet& jet) = 0;
+    virtual bool passesJvtCut(const xAOD::Jet& jet) const = 0;
 
     //Checks if the jet lies in the pt and eta range where Jvt is valid.
-    virtual bool isInRange(const xAOD::Jet& jet) = 0;
+    virtual bool isInRange(const xAOD::Jet& jet) const = 0;
 
     //returns actual jvtthreshold
     virtual float getJvtThresh() const = 0;
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/CMakeLists.txt b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/CMakeLists.txt
index 1cdcdf6237b00e83ee19992733f760026774d2eb..773ec982b3f06f1297adfcbab9b30151d085d9f7 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/CMakeLists.txt
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/CMakeLists.txt
@@ -36,7 +36,7 @@ atlas_add_library( JetSelectorToolsLib
 
 if( NOT XAOD_STANDALONE )
    atlas_add_component( JetSelectorTools
-      src/components/*.cxx
+      src/*.h src/*.cxx src/components/*.cxx
       LINK_LIBRARIES GaudiKernel JetSelectorToolsLib )
 endif()
 
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.cxx b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.cxx
index 08f3c23cb974b1146cd77c7727de44922081fed0..59dd4b871cda45c14ae41f90f3646da91235b2e2 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.cxx
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // EDM includes
@@ -7,8 +7,6 @@
 // Local includes
 #include "EventCleaningTestAlg.h"
 
-static const float GeV = 1000.;
-static const float invGeV = 1./GeV;
 
 //-----------------------------------------------------------------------------
 // Constructor
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.h b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.h
index d57a5bc73832caf6a049d04b00580169e9f24ffe..b3dee4bb7bd76b93a6d8d60dfe812b53ea6d7150 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.h
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.h
@@ -27,7 +27,7 @@ class EventCleaningTestAlg : public AthAlgorithm
   public:
 
     /// Standard algorithm constructor
-    EventCleaningTestAlg(const std::string& name, ISvcLocator* svcLoc) override;
+    EventCleaningTestAlg(const std::string& name, ISvcLocator* svcLoc);
 
     /// Initialize the algorithm
     virtual StatusCode initialize() override;
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/components/JetSelectorTools_entries.cxx b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/components/JetSelectorTools_entries.cxx
index e9778688c98155bcab6e059caddef60b9cb00289..126faf470d07f016a8e9473e68fbd7404cdeaadc 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/components/JetSelectorTools_entries.cxx
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/components/JetSelectorTools_entries.cxx
@@ -1,6 +1,7 @@
 #include "JetSelectorTools/JetCleaningTool.h"
 #include "JetSelectorTools/EventCleaningTool.h"
+#include "../EventCleaningTestAlg.h"
 
 DECLARE_COMPONENT( JetCleaningTool )
 DECLARE_COMPONENT( ECUtils::EventCleaningTool )
-
+DECLARE_COMPONENT( EventCleaningTestAlg )
diff --git a/PhysicsAnalysis/MuonID/MuonSelectorTools/Root/MuonSelectionTool.cxx b/PhysicsAnalysis/MuonID/MuonSelectorTools/Root/MuonSelectionTool.cxx
index e4f059a355f00ac836064be076fcdd390aded78e..a75df787ea720fcea5c66e545741c06356db4b01 100644
--- a/PhysicsAnalysis/MuonID/MuonSelectorTools/Root/MuonSelectionTool.cxx
+++ b/PhysicsAnalysis/MuonID/MuonSelectorTools/Root/MuonSelectionTool.cxx
@@ -1262,11 +1262,11 @@ namespace CP {
     float symmetric_eta = std::abs( mu.eta() );
     float pt = mu.pt() / 1000.0; // GeV                                                                                                                                                                                                                                                                                                                                     
     // Impose pT and eta cuts; the bounds of the cut maps  
-    if( pt < 4.0 || symmetric_eta>2.5 ) return false;
+    if( pt < 4.0 || symmetric_eta >= 2.5 ) return false;
     ATH_MSG_VERBOSE( "Muon is passing tight WP kinematic cuts with pT,eta " << mu.pt() << "  ,  " << mu.eta()  );
 
     // ** Low pT specific cuts ** //  
-    if( pt > 4.0 && pt <= 20.0 ){
+    if( pt < 20.0 ){
 
       double rhoCut    = m_tightWP_lowPt_rhoCuts->Interpolate( pt, symmetric_eta );
       double qOverPCut = m_tightWP_lowPt_qOverPCuts->Interpolate( pt , symmetric_eta );
@@ -1287,7 +1287,7 @@ namespace CP {
     }
 
     // ** Medium pT specific cuts ** //  
-    else if ( pt > 20.0 && pt <= 100.0 ) {
+    else if ( pt < 100.0 ) {
       double rhoCut = m_tightWP_mediumPt_rhoCuts->Interpolate( pt , symmetric_eta );
       // 
       ATH_MSG_VERBOSE( "Applying tight WP cuts to a medium pt muon with (pt,eta) (" << pt << "," << mu.eta() << ")" );
@@ -1302,7 +1302,7 @@ namespace CP {
     }
 
     // ** High pT specific cuts  
-    else if ( pt > 100.0 && pt <= 500.0 ){
+    else if ( pt < 500.0 ){
       // 
       ATH_MSG_VERBOSE( "Applying tight WP cuts to a high pt muon with (pt,eta) (" << pt << "," << mu.eta() << ")" );
       // No interpolation, since bins with -1 mean we should cut really loose       
diff --git a/PhysicsAnalysis/TruthParticleID/McParticleEvent/McParticleEvent/TruthParticleContainer.h b/PhysicsAnalysis/TruthParticleID/McParticleEvent/McParticleEvent/TruthParticleContainer.h
index bc14d8075330bae2843c99ebc505b0157134e46f..8199b5a3249ada6ab0843cb3c4c62bad59ecce36 100644
--- a/PhysicsAnalysis/TruthParticleID/McParticleEvent/McParticleEvent/TruthParticleContainer.h
+++ b/PhysicsAnalysis/TruthParticleID/McParticleEvent/McParticleEvent/TruthParticleContainer.h
@@ -1,7 +1,7 @@
 ///////////////////////// -*- C++ -*- /////////////////////////////
 
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // TruthParticleContainer.h 
@@ -220,7 +220,7 @@ inline
 std::ostream& TruthParticleContainer::dump( std::ostream& out ) const 
 {
   if ( m_genEvent.isValid() ) {
-    (*m_genEvent)->print( out );
+    HepMC::Print::line(out,*m_genEvent);
   }
   return out;
 }
diff --git a/Projects/AnalysisBase/package_filters.txt b/Projects/AnalysisBase/package_filters.txt
index 347b2ae6dee32c626ad0a874f7e80735d5cf7e1c..89e1098b63b0c3610cb7fa1cf618ede26ff9f6ca 100644
--- a/Projects/AnalysisBase/package_filters.txt
+++ b/Projects/AnalysisBase/package_filters.txt
@@ -116,7 +116,7 @@
 + Reconstruction/egamma/egammaLayerRecalibTool
 + Reconstruction/egamma/egammaMVACalib
 + Reconstruction/egamma/egammaRecEvent
-#+ Reconstruction/tauRecTools
++ Reconstruction/tauRecTools
 + Tools/ART
 + Tools/DirectIOART
 + Tools/PathResolver
diff --git a/Projects/Athena/package_filters.txt b/Projects/Athena/package_filters.txt
index 4b3e7b0a29ba96b376d1e17d1ffddf75e9f506f4..2319dac52c2c1244a0b6031765b58423fa4cca4f 100644
--- a/Projects/Athena/package_filters.txt
+++ b/Projects/Athena/package_filters.txt
@@ -45,7 +45,6 @@
 - PhysicsAnalysis/TopPhys/xAOD/.*
 - PhysicsAnalysis/TrackingID/InDetTrackSystematicsTools
 - Reconstruction/Jet/JetAnalysisTools/JetTileCorrection
-- Reconstruction/Jet/JetJvtEfficiency
 - Reconstruction/Jet/JetReclustering
 - Trigger/TrigAnalysis/TrigTauAnalysis/TrigTauMatching
 
diff --git a/Reconstruction/HeavyIonRec/HIJetRec/HIJetRec/HIJetSignificanceTool.h b/Reconstruction/HeavyIonRec/HIJetRec/HIJetRec/HIJetSignificanceTool.h
index b97f8d17403053ea74cbb15f5cb7f4bc3f5bdde0..a4dc4db8b370a38377421f0c1ebe6c56bec9a623 100644
--- a/Reconstruction/HeavyIonRec/HIJetRec/HIJetRec/HIJetSignificanceTool.h
+++ b/Reconstruction/HeavyIonRec/HIJetRec/HIJetRec/HIJetSignificanceTool.h
@@ -29,7 +29,7 @@ class HIJetSignificanceTool: public asg::AsgTool,
  public:
   HIJetSignificanceTool(const std::string & name);
 
-  virtual StatusCode initialize();
+  virtual StatusCode initialize() override;
 
   //The modifyJet function has to be replaced by decorate
   //virtual int modifyJet(xAOD::Jet& ) const ;
diff --git a/Reconstruction/Jet/JetJvtEfficiency/CMakeLists.txt b/Reconstruction/Jet/JetJvtEfficiency/CMakeLists.txt
index 3086a3fc54a8f8aa3f3448ab5a87cc60645cf1ca..29fdb6aca282106e42b1f9dd2ab5be6157e56352 100644
--- a/Reconstruction/Jet/JetJvtEfficiency/CMakeLists.txt
+++ b/Reconstruction/Jet/JetJvtEfficiency/CMakeLists.txt
@@ -13,6 +13,7 @@ endif()
 atlas_depends_on_subdirs(
    PUBLIC
    Control/AthToolSupport/AsgTools
+   Event/xAOD/xAODEventInfo
    Event/xAOD/xAODJet
    PhysicsAnalysis/AnalysisCommon/PATInterfaces
    PRIVATE
@@ -27,7 +28,7 @@ atlas_add_library( JetJvtEfficiencyLib
    JetJvtEfficiency/*.h Root/*.cxx
    PUBLIC_HEADERS JetJvtEfficiency
    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-   LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools xAODJet PATInterfaces
+   LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools xAODJet xAODEventInfo JetAnalysisInterfacesLib PATInterfaces
    PRIVATE_LINK_LIBRARIES PathResolver )
 
 if( NOT XAOD_STANDALONE )
@@ -43,3 +44,4 @@ atlas_add_dictionary( JetJvtEfficiencyDict
 
 # Install files from the package:
 atlas_install_data( share/*.root )
+atlas_install_python_modules( python/*.py )
\ No newline at end of file
diff --git a/Reconstruction/Jet/JetJvtEfficiency/JetJvtEfficiency/JetJvtEfficiency.h b/Reconstruction/Jet/JetJvtEfficiency/JetJvtEfficiency/JetJvtEfficiency.h
index 4fbc880773997f31dc430679a53e944a4d01638b..23239ec6ab16bf7038b97bf5de0a0ed2fc8a6eff 100644
--- a/Reconstruction/Jet/JetJvtEfficiency/JetJvtEfficiency/JetJvtEfficiency.h
+++ b/Reconstruction/Jet/JetJvtEfficiency/JetJvtEfficiency/JetJvtEfficiency.h
@@ -1,58 +1,59 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef JETJVTEFFICIENCYSCALEFACTORS_H_
 #define JETJVTEFFICIENCYSCALEFACTORS_H_
 
-#include "JetJvtEfficiency/IJetJvtEfficiency.h"
+#include "JetAnalysisInterfaces/IJetJvtEfficiency.h"
 #include "PATInterfaces/SystematicsTool.h"
 #include "AsgTools/AsgTool.h"
-#include "TRandom3.h"
+
+#include "xAODEventInfo/EventInfo.h"
 
 #include <TH2.h>
 #include <string>
+#include <memory>
 
 namespace CP {
 
 enum SystApplied {
   NONE,
   JVT_EFFICIENCY_DOWN,
-  JVT_EFFICIENCY_UP
+  JVT_EFFICIENCY_UP,
+  FJVT_EFFICIENCY_DOWN,
+  FJVT_EFFICIENCY_UP,
+  MVFJVT_EFFICIENCY_DOWN,
+  MVFJVT_EFFICIENCY_UP
 };
 
-class JetJvtEfficiency: public CP::IJetJvtEfficiency, public asg::AsgTool, public CP::SystematicsTool{
+class JetJvtEfficiency: public asg::AsgTool, public CP::SystematicsTool, virtual public CP::IJetJvtEfficiency {
     ASG_TOOL_CLASS( JetJvtEfficiency, CP::IJetJvtEfficiency)
 
 public:
     JetJvtEfficiency( const std::string& name);
 
-    virtual StatusCode initialize();
-    virtual StatusCode finalize();
+    virtual StatusCode initialize() override;
 
     StatusCode histInitialize();
 
-    virtual CorrectionCode getEfficiencyScaleFactor(const xAOD::Jet& jet,float& sf);
-    virtual CorrectionCode getInefficiencyScaleFactor(const xAOD::Jet& jet,float& sf);
-    virtual CorrectionCode applyEfficiencyScaleFactor(const xAOD::Jet& jet);
-    virtual CorrectionCode applyInefficiencyScaleFactor(const xAOD::Jet& jet);
-    virtual CorrectionCode applyAllEfficiencyScaleFactor(const xAOD::IParticleContainer *jets,float& sf);
-    virtual CorrectionCode applyRandomDropping( const xAOD::Jet& jet );
-    virtual CorrectionCode applyAllRandomDropping( const xAOD::IParticleContainer *jets);
-
-    virtual bool passesJvtCut(const xAOD::Jet& jet);
-    virtual bool isInRange(const xAOD::Jet& jet);
+    virtual CorrectionCode getEfficiencyScaleFactor(const xAOD::Jet& jet,float& sf) override;
+    virtual CorrectionCode getInefficiencyScaleFactor(const xAOD::Jet& jet,float& sf) override;
+    virtual CorrectionCode applyEfficiencyScaleFactor(const xAOD::Jet& jet) override;
+    virtual CorrectionCode applyInefficiencyScaleFactor(const xAOD::Jet& jet) override;
+    virtual CorrectionCode applyAllEfficiencyScaleFactor(const xAOD::IParticleContainer *jets,float& sf) override;
+    virtual bool passesJvtCut(const xAOD::Jet& jet) const override;
+    virtual bool isInRange(const xAOD::Jet& jet) const override;
 
-    bool isAffectedBySystematic(const CP::SystematicVariation& var) const{return CP::SystematicsTool::isAffectedBySystematic(var);}
-    CP::SystematicSet affectingSystematics() const {return CP::SystematicsTool::affectingSystematics();}
-    CP::SystematicSet recommendedSystematics() const {return CP::SystematicsTool::recommendedSystematics();}
-    CP::SystematicCode applySystematicVariation(const CP::SystematicSet& set) {return CP::SystematicsTool::applySystematicVariation(set);}
-    CP::SystematicCode sysApplySystematicVariation(const CP::SystematicSet&);
+    bool isAffectedBySystematic(const CP::SystematicVariation& var) const override {return CP::SystematicsTool::isAffectedBySystematic(var);}
+    CP::SystematicSet affectingSystematics() const override {return CP::SystematicsTool::affectingSystematics();}
+    CP::SystematicSet recommendedSystematics() const override {return CP::SystematicsTool::recommendedSystematics();}
+    CP::SystematicCode applySystematicVariation(const CP::SystematicSet& set) override {return CP::SystematicsTool::applySystematicVariation(set);}
+    CP::SystematicCode sysApplySystematicVariation(const CP::SystematicSet&) override;
 
-    float getJvtThresh() const {return m_jvtCut;}
-    float getUserPtMax() const {return m_maxPtForJvt;}
-    void setRandomSeed(int seed);
-    StatusCode tagTruth(const xAOD::IParticleContainer *jets,const xAOD::IParticleContainer *truthJets);
+    float getJvtThresh() const override {return m_jvtCut;}
+    float getUserPtMax() const override {return m_maxPtForJvt;} 
+    StatusCode tagTruth(const xAOD::IParticleContainer *jets,const xAOD::IParticleContainer *truthJets) override;
 
 private:
 
@@ -62,23 +63,27 @@ private:
 
     std::string m_wp;
     std::string m_file;
-    SG::AuxElement::Decorator< float >* m_sfDec;
-    SG::AuxElement::Decorator< char >* m_dropDec;
-    TH2 *m_h_JvtHist;
-    TH2 *m_h_EffHist;
+    std::unique_ptr<SG::AuxElement::Decorator< float > > m_sfDec;
+    std::unique_ptr<SG::AuxElement::Decorator< char > > m_isHSDec;
+    std::unique_ptr<SG::AuxElement::ConstAccessor< char > > m_isHSAcc;
+    std::unique_ptr<TH2> m_h_JvtHist;
+    std::unique_ptr<TH2> m_h_EffHist;
     std::string m_sf_decoration_name;
-    std::string m_drop_decoration_name;
+    std::string m_isHS_decoration_name;
+    std::string m_truthJetContName;
     float m_jvtCut;
+    float m_jvtCutBorder;
     std::string m_jetJvtMomentName;
     std::string m_jetfJvtMomentName;
+    std::string m_jetMVfJvtMomentName;
     std::string m_jetEtaName;
     float m_maxPtForJvt;
-    TRandom3 m_rand;
-    std::string m_truthLabel;
     bool m_dofJVT;
+    bool m_doMVfJVT;
     bool m_doTruthRequirement;
     std::string m_ORdec;
     bool m_doOR;
+    bool m_useMuBinsSF;
 };
 
 } /* namespace CP */
diff --git a/Reconstruction/Jet/JetJvtEfficiency/Root/JetJvtEfficiency.cxx b/Reconstruction/Jet/JetJvtEfficiency/Root/JetJvtEfficiency.cxx
index 6f1d5ba09615c377cb02d8730628a105e7abda55..9909746ba03b1155196e2ed93b31a448f46de1cd 100644
--- a/Reconstruction/Jet/JetJvtEfficiency/Root/JetJvtEfficiency.cxx
+++ b/Reconstruction/Jet/JetJvtEfficiency/Root/JetJvtEfficiency.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "JetJvtEfficiency/JetJvtEfficiency.h"
@@ -12,40 +12,56 @@
 
 namespace CP {
 
-static SG::AuxElement::Decorator<char>  isHS("isJvtHS");
-static SG::AuxElement::Decorator<char>  isPU("isJvtPU");
+static SG::AuxElement::Decorator<char>  isPUDec("isJvtPU");
 
 JetJvtEfficiency::JetJvtEfficiency( const std::string& name): asg::AsgTool( name ),
   m_appliedSystEnum(NONE),
+  m_sfDec(nullptr),
+  m_isHSDec(nullptr),
+  m_isHSAcc(nullptr),
   m_h_JvtHist(nullptr),
   m_h_EffHist(nullptr),
   m_jvtCut(0),
-  m_rand(0)
+  m_jvtCutBorder(0)
   {
-    declareProperty( "WorkingPoint", m_wp = "Medium"                             );
-    declareProperty( "SFFile",m_file="JetJvtEfficiency/Moriond2016_v2/JvtSFFile.root");
-    //declareProperty( "SFFile",m_file="JetJvtEfficiency/JvtSFFile.root");
-    declareProperty( "ScaleFactorDecorationName", m_sf_decoration_name = "JvtSF"  );
-    declareProperty( "RandomDropDecorationName", m_drop_decoration_name = "drop"  );
-    declareProperty( "JetJvtMomentName",   m_jetJvtMomentName   = "Jvt"           );
-    declareProperty( "JetfJvtMomentName",   m_jetfJvtMomentName   = "passFJVT"    );
-    declareProperty("OverlapDecorator", m_ORdec = ""                        );
-    declareProperty( "JetEtaName",   m_jetEtaName   = "DetectorEta"               );
-    declareProperty( "MaxPtForJvt",   m_maxPtForJvt   = 60e3                      );
-    declareProperty( "TruthLabel",   m_truthLabel   = "isJvtHS"                      );
-    applySystematicVariation(CP::SystematicSet()).ignore();
+    declareProperty( "WorkingPoint",              m_wp = "Default"                                                );
+    declareProperty( "SFFile",                    m_file="JetJvtEfficiency/Moriond2018/JvtSFFile_EMTopoJets.root" );
+    declareProperty( "ScaleFactorDecorationName", m_sf_decoration_name = "JvtSF"                                  );
+    declareProperty( "JetJvtMomentName",          m_jetJvtMomentName   = "Jvt"                                    );
+    declareProperty( "JetfJvtMomentName",         m_jetfJvtMomentName   = "passFJVT"                              );
+    declareProperty( "JetMVfJvtMomentName",       m_jetMVfJvtMomentName = "passMVFJVT"                            );
+    declareProperty( "OverlapDecorator",          m_ORdec = ""                                                    );
+    declareProperty( "JetEtaName",                m_jetEtaName   = "DetectorEta"                                  );
+    declareProperty( "MaxPtForJvt",               m_maxPtForJvt   = 120e3                                         );
+    declareProperty( "DoTruthReq",                m_doTruthRequirement   = true                                   );
+    declareProperty( "TruthLabel",                m_isHS_decoration_name  = "isJvtHS"                             );
+    declareProperty( "TruthJetContainerName",     m_truthJetContName = "AntiKt4TruthJets"                         );
+    declareProperty( "UseMuSFFormat",             m_useMuBinsSF = false , "Use (mu,pT) or (|eta|,pT) binning for fJVT SFs" );
 }
 
 StatusCode JetJvtEfficiency::initialize(){
-  m_sfDec = new SG::AuxElement::Decorator< float>(m_sf_decoration_name);
-  m_dropDec = new SG::AuxElement::Decorator<char>(m_drop_decoration_name);
+  m_sfDec.reset(new SG::AuxElement::Decorator< float>(m_sf_decoration_name));
+  m_isHSDec.reset(new SG::AuxElement::Decorator<char>(m_isHS_decoration_name));
+  m_isHSAcc.reset(new SG::AuxElement::ConstAccessor<char>(m_isHS_decoration_name));
   m_dofJVT = (m_file.find("fJvt") != std::string::npos);
+  m_doMVfJVT = (m_file.find("MVfJVT") != std::string::npos);
   m_doOR = (!m_ORdec.empty());
-  m_doTruthRequirement = !(m_truthLabel.empty());
   if (!m_doTruthRequirement) ATH_MSG_WARNING ( "No truth requirement will be performed, which is not recommended.");
 
-  if (m_wp=="Loose") m_jvtCut = 0.11;
-  else if (m_wp=="Medium") m_jvtCut = 0.59;
+  bool ispflow = (m_file.find("EMPFlow") != std::string::npos);
+  
+  if (m_wp=="Default" && m_useMuBinsSF) m_wp = "Loose";
+  if (m_wp=="Default" && !ispflow) m_wp = "Medium";
+  if (m_wp=="Default" && ispflow) m_wp = "Tight";
+
+  m_jvtCutBorder = -2.;
+  if (m_wp=="Loose" && !ispflow) m_jvtCut = 0.11;
+  else if (m_wp=="Medium" && ispflow) m_jvtCut = 0.2;
+  else if (m_wp=="Tight" && ispflow) m_jvtCut = 0.5;
+  else if (m_wp=="Medium"){
+    m_jvtCut = 0.59;
+    m_jvtCutBorder = 0.11;
+  }
   else if (m_wp=="Tight") m_jvtCut = 0.91;
   else if (m_wp=="None") {
     m_jvtCut = -2;
@@ -53,8 +69,11 @@ StatusCode JetJvtEfficiency::initialize(){
     m_wp = "Medium";
   }
   else {
-    ATH_MSG_ERROR("Invalid jvt working point name");
-    return StatusCode::FAILURE;
+    // don't crash for fjvt WP names
+    if(!(m_dofJVT || m_doMVfJVT)){
+      ATH_MSG_ERROR("Invalid jvt working point name");
+      return StatusCode::FAILURE;
+    }
   }
 
   if (m_file.empty()) return StatusCode::SUCCESS;
@@ -68,28 +87,71 @@ StatusCode JetJvtEfficiency::initialize(){
 
   TFile *infile = TFile::Open(filename.c_str());
 
-  if (m_wp=="Loose") m_h_JvtHist = dynamic_cast<TH2*>(infile->Get("JvtLoose")) ;
-  else if (m_wp=="Medium") m_h_JvtHist = dynamic_cast<TH2*>(infile->Get("JvtDefault")) ;
-  else if (m_wp=="Tight") m_h_JvtHist = dynamic_cast<TH2*>(infile->Get("JvtTight")) ;
+  std::string histname = "Jvt";
 
-  m_h_JvtHist->SetDirectory(0);
+  if (m_wp=="Loose") histname+="Loose";
+  else if (m_wp=="Medium") histname+="Default";//this is a legacy working point
+  else if (m_wp=="Tight")  histname+="Tight";
+  else if (m_wp=="Tighter")  histname+="Tighter";
 
-  if (m_wp=="Loose") m_h_EffHist = dynamic_cast<TH2*>(infile->Get("EffLoose"));
-  else if (m_wp=="Medium") m_h_EffHist = dynamic_cast<TH2*>(infile->Get("EffDefault"));
-  else if (m_wp=="Tight") m_h_EffHist = dynamic_cast<TH2*>(infile->Get("EffTight"));
 
+  m_h_JvtHist.reset( dynamic_cast<TH2*>(infile->Get(histname.c_str())) );
+  if(!m_h_JvtHist){
+    ATH_MSG_ERROR("Histogram does not exist! " << histname << " If you are using Default please update to Loose");
+    return StatusCode::FAILURE;
+  }
+  m_h_JvtHist->SetDirectory(0);
+  histname.replace(0,3,"Eff");
+  m_h_EffHist.reset( dynamic_cast<TH2*>(infile->Get(histname.c_str())) );
   m_h_EffHist->SetDirectory(0);
 
-  if (!addAffectingSystematic(JvtEfficiencyUp,true) || !addAffectingSystematic(JvtEfficiencyDown,true)) {
-    ATH_MSG_ERROR("failed to set up Jvt systematics");
+  // Check consistency between config file and requested SF binning
+  if ( !(m_dofJVT || m_doMVfJVT) && m_useMuBinsSF ){
+    ATH_MSG_ERROR( "Mismatch in SF format. Please set UseMuSFFormat to false for JVT.");
+    return StatusCode::FAILURE;
+  }
+  if( m_dofJVT || m_doMVfJVT ){
+    if (m_useMuBinsSF && m_h_JvtHist->GetYaxis()->GetBinUpEdge(m_h_JvtHist->GetNbinsY())<=5. ){
+      ATH_MSG_ERROR( "Mismatch in fJVT SF format. Please set UseMuSFFormat to false to match the current configuration file.");
+      return StatusCode::FAILURE;
+    }
+    if (!m_useMuBinsSF && m_h_JvtHist->GetYaxis()->GetBinUpEdge(m_h_JvtHist->GetNbinsY())>5. ){
+      ATH_MSG_ERROR( "Mismatch in fJVT SF format. Please set UseMuSFFormat to true to match the current configuration file");
+      return StatusCode::FAILURE;
+    }
+  }
+
+  if(m_h_JvtHist.get()==nullptr || m_h_EffHist.get()==nullptr) {
+    ATH_MSG_ERROR("Failed to retrieve histograms.");
+    return StatusCode::FAILURE;
+  }
+
+  if (m_dofJVT){                                              
+    if ( !addAffectingSystematic(fJvtEfficiencyUp,true)
+	 || !addAffectingSystematic(fJvtEfficiencyDown,true)) {
+	ATH_MSG_ERROR("failed to set up fJvt systematics");
+	return StatusCode::FAILURE;
+    }
+  } else if (m_doMVfJVT){
+    if ( !addAffectingSystematic(MVfJvtEfficiencyUp,true)
+	 || !addAffectingSystematic(MVfJvtEfficiencyDown,true)) {
+	ATH_MSG_ERROR("failed to set up MVfJvt systematics");
+	return StatusCode::FAILURE;
+    }
+  } else {
+      if (!addAffectingSystematic(JvtEfficiencyUp,true)
+	  || !addAffectingSystematic(JvtEfficiencyDown,true)) {
+	  ATH_MSG_ERROR("failed to set up Jvt systematics");
+	  return StatusCode::FAILURE;
+      }
+  }
+
+  // Configure for nominal systematics
+  if (applySystematicVariation(CP::SystematicSet()) != CP::SystematicCode::Ok) {
+    ATH_MSG_ERROR("Could not configure for nominal settings");
     return StatusCode::FAILURE;
   }
-  return StatusCode::SUCCESS;
-}
 
-StatusCode JetJvtEfficiency::finalize(){
-  delete m_h_JvtHist;
-  delete m_h_EffHist;
   return StatusCode::SUCCESS;
 }
 
@@ -98,13 +160,42 @@ CorrectionCode JetJvtEfficiency::getEfficiencyScaleFactor( const xAOD::Jet& jet,
       sf = 1;
       return CorrectionCode::OutOfValidityRange;
     }
-    int jetbin = m_h_JvtHist->FindBin(jet.pt(),fabs(jet.getAttribute<float>(m_jetEtaName)));
+    if (m_doTruthRequirement) {
+        if(!m_isHSAcc->isAvailable(jet)) {
+            ATH_MSG_ERROR("Truth tagging required but decoration not available. Please call JetJvtEfficiency::tagTruth(...) first.");
+            return CorrectionCode::Error;
+        } else {
+            if (!(*m_isHSAcc)(jet)) {
+                sf = 1;
+                return CorrectionCode::Ok;
+            }
+        }
+    }
+
+    int jetbin = 0;
+    if( m_useMuBinsSF ){ // fJVT SFs used (pT,eta) binning, changed to (pT,mu) starting with 'Nov2019' calibration
+      const xAOD::EventInfo *eventInfo = nullptr;
+      if ( evtStore()->retrieve(eventInfo, "EventInfo").isFailure() )
+	{
+	  ATH_MSG_ERROR(" Could not retrieve EventInfo ");
+	  return CorrectionCode::Error;
+	}
+      jetbin = m_h_JvtHist->FindBin(jet.pt(),eventInfo->actualInteractionsPerCrossing());
+    } else {
+      jetbin = m_h_JvtHist->FindBin(jet.pt(),std::abs(jet.getAttribute<float>(m_jetEtaName)));
+    }
+
     float baseFactor = m_h_JvtHist->GetBinContent(jetbin);
     float errorTerm  = m_h_JvtHist->GetBinError(jetbin);
-    if (m_appliedSystEnum==JVT_EFFICIENCY_UP) baseFactor += errorTerm;
-    else if (m_appliedSystEnum==JVT_EFFICIENCY_DOWN) baseFactor -= errorTerm;
-    if (m_doTruthRequirement && !jet.auxdata<char>(m_truthLabel)) sf = 1;
-    else sf = baseFactor;
+    
+    if      ( !m_dofJVT && !m_doMVfJVT && m_appliedSystEnum==JVT_EFFICIENCY_UP      ) baseFactor += errorTerm;
+    else if ( !m_dofJVT && !m_doMVfJVT && m_appliedSystEnum==JVT_EFFICIENCY_DOWN    ) baseFactor -= errorTerm;
+    else if ( m_dofJVT  && !m_doMVfJVT && m_appliedSystEnum==FJVT_EFFICIENCY_UP     ) baseFactor += errorTerm;
+    else if ( m_dofJVT  && !m_doMVfJVT && m_appliedSystEnum==FJVT_EFFICIENCY_DOWN   ) baseFactor -= errorTerm;
+    else if ( !m_dofJVT && m_doMVfJVT  && m_appliedSystEnum==MVFJVT_EFFICIENCY_UP   ) baseFactor += errorTerm;
+    else if ( !m_dofJVT && m_doMVfJVT  && m_appliedSystEnum==MVFJVT_EFFICIENCY_DOWN ) baseFactor -= errorTerm;
+ 
+    sf = baseFactor;
     return CorrectionCode::Ok;
 }
 
@@ -113,17 +204,51 @@ CorrectionCode JetJvtEfficiency::getInefficiencyScaleFactor( const xAOD::Jet& je
       sf = 1;
       return CorrectionCode::OutOfValidityRange;
     }
-    int jetbin = m_h_JvtHist->FindBin(jet.pt(),fabs(jet.getAttribute<float>(m_jetEtaName)));
+    if (m_doTruthRequirement) {
+        if(!m_isHSAcc->isAvailable(jet)) {
+            ATH_MSG_ERROR("Truth tagging required but decoration not available. Please call JetJvtEfficiency::tagTruth(...) first.");
+            return CorrectionCode::Error;
+        } else {
+            if(!(*m_isHSAcc)(jet)) {
+                sf = 1;
+                return CorrectionCode::Ok;
+            }
+        }
+    }
+
+    int jetbin = 0;
+    if( m_useMuBinsSF ){
+      const xAOD::EventInfo *eventInfo = nullptr;
+      if ( evtStore()->retrieve(eventInfo, "EventInfo").isFailure() )
+	{
+	  ATH_MSG_ERROR(" Could not retrieve EventInfo ");
+	  return CorrectionCode::Error;
+	}
+      jetbin = m_h_JvtHist->FindBin(jet.pt(),eventInfo->actualInteractionsPerCrossing());
+    } else {
+      jetbin = m_h_JvtHist->FindBin(jet.pt(),std::abs(jet.getAttribute<float>(m_jetEtaName)));
+    }
+
     float baseFactor = m_h_JvtHist->GetBinContent(jetbin);
     float effFactor = m_h_EffHist->GetBinContent(jetbin);
     float errorTerm  = m_h_JvtHist->GetBinError(jetbin);
     float errorEffTerm  = m_h_EffHist->GetBinError(jetbin);
-    if (m_appliedSystEnum==JVT_EFFICIENCY_UP) baseFactor += errorTerm;
-    else if (m_appliedSystEnum==JVT_EFFICIENCY_DOWN) baseFactor -= errorTerm;
-    if (m_appliedSystEnum==JVT_EFFICIENCY_UP) effFactor += errorEffTerm;
-    else if (m_appliedSystEnum==JVT_EFFICIENCY_DOWN) effFactor -= errorEffTerm;
-    if (m_doTruthRequirement && !jet.auxdata<char>(m_truthLabel)) sf = 1;
-    else sf = (1-baseFactor*effFactor)/(1-effFactor);
+ 
+    if      ( !m_dofJVT && !m_doMVfJVT && m_appliedSystEnum==JVT_EFFICIENCY_UP      ) baseFactor += errorTerm;
+    else if ( !m_dofJVT && !m_doMVfJVT && m_appliedSystEnum==JVT_EFFICIENCY_DOWN    ) baseFactor -= errorTerm;
+    else if ( m_dofJVT  && !m_doMVfJVT && m_appliedSystEnum==FJVT_EFFICIENCY_UP     ) baseFactor += errorTerm;
+    else if ( m_dofJVT  && !m_doMVfJVT && m_appliedSystEnum==FJVT_EFFICIENCY_DOWN   ) baseFactor -= errorTerm;
+    else if ( !m_dofJVT && m_doMVfJVT  && m_appliedSystEnum==MVFJVT_EFFICIENCY_UP   ) baseFactor += errorTerm;
+    else if ( !m_dofJVT && m_doMVfJVT  && m_appliedSystEnum==MVFJVT_EFFICIENCY_DOWN ) baseFactor -= errorTerm;
+
+    if      ( !m_dofJVT && !m_doMVfJVT && m_appliedSystEnum==JVT_EFFICIENCY_UP      ) effFactor += errorEffTerm;
+    else if ( !m_dofJVT && !m_doMVfJVT && m_appliedSystEnum==JVT_EFFICIENCY_DOWN    ) effFactor -= errorEffTerm;
+    else if ( m_dofJVT  && !m_doMVfJVT && m_appliedSystEnum==FJVT_EFFICIENCY_UP     ) effFactor += errorEffTerm;
+    else if ( m_dofJVT  && !m_doMVfJVT && m_appliedSystEnum==FJVT_EFFICIENCY_DOWN   ) effFactor -= errorEffTerm;
+    else if ( !m_dofJVT && m_doMVfJVT  && m_appliedSystEnum==MVFJVT_EFFICIENCY_UP   ) effFactor += errorEffTerm;
+    else if ( !m_dofJVT && m_doMVfJVT  && m_appliedSystEnum==MVFJVT_EFFICIENCY_DOWN ) effFactor -= errorEffTerm;
+
+    sf = (1-baseFactor*effFactor)/(1-effFactor);
     return CorrectionCode::Ok;
 }
 
@@ -144,22 +269,34 @@ CorrectionCode JetJvtEfficiency::applyInefficiencyScaleFactor(const xAOD::Jet& j
 CorrectionCode JetJvtEfficiency::applyAllEfficiencyScaleFactor(const xAOD::IParticleContainer *jets,float& sf) {
   sf = 1;
   const xAOD::JetContainer *truthJets = nullptr;
-  if( evtStore()->retrieve(truthJets, "AntiKt4TruthJets").isFailure()) {
-      ATH_MSG_WARNING("Unable to retrieve AntiKt4TruthJets container");
+  if( evtStore()->retrieve(truthJets, m_truthJetContName).isFailure()) {
+    ATH_MSG_ERROR("Unable to retrieve truth jet container with name " << m_truthJetContName);
+    return CP::CorrectionCode::Error;
+    
   }
-  if(tagTruth(jets,truthJets).isFailure()) {
-    ATH_MSG_WARNING("Unable to match truthJets to jets in tagTruth() method");
+  if(!truthJets || tagTruth(jets,truthJets).isFailure()) {
+    ATH_MSG_ERROR("Unable to match truthJets to jets in tagTruth() method");
+    return CP::CorrectionCode::Error;
   }
   for(const auto& ipart : *jets) {
     if (ipart->type()!=xAOD::Type::Jet) {
-      ATH_MSG_WARNING("Input is not a jet");
+      ATH_MSG_ERROR("Input is not a jet");
       return CP::CorrectionCode::Error;
     }
     const xAOD::Jet *jet = static_cast<const xAOD::Jet*>(ipart);
     float current_sf = 0;
-    CorrectionCode result = (m_dofJVT?jet->getAttribute<char>(m_jetfJvtMomentName):passesJvtCut(*jet))?this->getEfficiencyScaleFactor(*jet,current_sf):this->getInefficiencyScaleFactor(*jet,current_sf);
+
+    CorrectionCode result;
+    if( ( m_dofJVT   && jet->getAttribute<char>(m_jetfJvtMomentName) )   ||
+        ( m_doMVfJVT && jet->getAttribute<char>(m_jetMVfJvtMomentName) ) ||
+	( (!m_dofJVT && ! m_doMVfJVT) && passesJvtCut(*jet) )              ){
+      result = this->getEfficiencyScaleFactor(*jet,current_sf);
+    } else {
+      result = this->getInefficiencyScaleFactor(*jet,current_sf);
+    }
+   
     if (result == CP::CorrectionCode::Error) {
-      ATH_MSG_WARNING("Inexplicably failed JVT calibration" );
+      ATH_MSG_ERROR("Inexplicably failed JVT calibration" );
       return result;
     }
     (*m_sfDec)(*jet) = current_sf;
@@ -168,44 +305,23 @@ CorrectionCode JetJvtEfficiency::applyAllEfficiencyScaleFactor(const xAOD::IPart
   return CorrectionCode::Ok;
 }
 
-CorrectionCode JetJvtEfficiency::applyRandomDropping( const xAOD::Jet& jet ) {
-  float sf = 0;
-  CorrectionCode result = this->getEfficiencyScaleFactor(jet,sf);
-  if (result == CP::CorrectionCode::Error) {
-    ATH_MSG_WARNING("Inexplicably failed JVT calibration" );
-    return result;
-  }
-  if (!isInRange(jet) || jet.getAttribute<float>(m_jetJvtMomentName)<m_jvtCut || (m_doTruthRequirement && !jet.auxdata<char>(m_truthLabel))) (*m_dropDec)(jet) = 0;
-  else (*m_dropDec)(jet) = m_rand.Rndm()>sf?1:0;
-  return result;
-}
 
-CorrectionCode JetJvtEfficiency::applyAllRandomDropping(const xAOD::IParticleContainer *jets) {
-  for(const auto& ipart : *jets) {
-    if (ipart->type()!=xAOD::Type::Jet) {
-      ATH_MSG_WARNING("Input is not a jet");
-      return CP::CorrectionCode::Error;
-    }
-    const xAOD::Jet *jet = static_cast<const xAOD::Jet*>(ipart);
-    CorrectionCode result = this->applyRandomDropping(*jet);
-    if (result == CP::CorrectionCode::Error) {
-      ATH_MSG_WARNING("Inexplicably failed JVT calibration" );
-      return result;
-    }
-  }
-  return CorrectionCode::Ok;
-}
 
-bool JetJvtEfficiency::passesJvtCut(const xAOD::Jet& jet) {
-  if (jet.isAvailable<char>(m_drop_decoration_name) && jet.auxdata<char>(m_drop_decoration_name)) return false;
+bool JetJvtEfficiency::passesJvtCut(const xAOD::Jet& jet) const {
   if (!isInRange(jet)) return true;
+  if (std::abs(jet.getAttribute<float>(m_jetEtaName))>2.4 && std::abs(jet.getAttribute<float>(m_jetEtaName))<2.5) return jet.getAttribute<float>(m_jetJvtMomentName)>m_jvtCutBorder;
   return jet.getAttribute<float>(m_jetJvtMomentName)>m_jvtCut;
 }
 
-bool JetJvtEfficiency::isInRange(const xAOD::Jet& jet) {
+bool JetJvtEfficiency::isInRange(const xAOD::Jet& jet) const {
   if (m_doOR && !jet.getAttribute<char>(m_ORdec)) return false;
-  if (fabs(jet.getAttribute<float>(m_jetEtaName))<m_h_JvtHist->GetYaxis()->GetBinLowEdge(1)) return false;
-  if (fabs(jet.getAttribute<float>(m_jetEtaName))>m_h_JvtHist->GetYaxis()->GetBinUpEdge(m_h_JvtHist->GetNbinsY())) return false;
+  if ( m_useMuBinsSF ){
+    if (std::abs(jet.getAttribute<float>(m_jetEtaName))<2.5) return false;
+    if (std::abs(jet.getAttribute<float>(m_jetEtaName))>4.5) return false;
+  } else {
+    if (std::abs(jet.getAttribute<float>(m_jetEtaName))<m_h_JvtHist->GetYaxis()->GetBinLowEdge(1)) return false;
+    if (std::abs(jet.getAttribute<float>(m_jetEtaName))>m_h_JvtHist->GetYaxis()->GetBinUpEdge(m_h_JvtHist->GetNbinsY())) return false;
+  }
   if (jet.pt()<m_h_JvtHist->GetXaxis()->GetBinLowEdge(1)) return false;
   if (jet.pt()>m_h_JvtHist->GetXaxis()->GetBinUpEdge(m_h_JvtHist->GetNbinsX())) return false;
   if (jet.pt()>m_maxPtForJvt) return false;
@@ -223,21 +339,18 @@ SystematicCode JetJvtEfficiency::sysApplySystematicVariation(const CP::Systemati
   }
   SystematicVariation systVar = *systSet.begin();
   if (systVar == SystematicVariation("")) m_appliedSystEnum = NONE;
-  else if (systVar == JvtEfficiencyUp) m_appliedSystEnum = JVT_EFFICIENCY_UP;
-  else if (systVar == JvtEfficiencyDown) m_appliedSystEnum = JVT_EFFICIENCY_DOWN;
-  else {
-    ATH_MSG_WARNING("unsupported systematic applied");
-    return SystematicCode::Unsupported;
-  }
+  else if (!m_dofJVT && !m_doMVfJVT && systVar == JvtEfficiencyUp      ) m_appliedSystEnum = JVT_EFFICIENCY_UP;
+  else if (!m_dofJVT && !m_doMVfJVT && systVar == JvtEfficiencyDown    ) m_appliedSystEnum = JVT_EFFICIENCY_DOWN;
+  else if (m_dofJVT && !m_doMVfJVT  && systVar == fJvtEfficiencyUp     ) m_appliedSystEnum = FJVT_EFFICIENCY_UP;
+  else if (m_dofJVT && !m_doMVfJVT  && systVar == fJvtEfficiencyDown   ) m_appliedSystEnum = FJVT_EFFICIENCY_DOWN;
+  else if (!m_dofJVT && m_doMVfJVT  && systVar == MVfJvtEfficiencyUp   ) m_appliedSystEnum = MVFJVT_EFFICIENCY_UP;
+  else if (!m_dofJVT && m_doMVfJVT  && systVar == MVfJvtEfficiencyDown ) m_appliedSystEnum = MVFJVT_EFFICIENCY_DOWN;
+  else m_appliedSystEnum = NONE;
 
   ATH_MSG_DEBUG("applied systematic is " << m_appliedSystEnum);
   return SystematicCode::Ok;
 }
 
-  void JetJvtEfficiency::setRandomSeed(int seed){
-    m_rand.SetSeed(seed);
-  }
-
 StatusCode JetJvtEfficiency::tagTruth(const xAOD::IParticleContainer *jets,const xAOD::IParticleContainer *truthJets) {
     for(const auto& jet : *jets) {
       bool ishs = false;
@@ -246,8 +359,8 @@ StatusCode JetJvtEfficiency::tagTruth(const xAOD::IParticleContainer *jets,const
         if (tjet->p4().DeltaR(jet->p4())<0.3 && tjet->pt()>10e3) ishs = true;
         if (tjet->p4().DeltaR(jet->p4())<0.6) ispu = false;
       }
-      isHS(*jet)=ishs;
-      isPU(*jet)=ispu;
+      (*m_isHSDec)(*jet)=ishs;
+      isPUDec(*jet)=ispu;
     }
     return StatusCode::SUCCESS;
   }
diff --git a/Reconstruction/Jet/JetJvtEfficiency/python/JetJvtEfficiencyToolConfig.py b/Reconstruction/Jet/JetJvtEfficiency/python/JetJvtEfficiencyToolConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..174f312d0ed817c66a049aa71af3c69fd11d7e23
--- /dev/null
+++ b/Reconstruction/Jet/JetJvtEfficiency/python/JetJvtEfficiencyToolConfig.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+########################################################################
+#                                                                      #
+# JetJvtEfficiencyToolConfig: A helper module for configuring jet jvt  #
+# efficiency configurations. This way the derivation framework can     #
+# easily be kept up to date with the latest recommendations.           #
+# Author: mswiatlo
+#                                                                      #
+########################################################################
+
+from AnaAlgorithm import Logging
+jetjvttoollog = Logging.logging.getLogger('JetJvtEfficiencyToolConfig')
+
+def getJvtEffTool( jetalg , toolname = ''):
+  from AthenaCommon import CfgMgr
+  if not toolname:
+    toolname = getJvtEffToolName( jetalg )
+
+  configs = {
+    "AntiKt4EMTopo": "JetJvtEfficiency/Moriond2018/JvtSFFile_EMTopoJets.root",
+    "AntiKt4EMPFlow": "JetJvtEfficiency/Moriond2018/JvtSFFile_EMPFlow.root"
+  }
+
+  jvtefftool = CfgMgr.CP__JetJvtEfficiency(toolname)
+  jvtefftool.SFFile=configs[ jetalg ] 
+
+  jetjvttoollog.info("Configured JetJvtEfficiencyTool {} for jetalg {}".format(toolname, jetalg))
+
+  return jvtefftool
+
+# return the default toolname for the specified alg
+def getJvtEffToolName( jetalg ):
+  toolname = "JVTEff_{0}".format(jetalg)
+  return toolname
diff --git a/Tracking/TrkEventCnv/TrkEventAthenaPool/python/__init__.py b/Reconstruction/Jet/JetJvtEfficiency/python/__init__.py
similarity index 100%
rename from Tracking/TrkEventCnv/TrkEventAthenaPool/python/__init__.py
rename to Reconstruction/Jet/JetJvtEfficiency/python/__init__.py
diff --git a/Reconstruction/Jet/JetMomentTools/CMakeLists.txt b/Reconstruction/Jet/JetMomentTools/CMakeLists.txt
index 00d9ffb3b84ca02d8a7c64129d2d28da1e28345d..79333ec13f2aef45cf32405fb5b53b2fda007c84 100644
--- a/Reconstruction/Jet/JetMomentTools/CMakeLists.txt
+++ b/Reconstruction/Jet/JetMomentTools/CMakeLists.txt
@@ -19,6 +19,9 @@ if( XAOD_STANDALONE OR XAOD_ANALYSIS )
       Event/xAOD/xAODJet
       Event/xAOD/xAODMissingET
       Event/xAOD/xAODTracking
+      Event/xAOD/xAODTruth
+      InnerDetector/InDetRecTools/InDetTrackSelectionTool
+      InnerDetector/InDetRecTools/TrackVertexAssociationTool
       Reconstruction/Jet/JetEDM
       Reconstruction/Jet/JetInterface
       Reconstruction/Jet/JetRec
@@ -39,6 +42,9 @@ else()
       Event/xAOD/xAODJet
       Event/xAOD/xAODMissingET
       Event/xAOD/xAODTracking
+      Event/xAOD/xAODTruth
+      InnerDetector/InDetRecTools/InDetTrackSelectionTool
+      InnerDetector/InDetRecTools/TrackVertexAssociationTool
       Reconstruction/Jet/JetEDM
       Reconstruction/Jet/JetInterface
       Reconstruction/Jet/JetRec
@@ -66,7 +72,7 @@ atlas_add_library( JetMomentToolsLib
    PUBLIC_HEADERS JetMomentTools
    PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
    LINK_LIBRARIES ${ROOT_LIBRARIES} ${Boost_LIBRARIES}
-   AsgTools xAODCaloEvent xAODJet xAODMissingET xAODTracking JetEDM JetInterface
+   AsgTools xAODCaloEvent xAODJet xAODMissingET xAODTracking xAODTruth JetEDM JetInterface TrackVertexAssociationToolLib
    JetRecLib JetUtils
    PRIVATE_LINK_LIBRARIES CaloGeoHelpers xAODEventInfo xAODPFlow PathResolver )
 
diff --git a/Reconstruction/Jet/JetMomentTools/JetMomentTools/JetQGTaggerVariableTool.h b/Reconstruction/Jet/JetMomentTools/JetMomentTools/JetQGTaggerVariableTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..236272322f31a75dc35ea25b1eabf0c802f85a16
--- /dev/null
+++ b/Reconstruction/Jet/JetMomentTools/JetMomentTools/JetQGTaggerVariableTool.h
@@ -0,0 +1,77 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+// JetQGTaggerVariableTool.h
+
+#ifndef JETMOMENTTOOLS_JETQGTAGGERVARIABLETOOL_H
+#define JETMOMENTTOOLS_JETQGTAGGERVARIABLETOOL_H
+
+/// Properties:
+///  VertexContainer - name of the vertex container
+///  EventInfo - name of EventInfo container
+///  AssociatedTracks - name for attribute holding the list of associated tracks
+///  TVATool - tool to do track-vertex association
+///  TrkSelTool - tool to select tracks (none ==> no selection)
+
+#include "AsgTools/ToolHandle.h"
+#include "AsgTools/AsgTool.h"
+#include "StoreGate/ReadDecorHandleKey.h"
+#include "StoreGate/WriteDecorHandleKey.h"
+
+#include "xAODTracking/Vertex.h"
+#include "xAODTracking/VertexContainer.h"
+#include "xAODTracking/TrackParticle.h"
+#include "xAODTracking/TrackParticleContainer.h"
+
+#include "InDetTrackSelectionTool/IInDetTrackSelectionTool.h"
+#include "TrackVertexAssociationTool/ITrackVertexAssociationTool.h"
+
+#include "xAODEventInfo/EventInfo.h"
+
+#include "xAODTruth/TruthParticle.h"
+
+#include "JetInterface/IJetDecorator.h"
+
+#include <vector>
+#include <string>
+
+class JetQGTaggerVariableTool : public asg::AsgTool,
+  virtual public IJetDecorator {
+  ASG_TOOL_CLASS(JetQGTaggerVariableTool,IJetDecorator)
+
+public:
+  // Constructor from tool name
+  JetQGTaggerVariableTool(const std::string& name);
+
+  // Initialization.
+  StatusCode initialize() override;
+
+  // Inherited method to decorate a jet container
+  virtual StatusCode decorate(const xAOD::JetContainer& jetCont) const override;
+
+  // Local method to return the HS vertex - that of type PriVtx
+  const xAOD::Vertex* findHSVertex(const xAOD::VertexContainer*&) const;
+
+private:  // data
+
+  // Configurable parameters
+  Gaudi::Property<std::string> m_jetContainerName{this,"JetContainer", "", "SG key for the input jet container"};
+  SG::ReadHandleKey<xAOD::VertexContainer> m_vertexContainer_key{this, "VertexContainer", "PrimaryVertices", "SG key for input vertex container"};
+  SG::ReadHandleKey<xAOD::EventInfo> m_eventInfo_key{this, "EventInfo", "EventInfo", "SG key for input EventInfo"};
+
+  ToolHandle<InDet::IInDetTrackSelectionTool> m_trkSelectionTool{this, "TrkSelTool", "Track selector tool"};
+  ToolHandle<CP::ITrackVertexAssociationTool> m_trkVertexAssocTool{this, "TVATool", "Track-vertex association tool"};
+
+  SG::WriteDecorHandleKey<xAOD::JetContainer> m_nTrkKey{this, "NTrksDecorName", "DFCommonJets_QGTagger_NTracks", "SG key for output NTracks decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetContainer> m_trkWidthKey{this, "TracksWidthDecorName", "DFCommonJets_QGTagger_TracksWidth", "SG key for output TracksWidth decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetContainer> m_trkC1Key{this, "TracksC1DecorName", "DFCommonJets_QGTagger_TracksC1", "SG key for output TracksC1 decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetContainer> m_nChargedKey{this, "nChargedDecorName", "DFCommonJets_QGTagger_truthjet_nCharged", "SG key for output truthjet_nCharged decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetContainer> m_truthPtKey{this, "truthPtDecorName", "DFCommonJets_QGTagger_truthjet_pt", "SG key for output truthjet_pt decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetContainer> m_truthEtaKey{this, "truthEtaDecorName", "DFCommonJets_QGTagger_truthjet_eta", "SG key for output truthjet_eta decoration"};
+
+};
+
+
+#endif
+
diff --git a/Reconstruction/Jet/JetMomentTools/Root/JetConstitFourMomTool.cxx b/Reconstruction/Jet/JetMomentTools/Root/JetConstitFourMomTool.cxx
index 145bf52d03541b5888f326b04fb2304e225e98d6..53c52473715208ea7a83ca1d6be4103c266c775e 100644
--- a/Reconstruction/Jet/JetMomentTools/Root/JetConstitFourMomTool.cxx
+++ b/Reconstruction/Jet/JetMomentTools/Root/JetConstitFourMomTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // JetConstitFourMomTool.cxx
@@ -155,10 +155,13 @@ StatusCode JetConstitFourMomTool::modify(xAOD::JetContainer& jets) const {
       if(m_isDetectorEtaPhi[iScale]) {
 	const static SG::AuxElement::Accessor<float> acc_modEta("DetectorEta");
 	const static SG::AuxElement::Accessor<float> acc_modPhi("DetectorPhi");
+	const static SG::AuxElement::Accessor<float> acc_modY("DetectorY");
 	acc_modEta(*jet) = constitFourVecs[iScale].Eta();
 	acc_modPhi(*jet) = constitFourVecs[iScale].Phi();
+	acc_modY(*jet) = constitFourVecs[iScale].Rapidity();
       ATH_MSG_VERBOSE("Detector eta: " << constitFourVecs[iScale].Eta()
-		   << ", phi: " << constitFourVecs[iScale].Phi());
+		      << ", phi: " << constitFourVecs[iScale].Phi()
+		      << ", rapidity: " << constitFourVecs[iScale].Rapidity());
       } else {
 	jet->setJetP4(m_jetScaleNames[iScale], constitFourVecs[iScale]);
       }
diff --git a/Reconstruction/Jet/JetMomentTools/Root/JetMomentToolsDict.h b/Reconstruction/Jet/JetMomentTools/Root/JetMomentToolsDict.h
index 1af9a28b11be4c61855dc19f57e4b95718c1aa37..0904e1b560e8bf80e3e564fb819d148868ad44a1 100644
--- a/Reconstruction/Jet/JetMomentTools/Root/JetMomentToolsDict.h
+++ b/Reconstruction/Jet/JetMomentTools/Root/JetMomentToolsDict.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef JETMOMENTTOOLS_JETMOMENTTOOLSDICT_H
@@ -20,5 +20,6 @@
 #include "JetMomentTools/JetVertexFractionTool.h"
 #include "JetMomentTools/JetVertexTaggerTool.h"
 #include "JetMomentTools/JetWidthTool.h"
+#include "JetMomentTools/JetQGTaggerVariableTool.h"
 
 #endif
diff --git a/Reconstruction/Jet/JetMomentTools/Root/JetQGTaggerVariableTool.cxx b/Reconstruction/Jet/JetMomentTools/Root/JetQGTaggerVariableTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..45211aed74ca16168469b167e0d649e37a18bf76
--- /dev/null
+++ b/Reconstruction/Jet/JetMomentTools/Root/JetQGTaggerVariableTool.cxx
@@ -0,0 +1,254 @@
+///////////////////////// -*- C++ -*- ////////////////////////////
+
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+
+#include "JetMomentTools/JetQGTaggerVariableTool.h"
+#include "PathResolver/PathResolver.h"
+#include "StoreGate/ReadDecorHandle.h"
+#include "StoreGate/WriteDecorHandle.h"
+
+
+using std::string;
+using xAOD::JetFourMom_t;
+
+//**********************************************************************
+
+JetQGTaggerVariableTool::JetQGTaggerVariableTool(const std::string& name)
+: asg::AsgTool(name){
+  declareInterface<IJetDecorator>(this);
+}
+
+//**********************************************************************
+
+StatusCode JetQGTaggerVariableTool::initialize() {
+  ATH_MSG_INFO("Initializing JetQGTaggerVariableTool " << name());
+
+  if(m_jetContainerName.empty()){
+    ATH_MSG_ERROR("JetQGTaggerVariableTool needs to have its input jet container configured!");
+    return StatusCode::FAILURE;
+  }
+
+  m_nTrkKey = m_jetContainerName + "." + m_nTrkKey.key();
+  m_trkWidthKey = m_jetContainerName + "." + m_trkWidthKey.key();
+  m_trkC1Key = m_jetContainerName + "." + m_trkC1Key.key();
+  m_nChargedKey = m_jetContainerName + "." + m_nChargedKey.key();
+  m_truthPtKey = m_jetContainerName + "." + m_truthPtKey.key();
+  m_truthEtaKey = m_jetContainerName + "." + m_truthEtaKey.key();
+
+  ATH_CHECK(m_vertexContainer_key.initialize());
+  ATH_CHECK(m_eventInfo_key.initialize());
+
+  ATH_CHECK(m_nTrkKey.initialize());
+  ATH_CHECK(m_trkWidthKey.initialize());
+  ATH_CHECK(m_trkC1Key.initialize());
+  ATH_CHECK(m_nChargedKey.initialize());
+  ATH_CHECK(m_truthPtKey.initialize());
+  ATH_CHECK(m_truthEtaKey.initialize());
+
+  return StatusCode::SUCCESS;
+}
+
+//**********************************************************************
+
+StatusCode JetQGTaggerVariableTool::decorate(const xAOD::JetContainer& jetCont) const {
+
+
+  SG::WriteDecorHandle<xAOD::JetContainer, int> nTrkHandle(m_nTrkKey);
+  SG::WriteDecorHandle<xAOD::JetContainer, float> trkWidthHandle(m_trkWidthKey);
+  SG::WriteDecorHandle<xAOD::JetContainer, float> trkC1Handle(m_trkC1Key);
+  SG::WriteDecorHandle<xAOD::JetContainer, int> nChargedHandle(m_nChargedKey);
+  SG::WriteDecorHandle<xAOD::JetContainer, float> truthPtHandle(m_truthPtKey);
+  SG::WriteDecorHandle<xAOD::JetContainer, float> truthEtaHandle(m_truthEtaKey);
+
+  // Get input vertex collection
+  auto vertexContainer = SG::makeHandle (m_vertexContainer_key);
+  if (!vertexContainer.isValid()){
+    ATH_MSG_ERROR("Invalid VertexContainer datahandle: " << m_vertexContainer_key.key());
+    return StatusCode::FAILURE;
+  }
+
+  auto vertices = vertexContainer.cptr();
+
+  ATH_MSG_DEBUG("Successfully retrieved VertexContainer: " << m_vertexContainer_key.key());
+
+  if (vertices->size() == 0 ) {
+    ATH_MSG_WARNING("There are no vertices in the container. Exiting");
+
+    for(const xAOD::Jet* jet : jetCont){
+      nTrkHandle(*jet) = -1;
+      trkWidthHandle(*jet) = -1.;
+      trkC1Handle(*jet) = -1.;
+      nChargedHandle(*jet) = -1;
+      truthPtHandle(*jet) = -1.;
+      truthEtaHandle(*jet) = -1.;
+    }
+
+    return StatusCode::SUCCESS;
+  }
+
+  //Find the HS vertex
+  const xAOD::Vertex* HSvertex = findHSVertex(vertices);
+
+  //Loop over the jets
+  for(const xAOD::Jet* jet : jetCont){
+
+    int nTracksCount = 0;
+    float TracksWidth = 0., SumTracks_pTs = 0., TracksC1 = 0., beta = 0.2;
+  
+    //Get ghost-associated tracks
+    std::vector<const xAOD::IParticle*> jettracks;
+    jet->getAssociatedObjects<xAOD::IParticle>(xAOD::JetAttribute::GhostTrack,jettracks);
+
+    //Loop over the tracks
+    std::vector<bool> IsGoodTrack;
+    TLorentzVector tracki_TLV, trackj_TLV;
+    TLorentzVector jet_TLV = jet -> p4();
+    for (size_t i = 0; i < jettracks.size(); i++) {
+
+      if(!jettracks[i]){
+	IsGoodTrack.push_back(false);
+	continue;
+      }
+
+      const xAOD::TrackParticle* trk = static_cast<const xAOD::TrackParticle*>(jettracks[i]);
+
+      // only count tracks with selections                                                                                                                                                              
+      // 1) pt>500 MeV                                                                                                                                                                                  
+      // 2) accepted track from InDetTrackSelectionTool with CutLevel==Loose                                                                                                                            
+      // 3) associated to primary vertex OR within 3mm of the primary vertex                                                                                                                            
+
+      bool accept = (trk->pt()>500 &&
+      		     m_trkSelectionTool->accept(*trk) &&
+		     (m_trkVertexAssocTool->isCompatible(*trk,*HSvertex) || (!m_trkVertexAssocTool->isCompatible(*trk,*HSvertex) && fabs((trk->z0()+trk->vz()-HSvertex->z())*sin(trk->theta()))<3.))
+		     );
+
+      IsGoodTrack.push_back(accept);
+      if (!accept) continue;
+
+      nTracksCount++;
+      
+      tracki_TLV = trk -> p4();
+      double DR_tracki_jet = tracki_TLV.DeltaR(jet_TLV);
+      TracksWidth += trk -> pt() * DR_tracki_jet;
+      SumTracks_pTs += trk -> pt();
+      
+    }// end loop over jettracks                                                                                                                                                                         
+    
+    if(SumTracks_pTs>0.) TracksWidth = TracksWidth / SumTracks_pTs;
+    else TracksWidth = -1.;
+
+    //Calculate C1 from tracks
+    for(size_t i = 0; i < jettracks.size(); i++) {
+      const xAOD::TrackParticle* trki = static_cast<const xAOD::TrackParticle*>(jettracks[i]);
+      if( !( IsGoodTrack.at(i) ) ) continue;
+
+      for(size_t j = i+1; j < jettracks.size(); j++) {
+	const xAOD::TrackParticle* trkj = static_cast<const xAOD::TrackParticle*>(jettracks[j]);
+	if( !( IsGoodTrack.at(j) ) ) continue;
+
+	tracki_TLV = trki -> p4();
+	trackj_TLV = trkj -> p4();
+	double DR_tracki_trackj = tracki_TLV.DeltaR(trackj_TLV);
+	TracksC1 += trki -> pt() * trkj -> pt() * pow( DR_tracki_trackj, beta) ;
+	
+      }//end loop over j 
+    }//end double loop over ij                                                                                                                                                                          
+
+    if(SumTracks_pTs>0.) TracksC1 = TracksC1 / ( pow(SumTracks_pTs, 2.) );
+    else TracksC1 = -1.;
+
+    // Add truth variables for QG tagging                                                                                                                                                               
+
+    auto eventInfoContainer = SG::makeHandle (m_eventInfo_key);
+    if (!eventInfoContainer.isValid()){
+      ATH_MSG_ERROR("Invalid EventInfo datahandle: " << m_eventInfo_key.key());
+      return StatusCode::FAILURE;
+    }
+
+    auto eventInfo = eventInfoContainer.cptr();
+
+    bool isMC = eventInfo->eventType(xAOD::EventInfo::IS_SIMULATION);
+    int tntrk = 0;
+    float truthjet_pt  = -999.0;
+    float truthjet_eta = -999.0;
+
+    if(isMC){
+      const xAOD::Jet* tjet=nullptr;
+      if(jet->isAvailable< ElementLink<xAOD::JetContainer> >("GhostTruthAssociationLink") ){
+	ATH_MSG_DEBUG("Accessing GhostTruthAssociationLink: is available");
+	if(jet->auxdata< ElementLink<xAOD::JetContainer> >("GhostTruthAssociationLink").isValid() ){
+	  ATH_MSG_DEBUG("Accessing GhostTruthAssociationLink: is valid");
+	  ElementLink<xAOD::JetContainer> truthlink = jet->auxdata< ElementLink<xAOD::JetContainer> >("GhostTruthAssociationLink");
+	  if(truthlink)
+	    tjet = * truthlink;
+	  else{
+	    ATH_MSG_DEBUG("Skipping...truth link is broken");
+	  }//endelse NULL pointer                                                                                                                                                                       
+	}
+	else {
+	  ATH_MSG_DEBUG("Invalid truth link: setting weight to 1");
+	} //endelse isValid                                                                                                                                                                             
+      } //endif isAvailable                                                                                                                                                                             
+      else {
+	ATH_MSG_DEBUG("Cannot access truth Link: setting weight to 1");
+      }//endelse isAvailable                                                                                                                                                                            
+      
+      if(tjet){
+	ATH_MSG_DEBUG("Truth Jet: " << tjet->numConstituents());
+	
+	truthjet_pt  = tjet->pt();
+	truthjet_eta = tjet->eta();
+	
+	//Calculate the number of charged final state particles with pT > 500 MeV
+	for (size_t ind = 0; ind < tjet->numConstituents(); ind++) {
+	  const xAOD::TruthParticle *part = static_cast<const xAOD::TruthParticle*>(tjet->rawConstituent(ind));
+	  ATH_MSG_DEBUG("part: " << part );
+	  // dont count invalid truth particles                                                                                                                                                         
+	  if (!part) continue;
+	  // require the particle in the final state                                                                                                                                                    
+	  ATH_MSG_DEBUG("status: " << (part->status()) );
+	  if( ! (part->status() == 1) ) continue;
+	  // require that the particle type (e.g. production type) be valid (e.g. not primaries)                                                                                                        
+	  ATH_MSG_DEBUG("barcode: " << (part->barcode()) );
+	  if ((part->barcode())>2e5) continue;
+	  // pt>500 MeV
+	  ATH_MSG_DEBUG("pt: " << (part->pt()) );
+	  if( ! (part->pt()>500.) )  continue;
+	  // charged                                                                                                                                                                                    
+	  ATH_MSG_DEBUG("isCharged: " << (part->isCharged()) );
+	  if( !(part->isCharged()) ) continue;
+	  tntrk++;
+	}
+      }
+    }
+
+    nTrkHandle(*jet) = nTracksCount;
+    trkWidthHandle(*jet) = TracksWidth;
+    trkC1Handle(*jet) = TracksC1;
+    nChargedHandle(*jet) = tntrk;
+    truthPtHandle(*jet) = truthjet_pt;
+    truthEtaHandle(*jet) = truthjet_eta;
+
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//**********************************************************************
+
+const xAOD::Vertex* JetQGTaggerVariableTool::findHSVertex(const xAOD::VertexContainer*& vertices) const
+{
+  for ( size_t iVertex = 0; iVertex < vertices->size(); ++iVertex ) {
+    if(vertices->at(iVertex)->vertexType() == xAOD::VxType::PriVtx) {
+
+      ATH_MSG_VERBOSE("JetQGTaggerVariableTool " << name() << " Found HS vertex at index: "<< iVertex);
+      return vertices->at(iVertex);
+    }
+  }
+  ATH_MSG_VERBOSE("There is no vertex of type PriVx. Taking default vertex.");
+  return vertices->at(0);
+}
diff --git a/Reconstruction/Jet/JetMomentTools/Root/LinkDef.h b/Reconstruction/Jet/JetMomentTools/Root/LinkDef.h
index 608de1d77d845008676a2359f6e0c623a614f7ea..e893f68c72928edd9e777ee0a738a42c915fd194 100644
--- a/Reconstruction/Jet/JetMomentTools/Root/LinkDef.h
+++ b/Reconstruction/Jet/JetMomentTools/Root/LinkDef.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "PFlowUtils/IWeightPFOTool.h"
@@ -17,6 +17,7 @@
 #include "JetMomentTools/JetVertexTaggerTool.h"
 #include "JetMomentTools/JetWidthTool.h"
 #include "JetMomentTools/JetCaloEnergies.h"
+#include "JetMomentTools/JetQGTaggerVariableTool.h"
 
 #ifdef __CINT__
 
@@ -39,6 +40,6 @@
 #pragma link C++ class JetVertexTaggerTool+;
 #pragma link C++ class JetWidthTool+;
 #pragma link C++ class JetCaloEnergies+;
-
+#pragma link C++ class JetQGTaggerVariableTool+;
 
 #endif
diff --git a/Reconstruction/Jet/JetMomentTools/Root/selection.xml b/Reconstruction/Jet/JetMomentTools/Root/selection.xml
index f2be0c3e7a37e5685c08b8f7ef19b6168e75e3b9..75c2e45b4e20224eb49e577a75c4fba9e3ae0505 100644
--- a/Reconstruction/Jet/JetMomentTools/Root/selection.xml
+++ b/Reconstruction/Jet/JetMomentTools/Root/selection.xml
@@ -13,4 +13,5 @@
 <class name="JetVertexFractionTool"/>
 <class name="JetVertexTaggerTool"/>
 <class name="JetWidthTool"/>
+<class name="JetQGTaggerVariableTool"/>
 </lcgdict>
diff --git a/Reconstruction/Jet/JetMomentTools/src/components/JetMomentTools_entries.cxx b/Reconstruction/Jet/JetMomentTools/src/components/JetMomentTools_entries.cxx
index c5f220232aaf8f632aba7a29d932764f457b5551..4b8bd610fc09d0912c42d18cf61c8221441a7bf7 100644
--- a/Reconstruction/Jet/JetMomentTools/src/components/JetMomentTools_entries.cxx
+++ b/Reconstruction/Jet/JetMomentTools/src/components/JetMomentTools_entries.cxx
@@ -16,6 +16,7 @@
 #include "JetMomentTools/JetOriginCorrectionTool.h"
 #include "JetMomentTools/JetECPSFractionTool.h"
 #include "JetMomentTools/JetConstitFourMomTool.h"
+#include "JetMomentTools/JetQGTaggerVariableTool.h"
 
 #ifndef XAOD_ANALYSIS
 #include "JetMomentTools/JetBadChanCorrTool.h"
@@ -39,6 +40,7 @@ DECLARE_COMPONENT( JetLArHVTool )
 DECLARE_COMPONENT( JetOriginCorrectionTool )
 DECLARE_COMPONENT( JetECPSFractionTool )
 DECLARE_COMPONENT( JetConstitFourMomTool )
+DECLARE_COMPONENT( JetQGTaggerVariableTool )
 
 #ifndef XAOD_ANALYSIS
 DECLARE_COMPONENT( JetBadChanCorrTool )
diff --git a/Reconstruction/Jet/JetRec/JetRec/JetClusterer.h b/Reconstruction/Jet/JetRec/JetRec/JetClusterer.h
index 32fbe46d8b8bed5843b1d39c548b81740c8b46c2..64b71f7bd2e950f6d0c316b40ef139c8b640341b 100644
--- a/Reconstruction/Jet/JetRec/JetRec/JetClusterer.h
+++ b/Reconstruction/Jet/JetRec/JetRec/JetClusterer.h
@@ -19,13 +19,14 @@
 
 #include "xAODEventInfo/EventInfo.h"
 #include "StoreGate/ReadHandleKey.h"
+#include "StoreGate/WriteHandleKey.h"
 
 #include "JetInterface/IJetProvider.h"
 #include "AsgTools/AsgTool.h"
 
 #include "JetRec/PseudoJetContainer.h"
 #include "JetRec/JetFromPseudojet.h"
-
+#include "JetEDM/PseudoJetVector.h"
 
 #include "fastjet/PseudoJet.hh"
 #include "fastjet/AreaDefinition.hh"
@@ -61,7 +62,7 @@ protected:
   SG::ReadHandleKey<PseudoJetContainer> m_inputPseudoJets {this, "InputPseudoJets", "inputpseudojet", "input constituents"};
 
   /// used to build the key under which the final PJ will be stored in evtStore() 
-  std::string m_finalPseudoJets;
+  SG::WriteHandleKey<PseudoJetVector> m_finalPseudoJets {this, "FinalPseudoJets_DONOTSET", "", "output pseudojets -- autoconfigured name"};
   
   // Job options.
   Gaudi::Property<std::string>  m_jetalg {this, "JetAlgorithm", "AntiKt", "alg type : AntiKt, Kt, CA..."};
diff --git a/Reconstruction/Jet/JetRec/JetRec/JetGroomer.h b/Reconstruction/Jet/JetRec/JetRec/JetGroomer.h
index 3cbff98faf653e31b81a69fc7cfc2fb7ec9e6ce0..60bca3c63ccdc57afbdca8c32a31ad5505fbdab6 100644
--- a/Reconstruction/Jet/JetRec/JetRec/JetGroomer.h
+++ b/Reconstruction/Jet/JetRec/JetRec/JetGroomer.h
@@ -9,16 +9,23 @@
 ///
 /// \class JetGroomer
 ///
-/// Creates a new JetContainer by grooming an input jet collection
+/// Base class for tools that create a new JetContainer by grooming an input jet collection
 ///
-/// This tool implements the IJetProvider interface. The JetContainer it returns is built by
-/// running an IJetGroomer tool (e.g. JetTrimmer) on the input jets.
+/// This tool implements the IJetProvider interface. Children should override (only)
+/// the initialize and insertGroomedJet methods, to implement a specific instance of
+/// jet grooming.
 ///
 
 #include "AsgTools/AsgTool.h"
+
 #include "StoreGate/ReadHandleKey.h"
+#include "StoreGate/WriteHandleKey.h"
+
 #include "JetInterface/IJetProvider.h"
-#include "JetInterface/IJetGroomer.h"
+
+#include "JetEDM/PseudoJetVector.h"
+#include "JetRec/PseudoJetContainer.h"
+
 #include "xAODJet/JetContainer.h"
 #include "xAODJet/JetAuxContainer.h"
 
@@ -32,17 +39,23 @@ class JetGroomer
     using asg::AsgTool::AsgTool;
 
     virtual StatusCode initialize() override;
-    virtual std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> > getJets() const override;
 
-  private:
-    // Handle Input JetContainer
-    SG::ReadHandleKey<xAOD::JetContainer> m_inputJetsKey {this, "UngroomedJets", "", "Jet collection to be groomed"};
+    // From IJetProvider
+    virtual std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> > getJets() const override final;
+
+    // Implementation of grooming goes here
+    // The jet is inserted into the output container, which is necessary for speed
+    // in the xAOD container paradigm
+  virtual void insertGroomedJet(const xAOD::Jet&, const PseudoJetContainer&, xAOD::JetContainer&, PseudoJetVector&) const = 0;
+
+  protected:
+  /// Handle Input JetContainer (this contains the parent ungroomed jets to be trimmed)
+  SG::ReadHandleKey<xAOD::JetContainer> m_inputJetContainer {this, "UngroomedJets", "ungroomedinput", "Input ungroomed jet container"};
 
-    // Handle Input PseudoJetContainer
-    // Needed to extract the constituents
-    SG::ReadHandleKey<PseudoJetContainer> m_inputPseudoJetsKey {this, "ParentPseudoJets", "", "Input constituents"};
+  /// This is the input to the parent JetContainer. It is needed in order to re-assign the ghost constituents from the final groomed PJ to the xAOD::Jet
+  SG::ReadHandleKey<PseudoJetContainer> m_inputPseudoJets {this, "ParentPseudoJets", "inputpseudojet", "input constituents of parent JetContainer"};
 
-    ToolHandle<IJetGroomer> m_groomer ={this , "Groomer" , {} , "Tool grooming the jets (trim, prune, softdrop etc)"};
+   SG::WriteHandleKey<PseudoJetVector> m_finalPseudoJets {this, "FinalPseudoJets_DONOTSET", "", "output pseudojets -- autoconfigured name"};
 
 };
 
diff --git a/Reconstruction/Jet/JetRec/JetRec/PseudoJetTranslator.h b/Reconstruction/Jet/JetRec/JetRec/PseudoJetTranslator.h
index 6053fd625d034a8709f3dd97407ee0b0517a6596..84cd8386558978265c2208b4f2ff98c3aa8a1d66 100644
--- a/Reconstruction/Jet/JetRec/JetRec/PseudoJetTranslator.h
+++ b/Reconstruction/Jet/JetRec/JetRec/PseudoJetTranslator.h
@@ -15,14 +15,14 @@ public:
 
   PseudoJetTranslator(bool saveArea, bool saveArea4Vec) : m_saveArea(saveArea), m_saveArea4Vec(saveArea4Vec) {}
   
-  xAOD::Jet * translate(const fastjet::PseudoJet& pj,
-			const PseudoJetContainer& pjCont,
-			xAOD::JetContainer& jetCont) const ;
+  xAOD::Jet& translate(const fastjet::PseudoJet& pj,
+		       const PseudoJetContainer& pjCont,
+		       xAOD::JetContainer& jetCont) const ;
 
-  xAOD::Jet * translate(const fastjet::PseudoJet& pj,
-			const PseudoJetContainer& pjCont,
-			xAOD::JetContainer& jetCont,
-			const xAOD::Jet &parent) const ;
+  xAOD::Jet& translate(const fastjet::PseudoJet& pj,
+		       const PseudoJetContainer& pjCont,
+		       xAOD::JetContainer& jetCont,
+		       const xAOD::Jet &parent) const ;
 
   
   
diff --git a/Reconstruction/Jet/JetRec/Root/JetClusterer.cxx b/Reconstruction/Jet/JetRec/Root/JetClusterer.cxx
index e7ac8847ef1a8fc1dd0eccac20c9ff6cdd604428..fba227864d178fa7510fbb259ad40682dfbd8ca8 100644
--- a/Reconstruction/Jet/JetRec/Root/JetClusterer.cxx
+++ b/Reconstruction/Jet/JetRec/Root/JetClusterer.cxx
@@ -14,7 +14,6 @@
 #include "xAODJet/JetAuxContainer.h"
 
 #include "JetEDM/FastJetUtils.h"
-#include "JetEDM/PseudoJetVector.h"
 
 #include "JetRec/PseudoJetTranslator.h"
 
@@ -25,15 +24,15 @@ namespace JetClustererHelper {
       //const xAOD::EventInfo* pevinfo = handle.cptr();
       auto ievt = ei->eventNumber();
       auto irun = ei->runNumber();
-      
+
       if ( ei->eventType(xAOD::EventInfo::IS_SIMULATION)) {
 	// For MC, use the channel and MC event number
 	ievt = ei->mcEventNumber();
 	irun = ei->mcChannelNumber();
-      }      
+      }
       seeds.push_back(ievt);
       seeds.push_back(irun);
-  }  
+  }
 }
 
 StatusCode JetClusterer::initialize() {
@@ -50,17 +49,22 @@ StatusCode JetClusterer::initialize() {
     ATH_MSG_ERROR("Invalid jet size parameter: " << m_jetrad);
     return StatusCode::FAILURE;
   }
-  
+
   // buld an empty ClusterSequence, just for the fastjet splash screen to appear during initialization (?)
   fastjet::JetDefinition jetdef(m_fjalg, m_jetrad);
   PseudoJetVector empty;
   fastjet::ClusterSequence cs(empty, jetdef);
   cs.inclusive_jets(m_ptmin);
-  
+
   // Input DataHandles
+  if( !m_finalPseudoJets.empty() ) {
+    ATH_MSG_WARNING("A non-empty value was found for the FinalPseudoJets WriteHandleKey -- this will be ignored!");
+  }
+
   ATH_CHECK( m_eventinfokey.initialize() );
   ATH_CHECK( m_inputPseudoJets.initialize() );
-  m_finalPseudoJets = m_inputPseudoJets.key() +"FinalPJ";
+  m_finalPseudoJets = name() + "FinalPJ";
+  ATH_CHECK( m_finalPseudoJets.initialize() );
 
   return StatusCode::SUCCESS;
 }
@@ -78,7 +82,7 @@ std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> >
     return nullreturn;
   }
 
-  // Build the container to be returned 
+  // Build the container to be returned
   // Avoid memory leaks with unique_ptr
   auto jets = std::make_unique<xAOD::JetContainer>();
   auto auxCont = std::make_unique<xAOD::JetAuxContainer>();
@@ -94,7 +98,7 @@ std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> >
   bool useArea = m_ghostarea <= 0 ;
   if ( useArea ) {
     ATH_MSG_DEBUG("Creating input cluster sequence");
-    clSequence = new fastjet::ClusterSequence(*pseudoJetVector, jetdef);    
+    clSequence = new fastjet::ClusterSequence(*pseudoJetVector, jetdef);
   } else {
     // Prepare ghost area specifications -------------
     ATH_MSG_DEBUG("Creating input area cluster sequence");
@@ -104,7 +108,7 @@ std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> >
     else {return nullreturn;}
   }
 
-  
+
   // -----------------------
   // Build a new pointer to a PseudoJetVector containing the final PseudoJet
   // This allows us to own the vector of PseudoJet which we will put in the evt store.
@@ -116,7 +120,7 @@ std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> >
       msg() << "  Pseudojet with pt " << std::setprecision(4) << pj.Et()*1e-3 << " has " << pj.constituents().size() << " constituents" << endmsg;
     }
   }
-  
+
   // Let fastjet deal with deletion of ClusterSequence, so we don't need to also put it in the EventStore.
   clSequence->delete_self_when_unused();
 
@@ -128,19 +132,19 @@ std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> >
   PseudoJetTranslator pjTranslator(useArea, useArea);
   for (const fastjet::PseudoJet &  pj: *pjVector ) {
     // create the xAOD::Jet from the PseudoJet, doing the signal & ghost constituents extraction
-    xAOD::Jet* jet = pjTranslator.translate(pj, *pjContHandle, *jets);
-    
+    xAOD::Jet& jet = pjTranslator.translate(pj, *pjContHandle, *jets);
+
     // Add the PseudoJet onto the xAOD jet. Maybe we should do it in the above JetFromPseudojet call ??
-    pjAccessor(*jet) = &pj;
+    pjAccessor(jet) = &pj;
 
-    jet->setInputType(  xAOD::JetInput::Type( (int) m_inputType) ) ;
+    jet.setInputType(  xAOD::JetInput::Type( (int) m_inputType) ) ;
     xAOD::JetAlgorithmType::ID ialg = xAOD::JetAlgorithmType::algId(m_fjalg);
-    jet->setAlgorithmType(ialg);
-    jet->setSizeParameter((float)m_jetrad);
-    if(useArea) jet->setAttribute(xAOD::JetAttribute::JetGhostArea, (float)m_ghostarea);
-    
-    ATH_MSG_VERBOSE( "  xAOD::Jet with pt " << std::setprecision(4) << jet->pt()*1e-3 << " has " << jet->getConstituents().size() << " constituents" );
-    ATH_MSG_VERBOSE( "  Leading constituent is of type " << jet->getConstituents()[0].rawConstituent()->type());
+    jet.setAlgorithmType(ialg);
+    jet.setSizeParameter((float)m_jetrad);
+    if(useArea) jet.setAttribute(xAOD::JetAttribute::JetGhostArea, (float)m_ghostarea);
+
+    ATH_MSG_VERBOSE( "  xAOD::Jet with pt " << std::setprecision(4) << jet.pt()*1e-3 << " has " << jet.getConstituents().size() << " constituents" );
+    ATH_MSG_VERBOSE( "  Leading constituent is of type " << jet.getConstituents()[0].rawConstituent()->type());
   }
 
   // -------------------------------------
@@ -163,9 +167,9 @@ fastjet::AreaDefinition JetClusterer::buildAreaDefinition(bool & seedsok) const
 
     fastjet::GhostedAreaSpec gspec(5.0, 1, m_ghostarea);
     seedsok = true;
-    
+
     if ( m_ranopt == 1 ) {
-      // Use run/event number as random number seeds.      
+      // Use run/event number as random number seeds.
       auto evtInfoHandle = SG::makeHandle(m_eventinfokey);
       if (!evtInfoHandle.isValid()){
         ATH_MSG_ERROR("Unable to retrieve event info");
@@ -178,7 +182,7 @@ fastjet::AreaDefinition JetClusterer::buildAreaDefinition(bool & seedsok) const
       gspec.set_random_status(inseeds);
     }
 
-    
+
     ATH_MSG_DEBUG("Active area specs:");
     ATH_MSG_DEBUG("  Requested ghost area: " << m_ghostarea);
     ATH_MSG_DEBUG("     Actual ghost area: " << gspec.actual_ghost_area());
diff --git a/Reconstruction/Jet/JetRec/Root/JetGroomer.cxx b/Reconstruction/Jet/JetRec/Root/JetGroomer.cxx
index 44aefcb547a5bd9e113ea5d13be5ddac2c67b8ab..65138a0b6222fda95d80f2f654a301bcaf3b9164 100644
--- a/Reconstruction/Jet/JetRec/Root/JetGroomer.cxx
+++ b/Reconstruction/Jet/JetRec/Root/JetGroomer.cxx
@@ -4,6 +4,7 @@
 
 #include "JetRec/JetGroomer.h"
 
+#include "fastjet/PseudoJet.hh"
 #include "JetRec/PseudoJetContainer.h"
 
 using xAOD::JetContainer;
@@ -12,47 +13,73 @@ StatusCode JetGroomer::initialize() {
 
   ATH_MSG_DEBUG("Initializing...");
 
- if(m_inputJetsKey.empty()){
+ if(m_inputJetContainer.empty()){
     ATH_MSG_ERROR("Jet grooming requested with no input ungroomed jets");
     return StatusCode::FAILURE;
-  } else if(m_inputPseudoJetsKey.empty()){
+  } else if(m_inputPseudoJets.empty()){
     ATH_MSG_ERROR("Jet grooming requested with no input pseudojets");
     return StatusCode::FAILURE;
   }
   else{
-    ATH_CHECK(m_inputJetsKey.initialize());
-    ATH_CHECK(m_inputPseudoJetsKey.initialize());
-    ATH_CHECK(m_groomer.retrieve());
+    if(!m_finalPseudoJets.empty()){
+      ATH_MSG_WARNING("A non-empty value was found for the FinalPseudoJets WriteHandleKey -- this will be ignored!");
+    }
+
+    ATH_CHECK(m_inputJetContainer.initialize());
+    ATH_CHECK(m_inputPseudoJets.initialize());
+    m_finalPseudoJets = name() + "FinalPJ";
+    ATH_CHECK(m_finalPseudoJets.initialize());
   }
 
   return StatusCode::SUCCESS;
 }
 
 
+// Common operations for any jet groomer
 std::pair<std::unique_ptr<xAOD::JetContainer>,std::unique_ptr<SG::IAuxStore> > JetGroomer::getJets() const {
+  // Return this in case of any problems
+  auto nullreturn = std::make_pair(std::unique_ptr<xAOD::JetContainer>(nullptr), std::unique_ptr<SG::IAuxStore>(nullptr));
 
+  // -----------------------
   // retrieve input
-  SG::ReadHandle<JetContainer> inputJets(m_inputJetsKey);
+  SG::ReadHandle<xAOD::JetContainer> jetContHandle(m_inputJetContainer);
+  if(!jetContHandle.isValid()) {
+    ATH_MSG_ERROR("No valid JetContainer with key "<< m_inputJetContainer.key());
+    return nullreturn;
+  }
 
-  if(inputJets.isValid()) {
-    ATH_MSG_DEBUG("Retrieval of ungroomed jets succeeded");
-  } else {
-    ATH_MSG_ERROR("Retrieval of ungroomed jets failed");
-    return std::make_pair(std::unique_ptr<xAOD::JetContainer>(nullptr),std::unique_ptr<SG::IAuxStore>(nullptr));
+  SG::ReadHandle<PseudoJetContainer> pjContHandle(m_inputPseudoJets);
+  if(!pjContHandle.isValid()) {
+    ATH_MSG_ERROR("No valid PseudoJetContainer with key "<< m_inputPseudoJets.key());
+    return nullreturn;
   }
 
-  ATH_MSG_DEBUG("Grooming jets");
-  // Create the output containers
-  // Make sure that memory is managed safely
-  auto outjets = std::make_unique<xAOD::JetContainer>();
-  auto outaux  = std::make_unique<xAOD::JetAuxContainer>();
-  outjets->setStore(outaux.get());
+  // Build the container to be returned
+  // Avoid memory leaks with unique_ptr
+  auto groomedJets = std::make_unique<xAOD::JetContainer>();
+  auto auxCont = std::make_unique<xAOD::JetAuxContainer>();
+  groomedJets->setStore(auxCont.get());
 
-  SG::ReadHandle<PseudoJetContainer> inputPseudoJets(m_inputPseudoJetsKey);
+  // -----------------------
+  // Build a new pointer to a PseudoJetVector containing the final groomed PseudoJets
+  // This allows us to own the vector of PseudoJet which we will put in the evt store.
+  // Thus the contained PseudoJet will be kept frozen there and we can safely use pointer to them from the xAOD::Jet objects
+  auto groomPJVector = std::make_unique<PseudoJetVector>( );
+  groomPJVector->resize( jetContHandle->size() );
+
+  // loop over input jets
+  for (const xAOD::Jet* parentJet: *jetContHandle){
+    // Child will create a groomed jet and insert it into the output container
+    this->insertGroomedJet(*parentJet, *pjContHandle, *groomedJets, *groomPJVector);
+  }
 
-  for (const xAOD::Jet* jet : *inputJets){
-    m_groomer->groom(*jet, *inputPseudoJets, *outjets);
+  // -------------------------------------
+  // record final PseudoJetVector
+  SG::WriteHandle<PseudoJetVector> pjVectorHandle(m_finalPseudoJets);
+  if(!pjVectorHandle.record(std::move(groomPJVector))){
+    ATH_MSG_ERROR("Can't record PseudoJetVector under key "<< m_finalPseudoJets);
+    return nullreturn;
   }
 
-  return std::make_pair(std::move(outjets),std::move(outaux));
+  return std::make_pair(std::move(groomedJets),std::move(auxCont));
 }
diff --git a/Reconstruction/Jet/JetRec/Root/JetTrimmer.cxx b/Reconstruction/Jet/JetRec/Root/JetTrimmer.cxx
index 507e04ecf793816c78453aade05f05810189d17c..5c52857d1e88f09c83153957663d9084b3d21e02 100644
--- a/Reconstruction/Jet/JetRec/Root/JetTrimmer.cxx
+++ b/Reconstruction/Jet/JetRec/Root/JetTrimmer.cxx
@@ -73,8 +73,8 @@ int JetTrimmer::groom(const xAOD::Jet& jin,
   // Add jet to collection.
   xAOD::Jet* pjet = m_bld->add(pjtrim, pjContainer, jets, &jin);
   pjet->setAttribute<int>("TransformType", xAOD::JetTransform::Trim);
-  pjet->setAttribute("RClus", m_rclus);
-  pjet->setAttribute("PtFrac", m_ptfrac);
+  pjet->setAttribute("RClus", float(m_rclus));
+  pjet->setAttribute("PtFrac", float(m_ptfrac));
   pjet->setAttribute<int>("NTrimSubjets", nptrim);
   ATH_MSG_DEBUG("Properties after trimming:");
   ATH_MSG_DEBUG("   ncon: " << pjtrim.constituents().size() << "/"
diff --git a/Reconstruction/Jet/JetRec/Root/PseudoJetTranslator.cxx b/Reconstruction/Jet/JetRec/Root/PseudoJetTranslator.cxx
index c194e9044adf4a0b8898c392c6514862d25952ed..d5ae49d2096e4c0845a69add3e71b138fc58114f 100644
--- a/Reconstruction/Jet/JetRec/Root/PseudoJetTranslator.cxx
+++ b/Reconstruction/Jet/JetRec/Root/PseudoJetTranslator.cxx
@@ -4,53 +4,54 @@
 #include "JetRec/PseudoJetTranslator.h"
 
 
-xAOD::Jet* PseudoJetTranslator::translate(const fastjet::PseudoJet& pj,
+xAOD::Jet& PseudoJetTranslator::translate(const fastjet::PseudoJet& pj,
 					  const PseudoJetContainer& pjCont,
 					  xAOD::JetContainer& jetCont) const {
 
-  xAOD::Jet* jet = new xAOD::Jet();
-  jetCont.push_back(jet);
-  jet->setJetP4( xAOD::JetFourMom_t( pj.pt(), pj.eta(), pj.phi(), pj.m() ) );
+  // Create a new jet in place at the end of the container
+  jetCont.emplace_back(new xAOD::Jet());
+  xAOD::Jet& jet = *jetCont.back();
+  jet.setJetP4( xAOD::JetFourMom_t( pj.pt(), pj.eta(), pj.phi(), pj.m() ) );
 
-  static SG::AuxElement::Accessor<const fastjet::PseudoJet*> pjAccessor("PseudoJet");
-  pjAccessor(*jet) = &pj;
+  const static SG::AuxElement::Accessor<const fastjet::PseudoJet*> pjAccessor("PseudoJet");
+  pjAccessor(jet) = &pj;
 
   // Record the jet-finding momentum, i.e. the one used to find/groom the jet.
-  jet->setJetP4(xAOD::JetConstitScaleMomentum, jet->jetP4());
+  jet.setJetP4(xAOD::JetConstitScaleMomentum, jet.jetP4());
 
   // save area if needed ---------
   if( pj.has_area() ){
 
-    if(m_saveArea) jet->setAttribute(xAOD::JetAttribute::ActiveArea,pj.area());
+    if(m_saveArea) jet.setAttribute(xAOD::JetAttribute::ActiveArea,pj.area());
     if(m_saveArea4Vec){
         fastjet::PseudoJet pja = pj.area_4vector();
         xAOD::JetFourMom_t fvarea(pja.pt(), pja.eta(), pja.phi(), pja.m());
-        jet->setAttribute(xAOD::JetAttribute::ActiveArea4vec, fvarea);      
+        jet.setAttribute(xAOD::JetAttribute::ActiveArea4vec, fvarea);      
     }    
   }// area -------------
   
-  pjCont.extractConstituents(*jet, pj);
+  pjCont.extractConstituents(jet, pj);
 
   return jet;
 }
 
-xAOD::Jet* PseudoJetTranslator::translate(const fastjet::PseudoJet& pj,
+xAOD::Jet& PseudoJetTranslator::translate(const fastjet::PseudoJet& pj,
 					  const PseudoJetContainer& pjCont,
 					  xAOD::JetContainer& jetCont,
 					  const xAOD::Jet &parent ) const {
-  xAOD::Jet * jet = translate(pj, pjCont, jetCont);
+  xAOD::Jet& jet = translate(pj, pjCont, jetCont);
 
   const xAOD::JetContainer* parentCont = dynamic_cast<const xAOD::JetContainer*>(parent.container());
   if ( parentCont == 0 ) { return jet ;}  // can this happen? if so THIS IS an ERROR ! should do something
 
   ElementLink<xAOD::JetContainer> el(*parentCont, parent.index());
-  jet->setAttribute("Parent", el);
+  jet.setAttribute("Parent", el);
 
-  jet->setInputType(parent.getInputType());
-  jet->setAlgorithmType(parent.getAlgorithmType());
-  jet->setSizeParameter(parent.getSizeParameter());
-  jet->setConstituentsSignalState(parent.getConstituentsSignalState());
-  jet->setAttribute(xAOD::JetAttribute::JetGhostArea, parent.getAttribute<float>(xAOD::JetAttribute::JetGhostArea));
+  jet.setInputType(parent.getInputType());
+  jet.setAlgorithmType(parent.getAlgorithmType());
+  jet.setSizeParameter(parent.getSizeParameter());
+  jet.setConstituentsSignalState(parent.getConstituentsSignalState());
+  jet.setAttribute(xAOD::JetAttribute::JetGhostArea, parent.getAttribute<float>(xAOD::JetAttribute::JetGhostArea));
 
   return jet;
 }
diff --git a/Reconstruction/Jet/JetRec/python/JetRecStandardToolManager.py b/Reconstruction/Jet/JetRec/python/JetRecStandardToolManager.py
index da2507bb949cb9274417ab0c288002493910b625..725707b5f7742a8b12442ae047ebdd4f288a3416 100644
--- a/Reconstruction/Jet/JetRec/python/JetRecStandardToolManager.py
+++ b/Reconstruction/Jet/JetRec/python/JetRecStandardToolManager.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # JetRecStandardToolManager.py
 #
@@ -249,6 +249,9 @@ pflow_groomed_modifiers = []
 pflow_groomed_modifiers += [jtm.constitfourmom_pflow]
 pflow_groomed_modifiers += groomed_modifiers
 
+# For truth jets, don't add track moments
+truth_groomed_modifiers = filterout(["trksummoms"], groomed_modifiers)
+
 # Here add tools to be run for topo jets and NOT for pflow.
 
 # Cluster moments.
@@ -324,6 +327,7 @@ jtm.modifiersMap["pflow_reduced"]         =        list(pflow_reduced_modifiers)
 
 if jetFlags.useTruth():
   jtm.modifiersMap["truth_ungroomed"]     =      list(truth_ungroomed_modifiers)
+  jtm.modifiersMap["truth_groomed"]       =      list(truth_groomed_modifiers)
 jtm.modifiersMap["track_ungroomed"]       =      list(track_ungroomed_modifiers)
 
 # Also index modifier type names by input type name.
diff --git a/Reconstruction/Jet/JetRec/share/JetRecAlgTestCfg.py b/Reconstruction/Jet/JetRec/share/JetRecAlgTestCfg.py
index ad9f2e7cc7553c5f160a5cc769766a10c38b25a0..9232884db3d359d1aeb11019c4c070e5eaff954c 100755
--- a/Reconstruction/Jet/JetRec/share/JetRecAlgTestCfg.py
+++ b/Reconstruction/Jet/JetRec/share/JetRecAlgTestCfg.py
@@ -32,8 +32,8 @@ ConfigFlags.lock()
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 
 # Get a ComponentAccumulator setting up the fundamental Athena job
-from AthenaConfiguration.MainServicesConfig import MainServicesCfg 
-cfg=MainServicesCfg(ConfigFlags) 
+from AthenaConfiguration.MainServicesConfig import MainServicesCfg
+cfg=MainServicesCfg(ConfigFlags)
 
 # Add the components for reading in pool files
 from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
@@ -120,7 +120,7 @@ def JetBuildAlgCfg(ConfigFlags,buildjetsname):
         "pjmergealg_"+buildjetsname,
         InputPJContainers = pjcs,
         OutputContainer = "PseudoJetMerged_"+buildjetsname)
-    
+
     buildcfg.addEventAlgo(mergepjalg)
 
     # Create the JetClusterer, set some standard options
@@ -162,15 +162,14 @@ def JetGroomAlgCfg(ConfigFlags,buildjetsname,groomjetsname):
 
     # Create the JetGroomer, provide it with a JetTrimmer
     jtrim = CompFactory.JetTrimming("trimSmallR2Frac5",RClus=0.2,PtFrac=0.05)
-    jtrim.InputJetContainer = buildjetsname
-    jtrim.InputPseudoJets = "PseudoJetMerged_"+buildjetsname
-    jtrim.TrimmedOutputPseudoJets = "PseudoJet"+groomjetsname
+    jtrim.UngroomedJets = buildjetsname
+    jtrim.ParentPseudoJets = "PseudoJetMerged_"+buildjetsname
 
     # Create the JetRecAlg, configure it to use the builder
     # using constructor syntax instead
     # (equivalent to setting properties with "=")
     jra = CompFactory.JetRecAlg(
-        "JRA_groom",
+        "JRA_trim",
         Provider = jtrim,       # Single ToolHandle
         Modifiers = [], # ToolHandleArray
         OutputContainer = groomjetsname)
diff --git a/Reconstruction/Jet/JetRec/src/JetTrimming.cxx b/Reconstruction/Jet/JetRec/src/JetTrimming.cxx
index 445674e9ffa5bb41b0eaa2e33b0cf4ad78c771b5..6379a4d8d0f6e41b49d2b966542f669eda932e13 100644
--- a/Reconstruction/Jet/JetRec/src/JetTrimming.cxx
+++ b/Reconstruction/Jet/JetRec/src/JetTrimming.cxx
@@ -7,124 +7,77 @@
 #include "fastjet/PseudoJet.hh"
 #include "fastjet/JetDefinition.hh"
 #include "fastjet/Selector.hh"
-#include "fastjet/tools/Filter.hh"
 #include "JetEDM/PseudoJetVector.h"
 
 #include "JetRec/PseudoJetTranslator.h"
 
 
-using fastjet::PseudoJet;
-using xAOD::JetContainer;
-
-
+  // tool implementing the operations to convert fastjet::PseudoJet -> xAOD::Jet
+const static PseudoJetTranslator s_pjTranslator(false, false); // false => do not save jet areas
 
 //**********************************************************************
 
 StatusCode JetTrimming::initialize() {
+  ATH_CHECK( JetGroomer::initialize() );
+
+  // Unfortunately not possible to do this because there is no
+  // declareProperty overload for CheckedProperty in AsgTool
+  //
+  // Enforce upper/lower limits of Gaudi::Properties
+  // m_rclus.verifier().setBounds(0.,10.);
+  // m_ptfrac.verifier().setBounds(0.,1.);
   if ( m_rclus < 0.0 || m_rclus > 10.0 ) {
-    ATH_MSG_ERROR("Invalid value for RClus " << m_rclus);
+    ATH_MSG_ERROR("Invalid value " << m_rclus << "for RClus. Allowable range is 0-10");
     return StatusCode::FAILURE;
   }
   if ( m_ptfrac < 0.0 || m_ptfrac > 1.0 ) {
-    ATH_MSG_ERROR("Invalid value for PtFrac " << m_ptfrac);
+    ATH_MSG_ERROR("Invalid value " << m_ptfrac << "for PtFrac. Allowable range is 0-1");
     return StatusCode::FAILURE;
   }
 
-  ATH_CHECK( m_inputPseudoJets.initialize() );
-  ATH_CHECK( m_inputJetContainer.initialize() );
+  // Define the trimmer
+  m_trimmer = std::make_unique<fastjet::Filter>(fastjet::JetDefinition(fastjet::kt_algorithm, m_rclus),
+						fastjet::SelectorPtFractionMin(m_ptfrac));
 
   ATH_MSG_INFO("     Recluster R: " << m_rclus);
   ATH_MSG_INFO("  pT faction min: " << m_ptfrac);
+
   return StatusCode::SUCCESS;
 }
 
 
 //**********************************************************************
-std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> > JetTrimming::getJets() const {
-  // Return this in case of any problems
-  auto nullreturn = std::make_pair(std::unique_ptr<xAOD::JetContainer>(nullptr), std::unique_ptr<SG::IAuxStore>(nullptr));
-
-  // -----------------------
-  // retrieve input
-  SG::ReadHandle<xAOD::JetContainer> jetContHandle(m_inputJetContainer);
-  if(!jetContHandle.isValid()) {
-    ATH_MSG_ERROR("No valid JetContainer with key "<< m_inputJetContainer.key());
-    return nullreturn;
-  }
-
-  SG::ReadHandle<PseudoJetContainer> pjContHandle(m_inputPseudoJets);
-  if(!pjContHandle.isValid()) {
-    ATH_MSG_ERROR("No valid PseudoJetContainer with key "<< m_inputPseudoJets.key());
-    return nullreturn;
-  }
-
-  // Build the container to be returned 
-  // Avoid memory leaks with unique_ptr
-  auto trimmedJets = std::make_unique<xAOD::JetContainer>();
-  auto auxCont = std::make_unique<xAOD::JetAuxContainer>();
-  trimmedJets->setStore(auxCont.get());
-
-
-  // The trimmer 
-  fastjet::Filter trimmer(fastjet::JetDefinition(fastjet::kt_algorithm, m_rclus),
-                          fastjet::SelectorPtFractionMin(m_ptfrac));
-
-  // tool implementing the operations to convert fastjet::PseudoJet -> xAOD::Jet
-  PseudoJetTranslator pjTranslator(false, false); // false => do not save jet areas
-
-  // -----------------------
-  // Build a new pointer to a PseudoJetVector containing the final trimmed PseudoJets
-  // This allows us to own the vector of PseudoJet which we will put in the evt store.
-  // Thus the contained PseudoJet will be kept frozen there and we can safely use pointer to them from the xAOD::Jet objects
-  auto trimPJVector = std::make_unique<PseudoJetVector>( );
-  trimPJVector->resize( jetContHandle->size() );
-  // Accessors to retrieve and set the pointers to PseudoJet 
-  static SG::AuxElement::ConstAccessor<const fastjet::PseudoJet*> pjConstAcc("PseudoJet");
-  static SG::AuxElement::Accessor<const fastjet::PseudoJet*> pjAcc("PseudoJet");
-
-
-  // loop over input jets
-  int count = 0;
-  for (const xAOD::Jet* parentJet: *jetContHandle){
-    // retrieve the PseudoJet from the parent :
-    const PseudoJet * parentPJ = pjConstAcc(*parentJet);
-    
-    // Trim :
-    PseudoJet trimmedPJ = trimmer(*parentPJ) ;
-    (*trimPJVector)[count] = trimmedPJ; // save a *copy* of this trimmed PJ
-    
-    ATH_MSG_VERBOSE("   Input cluster sequence: " << parentPJ->associated_cluster_sequence());
-    ATH_MSG_VERBOSE(" Trimmed cluster sequence: " << trimmedPJ.associated_cluster_sequence());
-
-    // build the xAOD::Jet from the PseudoJet, and put it in the container
-    xAOD::Jet* jet = pjTranslator.translate(trimmedPJ, *pjContHandle, *trimmedJets, *parentJet);
-
-    // decorate with the pointer to the PJ we keep in the evt store. 
-    pjAcc(*jet) = & (*trimPJVector)[count] ; 
-    
-    int nptrim = trimmedPJ.pieces().size();
-    jet->setAttribute<int>(xAOD::JetAttribute::TransformType, xAOD::JetTransform::Trim);
-    jet->setAttribute<int>(xAOD::JetAttribute::NTrimSubjets, nptrim);
-    // Need to convert from GaudiProperty
-    jet->setAttribute(xAOD::JetAttribute::RClus, float(m_rclus));
-    jet->setAttribute(xAOD::JetAttribute::PtFrac, float(m_ptfrac));
-    ATH_MSG_DEBUG("Properties after trimming:");
-    ATH_MSG_DEBUG("   ncon: " << trimmedPJ.constituents().size() << "/"
-		  << parentPJ->constituents().size());
-    ATH_MSG_DEBUG("   nsub: " << nptrim);
-    count++;
-  }
-
-  // -------------------------------------
-  // record final PseudoJetVector
-  SG::WriteHandle<PseudoJetVector> pjVectorHandle(m_finalPseudoJets);
-  if(!pjVectorHandle.record(std::move(trimPJVector))){
-    ATH_MSG_ERROR("Can't record PseudoJetVector under key "<< m_finalPseudoJets);
-    return nullreturn;
-  }
-  
-  // Return the jet container and aux, use move to transfer
-  // ownership of pointers to caller
-  return std::make_pair(std::move(trimmedJets), std::move(auxCont));
 
+void JetTrimming::insertGroomedJet(const xAOD::Jet& parentjet, const PseudoJetContainer& inpjcont, xAOD::JetContainer& outcont, PseudoJetVector& trimpjvec) const {
+
+  const static SG::AuxElement::Accessor<const fastjet::PseudoJet*> s_pjAcc("PseudoJet");
+  const static SG::AuxElement::ConstAccessor<const fastjet::PseudoJet*> s_pjConstAcc("PseudoJet");
+
+  // retrieve the PseudoJet from the parent :
+  const fastjet::PseudoJet& parentPJ = *s_pjConstAcc(parentjet);
+
+  // Trim :
+  fastjet::PseudoJet trimmedPJ = m_trimmer->result(parentPJ) ;
+  ATH_MSG_VERBOSE("   Input cluster sequence: " << parentPJ.associated_cluster_sequence());
+  ATH_MSG_VERBOSE(" Trimmed cluster sequence: " << trimmedPJ.associated_cluster_sequence());
+
+  // build the xAOD::Jet from the PseudoJet, and put it in the container
+  xAOD::Jet& jet = s_pjTranslator.translate(trimmedPJ, inpjcont, outcont, parentjet);
+  // The vector is resized externally to match the jet container size,
+  // so just fill the corresponding entry
+  trimpjvec[jet.index()] = trimmedPJ; // save a *copy* of this trimmed PJ
+
+  // decorate with the pointer to the PJ we keep in the evt store.
+  s_pjAcc(jet) = & trimpjvec[jet.index()];
+
+  int nptrim = trimmedPJ.pieces().size();
+  jet.setAttribute<int>(xAOD::JetAttribute::TransformType, xAOD::JetTransform::Trim);
+  jet.setAttribute<int>(xAOD::JetAttribute::NTrimSubjets, nptrim);
+  // Need to convert from GaudiProperty
+  jet.setAttribute(xAOD::JetAttribute::RClus, float(m_rclus));
+  jet.setAttribute(xAOD::JetAttribute::PtFrac, float(m_ptfrac));
+  ATH_MSG_VERBOSE("Properties after trimming:");
+  ATH_MSG_VERBOSE("   ncon: " << trimmedPJ.constituents().size() << "/"
+		  << parentPJ.constituents().size());
+  ATH_MSG_VERBOSE("   nsub: " << nptrim);
 }
diff --git a/Reconstruction/Jet/JetRec/src/JetTrimming.h b/Reconstruction/Jet/JetRec/src/JetTrimming.h
index faa7d192ac173db6b800ade3607c9b25ed5701fe..4302969abe17fc70af7f247b3efafc6493f26855 100644
--- a/Reconstruction/Jet/JetRec/src/JetTrimming.h
+++ b/Reconstruction/Jet/JetRec/src/JetTrimming.h
@@ -15,47 +15,35 @@
 /// running the trimming procedure on each jet of the parent JetContainer the tool is acting on.
 /// Obviously the parent JetContainer must be present in the evt store, but also the input PseudoJetContainer from which it has been built.
 
-#include "xAODEventInfo/EventInfo.h"
-#include "StoreGate/ReadHandleKey.h"
-#include "xAODJet/JetAuxContainer.h"
+#include "fastjet/PseudoJet.hh"
+#include "fastjet/tools/Filter.hh"
 
-#include "JetInterface/IJetProvider.h"
-#include "AsgTools/AsgTool.h"
+#include "xAODJet/JetContainer.h"
 
+#include "JetInterface/IJetProvider.h"
+#include "JetRec/JetGroomer.h"
 #include "JetRec/PseudoJetContainer.h"
 
-
 class JetTrimming
-: public asg::AsgTool,
-  virtual public JetProvider<xAOD::JetAuxContainer> {
+: virtual public JetGroomer {
   ASG_TOOL_CLASS(JetTrimming, IJetProvider)
 
 public:
 
-  using asg::AsgTool::AsgTool;
+  using JetGroomer::JetGroomer;
 
-  StatusCode initialize() override;
+  StatusCode initialize() override final;
 
-  /// Return the final jets with their aux store.
-  /// Can return a pair of null pointers if an error occurs.
-  std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore> > getJets() const override;
+  virtual void insertGroomedJet(const xAOD::Jet&, const PseudoJetContainer&, xAOD::JetContainer&, PseudoJetVector&) const override final;
 
+private:
 
-protected:
+  // The filter object that will apply the grooming
+  std::unique_ptr<fastjet::Filter> m_trimmer;
     
-
-  /// Handle Input JetContainer (this contains the parent ungroomed jets to be trimmed) 
-  SG::ReadHandleKey<xAOD::JetContainer> m_inputJetContainer {this, "InputJetContainer", "ungroomedinput", "Input ungroomed jet container"};
-
-  /// This is the input to the parent JetContainer. It is needed in order to re-assign the ghost constituents from the final trimmed PJ to the xAOD::Jet
-  SG::ReadHandleKey<PseudoJetContainer> m_inputPseudoJets {this, "InputPseudoJets", "inputpseudojet", "input constituents of parent JetContainer"};
-  
-  
   // Job options.
   Gaudi::Property<float> m_rclus        {this, "RClus", 0.3 , "R for reclustering (0 for none)"}; 
   Gaudi::Property<float> m_ptfrac       {this, "PtFrac", 0.03, "pT fraction for retaining subjets"};
-  Gaudi::Property<std::string> m_finalPseudoJets       {this, "TrimmedOutputPseudoJets", "undef", "Key to save the final trimmed pj. Necessary in order to ensure a valid PJ can be linked from xAOD::Jet"};
-  
   
 };
 
diff --git a/Reconstruction/Jet/JetRec/src/components/JetRec_entries.cxx b/Reconstruction/Jet/JetRec/src/components/JetRec_entries.cxx
index 87ea18b902ceac02071a4eaa10fbbc5250129603..bc1988eef2711cb477c5cedbee0cf4f921bb7184 100644
--- a/Reconstruction/Jet/JetRec/src/components/JetRec_entries.cxx
+++ b/Reconstruction/Jet/JetRec/src/components/JetRec_entries.cxx
@@ -27,7 +27,6 @@
 #include "JetRec/JetConstitRemover.h"
 #include "JetRec/JetClusterer.h"
 #include "JetRec/JetCopier.h"
-#include "JetRec/JetGroomer.h"
 
 DECLARE_COMPONENT( JetToolRunner )
 DECLARE_COMPONENT( JetRecTool )
@@ -48,7 +47,6 @@ DECLARE_COMPONENT( JetPseudojetCopier )
 DECLARE_COMPONENT( JetConstitRemover )
 DECLARE_COMPONENT( JetClusterer )
 DECLARE_COMPONENT( JetCopier )
-DECLARE_COMPONENT( JetGroomer )
 DECLARE_COMPONENT( PseudoJetMerger )
 
 DECLARE_COMPONENT( JetAlgorithm )
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedRatiosTool.h b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedRatiosTool.h
index 8f65864f88a0841eb355341f439a20aff687caef..9fd0c235caf7820084799b5021cb79dc6148640b 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedRatiosTool.h
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedRatiosTool.h
@@ -27,7 +27,8 @@ class EnergyCorrelatorGeneralizedRatiosTool :
     ASG_TOOL_CLASS(EnergyCorrelatorGeneralizedRatiosTool, IJetModifier)
     
     public:
-      // Constructor and destructor
+      
+      /// Constructor
       EnergyCorrelatorGeneralizedRatiosTool(std::string name);
 
       virtual StatusCode initialize() override;
@@ -35,12 +36,106 @@ class EnergyCorrelatorGeneralizedRatiosTool :
       int modifyJet(xAOD::Jet &jet) const override;
 
     private:
+
+      /// ECFG ratio moments structure
+      struct moments_t;
+      
+      /// Configurable as properties
+      bool m_doM3;
       bool m_doN3;
       bool m_doLSeries;
       std::vector<float> m_rawBetaVals; /// Vector of input values before cleaning
-      std::vector<float> m_betaVals; /// Local vector for cleaned up inputs
       bool m_doDichroic;
 
+      /// Map of moment accessors and decorators using beta as the key
+      std::map< float, moments_t > m_moments;
+
+      /// ConstAccessors for L-series ECFs
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_2_1_2;
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_3_1_1;
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_3_2_1;
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_3_2_2;
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_3_3_1;
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_4_2_2;
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_4_4_1;
+      
+      /// Decorator for L-series ECFRs
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_L1;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_L2;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_L3;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_L4;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_L5;
+
+};
+
+/**
+ * --------------------------------------------------------------------------------
+ * Structure to hold all of the necessary moment information for a single set of
+ * EnergyCorrelatorGeneralized ratio calculations. This includes the prefix and 
+ * suffix, beta, and the necessary accessors and decorators.
+ * --------------------------------------------------------------------------------
+ **/
+
+struct EnergyCorrelatorGeneralizedRatiosTool::moments_t {
+
+  /// Prefix for decorations
+  std::string prefix;
+
+  /// Suffix for decorations
+  std::string suffix;
+
+  /// Beta value for calculations
+  float beta;
+
+  /// ECFG accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_2_1;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_3_1;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_3_2;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_4_1;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_4_2;
+
+  /// ECFG ungroomed accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_2_1_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_3_1_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_3_2_ungroomed;
+  
+  /// M and N series decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_M2;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_M3;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_N2;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_N3;
+
+  /// Dichroic M and N series decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_M2_dichroic;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_N2_dichroic;
+
+  moments_t (float Beta, std::string Prefix) {
+
+    prefix = Prefix;
+    beta = Beta;
+
+    suffix = GetBetaSuffix(beta);
+
+    acc_ECFG_2_1 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_2_1"+suffix);
+    acc_ECFG_3_1 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_3_1"+suffix);
+    acc_ECFG_3_2 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_3_2"+suffix);
+    acc_ECFG_4_1 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_4_1"+suffix);
+    acc_ECFG_4_2 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_4_2"+suffix);
+
+    acc_ECFG_2_1_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_2_1_ungroomed"+suffix);
+    acc_ECFG_3_1_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_3_1_ungroomed"+suffix);
+    acc_ECFG_3_2_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_3_2_ungroomed"+suffix);
+    
+    dec_M2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"M2"+suffix);
+    dec_M3 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"M3"+suffix);
+    dec_N2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"N2"+suffix);
+    dec_N3 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"N3"+suffix);
+    
+    dec_M2_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"M2_dichroic"+suffix);
+    dec_N2_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"N2_dichroic"+suffix);
+
+  }
+
 };
 
 #endif
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedTool.h b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedTool.h
index 7f4169048884d3e0a80eb634c4550bc1a2207949..c997afcbc51b53c5700b1065f36bbf412ebaf1dd 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedTool.h
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedTool.h
@@ -25,9 +25,10 @@
 class EnergyCorrelatorGeneralizedTool :
   public JetSubStructureMomentToolsBase {
     ASG_TOOL_CLASS(EnergyCorrelatorGeneralizedTool, IJetModifier)
-    
+
     public:
-      // Constructor and destructor
+
+      /// Constructor
       EnergyCorrelatorGeneralizedTool(std::string name);
 
       virtual StatusCode initialize() override;
@@ -35,13 +36,82 @@ class EnergyCorrelatorGeneralizedTool :
       int modifyJet(xAOD::Jet &injet) const override;
 
     private:
+
+      /// ECFG moments structure
+      struct moments_t;
+
+      /// Configurable as properties
       float m_Beta;
+      bool m_doM3;
       bool m_doN3;
       bool m_doLSeries;
       std::vector<float> m_rawBetaVals; /// Vector of input values before cleaning
-      std::vector<float> m_betaVals; /// Local vector for cleaned up inputs
       bool m_doDichroic;
 
+      /// Map of moment decorators using beta as the key
+      std::map< float, moments_t > m_moments;
+
+      /// Decorators for L-series ECFs
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_2_1_2;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_3_1_1;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_3_2_1;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_3_2_2;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_3_3_1;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_4_2_2;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_4_4_1;
+
+  };
+
+/**
+ * --------------------------------------------------------------------------------
+ * Structure to hold all of the necessary moment information for a single set of 
+ * EnergyCorrelatorGeneralized calculations. This includes the prefix and suffix, 
+ * beta, and the necessary decorators.
+ * --------------------------------------------------------------------------------
+ **/
+
+struct EnergyCorrelatorGeneralizedTool::moments_t {
+
+  /// Prefix for decorations
+  std::string prefix;
+
+  /// Suffix for decorations
+  std::string suffix;
+
+  /// Beta value for calculations
+  float beta;
+
+  /// ECFG decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_2_1;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_3_1;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_3_2;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_4_1;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_4_2;
+  
+  /// ECFG ungroomed decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_2_1_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_3_1_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_3_2_ungroomed;
+  
+  moments_t (float Beta, std::string Prefix) {
+
+    prefix = Prefix;
+    beta = Beta;
+
+    suffix = GetBetaSuffix(beta);
+
+    dec_ECFG_2_1 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_2_1"+suffix);
+    dec_ECFG_3_1 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_3_1"+suffix);
+    dec_ECFG_3_2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_3_2"+suffix);
+    dec_ECFG_4_1 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_4_1"+suffix);
+    dec_ECFG_4_2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_4_2"+suffix);
+    
+    dec_ECFG_2_1_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_2_1_ungroomed"+suffix);
+    dec_ECFG_3_1_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_3_1_ungroomed"+suffix);
+    dec_ECFG_3_2_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_3_2_ungroomed"+suffix);
+
+  }
+
 };
 
 #endif
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorRatiosTool.h b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorRatiosTool.h
index 6148b1e3210488420183ea10934258d3b155002a..3ec8f99a473156b02e79627620f78d65ed7b138f 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorRatiosTool.h
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorRatiosTool.h
@@ -25,9 +25,10 @@
 class EnergyCorrelatorRatiosTool :
   public JetSubStructureMomentToolsBase {
     ASG_TOOL_CLASS(EnergyCorrelatorRatiosTool, IJetModifier)
-    
+
     public:
-      // Constructor and destructor
+
+      /// Constructor
       EnergyCorrelatorRatiosTool(std::string name);
      
       virtual StatusCode initialize() override;
@@ -35,12 +36,89 @@ class EnergyCorrelatorRatiosTool :
       int modifyJet(xAOD::Jet &jet) const override;
 
     private:
+
+      /// ECF ratio moments structure
+      struct moments_t;
+
+      /// Configurable as properties
       bool m_doC3;
       bool m_doC4;
       std::vector<float> m_rawBetaVals; /// Vector of input values before cleaning
-      std::vector<float> m_betaVals; /// Local vector for cleaned up inputs
       bool m_doDichroic;
 
+      /// Map of moment accessors and decorators using beta as the key
+      std::map< float, moments_t > m_moments;
+
+  };
+
+/**
+ * --------------------------------------------------------------------------------
+ * Structure to hold all of the necessary moment information for a single set of
+ * EnergyCorrelator ratio calculations. This includes the prefix and suffix, beta,
+ * and the necessary accessors and decorators.
+ * --------------------------------------------------------------------------------
+ **/
+
+struct EnergyCorrelatorRatiosTool::moments_t {
+
+  /// Prefix for decorations
+  std::string prefix;
+
+  /// Suffix for decorations
+  std::string suffix;
+
+  /// Beta value for calculations
+  float beta;
+
+  /// ECF accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF1;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF2;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF3;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF4;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF5;
+
+  /// ECF ungroomed accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF1_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF2_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF3_ungroomed;
+
+  /// C and D series decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_C1;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_C2;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_C3;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_C4;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_D2;
+
+  /// Dichroic C and D series decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_D2_dichroic;
+
+  moments_t (float Beta, std::string Prefix) {
+
+    prefix = Prefix;
+    beta = Beta;
+
+    suffix = GetBetaSuffix(beta);
+
+    acc_ECF1 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF1"+suffix);
+    acc_ECF2 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF2"+suffix);
+    acc_ECF3 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF3"+suffix);
+    acc_ECF4 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF4"+suffix);
+    acc_ECF5 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF5"+suffix);
+
+    acc_ECF1_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF1_ungroomed"+suffix);
+    acc_ECF2_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF2_ungroomed"+suffix);
+    acc_ECF3_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF3_ungroomed"+suffix);
+
+    dec_C1 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"C1"+suffix);
+    dec_C2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"C2"+suffix);
+    dec_C3 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"C3"+suffix);
+    dec_C4 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"C4"+suffix);
+    dec_D2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"D2"+suffix);
+
+    dec_D2_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"D2_dichroic"+suffix);
+
+  }
+
 };
 
 #endif
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorTool.h b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorTool.h
index 10653bc77b8ebad5da5a280dc663e4fbf6fb0682..66159e793a8d773e42c672c7c64ebf4785013219 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorTool.h
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorTool.h
@@ -25,9 +25,10 @@
 class EnergyCorrelatorTool :
   public JetSubStructureMomentToolsBase {
     ASG_TOOL_CLASS(EnergyCorrelatorTool, IJetModifier)
-    
+
     public:
-      // Constructor and destructor
+      
+      /// Constructor
       EnergyCorrelatorTool(std::string name);
      
       virtual StatusCode initialize() override;
@@ -35,12 +36,71 @@ class EnergyCorrelatorTool :
       int modifyJet(xAOD::Jet &injet) const override;
 
     private:
+
+      /// ECF moments structure
+      struct moments_t;
+
+      /// Configurable as properties
       float m_Beta;
       bool m_doC3;
       bool m_doC4;
       std::vector<float> m_rawBetaVals; /// Vector of input values before cleaning
-      std::vector<float> m_betaVals; /// Local vector for cleaned up inputs
       bool m_doDichroic;
+      
+      /// Map of moment calculators and decorators using beta as the key
+      std::map< float, moments_t > m_moments;
+
+  };
+
+/**
+ * --------------------------------------------------------------------------------
+ * Structure to hold all of the necessary moment information for a single set of
+ * EnergyCorrelator calculations. This includes the prefix and suffix, beta, and
+ * the necessary decorators.
+ * --------------------------------------------------------------------------------
+ **/
+
+struct EnergyCorrelatorTool::moments_t {
+
+  /// Prefix for decorations
+  std::string prefix;
+
+  /// Suffix for decorations
+  std::string suffix;
+
+  /// Beta value for calculations
+  float beta;
+
+  /// ECF decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF1;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF2;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF3;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF4;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF5;
+
+  /// ECF ungroomed decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF1_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF2_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF3_ungroomed;
+
+  moments_t (float Beta, std::string Prefix) {
+
+    prefix = Prefix;
+    beta = Beta;
+
+    suffix = GetBetaSuffix(beta);
+
+    dec_ECF1 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF1"+suffix);
+    dec_ECF2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF2"+suffix);
+    dec_ECF3 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF3"+suffix);
+    dec_ECF4 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF4"+suffix);
+    dec_ECF5 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF5"+suffix);
+
+    dec_ECF1_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF1_ungroomed"+suffix);
+    dec_ECF2_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF2_ungroomed"+suffix);
+    dec_ECF3_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF3_ungroomed"+suffix);
+
+  }
 
 };
 
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessRatiosTool.h b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessRatiosTool.h
index 49bdf099de909ee959fb9be9888c10cb7fc33a1c..8262e7c0f7949d075a34a967ca49b28d509c69f3 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessRatiosTool.h
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessRatiosTool.h
@@ -27,7 +27,8 @@ class NSubjettinessRatiosTool :
     ASG_TOOL_CLASS(NSubjettinessRatiosTool, IJetModifier)
 
     public:
-      // Constructor and destructor
+
+      /// Constructor
       NSubjettinessRatiosTool(std::string name);
 
       StatusCode initialize();
@@ -35,9 +36,123 @@ class NSubjettinessRatiosTool :
       int modifyJet(xAOD::Jet &jet) const;
 
     private:
+
+      /// N-subjettiness ratio moments structure
+      struct moments_t;
+
+      /// Configurable as properties
       std::vector<float> m_rawAlphaVals; /// Vector of input values before cleaning
-      std::vector<float> m_alphaVals; /// Local vector for cleaned up inputs
       bool m_doDichroic;
+  
+      /// Map of moment accessors and decorators using alpha as the key
+      std::map< float, moments_t > m_moments;
+
+  };
+
+/**
+ * --------------------------------------------------------------------------------
+ * Structure to hold all of the necessary moment information for a single set of
+ * NSubjettiness ratio calculations. This includes the prefix and suffix, alpha, 
+ * and the necessary accessors and decorators.
+ * --------------------------------------------------------------------------------
+ **/
+
+struct NSubjettinessRatiosTool::moments_t {
+
+  /// Prefix for decorations
+  std::string prefix;
+
+  /// Suffix for decorations
+  std::string suffix;
+
+  /// Beta value for calculations
+  float alpha;
+
+  /// NSubjettiness accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau1;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau2;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau3;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau4;
+
+  /// NSubjettiness ungroomed accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau2_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau3_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau4_ungroomed;
+
+  /// WTA NSubjettiness accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau1_wta;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau2_wta;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau3_wta;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau4_wta;
+
+  /// WTA NSubjettiness ungroomed accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau2_wta_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau3_wta_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau4_wta_ungroomed;
+
+  /// NSubjettiness Ratios decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau21;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau32;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau42;
+
+  /// Dichroic NSubjettiness Ratios decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau21_dichroic;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau32_dichroic;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau42_dichroic;
+
+  /// WTA NSubjettiness Ratios decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau21_wta;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau32_wta;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau42_wta;
+
+  /// WTA Dichroic NSubjettiness Ratios decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau21_wta_dichroic;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau32_wta_dichroic;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau42_wta_dichroic;
+
+  moments_t (float Alpha, std::string Prefix) {
+
+    prefix = Prefix;
+    alpha = Alpha;
+
+    suffix = GetAlphaSuffix(alpha);
+
+    acc_Tau1 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau1"+suffix);
+    acc_Tau2 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau2"+suffix);
+    acc_Tau3 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau3"+suffix);
+    acc_Tau4 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau4"+suffix);
+
+    acc_Tau2_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau2_ungroomed"+suffix);
+    acc_Tau3_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau3_ungroomed"+suffix);
+    acc_Tau4_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau4_ungroomed"+suffix);
+
+    acc_Tau1_wta = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau1_wta"+suffix);
+    acc_Tau2_wta = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau2_wta"+suffix);
+    acc_Tau3_wta = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau3_wta"+suffix);
+    acc_Tau4_wta = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau4_wta"+suffix);
+
+    acc_Tau2_wta_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau2_wta_ungroomed"+suffix);
+    acc_Tau3_wta_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau3_wta_ungroomed"+suffix);
+    acc_Tau4_wta_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau4_wta_ungroomed"+suffix);
+
+    dec_Tau21 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau21"+suffix);
+    dec_Tau32 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau32"+suffix);
+    dec_Tau42 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau42"+suffix);
+
+    dec_Tau21_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau21_dichroic"+suffix);
+    dec_Tau32_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau32_dichroic"+suffix);
+    dec_Tau42_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau42_dichroic"+suffix);
+
+    dec_Tau21_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau21_wta"+suffix);
+    dec_Tau32_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau32_wta"+suffix);
+    dec_Tau42_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau42_wta"+suffix);
+
+    dec_Tau21_wta_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau21_wta_dichroic"+suffix);
+    dec_Tau32_wta_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau32_wta_dichroic"+suffix);
+    dec_Tau42_wta_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau42_wta_dichroic"+suffix);
+
+  }
+
 };
 
 #endif
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessTool.h b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessTool.h
index df9087ef86d7945db1d0509105e7311d6db66960..500b645d794a9d6f568ee7728b68aab4dff3a81a 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessTool.h
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessTool.h
@@ -35,11 +35,85 @@ class NSubjettinessTool :
       int modifyJet(xAOD::Jet &injet) const;
 
     private:
+
+      /// N-subjettiness moments structure
+      struct moments_t;
+
+      /// Configurable as properties
       float m_Alpha;
       std::vector<float> m_rawAlphaVals; /// Vector of input values before cleaning
-      std::vector<float> m_alphaVals; /// Local vector for cleaned up inputs
       bool m_doDichroic;
-      
+
+      /// Map of decorators using alpha as the key
+      std::map< float, moments_t > m_moments;
+
+  };
+
+/**
+ * --------------------------------------------------------------------------------
+ * Structure to hold all of the necessary moment information for a single set of
+ * NSubjettiness calculations. This includes the prefix and suffix, alpha, and the
+ * necessary decorators.
+ * --------------------------------------------------------------------------------
+ **/
+
+struct NSubjettinessTool::moments_t {
+
+  /// Prefix for decorations
+  std::string prefix;
+
+  /// Alpha value for calculations
+  float alpha;
+
+  /// NSubjettiness decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau1;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau2;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau3;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau4;
+
+  /// NSubjettiness ungroomed decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau2_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau3_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau4_ungroomed;
+
+  /// WTA NSubjettiness decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau1_wta;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau2_wta;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau3_wta;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau4_wta;
+
+  /// WTA NSubjettiness ungroomed decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau2_wta_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau3_wta_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau4_wta_ungroomed;
+
+  moments_t (float Alpha, std::string Prefix) {
+
+    prefix = Prefix;
+    alpha = Alpha;
+
+    std::string suffix = GetAlphaSuffix(alpha);
+
+    dec_Tau1 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau1"+suffix);
+    dec_Tau2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau2"+suffix);
+    dec_Tau3 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau3"+suffix);
+    dec_Tau4 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau4"+suffix);
+
+    dec_Tau2_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau2_ungroomed"+suffix);
+    dec_Tau3_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau3_ungroomed"+suffix);
+    dec_Tau4_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau4_ungroomed"+suffix);
+
+    dec_Tau1_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau1_wta"+suffix);
+    dec_Tau2_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau2_wta"+suffix);
+    dec_Tau3_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau3_wta"+suffix);
+    dec_Tau4_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau4_wta"+suffix);
+
+    dec_Tau2_wta_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau2_wta_ungroomed"+suffix);
+    dec_Tau3_wta_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau3_wta_ungroomed"+suffix);
+    dec_Tau4_wta_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau4_wta_ungroomed"+suffix);
+
+  }
+
 };
 
 #endif
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedRatiosTool.cxx b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedRatiosTool.cxx
index c0438a37449a499a5a27698c1254d51fec292d3d..ac2ade3f53e2b8225ac15c3afb1f8d3fc16393e7 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedRatiosTool.cxx
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedRatiosTool.cxx
@@ -8,214 +8,261 @@
 EnergyCorrelatorGeneralizedRatiosTool::EnergyCorrelatorGeneralizedRatiosTool(std::string name) : 
   JetSubStructureMomentToolsBase(name)
 {
-  declareProperty("BetaList", m_rawBetaVals = {});
-  declareProperty("DoN3", m_doN3 = false);
-  declareProperty("DoLSeries", m_doLSeries = false);
+  declareProperty("BetaList",   m_rawBetaVals = {});
+  declareProperty("DoM3",       m_doM3 = false);
+  declareProperty("DoN3",       m_doN3 = false);
+  declareProperty("DoLSeries",  m_doLSeries = false);
   declareProperty("DoDichroic", m_doDichroic = false);
 }
 
 StatusCode EnergyCorrelatorGeneralizedRatiosTool::initialize() {
 
-  // Add beta = 1.0 by default
-  m_betaVals.push_back(1.0);
+  /// Call base class initialize to fix up m_prefix
+  ATH_CHECK( JetSubStructureMomentToolsBase::initialize() );
 
-  // Clean up input list of beta values
-  for(float beta : m_rawBetaVals) {
+  /// Add beta = 1.0 by default
+  m_moments.emplace( 1.0, moments_t(1.0, m_prefix) );
 
-    // Round to the nearest 0.1
+  /// Clean up input list of beta values
+  for( float beta : m_rawBetaVals ) {
+
+    /// Round to the nearest 0.1
     float betaFix = round( beta * 10.0 ) / 10.0;
-    if(std::abs(beta-betaFix) > 1.0e-5) ATH_MSG_DEBUG("beta = " << beta << " has been rounded to " << betaFix);
+    if( std::abs(beta-betaFix) > 1.0e-5 ) ATH_MSG_DEBUG( "beta = " << beta << " has been rounded to " << betaFix );
 
-    // Skip negative values of beta
-    if(betaFix < 0.0) {
-      ATH_MSG_WARNING("beta must be positive. Skipping beta = " << beta);
+    /// Skip negative values of beta
+    if( betaFix < 0.0 ) {
+      ATH_MSG_WARNING( "beta must be positive. Skipping beta = " << beta );
       continue;
     }
 
-    // Only store value if it is not already in the list
-    if( std::find(m_betaVals.begin(), m_betaVals.end(), betaFix) == m_betaVals.end() ) m_betaVals.push_back(betaFix);
+    /// Store value. std::map::emplace prevents duplicate entries
+    m_moments.emplace( betaFix, moments_t(betaFix, m_prefix) );
+
   }
 
-  for(float beta : m_betaVals) {
-    ATH_MSG_DEBUG("Including beta = " << beta);
+  /// Print out list of beta values to debug stream
+  for( auto const& moment : m_moments ) {
+    ATH_MSG_DEBUG( "Including beta = " << moment.first );
   }
 
-  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+  /// Initialize accessors for L-series
+  m_acc_ECFG_2_1_2 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_2_1_2");
+  m_acc_ECFG_3_1_1 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_3_1_1");
+  m_acc_ECFG_3_2_1 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_3_2_1");
+  m_acc_ECFG_3_2_2 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_3_2_2");
+  m_acc_ECFG_3_3_1 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_3_3_1");
+  m_acc_ECFG_4_2_2 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_4_2_2");
+  m_acc_ECFG_4_4_1 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_4_4_1");
+
+  /// Initialize decorators for L-series
+  m_dec_L1 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"L1");
+  m_dec_L2 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"L2");
+  m_dec_L3 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"L3");
+  m_dec_L4 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"L4");
+  m_dec_L5 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"L5");
 
   return StatusCode::SUCCESS;
+
 }
 
 int EnergyCorrelatorGeneralizedRatiosTool::modifyJet(xAOD::Jet &jet) const {
 
-  for(float beta : m_betaVals) {
-    std::string suffix = GetBetaSuffix(beta);
+  for( auto const& moment : m_moments ) {
+
+    std::string suffix = moment.second.suffix;
 
-    if (!jet.isAvailable<float>(m_prefix+"ECFG_2_1"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_2_1" << suffix << "' is not available. Exiting..");
+    /// Check to make sure all of the necessary ECFG decorations are available
+    if( !moment.second.acc_ECFG_2_1->isAvailable(jet) ) {
+      ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_2_1" << suffix << "' is not available. Exiting." );
       return 1;
     }
 
-    if (!jet.isAvailable<float>(m_prefix+"ECFG_3_2"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_3_2" << suffix << "' is not available. Exiting..");
+    if( !moment.second.acc_ECFG_3_2->isAvailable(jet) ) {
+      ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_3_2" << suffix << "' is not available. Exiting." );
       return 1;
     }
 
-    if(m_doN3) {
-      if (!jet.isAvailable<float>(m_prefix+"ECFG_3_1"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_3_1" << suffix << "' is not available. Exiting..");
+    if( m_doM3 || m_doN3 ) {
+      if( !moment.second.acc_ECFG_3_1->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_3_1" << suffix << "' is not available. Exiting." );
         return 1;
       }
+    }
 
-      if (!jet.isAvailable<float>(m_prefix+"ECFG_4_2"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_4_2" << suffix << "' is not available. Exiting..");
+    if( m_doM3 ) {
+      if( !moment.second.acc_ECFG_4_1->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_4_1" << suffix << "' is not available. Exiting." );
         return 1;
       }
     }
 
-    if (m_doDichroic) {
-      if (!jet.isAvailable<float>(m_prefix+"ECFG_2_1_ungroomed"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_2_1_ungroomed" << suffix << "' is not available. Exiting..");
+    if( m_doN3 ) {
+      if( !moment.second.acc_ECFG_4_2->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_4_2" << suffix << "' is not available. Exiting." );
         return 1;
       }
+    }
 
-      if (!jet.isAvailable<float>(m_prefix+"ECFG_3_1_ungroomed"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_3_1_ungroomed" << suffix << "' is not available. Exiting..");
+    if( m_doDichroic ) {
+      if( !moment.second.acc_ECFG_2_1_ungroomed->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_2_1_ungroomed" << suffix << "' is not available. Exiting." );
         return 1;
       }
 
-      if(m_doN3) {
-        if (!jet.isAvailable<float>(m_prefix+"ECFG_3_2_ungroomed"+suffix)) {
-          ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_3_2_ungroomed" << suffix << "' is not available. Exiting..");
-          return 1;
-        }
+      if( !moment.second.acc_ECFG_3_1_ungroomed->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_3_1_ungroomed" << suffix << "' is not available. Exiting." );
+        return 1;
       }
-    }
 
-    float ecfg_2_1 = jet.getAttribute<float>(m_prefix+"ECFG_2_1"+suffix);
-    float ecfg_3_1 = jet.getAttribute<float>(m_prefix+"ECFG_3_1"+suffix);
-    float ecfg_3_2 = jet.getAttribute<float>(m_prefix+"ECFG_3_2"+suffix);
-    float ecfg_4_2 = jet.getAttribute<float>(m_prefix+"ECFG_4_2"+suffix);
+      if( !moment.second.acc_ECFG_3_2_ungroomed->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_3_2_ungroomed" << suffix << "' is not available. Exiting." );
+        return 1;
+      }
+    }
 
+    float ecfg_2_1 = (*moment.second.acc_ECFG_2_1)(jet);
+    float ecfg_3_1 = (*moment.second.acc_ECFG_3_1)(jet);
+    float ecfg_3_2 = (*moment.second.acc_ECFG_3_2)(jet);
+    float ecfg_4_1 = (*moment.second.acc_ECFG_4_2)(jet);
+    float ecfg_4_2 = (*moment.second.acc_ECFG_4_2)(jet);
+    
     float ecfg_2_1_ungroomed = -999.0;
     float ecfg_3_1_ungroomed = -999.0;
     float ecfg_3_2_ungroomed = -999.0;
 
-    if (m_doDichroic) {
-      ecfg_2_1_ungroomed = jet.getAttribute<float>(m_prefix+"ECFG_2_1_ungroomed"+suffix);
-      ecfg_3_1_ungroomed = jet.getAttribute<float>(m_prefix+"ECFG_3_1_ungroomed"+suffix);
-      ecfg_3_2_ungroomed = jet.getAttribute<float>(m_prefix+"ECFG_3_2_ungroomed"+suffix);
+    if( m_doDichroic ) {
+      ecfg_2_1_ungroomed = (*moment.second.acc_ECFG_2_1_ungroomed)(jet);
+      ecfg_3_1_ungroomed = (*moment.second.acc_ECFG_3_1_ungroomed)(jet);
+      ecfg_3_2_ungroomed = (*moment.second.acc_ECFG_3_2_ungroomed)(jet);
     }
 
-    // N2
-    if(ecfg_2_1 > 1e-8) { // Prevent div-0
-      jet.setAttribute(m_prefix+"N2"+suffix, ecfg_3_2 / (pow(ecfg_2_1, 2.0)));
+    float M2 = -999.0;
+    float M3 = -999.0;
+
+    float N2 = -999.0;
+    float N3 = -999.0;
+    
+    float M2_dichroic = -999.0;
+    float N2_dichroic = -999.0;
 
-      if(ecfg_3_2_ungroomed > 1e-8 && ecfg_2_1_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"N2_dichroic"+suffix, ecfg_3_2_ungroomed / (ecfg_2_1_ungroomed * ecfg_2_1));
-      else
-        jet.setAttribute(m_prefix+"N2_dichroic"+suffix, -999.0);
+    /// M2
+    if( ecfg_2_1 > 1e-8 ) /// Prevent div-0
+    {
+     
+      M2 = ecfg_3_1 / ecfg_2_1;
+
+      if( ecfg_3_1_ungroomed > 1e-8 )
+      {
+        M2_dichroic = ecfg_3_1_ungroomed / ecfg_2_1;
+      }
+    
     }
-    else {
-      jet.setAttribute(m_prefix+"N2"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"N2_dichroic"+suffix, -999.0);
+    
+    /// M3
+    if( m_doM3 && ecfg_3_1 > 1e-8 ) /// Prevent div-0
+    {
+      M3 = ecfg_4_1 / ecfg_3_1;
     }
 
-    // N3
-    if(m_doN3 && ecfg_3_1 > 1e-8) // Prevent div-0
-      jet.setAttribute(m_prefix+"N3"+suffix, ecfg_4_2 / (pow(ecfg_3_1, 2.0)));
-    else
-      jet.setAttribute(m_prefix+"N3"+suffix, -999.0);
+    /// N2
+    if( ecfg_2_1 > 1e-8 ) /// Prevent div-0
+    {
+      
+      N2 = ecfg_3_2 / pow( ecfg_2_1, 2.0 );
 
-    // M2
-    if(ecfg_2_1 > 1e-8) { // Prevent div-0
-      jet.setAttribute(m_prefix+"M2"+suffix, ecfg_3_1 / ecfg_2_1);
+      if( ecfg_3_2_ungroomed > 1e-8 && ecfg_2_1_ungroomed > 1e-8 )
+      {
+        N2_dichroic = ecfg_3_2_ungroomed / ( ecfg_2_1_ungroomed * ecfg_2_1 );
+      }
 
-      if(ecfg_3_1_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"M2_dichroic"+suffix, ecfg_3_1_ungroomed / ecfg_2_1);
-      else
-        jet.setAttribute(m_prefix+"M2_dichroic"+suffix, -999.0);
     }
-    else {
-      jet.setAttribute(m_prefix+"M2"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"M2_dichroic"+suffix, -999.0);
+
+    /// N3
+    if( m_doN3 && ecfg_3_1 > 1e-8 ) /// Prevent div-0
+    {
+      N3 = ecfg_4_2 / pow( ecfg_3_1, 2.0 );
     }
 
+    (*moment.second.dec_M2)(jet) = M2;
+    (*moment.second.dec_M3)(jet) = M3;
+    
+    (*moment.second.dec_N2)(jet) = N2;
+    (*moment.second.dec_N3)(jet) = N3;
+    
+    (*moment.second.dec_M2_dichroic)(jet) = M2_dichroic;
+    (*moment.second.dec_N2_dichroic)(jet) = N2_dichroic;
+
   }
 
-  if (m_doLSeries) {
-    // These are for t/H discrimination
-    if (!jet.isAvailable<float>(m_prefix+"ECFG_2_1_2") ||
-        !jet.isAvailable<float>(m_prefix+"ECFG_3_1_1") ||
-        !jet.isAvailable<float>(m_prefix+"ECFG_3_2_1") ||
-        !jet.isAvailable<float>(m_prefix+"ECFG_3_2_2") ||
-        !jet.isAvailable<float>(m_prefix+"ECFG_4_2_2") ||
-        !jet.isAvailable<float>(m_prefix+"ECFG_3_3_1") ||
-        !jet.isAvailable<float>(m_prefix+"ECFG_4_4_1")) {
+  /**
+   * ------------------------------------------------------------------
+   * L-series ECFG ratios (experimental for ttH t/H discrimination)
+   *
+   * The exponents E are determined in order to make the ratios dimensionless
+   *
+   * E = (a*n) / (b*m)
+   * for an ECFG_X_Y_Z, a=Y, n=Z
+   *
+   * e.g. for L1
+   * ecfg_3_3_1 / ecfg_2_1_2
+   * E = (3*1) / (1*2) = 3./2.
+   * ------------------------------------------------------------------
+   */
+
+  float L1 = -999.0;
+  float L2 = -999.0;
+  float L3 = -999.0;
+  float L4 = -999.0;
+  float L5 = -999.0;
+
+  if( m_doLSeries ) {
+
+    if( !m_acc_ECFG_2_1_2->isAvailable(jet) ||
+        !m_acc_ECFG_3_1_1->isAvailable(jet) ||
+        !m_acc_ECFG_3_2_1->isAvailable(jet) ||
+        !m_acc_ECFG_3_2_2->isAvailable(jet) ||
+        !m_acc_ECFG_3_3_1->isAvailable(jet) ||
+        !m_acc_ECFG_4_2_2->isAvailable(jet) ||
+        !m_acc_ECFG_4_4_1->isAvailable(jet) ) {
       ATH_MSG_WARNING("L series energy correlation functions with prefix '" << m_prefix << "' are not all available. Exiting..");
       return 1;
     }
-  }
-
-  float ecfg_2_1_2 = -999.0;
-  float ecfg_3_1_1 = -999.0;
-  float ecfg_3_2_1 = -999.0;
-  float ecfg_3_2_2 = -999.0;
-  float ecfg_4_2_2 = -999.0;
-  float ecfg_3_3_1 = -999.0;
-  float ecfg_4_4_1 = -999.0;
-
-  if (m_doLSeries) {
-    ecfg_2_1_2 = jet.getAttribute<float>(m_prefix+"ECFG_2_1_2");
-    ecfg_3_1_1 = jet.getAttribute<float>(m_prefix+"ECFG_3_1_1");
-    ecfg_3_2_1 = jet.getAttribute<float>(m_prefix+"ECFG_3_2_1");  
-    ecfg_3_2_2 = jet.getAttribute<float>(m_prefix+"ECFG_3_2_2");
-    ecfg_4_2_2 = jet.getAttribute<float>(m_prefix+"ECFG_4_2_2");
-    ecfg_3_3_1 = jet.getAttribute<float>(m_prefix+"ECFG_3_3_1");
-    ecfg_4_4_1 = jet.getAttribute<float>(m_prefix+"ECFG_4_4_1");
-  }
-
-  // L-series variables
-  // (experimental for ttH t/H discrimination)
-
-  /*
-     The exponents are determined in order to make 
-     the whole thing dimensionless
 
-     E = (a*n) / (b*m)
-     for an ECFG_X_Y_Z, a=Y, n=Z
+    float ecfg_2_1_2 = (*m_acc_ECFG_2_1_2)(jet);
+    float ecfg_3_1_1 = (*m_acc_ECFG_3_1_1)(jet);
+    float ecfg_3_2_1 = (*m_acc_ECFG_3_2_1)(jet);
+    float ecfg_3_2_2 = (*m_acc_ECFG_3_2_2)(jet);
+    float ecfg_3_3_1 = (*m_acc_ECFG_3_3_1)(jet);
+    float ecfg_4_2_2 = (*m_acc_ECFG_4_2_2)(jet);
+    float ecfg_4_4_1 = (*m_acc_ECFG_4_4_1)(jet);
+
+    if( ecfg_2_1_2 > 1e-8 ) /// Prevent div-0
+    {
+      L1 = ecfg_3_2_1 / pow( ecfg_2_1_2, 1.0 );
+      L2 = ecfg_3_3_1 / pow( ecfg_2_1_2, (3.0/2.0) );
+    }
 
-     e.g. for L1
+    if( ecfg_3_3_1 > 1e-8 ) /// Prevent div-0
+    {
+      L3 = ecfg_3_1_1 / pow( ecfg_3_3_1, (1.0/3.0) );
+      L4 = ecfg_3_2_2 / pow( ecfg_3_3_1, (4.0/3.0) );
+    }
 
-     ecfg_3_3_1 / ecfg_2_1_2
-     E = (3*1) / (1*2) = 3./2.
-     */
+    if( ecfg_4_4_1 > 1e-8 ) /// Prevent div-0
+    {
+      L5 = ecfg_4_2_2 / pow( ecfg_4_4_1, 1.0 );
+    }
 
-  if(ecfg_2_1_2 > 1e-8) // Prevent div-0
-  {
-    jet.setAttribute(m_prefix+"L1", ecfg_3_2_1 / (pow(ecfg_2_1_2, (1.) )));
-    jet.setAttribute(m_prefix+"L2", ecfg_3_3_1 / (pow(ecfg_2_1_2, (3./2.) )));
-  }
-  else
-  {
-    jet.setAttribute(m_prefix+"L1",-999.0);
-    jet.setAttribute(m_prefix+"L2",-999.0);
-  }
 
-  if(ecfg_3_3_1 > 1e-8) // Prevent div-0
-  {  
-    jet.setAttribute(m_prefix+"L3", ecfg_3_1_1 / (pow(ecfg_3_3_1, (1./3.) )) );
-    jet.setAttribute(m_prefix+"L4", ecfg_3_2_2 / (pow(ecfg_3_3_1, (4./3.) )) );
-  }
-  else
-  {
-    jet.setAttribute(m_prefix+"L3",-999.0);
-    jet.setAttribute(m_prefix+"L4",-999.0);
   }
 
-  if(ecfg_4_4_1 > 1e-8) // Prevent div-0
-    jet.setAttribute(m_prefix+"L5", ecfg_4_2_2 / (pow(ecfg_4_4_1, (1.) )) );
-  else
-    jet.setAttribute(m_prefix+"L5",-999.0);
+  (*m_dec_L1)(jet) = L1;
+  (*m_dec_L2)(jet) = L2;
+  (*m_dec_L3)(jet) = L3;
+  (*m_dec_L4)(jet) = L4;
+  (*m_dec_L5)(jet) = L5;
 
   return 0;
+
 }
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedTool.cxx b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedTool.cxx
index 8bff896e130cdcd57dbdb9351ccac6a58b7882d6..bf5143f67fd7190323a307ce5eb5360e9f3523b2 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedTool.cxx
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedTool.cxx
@@ -3,181 +3,255 @@
 */
 
 #include "JetSubStructureMomentTools/EnergyCorrelatorGeneralizedTool.h"
-#include "JetSubStructureUtils/EnergyCorrelatorGeneralized.h" 
-#include "JetSubStructureUtils/EnergyCorrelator.h" 
+#include "JetSubStructureUtils/EnergyCorrelatorGeneralized.h"
+#include "JetSubStructureUtils/EnergyCorrelator.h"
 
 EnergyCorrelatorGeneralizedTool::EnergyCorrelatorGeneralizedTool(std::string name) : 
   JetSubStructureMomentToolsBase(name)
 {
-  declareProperty("Beta", m_Beta = 1.0);
-  declareProperty("BetaList", m_rawBetaVals = {});
-  declareProperty("DoN3", m_doN3 = false);
-  declareProperty("DoLSeries", m_doLSeries = false);
+  declareProperty("Beta",       m_Beta = 1.0);
+  declareProperty("BetaList",   m_rawBetaVals = {});
+  declareProperty("DoM3",       m_doM3 = false);
+  declareProperty("DoN3",       m_doN3 = false);
+  declareProperty("DoLSeries",  m_doLSeries = false);
   declareProperty("DoDichroic", m_doDichroic = false);
 }
 
 StatusCode EnergyCorrelatorGeneralizedTool::initialize() {
 
-  // Add beta = 1.0 by default
-  m_betaVals.push_back(1.0);
+  /// Call base class initialize to fix up m_prefix
+  ATH_CHECK( JetSubStructureMomentToolsBase::initialize() );
 
-  // Add beta = m_Beta by default to keep backwards compatibility
-  if( std::abs(m_Beta-1.0) > 1.0e-5 ) m_betaVals.push_back(m_Beta);
+  /// Add beta = 1.0 by default
+  m_moments.emplace( 1.0, moments_t(1.0, m_prefix) );
 
-  // Clean up input list of beta values
-  for(float beta : m_rawBetaVals) {
+  /// Add beta = m_Beta by default to keep backwards compatibility
+  if( std::abs(m_Beta-1.0) > 1.0e-5 ) {
 
-    // Round to the nearest 0.1
+    /// Give warning about deprecation
+    ATH_MSG_WARNING( "The Beta property is deprecated, please use the BetaList property to provide a list of values" );
+
+    /// Use m_Beta to not break analysis code
+    m_moments.emplace( m_Beta, moments_t(m_Beta, m_prefix) );
+
+  }
+
+  /// Clean up input list of beta values
+  for( float beta : m_rawBetaVals ) {
+
+    /// Round to the nearest 0.1
     float betaFix = round( beta * 10.0 ) / 10.0;
-    if(std::abs(beta-betaFix) > 1.0e-5) ATH_MSG_DEBUG("beta = " << beta << " has been rounded to " << betaFix);
+    if( std::abs(beta-betaFix) > 1.0e-5 ) ATH_MSG_DEBUG( "beta = " << beta << " has been rounded to " << betaFix );
 
-    // Skip negative values of beta
-    if(betaFix < 0.0) {
-      ATH_MSG_WARNING("beta must be positive. Skipping beta = " << beta);
+    /// Skip negative values of beta
+    if( betaFix < 0.0 ) {
+      ATH_MSG_WARNING( "beta must be positive. Skipping beta = " << beta );
       continue;
     }
 
-    // Only store value if it is not already in the list
-    if( std::find(m_betaVals.begin(), m_betaVals.end(), betaFix) == m_betaVals.end() ) m_betaVals.push_back(betaFix);
+    /// Store value. std::map::emplace prevents duplicate entries
+    m_moments.emplace( betaFix, moments_t(betaFix, m_prefix) );
+
   }
 
-  for(float beta : m_betaVals) {
-    ATH_MSG_DEBUG("Including beta = " << beta);
+  /// Print out list of beta values to debug stream
+  for( auto const& moment : m_moments ) {
+    ATH_MSG_DEBUG( "Including beta = " << moment.first );
   }
 
-  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+  /// Initialize decorators for L-series
+  m_dec_ECFG_2_1_2 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_2_1_2");
+  m_dec_ECFG_3_1_1 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_3_1_1");
+  m_dec_ECFG_3_2_1 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_3_2_1");
+  m_dec_ECFG_3_2_2 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_3_2_2");
+  m_dec_ECFG_3_3_1 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_3_3_1");
+  m_dec_ECFG_4_2_2 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_4_2_2");
+  m_dec_ECFG_4_4_1 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_4_4_1");
 
   return StatusCode::SUCCESS;
+
 }
 
 int EnergyCorrelatorGeneralizedTool::modifyJet(xAOD::Jet &injet) const {
-  
+
   fastjet::PseudoJet jet;
   fastjet::PseudoJet jet_ungroomed;
-  
-  bool decorate = SetupDecoration(jet,injet);
-  bool decorate_ungroomed = false;
-  if(m_doDichroic) {
-    // Get parent jet here and replace injet
+
+  /// Bool to decide whether calculation should be performed
+  bool calculate = SetupDecoration(jet,injet);
+
+  /// Bool to decide if ungroomed jet moments should be calculated
+  bool calculate_ungroomed = false;
+
+  if( m_doDichroic ) {
+
+    /// Get parent jet
     ElementLink<xAOD::JetContainer> parentLink = injet.auxdata<ElementLink<xAOD::JetContainer> >("Parent");
 
-    // Return error is parent element link is broken
-    if(!parentLink.isValid()) {
-      ATH_MSG_ERROR("Parent element link is not valid. Aborting");
+    /// Return error is parent element link is broken
+    if( !parentLink.isValid() ) {
+      ATH_MSG_ERROR( "Parent element link is not valid. Aborting" );
       return 1;
     }
 
     const xAOD::Jet* parentJet = *(parentLink);
-    decorate_ungroomed = SetupDecoration(jet_ungroomed,*parentJet);
-  }
+    calculate_ungroomed = SetupDecoration(jet_ungroomed,*parentJet);
 
-  for(float beta : m_betaVals) {
+  }
 
-    std::string suffix = GetBetaSuffix(beta);
+  /// Loop over all of the moments
+  for( auto const& moment : m_moments ) {
 
-    // These are used for N2 and M2
-    float ECFG_2_1_value = -999, ECFG_3_2_value = -999;
-    float ECFG_2_1_value_ungroomed = -999, ECFG_3_2_value_ungroomed = -999;
+    float beta = moment.first;
 
-    // These are used for N3
-    float ECFG_3_1_value = -999, ECFG_4_2_value = -999;
-    float ECFG_3_1_value_ungroomed = -999;
+    /// These are used for M2 and N2
+    float ECFG_2_1_value = -999.0;
+    float ECFG_3_2_value = -999.0;
+    
+    /// These are used for dichroic M2 and N2
+    float ECFG_2_1_ungroomed_value = -999.0;
+    float ECFG_3_1_ungroomed_value = -999.0;
+    float ECFG_3_2_ungroomed_value = -999.0;
 
-    if (decorate) {
+    /// These are used for M3 and N3
+    float ECFG_3_1_value = -999.0;
+    float ECFG_4_1_value = -999.0;
+    float ECFG_4_2_value = -999.0;
 
-      // These are used for N2 and M2
+    if( calculate ) {
 
+      /// These are used for N2 and M2
       JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_2(2, 3, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
       JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_2_1(1, 2, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
+
       ECFG_2_1_value = ECFG_2_1.result(jet);
       ECFG_3_2_value = ECFG_3_2.result(jet);
 
-      if (decorate_ungroomed) {
-        ECFG_2_1_value_ungroomed = ECFG_2_1.result(jet_ungroomed);
-        ECFG_3_2_value_ungroomed = ECFG_3_2.result(jet_ungroomed);
+      /// These are used for dichroic N2 and M2
+      if( calculate_ungroomed ) {
+        ECFG_2_1_ungroomed_value = ECFG_2_1.result(jet_ungroomed);
+        ECFG_3_2_ungroomed_value = ECFG_3_2.result(jet_ungroomed);
       }
 
-      // These are used for N3
+      /// These are used for M3 and N3
+      if( m_doM3 || m_doN3 ) {
 
-      if(m_doN3) {
-        JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_4_2(2, 4, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
         JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_1(1, 3, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
+
         ECFG_3_1_value = ECFG_3_1.result(jet);
-        ECFG_4_2_value = ECFG_4_2.result(jet);
 
-        if (decorate_ungroomed) {
-          ECFG_3_1_value_ungroomed = ECFG_3_1.result(jet_ungroomed);
+        if( calculate_ungroomed ) {
+          ECFG_3_1_ungroomed_value = ECFG_3_1.result(jet_ungroomed);
+        }
+
+        /// This is used for M3
+        if( m_doM3 ) {
+          JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_4_1(1, 4, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
+          ECFG_4_1_value = ECFG_4_1.result(jet);
+        }
+
+        /// This is used for N3
+        if( m_doN3 ) {
+          JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_4_2(2, 4, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
+          ECFG_4_2_value = ECFG_4_2.result(jet);
         }
 
       }
 
     }
 
-    injet.setAttribute(m_prefix+"ECFG_2_1"+suffix, ECFG_2_1_value);
-    injet.setAttribute(m_prefix+"ECFG_3_2"+suffix, ECFG_3_2_value);
-    injet.setAttribute(m_prefix+"ECFG_3_1"+suffix, ECFG_3_1_value);
-    injet.setAttribute(m_prefix+"ECFG_4_2"+suffix, ECFG_4_2_value);
+    (*moment.second.dec_ECFG_2_1)(injet) = ECFG_2_1_value;
+    (*moment.second.dec_ECFG_3_1)(injet) = ECFG_3_1_value;
+    (*moment.second.dec_ECFG_3_2)(injet) = ECFG_3_2_value;
+    (*moment.second.dec_ECFG_4_1)(injet) = ECFG_4_1_value;
+    (*moment.second.dec_ECFG_4_2)(injet) = ECFG_4_2_value;
 
-    injet.setAttribute(m_prefix+"ECFG_2_1_ungroomed"+suffix, ECFG_2_1_value_ungroomed);
-    injet.setAttribute(m_prefix+"ECFG_3_2_ungroomed"+suffix, ECFG_3_2_value_ungroomed);
-    injet.setAttribute(m_prefix+"ECFG_3_1_ungroomed"+suffix, ECFG_3_1_value_ungroomed);
+    (*moment.second.dec_ECFG_2_1_ungroomed)(injet) = ECFG_2_1_ungroomed_value;
+    (*moment.second.dec_ECFG_3_1_ungroomed)(injet) = ECFG_3_1_ungroomed_value;
+    (*moment.second.dec_ECFG_3_2_ungroomed)(injet) = ECFG_3_2_ungroomed_value;
 
   }
 
-  // These are for t/H discrimination
-  float ECFG_3_3_2_value = -999, ECFG_3_2_2_value = -999, ECFG_3_3_1_value = -999,
-        ECFG_4_2_2_value = -999, ECFG_4_4_1_value = -999, ECFG_2_1_2_value = -999, ECFG_3_2_1_value =  -999,
-        ECFG_3_1_1_value = -999;
-  // N.B. ECFG_angles_n_beta !!
-
-  if (decorate) {
+  /// ECFGs for L-series ratios that are for t/H discrimination
+  float ECFG_2_1_2_value = -999;
+  float ECFG_3_1_1_value = -999;
+  float ECFG_3_2_1_value = -999;
+  float ECFG_3_2_2_value = -999;
+  float ECFG_3_3_1_value = -999;
+  float ECFG_4_2_2_value = -999;
+  float ECFG_4_4_1_value = -999;
+
+  /// N.B. ECFG_angles_n_beta !!
+
+  if( calculate && m_doLSeries ) {
+
+    /**
+     * ------------------------------------------------------
+     * Some of the ECFGs for the L-series ratios may already have been calculated
+     * depending on which beta values are included. Checks are put in place for
+     * each one and if it has already been calculated the value is simply copied.
+     * This is meant to prevent duplicating CPU intensive calculations that have
+     * already been performed.
+     * ------------------------------------------------------
+     */
+
+    /// 212
+    if( m_moments.count(2.0) ) {
+      ECFG_2_1_2_value = (*m_moments.at(2.0).dec_ECFG_2_1)(injet);
+    }
+    else {
+      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_2_1_2(1, 2, 2, JetSubStructureUtils::EnergyCorrelator::pt_R);
+      ECFG_2_1_2_value = ECFG_2_1_2.result(jet);
+    }
 
-    // These are for t/H discrimination
+    /// 311
+    if( m_doN3 ) {
+      ECFG_3_1_1_value = (*m_moments.at(1.0).dec_ECFG_3_1)(injet);
+    }
+    else {
+      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_1_1(1, 3, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
+      ECFG_3_1_1_value = ECFG_3_1_1.result(jet);
+    }
 
-    if(m_doLSeries) {
-      // 332
-      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_3_2(3, 3, 2, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_3_3_2_value = ECFG_3_3_2.result(jet);
+    /// 321
+    ECFG_3_2_1_value = (*m_moments.at(1.0).dec_ECFG_3_2)(injet);
 
-      // 322
+    /// 322
+    if( m_moments.count(2.0) ) {
+      ECFG_3_2_2_value = (*m_moments.at(2.0).dec_ECFG_3_2)(injet);
+    }
+    else {
       JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_2_2(2, 3, 2, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_3_2_2_value =  ECFG_3_2_2.result(jet);
+      ECFG_3_2_2_value = ECFG_3_2_2.result(jet);
+    }
 
-      // 331
-      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_3_1(3, 3, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_3_3_1_value = ECFG_3_3_1.result(jet);
+    /// 331
+    JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_3_1(3, 3, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
+    ECFG_3_3_1_value = ECFG_3_3_1.result(jet);
 
-      // 422
+    /// 422
+    if( m_doN3 && m_moments.count(2.0) ) {
+      ECFG_4_2_2_value = (*m_moments.at(2.0).dec_ECFG_4_2)(injet);
+    }
+    else {
       JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_4_2_2(2, 4, 2, JetSubStructureUtils::EnergyCorrelator::pt_R);
       ECFG_4_2_2_value = ECFG_4_2_2.result(jet);
-
-      // 441
-      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_4_4_1(4, 4, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_4_4_1_value = ECFG_4_4_1.result(jet);
-
-      // 212
-      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_2_1_2(1, 2, 2, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_2_1_2_value = ECFG_2_1_2.result(jet);
-
-      // 321
-      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_2_1(2, 3, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_3_2_1_value = ECFG_3_2_1.result(jet);
-
-      // 311
-      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_1_1(1, 3, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_3_1_1_value = ECFG_3_1_1.result(jet);
     }
 
+    /// 441
+    JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_4_4_1(4, 4, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
+    ECFG_4_4_1_value = ECFG_4_4_1.result(jet);
+  
   }
 
-  injet.setAttribute(m_prefix+"ECFG_3_3_2", ECFG_3_3_2_value);
-  injet.setAttribute(m_prefix+"ECFG_3_2_2", ECFG_3_2_2_value);
-  injet.setAttribute(m_prefix+"ECFG_3_3_1", ECFG_3_3_1_value);
-  injet.setAttribute(m_prefix+"ECFG_4_2_2", ECFG_4_2_2_value);
-  injet.setAttribute(m_prefix+"ECFG_4_4_1", ECFG_4_4_1_value);
-  injet.setAttribute(m_prefix+"ECFG_2_1_2", ECFG_2_1_2_value);
-  injet.setAttribute(m_prefix+"ECFG_3_2_1", ECFG_3_2_1_value);
-  injet.setAttribute(m_prefix+"ECFG_3_1_1", ECFG_3_1_1_value);
+  (*m_dec_ECFG_2_1_2)(injet) = ECFG_2_1_2_value;
+  (*m_dec_ECFG_3_1_1)(injet) = ECFG_3_1_1_value;
+  (*m_dec_ECFG_3_2_1)(injet) = ECFG_3_2_1_value;
+  (*m_dec_ECFG_3_2_2)(injet) = ECFG_3_2_2_value;
+  (*m_dec_ECFG_3_3_1)(injet) = ECFG_3_3_1_value;
+  (*m_dec_ECFG_4_2_2)(injet) = ECFG_4_2_2_value;
+  (*m_dec_ECFG_4_4_1)(injet) = ECFG_4_4_1_value;
 
   return 0;
+
 }
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorRatiosTool.cxx b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorRatiosTool.cxx
index 67c6b03e30eef7c460a7e153a3bfa1a211fa4fd0..0f1fb76f891d109cee0f327e9a1e25b3f144db9f 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorRatiosTool.cxx
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorRatiosTool.cxx
@@ -16,149 +16,177 @@ EnergyCorrelatorRatiosTool::EnergyCorrelatorRatiosTool(std::string name) :
 
 StatusCode EnergyCorrelatorRatiosTool::initialize() {
 
-  // Add beta = 1.0 by default
-  m_betaVals.push_back(1.0);
+  /// Call base class initialize to fix up m_prefix
+  ATH_CHECK( JetSubStructureMomentToolsBase::initialize() );
 
-  // Clean up input list of beta values
-  for(float beta : m_rawBetaVals) {
+  /// Add beta = 1.0 by default
+  m_moments.emplace( 1.0, moments_t(1.0, m_prefix) );
 
-    // Round to the nearest 0.1
+  /// Clean up input list of beta values
+  for( float beta : m_rawBetaVals ) {
+
+    /// Round to the nearest 0.1
     float betaFix = round( beta * 10.0 ) / 10.0;
-    if(std::abs(beta-betaFix) > 1.0e-5) ATH_MSG_DEBUG("beta = " << beta << " has been rounded to " << betaFix);
+    if( std::abs(beta-betaFix) > 1.0e-5 ) ATH_MSG_DEBUG( "beta = " << beta << " has been rounded to " << betaFix );
 
-    // Skip negative values of beta
-    if(betaFix < 0.0) {
-      ATH_MSG_WARNING("beta must be positive. Skipping beta = " << beta);
+    /// Skip negative values of beta
+    if( betaFix < 0.0 ) {
+      ATH_MSG_WARNING( "beta must be positive. Skipping beta = " << beta );
       continue;
     }
 
-    // Only store value if it is not already in the list
-    if( std::find(m_betaVals.begin(), m_betaVals.end(), betaFix) == m_betaVals.end() ) m_betaVals.push_back(betaFix);
+    /// Store value. std::map::emplace prevents duplicate entries
+    m_moments.emplace( betaFix, moments_t(betaFix, m_prefix) );
+  
   }
 
-  for(float beta : m_betaVals) {
-    ATH_MSG_DEBUG("Including beta = " << beta);
+  /// Print out list of beta values to debug stream
+  for( auto const& moment : m_moments ) {
+    ATH_MSG_DEBUG( "Including beta = " << moment.first );
   }
 
-  // If DoC4 is set to true, set DoC3 to true by default since it won't
-  // add any additional computational overhead
-  if(m_doC4) m_doC3 = true;
-
-  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+  /// If DoC4 is set to true, set DoC3 to true by default since it won't
+  /// add any additional computational overhead
+  if( m_doC4 ) m_doC3 = true;
 
   return StatusCode::SUCCESS;
+
 }
 
 int EnergyCorrelatorRatiosTool::modifyJet(xAOD::Jet &jet) const {
   
-  for(float beta : m_betaVals) {
-    std::string suffix = GetBetaSuffix(beta);
+  for( auto const& moment : m_moments ) {
+ 
+    std::string suffix = moment.second.suffix;
 
-    if (!jet.isAvailable<float>(m_prefix+"ECF1"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF1" << suffix << " is not available. Exiting..");
+    /// Check to make sure all of the necessary ECF decorations are available
+    if( !moment.second.acc_ECF1->isAvailable(jet) ) {
+      ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF1" << suffix << " is not available. Exiting." );
       return 1;
     }
 
-    if (!jet.isAvailable<float>(m_prefix+"ECF2"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF2" << suffix << " is not available. Exiting..");
+    if( !moment.second.acc_ECF2->isAvailable(jet) ) {
+      ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF2" << suffix << " is not available. Exiting." );
       return 1;
     }
 
-    if (!jet.isAvailable<float>(m_prefix+"ECF3"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF3" << suffix << " is not available. Exiting..");
+    if( !moment.second.acc_ECF3->isAvailable(jet) ) {
+      ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF3" << suffix << " is not available. Exiting." );
       return 1;
     }
 
-    if (m_doC3 && !jet.isAvailable<float>(m_prefix+"ECF4"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF4" << suffix << " is not available. Exiting..");
-      return 1;
+    if( m_doC3 ) {
+      if( !moment.second.acc_ECF4->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF4" << suffix << " is not available. Exiting." );
+        return 1;
+      }
     }
 
-    if (m_doC4 && !jet.isAvailable<float>(m_prefix+"ECF5"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF5" << suffix << " is not available. Exiting..");
-      return 1;
+    if( m_doC4 ) {
+      if( !moment.second.acc_ECF5->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF5" << suffix << " is not available. Exiting." );
+        return 1;
+      }
     }
 
     if(m_doDichroic) {
-      if (!jet.isAvailable<float>(m_prefix+"ECF1_ungroomed"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF1_ungroomed" << suffix << " is not available. Exiting..");
+      if( !moment.second.acc_ECF1_ungroomed->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF1_ungroomed" << suffix << " is not available. Exiting." );
         return 1;
       }
 
-      if (!jet.isAvailable<float>(m_prefix+"ECF2_ungroomed"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF2_ungroomed" << suffix << " is not available. Exiting..");
+      if( !moment.second.acc_ECF2_ungroomed->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF2_ungroomed" << suffix << " is not available. Exiting." );
         return 1;
       }
 
-      if (!jet.isAvailable<float>(m_prefix+"ECF3_ungroomed"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF3_ungroomed" << suffix << " is not available. Exiting..");
+      if( !moment.second.acc_ECF3_ungroomed->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF3_ungroomed" << suffix << " is not available. Exiting." );
         return 1;
       }
     }
 
-    float ecf1 = jet.getAttribute<float>(m_prefix+"ECF1"+suffix);
-    float ecf2 = jet.getAttribute<float>(m_prefix+"ECF2"+suffix);
-    float ecf3 = jet.getAttribute<float>(m_prefix+"ECF3"+suffix);
+    float ecf1 = (*moment.second.acc_ECF1)(jet);
+    float ecf2 = (*moment.second.acc_ECF2)(jet);
+    float ecf3 = (*moment.second.acc_ECF3)(jet);
 
     float ecf4 = -999.0;
-    if(m_doC3) {
-      ecf4 = jet.getAttribute<float>(m_prefix+"ECF4"+suffix);
+    if( m_doC3 ) {
+      ecf4 = (*moment.second.acc_ECF4)(jet);
     }
 
     float ecf5 = -999.0;
-    if(m_doC4) {
-      ecf5 = jet.getAttribute<float>(m_prefix+"ECF5"+suffix);
+    if( m_doC4 ) {
+      ecf5 = (*moment.second.acc_ECF5)(jet);
     }
 
     float ecf1_ungroomed = -999.0;
     float ecf2_ungroomed = -999.0;
     float ecf3_ungroomed = -999.0;
 
-    if(m_doDichroic) {
-      ecf1_ungroomed = jet.getAttribute<float>(m_prefix+"ECF1_ungroomed"+suffix);
-      ecf2_ungroomed = jet.getAttribute<float>(m_prefix+"ECF2_ungroomed"+suffix);
-      ecf3_ungroomed = jet.getAttribute<float>(m_prefix+"ECF3_ungroomed"+suffix);
+    if( m_doDichroic ) {
+      ecf1_ungroomed = (*moment.second.acc_ECF1_ungroomed)(jet);
+      ecf2_ungroomed = (*moment.second.acc_ECF2_ungroomed)(jet);
+      ecf3_ungroomed = (*moment.second.acc_ECF3_ungroomed)(jet);
     }
 
-    // D2
-    if(ecf2 > 1e-8) { // Prevent div-0
-      jet.setAttribute(m_prefix+"D2"+suffix, ecf3 * pow(ecf1, 3.0) / pow(ecf2, 3.0));
+    float C1 = -999.0;
+    float C2 = -999.0;
+    float C3 = -999.0;
+    float C4 = -999.0;
+    
+    float D2 = -999.0;
+    
+    float D2_dichroic = -999.0;
+
+    /// C1
+    if( ecf1 > 1e-8 ) /// Prevent div-0
+    {
+      C1 = ecf2 / pow( ecf1, 2.0 );
+    }
 
-      if(ecf2_ungroomed > 1e-8 && ecf3_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"D2_dichroic"+suffix, ecf3_ungroomed * ecf1_ungroomed * pow(ecf1, 2.0) / ( pow(ecf2_ungroomed, 2.0) * ecf2 ));
-      else
-        jet.setAttribute(m_prefix+"D2_dichroic"+suffix, -999.0);
+    /// C2
+    if( ecf2 > 1e-8 ) /// Prevent div-0
+    {
+      C2 = ecf3 * ecf1 / pow( ecf2, 2.0 );
+    }
 
+    /// C3
+    if( m_doC3 && ecf3 > 1e-8 ) /// Prevent div-0
+    {
+      C3 = ecf4 * ecf2 / pow( ecf3, 2.0 );
     }
-    else {
-      jet.setAttribute(m_prefix+"D2"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"D2_dichroic"+suffix, -999.0);
+
+    /// C4
+    if( m_doC4 && ecf4 > 1e-8 ) /// Prevent div-0
+    {
+      C4 = ecf5 * ecf3 / pow( ecf4, 2.0 );
     }
 
-    // C1
-    if(ecf1 > 1e-8) // Prevent div-0
-      jet.setAttribute(m_prefix+"C1"+suffix, ecf2 / pow(ecf1, 2.0));
-    else
-      jet.setAttribute(m_prefix+"C1"+suffix, -999.0);
-
-    // C2
-    if(ecf2 > 1e-8) // Prevent div-0
-      jet.setAttribute(m_prefix+"C2"+suffix, ecf3 * ecf1 / pow(ecf2, 2.0));
-    else
-      jet.setAttribute(m_prefix+"C2"+suffix, -999.0);
-
-    // C3
-    if(m_doC3 && ecf3 > 1e-8) // Prevent div-0
-      jet.setAttribute(m_prefix+"C3"+suffix, ecf4 * ecf2 / pow(ecf3, 2.0));
-    else
-      jet.setAttribute(m_prefix+"C3"+suffix, -999.0);
-
-    // C4
-    if(m_doC4 && ecf4 > 1e-8) // Prevent div-0
-      jet.setAttribute(m_prefix+"C4"+suffix, ecf5 * ecf3 / pow(ecf4, 2.0));
-    else
-      jet.setAttribute(m_prefix+"C4"+suffix, -999.0);
+    /// D2
+    if( ecf2 > 1e-8 ) /// Prevent div-0
+    {
+
+      D2 = ecf3 * pow( ecf1, 3.0 ) / pow( ecf2, 3.0 );
+
+      if( ecf2_ungroomed > 1e-8 && ecf3_ungroomed > 1e-8 )
+      {
+        D2_dichroic = ecf3_ungroomed * ecf1_ungroomed * pow( ecf1, 2.0 ) / ( pow( ecf2_ungroomed, 2.0 ) * ecf2 );
+      }
+
+    }
+
+    (*moment.second.dec_C1)(jet) = C1;
+    (*moment.second.dec_C2)(jet) = C2;
+    (*moment.second.dec_C3)(jet) = C3;
+    (*moment.second.dec_C4)(jet) = C4;
+    
+    (*moment.second.dec_D2)(jet) = D2;
+
+    (*moment.second.dec_D2_dichroic)(jet) = D2_dichroic;
+
   }
 
   return 0;
+
 }
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorTool.cxx b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorTool.cxx
index 23cc78c2d22ffc815b6f1a03aec444fb1c88b700..44cd07c5bc7498aafe919abd1f7fbb43648c24db 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorTool.cxx
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorTool.cxx
@@ -3,54 +3,66 @@
 */
 
 #include "JetSubStructureMomentTools/EnergyCorrelatorTool.h"
-#include "JetSubStructureUtils/EnergyCorrelator.h" 
+#include "JetSubStructureUtils/EnergyCorrelator.h"
 
 EnergyCorrelatorTool::EnergyCorrelatorTool(std::string name) : 
   JetSubStructureMomentToolsBase(name)
 {
-  declareProperty("Beta", m_Beta = 1.0);
-  declareProperty("BetaList", m_rawBetaVals = {});
-  declareProperty("DoC3", m_doC3 = false);
-  declareProperty("DoC4", m_doC4 = false);
+  declareProperty("Beta",       m_Beta = 1.0);
+  declareProperty("BetaList",   m_rawBetaVals = {});
+  declareProperty("DoC3",       m_doC3 = false);
+  declareProperty("DoC4",       m_doC4 = false);
   declareProperty("DoDichroic", m_doDichroic = false);
 }
 
 StatusCode EnergyCorrelatorTool::initialize() {
 
-  // Add beta = 1.0 by default
-  m_betaVals.push_back(1.0);
+  /// Call base class initialize to fix up m_prefix
+  ATH_CHECK( JetSubStructureMomentToolsBase::initialize() );
 
-  // Add beta = m_Beta by default to keep backwards compatibility
-  if( std::abs(m_Beta-1.0) > 1.0e-5 ) m_betaVals.push_back(m_Beta);
+  /// Add beta = 1.0 by default
+  m_moments.emplace( 1.0, moments_t(1.0, m_prefix) );
 
-  // Clean up input list of beta values
-  for(float beta : m_rawBetaVals) {
+  /// Add beta = m_Beta by default to keep backwards compatibility
+  if( std::abs(m_Beta-1.0) > 1.0e-5 ) {
 
-    // Round to the nearest 0.1
+    /// Give warning about deprecation
+    ATH_MSG_WARNING( "The Beta property is deprecated, please use the BetaList property to provide a list of values");
+
+    /// Use m_Beta to not break analysis code
+    m_moments.emplace( m_Beta, moments_t(m_Beta, m_prefix) );
+
+  }
+
+  /// Clean up input list of beta values
+  for( float beta : m_rawBetaVals ) {
+
+    /// Round to the nearest 0.1
     float betaFix = round( beta * 10.0 ) / 10.0;
-    if(std::abs(beta-betaFix) > 1.0e-5) ATH_MSG_DEBUG("beta = " << beta << " has been rounded to " << betaFix);
+    if( std::abs(beta-betaFix) > 1.0e-5 ) ATH_MSG_DEBUG( "beta = " << beta << " has been rounded to " << betaFix );
 
-    // Skip negative values of beta
-    if(betaFix < 0.0) {
-      ATH_MSG_WARNING("beta must be positive. Skipping beta = " << beta);
+    /// Skip negative values of beta
+    if( betaFix < 0.0 ) {
+      ATH_MSG_WARNING( "beta must be positive. Skipping beta = " << beta );
       continue;
     }
 
-    // Only store value if it is not already in the list
-    if( std::find(m_betaVals.begin(), m_betaVals.end(), betaFix) == m_betaVals.end() ) m_betaVals.push_back(betaFix);
-  }
+    /// Store value. std::map::emplace prevents duplicate entries
+    m_moments.emplace( betaFix, moments_t(betaFix, m_prefix) );
 
-  for(float beta : m_betaVals) {
-    ATH_MSG_DEBUG("Including beta = " << beta);
   }
 
-  // If DoC4 is set to true, set DoC3 to true by default since it won't
-  // add any additional computational overhead
-  if(m_doC4) m_doC3 = true;
+  /// Print out list of beta values to debug stream
+  for( auto const& moment : m_moments ) {
+    ATH_MSG_DEBUG( "Including beta = " << moment.first );
+  }
 
-  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+  /// If DoC4 is set to true, set DoC3 to true by default since it won't
+  /// add any additional computational overhead
+  if( m_doC4 ) m_doC3 = true;
 
   return StatusCode::SUCCESS;
+
 }
 
 int EnergyCorrelatorTool::modifyJet(xAOD::Jet &injet) const {
@@ -58,81 +70,82 @@ int EnergyCorrelatorTool::modifyJet(xAOD::Jet &injet) const {
   fastjet::PseudoJet jet;
   fastjet::PseudoJet jet_ungroomed;
 
-  bool decorate = SetupDecoration(jet,injet);
-  bool decorate_ungroomed = false;
-  if(m_doDichroic) {
-    // Get parent jet here and replace injet
+  /// Bool to decide whether calculation should be performed
+  bool calculate = SetupDecoration(jet,injet);
+
+  /// Bool to decide if ungroomed jet moments should be calculated
+  bool calculate_ungroomed = false;
+
+  if( m_doDichroic ) {
+
+    /// Get parent jet
     ElementLink<xAOD::JetContainer> parentLink = injet.auxdata<ElementLink<xAOD::JetContainer> >("Parent");
 
-    // Return error is parent element link is broken
-    if(!parentLink.isValid()) {
-      ATH_MSG_ERROR("Parent element link is not valid. Aborting");
+    /// Return error is parent element link is broken
+    if( !parentLink.isValid() ) {
+      ATH_MSG_ERROR( "Parent element link is not valid. Aborting" );
       return 1;
     }
 
     const xAOD::Jet* parentJet = *(parentLink);
-    decorate_ungroomed = SetupDecoration(jet_ungroomed,*parentJet);
-  }
+    calculate_ungroomed = SetupDecoration(jet_ungroomed,*parentJet);
 
-  for(float beta : m_betaVals) {
+  }
 
-    if(beta < 0.0) {
-      ATH_MSG_WARNING("Negative beta values are not supported. Skipping " << beta);
-      continue;
-    }
+  for( auto const& moment : m_moments ) {
 
-    std::string suffix = GetBetaSuffix(beta);
+    float beta = moment.first;
 
-    float result_ECF1 = -999;
-    float result_ECF2 = -999;
-    float result_ECF3 = -999;
-    float result_ECF4 = -999;
-    float result_ECF5 = -999;
+    float ECF1_value = -999;
+    float ECF2_value = -999;
+    float ECF3_value = -999;
+    float ECF4_value = -999;
+    float ECF5_value = -999;
 
-    float result_ECF1_ungroomed = -999;
-    float result_ECF2_ungroomed = -999;
-    float result_ECF3_ungroomed = -999;
+    float ECF1_ungroomed_value = -999;
+    float ECF2_ungroomed_value = -999;
+    float ECF3_ungroomed_value = -999;
 
-    if(decorate) {
+    if( calculate ) {
 
       JetSubStructureUtils::EnergyCorrelator ECF1(1, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
       JetSubStructureUtils::EnergyCorrelator ECF2(2, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
       JetSubStructureUtils::EnergyCorrelator ECF3(3, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
 
-      result_ECF1 = ECF1.result(jet);
-      result_ECF2 = ECF2.result(jet);
-      result_ECF3 = ECF3.result(jet);
+      ECF1_value = ECF1.result(jet);
+      ECF2_value = ECF2.result(jet);
+      ECF3_value = ECF3.result(jet);
 
-      if(m_doC3) {
+      if( m_doC3 ) {
         JetSubStructureUtils::EnergyCorrelator ECF4(4, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
-        result_ECF4 = ECF4.result(jet);
+        ECF4_value = ECF4.result(jet);
       }
 
-      if(m_doC4) {
+      if( m_doC4 ) {
         JetSubStructureUtils::EnergyCorrelator ECF5(5, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
-        result_ECF5 = ECF5.result(jet);
+        ECF5_value = ECF5.result(jet);
       }
 
-      if(decorate_ungroomed) {
-        result_ECF1_ungroomed = ECF1.result(jet_ungroomed);
-        result_ECF2_ungroomed = ECF2.result(jet_ungroomed);
-        result_ECF3_ungroomed = ECF3.result(jet_ungroomed);
+      if( calculate_ungroomed ) {
+        ECF1_ungroomed_value = ECF1.result(jet_ungroomed);
+        ECF2_ungroomed_value = ECF2.result(jet_ungroomed);
+        ECF3_ungroomed_value = ECF3.result(jet_ungroomed);
       }
 
     }
 
-    injet.setAttribute(m_prefix+"ECF1"+suffix, result_ECF1);
-    injet.setAttribute(m_prefix+"ECF2"+suffix, result_ECF2);
-    injet.setAttribute(m_prefix+"ECF3"+suffix, result_ECF3);
-    injet.setAttribute(m_prefix+"ECF4"+suffix, result_ECF4);
-    injet.setAttribute(m_prefix+"ECF5"+suffix, result_ECF5);
+    (*moment.second.dec_ECF1)(injet) = ECF1_value;
+    (*moment.second.dec_ECF2)(injet) = ECF2_value;
+    (*moment.second.dec_ECF3)(injet) = ECF3_value;
+    (*moment.second.dec_ECF4)(injet) = ECF4_value;
+    (*moment.second.dec_ECF5)(injet) = ECF5_value;
 
-    injet.setAttribute(m_prefix+"ECF1_ungroomed"+suffix, result_ECF1_ungroomed);
-    injet.setAttribute(m_prefix+"ECF2_ungroomed"+suffix, result_ECF2_ungroomed);
-    injet.setAttribute(m_prefix+"ECF3_ungroomed"+suffix, result_ECF3_ungroomed);
+    (*moment.second.dec_ECF1_ungroomed)(injet) = ECF1_ungroomed_value;
+    (*moment.second.dec_ECF2_ungroomed)(injet) = ECF2_ungroomed_value;
+    (*moment.second.dec_ECF3_ungroomed)(injet) = ECF3_ungroomed_value;
 
   }
 
   return 0;
-}
 
+}
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessRatiosTool.cxx b/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessRatiosTool.cxx
index a4c36cd9f4e7c392a3e370f40c601f6dcf1038f4..4e00035896ce04fbfdc8d8c5c519e64f025f903c 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessRatiosTool.cxx
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessRatiosTool.cxx
@@ -12,170 +12,195 @@ NSubjettinessRatiosTool::NSubjettinessRatiosTool(std::string name) :
 }
 
 StatusCode NSubjettinessRatiosTool::initialize() {
-  // Add alpha = 1.0 by default
-  m_alphaVals.push_back(1.0);
 
-  // Clean up input list of alpha values
-  for(float alpha : m_rawAlphaVals) {
+  /// Call base class initialize to fix up m_prefix
+  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+
+  /// Add alpha = 1.0 by default
+  m_moments.emplace( 1.0, moments_t(1.0, m_prefix) );
+
+  /// Clean up input list of alpha values
+  for( float alpha : m_rawAlphaVals ) {
 
-    // Round to the nearest 0.1
+    /// Round to the nearest 0.1
     float alphaFix = round( alpha * 10.0 ) / 10.0;
-    if(std::abs(alpha-alphaFix) > 1.0e-5) ATH_MSG_DEBUG("alpha = " << alpha << " has been rounded to " << alphaFix);
+    if( std::abs(alpha-alphaFix) > 1.0e-5 ) ATH_MSG_DEBUG( "alpha = " << alpha << " has been rounded to " << alphaFix );
 
-    // Skip negative values of alpha
-    if(alphaFix < 0.0) {
-      ATH_MSG_WARNING("alpha must be positive. Skipping alpha = " << alpha);
+    /// Skip negative values of alpha
+    if( alphaFix < 0.0 ) {
+      ATH_MSG_WARNING( "alpha must be positive. Skipping alpha = " << alpha );
       continue;
     }
 
-    // Only store value if it is not already in the list
-    if( std::find(m_alphaVals.begin(), m_alphaVals.end(), alphaFix) == m_alphaVals.end() ) m_alphaVals.push_back(alphaFix);
-  }
+    /// Store value. std::map::emplace prevents duplicate entries
+    m_moments.emplace( alphaFix, moments_t(alphaFix, m_prefix) );
 
-  for(float alpha : m_alphaVals) {
-    ATH_MSG_DEBUG("Including alpha = " << alpha);
   }
 
-  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+  for( auto const& moment : m_moments ) {
+    ATH_MSG_DEBUG( "Including alpha = " << moment.first );
+  }
 
   return StatusCode::SUCCESS;
+
 }
 
 int NSubjettinessRatiosTool::modifyJet(xAOD::Jet &jet) const {
 
-  for(float alpha : m_alphaVals) {
-    std::string suffix = GetAlphaSuffix(alpha);
+  for( auto const& moment : m_moments ) {
+
+    std::string suffix = moment.second.suffix;
 
-    if (!jet.isAvailable<float>(m_prefix+"Tau1"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau2"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau3"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau4"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau1_wta"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau2_wta"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau3_wta"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau4_wta"+suffix)) {
+    if( !moment.second.acc_Tau1->isAvailable(jet) ||
+        !moment.second.acc_Tau2->isAvailable(jet) ||
+        !moment.second.acc_Tau3->isAvailable(jet) ||
+        !moment.second.acc_Tau4->isAvailable(jet) ||
+        !moment.second.acc_Tau1_wta->isAvailable(jet) ||
+        !moment.second.acc_Tau2_wta->isAvailable(jet) ||
+        !moment.second.acc_Tau3_wta->isAvailable(jet) ||
+        !moment.second.acc_Tau4_wta->isAvailable(jet)) {
 
-      ATH_MSG_ERROR("Tau decorations for " << m_prefix << " with " << suffix << " are not all available. Exiting..");
+      ATH_MSG_ERROR( "Not all " << m_prefix << " Tau decorations with " << suffix << " are available. Exiting." );
       return 1;
+
     }
 
-    if (m_doDichroic) {
-      if (!jet.isAvailable<float>(m_prefix+"Tau2_ungroomed"+suffix) ||
-          !jet.isAvailable<float>(m_prefix+"Tau3_ungroomed"+suffix) ||
-          !jet.isAvailable<float>(m_prefix+"Tau4_ungroomed"+suffix) ||
-          !jet.isAvailable<float>(m_prefix+"Tau2_wta_ungroomed"+suffix) ||
-          !jet.isAvailable<float>(m_prefix+"Tau3_wta_ungroomed"+suffix) ||
-          !jet.isAvailable<float>(m_prefix+"Tau4_wta_ungroomed"+suffix)) {
+    if( m_doDichroic ) {
+
+      if( !moment.second.acc_Tau2_ungroomed->isAvailable(jet) ||
+          !moment.second.acc_Tau3_ungroomed->isAvailable(jet) ||
+          !moment.second.acc_Tau4_ungroomed->isAvailable(jet) ||
+          !moment.second.acc_Tau2_wta_ungroomed->isAvailable(jet) ||
+          !moment.second.acc_Tau3_wta_ungroomed->isAvailable(jet) ||
+          !moment.second.acc_Tau4_wta_ungroomed->isAvailable(jet)) {
 
-        ATH_MSG_ERROR("Ungroomed tau decorations for " << m_prefix << " with " << suffix << " are not all available. Exiting..");
+        ATH_MSG_ERROR( "Not all ungroomed " << m_prefix << " Tau decorations with " << suffix << " are available. Exiting." );
         return 1;
+
       }
+
     }
 
-    // Regular
-    float tau1 = jet.getAttribute<float>(m_prefix+"Tau1"+suffix);
-    float tau2 = jet.getAttribute<float>(m_prefix+"Tau2"+suffix);
-    float tau3 = jet.getAttribute<float>(m_prefix+"Tau3"+suffix);
-    float tau4 = jet.getAttribute<float>(m_prefix+"Tau4"+suffix);
+    /// Regular NSubjettiness
+    float Tau1 = (*moment.second.acc_Tau1)(jet);
+    float Tau2 = (*moment.second.acc_Tau2)(jet);
+    float Tau3 = (*moment.second.acc_Tau3)(jet);
+    float Tau4 = (*moment.second.acc_Tau4)(jet);
 
-    float tau2_ungroomed = -999.0;
-    float tau3_ungroomed = -999.0;
-    float tau4_ungroomed = -999.0;
+    float Tau2_ungroomed = -999.0;
+    float Tau3_ungroomed = -999.0;
+    float Tau4_ungroomed = -999.0;
 
-    if (m_doDichroic) {
-      tau2_ungroomed = jet.getAttribute<float>(m_prefix+"Tau2_ungroomed"+suffix);
-      tau3_ungroomed = jet.getAttribute<float>(m_prefix+"Tau3_ungroomed"+suffix);
-      tau4_ungroomed = jet.getAttribute<float>(m_prefix+"Tau4_ungroomed"+suffix);
+    if( m_doDichroic ) {
+      Tau2_ungroomed = (*moment.second.acc_Tau2_ungroomed)(jet);
+      Tau3_ungroomed = (*moment.second.acc_Tau3_ungroomed)(jet);
+      Tau4_ungroomed = (*moment.second.acc_Tau4_ungroomed)(jet);
     }
 
-    //Prevent div-0 and check against default value (-999) of the decoration
-    if(tau1 > 1e-8) {
-      jet.setAttribute(m_prefix+"Tau21"+suffix, tau2/tau1);
-      if(tau2_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"Tau21_dichroic"+suffix, tau2_ungroomed/tau1);
-      else
-        jet.setAttribute(m_prefix+"Tau21_dichroic"+suffix, -999.0);
-    }
-    else {
-      jet.setAttribute(m_prefix+"Tau21"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"Tau21_dichroic"+suffix, -999.0);
-    }
+    float Tau21 = -999.0;
+    float Tau32 = -999.0;
+    float Tau42 = -999.0;
 
-    //Prevent div-0 and check against default value (-999) of the decoration
-    if(tau2 > 1e-8) {
-      jet.setAttribute(m_prefix+"Tau32"+suffix, tau3/tau2);
-      jet.setAttribute(m_prefix+"Tau42"+suffix, tau4/tau2);
+    float Tau21_dichroic = -999.0;
+    float Tau32_dichroic = -999.0;
+    float Tau42_dichroic = -999.0;
 
-      if(tau3_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"Tau32_dichroic"+suffix, tau3_ungroomed/tau2);
-      else
-        jet.setAttribute(m_prefix+"Tau32_dichroic"+suffix, -999.0);
+    /// Prevent div-0 and check against default value (-999) of the decoration
+    if( Tau1 > 1e-8 ) {
 
-      if(tau4_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"Tau42_dichroic"+suffix, tau4_ungroomed/tau2);
-      else
-        jet.setAttribute(m_prefix+"Tau42_dichroic"+suffix, -999.0);
-    }
-    else {
-      jet.setAttribute(m_prefix+"Tau32"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"Tau42"+suffix, -999.0);
+      Tau21 = Tau2 / Tau1;
+
+      if( Tau2_ungroomed > 1e-8 ) {
+        Tau21_dichroic = Tau2_ungroomed/Tau1;
+      }
 
-      jet.setAttribute(m_prefix+"Tau32_dichroic"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"Tau42_dichroic"+suffix, -999.0);
     }
 
-    float tau1_wta = jet.getAttribute<float>(m_prefix+"Tau1_wta"+suffix);
-    float tau2_wta = jet.getAttribute<float>(m_prefix+"Tau2_wta"+suffix);
-    float tau3_wta = jet.getAttribute<float>(m_prefix+"Tau3_wta"+suffix);
-    float tau4_wta = jet.getAttribute<float>(m_prefix+"Tau4_wta"+suffix);
+    /// Prevent div-0 and check against default value (-999) of the decoration
+    if( Tau2 > 1e-8 ) {
 
-    float tau2_wta_ungroomed = -999.0;
-    float tau3_wta_ungroomed = -999.0;
-    float tau4_wta_ungroomed = -999.0;
+      Tau32 = Tau3 / Tau2;
+      Tau42 = Tau4 / Tau2;
 
-    if (m_doDichroic) {
-      tau2_wta_ungroomed = jet.getAttribute<float>(m_prefix+"Tau2_wta_ungroomed"+suffix);
-      tau3_wta_ungroomed = jet.getAttribute<float>(m_prefix+"Tau3_wta_ungroomed"+suffix);
-      tau4_wta_ungroomed = jet.getAttribute<float>(m_prefix+"Tau4_wta_ungroomed"+suffix);
-    }
+      if(Tau3_ungroomed > 1e-8) {
+        Tau32_dichroic = Tau3_ungroomed / Tau2;
+      }
+
+      if(Tau4_ungroomed > 1e-8) {
+        Tau42_dichroic = Tau4_ungroomed / Tau2;
+      }
 
-    // WTA
-    //Prevent div-0 and check against default value (-999) of the decoration
-    if(tau1_wta > 1e-8) {
-      jet.setAttribute(m_prefix+"Tau21_wta"+suffix, tau2_wta/tau1_wta);
-      if(tau2_wta_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"Tau21_wta_dichroic"+suffix, tau2_wta_ungroomed/tau1_wta);
-      else
-        jet.setAttribute(m_prefix+"Tau21_wta_dichroic"+suffix, -999.0);
     }
-    else {
-      jet.setAttribute(m_prefix+"Tau21_wta"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"Tau21_wta_dichroic"+suffix, -999.0);
+
+    /// WTA NSubjettiness
+    float Tau1_wta = (*moment.second.acc_Tau1_wta)(jet);
+    float Tau2_wta = (*moment.second.acc_Tau2_wta)(jet);
+    float Tau3_wta = (*moment.second.acc_Tau3_wta)(jet);
+    float Tau4_wta = (*moment.second.acc_Tau4_wta)(jet);
+
+    float Tau2_wta_ungroomed = -999.0;
+    float Tau3_wta_ungroomed = -999.0;
+    float Tau4_wta_ungroomed = -999.0;
+
+    if( m_doDichroic ) {
+      Tau2_wta_ungroomed = (*moment.second.acc_Tau2_wta_ungroomed)(jet);
+      Tau3_wta_ungroomed = (*moment.second.acc_Tau3_wta_ungroomed)(jet);
+      Tau4_wta_ungroomed = (*moment.second.acc_Tau4_wta_ungroomed)(jet);
     }
 
-    //Prevent div-0 and check against default value (-999) of the decoration
-    if(tau2_wta > 1e-8) {
-      jet.setAttribute(m_prefix+"Tau32_wta"+suffix, tau3_wta/tau2_wta);
-      jet.setAttribute(m_prefix+"Tau42_wta"+suffix, tau4_wta/tau2_wta);
+    float Tau21_wta = -999.0;
+    float Tau32_wta = -999.0;
+    float Tau42_wta = -999.0;
+
+    float Tau21_wta_dichroic = -999.0;
+    float Tau32_wta_dichroic = -999.0;
+    float Tau42_wta_dichroic = -999.0;
 
-      if(tau3_wta_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"Tau32_wta_dichroic"+suffix, tau3_wta_ungroomed/tau2_wta);
-      else
-        jet.setAttribute(m_prefix+"Tau32_wta_dichroic"+suffix, -999.0);
+    /// Prevent div-0 and check against default value (-999) of the decoration
+    if( Tau1_wta > 1e-8 ) {
+
+      Tau21_wta = Tau2_wta / Tau1_wta;
+
+      if( Tau2_wta_ungroomed > 1e-8 ) {
+        Tau21_wta_dichroic = Tau2_wta_ungroomed / Tau1_wta;
+      }
 
-      if(tau4_wta_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"Tau42_wta_dichroic"+suffix, tau4_wta_ungroomed/tau2_wta);
-      else
-        jet.setAttribute(m_prefix+"Tau42_wta_dichroic"+suffix, -999.0);
     }
-    else {
-      jet.setAttribute(m_prefix+"Tau32_wta"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"Tau42_wta"+suffix, -999.0);
 
-      jet.setAttribute(m_prefix+"Tau32_wta_dichroic"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"Tau42_wta_dichroic"+suffix, -999.0);
+    /// Prevent div-0 and check against default value (-999) of the decoration
+    if( Tau2_wta > 1e-8 ) {
+
+      Tau32_wta = Tau3_wta / Tau2_wta;
+      Tau42_wta = Tau4_wta / Tau2_wta;
+
+      if( Tau3_wta_ungroomed > 1e-8 ) {
+        Tau32_wta_dichroic = Tau3_wta_ungroomed / Tau2_wta;
+      }
+
+      if(Tau4_wta_ungroomed > 1e-8) {
+        Tau42_wta_dichroic = Tau4_wta_ungroomed / Tau2_wta;
+      }
+
     }
+
+    (*moment.second.dec_Tau21)(jet) = Tau21;
+    (*moment.second.dec_Tau32)(jet) = Tau32;
+    (*moment.second.dec_Tau42)(jet) = Tau42;
+
+    (*moment.second.dec_Tau21_dichroic)(jet) = Tau21_dichroic;
+    (*moment.second.dec_Tau32_dichroic)(jet) = Tau32_dichroic;
+    (*moment.second.dec_Tau42_dichroic)(jet) = Tau42_dichroic;
+
+    (*moment.second.dec_Tau21_wta)(jet) = Tau21_wta;
+    (*moment.second.dec_Tau32_wta)(jet) = Tau32_wta;
+    (*moment.second.dec_Tau42_wta)(jet) = Tau42_wta;
+
+    (*moment.second.dec_Tau21_wta_dichroic)(jet) = Tau21_wta_dichroic;
+    (*moment.second.dec_Tau32_wta_dichroic)(jet) = Tau32_wta_dichroic;
+    (*moment.second.dec_Tau42_wta_dichroic)(jet) = Tau42_wta_dichroic;
+
   }
 
   return 0;
+
 }
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessTool.cxx b/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessTool.cxx
index b71d2b1d160703d5420f72dbd7d7dca0bc193faf..3999d0d7909192a2497bcbff51755a7ecf32c304 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessTool.cxx
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessTool.cxx
@@ -9,42 +9,54 @@
 NSubjettinessTool::NSubjettinessTool(std::string name) : 
   JetSubStructureMomentToolsBase(name)
 {
-  declareProperty("Alpha", m_Alpha = 1.0);
-  declareProperty("AlphaList", m_rawAlphaVals = {});
+  declareProperty("Alpha",      m_Alpha = 1.0);
+  declareProperty("AlphaList",  m_rawAlphaVals = {});
   declareProperty("DoDichroic", m_doDichroic = false);
 }
 
 StatusCode NSubjettinessTool::initialize() {
-  // Add alpha = 1.0 by default
-  m_alphaVals.push_back(1.0);
+  
+  /// Call base class initialize to fix up m_prefix
+  ATH_CHECK( JetSubStructureMomentToolsBase::initialize() );
+
+  /// Add alpha = 1.0 by default
+  m_moments.emplace( 1.0, moments_t(1.0, m_prefix) );
+
+  /// Add alpha = m_Alpha by default to keep backwards compatibility
+  if( std::abs(m_Alpha-1.0) > 1.0e-5 ) {
+    
+    /// Give warning about deprecation
+    ATH_MSG_WARNING( "The Alpha property is deprecated, please use the AlphaList property to provide a list of values" );
 
-  // Add alpha = m_Alpha by default to keep backwards compatibility
-  if( std::abs(m_Alpha-1.0) > 1.0e-5 ) m_alphaVals.push_back(m_Alpha);
+    /// Use m_Alpha to not break analysis code
+    m_moments.emplace( m_Alpha, moments_t(m_Alpha, m_prefix) );
+  
+  }
 
-  // Clean up input list of alpha values
-  for(float alpha : m_rawAlphaVals) {
+  /// Clean up input list of alpha values
+  for( float alpha : m_rawAlphaVals ) {
     
-    // Round to the nearest 0.1
+    /// Round to the nearest 0.1
     float alphaFix = round( alpha * 10.0 ) / 10.0;
-    if(std::abs(alpha-alphaFix) > 1.0e-5) ATH_MSG_DEBUG("alpha = " << alpha << " has been rounded to " << alphaFix);
+    if( std::abs(alpha-alphaFix) > 1.0e-5 ) ATH_MSG_DEBUG( "alpha = " << alpha << " has been rounded to " << alphaFix );
 
-    // Skip negative values of alpha
-    if(alphaFix < 0.0) {
-      ATH_MSG_WARNING("alpha must be positive. Skipping alpha = " << alpha);
+    /// Skip negative values of alpha
+    if( alphaFix < 0.0 ) {
+      ATH_MSG_WARNING( "alpha must be positive. Skipping alpha = " << alpha );
       continue;
     }
 
-    // Only store value if it is not already in the list
-    if( std::find(m_alphaVals.begin(), m_alphaVals.end(), alphaFix) == m_alphaVals.end() ) m_alphaVals.push_back(alphaFix);
-  }
+    /// Store value. std::map::emplace prevents duplicate entries
+    m_moments.emplace( alphaFix, moments_t(alphaFix, m_prefix) );
 
-  for(float alpha : m_alphaVals) {
-    ATH_MSG_DEBUG("Including alpha = " << alpha);
   }
 
-  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+  for( auto const& moment : m_moments ) {
+    ATH_MSG_DEBUG( "Including alpha = " << moment.first );
+  }
 
   return StatusCode::SUCCESS;
+
 }
 
 int NSubjettinessTool::modifyJet(xAOD::Jet &injet) const {
@@ -52,20 +64,25 @@ int NSubjettinessTool::modifyJet(xAOD::Jet &injet) const {
   fastjet::PseudoJet jet;
   fastjet::PseudoJet jet_ungroomed;
 
-  bool decorate = SetupDecoration(jet,injet);
-  bool decorate_ungroomed = false;
-  if(m_doDichroic) {
-    // Get parent jet here and replace injet
-    ElementLink<xAOD::JetContainer> parentLink = injet.auxdata<ElementLink<xAOD::JetContainer> >("Parent");
+  /// Bool to decide whether calculation should be performed
+  bool calculate = SetupDecoration(jet,injet);
+
+  /// Bool to decide if ungroomed jet moments should be calculated
+  bool calculate_ungroomed = false;
   
-    // Return error is parent element link is broken
-    if(!parentLink.isValid()) {
-      ATH_MSG_ERROR("Parent element link is not valid. Aborting");
+  if( m_doDichroic ) {
+
+    /// Get parent jet
+    ElementLink<xAOD::JetContainer> parentLink = injet.auxdata<ElementLink<xAOD::JetContainer> >("Parent");
+
+    /// Return error is parent element link is broken
+    if( !parentLink.isValid() ) {
+      ATH_MSG_ERROR( "Parent element link is not valid. Aborting" );
       return 1;
     }
 
     const xAOD::Jet* parentJet = *(parentLink);
-    decorate_ungroomed = SetupDecoration(jet_ungroomed,*parentJet);
+    calculate_ungroomed = SetupDecoration(jet_ungroomed,*parentJet);
   }
 
   // Supress a warning about undefined behavior in the fastjet
@@ -76,27 +93,35 @@ int NSubjettinessTool::modifyJet(xAOD::Jet &injet) const {
   std::call_once (oflag, CxxUtils::ubsan_suppress,
                   []() { fastjet::contrib::WTA_KT_Axes x; });
 
-  for(float alpha : m_alphaVals) {
-
-    if(alpha < 0.0) {
-      ATH_MSG_WARNING("Negative alpha values are not supported. Skipping " << alpha);
-      continue;
-    }
+  for( auto const& moment : m_moments ) {
 
-    std::string suffix = GetAlphaSuffix(alpha);
+    float alpha = moment.first;
 
+    /// This needs to be redone for each jet since it depends on the size parameter
     fastjet::contrib::NormalizedCutoffMeasure normalized_measure(alpha, injet.getSizeParameter(), 1000000);
 
-    // Groomed jet moments
-    float Tau1_value = -999, Tau2_value = -999, Tau3_value = -999, Tau4_value = -999,
-          Tau1_wta_value = -999, Tau2_wta_value = -999, Tau3_wta_value = -999, Tau4_wta_value = -999;
+    float Tau1_value = -999;
+    float Tau2_value = -999;
+    float Tau3_value = -999;
+    float Tau4_value = -999;
+    
+    float Tau2_ungroomed_value = -999;
+    float Tau3_ungroomed_value = -999;
+    float Tau4_ungroomed_value = -999;
+    
+    float Tau1_wta_value = -999;
+    float Tau2_wta_value = -999;
+    float Tau3_wta_value = -999;
+    float Tau4_wta_value = -999;
 
-    // Ungroomed jet moments
-    float Tau2_ungroomed_value = -999, Tau3_ungroomed_value = -999, Tau4_ungroomed_value = -999,
-          Tau2_wta_ungroomed_value = -999, Tau3_wta_ungroomed_value = -999, Tau4_wta_ungroomed_value = -999;
+    float Tau2_wta_ungroomed_value = -999;
+    float Tau3_wta_ungroomed_value = -999;
+    float Tau4_wta_ungroomed_value = -999;
 
-    if (decorate) {
+    if( calculate ) {
 
+      /// These calculators need to be created for each jet due to
+      /// the jet size parameter dependence in the normalized measure
       fastjet::contrib::KT_Axes kt_axes;
       JetSubStructureUtils::Nsubjettiness tau1(1, kt_axes, normalized_measure);
       JetSubStructureUtils::Nsubjettiness tau2(2, kt_axes, normalized_measure);
@@ -108,12 +133,14 @@ int NSubjettinessTool::modifyJet(xAOD::Jet &injet) const {
       Tau3_value = tau3.result(jet);
       Tau4_value = tau4.result(jet);
 
-      if(decorate_ungroomed) {
+      if( calculate_ungroomed ) {
         Tau2_ungroomed_value = tau2.result(jet_ungroomed);
         Tau3_ungroomed_value = tau3.result(jet_ungroomed);
         Tau4_ungroomed_value = tau4.result(jet_ungroomed);
       }
 
+      /// These calculators need to be created for each jet due to
+      /// the jet size parameter dependence in the normalized measure
       fastjet::contrib::WTA_KT_Axes wta_kt_axes;
       JetSubStructureUtils::Nsubjettiness tau1_wta(1, wta_kt_axes, normalized_measure);
       JetSubStructureUtils::Nsubjettiness tau2_wta(2, wta_kt_axes, normalized_measure);
@@ -125,7 +152,7 @@ int NSubjettinessTool::modifyJet(xAOD::Jet &injet) const {
       Tau3_wta_value = tau3_wta.result(jet);
       Tau4_wta_value = tau4_wta.result(jet);
 
-      if(decorate_ungroomed) {
+      if( calculate_ungroomed ) {
         Tau2_wta_ungroomed_value = tau2_wta.result(jet_ungroomed);
         Tau3_wta_ungroomed_value = tau3_wta.result(jet_ungroomed);
         Tau4_wta_ungroomed_value = tau4_wta.result(jet_ungroomed);
@@ -133,27 +160,26 @@ int NSubjettinessTool::modifyJet(xAOD::Jet &injet) const {
 
     }
 
-    // Groomed jet moments
-    injet.setAttribute(m_prefix+"Tau1"+suffix, Tau1_value);
-    injet.setAttribute(m_prefix+"Tau2"+suffix, Tau2_value);
-    injet.setAttribute(m_prefix+"Tau3"+suffix, Tau3_value);
-    injet.setAttribute(m_prefix+"Tau4"+suffix, Tau4_value);
-
-    injet.setAttribute(m_prefix+"Tau1_wta"+suffix, Tau1_wta_value);
-    injet.setAttribute(m_prefix+"Tau2_wta"+suffix, Tau2_wta_value);
-    injet.setAttribute(m_prefix+"Tau3_wta"+suffix, Tau3_wta_value);
-    injet.setAttribute(m_prefix+"Tau4_wta"+suffix, Tau4_wta_value);
+    (*moment.second.dec_Tau1)(injet) = Tau1_value;
+    (*moment.second.dec_Tau2)(injet) = Tau2_value;
+    (*moment.second.dec_Tau3)(injet) = Tau3_value;
+    (*moment.second.dec_Tau4)(injet) = Tau4_value;
+    
+    (*moment.second.dec_Tau2_ungroomed)(injet) = Tau2_ungroomed_value;
+    (*moment.second.dec_Tau3_ungroomed)(injet) = Tau3_ungroomed_value;
+    (*moment.second.dec_Tau4_ungroomed)(injet) = Tau4_ungroomed_value;
 
-    // Ungroomed jet moments
-    injet.setAttribute(m_prefix+"Tau2_ungroomed"+suffix, Tau2_ungroomed_value);
-    injet.setAttribute(m_prefix+"Tau3_ungroomed"+suffix, Tau3_ungroomed_value);
-    injet.setAttribute(m_prefix+"Tau4_ungroomed"+suffix, Tau4_ungroomed_value);
+    (*moment.second.dec_Tau1_wta)(injet) = Tau1_wta_value;
+    (*moment.second.dec_Tau2_wta)(injet) = Tau2_wta_value;
+    (*moment.second.dec_Tau3_wta)(injet) = Tau3_wta_value;
+    (*moment.second.dec_Tau4_wta)(injet) = Tau4_wta_value;
 
-    injet.setAttribute(m_prefix+"Tau2_wta_ungroomed"+suffix, Tau2_wta_ungroomed_value);
-    injet.setAttribute(m_prefix+"Tau3_wta_ungroomed"+suffix, Tau3_wta_ungroomed_value);
-    injet.setAttribute(m_prefix+"Tau4_wta_ungroomed"+suffix, Tau4_wta_ungroomed_value);
+    (*moment.second.dec_Tau2_wta_ungroomed)(injet) = Tau2_wta_ungroomed_value;
+    (*moment.second.dec_Tau3_wta_ungroomed)(injet) = Tau3_wta_ungroomed_value;
+    (*moment.second.dec_Tau4_wta_ungroomed)(injet) = Tau4_wta_ungroomed_value;
 
   }
 
   return 0;
+
 }
diff --git a/Reconstruction/MVAUtils/util/convertXGBoostToRootTree.py b/Reconstruction/MVAUtils/util/convertXGBoostToRootTree.py
index 3aa1ff95fde9453fea92f2e78fbc60eb420327d9..96b7bca5e5ed7b6746e0c00947d55ee22992cff5 100755
--- a/Reconstruction/MVAUtils/util/convertXGBoostToRootTree.py
+++ b/Reconstruction/MVAUtils/util/convertXGBoostToRootTree.py
@@ -159,6 +159,9 @@ def test(model_file, tree_file, objective, tree_name='xgboost', ntests=10000, te
     if 'binary' in objective:
         logging.info("testing binary")
         return test_binary(bst, mva_utils, objective, ntests, test_file)
+    elif 'multi' in objective:
+        logging.info("testing multi-class")
+        return test_multiclass(bst,mva_utils, objective, ntests, test_file)
     else:
         logging.info("testing regression")
         return test_regression(bst, mva_utils, objective, ntests, test_file)
@@ -202,7 +205,6 @@ def test_regression(booster, mva_utils, objective, ntests=10000, test_file=None)
 def test_binary(booster, mva_utils, objective, ntests=10000, test_file=None):
     import numpy as np
     logging.info("Testing input features with binary classification")
-    print(test_file)
     if test_file is not None:
         data_input = np.load(test_file)
         logging.info("using as input %s inputs from file %s", len(data_input), test_file)
@@ -234,6 +236,44 @@ def test_binary(booster, mva_utils, objective, ntests=10000, test_file=None):
             return False
     return True
 
+def test_multiclass(booster, mva_utils, objective, ntests=10000, test_file=None):
+    import numpy as np
+    logging.info("using multiclass model")
+
+    if test_file is not None:
+        data_input = np.load(test_file)
+        logging.info("using as input %s inputs from file %s", len(data_input), test_file)
+    else:
+        logging.error("Please provide an input test file for testing")
+
+    start = time.time()
+    dTest = xgb.DMatrix(data_input)
+    results_xgboost = booster.predict(dTest)
+    ##Extract the number of classes from the python prediction
+    nclasses = results_xgboost.shape[1]
+    logging.info("xgboost (vectorized) timing = %s ms/input", (time.time() - start) * 1000 / len(data_input))
+
+    input_values_vector = ROOT.std.vector("float")()
+    results_MVAUtils = []
+    start = time.time()
+    for input_values in data_input:
+        input_values_vector.clear()
+        for v in input_values:
+            input_values_vector.push_back(v)
+        output_MVAUtils = mva_utils.GetMultiResponse(input_values_vector, nclasses)
+        results_MVAUtils.append(output_MVAUtils)
+
+    logging.info("mvautils (not vectorized+overhead) timing = %s ms/input", (time.time() - start) * 1000 / len(data_input))
+
+    for input_values, output_xgb, output_MVAUtils in zip(data_input, results_xgboost, results_MVAUtils):
+        if not np.allclose(output_xgb, output_MVAUtils):
+            logging.info("output are different:"
+                         "mvautils: %s\n"
+                         "xgboost: %s\n"
+                         "inputs: %s", output_MVAUtils, output_xgb, input_values)
+            return False
+    return True
+
 
 def check_file(fn):
     f = ROOT.TFile.Open(fn)
@@ -262,13 +302,13 @@ if __name__ == "__main__":
     parser.add_argument('--no-test', action='store_true', help="don't run test (not suggested)")
     parser.add_argument('--ntests', type=int, default=1000, help="number of random test, default=1000")
     parser.add_argument('--test-file', type=str, help='numpy table')
-    parser.add_argument('--objective', type=str, help='Specify the learning task and the corresponding learning objective, currently support options: binary:logistic, reg:linear(squarederror)')
+    parser.add_argument('--objective', type=str, help='Specify the learning task and the corresponding learning objective, currently support options: binary:logistic, reg:linear(squarederror), multi:softprob')
 
     args = parser.parse_args()
     logging.info("converting input file %s to root file %s", args.input, args.output)
 
-    #  'reg:linear'is been named as 'reg:squarederror' in newer version of xgboost (> 0.90) 
-    supported_objective = ['binary:logistic', 'reg:linear', 'reg:squarederror']
+    #  'reg:linear'is been named as 'reg:squarederror' in newer version of xgboost (> 0.90)
+    supported_objective = ['binary:logistic', 'reg:linear', 'reg:squarederror','multi:softprob']
 
     if args.objective not in supported_objective:
         parser.error('''
@@ -276,6 +316,7 @@ if __name__ == "__main__":
                      Only the following objectives are supported and tested:
                      - binary:logistic
                      - reg:linear(or squarederror)
+                     - multi:softprob
                      ''')
 
     if not args.input:
@@ -290,6 +331,8 @@ if __name__ == "__main__":
         print("model has not been tested. Do not use it production!")
     else:
         logging.info("testing model")
+        if not args.test_file:
+            parser.error("Attempting to do test but no test file was provided, pass this with '--test-file <test_file> or use option '--no_test' ")
         if not check_file(args.output):
             print("problem when checking file")
         result = test(args.input, args.output, args.objective, args.tree_name, args.ntests, args.test_file)
@@ -328,3 +371,17 @@ MVAUtils::BDT my_bdt(tree);
 // ...
 float output = my_bdt.Predict(input_values);
                 ''' % (args.output, output_treename, len(data[0])))
+            elif "multi" in objective:
+                print('''In c++ use your BDT as:
+#include "MVAUtils/BDT.h"
+
+TFile* f = TFile::Open("%s");
+TTree* tree = nullptr;
+f->GetObject("%s", tree);
+MVAUtils::BDT my_bdt(tree);
+// ...
+// std::vector<float> input_values(%d, 0.);
+// fill the vector using the order as in the trainig
+// ...
+float output = my_bdt.GetMultiResponse(input_values, nclasses);
+''' % (args.output, output_treename, len(data[0])))
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCaloTagTool.cxx b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCaloTagTool.cxx
index cb54becfc0e1bb6836e301706bce9ebdf660701c..9dfdec550926a9a1ed8b0c06150fe91d03bc4a2e 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCaloTagTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCaloTagTool.cxx
@@ -13,7 +13,6 @@
 //  (c) ATLAS Combined Muon software
 //////////////////////////////////////////////////////////////////////////////
 
-//<<<<<< INCLUDES                                                       >>>>>>
 
 #include "MuonCombinedToolInterfaces/IMuonCombinedTagTool.h"
 #include "MuonCombinedEvent/InDetCandidate.h"
@@ -42,7 +41,6 @@
 
 namespace MuonCombined {
  
-  //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
 
   MuonCaloTagTool::MuonCaloTagTool (const std::string& type, const std::string& name, const IInterface* parent)
     :	AthAlgTool(type, name, parent),
@@ -92,7 +90,6 @@ namespace MuonCombined {
   MuonCaloTagTool::~MuonCaloTagTool()
   {}
 
-  //<<<<<< PUBLIC MEMBER FUNCTION DEFINITIONS                             >>>>>>
 
   StatusCode MuonCaloTagTool::initialize() {
     
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonSegmentTagTool.cxx b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonSegmentTagTool.cxx
index 4ba31bc953e8efbb799e022007542993bd651320..5d9f4211223e11fd1ecafc3619e6f1acaa03c03f 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonSegmentTagTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonSegmentTagTool.cxx
@@ -55,7 +55,7 @@ namespace MuonCombined {
 	m_printer("Muon::MuonEDMPrinterTool/MuonEDMPrinterTool"),
 	p_MuTagMatchingTool("MuTagMatchingTool/MuTagMatchingTool") ,
 	p_MuTagAmbiguitySolverTool("MuTagAmbiguitySolverTool/MuTagAmbiguitySolverTool") ,
-  m_caloExtensionTool("Trk::ParticleCaloExtensionTool/ParticleCaloExtensionTool", this),
+  	m_caloExtensionTool("Trk::ParticleCaloExtensionTool/ParticleCaloExtensionTool", this),
 	m_segmentSelector("Muon::MuonSegmentSelectionTool/MuonSegmentSelectionTool"),
 	m_hitSummaryTool("Muon::MuonSegmentHitSummaryTool/MuonSegmentHitSummaryTool"),
 	m_surfaces(0),
@@ -119,38 +119,44 @@ namespace MuonCombined {
     return StatusCode::SUCCESS;
   }
 
-  StatusCode MuonSegmentTagTool::finalize() {
-    delete m_surfaces;
-    ATH_MSG_INFO( "Total number of considered ID tracks         " << m_ntotTracks);
-    ATH_MSG_INFO( "Total number of ID tracks with angular match " << m_nangleMatch);
-    ATH_MSG_INFO( "Total number of preselected ID tracks        " << m_npmatch);
-    ATH_MSG_INFO( "Total number of ID tracks at MS entry        " << m_natMSEntrance);
-    ATH_MSG_INFO( "Total number of accepted ID tracks           " << m_naccepted);
-    for( unsigned int i=0;i<12;++i ){
-      double ratio = m_extrapolated[i] == 0 ? 0 : m_goodExtrapolated[i]/(double)m_extrapolated[i];
-      ATH_MSG_INFO( "Layer " << i << " extrap " << m_extrapolated[i] << " good " << m_goodExtrapolated[i] << " ratio " << ratio );
-    }
-    return StatusCode::SUCCESS;
+  StatusCode MuonSegmentTagTool::finalize()
+  {
+	  delete m_surfaces;
+	  ATH_MSG_INFO("Total number of considered ID tracks         " << m_ntotTracks);
+	  ATH_MSG_INFO("Total number of ID tracks with angular match " << m_nangleMatch);
+	  ATH_MSG_INFO("Total number of preselected ID tracks        " << m_npmatch);
+	  ATH_MSG_INFO("Total number of ID tracks at MS entry        " << m_natMSEntrance);
+	  ATH_MSG_INFO("Total number of accepted ID tracks           " << m_naccepted);
+	  for (unsigned int i = 0; i < 12; ++i)
+	  {
+		  double ratio = m_extrapolated[i] == 0 ? 0 : m_goodExtrapolated[i] / (double)m_extrapolated[i];
+		  ATH_MSG_INFO("Layer " << i << " extrap " << m_extrapolated[i] << " good " << m_goodExtrapolated[i] << " ratio " << ratio);
+	  }
+	  return StatusCode::SUCCESS;
   }
 
-  void MuonSegmentTagTool::tag( const InDetCandidateCollection& inDetCandidates, const xAOD::MuonSegmentContainer& xaodSegments, InDetCandidateToTagMap* tagMap ) const {
-
-    // loop over segments are extract MuonSegments + create links between segments and xAOD segments
-    std::map< const Muon::MuonSegment*, ElementLink<xAOD::MuonSegmentContainer> > segmentToxAODSegmentMap;
-    std::vector< const Muon::MuonSegment* > segments;
-    segments.reserve(xaodSegments.size());
-    unsigned int index = 0;
-    for( auto it = xaodSegments.begin();it!=xaodSegments.end();++it,++index ){
-      if( !(*it)->muonSegment().isValid() ) continue;
-      const Muon::MuonSegment* mseg = dynamic_cast<const Muon::MuonSegment*>(*(*it)->muonSegment());
-      ElementLink<xAOD::MuonSegmentContainer> link(xaodSegments,index);
-      link.toPersistent();
-      if( mseg ) {
-        segments.push_back(mseg);
-        segmentToxAODSegmentMap[mseg] = link;
-      }
-    }
-    tag(inDetCandidates, segments, &segmentToxAODSegmentMap, tagMap);
+  void MuonSegmentTagTool::tag(const InDetCandidateCollection &inDetCandidates, const xAOD::MuonSegmentContainer &xaodSegments, InDetCandidateToTagMap *tagMap) const
+  {
+
+	  // loop over segments are extract MuonSegments + create links between segments and xAOD segments
+	  std::map<const Muon::MuonSegment *, ElementLink<xAOD::MuonSegmentContainer>> segmentToxAODSegmentMap;
+	  std::vector<const Muon::MuonSegment *> segments;
+	  segments.reserve(xaodSegments.size());
+	  unsigned int index = 0;
+	  for (auto it = xaodSegments.begin(); it != xaodSegments.end(); ++it, ++index)
+	  {
+		  if (!(*it)->muonSegment().isValid())
+			  continue;
+		  const Muon::MuonSegment *mseg = dynamic_cast<const Muon::MuonSegment *>(*(*it)->muonSegment());
+		  ElementLink<xAOD::MuonSegmentContainer> link(xaodSegments, index);
+		  link.toPersistent();
+		  if (mseg)
+		  {
+			  segments.push_back(mseg);
+			  segmentToxAODSegmentMap[mseg] = link;
+		  }
+	  }
+	  tag(inDetCandidates, segments, &segmentToxAODSegmentMap, tagMap);
   }
   //todo: fix segmentToxAODSegmentMap
   void MuonSegmentTagTool::tag( const InDetCandidateCollection& inDetCandidates, const std::vector<const Muon::MuonSegment*>& segments, 
@@ -266,15 +272,15 @@ namespace MuonCombined {
       ATH_MSG_VERBOSE( "========================== dumping the full track =========================" );
       ATH_MSG_VERBOSE( *track );
 
-      const Trk::TrackSummary* summary =  track->trackSummary() ; // Summary retrieved from TrackParticle (not from Track: it might be absent there)
       bool trkEtaInfo(false);
-      if( !summary ) {
-	ATH_MSG_WARNING( "Track has no trackSummary ! No ID eta information retrieved !" );
-      } else {
-	unsigned int nrIDetaHits = summary->get( Trk::numberOfSCTHits ) +  summary->get( Trk::numberOfPixelHits ) ;
-	if( nrIDetaHits >=5 ) trkEtaInfo = true;
-	if( !trkEtaInfo ) ATH_MSG_DEBUG( "Track has no ID eta information! (" << nrIDetaHits << " etaHits)" );
-      }
+	  uint8_t numSCTHits = 0; uint8_t numPixelHits=0;
+	  if (!idTP->indetTrackParticle().summaryValue( numSCTHits, xAOD::numberOfSCTHits ) ) ATH_MSG_DEBUG("TrackParticle missing numberOfSCTHits");
+	  if (!idTP->indetTrackParticle().summaryValue( numPixelHits, xAOD::numberOfPixelHits ) )  ATH_MSG_DEBUG("TrackParticle missing numberOfPixelHits");
+	  
+	  unsigned int nrIDetaHits = numSCTHits +  numPixelHits;
+	  if( nrIDetaHits >=5 ) trkEtaInfo = true;
+	  if( !trkEtaInfo ) ATH_MSG_DEBUG( "Track has no ID eta information! (" << nrIDetaHits << " etaHits)" );
+      
       ++m_ntotTracks;
       bool hasMatch = m_doBidirectional;
       if( !m_doBidirectional ){
@@ -605,7 +611,7 @@ namespace MuonCombined {
 
 	      MuonCombined::MuonSegmentInfo info = p_MuTagMatchingTool->muTagSegmentInfo(track,*itSeg,atSegSurface) ;
 	      if(segmentToxAODSegmentMap)
-		info.link = (*segmentToxAODSegmentMap)[*itSeg];
+			info.link = (*segmentToxAODSegmentMap)[*itSeg];
 		//              ATH_MSG_DEBUG( " MuTagSegmentInfo  matchPosition  pullY " <<  info.pullY << " pullX " << info.pullX << " resY " <<  info.resY << " resX " << info.resX << " exErrorY " <<  info.exErrorY << " ex errorX " << info.exErrorX << " seg errorY " << info.segErrorY << " seg errorX " << info.segErrorX );
 	      //              ATH_MSG_DEBUG( " MuTagSegmentInfo matchDirection pullYZ " <<  info.pullYZ << " pullXZ " << info.pullXZ << " resYZ " <<  info.dangleYZ << " resXZ " << info.dangleXZ << " exErrorYZ " <<  info.exErrorYZ << " ex errorXZ " << info.exErrorXZ << " seg errorYZ " << info.segErrorYZ << " seg errorXZ " << info.segErrorXZ );
 	      //              ATH_MSG_DEBUG( " MuTagSegmentInfo matchDistance hasPhi " << info.hasPhi << " resX " << info.resX << " dangleXZ " << info.dangleXZ << " maximumResidualAlongTube " << info.maximumResidualAlongTube << " resY " << info.resY << " dangleYZ " << info.dangleYZ );    
@@ -614,15 +620,19 @@ namespace MuonCombined {
 
 	      isMatched =  p_MuTagMatchingTool->matchSegmentPosition( &info,trkEtaInfo);
 
-	      if( !isMatched ){  
-		if( m_doTable ){
-		  if( !trkEtaInfo ) segVsSurf[segmentCount] = "posPhi" ;
-		  else segVsSurf[segmentCount] = "pos" ;
-		}
-		delete atSegSurface;
-		continue;	
-	      } 
-	      isMatched =  p_MuTagMatchingTool->matchSegmentDirection( &info,trkEtaInfo);
+		  if (!isMatched)
+		  {
+			  if (m_doTable)
+			  {
+				  if (!trkEtaInfo)
+					  segVsSurf[segmentCount] = "posPhi";
+				  else
+					  segVsSurf[segmentCount] = "pos";
+			  }
+			  delete atSegSurface;
+			  continue;
+		  }
+		  isMatched =  p_MuTagMatchingTool->matchSegmentDirection( &info,trkEtaInfo);
 
 	      if( !isMatched ){ 
 		if( m_doTable ){
@@ -783,7 +793,6 @@ namespace MuonCombined {
 
 
 
-
   }
 
   void MuonSegmentTagTool::printTable( std::vector< std::string > didEx ,  
diff --git a/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedFitTools.py b/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedFitTools.py
index eefb5bf3a6d6b8dfa2e3d64abc52c7d948f1d579..784b26b802571f3c6035e78f759f1d20630e0600 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedFitTools.py
+++ b/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedFitTools.py
@@ -185,6 +185,27 @@ def MuidSegmentRegionRecoveryTool( name ='MuidSegmentRegionRecoveryTool', **kwar
     import MuonCombinedRecExample.CombinedMuonTrackSummary
     from AthenaCommon.AppMgr import ToolSvc
     kwargs.setdefault("TrackSummaryTool", ToolSvc.CombinedMuonTrackSummary)
+
+    from RegionSelector.RegSelToolConfig import makeRegSelTool_MDT, makeRegSelTool_RPC, makeRegSelTool_TGC
+    kwargs.setdefault("MDTRegionSelector", makeRegSelTool_MDT())
+    kwargs.setdefault("RPCRegionSelector", makeRegSelTool_RPC())
+    kwargs.setdefault("TGCRegionSelector", makeRegSelTool_TGC())
+    if MuonGeometryFlags.hasCSC():
+        from RegionSelector.RegSelToolConfig import makeRegSelTool_CSC
+        kwargs.setdefault("CSCRegionSelector", makeRegSelTool_CSC())
+    else:
+        kwargs.setdefault("CSCRegionSelector", "")
+    if MuonGeometryFlags.hasSTGC():
+        from RegionSelector.RegSelToolConfig import makeRegSelTool_sTGC
+        kwargs.setdefault("STGCRegionSelector", makeRegSelTool_sTGC())
+    else:
+        kwargs.setdefault("STGCRegionSelector", "")
+    if MuonGeometryFlags.hasMM():
+        from RegionSelector.RegSelToolConfig import makeRegSelTool_MM
+        kwargs.setdefault("MMRegionSelector", makeRegSelTool_MM())
+    else:
+        kwargs.setdefault("MMRegionSelector", "")
+
     return CfgMgr.Muon__MuonSegmentRegionRecoveryTool(name,**kwargs)
 
 
diff --git a/Reconstruction/PFlow/PFlowUtils/CMakeLists.txt b/Reconstruction/PFlow/PFlowUtils/CMakeLists.txt
index 6407592f882a4221c06d85012d8de55504ab8c01..d81a34ffcaff3a3874cc01d0b6a3c42457007f37 100644
--- a/Reconstruction/PFlow/PFlowUtils/CMakeLists.txt
+++ b/Reconstruction/PFlow/PFlowUtils/CMakeLists.txt
@@ -34,7 +34,7 @@ if( NOT XAOD_STANDALONE )
    atlas_add_component( PFlowUtils
       src/*.h src/*.cxx src/components/*.cxx
       LINK_LIBRARIES AthenaBaseComps xAODJet xAODPFlow GaudiKernel xAODTruth
-      PFlowUtilsLib )
+      PFlowUtilsLib CaloCalibHitRecLib )
 endif()
 
 # Install files from the package:
diff --git a/Reconstruction/RecExample/RecExCommon/CMakeLists.txt b/Reconstruction/RecExample/RecExCommon/CMakeLists.txt
index 855b5133882ef2a3c75c9ef56355a0e416a40c99..e74cfbac9c44be0f071fc00b66d29a68076c3e35 100644
--- a/Reconstruction/RecExample/RecExCommon/CMakeLists.txt
+++ b/Reconstruction/RecExample/RecExCommon/CMakeLists.txt
@@ -6,7 +6,6 @@
 atlas_subdir( RecExCommon )
 
 # Install files from the package:
-atlas_install_python_modules( python/*.py )
 atlas_install_joboptions( share/*.py )
 atlas_install_runtime( data/*.ascii.gz )
 atlas_install_scripts( share/RecExCommon_links.sh share/recexcommon-links.py share/qtest_run1.sh share/qtest_run2.sh )
diff --git a/Reconstruction/RecExample/RecExCommon/python/__init__.py b/Reconstruction/RecExample/RecExCommon/python/__init__.py
deleted file mode 100755
index 095f3a1645ea5d8088272ba50532599bc7ce2b9f..0000000000000000000000000000000000000000
--- a/Reconstruction/RecExample/RecExCommon/python/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
-# File: RecExCommon/python/__init__.py
-# Author: Wim Lavrijsen (WLavrijsen@lbl.gov)
-
-__version__ = '1.0.0'
-__author__  = 'David Rousseau (rousseau@lal.in2p3.fr) '
-
-
diff --git a/Reconstruction/RecoTools/TrackToCalo/CMakeLists.txt b/Reconstruction/RecoTools/TrackToCalo/CMakeLists.txt
index fe374b6bc281616e8fe7142bf80357958c6b2d8b..51ad0d43c436f7ca52438f6406506df14e63b820 100644
--- a/Reconstruction/RecoTools/TrackToCalo/CMakeLists.txt
+++ b/Reconstruction/RecoTools/TrackToCalo/CMakeLists.txt
@@ -58,7 +58,8 @@ atlas_add_library( TrackToCaloLib
                    LINK_LIBRARIES ${EIGEN_LIBRARIES} CaloEvent CaloGeoHelpers GeoPrimitives xAODCaloEvent GaudiKernel ParticleCaloExtension RecoToolInterfaces 
 		   TrackCaloClusterRecToolsLib TrkCaloExtension TrkParametersIdentificationHelpers CaloDetDescrLib CaloUtilsLib InDetReadoutGeometry TRT_ReadoutGeometry
                    PRIVATE_LINK_LIBRARIES CaloIdentifier AthenaBaseComps AtlasDetDescr FourMomUtils xAODTracking xAODMuon xAODEgamma xAODTruth TrkSurfaces 
-                   TrkEventPrimitives TrkParameters TrkTrack TrkExInterfaces TrkToolInterfaces CxxUtils StoreGateLib EventKernel )
+                   TrkEventPrimitives TrkParameters TrkTrack TrkExInterfaces TrkToolInterfaces CxxUtils StoreGateLib EventKernel ParticlesInConeToolsLib ITrackToVertex
+                   InDetTrackSelectionToolLib )
 
 atlas_add_component( TrackToCalo
                      src/components/*.cxx
diff --git a/Reconstruction/eflowRec/eflowRec/IEFlowCellEOverPTool.h b/Reconstruction/eflowRec/eflowRec/IEFlowCellEOverPTool.h
index 483aebd653e20bd23a1a63295024355ce52f49aa..fd1f5a5852e8724374e488d0b5db836d19a6868b 100644
--- a/Reconstruction/eflowRec/eflowRec/IEFlowCellEOverPTool.h
+++ b/Reconstruction/eflowRec/eflowRec/IEFlowCellEOverPTool.h
@@ -25,25 +25,25 @@ class eflowEEtaBinnedParameters;
 static const InterfaceID IID_IEFlowCellEOverPTool("IEFlowCellEOverPTool", 1, 0);
 
 /**
-Pure virtual base class, from which concrete classes inherit and define  reference e/p mean and widths, as well as reference energy density radial profile fit parameters. Inherits from AthAlgTool. 
+Pure virtual base class, from which concrete classes inherit and define  reference e/p mean and widths, as well as reference energy density radial profile fit parameters. Inherits from AthAlgTool.
 */
 class IEFlowCellEOverPTool : public AthAlgTool {
 
  public:
 
   IEFlowCellEOverPTool(const std::string& type,const std::string& name,const IInterface* parent) : AthAlgTool(type,name,parent) {};
-  
+
   virtual ~IEFlowCellEOverPTool() {};
 
   static const InterfaceID& interfaceID();
 
   virtual StatusCode intialize() {return StatusCode::SUCCESS;};
-  virtual StatusCode execute(eflowEEtaBinnedParameters *binnedParameters) = 0 ;
+  virtual StatusCode fillBinnedParameters(eflowEEtaBinnedParameters *binnedParameters) const = 0;
   virtual StatusCode finalize() {return StatusCode::SUCCESS;};
 
 protected:
   enum E_BINS        { ENERGY_BIN_START = 0, E001bin = ENERGY_BIN_START, E003point5bin = 1, E010bin = 2, E020bin = 3, E032point5bin = 4, E040bin = 5, ENERGY_BIN_END = 6 };
-    
+
   enum ETA_BINS      { ETA_BIN_START = 0, eta050bin = ETA_BIN_START, eta100bin = 1, eta150bin = 2, eta250bin = 3, eta350bin = 4, eta450bin = 5, ETA_BIN_END = 6};
 
   enum SHAPE_PARAMS  { SHAPE_START = 0, NORM1 = SHAPE_START, WIDTH1 = 1, NORM2 = 2, WIDTH2 = 3, SHAPE_END = 4 };
@@ -51,8 +51,8 @@ protected:
 };
 
 inline const InterfaceID& IEFlowCellEOverPTool::interfaceID()
-{ 
-  return IID_IEFlowCellEOverPTool; 
+{
+  return IID_IEFlowCellEOverPTool;
 }
 
 
diff --git a/Reconstruction/eflowRec/eflowRec/PFLCCalibTool.h b/Reconstruction/eflowRec/eflowRec/PFLCCalibTool.h
index 229c9416e69789f71b70e7eea4e06bd73ce3eab6..6da1879999ff843f3e90e7413d1cc689f6e0a437 100644
--- a/Reconstruction/eflowRec/eflowRec/PFLCCalibTool.h
+++ b/Reconstruction/eflowRec/eflowRec/PFLCCalibTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef PFLCCALIBTOOL_H
@@ -8,7 +8,7 @@
 #include "AthenaBaseComps/AthAlgTool.h"
 #include "GaudiKernel/ToolHandle.h"
 #include "xAODCaloEvent/CaloCluster.h"
-#include "CaloRec/CaloClusterCollectionProcessor.h"
+#include "CaloRec/CaloClusterProcessor.h"
 #include "eflowRec/IPFBaseTool.h"
 #include "eflowRec/IPFClusterCollectionTool.h"
 
@@ -16,7 +16,7 @@ class eflowCaloObjectContainer;
 class eflowRecCluster;
 
 /**
-This tool can either use a series of CaloClusterCollectionProcessor to calibrate the modified xAOD::CaloCluster (modified when we do the charged shower subtraction) using recalculated LC weights or its own internal method to use the stored LC weights in the eflowRecCluster objects. If using the LC weights which were stored in the eflowRecCluster then we use the container of eflowRecCluster, but if using recalculated LC weights for the modified xAOD::CaloCluster (modified when we remove calorimeter cells in the charged shower subtraction) then we need the container of xAOD::CaloCluster. The PFClusterCollectionTool provides both of these containers.
+This tool can either use a series of CaloClusterProcessor to calibrate the modified xAOD::CaloCluster (modified when we do the charged shower subtraction) using recalculated LC weights or its own internal method to use the stored LC weights in the eflowRecCluster objects. If using the LC weights which were stored in the eflowRecCluster then we use the container of eflowRecCluster, but if using recalculated LC weights for the modified xAOD::CaloCluster (modified when we remove calorimeter cells in the charged shower subtraction) then we need the container of xAOD::CaloCluster. The PFClusterCollectionTool provides both of these containers.
 */
 class PFLCCalibTool : public extends<AthAlgTool, IPFBaseTool> {
 
@@ -32,24 +32,24 @@ class PFLCCalibTool : public extends<AthAlgTool, IPFBaseTool> {
 
  private:
 
-  void apply(ToolHandle<CaloClusterCollectionProcessor>& calibTool, xAOD::CaloCluster* cluster);
-  void applyLocal(ToolHandle<CaloClusterCollectionProcessor>& calibTool, eflowRecCluster *cluster);
+  void apply(ToolHandle<CaloClusterProcessor>& calibTool, xAOD::CaloCluster* cluster);
+  void applyLocal(ToolHandle<CaloClusterProcessor>& calibTool, eflowRecCluster *cluster);
   void applyLocalWeight(eflowRecCluster* theEFRecCluster);
 
   /** Tool to put all clusters into a temporary container - then we use this to calculate moments, some of which depend on configuration of nearby clusters */
   ToolHandle<IPFClusterCollectionTool> m_clusterCollectionTool{this,"eflowRecClusterCollectionTool","eflowRecClusterCollectionTool","Tool to put all clusters into a temporary container - then we use this to calculate moments, some of which depend on configuration of nearby clusters"};
 
   /* Tool for applying local hadronc calibration weights to cells */
-  ToolHandle<CaloClusterCollectionProcessor> m_clusterLocalCalibTool{this,"CaloClusterLocalCalib","CaloClusterLocalCalib","Tool for applying local hadronc calibration weights to cells"};
+  ToolHandle<CaloClusterProcessor> m_clusterLocalCalibTool{this,"CaloClusterLocalCalib","CaloClusterLocalCalib","Tool for applying local hadronc calibration weights to cells"};
 
   /* Tool to deal with out of cluster corrections */
-  ToolHandle<CaloClusterCollectionProcessor> m_clusterLocalCalibOOCCTool{this,"CaloClusterLocalCalibOOCC","CaloClusterLocalCalib","Tool to deal with out of cluster corrections"};
+  ToolHandle<CaloClusterProcessor> m_clusterLocalCalibOOCCTool{this,"CaloClusterLocalCalibOOCC","CaloClusterLocalCalib","Tool to deal with out of cluster corrections"};
 
   /* Tool to do Pi0 corrections */
-  ToolHandle<CaloClusterCollectionProcessor> m_clusterLocalCalibOOCCPi0Tool{this,"CaloClusterLocalCalibOOCCPi0","CaloClusterLocalCalib","Tool to do Pi0 corrections"};
+  ToolHandle<CaloClusterProcessor> m_clusterLocalCalibOOCCPi0Tool{this,"CaloClusterLocalCalibOOCCPi0","CaloClusterLocalCalib","Tool to do Pi0 corrections"};
 
   /* Tool for correcting clusters at cell level for dead material */
-  ToolHandle<CaloClusterCollectionProcessor> m_clusterLocalCalibDMTool{this,"CaloClusterLocalCalibDM","CaloClusterLocalCalib","Tool for correcting clusters at cell level for dead material"};
+  ToolHandle<CaloClusterProcessor> m_clusterLocalCalibDMTool{this,"CaloClusterLocalCalibDM","CaloClusterLocalCalib","Tool for correcting clusters at cell level for dead material"};
 
   /** Toggle which LC weights scheme to use - default is to recalculate weights, rather than use saved weights */
   Gaudi::Property<bool> m_useLocalWeight{this,"UseLocalWeight",false,"Toggle which LC weights scheme to use - default is to recalculate weights, rather than use saved weights"};
diff --git a/Reconstruction/eflowRec/eflowRec/PFMatchInterfaces.h b/Reconstruction/eflowRec/eflowRec/PFMatchInterfaces.h
index 66c420a2aacdd77a1fd1d0dcaa8f024931b41a7b..11d503c72d3da4767bd1c03bed90e04ca07b6df6 100644
--- a/Reconstruction/eflowRec/eflowRec/PFMatchInterfaces.h
+++ b/Reconstruction/eflowRec/eflowRec/PFMatchInterfaces.h
@@ -131,8 +131,11 @@ public:
   DistanceProvider(std::unique_ptr<IPositionProvider> trackPosition,
                    std::unique_ptr<IPositionProvider> clusterPosition,
                    std::unique_ptr<DistanceCalculator<TrackPositionType, ClusterPositionType> > distanceCalculator):
-    m_trackPosition(std::move(trackPosition)), m_clusterPosition(std::move(clusterPosition)), m_distanceCalculator(std::move(distanceCalculator)) {
-    //in debug builds we check the pointer validity here to catch a problem early on
+    // dynamic_cast to ensure that the right distance provider classes are received
+    m_trackPosition(dynamic_cast<TrackPositionProvider<TrackPositionType>*>(trackPosition.release())),
+    m_clusterPosition(dynamic_cast<ClusterPositionProvider<ClusterPositionType>*>(clusterPosition.release())),
+    m_distanceCalculator(std::move(distanceCalculator)) {
+    // in debug builds we check the pointer validity here to catch a problem early on
     assert(m_trackPosition.get());
     assert(m_clusterPosition.get());
     assert(m_distanceCalculator.get());
@@ -140,33 +143,14 @@ public:
   virtual ~DistanceProvider() {}
 
   double distanceBetween(const ITrack* track, const ICluster* cluster) {
-    //if anything is not valid we return 10000 to indicate no match, in addition to error messages.
-    if (m_trackPosition.get()){
-      TrackPositionProvider<TrackPositionType>* trackPositionProvider = dynamic_cast<TrackPositionProvider<TrackPositionType>*>(m_trackPosition.get());
-      if (m_clusterPosition.get()){
-	ClusterPositionProvider<ClusterPositionType>* clusterPositionProvider = dynamic_cast<ClusterPositionProvider<ClusterPositionType>*>(m_clusterPosition.get());
-	if (m_distanceCalculator.get()){
-	  return m_distanceCalculator->distanceBetween(trackPositionProvider->getPosition(track),clusterPositionProvider->getPosition(cluster));
-	}
-	else{
-	  std::cerr << "ERROR: DistanceProvider has invalid std::unique_ptr<DistanceCalculator>" << std::endl;
-	return 10000;
-	}
-      }
-      else{
-	std::cerr << "ERROR: DistanceProvider has invalid std::unique_ptr<IPositionProvider> clusters" << std::endl;
-	return 10000;
-      }
-    }
-    else{
-      std::cerr << "ERROR: DistanceProvider has invalid std::unique_ptr<IPositionProvider> for tracks" << std::endl;
-      return 10000;
-    }
+    TrackPositionProvider<TrackPositionType>* trackPositionProvider = m_trackPosition.get();
+    ClusterPositionProvider<ClusterPositionType>* clusterPositionProvider = m_clusterPosition.get();
+    return m_distanceCalculator->distanceBetween(trackPositionProvider->getPosition(track),clusterPositionProvider->getPosition(cluster));
   }
 
 private:
-  std::unique_ptr<IPositionProvider> m_trackPosition;
-  std::unique_ptr<IPositionProvider> m_clusterPosition;
+  std::unique_ptr<TrackPositionProvider<TrackPositionType> > m_trackPosition;
+  std::unique_ptr<ClusterPositionProvider<ClusterPositionType> > m_clusterPosition;
   std::unique_ptr<DistanceCalculator<TrackPositionType, ClusterPositionType> > m_distanceCalculator;
 };
 
diff --git a/Reconstruction/eflowRec/eflowRec/eflowCaloObjectMaker.h b/Reconstruction/eflowRec/eflowRec/eflowCaloObjectMaker.h
index bc0704b1029dd3f706575b077efdbe237075ba44..599203aa99a68a0860db585ba8051e682f993b7d 100644
--- a/Reconstruction/eflowRec/eflowRec/eflowCaloObjectMaker.h
+++ b/Reconstruction/eflowRec/eflowRec/eflowCaloObjectMaker.h
@@ -30,7 +30,7 @@ public:
   eflowCaloObjectMaker() { }
 
   int makeTrkCluCaloObjects(eflowRecTrackContainer* eflowTrackContainer, eflowRecClusterContainer* eflowClusterContainer, eflowCaloObjectContainer* caloObjectContainer);
-  int makeTrkCluCaloObjects(std::vector<eflowRecTrack*> m_tracksToRecover, std::vector<eflowRecCluster*> m_clustersToConsider, eflowCaloObjectContainer* caloObjectContainer);
+  int makeTrkCluCaloObjects(std::vector<eflowRecTrack*>& tracksToRecover, std::vector<eflowRecCluster*>& clustersToConsider, eflowCaloObjectContainer* caloObjectContainer);
 
 private:
 
diff --git a/Reconstruction/eflowRec/eflowRec/eflowCellEOverPTool_mc12_HLLHC.h b/Reconstruction/eflowRec/eflowRec/eflowCellEOverPTool_mc12_HLLHC.h
index a6483bd57f35fccb292a27510fe5a4e565e638c0..140667c200354397fdff5a6e47c0b7248d0457ea 100644
--- a/Reconstruction/eflowRec/eflowRec/eflowCellEOverPTool_mc12_HLLHC.h
+++ b/Reconstruction/eflowRec/eflowRec/eflowCellEOverPTool_mc12_HLLHC.h
@@ -17,11 +17,11 @@ class eflowCellEOverPTool_mc12_HLLHC : public IEFlowCellEOverPTool {
  public:
 
   eflowCellEOverPTool_mc12_HLLHC(const std::string& type,const std::string& name,const IInterface* parent);
-  
+
   ~eflowCellEOverPTool_mc12_HLLHC() {};
 
   StatusCode initialize();
-  StatusCode execute(eflowEEtaBinnedParameters *binnedParameters) ;
+  StatusCode fillBinnedParameters(eflowEEtaBinnedParameters *binnedParameters) const;
   StatusCode finalize() ;
 
  private:
diff --git a/Reconstruction/eflowRec/eflowRec/eflowCellEOverPTool_mc12_JetETMiss.h b/Reconstruction/eflowRec/eflowRec/eflowCellEOverPTool_mc12_JetETMiss.h
index fb5b042b92f2a92ddff39509265e5849160f1e93..151649875ca920b21ad693c99a1bfdf6e36fd62f 100644
--- a/Reconstruction/eflowRec/eflowRec/eflowCellEOverPTool_mc12_JetETMiss.h
+++ b/Reconstruction/eflowRec/eflowRec/eflowCellEOverPTool_mc12_JetETMiss.h
@@ -29,11 +29,11 @@ class eflowCellEOverPTool_mc12_JetETMiss : public IEFlowCellEOverPTool {
  public:
 
   eflowCellEOverPTool_mc12_JetETMiss(const std::string& type,const std::string& name,const IInterface* parent);
-  
+
   ~eflowCellEOverPTool_mc12_JetETMiss() {};
 
   StatusCode initialize();
-  StatusCode execute(eflowEEtaBinnedParameters *binnedParameters) ;
+  StatusCode fillBinnedParameters(eflowEEtaBinnedParameters *binnedParameters) const;
   StatusCode finalize() ;
 
  private:
diff --git a/Reconstruction/eflowRec/eflowRec/eflowCellEOverPTool_mc12_LC.h b/Reconstruction/eflowRec/eflowRec/eflowCellEOverPTool_mc12_LC.h
index fad7105eaeb4f3cce4fae60789296e945558e09e..3d271515670fa619cc570ba197db02d0bcbd3fdd 100644
--- a/Reconstruction/eflowRec/eflowRec/eflowCellEOverPTool_mc12_LC.h
+++ b/Reconstruction/eflowRec/eflowRec/eflowCellEOverPTool_mc12_LC.h
@@ -29,11 +29,11 @@ class eflowCellEOverPTool_mc12_LC : public IEFlowCellEOverPTool {
  public:
 
   eflowCellEOverPTool_mc12_LC(const std::string& type,const std::string& name,const IInterface* parent);
-  
+
   ~eflowCellEOverPTool_mc12_LC() {};
 
   StatusCode initialize();
-  StatusCode execute(eflowEEtaBinnedParameters *binnedParameters) ;
+  StatusCode fillBinnedParameters(eflowEEtaBinnedParameters *binnedParameters) const;
   StatusCode finalize() ;
 
  private:
diff --git a/Reconstruction/eflowRec/python/PFOnlineMon.py b/Reconstruction/eflowRec/python/PFOnlineMon.py
index ec071ead7346304301b5462375d0eac2687688ec..d6375b1c0798f6b8a9cde0c3cf71a61f24787bb9 100644
--- a/Reconstruction/eflowRec/python/PFOnlineMon.py
+++ b/Reconstruction/eflowRec/python/PFOnlineMon.py
@@ -6,13 +6,13 @@ def getMonTool_PFAlgorithm():
 
     #monTool.HistPath = 'MyGroup/MySubDir'  # default is the parent name of MonTool
     monTool.defineHistogram( 'TIME_execute', path='EXPERT', type='TH1F', title='Counts',
-                             xbins=100, xmin=0, xmax=1000 )
+                             xbins=100, xmin=0., xmax=1000. )
     monTool.defineHistogram( 'TIME_subtract', path='EXPERT', type='TH1F', title='Counts',
-                             xbins=100, xmin=0, xmax=1000 )
+                             xbins=100, xmin=0., xmax=1000. )
     monTool.defineHistogram( 'N_efrTracks', path='EXPERT', type='TH1F', title='Counts',
-                             xbins=100, xmin=0, xmax=1000 )
+                             xbins=100, xmin=0., xmax=1000. )
     monTool.defineHistogram( 'N_efrClusters', path='EXPERT', type='TH1F', title='Counts',
-                             xbins=100, xmin=0, xmax=2000 )
+                             xbins=100, xmin=0., xmax=2000. )
     return monTool
 
 def getMonTool_PFTrackSelector():
@@ -21,9 +21,18 @@ def getMonTool_PFTrackSelector():
 
     #monTool.HistPath = 'MyGroup/MySubDir'  # default is the parent name of MonTool
     monTool.defineHistogram( 'TIME_execute', path='EXPERT', type='TH1F', title='Counts',
-                             xbins=100, xmin=0, xmax=1000 )
+                             xbins=100, xmin=0., xmax=1000. )
     monTool.defineHistogram( 'TIME_track', path='EXPERT', type='TH1F', title='Counts',
-                             xbins=50, xmin=0, xmax=50 )
+                             xbins=100, xmin=0., xmax=2500. )
     monTool.defineHistogram( 'N_tracks', path='EXPERT', type='TH1F', title='Counts',
-                             xbins=100, xmin=0, xmax=500 )
+                             xbins=100, xmin=0., xmax=1000. )
+    monTool.defineHistogram( 'eta_track', path='EXPERT', type='TH1F', title='Counts',
+                             xbins=120, xmin=-3., xmax=3. )
+    monTool.defineHistogram( 'pt_track', path='EXPERT', type='TH1F', title='Counts',
+                             xbins=100, xmin=0., xmax=25. )
+
+    monTool.defineHistogram( 'eta_track,TIME_track', path='EXPERT', type='TH2F', title='Counts',
+                             xbins=30, xmin=-3., xmax=3., ybins=50, ymin=0., ymax=2500. )
+    monTool.defineHistogram( 'pt_track,TIME_track', path='EXPERT', type='TH2F', title='Counts',
+                             xbins=25, xmin=0., xmax=25., ybins=50, ymin=0., ymax=2500. )
     return monTool
diff --git a/Reconstruction/eflowRec/src/PFCellLevelSubtractionTool.cxx b/Reconstruction/eflowRec/src/PFCellLevelSubtractionTool.cxx
index e4736422bbcf52c18ef81a75c8ef1e4317655836..3cefba89fe5f70768b0da53aa6812695f497f943 100644
--- a/Reconstruction/eflowRec/src/PFCellLevelSubtractionTool.cxx
+++ b/Reconstruction/eflowRec/src/PFCellLevelSubtractionTool.cxx
@@ -73,7 +73,7 @@ StatusCode PFCellLevelSubtractionTool::initialize(){
   m_integrator = std::make_unique<eflowLayerIntegrator>(gaussianRadius, gaussianRadiusError, maximumRadiusSigma, m_isHLLHC);
   m_binnedParameters = std::make_unique<eflowEEtaBinnedParameters>();
   
-  sc = m_theEOverPTool->execute(m_binnedParameters.get());
+  sc = m_theEOverPTool->fillBinnedParameters(m_binnedParameters.get());
 
   if (sc.isFailure()) {
     msg(MSG::WARNING) << "Could not execute eflowCellEOverPTool " << endmsg;
diff --git a/Reconstruction/eflowRec/src/PFLCCalibTool.cxx b/Reconstruction/eflowRec/src/PFLCCalibTool.cxx
index 4eb36e5e9a9997307b7d65b38807bb4636c09e15..9778ee2fdb6d36207d6ef1804ad87941ffbf0e94 100644
--- a/Reconstruction/eflowRec/src/PFLCCalibTool.cxx
+++ b/Reconstruction/eflowRec/src/PFLCCalibTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "eflowRec/PFLCCalibTool.h"
@@ -69,15 +69,9 @@ StatusCode PFLCCalibTool::finalize() {
 }
 
 
-void PFLCCalibTool::apply(ToolHandle<CaloClusterCollectionProcessor>& calibTool, xAOD::CaloCluster* cluster) {
-
-  if (m_useLocalWeight) ATH_MSG_WARNING("Applying recalculated weights, when configuraiton requested to use original weights");
-  CaloClusterCollectionProcessor* myCollectionProcessor = &(*calibTool);
-  CaloClusterProcessor* myCalibProcessor = dynamic_cast<CaloClusterProcessor*>(myCollectionProcessor);
-  if (myCalibProcessor) {
-    if (myCalibProcessor->execute(cluster).isFailure()) ATH_MSG_WARNING("Could not execute " << calibTool.name());
-  }
-  else ATH_MSG_WARNING("Dynamic_cast provided NULL pointer to CaloClusterProcessor");
+void PFLCCalibTool::apply(ToolHandle<CaloClusterProcessor>& calibTool, xAOD::CaloCluster* cluster) {
+  if (m_useLocalWeight) ATH_MSG_WARNING("Applying recalculated weights, when configuration requested to use original weights");
+  if (calibTool->execute(cluster).isFailure()) ATH_MSG_WARNING("Could not execute " << calibTool.name());
 }
 
 void PFLCCalibTool::applyLocalWeight(eflowRecCluster* theEFRecClusters) {
diff --git a/Reconstruction/eflowRec/src/PFRecoverSplitShowersTool.cxx b/Reconstruction/eflowRec/src/PFRecoverSplitShowersTool.cxx
index 7b35b6aac13ecb0a860f1ad327651053065f805f..309bc881ff5fd4903e1111d91394e701e9cf5fb6 100644
--- a/Reconstruction/eflowRec/src/PFRecoverSplitShowersTool.cxx
+++ b/Reconstruction/eflowRec/src/PFRecoverSplitShowersTool.cxx
@@ -48,7 +48,7 @@ StatusCode PFRecoverSplitShowersTool::initialize(){
     return StatusCode::SUCCESS;
   }
 
-  if (m_theEOverPTool->execute(m_binnedParameters.get()).isFailure()){
+  if (m_theEOverPTool->fillBinnedParameters(m_binnedParameters.get()).isFailure()){
     ATH_MSG_WARNING("Could not execute eflowCellEOverPTool");
     return StatusCode::SUCCESS;
   }
diff --git a/Reconstruction/eflowRec/src/PFTrackSelector.cxx b/Reconstruction/eflowRec/src/PFTrackSelector.cxx
index e07e2781433624088b8893fafcff568caaec35ec..b3255e6d9812a23ccad187a46f9b03bb2a17dbbb 100644
--- a/Reconstruction/eflowRec/src/PFTrackSelector.cxx
+++ b/Reconstruction/eflowRec/src/PFTrackSelector.cxx
@@ -5,7 +5,9 @@
 #include "eflowRec/PFTrackSelector.h"
 #include "StoreGate/ReadCondHandleKey.h"
 #include "xAODEgamma/ElectronxAODHelpers.h"
+#include "GaudiKernel/SystemOfUnits.h"
 
+constexpr float invGeV = 1./CLHEP::GeV;
 
 PFTrackSelector::PFTrackSelector(const std::string& name, ISvcLocator* pSvcLocator):
   AthAlgorithm(name, pSvcLocator)
@@ -43,6 +45,8 @@ StatusCode PFTrackSelector::execute(){
   // Monitor the time taken to execute the alg
   auto t_exec = Monitored::Timer<std::chrono::milliseconds>( "TIME_execute" );
   auto N_tracks = Monitored::Scalar( "N_tracks", 0 );
+  auto eta_track = Monitored::Scalar( "eta_track", 0. );
+  auto pt_track = Monitored::Scalar( "pt_track", 0. );
 
   SG::WriteHandle<eflowRecTrackContainer> eflowRecTracksWriteHandle(m_eflowRecTracksWriteHandleKey);  
   ATH_CHECK(eflowRecTracksWriteHandle.record(std::make_unique<eflowRecTrackContainer>()));
@@ -76,13 +80,15 @@ StatusCode PFTrackSelector::execute(){
     
     if (!rejectTrack) {
       // Monitor the time per selected track
-      auto t_track = Monitored::Timer<std::chrono::milliseconds>( "TIME_track" );
+      auto t_track = Monitored::Timer<std::chrono::microseconds>( "TIME_track" );
       /* Create the eflowRecCluster and put it in the container */
       std::unique_ptr<eflowRecTrack> thisEFRecTrack  = std::make_unique<eflowRecTrack>(ElementLink<xAOD::TrackParticleContainer>(*tracksReadHandle, trackIndex), m_theTrackExtrapolatorTool);
       thisEFRecTrack->setTrackId(trackIndex);
       eflowRecTracksWriteHandle->push_back(std::move(thisEFRecTrack));
+      eta_track = thisTrack->eta();
+      pt_track = thisTrack->pt() * invGeV;
       // Fill histogram
-      auto mon_trktime = Monitored::Group(m_monTool, t_track);
+      auto mon_trk = Monitored::Group(m_monTool, t_track, eta_track, pt_track);
     }
     trackIndex++;
   }
diff --git a/Reconstruction/eflowRec/src/eflowCaloObjectMaker.cxx b/Reconstruction/eflowRec/src/eflowCaloObjectMaker.cxx
index e54537266bc0b58dbb7d7d8c3b6d4febe8785d76..8b0cc18da02c8c5d4572316c07b8e8ad37d47efe 100644
--- a/Reconstruction/eflowRec/src/eflowCaloObjectMaker.cxx
+++ b/Reconstruction/eflowRec/src/eflowCaloObjectMaker.cxx
@@ -38,7 +38,7 @@ int eflowCaloObjectMaker::makeTrkCluCaloObjects(eflowRecTrackContainer* eflowTra
 
 }
 
-int eflowCaloObjectMaker::makeTrkCluCaloObjects(std::vector<eflowRecTrack*> tracksToRecover, std::vector<eflowRecCluster*> clustersToConsider, eflowCaloObjectContainer* caloObjectContainer) {
+int eflowCaloObjectMaker::makeTrkCluCaloObjects(std::vector<eflowRecTrack*>& tracksToRecover, std::vector<eflowRecCluster*>& clustersToConsider, eflowCaloObjectContainer* caloObjectContainer) {
   int result(0);
 
   /* Create all eflowCaloObjects that contain only eflowRecTracks and cache eflowRecTracks matched with cluster */
diff --git a/Reconstruction/eflowRec/src/eflowCellEOverPTool_mc12_HLLHC.cxx b/Reconstruction/eflowRec/src/eflowCellEOverPTool_mc12_HLLHC.cxx
index a38b6d6bc47832483ac74770c282c25a80b68c4e..fbe182c2c1ddcbc8c7ead0eae6ee660d2c5d632e 100644
--- a/Reconstruction/eflowRec/src/eflowCellEOverPTool_mc12_HLLHC.cxx
+++ b/Reconstruction/eflowRec/src/eflowCellEOverPTool_mc12_HLLHC.cxx
@@ -36,10 +36,10 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::initialize(){
   return StatusCode::SUCCESS;
 }
 
-StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *binnedParameters){
+StatusCode eflowCellEOverPTool_mc12_HLLHC::fillBinnedParameters(eflowEEtaBinnedParameters *binnedParameters) const {
 
   if (binnedParameters) {
-    
+
     binnedParameters->initialise(m_eBinValues, m_etaBinBounds);
 
     ////////////////////////////
@@ -47,8 +47,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E001bin, eta050bin, eflowFirstIntRegions::EMB1, 0.321000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta050bin, eflowFirstIntRegions::EMB1, 0.299000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta050bin, eflowFirstIntRegions::EMB1, 0.321000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta050bin, eflowFirstIntRegions::EMB1, 0.299000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta050bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,1.58218);
@@ -74,8 +74,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E001bin, eta050bin, eflowFirstIntRegions::EMB2, 0.465000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta050bin, eflowFirstIntRegions::EMB2, 0.304000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta050bin, eflowFirstIntRegions::EMB2, 0.465000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta050bin, eflowFirstIntRegions::EMB2, 0.304000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta050bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.292708);
@@ -97,8 +97,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E001bin, eta050bin, eflowFirstIntRegions::EMB3, 0.300000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta050bin, eflowFirstIntRegions::EMB3, 0.288000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta050bin, eflowFirstIntRegions::EMB3, 0.300000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta050bin, eflowFirstIntRegions::EMB3, 0.288000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta050bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.332119);
@@ -148,8 +148,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E001bin, eta050bin, eflowFirstIntRegions::Tile, 0.308000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta050bin, eflowFirstIntRegions::Tile, 0.542000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta050bin, eflowFirstIntRegions::Tile, 0.308000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta050bin, eflowFirstIntRegions::Tile, 0.542000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta050bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.0698781);
@@ -181,8 +181,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E001bin, eta100bin, eflowFirstIntRegions::EMB1, 0.304000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta100bin, eflowFirstIntRegions::EMB1, 0.312000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta100bin, eflowFirstIntRegions::EMB1, 0.304000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta100bin, eflowFirstIntRegions::EMB1, 0.312000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta100bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,1.0613);
@@ -204,8 +204,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E001bin, eta100bin, eflowFirstIntRegions::EMB2, 0.457000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta100bin, eflowFirstIntRegions::EMB2, 0.285000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta100bin, eflowFirstIntRegions::EMB2, 0.457000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta100bin, eflowFirstIntRegions::EMB2, 0.285000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta100bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.201064);
@@ -227,8 +227,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E001bin, eta100bin, eflowFirstIntRegions::EMB3, 0.300000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta100bin, eflowFirstIntRegions::EMB3, 0.509000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta100bin, eflowFirstIntRegions::EMB3, 0.300000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta100bin, eflowFirstIntRegions::EMB3, 0.509000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta100bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.233052);
@@ -274,8 +274,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E001bin, eta100bin, eflowFirstIntRegions::Tile, 0.515000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta100bin, eflowFirstIntRegions::Tile, 1.039000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta100bin, eflowFirstIntRegions::Tile, 0.515000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta100bin, eflowFirstIntRegions::Tile, 1.039000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta100bin, eflowFirstIntRegions::Tile, eflowCalo::Tile1, NORM1,0.393702);
@@ -291,8 +291,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E001bin, eta150bin, eflowFirstIntRegions::EMB1, 0.316000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta150bin, eflowFirstIntRegions::EMB1, 0.229000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta150bin, eflowFirstIntRegions::EMB1, 0.316000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta150bin, eflowFirstIntRegions::EMB1, 0.229000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta150bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,0.711413);
@@ -314,8 +314,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E001bin, eta150bin, eflowFirstIntRegions::EMB2, 0.444000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta150bin, eflowFirstIntRegions::EMB2, 0.255000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta150bin, eflowFirstIntRegions::EMB2, 0.444000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta150bin, eflowFirstIntRegions::EMB2, 0.255000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta150bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.168614);
@@ -337,8 +337,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E001bin, eta150bin, eflowFirstIntRegions::EMB3, 0.300000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta150bin, eflowFirstIntRegions::EMB3, 0.583000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta150bin, eflowFirstIntRegions::EMB3, 0.300000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta150bin, eflowFirstIntRegions::EMB3, 0.583000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta150bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.297088);
@@ -360,15 +360,15 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME1
-    binnedParameters->setFudgeMean( E001bin, eta150bin, eflowFirstIntRegions::EME1, 0.591000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta150bin, eflowFirstIntRegions::EME1, 0.343000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta150bin, eflowFirstIntRegions::EME1, 0.591000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta150bin, eflowFirstIntRegions::EME1, 0.343000 );
 
 
 
 
    // j1st = EME2
-    binnedParameters->setFudgeMean( E001bin, eta150bin, eflowFirstIntRegions::EME2, 0.651000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta150bin, eflowFirstIntRegions::EME2, 0.811000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta150bin, eflowFirstIntRegions::EME2, 0.651000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta150bin, eflowFirstIntRegions::EME2, 0.811000 );
 
 
 
@@ -384,8 +384,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E001bin, eta150bin, eflowFirstIntRegions::Tile, 0.332000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta150bin, eflowFirstIntRegions::Tile, 0.472000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta150bin, eflowFirstIntRegions::Tile, 0.332000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta150bin, eflowFirstIntRegions::Tile, 0.472000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta150bin, eflowFirstIntRegions::Tile, eflowCalo::Tile1, NORM1,0.0810416);
@@ -428,8 +428,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME1
-    binnedParameters->setFudgeMean( E001bin, eta250bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta250bin, eflowFirstIntRegions::EME1, 0.000000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta250bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta250bin, eflowFirstIntRegions::EME1, 0.000000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta250bin, eflowFirstIntRegions::EME1, eflowCalo::EME1, NORM1,1.74282);
@@ -451,8 +451,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME2
-    binnedParameters->setFudgeMean( E001bin, eta250bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta250bin, eflowFirstIntRegions::EME2, 0.000000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta250bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta250bin, eflowFirstIntRegions::EME2, 0.000000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta250bin, eflowFirstIntRegions::EME2, eflowCalo::EME1, NORM1,0.364715);
@@ -474,8 +474,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME3
-    binnedParameters->setFudgeMean( E001bin, eta250bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta250bin, eflowFirstIntRegions::EME3, 0.000000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta250bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta250bin, eflowFirstIntRegions::EME3, 0.000000 );
 
 
     binnedParameters->setShapeParam( E001bin, eta250bin, eflowFirstIntRegions::EME3, eflowCalo::HEC1, NORM1,0.667073);
@@ -489,8 +489,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = HEC
-    binnedParameters->setFudgeMean( E001bin, eta250bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta250bin, eflowFirstIntRegions::HEC, 0.000000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta250bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta250bin, eflowFirstIntRegions::HEC, 0.000000 );
 
 
 
@@ -503,8 +503,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E003point5bin, eta050bin, eflowFirstIntRegions::EMB1, 0.406000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta050bin, eflowFirstIntRegions::EMB1, 0.312000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta050bin, eflowFirstIntRegions::EMB1, 0.406000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta050bin, eflowFirstIntRegions::EMB1, 0.312000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta050bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,1.43156);
@@ -534,8 +534,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E003point5bin, eta050bin, eflowFirstIntRegions::EMB2, 0.499000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta050bin, eflowFirstIntRegions::EMB2, 0.198000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta050bin, eflowFirstIntRegions::EMB2, 0.499000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta050bin, eflowFirstIntRegions::EMB2, 0.198000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta050bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.248212);
@@ -565,8 +565,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E003point5bin, eta050bin, eflowFirstIntRegions::EMB3, 0.334000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta050bin, eflowFirstIntRegions::EMB3, 0.316000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta050bin, eflowFirstIntRegions::EMB3, 0.334000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta050bin, eflowFirstIntRegions::EMB3, 0.316000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta050bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.148983);
@@ -616,8 +616,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E003point5bin, eta050bin, eflowFirstIntRegions::Tile, 0.740000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta050bin, eflowFirstIntRegions::Tile, 0.230000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta050bin, eflowFirstIntRegions::Tile, 0.740000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta050bin, eflowFirstIntRegions::Tile, 0.230000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta050bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.11613);
@@ -649,8 +649,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E003point5bin, eta100bin, eflowFirstIntRegions::EMB1, 0.357000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta100bin, eflowFirstIntRegions::EMB1, 0.285000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta100bin, eflowFirstIntRegions::EMB1, 0.357000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta100bin, eflowFirstIntRegions::EMB1, 0.285000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta100bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,0.951874);
@@ -680,8 +680,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E003point5bin, eta100bin, eflowFirstIntRegions::EMB2, 0.482000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta100bin, eflowFirstIntRegions::EMB2, 0.214000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta100bin, eflowFirstIntRegions::EMB2, 0.482000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta100bin, eflowFirstIntRegions::EMB2, 0.214000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta100bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.162365);
@@ -707,8 +707,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E003point5bin, eta100bin, eflowFirstIntRegions::EMB3, 0.367000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta100bin, eflowFirstIntRegions::EMB3, 0.232000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta100bin, eflowFirstIntRegions::EMB3, 0.367000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta100bin, eflowFirstIntRegions::EMB3, 0.232000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta100bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.124101);
@@ -758,8 +758,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E003point5bin, eta100bin, eflowFirstIntRegions::Tile, 0.755000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta100bin, eflowFirstIntRegions::Tile, 0.293000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta100bin, eflowFirstIntRegions::Tile, 0.755000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta100bin, eflowFirstIntRegions::Tile, 0.293000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta100bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.0778484);
@@ -791,8 +791,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E003point5bin, eta150bin, eflowFirstIntRegions::EMB1, 0.300000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta150bin, eflowFirstIntRegions::EMB1, 0.275000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta150bin, eflowFirstIntRegions::EMB1, 0.300000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta150bin, eflowFirstIntRegions::EMB1, 0.275000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta150bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,0.618127);
@@ -830,8 +830,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E003point5bin, eta150bin, eflowFirstIntRegions::EMB2, 0.414000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta150bin, eflowFirstIntRegions::EMB2, 0.250000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta150bin, eflowFirstIntRegions::EMB2, 0.414000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta150bin, eflowFirstIntRegions::EMB2, 0.250000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta150bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.135475);
@@ -857,8 +857,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E003point5bin, eta150bin, eflowFirstIntRegions::EMB3, 0.373000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta150bin, eflowFirstIntRegions::EMB3, 0.218000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta150bin, eflowFirstIntRegions::EMB3, 0.373000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta150bin, eflowFirstIntRegions::EMB3, 0.218000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta150bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.125619);
@@ -900,15 +900,15 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME1
-    binnedParameters->setFudgeMean( E003point5bin, eta150bin, eflowFirstIntRegions::EME1, 0.300000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta150bin, eflowFirstIntRegions::EME1, 0.262000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta150bin, eflowFirstIntRegions::EME1, 0.300000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta150bin, eflowFirstIntRegions::EME1, 0.262000 );
 
 
 
 
    // j1st = EME2
-    binnedParameters->setFudgeMean( E003point5bin, eta150bin, eflowFirstIntRegions::EME2, 0.339000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta150bin, eflowFirstIntRegions::EME2, 0.223000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta150bin, eflowFirstIntRegions::EME2, 0.339000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta150bin, eflowFirstIntRegions::EME2, 0.223000 );
 
 
 
@@ -924,8 +924,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E003point5bin, eta150bin, eflowFirstIntRegions::Tile, 0.300000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta150bin, eflowFirstIntRegions::Tile, 0.672000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta150bin, eflowFirstIntRegions::Tile, 0.300000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta150bin, eflowFirstIntRegions::Tile, 0.672000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta150bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.0276654);
@@ -985,8 +985,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME1
-    binnedParameters->setFudgeMean( E003point5bin, eta250bin, eflowFirstIntRegions::EME1, 0.300000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta250bin, eflowFirstIntRegions::EME1, 0.279000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta250bin, eflowFirstIntRegions::EME1, 0.300000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta250bin, eflowFirstIntRegions::EME1, 0.279000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta250bin, eflowFirstIntRegions::EME1, eflowCalo::EME1, NORM1,2.80389);
@@ -1020,8 +1020,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME2
-    binnedParameters->setFudgeMean( E003point5bin, eta250bin, eflowFirstIntRegions::EME2, 0.415000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta250bin, eflowFirstIntRegions::EME2, 0.244000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta250bin, eflowFirstIntRegions::EME2, 0.415000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta250bin, eflowFirstIntRegions::EME2, 0.244000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta250bin, eflowFirstIntRegions::EME2, eflowCalo::EME1, NORM1,0.411762);
@@ -1055,8 +1055,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME3
-    binnedParameters->setFudgeMean( E003point5bin, eta250bin, eflowFirstIntRegions::EME3, 0.360000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta250bin, eflowFirstIntRegions::EME3, 0.264000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta250bin, eflowFirstIntRegions::EME3, 0.360000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta250bin, eflowFirstIntRegions::EME3, 0.264000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta250bin, eflowFirstIntRegions::EME3, eflowCalo::EME1, NORM1,0.221942);
@@ -1090,8 +1090,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = HEC
-    binnedParameters->setFudgeMean( E003point5bin, eta250bin, eflowFirstIntRegions::HEC, 0.582000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta250bin, eflowFirstIntRegions::HEC, 0.334000 ); 
+    binnedParameters->setFudgeMean( E003point5bin, eta250bin, eflowFirstIntRegions::HEC, 0.582000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta250bin, eflowFirstIntRegions::HEC, 0.334000 );
 
 
     binnedParameters->setShapeParam( E003point5bin, eta250bin, eflowFirstIntRegions::HEC, eflowCalo::EME1, NORM1,0.284158);
@@ -1156,8 +1156,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E010bin, eta050bin, eflowFirstIntRegions::EMB1, 0.576000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta050bin, eflowFirstIntRegions::EMB1, 0.180000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta050bin, eflowFirstIntRegions::EMB1, 0.576000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta050bin, eflowFirstIntRegions::EMB1, 0.180000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta050bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,2.43176);
@@ -1187,8 +1187,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E010bin, eta050bin, eflowFirstIntRegions::EMB2, 0.608000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta050bin, eflowFirstIntRegions::EMB2, 0.154000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta050bin, eflowFirstIntRegions::EMB2, 0.608000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta050bin, eflowFirstIntRegions::EMB2, 0.154000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta050bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.406566);
@@ -1218,8 +1218,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E010bin, eta050bin, eflowFirstIntRegions::EMB3, 0.524000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta050bin, eflowFirstIntRegions::EMB3, 0.154000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta050bin, eflowFirstIntRegions::EMB3, 0.524000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta050bin, eflowFirstIntRegions::EMB3, 0.154000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta050bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.14787);
@@ -1269,8 +1269,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E010bin, eta050bin, eflowFirstIntRegions::Tile, 0.722000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta050bin, eflowFirstIntRegions::Tile, 0.154000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta050bin, eflowFirstIntRegions::Tile, 0.722000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta050bin, eflowFirstIntRegions::Tile, 0.154000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta050bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.128433);
@@ -1303,8 +1303,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E010bin, eta100bin, eflowFirstIntRegions::EMB1, 0.543000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta100bin, eflowFirstIntRegions::EMB1, 0.190000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta100bin, eflowFirstIntRegions::EMB1, 0.543000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta100bin, eflowFirstIntRegions::EMB1, 0.190000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta100bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,1.52832);
@@ -1334,8 +1334,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E010bin, eta100bin, eflowFirstIntRegions::EMB2, 0.590000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta100bin, eflowFirstIntRegions::EMB2, 0.157000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta100bin, eflowFirstIntRegions::EMB2, 0.590000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta100bin, eflowFirstIntRegions::EMB2, 0.157000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta100bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.186236);
@@ -1361,8 +1361,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E010bin, eta100bin, eflowFirstIntRegions::EMB3, 0.510000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta100bin, eflowFirstIntRegions::EMB3, 0.155000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta100bin, eflowFirstIntRegions::EMB3, 0.510000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta100bin, eflowFirstIntRegions::EMB3, 0.155000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta100bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.109028);
@@ -1412,8 +1412,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E010bin, eta100bin, eflowFirstIntRegions::Tile, 0.721000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta100bin, eflowFirstIntRegions::Tile, 0.144000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta100bin, eflowFirstIntRegions::Tile, 0.721000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta100bin, eflowFirstIntRegions::Tile, 0.144000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta100bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.107734);
@@ -1445,8 +1445,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E010bin, eta150bin, eflowFirstIntRegions::EMB1, 0.489000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta150bin, eflowFirstIntRegions::EMB1, 0.226000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta150bin, eflowFirstIntRegions::EMB1, 0.489000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta150bin, eflowFirstIntRegions::EMB1, 0.226000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta150bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,0.79114);
@@ -1484,8 +1484,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E010bin, eta150bin, eflowFirstIntRegions::EMB2, 0.550000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta150bin, eflowFirstIntRegions::EMB2, 0.191000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta150bin, eflowFirstIntRegions::EMB2, 0.550000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta150bin, eflowFirstIntRegions::EMB2, 0.191000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta150bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.175507);
@@ -1523,8 +1523,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E010bin, eta150bin, eflowFirstIntRegions::EMB3, 0.535000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta150bin, eflowFirstIntRegions::EMB3, 0.198000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta150bin, eflowFirstIntRegions::EMB3, 0.535000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta150bin, eflowFirstIntRegions::EMB3, 0.198000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta150bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.0852493);
@@ -1562,15 +1562,15 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME1
-    binnedParameters->setFudgeMean( E010bin, eta150bin, eflowFirstIntRegions::EME1, 0.402000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta150bin, eflowFirstIntRegions::EME1, 0.233000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta150bin, eflowFirstIntRegions::EME1, 0.402000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta150bin, eflowFirstIntRegions::EME1, 0.233000 );
 
 
 
 
    // j1st = EME2
-    binnedParameters->setFudgeMean( E010bin, eta150bin, eflowFirstIntRegions::EME2, 0.459000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta150bin, eflowFirstIntRegions::EME2, 0.168000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta150bin, eflowFirstIntRegions::EME2, 0.459000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta150bin, eflowFirstIntRegions::EME2, 0.168000 );
 
 
 
@@ -1614,8 +1614,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E010bin, eta150bin, eflowFirstIntRegions::Tile, 0.795000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta150bin, eflowFirstIntRegions::Tile, 0.169000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta150bin, eflowFirstIntRegions::Tile, 0.795000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta150bin, eflowFirstIntRegions::Tile, 0.169000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta150bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.10351);
@@ -1694,8 +1694,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME1
-    binnedParameters->setFudgeMean( E010bin, eta250bin, eflowFirstIntRegions::EME1, 0.483000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta250bin, eflowFirstIntRegions::EME1, 0.239000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta250bin, eflowFirstIntRegions::EME1, 0.483000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta250bin, eflowFirstIntRegions::EME1, 0.239000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta250bin, eflowFirstIntRegions::EME1, eflowCalo::EME1, NORM1,4.15008);
@@ -1729,8 +1729,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME2
-    binnedParameters->setFudgeMean( E010bin, eta250bin, eflowFirstIntRegions::EME2, 0.547000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta250bin, eflowFirstIntRegions::EME2, 0.192000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta250bin, eflowFirstIntRegions::EME2, 0.547000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta250bin, eflowFirstIntRegions::EME2, 0.192000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta250bin, eflowFirstIntRegions::EME2, eflowCalo::EME1, NORM1,0.587762);
@@ -1764,8 +1764,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME3
-    binnedParameters->setFudgeMean( E010bin, eta250bin, eflowFirstIntRegions::EME3, 0.572000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta250bin, eflowFirstIntRegions::EME3, 0.220000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta250bin, eflowFirstIntRegions::EME3, 0.572000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta250bin, eflowFirstIntRegions::EME3, 0.220000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta250bin, eflowFirstIntRegions::EME3, eflowCalo::EME1, NORM1,0.300834);
@@ -1799,8 +1799,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = HEC
-    binnedParameters->setFudgeMean( E010bin, eta250bin, eflowFirstIntRegions::HEC, 0.679000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta250bin, eflowFirstIntRegions::HEC, 0.230000 ); 
+    binnedParameters->setFudgeMean( E010bin, eta250bin, eflowFirstIntRegions::HEC, 0.679000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta250bin, eflowFirstIntRegions::HEC, 0.230000 );
 
 
     binnedParameters->setShapeParam( E010bin, eta250bin, eflowFirstIntRegions::HEC, eflowCalo::EMB1, NORM1,0.0796651);
@@ -1885,8 +1885,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E020bin, eta050bin, eflowFirstIntRegions::EMB1, 0.658000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta050bin, eflowFirstIntRegions::EMB1, 0.127000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta050bin, eflowFirstIntRegions::EMB1, 0.658000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta050bin, eflowFirstIntRegions::EMB1, 0.127000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta050bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,3.26847);
@@ -1916,8 +1916,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E020bin, eta050bin, eflowFirstIntRegions::EMB2, 0.669000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta050bin, eflowFirstIntRegions::EMB2, 0.126000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta050bin, eflowFirstIntRegions::EMB2, 0.669000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta050bin, eflowFirstIntRegions::EMB2, 0.126000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta050bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.397084);
@@ -1947,8 +1947,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E020bin, eta050bin, eflowFirstIntRegions::EMB3, 0.583000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta050bin, eflowFirstIntRegions::EMB3, 0.123000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta050bin, eflowFirstIntRegions::EMB3, 0.583000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta050bin, eflowFirstIntRegions::EMB3, 0.123000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta050bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.107883);
@@ -1998,8 +1998,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E020bin, eta050bin, eflowFirstIntRegions::Tile, 0.760000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta050bin, eflowFirstIntRegions::Tile, 0.134000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta050bin, eflowFirstIntRegions::Tile, 0.760000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta050bin, eflowFirstIntRegions::Tile, 0.134000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta050bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.112534);
@@ -2031,8 +2031,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E020bin, eta100bin, eflowFirstIntRegions::EMB1, 0.620000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta100bin, eflowFirstIntRegions::EMB1, 0.139000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta100bin, eflowFirstIntRegions::EMB1, 0.620000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta100bin, eflowFirstIntRegions::EMB1, 0.139000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta100bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,1.45897);
@@ -2062,8 +2062,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E020bin, eta100bin, eflowFirstIntRegions::EMB2, 0.654000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta100bin, eflowFirstIntRegions::EMB2, 0.126000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta100bin, eflowFirstIntRegions::EMB2, 0.654000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta100bin, eflowFirstIntRegions::EMB2, 0.126000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta100bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.23826);
@@ -2093,8 +2093,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E020bin, eta100bin, eflowFirstIntRegions::EMB3, 0.556000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta100bin, eflowFirstIntRegions::EMB3, 0.107000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta100bin, eflowFirstIntRegions::EMB3, 0.556000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta100bin, eflowFirstIntRegions::EMB3, 0.107000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta100bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.080015);
@@ -2144,8 +2144,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E020bin, eta100bin, eflowFirstIntRegions::Tile, 0.738000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta100bin, eflowFirstIntRegions::Tile, 0.128000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta100bin, eflowFirstIntRegions::Tile, 0.738000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta100bin, eflowFirstIntRegions::Tile, 0.128000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta100bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.0456492);
@@ -2177,8 +2177,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E020bin, eta150bin, eflowFirstIntRegions::EMB1, 0.581000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta150bin, eflowFirstIntRegions::EMB1, 0.166000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta150bin, eflowFirstIntRegions::EMB1, 0.581000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta150bin, eflowFirstIntRegions::EMB1, 0.166000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta150bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,1.30745);
@@ -2212,8 +2212,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E020bin, eta150bin, eflowFirstIntRegions::EMB2, 0.629000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta150bin, eflowFirstIntRegions::EMB2, 0.159000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta150bin, eflowFirstIntRegions::EMB2, 0.629000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta150bin, eflowFirstIntRegions::EMB2, 0.159000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta150bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.338733);
@@ -2247,8 +2247,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E020bin, eta150bin, eflowFirstIntRegions::EMB3, 0.618000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta150bin, eflowFirstIntRegions::EMB3, 0.155000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta150bin, eflowFirstIntRegions::EMB3, 0.618000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta150bin, eflowFirstIntRegions::EMB3, 0.155000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta150bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.09757);
@@ -2294,15 +2294,15 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME1
-    binnedParameters->setFudgeMean( E020bin, eta150bin, eflowFirstIntRegions::EME1, 0.474000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta150bin, eflowFirstIntRegions::EME1, 0.167000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta150bin, eflowFirstIntRegions::EME1, 0.474000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta150bin, eflowFirstIntRegions::EME1, 0.167000 );
 
 
 
 
    // j1st = EME2
-    binnedParameters->setFudgeMean( E020bin, eta150bin, eflowFirstIntRegions::EME2, 0.538000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta150bin, eflowFirstIntRegions::EME2, 0.140000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta150bin, eflowFirstIntRegions::EME2, 0.538000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta150bin, eflowFirstIntRegions::EME2, 0.140000 );
 
 
 
@@ -2346,8 +2346,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E020bin, eta150bin, eflowFirstIntRegions::Tile, 0.816000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta150bin, eflowFirstIntRegions::Tile, 0.129000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta150bin, eflowFirstIntRegions::Tile, 0.816000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta150bin, eflowFirstIntRegions::Tile, 0.129000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta150bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.0877375);
@@ -2411,8 +2411,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME1
-    binnedParameters->setFudgeMean( E020bin, eta250bin, eflowFirstIntRegions::EME1, 0.580000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta250bin, eflowFirstIntRegions::EME1, 0.175000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta250bin, eflowFirstIntRegions::EME1, 0.580000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta250bin, eflowFirstIntRegions::EME1, 0.175000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta250bin, eflowFirstIntRegions::EME1, eflowCalo::EME1, NORM1,5.29384);
@@ -2446,8 +2446,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME2
-    binnedParameters->setFudgeMean( E020bin, eta250bin, eflowFirstIntRegions::EME2, 0.638000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta250bin, eflowFirstIntRegions::EME2, 0.145000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta250bin, eflowFirstIntRegions::EME2, 0.638000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta250bin, eflowFirstIntRegions::EME2, 0.145000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta250bin, eflowFirstIntRegions::EME2, eflowCalo::EME1, NORM1,0.929508);
@@ -2481,8 +2481,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME3
-    binnedParameters->setFudgeMean( E020bin, eta250bin, eflowFirstIntRegions::EME3, 0.661000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta250bin, eflowFirstIntRegions::EME3, 0.157000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta250bin, eflowFirstIntRegions::EME3, 0.661000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta250bin, eflowFirstIntRegions::EME3, 0.157000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta250bin, eflowFirstIntRegions::EME3, eflowCalo::EME1, NORM1,0.359184);
@@ -2516,8 +2516,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = HEC
-    binnedParameters->setFudgeMean( E020bin, eta250bin, eflowFirstIntRegions::HEC, 0.722000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta250bin, eflowFirstIntRegions::HEC, 0.175000 ); 
+    binnedParameters->setFudgeMean( E020bin, eta250bin, eflowFirstIntRegions::HEC, 0.722000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta250bin, eflowFirstIntRegions::HEC, 0.175000 );
 
 
     binnedParameters->setShapeParam( E020bin, eta250bin, eflowFirstIntRegions::HEC, eflowCalo::EMB1, NORM1,0.0129383);
@@ -2594,8 +2594,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E032point5bin, eta050bin, eflowFirstIntRegions::EMB1, 0.691000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta050bin, eflowFirstIntRegions::EMB1, 0.099000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta050bin, eflowFirstIntRegions::EMB1, 0.691000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta050bin, eflowFirstIntRegions::EMB1, 0.099000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta050bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,3.22286);
@@ -2625,8 +2625,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E032point5bin, eta050bin, eflowFirstIntRegions::EMB2, 0.694000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta050bin, eflowFirstIntRegions::EMB2, 0.103000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta050bin, eflowFirstIntRegions::EMB2, 0.694000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta050bin, eflowFirstIntRegions::EMB2, 0.103000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta050bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.793048);
@@ -2656,8 +2656,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E032point5bin, eta050bin, eflowFirstIntRegions::EMB3, 0.600000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta050bin, eflowFirstIntRegions::EMB3, 0.110000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta050bin, eflowFirstIntRegions::EMB3, 0.600000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta050bin, eflowFirstIntRegions::EMB3, 0.110000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta050bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.104622);
@@ -2707,8 +2707,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E032point5bin, eta050bin, eflowFirstIntRegions::Tile, 0.783000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta050bin, eflowFirstIntRegions::Tile, 0.102000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta050bin, eflowFirstIntRegions::Tile, 0.783000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta050bin, eflowFirstIntRegions::Tile, 0.102000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta050bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.0682025);
@@ -2740,8 +2740,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E032point5bin, eta100bin, eflowFirstIntRegions::EMB1, 0.663000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta100bin, eflowFirstIntRegions::EMB1, 0.114000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta100bin, eflowFirstIntRegions::EMB1, 0.663000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta100bin, eflowFirstIntRegions::EMB1, 0.114000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta100bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,1.51378);
@@ -2771,8 +2771,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E032point5bin, eta100bin, eflowFirstIntRegions::EMB2, 0.681000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta100bin, eflowFirstIntRegions::EMB2, 0.108000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta100bin, eflowFirstIntRegions::EMB2, 0.681000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta100bin, eflowFirstIntRegions::EMB2, 0.108000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta100bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.490985);
@@ -2802,8 +2802,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E032point5bin, eta100bin, eflowFirstIntRegions::EMB3, 0.584000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta100bin, eflowFirstIntRegions::EMB3, 0.089000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta100bin, eflowFirstIntRegions::EMB3, 0.584000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta100bin, eflowFirstIntRegions::EMB3, 0.089000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta100bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.0759035);
@@ -2853,8 +2853,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E032point5bin, eta100bin, eflowFirstIntRegions::Tile, 0.761000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta100bin, eflowFirstIntRegions::Tile, 0.110000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta100bin, eflowFirstIntRegions::Tile, 0.761000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta100bin, eflowFirstIntRegions::Tile, 0.110000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta100bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.0554494);
@@ -2886,8 +2886,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E032point5bin, eta150bin, eflowFirstIntRegions::EMB1, 0.632000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta150bin, eflowFirstIntRegions::EMB1, 0.138000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta150bin, eflowFirstIntRegions::EMB1, 0.632000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta150bin, eflowFirstIntRegions::EMB1, 0.138000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta150bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,0.923022);
@@ -2929,8 +2929,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E032point5bin, eta150bin, eflowFirstIntRegions::EMB2, 0.674000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta150bin, eflowFirstIntRegions::EMB2, 0.141000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta150bin, eflowFirstIntRegions::EMB2, 0.674000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta150bin, eflowFirstIntRegions::EMB2, 0.141000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta150bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.481914);
@@ -2964,8 +2964,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E032point5bin, eta150bin, eflowFirstIntRegions::EMB3, 0.670000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta150bin, eflowFirstIntRegions::EMB3, 0.124000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta150bin, eflowFirstIntRegions::EMB3, 0.670000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta150bin, eflowFirstIntRegions::EMB3, 0.124000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta150bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.0896502);
@@ -3003,15 +3003,15 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME1
-    binnedParameters->setFudgeMean( E032point5bin, eta150bin, eflowFirstIntRegions::EME1, 0.519000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta150bin, eflowFirstIntRegions::EME1, 0.149000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta150bin, eflowFirstIntRegions::EME1, 0.519000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta150bin, eflowFirstIntRegions::EME1, 0.149000 );
 
 
 
 
    // j1st = EME2
-    binnedParameters->setFudgeMean( E032point5bin, eta150bin, eflowFirstIntRegions::EME2, 0.576000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta150bin, eflowFirstIntRegions::EME2, 0.103000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta150bin, eflowFirstIntRegions::EME2, 0.576000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta150bin, eflowFirstIntRegions::EME2, 0.103000 );
 
 
 
@@ -3055,8 +3055,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E032point5bin, eta150bin, eflowFirstIntRegions::Tile, 0.805000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta150bin, eflowFirstIntRegions::Tile, 0.120000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta150bin, eflowFirstIntRegions::Tile, 0.805000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta150bin, eflowFirstIntRegions::Tile, 0.120000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta150bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.0728621);
@@ -3119,8 +3119,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME1
-    binnedParameters->setFudgeMean( E032point5bin, eta250bin, eflowFirstIntRegions::EME1, 0.635000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta250bin, eflowFirstIntRegions::EME1, 0.141000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta250bin, eflowFirstIntRegions::EME1, 0.635000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta250bin, eflowFirstIntRegions::EME1, 0.141000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta250bin, eflowFirstIntRegions::EME1, eflowCalo::EME1, NORM1,6.19746);
@@ -3154,8 +3154,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME2
-    binnedParameters->setFudgeMean( E032point5bin, eta250bin, eflowFirstIntRegions::EME2, 0.690000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta250bin, eflowFirstIntRegions::EME2, 0.127000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta250bin, eflowFirstIntRegions::EME2, 0.690000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta250bin, eflowFirstIntRegions::EME2, 0.127000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta250bin, eflowFirstIntRegions::EME2, eflowCalo::EME1, NORM1,1.20666);
@@ -3189,8 +3189,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME3
-    binnedParameters->setFudgeMean( E032point5bin, eta250bin, eflowFirstIntRegions::EME3, 0.692000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta250bin, eflowFirstIntRegions::EME3, 0.119000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta250bin, eflowFirstIntRegions::EME3, 0.692000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta250bin, eflowFirstIntRegions::EME3, 0.119000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta250bin, eflowFirstIntRegions::EME3, eflowCalo::EME1, NORM1,0.446582);
@@ -3224,8 +3224,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = HEC
-    binnedParameters->setFudgeMean( E032point5bin, eta250bin, eflowFirstIntRegions::HEC, 0.739000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta250bin, eflowFirstIntRegions::HEC, 0.136000 ); 
+    binnedParameters->setFudgeMean( E032point5bin, eta250bin, eflowFirstIntRegions::HEC, 0.739000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta250bin, eflowFirstIntRegions::HEC, 0.136000 );
 
 
     binnedParameters->setShapeParam( E032point5bin, eta250bin, eflowFirstIntRegions::HEC, eflowCalo::EMB1, NORM1,0.0153596);
@@ -3306,8 +3306,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E040bin, eta050bin, eflowFirstIntRegions::EMB1, 0.730000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta050bin, eflowFirstIntRegions::EMB1, 0.083000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta050bin, eflowFirstIntRegions::EMB1, 0.730000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta050bin, eflowFirstIntRegions::EMB1, 0.083000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta050bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,2.17614);
@@ -3333,8 +3333,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E040bin, eta050bin, eflowFirstIntRegions::EMB2, 0.729000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta050bin, eflowFirstIntRegions::EMB2, 0.084000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta050bin, eflowFirstIntRegions::EMB2, 0.729000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta050bin, eflowFirstIntRegions::EMB2, 0.084000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta050bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.67587);
@@ -3360,8 +3360,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E040bin, eta050bin, eflowFirstIntRegions::EMB3, 0.646000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta050bin, eflowFirstIntRegions::EMB3, 0.080000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta050bin, eflowFirstIntRegions::EMB3, 0.646000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta050bin, eflowFirstIntRegions::EMB3, 0.080000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta050bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.120833);
@@ -3403,8 +3403,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E040bin, eta050bin, eflowFirstIntRegions::Tile, 0.801000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta050bin, eflowFirstIntRegions::Tile, 0.089000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta050bin, eflowFirstIntRegions::Tile, 0.801000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta050bin, eflowFirstIntRegions::Tile, 0.089000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta050bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.0661352);
@@ -3428,8 +3428,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E040bin, eta100bin, eflowFirstIntRegions::EMB1, 0.708000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta100bin, eflowFirstIntRegions::EMB1, 0.091000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta100bin, eflowFirstIntRegions::EMB1, 0.708000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta100bin, eflowFirstIntRegions::EMB1, 0.091000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta100bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,1.56119);
@@ -3459,8 +3459,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E040bin, eta100bin, eflowFirstIntRegions::EMB2, 0.717000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta100bin, eflowFirstIntRegions::EMB2, 0.085000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta100bin, eflowFirstIntRegions::EMB2, 0.717000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta100bin, eflowFirstIntRegions::EMB2, 0.085000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta100bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.392916);
@@ -3490,8 +3490,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E040bin, eta100bin, eflowFirstIntRegions::EMB3, 0.617000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta100bin, eflowFirstIntRegions::EMB3, 0.089000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta100bin, eflowFirstIntRegions::EMB3, 0.617000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta100bin, eflowFirstIntRegions::EMB3, 0.089000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta100bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.0779037);
@@ -3541,8 +3541,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E040bin, eta100bin, eflowFirstIntRegions::Tile, 0.787000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta100bin, eflowFirstIntRegions::Tile, 0.106000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta100bin, eflowFirstIntRegions::Tile, 0.787000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta100bin, eflowFirstIntRegions::Tile, 0.106000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta100bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.0522344);
@@ -3574,8 +3574,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     ////////////////////////////
 
    // j1st = EMB1
-    binnedParameters->setFudgeMean( E040bin, eta150bin, eflowFirstIntRegions::EMB1, 0.693000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta150bin, eflowFirstIntRegions::EMB1, 0.112000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta150bin, eflowFirstIntRegions::EMB1, 0.693000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta150bin, eflowFirstIntRegions::EMB1, 0.112000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta150bin, eflowFirstIntRegions::EMB1, eflowCalo::EMB1, NORM1,1.04058);
@@ -3613,8 +3613,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB2
-    binnedParameters->setFudgeMean( E040bin, eta150bin, eflowFirstIntRegions::EMB2, 0.721000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta150bin, eflowFirstIntRegions::EMB2, 0.126000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta150bin, eflowFirstIntRegions::EMB2, 0.721000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta150bin, eflowFirstIntRegions::EMB2, 0.126000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta150bin, eflowFirstIntRegions::EMB2, eflowCalo::EMB1, NORM1,0.417358);
@@ -3652,8 +3652,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EMB3
-    binnedParameters->setFudgeMean( E040bin, eta150bin, eflowFirstIntRegions::EMB3, 0.720000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta150bin, eflowFirstIntRegions::EMB3, 0.108000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta150bin, eflowFirstIntRegions::EMB3, 0.720000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta150bin, eflowFirstIntRegions::EMB3, 0.108000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta150bin, eflowFirstIntRegions::EMB3, eflowCalo::EMB1, NORM1,0.0769331);
@@ -3695,15 +3695,15 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME1
-    binnedParameters->setFudgeMean( E040bin, eta150bin, eflowFirstIntRegions::EME1, 0.563000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta150bin, eflowFirstIntRegions::EME1, 0.140000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta150bin, eflowFirstIntRegions::EME1, 0.563000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta150bin, eflowFirstIntRegions::EME1, 0.140000 );
 
 
 
 
    // j1st = EME2
-    binnedParameters->setFudgeMean( E040bin, eta150bin, eflowFirstIntRegions::EME2, 0.627000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta150bin, eflowFirstIntRegions::EME2, 0.127000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta150bin, eflowFirstIntRegions::EME2, 0.627000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta150bin, eflowFirstIntRegions::EME2, 0.127000 );
 
 
 
@@ -3751,8 +3751,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = Tile
-    binnedParameters->setFudgeMean( E040bin, eta150bin, eflowFirstIntRegions::Tile, 0.822000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta150bin, eflowFirstIntRegions::Tile, 0.110000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta150bin, eflowFirstIntRegions::Tile, 0.822000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta150bin, eflowFirstIntRegions::Tile, 0.110000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta150bin, eflowFirstIntRegions::Tile, eflowCalo::EMB1, NORM1,0.0641832);
@@ -3831,8 +3831,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME1
-    binnedParameters->setFudgeMean( E040bin, eta250bin, eflowFirstIntRegions::EME1, 0.697000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta250bin, eflowFirstIntRegions::EME1, 0.123000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta250bin, eflowFirstIntRegions::EME1, 0.697000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta250bin, eflowFirstIntRegions::EME1, 0.123000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta250bin, eflowFirstIntRegions::EME1, eflowCalo::EME1, NORM1,6.5128);
@@ -3866,8 +3866,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME2
-    binnedParameters->setFudgeMean( E040bin, eta250bin, eflowFirstIntRegions::EME2, 0.736000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta250bin, eflowFirstIntRegions::EME2, 0.100000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta250bin, eflowFirstIntRegions::EME2, 0.736000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta250bin, eflowFirstIntRegions::EME2, 0.100000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta250bin, eflowFirstIntRegions::EME2, eflowCalo::EME1, NORM1,1.73191);
@@ -3901,8 +3901,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = EME3
-    binnedParameters->setFudgeMean( E040bin, eta250bin, eflowFirstIntRegions::EME3, 0.729000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta250bin, eflowFirstIntRegions::EME3, 0.095000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta250bin, eflowFirstIntRegions::EME3, 0.729000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta250bin, eflowFirstIntRegions::EME3, 0.095000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta250bin, eflowFirstIntRegions::EME3, eflowCalo::EME1, NORM1,0.323704);
@@ -3936,8 +3936,8 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
 
 
    // j1st = HEC
-    binnedParameters->setFudgeMean( E040bin, eta250bin, eflowFirstIntRegions::HEC, 0.763000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta250bin, eflowFirstIntRegions::HEC, 0.111000 ); 
+    binnedParameters->setFudgeMean( E040bin, eta250bin, eflowFirstIntRegions::HEC, 0.763000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta250bin, eflowFirstIntRegions::HEC, 0.111000 );
 
 
     binnedParameters->setShapeParam( E040bin, eta250bin, eflowFirstIntRegions::HEC, eflowCalo::EMB1, NORM1,0.0236786);
@@ -4022,109 +4022,109 @@ StatusCode eflowCellEOverPTool_mc12_HLLHC::execute(eflowEEtaBinnedParameters *bi
     binnedParameters->setShapeParam( E040bin, eta250bin, eflowFirstIntRegions::Tile, eflowCalo::Tile2, NORM2,0.00138243);
     binnedParameters->setShapeParam( E040bin, eta250bin, eflowFirstIntRegions::Tile, eflowCalo::Tile2, WIDTH2,0.0876664);
 
-    binnedParameters->setFudgeMean( E001bin, eta350bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta350bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeMean( E003point5bin, eta350bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta350bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeMean( E010bin, eta350bin, eflowFirstIntRegions::EME1, 0.619000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta350bin, eflowFirstIntRegions::EME1, 0.613000 ); 
-    binnedParameters->setFudgeMean( E020bin, eta350bin, eflowFirstIntRegions::EME1, 0.532000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta350bin, eflowFirstIntRegions::EME1, 0.233000 ); 
-    binnedParameters->setFudgeMean( E032point5bin, eta350bin, eflowFirstIntRegions::EME1, 0.572000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta350bin, eflowFirstIntRegions::EME1, 0.130000 ); 
-    binnedParameters->setFudgeMean( E040bin, eta350bin, eflowFirstIntRegions::EME1, 0.639000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta350bin, eflowFirstIntRegions::EME1, 0.195000 ); 
-
-    binnedParameters->setFudgeMean( E001bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeMean( E003point5bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeMean( E010bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeMean( E020bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeMean( E032point5bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeMean( E040bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 ); 
-
-    binnedParameters->setFudgeMean( E001bin, eta350bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta350bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeMean( E003point5bin, eta350bin, eflowFirstIntRegions::EME2, 0.300000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta350bin, eflowFirstIntRegions::EME2, 1.837000 ); 
-    binnedParameters->setFudgeMean( E010bin, eta350bin, eflowFirstIntRegions::EME2, 0.515000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta350bin, eflowFirstIntRegions::EME2, 0.203000 ); 
-    binnedParameters->setFudgeMean( E020bin, eta350bin, eflowFirstIntRegions::EME2, 0.594000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta350bin, eflowFirstIntRegions::EME2, 0.186000 ); 
-    binnedParameters->setFudgeMean( E032point5bin, eta350bin, eflowFirstIntRegions::EME2, 0.636000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta350bin, eflowFirstIntRegions::EME2, 0.148000 ); 
-    binnedParameters->setFudgeMean( E040bin, eta350bin, eflowFirstIntRegions::EME2, 0.693000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta350bin, eflowFirstIntRegions::EME2, 0.131000 ); 
-
-    binnedParameters->setFudgeMean( E001bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeMean( E003point5bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeMean( E010bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeMean( E020bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeMean( E032point5bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeMean( E040bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 ); 
-
-    binnedParameters->setFudgeMean( E001bin, eta350bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta350bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeMean( E003point5bin, eta350bin, eflowFirstIntRegions::EME3, 0.424000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta350bin, eflowFirstIntRegions::EME3, 0.253000 ); 
-    binnedParameters->setFudgeMean( E010bin, eta350bin, eflowFirstIntRegions::EME3, 0.549000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta350bin, eflowFirstIntRegions::EME3, 0.230000 ); 
-    binnedParameters->setFudgeMean( E020bin, eta350bin, eflowFirstIntRegions::EME3, 0.612000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta350bin, eflowFirstIntRegions::EME3, 0.166000 ); 
-    binnedParameters->setFudgeMean( E032point5bin, eta350bin, eflowFirstIntRegions::EME3, 0.642000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta350bin, eflowFirstIntRegions::EME3, 0.139000 ); 
-    binnedParameters->setFudgeMean( E040bin, eta350bin, eflowFirstIntRegions::EME3, 0.687000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta350bin, eflowFirstIntRegions::EME3, 0.120000 ); 
-
-    binnedParameters->setFudgeMean( E001bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeMean( E003point5bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeMean( E010bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeMean( E020bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeMean( E032point5bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeMean( E040bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 ); 
-
-    binnedParameters->setFudgeMean( E001bin, eta350bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta350bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeMean( E003point5bin, eta350bin, eflowFirstIntRegions::HEC, 0.971000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta350bin, eflowFirstIntRegions::HEC, 0.500000 ); 
-    binnedParameters->setFudgeMean( E010bin, eta350bin, eflowFirstIntRegions::HEC, 0.636000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta350bin, eflowFirstIntRegions::HEC, 0.220000 ); 
-    binnedParameters->setFudgeMean( E020bin, eta350bin, eflowFirstIntRegions::HEC, 0.682000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta350bin, eflowFirstIntRegions::HEC, 0.180000 ); 
-    binnedParameters->setFudgeMean( E032point5bin, eta350bin, eflowFirstIntRegions::HEC, 0.705000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta350bin, eflowFirstIntRegions::HEC, 0.145000 ); 
-    binnedParameters->setFudgeMean( E040bin, eta350bin, eflowFirstIntRegions::HEC, 0.732000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta350bin, eflowFirstIntRegions::HEC, 0.130000 ); 
-
-    binnedParameters->setFudgeMean( E001bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E001bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeMean( E003point5bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E003point5bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeMean( E010bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E010bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeMean( E020bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E020bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeMean( E032point5bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E032point5bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeMean( E040bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 ); 
-    binnedParameters->setFudgeStdDev( E040bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 ); 
+    binnedParameters->setFudgeMean( E001bin, eta350bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta350bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeMean( E003point5bin, eta350bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta350bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeMean( E010bin, eta350bin, eflowFirstIntRegions::EME1, 0.619000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta350bin, eflowFirstIntRegions::EME1, 0.613000 );
+    binnedParameters->setFudgeMean( E020bin, eta350bin, eflowFirstIntRegions::EME1, 0.532000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta350bin, eflowFirstIntRegions::EME1, 0.233000 );
+    binnedParameters->setFudgeMean( E032point5bin, eta350bin, eflowFirstIntRegions::EME1, 0.572000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta350bin, eflowFirstIntRegions::EME1, 0.130000 );
+    binnedParameters->setFudgeMean( E040bin, eta350bin, eflowFirstIntRegions::EME1, 0.639000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta350bin, eflowFirstIntRegions::EME1, 0.195000 );
+
+    binnedParameters->setFudgeMean( E001bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeMean( E003point5bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeMean( E010bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeMean( E020bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeMean( E032point5bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeMean( E040bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta450bin, eflowFirstIntRegions::EME1, 0.000000 );
+
+    binnedParameters->setFudgeMean( E001bin, eta350bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta350bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeMean( E003point5bin, eta350bin, eflowFirstIntRegions::EME2, 0.300000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta350bin, eflowFirstIntRegions::EME2, 1.837000 );
+    binnedParameters->setFudgeMean( E010bin, eta350bin, eflowFirstIntRegions::EME2, 0.515000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta350bin, eflowFirstIntRegions::EME2, 0.203000 );
+    binnedParameters->setFudgeMean( E020bin, eta350bin, eflowFirstIntRegions::EME2, 0.594000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta350bin, eflowFirstIntRegions::EME2, 0.186000 );
+    binnedParameters->setFudgeMean( E032point5bin, eta350bin, eflowFirstIntRegions::EME2, 0.636000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta350bin, eflowFirstIntRegions::EME2, 0.148000 );
+    binnedParameters->setFudgeMean( E040bin, eta350bin, eflowFirstIntRegions::EME2, 0.693000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta350bin, eflowFirstIntRegions::EME2, 0.131000 );
+
+    binnedParameters->setFudgeMean( E001bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeMean( E003point5bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeMean( E010bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeMean( E020bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeMean( E032point5bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeMean( E040bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta450bin, eflowFirstIntRegions::EME2, 0.000000 );
+
+    binnedParameters->setFudgeMean( E001bin, eta350bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta350bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeMean( E003point5bin, eta350bin, eflowFirstIntRegions::EME3, 0.424000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta350bin, eflowFirstIntRegions::EME3, 0.253000 );
+    binnedParameters->setFudgeMean( E010bin, eta350bin, eflowFirstIntRegions::EME3, 0.549000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta350bin, eflowFirstIntRegions::EME3, 0.230000 );
+    binnedParameters->setFudgeMean( E020bin, eta350bin, eflowFirstIntRegions::EME3, 0.612000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta350bin, eflowFirstIntRegions::EME3, 0.166000 );
+    binnedParameters->setFudgeMean( E032point5bin, eta350bin, eflowFirstIntRegions::EME3, 0.642000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta350bin, eflowFirstIntRegions::EME3, 0.139000 );
+    binnedParameters->setFudgeMean( E040bin, eta350bin, eflowFirstIntRegions::EME3, 0.687000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta350bin, eflowFirstIntRegions::EME3, 0.120000 );
+
+    binnedParameters->setFudgeMean( E001bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeMean( E003point5bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeMean( E010bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeMean( E020bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeMean( E032point5bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeMean( E040bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta450bin, eflowFirstIntRegions::EME3, 0.000000 );
+
+    binnedParameters->setFudgeMean( E001bin, eta350bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta350bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeMean( E003point5bin, eta350bin, eflowFirstIntRegions::HEC, 0.971000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta350bin, eflowFirstIntRegions::HEC, 0.500000 );
+    binnedParameters->setFudgeMean( E010bin, eta350bin, eflowFirstIntRegions::HEC, 0.636000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta350bin, eflowFirstIntRegions::HEC, 0.220000 );
+    binnedParameters->setFudgeMean( E020bin, eta350bin, eflowFirstIntRegions::HEC, 0.682000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta350bin, eflowFirstIntRegions::HEC, 0.180000 );
+    binnedParameters->setFudgeMean( E032point5bin, eta350bin, eflowFirstIntRegions::HEC, 0.705000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta350bin, eflowFirstIntRegions::HEC, 0.145000 );
+    binnedParameters->setFudgeMean( E040bin, eta350bin, eflowFirstIntRegions::HEC, 0.732000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta350bin, eflowFirstIntRegions::HEC, 0.130000 );
+
+    binnedParameters->setFudgeMean( E001bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeStdDev( E001bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeMean( E003point5bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeStdDev( E003point5bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeMean( E010bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeStdDev( E010bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeMean( E020bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeStdDev( E020bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeMean( E032point5bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeStdDev( E032point5bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeMean( E040bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 );
+    binnedParameters->setFudgeStdDev( E040bin, eta450bin, eflowFirstIntRegions::HEC, 0.000000 );
 
     binnedParameters->setFudgeMean( E001bin, eta350bin, eflowFirstIntRegions::FCAL, 0.000000 );
     binnedParameters->setFudgeStdDev( E001bin, eta350bin, eflowFirstIntRegions::FCAL, 0.000000 );
diff --git a/Reconstruction/eflowRec/src/eflowCellEOverPTool_mc12_JetETMiss.cxx b/Reconstruction/eflowRec/src/eflowCellEOverPTool_mc12_JetETMiss.cxx
index 4ea723a7072f33c2285515864acedbf16c0350a3..0a3a70003c47da02683f7f1307ade7ecdbb1c001 100644
--- a/Reconstruction/eflowRec/src/eflowCellEOverPTool_mc12_JetETMiss.cxx
+++ b/Reconstruction/eflowRec/src/eflowCellEOverPTool_mc12_JetETMiss.cxx
@@ -35,10 +35,10 @@ StatusCode eflowCellEOverPTool_mc12_JetETMiss::initialize(){
   return StatusCode::SUCCESS;
 }
 
-StatusCode eflowCellEOverPTool_mc12_JetETMiss::execute(eflowEEtaBinnedParameters *binnedParameters){
+StatusCode eflowCellEOverPTool_mc12_JetETMiss::fillBinnedParameters(eflowEEtaBinnedParameters *binnedParameters) const {
 
   if (binnedParameters) {
-    
+
     binnedParameters->initialise(m_eBinValues, m_etaBinBounds);
 
     ////////////////////////////
diff --git a/Reconstruction/eflowRec/src/eflowCellEOverPTool_mc12_LC.cxx b/Reconstruction/eflowRec/src/eflowCellEOverPTool_mc12_LC.cxx
index 2024273ab28d53a3f58f3dd3bc6e581b7e1a9907..634e017af21bf4d2a67c40fe2be041c7dcfd5712 100644
--- a/Reconstruction/eflowRec/src/eflowCellEOverPTool_mc12_LC.cxx
+++ b/Reconstruction/eflowRec/src/eflowCellEOverPTool_mc12_LC.cxx
@@ -39,10 +39,10 @@ StatusCode eflowCellEOverPTool_mc12_LC::initialize(){
   return StatusCode::SUCCESS;
 }
 
-StatusCode eflowCellEOverPTool_mc12_LC::execute(eflowEEtaBinnedParameters *binnedParameters){
+StatusCode eflowCellEOverPTool_mc12_LC::fillBinnedParameters(eflowEEtaBinnedParameters *binnedParameters) const {
 
   if (binnedParameters) {
-    
+
     binnedParameters->initialise(m_eBinValues, m_etaBinBounds);
 
     ////////////////////////////
diff --git a/Reconstruction/egamma/egammaAlgs/src/EMBremCollectionBuilder.cxx b/Reconstruction/egamma/egammaAlgs/src/EMBremCollectionBuilder.cxx
index 3642deb631cecf3ab387af6a5d9bf337b37981dc..969e7ee50f97c250df82079f369467d3057394bb 100644
--- a/Reconstruction/egamma/egammaAlgs/src/EMBremCollectionBuilder.cxx
+++ b/Reconstruction/egamma/egammaAlgs/src/EMBremCollectionBuilder.cxx
@@ -192,9 +192,9 @@ EMBremCollectionBuilder::refitTracks(
 
 StatusCode
 EMBremCollectionBuilder::createCollections(
-  const std::vector<TrackWithIndex>& refitted,
-  const std::vector<TrackWithIndex>& failedfit,
-  const std::vector<TrackWithIndex>& trtAlone,
+  std::vector<TrackWithIndex>& refitted,
+  std::vector<TrackWithIndex>& failedfit,
+  std::vector<TrackWithIndex>& trtAlone,
   TrackCollection* finalTracks,
   xAOD::TrackParticleContainer* finalTrkPartContainer,
   const xAOD::TrackParticleContainer* AllTracks) const
@@ -223,87 +223,83 @@ EMBremCollectionBuilder::createCollections(
 
 StatusCode
 EMBremCollectionBuilder::createNew(
-  const TrackWithIndex& Info,
+  TrackWithIndex& Info,
   TrackCollection* finalTracks,
   xAOD::TrackParticleContainer* finalTrkPartContainer,
   const xAOD::TrackParticleContainer* AllTracks) const
 {
 
-  Trk::Track* track= Info.track.get();
-  size_t origIndex = Info.origIndex; 
+  size_t origIndex = Info.origIndex;
   const xAOD::TrackParticle* original = AllTracks->at(origIndex);
   /*
    * Create TrackParticle it should be now owned by finalTrkPartContainer
    */
   xAOD::TrackParticle* aParticle = m_particleCreatorTool->createParticle(
-    *track, finalTrkPartContainer, nullptr, xAOD::electron);
+    *(Info.track), finalTrkPartContainer, nullptr, xAOD::electron);
 
-  if (!aParticle){
-    ATH_MSG_WARNING("Could not create TrackParticle!!! for Track: " << *track);
+  if (!aParticle) {
+    ATH_MSG_WARNING(
+      "Could not create TrackParticle!!! for Track: " << *(Info.track));
     return StatusCode::SUCCESS;
   }
 
-  //Add an element link back to original Track Particle collection
+  // Add an element link back to original Track Particle collection
   static const SG::AuxElement::Accessor<
     ElementLink<xAOD::TrackParticleContainer>>
     tP("originalTrackParticle");
-  ElementLink<xAOD::TrackParticleContainer> linkToOriginal(*AllTracks,origIndex);   	  
-  tP(*aParticle) = linkToOriginal;	      
+  ElementLink<xAOD::TrackParticleContainer> linkToOriginal(*AllTracks,
+                                                           origIndex);
+  tP(*aParticle) = linkToOriginal;
 
-  if(m_doTruth){
-    //Add Truth decorations. Copy from the original.
+  if (m_doTruth) {
+    // Add Truth decorations. Copy from the original.
     static const SG::AuxElement::Accessor<
       ElementLink<xAOD::TruthParticleContainer>>
       tPL("truthParticleLink");
-    if(tPL.isAvailable(*original)){
-      ElementLink<xAOD::TruthParticleContainer> linkToTruth= tPL(*original);
-      tPL(*aParticle) = linkToTruth;	      
-    }	 
-    static const SG::AuxElement::Accessor<float >  tMP ("truthMatchProbability");
-    if(tMP.isAvailable(*original)){
+    if (tPL.isAvailable(*original)) {
+      ElementLink<xAOD::TruthParticleContainer> linkToTruth = tPL(*original);
+      tPL(*aParticle) = linkToTruth;
+    }
+    static const SG::AuxElement::Accessor<float> tMP("truthMatchProbability");
+    if (tMP.isAvailable(*original)) {
       float originalProbability = tMP(*original);
-      tMP(*aParticle)= originalProbability ;
+      tMP(*aParticle) = originalProbability;
     }
-    static const SG::AuxElement::Accessor<int> tT("truthType") ;
-    if(tT.isAvailable(*original)){
+    static const SG::AuxElement::Accessor<int> tT("truthType");
+    if (tT.isAvailable(*original)) {
       int truthType = tT(*original);
-      tT(*aParticle) = truthType ;
+      tT(*aParticle) = truthType;
     }
-    static const SG::AuxElement::Accessor<int> tO("truthOrigin") ;
-    if(tO.isAvailable(*original)){
+    static const SG::AuxElement::Accessor<int> tO("truthOrigin");
+    if (tO.isAvailable(*original)) {
       int truthOrigin = tO(*original);
-      tO(*aParticle) = truthOrigin ;
-    } 
-  }//End truth
+      tO(*aParticle) = truthOrigin;
+    }
+  } // End truth
 
   /*
    * Add qoverP from the last measurement
    */
-  static const SG::AuxElement::Accessor<float > QoverPLM  ("QoverPLM");
+  static const SG::AuxElement::Accessor<float> QoverPLM("QoverPLM");
   float QoverPLast(0);
-  auto rtsos = track->trackStateOnSurfaces()->rbegin();
-  for (;rtsos != track->trackStateOnSurfaces()->rend(); ++rtsos){
-    if ((*rtsos)->type(Trk::TrackStateOnSurface::Measurement) 
-        && (*rtsos)->trackParameters()!=nullptr
-        &&(*rtsos)->measurementOnTrack()!=nullptr
-        && !(*rtsos)->measurementOnTrack()->type(Trk::MeasurementBaseType::PseudoMeasurementOnTrack)) {
-      QoverPLast  = (*rtsos)->trackParameters()->parameters()[Trk::qOverP];
+  auto rtsos = Info.track->trackStateOnSurfaces()->rbegin();
+  for (; rtsos != Info.track->trackStateOnSurfaces()->rend(); ++rtsos) {
+    if ((*rtsos)->type(Trk::TrackStateOnSurface::Measurement) &&
+        (*rtsos)->trackParameters() != nullptr &&
+        (*rtsos)->measurementOnTrack() != nullptr &&
+        !(*rtsos)->measurementOnTrack()->type(
+          Trk::MeasurementBaseType::PseudoMeasurementOnTrack)) {
+      QoverPLast = (*rtsos)->trackParameters()->parameters()[Trk::qOverP];
       break;
     }
   }
   QoverPLM(*aParticle) = QoverPLast;
 
-  //Now  Slim the TrK::Track for writing to disk   
-  std::unique_ptr<Trk::Track> slimmed = m_slimTool->slimCopy(*track);
-  if(!slimmed){
-    ATH_MSG_WARNING ("TrackSlimming failed");
-    ElementLink<TrackCollection> dummy;
-    aParticle->setTrackLink(dummy);     
-  }else{
-    finalTracks->push_back(std::move(slimmed));
-    ElementLink<TrackCollection> trackLink(*finalTracks,finalTracks->size()-1);
-    aParticle->setTrackLink( trackLink );     
-  }
+  // Now  Slim the Trk::Track for writing to disk
+  m_slimTool->slimTrack(*(Info.track));
+  finalTracks->push_back(std::move(Info.track));
+  ElementLink<TrackCollection> trackLink(*finalTracks,finalTracks->size()-1);
+  aParticle->setTrackLink( trackLink );     
   return StatusCode::SUCCESS;
 }
 
diff --git a/Reconstruction/egamma/egammaAlgs/src/EMBremCollectionBuilder.h b/Reconstruction/egamma/egammaAlgs/src/EMBremCollectionBuilder.h
index cd0f9da03c2f8738f74afaa234fc2c7061263b8b..8dbb3cf1a1f1559c3958094f074ee4fc05ca62a5 100644
--- a/Reconstruction/egamma/egammaAlgs/src/EMBremCollectionBuilder.h
+++ b/Reconstruction/egamma/egammaAlgs/src/EMBremCollectionBuilder.h
@@ -73,14 +73,14 @@ private:
                          std::vector<TrackWithIndex>& failedfit) const;
 
   StatusCode createCollections(
-    const std::vector<TrackWithIndex>& refitted,
-    const std::vector<TrackWithIndex>& failedfit,
-    const std::vector<TrackWithIndex>& trtAlone,
+    std::vector<TrackWithIndex>& refitted,
+    std::vector<TrackWithIndex>& failedfit,
+    std::vector<TrackWithIndex>& trtAlone,
     TrackCollection* finalTracks,
     xAOD::TrackParticleContainer* finalTrkPartContainer,
     const xAOD::TrackParticleContainer* AllTracks) const;
 
-  StatusCode createNew(const TrackWithIndex& Info,
+  StatusCode createNew(TrackWithIndex& Info,
                        TrackCollection* finalTracks,
                        xAOD::TrackParticleContainer* finalTrkPartContainer,
                        const xAOD::TrackParticleContainer* AllTracks) const;
diff --git a/Reconstruction/egamma/egammaValidation/src/ClusterHistograms.cxx b/Reconstruction/egamma/egammaValidation/src/ClusterHistograms.cxx
index d32ad1a47764e0ccda0aef8bad19e7aeabf6f4c3..b9de6cc501a99804469a9a080d8fad7622ebfc03 100644
--- a/Reconstruction/egamma/egammaValidation/src/ClusterHistograms.cxx
+++ b/Reconstruction/egamma/egammaValidation/src/ClusterHistograms.cxx
@@ -15,7 +15,7 @@ StatusCode ClusterHistograms::initializePlots() {
   histo2DMap["number_cells_vs_et_in_layer_0_2D"] = (new TH2D(Form("%s_%s",m_name.c_str(),"number_cells_vs_et_in_layer_0_2D"), "Number of cells;E_{T}", 60,0,300,50,   0,100.));
   histo2DMap["number_cells_vs_et_in_layer_1_2D"] = (new TH2D(Form("%s_%s",m_name.c_str(),"number_cells_vs_et_in_layer_1_2D"), "Number of cells;E_{T}", 60,0,300,50,   0,100.));
   histo2DMap["number_cells_vs_et_in_layer_2_2D"] = (new TH2D(Form("%s_%s",m_name.c_str(),"number_cells_vs_et_in_layer_2_2D"), "Number of cells;E_{T}", 60,0,300,50,   0,100.));
-  histo2DMap["number_cells_vs_et_in_layer_3_2D"] = (new TH2D(Form("%s_%s",m_name.c_str(),"number_cells_vs_et_in_layer_3_2D"), "Number of cells;E_{T}", 600,0,300,50,   0,100.));
+  histo2DMap["number_cells_vs_et_in_layer_3_2D"] = (new TH2D(Form("%s_%s",m_name.c_str(),"number_cells_vs_et_in_layer_3_2D"), "Number of cells;E_{T}", 60,0,300,50,   0,100.));
   
   histo2DMap["number_cell_in_layer"] = (new TH2D(Form("%s_%s",m_name.c_str(),"number_cell_in_layer"), ";Number of cells;Layer",100,0,200, 4,0,4));  
   histo2DMap["mu_energy_resolution_2D"] = (new TH2D(Form("%s_%s",m_name.c_str(),"mu_energy_resolution_2D"), ";<#mu>; Energy Resolution", 5,0,80,20,-1,1));
diff --git a/Reconstruction/egamma/egammaValidation/src/ShowerShapesHistograms.cxx b/Reconstruction/egamma/egammaValidation/src/ShowerShapesHistograms.cxx
index d17464aaaea9fec8c74100a59df4deaa2449afb4..69c66784f5bd467db03942c72c0540ca92b1f2a9 100644
--- a/Reconstruction/egamma/egammaValidation/src/ShowerShapesHistograms.cxx
+++ b/Reconstruction/egamma/egammaValidation/src/ShowerShapesHistograms.cxx
@@ -17,9 +17,9 @@ StatusCode ShowerShapesHistograms::initializePlots() {
   histoMap["rphi"]    = (new TH1D(Form("%s_%s",m_name.c_str(),"rphi"   ), ";R_{#phi}; R_{#phi} Events"                  , 355,  0.  ,  1.1005));
   histoMap["weta2"]   = (new TH1D(Form("%s_%s",m_name.c_str(),"weta2"  ), ";W_{#etas2}; W_{#etas2} Events"              , 100,  0.  ,  0.03  ));
   histoMap["eratio"]  = (new TH1D(Form("%s_%s",m_name.c_str(),"eratio" ), ";E_{ratio}; E_{ratio} Events"                , 100,  0.  ,  1.    ));
-  histoMap["deltae"]  = (new TH1D(Form("%s_%s",m_name.c_str(),"deltae" ), ";#DeltaE [GeV]; #DeltaE Events"              , 250,  0.  ,  0.5   ));
+  histoMap["deltae"]  = (new TH1D(Form("%s_%s",m_name.c_str(),"deltae" ), ";#DeltaE [GeV]; #DeltaE Events"              , 100,  0.  ,  0.1   ));
   histoMap["f1"]      = (new TH1D(Form("%s_%s",m_name.c_str(),"f1"     ), ";f_{1}; f_{1} Events"                        , 100,  0.  ,  1.0   ));
-  histoMap["fside"]   = (new TH1D(Form("%s_%s",m_name.c_str(),"fside"  ), ";f_{side}; f_{side} Events"                  , 350,  0.  ,  3.5   ));
+  histoMap["fside"]   = (new TH1D(Form("%s_%s",m_name.c_str(),"fside"  ), ";f_{side}; f_{side} Events"                  , 100,  0.  ,  2.0   ));
   histoMap["wtots1"]  = (new TH1D(Form("%s_%s",m_name.c_str(),"wtots1" ), ";w_{s, tot}; w_{s, tot} Events"              , 100,  0.  , 10.    ));
   histoMap["ws3"]     = (new TH1D(Form("%s_%s",m_name.c_str(),"ws3"    ), ";w_{s, 3}; w_{s, 3} Events"                  , 100,  0.  ,  1.    ));
   histoMap["lateral"] = (new TH1D(Form("%s_%s",m_name.c_str(),"lateral"), ";Lateral of seed; Events", 50, 0, 1));
diff --git a/Reconstruction/egamma/egammaValidation/src/TruthElectronHistograms.cxx b/Reconstruction/egamma/egammaValidation/src/TruthElectronHistograms.cxx
index 7cac5c16162bf9dbc8672d1cda0d2ec5abe4a4bb..07d7b265cefc434ef0f7eb5f0af2bd80139c669c 100644
--- a/Reconstruction/egamma/egammaValidation/src/TruthElectronHistograms.cxx
+++ b/Reconstruction/egamma/egammaValidation/src/TruthElectronHistograms.cxx
@@ -13,11 +13,11 @@ using namespace egammaMonitoring;
 
 StatusCode TruthElectronHistograms::initializePlots() {
 
-  histoMap["deltaPhi2"] = new TH1D(Form("%s_%s",m_name.c_str(),"deltaPhi2"), ";deltaPhi2; Events", 20, -0.06, 0.06);
-  histoMap["deltaEta2"] = new TH1D(Form("%s_%s",m_name.c_str(),"deltaEta2"), ";deltaEta2; Events", 20, -0.04, 0.04);
-  histoMap["deltaPhiRescaled2"] = new TH1D(Form("%s_%s",m_name.c_str(),"deltaPhiRescaled2"), ";deltaPhi2; Events", 20, -0.04, 0.04);
+  histoMap["deltaPhi2"] = new TH1D(Form("%s_%s",m_name.c_str(),"deltaPhi2"), ";deltaPhi2; Events", 40, -0.06, 0.06);
+  histoMap["deltaEta2"] = new TH1D(Form("%s_%s",m_name.c_str(),"deltaEta2"), ";deltaEta2; Events", 40, -0.04, 0.04);
+  histoMap["deltaPhiRescaled2"] = new TH1D(Form("%s_%s",m_name.c_str(),"deltaPhiRescaled2"), ";deltaPhi2; Events", 40, -0.04, 0.04);
 
-  histoMap["d0Oversigmad0"] = new TH1D(Form("%s_%s",m_name.c_str(),"d0Oversigmad0"), "; d0Oversigmad0; Events", 20, -10, 10);
+  histoMap["d0Oversigmad0"] = new TH1D(Form("%s_%s",m_name.c_str(),"d0Oversigmad0"), "; d0Oversigmad0; Events", 40, -10, 10);
   histoMap["qOverp_resolution"] = new TH1D(Form("%s_%s",m_name.c_str(),"qOverp_resolution"), ";(q/P reco - q/P truth)/ q/p truth; Events", 60, -1, 1.5);
 
 
diff --git a/Reconstruction/tauRec/python/tauRecFlags.py b/Reconstruction/tauRec/python/tauRecFlags.py
index 3e9f8fa0b4e9f312581eb5fc34d6903762a213bf..6ec2d19d5914c4df43419f33acf3848784bfb84c 100644
--- a/Reconstruction/tauRec/python/tauRecFlags.py
+++ b/Reconstruction/tauRec/python/tauRecFlags.py
@@ -52,6 +52,12 @@ class tauRecToolsCVMFSPath(JobProperty):
     allowedTypes=['string']
     StoredValue="tauRecTools/00-02-00/"
 
+class doTJVA(JobProperty):
+    """ switch of TJVA """
+    statusOn=True
+    allowedTypes=['bool']
+    StoredValue=True
+
 #deprecated
 class TauDiscriminantCVMFSPath(JobProperty):
     """ path to cvmfs file location
@@ -141,11 +147,10 @@ class doPanTau(JobProperty):
     StoredValue=True
 
 class doPi0(JobProperty):
-    """ switch on Pi0 Finder
-    """
+    """ switch of Pi0 Finder """
     statusOn=True
     allowedTypes=['bool']
-    StoredValue=False
+    StoredValue=True
 
 class pi0EtCuts(JobProperty):
     """ Set |eta| dependent Et requirement for pi0 tag
@@ -205,7 +210,7 @@ class tauRecFlags(JobPropertyContainer):
 jobproperties.add_Container(tauRecFlags)
 
 # I want always the following flags in the Rec container  
-_list_tau=[Enabled,doTauRec,isStandalone,tauRecSeedJetCollection,tauRecToolsCVMFSPath,TauDiscriminantCVMFSPath,tauRecMVATrackClassification,tauRecRNNTrackClassification,tauRecMVATrackClassificationConfig,tauRecRNNTrackClassificationConfig,tauRecSeedMaxEta,tauRecToolsDevToolList,tauRecToolsDevToolListProcessor,doRunTauDiscriminant,useVertexBasedConvFinder,useNewPIDBasedConvFinder,doPanTau,doPi0,pi0EtCuts,pi0MVACuts_1prong,pi0MVACuts_mprong,shotPtCut_1Photon,shotPtCut_2Photons,useOldVertexFitterAPI,useShowerSubClusters]
+_list_tau=[Enabled,doTauRec,isStandalone,tauRecSeedJetCollection,tauRecToolsCVMFSPath,doTJVA,TauDiscriminantCVMFSPath,tauRecMVATrackClassification,tauRecRNNTrackClassification,tauRecMVATrackClassificationConfig,tauRecRNNTrackClassificationConfig,tauRecSeedMaxEta,tauRecToolsDevToolList,tauRecToolsDevToolListProcessor,doRunTauDiscriminant,useVertexBasedConvFinder,useNewPIDBasedConvFinder,doPanTau,doPi0,pi0EtCuts,pi0MVACuts_1prong,pi0MVACuts_mprong,shotPtCut_1Photon,shotPtCut_2Photons,useOldVertexFitterAPI,useShowerSubClusters]
 for j in _list_tau: 
     jobproperties.tauRecFlags.add_JobProperty(j)
 del _list_tau
diff --git a/Reconstruction/tauRec/share/tauRec_jobOptions.py b/Reconstruction/tauRec/share/tauRec_jobOptions.py
index 50f62486ad0eedb3ffd0c9c8922a291d2db7b91e..7523c60066c9d03320841f9c11780d5c344b6468 100644
--- a/Reconstruction/tauRec/share/tauRec_jobOptions.py
+++ b/Reconstruction/tauRec/share/tauRec_jobOptions.py
@@ -12,29 +12,19 @@ from RecExConfig.RecFlags import rec
 from AthenaCommon.BeamFlags import jobproperties
 from AthenaCommon.GlobalFlags import globalflags
 import AthenaCommon.SystemOfUnits as Units
-from tauRec.tauRecFlags import jobproperties as taujp
+from tauRec.tauRecFlags import tauFlags
 
 # use Tau Jet Vertex Association Tool
-# each Tau candidate gets its own primary vertex
-# and the tracks are selected accroding to this vertex
-_doTJVA = True
+_doTJVA = tauFlags.doTJVA()
 
 # Pi0-finding algorithm
-_doPi0Clus = taujp.tauRecFlags.doPi0() #False by default
-_doPi0Clus = True 
+_doPi0Clus = tauFlags.doPi0()
 
-# Change jet seed (default AntiKt4LCTopoJets)
-# taujp.tauRecFlags.tauRecSeedJetCollection.set_Value_and_Lock("AntiKt4LCTopoJets")
-
-# the TauCoreBuilder
 from tauRec.TauRecBuilder import TauRecCoreBuilder
 TauRecCoreBuilder(doPi0Clus=_doPi0Clus, doTJVA=_doTJVA)
 
-#include("tauRec/Pi0ClusterMaker_Crakow_jobOptions.py")
 if _doPi0Clus:
     include("tauRec/Pi0ClusterMaker_jobOptions.py")
 
 from tauRec.TauRecRunner import TauRecRunner
 TauRecRunner(doPi0Clus=_doPi0Clus, doTJVA=_doTJVA)
-
-
diff --git a/Reconstruction/tauRec/test/test_tau_q221_serial.sh b/Reconstruction/tauRec/test/test_tau_q221_serial.sh
new file mode 100755
index 0000000000000000000000000000000000000000..9280bfca3a1f3690c3352dbcd4c8840ea51dd27a
--- /dev/null
+++ b/Reconstruction/tauRec/test/test_tau_q221_serial.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+#
+# art-description: q221 reconstruction ART on MC in serial mode
+# art-type: grid
+# art-include: master/Athena
+# art-output: myAOD.pool.root
+# art-output: NTUP_PHYSVAL.root
+# art-output: rootcomp.root
+# art-output: *.log
+# art-output: *.ps
+# art-output: dcube
+# art-html: dcube
+
+NEVENTS=500
+REF_DIR="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/tauRec/reference/q221"
+
+# run the reconstruction
+Reco_tf.py --maxEvents ${NEVENTS} --AMI q221
+echo "art-result: $? Reconstrution"
+
+# compare the AOD file
+art.py compare ref --entries 200 --mode semi-detailed --order-trees --diff-root myAOD.pool.root ${REF_DIR}/myAOD.pool.root >> AOD_diff_root.log 2>&1
+echo "art-result: $? diff-root"
+
+# run the physics validation
+Reco_tf.py --maxEvents ${NEVENTS} --validationFlags 'noExample,doTau' --inputAODFile myAOD.pool.root  --outputNTUP_PHYSVALFile NTUP_PHYSVAL.root
+echo "art-result: $? PhysVal"
+
+# compare the histograms
+rootcomp.py NTUP_PHYSVAL.root ${REF_DIR}/NTUP_PHYSVAL.root >> rootcomp.log 2>&1
+echo "art-result: $? rootcomp"
+
+# run dcube
+INPUT_DIR="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/tauRec/input"
+$ATLAS_LOCAL_ROOT/dcube/current/DCubeClient/python/dcube.py \
+    --plot --output dcube \
+    --config ${INPUT_DIR}/config_mc.xml \
+    --reference ${REF_DIR}/NTUP_PHYSVAL.root \
+    NTUP_PHYSVAL.root
+echo "art-result: $? dcube"
diff --git a/Reconstruction/tauRec/test/test_tau_q431.sh b/Reconstruction/tauRec/test/test_tau_q431_serial.sh
similarity index 79%
rename from Reconstruction/tauRec/test/test_tau_q431.sh
rename to Reconstruction/tauRec/test/test_tau_q431_serial.sh
index 272f65b27e671d41b85c2b8e0104a69d96246b5f..da986bd30c1374a698e0c851065f7d9a845e59d5 100755
--- a/Reconstruction/tauRec/test/test_tau_q431.sh
+++ b/Reconstruction/tauRec/test/test_tau_q431_serial.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 #
-# art-description: ART for standalone tau reconstruction
+# art-description: q431 reconstruction ART on data in serail mode
 # art-type: grid
 # art-include: master/Athena
 # art-output: myAOD.pool.root
@@ -15,7 +15,7 @@ NEVENTS=500
 REF_DIR="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/tauRec/reference/q431"
 
 # run the reconstruction
-Reco_tf.py --maxEvents=${NEVENTS} --AMI=q431
+Reco_tf.py --maxEvents ${NEVENTS} --AMI=q431
 echo "art-result: $? Reconstrution"
 
 # compare the AOD file
@@ -23,7 +23,7 @@ art.py compare ref --entries 200 --mode=semi-detailed --order-trees --diff-root
 echo "art-result: $? diff-root"
 
 # run the physics validation
-Reco_tf.py --maxEvents=${NEVENTS} --validationFlags 'noExample,doTau' --inputAODFile=myAOD.pool.root  --outputNTUP_PHYSVALFile=NTUP_PHYSVAL.root
+Reco_tf.py --maxEvents ${NEVENTS} --validationFlags 'noExample,doTau' --inputAODFile=myAOD.pool.root  --outputNTUP_PHYSVALFile NTUP_PHYSVAL.root
 echo "art-result: $? PhysVal"
 
 # compare the histograms
@@ -34,7 +34,7 @@ echo "art-result: $? rootcomp"
 INPUT_DIR="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/tauRec/input"
 $ATLAS_LOCAL_ROOT/dcube/current/DCubeClient/python/dcube.py \
     --plot --output dcube \
-    --config ${INPUT_DIR}/config.xml \
+    --config ${INPUT_DIR}/config_data.xml \
     --reference ${REF_DIR}/NTUP_PHYSVAL.root \
     NTUP_PHYSVAL.root
 echo "art-result: $? dcube"
diff --git a/Reconstruction/tauRec/test/test_tau_standalone_multithread.sh b/Reconstruction/tauRec/test/test_tau_standalone_multithread.sh
new file mode 100755
index 0000000000000000000000000000000000000000..bdbdb141cffbd4eacac849d2cdf9f6e02396a5b9
--- /dev/null
+++ b/Reconstruction/tauRec/test/test_tau_standalone_multithread.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+#
+# art-description: standalone tau reconstruction ART on MC in multithread mode
+# art-type: grid
+# art-athena-mt: 8
+# art-include: master/Athena
+# art-output: *.root
+# art-output: *.log
+# art-output: *.ps
+# art-output: dcube
+# art-html: dcube
+
+NEVENTS=1000
+REF_DIR="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/tauRec/reference/standalone"
+
+# run the reconstruction
+athena.py --threads 4 --evtMax ${NEVENTS}  tauRec/tau_standalone_ESDtoAOD.py >> tau_standalone.log 2>&1
+echo "art-result: $? Reconstrution"
+
+# compare the AOD file
+art.py compare ref --entries ${NEVENTS} --mode semi-detailed --order-trees --diff-root AOD.pool.root ${REF_DIR}/AOD.pool.root >> AOD_diff_root.log 2>&1
+echo "art-result: $? diff-root"
+
+# run the physics validation
+Reco_tf.py --maxEvents ${NEVENTS} --validationFlags 'noExample,doTau' --inputAODFile AOD.pool.root  --outputNTUP_PHYSVALFile NTUP_PHYSVAL.root
+echo "art-result: $? PhysVal"
+
+# compare the histograms
+rootcomp.py NTUP_PHYSVAL.root ${REF_DIR}/NTUP_PHYSVAL.root >> rootcomp.log 2>&1
+echo "art-result: $? rootcomp"
+
+# run dcube
+INPUT_DIR="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/tauRec/input"
+$ATLAS_LOCAL_ROOT/dcube/current/DCubeClient/python/dcube.py \
+    --plot --output dcube \
+    --config ${INPUT_DIR}/config_mc.xml \
+    --reference ${REF_DIR}/NTUP_PHYSVAL.root \
+    NTUP_PHYSVAL.root
+echo "art-result: $? dcube"
diff --git a/Reconstruction/tauRec/test/test_tau_standalone.sh b/Reconstruction/tauRec/test/test_tau_standalone_serial.sh
similarity index 72%
rename from Reconstruction/tauRec/test/test_tau_standalone.sh
rename to Reconstruction/tauRec/test/test_tau_standalone_serial.sh
index 94247e5c67a7f74e3a2da9f83d6e1f1b8a8d05c8..1dbaf0c82c2f3259c4c97e2bffc9419360fd9711 100755
--- a/Reconstruction/tauRec/test/test_tau_standalone.sh
+++ b/Reconstruction/tauRec/test/test_tau_standalone_serial.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 #
-# art-description: ART for standalone tau reconstruction
+# art-description: standalone tau reconstruction on MC in serial mode
 # art-type: grid
 # art-include: master/Athena
 # art-output: *.root
@@ -13,15 +13,15 @@ NEVENTS=1000
 REF_DIR="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/tauRec/reference/standalone"
 
 # run the reconstruction
-athena.py --evtMax=${NEVENTS}  tauRec/tau_standalone_ESDtoAOD.py >> tau_standalone.log 2>&1
+athena.py --evtMax ${NEVENTS}  tauRec/tau_standalone_ESDtoAOD.py >> tau_standalone.log 2>&1
 echo "art-result: $? Reconstrution"
 
 # compare the AOD file
-art.py compare ref --entries ${NEVENTS} --mode=semi-detailed --order-trees --diff-root AOD.pool.root ${REF_DIR}/AOD.pool.root >> AOD_diff_root.log 2>&1
+art.py compare ref --entries ${NEVENTS} --mode semi-detailed --order-trees --diff-root AOD.pool.root ${REF_DIR}/AOD.pool.root >> AOD_diff_root.log 2>&1
 echo "art-result: $? diff-root"
 
 # run the physics validation
-Reco_tf.py --maxEvents=${NEVENTS} --validationFlags 'noExample,doTau' --inputAODFile=AOD.pool.root  --outputNTUP_PHYSVALFile=NTUP_PHYSVAL.root
+Reco_tf.py --maxEvents ${NEVENTS} --validationFlags 'noExample,doTau' --inputAODFile AOD.pool.root  --outputNTUP_PHYSVALFile NTUP_PHYSVAL.root
 echo "art-result: $? PhysVal"
 
 # compare the histograms
@@ -32,7 +32,7 @@ echo "art-result: $? rootcomp"
 INPUT_DIR="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/tauRec/input"
 $ATLAS_LOCAL_ROOT/dcube/current/DCubeClient/python/dcube.py \
     --plot --output dcube \
-    --config ${INPUT_DIR}/config.xml \
+    --config ${INPUT_DIR}/config_mc.xml \
     --reference ${REF_DIR}/NTUP_PHYSVAL.root \
     NTUP_PHYSVAL.root
 echo "art-result: $? dcube"
diff --git a/Reconstruction/tauRecTools/CMakeLists.txt b/Reconstruction/tauRecTools/CMakeLists.txt
index 0b6620ae5c293eaa1a59ade536ee2da1d2a7ea70..657c3091f773327a6ec13bfcac5c44149f7e047c 100644
--- a/Reconstruction/tauRecTools/CMakeLists.txt
+++ b/Reconstruction/tauRecTools/CMakeLists.txt
@@ -6,73 +6,6 @@
 # Declare the package name:
 atlas_subdir( tauRecTools )
 
-# Declare the package's dependencies:
-if( XAOD_STANDALONE OR XAOD_ANALYSIS )
-   set( extra_deps )
-   if( XAOD_ANALYSIS )
-      set( extra_deps GaudiKernel )
-   endif()
-   atlas_depends_on_subdirs(
-      PUBLIC
-      Control/AthLinks
-      Control/AthToolSupport/AsgDataHandles
-      Control/AthToolSupport/AsgTools
-      Control/CxxUtils
-      Event/xAOD/xAODCaloEvent
-      Event/xAOD/xAODEventInfo
-      Event/xAOD/xAODPFlow
-      Event/xAOD/xAODTau
-      Event/xAOD/xAODEgamma
-      Event/xAOD/xAODTracking
-      Event/xAOD/xAODParticleEvent
-      Reconstruction/MVAUtils
-      PRIVATE
-      Event/FourMomUtils
-      Event/xAOD/xAODJet
-      Tools/PathResolver
-      PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools
-      ${extra_deps} )
-else()
-   atlas_depends_on_subdirs(
-      PUBLIC
-      Calorimeter/CaloUtils
-      Control/AthLinks
-      Control/AthToolSupport/AsgDataHandles
-      Control/AthToolSupport/AsgTools
-      Control/CxxUtils
-      Event/xAOD/xAODCaloEvent
-      Event/xAOD/xAODEventInfo
-      Event/xAOD/xAODPFlow
-      Event/xAOD/xAODTau
-      Event/xAOD/xAODEgamma
-      Event/xAOD/xAODTracking
-      Event/xAOD/xAODParticleEvent
-      Reconstruction/Particle
-      Reconstruction/MVAUtils
-      PRIVATE
-      Calorimeter/CaloInterface
-      Control/AthContainers
-      Event/FourMomUtils
-      Event/NavFourMom
-      Event/xAOD/xAODJet
-      GaudiKernel
-      InnerDetector/InDetRecTools/InDetRecToolInterfaces
-      InnerDetector/InDetRecTools/InDetTrackSelectionTool
-      InnerDetector/InDetConditions/BeamSpotConditionsData
-      Reconstruction/Jet/JetEDM
-      Reconstruction/RecoTools/ITrackToVertex
-      Reconstruction/RecoTools/RecoToolInterfaces
-      Tools/PathResolver
-      PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools
-      Tracking/TrkEvent/TrkLinks
-      Tracking/TrkEvent/TrkParametersIdentificationHelpers
-      Tracking/TrkEvent/TrkTrackSummary
-      Tracking/TrkEvent/VxVertex
-      Tracking/TrkTools/TrkToolInterfaces
-      Tracking/TrkVertexFitter/TrkVertexFitterInterfaces
-      Tracking/TrkVertexFitter/TrkVertexFitters)
-endif()
-
 # External dependencies:
 find_package( Boost )
 find_package( ROOT COMPONENTS Core Tree Hist RIO )
@@ -95,7 +28,6 @@ atlas_add_root_dictionary( tauRecToolsLib tauRecToolsLibCintDict
   tauRecTools/TauJetBDTEvaluator.h
   tauRecTools/TauJetRNNEvaluator.h
   tauRecTools/TauIDVarCalculator.h
-  tauRecTools/TauEleOLRDecorator.h
   Root/LinkDef.h
   EXTERNAL_PACKAGES ROOT
   )
@@ -112,7 +44,7 @@ if( XAOD_STANDALONE OR XAOD_ANALYSIS )
       AthLinks AsgTools CxxUtils xAODCaloEvent xAODEventInfo xAODPFlow xAODEgamma xAODTau
       xAODTracking xAODParticleEvent AsgDataHandlesLib
       PRIVATE_LINK_LIBRARIES ${FASTJETCONTRIB_LIBRARIES} ${LWTNN_LIBRARIES} FourMomUtils xAODJet
-      PathResolver MVAUtils ElectronPhotonSelectorToolsLib )
+      PathResolver MVAUtils )
 else()
    atlas_add_library( tauRecToolsLib
       tauRecTools/*.h Root/*.cxx tauRecTools/lwtnn/*.h Root/lwtnn/*.cxx  ${tauRecToolsLibCintDict}
@@ -134,7 +66,7 @@ if( NOT XAOD_STANDALONE )
          INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${LWTNN_INCLUDE_DIRS}
          LINK_LIBRARIES ${ROOT_LIBRARIES} ${Boost_LIBRARIES} ${LWTNN_LIBRARIES} xAODTau
          xAODTracking xAODEgamma AthContainers FourMomUtils xAODCaloEvent xAODJet 
-         xAODPFlow xAODParticleEvent MVAUtils ElectronPhotonSelectorToolsLib GaudiKernel tauRecToolsLib )
+         xAODPFlow xAODParticleEvent MVAUtils ElectronPhotonSelectorToolsLib BeamSpotConditionsData GaudiKernel tauRecToolsLib )
    else()
       atlas_add_component( tauRecTools
          src/*.h src/*.cxx src/components/*.cxx
@@ -145,12 +77,8 @@ if( NOT XAOD_STANDALONE )
          InDetRecToolInterfaces JetEDM Particle ITrackToVertex
          RecoToolInterfaces TrkLinks TrkParametersIdentificationHelpers
          TrkTrackSummary VxVertex TrkToolInterfaces TrkVertexFitterInterfaces
-         TrkVertexFittersLib InDetTrackSelectionToolLib
+         TrkVertexFittersLib InDetTrackSelectionToolLib BeamSpotConditionsData
          tauRecToolsLib )
    endif()
 endif()
 
-# Install files from the package:
-atlas_install_runtime( share/*.xml )
-atlas_install_runtime( share/*.root )
-atlas_install_data( share/* )
diff --git a/Reconstruction/tauRecTools/Root/LinkDef.h b/Reconstruction/tauRecTools/Root/LinkDef.h
index f5a919a42f3923dada64bc7e879d0e9131594e8f..26af63aa53b821cbe81e453cb765ed7dddf6c2aa 100644
--- a/Reconstruction/tauRecTools/Root/LinkDef.h
+++ b/Reconstruction/tauRecTools/Root/LinkDef.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "tauRecTools/TauCalibrateLC.h"
@@ -15,7 +15,6 @@
 #include "tauRecTools/TauWPDecorator.h"
 #include "tauRecTools/TauJetBDTEvaluator.h"
 #include "tauRecTools/TauIDVarCalculator.h"
-#include "tauRecTools/TauEleOLRDecorator.h"
 #include "tauRecTools/TauJetRNNEvaluator.h"
 
 #ifdef __CINT__
@@ -25,10 +24,6 @@
 #pragma link off all functions;
 #pragma link C++ nestedclass;
 
-#endif
-
-#ifdef __CINT__
-
 #pragma link C++ class TauCalibrateLC+;
 #pragma link C++ class TauCommonCalcVars+;
 #pragma link C++ class TauSubstructureVariables+;
@@ -44,7 +39,6 @@
 #pragma link C++ class TauWPDecorator+;
 #pragma link C++ class TauJetBDTEvaluator+;
 #pragma link C++ class TauIDVarCalculator+;
-#pragma link C++ class TauEleOLRDecorator+;
 #pragma link C++ class TauJetRNNEvaluator+;
 
 #endif
diff --git a/Reconstruction/tauRecTools/Root/TauEleOLRDecorator.cxx b/Reconstruction/tauRecTools/Root/TauEleOLRDecorator.cxx
index c3f01225741f45880bc9a585ca98f3a47ee91ad2..028b99cd08634f595941ff19778ff76c9a7fafeb 100644
--- a/Reconstruction/tauRecTools/Root/TauEleOLRDecorator.cxx
+++ b/Reconstruction/tauRecTools/Root/TauEleOLRDecorator.cxx
@@ -2,6 +2,8 @@
   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
+#ifndef XAOD_STANDALONE 
+
 /**
  * Tau Electron Overlap Removal Decorator Tool
  *
@@ -109,3 +111,5 @@ float TauEleOLRDecorator::getCutVal(float fEta, float fPt) const
   int iBin= m_hCutValues->FindBin(fPt, std::abs(fEta));
   return m_hCutValues->GetBinContent(iBin);
 }
+
+#endif
diff --git a/Reconstruction/tauRecTools/Root/TauPi0ClusterScaler.cxx b/Reconstruction/tauRecTools/src/TauPi0ClusterScaler.cxx
similarity index 99%
rename from Reconstruction/tauRecTools/Root/TauPi0ClusterScaler.cxx
rename to Reconstruction/tauRecTools/src/TauPi0ClusterScaler.cxx
index 5568f08bc3044916c947eaee70915bbdca98ccf5..2d9a903a0ac915b636c5e7670e2adef5442da919 100644
--- a/Reconstruction/tauRecTools/Root/TauPi0ClusterScaler.cxx
+++ b/Reconstruction/tauRecTools/src/TauPi0ClusterScaler.cxx
@@ -12,7 +12,7 @@
 
 #include <vector>
 
-#include "tauRecTools/TauPi0ClusterScaler.h"
+#include "TauPi0ClusterScaler.h"
 #include "xAODTau/TauJet.h"
 #include "xAODPFlow/PFO.h"
 #include "tauRecTools/ITauToolBase.h"
diff --git a/Reconstruction/tauRecTools/tauRecTools/TauPi0ClusterScaler.h b/Reconstruction/tauRecTools/src/TauPi0ClusterScaler.h
similarity index 100%
rename from Reconstruction/tauRecTools/tauRecTools/TauPi0ClusterScaler.h
rename to Reconstruction/tauRecTools/src/TauPi0ClusterScaler.h
diff --git a/Reconstruction/tauRecTools/src/components/tauRecTools_entries.cxx b/Reconstruction/tauRecTools/src/components/tauRecTools_entries.cxx
index 83a774a34059c5934f683f8fd5bf67779243cb2d..881c83e2414222a669f3cd842d68ebfd0a85ab68 100644
--- a/Reconstruction/tauRecTools/src/components/tauRecTools_entries.cxx
+++ b/Reconstruction/tauRecTools/src/components/tauRecTools_entries.cxx
@@ -8,8 +8,10 @@
 #include "../TauShotFinder.h"
 #include "../TauPi0ClusterCreator.h"
 #include "../TauPi0CreateROI.h"
+#include "../TauPi0ClusterScaler.h"
 #include "../TauVertexVariables.h"
 #endif
+
 #include "tauRecTools/TauCalibrateLC.h"
 #include "tauRecTools/TauCommonCalcVars.h"
 #include "tauRecTools/TauSubstructureVariables.h"
@@ -18,7 +20,6 @@
 #include "tauRecTools/TauTrackClassifier.h"
 #include "tauRecTools/TauTrackRNNClassifier.h"
 #include "tauRecTools/CombinedP4FromRecoTaus.h"
-#include "tauRecTools/TauPi0ClusterScaler.h"
 #include "tauRecTools/TauPi0ScoreCalculator.h"
 #include "tauRecTools/TauPi0Selector.h"
 #include "tauRecTools/TauWPDecorator.h"
@@ -37,6 +38,7 @@ DECLARE_COMPONENT( TauElectronVetoVariables )
 DECLARE_COMPONENT( TauShotFinder )
 DECLARE_COMPONENT( TauPi0ClusterCreator )
 DECLARE_COMPONENT( TauPi0CreateROI )
+DECLARE_COMPONENT( TauPi0ClusterScaler )
 DECLARE_COMPONENT( TauVertexVariables )
 #endif
 
@@ -50,7 +52,6 @@ DECLARE_COMPONENT( tauRecTools::TrackRNN )
 DECLARE_COMPONENT( CombinedP4FromRecoTaus )
 DECLARE_COMPONENT( TauSubstructureVariables )
 DECLARE_COMPONENT( TauCommonCalcVars )
-DECLARE_COMPONENT( TauPi0ClusterScaler )
 DECLARE_COMPONENT( TauPi0ScoreCalculator )
 DECLARE_COMPONENT( TauPi0Selector )
 DECLARE_COMPONENT( TauWPDecorator )
diff --git a/Reconstruction/tauRecTools/tauRecTools/ToolsDef.h b/Reconstruction/tauRecTools/tauRecTools/ToolsDef.h
deleted file mode 100644
index 03bd606eb5faa409accffabe674b7e360fd3d086..0000000000000000000000000000000000000000
--- a/Reconstruction/tauRecTools/tauRecTools/ToolsDef.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-*/
-
-
-#include "tauRecTools/TauCalibrateLC.h"
-#include "tauRecTools/TauSubstructureVariables.h"
-#include "tauRecTools/TauCommonCalcVars.h"
-#include "tauRecTools/MvaTESVariableDecorator.h"
-#include "tauRecTools/MvaTESEvaluator.h"
-#include "tauRecTools/CombinedP4FromRecoTaus.h"
-#include "tauRecTools/TauTrackClassifier.h"
-#include "tauRecTools/TauTrackRNNClassifier.h"
-#include "tauRecTools/TauWPDecorator.h"
-#include "tauRecTools/TauJetBDTEvaluator.h"
-#include "tauRecTools/TauIDVarCalculator.h"
-#include "tauRecTools/TauEleOLRDecorator.h"
-#include "tauRecTools/TauJetRNNEvaluator.h"
-
-REGISTER_TOOL(TauCalibrateLC)
-REGISTER_TOOL(TauCommonCalcVars)
-REGISTER_TOOL(TauSubstructureVariables)
-REGISTER_TOOL(MvaTESVariableDecorator)
-REGISTER_TOOL(MvaTESEvaluator)
-REGISTER_TOOL(CombinedP4FromRecoTaus)
-REGISTER_TOOL(tauRecTools::TauTrackClassifier)
-REGISTER_TOOL(tauRecTools::TauTrackRNNClassifier)
-REGISTER_TOOL(tauRecTools::TrackMVABDT)
-REGISTER_TOOL(tauRecTools::TrackRNN)
-REGISTER_TOOL(TauWPDecorator)
-REGISTER_TOOL(TauJetBDTEvaluator)
-REGISTER_TOOL(TauEleOLRDecorator)
-REGISTER_TOOL(TauIDVarCalculator)
-REGISTER_TOOL(TauJetRNNEvaluator)
diff --git a/Simulation/FastSimulation/FastChainPileup/test/test_g4ms_validation.sh b/Simulation/FastSimulation/FastChainPileup/test/test_g4ms_validation.sh
index b0daa560e85fe5302956b801d0e6cf4d0fe84de2..4c1f8434b5f21f6446640f1c5c16f3f69d9f2071 100755
--- a/Simulation/FastSimulation/FastChainPileup/test/test_g4ms_validation.sh
+++ b/Simulation/FastSimulation/FastChainPileup/test/test_g4ms_validation.sh
@@ -3,8 +3,10 @@
 # art-description: test
 #
 # art-type: grid
-# art-include: master/Athena
+# art-input: mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.merge.EVNT.e6337_e5984
+# art-input-nfiles: 1
 # art-cores: 10
+# art-include: master/Athena
 # art-output: *.root
 # art-output: art_core*
 # art-output: dcube-*
@@ -34,27 +36,32 @@ case $ArtProcess in
 
         dcubeXmlNTUP="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/FastChainPileup/DCube-configs/${AtlasBuildBranch}/physval-validation.xml"
         dcubeRefNTUP="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/FastChainPileup/DCube-refs/${AtlasBuildBranch}/test_g4ms_validation/${merge_ntup_file}"
-        dcubeRefAF2NTUP="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/FastChainPileup/DCube-refs/${AtlasBuildBranch}/test_af2_validation/physval_af2_validation_all.root"
+        dcubeRefAF2NTUP="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/FastChainPileup/DCube-refs/${AtlasBuildBranch}/test_af2_validation/physval_af2_validation_merge.root"
 
         # Histogram comparison of G4MS with AF2 DCube
-        $ATLAS_LOCAL_ROOT/dcube/current/DCubeClient/python/dcube.py \
-        -p -x dcube-physval \
-        -c ${dcubeXmlNTUP} -r ${dcubeRefNTUP} ./${merge_ntup_file}
-        echo  "art-result: $? dcube-physval"
+         $ATLAS_LOCAL_ROOT/dcube/current/DCubeClient/python/dcube.py \
+         -p -x dcube-physval \
+         -c ${dcubeXmlNTUP} -r ${dcubeRefNTUP} ./${merge_ntup_file}
+         echo  "art-result: $? dcube-physval"
 
-        # Histogram comparison of G4MS with AF2 DCube
-        $ATLAS_LOCAL_ROOT/dcube/current/DCubeClient/python/dcube.py \
-        -p -x dcube-g4msVsaf2 \
-        -c ${dcubeXmlNTUP} -r ${dcubeRefAF2NTUP} ./${merge_ntup_file}
-        echo  "art-result: $? dcube-g4msVsaf2"
+         # Histogram comparison of G4MS with AF2 DCube
+         $ATLAS_LOCAL_ROOT/dcube/current/DCubeClient/python/dcube.py \
+         -p -x dcube-g4msVsaf2 \
+         -c ${dcubeXmlNTUP} -r ${dcubeRefAF2NTUP} ./${merge_ntup_file}
+         echo  "art-result: $? dcube-g4msVsaf2"
 
 	;;
 
     *)
 	echo "Test $ArtProcess"
-	
+
 	mkdir "art_core_${ArtProcess}"
 	cd "art_core_${ArtProcess}"
+
+        IFS=',' read -r -a file <<< "${ArtInFile}"
+        file=${file[0]}
+        x="../$file"
+
         
         max_events=1000
         skip_events=$((${max_events}*${ArtProcess}))
@@ -64,7 +71,7 @@ case $ArtProcess in
 	unset  ATHENA_NUM_PROC
 	
         # Output files to be saved
-        hist_file=HITS_${ArtProcess}.pool.root
+        hits_file=HITS_${ArtProcess}.pool.root
         aod_file=AOD_${ArtProcess}.pool.root
         ntup_file=physval_g4ms_${ArtProcess}.root
 
@@ -76,8 +83,8 @@ case $ArtProcess in
                   --preInclude 'EVNTtoHITS:SimulationJobOptions/preInclude.BeamPipeKill.py' \
                   --preExec 'EVNTtoHITS:simFlags.TightMuonStepping=True' \
                   --DataRunNumber '284500' --geometryVersion 'default:ATLAS-R2-2016-01-00-01' \
-                  --inputEVNTFile='/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/FastChainPileup/mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.merge.EVNT.e6337_e5984_tid12860049_00/EVNT.12860049._002516.pool.root.1' \
-                  --outputHITSFile=${hist_file} \
+                  --inputEVNTFile=${x} \
+                  --outputHITSFile=${hits_file} \
                   --maxEvents ${max_events} --skipEvents ${skip_events} \
                   --randomSeed=1234 --imf False
         rc=$?
@@ -85,7 +92,7 @@ case $ArtProcess in
         if [ $rc -eq 0 ]
         then
             Reco_tf.py --autoConfiguration 'everything' \
-                  --inputHITSFile=${hist_file} --conditionsTag 'default:OFLCOND-MC16-SDR-25' \
+                  --inputHITSFile=${hits_file} --conditionsTag 'default:OFLCOND-MC16-SDR-25' \
                   --geometryVersion 'default:ATLAS-R2-2016-01-00-01' \
                   --postExec "all:CfgMgr.MessageSvc().setError+=['HepMcParticleLink']" \
                   --postInclude "default:PyJobTransforms/UseFrontier.py" \
@@ -98,7 +105,7 @@ case $ArtProcess in
 	    echo  "art-result: $rc2 Reco_${ArtProcess}"
             # if no problem, remove all files except the output files
 	fi
-        # for i in `ls | grep -v "${aod_file}\|${hist_file}\|${ntup_file}"` ; do rm -vrf $i; done
+        # for i in `ls | grep -v "${aod_file}\|${hits_file}\|${ntup_file}"` ; do rm -vrf $i; done
         for i in `ls | grep -v "${aod_file}\|${ntup_file}"` ; do rm -vrf $i; done
         
 
diff --git a/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/ISF_FatrasDetDescrTools/LayerMaterialProvider.h b/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/ISF_FatrasDetDescrTools/LayerMaterialProvider.h
index e02deeea8422a4cf646fa30baa6d36e1b4c3b934..d85ca20ef799c18cd7a356f908ce79972166bee3 100644
--- a/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/ISF_FatrasDetDescrTools/LayerMaterialProvider.h
+++ b/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/ISF_FatrasDetDescrTools/LayerMaterialProvider.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -46,20 +46,20 @@ namespace iFatras {
     virtual ~LayerMaterialProvider();
 
     /** Processor Action to work on TrackingGeometry& tgeo */
-    virtual StatusCode process(const Trk::TrackingGeometry& tgeo);
+    virtual StatusCode process(const Trk::TrackingGeometry& tgeo) const;
        
     /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-    virtual StatusCode process(const Trk::TrackingVolume& tvol, size_t level = 0);   
+    virtual StatusCode process(const Trk::TrackingVolume& tvol, size_t level = 0) const;
        
     /** Processor Action to work on Layers */
-    virtual StatusCode process(const Trk::Layer& lay, size_t level = 0);
+    virtual StatusCode process(const Trk::Layer& lay, size_t level = 0) const;
        
     /** Processor Action to work on Surfaces */
-    virtual StatusCode process(const Trk::Surface& surf, size_t level = 0);
+    virtual StatusCode process(const Trk::Surface& surf, size_t level = 0) const;
 
   private:
           
-    StatusCode loadMaterialMap();               //!< reatrieve the Material map from the detector store
+    StatusCode loadMaterialMap() const; //!< retrieve the Material map from the detector store
 
     //!< boolean switch for assignLayerMaterial
     mutable const Trk::LayerMaterialMap*         m_layerMaterialMap;
diff --git a/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/src/LayerMaterialProvider.cxx b/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/src/LayerMaterialProvider.cxx
index 6ba568e5eaf3ee21fa395d106af2d0ea5029ba20..1c4d75f1a78ed84341f4f4367b73810b49fbcb88 100644
--- a/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/src/LayerMaterialProvider.cxx
+++ b/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/src/LayerMaterialProvider.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -34,7 +34,7 @@ iFatras::LayerMaterialProvider::~LayerMaterialProvider()
 
 
 // Processor Action to work on TrackingGeometry 
-StatusCode iFatras::LayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo) {
+StatusCode iFatras::LayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo) const{
   
   ATH_MSG_VERBOSE("Start processing the TrackingGeometry recursively");
   // retrieve the highest tracking volume
@@ -79,7 +79,7 @@ StatusCode iFatras::LayerMaterialProvider::process(const Trk::TrackingGeometry&
 }
 
 // Processor Action to work on TrackingVolumes
-StatusCode iFatras::LayerMaterialProvider::process(const Trk::TrackingVolume& tvol, size_t level) {
+StatusCode iFatras::LayerMaterialProvider::process(const Trk::TrackingVolume& tvol, size_t level) const{
   
   // load the material map if not done yet
   if (!m_layerMaterialMap){ 
@@ -149,7 +149,7 @@ StatusCode iFatras::LayerMaterialProvider::process(const Trk::TrackingVolume& tv
 }
 
 // Processor Action to work on Layers 
-StatusCode iFatras::LayerMaterialProvider::process(const Trk::Layer& lay, size_t level) {
+StatusCode iFatras::LayerMaterialProvider::process(const Trk::Layer& lay, size_t level) const {
 
     // load the material map if not done yet
     if (!m_layerMaterialMap){ 
@@ -187,12 +187,12 @@ StatusCode iFatras::LayerMaterialProvider::process(const Trk::Layer& lay, size_t
 }
 
 // Processor Action to work on Surfaces 
-StatusCode iFatras::LayerMaterialProvider::process(const Trk::Surface&, size_t) {
+StatusCode iFatras::LayerMaterialProvider::process(const Trk::Surface&, size_t) const {
     return StatusCode::SUCCESS;
 }
 
 // load the material map from StoreGate
-StatusCode iFatras::LayerMaterialProvider::loadMaterialMap() {
+StatusCode iFatras::LayerMaterialProvider::loadMaterialMap() const {
     
     // -------------------------------------------------------------------------------
     if (detStore()->retrieve(m_layerMaterialMap, m_layerMaterialMapName).isFailure()){
diff --git a/TileCalorimeter/TileMonitoring/src/TileRawChannelNoiseMonTool.cxx b/TileCalorimeter/TileMonitoring/src/TileRawChannelNoiseMonTool.cxx
index 9b38986f2b90650bf467e79edd39a422baea3166..dc4c8739428e38ddc4ea25d9f7e3faa2650a199d 100644
--- a/TileCalorimeter/TileMonitoring/src/TileRawChannelNoiseMonTool.cxx
+++ b/TileCalorimeter/TileMonitoring/src/TileRawChannelNoiseMonTool.cxx
@@ -525,7 +525,7 @@ StatusCode TileRawChannelNoiseMonTool::fillHistoPerRawChannel() {
 
     int fragId = rawChannelCollection->identify();
     IdentifierHash fragHash = (rawChannelContainerDSP->hashFunc())(fragId);
-    const TileRawChannelCollection* rawChannelCollectionDSP = *(rawChannelContainerDSP->indexFind(fragHash));
+    const TileRawChannelCollection* rawChannelCollectionDSP = rawChannelContainerDSP->indexFindPtr(fragHash);
 
     if (rawChannelCollectionDSP->getLvl1Type() != getL1info()) continue;
 
diff --git a/Tools/PyUtils/python/FilePeekerTool.py b/Tools/PyUtils/python/FilePeekerTool.py
index 18b82f54c7e795f7b6a169f9236e1c675f66945c..da93fbdde436f6709113510918446e905cc5e1fb 100644
--- a/Tools/PyUtils/python/FilePeekerTool.py
+++ b/Tools/PyUtils/python/FilePeekerTool.py
@@ -265,7 +265,7 @@ class FilePeekerTool():
                         spec   = a.specification()
                         a_type = spec.typeName()
                         if a_type.find('string') >= 0:
-                            a_data = a.data('string')()
+                            a_data = a.data['string']()
 #                           a_data = getattr(a, 'data<std::basic_string<char> >') ()
                             try:
                                 a_data = eval(a_data,{},{})
@@ -274,7 +274,7 @@ class FilePeekerTool():
                                 pass
 #                           print (spec.name(),a_data, file=stdout)
                         else:
-                            a_data = a.data(a_type)()
+                            a_data = a.data[a_type]()
                         #print ("%s: %s  %s" (spec.name(), a_data, type(a_data) ), file=stdout)
                         attr_data.append( (spec.name(), a_data) )
                     attrs.append(dict(attr_data))
diff --git a/Tools/PyUtils/python/RootUtils.py b/Tools/PyUtils/python/RootUtils.py
index 8721cb3042a31a21798f8586d852598cf8f0f9a6..b921060778c5ec902571b6e6f095333e25c79f77 100644
--- a/Tools/PyUtils/python/RootUtils.py
+++ b/Tools/PyUtils/python/RootUtils.py
@@ -19,18 +19,10 @@ __all__ = [
 import os
 import re
 import six
-from array import array
 
 from .Decorators import memoize
 
 ### functions -----------------------------------------------------------------
-# Set buffer size, in bytes.
-# The argument to reshape is in elements, not bytes.
-def _set_byte_size (buf, sz):
-    eltsz = array(buf.typecode).itemsize
-    buf.reshape ((sz // eltsz,))
-    return
-
 def import_root(batch=True):
     """a helper method to wrap the 'import ROOT' statement to prevent ROOT
     from screwing up the display or loading graphics libraries when in batch
@@ -158,19 +150,17 @@ def _pythonize_tfile():
         """
         SZ = 4096
 
+        # FIXME: Once we drop py2, we can simplify this by using a bytes
+        # object directly instead of PyBytes.
         if size>=0:
             #size = _adjust_sz(size)
             #print ("-->0",self.tell(),size)
             c_buf = read_root_file(self, size)
             if c_buf and c_buf.sz:
-                #print ("-->1",self.tell(),c_buf.sz)
-                #self.seek(c_buf.sz+self.tell())
-                #print ("-->2",self.tell())
-                buf = c_buf.buffer()
-                _set_byte_size (buf, c_buf.sz)
+                v = c_buf.buf
                 if six.PY3:
-                    return buf.tobytes()
-                return str(buf[:])
+                    return bytes([ord(v[i]) for i in range(v.size())])
+                return ''.join([v[i] for i in range(v.size())])
             return ''
         else:
             size = SZ
@@ -179,12 +169,18 @@ def _pythonize_tfile():
                 #size = _adjust_sz(size)
                 c_buf = read_root_file(self, size)
                 if c_buf and c_buf.sz:
-                    buf = c_buf.buffer()
-                    _set_byte_size (buf, c_buf.sz)
-                    out.append(str(buf[:]))
+                    v = c_buf.buf
+                    if six.PY3:
+                        chunk = bytes([ord(v[i]) for i in range(v.size())])
+                    else:
+                        chunk = ''.join([v[i] for i in range(v.size())])
+                    out.append(chunk)
                 else:
                     break
+            if six.PY3:
+                return b''.join(out)
             return ''.join(out)
+            
     root.TFile.read = read
     del read
     
diff --git a/Tools/PyUtils/python/scripts/cmake_depends.py b/Tools/PyUtils/python/scripts/cmake_depends.py
index d598e41b096673e750b9273d4b22bfc09d70b2b6..30b92b9a377a81380a4184a4e150885c4a89b017 100644
--- a/Tools/PyUtils/python/scripts/cmake_depends.py
+++ b/Tools/PyUtils/python/scripts/cmake_depends.py
@@ -16,19 +16,22 @@ from collections import deque
 import PyUtils.acmdlib as acmdlib
 import argparse
 
-# Hack until we have pygraphviz in LCG (SPI-1633):
+# Hack until we switched to LCG>=97a:
 try:
    import pygraphviz
 except ImportError:
    if sys.version_info[0]==2:
-      sys.path.append('/cvmfs/sft.cern.ch/lcg/nightlies/dev4/Tue/pygraphviz/1.5/x86_64-centos7-gcc8-opt/lib/python2.7/site-packages/')
+      sys.path.append('/cvmfs/sft.cern.ch/lcg/releases/LCG_97a/pygraphviz/1.5/'+os.getenv('BINARY_TAG')+'/lib/python2.7/site-packages/')
    else:
-      sys.path.append('/cvmfs/sft.cern.ch/lcg/nightlies/dev3python3/Tue/pygraphviz/1.5/x86_64-centos7-gcc8-opt/lib/python3.7/site-packages')
+      sys.path.append('/cvmfs/sft.cern.ch/lcg/releases/LCG_97apython3/pygraphviz/1.5/'+os.getenv('BINARY_TAG')+'/lib/python3.7/site-packages')
    import pygraphviz
 
-#
-# Some helper functions
-#
+
+# Targets ending in those strings are ignored:
+custom_targets = ['Pkg', 'PkgPrivate', 'ClidGen', 'ComponentsList', 'Configurables',
+                  'JobOptInstall', 'PythonBytecodeInstall', 'PythonInstall']
+
+
 def read_package_list(package_file):
    """Read packages.txt as a source for the full package path"""
 
@@ -52,9 +55,13 @@ def externals_name(lib):
 
 def ignore_target(t):
    """Check if target should be ignored"""
-   if t.startswith('__MUST_NOT_LINK_AGAINST') or t.startswith('-') or \
-      t.endswith('Pkg') or t.endswith('PkgPrivate'): return True
-   else: return False
+   if t.startswith('__MUST_NOT_LINK_AGAINST') or t.startswith('-'):
+      return True
+
+   for s in custom_targets:
+      if t.endswith(s): return True
+
+   return False
 
 
 def lrstrip(s, prefix, postfix):
@@ -85,6 +92,9 @@ def traverse(graph, root, reverse=False, maxdepth=None, nodegetter=lambda n:n):
 
       if node not in visited_nodes:
          visited_nodes.add(node)
+         if ignore_target(node.attr['label']):
+            continue
+
          # Add edges to neighbors into queue:
          if maxdepth is None or level < maxdepth:
             queue.extend((node,n,level+1) for n in neighbors(node))
@@ -104,7 +114,7 @@ def subgraph(graph, sources, reverse=False, maxdepth=None, nodegetter=lambda n :
    g = pygraphviz.AGraph(directed=True)
    for root in sources:
       for a,b in traverse(graph, root, reverse=reverse, maxdepth=maxdepth, nodegetter=nodegetter):
-         if a and b and a!=b and not ignore_target(a) and not ignore_target(b):
+         if a and b and a!=b:
             if reverse: g.add_edge(b,a)
             else: g.add_edge(a,b)
 
@@ -230,7 +240,6 @@ def main(args):
          # within that package. First find all targets within the package:
          if args.clients and not args.target:
             sources.extend([b for a,b in traverse(d.graph, d.get_node(l), maxdepth=1)])
-            l
          else:
             sources.extend([d.get_node(l)])
 
diff --git a/Tracking/Acts/ActsGeometry/ActsGeometry/ActsExtrapolationAlg.h b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsExtrapolationAlg.h
index f7992802058a560e141ad9cc22f194c5cc17f3fd..9c6aa5d3058a8296f7eee7da2395dd427322651d 100755
--- a/Tracking/Acts/ActsGeometry/ActsGeometry/ActsExtrapolationAlg.h
+++ b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsExtrapolationAlg.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef ACTSGEOMETRY_ACTSEXTRAPOLATIONALG_H
@@ -14,9 +14,6 @@
 // ACTS
 #include "Acts/EventData/TrackParameters.hpp"
 #include "Acts/Geometry/GeometryID.hpp"
-#include "Acts/Utilities/Helpers.hpp"
-
-// PACKAGE
 
 // STL
 #include <memory>
@@ -27,12 +24,14 @@
 
 namespace Acts {
   class TrackingGeometry;
-
   namespace detail {
     class Step;
   }
 }
 
+
+class IActsMaterialTrackWriterSvc;
+
 class EventContext;
 class IAthRNGSvc;
 class IActsExtrapolationTool;
@@ -51,16 +50,15 @@ private:
 
   ToolHandle<IActsExtrapolationTool> m_extrapolationTool{this, "ExtrapolationTool", "ActsExtrapolationTool"};
 
-  // std::shared_ptr<RootExCellWriter<Acts::TrackParameters>> m_rootEccWriter;
 
   // poor-mans Particle Gun is included here right now
   Gaudi::Property<std::vector<double>> m_etaRange{this, "EtaRange", {-3, 3}, "The eta range for particles"};
   Gaudi::Property<std::vector<double>> m_ptRange{this, "PtRange", {0.1, 1000}, "The pt range for particles"};
   Gaudi::Property<size_t> m_nParticlePerEvent{this, "NParticlesPerEvent", 1, "The number of particles per event"};
 
-  // this does not work right now
-  //Gaudi::Property<bool> m_writeMaterialTracks{this, "WriteMaterialTracks", false, ""};
-  //ServiceHandle<IActsMaterialTrackWriterSvc> m_materialTrackWriterSvc;
+  // material track writer for the material map validation
+  Gaudi::Property<bool> m_writeMaterialTracks{this, "WriteMaterialTracks", false, "Write material track"};
+  ServiceHandle<IActsMaterialTrackWriterSvc> m_materialTrackWriterSvc;
 
   mutable std::mutex m_writeMutex{};
   mutable std::unique_ptr<std::ofstream> m_objOut;
diff --git a/Tracking/Acts/ActsGeometry/ActsGeometry/ActsExtrapolationTool.h b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsExtrapolationTool.h
index 1b1b5e3a82b276b96bb451b7458bf3372cb8489a..ddd2a3ca6fc28aa3f60dd6a259cd11fe77654e2a 100644
--- a/Tracking/Acts/ActsGeometry/ActsGeometry/ActsExtrapolationTool.h
+++ b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsExtrapolationTool.h
@@ -15,16 +15,14 @@
 // PACKAGE
 #include "ActsGeometryInterfaces/IActsExtrapolationTool.h"
 #include "ActsGeometryInterfaces/IActsTrackingGeometryTool.h"
-#include "ActsGeometry/ActsGeometryContext.h"
 #include "ActsGeometry/ATLASMagneticFieldWrapper.h"
 
 // ACTS
+#include "Acts/MagneticField/ConstantBField.hpp"
+#include "Acts/MagneticField/MagneticFieldContext.hpp"
 #include "Acts/Propagator/detail/SteppingLogger.hpp"
 #include "Acts/Propagator/DebugOutputActor.hpp"
 #include "Acts/Propagator/StandardAborters.hpp"
-#include "ActsGeometry/ATLASMagneticFieldWrapper.h"
-#include "Acts/MagneticField/ConstantBField.hpp"
-#include "Acts/MagneticField/MagneticFieldContext.hpp"
 #include "Acts/Utilities/Result.hpp"
 #include "Acts/Utilities/Units.hpp"
 #include "Acts/Utilities/Helpers.hpp"
@@ -48,7 +46,6 @@ namespace ActsExtrapolationDetail {
 
 class ActsExtrapolationTool : public extends<AthAlgTool, IActsExtrapolationTool>
 {
-
 public:
   virtual StatusCode initialize() override;
 
@@ -62,32 +59,33 @@ private:
   using SteppingLogger = Acts::detail::SteppingLogger;
   using DebugOutput = Acts::DebugOutputActor;
   using EndOfWorld = Acts::EndOfWorldReached;
-  using ResultType = Acts::Result<std::pair<std::vector<Acts::detail::Step>,
+  using ResultType = Acts::Result<std::pair<ActsPropagationOutput,
                                             DebugOutput::result_type>>;
 
+
 public:
   virtual
-  std::vector<Acts::detail::Step>
+  ActsPropagationOutput
   propagationSteps(const EventContext& ctx,
                    const Acts::BoundParameters& startParameters,
                    Acts::NavigationDirection navDir = Acts::forward,
                    double pathLimit = std::numeric_limits<double>::max()) const override;
-                   
+
   virtual
   std::unique_ptr<const Acts::CurvilinearParameters>
   propagate(const EventContext& ctx,
             const Acts::BoundParameters& startParameters,
             Acts::NavigationDirection navDir = Acts::forward,
             double pathLimit = std::numeric_limits<double>::max()) const override;
-            
+
   virtual
-  std::vector<Acts::detail::Step>
+  ActsPropagationOutput
   propagationSteps(const EventContext& ctx,
                    const Acts::BoundParameters& startParameters,
                    const Acts::Surface& target,
                    Acts::NavigationDirection navDir = Acts::forward,
                    double pathLimit = std::numeric_limits<double>::max()) const override;
-            
+
   virtual
   std::unique_ptr<const Acts::BoundParameters>
   propagate(const EventContext& ctx,
@@ -114,8 +112,12 @@ private:
   Gaudi::Property<std::vector<double>> m_constantFieldVector{this, "ConstantFieldVector", {0, 0, 0}, "Constant field value to use if FieldMode == Constant"};
 
   Gaudi::Property<double> m_ptLoopers{this, "PtLoopers", 300, "PT loop protection threshold. Will be converted to Acts MeV unit"};
-
   Gaudi::Property<double> m_maxStepSize{this, "MaxStepSize", 10, "Max step size in Acts m unit"};
+
+  // Material inteaction option
+  Gaudi::Property<bool> m_interactionMultiScatering{this, "InteractionMultiScatering", false, "Whether to consider multiple scattering in the interactor"};
+  Gaudi::Property<bool> m_interactionEloss{this, "InteractionEloss", false, "Whether to consider energy loss in the interactor"};
+  Gaudi::Property<bool> m_interactionRecord{this, "InteractionRecord", false, "Whether to record all material interactions"};
 };
 
 
diff --git a/Tracking/Acts/ActsGeometry/ActsGeometry/ActsMaterialJsonWriterTool.h b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsMaterialJsonWriterTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..c457d4ee3efc7186e6da1a7b372e6a9b91d97c90
--- /dev/null
+++ b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsMaterialJsonWriterTool.h
@@ -0,0 +1,50 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ACTSGEOMETRY_ACTSMATERIALJSONWRITERTOOL_H
+#define ACTSGEOMETRY_ACTSMATERIALJSONWRITERTOOL_H
+
+// ATHENA
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "AthenaBaseComps/AthService.h"
+#include "GaudiKernel/IInterface.h"
+#include "GaudiKernel/Property.h"  /*no forward decl: typedef*/
+
+// PACKAGE
+#include "ActsGeometryInterfaces/IActsMaterialJsonWriterTool.h"
+
+// ACTS
+#include "Acts/Plugins/Json/JsonGeometryConverter.hpp"
+
+namespace Acts {
+  class TrackingGeometry;
+}
+
+class ActsMaterialJsonWriterTool : public extends<AthAlgTool, IActsMaterialJsonWriterTool>
+{
+
+public:
+
+  virtual StatusCode initialize() override;
+
+  ActsMaterialJsonWriterTool(const std::string& type, const std::string& name,
+                                const IInterface* parent);
+
+  ~ActsMaterialJsonWriterTool();
+
+  virtual
+  void
+  write(const Acts::JsonGeometryConverter::DetectorMaterialMaps& detMaterial) const override;
+
+  virtual
+  void
+  write(const Acts::TrackingGeometry& tGeometry) const override;
+
+
+private:
+
+  Gaudi::Property<std::string> m_filePath{this, "FilePath", "material-maps.json", "Output json file for the Material Map"};
+
+};
+#endif
diff --git a/Tracking/Acts/ActsGeometry/ActsGeometry/ActsMaterialMapping.h b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsMaterialMapping.h
new file mode 100755
index 0000000000000000000000000000000000000000..10a7105a2454a5b577f08d4154d85db3002dfb64
--- /dev/null
+++ b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsMaterialMapping.h
@@ -0,0 +1,69 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ACTSMATERIALMAPPING_H
+#define ACTSMATERIALMAPPING_H
+
+// ATHENA
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/Property.h"  /*no forward decl: typedef*/
+#include "GaudiKernel/ISvcLocator.h"
+#include "StoreGate/ReadHandleKey.h"
+#include "TrkGeometry/MaterialStepCollection.h"
+
+// ACTS
+#include "Acts/EventData/TrackParameters.hpp"
+#include "Acts/Geometry/GeometryID.hpp"
+#include "Acts/Utilities/Helpers.hpp"
+#include "Acts/Material/SurfaceMaterialMapper.hpp"
+
+// PACKAGE
+#include "ActsGeometry/ActsTrackingGeometryTool.h"
+
+// STL
+#include <memory>
+#include <vector>
+#include <fstream>
+#include <mutex>
+
+namespace Acts {
+  class ISurfaceMaterial;
+  class IVolumeMaterial;
+
+  using SurfaceMaterialMap
+      = std::map<GeometryID, std::shared_ptr<const ISurfaceMaterial>>;
+
+  using VolumeMaterialMap
+      = std::map<GeometryID, std::shared_ptr<const IVolumeMaterial>>;
+
+  using DetectorMaterialMaps = std::pair<SurfaceMaterialMap, VolumeMaterialMap>;
+}
+
+class IActsMaterialTrackWriterSvc;
+class IActsMaterialStepConverterTool;
+class IActsSurfaceMappingTool;
+class IActsMaterialJsonWriterTool;
+
+class ActsMaterialMapping : public AthReentrantAlgorithm {
+public:
+  ActsMaterialMapping (const std::string& name, ISvcLocator* pSvcLocator);
+  virtual StatusCode initialize() override;
+  virtual StatusCode execute(const EventContext& ctx) const override;
+  virtual StatusCode finalize() override;
+
+private:
+  ServiceHandle<IActsMaterialTrackWriterSvc>      m_materialTrackWriterSvc;
+  ToolHandle<IActsMaterialStepConverterTool>      m_materialStepConverterTool{this, "MaterialStepConverterTool", "ActsMaterialStepConverterTool"};
+  SG::ReadHandleKey<Trk::MaterialStepCollection>  m_inputMaterialStepCollection;
+  ToolHandle<IActsSurfaceMappingTool>             m_surfaceMappingTool{this, "SurfaceMappingTool", "ActsSurfaceMappingTool"};
+  ToolHandle<IActsMaterialJsonWriterTool>         m_materialJsonWriterTool{this, "MaterialJsonWriterTool", "ActsMaterialJsonWriterTool"};
+
+  Acts::MagneticFieldContext                      m_mctx;
+  Acts::GeometryContext                           m_gctx;
+  Acts::SurfaceMaterialMapper::State              m_mappingState;
+};
+
+#endif // ActsGeometry_ActsExtrapolation_h
diff --git a/Tracking/Acts/ActsGeometry/ActsGeometry/ActsMaterialStepConverterTool.h b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsMaterialStepConverterTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..13e05adcf52ea03ffcb6575d1f7277f239cbd57e
--- /dev/null
+++ b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsMaterialStepConverterTool.h
@@ -0,0 +1,34 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ACTSGEOMETRY_ACTSMATERIALSTEPCONVERTERTOOL_H
+#define ACTSGEOMETRY_ACTSMATERIALSTEPCONVERTERTOOL_H
+
+// ATHENA
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/EventContext.h"
+#include "GaudiKernel/IInterface.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "StoreGate/ReadCondHandleKey.h"
+
+// PACKAGE
+#include "ActsGeometry/ActsAlignmentStore.h" // ReadCondHandleKey wants complete type
+#include "ActsGeometry/ActsGeometryContext.h"
+#include "ActsGeometryInterfaces/IActsMaterialStepConverterTool.h"
+
+class ActsMaterialStepConverterTool : public extends<AthAlgTool, IActsMaterialStepConverterTool>
+{
+
+public:
+  virtual StatusCode initialize() override;
+
+  ActsMaterialStepConverterTool(const std::string &type, const std::string &name,
+                                const IInterface *parent);
+
+  virtual
+  const Acts::RecordedMaterialTrack
+  convertToMaterialTrack(const Trk::MaterialStepCollection &colStep) const override;
+
+};
+#endif
diff --git a/Tracking/Acts/ActsGeometry/ActsGeometry/ActsMaterialTrackWriterSvc.h b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsMaterialTrackWriterSvc.h
index d36b5c8bdd603b30f9957ae125ae14c5b1dabe19..c8aeff8c547570008f850dc0fbe71aa8629fa78e 100644
--- a/Tracking/Acts/ActsGeometry/ActsGeometry/ActsMaterialTrackWriterSvc.h
+++ b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsMaterialTrackWriterSvc.h
@@ -1,11 +1,11 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef ACTSGEOMETRY_ACTSMATERIALTRACKWRITERSVC_H
 #define ACTSGEOMETRY_ACTSMATERIALTRACKWRITERSVC_H
 
-#include "ActsGeometry/IActsMaterialTrackWriterSvc.h"
+#include "ActsGeometryInterfaces/IActsMaterialTrackWriterSvc.h"
 
 #include "AthenaBaseComps/AthService.h"
 #include "GaudiKernel/IInterface.h"
@@ -20,67 +20,63 @@
 #include "TTree.h"
 #include "TFile.h"
 
-namespace Acts {
-  class MaterialTrack;
-}
-
 class ActsMaterialTrackWriterSvc : public extends<AthService, IActsMaterialTrackWriterSvc> {
 public:
-    
+
   virtual StatusCode initialize() override;
   virtual StatusCode finalize() override;
-    
+
   ActsMaterialTrackWriterSvc( const std::string& name, ISvcLocator* svc );
 
-  void
-  write(const Acts::MaterialTrack& mTrack) override;
+  virtual void
+  write(const Acts::RecordedMaterialTrack& mTrack) override;
 
 private:
 
-  std::deque<Acts::MaterialTrack> m_mTracks;
+  std::deque<Acts::RecordedMaterialTrack> m_mTracks;
   std::mutex m_writeMutex;
   std::thread m_writeThread;
   std::atomic<bool> m_doEnd;
   TFile* p_tFile;
   TTree* p_tree;
 
-  // tree branches
-  double m_treeX0;
-  double m_treeL0;
-  double m_treeTheta;
-  double m_treePhi;
-  double m_treeT;
-  double m_treedInX0;
-  double m_treedInL0;
-
-  //std::vector<std::array<double, 3>> m_treeStepPos;
-  std::vector<double> m_treeStepX0;
-  std::vector<double> m_treeStepL0;
-  std::vector<double> m_treeStepA;
-  std::vector<double> m_treeStepZ;
-  std::vector<double> m_treeStepRho;
-  std::vector<double> m_treeStepT;
-  std::vector<double> m_treeStepdInX0;
-  std::vector<double> m_treeStepdInL0;
-  
-  std::vector<double> m_treeStepPosX;
-  std::vector<double> m_treeStepPosY;
-  std::vector<double> m_treeStepPosZ;
-  std::vector<double> m_treeStepPosR;
-  std::vector<double> m_treeStepPosPhi;
-
-  std::vector<ULong64_t> m_treeStepGeoID;
+  float m_v_x;    ///< start global x
+  float m_v_y;    ///< start global y
+  float m_v_z;    ///< start global z
+  float m_v_px;   ///< start global momentum x
+  float m_v_py;   ///< start global momentum y
+  float m_v_pz;   ///< start global momentum z
+  float m_v_phi;  ///< start phi direction
+  float m_v_eta;  ///< start eta direction
+  float m_tX0;    ///< thickness in X0/L0
+  float m_tL0;    ///< thickness in X0/L0
+
+  std::vector<float> m_step_sx;      ///< step x (start) position (optional)
+  std::vector<float> m_step_sy;      ///< step y (start) position (optional)
+  std::vector<float> m_step_sz;      ///< step z (start) position (optional)
+  std::vector<float> m_step_x;       ///< step x position
+  std::vector<float> m_step_y;       ///< step y position
+  std::vector<float> m_step_z;       ///< step z position
+  std::vector<float> m_step_ex;      ///< step x (end) position (optional)
+  std::vector<float> m_step_ey;      ///< step y (end) position (optional)
+  std::vector<float> m_step_ez;      ///< step z (end) position (optional)
+  std::vector<float> m_step_length;  ///< step length
+  std::vector<float> m_step_X0;      ///< step material x0
+  std::vector<float> m_step_L0;      ///< step material l0
+  std::vector<float> m_step_A;       ///< step material A
+  std::vector<float> m_step_Z;       ///< step material Z
+  std::vector<float> m_step_rho;     ///< step material rho
 
 
   void writerThread();
-  void doWrite(const Acts::MaterialTrack &mTrack);
+  void doWrite(const Acts::RecordedMaterialTrack &mTrack);
 
   // jobOptions properties
   Gaudi::Property<std::string> m_filePath{this, "FilePath", "MaterialTracks.root", "Output root file for charged particle"};
-  Gaudi::Property<std::string> m_treeName{this, "TreeName", "MaterialTracks", ""};
+  Gaudi::Property<std::string> m_treeName{this, "TreeName", "material-tracks", ""};
   Gaudi::Property<size_t> m_maxQueueSize{this, "MaxQueueSize", 5000, "Limit the write queue to this size"};
 
 };
 
 
-#endif 
+#endif
diff --git a/Tracking/Acts/ActsGeometry/ActsGeometry/ActsSurfaceMappingTool.h b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsSurfaceMappingTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..c2174e4fe61327ff4e6070097cbb3b0828930d07
--- /dev/null
+++ b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsSurfaceMappingTool.h
@@ -0,0 +1,65 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ACTSGEOMETRY_ACTSSURFACEMAPPINGTOOL_H
+#define ACTSGEOMETRY_ACTSSURFACEMAPPINGTOOL_H
+
+// ATHENA
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/IInterface.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/Property.h"
+#include "GaudiKernel/EventContext.h"
+
+// PACKAGE
+#include "ActsGeometryInterfaces/IActsSurfaceMappingTool.h"
+#include "ActsGeometryInterfaces/IActsTrackingGeometryTool.h"
+
+// ACTS
+#include "Acts/Material/SurfaceMaterialMapper.hpp"
+
+// BOOST
+#include <cmath>
+
+class ActsSurfaceMappingTool : public extends<AthAlgTool, IActsSurfaceMappingTool>
+{
+
+public:
+  virtual StatusCode initialize() override;
+
+  ActsSurfaceMappingTool(const std::string& type, const std::string& name,
+	           const IInterface* parent);
+
+  std::shared_ptr<Acts::SurfaceMaterialMapper>
+  mapper() const
+  {
+    return m_mapper;
+  };
+
+  virtual
+  Acts::SurfaceMaterialMapper::State
+  mappingState() const override;
+
+  virtual
+  const IActsTrackingGeometryTool*
+  trackingGeometryTool() const override
+  {
+    return m_trackingGeometryTool.get();
+  }
+
+
+private:
+  // Straight line stepper
+  Acts::MagneticFieldContext m_magFieldContext;
+  Acts::GeometryContext      m_geoContext;
+  using SlStepper  = Acts::StraightLineStepper;
+  using StraightLinePropagator = Acts::Propagator<SlStepper, Acts::Navigator>;
+  ToolHandle<IActsTrackingGeometryTool> m_trackingGeometryTool{this, "TrackingGeometryTool", "ActsTrackingGeometryTool"};
+  std::shared_ptr<Acts::SurfaceMaterialMapper> m_mapper;
+  std::shared_ptr<const Acts::TrackingGeometry> m_trackingGeometry;
+};
+
+
+
+#endif
diff --git a/Tracking/Acts/ActsGeometry/ActsGeometry/ActsVolumeMappingTool.h b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsVolumeMappingTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..e22160eb09baf4e517c8401aa77241a4d72af9ee
--- /dev/null
+++ b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsVolumeMappingTool.h
@@ -0,0 +1,66 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ACTSGEOMETRY_ACTSVOLUMEMAPPINGTOOL_H
+#define ACTSGEOMETRY_ACTSVOLUMEMAPPINGTOOL_H
+
+// ATHENA
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/IInterface.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/Property.h"
+#include "GaudiKernel/EventContext.h"
+
+// PACKAGE
+#include "ActsGeometryInterfaces/IActsVolumeMappingTool.h"
+#include "ActsGeometryInterfaces/IActsTrackingGeometryTool.h"
+
+// ACTS
+#include "Acts/Material/VolumeMaterialMapper.hpp"
+
+// BOOST
+
+#include <cmath>
+
+class ActsVolumeMappingTool : public extends<AthAlgTool, IActsVolumeMappingTool>
+{
+
+public:
+  virtual StatusCode initialize() override;
+
+  ActsVolumeMappingTool(const std::string& type, const std::string& name,
+	           const IInterface* parent);
+
+  std::shared_ptr<Acts::VolumeMaterialMapper>
+  mapper() const
+  {
+    return m_mapper;
+  };
+
+  virtual
+  Acts::VolumeMaterialMapper::State
+  mappingState() const override;
+
+  virtual
+  const IActsTrackingGeometryTool*
+  trackingGeometryTool() const override
+  {
+    return m_trackingGeometryTool.get();
+  }
+
+
+private:
+  // Straight line stepper
+  Acts::MagneticFieldContext m_magFieldContext;
+  Acts::GeometryContext      m_geoContext;
+  using SlStepper  = Acts::StraightLineStepper;
+  using StraightLinePropagator = Acts::Propagator<SlStepper, Acts::Navigator>;
+  ToolHandle<IActsTrackingGeometryTool> m_trackingGeometryTool{this, "TrackingGeometryTool", "ActsTrackingGeometryTool"};
+  std::shared_ptr<Acts::VolumeMaterialMapper> m_mapper;
+  std::shared_ptr<const Acts::TrackingGeometry> m_trackingGeometry;
+};
+
+
+
+#endif
diff --git a/Tracking/Acts/ActsGeometry/ActsGeometry/ActsWriteTrackingGeometry.h b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsWriteTrackingGeometry.h
index 29a1c517f10c6d31d310c09ebee3ead844ef7059..206e485aed91e915ab4ab6fd57c76cecbc6813d4 100755
--- a/Tracking/Acts/ActsGeometry/ActsGeometry/ActsWriteTrackingGeometry.h
+++ b/Tracking/Acts/ActsGeometry/ActsGeometry/ActsWriteTrackingGeometry.h
@@ -27,6 +27,7 @@ namespace Acts {
 }
 
 class IActsTrackingGeometrySvc;
+class IActsMaterialJsonWriterTool;
 
 class ActsWriteTrackingGeometry : public AthReentrantAlgorithm {
 public:
@@ -40,6 +41,7 @@ private:
   ToolHandle<ActsTrackingGeometryTool> m_trackingGeometryTool{this, "TrackingGeometryTool", "ActsTrackingGeometryTool"};
 
   ToolHandle<ActsObjWriterTool> m_objWriterTool{this, "ObjWriterTool", "ActsObjWriterTool"};
+  ToolHandle<IActsMaterialJsonWriterTool> m_materialJsonWriterTool{this, "MaterialJsonWriterTool", "ActsMaterialJsonWriterTool"};
 
 };
 
diff --git a/Tracking/Acts/ActsGeometry/CMakeLists.txt b/Tracking/Acts/ActsGeometry/CMakeLists.txt
index 9bd53b33422c69c7f0fd27bc6a88ab12978c06e4..f3f13b63cca78e91155cd5633323270d99cd0f9d 100755
--- a/Tracking/Acts/ActsGeometry/CMakeLists.txt
+++ b/Tracking/Acts/ActsGeometry/CMakeLists.txt
@@ -21,14 +21,16 @@ atlas_depends_on_subdirs( PUBLIC
                           MagneticField/MagFieldInterfaces
                           Calorimeter/CaloDetDescr
                           Tracking/Acts/ActsGeometryInterfaces
-                          Tracking/Acts/ActsInterop )
+                          Tracking/Acts/ActsInterop
+                          Tracking/TrkDetDescr/TrkGeometry)
 
 # External dependencies:
 find_package( CLHEP )
 find_package( Eigen )
 find_package( Boost )
+find_package( nlohmann_json )
 
-find_package( Acts COMPONENTS Core )
+find_package( Acts COMPONENTS Core JsonPlugin)
 
 # Component(s) in the package:
 
@@ -46,6 +48,8 @@ atlas_add_library( ActsGeometryLib
                    ActsInteropLib
                    ActsGeometryInterfacesLib
                    ActsCore
+                   ActsJsonPlugin
+                   TrkGeometry
                    PixelReadoutGeometry
                    SCT_ReadoutGeometry
                    TRT_ReadoutGeometry)
@@ -55,9 +59,14 @@ atlas_add_component( ActsGeometry
                      src/ActsWriteTrackingGeometry.cxx
                      src/ActsWriteTrackingGeometryTransforms.cxx
                      src/ActsExtrapolationTool.cxx
+                     src/ActsMaterialMapping.cxx
+                     src/ActsSurfaceMappingTool.cxx
+                     #src/ActsVolumeMappingTool.cxx
                      src/ActsObjWriterTool.cxx
                      #src/ActsExCellWriterSvc.cxx
-                     #src/ActsMaterialTrackWriterSvc.cxx
+                     src/ActsMaterialStepConverterTool.cxx
+                     src/ActsMaterialJsonWriterTool.cxx
+                     src/ActsMaterialTrackWriterSvc.cxx
                      #src/GeomShiftCondAlg.cxx
                      src/ActsAlignmentCondAlg.cxx
                      src/NominalAlignmentCondAlg.cxx
@@ -67,16 +76,16 @@ atlas_add_component( ActsGeometry
                      src/components/*.cxx
                      PUBLIC_HEADERS ActsGeometry
                      INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS} ${BOOST_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} 
+                     LINK_LIBRARIES ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES}
                      EventInfo
                      CaloDetDescrLib
-                     ActsInteropLib 
+                     ActsInteropLib
                      ActsGeometryLib
                      ActsGeometryInterfacesLib
-                     ActsCore)
+                     ActsCore
+                     ActsJsonPlugin)
 
 # Install files from the package:
 atlas_install_headers( ActsGeometry )
 atlas_install_joboptions( share/*.py )
 atlas_install_python_modules( python/*.py )
-
diff --git a/Tracking/Acts/ActsGeometry/share/ActsExtrapolationAlg.py b/Tracking/Acts/ActsGeometry/share/ActsExtrapolationAlg.py
index 8e52e01b92192f930d919ee5b6eb30d8133721bc..e2907f4e0508cd17c93d25e78e576bc4086e63ae 100644
--- a/Tracking/Acts/ActsGeometry/share/ActsExtrapolationAlg.py
+++ b/Tracking/Acts/ActsGeometry/share/ActsExtrapolationAlg.py
@@ -5,7 +5,7 @@ Acts tracking geometry and the Acts extrapolation toolchain.
 
 # start from scratch with component accumulator
 
-from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator 
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
 
 from ActsGeometry.ActsGeometryConfig import ActsExtrapolationToolCfg
@@ -33,7 +33,7 @@ if "__main__" == __name__:
   from AthenaCommon.Logging import log
   from AthenaCommon.Constants import VERBOSE
   from AthenaConfiguration.AllConfigFlags import ConfigFlags
-  from AthenaConfiguration.MainServicesConfig import MainServicesCfg    
+  from AthenaConfiguration.MainServicesConfig import MainServicesCfg
 
   Configurable.configurableRun3Behavior = True
 
@@ -43,7 +43,7 @@ if "__main__" == __name__:
   ConfigFlags.GeoModel.AtlasVersion  = "ATLAS-R2-2016-01-00-01"
   ConfigFlags.IOVDb.GlobalTag        = "OFLCOND-SIM-00-00-00"
   ConfigFlags.Detector.SimulateBpipe = True
-  ConfigFlags.Detector.SimulateID    = True    
+  ConfigFlags.Detector.SimulateID    = True
   ConfigFlags.Detector.GeometryBpipe = True
   ConfigFlags.Detector.GeometryID    = True
   ConfigFlags.Detector.GeometryPixel = True
@@ -81,6 +81,3 @@ if "__main__" == __name__:
   log.info("CONFIG DONE")
 
   cfg.run(1)
-
-
-
diff --git a/Tracking/Acts/ActsGeometry/share/ActsMaterialMapping_jobOptions.py b/Tracking/Acts/ActsGeometry/share/ActsMaterialMapping_jobOptions.py
index 6283e09a0e480e0e1f1bb99cbfdb3af71915cf3c..b20518e8aa9d2d6d1d72f487d9d35a9351157872 100644
--- a/Tracking/Acts/ActsGeometry/share/ActsMaterialMapping_jobOptions.py
+++ b/Tracking/Acts/ActsGeometry/share/ActsMaterialMapping_jobOptions.py
@@ -18,13 +18,13 @@ ServiceMgr.MessageSvc.defaultLimit = 20000
 DetFlags.ID_setOn()
 DetFlags.detdescr.pixel_setOn()
 DetFlags.detdescr.SCT_setOn()
-
+DetFlags.Calo_setOff()
 
 # MC or data - affects which conditions database instance is used
 globalflags.DataSource='geant4'
 #globalflags.DataSource='data'
 
-# Select the geometry version. 
+# Select the geometry version.
 globalflags.DetDescrVersion = 'ATLAS-R2-2016-00-00-00'
 
 # print "HERE"
@@ -43,15 +43,11 @@ from IOVDbSvc.CondDB import conddb
 conddb.setGlobalTag('OFLCOND-SIM-00-00-00')
 # conddb.addOverride("/Indet/Align", "InDetAlign_R2_Nominal")
 
-import glob
-fileList = glob.glob("*root*") #/tmp/salzburg/*/*.root*")
-
 from AthenaCommon.AppMgr import ServiceMgr
 
 # Read material step file
-import AthenaPoolCnvSvc.ReadAthenaPool 
-ServiceMgr.EventSelector.InputCollections =  ["MaterialStepFile_1e6.root"]
-
+import AthenaPoolCnvSvc.ReadAthenaPool
+ServiceMgr.EventSelector.InputCollections =  ["MaterialStepFile.root"]
 
 
 from AthenaCommon.AlgScheduler import AlgScheduler
@@ -69,32 +65,52 @@ svcMgr += CondSvc( OutputLevel=INFO )
 # ServiceMgr.THistSvc.Output += ["MATTRACKVAL DATAFILE='MaterialTracks.root' OPT='RECREATE'"]
 # ServiceMgr.ToolSvc.OutputLevel = VERBOSE
 
+
 # Set up ACTS tracking geometry service
-from ActsGeometry.ActsGeometryConfig import TrackingGeometrySvc
-trkGeomSvc = TrackingGeometrySvc()
+from ActsGeometry.ActsGeometryConf import ActsTrackingGeometrySvc
+trkGeomSvc = ActsTrackingGeometrySvc()
 trkGeomSvc.OutputLevel = INFO
 trkGeomSvc.BarrelMaterialBins = [40, 60] # phi z
 trkGeomSvc.EndcapMaterialBins = [50, 20] # phi r
+trkGeomSvc.BuildSubDetectors = [
+  "Pixel",
+  "SCT",
+  # "TRT",
+  # "Calo",
+]
 ServiceMgr += trkGeomSvc
 
-# Set up ACTS extrapolation cell writer service
-exCellWriterSvc = CfgMgr.Acts__ExCellWriterSvc("ExCellWriterSvc")
-exCellWriterSvc.FilePath = "excells_charged_mapping.root"
-ServiceMgr += exCellWriterSvc
+trkGeomTool = CfgMgr.ActsTrackingGeometryTool("ActsTrackingGeometryTool")
+trkGeomTool.OutputLevel = INFO;
 
-mTrackWriterSvc = CfgMgr.Acts__MaterialTrackWriterSvc("MaterialTrackWriterSvc")
-mTrackWriterSvc.OutputLevel = DEBUG
+# Set up ACTS extrapolation cell writer service
+# exCellWriterSvc = CfgMgr.ActsExCellWriterSvc("ActsExCellWriterSvc")
+# exCellWriterSvc.FilePath = "excells_charged_mapping.root"
+# ServiceMgr += exCellWriterSvc
+mTrackWriterSvc = CfgMgr.ActsMaterialTrackWriterSvc("ActsMaterialTrackWriterSvc")
+mTrackWriterSvc.OutputLevel = INFO
 mTrackWriterSvc.FilePath = "MaterialTracks_mapping.root"
 # mTrackWriterSvc.MaxQueueSize = 10
 ServiceMgr += mTrackWriterSvc
 
+mMaterialStepConverterTool = CfgMgr.ActsMaterialStepConverterTool("ActsMaterialStepConverterTool")
+mMaterialStepConverterTool.OutputLevel = INFO
+
+mActsSurfaceMappingTool = CfgMgr.ActsSurfaceMappingTool("ActsSurfaceMappingTool")
+mActsSurfaceMappingTool.OutputLevel = INFO
+mActsSurfaceMappingTool.TrackingGeometryTool = trkGeomTool
+
+mActsMaterialJsonWriterTool = CfgMgr.ActsMaterialJsonWriterTool("ActsMaterialJsonWriterTool")
+mActsMaterialJsonWriterTool.OutputLevel = VERBOSE
+mActsMaterialJsonWriterTool.FilePath = "material-maps.json"
+
 from ActsGeometry import ActsGeometryConf
 
 ## SET UP ALIGNMENT CONDITIONS ALGORITHM
-from AthenaCommon.AlgSequence import AthSequencer 
-condSeq = AthSequencer("AthCondSeq") 
-condSeq += ActsGeometryConf.NominalAlignmentCondAlg("NominalAlignmentCondAlg", 
-                                                     OutputLevel=VERBOSE)
+from AthenaCommon.AlgSequence import AthSequencer
+condSeq = AthSequencer("AthCondSeq")
+condSeq += ActsGeometryConf.NominalAlignmentCondAlg("NominalAlignmentCondAlg",
+                                                 OutputLevel=INFO)
 ## END OF CONDITIONS SETUP
 
 # Set up algorithm sequence
@@ -108,20 +124,16 @@ if hasattr(ServiceMgr,"AthenaEventLoopMgr"):
 if hasattr(ServiceMgr,"AthenaHiveEventLoopMgr"):
     ServiceMgr.AthenaHiveEventLoopMgr.EventPrintoutInterval = eventPrintFrequency
 
-# from GaudiAlg.GaudiAlgConf import EventCounter
-# job += EventCounter(Frequency=1000)
+from GaudiAlg.GaudiAlgConf import EventCounter
+job += EventCounter(Frequency=1000)
 
 # Set up material mapping algorithm
 from ActsGeometry.ActsGeometryConf import ActsMaterialMapping
 
 alg = ActsMaterialMapping()
 alg.Cardinality = 0#nThreads
-alg.OutputLevel = VERBOSE
-alg.ExtrapolationTool.FieldMode = "Constant"
-alg.ExtrapolationTool.ConstantFieldVector = [0, 0, 0]
-alg.ExtrapolationTool.OutputLevel = INFO
-
-
+alg.MaterialStepConverterTool = mMaterialStepConverterTool
+alg.SurfaceMappingTool = mActsSurfaceMappingTool
+alg.MaterialJsonWriterTool = mActsMaterialJsonWriterTool
 alg.OutputLevel = INFO
 job += alg
-
diff --git a/Tracking/Acts/ActsGeometry/share/ActsMaterialValidationAlg.py b/Tracking/Acts/ActsGeometry/share/ActsMaterialValidationAlg.py
new file mode 100644
index 0000000000000000000000000000000000000000..cdaed670692e63b85b2f4357eaeaae204d5200d9
--- /dev/null
+++ b/Tracking/Acts/ActsGeometry/share/ActsMaterialValidationAlg.py
@@ -0,0 +1,148 @@
+"""
+This job options file will run an example extrapolation using the
+Acts tracking geometry, the material map and the Acts extrapolation toolchain.
+"""
+
+import os
+import logging
+
+# Use Global flags and DetFlags.
+from AthenaCommon.DetFlags import DetFlags
+from AthenaCommon.GlobalFlags import globalflags
+
+from AthenaCommon.ConcurrencyFlags import jobproperties as jp
+from AthenaCommon.Logging import log as msg
+nThreads = jp.ConcurrencyFlags.NumThreads()
+# for some reason, the synchronization fails if we run in ST...
+if (nThreads < 1) :
+    msg.fatal('numThreads must be >0. Did you set the --threads=N option?')
+    sys.exit(AthenaCommon.ExitCodes.CONFIGURATION_ERROR)
+
+from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
+athenaCommonFlags.FilesInput = [
+    "/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/esd/100evts10lumiblocks.ESD.root"
+]
+
+import AthenaPoolCnvSvc.ReadAthenaPool
+
+# build GeoModel
+import AthenaPython.ConfigLib as apcl
+cfg = apcl.AutoCfg(name = 'MaterialMapValidation', input_files=athenaCommonFlags.FilesInput())
+
+cfg.configure_job()
+
+from AthenaCommon.GlobalFlags import globalflags
+if len(globalflags.ConditionsTag())!=0:
+  from IOVDbSvc.CondDB import conddb
+  conddb.setGlobalTag(globalflags.ConditionsTag())
+
+from AtlasGeoModel.InDetGMJobProperties import InDetGeometryFlags
+InDetGeometryFlags.useDynamicAlignFolders=True
+
+# Just the pixel and SCT
+DetFlags.ID_setOn()
+DetFlags.Calo_setOn()
+
+
+# Initialize geometry
+# THIS ACTUALLY DOES STUFF!!
+from AtlasGeoModel import GeoModelInit
+from AtlasGeoModel import SetGeometryVersion
+
+from AthenaCommon.AlgScheduler import AlgScheduler
+AlgScheduler.OutputLevel( INFO )
+AlgScheduler.ShowControlFlow( True )
+AlgScheduler.ShowDataDependencies( True )
+AlgScheduler.EnableConditions( True )
+AlgScheduler.setDataLoaderAlg( "SGInputLoader" )
+
+## SET UP ALIGNMENT CONDITIONS ALGORITHM
+from IOVSvc.IOVSvcConf import CondSvc
+svcMgr += CondSvc( OutputLevel=INFO )
+from ActsGeometry import ActsGeometryConf
+from AthenaCommon.AlgSequence import AthSequencer
+condSeq = AthSequencer("AthCondSeq")
+
+# nominal alignment: all deltas are identity
+# condSeq += ActsGeometryConf.NominalAlignmentCondAlg("NominalAlignmentCondAlg",
+                                                     # OutputLevel=VERBOSE)
+
+condSeq += ActsGeometryConf.ActsAlignmentCondAlg("ActsAlignCondAlg",
+                                                 OutputLevel=INFO)
+# periodic shift alignment. Configurable z-shift per lumiblock.
+# (currently pixel only)
+# condSeq+=ActsGeometryConf.GeomShiftCondAlg("GeomShiftCondAlg_1",
+                                            # ZShiftPerLB=0.5,
+                                            # OutputLevel=VERBOSE)
+## END OF CONDITIONS SETUP
+
+from AthenaCommon.AppMgr import ServiceMgr
+
+# set up and configure the acts geometry construction
+from ActsGeometry.ActsGeometryConf import ActsTrackingGeometrySvc
+trkGeomSvc = ActsTrackingGeometrySvc()
+# used for the proxies during material mapping
+trkGeomSvc.BarrelMaterialBins = [40, 60] # phi z
+trkGeomSvc.EndcapMaterialBins = [50, 20] # phi r
+trkGeomSvc.OutputLevel = INFO
+trkGeomSvc.BuildSubDetectors = [
+  "Pixel",
+  "SCT",
+  # "TRT",
+  # "Calo",
+]
+trkGeomSvc.UseMaterialMap = True
+trkGeomSvc.MaterialMapInputFile = "material-maps.json"
+ServiceMgr += trkGeomSvc
+
+# We need the Magnetic fiels
+import MagFieldServices.SetupField
+
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+# This is the main extrapolation demo algorithm
+from ActsGeometry.ActsGeometryConf import ActsExtrapolationAlg
+alg = ActsExtrapolationAlg()
+alg.EtaRange = [-2.4, 2.4]
+alg.OutputLevel = INFO
+alg.NParticlesPerEvent = int(1e4)
+
+
+# Record the material track for material map validation
+alg.WriteMaterialTracks = True
+# we only need this if the extrap alg is set up to write mat tracks
+if alg.WriteMaterialTracks == True:
+  mTrackWriterSvc = CfgMgr.ActsMaterialTrackWriterSvc("ActsMaterialTrackWriterSvc")
+  mTrackWriterSvc.OutputLevel = INFO
+  mTrackWriterSvc.FilePath = "MaterialTracks_mapped.root"
+  ServiceMgr += mTrackWriterSvc
+
+# sets up the extrapolation tool
+# this sets up the tracking geometry svc through the tracking geometry tool
+exTool = CfgMgr.ActsExtrapolationTool("ActsExtrapolationTool")
+exTool.OutputLevel = INFO
+exTool.FieldMode = "ATLAS"
+exTool.InteractionMultiScatering = True
+exTool.InteractionEloss = True
+exTool.InteractionRecord = True
+# The extrapolation tool accesses the trackinggeometry service
+# through this tool. This tool has the conditions dependencies
+# on the alignment GeoAlignmentStores (pseudo-alignment only right now).
+# For each event, the GAS for the IOV needs to be set from the algorithm.
+trkGeomTool = CfgMgr.ActsTrackingGeometryTool("ActsTrackingGeometryTool")
+trkGeomTool.OutputLevel = INFO;
+exTool.TrackingGeometryTool = trkGeomTool
+
+alg.ExtrapolationTool = exTool
+
+# Make the event heardbeat output a bit nicer
+eventPrintFrequency = 10000
+if hasattr(ServiceMgr,"AthenaEventLoopMgr"):
+    ServiceMgr.AthenaEventLoopMgr.EventPrintoutInterval = eventPrintFrequency
+if hasattr(ServiceMgr,"AthenaHiveEventLoopMgr"):
+    ServiceMgr.AthenaHiveEventLoopMgr.EventPrintoutInterval = eventPrintFrequency
+
+job += alg
+
+theApp.EvtMax = 10000
diff --git a/Tracking/Acts/ActsGeometry/share/ActsWriteTrackingGeometry.py b/Tracking/Acts/ActsGeometry/share/ActsWriteTrackingGeometry.py
index af95eb1b81e1808f065610745ceb6cae537c0801..6bdf79f04d72d20f359a127d1c8d743d07253715 100644
--- a/Tracking/Acts/ActsGeometry/share/ActsWriteTrackingGeometry.py
+++ b/Tracking/Acts/ActsGeometry/share/ActsWriteTrackingGeometry.py
@@ -72,6 +72,12 @@ trkGeomSvc = ActsTrackingGeometrySvc()
 trkGeomSvc.BarrelMaterialBins = [40, 60] # phi z
 trkGeomSvc.EndcapMaterialBins = [50, 20] # phi r
 trkGeomSvc.OutputLevel = INFO
+trkGeomSvc.BuildSubDetectors = [
+  "Pixel",
+  "SCT",
+  # "TRT",
+  # "Calo",
+]
 ServiceMgr += trkGeomSvc
 
 import MagFieldServices.SetupField
@@ -87,12 +93,16 @@ trkGeomTool.OutputLevel = INFO;
 # alg.TrackingGeometryTool = trkGeomTool
 # job += alg
 
+mActsMaterialJsonWriterTool = CfgMgr.ActsMaterialJsonWriterTool("ActsMaterialJsonWriterTool")
+mActsMaterialJsonWriterTool.OutputLevel = VERBOSE
+mActsMaterialJsonWriterTool.FilePath = "geometry-maps.json"
 
 from ActsGeometry.ActsGeometryConf import ActsWriteTrackingGeometry
 alg = ActsWriteTrackingGeometry(OutputLevel = VERBOSE)
 alg.TrackingGeometryTool = trkGeomTool
 alg.ObjWriterTool.OutputDirectory = "obj"
 alg.ObjWriterTool.SubDetectors = ["Pixel", "SCT"]
+alg.MaterialJsonWriterTool = mActsMaterialJsonWriterTool
 
 job += alg
 
@@ -106,4 +116,3 @@ if hasattr(ServiceMgr,"AthenaHiveEventLoopMgr"):
 
 
 theApp.EvtMax = 1
-
diff --git a/Tracking/Acts/ActsGeometry/share/GeantinoMapping_jobOptions.py b/Tracking/Acts/ActsGeometry/share/GeantinoMapping_jobOptions.py
index 1bd322b752cc7167957005efe845c0109fa66eaf..53291813e5ba7bd9bf411ec83c7138202ed6fb55 100644
--- a/Tracking/Acts/ActsGeometry/share/GeantinoMapping_jobOptions.py
+++ b/Tracking/Acts/ActsGeometry/share/GeantinoMapping_jobOptions.py
@@ -42,7 +42,7 @@ if 'myRandomSeed2' not in dir() :
     myRandomSeed2 = int(random.uniform(0,time.time()))
 
 if 'myMaxEvent' not in dir() :
-    myMaxEvent = 10
+    myMaxEvent = 100
 
 if 'myPt' not in dir() :
     myPt = 'pt'  # values are 'p' or 'pt'
@@ -66,7 +66,7 @@ print globalflags.ConditionsTag
 from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
 athenaCommonFlags.PoolEvgenInput.set_Off()   ### is this necessary?
 athenaCommonFlags.PoolHitsOutput = 'Hits.pool.root'
-athenaCommonFlags.EvtMax = 1000
+athenaCommonFlags.EvtMax = 1000000
 
 #--- Simulation flags -----------------------------------------
 from G4AtlasApps.SimFlags import simFlags
@@ -74,19 +74,19 @@ simFlags.load_atlas_flags() # Going to use an ATLAS layout
 simFlags.SimLayout = myGeo
 simFlags.EventFilter.set_Off()
 
-myMinEta = -6.0
-myMaxEta =  6.0
+myMinEta = -2.5
+myMaxEta =  2.5
 
 myPDG    = 999   # 999 = Geantinos, 13 = Muons
 
 include("GeneratorUtils/StdEvgenSetup.py")
-theApp.EvtMax = 1000
+theApp.EvtMax = 20000
 
 import ParticleGun as PG
 pg = PG.ParticleGun()
 pg.sampler.pid = 999
 pg.randomSeed = 123456
-pg.sampler.mom = PG.EEtaMPhiSampler(energy=10000, eta=[-6.,6.])
+pg.sampler.mom = PG.EEtaMPhiSampler(energy=10000, eta=[myMinEta,myMaxEta])
 topSeq += pg
 
 simFlags.RandomSeedOffset = myRandomOffset
@@ -151,4 +151,3 @@ if not hasattr(condSeq, "BeamSpotCondAlg"):
 
 
 #--- End jobOptions.GeantinoMapping.py file  ------------------------------
-
diff --git a/Tracking/Acts/ActsGeometry/src/ActsExtrapolationAlg.cxx b/Tracking/Acts/ActsGeometry/src/ActsExtrapolationAlg.cxx
index 8ed4b0569a2edb170eb83830ef07c3788ad686d6..84ada281557659e88deb733e78e9f084ae7cfc7e 100755
--- a/Tracking/Acts/ActsGeometry/src/ActsExtrapolationAlg.cxx
+++ b/Tracking/Acts/ActsGeometry/src/ActsExtrapolationAlg.cxx
@@ -1,13 +1,10 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "ActsGeometry/ActsExtrapolationAlg.h"
 
 // ATHENA
-#include "Acts/Surfaces/PerigeeSurface.hpp"
-#include "Acts/Utilities/Logger.hpp"
-#include "ActsGeometry/IActsPropStepRootWriterSvc.h"
 #include "AthenaKernel/IAthRNGSvc.h"
 #include "AthenaKernel/RNGWrapper.h"
 #include "GaudiKernel/EventContext.h"
@@ -15,16 +12,20 @@
 #include "MagFieldInterfaces/IMagFieldSvc.h"
 
 // ACTS
+#include "Acts/Propagator/MaterialInteractor.hpp"
 #include "Acts/Propagator/detail/SteppingLogger.hpp"
+#include "Acts/Surfaces/PerigeeSurface.hpp"
 #include "Acts/Utilities/Helpers.hpp"
 #include "Acts/Utilities/Units.hpp"
+#include "Acts/Utilities/Logger.hpp"
 
 // PACKAGE
 #include "ActsGeometry/ActsGeometryContext.h"
+#include "ActsGeometry/IActsPropStepRootWriterSvc.h"
 #include "ActsGeometryInterfaces/IActsExtrapolationTool.h"
+#include "ActsGeometryInterfaces/IActsMaterialTrackWriterSvc.h"
 #include "ActsGeometryInterfaces/IActsTrackingGeometryTool.h"
 #include "ActsInterop/Logger.h"
-//#include "ActsGeometry/IActsMaterialTrackWriterSvc.h"
 
 // OTHER
 #include "CLHEP/Random/RandomEngine.h"
@@ -35,12 +36,20 @@
 
 using namespace Acts::UnitLiterals;
 
+namespace Acts{
+  /// Recorded material track
+  /// - this is start:  position, start momentum
+  ///   and the Recorded material
+  using RecordedMaterialTrack =
+      std::pair<std::pair<Acts::Vector3D, Acts::Vector3D>, RecordedMaterial>;
+}
+
 ActsExtrapolationAlg::ActsExtrapolationAlg(const std::string &name,
                                            ISvcLocator *pSvcLocator)
     : AthReentrantAlgorithm(name, pSvcLocator),
       m_propStepWriterSvc("ActsPropStepRootWriterSvc", name),
-      m_rndmGenSvc("AthRNGSvc", name) //,
-// m_materialTrackWriterSvc("ActsMaterialTrackWriterSvc", name)
+      m_rndmGenSvc("AthRNGSvc", name) ,
+      m_materialTrackWriterSvc("ActsMaterialTrackWriterSvc", name)
 {}
 
 StatusCode ActsExtrapolationAlg::initialize() {
@@ -51,9 +60,9 @@ StatusCode ActsExtrapolationAlg::initialize() {
   ATH_CHECK(m_extrapolationTool.retrieve());
   ATH_CHECK(m_propStepWriterSvc.retrieve());
 
-  // if (m_writeMaterialTracks) {
-  // ATH_CHECK( m_materialTrackWriterSvc.retrieve() );
-  //}
+  if (m_writeMaterialTracks) {
+  ATH_CHECK( m_materialTrackWriterSvc.retrieve() );
+  }
 
   m_objOut = std::make_unique<std::ofstream>("steps.obj");
 
@@ -105,7 +114,7 @@ StatusCode ActsExtrapolationAlg::execute(const EventContext &ctx) const {
     pars << d0, z0, phi, theta, qop, t;
     std::optional<Acts::BoundSymMatrix> cov = std::nullopt;
 
-    std::vector<Acts::detail::Step> steps;
+    ActsPropagationOutput output;
 
     if (charge != 0.) {
       // Perigee, no alignment -> default geo context
@@ -114,11 +123,18 @@ StatusCode ActsExtrapolationAlg::execute(const EventContext &ctx) const {
       auto anygctx = gctx.any();
       Acts::BoundParameters startParameters(
           anygctx, std::move(cov), std::move(pars), std::move(surface));
-      steps = m_extrapolationTool->propagationSteps(ctx, startParameters);
-      if(steps.size() == 0) {
-	ATH_MSG_WARNING("Got ZERO steps from the extrapolation tool");
+      output = m_extrapolationTool->propagationSteps(ctx, startParameters);
+      if(output.first.size() == 0) {
+        ATH_MSG_WARNING("Got ZERO steps from the extrapolation tool");
+      }
+      m_propStepWriterSvc->write(output.first);
+      if(m_writeMaterialTracks){
+        Acts::RecordedMaterialTrack track;
+        track.first.first = Acts::Vector3D(0,0,0);
+        track.first.second = momentum;
+        track.second = std::move(output.second);
+        m_materialTrackWriterSvc->write(track);
       }
-      m_propStepWriterSvc->write(steps);
     }
 
     ATH_MSG_VERBOSE(name() << " execute done");
diff --git a/Tracking/Acts/ActsGeometry/src/ActsExtrapolationTool.cxx b/Tracking/Acts/ActsGeometry/src/ActsExtrapolationTool.cxx
index 1ce2a07cc996a0a4c58ecb38370ba8e13ea9130b..5ba834fc0b993e64f57d356b4fd569d2e695fec8 100644
--- a/Tracking/Acts/ActsGeometry/src/ActsExtrapolationTool.cxx
+++ b/Tracking/Acts/ActsGeometry/src/ActsExtrapolationTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "ActsGeometry/ActsExtrapolationTool.h"
@@ -9,18 +9,19 @@
 #include "MagFieldInterfaces/IMagFieldSvc.h"
 
 // PACKAGE
+#include "ActsGeometry/ActsGeometryContext.h"
 #include "ActsGeometry/ActsTrackingGeometrySvc.h"
-#include "ActsInterop/Logger.h"
 #include "ActsGeometry/ActsTrackingGeometryTool.h"
+#include "ActsInterop/Logger.h"
 
 // ACTS
-#include "Acts/Surfaces/Surface.hpp"
-#include "Acts/Surfaces/BoundaryCheck.hpp"
 #include "Acts/Propagator/Navigator.hpp"
 #include "Acts/Propagator/EigenStepper.hpp"
 #include "Acts/Propagator/Propagator.hpp"
 #include "Acts/Propagator/AbortList.hpp"
 #include "Acts/Propagator/ActionList.hpp"
+#include "Acts/Surfaces/BoundaryCheck.hpp"
+#include "Acts/Surfaces/Surface.hpp"
 
 // BOOST
 #include <boost/variant/variant.hpp>
@@ -31,7 +32,6 @@
 #include <iostream>
 #include <memory>
 
-
 namespace ActsExtrapolationDetail {
   using VariantPropagatorBase = boost::variant<
     Acts::Propagator<Acts::EigenStepper<ATLASMagneticFieldWrapper>, Acts::Navigator>,
@@ -46,7 +46,6 @@ namespace ActsExtrapolationDetail {
 
 }
 
-
 using ActsExtrapolationDetail::VariantPropagator;
 
 
@@ -55,7 +54,6 @@ ActsExtrapolationTool::ActsExtrapolationTool(const std::string& type, const std:
   : base_class(type, name, parent),
     m_fieldServiceHandle("AtlasFieldSvc", name)
 {
-
 }
 
 
@@ -85,7 +83,7 @@ ActsExtrapolationTool::initialize()
     using BField_t = ATLASMagneticFieldWrapper;
     BField_t bField(m_fieldServiceHandle.get());
     auto stepper = Acts::EigenStepper<BField_t>(std::move(bField));
-    auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper), 
+    auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper),
                                                                       std::move(navigator));
     m_varProp = std::make_unique<VariantPropagator>(propagator);
   }
@@ -98,7 +96,7 @@ ActsExtrapolationTool::initialize()
     using BField_t = Acts::ConstantBField;
     BField_t bField(Bx, By, Bz);
     auto stepper = Acts::EigenStepper<BField_t>(std::move(bField));
-    auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper), 
+    auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper),
                                                                       std::move(navigator));
     m_varProp = std::make_unique<VariantPropagator>(propagator);
   }
@@ -108,7 +106,7 @@ ActsExtrapolationTool::initialize()
 }
 
 
-std::vector<Acts::detail::Step>
+ActsPropagationOutput
 ActsExtrapolationTool::propagationSteps(const EventContext& ctx,
                                         const Acts::BoundParameters& startParameters,
                                         Acts::NavigationDirection navDir /*= Acts::forward*/,
@@ -124,7 +122,8 @@ ActsExtrapolationTool::propagationSteps(const EventContext& ctx,
   auto anygctx = gctx.any();
 
   // Action list and abort list
-  using ActionList = Acts::ActionList<SteppingLogger, DebugOutput>;
+  using ActionList =
+  Acts::ActionList<SteppingLogger, Acts::MaterialInteractor, DebugOutput>;
   using AbortConditions = Acts::AbortList<EndOfWorld>;
 
   using Options = Acts::PropagatorOptions<ActionList, AbortConditions>;
@@ -140,7 +139,12 @@ ActsExtrapolationTool::propagationSteps(const EventContext& ctx,
   options.maxStepSize = m_maxStepSize * 1_m;
   options.direction = navDir;
 
-  std::vector<Acts::detail::Step> steps;
+  auto& mInteractor = options.actionList.get<Acts::MaterialInteractor>();
+  mInteractor.multipleScattering = m_interactionMultiScatering;
+  mInteractor.energyLoss = m_interactionEloss;
+  mInteractor.recordInteractions = m_interactionRecord;
+
+  ActsPropagationOutput output;
   DebugOutput::result_type debugOutput;
 
   auto res = boost::apply_visitor([&](const auto& propagator) -> ResultType {
@@ -152,33 +156,37 @@ ActsExtrapolationTool::propagationSteps(const EventContext& ctx,
 
       auto steppingResults = propRes.template get<SteppingLogger::result_type>();
       auto debugOutput = propRes.template get<DebugOutput::result_type>();
+      auto materialResult = propRes.template get<Acts::MaterialInteractor::result_type>();
+      output.first = std::move(steppingResults.steps);
+      output.second = std::move(materialResult);
       // try to force return value optimization, not sure this is necessary
-      return std::make_pair(std::move(steppingResults.steps), std::move(debugOutput));
+      return std::make_pair(std::move(output), std::move(debugOutput));
     }, *m_varProp);
 
   if (!res.ok()) {
-    ATH_MSG_ERROR("Got error during propagation: " 
+    ATH_MSG_ERROR("Got error during propagation: "
 		  << res.error() << " " << res.error().message()
                   << ". Returning empty step vector.");
     return {};
   }
-  std::tie(steps, debugOutput) = std::move(*res);
+  std::tie(output, debugOutput) = std::move(*res);
 
   if(debug) {
     ATH_MSG_VERBOSE(debugOutput.debugString);
   }
 
-  ATH_MSG_VERBOSE("Collected " << steps.size() << " steps");
-  if(steps.size() == 0) {
+  ATH_MSG_VERBOSE("Collected " << output.first.size() << " steps");
+  if(output.first.size() == 0) {
     ATH_MSG_WARNING("ZERO steps returned by stepper, that is not typically a good sign");
   }
 
   ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " end");
 
-  return steps;
+  return output;
 }
 
 
+
 std::unique_ptr<const Acts::CurvilinearParameters>
 ActsExtrapolationTool::propagate(const EventContext& ctx,
                                  const Acts::BoundParameters& startParameters,
@@ -195,7 +203,8 @@ ActsExtrapolationTool::propagate(const EventContext& ctx,
   auto anygctx = gctx.any();
 
   // Action list and abort list
-  using ActionList = Acts::ActionList<DebugOutput>;
+  using ActionList =
+  Acts::ActionList<Acts::MaterialInteractor, DebugOutput>;
   using AbortConditions = Acts::AbortList<EndOfWorld>;
   using Options = Acts::PropagatorOptions<ActionList, AbortConditions>;
 
@@ -210,8 +219,10 @@ ActsExtrapolationTool::propagate(const EventContext& ctx,
   options.maxStepSize = m_maxStepSize * 1_m;
   options.direction = navDir;
 
-  std::vector<Acts::detail::Step> steps;
-  DebugOutput::result_type debugOutput;
+  auto& mInteractor = options.actionList.get<Acts::MaterialInteractor>();
+  mInteractor.multipleScattering = m_interactionMultiScatering;
+  mInteractor.energyLoss = m_interactionEloss;
+  mInteractor.recordInteractions = m_interactionRecord;
 
   auto parameters = boost::apply_visitor([&](const auto& propagator) -> std::unique_ptr<const Acts::CurvilinearParameters> {
       auto result = propagator.propagate(startParameters, options);
@@ -222,16 +233,16 @@ ActsExtrapolationTool::propagate(const EventContext& ctx,
       }
       return std::move(result.value().endParameters);
     }, *m_varProp);
-  
+
   return parameters;
 }
-            
-std::vector<Acts::detail::Step>
+
+ActsPropagationOutput
 ActsExtrapolationTool::propagationSteps(const EventContext& ctx,
                                         const Acts::BoundParameters& startParameters,
                                         const Acts::Surface& target,
                                         Acts::NavigationDirection navDir /*= Acts::forward*/,
-                                        double pathLimit /*= std::numeric_limits<double>::max()*/) const 
+                                        double pathLimit /*= std::numeric_limits<double>::max()*/) const
 {
   using namespace Acts::UnitLiterals;
   ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " begin");
@@ -243,7 +254,8 @@ ActsExtrapolationTool::propagationSteps(const EventContext& ctx,
   auto anygctx = gctx.any();
 
   // Action list and abort list
-  using ActionList = Acts::ActionList<SteppingLogger, DebugOutput>;
+  using ActionList =
+  Acts::ActionList<SteppingLogger, Acts::MaterialInteractor, DebugOutput>;
   using AbortConditions = Acts::AbortList<EndOfWorld>;
   using Options = Acts::PropagatorOptions<ActionList, AbortConditions>;
 
@@ -258,7 +270,12 @@ ActsExtrapolationTool::propagationSteps(const EventContext& ctx,
   options.maxStepSize = m_maxStepSize * 1_m;
   options.direction = navDir;
 
-  std::vector<Acts::detail::Step> steps;
+  auto& mInteractor = options.actionList.get<Acts::MaterialInteractor>();
+  mInteractor.multipleScattering = m_interactionMultiScatering;
+  mInteractor.energyLoss = m_interactionEloss;
+  mInteractor.recordInteractions = m_interactionRecord;
+
+  ActsPropagationOutput output;
   DebugOutput::result_type debugOutput;
 
   auto res = boost::apply_visitor([&](const auto& propagator) -> ResultType {
@@ -270,8 +287,10 @@ ActsExtrapolationTool::propagationSteps(const EventContext& ctx,
 
       auto steppingResults = propRes.template get<SteppingLogger::result_type>();
       auto debugOutput = propRes.template get<DebugOutput::result_type>();
-      // try to force return value optimization, not sure this is necessary
-      return std::make_pair(std::move(steppingResults.steps), std::move(debugOutput));
+      auto materialResult = propRes.template get<Acts::MaterialInteractor::result_type>();
+      output.first = std::move(steppingResults.steps);
+      output.second = std::move(materialResult);
+      return std::make_pair(std::move(output), std::move(debugOutput));
     }, *m_varProp);
 
   if (!res.ok()) {
@@ -279,24 +298,24 @@ ActsExtrapolationTool::propagationSteps(const EventContext& ctx,
                   << ". Returning empty step vector.");
     return {};
   }
-  std::tie(steps, debugOutput) = std::move(*res);
+  std::tie(output, debugOutput) = std::move(*res);
 
   if(debug) {
     ATH_MSG_VERBOSE(debugOutput.debugString);
   }
 
-  ATH_MSG_VERBOSE("Collected " << steps.size() << " steps");
+  ATH_MSG_VERBOSE("Collected " << output.first.size() << " steps");
   ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " end");
 
-  return steps;  
+  return output;
 }
-            
+
 std::unique_ptr<const Acts::BoundParameters>
 ActsExtrapolationTool::propagate(const EventContext& ctx,
                                  const Acts::BoundParameters& startParameters,
                                  const Acts::Surface& target,
                                  Acts::NavigationDirection navDir /*= Acts::forward*/,
-                                 double pathLimit /*= std::numeric_limits<double>::max()*/) const 
+                                 double pathLimit /*= std::numeric_limits<double>::max()*/) const
 {
   using namespace Acts::UnitLiterals;
   ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " begin");
@@ -308,23 +327,26 @@ ActsExtrapolationTool::propagate(const EventContext& ctx,
   auto anygctx = gctx.any();
 
   // Action list and abort list
-  using ActionList = Acts::ActionList<DebugOutput>;
+  using ActionList =
+  Acts::ActionList<Acts::MaterialInteractor, DebugOutput>;
   using AbortConditions = Acts::AbortList<EndOfWorld>;
   using Options = Acts::PropagatorOptions<ActionList, AbortConditions>;
-  
+
   Options options(anygctx, mctx);
   options.pathLimit = pathLimit;
   bool debug = msg().level() == MSG::VERBOSE;
   options.debug = debug;
-  
+
   options.loopProtection
     = (Acts::VectorHelpers::perp(startParameters.momentum())
        < m_ptLoopers * 1_MeV);
   options.maxStepSize = m_maxStepSize * 1_m;
   options.direction = navDir;
 
-  std::vector<Acts::detail::Step> steps;
-  DebugOutput::result_type debugOutput;
+  auto& mInteractor = options.actionList.get<Acts::MaterialInteractor>();
+  mInteractor.multipleScattering = m_interactionMultiScatering;
+  mInteractor.energyLoss = m_interactionEloss;
+  mInteractor.recordInteractions = m_interactionRecord;
 
   auto parameters = boost::apply_visitor([&](const auto& propagator) -> std::unique_ptr<const Acts::BoundParameters> {
       auto result = propagator.propagate(startParameters, target, options);
@@ -335,6 +357,6 @@ ActsExtrapolationTool::propagate(const EventContext& ctx,
       }
       return std::move(result.value().endParameters);
     }, *m_varProp);
-  
-  return parameters;  
+
+  return parameters;
 }
diff --git a/Tracking/Acts/ActsGeometry/src/ActsMaterialJsonWriterTool.cxx b/Tracking/Acts/ActsGeometry/src/ActsMaterialJsonWriterTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b13694f69ac0b6c95fc8a4c37196315722870fc6
--- /dev/null
+++ b/Tracking/Acts/ActsGeometry/src/ActsMaterialJsonWriterTool.cxx
@@ -0,0 +1,52 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "ActsGeometry/ActsMaterialJsonWriterTool.h"
+
+#include <fstream>
+#include <ios>
+#include <iostream>
+#include <stdexcept>
+
+ActsMaterialJsonWriterTool::ActsMaterialJsonWriterTool(const std::string &type, const std::string &name,
+                                const IInterface *parent)
+  : base_class(type, name, parent)
+{
+}
+
+ActsMaterialJsonWriterTool::~ActsMaterialJsonWriterTool()
+{
+}
+
+StatusCode
+ActsMaterialJsonWriterTool::initialize()
+{
+  ATH_MSG_INFO("Starting Material writer");
+
+  return StatusCode::SUCCESS;
+}
+
+void
+ActsMaterialJsonWriterTool::write(const Acts::JsonGeometryConverter::DetectorMaterialMaps& detMaterial) const
+{
+  Acts::JsonGeometryConverter::Config cfg;
+  // Evoke the converter
+  Acts::JsonGeometryConverter jmConverter(cfg);
+  auto jout = jmConverter.materialMapsToJson(detMaterial);
+  // And write the file
+  std::ofstream ofj(m_filePath);
+  ofj << std::setw(4) << jout << std::endl;
+}
+
+void
+ActsMaterialJsonWriterTool::write(const Acts::TrackingGeometry& tGeometry) const
+{
+  Acts::JsonGeometryConverter::Config cfg;
+  // Evoke the converter
+  Acts::JsonGeometryConverter jmConverter(cfg);
+  auto jout = jmConverter.trackingGeometryToJson(tGeometry);
+  // And write the file
+  std::ofstream ofj(m_filePath);
+  ofj << std::setw(4) << jout << std::endl;
+}
diff --git a/Tracking/Acts/ActsGeometry/src/ActsMaterialMapping.cxx b/Tracking/Acts/ActsGeometry/src/ActsMaterialMapping.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..3efd705c4e61e6e64b3e091458bd745f2d52dfbb
--- /dev/null
+++ b/Tracking/Acts/ActsGeometry/src/ActsMaterialMapping.cxx
@@ -0,0 +1,107 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "ActsGeometry/ActsMaterialMapping.h"
+
+// ATHENA
+#include "Acts/Surfaces/PerigeeSurface.hpp"
+#include "Acts/Utilities/Logger.hpp"
+#include "ActsGeometry/IActsPropStepRootWriterSvc.h"
+#include "GaudiKernel/EventContext.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "MagFieldInterfaces/IMagFieldSvc.h"
+
+// ACTS
+#include "Acts/Propagator/detail/SteppingLogger.hpp"
+#include "Acts/Utilities/Helpers.hpp"
+#include "Acts/Utilities/Units.hpp"
+
+// PACKAGE
+#include "ActsInterop/Logger.h"
+#include "ActsGeometry/ActsGeometryContext.h"
+#include "ActsGeometryInterfaces/IActsMaterialJsonWriterTool.h"
+#include "ActsGeometryInterfaces/IActsMaterialStepConverterTool.h"
+#include "ActsGeometryInterfaces/IActsMaterialTrackWriterSvc.h"
+#include "ActsGeometryInterfaces/IActsTrackingGeometryTool.h"
+#include "ActsGeometryInterfaces/IActsSurfaceMappingTool.h"
+
+// STL
+#include <fstream>
+#include <string>
+
+//TEST
+#include "Acts/EventData/NeutralParameters.hpp"
+#include "Acts/Propagator/ActionList.hpp"
+#include "Acts/Propagator/DebugOutputActor.hpp"
+#include "Acts/Propagator/Navigator.hpp"
+#include "Acts/Propagator/Propagator.hpp"
+#include "Acts/Propagator/StandardAborters.hpp"
+#include "Acts/Propagator/StraightLineStepper.hpp"
+
+ActsMaterialMapping::ActsMaterialMapping(const std::string &name,
+                                           ISvcLocator *pSvcLocator)
+    : AthReentrantAlgorithm(name, pSvcLocator),
+      m_materialTrackWriterSvc("ActsMaterialTrackWriterSvc", name),
+      m_inputMaterialStepCollection("MaterialStepRecords"),
+      m_mappingState(m_gctx,m_mctx)
+{}
+
+StatusCode ActsMaterialMapping::initialize() {
+
+  ATH_MSG_DEBUG(name() << "::" << __FUNCTION__);
+
+  ATH_CHECK(m_materialStepConverterTool.retrieve() );
+  ATH_CHECK(m_materialTrackWriterSvc.retrieve() );
+  ATH_CHECK(m_surfaceMappingTool.retrieve() );
+  ATH_CHECK(m_materialJsonWriterTool.retrieve() );
+
+  ATH_CHECK( m_inputMaterialStepCollection.initialize() );
+
+  m_mappingState = m_surfaceMappingTool->mappingState();
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode ActsMaterialMapping::execute(const EventContext &ctx) const {
+
+  ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__);
+
+  m_surfaceMappingTool->trackingGeometryTool()->getGeometryContext(ctx);
+
+  Acts::RecordedMaterialTrack mTrack;
+
+  SG::ReadHandle<Trk::MaterialStepCollection> materialStepCollection(m_inputMaterialStepCollection, ctx);
+
+  mTrack = m_materialStepConverterTool->convertToMaterialTrack(*materialStepCollection);
+
+  m_materialTrackWriterSvc->write(mTrack);
+
+  auto mappingState
+        = const_cast<Acts::SurfaceMaterialMapper::State*>(&m_mappingState);
+
+
+  m_surfaceMappingTool->mapper()->mapMaterialTrack(*mappingState, mTrack);
+
+  ATH_MSG_VERBOSE(name() << " execute done");
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode ActsMaterialMapping::finalize() {
+
+  // Finalize all the maps using the cached state
+  m_surfaceMappingTool->mapper()->finalizeMaps(m_mappingState);
+
+  Acts::DetectorMaterialMaps detectorMaterial;
+
+  // Loop over the state, and collect the maps for surfaces
+  for (auto& [key, value] : m_mappingState.surfaceMaterial) {
+    detectorMaterial.first.insert({key, std::move(value)});
+  }
+
+  m_materialJsonWriterTool->write(detectorMaterial);
+
+  return StatusCode::SUCCESS;
+
+}
diff --git a/Tracking/Acts/ActsGeometry/src/ActsMaterialStepConverterTool.cxx b/Tracking/Acts/ActsGeometry/src/ActsMaterialStepConverterTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9d1c0703ad4c35317020cad8830c1da9463d97b2
--- /dev/null
+++ b/Tracking/Acts/ActsGeometry/src/ActsMaterialStepConverterTool.cxx
@@ -0,0 +1,84 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "ActsGeometry/ActsMaterialStepConverterTool.h"
+
+// ATHENA
+#include "GaudiKernel/EventContext.h"
+
+// PACKAGE
+#include "ActsGeometryInterfaces/IActsTrackingGeometrySvc.h"
+
+// Tracking
+#include "TrkGeometry/MaterialStep.h"
+
+// ACTS
+#include "Acts/Material/MaterialProperties.hpp"
+
+// STL
+#include <iostream>
+#include <memory>
+
+ActsMaterialStepConverterTool::ActsMaterialStepConverterTool(const std::string& type, const std::string& name,
+    const IInterface* parent)
+  : base_class(type, name, parent)
+{
+}
+
+StatusCode
+ActsMaterialStepConverterTool::initialize()
+{
+  ATH_MSG_INFO(name() << " initializing");
+
+  return StatusCode::SUCCESS;
+}
+
+
+const Acts::RecordedMaterialTrack
+ActsMaterialStepConverterTool::convertToMaterialTrack(const Trk::MaterialStepCollection &colStep) const
+{
+  Acts::RecordedMaterialTrack mTrack;
+  std::vector<Acts::MaterialInteraction> nStep;
+  Acts::RecordedMaterial recorded;
+  double sum_X0 = 0;
+  double sum_L0 = 0;
+
+  double x_lengh = colStep.back()->hitX() - colStep.front()->hitX();
+  double y_lengh = colStep.back()->hitY() - colStep.front()->hitY();
+  double z_lengh = colStep.back()->hitZ() - colStep.front()->hitZ();
+  double r_lengh = colStep.back()->hitR() - colStep.front()->hitR();
+
+  double norm = 1/(std::sqrt(x_lengh*x_lengh +
+                                 y_lengh*y_lengh +
+                                 z_lengh*z_lengh));
+
+
+  Acts::Vector3D v_pos{0, 0, colStep.front()->hitZ() - (z_lengh/r_lengh)*colStep.front()->hitR() };
+  // Acts::Vector3D v_pos{0, 0, 0};
+
+  Acts::Vector3D v_imp{x_lengh*norm, y_lengh*norm, z_lengh*norm};
+  // Acts::Vector3D v_imp{1, 0, 0};
+
+  for(auto const& step: colStep) {
+
+    Acts::MaterialInteraction interaction;
+
+    Acts::Vector3D pos{step->hitX(), step->hitY(), step->hitZ()};
+    Acts::MaterialProperties matProp(step->x0(), step->l0(), step->A(), step->Z(), step->rho(),step->steplength());
+    interaction.position = pos;
+    interaction.materialProperties = matProp;
+    sum_X0 += step->steplengthInX0();
+    sum_L0 += step->steplengthInL0();
+    nStep.push_back(interaction);
+  }
+
+  recorded.materialInX0 = sum_X0;
+  recorded.materialInL0 = sum_L0;
+  recorded.materialInteractions = nStep;
+
+  mTrack = std::make_pair(std::make_pair(v_pos, v_imp), recorded);
+
+return mTrack;
+
+}
diff --git a/Tracking/Acts/ActsGeometry/src/ActsMaterialTrackWriterSvc.cxx b/Tracking/Acts/ActsGeometry/src/ActsMaterialTrackWriterSvc.cxx
index c307ada289638de80a38e8b38a0602cf64c7a4d9..dd5b9ad679b3cb19b64ea336ec5df7975e5fc020 100644
--- a/Tracking/Acts/ActsGeometry/src/ActsMaterialTrackWriterSvc.cxx
+++ b/Tracking/Acts/ActsGeometry/src/ActsMaterialTrackWriterSvc.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "ActsGeometry/ActsMaterialTrackWriterSvc.h"
@@ -8,7 +8,6 @@
 #include "TTree.h"
 #include "TFile.h"
 
-#include "Acts/Plugins/MaterialMapping/MaterialTrack.hpp"
 #include "Acts/Material/MaterialProperties.hpp"
 #include "Acts/Utilities/Helpers.hpp"
 
@@ -33,30 +32,27 @@ ActsMaterialTrackWriterSvc::initialize()
   p_tFile->cd();
   p_tree = new TTree(treeName.c_str(), treeName.c_str());
 
-  p_tree->Branch("X0", &m_treeX0);
-  p_tree->Branch("L0", &m_treeL0);
-  p_tree->Branch("phi", &m_treePhi);
-  p_tree->Branch("theta", &m_treeTheta);
-  p_tree->Branch("T", &m_treeT);
-  p_tree->Branch("dInX0", &m_treedInX0);
-  p_tree->Branch("dInL0", &m_treedInL0);
-
-  p_tree->Branch("step_X0", &m_treeStepX0);
-  p_tree->Branch("step_L0", &m_treeStepL0);
-  p_tree->Branch("step_A", &m_treeStepA);
-  p_tree->Branch("step_Z", &m_treeStepZ);
-  p_tree->Branch("step_rho", &m_treeStepRho);
-  p_tree->Branch("step_t", &m_treeStepT);
-  p_tree->Branch("step_dInX0", &m_treeStepdInX0);
-  p_tree->Branch("step_dInL0", &m_treeStepdInL0);
-
-  p_tree->Branch("step_x", &m_treeStepPosX);
-  p_tree->Branch("step_y", &m_treeStepPosY);
-  p_tree->Branch("step_z", &m_treeStepPosZ);
-  p_tree->Branch("step_r", &m_treeStepPosR);
-  p_tree->Branch("step_phi", &m_treeStepPosPhi);
-
-  p_tree->Branch("step_geo_id", &m_treeStepGeoID);
+  p_tree->Branch("v_x", &m_v_x);
+  p_tree->Branch("v_y", &m_v_y);
+  p_tree->Branch("v_z", &m_v_z);
+  p_tree->Branch("v_px", &m_v_px);
+  p_tree->Branch("v_py", &m_v_py);
+  p_tree->Branch("v_pz", &m_v_pz);
+  p_tree->Branch("v_phi", &m_v_phi);
+  p_tree->Branch("v_eta", &m_v_eta);
+
+  p_tree->Branch("t_X0", &m_tX0);
+  p_tree->Branch("t_L0", &m_tL0);
+
+  p_tree->Branch("mat_x", &m_step_x);
+  p_tree->Branch("mat_y", &m_step_y);
+  p_tree->Branch("mat_z", &m_step_z);
+  p_tree->Branch("mat_step_length", &m_step_length);
+  p_tree->Branch("mat_X0", &m_step_X0);
+  p_tree->Branch("mat_L0", &m_step_L0);
+  p_tree->Branch("mat_A", &m_step_A);
+  p_tree->Branch("mat_Z", &m_step_Z);
+  p_tree->Branch("mat_rho", &m_step_rho);
 
   ATH_MSG_INFO("Starting writer thread");
   ATH_MSG_DEBUG("Maximum queue size is set to:" << m_maxQueueSize);
@@ -65,8 +61,8 @@ ActsMaterialTrackWriterSvc::initialize()
 
   return StatusCode::SUCCESS;
 }
-  
-StatusCode 
+
+StatusCode
 ActsMaterialTrackWriterSvc::finalize()
 {
 
@@ -74,20 +70,20 @@ ActsMaterialTrackWriterSvc::finalize()
   m_doEnd = true;
   m_writeThread.join();
   ATH_MSG_INFO("Writer thread has terminated.");
-  
+
   ATH_MSG_INFO("Closing TFile");
   p_tFile->cd();
   p_tree->FlushBaskets();
   p_tree->AutoSave();
   p_tree->Write();
-  //p_tFile->Write()
+  p_tFile->Write();
   p_tFile->Close();
 
   return StatusCode::SUCCESS;
 }
 
-void 
-ActsMaterialTrackWriterSvc::write(const Acts::MaterialTrack& mTrack)
+void
+ActsMaterialTrackWriterSvc::write(const Acts::RecordedMaterialTrack& mTrack)
 {
   std::lock_guard<std::mutex> lock(m_writeMutex);
 
@@ -109,7 +105,7 @@ ActsMaterialTrackWriterSvc::writerThread()
   while(true) {
     ATH_MSG_VERBOSE("Obtaining write lock");
     std::unique_lock<std::mutex> lock(m_writeMutex);
-    
+
     if (m_mTracks.empty()) {
       lock.unlock();
       if (!m_doEnd) {
@@ -124,111 +120,115 @@ ActsMaterialTrackWriterSvc::writerThread()
     }
 
 
-    //if(m_mTracks.size() < m_maxQueueSize) {
+    if(m_mTracks.size() < m_maxQueueSize) {
       // just pop one
-      ATH_MSG_VERBOSE("Queue at " << m_mTracks.size() << "/" << m_maxQueueSize 
+      ATH_MSG_VERBOSE("Queue at " << m_mTracks.size() << "/" << m_maxQueueSize
           << ": Pop entry and write");
-      Acts::MaterialTrack mTrack = std::move(m_mTracks.front());
+      Acts::RecordedMaterialTrack mTrack = std::move(m_mTracks.front());
       m_mTracks.pop_front();
       // writing can now happen without lock
       lock.unlock();
       doWrite(std::move(mTrack));
-    //}
-    //else {
-      //ATH_MSG_DEBUG("Queue at " << m_mTracks.size() << "/" << m_maxQueueSize 
-          //<< ": Lock and write until empty");
-      //while(!m_mTracks.empty()) {
-        //ATH_MSG_VERBOSE("Pop entry and write");
-        //// keep the lock!
-        //MaterialTrack mTrack = std::move(m_mTracks.front());
-        //m_mTracks.pop_front();
-        //doWrite(std::move(mTrack));
-      //}
-      //ATH_MSG_DEBUG("Queue is empty, continue");
-
-    //}
-
+    }
+    else {
+      ATH_MSG_DEBUG("Queue at " << m_mTracks.size() << "/" << m_maxQueueSize
+          << ": Lock and write until empty");
+      while(!m_mTracks.empty()) {
+        ATH_MSG_VERBOSE("Pop entry and write");
+        // keep the lock!
+        Acts::RecordedMaterialTrack mTrack = std::move(m_mTracks.front());
+        m_mTracks.pop_front();
+        doWrite(std::move(mTrack));
+      }
+      ATH_MSG_DEBUG("Queue is empty, continue");
 
+    }
   }
 }
 
 void
-ActsMaterialTrackWriterSvc::doWrite(const Acts::MaterialTrack& mTrack)
+ActsMaterialTrackWriterSvc::doWrite(const Acts::RecordedMaterialTrack& mTrack)
 {
   ATH_MSG_VERBOSE("Write to tree");
-  size_t nSteps = mTrack.materialSteps().size();
-  //m_treeStepPos.clear();
-  //m_treeStepPos.reserve(nSteps);
-  m_treeStepX0.clear();
-  m_treeStepX0.reserve(nSteps);
-  m_treeStepL0.clear();
-  m_treeStepL0.reserve(nSteps);
-  m_treeStepA.clear();
-  m_treeStepA.reserve(nSteps);
-  m_treeStepZ.clear();
-  m_treeStepZ.reserve(nSteps);
-  m_treeStepRho.clear();
-  m_treeStepRho.reserve(nSteps);
-  m_treeStepT.clear();
-  m_treeStepT.reserve(nSteps);
-  m_treeStepdInX0.clear();
-  m_treeStepdInX0.reserve(nSteps);
-  m_treeStepdInL0.clear();
-  m_treeStepdInL0.reserve(nSteps);
-
-  m_treeStepPosX.clear();
-  m_treeStepPosX.reserve(nSteps);
-  m_treeStepPosY.clear();
-  m_treeStepPosY.reserve(nSteps);
-  m_treeStepPosZ.clear();
-  m_treeStepPosZ.reserve(nSteps);
-  m_treeStepPosR.clear();
-  m_treeStepPosR.reserve(nSteps);
-  m_treeStepPosPhi.clear();
-  m_treeStepPosPhi.reserve(nSteps);
-
-  m_treeStepGeoID.clear();
-  m_treeStepGeoID.reserve(nSteps);
-
-
-  m_treeX0 = mTrack.thicknessInX0(); // name?
-  m_treeL0 = mTrack.thicknessInL0(); // name?
-  m_treeTheta = mTrack.theta();
-  m_treePhi = mTrack.phi();
-  m_treeT = 0;
-  m_treedInX0 = 0;
-  m_treedInL0 = 0;
-
-  for(const auto& step : mTrack.materialSteps()) {
-    const Acts::MaterialProperties& matProp = step.materialProperties();
-    const Acts::Material& mat = matProp.material();
-    const Acts::Vector3D pos = step.position();
-
-    m_treeStepPosX.push_back(pos.x());
-    m_treeStepPosY.push_back(pos.y());
-    m_treeStepPosZ.push_back(pos.z());
-    m_treeStepPosR.push_back(perp(pos));
-    m_treeStepPosPhi.push_back(phi(pos));
-
-    m_treeStepX0.push_back(mat.X0());
-    m_treeStepL0.push_back(mat.L0());
-    m_treeStepA.push_back(mat.A());
-    m_treeStepZ.push_back(mat.Z());
-    m_treeStepRho.push_back(mat.rho());
-    m_treeStepT.push_back(matProp.thickness());
-    m_treeStepdInX0.push_back(matProp.thicknessInX0());
-    m_treeStepdInX0.push_back(matProp.thicknessInL0());
-
-    m_treeT += matProp.thickness();
-    m_treedInX0 += matProp.thicknessInX0();
-    m_treedInL0 += matProp.thicknessInL0();
-
-    m_treeStepGeoID.push_back(step.geoID());
+  size_t mints = mTrack.second.materialInteractions.size();
+
+  // Clearing the vector first
+  m_step_sx.clear();
+  m_step_sy.clear();
+  m_step_sz.clear();
+  m_step_x.clear();
+  m_step_y.clear();
+  m_step_z.clear();
+  m_step_ex.clear();
+  m_step_ey.clear();
+  m_step_ez.clear();
+  m_step_length.clear();
+  m_step_X0.clear();
+  m_step_L0.clear();
+  m_step_A.clear();
+  m_step_Z.clear();
+  m_step_rho.clear();
+
+  // Reserve the vector then
+  m_step_sx.reserve(mints);
+  m_step_sy.reserve(mints);
+  m_step_sz.reserve(mints);
+  m_step_x.reserve(mints);
+  m_step_y.reserve(mints);
+  m_step_ez.reserve(mints);
+  m_step_ex.reserve(mints);
+  m_step_ey.reserve(mints);
+  m_step_ez.reserve(mints);
+  m_step_length.reserve(mints);
+  m_step_X0.reserve(mints);
+  m_step_L0.reserve(mints);
+  m_step_A.reserve(mints);
+  m_step_Z.reserve(mints);
+  m_step_rho.reserve(mints);
+
+
+  // reset the global counter
+  m_tX0 = mTrack.second.materialInX0;
+  m_tL0 = mTrack.second.materialInL0;
+
+  // set the track information at vertex
+  m_v_x   = mTrack.first.first.x();
+  m_v_y   = mTrack.first.first.y();
+  m_v_z   = mTrack.first.first.z();
+  m_v_px  = mTrack.first.second.x();
+  m_v_py  = mTrack.first.second.y();
+  m_v_pz  = mTrack.first.second.z();
+  m_v_phi = phi(mTrack.first.second);
+  m_v_eta = eta(mTrack.first.second);
+
+  // an now loop over the material
+  for (auto& mint : mTrack.second.materialInteractions) {
+    // The material step position information
+    m_step_x.push_back(mint.position.x());
+    m_step_y.push_back(mint.position.y());
+    m_step_z.push_back(mint.position.z());
+
+      Acts::Vector3D prePos
+          = mint.position - 0.5 * mint.pathCorrection * mint.direction;
+      Acts::Vector3D posPos
+          = mint.position + 0.5 * mint.pathCorrection * mint.direction;
+      m_step_sx.push_back(prePos.x());
+      m_step_sy.push_back(prePos.y());
+      m_step_sz.push_back(prePos.z());
+      m_step_ex.push_back(posPos.x());
+      m_step_ey.push_back(posPos.y());
+      m_step_ez.push_back(posPos.z());
+
+    // the material information
+    const auto& mprops = mint.materialProperties;
+    m_step_length.push_back(mprops.thickness());
+    m_step_X0.push_back(mprops.material().X0());
+    m_step_L0.push_back(mprops.material().L0());
+    m_step_A.push_back(mprops.material().Ar());
+    m_step_Z.push_back(mprops.material().Z());
+    m_step_rho.push_back(mprops.material().massDensity());
 
   }
-
   p_tree->Fill();
-  //m_treeTTot = 0;
-
   ATH_MSG_VERBOSE("Write complete");
 }
diff --git a/Tracking/Acts/ActsGeometry/src/ActsObjWriterTool.cxx b/Tracking/Acts/ActsGeometry/src/ActsObjWriterTool.cxx
index 21c97a0b5cc135f1e4f69dd6816868bd9a7ee9ac..b9165d762733d775a9357757181ae030120e1917 100644
--- a/Tracking/Acts/ActsGeometry/src/ActsObjWriterTool.cxx
+++ b/Tracking/Acts/ActsGeometry/src/ActsObjWriterTool.cxx
@@ -24,8 +24,8 @@ ActsObjWriterTool::ActsObjWriterTool(const std::string& type, const std::string&
     const IInterface* parent)
   : AthAlgTool(type, name, parent)
 {
-  //declareProperty("OutputDirectory", m_outputDirectory = "");
-  //declareProperty("SubDetectors", m_subDetectors = {});
+  // declareProperty("OutputDirectory", m_outputDirectory = "");
+  // declareProperty("SubDetectors", m_subDetectors = {});
 }
 
 StatusCode
@@ -38,8 +38,7 @@ ActsObjWriterTool::initialize()
 
 void
 ActsObjWriterTool::write(const ActsGeometryContext& gctx, const Acts::TrackingGeometry& tg) const
-{
-
+{ 
   const auto& ctx = Gaudi::Hive::currentContext();
   std::stringstream ss;
   ss << ctx.eventID().run_number() << "_" << ctx.eventID().event_number();
diff --git a/Tracking/Acts/ActsGeometry/src/ActsSurfaceMappingTool.cxx b/Tracking/Acts/ActsGeometry/src/ActsSurfaceMappingTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ce6e4327358d5bbb5fe371612fd2e684ef69e248
--- /dev/null
+++ b/Tracking/Acts/ActsGeometry/src/ActsSurfaceMappingTool.cxx
@@ -0,0 +1,69 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "ActsGeometry/ActsSurfaceMappingTool.h"
+
+// ATHENA
+#include "GaudiKernel/IInterface.h"
+#include "MagFieldInterfaces/IMagFieldSvc.h"
+
+// PACKAGE
+#include "ActsInterop/Logger.h"
+#include "ActsGeometry/ActsGeometryContext.h"
+#include "ActsGeometry/ActsTrackingGeometryTool.h"
+#include "ActsGeometryInterfaces/IActsTrackingGeometryTool.h"
+
+// ActsSurfaceMappingTool
+#include "Acts/Geometry/GeometryContext.hpp"
+#include "Acts/Propagator/Navigator.hpp"
+#include "Acts/Propagator/Propagator.hpp"
+#include "Acts/Propagator/StraightLineStepper.hpp"
+
+// STL
+#include <iostream>
+#include <memory>
+
+
+ActsSurfaceMappingTool::ActsSurfaceMappingTool(const std::string& type, const std::string& name,
+    const IInterface* parent)
+  : base_class(type, name, parent)
+{
+}
+
+StatusCode
+ActsSurfaceMappingTool::initialize()
+{
+  ATH_MSG_INFO("Initializing ACTS Surface Mapper");
+
+  ATH_CHECK( m_trackingGeometryTool.retrieve() );
+
+  m_trackingGeometry = m_trackingGeometryTool->trackingGeometry();
+
+  Acts::Navigator navigator(m_trackingGeometry);
+  // Make stepper and propagator
+  SlStepper stepper;
+  StraightLinePropagator propagator = StraightLinePropagator(std::move(stepper), std::move(navigator));
+
+  /// The material mapper
+  Acts::SurfaceMaterialMapper::Config smmConfig;
+  smmConfig.mapperDebugOutput = true;
+  m_mapper = std::make_shared<Acts::SurfaceMaterialMapper>(
+      smmConfig,
+      std::move(propagator),
+      Acts::getDefaultLogger("SurfaceMaterialMapper", Acts::Logging::INFO));
+
+  m_geoContext = m_trackingGeometryTool->getNominalGeometryContext().any();
+
+  ATH_MSG_INFO("ACTS Surface Mapper successfully initialized");
+  return StatusCode::SUCCESS;
+}
+
+Acts::SurfaceMaterialMapper::State
+ActsSurfaceMappingTool::mappingState() const
+{
+  auto mappingState = m_mapper->createState(
+    m_geoContext, m_magFieldContext, *m_trackingGeometry);
+
+  return mappingState;
+}
diff --git a/Tracking/Acts/ActsGeometry/src/ActsTrackingGeometryTool.cxx b/Tracking/Acts/ActsGeometry/src/ActsTrackingGeometryTool.cxx
index 76cb9dad074fcdee9f35dada7ca50faa11e43be7..49717d0da5f5dcc2d0e9f9543803a0ad42166696 100644
--- a/Tracking/Acts/ActsGeometry/src/ActsTrackingGeometryTool.cxx
+++ b/Tracking/Acts/ActsGeometry/src/ActsTrackingGeometryTool.cxx
@@ -16,7 +16,7 @@
 #include <memory>
 
 ActsTrackingGeometryTool::ActsTrackingGeometryTool(const std::string& type, const std::string& name,
-    const IInterface* parent) 
+    const IInterface* parent)
   : base_class(type, name, parent),
     m_trackingGeometrySvc("ActsTrackingGeometrySvc", name)
 {
diff --git a/Tracking/Acts/ActsGeometry/src/ActsVolumeMappingTool.cxx b/Tracking/Acts/ActsGeometry/src/ActsVolumeMappingTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..627bc1cfdf82a5a0a94f7bc8a32c5728e175e2f3
--- /dev/null
+++ b/Tracking/Acts/ActsGeometry/src/ActsVolumeMappingTool.cxx
@@ -0,0 +1,70 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "ActsGeometry/ActsVolumeMappingTool.h"
+
+// ATHENA
+#include "GaudiKernel/IInterface.h"
+#include "MagFieldInterfaces/IMagFieldSvc.h"
+
+// PACKAGE
+#include "ActsGeometry/ActsGeometryContext.h"
+#include "ActsInterop/Logger.h"
+#include "ActsGeometry/ActsTrackingGeometryTool.h"
+#include "ActsGeometry/ActsGeometryContext.h"
+#include "ActsGeometryInterfaces/IActsTrackingGeometryTool.h"
+
+// ACTS
+#include "Acts/Propagator/Navigator.hpp"
+#include "Acts/Propagator/Propagator.hpp"
+#include "Acts/Propagator/StraightLineStepper.hpp"
+#include "Acts/Geometry/GeometryContext.hpp"
+
+// STL
+#include <iostream>
+#include <memory>
+
+
+ActsVolumeMappingTool::ActsVolumeMappingTool(const std::string& type, const std::string& name,
+    const IInterface* parent)
+  : base_class(type, name, parent)
+{
+}
+
+StatusCode
+ActsVolumeMappingTool::initialize()
+{
+  ATH_MSG_INFO("Initializing ACTS Volume Mapper");
+
+  ATH_CHECK( m_trackingGeometryTool.retrieve() );
+
+  m_trackingGeometry = m_trackingGeometryTool->trackingGeometry();
+
+  Acts::Navigator navigator(m_trackingGeometry);
+  // Make stepper and propagator
+  SlStepper stepper;
+  StraightLinePropagator propagator = StraightLinePropagator(std::move(stepper), std::move(navigator));
+
+  /// The material mapper
+  Acts::VolumeMaterialMapper::Config smmConfig;
+  smmConfig.mapperDebugOutput = true;
+  m_mapper = std::make_shared<Acts::VolumeMaterialMapper>(
+      smmConfig,
+      std::move(propagator),
+      Acts::getDefaultLogger("VolumeMaterialMapper", Acts::Logging::INFO));
+
+  m_geoContext = m_trackingGeometryTool->getNominalGeometryContext().any();
+
+  ATH_MSG_INFO("ACTS Surface Mapper successfully initialized");
+  return StatusCode::SUCCESS;
+}
+
+Acts::VolumeMaterialMapper::State
+ActsVolumeMappingTool::mappingState() const
+{
+  auto mappingState = m_mapper->createState(
+    m_geoContext, m_magFieldContext, *m_trackingGeometry);
+
+  return mappingState;
+}
diff --git a/Tracking/Acts/ActsGeometry/src/ActsWriteTrackingGeometry.cxx b/Tracking/Acts/ActsGeometry/src/ActsWriteTrackingGeometry.cxx
index 30ee723e10ffd7a2a87102f39644fbf9a07909fa..59d221239de58eb7b61ef32e9994aaaed867439e 100755
--- a/Tracking/Acts/ActsGeometry/src/ActsWriteTrackingGeometry.cxx
+++ b/Tracking/Acts/ActsGeometry/src/ActsWriteTrackingGeometry.cxx
@@ -12,6 +12,7 @@
 
 // PACKAGE
 #include "ActsGeometryInterfaces/IActsTrackingGeometrySvc.h"
+#include "ActsGeometryInterfaces/IActsMaterialJsonWriterTool.h"
 #include "ActsGeometry/ActsGeometryContext.h"
 
 // STL
@@ -28,7 +29,7 @@ StatusCode ActsWriteTrackingGeometry::initialize() {
 
   ATH_CHECK(m_objWriterTool.retrieve());
   ATH_CHECK(m_trackingGeometryTool.retrieve());
-
+  ATH_CHECK(m_materialJsonWriterTool.retrieve() );
 
 
   return StatusCode::SUCCESS;
@@ -42,6 +43,7 @@ StatusCode ActsWriteTrackingGeometry::execute(const EventContext& ctx) const {
   const ActsGeometryContext& gctx = m_trackingGeometryTool->getGeometryContext(ctx);
 
   m_objWriterTool->write(gctx, *trackingGeometry);
+  m_materialJsonWriterTool->write(*trackingGeometry);
   return StatusCode::SUCCESS;
 }
 
diff --git a/Tracking/Acts/ActsGeometry/src/components/ActsGeometry_entries.cxx b/Tracking/Acts/ActsGeometry/src/components/ActsGeometry_entries.cxx
index 5c7f1a4f204aa5c6fe4277fc8e83b894febbba1f..311f5dfe30a87475d7db65a09f2266b8f930d1f9 100755
--- a/Tracking/Acts/ActsGeometry/src/components/ActsGeometry_entries.cxx
+++ b/Tracking/Acts/ActsGeometry/src/components/ActsGeometry_entries.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "ActsGeometry/ActsExtrapolationAlg.h"
@@ -7,9 +7,13 @@
 #include "ActsGeometry/ActsWriteTrackingGeometryTransforms.h"
 #include "ActsGeometry/ActsTrackingGeometrySvc.h"
 #include "ActsGeometry/ActsExtrapolationTool.h"
+
+#include "ActsGeometry/ActsMaterialMapping.h"
+#include "ActsGeometry/ActsSurfaceMappingTool.h"
+// #include "ActsGeometry/ActsVolumeMappingTool.h"
 #include "ActsGeometry/ActsObjWriterTool.h"
 //#include "ActsGeometry/ActsExCellWriterSvc.h"
-//#include "ActsGeometry/ActsMaterialTrackWriterSvc.h"
+#include "ActsGeometry/ActsMaterialTrackWriterSvc.h"
 
 //#include "ActsGeometry/GeomShiftCondAlg.h"
 #include "ActsGeometry/NominalAlignmentCondAlg.h"
@@ -18,15 +22,23 @@
 
 #include "ActsGeometry/ActsPropStepRootWriterSvc.h"
 #include "ActsGeometry/ActsCaloTrackingVolumeBuilder.h"
+#include "ActsGeometry/ActsMaterialStepConverterTool.h"
+#include "ActsGeometry/ActsMaterialJsonWriterTool.h"
 
 DECLARE_COMPONENT( ActsExtrapolationAlg )
 DECLARE_COMPONENT( ActsWriteTrackingGeometry )
 DECLARE_COMPONENT( ActsWriteTrackingGeometryTransforms )
 DECLARE_COMPONENT( ActsTrackingGeometrySvc )
 DECLARE_COMPONENT( ActsExtrapolationTool )
+
+DECLARE_COMPONENT( ActsMaterialMapping )
+DECLARE_COMPONENT( ActsSurfaceMappingTool )
+// DECLARE_COMPONENT( ActsVolumeMappingTool )
 DECLARE_COMPONENT( ActsObjWriterTool )
 //DECLARE_COMPONENT( ActsExCellWriterSvc )
-//DECLARE_COMPONENT( ActsMaterialTrackWriterSvc )
+DECLARE_COMPONENT( ActsMaterialTrackWriterSvc )
+DECLARE_COMPONENT( ActsMaterialStepConverterTool )
+DECLARE_COMPONENT( ActsMaterialJsonWriterTool )
 
 //DECLARE_COMPONENT( GeomShiftCondAlg )
 DECLARE_COMPONENT( NominalAlignmentCondAlg )
diff --git a/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsExtrapolationTool.h b/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsExtrapolationTool.h
index 03ecfe769983bd51d4b3327db61b98c2b92661a2..380aa667da03ab1e3af50ec604946092a5ff5f08 100644
--- a/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsExtrapolationTool.h
+++ b/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsExtrapolationTool.h
@@ -11,12 +11,16 @@
 #include "GaudiKernel/EventContext.h"
 #include "ActsGeometry/ActsGeometryContext.h"
 
+#include "Acts/Propagator/MaterialInteractor.hpp"
 #include "Acts/Propagator/detail/SteppingLogger.hpp"
 #include "Acts/EventData/TrackParameters.hpp"
 
-namespace Acts {
-  class TrackingGeometry;
-}
+/// Using some short hands for Recorded Material
+using ActsRecordedMaterial = Acts::MaterialInteractor::result_type;
+/// Finally the output of the propagation test
+using ActsPropagationOutput =
+        std::pair<std::vector<Acts::detail::Step>, ActsRecordedMaterial>;
+
 
 class IActsTrackingGeometryTool;
 
@@ -27,27 +31,27 @@ class IActsExtrapolationTool : virtual public IAlgTool {
   DeclareInterfaceID(IActsExtrapolationTool, 1, 0);
 
   virtual
-  std::vector<Acts::detail::Step>
+  ActsPropagationOutput
   propagationSteps(const EventContext& ctx,
                    const Acts::BoundParameters& startParameters,
                    Acts::NavigationDirection navDir = Acts::forward,
                    double pathLimit = std::numeric_limits<double>::max()) const = 0;
-                   
+
   virtual
   std::unique_ptr<const Acts::CurvilinearParameters>
   propagate(const EventContext& ctx,
             const Acts::BoundParameters& startParameters,
             Acts::NavigationDirection navDir = Acts::forward,
             double pathLimit = std::numeric_limits<double>::max()) const = 0;
-            
+
   virtual
-  std::vector<Acts::detail::Step>
+  ActsPropagationOutput
   propagationSteps(const EventContext& ctx,
                    const Acts::BoundParameters& startParameters,
                    const Acts::Surface& target,
                    Acts::NavigationDirection navDir = Acts::forward,
                    double pathLimit = std::numeric_limits<double>::max()) const = 0;
-            
+
   virtual
   std::unique_ptr<const Acts::BoundParameters>
   propagate(const EventContext& ctx,
diff --git a/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsMaterialJsonWriterTool.h b/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsMaterialJsonWriterTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..b18d4e56a7a780af10af55e7d7c51703bb95477b
--- /dev/null
+++ b/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsMaterialJsonWriterTool.h
@@ -0,0 +1,34 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ACTSGEOMETRY_IACTSMATERIALJSONWRITERTOOL_H
+#define ACTSGEOMETRY_IACTSMATERIALJSONWRITERTOOL_H
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/IInterface.h"
+#include "GaudiKernel/IAlgTool.h"
+
+#include "Acts/Plugins/Json/JsonGeometryConverter.hpp"
+
+namespace Acts {
+  class TrackingGeometry;
+}
+
+class IActsMaterialJsonWriterTool : virtual public IAlgTool {
+public:
+
+  DeclareInterfaceID(IActsMaterialJsonWriterTool, 1, 0);
+
+  virtual
+  void
+  write(const Acts::JsonGeometryConverter::DetectorMaterialMaps& detMaterial) const = 0;
+
+  virtual
+  void
+  write(const Acts::TrackingGeometry& tGeometry) const = 0;
+
+};
+
+
+#endif
diff --git a/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsMaterialStepConverterTool.h b/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsMaterialStepConverterTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..e42a4c3b218f9a925c6a61d54f9cec92c246a073
--- /dev/null
+++ b/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsMaterialStepConverterTool.h
@@ -0,0 +1,23 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ACTSGEOMETRYINTERFACES_IACTSMATERIALSTEPCONVERTERTOOL_H
+#define ACTSGEOMETRYINTERFACES_IACTSMATERIALSTEPCONVERTERTOOL_H
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/IInterface.h"
+#include "Acts/Propagator/MaterialInteractor.hpp"
+#include "TrkGeometry/MaterialStepCollection.h"
+
+class IActsMaterialStepConverterTool : virtual public IAlgTool {
+  public:
+
+  DeclareInterfaceID(IActsMaterialStepConverterTool, 1, 0);
+
+  virtual
+  const Acts::RecordedMaterialTrack
+  convertToMaterialTrack(const Trk::MaterialStepCollection &colStep) const = 0;
+};
+
+#endif
diff --git a/Tracking/Acts/ActsGeometry/ActsGeometry/IActsMaterialTrackWriterSvc.h b/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsMaterialTrackWriterSvc.h
similarity index 68%
rename from Tracking/Acts/ActsGeometry/ActsGeometry/IActsMaterialTrackWriterSvc.h
rename to Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsMaterialTrackWriterSvc.h
index 8f3804142e7656afd9b17835078149bc659a1f8f..d7453618305823adcdc2b8cd1832f2955392f060 100644
--- a/Tracking/Acts/ActsGeometry/ActsGeometry/IActsMaterialTrackWriterSvc.h
+++ b/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsMaterialTrackWriterSvc.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef ACTSGEOMETRY_IACTSMATERIALTRACKWRITERSVC_H
@@ -8,21 +8,19 @@
 #include "GaudiKernel/IInterface.h"
 #include "Acts/EventData/TrackParameters.hpp"
 
-namespace Acts {
-class MaterialTrack;
-}
+#include "Acts/Propagator/MaterialInteractor.hpp"
 
 class IActsMaterialTrackWriterSvc : virtual public IInterface {
 public:
-    
+
   DeclareInterfaceID(IActsMaterialTrackWriterSvc, 1, 0);
 
   IActsMaterialTrackWriterSvc() {;}
-    
+
   void
   virtual
-  write(const Acts::MaterialTrack& mTrack) = 0;
+  write(const Acts::RecordedMaterialTrack& mTrack) = 0;
 
 };
 
-#endif 
+#endif
diff --git a/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsSurfaceMappingTool.h b/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsSurfaceMappingTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..e0c5e7cbe13c9ee4ca3859bb1843310cd95096bc
--- /dev/null
+++ b/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsSurfaceMappingTool.h
@@ -0,0 +1,37 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ACTSGEOMETRYINTERFACES_IACTSSURFACEMAPPINGTOOL_H
+#define ACTSGEOMETRYINTERFACES_IACTSSURFACEMAPPINGTOOL_H
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/IInterface.h"
+#include "GaudiKernel/IAlgTool.h"
+#include "GaudiKernel/EventContext.h"
+
+#include "Acts/Material/SurfaceMaterialMapper.hpp"
+
+class IActsTrackingGeometryTool;
+
+class IActsSurfaceMappingTool : virtual public IAlgTool {
+  public:
+
+  DeclareInterfaceID(IActsSurfaceMappingTool, 1, 0);
+
+
+  virtual
+  std::shared_ptr<Acts::SurfaceMaterialMapper>
+  mapper() const = 0;
+
+  virtual
+  Acts::SurfaceMaterialMapper::State
+  mappingState() const = 0;
+
+  virtual
+  const IActsTrackingGeometryTool*
+  trackingGeometryTool() const = 0;
+
+};
+
+#endif
diff --git a/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsVolumeMappingTool.h b/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsVolumeMappingTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..cedc321f3388fcb3535c684cffcefd16afe1c9c5
--- /dev/null
+++ b/Tracking/Acts/ActsGeometryInterfaces/ActsGeometryInterfaces/IActsVolumeMappingTool.h
@@ -0,0 +1,37 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ACTSGEOMETRYINTERFACES_IACTSVOLUMEMAPPINGTOOL_H
+#define ACTSGEOMETRYINTERFACES_IACTSVOLUMEMAPPINGTOOL_H
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/IInterface.h"
+#include "GaudiKernel/IAlgTool.h"
+#include "GaudiKernel/EventContext.h"
+
+#include "Acts/Material/VolumeMaterialMapper.hpp"
+
+class IActsTrackingGeometryTool;
+
+class IActsVolumeMappingTool : virtual public IAlgTool {
+  public:
+
+  DeclareInterfaceID(IActsVolumeMappingTool, 1, 0);
+
+
+  virtual
+  std::shared_ptr<Acts::VolumeMaterialMapper>
+  mapper() const = 0;
+
+  virtual
+  Acts::VolumeMaterialMapper::State
+  mappingState() const = 0;
+
+  virtual
+  const IActsTrackingGeometryTool*
+  trackingGeometryTool() const = 0;
+
+};
+
+#endif
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/CMakeLists.txt b/Tracking/TrkConditions/TrackingGeometryCondAlg/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fcae79acc8299bfd740f93630427bf644195dd7a
--- /dev/null
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/CMakeLists.txt
@@ -0,0 +1,40 @@
+################################################################################
+# Package: TrackingGeometryCondAlg
+################################################################################
+
+# Declare the package name:
+atlas_subdir( TrackingGeometryCondAlg )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs(
+   PUBLIC
+   Control/AthenaBaseComps
+   Control/AthenaKernel
+   GaudiKernel
+   Tracking/TrkDetDescr/TrkDetDescrInterfaces
+   Tracking/TrkDetDescr/TrkDetDescrUtils
+   Tracking/TrkDetDescr/TrkGeometry
+   InnerDetector/InDetDetDescr/InDetReadoutGeometry
+   PRIVATE
+    )
+
+find_package( Eigen )
+
+# Component(s) in the package:
+
+atlas_add_component( TrackingGeometryCondAlg
+   TrackingGeometryCondAlg/*.h src/*.cxx src/components/*.cxx
+   INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS}
+   LINK_LIBRARIES ${EIGEN_LIBRARIES} 
+   AthenaBaseComps
+   AthenaKernel
+   GaudiKernel 
+   TrkDetDescrInterfaces
+   TrkDetDescrUtils
+   TrkGeometry
+   InDetReadoutGeometry
+    )
+
+# Install files from the package:
+atlas_install_python_modules( python/*.py )
+
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h b/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..b450935f4c7e44746af3f27e33d0e07c9a53355b
--- /dev/null
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h
@@ -0,0 +1,45 @@
+/*
+ *   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#ifndef TRACKINGGEOMETRYCONDALG_H
+#define TRACKINGGEOMETRYCONDALG_H
+
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "PersistentDataModel/AthenaAttributeList.h"
+#include "StoreGate/ReadCondHandleKey.h"
+#include "StoreGate/WriteCondHandleKey.h"
+
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrInterfaces/IGeometryProcessor.h"
+#include "InDetReadoutGeometry/SiDetectorElementCollection.h"
+
+#include "GaudiKernel/ICondSvc.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "AthenaKernel/CLASS_DEF.h"
+
+namespace Trk{
+class TrackingGeometryCondAlg : public AthReentrantAlgorithm
+{
+public:
+  TrackingGeometryCondAlg(const std::string& name, ISvcLocator* pSvcLocator);
+  virtual ~TrackingGeometryCondAlg() override = default;
+
+  virtual StatusCode initialize() override;
+  virtual StatusCode execute(const EventContext& ctx) const override;
+  virtual StatusCode finalize() override {return StatusCode::SUCCESS;}
+  /** Make this algorithm clonable. */
+  virtual bool isClonable() const override { return true; };
+
+private:
+
+  /// Output conditions object.
+  SG::WriteCondHandleKey<TrackingGeometry> m_trackingGeometryWriteKey{this, "TrackingGeometryWriteKey", "AlignedTrackingGeometry", "Key of output of TrackingGeometry for ID"};
+  ServiceHandle<ICondSvc> m_condSvc{this, "CondSvc", "CondSvc"};
+  ToolHandle<Trk::IGeometryBuilderCond>           m_trackingGeometryBuilder {this, "GeometryBuilder", ""};
+  ToolHandleArray<Trk::IGeometryProcessor>    m_geometryProcessors ;
+};
+}
+#endif //TRACKINGGEOMETRYCONDALG_H
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlg.py b/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlg.py
new file mode 100644
index 0000000000000000000000000000000000000000..8a433eb66a8739b379dfaac6ce72e5fd3d8cd68b
--- /dev/null
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlg.py
@@ -0,0 +1,180 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+##################################################################################
+# The AtlasTrackingGeometryCondAlg fragment
+#
+# usage: 
+#   from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlg import ConfiguredTrackingGeometryCondAlg
+#   TrkGeoCondAlg = ConfiguredTrackingGeometryCondAlg('AtlasTrackingGeometryCondAlg')
+#   from AthenaCommon.AlgSequence import AthSequencer
+#   condSeq = AthSequencer("AthCondSeq")
+#   condSeq+= TrkGeoCondAlg
+#
+##################################################################################
+# import the DetFlags for the setting
+from AthenaCommon.DetFlags import DetFlags
+
+#################################################################################
+# Material for the Geometry comes from COOL or local database
+#################################################################################
+
+from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+
+
+from TrackingGeometryCondAlg.TrackingGeometryCondAlgConf import Trk__TrackingGeometryCondAlg
+   
+class ConfiguredTrackingGeometryCondAlg( Trk__TrackingGeometryCondAlg ) :   
+
+    # constructor
+    def __init__(self,name = 'AtlasTrackingGeometryCondAlg'):
+        
+        if TrkDetFlags.ConfigurationOutputLevel() < 3 :
+          print ('[ Configuration : start ] *** '+name+' ********************************')
+          print ('[ TrackingGeometryCondAlg ]')
+        
+        from AthenaCommon.AppMgr import ToolSvc 
+
+        #################################################################################
+        # The Geometry Builder
+        #################################################################################
+        
+        # the geometry builder alg tool
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__GeometryBuilderCond
+        AtlasGeometryBuilder = Trk__GeometryBuilderCond(name = 'AtlasGeometryBuilder')
+        # switch the building outputlevel on 
+        AtlasGeometryBuilder.OutputLevel = TrkDetFlags.ConfigurationOutputLevel()
+        
+        # the envelope definition service
+        from AthenaCommon.CfgGetter import getPrivateTool,getPrivateToolClone,getPublicTool,getPublicToolClone,\
+           getService,getServiceClone,getAlgorithm,getAlgorithmClone
+        AtlasEnvelopeSvc = getService('AtlasGeometry_EnvelopeDefSvc')
+           
+        # (ID) 
+        if DetFlags.ID_on() :
+#          FIXME: removed to get the migration to CondAlg started
+#          # get hand on the ID Tracking Geometry Builder
+#          if TrkDetFlags.ISF_FatrasCustomGeometry() :
+#              if hasattr(ToolSvc, TrkDetFlags.ISF_FatrasCustomGeometryBuilderName()):
+#                  InDetTrackingGeometryBuilder = getattr(ToolSvc, TrkDetFlags.ISF_FatrasCustomGeometryBuilderName())
+#          elif TrkDetFlags.XMLFastCustomGeometry() :
+#              if hasattr(ToolSvc, TrkDetFlags.InDetTrackingGeometryBuilderName()):
+#                  InDetTrackingGeometryBuilder = getattr(ToolSvc, TrkDetFlags.InDetTrackingGeometryBuilderName())
+#          else:
+          if not TrkDetFlags.InDetStagedGeometryBuilder():
+              from InDetTrackingGeometry.ConfiguredInDetTrackingGeometryBuilderCond import ConfiguredInDetTrackingGeometryBuilderCond as IDGeometryBuilder
+          else:
+              from InDetTrackingGeometry.ConfiguredStagedTrackingGeometryBuilderCond import ConfiguredStagedTrackingGeometryBuilderCond as IDGeometryBuilder
+          InDetTrackingGeometryBuilder = IDGeometryBuilder(name ='InDetTrackingGeometryBuilder')
+                
+          InDetTrackingGeometryBuilder.EnvelopeDefinitionSvc = AtlasEnvelopeSvc
+          InDetTrackingGeometryBuilder.OutputLevel = TrkDetFlags.InDetBuildingOutputLevel()
+          # and give it to the Geometry Builder
+          AtlasGeometryBuilder.InDetTrackingGeometryBuilder = InDetTrackingGeometryBuilder
+          # 
+        # (Calo)
+        if DetFlags.Calo_on() :
+           from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__CylinderVolumeCreator
+           CaloVolumeCreator = Trk__CylinderVolumeCreator("CaloVolumeCreator")
+           CaloVolumeCreator.OutputLevel = TrkDetFlags.CaloBuildingOutputLevel()
+           ToolSvc += CaloVolumeCreator
+
+           from CaloTrackingGeometry.ConfiguredCaloTrackingGeometryBuilderCond import ConfiguredCaloTrackingGeometryBuilderCond as ConfiguredCaloGeo 
+           CaloTrackingGeometryBuilder = ConfiguredCaloGeo(name='CaloTrackingGeometryBuilder');
+           CaloTrackingGeometryBuilder.TrackingVolumeCreator = CaloVolumeCreator
+           CaloTrackingGeometryBuilder.EnvelopeDefinitionSvc = AtlasEnvelopeSvc
+           CaloTrackingGeometryBuilder.OutputLevel           = TrkDetFlags.CaloBuildingOutputLevel()
+           CaloTrackingGeometryBuilder.GeometryName          = 'Calo'
+           # and give it to the Geometry Builder
+           AtlasGeometryBuilder.CaloTrackingGeometryBuilder = CaloTrackingGeometryBuilder
+        
+        # (Muon)
+        if DetFlags.Muon_on() :
+           from MuonTrackingGeometry.ConfiguredMuonTrackingGeometryCond import MuonTrackingGeometryBuilderCond
+           MuonTrackingGeometryBuilderCond.EnvelopeDefinitionSvc = AtlasEnvelopeSvc
+           # and give it to the Geometry Builder
+           AtlasGeometryBuilder.MuonTrackingGeometryBuilder = MuonTrackingGeometryBuilderCond
+           
+        # processors
+        AtlasGeometryProcessors = []   
+           
+        # check whether the material retrieval is ment to be from COOL
+        if TrkDetFlags.MaterialSource() is 'COOL':
+            # the material provider
+            from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__LayerMaterialProvider as LayerMaterialProvider
+            AtlasMaterialProvider = LayerMaterialProvider('AtlasMaterialProvider')
+            AtlasMaterialProvider.OutputLevel           = TrkDetFlags.ConfigurationOutputLevel()
+            AtlasMaterialProvider.LayerMaterialMapName  = TrkDetFlags.MaterialStoreGateKey()
+        
+            AtlasGeometryProcessors += [ AtlasMaterialProvider ]
+        
+            # the tag names
+            CoolDataBaseFolder = TrkDetFlags.MaterialStoreGateKey()
+            AtlasMaterialTag = TrkDetFlags.MaterialTagBase()+str(TrkDetFlags.MaterialVersion())+TrkDetFlags.MaterialSubVersion()+'_'
+        
+            if TrkDetFlags.ConfigurationOutputLevel() < 3 :
+               print '[ TrackingGeometryCondAlg ] Associating DB folder : ', CoolDataBaseFolder
+        
+            # we need the conditions interface
+            from IOVDbSvc.CondDB import conddb
+            # use a local database
+            if TrkDetFlags.MaterialDatabaseLocal():
+                # specify the local database
+                DataBasePath  = TrkDetFlags.MaterialDatabaseLocalPath() 
+                DataBaseName  = TrkDetFlags.MaterialDatabaseLocalName()
+                MagicTag      = TrkDetFlags.MaterialMagicTag()
+                DataBaseConnection = '<dbConnection>sqlite://X;schema='+DataBasePath+DataBaseName+';dbname=OFLP200</dbConnection>'
+                conddb.blockFolder('/GLOBAL/TrackingGeo/LayerMaterialV2')
+                conddb.addFolderWithTag('',DataBaseConnection+CoolDataBaseFolder,AtlasMaterialTag+MagicTag,force=True)
+                if TrkDetFlags.ConfigurationOutputLevel() < 3 :
+                    print '[ TrackingGeometryCondAlg ] Using Local Database: '+DataBaseConnection        
+                # make sure that the pool files are in the catalog
+            elif TrkDetFlags.SLHC_Geometry() :
+                # set the folder to the SLHC location        
+                CoolDataBaseFolder = '/GLOBAL/TrackingGeo/LayerMaterialITK'
+                ctag = AtlasMaterialTag+TrkDetFlags.MaterialMagicTag()
+                cfoldertag = CoolDataBaseFolder+' <tag>'+ctag+'</tag>'
+                conddb.addFolderSplitMC('GLOBAL',cfoldertag,cfoldertag)
+            else :
+                print '[ TrackingGeometryCondAlg ]     base material tag : ', AtlasMaterialTag
+                cfolder = CoolDataBaseFolder +'<tag>TagInfoMajor/'+AtlasMaterialTag+'/GeoAtlas</tag>'
+                print '[ TrackingGeometryCondAlg ]     translated to COOL: ', cfolder
+                # load the right folders (preparation for calo inclusion)
+                conddb.addFolderSplitMC('GLOBAL',cfolder,cfolder)
+
+        elif TrkDetFlags.MaterialSource() is 'Input' :
+            # the material provider
+            from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__InputLayerMaterialProvider
+            AtlasMaterialProvider = Trk__InputLayerMaterialProvider('AtlasMaterialProvider')
+            AtlasMaterialProvider.OutputLevel           = TrkDetFlags.ConfigurationOutputLevel()
+            AtlasGeometryProcessors += [ AtlasMaterialProvider ]            
+
+        # material validation
+        if TrkDetFlags.MaterialValidation() :
+            # load the material inspector
+            from TrkDetDescrTestTools.TrkDetDescrTestToolsConf import Trk__LayerMaterialInspector
+            AtlasLayerMaterialInspector = Trk__LayerMaterialInspector('AtlasLayerMaterialInspector')
+            AtlasLayerMaterialInspector.OutputLevel = TrkDetFlags.ConfigurationOutputLevel()
+            
+            AtlasGeometryProcessors += [ AtlasLayerMaterialInspector ]
+
+        # call the base class constructor : sets the tools
+        Trk__TrackingGeometryCondAlg.__init__(self,name,\
+                                          GeometryBuilder = AtlasGeometryBuilder,\
+                                          GeometryProcessors = AtlasGeometryProcessors, \
+                                          OutputLevel = TrkDetFlags.ConfigurationOutputLevel())
+        
+        # screen output of the configuration
+        if TrkDetFlags.ConfigurationOutputLevel() < 3 :
+           print self
+           print '* [ GeometryBuilder       ]'
+           print AtlasGeometryBuilder
+           print '* [ Configuration : end   ] ***'+name+'********************************'
+        
+##################################################################################    
+
+# now create the instance
+#AtlasTrackingGeometryCondAlg = ConfiguredTrackingGeometryCondAlg('AtlasTrackingGeometryCondAlg')
+# add it to the ServiceManager
+#from AthenaCommon.AlgSequence import AthSequencer
+#condSeq = AthSequencer("AthCondSeq")
+#condSeq+= AtlasTrackingGeometryCondAlg
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlgConfig.py b/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlgConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..fe96f02eaf913c9105b1789036a56a5510a198b2
--- /dev/null
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlgConfig.py
@@ -0,0 +1,293 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+Trk__TrackingGeometryCondAlg=CompFactory.Trk__TrackingGeometryCondAlg
+from IOVDbSvc.IOVDbSvcConfig import addFoldersSplitOnline
+from SubDetectorEnvelopes.SubDetectorEnvelopesConfig import getEnvelopeDefSvc
+
+# This file is a placeholder - the entire way we build geometry needs to be rewritten so this is to unblock new configuration developments for the moment.
+# It is based on: https://gitlab.cern.ch/atlas/athena/blob/master/Tracking/TrkDetDescr/TrkDetDescrSvc/python/AtlasTrackingGeometrySvc.py#L112
+
+def _setupCondDB(flags, CoolDataBaseFolder, quiet=True):
+    result=ComponentAccumulator()
+    
+    # the tag names
+    materialTagBase = 'AtlasLayerMat_v'
+    version = 21
+    sub_version = ''
+    
+    AtlasMaterialTag = materialTagBase+str(version)+sub_version+'_'
+    cfolder = CoolDataBaseFolder +'<tag>TagInfoMajor/'+AtlasMaterialTag+'/GeoAtlas</tag>'
+
+    # if not quiet:
+    #   print('[ TrackingGeometrySvc ]     base material tag : ' + AtlasMaterialTag)
+    #   print('[ TrackingGeometrySvc ]     translated to COOL: ' + cfolder)
+
+    # load the right folders
+    result.merge( addFoldersSplitOnline(flags,'GLOBAL',[cfolder],[cfolder],splitMC=True) )
+    return result
+    
+def _getInDetTrackingGeometryBuilder(name, flags,result, envelopeDefinitionSvc, namePrefix='', setLayerAssociation = True, buildTrtStrawLayers = False):
+  # Based on https://gitlab.cern.ch/atlas/athena/blob/master/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredInDetTrackingGeometryBuilder.py
+  # A lot of comments below are to help people understand differences from the above, in case we need to revert some simplifications I made
+  # i.e. this is far from complete, but is better than what was there before.
+  
+  # beampipe        
+  InDet__BeamPipeBuilder=CompFactory.InDet__BeamPipeBuilderCond
+  beamPipeBuilder = InDet__BeamPipeBuilder(name=namePrefix+'BeamPipeBuilder')
+
+  result.addPublicTool(beamPipeBuilder)
+  layerbuilders = []
+  binnings      = []
+  colors        = []
+
+  # Pixel
+  if flags.Detector.GeometryPixel:
+    InDet__SiLayerBuilder=CompFactory.InDet__SiLayerBuilderCond
+    PixelLayerBuilder = InDet__SiLayerBuilder(name=namePrefix+'PixelLayerBuilder')
+    PixelLayerBuilder.PixelCase            = True
+    PixelLayerBuilder.Identification       = 'Pixel'
+    PixelLayerBuilder.SiDetManagerLocation = 'Pixel'
+    # additional layers - handle with care !
+    PixelLayerBuilder.BarrelAdditionalLayerRadii      = [ 130 ]   # The PST
+    PixelLayerBuilder.BarrelAdditionalLayerType       = [ 0 ]     # -- will shift volume boundary to PST
+    PixelLayerBuilder.EndcapAdditionalLayerPositionsZ = [ -1900. , 1900. ] # DBM
+    PixelLayerBuilder.EndcapAdditionalLayerType       = [  1 , 1 ] # DBM
+    # Pixel barrel specifications
+    # Since we don't have TrkDetFlags, using defaults here.
+    
+    # set the layer association
+    PixelLayerBuilder.SetLayerAssociation  = setLayerAssociation
+
+    # the binning type of the layers   
+    PixelLayerBinning = 2
+    # add it to tool service
+    result.addPublicTool(PixelLayerBuilder)
+    # put them to the caches
+    layerbuilders += [ PixelLayerBuilder ]
+    binnings      += [ PixelLayerBinning ]
+    colors        += [ 3 ]
+
+  if flags.Detector.GeometrySCT:
+    # SCT building
+    InDet__SiLayerBuilder=CompFactory.InDet__SiLayerBuilderCond
+    SCT_LayerBuilder = InDet__SiLayerBuilder(name=namePrefix+'SCT_LayerBuilder')
+    SCT_LayerBuilder.PixelCase                       = False
+    SCT_LayerBuilder.Identification                  = 'SCT'
+    SCT_LayerBuilder.SiDetManagerLocation            = 'SCT'
+    # additionall layers - handle with care !
+    SCT_LayerBuilder.EndcapAdditionalLayerPositionsZ = [ -2850 , 2850 ] 
+    SCT_LayerBuilder.EndcapAdditionalLayerType       = [  0 , 0 ] 
+    # SCT barrel specifications - use defaults
+    # SCT endcap specifications - use defaults           
+    # set the layer association                   
+    SCT_LayerBuilder.SetLayerAssociation             = setLayerAssociation        
+    # the binning type of the layer     
+    SCT_LayerBinning = 2
+    # SCT -> ToolSvc                             
+    result.addPublicTool(SCT_LayerBuilder)
+                       
+    # put them to the caches
+    layerbuilders += [ SCT_LayerBuilder ]
+    binnings      += [ SCT_LayerBinning ]
+    colors        += [ 4 ]
+
+  if flags.Detector.GeometryTRT:                                                      
+    InDet__TRT_LayerBuilder=CompFactory.InDet__TRT_LayerBuilderCond
+    TRT_LayerBuilder = InDet__TRT_LayerBuilder(name=namePrefix+'TRT_LayerBuilder')
+    # TRT barrel specifications - assume defaults
+    # SCT endcap specifications - assume defaults
+                       
+    # set the binning from bi-aequidistant to arbitrary for complex TRT volumes
+    TRT_LayerBinning = 1        
+    if buildTrtStrawLayers:
+       TRT_LayerBinning = 2
+       TRT_LayerBuilder.ModelLayersOnly = False
+    # TRT -> ToolSvc                      
+    result.addPublicTool(TRT_LayerBuilder)
+    
+    # put them to the caches
+    layerbuilders += [ TRT_LayerBuilder ]
+    binnings      += [ TRT_LayerBinning ]
+    colors        += [ 5 ]
+
+  # helpers for the InDetTrackingGeometry Builder : layer array creator
+  Trk__LayerArrayCreator=CompFactory.Trk__LayerArrayCreator
+  InDetLayerArrayCreator = Trk__LayerArrayCreator(name = 'InDetLayerArrayCreator')
+  InDetLayerArrayCreator.EmptyLayerMode           = 2 # deletes empty material layers from arrays
+  # add to ToolSvc
+  result.addPublicTool(InDetLayerArrayCreator)  
+
+  # helpers for the InDetTrackingGeometry Builder : volume array creator
+  Trk__TrackingVolumeArrayCreator=CompFactory.Trk__TrackingVolumeArrayCreator
+  InDetTrackingVolumeArrayCreator                       = Trk__TrackingVolumeArrayCreator(name = 'InDetTrackingVolumeArrayCreator')
+  # add to ToolSvc
+  result.addPublicTool(InDetTrackingVolumeArrayCreator)  
+
+  # helpers for the InDetTrackingGeometry Builder : tracking voluem helper for glueing
+  Trk__TrackingVolumeHelper=CompFactory.Trk__TrackingVolumeHelper
+  InDetTrackingVolumeHelper                             = Trk__TrackingVolumeHelper(name ='InDetTrackingVolumeHelper')
+  # the material bins - assume defaults
+  # add to ToolSvc
+  result.addPublicTool(InDetTrackingVolumeHelper)  
+  
+  # helpers for the InDetTrackingGeometry Builder : cylinder volume creator
+  Trk__CylinderVolumeCreator=CompFactory.Trk__CylinderVolumeCreator
+  InDetCylinderVolumeCreator = Trk__CylinderVolumeCreator(name = 'InDetCylinderVolumeCreator')
+  # give it the layer array creator - assume defaults
+  # specifiy the binning, passive layers, entry layers - assume defaults
+  # add to ToolSvc
+  result.addPublicTool(InDetCylinderVolumeCreator)  
+
+  # the tracking geometry builder
+  InDet__RobustTrackingGeometryBuilder=CompFactory.InDet__RobustTrackingGeometryBuilderCond
+  return InDet__RobustTrackingGeometryBuilder(namePrefix+name,
+                                                BeamPipeBuilder   = beamPipeBuilder,
+                                                LayerBuilders     = layerbuilders,
+                                                LayerBinningType  = binnings,
+                                                ColorCodes        = colors,
+                                                EnvelopeDefinitionSvc = envelopeDefinitionSvc,
+                                                VolumeEnclosureDiscPositions = [ 3000., 3450. ],
+                                                TrackingVolumeCreator     = InDetCylinderVolumeCreator,
+                                                LayerArrayCreator         = InDetLayerArrayCreator)
+
+                                                # FIXME - not sure what to do about the following:
+                                                # BuildBoundaryLayers       = TrkDetFlags.InDetBuildMaterialBoundaries(),
+                                                # ReplaceAllJointBoundaries = TrkDetFlags.InDetBuildJointBoundaries(),
+                                                # OutputLevel               = TrkDetFlags.InDetBuildingOutputLevel(),
+                                                # ExitVolumeName            = TrkDetFlags.InDetContainerName(),
+                                                
+                                                # Probably they should just be dropped, but I leave this comment for the moment so reviewers can have a think as well.
+                                                
+                                                # Barrel Entry layers (in old config) etc were removed in 323990adfce581a635ae1809fd2ecc6a093a704c (!)
+  
+# Replaces https://gitlab.cern.ch/atlas/athena/blob/master/Calorimeter/CaloTrackingGeometry/python/ConfiguredCaloTrackingGeometryBuilder.py
+def _getCaloTrackingGeometryBuilder(name, flags,result, envelopeDefinitionSvc, trackingVolumeHelper, namePrefix=''):
+  # The following replaces LArCalorimeter/LArTrackingGeometry/python/ConfiguredLArVolumeBuilder.py
+  LAr__LArVolumeBuilder=CompFactory.LAr__LArVolumeBuilder
+  lArVolumeBuilder = LAr__LArVolumeBuilder(TrackingVolumeHelper = trackingVolumeHelper,)
+  result.addPublicTool(lArVolumeBuilder)
+  
+  # The following replaces TileCalorimeter/TileTrackingGeometry/python/ConfiguredTileVolumeBuilder.py
+  Tile__TileVolumeBuilder=CompFactory.Tile__TileVolumeBuilder
+  tileVolumeBuilder = Tile__TileVolumeBuilder( TrackingVolumeHelper = trackingVolumeHelper,  )
+  result.addPublicTool(tileVolumeBuilder)
+  
+  Calo__CaloTrackingGeometryBuilder=CompFactory.Calo__CaloTrackingGeometryBuilderCond
+  return Calo__CaloTrackingGeometryBuilder(namePrefix+name, LArVolumeBuilder = lArVolumeBuilder,
+                                                   TileVolumeBuilder = tileVolumeBuilder,
+                                                   TrackingVolumeHelper = trackingVolumeHelper,
+                                                   EnvelopeDefinitionSvc = envelopeDefinitionSvc,
+                                                   )
+
+# Originally this function would use was TrkDetFlags.MaterialSource() and TrkDetFlags.MaterialValidation(). For new configuration, (temporarily?) pass as parameters.
+# https://gitlab.cern.ch/atlas/athena/blob/master/Tracking/TrkDetDescr/TrkDetDescrSvc/python/AtlasTrackingGeometrySvc.py#L112
+def TrackingGeometryCondAlgCfg( flags , name = 'AtlasTrackingGeometryCondAlg', doMaterialValidation=False ) :
+    """
+    Sets up the Tracking Geometry Conditions Algorithm
+    """
+    result = ComponentAccumulator()
+    atlas_tracking_geometry_name = 'AtlasTrackingGeometry'
+    Trk__GeometryBuilder=CompFactory.Trk__GeometryBuilderCond
+    atlas_geometry_builder = Trk__GeometryBuilder(name = 'AtlasGeometryBuilder')
+
+    atlas_env_def_service = getEnvelopeDefSvc()
+    result.addService(atlas_env_def_service)  
+
+    # Depending on the job configuration, setup the various detector builders, and add to atlas_geometry_builder
+    if flags.Detector.GeometryID:
+      # TODO Not sure how to handle TrkDetFlags, specifically ISF_FatrasCustomGeometry, XMLFastCustomGeometry, SLHC_Geometry
+      # So, here we only setup the default InDet geometry builder!
+      inDetTrackingGeometryBuilder = _getInDetTrackingGeometryBuilder(name ='InDetTrackingGeometryBuilder', flags=flags, result=result, envelopeDefinitionSvc=atlas_env_def_service)
+      result.addPublicTool(inDetTrackingGeometryBuilder)
+      
+      atlas_geometry_builder.InDetTrackingGeometryBuilder = inDetTrackingGeometryBuilder
+      
+    if flags.Detector.GeometryCalo:
+      Trk__CylinderVolumeCreator=CompFactory.Trk__CylinderVolumeCreator
+      caloVolumeCreator = Trk__CylinderVolumeCreator("CaloVolumeCreator")
+      result.addPublicTool(caloVolumeCreator)
+
+      Trk__TrackingVolumeHelper=CompFactory.Trk__TrackingVolumeHelper
+      trackingVolumeHelper = Trk__TrackingVolumeHelper(name='TrackingVolumeHelper')
+      result.addPublicTool(trackingVolumeHelper)
+
+      caloTrackingGeometryBuilder = _getCaloTrackingGeometryBuilder(name ='CaloTrackingGeometryBuilder', flags=flags, result=result, envelopeDefinitionSvc=atlas_env_def_service, trackingVolumeHelper=trackingVolumeHelper)
+      result.addPublicTool(caloTrackingGeometryBuilder)
+      atlas_geometry_builder.CaloTrackingGeometryBuilder = caloTrackingGeometryBuilder
+
+    if flags.Detector.GeometryMuon:
+      # Copied from from MuonTrackingGeometry.ConfiguredMuonTrackingGeometry import MuonTrackingGeometryBuilder
+      Muon__MuonStationTypeBuilder=CompFactory.Muon__MuonStationTypeBuilder
+      muonStationTypeBuilder= Muon__MuonStationTypeBuilder(name = 'MuonStationTypeBuilder')
+      result.addPublicTool(muonStationTypeBuilder)
+    
+      Muon__MuonStationBuilder=CompFactory.Muon__MuonStationBuilder
+      muonStationBuilder= Muon__MuonStationBuilder(name = 'MuonStationBuilder')
+      muonStationBuilder.StationTypeBuilder = muonStationTypeBuilder
+      result.addPublicTool(muonStationBuilder)
+
+      Muon__MuonInertMaterialBuilder=CompFactory.Muon__MuonInertMaterialBuilder
+      muonInertMaterialBuilder= Muon__MuonInertMaterialBuilder(name = 'MuonInertMaterialBuilder')
+      result.addPublicTool(muonInertMaterialBuilder)
+
+      Muon__MuonTrackingGeometryBuilder=CompFactory.Muon__MuonTrackingGeometryBuilderCond
+      muonTrackingGeometryBuilder= Muon__MuonTrackingGeometryBuilder(name = 'MuonTrackingGeometryBuilder', EnvelopeDefinitionSvc=atlas_env_def_service)
+      result.addPublicTool(muonTrackingGeometryBuilder)
+    
+      atlas_geometry_builder.MuonTrackingGeometryBuilder = muonTrackingGeometryBuilder
+    
+    # Now set up processors
+    atlas_geometry_processors=[]
+    
+    if flags.TrackingGeometry.MaterialSource == 'COOL':
+       CoolDataBaseFolder = '/GLOBAL/TrackingGeo/LayerMaterialV2' # Was from TrkDetFlags.MaterialStoreGateKey()
+       # the material provider
+       Trk__LayerMaterialProvider=CompFactory.Trk__LayerMaterialProvider
+       atlasMaterialProvider = Trk__LayerMaterialProvider('AtlasMaterialProvider', LayerMaterialMapName=CoolDataBaseFolder)
+       atlas_geometry_processors += [ atlasMaterialProvider ]
+
+       # Setup DBs
+       result.merge(_setupCondDB(flags, CoolDataBaseFolder))
+    elif  flags.TrackingGeometry.MaterialSource == 'Input':
+      Trk__InputLayerMaterialProvider=CompFactory.Trk__InputLayerMaterialProvider
+      atlasMaterialProvider = Trk__InputLayerMaterialProvider('AtlasMaterialProvider')
+      atlas_geometry_processors += [ atlasMaterialProvider ]
+      
+    if doMaterialValidation:
+      Trk__LayerMaterialInspector=CompFactory.Trk__LayerMaterialInspector
+      atlasLayerMaterialInspector = Trk__LayerMaterialInspector('AtlasLayerMaterialInspector')
+      atlas_geometry_processors += [ atlasLayerMaterialInspector ]
+
+    condAlg = Trk__TrackingGeometryCondAlg( name, GeometryBuilder = atlas_geometry_builder,
+                                    TrackingGeometryWriteKey = atlas_tracking_geometry_name,
+                                    GeometryProcessors = atlas_geometry_processors, 
+                                    BuildGeometryFromTagInfo = True)
+    result.addCondAlgo(condAlg, primary = True)
+
+    return result
+        
+if __name__ == '__main__':
+    from AthenaCommon.Configurable import Configurable
+    Configurable.configurableRun3Behavior=1
+    from AthenaConfiguration.AllConfigFlags import ConfigFlags
+    from AthenaConfiguration.TestDefaults import defaultTestFiles
+
+    ConfigFlags.Input.Files = defaultTestFiles.RAW
+    ConfigFlags.Detector.GeometryPixel = True     
+    ConfigFlags.Detector.GeometrySCT   = True 
+    ConfigFlags.Detector.GeometryTRT   = True 
+    ConfigFlags.Detector.GeometryLAr   = True     
+    ConfigFlags.Detector.GeometryTile  = True     
+    ConfigFlags.Detector.GeometryMDT   = True 
+    ConfigFlags.Detector.GeometryTGC   = True
+    ConfigFlags.Detector.GeometryCSC   = True     
+    ConfigFlags.Detector.GeometryRPC   = True 
+    ConfigFlags.lock()
+
+    acc = TrackingGeometryCondAlgCfg(ConfigFlags )
+
+    f=open('TrackingGeometryCondAlgCfg.pkl','wb')
+    acc.store(f)
+    f.close()
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/src/TrackingGeometryCondAlg.cxx b/Tracking/TrkConditions/TrackingGeometryCondAlg/src/TrackingGeometryCondAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..572bfdb7c6ba3eb6246cf18f6bf01a22fde4c285
--- /dev/null
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/src/TrackingGeometryCondAlg.cxx
@@ -0,0 +1,71 @@
+/*
+ *   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+// Trk includes
+#include "TrkGeometry/TrackingGeometry.h"
+#include "AthenaKernel/IOVSvcDefs.h"
+
+#include "TrackingGeometryCondAlg/TrackingGeometryCondAlg.h"
+
+
+Trk::TrackingGeometryCondAlg::TrackingGeometryCondAlg(const std::string& name, ISvcLocator* pSvcLocator)
+  : AthReentrantAlgorithm(name, pSvcLocator),
+    m_geometryProcessors(this) 
+{
+  declareProperty("GeometryBuilder", m_trackingGeometryBuilder);
+  declareProperty("GeometryProcessors", m_geometryProcessors);
+}
+
+StatusCode Trk::TrackingGeometryCondAlg::initialize()
+{
+  ATH_MSG_DEBUG("initialize " << name());
+
+  // Write Handle
+  ATH_CHECK(m_trackingGeometryWriteKey.initialize());
+  // CondSvc
+  ATH_CHECK(m_condSvc.retrieve());
+  // Register write handle
+  ATH_CHECK(m_condSvc->regHandle(this, m_trackingGeometryWriteKey));
+  // Retrieve tools
+  ATH_CHECK(m_trackingGeometryBuilder.retrieve());
+  if (m_geometryProcessors.retrieve().isFailure()){
+    ATH_MSG_FATAL( "Could not retrieve " << m_geometryProcessors );
+    return StatusCode::FAILURE;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode Trk::TrackingGeometryCondAlg::execute(const EventContext& ctx) const{
+  //Set up write handle
+  SG::WriteCondHandle<Trk::TrackingGeometry> writeHandle{m_trackingGeometryWriteKey, ctx};
+
+
+  if (writeHandle.isValid()) {
+    ATH_MSG_DEBUG("Found valid write handle");
+    return StatusCode::SUCCESS;
+  }
+
+  //Create dummy IOV range covering 0 - inf
+  EventIDRange range;
+
+  std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometryPair = m_trackingGeometryBuilder->trackingGeometry(ctx, std::pair<EventIDRange, const Trk::TrackingVolume*>(range, nullptr));
+  // cast constness away for StoreGate
+  Trk::TrackingGeometry* trackingGeometry = const_cast<Trk::TrackingGeometry*>(trackingGeometryPair.second);
+
+  // loop over the recursive geometry processors
+  auto gpIter  = m_geometryProcessors.begin();
+  auto gpIterE = m_geometryProcessors.end();
+  for ( ; gpIter != gpIterE; ++ gpIter ){
+      if ( (*gpIter)->process(*trackingGeometry).isFailure() ){
+          ATH_MSG_FATAL("Processing of TrackingGeometry did not succeed. Abort." );
+          return StatusCode::FAILURE;
+      } else {
+          ATH_MSG_VERBOSE("Successfully processed the TrackingGeometry with " << (*gpIter) );
+      }
+  }
+  ATH_CHECK(writeHandle.record(trackingGeometryPair.first,trackingGeometry));
+  return StatusCode::SUCCESS;
+}
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/src/components/TrackingGeometryCondAlg_entries.cxx b/Tracking/TrkConditions/TrackingGeometryCondAlg/src/components/TrackingGeometryCondAlg_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..cf3e2c0fb66c69d11467f8618e355973d7a73a3f
--- /dev/null
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/src/components/TrackingGeometryCondAlg_entries.cxx
@@ -0,0 +1,3 @@
+#include "TrackingGeometryCondAlg/TrackingGeometryCondAlg.h"
+
+DECLARE_COMPONENT( Trk::TrackingGeometryCondAlg )
diff --git a/Tracking/TrkConditions/TrkCondTest/CMakeLists.txt b/Tracking/TrkConditions/TrkCondTest/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7540c13fa3d6310bc06e4337397db30753980611
--- /dev/null
+++ b/Tracking/TrkConditions/TrkCondTest/CMakeLists.txt
@@ -0,0 +1,40 @@
+################################################################################
+# Package: TrkCondTest
+################################################################################
+
+# Declare the package name:
+atlas_subdir( TrkCondTest )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs(
+   PUBLIC
+   Control/AthenaBaseComps
+   Control/AthenaKernel
+   GaudiKernel
+   Tracking/TrkDetDescr/TrkDetDescrInterfaces
+   Tracking/TrkDetDescr/TrkDetDescrUtils
+   Tracking/TrkDetDescr/TrkGeometry
+   InnerDetector/InDetDetDescr/InDetReadoutGeometry
+   PRIVATE
+    )
+
+find_package( Eigen )
+
+# Component(s) in the package:
+
+atlas_add_component( TrackingGeometryCondAlgTest
+   TrkCondTest/*.h src/*.cxx src/components/*.cxx
+   INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS}
+   LINK_LIBRARIES ${EIGEN_LIBRARIES} 
+   AthenaBaseComps
+   AthenaKernel
+   GaudiKernel 
+   TrkDetDescrInterfaces
+   TrkDetDescrUtils
+   TrkGeometry
+   InDetReadoutGeometry
+    )
+
+# Install files from the package:
+atlas_install_python_modules( python/*.py )
+atlas_install_joboptions( share/*.py )
diff --git a/Tracking/TrkConditions/TrkCondTest/TrkCondTest/TrackingGeometryCondAlgTest.h b/Tracking/TrkConditions/TrkCondTest/TrkCondTest/TrackingGeometryCondAlgTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..8f3c5a1b562ab5f5f0386b4baf883b6dfbe9edc2
--- /dev/null
+++ b/Tracking/TrkConditions/TrkCondTest/TrkCondTest/TrackingGeometryCondAlgTest.h
@@ -0,0 +1,40 @@
+/*
+ *   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRACKINGGEOMETRYCONDALG_H
+#define TRACKINGGEOMETRYCONDALG_H
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "PersistentDataModel/AthenaAttributeList.h"
+#include "StoreGate/ReadCondHandleKey.h"
+#include "StoreGate/WriteCondHandleKey.h"
+
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkDetDescrInterfaces/IGeometryBuilder.h"
+#include "TrkDetDescrInterfaces/IGeometryProcessor.h"
+#include "InDetReadoutGeometry/SiDetectorElementCollection.h"
+
+#include "GaudiKernel/ToolHandle.h"
+#include "AthenaKernel/CLASS_DEF.h"
+
+namespace Trk{
+class TrackingGeometryCondAlgTest : public AthReentrantAlgorithm
+{
+public:
+    TrackingGeometryCondAlgTest(const std::string& name, ISvcLocator* pSvcLocator);
+    virtual ~TrackingGeometryCondAlgTest() override = default;
+
+    virtual StatusCode initialize() override;
+    virtual StatusCode execute(const EventContext& ctx)const override;
+    virtual StatusCode finalize() override {return StatusCode::SUCCESS;}
+
+private:
+
+  /// Input conditions object.
+  SG::ReadCondHandleKey<TrackingGeometry> m_trackingGeometryReadKey{this, "TrackingGeometryReadKey", "AlignedTrackingGeometry", "Key of input TrackingGeometry"};
+  mutable std::vector<Amg::Vector3D> m_worldVolumeCenterCollection;
+};
+}
+#endif //TRACKINGGEOMETRYCONDALG_H
diff --git a/Tracking/TrkConditions/TrkCondTest/share/TrackingGeometryTest_jobOptions.py b/Tracking/TrkConditions/TrkCondTest/share/TrackingGeometryTest_jobOptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ac5625c8657a25c7a4c69cfccc26dcce601c5d7
--- /dev/null
+++ b/Tracking/TrkConditions/TrkCondTest/share/TrackingGeometryTest_jobOptions.py
@@ -0,0 +1,105 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+###############################################################
+#
+# Job options 
+#
+#==============================================================
+
+#--------------------------------------------------------------
+# ATLAS default Application Configuration options
+#--------------------------------------------------------------
+
+# Use McEventSelector so we can run with AthenaMP
+
+#--------------------------------------------------------------
+# Private Application Configuration options
+#--------------------------------------------------------------
+
+from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
+athenaCommonFlags.FilesInput = ["/afs/cern.ch/work/r/rlangenb/public/data18_13TeV.00363979.physics_Main.daq.ESD/100evts10lumiblocks.ESD.root"]
+
+import AthenaPoolCnvSvc.ReadAthenaPool
+
+# build GeoModel
+import AthenaPython.ConfigLib as apcl
+cfg = apcl.AutoCfg(name = 'TrackingGeometryTest', input_files=athenaCommonFlags.FilesInput())
+
+cfg.configure_job()
+
+from AthenaCommon.GlobalFlags import globalflags
+if len(globalflags.ConditionsTag())!=0:
+  from IOVDbSvc.CondDB import conddb
+  conddb.setGlobalTag(globalflags.ConditionsTag())
+from AtlasGeoModel.InDetGMJobProperties import InDetGeometryFlags
+InDetGeometryFlags.useDynamicAlignFolders=True
+
+import MagFieldServices.SetupField
+
+# the global detflags
+from AthenaCommon.DetFlags import DetFlags
+DetFlags.ID_setOn()
+DetFlags.Calo_setOn()
+DetFlags.Muon_setOn()
+DetFlags.TRT_setOn()
+
+# Full job is a list of algorithms
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+from AtlasGeoModel import SetGeometryVersion 
+from AtlasGeoModel import GeoModelInit 
+
+# switch the material loading off
+from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+TrkDetFlags.MaterialSource           = 'None'
+TrkDetFlags.MaterialVersion          = 16
+TrkDetFlags.ConfigurationOutputLevel = VERBOSE
+
+
+TrkDetFlags.PixelBuildingOutputLevel     = VERBOSE
+TrkDetFlags.SCT_BuildingOutputLevel      = VERBOSE
+TrkDetFlags.TRT_BuildingOutputLevel      = VERBOSE
+TrkDetFlags.InDetBuildingOutputLevel     = VERBOSE
+TrkDetFlags.ConfigurationOutputLevel     = VERBOSE
+
+
+# load the tracking geometry cond alg
+from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlg import ConfiguredTrackingGeometryCondAlg
+TrkGeoCondAlg = ConfiguredTrackingGeometryCondAlg('AtlasTrackingGeometryCondAlg')
+from AthenaCommon.AlgSequence import AthSequencer
+condSeq = AthSequencer("AthCondSeq")
+condSeq+= TrkGeoCondAlg
+
+from TrkCondTest.TrackingGeometryCondAlgTestConf import Trk__TrackingGeometryCondAlgTest
+TrkGeomCondAlgTest = Trk__TrackingGeometryCondAlgTest(name = "TrkGeomTest")
+job += TrkGeomCondAlgTest
+
+#--------------------------------------------------------------
+# Set output level threshold (DEBUG, INFO, WARNING, ERROR, FATAL)
+#--------------------------------------------------------------
+
+# Output level for HelloAlg only (note name: instance, not type)
+#TrackingGeometryTest = INFO
+
+# You can set the global output level on the message svc (not
+# recommended) or by using the -l athena CLI parameter
+
+#--------------------------------------------------------------
+# Event related parameters
+#--------------------------------------------------------------
+
+theApp.EvtMax = 22
+
+from AthenaCommon.AppMgr import ServiceMgr
+# output level
+ServiceMgr.MessageSvc.OutputLevel  = INFO
+# increase the number of letter reserved to the alg/tool name from 18 to 30
+ServiceMgr.MessageSvc.Format       = "% F%50W%S%7W%R%T %0W%M"
+# to change the default limit on number of message
+ServiceMgr.MessageSvc.defaultLimit = 9999999  # all messages
+
+#==============================================================
+#
+# End of job options file
+#
+###############################################################
diff --git a/Tracking/TrkConditions/TrkCondTest/src/TrackingGeometryCondAlgTest.cxx b/Tracking/TrkConditions/TrkCondTest/src/TrackingGeometryCondAlgTest.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..364faa7072016d4b1248a87a1b74b86c611d6b8e
--- /dev/null
+++ b/Tracking/TrkConditions/TrkCondTest/src/TrackingGeometryCondAlgTest.cxx
@@ -0,0 +1,47 @@
+/*
+ *   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+// Trk includes
+#include "AthenaKernel/IOVSvcDefs.h"
+
+#include "TrkCondTest/TrackingGeometryCondAlgTest.h"
+
+
+Trk::TrackingGeometryCondAlgTest::TrackingGeometryCondAlgTest(const std::string& name, ISvcLocator* pSvcLocator)
+  : AthReentrantAlgorithm(name, pSvcLocator)
+{
+}
+
+StatusCode Trk::TrackingGeometryCondAlgTest::initialize()
+{
+  ATH_MSG_DEBUG("initialize " << name());
+
+  // Read Handle Key
+  ATH_CHECK(m_trackingGeometryReadKey.initialize());
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode Trk::TrackingGeometryCondAlgTest::execute(const EventContext& ctx) const {
+  
+  //Set up read handle
+  SG::ReadCondHandle<Trk::TrackingGeometry> readHandle{m_trackingGeometryReadKey, ctx};
+  if (!readHandle.isValid() || *readHandle == nullptr) {
+    ATH_MSG_WARNING(m_trackingGeometryReadKey.fullKey() << " is not available.");
+    return StatusCode::FAILURE;
+  }
+  const Trk::TrackingGeometry* trkGeom = *readHandle;
+  ATH_MSG_INFO( "eventID: "  << ctx.eventID());
+
+  Amg::Vector3D center = trkGeom->highestTrackingVolume()->center();
+  ATH_MSG_INFO("Center coordinates of highest tracking volume");
+  ATH_MSG_INFO(center);
+  if(m_worldVolumeCenterCollection.size()>=1 && m_worldVolumeCenterCollection.back() != center){
+    ATH_MSG_INFO("hooray, we have moved the world");
+  }
+  m_worldVolumeCenterCollection.push_back(center);
+
+  ATH_MSG_INFO("TrackingGeometry retrieved");
+  return StatusCode::SUCCESS;
+}
diff --git a/Tracking/TrkConditions/TrkCondTest/src/components/TrkCondTest_entries.cxx b/Tracking/TrkConditions/TrkCondTest/src/components/TrkCondTest_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9d545d5244641d64a453829e5fc1389887189d1e
--- /dev/null
+++ b/Tracking/TrkConditions/TrkCondTest/src/components/TrkCondTest_entries.cxx
@@ -0,0 +1,3 @@
+#include "TrkCondTest/TrackingGeometryCondAlgTest.h"
+
+DECLARE_COMPONENT( Trk::TrackingGeometryCondAlgTest )
diff --git a/Tracking/TrkConfig/python/TrackCollectionReadConfig.py b/Tracking/TrkConfig/python/TrackCollectionReadConfig.py
index 13be290062348a0f1bc29768fb4c98479c579f86..9ef0980dcb088f8c19e5b223b98d1c2908cadb73 100644
--- a/Tracking/TrkConfig/python/TrackCollectionReadConfig.py
+++ b/Tracking/TrkConfig/python/TrackCollectionReadConfig.py
@@ -64,7 +64,8 @@ in the input file."""
                       Key = 'TrackCollection/' + key,
                       Aliases = aliases,
                       ExtraInputs = [('InDetDD::SiDetectorElementCollection', 'ConditionStore+PixelDetectorElementCollection'),
-                                     ('InDetDD::SiDetectorElementCollection', 'ConditionStore+SCT_DetectorElementCollection')])
+                                     ('InDetDD::SiDetectorElementCollection', 'ConditionStore+SCT_DetectorElementCollection'), 
+                                     ( 'InDetDD::TRT_DetElementContainer' , 'ConditionStore+TRT_DetElementContainer' ) ])
     result.addEventAlgo (alg)
 
     # We also require AddressRemappingSvc.
diff --git a/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryBuilderCond.h b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryBuilderCond.h
new file mode 100755
index 0000000000000000000000000000000000000000..c0a3e1f20b2f3ef8864db7071711499ffdfd4757
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryBuilderCond.h
@@ -0,0 +1,69 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// IGeometryBuilderCond.hm (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef TRKDETDESCRINTERFACES_IGEOMETRYBUILDERCOND_H
+#define TRKDETDESCRINTERFACES_IGEOMETRYBUILDERCOND_H
+
+// Gaudi
+#include "GaudiKernel/IAlgTool.h"
+#include "GaudiKernel/EventContext.h"
+// Trk - enum
+#include "TrkDetDescrUtils/GeometrySignature.h"
+// STL
+#include <vector>
+
+class EventIDRange;
+namespace Trk {
+
+  class TrackingGeometry;
+  class TrackingVolume;
+
+  /** Interface ID for IGeometryBuilderConds*/  
+  static const InterfaceID IID_IGeometryBuilderCond("IGeometryBuilderCond", 1, 0);
+  
+  /** @class IGeometryBuilderCond
+    
+    Interface class IGeometryBuilderCond,
+    the GeometryBuilder inherits from this one.
+    
+    VolumeBounds can be given optionally to force a specific size/shape/boundary
+
+    This interface class implements protected glue and surface
+    exchange methods, that require friend rights to the classes
+    
+    @author Andreas.Salzburger@cern.ch
+    */
+  class IGeometryBuilderCond : virtual public IAlgTool {
+    
+    public:
+      /**Virtual destructor*/
+      virtual ~IGeometryBuilderCond(){}
+      
+      /** AlgTool and IAlgTool interface methods */
+      static const InterfaceID& interfaceID() { return IID_IGeometryBuilderCond; }
+
+      /** TrackingGeometry Interface methode -
+       *   - Event context
+       *   - pair with EventIDRange and corresponding TrackingVolume, from which
+       *     we retrieve the volume to wrap the TrackingGeometry around. If
+       *     TrackingGeometry is nullptr, range should be infinite (so
+       *     intersecting with another range has no effect)
+       */
+      virtual std::pair<EventIDRange, const TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const = 0;
+
+      /** The unique signature */
+      virtual GeometrySignature geometrySignature() const = 0;
+      
+  };
+
+} // end of namespace
+
+
+#endif // TRKDETDESCRINTERFACES_IGEOMETRYBUILDERCOND_H
+
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryProcessor.h b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryProcessor.h
index 2e79fed6792a8facafc8060633d3447c7e400f1b..01b6bd5d76f92e305017f1125d3cb1a2d8139be0 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryProcessor.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryProcessor.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -40,16 +40,16 @@ namespace Trk {
       static const InterfaceID& interfaceID() { return IID_IGeometryProcessor; }
 
       /** Processor Action to work on TrackingGeometry& tgeo */
-      virtual StatusCode process(const TrackingGeometry& tvol) = 0;
+      virtual StatusCode process(const TrackingGeometry& tvol) const = 0;
 
       /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-      virtual StatusCode process(const TrackingVolume& tvol, size_t level=0) = 0;
+      virtual StatusCode process(const TrackingVolume& tvol, size_t level=0) const = 0;
      
       /** Processor Action to work on Layers */
-      virtual StatusCode process(const Layer& lay, size_t level=0) = 0;
+      virtual StatusCode process(const Layer& lay, size_t level=0) const = 0;
 
       /** Processor Action to work on Surfaces */
-      virtual StatusCode process(const Surface& surf, size_t level=0) = 0;
+      virtual StatusCode process(const Surface& surf, size_t level=0) const = 0;
 
   };
 
diff --git a/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerBuilderCond.h b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerBuilderCond.h
new file mode 100755
index 0000000000000000000000000000000000000000..c929d43bdb8e2d44d562796a85194f3ca75e1930
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerBuilderCond.h
@@ -0,0 +1,73 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// ILayerBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef TRKDETDESCRINTERFACES_ILAYERBUILDERCOND_H
+#define TRKDETDESCRINTERFACES_ILAYERBUILDERCOND_H
+
+// Gaudi
+#include "GaudiKernel/IAlgTool.h"
+#include "TrkSurfaces/Surface.h"
+// STL
+#include <vector>
+#include <string>
+
+namespace Trk {
+
+  class CylinderLayer;
+  class DiscLayer;
+  class PlaneLayer;
+  class Layer;
+
+  /** Interface ID for ILayerBuilderCond*/  
+  static const InterfaceID IID_ILayerBuilderCond("ILayerBuilderCond", 1, 0);
+  
+  /** @class ILayerBuilderCond
+    Interface class ILayerBuilderConds
+    It inherits from IAlgTool. The actual implementation of the AlgTool depends on the SubDetector,
+    more detailed information should be found there.
+    
+    @author Andreas.Salzburger@cern.ch
+    */
+  class ILayerBuilderCond : virtual public IAlgTool {
+    
+    public:
+      /**Virtual destructor*/
+      virtual ~ILayerBuilderCond(){}
+      
+      /** AlgTool and IAlgTool interface methods */
+      static const InterfaceID& interfaceID() { return IID_ILayerBuilderCond; }
+
+      /** LayerBuilder interface method - returning Barrel-like layers */
+      virtual std::pair<EventIDRange, const std::vector< const CylinderLayer* >*> cylindricalLayers(const EventContext& ctx) const = 0; 
+      
+      /** LayerBuilder interface method - returning Endcap-like layers */
+      virtual std::pair<EventIDRange, const std::vector< const DiscLayer* >*>     discLayers(const EventContext& ctx) const = 0; 
+      
+      /** LayerBuilder interface method - returning Planar-like layers */
+      virtual std::pair<EventIDRange, const std::vector< const PlaneLayer* >*>    planarLayers(const EventContext& ctx) const = 0;
+
+      /** Name identification */
+      virtual const std::string& identification() const = 0;
+      
+      /** Validation Action:
+          Can be implemented optionally, outside access to internal validation steps */
+      virtual void validationAction() const {}
+
+    protected:
+      /** Protected method to register the Layer to the Surface */
+      void associateLayer(const Layer& lay, const Surface& sf) const { sf.associateLayer(lay); }
+       
+  };
+
+
+} // end of namespace
+
+
+#endif // TRKDETDESCRINTERFACES_ILAYERBUILDERCOND_H
+
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerProviderCond.h b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerProviderCond.h
new file mode 100644
index 0000000000000000000000000000000000000000..da5049f8b220548b9cd13ba1b4a495abddb2dddb
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerProviderCond.h
@@ -0,0 +1,62 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// ILayerProviderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef TRKDETDESCRINTERFACES_ILAYERPROVIDERCOND_H
+#define TRKDETDESCRINTERFACES_ILAYERPROVIDERCOND_H
+
+// Gaudi
+#include "GaudiKernel/IAlgTool.h"
+#include "GaudiKernel/EventIDRange.h"
+#include "GaudiKernel/EventContext.h"
+// STL
+#include <vector>
+#include <string>
+
+namespace Trk {
+
+  class Layer;
+
+  /** Interface ID for ILayerProviderConds*/  
+  static const InterfaceID IID_ILayerProviderCond("ILayerProviderCond", 1, 0);
+  
+  /** @class ILayerProviderCond
+  
+    Interface class ILayerProviderConds
+    it feeds into the StagedGeometryBuilder
+    
+    @author Andreas.Salzburger@cern.ch
+    */
+  class ILayerProviderCond : virtual public IAlgTool {
+    
+    public:
+      /**Virtual destructor*/
+      virtual ~ILayerProviderCond(){}
+      
+      /** AlgTool and IAlgTool interface methods */
+      static const InterfaceID& interfaceID() { return IID_ILayerProviderCond; }
+
+      /** LayerBuilder interface method - returning the layers at negative side */
+      virtual std::pair<EventIDRange, const std::vector< const Layer* > > negativeLayers(const EventContext& ctx) const = 0; 
+      
+      /** LayerBuilder interface method - returning the central layers */
+      virtual std::pair<EventIDRange, const std::vector< const Layer* > > centralLayers(const EventContext& ctx) const = 0; 
+      
+      /** LayerBuilder interface method - returning the layers at negative side */
+      virtual std::pair<EventIDRange, const std::vector< const Layer* > > positiveLayers(const EventContext& ctx) const = 0; 
+
+      /** Name identification */
+      virtual const std::string& identification() const = 0;
+             
+  };
+
+} // end of namespace
+
+
+#endif // TRKDETDESCRINTERFACES_ILAYERPROVIDER_H
+
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryAsciiDumper.h b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryAsciiDumper.h
index 831cec3dff98b9c6546806780eb7ba8c3a4f466f..1ab2e4ecd3ff849e8b4be44511eabbd1e86e5665 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryAsciiDumper.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryAsciiDumper.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -52,15 +52,15 @@ namespace Trk {
       private:
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const TrackingVolume& tvol, size_t level=0);
+        StatusCode processNode(const TrackingVolume& tvol, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Layer& lay, size_t level=0);
+        StatusCode processNode(const Layer& lay, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Surface&, size_t level=0);
+        StatusCode processNode(const Surface&, size_t level=0) const;
 
-        std::ofstream               m_outputFile;
+        mutable std::ofstream       m_outputFile;
         std::string                 m_outputFileName;  //!< where the tree is written to  
         int                         m_outputPrecision;
 
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryJsonDumper.h b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryJsonDumper.h
index 9a02125c26a4af6ed56cc0892573413d8e398e6d..5a70fc1f15c3fe405228e88b6cefbefaf7a523e1 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryJsonDumper.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryJsonDumper.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -52,18 +52,18 @@ namespace Trk {
       private:
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const TrackingVolume& tvol, size_t level=0);
+        StatusCode processNode(const TrackingVolume& tvol, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Layer& lay, size_t level=0);
+        StatusCode processNode(const Layer& lay, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Surface&, size_t level=0);
+        StatusCode processNode(const Surface&, size_t level=0) const;
 
-        std::ofstream               m_outputFile;
+        mutable std::ofstream       m_outputFile;
         std::string                 m_outputFileName;  //!< where the tree is written to  
         int                         m_outputPrecision;
-        bool                        m_firstLayerWritten;
+        mutable bool                m_firstLayerWritten;
 
     };
 }
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryTTreeDumper.h b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryTTreeDumper.h
index a7fc2e844c7745b84766a327a2d97a934f909059..58cf1359645df88719c77414882d9d22b42ea875 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryTTreeDumper.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryTTreeDumper.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -45,15 +45,15 @@ namespace Trk {
       private:
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const TrackingVolume& tvol, size_t level=0);
+        StatusCode processNode(const TrackingVolume& tvol, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Layer& lay, size_t level=0);
+        StatusCode processNode(const Layer& lay, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Surface&, size_t level=0);
+        StatusCode processNode(const Surface&, size_t level=0) const;
 
-        TTree*              m_currentTree; //!< the tree for the currently processed tracking Volume
+        mutable TTree*      m_currentTree; //!< the tree for the currently processed tracking Volume
         std::string         m_treeFolder;  //!< where the tree is written to  
 
     };
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/LayerMaterialInspector.h b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/LayerMaterialInspector.h
index 4a16e07bef87148887e09f98eaf892ee19601bba..d3f5d98987b4a5836c518432a1baa0dad082efe8 100755
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/LayerMaterialInspector.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/LayerMaterialInspector.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -43,14 +43,14 @@ namespace Trk {
       private:
 
         /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-        virtual StatusCode processNode(const TrackingVolume& tvol, size_t level = 0);
+        virtual StatusCode processNode(const TrackingVolume& tvol, size_t level = 0) const;
        
         /** Processor Action to work on Layers */
-        virtual StatusCode processNode(const Layer& lay, size_t level = 0);
+        virtual StatusCode processNode(const Layer& lay, size_t level = 0) const;
        
         /** Processor Action to work on Surfaces */
-        virtual StatusCode processNode(const Surface& surf, size_t level = 0);
-      
+        virtual StatusCode processNode(const Surface& surf, size_t level = 0) const;
+     
         std::string m_treeFolder;
         
     };
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/RecursiveGeometryProcessor.h b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/RecursiveGeometryProcessor.h
index b5885f61cb78289d6fabd113c78fa32dd7dd8198..e6b085000bc7319490d91898026c35d64a82ae57 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/RecursiveGeometryProcessor.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/RecursiveGeometryProcessor.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -49,28 +49,28 @@ namespace Trk {
         StatusCode finalize();
        
         /** Processor Action to work on TrackingGeometry& tgeo */
-        virtual StatusCode process(const TrackingGeometry& tgeo);
+        virtual StatusCode process(const TrackingGeometry& tgeo) const;
        
         /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-        virtual StatusCode process(const TrackingVolume& tvol, size_t level = 0);   
+        virtual StatusCode process(const TrackingVolume& tvol, size_t level = 0) const;
        
         /** Processor Action to work on Layers */
-        virtual StatusCode process(const Layer& lay, size_t level = 0);
+        virtual StatusCode process(const Layer& lay, size_t level = 0) const;
        
         /** Processor Action to work on Surfaces */
-        virtual StatusCode process(const Surface& surf, size_t level = 0);
+        virtual StatusCode process(const Surface& surf, size_t level = 0) const;
      
       protected:
         /** Dedicated action for the different processors */
        
         /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-        virtual StatusCode processNode(const TrackingVolume& tvol, size_t level = 0);
+        virtual StatusCode processNode(const TrackingVolume& tvol, size_t level = 0) const;
        
         /** Processor Action to work on Layers */
-        virtual StatusCode processNode(const Layer& lay, size_t level = 0);
+        virtual StatusCode processNode(const Layer& lay, size_t level = 0) const;
        
         /** Processor Action to work on Surfaces */
-        virtual StatusCode processNode(const Surface& surf, size_t level = 0);
+        virtual StatusCode processNode(const Surface& surf, size_t level = 0) const;
          
 
 
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/TrackingVolumeDisplayer.h b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/TrackingVolumeDisplayer.h
index c3ff2245c7651d052e609762e733c41e2769849c..e23b641efb4871eee78ace1b547af77bc034a1eb 100755
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/TrackingVolumeDisplayer.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/TrackingVolumeDisplayer.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -49,13 +49,13 @@ namespace Trk {
       private:
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const TrackingVolume& tvol, size_t level=0);
+        StatusCode processNode(const TrackingVolume& tvol, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Layer& lay, size_t level=0);
+        StatusCode processNode(const Layer& lay, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Surface&, size_t level=0);
+        StatusCode processNode(const Surface&, size_t level=0) const;
 
         void openFile(std::ofstream& output, const std::string& filename) const;  //!< File handling: open + write header
         void closeFile(std::ofstream& output) const;                              //!< File handling: write footer + close
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryAsciiDumper.cxx b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryAsciiDumper.cxx
index afb550433ab8d546e0d7a7cafd894d5c4b246ebc..723f5a871d7d432f89f911bfaa17bd98d7173810 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryAsciiDumper.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryAsciiDumper.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -57,7 +57,7 @@ StatusCode Trk::GeometryAsciiDumper::finalize()
 
 
 
-StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::TrackingVolume& tvol, size_t level)
+StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::TrackingVolume& tvol, size_t level) const
 {
 
    ATH_MSG_VERBOSE("Dumping information for TrackingVolume.");
@@ -95,7 +95,7 @@ StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::TrackingVolume& tvol
 }
 
 
-StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::Layer& lay, size_t level)
+StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::Layer& lay, size_t level) const
 {
     
     ATH_MSG_VERBOSE("Dumping information for Layer.");
@@ -121,7 +121,7 @@ StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::Layer& lay, size_t l
 }
 
 
-StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::Surface& sf, size_t level)
+StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::Surface& sf, size_t level) const
 {
     ATH_MSG_VERBOSE("Dumping information for Surfaces.");
     std::stringstream levelBuffer;
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryJsonDumper.cxx b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryJsonDumper.cxx
index 264061da3926321e13b1bd006e69417907503b95..43d78d6609e61e3e94dcf547f5572077dc4f5bc4 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryJsonDumper.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryJsonDumper.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -59,13 +59,13 @@ StatusCode Trk::GeometryJsonDumper::finalize()
 
 
 
-StatusCode Trk::GeometryJsonDumper::processNode(const Trk::TrackingVolume& /*tvol*/, size_t /*level*/)
+StatusCode Trk::GeometryJsonDumper::processNode(const Trk::TrackingVolume& /*tvol*/, size_t /*level*/) const
 {
    return StatusCode::SUCCESS;
 }
 
 
-StatusCode Trk::GeometryJsonDumper::processNode(const Trk::Layer& lay, size_t /*level*/)
+StatusCode Trk::GeometryJsonDumper::processNode(const Trk::Layer& lay, size_t /*level*/) const
 {
     
     ATH_MSG_VERBOSE("Dumping information for Layer with index " << lay.layerIndex().value());
@@ -112,7 +112,7 @@ StatusCode Trk::GeometryJsonDumper::processNode(const Trk::Layer& lay, size_t /*
 }
 
 
-StatusCode Trk::GeometryJsonDumper::processNode(const Trk::Surface& /*sf*/, size_t /*level*/)
+StatusCode Trk::GeometryJsonDumper::processNode(const Trk::Surface& /*sf*/, size_t /*level*/) const
 {
     ATH_MSG_VERBOSE("Dumping information for Surfaces.");
     
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryTTreeDumper.cxx b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryTTreeDumper.cxx
index 361f41fd997da6e26c077e84d27e99b2a0db4e65..235a3b74adb3296bafffbcbe9d7da385bf9df8ac 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryTTreeDumper.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryTTreeDumper.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -33,7 +33,7 @@ Trk::GeometryTTreeDumper::~GeometryTTreeDumper()
 {}
 
 
-StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::TrackingVolume& tvol, size_t)
+StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::TrackingVolume& tvol, size_t) const
 {
    ATH_MSG_VERBOSE("Dumping information for TrackingVolume.");
    // clean up from the previous event
@@ -73,7 +73,7 @@ StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::TrackingVolume& tvol
 }
 
 
-StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::Layer& lay, size_t)
+StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::Layer& lay, size_t) const
 {
     
     ATH_MSG_VERBOSE("Dumping information for Layer.");
@@ -90,7 +90,7 @@ StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::Layer& lay, size_t)
 }
 
 
-StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::Surface& sf, size_t)
+StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::Surface& sf, size_t) const
 {
     ATH_MSG_VERBOSE("Dumping information for Surfaces.");
 
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/LayerMaterialInspector.cxx b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/LayerMaterialInspector.cxx
index 960ee66c1b9ec63aa8d750b86ae4da078940521a..a3efa72db2145047228b4564b84627da883c5bb0 100755
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/LayerMaterialInspector.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/LayerMaterialInspector.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -33,12 +33,12 @@ Trk::LayerMaterialInspector::LayerMaterialInspector(const std::string& t, const
 Trk::LayerMaterialInspector::~LayerMaterialInspector()
 {}
 
-StatusCode Trk::LayerMaterialInspector::processNode(const Trk::TrackingVolume& , size_t)
+StatusCode Trk::LayerMaterialInspector::processNode(const Trk::TrackingVolume& , size_t) const
 {
   return StatusCode::SUCCESS;
 }  
 
-StatusCode Trk::LayerMaterialInspector::processNode(const Trk::Layer& lay, size_t)
+StatusCode Trk::LayerMaterialInspector::processNode(const Trk::Layer& lay, size_t) const
 {
     
     const Trk::TrackingVolume* tvol = lay.enclosingTrackingVolume();
@@ -152,7 +152,7 @@ StatusCode Trk::LayerMaterialInspector::processNode(const Trk::Layer& lay, size_
     return StatusCode::SUCCESS;    
 }
 
-StatusCode Trk::LayerMaterialInspector::processNode(const Trk::Surface& , size_t)
+StatusCode Trk::LayerMaterialInspector::processNode(const Trk::Surface& , size_t) const
 {
   return StatusCode::SUCCESS;
 }  
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/RecursiveGeometryProcessor.cxx b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/RecursiveGeometryProcessor.cxx
index 841be93c2bbe058f2f298c96861ad4ae7d23c946..1fe9d38a6c1e62ec583fa0b7892a23d70c452a38 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/RecursiveGeometryProcessor.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/RecursiveGeometryProcessor.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -43,7 +43,7 @@ StatusCode Trk::RecursiveGeometryProcessor::finalize()
 }
 
 // Processor Action to work on TrackingGeometry 
-StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::TrackingGeometry& tgeo) {
+StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::TrackingGeometry& tgeo) const {
   
   ATH_MSG_VERBOSE("Start processing the TrackingGeometry recursively");
   // retrieve the highest tracking volume
@@ -58,7 +58,7 @@ StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::TrackingGeometry&
 }
 
 // Processor Action to work on TrackingVolumes
-StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::TrackingVolume& tvol, size_t level) {
+StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::TrackingVolume& tvol, size_t level) const {
   
   std::stringstream displayBuffer;
   for (size_t il = 0; il < level; ++il) displayBuffer << " ";
@@ -121,7 +121,7 @@ StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::TrackingVolume& t
 }
 
 // Processor Action to work on Layers 
-StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::Layer& lay, size_t level) {
+StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::Layer& lay, size_t level) const {
 
     std::stringstream displayBuffer;
     for (size_t il = 0; il < level; ++il) displayBuffer << " ";
@@ -155,20 +155,20 @@ StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::Layer& lay, size_
 }
 
 // Processor Action to work on Surfaces 
-StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::Surface& surf, size_t level) {
+StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::Surface& surf, size_t level) const {
     return processNode(surf, level);
 }
 
 // Processor Action to work on TrackingVolume - to be overloaded 
-StatusCode Trk::RecursiveGeometryProcessor::processNode(const Trk::TrackingVolume&, size_t ) {
+StatusCode Trk::RecursiveGeometryProcessor::processNode(const Trk::TrackingVolume&, size_t ) const {
     return StatusCode::SUCCESS;
 }
 
 // Processor Action to work on Layers - to be overloaded 
-StatusCode Trk::RecursiveGeometryProcessor::processNode(const Trk::Layer&, size_t ) {
+StatusCode Trk::RecursiveGeometryProcessor::processNode(const Trk::Layer&, size_t ) const {
     return StatusCode::SUCCESS;
 }
 // Processor Action to work on Surfaces - to be overloaded
-StatusCode Trk::RecursiveGeometryProcessor::processNode(const Trk::Surface&, size_t ) {
+StatusCode Trk::RecursiveGeometryProcessor::processNode(const Trk::Surface&, size_t ) const {
     return StatusCode::SUCCESS;
 }
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/TrackingVolumeDisplayer.cxx b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/TrackingVolumeDisplayer.cxx
index 6cecce2e0fafd68f2930ec2118ac34da5c621a4a..a90f95cfec6d9c364391e2f58e0c9e6e29d4d0d9 100755
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/TrackingVolumeDisplayer.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/TrackingVolumeDisplayer.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -125,7 +125,7 @@ void Trk::TrackingVolumeDisplayer::closeFile(std::ofstream& out) const
 }
 
 
-StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::TrackingVolume& tvol, size_t)
+StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::TrackingVolume& tvol, size_t) const
 {
 
     ATH_MSG_VERBOSE("Writing display information for TrackingVolume.");
@@ -163,7 +163,7 @@ StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::TrackingVolume&
 }
 
 
-StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::Layer& lay, size_t)
+StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::Layer& lay, size_t) const
 {
     
     ATH_MSG_VERBOSE("Writing display information for Layer.");
@@ -256,7 +256,7 @@ StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::Layer& lay, size
 }
 
 
-StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::Surface& sf, size_t)
+StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::Surface& sf, size_t) const
 {
 
     ++s_displaySurfaces;
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GenericGeometryBuilderCond.h b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GenericGeometryBuilderCond.h
new file mode 100644
index 0000000000000000000000000000000000000000..0e3e2aa1c92183f95e1fd828a795e0b9f2fdb967
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GenericGeometryBuilderCond.h
@@ -0,0 +1,83 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// GenericGeometryBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef TRKDETDESCRTOOLS_GENERICGEOMETRYBUILDERCOND_H
+#define TRKDETDESCRTOOLS_GENERICGEOMETRYBUILDERCOND_H
+
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// Trk
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrUtils/GeometrySignature.h"
+
+// Gaudi & Athena
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+
+class IEnvelopeDefSvc;
+
+namespace Trk {
+
+    class TrackingGeometry;
+    class TrackingVolume;
+    class ITrackingVolumeCreator;   
+    class ITrackingVolumeHelper;   
+
+    /** @class GenericGeometryBuilderCond
+
+      A TrackingGeometry builder that takes the EnvelopSvc and creates 
+      a very simple generic tracking geoemtry configured with Layers
+      
+      @author Andreas.Salzburger@cern.ch   
+     */
+
+    class GenericGeometryBuilderCond : public AthAlgTool, virtual public IGeometryBuilderCond {
+
+      public:
+        /** Constructor */
+        GenericGeometryBuilderCond(const std::string&,const std::string&,const IInterface*);
+        
+        /** Destructor */
+        virtual ~GenericGeometryBuilderCond();
+
+        /** AlgTool initialize method */
+        StatusCode initialize();
+        
+        /** AlgTool finalize method */
+        StatusCode finalize();
+        
+        /** TrackingGeometry Interface method - optionally a pointer to Bounds */
+        std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const;
+
+        /** The unique signature */
+        GeometrySignature geometrySignature() const;
+
+      private:
+        ServiceHandle<IEnvelopeDefSvc>          m_enclosingEnvelopeSvc;         //!< The service that determines the outermost boundaries
+        int                                     m_enclosingEnvelope;            //!< define which service you wanna have
+                                                                                
+        ToolHandle<Trk::ITrackingVolumeCreator> m_trackingVolumeCreator;        //!< Helper Tool to create TrackingVolumes
+                                                                                
+        int                                     m_geometrySignature;            //!< should hopefully correspond soon to the enclosing envelope
+        std::string                             m_geometryName;                 //!< name for the volumes
+        int                                     m_geometryColorCode;            //!< ->registerColorCode()
+        
+        double                                  m_barrelFraction;               //!< Barrel configuration                                                                        
+        int                                     m_barrelLayers;                 //!< Barrel configuration
+        int                                     m_endcapLayers;                 //!< Endcap configuration
+        mutable bool                            m_extendedEndcap;               //!< extended Endcap configuration
+        int                                     m_extendedEndcapLayers;         //!< extended Endcap configuration
+
+    };
+    
+    inline GeometrySignature GenericGeometryBuilderCond::geometrySignature() const { return (GeometrySignature)m_geometrySignature; }
+
+} // end of namespace
+
+#endif // TRKDETDESCRTOOLS_GENERICGEOMETRYBUILDERCOND_H
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GeometryBuilderCond.h b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GeometryBuilderCond.h
new file mode 100755
index 0000000000000000000000000000000000000000..15aea0b5cace88f5ffff9e65a9f8fbc74ccc02ec
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GeometryBuilderCond.h
@@ -0,0 +1,107 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// GeometryBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef TRKDETDESCRTOOLS_GEOMETRYBUILDERCOND_H
+#define TRKDETDESCRTOOLS_GEOMETRYBUILDERCOND_H
+
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// Trk
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrUtils/GeometrySignature.h"
+#include "TrkGeometry/TrackingVolumeManipulator.h"
+#include "TrkGeometry/Material.h"
+// Gaudi & Athena
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+
+#ifdef TRKDETDESCR_MEMUSAGE   
+#include "TrkDetDescrUtils/MemoryLogger.h"
+#endif  
+
+namespace Trk {
+
+    class TrackingGeometry;
+    class TrackingVolume;
+    class ITrackingVolumeBuilder;
+    class ITrackingVolumeHelper;
+    class ITrackingVolumeArrayCreator;
+
+    /** @class GeometryBuilderCond
+
+      The Trk::TrackingGeometry Builder for ATLAS Geometry
+
+      It retrieves Trk::TrackingGeometry builders for the subdetectors and joins them together 
+      to a single Trk::TrackingGeometry.
+
+      @author Andreas.Salzburger@cern.ch   
+     */
+
+    class GeometryBuilderCond : public AthAlgTool,
+                            public TrackingVolumeManipulator,
+                    virtual public IGeometryBuilderCond {
+
+      public:
+        /** Constructor */
+        GeometryBuilderCond(const std::string&,const std::string&,const IInterface*);
+        
+        /** Destructor */
+        virtual ~GeometryBuilderCond();
+
+        /** AlgTool initialize method */
+        StatusCode initialize();
+        
+        /** AlgTool finalize method */
+        StatusCode finalize();
+        
+        /** TrackingGeometry Interface method - optionally a pointer to Bounds */
+        std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const;
+
+        /** The unique signature */
+        GeometrySignature geometrySignature() const { return Trk::Global; }
+
+      private:
+
+        /** TrackingGeometry for ATLAS setup */
+        std::pair<EventIDRange, const Trk::TrackingGeometry*> atlasTrackingGeometry(const EventContext& ctx) const;
+
+#ifdef TRKDETDESCR_MEMUSAGE         
+        MemoryLogger                        m_memoryLogger;                //!< in case the memory is logged
+#endif      
+
+        bool                                m_createWorld;                 //!< Boolean Switch to create World manually
+        int                                 m_navigationLevel;             //!< NavigationLevel
+
+        std::vector< double >               m_worldDimension;              //!< The dimensions of the manually created world
+        std::vector< double >               m_worldMaterialProperties;     //!< The material properties of the created world
+        Material                            m_worldMaterial;               //!< the world material
+
+        // -------------------------- Tools for geometry building ------------------------------------------------------ //
+
+        ToolHandle<ITrackingVolumeArrayCreator>   m_trackingVolumeArrayCreator;       //!< Helper Tool to create TrackingVolume Arrays
+
+        ToolHandle<ITrackingVolumeHelper>         m_trackingVolumeHelper;             //!< Helper Tool to create TrackingVolumes
+
+        //bool                                      m_inDetGeometry;                     //!< switch on TrackingGeometry for the InnerDetector
+        ToolHandle<IGeometryBuilderCond>              m_inDetGeometryBuilderCond;              //!< GeometryBuilderCond for the InnerDetector
+
+        bool                                      m_caloGeometry;                     //!< switch on TrackingGeometry for the Calorimeters
+        ToolHandle<IGeometryBuilderCond>              m_caloGeometryBuilderCond;              //!< GeometryBuilderCond for the Calorimeters
+
+        bool                                      m_muonGeometry;                     //!< GeometryBuilderCond for the Muon System
+        ToolHandle<IGeometryBuilderCond>              m_muonGeometryBuilderCond;              //!< GeometryBuilderCond for the Muon System
+        
+        bool                                      m_compactify;                       //!< optimize event memory usage: register all surfaces with TG
+        bool                                      m_synchronizeLayers;                //!< synchronize contained layer dimensions to volumes
+
+    };
+
+} // end of namespace
+
+#endif // TRKDETDESCRTOOLS_GEOMETRYBUILDERCOND_H
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/InputLayerMaterialProvider.h b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/InputLayerMaterialProvider.h
index 55ca754bfdfdef8fe88f2f8be7b7ec4d516ca7d7..12ee4de10dd34c627da6417f6a4295747c9d4979 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/InputLayerMaterialProvider.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/InputLayerMaterialProvider.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -45,16 +45,16 @@ namespace Trk {
         virtual StatusCode initialize();
 
         /** Processor Action to work on TrackingGeometry& tgeo */
-        virtual StatusCode process(const TrackingGeometry& tgeo);
+        virtual StatusCode process(const TrackingGeometry& tgeo) const;
        
         /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-        virtual StatusCode process(const TrackingVolume& tvol, size_t level = 0);   
+        virtual StatusCode process(const TrackingVolume& tvol, size_t level = 0) const;
        
         /** Processor Action to work on Layers */
-        virtual StatusCode process(const Layer& lay, size_t level = 0);
+        virtual StatusCode process(const Layer& lay, size_t level = 0) const;
        
         /** Processor Action to work on Surfaces */
-        virtual StatusCode process(const Surface& surf, size_t level = 0);
+        virtual StatusCode process(const Surface& surf, size_t level = 0) const;
 
       private:
          bool               m_constantMaterialToAllLayers;  //!< just assign a dummy material to all layers
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerMaterialProvider.h b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerMaterialProvider.h
index 90e1553759c59599a31dc9ae03477a6e8d77ca8f..69f164d1feef58446b3680e19e900dd68df670cb 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerMaterialProvider.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerMaterialProvider.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -42,23 +42,25 @@ namespace Trk {
         virtual ~LayerMaterialProvider();
 
         /** Processor Action to work on TrackingGeometry& tgeo */
-        virtual StatusCode process(const TrackingGeometry& tgeo);
+        virtual StatusCode process(const TrackingGeometry& tgeo) const;
        
         /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-        virtual StatusCode process(const TrackingVolume& tvol, size_t level = 0);   
+        virtual StatusCode process(const TrackingVolume& tvol, size_t level = 0) const;
        
         /** Processor Action to work on Layers */
-        virtual StatusCode process(const Layer& lay, size_t level = 0);
+        virtual StatusCode process(const Layer& lay, size_t level = 0) const;
        
         /** Processor Action to work on Surfaces */
-        virtual StatusCode process(const Surface& surf, size_t level = 0);
+        virtual StatusCode process(const Surface& surf, size_t level = 0) const;
 
       private:
           
-        StatusCode loadMaterialMap();               //!< reatrieve the Material map from the detector store
+        StatusCode loadMaterialMap() const;               //!< reatrieve the Material map from the detector store
 
         //!< boolean switch for assignLayerMaterial
-        mutable const LayerMaterialMap*             m_layerMaterialMap;
+
+        mutable std::once_flag                      m_loadMapOnceFlag ATLAS_THREAD_SAFE;
+        mutable const LayerMaterialMap*             m_layerMaterialMap ATLAS_THREAD_SAFE;
         std::string                                 m_layerMaterialMapName;
                         
         
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerProviderCond.h b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerProviderCond.h
new file mode 100644
index 0000000000000000000000000000000000000000..95850128548239529dd7607119ab28b3c7a17e2a
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerProviderCond.h
@@ -0,0 +1,72 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// LayerProviderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef TRKDETDESCRTOOLS_LAYERPROVIDERCOND_H
+#define TRKDETDESCRTOOLS_LAYERPROVIDERCOND_H
+
+// Trk
+#include "TrkDetDescrInterfaces/ILayerProviderCond.h"
+// Gaudi & Athena
+#include "GaudiKernel/ToolHandle.h"
+#include "AthenaBaseComps/AthAlgTool.h"
+
+
+namespace Trk {
+
+    class Layer;
+    class ILayerBuilderCond;
+
+
+    /** @class LayerProviderCond
+
+      Wrapper around an ILayerBuilderCond to feed into the StagedGeometryBuilder
+
+      @author Andreas.Salzburger@cern.ch
+     */
+
+    class LayerProviderCond :  public AthAlgTool, virtual public ILayerProviderCond {
+     
+      public:
+        /** Constructor */
+        LayerProviderCond(const std::string&,const std::string&,const IInterface*);
+
+        /** Destructor */
+        virtual ~LayerProviderCond();
+        
+        /** initialize */
+        StatusCode initialize();
+        
+        /** finalize */
+        StatusCode finalize();
+
+        /** LayerBuilder interface method - returning the layers at negative side */
+        std::pair<EventIDRange, const std::vector< const Layer* > > negativeLayers(const EventContext& ctx) const; 
+      
+        /** LayerBuilder interface method - returning the central layers */
+        std::pair<EventIDRange, const std::vector< const Layer* > > centralLayers(const EventContext& ctx) const; 
+      
+        /** LayerBuilder interface method - returning the layers at negative side */
+        std::pair<EventIDRange, const std::vector< const Layer* > > positiveLayers(const EventContext& ctx) const; 
+
+        /** Name identification */
+        const std::string& identification() const;
+
+      private:
+        /** LayerBuilder interface method - returning the layers at negative side */
+        std::pair<EventIDRange, const std::vector< const Layer* > > discLayers(const EventContext& ctx, int posneg) const;   
+      
+        ToolHandle<ILayerBuilderCond>           m_layerBuilder;
+        mutable std::vector<const Trk::Layer*>  m_layerCache;
+        
+    };
+
+
+} // end of namespace
+
+#endif // TRKDETDESCRTOOLS_LAYERPROVIDERCOND_H
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/src/GenericGeometryBuilderCond.cxx b/Tracking/TrkDetDescr/TrkDetDescrTools/src/GenericGeometryBuilderCond.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f65cdef1ce26412622aa5a9a53f2284ab16266c7
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/src/GenericGeometryBuilderCond.cxx
@@ -0,0 +1,281 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// GenericGeometryBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+// EnvelopeDefinitionService
+#include "SubDetectorEnvelopes/IEnvelopeDefSvc.h"
+// Trk include
+#include "TrkDetDescrTools/GenericGeometryBuilderCond.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeCreator.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeHelper.h"
+#include "TrkVolumes/CylinderVolumeBounds.h"
+#include "TrkGeometry/TrackingVolume.h"
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkGeometry/Material.h"
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// STD
+#include <map>
+// Gaudi
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/SystemOfUnits.h"
+
+
+// constructor
+Trk::GenericGeometryBuilderCond::GenericGeometryBuilderCond(const std::string& t, const std::string& n, const IInterface* p)
+: AthAlgTool(t,n,p),
+  m_enclosingEnvelopeSvc("AtlasEnvelopeDefSvc", n),      
+  m_enclosingEnvelope(0),         
+  m_trackingVolumeCreator(""),
+  m_geometrySignature(0),
+  m_geometryName("Undefined"),
+  m_geometryColorCode(8),
+  m_barrelFraction(0.75),         
+  m_barrelLayers(10),         
+  m_endcapLayers(20),       
+  m_extendedEndcap(false),            
+  m_extendedEndcapLayers(5)
+{
+    // declare the interface
+    declareInterface<Trk::IGeometryBuilderCond>(this);
+    // Tools & Services
+    declareProperty("EnvelopeDefinitionSvc",        m_enclosingEnvelopeSvc);      
+    declareProperty("Envelope",                     m_enclosingEnvelope);         
+    declareProperty("TrackingVolumeCreator",        m_trackingVolumeCreator);  
+    // configuration                                
+    declareProperty("GeometrySignature",            m_geometrySignature);
+    declareProperty("GeometryName",                 m_geometryName);
+    declareProperty("GeometryColorCode",            m_geometryColorCode);
+    // Barrel Layer configuration                   
+    declareProperty("BarrelFraction",               m_barrelFraction);              
+    declareProperty("BarrelLayers",                 m_barrelLayers);              
+    // Endcap Layer configuration                   
+    declareProperty("EndcapLayers",                 m_endcapLayers);             
+    // Extended endcap Layer configuration 
+    declareProperty("ExtendedEndcap",               m_extendedEndcap);            
+    declareProperty("ExtendedEndcapLayers",         m_extendedEndcapLayers);      
+}
+
+// destructor
+Trk::GenericGeometryBuilderCond::~GenericGeometryBuilderCond()
+{}
+
+// Athena standard methods - initialize
+StatusCode Trk::GenericGeometryBuilderCond::initialize()
+{
+    // Retrieve the volume array creator  ----------------------------------------------------
+    if (m_enclosingEnvelopeSvc.retrieve().isFailure()) {
+        ATH_MSG_FATAL("Failed to retrieve EnvelopeSvc " << m_enclosingEnvelopeSvc );
+        return StatusCode::FAILURE;
+    } else 
+        ATH_MSG_INFO( "Retrieved " << m_enclosingEnvelopeSvc );
+
+    // Retrieve the tracking volume creator  --------------------------------------------------    
+    if (m_trackingVolumeCreator.retrieve().isFailure()) {
+        ATH_MSG_FATAL("Failed to retrieve tool " << m_trackingVolumeCreator );
+        return StatusCode::FAILURE;
+    } else 
+        ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeCreator );
+
+    ATH_MSG_INFO( " initialize() successful" );
+    return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode Trk::GenericGeometryBuilderCond::finalize()
+{
+    ATH_MSG_INFO( "finalize() successful." );
+    return StatusCode::SUCCESS;
+}
+
+
+std::pair<EventIDRange, const Trk::TrackingGeometry*> Trk::GenericGeometryBuilderCond::trackingGeometry(const EventContext& /*ctx*/, std::pair< EventIDRange, const Trk::TrackingVolume*> innerVolPair) const
+{
+
+    ATH_MSG_VERBOSE("Starting to build TrackingGeometry for GeometrySignature : " << m_geometrySignature );
+
+    // the geometry to be constructed
+    const Trk::TrackingGeometry* tGeometry = 0;
+    
+    double innerVolumeRadius             = 0.;
+    double innerVolumeHalfZ              = 0.;
+    double enclosingVolumeRadius         = 0.;
+    double enclosingVolumeHalfZ          = 0.;
+    double enclosingExtendedVolumeRadius = 0.;
+    double enclosingExtendedVolumeHalfZ  = 0.;
+
+    // vacuum
+    Trk::Material vacuum;
+    
+    RZPairVector envelopeDefs;  
+    // build the inner detector if configured
+    if (m_geometrySignature == Trk::ID){
+        // get the dimensions from the envelope service 
+        envelopeDefs = m_enclosingEnvelopeSvc->getInDetRZValues();
+        ATH_MSG_VERBOSE("       -> retrieved Inner Detector envelope definitions at size " << envelopeDefs.size());
+    } else if ( m_geometrySignature == Trk::Calo  ){
+        // get the dimensions from the envelope service 
+        envelopeDefs = m_enclosingEnvelopeSvc->getCaloRZValues();
+        ATH_MSG_VERBOSE("       -> retrieved Calorimeter envelope definitions at size " << envelopeDefs.size());
+    } else if ( m_geometrySignature == Trk::MS ) {
+        // get the dimensions from the envelope service 
+        envelopeDefs = m_enclosingEnvelopeSvc->getMuonRZValues();
+        ATH_MSG_VERBOSE("       -> retrieved Muon System envelope definitions at size " << envelopeDefs.size());
+    } else {
+        ATH_MSG_WARNING("No geometry signature found, return 0.");
+        //dummy infinite range
+        EventIDRange range;
+        return std::make_pair(range,tGeometry);
+    }
+
+    // ------------------------------- overall dimensions ----------------------------------------------
+    // get the maximum extend in R
+    for ( auto& rzIter : envelopeDefs){
+        if ( rzIter.first > enclosingVolumeRadius ) {
+            // maximal r-extend
+            enclosingVolumeRadius = rzIter.first;
+            enclosingVolumeHalfZ  = fabs(rzIter.second);            
+        }
+    }
+    ATH_MSG_VERBOSE("       -> Overall dimensions estimated as (r,hZ) = " << enclosingVolumeRadius << ", " << enclosingVolumeHalfZ);
+    
+    // we need to build extended barrels ---------------------------------------------------------------
+    if ( m_extendedEndcap && envelopeDefs.size() > 4){
+        ATH_MSG_VERBOSE("       -> configured to build extended Barrel, checking for RZpair direction.");
+        // find out the direction of the rz points point
+        Amg::Vector3D p1(envelopeDefs[0].second,envelopeDefs[0].first, 0.);
+        Amg::Vector3D p2(envelopeDefs[1].second,envelopeDefs[1].first, 0.);
+        int clockwise = p1.cross(p2).z() < 0. ? 1 : -1;
+        ATH_MSG_VERBOSE("       -> determined " << ( clockwise>0 ? "clockwise" : "anti-clockwise") << " direction from (z1,r1) = " 
+            << envelopeDefs[0].second << ", " << envelopeDefs[0].first << " and " << envelopeDefs[1].second << ", " << envelopeDefs[1].first );
+        // now parse for the extended barrel  
+        size_t irz = 0;  
+        for ( auto& rzIter : envelopeDefs){
+            if (irz > 1 && rzIter.second > 0 && rzIter.first >= enclosingVolumeRadius ) {
+                // maximal r-extend
+                enclosingExtendedVolumeRadius = envelopeDefs[irz-clockwise*2].first;
+                enclosingExtendedVolumeHalfZ  = envelopeDefs[irz-clockwise*2].second;            
+            }
+            ++irz;
+        }
+        ATH_MSG_VERBOSE("       -> Extended dimensions estimated as (r,hZ) = " << enclosingExtendedVolumeRadius << ", " << enclosingExtendedVolumeHalfZ);
+            
+    } else {
+        ATH_MSG_WARNING("Could not parse dimensions for extended Barrel, ignoring it.");
+        m_extendedEndcap = false;
+    }
+    // --------------------------------------------------------------------------------------------------
+
+    //generic detector has infinite alignment validity range or if exists of input volume
+    EventIDRange range;
+
+    // get the inner radius and half length if a volume is provided
+    const Trk::CylinderVolumeBounds* cvb = 0;
+    const Trk::TrackingVolume* innerVol = innerVolPair.second;
+    if (innerVol){
+        range = innerVolPair.first;
+        cvb = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(innerVol->volumeBounds()));
+        if (cvb){
+            innerVolumeRadius = cvb->outerRadius();
+            innerVolumeHalfZ  = cvb->halflengthZ();
+            ATH_MSG_VERBOSE("       -> inner cylindrical volume found with (r,hZ) = " << innerVolumeRadius << ", " << innerVolumeHalfZ);
+        } 
+    }
+    if (!cvb){
+       // if no suitable inner volume is given, divide into the configured barrel fraction
+       innerVolumeHalfZ = m_barrelFraction*0.5*enclosingVolumeHalfZ;
+       ATH_MSG_VERBOSE("       -> no (suitable) inner volume found, setting barrel/endcap fraction as configured.");
+       
+    }
+
+    // now create the barrel-type volume wrapping around the  inner volume
+    const Trk::TrackingVolume* cSector = m_trackingVolumeCreator->createGapTrackingVolume(vacuum,
+                                                                                         innerVolumeRadius, enclosingVolumeRadius,
+                                                                                         -innerVolumeHalfZ, innerVolumeHalfZ,
+                                                                                         m_barrelLayers,
+                                                                                         true,
+                                                                                         m_geometryName+"::Generic::Barrel");
+    cSector->registerColorCode(m_geometryColorCode);
+    // wrap the inner volume into a centralSector 
+    if (cvb){ 
+        auto centralVolumes = std::vector<const Trk::TrackingVolume*>{innerVol, cSector};
+        // override barrelVolume if enclosing is needed -> memory ownership shifted to container
+        cSector = m_trackingVolumeCreator->createContainerTrackingVolume(centralVolumes,
+                                                                         vacuum,
+                                                                         m_geometryName+"::Containers::Central");
+    }
+    // create the two endcaps
+    const Trk::TrackingVolume* nSector = m_trackingVolumeCreator->createGapTrackingVolume(vacuum,
+                                                                                         0., enclosingVolumeRadius,
+                                                                                         -enclosingVolumeHalfZ, -innerVolumeHalfZ,
+                                                                                         m_endcapLayers,
+                                                                                         false,
+                                                                                         m_geometryName+"::Generic::NegativeEndcap");
+    nSector->registerColorCode(m_geometryColorCode);
+    // create the two endcaps
+    const Trk::TrackingVolume* pSector = m_trackingVolumeCreator->createGapTrackingVolume(vacuum,
+                                                                                         0., enclosingVolumeRadius,
+                                                                                         innerVolumeHalfZ, enclosingVolumeHalfZ,
+                                                                                         m_endcapLayers,
+                                                                                         false,
+                                                                                         m_geometryName+"::Generic::PositiveEndcap");
+    pSector->registerColorCode(m_geometryColorCode);
+    
+    auto allVolumes = std::vector<const Trk::TrackingVolume*>();
+    // if extended barrel is to be built
+    auto extendedVolumes = std::vector<const Trk::TrackingVolume*>();
+    if ( m_extendedEndcap){
+        auto names = std::vector<std::string>{ "Negative", "Positive"};
+        for ( size_t it = 0; it < 2; ++it){ 
+          // which side we are
+          double minZ = !it ? -enclosingExtendedVolumeHalfZ : enclosingVolumeHalfZ;
+          double maxZ = !it ? -enclosingVolumeHalfZ : enclosingExtendedVolumeHalfZ;  
+          // create the extended volume (bottom part)
+          const Trk::TrackingVolume* exVolume = m_trackingVolumeCreator->createGapTrackingVolume(
+                                                                                vacuum,
+                                                                                0., enclosingExtendedVolumeRadius,
+                                                                                minZ, maxZ,
+                                                                                m_extendedEndcapLayers,
+                                                                                false,
+                                                                                m_geometryName+"::Generic::Extended"+names[it]);
+          exVolume->registerColorCode(m_geometryColorCode);
+          // create the extended volume (ring part)
+          const Trk::TrackingVolume* exrVolume = m_trackingVolumeCreator->createGapTrackingVolume(
+                                                                                vacuum,
+                                                                                enclosingExtendedVolumeRadius, enclosingVolumeRadius,
+                                                                                minZ, maxZ,
+                                                                                m_extendedEndcapLayers,
+                                                                                false,
+                                                                                m_geometryName+"::Generic::RingExtended"+names[it]);
+          // sign it with one higher volume id 
+          exrVolume->sign( Trk::GeometrySignature(int(geometrySignature())+1) );
+          // pack it into a container
+          auto exVolumes = std::vector<const Trk::TrackingVolume*>{exVolume, exrVolume};
+          const Trk::TrackingVolume* exSector = m_trackingVolumeCreator->createContainerTrackingVolume(exVolumes,
+                                                                                                       vacuum,
+                                                                                                       m_geometryName+"::Generic::"+names[it]+"ExtendedEndcap");
+          // for the overall geometry                                                                     
+          extendedVolumes.push_back(exSector);                                                                    
+       }
+    }
+    // and now create the triple
+    allVolumes = extendedVolumes.size() ?  std::vector<const Trk::TrackingVolume*>{extendedVolumes[0],nSector,cSector,pSector,extendedVolumes[1]} : 
+                                           std::vector<const Trk::TrackingVolume*>{nSector,cSector,pSector};
+    const Trk::TrackingVolume* tVolume = m_trackingVolumeCreator->createContainerTrackingVolume(allVolumes,
+                                                                                                vacuum,
+                                                                                                m_geometryName+"::Container");                                                                                      
+    // now create the TrackingGeometry from the highest volume
+    if (tVolume) {
+      tGeometry = new Trk::TrackingGeometry(tVolume);
+      tGeometry->indexStaticLayers(geometrySignature());   
+    }
+
+
+    return std::make_pair(range, tGeometry);
+
+}
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/src/GeometryBuilderCond.cxx b/Tracking/TrkDetDescr/TrkDetDescrTools/src/GeometryBuilderCond.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..c0d068d95a28e5899cc03540b94aabd6be8b491e
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/src/GeometryBuilderCond.cxx
@@ -0,0 +1,451 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// GeometryBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+// Trk include
+#include "TrkDetDescrTools/GeometryBuilderCond.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeBuilder.h"
+#include "TrkDetDescrInterfaces/ILayerBuilderCond.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeArrayCreator.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeHelper.h"
+#include "TrkVolumes/CylinderVolumeBounds.h"
+#include "TrkGeometry/TrackingVolume.h"
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkGeometry/GlueVolumesDescriptor.h"
+
+#ifdef TRKDETDESCR_MEMUSAGE                            
+#include <unistd.h>
+#endif
+
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// STD
+#include <map>
+// Gaudi
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/SystemOfUnits.h"
+
+
+// constructor
+Trk::GeometryBuilderCond::GeometryBuilderCond(const std::string& t, const std::string& n, const IInterface* p)
+: AthAlgTool(t,n,p),
+  TrackingVolumeManipulator(),
+#ifdef TRKDETDESCR_MEMUSAGE      
+  m_memoryLogger(),
+#endif 
+  m_createWorld(true),
+  m_navigationLevel(2),
+  m_worldDimension(),
+  m_worldMaterialProperties(),
+  m_trackingVolumeArrayCreator("Trk::TrackingVolumeArrayCreator/TrackingVolumeArrayCreator"),
+  m_trackingVolumeHelper("Trk::TrackingVolumeHelper/TrackingVolumeHelper"),
+  m_inDetGeometryBuilderCond("", this),
+  m_caloGeometry{},
+  m_caloGeometryBuilderCond("", this),
+  m_muonGeometry{},
+  m_muonGeometryBuilderCond("", this),
+  m_compactify(true),
+  m_synchronizeLayers(true)
+{
+    declareInterface<IGeometryBuilderCond>(this);
+    // by hand declarations
+    declareProperty("CreateWorldManually",                  m_createWorld);
+    declareProperty("NavigationLevel",                      m_navigationLevel);
+    // (1) dimension & material
+    declareProperty("WorldDimension",                       m_worldDimension);
+    declareProperty("WorldMaterialProperties",              m_worldMaterialProperties);
+    // tool declarations ----------------------------------------------------------------
+    declareProperty("TrackingVolumeArrayCreator",           m_trackingVolumeArrayCreator);
+    declareProperty("TrackingVolumeHelper",                 m_trackingVolumeHelper);
+    declareProperty("InDetTrackingGeometryBuilder",         m_inDetGeometryBuilderCond);
+    declareProperty("CaloTrackingGeometryBuilder",          m_caloGeometryBuilderCond);
+    declareProperty("MuonTrackingGeometryBuilder",          m_muonGeometryBuilderCond);
+    // optimize layer dimension & memory usage -------------------------------
+    declareProperty("Compactify",                           m_compactify );
+    declareProperty("SynchronizeLayers",                    m_synchronizeLayers );
+}
+
+// destructor
+Trk::GeometryBuilderCond::~GeometryBuilderCond()
+{}
+
+
+// Athena standard methods
+// initialize
+StatusCode Trk::GeometryBuilderCond::initialize()
+{
+
+    // Retrieve the volume array creator  ----------------------------------------------------
+    ATH_CHECK(m_trackingVolumeArrayCreator.retrieve()); 
+
+    // Retrieve the tracking volume helper  --------------------------------------------------    
+    ATH_CHECK (m_trackingVolumeHelper.retrieve()); 
+    // Geometries =============================================================================
+    // (I) Inner Detector ---------------------------------------------------------------------
+    if (!m_inDetGeometryBuilderCond.empty()) {
+        ATH_CHECK(m_inDetGeometryBuilderCond.retrieve());
+    }
+    // (C) Calorimeter --------------------------------------------------------------------------
+    if (!m_caloGeometryBuilderCond.empty()) {
+        ATH_CHECK (m_caloGeometryBuilderCond.retrieve());
+    }
+    // (M) Muon System -------------------------------------------------------------------------
+    if (!m_muonGeometryBuilderCond.empty()) {
+        ATH_CHECK(m_muonGeometryBuilderCond.retrieve());
+    }
+
+    // if no world dimensions are declared, take default ones
+    if (!m_worldDimension.size())
+        m_worldDimension = std::vector<double>{0.*Gaudi::Units::meter, 10.*Gaudi::Units::meter, 15.*Gaudi::Units::meter};
+
+    // if no world materials are declared, take default ones - set vacuum 
+    if (m_worldMaterialProperties.size() < 5) 
+        m_worldMaterialProperties = std::vector<double>{10.e10,10.e10,0., 0., 0.};
+
+    m_worldMaterial = Trk::Material(m_worldMaterialProperties[0],
+				    m_worldMaterialProperties[1],
+				    m_worldMaterialProperties[2],
+				    m_worldMaterialProperties[3],
+				    m_worldMaterialProperties[4]);
+
+    ATH_MSG_DEBUG( " initialize() successful" );
+
+    return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode Trk::GeometryBuilderCond::finalize()
+{
+    ATH_MSG_DEBUG( "finalize() successful." );
+    return StatusCode::SUCCESS;
+}
+
+
+std::pair<EventIDRange, const Trk::TrackingGeometry*> Trk::GeometryBuilderCond::trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> /*tVolPair*/) const
+{
+
+    // the geometry to be constructed
+    std::pair<EventIDRange, const Trk::TrackingGeometry*> tGeometry;
+    if ( m_inDetGeometryBuilderCond.empty() && m_caloGeometryBuilderCond.empty() && m_muonGeometryBuilderCond.empty() ) {
+
+        ATH_MSG_VERBOSE( "Configured to only create world TrackingVolume." );
+
+        Trk::VolumeBounds* worldBounds = new Trk::CylinderVolumeBounds(m_worldDimension[0],
+                                                                       m_worldDimension[1],
+                                                                       m_worldDimension[2]);
+
+        Trk::TrackingVolume* worldVolume = new Trk::TrackingVolume(0,
+                                                                   worldBounds,
+                                                                   m_worldMaterial,
+                                                                   (const LayerArray*) 0,
+                                                                   (const TrackingVolumeArray*) 0,
+                                                                   "EmptyWorldVolume");
+        //dummy infinite IOV range
+        EventIDRange range;
+
+        // create a new geometry
+        tGeometry = std::make_pair(range, new Trk::TrackingGeometry(worldVolume));
+    } else
+        tGeometry = atlasTrackingGeometry(ctx);
+    // sign it before you return anything
+    tGeometry.second->sign(geometrySignature());
+    return tGeometry;
+
+}
+
+
+std::pair<EventIDRange, const Trk::TrackingGeometry*> Trk::GeometryBuilderCond::atlasTrackingGeometry(const EventContext& ctx) const
+{
+    // the return geometry
+    std::pair<EventIDRange, const Trk::TrackingGeometry*> atlasTrackingGeometry;
+    //Set IOV range covering 0 - inf
+    EventIDRange range;
+
+    // A ------------- INNER DETECTOR SECTION --------------------------------------------------------------------------------
+    // get the Inner Detector and/or Calorimeter trackingGeometry
+    std::pair<EventIDRange, const Trk::TrackingGeometry*> inDetTrackingGeometry;
+    std::pair<EventIDRange, const Trk::TrackingGeometry*> caloTrackingGeometry ;
+
+    // the volumes to be given to higher level tracking geometry builders
+    const Trk::TrackingVolume* inDetVolume    = 0;
+    const Trk::TrackingVolume* caloVolume     = 0;
+
+    // mark the highest volume
+    const Trk::TrackingVolume* highestVolume  = 0;
+
+#ifdef TRKDETDESCR_MEMUSAGE       
+    m_memoryLogger.refresh(getpid());
+    ATH_MSG_INFO( "[ memory usage ] Start of TrackingGeometry building: "  );    
+    ATH_MSG_INFO( m_memoryLogger );                     
+#endif  
+
+    // ========================== INNER DETECTOR PART =================================================
+    if (!m_inDetGeometryBuilderCond.empty()) {
+        // debug output
+        ATH_MSG_VERBOSE( "ID Tracking Geometry is going to be built." );
+        // build the geometry
+        inDetTrackingGeometry = m_inDetGeometryBuilderCond->trackingGeometry(ctx, std::pair<EventIDRange, const Trk::TrackingVolume*>(range, nullptr));
+        // check
+        if (inDetTrackingGeometry.second) {
+            // sign it
+            inDetTrackingGeometry.second->sign(m_inDetGeometryBuilderCond->geometrySignature());
+            // check whether the world has to be created or not
+            if (m_createWorld || m_caloGeometry || m_muonGeometry) {
+                // checkout the highest InDet volume
+                inDetVolume = inDetTrackingGeometry.second->checkoutHighestTrackingVolume();
+                // assign it as the highest volume
+                highestVolume = inDetVolume;
+                range = inDetTrackingGeometry.first;
+                // cleanup
+                delete inDetTrackingGeometry.second;
+            } else // -> Take the exit and return ID stand alone
+                atlasTrackingGeometry = inDetTrackingGeometry;
+        }
+
+#ifdef TRKDETDESCR_MEMUSAGE            
+        m_memoryLogger.refresh(getpid());
+        ATH_MSG_INFO( "[ memory usage ] After InDet TrackingGeometry building: "  );
+        ATH_MSG_INFO( m_memoryLogger );
+#endif
+
+    }
+
+    // ========================== CALORIMETER PART =================================================
+    // if a Calo Geometry Builder is present -> wrap it around the ID
+    if (!m_caloGeometryBuilderCond.empty()) {
+        if (inDetVolume)
+            ATH_MSG_VERBOSE( "Calorimeter Tracking Geometry is going to be built with enclosed ID." );
+        else 
+            ATH_MSG_VERBOSE( "Calorimeter Tracking Geometry is going to be built stand-alone." );
+        // get the InnerDetector TrackingGeometry
+        caloTrackingGeometry = m_caloGeometryBuilderCond->trackingGeometry(ctx, std::make_pair(inDetTrackingGeometry.first, inDetVolume));
+        // if you have to create world or there is a Muon geometry builder ...
+        if (caloTrackingGeometry.second) {
+            // sign it
+            caloTrackingGeometry.second->sign(m_caloGeometryBuilderCond->geometrySignature());
+            if (m_createWorld || m_muonGeometry){
+                // check out the highest Calo volume
+                caloVolume = caloTrackingGeometry.second->checkoutHighestTrackingVolume();
+                // assign it as the highest volume (overwrite ID)
+                highestVolume = caloVolume;
+                range = caloTrackingGeometry.first;
+                // cleanup
+                delete caloTrackingGeometry.second;
+            } else // -> Take the exit and return Calo back
+                atlasTrackingGeometry = caloTrackingGeometry;
+        }
+
+#ifdef TRKDETDESCR_MEMUSAGE            
+        m_memoryLogger.refresh(getpid());
+        ATH_MSG_INFO( "[ memory usage ] After Calo TrackingGeometry building: "  );
+        ATH_MSG_INFO( m_memoryLogger );
+#endif
+
+    }
+
+    // ========================== MUON SYSTEM PART =================================================
+    // if Muon Geometry Builder is present -> wrap either ID or Calo
+    if (!m_muonGeometryBuilderCond.empty()) {
+
+        std::string enclosed = "stand-alone.";
+        if (inDetVolume && caloVolume)
+            enclosed = "with encloded ID/Calo.";
+        else if (inDetVolume || caloVolume)
+            enclosed = (inDetVolume) ? "with encloded ID." : "with encloded Calo.";                  
+        ATH_MSG_VERBOSE( "Muon System Tracking Geometry is going to be built "<< enclosed );
+        // there's nothing outside the muons -- wrap the calo if it exists
+        if (inDetVolume && !caloVolume)
+            atlasTrackingGeometry = m_muonGeometryBuilderCond->trackingGeometry(ctx, std::make_pair(inDetTrackingGeometry.first, inDetVolume));
+        else
+            atlasTrackingGeometry = m_muonGeometryBuilderCond->trackingGeometry(ctx, std::make_pair(caloTrackingGeometry.first, caloVolume));
+
+        // sign it
+        if (atlasTrackingGeometry.second)
+            atlasTrackingGeometry.second->sign(m_muonGeometryBuilderCond->geometrySignature());
+
+#ifdef TRKDETDESCR_MEMUSAGE            
+        m_memoryLogger.refresh(getpid());
+        ATH_MSG_INFO( "[ memory usage ] After Muon TrackingGeometry building: "  );
+        ATH_MSG_INFO( m_memoryLogger );
+#endif
+
+        // ========================== WRAPPING SECTION FOR ID/CALO ====================================
+    } else if (m_createWorld && highestVolume) {
+        // wrapping and world creation has been switched on
+        ATH_MSG_VERBOSE( "Enclosing world is going to be built for: " << highestVolume->volumeName() );
+        // get the glue volumes
+        const Trk::GlueVolumesDescriptor& innerGlueVolumes = highestVolume->glueVolumesDescriptor();
+        // some screen output
+        ATH_MSG_VERBOSE( "Retrieved with following glue volumes: " << innerGlueVolumes );
+        // at negative face
+        const std::vector<const Trk::TrackingVolume*>& innerNegativeFaceVolumes = innerGlueVolumes.glueVolumes(Trk::negativeFaceXY);
+        // at cylinder cover
+        const std::vector<const Trk::TrackingVolume*>& innerCentralFaceVolumes = innerGlueVolumes.glueVolumes(Trk::cylinderCover);
+        // at positive face
+        const std::vector<const Trk::TrackingVolume*>& innerPositiveFaceVolumes = innerGlueVolumes.glueVolumes(Trk::positiveFaceXY);
+
+        // get the dimensions
+        // cast them to CylinderVolumeBounds
+        const Trk::CylinderVolumeBounds* innerVolumeBounds = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(highestVolume->volumeBounds()));
+        if (!innerVolumeBounds) ATH_MSG_WARNING( "atlasTrackingGeometry() ... dynamic cast to innerVolumeBounds failed!" );
+        double innerVolumeOuterR      = innerVolumeBounds ? innerVolumeBounds->outerRadius() : 0;
+        double innerVolumeHalflengthZ = innerVolumeBounds ? innerVolumeBounds->halflengthZ() : 0;
+        // Hierarchy after enclosing
+        //
+        // AtlasWorldVolume:
+        //    AtlasInnerCylinder
+        //       AtlasInnerNegativeSector
+        //       InnerEnclosedVolume (can be ID/Calo)
+        //       AtlasOuterNegativeSector
+        //    AtlasOuterTube
+        // B -------------- BUILD WORLD AROUND for ID stand alone applications
+
+        double innerCylinderSectorHalflengthZ = 0.5*(m_worldDimension[2] - innerVolumeHalflengthZ);
+        Trk::CylinderVolumeBounds* innerCylinderSectorBounds =
+                new Trk::CylinderVolumeBounds(0., innerVolumeOuterR, innerCylinderSectorHalflengthZ);
+
+        double innerCylinderSectorPositionZ = fabs(m_worldDimension[2]-innerCylinderSectorHalflengthZ);
+
+        // the AtlasInnerNegativeSector
+        Amg::Transform3D* atlasInnerNegativeSectorTransf = new Amg::Transform3D;
+                        (*atlasInnerNegativeSectorTransf) = Amg::Translation3D(0.,0.,-innerCylinderSectorPositionZ);
+        Trk::TrackingVolume* atlasInnerNegativeSector = new Trk::TrackingVolume(
+                               atlasInnerNegativeSectorTransf,
+                               innerCylinderSectorBounds,
+                               m_worldMaterial,
+                               (const LayerArray*) 0,
+                               (const TrackingVolumeArray*) 0,
+                               "AtlasInnerNegativeSector");
+
+        // the AtlasInnerPositiveSector
+        Amg::Transform3D* atlasInnerPositiveSectorTransf = new Amg::Transform3D;
+                        (*atlasInnerPositiveSectorTransf) = Amg::Translation3D(0.,0.,innerCylinderSectorPositionZ);
+        Trk::TrackingVolume* atlasInnerPositiveSector = new Trk::TrackingVolume(
+                               atlasInnerPositiveSectorTransf,
+                               innerCylinderSectorBounds->clone(),
+                               m_worldMaterial,
+                               (const LayerArray*) 0,
+                               (const TrackingVolumeArray*) 0,
+                               "AtlasInnerPositiveSector");
+
+        ATH_MSG_VERBOSE( "Inner Negative/Positive Sectors built successfully." );
+
+        // create the subvolume Array
+        auto atlasInnerSectorVolumes = std::vector<const Trk::TrackingVolume*>{atlasInnerNegativeSector,highestVolume,atlasInnerPositiveSector}; 
+
+        ATH_MSG_VERBOSE( "Create the Atlas Inner Sector volumes. " );
+        Trk::BinnedArray<Trk::TrackingVolume>* atlasInnerSectorVolumeArray = m_trackingVolumeArrayCreator ?
+                m_trackingVolumeArrayCreator->cylinderVolumesArrayInZ(atlasInnerSectorVolumes) : 0;
+
+
+        // Atlas inner Sector bounds
+        Trk::CylinderVolumeBounds* innerSectorBounds =
+                new Trk::CylinderVolumeBounds(0., innerVolumeOuterR, m_worldDimension[2]);
+        // build the Tracking volumes
+        Trk::TrackingVolume* atlasInnerSector = new Trk::TrackingVolume(0,
+                                                                        innerSectorBounds,
+                                                                        m_worldMaterial,
+                                                                        0,atlasInnerSectorVolumeArray,
+                                                                        "AtlasInnerSector");
+
+        // Atlas outer Sector
+        Trk::CylinderVolumeBounds* outerSectorBounds =
+                new Trk::CylinderVolumeBounds(innerVolumeOuterR, m_worldDimension[1], m_worldDimension[2]);
+        Trk::TrackingVolume* atlasOuterSector = new Trk::TrackingVolume(0,
+                                                                        outerSectorBounds,
+                                                                        m_worldMaterial,
+                                                                        (const LayerArray*) 0,
+                                                                        (const TrackingVolumeArray*) 0,
+                                                                        "AtlasOuterSector");
+
+        ATH_MSG_VERBOSE( "Atlas Inner/Outer Sectors built successfully." );
+
+        // create the array of Inner and Outer sector
+        auto atlasVolumes =  std::vector<const Trk::TrackingVolume*>{atlasInnerSector, atlasOuterSector};
+
+        Trk::BinnedArray<Trk::TrackingVolume>* atlasVolumeArray = m_trackingVolumeArrayCreator ?
+                m_trackingVolumeArrayCreator->cylinderVolumesArrayInR(atlasVolumes) : 0;
+
+        // create the Atlas volume bounds
+        Trk::CylinderVolumeBounds* atlasBounds = new Trk::CylinderVolumeBounds(0., m_worldDimension[1], m_worldDimension[2]);
+
+        // create the Atlas TrackingVolume
+        Trk::TrackingVolume* atlasVolume = new Trk::TrackingVolume(0,
+                                                                   atlasBounds,
+                                                                   m_worldMaterial,
+                                                                   0,atlasVolumeArray,
+                                                                   "Atlas");
+
+        ATH_MSG_VERBOSE( "Atlas Tracking World volume built successfully." );
+
+
+        // glue the inner sector to be complete
+        m_trackingVolumeHelper->glueTrackingVolumes( *atlasInnerNegativeSector, Trk::positiveFaceXY,
+                                                      innerNegativeFaceVolumes, Trk::negativeFaceXY );
+
+        m_trackingVolumeHelper->glueTrackingVolumes( *atlasInnerPositiveSector, Trk::negativeFaceXY,
+                                                      innerPositiveFaceVolumes, Trk::positiveFaceXY );
+
+        ATH_MSG_VERBOSE( "Atlas Inner Sector glued successfully together." );
+
+        // iterators to the face volumes
+        auto volIter    = innerCentralFaceVolumes.begin();
+        auto volIterEnd = innerCentralFaceVolumes.end();
+
+        // glue outer and inner sector together
+        std::vector<const Trk::TrackingVolume*> atlasInnerOuterVolumes;
+        atlasInnerOuterVolumes.push_back(atlasInnerNegativeSector);
+        for ( ; volIter != volIterEnd; ++volIter)
+            if (*volIter) atlasInnerOuterVolumes.push_back(*volIter);
+        atlasInnerOuterVolumes.push_back(atlasInnerPositiveSector);
+
+        m_trackingVolumeHelper->glueTrackingVolumes(*atlasOuterSector, Trk::tubeInnerCover,
+                                                     atlasInnerOuterVolumes, Trk::tubeOuterCover);
+
+        ATH_MSG_VERBOSE( "Atlas Inner/Outer Sector glued successfully together." );
+
+        // job done -> create the TrackingGeometry
+        atlasTrackingGeometry.second = new Trk::TrackingGeometry(atlasVolume);
+
+        atlasTrackingGeometry.first = range;
+        
+        // detailed information about this tracking geometry
+        ATH_MSG_VERBOSE( "Atlas TrackingGeometry built with following parameters : ");
+        //ATH_MSG_VERBOSE( " - TrackingVolume containers            : " << atlasTrackingGeometry->numberOfContainerVolumes() );
+        //ATH_MSG_VERBOSE( " - TrackingVolume at navigation level   : " << atlasTrackingGeometry->numberOfContainerVolumes() );
+        //ATH_MSG_VERBOSE( " - Contained static layers              : " << atlasTrackingGeometry->boundaryLayers().size());        
+        ATH_MSG_VERBOSE( " - Unique material layers on boundaries : " << atlasTrackingGeometry.second->boundaryLayers().size());        
+
+#ifdef TRKDETDESCR_MEMUSAGE            
+        m_memoryLogger.refresh(getpid());
+        ATH_MSG_INFO( "[ memory usage ] After Outer Sector TrackingGeometry building: "  );
+        ATH_MSG_INFO( m_memoryLogger );
+#endif
+
+    }
+
+    if (atlasTrackingGeometry.second) {
+        if (m_navigationLevel < 3)
+            atlasTrackingGeometry.second->registerNavigationLevel( Trk::NavigationLevel(m_navigationLevel));
+    }
+    else ATH_MSG_WARNING( "atlasTrackingGeometry() ... atlasTrackingGeometry = 0, could not call registerNavigationLevel and propagateMagneticFieldProperties" );
+
+#ifdef TRKDETDESCR_MEMUSAGE            
+    m_memoryLogger.refresh(getpid());
+    ATH_MSG_INFO( "[ memory usage ] End of TrackingGeometry building: "  );    
+    ATH_MSG_INFO( m_memoryLogger );                     
+#endif
+
+    // synchronize the layers
+    if (atlasTrackingGeometry.second) {
+    if (m_synchronizeLayers) atlasTrackingGeometry.second->synchronizeLayers(msg());
+
+    // compactify if configured to do so
+    if (m_compactify) atlasTrackingGeometry.second->compactify(msg());
+    }
+    return atlasTrackingGeometry;
+} 
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/src/InputLayerMaterialProvider.cxx b/Tracking/TrkDetDescr/TrkDetDescrTools/src/InputLayerMaterialProvider.cxx
index b17891b7150d6fde4338d4334a784ec4186f707f..f45dbb13139c7634e48c068632b1fedbdb8cb142 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTools/src/InputLayerMaterialProvider.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/src/InputLayerMaterialProvider.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -56,7 +56,7 @@ StatusCode Trk::InputLayerMaterialProvider::initialize() {
 }
 
 // Processor Action to work on TrackingGeometry 
-StatusCode Trk::InputLayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo) {
+StatusCode Trk::InputLayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo) const {
   
   ATH_MSG_VERBOSE("Start processing the TrackingGeometry recursively");
   // retrieve the highest tracking volume
@@ -71,7 +71,7 @@ StatusCode Trk::InputLayerMaterialProvider::process(const Trk::TrackingGeometry&
 }
 
 // Processor Action to work on TrackingVolumes
-StatusCode Trk::InputLayerMaterialProvider::process(const Trk::TrackingVolume& tvol, size_t level) {
+StatusCode Trk::InputLayerMaterialProvider::process(const Trk::TrackingVolume& tvol, size_t level) const {
   
   std::stringstream displayBuffer;
   for (size_t il = 0; il < level; ++il) displayBuffer << " ";
@@ -118,7 +118,7 @@ StatusCode Trk::InputLayerMaterialProvider::process(const Trk::TrackingVolume& t
 }
 
 // Processor Action to work on Layers 
-StatusCode Trk::InputLayerMaterialProvider::process(const Trk::Layer& lay, size_t level) {
+StatusCode Trk::InputLayerMaterialProvider::process(const Trk::Layer& lay, size_t level) const {
     
     // skip Layers w/o material
     if (!lay.layerMaterialProperties()) 
@@ -142,7 +142,7 @@ StatusCode Trk::InputLayerMaterialProvider::process(const Trk::Layer& lay, size_
 }
 
 // Processor Action to work on Surfaces 
-StatusCode Trk::InputLayerMaterialProvider::process(const Trk::Surface&, size_t) {
+StatusCode Trk::InputLayerMaterialProvider::process(const Trk::Surface&, size_t) const {
     return StatusCode::SUCCESS;
 }
 
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerMaterialProvider.cxx b/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerMaterialProvider.cxx
index ecd20cec315a9039cd205842b0ad373b81696d2b..6054b6d539ceaa3e42431ac181c00c1dd73311ac 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerMaterialProvider.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerMaterialProvider.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -36,7 +36,7 @@ Trk::LayerMaterialProvider::~LayerMaterialProvider()
 
 
 // Processor Action to work on TrackingGeometry 
-StatusCode Trk::LayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo) {
+StatusCode Trk::LayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo) const{
   
   ATH_MSG_VERBOSE("Start processing the TrackingGeometry recursively");
   // retrieve the highest tracking volume
@@ -81,14 +81,16 @@ StatusCode Trk::LayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo
 }
 
 // Processor Action to work on TrackingVolumes
-StatusCode Trk::LayerMaterialProvider::process(const Trk::TrackingVolume& tvol, size_t level) {
+StatusCode Trk::LayerMaterialProvider::process(const Trk::TrackingVolume& tvol, size_t level) const {
   
   // load the material map if not done yet
-  if (!m_layerMaterialMap){ 
-      if (loadMaterialMap().isFailure()){
-            ATH_MSG_DEBUG( "Problems loading hte LayerMaterialMap - check name or call sequence." );
-            return StatusCode::FAILURE;
-      }
+  bool loadMapFailed = false;
+  std::call_once(m_loadMapOnceFlag, [&](){
+      loadMapFailed = loadMaterialMap().isFailure();
+  });
+  if (loadMapFailed){
+      ATH_MSG_DEBUG( "Problems loading the LayerMaterialMap - check name or call sequence." );
+      return StatusCode::FAILURE;
   }
   
   std::stringstream displayBuffer;
@@ -148,14 +150,16 @@ StatusCode Trk::LayerMaterialProvider::process(const Trk::TrackingVolume& tvol,
 }
 
 // Processor Action to work on Layers 
-StatusCode Trk::LayerMaterialProvider::process(const Trk::Layer& lay, size_t level) {
+StatusCode Trk::LayerMaterialProvider::process(const Trk::Layer& lay, size_t level) const {
 
     // load the material map if not done yet
-    if (!m_layerMaterialMap){ 
-        if (loadMaterialMap().isFailure()){
-              ATH_MSG_WARNING( "Problems loading the LayerMaterialMap - check name or call sequence." );
-              return StatusCode::FAILURE;
-        }
+    bool loadMapFailed = false;
+    std::call_once(m_loadMapOnceFlag, [&](){
+        loadMapFailed = loadMaterialMap().isFailure();
+    });
+    if (loadMapFailed){
+        ATH_MSG_DEBUG( "Problems loading the LayerMaterialMap - check name or call sequence." );
+        return StatusCode::FAILURE;
     }
     // is the pointer still null?
     if (!m_layerMaterialMap) {
@@ -190,12 +194,12 @@ StatusCode Trk::LayerMaterialProvider::process(const Trk::Layer& lay, size_t lev
 }
 
 // Processor Action to work on Surfaces 
-StatusCode Trk::LayerMaterialProvider::process(const Trk::Surface&, size_t) {
+StatusCode Trk::LayerMaterialProvider::process(const Trk::Surface&, size_t) const{
     return StatusCode::SUCCESS;
 }
 
 // load the material map from StoreGate
-StatusCode Trk::LayerMaterialProvider::loadMaterialMap() {
+StatusCode Trk::LayerMaterialProvider::loadMaterialMap() const {
     
     // -------------------------------------------------------------------------------
     if (detStore()->retrieve(m_layerMaterialMap, m_layerMaterialMapName).isFailure()){
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerProviderCond.cxx b/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerProviderCond.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..350c99121c501c0ccba147beb8b82b68a2f47be0
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerProviderCond.cxx
@@ -0,0 +1,114 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// LayerProviderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+// STL
+#include <sstream>
+// Trk include
+#include "TrkDetDescrTools/LayerProviderCond.h"
+#include "TrkDetDescrInterfaces/ILayerBuilderCond.h"
+#include "TrkGeometry/Layer.h"
+#include "TrkGeometry/CylinderLayer.h"
+#include "TrkGeometry/DiscLayer.h"
+
+// constructor
+Trk::LayerProviderCond::LayerProviderCond(const std::string& t, const std::string& n, const IInterface* p)
+: AthAlgTool(t,n,p)
+{
+    declareInterface<Trk::ILayerProviderCond>(this);
+    
+    // Name specification from outside
+    declareProperty("LayerBuilder", m_layerBuilder);
+    
+}
+
+// destructor
+Trk::LayerProviderCond::~LayerProviderCond()
+{}
+
+// initialize
+StatusCode Trk::LayerProviderCond::initialize()
+{
+    if (m_layerBuilder.retrieve().isFailure()){
+        ATH_MSG_WARNING("Could not retrieve layer builder");
+    }
+    return StatusCode::SUCCESS;
+}
+
+/** LayerBuilderCond interface method - returning the layers at negative side */
+std::pair<EventIDRange, const std::vector< const Trk::Layer*>  > Trk::LayerProviderCond::negativeLayers(const EventContext& ctx) const
+{
+    // this will fill the cache with positive layers
+    return discLayers(ctx, -1);
+}    
+
+/** LayerBuilderCond interface method - returning the central layers */
+std::pair<EventIDRange, const std::vector< const Trk::Layer* > > Trk::LayerProviderCond::centralLayers(const EventContext& ctx) const
+{
+    // central layers
+    std::vector< const Trk::Layer* >            cLayers;
+    // retrieving the cylinder layers from the layer builder
+    std::pair<EventIDRange, const std::vector< const Trk::CylinderLayer* >* >  cylinderLayersPair = m_layerBuilder->cylindricalLayers(ctx);
+    auto cylinderLayers = cylinderLayersPair.second;
+    // loop over it and push into the return vector;
+    if (cylinderLayers){
+        for (auto& cL : (*cylinderLayers))
+            cLayers.push_back(cL);
+    }
+    // memory cleanup
+    delete cylinderLayers;
+    // and return
+    return std::make_pair(cylinderLayersPair.first, cLayers);
+} 
+
+/** LayerBuilderCond interface method - returning the layers at negative side */
+std::pair<EventIDRange,const std::vector< const Trk::Layer*> > Trk::LayerProviderCond::positiveLayers(const EventContext& ctx) const
+{
+    // this will fill the cache with negative layers
+    return discLayers(ctx, 1);
+}
+
+/** LayerBuilderCond interface method - returning the layers at negative side */
+std::pair<EventIDRange, const std::vector< const Trk::Layer* > > Trk::LayerProviderCond::discLayers(const EventContext& ctx, int posneg) const
+{
+    // get the disc layers
+    std::vector < const Trk::Layer* >   dLayers;
+    // retrieving the cylinder layers from the layer builder
+    std::pair<EventIDRange, const std::vector<const Trk::DiscLayer*>*>  discLayersPair = m_layerBuilder->discLayers(ctx);
+    auto discLayers = discLayersPair.second;
+    // loop and fill either cache or dLayers
+    if (discLayers){
+        // loop over and push into the return/cache vector 
+        for (auto& dL : (*discLayers) ){
+            // get the center posituion 
+            double zpos = dL->surfaceRepresentation().center().z();
+            if (posneg > 0){
+                // configured to provide positive and cache negative
+                if (zpos > 0.) dLayers.push_back(dL);
+            } else {
+                // configured to provide negative and cache positive
+                if (zpos < 0.) dLayers.push_back(dL);
+            }
+        }
+    }
+    // memory cleanup
+    delete discLayers;
+    // and return
+    return std::make_pair(discLayersPair.first, dLayers);   
+}
+
+
+// finalize
+StatusCode Trk::LayerProviderCond::finalize()
+{
+    return StatusCode::SUCCESS;
+}
+
+const std::string& Trk::LayerProviderCond::identification() const
+{
+    return m_layerBuilder->identification();
+}
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/src/components/TrkDetDescrTools_entries.cxx b/Tracking/TrkDetDescr/TrkDetDescrTools/src/components/TrkDetDescrTools_entries.cxx
index 0cff6b5e051406e9f7fe921a2441bbffd626fe08..3a1fa376857348551f8077cda7d9f03d846a3dc5 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTools/src/components/TrkDetDescrTools_entries.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/src/components/TrkDetDescrTools_entries.cxx
@@ -12,6 +12,10 @@
 #include "TrkDetDescrTools/TrackingVolumeArrayCreator.h"
 #include "TrkDetDescrTools/TrackingVolumeHelper.h"
 
+#include "TrkDetDescrTools/GeometryBuilderCond.h"
+#include "TrkDetDescrTools/GenericGeometryBuilderCond.h"
+#include "TrkDetDescrTools/LayerProviderCond.h"
+
 using namespace Trk;
 
 DECLARE_COMPONENT( CylinderVolumeCreator )
@@ -28,3 +32,6 @@ DECLARE_COMPONENT( InputLayerMaterialProvider )
 DECLARE_COMPONENT( TrackingVolumeArrayCreator )
 DECLARE_COMPONENT( TrackingVolumeHelper )
 
+DECLARE_COMPONENT( GeometryBuilderCond )
+DECLARE_COMPONENT( GenericGeometryBuilderCond )
+DECLARE_COMPONENT( LayerProviderCond )
diff --git a/Tracking/TrkDetDescr/TrkGeometry/TrkGeometry/TrackingGeometry.h b/Tracking/TrkDetDescr/TrkGeometry/TrkGeometry/TrackingGeometry.h
index 02efbc103fc26a818e7f346ba83745ea994b4c28..71b577d0532ac647269c5c9144c323746c995028 100755
--- a/Tracking/TrkDetDescr/TrkGeometry/TrkGeometry/TrackingGeometry.h
+++ b/Tracking/TrkDetDescr/TrkGeometry/TrkGeometry/TrackingGeometry.h
@@ -60,6 +60,9 @@ namespace Trk {
     /** Give the GeometryBuilder friend rights */  
     friend class GeometryBuilder;
     friend class IGeometryBuilder;
+    
+    friend class GeometryBuilderCond;
+    friend class IGeometryBuilderCond;
   
     public :
       /** Constructor */
@@ -212,5 +215,8 @@ namespace Trk {
 } // end of namespace
 
 CLASS_DEF(Trk::TrackingGeometry, 167645219, 1)
+#include "AthenaKernel/CondCont.h" 
+CONDCONT_DEF( Trk::TrackingGeometry , 119021535 );
+
 
 #endif //TRKGEOMETRY_TRACKINGGEOMETRY_H
diff --git a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersT.icc b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersT.icc
index 9c6cb0e145b1f2865739b62054b854a5c10ec7eb..6c30adc6f5ee8acff6211df9aa430a30a1f73a14 100644
--- a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersT.icc
+++ b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersT.icc
@@ -32,7 +32,7 @@ ParametersT<DIM, T, S>::ParametersT(double loc1,
                                     double qop,
                                     const S& surface,
                                     AmgSymMatrix(DIM) * cov)
-  : ParametersBase<DIM, T>({}, cov, {}, {}, sgn(qop))
+  : ParametersBase<DIM, T>(AmgVector(DIM)::Zero(), cov, Amg::Vector3D::Zero(), Amg::Vector3D::Zero(), sgn(qop))
   , m_surface(nullptr)
 {
   m_surface.reset((surface.isFree() ? surface.clone() : &surface));
@@ -64,8 +64,8 @@ ParametersT<DIM, T, S>::ParametersT(const AmgVector(DIM) & parameters,
                                     AmgSymMatrix(DIM) * cov)
   : ParametersBase<DIM, T>(parameters,
                            cov,
-                           {},
-                           {},
+                           Amg::Vector3D::Zero(),
+                           Amg::Vector3D::Zero(),
                            sgn(parameters[Trk::qOverP]))
   , m_surface(nullptr)
 {
@@ -99,7 +99,7 @@ ParametersT<DIM, T, S>::ParametersT(const Amg::Vector3D& pos,
                                     double charge,
                                     const S& surface,
                                     AmgSymMatrix(DIM) * cov)
-  : ParametersBase<DIM, T>({}, cov, pos, mom, charge)
+  : ParametersBase<DIM, T>(AmgVector(DIM)::Zero(), cov, pos, mom, charge)
   , m_surface(surface.isFree() ? surface.clone() : &surface)
 {
   // get the local parameters via the surface
@@ -130,7 +130,7 @@ Trk::ParametersT<DIM, T, S>::ParametersT(const Amg::Vector3D& pos,
                                          double qop,
                                          const S& surface,
                                          AmgSymMatrix(DIM) * cov)
-  : ParametersBase<DIM, T>({}, cov, pos, {}, 1.)
+  : ParametersBase<DIM, T>(AmgVector(DIM)::Zero(), cov, pos, Amg::Vector3D::Zero(), 1.)
   , m_surface(surface.isFree() ? surface.clone() : &surface)
 {
   // decide the sign of the charge
diff --git a/Tracking/TrkEventCnv/TrkEventAthenaPool/CMakeLists.txt b/Tracking/TrkEventCnv/TrkEventAthenaPool/CMakeLists.txt
index 037e887b6681ac09b0ac11479bc4ad0404a07f16..d76b58d2a8cea04add92bf64e6989e4d190be703 100644
--- a/Tracking/TrkEventCnv/TrkEventAthenaPool/CMakeLists.txt
+++ b/Tracking/TrkEventCnv/TrkEventAthenaPool/CMakeLists.txt
@@ -15,7 +15,6 @@ atlas_add_poolcnv_library( TrkEventAthenaPoolPoolCnv
 
 # Install files from the package:
 atlas_install_joboptions( share/*.py )
-atlas_install_python_modules( python/*.py )
 
 # Set up (a) test(s) for the converter(s):
 find_package( AthenaPoolUtilitiesTest )
diff --git a/Tracking/TrkEventCnv/TrkEventCnvTools/TrkEventCnvTools/ITrkEventCnvTool.icc b/Tracking/TrkEventCnv/TrkEventCnvTools/TrkEventCnvTools/ITrkEventCnvTool.icc
index 61043489583f864cb44c7d10d532aad0bf8c2c48..a8e014db277ba1664d9e850c37cdaed71ac76197 100644
--- a/Tracking/TrkEventCnv/TrkEventCnvTools/TrkEventCnvTools/ITrkEventCnvTool.icc
+++ b/Tracking/TrkEventCnv/TrkEventCnvTools/TrkEventCnvTools/ITrkEventCnvTool.icc
@@ -52,12 +52,12 @@ void Trk::ITrkEventCnvTool::prepareRIO_OnTrackElementLink(const ROT* rot,
     IdentifierHash          idHash  = prd->getHashAndIndex().collHash(); // idHash of collection
 
     const CONT& cont = *dh; // container
-    typename CONT::const_iterator coll = cont.indexFind(idHash); //matching collection
+    auto coll = cont.indexFindPtr(idHash); //matching collection
 
     // does coll exist?
     // check prd exists in collection
     // check pointer value the same.
-    if ( (coll!=cont.end())&& ((*coll)->size()>oindex) && (prd==(**coll)[oindex]) ) {
+    if ( (coll!=nullptr)&& (coll->size()>oindex) && (prd==(*coll)[oindex]) ) {
       // okay, so we found the correct PRD in the container.
       // Return EL components.
       // dh.key() is the name of the container. oindex is the index within the collection. IdHash????
@@ -101,12 +101,11 @@ bool Trk::ITrkEventCnvTool::getHashAndIndex(const ROT* rot,
 
   const IdentContIndex& idContIndex{prd->getHashAndIndex()};
   const IdentifierHash& idHash{idContIndex.collHash()}; // idHash of collection
-  typename CONT::const_iterator contItr{cont->indexFind(idHash)}; //matching collection
-  if (contItr==cont->end()) return false;
-  if ((*contItr)==nullptr) return false;
+  auto contItr = cont->indexFindPtr(idHash); //matching collection
+  if (contItr==nullptr) return false;
 
   unsigned int index{idContIndex.objIndex()}; // prd index within collection
-  if (((*contItr)->size()>index) and (prd==(**contItr)[index])) {
+  if ((contItr->size()>index) and (prd==(*contItr)[index])) {
     hashAndIndex = idContIndex.hashAndIndex();
     return true;
   }
diff --git a/Tracking/TrkFitter/TrkFitterInterfaces/TrkFitterInterfaces/ITrackFitter.h b/Tracking/TrkFitter/TrkFitterInterfaces/TrkFitterInterfaces/ITrackFitter.h
index d8cf4ee66365bf1ec5c820c9322bfcc6d355be07..bc0b561ed1e5e771d97498396393cea9b7a5913e 100755
--- a/Tracking/TrkFitter/TrkFitterInterfaces/TrkFitterInterfaces/ITrackFitter.h
+++ b/Tracking/TrkFitter/TrkFitterInterfaces/TrkFitterInterfaces/ITrackFitter.h
@@ -61,10 +61,8 @@ public:
   }
 
   /*
-   * First the context aware retun unique_ptr
-   * methods.
-   * If this set is not overloaded , it
-   * will call the methods without EventContext
+   * Event context aware  methods
+   * returning unique_ptr
    */
 
   /** Event context aware (Athena MT) RE-FIT A TRACK. */
@@ -134,10 +132,12 @@ public:
     const ParticleHypothesis matEffects = Trk::nonInteracting) const = 0;
 
   /*
-   * Then the context unaware methods.
+   * Context unaware methods.
    * These are here for client compatibility.
    * They just call the EventContext aware
    * methods.
+   * They can be removed if all clients are
+   * updated
    * Implementations do not need to provide them.
    */
 
diff --git a/Tracking/TrkFitter/TrkiPatFitterUtils/src/FitMeasurement.cxx b/Tracking/TrkFitter/TrkiPatFitterUtils/src/FitMeasurement.cxx
index a005b63d24d5a70017d63a31a8437b646469fe13..f165e58087962c52660c9bb88ac310070fde5ca0 100755
--- a/Tracking/TrkFitter/TrkiPatFitterUtils/src/FitMeasurement.cxx
+++ b/Tracking/TrkFitter/TrkiPatFitterUtils/src/FitMeasurement.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 /***************************************************************************
@@ -8,10 +8,6 @@
    i.e. position, surface, weights, intersection, derivatives, residual etc
  ***************************************************************************/
 
-#include <cmath>
-#include <iomanip>
-#include <iostream>
-// #include "EventPrimitives/EventPrimitives.h"
 #include "EventPrimitives/EventPrimitivesHelpers.h"
 #include "GaudiKernel/MsgStream.h"
 #include "GaudiKernel/SystemOfUnits.h"
@@ -34,6 +30,10 @@
 #include "TrkTrack/TrackStateOnSurface.h"
 #include "TrkiPatFitterUtils/FitMeasurement.h"
 
+#include <cmath>
+#include <iomanip>
+#include <iostream>
+
 namespace Trk{
   
 // MeasurementBase
@@ -1017,21 +1017,7 @@ void
 FitMeasurement::intersection (ExtrapolationType type,
 			      const TrackSurfaceIntersection* value)
 {
-    // by convention: FittedTrajectory clears out the previous intersections
-//     if (type == FittedTrajectory)
-//     {
-// 	for (int typ = 0; typ != ExtrapolationTypes; ++typ)
-// 	{
-// 	    if (! m_intersection[typ]) continue;
-// 	    delete m_intersection[typ];
-// 	    m_intersection[typ] = 0;
-// 	}
-//     }
-//     else
-    {
-	delete m_intersection[type];
-    }
-    
+    if (type!=FittedTrajectory) delete m_intersection[type];
     m_intersection[type] = value;
 }
 
diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/CMakeLists.txt b/Tracking/TrkTools/TrkAmbiguityProcessor/CMakeLists.txt
index a39d791962042c5652221284c731504e4c58630a..b17deee787ed6afc28f2f771a635fbdbc1d4813d 100644
--- a/Tracking/TrkTools/TrkAmbiguityProcessor/CMakeLists.txt
+++ b/Tracking/TrkTools/TrkAmbiguityProcessor/CMakeLists.txt
@@ -35,6 +35,7 @@ find_package( HepPDT )
 atlas_add_library(   TrkAmbiguityProcessorLib
                      src/DenseEnvironmentsAmbiguityProcessorTool.cxx
                      src/DenseEnvironmentsAmbiguityScoreProcessorTool.cxx
+                   
                      PUBLIC_HEADERS TrkAmbiguityProcessor
                      PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
                      LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaKernel AthenaBaseComps AtlasDetDescr GaudiKernel InDetPrepRawData InDetRecToolInterfaces TrkDetElementBase TrkEventPrimitives TrkParameters TrkRIO_OnTrack TrkTrack TrkTrackSummary TrkTruthData TrkFitterInterfaces TrkToolInterfaces TrkValInterfaces TrkExInterfaces TrkCaloClusterROI)
diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiCounter.icc b/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiCounter.icc
new file mode 100644
index 0000000000000000000000000000000000000000..cc6b2af9c86dd08c54cba26e54b6b70aa3d2838f
--- /dev/null
+++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiCounter.icc
@@ -0,0 +1,117 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TrkAmbiguityProcessor_AmbiCounter_icc
+#define TrkAmbiguityProcessor_AmbiCounter_icc
+#include <array>
+#include <vector>
+#include <string>
+#include "TrkTrack/Track.h"
+
+template<class EnumType>
+class AmbiCounter {
+public:
+  using Categories = EnumType;
+  enum RegionIndex {iAll = 0, iBarrel = 1, iTransi = 2, iEndcap = 3, iDBM = 4, nRegions=5, iForwrd = 4};
+  enum GlobalCounterIndices {
+    nEvents,
+    nInvalidTracks,
+    nTracksWithoutParam,
+    nGlobalCounters,
+  };
+  //
+  AmbiCounter(const std::vector<float> &eta_bounds): m_etaBounds(eta_bounds){
+    //nop
+  }
+  
+  //convert Category to array index
+  size_t 
+  idx(const Categories & categoryIndex) const{
+    return static_cast<size_t>(categoryIndex);
+  }
+  
+  //increment event count
+  void 
+  newEvent(){
+    ++m_globalCounter[nEvents];
+  }
+  
+  //return number of events
+  int 
+  numberOfEvents() const{
+    return m_globalCounter[nEvents];
+  }
+  // increment one bin
+  void 
+  increment(Categories regionIdx, unsigned int etaBinIdx) {
+    if (etaBinIdx>=nRegions) return;
+    if (regionIdx<Categories::kNCounter && etaBinIdx < m_counter[idx(regionIdx)].size()) {
+      ++m_counter[idx(regionIdx)][etaBinIdx];
+    } else {  throw std::range_error("out of range"); }
+    
+  }
+  //
+  AmbiCounter<EnumType> & operator +=(const AmbiCounter<EnumType> &a) {
+  for (unsigned int i=0; i<nGlobalCounters; ++i) {
+       m_globalCounter[i]+= a.m_globalCounter[i];
+  }
+  for (size_t regionIdx=0; regionIdx < idx(Categories::kNCounter); ++regionIdx) {
+     for (unsigned int etaBinIdx=0; etaBinIdx < a.m_counter[regionIdx].size(); ++etaBinIdx) {
+        m_counter[regionIdx][etaBinIdx] += a.m_counter[regionIdx][etaBinIdx];
+     }
+  }
+  return *this;
+}
+  //
+  void incrementCounterByRegion(Categories regionIdx,const Trk::Track* track, bool updateAll=true){
+   if (updateAll) increment(regionIdx,iAll);
+   // test
+   if (!track) {
+      ++m_globalCounter[nEvents];
+      return;
+   }
+   // use first parameter
+   if (!track->trackParameters()) {
+      ++m_globalCounter[nTracksWithoutParam];
+   } else {
+      std::array<int, nRegions> &nTracks = m_counter[idx(regionIdx)];
+      // @TODO make sure that list of track parameters is not empty
+      const double absEta = std::abs(track->trackParameters()->front()->eta());
+      ++nTracks[etaBin(absEta)];
+    }
+  }
+  //
+  std::string 
+  dumpRegions(const std::string & head,Categories regionIdx, const int iw =9) const {
+    std::stringstream out;
+    out << head;
+    for (unsigned int etaBinIdx=0; etaBinIdx < nRegions; ++etaBinIdx) {
+       assert( etaBinIdx < m_counter[idx(regionIdx)].size() );
+       out << std::setiosflags(std::ios::dec) << std::setw(iw) << m_counter[idx(regionIdx)][etaBinIdx];
+    }
+    out << "\n";
+    return out.str();
+  }
+  //
+  int 
+  globalCount(GlobalCounterIndices i) const{
+    return m_globalCounter[i]; 
+  }
+  
+private:
+  std::array<std::array<int, nRegions>,static_cast<size_t>(Categories::kNCounter)> m_counter{};
+  std::array<int,nGlobalCounters>                      m_globalCounter{};
+  const std::vector<float>  &m_etaBounds;           //!< eta intervals for internal monitoring
+  size_t 
+  etaBin(const double val){
+    size_t regionIdx=1; 
+    //eta *must be* in ascending order in the m_etaBounds vector
+    for (;regionIdx< nRegions; ++regionIdx){
+      if (val < m_etaBounds[regionIdx-1]) break;
+    }
+    return regionIdx;
+  }
+};
+
+#endif
diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.cxx b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.cxx
index 20b1fa2ed7d90ad4bef01d38bc52752ba4c773a1..38979306628ed799de67657917dd137c922a49d0 100644
--- a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.cxx
+++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.cxx
@@ -14,14 +14,11 @@
 #include "TrkExInterfaces/IExtrapolator.h"
 #include "TrkTrackSummary/TrackSummary.h"
 #include "TrkCaloClusterROI/CaloClusterROI_Collection.h"
-
-#include <iterator>
-#include "TString.h"
-
 #include "InDetPrepRawData/PixelCluster.h"
 #include "InDetPrepRawData/SCT_Cluster.h"
 #include "InDetIdentifier/PixelID.h"
 #include <cmath>
+#include <iterator>
 
 //TODO: to be improved
 bool Trk::DenseEnvironmentsAmbiguityProcessorTool::checkTrack( const Trk::Track *track) const {
@@ -56,8 +53,8 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::DenseEnvironmentsAmbiguityProcesso
   m_scoringTool("Trk::TrackScoringTool/TrackScoringTool"),
   m_extrapolatorTool("Trk::Extrapolator/AtlasExtrapolator"),
   m_selectionTool("InDet::InDetDenseEnvAmbiTrackSelectionTool/InDetAmbiTrackSelectionTool"),
-  m_etabounds{0.8, 1.6, 2.5, 4.0},
-  m_stat(m_etabounds)
+  m_etaBounds{0.8, 1.6, 2.5, 4.0},
+  m_stat(m_etaBounds)
 {
   // statitics stuff
 
@@ -77,7 +74,7 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::DenseEnvironmentsAmbiguityProcesso
   declareProperty("tryBremFit"           , m_tryBremFit         = false);
   declareProperty("caloSeededBrem"       , m_caloSeededBrem     = false);
   declareProperty("pTminBrem"            , m_pTminBrem          = 1000.);
-  declareProperty("etaBounds"            , m_etabounds,"eta intervals for internal monitoring");
+  declareProperty("etaBounds"            , m_etaBounds,"eta intervals for internal monitoring");
 
   //To determine the ROI for high pt Bs
   declareProperty("doHadCaloSeed"        ,m_useHClusSeed = false );
@@ -131,9 +128,9 @@ StatusCode Trk::DenseEnvironmentsAmbiguityProcessorTool::initialize()
      ATH_CHECK(m_dRMap.initialize() );
   }
 
-  if (m_stat.etaBounds().size() != TrackStat::kNStatRegions-1) {
-     ATH_MSG_FATAL("There must be exactly " << (TrackStat::kNStatRegions-1) << " eta bounds but "
-                   << m_stat.etaBounds().size() << " are set." );
+  if (m_etaBounds.size() != TrackStat::nRegions-1) {
+     ATH_MSG_FATAL("There must be exactly " << (TrackStat::nRegions-1) << " eta bounds but "
+                   << m_etaBounds.size() << " are set." );
      return StatusCode::FAILURE;
   }
   return sc;
@@ -151,72 +148,11 @@ void Trk::DenseEnvironmentsAmbiguityProcessorTool::statistics()
      MsgStream &out=msg(MSG::INFO);
      out << " -- statistics \n";
      std::lock_guard<std::mutex> lock( m_statMutex );
-     m_stat.dump(out, m_tryBremFit);
+     dumpStat(out);
      out << endmsg;
   }
 }
 
-void Trk::DenseEnvironmentsAmbiguityProcessorTool::TrackStat::dump(MsgStream &out, bool try_brem_fit) const
-{
-   auto parseFileName=[](const std::string & fullname){
-    auto dotPosition = fullname.rfind('.');
-    auto slashPosition = fullname.rfind('/');
-    auto stringLength = dotPosition - slashPosition;
-    return fullname.substr(slashPosition, stringLength);
-   };
-   // @TODO restore ios
-   std::streamsize ss = out.precision();
-   int iw=9;
-   out << "Output from ";
-   out << parseFileName(__FILE__);
-   out << "::";
-   out << __func__;
-   out << "\n";
-   out << "------------------------------------------------------------------------------------" << "\n";
-   out << "  Number of events processed      :   "<< m_globalCounter[kNevents].value() << "\n";
-   if (m_globalCounter[kNInvalidTracks]>0) {
-      out << "  Number of invalid tracks        :   "<< m_globalCounter[kNInvalidTracks].value() << "\n";
-   }
-   if (m_globalCounter[kNTracksWithoutParam]>0) {
-      out << "  Tracks without parameters       :   "<< m_globalCounter[kNTracksWithoutParam].value() << "\n";
-   }
-   out << "  statistics by eta range          ------All---Barrel---Trans.-- Endcap-- Forwrd-- " << "\n";
-   out << "------------------------------------------------------------------------------------" << "\n";
-   dumpStatType(out, "  Number of candidates at input   :",    kNcandidates,iw);
-   out << "------------------------------------------------------------------------------------" << "\n";
-   dumpStatType(out, "  candidates with good score      :",    kNscoreOk,iw);
-   if (try_brem_fit) {
-      dumpStatType(out, "  + recovered after brem refit    :", kNscoreZeroBremRefit,iw);
-   }
-   dumpStatType(out, "  candidates rejected score 0     :",    kNscoreZero,iw);
-   if (try_brem_fit) {
-      dumpStatType(out, "  + m refit                       :", kNscoreZeroBremRefitFailed,iw);
-      dumpStatType(out, "  + rejected brem refit score 0   :", kNscoreZeroBremRefitScoreZero,iw);
-   }
-   out << "------------------------------------------------------------------------------------" << "\n";
-   dumpStatType(out, "  number of normal fits           :" ,   kNfits,iw);
-   if (try_brem_fit) {
-      dumpStatType(out, "  + 2nd brem fit for failed fit   :", kNrecoveryBremFits,iw);
-      dumpStatType(out, "  normal brem fits for electrons  :", kNbremFits,iw);
-   }
-   out << "------------------------------------------------------------------------------------" << "\n";
-   dumpStatType(out, "  sum of succesful fits           :",    kNgoodFits,iw);
-   dumpStatType(out, "  sum of failed fits              :",    kNfailedFits,iw);
-   out << "------------------------------------------------------------------------------------" << "\n";
-   dumpStatType(out, "  Number of subtracks created     :",    kNsubTrack,iw);
-   dumpStatType(out, "  Number of candidates excluded   :",    kNnoSubTrack,iw);
-   out << "------------------------------------------------------------------------------------" << "\n";
-   dumpStatType(out, "  Number of tracks accepted       :",    kNaccepted,iw);
-   if (try_brem_fit) {
-      dumpStatType(out, "  including number of brem fits   :", kNacceptedBrem,iw);
-   }
-   out << "------------------------------------------------------------------------------------" << "\n";
-   out << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setprecision(2)
-       << "    definition: ( 0.0 < Barrel < " << (*m_etabounds)[iBarrel-1] << " < Transition < " << (*m_etabounds)[iTransi-1]
-       << " < Endcap < " << (*m_etabounds)[iEndcap-1] << " < Forward < " << (*m_etabounds)[iForwrd-1] << " )" << "\n";
-   out << "------------------------------------------------------------------------------------" << "\n";
-   out << std::setprecision(ss);
-  }
 
 
 //==================================================================================================
@@ -254,7 +190,7 @@ TrackCollection* Trk::DenseEnvironmentsAmbiguityProcessorTool::process(const Tra
 
   TrackCollection* finalTracks = new TrackCollection;
   {
-     TrackStat stat(m_stat.etaBounds());
+     TrackStat stat(m_etaBounds);
      stat.newEvent();
      solveTracks(*trackScoreTrackMap, *prd_to_track_map, *finalTracks, cleanup_tracks,stat);
      {
@@ -277,7 +213,7 @@ void Trk::DenseEnvironmentsAmbiguityProcessorTool::addTrack(Trk::Track* track, c
                                                             std::multimap<float, TrackPtr > &scoreTrackFitflagMap,
                                                             const Trk::PRDtoTrackMap &prd_to_track_map,
                                                             std::vector<std::unique_ptr<const Trk::Track> >& cleanup_tracks,
-                                                            Trk::DenseEnvironmentsAmbiguityProcessorTool::TrackStat &stat) const
+                                        TrackStat &stat) const
 {
   // compute score
   TrackScore score;
@@ -310,8 +246,8 @@ void Trk::DenseEnvironmentsAmbiguityProcessorTool::addTrack(Trk::Track* track, c
     Trk::Track* bremTrack = fit(*track,true,Trk::electron);
     if (!bremTrack){
       ATH_MSG_DEBUG ("Brem refit failed, drop track");
-      stat.increment_by_eta(TrackStat::kNscoreZeroBremRefitFailed,track);
-      stat.increment_by_eta(TrackStat::kNfailedFits,track);
+      stat.incrementCounterByRegion(EStatType::kNscoreZeroBremRefitFailed,track);
+      stat.incrementCounterByRegion(EStatType::kNfailedFits,track);
       // clean up
       cleanup_tracks.push_back(std::unique_ptr<const Trk::Track>(track) );
       track=nullptr;
@@ -319,7 +255,7 @@ void Trk::DenseEnvironmentsAmbiguityProcessorTool::addTrack(Trk::Track* track, c
       if (m_trackSummaryTool.isEnabled()) {
          m_trackSummaryTool->computeAndReplaceTrackSummary(*bremTrack,&prd_to_track_map,m_suppressHoleSearch);
       }
-      stat.increment_by_eta(TrackStat::kNgoodFits,bremTrack);
+      stat.incrementCounterByRegion(EStatType::kNgoodFits,bremTrack);
       // rerun score
       score = m_scoringTool->score( *bremTrack, suppressHoleSearch );
       cleanup_tracks.push_back(std::unique_ptr<const Trk::Track>(track) );
@@ -327,20 +263,20 @@ void Trk::DenseEnvironmentsAmbiguityProcessorTool::addTrack(Trk::Track* track, c
       // do we accept the track ?
       if (score!=0){
         ATH_MSG_DEBUG ("Brem refit successful, recovered track  ("<< track <<") has score "<<score);
-        stat.increment_by_eta(TrackStat::kNscoreZeroBremRefit,bremTrack);
+        stat.incrementCounterByRegion(EStatType::kNscoreZeroBremRefit,bremTrack);
         // add track to map, map is sorted small to big !
         scoreTrackFitflagMap.emplace( -score, TrackPtr(bremTrack, true) );
         return;
       } 
         ATH_MSG_DEBUG ("Brem refit gave still track score zero, reject it");
-        stat.increment_by_eta(TrackStat::kNscoreZeroBremRefitScoreZero,bremTrack);
+        stat.incrementCounterByRegion(EStatType::kNscoreZeroBremRefitScoreZero,bremTrack);
         // clean up
         cleanup_tracks.push_back(std::unique_ptr<const Trk::Track>(bremTrack) );
       
     }
   } else {
     ATH_MSG_DEBUG ("Track score is zero, reject it");
-    stat.increment_by_eta(TrackStat::kNscoreZero,track);
+    stat.incrementCounterByRegion(EStatType::kNscoreZero,track);
     // @TODO can delete this track ?
     cleanup_tracks.push_back(std::unique_ptr<const Trk::Track>(track) );
   }
@@ -352,13 +288,13 @@ void Trk::DenseEnvironmentsAmbiguityProcessorTool::solveTracks(const TracksScore
                                                                Trk::PRDtoTrackMap &prd_to_track_map,
                                                                TrackCollection &finalTracks,
                                                                std::vector<std::unique_ptr<const Trk::Track> > &cleanup_tracks,
-                                                               Trk::DenseEnvironmentsAmbiguityProcessorTool::TrackStat &stat) const
+                                           TrackStat &stat) const
 {
 
   std::multimap<float, TrackPtr  > scoreTrackFitflagMap;
   for(const std::pair< const Trk::Track *, float> &scoreTrack: trackScoreTrackMap){
      scoreTrackFitflagMap.emplace(scoreTrack.second, TrackPtr(scoreTrack.first) );
-     stat.increment_by_eta(TrackStat::kNcandidates,scoreTrack.first);
+     stat.incrementCounterByRegion(EStatType::kNcandidates,scoreTrack.first);
   }
 
   ATH_MSG_DEBUG ("Starting to solve tracks");
@@ -386,9 +322,9 @@ void Trk::DenseEnvironmentsAmbiguityProcessorTool::solveTracks(const TracksScore
     {
       // track can be kept as is and is already fitted
        ATH_MSG_DEBUG ("Accepted track "<<atrack.track()<<"\t has score "<<-ascore);
-       stat.increment_by_eta(TrackStat::kNaccepted, atrack.track() );
+       stat.incrementCounterByRegion(EStatType::kNaccepted, atrack.track() );
        if (m_tryBremFit && atrack.track()->info().trackProperties(Trk::TrackInfo::BremFit)) {
-          stat.increment_by_eta(TrackStat::kNacceptedBrem,atrack.track());
+          stat.incrementCounterByRegion(EStatType::kNacceptedBrem,atrack.track());
        }
 
       //Compute the fitQuality
@@ -442,7 +378,7 @@ void Trk::DenseEnvironmentsAmbiguityProcessorTool::solveTracks(const TracksScore
     else if ( cleanedTrack ) //cleanedTrack != atrack
     {
       ATH_MSG_DEBUG ("Candidate excluded, add subtrack to map. Track "<<cleanedTrack.get());
-      stat.increment_by_eta(TrackStat::kNsubTrack,cleanedTrack.get());
+      stat.incrementCounterByRegion(EStatType::kNsubTrack,cleanedTrack.get());
 
       // for this case clenedTrack is a new created object.
       addTrack(cleanedTrack.release(), false, scoreTrackFitflagMap, prd_to_track_map, cleanup_tracks, stat);
@@ -456,7 +392,7 @@ void Trk::DenseEnvironmentsAmbiguityProcessorTool::solveTracks(const TracksScore
     {
       // track should be discarded
       ATH_MSG_DEBUG ("Track "<< atrack.track() << " is excluded, no subtrack, reject");
-      stat.increment_by_eta(TrackStat::kNnoSubTrack,atrack.track());
+      stat.incrementCounterByRegion(EStatType::kNnoSubTrack,atrack.track());
 
       // remove original copy, but delay removal since some pointer to it or its constituents may still be in used
       if (atrack.newTrack()) {
@@ -473,7 +409,7 @@ void Trk::DenseEnvironmentsAmbiguityProcessorTool::solveTracks(const TracksScore
 //==================================================================================================
 Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitTrack( const Trk::Track* track,
                                                                       Trk::PRDtoTrackMap &prd_to_track_map,
-                                                                      Trk::DenseEnvironmentsAmbiguityProcessorTool::TrackStat &stat) const
+                                                  TrackStat &stat) const
 {
   Trk::Track* newTrack = nullptr;
   if (!m_suppressTrackFit){
@@ -533,7 +469,7 @@ Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitTrack( const Trk:
 
 Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitPrds( const Trk::Track* track,
                                                                      Trk::PRDtoTrackMap &prd_to_track_map,
-                                                                     Trk::DenseEnvironmentsAmbiguityProcessorTool::TrackStat &stat) const
+                                                 TrackStat &stat) const
 {
 
   // get vector of PRDs
@@ -563,7 +499,7 @@ Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitPrds( const Trk::
   if (m_tryBremFit && track->info().trackProperties(Trk::TrackInfo::BremFit))
   {
 
-    stat.increment_by_eta(TrackStat::kNbremFits,track);
+    stat.incrementCounterByRegion(EStatType::kNbremFits,track);
 
     ATH_MSG_VERBOSE ("Brem track, refit with electron brem fit");
     // TODO revert once GlobalChi2Fitter properly handles brem fits when 
@@ -574,7 +510,7 @@ Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitPrds( const Trk::
   }
   else
   {
-    stat.increment_by_eta(TrackStat::kNfits,track);
+    stat.incrementCounterByRegion(EStatType::kNfits,track);
 
     ATH_MSG_VERBOSE ("Normal track, refit");
     newTrack = fit(prds, *par, true, m_particleHypothesis);
@@ -582,7 +518,7 @@ Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitPrds( const Trk::
     if (!newTrack && m_tryBremFit && par->pT() > m_pTminBrem &&
   (!m_caloSeededBrem || track->info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI)))
     {
-      stat.increment_by_eta(TrackStat::kNrecoveryBremFits,track);
+      stat.incrementCounterByRegion(EStatType::kNrecoveryBremFits,track);
       ATH_MSG_VERBOSE ("Normal fit failed, try brem recovery");
       // TODO revert once GlobalChi2Fitter properly handles brem fits when 
       //      starting from prds
@@ -593,13 +529,13 @@ Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitPrds( const Trk::
   }
   
   if(newTrack) {
-    stat.increment_by_eta(TrackStat::kNgoodFits,newTrack);
+    stat.incrementCounterByRegion(EStatType::kNgoodFits,newTrack);
     //keeping the track of previously accumulated TrackInfo
     const Trk::TrackInfo& old_info = track->info();
     newTrack->info().addPatternReco(old_info);
   }
   else {
-     stat.increment_by_eta(TrackStat::kNfailedFits,track);
+     stat.incrementCounterByRegion(EStatType::kNfailedFits,track);
   }
   return newTrack;
 }
@@ -607,7 +543,7 @@ Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitPrds( const Trk::
 //==================================================================================================
 
 Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitRots(const Trk::Track* track,
-                                                                    Trk::DenseEnvironmentsAmbiguityProcessorTool::TrackStat &stat) const
+                                                TrackStat &stat) const
 {
 
   ATH_MSG_VERBOSE ("Refit track "<<track);
@@ -618,14 +554,14 @@ Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitRots(const Trk::T
   if (m_tryBremFit &&
       track->info().trackProperties(Trk::TrackInfo::BremFit))
   {
-    stat.increment_by_eta(TrackStat::kNbremFits,track);
+    stat.incrementCounterByRegion(EStatType::kNbremFits,track);
     ATH_MSG_VERBOSE ("Brem track, refit with electron brem fit");
     newTrack = fit(*track, true, Trk::electron);
   }
   else
   {
 
-    stat.increment_by_eta(TrackStat::kNfits,track);
+    stat.incrementCounterByRegion(EStatType::kNfits,track);
     ATH_MSG_VERBOSE ("Normal track, refit");
     newTrack = fit(*track, true, m_particleHypothesis);
 
@@ -633,7 +569,7 @@ Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitRots(const Trk::T
         track->trackParameters()->front()->pT() > m_pTminBrem &&
         (!m_caloSeededBrem || track->info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI)))
     {
-      stat.increment_by_eta(TrackStat::kNrecoveryBremFits,track);
+      stat.incrementCounterByRegion(EStatType::kNrecoveryBremFits,track);
       ATH_MSG_VERBOSE ("Normal fit failed, try brem recovery");
       newTrack = fit(*track, true, Trk::electron);
     }
@@ -641,13 +577,13 @@ Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitRots(const Trk::T
 
   if(newTrack)
   {
-    stat.increment_by_eta(TrackStat::kNgoodFits,newTrack);
+    stat.incrementCounterByRegion(EStatType::kNgoodFits,newTrack);
     //keeping the track of previously accumulated TrackInfo
     const Trk::TrackInfo& old_info = track->info();
     newTrack->info().addPatternReco(old_info);
   }
   else {
-    stat.increment_by_eta(TrackStat::kNfailedFits,track);
+    stat.incrementCounterByRegion(EStatType::kNfailedFits,track);
   }
   return newTrack;
 }
@@ -909,3 +845,66 @@ Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitTracksFromB(const
     }
   }
 }
+
+void 
+Trk::DenseEnvironmentsAmbiguityProcessorTool::dumpStat(MsgStream &out) const{
+   auto parseFileName=[](const std::string & fullname){
+    auto dotPosition = fullname.rfind(".");
+    auto slashPosition = fullname.rfind("/");
+    auto stringLength = dotPosition - slashPosition;
+    return fullname.substr(slashPosition, stringLength);
+   };
+   // @TODO restore ios
+   std::streamsize ss = out.precision();
+   int iw=9;
+   out << "Output from ";
+   out << parseFileName(__FILE__);
+   out << "::";
+   out << __func__;
+   out << "\n";
+   out << "------------------------------------------------------------------------------------" << "\n";
+   out << "  Number of events processed      :   "<< m_stat.globalCount(TrackStat::nEvents) << "\n";
+   if (const auto nInvalid = m_stat.globalCount(TrackStat::nInvalidTracks); nInvalid>0) {
+      out << "  Number of invalid tracks        :   "<< nInvalid<< "\n";
+   }
+   if (const auto nNoParams = m_stat.globalCount(TrackStat::nTracksWithoutParam); nNoParams>0) {
+      out << "  Tracks without parameters       :   "<< nNoParams << "\n";
+   }
+   out << "  statistics by eta range          ------All---Barrel---Trans.-- Endcap-- Forwrd-- " << "\n";
+   out << "------------------------------------------------------------------------------------" << "\n";
+   out << m_stat.dumpRegions( "  Number of candidates at input   :",    EStatType::kNcandidates,iw);
+   out << "------------------------------------------------------------------------------------" << "\n";
+   out << m_stat.dumpRegions( "  candidates with good score      :",    EStatType::kNscoreOk,iw);
+   if (m_tryBremFit) {
+      out << m_stat.dumpRegions( "  + recovered after brem refit    :", EStatType::kNscoreZeroBremRefit,iw);
+   }
+   out << m_stat.dumpRegions( "  candidates rejected score 0     :",    EStatType::kNscoreZero,iw);
+   if (m_tryBremFit) {
+      out << m_stat.dumpRegions( "  + m refit                       :", EStatType::kNscoreZeroBremRefitFailed,iw);
+      out << m_stat.dumpRegions( "  + rejected brem refit score 0   :", EStatType::kNscoreZeroBremRefitScoreZero,iw);
+   }
+   out << "------------------------------------------------------------------------------------" << "\n";
+   out << m_stat.dumpRegions( "  number of normal fits           :" ,   EStatType::kNfits,iw);
+   if (m_tryBremFit) {
+      out << m_stat.dumpRegions( "  + 2nd brem fit for failed fit   :", EStatType::kNrecoveryBremFits,iw);
+      out << m_stat.dumpRegions( "  normal brem fits for electrons  :", EStatType::kNbremFits,iw);
+   }
+   out << "------------------------------------------------------------------------------------" << "\n";
+   out << m_stat.dumpRegions( "  sum of succesful fits           :",    EStatType::kNgoodFits,iw);
+   out << m_stat.dumpRegions( "  sum of failed fits              :",    EStatType::kNfailedFits,iw);
+   out << "------------------------------------------------------------------------------------" << "\n";
+   out << m_stat.dumpRegions( "  Number of subtracks created     :",    EStatType::kNsubTrack,iw);
+   out << m_stat.dumpRegions( "  Number of candidates excluded   :",    EStatType::kNnoSubTrack,iw);
+   out << "------------------------------------------------------------------------------------" << "\n";
+   out << m_stat.dumpRegions( "  Number of tracks accepted       :",    EStatType::kNaccepted,iw);
+   if (m_tryBremFit) {
+      out << m_stat.dumpRegions( "  including number of brem fits   :", EStatType::kNacceptedBrem,iw);
+   }
+   out << "------------------------------------------------------------------------------------" << "\n";
+   out << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setprecision(2)
+       << "    definition: ( 0.0 < Barrel < " << m_etaBounds[TrackStat::iBarrel-1] << " < Transition < " << m_etaBounds[TrackStat::iTransi-1]
+       << " < Endcap < " << m_etaBounds[TrackStat::iEndcap-1] << " < Forward < " << m_etaBounds[TrackStat::iForwrd-1] << " )" << "\n";
+   out << "------------------------------------------------------------------------------------" << "\n";
+   out << std::setprecision(ss);
+  }
+
diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.h b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.h
index 9ea3b8ded714ccaf3ad889dd248499f88c9fa467..ebe80437b0587eb8f44747e8a958cd9a6961486b 100644
--- a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.h
+++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.h
@@ -24,14 +24,15 @@
 #include "TrkTrack/TrackCollection.h"
 #include "TrkTrack/TrackSeedMap.h"
 #include "TrkParameters/TrackParameters.h"
-
+//
+#include "AmbiCounter.icc"
+//
 #include <map>
-#include <set>
 #include <vector>
-#include <ostream>
 
 #include "TrackPtr.h"
 
+
 class AtlasDetectorID;
 class PixelID;
 
@@ -42,21 +43,41 @@ namespace InDet{
 }
 
 namespace Trk {
-
   class ITrackScoringTool;
   class ITruthToTrack;
   class IExtrapolator;
-
+  //
   class DenseEnvironmentsAmbiguityProcessorTool : public AthAlgTool, 
-                                                  virtual public ITrackAmbiguityProcessorTool
-    {
-    public:
-    
-      // default methods
-      DenseEnvironmentsAmbiguityProcessorTool(const std::string&,const std::string&,const IInterface*);
-      virtual ~DenseEnvironmentsAmbiguityProcessorTool ();
-      virtual StatusCode initialize() override;
-      virtual StatusCode finalize  () override;
+        virtual public ITrackAmbiguityProcessorTool{
+  public:
+    enum class EStatType {
+      kNtracks,
+      kNinvalid,
+      kNcandidates,
+      kNscoreOk,
+      kNscoreZeroBremRefit,
+      kNscoreZeroBremRefitFailed,
+      kNscoreZeroBremRefitScoreZero,
+      kNscoreZero,
+      kNaccepted,
+      kNsubTrack,
+      kNnoSubTrack,
+      kNacceptedBrem,
+      kNbremFits,
+      kNfits,
+      kNrecoveryBremFits,
+      kNgoodFits,
+      kNfailedFits,
+      kNCounter
+   };
+   using TrackStat = AmbiCounter<EStatType>;
+   // default methods
+   DenseEnvironmentsAmbiguityProcessorTool(const std::string&,const std::string&,const IInterface*);
+   virtual ~DenseEnvironmentsAmbiguityProcessorTool ();
+   virtual StatusCode initialize() override;
+   virtual StatusCode finalize  () override;
+   void dumpStat(MsgStream &out) const;
+
 
       /**Returns a processed TrackCollection from the passed 'tracks'
      @param tracks collection of tracks which will have ambiguities resolved. Will not be 
@@ -71,108 +92,31 @@ namespace Trk {
       /** statistics output to be called by algorithm during finalize. */
       virtual void statistics() override;
     private:
-      class TrackStat {
-      public:
-         TrackStat(const std::vector<float> &eta_bounds) : m_etabounds(&eta_bounds){}
-
-         enum EStatType {
-            kNtracks,
-            kNinvalid,
-            kNcandidates,
-            // kNcandScoreZero,
-            // kNcandDouble,
-            kNscoreOk,
-            kNscoreZeroBremRefit,
-            kNscoreZeroBremRefitFailed,
-            kNscoreZeroBremRefitScoreZero,
-            kNscoreZero,
-            kNaccepted,
-            kNsubTrack,
-            kNnoSubTrack,
-            kNacceptedBrem,
-            kNbremFits,
-            kNfits,
-            kNrecoveryBremFits,
-            kNgoodFits,
-            kNfailedFits,
-            kNStatTypes
-         };
-         enum EGlobalStatType {
-            kNevents,
-            kNInvalidTracks,
-            kNTracksWithoutParam,
-            kNGlobalStatTypes,
-         };
-         /** internal monitoring: categories for counting different types of extension results*/
-         enum StatIndex {iAll = 0, iBarrel = 1, iTransi = 2, iEndcap = 3, iForwrd = 4, kNStatRegions=5};
-
-         class Counter {
-         public:
-            Counter &operator+=(const Counter &a) {
-               m_counter += a.m_counter;
-               return *this;
-            }
-            Counter &operator++()   { ++m_counter; return *this;}
-            operator int() const    { return m_counter; }
-            int value()    const    { return m_counter; }
-         private:
-            unsigned int m_counter=0;
-         };
-
-         void newEvent() {
-            ++m_globalCounter[kNevents];
-         }
-
-         TrackStat &operator+=(const TrackStat &a) {
-            for (unsigned int i=0; i<kNGlobalStatTypes; ++i) {
-               m_globalCounter[i]+= a.m_globalCounter[i];
-            }
-            for (unsigned int i=0; i<kNStatTypes; ++i) {
-               for (unsigned int region_i=0; region_i< kNStatRegions; ++region_i) {
-                  m_counter[i][region_i] += a.m_counter[i][region_i];
-               }
-            }
-            return *this;
-         }
-
-         /** helper for monitoring and validation: does success/failure counting */
-         void increment_by_eta(EStatType type, const Track* track, bool updateAll=true);
-         void dumpStatType(MsgStream &out, const std::string &head, EStatType type, unsigned short iw=9) const;
-         void dump(MsgStream &out, bool try_brem_fit) const;
-
-         const std::vector<float>  &etaBounds() const { return *m_etabounds; }  //!< eta intervals for internal monitoring
-
-      private:
-         std::array<Counter,kNGlobalStatTypes>                      m_globalCounter;
-         std::array<std::array<Counter, kNStatRegions>,kNStatTypes> m_counter;
-
-         const std::vector<float>  *m_etabounds;           //!< eta intervals for internal monitoring
-      };
 
       //transfer ownership
       void addTrack(Track* track, const bool fitted,
                     std::multimap<float, TrackPtr > &scoreTrackFitflagMap,
                     const Trk::PRDtoTrackMap &prd_to_track_map,
                     std::vector<std::unique_ptr<const Trk::Track> >& cleanup_tracks,
-                    Trk::DenseEnvironmentsAmbiguityProcessorTool::TrackStat &stat) const;
+                    TrackStat &stat) const;
 
       void solveTracks(const TracksScores& trackScoreTrackMap,
                        Trk::PRDtoTrackMap &prd_to_track_map,
                        TrackCollection &finalTracks,
                        std::vector<std::unique_ptr<const Trk::Track> >& cleanup_tracks,
-                       Trk::DenseEnvironmentsAmbiguityProcessorTool::TrackStat &stat) const;
+                       TrackStat &stat) const;
 
       /** refit track */
       Track* refitTrack( const Trk::Track* track, Trk::PRDtoTrackMap &prd_to_track_map,
-                         Trk::DenseEnvironmentsAmbiguityProcessorTool::TrackStat &stat) const;
+     TrackStat &stat) const;
 
       /** refit PRDs */
       Track* refitPrds( const Track* track, Trk::PRDtoTrackMap &prd_to_track_map,
-                        Trk::DenseEnvironmentsAmbiguityProcessorTool::TrackStat &stat) const;
+    TrackStat &stat) const;
 
       /** refit ROTs corresponding to PRDs*/
       //TODO or Q: new created track, why const
-      Track* refitRots( const Track* track, Trk::DenseEnvironmentsAmbiguityProcessorTool::TrackStat &stat) const;
+      Track* refitRots( const Track* track, TrackStat &stat) const;
 
       /** stores the minimal dist(trk,trk) for covariance correction*/
       void storeTrkDistanceMapdR(TrackCollection& tracks,
@@ -269,7 +213,7 @@ namespace Trk {
       /**These allow us to retrieve the helpers*/
       const PixelID* m_pixelId;
       const AtlasDetectorID* m_idHelper;
-      std::vector<float>     m_etabounds;           //!< eta intervals for internal monitoring
+      std::vector<float>     m_etaBounds;           //!< eta intervals for internal monitoring
 
       SG::WriteHandleKey<InDet::DRMap>                    m_dRMap;      //!< the actual dR map         
 
@@ -348,41 +292,6 @@ namespace Trk {
       }
 } //end ns
 
-void Trk::DenseEnvironmentsAmbiguityProcessorTool::TrackStat::increment_by_eta(EStatType type,
-                                                                               const Track* track,
-                                                                               bool updateAll) {
-   std::array<Counter,kNStatRegions> &Ntracks = m_counter[type];
-   if (updateAll) ++Ntracks[iAll];
-
-   // test
-   if (!track) {
-      ++m_globalCounter[kNInvalidTracks];
-   }
-   // use first parameter
-   if (!track->trackParameters()) {
-      ++m_globalCounter[kNTracksWithoutParam];
-   }
-   else {
-      double eta = track->trackParameters()->front()->eta();
-      for (unsigned int region_i=1; region_i< kNStatRegions; ++region_i) {
-         if (std::abs(eta)      < (*m_etabounds)[region_i-1]) {
-            ++Ntracks[region_i];
-            break;
-         }
-      }
-   }
-}
-
-void Trk::DenseEnvironmentsAmbiguityProcessorTool::TrackStat::dumpStatType(MsgStream &out,
-                                                                           const std::string &head,
-                                                                           EStatType type,
-                                                                           unsigned short iw) const {
-   out << head << std::setiosflags(std::ios::dec);
-   for (unsigned region_i=0; region_i<kNStatRegions; ++region_i) {
-      out << std::setw(iw) << m_counter[type][region_i].value();
-   }
-   out << "\n";
-}
 
 #endif // TrackAmbiguityProcessorTool_H
 
diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.cxx b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.cxx
index fd5b425131e4134f8495ea93822f88208fc04812..9cca17d85c476a3bc76d7469762d73e786053f19 100644
--- a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.cxx
+++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.cxx
@@ -29,8 +29,8 @@ Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::DenseEnvironmentsAmbiguitySco
   m_scoringTool("Trk::TrackScoringTool/TrackScoringTool"), 
   m_selectionTool("InDet::InDetDenseEnvAmbiTrackSelectionTool/InDetAmbiTrackSelectionTool"),
   m_splitProbTool("InDet::NnPixelClusterSplitProbTool/NnPixelClusterSplitProbTool"),
-  m_etabounds{0.8, 1.6, 2.5,4.0},
-  m_stat(m_etabounds)
+  m_etaBounds{0.8, 1.6, 2.5,4.0},
+  m_stat(m_etaBounds)
 {
 
   declareInterface<ITrackAmbiguityScoreProcessorTool>(this);
@@ -41,7 +41,7 @@ Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::DenseEnvironmentsAmbiguitySco
   declareProperty("SplitClusterMap_new"  , m_splitClusterMapKey);
   declareProperty("sharedProbCut"        , m_sharedProbCut           = 0.3);
   declareProperty("sharedProbCut2"       , m_sharedProbCut2          = 0.3);
-  declareProperty("etaBounds"            , m_etabounds,"eta intervals for internal monitoring");
+  declareProperty("etaBounds"            , m_etaBounds,"eta intervals for internal monitoring");
 
 }
 //==================================================================================================
@@ -68,9 +68,9 @@ StatusCode Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::initialize()
   ATH_CHECK( m_splitClusterMapKey_last.initialize(!m_splitClusterMapKey_last.key().empty()) );
   ATH_CHECK( m_splitClusterMapKey.initialize(!m_splitClusterMapKey.key().empty()) );
 
-  if (m_stat.etaBounds().size() != TrackStat::kNStatRegions-1) {
-     ATH_MSG_FATAL("There must be exactly " << (TrackStat::kNStatRegions-1) << " eta bounds but "
-                   << m_stat.etaBounds().size() << " are set." );
+  if (m_etaBounds.size() != TrackStat3::nRegions-1) {
+     ATH_MSG_FATAL("There must be exactly " << (TrackStat3::nRegions-1) << " eta bounds but "
+                   << m_etaBounds.size() << " are set." );
      return StatusCode::FAILURE;
   }
 
@@ -88,46 +88,11 @@ void Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::statistics() {
       MsgStream &out=msg(MSG::INFO);
       out << " -- statistics " << "\n";
       std::lock_guard<std::mutex> lock( m_statMutex );
-      m_stat.dump(out);
+      dumpStat(out);
       out << endmsg;
    }
 }
 
-void Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::TrackStat::dump(MsgStream &out) const
-{
-   auto parseFileName=[](const std::string & fullname){
-     auto dotPosition = fullname.rfind('.');
-     auto slashPosition = fullname.rfind('/');
-     auto stringLength = dotPosition - slashPosition;
-     return fullname.substr(slashPosition, stringLength);
-   };
-   std::streamsize ss = out.precision();
-   int iw=9;
-   out << "Output from ";
-   out << parseFileName(__FILE__);
-   out << "::";
-   out << __func__;
-   out << "\n";
-   out << "------------------------------------------------------------------------------------" << "\n";
-   out << "  Number of events processed      :   "<< m_globalCounter[kNevents].value() << "\n";
-   if (m_globalCounter[kNInvalidTracks]>0) {
-      out << "  Number of invalid tracks        :   "<< m_globalCounter[kNInvalidTracks].value() << "\n";
-   }
-   if (m_globalCounter[kNTracksWithoutParam]>0) {
-      out << "  Tracks without parameters       :   "<< m_globalCounter[kNTracksWithoutParam].value() << "\n";
-   }
-   out << "  statistics by eta range          ------All---Barrel---Trans.-- Endcap-- Forwrd-- " << "\n";
-   out << "------------------------------------------------------------------------------------" << "\n";
-   dumpStatType(out, "  Number of candidates at input   :",    kNcandidates,iw);
-   dumpStatType(out, "  - candidates rejected score 0   :",    kNcandScoreZero,iw);
-   dumpStatType(out, "  - candidates rejected as double :",    kNcandDouble,iw);
-   out << "------------------------------------------------------------------------------------" << "\n";
-   out << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setprecision(2)
-       << "    definition: ( 0.0 < Barrel < " << (*m_etabounds)[iBarrel-1] << " < Transition < " << (*m_etabounds)[iTransi-1]
-       << " < Endcap < " << (*m_etabounds)[iEndcap-1] << " < Forward < " << (*m_etabounds)[iForwrd-1] << " )" << "\n";
-   out << "------------------------------------------------------------------------------------" << "\n";
-   out << std::setprecision(ss);
-}
 
 //==================================================================================================
 
@@ -181,7 +146,7 @@ void Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::process(std::vector<cons
 void Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::addNewTracks(std::vector<const Track*>* tracks,
                                                                      Trk::TracksScores* trackScoreTrackMap) const
 {
-  TrackStat stat(m_stat.etaBounds());
+  TrackStat3 stat(m_etaBounds);
   stat.newEvent();
 
   std::unique_ptr<Trk::PRDtoTrackMap> prd_to_track_map( m_assoTool->createPRDtoTrackMap() );
@@ -191,7 +156,7 @@ void Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::addNewTracks(std::vector
  
   for(const Track* a_track : *tracks) {
     ATH_MSG_DEBUG ("Processing track candidate "<<a_track);
-    stat.increment_by_eta(TrackStat::kNcandidates,a_track); // @TODO should go to the score processor
+    stat.incrementCounterByRegion(EStatType::kNcandidates,a_track); // @TODO should go to the score processor
     
     // only fitted tracks get hole search, input is not fitted
     float score = m_scoringTool->score( *a_track, true);
@@ -199,15 +164,15 @@ void Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::addNewTracks(std::vector
     // veto tracks with score 0
     bool reject = score==0;      
     if (reject){
-      stat.increment_by_eta(TrackStat::kNcandScoreZero,a_track);
+      stat.incrementCounterByRegion(EStatType::kNcandScoreZero,a_track);
     } else {// double track rejection
-      std::vector<const Trk::PrepRawData*> prds = m_assoTool->getPrdsOnTrack(*prd_to_track_map, *a_track);
+      const std::vector<const Trk::PrepRawData*> & prds = m_assoTool->getPrdsOnTrack(*prd_to_track_map, *a_track);
       // convert to set
-      PrdSignature prdSig( prds.begin(),prds.end() );
+      //PrdSignature prdSig( prds.begin(),prds.end() );
       // we try to insert it into the set, if we fail (pair.second), it then exits already
-      if ( !(prdSigSet.insert(prdSig)).second ) {
+      if ( !(prdSigSet.insert(prds)).second ) {
         ATH_MSG_DEBUG ("Double track, reject it !");
-        stat.increment_by_eta(TrackStat::kNcandDouble,a_track);
+        stat.incrementCounterByRegion(EStatType::kNcandDouble,a_track);
         reject = true;
       } else {
         ATH_MSG_DEBUG ("Insert new track in PrdSignatureSet");
@@ -269,7 +234,8 @@ void Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::updatePixelSplitInformat
 }
 
 //==================================================================================================
-void Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::overlappingTracks(const TracksScores* scoredTracks,
+void 
+Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::overlappingTracks(const TracksScores* scoredTracks,
                                                                           InDet::PixelGangedClusterAmbiguities *splitClusterMap,
                                                                           Trk::PRDtoTrackMap &prd_to_track_map) const
 {
@@ -372,5 +338,43 @@ void Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::overlappingTracks(const
     }
     
   }  
-  }
+}
+
+void
+Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::dumpStat(MsgStream &out) const
+{
+   auto parseFileName=[](const std::string & fullname){
+     auto dotPosition = fullname.rfind(".");
+     auto slashPosition = fullname.rfind("/");
+     auto stringLength = dotPosition - slashPosition;
+     return fullname.substr(slashPosition, stringLength);
+   };
+   std::streamsize ss = out.precision();
+   int iw=9;
+   out << "Output from ";
+   out << parseFileName(__FILE__);
+   out << "::";
+   out << __func__;
+   out << "\n";
+   out << "------------------------------------------------------------------------------------" << "\n";
+   out << "  Number of events processed      :   "<< m_stat.globalCount(TrackStat3::nEvents) << "\n";
+   if (m_stat.globalCount(TrackStat3::nInvalidTracks)>0) {
+      out << "  Number of invalid tracks        :   "<< m_stat.globalCount(TrackStat3::nInvalidTracks) << "\n";
+   }
+   if (m_stat.globalCount(TrackStat3::nTracksWithoutParam)>0) {
+      out << "  Tracks without parameters       :   "<< m_stat.globalCount(TrackStat3::nTracksWithoutParam) << "\n";
+   }
+   out << "  statistics by eta range          ------All---Barrel---Trans.-- Endcap-- Forwrd-- " << "\n";
+   out << "------------------------------------------------------------------------------------" << "\n";
+   out << m_stat.dumpRegions("  Number of candidates at input   :",    EStatType::kNcandidates,iw);
+   out << m_stat.dumpRegions("  - candidates rejected score 0   :",    EStatType::kNcandScoreZero,iw);
+   out << m_stat.dumpRegions("  - candidates rejected as double :",    EStatType::kNcandDouble,iw);
+   out << "------------------------------------------------------------------------------------" << "\n";
+   out << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setprecision(2)
+       << "    definition: ( 0.0 < Barrel < " << m_etaBounds[TrackStat3::iBarrel-1] << " < Transition < " << m_etaBounds[TrackStat3::iTransi-1]
+       << " < Endcap < " << m_etaBounds[TrackStat3::iEndcap-1] << " < Forward < " << m_etaBounds[TrackStat3::iForwrd-1] << " )" << "\n";
+   out << "------------------------------------------------------------------------------------" << "\n";
+   out << std::setprecision(ss);
+}
+
 
diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.h b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.h
index a64481f3b548932a01c9304af0723ba7f12ac947..69cfa2e5ae91ef14b0974fc35fcfe09778d57acc 100644
--- a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.h
+++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.h
@@ -21,12 +21,10 @@
 
 #include "TrkToolInterfaces/IPRDtoTrackMapTool.h"
 #include "TrkEventUtils/PRDtoTrackMap.h"
-
+#include "AmbiCounter.icc"
 #include <map>
 #include <set>
 #include <vector>
-#include <ostream>
-
 
 namespace InDet{
   class IPixelClusterSplitProbTool;
@@ -40,12 +38,19 @@ namespace Trk {
 
   class DenseEnvironmentsAmbiguityScoreProcessorTool: public AthAlgTool, 
                                                       virtual public ITrackAmbiguityScoreProcessorTool
-    {
-    public:
-      
+  {
+  public:
+    enum class EStatType {
+      kNtracks,
+      kNcandidates,
+      kNcandScoreZero,
+      kNcandDouble,
+      kNCounter
+    };
+    using TrackStat3 = AmbiCounter<EStatType>;
       // public types
       typedef std::multimap< TrackScore, const Track* > TrackScoreMap;
-      typedef std::set<const PrepRawData*> PrdSignature;
+      typedef std::vector<const PrepRawData*> PrdSignature;
       typedef std::set<PrdSignature> PrdSignatureSet;
       
       // default methods
@@ -59,69 +64,9 @@ namespace Trk {
 
       /** statistics output to be called by algorithm during finalize. */
       void statistics() override;
+      void dumpStat(MsgStream &out) const;
     private:
-      class TrackStat {
-      public:
-         TrackStat(const std::vector<float> &eta_bounds) : m_etabounds(&eta_bounds){}
-
-         enum EStatType {
-            kNtracks,
-            kNcandidates,
-            kNcandScoreZero,
-            kNcandDouble,
-            kNStatTypes
-         };
-         enum EGlobalStatType {
-            kNevents,
-            kNInvalidTracks,
-            kNTracksWithoutParam,
-            kNGlobalStatTypes,
-         };
-         /** internal monitoring: categories for counting different types of extension results*/
-         enum StatIndex {iAll = 0, iBarrel = 1, iTransi = 2, iEndcap = 3, iForwrd = 4, kNStatRegions=5};
-
-         class Counter {
-         public:
-            Counter &operator+=(const Counter &a) {
-               m_counter += a.m_counter;
-               return *this;
-            }
-            Counter &operator++()   { ++m_counter; return *this;}
-            operator int() const    { return m_counter; }
-            int value()    const    { return m_counter; }
-         private:
-            unsigned int m_counter=0;
-         };
-
-         void newEvent() {
-            ++m_globalCounter[kNevents];
-         }
-
-         TrackStat &operator+=(const TrackStat &a) {
-            for (unsigned int i=0; i<kNGlobalStatTypes; ++i) {
-               m_globalCounter[i]+= a.m_globalCounter[i];
-            }
-            for (unsigned int i=0; i<kNStatTypes; ++i) {
-               for (unsigned int region_i=0; region_i< kNStatRegions; ++region_i) {
-                  m_counter[i][region_i] += a.m_counter[i][region_i];
-               }
-            }
-            return *this;
-         }
-
-         /** helper for monitoring and validation: does success/failure counting */
-         void increment_by_eta(EStatType type, const Track* track, bool updateAll=true);
-         void dumpStatType(MsgStream &out, const std::string &head, EStatType type, unsigned short iw=9) const;
-         void dump(MsgStream &out) const;
-
-         const std::vector<float>  &etaBounds() const { return *m_etabounds; }  //!< eta intervals for internal monitoring
-
-      private:
-         std::array<Counter,kNGlobalStatTypes>                      m_globalCounter;
-         std::array<std::array<Counter, kNStatRegions>,kNStatTypes> m_counter;
-
-         const std::vector<float>  *m_etabounds;           //!< eta intervals for internal monitoring
-      };
+
       
       /**Add passed TrackCollection, and Trk::PrepRawData from tracks to caches
          @param tracks the TrackCollection is looped over, 
@@ -175,46 +120,11 @@ namespace Trk {
       /**NN split sprob cut for 3 particle clusters */      
       float m_sharedProbCut2;
 
-      std::vector<float>     m_etabounds;           //!< eta intervals for internal monitoring
+      std::vector<float>     m_etaBounds;           //!< eta intervals for internal monitoring
       mutable std::mutex m_statMutex;
-      mutable TrackStat  m_stat ATLAS_THREAD_SAFE;
+      mutable TrackStat3  m_stat ATLAS_THREAD_SAFE;
   };
 } //end ns
 
-void Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::TrackStat::increment_by_eta(EStatType type,
-                                                                               const Track* track,
-                                                                               bool updateAll) {
-   std::array<Counter,kNStatRegions> &Ntracks = m_counter[type];
-   if (updateAll) ++Ntracks[iAll];
-
-   // test
-   if (!track) {
-      ++m_globalCounter[kNInvalidTracks];
-   }
-   // use first parameter
-   if (!track->trackParameters()) {
-      ++m_globalCounter[kNTracksWithoutParam];
-   }
-   else {
-      double eta = track->trackParameters()->front()->eta();
-      for (unsigned int region_i=1; region_i< kNStatRegions; ++region_i) {
-         if (std::abs(eta)      < (*m_etabounds)[region_i-1]) {
-            ++Ntracks[region_i];
-            break;
-         }
-      }
-   }
-}
-
-void Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::TrackStat::dumpStatType(MsgStream &out,
-                                                                           const std::string &head,
-                                                                           EStatType type,
-                                                                           unsigned short iw) const {
-   out << head << std::setiosflags(std::ios::dec);
-   for (unsigned region_i=0; region_i<kNStatRegions; ++region_i) {
-      out << std::setw(iw) << m_counter[type][region_i].value();
-   }
-   out << "\n";
-}
 
 #endif // TrackAmbiguityProcessorTool_H
diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.cxx b/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.cxx
index a67dd8230344107925d51845e1448db83ed2fca9..732a75b3b66279310040dd962d10c799c37df8c5 100644
--- a/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.cxx
+++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.cxx
@@ -11,8 +11,6 @@
 #include "TrkToolInterfaces/IPRD_AssociationTool.h"
 #include "TrkTrack/TrackCollection.h"
 #include "TrkTrack/TrackInfo.h"
-#include <ext/functional>
-#include <iterator>
 #include <map>
 #include <memory>
 
@@ -31,7 +29,7 @@ Trk::SimpleAmbiguityProcessorTool::SimpleAmbiguityProcessorTool(const std::strin
                 2.5,
                 2.5,
                 10.0} ),
-  m_Nevents(0)
+  m_stat(m_etabounds)
 {
   // statitics stuff
 
@@ -123,101 +121,30 @@ StatusCode Trk::SimpleAmbiguityProcessorTool::initialize()
   }
 
   // statistics
-  if (m_etabounds.size() != kNRegions) {
-     ATH_MSG_ERROR( "There must be exactly " << kNRegions
+  if (m_etabounds.size() != Counter::nRegions) {
+     ATH_MSG_ERROR( "There must be exactly " << Counter::nRegions
                     << " etaBounds: barrel end, transition region end, end-cap end, DBM start, DBM end." );
      return StatusCode::FAILURE;
   }
-  m_stat.init();
   return sc;
 }
 //==================================================================================================
 
 
-StatusCode Trk::SimpleAmbiguityProcessorTool::finalize()
-{
+StatusCode Trk::SimpleAmbiguityProcessorTool::finalize(){
   return StatusCode::SUCCESS;
 }
 
-void Trk::SimpleAmbiguityProcessorTool::statistics()
-{
-
+void Trk::SimpleAmbiguityProcessorTool::statistics(){
   if (msgLvl(MSG::INFO)) {
      MsgStream &out=msg(MSG::INFO);
      out << " -- statistics:" << "\n";
+     std::lock_guard<std::mutex> lock( m_statMutex );
      dumpStat(out);
      out << endmsg;
   }
 }
 
-void Trk::SimpleAmbiguityProcessorTool::dumpStat(MsgStream &out) const {
-   std::lock_guard<std::mutex> lock( m_statMutex );
-    auto parseFileName=[](const std::string & fullname){
-      auto dotPosition = fullname.rfind('.');
-      auto slashPosition = fullname.rfind('/');
-      auto stringLength = dotPosition - slashPosition;
-    return fullname.substr(slashPosition, stringLength);
-   };
-   // @TODO restore ios
-    std::streamsize ss = std::cout.precision();
-    out << "Output from ";
-    out << parseFileName(__FILE__);
-    out << "::";
-    out << __func__;
-    out << "\n";
-    out <<             "---------------------------------------------------------------------------------" << "\n";
-    out <<             "  Number of events processed      :   "<< m_Nevents << "\n";
-    out <<             "  statistics by eta range          ------All---Barrel---Trans.--- Endcap---DBM---" << "\n";
-    out <<             "---------------------------------------------------------------------------------" << "\n";
-    dumpRegions(out,   "  Number of candidates at input   :", Trk::SimpleAmbiguityProcessorTool::Counter::kNcandidates);
-    dumpRegions(out,   "  - candidates rejected score 0   :", Trk::SimpleAmbiguityProcessorTool::Counter::kNcandScoreZero);
-    dumpRegions(out,   "  - candidates rejected as double :", Trk::SimpleAmbiguityProcessorTool::Counter::kNcandDouble);
-    out <<             "---------------------------------------------------------------------------------" << "\n";
-    dumpRegions(out,   "  candidates with good score      :", Trk::SimpleAmbiguityProcessorTool::Counter::kNscoreOk);
-    if (m_tryBremFit) {
-       dumpRegions(out,"  + recovered after brem refit    :", Trk::SimpleAmbiguityProcessorTool::Counter::kNscoreZeroBremRefit);
-    }
-    dumpRegions(out,   "  candidates rejected score 0     :", Trk::SimpleAmbiguityProcessorTool::Counter::kNscoreZero);
-    if (m_tryBremFit) {
-       dumpRegions(out,"  + rejected failed brem refit    :", Trk::SimpleAmbiguityProcessorTool::Counter::kNscoreZeroBremRefitFailed);
-    }
-    out <<             "---------------------------------------------------------------------------------" << "\n";
-    dumpRegions(out,   "  number of normal fits           :", Trk::SimpleAmbiguityProcessorTool::Counter::kNfits);
-    if (m_tryBremFit) {
-       dumpRegions(out,"  + 2nd brem fit for failed fit   :", Trk::SimpleAmbiguityProcessorTool::Counter::kNrecoveryBremFits);
-       dumpRegions(out,"  normal brem fits for electrons  :", Trk::SimpleAmbiguityProcessorTool::Counter::kNbremFits);
-    }
-    out <<             "---------------------------------------------------------------------------------" << "\n";
-    dumpRegions(out,   "  sum of succesful fits           :", Trk::SimpleAmbiguityProcessorTool::Counter::kNgoodFits);
-    dumpRegions(out,   "  sum of failed fits              :", Trk::SimpleAmbiguityProcessorTool::Counter::kNfailedFits);
-    out <<             "---------------------------------------------------------------------------------" << "\n";
-    dumpRegions(out,   "  Number of subtracks created     :", Trk::SimpleAmbiguityProcessorTool::Counter::kNsubTrack);
-    dumpRegions(out,   "  Number of candidates excluded   :", Trk::SimpleAmbiguityProcessorTool::Counter::kNnoSubTrack);
-    out <<             "---------------------------------------------------------------------------------" << "\n";
-    dumpRegions(out,   "  Number of tracks accepted       :", Trk::SimpleAmbiguityProcessorTool::Counter::kNaccepted);
-    if (m_tryBremFit) {
-       dumpRegions(out,"  including number of brem fits   :", Trk::SimpleAmbiguityProcessorTool::Counter::kNacceptedBrem);
-    }
-    out <<             "---------------------------------------------------------------------------------" << "\n";
-    out << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setprecision(2)
-        <<             "    definition: ( 0.0 < Barrel < " << m_etabounds[iBarrel-1] << " < Transition < " << m_etabounds[iTransi-1]
-        <<             " < Endcap < " << m_etabounds[iEndcap-1] << " DBM )" << "\n";
-    out <<             "-------------------------------------------------------------------------------" << "\n";
-    out.precision (ss);
-}
-
-//==================================================================================================
-
-/** helper function for statistics */
-void Trk::SimpleAmbiguityProcessorTool::missingTrackOrParameters(const Track* track) const {
-  if (!track) {
-     ATH_MSG_ERROR ("track pointer zero, should not happen!");
-     return;
-  }
-  if (!track->trackParameters()) {
-     ATH_MSG_WARNING ("No track parameters, needed for statistics code in Trk::SimpleAmbiguityProcessorTool!");
-  }
-}
 
 //==================================================================================================
 
@@ -225,13 +152,13 @@ void Trk::SimpleAmbiguityProcessorTool::missingTrackOrParameters(const Track* tr
     and then returns the tracks which have been selected*/
 
 
-TrackCollection*  Trk::SimpleAmbiguityProcessorTool::process(const TrackCollection* trackCol, Trk::PRDtoTrackMap *prd_to_track_map) const {
+TrackCollection*  Trk::SimpleAmbiguityProcessorTool::process(const TrackCollection* trackCol, Trk::PRDtoTrackMap *prdToTrackMap) const {
   std::vector<const Track*> tracks;
   tracks.reserve(trackCol->size());
   for(const Track* e: *trackCol){
     tracks.push_back(e);
   }
-  return process_vector(tracks, prd_to_track_map);
+  return process_vector(tracks, prdToTrackMap);
 }
 
 
@@ -246,24 +173,22 @@ TrackCollection*  Trk::SimpleAmbiguityProcessorTool::process(const TracksScores*
   return re_tracks;
 }
 
-TrackCollection*  Trk::SimpleAmbiguityProcessorTool::process_vector(std::vector<const Track*> &tracks, Trk::PRDtoTrackMap *prd_to_track_map) const{
+TrackCollection*  Trk::SimpleAmbiguityProcessorTool::process_vector(std::vector<const Track*> &tracks, Trk::PRDtoTrackMap *prdToTrackMap) const{
   using namespace std;
 
-  DEBUG_CODE( ntupleReset(tracks) );
-  DEBUG_CODE( fillEventData(tracks) );
-  ++m_Nevents; // statistics
+  m_stat.newEvent(); // statistics
 
   TrackScoreMap trackScoreTrackMap;
-  std::unique_ptr<Trk::PRDtoTrackMap> prd_to_track_map_cleanup;
-  if (!prd_to_track_map) {
+  std::unique_ptr<Trk::PRDtoTrackMap> prdToTrackMap_cleanup;
+  if (!prdToTrackMap) {
      // create internal PRD-to-track map
-     prd_to_track_map_cleanup = m_assoTool->createPRDtoTrackMap();
-     prd_to_track_map = prd_to_track_map_cleanup.get();
+     prdToTrackMap_cleanup = m_assoTool->createPRDtoTrackMap();
+     prdToTrackMap = prdToTrackMap_cleanup.get();
   }
   //put tracks into maps etc
   ATH_MSG_DEBUG ("Adding input track candidates to list");
-  Counter stat;
-  addNewTracks(tracks, trackScoreTrackMap, *prd_to_track_map, stat);
+  Counter stat(m_etabounds);
+  addNewTracks(tracks, trackScoreTrackMap, *prdToTrackMap, stat);
 
   // going to do simple algorithm for now:
   // - take track with highest score
@@ -271,73 +196,75 @@ TrackCollection*  Trk::SimpleAmbiguityProcessorTool::process_vector(std::vector<
   // - take next highest scoring tracks, and repeat
 
   ATH_MSG_DEBUG ("Solving Tracks");
-  std::vector<std::unique_ptr<const Trk::Track> > cleanup_tracks;
-  TrackCollection* final_tracks = solveTracks(trackScoreTrackMap, *prd_to_track_map,cleanup_tracks, stat);
+  std::vector<std::unique_ptr<const Trk::Track> > cleanupTracks;
+  TrackCollection* finalTracks = solveTracks(trackScoreTrackMap, *prdToTrackMap,cleanupTracks, stat);
   {
      std::lock_guard<std::mutex> lock(m_statMutex);
      m_stat += stat;
   }
-  if (msgLvl(MSG::DEBUG)) dumpTracks(*final_tracks);
-  return final_tracks;
+  if (msgLvl(MSG::DEBUG)) dumpTracks(*finalTracks);
+  return finalTracks;
 }
 
 //==================================================================================================
 void Trk::SimpleAmbiguityProcessorTool::addNewTracks(const std::vector<const Track*> &tracks,
                                                      TrackScoreMap& trackScoreTrackMap,
-                                                     Trk::PRDtoTrackMap &prd_to_track_map,
-                                                     Trk::SimpleAmbiguityProcessorTool::Counter &stat) const
+                                                     Trk::PRDtoTrackMap &prdToTrackMap,
+                                                     Counter &stat) const
 {
-  using namespace std;
-  DEBUG_CODE( findTrueTracks(&tracks) );
+  using namespace std; 
   ATH_MSG_DEBUG ("Number of tracks at Input: "<<tracks.size());
+
   /** signature map to drop double track. */
   PrdSignatureSet prdSigSet;
-  for(const Track *a_track : tracks) {
-    DEBUG_CODE( resetTrackOutliers() );
-    ATH_MSG_DEBUG ("Processing track candidate "<<a_track);
-    // statistics
-    increment_by_eta(Counter::kNcandidates,stat,a_track);
-    bool reject = false;
-    // only fitted tracks get hole search, input is not fitted
-    TrackScore score = m_scoringTool->score( *a_track, true);
-    DEBUG_CODE( setBarcodeStats(a_track,score) );
-    // veto tracks with score 0
-    if (score==0) { 
-      ATH_MSG_DEBUG ("Candidate score is zero, reject it");
-      // statistic
-      increment_by_eta(Counter::kNcandScoreZero,stat,a_track);
-      reject = true;
-      DEBUG_CODE(fillBadTrack(a_track,prd_to_track_map) );
-    } else {
-      ATH_MSG_DEBUG ("Track Score is "<< score);
-      // double track rejection
-      if (m_dropDouble) {
-        std::vector<const Trk::PrepRawData*> prds = m_assoTool->getPrdsOnTrack(prd_to_track_map, *a_track);
-        // unfortunately PrepRawDataSet is not a set !
-        PrdSignature prdSig;
-        prdSig.insert( prds.begin(),prds.end() );
-        // we try to insert it into the set, if we fail (pair.second), it then exits already
-        if ( !(prdSigSet.insert(prdSig)).second ) {
-          ATH_MSG_DEBUG ("Double track, reject it !");
-          // statistic
-          increment_by_eta(Counter::kNcandDouble,stat,a_track);
-          reject = true;
-          DEBUG_CODE(fillDuplicateTrack(a_track) );
-        } else {
-          ATH_MSG_DEBUG ("Insert new track in PrdSignatureSet");
-        }
+
+  for(const Track *pTrack : tracks) {
+      ATH_MSG_DEBUG ("Processing track candidate "<<pTrack);
+      // statistics
+      stat.incrementCounterByRegion(ECounter::kNcandidates,pTrack);
+      bool reject = false;
+      // only fitted tracks get hole search, input is not fitted
+      TrackScore score = m_scoringTool->score( *pTrack, true);
+      // veto tracks with score 0
+      if (score==0) { 
+        ATH_MSG_DEBUG ("Candidate score is zero, reject it");
+        // statistic
+        stat.incrementCounterByRegion(ECounter::kNcandScoreZero,pTrack);
+        reject = true;
+      } else {
+
+	ATH_MSG_DEBUG ("Track Score is "<< score);
+	
+	// double track rejection
+	if (m_dropDouble) {
+          std::vector<const Trk::PrepRawData*> prds = m_assoTool->getPrdsOnTrack(prdToTrackMap, *pTrack);
+
+	  // unfortunately PrepRawDataSet is not a set !
+	  PrdSignature prdSig;
+	  prdSig.insert( prds.begin(),prds.end() );
+
+	  // we try to insert it into the set, if we fail (pair.second), it then exits already
+	  if ( !(prdSigSet.insert(prdSig)).second ) {
+	    ATH_MSG_DEBUG ("Double track, reject it !");
+	    // statistic
+	    stat.incrementCounterByRegion(ECounter::kNcandDouble,pTrack);
+	    reject = true;
+	  } else {
+	    ATH_MSG_DEBUG ("Insert new track in PrdSignatureSet");
+	  }
+	}
+      }
+ 
+      if (!reject) {
+        // add track to map, map is sorted small to big ! set if fitted
+        ATH_MSG_VERBOSE ("Track  ("<< pTrack <<") has score "<<score);
+        TrackPtr ptr(pTrack);
+        if (!m_forceRefit) ptr.forceFitted();
+	      trackScoreTrackMap.insert( make_pair(-score,std::move(ptr)) );
       }
     }
-    if (!reject) {
-      // add track to map, map is sorted small to big ! set if fitted
-      ATH_MSG_VERBOSE ("Track  ("<< a_track <<") has score "<<score);
-      TrackPtr ptr(a_track);
-      if (!m_forceRefit) ptr.forceFitted();
-      trackScoreTrackMap.insert( make_pair(-score,std::move(ptr)) );
-    }
-  }
+  
   ATH_MSG_DEBUG ("Number of tracks in map:"<<trackScoreTrackMap.size());
-  DEBUG_CODE( countTrueTracksInMap( trackScoreTrackMap ) );
 }
 
 //==================================================================================================
@@ -345,9 +272,9 @@ void Trk::SimpleAmbiguityProcessorTool::addNewTracks(const std::vector<const Tra
 void Trk::SimpleAmbiguityProcessorTool::addTrack(Trk::Track* in_track,
                                                  const bool fitted,
                                                  TrackScoreMap &trackScoreTrackMap,
-                                                 Trk::PRDtoTrackMap &prd_to_track_map,
-                                                 std::vector<std::unique_ptr<const Trk::Track> >& cleanup_tracks,
-                                                 Trk::SimpleAmbiguityProcessorTool::Counter &stat) const
+                                                 Trk::PRDtoTrackMap &prdToTrackMap,
+                                                 std::vector<std::unique_ptr<const Trk::Track> >& cleanupTracks,
+                                                 Counter &stat) const
 {
   using namespace std;
   std::unique_ptr<Trk::Track> atrack(in_track);
@@ -356,79 +283,96 @@ void Trk::SimpleAmbiguityProcessorTool::addTrack(Trk::Track* in_track,
   bool suppressHoleSearch = fitted ? m_suppressHoleSearch : true;
   if (m_trackSummaryTool.isEnabled()) {
      m_trackSummaryTool->computeAndReplaceTrackSummary(*atrack,
-                                                       &prd_to_track_map,
+                                                       &prdToTrackMap,
                                                        suppressHoleSearch);
   }
 
   score = m_scoringTool->score( *atrack, suppressHoleSearch );
 
   // do we accept the track ?
-  if (score!=0){
-    ATH_MSG_DEBUG ("Track  ("<< atrack.get() <<") has score "<<score);
-    // statistic
-    increment_by_eta(Counter::kNscoreOk,stat,atrack.get());
-    // add track to map, map is sorted small to big !
-    trackScoreTrackMap.insert( make_pair(-score, TrackPtr(atrack.release(), fitted)) );
-    return;
-  }
-  //track score is zero here...
-  // do we try to recover the track ?
-  if (fitted && m_tryBremFit &&
-    !atrack->info().trackProperties(Trk::TrackInfo::BremFit) &&
-    atrack->trackParameters()->front()->pT() > m_pTminBrem &&
-    (!m_caloSeededBrem || atrack->info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI))){
-    ATH_MSG_DEBUG ("Track score is zero, try to recover it via brem fit");
-    // run track fit using electron hypothesis
-    std::unique_ptr<Trk::Track> bremTrack( m_fitterTool->fit(*atrack,true,Trk::electron) );
-    if (!bremTrack){
-      ATH_MSG_DEBUG ("Brem refit failed, drop track");
+  if (score!=0)
+    {
+      ATH_MSG_DEBUG ("Track  ("<< atrack.get() <<") has score "<<score);
       // statistic
-      increment_by_eta(Counter::kNscoreZeroBremRefitFailed,stat,atrack.get());
-      increment_by_eta(Counter::kNfailedFits,stat,atrack.get());
-      // clean up
-      cleanup_tracks.push_back(std::move(atrack));
-	} else {
+      stat.incrementCounterByRegion(ECounter::kNscoreOk,atrack.get());
+
+      // add track to map, map is sorted small to big !
+      trackScoreTrackMap.insert( make_pair(-score, TrackPtr(atrack.release(), fitted)) );
+
+      return;
+    }
+
+  // do we try to recover the track ?
+  if (score==0 && fitted && m_tryBremFit &&
+      !atrack->info().trackProperties(Trk::TrackInfo::BremFit) &&
+      atrack->trackParameters()->front()->pT() > m_pTminBrem &&
+      (!m_caloSeededBrem || atrack->info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI)))
+    {
+
+      ATH_MSG_DEBUG ("Track score is zero, try to recover it via brem fit");
+
+      // run track fit using electron hypothesis
+      std::unique_ptr<Trk::Track> bremTrack( m_fitterTool->fit(*atrack,true,Trk::electron) );
+
+      if (!bremTrack)
+	{
+	  ATH_MSG_DEBUG ("Brem refit failed, drop track");
+	  // statistic
+	  stat.incrementCounterByRegion(ECounter::kNscoreZeroBremRefitFailed,atrack.get());
+	  stat.incrementCounterByRegion(ECounter::kNfailedFits,atrack.get());
+
+	  // clean up
+          cleanupTracks.push_back(std::move(atrack));
+
+	}
+      else
+	{
+
 	  // statistic
-    increment_by_eta(Counter::kNgoodFits,stat,bremTrack.get());
+          stat.incrementCounterByRegion(ECounter::kNgoodFits,bremTrack.get());
+
 	  // rerun score
 	  score = m_scoringTool->score( *bremTrack, suppressHoleSearch );
+
 	  // do we accept the track ?
-	  if (score!=0){
-        ATH_MSG_DEBUG ("Brem refit successful, recovered track  ("<< atrack.get() <<") has score "<<score);
+	  if (score!=0)
+	    {
+              ATH_MSG_DEBUG ("Brem refit successful, recovered track  ("<< atrack.get() <<") has score "<<score);
 	      // statistics
-	      increment_by_eta(Counter::kNscoreZeroBremRefit,stat,bremTrack.get());
+	      stat.incrementCounterByRegion(ECounter::kNscoreZeroBremRefit,bremTrack.get());
+
 	      // add track to map, map is sorted small to big !
 	      trackScoreTrackMap.insert( make_pair(-score, TrackPtr(bremTrack.release(), fitted)) );
 	      return;
-	    } 
+	    }
+	  else
+	    {
 	      ATH_MSG_DEBUG ("Brem refit gave still track score zero, reject it");
 	      // statistic
-	      increment_by_eta(Counter::kNscoreZeroBremRefitScoreZero,stat,bremTrack.get());
-	    
-      cleanup_tracks.push_back(std::move(atrack));
-	  }
-  } else {
-    ATH_MSG_DEBUG ("Track score is zero, reject it");
-    // statistic
-    increment_by_eta(Counter::kNscoreZero,stat,atrack.get());
-    DEBUG_CODE( rejectedTrack(atrack.get(), prd_to_track_map) );
-    cleanup_tracks.push_back(std::move(atrack));
+	      stat.incrementCounterByRegion(ECounter::kNscoreZeroBremRefitScoreZero,bremTrack.get());
+
+	    }
+          cleanupTracks.push_back(std::move(atrack));
+	}
+    }
+  else
+    {
+      ATH_MSG_DEBUG ("Track score is zero, reject it");
+      // statistic
+      stat.incrementCounterByRegion(ECounter::kNscoreZero,atrack.get());
+
+      cleanupTracks.push_back(std::move(atrack));
+    }
   }
-}
 //==================================================================================================
 
 TrackCollection *Trk::SimpleAmbiguityProcessorTool::solveTracks(TrackScoreMap& trackScoreTrackMap,
-                                                                Trk::PRDtoTrackMap &prd_to_track_map,
-                                                                std::vector<std::unique_ptr<const Trk::Track> >& cleanup_tracks,
-                                                                Trk::SimpleAmbiguityProcessorTool::Counter &stat) const
+                                                                Trk::PRDtoTrackMap &prdToTrackMap,
+                                                                std::vector<std::unique_ptr<const Trk::Track> >& cleanupTracks,
+                                                                Counter &stat) const
 {
-  std::unique_ptr<TrackCollection> final_tracks(std::make_unique<TrackCollection>());
-  using namespace std;
- 
-  DEBUG_CODE( fitStatReset() );
-
+  std::unique_ptr<TrackCollection> finalTracks(std::make_unique<TrackCollection>());
   ATH_MSG_DEBUG ("Starting to solve tracks");
-
   // now loop as long as map is not empty
   while ( !trackScoreTrackMap.empty() )
     {
@@ -441,93 +385,75 @@ TrackCollection *Trk::SimpleAmbiguityProcessorTool::solveTracks(TrackScoreMap& t
       // clean it out to make sure not to many shared hits
       ATH_MSG_VERBOSE ("--- Trying next track "<<atrack.track()<<"\t with score "<<-ascore);
       std::unique_ptr<Trk::Track> cleanedTrack;
-      auto [cleanedTrack_tmp,keep_orig] = m_selectionTool->getCleanedOutTrack( atrack.track() , -(ascore), prd_to_track_map);
+      auto [cleanedTrack_tmp,keep_orig] = m_selectionTool->getCleanedOutTrack( atrack.track() , -(ascore), prdToTrackMap);
       cleanedTrack.reset( cleanedTrack_tmp);
 
       // cleaned track is input track and fitted
       if (keep_orig && atrack.fitted() )
 	{
 
-          DEBUG_CODE( keepFittedInputTrack(atrack.track(), ascore) );
 	  // track can be kept as is and is already fitted
 	  ATH_MSG_DEBUG ("Accepted track "<<atrack.track()<<"\t has score "<<-(ascore));
 	  // statistic
-	  increment_by_eta(Counter::kNaccepted,stat,atrack.track());
+	  stat.incrementCounterByRegion(ECounter::kNaccepted,atrack.track());
 	  if (m_tryBremFit && atrack->info().trackProperties(Trk::TrackInfo::BremFit))
-             increment_by_eta(Counter::kNacceptedBrem,stat,atrack.track());
+             stat.incrementCounterByRegion(ECounter::kNacceptedBrem,atrack.track());
 
 	  // add track to PRD_AssociationTool
-          StatusCode sc = m_assoTool->addPRDs(prd_to_track_map, *atrack.track());
+          StatusCode sc = m_assoTool->addPRDs(prdToTrackMap, *atrack.track());
 	  if (sc.isFailure()) msg(MSG::ERROR) << "addPRDs() failed" << endmsg;
 	  // add to output list 
-
-          DEBUG_CODE( acceptedTrack(atrack.track()) );
-
-	  final_tracks->push_back( const_cast<Track*>(atrack.release()) );
-
-	}
-      else if ( keep_orig )
-	{
-
-          DEBUG_CODE( memoriseOutliers(itnext->second.frst) );
-
+	  finalTracks->push_back( const_cast<Track*>(atrack.release()) );
+	} else if ( keep_orig ) {
 	  // don't forget to drop track from map
 	  // track can be kept as is, but is not yet fitted
 	  ATH_MSG_DEBUG ("Good track, but need to fit this track first, score, add it into map again and retry !");
-	  refitTrack(atrack.track(),trackScoreTrackMap, prd_to_track_map, cleanup_tracks, stat);
+	  refitTrack(atrack.track(),trackScoreTrackMap, prdToTrackMap, cleanupTracks, stat);
           if (atrack.newTrack()) {
-             cleanup_tracks.push_back( std::unique_ptr<Trk::Track>(atrack.release()) );
+             cleanupTracks.push_back( std::unique_ptr<Trk::Track>(atrack.release()) );
           }
 	  // delete original copy
 	 }
       else if ( cleanedTrack )
 	{
-
-           DEBUG_CODE(newCleanedTrack(cleanedTrack.get(), atrack.track()) );
-
 	  // now delete original track
           if (atrack.newTrack()) {
-              cleanup_tracks.push_back( std::unique_ptr<Trk::Track>(atrack.release()));
+              cleanupTracks.push_back( std::unique_ptr<Trk::Track>(atrack.release()));
           }
 	  // don't forget to drop track from map
 
 	  // stripped down version should be reconsidered
 	  ATH_MSG_DEBUG ("Candidate excluded, add subtrack to map. Track "<<cleanedTrack.get());
 	  // statistic
-	  increment_by_eta(Counter::kNsubTrack,stat,cleanedTrack.get());
+	  stat.incrementCounterByRegion(ECounter::kNsubTrack,cleanedTrack.get());
 
 	  // track needs fitting !
-	  addTrack( cleanedTrack.release(), false, trackScoreTrackMap, prd_to_track_map, cleanup_tracks, stat);
+	  addTrack( cleanedTrack.release(), false, trackScoreTrackMap, prdToTrackMap, cleanupTracks, stat);
 
-	}
-      else
-	{
-
-          DEBUG_CODE( acceptedTrack(atrack.track()));
+	} else {
 
 	  // track should be discarded
 	  ATH_MSG_DEBUG ("Track "<< atrack.track() << " is excluded, no subtrack, reject");
 	  // statistic
-	  increment_by_eta(Counter::kNnoSubTrack,stat,atrack.track());
-    if (atrack.newTrack()) {
-       cleanup_tracks.push_back(  std::unique_ptr<Trk::Track>(atrack.release()) );
-    }
+	  stat.incrementCounterByRegion(ECounter::kNnoSubTrack,atrack.track());
+
+          if (atrack.newTrack()) {
+             cleanupTracks.push_back(  std::unique_ptr<Trk::Track>(atrack.release()) );
+          }
 	  // don't forget to drop track from map
 	}
     }
-  
-  ATH_MSG_DEBUG ("Finished, number of track on output: "<<final_tracks->size());
-  DEBUG_CODE( eventSummary(final_tracks) );
-  return final_tracks.release();
+  ATH_MSG_DEBUG ("Finished, number of track on output: "<<finalTracks->size());
+  return finalTracks.release();
 }
 
 //==================================================================================================
 
 void Trk::SimpleAmbiguityProcessorTool::refitTrack( const Trk::Track* track,
                                                     TrackScoreMap& trackScoreTrackMap,
-                                                    Trk::PRDtoTrackMap &prd_to_track_map,
-                                                    std::vector<std::unique_ptr<const Trk::Track> >& cleanup_tracks,
-                                                    Trk::SimpleAmbiguityProcessorTool::Counter &stat) const
+                                                    Trk::PRDtoTrackMap &prdToTrackMap,
+                                                    std::vector<std::unique_ptr<const Trk::Track> >& cleanupTracks,
+                                                    Counter &stat) const
 {
   using namespace std;
   std::unique_ptr<Trk::Track> newTrack;
@@ -536,7 +462,7 @@ void Trk::SimpleAmbiguityProcessorTool::refitTrack( const Trk::Track* track,
       {
 	// simple case, fit PRD directly
 	ATH_MSG_VERBOSE ("Refit track "<<track<<" from PRDs");
-	newTrack.reset( refitPrds (track, prd_to_track_map,stat) );
+	newTrack.reset( refitPrds (track, prdToTrackMap,stat) );
       }
     else 
       {
@@ -578,12 +504,9 @@ void Trk::SimpleAmbiguityProcessorTool::refitTrack( const Trk::Track* track,
   if (newTrack)
     {
       ATH_MSG_DEBUG ("New track successfully fitted"<<newTrack.get());
-      DEBUG_CODE( newCleanedTrack( newTrack.get(), atrack.get()) );
-
-      addTrack( newTrack.release(), true, trackScoreTrackMap, prd_to_track_map, cleanup_tracks, stat);
+      addTrack( newTrack.release(), true, trackScoreTrackMap, prdToTrackMap, cleanupTracks, stat);
     }
   else {
-     DEBUG_CODE( fillFailedFit(track, prd_to_track_map) );
      ATH_MSG_DEBUG ("Fit failed !");
   }  
   
@@ -592,12 +515,12 @@ void Trk::SimpleAmbiguityProcessorTool::refitTrack( const Trk::Track* track,
 //==================================================================================================
 
 Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitPrds( const Trk::Track* track,
-                                                          Trk::PRDtoTrackMap &prd_to_track_map,
-                                                          Trk::SimpleAmbiguityProcessorTool::Counter &stat) const
+                                                          Trk::PRDtoTrackMap &prdToTrackMap,
+                                                          Counter &stat) const
 {
 
   // get vector of PRDs
-  std::vector<const Trk::PrepRawData*> prds = m_assoTool->getPrdsOnTrack(prd_to_track_map,*track);
+  std::vector<const Trk::PrepRawData*> prds = m_assoTool->getPrdsOnTrack(prdToTrackMap,*track);
 
   if ( prds.empty() ) {
     msg(MSG::WARNING) << "No PRDs on track"<<endmsg;
@@ -622,7 +545,7 @@ Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitPrds( const Trk::Track* trac
   if (m_tryBremFit && track->info().trackProperties(Trk::TrackInfo::BremFit))
     {
       // statistics
-      increment_by_eta(Counter::kNbremFits,stat,track);
+      stat.incrementCounterByRegion(ECounter::kNbremFits,track);
 
       ATH_MSG_VERBOSE ("Brem track, refit with electron brem fit");
       newTrack = m_fitterTool->fit(prds, *par, true, Trk::electron);
@@ -631,7 +554,7 @@ Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitPrds( const Trk::Track* trac
   else
     {
       // statistics
-      increment_by_eta(Counter::kNfits,stat,track);
+      stat.incrementCounterByRegion(ECounter::kNfits,track);
 
       ATH_MSG_VERBOSE ("Normal track, refit");
       newTrack = m_fitterTool->fit(prds, *par, true, m_particleHypothesis);
@@ -640,7 +563,7 @@ Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitPrds( const Trk::Track* trac
 	  (!m_caloSeededBrem || track->info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI)))
 	{
 	  // statistics
-          increment_by_eta(Counter::kNrecoveryBremFits,stat,track);
+          stat.incrementCounterByRegion(ECounter::kNrecoveryBremFits,track);
 
 	  ATH_MSG_VERBOSE ("Normal fit failed, try brem recovery");
 	  newTrack = m_fitterTool->fit(prds, *par, true, Trk::electron);
@@ -650,7 +573,7 @@ Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitPrds( const Trk::Track* trac
   if(newTrack)
     {
       // statistic
-      increment_by_eta(Counter::kNgoodFits,stat,newTrack);
+      stat.incrementCounterByRegion(ECounter::kNgoodFits,newTrack);
 
       //keeping the track of previously accumulated TrackInfo
       const Trk::TrackInfo& old_info = track->info();
@@ -659,7 +582,7 @@ Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitPrds( const Trk::Track* trac
   else
     {
       // statistic
-      increment_by_eta(Counter::kNfailedFits,stat,track);
+      stat.incrementCounterByRegion(ECounter::kNfailedFits,track);
     }
   return newTrack;
 }
@@ -667,7 +590,7 @@ Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitPrds( const Trk::Track* trac
 //==================================================================================================
 
 Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitRots( const Trk::Track* track,
-                                                          Trk::SimpleAmbiguityProcessorTool::Counter &stat) const
+                                                          Counter &stat) const
 {
 
   ATH_MSG_VERBOSE ("Refit track "<<track);
@@ -679,7 +602,7 @@ Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitRots( const Trk::Track* trac
       track->info().trackProperties(Trk::TrackInfo::BremFit))
     {
       // statistics
-      increment_by_eta(Counter::kNbremFits,stat,track);
+      stat.incrementCounterByRegion(ECounter::kNbremFits,track);
 
       ATH_MSG_VERBOSE ("Brem track, refit with electron brem fit");
       newTrack = m_fitterTool->fit(*track, true, Trk::electron);
@@ -687,7 +610,7 @@ Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitRots( const Trk::Track* trac
   else
     {
       // statistics
-      increment_by_eta(Counter::kNfits,stat,track);
+      stat.incrementCounterByRegion(ECounter::kNfits,track);
 
       ATH_MSG_VERBOSE ("Normal track, refit");
       newTrack = m_fitterTool->fit(*track, true, m_particleHypothesis);
@@ -697,7 +620,7 @@ Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitRots( const Trk::Track* trac
 	  (!m_caloSeededBrem || track->info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI)))
 	{
 	  // statistics
-          increment_by_eta(Counter::kNrecoveryBremFits,stat,track);
+          stat.incrementCounterByRegion(ECounter::kNrecoveryBremFits,track);
 
 	  ATH_MSG_VERBOSE ("Normal fit failed, try brem recovery");
 	  newTrack = m_fitterTool->fit(*track, true, Trk::electron);
@@ -707,7 +630,7 @@ Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitRots( const Trk::Track* trac
   if(newTrack)
     {
       // statistic
-      increment_by_eta(Counter::kNgoodFits,stat,newTrack);
+      stat.incrementCounterByRegion(ECounter::kNgoodFits,newTrack);
 
       //keeping the track of previously accumulated TrackInfo
       const Trk::TrackInfo& old_info = track->info();
@@ -716,7 +639,7 @@ Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitRots( const Trk::Track* trac
   else
     {
       // statistic
-      increment_by_eta(Counter::kNfailedFits,stat,track);
+      stat.incrementCounterByRegion(ECounter::kNfailedFits,track);
     }
   return newTrack;
 }
@@ -731,14 +654,71 @@ void Trk::SimpleAmbiguityProcessorTool::dumpTracks( const TrackCollection& track
   TrackScore totalScore = 0;
   TrackCollection::const_iterator it    = tracks.begin();
   TrackCollection::const_iterator itEnd = tracks.end();
-  for (; it != itEnd ; ++it)
-    {
+  for (; it != itEnd ; ++it){
       // score track:
       const TrackScore score = m_scoringTool->score( **it, m_suppressHoleSearch );
       ATH_MSG_VERBOSE (num++<<"\tTrack :"<<*it<<"\tScore: "<<score);
       totalScore+=score;
     }
   ATH_MSG_DEBUG ("Total event score : "<<totalScore);
+  
+  
+}
+
+void 
+Trk::SimpleAmbiguityProcessorTool::dumpStat(MsgStream &out) const {
+  auto parseFileName=[](const std::string & fullname){
+    auto dotPosition = fullname.rfind(".");
+    auto slashPosition = fullname.rfind("/");
+    auto stringLength = dotPosition - slashPosition;
+    return fullname.substr(slashPosition, stringLength);
+  };
+  // @TODO restore ios
+  std::streamsize ss = std::cout.precision();
+  out << "Output from ";
+  out << parseFileName(__FILE__);
+  out << "::";
+  out << __func__;
+  out << "\n";
+  out <<             "---------------------------------------------------------------------------------" << "\n";
+  out <<             "  Number of events processed      :   "<< m_stat.numberOfEvents() << "\n";
+  out <<             "  statistics by eta range          ------All---Barrel---Trans.--- Endcap---DBM---" << "\n";
+  out <<             "---------------------------------------------------------------------------------" << "\n";
+  out << m_stat.dumpRegions(   "  Number of candidates at input   :", ECounter::kNcandidates);
+  out << m_stat.dumpRegions(   "  - candidates rejected score 0   :", ECounter::kNcandScoreZero);
+  out << m_stat.dumpRegions(   "  - candidates rejected as double :", ECounter::kNcandDouble);
+  out <<             "---------------------------------------------------------------------------------" << "\n";
+  out << m_stat.dumpRegions(   "  candidates with good score      :", ECounter::kNscoreOk);
+  if (m_tryBremFit) {
+     out << m_stat.dumpRegions("  + recovered after brem refit    :", ECounter::kNscoreZeroBremRefit);
+  }
+  out << m_stat.dumpRegions(   "  candidates rejected score 0     :", ECounter::kNscoreZero);
+  if (m_tryBremFit) {
+     out << m_stat.dumpRegions("  + rejected failed brem refit    :", ECounter::kNscoreZeroBremRefitFailed);
+  }
+  out <<             "---------------------------------------------------------------------------------" << "\n";
+  out << m_stat.dumpRegions(   "  number of normal fits           :", ECounter::kNfits);
+  if (m_tryBremFit) {
+     out << m_stat.dumpRegions("  + 2nd brem fit for failed fit   :", ECounter::kNrecoveryBremFits);
+     out << m_stat.dumpRegions("  normal brem fits for electrons  :", ECounter::kNbremFits);
+  }
+  out <<             "---------------------------------------------------------------------------------" << "\n";
+  out << m_stat.dumpRegions(   "  sum of succesful fits           :", ECounter::kNgoodFits);
+  out << m_stat.dumpRegions(   "  sum of failed fits              :", ECounter::kNfailedFits);
+  out <<             "---------------------------------------------------------------------------------" << "\n";
+  out << m_stat.dumpRegions(   "  Number of subtracks created     :", ECounter::kNsubTrack);
+  out << m_stat.dumpRegions(   "  Number of candidates excluded   :", ECounter::kNnoSubTrack);
+  out <<             "---------------------------------------------------------------------------------" << "\n";
+  out << m_stat.dumpRegions(   "  Number of tracks accepted       :", ECounter::kNaccepted);
+  if (m_tryBremFit) {
+     out << m_stat.dumpRegions("  including number of brem fits   :", ECounter::kNacceptedBrem);
+  }
+  out <<             "---------------------------------------------------------------------------------" << "\n";
+  out << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setprecision(2)
+      <<             "    definition: ( 0.0 < Barrel < " << m_etabounds[Counter::iBarrel-1] << " < Transition < " << m_etabounds[Counter::iTransi-1]
+      <<             " < Endcap < " << m_etabounds[Counter::iEndcap-1] << " DBM )" << "\n";
+  out <<             "-------------------------------------------------------------------------------" << "\n";
+  out.precision (ss);
 }
 
 
diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.h b/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.h
index deeaa910ead8a4963c6e2786eeca05777f6c8db8..1f7b0f441b4671abc6b27c376f8f5d80d1bb7960 100644
--- a/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.h
+++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.h
@@ -5,8 +5,6 @@
 #ifndef SIMPLEAMBIGUITYPROCESSORTOOL_H
 #define SIMPLEAMBIGUITYPROCESSORTOOL_H
 
-// turn on debugging ? uncomment this
-//#define SIMPLEAMBIGPROCDEBUGCODE
 
 #include "AthenaBaseComps/AthAlgTool.h"
 #include "TrkToolInterfaces/ITrackAmbiguityProcessorTool.h"
@@ -25,20 +23,11 @@
 
 #include <set>
 #include <vector>
-#include <functional>
-#include <atomic>
 #include <mutex>
-#include <algorithm>
 #include <array>
+#include "AmbiCounter.icc"
 
 #include "TrackPtr.h"
-
-#if defined SIMPLEAMBIGPROCNTUPLECODE || defined SIMPLEAMBIGPROCDEBUGCODE
-#define DEBUG_CODE(a) do { a; } while (false)
-#else
-#define DEBUG_CODE(a) do {  } while (false)
-#endif
-
 class AtlasDetectorID;
 class PixelID;
 
@@ -50,8 +39,12 @@ namespace Trk {
 
   class SimpleAmbiguityProcessorTool : public AthAlgTool, virtual public ITrackAmbiguityProcessorTool 
     {
-      struct Counter;
     public:
+      enum class ECounter {kNcandidates, kNcandScoreZero, kNcandDouble,
+                  kNscoreOk,kNscoreZeroBremRefit,kNscoreZeroBremRefitFailed,kNscoreZeroBremRefitScoreZero,kNscoreZero,
+                  kNaccepted,kNsubTrack,kNnoSubTrack,kNacceptedBrem,
+                  kNbremFits,kNfits,kNrecoveryBremFits,kNgoodFits,kNfailedFits, kNCounter};
+      using Counter = AmbiCounter<ECounter>;
       // public types
       typedef std::multimap< TrackScore, TrackPtr > TrackScoreMap;
     
@@ -68,20 +61,20 @@ namespace Trk {
 	 @param tracks collection of tracks which will have ambiguities resolved. Will not be 
 	 modified.
 	 The tracks will be refitted if no fitQuality is given at input.
-         @param prd_to_track_map on optional prd-to-track map being filled by the processor.
+         @param prdToTrackMap on optional prd-to-track map being filled by the processor.
 	 @return new collections of tracks, with ambiguities resolved. Ownership is passed on 
 	 (i.e. client handles deletion).
 
          If no prd-to-track map is given the processor will create
          one internally (exported to storegate).*/
-      virtual TrackCollection*  process(const TrackCollection*, Trk::PRDtoTrackMap *prd_to_track_map) const override;
+      virtual TrackCollection*  process(const TrackCollection*, Trk::PRDtoTrackMap *prdToTrackMap) const override;
       virtual TrackCollection*  process(const TracksScores* scoredTracks) const override;
 
       /** statistics output to be called by algorithm during finalize. */
       virtual void statistics() override;
     private:
 
-      TrackCollection*  process_vector(std::vector<const Track*> &tracks, Trk::PRDtoTrackMap *prd_to_track_map) const;
+      TrackCollection*  process_vector(std::vector<const Track*> &tracks, Trk::PRDtoTrackMap *prdToTrackMap) const;
 
       /**Add passed TrackCollection, and Trk::PrepRawData from tracks to caches
 	 @param tracks the TrackCollection is looped over, 
@@ -89,19 +82,19 @@ namespace Trk {
 	 The Trk::PrepRawData from each Trk::Track are added to the IPRD_AssociationTool*/
       void addNewTracks(const std::vector<const Track*> &tracks,
                         TrackScoreMap& trackScoreTrackMap,
-                        Trk::PRDtoTrackMap &prd_to_track_map,
-                        Trk::SimpleAmbiguityProcessorTool::Counter &stat) const;
+                        Trk::PRDtoTrackMap &prdToTrackMap,
+                        Counter &stat) const;
 
       void addTrack(Track* track, const bool fitted,
                     TrackScoreMap &trackScoreMap,
-                    Trk::PRDtoTrackMap &prd_to_track_map,
-                    std::vector<std::unique_ptr<const Trk::Track> >& cleanup_tracks,
-                    Trk::SimpleAmbiguityProcessorTool::Counter &stat) const;
+                    Trk::PRDtoTrackMap &prdToTrackMap,
+                    std::vector<std::unique_ptr<const Trk::Track> >& cleanupTracks,
+                    Counter &stat) const;
 
       TrackCollection *solveTracks(TrackScoreMap &trackScoreTrackMap,
-                                   Trk::PRDtoTrackMap &prd_to_track_map,
-                                   std::vector<std::unique_ptr<const Trk::Track> > &cleanup_tracks,
-                                   Trk::SimpleAmbiguityProcessorTool::Counter &stat) const;
+                                   Trk::PRDtoTrackMap &prdToTrackMap,
+                                   std::vector<std::unique_ptr<const Trk::Track> > &cleanupTracks,
+                                   Counter &stat) const;
 
       /** add subtrack to map */
       void addSubTrack( const std::vector<const TrackStateOnSurface*>& tsos) const;
@@ -109,17 +102,17 @@ namespace Trk {
       /** refit track */
       void refitTrack( const Trk::Track* track,
                        TrackScoreMap &trackScoreMap,
-                       Trk::PRDtoTrackMap &prd_to_track_map,
-                       std::vector<std::unique_ptr<const Trk::Track> >& cleanup_tracks,
-                       Trk::SimpleAmbiguityProcessorTool::Counter &stat) const;
+                       Trk::PRDtoTrackMap &prdToTrackMap,
+                       std::vector<std::unique_ptr<const Trk::Track> >& cleanupTracks,
+                       Counter &stat) const;
 
       /** refit PRDs */
-      Track* refitPrds( const Track* track, Trk::PRDtoTrackMap &prd_to_track_map,
-                        Trk::SimpleAmbiguityProcessorTool::Counter &stat) const;
+      Track* refitPrds( const Track* track, Trk::PRDtoTrackMap &prdToTrackMap,
+                        Counter &stat) const;
 
       /** refit ROTs corresponding to PRDs */
       Track* refitRots( const Track* track,
-                        Trk::SimpleAmbiguityProcessorTool::Counter &stat) const;
+                        Counter &stat) const;
 
       /** print out tracks and their scores for debugging*/
       void dumpTracks(const TrackCollection& tracks) const;
@@ -155,13 +148,13 @@ namespace Trk {
       Trk::ParticleHypothesis m_particleHypothesis;
    
       /**Scoring tool
-	 This tool is used to 'score' the tracks, i.e. to quantify what a good track is.
-	 @todo The actual tool that is used should be configured through job options*/
+	    This tool is used to 'score' the tracks, i.e. to quantify what a good track is.
+	    @todo The actual tool that is used should be configured through job options*/
       ToolHandle<ITrackScoringTool> m_scoringTool;
 
 
       /** refitting tool - used to refit tracks once shared hits are removed. 
-	  Refitting tool used is configured via jobOptions.*/
+	    Refitting tool used is configured via jobOptions.*/
       ToolHandle<ITrackFitter> m_fitterTool;
 
       ToolHandle<Trk::IPRDtoTrackMapTool>         m_assoTool
@@ -171,134 +164,17 @@ namespace Trk {
         {this, "TrackSummaryTool", "InDetTrackSummaryToolNoHoleSearch"};
 
       /** selection tool - here the decision which hits remain on a track and
-	  which are removed are made
+	     which are removed are made
       */
       ToolHandle<IAmbiTrackSelectionTool> m_selectionTool;
 
       /** monitoring statistics */
-      enum StatIndex {iAll = 0, iBarrel = 1, iTransi = 2, iEndcap = 3, iDBM = 4, kNRegions=5};
+      //enum RegionIndex {iAll = 0, iBarrel = 1, iTransi = 2, iEndcap = 3, iDBM = 4, nRegions=5};
       std::vector<float> m_etabounds;           //!< eta intervals for internal monitoring
-      struct Counter {
-         enum ECounter {kNcandidates, kNcandScoreZero, kNcandDouble,
-                        kNscoreOk,kNscoreZeroBremRefit,kNscoreZeroBremRefitFailed,kNscoreZeroBremRefitScoreZero,kNscoreZero,
-                        kNaccepted,kNsubTrack,kNnoSubTrack,kNacceptedBrem,
-                        kNbremFits,kNfits,kNrecoveryBremFits,kNgoodFits,kNfailedFits, kNCounter};
-         Counter() {init(); }
-         void init() {
-            for (unsigned int stat_i=0; stat_i < kNCounter; ++stat_i) {
-               std::fill(m_counter[stat_i].begin(),m_counter[stat_i].end(),0);
-            }
-         }
-         void increment(ECounter stat_i, unsigned int eta_bin_i) {
-            if (eta_bin_i>=kNRegions) return;
-            if (stat_i<kNCounter && eta_bin_i < m_counter[stat_i].size()) {} else {  throw std::range_error("out of range"); }
-            ++m_counter[stat_i][eta_bin_i];
-         }
-         void operator +=(const Counter &a) {
-            for (unsigned int stat_i=0; stat_i < kNCounter; ++stat_i) {
-               for (unsigned int eta_bin_i=0; eta_bin_i < a.m_counter[stat_i].size(); ++eta_bin_i) {
-                  m_counter[stat_i][eta_bin_i] += a.m_counter[stat_i][eta_bin_i];
-               }
-            }
-         }
-
-         std::array<int,SimpleAmbiguityProcessorTool::kNRegions> m_counter[kNCounter];
-      };
-      mutable std::atomic<int> m_Nevents;
       mutable std::mutex m_statMutex;
-      mutable Counter m_stat;
-      /** internal monitoring: categories for counting different types of extension results*/
-
-      /** helper for monitoring and validation: does success/failure counting */
-      void increment_by_eta(SimpleAmbiguityProcessorTool::Counter::ECounter counter,
-                            SimpleAmbiguityProcessorTool::Counter &stat,
-                            const Track*,
-                            bool update_all=true) const;
-
-      SimpleAmbiguityProcessorTool::StatIndex etaIndex(double eta) const;
-      void missingTrackOrParameters(const Track* track) const;
-
-      void dumpRegions(MsgStream &out,
-                       const char *head,
-                       SimpleAmbiguityProcessorTool::Counter::ECounter stat_i) const;
-
-//==================================================================================================
-//
-//
-//   FROM HERE EVERYTHING IS DEBUGGING CODE !!!
-//
-//==================================================================================================
-
-#if defined SIMPLEAMBIGPROCNTUPLECODE || defined SIMPLEAMBIGPROCDEBUGCODE
-       virtual void ntupleReset() {}
-       virtual void fillEventData(std::vector<const Track*> &tracks)  { (void) tracks; };
-       virtual void findTrueTracks(std::vector<const Track*> &recTracks)  { (void) recTracks; }; 
-       virtual void fillValidationTree(const Trk::Track* track) const { (void) track; }
-       virtual void resetTrackOutliers() {}
-       virtual void setBarcodeStats(const Trk::Track *a_track, TrackScore score) { (void) a_track; (void) score;}
-       virtual void fillBadTrack(const Trk::Track *a_track, const Trk::PRDtoTrackMap &prd_to_track_map)
-         { (void) a_track; (void) prd_to_track_map; }
-
-       virtual void fillDuplicateTrack(const Trk::Track *a_track) { (void) a_track; }
-       virtual void associateToOrig(const Trk::Track*new_track, const Trk::Track* orig_track) { (void) new_track; (void) orig_track; }
-       virtual void keepTrackOfTracks(const Trk::Track* oldTrack, const Trk::Track* newTrack) { (void) oldTrack; (void) newTrack; }
-       virtual void countTrueTracksInMap(const TrackScoreMap &trackScoreTrackMap) { (void) trackScoreTrackMap; }
-       virtual void rejectedTrack(const Trk::Track*track, const Trk::PRDtoTrackMap &prd_to_track_map)
-         { (void) track; (void) prd_to_track_map; }
-
-       virtual void fitStatReset() {}
-       virtual void keepFittedInputTrack(const Trk::Track *a_track, TrackScore ascore)
-         { (void) a_track; (void) ascore; }
-
-       virtual void acceptedTrack(const Trk::Track*track) { (void) track; }
-       virtual void memoriseOutliers(const Trk::Track*track) { (void) track; }
-       virtual void newCleanedTrack(const Trk::Track*new_track, const Trk::Track* orig_track) { (void) new_track; (void) orig_track; }
-       virtual void eventSummary(const TrackCollection *final_tracks) override {(void) final_tracks; }
-       virtual void fillFailedFit(const Trk::Track *a_track, const Trk::PRDtoTrackMap &prd_to_track_map)
-         { (void) a_track; (void) prd_to_track_map; }
-
-#endif // DebugCode
-    };
-
-    inline
-    SimpleAmbiguityProcessorTool::StatIndex SimpleAmbiguityProcessorTool::etaIndex(double eta) const {
-       eta=std::abs(eta);
-       if (eta < m_etabounds[0]) return Trk::SimpleAmbiguityProcessorTool::iBarrel;
-       else if (eta < m_etabounds[1]) return Trk::SimpleAmbiguityProcessorTool::iTransi;
-       else if (eta < m_etabounds[2]) return Trk::SimpleAmbiguityProcessorTool::iEndcap;
-       else if ((eta > m_etabounds[3]) && (eta < m_etabounds[4])) return Trk::SimpleAmbiguityProcessorTool::iDBM;
-       return Trk::SimpleAmbiguityProcessorTool::kNRegions;
-    }
-
-    inline void SimpleAmbiguityProcessorTool::increment_by_eta(SimpleAmbiguityProcessorTool::Counter::ECounter stat_i,
-                                                               SimpleAmbiguityProcessorTool::Counter &stat,
-                                                               const Track* track,
-                                                               bool updateAll) const
-    {
-       if (updateAll) stat.increment(stat_i,Trk::SimpleAmbiguityProcessorTool::iAll);
-       // test
-       if (track && track->trackParameters() ) {
-          // @TODO make sure that list of track parameters is not empty
-          stat.increment(stat_i, etaIndex(track->trackParameters()->front()->eta()) );
-       }
-       else {
-          missingTrackOrParameters(track);
-       }
-    }
-
-   inline
-   void SimpleAmbiguityProcessorTool::dumpRegions(MsgStream &out,
-                                                  const char *head,
-                                                  SimpleAmbiguityProcessorTool::Counter::ECounter stat_i) const {
-      const int iw=9;
-      out << head;
-      for (unsigned int eta_bin_i=0; eta_bin_i < kNRegions; ++eta_bin_i) {
-         assert( eta_bin_i < m_stat.m_counter[stat_i].size() );
-         out << std::setiosflags(std::ios::dec) << std::setw(iw) << m_stat.m_counter[stat_i][eta_bin_i];
-      }
-      out << "\n";
-   }
+      mutable Counter m_stat ATLAS_THREAD_SAFE;
 
+    };
 } //end ns
 
 #endif // TrackAmbiguityProcessorTool_H
diff --git a/Tracking/TrkTools/TrkParticleCreator/src/TrackParticleCreatorTool.cxx b/Tracking/TrkTools/TrkParticleCreator/src/TrackParticleCreatorTool.cxx
index 4d3f381d258fea0a44a2afd8e5f3bb9b4e07c65d..a928cff654bd9c3d12e781fccdb23b1a374d39d1 100644
--- a/Tracking/TrkTools/TrkParticleCreator/src/TrackParticleCreatorTool.cxx
+++ b/Tracking/TrkTools/TrkParticleCreator/src/TrackParticleCreatorTool.cxx
@@ -363,7 +363,7 @@ TrackParticleCreatorTool::TrackParticleCreatorTool(const std::string& t, const s
 
     std::unique_ptr<const Trk::TrackSummary> summary;
     if (m_trackSummaryTool.get()!=nullptr) {
-      summary.reset(m_trackSummaryTool->createSummary(*track));
+      summary = m_trackSummaryTool->summary(*track, nullptr);
       if (summary == nullptr) {
         ATH_MSG_DEBUG ("No proper TrackSummary was returned. Creating TrackParticle with a dummy TrackSummary");
         summary = std::make_unique<Trk::TrackSummary>();
diff --git a/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackSlimmingTool.h b/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackSlimmingTool.h
index 6a83f57791e3fa45cccb69b486ba4299a978c4b1..e34b42f63e59154ee97fc6739df1de9013b0e5aa 100755
--- a/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackSlimmingTool.h
+++ b/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackSlimmingTool.h
@@ -43,6 +43,12 @@ namespace Trk
           @return A 'slimmed' version of 'track', where exactly what information is copied depends on how the tool is configured
           */
         virtual std::unique_ptr<Trk::Track> slimCopy(const Trk::Track& track) const=0;
+
+       /**
+        * Slim/skim a non const Track. (m_setPersistificationHints is not used)
+        * @param track A reference to the track to be skimmed. It will be modified.
+        */
+        virtual void slimTrack(Trk::Track& track) const = 0;
     };
 
 inline const InterfaceID& Trk::ITrackSlimmingTool::interfaceID()
diff --git a/Tracking/TrkTools/TrkTrackSlimmingTool/TrkTrackSlimmingTool/TrackSlimmingTool.h b/Tracking/TrkTools/TrkTrackSlimmingTool/TrkTrackSlimmingTool/TrackSlimmingTool.h
index 95e0a09900f3a1afb6e3dccb5837944802e699c0..7c2e2b4671e583b0ecc0df9031f3ba20d91f447c 100755
--- a/Tracking/TrkTools/TrkTrackSlimmingTool/TrkTrackSlimmingTool/TrackSlimmingTool.h
+++ b/Tracking/TrkTools/TrkTrackSlimmingTool/TrkTrackSlimmingTool/TrackSlimmingTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -62,6 +62,11 @@ namespace Trk
        */
       std::unique_ptr<Trk::Track> slimCopy(const Trk::Track& track) const override final;
       
+       /**
+        * Slim/skim a non const Track. (m_setPersistificationHints is not used)
+        * @param track A reference to the track to be skimmed. It will be modified.
+        */     
+      void slimTrack(Trk::Track& track) const override final;
     private:
       /** any CaloDeposit with its adjacent MEOT's will be kept on the slimmed track (combined muon property) */
       bool m_keepCaloDeposit;
diff --git a/Tracking/TrkTools/TrkTrackSlimmingTool/src/TrackSlimmingTool.cxx b/Tracking/TrkTools/TrkTrackSlimmingTool/src/TrackSlimmingTool.cxx
index 0275cb2af7c3f2270608e5278d3238ee3dbe5614..72b92612ef661692cafd57e15c1279afff509832 100755
--- a/Tracking/TrkTools/TrkTrackSlimmingTool/src/TrackSlimmingTool.cxx
+++ b/Tracking/TrkTools/TrkTrackSlimmingTool/src/TrackSlimmingTool.cxx
@@ -61,7 +61,6 @@ StatusCode Trk::TrackSlimmingTool::initialize()
   return StatusCode::SUCCESS;
 }
 
-  //================ Finalisation =================================================
 
 StatusCode Trk::TrackSlimmingTool::finalize()
 {
@@ -161,105 +160,135 @@ Trk::Track* Trk::TrackSlimmingTool::slim(const Trk::Track& track) const
   return nullptr;
 }
 
-std::unique_ptr<Trk::Track> Trk::TrackSlimmingTool::slimCopy(const Trk::Track& track) const
+void
+Trk::TrackSlimmingTool::slimTrack(Trk::Track& track) const
 {
-  const DataVector<const TrackStateOnSurface>* oldTrackStates = track.trackStateOnSurfaces();
-  if (oldTrackStates ==nullptr){
+  const DataVector<const TrackStateOnSurface>* oldTrackStates =
+    track.trackStateOnSurfaces();
+  if (oldTrackStates == nullptr) {
     ATH_MSG_WARNING("Track has no TSOS vector! Skipping track, returning 0.");
-    return nullptr;
   }
   // create vector for new TSOS (the ones which are kept)
-  DataVector<const TrackStateOnSurface>* trackStates = new DataVector<const TrackStateOnSurface>; 
-  const TrackStateOnSurface* firstValidIDTSOS(nullptr); 
+  DataVector<const TrackStateOnSurface>* trackStates =
+    new DataVector<const TrackStateOnSurface>;
+  const TrackStateOnSurface* firstValidIDTSOS(nullptr);
   const TrackStateOnSurface* lastValidIDTSOS(nullptr);
   const TrackStateOnSurface* firstValidMSTSOS(nullptr);
   const TrackStateOnSurface* lastValidMSTSOS(nullptr);
-  if (m_keepParameters){
+  if (m_keepParameters) {
     // search last valid TSOS first (as won't be found in later loop)
-    findLastValidTSoS(oldTrackStates, lastValidIDTSOS,lastValidMSTSOS);  
+    findLastValidTSoS(oldTrackStates, lastValidIDTSOS, lastValidMSTSOS);
   }
 
-  // If m_keepParameters is true, then we want to keep the first and last parameters of ID & MS. 
+  // If m_keepParameters is true, then we want to keep the first and last
+  // parameters of ID & MS.
   const Trk::MeasurementBase* rot = nullptr;
   const Trk::TrackParameters* parameters = nullptr;
-  bool keepParameter=false;
-  std::bitset<TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern(0); 
-  
-  DataVector<const TrackStateOnSurface>::const_iterator itTSoS = oldTrackStates->begin();
-  for (; itTSoS!=oldTrackStates->end(); ++itTSoS)
-  {
-    parameters=nullptr; 
-    rot=nullptr;
-    // if requested: keep calorimeter TSOS with adjacent scatterers (on combined muons)
-    if (m_keepCaloDeposit && (**itTSoS).type(TrackStateOnSurface::CaloDeposit)){
+  bool keepParameter = false;
+  std::bitset<TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes>
+    typePattern(0);
+
+  DataVector<const TrackStateOnSurface>::const_iterator itTSoS =
+    oldTrackStates->begin();
+  for (; itTSoS != oldTrackStates->end(); ++itTSoS) {
+    parameters = nullptr;
+    rot = nullptr;
+    // if requested: keep calorimeter TSOS with adjacent scatterers (on combined
+    // muons)
+    if (m_keepCaloDeposit &&
+        (**itTSoS).type(TrackStateOnSurface::CaloDeposit)) {
       // preceding TSOS (if Scatterer)
-      if (itTSoS != oldTrackStates->begin()){
+      if (itTSoS != oldTrackStates->begin()) {
         --itTSoS;
-        if ((**itTSoS).type(TrackStateOnSurface::Scatterer)){
-            trackStates->push_back((**itTSoS).clone());
+        if ((**itTSoS).type(TrackStateOnSurface::Scatterer)) {
+          trackStates->push_back((**itTSoS).clone());
         }
         ++itTSoS;
       }
-      // copy removes CaloEnergy (just keep base EnergyLoss) 
-      const MaterialEffectsOnTrack* meot  =
-        dynamic_cast<const MaterialEffectsOnTrack*>((**itTSoS).materialEffectsOnTrack());
-      if (meot && meot->energyLoss()){
-        trackStates->push_back(new TrackStateOnSurface(nullptr,
-                                                       (**itTSoS).trackParameters()->clone(),
-                                                       nullptr,
-                                                       new MaterialEffectsOnTrack(meot->thicknessInX0(),
-                                                                                  nullptr,
-                                                                                  new EnergyLoss(*meot->energyLoss()),
-                                                                                  meot->associatedSurface()),
-                                                       (**itTSoS).types()));
+      // copy removes CaloEnergy (just keep base EnergyLoss)
+      const MaterialEffectsOnTrack* meot =
+        dynamic_cast<const MaterialEffectsOnTrack*>(
+          (**itTSoS).materialEffectsOnTrack());
+      if (meot && meot->energyLoss()) {
+        trackStates->push_back(new TrackStateOnSurface(
+          nullptr,
+          (**itTSoS).trackParameters()->clone(),
+          nullptr,
+          new MaterialEffectsOnTrack(meot->thicknessInX0(),
+                                     nullptr,
+                                     new EnergyLoss(*meot->energyLoss()),
+                                     meot->associatedSurface()),
+          (**itTSoS).types()));
       }
       // following TSOS (if Scatterer)
       ++itTSoS;
-      if (itTSoS != oldTrackStates->end() && (**itTSoS).type(TrackStateOnSurface::Scatterer))
-      {
-          trackStates->push_back((**itTSoS).clone());
+      if (itTSoS != oldTrackStates->end() &&
+          (**itTSoS).type(TrackStateOnSurface::Scatterer)) {
+        trackStates->push_back((**itTSoS).clone());
       }
       --itTSoS;
     }
     // We only keep TSOS if they either contain a perigee, OR are a measurement
-    if ((*itTSoS)->measurementOnTrack()==nullptr && !(*itTSoS)->type(TrackStateOnSurface::Perigee)){
+    if ((*itTSoS)->measurementOnTrack() == nullptr &&
+        !(*itTSoS)->type(TrackStateOnSurface::Perigee)) {
       continue;
     }
-    typePattern.reset(); 
-    keepParameter=keepParameters((*itTSoS),firstValidIDTSOS, lastValidIDTSOS,firstValidMSTSOS,lastValidMSTSOS);
+    typePattern.reset();
+    keepParameter = keepParameters((*itTSoS),
+                                   firstValidIDTSOS,
+                                   lastValidIDTSOS,
+                                   firstValidMSTSOS,
+                                   lastValidMSTSOS);
 
-   if (keepParameter) {
-      parameters=(*itTSoS)->trackParameters()->clone(); // make sure we add a new parameter by cloning
-      if ((*itTSoS)->type(TrackStateOnSurface::Perigee))  {
+    if (keepParameter) {
+      parameters = (*itTSoS)
+                     ->trackParameters()
+                     ->clone(); // make sure we add a new parameter by cloning
+      if ((*itTSoS)->type(TrackStateOnSurface::Perigee)) {
         typePattern.set(TrackStateOnSurface::Perigee);
       }
     }
-    
-    if ( (*itTSoS)->measurementOnTrack()!=nullptr &&  
-      ( (*itTSoS)->type(TrackStateOnSurface::Measurement) || ( m_keepOutliers && (*itTSoS)->type(TrackStateOnSurface::Outlier) ) ) ) 
-    { 
-      if ((*itTSoS)->type(TrackStateOnSurface::Measurement))  {typePattern.set(TrackStateOnSurface::Measurement);}
-      if ((*itTSoS)->type(TrackStateOnSurface::Outlier))      {typePattern.set(TrackStateOnSurface::Outlier);}
-      rot=(*itTSoS)->measurementOnTrack()->clone();
 
-    } 
+    if ((*itTSoS)->measurementOnTrack() != nullptr &&
+        ((*itTSoS)->type(TrackStateOnSurface::Measurement) ||
+         (m_keepOutliers && (*itTSoS)->type(TrackStateOnSurface::Outlier)))) {
+      if ((*itTSoS)->type(TrackStateOnSurface::Measurement)) {
+        typePattern.set(TrackStateOnSurface::Measurement);
+      }
+      if ((*itTSoS)->type(TrackStateOnSurface::Outlier)) {
+        typePattern.set(TrackStateOnSurface::Outlier);
+      }
+      rot = (*itTSoS)->measurementOnTrack()->clone();
+    }
 
     Trk::TrackStateOnSurface* newTSOS = nullptr;
-    if (rot!=nullptr || parameters!=nullptr) {
-      newTSOS = new Trk::TrackStateOnSurface(rot, parameters, nullptr, nullptr, typePattern);
-      trackStates->push_back( newTSOS );
-    } 
-  }       
+    if (rot != nullptr || parameters != nullptr) {
+      newTSOS = new Trk::TrackStateOnSurface(
+        rot, parameters, nullptr, nullptr, typePattern);
+      trackStates->push_back(newTSOS);
+    }
+  }
+  track.setTrackStateOnSurfaces(trackStates);
+  track.info().setTrackProperties(TrackInfo::SlimmedTrack); 
+  //The above resets also the caches.
+}
 
-  std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(Trk::TrackInfo(track.info()),
-                                                                      trackStates,
-                                                                      track.fitQuality()->clone()
-                                                                     );
-  newTrack->info().setTrackProperties(TrackInfo::SlimmedTrack);
+std::unique_ptr<Trk::Track>
+Trk::TrackSlimmingTool::slimCopy(const Trk::Track& track) const
+{
+  const DataVector<const TrackStateOnSurface>* oldTrackStates =
+    track.trackStateOnSurfaces();
+  if (oldTrackStates == nullptr) {
+    ATH_MSG_WARNING("Track has no TSOS vector! Skipping track, returning 0.");
+    return nullptr;
+  }
+  //Make a copy of the input
+  std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(track);
   // only attempt to copy the summary if the track has it!
   if (track.trackSummary()!=nullptr){
     newTrack->m_trackSummary = new Trk::TrackSummary(*(track.trackSummary()));
   }
+  slimTrack(*newTrack);
   return newTrack;
 }
 
diff --git a/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.cxx b/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.cxx
index 206ec3bd3a03dba04207dfb255be2cb1694f9af4..2491f08ee73933f90093f282127fe4c4f8a024d0 100644
--- a/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.cxx
+++ b/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.cxx
@@ -38,8 +38,6 @@
 #include "TrkTrackSummary/TrackSummary.h"
 #include "TrkToolInterfaces/ITrackSummaryTool.h"
 
-#include "IRegionSelector/IRegSelSvc.h"
-
 #include "TrigInDetEvent/TrigSiSpacePointBase.h"
 
 #include "InDetIdentifier/SCT_ID.h"
diff --git a/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.h b/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.h
index d4f73491854a1413a7739477abdae14482ebad2a..e44ad23760b606c2a32dfb2f2361228622c0da22 100644
--- a/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.h
+++ b/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.h
@@ -39,7 +39,6 @@ class ITrigSpacePointConversionTool;
 class ITrigL2ResidualCalculator;
 class ITrigInDetTrackFitter;
 class ITrigZFinder;
-class IRegSelSvc;
 class TrigRoiDescriptor;
 class TrigSiSpacePointBase;
 class Identifier;
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/AlignmentBarrelLUTSvc.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/AlignmentBarrelLUTSvc.h
index 0922223f7101410fa0864c2fb6f6378532818c2a..e97b9c2aea3b3989a8584ea33605139eb02af249 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/AlignmentBarrelLUTSvc.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/AlignmentBarrelLUTSvc.h
@@ -26,7 +26,7 @@ namespace TrigL2MuonSA {
   public:
     AlignmentBarrelLUTSvc(const std::string& name,ISvcLocator* sl);
 
-    virtual StatusCode queryInterface(const InterfaceID& riid,void** ppvIF);
+    virtual StatusCode queryInterface(const InterfaceID& riid,void** ppvIF) override;
 
     virtual StatusCode initialize() override;
 
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/MuFastDataPreparator.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/MuFastDataPreparator.h
index b79f4232cb3ee156e975d5a60f06f538c8b37db4..40b1865f6aeb12047db5929cd6e1e0b4781064d8 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/MuFastDataPreparator.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/MuFastDataPreparator.h
@@ -32,7 +32,6 @@
 
 #include "TrigMuonBackExtrapolator/ITrigMuonBackExtrapolator.h"
 #include "TrigL2MuonSA/PtEndcapLUTSvc.h"
-#include "RegionSelector/IRegSelSvc.h"
 
 #include "RPC_CondCabling/RpcCablingCondData.h"
 #include "StoreGate/ReadCondHandleKey.h"
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtEndcapLUT.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtEndcapLUT.h
index ea7c83c8b02e854e697c4be3e267ea9a748233f1..3344eb1cc6f62e429be582c9975e9fb9de677a11 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtEndcapLUT.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtEndcapLUT.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGL2MUONSA_PTENDCAPLUT_H
@@ -9,7 +9,6 @@
 
 #include "GaudiKernel/Service.h"
 #include "GaudiKernel/IInterface.h"
-#include "GaudiKernel/StatusCode.h"
 
 #include <map>
 #include <cstring>
@@ -25,16 +24,12 @@ class PtEndcapLUT: public AthAlgTool
   enum DataType { INVALID, ALPHAPOL2, BETAPOL2, TGCALPHAPOL2, INVRADIUSPOL2, CSCPOL2 };
     
   public:
-    static const InterfaceID& interfaceID();
 
     PtEndcapLUT(const std::string& type, 
                 const std::string& name,
                 const IInterface*  parent);
     ~PtEndcapLUT(void);
 
-    virtual StatusCode initialize();
-    virtual StatusCode finalize  ();
-
     StatusCode readLUT(std::string lut_fileName);
     StatusCode readLUTSigmaMean(std::string lut_mean, std::string lut_sigma);
 
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtEndcapLUTSvc.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtEndcapLUTSvc.h
index b87d9d408af486eac3bb5539abbf3bef76bbca95..936393e4d4a1906965ef76d35cf93cf781650f86 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtEndcapLUTSvc.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtEndcapLUTSvc.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGL2MUONSA_PTENDCAPLUTSVC_H
@@ -7,7 +7,6 @@
 
 #include "AthenaBaseComps/AthService.h"
 #include "GaudiKernel/IInterface.h"
-#include "GaudiKernel/StatusCode.h"
 
 #include "GaudiKernel/ServiceHandle.h"
 #include "GaudiKernel/ToolHandle.h"
@@ -34,8 +33,7 @@ class PtEndcapLUTSvc : public AthService, virtual public IInterface
     
     virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvIF);
 
-    virtual StatusCode initialize();
-    virtual StatusCode finalize();
+    virtual StatusCode initialize() override;
 
   private:
     Gaudi::Property< std::string >    m_lut_fileNameRun2 {
@@ -47,7 +45,7 @@ class PtEndcapLUTSvc : public AthService, virtual public IInterface
     Gaudi::Property< std::string >    m_lut_sigma {
 	this, "ESigmaLUT", "pt_comb_sigma.lut", ""};
 
-    ToolHandle<PtEndcapLUT>      m_ptEndcapLUT;
+    ToolHandle<PtEndcapLUT> m_ptEndcapLUT{this, "PtEndcapLUT", "TrigL2MuonSA::PtEndcapLUT"};
 
   public:
     const ToolHandle<PtEndcapLUT>* ptEndcapLUT(void) const
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtFromAlphaBeta.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtFromAlphaBeta.h
index c77cb56ac585f5b9e0e78c48469f86e6566f0a91..cef2d61e21b07ad0239bb104f637a1b291278704 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtFromAlphaBeta.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtFromAlphaBeta.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef  TRIGL2MUONSA_PTFROMALPHABETA_H
@@ -20,16 +20,11 @@ class PtFromAlphaBeta: public AthAlgTool
 {
  public:
     
-  static const InterfaceID& interfaceID();
-
   PtFromAlphaBeta(const std::string& type, 
 		  const std::string& name,
 		  const IInterface*  parent);
     
-  ~PtFromAlphaBeta();
-    
-  virtual StatusCode initialize();
-  virtual StatusCode finalize  ();
+  virtual StatusCode initialize() override;
 
   void setMCFlag(BooleanProperty use_mcLUT,
 		 const TrigL2MuonSA::PtEndcapLUTSvc* ptEndcapLUTSvc);
@@ -54,7 +49,7 @@ class PtFromAlphaBeta: public AthAlgTool
     Gaudi::Property< bool > m_avoid_misaligned_cscs {
 	this, "AvoidMisalignedCSCs", true, "avoid using the 2 new chambers, whose alignment is not completed"};
 
-    const ToolHandle<PtEndcapLUT>*    m_ptEndcapLUT;
+    const ToolHandle<PtEndcapLUT>*    m_ptEndcapLUT{nullptr};
       
 };
 
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtFromRadius.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtFromRadius.h
index cf86ee8db5c7940860a502533def879d24e68847..9e1020c3efe212f8dc5762f0eb00f0aba6afdb3c 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtFromRadius.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/PtFromRadius.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef  TRIGL2MUONSA_PTFROMRADIUS_H
@@ -19,17 +19,10 @@ class PtFromRadius: public AthAlgTool
 {
  public:
   
-  static const InterfaceID& interfaceID();
-
   PtFromRadius(const std::string& type, 
 	       const std::string& name,
 	       const IInterface*  parent);
   
-  ~PtFromRadius();
-  
-  virtual StatusCode initialize();
-  virtual StatusCode finalize  ();
-
   void setMCFlag(BooleanProperty  m_use_mcLUT,
 		 const TrigL2MuonSA::PtBarrelLUTSvc* ptBarrelLUTSvc);
   
@@ -39,9 +32,9 @@ class PtFromRadius: public AthAlgTool
   StatusCode setPt(TrigL2MuonSA::TrackPattern& trackPattern);
   
  private:
-  BooleanProperty  m_use_mcLUT;
+  BooleanProperty  m_use_mcLUT{0};
   
-  const ToolHandle<PtBarrelLUT>*    m_ptBarrelLUT;
+  const ToolHandle<PtBarrelLUT>*   m_ptBarrelLUT{nullptr};
 };
  
 } // namespace PtFromRadius
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/RecMuonRoIUtils.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/RecMuonRoIUtils.h
index d438ea1b66690a63e6ce2928d57ae6810d1c341c..091cedda2bd8c7db61789e79efcc8d88e861dbf0 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/RecMuonRoIUtils.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/RecMuonRoIUtils.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef  TRIGL2MUONSA_RECMUONROIUTILS_H
@@ -16,9 +16,15 @@ class RecMuonRoIUtils
       ~RecMuonRoIUtils() {};
 
    public:
-      bool isBarrel(const LVL1::RecMuonRoI* p_roi);
-      bool isLowPt(const LVL1::RecMuonRoI* p_roi);
-      bool isHighPt(const LVL1::RecMuonRoI* p_roi);
+      bool isBarrel(const LVL1::RecMuonRoI* p_roi){
+        return (p_roi->sysID()==0) ? true : false; 
+      };
+      bool isLowPt(const LVL1::RecMuonRoI* p_roi){
+        return (p_roi->getThresholdNumber() <4) ? true : false;
+      };
+      bool isHighPt(const LVL1::RecMuonRoI* p_roi){
+        return (p_roi->getThresholdNumber()>=4) ? true : false;
+      };
 };
 
 }
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/RpcPatFinder.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/RpcPatFinder.h
index e13832c443619c84d7bc6df0b0b60d29a89389da..68982e7c1cfdc0bd092867d2ddaf731897c85b46 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/RpcPatFinder.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/TrigL2MuonSA/RpcPatFinder.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef  TRIGL2MUONSA_RPAPATFINDER_H
@@ -21,15 +21,10 @@ class RpcPatFinder: public AthAlgTool
 {
 
  public:
-  static const InterfaceID& interfaceID();
 
   RpcPatFinder(const std::string& type, 
 	       const std::string& name,
                  const IInterface*  parent);
-  ~RpcPatFinder(void);
-
-  virtual StatusCode initialize();
-  virtual StatusCode finalize  ();
 
  public:
 
@@ -62,7 +57,7 @@ class RpcPatFinder: public AthAlgTool
 		    double result_dist[]);
 
   bool deltaOK(int l1, int l2, double x1, double x2, int isphi, double &delta);  
-  double calibR(std::string stationName, double R, double Phi);  
+  double calibR(std::string stationName, double R, double Phi) const;  
   void abcal(unsigned int result_pat, size_t index[], double aw[], double bw[]);
 };
 
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MdtDataPreparator.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MdtDataPreparator.cxx
index 1812493f0c191b59287a70a1548a9eeda0c9bc88..b84d02b8537676c3bd381a6bad6fa86f7b89e948 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MdtDataPreparator.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MdtDataPreparator.cxx
@@ -380,9 +380,9 @@ StatusCode TrigL2MuonSA::MdtDataPreparator::getMdtCsm(const MdtCsmContainer* pMd
       ml_id = m_idHelperSvc->mdtIdHelper().multilayerID(tmp_id, processingDetEl);
       m_idHelperSvc->mdtIdHelper().get_detectorElement_hash(ml_id, v_idHash_corr);
     }
-    MdtCsmContainer::const_iterator pCsmIt = pMdtCsmContainer->indexFind(v_idHash_corr);
+    auto pCsmIt = pMdtCsmContainer->indexFindPtr(v_idHash_corr);
     
-    if( pCsmIt==pMdtCsmContainer->end() ) {
+    if( pCsmIt==nullptr ) {
       if(processingDetEl == 1){
 	if ( m_idHelperSvc->mdtIdHelper().stationName(ml_id) == 53 ) processingDetEl = 2;   //if this is BME, the 2nd layer should be checked next
 	else ++i;
@@ -393,7 +393,7 @@ StatusCode TrigL2MuonSA::MdtDataPreparator::getMdtCsm(const MdtCsmContainer* pMd
       continue;
     }
     if( BMEpresent ){
-      Identifier elementId = ((*pCsmIt)->identify());
+      Identifier elementId = (pCsmIt->identify());
       // if there are BMEs it's also required to process there 2nd CSM
       if( m_idHelperSvc->mdtIdHelper().stationName(elementId) == 53 ) { // is BME chamber
         // do the loop once again with the SAME iterator, but for the 2nd multilayer
@@ -407,14 +407,14 @@ StatusCode TrigL2MuonSA::MdtDataPreparator::getMdtCsm(const MdtCsmContainer* pMd
       }
     }
 
-    v_mdtCsms.push_back(*pCsmIt);
+    v_mdtCsms.push_back(pCsmIt);
     ATH_MSG_DEBUG("MDT Collection hash " << v_idHash_corr
 		  << " associated to:  SubDet 0x" << MSG::hex
-		  << (*pCsmIt)->SubDetId() << " MRod 0x"
-		  << (*pCsmIt)->MrodId() << " Link 0x"
-		  << (*pCsmIt)->CsmId() << MSG::dec);
+		  << pCsmIt->SubDetId() << " MRod 0x"
+		  << pCsmIt->MrodId() << " Link 0x"
+		  << pCsmIt->CsmId() << MSG::dec);
     ATH_MSG_DEBUG("Number of digit in  MDT Collection "
-		  << v_idHash_corr << ": " << (*pCsmIt)->size());
+		  << v_idHash_corr << ": " << pCsmIt->size());
     
     if(processingDetEl == 1) ++i;
   }
@@ -847,23 +847,23 @@ StatusCode TrigL2MuonSA::MdtDataPreparator::collectMdtHitsFromPrepData(const std
 
   for(const IdentifierHash& id : v_idHash) {
 
-    Muon::MdtPrepDataContainer::const_iterator MDTcoll = mdtPrds->indexFind(id);
+    auto MDTcoll = mdtPrds->indexFindPtr(id);
 
-    if( MDTcoll == mdtPrds->end() ) {
+    if( MDTcoll == nullptr ) {
       ATH_MSG_DEBUG("MDT prep data collection not found in Hash ID" << (int)id);
       continue;
     }
 
-    if( (*MDTcoll)->size() == 0 ) {
+    if( MDTcoll->size() == 0 ) {
       ATH_MSG_DEBUG("MDT prep data collection is empty in Hash ID" << (int)id);
       continue;
     }
 
-    mdtCols.push_back(*MDTcoll);
+    mdtCols.push_back(MDTcoll);
 
     ATH_MSG_DEBUG("Selected Mdt Collection: "
-		  << m_idHelperSvc->mdtIdHelper().show_to_string((*MDTcoll)->identify())
-		  << " with size " << (*MDTcoll)->size()
+		  << m_idHelperSvc->mdtIdHelper().show_to_string(MDTcoll->identify())
+		  << " with size " << MDTcoll->size()
 		  << "in Hash ID" << (int)id);
   }
 
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuCalStreamerTool.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuCalStreamerTool.cxx
index eacc301989c2215a6d6276e7e8df9f06abf8ecf9..970113025cdf3d3c9455d61a1bdb7a639670307d 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuCalStreamerTool.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuCalStreamerTool.cxx
@@ -491,14 +491,13 @@ StatusCode TrigL2MuonSA::MuCalStreamerTool::createRpcFragment(const LVL1::RecMuo
   unsigned int padIdHash;
   if (readCdo->give_PAD_address( side, sector, roiNumber, padIdHash)) {
 
-    RpcPadContainer::const_iterator itPad = rpcPadContainer->indexFind(padIdHash);  
-    if( itPad==rpcPadContainer->end() ) {        
+    auto itPad = rpcPadContainer->indexFindPtr(padIdHash);  
+    if( itPad==nullptr ) {        
       ATH_MSG_WARNING("Failed to retrieve PAD hash Id " << padIdHash);  
       return StatusCode::FAILURE;                         
     }
-    const RpcPad* rpcPad = *itPad;
+    const RpcPad* rpcPad = itPad;
 
-    if(rpcPad) {
       uint16_t sector = rpcPad->sector();
       uint16_t sysId  = (sector<32)? 0x66 : 0x65;
       uint16_t secId  = sector%32;
@@ -540,11 +539,6 @@ StatusCode TrigL2MuonSA::MuCalStreamerTool::createRpcFragment(const LVL1::RecMuo
 	rpcFragment << matrix;
       } // loop on the pad matrices
     
-    }
-    else {
-      ATH_MSG_WARNING("Can't initialize the RpcPad");
-      return StatusCode::FAILURE;
-    }
   }
   else {
     ATH_MSG_WARNING("Can't get the pad address from the RpcCablingCondData");
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtEndcapLUT.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtEndcapLUT.cxx
index c7c95442f850ba601c368f051d2c6d02c2142dec..06ad499b6a58c11d38e5814eaddc12246a03c3c2 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtEndcapLUT.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtEndcapLUT.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TrigL2MuonSA/PtEndcapLUT.h"
@@ -12,19 +12,11 @@
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
-static const InterfaceID IID_PtEndcapLUT("IID_PtEndcapLUT", 1, 0);
-
-const InterfaceID& TrigL2MuonSA::PtEndcapLUT::interfaceID() { return IID_PtEndcapLUT; }
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
-
 TrigL2MuonSA::PtEndcapLUT::PtEndcapLUT(const std::string& type,
                                        const std::string& name,
                                        const IInterface*  parent):
   AthAlgTool(type, name, parent)
 {
-  declareInterface<TrigL2MuonSA::PtEndcapLUT>(this);
 }
 
 // --------------------------------------------------------------------------------
@@ -40,24 +32,6 @@ TrigL2MuonSA::PtEndcapLUT::~PtEndcapLUT()
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
-StatusCode TrigL2MuonSA::PtEndcapLUT::initialize()
-{
-  ATH_MSG_DEBUG("Initializing PtEndcapLUT - package version " << PACKAGE_VERSION) ;
-   
-  StatusCode sc;
-  sc = AthAlgTool::initialize();
-  if (!sc.isSuccess()) {
-    ATH_MSG_ERROR("Could not initialize the AthAlgTool base class.");
-    return sc;
-  }
-
-  // 
-  return StatusCode::SUCCESS; 
-}
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
-
 bool TrigL2MuonSA::PtEndcapLUT::KeyType::operator<(const KeyType& other) const
 {
   if (m_side   < other.m_side)   return (true);
@@ -330,31 +304,21 @@ const char* TrigL2MuonSA::PtEndcapLUT::dt2s(TrigL2MuonSA::PtEndcapLUT::DataType
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
-StatusCode TrigL2MuonSA::PtEndcapLUT::finalize()
-{
-  ATH_MSG_DEBUG("Finalizing TgcRoadDefiner - package version " << PACKAGE_VERSION);
-   
-  StatusCode sc = AthAlgTool::finalize(); 
-  return sc;
-}
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
 double TrigL2MuonSA::PtEndcapLUT::ptcombined(int iEta, int iPhi, double ApT, double BpT, double &CApT, \
 					     double &CBpT) const
 {
-  msg() << MSG::DEBUG << "pTcombined("
+  ATH_MSG_DEBUG("pTcombined("
 	<< "iEta="      << iEta
 	<< "iPhi="      << iPhi
 	<< "Alpha pT="  << ApT
 	<< "Beta pT="   << BpT
-	<< ")" << endmsg;
+	<< ")" );
 
   if (iEta == -1) iEta =  0;
   if (iEta == 30) iEta = 29;
 
   if (iEta < 0 || iEta >= ETAS || iPhi < 0 || iPhi >= PHIS) {
-    msg() << MSG::WARNING << "pTcombined("<< iEta << ", " << iPhi << ") Invalid indices" << endmsg;
+    ATH_MSG_WARNING("pTcombined("<< iEta << ", " << iPhi << ") Invalid indices");
     return 0.0;
   }
 
@@ -420,11 +384,11 @@ StatusCode TrigL2MuonSA::PtEndcapLUT::readLUTSigmaMean(std::string lut_mean, std
   std::ifstream ifsmean(lut_mean.c_str());
   std::ifstream ifssigma(lut_sigma.c_str());
   if (!ifsmean.is_open()) {
-    msg() << MSG::ERROR << "Cannot open EndcapLUT Mean file " << lut_mean << endmsg;
+    ATH_MSG_ERROR("Cannot open EndcapLUT Mean file " << lut_mean);
     return StatusCode::FAILURE;
   }
   if (!ifssigma.is_open()) {
-    msg() << MSG::ERROR << "Cannot open EndcapLUT Sigma file " << lut_sigma << endmsg;
+    ATH_MSG_ERROR("Cannot open EndcapLUT Sigma file " << lut_sigma);
     return StatusCode::FAILURE;
   }
 
@@ -450,7 +414,7 @@ StatusCode TrigL2MuonSA::PtEndcapLUT::readLUTSigmaMean(std::string lut_mean, std
     int iEta, iPhi, iNP;
     double tmp_par1, tmp_par2, tmp_par3;
     if (sscanf(line.c_str(), "%d %d %d %lf %lf %lf", &iEta, &iPhi, &iNP, &tmp_par1, &tmp_par2, &tmp_par3) != 6) {
-      msg() << MSG::ERROR << " Invalid data in mean EndcapLUT file " << lut_mean << endmsg;
+      ATH_MSG_ERROR(" Invalid data in mean EndcapLUT file " << lut_mean);
       return StatusCode::FAILURE;
     }
 
@@ -467,7 +431,7 @@ StatusCode TrigL2MuonSA::PtEndcapLUT::readLUTSigmaMean(std::string lut_mean, std
     int iEta, iPhi, iNP;
     double tmp_par1, tmp_par2, tmp_par3;
     if (sscanf(line2.c_str(), "%d %d %d %lf %lf %lf", &iEta, &iPhi, &iNP, &tmp_par1, &tmp_par2, &tmp_par3) != 6) {
-      msg() << MSG::ERROR << " Invalid data in mean EndcapLUT file " << lut_mean << endmsg;
+      ATH_MSG_ERROR(" Invalid data in mean EndcapLUT file " << lut_mean);
       return StatusCode::FAILURE;
     }
 
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtEndcapLUTSvc.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtEndcapLUTSvc.cxx
index 96cac233b8f865572bd6824bf683e381dd600342..85633851c2e4c0a0e0f3e837d5d6b9f6af9f1efd 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtEndcapLUTSvc.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtEndcapLUTSvc.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "GaudiKernel/ISvcLocator.h"
@@ -13,8 +13,7 @@
 // --------------------------------------------------------------------------------
 
 TrigL2MuonSA::PtEndcapLUTSvc::PtEndcapLUTSvc(const std::string& name, ISvcLocator* sl) :
-  AthService(name,sl),
-  m_ptEndcapLUT("TrigL2MuonSA::PtEndcapLUT")
+  AthService(name,sl)
 {
 }
 
@@ -37,11 +36,6 @@ StatusCode TrigL2MuonSA::PtEndcapLUTSvc::queryInterface(const InterfaceID& riid,
 
 StatusCode TrigL2MuonSA::PtEndcapLUTSvc::initialize()
 {   
-  StatusCode sc;
-  
-  sc = AthService::initialize();
-  if ( sc.isFailure() ) return sc;
- 
   // implement the search of LUT trought the pathresolver Tool.
   std::string lut_fileName = PathResolver::find_file(m_lut_fileNameRun2, "DATAPATH");
   ATH_MSG_INFO(lut_fileName);
@@ -55,11 +49,8 @@ StatusCode TrigL2MuonSA::PtEndcapLUTSvc::initialize()
   ATH_MSG_DEBUG("Retrieved service " << m_ptEndcapLUT);
 
   // read LUT
-  sc = m_ptEndcapLUT->readLUT(lut_fileName);
-  if ( sc.isFailure() ) {
-    ATH_MSG_ERROR("Failed to read endcap LUT" << m_lut_fileNameRun2);
-    return sc;
-  }
+  ATH_CHECK( m_ptEndcapLUT->readLUT(lut_fileName) );
+  ATH_MSG_DEBUG("Read endcap LUT" << m_lut_fileNameRun2);
 
   return StatusCode::SUCCESS;
 }
@@ -67,10 +58,3 @@ StatusCode TrigL2MuonSA::PtEndcapLUTSvc::initialize()
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
-StatusCode TrigL2MuonSA::PtEndcapLUTSvc::finalize()
-{
-  return StatusCode::SUCCESS;
-}
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtFromAlphaBeta.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtFromAlphaBeta.cxx
index 19f747512c9e0e6ea1f39af4a4c06a94e58f7f97..eaafa5c07189a2c4576b37970b85ea5ebf6e5d25 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtFromAlphaBeta.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtFromAlphaBeta.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TrigL2MuonSA/PtFromAlphaBeta.h"
@@ -12,26 +12,10 @@
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
-static const InterfaceID IID_PtFromAlphaBeta("IID_PtFromAlphaBeta", 1, 0);
-
-const InterfaceID& TrigL2MuonSA::PtFromAlphaBeta::interfaceID() { return IID_PtFromAlphaBeta; }
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
-
 TrigL2MuonSA::PtFromAlphaBeta::PtFromAlphaBeta(const std::string& type,
 					       const std::string& name,
 					       const IInterface*  parent):
-  AthAlgTool(type, name, parent), 
-  m_ptEndcapLUT(0)
-{
-  declareInterface<TrigL2MuonSA::PtFromAlphaBeta>(this);
-}
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
-
-TrigL2MuonSA::PtFromAlphaBeta::~PtFromAlphaBeta() 
+  AthAlgTool(type, name, parent) 
 {
 }
 
@@ -40,15 +24,6 @@ TrigL2MuonSA::PtFromAlphaBeta::~PtFromAlphaBeta()
 
 StatusCode TrigL2MuonSA::PtFromAlphaBeta::initialize()
 {
-  ATH_MSG_DEBUG("Initializing PtFromAlphaBeta - package version " << PACKAGE_VERSION) ;
-   
-  StatusCode sc;
-  sc = AthAlgTool::initialize();
-  if (!sc.isSuccess()) {
-    ATH_MSG_ERROR("Could not initialize the AthAlgTool base class.");
-    return sc;
-  }
-
   ATH_MSG_DEBUG(m_use_cscpt);
   // 
   return StatusCode::SUCCESS; 
@@ -62,8 +37,6 @@ void TrigL2MuonSA::PtFromAlphaBeta::setMCFlag(BooleanProperty use_mcLUT,
 {
   m_use_mcLUT = use_mcLUT;
   m_ptEndcapLUT = ptEndcapLUTSvc->ptEndcapLUT();
-
-  return;
 }
 
 // --------------------------------------------------------------------------------
@@ -82,11 +55,11 @@ StatusCode TrigL2MuonSA::PtFromAlphaBeta::setPt(TrigL2MuonSA::TrackPattern& trac
   if ( fabs(trackPattern.slope)<ZERO_LIMIT && fabs(trackPattern.intercept)<ZERO_LIMIT )
     return StatusCode::SUCCESS;
   
-  float tgcPt = tgcFitResult.tgcPT ;
+  const float tgcPt = tgcFitResult.tgcPT ;
   
   // MDT pT by alpha
-  int  side   = (trackPattern.etaMap <= 0.0) ? 0 : 1;
-  int  charge = (trackPattern.intercept * trackPattern.etaMap) < 0.0 ? 0 : 1;
+  const int  side   = (trackPattern.etaMap <= 0.0) ? 0 : 1;
+  const int  charge = (trackPattern.intercept * trackPattern.etaMap) < 0.0 ? 0 : 1;
 
   float mdtPt = (*m_ptEndcapLUT)->lookup(side, charge, PtEndcapLUT::ALPHAPOL2, trackPattern.etaBin,
 				      trackPattern.phiBin, trackPattern.endcapAlpha) / 1000;
@@ -107,7 +80,7 @@ StatusCode TrigL2MuonSA::PtFromAlphaBeta::setPt(TrigL2MuonSA::TrackPattern& trac
     if (charge == 0)  betaPt = -betaPt;
     trackPattern.ptEndcapBeta = betaPt;//pt calculated by beta
 
-    int outer = xAOD::L2MuonParameters::Chamber::EndcapOuter;
+    const int outer = xAOD::L2MuonParameters::Chamber::EndcapOuter;
     if ( fabs((betaPt - mdtPt) / mdtPt) < ALPHA_TO_BETA_RATIO ) {
       mdtPt = betaPt;
     } else if ( fabs(trackPattern.superPoints[outer].Z) < ZERO_LIMIT) {
@@ -116,7 +89,7 @@ StatusCode TrigL2MuonSA::PtFromAlphaBeta::setPt(TrigL2MuonSA::TrackPattern& trac
   }
   if (trackPattern.endcapRadius3P>0) {//calculate pt from radius
     ATH_MSG_DEBUG("calculate pt from Radius");
-    float invR = 1. / trackPattern.endcapRadius3P;
+    const float invR = 1. / trackPattern.endcapRadius3P;
 
     if (trackPattern.etaBin<8){
       trackPattern.ptEndcapRadius =  (*m_ptEndcapLUT)->lookup(side, charge, PtEndcapLUT::INVRADIUSPOL2, 
@@ -141,8 +114,8 @@ StatusCode TrigL2MuonSA::PtFromAlphaBeta::setPt(TrigL2MuonSA::TrackPattern& trac
   if(m_use_cscpt){
     const float &cscPt = trackPattern.ptCSC;
     const int &etabin = trackPattern.etaBin;
-    bool validrange = (20<=etabin && etabin<=27) || (etabin==20 && abs(side-charge)!=1);//side-charge==0 <=> Qeta==1
-    bool validchamber = !m_avoid_misaligned_cscs || (16!=trackPattern.hashID_CSC && 17!=trackPattern.hashID_CSC);
+    const bool validrange = (20<=etabin && etabin<=27) || (etabin==20 && abs(side-charge)!=1);//side-charge==0 <=> Qeta==1
+    const bool validchamber = !m_avoid_misaligned_cscs || (16!=trackPattern.hashID_CSC && 17!=trackPattern.hashID_CSC);
     if( etabin !=23 && etabin!=24 &&  validrange && validchamber){
       if(fabs(trackPattern.ptEndcapBeta)<ZERO_LIMIT && fabs(cscPt)>ZERO_LIMIT 
 	 &&  fabs((cscPt - mdtPt) / mdtPt)<ALPHA_TO_CSC_RATIO && fabs(1./cscPt-1./mdtPt)<ALPHA_TO_CSC_RATIO_PT ){
@@ -190,13 +163,3 @@ StatusCode TrigL2MuonSA::PtFromAlphaBeta::setPt(TrigL2MuonSA::TrackPattern& trac
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
-StatusCode TrigL2MuonSA::PtFromAlphaBeta::finalize()
-{
-  ATH_MSG_DEBUG("Finalizing PtFromAlphaBeta - package version " << PACKAGE_VERSION);
-   
-  StatusCode sc = AthAlgTool::finalize(); 
-  return sc;
-}
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtFromRadius.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtFromRadius.cxx
index 2436a85aab7e61d7079d7fda8844ee2bc7fa9f65..267c73445a9d4727a1878af8ab2da0d10a8c4750 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtFromRadius.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/PtFromRadius.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TrigL2MuonSA/PtFromRadius.h"
@@ -12,51 +12,16 @@
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
-static const InterfaceID IID_PtFromRadius("IID_PtFromRadius", 1, 0);
-
-const InterfaceID& TrigL2MuonSA::PtFromRadius::interfaceID() { return IID_PtFromRadius; }
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
-
 TrigL2MuonSA::PtFromRadius::PtFromRadius(const std::string& type,
 					 const std::string& name,
 					 const IInterface*  parent):
-  AthAlgTool(type, name, parent), 
-  m_use_mcLUT(0),
-  m_ptBarrelLUT(0)
-{
-  declareInterface<TrigL2MuonSA::PtFromRadius>(this);
-}
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
-
-TrigL2MuonSA::PtFromRadius::~PtFromRadius() 
+  AthAlgTool(type, name, parent) 
 {
 }
 
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
-StatusCode TrigL2MuonSA::PtFromRadius::initialize()
-{
-  ATH_MSG_DEBUG("Initializing PtFromRadius - package version " << PACKAGE_VERSION) ;
-   
-  StatusCode sc;
-  sc = AthAlgTool::initialize();
-  if (!sc.isSuccess()) {
-    ATH_MSG_ERROR("Could not initialize the AthAlgTool base class.");
-    return sc;
-  }
-
-  // 
-  return StatusCode::SUCCESS; 
-}
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
-
 void TrigL2MuonSA::PtFromRadius::setMCFlag(BooleanProperty use_mcLUT,
                                            const TrigL2MuonSA::PtBarrelLUTSvc* ptBarrelLUTSvc)
 {
@@ -69,6 +34,8 @@ void TrigL2MuonSA::PtFromRadius::setMCFlag(BooleanProperty use_mcLUT,
 
 StatusCode TrigL2MuonSA::PtFromRadius::setPt(TrigL2MuonSA::TrackPattern& trackPattern)
 {
+  const double ZERO_LIMIT = 1e-5;
+
   const PtBarrelLUT::LUT&   lut   = (*m_ptBarrelLUT)->lut();
   const PtBarrelLUT::LUTsp& lutSP = (*m_ptBarrelLUT)->lutSP();
 
@@ -81,94 +48,91 @@ StatusCode TrigL2MuonSA::PtFromRadius::setPt(TrigL2MuonSA::TrackPattern& trackPa
   float phistep,etastep,pstep,dist,distp,disteta,distphi;
   float A0[6]={0.,0.,0.,0.,0.,0.},A1[6]={0.,0.,0.,0.,0.,0.};
 
-  float scale = 0.1;
-  
-  if(trackPattern.barrelRadius > 0.) {
+  const float scale = 0.1;
+
+  if(trackPattern.barrelRadius > ZERO_LIMIT) {
     add = trackPattern.s_address;
     etabin = (int)((trackPattern.etaMap - lut.EtaMin[add])/lut.EtaStep[add]);
     phibin = (int)((trackPattern.phiMap - lut.PhiMin[add])/lut.PhiStep[add]);
-    
+
     if(etabin<=-1) etabin = 0;
     if(etabin>=lut.NbinEta[add]) etabin = lut.NbinEta[add]-1;
     if(phibin<=-1) phibin = 0;
     if(phibin>=lut.NbinPhi[add]) phibin = lut.NbinPhi[add]-1;
-        
+
     disteta = trackPattern.etaMap - (etabin*lut.EtaStep[add] +
-				  lut.EtaStep[add]/2. + lut.EtaMin[add]);
+        lut.EtaStep[add]/2. + lut.EtaMin[add]);
     distphi = trackPattern.phiMap - (phibin*lut.PhiStep[add] + 
-				  lut.PhiStep[add]/2. + lut.PhiMin[add]);
+        lut.PhiStep[add]/2. + lut.PhiMin[add]);
     neweta  = (disteta >= 0.) ? etabin+1 : etabin-1;
     newphi  = (distphi >= 0.) ? phibin+1 : phibin-1;
     etastep = (disteta >= 0.) ? lut.EtaStep[add] : -lut.EtaStep[add];
     phistep = (distphi >= 0.) ? lut.PhiStep[add] : -lut.PhiStep[add];
 
-    if(trackPattern.barrelRadius!=0.) {
-
-      ch = (trackPattern.charge>=0.)? 1 : 0;
-
-      if( add==1 ) {
-	// Use special table for Large-SP data
-
-	int iR = ( superPoints[0]->R > 6000 )? 1: 0;
-        int qeta = ( trackPattern.charge*trackPattern.etaMap >= 0.)? 1 : 0;
-
-	A0[0] = lutSP.table_LargeSP[qeta][iR][etabin][phibin][0];
-	A1[0] = lutSP.table_LargeSP[qeta][iR][etabin][phibin][1];
-
-	trackPattern.pt = trackPattern.barrelRadius*A0[0] + A1[0];
-
+    ch = (trackPattern.charge>=0.)? 1 : 0;
+
+    if( add==1 ) {
+      // Use special table for Large-SP data
+
+      int iR = ( superPoints[0]->R > 6000 )? 1: 0;
+      int qeta = ( trackPattern.charge*trackPattern.etaMap >= 0.)? 1 : 0;
+
+      A0[0] = lutSP.table_LargeSP[qeta][iR][etabin][phibin][0];
+      A1[0] = lutSP.table_LargeSP[qeta][iR][etabin][phibin][1];
+
+      trackPattern.pt = trackPattern.barrelRadius*A0[0] + A1[0];
+
+    } else {
+
+      A0[0] = lut.table[add][ch][etabin][phibin][0];
+      A1[0] = lut.table[add][ch][etabin][phibin][1];
+      if((neweta<0||neweta>=lut.NbinEta[add])&&
+          (newphi<0||newphi>=lut.NbinPhi[add])) {
+        trackPattern.pt = trackPattern.barrelRadius*scale*A0[0] + A1[0];
+      } else if (neweta<0||neweta>=lut.NbinEta[add]) {
+        A0[1] = lut.table[add][ch][etabin][newphi][0];
+        A1[1] = lut.table[add][ch][etabin][newphi][1];
+        A0[2] = A0[0] + ((A0[1] - A0[0])/phistep)*distphi;
+        A1[2] = A1[0] + ((A1[1] - A1[0])/phistep)*distphi;
+        trackPattern.pt = trackPattern.barrelRadius*scale*A0[2] + A1[2];
+      } else if (newphi<0||newphi>=lut.NbinPhi[add]) {
+        A0[1] = lut.table[add][ch][neweta][phibin][0];
+        A1[1] = lut.table[add][ch][neweta][phibin][1];
+        A0[2] = A0[0] + ((A0[1] - A0[0])/etastep)*disteta;
+        A1[2] = A1[0] + ((A1[1] - A1[0])/etastep)*disteta;
+        trackPattern.pt = trackPattern.barrelRadius*scale*A0[2] + A1[2];
       } else {
-
-	A0[0] = lut.table[add][ch][etabin][phibin][0];
-	A1[0] = lut.table[add][ch][etabin][phibin][1];
-	if((neweta<0||neweta>=lut.NbinEta[add])&&
-	   (newphi<0||newphi>=lut.NbinPhi[add])) {
-	  trackPattern.pt = trackPattern.barrelRadius*scale*A0[0] + A1[0];
-	} else if (neweta<0||neweta>=lut.NbinEta[add]) {
-	  A0[1] = lut.table[add][ch][etabin][newphi][0];
-	  A1[1] = lut.table[add][ch][etabin][newphi][1];
-	  A0[2] = A0[0] + ((A0[1] - A0[0])/phistep)*distphi;
-	  A1[2] = A1[0] + ((A1[1] - A1[0])/phistep)*distphi;
-	  trackPattern.pt = trackPattern.barrelRadius*scale*A0[2] + A1[2];
-	} else if (newphi<0||newphi>=lut.NbinPhi[add]) {
-	  A0[1] = lut.table[add][ch][neweta][phibin][0];
-	  A1[1] = lut.table[add][ch][neweta][phibin][1];
-	  A0[2] = A0[0] + ((A0[1] - A0[0])/etastep)*disteta;
-	  A1[2] = A1[0] + ((A1[1] - A1[0])/etastep)*disteta;
-	  trackPattern.pt = trackPattern.barrelRadius*scale*A0[2] + A1[2];
-	} else {
-	  if(disteta >= distphi*lut.EtaStep[add]/lut.PhiStep[add]) {
-	    A0[1] = lut.table[add][ch][neweta][phibin][0];
-	    A1[1] = lut.table[add][ch][neweta][phibin][1];
-	    A0[2] = lut.table[add][ch][neweta][newphi][0];
-	    A1[2] = lut.table[add][ch][neweta][newphi][1];
-	    A0[3] = A0[0] + ((A0[1] - A0[0])/etastep)*disteta;
-	    A1[3] = A1[0] + ((A1[1] - A1[0])/etastep)*disteta;
-	    dist  = sqrt(phistep*phistep + etastep*etastep);
-	    distp = sqrt(disteta*disteta + distphi*distphi);
-	    A0[4] = A0[0] + ((A0[2] - A0[0])/dist)*distp;
-	    A1[4] = A1[0] + ((A1[2] - A1[0])/dist)*distp;
-	    pstep = (phistep/dist)*distp;
-	    A0[5] = A0[3] + ((A0[4] - A0[3])/pstep)*distphi;
-	    A1[5] = A1[3] + ((A1[4] - A1[3])/pstep)*distphi;
-	    trackPattern.pt = trackPattern.barrelRadius*scale*A0[5] + A1[5];
-	  } else {
-	    A0[1] = lut.table[add][ch][etabin][newphi][0];
-	    A1[1] = lut.table[add][ch][etabin][newphi][1];
-	    A0[2] = lut.table[add][ch][neweta][newphi][0];
-	    A1[2] = lut.table[add][ch][neweta][newphi][1];
-	    A0[3] = A0[0] + ((A0[1] - A0[0])/phistep)*distphi;
-	    A1[3] = A1[0] + ((A1[1] - A1[0])/phistep)*distphi;
-	    dist  = sqrt(phistep*phistep + etastep*etastep);
-	    distp = sqrt(disteta*disteta + distphi*distphi);
-	    A0[4] = A0[0] + ((A0[2] - A0[0])/dist)*distp;
-	    A1[4] = A1[0] + ((A1[2] - A1[0])/dist)*distp;
-	    pstep = (etastep/dist)*distp;
-	    A0[5] = A0[3] + ((A0[4] - A0[3])/pstep)*disteta;
-	    A1[5] = A1[3] + ((A1[4] - A1[3])/pstep)*disteta;
-	    trackPattern.pt = trackPattern.barrelRadius*scale*A0[5] + A1[5];
-	  }
-	}
+        if(disteta >= distphi*lut.EtaStep[add]/lut.PhiStep[add]) {
+          A0[1] = lut.table[add][ch][neweta][phibin][0];
+          A1[1] = lut.table[add][ch][neweta][phibin][1];
+          A0[2] = lut.table[add][ch][neweta][newphi][0];
+          A1[2] = lut.table[add][ch][neweta][newphi][1];
+          A0[3] = A0[0] + ((A0[1] - A0[0])/etastep)*disteta;
+          A1[3] = A1[0] + ((A1[1] - A1[0])/etastep)*disteta;
+          dist  = sqrt(phistep*phistep + etastep*etastep);
+          distp = sqrt(disteta*disteta + distphi*distphi);
+          A0[4] = A0[0] + ((A0[2] - A0[0])/dist)*distp;
+          A1[4] = A1[0] + ((A1[2] - A1[0])/dist)*distp;
+          pstep = (phistep/dist)*distp;
+          A0[5] = A0[3] + ((A0[4] - A0[3])/pstep)*distphi;
+          A1[5] = A1[3] + ((A1[4] - A1[3])/pstep)*distphi;
+          trackPattern.pt = trackPattern.barrelRadius*scale*A0[5] + A1[5];
+        } else {
+          A0[1] = lut.table[add][ch][etabin][newphi][0];
+          A1[1] = lut.table[add][ch][etabin][newphi][1];
+          A0[2] = lut.table[add][ch][neweta][newphi][0];
+          A1[2] = lut.table[add][ch][neweta][newphi][1];
+          A0[3] = A0[0] + ((A0[1] - A0[0])/phistep)*distphi;
+          A1[3] = A1[0] + ((A1[1] - A1[0])/phistep)*distphi;
+          dist  = sqrt(phistep*phistep + etastep*etastep);
+          distp = sqrt(disteta*disteta + distphi*distphi);
+          A0[4] = A0[0] + ((A0[2] - A0[0])/dist)*distp;
+          A1[4] = A1[0] + ((A1[2] - A1[0])/dist)*distp;
+          pstep = (etastep/dist)*distp;
+          A0[5] = A0[3] + ((A0[4] - A0[3])/pstep)*disteta;
+          A1[5] = A1[3] + ((A1[4] - A1[3])/pstep)*disteta;
+          trackPattern.pt = trackPattern.barrelRadius*scale*A0[5] + A1[5];
+        }
       }
     }
   }
@@ -184,13 +148,3 @@ StatusCode TrigL2MuonSA::PtFromRadius::setPt(TrigL2MuonSA::TrackPattern& trackPa
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
-StatusCode TrigL2MuonSA::PtFromRadius::finalize()
-{
-  ATH_MSG_DEBUG("Finalizing PtFromRadius - package version " << PACKAGE_VERSION);
-   
-  StatusCode sc = AthAlgTool::finalize(); 
-  return sc;
-}
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RecMuonRoIUtils.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RecMuonRoIUtils.cxx
deleted file mode 100644
index ea259af42189c1cc36e010cc1186b722e82c7abb..0000000000000000000000000000000000000000
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RecMuonRoIUtils.cxx
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
-*/
-
-#include "TrigL2MuonSA/RecMuonRoIUtils.h"
-
-bool TrigL2MuonSA::RecMuonRoIUtils::isBarrel(const LVL1::RecMuonRoI* p_roi) {
-   return (p_roi->sysID()==0) ? true : false; 
-}
-bool TrigL2MuonSA::RecMuonRoIUtils::isLowPt(const LVL1::RecMuonRoI* p_roi)  { 
-   return (p_roi->getThresholdNumber() <4) ? true : false;
-}
-bool TrigL2MuonSA::RecMuonRoIUtils::isHighPt(const LVL1::RecMuonRoI* p_roi) {
-   return (p_roi->getThresholdNumber()>=4) ? true : false;
-}
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcDataPreparator.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcDataPreparator.cxx
index 4e4d4efa032056599e50e4d2d888e130ca103316..e13a314a9d9a79061015b4c8d3113e490396685a 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcDataPreparator.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcDataPreparator.cxx
@@ -182,19 +182,19 @@ StatusCode TrigL2MuonSA::RpcDataPreparator::prepareData(const TrigRoiDescriptor*
      // Get RPC collections
      for(const IdentifierHash& id : rpcHashList) {
 
-       Muon::RpcPrepDataContainer::const_iterator RPCcoll = rpcPrds->indexFind(id);
+       auto RPCcoll = rpcPrds->indexFindPtr(id);
 
-       if( RPCcoll == rpcPrds->end() ) {
+       if( RPCcoll == nullptr ) {
          continue;
        }
 
-       if( (*RPCcoll)->size() == 0) {
+       if( RPCcoll->size() == 0) {
          ATH_MSG_DEBUG("Empty RPC list");
          continue;
        }
 
        rpcHashList_cache.push_back(id);
-       rpcCols.push_back(*RPCcoll);
+       rpcCols.push_back(RPCcoll);
      }
    }
 
@@ -256,9 +256,7 @@ StatusCode TrigL2MuonSA::RpcDataPreparator::prepareData(const TrigRoiDescriptor*
        lutDigit.layer       = layer;
        
        const float r2 = hitx*hitx+hity*hity;
-       float phi = atan(hity/hitx);
-       if (hitx<0 && hity>0) phi += M_PI;
-       if (hitx<0 && hity<0) phi -= M_PI;
+       float phi = atan2(hity,hitx);
        const float l = sqrt(hitz*hitz+r2);
        const float tan = sqrt( (l-hitz)/(l+hitz) );
        const float eta = -log(tan);
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcPatFinder.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcPatFinder.cxx
index 0277aeb3dbf28a5533b227336b9b947c0c57b7b1..1c432aad75f2ac9ec15d4bcad8289b1cd50bed7e 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcPatFinder.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcPatFinder.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TrigL2MuonSA/RpcPatFinder.h"
@@ -15,44 +15,11 @@
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
-static const InterfaceID IID_RpcPatFinder("IID_RpcPatFinder", 1, 0);
-
-const InterfaceID& TrigL2MuonSA::RpcPatFinder::interfaceID() { return IID_RpcPatFinder; }
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
-
 TrigL2MuonSA::RpcPatFinder::RpcPatFinder(const std::string& type,
 					 const std::string& name,
 					 const IInterface*  parent):
   AthAlgTool(type, name, parent)  
 {  
-  declareInterface<TrigL2MuonSA::RpcPatFinder>(this);
-}
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
-
-TrigL2MuonSA::RpcPatFinder::~RpcPatFinder()
-{
-}
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
-
-StatusCode TrigL2MuonSA::RpcPatFinder::initialize()
-{
-  ATH_MSG_DEBUG("Initializing RpcPatFinder - package version " << PACKAGE_VERSION) ;
-   
-  StatusCode sc;
-  sc = AthAlgTool::initialize();
-  if (!sc.isSuccess()) {
-    ATH_MSG_ERROR("Could not initialize the AthAlgTool base class.");
-    return sc;
-  }
-
-  // 
-  return StatusCode::SUCCESS; 
 }
 
 // --------------------------------------------------------------------------------
@@ -92,7 +59,7 @@ void TrigL2MuonSA::RpcPatFinder::addHit(std::string stationName,
   ilay+=gasGap-1;
 
   double R=sqrt(gPosX*gPosX+gPosY*gPosY);
-  double Phi=atan2(gPosY,gPosX);
+  const double Phi=atan2(gPosY,gPosX);
 
   if (!measuresPhi){
     // if eta measurement then save Z/R
@@ -417,7 +384,7 @@ bool  TrigL2MuonSA::RpcPatFinder::deltaOK(int l1, int l2, double x1, double x2,
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
-double TrigL2MuonSA::RpcPatFinder::calibR(std::string stationName, double R, double Phi){
+double TrigL2MuonSA::RpcPatFinder::calibR(std::string stationName, double R, double Phi) const{
   double DeltaPhi, temp_phi;
   double calibPhi = acos(cos(Phi)); // 0 < Phi < 2PI
   
@@ -584,13 +551,3 @@ void TrigL2MuonSA::RpcPatFinder::abcal(unsigned int result_pat, size_t index[],
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
-StatusCode TrigL2MuonSA::RpcPatFinder::finalize()
-{
-  ATH_MSG_DEBUG("Finalizing RpcPatFinder - package version " << PACKAGE_VERSION);
-   
-  StatusCode sc = AthAlgTool::finalize(); 
-  return sc;
-}
-
-// --------------------------------------------------------------------------------
-// --------------------------------------------------------------------------------
diff --git a/Trigger/TrigAlgorithms/TrigMuonEF/src/TrigMuonEFStandaloneTrackTool.cxx b/Trigger/TrigAlgorithms/TrigMuonEF/src/TrigMuonEFStandaloneTrackTool.cxx
index d775ea4ceed194bd6b3c9d68ac4eb1488bcba738..82f62109e232a55bf6b264dece63183efec95f94 100644
--- a/Trigger/TrigAlgorithms/TrigMuonEF/src/TrigMuonEFStandaloneTrackTool.cxx
+++ b/Trigger/TrigAlgorithms/TrigMuonEF/src/TrigMuonEFStandaloneTrackTool.cxx
@@ -1107,10 +1107,10 @@ if (m_useMdtData>0) {
       msg()<< MSG::DEBUG << " RPC PRD Container retrieved" << endmsg;
     }
     // Get RPC collections
-    RpcPrepDataContainer::const_iterator RPCcoll;
+    const Muon::RpcPrepDataCollection* RPCcoll = nullptr;
     for(std::vector<IdentifierHash>::const_iterator idit = rpc_hash_ids.begin(); idit != rpc_hash_ids.end(); ++idit) {
-      RPCcoll = rpcPrds->indexFind(*idit);
-      if( RPCcoll == rpcPrds->end() ) {
+      RPCcoll = rpcPrds->indexFindPtr(*idit);
+      if( RPCcoll == nullptr ) {
         if (msgLvl(MSG::VERBOSE)) {
 	       Identifier idColl;
           IdContext rpcContext = m_idHelperSvc->rpcIdHelper().module_context();
@@ -1121,7 +1121,7 @@ if (m_useMdtData>0) {
         }
         continue;
       }
-      if( (*RPCcoll)->size() == 0)    {
+      if( RPCcoll->size() == 0)    {
         if (msgLvl(MSG::VERBOSE)) {
           Identifier idColl;
           IdContext rpcContext = m_idHelperSvc->rpcIdHelper().module_context();
@@ -1135,18 +1135,18 @@ if (m_useMdtData>0) {
       
       rpc_hash_ids_cache.push_back(*idit);
       
-      nRpcHits+=(*RPCcoll)->size(); // count hits for TrigMuonEFInfo
-      rpcCols.push_back(*RPCcoll);
+      nRpcHits+=RPCcoll->size(); // count hits for TrigMuonEFInfo
+      rpcCols.push_back(RPCcoll);
       if (msgLvl(MSG::DEBUG)) 
         ATH_MSG_DEBUG("Selected Rpc Collection: "
-              << m_idHelperSvc->rpcIdHelper().show_to_string((*RPCcoll)->identify())
+              << m_idHelperSvc->rpcIdHelper().show_to_string(RPCcoll->identify())
               << " (hash = " << (int)*idit
-              << ") with size " << (*RPCcoll)->size());
+              << ") with size " << RPCcoll->size());
       else if (testRoiDrivenMode) 
         ATH_MSG_INFO("Selected Rpc Collection: "
-				  << m_idHelperSvc->rpcIdHelper().show_to_string((*RPCcoll)->identify())
+				  << m_idHelperSvc->rpcIdHelper().show_to_string(RPCcoll->identify())
               << " (hash = " << (int)*idit
-				  << "), with size " << (*RPCcoll)->size());
+				  << "), with size " << RPCcoll->size());
 
     }
     if (rpcCols.empty()) {
@@ -1169,11 +1169,11 @@ if (m_useMdtData>0) {
     }
     
     // Get MDT collections
-    MdtPrepDataContainer::const_iterator MDTcoll;
+    const Muon::MdtPrepDataCollection* MDTcoll = nullptr;
     for(std::vector<IdentifierHash>::const_iterator idit = mdt_hash_ids.begin();
 	idit != mdt_hash_ids.end(); ++idit) {
-      MDTcoll = mdtPrds->indexFind(*idit);
-      if( MDTcoll == mdtPrds->end() ) {
+      MDTcoll = mdtPrds->indexFindPtr(*idit);
+      if( MDTcoll == nullptr ) {
 	if (msgLvl(MSG::VERBOSE)) {
 	  Identifier idColl;
 	  IdContext mdtContext = m_idHelperSvc->mdtIdHelper().module_context();
@@ -1184,7 +1184,7 @@ if (m_useMdtData>0) {
 	}
 	continue;
       }
-      if( (*MDTcoll)->size() == 0)    {
+      if( MDTcoll->size() == 0)    {
 	if (msgLvl(MSG::VERBOSE)) {
 	  Identifier idColl;
 	  IdContext mdtContext = m_idHelperSvc->mdtIdHelper().module_context();
@@ -1200,8 +1200,8 @@ if (m_useMdtData>0) {
 	Muon::MdtPrepDataCollection *mdtcollection=new Muon::MdtPrepDataCollection();
 	addElement( m_mdtcollCache, mdtcollection );
 
-      	Muon::MdtPrepDataCollection::const_iterator cit_begin = (*MDTcoll)->begin();
-      	Muon::MdtPrepDataCollection::const_iterator cit_end = (*MDTcoll)->end();
+      	Muon::MdtPrepDataCollection::const_iterator cit_begin = MDTcoll->begin();
+      	Muon::MdtPrepDataCollection::const_iterator cit_end   = MDTcoll->end();
       	Muon::MdtPrepDataCollection::const_iterator cit = cit_begin;   
       	for( ; cit!=cit_end;++cit ) // first
       	  {
@@ -1229,24 +1229,24 @@ if (m_useMdtData>0) {
       	    }
       	  }
 
-      	mdtcollection->setIdentifier((*MDTcoll)->identify());
+      	mdtcollection->setIdentifier(MDTcoll->identify());
       	nMdtHits+=mdtcollection->size(); // count hits for TrigMuonEFInfo
       	mdtCols2.push_back(mdtcollection);      
       }
       else{
-	nMdtHits+=(*MDTcoll)->size(); 
+	nMdtHits+=MDTcoll->size(); 
       }
 
       
       mdt_hash_ids_cache.push_back(*idit);
-      mdtCols.push_back(*MDTcoll);
+      mdtCols.push_back(MDTcoll);
       if (msgLvl(MSG::DEBUG)) ATH_MSG_DEBUG("Selected Mdt Collection: "
-			 << m_idHelperSvc->mdtIdHelper().show_to_string((*MDTcoll)->identify())
-			 << " with size " << (*MDTcoll)->size());
+			 << m_idHelperSvc->mdtIdHelper().show_to_string(MDTcoll->identify())
+			 << " with size " << MDTcoll->size());
       else
 	if (testRoiDrivenMode) ATH_MSG_INFO("Selected Mdt Collection: "
-				     << m_idHelperSvc->mdtIdHelper().show_to_string((*MDTcoll)->identify())
-				     << " with size " << (*MDTcoll)->size());
+				     << m_idHelperSvc->mdtIdHelper().show_to_string(MDTcoll->identify())
+				     << " with size " << MDTcoll->size());
     }
     if (mdtCols.empty()) {
       ATH_MSG_DEBUG("No Mdt data collections selected");
@@ -1269,11 +1269,11 @@ if (m_useMdtData>0) {
     }
 
     // Get TGC collections
-    TgcPrepDataContainer::const_iterator TGCcoll;
+    const Muon::TgcPrepDataCollection* TGCcoll;
     for(std::vector<IdentifierHash>::const_iterator idit = tgc_hash_ids.begin();
 	idit != tgc_hash_ids.end(); ++idit) {
-      TGCcoll = tgcPrds->indexFind(*idit);
-      if( TGCcoll == tgcPrds->end() ) {
+      TGCcoll = tgcPrds->indexFindPtr(*idit);
+      if( TGCcoll == nullptr ) {
 	if (msgLvl(MSG::VERBOSE)) {
 	  Identifier idColl;
 	  IdContext tgcContext = m_idHelperSvc->tgcIdHelper().module_context();
@@ -1284,7 +1284,7 @@ if (m_useMdtData>0) {
 	}
 	continue;
       }
-      if( (*TGCcoll)->size() == 0)    {
+      if( TGCcoll->size() == 0)    {
 	if (msgLvl(MSG::VERBOSE)) {
 	  Identifier idColl;
 	  IdContext tgcContext = m_idHelperSvc->tgcIdHelper().module_context();
@@ -1297,15 +1297,15 @@ if (m_useMdtData>0) {
       }
       
       tgc_hash_ids_cache.push_back(*idit);
-      nTgcHits+=(*TGCcoll)->size(); // count hits for TrigMuonEFInfo
-      tgcCols.push_back(*TGCcoll);
+      nTgcHits+=TGCcoll->size(); // count hits for TrigMuonEFInfo
+      tgcCols.push_back(TGCcoll);
       if (msgLvl(MSG::DEBUG)) ATH_MSG_DEBUG("Selected Tgc Collection: "
-			 << m_idHelperSvc->tgcIdHelper().show_to_string((*TGCcoll)->identify())
-			 << " with size " << (*TGCcoll)->size());
+			 << m_idHelperSvc->tgcIdHelper().show_to_string(TGCcoll->identify())
+			 << " with size " << TGCcoll->size());
       else
 	if (testRoiDrivenMode) ATH_MSG_INFO("Selected Tgc Collection: "
-				     << m_idHelperSvc->tgcIdHelper().show_to_string((*TGCcoll)->identify())
-				     << " with size " << (*TGCcoll)->size());
+				     << m_idHelperSvc->tgcIdHelper().show_to_string(TGCcoll->identify())
+				     << " with size " << TGCcoll->size());
     }
     
     if(m_useTGCInPriorNextBC){
@@ -1313,8 +1313,8 @@ if (m_useMdtData>0) {
       
       for(std::vector<IdentifierHash>::const_iterator idit = tgc_hash_ids.begin();
 	  idit != tgc_hash_ids.end(); ++idit) {
-	TGCcoll = tgcPrdsPriorBC->indexFind(*idit);
-	if( TGCcoll == tgcPrdsPriorBC->end() ) {
+	TGCcoll = tgcPrdsPriorBC->indexFindPtr(*idit);
+	if( TGCcoll == nullptr ) {
 	  if (msgLvl(MSG::VERBOSE)) {
 	    Identifier idColl;
 	    IdContext tgcContext = m_idHelperSvc->tgcIdHelper().module_context();
@@ -1325,7 +1325,7 @@ if (m_useMdtData>0) {
 	  }
 	  continue;
 	}
-	if( (*TGCcoll)->size() == 0)    {
+	if( TGCcoll->size() == 0)    {
 	  if (msgLvl(MSG::VERBOSE)) {
 	    Identifier idColl;
 	    IdContext tgcContext = m_idHelperSvc->tgcIdHelper().module_context();
@@ -1336,11 +1336,11 @@ if (m_useMdtData>0) {
 	  }
 	  continue;
 	}
-	nTgcHits+=(*TGCcoll)->size(); // count hits for TrigMuonEFInfo
-	tgcCols.push_back(*TGCcoll);
+	nTgcHits+=TGCcoll->size(); // count hits for TrigMuonEFInfo
+	tgcCols.push_back(TGCcoll);
 	if (msgLvl(MSG::DEBUG)) ATH_MSG_DEBUG("Selected Tgc Collection: "
-			   << m_idHelperSvc->tgcIdHelper().show_to_string((*TGCcoll)->identify())
-			   << " with size " << (*TGCcoll)->size());
+			   << m_idHelperSvc->tgcIdHelper().show_to_string(TGCcoll->identify())
+			   << " with size " << TGCcoll->size());
       }
       const TgcPrepDataContainer* tgcPrdsNextBC = 0;
       SG::ReadHandle<Muon::TgcPrepDataContainer> TgcCont(m_tgcKeyNextBC);
@@ -1355,8 +1355,8 @@ if (m_useMdtData>0) {
 
       for(std::vector<IdentifierHash>::const_iterator idit = tgc_hash_ids.begin();
 	  idit != tgc_hash_ids.end(); ++idit) {
-	TGCcoll = tgcPrdsNextBC->indexFind(*idit);
-	if( TGCcoll == tgcPrdsNextBC->end() ) {
+	TGCcoll = tgcPrdsNextBC->indexFindPtr(*idit);
+	if( TGCcoll == nullptr ) {
 	  if (msgLvl(MSG::VERBOSE)) {
 	    Identifier idColl;
 	    IdContext tgcContext = m_idHelperSvc->tgcIdHelper().module_context();
@@ -1367,7 +1367,7 @@ if (m_useMdtData>0) {
 	  }
 	  continue;
 				}
-	if( (*TGCcoll)->size() == 0)    {
+	if( TGCcoll->size() == 0)    {
 	  if (msgLvl(MSG::VERBOSE)) {
 	    Identifier idColl;
 	    IdContext tgcContext = m_idHelperSvc->tgcIdHelper().module_context();
@@ -1378,11 +1378,11 @@ if (m_useMdtData>0) {
 	  }
 	  continue;
 	}
-	nTgcHits+=(*TGCcoll)->size(); // count hits for TrigMuonEFInfo
-	tgcCols.push_back(*TGCcoll);
+	nTgcHits+=TGCcoll->size(); // count hits for TrigMuonEFInfo
+	tgcCols.push_back(TGCcoll);
 	ATH_MSG_DEBUG("Selected Tgc Collection: "
-			   << m_idHelperSvc->tgcIdHelper().show_to_string((*TGCcoll)->identify())
-			   << " with size " << (*TGCcoll)->size());
+			   << m_idHelperSvc->tgcIdHelper().show_to_string(TGCcoll->identify())
+			   << " with size " << TGCcoll->size());
       }
     }
     
@@ -1407,27 +1407,27 @@ if (m_useMdtData>0) {
     }
 
     // Get CSC collections
-    CscPrepDataContainer::const_iterator CSCcoll;
+    const Muon::CscPrepDataCollection* CSCcoll = nullptr;
     for(std::vector<IdentifierHash>::const_iterator idit = csc_hash_ids.begin();
 	idit != csc_hash_ids.end(); ++idit) {
       if(m_ignoreCSC && (*idit==16 || *idit==17)){
 	ATH_MSG_DEBUG("Skipping misaligned chamber with hashid "<<*idit);
 	continue;
       }
-      CSCcoll = cscPrds->indexFind(*idit);
-      if( CSCcoll == cscPrds->end() ) continue;
-      if( (*CSCcoll)->size() == 0)    continue;
+      CSCcoll = cscPrds->indexFindPtr(*idit);
+      if( CSCcoll == nullptr ) continue;
+      if( CSCcoll->size() == 0)    continue;
       
       csc_hash_ids_cache.push_back(*idit);
-      nCscHits+=(*CSCcoll)->size(); // count hits for TrigMuonEFInfo
-      cscCols.push_back(*CSCcoll);
+      nCscHits+=CSCcoll->size(); // count hits for TrigMuonEFInfo
+      cscCols.push_back(CSCcoll);
       if (msgLvl(MSG::DEBUG)) ATH_MSG_DEBUG("Selected Csc Collection: "
-			 << m_idHelperSvc->cscIdHelper().show_to_string((*CSCcoll)->identify())
-			 << " with size " << (*CSCcoll)->size());
+			 << m_idHelperSvc->cscIdHelper().show_to_string(CSCcoll->identify())
+			 << " with size " << CSCcoll->size());
       else
 	if (testRoiDrivenMode) ATH_MSG_INFO("Selected Csc Collection: "
-				     << m_idHelperSvc->cscIdHelper().show_to_string((*CSCcoll)->identify())
-				     << " with size " << (*CSCcoll)->size());
+				     << m_idHelperSvc->cscIdHelper().show_to_string(CSCcoll->identify())
+				     << " with size " << CSCcoll->size());
     }
     if (cscCols.empty()) {
       ATH_MSG_DEBUG("No Csc data collections selected");
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloCommon/TrigT2CaloCommon/ITrigDataAccess.h b/Trigger/TrigAlgorithms/TrigT2CaloCommon/TrigT2CaloCommon/ITrigDataAccess.h
index 7a6fd0057a29e8bc742f343bc530f637d819b8e0..945d829fa8db9a4c7f89f95cca1a07bc66bf01c8 100644
--- a/Trigger/TrigAlgorithms/TrigT2CaloCommon/TrigT2CaloCommon/ITrigDataAccess.h
+++ b/Trigger/TrigAlgorithms/TrigT2CaloCommon/TrigT2CaloCommon/ITrigDataAccess.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 /********************************************************************
@@ -25,7 +25,8 @@
 #include "LArRecEvent/LArFebEnergyCollection.h"
 #include "TileEvent/TileCellCollection.h"
 #include "TileEvent/TileL2Container.h"
-#include "IRegionSelector/IRegSelSvc.h"
+#include "IRegionSelector/IRoiDescriptor.h"
+#include "IRegionSelector/RegSelEnums.h"
 #include "CaloEvent/CaloCellContainer.h"
 #include "ZdcEvent/ZdcRawChannelCollection.h"
 
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloCommon/python/TrigCaloDataAccessConfig.py b/Trigger/TrigAlgorithms/TrigT2CaloCommon/python/TrigCaloDataAccessConfig.py
index 89b0204f7c36eadb2f13431f90298bddefd51b11..814312213c790cae9fa4b85d3f79a81da9f979e7 100644
--- a/Trigger/TrigAlgorithms/TrigT2CaloCommon/python/TrigCaloDataAccessConfig.py
+++ b/Trigger/TrigAlgorithms/TrigT2CaloCommon/python/TrigCaloDataAccessConfig.py
@@ -94,8 +94,8 @@ if __name__ == "__main__":
     ConfigFlags.lock()
     acc = ComponentAccumulator()
     
-    from ByteStreamCnvSvc.ByteStreamConfig import TrigBSReadCfg
-    acc.merge( TrigBSReadCfg( ConfigFlags ) )
+    from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
+    acc.merge( ByteStreamReadCfg( ConfigFlags ) )
 
     acc.merge( trigCaloDataAccessSvcCfg( ConfigFlags ) )
     
diff --git a/Trigger/TrigAlgorithms/TrigT2MinBias/src/TrigCountSpacePoints.cxx b/Trigger/TrigAlgorithms/TrigT2MinBias/src/TrigCountSpacePoints.cxx
index 3133e740ebc8123d85de4bf44301776f5adb6043..d5ffe2de28917be59ae8cb46ea004f6631204bfb 100644
--- a/Trigger/TrigAlgorithms/TrigT2MinBias/src/TrigCountSpacePoints.cxx
+++ b/Trigger/TrigAlgorithms/TrigT2MinBias/src/TrigCountSpacePoints.cxx
@@ -420,12 +420,11 @@ HLT::ErrorCode TrigCountSpacePoints::hltExecute(std::vector<std::vector<HLT::Tri
       //std::vector<int>::iterator idIt = m_listOfPixIds.begin();
       for( ; hashIt != hashItEnd; ++hashIt ){
         // get single pixel collection -> pixSpCollIt
-        SpacePointContainer::const_iterator pixSpCollIt = pixCont->indexFind( (*hashIt) );
-        if( pixSpCollIt == pixCont->end() ) continue;
-        if( (*pixSpCollIt) == NULL ) continue;
+        auto pixSpCollIt = pixCont->indexFindPtr( (*hashIt) );
+        if( pixSpCollIt == NULL ) continue;
 
         // identify a module/wafer
-        Identifier pixid = (*pixSpCollIt)->identify();
+        Identifier pixid = pixSpCollIt->identify();
 
         // If B-layer only mode, then enforce layer 0
         if (m_doOnlyBLayer == true && m_pixHelper->layer_disk(pixid) != 0) continue;
@@ -433,8 +432,8 @@ HLT::ErrorCode TrigCountSpacePoints::hltExecute(std::vector<std::vector<HLT::Tri
         int bec = m_pixHelper->barrel_ec(pixid);
 
         // retrieve number of pixel SP/CL per collection
-        SpacePointCollection::const_iterator spItEnd = (*pixSpCollIt)->end();
-        SpacePointCollection::const_iterator spIt = (*pixSpCollIt)->begin();
+        SpacePointCollection::const_iterator spItEnd = pixSpCollIt->end();
+        SpacePointCollection::const_iterator spIt = pixSpCollIt->begin();
 
         for( ; spIt != spItEnd; ++spIt ){
           const Trk::SpacePoint* pSP = (*spIt);
@@ -638,16 +637,15 @@ HLT::ErrorCode TrigCountSpacePoints::hltExecute(std::vector<std::vector<HLT::Tri
       std::vector<IdentifierHash>::iterator sctItEnd = m_listOfSctIds.end();
       std::vector<IdentifierHash>::iterator sctIt = m_listOfSctIds.begin();
       for ( ; sctIt != sctItEnd; ++sctIt ) {
-        SpacePointContainer::const_iterator sctSpCollIt = sctCont->indexFind( (*sctIt) );
+        auto sctSpCollIt = sctCont->indexFindPtr( (*sctIt) );
 
-        if( sctSpCollIt == sctCont->end() ) continue;
-        if( (*sctSpCollIt) == NULL ) continue;
+        if( sctSpCollIt == NULL ) continue;
 
         const std::vector<Identifier>& rdoList();
-        m_nSctSP = (*sctSpCollIt)->size();
+        m_nSctSP = sctSpCollIt->size();
 
         // returns detector element identifier
-        Identifier sctid = (*sctSpCollIt)->identify();
+        Identifier sctid = sctSpCollIt->identify();
 
         int bec = (int)m_sctHelper->barrel_ec(sctid);
 
diff --git a/Trigger/TrigAlgorithms/TrigT2MinBias/src/TrigCountSpacePoints.h b/Trigger/TrigAlgorithms/TrigT2MinBias/src/TrigCountSpacePoints.h
index abb9dc2f8206c4b989e428516c9d92ca5b4d2bb2..e1ae048b3b8edca80a87b9926bee56c4f2deddfa 100644
--- a/Trigger/TrigAlgorithms/TrigT2MinBias/src/TrigCountSpacePoints.h
+++ b/Trigger/TrigAlgorithms/TrigT2MinBias/src/TrigCountSpacePoints.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGMINBIAS_TRIGCOUNTSPACEPOINTS_H
@@ -16,7 +16,6 @@ class SCT_ID;
 class PixelID;
 class TrigSpacePointCounts;
 class IRegSelSvc;
-class IRegSelSvc;
 
 /** @class TrigCountSpacePoints
 
diff --git a/Trigger/TrigAlgorithms/TrigTRTHighTHitCounter/src/TrigTRTHTHCounter.h b/Trigger/TrigAlgorithms/TrigTRTHighTHitCounter/src/TrigTRTHTHCounter.h
index 7258f0defc645557011018f14412587a2b0ca404..3ad5f917ea4bb37dccf744347d0ff076e85bc9f5 100644
--- a/Trigger/TrigAlgorithms/TrigTRTHighTHitCounter/src/TrigTRTHTHCounter.h
+++ b/Trigger/TrigAlgorithms/TrigTRTHighTHitCounter/src/TrigTRTHTHCounter.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGTRTHTHCOUNTER_H
@@ -18,7 +18,6 @@
 */
 
 class TRT_ID;
-class IRegSelSvc;
 class ITrigTRT_DriftCircleProviderTool;
 class IdentifierHash;
 
@@ -37,7 +36,6 @@ class TrigTRTHTHCounter: public HLT::FexAlgo {
 
   
   const TRT_ID *m_trtHelper;                     //!<  TRT ID helper
-  //  ServiceHandle<IRegSelSvc>    m_regionSelector; //!<  region selector service
 
   std::vector<IdentifierHash> m_listOfTrtIds;    //!<  IDs of DE from regionSelector
 
diff --git a/Trigger/TrigAlgorithms/TrigTauRec/python/TrigTauRecMonitoring.py b/Trigger/TrigAlgorithms/TrigTauRec/python/TrigTauRecMonitoring.py
index 7dc04482185be8ef179077eb3fba1c8146c1e2f4..f47473bbe10f544d24bab72e75e9f41225203b21 100644
--- a/Trigger/TrigAlgorithms/TrigTauRec/python/TrigTauRecMonitoring.py
+++ b/Trigger/TrigAlgorithms/TrigTauRec/python/TrigTauRecMonitoring.py
@@ -137,11 +137,6 @@ def tauMonitoringCaloOnly():
    monTool.defineHistogram('ChPiEMEOverCaloEME', path='EXPERT', type='TH1F', title="EF EM energy of charged pions over calorimetric EM energy;ChPiEME over CaloEME; nRoIs", xbins=40, xmin=-20., xmax=20.)
    monTool.defineHistogram('innerTrkAvgDist', path='EXPERT', type='TH1F', title="EF inner track average distance; innerTrkAvgDist; nRoIs", xbins=40, xmin=-0.05, xmax=0.5)
    monTool.defineHistogram('nCand', path='EXPERT', type='TH1F', title="Number of tau candidates;Number of tau candidates; nevents", xbins=10, xmin=-1.0, xmax=9.)
-   monTool.defineHistogram('ActualInteractions', path='EXPERT', type='TH1F', title="Number of actual interaction per bunch crossing;ActualInteractions;nevents", xbins=80, xmin=0.0, xmax=80.)
-   monTool.defineHistogram('AvgInteractions', path='EXPERT', type='TH1F', title="Number of average interaction per bunch crossing;AvgInteractions;nevents", xbins=80, xmin=0.0, xmax=80.)
-   monTool.defineHistogram('beamspot_x', path='EXPERT', type='TH1F', title="Beamspot position;Beamspot x;nevents", xbins=50, xmin=-10.0, xmax=10.)
-   monTool.defineHistogram('beamspot_y', path='EXPERT', type='TH1F', title="Beamspot position;Beamspot y;nevents", xbins=50, xmin=-10.0, xmax=10.)
-   monTool.defineHistogram('beamspot_z', path='EXPERT', type='TH1F', title="Beamspot position;Beamspot z;nevents", xbins=100, xmin=-500.0, xmax=500.)
    monTool.defineHistogram('PhiL1', path='EXPERT', type='TH1F', title="L1 RoI Phi; L1 RoI Phi; nRoIs", xbins=65, xmin=-3.1415936-0.098174/2., xmax=3.1415936+0.098174/2.)
    monTool.defineHistogram('EtaL1', path='EXPERT', type='TH1F', title="L1 RoI Eta; L1 RoI Eta; nRoIs", xbins=51, xmin=-2.55, xmax=2.55)
    monTool.defineHistogram('EtaL1, PhiL1', path='EXPERT', type='TH2F', title="L1 ROI Eta vs Phi in TrigTauRecMerged FEX; #eta; #phi",
diff --git a/Trigger/TrigAlgorithms/TrigTauRec/src/TrigTauRecMergedMT.cxx b/Trigger/TrigAlgorithms/TrigTauRec/src/TrigTauRecMergedMT.cxx
index 11021919d78c22140d2e597f95e672f174bfece6..eec012767adc03c990838f230383a4ab2427dab0 100644
--- a/Trigger/TrigAlgorithms/TrigTauRec/src/TrigTauRecMergedMT.cxx
+++ b/Trigger/TrigAlgorithms/TrigTauRec/src/TrigTauRecMergedMT.cxx
@@ -31,8 +31,6 @@
 #include "xAODTau/TauTrackContainer.h"
 #include "xAODTau/TauTrackAuxContainer.h"
 
-#include "LumiBlockComps/ILumiBlockMuTool.h"
-
 #include "TrigTauRecMergedMT.h"
 #include "AthenaMonitoringKernel/Monitored.h"
 
@@ -46,12 +44,10 @@
 TrigTauRecMergedMT::TrigTauRecMergedMT(const std::string& name,ISvcLocator* pSvcLocator)
   :AthAlgorithm(name, pSvcLocator),
    m_tools(this),
-   m_endtools(this),
-   m_lumiBlockMuTool("LumiBlockMuTool/LumiBlockMuTool")
+   m_endtools(this)
 {
   declareProperty("Tools", m_tools, "List of ITauToolBase tools" );
   declareProperty("EndTools", m_endtools, "List of End ITauToolBase tools" );
-  declareProperty("LumiBlockMuTool", m_lumiBlockMuTool, "Luminosity Tool" );
 }
 
 TrigTauRecMergedMT::~TrigTauRecMergedMT()
@@ -106,16 +102,6 @@ StatusCode TrigTauRecMergedMT::initialize()
     }
   }
 
-  if (m_lumiBlockMuTool.retrieve().isFailure()) {
-    ATH_MSG_WARNING("Unable to retrieve LumiBlockMuTool");
-  } 
-  else {
-    ATH_MSG_DEBUG("Successfully retrieved LumiBlockMuTool");
-  }
-
-  // Retrieve beam conditions
-  CHECK(m_beamSpotKey.initialize());
-
   if ( not m_monTool.name().empty() ) {
     ATH_CHECK( m_monTool.retrieve() );
   }
@@ -178,11 +164,6 @@ StatusCode TrigTauRecMergedMT::execute()
   auto SumPtTrkFrac       = Monitored::Scalar<float>("SumPtTrkFrac",-999.9);
   auto innerTrkAvgDist    = Monitored::Scalar<float>("innerTrkAvgDist",-1.0);
   auto Ncand              = Monitored::Scalar<int>("nCand",0);
-  auto ActualInteractions = Monitored::Scalar<float>("ActualInteractions",-999.9);
-  auto AvgInteractions    = Monitored::Scalar<float>("AvgInteractions",-999.9);
-  auto beamspot_x         = Monitored::Scalar<float>("beamspot_x",-999.9);
-  auto beamspot_y         = Monitored::Scalar<float>("beamspot_y",-999.9);
-  auto beamspot_z         = Monitored::Scalar<float>("beamspot_z",-999.9);
   auto EtaL1              = Monitored::Scalar<float>("EtaL1",-99.9);
   auto PhiL1              = Monitored::Scalar<float>("PhiL1",-99.9);
   auto EtaEF              = Monitored::Scalar<float>("EtaEF",-99.9);
@@ -194,8 +175,7 @@ StatusCode TrigTauRecMergedMT::execute()
   auto monitorIt = Monitored::Group( m_monTool, nCells, nTracks, dEta, dPhi, emRadius, hadRadius,
                                      EtFinal, Et, EtHad, EtEm, EMFrac, IsoFrac, centFrac, nWideTrk, ipSigLeadTrk, trFlightPathSig, massTrkSys,
                                      dRmax, numTrack, trkAvgDist, etovPtLead, PSSFraction, EMPOverTrkSysP, ChPiEMEOverCaloEME, SumPtTrkFrac,
-                                     innerTrkAvgDist, Ncand, ActualInteractions, AvgInteractions, beamspot_x, beamspot_y, beamspot_z, EtaL1,
-                                     PhiL1, EtaEF, PhiEF );
+                                     innerTrkAvgDist, Ncand, EtaL1, PhiL1, EtaEF, PhiEF );
 
   // Retrieve store.
   ATH_MSG_DEBUG("Executing TrigTauRecMergedMT");
@@ -222,41 +202,6 @@ StatusCode TrigTauRecMergedMT::execute()
     return StatusCode::SUCCESS;
   }
 
-  double mu = 0.0;
-  double avg_mu = 0.0;
-  if(m_lumiBlockMuTool){
-    mu     = m_lumiBlockMuTool->actualInteractionsPerCrossing(); // (retrieve mu for the current BCID)
-    avg_mu = m_lumiBlockMuTool->averageInteractionsPerCrossing();
-    ActualInteractions = mu;
-    AvgInteractions    = avg_mu;
-    ATH_MSG_DEBUG(" Retrieved Mu Value : " << mu);
-    ATH_MSG_DEBUG(" Average Mu Value   : " << avg_mu);
-  }
-	
-
-  //-------------------------------------------------------------------------
-  // Get beamspot
-  //-------------------------------------------------------------------------
-
-  // Copy the first vertex from a const object
-  xAOD::Vertex theBeamspot;
-  theBeamspot.makePrivateStore();
-
-  SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey, ctx };
-  if(beamSpotHandle.isValid()){
-	
-    // Alter the position of the vertex
-    theBeamspot.setPosition(beamSpotHandle->beamPos());
-	
-    beamspot_x=theBeamspot.x();
-    beamspot_y=theBeamspot.y();
-    beamspot_z=theBeamspot.z();
-
-    // Create a AmgSymMatrix to alter the vertex covariance mat.
-    const auto& cov = beamSpotHandle->beamVtx().covariancePosition();
-    theBeamspot.setCovariancePosition(cov);
-  }
-
   // get TauJetContainer from SG
   const xAOD::TauJetContainer *pTauContainer = nullptr;
   const xAOD::TauTrackContainer *pTauTrackContainer = nullptr;
diff --git a/Trigger/TrigAlgorithms/TrigTauRec/src/TrigTauRecMergedMT.h b/Trigger/TrigAlgorithms/TrigTauRec/src/TrigTauRecMergedMT.h
index fa9435ad5812b53ae8ec673b465a9df04ce5aa9f..ca58d8b7ef5d0fa7891b40da327c64d1f334bfa4 100755
--- a/Trigger/TrigAlgorithms/TrigTauRec/src/TrigTauRecMergedMT.h
+++ b/Trigger/TrigAlgorithms/TrigTauRec/src/TrigTauRecMergedMT.h
@@ -25,12 +25,6 @@
 
 #include "TrigSteeringEvent/TrigRoiDescriptor.h"
 
-namespace HLT {
-  class TriggerElement;
-}
-
-class ILumiBlockMuTool;
-
 class TrigTauRecMergedMT: public AthAlgorithm {
 
  public:
@@ -75,15 +69,6 @@ class TrigTauRecMergedMT: public AthAlgorithm {
   /** internal tool store */
   ToolHandleArray<ITauToolBase>  m_endtools;
 
-  /** Luminosity Tool */
-  ToolHandle<ILumiBlockMuTool> m_lumiBlockMuTool;
-
-  /** Beam spot Object */
-  SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey { this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot" };
-
-  /** vector of Timers */
-  std::vector<TrigTimer* > m_mytimers;
-
   // Monitoring tool
   ToolHandle< GenericMonitoringTool > m_monTool { this, "MonTool", "", "Monitoring tool" };
 
diff --git a/Trigger/TrigAlgorithms/TrigTileMuId/src/TrigTileLookForMuAlg.cxx b/Trigger/TrigAlgorithms/TrigTileMuId/src/TrigTileLookForMuAlg.cxx
index 1a045197a01dbb6882cf7381b0c037fa797caf7e..4f0265c5e8bc463f546e100c8c83af091f448dee 100755
--- a/Trigger/TrigAlgorithms/TrigTileMuId/src/TrigTileLookForMuAlg.cxx
+++ b/Trigger/TrigAlgorithms/TrigTileMuId/src/TrigTileLookForMuAlg.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //---------------------------------------------------------------------------
@@ -13,7 +13,6 @@
 #include "GaudiKernel/ITHistSvc.h"
 #include "TrigT1Interfaces/TrigT1Interfaces_ClassDEF.h"
 #include "TrigSteeringEvent/TrigRoiDescriptor.h"
-#include "RegionSelector/IRegSelSvc.h"
 #include "ByteStreamCnvSvcBase/IROBDataProviderSvc.h"
 #include "CaloIdentifier/TileID.h"
 #include "ByteStreamData/ROBData.h"
@@ -472,7 +471,7 @@ HLT::ErrorCode TrigTileLookForMuAlg::hltExecute(std::vector<std::vector<HLT::Tri
           OK_HighThr = true;
           if (!m_LooseSelection && (m0[k1][j1]>=m_thres0[k1]) ) OK_HighThr=false;
 
-          if ( ( ( (k1!=4 || k1!=25) && m0[k1][j1]>m_th0d ) || ( (k1==4 || k1==25) && m0[k1][j1]>m_thitcd ) ) && OK_HighThr ) { 
+          if ( ( ( (k1!=4 && k1!=25) && m0[k1][j1]>m_th0d ) || ( (k1==4 || k1==25) && m0[k1][j1]>m_thitcd ) ) && OK_HighThr ) { 
 
 	    enedp1[ci3] = m0[k1][j1];
 	    aquality[ci3]=(m0[k1][j1] < m_thres0[k1] ? 0:1);  
diff --git a/Trigger/TrigAlgorithms/TrigTileMuId/src/TrigTileLookForMuAlg.h b/Trigger/TrigAlgorithms/TrigTileMuId/src/TrigTileLookForMuAlg.h
index be9685ec38b80b330781e6049c43a48ae431b633..4aa9f20b71fee67fc6743a757f10bad0442fcf19 100755
--- a/Trigger/TrigAlgorithms/TrigTileMuId/src/TrigTileLookForMuAlg.h
+++ b/Trigger/TrigAlgorithms/TrigTileMuId/src/TrigTileLookForMuAlg.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //****************************************************************************
@@ -30,7 +30,6 @@
 namespace HLT {
   class TriggerElement;
 }
-class IRegSelSvc;
 class Identifier;
 class TileID;
 
diff --git a/Trigger/TrigAnalysis/TrigEgammaAnalysisTools/CMakeLists.txt b/Trigger/TrigAnalysis/TrigEgammaAnalysisTools/CMakeLists.txt
index 03461a2f752301b6bf6c35f31348f5023d4d59bb..3d6d3226ba7eb59f1e3aae6a0bdd5bb4dd6b22ff 100644
--- a/Trigger/TrigAnalysis/TrigEgammaAnalysisTools/CMakeLists.txt
+++ b/Trigger/TrigAnalysis/TrigEgammaAnalysisTools/CMakeLists.txt
@@ -1,43 +1,8 @@
-################################################################################
-# Package: TrigEgammaAnalysisTools
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( TrigEgammaAnalysisTools )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          Control/AthToolSupport/AsgTools
-                          Event/xAOD/xAODCaloEvent
-                          Event/xAOD/xAODEgamma
-                          Event/xAOD/xAODEventInfo
-                          Event/xAOD/xAODJet
-                          Event/xAOD/xAODPrimitives
-                          Event/xAOD/xAODTracking
-                          Event/xAOD/xAODTrigCalo
-                          Event/xAOD/xAODTrigEgamma
-                          Event/xAOD/xAODTrigRinger
-                          Event/xAOD/xAODTrigger
-                          Event/xAOD/xAODTruth
-                          Event/xAOD/xAODMissingET
-                          Event/xAOD/xAODCaloRings
-                          LumiBlock/LumiBlockComps
-                          PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools
-                          Reconstruction/RecoTools/RecoToolInterfaces
-                          Reconstruction/egamma/egammaMVACalib
-                          Trigger/TrigAnalysis/TrigDecisionTool
-                          Trigger/TrigAnalysis/TrigEgammaMatchingTool
-                          Trigger/TrigAnalysis/TrigEgammaEmulationTool
-                          Trigger/TrigConfiguration/TrigConfHLTData
-                          Trigger/TrigEvent/TrigSteeringEvent
-                          Trigger/TrigMonitoring/TrigHLTMonitoring
-                          PhysicsAnalysis/AnalysisCommon/PATCore
-                          PRIVATE
-                          Control/AthenaBaseComps
-                          Control/AthenaMonitoring
-                          Control/StoreGate
-                          GaudiKernel
-                          Trigger/TrigConfiguration/TrigConfxAOD )
 # External dependencies:
 find_package( Boost )
 find_package( ROOT COMPONENTS Core Hist Tree )
@@ -48,25 +13,18 @@ atlas_add_library( TrigEgammaAnalysisToolsLib
    PUBLIC_HEADERS TrigEgammaAnalysisTools
    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
    PRIVATE_INCLUDE_DIRS ${Boost_INCLUDE_DIRS}
-   LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools xAODCaloEvent xAODEgamma
-   xAODEventInfo xAODJet xAODTracking xAODTrigCalo xAODTrigEgamma xAODTrigRinger xAODMissingET
-   xAODTrigger xAODCaloRings xAODTruth LumiBlockCompsLib EgammaAnalysisInterfacesLib
-   RecoToolInterfaces egammaMVACalibAnalysisLib 
-   TrigEgammaMatchingToolLib TrigEgammaEmulationToolLib TrigConfHLTData
-   TrigSteeringEvent TrigHLTMonitoringLib PATCoreLib
-   PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES} TrigConfxAODLib )
+   LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools EgammaAnalysisInterfacesLib GaudiKernel LumiBlockCompsLib LumiBlockData PATCoreLib StoreGateLib TrigConfHLTData TrigDecisionToolLib TrigEgammaEmulationToolLib TrigEgammaMatchingToolLib TrigHLTMonitoringLib TrigNavigationLib xAODCaloEvent xAODCaloRings xAODEgamma xAODEventInfo xAODJet xAODMissingET xAODTracking xAODTrigCalo xAODTrigEgamma xAODTrigRinger xAODTrigger xAODTruth
+   PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES} AthenaMonitoringLib TrigConfxAODLib TrigSteeringEvent )
 
 atlas_add_component( TrigEgammaAnalysisTools
-                     src/*.h
-                     src/*.cxx
-                     src/components/*.cxx
-                     INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${Boost_LIBRARIES} ElectronPhotonSelectorToolsLib egammaMVACalibLib TrigDecisionToolLib AthenaBaseComps AthenaMonitoringLib StoreGateLib SGtests GaudiKernel TrigEgammaAnalysisToolsLib )
+   src/*.h
+   src/*.cxx
+   src/components/*.cxx
+   LINK_LIBRARIES AthenaBaseComps AthenaMonitoringLib TrigEgammaAnalysisToolsLib )
 
 # Install files from the package:
 atlas_install_python_modules( python/TrigEgamma*.py )
 atlas_install_joboptions( share/test*.py )
 atlas_install_generic( share/trigEgammaDQ.py share/get_trigEgammaDQ.sh 
-                        DESTINATION share
-                        EXECUTABLE )
-
+   DESTINATION share
+   EXECUTABLE )
diff --git a/Trigger/TrigAnalysis/TrigEgammaEmulationTool/CMakeLists.txt b/Trigger/TrigAnalysis/TrigEgammaEmulationTool/CMakeLists.txt
index 72cdd17128357046d59524158a95efd71b04530d..e1c5b631fdca4c47646d265f91802e832a98a8b6 100644
--- a/Trigger/TrigAnalysis/TrigEgammaEmulationTool/CMakeLists.txt
+++ b/Trigger/TrigAnalysis/TrigEgammaEmulationTool/CMakeLists.txt
@@ -1,41 +1,8 @@
-################################################################################
-# Package: TrigEgammaEmulationTool
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( TrigEgammaEmulationTool )
 
-
-# Declare the package's dependencies:
-atlas_depends_on_subdirs(
-   PUBLIC
-   Control/AthContainers
-   Control/AthToolSupport/AsgTools
-   Event/xAOD/xAODBase
-   Event/xAOD/xAODCaloEvent
-   Event/xAOD/xAODEgamma
-   Event/xAOD/xAODPrimitives
-   Event/xAOD/xAODTracking
-   Event/xAOD/xAODTrigCalo
-   Event/xAOD/xAODTrigEgamma
-   Event/xAOD/xAODTrigRinger
-   Event/xAOD/xAODTrigger
-   PhysicsAnalysis/AnalysisCommon/PATCore
-   PhysicsAnalysis/Interfaces/EgammaAnalysisInterfaces
-   LumiBlock/LumiBlockComps
-   InnerDetector/InDetRecTools/InDetTrackSelectionTool
-   Reconstruction/RecoTools/RecoToolInterfaces
-   Tools/PathResolver
-   Trigger/TrigAnalysis/TrigDecisionTool
-   Trigger/TrigConfiguration/TrigConfHLTData
-   Trigger/TrigEvent/TrigSteeringEvent
-   Trigger/TrigHypothesis/TrigMultiVarHypo
-   Trigger/TrigAnalysis/TrigEgammaMatchingTool
-   PRIVATE
-   Control/AthenaBaseComps
-   Control/StoreGate
-   GaudiKernel )
-
 # External dependencies:
 find_package( Boost )
 find_package( CLHEP )
@@ -46,25 +13,13 @@ atlas_add_library( TrigEgammaEmulationToolLib
    PUBLIC_HEADERS TrigEgammaEmulationTool 
    INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS}
    PRIVATE_INCLUDE_DIRS ${Boost_INCLUDE_DIRS}
-   LINK_LIBRARIES ${CLHEP_LIBRARIES} AthContainers AsgTools xAODBase
-   xAODCaloEvent xAODEgamma xAODTracking xAODTrigCalo xAODTrigEgamma
-   xAODTrigRinger xAODTrigger PATCoreLib EgammaAnalysisInterfacesLib
-   LumiBlockCompsLib InDetTrackSelectionToolLib RecoToolInterfaces
-   TrigDecisionToolLib TrigConfHLTData TrigSteeringEvent TrigMultiVarHypoLib
-   TrigEgammaMatchingToolLib
-   PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES} )
+   LINK_LIBRARIES ${Boost_LIBRARIES} AsgTools AthContainers EgammaAnalysisInterfacesLib InDetTrackSelectionToolLib LumiBlockCompsLib PATCoreLib RecoToolInterfaces TrigConfHLTData TrigDecisionToolLib TrigEgammaMatchingToolLib TrigMultiVarHypoLib xAODBase xAODCaloEvent xAODCaloRings xAODEgamma xAODPrimitives xAODTracking xAODTrigCalo xAODTrigEgamma xAODTrigRinger xAODTrigger
+   PRIVATE_LINK_LIBRARIES StoreGateLib TrigSteeringEvent )
 
 atlas_add_component( TrigEgammaEmulationTool
-    src/*.h src/*.cxx src/components/*.cxx
-    LINK_LIBRARIES ${Boost_LIBRARIES} ${CLHEP_LIBRARIES}
-    AthContainers AsgTools xAODBase xAODCaloEvent xAODEgamma  xAODTracking
-    xAODTrigCalo xAODTrigEgamma xAODTrigRinger xAODTrigger PATCoreLib
-    ElectronPhotonSelectorToolsLib TrigDecisionToolLib TrigConfHLTData
-    TrigSteeringEvent TrigMultiVarHypoLib AthenaBaseComps StoreGateLib SGtests
-    GaudiKernel TrigEgammaMatchingToolLib LumiBlockCompsLib IsolationToolLib
-    TrigEgammaEmulationToolLib) 
-
+   src/*.cxx src/components/*.cxx
+   LINK_LIBRARIES AthenaBaseComps GaudiKernel TrigEgammaEmulationToolLib )
 
 # Install files from the package:
-atlas_install_python_modules( python/TrigEgamma*.py )
+atlas_install_python_modules( python/TrigEgamma*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
 atlas_install_joboptions( share/test*.py )
diff --git a/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationEFConfig.py b/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationEFConfig.py
index 32bad9c316e894ee4d7b149b3177b08acc5158b0..d6415bdd0b2a02fad28e71c38b201f3f0e5d999e 100644
--- a/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationEFConfig.py
+++ b/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationEFConfig.py
@@ -1,12 +1,10 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-from AthenaCommon                                                 import CfgMgr
 from AthenaCommon.AppMgr                                          import ToolSvc
 from egammaRec.Factories                                          import ToolFactory
 #from TrigEgammaHypo.TrigEgammaPidTools                            import ElectronToolName
 #from ElectronPhotonSelectorTools.ElectronPhotonSelectorToolsConf  import AsgElectronIsEMSelector
 #from ElectronPhotonSelectorTools.ElectronIsEMSelectorMapping      import ElectronIsEMMap,electronPIDmenu
-from TrigEgammaEmulationTool.TrigEgammaEmulationToolConfig        import OutputLevel
 
 
 #***********************************************************************
diff --git a/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationIsolationConfig.py b/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationIsolationConfig.py
index 23961e8ee341da9225168e7a51a8f84b4086fa12..d1b7d61ec9f37638f1f9136fcf1a76d818990f80 100644
--- a/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationIsolationConfig.py
+++ b/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationIsolationConfig.py
@@ -1,15 +1,12 @@
-# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 def createIsoToolElectronSelector():
 
   from AthenaCommon.AppMgr import ToolSvc
-  from AthenaCommon import CfgMgr
-  from egammaRec.Factories                                          import ToolFactory
   from TrigEgammaEmulationTool.TrigEgammaEmulationToolConf import Trig__TrigEgammaIsolationSelectorTool
   from TrigEgammaEmulationTool.TrigEgammaEmulationToolConfig        import OutputLevel
   
   from TrigEgammaHypo.TrigEFElectronHypoConfig import isolation_dict, caloisolation_dict
-  from TrigEgammaHypo.TrigEFPhotonHypoConfig   import TrigEFPhotonIsoCutDefs
 
   # Track isolation -- remember to add TrackIsolation as a property of the class
   from IsolationTool.IsolationToolConf import xAOD__TrackIsolationTool
@@ -37,7 +34,7 @@ def createIsoToolElectronSelector():
   for wp in isolations:
 
     caloiso = True if 'icalo' in wp else False
-    trkiso = True if not 'icalo' in wp else False
+    trkiso = True if 'icalo' not in wp else False
     
     tool = Trig__TrigEgammaIsolationSelectorTool( 'IsolationTool_'+wp,
                                           RelEtConeCut = caloisolation_dict[wp] if caloiso else [-1,-1,-1,-1,-1,-1],
@@ -52,10 +49,4 @@ def createIsoToolElectronSelector():
     ToolSvc += tool
     IsoToolSelectors.append( tool )
 
-    #Just to see WTF!
-    _toolname='IsolationTool_'+wp
-    RelEtConeCut = caloisolation_dict[wp] if caloiso else [-1,-1,-1,-1,-1,-1],
-    RelPtConeCut = isolation_dict[wp] if trkiso else [-1,-1,-1,-1,-1,-1],
-
   return IsoToolSelectors
-
diff --git a/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationL2Config.py b/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationL2Config.py
index 75e49f2fd78659aac78e0351ee8a1dcfd78fd75c..0e04d23bd04f478258cab8138b78bdb9f47129d4 100644
--- a/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationL2Config.py
+++ b/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationL2Config.py
@@ -1,7 +1,6 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-
-from egammaRec.Factories  import ToolFactory,FcnWrapper,AlgFactory, getPropertyValue
+from egammaRec.Factories  import ToolFactory
 from TrigEgammaEmulationTool.TrigEgammaEmulationToolConf import Trig__TrigEgammaL2CaloSelectorTool
 from TrigEgammaEmulationTool.TrigEgammaEmulationToolConf import Trig__TrigEgammaL2ElectronSelectorTool
 from AthenaCommon.SystemOfUnits                          import GeV
diff --git a/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationPidToolsConfig.py b/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationPidToolsConfig.py
index 2f8a02f377849e9fbdbe5e8ce875e42072de690e..4f708648df04dc3de9aed922ee9a286892fecd05 100644
--- a/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationPidToolsConfig.py
+++ b/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationPidToolsConfig.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 #
 # TrigEgammaPidTools
 # Add all pid selectors to ToolSvc
@@ -11,18 +11,13 @@
 ###############################################################
 
 from AthenaCommon import CfgMgr
-from AthenaCommon.AppMgr import ToolSvc
 
 import PyUtils.RootUtils as ru
 ROOT = ru.import_root()
 import cppyy
 cppyy.loadDictionary('ElectronPhotonSelectorToolsDict')
-from ROOT import LikeEnum
-from ROOT import egammaPID
 
 from ElectronPhotonSelectorTools.TrigEGammaPIDdefs import SelectionDefElectron
-from ElectronPhotonSelectorTools.ElectronPhotonSelectorToolsConf import AsgElectronIsEMSelector
-from ElectronPhotonSelectorTools.ElectronIsEMSelectorMapping import ElectronIsEMMap,electronPIDmenu
 
 ###################################################################################################
 
@@ -44,7 +39,11 @@ def getEgammaIsEMSelectorCaloOnly( calibPath ):
   for idx, config in enumerate(configList):
     name = config.split('/')[-1].replace('.conf','_EFCalo_'+calibname)
     asg = CfgMgr.AsgElectronIsEMSelector(name)
-    asg.caloOnly=True; asg.isEMMask=mask[idx];  asg.ConfigFile=config; ToolSvc+=asg; asgTools.append(asg)
+    asg.caloOnly=True
+    asg.isEMMask=mask[idx]
+    asg.ConfigFile=config
+    ToolSvc+=asg
+    asgTools.append(asg)
   return asgTools
 
 
@@ -66,14 +65,17 @@ def getElectronIsEMSelector( calibPath ):
   for idx, config in enumerate(configList):
     name = config.split('/')[-1].replace('.conf','_HLT_'+calibname)
     asg = CfgMgr.AsgElectronIsEMSelector(name)
-    asg.isEMMask=mask[idx];  asg.ConfigFile=config; ToolSvc+=asg; asgTools.append(asg)
+    asg.isEMMask=mask[idx]
+    asg.ConfigFile=config
+    ToolSvc+=asg
+    asgTools.append(asg)
   return asgTools
 
 # http://atlas.web.cern.ch/Atlas/GROUPS/DATABASE/GroupData/ElectronPhotonSelectorTools/trigger/rel21_20170214/
 # http://atlas.web.cern.ch/Atlas/GROUPS/DATABASE/GroupData/ElectronPhotonSelectorTools/trigger/rel21_20170217/
 # http://atlas.web.cern.ch/Atlas/GROUPS/DATABASE/GroupData/ElectronPhotonSelectorTools/trigger/rel21_20170217_mc16a/
 def getEgammaLikelihoodSelectorCaloOnly( calibPath ):
-  
+
   from AthenaCommon.AppMgr import ToolSvc
   calibname = calibPath.split('/')[-1]
   configList = [
@@ -86,14 +88,18 @@ def getEgammaLikelihoodSelectorCaloOnly( calibPath ):
   for idx, config in enumerate(configList):
     name = config.split('/')[-1].replace('.conf','_EFCalo_'+calibname)
     asg = CfgMgr.AsgElectronLikelihoodTool(name)
-    asg.usePVContainer = False;  asg.ConfigFile=config; asg.caloOnly = True; ToolSvc+=asg; asgTools.append(asg)
+    asg.usePVContainer = False
+    asg.ConfigFile=config
+    asg.caloOnly = True
+    ToolSvc+=asg
+    asgTools.append(asg)
   return asgTools
 
 # http://atlas.web.cern.ch/Atlas/GROUPS/DATABASE/GroupData/ElectronPhotonSelectorTools/trigger/rel21_20170214/
 # http://atlas.web.cern.ch/Atlas/GROUPS/DATABASE/GroupData/ElectronPhotonSelectorTools/trigger/rel21_20170217/
 # http://atlas.web.cern.ch/Atlas/GROUPS/DATABASE/GroupData/ElectronPhotonSelectorTools/trigger/rel21_20170217_mc16a/
 def getElectronLikelihoodSelector2015( calibPath ):
-  
+
   from AthenaCommon.AppMgr import ToolSvc
   calibname = calibPath.split('/')[-1]
   configList = [
@@ -106,14 +112,18 @@ def getElectronLikelihoodSelector2015( calibPath ):
   for idx, config in enumerate(configList):
     name = config.split('/')[-1].replace('.conf','_HLT_'+calibname)
     asg = CfgMgr.AsgElectronLikelihoodTool(name)
-    asg.usePVContainer = False;  asg.ConfigFile=config; asg.caloOnly = True; ToolSvc+=asg; asgTools.append(asg)
+    asg.usePVContainer = False
+    asg.ConfigFile=config
+    asg.caloOnly = True
+    ToolSvc+=asg
+    asgTools.append(asg)
   return asgTools
 
 # http://atlas.web.cern.ch/Atlas/GROUPS/DATABASE/GroupData/ElectronPhotonSelectorTools/trigger/rel21_20170214/
 # http://atlas.web.cern.ch/Atlas/GROUPS/DATABASE/GroupData/ElectronPhotonSelectorTools/trigger/rel21_20170217/
 # http://atlas.web.cern.ch/Atlas/GROUPS/DATABASE/GroupData/ElectronPhotonSelectorTools/trigger/rel21_20170217_mc16a/
 def getElectronLikelihoodSelectorNoD0( calibPath ):
-  
+
   from AthenaCommon.AppMgr import ToolSvc
   calibname = calibPath.split('/')[-1]
   configList = [
@@ -126,7 +136,11 @@ def getElectronLikelihoodSelectorNoD0( calibPath ):
   for idx, config in enumerate(configList):
     name = config.split('/')[-1].replace('.conf','_HLT_'+calibname)
     asg = CfgMgr.AsgElectronLikelihoodTool(name)
-    asg.usePVContainer = False;  asg.ConfigFile=config; asg.caloOnly = True; ToolSvc+=asg; asgTools.append(asg)
+    asg.usePVContainer = False
+    asg.ConfigFile=config
+    asg.caloOnly = True
+    ToolSvc+=asg
+    asgTools.append(asg)
   return asgTools
 
 #####################################################################################################
diff --git a/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationToolConfig.py b/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationToolConfig.py
index 9872f0545619b8cd755cb97f6017923f8f5e7bbe..6e3ce5b1de4ef1084a90ee9820f8f49508a2f60c 100644
--- a/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationToolConfig.py
+++ b/Trigger/TrigAnalysis/TrigEgammaEmulationTool/python/TrigEgammaEmulationToolConfig.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 #********************************************************************************
 #
@@ -14,16 +14,11 @@ OutputLevel = 0
 from AthenaCommon.Logging import logging
 logger = logging.getLogger("TrigEgammaEmulationToolConfig")
 
-from AthenaCommon         import CfgMgr
 from AthenaCommon.AppMgr  import ToolSvc
-from egammaRec.Factories  import ToolFactory,FcnWrapper,AlgFactory, getPropertyValue
+from egammaRec.Factories  import ToolFactory
 import PyUtils.RootUtils as ru
 ROOT = ru.import_root()
-import cppyy
-
-# Following loads the online selectors
-from ElectronPhotonSelectorTools.ElectronPhotonSelectorToolsConf  import AsgElectronIsEMSelector
-from ElectronPhotonSelectorTools.ElectronIsEMSelectorMapping      import ElectronIsEMMap,electronPIDmenu
+import cppyy  # noqa: F401
 
 #*****************************************************************************
 #from TrigEgammaMatchingTool.TrigEgammaMatchingToolConf import Trig__TrigEgammaMatchingTool
diff --git a/Trigger/TrigAnalysis/TrigEgammaMatchingTool/CMakeLists.txt b/Trigger/TrigAnalysis/TrigEgammaMatchingTool/CMakeLists.txt
index 79db3b49f8e722b3065c7739da9ebf3e37795b34..ab41d94b4aaa1be32bdec6f30601510be4a8257e 100644
--- a/Trigger/TrigAnalysis/TrigEgammaMatchingTool/CMakeLists.txt
+++ b/Trigger/TrigAnalysis/TrigEgammaMatchingTool/CMakeLists.txt
@@ -1,52 +1,19 @@
-################################################################################
-# Package: TrigEgammaMatchingTool
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( TrigEgammaMatchingTool )
 
-
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          Event/xAOD/xAODCaloEvent
-                          Event/xAOD/xAODEgamma
-                          Event/xAOD/xAODTracking
-                          Event/xAOD/xAODTrigCalo
-                          Event/xAOD/xAODTrigEgamma
-                          Event/xAOD/xAODMuon
-                          Event/xAOD/xAODTau
-                          Event/xAOD/xAODTrigger
-                          Trigger/TrigAnalysis/TrigDecisionTool
-                          Trigger/TrigConfiguration/TrigConfHLTData
-                          Trigger/TrigEvent/TrigSteeringEvent
-                          Trigger/TrigSteer/DecisionHandling
-                          PRIVATE
-                          Control/AthToolSupport/AsgTools
-                          Control/AthenaMonitoring
-                          Control/StoreGate
-                          Control/AthenaBaseComps
-                          GaudiKernel )
-
-
-
 # External dependencies:
-find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
+find_package( Boost )
 
 # Component(s) in the package:
 atlas_add_library( TrigEgammaMatchingToolLib
                    Root/*.cxx
                    PUBLIC_HEADERS TrigEgammaMatchingTool
-                   PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                   LINK_LIBRARIES AsgTools xAODCaloEvent xAODEgamma xAODTracking xAODTrigCalo xAODTrigEgamma TrigConfHLTData 
-                   TrigSteeringEvent TrigDecisionToolLib DecisionHandlingLib AthenaMonitoringLib
-                   PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} xAODMuon xAODTau xAODTrigger  )
-
+                   PRIVATE_INCLUDE_DIRS ${Boost_INCLUDE_DIRS}
+                   PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES} TrigSteeringEvent xAODRootAccess
+                   LINK_LIBRARIES AsgTools DecisionHandlingLib GaudiKernel TrigConfHLTData TrigDecisionToolLib xAODCaloEvent xAODEgamma xAODTracking xAODTrigCalo xAODTrigEgamma xAODTrigger )
 
 atlas_add_component( TrigEgammaMatchingTool
                      src/*.h src/*.cxx src/components/*.cxx
-                     INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools xAODCaloEvent xAODEgamma xAODTracking xAODTrigCalo xAODTrigEgamma 
-                     TrigDecisionToolLib TrigConfHLTData TrigSteeringEvent AthenaBaseComps xAODMuon xAODTau xAODTrigger GaudiKernel 
-                     TrigEgammaMatchingToolLib AthenaMonitoringLib StoreGateLib)
-
-
+                     LINK_LIBRARIES AthenaBaseComps AthenaMonitoringLib GaudiKernel StoreGateLib TrigEgammaMatchingToolLib TriggerMatchingToolLib xAODMuon xAODTau )
diff --git a/Trigger/TrigAnalysis/TrigInDetAnalysisUser/Analysis/src/rmain.cxx b/Trigger/TrigAnalysis/TrigInDetAnalysisUser/Analysis/src/rmain.cxx
index e330577804045b851ac307bc8036e018a3ce8f1b..6f9eec0452cd66925854b98715fdf491ad8a0c3e 100644
--- a/Trigger/TrigAnalysis/TrigInDetAnalysisUser/Analysis/src/rmain.cxx
+++ b/Trigger/TrigAnalysis/TrigInDetAnalysisUser/Analysis/src/rmain.cxx
@@ -535,6 +535,8 @@ int main(int argc, char** argv)
   int nbl = -1;
 
   int nsiholes = 2;
+  int npixholes = 20; /// essentially no limit
+  int nsctholes = 20; /// essentially no limit
 
   bool expectBL = false;
 
@@ -590,6 +592,8 @@ int main(int argc, char** argv)
   if ( inputdata.isTagDefined("zed") )      zed      = inputdata.GetValue("zed");
   if ( inputdata.isTagDefined("npix") )     npix     = inputdata.GetValue("npix");
   if ( inputdata.isTagDefined("nsiholes") ) nsiholes = inputdata.GetValue("nsiholes");
+  if ( inputdata.isTagDefined("npixholes") ) npixholes = inputdata.GetValue("npixholes");
+  if ( inputdata.isTagDefined("nsctholes") ) nsctholes = inputdata.GetValue("nsctholes");
   if ( inputdata.isTagDefined("expectBL") ) expectBL = ( inputdata.GetValue("expectBL") > 0.5 ? true : false );
   if ( inputdata.isTagDefined("nsct") )     nsct     = inputdata.GetValue("nsct");
   if ( inputdata.isTagDefined("nbl") )      nbl      = inputdata.GetValue("nbl");
@@ -930,7 +934,7 @@ int main(int argc, char** argv)
   Filter_Track filter_offline( eta, 1000, zed, pT, 
                                npix, nsct, -1, nbl, 
                                -2, -2, chi2prob, 
-                               20, 20, nsiholes, expectBL ); /// include chi2 probability cut 
+                               npixholes, nsctholes, nsiholes, expectBL ); /// include chi2 probability cut 
 
   if ( selectcharge!=0 ) filter_offline.chargeSelection( selectcharge );
   if ( pTMax>pT )        filter_offline.maxpT( pTMax );
diff --git a/Trigger/TrigAnalysis/TrigJiveXML/src/TrigSiSpacePointRetriever.cxx b/Trigger/TrigAnalysis/TrigJiveXML/src/TrigSiSpacePointRetriever.cxx
index 1e35fd89560d38f76fd4ad7b2a63c04504cf1c84..c42287556dbb754343892b217be39daccc0df46e 100755
--- a/Trigger/TrigAnalysis/TrigJiveXML/src/TrigSiSpacePointRetriever.cxx
+++ b/Trigger/TrigAnalysis/TrigJiveXML/src/TrigSiSpacePointRetriever.cxx
@@ -55,9 +55,9 @@ namespace JiveXML {
  
     int maxHash = m_pixelHelper->wafer_hash_max();
      for(int id=0;id<maxHash;++id){
-	    TrigSiSpacePointContainer::const_iterator spCollIt=pCont->indexFind(id);
-	    if(spCollIt==pCont->end()) continue;
-	    for(TrigSiSpacePointCollection::const_iterator spIt=(*spCollIt)->begin(); spIt!=(*spCollIt)->end();++spIt){
+	    auto spCollIt=pCont->indexFindPtr(id);
+	    if(spCollIt==nullptr) continue;
+	    for(TrigSiSpacePointCollection::const_iterator spIt=spCollIt->begin(); spIt!=spCollIt->end();++spIt){
 		x.push_back(DataType((*spIt)->x() /10.));
 		y.push_back(DataType((*spIt)->y() /10.));
 		z.push_back(DataType((*spIt)->z() /10.));
@@ -77,9 +77,9 @@ namespace JiveXML {
 
     int maxHash = m_sctHelper->wafer_hash_max();
        for(int id=0;id<maxHash;++id){
-	    TrigSiSpacePointContainer::const_iterator spCollIt=pCont->indexFind(id);
-	    if(spCollIt==pCont->end()) continue;
-	    for(TrigSiSpacePointCollection::const_iterator spIt=(*spCollIt)->begin(); spIt!=(*spCollIt)->end();++spIt){
+	    auto spCollIt=pCont->indexFindPtr(id);
+	    if(spCollIt==nullptr) continue;
+	    for(TrigSiSpacePointCollection::const_iterator spIt=spCollIt->begin(); spIt!=spCollIt->end();++spIt){
 		x.push_back(DataType((*spIt)->x() /10.));
 		y.push_back(DataType((*spIt)->y() /10.));
 		z.push_back(DataType((*spIt)->z() /10.));
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTChain.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTChain.h
index f95829c949b35c9300cebc905149d6f0540e79ba..c0755dda26977142d5039171db0747cffa54edd4 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTChain.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTChain.h
@@ -50,7 +50,7 @@ namespace TrigConf {
       std::vector<std::string> l1thresholds() const;
 
       /** Accessor to the connected output streams */
-      std::vector<DataStructure> streams() const;
+      std::vector<std::string> streams() const;
 
       /** Accessor to the groups this chain belongs to */
       std::vector<std::string> groups() const;
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTMenu.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTMenu.h
index 887766cf8f4e595cbead29c167856fac6a89c307..ec445700604467987e1761a969b8a29d916c70b9 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTMenu.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTMenu.h
@@ -54,6 +54,9 @@ namespace TrigConf {
        */
       const_iterator end() const;
 
+      /** Accessor to the connected output streams */
+      std::vector<DataStructure> streams() const;
+
       /** print overview of L1 Menu */
       void printMenu(bool full = false) const;
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/HLTChain.cxx b/Trigger/TrigConfiguration/TrigConfData/src/HLTChain.cxx
index 261e3f443081a066a3b7695b1aa598e10adb6357..0a072f3e40e12b3ae0cd2bcb7d0b305ade89b5ed 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/HLTChain.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/HLTChain.cxx
@@ -66,19 +66,22 @@ TrigConf::Chain::l1thresholds() const
 }
 
 
-std::vector<TrigConf::DataStructure>
+std::vector<std::string>
 TrigConf::Chain::streams() const
 {
-   std::vector<DataStructure> strlist;
-   const auto & streams = data().get_child("streams");
-   strlist.reserve(streams.size());
 
-   for( auto & strData : streams )
-      strlist.emplace_back( strData.second );
-   
+   std::vector<std::string> strlist;
+   const auto & streams = getList("streams");
+   if( !streams.empty() ) {
+      strlist.reserve(streams.size());
+      for( auto & stream : streams ) {
+         strlist.emplace_back( stream.getValue<std::string>() );
+      }
+   }
    return strlist;
 }
 
+
 std::vector<std::string>
 TrigConf::Chain::groups() const
 {
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/HLTMenu.cxx b/Trigger/TrigConfiguration/TrigConfData/src/HLTMenu.cxx
index 8c81eddb00127f21f769700662cb831c69a6f44a..817ae1ee6f82ee2f446207aec8c2111c06297532 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/HLTMenu.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/HLTMenu.cxx
@@ -60,11 +60,25 @@ TrigConf::HLTMenu::end() const
 }
 
 
+std::vector<TrigConf::DataStructure>
+TrigConf::HLTMenu::streams() const
+{
+   std::vector<DataStructure> strlist;
+   const auto & streams = data().get_child("streams");
+   strlist.reserve(streams.size());
+
+   for( auto & strData : streams )
+      strlist.emplace_back( strData.second );
+
+   return strlist;
+}
+
 
 void
 TrigConf::HLTMenu::printMenu(bool full) const
 {
    cout << "HLT menu '" << name() << "'" << endl;
+   cout << "Streams: " << data().get_child("streams").size() << endl;
    cout << "Chains: " << size() << endl;
    if(full) {
       int c(0);
diff --git a/Trigger/TrigConfiguration/TrigConfIO/python/HLTTriggerConfigAccess.py b/Trigger/TrigConfiguration/TrigConfIO/python/HLTTriggerConfigAccess.py
index 8aff51fee8b64ba8351c1ff7eb60bb63d6d67ed2..daed3c4457ba57bd2fb9ecd7e39fc028cd0b99cc 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/python/HLTTriggerConfigAccess.py
+++ b/Trigger/TrigConfiguration/TrigConfIO/python/HLTTriggerConfigAccess.py
@@ -25,12 +25,16 @@ class HLTMenuAccess(TriggerConfigAccess):
     def chains(self):
         return iter(self)
 
+    def streams(self):
+        return self["streams"]
+
     def sequencers(self):
         return self["sequencers"]
 
     def printSummary(self):
         print("HLT menu %s" % self.name())
         print("Number of chains: %i" % len(self) )
+        print("Number of streams: %i" % len(self.streams()) )
         print("Number of sequencers: %i" % len(self.sequencers()) )
 
 
diff --git a/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx b/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx
index 76b6c13bc1b2ec2cc5852c869c8e41d3f4b2f1f3..39cb2b5992ee628fa7bc2550cdaaa030e51da945 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx
@@ -274,11 +274,15 @@ bool testHLTMenu(const string & filename) {
          printComma = true;
       }
       cout << endl;
-      cout << "streams:" << endl;
+      cout << "streams:" << endl << "  ";
+      printComma = false;
       for( auto & s : ch.streams() ) {
-         cout << "  " << s["type"] << "_" << s["name"] 
-              << (s["obeyLB"]=="yes" ? " (obeys LB" : " (does not obey LB") << " and has prescale " << s["prescale"] << ")" << endl;
+         if (printComma)
+            cout << ", ";
+         cout << s;
+         printComma = true;
       }
+      cout << endl;
       cout << "and groups:" << endl << "  ";
       printComma = false;
       for( auto & g : ch.groups() ) {
@@ -290,6 +294,16 @@ bool testHLTMenu(const string & filename) {
       cout << endl;
       if(--np==0) break;
    }
+   vector<TrigConf::DataStructure> streams = hltmenu.streams();
+   cout << "Menu has " << streams.size() << " streams, going to print the first 3." << endl;
+   np = 3;
+   for( auto & s : streams ) {
+      cout << "  " << s["type"] << "_" << s["name"]
+           << (s["obeyLB"]=="true" ? " (obeys LB" : " (does not obey LB") << ")"
+           << (s["forceFullEventBuilding"]=="true" ? " (forces FullEventBuilding" : " (does not force FullEventBuilding") << ")"
+           << endl;
+      if(--np==0) break;
+   }
    return true;
 }
 
diff --git a/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcCfg.py b/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcCfg.py
index 0b892f7f501f1a457873dc765ed3323d92cb15d9..a1603a63f1b97239d88cebfcb802a0834be482f6 100644
--- a/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcCfg.py
+++ b/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcCfg.py
@@ -98,18 +98,17 @@ def createHLTPrescalesFileFromMenu( flags=None ):
     log = logging.getLogger('TrigConfigSvcCfg')
     menuFN = getHLTMenuFileName( flags )
     with open(menuFN,'r') as fh:
-        data = json.load(fh)
+        data = json.load(fh, object_pairs_hook = odict)
         pso = odict()
         pso['filetype'] = 'hltprescale'
         pso['name'] = data['name']
         pso['prescales'] = odict()
         ps = pso['prescales']
-        for ch in data['chains']:
-            chName = ch['name']
-            ps[chName] = odict([
-                ("name", chName),
-                ("counter", ch['counter']),
-                ("hash", ch['nameHash']),
+        for name, chain in data['chains'].items():
+            ps[name] = odict([
+                ("name", name),
+                ("counter", chain['counter']),
+                ("hash", chain['nameHash']),
                 ("prescale", 1),
                 ("enabled", 1)
             ])
diff --git a/Trigger/TrigEvent/TrigBSExtraction/CMakeLists.txt b/Trigger/TrigEvent/TrigBSExtraction/CMakeLists.txt
index 0f7f9b618324ea9475bab0a6850837e0ce2f9e41..10c01220bf6ae397ebdb3e6b7ea12e57980f9fcb 100644
--- a/Trigger/TrigEvent/TrigBSExtraction/CMakeLists.txt
+++ b/Trigger/TrigEvent/TrigBSExtraction/CMakeLists.txt
@@ -56,7 +56,7 @@ atlas_depends_on_subdirs( PUBLIC
 atlas_add_component( TrigBSExtraction
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaBaseComps StoreGateLib SGtests GaudiKernel TrigSerializeCnvSvcLib TrigNavigationLib TrigSteeringEvent xAODJet xAODMuon xAODTracking xAODTrigBphys xAODTrigCalo xAODTrigMinBias xAODTrigMissingET xAODTrigMuon xAODTau xAODEgamma xAODCaloEvent xAODTrigger xAODBTagging JetEvent Particle tauEvent egammaEvent CaloEvent TrkTrack TrigCaloEvent TrigInDetEvent TrigMissingEtEvent TrigMuonEvent TrigParticle TrigStorageDefinitions )
+                     LINK_LIBRARIES AthenaBaseComps StoreGateLib SGtests GaudiKernel TrigSerializeCnvSvcLib TrigNavigationLib TrigSteeringEvent xAODJet xAODMuon xAODTracking xAODTrigBphys xAODTrigCalo xAODTrigMinBias xAODTrigMissingET xAODTrigMuon xAODTau xAODEgamma xAODCaloEvent xAODTrigger xAODBTagging JetEvent Particle tauEvent egammaEvent CaloEvent TrkTrack TrigCaloEvent TrigInDetEvent TrigMissingEtEvent TrigMuonEvent TrigParticle TrigStorageDefinitions xAODTauCnvLib xAODTrigMuonCnvLib xAODJetCnvLib xAODTrigCaloCnvLib xAODBTaggingCnvLib xAODTrigBphysCnvLib xAODTrigMissingETCnvLib xAODTrigMinBiasCnvLib xAODEgammaCnvLib xAODCaloEventCnvLib xAODTriggerCnvLib )
 
 # Install files from the package:
 atlas_install_headers( TrigBSExtraction )
diff --git a/Trigger/TrigHypothesis/TrigHypoCommonTools/TrigHypoCommonTools/L1InfoHypo.hxx b/Trigger/TrigHypothesis/TrigHypoCommonTools/TrigHypoCommonTools/L1InfoHypo.hxx
index 1c899f4a209341a1b484eba7edfdc0c5083e269c..9936bbd30c89d972704403aec1332eef56da5366 100755
--- a/Trigger/TrigHypothesis/TrigHypoCommonTools/TrigHypoCommonTools/L1InfoHypo.hxx
+++ b/Trigger/TrigHypothesis/TrigHypoCommonTools/TrigHypoCommonTools/L1InfoHypo.hxx
@@ -19,8 +19,6 @@
 #include "TrigSteering/LvlConverter.h"
 #include "TrigConfInterfaces/ILVL1ConfigSvc.h"
 
-class IRegSelSvc;
-
 namespace HLT 
 {
   class ILvl1ResultAccessTool;
diff --git a/Trigger/TrigHypothesis/TrigHypoCommonTools/src/L1InfoHypo.cxx b/Trigger/TrigHypothesis/TrigHypoCommonTools/src/L1InfoHypo.cxx
index 221bbaed6c72a93b53955b0decbf09cf0d67ad6d..b6f8e0fca95f1271a8d89c7338d081e4b3ff250e 100755
--- a/Trigger/TrigHypothesis/TrigHypoCommonTools/src/L1InfoHypo.cxx
+++ b/Trigger/TrigHypothesis/TrigHypoCommonTools/src/L1InfoHypo.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 /*
@@ -12,7 +12,6 @@
 #include "EventInfo/TriggerInfo.h"
 #include "EventInfo/EventInfo.h"
 
-#include "RegionSelector/IRegSelSvc.h"
 #include "PathResolver/PathResolver.h"
 #include "GaudiKernel/ITHistSvc.h"
 #include "TrigSteeringEvent/TrigRoiDescriptor.h"
diff --git a/Trigger/TrigHypothesis/TrigLongLivedParticlesHypo/src/TrigLLPInnerDetectorHypo.cxx b/Trigger/TrigHypothesis/TrigLongLivedParticlesHypo/src/TrigLLPInnerDetectorHypo.cxx
index 77c8c0f8b86200e56902b90387714cbc216f8822..2482c6ff75bf337f9265fa98ff0dc9be6c73170b 100644
--- a/Trigger/TrigHypothesis/TrigLongLivedParticlesHypo/src/TrigLLPInnerDetectorHypo.cxx
+++ b/Trigger/TrigHypothesis/TrigLongLivedParticlesHypo/src/TrigLLPInnerDetectorHypo.cxx
@@ -242,13 +242,12 @@ HLT::ErrorCode TrigLLPInnerDetectorHypo::hltExecute(const HLT::TriggerElement* /
     for( ; hashIt != hashItEnd; ++hashIt ){
       
       // get single pixel collection -> pixSpCollIt
-      SpacePointContainer::const_iterator pixSpCollIt = pixCont->indexFind( (*hashIt) );
-      if( pixSpCollIt == pixCont->end() ) continue;
-      if( (*pixSpCollIt) == NULL ) continue;
+      auto pixSpCollIt = pixCont->indexFindPtr( (*hashIt) );
+      if( pixSpCollIt == NULL ) continue;
       
       // retrieve number of pixel SP/CL per collection
-      SpacePointCollection::const_iterator spItEnd = (*pixSpCollIt)->end();
-      SpacePointCollection::const_iterator spIt = (*pixSpCollIt)->begin();
+      SpacePointCollection::const_iterator spItEnd = pixSpCollIt->end();
+      SpacePointCollection::const_iterator spIt = pixSpCollIt->begin();
       
       for( ; spIt != spItEnd; ++spIt ){
 	
@@ -315,16 +314,15 @@ HLT::ErrorCode TrigLLPInnerDetectorHypo::hltExecute(const HLT::TriggerElement* /
     std::vector<IdentifierHash>::iterator sctIt = m_listOfSctIds.begin();
     for( ; sctIt != sctItEnd; ++sctIt ){
       
-      SpacePointContainer::const_iterator sctSpCollIt = sctCont->indexFind( (*sctIt) );
+      auto sctSpCollIt = sctCont->indexFindPtr( (*sctIt) );
       
-      if( sctSpCollIt == sctCont->end() ) continue;
-      if( (*sctSpCollIt) == NULL ) continue;
+      if( sctSpCollIt == NULL ) continue;
       
       const std::vector<Identifier>& rdoList();
-      m_nSctSP = (*sctSpCollIt)->size();
+      m_nSctSP = sctSpCollIt->size();
       
       // returns detector element identifier
-      Identifier sctid = (*sctSpCollIt)->identify();
+      Identifier sctid = sctSpCollIt->identify();
       
       //int bec = (int)m_sctHelper->barrel_ec(sctid);
       
diff --git a/Trigger/TrigMonitoring/TrigSteerMonitor/src/TrigSignatureMoniMT.cxx b/Trigger/TrigMonitoring/TrigSteerMonitor/src/TrigSignatureMoniMT.cxx
index c2531161d548be0c3472097f10fc9ab38650abb6..3e8d5c063653c546bf03a78b016b701ad891fee5 100644
--- a/Trigger/TrigMonitoring/TrigSteerMonitor/src/TrigSignatureMoniMT.cxx
+++ b/Trigger/TrigMonitoring/TrigSteerMonitor/src/TrigSignatureMoniMT.cxx
@@ -52,8 +52,8 @@ StatusCode TrigSignatureMoniMT::start() {
       }
     }
 
-    for ( const auto& stream : chain.streams() ){
-      m_streamToChainMap[stream.getAttribute("name")].insert( HLT::Identifier(chain.name()) );
+    for ( const std::string& stream : chain.streams() ){
+      m_streamToChainMap[stream].insert( HLT::Identifier(chain.name()) );
     }
 
     if( gotL1Menu && !chain.l1item().empty() ) {
diff --git a/Trigger/TrigSteer/TrigOutputHandling/src/StreamTagMakerTool.cxx b/Trigger/TrigSteer/TrigOutputHandling/src/StreamTagMakerTool.cxx
index 3c5211163a921f8a0d5ab118c2a63b66e2fe8f8a..5cf723383e05f6c55cb4a159126cb2ed34890030 100644
--- a/Trigger/TrigSteer/TrigOutputHandling/src/StreamTagMakerTool.cxx
+++ b/Trigger/TrigSteer/TrigOutputHandling/src/StreamTagMakerTool.cxx
@@ -36,32 +36,46 @@ StatusCode StreamTagMakerTool::initialize() {
   }
 
   ATH_MSG_INFO("Configuring from HLTMenu from DetStore with " << hltMenu->size() << " chains");
+
+  std::vector<TrigConf::DataStructure> allStreams = hltMenu->streams();
+  ATH_MSG_INFO("Menu has " << allStreams.size() << " streams defined");
+  std::map<std::string, StreamTagInfo> streamDictionary;
+  ATH_MSG_DEBUG("StreamTags [Name,type,obeyLB,forceFullEventBuilding]:");
+  for (const TrigConf::DataStructure& stream : allStreams) {
+    try {
+      std::string stream_name         = stream.getAttribute("name");
+      std::string stream_type         = stream.getAttribute("type");
+      std::string_view obeyLB         = stream.getAttribute("obeyLB");
+      std::string_view fullEventBuild = stream.getAttribute("forceFullEventBuilding");
+      StreamTagInfo streamTag = {
+        stream_name,
+        stream_type,
+        obeyLB == "true",
+        fullEventBuild == "true"
+      };
+      ATH_MSG_DEBUG("-- " << streamTag);
+      streamDictionary.insert(std::pair<std::string, StreamTagInfo>(stream.getAttribute("name"),streamTag));
+    } catch (const std::exception& ex) {
+      ATH_MSG_ERROR("Failure reading stream tag configuration from JSON: " << ex.what());
+      return StatusCode::FAILURE;
+    }
+  }
+
   for (const TrigConf::Chain & chain : *hltMenu) {
-    std::vector<TrigConf::DataStructure> streams = chain.streams();
+    std::vector<std::string> streams = chain.streams();
     if (streams.empty()) {
       ATH_MSG_ERROR("Chain " << chain.name() << " has no streams assigned");
       return StatusCode::FAILURE;
     }
     ATH_MSG_DEBUG("Chain " << chain.name() << " is assigned to " << streams.size() << " streams");
     m_mapping[ HLT::Identifier( chain.name() ) ] = {};
-    for (const TrigConf::DataStructure& stream : streams) {
-      try {
-        std::string stream_name         = stream.getAttribute("name");
-        std::string stream_type         = stream.getAttribute("type");
-        std::string_view obeyLB         = stream.getAttribute("obeyLB");
-        std::string_view fullEventBuild = stream.getAttribute("forceFullEventBuilding");
-        StreamTagInfo streamTag = {
-          stream_name,
-          stream_type,
-          obeyLB == "true",
-          fullEventBuild == "true"
-        };
-        m_mapping[ HLT::Identifier(chain.name()).numeric() ].push_back(streamTag);
-        ATH_MSG_DEBUG("-- " << stream_type << "_" << stream_name
-                      << " (obeyLB=" << obeyLB << ", forceFullEventBuilding=" << fullEventBuild << ")");
-      } catch (const std::exception& ex) {
-        ATH_MSG_ERROR("Failure reading stream tag configuration from JSON: " << ex.what());
-        return StatusCode::FAILURE;
+    for (const std::string& stream : streams) {
+      ATH_MSG_DEBUG("-- " << stream);
+      if (const auto streamIt = streamDictionary.find(stream); streamIt != streamDictionary.end()) {
+         m_mapping[ HLT::Identifier(chain.name()).numeric() ].push_back(streamIt->second);
+      }else{
+         ATH_MSG_ERROR("Failure reading stream tag configuration for stream: " << stream);
+         return StatusCode::FAILURE;
       }
     }
   }
diff --git a/Trigger/TrigT1/L1Topo/L1TopoSimulation/CMakeLists.txt b/Trigger/TrigT1/L1Topo/L1TopoSimulation/CMakeLists.txt
index c9aab2bc2571b83596d506a1556da6af688a0d85..d59494a9456fba0a3be7143cd576cafee83cea52 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoSimulation/CMakeLists.txt
+++ b/Trigger/TrigT1/L1Topo/L1TopoSimulation/CMakeLists.txt
@@ -33,7 +33,7 @@ atlas_disable_as_needed()
 
 # Component(s) in the package:
 atlas_add_library( L1TopoSimulationLib
-   L1TopoSimulation/*.h Root/*.cxx
+   L1TopoSimulation/*.h
    INTERFACE
    PUBLIC_HEADERS L1TopoSimulation
    LINK_LIBRARIES GaudiKernel )
diff --git a/Trigger/TrigT1/L1Topo/L1TopoSimulationUtils/L1TopoSimulationUtils/L1TopoDataTypes.h b/Trigger/TrigT1/L1Topo/L1TopoSimulationUtils/L1TopoSimulationUtils/L1TopoDataTypes.h
index 9bb22c40c45863c8fc1d730708bdabb3281e6888..c35486b9ea89211ab096a818eb9cf9091a2446c1 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoSimulationUtils/L1TopoSimulationUtils/L1TopoDataTypes.h
+++ b/Trigger/TrigT1/L1Topo/L1TopoSimulationUtils/L1TopoSimulationUtils/L1TopoDataTypes.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 /*********************************
  * L1TopoDataTypes.h
@@ -182,8 +182,9 @@ namespace TSU {
           // Get integer part
           res += (m_tvalue>>F)&((1<<(PREC-F))-1) ? float((m_tvalue>>F)&((1<<(PREC-F))-1)) : 0;
           // Do the fractional part
-          for(unsigned j=0;j<F;++j){
-            res += (m_tvalue & (1 << (F-1-j))) ? 1./(2<<(j)) : 0;
+          if (F > 0) {
+            unsigned frac = m_tvalue & ( (1<<F)-1 );
+            res += static_cast<float>(frac) / (2<<(F-1));
           }
           return res;
        }
diff --git a/Trigger/TrigT1/TrigT1CaloMonitoring/CMakeLists.txt b/Trigger/TrigT1/TrigT1CaloMonitoring/CMakeLists.txt
index 07d356ecaf64cf428ad7af2098692dadd2f0b2e2..dde39bcc376450bacb5116b1faeaf3c3e0dfaa06 100644
--- a/Trigger/TrigT1/TrigT1CaloMonitoring/CMakeLists.txt
+++ b/Trigger/TrigT1/TrigT1CaloMonitoring/CMakeLists.txt
@@ -53,4 +53,5 @@ atlas_add_component( TrigT1CaloMonitoring
 
 # Install files from the package:
 atlas_install_joboptions( share/*.py )
-
+# required for Run 3 monitoring
+atlas_install_python_modules( python/*.py )
diff --git a/Trigger/TrigT1/TrigT1CaloMonitoring/python/CpmMonitorAlgorithm.py b/Trigger/TrigT1/TrigT1CaloMonitoring/python/CpmMonitorAlgorithm.py
new file mode 100644
index 0000000000000000000000000000000000000000..a8e51a91664706ca133de2f8ba265f03f02a415f
--- /dev/null
+++ b/Trigger/TrigT1/TrigT1CaloMonitoring/python/CpmMonitorAlgorithm.py
@@ -0,0 +1,255 @@
+#
+#  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+#
+def CpmMonitoringConfig(inputFlags):
+    '''Function to configure LVL1 Cpm algorithm in the monitoring system.'''
+
+    import math 
+    # get the component factory - used for getting the algorithms
+    from AthenaConfiguration.ComponentFactory import CompFactory
+    from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+    result = ComponentAccumulator()
+
+    # make the athena monitoring helper
+    from AthenaMonitoring import AthMonitorCfgHelper
+    helper = AthMonitorCfgHelper(inputFlags,'CpmMonitoringCfg')
+
+    # get any algorithms
+    CpmMonAlg = helper.addAlgorithm(CompFactory.CpmMonitorAlgorithm,'CpmMonAlg')
+
+    # add any steering
+    groupName = 'CpmMonitor' # the monitoring group name is also used for the package name
+    CpmMonAlg.PackageName = groupName
+    crates = 4
+    CpmMonAlg.s_crates = crates
+    maxSlices = 5
+    CpmMonAlg.s_maxSlices = maxSlices
+    isolBits = 4
+    CpmMonAlg.s_isolBits = isolBits
+    tobsPerCPM = 5
+    CpmMonAlg.s_tobsPerCPM = tobsPerCPM
+    maxTobsPerCmx = 70
+    CpmMonAlg.MaxTOBsPerCMX = maxTobsPerCmx
+
+    # set up the directory structure
+    mainDir = 'L1Calo'
+    trigPath = 'CPM' # replaces m_rootDir
+    errorDir=trigPath+"/Errors/Hardware"
+    monDetailPath=errorDir+"/Detail/"
+    monCPMinputPath=trigPath+"/Input/"
+    monRoIPath=trigPath+"/Output/"
+    #monCMXPath=trigPath+"_CMX/Errors/Hardware/"
+    monCMXinPath=trigPath+"_CMX/Input/"
+    #monCMXoutPath=trigPath+"_CMX/Output/"
+
+    # add monitoring algorithm to group, with group name and main directory 
+    myGroup = helper.addGroup(CpmMonAlg, groupName , mainDir)
+
+    #
+    #   CPM Towers - monCPMinputPath
+    #
+    # Trigger Tower plots - for binning see TrigT1CaloLWHistogramTool::bookPPMEmEtaVsPhi
+    etabins_2d=66
+    etamin_2d=-3.3
+    etamax_2d=3.3
+    phibins_2d=64
+    phimin_2d=0.0
+    phimax_2d=64.0    
+    # for 2D histograms x,y;histogram alias
+    myGroup.defineHistogram('etaTT,phiTT;ppm_em_2d_etaPhi_tt_Hitmap',title='PPM Trigger Tower EM eta/phi;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='mask_em_TT',path=monCPMinputPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d)
+    myGroup.defineHistogram('etaTT,phiTT;ppm_had_2d_etaPhi_tt_Hitmap',title='PPM Trigger Tower HAD eta/phi;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='mask_had_TT',path=monCPMinputPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d)
+    
+    # CPMTower plots
+    maxEnergyRange = 256 # Maximum energy plotted
+    # EM 1d
+    myGroup.defineHistogram('etCpmTT_em;cpm_em_1d_tt_Et', title='CPM Tower EM Et;CPM Tower EM Energy;',
+                            cutmask='',path=monCPMinputPath,xbins=maxEnergyRange,xmin=0,xmax=maxEnergyRange)
+    myGroup.defineHistogram('etaCpmTT_em;cpm_em_1d_tt_Eta', title='CPM Tower EM eta;CPM Tower EM #eta;',
+                            cutmask='',path=monCPMinputPath,xbins=50,xmin=-2.5,xmax=2.5)
+    myGroup.defineHistogram('phiCpmTT_em;cpm_em_1d_tt_Phi', title='CPM Tower EM phi;CPM Tower EM #phi;',
+                            cutmask='',path=monCPMinputPath,xbins=64,xmin=0,xmax=2*math.pi)
+    # EM 2d
+    myGroup.defineHistogram('etaCpmTT_em,phiScaledCpmTT_em;cpm_em_2d_etaPhi_tt_Hitmap',
+                            title='CPM Tower EM eta/phi;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='',path=monCPMinputPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d)
+    myGroup.defineHistogram('etaCpmTT_em,phiScaledCpmTT_em;cpm_em_2d_etaPhi_tt_EtWeighted',
+                            title='CPM Tower EM eta/phi weighted;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='',path=monCPMinputPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d, weight="etCpmTT_em")
+
+    
+    # HAD 1d
+    myGroup.defineHistogram('etCpmTT_had;cpm_had_1d_tt_Et', title='CPM Tower HAD Et;CPM Tower HAD Energy;',
+                            cutmask='',path=monCPMinputPath,xbins=maxEnergyRange,xmin=0,xmax=maxEnergyRange)
+    myGroup.defineHistogram('etaCpmTT_had;cpm_had_1d_tt_Eta', title='CPM Tower HAD eta;CPM Tower HAD #eta;',
+                            cutmask='',path=monCPMinputPath,xbins=50,xmin=-2.5,xmax=2.5)
+    myGroup.defineHistogram('phiCpmTT_had;cpm_had_1d_tt_Phi', title='CPM Tower HAD phi;CPM Tower HAD #phi;',
+                            cutmask='',path=monCPMinputPath,xbins=64,xmin=0,xmax=2*math.pi)
+    # HAD 2d
+    myGroup.defineHistogram('etaCpmTT_had,phiScaledCpmTT_had;cpm_had_2d_etaPhi_tt_Hitmap',
+                            title='CPM Tower HAD eta/phi;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='',path=monCPMinputPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d)
+    myGroup.defineHistogram('etaCpmTT_had,phiScaledCpmTT_had;cpm_had_2d_etaPhi_tt_EtWeighted'
+                            ,title='CPM Tower HAD eta/phi weighted;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='',path=monCPMinputPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d, weight="etCpmTT_had")
+
+    xbinshist = int(crates * maxSlices)
+    myGroup.defineHistogram('sliceCpmTT_tot,peakCpmTT_tot;cpm_2d_tt_Slices'
+                            ,title='CPM Slices and Triggered Slice;Crate/Number of Slices;Triggered Slice',type='TH2F',
+                            cutmask='',path=monCPMinputPath,
+                            xbins=xbinshist,xmin=0,xmax=xbinshist,ybins=maxSlices,ymin=0,ymax=maxSlices)
+
+
+    #
+    # Errors - monDetailPath
+    #
+    # em - tot means addition of CPM and Overlap containers
+    myGroup.defineHistogram('etaCpmTT_em_tot,phiScaledCpmTT_em_tot;cpm_em_2d_etaPhi_tt_Parity'
+                            ,title='CPM Tower EM Parity Errors;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='parityErrorCpmTT_em',path=monDetailPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d)
+    myGroup.defineHistogram('etaCpmTT_em_tot,phiScaledCpmTT_em_tot;cpm_em_2d_etaPhi_tt_LinkDown',
+                            title='CPM Tower EM Link Down Errors;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='linkDownErrorCpmTT_em',path=monDetailPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d)
+
+    # had
+    myGroup.defineHistogram('etaCpmTT_had_tot,phiScaledCpmTT_had_tot;cpm_had_2d_etaPhi_tt_Parity',
+                            title='CPM Tower HAD Parity Errors;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='parityErrorCpmTT_had',path=monDetailPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d)
+    myGroup.defineHistogram('etaCpmTT_had_tot,phiScaledCpmTT_had_tot;cpm_had_2d_etaPhi_tt_LinkDown',
+                            title='CPM Tower HAD Link Down Errors;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='linkDownErrorCpmTT_had',path=monDetailPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d)
+
+
+    #
+    #  CPM TOB RoIs - monRoIPath
+    #
+    isolRange=32 # Maximum range for encoded isolation
+    myGroup.defineHistogram('energyTobRoIsEner;cpm_1d_roi_EnergyEm', title='CPM TOB RoI Cluster Energy EM;Cluster Energy;',
+                            cutmask='mask_tobroi_ener_em',path=monRoIPath,
+                            xbins=maxEnergyRange,xmin=0,xmax=maxEnergyRange)
+    myGroup.defineHistogram('energyTobRoIsEner;cpm_1d_roi_EnergyTau', title='CPM TOB RoI Cluster Energy Tau;Cluster Energy;',
+                            cutmask='mask_tobroi_ener_tau',path=monRoIPath,
+                            xbins=maxEnergyRange,xmin=0,xmax=maxEnergyRange)
+
+    myGroup.defineHistogram('energyTobRoIsIsol;cpm_1d_roi_IsolationEm', title='CPM TOB RoI Encoded Isolation Value EM;;',
+                            cutmask='mask_tobroi_isol_em',path=monRoIPath,
+                            xbins=isolRange,xmin=0,xmax=isolRange)
+    myGroup.defineHistogram('energyTobRoIsIsol;cpm_1d_roi_IsolationTau', title='CPM TOB RoI Encoded Isolation Value Tau;;',
+                            cutmask='mask_tobroi_isol_tau',path=monRoIPath,
+                            xbins=isolRange,xmin=0,xmax=isolRange)
+
+
+    # bit masks to be done
+    #myGroup.defineHistogram('bitsTobRoIsIsol;cpm_1d_roi_IsolationBitsEm', title='CPM TOB RoI Encoded Isolation Bits EM;;',
+    #                        cutmask='mask_tobroi_isol_em',path=monRoIPath,
+    #                        xbins=isolBits,xmin=0,xmax=isolBits)
+
+    # 2D
+    # For binning see TrigT1CaloLWHistogramTool::bookCPMRoIEtaVsPhi,fillCPMRoIEtaVsPhi m_shrinkEtaBins=true
+    # isolation
+    myGroup.defineHistogram('etaTobRoIsIsol,phiTobRoIsIsol;cpm_2d_etaPhi_roi_HitmapIsolEm',
+                            title='CPM TOB RoIs EM Non-zero Isolation Hit Map;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='mask_tobroi_isol_em',path=monRoIPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d)
+    myGroup.defineHistogram('etaTobRoIsIsol,phiTobRoIsIsol;cpm_2d_etaPhi_roi_HitmapIsolTau',
+                            title='CPM TOB RoIs Tau Non-zero Isolation Hit Map;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='mask_tobroi_isol_tau',path=monRoIPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d)
+
+    # energy
+    myGroup.defineHistogram('etaTobRoIsEner,phiTobRoIsEner;cpm_2d_etaPhi_roi_HitmapEm',
+                            title='CPM TOB RoIs EM Hit Map;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='mask_tobroi_ener_em',path=monRoIPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d)
+    myGroup.defineHistogram('etaTobRoIsEner,phiTobRoIsEner;cpm_2d_etaPhi_roi_EtWeightedEm',
+                            title='CPM TOB RoIs EM Weighted by Energy;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='mask_tobroi_ener_em',path=monRoIPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d, weight="energyTobRoIsEner")
+
+    myGroup.defineHistogram('etaTobRoIsEner,phiTobRoIsEner;cpm_2d_etaPhi_roi_HitmapTau',
+                            title='CPM TOB RoIs Tau Hit Map;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='mask_tobroi_ener_tau',path=monRoIPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d)
+    myGroup.defineHistogram('etaTobRoIsEner,phiTobRoIsEner;cpm_2d_etaPhi_roi_EtWeightedTau',
+                            title='CPM TOB RoIs Tau Weighted by Energy;Tower #eta; Tower #phi',type='TH2F',
+                            cutmask='mask_tobroi_ener_tau',path=monRoIPath,
+                            xbins=etabins_2d,xmin=etamin_2d,xmax=etamax_2d,ybins=phibins_2d,ymin=phimin_2d,ymax=phimax_2d, weight="energyTobRoIsEner")
+
+    # TOBs per CPM 
+    myGroup.defineHistogram('tobPerCPMEm;cpm_1d_roi_TOBsPerCPMEm', title='CPM TOB RoI TOBs per CPM EM;Number of TOBs;',
+                            cutmask='',path=monRoIPath,
+                            xbins=tobsPerCPM+1,xmin=1,xmax=tobsPerCPM+2)
+    myGroup.defineHistogram('tobPerCPMTau;cpm_1d_roi_TOBsPerCPMTau', title='CPM TOB RoI TOBs per CPM Tau;Number of TOBs;',
+                            cutmask='',path=monRoIPath,
+                            xbins=tobsPerCPM+1,xmin=1,xmax=tobsPerCPM+2)
+    # How to set labels e.g.
+    # m_h_cpm_1d_roi_TOBsPerCPMEm->GetXaxis()->SetBinLabel(s_tobsPerCPM + 1, "More");
+
+    #
+    #  CMX-CP TOBs - monCMXinPath
+    #
+    myGroup.defineHistogram('enerTobCmxEner;cmx_1d_tob_TOBsPerCMXLeft', title='CMX-CP TOBs per CMX Left;Number of TOBs;',
+                            cutmask='',path=monCMXinPath,
+                            xbins=maxTobsPerCmx,xmin=0,xmax=maxTobsPerCmx)
+
+
+    acc = helper.result()
+    result.merge(acc)
+    return result
+
+
+if __name__=='__main__':
+    # For direct tests
+    from AthenaCommon.Configurable import Configurable
+    Configurable.configurableRun3Behavior = 1
+
+    # set debug level for whole job
+    from AthenaCommon.Logging import log
+    from AthenaCommon.Constants import INFO #DEBUG
+    log.setLevel(INFO)
+
+    # set input file and config options
+    from AthenaConfiguration.AllConfigFlags import ConfigFlags
+    import glob
+
+    inputs = glob.glob('/eos/atlas/atlascerngroupdisk/data-art/build-output/master/Athena/x86_64-centos7-gcc8-opt/2020-04-06T2139/TrigP1Test/test_trigP1_v1PhysP1_T0Mon_build/ESD.pool.root')
+
+    ConfigFlags.Input.Files = inputs
+    ConfigFlags.Output.HISTFileName = 'ExampleMonitorOutput_LVL1.root'
+
+    ConfigFlags.lock()
+    ConfigFlags.dump() # print all the configs
+
+    from AthenaCommon.AppMgr import ServiceMgr
+    ServiceMgr.Dump = False
+
+    from AthenaConfiguration.MainServicesConfig import MainServicesSerialCfg 
+    from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
+    cfg = MainServicesSerialCfg()
+    cfg.merge(PoolReadCfg(ConfigFlags))
+
+    CpmMonitorCfg = CpmMonitoringConfig(ConfigFlags)
+    cfg.merge(CpmMonitorCfg)
+
+    # message level for algorithm
+    CpmMonitorCfg.getEventAlgo('CpmMonAlg').OutputLevel = 2 # 1/2 INFO/DEBUG
+    # options - print all details of algorithms, very short summary 
+    cfg.printConfig(withDetails=False, summariseProps = True)
+
+    nevents=-1
+    cfg.run(nevents)
+
+
+
+
diff --git a/Trigger/TrigT1/TrigT1CaloMonitoring/python/LVL1CaloMonitoringConfig.py b/Trigger/TrigT1/TrigT1CaloMonitoring/python/LVL1CaloMonitoringConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..04d66e715e0bce43ad098956e782a229950dad5b
--- /dev/null
+++ b/Trigger/TrigT1/TrigT1CaloMonitoring/python/LVL1CaloMonitoringConfig.py
@@ -0,0 +1,24 @@
+#
+#  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+#
+
+def LVL1CaloMonitoringConfig(flags):
+    '''Function to call l1calo DQ monitoring algorithms'''
+    from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+    import logging
+
+    # local printing
+    local_logger = logging.getLogger('AthenaMonitoringCfg')
+    info = local_logger.info
+    info('In LVL1CaloMonitoringConfig')
+
+    result = ComponentAccumulator()
+
+    # monitoring algorithm configs
+    # do not run in RAW->ESD, or AOD-only
+    if flags.DQ.Environment not in ('tier0Raw', 'AOD'):
+        from TrigT1CaloMonitoring.CpmMonitorAlgorithm import CpmMonitoringConfig
+        result.merge(CpmMonitoringConfig(flags))
+
+
+    return result
diff --git a/Trigger/TrigT1/TrigT1CaloMonitoring/src/CpmMonitorAlgorithm.cxx b/Trigger/TrigT1/TrigT1CaloMonitoring/src/CpmMonitorAlgorithm.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..08fdefa3fa3fa094658b8d6d4362aa480ed8ab48
--- /dev/null
+++ b/Trigger/TrigT1/TrigT1CaloMonitoring/src/CpmMonitorAlgorithm.cxx
@@ -0,0 +1,479 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "CpmMonitorAlgorithm.h"
+#include "TrigT1CaloUtils/CoordToHardware.h"
+#include "TrigT1CaloUtils/DataError.h"
+#include "TrigT1Interfaces/CPRoIDecoder.h"
+
+CpmMonitorAlgorithm::CpmMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator )
+  : AthMonitorAlgorithm(name,pSvcLocator),
+    m_phiScaleTT(32./M_PI), m_phiScaleJE(16./M_PI)
+{
+}
+
+StatusCode CpmMonitorAlgorithm::initialize() {
+
+  ATH_MSG_DEBUG("CpmMonitorAlgorith::initialize");
+  ATH_MSG_DEBUG("Package Name "<< m_packageName);
+  // container names
+  ATH_MSG_DEBUG("m_xAODTriggerTowerContainerName"<< m_xAODTriggerTowerContainerName); 
+  ATH_MSG_DEBUG("m_cpmTowerLocation"<< m_cpmTowerLocation); 
+  ATH_MSG_DEBUG("m_cpmTowerLocationOverlap"<< m_cpmTowerLocationOverlap); 
+
+  // steering parameters
+  ATH_MSG_DEBUG("m_crates"<<m_crates ); 
+  ATH_MSG_DEBUG("m_modules"<<m_modules ); 
+  ATH_MSG_DEBUG("m_maxSlices"<<m_maxSlices );
+  ATH_MSG_DEBUG("m_tobsPerCPM"<<m_tobsPerCPM );  
+  ATH_MSG_DEBUG("m_isolBits"<<m_isolBits ); 
+  ATH_MSG_DEBUG("m_maxTobsPerCmx"<<m_maxTobsPerCmx ); 
+
+  // initialise all the containers that we need
+  ATH_CHECK(m_xAODTriggerTowerContainerName.initialize());
+  ATH_CHECK(m_cpmTowerLocation.initialize());
+  ATH_CHECK(m_cpmTowerLocationOverlap.initialize());
+  ATH_CHECK( m_cpmTobRoiLocation.initialize());
+  ATH_CHECK( m_cmxCpTobLocation.initialize());
+  ATH_CHECK( m_cmxCpHitsLocation.initialize());
+
+  return AthMonitorAlgorithm::initialize();
+}
+
+StatusCode CpmMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
+
+  ATH_MSG_DEBUG("CpmMonitorAlgorithm::fillHistograms");
+
+  // Retrieve Trigger Towers from SG
+  SG::ReadHandle<xAOD::TriggerTowerContainer> triggerTowerTES(m_xAODTriggerTowerContainerName, ctx);
+  ATH_CHECK(triggerTowerTES.isValid());
+
+  // Retrieve Core CPM Towers from SG
+  SG::ReadHandle<xAOD::CPMTowerContainer> cpmTowerTES(m_cpmTowerLocation, ctx);
+  ATH_CHECK(cpmTowerTES.isValid());
+  
+  // Retrieve Overlap CPM Towers from SG
+  SG::ReadHandle<xAOD::CPMTowerContainer> cpmTowerOverlapTES(m_cpmTowerLocationOverlap, ctx);
+  ATH_CHECK(cpmTowerOverlapTES.isValid());
+
+  //Retrieve CPM TOB RoIs from SG
+  SG::ReadHandle<xAOD::CPMTobRoIContainer> cpmTobRoiTES(m_cpmTobRoiLocation, ctx);
+  ATH_CHECK(cpmTobRoiTES.isValid());
+
+  //Retrieve CMX-CP TOBs from SG
+  SG::ReadHandle<xAOD::CMXCPTobContainer> cmxCpTobTES(m_cmxCpTobLocation, ctx);
+  ATH_CHECK(cmxCpTobTES.isValid());
+
+  //Retrieve CMX-CP Hits from SG
+  SG::ReadHandle<xAOD::CMXCPHitsContainer> cmxCpHitsTES(m_cmxCpHitsLocation, ctx);
+  ATH_CHECK(cmxCpHitsTES.isValid());
+
+  //
+  // array of monitored items
+  std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>> variables;
+
+  // Global plots
+  // Create a vector of towers we want to monitor 
+  std::vector<MonitorTT> monTTs;
+  xAOD::TriggerTowerContainer::const_iterator ttIterator = (*triggerTowerTES).begin();
+  xAOD::TriggerTowerContainer::const_iterator ttIteratorEnd = (*triggerTowerTES).end();
+  for (; ttIterator != ttIteratorEnd; ++ttIterator) {
+    const int layer = (*ttIterator)->layer();
+    const xAOD::TriggerTower_v2* tt = *ttIterator; 
+    const double eta = (*ttIterator)->eta();
+    if ( std::abs(eta) > 2.5) continue;
+      
+    if (!tt->cpET()) continue; 
+    //check if the TriggerTower is in EM or HAD layer
+    if (layer == 0) { //EM
+      const int em = int(tt->cpET()); 
+      if (em) { 
+	MonitorTT monTT; 
+	monTT.ttower=(*ttIterator);
+	monTT.phi_scaled=(*ttIterator)->phi()*m_phiScaleTT;
+	monTTs.push_back(monTT);
+      }
+    }
+    if (layer == 1) { //HAD
+      const int had = int(tt->cpET()); 
+      if (had)  {
+	MonitorTT monTT; 
+	monTT.ttower=(*ttIterator);
+	monTT.phi_scaled=(*ttIterator)->phi()*m_phiScaleTT;
+	monTTs.push_back(monTT);
+      }
+    }      
+  } //ttIterator
+
+  // setup cutmasks to select the em and had TTs
+  auto mask_em_TT = Monitored::Collection("mask_em_TT", monTTs, []( const auto &tower ) {return ( tower.ttower->layer()==0); } );  variables.push_back( mask_em_TT );
+  auto mask_had_TT = Monitored::Collection("mask_had_TT", monTTs, []( const auto &tower ){return ( tower.ttower->layer()==1); } ); variables.push_back( mask_had_TT );
+
+  // the variables to monitor
+  auto etaTT = Monitored::Collection("etaTT", monTTs, []( const auto &tower ){return tower.ttower->eta();} );  variables.push_back( etaTT );
+  auto phiTT = Monitored::Collection("phiTT", monTTs, []( const auto &tower ){return tower.phi_scaled;} );  variables.push_back( phiTT );
+
+  // CPM Global maps
+
+  // Vectors for error overview bits;
+  std::vector<int> errorsCPM(m_crates * m_modules);
+  std::vector<int> errorsCMX(m_crates * 2); // L/R
+  //cpmTowerTES
+  std::vector<MonitorCpmTT> monCpmTTs_em;
+  std::vector<MonitorCpmTT> monCpmTTs_had;
+  bool core=true;
+  ATH_CHECK(fillCpmTowerVectors(cpmTowerTES, monCpmTTs_em, monCpmTTs_had, errorsCPM, core));
+  std::vector<MonitorCpmTT> monCpmOverlapTTs_em;
+  std::vector<MonitorCpmTT> monCpmOverlapTTs_had;
+  core=false;
+  ATH_CHECK(fillCpmTowerVectors(cpmTowerOverlapTES, monCpmOverlapTTs_em, monCpmOverlapTTs_had, errorsCPM, core));
+
+  // add the CPM global variables to be monitored - exclude Overlap
+  auto etCpmTT_em = Monitored::Collection("etCpmTT_em", monCpmTTs_em, []( const auto &tt ){return tt.ttower->emEnergy();} ); variables.push_back( etCpmTT_em );
+  auto etaCpmTT_em = Monitored::Collection("etaCpmTT_em", monCpmTTs_em, []( const auto &tt ){return tt.ttower->eta();} ); variables.push_back( etaCpmTT_em );
+  auto phiCpmTT_em = Monitored::Collection("phiCpmTT_em", monCpmTTs_em, []( const auto &tt ){return tt.ttower->phi();} ); variables.push_back( phiCpmTT_em );
+  auto phiScaledCpmTT_em = Monitored::Collection("phiScaledCpmTT_em", monCpmTTs_em, []( const auto &tt ){return tt.phi_scaled;} ); 
+  variables.push_back( phiScaledCpmTT_em );
+  auto etCpmTT_had = Monitored::Collection("etCpmTT_had", monCpmTTs_had, []( const auto &tt ){return tt.ttower->hadEnergy();} ); variables.push_back( etCpmTT_had );
+  auto etaCpmTT_had = Monitored::Collection("etaCpmTT_had", monCpmTTs_had, []( const auto &tt ){return tt.ttower->eta();} ); variables.push_back( etaCpmTT_had );
+  auto phiCpmTT_had = Monitored::Collection("phiCpmTT_had", monCpmTTs_had, []( const auto &tt ){return tt.ttower->phi();} ); variables.push_back( phiCpmTT_had );
+  auto phiScaledCpmTT_had = Monitored::Collection("phiScaledCpmTT_had", monCpmTTs_had, []( const auto &tt ){return tt.phi_scaled;} ); 
+  variables.push_back( phiScaledCpmTT_had );
+
+  // errors and slices are filled for sum of Core and Overlap
+  std::vector<MonitorCpmTT> monCpmTTs_em_tot(monCpmTTs_em.begin(),monCpmTTs_em.end());
+  monCpmTTs_em_tot.insert(monCpmTTs_em_tot.end(), monCpmOverlapTTs_em.begin(),monCpmOverlapTTs_em.end());
+  std::vector<MonitorCpmTT> monCpmTTs_had_tot(monCpmTTs_had.begin(),monCpmTTs_had.end());
+  monCpmTTs_had_tot.insert(monCpmTTs_had_tot.end(), monCpmOverlapTTs_had.begin(),monCpmOverlapTTs_had.end());
+  // the variables
+  auto etaCpmTT_em_tot = Monitored::Collection("etaCpmTT_em_tot", monCpmTTs_em_tot, []( const auto &tt ){return tt.ttower->eta();} ); 
+  variables.push_back( etaCpmTT_em_tot) ;
+  auto phiScaledCpmTT_em_tot = Monitored::Collection("phiScaledCpmTT_em_tot", monCpmTTs_em_tot, []( const auto &tt ){return tt.phi_scaled;} ); 
+  variables.push_back( phiScaledCpmTT_em_tot );
+  auto etaCpmTT_had_tot = Monitored::Collection("etaCpmTT_had_tot", monCpmTTs_had_tot, []( const auto &tt ){return tt.ttower->eta();} ); 
+  variables.push_back( etaCpmTT_had_tot) ;
+  auto phiScaledCpmTT_had_tot = Monitored::Collection("phiScaledCpmTT_had_tot", monCpmTTs_had_tot, []( const auto &tt ){return tt.phi_scaled;} ); 
+  variables.push_back( phiScaledCpmTT_had_tot );
+
+
+  // the masks
+  auto parityErrorCpmTT_em = Monitored::Collection("parityErrorCpmTT_em", monCpmTTs_em_tot, []( const auto &tt ){return tt.emParityError;} ); 
+  variables.push_back( parityErrorCpmTT_em );
+  auto linkDownErrorCpmTT_em = Monitored::Collection("linkDownErrorCpmTT_em", monCpmTTs_em_tot, []( const auto &tt ){return tt.emLinkDownError;} ); 
+  variables.push_back( linkDownErrorCpmTT_em );
+  auto parityErrorCpmTT_had = Monitored::Collection("parityErrorCpmTT_had", monCpmTTs_had_tot, []( const auto &tt ){return tt.hadParityError;} ); 
+  variables.push_back( parityErrorCpmTT_had );
+  auto linkDownErrorCpmTT_had = Monitored::Collection("linkDownErrorCpmTT_had", monCpmTTs_had_tot, []( const auto &tt ){return tt.hadLinkDownError;} ); 
+  variables.push_back( linkDownErrorCpmTT_had );
+
+  // and the sum of the Core and Overlap for EM and HAD
+  std::vector<MonitorCpmTT> monCpmTTs_tot(monCpmTTs_em_tot.begin(),monCpmTTs_em_tot.end());
+  monCpmTTs_tot.insert(monCpmTTs_tot.end(), monCpmTTs_had_tot.begin(),monCpmTTs_had_tot.end());
+
+  auto peakCpmTT_tot = Monitored::Collection("peakCpmTT_tot", monCpmTTs_tot, []( const auto &tt ){return tt.ttower->peak();} ); 
+  variables.push_back( peakCpmTT_tot );
+  auto sliceCpmTT_tot = Monitored::Collection("sliceCpmTT_tot", monCpmTTs_tot, []( const auto &tt ){return tt.slice;} ); 
+  variables.push_back( sliceCpmTT_tot );
+
+  //=============================================
+  //  CPM TOB RoIs
+  //=============================================
+
+  std::vector<MonitorTobRoI> monTobRoIsEner;
+  std::vector<MonitorTobRoI> monTobRoIsIsol;
+
+  const int vecSize = m_crates * m_modules * 2;
+  std::vector<int> tobCount(vecSize);
+  LVL1::CPRoIDecoder decoder;
+  xAOD::CPMTobRoIContainer::const_iterator crIterator    = (*cpmTobRoiTES).begin();
+  xAOD::CPMTobRoIContainer::const_iterator crIteratorEnd = (*cpmTobRoiTES).end();
+  for (; crIterator != crIteratorEnd; ++crIterator) {
+    const int type      = (*crIterator)->type();  // 0=EM, 1=Tau
+    const int energy    = (*crIterator)->energy();
+    const int isolation = (*crIterator)->isolation();
+    const LVL1::CoordinateRange coord(decoder.coordinate((*crIterator)->roiWord())); 
+    const double eta = coord.eta();
+    const double phi = coord.phi();
+    const double phiMod = phi * m_phiScaleTT - 0.5;
+    const double etaMod = eta - 0.05;
+    if (energy) {
+      MonitorTobRoI monTobRoI;
+      monTobRoI.tobroi=(*crIterator);
+      monTobRoI.etaMod=etaMod;
+      monTobRoI.phiMod=phiMod;
+      monTobRoIsEner.push_back(monTobRoI);
+    }
+    if (isolation) {
+      // have a go at isolation bits
+      int * isolbits=getIsolationBits(isolation, m_isolBits, 1);
+      bool isolationBits[4]={false}; //cannot use Gaudi::Property<int> so set size
+
+      bool isolationBitSet=false;
+      for (int thr = 0; thr < m_isolBits; ++thr) {
+	isolationBits[thr]=isolbits[thr];
+	if (isolationBits[thr])
+	  isolationBitSet=true;
+      }
+      //
+      MonitorTobRoI monTobRoI;
+      monTobRoI.tobroi=(*crIterator);
+      monTobRoI.etaMod=etaMod;
+      monTobRoI.phiMod=phiMod;
+      memcpy(monTobRoI.isolationBits, isolationBits , sizeof(isolationBits));
+      monTobRoI.isolationBitSet=isolationBitSet;
+      monTobRoIsIsol.push_back(monTobRoI);
+    }
+    const int crate = (*crIterator)->crate();
+    const int cpm   = (*crIterator)->cpm();
+    ++tobCount[(crate * m_modules + cpm - 1) * 2 + type];
+  }
+  // Energy
+  auto etaTobRoIsEner = Monitored::Collection("etaTobRoIsEner", monTobRoIsEner, []( const auto &roi ){return roi.etaMod;} ); 
+  variables.push_back(etaTobRoIsEner);
+  auto phiTobRoIsEner = Monitored::Collection("phiTobRoIsEner", monTobRoIsEner, []( const auto &roi ){return roi.phiMod;} );
+  variables.push_back(phiTobRoIsEner);
+  auto energyTobRoIsEner = Monitored::Collection("energyTobRoIsEner", monTobRoIsEner, []( const auto &roi ){return roi.tobroi->energy();} ); 
+  variables.push_back(energyTobRoIsEner);
+  auto typeTobRoIsEner = Monitored::Collection("typeTobRoIsEner", monTobRoIsEner, []( const auto &roi ){return roi.tobroi->type();} ); 
+  variables.push_back(typeTobRoIsEner);
+
+  // setup cutmasks to select EM or Tau
+  auto mask_tobroi_ener_em = Monitored::Collection("mask_tobroi_ener_em", monTobRoIsEner, []( const auto &roi ) {return ( roi.tobroi->type()==0); } );  
+  variables.push_back( mask_tobroi_ener_em );
+  auto mask_tobroi_ener_tau = Monitored::Collection("mask_tobroi_ener_tau", monTobRoIsEner, []( const auto &roi ){return ( roi.tobroi->type()==1); } ); 
+  variables.push_back( mask_tobroi_ener_tau );
+
+  // Isol
+  auto etaTobRoIsIsol = Monitored::Collection("etaTobRoIsIsol", monTobRoIsIsol, []( const auto &roi ){return roi.etaMod;} ); 
+  variables.push_back(etaTobRoIsIsol);
+  auto phiTobRoIsIsol = Monitored::Collection("phiTobRoIsIsol", monTobRoIsIsol, []( const auto &roi ){return roi.phiMod;} );
+  variables.push_back(phiTobRoIsIsol);
+  auto energyTobRoIsIsol = Monitored::Collection("energyTobRoIsIsol", monTobRoIsIsol, []( const auto &roi ){return roi.tobroi->isolation();} ); 
+  variables.push_back(energyTobRoIsIsol);
+
+  auto mask_tobroi_isol_em = Monitored::Collection("mask_tobroi_isol_em", monTobRoIsIsol, []( const auto &roi ) {return ( roi.tobroi->type()==0); } );  
+  variables.push_back( mask_tobroi_isol_em );
+  auto mask_tobroi_isol_tau = Monitored::Collection("mask_tobroi_isol_tau", monTobRoIsIsol, []( const auto &roi ){return ( roi.tobroi->type()==1); } ); 
+  variables.push_back( mask_tobroi_isol_tau );
+
+
+  // count ToBs
+  std::vector<int> tobCountEm;
+  std::vector<int> tobCountTau;
+  for (int crate = 0; crate < m_crates; ++crate) {
+    for (int cpm = 1; cpm <= m_modules; ++cpm) {
+      for (int type = 0; type < 2; ++type) {
+	int val = tobCount[(crate * m_modules + cpm - 1) * 2 + type];
+	if (val) {
+	  if (val > m_tobsPerCPM) val = m_tobsPerCPM + 1;
+	  if (type == 0) {
+	    tobCountEm.push_back(val);
+	  } else {
+	    tobCountTau.push_back(val);
+	  }
+	}
+      }
+    }
+  }
+  auto tobEm = Monitored::Collection("tobPerCPMEm", tobCountEm, []( const auto &tob ){return tob;} );  variables.push_back( tobEm );
+  auto tobTau = Monitored::Collection("tobPerCPMTau", tobCountTau, []( const auto &tob ){return tob;} );  variables.push_back( tobTau );
+
+
+  //=============================================
+  //  CMX-CP TOBs
+  //=============================================
+
+  std::vector<MonitorCmxCpTob> monCmxCpTobEner;
+  std::vector<MonitorCmxCpTob> monCmxCpTobIsol;
+  std::vector<MonitorCmxCpTob> monCmxCpTobError;
+
+  tobCount.assign(vecSize, 0);
+  std::vector<int> cmxCount(m_crates * 2);
+  xAOD::CMXCPTobContainer::const_iterator cmxCpTobIter    = (*cmxCpTobTES).begin();
+  xAOD::CMXCPTobContainer::const_iterator cmxCpTobIterEnd = (*cmxCpTobTES).end();
+  for (; cmxCpTobIter != cmxCpTobIterEnd; ++cmxCpTobIter) {
+    const uint8_t crate     = (*cmxCpTobIter)->crate();
+    const uint8_t cpm       = (*cmxCpTobIter)->cpm();     // 1-14
+    const uint8_t cmx       = (*cmxCpTobIter)->cmx();     // 0=Left, 1=Right  (Assumed in Sim to be Left Tau, Right EM)
+    const uint8_t chip      = (*cmxCpTobIter)->chip();    // 4 bits
+    const uint8_t location  = (*cmxCpTobIter)->location();// 2 bits
+    const uint8_t energy    = (*cmxCpTobIter)->energy();
+    const uint8_t isolation = (*cmxCpTobIter)->isolation();
+    const uint32_t error     = (*cmxCpTobIter)->error();
+    const uint8_t x = crate * m_modules + cpm - 1;
+    const uint8_t y = chip * 4 + location;
+    if (energy) {
+      MonitorCmxCpTob monCmxCpTob;
+      monCmxCpTob.tob=(*cmxCpTobIter);
+      monCmxCpTob.x=x;
+      monCmxCpTob.y=y;
+      monCmxCpTobEner.push_back(monCmxCpTob);
+
+    }
+    if (isolation) {
+      MonitorCmxCpTob monCmxCpTob;
+      monCmxCpTob.tob=(*cmxCpTobIter);
+      monCmxCpTob.x=x;
+      monCmxCpTob.y=y;
+      monCmxCpTobIsol.push_back(monCmxCpTob);
+    }
+    if (error) {
+      const LVL1::DataError err(error);
+      if (err.get(LVL1::DataError::Overflow)) {
+	tobCount[x * 2 + cmx] = m_tobsPerCPM + 1;
+      }
+      const int ybase = cmx * 5;
+      bool parity = false;
+      if (err.get(LVL1::DataError::ParityMerge)) {
+	parity = true;
+      }
+      if (err.get(LVL1::DataError::ParityPhase0)) {
+	parity = true;
+      }
+      if (err.get(LVL1::DataError::ParityPhase1)) {
+	parity = true;
+      }
+      if (err.get(LVL1::DataError::ParityPhase2)) {
+	parity = true;
+      }
+      if (err.get(LVL1::DataError::ParityPhase3)) {
+	parity = true;
+      }
+      if (parity) errorsCMX[crate * 2 + cmx] |= (1 << TOBParity);
+
+      MonitorCmxCpTob monCmxCpTob;
+      monCmxCpTob.tob=(*cmxCpTobIter);
+      monCmxCpTob.x=x;
+      monCmxCpTob.ybase=ybase;
+      monCmxCpTobEner.push_back(monCmxCpTob);
+    }
+    if (energy || isolation || error) {
+      ++tobCount[x * 2 + cmx];
+      ++cmxCount[crate * 2 + cmx];
+    }
+  }
+  
+
+  fill(m_packageName,variables);
+  variables.clear();
+  return StatusCode::SUCCESS;
+}
+
+
+int* CpmMonitorAlgorithm::getIsolationBits(int val, int nThresh, int nBits, int offset) const
+{
+  // return array of threshold bits
+  // 
+  static int nthres[20]={0};
+  for (int thr = 0; thr < 20; ++thr) {
+    nthres[thr]=0;
+  }
+  if (val) {
+    const int mask = (1 << nBits) - 1;
+    for (int thr = 0; thr < nThresh; ++thr) {
+      const int hit = (val >> (nBits*thr)) & mask;
+      if (hit) {
+	nthres[thr+offset]=hit;
+      }  
+    }
+  } else {
+    ATH_MSG_WARNING("getIsolationBits: no input word supplied" ); 
+  }
+  return nthres;
+
+}
+
+StatusCode CpmMonitorAlgorithm::fillCpmTowerVectors(SG::ReadHandle<xAOD::CPMTowerContainer> &cpmTower,
+						    std::vector<MonitorCpmTT> &monCpmTTs_em, std::vector<MonitorCpmTT> &monCpmTTs_had,
+						    std::vector<int> &errorsCPM,
+						    bool core
+						    ) const
+{
+  //   
+  xAOD::CPMTowerContainer::const_iterator ctIterator    = (*cpmTower).begin();
+  xAOD::CPMTowerContainer::const_iterator ctIteratorEnd = (*cpmTower).end();      
+  for (; ctIterator != ctIteratorEnd; ++ctIterator) {
+    const xAOD::CPMTower* ct = *ctIterator;
+    const uint8_t    em  = ct->emEnergy();
+    const uint8_t    had = ct->hadEnergy();
+    const double eta = ct->eta();
+    const double phi = ct->phi();
+    const LVL1::Coordinate coord(phi, eta);
+    LVL1::CoordToHardware converter;
+    const int crate  = (core) ? converter.cpCrate(coord)
+      : converter.cpCrateOverlap(coord);
+    const int cpm    = (core) ? converter.cpModule(coord)
+      : converter.cpModuleOverlap(coord);
+    const int loc    = crate * m_modules + cpm - 1;
+    const int slices = (ct->emEnergyVec()).size();
+    const int slice = crate * m_maxSlices + slices - 1;
+    if (crate==999) {
+      ATH_MSG_DEBUG("Crate number is 999, "<< crate << " eta " << eta << " phi " << phi <<       
+ 		    " cpm " << cpm << " slices " << slices <<
+		    " max slices " << m_maxSlices << " m_modules " << m_modules <<
+		    " slice " << slice);
+    }
+
+    // Errors    
+    bool emParityError=true;
+    bool emLinkDownError=true;
+    bool emGLinkParityError[8]={false};
+    uint32_t error = ct->emError(); // uint8_t
+    if (error) {
+      const LVL1::DataError emError(error);
+      if (emError.get(LVL1::DataError::Parity)) {
+	emParityError=true;
+        errorsCPM[loc] |= (1 << EMParity);
+      }
+      if (emError.get(LVL1::DataError::LinkDown)) {
+	emLinkDownError=true;
+        errorsCPM[loc] |= (1 << EMLink);
+      }
+      const int status = (error >> LVL1::DataError::GLinkParity) & 0xff;
+      if (status) {
+        for (int bit = 0; bit < 8; ++bit) {
+          if ((status >> bit) & 0x1) emGLinkParityError[bit]=true; 
+        }
+        errorsCPM[loc] |= (1 << CPMStatus);
+      }
+    }
+
+    bool hadParityError=true;
+    bool hadLinkDownError=true;
+    error = ct->hadError();
+    if (error) {
+      const LVL1::DataError hadError(error);
+      if (hadError.get(LVL1::DataError::Parity)) {
+	hadParityError=true;
+        errorsCPM[loc] |= (1 << HadParity);
+      }
+      if (hadError.get(LVL1::DataError::LinkDown)) {
+	hadLinkDownError=true;
+        errorsCPM[loc] |= (1 << HadLink);
+      }
+    }
+    // fill tower vector for plots
+    MonitorCpmTT monTT; 
+    monTT.ttower=ct;
+    monTT.phi_scaled=ct->phi()*m_phiScaleTT;
+    monTT.slice=slice;
+    monTT.emParityError=emParityError;
+    monTT.emLinkDownError=emLinkDownError;
+    memcpy(monTT.emGLinkParityError, emGLinkParityError, sizeof(emGLinkParityError));
+    monTT.hadParityError=hadParityError;
+    monTT.hadLinkDownError=hadLinkDownError;
+    if (em) {
+      monCpmTTs_em.push_back(monTT);
+    }
+    if (had) {
+      monCpmTTs_had.push_back(monTT);
+    }
+
+  } // iterator
+
+
+  return StatusCode::SUCCESS;
+}
+
+
diff --git a/Trigger/TrigT1/TrigT1CaloMonitoring/src/CpmMonitorAlgorithm.h b/Trigger/TrigT1/TrigT1CaloMonitoring/src/CpmMonitorAlgorithm.h
new file mode 100644
index 0000000000000000000000000000000000000000..42033d2e5c41df3bb4413679d5de515fe0a412a6
--- /dev/null
+++ b/Trigger/TrigT1/TrigT1CaloMonitoring/src/CpmMonitorAlgorithm.h
@@ -0,0 +1,110 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+#ifndef TRIGT1CALOMONITORING_CPMMONITORALGORITHM_H
+#define TRIGT1CALOMONITORING_CPMMONITORALGORITHM_H
+
+#include "AthenaMonitoring/AthMonitorAlgorithm.h"
+#include "AthenaMonitoringKernel/Monitored.h"
+#include "StoreGate/ReadHandleKey.h"
+#include "xAODTrigL1Calo/CPMTowerContainer.h" 
+#include "xAODTrigL1Calo/CPMTobRoIContainer.h"
+#include "xAODTrigL1Calo/CMXCPTobContainer.h"
+#include "xAODTrigL1Calo/CMXCPHitsContainer.h"
+#include "TrigT1Interfaces/TrigT1CaloDefs.h"
+
+
+class CpmMonitorAlgorithm : public AthMonitorAlgorithm {
+ public:CpmMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator );
+  virtual ~CpmMonitorAlgorithm()=default;
+  virtual StatusCode initialize() override;
+  virtual StatusCode fillHistograms( const EventContext& ctx ) const override;
+
+  // monitoring trigger tower structs for various towers
+  struct MonitorTT{
+    const xAOD::TriggerTower_v2* ttower;
+    double phi_scaled; // rescaled for 2D plots
+  };
+  struct MonitorCpmTT{
+    const xAOD::CPMTower_v2* ttower;
+    // some modified/derived information 
+    double phi_scaled; // rescaled for 2D plots
+    int slice; // crate * m_maxSlices + emEnergyVec()).size() - 1;
+    // errors
+    bool emParityError;
+    bool emLinkDownError;
+    bool emGLinkParityError[8]; 
+    bool hadParityError;
+    bool hadLinkDownError;   
+  };
+
+  struct MonitorTobRoI{
+    const xAOD::CPMTobRoI_v1* tobroi;
+    //xAOD::CPMTower_v2
+    // some modified/derived information 
+    double etaMod; 
+    double phiMod; 
+    bool isolationBits[4]; 
+    bool isolationBitSet; // set to true if at least one bit set 
+  };
+
+
+  struct MonitorCmxCpTob{
+    const xAOD::CMXCPTob_v1* tob;
+    // some modified/derived information 
+    uint8_t x; // crate * m_modules + cpm - 1;
+    uint8_t y; // chip * 4 + location;
+    int ybase; // cmx * 5;
+  };
+
+
+
+
+private:
+
+  // Phi scale for trigger tower eta/phi plots
+  double m_phiScaleTT;
+  // Phi scale for jet element eta/phi plots
+  double m_phiScaleJE;
+
+  StringProperty m_packageName{this,"PackageName","CpmMonitor","group name for histograming"};
+
+  // The following enums are set in the python in order to get consistent histogram bins
+  // only add here if they are used in the .cxx
+  Gaudi::Property<int> m_crates{this,"s_crates", 4,  "Number of CPM crates"};
+  Gaudi::Property<int> m_modules{this,"s_modules", 14, "Number of modules per crate (modules numbered 1-14)"};
+  Gaudi::Property<int> m_maxSlices{this,"s_maxSlices", 5,  "Maximum number of slices"};
+  Gaudi::Property<int> m_tobsPerCPM{this,"s_tobsPerCPM", 5,  "Maximum number of TOBs per CPM sent to CMX"};
+  Gaudi::Property<int> m_isolBits{this,"s_isolBits", 4,  "Number of bits for encoded isolation"};
+  // see fillXVsThresholds
+  Gaudi::Property<int> m_threshBits{this,"s_threshBits", 3,  "Number of bits per threshold for hit sums"};
+  Gaudi::Property<int> m_thresholds{this,"s_thresholds", 16, "Number of EM/Tau threshold bits"};
+
+  // previously declared in .cxx
+  Gaudi::Property<int> m_maxTobsPerCmx{this,"MaxTOBsPerCMX", 70,  "Maximum number of TOBs per CMX plotted"};
+
+  /// Error summary plot bins
+  enum SummaryErrors { EMParity, EMLink, HadParity, HadLink, CPMStatus,
+                       TOBParity, SumParity, CMXStatus, NumberOfSummaryBins };
+
+
+  // container keys including steering parameter and description
+  SG::ReadHandleKey<xAOD::TriggerTowerContainer> m_xAODTriggerTowerContainerName{this, "BS_xAODTriggerTowerContainer",LVL1::TrigT1CaloDefs::xAODTriggerTowerLocation,"Trigger Tower Container"};
+  SG::ReadHandleKey<xAOD::CPMTowerContainer> m_cpmTowerLocation{this, "CPMTowerLocation", LVL1::TrigT1CaloDefs::CPMTowerLocation, "CPM container"};
+  SG::ReadHandleKey<xAOD::CPMTowerContainer> m_cpmTowerLocationOverlap{this, "CPMTowerLocationOverlap",LVL1::TrigT1CaloDefs::CPMTowerLocation + "Overlap", "CPM Overlap container"};
+  SG::ReadHandleKey<xAOD::CPMTobRoIContainer> m_cpmTobRoiLocation{this, "CPMTobRoILocation", LVL1::TrigT1CaloDefs::CPMTobRoILocation, "CPMTobRoI container"};
+  SG::ReadHandleKey<xAOD::CMXCPTobContainer> m_cmxCpTobLocation{this, "CMXCPTobLocation", LVL1::TrigT1CaloDefs::CMXCPTobLocation, "CMXCPTob container"};
+  SG::ReadHandleKey<xAOD::CMXCPHitsContainer> m_cmxCpHitsLocation{this, "CMXCPHitsLocation", LVL1::TrigT1CaloDefs::CMXCPHitsLocation, "CMXCPHits container"};
+
+  int * getIsolationBits(int val, int nThresh, int nBits, int offset=0) const;
+
+
+  StatusCode fillCpmTowerVectors(SG::ReadHandle<xAOD::CPMTowerContainer> &cpmTower,
+				 std::vector<MonitorCpmTT> &monCpmTTs_em, std::vector<MonitorCpmTT> &monCpmTTs_had,
+				 std::vector<int> &errorsCPM, 
+				 bool core
+				 ) const;
+
+
+};
+#endif
diff --git a/Trigger/TrigT1/TrigT1CaloMonitoring/src/components/TrigT1CaloMonitoring_entries.cxx b/Trigger/TrigT1/TrigT1CaloMonitoring/src/components/TrigT1CaloMonitoring_entries.cxx
index 6656b9ccd8da4327c88604be8fc2af55042316de..22a5bd4ca7d188b0dd987abf1bad225ba17b6bfd 100644
--- a/Trigger/TrigT1/TrigT1CaloMonitoring/src/components/TrigT1CaloMonitoring_entries.cxx
+++ b/Trigger/TrigT1/TrigT1CaloMonitoring/src/components/TrigT1CaloMonitoring_entries.cxx
@@ -1,3 +1,12 @@
+// Run 3
+#include "../CpmMonitorAlgorithm.h"
+//#include "../CpmSimMonitorAlgorithm.h"
+//#include "../PpmSimBsMonitorAlgorithm.h"
+//#include "../PprMonitorAlgorithm.h"
+//#include "../PprSpareMonitorAlgorithm.h"
+//#include "../PprStabilityMonitorAlgorithm.h"
+
+// Run 2
 #include "../CPMon.h"
 #include "../CPSimMon.h"
 #include "../JEPJEMMon.h"
@@ -24,7 +33,15 @@
 #include "../JetEfficienciesMonTool.h"
 #include "../RODMonV1.h"
 
+// Run 3
+DECLARE_COMPONENT( CpmMonitorAlgorithm )
+//DECLARE_COMPONENT( CpmSimMonitorAlgorithm )
+//DECLARE_COMPONENT( PpmSimBsMonitorAlgorithm )
+//DECLARE_COMPONENT( PprMonitorAlgorithm )
+//DECLARE_COMPONENT( PprSpareMonitorAlgorithm )
+//DECLARE_COMPONENT( PprStabilityMonitorAlgorithm )
 
+// Run 2
 DECLARE_COMPONENT( LVL1::OverviewMon )
 DECLARE_COMPONENT( LVL1::CPMon )
 DECLARE_COMPONENT( LVL1::CPSimMon )
diff --git a/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloL1TopoMon.cxx b/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloL1TopoMon.cxx
index 8f0e33e0f6f085bb5852084e026b15d7f074a06a..b22d1b883e05c8e92c54961e80de7a256eb20439 100755
--- a/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloL1TopoMon.cxx
+++ b/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloL1TopoMon.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include <map>
@@ -431,7 +431,7 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
     topo_error|=(1<<CALO_CONV);
   }
 
-  const DataHandle<CTP_RDO> ctpRDO = 0;
+  const CTP_RDO* ctpRDO = 0;
   sc = evtStore()->retrieve(ctpRDO,"CTP_RDO");
   if (sc.isFailure()) {
     ATH_MSG_WARNING("Could not find CTP_RDO in StoreGate");
@@ -467,7 +467,7 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
   }
   
   // Retrieve CMX CP tobs
-  const DataHandle<xAOD::CMXCPTobContainer> cmxcptob = 0;
+  const xAOD::CMXCPTobContainer* cmxcptob = 0;
   sc = evtStore()->retrieve(cmxcptob);
   if (sc.isFailure() || !cmxcptob) {
     ATH_MSG_DEBUG ("No CMX CP tobs found in TES");
@@ -494,7 +494,7 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
   
   std::vector<const xAOD::CMXJetTob*> cmxtobs;  
   // Retrieve CMX jet tobs
-  const DataHandle<xAOD::CMXJetTobContainer> cmxtob = 0;
+  const xAOD::CMXJetTobContainer* cmxtob = 0;
   sc = evtStore()->retrieve(cmxtob);
   if (sc.isFailure() || !cmxtob) {
     ATH_MSG_DEBUG ("No CMX tobs found in TES");
@@ -525,7 +525,7 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
 		  << m_topoCTPLoc.value());
   }
   else {
-    const DataHandle< LVL1::FrontPanelCTP > topoCTP;
+    const LVL1::FrontPanelCTP* topoCTP = nullptr;
     CHECK_RECOVERABLE(evtStore()->retrieve(topoCTP,m_topoCTPLoc.value()));
     if (!topoCTP){
       ATH_MSG_INFO( "Retrieve of LVL1::FrontPanelCTP failed." );
@@ -566,7 +566,7 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
 
   // Retrieve the L1Topo RDOs from the DAQ RODs
   const int NFPGA=4;
-  const DataHandle<L1TopoRDOCollection> rdos = 0;
+  const L1TopoRDOCollection* rdos = 0;
   sc = evtStore()->retrieve(rdos);
   if (sc.isFailure() or 0 == rdos) {
     m_h_l1topo_1d_Errors->Fill(NO_DAQ);
diff --git a/Trigger/TrigTools/TrigInDetConfig/python/TrigInDetConfig.py b/Trigger/TrigTools/TrigInDetConfig/python/TrigInDetConfig.py
index 21b0c07f878f2cd884fff2546317de7b8ca36bfb..a5fceef394520721819ea69a3afc09cb18d09a82 100644
--- a/Trigger/TrigTools/TrigInDetConfig/python/TrigInDetConfig.py
+++ b/Trigger/TrigTools/TrigInDetConfig/python/TrigInDetConfig.py
@@ -417,8 +417,8 @@ if __name__ == "__main__":
     l1DecoderAcc, l1DecoderAlg = L1DecoderCfg( ConfigFlags )
     acc.addEventAlgo(l1DecoderAlg)
     acc.merge(l1DecoderAcc)
-    from ByteStreamCnvSvc.ByteStreamConfig import TrigBSReadCfg
-    acc.merge(TrigBSReadCfg(ConfigFlags))
+    from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
+    acc.merge(ByteStreamReadCfg(ConfigFlags))
 
     acc.merge( TrigInDetConfig( ConfigFlags ) )
     from RegionSelector.RegSelConfig import regSelCfg
diff --git a/Trigger/TrigTools/TrigOnlineSpacePointTool/src/SpacePointConversionUtils.h b/Trigger/TrigTools/TrigOnlineSpacePointTool/src/SpacePointConversionUtils.h
index f667fa9035ada02593ff6cfd6507cfc2e266a43e..2b5ba4897bb6d8d6bf3f30034e0a8c512e0c9ed6 100644
--- a/Trigger/TrigTools/TrigOnlineSpacePointTool/src/SpacePointConversionUtils.h
+++ b/Trigger/TrigTools/TrigOnlineSpacePointTool/src/SpacePointConversionUtils.h
@@ -146,15 +146,15 @@ namespace FTF {//FastTrackFinder
     void operator() (const IdentifierHash& id) {
 
       if (m_pIDC) {
-        SpacePointContainer::const_iterator collIt = m_pIDC->indexFind(id);
-        if(collIt!=m_pIDC->end()) {
-          if(m_hash2layer ==  nullptr) m_filter.setLayer((*collIt)->identify());
+        auto collIt = m_pIDC->indexFindPtr(id);
+        if(collIt!=nullptr) {
+          if(m_hash2layer ==  nullptr) m_filter.setLayer(collIt->identify());
 	  else {
-	    int layerId = m_hash2layer->at((int)(*collIt)->identifyHash());
+	    int layerId = m_hash2layer->at((int)collIt->identifyHash());
 	    if(layerId<0) return;
-	    m_filter.setLayer(layerId,(*collIt)->identify());
+	    m_filter.setLayer(layerId,collIt->identify());
 	  }
-          std::for_each((*collIt)->begin(),(*collIt)->end(),m_filter);
+          std::for_each(collIt->begin(),collIt->end(),m_filter);
         }
       }
     }
diff --git a/Trigger/TrigTools/TrigOnlineSpacePointTool/src/TrigSpacePointConversionTool.cxx b/Trigger/TrigTools/TrigOnlineSpacePointTool/src/TrigSpacePointConversionTool.cxx
index 6217d130fd8ed4b755625cbc721b366053e3a0b4..aefb54809a0679ba70330baed16593d7c8e9faa5 100644
--- a/Trigger/TrigTools/TrigOnlineSpacePointTool/src/TrigSpacePointConversionTool.cxx
+++ b/Trigger/TrigTools/TrigOnlineSpacePointTool/src/TrigSpacePointConversionTool.cxx
@@ -13,7 +13,6 @@
 #include "TrigInDetToolInterfaces/ITrigL2LayerNumberTool.h"
 
 #include "SpacePointConversionUtils.h"
-#include "IRegionSelector/IRegSelSvc.h"
 
 #include "IRegionSelector/IRegSelTool.h"
 
diff --git a/Trigger/TrigTools/TrigOnlineSpacePointTool/src/TrigSpacePointConversionTool.h b/Trigger/TrigTools/TrigOnlineSpacePointTool/src/TrigSpacePointConversionTool.h
index 26b3e6e7da0bf99cdde58469217d85a6b1b8f6b9..284bf60acc22c8b876c6f612496af444d471cc03 100644
--- a/Trigger/TrigTools/TrigOnlineSpacePointTool/src/TrigSpacePointConversionTool.h
+++ b/Trigger/TrigTools/TrigOnlineSpacePointTool/src/TrigSpacePointConversionTool.h
@@ -21,7 +21,6 @@
 class AtlasDetectorID;
 class SCT_ID;
 class PixelID;
-class IRegSelSvc;
 
 
 class ITrigL2LayerNumberTool;
@@ -49,9 +48,6 @@ class TrigSpacePointConversionTool : virtual public ITrigSpacePointConversionToo
   const SCT_ID*  m_sctId;
   const PixelID* m_pixelId;
 
-  //  std::string    m_regionSelectorName;
-  //  IRegSelSvc*    m_regionSelector;
-
   SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey { this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot" };
 
   std::string m_pixelSpContName,m_sctSpContName;// offline/EF containers
diff --git a/Trigger/TrigValidation/TrigInDetValidation/CMakeLists.txt b/Trigger/TrigValidation/TrigInDetValidation/CMakeLists.txt
index 6032f1506bd86b840ea50134eb3c26d2bcc47515..7905b91e9b90b33d783f8d3a4d3517988eae1e19 100644
--- a/Trigger/TrigValidation/TrigInDetValidation/CMakeLists.txt
+++ b/Trigger/TrigValidation/TrigInDetValidation/CMakeLists.txt
@@ -13,4 +13,10 @@ atlas_install_python_modules( python/*.py )
 atlas_install_joboptions( share/TrigInDetValidation_RTT_*.py )
 atlas_install_runtime( test/TrigInDetValidation_TestConfiguration.xml share/TrigInDetValidation_RTT_*.py TIDAbuild )
 
-atlas_install_scripts( scripts/TIDA*.py )
+atlas_install_scripts( scripts/TIDA*.py test/test*.py POST_BUILD_CMD ${ATLAS_FLAKE8} --extend-ignore=ATL902 )
+
+# Unit test for python test scripts:
+atlas_add_test( TrigValSteeringUT
+                SCRIPT trigvalsteering-unit-tester.py ${CMAKE_CURRENT_SOURCE_DIR}/test
+                PROPERTIES TIMEOUT 300
+                POST_EXEC_SCRIPT nopost.sh )
diff --git a/Trigger/TrigValidation/TrigInDetValidation/scripts/TIDAdataset.py b/Trigger/TrigValidation/TrigInDetValidation/scripts/TIDAdataset.py
index 84880e6f76973c8cb1a82356267d93c603256e4e..9e15e1ec9c48c20bf192af45b9768b36652030cb 100755
--- a/Trigger/TrigValidation/TrigInDetValidation/scripts/TIDAdataset.py
+++ b/Trigger/TrigValidation/TrigInDetValidation/scripts/TIDAdataset.py
@@ -1,5 +1,7 @@
 #!/bin/env python
 
+from __future__ import print_function
+
 #Import datasets from RTT--------------------------------------------------------------------------                                                   
 def importRTTdatasets(jobID):
     from AthenaCommon.Utils.unixtools import find_datafile
@@ -20,7 +22,7 @@ def importRTTdatasets(jobID):
 def main(argv):
     for x in argv[1:]:
         for ds in importRTTdatasets( x ):
-            print ds
+            print (ds)
 
 if __name__ == "__main__":
     import sys
diff --git a/Trigger/TrigValidation/TrigInDetValidation/test/test_trigID_mu_zmumu_ibl_pu40.py b/Trigger/TrigValidation/TrigInDetValidation/test/test_trigID_mu_zmumu_ibl_pu40.py
new file mode 100755
index 0000000000000000000000000000000000000000..8ea0f6fbf893dbc645b15ccdbd8eb75c5360ea59
--- /dev/null
+++ b/Trigger/TrigValidation/TrigInDetValidation/test/test_trigID_mu_zmumu_ibl_pu40.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+
+# art-description: art job for mu_Zmumu_IBL_pu40
+# art-type: grid
+# art-include: master/Athena
+# art-input: mc15_13TeV.361107.PowhegPythia8EvtGen_AZNLOCTEQ6L1_Zmumu.recon.RDO.e3601_s2576_s2132_r7143
+# art-input-nfiles: 4
+# art-athena-mt: 4
+# art-output: *.txt
+# art-output: *.log
+# art-output: log.*
+# art-output: *.out
+# art-output: *.err
+# art-output: *.log.tar.gz
+# art-output: *.new
+# art-output: *.json
+# art-output: *.root
+# art-output: *.check*
+
+from TrigValTools.TrigValSteering import Test, ExecStep, CheckSteps
+
+chains = [
+    'HLT_mu6_idperf_L1MU6',
+    'HLT_mu24_idperf_L1MU20'
+]
+
+preexec_trig = ';'.join([
+    'doEmptyMenu=True',
+    'doMuonSlice=True',
+    'selectChains='+str(chains)
+])
+
+preexec_reco = ';'.join([
+    'pass' # TODO: figure out a working set of options to disable parts of reco
+    # 'from RecExConfig.RecFlags import rec',
+    # 'rec.doForwardDet=False',
+    # 'rec.doEgamma=False',
+    # 'rec.doMuonCombined=False',
+    # 'rec.doJetMissingETTag=False',
+    # 'rec.doTau=False'
+])
+
+preexec_all = ';'.join([
+    'from TriggerJobOpts.TriggerFlags import TriggerFlags',
+    'TriggerFlags.AODEDMSet.set_Value_and_Lock(\\\"AODFULL\\\")',
+])
+
+rdo2aod = ExecStep.ExecStep()
+rdo2aod.type = 'Reco_tf'
+rdo2aod.input = ''  # specified in inputRDOFile below
+rdo2aod.max_events = 100 # TODO: 2000 events
+rdo2aod.threads = 1 # TODO: change to 4
+rdo2aod.concurrent_events = 1 # TODO: change to 4
+rdo2aod.perfmon = False
+rdo2aod.args = '--inputRDOFile=$ArtInFile --outputAODFile=AOD.pool.root --steering="doRDO_TRIG"'
+rdo2aod.args += ' --preExec "RDOtoRDOTrigger:{:s};" "all:{:s};" "RAWtoESD:{:s};" "ESDtoAOD:{:s};"'.format(
+    preexec_trig, preexec_all, preexec_reco, preexec_reco)
+
+test = Test.Test()
+test.art_type = 'grid'
+test.exec_steps = [rdo2aod]
+test.check_steps = CheckSteps.default_check_steps(test)
+
+import sys
+sys.exit(test.run())
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/python/EmuStepProcessingConfig.py b/Trigger/TrigValidation/TrigUpgradeTest/python/EmuStepProcessingConfig.py
index ca8ad18a78a5f543c180332a3ce2579467fc0f98..4788082778a704eabef42d44a5b50a705b641c97 100644
--- a/Trigger/TrigValidation/TrigUpgradeTest/python/EmuStepProcessingConfig.py
+++ b/Trigger/TrigValidation/TrigUpgradeTest/python/EmuStepProcessingConfig.py
@@ -1,6 +1,5 @@
 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-# Configure the scheduler
 from AthenaCommon.AlgScheduler import AlgScheduler
 from AthenaCommon.CFElements import parOR
 from AthenaCommon.Logging import logging
@@ -8,7 +7,7 @@ from L1Decoder.L1DecoderConf import CTPUnpackingEmulationTool, RoIsUnpackingEmul
 from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import EmptyMenuSequence
 log = logging.getLogger('EmuStepProcessingConfig')
 
-
+###########################################################################    
 def thresholdToChains( chains ):
     """
     Produces list "threshod : chain" for all chains passed. Uses the L1Thresholds/vseeds Chain property
@@ -18,9 +17,56 @@ def thresholdToChains( chains ):
         for t in c.vseeds:
             ret.append(t+ " : " + c.name)
     return ret
-            
 
-def generateL1DecoderAndChains():
+###########################################################################    
+def generateL1DecoderAndChainsManually(topSequence):
+    generateEmuEvents()
+    l1Decoder = generateL1Decoder()
+    topSequence += l1Decoder
+    generateChainsManually()
+    from TriggerMenuMT.HLTMenuConfig.Menu.HLTCFConfig import makeHLTTree
+    from TriggerMenuMT.HLTMenuConfig.Menu.TriggerConfigHLT import TriggerConfigHLT
+    makeHLTTree( triggerConfigHLT=TriggerConfigHLT )
+
+
+###########################################################################    
+def generateL1DecoderAndChainsByMenu(topSequence):
+    generateEmuEvents()
+    l1Decoder = generateL1Decoder()
+    topSequence += l1Decoder
+    generateEmuMenu()
+
+
+
+###########################################################################    
+def generateEmuMenu():    
+    from TriggerMenuMT.HLTMenuConfig.Menu import LS2_v1
+    from TriggerMenuMT.HLTMenuConfig.Menu import LS2_emu_v1 
+    from TriggerMenuMT.HLTMenuConfig.Menu.GenerateMenuMT import GenerateMenuMT
+    from TriggerJobOpts.TriggerFlags import TriggerFlags
+    from AthenaCommon.Logging import logging
+    log = logging.getLogger('EmuMenuTest')
+    log.debug("generateEmuMenu")
+
+    # overwrite LS2_v1 menu
+    TriggerFlags.triggerMenuSetup = 'LS2_v1'
+    LS2_v1.setupMenu = LS2_emu_v1.setupMenu
+
+    # switch on only TestSlice
+    def signaturesToGenerate():
+        TriggerFlags.Slices_all_setOff()
+        TriggerFlags.TestSlice.setAll()
+        #TriggerFlags.EgammaSlice.setAll()
+
+    # Generate the menu    
+    menu = GenerateMenuMT()
+    menu.overwriteSignaturesWith(signaturesToGenerate)    
+    menu.generateMT()
+
+
+
+###########################################################################    
+def generateEmuEvents():
     AlgScheduler.ShowControlFlow( True )
     AlgScheduler.ShowDataFlow( True )
 
@@ -34,34 +80,60 @@ def generateL1DecoderAndChains():
         'l1muroi': [';', ';', ';',';']
         }  # in the lists there are the events
 
-
-    
     # event 0: empty
-    data['ctp'] [0]      =  'HLT_e20_L1EM10 HLT_e5_e8_L1EM3_EM5 HLT_e5_L1EM3 HLT_e8_L1EM5 HLT_g5_EM7'
+    data['ctp'] [0]      =  'HLT_TestChain5_ev1_L1EM3 \
+                             HLT_TestChain8_ev1_L1EM5 \
+                             HLT_g5_EM7'
     data['l1emroi'][0]   = ';'
     data['emclusters'][0]= ';'
     data['l1muroi'][0]   = ';'
     data['msmu'][0]      = ';'
 
 
-    #event 1: 3e (1 not passing at L1, 1 not passing at step1) + 2mu (2 not passing) - HLT_e5_e8_L1EM3_EM5 HLT_2mu6_L12MU6
-    data['ctp'] [1]      =  'HLT_e20_L1EM10 HLT_e5_L1EM3 HLT_e8_L1EM5 HLT_g5_L1EM7 HLT_e5_v3_L1EM7 HLT_e5_e8_L1EM3_EM5 HLT_mu8_e8_L1MU6_EM7 HLT_2mu6_L12MU6 HLT_mu6_mu10_L12MU6 HLT_2mu4_bDimu_L12MU6'
+    #event 1: 3e (1 not passing at L1, 1 not passing at step1) + 2mu (2 not passing) - HLT_e5_e8_L12EM3 HLT_2TestChain6_muv1_L12MU6
+    data['ctp'] [1]      =  'HLT_TestChain5_ev1_L1EM3 \
+                             HLT_TestChain8_ev1_L1EM5 \
+                             HLT_TestChain5_gv1_L1EM7 \
+                             HLT_TestChain5_ev3_L1EM7 \
+                             HLT_2TestChain6_muv1_L12MU6 \
+                             HLT_TestChain10_muv2_L1MU10 \
+                             HLT_TestChain6_muv1_TestChain10_muv1_L12MU6 \
+                             HLT_2TestChain4_muv1_dr_L12MU6'
     data['l1emroi'][1]   =  '1,1,0,EM3,EM5,EM7,EM20,EM50,EM100; 2.,-1.2,0,EM3,EM5,EM7; 3.,0.2,0,EM3;'
     data['emclusters'][1]=  'eta:1,phi:1,et:180000; eta:1,phi:-1.2,et:6000; eta:0.5,phi:-1.2,et:3000;'
     data['l1muroi'][1]   =  '2,0.5,0,MU6; 3,0.5,0,MU6;'
     #data['l1muroi'][1]   =  '0,0,0,MU0;'
     data['msmu'][1]      = 'eta:-1.2,phi:0.7,pt:1500,pt2:1500; eta:-1.1,phi:0.6,pt:1500,pt2:1500;'
 
-    # event 2: 2e+ 3mu : HLT_e5_e8_2mu6_L1EM3_EM5_L12MU6, HLT_mu6_e10_L1MU6_EM5
-    data['ctp'] [2]      =  'HLT_mu6_L1MU6 HLT_mu8_L1MU10 HLT_mu10_L1MU10 HLT_mu8_1step_L1MU6 HLT_e20_L1EM10 HLT_e5_L1EM3 HLT_e8_L1EM5 HLT_mu6_e10_L1MU6_EM5 HLT_mu6Comb_e8_L1MU6_EM5 HLT_e3_e5_L1EM3_EM5 HLT_2mu6_L12MU6 HLT_2mu6Comb_L12MU6 HLT_mu6_mu10_L12MU6 HLT_2mu4_bDimu_L12MU6 HLT_e5_e8_L1EM3_EM5 HLT_e5_e8_2mu6_L1EM3_EM5_L12MU6 HLT_mu6_mu6noL1_L1MU6'
+    # event 2: 2e+ 3mu : HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6, HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5
+    data['ctp'] [2]      =  'HLT_TestChain6_muv1_L1MU6 \
+                             HLT_TestChain8_muv1_L1MU10 \
+                             HLT_TestChain10_muv2_L1MU10 \
+                             HLT_TestChain8_muv1step_L1MU6 \
+                             HLT_TestChain5_ev1_L1EM3 \
+                             HLT_TestChain8_ev1_L1EM5 \
+                             HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 \
+                             HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 \
+                             HLT_2TestChain6_muv1_L12MU6 \
+                             HLT_2TestChain6_muEmpty_L12MU6 \
+                             HLT_TestChain6_muv1_TestChain10_muv1_L12MU6 \
+                             HLT_2TestChain4_muv1_dr_L12MU6 HLT_e5_e8_L12EM3 \
+                             HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 \
+                             HLT_TestChain6_muv1_TestChain6_muEmpty_L1MU6 \
+                             HLT_TestChain6_muv1_TestChain5_ev1_dr_L12MU6'
     data['l1emroi'][2]   =  '2,0.2,0,EM3,EM5,EM7,EM15,EM20,EM50,EM100; 1,-1.1,0,EM3,EM5,EM7,EM15,EM20,EM50;'
     data['emclusters'][2]=  'eta:0.5,phi:0,et:120000; eta:1,phi:-1.2,et:65000;'
     data['l1muroi'][2]   =  '2,0.5,0,MU6,MU8; 3,0.5,0,MU6,MU8,MU10;2.2,0.6,0,MU6;'
     data['msmu'][2]      =  'eta:-1.2,phi:0.7,pt:6500,pt2:8500; eta:-1.1,phi:0.6,pt:8500,pt2:8500;eta:-1.1,phi:0.6,pt:8500,pt2:8500;'
 
-    #event 3: 1e + 1mu; HLT_mu6_e10_L1MU6_EM5 does not pass because of e10
-    data['ctp'] [3]      =  'HLT_mu20_L1MU10 HLT_mu10_L1MU10 HLT_mu8_L1MU10 HLT_mu8_1step_L1MU6 HLT_2mu8 HLT_e8_L1EM5 HLT_mu6_e10_L1MU6_EM5 HLT_mu6Comb_e8_L1MU6_EM5'
-
+    #event 3: 1e + 1mu; HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 does not pass because of e10
+    data['ctp'] [3]      =  'HLT_TestChain20_muv1_L1MU10 \
+                             HLT_TestChain10_muv1_L1MU10 \
+                             HLT_TestChain8_muv1_L1MU10 \
+                             HLT_TestChain8_muv1step_L1MU6 \
+                             HLT_TestChain8_ev1_L1EM5 \
+                             HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5\
+                             HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5'
     data['l1emroi'][3]   =  '1,1.5,0,EM3,EM5,EM7;'
     data['emclusters'][3]=  'eta:-0.6,phi:1.7,et:9000;'
     data['l1muroi'][3]   =  '2,-0.1,0,MU6,MU8,MU10;'
@@ -88,13 +160,15 @@ def generateL1DecoderAndChains():
                        ';',
                        ';']
 
-
-
-    from TrigUpgradeTest.TestUtils import writeEmulationFiles, makeChain
+    from TrigUpgradeTest.TestUtils import writeEmulationFiles
     writeEmulationFiles(data)
 
-    from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import ChainStep
 
+###########################################################################    
+def generateChainsManually():
+    from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import ChainStep
+    from TrigUpgradeTest.TestUtils import makeChain
+    
 
     doMuon     = True
     doElectron = True
@@ -127,15 +201,12 @@ def generateL1DecoderAndChains():
         
         step_empy= ChainStep("Step2_empty")
 
-
         MuChains  = [
-            makeChain(name='HLT_mu8_1step_L1MU6',  L1Thresholds=["MU6"],  ChainSteps=[step_mu11]),
-            makeChain(name='HLT_mu20_L1MU10',   L1Thresholds=["MU10"],   ChainSteps=[step_mu11 , step_mu21 , step_mu31] ),
-            makeChain(name='HLT_mu10_L1MU10',   L1Thresholds=["MU10"],   ChainSteps=[step_mu11 , step_mu22 , step_mu31] ),
-            makeChain(name='HLT_mu8_L1MU10',    L1Thresholds=["MU10"],   ChainSteps=[step_mu11 , step_mu21 , step_mu32, step_mu41] ),
-            makeChain(name='HLT_mu6_L1MU6',     L1Thresholds=["MU6"],    ChainSteps=[step_mu11 , step_empy , step_mu32, step_mu41] ),
- #           Chain(name='HLT_mu6_1step_L1MU6',  L1Item="L1_MU6",  ChainSteps=[step_mu11 , step_empy , step_mu31]),
-#            Chain(name='HLT_2mu6_L12MU6',  L1Item="L1_2MU6",      ChainSteps=[ChainStep("Step_2muSA", [muSA,muSA])  ] )
+            makeChain(name='HLT_TestChain8_muv1step_L1MU6',  L1Thresholds=["MU6"],  ChainSteps=[step_mu11]),
+            makeChain(name='HLT_TestChain8_muv1_L1MU10',    L1Thresholds=["MU10"],   ChainSteps=[step_mu11 , step_mu21 , step_mu31, step_mu41] ),
+            makeChain(name='HLT_TestChain20_muv1_L1MU10',   L1Thresholds=["MU10"],   ChainSteps=[step_mu11 , step_mu21 , step_mu31, step_mu41] ),
+            makeChain(name='HLT_TestChain10_muv2_L1MU10',   L1Thresholds=["MU10"],   ChainSteps=[step_mu11 , step_mu22 , step_mu31] ),
+            makeChain(name='HLT_TestChain6_muEmpty_L1MU6',     L1Thresholds=["MU6"],    ChainSteps=[step_mu11 , step_empy , step_mu32, step_mu41] ), 
             ]
             
 
@@ -153,18 +224,16 @@ def generateL1DecoderAndChains():
 
         # gamma
         gamm11 = gamMenuSequence("1", reconame="v1", hyponame="v1")
-
     
         ElChains  = [
-            makeChain(name='HLT_e5_L1EM3'   , L1Thresholds=["EM3"], ChainSteps=[ ChainStep("Step1_em11", [el11]), ChainStep("Step2_em21",  [el21]) ] ),
-            makeChain(name='HLT_e5_v2_L1EM7', L1Thresholds=["EM7"], ChainSteps=[ ChainStep("Step1_em11", [el11]), ChainStep("Step2_em22",  [el22]) ] ),
-            makeChain(name='HLT_e5_v3_L1EM7', L1Thresholds=["EM7"], ChainSteps=[ ChainStep("Step1_em11", [el11]), ChainStep("Step2_em23",  [el23]) ] ),
-            makeChain(name='HLT_e8_L1EM5'   , L1Thresholds=["EM5"], ChainSteps=[ ChainStep("Step1_em11", [el11]), ChainStep("Step2_em21",  [el21]), ChainStep("Step3_em31",  [el31]) ] ),
-            makeChain(name='HLT_g5_L1EM7'   , L1Thresholds=["EM7"], ChainSteps=[ ChainStep("Step1_gam11", [gamm11]) ] )
+            makeChain(name='HLT_TestChain5_ev1_L1EM3', L1Thresholds=["EM3"], ChainSteps=[ ChainStep("Step1_em11", [el11]), ChainStep("Step2_em21",  [el21]), ChainStep("Step3_em31",  [el31])] ),
+            makeChain(name='HLT_TestChain8_ev1_L1EM5', L1Thresholds=["EM5"], ChainSteps=[ ChainStep("Step1_em11", [el11]), ChainStep("Step2_em21",  [el21]), ChainStep("Step3_em31",  [el31]) ] ),
+            makeChain(name='HLT_TestChain5_ev2_L1EM7', L1Thresholds=["EM7"], ChainSteps=[ ChainStep("Step1_em11", [el11]), ChainStep("Step2_em22",  [el22]) ] ),
+            makeChain(name='HLT_TestChain5_ev3_L1EM7', L1Thresholds=["EM7"], ChainSteps=[ ChainStep("Step1_em11", [el11]), ChainStep("Step2_em23",  [el23]) ] ),
+            makeChain(name='HLT_TestChain5_gv1_L1EM7', L1Thresholds=["EM7"], ChainSteps=[ ChainStep("Step1_gam11", [gamm11]) ] )
         ]
 
         HLTChains += ElChains
-
         
 
     # combined chain
@@ -192,55 +261,50 @@ def generateL1DecoderAndChains():
            
            
         from TrigUpgradeTest.HLTSignatureHypoTools import dimuDrComboHypoTool
-
-            
-           
+                       
         # multiplicity here indicates the number of objects to be combined:
         # for the chain dictionary, get the sum of the multiplicity in the multiplicy array
         # in symmetric chains, multiplicity=2 but only one sequence is used
-
-
      
         CombChains =[
             # This is an example of a chain running in "serial"
-            makeChain(name='HLT_mu6_e10_L1MU6_EM5',  L1Thresholds=["MU6","EM5"], ChainSteps=[
+            makeChain(name='HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5',  L1Thresholds=["MU6","EM5"], ChainSteps=[
                 ChainStep("Step1_mu_em_serial", [mu11, emptySeq1], multiplicity=[1,1]),
                 ChainStep("Step2_mu_em_serial", [emptySeq2, el21], multiplicity=[1,1])] ),
 
-            makeChain(name='HLT_mu6Comb_e8_L1MU6_EM5', L1Thresholds=["MU6","EM5"], ChainSteps=[
+            makeChain(name='HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5', L1Thresholds=["MU6","EM5"], ChainSteps=[
                 ChainStep("Step1_mu2_em", [mu12, el11], multiplicity=[1,1]),
                 ChainStep("Step2_mu_em", [mu21, el21], multiplicity=[1,1])] ),
 
-            makeChain(name='HLT_e5_e8_L12EM3',   L1Thresholds=["EM3","EM3"], ChainSteps=[
+            makeChain(name='HLT_TestChain5_ev1_TestChain8_ev1_L12EM3',   L1Thresholds=["EM3","EM3"], ChainSteps=[ #norun
                 ChainStep("Step1_2emAs",   [el11, el11], multiplicity=[1,1]),
                 ChainStep("Step2_2emAs",   [el21, el21], multiplicity=[1,1]) ]),
                 
-            makeChain(name='HLT_e5_e8_2mu6_L1EM3_EM5_L12MU6',   L1Thresholds=["EM3","EM5","MU6"], ChainSteps=[
+            makeChain(name='HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6',   L1Thresholds=["EM3","EM5","MU6"], ChainSteps=[
                 ChainStep("Step1_2em_2mu",   [el11,el11,mu11], multiplicity=[1,1,2]),
                 ChainStep("Step2_2em_2mu",   [el21,el21,mu21], multiplicity=[1,1,2]) ]),
 
-            makeChain(name='HLT_2mu6_L12MU6',       L1Thresholds=["MU6"], ChainSteps=[
+            makeChain(name='HLT_2TestChain6_muv1_L12MU6',       L1Thresholds=["MU6"], ChainSteps=[
                 ChainStep("Step1_2mu",   [mu11], multiplicity=[2]),
                 ChainStep("Step2_2mu",   [mu21], multiplicity=[2]) ]),
 
-            makeChain(name='HLT_mu6_mu10_L12MU6',       L1Thresholds=["MU6", "MU6"], ChainSteps=[
+            makeChain(name='HLT_TestChain6_muv1_TestChain10_muv1_L12MU6',       L1Thresholds=["MU6", "MU6"], ChainSteps=[
                 ChainStep("Step1_2muAs",   [mu11,mu11], multiplicity=[1,1]),
                 ChainStep("Step2_2muAs",   [mu21,mu21], multiplicity=[1,1]) ]),
                 
-            makeChain(name='HLT_2mu6Comb_L12MU6',   L1Thresholds=["MU6"], ChainSteps=[
+            makeChain(name='HLT_2TestChain6_muEmpty_L12MU6',   L1Thresholds=["MU6"], ChainSteps=[
                 ChainStep("Step1_2mu_empty",  multiplicity=[2]),
                 ChainStep("Step2_2mu", [mu21], multiplicity=[2]) ]),
 
-            makeChain(name='HLT_mu6_e5_L1MU6_EM5',  L1Thresholds=["MU6","EM5"], ChainSteps=[
+            makeChain(name='HLT_TestChain6_muv1_TestChain5_ev1dr_L12MU6',  L1Thresholds=["MU6","EM5"], ChainSteps=[
                 ChainStep("Step1_mu_em", [mu11, el11], multiplicity=[1,1], comboToolConfs=[dimuDrComboHypoTool]),
                 ChainStep("Step2_mu_em", [mu21, el21], multiplicity=[1,1], comboToolConfs=[dimuDrComboHypoTool])] ),
                                                                                        
-            makeChain(name='HLT_2mu4_bDimu_L12MU6', L1Thresholds=["MU6"], ChainSteps=[
+            makeChain(name='HLT_2TestChain4_muv1dr_L12MU6', L1Thresholds=["MU6"], ChainSteps=[
                 ChainStep("Step1_2mu",    [mu11], multiplicity=[2], comboToolConfs=[dimuDrComboHypoTool]),
-                ChainStep("Step2_2mu22",  [mu22], multiplicity=[2]),
-                ChainStep("Step3_2mu",    [mu31], multiplicity=[2]) ] ),
+                ChainStep("Step2_2mu22",  [mu22], multiplicity=[2]) ] ),
                                                                                        
-            makeChain(name='HLT_mu6_mu6noL1_L1MU6', L1Thresholds=["MU6", "FSNOSEED"], ChainSteps=[
+            makeChain(name='HLT_TestChain6_muv1_TestChain6_muEmpty_L1MU6', L1Thresholds=["MU6", "FSNOSEED"], ChainSteps=[
                 ChainStep("Step1_2muAs",   [mu11, mu11], multiplicity=[1,1]),
                 ChainStep("Step2_2muAs",   [mu21, mu21], multiplicity=[1,1]) ])
                                                                               
@@ -251,8 +315,8 @@ def generateL1DecoderAndChains():
 
 
 
-
-    ########################## L1 #################################################
+########################## L1 #################################################        
+def generateL1Decoder():
 
     L1UnpackingSeq = parOR("L1UnpackingSeq")
 
@@ -274,10 +338,9 @@ def generateL1DecoderAndChains():
 
     l1Decoder.roiUnpackers = [emUnpacker, muUnpacker]
 
-    #print l1Decoder
     L1UnpackingSeq += l1Decoder
     log.debug(L1UnpackingSeq)
 
-    ########################## L1 #################################################
+    return l1Decoder
+
 
-    return l1Decoder, HLTChains
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/python/HLTSignatureHypoTools.py b/Trigger/TrigValidation/TrigUpgradeTest/python/HLTSignatureHypoTools.py
index da5d178a68bbb725e4075767c02018bd3aa20b1e..c4aa432e07bafef8434ba09c87a849657b0876c8 100644
--- a/Trigger/TrigValidation/TrigUpgradeTest/python/HLTSignatureHypoTools.py
+++ b/Trigger/TrigValidation/TrigUpgradeTest/python/HLTSignatureHypoTools.py
@@ -10,35 +10,36 @@ def TestHypoTool(name, prop, threshold_value):
 
 def MuTestHypoTool(chainDict):
     name = chainDict['chainName']
-    threshold = getThreshold(chainDict, 'mu') 
+    threshold = getThreshold(chainDict) 
     return TestHypoTool(name,prop="pt", threshold_value=threshold)
 
 def ElTestHypoTool(chainDict):
     name = chainDict['chainName']
-    threshold = getThreshold(chainDict, 'e') 
+    threshold = getThreshold(chainDict) 
     return TestHypoTool(name,prop="et", threshold_value=threshold)
 
 def GammTestHypoTool(chainDict):
     name = chainDict['chainName']
-    threshold = getThreshold(chainDict, 'g') 
+    threshold = getThreshold(chainDict) 
     return TestHypoTool(name,prop="et", threshold_value=threshold)
 
 
 def MuTest2HypoTool(chainDict):
     name = chainDict['chainName']
-    threshold = getThreshold(chainDict, 'mu') 
+    threshold = getThreshold(chainDict) 
     return TestHypoTool(name,prop="pt2", threshold_value=threshold)
 
 def ElTest2HypoTool(chainDict):
     name = chainDict['chainName']
-    threshold = getThreshold(chainDict, 'e') 
+    threshold = getThreshold(chainDict) 
     return TestHypoTool(name,prop="et", threshold_value=threshold)
 
 
-def getThreshold(chainDict, signature):
+def getThreshold(chainDict):
     name = chainDict['chainParts'][0]['chainPartName']
     from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import getChainThresholdFromName
-    return getChainThresholdFromName( name.split("_"), signature)
+    return getChainThresholdFromName( name.split("_"), "TestChain")
+
 
 
 def dimuDrComboHypoTool(chainDict):
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/EmuNewJOTest.py b/Trigger/TrigValidation/TrigUpgradeTest/share/EmuNewJOTest.py
index 84c4201a66e02c81c993d2e06299a45d2eae29f3..749f814e09d9ede13138d30c9e9e848e650fb238 100644
--- a/Trigger/TrigValidation/TrigUpgradeTest/share/EmuNewJOTest.py
+++ b/Trigger/TrigValidation/TrigUpgradeTest/share/EmuNewJOTest.py
@@ -7,7 +7,7 @@ from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.AllConfigFlags import ConfigFlags as flags
 from AthenaCommon.Constants import INFO, DEBUG, VERBOSE
 from AthenaCommon.Logging import logging
-from ByteStreamCnvSvc.ByteStreamConfig import TrigBSReadCfg
+from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
 from TrigUpgradeTest.TriggerHistSvcConfig import TriggerHistSvcConfig
 from MuonConfig.MuonCablingConfig import RPCCablingConfigCfg, TGCCablingConfigCfg
 from TrigConfigSvc.TrigConfigSvcConfig import TrigConfigSvcCfg
@@ -31,7 +31,7 @@ flags.Trigger.L1Decoder.forceEnableAllChains = True
 flags.lock()
 
 acc = ComponentAccumulator()
-acc.merge(TrigBSReadCfg(flags))
+acc.merge(ByteStreamReadCfg(flags))
 acc.merge(TriggerHistSvcConfig(flags))
 
 l1DecoderAlg, OrigHLTChains = generateL1DecoderAndChains()
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/EmuStepProcessingTest.py b/Trigger/TrigValidation/TrigUpgradeTest/share/EmuStepProcessingTest.py
index 1dfdf4f95f18cb273e1d07c063ea522743450b08..793ece34ea4445ed286e043914f44b723fb93993 100644
--- a/Trigger/TrigValidation/TrigUpgradeTest/share/EmuStepProcessingTest.py
+++ b/Trigger/TrigValidation/TrigUpgradeTest/share/EmuStepProcessingTest.py
@@ -9,15 +9,19 @@
 #--------------------------------------------------------------
 # ATLAS default Application Configuration options
 #--------------------------------------------------------------
-
 from __future__ import print_function
 
-from TriggerJobOpts.TriggerFlags import TriggerFlags
-TriggerFlags.triggerMenuSetup = "LS2_emu_v1"
-TriggerFlags.generateMenuDiagnostics=True
+# input parameters:
+class opt:
+    doMenu          = False # use either menu or manual chain building
+
 
 
-from TrigUpgradeTest.EmuStepProcessingConfig import generateL1DecoderAndChains
+from AthenaCommon.Logging import logging
+from TriggerJobOpts.TriggerFlags import TriggerFlags
+from TrigUpgradeTest.EmuStepProcessingConfig import generateL1DecoderAndChainsManually, generateL1DecoderAndChainsByMenu
+from AthenaCommon.AlgSequence import AlgSequence
+from TriggerMenuMT.HLTMenuConfig.Menu.HLTMenuJSON import generateJSON
 
 # signatures
 # steps: sequential AND of 1=Filter 2=Processing
@@ -26,16 +30,24 @@ from TrigUpgradeTest.EmuStepProcessingConfig import generateL1DecoderAndChains
 # filters: one SeqFilter per step, per chain
 # inputMakers: one per each first RecoAlg in a step (so one per step), one input per chain that needs that step
 
-from AthenaCommon.AlgSequence import AlgSequence
+log = logging.getLogger('EmuStepProcessingTest.py')
+log.info('Setup options:')
+defaultOptions = [a for a in dir(opt)]
+for option in defaultOptions:
+    if option in globals():
+        setattr(opt, option, globals()[option])
+        print(' %20s = %s' % (option, getattr(opt, option)))
+    else:        
+        print(' %20s = (Default) %s' % (option, getattr(opt, option)))
+
+
+
 topSequence = AlgSequence()
-l1Decoder, HLTChains = generateL1DecoderAndChains()
-topSequence += l1Decoder
-##### Make all HLT #######
-from TriggerMenuMT.HLTMenuConfig.Menu.TriggerConfigHLT import TriggerConfigHLT
-from TriggerMenuMT.HLTMenuConfig.Menu.HLTCFConfig import makeHLTTree
-makeHLTTree( triggerConfigHLT=TriggerConfigHLT )
+if opt.doMenu is True:
+    generateL1DecoderAndChainsByMenu(topSequence)
+else:
+    generateL1DecoderAndChainsManually(topSequence)
 
-from TriggerMenuMT.HLTMenuConfig.Menu.HLTMenuJSON import generateJSON
 generateJSON()
 
 from TrigConfigSvc.TrigConfigSvcCfg import getHLTConfigSvc, getL1ConfigSvc
@@ -58,3 +70,4 @@ dumpSequence( topSequence )
 
 theApp.EvtMax = 4
 
+TriggerFlags.generateMenuDiagnostics=True
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/emu_step_menu_processing.ref b/Trigger/TrigValidation/TrigUpgradeTest/share/emu_step_menu_processing.ref
new file mode 100644
index 0000000000000000000000000000000000000000..76bd11507d3c05b4ab1170a1fcf27039c1a4732c
--- /dev/null
+++ b/Trigger/TrigValidation/TrigUpgradeTest/share/emu_step_menu_processing.ref
@@ -0,0 +1,134 @@
+TriggerSummaryStep1                        1   0   DEBUG In summary 4 chains passed:
+TriggerSummaryStep1                        1   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep1                        1   0   DEBUG  +++ HLT_TestChain5_ev1_L1EM3 ID#1756953305
+TriggerSummaryStep1                        1   0   DEBUG  +++ HLT_TestChain5_ev3_L1EM7 ID#2336588294
+TriggerSummaryStep1                        1   0   DEBUG  +++ HLT_TestChain5_gv1_L1EM7 ID#3893303900
+TriggerSummaryStep2                        1   0   DEBUG In summary 3 chains passed:
+TriggerSummaryStep2                        1   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep2                        1   0   DEBUG  +++ HLT_TestChain5_ev1_L1EM3 ID#1756953305
+TriggerSummaryStep2                        1   0   DEBUG  +++ HLT_TestChain5_ev3_L1EM7 ID#2336588294
+TriggerSummaryStep3                        1   0   DEBUG In summary 2 chains passed:
+TriggerSummaryStep3                        1   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep3                        1   0   DEBUG  +++ HLT_TestChain5_ev1_L1EM3 ID#1756953305
+TriggerSummaryStep1                        2   0   DEBUG In summary 18 chains passed:
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#64374772
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg001_HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#122300819
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#171620884
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_2TestChain6_muEmpty_L12MU6 ID#241766530
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_2TestChain6_muv1_L12MU6 ID#1408409992
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_TestChain6_muv1_TestChain6_muEmpty_L1MU6 ID#1462041536
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg001_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#1546253468
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#1601708571
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain5_ev1_L1EM3 ID#1756953305
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg001_HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#1777912350
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_TestChain6_muv1_TestChain10_muv1_L12MU6 ID#1790520567
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#1827802456
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain8_muv1_L1MU10 ID#2288364952
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#3476793373
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg002_HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#3575185873
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain8_muv1step_L1MU6 ID#3588359947
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#4283304400
+TriggerSummaryStep2                        2   0   DEBUG In summary 14 chains passed:
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#64374772
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg001_HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#122300819
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#171620884
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_2TestChain6_muEmpty_L12MU6 ID#241766530
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_2TestChain6_muv1_L12MU6 ID#1408409992
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg001_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#1546253468
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg000_HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#1601708571
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_TestChain5_ev1_L1EM3 ID#1756953305
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg001_HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#1777912350
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg000_HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#1827802456
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#3476793373
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg002_HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#3575185873
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg000_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#4283304400
+TriggerSummaryStep3                        2   0   DEBUG In summary 2 chains passed:
+TriggerSummaryStep3                        2   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep3                        2   0   DEBUG  +++ HLT_TestChain5_ev1_L1EM3 ID#1756953305
+TriggerSummaryStep1                        3   0   DEBUG In summary 10 chains passed:
+TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#64374772
+TriggerSummaryStep1                        3   0   DEBUG  +++ leg001_HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#122300819
+TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_TestChain20_muv1_L1MU10 ID#356594709
+TriggerSummaryStep1                        3   0   DEBUG  +++ leg001_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#1546253468
+TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep1                        3   0   DEBUG  +++ leg000_HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#1827802456
+TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_TestChain8_muv1_L1MU10 ID#2288364952
+TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#3476793373
+TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_TestChain8_muv1step_L1MU6 ID#3588359947
+TriggerSummaryStep1                        3   0   DEBUG  +++ leg000_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#4283304400
+TriggerSummaryStep2                        3   0   DEBUG In summary 6 chains passed:
+TriggerSummaryStep2                        3   0   DEBUG  +++ HLT_TestChain20_muv1_L1MU10 ID#356594709
+TriggerSummaryStep2                        3   0   DEBUG  +++ leg001_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#1546253468
+TriggerSummaryStep2                        3   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep2                        3   0   DEBUG  +++ HLT_TestChain8_muv1_L1MU10 ID#2288364952
+TriggerSummaryStep2                        3   0   DEBUG  +++ HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#3476793373
+TriggerSummaryStep2                        3   0   DEBUG  +++ leg000_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#4283304400
+TriggerSummaryStep3                        3   0   DEBUG In summary 3 chains passed:
+TriggerSummaryStep3                        3   0   DEBUG  +++ HLT_TestChain20_muv1_L1MU10 ID#356594709
+TriggerSummaryStep3                        3   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep3                        3   0   DEBUG  +++ HLT_TestChain8_muv1_L1MU10 ID#2288364952
+TriggerSummaryStep4                        3   0   DEBUG In summary 2 chains passed:
+TriggerSummaryStep4                        3   0   DEBUG  +++ HLT_TestChain20_muv1_L1MU10 ID#356594709
+TriggerSummaryStep4                        3   0   DEBUG  +++ HLT_TestChain8_muv1_L1MU10 ID#2288364952
+TrigSignatureMoniMT                                 INFO HLT_2TestChain4_muv1dr_L12MU6 #3176095517
+TrigSignatureMoniMT                                 INFO -- #3176095517 Events         0          0          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #3176095517 Features                             0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_2TestChain6_muEmpty_L12MU6 #241766530
+TrigSignatureMoniMT                                 INFO -- #241766530 Events          1          1          0          1          -          -          1          
+TrigSignatureMoniMT                                 INFO -- #241766530 Features                              0          6          -          -          
+TrigSignatureMoniMT                                 INFO HLT_2TestChain6_muv1_L12MU6 #1408409992
+TrigSignatureMoniMT                                 INFO -- #1408409992 Events         2          2          1          1          -          -          1          
+TrigSignatureMoniMT                                 INFO -- #1408409992 Features                             6          6          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain10_muv2_L1MU10 #3482819675
+TrigSignatureMoniMT                                 INFO -- #3482819675 Events         2          2          0          0          0          -          0          
+TrigSignatureMoniMT                                 INFO -- #3482819675 Features                             0          0          0          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain20_muv1_L1MU10 #356594709
+TrigSignatureMoniMT                                 INFO -- #356594709 Events          1          1          1          1          1          1          1          
+TrigSignatureMoniMT                                 INFO -- #356594709 Features                              1          1          1          1          
+TrigSignatureMoniMT                                 INFO HLT_TestChain5_ev1_L1EM3 #1756953305
+TrigSignatureMoniMT                                 INFO -- #1756953305 Events         3          3          2          2          2          -          2          
+TrigSignatureMoniMT                                 INFO -- #1756953305 Features                             4          4          4          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 #171620884
+TrigSignatureMoniMT                                 INFO -- #171620884 Events          1          1          1          1          -          -          1          
+TrigSignatureMoniMT                                 INFO -- #171620884 Features                              2          2          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain5_ev1_TestChain8_ev1_L12EM3 #2709794009
+TrigSignatureMoniMT                                 INFO -- #2709794009 Events         0          0          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #2709794009 Features                             0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain5_ev2_L1EM7 #1760405581
+TrigSignatureMoniMT                                 INFO -- #1760405581 Events         0          0          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #1760405581 Features                             0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain5_ev3_L1EM7 #2336588294
+TrigSignatureMoniMT                                 INFO -- #2336588294 Events         1          1          1          1          -          -          1          
+TrigSignatureMoniMT                                 INFO -- #2336588294 Features                             2          2          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain5_gv1_L1EM7 #3893303900
+TrigSignatureMoniMT                                 INFO -- #3893303900 Events         1          1          1          -          -          -          1          
+TrigSignatureMoniMT                                 INFO -- #3893303900 Features                             2          -          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain6_muEmpty_L1MU6 #3519633296
+TrigSignatureMoniMT                                 INFO -- #3519633296 Events         0          0          0          0          0          0          0          
+TrigSignatureMoniMT                                 INFO -- #3519633296 Features                             0          0          0          0          
+TrigSignatureMoniMT                                 INFO HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 #64374772
+TrigSignatureMoniMT                                 INFO -- #64374772 Events           2          2          2          1          -          -          1          
+TrigSignatureMoniMT                                 INFO -- #64374772 Features                               4          3          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain6_muv1_TestChain10_muv1_L12MU6 #3196402061
+TrigSignatureMoniMT                                 INFO -- #3196402061 Events         2          2          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #3196402061 Features                             0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain6_muv1_TestChain5_ev1dr_L12MU6 #3205587050
+TrigSignatureMoniMT                                 INFO -- #3205587050 Events         0          0          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #3205587050 Features                             0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain6_muv1_TestChain6_muEmpty_L1MU6 #293762221
+TrigSignatureMoniMT                                 INFO -- #293762221 Events          1          1          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #293762221 Features                              0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 #3476793373
+TrigSignatureMoniMT                                 INFO -- #3476793373 Events         2          2          2          2          -          -          2          
+TrigSignatureMoniMT                                 INFO -- #3476793373 Features                             4          4          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain8_ev1_L1EM5 #1677577445
+TrigSignatureMoniMT                                 INFO -- #1677577445 Events         4          4          3          3          3          -          3          
+TrigSignatureMoniMT                                 INFO -- #1677577445 Features                             4          4          4          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain8_muv1_L1MU10 #2288364952
+TrigSignatureMoniMT                                 INFO -- #2288364952 Events         2          2          2          1          1          1          1          
+TrigSignatureMoniMT                                 INFO -- #2288364952 Features                             2          1          1          1          
+TrigSignatureMoniMT                                 INFO HLT_TestChain8_muv1step_L1MU6 #3588359947
+TrigSignatureMoniMT                                 INFO -- #3588359947 Events         2          2          2          -          -          -          2          
+TrigSignatureMoniMT                                 INFO -- #3588359947 Features                             3          -          -          -          
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/emu_step_processing.ref b/Trigger/TrigValidation/TrigUpgradeTest/share/emu_step_processing.ref
index db56788c55ff5106baf0bb701dd4b9c0e479ed1d..76bd11507d3c05b4ab1170a1fcf27039c1a4732c 100644
--- a/Trigger/TrigValidation/TrigUpgradeTest/share/emu_step_processing.ref
+++ b/Trigger/TrigValidation/TrigUpgradeTest/share/emu_step_processing.ref
@@ -1,142 +1,134 @@
 TriggerSummaryStep1                        1   0   DEBUG In summary 4 chains passed:
-TriggerSummaryStep1                        1   0   DEBUG  +++ HLT_e5_L1EM3 ID#744746179
-TriggerSummaryStep1                        1   0   DEBUG  +++ HLT_e8_L1EM5 ID#1310390142
-TriggerSummaryStep1                        1   0   DEBUG  +++ HLT_e5_v3_L1EM7 ID#1502850332
-TriggerSummaryStep1                        1   0   DEBUG  +++ HLT_g5_L1EM7 ID#3537091008
+TriggerSummaryStep1                        1   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep1                        1   0   DEBUG  +++ HLT_TestChain5_ev1_L1EM3 ID#1756953305
+TriggerSummaryStep1                        1   0   DEBUG  +++ HLT_TestChain5_ev3_L1EM7 ID#2336588294
+TriggerSummaryStep1                        1   0   DEBUG  +++ HLT_TestChain5_gv1_L1EM7 ID#3893303900
 TriggerSummaryStep2                        1   0   DEBUG In summary 3 chains passed:
-TriggerSummaryStep2                        1   0   DEBUG  +++ HLT_e5_L1EM3 ID#744746179
-TriggerSummaryStep2                        1   0   DEBUG  +++ HLT_e8_L1EM5 ID#1310390142
-TriggerSummaryStep2                        1   0   DEBUG  +++ HLT_e5_v3_L1EM7 ID#1502850332
-TriggerSummaryStep3                        1   0   DEBUG In summary 1 chains passed:
-TriggerSummaryStep3                        1   0   DEBUG  +++ HLT_e8_L1EM5 ID#1310390142
-TriggerSummaryStep1                        2   0   DEBUG In summary 20 chains passed:
-TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_mu6_mu10_L12MU6 ID#308277064
-TriggerSummaryStep1                        2   0   DEBUG  +++ leg002_HLT_e5_e8_2mu6_L1EM3_EM5_L12MU6 ID#345317877
-TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_mu6_e10_L1MU6_EM5 ID#463671945
-TriggerSummaryStep1                        2   0   DEBUG  +++ leg001_HLT_mu6_e10_L1MU6_EM5 ID#474197064
-TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_e5_L1EM3 ID#744746179
-TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_mu6Comb_e8_L1MU6_EM5 ID#1248852240
-TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_e8_L1EM5 ID#1310390142
-TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_2mu6_L12MU6 ID#1747073535
-TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_2mu6Comb_L12MU6 ID#2046267508
-TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_mu8_L1MU10 ID#2258266078
-TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_mu6Comb_e8_L1MU6_EM5 ID#2371747463
-TriggerSummaryStep1                        2   0   DEBUG  +++ leg001_HLT_e5_e8_2mu6_L1EM3_EM5_L12MU6 ID#2467396139
-TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_mu6_L1MU6 ID#2560542253
-TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_e5_e8_2mu6_L1EM3_EM5_L12MU6 ID#2627130263
-TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_mu6_mu6noL1_L1MU6 ID#2893452617
-TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_mu8_1step_L1MU6 ID#3380352717
-TriggerSummaryStep1                        2   0   DEBUG  +++ leg001_HLT_mu6Comb_e8_L1MU6_EM5 ID#3495876895
-TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_mu6_e10_L1MU6_EM5 ID#3616111893
-TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_2mu4_bDimu_L12MU6 ID#3793062581
-TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_e5_e8_2mu6_L1EM3_EM5_L12MU6 ID#4130483534
-TriggerSummaryStep2                        2   0   DEBUG In summary 16 chains passed:
-TriggerSummaryStep2                        2   0   DEBUG  +++ leg002_HLT_e5_e8_2mu6_L1EM3_EM5_L12MU6 ID#345317877
-TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_mu6_e10_L1MU6_EM5 ID#463671945
-TriggerSummaryStep2                        2   0   DEBUG  +++ leg001_HLT_mu6_e10_L1MU6_EM5 ID#474197064
-TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_e5_L1EM3 ID#744746179
-TriggerSummaryStep2                        2   0   DEBUG  +++ leg000_HLT_mu6Comb_e8_L1MU6_EM5 ID#1248852240
-TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_e8_L1EM5 ID#1310390142
-TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_2mu6_L12MU6 ID#1747073535
-TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_2mu6Comb_L12MU6 ID#2046267508
-TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_mu6Comb_e8_L1MU6_EM5 ID#2371747463
-TriggerSummaryStep2                        2   0   DEBUG  +++ leg001_HLT_e5_e8_2mu6_L1EM3_EM5_L12MU6 ID#2467396139
-TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_mu6_L1MU6 ID#2560542253
-TriggerSummaryStep2                        2   0   DEBUG  +++ leg000_HLT_e5_e8_2mu6_L1EM3_EM5_L12MU6 ID#2627130263
-TriggerSummaryStep2                        2   0   DEBUG  +++ leg001_HLT_mu6Comb_e8_L1MU6_EM5 ID#3495876895
-TriggerSummaryStep2                        2   0   DEBUG  +++ leg000_HLT_mu6_e10_L1MU6_EM5 ID#3616111893
-TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_2mu4_bDimu_L12MU6 ID#3793062581
-TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_e5_e8_2mu6_L1EM3_EM5_L12MU6 ID#4130483534
-TriggerSummaryStep3                        2   0   DEBUG In summary 3 chains passed:
-TriggerSummaryStep3                        2   0   DEBUG  +++ HLT_e8_L1EM5 ID#1310390142
-TriggerSummaryStep3                        2   0   DEBUG  +++ HLT_mu6_L1MU6 ID#2560542253
-TriggerSummaryStep3                        2   0   DEBUG  +++ HLT_2mu4_bDimu_L12MU6 ID#3793062581
-TriggerSummaryStep4                        2   0   DEBUG In summary 1 chains passed:
-TriggerSummaryStep4                        2   0   DEBUG  +++ HLT_mu6_L1MU6 ID#2560542253
-TriggerSummaryStep1                        3   0   DEBUG In summary 11 chains passed:
-TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_mu10_L1MU10 ID#209090273
-TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_mu20_L1MU10 ID#361599135
-TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_mu6_e10_L1MU6_EM5 ID#463671945
-TriggerSummaryStep1                        3   0   DEBUG  +++ leg001_HLT_mu6_e10_L1MU6_EM5 ID#474197064
-TriggerSummaryStep1                        3   0   DEBUG  +++ leg000_HLT_mu6Comb_e8_L1MU6_EM5 ID#1248852240
-TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_e8_L1EM5 ID#1310390142
-TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_mu8_L1MU10 ID#2258266078
-TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_mu6Comb_e8_L1MU6_EM5 ID#2371747463
-TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_mu8_1step_L1MU6 ID#3380352717
-TriggerSummaryStep1                        3   0   DEBUG  +++ leg001_HLT_mu6Comb_e8_L1MU6_EM5 ID#3495876895
-TriggerSummaryStep1                        3   0   DEBUG  +++ leg000_HLT_mu6_e10_L1MU6_EM5 ID#3616111893
-TriggerSummaryStep2                        3   0   DEBUG In summary 7 chains passed:
-TriggerSummaryStep2                        3   0   DEBUG  +++ HLT_mu10_L1MU10 ID#209090273
-TriggerSummaryStep2                        3   0   DEBUG  +++ HLT_mu20_L1MU10 ID#361599135
-TriggerSummaryStep2                        3   0   DEBUG  +++ leg000_HLT_mu6Comb_e8_L1MU6_EM5 ID#1248852240
-TriggerSummaryStep2                        3   0   DEBUG  +++ HLT_e8_L1EM5 ID#1310390142
-TriggerSummaryStep2                        3   0   DEBUG  +++ HLT_mu8_L1MU10 ID#2258266078
-TriggerSummaryStep2                        3   0   DEBUG  +++ HLT_mu6Comb_e8_L1MU6_EM5 ID#2371747463
-TriggerSummaryStep2                        3   0   DEBUG  +++ leg001_HLT_mu6Comb_e8_L1MU6_EM5 ID#3495876895
-TriggerSummaryStep3                        3   0   DEBUG In summary 4 chains passed:
-TriggerSummaryStep3                        3   0   DEBUG  +++ HLT_mu10_L1MU10 ID#209090273
-TriggerSummaryStep3                        3   0   DEBUG  +++ HLT_mu20_L1MU10 ID#361599135
-TriggerSummaryStep3                        3   0   DEBUG  +++ HLT_e8_L1EM5 ID#1310390142
-TriggerSummaryStep3                        3   0   DEBUG  +++ HLT_mu8_L1MU10 ID#2258266078
-TriggerSummaryStep4                        3   0   DEBUG In summary 1 chains passed:
-TriggerSummaryStep4                        3   0   DEBUG  +++ HLT_mu8_L1MU10 ID#2258266078
-TrigSignatureMoniMT                                 INFO HLT_2mu4_bDimu_L12MU6 #3793062581
-TrigSignatureMoniMT                                 INFO -- #3793062581 Events         2          2          1          1          1          -          1          
-TrigSignatureMoniMT                                 INFO -- #3793062581 Features                             5          4          4          -          
-TrigSignatureMoniMT                                 INFO HLT_2mu6Comb_L12MU6 #2046267508
-TrigSignatureMoniMT                                 INFO -- #2046267508 Events         1          1          0          1          -          -          1          
-TrigSignatureMoniMT                                 INFO -- #2046267508 Features                             0          6          -          -          
-TrigSignatureMoniMT                                 INFO HLT_2mu6_L12MU6 #1747073535
-TrigSignatureMoniMT                                 INFO -- #1747073535 Events         2          2          1          1          -          -          1          
-TrigSignatureMoniMT                                 INFO -- #1747073535 Features                             6          6          -          -          
-TrigSignatureMoniMT                                 INFO HLT_e5_L1EM3 #744746179
-TrigSignatureMoniMT                                 INFO -- #744746179 Events          3          3          2          2          -          -          2          
-TrigSignatureMoniMT                                 INFO -- #744746179 Features                              4          4          -          -          
-TrigSignatureMoniMT                                 INFO HLT_e5_e8_2mu6_L1EM3_EM5_L12MU6 #4130483534
-TrigSignatureMoniMT                                 INFO -- #4130483534 Events         1          1          1          1          -          -          1          
-TrigSignatureMoniMT                                 INFO -- #4130483534 Features                             2          2          -          -          
-TrigSignatureMoniMT                                 INFO HLT_e5_e8_L12EM3 #1990716439
-TrigSignatureMoniMT                                 INFO -- #1990716439 Events         0          0          0          0          -          -          0          
-TrigSignatureMoniMT                                 INFO -- #1990716439 Features                             0          0          -          -          
-TrigSignatureMoniMT                                 INFO HLT_e5_v2_L1EM7 #1479704746
-TrigSignatureMoniMT                                 INFO -- #1479704746 Events         0          0          0          0          -          -          0          
-TrigSignatureMoniMT                                 INFO -- #1479704746 Features                             0          0          -          -          
-TrigSignatureMoniMT                                 INFO HLT_e5_v3_L1EM7 #1502850332
-TrigSignatureMoniMT                                 INFO -- #1502850332 Events         1          1          1          1          -          -          1          
-TrigSignatureMoniMT                                 INFO -- #1502850332 Features                             2          2          -          -          
-TrigSignatureMoniMT                                 INFO HLT_e8_L1EM5 #1310390142
-TrigSignatureMoniMT                                 INFO -- #1310390142 Events         4          4          3          3          3          -          3          
-TrigSignatureMoniMT                                 INFO -- #1310390142 Features                             4          4          4          -          
-TrigSignatureMoniMT                                 INFO HLT_g5_L1EM7 #3537091008
-TrigSignatureMoniMT                                 INFO -- #3537091008 Events         1          1          1          -          -          -          1          
-TrigSignatureMoniMT                                 INFO -- #3537091008 Features                             2          -          -          -          
-TrigSignatureMoniMT                                 INFO HLT_mu10_L1MU10 #209090273
-TrigSignatureMoniMT                                 INFO -- #209090273 Events          2          2          1          1          1          -          1          
-TrigSignatureMoniMT                                 INFO -- #209090273 Features                              1          1          1          -          
-TrigSignatureMoniMT                                 INFO HLT_mu20_L1MU10 #361599135
-TrigSignatureMoniMT                                 INFO -- #361599135 Events          1          1          1          1          1          -          1          
-TrigSignatureMoniMT                                 INFO -- #361599135 Features                              1          1          1          -          
-TrigSignatureMoniMT                                 INFO HLT_mu6Comb_e8_L1MU6_EM5 #2371747463
-TrigSignatureMoniMT                                 INFO -- #2371747463 Events         2          2          2          2          -          -          2          
-TrigSignatureMoniMT                                 INFO -- #2371747463 Features                             4          4          -          -          
-TrigSignatureMoniMT                                 INFO HLT_mu6_L1MU6 #2560542253
-TrigSignatureMoniMT                                 INFO -- #2560542253 Events         1          1          1          0          1          1          1          
-TrigSignatureMoniMT                                 INFO -- #2560542253 Features                             3          0          3          3          
-TrigSignatureMoniMT                                 INFO HLT_mu6_e10_L1MU6_EM5 #463671945
-TrigSignatureMoniMT                                 INFO -- #463671945 Events          2          2          2          1          -          -          1          
-TrigSignatureMoniMT                                 INFO -- #463671945 Features                              4          3          -          -          
-TrigSignatureMoniMT                                 INFO HLT_mu6_e5_L1MU6_EM5 #1137020258
-TrigSignatureMoniMT                                 INFO -- #1137020258 Events         0          0          0          0          -          -          0          
-TrigSignatureMoniMT                                 INFO -- #1137020258 Features                             0          0          -          -          
-TrigSignatureMoniMT                                 INFO HLT_mu6_mu10_L12MU6 #1678556515
-TrigSignatureMoniMT                                 INFO -- #1678556515 Events         2          2          0          0          -          -          0          
-TrigSignatureMoniMT                                 INFO -- #1678556515 Features                             0          0          -          -          
-TrigSignatureMoniMT                                 INFO HLT_mu6_mu6noL1_L1MU6 #451489897
-TrigSignatureMoniMT                                 INFO -- #451489897 Events          1          1          0          0          -          -          0          
-TrigSignatureMoniMT                                 INFO -- #451489897 Features                              0          0          -          -          
-TrigSignatureMoniMT                                 INFO HLT_mu8_1step_L1MU6 #3380352717
-TrigSignatureMoniMT                                 INFO -- #3380352717 Events         2          2          2          -          -          -          2          
-TrigSignatureMoniMT                                 INFO -- #3380352717 Features                             3          -          -          -          
-TrigSignatureMoniMT                                 INFO HLT_mu8_L1MU10 #2258266078
-TrigSignatureMoniMT                                 INFO -- #2258266078 Events         2          2          2          1          1          1          1          
-TrigSignatureMoniMT                                 INFO -- #2258266078 Features                             2          1          1          1          
+TriggerSummaryStep2                        1   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep2                        1   0   DEBUG  +++ HLT_TestChain5_ev1_L1EM3 ID#1756953305
+TriggerSummaryStep2                        1   0   DEBUG  +++ HLT_TestChain5_ev3_L1EM7 ID#2336588294
+TriggerSummaryStep3                        1   0   DEBUG In summary 2 chains passed:
+TriggerSummaryStep3                        1   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep3                        1   0   DEBUG  +++ HLT_TestChain5_ev1_L1EM3 ID#1756953305
+TriggerSummaryStep1                        2   0   DEBUG In summary 18 chains passed:
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#64374772
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg001_HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#122300819
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#171620884
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_2TestChain6_muEmpty_L12MU6 ID#241766530
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_2TestChain6_muv1_L12MU6 ID#1408409992
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_TestChain6_muv1_TestChain6_muEmpty_L1MU6 ID#1462041536
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg001_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#1546253468
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#1601708571
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain5_ev1_L1EM3 ID#1756953305
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg001_HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#1777912350
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_TestChain6_muv1_TestChain10_muv1_L12MU6 ID#1790520567
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#1827802456
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain8_muv1_L1MU10 ID#2288364952
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#3476793373
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg002_HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#3575185873
+TriggerSummaryStep1                        2   0   DEBUG  +++ HLT_TestChain8_muv1step_L1MU6 ID#3588359947
+TriggerSummaryStep1                        2   0   DEBUG  +++ leg000_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#4283304400
+TriggerSummaryStep2                        2   0   DEBUG In summary 14 chains passed:
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#64374772
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg001_HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#122300819
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#171620884
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_2TestChain6_muEmpty_L12MU6 ID#241766530
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_2TestChain6_muv1_L12MU6 ID#1408409992
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg001_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#1546253468
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg000_HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#1601708571
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_TestChain5_ev1_L1EM3 ID#1756953305
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg001_HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#1777912350
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg000_HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#1827802456
+TriggerSummaryStep2                        2   0   DEBUG  +++ HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#3476793373
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg002_HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 ID#3575185873
+TriggerSummaryStep2                        2   0   DEBUG  +++ leg000_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#4283304400
+TriggerSummaryStep3                        2   0   DEBUG In summary 2 chains passed:
+TriggerSummaryStep3                        2   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep3                        2   0   DEBUG  +++ HLT_TestChain5_ev1_L1EM3 ID#1756953305
+TriggerSummaryStep1                        3   0   DEBUG In summary 10 chains passed:
+TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#64374772
+TriggerSummaryStep1                        3   0   DEBUG  +++ leg001_HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#122300819
+TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_TestChain20_muv1_L1MU10 ID#356594709
+TriggerSummaryStep1                        3   0   DEBUG  +++ leg001_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#1546253468
+TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep1                        3   0   DEBUG  +++ leg000_HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 ID#1827802456
+TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_TestChain8_muv1_L1MU10 ID#2288364952
+TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#3476793373
+TriggerSummaryStep1                        3   0   DEBUG  +++ HLT_TestChain8_muv1step_L1MU6 ID#3588359947
+TriggerSummaryStep1                        3   0   DEBUG  +++ leg000_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#4283304400
+TriggerSummaryStep2                        3   0   DEBUG In summary 6 chains passed:
+TriggerSummaryStep2                        3   0   DEBUG  +++ HLT_TestChain20_muv1_L1MU10 ID#356594709
+TriggerSummaryStep2                        3   0   DEBUG  +++ leg001_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#1546253468
+TriggerSummaryStep2                        3   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep2                        3   0   DEBUG  +++ HLT_TestChain8_muv1_L1MU10 ID#2288364952
+TriggerSummaryStep2                        3   0   DEBUG  +++ HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#3476793373
+TriggerSummaryStep2                        3   0   DEBUG  +++ leg000_HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 ID#4283304400
+TriggerSummaryStep3                        3   0   DEBUG In summary 3 chains passed:
+TriggerSummaryStep3                        3   0   DEBUG  +++ HLT_TestChain20_muv1_L1MU10 ID#356594709
+TriggerSummaryStep3                        3   0   DEBUG  +++ HLT_TestChain8_ev1_L1EM5 ID#1677577445
+TriggerSummaryStep3                        3   0   DEBUG  +++ HLT_TestChain8_muv1_L1MU10 ID#2288364952
+TriggerSummaryStep4                        3   0   DEBUG In summary 2 chains passed:
+TriggerSummaryStep4                        3   0   DEBUG  +++ HLT_TestChain20_muv1_L1MU10 ID#356594709
+TriggerSummaryStep4                        3   0   DEBUG  +++ HLT_TestChain8_muv1_L1MU10 ID#2288364952
+TrigSignatureMoniMT                                 INFO HLT_2TestChain4_muv1dr_L12MU6 #3176095517
+TrigSignatureMoniMT                                 INFO -- #3176095517 Events         0          0          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #3176095517 Features                             0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_2TestChain6_muEmpty_L12MU6 #241766530
+TrigSignatureMoniMT                                 INFO -- #241766530 Events          1          1          0          1          -          -          1          
+TrigSignatureMoniMT                                 INFO -- #241766530 Features                              0          6          -          -          
+TrigSignatureMoniMT                                 INFO HLT_2TestChain6_muv1_L12MU6 #1408409992
+TrigSignatureMoniMT                                 INFO -- #1408409992 Events         2          2          1          1          -          -          1          
+TrigSignatureMoniMT                                 INFO -- #1408409992 Features                             6          6          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain10_muv2_L1MU10 #3482819675
+TrigSignatureMoniMT                                 INFO -- #3482819675 Events         2          2          0          0          0          -          0          
+TrigSignatureMoniMT                                 INFO -- #3482819675 Features                             0          0          0          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain20_muv1_L1MU10 #356594709
+TrigSignatureMoniMT                                 INFO -- #356594709 Events          1          1          1          1          1          1          1          
+TrigSignatureMoniMT                                 INFO -- #356594709 Features                              1          1          1          1          
+TrigSignatureMoniMT                                 INFO HLT_TestChain5_ev1_L1EM3 #1756953305
+TrigSignatureMoniMT                                 INFO -- #1756953305 Events         3          3          2          2          2          -          2          
+TrigSignatureMoniMT                                 INFO -- #1756953305 Features                             4          4          4          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6 #171620884
+TrigSignatureMoniMT                                 INFO -- #171620884 Events          1          1          1          1          -          -          1          
+TrigSignatureMoniMT                                 INFO -- #171620884 Features                              2          2          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain5_ev1_TestChain8_ev1_L12EM3 #2709794009
+TrigSignatureMoniMT                                 INFO -- #2709794009 Events         0          0          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #2709794009 Features                             0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain5_ev2_L1EM7 #1760405581
+TrigSignatureMoniMT                                 INFO -- #1760405581 Events         0          0          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #1760405581 Features                             0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain5_ev3_L1EM7 #2336588294
+TrigSignatureMoniMT                                 INFO -- #2336588294 Events         1          1          1          1          -          -          1          
+TrigSignatureMoniMT                                 INFO -- #2336588294 Features                             2          2          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain5_gv1_L1EM7 #3893303900
+TrigSignatureMoniMT                                 INFO -- #3893303900 Events         1          1          1          -          -          -          1          
+TrigSignatureMoniMT                                 INFO -- #3893303900 Features                             2          -          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain6_muEmpty_L1MU6 #3519633296
+TrigSignatureMoniMT                                 INFO -- #3519633296 Events         0          0          0          0          0          0          0          
+TrigSignatureMoniMT                                 INFO -- #3519633296 Features                             0          0          0          0          
+TrigSignatureMoniMT                                 INFO HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5 #64374772
+TrigSignatureMoniMT                                 INFO -- #64374772 Events           2          2          2          1          -          -          1          
+TrigSignatureMoniMT                                 INFO -- #64374772 Features                               4          3          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain6_muv1_TestChain10_muv1_L12MU6 #3196402061
+TrigSignatureMoniMT                                 INFO -- #3196402061 Events         2          2          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #3196402061 Features                             0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain6_muv1_TestChain5_ev1dr_L12MU6 #3205587050
+TrigSignatureMoniMT                                 INFO -- #3205587050 Events         0          0          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #3205587050 Features                             0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain6_muv1_TestChain6_muEmpty_L1MU6 #293762221
+TrigSignatureMoniMT                                 INFO -- #293762221 Events          1          1          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #293762221 Features                              0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5 #3476793373
+TrigSignatureMoniMT                                 INFO -- #3476793373 Events         2          2          2          2          -          -          2          
+TrigSignatureMoniMT                                 INFO -- #3476793373 Features                             4          4          -          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain8_ev1_L1EM5 #1677577445
+TrigSignatureMoniMT                                 INFO -- #1677577445 Events         4          4          3          3          3          -          3          
+TrigSignatureMoniMT                                 INFO -- #1677577445 Features                             4          4          4          -          
+TrigSignatureMoniMT                                 INFO HLT_TestChain8_muv1_L1MU10 #2288364952
+TrigSignatureMoniMT                                 INFO -- #2288364952 Events         2          2          2          1          1          1          1          
+TrigSignatureMoniMT                                 INFO -- #2288364952 Features                             2          1          1          1          
+TrigSignatureMoniMT                                 INFO HLT_TestChain8_muv1step_L1MU6 #3588359947
+TrigSignatureMoniMT                                 INFO -- #3588359947 Events         2          2          2          -          -          -          2          
+TrigSignatureMoniMT                                 INFO -- #3588359947 Features                             3          -          -          -          
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/newJOtest.py b/Trigger/TrigValidation/TrigUpgradeTest/share/newJOtest.py
index 29835f3dd108a30d3b575b0d047e19ae98cd966e..8461b59495332fd60949158de2c550d875d26a08 100644
--- a/Trigger/TrigValidation/TrigUpgradeTest/share/newJOtest.py
+++ b/Trigger/TrigValidation/TrigUpgradeTest/share/newJOtest.py
@@ -54,8 +54,8 @@ flags.lock()
 from AthenaCommon.Constants import INFO,DEBUG,WARNING
 acc = MainServicesCfg( flags )
 
-from ByteStreamCnvSvc.ByteStreamConfig import TrigBSReadCfg
-acc.merge(TrigBSReadCfg( flags ))
+from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
+acc.merge(ByteStreamReadCfg( flags ))
 
 
 from TrigUpgradeTest.TriggerHistSvcConfig import TriggerHistSvcConfig
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/test/test_trigUpgr_emu_step_menu_processing_build.sh b/Trigger/TrigValidation/TrigUpgradeTest/test/test_trigUpgr_emu_step_menu_processing_build.sh
new file mode 100755
index 0000000000000000000000000000000000000000..47c1dc8522cb2baec6d7abe6d10ed149ce38ced6
--- /dev/null
+++ b/Trigger/TrigValidation/TrigUpgradeTest/test/test_trigUpgr_emu_step_menu_processing_build.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+# art-description: athenaMT HLT emulation test
+# art-type: build
+# art-include: master/Athena
+
+# This is a unit test of HLT Control Flow and should be moved to TriggerMenuMT
+
+export THREADS=1
+export EVENTS=4
+export SLOTS=1
+export JOBOPTION="TrigUpgradeTest/EmuStepProcessingTest.py"
+export REGTESTEXP="TrigSignatureMoniMT.*INFO HLT_.*|TrigSignatureMoniMT.*-- #[0-9]+ (Events|Features).*|TriggerSummaryStep.* chains passed:|TriggerSummaryStep.*+++ HLT_.*|TriggerSummaryStep.*+++ leg.*"
+export DOPERFMON=0
+export ATHENAOPTS=' -l DEBUG -c "DoMenu=True"'
+export REGTESTREF=`find_data.py TrigUpgradeTest/emu_step_menu_processing.ref`
+
+
+source exec_TrigUpgradeTest_art_athenaMT.sh
+source exec_TrigUpgradeTest_art_post.sh
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/test/test_trigUpgr_emu_step_processing_build.sh b/Trigger/TrigValidation/TrigUpgradeTest/test/test_trigUpgr_emu_step_processing_build.sh
index 43526aad4b551e39d122d7d98673918f3f3f26e7..f2397e8f3e380069d8011905f9a734af2a205158 100755
--- a/Trigger/TrigValidation/TrigUpgradeTest/test/test_trigUpgr_emu_step_processing_build.sh
+++ b/Trigger/TrigValidation/TrigUpgradeTest/test/test_trigUpgr_emu_step_processing_build.sh
@@ -11,7 +11,7 @@ export SLOTS=1
 export JOBOPTION="TrigUpgradeTest/EmuStepProcessingTest.py"
 export REGTESTEXP="TrigSignatureMoniMT.*INFO HLT_.*|TrigSignatureMoniMT.*-- #[0-9]+ (Events|Features).*|TriggerSummaryStep.* chains passed:|TriggerSummaryStep.*+++ HLT_.*|TriggerSummaryStep.*+++ leg.*"
 export DOPERFMON=0
-export ATHENAOPTS=" -l DEBUG"
+export ATHENAOPTS=' -l DEBUG -c "DoMenu=False"'
 export REGTESTREF=`find_data.py TrigUpgradeTest/emu_step_processing.ref`
 
 
diff --git a/Trigger/TrigValidation/TrigValTools/python/TrigValSteering/Common.py b/Trigger/TrigValidation/TrigValTools/python/TrigValSteering/Common.py
index 1c1d8c2cb5b11bef7ff33be6883a58aa2b567b9c..88351701d8ad734a763a7d2d4f1c51cc826e9e25 100644
--- a/Trigger/TrigValidation/TrigValTools/python/TrigValSteering/Common.py
+++ b/Trigger/TrigValidation/TrigValTools/python/TrigValSteering/Common.py
@@ -17,10 +17,11 @@ from AthenaCommon.Utils.unixtools import FindFile
 trigvalsteering_logging_level = logging.INFO
 
 # Dictionary of required prefixes identifying a package, see ATR-19735
-package_prefix_dict = {'TriggerTest':      'trig_',
-                       'TrigP1Test':       'trigP1_',
-                       'TrigAnalysisTest': 'trigAna_',
-                       'TrigUpgradeTest':  'trigUpgr_'}
+package_prefix_dict = {'TriggerTest':         'trig_',
+                       'TrigP1Test':          'trigP1_',
+                       'TrigAnalysisTest':    'trigAna_',
+                       'TrigUpgradeTest':     'trigUpgr_',
+                       'TrigInDetValidation': 'trigID_'}
 
 # Log file with all art-result statements
 art_result_summary = 'art-result-summary.log'
diff --git a/Trigger/TriggerCommon/TrigTier0/CMakeLists.txt b/Trigger/TriggerCommon/TrigTier0/CMakeLists.txt
index eda49c731aae22a854d4a2a76f857c63708fb691..b88371aeb5ec8df29af544168692244c209d9716 100644
--- a/Trigger/TriggerCommon/TrigTier0/CMakeLists.txt
+++ b/Trigger/TriggerCommon/TrigTier0/CMakeLists.txt
@@ -5,11 +5,6 @@
 # Declare the package name:
 atlas_subdir( TrigTier0 )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs( PUBLIC
-                          GaudiKernel )
-
 # Install files from the package:
-atlas_install_python_modules( python/*.py )
 atlas_install_joboptions( share/*.py )
 
diff --git a/Trigger/TriggerCommon/TrigTier0/python/NtupleProdFlags.py b/Trigger/TriggerCommon/TrigTier0/python/NtupleProdFlags.py
deleted file mode 100644
index 8cdcc77bc6f85fbaa6ea26630ad7b1ff54d6622f..0000000000000000000000000000000000000000
--- a/Trigger/TriggerCommon/TrigTier0/python/NtupleProdFlags.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-
-from AthenaCommon.JobProperties import JobProperty, JobPropertyContainer
-
-from AthenaCommon.Logging import logging 
-	
-__author__  = 'Emily Nurse <Emily.Nurse@cern.ch>, Joerg Stelzer <Joerg.Stelzer@cern.ch>'
-__doc__ = "Flags to steer the trigger ntuple production at the various sites and for development"
-
-
-###
-### property container class
-###
-class NtupleProductionFlags(JobPropertyContainer):
-    """Container for trigger ntuple production setup"""
-    log = logging.getLogger("TriggerFlags.NtupleProductionFlags")
-
-    def produceNtuples(self):
-        return self.ProductionLocation() != ''
-
-
-from TriggerJobOpts.TriggerFlags import TriggerFlags
-TriggerFlags.add_Container(NtupleProductionFlags)
-NPF = TriggerFlags.NtupleProductionFlags
-
-
-
-
-###
-### JobProperty SliceTuples: to group the different ntuples into files
-###
-class SliceTuples(JobProperty):
-    '''Slice specification, and Grouping
-
-    * A list of strings can be specified, each string corresponding to one root file.
-    
-    * Within a string a comma separated list of slices needs to be given, which specifies the
-    ntuples that are contained in that file. For example
-    
-    * e.g. TriggerFlags.NtupleProduction.SliceTuples = ["EGamma, Tau", "MinBias", "MET, Jet", "BPhys, BJet"]
-    '''
-    statusOn=True
-    allowedType=['list']
-    StoredValue=[]
-    # list of possible slice ntuples
-    definedSlices=['EGamma', 'Muon', 'MuonL2', 'MuonEF', 'Tau', 'Jet', 'MET', 'MinBias', 'BPhys', 'BJet','L1Calo','TrigMenu']
-    
-    def _do_action(self):
-        """Check if only defined slices are requested"""
-        if self.get_Value()==[]: return
-        for sl in ','.join(self.get_Value()).split(','):
-            if not sl.strip() in self.definedSlices:
-                raise RuntimeError ('Slice "%s" is not a slice that has an ntuple defined! Must be on of %r !' % (sl,self.definedSlices))
-
-    def doSlice(self,slicename):
-        """Checks if a slice was requested
-
-        This is for the individual slice to ease the entrance to their
-        ntuple production. It respects the DisabledSlices Flag
-        """
-        if slicename not in self.definedSlices:
-            raise RuntimeError ('Slice "%s" is not a slice that has an ntuple defined! Must be on of %r !' % (slicename,self.definedSlices))
-        inSliceTuples = slicename in [sl.strip() for sl in ','.join(self.get_Value()).split(',')]
-        inDisabledSlices = slicename in [sl.strip() for sl in NPF.DisabledSlices()]
-        return inSliceTuples and not inDisabledSlices
-
-NPF.add_JobProperty(SliceTuples)
-    
-
-
-###
-### JobProperty FileNames: File names for the different groups
-###
-class FileNames(JobProperty):
-    '''File name specification for each group of slices
-
-    * A list of filenames must be specified, each corresponding to the entry in SliceTuples.
-
-    * Must always be set after the SliceTuples are specified, because we are checking that the length is the same
-    
-    * e.g. TriggerFlags.NtupleProduction.FileNames = ["EgammaTau.root", "MinBiasValidation.root", "MissingETandJet.root", "B.root"]
-    '''
-    statusOn=True
-    allowedType=['list']
-    StoredValue=[]
-
-    def _do_action(self):
-        """Check if number of filename agrees with number of slice groups"""
-        if not NPF.SliceTuples.isDefault() and len(NPF.SliceTuples()) != len(self.get_Value()):
-            raise RuntimeError ("Expected %i root file names, since that many slice groups were defined" % len(NPF.SliceTuples()))
-
-    def forSlice(self,slicename): 
-        """return the root file name for an individual slice
-        
-        This is not to be used in the production, where one algorithm
-        will write all the files. This function respects the DisabledSlices flag
-        """
-
-        if not NPF.SliceTuples.doSlice(slicename):
-            return ""
-
-        if len(self.get_Value())==0:
-                NPF.log.error("NPF.FileNames is empty, please provide at least one file name")
-
-        for index, group in enumerate(NPF.SliceTuples()):
-            inSliceGroup = slicename in [sl.strip() for sl in group.split(',')]
-            if inSliceGroup:
-                if index>=len(self.get_Value()): index=0
-                return self.get_Value()[index]
-
-        assert RuntimeError, "Should not get here"
-
-        
-NPF.add_JobProperty(FileNames)
-
-
-###
-### JobProperty DisabledSlices: To quickly disable a certain slice from NTuple Production
-###
-class DisabledSlices(JobProperty):
-    '''Names of slices (list) to be excluded from production'''
-    statusOn=True
-    allowedType=['list']
-    StoredValue=[]
-
-    def _do_action(self):
-        """Check if only defined slices are listed"""
-        sl = [x for x in self.get_Value() if x not in NPF.SliceTuples.definedSlices]
-        if sl:
-            raise RuntimeError ('Slices %s do not have an ntuple defined! Must be on of %r !' % (','.join(sl),NPF.SliceTuples.definedSlices))
-
-NPF.add_JobProperty(DisabledSlices)
-
-
-
-###
-### JobProperty ProductionLocation: to specify where to run and setting the defaults
-###
-class ProductionLocation(JobProperty):
-    '''Production environment'''
-    statusOn=True
-    allowedType=['string']
-    allowedValues=['','Tier0','Tier1','CAF','User']
-    StoredValue=''
-    
-    def _do_action(self):
-        """Define ntuple production at the different places"""
-
-        if NPF.SliceTuples.is_locked(): NPF.SliceTuples.unlock()
-        #if NPF.FileNames.is_locked(): NPF.FileNames.unlock()
-
-        #
-        # Here the default values for ntuple production are set
-        #
-        if self.get_Value() == '':
-            NPF.SliceTuples.set_Value([])
-            NPF.FileNames.set_Value([])
-            NPF.log.info("Disabling Ntuple Production")
-
-        elif self.get_Value() == 'Tier0':
-            NPF.SliceTuples.set_Value(['MinBias, EGamma, Tau, Muon, TrigMenu'])
-            #NPF.FileNames.set_Value(['TriggerNT.root'])
-            
-        elif self.get_Value() == 'Tier1':
-            NPF.SliceTuples.set_Value(['L1Calo'])
-            #NPF.FileNames.set_Value(['TriggerNT.root'])
-            
-        elif self.get_Value() == 'CAF':
-            NPF.SliceTuples.set_Value(['MinBias', 'EGamma', 'Tau', 'Muon', 'L1Calo'])
-            if NPF.FileNames()==[]:
-                NPF.FileNames.set_Value(['MinBiasNT.root', 'EGammaNT.root', 'TauNT.root', 'MuonNT.root', 'L1CaloNT.root'])
-            
-        elif self.get_Value() == 'User':
-            pass
-
-        # lock the properties
-        if self.get_Value()!= 'User':
-            NPF.SliceTuples.lock()
-
-        if self.get_Value()!= 'User' and self.get_Value()!= 'Tier0':
-            NPF.FileNames.lock()
-
-NPF.add_JobProperty(ProductionLocation)
diff --git a/Trigger/TriggerCommon/TrigTier0/python/__init__.py b/Trigger/TriggerCommon/TrigTier0/python/__init__.py
deleted file mode 100644
index 44eb2f950ae699b90ee6d1e64a52c9e5ac764e2b..0000000000000000000000000000000000000000
--- a/Trigger/TriggerCommon/TrigTier0/python/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
-__version__ = '1.0.0'
-__author__  = 'Moritz.Backes@cern.ch'
-__all__ = [ 'NtupleProdFlags' ]
-
-
diff --git a/Trigger/TriggerCommon/TrigTier0/share/TrigConfigForPrivateRerunHLT.py b/Trigger/TriggerCommon/TrigTier0/share/TrigConfigForPrivateRerunHLT.py
deleted file mode 100644
index 5ee24cd523354172d857838b2cb8a7ccad112ead..0000000000000000000000000000000000000000
--- a/Trigger/TriggerCommon/TrigTier0/share/TrigConfigForPrivateRerunHLT.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# This sets up the trigger config for a BStoESD job
-# to use the HLT output XML file generated by a previous BStoBS step
-# and a fixed LVL1 file from the release which should be what was used to rerun the trigger over BS
-# It is intended for private trigger reprocessing only.
-# Contact:  Clemencia Mora or  trigger configuration experts
-
-##preInclude for all steps but enable only for RAWtoESD
-##don't set this in ESDtoAOD, it works with HLTonline since DS folders are stored in ESD metadata
-
-from RecExConfig.RecFlags import rec
-if rec.readRDO and rec.doESD:
-    from TriggerJobOpts.TriggerFlags import TriggerFlags as tf
-    tf.inputHLTconfigFile.set_Value_and_Lock("outputHLTconfig.xml")
-    tf.inputLVL1configFile.set_Value_and_Lock("TriggerMenuXML/LVL1config_InitialBeam_v3.xml")
-    tf.configForStartup.set_Value_and_Lock("HLToffline")
-    tf.configurationSourceList.set_Value_and_Lock(['xml'])
-    tf.readHLTconfigFromXML.set_Value_and_Lock(True)
-    tf.readLVL1configFromXML.set_Value_and_Lock(True)
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py
index cc9977e247f1872f768a0d50380dd21ebe8b271d..fa7e32f0ef0bdcbafa21d4f8a94ed7d4403de4a2 100755
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py
@@ -62,7 +62,7 @@ class GenerateMenuMT(object):
         self.signaturesToGenerate = []
         self.allSignatures = ['Egamma', 'Muon', 'Jet', 'Bjet', 'Bphysics', 'MET', 'Tau',
                               'HeavyIon', 'Beamspot', 'Cosmic', 'EnhancedBias',
-                              'Monitor', 'Calib', 'Streaming', 'Combined', 'MinBias'] #, AFP
+                              'Monitor', 'Calib', 'Streaming', 'Combined', 'MinBias', 'Test'] #, AFP
         self.calibCosmicMonSigs = ['Streaming','Monitor','Beamspot','Cosmic'] #others not implemented yet ['Beamspot', 'Cosmic', 'EnhancedBias', 'Monitor', 'Calib', 'Streaming']
 
         # flags
@@ -82,8 +82,8 @@ class GenerateMenuMT(object):
         self.doMonitorChains        = True
         self.doBeamspotChains       = True
         self.doEnhancedBiasChains   = True
-        self.doTestChains           = True
         self.doCombinedChains       = True
+        self.doTestChains           = True
 
 
     def setTriggerConfigHLT(self):
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTMenuJSON.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTMenuJSON.py
index 2b42306e92f30bbe059d3f905d58d0f0cb3c2b03..8e34146f6d1dff33b35141a03cb2fe0c9eaad2fd 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTMenuJSON.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTMenuJSON.py
@@ -74,47 +74,61 @@ def __getSequencerAlgs(stepsData):
 def __generateJSON( chainDicts, chainConfigs, HLTAllSteps, menuName, fileName ):
     """ Generates JSON given the ChainProps and sequences
     """
-    menuDict = odict([ ("filetype", "hltmenu"), ("name", menuName), ("chains", []), ("sequencers", odict()) ])
+    # Menu dictionary that is used to create the JSON content
+    menuDict = odict([ ("filetype", "hltmenu"), ("name", menuName), ("chains", odict()), ("streams", odict()), ("sequencers", odict()) ])
 
-    # List of steps data
+    # List of steps data for sequencers
     stepsData = __getStepsDataFromAlgSequence(HLTAllSteps)
 
     from TriggerMenuMT.HLTMenuConfig.Menu import StreamInfo
     for chain in chainDicts:
-        streamDicts = []
-        streamTags = StreamInfo.getStreamTags(chain["stream"])
-        for streamTag in streamTags:
-            streamDicts.append({"name": streamTag.name(),
-                                "type": streamTag.type(),
-                                "obeyLB": streamTag.obeysLumiBlock(),
-                                "forceFullEventBuilding": streamTag.forceFullEventBuilding()})
-
+        # Prepare information for stream list and fill separate dictionary
+        chainStreamTags = []
+        for streamName in chain["stream"]:
+            streamTag = StreamInfo.getStreamTag(streamName)
+            # Stream needs to have been defined in StreamInfo.py otherwise is not added to JSON
+            if streamTag is None:
+                __log.error('Stream %s does not have StreamTags defined excluding from JSON', streamName)
+                continue
+            # Add stream to the chain
+            chainStreamTags.append(streamName)
+            # If not already listed, add stream details to stream dictionary
+            if streamName not in menuDict["streams"]:
+                menuDict["streams"][streamName] = odict([
+                    ("name", streamName),
+                    ("type", streamTag.type()),
+                    ("obeyLB", streamTag.obeysLumiBlock()),
+                    ("forceFullEventBuilding", streamTag.forceFullEventBuilding())
+                ])
+
+        # Find L1 Threshold information for current chain
         l1Thresholds  = []
         [ l1Thresholds.append(p['L1threshold']) for p in chain['chainParts'] ]
 
-        chainDict = odict([ 
+        # Now have all information to write the chain to the menu dictionary
+        chainName = chain["chainName"]
+        menuDict["chains"][chainName] = odict([
             ("counter", chain["chainCounter"]),
-            ("name", chain["chainName"]),
+            ("name", chainName),
             ("nameHash", chain["chainNameHash"]),
             ("l1item", chain["L1item"]),
             ("l1thresholds", l1Thresholds),
             ("groups", chain["groups"]),
-            ("streams", streamDicts),
-            ("sequencers", __getChainSequencers(stepsData, chain["chainName"]) )
+            ("streams", chainStreamTags),
+            ("sequencers", __getChainSequencers(stepsData, chainName) )
         ])
 
-        menuDict["chains"].append( chainDict )
-
     # All algorithms executed by a given Sequencer
     menuDict["sequencers"].update( __getSequencerAlgs(stepsData) )
 
-    __log.info( "Writing trigger menu to %s", fileName )
+    # Menu dictionary now completed, write to JSON
+    __log.info( "Writing HLT Menu JSON to %s", fileName )
     with open( fileName, 'w' ) as fp:
         json.dump( menuDict, fp, indent=4, sort_keys=False )
 
 
 def generateJSON():
-    __log.info("Generating HLT JSON config in the rec-ex-common job")
+    __log.info("Generating HLT Menu JSON in the rec-ex-common job")
     from TriggerJobOpts.TriggerFlags import TriggerFlags
     from TriggerMenuMT.HLTMenuConfig.Menu.TriggerConfigHLT import TriggerConfigHLT
     from AthenaCommon.AlgSequence import AlgSequence
@@ -127,7 +141,7 @@ def generateJSON():
                            getHLTMenuFileName() )
     
 def generateJSON_newJO( chainDicts, chainConfigs, HLTAllSteps ):
-    __log.info("Generating HLT JSON config in the new JO")
+    __log.info("Generating HLT Menu JSON in the new JO")
     from AthenaConfiguration.AllConfigFlags import ConfigFlags
 
     return __generateJSON( chainDicts, 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_emu_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_emu_v1.py
index 58a34e266450a824d76e6ecc2c0e2244878a8e15..99de9df2c1e65392fb4396dfa4974b58db5a65a0 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_emu_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_emu_v1.py
@@ -2,11 +2,14 @@
 
 #------------------------------------------------------------------------#
 #------------------------------------------------------------------------#
+from TriggerMenuMT.HLTMenuConfig.Menu.ChainDefInMenu import ChainProp
 from TriggerMenuMT.HLTMenuConfig.Menu.MenuPrescaleConfig import addSliceChainsToPrescales
 
+
 def setupMenu():
 
     from TriggerJobOpts.TriggerFlags          import TriggerFlags
+    from AthenaCommon.Logging                 import logging
 
     # IMPORTANT: Needs to be commented in again!
     #PhysicsStream = "Main"
@@ -21,30 +24,54 @@ def setupMenu():
     # be aware that it is necessary to leave at least one chain in the muon slice
     # otherwise athenaHLT will seg-fault 
     #---------------------------------------------------------------------
-
-    TriggerFlags.Slices_all_setOff()
+    log = logging.getLogger( __name__ )
+    log.info('Executing menu....')
 
     TriggerFlags.TestSlice.signatures = [
-        #this seems to do nothing
-        # ChainProp(name='HLT_mu20_L1MU10', groups=SingleMuonGroup),
-        # ChainProp(name='HLT_e5_e8_L12EM3', groups=SingleMuonGroup),         
-        ]
+        # muons
+        ChainProp(name='HLT_TestChain8_muv1step_L1MU6', stream=['Main'], groups=['RATE:Test','BW:Other'] ),
+        ChainProp(name='HLT_TestChain8_muv1_L1MU10', stream=['Main'], groups=['RATE:Test','BW:Other'] ),
+        ChainProp(name='HLT_TestChain20_muv1_L1MU10',stream=['Main'], groups=['RATE:Test','BW:Other'] ),
+        ChainProp(name='HLT_TestChain10_muv2_L1MU10',stream=['Main'], groups=['RATE:Test','BW:Other'] ),
+        ChainProp(name='HLT_TestChain6_muEmpty_L1MU6',  stream=['Main'], groups=['RATE:Test','BW:Other'] ),
 
-    TriggerFlags.MuonSlice.signatures = [
-        #['HLT_mu20_L1MU10',   [], [PhysicsStream], ['RATE:SingleMuon', 'BW:Muon']],
-    ]
-    TriggerFlags.EgammaSlice.signatures = [
-        #['HLT_e7_etcut_L1EM3',      ['L1_EM3', ['EM3']],  [PhysicsStream], ['RATE:SingleElectron', 'BW:Electron']],
+        # egamma
+        ChainProp(name='HLT_TestChain5_ev1_L1EM3', stream=['Main'], groups=['RATE:Test','BW:Other'] ),
+        ChainProp(name='HLT_TestChain8_ev1_L1EM5', stream=['Main'], groups=['RATE:Test','BW:Other'] ),
+        ChainProp(name='HLT_TestChain5_ev2_L1EM7', stream=['Main'], groups=['RATE:Test','BW:Other'] ),
+        ChainProp(name='HLT_TestChain5_ev3_L1EM7', stream=['Main'], groups=['RATE:Test','BW:Other'] ),
+        ChainProp(name='HLT_TestChain5_gv1_L1EM7', stream=['Main'], groups=['RATE:Test','BW:Other'] ),
+
+        # combined
+        ChainProp(name='HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5', stream=['Main'], groups=['RATE:Test','BW:Other'] ), #serial         
+        ChainProp(name='HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5',  stream=['Main'], groups=['RATE:Test','BW:Other'] ),
+        ChainProp(name='HLT_TestChain5_ev1_TestChain8_ev1_L12EM3',      stream=['Main'], groups=['RATE:Test','BW:Other']),
+      #  ChainProp(name='HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_EM5_L12MU6', stream=['Main'], groups=['RATE:Test','BW:Other']   ),
+        ChainProp(name='HLT_2TestChain6_muv1_L12MU6',                   stream=['Main'], groups=['RATE:Test','BW:Other']   ),
+        ChainProp(name='HLT_TestChain6_muv1_TestChain10_muv1_L12MU6',   stream=['Main'], groups=['RATE:Test','BW:Other']  ),        
+        ChainProp(name='HLT_2TestChain6_muEmpty_L12MU6',                stream=['Main'], groups=['RATE:Test','BW:Other']), #may differ from manual
+        ChainProp(name='HLT_TestChain6_muv1_TestChain5_ev1dr_L12MU6', stream=['Main'], groups=['RATE:Test','BW:Other'] ), 
+        ChainProp(name='HLT_2TestChain4_muv1dr_L12MU6', stream=['Main'], groups=['RATE:Test','BW:Other'] ),
+                                                                                       
+    # problem here    ChainProp(name='HLT_TestChain6_muv1_TestChain6_muEmpty_L1MU6',  l1SeedThresholds=['MU6','FSNOSEED'],  stream=['Main'], groups=['RATE:Test','BW:Other']) # revisit this
         
-    ]
-    TriggerFlags.CombinedSlice.signatures = [
-        #['e8_mu8_L1EM6_MU6',	   [], [PhysicsStream], ['RATE:SingleMuon', 'BW:Muon']],
-    ]
-    TriggerFlags.JetSlice.signatures = [ ]
+        ]
+
+
+    
+    TriggerFlags.EgammaSlice.signatures =  [
+    # ElectronChains----------
+#        ChainProp(name='HLT_e3_etcut_L1EM3', stream=['Main'], groups=['RATE:Test','BW:Other'])
+        ]
+
+
+    TriggerFlags.MuonSlice.signatures = []
+    TriggerFlags.CombinedSlice.signatures = []
+    TriggerFlags.JetSlice.signatures = []
     TriggerFlags.BjetSlice.signatures = [] 
     TriggerFlags.METSlice.signatures = []
     TriggerFlags.TauSlice.signatures = []
-    TriggerFlags.BphysicsSlice.signatures = [ ]
+    TriggerFlags.BphysicsSlice.signatures  = []
     TriggerFlags.HeavyIonSlice.signatures  = []
     TriggerFlags.BeamspotSlice.signatures  = []   
     TriggerFlags.MinBiasSlice.signatures   = []    
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
index 7828ddcdd6724a4e614062b817668759dcdaecc8..7b9105fe4d0ed402e1f9e18029d29a9099ac2515 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
@@ -29,6 +29,7 @@ def setupMenu():
 
     TriggerFlags.TestSlice.signatures = TriggerFlags.TestSlice.signatures() + []
 
+
     TriggerFlags.MuonSlice.signatures = TriggerFlags.MuonSlice.signatures() + [
         #ART-19985
         ChainProp(name='HLT_mu6_idperf_L1MU6', groups=SingleMuonGroup),
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py
index bff457151ad634ce7e7c36b03ceb59bef78f7a22..60c0cebdab7092fa24f270e66344de69838333f6 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py
@@ -65,7 +65,8 @@ TestChainParts = {
     'L1threshold'    : '',
     'signature'      : ['Test'],
     'chainPartName'  : '',
-    'multiplicity'   : '',    
+    'multiplicity'   : '',
+    'extra'          : ['muv1', 'muv1step', 'muv2', 'ev1', 'ev2', 'ev3', 'gv1', 'muEmpty', 'ev1dr', 'muv1dr'],
     'trigType'       : ['TestChain'],
     'threshold'      : '',
     'addInfo'        : [''],
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Test/GenerateTestChainDefs.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Test/GenerateTestChainDefs.py
index 2e1c1fb48d5552bd8aa106cf50f96a638d526bdb..d5abe5ffdf7fe22f42cd82f2f8cc6df24295f4a5 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Test/GenerateTestChainDefs.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Test/GenerateTestChainDefs.py
@@ -2,6 +2,7 @@
 
 from TriggerMenuMT.HLTMenuConfig.Menu.ChainDictTools import splitChainDict
 from TriggerMenuMT.HLTMenuConfig.Test.TestDef import TestChainConfiguration as TestChainConfiguration
+from TriggerMenuMT.HLTMenuConfig.Menu.ChainMerging import mergeChainDefs
 
 import pprint
 from AthenaCommon.Logging import logging
@@ -18,23 +19,17 @@ def generateChainConfigs( chainDict ):
     listOfChainDefs = []
 
     for subChainDict in listOfChainDicts:
-        
+        log.debug('Assembling subChainsDict %s for chain %s', len(listOfChainDefs), subChainDict['chainName'] )
         Test = TestChainConfiguration(subChainDict).assembleChain() 
 
         listOfChainDefs += [Test]
-        log.debug('length of chaindefs %s', len(listOfChainDefs) )
         
 
     if len(listOfChainDefs)>1:
-        log.warning("Implement case for multiplicity >1  test chain!!") 
-        theChainDef = listOfChainDefs[0] #needs to be implemented properly
+        theChainDef = mergeChainDefs(listOfChainDefs, chainDict)
     else:
         theChainDef = listOfChainDefs[0]
 
-    log.debug("theChainDef.name: %s" , theChainDef.name)
-    log.debug("theChainDef.seed: %s" , theChainDef.seed)
-    log.debug("theChainDef.ChainSteps: %s" , theChainDef.steps)
-
     return theChainDef
 
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Test/TestDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Test/TestDef.py
index 8b02f8d6e2a36a96d09c0295dd4d69952c904f21..bb4e0ccac606b017bdf0d447e178382b6eb1c878 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Test/TestDef.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Test/TestDef.py
@@ -7,7 +7,64 @@ log = logging.getLogger("TriggerMenuMT.HLTMenuConfig.Test.TestDef")
 
 from TriggerMenuMT.HLTMenuConfig.Menu.ChainConfigurationBase import ChainConfigurationBase
 
+from TrigUpgradeTest.HLTSignatureConfig import  muMenuSequence, elMenuSequence, gamMenuSequence
+from TrigUpgradeTest.HLTSignatureHypoTools import dimuDrComboHypoTool
 
+#--------------------------------------------------------
+# fragments generating config will be functions in new JO
+#--------------------------------------------------------
+
+
+# Muons
+def muCfg(step,reconame, hyponame):
+    return muMenuSequence(step,reconame, hyponame)
+
+def muCfg111(flags):
+    return muCfg(step="1",reconame="v1", hyponame="v1")
+
+def muCfg211(flags):
+    return muCfg(step="2",reconame="v1", hyponame="v1")
+
+def muCfg311(flags):
+    return muCfg(step="3",reconame="v1", hyponame="v1")
+
+def muCfg322(flags):
+    return muCfg(step="3",reconame="v2", hyponame="v2")
+
+def muCfg411(flags):
+    return muCfg(step="4",reconame="v1", hyponame="v1")
+
+def muCfg222(flags):
+    return muCfg(step="2",reconame="v2", hyponame="v2")
+
+
+# Egamma
+def elCfg(step,reconame, hyponame):
+    return elMenuSequence(step,reconame, hyponame)
+
+def gamCfg(step,reconame, hyponame):
+    return gamMenuSequence(step,reconame, hyponame)
+
+def elCfg111(flags):
+    return elCfg(step="1",reconame="v1", hyponame="v1")
+
+def elCfg211(flags):
+    return elCfg(step="2",reconame="v1", hyponame="v1")
+
+def elCfg222(flags):
+    return elCfg(step="2",reconame="v2", hyponame="v2")
+
+def elCfg223(flags):
+    return elCfg(step="2",reconame="v2", hyponame="v3")
+
+def elCfg311(flags):
+    return elCfg(step="3",reconame="v1", hyponame="v1")
+
+def gamCfg111(flags):
+    return gamCfg(step="1",reconame="v1", hyponame="v1")
+
+
+ 
 #----------------------------------------------------------------
 # Class to configure chain
 #----------------------------------------------------------------
@@ -26,10 +83,94 @@ class TestChainConfiguration(ChainConfigurationBase):
         # define here the names of the steps and obtain the chainStep configuration 
         # --------------------
 
+        stepDictionary = {
+            #muons
+            'muv1step': ['Step_mu11'],
+            'muv1':     ['Step_mu11', 'Step_mu21', 'Step_mu31', 'Step_mu41'], 
+            'muv2':     ['Step_mu11', 'Step_mu22', 'Step_mu31'],
+            'muEmpty' : ['Step_mu11' ,'Step_empty' ,'Step_mu32', 'Step_mu41'],
+            'muv1dr' : ['Step_mu11Dr', 'Step_mu21'],
+            #egamma
+            'ev1':     ['Step_em11', 'Step_em21', 'Step_em31'],
+            'ev2':     ['Step_em11', 'Step_em22'], 
+            'ev3':     ['Step_em11', 'Step_em23'],
+            'gv1':     ['Step_gam11'],
+            'ev1dr' : ['Step_em11Dr', 'Step_em21Dr']
+        }
+
+        log.debug('test chain part = ' + str(self.chainPart))
+        key = self.chainPart['extra']
+
+        log.debug('testChain key = ' + key)
+        if key in stepDictionary:
+            steps=stepDictionary[key]
+        else:
+            raise RuntimeError("Chain configuration unknown for electron chain with key: " + key )
+        
+        for step in steps:
+            log.debug('Adding TestSlice trigger step ' + str(step))
+            chainstep = getattr(self, step)()
+            chainSteps+=[chainstep]
+
+            
         myChain = self.buildChain(chainSteps)
         return myChain
         
             
 
-        
-                
+    ## Muons    
+    
+    def Step_mu11(self):
+        return self.getStep(1,"mu11",[ muCfg111 ])
+
+    def Step_mu21(self):
+        return self.getStep(2,"mu21",[ muCfg211 ])
+
+    def Step_mu11Dr(self):
+        return self.getStep(1,"mu11",[ muCfg111 ], comboTools=[dimuDrComboHypoTool])
+
+    def Step_mu21Dr(self):
+        return self.getStep(2,"mu21",[ muCfg211 ], comboTools=[dimuDrComboHypoTool])
+
+    def Step_mu22(self):
+        return self.getStep(2,"mu22",[ muCfg222 ])
+
+    def Step_mu31(self):
+        return self.getStep(3,"mu31",[ muCfg311 ])
+
+    def Step_mu32(self):
+        return self.getStep(3,"mu32",[ muCfg322 ])
+
+    def Step_mu41(self):
+        return self.getStep(4,"mu11",[ muCfg411 ])
+
+    def Step_empty(self):
+        return self.getStep(2, "empty", [])
+
+
+    # Electrons
+
+    def Step_em11(self):
+        return self.getStep(1,"em11",[ elCfg111 ])
+    
+    def Step_em11Dr(self):
+        return self.getStep(1,"em11",[ elCfg111 ], comboTools=[dimuDrComboHypoTool])
+
+    def Step_em21(self):
+        return self.getStep(2,"em21",[ elCfg211 ])
+
+    def Step_em21Dr(self):
+        return self.getStep(2,"em21",[ elCfg211 ], comboTools=[dimuDrComboHypoTool])
+
+    def Step_em22(self):
+        return self.getStep(2,"em22",[ elCfg222 ])
+
+    def Step_em23(self):
+        return self.getStep(2,"em23",[ elCfg223 ])
+
+    def Step_em31(self):
+        return self.getStep(3,"em31",[ elCfg311 ])
+
+    def Step_gam11(self):
+        return self.getStep(1,"gam11",[ gamCfg111 ])
+
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/scripts/menu_config_tests.py b/Trigger/TriggerCommon/TriggerMenuMT/scripts/menu_config_tests.py
index 2ae3d786e0f94666a437e5a31332ee85f136c0b9..b744da8dbc666d61ddbb921767d136d3ab705998 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/scripts/menu_config_tests.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/scripts/menu_config_tests.py
@@ -34,7 +34,7 @@ class UniqueChainNames(MenuVerification):
             description="Chain names are unique")
 
     def run(self, config):
-        names = [chain["name"] for chain in config["chains"]]
+        names = [chain["name"] for chain in config["chains"].values()]
         counts = Counter(names)
         self.failures = [chain for chain, count
                          in counts.items() if count > 1]
@@ -47,7 +47,7 @@ class ConsecutiveChainCounters(MenuVerification):
 
     def run(self, config):
         counters = [chain["counter"] for chain
-                    in config["chains"]]
+                    in config["chains"].values()]
         prev_counter = 0
         for count in counters:
             if count != prev_counter + 1:
@@ -80,7 +80,7 @@ class StructuredChainNames(MenuVerification):
 
     def run(self, config):
         if self._trigger_level == TriggerLevel.HLT:
-            names = [chain["name"] for chain in config["chains"]]
+            names = [chain["name"] for chain in config["chains"].values()]
             self.failures = [n for n in names
                              if not self._name_matches_hlt_convention(n)]
         elif self._trigger_level == TriggerLevel.L1:
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/scripts/verify_menu_config.py b/Trigger/TriggerCommon/TriggerMenuMT/scripts/verify_menu_config.py
index d4e512a10bf513be1681a032f5abf4de3762bf9e..8620227d8878a00792b06626d99e0c4f2ade4772 100755
--- a/Trigger/TriggerCommon/TriggerMenuMT/scripts/verify_menu_config.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/scripts/verify_menu_config.py
@@ -14,6 +14,7 @@ import os
 import sys
 import argparse
 
+from collections import OrderedDict as odict
 from AthenaCommon.Logging import logging
 from menu_config_tests import TriggerLevel, menu_tests
 
@@ -44,7 +45,7 @@ def load_and_verify(file_path, trigger_level):
         log.error("'{}' is not a JSON file".format(file_path))
     else:
         with open(file_path, "r") as config_file:
-            config = json.load(config_file)
+            config = json.load(config_file, object_pairs_hook = odict)
 
         return verify(config, trigger_level)
 
@@ -104,7 +105,7 @@ if __name__ == "__main__":
         for failed_test in result["failures"]:
             log.error("'{}' failed for: {}".format(
                 failed_test.description,
-                ", ".join(failed_test.failures)))
+                ", ".join([str(i) for i in failed_test.failures])))
 
         if result["failures"]:
             any_failures = True