diff --git a/Calorimeter/CaloCalibHitRec/share/jobOptions_SimpleCaloRec.py b/Calorimeter/CaloCalibHitRec/share/jobOptions_SimpleCaloRec.py
index 5e54ab034cd58fa3afbf10064a250cb09dff43f5..7151b5fd3f43b67c84aaf1d4e21cbedfd0277f98 100644
--- a/Calorimeter/CaloCalibHitRec/share/jobOptions_SimpleCaloRec.py
+++ b/Calorimeter/CaloCalibHitRec/share/jobOptions_SimpleCaloRec.py
@@ -63,8 +63,6 @@ include( "TileConditions/TileConditions_jobOptions.py" )
 include( "CaloIdCnv/CaloIdCnv_joboptions.py" )
 include( "TileIdCnv/TileIdCnv_jobOptions.py" )
 include( "LArDetDescr/LArDetDescr_joboptions.py" )
-from CaloTools.CaloNoiseToolDefault import CaloNoiseToolDefault
-ToolSvc += CaloNoiseToolDefault()
 
 # data from pool
 include( "EventAthenaPool/EventAthenaPool_joboptions.py" )
diff --git a/Calorimeter/CaloTools/src/CaloNoiseCondAlg.cxx b/Calorimeter/CaloTools/src/CaloNoiseCondAlg.cxx
index 20e587f11576a9cbeb2ce5899b4793f7f20c6f06..6dc716e4997e4a8414b9a6b37f8a5c8e8c381bfd 100644
--- a/Calorimeter/CaloTools/src/CaloNoiseCondAlg.cxx
+++ b/Calorimeter/CaloTools/src/CaloNoiseCondAlg.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "CaloNoiseCondAlg.h" 
@@ -36,10 +36,9 @@ StatusCode CaloNoiseCondAlg::initialize() {
 
   ATH_CHECK( m_hvCorrKey.initialize(m_useHVCorr) );
 
-  if (m_lumi0<0) {
-    if (m_lumiFolderKey.initialize().isFailure()) {
+  const bool doLumiFolderInit = m_lumi0 < 0;
+  if (m_lumiFolderKey.initialize(doLumiFolderInit).isFailure()) {
       ATH_MSG_ERROR("Luminosity set to < 0 but failed to initialize LumiFolder");
-    }
   }
  
   ATH_CHECK( m_cablingKey.initialize() );
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc
index 71a685760f5b141c32ed9ef4c7d083ec427a0b51..b42868087bdec42c19ce0e919b55aedc3e1c725d 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 /**
  * @file AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc
@@ -9,6 +9,7 @@
  */
 
 
+#include "AthenaPoolCnvSvc/exceptions.h"
 #include "AthContainers/tools/copyThinned.h"
 #include "AthenaKernel/getThinningCache.h"
 
@@ -46,8 +47,13 @@ T_AthenaPoolAuxContainerCnv<AUXSTORE, TPCNVS...>::createPersistentWithKey( AUXST
   try {
      const SG::ThinningInfo* info = SG::getThinningInfo (key2);
      return SG::copyThinned (*trans, info).release();
-  }catch( const std::exception &ex ) {
-     throw std::runtime_error( std::string("Exception from AuxContainer Thinning of type: ") + typeid(ex).name() + ", msg: " + ex.what());
+  }
+  catch( const std::exception &ex ) {
+    AthenaPoolCnvSvc::throwExcCaughtException (__PRETTY_FUNCTION__,
+                                               "thinning aux container",
+                                               ex,
+                                               typeid(AUXSTORE),
+                                               key);
   }
 }
 
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.icc
index 5b3708838674f71d97d998f2e71728ca51b50f74..d1c6f94e839db69cc472c9a725603840665b451a 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.icc
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.icc
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 /** @file T_AthenaPoolCnvBase.icc
@@ -22,6 +22,7 @@
 #include "AthenaKernel/CLASS_DEF.h"
 #include "AthenaKernel/ClassName.h"
 #include "AthenaKernel/StorableConversions.h"
+#include "AthenaPoolCnvSvc/exceptions.h"
 
 //__________________________________________________________________________
 template <class T>
@@ -85,16 +86,19 @@ StatusCode T_AthenaPoolCnvBase<T>::DataObjectToPool(IOpaqueAddress* pAddr, DataO
 template <class T>
 StatusCode T_AthenaPoolCnvBase<T>::PoolToDataObject(DataObject*& pObj,
                                                     const Token* token,
-                                                    const std::string& /*key*/)
+                                                    const std::string& key)
 {
    const std::string className = ClassName<T>::name();
    void* voidPtr = nullptr;
    try {
       m_athenaPoolCnvSvc->setObjPtr(voidPtr, token);
-   } catch (std::exception &e) {
-      std::string error = e.what();
-      ATH_MSG_ERROR("poolToObject: caught error: " << error);
-      return(StatusCode::FAILURE);
+   }
+   catch (const std::exception& ex) {
+     AthenaPoolCnvSvc::throwExcCaughtException (__PRETTY_FUNCTION__,
+                                                "converting to DataObject",
+                                                ex,
+                                                typeid(T),
+                                                key);
    }
    T* obj = reinterpret_cast<T*>(voidPtr);
    pObj = SG::asStorable(obj);
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.icc
index f2b83c45b1e3fd42bfa05bc19f67040c0087a7f3..94bce3ad0dd692f0d0f2f81f5c5da87d13efa6b2 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.icc
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.icc
@@ -278,7 +278,7 @@ T_AthenaPoolCoolMultChanCnv<COLL_T, ELEM_T, ELEM_P>::attrListCollToObject(CondAt
             token=attrList["PoolRef"].data<std::string>();
 	}
         // FIXME exception
-	catch(std::exception& x) {
+	catch(const std::exception& x) {
 	    ATH_MSG_ERROR("PoolRef not found in attribute list");
 	    return(StatusCode::FAILURE);
 	}
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc
index 986176a84ed8f48775084efa8d700a835f0fcc3f..e45b2e3a04c697efe7af31aa082f3f2bcf588a77 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 /** @file T_AthenaPoolCustCnv.icc
@@ -8,6 +8,7 @@
  **/
 
 #include "AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h"
+#include "AthenaPoolCnvSvc/exceptions.h"
 
 #include "GaudiKernel/StatusCode.h"
 #include "GaudiKernel/DataObject.h"
@@ -81,9 +82,13 @@ StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::poolToObject(const Token*& token, P
    void* voidPtr = nullptr;
    try {
       this->m_athenaPoolCnvSvc->setObjPtr(voidPtr, token);
-   } catch (std::exception &e) {
-      ATH_MSG_ERROR("poolToObject: caught error: " << e.what());
-      return(StatusCode::FAILURE);
+   }
+   catch (const std::exception& ex) {
+    AthenaPoolCnvSvc::throwExcCaughtException (__PRETTY_FUNCTION__,
+                                               "pooltoObject",
+                                               ex,
+                                               typeid(P),
+                                               token->toString());
    }
    if (voidPtr == nullptr) {
       ATH_MSG_ERROR("poolToObject: Could not get object for Token = " << (token != nullptr ? token->toString() : ""));
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.icc
index c8efe8a5ff8650fd0aef70f21ca971d989cd82af..aec92f536b0bb3eeaa62f64241599990706fc4d6 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.icc
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.icc
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 /** @file T_AthenaPoolCustomCnv.icc
@@ -16,6 +16,7 @@
 
 #include "AthenaKernel/StorableConversions.h"
 
+#include "AthenaPoolCnvSvc/exceptions.h"
 #include "AthenaPoolCnvTPExtension.h"
 
 #include <sstream>
@@ -44,9 +45,13 @@ StatusCode T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::DataObjectToPool(IOpaqueAd
    }
    try {
      persObj = createPersistentWithKey(obj, pObj->name());
-   } catch (std::exception &e) {
-      ATH_MSG_ERROR("Failed to create persistent object: " << e.what());
-      return(StatusCode::FAILURE);
+   }
+   catch (const std::exception& ex) {
+    AthenaPoolCnvSvc::throwExcCaughtException (__PRETTY_FUNCTION__,
+                                               "creating persistent object",
+                                               ex,
+                                               typeid(TRANS),
+                                               pObj->name());
    }
    Token* token = nullptr;
    StatusCode status = this->objectToPool(persObj, token, pObj->name(), *pAddr->par());
@@ -92,13 +97,13 @@ T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::PoolToDataObject(DataObject*& pObj,
    }
    try {
       transObj = createTransientWithKey(key);
-   } catch(std::exception &e) {
-      ATH_MSG_ERROR("Failed to convert persistent object to transient: " << e.what());
-      // cleanup
-      if (extCnv != nullptr) {
-         extCnv->deletePersistentObjects();
-      }
-      return(StatusCode::FAILURE);
+   }
+   catch(const std::exception& ex) {
+    AthenaPoolCnvSvc::throwExcCaughtException (__PRETTY_FUNCTION__,
+                                               "creating transient object",
+                                               ex,
+                                               typeid(TRANS),
+                                               key);
    }
    if (extCnv != nullptr) {
       extCnv->deletePersistentObjects();
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/exceptions.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/exceptions.h
index 18a6db845d1446de972420b6c290d2b216d72109..9f2ba9a1f06bff62da1b28e22cceeea83cdbe26a 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/exceptions.h
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/exceptions.h
@@ -1,10 +1,9 @@
 // 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-2021 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id$
 /**
  * @file AthenaPoolCnvSvc/exceptions.h
  * @author scott snyder <snyder@bnl.gov>
@@ -73,11 +72,54 @@ public:
  * @brief Throw a AthenaPoolCnvSvc::ExcUnsupportedVersion exception.
  * @param ti The class being read.
  * @param guid The GUID of the persistent class.
-o */
+ */
 [[noreturn]]
 void throwExcUnsupportedVersion (const std::type_info& ti, const Guid& guid);
 
   
+/**
+ * @brief Exception --- Caught an exception during conversion.
+ *
+ * Encountered an exception during conversion.
+ */
+class ExcCaughtException
+  : public std::runtime_error
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param fnname Name of the function being executed.
+   * @param action What we were doing when we caught the exception.
+   * @param ex The caught exception.
+   * @param ti The class being thinned.
+   * @param key Key of the class being thinned.
+   */
+  ExcCaughtException (const char* fnname,
+                      const char* action,
+                      const std::exception& ex,
+                      const std::type_info& ti,
+                      const std::string& key);
+};
+
+
+/**
+ * @brief Throw a AthenaPoolCnvSvc::ExcCaughtException exception.
+ * @param fnname Name of the function being executed.
+ * @param action What we were doing when we caught the exception.
+ * @param ex The caught exception.
+ * @param ti The class being thinned.
+ * @param key Key of the class being thinned.
+ *
+ * Will also print a stack trace if exctrace is enabled.
+ */
+[[noreturn]]
+void throwExcCaughtException (const char* fnname,
+                              const char* action,
+                              const std::exception& ex,
+                              const std::type_info& ti,
+                              const std::string& key);
+
+  
 } // namespace AthenaPoolCnvSvc
 
 
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt b/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt
index b51f4c7ce566738b0eca70aff47a7206e6452fc3..01343f1028df23ed46c4563a5760c3f4cf02ed36 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( AthenaPoolCnvSvc )
@@ -49,22 +49,26 @@ atlas_add_test( T_AthenaPoolCreateFuncs_test
 atlas_add_test( T_AthenaPoolViewVectorCnv_test
    SOURCES test/T_AthenaPoolViewVectorCnv_test.cxx
    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaPoolCnvSvcLib TestTools )
+   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaPoolCnvSvcLib TestTools
+   LOG_IGNORE_PATTERN "basic_string" )
 
 atlas_add_test( T_AthenaPoolxAODCnv_test
    SOURCES test/T_AthenaPoolxAODCnv_test.cxx
    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaPoolCnvSvcLib TestTools )
+   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaPoolCnvSvcLib TestTools
+   LOG_IGNORE_PATTERN "basic_string" )
 
 atlas_add_test( T_AthenaPoolAuxContainerCnv_test
    SOURCES test/T_AthenaPoolAuxContainerCnv_test.cxx
    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaPoolCnvSvcLib TestTools )
+   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaPoolCnvSvcLib TestTools
+   LOG_IGNORE_PATTERN "basic_string" )
 
 atlas_add_test( T_AthenaPoolTPCnvCnv_test
    SOURCES test/T_AthenaPoolTPCnvCnv_test.cxx
    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaPoolCnvSvcLib TestTools )
+   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaPoolCnvSvcLib TestTools
+   LOG_IGNORE_PATTERN "basic_string" )
 
 atlas_add_test( T_AuxContainerCopyTPCnv_test
    SOURCES test/T_AuxContainerCopyTPCnv_test.cxx
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolAuxContainerCnv_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolAuxContainerCnv_test.ref
index 3185ff4fc675710846a1a8a6d630df40762f1fa0..9bdf547c275af746a1f10fe0c00dc24053e39655 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolAuxContainerCnv_test.ref
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolAuxContainerCnv_test.ref
@@ -1,20 +1,19 @@
 
 
-Initializing Gaudi ApplicationMgr using job opts ../share/test.txt
-JobOptionsSvc        INFO Job options successfully read in from ../share/test.txt
+Initializing Gaudi ApplicationMgr using job opts /home/sss/atlas/dvtest/build/joboptions/AthenaPoolCnvSvc/test.txt
+JobOptionsSvc        INFO Job options successfully read in from /home/sss/atlas/dvtest/build/joboptions/AthenaPoolCnvSvc/test.txt
 ApplicationMgr    SUCCESS 
 ====================================================================================================================================
-                                                   Welcome to ApplicationMgr (GaudiCoreSvc v999r999)
-                                          running on karma on Thu Jan 21 14:08:47 2016
+                                                   Welcome to ApplicationMgr (GaudiCoreSvc v27r1p99)
+                                          running on karma on Thu Mar 25 17:20:07 2021
 ====================================================================================================================================
 ApplicationMgr       INFO Application Manager Configured successfully
 EventLoopMgr      WARNING Unable to locate service "EventSelector" 
 EventLoopMgr      WARNING No events will be processed from external input.
-HistogramPersis...WARNING Histograms saving not required.
 ApplicationMgr       INFO Application Manager Initialized successfully
 ApplicationMgr Ready
 test1
 test2
-AthenaPoolConve...  ERROR Failed to convert persistent object to transient: AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of AthenaPoolCnvSvcTest::YAuxCont_v2 found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA
-AthenaPoolConve...  ERROR createObj PoolToDataObject() failed, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
+Exception: AthenaPoolCnvSvc::::ExcUnsupportedVersion: Unsupported persistent version of AthenaPoolCnvSvcTest::YAuxCont_v2 found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA (no backtrace available).
+AthenaPoolConve...  ERROR createObj - caught exception: AthenaPoolCnvSvc::::ExcCaughtException: Caught exception in StatusCode T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::PoolToDataObject(DataObject*&, const Token*, const string&) [with TRANS = AthenaPoolCnvSvcTest::YAuxCont_v2; PERS = AthenaPoolCnvSvcTest::YAuxCont_v2; std::string = std::__cxx11::basic_string<char>] while creating transient objectAthenaPoolCnvSvcTest::YAuxCont_v2/: AthenaPoolCnvSvc::ExcUnsupportedVersion: AthenaPoolCnvSvc::::ExcUnsupportedVersion: Unsupported persistent version of AthenaPoolCnvSvcTest::YAuxCont_v2 found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA
 AthenaPoolConve...  ERROR createObj failed to get DataObject, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolTPCnvCnv_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolTPCnvCnv_test.ref
index cabfcb0f73c7e1a5ea11db916dc3a57ec5d35c2a..82602e4c549dcc678321cbb34a8e099fa6c56003 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolTPCnvCnv_test.ref
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolTPCnvCnv_test.ref
@@ -1,20 +1,19 @@
 
 
-Initializing Gaudi ApplicationMgr using job opts ../share/test.txt
-JobOptionsSvc        INFO Job options successfully read in from ../share/test.txt
+Initializing Gaudi ApplicationMgr using job opts /home/sss/atlas/dvtest/build/joboptions/AthenaPoolCnvSvc/test.txt
+JobOptionsSvc        INFO Job options successfully read in from /home/sss/atlas/dvtest/build/joboptions/AthenaPoolCnvSvc/test.txt
 ApplicationMgr    SUCCESS 
 ====================================================================================================================================
-                                                   Welcome to ApplicationMgr (GaudiCoreSvc v999r999)
-                                          running on karma on Fri Jan 22 14:26:54 2016
+                                                   Welcome to ApplicationMgr (GaudiCoreSvc v27r1p99)
+                                          running on karma on Thu Mar 25 17:19:52 2021
 ====================================================================================================================================
 ApplicationMgr       INFO Application Manager Configured successfully
 EventLoopMgr      WARNING Unable to locate service "EventSelector" 
 EventLoopMgr      WARNING No events will be processed from external input.
-HistogramPersis...WARNING Histograms saving not required.
 ApplicationMgr       INFO Application Manager Initialized successfully
 ApplicationMgr Ready
 test1
 test2
-AthenaPoolConve...  ERROR Failed to convert persistent object to transient: AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of DataVector<AthenaPoolCnvSvcTest::X,DataModel_detail::NoBase> found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA
-AthenaPoolConve...  ERROR createObj PoolToDataObject() failed, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
+Exception: AthenaPoolCnvSvc::::ExcUnsupportedVersion: Unsupported persistent version of DataVector<AthenaPoolCnvSvcTest::X,DataModel_detail::NoBase> found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA (no backtrace available).
+AthenaPoolConve...  ERROR createObj - caught exception: AthenaPoolCnvSvc::::ExcCaughtException: Caught exception in StatusCode T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::PoolToDataObject(DataObject*&, const Token*, const string&) [with TRANS = DataVector<AthenaPoolCnvSvcTest::X>; PERS = AthenaPoolCnvSvcTest::XCont_p2; std::string = std::__cxx11::basic_string<char>] while creating transient objectDataVector<AthenaPoolCnvSvcTest::X,DataModel_detail::NoBase>/: AthenaPoolCnvSvc::ExcUnsupportedVersion: AthenaPoolCnvSvc::::ExcUnsupportedVersion: Unsupported persistent version of DataVector<AthenaPoolCnvSvcTest::X,DataModel_detail::NoBase> found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA
 AthenaPoolConve...  ERROR createObj failed to get DataObject, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolViewVectorCnv_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolViewVectorCnv_test.ref
index 70549329e491fc995d67031df8ffbca38ce8c6a4..91b403b1afc34b16629eafc30ebace864e6d33e1 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolViewVectorCnv_test.ref
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolViewVectorCnv_test.ref
@@ -1,20 +1,19 @@
 
 
-Initializing Gaudi ApplicationMgr using job opts ../share/test.txt
-JobOptionsSvc        INFO Job options successfully read in from ../share/test.txt
+Initializing Gaudi ApplicationMgr using job opts /home/sss/atlas/dvtest/build/joboptions/AthenaPoolCnvSvc/test.txt
+JobOptionsSvc        INFO Job options successfully read in from /home/sss/atlas/dvtest/build/joboptions/AthenaPoolCnvSvc/test.txt
 ApplicationMgr    SUCCESS 
 ====================================================================================================================================
                                                    Welcome to ApplicationMgr (GaudiCoreSvc v27r1p99)
-                                          running on karma on Mon Oct 10 19:17:16 2016
+                                          running on karma on Thu Mar 25 17:22:26 2021
 ====================================================================================================================================
 ApplicationMgr       INFO Application Manager Configured successfully
 EventLoopMgr      WARNING Unable to locate service "EventSelector" 
 EventLoopMgr      WARNING No events will be processed from external input.
-HistogramPersis...WARNING Histograms saving not required.
 ApplicationMgr       INFO Application Manager Initialized successfully
 ApplicationMgr Ready
 test1
-AthenaPoolConve...  ERROR Failed to convert persistent object to transient: AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of ViewVector<DataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase> > found; guid: 79E2478D-C17F-45E9-848D-278240C2FED3
-AthenaPoolConve...  ERROR createObj PoolToDataObject() failed, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=79E2478D-C17F-45E9-848D-278240C2FED3][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
+Exception: AthenaPoolCnvSvc::::ExcUnsupportedVersion: Unsupported persistent version of ViewVector<DataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase> > found; guid: 79E2478D-C17F-45E9-848D-278240C2FED3 (no backtrace available).
+AthenaPoolConve...  ERROR createObj - caught exception: AthenaPoolCnvSvc::::ExcCaughtException: Caught exception in StatusCode T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::PoolToDataObject(DataObject*&, const Token*, const string&) [with TRANS = ViewVector<DataVector<AthenaPoolCnvSvcTest::Y_v2> >; PERS = ViewVector<DataVector<AthenaPoolCnvSvcTest::Y_v2> >; std::string = std::__cxx11::basic_string<char>] while creating transient objectViewVector<DataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase> >/: AthenaPoolCnvSvc::ExcUnsupportedVersion: AthenaPoolCnvSvc::::ExcUnsupportedVersion: Unsupported persistent version of ViewVector<DataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase> > found; guid: 79E2478D-C17F-45E9-848D-278240C2FED3
 AthenaPoolConve...  ERROR createObj failed to get DataObject, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=79E2478D-C17F-45E9-848D-278240C2FED3][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
 test2
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolxAODCnv_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolxAODCnv_test.ref
index 0d634f54b84335ee0850ea14473dc295edebf21a..c6d7f7e80520c22e50a8553ea231b09d7fd082c8 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolxAODCnv_test.ref
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolxAODCnv_test.ref
@@ -1,20 +1,19 @@
 
 
-Initializing Gaudi ApplicationMgr using job opts ../share/test.txt
-JobOptionsSvc        INFO Job options successfully read in from ../share/test.txt
+Initializing Gaudi ApplicationMgr using job opts /home/sss/atlas/dvtest/build/joboptions/AthenaPoolCnvSvc/test.txt
+JobOptionsSvc        INFO Job options successfully read in from /home/sss/atlas/dvtest/build/joboptions/AthenaPoolCnvSvc/test.txt
 ApplicationMgr    SUCCESS 
 ====================================================================================================================================
                                                    Welcome to ApplicationMgr (GaudiCoreSvc v27r1p99)
-                                          running on karma on Wed Oct 16 11:26:09 2019
+                                          running on karma on Thu Mar 25 17:21:54 2021
 ====================================================================================================================================
 ApplicationMgr       INFO Application Manager Configured successfully
 EventLoopMgr      WARNING Unable to locate service "EventSelector" 
 EventLoopMgr      WARNING No events will be processed from external input.
-HistogramPersis...WARNING Histograms saving not required.
 ApplicationMgr       INFO Application Manager Initialized successfully
 ApplicationMgr Ready
 test1
-AthenaPoolConve...  ERROR Failed to convert persistent object to transient: AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of DataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase> found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA
-AthenaPoolConve...  ERROR createObj PoolToDataObject() failed, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
+Exception: AthenaPoolCnvSvc::::ExcUnsupportedVersion: Unsupported persistent version of DataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase> found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA (no backtrace available).
+AthenaPoolConve...  ERROR createObj - caught exception: AthenaPoolCnvSvc::::ExcCaughtException: Caught exception in StatusCode T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::PoolToDataObject(DataObject*&, const Token*, const string&) [with TRANS = DataVector<AthenaPoolCnvSvcTest::Y_v2>; PERS = DataVector<AthenaPoolCnvSvcTest::Y_v2>; std::string = std::__cxx11::basic_string<char>] while creating transient objectDataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase>/key: AthenaPoolCnvSvc::ExcUnsupportedVersion: AthenaPoolCnvSvc::::ExcUnsupportedVersion: Unsupported persistent version of DataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase> found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA
 AthenaPoolConve...  ERROR createObj failed to get DataObject, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
 test2
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/exceptions_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/exceptions_test.ref
index 8809968d6245e8b2dcc9f58caf74ab4b8a5687bb..7f37946eeb0444e3ff85644e1f3fbd5e40e9860e 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/exceptions_test.ref
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/exceptions_test.ref
@@ -1,3 +1,4 @@
 test1
 AthenaPoolCnvSvc::::ExcNoDictForClass: Can't find dictionary information for class: int
-AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of int found; guid: 336F636C-D414-4261-8286-37429F353F0A
+AthenaPoolCnvSvc::::ExcUnsupportedVersion: Unsupported persistent version of int found; guid: 336F636C-D414-4261-8286-37429F353F0A
+AthenaPoolCnvSvc::::ExcCaughtException: Caught exception in fnname while chasing my tailint/key: std::runtime_error: foofoo
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/exceptions.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/exceptions.cxx
index 7a46d4896963d54ad5a89f11dc11e3f13598ff20..f85780d0c8a25bf5de18b01192a08a15845c3653 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/exceptions.cxx
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/exceptions.cxx
@@ -1,8 +1,7 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id$
 /**
  * @file AthenaPoolCnvSvc/src/exceptions.cxx
  * @author scott snyder <snyder@bnl.gov>
@@ -12,6 +11,7 @@
 
 
 #include "AthenaPoolCnvSvc/exceptions.h"
+#include "CxxUtils/exctrace.h"
 #include "GaudiKernel/System.h"
 #include <sstream>
 
@@ -58,7 +58,7 @@ std::string excUnsupportedVersion_format (const std::type_info& ti,
                                           const Guid& guid)
 {
   std::ostringstream os;
-  os << "AthenaPoolCnvSvc::::ExcUnsupported version: "
+  os << "AthenaPoolCnvSvc::::ExcUnsupportedVersion: "
      << "Unsupported persistent version of "
      << System::typeinfoName(ti)
      << " found; guid: " << guid.toString();
@@ -89,4 +89,65 @@ void throwExcUnsupportedVersion (const std::type_info& ti, const Guid& guid)
 }
 
 
+//*************************************************************************
+
+
+/// Helper: format exception error string.
+std::string excCaughtException_format (const char* fnname,
+                                       const char* action,
+                                       const std::exception& ex,
+                                       const std::type_info& ti,
+                                       const std::string& key)
+{
+  std::ostringstream os;
+  os << "AthenaPoolCnvSvc::::ExcCaughtException: "
+     << "Caught exception in " << fnname
+     << " while " << action
+     << System::typeinfoName(ti) << "/" << key
+     << ": " << System::typeinfoName(typeid(ex)) << ": " << ex.what();
+  return os.str();
+}
+
+
+/**
+ * @brief Constructor.
+ * @param fnname Name of the function being executed.
+ * @param action What we were doing when we caught the exception.
+ * @param ex The caught exception.
+ * @param ti The class being thinned.
+ * @param key Key of the class being thinned.
+ */
+ExcCaughtException::ExcCaughtException (const char* fnname,
+                                        const char* action,
+                                        const std::exception& ex,
+                                        const std::type_info& ti,
+                                        const std::string& key)
+  : std::runtime_error (excCaughtException_format (fnname, action, ex, ti, key))
+{
+}
+
+
+/**
+ * @brief Throw a AthenaPoolCnvSvc::ExcCaughtException exception.
+ * @param fnname Name of the function being executed.
+ * @param action What we were doing when we caught the exception.
+ * @param ex The caught exception.
+ * @param ti The class being thinned.
+ * @param key Key of the class being thinned.
+ *
+ * Will also print a stack trace if exctrace is enabled.
+ */
+void throwExcCaughtException (const char* fnname,
+                              const char* action,
+                              const std::exception& ex,
+                              const std::type_info& ti,
+                              const std::string& key)
+{
+  std::cout.flush();
+  std::cerr.flush();
+  CxxUtils::exctrace (ex);
+  throw ExcCaughtException (fnname, action, ex, ti, key);
+}
+
+
 } // namespace AthenaPoolCnvSvc
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/exceptions_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/exceptions_test.cxx
index c72d18fa9ce71295725109a334c3354f9e60144b..fc5fc2c4ea4fee57fe4b7b9d21edb5ce7bdc2e03 100644
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/exceptions_test.cxx
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/exceptions_test.cxx
@@ -1,8 +1,7 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id$
 /**
  * @file AthenaPoolCnvSvc/test/exceptions_test.cxx
  * @author scott snyder <snyder@bnl.gov>
@@ -25,6 +24,12 @@ void test1()
   std::cout << AthenaPoolCnvSvc::ExcUnsupportedVersion
     ( typeid(int),
       Guid("336F636C-D414-4261-8286-37429F353F0A") ).what() << "\n";
+  std::cout << AthenaPoolCnvSvc::ExcCaughtException
+    ( "fnname",
+      "chasing my tail",
+      std::runtime_error ("foofoo"),
+      typeid(int),
+      "key").what() << "\n";
 }
 
 
diff --git a/Database/AthenaPOOL/AthenaPoolExample/AthenaPoolExampleAlgorithms/share/AthenaPoolExample_RCond.ref b/Database/AthenaPOOL/AthenaPoolExample/AthenaPoolExampleAlgorithms/share/AthenaPoolExample_RCond.ref
index 7c4c0f0e89c0dc024db5e5767c1ae97ba3fd75ae..ee15cc6f9cea8841c1a98254115de690a1a193f0 100644
--- a/Database/AthenaPOOL/AthenaPoolExample/AthenaPoolExampleAlgorithms/share/AthenaPoolExample_RCond.ref
+++ b/Database/AthenaPOOL/AthenaPoolExample/AthenaPoolExampleAlgorithms/share/AthenaPoolExample_RCond.ref
@@ -1,19 +1,61 @@
+Tue Mar 30 10:39:50 CDT 2021
+Preloading tcmalloc_minimal.so
+Athena               INFO including file "AthenaCommon/Preparation.py"
+Athena               INFO including file "AthenaCommon/Atlas.UnixStandardJob.py"
 Athena               INFO executing ROOT6Setup
+Athena               INFO including file "AthenaCommon/Execution.py"
+Athena               INFO including file "AthenaPoolExampleAlgorithms/AthenaPoolExample_RCondJobOptions.py"
+Py:ConfigurableDb    INFO Read module info for 5121 configurables from 59 genConfDb files
+Py:ConfigurableDb    INFO No duplicates have been found: that's good !
+Athena               INFO including file "AthenaCommon/runbatch.py"
+ApplicationMgr    SUCCESS 
+====================================================================================================================================
+                                                   Welcome to ApplicationMgr (GaudiCoreSvc v35r1)
+                                          running on hepd-0003 on Tue Mar 30 10:39:57 2021
+====================================================================================================================================
 ApplicationMgr       INFO Application Manager Configured successfully
 AthDictLoaderSvc     INFO in initialize...
 AthDictLoaderSvc     INFO acquired Dso-registry
+ClassIDSvc           INFO  getRegistryEntries: read 3200 CLIDRegistry entries for module ALL
+AthenaEventLoopMgr   INFO Initializing AthenaEventLoopMgr - package version AthenaServices-00-00-00
+ClassIDSvc           INFO  getRegistryEntries: read 861 CLIDRegistry entries for module ALL
+ReadCond            DEBUG Property update for OutputLevel : new value = 2
 ReadCond             INFO in initialize()
+ReadCond            DEBUG input handles: 0
+ReadCond            DEBUG output handles: 0
+ReadCond            DEBUG Data Deps for ReadCond
+ReadData            DEBUG Property update for OutputLevel : new value = 2
 ReadData             INFO in initialize()
+MetaDataSvc         DEBUG Property update for OutputLevel : new value = 2
+MetaDataSvc          INFO Initializing MetaDataSvc - package version AthenaServices-00-00-00
+MetaDataSvc         DEBUG Service base class initialized successfully
+PoolSvc             DEBUG Property update for OutputLevel : new value = 2
+PoolSvc             DEBUG Service base class initialized successfully
+PoolSvc              INFO Set connectionsvc retry/timeout/IDLE timeout to  'ConnectionRetrialPeriod':300/ 'ConnectionRetrialTimeOut':3600/ 'ConnectionTimeOut':5 seconds with connection cleanup disabled
+PoolSvc              INFO Frontier compression level set to 5
+DBReplicaSvc         INFO Frontier server at (serverurl=http://atlasfrontier-ai.cern.ch:8000/atlr)(serverurl=http://frontier-atlas.lcg.triumf.ca:3128/ATLAS_frontier)(serverurl=http://ccfrontier.in2p3.fr:23128/ccin2p3-AtlasFrontier)(proxyurl=http://atlasbpfrontier.cern.ch:3127)(proxyurl=http://atlasbpfrontier.fnal.gov:3127) will be considered for COOL data
+DBReplicaSvc         INFO Read replica configuration from /home/gemmeren/workarea/build/x86_64-centos7-gcc8-opt/share/dbreplica.config
+DBReplicaSvc         INFO Total of 1 servers found for host hepd-0003.lcrc.anl.gov [ATLF ]
+PoolSvc              INFO Successfully setup replica sorting algorithm
 PoolSvc             DEBUG OutputLevel is 2
+PoolSvc              INFO Setting up APR FileCatalog and Streams
 PoolSvc             DEBUG POOL ReadCatalog is file:Catalog0.xml
 PoolSvc             DEBUG POOL ReadCatalog is file:Catalog1.xml
+PoolSvc              INFO POOL WriteCatalog is file:Catalog2.xml
+DbSession            INFO     Open     DbSession    
+Domain[ROOT_All]     INFO >   Access   DbDomain     READ      [ROOT_All] 
+MetaDataSvc          INFO Found MetaDataTools = PublicToolHandleArray(['IOVDbMetaDataTool'])
+EventSelector       DEBUG Property update for OutputLevel : new value = 2
 EventSelector       DEBUG Initializing EventSelector
+EventSelector       DEBUG Service base class initialized successfully
 EventSelector       DEBUG reinitialization...
 EventSelector        INFO EventSelection with query 
 EventSelector       DEBUG Try item: "SimplePoolFile1.root" from the collection list.
 PoolSvc             DEBUG createCollection() type=RootCollection, connection=PFN:SimplePoolFile1.root, name=SimplePoolFile1.root, contextID=0
 MetaDataSvc         DEBUG handle() FirstInputFile for FID:????
 MetaDataSvc         DEBUG initInputMetaDataStore: file name FID:????
+Domain[ROOT_All]     INFO ->  Access   DbDatabase   READ      [ROOT_All] ????
+Domain[ROOT_All]     INFO                           SimplePoolFile1.root
 SimplePoolFile1...  DEBUG --> Access   DbContainer  READ      [ROOT_All] ##Shapes
 ##Shapes            DEBUG Opening
 ##Shapes            DEBUG    attributes# = 1
@@ -112,18 +154,33 @@ MetaDataHdr(Dat...  DEBUG Opening
 MetaDataHdr(Dat...  DEBUG    attributes# = 1
 MetaDataHdr(Dat...  DEBUG Branch container 'DataHeader'
 MetaDataHdr(Dat...  DEBUG Opened container MetaDataHdr(DataHeader) of type ROOT_Tree
+ClassIDSvc           INFO  getRegistryEntries: read 1710 CLIDRegistry entries for module ALL
+EventPersistenc...   INFO Added successfully Conversion service:AthenaPoolCnvSvc
 SimplePoolFile1...  DEBUG --> Access   DbContainer  READ      [ROOT_Tree] MetaDataHdrForm(DataHeaderForm)
 MetaDataHdrForm...  DEBUG Opening
 MetaDataHdrForm...  DEBUG    attributes# = 1
 MetaDataHdrForm...  DEBUG Branch container 'DataHeaderForm'
 MetaDataHdrForm...  DEBUG Opened container MetaDataHdrForm(DataHeaderForm) of type ROOT_Tree
 MetaDataSvc         DEBUG Loaded input meta data store proxies
+ClassIDSvc           INFO  getRegistryEntries: read 2 CLIDRegistry entries for module ALL
+OutputStreamSeq...   INFO Initializing OutputStreamSequencerSvc - package version AthenaServices-00-00-00
 MetaDataSvc         DEBUG Registering all Tools in ToolHandleArray MetaDataTools
 MetaDataSvc         DEBUG Adding public ToolHandle tool ToolSvc.IOVDbMetaDataTool (IOVDbMetaDataTool)
+MetaDataSvc          INFO   AlgTool: ToolSvc.IOVDbMetaDataTool
+AthenaPoolAddre...  DEBUG Property update for OutputLevel : new value = 2
+AthenaPoolAddre...  DEBUG Service base class initialized successfully
+CondProxyProvider   DEBUG Property update for OutputLevel : new value = 2
+CondProxyProvider    INFO Initializing CondProxyProvider - package version EventSelectorAthenaPool-00-00-00
+CondProxyProvider   DEBUG Service base class initialized successfully
 CondProxyProvider    INFO Inputs: SimplePoolFile4.root
 CondProxyProvider   DEBUG Try item: "SimplePoolFile4.root" from the collection list.
-PoolSvc             DEBUG createCollection() type=RootCollection, connection=PFN:SimplePoolFile4.root, name=SimplePoolFile4.root, contextID=0
-PoolSvc             DEBUG createCollection() type=ImplicitCollection, connection=PFN:SimplePoolFile4.root, name=POOLContainer(DataHeader), contextID=0
+PoolSvc             DEBUG createCollection() type=RootCollection, connection=PFN:SimplePoolFile4.root, name=SimplePoolFile4.root, contextID=2
+PoolSvc             DEBUG createCollection() type=ImplicitCollection, connection=PFN:SimplePoolFile4.root, name=POOLContainer(DataHeader), contextID=2
+PersistencySvc:...  DEBUG lookupPFN: SimplePoolFile4.root returned FID: '????' tech=ROOT_All
+DbSession            INFO     Open     DbSession    
+Domain[ROOT_All]     INFO >   Access   DbDomain     READ      [ROOT_All] 
+Domain[ROOT_All]     INFO ->  Access   DbDatabase   READ      [ROOT_All] ????
+Domain[ROOT_All]     INFO                           SimplePoolFile4.root
 SimplePoolFile4...  DEBUG --> Access   DbContainer  READ      [ROOT_All] ##Shapes
 ##Shapes            DEBUG Opening
 ##Shapes            DEBUG    attributes# = 1
@@ -157,6 +214,9 @@ SimplePoolFile4...  DEBUG --->Reading Param:PFN=[SimplePoolFile4.root]
 SimplePoolFile4...  DEBUG --->Reading Param:POOL_VSN=[1.1]
 SimplePoolFile4...  DEBUG --->Reading Param:FORMAT_VSN=[1.1]
 ##Params            DEBUG No objects passing selection criteria... Container has 4 Entries in total.
+ReadData            DEBUG input handles: 2
+ReadData            DEBUG output handles: 0
+ReadData            DEBUG Data Deps for ReadData
   + INPUT   ( 'ExampleHitContainer' , 'StoreGateSvc+MyHits' ) 
   + INPUT   ( 'ExampleTrackContainer' , 'StoreGateSvc+MyTracks' ) 
 AthenaEventLoopMgr   INFO Setup EventSelector service EventSelector
@@ -190,6 +250,7 @@ POOLContainerFo...  DEBUG Opened container POOLContainerForm(DataHeaderForm) of
 AthenaPoolAddre...  DEBUG The current Event contains: 3 objects
 AthenaPoolAddre...  DEBUG loadAddresses: DataObject address, clid = 2101, name = McEventInfo
 AthenaPoolAddre...  DEBUG loadAddresses: DataObject address, clid = 9102, name = MyHits
+AlgResourcePool      INFO TopAlg list empty. Recovering the one of Application Manager
 AthenaEventLoopMgr   INFO   ===>>>  start of run 1    <<<===
 AthenaEventLoopMgr   INFO   ===>>>  start processing event #0, run #1 0 events processed so far  <<<===
 ReadCond            DEBUG in execute()
@@ -199,8 +260,15 @@ POOLContainer(D...  DEBUG Opening
 POOLContainer(D...  DEBUG    attributes# = 1
 POOLContainer(D...  DEBUG Branch container 'DataHeader'
 POOLContainer(D...  DEBUG Opened container POOLContainer(DataHeader) of type ROOT_Tree
-StorageSvc          DEBUG Disconnect request for database: FID=???? PFN=SimplePoolFile4.root
-StorageSvc          DEBUG Closing database: FID=????
+SimplePoolFile4...  DEBUG --> Access   DbContainer  READ      [ROOT_Tree] POOLContainerForm(DataHeaderForm)
+POOLContainerFo...  DEBUG Opening
+POOLContainerFo...  DEBUG    attributes# = 1
+POOLContainerFo...  DEBUG Branch container 'DataHeaderForm'
+POOLContainerFo...  DEBUG Opened container POOLContainerForm(DataHeaderForm) of type ROOT_Tree
+CondProxyProvider   DEBUG The current File contains: 2 objects
+CondProxyProvider   DEBUG preLoadAddresses: DataObject address, clid = 9102, name = PedestalWriteData
+Domain[ROOT_All]     INFO ->  Access   DbDatabase   READ      [ROOT_All] ????
+Domain[ROOT_All]     INFO                           SimplePoolFile4.root
 SimplePoolFile4...  DEBUG --> Access   DbContainer  READ      [ROOT_All] ##Shapes
 ##Shapes            DEBUG Opening
 ##Shapes            DEBUG    attributes# = 1
@@ -234,18 +302,6 @@ SimplePoolFile4...  DEBUG --->Reading Param:PFN=[SimplePoolFile4.root]
 SimplePoolFile4...  DEBUG --->Reading Param:POOL_VSN=[1.1]
 SimplePoolFile4...  DEBUG --->Reading Param:FORMAT_VSN=[1.1]
 ##Params            DEBUG No objects passing selection criteria... Container has 4 Entries in total.
-SimplePoolFile4...  DEBUG --> Access   DbContainer  READ      [ROOT_Tree] POOLContainer(DataHeader)
-POOLContainer(D...  DEBUG Opening
-POOLContainer(D...  DEBUG    attributes# = 1
-POOLContainer(D...  DEBUG Branch container 'DataHeader'
-POOLContainer(D...  DEBUG Opened container POOLContainer(DataHeader) of type ROOT_Tree
-SimplePoolFile4...  DEBUG --> Access   DbContainer  READ      [ROOT_Tree] POOLContainerForm(DataHeaderForm)
-POOLContainerFo...  DEBUG Opening
-POOLContainerFo...  DEBUG    attributes# = 1
-POOLContainerFo...  DEBUG Branch container 'DataHeaderForm'
-POOLContainerFo...  DEBUG Opened container POOLContainerForm(DataHeaderForm) of type ROOT_Tree
-CondProxyProvider   DEBUG The current File contains: 2 objects
-CondProxyProvider   DEBUG preLoadAddresses: DataObject address, clid = 9102, name = PedestalWriteData
 SimplePoolFile4...  DEBUG --> Access   DbContainer  READ      [ROOT_Tree] ConditionsContainerExampleHitContainer_p1(PedestalWriteData)
 ConditionsConta...  DEBUG Opening
 ConditionsConta...  DEBUG    attributes# = 1
@@ -288,6 +344,7 @@ EventSelector       DEBUG Get AttributeList from the collection
 EventSelector       DEBUG AttributeList size 12
 EventSelector       DEBUG record AthenaAttribute, name = Token = [DB=????][CNT=POOLContainer(DataHeader)][CLID=????][TECH=00000203][OID=00000005-00000001].
 EventSelector       DEBUG record AthenaAttribute, name = eventRef = [DB=????][CNT=POOLContainer(DataHeader)][CLID=????][TECH=00000203][OID=00000005-00000001].
+ClassIDSvc           INFO  getRegistryEntries: read 21 CLIDRegistry entries for module ALL
 EventSelector       DEBUG found AthenaAttribute, name = eventRef = [DB=????][CNT=POOLContainer(DataHeader)][CLID=????][TECH=00000203][OID=00000005-00000001]
 AthenaPoolAddre...  DEBUG The current Event contains: 3 objects
 AthenaPoolAddre...  DEBUG loadAddresses: DataObject address, clid = 2101, name = McEventInfo
@@ -913,25 +970,37 @@ ReadData             INFO Hit x = 1930.12 y = 46.5449 z = -1856.17 detector = Du
 AthenaEventLoopMgr   INFO   ===>>>  done processing event #19, run #1 20 events processed so far  <<<===
 MetaDataSvc         DEBUG handle() EndInputFile for FID:????
 MetaDataSvc         DEBUG retireMetadataSource: FID:????
+EventSelector        INFO Disconnecting input sourceID: ????
 StorageSvc          DEBUG Disconnect request for database: FID=???? PFN=SimplePoolFile1.root
 StorageSvc          DEBUG Closing database: FID=????
+Domain[ROOT_All]     INFO ->  Deaccess DbDatabase   READ      [ROOT_All] ????
 AthenaEventLoopMgr   INFO No more events in event selection 
 MetaDataSvc         DEBUG MetaDataSvc::stop()
 PoolSvc             DEBUG Disconnect request for contextId=0
 StorageSvc          DEBUG Disconnect request for database: FID=???? PFN=SimplePoolFile4.root
 StorageSvc          DEBUG Closing database: FID=????
+Domain[ROOT_All]     INFO ->  Deaccess DbDatabase   READ      [ROOT_All] ????
+Domain[ROOT_All]     INFO >   Deaccess DbDomain     READ      [ROOT_All] 
 PoolSvc             DEBUG Disconnected PersistencySvc session
 PoolSvc             DEBUG Disconnect request for contextId=1
 PoolSvc             DEBUG Disconnect request for contextId=2
+StorageSvc          DEBUG Disconnect request for database: FID=???? PFN=SimplePoolFile4.root
+StorageSvc          DEBUG Closing database: FID=????
+Domain[ROOT_All]     INFO ->  Deaccess DbDatabase   READ      [ROOT_All] ????
+Domain[ROOT_All]     INFO >   Deaccess DbDomain     READ      [ROOT_All] 
 PoolSvc             DEBUG Disconnected PersistencySvc session
 ApplicationMgr       INFO Application Manager Stopped successfully
 ReadCond             INFO in finalize()
 ReadData             INFO in finalize()
+ReadData            DEBUG Calling destructor
 AthDictLoaderSvc     INFO in finalize...
 ToolSvc              INFO Removing all tools created by ToolSvc
 *****Chrono*****     INFO ****************************************************************************************************
 *****Chrono*****     INFO  The Final CPU consumption ( Chrono ) Table (ordered)
 *****Chrono*****     INFO ****************************************************************************************************
+cObjR_ALL            INFO Time User   : Tot=    0 [us] Ave/Min/Max=       0(+-       0)/       0/       0 [us] #= 49
+cObj_ALL             INFO Time User   : Tot=   10 [ms] Ave/Min/Max=   0.222(+-    1.47)/       0/      10 [ms] #= 45
+ChronoStatSvc        INFO Time User   : Tot=  170 [ms]  #=  1
 *****Chrono*****     INFO ****************************************************************************************************
 ChronoStatSvc.f...   INFO  Service finalized successfully 
 ApplicationMgr       INFO Application Manager Finalized successfully
diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.cxx b/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.cxx
index 3012b83caf359001f048b50715e73aba18d8221c..9f68c3f9d0b71a41bc89d8b52383826e9ea1fc46 100755
--- a/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.cxx
+++ b/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.cxx
@@ -31,7 +31,8 @@
 CondProxyProvider::CondProxyProvider(const std::string& name, ISvcLocator* pSvcLocator) :
 	::AthService(name, pSvcLocator),
 	m_athenaPoolCnvSvc("AthenaPoolCnvSvc", name),
-	m_poolCollectionConverter(0)
+	m_poolCollectionConverter(0),
+	m_contextId(IPoolSvc::kInputStream)
 	{
 }
 //________________________________________________________________________________
@@ -55,8 +56,8 @@ StatusCode CondProxyProvider::initialize() {
    }
    // Get PoolSvc and connect as "Conditions"
    IPoolSvc *poolSvc = m_athenaPoolCnvSvc->getPoolSvc();
-   StatusCode status = poolSvc->connect( pool::ITransaction::READ,
-                                         poolSvc->getInputContext("Conditions") );
+   m_contextId = poolSvc->getInputContext("Conditions");
+   StatusCode status = poolSvc->connect( pool::ITransaction::READ, m_contextId );
    if (!status.isSuccess()) {
       ATH_MSG_FATAL("Cannot connect to Database.");
       return(StatusCode::FAILURE);
@@ -131,7 +132,7 @@ StatusCode CondProxyProvider::preLoadAddresses(StoreID::type storeID,
       SG::VersionedKey myVersKey(name(), verNumber);
       Token* token = new Token;
       token->fromString(headerIterator->eventRef().toString());
-      TokenAddress* tokenAddr = new TokenAddress(POOL_StorageType, ClassID_traits<DataHeader>::ID(), "", myVersKey, IPoolSvc::kInputStream, token);
+      TokenAddress* tokenAddr = new TokenAddress(POOL_StorageType, ClassID_traits<DataHeader>::ID(), "", myVersKey, m_contextId, token);
       if (!detectorStoreSvc->recordAddress(tokenAddr).isSuccess()) {
          ATH_MSG_ERROR("Cannot record DataHeader.");
          return(StatusCode::FAILURE);
@@ -178,6 +179,7 @@ PoolCollectionConverter* CondProxyProvider::getCollectionCnv() {
    ATH_MSG_DEBUG("Try item: \"" << *m_inputCollectionsIterator << "\" from the collection list.");
    PoolCollectionConverter* pCollCnv = new PoolCollectionConverter("ImplicitROOT",
 	   *m_inputCollectionsIterator,
+	   m_contextId,
 	   "",
 	   m_athenaPoolCnvSvc->getPoolSvc());
    if (!pCollCnv->initialize().isSuccess()) {
diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.h b/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.h
index 0f39299504fcb58f037c0d58ff683ed98c221608..1f8d61cac6e8bfa501a255e30020675241014322 100755
--- a/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.h
+++ b/Database/AthenaPOOL/EventSelectorAthenaPool/src/CondProxyProvider.h
@@ -59,6 +59,7 @@ private: // data
    ServiceHandle<IAthenaPoolCnvSvc> m_athenaPoolCnvSvc;
 
    mutable PoolCollectionConverter* m_poolCollectionConverter ATLAS_THREAD_SAFE;
+   unsigned int m_contextId;
 
 private: // properties
    /// InputCollections, vector with names of the input collections.
diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx b/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx
index 1496c4d919f41c3ccc1cd826b16cd6d049f2b96b..feb31182bab8d7783ec58299f09bb2511e3997bc 100644
--- a/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx
+++ b/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx
@@ -780,6 +780,7 @@ StatusCode EventSelectorAthenaPool::seek(Context& /*ctxt*/, int evtNum) const {
          m_inputCollectionsIterator += m_curCollection;
          m_poolCollectionConverter = new PoolCollectionConverter(m_collectionType.value() + ":" + m_collectionTree.value(),
 	         m_inputCollectionsProp.value()[m_curCollection],
+	         IPoolSvc::kInputStream,
 	         m_query.value(),
 	         m_athenaPoolCnvSvc->getPoolSvc());
          if (!m_poolCollectionConverter->initialize().isSuccess()) {
@@ -827,6 +828,7 @@ int EventSelectorAthenaPool::findEvent(int evtNum) const {
       if (m_numEvt[i] == -1) {
          PoolCollectionConverter pcc(m_collectionType.value() + ":" + m_collectionTree.value(),
 	         m_inputCollectionsProp.value()[i],
+	         IPoolSvc::kInputStream,
 	         m_query.value(),
 	         m_athenaPoolCnvSvc->getPoolSvc());
          if (!pcc.initialize().isSuccess()) {
@@ -981,6 +983,7 @@ PoolCollectionConverter* EventSelectorAthenaPool::getCollectionCnv(bool throwInc
       ATH_MSG_DEBUG("Try item: \"" << *m_inputCollectionsIterator << "\" from the collection list.");
       PoolCollectionConverter* pCollCnv = new PoolCollectionConverter(m_collectionType.value() + ":" + m_collectionTree.value(),
 	      *m_inputCollectionsIterator,
+	      IPoolSvc::kInputStream,
 	      m_query.value(),
 	      m_athenaPoolCnvSvc->getPoolSvc());
       StatusCode status = pCollCnv->initialize();
diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/src/PoolCollectionConverter.cxx b/Database/AthenaPOOL/EventSelectorAthenaPool/src/PoolCollectionConverter.cxx
index 9ee099c22f4cd6a3fc4f7d4361d2f46f36e3e8ff..8ca01de0d3bf463a974d7bb51976833e53cf7e5e 100755
--- a/Database/AthenaPOOL/EventSelectorAthenaPool/src/PoolCollectionConverter.cxx
+++ b/Database/AthenaPOOL/EventSelectorAthenaPool/src/PoolCollectionConverter.cxx
@@ -30,11 +30,13 @@
 //______________________________________________________________________________
 PoolCollectionConverter::PoolCollectionConverter(const std::string& collectionType,
 	const std::string& inputCollection,
+	unsigned int contextId,
 	const std::string& query,
 	const IPoolSvc* svc) :
 	m_collectionType(),
 	m_connection(),
 	m_inputCollection(inputCollection),
+	m_contextId(contextId),
 	m_query(query),
 	m_poolSvc(svc),
 	m_poolCollection(nullptr),
@@ -85,7 +87,7 @@ StatusCode PoolCollectionConverter::initialize() {
          m_connection = "PFN:" + m_inputCollection;
       }
       try {
-         m_poolCollection = m_poolSvc->createCollection("RootCollection", m_connection, m_inputCollection);
+         m_poolCollection = m_poolSvc->createCollection("RootCollection", m_connection, m_inputCollection, m_contextId);
       } catch (std::exception &e) {
          m_poolCollection = nullptr;
       }
@@ -96,11 +98,11 @@ StatusCode PoolCollectionConverter::initialize() {
    }
    try {
       if (m_poolCollection == nullptr) {
-         m_poolCollection = m_poolSvc->createCollection(collectionTypeString, m_connection, m_inputCollection);
+         m_poolCollection = m_poolSvc->createCollection(collectionTypeString, m_connection, m_inputCollection, m_contextId);
       }
       if (m_poolCollection == nullptr && collectionTypeString == "ImplicitCollection") {
          m_inputCollection = m_inputContainer + "_DataHeader";
-         m_poolCollection = m_poolSvc->createCollection(collectionTypeString, m_connection, m_inputCollection);
+         m_poolCollection = m_poolSvc->createCollection(collectionTypeString, m_connection, m_inputCollection, m_contextId);
       }
    } catch (std::exception &e) {
       return(StatusCode::RECOVERABLE);
diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/src/PoolCollectionConverter.h b/Database/AthenaPOOL/EventSelectorAthenaPool/src/PoolCollectionConverter.h
index a606c321401a7a819b389bc85ddfdd5900b6cd0a..b69c18e50b99a0a60e9b6d7336a47f335c3a2873 100755
--- a/Database/AthenaPOOL/EventSelectorAthenaPool/src/PoolCollectionConverter.h
+++ b/Database/AthenaPOOL/EventSelectorAthenaPool/src/PoolCollectionConverter.h
@@ -18,7 +18,6 @@ namespace pool {
    class ICollection;
    class ICollectionQuery;
    class ICollectionCursor;
-   class ICollectionMetadata;
 }
 class StatusCode;
 
@@ -37,6 +36,7 @@ public:
    /// @param contextId [IN] id for PoolSvc persistency service to use for input.
    PoolCollectionConverter(const std::string& collectionType,
 		   const std::string& inputCollection,
+		   unsigned int contextId,
 		   const std::string& query,
 		   const IPoolSvc* svc);
 
@@ -67,6 +67,7 @@ private: // data
    std::string m_collectionType;
    std::string m_connection;
    std::string m_inputCollection;
+   unsigned int m_contextId;
    std::string m_query;
    const IPoolSvc* m_poolSvc;
    pool::ICollection* m_poolCollection;
diff --git a/Database/AthenaPOOL/OutputStreamAthenaPool/python/OutputStreamConfig.py b/Database/AthenaPOOL/OutputStreamAthenaPool/python/OutputStreamConfig.py
index e097435ce35128a542f9ae4094d91925ed7f3c76..8ad93126c1be83c19afea106bb22f428af9baffa 100644
--- a/Database/AthenaPOOL/OutputStreamAthenaPool/python/OutputStreamConfig.py
+++ b/Database/AthenaPOOL/OutputStreamAthenaPool/python/OutputStreamConfig.py
@@ -105,5 +105,4 @@ def OutputStreamCfg(configFlags, streamName, ItemList=[], MetadataItemList=[],
       poolcnvsvc.PoolAttributes += [ "DatabaseName = '" + fileName + "'; ContainerName = 'TTree=Aux.'; CONTAINER_SPLITLEVEL = '1'"]
 
    result.addEventAlgo(outputStream)
-   return result
-
+   return result
\ No newline at end of file
diff --git a/Database/AthenaPOOL/PoolSvc/PoolSvc/IPoolSvc.h b/Database/AthenaPOOL/PoolSvc/PoolSvc/IPoolSvc.h
index 037518d3a7e3ef1ddaa88bde47215e4fd309776d..5bd4251074ffd6fc33b0cbe01ca974daa8bcf672 100644
--- a/Database/AthenaPOOL/PoolSvc/PoolSvc/IPoolSvc.h
+++ b/Database/AthenaPOOL/PoolSvc/PoolSvc/IPoolSvc.h
@@ -95,13 +95,11 @@ public: // Non-static members
    /// @param collectionType [IN] string containing the collection type.
    /// @param connection [IN] string containing the connection.
    /// @param collectionName [IN] string containing the persistent name of the collection.
-   /// @param openMode [IN] ICollection open mode of the collection.
    /// @param contextId [IN] id for PoolSvc persistency service to use for input.
    virtual pool::ICollection* createCollection ATLAS_NOT_THREAD_SAFE
           (const std::string& collectionType,
 	   const std::string& connection,
 	   const std::string& collectionName,
-	   const pool::ICollection::OpenMode& openMode = pool::ICollection::READ,
 	   unsigned int contextId = IPoolSvc::kInputStream) const = 0;
 
    /// @return a token for a container entry.
diff --git a/Database/AthenaPOOL/PoolSvc/src/PoolSvc.cxx b/Database/AthenaPOOL/PoolSvc/src/PoolSvc.cxx
index 2bc26371bbd867e9ecf4f2dd370669b4b3d09909..ec216016684bfd51156542e1993fd16d6d489728 100644
--- a/Database/AthenaPOOL/PoolSvc/src/PoolSvc.cxx
+++ b/Database/AthenaPOOL/PoolSvc/src/PoolSvc.cxx
@@ -439,7 +439,6 @@ pool::ICollection* PoolSvc::createCollection ATLAS_NOT_THREAD_SAFE
                (const std::string& collectionType,
 		const std::string& connection,
 		const std::string& collectionName,
-		const pool::ICollection::OpenMode& openMode,
 		unsigned int contextId) const {
    ATH_MSG_DEBUG("createCollection() type="<< collectionType << ", connection=" << connection
                  << ", name=" << collectionName << ", contextID=" << contextId);
@@ -451,14 +450,9 @@ pool::ICollection* PoolSvc::createCollection ATLAS_NOT_THREAD_SAFE
 	 collection = "PFN:" + collectionName;
       }
    }
-   if (openMode == pool::ICollection::READ) {
-      if (contextId >= m_persistencySvcVec.size()) {
-         ATH_MSG_WARNING("createCollection: Using default input Stream instead of id = " << contextId);
-         contextId = IPoolSvc::kInputStream;
-      }
-   }
    if (contextId >= m_persistencySvcVec.size()) {
-      return(nullptr);
+      ATH_MSG_WARNING("createCollection: Using default input Stream instead of id = " << contextId);
+      contextId = IPoolSvc::kInputStream;
    }
    std::lock_guard<CallMutex> lock(*m_pers_mut[contextId]);
    // Check POOL FileCatalog entry.
@@ -511,10 +505,10 @@ pool::ICollection* PoolSvc::createCollection ATLAS_NOT_THREAD_SAFE
    if (collectionType == "RootCollection" &&
 	   m_persistencySvcVec[contextId]->session().defaultConnectionPolicy().writeModeForNonExisting() != pool::DatabaseConnectionPolicy::RAISE_ERROR) {
       ATH_MSG_INFO("Writing ExplicitROOT Collection - do not pass session pointer");
-      collPtr = collFac->create(collDes, openMode);
+      collPtr = collFac->create(collDes,  pool::ICollection::READ);
    } else {
       try {
-         collPtr = collFac->create(collDes, openMode, &m_persistencySvcVec[contextId]->session());
+         collPtr = collFac->create(collDes, pool::ICollection::READ, &m_persistencySvcVec[contextId]->session());
       } catch (std::exception &e) {
          if (insertFile) {
             std::unique_ptr<pool::IDatabase> dbH = getDbHandle(contextId, connection);
@@ -531,7 +525,7 @@ pool::ICollection* PoolSvc::createCollection ATLAS_NOT_THREAD_SAFE
       std::unique_ptr<pool::IDatabase> dbH = getDbHandle(contextId, connection);
       if (dbH == nullptr) {
          ATH_MSG_INFO("Failed to create FileCatalog entry.");
-      } else if (openMode == pool::ICollection::READ && dbH->fid().empty()) {
+      } else if (dbH->fid().empty()) {
          ATH_MSG_INFO("Cannot retrieve the FID of an existing POOL database: '"
                       << connection << "' - FileCatalog will NOT be updated.");
       } else {
diff --git a/Database/AthenaPOOL/PoolSvc/src/PoolSvc.h b/Database/AthenaPOOL/PoolSvc/src/PoolSvc.h
index db883011c212c1c5df50103491df79a3500373f2..2c77b047d5bf0e458942234c39160692c8cfc650 100644
--- a/Database/AthenaPOOL/PoolSvc/src/PoolSvc.h
+++ b/Database/AthenaPOOL/PoolSvc/src/PoolSvc.h
@@ -100,13 +100,11 @@ public: // Non-static members
    /// @param collectionType [IN] string containing the collection type.
    /// @param connection [IN] string containing the connection.
    /// @param collectionName [IN] string containing the persistent name of the collection.
-   /// @param openMode [IN] ICollection open mode of the collection.
    /// @param contextId [IN] id for PoolSvc persistency service to use for input.
    pool::ICollection* createCollection ATLAS_NOT_THREAD_SAFE
           (const std::string& collectionType,
 	   const std::string& connection,
 	   const std::string& collectionName,
-	   const pool::ICollection::OpenMode& openMode = pool::ICollection::READ,
 	   unsigned int contextId = IPoolSvc::kInputStream) const;
 
    /// @return a token for a container entry.
diff --git a/Event/DumpEventDataToJSON/CMakeLists.txt b/Event/DumpEventDataToJSON/CMakeLists.txt
index d8423e6b5d1868c3160a160d76fa8ecd5f9aa7ec..f97598a7eb5a982e4bb358842837f6086b407c13 100644
--- a/Event/DumpEventDataToJSON/CMakeLists.txt
+++ b/Event/DumpEventDataToJSON/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( DumpEventDataToJSON )
@@ -13,5 +13,4 @@ atlas_add_component( DumpEventDataToJSON
    LINK_LIBRARIES AthenaBaseComps GaudiKernel StoreGateLib TrkExInterfaces TrkTrack nlohmann_json::nlohmann_json xAODCaloEvent xAODEventInfo xAODJet xAODMuon xAODTracking )
 
 # Install files from the package:
-atlas_install_joboptions( share/*.py )
 atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
diff --git a/Event/DumpEventDataToJSON/python/DumpEventDataToJSONConfig.py b/Event/DumpEventDataToJSON/python/DumpEventDataToJSONConfig.py
index 20ca6ba2a8dbfd389abfe914a5fb7c6c4faefdbd..f06ef20251c316d8810588d856a884b0107d23fb 100644
--- a/Event/DumpEventDataToJSON/python/DumpEventDataToJSONConfig.py
+++ b/Event/DumpEventDataToJSON/python/DumpEventDataToJSONConfig.py
@@ -44,9 +44,16 @@ if __name__=="__main__":
     # ConfigFlags.Input.Files = ["../q431/myESD.pool.root"]
         
     # Just enable ID for the moment.
-    ConfigFlags.Detector.GeometryPixel = True     
+    ConfigFlags.Detector.GeometryBpipe   = True 
+    ConfigFlags.Detector.GeometryMDT   = True 
+    ConfigFlags.Detector.GeometryTGC   = True
+    ConfigFlags.Detector.GeometryCSC   = True     
+    ConfigFlags.Detector.GeometryRPC   = True     
+    ConfigFlags.Detector.GeometryTile  = True 
+    ConfigFlags.Detector.GeometryLAr   = True 
+    ConfigFlags.Detector.GeometryPixel = True 
     ConfigFlags.Detector.GeometrySCT   = True 
-    ConfigFlags.Detector.GeometryTRT   = True
+    ConfigFlags.Detector.GeometryTRT   = True  
     
     # This should run serially for the moment.
     ConfigFlags.Concurrency.NumThreads = 1
@@ -59,8 +66,41 @@ if __name__=="__main__":
     cfg=MainServicesCfg(ConfigFlags)
     cfg.merge(PoolReadCfg(ConfigFlags))
     
+    from AtlasGeoModel.GeoModelConfig import GeoModelCfg
+    cfg.merge( GeoModelCfg(ConfigFlags) )
+
+    from MuonConfig.MuonGeometryConfig import MuonGeoModelCfg 
+    cfg.merge( MuonGeoModelCfg(ConfigFlags) )
+
+    from LArGeoAlgsNV.LArGMConfig import LArGMCfg
+    cfg.merge( LArGMCfg(ConfigFlags) )
+
+    from TileGeoModel.TileGMConfig import TileGMCfg
+    cfg.merge( TileGMCfg(ConfigFlags) )
+
+    from BeamPipeGeoModel.BeamPipeGMConfig import BeamPipeGeometryCfg
+    cfg.merge( BeamPipeGeometryCfg(ConfigFlags) ) 
+
+    from PixelGeoModel.PixelGeoModelConfig import PixelGeometryCfg
+    cfg.merge(PixelGeometryCfg(ConfigFlags))
+
+    from SCT_GeoModel.SCT_GeoModelConfig import SCT_GeometryCfg
+    cfg.merge(SCT_GeometryCfg(ConfigFlags))
+
+    from TRT_GeoModel.TRT_GeoModelConfig import TRT_GeometryCfg
+    cfg.merge(TRT_GeometryCfg(ConfigFlags))
+
+    from TrkConfig.AtlasTrackingGeometrySvcConfig import TrackingGeometrySvcCfg
+    cfg.merge(TrackingGeometrySvcCfg(ConfigFlags))
+
+    from TrkConfig.TrackCollectionReadConfig import TrackCollectionReadCfg
+    cfg.merge (TrackCollectionReadCfg (ConfigFlags, 'Tracks'))
+
+    muon_edm_helper_svc = CompFactory.Muon.MuonEDMHelperSvc("MuonEDMHelperSvc")
+    cfg.addService( muon_edm_helper_svc )
+
     # Disable doExtrap if you would prefer not to use the extrapolator.
-    topoAcc=DumpEventDataToJSONAlgCfg(ConfigFlags, doExtrap = False, OutputLevel=VERBOSE, OutputLocation="EventData_new.json")
+    topoAcc=DumpEventDataToJSONAlgCfg(ConfigFlags, doExtrap = False, OutputLevel=VERBOSE, DumpTestEvent=True, OutputLocation="EventData.json")
     cfg.merge(topoAcc)
 
     cfg.run(10)
diff --git a/Event/DumpEventDataToJSON/share/DumpEventDataToJson.py b/Event/DumpEventDataToJSON/share/DumpEventDataToJson.py
deleted file mode 100644
index 915a4ed5808b9cf2519cfa3894d3dfdbdd353c55..0000000000000000000000000000000000000000
--- a/Event/DumpEventDataToJSON/share/DumpEventDataToJson.py
+++ /dev/null
@@ -1,77 +0,0 @@
-from RecExConfig.RecFlags  import rec
-from AthenaCommon.BeamFlags import jobproperties
-from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
-from AthenaCommon.GlobalFlags import globalflags
-athenaCommonFlags.FilesInput.set_Value_and_Lock(['/home/emoyse/master/q431/myESD.pool.root'])
-athenaCommonFlags.AllowIgnoreConfigError = False
-
-rec.AutoConfiguration=['everything']
-rec.readESD.set_Value_and_Lock(True)
-rec.doWriteESD.set_Value_and_Lock(False)
-
-import RecExConfig.AutoConfiguration as auto
-auto.ConfigureFromListOfKeys(rec.AutoConfiguration())
-
-import AthenaPoolCnvSvc.ReadAthenaPool
-svcMgr.EventSelector.InputCollections = athenaCommonFlags.FilesInput()
-
-from AthenaCommon.AlgScheduler import AlgScheduler
-AlgScheduler.OutputLevel( INFO )
-AlgScheduler.ShowControlFlow( True )
-AlgScheduler.ShowDataDependencies( True )
-
-from AthenaCommon.AlgSequence import AlgSequence
-topSequence = AlgSequence()
-if not hasattr(topSequence, "SGInputLoader"):
-  from SGComps.SGCompsConf import SGInputLoader
-  topSequence+=SGInputLoader(OutputLevel=DEBUG, ShowEventDump=False)
-
-# from IOVSvc.IOVSvcConf import CondInputLoader
-# topSequence += CondInputLoader( "CondInputLoader", OutputLevel=DEBUG,  )
-#
-# import StoreGate.StoreGateConf as StoreGateConf
-# svcMgr += StoreGateConf.StoreGateSvc("ConditionStore")
-#
-# from IOVSvc.IOVSvcConf import CondSvc
-# svcMgr += CondSvc()
-
-doExtrap = False
-
-ExtrapolationEngine=""
-if (doExtrap):
-  import MagFieldServices.SetupField
-  from AthenaCommon.DetFlags import DetFlags
-  DetFlags.geometry.ID_setOn()
-  DetFlags.detdescr.ID_setOn()
-  DetFlags.geometry.Calo_setOn()
-  DetFlags.detdescr.Calo_setOn()
-  DetFlags.geometry.Muon_setOn()
-  DetFlags.detdescr.Muon_setOn()
-  # from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
-  print "DetFlags:", DetFlags.Print()
-  from TrkDetDescrSvc.AtlasTrackingGeometrySvc import AtlasTrackingGeometrySvc
-  AtlasTrackingGeometrySvc  = svcMgr.AtlasTrackingGeometrySvc
-  print AtlasTrackingGeometrySvc
-
-  from AtlasGeoModel import SetGeometryVersion
-  from AtlasGeoModel import GeoModelInit
-
-  # from TrkExTools.AtlasExtrapolator import AtlasExtrapolator
-  # VP1ExtraPolatorName='VP1Extrapolator';
-  # VP1Extrapolator = AtlasExtrapolator(name=VP1ExtraPolatorName)
-
-  from TrkExEngine.AtlasExtrapolationEngine import AtlasExtrapolationEngine
-  ExtrapolationEngine = AtlasExtrapolationEngine(name='Extrapolation', nameprefix='Atlas', ToolOutputLevel=INFO)
-  print ExtrapolationEngine
-  ToolSvc += ExtrapolationEngine  
-
-from DumpEventDataToJSON.DumpEventDataToJSONConf import DumpEventDataToJsonAlg
-event_info_key = "EventInfo"
-topSequence += DumpEventDataToJsonAlg(OutputLevel=VERBOSE, EventInfoKey = event_info_key, ExtrapolateTrackParticles=doExtrap, Extrapolator = ExtrapolationEngine)
-
-ServiceMgr.MessageSvc.enableSuppression = False
-ServiceMgr.MessageSvc.Format = "% F%80W%S%7W%R%T %0W%M"
-
-theApp.EvtMax = 2
-theApp.OutputLevel=VERBOSE
-
diff --git a/Event/DumpEventDataToJSON/src/DumpEventDataToJsonAlg.cxx b/Event/DumpEventDataToJSON/src/DumpEventDataToJsonAlg.cxx
index 7fcc956e0f6d9c90503b8446bc4f79f731058025..884297e2005f076fb271655c72e993e2c4390752 100644
--- a/Event/DumpEventDataToJSON/src/DumpEventDataToJsonAlg.cxx
+++ b/Event/DumpEventDataToJSON/src/DumpEventDataToJsonAlg.cxx
@@ -1,149 +1,235 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
-
 #include "GaudiKernel/MsgStream.h"
 #include "Gaudi/Property.h"
 #include "GaudiKernel/Algorithm.h"
+#include "GeoPrimitives/GeoPrimitivesHelpers.h"
 
 #include "DumpEventDataToJsonAlg.h"
 
 #include <string>
 #include <fstream>
+#include <cmath>
 
-DumpEventDataToJsonAlg::DumpEventDataToJsonAlg(const std::string& name, 
-				       ISvcLocator* pSvcLocator) 
-  : AthAlgorithm(name,pSvcLocator)
+DumpEventDataToJsonAlg::DumpEventDataToJsonAlg(const std::string &name,
+                                               ISvcLocator *pSvcLocator)
+    : AthAlgorithm(name, pSvcLocator)
 {
 }
 
 StatusCode DumpEventDataToJsonAlg::initialize()
 {
-  ATH_CHECK( m_eventInfoKey.initialize());
-  ATH_CHECK( m_trackParticleKeys.initialize() );
-  ATH_CHECK( m_jetKeys.initialize() );
-  ATH_CHECK( m_caloClustersKeys.initialize() );
-  ATH_CHECK( m_muonKeys.initialize() );
-  ATH_CHECK( m_trackCollectionKeys.initialize() );
-  
-  if (m_extrapolateTrackParticless) {
-    ATH_CHECK( m_extrapolator.retrieve() );
-  } else {
+  ATH_CHECK(m_eventInfoKey.initialize());
+  ATH_CHECK(m_trackParticleKeys.initialize());
+  ATH_CHECK(m_jetKeys.initialize());
+  ATH_CHECK(m_caloClustersKeys.initialize());
+  ATH_CHECK(m_muonKeys.initialize());
+  ATH_CHECK(m_trackCollectionKeys.initialize());
+
+  if (m_extrapolateTrackParticless)
+  {
+    ATH_CHECK(m_extrapolator.retrieve());
+  }
+  else
+  {
     m_extrapolator.disable();
   }
   return StatusCode::SUCCESS;
 }
 
-StatusCode DumpEventDataToJsonAlg::execute ()
+StatusCode DumpEventDataToJsonAlg::execute()
 {
   SG::ReadHandle<xAOD::EventInfo> eventInfo(m_eventInfoKey);
-  if (!eventInfo.isValid() ){
-    ATH_MSG_WARNING("Did not find xAOD::EventInfo at "<<m_eventInfoKey);
+  if (!eventInfo.isValid())
+  {
+    ATH_MSG_WARNING("Did not find xAOD::EventInfo at " << m_eventInfoKey);
     return StatusCode::SUCCESS;
   }
-    
-  ATH_MSG_VERBOSE("Run num :"<<eventInfo->runNumber()<<" Event num: "<<eventInfo->eventNumber());
+
+  if (m_dumpTestEvent)
+  {
+    prependTestEvent();
+    m_dumpTestEvent = false;
+  }
+
+  ATH_MSG_VERBOSE("Run num :" << eventInfo->runNumber() << " Event num: " << eventInfo->eventNumber());
 
   nlohmann::json j;
-  
+  j["event number"] = eventInfo->eventNumber();
+  j["run number"] = eventInfo->runNumber();
+
   ATH_CHECK(getAndFillArrayOfContainers(j, m_jetKeys, "Jets"));
   ATH_CHECK(getAndFillArrayOfContainers(j, m_trackParticleKeys, "Tracks"));
   ATH_CHECK(getAndFillArrayOfContainers(j, m_muonKeys, "Muons"));
   ATH_CHECK(getAndFillArrayOfContainers(j, m_caloClustersKeys, "CaloClusters"));
   ATH_CHECK(getAndFillArrayOfContainers(j, m_trackCollectionKeys, "Tracks"));
-  
-  std::string key = std::to_string(eventInfo->eventNumber()) + "/" + std::to_string(eventInfo->runNumber());
-  
-  m_eventData[key] = j;
-  
+
+  // For the moment the label is just the event/run number again, but can be manually overwritten in the output file
+  std::string label = std::to_string(eventInfo->eventNumber()) + "/" + std::to_string(eventInfo->runNumber());
+  m_eventData[label] = j;
+
   return StatusCode::SUCCESS;
 }
 
-template< class TYPE >
-StatusCode DumpEventDataToJsonAlg::getAndFillArrayOfContainers(nlohmann::json& event, 
-                                                              const SG::ReadHandleKeyArray< TYPE >& keys, 
-                                                              const std::string jsonType ){
-  for (SG::ReadHandle<TYPE> handle : keys.makeHandles() ){
-    ATH_MSG_VERBOSE("Trying to load "<<handle.key());
-    ATH_CHECK( handle.isValid() );  
-    ATH_MSG_VERBOSE("Got back "<<handle->size());
-    
-    for (auto object : *handle ){
+void DumpEventDataToJsonAlg::prependTestEvent()
+{
+  nlohmann::json j;
+
+  // FIXME - this
+  auto writeEtaPhiLabel = [](float eta, float phi) { return std::to_string(eta) + "/" + std::to_string(phi); };
+
+  j["event number"] = 999;
+  j["run number"] = 999;
+
+  // Here we want to draw some tracks at predefined positons
+  unsigned int maxSteps = 3;
+  Amg::Vector3D trackPos;
+  float phi, eta;
+  for (unsigned int nPhi = 0; nPhi < maxSteps; ++nPhi)
+  {
+    phi = static_cast<float>(nPhi) / static_cast<float>(maxSteps) * M_PI; // Want to range from 0 to M_PI
+    for (unsigned int nEta = 0; nEta < maxSteps; ++nEta)
+    {
+      eta = static_cast<float>(nEta) / static_cast<float>(maxSteps) * 3.0; // Want to range from 0 to 3.0
+      
+      // Create a calo cluster at each value
+      nlohmann::json cluster;
+      cluster["phi"] = phi;
+      cluster["eta"] = eta;
+      cluster["energy"] = 999.9;
+      cluster["label"] = writeEtaPhiLabel(eta, phi);
+
+      j["CaloClusters"]["TestClusters"].push_back(cluster);
+
+      // create a jet at each value
+      nlohmann::json jet;
+      jet["phi"] = phi;
+      jet["eta"] = eta;
+      jet["energy"] = 99999.9;
+      jet["label"] = writeEtaPhiLabel(eta, phi);
+      j["Jets"]["TestJets"].push_back(jet);
+
+      nlohmann::json track;
+      track["chi2"] = 0.0;
+      track["dof"] = 0.0;
+
+      double theta = 2 * std::atan(std::exp(eta));
+      // d0, z0, phi, theta, qOverP
+      track["dparams"] = {0.0, 0.0, phi, theta, 0.0};
+      // Add three positions (less than this might not count as a)
+      for (unsigned int i = 0; i < 4; ++i)
+      {
+        Amg::setRThetaPhi(trackPos, i * 1000., theta, phi);
+        track["pos"].push_back({trackPos.x(), trackPos.y(), trackPos.z()});
+      }
+      track["label"] = writeEtaPhiLabel(eta, phi);
+      j["Tracks"]["TestTracks"].push_back(track);
+    }
+  }
+  m_eventData["Test"] = j;
+}
+
+template <class TYPE>
+StatusCode DumpEventDataToJsonAlg::getAndFillArrayOfContainers(nlohmann::json &event,
+                                                               const SG::ReadHandleKeyArray<TYPE> &keys,
+                                                               const std::string jsonType)
+{
+  for (SG::ReadHandle<TYPE> handle : keys.makeHandles())
+  {
+    ATH_MSG_VERBOSE("Trying to load " << handle.key());
+    ATH_CHECK(handle.isValid());
+    ATH_MSG_VERBOSE("Got back " << handle->size());
+
+    for (auto object : *handle)
+    {
       nlohmann::json tmp = getData(*object);
-      event[jsonType][handle.key()].push_back( tmp );
+      event[jsonType][handle.key()].push_back(tmp);
     }
   }
   return StatusCode::SUCCESS;
 }
 
 // Specialisation for Jets
-template <> 
-nlohmann::json DumpEventDataToJsonAlg::getData( const xAOD::Jet& jet){
+template <>
+nlohmann::json DumpEventDataToJsonAlg::getData(const xAOD::Jet &jet)
+{
   nlohmann::json data;
-  data["phi"]    = jet.phi();
-  data["eta"]    = jet.eta();
+  data["phi"] = jet.phi();
+  data["eta"] = jet.eta();
   data["energy"] = jet.e();
   return data;
 }
 
 // Specialisation for CaloClusters
-template <> 
-nlohmann::json DumpEventDataToJsonAlg::getData( const xAOD::CaloCluster& clust){
+template <>
+nlohmann::json DumpEventDataToJsonAlg::getData(const xAOD::CaloCluster &clust)
+{
   nlohmann::json data;
-  data["phi"]    = clust.phi();
-  data["eta"]    = clust.eta();
+  data["phi"] = clust.phi();
+  data["eta"] = clust.eta();
   data["energy"] = clust.e();
   //data["etaSize"] = clust.getClusterEtaSize(); // empty
   //data["phiSize"] = clust.getClusterPhiSize(); // empty
   return data;
 }
 
-
 // Specialisation for TracksParticles
-template <> 
-nlohmann::json DumpEventDataToJsonAlg::getData( const xAOD::TrackParticle& tp){
+template <>
+nlohmann::json DumpEventDataToJsonAlg::getData(const xAOD::TrackParticle &tp)
+{
   nlohmann::json data;
-  data["chi2"]    = tp.chiSquared();
-  data["dof"]    = tp.numberDoF();
-  data["dparams"] = { tp.d0(), tp.z0(), tp.phi0(), tp.theta(), tp.qOverP() };
-  
-  if (!m_extrapolateTrackParticless){
-    data["pos"] = { { tp.perigeeParameters ().position().x(), tp.perigeeParameters ().position().y(), tp.perigeeParameters ().position().z() } };
-    for (unsigned int i=0; i<tp.numberOfParameters() ; ++i ) {
-      data["pos"].push_back( {tp.parameterX (i), tp.parameterY (i), tp.parameterZ (i)} );
+  data["chi2"] = tp.chiSquared();
+  data["dof"] = tp.numberDoF();
+  data["dparams"] = {tp.d0(), tp.z0(), tp.phi0(), tp.theta(), tp.qOverP()};
+
+  if (!m_extrapolateTrackParticless)
+  {
+    data["pos"] = {{tp.perigeeParameters().position().x(), tp.perigeeParameters().position().y(), tp.perigeeParameters().position().z()}};
+    for (unsigned int i = 0; i < tp.numberOfParameters(); ++i)
+    {
+      data["pos"].push_back({tp.parameterX(i), tp.parameterY(i), tp.parameterZ(i)});
     }
-  } else {
-    std::vector<Amg::Vector3D> positions; 
-    const Trk::Perigee& peri = tp.perigeeParameters ();
-    positions.push_back(Amg::Vector3D(peri.position().x(), peri.position().y(), peri.position().z() ) );
-    
-    Trk::CurvilinearParameters startParameters(peri.position(),peri.momentum(),peri.charge());
+  }
+  else
+  {
+    std::vector<Amg::Vector3D> positions;
+    const Trk::Perigee &peri = tp.perigeeParameters();
+    positions.push_back(Amg::Vector3D(peri.position().x(), peri.position().y(), peri.position().z()));
+
+    Trk::CurvilinearParameters startParameters(peri.position(), peri.momentum(), peri.charge());
     Trk::ExtrapolationCell<Trk::TrackParameters> ecc(startParameters);
     ecc.addConfigurationMode(Trk::ExtrapolationMode::StopAtBoundary);
     ecc.addConfigurationMode(Trk::ExtrapolationMode::CollectPassive);
     ecc.addConfigurationMode(Trk::ExtrapolationMode::CollectSensitive);
     Trk::ExtrapolationCode eCode = m_extrapolator->extrapolate(ecc);
-    if (eCode.isSuccess()){
+    if (eCode.isSuccess())
+    {
       // loop over the collected information
-      for (auto& es : ecc.extrapolationSteps){
-      
+      for (auto &es : ecc.extrapolationSteps)
+      {
+
         // continue if we have parameters
-        const Trk::TrackParameters* parameters = es.parameters;
-        if (parameters){
+        const Trk::TrackParameters *parameters = es.parameters;
+        if (parameters)
+        {
           Amg::Vector3D pos = parameters->position();
-          positions.push_back(pos);        
+          positions.push_back(pos);
           delete parameters;
         }
       }
-      positions.push_back( ecc.endParameters->position() );
-     
+      positions.push_back(ecc.endParameters->position());
+
       // Now add the positions to the output
-      for (auto pos : positions) {
-        data["pos"].push_back( {pos.x(), pos.y(), pos.z()} );
-      } 
-    } else {
-      ATH_MSG_WARNING("Failure in extrapolation for Track with start parameters "<<startParameters);
+      for (auto pos : positions)
+      {
+        data["pos"].push_back({pos.x(), pos.y(), pos.z()});
+      }
+    }
+    else
+    {
+      ATH_MSG_WARNING("Failure in extrapolation for Track with start parameters " << startParameters);
     }
   }
   return data;
@@ -172,52 +258,68 @@ nlohmann::json DumpEventDataToJsonAlg::getData(const Trk::Track &track)
   }
 
   const DataVector<const Trk::MeasurementBase> *measurements = track.measurementsOnTrack();
-  for (auto meas : *measurements)
+  // prefer positions from measurements
+  if (measurements)
   {
-    data["pos"].push_back({meas->globalPosition().x(), meas->globalPosition().y(), meas->globalPosition().z()});
+    for (const Trk::MeasurementBase *meas : *measurements)
+    {
+      data["pos"].push_back({meas->globalPosition().x(), meas->globalPosition().y(), meas->globalPosition().z()});
+    }
+  }
+  else
+  {
+    // .. but trackparameters are okay too!
+    const DataVector<const Trk::TrackParameters> *parameters = track.trackParameters();
+    if (parameters)
+    {
+      for (const Trk::TrackParameters *param : *parameters)
+      {
+        data["pos"].push_back({param->position().x(), param->position().y(), param->position().z()});
+      }
+    }
   }
-
   return data;
 }
 
 // Specialisation for Muons
-template <> 
-nlohmann::json DumpEventDataToJsonAlg::getData( const xAOD::Muon& muon){
+template <>
+nlohmann::json DumpEventDataToJsonAlg::getData(const xAOD::Muon &muon)
+{
   nlohmann::json data;
-  data["Phi"]    = muon.phi();
-  data["Eta"]    = muon.eta();
+  data["Phi"] = muon.phi();
+  data["Eta"] = muon.eta();
 
-  std::vector<std::string> quality={"Tight","Medium","Loose","VeryLoose"};
+  std::vector<std::string> quality = {"Tight", "Medium", "Loose", "VeryLoose"};
   data["Quality"] = quality[static_cast<unsigned int>(muon.quality())];
-  std::vector<std::string> type={"Combined","Standalone","SegmentTagged","CaloTagged", "SiAssociatedForward"};
+  std::vector<std::string> type = {"Combined", "Standalone", "SegmentTagged", "CaloTagged", "SiAssociatedForward"};
   data["Type"] = type[static_cast<unsigned int>(muon.muonType())];
   data["PassedHighPt"] = muon.passesHighPtCuts();
 
-  addLink(muon.clusterLink(), data["LinkedClusters"]);    
-  addLink(muon.inDetTrackParticleLink(), data["LinkedTracks"]);  
+  addLink(muon.clusterLink(), data["LinkedClusters"]);
+  addLink(muon.inDetTrackParticleLink(), data["LinkedTracks"]);
   addLink(muon.muonSpectrometerTrackParticleLink(), data["LinkedTracks"]);
   addLink(muon.extrapolatedMuonSpectrometerTrackParticleLink(), data["LinkedTracks"]);
-    
+
   return data;
 }
 
-template <class TYPE> 
-void DumpEventDataToJsonAlg::addLink( const TYPE& link, nlohmann::json& data){
-  if (link.isValid()){
-    data.push_back( link.dataID()+":"+std::to_string(link.index())  );
+template <class TYPE>
+void DumpEventDataToJsonAlg::addLink(const TYPE &link, nlohmann::json &data)
+{
+  if (link.isValid())
+  {
+    data.push_back(link.dataID() + ":" + std::to_string(link.index()));
   }
 }
 
 StatusCode DumpEventDataToJsonAlg::finalize()
 {
   std::ofstream outputFile(m_outputJSON_Name);
-  if (!outputFile.is_open()) {
-    ATH_MSG_WARNING("Unable to open "<<m_outputJSON_Name<<" for writing.");
+  if (!outputFile.is_open())
+  {
+    ATH_MSG_WARNING("Unable to open " << m_outputJSON_Name << " for writing.");
     return StatusCode::FAILURE;
   }
-  outputFile<<m_eventData;  
+  outputFile << m_eventData;
   return StatusCode::SUCCESS;
 }
-
-
-
diff --git a/Event/DumpEventDataToJSON/src/DumpEventDataToJsonAlg.h b/Event/DumpEventDataToJSON/src/DumpEventDataToJsonAlg.h
index ab541da5b7d5d5f94c5e938050b2b0b6315edb15..280365422f8c2cc69eb871d42d0d6d62f9fd5e5d 100644
--- a/Event/DumpEventDataToJSON/src/DumpEventDataToJsonAlg.h
+++ b/Event/DumpEventDataToJSON/src/DumpEventDataToJsonAlg.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef DUMPEVENTDATATOJSONALG_H
@@ -24,54 +24,50 @@
 */
 class DumpEventDataToJsonAlg : public AthAlgorithm
 {
- public:
-  
+public:
   /// Algorithm constructor
-  DumpEventDataToJsonAlg(const std::string& name, ISvcLocator* pService);
+  DumpEventDataToJsonAlg(const std::string &name, ISvcLocator *pService);
 
   virtual ~DumpEventDataToJsonAlg() = default;
 
   /// inherited from Algorithm
   virtual StatusCode initialize() override;
-  virtual StatusCode execute () override;
+  virtual StatusCode execute() override;
   virtual StatusCode finalize() override;
 
- protected:
-   
-   template <class TYPE> 
-   StatusCode getAndFillArrayOfContainers(nlohmann::json& event, const SG::ReadHandleKeyArray< TYPE >& keys, const std::string jsonType);
-   
-   template <class TYPE> 
-   nlohmann::json getData( const TYPE& object);
-   
-   template <class TYPE> 
-   void addLink( const TYPE& link, nlohmann::json& data);
-   
-   SG::ReadHandleKey<xAOD::EventInfo>                     m_eventInfoKey
-   { this, "EventInfoKey", "EventInfo", "Key for the Event Info" };
-   
-   SG::ReadHandleKeyArray<xAOD::TrackParticleContainer>   m_trackParticleKeys
-   { this, "TrackParticleContainerKeys", {"InDetTrackParticles", "CombinedMuonTrackParticles" }, "Keys for TrackParticle Containers" };
-   
-   SG::ReadHandleKeyArray<xAOD::JetContainer>             m_jetKeys
-   { this, "JetContainerKeys", {"AntiKt4EMTopoJets"}, "Keys for Jet Containers" };
-
-   SG::ReadHandleKeyArray<xAOD::MuonContainer>             m_muonKeys
-   { this, "MuonContainerKeys", {"Muons"}, "Keys for Muon Containers" };
-   
-   SG::ReadHandleKeyArray<xAOD::CaloClusterContainer>      m_caloClustersKeys
-   { this, "CaloClusterContainerKeys", {"CaloCalTopoClusters"}, "Keys for CaloClusters Containers" };
-   
-   SG::ReadHandleKeyArray<TrackCollection>                m_trackCollectionKeys
-   { this, "TrackCollectionKeys", {"Tracks"}, "Keys for Track Containers" };
-  
-   Gaudi::Property<bool>                                  m_extrapolateTrackParticless 
-     {this, "ExtrapolateTrackParticles", false, "If true, attempt to extrapolate tracks and add additional positions."};
-   
-   ToolHandle<Trk::IExtrapolationEngine>                  m_extrapolator { this, "Extrapolator","Trk::ExtrapolationEngine/AtlasExtrapolation"};
-   
-   Gaudi::Property<std::string>                           m_outputJSON_Name 
-     {this, "OutputLocation", "EventData.json", "Default filename for "};
-  nlohmann::json                                         m_eventData;  
+protected:
+  /** Dumps a dummy event with some objects at specific eta/phi coordinates for calibration.*/
+  void prependTestEvent();
+
+  template <class TYPE>
+  StatusCode getAndFillArrayOfContainers(nlohmann::json &event, const SG::ReadHandleKeyArray<TYPE> &keys, const std::string jsonType);
+
+  template <class TYPE>
+  nlohmann::json getData(const TYPE &object);
+
+  template <class TYPE>
+  void addLink(const TYPE &link, nlohmann::json &data);
+
+  SG::ReadHandleKey<xAOD::EventInfo> m_eventInfoKey{this, "EventInfoKey", "EventInfo", "Key for the Event Info"};
+
+  SG::ReadHandleKeyArray<xAOD::TrackParticleContainer> m_trackParticleKeys{this, "TrackParticleContainerKeys", {"InDetTrackParticles", "CombinedMuonTrackParticles"}, "Keys for TrackParticle Containers"};
+
+  SG::ReadHandleKeyArray<xAOD::JetContainer> m_jetKeys{this, "JetContainerKeys", {"AntiKt4EMTopoJets"}, "Keys for Jet Containers"};
+
+  SG::ReadHandleKeyArray<xAOD::MuonContainer> m_muonKeys{this, "MuonContainerKeys", {"Muons"}, "Keys for Muon Containers"};
+
+  SG::ReadHandleKeyArray<xAOD::CaloClusterContainer> m_caloClustersKeys{this, "CaloClusterContainerKeys", {"CaloCalTopoClusters"}, "Keys for CaloClusters Containers"};
+
+  SG::ReadHandleKeyArray<TrackCollection> m_trackCollectionKeys{this, "TrackCollectionKeys", {"Tracks"}, "Keys for Track Containers"};
+
+  Gaudi::Property<bool> m_extrapolateTrackParticless{this, "ExtrapolateTrackParticles", false, "If true, attempt to extrapolate tracks and add additional positions."};
+
+  ToolHandle<Trk::IExtrapolationEngine> m_extrapolator{this, "Extrapolator", "Trk::ExtrapolationEngine/AtlasExtrapolation"};
+
+  Gaudi::Property<std::string> m_outputJSON_Name{this, "OutputLocation", "EventData.json", "Default filename for "};
+
+  Gaudi::Property<bool> m_dumpTestEvent{this, "DumpTestEvent", false, "If true, prepend a test event with some calibration data in it."};
+
+  nlohmann::json m_eventData;
 };
 #endif
diff --git a/Event/PyDumper/python/Dumpers.py b/Event/PyDumper/python/Dumpers.py
index 8839c00b350e8dd3fed903527aa3aa6c9c642287..6fa7df6668ad91135e6544ce7a41e0c8c5970647 100644
--- a/Event/PyDumper/python/Dumpers.py
+++ b/Event/PyDumper/python/Dumpers.py
@@ -1704,6 +1704,25 @@ def dump_TgcClusterOnTrack (p, f):
     return
     
 
+def dump_sTgcClusterOnTrack (p, f):
+    dump_MuonClusterOnTrack (p, f)
+    dump_EL (p.prepRawDataLink(), f)
+    fprint (f, p.detectorElement().identifyHash().value())
+    return
+    
+
+def dump_MMClusterOnTrack (p, f):
+    dump_MuonClusterOnTrack (p, f)
+    dump_EL (p.prepRawDataLink(), f)
+    fprint (f, p.detectorElement().identifyHash().value())
+    fprint (f, '\n    stripDriftDists: ', list(p.stripDriftDists()))
+    fprint (f, '\n    stripDriftDistErrors:')
+    for m in p.stripDriftDistErrors():
+        fprint ('\n      ')
+        dump_AmgMatrix (m, f)
+    return
+    
+
 def dump_CscClusterOnTrack (p, f):
     dump_MuonClusterOnTrack (p, f)
     dump_EL (p.prepRawDataLink(), f)
@@ -1744,6 +1763,10 @@ def dump_measurement (p, f):
         dump_RpcClusterOnTrack (p, f)
     elif nm == 'Muon::TgcClusterOnTrack':
         dump_TgcClusterOnTrack (p, f)
+    elif nm == 'Muon::sTgcClusterOnTrack':
+        dump_sTgcClusterOnTrack (p, f)
+    elif nm == 'Muon::MMClusterOnTrack':
+        dump_MMClusterOnTrack (p, f)
     elif nm == 'Muon::CscClusterOnTrack':
         dump_CscClusterOnTrack (p, f)
     elif nm == 'Trk::PseudoMeasurementOnTrack':
diff --git a/Event/xAOD/xAODBTagging/Root/xAODBTaggingAuxVariableInit.cxx b/Event/xAOD/xAODBTagging/Root/xAODBTaggingAuxVariableInit.cxx
index 059d36975016084c9515bae1b9f4e19a7b2dfcde..0bbb558fe74bed3cf1483d3608e6bcf0e9153f37 100644
--- a/Event/xAOD/xAODBTagging/Root/xAODBTaggingAuxVariableInit.cxx
+++ b/Event/xAOD/xAODBTagging/Root/xAODBTaggingAuxVariableInit.cxx
@@ -24,6 +24,10 @@ AUX_VAR( DL1r_pb );
 AUX_VAR( DL1r_pc );
 AUX_VAR( DL1r_pu );
 
+AUX_VAR( DL1rnn_pb );
+AUX_VAR( DL1rnn_pc );
+AUX_VAR( DL1rnn_pu );
+
 AUX_VAR( MV2c00_discriminant );
 AUX_VAR( MV2c10_discriminant );
 AUX_VAR( MV2c20_discriminant );
diff --git a/Event/xAOD/xAODTrackingCnv/src/TrackParticleCnvAlg.cxx b/Event/xAOD/xAODTrackingCnv/src/TrackParticleCnvAlg.cxx
index a8ba371fea76f6d7f06f72f3141b5e6ffe00ed47..2abe876d6f5a943587328ba5e927962d32e71788 100644
--- a/Event/xAOD/xAODTrackingCnv/src/TrackParticleCnvAlg.cxx
+++ b/Event/xAOD/xAODTrackingCnv/src/TrackParticleCnvAlg.cxx
@@ -89,50 +89,52 @@ namespace xAODMaker {
 
   StatusCode TrackParticleCnvAlg::execute(const EventContext& ctx) const {
 
-    const Rec::TrackParticleContainer *aod=nullptr;
-    const TrackCollection *tracks = nullptr;
-    const xAODTruthParticleLinkVector *truthLinks = nullptr;
-    const TrackParticleTruthCollection *aodTruth = nullptr;
-    const TrackTruthCollection *trackTruth = nullptr;
+    const Rec::TrackParticleContainer* aod = nullptr;
+    const TrackCollection* tracks = nullptr;
+    const xAODTruthParticleLinkVector* truthLinks = nullptr;
+    const TrackParticleTruthCollection* aodTruth = nullptr;
+    const TrackTruthCollection* trackTruth = nullptr;
 
     // Retrieve the AOD particles:
-    if (m_convertAODTrackParticles){
+    if (m_convertAODTrackParticles) {
       SG::ReadHandle<Rec::TrackParticleContainer> rh_aod(m_aod, ctx);
       if (!rh_aod.isValid()) {
-        ATH_MSG_DEBUG("Error finding " << m_aod.key() << " found. Do nothing.");
-        return StatusCode::SUCCESS;
-      } else {
-	aod = rh_aod.cptr();
+        ATH_MSG_ERROR( m_aod.key() << " not found");
+        return StatusCode::FAILURE;
+      }
+      else {
+        aod = rh_aod.cptr();
         ATH_MSG_VERBOSE("Got TrackParticleContainer with key " << m_aod.key() << " found.");
       }
     }
     // Retrieve the Tracks:
-    if (m_convertTracks){
+    if (m_convertTracks) {
       SG::ReadHandle<TrackCollection> rh_tracks(m_tracks, ctx);
       if (!rh_tracks.isValid()) {
-        ATH_MSG_DEBUG("Error finding " << m_tracks.key() << " found. Do nothing.");
+        ATH_MSG_ERROR( m_tracks.key() << " not found");
         return StatusCode::SUCCESS;
-      }  else {
-	tracks = rh_tracks.cptr();
+      }
+      else {
+        tracks = rh_tracks.cptr();
         ATH_MSG_VERBOSE("Got TrackCollection with key " << m_tracks.key() << " found.");
       }
     }
-    if( m_addTruthLink ){
-      if (m_convertAODTrackParticles){
-	SG::ReadHandle<TrackParticleTruthCollection> rh_aodTruth(m_aodTruth, ctx);
+    if (m_addTruthLink) {
+      if (m_convertAODTrackParticles) {
+        SG::ReadHandle<TrackParticleTruthCollection> rh_aodTruth(m_aodTruth, ctx);
         if (!rh_aodTruth.isValid()) {
           ATH_MSG_WARNING("No TrackParticleTruthCollection with key " << m_aodTruth.key() << " found. Do nothing.");
           return StatusCode::SUCCESS;
         }
-	else aodTruth = rh_aodTruth.cptr();
+        else aodTruth = rh_aodTruth.cptr();
       }
-      if (m_convertTracks){
-	SG::ReadHandle<TrackTruthCollection> rh_trackTruth(m_trackTruth, ctx);
+      if (m_convertTracks) {
+        SG::ReadHandle<TrackTruthCollection> rh_trackTruth(m_trackTruth, ctx);
         if (!rh_trackTruth.isValid()) {
           ATH_MSG_WARNING("No DetailedTrackTruthCollection with key " << m_trackTruth.key() << " found. Do nothing.");
           return StatusCode::SUCCESS;
         }
-	else trackTruth = rh_trackTruth.cptr();
+        else trackTruth = rh_trackTruth.cptr();
       }
 
       SG::ReadHandle<xAODTruthParticleLinkVector> rh_truthParticleLinkVec(m_truthParticleLinkVec, ctx);
@@ -145,13 +147,13 @@ namespace xAODMaker {
     if (m_convertTracks) {
       SG::WriteHandle<xAOD::TrackParticleContainer> wh_xaodout(m_xaodout, ctx);
       ATH_CHECK(wh_xaodout.record(std::make_unique<xAOD::TrackParticleContainer>(), std::make_unique<xAOD::TrackParticleAuxContainer>()));
-      convert((*tracks), trackTruth, m_TrackCollectionCnvTool,  wh_xaodout, truthLinks);
+      convert((*tracks), trackTruth, m_TrackCollectionCnvTool, wh_xaodout, truthLinks);
 
       //Monitor track parameters
-      if( m_doMonitoring) m_trackMonitoringTool->monitor_tracks( "Track", "Pass", *wh_xaodout );
+      if (m_doMonitoring) m_trackMonitoringTool->monitor_tracks("Track", "Pass", *wh_xaodout);
 
     }
-    if (m_convertAODTrackParticles){
+    if (m_convertAODTrackParticles) {
       SG::WriteHandle<xAOD::TrackParticleContainer> wh_xaodTrackParticlesout(m_xaodTrackParticlesout, ctx);
       ATH_CHECK(wh_xaodTrackParticlesout.record(std::make_unique<xAOD::TrackParticleContainer>(), std::make_unique<xAOD::TrackParticleAuxContainer>()));
       convert((*aod), aodTruth, m_RecTrackParticleContainerCnvTool, wh_xaodTrackParticlesout, truthLinks);
diff --git a/Generators/GeneratorFilters/GeneratorFilters/TauFilter.h b/Generators/GeneratorFilters/GeneratorFilters/TauFilter.h
index 146ecad0661531495ba26dc1209e7944c24b1ee2..b460fbd07a243ee6cc81423520d2ac6ed5e8f5fa 100644
--- a/Generators/GeneratorFilters/GeneratorFilters/TauFilter.h
+++ b/Generators/GeneratorFilters/GeneratorFilters/TauFilter.h
@@ -1,15 +1,18 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
-
 #ifndef GENERATORFILTERS_TAUFILTER_H
 #define GENERATORFILTERS_TAUFILTER_H
 
 #include "GeneratorModules/GenFilter.h"
 #include "CLHEP/Vector/LorentzVector.h"
 
+class IAtRndmGenSvc;
 
 /// @author Michael Heldmann, Jan 2003
+/// updated by Xin Chen, Nov. 2016
+/// updated by Simon Arnling B????th, Nov. 2017
+
 class TauFilter : public GenFilter {
 public:
 
@@ -22,6 +25,8 @@ public:
 
 private:
 
+  ServiceHandle<IAtRndmGenSvc> m_rand; // Random number generator
+
   int m_Ntau;
   double m_etaMaxe;
   double m_etaMaxmu;
@@ -31,8 +36,34 @@ private:
   double m_pTminmu;
   double m_pTminhad;
 
+  // new option variables:
+  bool m_NewOpt;
+  int m_Nleptau;
+  int m_Nhadtau;
+  double m_etaMaxlep;
+  double m_pTminlep;
+  double m_pTminlep_lead;
+  double m_pTminhad_lead;
+  bool m_ReverseFilter;
+  bool m_HasTightRegion;
+  double m_LooseRejectionFactor;
+  double m_pTminlep_tight;
+  double m_pTminlep_tight_lead;
+  double m_pTminhad_tight;
+  double m_pTminhad_tight_lead;
+  int m_filterEventNumber;
+  
+  // Maximum amount of Taus variables:
+  bool m_useMaxNTaus;
+  int m_maxNtau;
+  int m_maxNhadtau;
+  int m_maxNleptau;
+  
   //double m_eventsaccepted;
   //double m_eventsrefused;
+  
+  double m_events[6];
+  double m_events_sel[6];
 
   double m_eventse;
   double m_eventsmu;
diff --git a/Generators/GeneratorFilters/src/TauFilter.cxx b/Generators/GeneratorFilters/src/TauFilter.cxx
index 253607e6d5709464185fd1e979aebfa9f6a7a118..5edb9ca98938f2f829d39df2edf069025cff5f9b 100644
--- a/Generators/GeneratorFilters/src/TauFilter.cxx
+++ b/Generators/GeneratorFilters/src/TauFilter.cxx
@@ -1,24 +1,48 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration 
 */
-
 #include "GeneratorFilters/TauFilter.h"
 #include "CLHEP/Vector/LorentzVector.h"
+#include "AthenaKernel/IAtRndmGenSvc.h"
+#include "CLHEP/Random/RandomEngine.h"
 
 TauFilter::TauFilter( const std::string& name, ISvcLocator* pSvcLocator)
   : GenFilter( name,pSvcLocator ),
+    m_rand("AtRndmGenSvc", name),
     m_eventse(0), m_eventsmu(0), m_eventshad(0), 
     m_eventseacc(0), m_eventsmuacc(0), m_eventshadacc(0)
 {
   declareProperty( "Ntaus", m_Ntau = 1 );
+  declareProperty( "MaxNtaus", m_maxNtau = 100 );
   declareProperty( "EtaMaxe", m_etaMaxe = 2.5 );
   declareProperty( "EtaMaxmu", m_etaMaxmu = 2.5 );
   declareProperty( "EtaMaxhad", m_etaMaxhad = 2.5 );
 
-  // pt cuts for a0 -> tau + atau -> l + l + X
   declareProperty( "Ptcute", m_pTmine = 12000.0 );
   declareProperty( "Ptcutmu", m_pTminmu = 12000.0 );
   declareProperty( "Ptcuthad", m_pTminhad = 12000.0 );
+
+  // new options:
+  declareProperty( "UseNewOptions", m_NewOpt = false );
+  declareProperty( "UseMaxNTaus", m_useMaxNTaus = false );
+  declareProperty( "Nhadtaus", m_Nhadtau = 0 );
+  declareProperty( "MaxNhadtaus", m_maxNhadtau = 100 );
+  declareProperty( "Nleptaus", m_Nleptau = 0 );
+  declareProperty( "MaxNleptaus", m_maxNleptau = 100 );
+  declareProperty( "EtaMaxlep", m_etaMaxlep = 2.6 );
+  declareProperty( "Ptcutlep", m_pTminlep = 7000.0 );
+  declareProperty( "Ptcutlep_lead", m_pTminlep_lead = 7000.0);
+  declareProperty( "Ptcuthad_lead", m_pTminhad_lead = 12000.0 );
+  declareProperty( "ReverseFilter", m_ReverseFilter = false);
+  
+  declareProperty( "HasTightRegion", m_HasTightRegion = false);
+  declareProperty( "LooseRejectionFactor", m_LooseRejectionFactor = 1);
+  declareProperty( "Ptcutlep_tight", m_pTminlep_tight = 7000.0 );
+  declareProperty( "Ptcutlep_tight_lead", m_pTminlep_tight_lead = 7000.0 );
+  declareProperty( "Ptcuthad_tight", m_pTminhad_tight = 12000.0 );
+  declareProperty( "Ptcuthad_tight_lead", m_pTminhad_tight_lead = 12000.0 );
+
+  declareProperty( "filterEventNumber", m_filterEventNumber = 0 );
 }
 
 
@@ -29,20 +53,42 @@ StatusCode TauFilter::filterInitialize() {
   m_eventseacc = 0;
   m_eventsmuacc = 0;
   m_eventshadacc = 0;
+
+  for(int i=0; i<6; i++) {
+    m_events[i] = 0; m_events_sel[i] = 0;
+  }
+
+  if (m_rand.retrieve().isFailure()) {
+    ATH_MSG_ERROR("Unable to retrieve AtRndmGenSvc " << m_rand);
+    return StatusCode::FAILURE;
+  }
+  
   return StatusCode::SUCCESS;
 }
 
 
 StatusCode TauFilter::filterFinalize() {
-  ATH_MSG_INFO(" , e: " << m_eventse << " , mu: " << m_eventsmu << " , had: " << m_eventshad <<
-               " , eacc: " << m_eventseacc << " , muacc: " << m_eventsmuacc << " , hadacc: " << m_eventshadacc);
+  if(m_NewOpt) {
+    ATH_MSG_INFO("Sum of Events total: " << m_events[0] << " , selected: " << m_events_sel[0]);
+    ATH_MSG_INFO("Sum of Events with pos. weights total: " << m_events[1] << " , selected: " << m_events_sel[1]);
+    ATH_MSG_INFO("Sum of Events with neg. weights total: " << m_events[2] << " , selected: " << m_events_sel[2]);
+    ATH_MSG_INFO("Sum of weights total: " << m_events[3] << " , selected: " << m_events_sel[3]);
+    ATH_MSG_INFO("Sum of pos. weights total: " << m_events[4] << " , selected: " << m_events_sel[4]);
+    ATH_MSG_INFO("Sum of neg. weights total: " << m_events[5] << " , selected: " << m_events_sel[5]);
+  }
+  else {
+    ATH_MSG_INFO(" , e: " << m_eventse << " , mu: " << m_eventsmu << " , had: " << m_eventshad <<
+		 " , eacc: " << m_eventseacc << " , muacc: " << m_eventsmuacc << " , hadacc: " << m_eventshadacc);
+  }
+
   return StatusCode::SUCCESS;
 }
 
 
 CLHEP::HepLorentzVector TauFilter::sumDaughterNeutrinos( HepMC::ConstGenParticlePtr part ) {
   CLHEP::HepLorentzVector nu( 0, 0, 0, 0);
-  if ( ( std::abs( part->pdg_id() ) == 12 ) || ( std::abs( part->pdg_id() ) == 14 ) || ( std::abs( part->pdg_id() ) == 16 ) ) {
+  if ( ( (std::abs( part->pdg_id() ) == 12 ) || ( std::abs( part->pdg_id() ) == 14 ) || ( std::abs( part->pdg_id() ) == 16 )) 
+       && part->status() != 3) {
     nu.setPx(part->momentum().px());
     nu.setPy(part->momentum().py());
     nu.setPz(part->momentum().pz());
@@ -51,77 +97,248 @@ CLHEP::HepLorentzVector TauFilter::sumDaughterNeutrinos( HepMC::ConstGenParticle
 
   if (part->end_vertex() == 0) return nu;
 
- for ( auto beg: *(part->end_vertex())) nu += sumDaughterNeutrinos( beg );
+  HepMC::GenVertex::particles_out_const_iterator begin = part->end_vertex()->particles_out_const_begin();
+  HepMC::GenVertex::particles_out_const_iterator end = part->end_vertex()->particles_out_const_end();
+  for ( ; begin != end; begin++ ) nu += sumDaughterNeutrinos( *begin );
+
+//  for ( auto beg: *(part->end_vertex())) nu += sumDaughterNeutrinos( beg ); //when this replace the 3 lines above the loop does not work (?)
 
   return nu;
 }
 
 
 StatusCode TauFilter::filterEvent() {
+  // Get random number engine
+  CLHEP::HepRandomEngine* rndm(0);
+  if(m_HasTightRegion) {
+    rndm = m_rand->GetEngine("TauFilter");
+    if (!rndm) {
+      ATH_MSG_ERROR("Failed to retrieve random number engine for TauFilter");
+      setFilterPassed(false);
+      return StatusCode::SUCCESS;
+    }
+  }
+  
+  HepMC::GenParticlePtr tau;
   CLHEP::HepLorentzVector mom_tauprod;   // will contain the momentum of the products of the tau decay
   CLHEP::HepLorentzVector tauvis;
   CLHEP::HepLorentzVector nutau;
+  tau = 0;
   int ntau = 0;
 
+  double ptlep_max = 0;
+  double pthad_max = 0;
+  int ntaulep = 0;
+  int ntauhad = 0;
+  int ntaulep_tight = 0;
+  int ntauhad_tight = 0;
+  double weight = 1;
+
   McEventCollection::const_iterator itr;
-  for (itr = events()->begin(); itr!=events()->end(); ++itr) {
+  for (itr = events_const()->begin(); itr!=events_const()->end(); ++itr) {
+    int eventNumber = (*itr)->event_number();
+
+    if(m_filterEventNumber==1 && (eventNumber%2)==0) {
+      setFilterPassed(false);
+      return StatusCode::SUCCESS;
+    }
+    else if(m_filterEventNumber==2 && (eventNumber%2)==1) {
+      setFilterPassed(false);
+      return StatusCode::SUCCESS;
+    }
+    
     const HepMC::GenEvent* genEvt = (*itr);
-    for ( auto  tau: *genEvt) {
+    HepMC::WeightContainer wgtsC = genEvt->weights();
+    weight = wgtsC.size() > 0 ? wgtsC[0] : 1;
+
+    for (HepMC::GenEvent::particle_const_iterator pitr = genEvt->particles_begin(); pitr != genEvt->particles_end(); ++pitr) {
       // Look for the first tau with genstat != 3
-      if (std::abs(tau->pdg_id()) != 15 || tau->status() == 3)  continue;
-        ATH_MSG_DEBUG("found tau with barcode " << HepMC::barcode(tau) << " status " << tau->status());
+      if (abs((*pitr)->pdg_id()) == 15 && (*pitr)->status() != 3) {
+        tau = (*pitr);
+        ATH_MSG_DEBUG("found tau with barcode " << tau->barcode() << " status " << (*pitr)->status());
         ATH_MSG_DEBUG("pT\t\teta\tphi\tid");
         ATH_MSG_DEBUG(tau->momentum().perp() << "\t" <<
                       tau->momentum().eta() << "\t" <<
                       tau->momentum().phi() << "\t" <<
                       tau->pdg_id() << "\t");
-        int leptonic = 0;
-        if ( tau->production_vertex()) continue;
-        for (auto beg: *(tau->end_vertex())) {
-          if ( beg->production_vertex() != tau->end_vertex() ) continue;
-          if ( std::abs( beg->pdg_id() ) == 12 ) leptonic = 1;
-          if ( std::abs( beg->pdg_id() ) == 14 ) leptonic = 2;
-          if ( std::abs( beg->pdg_id() ) == 15 ) leptonic = 11;
-        }
 
-        if (leptonic == 11) {
+        HepMC::GenVertex::particles_out_const_iterator begin = tau->end_vertex()->particles_out_const_begin();
+        HepMC::GenVertex::particles_out_const_iterator end = tau->end_vertex()->particles_out_const_end();
+        int tauType = 0; 
+        //TauType initialized as 0. tauType = 1 is an Tau_el, tauType = 2 is an Tau_mu, tauType = 0 is an Tau_had, tauType = 11 is a tau with tau parent, e.g a photon radiation event.
+        
+        for ( ; begin != end; begin++ ) {
+          if ( (*begin)->production_vertex() != tau->end_vertex() ) continue; 
+         
+          else if ( abs( (*begin)->pdg_id() ) == 12 ) tauType = 1;   //Tau decays into an electron
+         
+          else if ( abs( (*begin)->pdg_id() ) == 14 ) tauType = 2;   //Tau decays into an muon
+                  	
+          else if ( abs( (*begin)->pdg_id() ) == 15 ) tauType = 11;  //Tau radiates a particle and decays into another tau
+        
+				}
+
+				if (tauType == 11) {
           ATH_MSG_DEBUG("tau has a tau as daughter - skipping");
           continue;
         }
         nutau = sumDaughterNeutrinos(tau);
 
         ATH_MSG_DEBUG("pT\t\teta\tphi\tlh");
-        ATH_MSG_DEBUG(nutau.perp() << "\t" << nutau.eta() << "\t" << nutau.phi() << "\t" << leptonic);
+        ATH_MSG_DEBUG(nutau.perp() << "\t" << nutau.eta() << "\t" << nutau.phi() << "\t" << tauType);
 
         tauvis.setPx(tau->momentum().px()-nutau.px());
         tauvis.setPy(tau->momentum().py()-nutau.py());
         tauvis.setPz(tau->momentum().pz()-nutau.pz());
         tauvis.setE(tau->momentum().e()-nutau.e());
 
-        ATH_MSG_DEBUG(tauvis.perp() << "\t" << tauvis.eta() << "\t" << tauvis.phi() << "\t" << leptonic);
+        ATH_MSG_DEBUG(tauvis.perp() << "\t" << tauvis.eta() << "\t" << tauvis.phi() << "\t" << tauType);
 
-        if ( leptonic == 1 ) {
-          m_eventse++;
-          if ( tauvis.perp() < m_pTmine ) continue;
-          if ( std::abs( tauvis.eta() ) > m_etaMaxe ) continue;
-          ntau++;
-          m_eventseacc++;
-        } else if ( leptonic == 2 ) {
-          m_eventsmu++;
-          if ( tauvis.perp() < m_pTminmu ) continue;
-          if ( std::abs( tauvis.eta() ) > m_etaMaxmu ) continue;
-          ntau++;
-          m_eventsmuacc++;
-        } else if ( leptonic == 0 ) {
+        if ( tauType == 1 ) {  
+					if(!m_NewOpt) {
+						m_eventse++;
+						if ( tauvis.perp() < m_pTmine ) continue;
+						if ( std::abs( tauvis.eta() ) > m_etaMaxe ) continue;
+						ntau++;
+						m_eventseacc++;
+					}
+					else {
+						if ( tauvis.perp() < m_pTminlep ) continue;
+						if ( std::abs( tauvis.eta() ) > m_etaMaxlep ) continue;
+						ntaulep++;
+						if ( tauvis.perp() >= ptlep_max ) ptlep_max = tauvis.perp();
+						if ( tauvis.perp() >= m_pTminlep_tight ) ntaulep_tight++;
+					}
+        }
+         
+        else if ( tauType == 2 ) {
+					if(!m_NewOpt) {
+						m_eventsmu++;
+						if ( tauvis.perp() < m_pTminmu ) continue;
+						if ( std::abs( tauvis.eta() ) > m_etaMaxmu ) continue;
+						ntau++;
+						m_eventsmuacc++;
+					}
+					else {
+						if ( tauvis.perp() < m_pTminlep ) continue;
+						if ( std::abs( tauvis.eta() ) > m_etaMaxlep ) continue;
+						ntaulep++;
+						if ( tauvis.perp() >= ptlep_max ) ptlep_max = tauvis.perp();
+						if ( tauvis.perp() >= m_pTminlep_tight ) ntaulep_tight++;
+					}
+        } 
+        
+        else if ( tauType == 0 ) {
           m_eventshad++;
           if ( tauvis.perp() < m_pTminhad ) continue;
           if ( std::abs( tauvis.eta() ) > m_etaMaxhad ) continue;
           ntau++;
           m_eventshadacc++;
+					ntauhad++;
+					if ( tauvis.perp() >= pthad_max ) pthad_max = tauvis.perp();
+					if ( tauvis.perp() >= m_pTminhad_tight ) ntauhad_tight++;
         }
+        
+        else {
+        	 ATH_MSG_DEBUG("Could not find a tauType! Something went wrong.");
+        	 std::cout << std::endl << std::endl <<"************    COULD NOT FIND A TAU TYPE   *****************" << std::endl << std::endl;
+        }	 
+      }
+    }
+  }
+
+  bool pass1 = ( ntaulep + ntauhad >= m_Ntau    //For use with UseNewOptions
+		 && ntaulep >= m_Nleptau
+		 && ntauhad >= m_Nhadtau
+		 && (ntaulep<2 || ptlep_max>=m_pTminlep_lead)
+		 && (ntauhad<2 || pthad_max>=m_pTminhad_lead)
+		 );
+  bool pass2 = ( ntaulep_tight + ntauhad_tight >= m_Ntau   //For use with UseNewOptions + HssTightRegion
+		 && ntaulep_tight >= m_Nleptau
+		 && ntauhad_tight >= m_Nhadtau
+		 && (ntaulep_tight<2 || ptlep_max>=m_pTminlep_tight_lead)
+		 && (ntauhad_tight<2 || pthad_max>=m_pTminhad_tight_lead)
+		 );
+	
+	bool pass3 = (ntaulep + ntauhad >= m_Ntau    //For use with UseNewOptions + UseMaxNTaus
+		 && ntaulep + ntauhad <= m_maxNtau	
+		 && ntaulep >= m_Nleptau
+		 && ntauhad >= m_Nhadtau
+		 && ntaulep <= m_maxNleptau
+		 && ntauhad <= m_maxNhadtau
+		 );
+		 
+	bool pass = false;  //Initializing the pass variable that will be checked to se if the filter is passed.
+	
+	if (m_NewOpt) pass = pass1;
+	if (m_useMaxNTaus) pass = pass3;
+		
+	double extra_weight = 1;
+  if(m_NewOpt && m_HasTightRegion) {
+    if (pass2) {
+      pass = pass2;
+      extra_weight = 1/m_LooseRejectionFactor;
+      weight *= extra_weight;
+    }
+    else if (pass1) {
+      double rnd = rndm->flat(); // a random number between (0,1)
+      if(rnd > 1/m_LooseRejectionFactor) pass = false;
+      else pass = true;
+    }
+    else pass = false;
+  }
+
+  m_events[0]++;
+  m_events[3] += weight;
+  if(weight>=0) {
+    m_events[1]++;
+    m_events[4] += weight;
+  }
+  else {
+    m_events[2]++;
+    m_events[5] += weight;
+  }
+
+  if(pass) {
+    m_events_sel[0]++;
+    m_events_sel[3] += weight;
+    if(weight>=0) {
+      m_events_sel[1]++;
+      m_events_sel[4] += weight;
+    }
+    else {
+      m_events_sel[2]++;
+      m_events_sel[5] += weight;
+    }
+  }
+
+  if(m_NewOpt && m_HasTightRegion) {
+    // Get MC event collection for setting weight
+    const DataHandle<McEventCollection> mecc = 0;
+    if ( evtStore()->retrieve( mecc ).isFailure() || !mecc ){
+      setFilterPassed(false);
+      ATH_MSG_ERROR("Could not retrieve MC Event Collection - weight might not work");
+      return StatusCode::SUCCESS;
+    }
+
+    // Event passed.  Will weight events
+    McEventCollection* mec = const_cast<McEventCollection*> (&(*mecc));
+    for (unsigned int i = 0; i < mec->size(); ++i) {
+      if (!(*mec)[i]) continue;
+      double existingWeight = (*mec)[i]->weights().size()>0 ? (*mec)[i]->weights()[0] : 1.;
+      if ((*mec)[i]->weights().size()>0) {
+	(*mec)[i]->weights()[0] = existingWeight*extra_weight;
+      } else {
+	(*mec)[i]->weights().push_back( existingWeight*extra_weight );
+      }
     }
   }
 
-  setFilterPassed(ntau >= m_Ntau );
+	if(!m_NewOpt) pass = (ntau >= m_Ntau);  //If UseNewOptions is not enabled, only look at total number of taus present.
+	
+	if (m_ReverseFilter) pass = !pass; //If reverse filter is active, flip the truth value of pass
+	
+	setFilterPassed(pass);
+  
   return StatusCode::SUCCESS;
 }
diff --git a/Generators/Pythia8_i/test/test_01_Z_tautau.sh b/Generators/Pythia8_i/test/test_01_Z_tautau.sh
index 0435ddc0dc8e2238934bcc2c5bd55848a797c6f1..deecb9faa332621fbaa9994deb143d44d9ac9859 100755
--- a/Generators/Pythia8_i/test/test_01_Z_tautau.sh
+++ b/Generators/Pythia8_i/test/test_01_Z_tautau.sh
@@ -16,9 +16,10 @@ Gen_tf.py --ecmEnergy=13000. --maxEvents=10000 --firstEvent=-1 --randomSeed=1234
 
 echo "art-result:$? Gen_tf"
 
-source `which setupRivet`
+asetup 22.6.1,AthGeneration
+source setupRivet
 
-python rootconvert.py MyOutput.yoda.gz
+python /cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/Pythia8i/rootconvert.py MyOutput.yoda.gz
 
 echo "art-result: $? convert"
 
diff --git a/Generators/Pythia8_i/test/test_02_minbias.sh b/Generators/Pythia8_i/test/test_02_minbias.sh
index abd918b4e44e04f3f6469566d2a4692806b33f5e..e5256e6fb912a15f00944b452b481305b5f3eba4 100755
--- a/Generators/Pythia8_i/test/test_02_minbias.sh
+++ b/Generators/Pythia8_i/test/test_02_minbias.sh
@@ -13,10 +13,11 @@
 
 Gen_tf.py --ecmEnergy=13000. --maxEvents=10000 --firstEvent=-1 --randomSeed=123456 --outputEVNTFile=EVNT.root --outputYODAFile=MyOutput.yoda.gz --postInclude=/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/Pythia8i/JO_MC/JO_MC_minbias.py --jobConfig=421113
 
-source setupRivet.sh
-
 echo "art-result:$? Gen_tf"
 
+asetup 22.6.1,AthGeneration
+source setupRivet
+
 python /cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/Pythia8i/rootconvert.py MyOutput.yoda.gz
 
 dcubeName = "Pythia8i"
diff --git a/InnerDetector/InDetConfig/python/TrackRecoConfig.py b/InnerDetector/InDetConfig/python/TrackRecoConfig.py
index 3fe4ecd42cc69a58285f873a51a7bf0a772fbe70..fca7b6ca9863d7aa8c9768245b9dbb1e75a3e8de 100644
--- a/InnerDetector/InDetConfig/python/TrackRecoConfig.py
+++ b/InnerDetector/InDetConfig/python/TrackRecoConfig.py
@@ -269,6 +269,15 @@ def TrackRecoCfg(flags):
     result.merge(TrackingSiPatternCfg(flags, [], "ResolvedTracks", "SiSPSeededTracks"))
     result.merge(TrackParticleCnvAlgCfg(flags, TrackContainerName="ResolvedTracks"))
 
+    from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
+    toAOD = ["xAOD::TrackParticleContainer#InDetTrackParticles", "xAOD::TrackParticleAuxContainer#InDetTrackParticlesAux."]
+    toESD = []
+    if flags.Output.doWriteESD:
+        result.merge(OutputStreamCfg(flags, "ESD", ItemList=toAOD+toESD))
+
+    if flags.Output.doWriteAOD:
+        result.merge(OutputStreamCfg(flags, "AOD", ItemList=toAOD ))
+    
     return result
 
 if __name__ == "__main__":
diff --git a/InnerDetector/InDetDigitization/PixelDigitization/src/FEI3SimTool.cxx b/InnerDetector/InDetDigitization/PixelDigitization/src/FEI3SimTool.cxx
index b946d8ce208f6b86801f0f0b286cddcb82c4546f..1e083cd6c688eb4be6e6eb04ed4ab987f5317cbc 100644
--- a/InnerDetector/InDetDigitization/PixelDigitization/src/FEI3SimTool.cxx
+++ b/InnerDetector/InDetDigitization/PixelDigitization/src/FEI3SimTool.cxx
@@ -3,6 +3,7 @@
  */
 
 #include "FEI3SimTool.h"
+#include "InDetReadoutGeometry/SiDetectorElement.h"
 
 FEI3SimTool::FEI3SimTool(const std::string& type, const std::string& name, const IInterface* parent) :
   FrontEndSimTool(type, name, parent) {
@@ -64,7 +65,8 @@ void FEI3SimTool::process(SiChargedDiodeCollection& chargedDiodes, PixelRDO_Coll
     // Merge ganged pixel
     InDetDD::SiCellId cellID = chargedDiodes.element()->cellIdFromIdentifier(chargedDiodes.getId(
                                                                                (*i_chargedDiode).first));
-    InDetDD::SiCellId gangedCell = chargedDiodes.element()->gangedCell(cellID);
+    const InDetDD::SiDetectorElement * siDetEl = static_cast<const InDetDD::SiDetectorElement *>(chargedDiodes.element());
+    InDetDD::SiCellId gangedCell = siDetEl->gangedCell(cellID);
     Identifier gangedID = chargedDiodes.element()->identifierFromCellId(gangedCell);
     if (gangedCell.isValid()) {
       SiChargedDiode* gangedChargeDiode = chargedDiodes.find(gangedID);
diff --git a/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_DigitizationTool.cxx b/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_DigitizationTool.cxx
index 49cf21f963c3784ac42c3b4228d9a41f15cb39ed..3e2f75b7119cd442674acc85b493f215cf339b96 100644
--- a/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_DigitizationTool.cxx
+++ b/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_DigitizationTool.cxx
@@ -639,8 +639,7 @@ std::unique_ptr<SCT_RDO_Collection> SCT_DigitizationTool::createRDO(SiChargedDio
         // create new SCT RDO
         InDetDD::SiReadoutCellId roCell{(*i_chargedDiode).second.getReadoutCell()};
         int strip{roCell.strip()};
-        const InDetDD::SiDetectorDesign& detDesign{collection->design()};
-        const InDetDD::SCT_ModuleSideDesign& sctDesign{dynamic_cast<const InDetDD::SCT_ModuleSideDesign&>(detDesign)};
+        const InDetDD::SCT_ModuleSideDesign& sctDesign{static_cast<const InDetDD::SCT_ModuleSideDesign&>(collection->design())};
         int row2D{sctDesign.row(strip)};
         Identifier id_readout;
         if (row2D < 0) { // SCT sensors
@@ -816,8 +815,7 @@ void SCT_DigitizationTool::addSDO(SiChargedDiodeCollection* collection, SG::Writ
     if (real_particle_hit or m_createNoiseSDO) {
       InDetDD::SiReadoutCellId roCell{(*i_chargedDiode).second.getReadoutCell()};
       int strip{roCell.strip()};
-      const InDetDD::SiDetectorDesign& detDesign{collection->design()};
-      const InDetDD::SCT_ModuleSideDesign& sctDesign{dynamic_cast<const InDetDD::SCT_ModuleSideDesign&>(detDesign)};
+      const InDetDD::SCT_ModuleSideDesign& sctDesign{dynamic_cast<const InDetDD::SCT_ModuleSideDesign&>(collection->design())};
 
       int row2D{sctDesign.row(strip)};
       Identifier id_readout;
diff --git a/InnerDetector/InDetDigitization/SiDigitization/CMakeLists.txt b/InnerDetector/InDetDigitization/SiDigitization/CMakeLists.txt
index 250ac67dd5dfb6912a3d305f6d8f39fb6214edbc..94f21af6e011f8e64f68386145da1f807a58d88d 100644
--- a/InnerDetector/InDetDigitization/SiDigitization/CMakeLists.txt
+++ b/InnerDetector/InDetDigitization/SiDigitization/CMakeLists.txt
@@ -9,5 +9,5 @@ atlas_add_library( SiDigitization
                    src/SiChargedDiodeCollection.cxx
                    src/SiSurfaceCharge.cxx
                    PUBLIC_HEADERS SiDigitization
-                   LINK_LIBRARIES AthenaKernel AthAllocators Identifier GaudiKernel InDetReadoutGeometry ReadoutGeometryBase InDetSimEvent )
+                   LINK_LIBRARIES AthenaKernel AthAllocators Identifier GaudiKernel ReadoutGeometryBase InDetSimEvent )
 
diff --git a/InnerDetector/InDetDigitization/SiDigitization/SiDigitization/IAmplifier.h b/InnerDetector/InDetDigitization/SiDigitization/SiDigitization/IAmplifier.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a3c8637044f77d48768849b9900764750d0a1ef
--- /dev/null
+++ b/InnerDetector/InDetDigitization/SiDigitization/SiDigitization/IAmplifier.h
@@ -0,0 +1,48 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * IAmplifier.h
+ * Header file for abstract base class IAmplier 
+ */
+
+#ifndef SIDIGITIZATION_IAMPLIFIER_H
+#define SIDIGITIZATION_IAMPLIFIER_H
+
+#include "GaudiKernel/IAlgTool.h"
+#include "InDetSimEvent/SiTotalCharge.h"
+
+#include <vector>
+
+static const InterfaceID IID_IAmplifier("IAmplifier", 1, 0);
+
+class IAmplifier : virtual public IAlgTool {
+
+  ///////////////////////////////////////////////////////////////////
+  // Public methods:
+  ///////////////////////////////////////////////////////////////////
+ public:
+  typedef SiTotalCharge::list_t list_t;
+
+  //Retrieve interface ID
+  static const InterfaceID& interfaceID() { return IID_IAmplifier; }
+
+  // Destructor:
+  virtual ~IAmplifier() {}
+
+  ///////////////////////////////////////////////////////////////////
+  // Pure virtual methods:
+  ///////////////////////////////////////////////////////////////////
+
+  // process the collection of charged diodes
+  /** main purpose: CR-RC^3 response to a list of charges with times */
+  virtual float response(const list_t& Charges, const float timeOverThreshold) const =0;
+  virtual void response(const list_t& Charges, const float timeOverThreshold, std::vector<float>& resp) const =0;
+
+  /** Neighbour strip cross talk response strip to a list of charges with times */
+  virtual float crosstalk(const list_t& Charges, const float timeOverThreshold) const =0;
+  virtual void crosstalk(const list_t& Charges, const float timeOverThreshold, std::vector<float> &resp) const =0;
+};
+
+#endif // SIDIGITIZATION_IAMPLIFIER_H
diff --git a/InnerDetector/InDetDigitization/SiDigitization/SiDigitization/IFrontEnd.h b/InnerDetector/InDetDigitization/SiDigitization/SiDigitization/IFrontEnd.h
new file mode 100644
index 0000000000000000000000000000000000000000..261ad44e984b681d3382381782a1af2d567e3035
--- /dev/null
+++ b/InnerDetector/InDetDigitization/SiDigitization/SiDigitization/IFrontEnd.h
@@ -0,0 +1,42 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * IFrontEnd.h
+ * Header file for interface class for FrontEnd
+ * (c) ATLAS Detector software
+ */
+
+#ifndef SIDIGITIZATION_IFRONTEND_H
+#define SIDIGITIZATION_IFRONTEND_H
+
+//Inheritance
+#include "SiDigitization/ISiChargedDiodesProcessorTool.h"
+#include "SiDigitization/SiChargedDiode.h"
+
+//methods
+#include "Identifier/Identifier.h"
+class SiChargedDiodeCollection;
+namespace CLHEP {
+  class HepRandomEngine;
+}
+
+static const InterfaceID IID_IFrontEnd("IFrontEnd", 1, 0);
+
+class IFrontEnd : virtual public ISiChargedDiodesProcessorTool {
+
+  ///////////////////////////////////////////////////////////////////
+  // Public methods:
+  ///////////////////////////////////////////////////////////////////
+ public:
+
+  //** Retrieve interface ID */
+  static const InterfaceID& interfaceID() { return IID_IFrontEnd; }
+
+  //** Destructor: */
+  virtual ~IFrontEnd() {}
+
+};
+
+#endif // SIDIGITIZATION_IFRONTEND_H
diff --git a/InnerDetector/InDetDigitization/SiDigitization/SiDigitization/IRandomDisabledCellGenerator.h b/InnerDetector/InDetDigitization/SiDigitization/SiDigitization/IRandomDisabledCellGenerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..cb4a5755ebaacb8f3638a17ed350d1c2c88a9161
--- /dev/null
+++ b/InnerDetector/InDetDigitization/SiDigitization/SiDigitization/IRandomDisabledCellGenerator.h
@@ -0,0 +1,42 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * IRandomDisabledCellGenerator.h
+ * Header file for interface class for RandomDisabledCellGenerator
+ * (c) ATLAS Detector software
+ */
+
+#ifndef SIDIGITIZATION_IRANDOMDISABLEDCELLGENERATOR_H
+#define SIDIGITIZATION_IRANDOMDISABLEDCELLGENERATOR_H
+
+//Inheritance
+#include "SiDigitization/ISiChargedDiodesProcessorTool.h"
+
+//methods
+class SiChargedDiodeCollection;
+namespace CLHEP {
+  class HepRandomEngine;
+}
+
+static const InterfaceID IID_IRandomDisabledCellGenerator("IRandomDisabledCellGenerator",1,0);
+
+class IRandomDisabledCellGenerator : virtual public ISiChargedDiodesProcessorTool {
+
+  ///////////////////////////////////////////////////////////////////
+  // Public methods:
+  ///////////////////////////////////////////////////////////////////
+ public:
+
+  //Retrieve interface ID
+  static const InterfaceID& interfaceID() { return IID_IRandomDisabledCellGenerator; }
+
+  // Destructor:
+  virtual ~IRandomDisabledCellGenerator() {}
+
+};
+
+#endif // SIDIGITIZATION_IRANDOMDISABLEDCELLGENERATOR_H
diff --git a/InnerDetector/InDetDigitization/SiDigitization/SiDigitization/SiChargedDiodeCollection.h b/InnerDetector/InDetDigitization/SiDigitization/SiDigitization/SiChargedDiodeCollection.h
index 6ce0ee1d42cf57de7d51cfe91169f6362dedaeb0..e1a1d8b343ea5c450e6065d59c21049d5b8e157e 100755
--- a/InnerDetector/InDetDigitization/SiDigitization/SiDigitization/SiChargedDiodeCollection.h
+++ b/InnerDetector/InDetDigitization/SiDigitization/SiDigitization/SiChargedDiodeCollection.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -30,7 +30,7 @@
 #include <unordered_map>
 #include "SiDigitization/SiChargedDiode.h"
 #include "Identifier/Identifier.h"
-#include "InDetReadoutGeometry/SiDetectorElement.h"
+#include "ReadoutGeometryBase/SolidStateDetectorElementBase.h"
 
 // Input/output classes 
 #include "InDetSimEvent/SiHit.h"
@@ -42,8 +42,7 @@
 
 class AtlasDetectorID;
 namespace InDetDD{
-  class SiDetectorElement;
-  class SiDetectorDesign;
+  class DetectorDesign;
   class SiCellId;
 }
 
@@ -117,7 +116,7 @@ class SiChargedDiodeCollection : Identifiable {
   //  ref. to the detector element for this collection
   SiChargedDiodeCollection( );
 
-  SiChargedDiodeCollection(const InDetDD::SiDetectorElement* );
+  SiChargedDiodeCollection(const InDetDD::SolidStateDetectorElementBase* );
 
 
   // Destructor:
@@ -128,7 +127,7 @@ class SiChargedDiodeCollection : Identifiable {
   ///////////////////////////////////////////////////////////////////
 
   // detector element:
-  const InDetDD::SiDetectorElement * element() const;
+  const InDetDD::SolidStateDetectorElementBase * element() const;
 
   // wafer identifier for this collection
   virtual Identifier identify() const override final;
@@ -138,7 +137,7 @@ class SiChargedDiodeCollection : Identifiable {
   const AtlasDetectorID* id_helper();
   
   // detector design:
-  const InDetDD::SiDetectorDesign &design() const;
+  const InDetDD::DetectorDesign &design() const;
 
   // translation from SiReadoutCellId to Identifier
   Identifier getId(const InDetDD::SiCellId& id) const 
@@ -157,7 +156,7 @@ class SiChargedDiodeCollection : Identifiable {
   SiChargedDiodeMap &chargedDiodes();
 
   // Set the SiDetectorElement
-  void setDetectorElement(const InDetDD::SiDetectorElement *SiElement);
+  void setDetectorElement(const InDetDD::SolidStateDetectorElementBase *SiElement);
 
   // Add a new SiCharge to the collection
   // (add or merge in an existing SiChargedDiode):
@@ -200,7 +199,7 @@ class SiChargedDiodeCollection : Identifiable {
   SiTotalCharge::alloc_t m_allocator; 
   SiChargedDiodeMap m_chargedDiodes; // list of SiChargedDiodes 
   SiChargedDiodeOrderedSet m_orderedChargedDiodes; // list of SiChargedDiodes 
-  const InDetDD::SiDetectorElement* m_sielement; // detector element
+  const InDetDD::SolidStateDetectorElementBase* m_sielement; // detector element
 };
 
 ///////////////////////////////////////////////////////////////////
@@ -208,7 +207,7 @@ class SiChargedDiodeCollection : Identifiable {
 ///////////////////////////////////////////////////////////////////
 
 // Set the DetectorElement
-inline void SiChargedDiodeCollection::setDetectorElement(const InDetDD::SiDetectorElement *SiElement) 
+inline void SiChargedDiodeCollection::setDetectorElement(const InDetDD::SolidStateDetectorElementBase *SiElement) 
 {
   m_sielement=SiElement;
 }
@@ -219,13 +218,13 @@ inline SiChargedDiodeMap &SiChargedDiodeCollection::chargedDiodes()
 }
 
 // access to the element
-inline const InDetDD::SiDetectorElement *SiChargedDiodeCollection::element() const
+inline const InDetDD::SolidStateDetectorElementBase *SiChargedDiodeCollection::element() const
 {
   return m_sielement;
 }
 
 // access to the design
-inline const InDetDD::SiDetectorDesign &SiChargedDiodeCollection::design() const
+inline const InDetDD::DetectorDesign &SiChargedDiodeCollection::design() const
 {
   return m_sielement->design();
 }
diff --git a/InnerDetector/InDetDigitization/SiDigitization/src/SiChargedDiodeCollection.cxx b/InnerDetector/InDetDigitization/SiDigitization/src/SiChargedDiodeCollection.cxx
index de52fa298ff6bb47f379aed2a98e7751342221f9..b3993828bd62201bdf5face95d28b31821a7f68d 100755
--- a/InnerDetector/InDetDigitization/SiDigitization/src/SiChargedDiodeCollection.cxx
+++ b/InnerDetector/InDetDigitization/SiDigitization/src/SiChargedDiodeCollection.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -15,7 +15,7 @@
 #include "SiDigitization/SiChargedDiodeCollection.h"
 // member classes
 #include "SiDigitization/SiHelper.h"
-#include "InDetReadoutGeometry/SiDetectorDesign.h"
+#include "ReadoutGeometryBase/DetectorDesign.h"
 #include "ReadoutGeometryBase/SiReadoutCellId.h"
 #include "ReadoutGeometryBase/SiCellId.h"
 #include "GaudiKernel/MsgStream.h"
@@ -31,7 +31,7 @@ SiChargedDiodeCollection::SiChargedDiodeCollection( ) :
 {
 }
 
-SiChargedDiodeCollection::SiChargedDiodeCollection(const InDetDD::SiDetectorElement* sielement ) :
+SiChargedDiodeCollection::SiChargedDiodeCollection(const InDetDD::SolidStateDetectorElementBase* sielement ) :
   m_chargedDiodes(),
   m_sielement(sielement)
 {
diff --git a/InnerDetector/InDetEventCnv/InDetJiveXML/CMakeLists.txt b/InnerDetector/InDetEventCnv/InDetJiveXML/CMakeLists.txt
index 33d992044e8f64c8d888d5ccc48151f208f882ea..40b5343013900a8f944d8b8ec0ddcd55f38c7491 100644
--- a/InnerDetector/InDetEventCnv/InDetJiveXML/CMakeLists.txt
+++ b/InnerDetector/InDetEventCnv/InDetJiveXML/CMakeLists.txt
@@ -11,7 +11,7 @@ atlas_add_component( InDetJiveXML
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${CLHEP_LIBRARIES} AthenaBaseComps StoreGateLib GaudiKernel InDetRawData TrkSpacePoint TrkTruthData JiveXMLLib AthContainers IdDictDetDescr InDetIdentifier ReadoutGeometryBase InDetReadoutGeometry TRT_ReadoutGeometry InDetPrepRawData TrkEventPrimitives TrkPrepRawData InDetBeamSpotServiceLib InDetCondTools )
+                     LINK_LIBRARIES ${CLHEP_LIBRARIES} AthenaBaseComps StoreGateLib GaudiKernel InDetRawData TrkSpacePoint TrkTruthData JiveXMLLib AthContainers IdDictDetDescr InDetIdentifier ReadoutGeometryBase InDetReadoutGeometry TRT_ReadoutGeometry InDetPrepRawData TrkEventPrimitives TrkPrepRawData BeamSpotConditionsData  InDetCondTools )
 
 # Install files from the package:
 atlas_install_joboptions( share/*.py )
diff --git a/InnerDetector/InDetEventCnv/InDetJiveXML/InDetJiveXML/BeamSpotRetriever.h b/InnerDetector/InDetEventCnv/InDetJiveXML/InDetJiveXML/BeamSpotRetriever.h
index 96bb9de9351c9433358611ac24fe2ef71e28ea5a..5b073753ac15701ca2a0f117a712221165cf2faf 100755
--- a/InnerDetector/InDetEventCnv/InDetJiveXML/InDetJiveXML/BeamSpotRetriever.h
+++ b/InnerDetector/InDetEventCnv/InDetJiveXML/InDetJiveXML/BeamSpotRetriever.h
@@ -7,8 +7,8 @@
 
 #include "JiveXML/IDataRetriever.h"
 #include "AthenaBaseComps/AthAlgTool.h"
-#include "GaudiKernel/ServiceHandle.h" 
-#include "InDetBeamSpotService/IBeamCondSvc.h"
+#include "BeamSpotConditionsData/BeamSpotData.h"
+
 
 namespace JiveXML {
   
@@ -25,6 +25,8 @@ namespace JiveXML {
     
   public:
     
+    virtual StatusCode initialize() override;
+    
     /// Standard constructor
     BeamSpotRetriever(const std::string& type,const std::string& name,const IInterface* parent);
 
@@ -39,8 +41,7 @@ namespace JiveXML {
       ///The data type that is generated by this retriever
       const std::string m_typeName;
 
-      /// A service handle for the beamspot service
-      ServiceHandle<IBeamCondSvc> m_beamSpotSvc; 
+      SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey { this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot" };
   };
 }
 
diff --git a/InnerDetector/InDetEventCnv/InDetJiveXML/src/BeamSpotRetriever.cxx b/InnerDetector/InDetEventCnv/InDetJiveXML/src/BeamSpotRetriever.cxx
index 50dd4142a700ac2f13a528688763731295fc1cd0..8e8cb25a3653ec831e7f03978fa82545c4c1b143 100755
--- a/InnerDetector/InDetEventCnv/InDetJiveXML/src/BeamSpotRetriever.cxx
+++ b/InnerDetector/InDetEventCnv/InDetJiveXML/src/BeamSpotRetriever.cxx
@@ -4,8 +4,6 @@
 
 #include "InDetJiveXML/BeamSpotRetriever.h"
 
-#include "InDetBeamSpotService/IBeamCondSvc.h" // the actual include, add this at the top
-
 #include "JiveXML/IFormatTool.h"
 
 namespace JiveXML {
@@ -17,12 +15,17 @@ namespace JiveXML {
    * @param parent AlgTools parent owning this tool
    **/
   BeamSpotRetriever::BeamSpotRetriever(const std::string& type,const std::string& name,const IInterface* parent):
-    AthAlgTool(type,name,parent), m_typeName("BeamSpot"), m_beamSpotSvc("BeamCondSvc",name){
+    AthAlgTool(type,name,parent), m_typeName("BeamSpot") {
     
     //Declare the interface
     declareInterface<IDataRetriever>(this);
   }
   
+  StatusCode BeamSpotRetriever::initialize() {
+      ATH_CHECK(m_beamSpotKey.initialize());
+      return StatusCode::SUCCESS;
+  }
+  
   /**
    * Implementation of DataRetriever interface
    * - for each pixel raw data object obtain the identifier
@@ -48,10 +51,10 @@ namespace JiveXML {
     DataVect status; status.reserve( 1 );  
 
 /// from: https://twiki.cern.ch/twiki/bin/view/Atlas/InDetBeamSpotFAQ#How_can_I_retrieve_the_beam_spot
-
+    SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
 // add the following into the initialize routine.
-  if ( m_beamSpotSvc.retrieve().isFailure() ) {
-    if (msgLvl(MSG::ERROR)) msg(MSG::ERROR) << "Failed to retrieve service " << m_beamSpotSvc << endmsg;
+  if ( !beamSpotHandle.isValid() ) {
+    if (msgLvl(MSG::ERROR)) msg(MSG::ERROR) << "Failed to retrieve beamspot " <<  endmsg;
     return StatusCode::RECOVERABLE;
   } else {
 
@@ -72,38 +75,38 @@ namespace JiveXML {
 // tiltX 	Tilt angle in x-z plane (rad)
 // tiltY 	Tilt angle in y-z plane (rad)
 
-    if (msgLvl(MSG::INFO)) msg(MSG::INFO) << "Retrieved service " << m_beamSpotSvc << endmsg;
+
 
     label.push_back( "Beamspot_position_at_PV_z_position" ); 
 	
-    Trk::RecVertex beamposition(m_beamSpotSvc->beamVtx());
+    Trk::RecVertex beamposition(beamSpotHandle->beamVtx());
     Amg::Vector3D posBS(beamposition.position());
 
     x.push_back( posBS.x() );
     y.push_back( posBS.y() );
     z.push_back( posBS.z() );
 
-    sigmaX.push_back( m_beamSpotSvc->beamSigma(0) ); 
-    sigmaY.push_back( m_beamSpotSvc->beamSigma(1) ); 
-    sigmaZ.push_back( m_beamSpotSvc->beamSigma(2) ); 
-    sigmaXY.push_back( m_beamSpotSvc->beamSigmaXY() ); 
+    sigmaX.push_back( beamSpotHandle->beamSigma(0) );
+    sigmaY.push_back( beamSpotHandle->beamSigma(1) );
+    sigmaZ.push_back( beamSpotHandle->beamSigma(2) );
+    sigmaXY.push_back( beamSpotHandle->beamSigmaXY() );
 
-    tiltX.push_back( m_beamSpotSvc->beamTilt(0) ); 
-    tiltY.push_back( m_beamSpotSvc->beamTilt(1) ); 
+    tiltX.push_back( beamSpotHandle->beamTilt(0) );
+    tiltY.push_back( beamSpotHandle->beamTilt(1) );
 
-    status.push_back( m_beamSpotSvc->beamStatus() ); 
+    status.push_back( beamSpotHandle->beamStatus() );
 
   if (msgLvl(MSG::DEBUG)) {
     msg(MSG::DEBUG)  << "BeamSpot Position: "
-                   << m_beamSpotSvc->beamPos() << endmsg;
+                   << beamSpotHandle->beamPos() << endmsg;
     msg(MSG::DEBUG)  << "BeamSpot Sigma "
-                   << m_beamSpotSvc->beamSigma(0) << ", "
-                   << m_beamSpotSvc->beamSigma(1) << ", "
-                   << m_beamSpotSvc->beamSigma(2) 
+                   << beamSpotHandle->beamSigma(0) << ", "
+                   << beamSpotHandle->beamSigma(1) << ", "
+                   << beamSpotHandle->beamSigma(2) 
                    << endmsg;
     msg(MSG::DEBUG)  << "BeamSpot Tilt: "
-                   << m_beamSpotSvc->beamTilt(0) << ", "
-                   << m_beamSpotSvc->beamTilt(1) 
+                   << beamSpotHandle->beamTilt(0) << ", "
+                   << beamSpotHandle->beamTilt(1) 
                    << endmsg;
     msg(MSG::DEBUG) << "Beamspot position at PV z-position" << endmsg;
   }
diff --git a/InnerDetector/InDetExample/InDetAlignExample/share/ElectronEoverPTracking.py b/InnerDetector/InDetExample/InDetAlignExample/share/ElectronEoverPTracking.py
index 5ba3d2480524a1de30f8a62a3c6b96c7da4a223c..8400f4020ced9df3eb2a72f3db4c9e73aee98b84 100755
--- a/InnerDetector/InDetExample/InDetAlignExample/share/ElectronEoverPTracking.py
+++ b/InnerDetector/InDetExample/InDetAlignExample/share/ElectronEoverPTracking.py
@@ -70,7 +70,11 @@ if not use_tracking_geometry_cond_alg :
 	acc = TrackingGeometrySvcCfg(flags)
 	geom_svc = acc.getPrimary()
 else :
-	from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlgConfig import TrackingGeometryCondAlgCfg
+  from AthenaCommon.AlgSequence import AthSequencer
+  condSeq = AthSequencer("AthCondSeq")
+  if not getattr (condSeq, 'AtlasTrackingGeometryCondAlg', None)
+    from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlg import ConfiguredTrackingGeometryCondAlg
+    condSeq += ConfiguredTrackingGeometryCondAlg()
 	geom_cond_key = 'AtlasTrackingGeometry'
 #
 # get propagator
diff --git a/InnerDetector/InDetExample/InDetRecExample/python/InDetJobProperties.py b/InnerDetector/InDetExample/InDetRecExample/python/InDetJobProperties.py
index dc7980f7dda3d2fcfbe3447230ef0ede0fc9b3af..5b0499ea796c19270391a68eca470d04d0fd521e 100644
--- a/InnerDetector/InDetExample/InDetRecExample/python/InDetJobProperties.py
+++ b/InnerDetector/InDetExample/InDetRecExample/python/InDetJobProperties.py
@@ -329,7 +329,7 @@ class doCaloSeededAmbi(InDetFlagsJobProperty):
     """Use Calo ROIs to seed specific cuts for the ambi"""
     statusOn     = True
     allowedTypes = ['bool']
-    StoredValue  = False
+    StoredValue  = True
 
 class doCaloSeededRefit(InDetFlagsJobProperty):
     """Use Calo ROIs to seed refif for the ambi processor"""
diff --git a/InnerDetector/InDetExample/InDetRecExample/python/TrackingCommon.py b/InnerDetector/InDetExample/InDetRecExample/python/TrackingCommon.py
index c599895f8c32b0981d862cd9ef11b657c92cb948..c55a257ad6b8d01f2871a24157da64c95d231dac 100644
--- a/InnerDetector/InDetExample/InDetRecExample/python/TrackingCommon.py
+++ b/InnerDetector/InDetExample/InDetRecExample/python/TrackingCommon.py
@@ -632,7 +632,6 @@ def getTrackingGeometryCondAlg(name="AtlasTrackingGeometryCondAlg",**kwargs) :
     the_name = makeName( name, kwargs )
     from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlg import ConfiguredTrackingGeometryCondAlg
     alg = ConfiguredTrackingGeometryCondAlg(the_name)
-    # alg.TrackingGeometryWriteKey = 'AlignedTrackingGeometry'
     return alg
 
 
diff --git a/InnerDetector/InDetMonitoring/InDetPerformanceMonitoring/CMakeLists.txt b/InnerDetector/InDetMonitoring/InDetPerformanceMonitoring/CMakeLists.txt
index c6a91ac07fdd8f8d5330e0c19b0bf97b189959d3..e788cd3c8bc2158c9cd42c71c2cb96f78276c783 100644
--- a/InnerDetector/InDetMonitoring/InDetPerformanceMonitoring/CMakeLists.txt
+++ b/InnerDetector/InDetMonitoring/InDetPerformanceMonitoring/CMakeLists.txt
@@ -12,7 +12,7 @@ atlas_add_component( InDetPerformanceMonitoring
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${CLHEP_LIBRARIES} ${ROOT_LIBRARIES} AthenaBaseComps AthenaMonitoringLib AtlasHepMCLib CxxUtils ElectronPhotonSelectorToolsLib EventPrimitives GaudiKernel ITrackToVertex IdDictDetDescr InDetBeamSpotServiceLib InDetIdentifier InDetPrepRawData InDetRIO_OnTrack InDetTrackSelectionToolLib JetInterface LWHists MuonAnalysisInterfacesLib MuonMomentumCorrectionsLib StoreGateLib TRT_ReadoutGeometry TrigDecisionToolLib TrkEventPrimitives TrkExInterfaces TrkParameters TrkParticleBase TrkTrack TrkTrackSummary TrkTruthData TrkV0Vertex TrkVertexAnalysisUtilsLib TrkVertexFitterInterfaces TrackVertexAssociationToolLib egammaEvent egammaInterfacesLib xAODCaloEvent xAODEgamma xAODEventInfo xAODJet xAODMissingET xAODMuon xAODTracking xAODTruth )
+                     LINK_LIBRARIES ${CLHEP_LIBRARIES} ${ROOT_LIBRARIES} AthenaBaseComps AthenaMonitoringLib AtlasHepMCLib CxxUtils ElectronPhotonSelectorToolsLib EventPrimitives GaudiKernel ITrackToVertex IdDictDetDescr BeamSpotConditionsData InDetIdentifier InDetPrepRawData InDetRIO_OnTrack InDetTrackSelectionToolLib JetInterface LWHists MuonAnalysisInterfacesLib MuonMomentumCorrectionsLib StoreGateLib TRT_ReadoutGeometry TrigDecisionToolLib TrkEventPrimitives TrkExInterfaces TrkParameters TrkParticleBase TrkTrack TrkTrackSummary TrkTruthData TrkV0Vertex TrkVertexAnalysisUtilsLib TrkVertexFitterInterfaces TrackVertexAssociationToolLib egammaEvent egammaInterfacesLib xAODCaloEvent xAODEgamma xAODEventInfo xAODJet xAODMissingET xAODMuon xAODTracking xAODTruth )
 
 # Install files from the package:
 atlas_install_joboptions( share/*.py )
diff --git a/InnerDetector/InDetMonitoring/InDetPerformanceMonitoring/InDetPerformanceMonitoring/IDPerfMonZmumu.h b/InnerDetector/InDetMonitoring/InDetPerformanceMonitoring/InDetPerformanceMonitoring/IDPerfMonZmumu.h
index a61ccb9ede36ff51acbb259fd8b0261c0edb7899..4c7fbe61b8cc0cf5495741621a6fecd064d44cd0 100755
--- a/InnerDetector/InDetMonitoring/InDetPerformanceMonitoring/InDetPerformanceMonitoring/IDPerfMonZmumu.h
+++ b/InnerDetector/InDetMonitoring/InDetPerformanceMonitoring/InDetPerformanceMonitoring/IDPerfMonZmumu.h
@@ -37,6 +37,8 @@
 #include "GaudiKernel/ToolHandle.h"
 #include "GaudiKernel/ServiceHandle.h"
 #include "TrkExInterfaces/IExtrapolator.h"
+#include "BeamSpotConditionsData/BeamSpotData.h"
+
 
 class IegammaTrkRefitterTool;
 class IBeamCondSvc;
@@ -128,7 +130,7 @@ class IDPerfMonZmumu : public AthAlgorithm
   ToolHandle< Trk::ITrackToVertexIPEstimator > m_trackToVertexIPEstimator;
 
   /** used for truth parameters**/
-  ServiceHandle<IBeamCondSvc> m_beamSpotSvc;
+  SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey { this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot" };
   ToolHandle<Trk::IExtrapolator> m_extrapolator;
 
   /* vertex */
diff --git a/InnerDetector/InDetMonitoring/InDetPerformanceMonitoring/src/IDPerfMonZmumu.cxx b/InnerDetector/InDetMonitoring/InDetPerformanceMonitoring/src/IDPerfMonZmumu.cxx
index 95176f2c1cb186713d7b675e58aa04e605d49f04..662c8553fc6385e68a84715efaabe399c66b7f3b 100755
--- a/InnerDetector/InDetMonitoring/InDetPerformanceMonitoring/src/IDPerfMonZmumu.cxx
+++ b/InnerDetector/InDetMonitoring/InDetPerformanceMonitoring/src/IDPerfMonZmumu.cxx
@@ -31,7 +31,6 @@
 
 /** needed for IP resolution studies **/
 #include "TrkVertexFitterInterfaces/ITrackToVertexIPEstimator.h"
-#include "InDetBeamSpotService/IBeamCondSvc.h"
 
 #include "TrigDecisionTool/TrigDecisionTool.h"
 #include "TrigDecisionTool/ChainGroup.h"
@@ -56,7 +55,6 @@ IDPerfMonZmumu::IDPerfMonZmumu(const std::string& name,
   m_triggerDecision("Trig::TrigDecisionTool/TrigDecisionTool"),
   m_selTool( "InDet::InDetTrackSelectionTool/TrackSelectionTool"),
   m_trackToVertexIPEstimator("Trk::TrackToVertexIPEstimator"),
-  m_beamSpotSvc("BeamCondSvc",name),
   m_extrapolator("Trk::Extrapolator/AtlasExtrapolator"),
   m_validationMode(true),
 
@@ -102,7 +100,6 @@ IDPerfMonZmumu::IDPerfMonZmumu(const std::string& name,
   declareProperty("isMC",              m_isMC = false);
   declareProperty("doRefit",           m_doRefit = false);
   declareProperty("doIPextrToPV",      m_doIP = false);
-  declareProperty("BeamCondSvc",       m_beamSpotSvc);
   declareProperty("Extrapolator",      m_extrapolator );
   declareProperty("MassWindowLow",     m_MassWindowLow = 60.0, "Lower cut in mu+mu- invariant mass" );
   declareProperty("MassWindowHigh",    m_MassWindowHigh = 120.0, "Upper cut in mu+mu- invariant mass" );
@@ -218,7 +215,7 @@ StatusCode IDPerfMonZmumu::initialize()
     ATH_CHECK (m_trackToVertexIPEstimator.retrieve());
   }
 
-  ATH_CHECK( m_beamSpotSvc.retrieve());
+  ATH_CHECK(m_beamSpotKey.initialize());
   ATH_CHECK( m_extrapolator.retrieve());
   
   ATH_CHECK (m_vertexKey.initialize());
@@ -1598,7 +1595,8 @@ StatusCode IDPerfMonZmumu::FillTruthParameters(const xAOD::TrackParticle* trackP
   const Amg::Vector3D position(xPos, yPos, z_truth);
   const Trk::CurvilinearParameters cParameters(position, momentum, charge);
 
-  Trk::PerigeeSurface persf( m_beamSpotSvc->beamPos() );
+  SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
+  Trk::PerigeeSurface persf( beamSpotHandle->beamPos() );
 
   const Trk::TrackParameters* tP = m_extrapolator->extrapolate(cParameters,persf, Trk::anyDirection, false);
 
diff --git a/LArCalorimeter/LArCafJobs/LArCafJobs/HistoryContainer.h b/LArCalorimeter/LArCafJobs/LArCafJobs/HistoryContainer.h
index 0d076f7e6762680eb386ac3c65b4e9c89513a8e0..37b030810ffad948c6059d1c748663dbf38157bb 100644
--- a/LArCalorimeter/LArCafJobs/LArCafJobs/HistoryContainer.h
+++ b/LArCalorimeter/LArCafJobs/LArCafJobs/HistoryContainer.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 /**
@@ -39,7 +39,7 @@ namespace LArSamples {
     unsigned int nDataContainers() const { return m_data.size(); }
     const DataContainer* dataContainer(unsigned int i) const { return m_data[i]; }
   
-    const CellInfo* cellInfo() const { return m_cellInfo; }
+    const CellInfo* cellInfo() const { return m_cellInfo.get(); }
     
     /** @brief append data (takes ownership) */
     void add(const DataContainer* data) { m_data.push_back(data); }
@@ -53,10 +53,10 @@ namespace LArSamples {
 
    private:
    
-    CellInfo* cell_info() const { return m_cellInfo; }
+    CellInfo* cell_info() const { return m_cellInfo.get(); }
 
     std::vector<const DataContainer*> m_data;
-    CellInfo* m_cellInfo;
+    std::unique_ptr<CellInfo> m_cellInfo;
 
     HistoryContainer& operator= (const HistoryContainer&);
   };
diff --git a/LArCalorimeter/LArCafJobs/LArCafJobs/PersistentAccessor.h b/LArCalorimeter/LArCafJobs/LArCafJobs/PersistentAccessor.h
index e824c98cdad346089bde22c59aa0a82bada3d775..8a756d057ec6341ead5fb5363f014b2bed6864cf 100644
--- a/LArCalorimeter/LArCafJobs/LArCafJobs/PersistentAccessor.h
+++ b/LArCalorimeter/LArCafJobs/LArCafJobs/PersistentAccessor.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 /**
@@ -29,6 +29,9 @@ namespace LArSamples {
       PersistentAccessor(TTree& cellTree, TTree& eventTree, TTree* runTree, TFile* file);
       PersistentAccessor(const TString& fileName);
 
+      PersistentAccessor (const PersistentAccessor&);
+      PersistentAccessor& operator= (const PersistentAccessor&);
+
       static PersistentAccessor* open(const TString& fileName);
 
       virtual ~PersistentAccessor();
diff --git a/LArCalorimeter/LArCafJobs/src/ClassCounts.cxx b/LArCalorimeter/LArCafJobs/src/ClassCounts.cxx
index 5dbefd84c43a83fca1f379d74c2db5c80003e50b..48a711500c504c0f9f54186747deea340066d71f 100644
--- a/LArCalorimeter/LArCafJobs/src/ClassCounts.cxx
+++ b/LArCalorimeter/LArCafJobs/src/ClassCounts.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "LArCafJobs/ClassCounts.h"
@@ -41,7 +41,6 @@ void ClassCounts::printCountsTable()
 {
   cout << "Class instance counts : " << endl;
   if (!m_counts) return;
-  for (std::map<TString, int>::const_iterator count = counts().begin();
-       count != counts().end(); count++)
-    cout << Form("%20s : %-d", count->first.Data(), count->second) << endl;
+  for (const std::pair<const TString, int>& p : counts())
+    cout << Form("%20s : %-d", p.first.Data(), p.second) << endl;
 }
diff --git a/LArCalorimeter/LArCafJobs/src/DataStore.cxx b/LArCalorimeter/LArCafJobs/src/DataStore.cxx
index a48cb17977e3caaae92011371ccf004554fe508c..09d06c066cedd9a1007888214c1008b18ca1ec64 100644
--- a/LArCalorimeter/LArCafJobs/src/DataStore.cxx
+++ b/LArCalorimeter/LArCafJobs/src/DataStore.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "LArCafJobs/DataStore.h"
@@ -31,9 +31,8 @@ DataStore::DataStore()
   
 DataStore::~DataStore()
 {
-  for (std::vector<HistoryContainer*>::iterator hist = m_cellHistories.begin(); 
-       hist != m_cellHistories.end(); hist++) 
-    if (*hist) delete *hist;
+  for (HistoryContainer* h : m_cellHistories)
+    delete h;
 }
 
 
diff --git a/LArCalorimeter/LArCafJobs/src/EventData.cxx b/LArCalorimeter/LArCafJobs/src/EventData.cxx
index c228355577e0c565cae2abe7d13d32573e27c275..1b273bc1a0f2e41b071fd8b5b0fef7dab2c700f8 100644
--- a/LArCalorimeter/LArCafJobs/src/EventData.cxx
+++ b/LArCalorimeter/LArCafJobs/src/EventData.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 
@@ -108,12 +108,13 @@ TString EventData::triggers() const
 {
   TString triggers = "";
   if (!runData()) return triggers;
-  for (std::map<TString, unsigned int>::const_iterator trigger = runData()->triggerConfig().begin();
-       trigger != runData()->triggerConfig().end(); trigger++)
-    if (isPassed(trigger->first)) {
+  for (const std::pair<const TString, unsigned int>& p : runData()->triggerConfig())
+  {
+    if (isPassed(p.first)) {
       if (triggers != "") triggers += " ";
-      triggers += trigger->first;
+      triggers += p.first;
     }
+  }
   return triggers;
 }
 
diff --git a/LArCalorimeter/LArCafJobs/src/HistoryContainer.cxx b/LArCalorimeter/LArCafJobs/src/HistoryContainer.cxx
index 085065716f5dbe7bca2ae418e05849a779c3997d..476ce7968c4c8fd698441c528899edc0041d72f8 100644
--- a/LArCalorimeter/LArCafJobs/src/HistoryContainer.cxx
+++ b/LArCalorimeter/LArCafJobs/src/HistoryContainer.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "LArCafJobs/HistoryContainer.h"
@@ -22,21 +22,18 @@ HistoryContainer::HistoryContainer(CellInfo* cellInfo)
 }
 
 HistoryContainer::HistoryContainer(const HistoryContainer& other) 
-  : m_data(other.m_data), 
-    m_cellInfo(0)
+  : m_data(other.m_data)
 { 
   ClassCounts::incrementInstanceCount("HistoryContainer"); 
-  if (other.m_cellInfo) m_cellInfo = new CellInfo(*other.m_cellInfo); 
+  if (other.m_cellInfo) m_cellInfo = std::make_unique<CellInfo>(*other.m_cellInfo); 
 }
 
 
 HistoryContainer::~HistoryContainer()
 {
-  ClassCounts::decrementInstanceCount("HistoryContainer"); 
-  for (std::vector<const DataContainer*>::iterator data = m_data.begin(); 
-       data != m_data.end(); data++) 
-    if (*data) delete *data;
-  if (m_cellInfo) delete m_cellInfo;
+  ClassCounts::decrementInstanceCount("HistoryContainer");
+  for (const DataContainer* data : m_data)
+    delete data;
 }
   
 
@@ -56,10 +53,10 @@ bool HistoryContainer::isValid() const
 {
   if (!m_cellInfo || !m_cellInfo->isValid()) return false;
   if (nDataContainers() == 0) return false;
-  
-  for (std::vector<const DataContainer*>::const_iterator data = m_data.begin(); 
-       data != m_data.end(); data++) 
-    if (!(*data)->isValid()) return false;
+
+  for (const DataContainer* data : m_data) {
+    if (!data->isValid()) return false;
+  }
   
   return true;
 }
diff --git a/LArCalorimeter/LArCafJobs/src/PersistentAccessor.cxx b/LArCalorimeter/LArCafJobs/src/PersistentAccessor.cxx
index 075afe156d6f7b839494d41240a445e9d6879252..414b0fb41bc98dbf5b25d1a978c1448dc758662e 100644
--- a/LArCalorimeter/LArCafJobs/src/PersistentAccessor.cxx
+++ b/LArCalorimeter/LArCafJobs/src/PersistentAccessor.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "LArCafJobs/PersistentAccessor.h"
@@ -191,18 +191,17 @@ PersistentAccessor* PersistentAccessor::merge(const std::vector<const Persistent
   std::map< std::pair<const PersistentAccessor*, int>, int > evtAccMap;
   
   cout << "Merging runs" << endl;
-  for (std::vector<const PersistentAccessor*>::const_iterator accessor = accessors.begin();
-       accessor != accessors.end(); accessor++) {
-    if (!*accessor) {
+  for (const PersistentAccessor* accessor : accessors) {
+    if (!accessor) {
       cout << "Cannot merge: one of the inputs is null!" << endl;
       delete newAcc;
       return 0;
     }
-    for (unsigned int i = 0; i < (*accessor)->nRuns(); i++) {
-      int run = (*accessor)->runData(i)->run();
+    for (unsigned int i = 0; i < accessor->nRuns(); i++) {
+      int run = accessor->runData(i)->run();
       if (runMap.find(run) != runMap.end()) continue;
       runMap[run] = runIndex;
-      RunData* newRun = new RunData(*(*accessor)->runData(i));
+      RunData* newRun = new RunData(*accessor->runData(i));
       newAcc->addRun(newRun);
       delete newRun;
       runIndex++;
@@ -211,25 +210,25 @@ PersistentAccessor* PersistentAccessor::merge(const std::vector<const Persistent
   
   cout << "Merging events" << endl;
   unsigned int nEventsTotal = 0, iEvt = 0;
-    for (std::vector<const PersistentAccessor*>::const_iterator accessor = accessors.begin();
-       accessor != accessors.end(); accessor++) nEventsTotal += (*accessor)->nEvents();  
-  for (std::vector<const PersistentAccessor*>::const_iterator accessor = accessors.begin();
-       accessor != accessors.end(); accessor++) {
-    for (unsigned int i = 0; i < (*accessor)->nEvents(); i++) {
+  for (const PersistentAccessor* accessor : accessors) {
+    nEventsTotal += accessor->nEvents();
+  }
+  for (const PersistentAccessor* accessor : accessors) {
+    for (unsigned int i = 0; i < accessor->nEvents(); i++) {
       iEvt++;
       if (iEvt % 100000 == 0) cout << "Merging event " << iEvt << "/" << nEventsTotal << endl;
-      std::pair<int, int> evtId((*accessor)->eventData(i)->run(), (*accessor)->eventData(i)->event());
-      std::pair<const PersistentAccessor*, int> evtAccId(*accessor, i);
+      std::pair<int, int> evtId(accessor->eventData(i)->run(), accessor->eventData(i)->event());
+      std::pair<const PersistentAccessor*, int> evtAccId(accessor, i);
       if (evtMap.find(evtId) != evtMap.end()) {
-        cout << "ERROR: Skipping duplicate entry for run " << (*accessor)->eventData(i)->run() << ", event " << (*accessor)->eventData(i)->event() << endl;
+        cout << "ERROR: Skipping duplicate entry for run " << accessor->eventData(i)->run() << ", event " << accessor->eventData(i)->event() << endl;
         continue;
       }
       evtAccMap[evtAccId] = evtIndex;
       evtMap[evtId] = evtIndex;
-      std::map<int, int>::const_iterator idx = runMap.find((*accessor)->eventData(i)->run());
+      std::map<int, int>::const_iterator idx = runMap.find(accessor->eventData(i)->run());
       int newRunIndex = (idx == runMap.end() ? -999 : idx->second);
-      //cout << "Storing eventData for run " << (*accessor)->eventData(i)->run() << " at index " << newRunIndex << " instead of " << (*accessor)->eventData(i)->runIndex() << endl;
-      EventData* newEvent = new EventData(*(*accessor)->eventData(i), newRunIndex);
+      //cout << "Storing eventData for run " << accessor->eventData(i)->run() << " at index " << newRunIndex << " instead of " << accessor->eventData(i)->runIndex() << endl;
+      EventData* newEvent = new EventData(*accessor->eventData(i), newRunIndex);
       newAcc->addEvent(newEvent);
       delete newEvent;
       evtIndex++;
@@ -242,9 +241,8 @@ PersistentAccessor* PersistentAccessor::merge(const std::vector<const Persistent
       //ClassCounts::printCountsTable();
     }
     HistoryContainer* newHistory = 0;
-    for (std::vector<const PersistentAccessor*>::const_iterator accessor = accessors.begin();
-         accessor != accessors.end(); accessor++) {
-      const HistoryContainer* history = (*accessor)->historyContainer(i);
+    for (const PersistentAccessor* accessor : accessors) {
+      const HistoryContainer* history = accessor->historyContainer(i);
       if (!history || !history->isValid()) continue;
       if (!newHistory) {
         info = new CellInfo(*history->cellInfo());
@@ -253,7 +251,7 @@ PersistentAccessor* PersistentAccessor::merge(const std::vector<const Persistent
       for (unsigned int j = 0; j < history->nDataContainers(); j++) {
         DataContainer* newDC = new DataContainer(*history->dataContainer(j));
         std::map<std::pair<const PersistentAccessor*, int>, int>::const_iterator newIndex 
-          = evtAccMap.find(std::make_pair(*accessor, history->dataContainer(j)->eventIndex()));
+          = evtAccMap.find(std::make_pair(accessor, history->dataContainer(j)->eventIndex()));
         if (newIndex == evtAccMap.end()) cout << "Event not found for cell " << i << ", data " << j << "." << endl;
         newDC->setEventIndex(newIndex != evtAccMap.end() ? newIndex->second : -1);
         newHistory->add(newDC);
@@ -279,16 +277,17 @@ PersistentAccessor* PersistentAccessor::merge(const std::vector<const Persistent
 PersistentAccessor* PersistentAccessor::merge(const std::vector<TString>& inputFiles, const TString& fileName)
 {
   std::vector<const PersistentAccessor*> accessors;
-  for (std::vector<TString>::const_iterator inputFile = inputFiles.begin(); inputFile != inputFiles.end(); inputFile++) {
-    PersistentAccessor* accessor = open(*inputFile);
+  for (const TString& inputFile : inputFiles) {
+    PersistentAccessor* accessor = open(inputFile);
     if (!accessor) {
-      cout << "ERROR : could not open file " << *inputFile << endl;
+      cout << "ERROR : could not open file " << inputFile << endl;
       return 0;
     }
     accessors.push_back(accessor);
   }
   PersistentAccessor* result = merge(accessors, fileName);
-  for (std::vector<const PersistentAccessor*>::iterator accessor = accessors.begin(); accessor != accessors.end(); accessor++) 
-    delete *accessor;
+  for (const PersistentAccessor* accessor : accessors) {
+    delete accessor;
+  }
   return result;
 }
diff --git a/LArCalorimeter/LArCafJobs/src/RunData.cxx b/LArCalorimeter/LArCafJobs/src/RunData.cxx
index 236c1150562d218833af23d33e7e67913561f452..0a3c0ef8870a8cc2e1c2ad78422ee4495663e35e 100644
--- a/LArCalorimeter/LArCafJobs/src/RunData.cxx
+++ b/LArCalorimeter/LArCafJobs/src/RunData.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 
@@ -45,10 +45,9 @@ int RunData::triggerBitPosition(const TString& triggerBitName) const
 TString RunData::triggerBits() const
 {
   TString bits;
-  for (std::map<TString, unsigned int>::const_iterator bit = m_triggerConfig.begin();
-       bit != m_triggerConfig.end(); bit++) {
+  for (const std::pair<const TString, unsigned int>& bit : m_triggerConfig) {
     if (bits != "") bits += "\n";
-    bits += bit->first;
+    bits += bit.first;
   }
   return bits;
 }
diff --git a/LArCalorimeter/LArGeoModel/LArGeoBarrel/LArGeoBarrel/BarrelConstruction.h b/LArCalorimeter/LArGeoModel/LArGeoBarrel/LArGeoBarrel/BarrelConstruction.h
index 6a4445778b1ea323ca0e0d11170a164eec250d32..a2792e0303c24df2b13811a1443498e38e004bec 100755
--- a/LArCalorimeter/LArGeoModel/LArGeoBarrel/LArGeoBarrel/BarrelConstruction.h
+++ b/LArCalorimeter/LArGeoModel/LArGeoBarrel/LArGeoBarrel/BarrelConstruction.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 // BarrelConstruction
@@ -11,8 +11,6 @@
 
 #include "LArGeoCode/VDetectorParameters.h"
 #include "GeoModelKernel/GeoFullPhysVol.h"
-#include "GeoGenericFunctions/FunctionNoop.h"
-
 
 namespace LArGeo {
 
@@ -45,41 +43,18 @@ namespace LArGeo {
 
     // It is illegal to assign a BarrelConstruction:
     BarrelConstruction & operator= (const BarrelConstruction &);
-
-    // Three auxiliary functions:------------------------------------//
-    //                                                               //
-    GeoGenfun::FunctionNoop Fx( double r,                               //
-			       GeoGenfun::GENFUNCTION G,                //
-			       const double Cenx[],                  //
-			       const double Ceny[] ) const;          //
-      //                                                             //
-      GeoGenfun::FunctionNoop Fy( double r,                             //
-			       GeoGenfun::GENFUNCTION G,                //
-			       const double Cenx[],                  //
-			       const double Ceny[] ) const;          //
-      //                                                             //
-      GeoGenfun::FunctionNoop Dely(GeoGenfun::GENFUNCTION G ) const;       //
-      GeoGenfun::FunctionNoop Del1(GeoGenfun::GENFUNCTION G ) const;       //
-      GeoGenfun::FunctionNoop Del2(GeoGenfun::GENFUNCTION G ) const;       //
-
-      //-------------------------------------------------------------//
-
-      // Atan2 for Generic Functions..:------------------------------//
-      GeoGenfun::FunctionNoop ATan2(GeoGenfun::GENFUNCTION y,              //
-				 GeoGenfun::GENFUNCTION x) const;       //
-      //-------------------------------------------------------------//
-
-      // Detector parameters ACCG, ACCA, ACMB, ACCO
-      LArGeo::VDetectorParameters* m_parameters;
-
-      bool                    m_A_SAGGING;
-      int                     m_NVISLIM;
-
-      // volumes that are private member variables:
-      GeoFullPhysVol*  m_ecamPhysicalPos;
-      GeoFullPhysVol*  m_ecamPhysicalNeg;
-
-      bool             m_fullGeo;  // true->FULL, false->RECO
+    
+    // Detector parameters ACCG, ACCA, ACMB, ACCO
+    LArGeo::VDetectorParameters* m_parameters;
+
+    bool                    m_A_SAGGING;
+    int                     m_NVISLIM;
+    
+    // volumes that are private member variables:
+    GeoFullPhysVol*  m_ecamPhysicalPos;
+    GeoFullPhysVol*  m_ecamPhysicalNeg;
+    
+    bool             m_fullGeo;  // true->FULL, false->RECO
   };
 
  
diff --git a/LArCalorimeter/LArGeoModel/LArGeoBarrel/LArGeoBarrel/ElStraightSectionBuilder.h b/LArCalorimeter/LArGeoModel/LArGeoBarrel/LArGeoBarrel/ElStraightSectionBuilder.h
new file mode 100755
index 0000000000000000000000000000000000000000..0d779109cb06c112e468d401555d4c5684625bc9
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoBarrel/LArGeoBarrel/ElStraightSectionBuilder.h
@@ -0,0 +1,32 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file  ElStraightSectionBuilder.h
+ *
+ * @brief Helper function for constructing the instances of GeoStraightAccSection
+ *        when LAr GeoModel description is built from the SQLite database.
+ *        The code for this function has been extracted from 
+ *        LArGeoBarrel/BarrelConstruction
+ **/
+
+#ifndef LARGEOBARREL_ELSTRAIGHTSECTIONBUILDER_H
+#define LARGEOBARREL_ELSTRAIGHTSECTIONBUILDER_H
+
+#include "GaudiKernel/StatusCode.h"
+
+class StoreGateSvc;
+class IRDBAccessSvc;
+class IMessageSvc;
+
+namespace LArGeo {
+
+  StatusCode buildElStraightSections(StoreGateSvc* detStore
+				     , IRDBAccessSvc* paramSvc
+				     , IMessageSvc* msgSvc
+				     , bool sagging);
+  
+}
+
+#endif 
diff --git a/LArCalorimeter/LArGeoModel/LArGeoBarrel/src/BarrelAuxFunctions.cxx b/LArCalorimeter/LArGeoModel/LArGeoBarrel/src/BarrelAuxFunctions.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..421c7706acc5597ccd05012a9ea7a24a818630ef
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoBarrel/src/BarrelAuxFunctions.cxx
@@ -0,0 +1,71 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "BarrelAuxFunctions.h"
+
+#include "GeoGenericFunctions/Abs.h"
+#include "GeoGenericFunctions/Sin.h"
+#include "GeoGenericFunctions/Cos.h"
+#include "GeoGenericFunctions/ATan.h"
+#include "GeoGenericFunctions/Rectangular.h"
+#include "GeoGenericFunctions/Mod.h"
+
+#include <cfloat>
+
+GeoGenfun::FunctionNoop LArGeo::Fx(double r, GeoGenfun::GENFUNCTION G, const double Cenx[], const double Ceny[] )
+{
+  GeoGenfun::Cos Cos;
+  GeoGenfun::Sin Sin;
+  int i = (int)rint(r-.1), j = (int)rint(r+.1) ;
+  GeoGenfun::GENFUNCTION result =  (Cos(G)*(Cenx[i]+Cenx[j])/2-Sin(G)*(Ceny[i]+Ceny[j])/2) ;
+  return GeoGenfun::FunctionNoop(&result);
+}
+
+GeoGenfun::FunctionNoop LArGeo::Fy(double r, GeoGenfun::GENFUNCTION G, const double Cenx[], const double Ceny[] )
+{
+  GeoGenfun::Cos Cos;
+  GeoGenfun::Sin Sin;
+  int i = (int)rint(r-.1), j = (int)rint(r+.1) ;
+  GeoGenfun::GENFUNCTION result = (Sin(G)*(Cenx[i]+Cenx[j])/2+Cos(G)*(Ceny[i]+Ceny[j])/2) ;
+  return GeoGenfun::FunctionNoop(&result);
+}
+
+GeoGenfun::FunctionNoop LArGeo::Del1(GeoGenfun::GENFUNCTION G)
+{
+  GeoGenfun::Cos Cos;
+  GeoGenfun::Sin Sin;
+  GeoGenfun::GENFUNCTION result = (Cos(  G ) * Sin( G ) );
+  return GeoGenfun::FunctionNoop(&result);
+}
+
+GeoGenfun::FunctionNoop LArGeo::Del2(GeoGenfun::GENFUNCTION G)
+{
+  GeoGenfun::Cos Cos;
+  GeoGenfun::GENFUNCTION result = (Cos(  G ) * Cos( G ) );
+  return GeoGenfun::FunctionNoop(&result);
+}
+
+
+GeoGenfun::FunctionNoop LArGeo::ATan2(GeoGenfun::GENFUNCTION y, GeoGenfun::GENFUNCTION x)
+{
+  // Manufacture a Theta Function:
+  GeoGenfun::Rectangular Theta;
+  Theta.x0().setValue(0.0);
+  Theta.x1().setValue(DBL_MAX);
+  Theta.baseline().setValue(0.0);
+  Theta.height().setValue(1.0);
+
+  // Manufacture an ATan function:
+  GeoGenfun::ATan ATan;
+  
+
+  // Manufacture a Mod function, putting this on the range (0-2PI)
+  GeoGenfun::Mod Mod2Pi(2*M_PI);
+
+  // Now take ATan if x is positive 
+  
+  GeoGenfun::GENFUNCTION result = Theta(x)*ATan(y/x) + Theta(-x)*(Mod2Pi(ATan(y/x)+M_PI)); 
+  return GeoGenfun::FunctionNoop(&result);
+
+}
diff --git a/LArCalorimeter/LArGeoModel/LArGeoBarrel/src/BarrelAuxFunctions.h b/LArCalorimeter/LArGeoModel/LArGeoBarrel/src/BarrelAuxFunctions.h
new file mode 100755
index 0000000000000000000000000000000000000000..92e072f43df5d2888cf84d265cefaacae09fae31
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoBarrel/src/BarrelAuxFunctions.h
@@ -0,0 +1,39 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file BarrelAuxFunctions.h
+ *
+ * @brief Namespace with auxiliary functions used by BarrelConstruction and
+ *        ElStraightSectionBuilder classes
+ *
+ **/
+
+#ifndef LARGEOBARREL_BARRELAUXFUNCTIONS_H
+#define LARGEOBARREL_BARRELAUXFUNCTIONS_H
+
+#include "GeoGenericFunctions/FunctionNoop.h"
+
+
+namespace LArGeo {
+
+  GeoGenfun::FunctionNoop Fx(double r
+			     , GeoGenfun::GENFUNCTION G
+			     , const double Cenx[]
+			     , const double Ceny[]);
+
+  GeoGenfun::FunctionNoop Fy(double r
+			     , GeoGenfun::GENFUNCTION G
+			     , const double Cenx[]
+			     , const double Ceny[]);
+
+  GeoGenfun::FunctionNoop Del1(GeoGenfun::GENFUNCTION G);
+  GeoGenfun::FunctionNoop Del2(GeoGenfun::GENFUNCTION G);
+
+  GeoGenfun::FunctionNoop ATan2(GeoGenfun::GENFUNCTION y
+				, GeoGenfun::GENFUNCTION x);
+
+}
+
+#endif
diff --git a/LArCalorimeter/LArGeoModel/LArGeoBarrel/src/BarrelConstruction.cxx b/LArCalorimeter/LArGeoModel/LArGeoBarrel/src/BarrelConstruction.cxx
index 3e8528b6574def568bf7a208286d3998f08df705..877abb2107424b83c3a5c4fdb5b2ba1d65ba084e 100755
--- a/LArCalorimeter/LArGeoModel/LArGeoBarrel/src/BarrelConstruction.cxx
+++ b/LArCalorimeter/LArGeoModel/LArGeoBarrel/src/BarrelConstruction.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 
@@ -12,6 +12,7 @@
 // creation: August 2003
 
 #include "LArGeoBarrel/BarrelConstruction.h"
+#include "BarrelAuxFunctions.h"
 
 #include "LArGeoCode/VDetectorParameters.h"
 
@@ -191,7 +192,6 @@ void LArGeo::BarrelConstruction::MakeEnvelope()
   log << MSG::INFO << "  Makes detailed absorber sandwich  ? " << doDetailedAbsorberStraight << " " << doDetailedAbsorberFold << endmsg;
   log << MSG::INFO << "  Use sagging in geometry  ? " << m_A_SAGGING << endmsg;
 
-
   GeoGenfun::Cos  Cos;
   GeoGenfun::Sin  Sin;
   GeoGenfun::Sqrt Sqrt;
@@ -1208,18 +1208,18 @@ void LArGeo::BarrelConstruction::MakeEnvelope()
 	      double Dz = Thce/2.;
 	   
 	      // For absorbers
-	      GeoGenfun::GENFUNCTION x1a = Fx(irl+0., Gama, Cenx, Ceny)
-                                           +deltay[irl]*Del1(Gama)
-                                           +deltax[irl]*Del2(Gama);
-	      GeoGenfun::GENFUNCTION x2a = Fx(irl+1., Gama, Cenx, Ceny)
-                                           +deltay[irl+1]*Del1(Gama)
-                                           +deltax[irl+1]*Del2(Gama);
-	      GeoGenfun::GENFUNCTION y1a = Fy(irl+0., Gama, Cenx, Ceny)
-                                           -deltay[irl]*Del2(Gama)
-                                           +deltax[irl]*Del1(Gama);
-	      GeoGenfun::GENFUNCTION y2a = Fy(irl+1., Gama, Cenx, Ceny)
-                                           -deltay[irl+1]*Del2(Gama)
-                                           +deltax[irl+1]*Del1(Gama);
+	      GeoGenfun::GENFUNCTION x1a = LArGeo::Fx(irl+0., Gama, Cenx, Ceny)
+                                           +deltay[irl]*LArGeo::Del1(Gama)
+                                           +deltax[irl]*LArGeo::Del2(Gama);
+	      GeoGenfun::GENFUNCTION x2a = LArGeo::Fx(irl+1., Gama, Cenx, Ceny)
+                                           +deltay[irl+1]*LArGeo::Del1(Gama)
+                                           +deltax[irl+1]*LArGeo::Del2(Gama);
+	      GeoGenfun::GENFUNCTION y1a = LArGeo::Fy(irl+0., Gama, Cenx, Ceny)
+                                           -deltay[irl]*LArGeo::Del2(Gama)
+                                           +deltax[irl]*LArGeo::Del1(Gama);
+	      GeoGenfun::GENFUNCTION y2a = LArGeo::Fy(irl+1., Gama, Cenx, Ceny)
+                                           -deltay[irl+1]*LArGeo::Del2(Gama)
+                                           +deltax[irl+1]*LArGeo::Del1(Gama);
 	      GeoGenfun::GENFUNCTION dx = x2a - x1a;
 	      GeoGenfun::GENFUNCTION dy = y2a - y1a;
 	   
@@ -1231,7 +1231,7 @@ void LArGeo::BarrelConstruction::MakeEnvelope()
 	      // newalpha (slant angle) value of the rotation angle around Z_axis
 	      GeoGenfun::GENFUNCTION cosalfa = (da*dx -iparit*2.*Rint*dy)/Da/Da;
 	      GeoGenfun::GENFUNCTION sinalfa = (da*dy +iparit*2.*Rint*dx)/Da/Da;
-	      GeoGenfun::GENFUNCTION newalpha = ATan2(sinalfa,cosalfa);       
+	      GeoGenfun::GENFUNCTION newalpha = LArGeo::ATan2(sinalfa,cosalfa);       
 	   
 	      GeoGenfun::GENFUNCTION h1 = da/2. * frac  - .007*Gaudi::Units::mm;
 	   
@@ -1449,12 +1449,12 @@ void LArGeo::BarrelConstruction::MakeEnvelope()
 // get slant angle for the previous zig-zag
                  int iirl=jrl-1;
                  if (iirl<0) iirl=1;
-                 GeoGenfun::GENFUNCTION x0a = Fx(iirl, Gama, Cenx, Ceny)
-                                           +deltay[iirl]*Del1(Gama)
-                                           +deltax[iirl]*Del2(Gama);
-                 GeoGenfun::GENFUNCTION y0a = Fy(iirl, Gama, Cenx, Ceny)
-                                           -deltay[iirl]*Del2(Gama)
-                                           +deltax[iirl]*Del1(Gama);
+                 GeoGenfun::GENFUNCTION x0a = LArGeo::Fx(iirl, Gama, Cenx, Ceny)
+                                           +deltay[iirl]*LArGeo::Del1(Gama)
+                                           +deltax[iirl]*LArGeo::Del2(Gama);
+                 GeoGenfun::GENFUNCTION y0a = LArGeo::Fy(iirl, Gama, Cenx, Ceny)
+                                           -deltay[iirl]*LArGeo::Del2(Gama)
+                                           +deltax[iirl]*LArGeo::Del1(Gama);
                  GeoGenfun::GENFUNCTION dx0 = x1a - x0a;
                  GeoGenfun::GENFUNCTION dy0 = y1a - y0a;
               // Da the two fold centers distance, da straight part length
@@ -1463,7 +1463,7 @@ void LArGeo::BarrelConstruction::MakeEnvelope()
               // newalpha (slant angle) value of the rotation angle around Z_axis
                  GeoGenfun::GENFUNCTION cosalfa0 = (da0*dx0 +iparit*2.*Rint*dy0)/Da0/Da0;
                  GeoGenfun::GENFUNCTION sinalfa0 = (da0*dy0 -iparit*2.*Rint*dx0)/Da0/Da0;
-                 GeoGenfun::GENFUNCTION alpha_prev = ATan2(sinalfa0,cosalfa0);
+                 GeoGenfun::GENFUNCTION alpha_prev = LArGeo::ATan2(sinalfa0,cosalfa0);
 
 #ifdef DEBUGGEO
                 if (jrl>0 && jrl<Nbrt) {
@@ -1701,18 +1701,18 @@ void LArGeo::BarrelConstruction::MakeEnvelope()
 	      double Dze = Thel/2.;
 	   
 	      // For electrodes
-	      GeoGenfun::GENFUNCTION x1e = Fx(irl+0., Game, Cenx, Ceny)
-                                           +deltay[irl]*Del1(Game)
-                                           +deltax[irl]*Del2(Game);
-	      GeoGenfun::GENFUNCTION x2e = Fx(irl+1., Game, Cenx, Ceny)
-                                           +deltay[irl+1]*Del1(Game)
-                                           +deltax[irl+1]*Del2(Game);
-	      GeoGenfun::GENFUNCTION y1e = Fy(irl+0., Game, Cenx, Ceny) 
-                                           -deltay[irl]*Del2(Game)
-                                           +deltax[irl]*Del1(Game);
-	      GeoGenfun::GENFUNCTION y2e = Fy(irl+1., Game, Cenx, Ceny)
-                                           -deltay[irl+1]*Del2(Game)
-                                           +deltax[irl+1]*Del1(Game);
+	      GeoGenfun::GENFUNCTION x1e = LArGeo::Fx(irl+0., Game, Cenx, Ceny)
+                                           +deltay[irl]*LArGeo::Del1(Game)
+                                           +deltax[irl]*LArGeo::Del2(Game);
+	      GeoGenfun::GENFUNCTION x2e = LArGeo::Fx(irl+1., Game, Cenx, Ceny)
+                                           +deltay[irl+1]*LArGeo::Del1(Game)
+                                           +deltax[irl+1]*LArGeo::Del2(Game);
+	      GeoGenfun::GENFUNCTION y1e = LArGeo::Fy(irl+0., Game, Cenx, Ceny) 
+                                           -deltay[irl]*LArGeo::Del2(Game)
+                                           +deltax[irl]*LArGeo::Del1(Game);
+	      GeoGenfun::GENFUNCTION y2e = LArGeo::Fy(irl+1., Game, Cenx, Ceny)
+                                           -deltay[irl+1]*LArGeo::Del2(Game)
+                                           +deltax[irl+1]*LArGeo::Del1(Game);
 	      GeoGenfun::GENFUNCTION dxe = x2e - x1e;
 	      GeoGenfun::GENFUNCTION dye = y2e - y1e;
 	    // De the two fold centers distance, de straight part length
@@ -1722,7 +1722,7 @@ void LArGeo::BarrelConstruction::MakeEnvelope()
 	    //newalphe (slant angle) value of the rotation angle around Z_axis
 	      GeoGenfun::GENFUNCTION cosalfae = (de*dxe -iparit*2.*Rint*dye)/De/De;
 	      GeoGenfun::GENFUNCTION sinalfae = (de*dye +iparit*2.*Rint*dxe)/De/De;
-	      GeoGenfun::GENFUNCTION newalphe = ATan2(sinalfae,cosalfae);
+	      GeoGenfun::GENFUNCTION newalphe = LArGeo::ATan2(sinalfae,cosalfae);
 	   
 	   
 	    // newalphae is already computed angle wrt z axis
@@ -1814,12 +1814,12 @@ void LArGeo::BarrelConstruction::MakeEnvelope()
 // get slant angle for the previous zig-zag
                  int iirl=jrl-1;
                  if (iirl<0) iirl=1;
-                 GeoGenfun::GENFUNCTION x0e = Fx(iirl, Game, Cenx, Ceny)
-                                           +deltay[iirl]*Del1(Game)
-                                           +deltax[iirl]*Del2(Game);
-                 GeoGenfun::GENFUNCTION y0e = Fy(iirl, Game, Cenx, Ceny)
-                                           -deltay[iirl]*Del2(Game)
-                                           +deltax[iirl]*Del1(Game);
+                 GeoGenfun::GENFUNCTION x0e = LArGeo::Fx(iirl, Game, Cenx, Ceny)
+                                           +deltay[iirl]*LArGeo::Del1(Game)
+                                           +deltax[iirl]*LArGeo::Del2(Game);
+                 GeoGenfun::GENFUNCTION y0e = LArGeo::Fy(iirl, Game, Cenx, Ceny)
+                                           -deltay[iirl]*LArGeo::Del2(Game)
+                                           +deltax[iirl]*LArGeo::Del1(Game);
                  GeoGenfun::GENFUNCTION dx0 = x1e - x0e;
                  GeoGenfun::GENFUNCTION dy0 = y1e - y0e;
               // Da the two fold centers distance, da straight part length
@@ -1828,7 +1828,7 @@ void LArGeo::BarrelConstruction::MakeEnvelope()
               // newalpha (slant angle) value of the rotation angle around Z_axis
                  GeoGenfun::GENFUNCTION cosalfa0 = (da0*dx0 +iparit*2.*Rint*dy0)/Da0/Da0;
                  GeoGenfun::GENFUNCTION sinalfa0 = (da0*dy0 -iparit*2.*Rint*dx0)/Da0/Da0;
-                 GeoGenfun::GENFUNCTION alphe_prev = ATan2(sinalfa0,cosalfa0);
+                 GeoGenfun::GENFUNCTION alphe_prev = LArGeo::ATan2(sinalfa0,cosalfa0);
 
 #ifdef DEBUGGEO
                 if (jrl>0 && jrl<Nbrt) {
@@ -1999,66 +1999,6 @@ void LArGeo::BarrelConstruction::MakeEnvelope()
   
 }
 
-// Generic Function Versions
-
-GeoGenfun::FunctionNoop LArGeo::BarrelConstruction::Fx(double r, GeoGenfun::GENFUNCTION G, const double Cenx[], const double Ceny[] ) const
-{
-  GeoGenfun::Cos Cos;
-  GeoGenfun::Sin Sin;
-  int i = (int)rint(r-.1), j = (int)rint(r+.1) ;
-  GeoGenfun::GENFUNCTION result =  (Cos(G)*(Cenx[i]+Cenx[j])/2-Sin(G)*(Ceny[i]+Ceny[j])/2) ;
-  return GeoGenfun::FunctionNoop(&result);
-}
-
-GeoGenfun::FunctionNoop LArGeo::BarrelConstruction::Fy(double r, GeoGenfun::GENFUNCTION G, const double Cenx[], const double Ceny[] ) const
-{
-  GeoGenfun::Cos Cos;
-  GeoGenfun::Sin Sin;
-  int i = (int)rint(r-.1), j = (int)rint(r+.1) ;
-  GeoGenfun::GENFUNCTION result = (Sin(G)*(Cenx[i]+Cenx[j])/2+Cos(G)*(Ceny[i]+Ceny[j])/2) ;
-  return GeoGenfun::FunctionNoop(&result);
-}
-
-GeoGenfun::FunctionNoop LArGeo::BarrelConstruction::Del1(GeoGenfun::GENFUNCTION G) const
-{
-  GeoGenfun::Cos Cos;
-  GeoGenfun::Sin Sin;
-  GeoGenfun::GENFUNCTION result = (Cos(  G ) * Sin( G ) );
-  return GeoGenfun::FunctionNoop(&result);
-}
-
-GeoGenfun::FunctionNoop LArGeo::BarrelConstruction::Del2(GeoGenfun::GENFUNCTION G) const
-{
-  GeoGenfun::Cos Cos;
-  GeoGenfun::GENFUNCTION result = (Cos(  G ) * Cos( G ) );
-  return GeoGenfun::FunctionNoop(&result);
-}
-
-
-GeoGenfun::FunctionNoop LArGeo::BarrelConstruction::ATan2(GeoGenfun::GENFUNCTION y, GeoGenfun::GENFUNCTION x) const {
-
-  // Manufacture a Theta Function:
-  GeoGenfun::Rectangular Theta;
-  Theta.x0().setValue(0.0);
-  Theta.x1().setValue(DBL_MAX);
-  Theta.baseline().setValue(0.0);
-  Theta.height().setValue(1.0);
-
-  // Manufacture an ATan function:
-  GeoGenfun::ATan ATan;
-  
-
-  // Manufacture a Mod function, putting this on the range (0-2PI)
-  GeoGenfun::Mod Mod2Pi(2*M_PI);
-
-  // Now take ATan if x is positive 
-  
-  GeoGenfun::GENFUNCTION result = Theta(x)*ATan(y/x) + Theta(-x)*(Mod2Pi(ATan(y/x)+M_PI)); 
-  return GeoGenfun::FunctionNoop(&result);
-
-}
-
-
 void LArGeo::BarrelConstruction::printParams()
 {
  std::cout << "******** Print out of LArBarrel Accordion parameters " << std::endl;
diff --git a/LArCalorimeter/LArGeoModel/LArGeoBarrel/src/ElStraightSectionBuilder.cxx b/LArCalorimeter/LArGeoModel/LArGeoBarrel/src/ElStraightSectionBuilder.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..41d8e8659e9d8ab03cd5b3416661ce995da8f82f
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoBarrel/src/ElStraightSectionBuilder.cxx
@@ -0,0 +1,443 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "LArGeoBarrel/ElStraightSectionBuilder.h"
+#include "BarrelAuxFunctions.h"
+
+#include "LArReadoutGeometry/GeoStraightAccSection.h"
+
+#include "RDBAccessSvc/IRDBRecord.h"
+#include "RDBAccessSvc/IRDBRecordset.h"
+#include "RDBAccessSvc/IRDBAccessSvc.h"
+
+#include "GeoModelKernel/GeoTrap.h"
+#include "StoreGate/StoreGateSvc.h"
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiKernel/MsgStream.h"
+
+#include "GeoGenericFunctions/Sqrt.h"
+#include "GeoGenericFunctions/ATan.h"
+#include "GeoGenericFunctions/Variable.h"
+#include "GeoGenericFunctions/FixedConstant.h"
+
+#define SYSTEM_OF_UNITS Gaudi::Units
+
+StatusCode LArGeo::buildElStraightSections(StoreGateSvc* detStore
+					   , IRDBAccessSvc* paramSvc
+					   , IMessageSvc* msgSvc
+					   , bool sagging)
+{
+  MsgStream log(msgSvc, "buildElStraightSections"); 
+  
+  GeoGenfun::Sqrt Sqrt;
+  GeoGenfun::ATan ATan;
+
+  IRDBRecordset_ptr barrelGeometryRec  = paramSvc->getRecordsetPtr("BarrelGeometry","");
+  IRDBRecordset_ptr barrelSaggingRec   = paramSvc->getRecordsetPtr("BarrelSagging","");
+  IRDBRecordset_ptr barrelEtaTransRec  = paramSvc->getRecordsetPtr("BarrelEtaTrans","");
+  IRDBRecordset_ptr coldContractionRec = paramSvc->getRecordsetPtr("ColdContraction","");
+
+  double Moth_Z_min = (*barrelGeometryRec)[0]->getDouble("ZMIN")*SYSTEM_OF_UNITS::cm;
+  double Moth_Z_max = (*barrelGeometryRec)[0]->getDouble("ZMAX")*SYSTEM_OF_UNITS::cm;
+  double Moth_inner_radius = (*barrelGeometryRec)[0]->getDouble("RMIN")*SYSTEM_OF_UNITS::cm;
+
+  // number of zigs for accordion
+  int    Nbrt = (*barrelGeometryRec)[0]->getInt("NBRT");  // =14
+
+  // Z coordinates for half barrel in 
+  double Bar_Z_min = Moth_Z_min;
+  double Bar_Z_max = Moth_Z_max;
+
+  double Bar_Rcmx  = (*barrelGeometryRec)[0]->getDouble("RMINHIGHZ")*SYSTEM_OF_UNITS::cm;
+
+  // Accordion shape parameters:
+  // rho phi of curvature centers and delta's
+  // IN 2D_transverse LOCAL framework of a layer and symetry axis as X_axis
+  // delta's are GEOMETRICAL angles of straight parts w.r. the Y_axis )
+
+  double Rhocen[15], Phicen[15], Delta[15], deltay[15], deltax[15], TetaTrans[15];
+  for (int idat=0; idat<15; idat++) {
+    std::string strIdat = std::to_string(idat);
+    Rhocen[idat] = (*barrelGeometryRec)[0]->getDouble("RHOCEN_"+strIdat)*SYSTEM_OF_UNITS::cm;
+    Phicen[idat] = (*barrelGeometryRec)[0]->getDouble("PHICEN_"+strIdat)*SYSTEM_OF_UNITS::deg;
+    Delta[idat]  = (*barrelGeometryRec)[0]->getDouble("DELTA_"+strIdat)*SYSTEM_OF_UNITS::deg;
+    if(idat == 14) {
+      Delta[idat]  = (90.0) * SYSTEM_OF_UNITS::deg;
+    }
+
+    // Maximum SAGGING displacement for each of the fifteen folds in Gaudi::Units::mm
+    // (should be 0.0, 0.17, 0.30, 0.63, 0.78, 1.06, 1.09, 1.21, 1.07, 1.03, 0.74, 0.61, 0.27, 0.20, 0.0)
+    //GUtmp sagging amplied by 10
+    if (sagging)  {
+      deltay[idat] = (*barrelSaggingRec)[0]->getDouble("SAG_"+strIdat)*SYSTEM_OF_UNITS::cm;
+      deltax[idat] = (*barrelSaggingRec)[0]->getDouble("SAG_"+strIdat+"_X")*SYSTEM_OF_UNITS::cm;
+    }
+    else {
+      deltay[idat]=0.;
+      deltax[idat]=0.;
+    }
+  
+    // eta of lead transition
+    double etaTrans = (*barrelEtaTransRec)[idat]->getDouble("ETATRANS");
+    TetaTrans[idat] = 2.*atan(exp(-etaTrans));
+  }
+
+  // parity of accordion waves
+  int checkParity = (Phicen[0]<0. ? 1 : 0);   // 0 for case where first absorber wave goes up
+                                              // 1 for case where first absorber wave goes down
+
+  int Ncell      = (*barrelGeometryRec)[0]->getInt("NCELMX");
+  int Nabsorber  = (Ncell==64)  ? Ncell + 1 : Ncell;
+  int Nelectrode = Ncell;
+
+  // z of end of G10 ring
+  double z1   = (*barrelGeometryRec)[0]->getDouble("G10FRONTDELTAZ")*SYSTEM_OF_UNITS::cm + Moth_Z_min;
+  // radius of end of G10 ring
+  const double r1    = Moth_inner_radius
+    + (*barrelGeometryRec)[0]->getDouble("XEL1")*SYSTEM_OF_UNITS::cm
+    + (*barrelGeometryRec)[0]->getDouble("XG10")*SYSTEM_OF_UNITS::cm;
+  // minimum radius at end of volume
+  const double r2    =  (*barrelGeometryRec)[0]->getDouble("RMINHIGHZ")*SYSTEM_OF_UNITS::cm;
+  const double inv_r2_r1 = 1. / (r2-r1);
+  
+  {
+    // Construct the straight and the corner parts of the Accordion plates
+    double Thgl       = (*barrelGeometryRec)[0]->getDouble("THGL")*SYSTEM_OF_UNITS::cm;
+    double Thfe       = (*barrelGeometryRec)[0]->getDouble("THFE")*SYSTEM_OF_UNITS::cm;
+    double Thpb       = (*barrelGeometryRec)[0]->getDouble("THPB")*SYSTEM_OF_UNITS::cm;
+    double Thcu       = (*barrelGeometryRec)[0]->getDouble("THCU")*SYSTEM_OF_UNITS::cm;
+    double Thfg       = (*barrelGeometryRec)[0]->getDouble("THFG")*SYSTEM_OF_UNITS::cm;
+
+    double Contract   = (*coldContractionRec)[0]->getDouble("ABSORBERCONTRACTION");
+
+    double Thce = (Thpb+Thgl+Thfe)*Contract;
+    double Thel = Thcu+Thfg;
+   
+    double Zmin = Bar_Z_min;
+    double Zmax = Bar_Z_max;
+    double /*Zcp2[15],*/Along[14];
+
+    double Zcp1l[14],Zcp1h[14],Zcp2l[14],Zcp2h[14];
+    double Rhol[14],Rhoh[14];
+
+    double safety_along = 0.007*SYSTEM_OF_UNITS::mm;
+
+    // Compute centers of curvature coordinates in a local frame.
+    double Cenx[15]={0}, Ceny[15]={0} ;
+    for (int jf=0; jf<(Nbrt+1); jf++) {
+	Cenx[jf] = Rhocen[jf]*cos(Phicen[jf]); // Phicen[] already in radians
+	Ceny[jf] = Rhocen[jf]*sin(Phicen[jf]);
+    }
+
+    // Compute staight lengths of folds
+    double Rint = (*barrelGeometryRec)[0]->getDouble("RINT")*SYSTEM_OF_UNITS::cm;
+    for (int jl=0; jl<Nbrt; jl++) {
+      double Adisc2 = (Cenx[jl+1]-Cenx[jl])*(Cenx[jl+1]-Cenx[jl])+
+                      (Ceny[jl+1]-Ceny[jl])*(Ceny[jl+1]-Ceny[jl]);
+      double Along2 = Adisc2 - 4.*Rint*Rint; 
+      Along[jl] = sqrt(Along2);
+
+      double ddelta = M_PI/2.-Delta[jl];
+      // different parity depending on direction of first wave
+      if (checkParity==0) {
+        if (jl%2==1) {
+	  ddelta=-1.*ddelta;
+	}
+      } else {
+        if (jl%2==0) {
+	  ddelta=-1.*ddelta;
+	}
+      }
+      double xlong=Along[jl]-2.*safety_along;
+      double x2=0.5*(Cenx[jl+1]+Cenx[jl])+0.5*xlong*cos(ddelta);
+      double y2=0.5*(Ceny[jl+1]+Ceny[jl])+0.5*xlong*sin(ddelta);
+      double x1=0.5*(Cenx[jl+1]+Cenx[jl])-0.5*xlong*cos(ddelta);
+      double y1=0.5*(Ceny[jl+1]+Ceny[jl])-0.5*xlong*sin(ddelta);
+      Rhol[jl] = sqrt(x1*x1+y1*y1);
+      Rhoh[jl] = sqrt(x2*x2+y2*y2);
+      Zcp1l[jl] = Rhol[jl]/tan(TetaTrans[jl]);
+      Zcp1h[jl] = Rhoh[jl]/tan(TetaTrans[jl+1]);
+      if (Rhol[jl] < r2) {
+	Zcp2l[jl] = z1 + (Rhol[jl]-r1)*inv_r2_r1*(Moth_Z_max-z1);
+      }
+      else {
+	Zcp2l[jl]=Moth_Z_max;
+      }
+      if (Rhoh[jl] < r2) {
+	Zcp2h[jl] = z1 + (Rhoh[jl]-r1)*inv_r2_r1*(Moth_Z_max-z1);
+      }
+      else {    
+	Zcp2h[jl]=Moth_Z_max;
+      }
+    }
+   
+    double Psi        = (*barrelGeometryRec)[0]->getDouble("ALFA")*SYSTEM_OF_UNITS::deg;   // 360.*Gaudi::Units::deg/1024
+    double Gama0      = (*barrelGeometryRec)[0]->getDouble("PHIFIRST");
+    double Alfa = Psi;                        // size of one phi cell   
+
+    GeoGenfun::Variable icopy;
+    GeoGenfun::GENFUNCTION Game = Gama0 + Psi/2 + Alfa*icopy;
+    GeoGenfun::GENFUNCTION Gama = Gama0 + Alfa*icopy;
+
+    GeoStraightAccSection* gStraightElectrodes{nullptr};
+    GeoStraightAccSection* gStraightAbsorbers{nullptr};
+    //
+    // Loop through the straight and corner(Fold) parts of the Accordion plates
+    // Repeat each part around Phi, then move to the next, towards outer radii
+    //
+
+    // GU 09/06/2004 add some safety in z size
+    double safety_zlen=0.050*SYSTEM_OF_UNITS::mm;
+   
+    for(int irl=0; irl<Nbrt; irl++) {  // loop over zig-zag in radius
+      int iparit;
+      // different parity depending on direction of first wave
+      if (checkParity==0) {       
+	iparit= (1-2*(irl%2));  // +1 for irl=0,2,4,..   -1 for irl=1,3,5,..
+      } 
+      else {
+	iparit=(2*(irl%2)-1);  // -1 for irl=0,2,3...  +1 for irl=1,3,5
+      }
+      
+      // special case if Rhocen[il] < Bar_Rcmx < Rhocen[il+1]
+      // we had to divide the fold in two different pieces to deal with the shape
+      int ndivi=1;
+      if (Rhocen[irl] < Bar_Rcmx && Rhocen[irl+1] > Bar_Rcmx) {
+	ndivi=2;
+      } 
+
+      for (int idivi=0;idivi<ndivi;idivi++) {
+
+	// lenght in z at beginning and end of straigth part
+	double bl1,tl1;
+	double frac;
+	if (ndivi==1) {
+	  bl1 = (std::min(Zcp2l[irl],Zmax)-Zmin)/2.;
+	  tl1 = (std::min(Zcp2h[irl],Zmax)-Zmin)/2.;
+	  frac=1.;
+	}
+	else {
+	  if (idivi==0) {
+	    bl1 = (std::min(Zcp2l[irl],Zmax)-Zmin)/2.;
+	    tl1 = (Zmax-Zmin)/2.;
+	    frac=(Bar_Rcmx-Rhol[irl])/(Rhoh[irl]-Rhol[irl]);
+	  }
+	  else {
+	    bl1 = (Zmax-Zmin)/2.;
+	    tl1 = (Zmax-Zmin)/2.;
+	    frac=(Rhoh[irl]-Bar_Rcmx)/(Rhoh[irl]-Rhol[irl]);
+	  }
+	}
+	//GU 09/06/2004 add small safety in size tl1 and bl1
+	tl1=tl1-safety_zlen;
+	bl1=bl1-safety_zlen;
+
+	//    =================================== Absorbers
+	{
+	  // thickness of absorber
+	  double Dz = Thce/2.;
+	   
+	  // For absorbers
+	  GeoGenfun::GENFUNCTION x1a = LArGeo::Fx(irl+0., Gama, Cenx, Ceny)
+	    +deltay[irl]*LArGeo::Del1(Gama)
+	    +deltax[irl]*LArGeo::Del2(Gama);
+	  GeoGenfun::GENFUNCTION x2a = LArGeo::Fx(irl+1., Gama, Cenx, Ceny)
+	    +deltay[irl+1]*LArGeo::Del1(Gama)
+	    +deltax[irl+1]*LArGeo::Del2(Gama);
+	  GeoGenfun::GENFUNCTION y1a = LArGeo::Fy(irl+0., Gama, Cenx, Ceny)
+	    -deltay[irl]*LArGeo::Del2(Gama)
+	    +deltax[irl]*LArGeo::Del1(Gama);
+	  GeoGenfun::GENFUNCTION y2a = LArGeo::Fy(irl+1., Gama, Cenx, Ceny)
+	    -deltay[irl+1]*LArGeo::Del2(Gama)
+	    +deltax[irl+1]*LArGeo::Del1(Gama);
+	  GeoGenfun::GENFUNCTION dx = x2a - x1a;
+	  GeoGenfun::GENFUNCTION dy = y2a - y1a;
+	   
+	  // Da the two fold centers distance, da straight part length
+	   
+	  GeoGenfun::GENFUNCTION Da = Sqrt ( dx*dx + dy*dy );
+	  GeoGenfun::GENFUNCTION da = Sqrt ( (Da - 2.*Rint)*(Da + 2.*Rint) );
+	   
+	  // newalpha (slant angle) value of the rotation angle around Z_axis
+	  GeoGenfun::GENFUNCTION cosalfa = (da*dx -iparit*2.*Rint*dy)/Da/Da;
+	  GeoGenfun::GENFUNCTION sinalfa = (da*dy +iparit*2.*Rint*dx)/Da/Da;
+	  GeoGenfun::GENFUNCTION newalpha = LArGeo::ATan2(sinalfa,cosalfa);       
+	  
+	  GeoGenfun::GENFUNCTION h1 = da/2. * frac  - .007*SYSTEM_OF_UNITS::mm;
+	   
+	  // thick absorber pieces
+	  // more correct computation with z lenght computed exactly at the
+	  // radius of the end and the beginning of the straight sections
+	  double Xb1,Xt1;
+	  if (ndivi==1) {
+	    Xb1 = (Zcp1l[irl]-Zmin)/2.;
+	    Xt1 = (Zcp1h[irl]-Zmin)/2.;
+	  } 
+	  else {
+	    double xfrac=(Bar_Rcmx-Rhol[irl])/(Rhoh[irl]-Rhol[irl]);
+	    if (idivi==0) {
+	      Xb1 = (Zcp1l[irl]-Zmin)/2.;
+	      Xt1 = (xfrac*Zcp1h[irl]+(1.-xfrac)*Zcp1l[irl]-Zmin)/2.;
+	    }
+	    else {
+	      Xb1 = (xfrac*Zcp1h[irl]+(1.-xfrac)*Zcp1l[irl]-Zmin)/2.;
+	      Xt1 = (Zcp1h[irl]-Zmin)/2.;
+	    } 
+	  }
+
+	  // lengths that remain to be covered with the thin absorber
+	  double Xt2 = tl1-Xt1;
+	  double Xb2 = bl1-Xb1;
+        
+	  Xt2 = Xt2 -0.007*SYSTEM_OF_UNITS::mm;
+	  Xb2 = Xb2 -0.007*SYSTEM_OF_UNITS::mm;
+           
+	   
+	  GeoGenfun::GENFUNCTION alpha = ATan(0.5*(bl1-tl1)/h1);
+
+	  // angle that would be needed for trap do describe only thin absorber
+	  //     ------------------|---------X---------|
+	  //     <------------------------------------->  2*tl1
+	  //                       <--------->   Xt2
+	  //
+	  //     <--------------------------------->  2*bl1
+	  //                    <-------->  Xb2 
+	  //     ---------------|--------X---------|
+	  // alpha = (-) angle between X's
+	  //   tan(alpha) = delta X size / width,   deltaX size = 2*tl1-Xt2-(2*bl1-Xb2),  width = 2.*h1  
+	   
+	  // .newalpha is already computed angle wrt z axis
+	  // P/2 rotation is to get absorber aligned along local x axis
+	  // instead of y, then rotate with angle newalpha
+	  GeoGenfun::GENFUNCTION alfrot =  -M_PI/2. - newalpha;
+	  
+	  GeoGenfun::GENFUNCTION Xcd    = (x1a + x2a)/2. + (2.*idivi-1.)*(1.-frac)*da/2.*cosalfa;
+	  GeoGenfun::GENFUNCTION Ycd    = (y1a + y2a)/2. + (2.*idivi-1.)*(1.-frac)*da/2.*sinalfa;
+	  GeoGenfun::GENFUNCTION Zcd    = GeoGenfun::FixedConstant(Zmin+(tl1+bl1)/2.+safety_zlen);
+	  
+	  GeoXF::TRANSFUNCTION TX = 
+	    GeoXF::Pow(GeoTrf::TranslateX3D(1.0),Xcd) *
+	    GeoXF::Pow(GeoTrf::TranslateY3D(1.0),Ycd) *
+	    GeoXF::Pow(GeoTrf::TranslateZ3D(1.0),Zcd) * 
+	    GeoXF::Pow(GeoTrf::RotateZ3D(1.0),-alfrot)*
+	    GeoTrf::RotateY3D(-90*SYSTEM_OF_UNITS::deg);                    
+	  
+	  for (int instance = 0; instance < Nabsorber; instance++) {
+		
+	    GeoTrap* thinTrap = new GeoTrap(Dz,0.,0.,h1(instance),tl1,bl1,alpha(instance),
+					    h1(instance),tl1,bl1,alpha(instance));
+	    thinTrap->ref();	    
+	    if (sagging) {
+	      if (!gStraightAbsorbers) {
+		gStraightAbsorbers = new GeoStraightAccSection();
+	      }
+	      gStraightAbsorbers->XCent(instance,irl)=TX(instance)(0,3); //dx
+	      gStraightAbsorbers->YCent(instance,irl)=TX(instance)(1,3); //dy
+	      gStraightAbsorbers->Cosu(instance,irl)    =-(TX(instance)(0,1)); //xy
+	      gStraightAbsorbers->Sinu(instance,irl)    = (TX(instance)(0,2)); //xz
+	      gStraightAbsorbers->HalfLength(instance,irl) = thinTrap->getDydzn();
+	      thinTrap->unref();	    
+	    }
+	    else {
+	      if (!gStraightAbsorbers) {
+		gStraightAbsorbers = new GeoStraightAccSection();
+	      }
+	      gStraightAbsorbers->setTransform (irl,TX);
+	      gStraightAbsorbers->setHalfLength(irl,thinTrap->getDydzn());
+	      thinTrap->unref();
+	      break;
+	    }
+	  }    // loop over instances
+	}   // end absorbers
+
+	// ========================  Electrodes:
+	{
+	  // thickness of electrode
+	  double Dze = Thel/2.;
+	  
+	  // For electrodes
+	  GeoGenfun::GENFUNCTION x1e = LArGeo::Fx(irl+0., Game, Cenx, Ceny)
+	    +deltay[irl]*LArGeo::Del1(Game)
+	    +deltax[irl]*LArGeo::Del2(Game);
+	  GeoGenfun::GENFUNCTION x2e = LArGeo::Fx(irl+1., Game, Cenx, Ceny)
+	    +deltay[irl+1]*LArGeo::Del1(Game)
+	    +deltax[irl+1]*LArGeo::Del2(Game);
+	  GeoGenfun::GENFUNCTION y1e = LArGeo::Fy(irl+0., Game, Cenx, Ceny) 
+	    -deltay[irl]*LArGeo::Del2(Game)
+	    +deltax[irl]*LArGeo::Del1(Game);
+	  GeoGenfun::GENFUNCTION y2e = LArGeo::Fy(irl+1., Game, Cenx, Ceny)
+	    -deltay[irl+1]*LArGeo::Del2(Game)
+	    +deltax[irl+1]*LArGeo::Del1(Game);
+	  GeoGenfun::GENFUNCTION dxe = x2e - x1e;
+	  GeoGenfun::GENFUNCTION dye = y2e - y1e;
+	  // De the two fold centers distance, de straight part length
+	  GeoGenfun::GENFUNCTION De = Sqrt ( dxe*dxe + dye*dye );
+	  GeoGenfun::GENFUNCTION de = Sqrt ( (De - 2.*Rint)*(De + 2.*Rint) );
+	  
+	  //newalphe (slant angle) value of the rotation angle around Z_axis
+	  GeoGenfun::GENFUNCTION cosalfae = (de*dxe -iparit*2.*Rint*dye)/De/De;
+	  GeoGenfun::GENFUNCTION sinalfae = (de*dye +iparit*2.*Rint*dxe)/De/De;
+	  GeoGenfun::GENFUNCTION newalphe = LArGeo::ATan2(sinalfae,cosalfae);
+	  
+	  // newalphae is already computed angle wrt z axis
+	  // P/2 rotation is to get absorber aligned along local x axis
+	  // instead of y, then rotate with angle newalpha
+	  GeoGenfun::GENFUNCTION alfrote = -M_PI/2. - newalphe;
+	   
+	  GeoGenfun::GENFUNCTION Xcde    = (x1e + x2e)/2.+ (2.*idivi-1.)*(1.-frac)*de/2.*cosalfae;
+	  GeoGenfun::GENFUNCTION Ycde    = (y1e + y2e)/2.+ (2.*idivi-1.)*(1.-frac)*de/2.*sinalfae;
+	  GeoGenfun::GENFUNCTION Zcde       = GeoGenfun::FixedConstant(Zmin+(tl1+bl1)/2.+safety_zlen);
+	  
+	  GeoGenfun::GENFUNCTION h1e      = de/2.*frac - .007*SYSTEM_OF_UNITS::mm;
+	  GeoGenfun::GENFUNCTION alpha_e  = ATan(0.5*(bl1-tl1)/h1e); 
+	  
+	  GeoXF::TRANSFUNCTION TXE = 
+	    GeoXF::Pow(GeoTrf::TranslateX3D(1.0),Xcde) *
+	    GeoXF::Pow(GeoTrf::TranslateY3D(1.0),Ycde) *
+	    GeoXF::Pow(GeoTrf::TranslateZ3D(1.0),Zcde) * 
+	    GeoXF::Pow(GeoTrf::RotateZ3D(1.0),-alfrote)*
+	    GeoTrf::RotateY3D(-90*SYSTEM_OF_UNITS::deg);                    
+	  
+	  for (int instance = 0; instance < Nelectrode; instance++) {
+
+	    GeoTrap* trap = new GeoTrap(Dze,0.,0.,h1e(instance),tl1,bl1,alpha_e(instance),
+					h1e(instance),tl1,bl1,alpha_e(instance));
+	    trap->ref();
+	    if (sagging) {
+	      if (!gStraightElectrodes) {
+		gStraightElectrodes = new GeoStraightAccSection();
+	      }
+	      gStraightElectrodes->XCent(instance,irl)=TXE(instance)(0,3); //dx
+	      gStraightElectrodes->YCent(instance,irl)=TXE(instance)(1,3); //dy
+	      gStraightElectrodes->Cosu(instance,irl)    =-(TXE(instance)(0,1)); //xy
+	      gStraightElectrodes->Sinu(instance,irl)    = (TXE(instance)(0,2)); //xz
+	      gStraightElectrodes->HalfLength(instance,irl) = trap->getDydzn();
+	      trap->unref();
+	    }
+	    else {
+	      if (!gStraightElectrodes) {
+		gStraightElectrodes = new GeoStraightAccSection();
+	      }
+	      gStraightElectrodes->setTransform (irl,TXE);
+	      gStraightElectrodes->setHalfLength(irl,trap->getDydzn());
+	      trap->unref();
+	      break;
+	    }
+	  }   // loop over instances
+         }        // end loop over ndivi
+      }         //  end loop over irl (zig-zag)
+    }
+
+    if(!detStore->record(gStraightElectrodes,"STRAIGHTELECTRODES").isSuccess()) {
+      log << MSG::FATAL << "Cannot store STRAIGHTELECTRODES structure" << endmsg;
+      return StatusCode::FAILURE;
+    }
+
+    if(!detStore->record(gStraightAbsorbers,"STRAIGHTABSORBERS").isSuccess()) {
+      log << MSG::FATAL << "Cannot store STRAIGHTABSORBERS structure" << endmsg;
+      return StatusCode::FAILURE;
+    }
+  }
+  return StatusCode::SUCCESS;
+}
diff --git a/LArCalorimeter/LArRecUtils/src/LArHVCondAlg.cxx b/LArCalorimeter/LArRecUtils/src/LArHVCondAlg.cxx
index f9364d83ef6dc4812d9c3ee4044f9a6b594ef89c..5532162a42581f4421115f692f1662f94e1a3886 100755
--- a/LArCalorimeter/LArRecUtils/src/LArHVCondAlg.cxx
+++ b/LArCalorimeter/LArRecUtils/src/LArHVCondAlg.cxx
@@ -49,6 +49,7 @@
 
 #define VDIFF_MAX 0.01 // maximum voltage difference allowed to be treated as equal
 #define WDIFF_MAX 0.0001 // maximum weight difference allowed to be treated as equal
+#define IDIFF_MAX 0.1 // maximum current difference allowed to be treated as equal
 
 #define HV_NON_NOMINAL_TOLERANCE 10 // tolerance : 1V for HV
 #define DEAD_HV_THRESHOLD 10 // HV <10 V="dead"
@@ -596,7 +597,8 @@ StatusCode LArHVCondAlg::fillPayload(LArHVData* hvdata
             unsigned int found=0;
             for(unsigned int i=0;i<v.size();++i) {
                for(unsigned int j=0; j<v.size(); ++j) {
-                  if(fabs(v[i].hv - oldv[j].hv) < VDIFF_MAX  && fabs(v[i].weight - oldv[j].weight) < WDIFF_MAX) {
+                  if(fabs(v[i].hv - oldv[j].hv) < VDIFF_MAX && fabs(v[i].current - oldv[j].current) < IDIFF_MAX  
+                               && fabs(v[i].weight - oldv[j].weight) < WDIFF_MAX ) {
                      ++found;
                      break;
                   }
@@ -682,7 +684,8 @@ StatusCode LArHVCondAlg::fillPayload(LArHVData* hvdata
           unsigned int found=0;
           for(unsigned int i=0;i<v.size();++i) {
              for(unsigned int j=0; j<v.size(); ++j) {
-                if(fabs(v[i].hv - oldv[j].hv) < VDIFF_MAX  && fabs(v[i].weight - oldv[j].weight) < WDIFF_MAX) {
+                if(fabs(v[i].hv - oldv[j].hv) < VDIFF_MAX && fabs(v[i].current - oldv[j].current) < IDIFF_MAX  
+                       && fabs(v[i].weight - oldv[j].weight) < WDIFF_MAX) {
                    ++found;
                    break;
                 }
@@ -774,7 +777,8 @@ StatusCode LArHVCondAlg::fillPayload(LArHVData* hvdata
             unsigned int found=0;
             for(unsigned int i=0;i<v.size();++i) {
                for(unsigned int j=0; j<v.size(); ++j) {
-                  if(fabs(v[i].hv - oldv[j].hv) < VDIFF_MAX  && fabs(v[i].weight - oldv[j].weight) < WDIFF_MAX) {
+                  if(fabs(v[i].hv - oldv[j].hv) < VDIFF_MAX && fabs(v[i].current - oldv[j].current) < IDIFF_MAX 
+                           && fabs(v[i].weight - oldv[j].weight) < WDIFF_MAX) {
                      ++found;
                      break;
                   }
diff --git a/MuonSpectrometer/MuonCalib/NSWCalib/NSWCalibTools/NSWCalibTools/INSWCalibTool.h b/MuonSpectrometer/MuonCalib/NSWCalib/NSWCalibTools/NSWCalibTools/INSWCalibTool.h
index c1248b88044395536372acf5877942da95c20046..a940701b88e1e30ede06c1f9a5383c13dd48aefd 100644
--- a/MuonSpectrometer/MuonCalib/NSWCalib/NSWCalibTools/NSWCalibTools/INSWCalibTool.h
+++ b/MuonSpectrometer/MuonCalib/NSWCalib/NSWCalibTools/NSWCalibTools/INSWCalibTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 #ifndef INSWCalibTool_h
 #define INSWCalibTool_h
@@ -19,13 +19,13 @@ static const InterfaceID IID_INSWCalibTool("Muon::INSWCalibTool",1,0);
 namespace NSWCalib { 
 
   struct CalibratedStrip {
-    double charge;
-    double time;
-    double resTime;
-    double distDrift;
-    double resTransDistDrift;
-    double resLongDistDrift;
-    double dx;
+    double charge = 0;
+    double time = 0;
+    double resTime = 0;
+    double distDrift = 0;
+    double resTransDistDrift = 0;
+    double resLongDistDrift = 0;
+    double dx = 0;
     Identifier identifier;
   };
 
diff --git a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/MuonTGC_CnvTools/ITgcPrepDataReplicationTool.h b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/MuonTGC_CnvTools/ITgcPrepDataReplicationTool.h
index fdec761197526cc800d928cc7ee4689bfc6d5021..599ea1022ecd70203a2a63b698039052198d6324 100644
--- a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/MuonTGC_CnvTools/ITgcPrepDataReplicationTool.h
+++ b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/MuonTGC_CnvTools/ITgcPrepDataReplicationTool.h
@@ -1,23 +1,21 @@
 /*
-  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 MUONTGC_CNVTOOL_ITGCPREPDATAREPLICATIONTOOL_H
 #define MUONTGC_CNVTOOL_ITGCPREPDATAREPLICATIONTOOL_H
 
 #include "GaudiKernel/IAlgTool.h"
-
-static const InterfaceID IID_ITgcPrepDataReplicationTool("Muon::ITgcPrepDataReplicationTool", 1, 0);
+#include "CxxUtils/checker_macros.h"
 
 namespace Muon {
 
-  class ITgcPrepDataReplicationTool : virtual public IAlgTool  {
+  class ATLAS_NOT_THREAD_SAFE ITgcPrepDataReplicationTool : virtual public IAlgTool  {
 
-  public: 
-    /** Provide interface ID of ITgcPrepDataReplicationTool */
-    static const InterfaceID& interfaceID() { return IID_ITgcPrepDataReplicationTool; };
+  public:
+    DeclareInterfaceID( ITgcPrepDataReplicationTool, 1, 0 );
 
-    virtual StatusCode replicate()=0;
+    virtual StatusCode replicate() const = 0;
   }; 
 
 } // end of namespace
diff --git a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationAlg.h b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationAlg.h
index 513e6b2070b2876d505627f68f20846bb5a4317e..66976ee330eb5c7eafe7e0a9537bfd1530823cd1 100644
--- a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationAlg.h
+++ b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationAlg.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 TgcPrepDataReplicationAlg_h
@@ -8,11 +8,12 @@
 #include "AthenaBaseComps/AthAlgorithm.h"
 #include "GaudiKernel/ToolHandle.h"
 #include "MuonTGC_CnvTools/ITgcPrepDataReplicationTool.h"
+#include "CxxUtils/checker_macros.h"
 
 namespace Muon 
 {
 
-  class TgcPrepDataReplicationAlg:public AthAlgorithm
+  class ATLAS_NOT_THREAD_SAFE TgcPrepDataReplicationAlg:public AthAlgorithm
   {
   public:
     TgcPrepDataReplicationAlg(const std::string& name, ISvcLocator* pSvcLocator); // Constructor
diff --git a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool.cxx b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool.cxx
index 48d8d1a0b26cc2dae313a4be39cd92cc08534f41..7695ff270d6f4a409a1e480a0407dc8178859961 100644
--- a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool.cxx
@@ -11,7 +11,7 @@
 //================ Constructor =================================================
 Muon::TgcPrepDataReplicationTool::TgcPrepDataReplicationTool
   (const std::string& t, const std::string& n, const IInterface* p)
-  : AthAlgTool(t, n, p)
+  : base_class(t, n, p)
 {
   for(int ibc = 0; ibc < BC_NUM; ibc++) m_tgcPrepDataContainer[ibc] = 0;
 }  
@@ -51,7 +51,7 @@ StatusCode Muon::TgcPrepDataReplicationTool::finalize()
 
 
 //================ Decoding ====================================================
-StatusCode Muon::TgcPrepDataReplicationTool::replicate()
+StatusCode Muon::TgcPrepDataReplicationTool::replicate() const
 {
   bool hasContainer[BC_NUM] = {false}; 
   ATH_MSG_VERBOSE("replicate");
@@ -82,7 +82,7 @@ StatusCode Muon::TgcPrepDataReplicationTool::replicate()
 }
 
 
-StatusCode Muon::TgcPrepDataReplicationTool::convertAllBCto3BC()
+StatusCode Muon::TgcPrepDataReplicationTool::convertAllBCto3BC() const
 {
 
   const Muon::TgcPrepDataContainer* tgcAll = 0;
@@ -151,7 +151,7 @@ StatusCode Muon::TgcPrepDataReplicationTool::convertAllBCto3BC()
 }
 
 
-StatusCode Muon::TgcPrepDataReplicationTool::convert3BCtoAllBC()
+StatusCode Muon::TgcPrepDataReplicationTool::convert3BCtoAllBC() const
 {
   // cleanup
   m_tgcPrepDataContainer[BC_ALL]->cleanup();
@@ -226,7 +226,7 @@ StatusCode Muon::TgcPrepDataReplicationTool::convert3BCtoAllBC()
 
 
 Muon::TgcPrepData*
-Muon::TgcPrepDataReplicationTool::makeTgcPrepData(Muon::TgcPrepDataCollection::const_iterator itr, uint16_t bcBitMap)
+Muon::TgcPrepDataReplicationTool::makeTgcPrepData(Muon::TgcPrepDataCollection::const_iterator itr, uint16_t bcBitMap) const
 {
   Identifier channelId = (*itr)->identify();
   IdentifierHash tgcHashId = (*itr)->collectionHash();
@@ -242,18 +242,3 @@ Muon::TgcPrepDataReplicationTool::makeTgcPrepData(Muon::TgcPrepDataCollection::c
 
   return newPrepData;
 }
-
-
-
-
-StatusCode Muon::TgcPrepDataReplicationTool::queryInterface(const InterfaceID& riid, void** ppvIf) {
-  ATH_MSG_DEBUG("queryInterface()");
-  if(ITgcPrepDataReplicationTool::interfaceID().versionMatch(riid)) {
-    *ppvIf = dynamic_cast<ITgcPrepDataReplicationTool*>(this);
-    addRef();
-    ATH_MSG_DEBUG("InterfaceID successfully matched with ITgcPrepDataReplicationTool one.");
-    return StatusCode::SUCCESS;
-  }
-
-  return AthAlgTool::queryInterface(riid, ppvIf);
-}
diff --git a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool.h b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool.h
index 99f0f0dc1db70fcbbdd75a662ef240032d1c3edd..a55f00cb570493fe2fdd3ad8c361d7228d1f8ee5 100644
--- a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool.h
+++ b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool.h
@@ -11,11 +11,12 @@
 
 #include "MuonPrepRawData/TgcPrepDataContainer.h"
 #include "MuonIdHelpers/IMuonIdHelperSvc.h"
+#include "CxxUtils/checker_macros.h"
 
 namespace Muon 
 {
-  class TgcPrepDataReplicationTool 
-    : virtual public ITgcPrepDataReplicationTool, virtual public AthAlgTool
+  class ATLAS_NOT_THREAD_SAFE TgcPrepDataReplicationTool 
+    : public extends<AthAlgTool, ITgcPrepDataReplicationTool>
   {
     public:
       /** Constructor */
@@ -24,17 +25,11 @@ namespace Muon
       /** Destructor */
       virtual ~TgcPrepDataReplicationTool()=default;
 
-      /** Provide InterfaceID */
-      static const InterfaceID& interfaceID() { return ITgcPrepDataReplicationTool::interfaceID(); };
-
-      /** Query interface */
-      virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvIF);
-
-      virtual StatusCode initialize();
-      virtual StatusCode finalize();
-      virtual StatusCode replicate();
-      virtual StatusCode convert3BCtoAllBC();
-      virtual StatusCode convertAllBCto3BC();
+      virtual StatusCode initialize() override;
+      virtual StatusCode finalize() override;
+      virtual StatusCode replicate() const override;
+      virtual StatusCode convert3BCtoAllBC() const;
+      virtual StatusCode convertAllBCto3BC() const;
       
     private:
       enum {BC_PREVIOUS=0, BC_CURRENT, BC_NEXT, BC_ALL, BC_NUM};
@@ -45,7 +40,7 @@ namespace Muon
       TgcPrepDataContainer* m_tgcPrepDataContainer[BC_NUM];
 
       /** Make new TgcPrepData */
-      TgcPrepData* makeTgcPrepData(TgcPrepDataCollection::const_iterator itr, uint16_t bcBitMap);
+      TgcPrepData* makeTgcPrepData(TgcPrepDataCollection::const_iterator itr, uint16_t bcBitMap) const;
 
    }; 
 } // end of namespace
diff --git a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool3BCtoAllBC.cxx b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool3BCtoAllBC.cxx
index 41e840aa2b208cddf36f66af7269064c33c07fbb..d9f1b69a44a35379ab0520d26666c95e6d9dc45b 100644
--- a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool3BCtoAllBC.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool3BCtoAllBC.cxx
@@ -12,7 +12,7 @@
 //================ Constructor =================================================
 Muon::TgcPrepDataReplicationTool3BCtoAllBC::TgcPrepDataReplicationTool3BCtoAllBC 
   (const std::string& t, const std::string& n, const IInterface* p)
-  : AthAlgTool(t, n, p),
+  : base_class(t, n, p),
   m_3BCKeys{"dummy", "dummy", "dummy"},
   m_AllBCKey("TGC_MeasurementsAllBCs")
 {
@@ -40,12 +40,12 @@ StatusCode Muon::TgcPrepDataReplicationTool3BCtoAllBC::initialize()
   return StatusCode::SUCCESS;
 }
 
-StatusCode Muon::TgcPrepDataReplicationTool3BCtoAllBC::replicate()
+StatusCode Muon::TgcPrepDataReplicationTool3BCtoAllBC::replicate() const
 {
     return convert3BCtoAllBC();
 }
 
-StatusCode Muon::TgcPrepDataReplicationTool3BCtoAllBC::convert3BCtoAllBC()
+StatusCode Muon::TgcPrepDataReplicationTool3BCtoAllBC::convert3BCtoAllBC() const
 {
 
   SG::WriteHandle<TgcPrepDataContainer> tgcPrepDataContainerAll(m_AllBCKey);
@@ -107,16 +107,3 @@ StatusCode Muon::TgcPrepDataReplicationTool3BCtoAllBC::convert3BCtoAllBC()
   return StatusCode::SUCCESS;
 }
 
-StatusCode Muon::TgcPrepDataReplicationTool3BCtoAllBC::queryInterface(const InterfaceID& riid, void** ppvIf) {
-  ATH_MSG_DEBUG("queryInterface()");
-  if(ITgcPrepDataReplicationTool::interfaceID().versionMatch(riid)) {
-    *ppvIf = dynamic_cast<ITgcPrepDataReplicationTool*>(this);
-    addRef();
-    ATH_MSG_DEBUG("InterfaceID successfully matched with ITgcPrepDataReplicationTool one.");
-    return StatusCode::SUCCESS;
-  }
-
-  return AthAlgTool::queryInterface(riid, ppvIf);
-}
-
-
diff --git a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool3BCtoAllBC.h b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool3BCtoAllBC.h
index 34d5d3baf7a9e8359dc53e4bfc1cd43eb9f91f85..ef32e05dee3566b2f7a085d0edc1f6b229ef4a57 100644
--- a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool3BCtoAllBC.h
+++ b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationTool3BCtoAllBC.h
@@ -11,11 +11,12 @@
 
 #include "MuonPrepRawData/TgcPrepDataContainer.h"
 #include "MuonIdHelpers/IMuonIdHelperSvc.h"
+#include "CxxUtils/checker_macros.h"
 
 namespace Muon 
 {
-  class TgcPrepDataReplicationTool3BCtoAllBC 
-    : virtual public ITgcPrepDataReplicationTool, virtual public AthAlgTool
+  class ATLAS_NOT_THREAD_SAFE TgcPrepDataReplicationTool3BCtoAllBC 
+    : public extends<AthAlgTool, ITgcPrepDataReplicationTool>
   {
     public:
       /** Constructor */
@@ -24,15 +25,9 @@ namespace Muon
       /** Destructor */
       virtual ~TgcPrepDataReplicationTool3BCtoAllBC()=default;
 
-      /** Provide InterfaceID */
-      static const InterfaceID& interfaceID() { return ITgcPrepDataReplicationTool::interfaceID(); };
-
-      /** Query interface */
-      virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvIF) override;
-
       virtual StatusCode initialize() override;
-      virtual StatusCode replicate() override;
-      StatusCode convert3BCtoAllBC();
+      virtual StatusCode replicate() const override;
+      StatusCode convert3BCtoAllBC() const;
 
       
     private:
diff --git a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationToolAllBCto3BC.cxx b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationToolAllBCto3BC.cxx
index 0a78da92a2feeb0c9b8b12ff68cede13323039e6..5ef5a42173e8fd8e124c83c971b8e22a9c2a4348 100644
--- a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationToolAllBCto3BC.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationToolAllBCto3BC.cxx
@@ -13,7 +13,7 @@
 //================ Constructor =================================================
 Muon::TgcPrepDataReplicationToolAllBCto3BC::TgcPrepDataReplicationToolAllBCto3BC 
   (const std::string& t, const std::string& n, const IInterface* p)
-  : AthAlgTool(t, n, p),
+  : base_class(t, n, p),
   m_3BCKeys{"dummy", "dummy", "dummy"},
   m_AllBCKey("TGC_MeasurementsAllBCs")
 {
@@ -41,12 +41,12 @@ StatusCode Muon::TgcPrepDataReplicationToolAllBCto3BC::initialize()
   return StatusCode::SUCCESS;
 }
 
-StatusCode Muon::TgcPrepDataReplicationToolAllBCto3BC::replicate()
+StatusCode Muon::TgcPrepDataReplicationToolAllBCto3BC::replicate() const
 {
     return convertAllBCto3BC();
 }
 
-StatusCode Muon::TgcPrepDataReplicationToolAllBCto3BC::convertAllBCto3BC()
+StatusCode Muon::TgcPrepDataReplicationToolAllBCto3BC::convertAllBCto3BC() const
 {
 
   SG::ReadHandle<TgcPrepDataContainer> tgcAll(m_AllBCKey);
@@ -118,20 +118,3 @@ Muon::TgcPrepDataReplicationToolAllBCto3BC::makeTgcPrepData(Muon::TgcPrepDataCol
 
   return newPrepData;
 }
-
-
-
-
-StatusCode Muon::TgcPrepDataReplicationToolAllBCto3BC::queryInterface(const InterfaceID& riid, void** ppvIf) {
-  ATH_MSG_DEBUG("queryInterface()");
-  if(ITgcPrepDataReplicationTool::interfaceID().versionMatch(riid)) {
-    *ppvIf = dynamic_cast<ITgcPrepDataReplicationTool*>(this);
-    addRef();
-    ATH_MSG_DEBUG("InterfaceID successfully matched with ITgcPrepDataReplicationTool one.");
-    return StatusCode::SUCCESS;
-  }
-
-  return AthAlgTool::queryInterface(riid, ppvIf);
-}
-
-
diff --git a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationToolAllBCto3BC.h b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationToolAllBCto3BC.h
index a3d6a0efc5a3aaf69ebcbed3fb54761a51eb181b..f2582e8e63ecb5fc7c88be9003aed0e9db3f9ddd 100644
--- a/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationToolAllBCto3BC.h
+++ b/MuonSpectrometer/MuonCnv/MuonTGC_CnvTools/src/TgcPrepDataReplicationToolAllBCto3BC.h
@@ -11,11 +11,12 @@
 
 #include "MuonPrepRawData/TgcPrepDataContainer.h"
 #include "MuonIdHelpers/IMuonIdHelperSvc.h"
+#include "CxxUtils/checker_macros.h"
 
 namespace Muon 
 {
-  class TgcPrepDataReplicationToolAllBCto3BC 
-    : virtual public ITgcPrepDataReplicationTool, virtual public AthAlgTool
+  class ATLAS_NOT_THREAD_SAFE TgcPrepDataReplicationToolAllBCto3BC 
+    : public extends<AthAlgTool, ITgcPrepDataReplicationTool>
   {
     public:
       /** Constructor */
@@ -24,15 +25,9 @@ namespace Muon
       /** Destructor */
       virtual ~TgcPrepDataReplicationToolAllBCto3BC()=default;
 
-      /** Provide InterfaceID */
-      static const InterfaceID& interfaceID() { return ITgcPrepDataReplicationTool::interfaceID(); };
-
-      /** Query interface */
-      virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvIF) override;
-
       virtual StatusCode initialize() override;
-      virtual StatusCode replicate() override;
-      StatusCode convertAllBCto3BC();
+      virtual StatusCode replicate() const override;
+      StatusCode convertAllBCto3BC() const;
       
 /** Make new TgcPrepData */ //Static to avoid code duplication with sister class
       static TgcPrepData* makeTgcPrepData(TgcPrepDataCollection::const_iterator itr, uint16_t bcBitMap);
diff --git a/MuonSpectrometer/MuonDigitization/RPC_Digitization/RPC_Digitization/RpcDigitizationTool.h b/MuonSpectrometer/MuonDigitization/RPC_Digitization/RPC_Digitization/RpcDigitizationTool.h
index 28c41f8fd9a512effebc2c02b1133c54a81d4271..c431c511ba17cff8269f9ed79f89c783ab43f207 100644
--- a/MuonSpectrometer/MuonDigitization/RPC_Digitization/RPC_Digitization/RpcDigitizationTool.h
+++ b/MuonSpectrometer/MuonDigitization/RPC_Digitization/RPC_Digitization/RpcDigitizationTool.h
@@ -134,6 +134,10 @@ private:
       int he gas gap's reference frame. */
   Gaudi::Property<double> m_UncorrJitter {this, "UncorrJitter", 1.5 , "jitter uncorrelated between eta and phi"};
   Gaudi::Property<double> m_CorrJitter   {this, "CorrJitter", 0.0 , "jitter correlated between eta and phi"};
+    
+  Gaudi::Property<double> m_UncorrJitter_BIS78 {this, "UncorrJitter_BIS78", 0.3 , "jitter uncorrelated between eta and phi BIS78"};
+  Gaudi::Property<double> m_CorrJitter_BIS78   {this, "CorrJitter_BIS78",  0.0 , "jitter correlated between eta and phi BIS78"};
+
   Amg::Vector3D posInPanel(const Identifier* id, const Amg::Vector3D posInGap);
   /** adjust strip numbering according to standard OIDs **/
   int adjustStripNumber(const Identifier* id,int nstrip);
@@ -198,6 +202,10 @@ private:
   Gaudi::Property< std::vector<float> > m_OnlyPhiEff_C  {this, "OnlyPhiEff_C"  , {} , ""};
   Gaudi::Property< std::vector<float> > m_OnlyEtaEff_C  {this, "OnlyEtaEff_C"  , {} , ""};
 
+  Gaudi::Property<float> m_PhiAndEtaEff_BIS78 {this, "PhiAndEtaEff_BIS78", 0.93, ""};
+  Gaudi::Property<float> m_OnlyEtaEff_BIS78 {this, "OnlyEtaEff_BIS78", 0.96, ""};
+  Gaudi::Property<float> m_OnlyPhiEff_BIS78 {this, "OnlyPhiEff_BIS78", 0.96, ""};
+ 
   Gaudi::Property< std::vector<double> > m_FracClusterSize1_A   {this, "FracClusterSize1_A"   , {} , ""};
   Gaudi::Property< std::vector<double> > m_FracClusterSize2_A   {this, "FracClusterSize2_A"   , {} , ""};
   Gaudi::Property< std::vector<double> > m_FracClusterSizeTail_A{this, "FracClusterSizeTail_A", {} , ""};
@@ -208,6 +216,11 @@ private:
   Gaudi::Property< std::vector<double> > m_FracClusterSizeTail_C{this, "FracClusterSizeTail_C", {} , ""};
   Gaudi::Property< std::vector<double> > m_MeanClusterSizeTail_C{this, "MeanClusterSizeTail_C", {} , ""};
 
+  Gaudi::Property<float> m_FracClusterSize1_BIS78    {this, "FracClusterSize1_BIS78", 0.60, ""};
+  Gaudi::Property<float> m_FracClusterSize2_BIS78    {this, "FracClusterSize2_BIS78", 0.35, ""};
+  Gaudi::Property<float> m_FracClusterSizeTail_BIS78 {this, "FracClusterSizeTail_BIA78", 0.05, ""};
+  Gaudi::Property<float> m_MeanClusterSizeTail_BIS78 {this, "MeanClusterSizeTail_BIA78", 3.5, ""};
+            
   std::vector<Identifier> m_DeadStripPanel;
 
   bool m_SetPhiOn{false};
@@ -252,6 +265,10 @@ protected:
       "File with Dead panel PanelId list"};
   Gaudi::Property<bool>        m_PanelId_OK_fromlist         {this, "PanelId_OK_fromlist", false,
       "Turn-on PanelId from file m_FileName_GoodPanels"};
+  Gaudi::Property<bool>        m_Efficiency_BIS78_fromCOOL   {this, "Efficiency_BIS78_fromCOOL", false,
+      " read BIS78 Efficiency from COOL DB"};
+  Gaudi::Property<bool>        m_ClusterSize_BIS78_fromCOOL  {this, "ClusterSize_BIS78_fromCOOL", false,
+      " read BIS78 Cluster Size from COOL DB"};  
   Gaudi::Property<std::string> m_FileName_GoodPanels         {this, "FileName_GoodPanels", "PermanentGoodPanels.txt",
       " File with Good panel PanelId list"};
 
diff --git a/MuonSpectrometer/MuonDigitization/RPC_Digitization/src/RpcDigitizationTool.cxx b/MuonSpectrometer/MuonDigitization/RPC_Digitization/src/RpcDigitizationTool.cxx
index 014fba1132d36fced8e3cfa9012cb89b5ac55560..c2907dd54e0296ff19a0fc8a124d0ecd9a0d4daa 100644
--- a/MuonSpectrometer/MuonDigitization/RPC_Digitization/src/RpcDigitizationTool.cxx
+++ b/MuonSpectrometer/MuonDigitization/RPC_Digitization/src/RpcDigitizationTool.cxx
@@ -53,6 +53,7 @@
 #include <atomic>
 #include <TString.h> // for Form
 
+
 //12 charge points, 15 BetaGamma points, 180 efficiency points for fcp search
 namespace {
   constexpr int N_Charge = 12;
@@ -110,8 +111,10 @@ StatusCode RpcDigitizationTool::initialize() {
   ATH_MSG_DEBUG ( "IgnoreRunDependentConfig "<< m_ignoreRunDepConfig       );
   ATH_MSG_DEBUG ( "turnON_efficiency      " <<  m_turnON_efficiency        );
   ATH_MSG_DEBUG ( "Efficiency_fromCOOL    " <<  m_Efficiency_fromCOOL      );
+  ATH_MSG_DEBUG ( "Efficiency_BIS78_fromCOOL"<< m_Efficiency_BIS78_fromCOOL );
   ATH_MSG_DEBUG ( "turnON_clustersize     " <<  m_turnON_clustersize       );
   ATH_MSG_DEBUG ( "ClusterSize_fromCOOL   " <<  m_ClusterSize_fromCOOL     );
+  ATH_MSG_DEBUG ( "ClusterSize_BIS78_fromCOOL"<< m_ClusterSize_BIS78_fromCOOL);
   ATH_MSG_DEBUG ( "testbeam_clustersize   " <<  m_testbeam_clustersize     );
   ATH_MSG_DEBUG ( "FirstClusterSizeInTail " <<  m_FirstClusterSizeInTail   );
   ATH_MSG_DEBUG ( "ClusterSize1_2uncorr   " <<  m_ClusterSize1_2uncorr     );
@@ -140,6 +143,9 @@ StatusCode RpcDigitizationTool::initialize() {
   if(!m_idHelper) {
     return StatusCode::FAILURE;
   }
+ // check the identifiers
+
+ ATH_MSG_INFO("Max Number of RPC Gas Gaps for these Identifiers = " <<  m_idHelper->gasGapMax());
 
   // check the input object name
   if (m_hitsContainerKey.key().empty()) {
@@ -162,7 +168,10 @@ StatusCode RpcDigitizationTool::initialize() {
   IRDBAccessSvc* rdbAccess(nullptr);
   ATH_CHECK(service("RDBAccessSvc",rdbAccess));
 
-  bool run1 = true;
+  
+  enum DataPeriod{Run1,Run2,Run3,Run4};
+  DataPeriod run = Run1;
+  
   std::string configVal = "";
   const IGeoModelSvc* geoModel(nullptr);
   ATH_CHECK(service("GeoModelSvc", geoModel));
@@ -171,7 +180,7 @@ StatusCode RpcDigitizationTool::initialize() {
 
   IRDBRecordset_ptr atlasCommonRec = rdbAccess->getRecordsetPtr("AtlasCommon",atlasVersion,"ATLAS");
   if (atlasCommonRec->size()==0) {
-    run1 = true;
+      run = Run1;
   }
   else {
     configVal = (*atlasCommonRec)[0]->getString("CONFIG");
@@ -179,28 +188,39 @@ StatusCode RpcDigitizationTool::initialize() {
     std::string MSgeoVersion = m_GMmgr->geometryVersion().substr(0,4);
     ATH_MSG_INFO( "From DD Database, MuonSpectrometer geometry version is "<< MSgeoVersion );
     if(configVal=="RUN1" || MSgeoVersion=="R.06"){
-      run1 = true;
+      run = Run1;
     }
-    else if (configVal=="RUN2" || configVal=="RUN3" || MSgeoVersion=="R.07") {
-      run1 = false;
+    else if (configVal=="RUN2" || MSgeoVersion=="R.07" ) {
+        run = Run2;
+    }
+    else if (configVal=="RUN3" || MSgeoVersion=="R.09") {
+        run = Run3;
+    }
+    else if (configVal=="RUN4" || MSgeoVersion=="R.10") {
+        run = Run4;
     }
     else {
-      ATH_MSG_FATAL("Unexpected value for geometry config read from the database: " << configVal);
-      return StatusCode::FAILURE;
+        ATH_MSG_FATAL("Unexpected value for geometry config read from the database: " << configVal << " Geometry version=" << MSgeoVersion);
+        return StatusCode::FAILURE;
     }
   }
+  if ( run==Run3 && m_idHelper->gasGapMax()<3) ATH_MSG_WARNING("Run3,  configVal = " <<configVal<<" and GasGapMax =" <<m_idHelper->gasGapMax());
+  //if ( configVal!="RUN3" && m_idHelper->gasGapMax()==3) ATH_MSG_WARNING("configVal = " <<configVal<<" and GasGapMax =" <<m_idHelper->gasGapMax());
   //
-  if (run1) ATH_MSG_INFO("From Geometry DB: MuonSpectrometer configuration is: RUN1 or MuonGeometry = R.06");
-  else      ATH_MSG_INFO("From Geometry DB: MuonSpectrometer configuration is: RUN2 or MuonGeometry = R.07");
-
-  if (m_ignoreRunDepConfig==false) {
+  
+  if (run==Run1) ATH_MSG_INFO("From Geometry DB: MuonSpectrometer configuration is: RUN1 or MuonGeometry = R.06");
+  else if (run==Run2)  ATH_MSG_INFO("From Geometry DB: MuonSpectrometer configuration is: RUN2 or MuonGeometry = R.07");
+  else if (run==Run3)  ATH_MSG_INFO("From Geometry DB: MuonSpectrometer configuration is: RUN3 or MuonGeometry = R.09");
+  else if (run==Run4)  ATH_MSG_INFO("From Geometry DB: MuonSpectrometer configuration is: RUN4 or MuonGeometry = R.10");
+  
+ if (m_ignoreRunDepConfig==false) {
     m_BOG_BOF_DoubletR2_OFF = false;
     m_Efficiency_fromCOOL   = false;
     m_ClusterSize_fromCOOL  = false;
     m_RPCInfoFromDb         = false;
     m_kill_deadstrips       = false;
     m_applyEffThreshold     = false;
-    if (run1) {
+    if (run==Run1) {
       //m_BOG_BOF_DoubletR2_OFF = true
       //m_Efficiency_fromCOOL   = true
       //m_ClusterSize_fromCOOL  = true
@@ -219,36 +239,36 @@ StatusCode RpcDigitizationTool::initialize() {
       //m_Efficiency_fromCOOL   = false # use common average values in python conf.
       //m_ClusterSize_fromCOOL  = false # use common average values in python conf.
       m_BOG_BOF_DoubletR2_OFF = false;
-      if (configVal=="RUN2" || configVal=="RUN3") {// MC15c setup
+      if (run==Run2) {// MC15c setup
         m_Efficiency_fromCOOL   = true;
         m_ClusterSize_fromCOOL  = true;
         m_RPCInfoFromDb         = true;
         m_kill_deadstrips       = false;
         m_applyEffThreshold     = false; //for MC16 [2015-2016]IoV will use measurements, [2017]IoV will use measurements with threshold at 50% already applied in the condition data ////// it was true (with threshold 50%) for MC15c;
         m_CutProjectedTracks    = 100;
-      }
+      } else {
+        ATH_MSG_INFO ( "Run3/4: configuration parameter not from COOL" );
+        m_Efficiency_fromCOOL   = false;
+        m_ClusterSize_fromCOOL  = false;
+        m_RPCInfoFromDb         = false;
+        m_kill_deadstrips       = false;
+        m_applyEffThreshold     = false;          
+      } 
     }
-    ATH_MSG_DEBUG ( "Run1/Run2-dependent configuration is enforced; option setting reset for: " );
-    ATH_MSG_DEBUG ( "......Efficiency_fromCOOL    " <<  m_Efficiency_fromCOOL      );
-    ATH_MSG_DEBUG ( "......ClusterSize_fromCOOL   " <<  m_ClusterSize_fromCOOL     );
-    ATH_MSG_DEBUG ( "......BOG_BOF_DoubletR2_OFF  " <<  m_BOG_BOF_DoubletR2_OFF    );
-    ATH_MSG_DEBUG ( "......RPCInfoFromDb          " <<  m_RPCInfoFromDb            );
-    ATH_MSG_DEBUG ( "......KillDeadStrips         " <<  m_kill_deadstrips          );
-    ATH_MSG_DEBUG ( "......ApplyEffThreshold      " <<  m_applyEffThreshold        );
-    ATH_MSG_DEBUG ( "......CutProjectedTracks     " <<  m_CutProjectedTracks       );
+    ATH_MSG_INFO ( "RPC Run1/2/3-dependent configuration is enforced" );
   }
   else {
-    ATH_MSG_WARNING ( "Run1/Run2-dependent configuration is bypassed; be careful with option settings" );
-    ATH_MSG_DEBUG ( "......Efficiency_fromCOOL    " <<  m_Efficiency_fromCOOL      );
-    ATH_MSG_DEBUG ( "......ClusterSize_fromCOOL   " <<  m_ClusterSize_fromCOOL     );
-    ATH_MSG_DEBUG ( "......BOG_BOF_DoubletR2_OFF  " <<  m_BOG_BOF_DoubletR2_OFF    );
-    ATH_MSG_DEBUG ( "......RPCInfoFromDb          " <<  m_RPCInfoFromDb            );
-    ATH_MSG_DEBUG ( "......KillDeadStrips         " <<  m_kill_deadstrips          );
-    ATH_MSG_DEBUG ( "......ApplyEffThreshold      " <<  m_applyEffThreshold        );
-    ATH_MSG_DEBUG ( "......CutProjectedTracks     " <<  m_CutProjectedTracks       );
+    ATH_MSG_WARNING ( "Run1/2/3-dependent configuration is bypassed; be careful with option settings" );
   }
 
-
+    ATH_MSG_DEBUG ( "......RPC Efficiency_fromCOOL    " <<  m_Efficiency_fromCOOL      );
+    ATH_MSG_DEBUG ( "......RPC ClusterSize_fromCOOL   " <<  m_ClusterSize_fromCOOL     );
+    ATH_MSG_DEBUG ( "......RPC BOG_BOF_DoubletR2_OFF  " <<  m_BOG_BOF_DoubletR2_OFF    );
+    ATH_MSG_DEBUG ( "......RPC RPCInfoFromDb          " <<  m_RPCInfoFromDb            );
+    ATH_MSG_DEBUG ( "......RPC KillDeadStrips         " <<  m_kill_deadstrips          );
+    ATH_MSG_DEBUG ( "......RPC ApplyEffThreshold      " <<  m_applyEffThreshold        );
+    ATH_MSG_DEBUG ( "......RPC CutProjectedTracks     " <<  m_CutProjectedTracks       );
+ 
   ATH_MSG_DEBUG ( "Ready to read parameters for cluster simulation from file" );
 
   ATH_CHECK(readParameters());
@@ -271,7 +291,7 @@ StatusCode RpcDigitizationTool::initialize() {
 
   m_DeadStripPanel.clear();
 
-  //////////////////// special test
+  ///////////////////// special test
   //  m_turnON_clustersize=false;
   m_BOF_id = m_idHelper->stationNameIndex("BOF");
   m_BOG_id = m_idHelper->stationNameIndex("BOG");
@@ -569,6 +589,7 @@ StatusCode RpcDigitizationTool::doDigitization(const EventContext& ctx, RpcDigit
       int         gasGap      = m_muonHelper->GetGasGapLayer(idHit);
       int         measphi     = m_muonHelper->GetMeasuresPhi(idHit);
 
+
       if( measphi!=0 ) continue; //Skip phi strip . To be created after efficiency evaluation
 
       //construct Atlas identifier from components
@@ -581,30 +602,35 @@ StatusCode RpcDigitizationTool::doDigitization(const EventContext& ctx, RpcDigit
 		      << " doubletPhi "   <<    doubletPhi
 		      << " gasGap "	 <<    gasGap
 		      << " measphi "	 <<    measphi );//
-
- 	    if (doubletZ>m_idHelper->doubletZMax()) {
+      
+	    if (doubletZ>m_idHelper->doubletZMax()) {
 	      ATH_MSG_WARNING("doubletZ retrieved from RpcHitIdHelper ("<<doubletZ<<") larger than doubletZMax="<<m_idHelper->doubletZMax()<<" for stationName="<<stationName<<", stationEta="<<stationEta<<", doubletPhi="<<doubletPhi<<", continuing...");
 	      continue;
 	    }
-
-      const Identifier idpaneleta = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR, doubletZ, doubletPhi,gasGap, 0, 1);
-      const Identifier idpanelphi = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR, doubletZ, doubletPhi,gasGap, 1, 1);
+      
+      const Identifier idpaneleta = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR,
+                                                          doubletZ, doubletPhi,gasGap, 0, 1);
+      const Identifier idpanelphi = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR,
+                                                          doubletZ, doubletPhi,gasGap, 1, 1);
 
       //loop on eta and phi to apply correlated efficiency between the two views
       //      Identifier atlasRpcId;
       //      Identifier atlasRpcIdphi;
       
       double corrtimejitter    =  0 ;
-      if(m_CorrJitter>0.01) corrtimejitter    = CLHEP::RandGaussZiggurat::shoot(rndmEngine,0.,m_CorrJitter); //correlated jitter
+      double tmp_CorrJitter = m_CorrJitter;
+      if (m_idHelper->stationName(idpaneleta)<2) tmp_CorrJitter = m_CorrJitter_BIS78;
+      if(tmp_CorrJitter>0.01) corrtimejitter    = CLHEP::RandGaussZiggurat::shoot(rndmEngine,0.,tmp_CorrJitter); //correlated jitter
+      //      std::cout<<" Correlated eta / phi jitter = "<<corrtimejitter<<std::endl;
       // handle here the special case where eta panel is dead => phi strip status (dead or eff.) cannot be resolved; 
       // measured panel eff. will be used in that case and no phi strip killing will happen
       bool undefPhiStripStat = false;
 
-      std::vector<int> pcseta = PhysicalClusterSize(ctx, &idpaneleta, &hit, rndmEngine); //set to one for new algorithms
+      std::vector<int> pcseta    = PhysicalClusterSize(ctx, &idpaneleta, &hit, rndmEngine); //set to one for new algorithms
       ATH_MSG_DEBUG ( "Simulated cluster on eta panel: size/first/last= "<<pcseta[0]   <<"/"<<pcseta[1]   <<"/"<<pcseta[2] );
       std::vector<int> pcsphi = PhysicalClusterSize(ctx, &idpanelphi, &hit, rndmEngine); //set to one for new algorithms
       ATH_MSG_DEBUG ( "Simulated cluster on phi panel: size/first/last= "<<pcsphi[0]<<"/"<<pcsphi[1]<<"/"<<pcsphi[2] );
-      
+
       // create Identifiers
       Identifier atlasRpcIdeta = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR,
                                                        doubletZ, doubletPhi,gasGap, 0, pcseta[1] );
@@ -615,18 +641,8 @@ StatusCode RpcDigitizationTool::doDigitization(const EventContext& ctx, RpcDigit
       const EBC_EVCOLL evColl = EBC_MAINEVCOLL;
       const HepMcParticleLink::PositionFlag idxFlag = (phit.eventId()==0) ? HepMcParticleLink::IS_POSITION: HepMcParticleLink::IS_INDEX;
       const HepMcParticleLink particleLink(phit->trackNumber(),phit.eventId(),evColl,idxFlag);
-
-      // as long there is no proper implementation of the BI RPC cabling and digitisation,
-      // skip this method to avoid hard crash of digitisation
-      static std::atomic<bool> biWarningPrinted = false;
-      if (stationName.find("BI")!=std::string::npos) {
-        if (!biWarningPrinted) {
-          ATH_MSG_WARNING("skipping call of RPC DetectionEfficiency for BI as long as no proper cabling is implemented, cf. ATLASRECTS-5803");
-          biWarningPrinted.store(true, std::memory_order_relaxed);
-        }
-      } else {
-        ATH_CHECK(DetectionEfficiency(ctx, &atlasRpcIdeta,&atlasRpcIdphi, undefPhiStripStat, rndmEngine, particleLink));
-      }
+      
+      ATH_CHECK(DetectionEfficiency(ctx, &atlasRpcIdeta,&atlasRpcIdphi, undefPhiStripStat, rndmEngine, particleLink));
 
       ATH_MSG_DEBUG ( "SetPhiOn " << m_SetPhiOn << " SetEtaOn " <<  m_SetEtaOn );
 
@@ -738,16 +754,17 @@ StatusCode RpcDigitizationTool::doDigitization(const EventContext& ctx, RpcDigit
 	      }
 	  }
 
-    if(!m_idHelper->valid(newId)){
-      if (stationName.find("BI")!=std::string::npos) {
-        ATH_MSG_WARNING("Temporary skipping creation of RPC digit for stationName="<<stationName<<", eta="<<stationEta<<", phi="<<stationPhi<<", doubletR="<<doubletR<<", doubletZ="<<doubletZ<<", doubletPhi="<<doubletPhi<<", gasGap="<<gasGap<<", measuresPhi="<<imeasphi<<", strip="<<clus<<", cf. ATLASRECTS-6124");
-        return StatusCode::SUCCESS;
-      } else {
-        ATH_MSG_ERROR( "Created an invalid id, aborting!");
-        m_idHelper->print(newId);
-        return StatusCode::FAILURE;
-      }
-    }
+
+          if(!m_idHelper->valid(newId)){
+              if (stationName.find("BI")!=std::string::npos) {
+                  ATH_MSG_WARNING("Temporary skipping creation of RPC digit for stationName="<<stationName<<", eta="<<stationEta<<", phi="<<stationPhi<<", doubletR="<<doubletR<<", doubletZ="<<doubletZ<<", doubletPhi="<<doubletPhi<<", gasGap="<<gasGap<<", measuresPhi="<<imeasphi<<", strip="<<clus<<", cf. ATLASRECTS-6124");
+                  return StatusCode::SUCCESS;
+              } else {
+                  ATH_MSG_ERROR( "Created an invalid id, aborting!");
+                  m_idHelper->print(newId);
+                  return StatusCode::FAILURE;
+              }
+          }
 
 	  ///////////////////////////////////////////////////////////////////
 	  /////////////// TEMP, waiting for Reco to learn using clusters...
@@ -846,7 +863,9 @@ StatusCode RpcDigitizationTool::doDigitization(const EventContext& ctx, RpcDigit
 
 	  // first add time jitter to the time:
           double uncorrjitter    = 0 ;
-	  if(m_UncorrJitter>0.01) uncorrjitter = CLHEP::RandGaussZiggurat::shoot(rndmEngine,0.,m_UncorrJitter);
+          double tmp_UncorrJitter = m_UncorrJitter;
+          if (m_idHelper->stationName(theId)<2) tmp_UncorrJitter = m_UncorrJitter_BIS78;
+	  if(tmp_UncorrJitter>0.01) uncorrjitter = CLHEP::RandGaussZiggurat::shoot(rndmEngine,0.,tmp_UncorrJitter);
 	  //	  std::cout<<" uncorrelated jitter = "<<uncorrjitter<<std::endl;
 
 	  //Historically patch for the cavern background
@@ -895,8 +914,8 @@ StatusCode RpcDigitizationTool::doDigitization(const EventContext& ctx, RpcDigit
 	  //std::cout << "Digit Id = " << m_idHelper->show_to_string(theId)<<" digit time "<<newDigit_time << std::endl;
 
 	  // put new collection in storegate
-	  const RpcDigitCollection* coll = digitContainer->indexFindPtr(coll_hash);
-	  if (nullptr ==  coll) {
+          const RpcDigitCollection* coll = digitContainer->indexFindPtr(coll_hash);
+          if (nullptr == coll) {
 	    digitCollection = new RpcDigitCollection(elemId,coll_hash);
 	    digitCollection->push_back(newDigit);
 	    StatusCode status = digitContainer->addCollection(digitCollection, coll_hash);
@@ -930,7 +949,7 @@ StatusCode RpcDigitizationTool::doDigitization(const EventContext& ctx, RpcDigit
 		  deposits.push_back((*map_dep_iter).second);
 		  std::pair<std::map<Identifier,MuonSimData>::iterator, bool> insertResult =
 		    sdoContainer->insert(std::make_pair( theId, MuonSimData(deposits,0) ) );
-		  if (!insertResult.second) ATH_MSG_ERROR("Attention: this sdo is not recorded, since the identifier already exists in the sdoContainer map");
+		  if (!insertResult.second) ATH_MSG_ERROR("Attention: this sdo is not recorded, since teh identifier already exists in the sdoContainer map");
 		}
 	    }
 
@@ -951,12 +970,16 @@ StatusCode RpcDigitizationTool::doDigitization(const EventContext& ctx, RpcDigit
 std::vector<int> RpcDigitizationTool::PhysicalClusterSize(const EventContext& ctx, const Identifier* id, const RPCSimHit* theHit, CLHEP::HepRandomEngine* rndmEngine)
 {
 
+
   int stationEta  = m_idHelper->stationEta(*id);
   float pitch;
   int measuresPhi = m_idHelper->measuresPhi(*id);
   std::vector<int> result(3,0);
 
+
+
   const RpcReadoutElement* ele= m_GMmgr->getRpcReadoutElement(*id);
+
   if (!ele) throw std::runtime_error(Form("File: %s, Line: %d\nRpcDigitizationTool::PhysicalClusterSize() - Could not retrieve RpcReadoutElement for stationName=%d (%s), stationEta=%d, stationPhi=%d, doubletZ=%d, doubletR=%d, doubletPhi=%d, gasGap=%d", 
                                           __FILE__, __LINE__, m_idHelper->stationName(*id), m_idHelper->stationNameString(m_idHelper->stationName(*id)).c_str(),
                                           m_idHelper->stationEta(*id), m_idHelper->stationPhi(*id), m_idHelper->doubletZ(*id), m_idHelper->doubletR(*id), m_idHelper->doubletPhi(*id), m_idHelper->gasGap(*id)));
@@ -975,6 +998,8 @@ std::vector<int> RpcDigitizationTool::PhysicalClusterSize(const EventContext& ct
 
   xstrip=xstrip*30./pitch;
 
+  //std::cout <<"xstrip "<< xstrip/30. << std::endl;
+
   cs1[0]=cs[0];
   cs2[0]=0;
 
@@ -1075,7 +1100,7 @@ std::vector<int> RpcDigitizationTool::PhysicalClusterSize(const EventContext& ct
   else{
 
     float xstripnorm=xstrip/30.;
-    result[0] = ClusterSizeEvaluation(ctx, id, xstripnorm, rndmEngine);
+    result[0] = ClusterSizeEvaluation(ctx, id, xstripnorm, rndmEngine );
 
     int nstrips = ele->Nstrips(measuresPhi);
     //
@@ -1100,8 +1125,12 @@ std::vector<int> RpcDigitizationTool::TurnOnStrips(std::vector<int> pcs, const I
   int nstrips;
   int measuresPhi = m_idHelper->measuresPhi(*id);
 
+
+
   const RpcReadoutElement* ele= m_GMmgr->getRpcReadoutElement(*id);
 
+
+  
   nstrips = ele->Nstrips(measuresPhi);
 
   //testbeam algorithm
@@ -1383,6 +1412,7 @@ int RpcDigitizationTool::findStripNumber(Amg::Vector3D posInGap, Identifier digi
 
   Amg::Vector3D posInElement=ele->SDtoModuleCoords(posInGap, digitId);
 
+
   // extract from digit id the relevant info
 
   int measuresPhi = m_idHelper->measuresPhi(digitId);
@@ -1415,16 +1445,17 @@ int RpcDigitizationTool::findStripNumber(Amg::Vector3D posInGap, Identifier digi
     ATH_MSG_WARNING("lastPos determination failed. "<<exc.what());
   }
 
+
   double start, stop, impact;
   double pitch = ele->StripPitch(measuresPhi);
   double dead=pitch-stripWidth;
 
   if(measuresPhi){
-    impact =  (posInElement.y());
+    impact =  (posInElement.y()); 
     start  =  (firstPos.y());
     stop   =  (lastPos.y());
   } else {
-    impact =  (posInElement.z());
+    impact =  (posInElement.z()); 
     start  =  (firstPos.z());
     stop   =  (lastPos.z());
   }
@@ -1688,34 +1719,38 @@ StatusCode RpcDigitizationTool::DetectionEfficiency(const EventContext& ctx, con
   int stripetagood = 0 ;
   int stripphigood = 0 ;
 
-  if(!m_Efficiency_fromCOOL){
-    unsigned int index = stationName - 2 ;
-    // BML and BMS, BOL and BOS  come first (stationName= 2 and 3, 4 and 5 -> index 0-3)
-    if(stationName>m_BOS_id && stationName<m_CSS_id) index = index - 2 ;
-    // BMF, BOF and BOG are 8,9,10 => must be 4,5 and 6
-    else if(stationName>m_CSS_id) index = index - 44 ;
-    // BME and BOE 53 and 54 are at indices 7 and 8 
-
-    if( index>m_PhiAndEtaEff_A.size() || index>m_OnlyEtaEff_A.size() || index>m_OnlyPhiEff_A.size()) {
-      ATH_MSG_ERROR ( "Index out of array in Detection Efficiency SideA " << index <<" stationName = "<<stationName) ;
-      return StatusCode::FAILURE;
-    }
-
-    PhiAndEtaEff = m_PhiAndEtaEff_A [index];
-    OnlyEtaEff   = m_OnlyEtaEff_A   [index];
-    OnlyPhiEff   = m_OnlyPhiEff_A   [index];
-
-    if(stationEta<0){
-      if( index>m_PhiAndEtaEff_C.size() || index>m_OnlyEtaEff_C.size() || index>m_OnlyPhiEff_C.size()) {
-	ATH_MSG_ERROR ( "Index out of array in Detection Efficiency SideC " << index <<" stationName = "<<stationName) ;
-	return StatusCode::FAILURE;
-      }
-      PhiAndEtaEff = m_PhiAndEtaEff_C [index];
-      OnlyEtaEff   = m_OnlyEtaEff_C   [index];
-      OnlyPhiEff   = m_OnlyPhiEff_C   [index];
-    }
-  }
-  else{
+  unsigned int index = stationName - 2 ;
+  // BML and BMS, BOL and BOS  come first (stationName= 2 and 3, 4 and 5 -> index 0-3)
+  if(stationName>5 && stationName<50) index = index - 2 ;
+  // BMF, BOF and BOG are 8,9,10 => must be 4,5 and 6
+  else if(stationName>50) index = index - 44 ;
+  // BME and BOE 53 and 54 are at indices 7 and 8 
+  
+  
+  if(!m_Efficiency_fromCOOL && stationName >= 2){
+          if( index>m_PhiAndEtaEff_A.size() || index>m_OnlyEtaEff_A.size() || index>m_OnlyPhiEff_A.size()) {
+              ATH_MSG_ERROR ( "Index out of array in Detection Efficiency SideA " << index <<" stationName = "<<stationName) ;
+              return StatusCode::FAILURE;
+          }
+          
+          PhiAndEtaEff = m_PhiAndEtaEff_A [index];
+          OnlyEtaEff   = m_OnlyEtaEff_A   [index];
+          OnlyPhiEff   = m_OnlyPhiEff_A   [index];
+          
+          if(stationEta<0){
+              if( index>m_PhiAndEtaEff_C.size() || index>m_OnlyEtaEff_C.size() || index>m_OnlyPhiEff_C.size()) {
+                  ATH_MSG_ERROR ( "Index out of array in Detection Efficiency SideC " << index <<" stationName = "<<stationName) ;
+                  return StatusCode::FAILURE;
+              }
+              PhiAndEtaEff = m_PhiAndEtaEff_C [index];
+              OnlyEtaEff   = m_OnlyEtaEff_C   [index];
+              OnlyPhiEff   = m_OnlyPhiEff_C   [index];
+          }
+  } else if ( stationName < 2 && (!m_Efficiency_fromCOOL || !m_Efficiency_BIS78_fromCOOL) ) { // BIS
+          PhiAndEtaEff = m_PhiAndEtaEff_BIS78;
+          OnlyEtaEff   = m_OnlyEtaEff_BIS78;
+          OnlyPhiEff   = m_OnlyPhiEff_BIS78;
+  } else { // Efficiency from Cool
 
     SG::ReadCondHandle<RpcCondDbData> readHandle{m_readKey, ctx};
     const RpcCondDbData* readCdo{*readHandle};
@@ -1731,29 +1766,25 @@ StatusCode RpcDigitizationTool::DetectionEfficiency(const EventContext& ctx, con
     float  FracDeadStripEta        = 0. ;
     float  FracDeadStripPhi        = 0. ;
     int    RPC_ProjectedTracksEta  = 0  ;
-    double EtaPanelEfficiency      = 0. ;
-    double PhiPanelEfficiency      = 0. ;
-    double GapEfficiency           = 0. ;
+    double EtaPanelEfficiency      = 1. ;
+    double PhiPanelEfficiency      = 1. ;
+    double GapEfficiency           = 1. ;
 
     bool noEntryInDb=false;
     
     if( readCdo->getFracDeadStripMap()  .find(IdEta) == readCdo->getFracDeadStripMap()  .end()){
-      ATH_MSG_DEBUG ( "Not In CoolDB the Panel IdEtaRpcStrip :  "  << IdEta << " i.e. "<<m_idHelper->show_to_string(IdEta));
-      noEntryInDb=true;      
-    }
-    else
-      {
+        ATH_MSG_DEBUG ( "Not In CoolDB the Panel IdEtaRpcStrip :  "  << IdEta << " i.e. "<<m_idHelper->show_to_string(IdEta));
+        noEntryInDb=true;      
+    } else {
 	ATH_MSG_DEBUG ( "Found In CoolDB the Panel IdEtaRpcStrip :  "  << IdEta << " i.e. "<<m_idHelper->show_to_string(IdEta));
-      }
+    }
     if( readCdo->getFracDeadStripMap()  .find(IdPhi) == readCdo->getFracDeadStripMap()  .end()) {
-      ATH_MSG_DEBUG ( "Not In CoolDB the Panel IdPhiRpcStrip :  "  << IdPhi << " i.e. "<<m_idHelper->show_to_string(IdPhi));
-      noEntryInDb=true;
+        ATH_MSG_DEBUG ( "Not In CoolDB the Panel IdPhiRpcStrip :  "  << IdPhi << " i.e. "<<m_idHelper->show_to_string(IdPhi));
+        noEntryInDb=true;
+    } else {
+        ATH_MSG_DEBUG ( "Found In CoolDB the Panel IdPhiRpcStrip :  "  << IdPhi << " i.e. "<<m_idHelper->show_to_string(IdPhi));
     }
-    else
-      {
-	ATH_MSG_DEBUG ( "Found In CoolDB the Panel IdPhiRpcStrip :  "  << IdPhi << " i.e. "<<m_idHelper->show_to_string(IdPhi));
-      }
- 
+    
     if( readCdo->getFracDeadStripMap()  .find(IdEta) != readCdo->getFracDeadStripMap()  .end()) FracDeadStripEta        = readCdo->getFracDeadStripMap().find(IdEta)->second ;
     if( readCdo->getFracDeadStripMap()  .find(IdPhi) != readCdo->getFracDeadStripMap()  .end()) FracDeadStripPhi        = readCdo->getFracDeadStripMap().find(IdPhi)->second ;
     if( readCdo->getProjectedTracksMap().find(IdEta) != readCdo->getProjectedTracksMap().end()) RPC_ProjectedTracksEta  = readCdo->getProjectedTracksMap().find(IdEta)->second ;
@@ -1765,14 +1796,14 @@ StatusCode RpcDigitizationTool::DetectionEfficiency(const EventContext& ctx, con
     if (std::abs(FracDeadStripEta-1.)<0.001) 
       {
 	ATH_MSG_DEBUG ("Watch out: SPECIAL CASE: Read from Cool: FracDeadStripEta/Phi "<<FracDeadStripEta<<"/"<<FracDeadStripPhi
-			 <<" RPC_ProjectedTracksEta "<<RPC_ProjectedTracksEta<<" Eta/PhiPanelEfficiency "<<EtaPanelEfficiency<<"/"<<PhiPanelEfficiency
-			 <<" gapEff "<<GapEfficiency<<" for gas gap "<<m_idHelper->show_to_string(IdEta)<<" id "<<IdEta.get_identifier32().get_compact());
+                       <<" RPC_ProjectedTracksEta "<<RPC_ProjectedTracksEta<<" Eta/PhiPanelEfficiency "<<EtaPanelEfficiency<<"/"<<PhiPanelEfficiency
+                       <<" gapEff "<<GapEfficiency<<" for gas gap "<<m_idHelper->show_to_string(IdEta)<<" id "<<IdEta.get_identifier32().get_compact());
 	// dead eta panel => cannot determine the strip status for phi strips 
 	// FracDeadStripPhi must be reset to 0. and undefinedPhiStripStatus = true
 	FracDeadStripPhi = 0.;
 	undefinedPhiStripStatus = true;
 	ATH_MSG_VERBOSE ("Watch out: SPECIAL CASE: Resetting FracDeadStripPhi "<<FracDeadStripPhi<<" ignoring phi dead strips ");
-      }
+    }
 
 
     // special test 
@@ -1784,14 +1815,14 @@ StatusCode RpcDigitizationTool::DetectionEfficiency(const EventContext& ctx, con
     ATH_MSG_DEBUG ("Read from Cool: FracDeadStripEta/Phi "<<FracDeadStripEta<<"/"<<FracDeadStripPhi<<" RPC_ProjectedTracksEta "<<RPC_ProjectedTracksEta<<" Eta/PhiPanelEfficiency "<<EtaPanelEfficiency<<"/"<<PhiPanelEfficiency<<" gapEff "<<GapEfficiency);
     //if ((1.-FracDeadStripEta)<EtaPanelEfficiency) 
     if ((maxGeomEff-FracDeadStripEta)-EtaPanelEfficiency<-0.011) 
-      {
-	  ATH_MSG_DEBUG("Ineff. from dead strips on Eta Panel larger that measured efficiency: deadFrac="<<FracDeadStripEta<<" Panel Eff="<<EtaPanelEfficiency<<" for Panel "<<m_idHelper->show_to_string(IdEta));
-	  ATH_MSG_DEBUG("... see the corresponding report from RpcDetectorStatusDbTool");
+    {
+        ATH_MSG_DEBUG("Ineff. from dead strips on Eta Panel larger that measured efficiency: deadFrac="<<FracDeadStripEta<<" Panel Eff="<<EtaPanelEfficiency<<" for Panel "<<m_idHelper->show_to_string(IdEta));
+        ATH_MSG_DEBUG("... see the corresponding report from RpcDetectorStatusDbTool");
 	//EtaPanelEfficiency = 1.-FracDeadStripEta;	
 	EtaPanelEfficiency = maxGeomEff-FracDeadStripEta;	
 	changing = true;
-      }
-      //if ((1.-FracDeadStripPhi)<PhiPanelEfficiency) 
+    }
+    //if ((1.-FracDeadStripPhi)<PhiPanelEfficiency) 
     if ((maxGeomEff-FracDeadStripPhi)-PhiPanelEfficiency<-0.011) 
     {
       ATH_MSG_DEBUG("Ineff. from dead strips on Phi Panel larger that measured efficiency: deadFrac="<<FracDeadStripPhi<<" Panel Eff="<<PhiPanelEfficiency<<" for Panel "<<m_idHelper->show_to_string(IdPhi));
@@ -1834,21 +1865,21 @@ StatusCode RpcDigitizationTool::DetectionEfficiency(const EventContext& ctx, con
 
     //gabriele //..stefania - if there are dead strips renormalize the eff. to the active area  
     if(m_kill_deadstrips){
-     if ((FracDeadStripEta>0.0&&FracDeadStripEta<1.0) || (FracDeadStripPhi>0.0&&FracDeadStripPhi<1.0) || (noEntryInDb))
-    {
-      EtaPanelEfficiency= EtaPanelEfficiency/(maxGeomEff-FracDeadStripEta);
-      PhiPanelEfficiency= PhiPanelEfficiency/(maxGeomEff-FracDeadStripPhi);
-      GapEfficiency     = GapEfficiency/(maxGeomEff-FracDeadStripEta*FracDeadStripPhi);
-
-      if (EtaPanelEfficiency>maxGeomEff) EtaPanelEfficiency=maxGeomEff;
-      if (PhiPanelEfficiency>maxGeomEff) PhiPanelEfficiency=maxGeomEff;
-      if (GapEfficiency     >maxGeomEff) GapEfficiency     =maxGeomEff;
-
-
-      if (EtaPanelEfficiency>GapEfficiency) GapEfficiency=EtaPanelEfficiency;
-      if (PhiPanelEfficiency>GapEfficiency) GapEfficiency=PhiPanelEfficiency;
-      ATH_MSG_DEBUG ("Eff Redefined (to correct for deadfrac): FracDeadStripEta/Phi "<<" Eta/PhiPanelEfficiency "<<EtaPanelEfficiency<<"/"<<PhiPanelEfficiency<<" gapEff "<<GapEfficiency);
-    }
+      if ((FracDeadStripEta>0.0&&FracDeadStripEta<1.0) || (FracDeadStripPhi>0.0&&FracDeadStripPhi<1.0) || (noEntryInDb))
+      {   
+          EtaPanelEfficiency= EtaPanelEfficiency/(maxGeomEff-FracDeadStripEta);
+          PhiPanelEfficiency= PhiPanelEfficiency/(maxGeomEff-FracDeadStripPhi);
+          GapEfficiency     = GapEfficiency/(maxGeomEff-FracDeadStripEta*FracDeadStripPhi);
+          
+          if (EtaPanelEfficiency>maxGeomEff) EtaPanelEfficiency=maxGeomEff;
+          if (PhiPanelEfficiency>maxGeomEff) PhiPanelEfficiency=maxGeomEff;
+          if (GapEfficiency     >maxGeomEff) GapEfficiency     =maxGeomEff;
+          
+          
+          if (EtaPanelEfficiency>GapEfficiency) GapEfficiency=EtaPanelEfficiency;
+          if (PhiPanelEfficiency>GapEfficiency) GapEfficiency=PhiPanelEfficiency;
+          ATH_MSG_DEBUG ("Eff Redefined (to correct for deadfrac): FracDeadStripEta/Phi "<<" Eta/PhiPanelEfficiency "<<EtaPanelEfficiency<<"/"<<PhiPanelEfficiency<<" gapEff "<<GapEfficiency);
+      }
     }				    
 
     //values from COOLDB (eventually overwritten later)
@@ -1890,7 +1921,8 @@ StatusCode RpcDigitizationTool::DetectionEfficiency(const EventContext& ctx, con
     //if projected tracks number too low or inconsistent values get efficiencies from joboption and overwrite previous values
     if(applySpecialPatch || RPC_ProjectedTracksEta<m_CutProjectedTracks || RPC_ProjectedTracksEta>10000000 || EtaPanelEfficiency>1 || EtaPanelEfficiency<0 || PhiPanelEfficiency>1 || PhiPanelEfficiency<0|| GapEfficiency>1 || GapEfficiency<0 || stripetagood == 1 || stripphigood == 1){
 
-      //std::cout<<" do we ever enter here ? "<<std::endl;
+        /*
+        //std::cout<<" do we ever enter here ? "<<std::endl;
       unsigned int index = stationName - 2 ;
       // BML and BMS, BOL and BOS  come first (stationName= 2 and 3, 4 and 5 -> index 0-3)
       if(stationName>m_BOS_id && stationName<m_CSS_id) index = index - 2 ;
@@ -1898,7 +1930,7 @@ StatusCode RpcDigitizationTool::DetectionEfficiency(const EventContext& ctx, con
       else if(stationName>m_BOS_id) index = index - 44 ;
       // BME and BOE 53 and 54 are at indices 7 and 8 
       ATH_MSG_DEBUG ( "Some special condition met here - resetting eff.s to python values at index=" << index << " i.e. StName="<<stationName) ;
-
+        */
       if( index>m_PhiAndEtaEff_A.size() || index>m_OnlyEtaEff_A.size() || index>m_OnlyPhiEff_A.size()) {
 	ATH_MSG_ERROR ( "Index out of array in Detection Efficiency SideA COOLDB" << index <<" stationName = "<<stationName) ;
 	return StatusCode::FAILURE;
@@ -1966,7 +1998,7 @@ StatusCode RpcDigitizationTool::DetectionEfficiency(const EventContext& ctx, con
       */
     }
 
-  }
+  }// End eff from COOL
 
 
   if (m_applyEffThreshold) {
@@ -2055,211 +2087,182 @@ StatusCode RpcDigitizationTool::DetectionEfficiency(const EventContext& ctx, con
 //--------------------------------------------
 int RpcDigitizationTool::ClusterSizeEvaluation(const EventContext& ctx, const Identifier* IdRpcStrip, float xstripnorm, CLHEP::HepRandomEngine* rndmEngine) {
 
-  ATH_MSG_DEBUG ( "RpcDigitizationTool::in ClusterSizeEvaluation" );
-
-  ATH_MSG_DEBUG ( "Digit Id = " << m_idHelper->show_to_string(*IdRpcStrip)  );
+    ATH_MSG_DEBUG ( "RpcDigitizationTool::in ClusterSizeEvaluation" );
 
-  if (IdRpcStrip==0) return 1;
-
-  int ClusterSize = 1 ;
-
-  float FracClusterSize1    = 1.00 ;
-  float FracClusterSize2    = 0.00 ;
-  float MeanClusterSize     = 1.50 ;
-  float FracClusterSizeTail = 0.00 ;
-  float MeanClusterSizeTail = 1.00 ;
-  // float FracClusterSize1norm  = 1  ; // not used
-  float FracClusterSize2norm  = 0  ;
-
-  //2=BML,3=BMS,4=BOL,5=BOS,8=BMF,9=BOF,10=BOG
-  int stationName  = m_idHelper->stationName(*IdRpcStrip);
-  int stationEta   = m_idHelper->stationEta (*IdRpcStrip);
-  int measuresPhi  = m_idHelper->measuresPhi(*IdRpcStrip);
-
-  unsigned int index = stationName - 2 ;
-  // BML and BMS, BOL and BOS  come first (stationName= 2 and 3, 4 and 5 -> index 0-3)
-  if(stationName>m_BOS_id && stationName<m_CSS_id) index = index - 2 ;
-  // BMF, BOF and BOG are 8,9,10 => must be 4,5 and 6
-  else if(stationName>m_CSS_id) index = index - 44 ;
-  // BME and BOE 53 and 54 are at indices 7 and 8 
-
-  static std::atomic<bool> clusterIndexAPrinted = false;
-  static std::atomic<bool> clusterIndexCPrinted = false;
-  if( !m_ClusterSize_fromCOOL ){
-    index += m_FracClusterSize1_A.size()/2*measuresPhi ;
-    if( index>m_FracClusterSize1_A.size()    || index>m_FracClusterSize2_A.size() ||
-      index>m_FracClusterSizeTail_A.size() || index>m_MeanClusterSizeTail_A.size() ) {
-      if (stationName==m_BIS_id || stationName==m_BIL_id) {
-        if (!clusterIndexAPrinted) {
-          ATH_MSG_WARNING("Index out of array in ClusterSizeEvaluation SideA " << index <<" statName "<<stationName<<" (ClusterSize not from COOL)");
-          clusterIndexAPrinted.store(true, std::memory_order_relaxed);
+    ATH_MSG_DEBUG ( "Digit Id = " << m_idHelper->show_to_string(*IdRpcStrip)  );
+  
+    if (IdRpcStrip==0) return 1;
+    
+    int ClusterSize = 1 ;
+    
+    float FracClusterSize1    = 1.00 ;
+    float FracClusterSize2    = 0.00 ;
+    float MeanClusterSize     = 1.00 ;
+    float FracClusterSizeTail = 0.00 ;
+    float MeanClusterSizeTail = 1.00 ;
+    // float FracClusterSize1norm  = 1  ; // not used
+    float FracClusterSize2norm  = 0  ;
+    
+    //2=BML,3=BMS,4=BOL,5=BOS,8=BMF,9=BOF,10=BOG
+    int stationName  = m_idHelper->stationName(*IdRpcStrip);
+    int stationEta   = m_idHelper->stationEta (*IdRpcStrip);
+    int measuresPhi  = m_idHelper->measuresPhi(*IdRpcStrip);
+    
+    
+    unsigned int index = stationName - 2 ;
+    // BML and BMS, BOL and BOS  come first (stationName= 2 and 3, 4 and 5 -> index 0-3)
+    if(stationName>5 && stationName<50) index = index - 2 ;
+    // BMF, BOF and BOG are 8,9,10 => must be 4,5 and 6
+    else if(stationName>50) index = index - 44 ;
+    // BME and BOE 53 and 54 are at indices 7 and 8 
+    
+    if( !m_ClusterSize_fromCOOL && stationName>=2){
+        index += m_FracClusterSize1_A.size()/2*measuresPhi ;
+        if( index>m_FracClusterSize1_A.size()    || index>m_FracClusterSize2_A.size() ||
+            index>m_FracClusterSizeTail_A.size() || index>m_MeanClusterSizeTail_A.size() ) {
+            ATH_MSG_ERROR ( "Index out of array in ClusterSizeEvaluation SideA " << index <<" statName "<<stationName) ;
+            return 1;
         }
-      } else ATH_MSG_WARNING("Index out of array in ClusterSizeEvaluation SideA " << index <<" statName "<<stationName<<" (ClusterSize not from COOL)");
-      return 1;
-    }
-    FracClusterSize1    = m_FracClusterSize1_A      [index];
-    FracClusterSize2    = m_FracClusterSize2_A      [index];
-    FracClusterSizeTail = m_FracClusterSizeTail_A   [index];
-    MeanClusterSizeTail = m_MeanClusterSizeTail_A   [index];
-
-    if(stationEta<0){
-      index += m_FracClusterSize1_C.size()/2*measuresPhi - m_FracClusterSize1_A.size()/2*measuresPhi ;
-      if( index>m_FracClusterSize1_C.size()    || index>m_FracClusterSize2_C.size() ||
-      index>m_FracClusterSizeTail_C.size() || index>m_MeanClusterSizeTail_C.size() ) {
-        if (stationName==m_BIS_id || stationName==m_BIL_id) {
-          if (!clusterIndexCPrinted) {
-            ATH_MSG_WARNING("Index out of array in ClusterSizeEvaluation SideC " << index <<" statName "<<stationName<<" (ClusterSize not from COOL)");
-            clusterIndexCPrinted.store(true, std::memory_order_relaxed);
-          }
-        } else ATH_MSG_WARNING("Index out of array in ClusterSizeEvaluation SideC " << index <<" statName "<<stationName<<" (ClusterSize not from COOL)");
-        return 1;
-      }
-
-      FracClusterSize1    = m_FracClusterSize1_C      [index];
-      FracClusterSize2    = m_FracClusterSize2_C      [index];
-      FracClusterSizeTail = m_FracClusterSizeTail_C   [index];
-      MeanClusterSizeTail = m_MeanClusterSizeTail_C   [index];
-    }
-  }
-  else{
-    SG::ReadCondHandle<RpcCondDbData> readHandle{m_readKey, ctx};
-    const RpcCondDbData* readCdo{*readHandle};
-
-    Identifier Id  = m_idHelper->panelID(*IdRpcStrip);
-
-    int    RPC_ProjectedTracks = 0;
-
-    if( readCdo->getProjectedTracksMap().find(Id) != readCdo->getProjectedTracksMap().end()) RPC_ProjectedTracks = readCdo->getProjectedTracksMap().find(Id)->second ;
-    // the FracClusterSize maps are 
-    static std::atomic<bool> fracCluster1Printed = false;
-    if(readCdo->getFracClusterSize1Map().find(Id) != readCdo->getFracClusterSize1Map().end()) FracClusterSize1  = float(readCdo->getFracClusterSize1Map().find(Id)->second) ;
-    else {
-      if (!fracCluster1Printed) {
-        ATH_MSG_WARNING("FracClusterSize1 entry not found for id = " <<m_idHelper->show_to_string(*IdRpcStrip)<<" (stationName="<<stationName<<") default will be used, cf. ATLASRECTS-5800");
-        fracCluster1Printed.store(true, std::memory_order_relaxed);
-      }
-    }
-    static std::atomic<bool> fracCluster2Printed = false;
-    if(readCdo->getFracClusterSize2Map().find(Id) != readCdo->getFracClusterSize2Map().end()) FracClusterSize2	= float(readCdo->getFracClusterSize2Map().find(Id)->second) ;
-    else {
-      if (!fracCluster2Printed) {
-        ATH_MSG_WARNING("FracClusterSize2 entry not found for id = " <<m_idHelper->show_to_string(*IdRpcStrip)<<" (stationName="<<stationName<<") default will be used, cf. ATLASRECTS-5800");
-        fracCluster2Printed.store(true, std::memory_order_relaxed);
-      }
-    }
-
-    ATH_MSG_DEBUG ( "FracClusterSize1 and 2 "<< FracClusterSize1 << " " << FracClusterSize2  );
-
-    FracClusterSizeTail = 1. - FracClusterSize1 - FracClusterSize2 ;
-
-    static std::atomic<bool> meanClusterPrinted = false;
-    if(readCdo->getMeanClusterSizeMap().find(Id) != readCdo->getMeanClusterSizeMap().end()) MeanClusterSize     = float(readCdo->getMeanClusterSizeMap().find(Id)->second)  ;
-    else {
-      if (!meanClusterPrinted) {
-        ATH_MSG_WARNING ("MeanClusterSize entry not found for id = " <<m_idHelper->show_to_string(*IdRpcStrip)<<" (stationName="<<stationName<<") default will be used, cf. ATLASRECTS-5801");
-        meanClusterPrinted.store(true, std::memory_order_relaxed);
-      }
-    }
-
-    MeanClusterSizeTail = MeanClusterSize - FracClusterSize1 - 2*FracClusterSize2 ;
-
-    ATH_MSG_DEBUG ( "MeanClusterSizeTail and FracClusterSizeTail "<< MeanClusterSizeTail << " " << FracClusterSizeTail  );
-
-    //if clustersize have anomalous values set to the average cluster size from joboption
-    if(RPC_ProjectedTracks<m_CutProjectedTracks ||  RPC_ProjectedTracks>10000000 || MeanClusterSize>m_CutMaxClusterSize || MeanClusterSize<=1 || FracClusterSizeTail < 0 || FracClusterSize1 < 0 || FracClusterSize2 < 0  || FracClusterSizeTail > 1 || FracClusterSize1 > 1 || FracClusterSize2 >1){
-      index += m_FracClusterSize1_A.size()/2*measuresPhi ;
-      if( index>m_FracClusterSize1_A.size()    || index>m_FracClusterSize2_A.size() ||
-        index>m_FracClusterSizeTail_A.size() || index>m_MeanClusterSizeTail_A.size() ) {
-        if (stationName==m_BIS_id || stationName==m_BIL_id) {
-          if (!clusterIndexAPrinted) {
-            ATH_MSG_WARNING("Index out of array in ClusterSizeEvaluation SideA " << index << " statName "<<stationName<<", cf. ATLASRECTS-5802");
-            clusterIndexAPrinted.store(true, std::memory_order_relaxed);
-          }
-        } else ATH_MSG_WARNING("Index out of array in ClusterSizeEvaluation SideA " << index << " statName "<<stationName);
-        return 1;
-      }
-      FracClusterSize1	= m_FracClusterSize1_A      [index];
-      FracClusterSize2	= m_FracClusterSize2_A      [index];
-      FracClusterSizeTail = m_FracClusterSizeTail_A   [index];
-      MeanClusterSizeTail = m_MeanClusterSizeTail_A   [index];
-
-      if(stationEta<0){
-        index += m_FracClusterSize1_C.size()/2*measuresPhi - m_FracClusterSize1_A.size()/2*measuresPhi ;
-        if( index>m_FracClusterSize1_C.size()    || index>m_FracClusterSize2_C.size() ||
-          index>m_FracClusterSizeTail_C.size() || index>m_MeanClusterSizeTail_C.size() ) {
-          if (stationName==m_BIS_id || stationName==m_BIL_id) {
-            if (!clusterIndexCPrinted) {
-              ATH_MSG_WARNING("Index out of array in ClusterSizeEvaluation SideC " << index << " statName "<<stationName<<", cf. ATLASRECTS-5802");
-              clusterIndexCPrinted.store(true, std::memory_order_relaxed);
+        FracClusterSize1    = m_FracClusterSize1_A      [index];
+        FracClusterSize2    = m_FracClusterSize2_A      [index];
+        FracClusterSizeTail = m_FracClusterSizeTail_A   [index];
+        MeanClusterSizeTail = m_MeanClusterSizeTail_A   [index];
+        
+        if(stationEta<0){
+            index += m_FracClusterSize1_C.size()/2*measuresPhi - m_FracClusterSize1_A.size()/2*measuresPhi ;
+            if( index>m_FracClusterSize1_C.size()    || index>m_FracClusterSize2_C.size() ||
+                index>m_FracClusterSizeTail_C.size() || index>m_MeanClusterSizeTail_C.size() ) {
+                ATH_MSG_ERROR ( "Index out of array in ClusterSizeEvaluation SideC " << index <<" statName "<<stationName) ;
+                return 1;
             }
-          } else ATH_MSG_WARNING("Index out of array in ClusterSizeEvaluation SideC " << index << " statName "<<stationName);
-          return 1;
+            FracClusterSize1    = m_FracClusterSize1_C      [index];
+            FracClusterSize2    = m_FracClusterSize2_C      [index];
+            FracClusterSizeTail = m_FracClusterSizeTail_C   [index];
+            MeanClusterSizeTail = m_MeanClusterSizeTail_C   [index];
         }
-        FracClusterSize1	 = m_FracClusterSize1_C      [index];
-        FracClusterSize2	 = m_FracClusterSize2_C      [index];
-        FracClusterSizeTail = m_FracClusterSizeTail_C   [index];
-        MeanClusterSizeTail = m_MeanClusterSizeTail_C   [index];
-      }
+    } else if (stationName<2 && ( !m_ClusterSize_fromCOOL|| !m_ClusterSize_BIS78_fromCOOL))  {// BIS78
+        FracClusterSize1    = m_FracClusterSize1_BIS78;
+        FracClusterSize2    = m_FracClusterSize2_BIS78;
+        FracClusterSizeTail = m_FracClusterSizeTail_BIS78;
+        MeanClusterSizeTail = m_MeanClusterSizeTail_BIS78;
+    }else{ // Cluster size from COOL
+        SG::ReadCondHandle<RpcCondDbData> readHandle{m_readKey, ctx};
+        const RpcCondDbData* readCdo{*readHandle};
+        
+        Identifier Id  = m_idHelper->panelID(*IdRpcStrip);
+        
+        int    RPC_ProjectedTracks = 0;
+        
+        if( readCdo->getProjectedTracksMap().find(Id) != readCdo->getProjectedTracksMap().end()) RPC_ProjectedTracks = readCdo->getProjectedTracksMap().find(Id)->second ;
+        
+        if(readCdo->getFracClusterSize1Map().find(Id) != readCdo->getFracClusterSize1Map().end()) FracClusterSize1	= float(readCdo->getFracClusterSize1Map().find(Id)->second) ;
+        else ATH_MSG_INFO ( "FracClusterSize1 entry not found for id = " <<m_idHelper->show_to_string(*IdRpcStrip)<<" default will be used") ;
+        if(readCdo->getFracClusterSize2Map().find(Id) != readCdo->getFracClusterSize2Map().end()) FracClusterSize2	= float(readCdo->getFracClusterSize2Map().find(Id)->second) ;
+        else ATH_MSG_INFO ( "FracClusterSize2 entry not found for id = " <<m_idHelper->show_to_string(*IdRpcStrip)<<" default will be used") ;
+        
+        ATH_MSG_DEBUG ( "FracClusterSize1 and 2 "<< FracClusterSize1 << " " << FracClusterSize2  );
+        
+        FracClusterSizeTail = 1. - FracClusterSize1 - FracClusterSize2 ;
+        
+        if(readCdo->getMeanClusterSizeMap().find(Id) != readCdo->getMeanClusterSizeMap().end()) MeanClusterSize     = float(readCdo->getMeanClusterSizeMap().find(Id)->second)  ;
+        else ATH_MSG_INFO ( "MeanClusterSize entry not found for id = " <<m_idHelper->show_to_string(*IdRpcStrip)<<" default will be used") ;
+        
+        MeanClusterSizeTail = MeanClusterSize - FracClusterSize1 - 2*FracClusterSize2 ;
+        
+        ATH_MSG_DEBUG ( "MeanClusterSizeTail and FracClusterSizeTail "<< MeanClusterSizeTail << " " << FracClusterSizeTail  );
+        
+        //if clustersize have anomalous values set to the average cluster size from joboption
+        if(RPC_ProjectedTracks<m_CutProjectedTracks ||  RPC_ProjectedTracks>10000000 || MeanClusterSize>m_CutMaxClusterSize || MeanClusterSize<=1 || FracClusterSizeTail < 0 || FracClusterSize1 < 0 || FracClusterSize2 < 0  || FracClusterSizeTail > 1 || FracClusterSize1 > 1 || FracClusterSize2 >1){
+            if (stationName>=2){
+                index += m_FracClusterSize1_A.size()/2*measuresPhi ;
+                if( index>m_FracClusterSize1_A.size()    || index>m_FracClusterSize2_A.size() ||
+                    index>m_FracClusterSizeTail_A.size() || index>m_MeanClusterSizeTail_A.size() ) {
+                    ATH_MSG_ERROR ( "Index out of array in ClusterSizeEvaluation SideA " << index << " statName "<<stationName) ;
+                    return 1;
+                }
+                FracClusterSize1	= m_FracClusterSize1_A      [index];
+                FracClusterSize2	= m_FracClusterSize2_A      [index];
+                FracClusterSizeTail = m_FracClusterSizeTail_A   [index];
+                MeanClusterSizeTail = m_MeanClusterSizeTail_A   [index];
+                
+                if(stationEta<0){
+                    index += m_FracClusterSize1_C.size()/2*measuresPhi - m_FracClusterSize1_A.size()/2*measuresPhi ;
+                    if( index>m_FracClusterSize1_C.size()    || index>m_FracClusterSize2_C.size() ||
+                        index>m_FracClusterSizeTail_C.size() || index>m_MeanClusterSizeTail_C.size() ) {
+                        ATH_MSG_ERROR ( "Index out of array in ClusterSizeEvaluation SideC " << index << " statName "<<stationName ) ;
+                        return 1;
+                    }
+                    
+                    FracClusterSize1	 = m_FracClusterSize1_C      [index];
+                    FracClusterSize2	 = m_FracClusterSize2_C      [index];
+                    FracClusterSizeTail = m_FracClusterSizeTail_C   [index];
+                    MeanClusterSizeTail = m_MeanClusterSizeTail_C   [index];
+                }
+            } else  {
+                FracClusterSize1    = m_FracClusterSize1_BIS78;
+                FracClusterSize2    = m_FracClusterSize2_BIS78;
+                FracClusterSizeTail = m_FracClusterSizeTail_BIS78;
+                MeanClusterSizeTail = m_MeanClusterSizeTail_BIS78;         
+            } 
+        }   
     }
-  }
-
-  if(FracClusterSize1>1   )FracClusterSize1   =1.;
-  if(FracClusterSize2>1   )FracClusterSize2   =1.;
-  if(FracClusterSizeTail>1)FracClusterSizeTail=1.;
-  float FracTot = FracClusterSize1+FracClusterSize2+FracClusterSizeTail;
-  if(FracTot!=1.&&FracTot>0) {
-    FracClusterSize1    =FracClusterSize1    / FracTot ;
-    FracClusterSize2    =FracClusterSize2    / FracTot ;
-    FracClusterSizeTail =FracClusterSizeTail / FracTot ;
-  }
-  if(MeanClusterSizeTail<0 || MeanClusterSizeTail>10 )MeanClusterSizeTail=1;
-
-  ATH_MSG_VERBOSE ( "ClusterSize Final " << FracClusterSize1 << " FracClusterSize1 " << FracClusterSize2 << " FracClusterSize2  " << FracClusterSizeTail << "   " << FracClusterSizeTail  << " MeanClusterSizeTail  " <<  MeanClusterSizeTail );
-
-  float FracClusterSize1plus2  = FracClusterSize1 + FracClusterSize2   	                    ;
-  float ITot                   = FracClusterSize1 + FracClusterSize2 +  FracClusterSizeTail ;
-
-  if( FracClusterSize1plus2!= 0 ){
-    //FracClusterSize1norm = FracClusterSize1 / FracClusterSize1plus2 ; // not used
-    FracClusterSize2norm = FracClusterSize2 / FracClusterSize1plus2 ;
-  }
-
-  float rndmCS = CLHEP::RandFlat::shoot(rndmEngine, ITot ) ;
-
-  //Expanded CS2 of 1.3 to match average CS1 and CS2 (to be investigate)
-  if(rndmCS < FracClusterSize1plus2){
-    //deterministic assignment of CS 1 or 2
-    if(xstripnorm <= FracClusterSize2norm/2.*1.3){
-      ClusterSize = -2 ;
+    if(FracClusterSize1>1   )FracClusterSize1   =1.;
+    if(FracClusterSize2>1   )FracClusterSize2   =1.;
+    if(FracClusterSizeTail>1)FracClusterSizeTail=1.;
+    float FracTot = FracClusterSize1+FracClusterSize2+FracClusterSizeTail;
+    if(FracTot!=1.&&FracTot>0) {
+        FracClusterSize1    =FracClusterSize1    / FracTot ;
+        FracClusterSize2    =FracClusterSize2    / FracTot ;
+        FracClusterSizeTail =FracClusterSizeTail / FracTot ;
     }
-    else if( (1.0-FracClusterSize2norm/2.*1.3) <= xstripnorm ){
-      ClusterSize =  2 ;
+    if(MeanClusterSizeTail<0 || MeanClusterSizeTail>10 )MeanClusterSizeTail=1;
+    
+    ATH_MSG_VERBOSE ( "ClusterSize Final " << FracClusterSize1 << " FracClusterSize1 " << FracClusterSize2 << " FracClusterSize2  " << FracClusterSizeTail << "   " << FracClusterSizeTail  << " MeanClusterSizeTail  " <<  MeanClusterSizeTail );
+    
+    float FracClusterSize1plus2  = FracClusterSize1 + FracClusterSize2   	                    ;
+    float ITot                   = FracClusterSize1 + FracClusterSize2 +  FracClusterSizeTail ;
+    
+    if( FracClusterSize1plus2!= 0 ){
+        //FracClusterSize1norm = FracClusterSize1 / FracClusterSize1plus2 ; // not used
+        FracClusterSize2norm = FracClusterSize2 / FracClusterSize1plus2 ;
     }
-    else {
-      ClusterSize =  1 ;
+    
+    float rndmCS = CLHEP::RandFlat::shoot(rndmEngine, ITot ) ;
+    
+    //Expanded CS2 of 1.3 to match average CS1 and CS2 (to be investigate)
+    if(rndmCS < FracClusterSize1plus2){
+        //deterministic assignment of CS 1 or 2
+        if(xstripnorm <= FracClusterSize2norm/2.*1.3){
+            ClusterSize = -2 ;
+        }
+        else if( (1.0-FracClusterSize2norm/2.*1.3) <= xstripnorm ){
+            ClusterSize =  2 ;
+        }
+        else {
+            ClusterSize =  1 ;
+        }
+        if(m_ClusterSize1_2uncorr==1){
+            float rndmCS1_2 = CLHEP::RandFlat::shoot(rndmEngine, 1 ) ;
+            ClusterSize =  1 ;
+            if(rndmCS1_2<FracClusterSize2norm)ClusterSize =  2 ;
+        }
+        
     }
-    if(m_ClusterSize1_2uncorr==1){
-      float rndmCS1_2 = CLHEP::RandFlat::shoot(rndmEngine, 1 ) ;
-      ClusterSize =  1 ;
-      if(rndmCS1_2<FracClusterSize2norm)ClusterSize =  2 ;
+    else if( ( FracClusterSize1plus2 <= rndmCS ) && ( rndmCS <= ITot ) ){
+        ClusterSize = m_FirstClusterSizeInTail  ;
+        ClusterSize += int(CLHEP::RandExponential::shoot(rndmEngine, MeanClusterSizeTail )) ;
+        float rndmLR = CLHEP::RandFlat::shoot(rndmEngine, 1.0 ) ;
+        if(rndmLR>0.5)ClusterSize = - ClusterSize ;
     }
-
-  }
-  else if( ( FracClusterSize1plus2 <= rndmCS ) && ( rndmCS <= ITot ) ){
-    ClusterSize = m_FirstClusterSizeInTail  ;
-    ClusterSize += int(CLHEP::RandExponential::shoot(rndmEngine, MeanClusterSizeTail )) ;
-    float rndmLR = CLHEP::RandFlat::shoot(rndmEngine, 1.0 ) ;
-    if(rndmLR>0.5)ClusterSize = - ClusterSize ;
-  }
-  else{
-    ClusterSize = 1  ;
-  }
-
-  //std::cout << "Cluster1_2 " << rndmCS <<" " << ITot<< " " << ClusterSize << " " << xstripnorm << " " << FracClusterSize2norm/2. <<" " <<  (1.0-FracClusterSize2norm/2.)<< std::endl ;
-
-  //negative CS correspond to left asymmetric cluster with respect to nstrip
-  return ClusterSize;
-
+    else{
+        ClusterSize = 1  ;
+    }
+    
+    //std::cout << "Cluster1_2 " << rndmCS <<" " << ITot<< " " << ClusterSize << " " << xstripnorm << " " << FracClusterSize2norm/2. <<" " <<  (1.0-FracClusterSize2norm/2.)<< std::endl ;
+    
+    //negative CS correspond to left asymmetric cluster with respect to nstrip
+    return ClusterSize;
+    
 }
 
 //--------------------------------------------
@@ -2293,8 +2296,15 @@ StatusCode RpcDigitizationTool::PrintCalibrationVector() {
   }
   vec_size = m_OnlyEtaEff_C.size() ;
   for(int i=0 ; i!= vec_size ; i++ ){
-    ATH_MSG_INFO ( "size of RPC calib vector OnlyEta_C: " << m_OnlyPhiEff_C.value().at(i) );
+    ATH_MSG_INFO ( "size of RPC calib vector OnlyEta_C: " << m_OnlyEtaEff_C.value().at(i) );
   }
+  ATH_MSG_INFO ( "PhiAndEtaEff_BIS78: " << m_PhiAndEtaEff_BIS78 );
+  ATH_MSG_INFO ( "OnlyPhiEff_BIS78: " << m_OnlyPhiEff_BIS78 );
+  ATH_MSG_INFO ( "OnlyEtaEff_BIS78: " << m_OnlyEtaEff_BIS78 );
+
+
+
+
   vec_size = m_FracClusterSize1_A.size() ;
   for(int i=0 ; i!= vec_size ; i++ ){
     ATH_MSG_INFO ( "size of RPC calib vector FracClusterSize1_A: " << m_FracClusterSize1_A.value().at(i) );
@@ -2327,7 +2337,12 @@ StatusCode RpcDigitizationTool::PrintCalibrationVector() {
   for(int i=0 ; i!= vec_size ; i++ ){
     ATH_MSG_INFO ( "size of RPC calib vector MeanClusterSizeTail_C: " << m_MeanClusterSizeTail_C.value().at(i) );
   }
+  ATH_MSG_INFO ( "FracClusterSize1_BIS78: " << m_FracClusterSize1_BIS78 );
+  ATH_MSG_INFO ( "FracClusterSize1_BIS78: " << m_FracClusterSize2_BIS78 );
+  ATH_MSG_INFO ( "FracClusterSizeTail_BIS78: " << m_FracClusterSizeTail_BIS78 );
+  ATH_MSG_INFO ( "MeanClusterSizeTail_BIS78: " << m_MeanClusterSizeTail_BIS78 );
 
+  
   return sc;
 
 }
@@ -2561,11 +2576,10 @@ StatusCode RpcDigitizationTool::DumpRPCCalibFromCoolDB(const EventContext& ctx)
 	  for( int doubletZ    =  1 ;  doubletZ    != 4;  doubletZ++   ){
 	    for( int doubletPhi  =  1 ;  doubletPhi  != 3;  doubletPhi++ ){
 	      for( int gasGap      =  1 ;  gasGap	  != 3;  gasGap++     ){
-
-    bool isValid=false;
-    Identifier rpcId = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR, doubletZ, doubletPhi, 1, 1, 1, true, &isValid); // last 5 arguments are: int doubletPhi, int gasGap, int measuresPhi, int strip, bool check, bool* isValid
-    if (!isValid) continue;
-		const RpcReadoutElement* rpc = m_GMmgr->getRpcReadoutElement(rpcId);
+                  bool isValid=false;
+                  Identifier rpcId = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR, doubletZ, doubletPhi, 1, 1, 1, true, &isValid); // last 5 arguments are: int doubletPhi, int gasGap, int measuresPhi, int strip, bool check, bool* isValid
+                  if (!isValid) continue;
+                  const RpcReadoutElement* rpc = m_GMmgr->getRpcReadoutElement(rpcId);
 		if(rpc == 0 )continue;
 		Identifier idr = rpc->identify();
 		if(idr == 0 )continue;
@@ -2764,10 +2778,11 @@ StatusCode RpcDigitizationTool::DumpRPCCalibFromCoolDB(const EventContext& ctx)
 	      for( int gasGap      =  1 ;  gasGap	  != 3;  gasGap++     ){
 		for( int measphi     =  0 ;  measphi	  != 2;  measphi++    ){
 
-      bool isValid=false;
-      Identifier rpcId = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR, doubletZ, doubletPhi, 1, 1, 1, true, &isValid); // last 5 arguments are: int doubletPhi, int gasGap, int measuresPhi, int strip, bool check, bool* isValid
-      if (!isValid) continue;
-		  const RpcReadoutElement* rpc = m_GMmgr->getRpcReadoutElement(rpcId);
+                    bool isValid=false;
+                    Identifier rpcId = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR, doubletZ, doubletPhi, 1, 1, 1, true, &isValid); // last 5 arguments are: int doubletPhi, int gasGap, int measuresPhi, int strip, bool check, bool* isValid
+                    if (!isValid) continue;
+                    const RpcReadoutElement* rpc = m_GMmgr->getRpcReadoutElement(rpcId);
+                    
 		  if(!rpc)continue;
 		  Identifier idr = rpc->identify();
 		  if(idr == 0 )continue;
@@ -2805,12 +2820,11 @@ StatusCode RpcDigitizationTool::DumpRPCCalibFromCoolDB(const EventContext& ctx)
 	    for( int doubletPhi  =  1 ;  doubletPhi  != 3;  doubletPhi++ ){
 	      for( int gasGap      =  1 ;  gasGap	  != 3;  gasGap++     ){
 		for( int measphi     =  0 ;  measphi	  != 2;  measphi++    ){
-
-      bool isValid=false;
-      Identifier rpcId = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR, doubletZ, doubletPhi, 1, 1, 1, true, &isValid); // last 5 arguments are: int doubletPhi, int gasGap, int measuresPhi, int strip, bool check, bool* isValid
-      if (!isValid) continue;
-		  const RpcReadoutElement* rpc = m_GMmgr->getRpcReadoutElement(rpcId);
-		  if(rpc == 0 )continue;
+                    bool isValid=false;
+                    Identifier rpcId = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR, doubletZ, doubletPhi, 1, 1, 1, true, &isValid); // last 5 arguments are: int doubletPhi, int gasGap, int measuresPhi, int strip, bool check, bool* isValid
+                    if (!isValid) continue;
+                    const RpcReadoutElement* rpc = m_GMmgr->getRpcReadoutElement(rpcId);
+                    if(rpc == 0 )continue;
 		  Identifier idr = rpc->identify();
 		  if(idr == 0 )continue;
 		  Identifier atlasId = m_idHelper->channelID(idr, doubletZ,doubletPhi , gasGap, measphi, 1)     ;
@@ -2896,11 +2910,10 @@ StatusCode RpcDigitizationTool::DumpRPCCalibFromCoolDB(const EventContext& ctx)
 	      for( int gasGap      =  1 ;  gasGap	  != 3;  gasGap++     ){
 		for( int measphi     =  0 ;  measphi	  != 2;  measphi++    ){
 		  for( int strip       =  1 ;  strip	  !=81;  strip++      ){
-
-        bool isValid=false;
-        Identifier rpcId = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR, doubletZ, doubletPhi, 1, 1, 1, true, &isValid); // last 5 arguments are: int doubletPhi, int gasGap, int measuresPhi, int strip, bool check, bool* isValid
-        if (!isValid) continue;
-		    const RpcReadoutElement* rpc = m_GMmgr->getRpcReadoutElement(rpcId);
+                      bool isValid=false;
+                      Identifier rpcId = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR, doubletZ, doubletPhi, 1, 1, 1, true, &isValid); // last 5 arguments are: int doubletPhi, int gasGap, int measuresPhi, int strip, bool check, bool* isValid
+                      if (!isValid) continue;
+                      const RpcReadoutElement* rpc = m_GMmgr->getRpcReadoutElement(rpcId);
 		    if(rpc == 0 )continue;
 		    Identifier idr = rpc->identify();
 		    if(idr == 0 )continue;
@@ -2909,6 +2922,7 @@ StatusCode RpcDigitizationTool::DumpRPCCalibFromCoolDB(const EventContext& ctx)
 		    int stripstatus	      = readCdo->getDeadStripIntMap      ().find(atlasId)->second ;
 		    if( stripstatus != 1 )continue;
 		    ATH_MSG_VERBOSE( "Identifier " << atlasId << " sName "<<stationName<<" sEta " <<stationEta<<" sPhi "<<stationPhi<<" dR "<<doubletR<<" dZ "<<doubletZ<<" dPhi "<<doubletPhi<<" Gap "<<gasGap<<" view "<<measphi<<" strip "<<strip << " stripstatus "<<stripstatus );
+		    //std::cout<<"Identifier " << atlasId << " sName "<<stationName<<" sEta " <<stationEta<<" sPhi "<<stationPhi<<" dR "<<doubletR<<" dZ "<<doubletZ<<" dPhi "<<doubletPhi<<" Gap "<<gasGap<<" view "<<measphi<<" strip "<<strip << " stripstatus "<<stripstatus << std::endl;
 
 		  }}}}}}}}}
   return sc;
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MooreTools.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MooreTools.py
index a7388a805d1a7af7cacbf423729e8b3dbebbb8b0..56312112eb03ff4e44e81b5d351d8d4269f6ab6d 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MooreTools.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MooreTools.py
@@ -33,6 +33,8 @@ from .MuonRecFlags import muonRecFlags
 from .MuonStandaloneFlags import muonStandaloneFlags
 from AtlasGeoModel.MuonGMJobProperties import MuonGeometryFlags
 from TriggerJobOpts.TriggerFlags import TriggerFlags
+
+from InDetRecExample.TrackingCommon import use_tracking_geometry_cond_alg
 #==============================================================
 
 # call  setDefaults to update flags
@@ -526,6 +528,13 @@ class MuonTrackExtrapolationTool(CfgMgr.Muon__MuonTrackExtrapolationTool,Configu
         self.applyUserDefaults(kwargs,name)
         super(MuonTrackExtrapolationTool,self).__init__(name,**kwargs)
 
+if use_tracking_geometry_cond_alg:
+  from AthenaCommon.AlgSequence import AthSequencer
+  condSeq = AthSequencer("AthCondSeq")
+  if not getattr (condSeq, 'AtlasTrackingGeometryCondAlg', None):
+    from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlg import ConfiguredTrackingGeometryCondAlg
+    condSeq += ConfiguredTrackingGeometryCondAlg()
+  MuonTrackExtrapolationTool.setDefaultProperties(TrackingGeometryReadKey='AtlasTrackingGeometry')
 MuonTrackExtrapolationTool.setDefaultProperties( TrackingGeometrySvc=ServiceMgr.AtlasTrackingGeometrySvc )
 if beamFlags.beamType() == 'cosmics':
     MuonTrackExtrapolationTool.setDefaultProperties( Cosmics = True )
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecTools/MuonRecToolInterfaces/MuonRecToolInterfaces/IMuonTrackTruthTool.h b/MuonSpectrometer/MuonReconstruction/MuonRecTools/MuonRecToolInterfaces/MuonRecToolInterfaces/IMuonTrackTruthTool.h
index bb4857d66f4f82e7cdbffb9ac0e94b52a8dba5cd..067446f3d55bf62ddecdd9ad233f487867c61413 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecTools/MuonRecToolInterfaces/MuonRecToolInterfaces/IMuonTrackTruthTool.h
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecTools/MuonRecToolInterfaces/MuonRecToolInterfaces/IMuonTrackTruthTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef MUON_IMUONTRACKTRUTHTOOL_H
@@ -43,7 +43,7 @@ namespace Muon {
   class MuonTrackTruth {
   public:
     const TrackRecord* truthTrack;
-    const TruthTrajectory* truthTrajectory;
+    std::shared_ptr<const TruthTrajectory> truthTrajectory;
     bool isHitMatched;
     bool isParameterMatched;
     MuonTechnologyTruth mdts;
@@ -78,7 +78,7 @@ namespace Muon {
     public:
     struct TruthTreeEntry {
       const TrackRecord* truthTrack;
-      const TruthTrajectory* truthTrajectory;
+      std::shared_ptr<const TruthTrajectory> truthTrajectory;
       MuonSimDataCollection mdtHits;
       CscSimDataCollection  cscHits;
       MuonSimDataCollection rpcHits;
@@ -98,6 +98,7 @@ namespace Muon {
     // collect track record entries per barcode
     typedef std::map<int,TruthTreeEntry> TruthTree;
     typedef TruthTree::iterator          TruthTreeIt;
+    typedef TruthTree::const_iterator    TruthTreeConstIt;
   
   public:
     /** access to tool interface */
@@ -105,28 +106,28 @@ namespace Muon {
 
 
     /** @brief perform truth matching for a given set of tracks */
-    virtual ResultVec match(const TrackCollection& tracks ) const = 0;
+    virtual ResultVec match(const TruthTree& truth_tree, const TrackCollection& tracks ) const = 0;
 
     /** @brief perform truth matching for a given set of segments */
-    virtual SegmentResultVec match(const std::vector<const MuonSegment*>& segments ) const = 0;
+    virtual SegmentResultVec match(const TruthTree& truth_tree, const std::vector<const MuonSegment*>& segments ) const = 0;
 
     /** create truth tree from sim data */
     virtual const TruthTree createTruthTree(const TrackRecordCollection* truthTrackCol, const McEventCollection* mcEventCollection,
 					    std::vector<const MuonSimDataCollection*> muonSimData, const CscSimDataCollection* cscSimDataMap) const = 0;
 
     /** @brief get track truth */
-    virtual MuonTrackTruth getTruth( const Trk::Track& track, bool restrictedTruth = false ) const = 0;
+    virtual MuonTrackTruth getTruth(const TruthTree& truth_tree, const Trk::Track& track, bool restrictedTruth = false ) const = 0;
 
     /** @brief get segment truth for a list of segments, the segments will be considered to belong to the same muon */
-    virtual MuonTrackTruth getTruth( const std::vector<const MuonSegment*>& segments, bool restrictedTruth = false ) const = 0;
+    virtual MuonTrackTruth getTruth(const TruthTree& truth_tree, const std::vector<const MuonSegment*>& segments, bool restrictedTruth = false ) const = 0;
 
     /** @brief get segment truth */
-    virtual MuonTrackTruth getTruth( const Muon::MuonSegment& segment ) const = 0;
+    virtual MuonTrackTruth getTruth(const TruthTree& truth_tree, const Muon::MuonSegment& segment ) const = 0;
 
     /** @brief get truth for a give set of hits. If restrictedTruth is set to true only missed hits 
 	in chambers with hits will be counted.
     */
-    virtual MuonTrackTruth getTruth( const std::vector<const Trk::MeasurementBase*>& measurements, bool restrictedTruth = false ) const = 0;
+    virtual MuonTrackTruth getTruth(const TruthTree& truth_tree, const std::vector<const Trk::MeasurementBase*>& measurements, bool restrictedTruth = false ) const = 0;
 
     /// returns the mother particle of the particle with barcodeIn if it is found in the truth trajectory
     /// It traces the decay chain until if finds the first particle that is different flavor from the starting one.
diff --git a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackSteeringTools/src/MuPatHitTool.cxx b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackSteeringTools/src/MuPatHitTool.cxx
index 348f063e93bdc878d375ec4bfcbe9e152d8261b8..739d5bc75423dc0344b9fbfe226f59868d7b9341 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackSteeringTools/src/MuPatHitTool.cxx
+++ b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackSteeringTools/src/MuPatHitTool.cxx
@@ -150,8 +150,8 @@ MuPatHitTool::create(const Trk::TrackParameters& pars, const std::vector<const T
         }
 
         // create hit and insert it into list
-        auto hit = std::make_unique<MuPatHit>(std::move(exPars), *sit, std::move(broadMeas), hitInfo);
         ATH_MSG_VERBOSE(" inserting hit " << m_idHelperSvc->toString(id) << " " << m_printer->print(*exPars));
+        auto hit = std::make_unique<MuPatHit>(std::move(exPars), *sit, std::move(broadMeas), hitInfo);
         currentHitIt = insert(hitList, currentHitIt, hit.get());
         hitsToBeDeleted.push_back (std::move (hit));
     }
diff --git a/MuonSpectrometer/MuonTruthAlgs/MuonTruthAlgs/MuonTrackTruthTool.h b/MuonSpectrometer/MuonTruthAlgs/MuonTruthAlgs/MuonTrackTruthTool.h
index d919b8381b1cc45a8e57d17b510176576fabed2e..891336afb13f0e4e735e43c2d0caa3f863fe5c23 100644
--- a/MuonSpectrometer/MuonTruthAlgs/MuonTruthAlgs/MuonTrackTruthTool.h
+++ b/MuonSpectrometer/MuonTruthAlgs/MuonTruthAlgs/MuonTrackTruthTool.h
@@ -66,27 +66,27 @@ namespace Muon {
     StatusCode initialize();
     
     /** @brief perform truth matching for a given set of tracks */
-    ResultVec match(const TrackCollection& tracks ) const;
+    ResultVec match(const TruthTree& truth_tree,  const TrackCollection& tracks ) const;
 
     /** @brief perform truth matching for a given set of segments */
-    SegmentResultVec match(const std::vector<const MuonSegment*>& segments ) const;
+    SegmentResultVec match(const TruthTree& truth_tree,  const std::vector<const MuonSegment*>& segments ) const;
 
     /** @brief get track truth */
-    MuonTrackTruth getTruth( const Trk::Track& track, bool restrictedTruth = false ) const;
+    MuonTrackTruth getTruth(const TruthTree& truth_tree,  const Trk::Track& track, bool restrictedTruth = false ) const;
 
     /** @brief get segment truth for a list of segments, the segments will be considered to belong to the same muon */
-    MuonTrackTruth getTruth( const std::vector<const MuonSegment*>& segments, bool restrictedTruth = false ) const;
+    MuonTrackTruth getTruth(const TruthTree& truth_tree,  const std::vector<const MuonSegment*>& segments, bool restrictedTruth = false ) const;
 
     /** @brief get segment truth */
-    MuonTrackTruth getTruth( const Muon::MuonSegment& segment ) const;
+    MuonTrackTruth getTruth(const TruthTree& truth_tree,  const Muon::MuonSegment& segment ) const;
 
     /** @brief get truth for a give set of hits. If restrictedTruth is set to true only missed hits 
 	in chambers with hits will be counted.
     */
-    MuonTrackTruth getTruth( const std::vector<const Trk::MeasurementBase*>& measurements, bool restrictedTruth = false ) const;
+    MuonTrackTruth getTruth(const TruthTree& truth_tree,  const std::vector<const Trk::MeasurementBase*>& measurements, bool restrictedTruth = false ) const;
 
     /** create truth tree from sim data */
-    const TruthTree createTruthTree(const TrackRecordCollection* truthTrackCol, const McEventCollection* mcEventCollection,
+    const TruthTree createTruthTree( const TrackRecordCollection* truthTrackCol, const McEventCollection* mcEventCollection,
 				    std::vector<const MuonSimDataCollection*> muonSimData, const CscSimDataCollection* cscSimDataMap) const;
 
     /// Returns the mother particle of the particle with barcodeIn if it is found in the truth trajectory.
@@ -108,11 +108,15 @@ namespace Muon {
 
   private:
 
-    MuonTrackTruth getTruth( const std::vector<const Trk::MeasurementBase*>& measurements,
-			     TruthTreeEntry& truthEntry, bool restrictedTruth ) const;
+    MuonTrackTruth getTruth(const std::vector<const Trk::MeasurementBase*>& measurements,
+                            const TruthTreeEntry& truthEntry, bool restrictedTruth ) const;
 
-    void addSimDataToTree( const MuonSimDataCollection* simDataCol ) const;
-    void addCscSimDataToTree( const CscSimDataCollection* simDataCol ) const;
+    void addSimDataToTree(TruthTree& truth_tree,
+                          std::map<int,int>& barcode_map, 
+                          const MuonSimDataCollection* simDataCol ) const;
+    void addCscSimDataToTree(TruthTree& truth_tree,
+                             std::map<int,int>& barcode_map, 
+                             const CscSimDataCollection* simDataCol ) const;
 
     void addMdtTruth( MuonTechnologyTruth& trackTruth, const Identifier& id, const Trk::MeasurementBase& meas, 
 		      const MuonSimDataCollection& simCol ) const;
@@ -130,8 +134,7 @@ namespace Muon {
 
     int manipulateBarCode( int barcode ) const;
 
-    void clear() const;
-
+   
     bool selectPdg( int pdg ) const { return m_selectedPdgs.count(pdg); }
 
     /// Returns the initial particle of the particle with barcodeIn if it is found in the truth trajectory.
@@ -146,10 +149,7 @@ namespace Muon {
     ToolHandle<Muon::MuonEDMPrinterTool> m_printer{this,"Printer","Muon::MuonEDMPrinterTool/MuonEDMPrinterTool"};
     ToolHandle<Trk::ITruthTrajectoryBuilder> m_truthTrajectoryBuilder{this,"TruthTrajectoryBuilder","Muon::MuonDecayTruthTrajectoryBuilder/MuonDecayTruthTrajectoryBuilder"};
 
-    mutable TruthTree m_truthTree;
-    mutable std::vector<std::unique_ptr<TruthTrajectory> > m_truthTrajectoriesToBeDeleted;
-    mutable std::map<int,int> m_barcodeMap; // map used to link barcode of TrackRecord particles/hits to 'final' state barcode
-
+    
     Gaudi::Property<bool> m_manipulateBarCode{this,"ManipulateBarCode",false};
     Gaudi::Property<bool> m_doSummary{this,"DoSummary",false};
     Gaudi::Property<bool> m_matchAllParticles{this,"MatchAllParticles",true};
diff --git a/MuonSpectrometer/MuonTruthAlgs/MuonTruthAlgs/TrackParticleTruthMaker.h b/MuonSpectrometer/MuonTruthAlgs/MuonTruthAlgs/TrackParticleTruthMaker.h
deleted file mode 100755
index 602428cee49aa679fbba34c28696e08ecbd2106e..0000000000000000000000000000000000000000
--- a/MuonSpectrometer/MuonTruthAlgs/MuonTruthAlgs/TrackParticleTruthMaker.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-///////////////////////////////////////////////////////////////////
-// TrackParticleTruthMaker.h
-//   Header file for class TrackParticleTruthMaker
-///////////////////////////////////////////////////////////////////
-
-#ifndef TRUTHPARTICLEALGS_TRACKPARTICLETRUTHMAKER_H
-#define TRUTHPARTICLEALGS_TRACKPARTICLETRUTHMAKER_H
-
-#include "AthenaBaseComps/AthAlgorithm.h"
-#include <string>
-
-namespace Muon {
-
-class TrackParticleTruthMaker : public AthAlgorithm  {
-
-public:
-
-  // Constructor with parameters:
-  TrackParticleTruthMaker(const std::string &name,ISvcLocator *pSvcLocator);
-
-  ///////////////////////////////////////////////////////////////////
-  // Non-const methods:
-  ///////////////////////////////////////////////////////////////////
-
-  // Basic algorithm methods:
-  virtual StatusCode initialize();
-  virtual StatusCode execute();
-  virtual StatusCode finalize();
-
-  ///////////////////////////////////////////////////////////////////
-  // Private methods:
-  ///////////////////////////////////////////////////////////////////
-private:
-  TrackParticleTruthMaker();
-  TrackParticleTruthMaker(const TrackParticleTruthMaker&);
-  TrackParticleTruthMaker &operator=(const TrackParticleTruthMaker&);
-  
-  ///////////////////////////////////////////////////////////////////
-  // Private data:
-  ///////////////////////////////////////////////////////////////////
-private:
-
-  std::string m_trackParticlesName;
-  std::string m_trackParticleTruthCollection;
-  std::string m_tracksName;
-  std::string m_tracksTruthName;
-
-};
-
-} // namespace Muon
-
-
-#endif //TRUTHPARTICLEALGS_TRACKPARTICLETRUTHMAKER_H
diff --git a/MuonSpectrometer/MuonTruthAlgs/src/MuonSegmentTruthAssociationAlg.cxx b/MuonSpectrometer/MuonTruthAlgs/src/MuonSegmentTruthAssociationAlg.cxx
index be594782038c51d12d070f272703eb08a7ade61c..c078ac608884b0c513660fef6011902b7ada00f8 100644
--- a/MuonSpectrometer/MuonTruthAlgs/src/MuonSegmentTruthAssociationAlg.cxx
+++ b/MuonSpectrometer/MuonTruthAlgs/src/MuonSegmentTruthAssociationAlg.cxx
@@ -15,7 +15,7 @@ namespace Muon {
 
   // Constructor with parameters:
   MuonSegmentTruthAssociationAlg::MuonSegmentTruthAssociationAlg(const std::string &name, ISvcLocator *pSvcLocator) :
-    AthAlgorithm(name,pSvcLocator) {  
+    AthReentrantAlgorithm(name,pSvcLocator) {  
   }
 
   // Initialize method:
@@ -37,12 +37,12 @@ namespace Muon {
   }
 
   // Execute method:
-  StatusCode MuonSegmentTruthAssociationAlg::execute() 
+  StatusCode MuonSegmentTruthAssociationAlg::execute(const EventContext& ctx) const 
   {
     
     // skip if no input data found
-    SG::WriteDecorHandle<xAOD::MuonSegmentContainer,ElementLink< xAOD::MuonSegmentContainer > > muonTruthSegments(m_muonTruthSegmentContainerName);
-    SG::WriteDecorHandle<xAOD::MuonSegmentContainer,ElementLink< xAOD::MuonSegmentContainer > > segments(m_muonSegmentCollectionName);
+    SG::WriteDecorHandle<xAOD::MuonSegmentContainer,ElementLink< xAOD::MuonSegmentContainer > > muonTruthSegments(m_muonTruthSegmentContainerName,ctx);
+    SG::WriteDecorHandle<xAOD::MuonSegmentContainer,ElementLink< xAOD::MuonSegmentContainer > > segments(m_muonSegmentCollectionName,ctx);
     if(!muonTruthSegments.isPresent()){
       ATH_MSG_DEBUG("No muon truth segments");
       return StatusCode::SUCCESS;
@@ -59,7 +59,7 @@ namespace Muon {
       ATH_MSG_ERROR("Muon segments not valid");
       return StatusCode::FAILURE;
     }
-    SG::ReadHandle<TrackRecordCollection> truthTrackCol(m_trackRecord);
+    SG::ReadHandle<TrackRecordCollection> truthTrackCol(m_trackRecord, ctx);
     if (!truthTrackCol.isValid()){
         ATH_MSG_ERROR("Track collection "<<m_trackRecord.key()<<" is not present");
         return StatusCode::FAILURE;
@@ -94,9 +94,9 @@ namespace Muon {
       ++segIndex;
     }
 
-    SG::ReadHandle<McEventCollection> mcEventCollection(m_mcEventColl);
+    SG::ReadHandle<McEventCollection> mcEventCollection(m_mcEventColl, ctx);
     std::vector<const MuonSimDataCollection*> muonSimData;
-    for(SG::ReadHandle<MuonSimDataCollection>& simDataMap : m_muonSimData.makeHandles()){
+    for(SG::ReadHandle<MuonSimDataCollection>& simDataMap : m_muonSimData.makeHandles(ctx)){
       if(!simDataMap.isValid()){
         ATH_MSG_WARNING(simDataMap.key()<<" not valid");
         continue;
@@ -104,19 +104,21 @@ namespace Muon {
       if(!simDataMap.isPresent()) continue;
       muonSimData.push_back(simDataMap.cptr());
     }
+    IMuonTrackTruthTool::TruthTree truth_tree;
     if(m_idHelperSvc->hasCSC()){
-      SG::ReadHandle<CscSimDataCollection> cscSimDataMap(m_cscSimData);
+      SG::ReadHandle<CscSimDataCollection> cscSimDataMap(m_cscSimData, ctx);
       if(!cscSimDataMap.isValid()){
         ATH_MSG_WARNING(cscSimDataMap.key()<<" not valid");
-	m_muonTrackTruthTool->createTruthTree(truthTrackCol.cptr(),mcEventCollection.cptr(),muonSimData,nullptr);
+        truth_tree = m_muonTrackTruthTool->createTruthTree(truthTrackCol.cptr(),mcEventCollection.cptr(),muonSimData,nullptr);
       }
       else{
-	m_muonTrackTruthTool->createTruthTree(truthTrackCol.cptr(),mcEventCollection.cptr(),muonSimData,cscSimDataMap.cptr());
+        truth_tree = m_muonTrackTruthTool->createTruthTree(truthTrackCol.cptr(),mcEventCollection.cptr(),muonSimData,cscSimDataMap.cptr());
       }
+    } else {
+      truth_tree = m_muonTrackTruthTool->createTruthTree(truthTrackCol.cptr(),mcEventCollection.cptr(),muonSimData,nullptr);
     }
-    else m_muonTrackTruthTool->createTruthTree(truthTrackCol.cptr(),mcEventCollection.cptr(),muonSimData,nullptr);
     ATH_MSG_DEBUG("Matching reconstructed segments " << muonSegments.size() );
-    IMuonTrackTruthTool::SegmentResultVec segmentMatchResult = m_muonTrackTruthTool->match(muonSegments);
+    IMuonTrackTruthTool::SegmentResultVec segmentMatchResult = m_muonTrackTruthTool->match(truth_tree, muonSegments);
 
     // create a map of chamber index onto the truth segments
     std::map<Muon::MuonStationIndex::ChIndex, std::vector<ElementLink< xAOD::MuonSegmentContainer> > > chamberTruthSegmentLinks;
diff --git a/MuonSpectrometer/MuonTruthAlgs/src/MuonSegmentTruthAssociationAlg.h b/MuonSpectrometer/MuonTruthAlgs/src/MuonSegmentTruthAssociationAlg.h
index d3d0a4979d7d836d085160bdce3cc2db59274a54..b38bd05e724a76bcefa9d4fba74f4270118d240a 100644
--- a/MuonSpectrometer/MuonTruthAlgs/src/MuonSegmentTruthAssociationAlg.h
+++ b/MuonSpectrometer/MuonTruthAlgs/src/MuonSegmentTruthAssociationAlg.h
@@ -1,11 +1,11 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRUTHPARTICLEALGS_MUONSEGMENTTRUTHASSOCIATION_H
 #define TRUTHPARTICLEALGS_MUONSEGMENTTRUTHASSOCIATION_H
 
-#include "AthenaBaseComps/AthAlgorithm.h"
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
 #include "GaudiKernel/ServiceHandle.h"
 #include "GaudiKernel/ToolHandle.h"
 
@@ -23,15 +23,15 @@
 
 namespace Muon {
 
-class MuonSegmentTruthAssociationAlg : public AthAlgorithm  {
+class MuonSegmentTruthAssociationAlg : public AthReentrantAlgorithm  {
 
 public:
   // Constructor with parameters:
   MuonSegmentTruthAssociationAlg(const std::string &name,ISvcLocator *pSvcLocator);
 
   // Basic algorithm methods:
-  virtual StatusCode initialize();
-  virtual StatusCode execute();
+  virtual StatusCode initialize() override;
+  virtual StatusCode execute(const EventContext& ctx) const override;
 
 private:
   ServiceHandle<Muon::IMuonIdHelperSvc> m_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"};
diff --git a/MuonSpectrometer/MuonTruthAlgs/src/MuonTrackTruthTool.cxx b/MuonSpectrometer/MuonTruthAlgs/src/MuonTrackTruthTool.cxx
index 8b81b7eee306aa984769b9aca88e33359814d6f3..97994280275cca783faa26f8ef42999361d2bd4c 100644
--- a/MuonSpectrometer/MuonTruthAlgs/src/MuonTrackTruthTool.cxx
+++ b/MuonSpectrometer/MuonTruthAlgs/src/MuonTrackTruthTool.cxx
@@ -76,7 +76,8 @@ namespace Muon {
 
 
 
-  MuonTrackTruthTool::ResultVec MuonTrackTruthTool::match( const TrackCollection& tracks ) const {
+  MuonTrackTruthTool::ResultVec MuonTrackTruthTool::match(const TruthTree& truth_tree,   
+                                                          const TrackCollection& tracks ) const {
     ResultVec result;
     result.reserve(tracks.size());
     
@@ -85,7 +86,7 @@ namespace Muon {
     TrackCollection::const_iterator tit_end = tracks.end();
     for( ;tit!=tit_end;++tit ){
 
-      MuonTrackTruth match = getTruth(**tit);
+      MuonTrackTruth match = getTruth(truth_tree, **tit);
       if( !match.truthTrack ) continue;
 
       if( match.numberOfMatchedHits() == 0 ) continue;
@@ -100,7 +101,8 @@ namespace Muon {
     return result;
   }
 
-  MuonTrackTruthTool::SegmentResultVec MuonTrackTruthTool::match(const std::vector<const MuonSegment*>& segments ) const {
+  MuonTrackTruthTool::SegmentResultVec MuonTrackTruthTool::match(const TruthTree& truth_tree,  
+                                                                 const std::vector<const MuonSegment*>& segments ) const {
     SegmentResultVec result;
     result.reserve(segments.size());
 
@@ -110,7 +112,7 @@ namespace Muon {
     for( ;sit!=sit_end;++sit ){
       
       // create truth association 
-      result.push_back( std::make_pair(*sit,getTruth(**sit)) );    
+      result.push_back( std::make_pair(*sit,getTruth(truth_tree, **sit)) );    
     }
     
     // sort result per muon and per number of matched hits
@@ -123,11 +125,11 @@ namespace Muon {
 									   std::vector<const MuonSimDataCollection*> muonSimData, const CscSimDataCollection* cscSimDataMap) const {
 
     
-    clear();
-
+    std::map<int,int> barcode_map;
+    MuonTrackTruthTool::TruthTree truth_tree;
     if( truthTrackCol->empty() ) {
       ATH_MSG_WARNING(" TrackRecordCollection is empty ");
-      return m_truthTree;
+      return truth_tree;
     }
 
     const HepMC::GenEvent* genEvent = nullptr;
@@ -150,8 +152,8 @@ namespace Muon {
       }
 
       // check whether barcode is already in, skip if that is the case
-      if( m_barcodeMap.count(barcode) ){
-	ATH_MSG_VERBOSE(" barcode " << barcode << " already in map, final state barcode " << m_barcodeMap[barcode]);	  
+      if( barcode_map.count(barcode) ){
+	ATH_MSG_VERBOSE(" barcode " << barcode << " already in map, final state barcode " << barcode_map[barcode]);	  
 	continue;
       }
       ATH_MSG_VERBOSE(" found new particle with pdgid " << PDGCode << " in truth record, barcode " << barcode);
@@ -199,45 +201,46 @@ namespace Muon {
                 if( (*pit)->production_vertex() ) ATH_MSG_VERBOSE(" vertex: r  " << (*pit)->production_vertex()->position().perp() 
                                                                     << " z " << (*pit)->production_vertex()->position().z());
 		// sanity check 
-		if( m_barcodeMap.count(code) ) ATH_MSG_VERBOSE("  pre-existing barcode " << code);
+		if( barcode_map.count(code) ) ATH_MSG_VERBOSE("  pre-existing barcode " << code);
 	      }
 		
 	      // enter barcode
-	      m_barcodeMap[code] = barcode;
+	      barcode_map[code] = barcode;
 	    }
 	  }else{
 	    ATH_MSG_WARNING(" empty truth trajectory " << barcode);
 	  }
 	}
       }else{
-	// add one to one relation
-	m_barcodeMap[barcode] = barcode;
+        // add one to one relation
+        barcode_map[barcode] = barcode;
       }
       
-      if( m_truthTree.count(barcode) ) {
+      if( truth_tree.count(barcode) ) {
 	ATH_MSG_WARNING(" found muon barcode twice in truth record: " << barcode);
 	continue;
       }
 	
-      TruthTreeEntry& entry = m_truthTree[barcode];
+      TruthTreeEntry& entry = truth_tree[barcode];
       entry.truthTrack = &(*tr_it);
-      entry.truthTrajectory = truthTrajectory.get();
-      m_truthTrajectoriesToBeDeleted.push_back(std::move(truthTrajectory));
+      //entry.truthTrajectory = truthTrajectory.get();
+      entry.truthTrajectory = std::move(truthTrajectory);
+      //m_truthTrajectoriesToBeDeleted.push_back(std::move(truthTrajectory));
     }
     
     // add sim data collections
     for(const MuonSimDataCollection* simDataMap : muonSimData){
-      addSimDataToTree(simDataMap);
+      addSimDataToTree(truth_tree, barcode_map,simDataMap);
     }
     if(cscSimDataMap){
-      addCscSimDataToTree(cscSimDataMap);
+      addCscSimDataToTree(truth_tree, barcode_map,cscSimDataMap);
     }
 
     unsigned int ngood(0);
     std::vector<int> badBarcodes;
     // erase entries with too few hits or no track record
-    TruthTreeIt it = m_truthTree.begin();
-    for( ;it!=m_truthTree.end();++it ){
+    TruthTreeIt it = truth_tree.begin();
+    for( ;it!=truth_tree.end();++it ){
       bool erase = false;
       unsigned int nhits = it->second.mdtHits.size() + it->second.rpcHits.size() + it->second.tgcHits.size() + 
 	it->second.cscHits.size() + it->second.stgcHits.size() + it->second.mmHits.size();
@@ -257,17 +260,17 @@ namespace Muon {
     
     std::vector<int>::iterator badIt = badBarcodes.begin();
     std::vector<int>::iterator badIt_end = badBarcodes.end();
-    for( ;badIt!=badIt_end;++badIt ) m_truthTree.erase(*badIt);
+    for( ;badIt!=badIt_end;++badIt ) truth_tree.erase(*badIt);
 
-    if( ngood != m_truthTree.size() ){
-      ATH_MSG_WARNING(" Problem cleaning map: size " << m_truthTree.size() << " accepted entries " << ngood);
+    if( ngood != truth_tree.size() ){
+      ATH_MSG_WARNING(" Problem cleaning map: size " << truth_tree.size() << " accepted entries " << ngood);
     }
     
     
     if( m_doSummary || msgLvl(MSG::DEBUG) ){
-      ATH_MSG_INFO(" summarizing truth tree: number of particles " << m_truthTree.size());
-      TruthTreeIt it = m_truthTree.begin();
-      TruthTreeIt it_end = m_truthTree.end();
+      ATH_MSG_INFO(" summarizing truth tree: number of particles " << truth_tree.size());
+      TruthTreeIt it = truth_tree.begin();
+      TruthTreeIt it_end = truth_tree.end();
       for( ;it!=it_end;++it ){
 	if( !it->second.truthTrack ) ATH_MSG_INFO(" no TrackRecord ");
 	else{
@@ -285,11 +288,13 @@ namespace Muon {
       }
     }
 
-    return m_truthTree;
+    return truth_tree;
   }
 
 
-  void MuonTrackTruthTool::addSimDataToTree( const MuonSimDataCollection* simDataCol ) const {
+  void MuonTrackTruthTool::addSimDataToTree(TruthTree& truth_tree,
+                                            std::map<int,int>& barcode_map, 
+                                            const MuonSimDataCollection* simDataCol ) const {
 
     // loop over sim collection and check whether identifiers are on track
     MuonSimDataCollection::const_iterator it = simDataCol->begin();
@@ -303,16 +308,16 @@ namespace Muon {
       std::vector<MuonSimData::Deposit>::const_iterator dit_end = it->second.getdeposits().end();
       for( ;dit!=dit_end;++dit ){
         int barcodeIn = dit->first.barcode();
-	std::map<int,int>::iterator bit = m_barcodeMap.find(barcodeIn);
-	if( bit == m_barcodeMap.end() ){
+	std::map<int,int>::const_iterator bit = barcode_map.find(barcodeIn);
+	if( bit == barcode_map.end() ){
 	  ATH_MSG_VERBOSE( " discarding " << "  " << m_idHelperSvc->toString(id) << "   barcode " << barcodeIn);
 	  continue;
 	}
 	// replace barcode with barcode from map
 	int barcode = bit->second;
 
-	TruthTreeIt eit = m_truthTree.find(barcode);
-	if( eit == m_truthTree.end() ){
+	TruthTreeIt eit = truth_tree.find(barcode);
+	if( eit == truth_tree.end() ){
 	  ATH_MSG_VERBOSE( " discarding " << "  " << m_idHelperSvc->toString(id) << "   barcode " << barcode);
 	  continue;
 	}
@@ -367,7 +372,7 @@ namespace Muon {
     }    
   }
 
-  void MuonTrackTruthTool::addCscSimDataToTree( const CscSimDataCollection* simDataCol ) const {
+  void MuonTrackTruthTool::addCscSimDataToTree(TruthTree& truth_tree, std::map<int,int>& barcode_map, const CscSimDataCollection* simDataCol ) const {
 
     // loop over sim collection and check whether identifiers are on track
     CscSimDataCollection::const_iterator it = simDataCol->begin();
@@ -382,16 +387,16 @@ namespace Muon {
       for( ;dit!=dit_end;++dit ){
 
 	int barcodeIn = manipulateBarCode(dit->first.barcode());
-	std::map<int,int>::iterator bit = m_barcodeMap.find(barcodeIn);
-	if( bit == m_barcodeMap.end() ){
+	std::map<int,int>::const_iterator bit = barcode_map.find(barcodeIn);
+	if( bit == barcode_map.end() ){
 	  ATH_MSG_VERBOSE( " discarding " << "  " << m_idHelperSvc->toString(id) << "   barcode " << barcodeIn);
 	  continue;
 	}
 	// replace barcode with barcode from map
 	int barcode = bit->second;
 
-	TruthTreeIt eit = m_truthTree.find(barcode);
-	if( eit == m_truthTree.end() ){
+	TruthTreeIt eit = truth_tree.find(barcode);
+	if( eit == truth_tree.end() ){
 	  ATH_MSG_VERBOSE( " discarding " << "  " << m_idHelperSvc->toString(id) << "   barcode " << barcode);
 	  continue;
 	}
@@ -405,18 +410,23 @@ namespace Muon {
     }    
   }
 
-  MuonTrackTruth MuonTrackTruthTool::getTruth( const Muon::MuonSegment& segment ) const {
+  MuonTrackTruth MuonTrackTruthTool::getTruth(const TruthTree& truth_tree,   
+                                              const Muon::MuonSegment& segment ) const {
 
-    return getTruth(segment.containedMeasurements(),true);
+    return getTruth(truth_tree, segment.containedMeasurements(),true);
   }
 
 
-  MuonTrackTruth MuonTrackTruthTool::getTruth( const Trk::Track& track, bool restrictedTruth ) const {
-    if( track.measurementsOnTrack() ) return getTruth(track.measurementsOnTrack()->stdcont(),restrictedTruth);
+  MuonTrackTruth MuonTrackTruthTool::getTruth( const TruthTree& truth_tree,  
+                                               const Trk::Track& track, 
+                                               bool restrictedTruth ) const {
+    if( track.measurementsOnTrack() ) return getTruth(truth_tree, track.measurementsOnTrack()->stdcont(),restrictedTruth);
     return MuonTrackTruth();
   }
 
-  MuonTrackTruth MuonTrackTruthTool::getTruth( const std::vector<const MuonSegment*>& segments, bool restrictedTruth ) const {
+  MuonTrackTruth MuonTrackTruthTool::getTruth(const TruthTree& truth_tree,   
+                                              const std::vector<const MuonSegment*>& segments, 
+                                              bool restrictedTruth ) const {
     Trk::RoT_Extractor rotExtractor;
     std::set<Identifier> ids;
     std::vector<const Trk::MeasurementBase*> measurements;
@@ -440,12 +450,13 @@ namespace Muon {
 	ids.insert(id);
       }
     }
-    return getTruth(measurements,restrictedTruth);
+    return getTruth(truth_tree, measurements,restrictedTruth);
   }
 
 
-  MuonTrackTruth MuonTrackTruthTool::getTruth( const std::vector<const Trk::MeasurementBase*>& measurements,
-					       bool restrictedTruth ) const {
+  MuonTrackTruth MuonTrackTruthTool::getTruth(const TruthTree& truth_tree,   
+                                              const std::vector<const Trk::MeasurementBase*>& measurements,
+					                          bool restrictedTruth ) const {
 
     MuonTrackTruth bestMatch;
     bestMatch.truthTrack = 0;
@@ -453,8 +464,8 @@ namespace Muon {
 
     unsigned int   nmatchedHitsBest = 0;
     // loop over muons and match hits
-    TruthTreeIt tit = m_truthTree.begin();
-    TruthTreeIt tit_end = m_truthTree.end();
+    TruthTreeConstIt tit = truth_tree.begin();
+    TruthTreeConstIt tit_end = truth_tree.end();
     for( ;tit!=tit_end;++tit ){
       
       unsigned int nhits = tit->second.mdtHits.size() + tit->second.cscHits.size() + tit->second.rpcHits.size() + tit->second.tgcHits.size() 
@@ -474,8 +485,8 @@ namespace Muon {
     return bestMatch;
   }
 
-  MuonTrackTruth MuonTrackTruthTool::getTruth( const std::vector<const Trk::MeasurementBase*>& measurements,
-                                               TruthTreeEntry& truthEntry, bool restrictedTruth ) const {
+  MuonTrackTruth MuonTrackTruthTool::getTruth(const std::vector<const Trk::MeasurementBase*>& measurements,
+                                              const TruthTreeEntry& truthEntry, bool restrictedTruth ) const {
     
     Trk::RoT_Extractor rotExtractor;
     MuonTrackTruth trackTruth;
@@ -492,7 +503,7 @@ namespace Muon {
         continue;
       }
 
-      const Trk::RIO_OnTrack* rot = 0;
+      const Trk::RIO_OnTrack* rot = nullptr;
       rotExtractor.extract(rot,meas);
       if( !rot ) {
         if( !dynamic_cast<const Trk::PseudoMeasurementOnTrack*>(meas) ) ATH_MSG_WARNING(" Could not get rot from measurement ");
@@ -704,12 +715,6 @@ namespace Muon {
     }
   }
 
-  void MuonTrackTruthTool::clear() const {
-    m_truthTree.clear();
-    m_barcodeMap.clear();
-    m_truthTrajectoriesToBeDeleted.clear();
-  }
-
   HepMC::ConstGenParticlePtr MuonTrackTruthTool::getMother( const TruthTrajectory& traj, const int barcodeIn ) const {
     ATH_MSG_DEBUG( "getMother() : size = " << traj.size() );
     int pdgFinal = ( (traj.size()==0)?  -999 : traj.front()->pdg_id());
diff --git a/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthAssociationAlg.cxx b/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthAssociationAlg.cxx
index 902d2082c81f56edbba73422de49b1088e435a44..9e1e1fb204f3fe0a958e22261863521ecfeac68b 100644
--- a/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthAssociationAlg.cxx
+++ b/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthAssociationAlg.cxx
@@ -10,9 +10,16 @@
 #include "MuonCompetingRIOsOnTrack/CompetingMuonClustersOnTrack.h"
 #include "StoreGate/WriteDecorHandle.h"
 
+namespace {
+    constexpr unsigned int dummy_unsigned = 999;
+    void increment_unsigned(unsigned& val){
+        if (val == dummy_unsigned) val = 1;
+        else ++val;
+    }
+}
 // Constructor with parameters:
 MuonTruthAssociationAlg::MuonTruthAssociationAlg(const std::string &name, ISvcLocator *pSvcLocator) :
-  AthAlgorithm(name,pSvcLocator)
+  AthReentrantAlgorithm(name,pSvcLocator)
 {}
 
 // Initialize method:
@@ -40,26 +47,25 @@ StatusCode MuonTruthAssociationAlg::initialize()
 }
 
 // Execute method:
-StatusCode MuonTruthAssociationAlg::execute() 
-{
+StatusCode MuonTruthAssociationAlg::execute(const EventContext& ctx) const {
 
-  SG::WriteDecorHandle<xAOD::TruthParticleContainer,ElementLink< xAOD::MuonContainer > > muonTruthParticleRecoLink(m_muonTruthParticleContainerName);
+  SG::WriteDecorHandle<xAOD::TruthParticleContainer,ElementLink< xAOD::MuonContainer > > muonTruthParticleRecoLink(m_muonTruthParticleContainerName,ctx);
   if(!muonTruthParticleRecoLink.isPresent()) return StatusCode::SUCCESS;
   if(!muonTruthParticleRecoLink.isValid()){
     ATH_MSG_WARNING("truth particle container not valid");
     return StatusCode::FAILURE;
   }
-  SG::WriteDecorHandle<xAOD::MuonContainer,ElementLink<xAOD::TruthParticleContainer> > muonTruthParticleLink(m_muonTruthParticleLink);
+  SG::WriteDecorHandle<xAOD::MuonContainer,ElementLink<xAOD::TruthParticleContainer> > muonTruthParticleLink(m_muonTruthParticleLink,ctx);
   if(!muonTruthParticleLink.isPresent()) return StatusCode::SUCCESS;
   if(!muonTruthParticleLink.isValid()){
     ATH_MSG_WARNING("muon particle container not valid");
     return StatusCode::FAILURE;
   }
-  SG::WriteDecorHandle<xAOD::MuonContainer,int > muonTruthParticleType(m_muonTruthParticleType);
-  SG::WriteDecorHandle<xAOD::MuonContainer,int > muonTruthParticleOrigin(m_muonTruthParticleOrigin);
-  SG::WriteDecorHandle<xAOD::MuonContainer,std::vector<unsigned int> > muonTruthParticleNPrecMatched(m_muonTruthParticleNPrecMatched);
-  SG::WriteDecorHandle<xAOD::MuonContainer,std::vector<unsigned int> > muonTruthParticleNPhiMatched(m_muonTruthParticleNPhiMatched);
-  SG::WriteDecorHandle<xAOD::MuonContainer,std::vector<unsigned int> > muonTruthParticleNTrigEtaMatched(m_muonTruthParticleNTrigEtaMatched);
+  SG::WriteDecorHandle<xAOD::MuonContainer,int > muonTruthParticleType(m_muonTruthParticleType,ctx);
+  SG::WriteDecorHandle<xAOD::MuonContainer,int > muonTruthParticleOrigin(m_muonTruthParticleOrigin,ctx);
+  SG::WriteDecorHandle<xAOD::MuonContainer,std::vector<unsigned int> > muonTruthParticleNPrecMatched(m_muonTruthParticleNPrecMatched,ctx);
+  SG::WriteDecorHandle<xAOD::MuonContainer,std::vector<unsigned int> > muonTruthParticleNPhiMatched(m_muonTruthParticleNPhiMatched,ctx);
+  SG::WriteDecorHandle<xAOD::MuonContainer,std::vector<unsigned int> > muonTruthParticleNTrigEtaMatched(m_muonTruthParticleNTrigEtaMatched,ctx);
     
   // add link to reco muons and viceversa
   
@@ -68,276 +74,191 @@ StatusCode MuonTruthAssociationAlg::execute()
   for( const auto muon : *muonTruthParticleLink ){
     // use primary track particle to get the truth link (except for the case of STACO, where we must use the ID track particle, as the combined is not truth-matched)
     ATH_MSG_DEBUG("muon with pT "<<muon->pt()<<" and author "<<muon->author());
-    const xAOD::TrackParticle* tp(0);
-    if (m_associateWithInDetTP || muon->author()==2 || muon->author()==6 ) {
+    const xAOD::TrackParticle* tp= nullptr;
+    if (m_associateWithInDetTP || muon->author()==xAOD::Muon::STACO || muon->author()==xAOD::Muon::MuGirl) {
       tp = muon->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
-    } 
-    else{
+    } else{
       tp=muon->primaryTrackParticle();
     }
     
-    if( !tp ){
-      ATH_MSG_DEBUG("no track particle associated?");
-      muonTruthParticleLink(*muon)=ElementLink<xAOD::TruthParticleContainer>();
-      muonTruthParticleOrigin(muonInd)=-99999;
-      muonTruthParticleType(muonInd)=-99999;
-      //add these empty vectors
-      std::vector<unsigned int> nprecHitsPerChamberLayer;
-      std::vector<unsigned int> nphiHitsPerChamberLayer;
-      std::vector<unsigned int> ntrigEtaHitsPerChamberLayer;
-      muonTruthParticleNPrecMatched(muonInd)=nprecHitsPerChamberLayer;
-      muonTruthParticleNPhiMatched(muonInd)=nphiHitsPerChamberLayer;
-      muonTruthParticleNTrigEtaMatched(muonInd)=ntrigEtaHitsPerChamberLayer;
-      continue;
+    bool foundTruth=false;
+    
+    if (tp){
+        // Associate reco with truth muon. Loop over reconstructed muons, get track particle for each one. 
+        //Each track particle should carry a link to the corresponding truth particle. Then compare this truth particle link with the given truth muon particle
+        try {
+              ElementLink< xAOD::TruthParticleContainer > truthLink = tp->auxdata<ElementLink< xAOD::TruthParticleContainer > >("truthParticleLink");
+              if (truthLink.isValid() ){
+                ATH_MSG_VERBOSE(" Got valid truth link for muon author " << muon->author() << " barcode " << (*truthLink)->barcode());
+                // loop over truth particles
+                
+                for( const auto truthParticle : *muonTruthParticleRecoLink ){
+                    if( truthParticle->status() != 1 ) continue;
+                    ATH_MSG_DEBUG("Got truth muon with barcode " << truthParticle->barcode() << " pt "<< truthParticle->pt());
+                    ElementLink< xAOD::MuonContainer > muonLink;
+                    if( ((*truthLink)->barcode())%m_barcodeOffset != truthParticle->barcode() ) {
+                        continue;
+                    }
+                    ATH_MSG_VERBOSE("Truth muon barcode matches -> creating link with truth particle " << (*truthLink)->barcode() );
+                    foundTruth=true;
+                    muonLink = ElementLink< xAOD::MuonContainer >(muon,*muonTruthParticleLink);
+                    // add the link from xAOD::Muon to TruthParticle in m_muonTruthParticleContainerName
+                    ElementLink< xAOD::TruthParticleContainer > muonTruthLink = ElementLink< xAOD::TruthParticleContainer >(truthParticle, *muonTruthParticleRecoLink);
+                    muonTruthLink.toPersistent();
+                    muonTruthParticleLink(*muon)=muonTruthLink;
+                    muonTruthParticleOrigin(muonInd)=tp->auxdata<int>("truthOrigin");
+                    muonTruthParticleType(muonInd)=tp->auxdata<int>("truthType");
+                   
+                    /// Zero supression do not want to store meaningless zeros
+                    std::vector<unsigned int> nprecHitsPerChamberLayer(Muon::MuonStationIndex::ChIndexMax, dummy_unsigned);
+                    std::vector<unsigned int> nphiHitsPerChamberLayer(Muon::MuonStationIndex::PhiIndexMax, dummy_unsigned);
+                    std::vector<unsigned int> ntrigEtaHitsPerChamberLayer(Muon::MuonStationIndex::PhiIndexMax, dummy_unsigned);
+                    
+                    count_chamber_layers( (muon->author()==xAOD::Muon::MuidCo || muon->author()==xAOD::Muon::MuidSA || muon->author()==xAOD::Muon::MuGirl)? truthParticle: nullptr,  
+                              tp->track(),
+                              nprecHitsPerChamberLayer,
+                              nphiHitsPerChamberLayer,
+                              ntrigEtaHitsPerChamberLayer );              
+                    /// Decorate the results
+                    muonTruthParticleNPrecMatched(muonInd)=nprecHitsPerChamberLayer;
+                    muonTruthParticleNPhiMatched(muonInd)=nphiHitsPerChamberLayer;
+                    muonTruthParticleNTrigEtaMatched(muonInd)=ntrigEtaHitsPerChamberLayer;	      
+                
+                    muonLink.toPersistent();
+                    muonTruthParticleRecoLink(*truthParticle)=muonLink;
+                    break;
+                }
+            }    
+         } catch ( const SG::ExcBadAuxVar& ) {
+          ATH_MSG_WARNING("Track particle is missing truthParticleLink variable!");
+        }
     }
     
-    // Associate reco with truth muon. Loop over reconstructed muons, get track particle for each one. 
-    //Each track particle should carry a link to the corresponding truth particle. Then compare this truth particle link with the given truth muon particle
-    try {
-      ElementLink< xAOD::TruthParticleContainer > truthLink = tp->auxdata<ElementLink< xAOD::TruthParticleContainer > >("truthParticleLink");
-      if( truthLink.isValid() ){
-      	ATH_MSG_VERBOSE(" Got valid truth link for muon author " << muon->author() << " barcode " << (*truthLink)->barcode());
-	// loop over truth particles
-	bool foundTruth=false;
-	for( const auto truthParticle : *muonTruthParticleRecoLink ){
-	  if( truthParticle->status() != 1 ) continue;
-	  ATH_MSG_DEBUG("Got truth muon with barcode " << truthParticle->barcode() << " pt "<< truthParticle->pt());
-	  ElementLink< xAOD::MuonContainer > muonLink;
-	  
-	  if( ((*truthLink)->barcode())%m_barcodeOffset == truthParticle->barcode() ) {
-	    ATH_MSG_VERBOSE("Truth muon barcode matches -> creating link with truth particle " << (*truthLink)->barcode() );
-	    foundTruth=true;
-	    muonLink = ElementLink< xAOD::MuonContainer >(muon,*muonTruthParticleLink);
-	    // add the link from xAOD::Muon to TruthParticle in m_muonTruthParticleContainerName
-	    ElementLink< xAOD::TruthParticleContainer > muonTruthLink = ElementLink< xAOD::TruthParticleContainer >(truthParticle, *muonTruthParticleRecoLink);
-	    muonTruthLink.toPersistent();
-	    muonTruthParticleLink(*muon)=muonTruthLink;
-	    muonTruthParticleOrigin(muonInd)=tp->auxdata<int>("truthOrigin");
-	    muonTruthParticleType(muonInd)=tp->auxdata<int>("truthType");
-	    if(muon->author()==1 || muon->author()==5 || muon->author()==6){ //only match hits for muons with MS tracks
-	      if(!truthParticle->isAvailable<std::vector<unsigned long long> >("truthMdtHits")){
-		ATH_MSG_DEBUG("muon with author "<<muon->author()<<" has no truth hits vector in the truth association alg");
-	      }
-	      else{
-		std::vector<unsigned long long> mdtTruth=truthParticle->auxdata<std::vector<unsigned long long> >("truthMdtHits");
-		std::vector<unsigned long long> cscTruth;
-		if(m_idHelperSvc->hasCSC()) cscTruth=truthParticle->auxdata<std::vector<unsigned long long> >("truthCscHits");
-		std::vector<unsigned long long> rpcTruth=truthParticle->auxdata<std::vector<unsigned long long> >("truthRpcHits");
-		std::vector<unsigned long long> tgcTruth=truthParticle->auxdata<std::vector<unsigned long long> >("truthTgcHits");
-		const Trk::Track* ptrk=tp->track();
-		const DataVector<const Trk::TrackStateOnSurface>* trkstates = ptrk->trackStateOnSurfaces();
-		DataVector<const Trk::TrackStateOnSurface>::const_reverse_iterator tsit = trkstates->rbegin();
-		DataVector<const Trk::TrackStateOnSurface>::const_reverse_iterator tsit_end = trkstates->rend();
-		std::vector<unsigned int> nprecHitsPerChamberLayer;
-		std::vector<unsigned int> nphiHitsPerChamberLayer;
-		std::vector<unsigned int> ntrigEtaHitsPerChamberLayer;
-		nprecHitsPerChamberLayer.resize(Muon::MuonStationIndex::ChIndexMax);
-		nphiHitsPerChamberLayer.resize(Muon::MuonStationIndex::PhiIndexMax);
-		ntrigEtaHitsPerChamberLayer.resize(Muon::MuonStationIndex::PhiIndexMax);
-		//zero-suppression: don't want to store meaningless zeroes (no truth or reco hits found)
-		for(unsigned int i=0;i<nprecHitsPerChamberLayer.size();i++) nprecHitsPerChamberLayer[i]=999;
-		for(unsigned int i=0;i<nphiHitsPerChamberLayer.size();i++) nphiHitsPerChamberLayer[i]=999;
-		for(unsigned int i=0;i<ntrigEtaHitsPerChamberLayer.size();i++) ntrigEtaHitsPerChamberLayer[i]=999;
-		for( ; tsit!=tsit_end ; ++tsit ){
-		  if(!*tsit) continue;
-		  if(!(*tsit)->trackParameters() || !(*tsit)->measurementOnTrack()) continue;
-		  const Trk::MeasurementBase* meas = (*tsit)->measurementOnTrack();
-		  Identifier id;
-		  const Trk::RIO_OnTrack* rot = dynamic_cast<const Trk::RIO_OnTrack*>(meas);
-		  if(rot) id=rot->identify();
-		  else{
-		    const Muon::CompetingMuonClustersOnTrack* crot = dynamic_cast<const Muon::CompetingMuonClustersOnTrack*>(meas);
-		    if(crot){
-		      if( !crot->containedROTs().empty() && crot->containedROTs().front() ) id=crot->containedROTs().front()->identify();
-		    }
-		  }
-		  if(!m_idHelperSvc->isMuon(id)) continue;
-		  bool measPhi = m_idHelperSvc->measuresPhi(id);
-		  bool isTgc = m_idHelperSvc->isTgc(id);
-		  Muon::MuonStationIndex::ChIndex chIndex = !isTgc ? m_idHelperSvc->chamberIndex(id) : Muon::MuonStationIndex::ChUnknown;
-		  bool found=false;
-		  for(unsigned int i=0;i<mdtTruth.size();i++){
-		    if(id==mdtTruth[i]){
-		      if(nprecHitsPerChamberLayer[chIndex]==999) nprecHitsPerChamberLayer[chIndex]=1;
-		      else ++nprecHitsPerChamberLayer[chIndex];
-		      found=true;
-		      break;
-		    }
-		  }
-		  if(found) continue;
-		  if(m_idHelperSvc->hasCSC()){
-		    for(unsigned int i=0;i<cscTruth.size();i++){
-		      if(id==cscTruth[i]){
-			if( measPhi ) {
-			  Muon::MuonStationIndex::PhiIndex index = m_idHelperSvc->phiIndex(id);
-			  if(nphiHitsPerChamberLayer[index]==999) nphiHitsPerChamberLayer[index]=1;
-			  else ++nphiHitsPerChamberLayer[index];
-			}
-			else{
-			  if(nprecHitsPerChamberLayer[chIndex]==999) nprecHitsPerChamberLayer[chIndex]=1;
-			  else ++nprecHitsPerChamberLayer[chIndex];
-			}
-			found=true;
-			break;
-		      }
-		    }
-		  }
-		  if(found) continue;
-		  for(unsigned int i=0;i<rpcTruth.size();i++){
-		    if(id==rpcTruth[i]){
-		      int index = m_idHelperSvc->phiIndex(id);
-		      if( measPhi ){
-			if(nphiHitsPerChamberLayer[index]==999) nphiHitsPerChamberLayer[index]=1;
-			else ++nphiHitsPerChamberLayer[index];
-		      }
-		      else{
-			if(ntrigEtaHitsPerChamberLayer[index]==999) ntrigEtaHitsPerChamberLayer[index]=1;
-			else ++ntrigEtaHitsPerChamberLayer[index];
-		      }
-		      found=true;
-		      break;
-		    }
-		  }
-		  if(found) continue;
-		  for(unsigned int i=0;i<tgcTruth.size();i++){
-		    if(id==tgcTruth[i]){
-		      int index = m_idHelperSvc->phiIndex(id);
-		      if( measPhi ){
-			if(nphiHitsPerChamberLayer[index]==999) nphiHitsPerChamberLayer[index]=1;
-			else ++nphiHitsPerChamberLayer[index];
-		      }
-		      else{
-			if(ntrigEtaHitsPerChamberLayer[index]==999) ntrigEtaHitsPerChamberLayer[index]=1;
-			else ++ntrigEtaHitsPerChamberLayer[index];
-		      }
-		      found=true;
-		      break;
-		    }
-		  }
-		} //end loop over TSOS
-		ATH_MSG_DEBUG("finished loop over TSOS");
-		//now, have to check if there are non-zero truth hits in indices without reco hits
-		for(unsigned int i=0;i<nprecHitsPerChamberLayer.size();i++){
-		  if(nprecHitsPerChamberLayer[i]==999){
-		    bool found=false;
-		    for(unsigned int j=0;j<mdtTruth.size();j++){
-		      Identifier id(mdtTruth[j]);
-		      if(m_idHelperSvc->chamberIndex(id)==(Muon::MuonStationIndex::ChIndex)i){ nprecHitsPerChamberLayer[i]=0; found=true; break;}
-		    }
-		    if(found) continue;
-		    if(m_idHelperSvc->hasCSC()){
-		      for(unsigned int j=0;j<cscTruth.size();j++){
-			Identifier id(cscTruth[j]);
-			if(!m_idHelperSvc->measuresPhi(id)){
-			  if(m_idHelperSvc->chamberIndex(id)==(Muon::MuonStationIndex::ChIndex)i){ nprecHitsPerChamberLayer[i]=0; break;}
-			}
-		      }
-		    }
-		  }
-		}
-		for(unsigned int i=0;i<nphiHitsPerChamberLayer.size();i++){
-		  if(nphiHitsPerChamberLayer[i]==999){
-		    bool found=false;
-		    if(m_idHelperSvc->hasCSC()){
-		      for(unsigned int j=0;j<cscTruth.size();j++){
-			Identifier id(cscTruth[j]);
-			if(m_idHelperSvc->measuresPhi(id)){
-			  if(m_idHelperSvc->phiIndex(id)==(Muon::MuonStationIndex::PhiIndex)i){nphiHitsPerChamberLayer[i]=0; found=true; break;}
-			}
-		      }
-		    }
-		    if(found) continue;
-		    for(unsigned int j=0;j<rpcTruth.size();j++){
-		      Identifier id(rpcTruth[j]);
-		      if(m_idHelperSvc->measuresPhi(id)){
-			if(m_idHelperSvc->phiIndex(id)==(Muon::MuonStationIndex::PhiIndex)i){nphiHitsPerChamberLayer[i]=0; found=true; break;}
-		      }
-		    }
-		    if(found) continue;
-		    for(unsigned int j=0;j<tgcTruth.size();j++){
-		      Identifier id(tgcTruth[j]);
-		      if(m_idHelperSvc->measuresPhi(id)){
-			if(m_idHelperSvc->phiIndex(id)==(Muon::MuonStationIndex::PhiIndex)i){nphiHitsPerChamberLayer[i]=0; break;}
-		      }
-		    }
-		  }
-		}
-		for(unsigned int i=0;i<ntrigEtaHitsPerChamberLayer.size();i++){
-		  if(ntrigEtaHitsPerChamberLayer[i]==999){
-		    bool found=false;
-		    for(unsigned int j=0;j<rpcTruth.size();j++){
-		      Identifier id(rpcTruth[j]);
-		      if(!m_idHelperSvc->measuresPhi(id)){
-			if(m_idHelperSvc->phiIndex(id)==(Muon::MuonStationIndex::PhiIndex)i){nphiHitsPerChamberLayer[i]=0; found=true; break;}
-		      }
-		    }
-		    if(found) continue;
-		    for(unsigned int j=0;j<tgcTruth.size();j++){
-		      Identifier id(tgcTruth[j]);
-		      if(!m_idHelperSvc->measuresPhi(id)){
-			if(m_idHelperSvc->phiIndex(id)==(Muon::MuonStationIndex::PhiIndex)i){nphiHitsPerChamberLayer[i]=0; break;}
-		      }
-		    }
-		  }
-		}
-		muonTruthParticleNPrecMatched(muonInd)=nprecHitsPerChamberLayer;
-		muonTruthParticleNPhiMatched(muonInd)=nphiHitsPerChamberLayer;
-		muonTruthParticleNTrigEtaMatched(muonInd)=ntrigEtaHitsPerChamberLayer;
-	      }
-	    }
-	    muonLink.toPersistent();
-	    muonTruthParticleRecoLink(*truthParticle)=muonLink;
-	    break;
-	  }
-	}
-	if(!foundTruth){
-	  ATH_MSG_DEBUG("failed to find a status=1 truth particle to match the truth link");
-	  muonTruthParticleLink(*muon)=ElementLink<xAOD::TruthParticleContainer>();
-	  muonTruthParticleOrigin(muonInd)=-99999;
-	  muonTruthParticleType(muonInd)=-99999;
-	  std::vector<unsigned int> nprecHitsPerChamberLayer;
-	  std::vector<unsigned int> nphiHitsPerChamberLayer;
-	  std::vector<unsigned int> ntrigEtaHitsPerChamberLayer;
-	  muonTruthParticleNPrecMatched(muonInd)=nprecHitsPerChamberLayer;
-	  muonTruthParticleNPhiMatched(muonInd)=nphiHitsPerChamberLayer;
-	  muonTruthParticleNTrigEtaMatched(muonInd)=ntrigEtaHitsPerChamberLayer;
-	}
-      }
-      else{ //no truth link, add a dummy
-	ATH_MSG_VERBOSE(" Reco muon has no truth association");
-	muonTruthParticleLink(*muon)=ElementLink<xAOD::TruthParticleContainer>();
-	muonTruthParticleOrigin(muonInd)=-99999;
-	muonTruthParticleType(muonInd)=-99999;
-	//add these empty vectors
-	std::vector<unsigned int> nprecHitsPerChamberLayer;
-	std::vector<unsigned int> nphiHitsPerChamberLayer;
-	std::vector<unsigned int> ntrigEtaHitsPerChamberLayer;
-	muonTruthParticleNPrecMatched(muonInd)=nprecHitsPerChamberLayer;
-	muonTruthParticleNPhiMatched(muonInd)=nphiHitsPerChamberLayer;
-	muonTruthParticleNTrigEtaMatched(muonInd)=ntrigEtaHitsPerChamberLayer;
-      }
-    }catch ( SG::ExcBadAuxVar& ) {
-      ATH_MSG_WARNING("Track particle is missing truthParticleLink variable!");
-      //there should always be a truthParticleLink, but just in case
+    if(!foundTruth) {
       muonTruthParticleLink(*muon)=ElementLink<xAOD::TruthParticleContainer>();
       muonTruthParticleOrigin(muonInd)=-99999;
       muonTruthParticleType(muonInd)=-99999;
-      std::vector<unsigned int> nprecHitsPerChamberLayer;
-      std::vector<unsigned int> nphiHitsPerChamberLayer;
-      std::vector<unsigned int> ntrigEtaHitsPerChamberLayer;
-      muonTruthParticleNPrecMatched(muonInd)=nprecHitsPerChamberLayer;
-      muonTruthParticleNPhiMatched(muonInd)=nphiHitsPerChamberLayer;
-      muonTruthParticleNTrigEtaMatched(muonInd)=ntrigEtaHitsPerChamberLayer;
-    }
+      //add these empty vectors
+      muonTruthParticleNPrecMatched(muonInd)=std::vector<unsigned int>{};
+      muonTruthParticleNPhiMatched(muonInd)=std::vector<unsigned int>{};
+      muonTruthParticleNTrigEtaMatched(muonInd)=std::vector<unsigned int>{};
+    }	
     muonInd++;
   }
-
-  //one more thing: need to have muonlink set for all truth particles to avoid ELReset errors
+  ///one more thing: need to have muonlink set for all truth particles to avoid ELReset errors
   for( const auto truthParticle : *muonTruthParticleRecoLink ){
-    if(!truthParticle->isAvailable<ElementLink< xAOD::MuonContainer > >("recoMuonLink")){
-      ATH_MSG_DEBUG("no reco muon link set, add an empty one");
-      muonTruthParticleRecoLink(*truthParticle)=ElementLink< xAOD::MuonContainer > ();
-    }
-  }
-    return StatusCode::SUCCESS;
+        if(!truthParticle->isAvailable<ElementLink< xAOD::MuonContainer > >("recoMuonLink")){
+            ATH_MSG_DEBUG("no reco muon link set, add an empty one");
+            muonTruthParticleRecoLink(*truthParticle)=ElementLink< xAOD::MuonContainer > ();
+        }
+   }
+   return StatusCode::SUCCESS;
+}
+
+
+void MuonTruthAssociationAlg::count_chamber_layers(const xAOD::IParticle* truthParticle,  
+                            const Trk::Track* ptrk,
+                            std::vector<unsigned int>& nprecHitsPerChamberLayer,
+                            std::vector<unsigned int>& nphiHitsPerChamberLayer,
+                            std::vector<unsigned int>& ntrigEtaHitsPerChamberLayer) const {
+                                
+    if(!truthParticle || !truthParticle->isAvailable<std::vector<unsigned long long> >("truthMdtHits")){
+        ATH_MSG_DEBUG("muon has no truth hits vector in the truth association alg");
+        nprecHitsPerChamberLayer.clear();
+        nphiHitsPerChamberLayer.clear();
+        ntrigEtaHitsPerChamberLayer.clear();
+        return;    
+    } 
+    std::vector<unsigned long long> mdtTruth=truthParticle->auxdata<std::vector<unsigned long long> >("truthMdtHits");
+    std::vector<unsigned long long> cscTruth;
+    if(m_idHelperSvc->hasCSC()) cscTruth=truthParticle->auxdata<std::vector<unsigned long long> >("truthCscHits");
+    std::vector<unsigned long long> rpcTruth=truthParticle->auxdata<std::vector<unsigned long long> >("truthRpcHits");
+    std::vector<unsigned long long> tgcTruth=truthParticle->auxdata<std::vector<unsigned long long> >("truthTgcHits");
+    
+    for(const Trk::TrackStateOnSurface* tsit : *ptrk->trackStateOnSurfaces()){
+        if(!tsit || !tsit->trackParameters() || !tsit->measurementOnTrack()) continue;
+        const Trk::MeasurementBase* meas = tsit->measurementOnTrack();
+        Identifier id;
+        const Trk::RIO_OnTrack* rot = dynamic_cast<const Trk::RIO_OnTrack*>(meas);
+         if(rot) id=rot->identify();
+         else{
+            const Muon::CompetingMuonClustersOnTrack* crot = dynamic_cast<const Muon::CompetingMuonClustersOnTrack*>(meas);
+            if(crot && !crot->containedROTs().empty() && crot->containedROTs().front() ) id=crot->containedROTs().front()->identify();
+        }		  
+        if(!m_idHelperSvc->isMuon(id)) continue;
+                
+        bool measPhi = m_idHelperSvc->measuresPhi(id);
+        bool isTgc = m_idHelperSvc->isTgc(id);
+        Muon::MuonStationIndex::ChIndex chIndex = !isTgc ? m_idHelperSvc->chamberIndex(id) : Muon::MuonStationIndex::ChUnknown;
+        if(m_idHelperSvc->isMdt(id)){
+            for(unsigned int i=0;i<mdtTruth.size();i++){
+                if(id==mdtTruth[i]){
+                    increment_unsigned(nprecHitsPerChamberLayer[chIndex]);
+                    break;
+                }
+            }
+        } else if(m_idHelperSvc->hasCSC() && m_idHelperSvc->isCsc(id)){
+            for(unsigned int i=0;i<cscTruth.size();i++){
+                if(id!=cscTruth[i]) continue;
+                if(measPhi) {
+                    Muon::MuonStationIndex::PhiIndex index = m_idHelperSvc->phiIndex(id);
+                    increment_unsigned(nphiHitsPerChamberLayer[index]);
+                } else{
+                    increment_unsigned(nprecHitsPerChamberLayer[chIndex]);
+                }
+                break;		      
+            }
+        } else if (m_idHelperSvc->isRpc(id)){
+            for(unsigned int i=0;i<rpcTruth.size();i++){
+                if(id!=rpcTruth[i]){ continue;}
+                int index = m_idHelperSvc->phiIndex(id);
+                if(measPhi) {
+                    increment_unsigned(nphiHitsPerChamberLayer[index]);
+                }else {
+                    increment_unsigned(ntrigEtaHitsPerChamberLayer[index]);
+                }
+                break;		    
+            }
+        } else if (m_idHelperSvc->isTgc(id)){
+            for(unsigned int i=0;i<tgcTruth.size();i++){
+                if(id!=tgcTruth[i]){continue;}
+                int index = m_idHelperSvc->phiIndex(id);
+                if( measPhi) {
+                    increment_unsigned(nphiHitsPerChamberLayer[index]);
+                } else{
+                    increment_unsigned(ntrigEtaHitsPerChamberLayer[index]);
+                }
+                break;
+            }
+        } 
+    } //end loop over TSOS
+    ATH_MSG_DEBUG("finished loop over TSOS"); 
+   
+    //now, have to check if there are non-zero truth hits in indices without reco hits
+    clear_dummys(mdtTruth, nprecHitsPerChamberLayer);
+    clear_dummys(cscTruth, nprecHitsPerChamberLayer);
+        
+    clear_dummys(cscTruth, nphiHitsPerChamberLayer);
+    clear_dummys(rpcTruth, nphiHitsPerChamberLayer);
+    clear_dummys(tgcTruth, nphiHitsPerChamberLayer);
+      
+    clear_dummys(rpcTruth, ntrigEtaHitsPerChamberLayer);
+    clear_dummys(tgcTruth, ntrigEtaHitsPerChamberLayer);
+         
 }
+void MuonTruthAssociationAlg::clear_dummys(const std::vector<unsigned long long>& identifiers, std::vector<unsigned int>& vec) const{  
+    /// If the identifiers are empty then there
+    /// is no change that a dummy value could be cleared from this list
+    if (identifiers.empty()){
+        return;
+    }
+    for(unsigned int i=0;i<vec.size();i++){
+        if (vec[i] != dummy_unsigned) continue;
+        for (unsigned j = 0;j< identifiers.size();++j){
+          Identifier id(identifiers[j]);
+          if((m_idHelperSvc->measuresPhi(id) && m_idHelperSvc->phiIndex(id)==(Muon::MuonStationIndex::PhiIndex)i) ||
+             (!m_idHelperSvc->measuresPhi(id) && m_idHelperSvc->chamberIndex(id)==(Muon::MuonStationIndex::ChIndex)i))
+                {vec[i]=0; break;}
+		} 
+    }
+}
\ No newline at end of file
diff --git a/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthAssociationAlg.h b/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthAssociationAlg.h
index 51bd40a309d1029a47561c5da99218a49ace98fa..35ac4bd6da22f3dd928f4d4adb86d949373f9d98 100644
--- a/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthAssociationAlg.h
+++ b/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthAssociationAlg.h
@@ -1,11 +1,11 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRUTHPARTICLEALGS_MUONTRUTHASSOCIATIONALG_H
 #define TRUTHPARTICLEALGS_MUONTRUTHASSOCIATIONALG_H
 
-#include "AthenaBaseComps/AthAlgorithm.h"
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
 #include "xAODMuon/MuonContainer.h"
 #include "xAODTruth/TruthParticleContainer.h"
 #include "StoreGate/WriteDecorHandleKey.h"
@@ -13,15 +13,15 @@
 #include "GaudiKernel/ServiceHandle.h"
 #include "MuonIdHelpers/IMuonIdHelperSvc.h"
 
-class MuonTruthAssociationAlg : public AthAlgorithm  {
+class MuonTruthAssociationAlg : public AthReentrantAlgorithm  {
 
 public:
   // Constructor with parameters:
   MuonTruthAssociationAlg(const std::string &name,ISvcLocator *pSvcLocator);
 
   // Basic algorithm methods:
-  virtual StatusCode initialize();
-  virtual StatusCode execute();
+  StatusCode initialize() override;
+  StatusCode execute(const EventContext& ctx) const override;
 
 private:
   SG::WriteDecorHandleKey<xAOD::TruthParticleContainer> m_muonTruthParticleContainerName{this,"MuonTruthParticleContainerName","MuonTruthParticles","container name for muon truth particles; the full handle name, including the reco muon link auxdata, is set in initialize()"};
@@ -32,13 +32,21 @@ private:
   SG::WriteDecorHandleKey<xAOD::MuonContainer> m_muonTruthParticleNPhiMatched{this,"MuonTruthParticleNPhiMatched","Muons.nphiMatchedHitsPerChamberLayer","muon vector of number of phi matched hits per chamber layer auxdata name; name will be reset in initialize() based on m_muonName"};
   SG::WriteDecorHandleKey<xAOD::MuonContainer> m_muonTruthParticleNTrigEtaMatched{this,"MuonTruthParticleNTrigEtaMatched","Muons.ntrigEtaMatchedHitsPerChamberLayer","muon vector of number of phi matched hits per chamber layer auxdata name; name will be reset in initialize() based on m_muonName"};
   SG::ReadDecorHandleKey<xAOD::MuonContainer> m_cbMuTrkPartLinkToRead{this,"CombinedMuonTrackParticlesTruthLink","CombinedMuonTrackParticles.truthParticleLink","CombinedMuonTrackParticles truth particle link auxdata name; just needed to schedule this alg after the TrackParticleTruthAlg"};
-  SG::ReadDecorHandleKey<xAOD::MuonContainer> m_extMuTrkPartLinkToRead{this,"ExtrapolateMuonTrackParticlesTruthLink","ExtrapolateMuonTrackParticles.truthParticleLink","ExtrapolateMuonTrackParticles truth particle link auxdata name; just needed to schedule this alg after the TrackParticleTruthAlg"};
+  SG::ReadDecorHandleKey<xAOD::MuonContainer> m_extMuTrkPartLinkToRead{this,"ExtrapolatedMuonTrackParticlesTruthLink","ExtrapolatedMuonTrackParticles.truthParticleLink","ExtrapolatedMuonTrackParticles truth particle link auxdata name; just needed to schedule this alg after the TrackParticleTruthAlg"};
   SG::ReadDecorHandleKey<xAOD::MuonContainer> m_indetTrkPartLinkToRead{this,"InDetTrackParticlesTruthLink","InDetTrackParticles.truthParticleLink","InDetTrackParticles truth particle link auxdata name; just needed to schedule this alg after the TrackParticleTruthAlg"};
   Gaudi::Property<std::string> m_muonName{this,"MuonContainerName","Muons","muon container name"};
   Gaudi::Property<bool>m_associateWithInDetTP{this,"AssociateWithInDetTP",false,"force use of ID track particles for association"};
   Gaudi::Property<int>m_barcodeOffset{this,"BarcodeOffset",1000000 ,"barcode offset for truth particles"};
 
   ServiceHandle<Muon::IMuonIdHelperSvc> m_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"};
+  
+  void count_chamber_layers(const xAOD::IParticle* truth_particle,  
+                            const Trk::Track* ptrk,
+                            std::vector<unsigned int>& nprecHitsPerChamberLayer,
+                            std::vector<unsigned int>& nphiHitsPerChamberLayer,
+                            std::vector<unsigned int>& ntrigEtaHitsPerChamberLayer) const;
+  void clear_dummys(const std::vector<unsigned long long>& identifiers, std::vector<unsigned int>& vec) const;
+  
 };
 
 
diff --git a/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthDecorationAlg.cxx b/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthDecorationAlg.cxx
index 14809093e5f11e8a4e448b05a9341a01120c0956..9dfda3d76ba0efc167faa4d4b48e89838d4ba58b 100644
--- a/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthDecorationAlg.cxx
+++ b/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthDecorationAlg.cxx
@@ -20,11 +20,18 @@
 #include "EventPrimitives/EventPrimitivesHelpers.h"
 #include "MuonReadoutGeometry/CscReadoutElement.h"
 
+
+namespace{
+    const SG::AuxElement::Decorator<int> dec_truthOrigin{"truthOrigin"};
+    const SG::AuxElement::Decorator<int> dec_truthType{"truthType"};
+    const std::vector<float> emptyVec;
+  
+}
 namespace Muon {
 
   // Constructor with parameters:
   MuonTruthDecorationAlg::MuonTruthDecorationAlg(const std::string &name, ISvcLocator *pSvcLocator) :
-    AthAlgorithm(name,pSvcLocator),
+    AthReentrantAlgorithm(name,pSvcLocator),
     m_muonMgr(nullptr) {
   }
 
@@ -39,7 +46,6 @@ namespace Muon {
     ATH_CHECK(m_SDO_TruthNames.initialize());
     if (!m_CSC_SDO_TruthNames.empty()) ATH_CHECK(m_CSC_SDO_TruthNames.initialize());
     ATH_CHECK(m_idHelperSvc.retrieve());
-    ATH_CHECK(m_printer.retrieve());
     ATH_CHECK(m_truthClassifier.retrieve());
     ATH_CHECK(m_extrapolator.retrieve());
     ATH_CHECK(detStore()->retrieve(m_muonMgr));
@@ -47,10 +53,9 @@ namespace Muon {
   }
 
   // Execute method:
-  StatusCode MuonTruthDecorationAlg::execute()
-  {
+  StatusCode MuonTruthDecorationAlg::execute(const EventContext& ctx) const  {
     // skip if no input data found
-    SG::ReadHandle<xAOD::TruthParticleContainer> truthContainer(m_truthParticleContainerName);
+    SG::ReadHandle<xAOD::TruthParticleContainer> truthContainer(m_truthParticleContainerName,ctx);
     if(!truthContainer.isPresent()) return StatusCode::SUCCESS;
     if(!truthContainer.isValid()){
       ATH_MSG_WARNING("truth container "<<truthContainer.name()<<" not valid");
@@ -58,11 +63,11 @@ namespace Muon {
     }
 
     // create output container
-    SG::WriteHandle<xAOD::TruthParticleContainer> muonTruthContainer(m_muonTruthParticleContainerName);
+    SG::WriteHandle<xAOD::TruthParticleContainer> muonTruthContainer(m_muonTruthParticleContainerName,ctx);
     ATH_CHECK(muonTruthContainer.record(std::make_unique<xAOD::TruthParticleContainer>(),std::make_unique<xAOD::TruthParticleAuxContainer>()));
     ATH_MSG_DEBUG( "Recorded TruthParticleContainer with key: " << m_muonTruthParticleContainerName );
 
-    SG::WriteHandle<xAOD::MuonSegmentContainer> segmentContainer(m_muonTruthSegmentContainerName);
+    SG::WriteHandle<xAOD::MuonSegmentContainer> segmentContainer(m_muonTruthSegmentContainerName,ctx);
     if(m_createTruthSegment){
       ATH_CHECK(segmentContainer.record(std::make_unique<xAOD::MuonSegmentContainer>(),std::make_unique<xAOD::MuonSegmentAuxContainer>()));
       ATH_MSG_DEBUG( "Recorded MuonSegmentContainer with key: " << segmentContainer.name() );
@@ -70,8 +75,7 @@ namespace Muon {
 
     // loop over truth coll
     for( const auto truth : *truthContainer ){
-      if( truth->status() != 1 ) continue;
-      if( abs(truth->pdgId()) != 13 || truth->pt() < 1000. ) continue;
+      if( truth->status() != 1 || !truth->isMuon() || truth->pt() < 1000. ) continue;
       xAOD::TruthParticle* truthParticle = new xAOD::TruthParticle();
       muonTruthContainer->push_back( truthParticle );
       truthParticle->setPdgId(truth->pdgId());
@@ -94,25 +98,21 @@ namespace Muon {
 
       // if configured look up truth classification
       if( !m_truthClassifier.empty() ){
-	// if configured also get truth classification
-	auto truthClass = m_truthClassifier->particleTruthClassifier(truth);
-	type = truthClass.first;
-	origin = truthClass.second;
-	ATH_MSG_VERBOSE("Got truth type  " << static_cast<int>(type) << "  origin " << static_cast<int>(origin));
-	int& theType   = const_cast<xAOD::TruthParticle*>(truthParticle)->auxdata<int>("truthType");
-	int& theOrigin = const_cast<xAOD::TruthParticle*>(truthParticle)->auxdata<int>("truthOrigin");
-	theType = static_cast<int>(type);
-	theOrigin = static_cast<int>(origin);
-	iType = static_cast<int>(type);
-	iOrigin = static_cast<int>(origin);
+            // if configured also get truth classification
+            auto truthClass = m_truthClassifier->particleTruthClassifier(truth);
+            int iType = truthClass.first;
+            int iOrigin = truthClass.second;
+            ATH_MSG_VERBOSE("Got truth type  " << static_cast<int>(type) << "  origin " << static_cast<int>(origin));
+            dec_truthOrigin(*truthParticle) = iOrigin;
+            dec_truthType(*truthParticle) = iType;
       }
 
-      // add track records
-      addTrackRecords(*truthParticle,truth->prodVtx());
+      /// add track records
+      addTrackRecords(ctx,*truthParticle);
       ChamberIdMap ids;
 
       // add hit counts
-      addHitCounts(*truthParticle,&ids);
+      addHitCounts(ctx, *truthParticle, ids);
 
       //add hit ID vectors
       addHitIDVectors(*truthParticle,ids);
@@ -125,7 +125,7 @@ namespace Muon {
 
       // create segments
       if( m_createTruthSegment && goodMuon ){
-	createSegments(truthLink,segmentContainer,ids);
+            createSegments(ctx, truthLink,segmentContainer,ids);
       }
     }
 
@@ -135,12 +135,14 @@ namespace Muon {
     return StatusCode::SUCCESS;
   }
 
-  void MuonTruthDecorationAlg::createSegments( const ElementLink< xAOD::TruthParticleContainer >& truthLink, SG::WriteHandle<xAOD::MuonSegmentContainer> segmentContainer,
+  void MuonTruthDecorationAlg::createSegments(const EventContext& ctx, 
+                                              const ElementLink< xAOD::TruthParticleContainer >& truthLink, 
+                                              SG::WriteHandle<xAOD::MuonSegmentContainer> segmentContainer,
                                                const MuonTruthDecorationAlg::ChamberIdMap& ids) const {
 
     std::vector<SG::ReadHandle<MuonSimDataCollection> > sdoCollections(6);
     for(const SG::ReadHandleKey<MuonSimDataCollection>& k : m_SDO_TruthNames){
-      SG::ReadHandle<MuonSimDataCollection> col(k);
+      SG::ReadHandle<MuonSimDataCollection> col(k,ctx);
       if(!col.isPresent()){
 	ATH_MSG_DEBUG("MuonSimDataCollection "<<col.name()<<" not in StoreGate");
 	continue;
@@ -236,7 +238,7 @@ namespace Muon {
 	    }
 	  }
 	  else{
-      SG::ReadHandle<CscSimDataCollection> cscCollection(m_CSC_SDO_TruthNames);
+      SG::ReadHandle<CscSimDataCollection> cscCollection(m_CSC_SDO_TruthNames,ctx);
 	    auto pos = cscCollection->find(id);
 	    if( pos != cscCollection->end() ) {
 	      const MuonGM::CscReadoutElement * descriptor = m_muonMgr->getCscReadoutElement(id);
@@ -294,16 +296,16 @@ namespace Muon {
     }
   }
 
-  void MuonTruthDecorationAlg::addTrackRecords( xAOD::TruthParticle& truthParticle,
-                                                const xAOD::TruthVertex* vertex ) const {
+  void MuonTruthDecorationAlg::addTrackRecords( const EventContext& ctx,xAOD::TruthParticle& truthParticle ) const {
 
     // first loop over track records, store parameters at the different positions
     int barcode = truthParticle.barcode();
+    const xAOD::TruthVertex* vertex = truthParticle.prodVtx();
     std::vector< std::pair< Amg::Vector3D, Amg::Vector3D > > parameters;
     if( vertex ) parameters.push_back( std::make_pair(Amg::Vector3D(vertex->x(),vertex->y(),vertex->z()),
                                                       Amg::Vector3D(truthParticle.px(),truthParticle.py(),truthParticle.pz())) );
 
-    for( SG::ReadHandle<TrackRecordCollection>& col : m_trackRecordCollectionNames.makeHandles() ){
+    for( SG::ReadHandle<TrackRecordCollection>& col : m_trackRecordCollectionNames.makeHandles(ctx) ){
       if(!col.isPresent()) continue;
       const std::string name = col.key();
       float& x   = truthParticle.auxdata<float>(name+"_x");
@@ -397,7 +399,7 @@ namespace Muon {
         epy=-99999.;
         epz=-99999.;
 
-        const Trk::TrackParameters* exPars = m_extrapolator->extrapolateToVolume(pars,*volume,Trk::alongMomentum,Trk::muon);
+        std::unique_ptr<const Trk::TrackParameters> exPars { m_extrapolator->extrapolateToVolume(ctx,pars,*volume,Trk::alongMomentum,Trk::muon)};
         if( exPars ){
           ex = exPars->position().x();
           ey = exPars->position().y();
@@ -417,22 +419,20 @@ namespace Muon {
                           << " res p " << (parameters[i+1].second.mag() - exPars->momentum().mag())
                           << " error " << errorp << " cov " << (*exPars->covariance())(Trk::qOverP,Trk::qOverP)
                           << " pull p " << (parameters[i+1].second.mag() - exPars->momentum().mag())/errorp);
-          delete exPars;
         }
       }
     }
-    std::vector<float> emptyVec;
     for( unsigned int i=0;i<m_trackRecordCollectionNames.size();i++){
       const std::string name = m_trackRecordCollectionNames.at(i).key();
       if(!truthParticle.isAvailable<std::vector<float> >(name+"_cov_extr")){
-	truthParticle.auxdata<std::vector<float> >(name+"_cov_extr")=emptyVec;
+        truthParticle.auxdata<std::vector<float> >(name+"_cov_extr")=emptyVec;
       }
     }
   }
 
 
-  void MuonTruthDecorationAlg::addHitCounts( xAOD::TruthParticle& truthParticle,
-					     MuonTruthDecorationAlg::ChamberIdMap* ids) const {
+  void MuonTruthDecorationAlg::addHitCounts(const EventContext& ctx, xAOD::TruthParticle& truthParticle,
+					     MuonTruthDecorationAlg::ChamberIdMap& ids) const {
     int barcode = truthParticle.barcode();
 
     std::vector<unsigned int> nprecHitsPerChamberLayer;
@@ -443,7 +443,7 @@ namespace Muon {
     ntrigEtaHitsPerChamberLayer.resize(Muon::MuonStationIndex::PhiIndexMax);
     ATH_MSG_DEBUG("addHitCounts: barcode " << barcode);
     // loop over detector technologies
-    for( SG::ReadHandle<PRD_MultiTruthCollection>& col : m_PRD_TruthNames.makeHandles() ){
+    for( SG::ReadHandle<PRD_MultiTruthCollection>& col : m_PRD_TruthNames.makeHandles(ctx) ){
       if(!col.isPresent()){
 	ATH_MSG_DEBUG("PRD_MultiTruthCollection "<<col.name()<<" not in StoreGate");
 	continue;
@@ -461,20 +461,19 @@ namespace Muon {
 	Muon::MuonStationIndex::ChIndex chIndex = !isTgc ? m_idHelperSvc->chamberIndex(id) : Muon::MuonStationIndex::ChUnknown;
 
 	// add identifier to map
-	if( ids ) {
 	  if( isTgc ){ // TGCS should be added to both EIL and EIS
 	    Muon::MuonStationIndex::PhiIndex index = m_idHelperSvc->phiIndex(id);
 	    if( index == Muon::MuonStationIndex::T4 ){
-	      (*ids)[Muon::MuonStationIndex::EIS].push_back(id);
-	      (*ids)[Muon::MuonStationIndex::EIL].push_back(id);
+	      ids[Muon::MuonStationIndex::EIS].push_back(id);
+	      ids[Muon::MuonStationIndex::EIL].push_back(id);
 	    }else{
-	      (*ids)[Muon::MuonStationIndex::EMS].push_back(id);
-	      (*ids)[Muon::MuonStationIndex::EML].push_back(id);
+	     ids[Muon::MuonStationIndex::EMS].push_back(id);
+	      ids[Muon::MuonStationIndex::EML].push_back(id);
 	    }
 	  }else{
-	    (*ids)[chIndex].push_back(id);
-	  }
-	}
+	    ids[chIndex].push_back(id);
+        }
+	
 	if( m_idHelperSvc->issTgc(id) ) {
 	  int index = m_idHelperSvc->phiIndex(id);
 	  if( measPhi ) ++nphiHitsPerChamberLayer[index];
diff --git a/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthDecorationAlg.h b/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthDecorationAlg.h
index ef4044910cf648f5cf7336bcbc76b57eb72f8025..a33fef954043068da350d2e63934a261fe4028be 100755
--- a/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthDecorationAlg.h
+++ b/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthDecorationAlg.h
@@ -1,16 +1,15 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRUTHPARTICLEALGS_MUONTRUTHDECORATIONALG_H
 #define TRUTHPARTICLEALGS_MUONTRUTHDECORATIONALG_H
 
-#include "AthenaBaseComps/AthAlgorithm.h"
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
 #include "GaudiKernel/ServiceHandle.h"
 #include "GaudiKernel/ToolHandle.h"
 
 #include "MuonIdHelpers/IMuonIdHelperSvc.h"
-#include "MuonRecToolInterfaces/IMuonTrackTruthTool.h"
 #include "MuonRecHelperTools/MuonEDMPrinterTool.h"
 #include "TrkExInterfaces/IExtrapolator.h"
 #include "TrackRecord/TrackRecordCollection.h"
@@ -38,7 +37,7 @@ namespace MuonGM {
 
 namespace Muon {
 
-class MuonTruthDecorationAlg : public AthAlgorithm  {
+class MuonTruthDecorationAlg : public AthReentrantAlgorithm  {
 
 public:
   typedef std::map<Muon::MuonStationIndex::ChIndex, std::vector<Identifier> >   ChamberIdMap;
@@ -47,14 +46,15 @@ public:
   MuonTruthDecorationAlg(const std::string &name,ISvcLocator *pSvcLocator);
 
   // Basic algorithm methods:
-  virtual StatusCode initialize();
-  virtual StatusCode execute();
+  virtual StatusCode initialize()override;
+  virtual StatusCode execute(const EventContext& ctx) const override;
 
 private:
-  void addTrackRecords( xAOD::TruthParticle& truthParticle, const xAOD::TruthVertex* vertex ) const;
-  void addHitCounts( xAOD::TruthParticle& truthParticle, ChamberIdMap* ids = 0 ) const;
+  void addTrackRecords( const EventContext& ctx,xAOD::TruthParticle& truthParticle) const;
+  void addHitCounts(const EventContext& ctx, xAOD::TruthParticle& truthParticle, ChamberIdMap& ids) const;
   void addHitIDVectors( xAOD::TruthParticle& truthParticle, const MuonTruthDecorationAlg::ChamberIdMap& ids) const;
-  void createSegments( const ElementLink< xAOD::TruthParticleContainer >& truthLink,SG::WriteHandle<xAOD::MuonSegmentContainer> segmentContainer,
+  void createSegments( const EventContext& ctx, 
+                       const ElementLink< xAOD::TruthParticleContainer >& truthLink,SG::WriteHandle<xAOD::MuonSegmentContainer> segmentContainer,
                        const MuonTruthDecorationAlg::ChamberIdMap& ids) const;
 
   SG::ReadHandleKey<xAOD::TruthParticleContainer> m_truthParticleContainerName{this,"TruthParticleContainerName","TruthParticles"};
@@ -68,7 +68,6 @@ private:
 
   ServiceHandle<Muon::IMuonIdHelperSvc> m_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"};
 
-  ToolHandle<Muon::MuonEDMPrinterTool> m_printer{this,"MuonEDMPrinterTool","Muon::MuonEDMPrinterTool/MuonEDMPrinterTool"};
   ToolHandle<IMCTruthClassifier> m_truthClassifier{this,"MCTruthClassifier","MCTruthClassifier/MCTruthClassifier"};
   ToolHandle<Trk::IExtrapolator> m_extrapolator{this,"Extrapolator","Trk::Extrapolator/AtlasExtrapolator"};
 
diff --git a/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthSummaryAlg.cxx b/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthSummaryAlg.cxx
deleted file mode 100644
index cdc3303d7ac89a22e9d59b053a68b6c37045e51e..0000000000000000000000000000000000000000
--- a/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthSummaryAlg.cxx
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-*/
-
-#include "MuonTruthSummaryAlg.h"
-
-#include "TrkTrack/TrackCollection.h"
-#include "TrkSegment/SegmentCollection.h"
-#include "MuonSegment/MuonSegment.h"
-#include "xAODTracking/TrackParticleContainer.h"
-
-MuonTruthSummaryAlg::MuonTruthSummaryAlg(const std::string& name, ISvcLocator* pSvcLocator) : 
-  AthAlgorithm( name, pSvcLocator ) {
-}
-
-StatusCode MuonTruthSummaryAlg::initialize() {
-  ATH_MSG_INFO ("Initializing " << name() << "...");
-  if( m_truthSummaryTool.retrieve().isFailure()){
-    ATH_MSG_ERROR("Failed to initialize " << m_truthSummaryTool );
-    return StatusCode::FAILURE;
-  }
-  return StatusCode::SUCCESS;
-}
-
-StatusCode MuonTruthSummaryAlg::execute() {  
-  ATH_MSG_DEBUG ("Executing " << name() << "...");
-
-  const Trk::SegmentCollection* segments = 0;
-  if (evtStore()->retrieve(segments, m_segmentContainerName).isSuccess()){
-    for (auto seg : *segments) {
-      const Trk::Segment* tseg = seg;
-      const Muon::MuonSegment* muonSeg = dynamic_cast<const Muon::MuonSegment*>(tseg);
-      if(muonSeg) m_truthSummaryTool->add(*muonSeg,2);
-      else ATH_MSG_WARNING ("Trk::Segment cannot be casted in Muon::MuonSegment.");
-    }
-  }
-  
-  const TrackCollection* tracks = 0;
-  if (evtStore()->retrieve(tracks, m_msTracksContainerName).isSuccess()){
-    for (auto trk : *tracks) {
-    	m_truthSummaryTool->add(*trk,3);
-    }
-  }
-
-  return StatusCode::SUCCESS;
-}
-
-
diff --git a/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthSummaryAlg.h b/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthSummaryAlg.h
deleted file mode 100644
index d5c8dc975443ea537e2562926fe5eee78e8b6671..0000000000000000000000000000000000000000
--- a/MuonSpectrometer/MuonTruthAlgs/src/MuonTruthSummaryAlg.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef MUONTRUTHALGS_MUONTRUTHSUMMARYALGS_H
-#define MUONTRUTHALGS_MUONTRUTHSUMMARYALGS_H
-
-#include "AthenaBaseComps/AthAlgorithm.h"
-#include "GaudiKernel/ToolHandle.h"
-
-#include "MuonRecToolInterfaces/IMuonTruthSummaryTool.h"
-
-#include <string>
-
-class MuonTruthSummaryAlg: public AthAlgorithm {
- public:
-  MuonTruthSummaryAlg( const std::string& name, ISvcLocator* pSvcLocator );
-  virtual ~MuonTruthSummaryAlg()=default;
-
-  virtual StatusCode initialize();
-  virtual StatusCode execute();
-
- private:
-   ToolHandle<Muon::IMuonTruthSummaryTool> m_truthSummaryTool{this,"MuonTruthSummaryTool","MuonTruthSummaryTool"};
-
-   Gaudi::Property<std::string> m_segmentContainerName{this,"SegmentContainerName","MuonSegments"};
-   Gaudi::Property<std::string> m_msTracksContainerName{this,"MSTracksContainerName","MuonSpectrometerTracks"};
-   Gaudi::Property<std::string> m_msTrackletContainerName{this,"MSTrackletsContainerName","MSonlyTracklets"};
-};
-
-#endif //> !MUONTRUTHALGS_MUONTRUTHSUMMARYALGS_H
diff --git a/MuonSpectrometer/MuonTruthAlgs/src/TrackParticleTruthMaker.cxx b/MuonSpectrometer/MuonTruthAlgs/src/TrackParticleTruthMaker.cxx
deleted file mode 100644
index ceb8c218aa48c742deaac2e2ccf2643696785137..0000000000000000000000000000000000000000
--- a/MuonSpectrometer/MuonTruthAlgs/src/TrackParticleTruthMaker.cxx
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-///////////////////////////////////////////////////////////////////
-// TrackParticleTruthMaker.cxx
-//   Implementation file for class TrackParticleTruthMaker
-///////////////////////////////////////////////////////////////////
-
-#include "MuonTruthAlgs/TrackParticleTruthMaker.h"
-
-#include "Particle/TrackParticleContainer.h"
-#include "TrkTruthData/TrackTruthCollection.h"
-#include "TrkTruthData/DetailedTrackTruthCollection.h"
-#include "ParticleTruth/TrackParticleTruthCollection.h"
-#include "TrkTrack/TrackCollection.h"
-#include "TrkTruthData/TruthTrajectory.h"
-#include "AtlasHepMC/GenParticle.h"
-
-#include <map>
-#include "AthLinks/ElementLink.h"
-
-namespace Muon {
-
-  // Constructor with parameters:
-  TrackParticleTruthMaker::TrackParticleTruthMaker(const std::string &name, 
-						   ISvcLocator *pSvcLocator) :
-    AthAlgorithm(name,pSvcLocator),
-    m_trackParticlesName          ("MooreTrackParticles"),  // input track particles
-    m_trackParticleTruthCollection("MooreTrackParticlesTruth"), // output container
-    m_tracksName                  ("MooreTracks"),  // input tracks
-    m_tracksTruthName             ("MooreTracksTruth")  // input track truth
-  {  
-    // Get parameter values from jobOptions file
-    declareProperty("trackParticlesName"           , m_trackParticlesName);
-    declareProperty("trackParticleTruthCollection" , m_trackParticleTruthCollection);
-    declareProperty("tracksName"                   , m_tracksName);
-    declareProperty("tracksTruthName"              , m_tracksTruthName);
-  }
-
-  // Initialize method:
-  StatusCode TrackParticleTruthMaker::initialize()
-  {
-    return StatusCode::SUCCESS;
-  }
-
-  // Execute method:
-  StatusCode TrackParticleTruthMaker::execute() 
-  {
-    StatusCode sc;
-
-    ///
-    const TrackCollection* myTracks(0); 
-    sc = evtStore()->retrieve(myTracks, m_tracksName);
-    if (sc.isFailure()) {
-      ATH_MSG_WARNING ("Could not retrieve '" << m_tracksName << "' from StoreGate !");
-      return StatusCode::SUCCESS;
-    } else {
-      ATH_MSG_DEBUG ("Retrieved '" << m_tracksName << "' from StoreGate !");
-    }
-    ///
-  
-    const DetailedTrackTruthCollection * simTrackMap(0);
-  
-    // retrieve associated TrackTruth from StoreGate (Track*, TrackTruth)
-    sc = evtStore()->retrieve(simTrackMap, m_tracksTruthName);
-    if (sc.isFailure()) {
-      ATH_MSG_WARNING ("Could not retrieve '" << m_tracksTruthName << "' from StoreGate !");
-      return StatusCode::SUCCESS;
-    } else {
-      ATH_MSG_DEBUG ("Retrieved '" << m_tracksTruthName << "' from StoreGate");
-    }
-  
-    const Rec::TrackParticleContainer * origTrackPC(0);
-    sc = evtStore()->retrieve(origTrackPC, m_trackParticlesName);
-    if (sc.isFailure()) {
-      ATH_MSG_WARNING ("Could not retrieve '" << m_trackParticlesName << "' from StoreGate !");
-      return StatusCode::SUCCESS;
-    } else {
-      ATH_MSG_DEBUG ("Retrieve '" << m_trackParticlesName << "' from StoreGate ! " << origTrackPC->size() );
-    }
-  
-    TrackParticleTruthCollection* tpTruthColl = new TrackParticleTruthCollection(origTrackPC);
-  
-    typedef Rec::TrackParticleContainer::const_iterator TPCIter;
-    for (TPCIter i=origTrackPC->begin(); i!=origTrackPC->end(); i++) {
-      const Trk::Track* track = (*i)->originalTrack();
-      ElementLink<TrackCollection> tracklink;
-      tracklink.setElement(const_cast<Trk::Track*>(track));
-      tracklink.setStorableObject(*myTracks); // otherwise the find does not work
-    
-    
-      // this should work since both DetailedTrackTruthCollection and TrackTruthCollection use the same kay: Trk::TrackTruthKey
-      DetailedTrackTruthCollection::const_iterator tempTrackTruthItr = simTrackMap->find(tracklink);  
-      if (tempTrackTruthItr != simTrackMap->end()) {
-	for (unsigned int j=0; j< (*tempTrackTruthItr).second.trajectory().size(); j++) {
-	  if(!(*tempTrackTruthItr).second.trajectory().at(j).cptr()) continue;
-	  ATH_MSG_DEBUG ("Barcode: " << (*tempTrackTruthItr).second.trajectory().at(j).cptr()->pdg_id() 
-			   << "Status: "  <<  (*tempTrackTruthItr).second.trajectory().at(j).cptr()->status() << "\t Probability: " << 1.);
-	  ElementLink< Rec::TrackParticleContainer > myLink;
-	  myLink.setElement(const_cast<Rec::TrackParticle*>(*i));
-	  myLink.setStorableObject(*origTrackPC);
-	  std::pair< ElementLink< Rec::TrackParticleContainer > , TrackParticleTruth> 
-	    entry(myLink,TrackParticleTruth((HepMcParticleLink)(*tempTrackTruthItr).second.trajectory().at(j),1.));
-	  tpTruthColl->insert(entry);
-	}
-      }else{
-	ATH_MSG_DEBUG(" no truth track found " );
-      }
-    } 
-  
-    // record associated TrackParticleTruth to StoreGate (TrackParticle*, TrackParticleTruth)
-    sc = evtStore()->record(tpTruthColl, m_trackParticleTruthCollection, false);
-    if (sc.isFailure()) {
-      ATH_MSG_FATAL ("Could not record '" << m_trackParticleTruthCollection << "' to StoreGate !");
-      return StatusCode::FAILURE;
-    } else {
-      ATH_MSG_DEBUG ("Recorded '" << m_trackParticleTruthCollection << "' to StoreGate !");
-    }
-    return StatusCode::SUCCESS;
-  }
-
-  // Finalize method:
-  StatusCode TrackParticleTruthMaker::finalize() 
-  {
-    return StatusCode::SUCCESS;
-  }
-
-} // namespace Muon
-
diff --git a/MuonSpectrometer/MuonTruthAlgs/src/components/MuonTruthAlgs_entries.cxx b/MuonSpectrometer/MuonTruthAlgs/src/components/MuonTruthAlgs_entries.cxx
index ae070958c899b8110823537ec798a6d83f6a94a4..12f5f894361f6d10e203f8a9de25198033bdbd51 100644
--- a/MuonSpectrometer/MuonTruthAlgs/src/components/MuonTruthAlgs_entries.cxx
+++ b/MuonSpectrometer/MuonTruthAlgs/src/components/MuonTruthAlgs_entries.cxx
@@ -3,12 +3,10 @@
 #include "MuonTruthAlgs/MuonPatternCombinationDetailedTrackTruthMaker.h"
 #include "MuonTruthAlgs/MuonTrackTruthTool.h"
 #include "../MuonDecayTruthTrajectoryBuilder.h"
-#include "MuonTruthAlgs/TrackParticleTruthMaker.h"
 #include "../DetailedMuonPatternTruthBuilder.h"
 #include "../MuonTruthDecorationAlg.h"
 #include "../MuonTruthAssociationAlg.h"
 #include "../MuonSegmentTruthAssociationAlg.h"
-#include "../MuonTruthSummaryAlg.h"
 
 
 using namespace Muon;
@@ -17,11 +15,9 @@ using namespace Trk;
 DECLARE_COMPONENT( MuonPRD_MultiTruthMaker )
 DECLARE_COMPONENT( MuonDetailedTrackTruthMaker )
 DECLARE_COMPONENT( MuonPatternCombinationDetailedTrackTruthMaker )
-DECLARE_COMPONENT( TrackParticleTruthMaker )
 DECLARE_COMPONENT( MuonTruthDecorationAlg )
 DECLARE_COMPONENT( MuonTruthAssociationAlg )
 DECLARE_COMPONENT( MuonSegmentTruthAssociationAlg )
-DECLARE_COMPONENT( MuonTruthSummaryAlg )
 
 DECLARE_COMPONENT( MuonTrackTruthTool )
 DECLARE_COMPONENT( MuonDecayTruthTrajectoryBuilder )
diff --git a/MuonSpectrometer/MuonValidation/MuonDQA/MuonRawDataMonitoring/MMRawDataMonitoring/python/MMMonitorAlgorithm.py b/MuonSpectrometer/MuonValidation/MuonDQA/MuonRawDataMonitoring/MMRawDataMonitoring/python/MMMonitorAlgorithm.py
index 3d2c55248381762098ccdf57e0893a36f1cb02b4..8341cf6ecb318e47ecdc16b767a3dd9b92f0a725 100644
--- a/MuonSpectrometer/MuonValidation/MuonDQA/MuonRawDataMonitoring/MMRawDataMonitoring/python/MMMonitorAlgorithm.py
+++ b/MuonSpectrometer/MuonValidation/MuonDQA/MuonRawDataMonitoring/MMRawDataMonitoring/python/MMMonitorAlgorithm.py
@@ -1,6 +1,5 @@
 #
-#Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration                                    
-        
+#Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 #
 
 from AthenaConfiguration.ComponentFactory import CompFactory
@@ -37,6 +36,15 @@ def MMMonitoringConfig(inputFlags):
     # Configure histograms
 
     # Overview histograms
+    mmGroup.defineHistogram('residual;Residuals',  type='TH1F',  title='Residuals;res[mm];Number of Entries',
+                        path='Overview',   xbins=200, xmin=-10, xmax=10.
+    )
+
+
+    mmGroup.defineHistogram('residual,eta_trk;Res_vs_eta', type='TH2F', title="Res vs Eta;Res;Eta;", path='Overview',xbins=100, xmin=-10, xmax=10., ybins=100, ymin=-3.,ymax=3.)
+    mmGroup.defineHistogram('residual,phi_trk;Res_vs_phi', type='TH2F', title="Res vs Eta;Res;Phi;", path='Overview',xbins=100, xmin=-10, xmax=10., ybins=16, ymin=-3.14,ymax=3.14)
+    mmGroup.defineHistogram('residual,stPhi_mon;Res_vs_stPhi', type='TH2F', title="Res vs Eta;Res;stPhi;", path='Overview',xbins=100, xmin=-10, xmax=10., ybins=16, ymin=0,ymax=16)
+    
     mmGroup.defineHistogram('charge_all;Charge',  type='TH1F',
                             title='Charge;Charge[fC];Number of Entries',
                         path='Overview',   xbins=120, xmin=0., xmax=1200.
@@ -148,6 +156,11 @@ def MMMonitoringConfig(inputFlags):
                             title_MMSummary_angle="uTPC angle "+iside+" "+isector+" stPhi"+str(phi)+" stEta"+str(eta)+" multiplet"+str(multi)+" gap"+str(gas_gap)
                             var3="mu_TPC_angle_"+iside+"_sector_"+isector+"_phi"+str(phi)+"_stationEta"+str(eta)+"_multiplet"+str(multi)+"_gas_gap"+str(gas_gap)+";uTPCangle_"+iside+"_"+isector+"_stPhi"+str(phi)+"_stEta"+str(eta)+"_multiplet"+str(multi)+"_gap"+str(gas_gap)
                             mmSideGroup.defineHistogram(var3,  type='TH1F', title=title_MMSummary_angle+"; #muTPC angle [degrees];Number of Entries",path='uTPC_angle_perLayer',    xbins=2000, xmin=-100, xmax=100)
+                            
+                            var_residual="residuals_"+iside+"_phi"+str(phi)+"_stationEta"+str(eta)+"_multiplet"+str(multi)+"_gas_gap"+str(gas_gap)
+                            print(var_residual)
+                            title_residual = "residuals "+iside+" "+isector+" stPhi"+str(phi)+" stEta"+str(eta)+" multiplet"+str(multi)+" gap"+str(gas_gap)
+                            mmSideGroup.defineHistogram(var_residual,  type='TH1F', title=title_residual+"; res [mm];Number of Entries",path='Residuals',    xbins=200, xmin=-10, xmax=10)
 
         for gas1 in range(1, 5):
             for multi1 in range(1, 3):
@@ -172,11 +185,25 @@ if __name__=='__main__':
     
     # Set the Athena configuration flags
     from AthenaConfiguration.AllConfigFlags import ConfigFlags
-    #ConfigFlags.Input.Files = ['/afs/cern.ch/work/e/elrossi/DQ_Run3/WorkDir/group.det-muon/group.det-muon.21673292.EXT1._000048.ESD.pool.root']
-    #ConfigFlags.Input.Files = ['/afs/cern.ch/work/e/elrossi/DQ_Run3/WorkDir/group.det-muon_Sym/group.det-muon.21823259.EXT1._000045_uTPC.ESD.pool.root']
     #ConfigFlags.Input.Files = ["/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_uTPC_v01_EXT1/group.det-muon.21673283.EXT1._000037.ESD.pool.root"]
-    #ConfigFlags.Input.Files = ['/afs/cern.ch/work/e/elrossi/DQ_updated_308/WorkDir/group.det-muon/group.det-muon.22415666.EXT1._000048.ESD.pool.root']
-    ConfigFlags.Input.Files = ['/afs/cern.ch/work/e/elrossi/DQ_Run3/WorkDir/group.det-muon_Sym/group.det-muon.21670802.EXT1._000006.ESD.pool.root','/afs/cern.ch/work/e/elrossi/DQ_updated/WorkDir/group.det-muon_Sym/group.det-muon.21670802.EXT1._000045.ESD.pool.root','/afs/cern.ch/work/e/elrossi/DQ_updated/WorkDir/group.det-muon_Sym/group.det-muon.21670802.EXT1._000030.ESD.pool.root','/afs/cern.ch/work/e/elrossi/DQ_updated/WorkDir/group.det-muon_Sym/group.det-muon.21670802.EXT1._000046.ESD.pool.root','/afs/cern.ch/work/e/elrossi/DQ_updated/WorkDir/group.det-muon_Sym/group.det-muon.21670802.EXT1._000014.ESD.pool.root']
+    ConfigFlags.Input.Files = ["/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000002.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000006.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000008.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000009.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000012.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000015.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000017.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000018.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000019.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000020.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000021.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000023.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000028.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000032.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000033.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000041.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000043.ESD.pool.root",
+                               "/afs/cern.ch/user/b/bigliett/work/DQ/group.det-muon.DiMuon10_100GeV.ESD.rel213_2020-06-18T2149_R3S_v01_EXT1/group.det-muon.21670802.EXT1._000050.ESD.pool.root"]
     #from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
   #  ConfigFlags.Input.isMC = True
     ConfigFlags.Output.HISTFileName = 'monitor.root'
@@ -198,4 +225,4 @@ if __name__=='__main__':
     cfg.merge(mmMonitorAcc)
     #cfg.printConfig(withDetails=True, summariseProps = True)  
     # number of events selected in the ESD
-    cfg.run(1000)
+    cfg.run(2000)
diff --git a/MuonSpectrometer/MuonValidation/MuonDQA/MuonRawDataMonitoring/MMRawDataMonitoring/src/MMRawDataMonAlg.cxx b/MuonSpectrometer/MuonValidation/MuonDQA/MuonRawDataMonitoring/MMRawDataMonitoring/src/MMRawDataMonAlg.cxx
index f7c30ff74ee0096fee0c91a8db3ca1bcb70da339..8ca9d8ae97a5a168c69905c811ec636934397780 100755
--- a/MuonSpectrometer/MuonValidation/MuonDQA/MuonRawDataMonitoring/MMRawDataMonitoring/src/MMRawDataMonAlg.cxx
+++ b/MuonSpectrometer/MuonValidation/MuonDQA/MuonRawDataMonitoring/MMRawDataMonitoring/src/MMRawDataMonAlg.cxx
@@ -87,6 +87,7 @@ namespace {
     std::vector<float> mu_TPC_angle;
     std::vector<float> x_ontrack;
     std::vector<float> y_ontrack;
+    std::vector<float> residuals;
   };
 
 }
@@ -216,6 +217,7 @@ StatusCode MMRawDataMonAlg::fillMMOverviewVects( const Muon::MMPrepData* prd, MM
   vects.R_mon.push_back(R);
 
     
+
   //MMS and MML phi sectors
   int phisec=0;
   if (stationNumber%2 == 0) phisec=1;
@@ -355,7 +357,8 @@ StatusCode MMRawDataMonAlg::fillMMSummaryVects( const Muon::MMPrepData* prd, MMS
 
     //    Filling Vectors for both sides, considering each strip  
     Vectors.strip_number.push_back(stripNumbers[sIdx]);
-    Vectors.sector_strip.push_back(get_bin_for_occ_ASide_hist(stationEta,multiplet,gas_gap));
+    if(iside==1)    Vectors.sector_strip.push_back(get_bin_for_occ_ASide_hist(stationEta,multiplet,gas_gap));
+    if(iside==0)    Vectors.sector_strip.push_back(get_bin_for_occ_CSide_hist(stationEta,multiplet,gas_gap));
     
   }
 
@@ -408,27 +411,31 @@ StatusCode MMRawDataMonAlg::fillMMHistograms( const Muon::MMPrepData* ) const{
 void MMRawDataMonAlg::clusterFromTrack(const xAOD::TrackParticleContainer*  muonContainer, int lb) const{
 
   MMSummaryHistogramStruct summaryPlots[2][2][4];
+  MMSummaryHistogramStruct summaryPlots_full[2][16][2][2][4];
   MMOverviewHistogramStruct overviewPlots;
+
   int nmu=0;
 
   for (const xAOD::TrackParticle* meTP  : *muonContainer){
 
     if (meTP) {
       nmu++;
+      auto eta_trk = Monitored::Scalar<float>("eta_trk", meTP->eta());
+      auto phi_trk = Monitored::Scalar<float>("phi_trk", meTP->phi());
 
       // retrieve the original track                                                       
       const Trk::Track* meTrack = meTP->track();
       if (meTrack) {
         // get the vector of measurements on track                                                           
-       
+
 	const DataVector<const Trk::MeasurementBase>* meas = meTrack->measurementsOnTrack();
+
 	
 	for(const Trk::MeasurementBase* it: *meas){
 	
 	  const Trk::RIO_OnTrack* rot = dynamic_cast<const Trk::RIO_OnTrack*>(it);
 	  
 	  if (rot) {
-	      
 	    Identifier rot_id = rot->identify();
 	    if (m_idHelperSvc->isMM(rot_id)) {
 	      const Muon::MMClusterOnTrack* cluster = dynamic_cast<const Muon::MMClusterOnTrack*>(rot);
@@ -479,12 +486,71 @@ void MMRawDataMonAlg::clusterFromTrack(const xAOD::TrackParticleContainer*  muon
 		  vects.sector_lb_ASide_eta2_ontrack.push_back(get_bin_for_occ_lb_ASide_pcb_eta2_hist(stEta,multi,gap,PCB,phisec));
 		  
 		  }
-	                      
+
+		float x =		cluster->localParameters()[Trk::loc1] ;
+
+		for (const Trk::TrackStateOnSurface* trkState: *meTrack->trackStateOnSurfaces()) {
+
+		  if(!(trkState)) continue;
+		  Identifier surfaceId = (trkState)->surface().associatedDetectorElementIdentifier();
+		  if(!m_idHelperSvc->isMM(surfaceId)) continue;
+
+		  int trk_stEta= m_idHelperSvc->mmIdHelper().stationEta(surfaceId);
+		  int trk_stPhi= m_idHelperSvc->mmIdHelper().stationPhi(surfaceId);
+		  int trk_multi = m_idHelperSvc->mmIdHelper().multilayer(surfaceId);
+		  int trk_gap=  m_idHelperSvc->mmIdHelper().gasGap(surfaceId);
+		  if(  trk_stPhi==stPhi  and trk_stEta==stEta and trk_multi==multi and trk_gap==gap ){
+		    double x_trk = trkState->trackParameters()->parameters()[Trk::loc1];
+		    double y_trk = trkState->trackParameters()->parameters()[Trk::locY];
+		    
+		    int stPhi16=0;
+		    if (stName=="MML")   stPhi16=2*stPhi-1;
+		    
+		    if (stName=="MMS")  stPhi16=2*stPhi;
+
+		    int iside=0;
+		    if(stEta>0) iside=1;
+
+		    float stereo_angle=		      0.02618;
+		    //		    float stereo_correction=stereo_angle*y_trk;
+		    float stereo_correction=sin(stereo_angle)*y_trk;
+		    if(multi==1 && gap<3) stereo_correction=0;
+		    if(multi==2 && gap>2) stereo_correction=0;
+		    if(multi==1 && gap==3 ) stereo_correction*=-1;
+		    if(multi==2 && gap==1 ) stereo_correction*=-1;
+		    if(multi==1 && gap<3) stereo_angle=0;
+		    if(multi==2 && gap>2) stereo_angle=0;
+		    float res_stereo = (x - x_trk)*cos(stereo_angle) - stereo_correction;
+		    auto residual_mon = Monitored::Scalar<float>("residual", res_stereo);
+		    auto stPhi_mon = Monitored::Scalar<float>("stPhi_mon",stPhi16);
+		    fill("mmMonitor",residual_mon, eta_trk, phi_trk, stPhi_mon);
+		    int abs_stEta= get_sectorEta_from_stationEta(stEta);
+		    auto& vectors = summaryPlots_full[iside][stPhi16-1][abs_stEta-1][multi-1][gap-1];
+		    vectors.residuals.push_back(res_stereo);
+		  }
+		}
 	      } //if cluster
 	    } //isMM
 	  } // if rot
 	} // loop on meas
 	
+	for (int iside=0;iside<2;iside++){
+	std::string MM_sideGroup = "MM_sideGroup"+MM_Side[iside];
+	  for( int statPhi=0; statPhi<16; statPhi++) {
+	    for( int statEta=0; statEta<2; statEta++) {
+	      for( int multiplet=0; multiplet<2; multiplet++) {
+		for( int gas_gap=0; gas_gap<4; gas_gap++) {	
+		  auto& vects=summaryPlots_full[iside][statPhi][statEta][multiplet][gas_gap];;
+		  auto residuals_gap = Monitored::Collection("residuals_"+MM_Side[iside]+"_phi"+std::to_string(statPhi+1)+"_stationEta"+EtaSector[statEta]+"_multiplet"+std::to_string(multiplet+1)+"_gas_gap"+std::to_string(gas_gap+1),vects.residuals);
+		  std::string MM_GapGroup = "MM_GapGroup"+std::to_string(gas_gap+1);
+
+		  fill(MM_sideGroup,residuals_gap);
+		}
+	      }}}}
+
+
+
+
 	for (const Trk::TrackStateOnSurface* trkState: *meTrack->trackStateOnSurfaces()) {
 	  
 	  if(!(trkState)) continue;
@@ -500,13 +566,12 @@ void MMRawDataMonAlg::clusterFromTrack(const xAOD::TrackParticleContainer*  muon
 	  int iside=0;
 	  if(stEta>0) iside=1;
 
-	  auto& Vectors = summaryPlots[iside][multi-1][gap-1];
-	  
+	  auto& Vectors = summaryPlots[iside][multi-1][gap-1];	  
+
 	  //Filling x-y position vectors using the trackStateonSurface 
-	    Vectors.x_ontrack.push_back(pos.x());
-	    Vectors.y_ontrack.push_back(pos.y());
-	
-	  
+	  Vectors.x_ontrack.push_back(pos.x());
+	  Vectors.y_ontrack.push_back(pos.y());
+	    
 	}
       } // if meTrack
     } // if muon
diff --git a/MuonSpectrometer/MuonValidation/MuonRecValidation/MuonTrackPerformance/MuonTrackPerformance/MuonTrackPerformanceAlg.h b/MuonSpectrometer/MuonValidation/MuonRecValidation/MuonTrackPerformance/MuonTrackPerformance/MuonTrackPerformanceAlg.h
index 8a51e1f90a7cdb4687af9871733bbce7a111b1cf..47d40f5b4b857109effc4b81b73abebc59b8db51 100644
--- a/MuonSpectrometer/MuonValidation/MuonRecValidation/MuonTrackPerformance/MuonTrackPerformance/MuonTrackPerformanceAlg.h
+++ b/MuonSpectrometer/MuonValidation/MuonRecValidation/MuonTrackPerformance/MuonTrackPerformance/MuonTrackPerformanceAlg.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef MUONTRACKPERFORMANCEALG_H
@@ -60,7 +60,7 @@ public:
   };
 
   struct TrackData{
-    TrackData() : truthTrack(0),motherPdg(-1),chi2Ndof(0.),productionVertex(0),momentumAtProduction(0),truthTrajectory(0),trackPars(0),trackSummary(0) {}
+    TrackData() : truthTrack(nullptr),motherPdg(-1),chi2Ndof(0.),productionVertex(nullptr),momentumAtProduction(nullptr),truthTrajectory(nullptr),trackPars(nullptr),trackSummary(nullptr) {}
 
     ~TrackData() {
       delete trackPars;
@@ -202,8 +202,7 @@ private:
   bool handleTrackTruth( const TrackCollection& trackCollection );
 
   bool handleSegmentCombi( const Muon::MuonSegmentCombination& combi );
-  bool handleSegmentTruth( const std::vector<const Muon::MuonSegment*>& segments );
-
+  
 
   void doSummary( const TrackCollection& tracks ) const;
   void doSummary( const Muon::IMuonTrackTruthTool::TruthTree& truthTracks ) const;
diff --git a/MuonSpectrometer/MuonValidation/MuonRecValidation/MuonTrackPerformance/src/MuonTrackPerformanceAlg.cxx b/MuonSpectrometer/MuonValidation/MuonRecValidation/MuonTrackPerformance/src/MuonTrackPerformanceAlg.cxx
index 302a732f07ab1352adf822f2916c7801de7b04eb..be2c679e658c51443a69de0dd63bfcb9e94b406a 100644
--- a/MuonSpectrometer/MuonValidation/MuonRecValidation/MuonTrackPerformance/src/MuonTrackPerformanceAlg.cxx
+++ b/MuonSpectrometer/MuonValidation/MuonRecValidation/MuonTrackPerformance/src/MuonTrackPerformanceAlg.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "MuonTrackPerformance/MuonTrackPerformanceAlg.h"
@@ -144,43 +144,6 @@ StatusCode MuonTrackPerformanceAlg::execute()
   return StatusCode::SUCCESS;
 }
 
-bool MuonTrackPerformanceAlg::handleSegmentTruth( const std::vector<const Muon::MuonSegment*>& segments ) {
-  Muon::IMuonTrackTruthTool::SegmentResultVec result = m_truthTool->match(segments);
-  Muon::IMuonTrackTruthTool::SegmentResultVec::iterator rit = result.begin();
-  Muon::IMuonTrackTruthTool::SegmentResultVec::iterator rit_end = result.end();
-  for( ;rit!=rit_end;++rit ){
-      
-    Muon::MuonTrackTruth& trackTruth = rit->second;
-    if( rit == result.begin() ) {
-      if( trackTruth.mdts.missedChambers.size() > 0 ){
-      	if( m_debug ) *m_log << MSG::DEBUG << "Missing mdt chamber " << endmsg;
-      }
-      if(m_idHelperSvc->hasCSC()){
-	if( trackTruth.cscs.missedChambers.size() > 0 ){
-	  if( m_debug ) *m_log << MSG::DEBUG << "Missing csc chamber " << endmsg;
-	}
-      }
-      if(m_idHelperSvc->hasSTgc()){
-	if( trackTruth.stgcs.missedChambers.size() > 0 ){
-	  if( m_debug ) *m_log << MSG::DEBUG << "Missing stgc chamber " << endmsg;
-	}
-      }
-      if(m_idHelperSvc->hasMM()){
-	if( trackTruth.mms.missedChambers.size() > 0 ){
-	  if( m_debug ) *m_log << MSG::DEBUG << "Missing mm chamber " << endmsg;
-	}
-      }
-      if( trackTruth.rpcs.missedChambers.size() > 0 ){
-      	if( m_debug ) *m_log << MSG::DEBUG << "Missing rpc chamber " << endmsg;
-      }
-      if( trackTruth.tgcs.missedChambers.size() > 0 ){
-      	if( m_debug ) *m_log << MSG::DEBUG << "Missing tgc chamber " << endmsg;
-      }
-    }
-  }
-  return true;
-}
-
 bool MuonTrackPerformanceAlg::handleSegmentCombi( const Muon::MuonSegmentCombination& combi ) {
   /** This method loops over the segments in the combi and filles them into the internal structure of the MuonCombiTrackMaker */
 
@@ -215,7 +178,7 @@ bool MuonTrackPerformanceAlg::handleSegmentCombi( const Muon::MuonSegmentCombina
 
 bool MuonTrackPerformanceAlg::handleTracks() {
 
-  std::unique_ptr<TrackCollection> allTracks(new TrackCollection());
+  std::unique_ptr<TrackCollection> allTracks = std::make_unique<TrackCollection>();
   if(!m_trackKey.key().empty()){ //MS tracks
     SG::ReadHandle<TrackCollection> trackCol(m_trackKey);
     if (!trackCol.isValid() ) {
@@ -328,7 +291,7 @@ bool MuonTrackPerformanceAlg::handleTrackTruth( const TrackCollection& trackColl
     if(!simDataMap.isPresent()) continue;
     muonSimData.push_back(simDataMap.cptr());
   }
-  const CscSimDataCollection* cscSimData=NULL;
+  const CscSimDataCollection* cscSimData=nullptr;
   if(m_idHelperSvc->hasCSC()){
     SG::ReadHandle<CscSimDataCollection> cscSimDataMap(m_cscSimData);
     if(!cscSimDataMap.isValid()){
@@ -370,7 +333,7 @@ bool MuonTrackPerformanceAlg::handleTrackTruth( const TrackCollection& trackColl
   unsigned int nmatched(0);
   unsigned int nmatchedSecondary(0);
   
-  Muon::IMuonTrackTruthTool::ResultVec result = m_truthTool->match(trackCollection);
+  Muon::IMuonTrackTruthTool::ResultVec result = m_truthTool->match(truthTree, trackCollection);
   Muon::IMuonTrackTruthTool::ResultVec::iterator rit = result.begin();
   Muon::IMuonTrackTruthTool::ResultVec::iterator rit_end = result.end();
   for( ;rit!=rit_end;++rit ){
diff --git a/PhysicsAnalysis/D3PDMaker/CaloSysD3PDMaker/src/LArNoisyROFillerTool.cxx b/PhysicsAnalysis/D3PDMaker/CaloSysD3PDMaker/src/LArNoisyROFillerTool.cxx
index d900ba8957e8a4b33810e7f2ed675afb24cdc67d..af0fc1dc0596f4f0c1c93bfc22b4f2a0a4e7cfe4 100644
--- a/PhysicsAnalysis/D3PDMaker/CaloSysD3PDMaker/src/LArNoisyROFillerTool.cxx
+++ b/PhysicsAnalysis/D3PDMaker/CaloSysD3PDMaker/src/LArNoisyROFillerTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 
@@ -44,8 +44,9 @@ StatusCode LArNoisyROFillerTool::fill (const LArNoisyROSummary& c)
   if (m_SaveFEBIDs) 
   {
     m_NoisyFEBIDs->clear();
-    for ( std::vector<HWIdentifier>::const_iterator it = noisyfebs.begin();
-	  it != noisyfebs.end(); it++ ) m_NoisyFEBIDs->push_back(it->get_identifier32().get_compact());
+    for (HWIdentifier hwid : noisyfebs) {
+      m_NoisyFEBIDs->push_back(hwid.get_identifier32().get_compact());
+    }
   }
 
 
diff --git a/PhysicsAnalysis/D3PDMaker/CaloSysD3PDMaker/src/SCFillerTool.cxx b/PhysicsAnalysis/D3PDMaker/CaloSysD3PDMaker/src/SCFillerTool.cxx
index 8725863dda5cea6ed9b4e619c34fdc1127f6dd95..8364ec0495f612a99940ffde10e94222dfa4d59f 100644
--- a/PhysicsAnalysis/D3PDMaker/CaloSysD3PDMaker/src/SCFillerTool.cxx
+++ b/PhysicsAnalysis/D3PDMaker/CaloSysD3PDMaker/src/SCFillerTool.cxx
@@ -1,12 +1,7 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id$
-/**
- */
-
-
 #include "AthenaKernel/errorcheck.h"
 
 #include <sstream>
@@ -278,7 +273,6 @@ void SCFillerTool::dumpHashTables( const CaloCellContainer& p ) {
     int key = scID;
     std::vector<const CaloCell*> v = (*it).second;
     int nl = v.size();
-    std::vector<const CaloCell*>::iterator vit;
     int pn = ((key >> 28) & 0x1) ? 1: -1;
     int calo = ((key >> 24) & 0xf)*pn;
     int region =  (key>>20) & 0xf;
@@ -289,8 +283,8 @@ void SCFillerTool::dumpHashTables( const CaloCellContainer& p ) {
       std::cout << "SCFillerTool::dumpHashTables() ===> scID = " << scID << " calo,pn,region,lay,ieta,jphi: " << calo << ", " << pn << ", " << region  << ", " << lay << ", " << ieta << ", " << jphi << std::endl;
       std::cout << "SCFillerTool::dumpHashTables() ===> scID = " << scID << " No. of cells: " << nl << std::endl;
       std::cout << "SCFillerTool::dumpHashTables() ===>        " ;
-      for( vit=v.begin(); vit!= v.end(); vit++) {
-	std::cout << *vit << ", " ;
+      for (const CaloCell* cell : v) {
+	std::cout << cell << ", " ;
       }
       std::cout << "" << std::endl;
     }
diff --git a/PhysicsAnalysis/D3PDMaker/JetTagD3PDMaker/share/MuonScatteringSigToolConfig.py b/PhysicsAnalysis/D3PDMaker/JetTagD3PDMaker/share/MuonScatteringSigToolConfig.py
index 5d1eb264e2c7ea113e9845cf7cc613d315b0adbd..a969e37c4ac092e46870b59edfde2d3d702922e0 100644
--- a/PhysicsAnalysis/D3PDMaker/JetTagD3PDMaker/share/MuonScatteringSigToolConfig.py
+++ b/PhysicsAnalysis/D3PDMaker/JetTagD3PDMaker/share/MuonScatteringSigToolConfig.py
@@ -17,6 +17,16 @@ muidMaterialAllocator = Trk__MaterialAllocator(
     AggregateMaterial         = True,
     Extrapolator              = atlasExtrapolator,
     TrackingGeometrySvc       = ServiceMgr.AtlasTrackingGeometrySvc)
+
+from InDetRecExample.TrackingCommon import use_tracking_geometry_cond_alg
+if use_tracking_geometry_cond_alg:
+  from AthenaCommon.AlgSequence import AthSequencer
+  condSeq = AthSequencer("AthCondSeq")
+  if not getattr (condSeq, 'AtlasTrackingGeometryCondAlg', None):
+    from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlg import ConfiguredTrackingGeometryCondAlg
+    condSeq += ConfiguredTrackingGeometryCondAlg()
+  muidMaterialAllocator.TrackingGeometryReadKey='AtlasTrackingGeometry'
+
 ToolSvc += muidMaterialAllocator
 
 # and the fitter
diff --git a/PhysicsAnalysis/D3PDMaker/TrackD3PDMaker/CMakeLists.txt b/PhysicsAnalysis/D3PDMaker/TrackD3PDMaker/CMakeLists.txt
index c83691606fe4c663034612c159e355bfde95a051..deddbc43775bed70ca8d5f517333a855035937f3 100644
--- a/PhysicsAnalysis/D3PDMaker/TrackD3PDMaker/CMakeLists.txt
+++ b/PhysicsAnalysis/D3PDMaker/TrackD3PDMaker/CMakeLists.txt
@@ -6,7 +6,7 @@ atlas_subdir( TrackD3PDMaker )
 # Component(s) in the package:
 atlas_add_component( TrackD3PDMaker
                      src/components/*.cxx
-                     LINK_LIBRARIES TrkParameters AthenaKernel CxxUtils Identifier EventPrimitives xAODBase xAODPrimitives xAODTracking GaudiKernel InDetIdentifier InDetReadoutGeometry InDetTestBLayerLib ParticleEvent D3PDMakerInterfaces D3PDMakerUtils Particle InDetRecToolInterfaces ITrackToVertex RecoToolInterfaces TrkEventPrimitives TrkParticleBase VxVertex InDetBeamSpotServiceLib )
+                     LINK_LIBRARIES TrkParameters AthenaKernel CxxUtils Identifier EventPrimitives xAODBase xAODPrimitives xAODTracking GaudiKernel InDetIdentifier InDetReadoutGeometry InDetTestBLayerLib ParticleEvent D3PDMakerInterfaces D3PDMakerUtils Particle InDetRecToolInterfaces ITrackToVertex RecoToolInterfaces TrkEventPrimitives TrkParticleBase VxVertex BeamSpotConditionsData )
 
 # Install files from the package:
 atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
diff --git a/PhysicsAnalysis/D3PDMaker/TrackD3PDMaker/src/TrackParticlePerigeeAtBSAssociationTool.cxx b/PhysicsAnalysis/D3PDMaker/TrackD3PDMaker/src/TrackParticlePerigeeAtBSAssociationTool.cxx
index 2d5b006be15b0b2980e0e2ed818434c22365b883..50b172622f970c44c056e4a75f5eb86676cc48ab 100644
--- a/PhysicsAnalysis/D3PDMaker/TrackD3PDMaker/src/TrackParticlePerigeeAtBSAssociationTool.cxx
+++ b/PhysicsAnalysis/D3PDMaker/TrackD3PDMaker/src/TrackParticlePerigeeAtBSAssociationTool.cxx
@@ -28,26 +28,19 @@ TrackParticlePerigeeAtBSAssociationTool::TrackParticlePerigeeAtBSAssociationTool
    const std::string& name,
    const IInterface* parent)
     : Base (type, name, parent),
-      m_iBeamCondSvc(0),
       m_trackToVertexTool("Reco::TrackToVertex")
 {
   declareProperty ("TrackToVertexTool", m_trackToVertexTool);
-  declareProperty("BeamCondSvcName", m_beamCondSvcName = "BeamCondSvc");
 }
 
 StatusCode TrackParticlePerigeeAtBSAssociationTool::initialize(){
 
   CHECK( Base::initialize() );
 
-  // Pick up the BeamConditionService
-  StatusCode sc = service(m_beamCondSvcName, m_iBeamCondSvc);
-  if (sc.isFailure() || m_iBeamCondSvc == 0) {
-    REPORT_MESSAGE (MSG::WARNING) << "Could not find BeamCondSvc: " <<  m_beamCondSvcName;
-    REPORT_MESSAGE (MSG::WARNING) << "Will use nominal beamspot at (0,0,0)";
-  }
+  ATH_CHECK(m_beamSpotKey.initialize());
 
   // Pick up the TrackToVertex tool
-  sc = m_trackToVertexTool.retrieve();
+  StatusCode sc = m_trackToVertexTool.retrieve();
   if(sc.isFailure()){
     REPORT_MESSAGE (MSG::ERROR) << "Could not retrieve TrackToVertexTool";
     return StatusCode::FAILURE;
@@ -68,11 +61,10 @@ TrackParticlePerigeeAtBSAssociationTool::get (const Rec::TrackParticle& track)
   // Protect against bad tracks.
   if (track.measuredPerigee()->covariance() && track.measuredPerigee()->covariance()->rows()==0)
     return 0;
-
+  SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
   /// Pick up the beamspot
   Amg::Vector3D beamSpot(0,0,0);
-  if (m_iBeamCondSvc)
-    beamSpot = m_iBeamCondSvc->beamVtx().position();
+  beamSpot = beamSpotHandle->beamVtx().position();
 
   return m_trackToVertexTool->perigeeAtVertex(track, beamSpot);
 }
@@ -88,8 +80,8 @@ TrackParticlePerigeeAtBSAssociationTool::get (const xAOD::TrackParticle& track)
 {
   /// Pick up the beamspot
   Amg::Vector3D beamSpot(0,0,0);
-  if (m_iBeamCondSvc)
-    beamSpot = m_iBeamCondSvc->beamVtx().position();
+  SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
+  beamSpot = beamSpotHandle->beamVtx().position();
 
   return m_trackToVertexTool->perigeeAtVertex(track, beamSpot);
 }
diff --git a/PhysicsAnalysis/D3PDMaker/TrackD3PDMaker/src/TrackParticlePerigeeAtBSAssociationTool.h b/PhysicsAnalysis/D3PDMaker/TrackD3PDMaker/src/TrackParticlePerigeeAtBSAssociationTool.h
index 03f486a080198c48bf16946647725727710c26f1..b214717ae297ed6719aac7355420925bd106cdb5 100644
--- a/PhysicsAnalysis/D3PDMaker/TrackD3PDMaker/src/TrackParticlePerigeeAtBSAssociationTool.h
+++ b/PhysicsAnalysis/D3PDMaker/TrackD3PDMaker/src/TrackParticlePerigeeAtBSAssociationTool.h
@@ -19,9 +19,8 @@
 #include "TrkParameters/TrackParameters.h"
 #include "xAODTracking/TrackParticle.h" 
 #include "GaudiKernel/ToolHandle.h"
-#include "InDetBeamSpotService/IBeamCondSvc.h"
 #include <vector>
-
+#include "BeamSpotConditionsData/BeamSpotData.h"
 
 namespace Rec {
   class TrackParticle;
@@ -75,9 +74,7 @@ public:
 
  private:
 
-  /* the beam condition service **/
-  IBeamCondSvc* m_iBeamCondSvc;
-  std::string   m_beamCondSvcName;
+  SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey { this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot" };
 
   /* Track to vertex extrapolator **/
   ToolHandle<Reco::ITrackToVertex> m_trackToVertexTool;
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkFlavourTag/python/FtagRun3DerivationConfig.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkFlavourTag/python/FtagRun3DerivationConfig.py
index 82be2e3127dc2765f2d55801e41e71ed6e293a00..62b9af5c61f3f440fb607e1d126220b784789c8b 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkFlavourTag/python/FtagRun3DerivationConfig.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkFlavourTag/python/FtagRun3DerivationConfig.py
@@ -5,20 +5,46 @@ from AthenaCommon.AthenaCommonFlags import jobproperties as jps
 
 from GaudiKernel.Configurable import WARNING
 
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaCommon.Configurable import Configurable
+from AthenaConfiguration.ComponentAccumulator import conf2toConfigurable
+from AthenaConfiguration.ComponentFactory import CompFactory
 
+# for backward compatability
+def FtagJetCollection(jetcol, seq, OutputLevel=WARNING):
+    FtagJetCollections([jetcol], seq, OutputLevel)
 
+# this should be able to tag a few collections
+def FtagJetCollections(jetcols, seq, OutputLevel=WARNING):
 
-def FtagJetCollection(jetcol, seq, OutputLevel=WARNING):
-    
+    Configurable.configurableRun3Behavior=1
+    from AthenaConfiguration.AllConfigFlags import ConfigFlags as cfgFlags
 
-    from AthenaCommon.AppMgr import athCondSeq
+    taggerlist = ['IP2D', 'IP3D', 'SV1', 'SoftMu']
 
-    from AthenaCommon.Configurable import Configurable
+    setupCondDb(cfgFlags, taggerlist)
+
+    acc = ComponentAccumulator()
+
+    if 'AntiKt4EMTopoJets' in jetcols:
+        acc.merge(RenameInputContainerEmTopoHacksCfg('oldAODVersion'))
+
+    for jetcol in jetcols:
+        acc.merge(getFtagComponent(cfgFlags, jetcol, taggerlist, OutputLevel))
+
+    Configurable.configurableRun3Behavior=0
+    algs = findAllAlgorithms(acc.getSequence("AthAlgSeq"))
+    for alg in algs:
+
+        seq += conf2toConfigurable(alg)
+
+    acc.wasMerged()
+
+
+# this returns a component accumulator, which is merged across jet
+# collections in FtagJetCollections above
+def getFtagComponent(cfgFlags, jetcol, taggerlist, OutputLevel=WARNING):
 
-    Configurable.configurableRun3Behavior=1
-    from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
-    from AthenaConfiguration.ComponentFactory import CompFactory
-    from AthenaConfiguration.ComponentAccumulator import conf2toConfigurable
     from BTagging.JetParticleAssociationAlgConfig import JetParticleAssociationAlgCfg
     from BTagging.JetBTaggingAlgConfig import JetBTaggingAlgCfg
     from BTagging.JetSecVertexingAlgConfig import JetSecVertexingAlgCfg
@@ -26,8 +52,6 @@ def FtagJetCollection(jetcol, seq, OutputLevel=WARNING):
     from BTagging.BTagTrackAugmenterAlgConfig import BTagTrackAugmenterAlgCfg
     from BTagging.BTagHighLevelAugmenterAlgConfig import BTagHighLevelAugmenterAlgCfg
     from BTagging.HighLevelBTagAlgConfig import HighLevelBTagAlgCfg
-    from AthenaConfiguration.AllConfigFlags import ConfigFlags as cfgFlags
-
 
     jetcol_name_without_Jets = jetcol.replace('Jets','')
     BTaggingCollection = cfgFlags.BTagging.OutputFiles.Prefix + jetcol_name_without_Jets
@@ -35,60 +59,35 @@ def FtagJetCollection(jetcol, seq, OutputLevel=WARNING):
     kwargs = {}
     kwargs['Release'] = '22'
 
-
     cfgFlags.Input.Files = jps.AthenaCommonFlags.FilesInput.get_Value()
 
-    
     acc = ComponentAccumulator()
 
-
-    taggerlist = ['IP2D', 'IP3D', 'SV1', 'SoftMu']
-
-
-    CalibrationChannelAliases = ["AntiKt4EMPFlow->AntiKt4EMPFlow,AntiKt4EMTopo,AntiKt4TopoEM,AntiKt4LCTopo"]
-
-    grades= cfgFlags.BTagging.Grades
-
-    RNNIPConfig = {'rnnip':''}
-
-    JetTagCalibCondAlg=CompFactory.Analysis.JetTagCalibCondAlg
-    jettagcalibcondalg = "JetTagCalibCondAlg"
-    readkeycalibpath = "/GLOBAL/BTagCalib/RUN12"
-    connSchema = "GLOBAL_OFL"
-    if not cfgFlags.Input.isMC:
-        readkeycalibpath = readkeycalibpath.replace("/GLOBAL/BTagCalib","/GLOBAL/Onl/BTagCalib")
-        connSchema = "GLOBAL"
-    histoskey = "JetTagCalibHistosKey"
-    from IOVDbSvc.CondDB import conddb
-
-    conddb.addFolder(connSchema, readkeycalibpath, className='CondAttrListCollection')
-    JetTagCalib = JetTagCalibCondAlg(jettagcalibcondalg, ReadKeyCalibPath=readkeycalibpath, HistosKey = histoskey, taggers = taggerlist,
-        channelAliases = CalibrationChannelAliases, IP2D_TrackGradePartitions = grades, RNNIP_NetworkConfig = RNNIPConfig)
-
-    athCondSeq+=conf2toConfigurable( JetTagCalib, indent="  " )
-    
     acc.merge(JetParticleAssociationAlgCfg(cfgFlags, jetcol_name_without_Jets, "InDetTrackParticles", 'BTagTrackToJetAssociator', **kwargs))
 
     SecVertexingAndAssociators = {'JetFitter':'BTagTrackToJetAssociator','SV1':'BTagTrackToJetAssociator'}
     for k, v in SecVertexingAndAssociators.items():
 
         acc.merge(JetSecVtxFindingAlgCfg(cfgFlags, jetcol_name_without_Jets, "PrimaryVertices", k, v))
-    
+
         acc.merge(JetSecVertexingAlgCfg(cfgFlags, BTaggingCollection, jetcol_name_without_Jets, "PrimaryVertices", k, v))
 
-    
+
     acc.merge( JetBTaggingAlgCfg(cfgFlags, BTaggingCollection = BTaggingCollection, JetCollection = jetcol_name_without_Jets, PrimaryVertexCollectionName="PrimaryVertices", TaggerList = taggerlist, SVandAssoc = SecVertexingAndAssociators) )
-    
 
 
     postTagDL2JetToTrainingMap={
         'AntiKt4EMPFlow': [
-        #'BTagging/201903/smt/antikt4empflow/network.json',
-        'BTagging/201903/rnnip/antikt4empflow/network.json',
-        'BTagging/201903/dl1r/antikt4empflow/network.json',
-        'BTagging/201903/dl1/antikt4empflow/network.json',
-        #'BTagging/201903/dl1rmu/antikt4empflow/network.json',
+            'BTagging/201903/rnnip/antikt4empflow/network.json',
+            'BTagging/201903/dl1r/antikt4empflow/network.json',
+            'BTagging/201903/dl1/antikt4empflow/network.json',
+        ],
+        'AntiKt4EMTopo': [
+            'BTagging/201903/rnnip/antikt4empflow/network.json',
+            'BTagging/201903/dl1r/antikt4empflow/network.json',
+            'BTagging/201903/dl1/antikt4empflow/network.json',
         ]
+
     }
 
     acc.merge(BTagTrackAugmenterAlgCfg(cfgFlags))
@@ -98,23 +97,52 @@ def FtagJetCollection(jetcol, seq, OutputLevel=WARNING):
     for jsonfile in postTagDL2JetToTrainingMap[jetcol_name_without_Jets]:
         acc.merge(HighLevelBTagAlgCfg(cfgFlags, BTaggingCollection=BTaggingCollection, TrackCollection='InDetTrackParticles', NNFile=jsonfile) )
 
+    return acc
 
-    Configurable.configurableRun3Behavior=0
-
-
-    algs = findAllAlgorithms(acc.getSequence("AthAlgSeq"))
-    
-    for alg in algs:
+# this probably only has to happen once
+def setupCondDb(cfgFlags, taggerlist):
+    from AthenaCommon.AppMgr import athCondSeq
+    CalibrationChannelAliases = ["AntiKt4EMPFlow->AntiKt4EMPFlow,AntiKt4EMTopo,AntiKt4TopoEM,AntiKt4LCTopo"]
+    grades= cfgFlags.BTagging.Grades
+    RNNIPConfig = {'rnnip':''}
 
-        seq += conf2toConfigurable(alg)
+    JetTagCalibCondAlg=CompFactory.Analysis.JetTagCalibCondAlg
+    jettagcalibcondalg = "JetTagCalibCondAlg"
+    readkeycalibpath = "/GLOBAL/BTagCalib/RUN12"
+    connSchema = "GLOBAL_OFL"
+    if not cfgFlags.Input.isMC:
+        readkeycalibpath = readkeycalibpath.replace("/GLOBAL/BTagCalib","/GLOBAL/Onl/BTagCalib")
+        connSchema = "GLOBAL"
+    histoskey = "JetTagCalibHistosKey"
+    from IOVDbSvc.CondDB import conddb
 
-    acc.wasMerged()
+    conddb.addFolder(connSchema, readkeycalibpath, className='CondAttrListCollection')
+    JetTagCalib = JetTagCalibCondAlg(jettagcalibcondalg, ReadKeyCalibPath=readkeycalibpath, HistosKey = histoskey, taggers = taggerlist,
+        channelAliases = CalibrationChannelAliases, IP2D_TrackGradePartitions = grades, RNNIP_NetworkConfig = RNNIPConfig)
 
-    
-    return
+    athCondSeq+=conf2toConfigurable( JetTagCalib, indent="  " )
 
 
 
+# Valerio's magic hacks for emtopo
+def RenameInputContainerEmTopoHacksCfg(suffix):
 
+    acc=ComponentAccumulator()
 
+    #Delete BTagging container read from input ESD
+    AddressRemappingSvc, ProxyProviderSvc=CompFactory.getComps("AddressRemappingSvc","ProxyProviderSvc",)
+    AddressRemappingSvc = AddressRemappingSvc("AddressRemappingSvc")
+    AddressRemappingSvc.TypeKeyRenameMaps += ['xAOD::JetAuxContainer#AntiKt4EMTopoJets.BTagTrackToJetAssociator->AntiKt4EMTopoJets.BTagTrackToJetAssociator_' + suffix]
+    AddressRemappingSvc.TypeKeyRenameMaps += ['xAOD::JetAuxContainer#AntiKt4EMTopoJets.JFVtx->AntiKt4EMTopoJets.JFVtx_' + suffix]
+    AddressRemappingSvc.TypeKeyRenameMaps += ['xAOD::JetAuxContainer#AntiKt4EMTopoJets.SecVtx->AntiKt4EMTopoJets.SecVtx_' + suffix]
 
+    AddressRemappingSvc.TypeKeyRenameMaps += ['xAOD::JetAuxContainer#AntiKt4EMTopoJets.btaggingLink->AntiKt4EMTopoJets.btaggingLink_' + suffix]
+    AddressRemappingSvc.TypeKeyRenameMaps += ['xAOD::BTaggingContainer#BTagging_AntiKt4EMTopo->BTagging_AntiKt4EMTopo_' + suffix]
+    AddressRemappingSvc.TypeKeyRenameMaps += ['xAOD::BTaggingAuxContainer#BTagging_AntiKt4EMTopoAux.->BTagging_AntiKt4EMTopo_' + suffix+"Aux."]
+    AddressRemappingSvc.TypeKeyRenameMaps += ['xAOD::VertexContainer#BTagging_AntiKt4EMTopoSecVtx->BTagging_AntiKt4EMTopoSecVtx_' + suffix]
+    AddressRemappingSvc.TypeKeyRenameMaps += ['xAOD::VertexAuxContainer#BTagging_AntiKt4EMTopoSecVtxAux.->BTagging_AntiKt4EMTopoSecVtx_' + suffix+"Aux."]
+    AddressRemappingSvc.TypeKeyRenameMaps += ['xAOD::BTagVertexContainer#BTagging_AntiKt4EMTopoJFVtx->BTagging_AntiKt4EMTopoJFVtx_' + suffix]
+    AddressRemappingSvc.TypeKeyRenameMaps += ['xAOD::BTagVertexAuxContainer#BTagging_AntiKt4EMTopoJFVtxAux.->BTagging_AntiKt4EMTopoJFVtx_' + suffix+"Aux."]
+    acc.addService(AddressRemappingSvc)
+    acc.addService(ProxyProviderSvc(ProviderNames = [ "AddressRemappingSvc" ]))
+    return acc
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkPhysicsValidation/share/PHYSVAL.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkPhysicsValidation/share/PHYSVAL.py
index 1ed4ba6d8ccb4b3cd17d6131d32b6999c0daeb11..c69d2713927fd20db5d710d072f7bdd3d9320bd4 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkPhysicsValidation/share/PHYSVAL.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkPhysicsValidation/share/PHYSVAL.py
@@ -161,8 +161,8 @@ SeqPHYSVAL += CfgMgr.DerivationFramework__DerivationKernel("PHYSVALKernel")
 # FLAVOUR TAGGING   
 #====================================================================
 
-from DerivationFrameworkFlavourTag.FtagRun3DerivationConfig import FtagJetCollection
-FtagJetCollection('AntiKt4EMPFlowJets',SeqPHYSVAL)
+from DerivationFrameworkFlavourTag.FtagRun3DerivationConfig import FtagJetCollections
+FtagJetCollections(['AntiKt4EMPFlowJets'],SeqPHYSVAL)
 
 
 #====================================================================
diff --git a/PhysicsAnalysis/ElectronPhotonID/EgammaAnalysisHelpers/EgammaAnalysisHelpers/AsgEGammaConfigHelper.h b/PhysicsAnalysis/ElectronPhotonID/EgammaAnalysisHelpers/EgammaAnalysisHelpers/AsgEGammaConfigHelper.h
index c99faa4d49ac8669d3c1231de0f7914d6829bcb5..741b1ddd8be717468f7a7866aaf8c60f5871d390 100644
--- a/PhysicsAnalysis/ElectronPhotonID/EgammaAnalysisHelpers/EgammaAnalysisHelpers/AsgEGammaConfigHelper.h
+++ b/PhysicsAnalysis/ElectronPhotonID/EgammaAnalysisHelpers/EgammaAnalysisHelpers/AsgEGammaConfigHelper.h
@@ -1,30 +1,38 @@
 /*
-    Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+    Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
-
 // Dear emacs, this is -*-c++-*-
 #ifndef ASGELEGAMMACONFIGHELPER_H
 #define ASGELEGAMMACONFIGHELPER_H
 
 /**
-   @brief Tool to simplify the configuration of some egamma tools based on TEnv input
-   @author Christos Anastopoulos (2017) Nils Gillwald (DESY, 2020) nils.gillwald@desy.de
+   @brief Tool to simplify the configuration of some egamma tools based on TEnv
+   input
+   @author Christos Anastopoulos (2017) Nils Gillwald (DESY, 2020)
+   nils.gillwald@desy.de
    @date February 2020
 */
+#include <map>
 #include <string>
 #include <vector>
-#include <map>
 class TEnv;
 
-namespace AsgConfigHelper{
-  std::string  findConfigFile (const std::string& input, const std::map<std::string,std::string>& configmap);
-  unsigned int  findMask (const std::string& input, const std::map<std::string,unsigned int>& maskmap);
-  std::vector<double> HelperDouble(const std::string& input,  TEnv& env);  
-  std::vector<float> HelperFloat(const std::string& input,  TEnv& env);  
-  std::vector<int> HelperInt(const std::string& input, TEnv& env);
-  std::vector<std::string> HelperString(const std::string& input, TEnv& env);  
+namespace AsgConfigHelper {
+std::string
+findConfigFile(const std::string& input,
+               const std::map<std::string, std::string>& configmap);
+unsigned int
+findMask(const std::string& input,
+         const std::map<std::string, unsigned int>& maskmap);
+std::vector<double>
+HelperDouble(const std::string& input, TEnv& env);
+std::vector<float>
+HelperFloat(const std::string& input, TEnv& env);
+std::vector<int>
+HelperInt(const std::string& input, TEnv& env);
+std::vector<std::string>
+HelperString(const std::string& input, TEnv& env);
 }
 
-
-#endif //ASGEGAMMACONFIGHELPER_H
+#endif // ASGEGAMMACONFIGHELPER_H
diff --git a/PhysicsAnalysis/ElectronPhotonID/EgammaAnalysisHelpers/Root/AsgEGammaConfigHelper.cxx b/PhysicsAnalysis/ElectronPhotonID/EgammaAnalysisHelpers/Root/AsgEGammaConfigHelper.cxx
index 545b8e4b20bcc9d35e9c470dd700313e6db1220d..896fc07757ac47add829f25acc7da095bfae226d 100644
--- a/PhysicsAnalysis/ElectronPhotonID/EgammaAnalysisHelpers/Root/AsgEGammaConfigHelper.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/EgammaAnalysisHelpers/Root/AsgEGammaConfigHelper.cxx
@@ -1,117 +1,126 @@
 /*
-    Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+    Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "EgammaAnalysisHelpers/AsgEGammaConfigHelper.h"
 #include "AsgMessaging/AsgMessaging.h"
 #include "TEnv.h"
 #include <iostream>
-#include <sstream>   
+#include <sstream>
 
-namespace AsgConfigHelper{
+namespace AsgConfigHelper {
 
-  std::string findConfigFile (const std::string& input, const std::map<std::string,std::string>& configmap){
-    auto confFile_itr=configmap.find(input);
-    if(confFile_itr == configmap.end()){
-      static const asg::AsgMessaging msg("Egamma::AsgConfigHelper");
-      msg.msg(MSG::WARNING)<<"Key "<<input<<" not found in map, no config file returned"<<endmsg;
-      return "";
-    }
-    return confFile_itr->second;
-  }
-  
-  unsigned int findMask (const std::string& input, const std::map<std::string,unsigned int>& maskmap){
-    auto mask_itr=maskmap.find(input);
-    if(mask_itr==maskmap.end()){
-      static const asg::AsgMessaging msg("Egamma::AsgConfigHelper");
-      msg.msg(MSG::WARNING)<<"Key "<<input<<" not found in map,  egammaPID::EgPidUndefined mask returned"<<endmsg;
-      // mask has the choice to default to all 1 or all 0 bits, choose the former
-      return std::numeric_limits<unsigned int>::max();
-    }
-    return static_cast < unsigned int> (mask_itr->second);  
+std::string
+findConfigFile(const std::string& input,
+               const std::map<std::string, std::string>& configmap)
+{
+  auto confFile_itr = configmap.find(input);
+  if (confFile_itr == configmap.end()) {
+    static const asg::AsgMessaging msg("Egamma::AsgConfigHelper");
+    msg.msg(MSG::WARNING) << "Key " << input
+                          << " not found in map, no config file returned"
+                          << endmsg;
+    return "";
   }
+  return confFile_itr->second;
+}
 
-  template <typename T>
-  bool strtof(const std::string& input, T& f){  
-    int diff = 0 ;
-    std::string tmp = input;
-    std::string::size_type first(0);
-    std::string::size_type last(0);
-    first = ( input.find('#') ) ;
- 
-    //if we do not find a comment character "#" we are fine
-    if (first == std::string::npos) {
-      std::istringstream buffer (tmp);
-      buffer>>f;
-      return true;
-    } 
-    else {
-      //if we have found comment character check if it is inlined between two "#"
-      last = (input.find('#',first+1) );
-      //if nor error
-      if (last == std::string::npos) {
-        static const asg::AsgMessaging msg("Egamma::AsgConfigHelper");
-	      msg.msg(MSG::WARNING)<<" Improper comment format , inline comment should be enclosed between two #  "<<endmsg;
-	      return false;
-      }
-      //else if between two "#" remove this part 
-      diff = last - first ;
-      tmp= tmp.erase(first,diff+1);
-      std::istringstream buffer (tmp);
-      buffer>>f;
-      return true;
-    }
+unsigned int
+findMask(const std::string& input,
+         const std::map<std::string, unsigned int>& maskmap)
+{
+  auto mask_itr = maskmap.find(input);
+  if (mask_itr == maskmap.end()) {
+    static const asg::AsgMessaging msg("Egamma::AsgConfigHelper");
+    msg.msg(MSG::WARNING)
+      << "Key " << input
+      << " not found in map,  egammaPID::EgPidUndefined mask returned"
+      << endmsg;
+    // mask has the choice to default to all 1 or all 0 bits, choose the former
+    return std::numeric_limits<unsigned int>::max();
   }
+  return static_cast<unsigned int>(mask_itr->second);
+}
 
-  template <typename T>  
-  std::vector<T> Helper (const std::string& input,  TEnv& env){ 
-    std::vector<T> CutVector;    
-    std::string env_input(env.GetValue(input.c_str(), ""));
-    if (!env_input.empty()) {
-      std::string::size_type end;
-      do {
-	      end = env_input.find(';');
-	      T  myValue(0);
-	      if(AsgConfigHelper::strtof(env_input.substr(0,end),myValue)){
-	        CutVector.push_back(myValue);
-	      }
-	      if (end != std::string::npos) {
-	        env_input= env_input.substr(end+1);
-	      }
-      } while (end != std::string::npos);     
+template<typename T>
+bool
+strtof(const std::string& input, T& f)
+{
+  int diff = 0;
+  std::string tmp = input;
+  std::string::size_type first(0);
+  std::string::size_type last(0);
+  first = (input.find('#'));
+
+  // if we do not find a comment character "#" we are fine
+  if (first == std::string::npos) {
+    std::istringstream buffer(tmp);
+    buffer >> f;
+    return true;
+  } else {
+    // if we have found comment character check if it is inlined between two "#"
+    last = (input.find('#', first + 1));
+    // if nor error
+    if (last == std::string::npos) {
+      static const asg::AsgMessaging msg("Egamma::AsgConfigHelper");
+      msg.msg(MSG::WARNING) << " Improper comment format , inline comment "
+                               "should be enclosed between two #  "
+                            << endmsg;
+      return false;
     }
-    return CutVector;
+    // else if between two "#" remove this part
+    diff = last - first;
+    tmp = tmp.erase(first, diff + 1);
+    std::istringstream buffer(tmp);
+    buffer >> f;
+    return true;
   }
 }
 
-//use the specializations 
-std::vector<double> AsgConfigHelper::HelperDouble(const std::string& input,  TEnv& env){
-  return AsgConfigHelper::Helper<double> ( input,env);
-}
-std::vector<float> AsgConfigHelper::HelperFloat(const std::string& input,  TEnv& env){
-  return AsgConfigHelper::Helper<float> (input, env);  
-}
-std::vector<int> AsgConfigHelper::HelperInt(const std::string& input, TEnv& env){
-  return AsgConfigHelper::Helper<int> (input, env);  
-}
-// template does not work for std::string because of the T myValue(0); declaration, so implement it again for std::string
-std::vector<std::string> AsgConfigHelper::HelperString(const std::string& input, TEnv& env){
-  std::vector<std::string> CutVector;
+template<typename T>
+std::vector<T>
+Helper(const std::string& input, TEnv& env)
+{
+  std::vector<T> CutVector;
   std::string env_input(env.GetValue(input.c_str(), ""));
   if (!env_input.empty()) {
     std::string::size_type end;
     do {
-	    end = env_input.find(';');
-	    std::string myValue("");
-	    if(AsgConfigHelper::strtof(env_input.substr(0,end),myValue)){
-	      CutVector.push_back(myValue);
-	    }
-	    if (end != std::string::npos) {
-	      env_input= env_input.substr(end+1);
-	    }
+      end = env_input.find(';');
+      T myValue{}; //default init
+      if (AsgConfigHelper::strtof(env_input.substr(0, end), myValue)) {
+        CutVector.push_back(myValue);
+      }
+      if (end != std::string::npos) {
+        env_input = env_input.substr(end + 1);
+      }
     } while (end != std::string::npos);
   }
   return CutVector;
 }
+}
 
+// use the specializations
+std::vector<double>
+AsgConfigHelper::HelperDouble(const std::string& input, TEnv& env)
+{
+  return AsgConfigHelper::Helper<double>(input, env);
+}
+std::vector<float>
+AsgConfigHelper::HelperFloat(const std::string& input, TEnv& env)
+{
+  return AsgConfigHelper::Helper<float>(input, env);
+}
+std::vector<int>
+AsgConfigHelper::HelperInt(const std::string& input, TEnv& env)
+{
+  return AsgConfigHelper::Helper<int>(input, env);
+}
+// template does not work for std::string because of the T myValue(0);
+// declaration, so implement it again for std::string
+std::vector<std::string>
+AsgConfigHelper::HelperString(const std::string& input, TEnv& env)
+{
+  return AsgConfigHelper::Helper<std::string>(input, env);
+}
 
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/ElectronPhotonSelectorTools/AsgElectronSelectorTool.h b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/ElectronPhotonSelectorTools/AsgElectronSelectorTool.h
index 099dc03f13cc73590c2243d96e1db1cb1a67ce48..ad9c9c2c10e306062e8fa8f82e1e631ca8c47f15 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/ElectronPhotonSelectorTools/AsgElectronSelectorTool.h
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/ElectronPhotonSelectorTools/AsgElectronSelectorTool.h
@@ -24,7 +24,7 @@ class AsgElectronSelectorTool final : public asg::AsgTool,
 
 public:
   /** Standard constructor */
-  AsgElectronSelectorTool( const std::string myname );
+  AsgElectronSelectorTool( const std::string& myname );
 
 
   /** Standard destructor */
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/Root/AsgElectronSelectorTool.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/Root/AsgElectronSelectorTool.cxx
index 78af09403266eb927ec3f6c8d126a4a62207ffc0..f7c313efb57e44be9d318e248a8b625c5b22ec04 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/Root/AsgElectronSelectorTool.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/Root/AsgElectronSelectorTool.cxx
@@ -35,7 +35,7 @@
 //=============================================================================
 // Standard constructor
 //=============================================================================
-AsgElectronSelectorTool::AsgElectronSelectorTool( std::string myname ) :
+AsgElectronSelectorTool::AsgElectronSelectorTool( const std::string& myname ) :
   AsgTool(myname),
   m_configFile{""},
   m_mvaTool(nullptr)
@@ -86,7 +86,7 @@ StatusCode AsgElectronSelectorTool::initialize()
 
   if (!m_configFile.empty()){
     std::string configFile = PathResolverFindCalibFile(m_configFile);
-    if (configFile==""){
+    if (configFile.empty()){
       ATH_MSG_ERROR("Could not locate " << m_configFile);
       return StatusCode::FAILURE;
     }
@@ -170,7 +170,7 @@ StatusCode AsgElectronSelectorTool::initialize()
       return StatusCode::FAILURE;
     }
 
-    if (m_cutSCT.size()){
+    if (!m_cutSCT.empty()){
       if (m_cutSCT.size() != numberOfExpectedEtaBins){
         ATH_MSG_ERROR("Configuration issue :  cutSCT expected size " << numberOfExpectedEtaBins <<
                       " input size " << m_cutSCT.size());
@@ -178,7 +178,7 @@ StatusCode AsgElectronSelectorTool::initialize()
       }
     }
 
-    if (m_cutPi.size()){
+    if (!m_cutPi.empty()){
       if (m_cutPi.size() != numberOfExpectedEtaBins){
         ATH_MSG_ERROR("Configuration issue :  cutPi expected size " << numberOfExpectedEtaBins <<
                       " input size " << m_cutPi.size());
@@ -186,7 +186,7 @@ StatusCode AsgElectronSelectorTool::initialize()
       }
     }
 
-    if (m_cutBL.size()){
+    if (!m_cutBL.empty()){
       if (m_cutBL.size() != numberOfExpectedEtaBins){
         ATH_MSG_ERROR("Configuration issue :  cutBL expected size " << numberOfExpectedEtaBins <<
                       " input size " << m_cutBL.size());
@@ -194,7 +194,7 @@ StatusCode AsgElectronSelectorTool::initialize()
       }
     }
 
-    if (m_cutAmbiguity.size()){
+    if (!m_cutAmbiguity.empty()){
       if (m_cutAmbiguity.size() != numberOfExpectedEtaBins){
         ATH_MSG_ERROR("Configuration issue :  cutAmbiguity expected size " << numberOfExpectedEtaBins <<
                       " input size " << m_cutAmbiguity.size());
@@ -364,7 +364,7 @@ asg::AcceptData AsgElectronSelectorTool::accept( const EventContext& ctx, const
   if (!passKine){return acceptData;}
 
   // ambiguity bit
-  if (m_cutAmbiguity.size()){
+  if (!m_cutAmbiguity.empty()){
     if (!ElectronSelectorHelpers::passAmbiguity((xAOD::AmbiguityTool::AmbiguityType)ambiguityBit, m_cutAmbiguity[etaBin])){
       ATH_MSG_DEBUG("MVA macro: ambiguity Bit Failed.");
       passAmbiguity = false;
@@ -372,21 +372,21 @@ asg::AcceptData AsgElectronSelectorTool::accept( const EventContext& ctx, const
   }
 
   // blayer cut
-  if (m_cutBL.size()) {
+  if (!m_cutBL.empty()) {
     if(m_cutBL[etaBin] == 1 && !passBLayerRequirement){
       ATH_MSG_DEBUG("MVA macro: Blayer cut failed.");
       passNBlayer = false;
     }
   }
   // pixel cut
-  if (m_cutPi.size()){
+  if (!m_cutPi.empty()){
     if (nPixHitsPlusDeadSensors < m_cutPi[etaBin]){
       ATH_MSG_DEBUG("MVA macro: Pixels Failed.");
       passNPixel = false;
     }
   }
   // SCT cut
-  if (m_cutSCT.size()){
+  if (!m_cutSCT.empty()){
     if (nSiHitsPlusDeadSensors < m_cutSCT[etaBin]){
       ATH_MSG_DEBUG( "MVA macro: Silicon Failed.");
       passNSilicon = false;
@@ -396,7 +396,7 @@ asg::AcceptData AsgElectronSelectorTool::accept( const EventContext& ctx, const
   double cutDiscriminant;
   unsigned int ibin_combinedMVA = etBin*s_fnDiscEtaBins+etaBin; // Must change if number of eta bins changes!.
 
-  if (m_cutSelector.size()){
+  if (!m_cutSelector.empty()){
     // To protect against a binning mismatch, which should never happen
     if (ibin_combinedMVA >= m_cutSelector.size()){
       throw std::runtime_error("AsgElectronSelectorTool: The desired eta/pt bin is outside of the range specified by the input. This should never happen! This indicates a mismatch between the binning in the configuration file and the tool implementation." );
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/Root/ElectronDNNCalculator.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/Root/ElectronDNNCalculator.cxx
index 82ff89af492f6ff9cb06b92677c3aacc25e28ec0..4397863948ed5e4fa49d5f2e11e894c2e5bb6706 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/Root/ElectronDNNCalculator.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools/Root/ElectronDNNCalculator.cxx
@@ -31,7 +31,7 @@ ElectronDNNCalculator::ElectronDNNCalculator(AsgElectronSelectorTool* owner,
 {
   ATH_MSG_INFO("Initializing ElectronDNNCalculator...");
 
-  if (modelFileName.size() == 0){
+  if (modelFileName.empty()){
     throw std::runtime_error("No file found at '" + modelFileName + "'");
   }
 
@@ -56,7 +56,7 @@ ElectronDNNCalculator::ElectronDNNCalculator(AsgElectronSelectorTool* owner,
   m_graph = std::make_unique<lwt::generic::FastGraph<float>>(parsedGraph, order);
 
 
-  if (quantileFileName.size() == 0){
+  if (quantileFileName.empty()){
     throw std::runtime_error("No file found at '" + quantileFileName + "'");
   }
 
@@ -150,7 +150,7 @@ int ElectronDNNCalculator::readQuantileTransformer( TTree* tree, const std::vect
   sc = tree->SetBranchAddress("references", &references) == -5 ? 0 : 1;
 
   std::map<std::string, double> readVars;
-  for ( auto var : variables ){
+  for ( const auto& var : variables ){
       sc = tree->SetBranchAddress(TString(var), &readVars[var]) == -5 ? 0 : 1;
   }
   for (int i = 0; i < tree->GetEntries(); i++){
diff --git a/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/ATLAS_CHECK_THREAD_SAFETY b/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..fd67419ce8710dc326b240ceb7e9eec54ffa2e38
--- /dev/null
+++ b/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection
diff --git a/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/PhotonEfficiencyCorrection/AsgPhotonEfficiencyCorrectionTool.h b/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/PhotonEfficiencyCorrection/AsgPhotonEfficiencyCorrectionTool.h
index b768614117ecb548d394056e3a94065ec0cd61c8..fb500318ef1c28ce0109973f31b30e1753e13bd5 100644
--- a/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/PhotonEfficiencyCorrection/AsgPhotonEfficiencyCorrectionTool.h
+++ b/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/PhotonEfficiencyCorrection/AsgPhotonEfficiencyCorrectionTool.h
@@ -44,7 +44,7 @@ class AsgPhotonEfficiencyCorrectionTool
 
 public:
   /// Standard constructor
-  AsgPhotonEfficiencyCorrectionTool ( const std::string myname );
+  AsgPhotonEfficiencyCorrectionTool ( const std::string& myname );
 
   /// Standard destructor
   virtual ~AsgPhotonEfficiencyCorrectionTool();
@@ -108,7 +108,7 @@ private:
   std::string m_sysSubstring;
   
   // Get the correction filename from the map
-  std::string getFileName(std::string isoWP, std::string trigWP, bool isConv);
+  std::string getFileName(const std::string& isoWP, const std::string& trigWP, bool isConv);
   
   // Set prefix of the corresponding calibration filenames:
   std::string m_file_prefix_ID="offline.Tight";
diff --git a/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/PhotonEfficiencyCorrection/IAsgPhotonEfficiencyCorrectionTool.h b/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/PhotonEfficiencyCorrection/IAsgPhotonEfficiencyCorrectionTool.h
deleted file mode 100644
index dcf194cde6ce4e444e7b97e817234f889a32a846..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/PhotonEfficiencyCorrection/IAsgPhotonEfficiencyCorrectionTool.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-//IAsgPhotonEfficiencyCorrection.h to be used in the tool.
-#ifndef __IASGPHOTONEFFICIENCYCORRECTION__
-#define __IASGPHOTONEFFICIENCYCORRECTION__
-
-#include "EgammaAnalysisInterfaces/IAsgPhotonEfficiencyCorrectionTool.h"
-#pragma message "In the process of moving the Interface part under PhysicsAnalysis/Interfaces/EgammaAnalysisInterfaces"
-
-#endif
-
diff --git a/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/Root/AsgPhotonEfficiencyCorrectionTool.cxx b/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/Root/AsgPhotonEfficiencyCorrectionTool.cxx
index a3178fe0f472f69390f168cc72d3b2db9240623e..01f6a32efb86ec66cddbd53508932c2a03567249 100644
--- a/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/Root/AsgPhotonEfficiencyCorrectionTool.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/Root/AsgPhotonEfficiencyCorrectionTool.cxx
@@ -14,10 +14,10 @@
 #include "PhotonEfficiencyCorrection/AsgPhotonEfficiencyCorrectionTool.h"
 
 // STL includes
-#include <string>
 #include <cfloat>
+#include <climits>
 #include <iostream>
-#include <limits.h>
+#include <string>
 
 // Include the return object
 #include "PATCore/PATCoreEnums.h"
@@ -45,11 +45,11 @@ typedef Root::TPhotonEfficiencyCorrectionTool::Result Result;
 // =============================================================================
 // Standard constructor
 // =============================================================================
-AsgPhotonEfficiencyCorrectionTool::AsgPhotonEfficiencyCorrectionTool( std::string myname ) : 
+AsgPhotonEfficiencyCorrectionTool::AsgPhotonEfficiencyCorrectionTool( const std::string& myname ) : 
   AsgTool(myname),
-  m_rootTool_unc(0),
-  m_rootTool_con(0),
-  m_appliedSystematics(0),
+  m_rootTool_unc(nullptr),
+  m_rootTool_con(nullptr),
+  m_appliedSystematics(nullptr),
   m_sysSubstring("")
 {
 
@@ -106,11 +106,11 @@ StatusCode AsgPhotonEfficiencyCorrectionTool::initialize()
   std::vector < std::string > corrFileNameList;
 
   // First check if the tool is initialized using the input files or map
-  if(m_mapFile.size()){ // using map file
+  if(!m_mapFile.empty()){ // using map file
      corrFileNameList.push_back(getFileName(m_isoWP,m_trigger,true));	// converted photons input
 	 corrFileNameList.push_back(getFileName(m_isoWP,m_trigger,false));  // unconverted photons input
   }
-  else if(m_corrFileNameConv.size() && m_corrFileNameUnconv.size()){ // initialize the tool using input files (old scheme)
+  else if(!m_corrFileNameConv.empty() && !m_corrFileNameUnconv.empty()){ // initialize the tool using input files (old scheme)
   	corrFileNameList.push_back(m_corrFileNameConv);
 	corrFileNameList.push_back(m_corrFileNameUnconv);
   }
@@ -140,7 +140,7 @@ StatusCode AsgPhotonEfficiencyCorrectionTool::initialize()
   if( corrFileNameList[0].find(m_file_prefix_ID) != std::string::npos) m_sysSubstring="ID_";
   if( corrFileNameList[0].find(m_file_prefix_ISO) != std::string::npos) m_sysSubstring="ISO_";
   if( corrFileNameList[0].find(m_file_prefix_Trig) != std::string::npos) m_sysSubstring="TRIGGER_";
-  if(m_sysSubstring == "") {ATH_MSG_ERROR ( "Invalid input file" ); return StatusCode::FAILURE;}
+  if(m_sysSubstring.empty()) {ATH_MSG_ERROR ( "Invalid input file" ); return StatusCode::FAILURE;}
 
   // Configure the underlying Root tool
   m_rootTool_con->addFileName( corrFileNameList[0] );
@@ -418,7 +418,7 @@ applySystematicVariation ( const CP::SystematicSet& systConfig )
 // Map Key Feature
 //===============================================================================
 // Gets the correction filename from map
-std::string AsgPhotonEfficiencyCorrectionTool::getFileName(std::string isoWP, std::string trigWP, bool isConv) {  
+std::string AsgPhotonEfficiencyCorrectionTool::getFileName(const std::string& isoWP, const std::string& trigWP, bool isConv) {  
 
   // First locate the map file:
   std::string mapFileName = PathResolverFindCalibFile( m_mapFile );
diff --git a/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/src/testAthenaPhotonAlg.cxx b/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/src/testAthenaPhotonAlg.cxx
index 3c8f8ed6051ae928c55106aa1a6f02cd1847949e..2f0eafc788efef48ac722045a17c84bcf14d7ea0 100644
--- a/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/src/testAthenaPhotonAlg.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/src/testAthenaPhotonAlg.cxx
@@ -41,7 +41,7 @@ StatusCode testAthenaPhotonAlg::execute() {
 //----------------------------
  // Event information
  //--------------------------- 
- const xAOD::EventInfo* eventInfo = 0; //NOTE: Everything that comes from the storegate direct from the input files is const!
+ const xAOD::EventInfo* eventInfo = nullptr; //NOTE: Everything that comes from the storegate direct from the input files is const!
 
  // ask the event store to retrieve the xAOD EventInfo container
  //ATH_CHECK( evtStore()->retrieve( eventInfo, "EventInfo") );  // the second argument ("EventInfo") is the key name
@@ -59,7 +59,7 @@ StatusCode testAthenaPhotonAlg::execute() {
  //---------
  // photons
  //---------
- const xAOD::PhotonContainer* photons = 0;
+ const xAOD::PhotonContainer* photons = nullptr;
  ATH_CHECK( evtStore()->retrieve( photons, "Photons") );
  ATH_MSG_DEBUG("Found "<<photons->size() <<" photons in event, itterate....");
  
diff --git a/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/util/PrintPhotonSF.cxx b/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/util/PrintPhotonSF.cxx
index f0f5e1f12d45a9f92dff5b66cf515ce35be71dc2..0576a441b11b4395955c8b4ef991d56e5c939da1 100644
--- a/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/util/PrintPhotonSF.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/PhotonEfficiencyCorrection/util/PrintPhotonSF.cxx
@@ -5,10 +5,10 @@
 //michael.pitt@cern.ch
 
 // System include(s):
-#include <stdio.h>
+#include <boost/filesystem.hpp>
+#include <cstdio>
 #include <cstdlib>
 #include <iostream>
-#include <boost/filesystem.hpp>
 
 // ROOT ide(s):
 #include "TFile.h"
@@ -67,7 +67,7 @@ int main (int argc, const char * argv[]) {
 	
 	// read first run number from the directory name:
 	int run_number = atoi(dirName.Tokenize("_")->First()->GetName());
-	if(getenv("ROOTCOREDIR")==NULL){
+	if(getenv("ROOTCOREDIR")==nullptr){
         cout << "Please setup RootCore before running the PrintPhotonSF [file]"<<endl;
         return 0.;
         }
diff --git a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/HighLevelBTagAlgConfig.py b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/HighLevelBTagAlgConfig.py
index 2225616ba33593b3d14272b7d2bdde0ca40e7c65..e7af664a77fdfd79b0c761bfdb98656942c5b0aa 100644
--- a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/HighLevelBTagAlgConfig.py
+++ b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/HighLevelBTagAlgConfig.py
@@ -46,7 +46,7 @@ def HighLevelBTagAlgCfg(ConfigFlags, BTaggingCollection, TrackCollection, NNFile
     options['BTaggingCollectionName'] = BTaggingCollection
     options['TrackContainer'] = TrackCollection
     options['JetDecorator'] = dl2
-    options['name'] = Name.lower()
+    options['name'] = '_'.join([Name.lower(), BTaggingCollection])
 
     # -- create the association algorithm
     acc.addEventAlgo(Analysis__HighLevelBTagAlg(**options))
diff --git a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/CMakeLists.txt b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/CMakeLists.txt
index f6fd74a94a7b7b2b4a90ca5972e54892a7e69dd6..22434c39b16d0c8a4f70856afc11d2ae509dd301 100644
--- a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/CMakeLists.txt
+++ b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/CMakeLists.txt
@@ -12,5 +12,6 @@ atlas_add_component( JetTagDQA
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} GaudiKernel AthenaBaseComps AthenaMonitoringLib xAODBTagging xAODBase xAODJet xAODTracking ParticleJetToolsLib TrkValHistUtils )
+                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} GaudiKernel AthenaBaseComps AthenaMonitoringLib xAODBTagging xAODBase xAODJet xAODTracking ParticleJetToolsLib TrkValHistUtils InDetTrackSystematicsToolsLib )
 
+atlas_install_data( data/*.json )
diff --git a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/data/PhysValBtag_VariablesMenu.json b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/data/PhysValBtag_VariablesMenu.json
new file mode 100755
index 0000000000000000000000000000000000000000..af1a674352badcacd98b16d2364eef1fd23d031f
--- /dev/null
+++ b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/data/PhysValBtag_VariablesMenu.json
@@ -0,0 +1,1610 @@
+{
+    "template": {
+        "histName": {
+            "_comment": "",
+            "title": "title",
+            "xtitle": "xtitle",
+            "ytitle": "ytitle",
+            "path":  {"ART": "path", "PHYSVAL": "path"},
+            "xbins": 100,
+            "xmin": -1.0,
+            "xmax": 1.0,
+            "type": "TH1D",
+            "forData": "true"
+        }
+    },
+
+    "GLOBAL": {
+        "nJets": {
+            "_comment": "",
+            "title": "jet multiplicity",
+            "xtitle": "Number of jets",
+            "ytitle": "Events",
+            "path":  {"ART": "Jet_quality", "PHYSVAL": "jet"},
+            "xbins": 51,
+            "xmin": -0.5,
+            "xmax": 50.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nTracks": {
+            "_comment": "",
+            "title": "track multiplicity",
+            "xtitle": "Number of tracks",
+            "ytitle": "Events",
+            "path":  {"ART": "Run_plots", "PHYSVAL": "global"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 3000,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nPrimVtx": {
+            "_comment": "",
+            "title": "number of primary vertices",
+            "xtitle": "Number of PVs",
+            "ytitle": "Events",
+            "path":  {"ART": "Run_plots", "PHYSVAL": "global"},
+            "xbins": 101,
+            "xmin": -0.5,
+            "xmax": 100.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nTracksPrimVtx": {
+            "_comment": "",
+            "title": "number of tracks from selected PV",
+            "xtitle": "Number of tracks",
+            "ytitle": "Events",
+            "path":  {"ART": "Run_plots", "PHYSVAL": "global"},
+            "xbins": 201,
+            "xmin": -0.5,
+            "xmax": 200.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "PV_x": {
+            "_comment": "",
+            "title": "x pos of selected PV",
+            "xtitle": "x [mm]",
+            "ytitle": "Events",
+            "path":  {"PHYSVAL": "global"},
+            "xbins": 50,
+            "xmin": -0.6,
+            "xmax": -0.4,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "PV_y": {
+            "_comment": "",
+            "title": "y pos of selected PV",
+            "xtitle": "y [mm]",
+            "ytitle": "Events",
+            "path":  {"PHYSVAL": "global"},
+            "xbins": 50,
+            "xmin": -0.6,
+            "xmax": -0.4,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "PV_z": {
+            "_comment": "",
+            "title": "z pos of selected PV",
+            "xtitle": "z [mm]",
+            "ytitle": "Events",
+            "path":  {"PHYSVAL": "global"},
+            "xbins": 50,
+            "xmin": -200,
+            "xmax": 200,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nJetsWithMuon": {
+            "_comment": "",
+            "title": "number of jets that contain a muon",
+            "xtitle": "Number of jets",
+            "ytitle": "Events",
+            "path":  {"PHYSVAL": "global"},
+            "xbins": 21,
+            "xmin": -0.5,
+            "xmax": 20.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nJetsWithSV": {
+            "_comment": "",
+            "title": "number of jets that contain a SV (SV1)",
+            "xtitle": "Number of jets",
+            "ytitle": "Events",
+            "path":  {"PHYSVAL": "global"},
+            "xbins": 21,
+            "xmin": -0.5,
+            "xmax": 20.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "fracJetsWithMuon": {
+            "_comment": "",
+            "title": "fraction of jets that contain a muon",
+            "xtitle": "Fraction of jets",
+            "ytitle": "Events",
+            "path":  {"PHYSVAL": "global"},
+            "xbins": 50,
+            "xmin": -0.01,
+            "xmax": 1.01,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "fracJetsWithSV": {
+            "_comment": "",
+            "title": "fraction of jets that contain a SV (SV1)",
+            "xtitle": "Fraction of jets",
+            "ytitle": "Events",
+            "path":  {"PHYSVAL": "global"},
+            "xbins": 50,
+            "xmin": -0.01,
+            "xmax": 1.01,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nJetsThatPassedWPCuts": {
+            "_comment": "",
+            "title": "number of jets that passed the WP cuts",
+            "xtitle": "Number of jets",
+            "ytitle": "Events",
+            "path":  {"PHYSVAL": "jet"},
+            "xbins": 21,
+            "xmin": -0.5,
+            "xmax": 20.5,
+            "type": "TH1D",
+            "forData": "true"
+        }
+
+    },
+
+    "JET": {
+        "jet_E": {
+            "_comment": "",
+            "title": "E",
+            "xtitle": "E [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "jet"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1000,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "jet_E_Zprime": {
+            "_comment": "",
+            "title": "E on Zprime samples",
+            "xtitle": "E [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "jet"},
+            "xbins": 100,
+            "xmin": 400,
+            "xmax": 3000,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "jet_pT": {
+            "_comment": "",
+            "title": "p_{T}",
+            "xtitle": "p_{T} [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "jet"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1000,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "jet_pT_Zprime": {
+            "_comment": "",
+            "title": "p_{T} on Zprime samples",
+            "xtitle": "p_{T} [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "jet"},
+            "xbins": 100,
+            "xmin": 400,
+            "xmax": 3000,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "jet_eta": {
+            "_comment": "",
+            "title": "#eta",
+            "xtitle": "#eta [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "jet"},
+            "xbins": 100,
+            "xmin": -5,
+            "xmax": 5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "jet_phi": {
+            "_comment": "",
+            "title": "#varphi",
+            "xtitle": "#varphi [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "jet"},
+            "xbins": 200,
+            "xmin": -3.2,
+            "xmax": 3.2,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "truth_label": {
+            "_comment": "",
+            "title": "truthLabel",
+            "xtitle": "truthLabel",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "jet"},
+            "xbins": 17,
+            "xmin": -0.5,
+            "xmax": 16.5,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "muon_pT_frac": {
+            "_comment": "",
+            "title": "muon p_{T}^{frac}",
+            "xtitle": "p_{T}(muon) / p_{T}(jet)",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "muon"},
+            "xbins": 100,
+            "xmin": -0.01,
+            "xmax": 1.5,
+            "type": "TH1D",
+            "forData": "true"
+        }
+
+    },
+
+    "TAGGER": {
+
+        "IP3D": {
+            "_comment": "pb, pc, and pu",
+            "title": "IP3D",
+            "xtitle": "IP3D px",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1,
+            "forEach": ["pb", "pc", "pu"],
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "RNNIP": {
+            "_comment": "pb, pc, and pu",
+            "title": "RNNIP",
+            "xtitle": "RNNIP px",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1,
+            "forEach": ["pb", "pc", "pu"],
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "SV1": {
+            "_comment": "pb, pc, and pu",
+            "title": "SV1",
+            "xtitle": "SV1 px",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1,
+            "forEach": ["pb", "pc", "pu"],
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "DL1": {
+            "_comment": "pb, pc, and pu",
+            "title": "DL1",
+            "xtitle": "DL1 px",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1,
+            "forEach": ["pb", "pc", "pu"],
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "DL1r": {
+            "_comment": "pb, pc, and pu",
+            "title": "DL1r",
+            "xtitle": "DL1r px",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1,
+            "forEach": ["pb", "pc", "pu"],
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP3D_nTracks": {
+            "_comment": "",
+            "title": "number of IP3D tracks",
+            "xtitle": "nTracks",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 21,
+            "xmin": -0.5,
+            "xmax": 20.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP2D_nTracks": {
+            "_comment": "",
+            "title": "number of IP2D tracks",
+            "xtitle": "nTracks",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "old_taggers"},
+            "xbins": 21,
+            "xmin": -0.5,
+            "xmax": 20.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP3D_gradeOfTracks": {
+            "_comment": "",
+            "title": "IP3D grade of tracks",
+            "xtitle": "grade of tracks",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 14,
+            "xmin": -0.5,
+            "xmax": 13.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP2D_gradeOfTracks": {
+            "_comment": "",
+            "title": "IP2D grade of tracks",
+            "xtitle": "grade of tracks",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "old_taggers"},
+            "xbins": 14,
+            "xmin": -0.5,
+            "xmax": 13.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP3D_d0wrtPVOfTracks": {
+            "_comment": "",
+            "title": "IP3D d_{0} wrt PV of tracks",
+            "xtitle": "d_{0} [mm]",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 200,
+            "xmin": -2,
+            "xmax": 2,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP3D_z0wrtPVOfTracks": {
+            "_comment": "",
+            "title": "IP3D z_{0} wrt PV of tracks",
+            "xtitle": "z_{0} [mm]",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 200,
+            "xmin": -0.5,
+            "xmax": 0.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP3D_sigD0wrtPVOfTracks": {
+            "_comment": "",
+            "title": "IP3D sig(d_{0}) wrt PV of tracks",
+            "xtitle": "sig(d_{0})",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 200,
+            "xmin": -2,
+            "xmax": 2,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP3D_sigZ0wrtPVOfTracks": {
+            "_comment": "",
+            "title": "IP3D sig(z_{0}) wrt PV of tracks",
+            "xtitle": "sig(z_{0})",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 200,
+            "xmin": -2,
+            "xmax": 2,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP3D_weightBOfTracks": {
+            "_comment": "",
+            "title": "IP3D weight B of tracks",
+            "xtitle": "weight B of tracks",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 200,
+            "xmin": -2,
+            "xmax": 2,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP3D_weightCOfTracks": {
+            "_comment": "",
+            "title": "IP3D weight C of tracks",
+            "xtitle": "weight C of tracks",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 200,
+            "xmin": -2,
+            "xmax": 2,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP3D_weightUOfTracks": {
+            "_comment": "",
+            "title": "IP3D weight U of tracks",
+            "xtitle": "weight U of tracks",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 200,
+            "xmin": -2,
+            "xmax": 2,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP2D_weightBOfTracks": {
+            "_comment": "",
+            "title": "IP2D weight B of tracks",
+            "xtitle": "weight B of tracks",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "old_taggers"},
+            "xbins": 200,
+            "xmin": -2,
+            "xmax": 2,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP2D_weightCOfTracks": {
+            "_comment": "",
+            "title": "IP2D weight C of tracks",
+            "xtitle": "weight C of tracks",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "old_taggers"},
+            "xbins": 200,
+            "xmin": -2,
+            "xmax": 2,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "IP2D_weightUOfTracks": {
+            "_comment": "",
+            "title": "IP2D weight U of tracks",
+            "xtitle": "weight U of tracks",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "old_taggers"},
+            "xbins": 200,
+            "xmin": -2,
+            "xmax": 2,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "SV1_nGoodTracks": {
+            "_comment": "",
+            "title": "number of good tracks in SV1",
+            "xtitle": "nTracks",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 21,
+            "xmin": -0.5,
+            "xmax": 20.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "SV0_nGoodTracks": {
+            "_comment": "",
+            "title": "number of good tracks in SV0",
+            "xtitle": "nTracks",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "old_taggers"},
+            "xbins": 21,
+            "xmin": -0.5,
+            "xmax": 20.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "llr": {
+            "_comment": "",
+            "title": "loglikelihoodratio of matched jets",
+            "xtitle": "loglikelihoodratio",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 250,
+            "xmin": -10,
+            "xmax": 40,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "llr_nTracksCut": {
+            "_comment": "",
+            "title": "loglikelihoodratio of matched jets with nTracks cut",
+            "xtitle": "loglikelihoodratio",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 250,
+            "xmin": -10,
+            "xmax": 40,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "llr_old_taggers": {
+            "_comment": "",
+            "title": "loglikelihoodratio of matched jets",
+            "xtitle": "loglikelihoodratio",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "old_taggers"},
+            "xbins": 250,
+            "xmin": -10,
+            "xmax": 40,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "llr_nTracksCut_old_taggers": {
+            "_comment": "",
+            "title": "loglikelihoodratio of matched jets with nTracks cut",
+            "xtitle": "loglikelihoodratio",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "old_taggers"},
+            "xbins": 250,
+            "xmin": -10,
+            "xmax": 40,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "llr_MV": {
+            "_comment": "has a different range",
+            "title": "loglikelihoodratio of matched jets",
+            "xtitle": "loglikelihoodratio",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "old_taggers"},
+            "xbins": 250,
+            "xmin": -1,
+            "xmax": 1,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "llr_nTracksCut_MV": {
+            "_comment": "has a different range",
+            "title": "loglikelihoodratio of matched jets with nTracks cut",
+            "xtitle": "loglikelihoodratio",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "old_taggers"},
+            "xbins": 250,
+            "xmin": -1,
+            "xmax": 1,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "pT_llrCut": {
+            "_comment": "",
+            "title": "p_{T} of matched jets",
+            "xtitle": "p_{T} [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1000,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "pT_llrCut_old_taggers": {
+            "_comment": "",
+            "title": "p_{T} of matched jets",
+            "xtitle": "p_{T} [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "old_taggers"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1000,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "pT_llrCut_Zprime": {
+            "_comment": "",
+            "title": "p_{T} of matched jets on Zprime samples",
+            "xtitle": "p_{T} [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 100,
+            "xmin": 400,
+            "xmax": 3000,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "pT_llrCut_Zprime_old_taggers": {
+            "_comment": "",
+            "title": "p_{T} of matched jets on Zprime samples",
+            "xtitle": "p_{T} [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "old_taggers"},
+            "xbins": 100,
+            "xmin": 400,
+            "xmax": 3000,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "Lxy_llrCut": {
+            "_comment": "",
+            "title": "(SV1) L_{xy} of matched jets",
+            "xtitle": "L_{xy} [mm]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 50,
+            "xmin": 0,
+            "xmax": 75,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "Lxy_llrCut_old_taggers": {
+            "_comment": "",
+            "title": "(SV1) L_{xy} of matched jets",
+            "xtitle": "L_{xy} [mm]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "old_taggers"},
+            "xbins": 50,
+            "xmin": 0,
+            "xmax": 75,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "efficiency_vs_rejection": {
+            "_comment": "",
+            "title": "b-efficiency vs. rejection",
+            "xtitle": "efficiency",
+            "ytitle": "rejection",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1,
+            "ymin": 0,
+            "ymax": 1000000,
+            "type": "TProfile",
+            "forData": "false"
+        },
+
+        "efficiency_vs_llr": {
+            "_comment": "",
+            "title": "efficiency vs. loglikelihoodratio",
+            "xtitle": "loglikelihoodratio",
+            "ytitle": "efficiency",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 250,
+            "xmin": -10,
+            "xmax": 40,
+            "ymin": 0,
+            "ymax": 1,
+            "type": "TProfile",
+            "forData": "false"
+        },
+
+        "efficiency_vs_llr_MV": {
+            "_comment": "has a different range",
+            "title": "efficiency vs. loglikelihoodratio",
+            "xtitle": "loglikelihoodratio",
+            "ytitle": "efficiency",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 250,
+            "xmin": -1,
+            "xmax": 1,
+            "ymin": 0,
+            "ymax": 1,
+            "type": "TProfile",
+            "forData": "false"
+        },
+
+        "efficiency_vs_pT": {
+            "_comment": "",
+            "title": "efficiency vs. p_{T}",
+            "xtitle": "p_{T} [GeV]",
+            "ytitle": "efficiency",
+            "path":  {"PHYSVAL": "tagger"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1000,
+            "ymin": 0,
+            "ymax": 1,
+            "type": "TProfile",
+            "forData": "false"
+        }
+
+
+    },
+
+    "TRACKS": {
+
+        "track_d0": {
+            "_comment": "",
+            "title": "d_{0} of BTagTrackToJetAssociator",
+            "xtitle": "d_{0} [mm]",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 200,
+            "xmin": -2.2,
+            "xmax": 2.2,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "track_z0": {
+            "_comment": "",
+            "title": "z_{0} of BTagTrackToJetAssociator",
+            "xtitle": "z_{0} [mm]",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 200,
+            "xmin": -11,
+            "xmax": 11,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "track_sigd0": {
+            "_comment": "",
+            "title": "d_{0} significance of BTagTrackToJetAssociator",
+            "xtitle": "d_{0} / #sigma_{d_{0}}",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 60,
+            "xmin": -3.3,
+            "xmax": 3.3,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "track_sigz0": {
+            "_comment": "",
+            "title": "z_{0} significance of BTagTrackToJetAssociator",
+            "xtitle": "z_{0} / #sigma_{z_{0}}",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 60,
+            "xmin": -5.5,
+            "xmax": 5.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "track_pT_frac": {
+            "_comment": "",
+            "title": "p_{T}^{frac}",
+            "xtitle": "p_{T}(track) / p_{T}(jet)",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 60,
+            "xmin": -0.01,
+            "xmax": 1.2,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "DeltaR_jet_track": {
+            "_comment": "",
+            "title": "DeltaR(jet, track)",
+            "xtitle": "#DeltaR",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 60,
+            "xmin": 0,
+            "xmax": 0.6,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "numTracks_perJet": {
+            "_comment": "",
+            "title": "number of tracks per jet",
+            "xtitle": "Number of tracks",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 75,
+            "xmin": 0,
+            "xmax": 75,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "numTracks_perJet_vs_pT": {
+            "_comment": "",
+            "title": "number of tracks per jet vs. jet pT",
+            "xtitle": "p_{T} [GeV]",
+            "ytitle": "Number of tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1000,
+            "ymin": 0,
+            "ymax": 75,
+            "type": "TProfile",
+            "forData": "true"
+        },
+
+        "numTracks": {
+            "_comment": "in Physval 'OtherOrigin' is only produced for detail level > 10",
+            "title": "number of tracks (per jet) from ",
+            "xtitle": "Number of tracks",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 40,
+            "xmin": 0,
+            "xmax": 40,
+            "forEach": ["B", "C", "Fragmentation", "Secondaries", "Pileup", "Fake", "OtherOrigin"],
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "numTracks_Secondaries": {
+            "_comment": "in Physval only produced for detail level > 10",
+            "title": "number of tracks (per jet) from ",
+            "xtitle": "Number of tracks",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 20,
+            "xmin": 0,
+            "xmax": 20,
+            "forEach": ["KshortDecay", "LambdaDecay", "GammaConversion", "OtherDecay", "HadronicInteraction", "OtherSecondary"],
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "nInnHits": {
+            "_comment": "",
+            "title": "number of innermost pixel layer hits",
+            "xtitle": "Number of hits",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 10,
+            "xmin": 0,
+            "xmax": 10,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nNextToInnHits": {
+            "_comment": "",
+            "title": "number of next to innermost pixel layer hits",
+            "xtitle": "Number of hits",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 10,
+            "xmin": 0,
+            "xmax": 10,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nBLHits": {
+            "_comment": "",
+            "title": "number of B layer hits",
+            "xtitle": "Number of hits",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 10,
+            "xmin": 0,
+            "xmax": 10,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nsharedBLHits": {
+            "_comment": "",
+            "title": "number of shared B layer hits",
+            "xtitle": "Number of hits",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 10,
+            "xmin": 0,
+            "xmax": 10,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nsplitBLHits": {
+            "_comment": "",
+            "title": "number of split B layer hits",
+            "xtitle": "Number of hits",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 10,
+            "xmin": 0,
+            "xmax": 10,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nPixHits": {
+            "_comment": "",
+            "title": "number of pixel hits",
+            "xtitle": "Number of hits",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 20,
+            "xmin": 0,
+            "xmax": 20,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nPixHoles": {
+            "_comment": "",
+            "title": "number of pixel holes",
+            "xtitle": "Number of hits",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 10,
+            "xmin": 0,
+            "xmax": 10,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nsharedPixHits": {
+            "_comment": "",
+            "title": "number of shared pixel hits",
+            "xtitle": "Number of hits",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 10,
+            "xmin": 0,
+            "xmax": 10,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nsplitPixHits": {
+            "_comment": "",
+            "title": "number of split pixel hits",
+            "xtitle": "Number of hits",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 10,
+            "xmin": 0,
+            "xmax": 10,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nSCTHits": {
+            "_comment": "",
+            "title": "number of SCT hits",
+            "xtitle": "Number of hits",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 20,
+            "xmin": 0,
+            "xmax": 20,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nSCTHoles": {
+            "_comment": "",
+            "title": "number of SCT holes",
+            "xtitle": "Number of hits",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 10,
+            "xmin": 0,
+            "xmax": 10,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "nsharedSCTHits": {
+            "_comment": "",
+            "title": "number of shared SCT hits",
+            "xtitle": "Number of hits",
+            "ytitle": "Tracks",
+            "path":  {"PHYSVAL": "tracks"},
+            "xbins": 10,
+            "xmin": 0,
+            "xmax": 10,
+            "type": "TH1D",
+            "forData": "true"
+        }
+
+    },
+
+    "SV": {
+
+        "SV1_numSVs": {
+            "_comment": "",
+            "title": "number of SV1 vertices",
+            "xtitle": "number",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 3,
+            "xmin": -0.5,
+            "xmax": 2.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "SV1_masssvx": {
+            "_comment": "",
+            "title": "mass of the secondary vertex",
+            "xtitle": "sv mass [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 50,
+            "xmin": 0,
+            "xmax": 8,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "SV1_N2Tpair": {
+            "_comment": "",
+            "title": "number of two-track vertices",
+            "xtitle": "number",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 26,
+            "xmin": -0.5,
+            "xmax": 25.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "SV1_efracsvx": {
+            "_comment": "",
+            "title": "ratio of track energies in SV to jet",
+            "xtitle": "SV energy ratio",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 50,
+            "xmin": -0.01,
+            "xmax": 1.01,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "SV1_deltaR": {
+            "_comment": "",
+            "title": "#DeltaR(jet, SV-PV)",
+            "xtitle": "#DeltaR(jet, SV-PV)",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 50,
+            "xmin": 0,
+            "xmax": 0.6,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "SV1_significance3d": {
+            "_comment": "",
+            "title": "SV1 significance 3d",
+            "xtitle": "significance 3d",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 50,
+            "xmin": 0,
+            "xmax": 50,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "SV1_energyTrkInJet": {
+            "_comment": "",
+            "title": "SV1 energyTrkInJet",
+            "xtitle": "energy [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 2000,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "SV1_NGTinSvx": {
+            "_comment": "",
+            "title": "number of good tracks in SV1 vertex",
+            "xtitle": "number",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 16,
+            "xmin": -0.5,
+            "xmax": 15.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "SV1_Lxy": {
+            "_comment": "",
+            "title": "SV1 L_{xy}",
+            "xtitle": "L_{xy}",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 50,
+            "xmin": 0,
+            "xmax": 75,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "SV1_purity": {
+            "_comment": "",
+            "title": "SV1 purity",
+            "xtitle": "purity",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 10,
+            "xmin": -0.01,
+            "xmax": 1.01,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "SV1_fracTracks_from": {
+            "_comment": "in Physval 'OtherOrigin' is only produced for detail level > 10",
+            "title": "SV1 fraction of tracks from ",
+            "xtitle": "fraction",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 10,
+            "xmin": -0.01,
+            "xmax": 1.01,
+            "forEach": ["B", "C", "Fragmentation", "Secondaries", "Pileup", "Fake", "OtherOrigin"],
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "SV1_fracTracks_Secondaries": {
+            "_comment": "in Physval only produced for detail level > 10",
+            "title": "SV1 fraction of tracks from ",
+            "xtitle": "fraction",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 10,
+            "xmin": -0.01,
+            "xmax": 1.01,
+            "forEach": ["KshortDecay", "LambdaDecay", "GammaConversion", "OtherDecay", "HadronicInteraction", "OtherSecondary"],
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "SV1_fracHFTracksInJet": {
+            "_comment": "",
+            "title": "SV1 fraction of HF tracks in jet",
+            "xtitle": "fraction",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 10,
+            "xmin": -0.01,
+            "xmax": 1.01,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "MSV_nvsec": {
+            "_comment": "",
+            "title": "number of MSV vertices",
+            "xtitle": "number",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 11,
+            "xmin": -0.5,
+            "xmax": 10.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "MSV_N2Tpair": {
+            "_comment": "",
+            "title": "MSV number of two-track vertices",
+            "xtitle": "number",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 51,
+            "xmin": -0.5,
+            "xmax": 50.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "MSV_energyTrkInJet": {
+            "_comment": "",
+            "title": "ratio of track energies in MSV vertices to jet",
+            "xtitle": "energy [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 100,
+            "xmin": 1,
+            "xmax": 2000,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "MSV_normdist": {
+            "_comment": "",
+            "title": "MSV normdist",
+            "xtitle": "normdist",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 50,
+            "xmin": 0,
+            "xmax": 100,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "MSV_purity": {
+            "_comment": "",
+            "title": "MSV average purity",
+            "xtitle": "purity",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 10,
+            "xmin": -0.01,
+            "xmax": 1.01,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "MSV_vtx_mass": {
+            "_comment": "",
+            "title": "MSV average vertex mass",
+            "xtitle": "mass [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 50,
+            "xmin": 0,
+            "xmax": 8,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "JetFitter_N2Tpair": {
+            "_comment": "",
+            "title": "JetFitter number of two-track vertices",
+            "xtitle": "number",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 36,
+            "xmin": -0.5,
+            "xmax": 35.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "JetFitter_nVTX": {
+            "_comment": "",
+            "title": "JetFitter nVTX",
+            "xtitle": "number",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 5,
+            "xmin": -0.5,
+            "xmax": 4.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "JetFitter_nSingleTracks": {
+            "_comment": "",
+            "title": "JetFitter nSingleTracks",
+            "xtitle": "number",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 11,
+            "xmin": -0.5,
+            "xmax": 10.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "JetFitter_nTracksAtVtx": {
+            "_comment": "",
+            "title": "JetFitter nTracksAtVtx",
+            "xtitle": "number",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 21,
+            "xmin": -0.5,
+            "xmax": 20.5,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "JetFitter_mass": {
+            "_comment": "",
+            "title": "JetFitter mass",
+            "xtitle": "mass [GeV]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 50,
+            "xmin": 0,
+            "xmax": 15,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "JetFitter_energyFraction": {
+            "_comment": "",
+            "title": "JetFitter energyFraction",
+            "xtitle": "fraction",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 50,
+            "xmin": -0.01,
+            "xmax": 1.01,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "JetFitter_significance3d": {
+            "_comment": "",
+            "title": "JetFitter significance3d",
+            "xtitle": "significance3d",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 50,
+            "xmin": 0,
+            "xmax": 50,
+            "type": "TH1D",
+            "forData": "true"
+        },
+
+        "JetFitter_purity": {
+            "_comment": "",
+            "title": "JetFitter average purity",
+            "xtitle": "purity",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 10,
+            "xmin": -0.01,
+            "xmax": 1.01,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "SV1_masssvx_vs_pT": {
+            "_comment": "",
+            "title": "mass of the secondary vertex vs. jet p_{T}",
+            "xtitle": "p_{T} [GeV]",
+            "ytitle": "sv mass [GeV]",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1000,
+            "ymin": 0,
+            "ymax": 6,
+            "type": "TProfile",
+            "forData": "true"
+        },
+
+        "SV1_N2Tpair_vs_pT": {
+            "_comment": "",
+            "title": "number of two-track vertices vs. jet p_{T}",
+            "xtitle": "p_{T} [GeV]",
+            "ytitle": "number",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1000,
+            "ymin": 0,
+            "ymax": 25,
+            "type": "TProfile",
+            "forData": "true"
+        },
+
+        "SV1_efracsvx_vs_pT": {
+            "_comment": "",
+            "title": "ratio of track energies in SV to jet vs. jet p_{T}",
+            "xtitle": "p_{T} [GeV]",
+            "ytitle": "SV energy ratio",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1000,
+            "ymin": -0.01,
+            "ymax": 1.01,
+            "type": "TProfile",
+            "forData": "true"
+        },
+
+        "SV1_deltaR_vs_pT": {
+            "_comment": "",
+            "title": "#DeltaR(jet, SV-PV) vs. jet p_{T}",
+            "xtitle": "p_{T} [GeV]",
+            "ytitle": "#DeltaR(jet, SV-PV)",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 100,
+            "xmin": 0,
+            "xmax": 1000,
+            "ymin": 0,
+            "ymax": 0.6,
+            "type": "TProfile",
+            "forData": "true"
+        },
+
+        "SV1_masssvx_vs_eta": {
+            "_comment": "",
+            "title": "mass of the secondary vertex vs. jet eta",
+            "xtitle": "#eta",
+            "ytitle": "sv mass [GeV]",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 100,
+            "xmin": -5,
+            "xmax": 5,
+            "ymin": 0,
+            "ymax": 6,
+            "type": "TProfile",
+            "forData": "true"
+        },
+
+        "SV1_N2Tpair_vs_eta": {
+            "_comment": "",
+            "title": "number of two-track vertices vs. jet eta",
+            "xtitle": "#eta",
+            "ytitle": "number",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 100,
+            "xmin": -5,
+            "xmax": 5,
+            "ymin": 0,
+            "ymax": 25,
+            "type": "TProfile",
+            "forData": "true"
+        },
+
+        "SV1_efracsvx_vs_eta": {
+            "_comment": "",
+            "title": "ratio of track energies in SV to jet vs. jet eta",
+            "xtitle": "#eta",
+            "ytitle": "SV energy ratio",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 100,
+            "xmin": -5,
+            "xmax": 5,
+            "ymin": 0,
+            "ymax": 1,
+            "type": "TProfile",
+            "forData": "true"
+        },
+
+        "SV1_deltaR_vs_eta": {
+            "_comment": "",
+            "title": "#DeltaR(jet, SV-PV) vs. jet eta",
+            "xtitle": "p_{T} [GeV]",
+            "ytitle": "#DeltaR(jet, SV-PV)",
+            "path":  {"PHYSVAL": "SV"},
+            "xbins": 100,
+            "xmin": -5,
+            "xmax": 5,
+            "ymin": 0,
+            "ymax": 4,
+            "type": "TProfile",
+            "forData": "true"
+        }
+    },
+
+
+    "TRUTH": {
+
+        "Truth_Lxy_b": {
+            "_comment": "",
+            "title": "L_{xy} of the BHadron",
+            "xtitle": "L_{xy} [mm]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "truth"},
+            "xbins": 50,
+            "xmin": 0,
+            "xmax": 75,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "Truth_Lxy_c": {
+            "_comment": "",
+            "title": "L_{xy} of the CHadron",
+            "xtitle": "L_{xy} [mm]",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "truth"},
+            "xbins": 50,
+            "xmin": 0,
+            "xmax": 75,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "deltaR_truthBHadronJet_b": {
+            "_comment": "",
+            "title": "#DeltaR(BHadron, jet)",
+            "xtitle": "#DeltaR",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "truth"},
+            "xbins": 50,
+            "xmin": 0.0,
+            "xmax": 1.0,
+            "type": "TH1D",
+            "forData": "false"
+        },
+
+        "deltaR_truthCHadronJet_c": {
+            "_comment": "",
+            "title": "#DeltaR(CHadron, jet)",
+            "xtitle": "#DeltaR",
+            "ytitle": "Jets",
+            "path":  {"PHYSVAL": "truth"},
+            "xbins": 50,
+            "xmin": 0.0,
+            "xmax": 1.0,
+            "type": "TH1D",
+            "forData": "false"
+        }
+
+    }
+
+
+} 
\ No newline at end of file
diff --git a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/CreatePhysValWebPage.py b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/CreatePhysValWebPage.py
new file mode 100755
index 0000000000000000000000000000000000000000..3a4c8fe20b200459195f1f0fc2dbdb3810e35e54
--- /dev/null
+++ b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/CreatePhysValWebPage.py
@@ -0,0 +1,165 @@
+###
+# Copyright (C) 2021 CERN for the benefit of the ATLAS collaboration
+###
+
+# Create Physics Validation Web page
+# Author: Arnaud Duperrin <duperrin@cppm.in2p3.fr> - March 2021
+
+# python CreatePhysValWebPage.py -h
+# python CreatePhysValWebPage.py -i ROC
+
+# Import os module to read directory
+import getopt,os,glob,argparse,sys
+
+parser = argparse.ArgumentParser(description='Create the Physics Validation web page:', usage='%(prog)s -i ROC/ ')
+parser.add_argument("-i", "--input_dir", help="path to the folder holding the plots (default: ./)", default=os.getcwd())
+parser.add_argument("-n", "--number_of_histo", help="number of histo per raw (default is 4)", default=4)
+#parser.add_argument("-o", "--output_dir", help="path for the output (default: ./FTAG_PhysValWebPage.html", default=os.getcwd()+"/FTAG_PhysValWebPage.html")
+parser.add_argument("-f", "--format", help='format for the plots (default: "*.png")', default="*.png")
+
+
+##############################################################################################################################
+def row_major(alist, sublen):      
+  return [alist[i:i+sublen] for i in range(0, len(alist), sublen)]
+
+def col_major(alist, sublen):
+  numrows = (len(alist)+sublen-1) // sublen 
+  return [alist[i::sublen] for i in range(numrows)]
+
+#example:
+#L = ['one','two','three','four','five','six','seven','eight','nine']
+#for r in row_major(L, 3): print r
+#for r in col_major(L, 3): print r
+#for r in row_major(L, 4): print r
+
+def html_table(lol):
+  string  = '<html><table>'
+  for sublist in lol:
+    string += '<tr><th> '
+    #print (sublist)
+    list_len = len(sublist)
+
+    #First the headers
+    for file in sublist:
+     idx = sublist.index(file)   
+     print("Histo: " + sublist[idx])
+     list_end = list_len - idx
+     if list_end != 1:
+         next_idx = idx + 1
+         string += '<p style=\"color:#0000FF\";>'+ str(file)+ '<p> </th><th>'
+     else:
+         #print("End Of List!")
+         string += '<p style=\"color:#0000FF\";>'+ str(file)+ '<p> </th></tr> ' 
+
+    #Then the plots
+    string += '<tr><td> '
+    for file in sublist:
+     idx = sublist.index(file)   
+     list_end = list_len - idx
+     if list_end != 1:
+         next_idx = idx + 1
+         string += '<a href="'+str(file)+'"> <img alt="'+str(file)+'" src="'+str(file)+'" width="400" height="300"></a> </td><th>'
+     else:
+         string += '<a href="'+str(file)+'"> <img alt="'+str(file)+'" src="'+str(file)+'" width="400" height="300"></a> </td><tr>'
+
+    #print("string= "+string)
+    #print(".........")     
+  string  +=  '</table></html>'
+  return string
+
+def list_to_html_table(alist, sublength, column_major=False):
+  if column_major:
+    lol = col_major(alist, sublength)
+  else:
+    lol = row_major(alist, sublength)
+  return(html_table(lol))
+##############################################################################################################################
+  
+
+#############################
+args = parser.parse_args()
+folder = os.path.abspath(args.input_dir)
+
+if not os.path.isdir(folder):
+  print("The folder " + folder + " doesn't exist !")
+  sys.exit()
+
+#out = args.output_dir
+format = args.format
+nHisto = int(args.number_of_histo)
+
+#origDir = os.getcwd()
+#output_file = os.path.abspath(args.output_dir)
+
+
+os.chdir(folder)
+
+files = glob.glob(format)
+
+#print ("nHisto = " + str(nHisto))
+
+print("=================================================")
+print("Processing histo in directory "+folder)
+print("=================================================")
+#Start by main ROC directory:
+my_htm_page= list_to_html_table(files, nHisto)
+#print(my_htm_page)
+hs = open("FTAG_PhysValWebPage.html", 'w')
+hs.write(my_htm_page)
+print("")
+print("See "+folder+"/FTAG_PhysValWebPage.html")
+
+folder_eff= folder+"/eff_vs_Lxy"
+if (os.path.isdir(folder_eff)):
+  os.chdir(folder_eff)
+  files = glob.glob(format)
+  my_htm_page= list_to_html_table(files, nHisto)
+  hs = open("FTAG_PhysValWebPage.html", 'w')
+  hs.write(my_htm_page)
+  #print("")
+  #print("See "+folder_eff+"/FTAG_PhysValWebPage.html")
+else:
+  print("There is no Efficiency vs Lxy directory: " + folder_eff)
+
+
+folder_pt= folder+"/eff_vs_pt_ttbar"
+is_ttbar = 1
+if (os.path.isdir(folder_pt)):
+  os.chdir(folder_pt)
+  files = glob.glob(format)
+  my_htm_page= list_to_html_table(files, nHisto)
+  hs = open("FTAG_PhysValWebPage.html", 'w')
+  hs.write(my_htm_page)
+  #print("")
+  #print("See "+folder_eff+"/FTAG_PhysValWebPage.html")
+else:
+ is_ttbar = 0   
+ folder_pt= folder+"/eff_vs_pt_Zprime"
+ if (os.path.isdir(folder_pt)):
+  os.chdir(folder_pt)
+  files = glob.glob(format)
+  my_htm_page= list_to_html_table(files, nHisto)
+  hs = open("FTAG_PhysValWebPage.html", 'w')
+  hs.write(my_htm_page)
+  #print("")
+  #print("See "+folder_pt+"/FTAG_PhysValWebPage.html")
+ else:
+  print("There is no Efficiency vs pT directory (ttbar or Z'): " + folder_pt)
+
+#Create the master web page  
+os.chdir(folder)
+mypage = "<html><table>"
+mypage += '<tr><th><p style=\"color:#0000FF\";> FTAG Physics validation web page <p> </th> </tr>'
+mypage += '<tr><td> <a href="FTAG_PhysValWebPage.html">' +str(args.input_dir)+'</a>  </td></tr> '
+mypage += '<tr><td> <ul> <li> <a href="eff_vs_Lxy/FTAG_PhysValWebPage.html"> Efficiency versus Lxy </a>  </li>  '
+if (is_ttbar): 
+ mypage += '              <li> <a href="eff_vs_pt_ttbar/FTAG_PhysValWebPage.html"> Efficiency versus pT </a>  </li> </td></tr> '
+else:
+ mypage += '              <li> <a href="eff_vs_pt_Zprime/FTAG_PhysValWebPage.html"> Efficiency versus pT </a>  </li> </td></tr> '
+mypage += "</table></html>"
+
+#print(mypage)
+hs = open("FTAG_PhysVal.html", 'w')
+hs.write(mypage)
+print("See "+folder+"/FTAG_PhysVal.html")
+
diff --git a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/Draw_PhysVal_btagROC.c b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/Draw_PhysVal_btagROC.c
new file mode 100644
index 0000000000000000000000000000000000000000..d1c4abbb89ba05660ced96f3120edf1097e7d3ff
--- /dev/null
+++ b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/Draw_PhysVal_btagROC.c
@@ -0,0 +1,1315 @@
+///////////////////////////////////////////////////////////////////////////////
+// Draw_PhysVal_btagROC.c - Author: Arnaud Duperrin <duperrin@cppm.in2p3.fr> - September 2019
+// code updates: March 2021
+//
+// Root macro class to produce ROC b-tagging physics validation plots.
+// Compare ROC curves for severals samples and for different algorithms.
+//
+// Inputs: NTUP_PHYSVAL (merged) root samples (produced by mergePhysValFiles.py)
+//
+// Variables to edit:
+//
+// -List of taggers:
+//  const vector<TString> taggers = {"IP2D","IP3D","SV1","IP3DSV1","MV2c10","JetFitter","DL1","DL1r"};
+//
+// -Output directories for plots
+//  const TString HistoDir = "ROC/";
+//
+// -Input samples directory path
+//  const TString sPath = "./";
+//
+// -Names of input samples:
+//  vector<TString> InputFilesNames = {"task1_ref.root","task1_test1.root","task1_test2.root"}; 
+//  
+//
+///////////////////////////////////////////////////////////////////
+//Several possible usages:
+// 1) root -l Draw_PhysVal_btagROC.c
+//
+// 2) root -l -q -b Draw_PhysVal_btagROC.c >&! output.log
+//
+// 3) root -l
+//    .L Draw_PhysVal_btagROC.c+
+//    Draw_PhysVal_btagROC()
+///////////////////////////////////////////////////////////////////
+
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <dirent.h>
+#include <cstdlib>
+#include "TFile.h"
+#include "TChain.h"
+#include "TCanvas.h"
+#include "TLegend.h"
+#include "TApplication.h"
+#include "TH2D.h"
+#include "TProfile.h"
+#include "TSystem.h"
+#include <algorithm>
+#include "TStyle.h"
+#include "TColor.h"
+#include "TProfile.h"
+#include "TMath.h"
+#include "THStack.h"
+#include "TLorentzVector.h"
+#include "TString.h"
+#include "TGraph.h"
+#include "TGraphAsymmErrors.h"
+#include "TMath.h"
+#include "TGraphErrors.h"
+#include "TMultiGraph.h"
+#include "TLine.h"
+#include <TLegendEntry.h>
+#include <TPaveText.h>
+#include "TLatex.h"
+#include "TGaxis.h"
+
+using namespace std;
+
+const float EffMin=.55;
+const float EffMax=1.;
+
+//Some global variables for plotting:
+// taggers with 'old_taggers' in their name are assumed to be in the folder called 'old_taggers' in the merged root file
+const vector<TString> taggers = {"IP2D","IP3D","RNNIP","SV1","IP3DSV1","MV2c10","JetFitter","DL1","DL1r"};
+//const vector<TString> taggers = {"IP2D"};
+//const vector<TString> taggers = {"IP3D"};
+//const vector<TString> taggers = {"RNNIP"};
+//const vector<TString> taggers = {"SV1"};
+//const vector<TString> taggers = {"IP3DSV1"};
+//const vector<TString> taggers = {"MV2c10"};
+//const vector<TString> taggers = {"DL1"};
+//const vector<TString> taggers = {"DL1r"};
+
+const float CWidth=800;
+const float CHeight=600;
+
+//where to save histos
+const TString HistoDir = "ROC/";
+
+// detail level (more WPs for high detail level)
+const bool high_detail_level = false;
+
+//samples directory path
+const TString sPath = "./"; 
+
+//MyGraphCleaner
+const bool kDebugON = true;
+const bool kDebugOFF = false;
+const float kTruncateXatOne = 1.; 
+const float kTruncateYatOne = 1.;
+const bool kApplyTruncateXON = true;
+const bool kApplyTruncateXOFF = false;
+const bool kApplyTruncateYON = true;
+const bool kApplyTruncateYOFF = false;
+const bool kMonotonicON = true;
+const bool kMonotonicOFF = false;
+const bool kBinToBinMonotonicON = true;
+const bool kBinToBinMonotonicOFF = false;
+const bool kRejectNullErrorsON = true;
+const bool kRejectNullErrorsOFF = false;
+const bool kForceNullErrorsON = true;
+const bool kForceNullErrorsOFF = false;
+
+
+int lcol[]= { kBlack, kCyan, kRed, kGreen+2, kBlue };
+int msty[]= { kFullCircle, kFullTriangleUp, kFullSquare, kFullTriangleDown, kOpenCircle };
+//const int lstyle = 9;
+const int lstyle = 2;
+
+vector<TString> truth_labels = {"b", "c", "u"};
+//vector<TString> truth_labels = {"b"};
+//vector<TString> truth_labels = {"c"};
+//vector<TString> truth_labels = {"u"};
+map<TString, vector<TString>> WP_values;
+
+
+void fill_WP_values(){
+  if(high_detail_level){
+    WP_values.insert(make_pair<TString, vector<TString>>("IP3D", {"50", "70", "80"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("RNNIP", {"50", "70", "80"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("SV1", {"40", "50", "60"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("JetFitter", {"50", "70", "80"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("DL1", {"60", "70", "77", "85"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("DL1r", {"60", "70", "77", "85"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("IP2D", {"50", "70", "80"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("IP3DSV1", {"50", "70", "80"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("MV2c10", {"60", "70", "77", "85"}));
+  }
+  else{
+    WP_values.insert(make_pair<TString, vector<TString>>("IP3D", {"70"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("RNNIP", {"70"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("SV1", {"60"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("JetFitter", {"70"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("DL1", {"70"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("DL1r", {"70"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("IP2D", {"70"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("IP3DSV1", {"70"}));
+    WP_values.insert(make_pair<TString, vector<TString>>("MV2c10", {"70"}));
+  }
+}
+
+TString getRefHistoName(TString var, TString truth_label){
+  TString name;
+  if(var == "pt_ttbar") name = "BTag/AntiKt4EMTopoJets/jet/jet/BTag_AntiKt4EMTopoJets_jet_jet_pt_" + truth_label + "_ttbar";
+  else if(var == "pt_Zprime") name = "BTag/AntiKt4EMTopoJets/jet/jet/BTag_AntiKt4EMTopoJets_jet_jet_pt_" + truth_label + "_Zprime";
+  else if(var == "Lxy"){
+    if(truth_label == "l") name = "BTag/AntiKt4EMTopoJets/SV/_" + truth_label + "/BTag_AntiKt4EMTopoJets_SV_SV1_Lxy_" + truth_label;
+    else name = "BTag/AntiKt4EMTopoJets/other_histograms/histos/BTag_AntiKt4EMTopoJets_truth_Truth_Lxy_" + truth_label;
+  }
+  else throw std::invalid_argument("getRefHistoName called with unknown var name: " + var + ". Only pt_ttbar, pt_Zprime and Lxy allowed. Aborting." );
+  return name;
+}
+
+
+void VALID_LABEL(Double_t x,Double_t y,Color_t color, TString sample, bool drawRatio=true) {
+  TLatex l; //l.SetTextAlign(12); l.SetTextSize(tsize);
+  l.SetTextSize(.045);
+  if(!drawRatio) l.SetTextSize(.04);    
+  l.SetNDC();
+  l.SetTextFont(72);
+  l.SetTextColor(color);
+  l.DrawLatex(x,y,"Physics Validation");
+
+  TLatex l2; //l.SetTextAlign(12); l.SetTextSize(tsize);
+  l2.SetTextSize(.04);
+  if(!drawRatio) l2.SetTextSize(.035);    
+  l2.SetNDC();
+  l2.SetTextFont(42);
+  l2.SetTextColor(color);
+  TString txt = "b-tagging, "+sample;
+  l2.DrawLatex(x,y-.05,txt.Data());
+  
+  //TLatex l3; 
+  //l3.SetTextSize(.04);
+  //if(!drawRatio) l3.SetTextSize(.035);    
+  //l3.SetNDC();
+  //l3.SetTextFont(42);
+  //l3.SetTextColor(color);
+  //l3.DrawLatex(x+.01,y-.1,sample.Data());
+}
+
+void myDescriptionLabel(TString txt, float x, float y, Color_t color, bool drawRatio=true) {
+  TLatex l;
+  l.SetTextSize(.04);
+  if(!drawRatio) l.SetTextSize(.035);    
+  l.SetNDC();
+  l.SetTextFont(42);
+  l.SetTextColor(color);
+  l.DrawLatex(x,y-0.1,txt.Data());
+}
+
+void myText(TString txt, float x, float y, Color_t color, bool drawRatio=true, float tsize=0.04) {
+  TLatex l;
+  l.SetTextSize(tsize);
+  if(!drawRatio) l.SetTextSize(.04);    
+  l.SetNDC();
+  l.SetTextFont(72);
+  l.SetTextColor(color);
+  l.DrawLatex(x,y,txt.Data());
+
+}
+
+
+TGraphErrors * h_RejvEff(TH1 *hsig, TH1 *hbkg, bool isSV1) {
+  int nbins = hsig->GetNbinsX();
+  //cout <<"nbins="<<nbins<<endl;
+  int inf = 0;
+  int sup = nbins+1;
+  double Isig = hsig->Integral(inf,sup);
+  double Ibkg = hbkg->Integral(inf,sup);
+  int point = 0;
+
+  set<double> repetitionControl;
+  vector<double> x;
+  vector<double> ex;
+  vector<double> y;
+  vector<double> ey;
+
+  for(int cut=inf; cut<sup; cut++) {
+    double sig = hsig->Integral(cut,sup);
+    double bkg = hbkg->Integral(cut,sup);
+    //cout << " ---- sig = " << sig << endl;
+    if (repetitionControl.count(sig)) continue;
+    repetitionControl.insert(sig);
+
+    double cutVal = hsig->GetBinLowEdge(cut);
+    double eff = 0;
+    double rej = 0;
+    double efferr = 0;
+    double rejerr = 0;
+//    if(Isig != 0){
+    eff = sig / Isig;
+    efferr = sqrt( eff * ( 1 - eff ) / Isig );
+//    }
+    if(bkg != 0){
+      rej = Ibkg / bkg;
+      rejerr = sqrt( rej * ( rej - 1 ) / bkg );
+    }
+    //cout << "cut= "<<cut<<" cutVal= "<<cutVal<<" sig= "<< sig <<" bkg="<<bkg<<" eff="<<eff<<" rej="<<rej<<endl;  
+    if ((isSV1 && eff<0.8) || !isSV1) {
+      x.push_back(eff);
+      y.push_back(rej);
+      ex.push_back(efferr);
+      ey.push_back(rejerr);
+    }
+  }
+  TGraphErrors * rejVsEff = new TGraphErrors(x.size());
+  for (unsigned int i=0;i<x.size();++i) {
+    rejVsEff->SetPoint(i, x.at(i), y.at(i));
+    rejVsEff->SetPointError(i, ex.at(i), ey.at(i));
+  }
+  return rejVsEff;
+}
+
+
+TGraphErrors* h_EffvsVar(TH1* histo, TH1* histo_WPcuts) {
+  //TGraphErrors* effVsVar = new TGraphErrors(histo->GetNbinsX());
+
+  if(!histo) {cout << "histo does not exist or is broken. " << histo->GetName(); }
+  if(!histo_WPcuts) {cout << "histo does not exist or is broken. " << histo_WPcuts->GetName();} 
+
+  // test if the histos are healty and stuff
+  if (!histo || !histo_WPcuts || histo->GetNbinsX() != histo_WPcuts->GetNbinsX() || histo->Integral() == 0) return NULL;
+
+  vector<double> x;
+  vector<double> ex;
+  vector<double> y;
+  vector<double> ey;
+
+  for (int bin_i = 1; bin_i <= histo->GetNbinsX(); ++bin_i){ 
+    if(histo->GetBinContent(bin_i) == 0) {continue;}
+    if(histo_WPcuts->GetBinContent(bin_i) == 0) {continue;}  // c'est important
+    double eff = histo_WPcuts->GetBinContent(bin_i) / histo->GetBinContent(bin_i);
+    double eff_err = sqrt(histo_WPcuts->GetBinContent(bin_i)*(1-eff))/histo->GetBinContent(bin_i);        
+    double var = histo->GetBinCenter(bin_i);
+    double var_err = histo->GetBinError(bin_i);
+
+    //cout << "bin_i = " << bin_i<< " eff = " << eff << " x = " << var << endl;
+    x.push_back(var);
+    //ex.push_back(var_err);
+    ex.push_back(0.); // pas important but I like it
+     y.push_back(eff);
+    ey.push_back(eff_err);
+    // cout << "var= " << var << " eff=" << eff << endl;  
+  }
+
+  TGraphErrors* effVsVar = new TGraphErrors(x.size()); // ca c'est important!!!
+
+  for (unsigned int i=0; i < x.size(); ++i) {
+    effVsVar->SetPoint(i, x.at(i), y.at(i));
+    effVsVar->SetPointError(i, ex.at(i), ey.at(i));
+  }
+  return effVsVar;
+
+}
+
+
+TGraphErrors* h_EffvsVar_debug(TH1* histo, TH1* histo_WPcuts) {
+
+  if(!histo) {cout << "histo does not exist or is broken. " << histo->GetName(); }
+  if(!histo_WPcuts) {cout << "histo does not exist or is broken. " << histo_WPcuts->GetName();} 
+
+  // test if the histos are healty and stuff
+  if (!histo || !histo_WPcuts || histo->GetNbinsX() != histo_WPcuts->GetNbinsX() || histo->Integral() == 0) return NULL;
+
+  vector<double> x;
+  vector<double> ex;
+  vector<double> y;
+  vector<double> ey;
+
+  for (int bin_i = 1; bin_i <= histo->GetNbinsX(); ++bin_i){ 
+    if(histo->GetBinContent(bin_i) == 0) {continue;}
+    if(histo_WPcuts->GetBinContent(bin_i) == 0) {continue;}
+    double eff = histo_WPcuts->GetBinContent(bin_i) / histo->GetBinContent(bin_i);
+    //cout << "bin_i = "<<bin_i<<" eff= "<<eff<< " num = " << histo_WPcuts->GetBinContent(bin_i) << " deno = " << histo->GetBinContent(bin_i) << endl;
+    double eff_err = sqrt(histo_WPcuts->GetBinContent(bin_i)*(1-eff))/histo->GetBinContent(bin_i);        
+    double var = histo->GetBinCenter(bin_i);
+    double var_err = histo->GetBinError(bin_i);
+    x.push_back(var);
+    //ex.push_back(var_err);
+    ex.push_back(0.);
+    y.push_back(eff);
+    ey.push_back(eff_err);
+    // cout << "var= " << var << " eff=" << eff << endl;  
+  }
+
+  TGraphErrors* effVsVar = new TGraphErrors(x.size());
+
+  for (unsigned int i=0; i < x.size(); ++i) {
+    effVsVar->SetPoint(i, x.at(i), y.at(i));
+    effVsVar->SetPointError(i, ex.at(i), ey.at(i));
+  }
+  return effVsVar;
+
+}
+
+
+// Perform interpolation of pVariation 
+TGraphErrors * Magic(const TGraphErrors* pReference, const TGraphErrors* pVariation) {
+  //cout << "Dans Magic" << endl;
+  const auto nPoints=pReference->GetN();
+  //cout << "nPoints= " << nPoints << endl;
+
+  for (unsigned int i=0;i<nPoints;++i) {
+    double x,y;
+    pReference->GetPoint(i, x, y);
+    //cout << " ----- # (reference) = " << i << " x = " << x << " y = " << y << endl;
+  }
+  TGraphErrors* result= new TGraphErrors(nPoints);
+
+  auto GetFirstPoint=[&](float pXValue)->int {
+    //cout << "   ---->> GetFirstPoint: pXValue=" << pXValue << endl;
+    const auto nThisPoints=pVariation->GetN();
+    unsigned int firstX=0;
+    for (unsigned int i=0;i<nThisPoints;++i) {
+      double x,y;
+      pVariation->GetPoint(i, x, y);
+      //cout << "       GetFirstPoint: i = " << i << " x = " << x << " y = " << y << endl;
+      //if (x<pXValue) {cout << "  ------------------>> GetFirstPoint: i = " << i << " x = " << x << " y = " << y << endl; return i;}
+      if (x<pXValue) return i;
+    }
+    //cout << "a la fin de GetFirstPoint -> nThisPoints = " << nThisPoints << endl;
+    return nThisPoints;
+  };
+
+  auto GetInterpolation=[&](float pXValue, int error)->double{
+    const auto firstPoint=GetFirstPoint(pXValue);
+    const auto secondPoint=firstPoint+(firstPoint==0?1:-1);
+    double x1, x2, y1, y2;
+    pVariation->GetPoint(firstPoint, x1, y1);
+    pVariation->GetPoint(secondPoint, x2, y2);
+    //cout << "   pVariation: pXValue=" << pXValue << " firstPoint= " << firstPoint << " secondPoint=" << secondPoint << " x1=" << x1 << " y1=" << y1 << " x2=" << x2 << " y2=" << y2 << endl;       
+    y1+=pVariation->GetErrorY(firstPoint)*error;
+    y2+=pVariation->GetErrorY(secondPoint)*error;
+
+    const auto A=TMath::Log(y1);
+    const auto k=(TMath::Log(y2)-A)/(x2-x1);
+
+    const auto NewY= y1*TMath::Exp(k*(pXValue-x1));
+    //cout << "result interpol NewY=" << NewY << " A = " << A << " k= " << k << endl;
+   return NewY;
+  };
+
+  for (unsigned int iPoint=0;iPoint<nPoints;++iPoint) {
+    double x,y;
+    pReference->GetPoint(iPoint, x,y);
+    const auto refX=x;
+    const auto refEX=pReference->GetErrorX(iPoint);
+    const auto interY=GetInterpolation(refX, 0);
+    const auto interEY=GetInterpolation(refX, +1);
+    //cout << "  iPoint = " << iPoint << " refX = " << refX << " interY = " << interY << endl;
+    result->SetPoint(iPoint, refX, interY);
+    result->SetPointError(iPoint, refEX, interEY-interY);
+  }
+
+  return result;
+}
+
+void PlotLikelihoodTaggers(vector<TString> InputFileNames, vector<vector<TH1F*>> h_b, vector<vector<TH1F*>> h_u){
+
+  TCanvas* c1 = new TCanvas("c1","c1",0,0,CWidth,CHeight);
+  c1->Divide(2*taggers.size(),InputFileNames.size());
+
+  int l = 1;
+  for(unsigned int it=0;it<InputFileNames.size();++it) {
+    std::cout<<"--Reading input histo from file: "<<InputFileNames[it]<<std::endl;
+    for (int i=0;i<taggers.size();i++) {
+      cout << "-taggers["<<i<<"]="<< taggers[i] << endl;
+      c1->cd(l);
+      h_b[it][i]->Draw();
+      c1->cd(l+1);
+      h_u[it][i]->Draw();
+      l=l+2;
+    }
+  }
+}
+
+
+void MyGraphCleaner(TGraphErrors* gr, bool debug=false, bool ApplyTruncatexAt = false, float truncatexAt=1., bool ApplyTruncateyAt = false, float truncateyAt=1., bool forceMonotonic=false, bool forceBinToBinMonotonic=false, bool rejectNullErrors=false, bool forceNullErrors=false, float forceAroundMean=0.) {
+  if(0==gr) return;
+  
+  debug=false;
+
+  if(debug) {cout<<endl; cout << "====" << endl;}
+  gr->Sort();
+
+  int npr=0;
+  int np = gr->GetN();
+  if(debug) std::cout<<"graph "<<gr->GetName()<<" has "<<np<<" points"<<std::endl;
+  double eff1,rej1;
+  double eff2,rej2;
+  int qq = gr->GetPoint(0,eff1,rej1);
+  double rejMin = rej1;
+  if(debug) std::cout<<"rejMin (Y at begining) = " << rejMin << endl;
+  double Ymean= gr->GetMean(2);
+  if(debug) std::cout<<"GetMean in Y = " << Ymean << endl;
+  if(forceMonotonic && debug) std::cout<<"reference point for monotonic cleaning: "<<eff1<<" "<<rej1<<std::endl;
+
+  int nop = 0;
+  for(int i=0;i<np;i++) {
+    nop++;
+    if(nop>np) break;   
+    qq = gr->GetPoint(i,eff2,rej2);
+    double ex = gr->GetErrorX(i);
+    double ey = gr->GetErrorY(i);
+    if(debug) std::cout<<"->examining point "<<i<<" x="<<eff2<<" y=" <<rej2<<" ex="<<ex<<" ey="<<ey<<std::endl;
+    if(eff2==0){
+      if(debug) std::cout<<"removing point "<<i<<" of "<<gr->GetName() <<"b/c above truncation: "<<eff2<<std::endl;
+      gr->RemovePoint(i);
+      i--;
+      npr++;
+      continue;
+    }
+    if(eff2>truncatexAt && ApplyTruncatexAt) {
+      if(debug) std::cout<<"removing point "<<i<<" of "<<gr->GetName() <<"x above truncation: "<<eff2<<std::endl;
+      gr->RemovePoint(i);
+      i--;
+      npr++;
+      continue;
+    }
+    if(rej2>truncateyAt && ApplyTruncateyAt) {
+      if(debug) std::cout<<"removing point "<<i<<" of "<<gr->GetName() <<"y above truncation: "<<rej2<<std::endl;
+      gr->RemovePoint(i);
+      i--;
+      npr++;
+      continue;
+    }
+
+    //forceAroundMean = deviation around the mean value in Y 
+    if(forceAroundMean!=0.) {
+      if(((rej2+ey)/Ymean>forceAroundMean) || (Ymean/(rej2-ey)>forceAroundMean) ) {
+	if(debug) std::cout<<"forceAAroundMean - removing point "<<i<<" of "<<gr->GetName()<<std::endl;
+	if(debug) std::cout<<"pt "<<qq<<" "<<i<<" x="<<eff2<<" y="<<rej2 <<" (rej2+ey)/Ymean ="<<(rej2+ey)/Ymean<< " Ymean/(rej2-ey) = " << Ymean/(rej2-ey) << std::endl;
+  	gr->RemovePoint(i);
+	i--;
+	npr++;
+      }
+    }
+
+    if(rejectNullErrors) {
+      if(ex==0 && ey==0) {
+	if(debug) std::cout<<"removing point "<<i<<" of "<<gr->GetName() <<"b/c null errors"<<std::endl;
+  	gr->RemovePoint(i);
+        i--;
+	npr++;
+	continue;
+      }
+    }
+    if(forceMonotonic) {
+      if(rej2>rejMin) {
+	if(debug) std::cout<<"forceMonotonic - removing point "<<i<<" of "<<gr->GetName()<<std::endl;
+	if(debug) std::cout<<"pt "<<qq<<" "<<i<<" e="<<eff2<<" r="<<rej2 <<" previous min="<<rejMin<<std::endl;
+  	gr->RemovePoint(i);
+	i--;
+	npr++;
+      }
+    }
+    if(forceBinToBinMonotonic) {
+      if( ( (eff2>eff1)&&(rej2>rej1) ) ||
+          ( (eff2<eff1)&&(rej2<rej1) ) ) {
+	if(debug) std::cout<<"removing point "<<i<<" of "<<gr->GetName()<<std::endl;
+	if(debug) std::cout<<"pt "<<qq<<" "<<i<<" e="<<eff2<<" r="<<rej2 <<" eprev="<<eff1<<" rejprev="<<rej1<<std::endl;
+  	gr->RemovePoint(i);
+	i--;
+	npr++;
+      } else {
+        eff1 = eff2;
+        rej1 = rej2;
+      }
+    }
+
+    if(forceNullErrors)
+      gr->SetPointError(i,0.,0.);
+
+  }
+
+  //if(debug) std::cout<<npr<<"(/"<<np<<") points of "<<gr->GetName()<<" removed."<<std::endl;
+
+}
+
+
+pair<double,double> GetMaxRatioTGraph(TGraphErrors* Gratio, double mineff, double maxeff) {
+  pair<double,double> ratio_ymax_ymin;
+  double ymaxratio = 0.;
+  double yminratio = 1.;
+  int N = Gratio->GetN();
+  //cout << "In GetMaxRatio"<<endl; cout << " N=" << N << " mineff = " << mineff << " maxeff = " << maxeff << endl;
+
+  for (int i=0;i<N;i++) {
+    double x,y;
+    Gratio->GetPoint(i,x,y);
+    double ey = Gratio->GetErrorY(i);
+    
+    double epsi = 0.01; // epsilon marge
+    if (x>(mineff-epsi) && x<(maxeff+epsi)) {
+      //cout << "---i=" << i << " x =" << x << "  y=" << y << "  y+ey=" << y+ey << " y-ey=" << y-ey << endl;
+      //if ((y+ey)>ymaxratio) ymaxratio = y+ey;
+      //if ((y-ey)<yminratio) yminratio = y-ey;
+      if (y>ymaxratio) ymaxratio = y;
+      if (y<yminratio) yminratio = y;
+    } 
+  } // for
+
+  ratio_ymax_ymin.first=ymaxratio;
+  ratio_ymax_ymin.second=yminratio;
+  //cout << "yminratio = " << yminratio << " ymaxratio = " << ymaxratio << " on quite ... " << endl;
+  return ratio_ymax_ymin;
+} ////
+
+
+void plotGraphs(vector<TString> InputFileNames, TString MC, TString sample, vector<TString> leg_entry,bool drawRatio = false, bool drawErrRatio=false) {
+
+  gROOT->SetStyle("ATLAS");
+  gROOT->ForceStyle();
+  gStyle->SetOptStat(kFALSE);
+
+  vector<vector<TH1F*>> h_b,h_u;
+  vector<vector<TGraphErrors*>> vGraph_bu;
+  int ifirst = -1;
+  //cout << "=========================" << endl; cout << "InputFileNames.size()="<< InputFileNames.size() << endl;
+  cout << "=========================" << endl; 
+  for(unsigned int it=0;it<InputFileNames.size();++it) {
+    if(ifirst==-1) ifirst = it;
+    //TString InputFileName = sPath+MC+"/"+InputFileNames[it];
+    TString InputFileName = sPath+InputFileNames[it];
+    TFile *f = TFile::Open(InputFileName);
+    //cout << endl; 
+    cout<<"--Reading input histo from file: "<<InputFileName<<endl;
+    vector<TH1F*> hb,hu;
+    vector<TGraphErrors*> Graph_bu;
+    for (int i=0;i<taggers.size();i++) {
+
+    TString folder1,folder2;
+    if ((taggers[i].View().find("IP2D") < 1) or (taggers[i].View().find("IP3DSV1") < 1) or (taggers[i].View().find("MV2c10") < 1)) {folder1 = "old_taggers/_"+taggers[i]; folder2="old_taggers_"+taggers[i];}
+    else {folder1 = "tagger_"+taggers[i]+"/other"; folder2="tagger_"+taggers[i];}
+    //cout <<"-folder1 ="<<folder1<<" -folder2 ="<<folder2<<endl;
+    TString hname_b= "BTag/AntiKt4EMTopoJets/"+folder1+"/BTag_AntiKt4EMTopoJets_"+folder2+"_b_matched_weight";
+    TString hname_u= "BTag/AntiKt4EMTopoJets/"+folder1+"/BTag_AntiKt4EMTopoJets_"+folder2+"_u_matched_weight";
+
+    //cout << "  hname_b = " << hname_b << " hname_u = " << hname_u << endl;
+    TH1F *MVX_b = (TH1F*)f->Get(hname_b);
+    TH1F *MVX_u = (TH1F*)f->Get(hname_u);
+
+    hb.push_back(MVX_b);
+    hu.push_back(MVX_u);
+    bool isSV1 = false;
+    if (taggers[i]=="SV1") isSV1 = true;
+    TGraphErrors* Graphbu = h_RejvEff(MVX_b,MVX_u,isSV1);
+    Graphbu->SetLineStyle(1);
+    if(InputFileNames.size()>=2 && it>=1) Graphbu->SetLineStyle(lstyle);
+    Graphbu->SetLineWidth(2);
+    if(InputFileNames.size()>2) Graphbu->SetLineColor(lcol[it]);
+    Graph_bu.push_back(Graphbu);
+
+    } // taggers i
+    h_b.push_back(hb);
+    h_u.push_back(hu);
+    vGraph_bu.push_back(Graph_bu);
+  } //root files it
+
+  cout << endl;
+
+  //PlotLikelihoodTaggers(InputFileNames,h_b,h_u);
+
+  //Compute ratio:
+  vector<vector<TGraphErrors*>> gratio;
+  vector <pair<double,double>> v_ratio_ymax_ymin;
+  if(drawRatio){
+    for (int i=0;i<taggers.size();i++) {
+      double ymaxratio = 0.; // to set range on Y of ratio pad
+      double yminratio = 1.; // to set range on Y of ratio pad
+      //cout << "i tagger="<<i << endl;
+      vector<TGraphErrors*> vratio;
+      TGraphErrors* gref=vGraph_bu[ifirst][i];
+      for(unsigned int it=0;it<InputFileNames.size();++it) {
+	//cout << "-it = " << it << endl;
+	if(ifirst==int(it)) continue;
+	TGraphErrors* Corrected = Magic(vGraph_bu[ifirst][i],vGraph_bu[it][i]); // perform extrapolation of Test curve
+	TGraphErrors* Gratio = Corrected;
+	//cout << " # of point = " << Gratio->GetN() << endl;
+	double x_ratio,y_ratio;
+	double eR,eT,eRatio;
+	for (int i=0;i<Gratio->GetN();i++) {
+	  //central value
+	  double x1,x2,y1,y2;
+	  Gratio->GetPoint(i,x1,y1); // Test extrapolated
+	  gref->GetPoint(i,x2,y2);
+	  //if (it==1) cout << " point # = " << i << " Ref: x2= " << x2 << " y2= " << y2 << " Test: x1= " << x1 << " y1= " << y1 << " y1/y2= " << y1/y2 << endl;
+
+	  bool skiplooping= false;
+	  if (y1==0 || y2==0 || isnan(y1) || isnan(y2)) skiplooping= true; 
+	  if (isinf(y1) || isinf(y2)) skiplooping= true; 
+	  //if (it==1) cout << " skiplooping = " << skiplooping << endl;
+
+	  if (!skiplooping) {
+	    x_ratio = x1;
+	    y_ratio = y1/y2;
+	    //uncertainty
+	    eT = Gratio->GetErrorY(i);
+	    eR = gref->GetErrorY(i);
+	    eRatio = (y_ratio)*sqrt(pow((eR/y2),2) + pow(eT/y1,2));
+	    //if (isnan(eRatio)) eRatio = 0;
+
+	  } // if (!skiplooping)
+
+	  //if (it==1) cout << " point # = " << i << " x_ratio = " << x_ratio << " y_ratio = " << y_ratio << " nan? = " << isnan(y_ratio) << endl;
+	  //if (it==1) cout << "eRatio = " << eRatio << " nan? = " << isnan(eRatio) << endl;
+	  Gratio->SetPoint(i,x_ratio,y_ratio);
+	  Gratio->SetPointError(i,Gratio->GetErrorX(i),eRatio);
+	    
+ 	} // for (int i=0;i<Gratio->GetN();i++)
+
+	vratio.push_back(Gratio);
+	float forceAroundMean=0.;
+	MyGraphCleaner(vratio.back(),kDebugOFF,kApplyTruncateXON,kTruncateXatOne,kApplyTruncateYOFF,kTruncateYatOne,kMonotonicOFF,kBinToBinMonotonicOFF,kRejectNullErrorsOFF,kForceNullErrorsOFF,forceAroundMean);
+	vratio.back()->SetLineWidth(2);
+	vratio.back()->SetLineStyle(vGraph_bu[it][i]->GetLineStyle());
+	vratio.back()->SetLineColor(vGraph_bu[it][i]->GetLineColor());
+	//vratio.back()->GetXaxis()->SetRangeUser(EffMin,EffMax); vratio.back()->Draw();
+	//double y_first_ratio = vratio.back()->Eval(EffMin); // get Y value at X=mineff
+	//double ymin = TMath::MinElement(vratio.back()->GetN(),vratio.back()->GetY()); 
+	//double ymax = TMath::MaxElement(vratio.back()->GetN(),vratio.back()->GetY()); 
+	//cout << "it=" << it << " Eval= " << yratio << " bin_min=" << bin_min << "  bin_max = " << bin_max << "  ymin = " << ymin << " ymax = " << ymax << endl;
+
+	pair<double,double> ratio_ymax_ymin_tmp = GetMaxRatioTGraph(vratio.back(),EffMin,EffMax);
+	//cout <<"ymin_tmp="<< ratio_ymax_ymin_tmp.second << " ymax_tmp=" << ratio_ymax_ymin_tmp.first << endl;
+	double ymax_tmp = ratio_ymax_ymin_tmp.first;
+	double ymin_tmp = ratio_ymax_ymin_tmp.second;
+ 	if (ymax_tmp>ymaxratio) ymaxratio=ymax_tmp;
+	if (ymin_tmp<yminratio) yminratio=ymin_tmp;
+      } // it
+      gratio.push_back(vratio);
+      pair<double,double> ratio_ymax_ymin;
+      //cout << "yminratio = " << yminratio << " ymaxratio=" << ymaxratio << endl;
+      ratio_ymax_ymin.first=ymaxratio;
+      ratio_ymax_ymin.second=yminratio;
+      v_ratio_ymax_ymin.push_back(ratio_ymax_ymin);
+    } // i tagger
+
+  } // compute ratio
+
+  //////////////////////////////////////////////////
+  for (int i=0;i<taggers.size();i++) {
+
+    //set Xaxis range
+    double mineff = EffMin;
+    double maxeff = EffMax;
+    //if (taggers[i]=="SV1") maxeff = 0.75;
+    vGraph_bu[ifirst][i]->GetXaxis()->SetLimits(mineff,maxeff);
+    vGraph_bu[ifirst][i]->SetMinimum(1.);
+    if(drawRatio) vGraph_bu[ifirst][i]->SetMinimum(0.8);
+    
+    //set Yaxis range
+    //double ymax = 1000.;
+    double ymax = vGraph_bu[ifirst][i]->Eval(mineff); // get Y value at X=mineff
+    ymax += 5.*ymax; //add 5x to ymax
+    //cout << "taggers[i]=" << taggers[i] << " ymax= " << ymax << endl;
+    vGraph_bu[ifirst][i]->SetMaximum(ymax);
+  
+    TCanvas* c1 = new TCanvas("c1"+taggers[i],"c1"+taggers[i],0,0,CWidth,CHeight);
+    c1->SetLogy(1);
+    c1->SetGrid();
+
+    if(drawRatio){
+      TPad *pad1 = new TPad("pad1", "pad1", 0, 0.3, 1, 1.0);
+      pad1->SetLeftMargin(0.15);
+      pad1->SetBottomMargin(0); // Upper and lower plot are joined
+      pad1->Draw();             // Draw the upper pad: pad1
+      pad1->cd();               // pad1 becomes the current pad
+      pad1->SetGrid();
+      gPad->SetTicks();
+      gPad->SetLogy();
+      vGraph_bu[ifirst][i]->GetXaxis()->SetLabelSize(0);
+    } // drawRatio
+
+    vGraph_bu[ifirst][i]->Draw("ALE");
+
+    //vGraph_bu[ifirst][i]->SetFillColor(18);
+    //vGraph_bu[ifirst][i]->SetFillStyle(3000);
+    //vGraph_bu[ifirst][i]->Draw("AL3"); //"3" shows the errors as a band.
+    //TGraphErrors* tmp_gr = (TGraphErrors*)vGraph_bu[ifirst][i]->Clone();
+    //tmp_gr->Draw("LX"); // "X" Do not draw error bars
+
+    vGraph_bu[ifirst][i]->GetXaxis()->SetTitle("b-jet efficiency");
+    vGraph_bu[ifirst][i]->GetYaxis()->SetTitle("light-jet rejection");
+    vGraph_bu[ifirst][i]->GetYaxis()->SetTitleOffset(1.3);
+ 
+   if(!drawRatio){
+      vGraph_bu[ifirst][i]->GetXaxis()->SetTitleSize(0.04);
+      vGraph_bu[ifirst][i]->GetXaxis()->SetLabelSize(0.04);
+      vGraph_bu[ifirst][i]->GetYaxis()->SetTitleSize(0.04);
+      vGraph_bu[ifirst][i]->GetYaxis()->SetLabelSize(0.04);
+    }
+
+    for(unsigned int it=0;it<InputFileNames.size();++it) {
+      if(ifirst==int(it)) continue;
+      vGraph_bu[it][i]->Draw("LE");
+      //vGraph_bu[it][i]->Draw("CLE");
+    }//file name
+
+    //Legend
+    TLegend* lg = new TLegend(0.55,0.5,0.88,0.845);
+    lg->SetBorderSize(0);
+    lg->SetFillStyle(0);
+    for(unsigned int it=0;it<InputFileNames.size();it++) {
+      //lg->AddEntry(vGraph_bu[it][i], leg_entry[it],"LF");
+      lg->AddEntry(vGraph_bu[it][i], leg_entry[it],"L");
+    }
+    lg->SetTextSize(0.03);
+    if(drawRatio) lg->SetTextSize(0.04);
+    lg->Draw();
+
+    //Text
+    VALID_LABEL(0.25,0.9,1,sample,drawRatio);
+    myText(taggers[i],0.25,0.3,1,drawRatio,0.07); 
+
+    if(drawRatio){
+      // lower plot will be in pad
+      c1->cd();          // Go back to the main canvas before defining pad2
+
+      //range on Y axis for ratio plot //
+      double ymin_ratio = 0.9;
+      double ymax_ratio = 1.1;
+ 
+      // 
+      double scale = 0.3; // scale up and down by 20% to set the ratio bondaries
+
+      double ymaxratio= v_ratio_ymax_ymin[i].first;
+      double yminratio= v_ratio_ymax_ymin[i].second;
+      
+      if(yminratio<ymin_ratio) ymin_ratio = yminratio-scale*(1.-yminratio);
+      if(ymaxratio>ymax_ratio) ymax_ratio = ymaxratio+scale*(ymaxratio-1.);
+
+      //cout << " i= " << i << " ratio ymax,ymin= " << ymaxratio << " " << yminratio << " |  scaled ymax_ratio =" << ymax_ratio << " scaled ymin_ratio =" << ymin_ratio << endl;
+
+
+      TPad *pad2 = new TPad("pad2", "pad2", 0, 0.05, 1, 0.3);
+      pad2->Range(mineff,ymin_ratio,maxeff,ymax_ratio);
+      pad2->SetLeftMargin(0.15);
+      pad2->SetTopMargin(0);
+      pad2->SetBottomMargin(0.35);
+      pad2->Draw();
+      pad2->cd();       // pad2 becomes the current pad
+      gStyle->SetEndErrorSize(0);
+      gPad->SetTicks();  
+      gPad->SetLogy(0);
+
+      gratio[i][0]->SetMinimum(ymin_ratio);
+      gratio[i][0]->SetMaximum(ymax_ratio);
+
+      gratio[i][0]->SetFillColor(18);
+      //gratio[i][0]->SetFillStyle(3001);
+
+
+      //Draw error band on ratio?
+      if (!drawErrRatio) {
+        gratio[i][0]->Draw("alx0"); // A: axis L: simple line 
+      } else {
+        gratio[i][0]->Draw("AC3"); // 
+        gratio[i][0]->Draw("lx"); //x: without error bar  
+      }
+
+      gratio[i][0]->GetYaxis()->SetLabelSize(0.);
+      TGaxis *axis2 = new TGaxis( mineff, 1.001*ymin_ratio, mineff, 0.999*ymax_ratio, 1.001*ymin_ratio, 0.999*ymax_ratio, 505,"");
+      axis2->SetLabelFont(43); // Absolute font size in pixel (precision 3)
+      axis2->SetLabelSize(15);
+      axis2->Draw();        
+
+      // Y axis ratio plot settings
+      gratio[i][0]->GetYaxis()->SetTitle("Ratio");
+      gratio[i][0]->GetYaxis()->SetNdivisions(505);
+      gratio[i][0]->GetYaxis()->SetTitleSize(20);
+      gratio[i][0]->GetYaxis()->SetTitleFont(43);
+      gratio[i][0]->GetYaxis()->SetTitleOffset(1.5);
+      gratio[i][0]->GetYaxis()->CenterTitle();
+      
+      // X axis ratio plot settings
+      gratio[i][0]->GetXaxis()->SetTitleSize(20);
+      gratio[i][0]->GetXaxis()->SetTitleFont(43);
+      gratio[i][0]->GetXaxis()->SetTitleOffset(4.);
+      gratio[i][0]->GetXaxis()->SetLabelFont(43); // Absolute font size in pixel (precision 3)
+      gratio[i][0]->GetXaxis()->SetLabelSize(15);
+      gratio[i][0]->GetXaxis()->SetTitle("b-jet efficiency");
+      gratio[i][0]->GetXaxis()->SetLimits(mineff,maxeff);
+      
+      TLine* line = new TLine(mineff, 1., maxeff,1.);
+      line->Draw("same");
+      line->SetLineStyle(lstyle);
+      
+      //cout << "gratio[i].size() = " << gratio[i].size() << endl;
+
+      for(unsigned int it=1;it<gratio[i].size();it++){
+	gratio[i][it]->Draw("Lxsame");
+      }
+
+    } // drawRatio
+
+ 
+    //check if the directory where to save histo exits
+    if(gSystem->AccessPathName("ROC/")){
+      std::cout << "ROC/ directory does not exist. Will create one." << std::endl;
+      gSystem->Exec("mkdir ROC");
+    } 
+
+    //TString Histo = HistoDir+MC+taggers[i]+".png";
+    TString Histo = HistoDir+taggers[i]+".png";
+    c1->SaveAs(Histo.Data(),"RECREATE");
+    Histo = HistoDir+taggers[i]+".pdf";
+    //cout << "Saving Histo = " << Histo.Data() << endl;
+    c1->SaveAs(Histo.Data(),"RECREATE");
+   
+  } // tagger i
+
+} // plotGraphs
+
+
+// a method for ploting the efficiency vs a variable
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void plotGraphsEffVsVar(TString var_name, vector<TString> InputFileNames, TString MC, TString sample, vector<TString> leg_entry,bool drawRatio = false, bool drawErrRatio=false) {
+
+  gROOT->SetStyle("ATLAS");
+  gROOT->ForceStyle();
+  gStyle->SetOptStat(kFALSE);
+
+  /////////////////////////////////////////////
+  // get the histograms and graphs
+
+  vector<vector<vector<vector<TH1F*> > > > histos, histos_WPcuts;
+  vector<vector<vector<vector<TGraphErrors*> > > > graphs;
+  int ifirst = -1;
+  cout << "=========================" << endl; 
+  // loop over the input files
+  for(unsigned int it = 0; it < InputFileNames.size(); ++it) {
+    if(ifirst==-1) ifirst = it;
+    // get the file
+    TString InputFileName = sPath+InputFileNames[it];
+    TFile *f = TFile::Open(InputFileName);
+    cout<<"--Reading input histo from file: "<<InputFileName<<endl;
+    // define vectors to hold histos
+    vector<vector<vector<TH1F*> > > histos_forTaggers, histos_WPcuts_forTaggers;
+    vector<vector<vector<TGraphErrors*> > > graphs_forTaggers;
+
+    // loop over the taggers
+    for (int i=0; i < taggers.size(); i++) {
+      // get the right histos
+
+      TString folder1,folder2;
+      if ((taggers[i].View().find("IP2D") < 1) or (taggers[i].View().find("IP3DSV1") < 1) or (taggers[i].View().find("MV2c10") < 1)) {folder1 = "old_taggers/_"+taggers[i]; folder2="old_taggers_"+taggers[i];}
+      else {folder1 = "tagger_"+taggers[i]+ "/_" + var_name; folder2="tagger_"+taggers[i];}
+      //cout <<"-folder1 ="<<folder1<<" -folder2 ="<<folder2<<endl;
+ 
+      /*
+      TString folder;
+      if(taggers[i].View().find("old_taggers") < 1) {folder = taggers[i]; folder.Insert(11, "/");}// insert a slash after "old_taggers"
+      else folder = taggers[i] + "/_" + var_name;
+      std::cout << "  folder = " << folder << std::endl;
+      */
+
+      // define vectors
+      vector<vector<TH1F*> > histos_forLabels, histos_WPcuts_forLabels;
+      vector<vector<TGraphErrors*> > graphs_forLabels;
+
+      // loop over the truth labels
+      for(int i_truthlabel = 0; i_truthlabel < truth_labels.size(); i_truthlabel++){
+        TString histo_truth_label = truth_labels[i_truthlabel];
+        if(histo_truth_label == "u") histo_truth_label = "l";
+        TString hname = getRefHistoName(var_name, histo_truth_label);
+        //cout << "  hname = " << hname << endl;
+        TH1F *histo = (TH1F*)f->Get(hname);
+
+        // define vectors
+        vector<TH1F*> histos_forWPs, histos_WPcuts_forWPs;
+        vector<TGraphErrors*> graphs_forWPs;
+
+        // loop over the WP cuts
+        vector<TString> tagger_WPs = WP_values.at(taggers[i]);
+        for(int i_WP = 0; i_WP < tagger_WPs.size(); i_WP++){
+
+	  TString hname_WPcuts = "BTag/AntiKt4EMTopoJets/"+folder1+"/BTag_AntiKt4EMTopoJets_"+folder2+"_" + truth_labels[i_truthlabel] + "_" + tagger_WPs[i_WP] + "_matched_" + var_name;
+          //cout << "  hname_WPcuts = " << hname_WPcuts << endl;
+
+          TH1F *histo_WPcuts = (TH1F*)f->Get(hname_WPcuts);
+
+          // define the graph
+          TGraphErrors* graph = h_EffvsVar(histo, histo_WPcuts);
+
+	  //Truncate y efficiency above 0.99 first...
+	  float TruncateAtY = 0.99;
+	  float forceAroundMean=0.;
+ 	  MyGraphCleaner(graph,kDebugON,kApplyTruncateXOFF,kTruncateXatOne,kApplyTruncateYON,kTruncateYatOne,kMonotonicOFF,kBinToBinMonotonicOFF,kRejectNullErrorsOFF,kForceNullErrorsOFF,forceAroundMean);
+
+	  //cout <<"Cleaning around mean, first pass..." <<  endl;
+	  forceAroundMean=3.;
+ 	  MyGraphCleaner(graph,kDebugON,kApplyTruncateXOFF,kTruncateXatOne,kApplyTruncateYON,kTruncateYatOne,kMonotonicOFF,kBinToBinMonotonicOFF,kRejectNullErrorsOFF,kForceNullErrorsOFF,forceAroundMean);
+
+	  //cout <<"Cleaning around mean, second pass (to get a more accurante mean in Y)..." <<  endl;
+ 	  MyGraphCleaner(graph,kDebugON,kApplyTruncateXOFF,kTruncateXatOne,kApplyTruncateYON,kTruncateYatOne,kMonotonicOFF,kBinToBinMonotonicOFF,kRejectNullErrorsOFF,kForceNullErrorsOFF,forceAroundMean);
+
+          // set line styles
+          graph->SetLineStyle(1);
+          if(InputFileNames.size()>=2 && it>=1) {graph->SetLineStyle(lstyle);}
+          graph->SetLineWidth(2);
+          if(InputFileNames.size()>2) {graph->SetLineColor(lcol[it]); graph->SetMarkerStyle(msty[it]);}
+
+          // add them to the vectors
+          histos_forWPs.push_back(histo);
+          histos_WPcuts_forWPs.push_back(histo_WPcuts);
+          graphs_forWPs.push_back(graph);
+        } // WPs
+        // add them to the vectors
+        histos_forLabels.push_back(histos_forWPs);
+        histos_WPcuts_forLabels.push_back(histos_WPcuts_forWPs);
+        graphs_forLabels.push_back(graphs_forWPs);
+      } // truth labels
+      histos_forTaggers.push_back(histos_forLabels);
+      histos_WPcuts_forTaggers.push_back(histos_WPcuts_forLabels);
+      graphs_forTaggers.push_back(graphs_forLabels);
+    } // taggers
+    histos.push_back(histos_forTaggers);
+    histos_WPcuts.push_back(histos_WPcuts_forTaggers);
+    graphs.push_back(graphs_forTaggers);
+  } //root files it
+
+  cout << endl;
+
+  /////////////////////////////////////////////
+  // compute ratio
+
+  vector<vector<vector<vector<TGraphErrors*> > > > graph_ratios;
+  vector<vector<vector<pair<double,double> > > >    v_ratio_ymax_ymin;
+  if(drawRatio){
+
+    for (int i=0;i<taggers.size();i++) {
+      vector<vector<vector<TGraphErrors*> > > graph_ratios_forLabels;
+      vector<vector<pair<double,double> > >  v_ratio_ymax_ymin_forLabels;
+
+      for(int i_truthlabel = 0; i_truthlabel < truth_labels.size(); i_truthlabel++){
+        vector<vector<TGraphErrors*> > graph_ratios_forWPs;
+	vector<pair<double,double> > v_ratio_ymax_ymin_forWPs;
+        vector<TString> tagger_WPs = WP_values.at(taggers[i]);
+
+        for(int i_WP = 0; i_WP < tagger_WPs.size(); i_WP++){
+          //cout << "i tagger="<<i << endl;
+          vector<TGraphErrors*> graph_ratios_forFiles;
+          TGraphErrors* Gref = graphs[ifirst][i][i_truthlabel][i_WP];
+
+	  double Xmin,Xmax,Ymin,Ymax;  // ??
+	  Gref->GetPoint(0,Xmin,Ymin);  // 
+	  Gref->GetPoint(Gref->GetN()-1,Xmax,Ymax); //
+	  //cout << "Xmin_pt0 = " << Xmin << " Xmax_ptend = " << Xmax << " Gref->GetN() = " << Gref->GetN() << endl;
+	  //cout << "Ymin_pt0 = " << Ymin << " Ymax_ptend = " << Ymax << " Gref->GetN() = " << Gref->GetN() << endl;
+	  double ymaxratio = 0.; // to set range on Y of ratio pad
+	  double yminratio = 1.; // to set range on Y of ratio pad
+	  
+          for(unsigned int it=0;it<InputFileNames.size();++it) {
+	    //cout << "-it = " << it << endl;
+	    if(ifirst==int(it)) continue;
+	    TGraphErrors* Gratio=(TGraphErrors*)graphs[it][i][i_truthlabel][i_WP]->Clone();
+	    
+	    //cout << " # of point = " << Gratio->GetN() << endl;
+	    double x_ratio,y_ratio;
+	    double eR,eT,eRatio;
+            // loop over bins
+	    for (int i=0; i < Gratio->GetN(); i++) {
+	      //central value
+	      double x1,x2,y1,y2;
+	      Gratio->GetPoint(i,x1,y1); // Test extrapolated
+	      Gref->GetPoint(i,x2,y2);
+	      //if (it==1) cout << " point # = " << i << " Ref: x2= " << x2 << " y2= " << y2 << " Test: x1= " << x1 << " y1= " << y1 << " y2/y1= " << y2/y1 << endl;
+	      
+	      bool skiplooping = false;
+	      if (y1==0 || y2==0 || isnan(y1) || isnan(y2)) skiplooping = true; 
+	      if (isinf(y1) || isinf(y2)) skiplooping = true; 
+	      //if (it==1) cout << " skiplooping = " << skiplooping << endl;
+	      
+	      if (!skiplooping) {
+		x_ratio = x1;
+		y_ratio = y1/y2; // Test/Ref
+		//y_ratio = y2/y1;
+		//uncertainty
+		eT = Gratio->GetErrorY(i);
+		eR = Gref->GetErrorY(i);
+		eRatio = (y_ratio)*sqrt(pow((eR/y2),2) + pow(eT/y1,2));
+		//if (isnan(eRatio)) eRatio = 0;
+              }
+	      
+	      //if (it==1) cout << " point # = " << i << " x_ratio = " << x_ratio << " y_ratio = " << y_ratio << " nan? = " << isnan(y_ratio) << endl;
+	      //if (it==1) cout << "eRatio = " << eRatio << " nan? = " << isnan(eRatio) << endl;
+	      Gratio->SetPoint(i,x_ratio,y_ratio);
+	      Gratio->SetPointError(i,Gratio->GetErrorX(i),eRatio);
+            } // end loop over bins
+	    
+	    Gratio->SetLineWidth(2);
+	    Gratio->SetLineStyle(graphs[it][i][i_truthlabel][i_WP]->GetLineStyle());
+	    Gratio->SetLineColor(graphs[it][i][i_truthlabel][i_WP]->GetLineColor());
+	    graph_ratios_forFiles.push_back(Gratio);
+	    
+	    //cout << "it=" << it << " Eval= " << yratio << " bin_min=" << bin_min << "  bin_max = " << bin_max << "  ymin = " << ymin << " ymax = " << ymax << endl;
+	    
+	    pair<double,double> ratio_ymax_ymin_tmp = GetMaxRatioTGraph(graph_ratios_forFiles.back(),Xmin,Xmax); 
+	    //cout <<"ymin_tmp="<< ratio_ymax_ymin_tmp.second << " ymax_tmp=" << ratio_ymax_ymin_tmp.first << endl;
+	    double ymax_tmp = ratio_ymax_ymin_tmp.first;
+	    double ymin_tmp = ratio_ymax_ymin_tmp.second;
+	    if (ymax_tmp>ymaxratio) ymaxratio=ymax_tmp;
+	    if (ymin_tmp<yminratio) yminratio=ymin_tmp;
+          } // loop over files
+          graph_ratios_forWPs.push_back(graph_ratios_forFiles);
+	  pair<double,double> ratio_ymax_ymin;
+	  //cout << "yminratio = " << yminratio << " ymaxratio=" << ymaxratio << endl;
+	  ratio_ymax_ymin.first=ymaxratio;
+	  ratio_ymax_ymin.second=yminratio;
+	  v_ratio_ymax_ymin_forWPs.push_back(ratio_ymax_ymin);
+        } // loop over WPs
+        graph_ratios_forLabels.push_back(graph_ratios_forWPs);
+	v_ratio_ymax_ymin_forLabels.push_back(v_ratio_ymax_ymin_forWPs);
+      } // loop over truth labels
+      graph_ratios.push_back(graph_ratios_forLabels);
+      v_ratio_ymax_ymin.push_back(v_ratio_ymax_ymin_forLabels);
+    } // loop over taggers
+
+  } // compute ratio
+
+  /////////////////////////////////////////////
+  // make the plots
+
+  for (int i=0;i<taggers.size();i++) {
+
+    vector<TString> tagger_WPs = WP_values.at(taggers[i]);
+    for(int i_truthlabel = 0; i_truthlabel < truth_labels.size(); i_truthlabel++){
+      for(int i_WP = 0; i_WP < tagger_WPs.size(); i_WP++){
+
+	double scale = 0.3; // scale up and down by 30% to set the ratio bondaries
+	double YmaxPlotEff = graphs[ifirst][i][i_truthlabel][i_WP]->GetHistogram()->GetMaximum();
+	YmaxPlotEff = (1.+scale)*YmaxPlotEff;
+
+        graphs[ifirst][i][i_truthlabel][i_WP]->SetMinimum(0.);
+        graphs[ifirst][i][i_truthlabel][i_WP]->SetMaximum(YmaxPlotEff);
+
+        TString myRandomNumber = to_string(rand());
+        TCanvas* c2 = new TCanvas("c2"+taggers[i]+truth_labels[i_truthlabel]+tagger_WPs[i_WP]+myRandomNumber,"c2"+taggers[i]+truth_labels[i_truthlabel]+tagger_WPs[i_WP]+myRandomNumber,0,0,CWidth,CHeight);
+        //c2->SetLogy(1);
+        c2->SetGrid();
+
+        if(drawRatio){
+          TPad *pad21 = new TPad("pad21"+taggers[i]+truth_labels[i_truthlabel]+tagger_WPs[i_WP]+myRandomNumber, "pad21"+taggers[i]+truth_labels[i_truthlabel]+tagger_WPs[i_WP]+myRandomNumber, 0, 0.3, 1, 1.0);
+          pad21->SetLeftMargin(0.15);
+          pad21->SetBottomMargin(0); // Upper and lower plot are joined 
+          pad21->Draw();             // Draw the upper pad: pad2
+          pad21->cd();               // pad2 becomes the current pad
+          pad21->SetGrid();
+          gPad->SetTicks();
+          //gPad->SetLogy();
+          graphs[ifirst][i][i_truthlabel][i_WP]->GetXaxis()->SetLabelSize(0); // to be put back
+        } // drawRatio
+
+        //graphs[ifirst][i][i_truthlabel][i_WP]->Draw("APLE");
+        //graphs[ifirst][i][i_truthlabel][i_WP]->Draw("AC");
+        graphs[ifirst][i][i_truthlabel][i_WP]->SetFillColor(18);
+        graphs[ifirst][i][i_truthlabel][i_WP]->SetFillStyle(3000);// https://root.cern.ch/doc/master/classTAttFill.html
+        graphs[ifirst][i][i_truthlabel][i_WP]->Draw("AL3"); //"3" shows the errors as a band.
+	TGraphErrors* tmp_gr = (TGraphErrors*)graphs[ifirst][i][i_truthlabel][i_WP]->Clone();
+	tmp_gr->Draw("LX"); // "X" Do not draw error bars
+	
+
+	c2->Update();
+	double Xmin,Xmax,Ymin,Ymax;  // ??
+	Xmin=gPad->GetUxmin();
+	Xmax=gPad->GetUxmax();
+	Ymin=gPad->GetUymin();
+	Ymax=gPad->GetUymax();
+	//cout << "Xmin = " << Xmin << " Xmax = " << Xmax << " Ymin = " << Ymin << " Ymax = " << Ymax << endl;
+
+	if(var_name == "pt_ttbar") graphs[ifirst][i][i_truthlabel][i_WP]->GetXaxis()->SetTitle("jet pT (GeV) for ttbar");
+	else if(var_name == "pt_Zprime") graphs[ifirst][i][i_truthlabel][i_WP]->GetXaxis()->SetTitle("jet pT (GeV) for Z'");
+	else if(var_name == "Lxy") graphs[ifirst][i][i_truthlabel][i_WP]->GetXaxis()->SetTitle("Transverse SV vertex decay length Lxy (mm)"); 
+
+        //graphs[ifirst][i][i_truthlabel][i_WP]->GetXaxis()->SetTitle("jet " + var_name);
+        graphs[ifirst][i][i_truthlabel][i_WP]->GetYaxis()->SetTitle("\% jets passing WP cut (efficiency)");
+        graphs[ifirst][i][i_truthlabel][i_WP]->GetYaxis()->SetTitleOffset(1.3);
+ 
+        if(!drawRatio){
+          graphs[ifirst][i][i_truthlabel][i_WP]->GetXaxis()->SetTitleSize(0.04);
+          graphs[ifirst][i][i_truthlabel][i_WP]->GetXaxis()->SetLabelSize(0.04);
+          graphs[ifirst][i][i_truthlabel][i_WP]->GetYaxis()->SetTitleSize(0.04);
+          graphs[ifirst][i][i_truthlabel][i_WP]->GetYaxis()->SetLabelSize(0.04);
+        }
+
+        for(unsigned int it=0;it<InputFileNames.size();++it) {
+          if(ifirst==int(it)) continue;
+          graphs[it][i][i_truthlabel][i_WP]->Draw("L0");
+	  //c2->Update();
+          //graphs[it][i][i_truthlabel][i_WPs]->Draw("LE");
+          //graphs[it][i][i_truthlabel][i_WPs]->Draw("CLE");
+        }//file name
+
+        //Legend
+        //TLegend* lg2 = new TLegend(0.55,0.5,0.88,0.845);
+        //TLegend* lg2 = new TLegend(0.7,0.7,0.90,0.90);
+        TLegend* lg2 = new TLegend(0.5,0.7,0.90,0.90);
+        lg2->SetBorderSize(0);
+        lg2->SetFillStyle(0);
+        for(unsigned int it=0;it<InputFileNames.size();it++) {
+          //lg2->AddEntry(graphs[it][i][i_truthlabel][i_WP], leg_entry[it],"L");
+          lg2->AddEntry(graphs[it][i][i_truthlabel][i_WP], leg_entry[it],"LF");
+        }
+        lg2->SetTextSize(0.03);
+        if(drawRatio) lg2->SetTextSize(0.04);
+        lg2->Draw();
+
+        //Text
+        VALID_LABEL(0.25,0.9,1,sample,drawRatio);
+        myDescriptionLabel(taggers[i]+", "+tagger_WPs[i_WP]+"\% WP"+", "+truth_labels[i_truthlabel]+"-jets",0.25,0.9,1,drawRatio); 
+
+        if(drawRatio){
+          // lower plot will be in pad
+          c2->cd();          // Go back to the main canvas before defining pad2
+
+          //range on Y axis for ratio plot //
+          double ymin_ratio = 0.9;
+          double ymax_ratio = 1.1;
+          double scale = 0.3; // scale up and down by 20% to set the ratio bondaries
+
+          double ymaxratio = v_ratio_ymax_ymin[i][i_truthlabel][i_WP].first;
+          double yminratio = v_ratio_ymax_ymin[i][i_truthlabel][i_WP].second;
+      
+          if(yminratio<ymin_ratio) ymin_ratio = yminratio-scale*(1.-yminratio);
+          if(ymaxratio>ymax_ratio) ymax_ratio = ymaxratio+scale*(ymaxratio-1.);
+
+          //cout << " i= " << i << " ratio ymax,ymin= " << ymaxratio << " " << yminratio << " |  scaled ymax_ratio =" << ymax_ratio << " scaled ymin_ratio =" << ymin_ratio << " Xmin = " << Xmin << " Xmax = " << Xmax << " Ymin = " << Ymin << " Ymax = " << Ymax << endl;
+
+          TPad *pad22 = new TPad("pad22"+taggers[i]+truth_labels[i_truthlabel]+tagger_WPs[i_WP]+myRandomNumber, "pad22"+taggers[i]+truth_labels[i_truthlabel]+tagger_WPs[i_WP]+myRandomNumber, 0, 0.05, 1, 0.3);
+          ////pad22->Range(xmin,ymin_ratio,xmax,ymax_ratio);
+          pad22->Range(Xmin,ymin_ratio,Xmax,ymax_ratio); // ??
+          pad22->SetLeftMargin(0.15);
+          pad22->SetTopMargin(0);
+          pad22->SetBottomMargin(0.35);
+          pad22->Draw();
+          pad22->cd();       // pad2 becomes the current pad
+          gStyle->SetEndErrorSize(0);
+          gPad->SetTicks();  
+          gPad->SetLogy(0);
+
+          graph_ratios[i][i_truthlabel][i_WP][0]->SetMinimum(ymin_ratio);
+          graph_ratios[i][i_truthlabel][i_WP][0]->SetMaximum(ymax_ratio);
+
+          graph_ratios[i][i_truthlabel][i_WP][0]->SetFillColor(18);
+          //graph_ratios[i][i_truthlabel][i_WP][0]->SetFillStyle(3001);
+
+
+          //Draw error band on ratio?
+          if (!drawErrRatio) {
+            graph_ratios[i][i_truthlabel][i_WP][0]->Draw("alx0"); // A: axis L: simple line 
+          } else {
+            graph_ratios[i][i_truthlabel][i_WP][0]->Draw("AC3"); // 
+            graph_ratios[i][i_truthlabel][i_WP][0]->Draw("lx"); //x: without error bar  
+          }
+
+          graph_ratios[i][i_truthlabel][i_WP][0]->GetYaxis()->SetLabelSize(0.);
+          TGaxis *axis22 = new TGaxis( Xmin, 1.001*ymin_ratio, Xmin, 0.999*ymax_ratio, 1.001*ymin_ratio, 0.999*ymax_ratio, 505,""); 
+          axis22->SetLabelFont(43); // Absolute font size in pixel (precision 3)
+          axis22->SetLabelSize(15);
+          axis22->Draw();        
+
+          // Y axis ratio plot settings
+          graph_ratios[i][i_truthlabel][i_WP][0]->GetYaxis()->SetTitle("Ratio");
+          graph_ratios[i][i_truthlabel][i_WP][0]->GetYaxis()->SetNdivisions(505);
+          graph_ratios[i][i_truthlabel][i_WP][0]->GetYaxis()->SetTitleSize(20);
+          graph_ratios[i][i_truthlabel][i_WP][0]->GetYaxis()->SetTitleFont(43);
+          graph_ratios[i][i_truthlabel][i_WP][0]->GetYaxis()->SetTitleOffset(1.5);
+          graph_ratios[i][i_truthlabel][i_WP][0]->GetYaxis()->CenterTitle();
+      
+          // X axis ratio plot settings
+          graph_ratios[i][i_truthlabel][i_WP][0]->GetXaxis()->SetTitleSize(20);
+          graph_ratios[i][i_truthlabel][i_WP][0]->GetXaxis()->SetTitleFont(43);
+          graph_ratios[i][i_truthlabel][i_WP][0]->GetXaxis()->SetTitleOffset(4.);
+          graph_ratios[i][i_truthlabel][i_WP][0]->GetXaxis()->SetLabelFont(43); // Absolute font size in pixel (precision 3)
+          graph_ratios[i][i_truthlabel][i_WP][0]->GetXaxis()->SetLabelSize(15);
+	  if(var_name == "pt_ttbar") graph_ratios[i][i_truthlabel][i_WP][0]->GetXaxis()->SetTitle("jet pT (GeV) for ttbar");
+	  else if(var_name == "pt_Zprime") graph_ratios[i][i_truthlabel][i_WP][0]->GetXaxis()->SetTitle("jet pT (GeV) for Z'");
+	  else if(var_name == "Lxy") graph_ratios[i][i_truthlabel][i_WP][0]->GetXaxis()->SetTitle("Transverse SV vertex decay length Lxy (mm)"); 
+
+          //graph_ratios[i][i_truthlabel][i_WP][0]->GetXaxis()->SetLimits(xmin,xmax);
+          graph_ratios[i][i_truthlabel][i_WP][0]->GetXaxis()->SetLimits(Xmin,Xmax); // ??
+      
+          //TLine* line = new TLine(mineff, 1., maxeff,1.);
+          //TLine* line = new TLine(xmin, 1., xmax, 1.);
+          TLine* line = new TLine(Xmin, 1., Xmax, 1.); // ??
+          line->Draw("same");
+          line->SetLineStyle(lstyle);
+      
+          //cout << "gratio[i].size() = " << gratio[i].size() << endl;
+
+          for(unsigned int it=1;it<graph_ratios[i][i_truthlabel][i_WP].size();it++){
+	    graph_ratios[i][i_truthlabel][i_WP][it]->Draw("Lxsame");
+          }
+
+        } // drawRatio
+	
+        //check if the directory where to save histo exits
+        if(gSystem->AccessPathName("ROC/eff_vs_"+var_name)){
+          std::cout << "ROC/eff_vs_"+var_name+" directory does not exist. Will create one." << std::endl;
+          gSystem->Exec("mkdir -p ROC/");
+          gSystem->Exec("mkdir ROC/eff_vs_"+var_name);
+        } 
+	
+        //TString Histo = HistoDir+MC+taggers[i]+".png";
+        TString plot_name = HistoDir+"eff_vs_"+var_name+"/eff_vs_"+var_name+"_"+taggers[i]+"_"+truth_labels[i_truthlabel]+"-jets"+"_"+tagger_WPs[i_WP]+"_WP.png";
+        c2->SaveAs(plot_name.Data(),"RECREATE");
+        plot_name = HistoDir+"eff_vs_"+var_name+"/eff_vs_"+var_name+"_"+taggers[i]+"_"+truth_labels[i_truthlabel]+"-jets"+"_"+tagger_WPs[i_WP]+"_WP.pdf";
+        c2->SaveAs(plot_name.Data(),"RECREATE");
+
+        //c2->Close();
+      }
+    } 
+  } // tagger i
+
+} // plotGraphs
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void Draw_PhysVal_btagROC(){
+  TH1::SetDefaultSumw2(true);
+  fill_WP_values();
+
+  //Save histos 
+  string outputName_Histos = "MyHistos.root"; 
+  TFile *hfile = new TFile(outputName_Histos.c_str(),"RECREATE");
+
+  ////////////////////////////////// 
+  //      validation              //
+  ////////////////////////////////// 
+  //ttbar
+  TString MC = "ttbar"; TString sample = "#sqrt{s}=13 TeV, t#bar{t}";
+  TString reffile = "files_merged/merged_NTUP_PHYSVAL_ref.root";
+  TString testfile = "files_merged/merged_NTUP_PHYSVAL_test.root";
+  vector<TString> InputFilesNames = {reffile, testfile};
+  vector<TString> leg_entry = {"Reference","Test"};
+
+
+  ///////////////////
+  //Plot ROC curves 
+  bool drawRatio=true;
+  bool drawErrRatio=false;
+  plotGraphs(InputFilesNames,MC,sample,leg_entry,drawRatio,drawErrRatio);
+  plotGraphsEffVsVar("Lxy", InputFilesNames,MC,sample,leg_entry,drawRatio,drawErrRatio);
+
+  drawRatio=true;
+  if(MC == "ttbar"){
+    //cout << "ttbar"<<endl;
+    plotGraphsEffVsVar("pt_ttbar", InputFilesNames,MC,sample,leg_entry,drawRatio,drawErrRatio);
+  }
+  else if (MC == "Zprime"){
+    plotGraphsEffVsVar("pt_Zprime", InputFilesNames,MC,sample,leg_entry,drawRatio,drawErrRatio);
+  }
+  ///////////////////
+
+  //Save histos
+  hfile->Write();
+
+} // end of Draw_PhysVal_btagROC()
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
diff --git a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/README.md b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..6db42b1e9e9f0705837ff092d9894537de6f0704
--- /dev/null
+++ b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/README.md
@@ -0,0 +1,4 @@
+## FTAG PHYSVAL
+
+These scripts are used for the post-processing of the FTag PHYSVAL.  
+The whole procedure is described here: [FTag PHYSVAL tutorial on the atlassoftwaredocs website](https://atlassoftwaredocs.web.cern.ch/_staging/create-ftag-guides/guides/ftag/tutorials/#1-physval).
\ No newline at end of file
diff --git a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/add_line_breaks_to_html.sh b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/add_line_breaks_to_html.sh
new file mode 100644
index 0000000000000000000000000000000000000000..7e01705ca72842a856b3fb240edae9bdb31243c4
--- /dev/null
+++ b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/add_line_breaks_to_html.sh
@@ -0,0 +1,9 @@
+DIR="./testMerging/"
+
+# look for all index.html file in the dir
+for FILE in $(find $DIR -name "index.html")
+do
+  echo $FILE
+  # add a break-word to the html at the right point
+  sed -i 's/style="text-overflow:ellipsis;overflow:hidden/style="word-wrap:break-word;text-overflow:ellipsis;overflow:hidden/g' $FILE
+done
\ No newline at end of file
diff --git a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/mergePhysValFiles.py b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/mergePhysValFiles.py
new file mode 100644
index 0000000000000000000000000000000000000000..feceab7d520e3dca59bb3a70bbc33fde7c4e07b3
--- /dev/null
+++ b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/mergePhysValFiles.py
@@ -0,0 +1,277 @@
+#!/usr/bin/env python
+
+#----------------------------------------------------------------------
+#stand-alone script to merge specific directories of NTUP_PHYSVAL files 
+#author: philipp.mogg@cern.ch
+#16 May 2016
+#updates: judith.hoefer@cern.ch
+#Nov 2020
+#----------------------------------------------------------------------
+
+from __future__ import print_function
+import getopt,os,sys,glob,argparse,ROOT,time
+from ROOT import gDirectory
+
+start = time.clock()
+
+# define the categories (= sub-folders)
+categories = ['jet',
+              'tracks',
+              'SV',
+              'tagger_IP3D',
+              'tagger_RNNIP',
+              'tagger_SV1',
+              'tagger_JetFitter',
+              'tagger_DL1',
+              'tagger_DL1r',
+              'old_taggers',
+              #'tagger_IP2D',
+              #'tagger_IP3DSV1',
+              #'tagger_MV2c10',
+             ]
+
+# name of the folder into which plots in no other category are sorted
+restCategory = 'other' 
+
+# make subcategories
+categories_with_subcategories_type_1 = ['SV', 'tracks']
+
+sub_categories_type_1 = [ '_incl',
+                   '_b',
+                   '_c',
+                   '_l',
+                   '_muon',
+                 ]
+
+categories_with_subcategories_type_2 = ['tagger_IP3D', 'tagger_RNNIP', 'tagger_SV1', 'tagger_JetFitter', 'tagger_DL1', 'tagger_DL1r']
+
+sub_categories_type_2 = [ '_pt_ttbar',
+                   '_pt_Zprime',
+                   '_Lxy'
+                 ]
+
+categories_with_subcategories_type_3 = ['old_taggers']
+
+sub_categories_type_3 = [ '_IP2D',
+                   '_IP3DSV1',
+                   '_MV2c10',
+                 ]
+
+categories_with_subcategories_type_4 = ['jet']
+
+sub_categories_type_4 = [ 'jet']
+
+TProfiles_name = 'TProfiles_do_not_use'
+sub_categories_TProfiles = ['IP3D',
+                   'SV1',
+                   'JetFitter',
+                   'DL1',
+                   'DL1r',
+                   'IP2D',
+                   'IP3DSV1',
+                   'MV2c10',
+                 ]
+
+# define the jet containers
+jetcontainers = ['AntiKt2PV0TrackJets',
+                 'AntiKt4PV0TrackJets',
+                 'AntiKt4EMTopoJets',
+                 'AntiKt4EMPFlowJets',
+                 'AntiKtVR30Rmax4Rmin02TrackJets'
+                 ]
+
+# parser arguments
+parser = argparse.ArgumentParser(description='Merge specific folder(s) in root files.')
+parser.add_argument("-i", "--input", help="path to the folder holding the samples (default: ./)", default=os.getcwd())
+parser.add_argument("-o", "--output", help="path for the output (default: ./merge.root", default=os.getcwd()+"/merge.root")
+parser.add_argument("-d", "--dir", nargs='+', help="ROOT directory to be merged, multiple arguments are possible (default: Summary)", default=["Summary"])
+parser.add_argument("-p", "--pattern", help='pattern of files to merge (default: "*PHYSVAL*")', default="*PHYSVAL*")
+args = parser.parse_args()
+folder = os.path.abspath(args.input)
+mergeDirs = args.dir
+origDir = os.getcwd()
+out = args.output
+pattern = args.pattern
+output_file = os.path.abspath(args.output)
+os.chdir(folder)
+
+files = glob.glob(folder + "/" + pattern)
+
+# open the output file
+f = ROOT.TFile(output_file, "recreate")
+folder = os.getcwd()
+f2 = ROOT.TFile(files[0])
+
+# check input files
+print("Target file: " + output_file)
+for infile in files:
+    print("Found input file: " + infile)
+    if os.path.samefile(output_file, infile):
+        print("Please make sure that the output file is not part of the input files! Stopping.")
+        quit()
+
+
+# -- define a method to merge --
+
+errors = []
+tagfolders = {}
+
+def mergeFolder(path):
+    # check input
+    print("Merging folder " + path)
+    d = f2.Get(path)
+    if not d:
+        error = "ERROR: Cannot find directory " + path + ". Omitting."
+        print(error)
+        errors.append(error)
+        return
+    dirlist = d.GetListOfKeys()
+    
+    # create folders
+    for jetcont in jetcontainers:
+        if jetcont in path:
+            currentdir = gDirectory.GetPath()
+            gDirectory.cd(path)
+            # create /restCategory
+            print("Create directory " + path + "/other_histograms/histos")
+            tagfolders[path+"/"+restCategory] = f.mkdir(path+"/other_histograms/histos")
+            # create /TProfiles
+            print("Create directory " + path + "/"+TProfiles_name)
+            tagfolders[path+"/"+TProfiles_name] = f.mkdir(path+"/"+TProfiles_name)
+            for sub_category in sub_categories_TProfiles:
+                tagfolders[path+"/"+TProfiles_name+"/"+sub_category] = f.mkdir(path+"/"+TProfiles_name+"/"+sub_category)
+            tagfolders[path+"/"+TProfiles_name+"/"+restCategory] = f.mkdir(path+"/"+TProfiles_name+"/"+restCategory)
+            # create category folders
+            for category in categories:
+                print("Create directory " + path + "/" + category)
+                tagfolders[path+"/"+category] = f.mkdir(path+"/"+category)
+                if category in categories_with_subcategories_type_1:
+                    for sub_category in sub_categories_type_1:
+                        tagfolders[path+"/"+category+"/"+sub_category] = f.mkdir(path+"/"+category+"/"+sub_category)
+                elif category in categories_with_subcategories_type_2:
+                    for sub_category in sub_categories_type_2:
+                        tagfolders[path+"/"+category+"/"+sub_category] = f.mkdir(path+"/"+category+"/"+sub_category)
+                elif category in categories_with_subcategories_type_3:
+                    for sub_category in sub_categories_type_3:
+                        tagfolders[path+"/"+category+"/"+sub_category] = f.mkdir(path+"/"+category+"/"+sub_category)
+                elif category in categories_with_subcategories_type_4:
+                    for sub_category in sub_categories_type_4:
+                        tagfolders[path+"/"+category+"/"+sub_category] = f.mkdir(path+"/"+category+"/"+sub_category)
+                tagfolders[path+"/"+category+"/"+restCategory] = f.mkdir(path+"/"+category+"/"+restCategory)
+            gDirectory.cd(currentdir)
+
+    for subdir in dirlist:
+        obj = subdir.ReadObj()
+
+        if obj.IsA().InheritsFrom(ROOT.TH1.Class()):
+            print("Now merging "+obj.GetName())
+            h1 = obj
+            hpath = d.GetPath()
+            hname = hpath[hpath.find(":")+2:]+"/"+obj.GetName()
+            print("Path: "+hname)
+                        
+            for tup in files:
+                if tup==files[0]: continue
+                nextfile = ROOT.TFile(tup)
+                h2 = nextfile.Get(hname)
+                if not h2:
+                    error = "ERROR: Cannot find " + hname + " in file " + tup + ". Omitting."
+                    print(error)
+                    errors.append(error)
+                    continue
+                h1.Add(h2)
+            if tagfolders:
+                for category in reversed(categories):
+                    # check for TProfiles first
+                    if not (obj.GetName()).startswith("BTag_"):
+                        subfolder = f.Get(hpath[hpath.find(":")+2:]+"/"+TProfiles_name)
+                        subfolder.cd()
+                        should_be_in_a_subcategory = True
+                        is_in_subcategory = False
+                        for sub_category in reversed(sub_categories_TProfiles):
+                            if(sub_category in obj.GetName()):
+                                is_in_subcategory = True
+                                subsubfolder = f.Get(hpath[hpath.find(":")+2:]+"/"+TProfiles_name+"/"+sub_category)
+                                subsubfolder.cd()
+                                break
+                        if should_be_in_a_subcategory and not is_in_subcategory:
+                            rest_subsubfolder = f.Get(hpath[hpath.find(":")+2:]+"/"+TProfiles_name+"/"+restCategory)
+                            rest_subsubfolder.cd()
+                        break
+                    # then for the categories
+                    elif ("_"+category+"_") in obj.GetName(): 
+                        print("Category: " + category)
+                        subfolder = f.Get(hpath[hpath.find(":")+2:]+"/"+category)
+                        subfolder.cd()
+                        # apply the sub-categories here
+                        should_be_in_a_subcategory = False
+                        is_in_subcategory = False
+                        if category in categories_with_subcategories_type_1:
+                            should_be_in_a_subcategory = True
+                            for sub_category in reversed(sub_categories_type_1):
+                                if(sub_category in obj.GetName()):
+                                    is_in_subcategory = True
+                                    subsubfolder = f.Get(hpath[hpath.find(":")+2:]+"/"+category+"/"+sub_category)
+                                    subsubfolder.cd()
+                                    break
+                        elif category in categories_with_subcategories_type_2:
+                            should_be_in_a_subcategory = True
+                            for sub_category in reversed(sub_categories_type_2):
+                                if(sub_category in obj.GetName()):
+                                    is_in_subcategory = True
+                                    subsubfolder = f.Get(hpath[hpath.find(":")+2:]+"/"+category+"/"+sub_category)
+                                    subsubfolder.cd()
+                                    break
+                        elif category in categories_with_subcategories_type_3:
+                            should_be_in_a_subcategory = True
+                            for sub_category in reversed(sub_categories_type_3):
+                                if(sub_category in obj.GetName()):
+                                    is_in_subcategory = True
+                                    subsubfolder = f.Get(hpath[hpath.find(":")+2:]+"/"+category+"/"+sub_category)
+                                    subsubfolder.cd()
+                                    break
+                        elif category in categories_with_subcategories_type_4:
+                            should_be_in_a_subcategory = True
+                            for sub_category in reversed(sub_categories_type_4):
+                                if(sub_category in obj.GetName()):
+                                    is_in_subcategory = True
+                                    subsubfolder = f.Get(hpath[hpath.find(":")+2:]+"/"+category+"/"+sub_category)
+                                    subsubfolder.cd()
+                                    break
+                        if should_be_in_a_subcategory and not is_in_subcategory:
+                            rest_subsubfolder = f.Get(hpath[hpath.find(":")+2:]+"/"+category+"/"+restCategory)
+                            rest_subsubfolder.cd()
+
+                        break
+                    # the rest goes into the restCategory
+                    else:
+                        subfolder = f.Get(hpath[hpath.find(":")+2:]+"/other_histograms/histos")
+                        subfolder.cd()
+
+            print(gDirectory.GetPath())
+            h1.Write()
+                            
+        if obj.IsA().InheritsFrom(ROOT.TDirectory.Class()):
+            print("Found subdirectory "+obj.GetName())
+            hpath = obj.GetPath()
+            subfolder = f.mkdir(hpath[hpath.find(":")+2:],obj.GetTitle())
+            print("Created new output directory " + hpath[hpath.find(":")+2:])
+            subfolder.cd()
+            mergeFolder(hpath[hpath.find(":")+2:])
+
+
+# merge the folders
+for mergeDir in mergeDirs:
+    newfolder = f.mkdir(mergeDir,mergeDir)
+    ROOT.TH1.AddDirectory(False)
+    mergeFolder(mergeDir)
+
+# close file and report
+f.Close()
+if len(errors)>0:
+    print("Summary of all errors:")
+    for phrase in errors:
+        print(phrase)
+
+end = time.clock()
+print("Wall time used: %s sec" % (end - start))
diff --git a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/rename_histos_in_files_from_old_code.py b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/rename_histos_in_files_from_old_code.py
new file mode 100644
index 0000000000000000000000000000000000000000..3239426144df35627938a116918749d9adc32044
--- /dev/null
+++ b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/rename_histos_in_files_from_old_code.py
@@ -0,0 +1,378 @@
+###
+# Copyright (C) 2021 CERN for the benefit of the ATLAS collaboration
+#
+# stand-alone script to rename histograms in FTag NTUP_PHYSVAL files produced before ~ April 2021 to the new scheme
+# author: judith.hoefer@cern.ch
+# Mar 2021
+###
+
+from __future__ import print_function
+import os
+import ROOT
+
+# run this on the unmerged files
+
+# input_file_name = 'NTUP_PHYSVAL_compare_to_standard.root'
+# input_file_name = '/afs/cern.ch/user/j/juhofer/WORK/validation/data/run_standard/NTUP_PHYSVAL_standard.root'
+input_file_name = '/afs/cern.ch/user/j/juhofer/WORK/validation/data/QSP_on/valid1.410000.PowhegPythiaEvtGen_P2012_ttbar_hdamp172p5_nonallhad.merge.NTUP_PHYSVAL.e4993_s3641_r12287_p4360_p3821_tid24086162_00/NTUP_PHYSVAL.24086162._000001.pool.root.1'
+
+
+production_process = 'ttbar'
+
+verbose = False
+
+jet_collections = [ 'AntiKt2PV0TrackJets',
+                    'AntiKt4EMPFlowJets',
+                    'AntiKt4EMTopoJets',
+                    'AntiKt4PV0TrackJets',
+                    'AntiKtVR30Rmax4Rmin02TrackJets']
+
+## don't change here
+
+if production_process not in ['ttbar', 'Zprime']:
+  print("Typo in the given production process: ", production_process, ". Exiting.")
+  exit()
+
+var_name_list = [
+'IP3D_b_matched_weight ',
+'IP3D_b_matched_weight_trackCuts ',
+'IP3D_b_50_matched_pt ',
+'IP3D_b_70_matched_pt ',
+'IP3D_b_80_matched_pt ',
+'IP3D_c_matched_weight ',
+'IP3D_c_matched_weight_trackCuts ',
+'IP3D_c_50_matched_pt ',
+'IP3D_c_70_matched_pt ',
+'IP3D_c_80_matched_pt ',
+'IP3D_tau_matched_weight ',
+'IP3D_tau_matched_weight_trackCuts ',
+'IP3D_tau_50_matched_pt ',
+'IP3D_tau_70_matched_pt ',
+'IP3D_tau_80_matched_pt ',
+'IP3D_u_matched_weight ',
+'IP3D_u_matched_weight_trackCuts ',
+'IP3D_u_50_matched_pt ',
+'IP3D_u_70_matched_pt ',
+'IP3D_u_80_matched_pt ',
+'IP2D_b_matched_weight ',
+'IP2D_b_matched_weight_trackCuts ',
+'IP2D_b_50_matched_pt ',
+'IP2D_b_70_matched_pt ',
+'IP2D_b_80_matched_pt ',
+'IP2D_c_matched_weight ',
+'IP2D_c_matched_weight_trackCuts ',
+'IP2D_c_50_matched_pt ',
+'IP2D_c_70_matched_pt ',
+'IP2D_c_80_matched_pt ',
+'IP2D_tau_matched_weight ',
+'IP2D_tau_matched_weight_trackCuts ',
+'IP2D_tau_50_matched_pt ',
+'IP2D_tau_70_matched_pt ',
+'IP2D_tau_80_matched_pt ',
+'IP2D_u_matched_weight ',
+'IP2D_u_matched_weight_trackCuts ',
+'IP2D_u_50_matched_pt ',
+'IP2D_u_70_matched_pt ',
+'IP2D_u_80_matched_pt ',
+'SV1_b_matched_weight ',
+'SV1_b_matched_weight_trackCuts ',
+'SV1_b_40_matched_pt ',
+'SV1_b_50_matched_pt ',
+'SV1_b_60_matched_pt ',
+'SV1_c_matched_weight ',
+'SV1_c_matched_weight_trackCuts ',
+'SV1_c_40_matched_pt ',
+'SV1_c_50_matched_pt ',
+'SV1_c_60_matched_pt ',
+'SV1_tau_matched_weight ',
+'SV1_tau_matched_weight_trackCuts ',
+'SV1_tau_40_matched_pt ',
+'SV1_tau_50_matched_pt ',
+'SV1_tau_60_matched_pt ',
+'SV1_u_matched_weight ',
+'SV1_u_matched_weight_trackCuts ',
+'SV1_u_40_matched_pt ',
+'SV1_u_50_matched_pt ',
+'SV1_u_60_matched_pt ',
+'IP3DSV1_b_matched_weight ',
+'IP3DSV1_b_matched_weight_trackCuts ',
+'IP3DSV1_b_50_matched_pt ',
+'IP3DSV1_b_70_matched_pt ',
+'IP3DSV1_b_80_matched_pt ',
+'IP3DSV1_c_matched_weight ',
+'IP3DSV1_c_matched_weight_trackCuts ',
+'IP3DSV1_c_50_matched_pt ',
+'IP3DSV1_c_70_matched_pt ',
+'IP3DSV1_c_80_matched_pt ',
+'IP3DSV1_tau_matched_weight ',
+'IP3DSV1_tau_matched_weight_trackCuts ',
+'IP3DSV1_tau_50_matched_pt ',
+'IP3DSV1_tau_70_matched_pt ',
+'IP3DSV1_tau_80_matched_pt ',
+'IP3DSV1_u_matched_weight ',
+'IP3DSV1_u_matched_weight_trackCuts ',
+'IP3DSV1_u_50_matched_pt ',
+'IP3DSV1_u_70_matched_pt ',
+'IP3DSV1_u_80_matched_pt ',
+'JetFitter_b_matched_weight ',
+'JetFitter_b_matched_weight_trackCuts ',
+'JetFitter_b_50_matched_pt ',
+'JetFitter_b_70_matched_pt ',
+'JetFitter_b_80_matched_pt ',
+'JetFitter_c_matched_weight ',
+'JetFitter_c_matched_weight_trackCuts ',
+'JetFitter_c_50_matched_pt ',
+'JetFitter_c_70_matched_pt ',
+'JetFitter_c_80_matched_pt ',
+'JetFitter_tau_matched_weight ',
+'JetFitter_tau_matched_weight_trackCuts ',
+'JetFitter_tau_50_matched_pt ',
+'JetFitter_tau_70_matched_pt ',
+'JetFitter_tau_80_matched_pt ',
+'JetFitter_u_matched_weight ',
+'JetFitter_u_matched_weight_trackCuts ',
+'JetFitter_u_50_matched_pt ',
+'JetFitter_u_70_matched_pt ',
+'JetFitter_u_80_matched_pt ',
+'MV2c10_b_matched_weight ',
+'MV2c10_b_matched_weight_trackCuts ',
+'MV2c10_c_matched_weight ',
+'MV2c10_c_matched_weight_trackCuts ',
+'MV2c10_tau_matched_weight ',
+'MV2c10_tau_matched_weight_trackCuts ',
+'MV2c10_u_matched_weight ',
+'MV2c10_u_matched_weight_trackCuts ',
+'MV2c10mu_b_matched_weight ',
+'MV2c10mu_b_matched_weight_trackCuts ',
+'MV2c10mu_c_matched_weight ',
+'MV2c10mu_c_matched_weight_trackCuts ',
+'MV2c10mu_tau_matched_weight ',
+'MV2c10mu_tau_matched_weight_trackCuts ',
+'MV2c10mu_u_matched_weight ',
+'MV2c10mu_u_matched_weight_trackCuts ',
+'MV2c10rnn_b_matched_weight ',
+'MV2c10rnn_b_matched_weight_trackCuts ',
+'MV2c10rnn_c_matched_weight ',
+'MV2c10rnn_c_matched_weight_trackCuts ',
+'MV2c10rnn_tau_matched_weight ',
+'MV2c10rnn_tau_matched_weight_trackCuts ',
+'MV2c10rnn_u_matched_weight ',
+'MV2c10rnn_u_matched_weight_trackCuts ',
+'truthLabel ',
+'TruthBpt ',
+'TruthLpt ',
+'TruthCpt ',
+'TruthTauPt ',
+'IP3Dpb ',
+'IP3Dpc ',
+'IP3Dpu ',
+'SV1pb ',
+'SV1pc ',
+'SV1pu ',
+'NTracksIP3D ',
+'NTracksIP2D ',
+'NGTinSvx1 ',
+'NGTinSvx0 ',
+'e ',
+'pt ',
+'eta ',
+'phi ',
+'d0 ',
+'z0 ',
+'IP3DgradeOfTracks ',
+'IP2DgradeOfTracks ',
+'IP3D_valD0wrtPVofTracks ',
+'IP3D_valZ0wrtPVofTracks ',
+'IP3D_sigD0wrtPVofTracks ',
+'IP3D_sigZ0wrtPVofTracks ',
+'IP3D_weightBofTracks ',
+'IP3D_weightUofTracks ',
+'IP2D_weightBofTracks ',
+'IP2D_weightUofTracks '
+]
+
+def get_name_associations(list):
+
+  taggers = ["_IP3D_", "_SV1_", "_JetFitter_"]
+  old_taggers = ["_IP2D_", "_IP3DSV1_", "_MV2c10_", "_MV2c10mu_", "_MV2c10rnn_"]
+  oneToOne_associations = {
+    '_truthLabel ': '_jet_truthLabel ',
+    '_IP3Dpb ': '_tagger_IP3D_pb ',
+    '_IP3Dpc ': '_tagger_IP3D_pc ',
+    '_IP3Dpu ': '_tagger_IP3D_pu ',
+    '_SV1pb ': '_tagger_SV1_pb ',
+    '_SV1pc ': '_tagger_SV1_pc ',
+    '_SV1pu ': '_tagger_SV1_pu ',
+    '_NTracksIP3D ': '_tagger_IP3D_NTracks_incl ',
+    '_NTracksIP2D ': '_old_taggers_IP2D_NTracks_incl ',
+    '_NGTinSvx1 ': '_tagger_SV1_nGoodTracks_incl ',
+    '_eta ': '_jet_jet_eta ',
+    '_phi ': '_jet_jet_phi ',
+    '_d0 ': '_tracks_d0_b ',
+    '_z0 ': '_tracks_z0_b ',
+    '_IP3DgradeOfTracks ': '_tagger_IP3D_gradeOfTracks_incl ',
+    '_IP2DgradeOfTracks ': '_old_taggers_IP2D_gradeOfTracks_incl ',
+  }  
+  oneToOne_associations_ttbar = {
+    '_TruthBpt ': '_jet_jet_pt_b_ttbar ',
+    '_TruthLpt ': '_jet_jet_pt_l_ttbar ',
+    '_TruthCpt ': '_jet_jet_pt_c_ttbar ',
+    '_e ': '_jet_jet_e ',
+    '_pt ': '_jet_jet_pt_ttbar ',
+  }
+  oneToOne_associations_Zprime = {
+    '_TruthBpt ': '_jet_jet_pt_b_Zprime ',
+    '_TruthLpt ': '_jet_jet_pt_l_Zprime ',
+    '_TruthCpt ': '_jet_jet_pt_c_Zprime ',
+    '_e ': '_jet_jet_e_Zprime ',
+    '_pt ': '_jet_jet_pt_Zprime ',
+  }
+  
+  name_associations = {}
+  
+  for name in list:
+    new_name = name
+  
+    for tag in taggers:
+      if tag in new_name:
+        new_name = new_name.replace(tag, "_tagger" + tag)
+    
+    for tag in old_taggers:
+      if tag in new_name:
+        new_name = new_name.replace(tag, "_old_taggers" + tag)
+  
+    if "_matched_pt" in new_name:
+      new_name = new_name.replace("_matched_pt", "_matched_pt_" + production_process)
+
+    if "AntiKt4EMPFlowJets" in new_name:
+      new_name = new_name.replace("AntiKt4EMPFlowJets", "AntiKt4EMPFlowJets_")
+
+    if "AntiKtVR30Rmax4Rmin02TrackJets" in new_name:
+      new_name = new_name.replace("AntiKtVR30Rmax4Rmin02TrackJets", "AntiKtVR30Rmax4Rmin02TrackJets_")
+
+    for key in oneToOne_associations:
+      if key in new_name:
+        new_name = new_name.replace(key, oneToOne_associations[key])
+
+    if production_process == 'ttbar':
+      for key in oneToOne_associations_ttbar:
+        if key in new_name:
+          new_name = new_name.replace(key, oneToOne_associations_ttbar[key])
+
+    if production_process == 'Zprime':
+      for key in oneToOne_associations_Zprime:
+        if key in new_name:
+          new_name = new_name.replace(key, oneToOne_associations_Zprime[key])
+
+    # if new_name not in new_list and "tau" not in new_name and "Tau" not in new_name and not "_NGTinSvx0" in new_name:
+    #   print(new_name)
+
+    # remove spaces
+    name = name.replace(" ", "")
+    new_name = new_name.replace(" ", "")
+    
+    # fill the dict
+    name_associations[name] = new_name
+
+  return name_associations
+  
+
+
+# get the name_list for all jet collections
+name_list = []
+for jet_col in jet_collections:
+  for var_name in var_name_list:
+    if jet_col == "AntiKt4EMPFlowJets" or jet_col == "AntiKtVR30Rmax4Rmin02TrackJets":
+      name_list.append("BTag_" + jet_col + var_name)
+    else:
+      name_list.append("BTag_" + jet_col + "_" + var_name)
+
+# get the name associations
+name_associations = get_name_associations(name_list)
+if verbose:
+  print(name_associations)
+
+# prepare the output file
+if input_file_name.endswith('.root'):
+  output_file_name = input_file_name[:-5] + '_renamed.root' 
+elif input_file_name.endswith('.pool.root.1'):
+  output_file_name = input_file_name[:-12] + '_renamed.pool.root.1' 
+else:
+  print("Input file ending is not .root and not .pool.root.1, I can't handle the conversion to an output name.")
+  exit()
+
+output_file = ROOT.TFile(output_file_name, 'RECREATE')
+
+# make the subdirectories
+output_file.mkdir("BTag")
+for jet_col in jet_collections:
+  path = "BTag/" + jet_col + "/"
+  output_file.mkdir(path)
+
+# close the file
+output_file.Close()
+
+# loop over all the jet collections
+for jet_col in jet_collections:
+
+  # open the input file
+  input_file = ROOT.TFile(input_file_name, 'READ')
+
+  if input_file.IsOpen(): #and output_file.IsOpen():
+
+    # go into the directory
+    path = "BTag;1/" + jet_col + ";1/"
+    ROOT.gDirectory.cd(path)
+
+    if verbose:
+      print("\njust cd'ed into: " + path)
+      print("\nls")
+      input_file.ls()
+      
+    # get the subdirectories here
+    currentdir = ROOT.gDirectory.GetPath()
+    dirlist = input_file.Get(currentdir).GetListOfKeys()
+
+    if verbose:
+      print("\ndirlist\n", dirlist)
+
+    histograms = []
+
+    # loop over the objects in here 
+    for subdir in dirlist:
+      obj = subdir.ReadObj()
+
+      # and see if they are histograms and ignore TProfiles
+      if obj.IsA().InheritsFrom(ROOT.TH1.Class()) and jet_col in obj.GetName():
+
+        if verbose:
+          print("\nobj: ", obj)
+          print("'", obj.GetName(), "'," )
+
+        # check if the name is on the list
+        if obj.GetName() not in name_associations:
+          print("This name is not defined!!!", obj.GetName())
+          exit()
+
+        # rename the histo and fill the list with histograms
+        new_histo = obj
+        new_histo.SetName(name_associations[obj.GetName()])
+        histograms.append(new_histo)
+
+    # now open the output file and got to the right dir
+    output_file = ROOT.TFile(output_file_name, 'UPDATE')
+
+    if output_file.IsOpen():
+
+      ROOT.gDirectory.cd(path)
+
+      # loop over the histos
+      for histo in histograms:
+        histo.Write()
+
+      output_file.Close()
+
+    input_file.Close()
+
+
+print("\n the output was written to:\n  ", output_file_name)
\ No newline at end of file
diff --git a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/BTaggingValidationPlots.cxx b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/BTaggingValidationPlots.cxx
index d16705fde6da008ca3736f7a0463d620dddcc220..c8527b6399b0887efc5ae6ada5dfe7af15ef09a2 100644
--- a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/BTaggingValidationPlots.cxx
+++ b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/BTaggingValidationPlots.cxx
@@ -1,656 +1,2059 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "BTaggingValidationPlots.h"
 #include "ParticleJetTools/JetFlavourInfo.h"
 #include "xAODBTagging/BTaggingUtilities.h" 
+#include "xAODBTagging/ftagfloat_t.h"
 using CLHEP::GeV;
+#include <stdexcept>
 
 namespace JetTagDQA{
+  BTaggingValidationPlots::BTaggingValidationPlots(PlotBase* pParent, 
+                                                   std::string sDir, 
+                                                   std::string sParticleType) :
+                                                   PlotBase(pParent, sDir),
+                                                   m_sParticleType(sParticleType),
+                                                   m_JVT_defined(false),
+                                                   m_JVTLargerEta_defined(false)
+  {
+    //std::cout << "m_sParticleType=" << m_sParticleType << std::endl;
+  }     
+  
+  void BTaggingValidationPlots::setDetailLevel(const unsigned int& detailLevel){
+    m_detailLevel = detailLevel;
+  }
 
-	BTaggingValidationPlots::BTaggingValidationPlots(PlotBase* pParent, std::string sDir, std::string sParticleType):PlotBase(pParent, sDir),
-															 m_sParticleType(sParticleType),m_isJVT_defined(false)
-	{
-	  //std::cout << "m_sParticleType=" << m_sParticleType << std::endl;
-	  if (m_sParticleType=="antiKt4EMTopoJets") { m_isJVT_defined = true; m_jvt_cut = 0.59;};
-	  if (m_sParticleType=="antiKt4EMPFlowJets") {m_isJVT_defined = true; m_jvt_cut = 0.2;};
-	}     
-	 
-	void BTaggingValidationPlots::initializePlots(){
-
-		bookEffHistos();		
-
-		m_truthLabel = Book1D("truthLabel", "truthLabel of "+ m_sParticleType +"; truthLabel ;Events", 17, -1., 16);
-//		m_GAFinalHadronLabel = Book1D("GAFinalHadronLabel", "GAFinalHadronLabel of "+ m_sParticleType +"; GAFinalHadronLabel ;Events", 17, -1., 16);
-//		m_GAInitialHadronLabel = Book1D("GAInitialHadronLabel", "GAInitialHadronLabel of "+ m_sParticleType +"; GAInitialHadronLabel ;Events", 17, -1., 16);
-//		m_GAFinalPartonLabel = Book1D("GAFinalPartonLabel", "GAFinalPartonLabel of "+ m_sParticleType +"; GAFinalPartonLabel ;Events", 17, -1., 16);
-
-//		m_GAFinalHadronC_dR = Book1D("GAFinalHadronC_dR", "DeltaR between final hadron C and "+ m_sParticleType +"; dR ;Events", 50, 0, 1);
-//		m_GAInitialHadronC_dR = Book1D("GAInitialHadronC_dR", "DeltaR between initial hadron C and "+ m_sParticleType +"; dR ;Events", 50, 0, 1);
-//		m_GAFinalPartonC_dR = Book1D("GAFinalPartonC_dR", "DeltaR between final parton C and "+ m_sParticleType +"; dR ;Events", 50, 0, 1);
-//		m_GAFinalHadronTau_dR = Book1D("GAFinalHadronTau_dR", "DeltaR between final hadron tau and "+ m_sParticleType +"; dR ;Events", 50, 0, 1);
-
-		m_truthPt_b  = Book1D("TruthBpt", "p_{T} of truth"+ m_sParticleType +"; p_{T} (GeV) ;Events", 100, 0., 1000);
-		m_truthPt_u  = Book1D("TruthLpt", "p_{T} of truth"+ m_sParticleType +", light jets; p_{T} (GeV) ;Events", 100, 0., 1000);
-		m_truthPt_c  = Book1D("TruthCpt", "p_{T} of truth"+ m_sParticleType +", c-jets; p_{T} (GeV) ;Events", 100, 0., 1000);
-		m_truthPt_tau  = Book1D("TruthTauPt", "p_{T} of truth"+ m_sParticleType +", tau-jets; p_{T} (GeV) ;Events", 100, 0., 1000);
-
-		m_IP3D_pb = Book1D("IP3Dpb", "IP3D pb of "+ m_sParticleType +"; IP3Dpb ;Events", 100, 0., 1.);
-		m_IP3D_pc = Book1D("IP3Dpc", "IP3D pc of "+ m_sParticleType +"; IP3Dpc ;Events", 100, 0., 1.);
-		m_IP3D_pu = Book1D("IP3Dpu", "IP3D pu of "+ m_sParticleType +"; IP3Dpu ;Events", 100, 0., 1.);
-
-		m_SV1_pb = Book1D("SV1pb", "SV1 pb of "+ m_sParticleType +"; SV1pb ;Events", 100, 0., 1.);
-		m_SV1_pc = Book1D("SV1pc", "SV1 pc of "+ m_sParticleType +"; SV1pc ;Events", 100, 0., 1.);
-		m_SV1_pu = Book1D("SV1pu", "SV1 pu of "+ m_sParticleType +"; SV1pu ;Events", 100, 0., 1.);
-		
-		m_IP3D_nTracks = Book1D("NTracksIP3D", "number of IP3D tracks of "+ m_sParticleType +"; NTracks ;Events", 21, -1., 20.);
-		m_IP2D_nTracks = Book1D("NTracksIP2D", "number of IP2D tracks of "+ m_sParticleType +"; NTracks ;Events", 21, -1., 20.);
-		m_SV1_NGTinSvx = Book1D("NGTinSvx1", "number of good tracks in secondary vertex (SV1); NTracks ;Events", 21, -1., 20.);
-		m_SV0_NGTinSvx = Book1D("NGTinSvx0", "number of good tracks in secondary vertex (SV0); NTracks ;Events", 21, -1., 20.);		
-
-		m_e  = Book1D("e", "E of "+ m_sParticleType +"; E (GeV) ;Events", 100, 0., 1000);
-		m_pt  = Book1D("pt", "p_{T} of "+ m_sParticleType +"; p_{T} (GeV) ;Events", 100, 0., 1000);
-		m_eta = Book1D("eta", "#eta of " + m_sParticleType +";#eta; Events ", 200,-5,5.);
-		m_phi = Book1D("phi", "#varphi of " + m_sParticleType +";#varphi;Events ",128 ,-3.2,3.2);
-
-		//ANDREA --- Store tracking info
-		m_track_d0       = Book1D("d0", "d_{0} of BTagTrackToJetAssociator -> "+ m_sParticleType +"; d_{0} (mm) ;Events", 200, -2, 2);
-		m_track_z0       = Book1D("z0", "z_{0} of BTagTrackToJetAssociator -> "+ m_sParticleType +"; z_{0} (mm) ;Events", 200, -10, 10); 
-		//m_track_sigd0	 = Book1D("d0Sig", "d_{0} Significance of BTagTrackToJetAssociator -> "+ m_sParticleType +"; d_{0} / #sigma_{d_{0}} ;Events", 60, -3, 3);
-		//m_track_sigz0    = Book1D("z0Sig", "z_{0} Significance of BTagTrackToJetAssociator -> "+ m_sParticleType +"; z_{0} / #sigma_{z_{0}} ;Events", 100, -5, 5);
-
-		//ANDREA --- Store IPTag track grading/category
-		m_IP3D_trackGrading = Book1D("IP3DgradeOfTracks","IP3D grade of Tracks "+m_sParticleType    +"; IP3D grade of Tracks ;Events"  ,12,-0.5,11.5);
-		m_IP2D_trackGrading = Book1D("IP2DgradeOfTracks","IP2D grade of Tracks "+m_sParticleType    +"; IP2D grade of Tracks ;Events"  ,12,-0.5,11.5);
-		m_tmpD0 = Book1D("IP3D_valD0wrtPVofTracks","IP3D valD0 wrt PV of Tracks "+m_sParticleType   +"; IP3D valD0 wrt PV of Tracks ;Events"  ,200,-2,2);
-		m_tmpZ0 = Book1D("IP3D_valZ0wrtPVofTracks","IP3D valZ0 wrt PV of Tracks "+m_sParticleType   +"; IP3D valZ0 wrt PV of Tracks ;Events"  ,100,-0.5,0.5);
-		m_tmpD0sig = Book1D("IP3D_sigD0wrtPVofTracks","IP3D sigD0 wrt PV of Tracks "+m_sParticleType+"; IP3D sigD0 wrt PV of Tracks ;Events"  ,200,-2,2);
-		m_tmpZ0sig = Book1D("IP3D_sigZ0wrtPVofTracks","IP3D sigZ0 wrt PV of Tracks "+m_sParticleType+"; IP3D sigZ0 wrt PV of Tracks ;Events"  ,200,-2,2);
-		m_tmpIP3DBwgt = Book1D("IP3D_weightBofTracks","IP3D weight B of Tracks"+m_sParticleType	    +"; IP3D weight B of Tracks ;Events"  ,200,-2,2);
-		m_tmpIP3DUwgt = Book1D("IP3D_weightUofTracks","IP3D weight U of Tracks"+m_sParticleType	    +"; IP3D weight U of Tracks ;Events"  ,200,-2,2);
-		m_tmpIP2DBwgt = Book1D("IP2D_weightBofTracks","IP2D weight B of Tracks"+m_sParticleType	    +"; IP2D weight B of Tracks ;Events"  ,200,-2,2);
-		m_tmpIP2DUwgt = Book1D("IP2D_weightUofTracks","IP2D weight U of Tracks"+m_sParticleType	    +"; IP2D weight U of Tracks ;Events"  ,200,-2,2);	
-
-	}
-	
-	void BTaggingValidationPlots::fill(const xAOD::BTagging* btag){
-		int nIP3DTracks, nGTinSvx1, nIP2DTracks, nGTinSvx0;
-		try{
-			nIP3DTracks = btag->nIP3D_TrackParticles(); 
-		}
-		catch(std::exception& exception){
-                        nIP3DTracks = -1;
-                }
-		m_IP3D_nTracks->Fill(nIP3DTracks);
-		try{
-			nIP2DTracks = btag->nIP2D_TrackParticles(); 
-		}
-		catch(std::exception& exception){
-                        nIP2DTracks = -1;
-                }
-		m_IP2D_nTracks->Fill(nIP2DTracks);
-		try{
-			btag->taggerInfo(nGTinSvx1, xAOD::SV1_NGTinSvx); 
-		}
-		catch(std::exception& exception){
-                        nGTinSvx1 = -1;
-                }
-		m_SV1_NGTinSvx->Fill(nGTinSvx1);
-		try{
-			btag->taggerInfo(nGTinSvx0, xAOD::SV0_NGTinSvx); 
-		}
-		catch(std::exception& exception){
-                        nGTinSvx0 = -1;
-                }
-		m_SV0_NGTinSvx->Fill(nGTinSvx0);
-
-		m_IP3D_pb->Fill(btag->IP3D_pb());
-		m_IP3D_pc->Fill(btag->IP3D_pc());
-		m_IP3D_pu->Fill(btag->IP3D_pu());
-		m_SV1_pb->Fill(btag->SV1_pb());
-		m_SV1_pc->Fill(btag->SV1_pc());
-		m_SV1_pu->Fill(btag->SV1_pu());
-	}
-
-	void BTaggingValidationPlots::fill(int truthLabel){
-		 m_truthLabel->Fill(truthLabel);
-	}
-
-	void BTaggingValidationPlots::fill(const xAOD::Jet* jet){
-		m_e->Fill(jet->e()/GeV);
-		m_pt->Fill(jet->pt()/GeV);
-		m_eta->Fill(jet->eta());
-		m_phi->Fill(jet->phi());
-//		m_GAFinalHadronLabel->Fill(xAOD::GAFinalHadronFlavourLabel(jet));	
-//		m_GAInitialHadronLabel->Fill(xAOD::GAInitialHadronFlavourLabel(jet));	
-//		m_GAFinalPartonLabel->Fill(xAOD::GAFinalPartonFlavourLabel(jet));	
-//		m_GAFinalHadronC_dR->Fill(xAOD::deltaR(jet, "GhostCHadronsFinal"));
-//		m_GAInitialHadronC_dR->Fill(xAOD::deltaR(jet, "GhostCHadronsInitial"));
-//		m_GAFinalPartonC_dR->Fill(xAOD::deltaR(jet, "GhostCQuarksFinal"));
-//		m_GAFinalHadronTau_dR->Fill(xAOD::deltaR(jet, "GhostTausFinal"));
-	}
-
-	void BTaggingValidationPlots::fill(const xAOD::Jet* jet, const xAOD::BTagging* btag, const xAOD::Vertex *myVertex){
-
-		int label(1000);
-
-		if(jet->isAvailable<int>("HadronConeExclTruthLabelID")) jet->getAttribute("HadronConeExclTruthLabelID", label);
-		else jet->getAttribute("TruthLabelID",label);	
-
- 		//ANDREA --- Store tracking quantities
- 		const xAOD::BTagging* bjet = xAOD::BTaggingUtilities::getBTagging( *jet );
- 		std::vector< ElementLink< xAOD::TrackParticleContainer > > assocTracks = bjet->auxdata<std::vector<ElementLink<xAOD::TrackParticleContainer> > >("BTagTrackToJetAssociator");
-		for (unsigned int iT=0; iT<assocTracks.size(); iT++) {
-      		  if (!assocTracks.at(iT).isValid()) continue;
-      		  const xAOD::TrackParticle* tmpTrk= *(assocTracks.at(iT));	 	
-		  double d0(1000), z0(1000); //, sigma_d0(1000), sigma_z0(1000);				
-		  d0 	         = tmpTrk->d0();
-		  z0 	         = tmpTrk->z0() + tmpTrk->vz() - myVertex->z(); //ANDREA: tmpTrk->z0() is defined wrt the beam spot-> Get it wrt the PV
-		  //z0 	         = tmpTrk->z0(); //Naive z0 wrt the beam spot
-
-		  //ANDREA: for IP significances we already have IP-categories
-		  //sigma_d0         = sqrt(tmpTrk->definingParametersCovMatrixVec().at(0)); 
-		  //sigma_z0         = sqrt(tmpTrk->definingParametersCovMatrixVec().at(2));
-
-		  //std::cout<<"****************** BS z0 = "<< tmpTrk->z0() <<" and PV z0 = "<< z0 <<std::endl;
-		  //std::cout<<"****************** d0 = "<< d0 <<" and sigma_d0 = "<< sigma_d0 <<std::endl;
-		  //if(sigma_d0<=0 || sigma_z0<=0) std::cout<<"********************** IP error = or < 0 !!!"<<std::endl;
-
-		  if(label == 5) {
-		  	m_track_d0     ->Fill(d0);
-	  	  	m_track_z0     ->Fill(z0);
-		  	//m_track_sigd0  ->Fill(d0/sigma_d0);
-		  	//m_track_sigz0  ->Fill(z0/sigma_z0);
-		  }
-		}	
-		//ANDREA --- Store tracking quantities
-
-		//ANDREA --- IPTag categories
-		std::vector<int>      tmpGrading   = bjet->auxdata<std::vector<int> >("IP3D_gradeOfTracks");
-		std::vector<int>      tmpGrading2  = bjet->auxdata<std::vector<int> >("IP2D_gradeOfTracks");
-		int IP3D_trackSize    = tmpGrading .size();
-		int IP2D_trackSize    = tmpGrading2.size();
-		m_IP3D_trackGrading   ->Fill( IP3D_trackSize );
-		m_IP2D_trackGrading   ->Fill( IP2D_trackSize );
-
-		std::vector<float> tmpD0       = bjet->auxdata<std::vector<float> >("IP3D_valD0wrtPVofTracks");
-       	        std::vector<float> tmpZ0       = bjet->auxdata<std::vector<float> >("IP3D_valZ0wrtPVofTracks");
-	        std::vector<float> tmpD0sig    = bjet->auxdata<std::vector<float> >("IP3D_sigD0wrtPVofTracks");
-	        std::vector<float> tmpZ0sig    = bjet->auxdata<std::vector<float> >("IP3D_sigZ0wrtPVofTracks");
-		for( unsigned int i=0; i<tmpD0   .size(); i++) m_tmpD0   ->Fill(tmpD0.at(i));
-		for( unsigned int i=0; i<tmpZ0   .size(); i++) m_tmpZ0   ->Fill(tmpZ0.at(i));
-		for( unsigned int i=0; i<tmpD0sig.size(); i++) m_tmpD0sig->Fill(tmpD0sig.at(i));
-		for( unsigned int i=0; i<tmpZ0sig.size(); i++) m_tmpZ0sig->Fill(tmpZ0sig.at(i));
-	
-	        std::vector<float> tmpIP3DBwgt = bjet->auxdata<std::vector<float> >("IP3D_weightBofTracks");
-	        std::vector<float> tmpIP3DUwgt = bjet->auxdata<std::vector<float> >("IP3D_weightUofTracks");
-	        std::vector<float> tmpIP2DBwgt = bjet->auxdata<std::vector<float> >("IP2D_weightBofTracks");
-	        std::vector<float> tmpIP2DUwgt = bjet->auxdata<std::vector<float> >("IP2D_weightUofTracks");
-
-		for( unsigned int i=0; i<tmpIP3DBwgt   .size(); i++) m_tmpIP3DBwgt  ->Fill(tmpIP3DBwgt.at(i));
-		for( unsigned int i=0; i<tmpIP3DUwgt   .size(); i++) m_tmpIP3DUwgt  ->Fill(tmpIP3DUwgt.at(i));
-		for( unsigned int i=0; i<tmpIP2DBwgt   .size(); i++) m_tmpIP2DBwgt  ->Fill(tmpIP2DBwgt.at(i));
-		for( unsigned int i=0; i<tmpIP2DUwgt   .size(); i++) m_tmpIP2DUwgt  ->Fill(tmpIP2DUwgt.at(i));
-		//ANDREA --- IPTag categories
-
-		int nGTinSvx(1000);
-		int nIP3DTracks(1000);
-		int nGTinSvx0(1000);
-		int nIP2DTracks(1000);
-		try{
-			nIP3DTracks = btag->nIP3D_TrackParticles(); 
-		}
-		catch(std::exception& exception){
-                        nIP3DTracks = -1;
-                }
-		try{
-			nIP2DTracks = btag->nIP2D_TrackParticles(); 
-		}
-		catch(std::exception& exception){
-                        nIP2DTracks = -1;
-                }
-		try{
-			btag->taggerInfo(nGTinSvx, xAOD::SV1_NGTinSvx); 
-		}
-		catch(std::exception& exception){
-                        nGTinSvx = -1;
-                }
-		try{
-			btag->taggerInfo(nGTinSvx0, xAOD::SV0_NGTinSvx); 
-		}
-		catch(std::exception& exception){
-                        nGTinSvx0 = -1;
-                }
-
-                if(jet->pt() > 20000 && std::abs(jet->eta()) < 2.5){
-			//std::cout << "IP3D weight of jet: " << btag->IP3D_loglikelihoodratio() << std::endl;
-                  	if(label == 5) m_truthPt_b->Fill(jet->pt()/GeV);
-                  	if(label == 0) m_truthPt_u->Fill(jet->pt()/GeV);
-                	if(label == 4) m_truthPt_c->Fill(jet->pt()/GeV);
-                	if(label == 15) m_truthPt_tau->Fill(jet->pt()/GeV);
-			for(std::map<std::string, TH1*>::const_iterator hist_iter=m_weight_histos.begin(); hist_iter!=m_weight_histos.end(); ++hist_iter){
-				for(std::map<std::string, int>::const_iterator label_iter = m_truthLabels.begin(); label_iter != 					m_truthLabels.end(); ++label_iter){
-					if((hist_iter->first).find("IP3D_") < 1 && (hist_iter->first).find("_matched") < (hist_iter->first).length()){
-						if( (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length() && label == label_iter->second && (hist_iter->first).find("_weight") < (hist_iter->first).length()){
-							if((hist_iter->first).find("_trackCuts") < (hist_iter->first).length()){
-								if(nIP3DTracks > 0)(hist_iter->second)->Fill(btag->IP3D_loglikelihoodratio());
-							}
-							else (hist_iter->second)->Fill(btag->IP3D_loglikelihoodratio());
-						}
-						else{
-							 for(std::map<std::string, double>::const_iterator ip3d_iter = m_IP3D_workingPoints.begin(); ip3d_iter != m_IP3D_workingPoints.end(); ++ip3d_iter){
-								if((hist_iter->first).find(ip3d_iter->first) < (hist_iter->first).length() && (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length()){
-									if(label == label_iter->second && btag->IP3D_loglikelihoodratio()>ip3d_iter->second){
-										(hist_iter->second)->Fill(jet->pt()/GeV);
-									}
-								}
-							}
-						}	
-					}
-					if((hist_iter->first).find("IP2D_") < 1 && (hist_iter->first).find("_matched") < (hist_iter->first).length()){
-						if( (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length() && label == label_iter->second && (hist_iter->first).find("_weight") < (hist_iter->first).length()){
-							if((hist_iter->first).find("_trackCuts") < (hist_iter->first).length()){
-								if(nIP2DTracks > 0)(hist_iter->second)->Fill(btag->IP2D_loglikelihoodratio());
-							}
-							else (hist_iter->second)->Fill(btag->IP2D_loglikelihoodratio());
-						}
-						else{
-							 for(std::map<std::string, double>::const_iterator ip2d_iter = m_IP2D_workingPoints.begin(); ip2d_iter != m_IP2D_workingPoints.end(); ++ip2d_iter){
-								if((hist_iter->first).find(ip2d_iter->first) < (hist_iter->first).length() && (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length()){
-									if(label == label_iter->second && btag->IP2D_loglikelihoodratio()>ip2d_iter->second){
-										(hist_iter->second)->Fill(jet->pt()/GeV);
-									}
-								}
-							}
-						}	
-					}
-				
-					if((hist_iter->first).find("SV1_") < 1 && (hist_iter->first).find("matched") < (hist_iter->first).length()){
-						if( (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length() && label == label_iter->second && (hist_iter->first).find("_weight") < (hist_iter->first).length()){
-							if((hist_iter->first).find("_trackCuts") < (hist_iter->first).length()){
-								if(nGTinSvx > 0) (hist_iter->second)->Fill(btag->SV1_loglikelihoodratio());
-							}
-							else (hist_iter->second)->Fill(btag->SV1_loglikelihoodratio());
-						}
-						else{
-							for(std::map<std::string, double>::const_iterator sv1_iter = m_SV1_workingPoints.begin(); sv1_iter != 					          	m_SV1_workingPoints.end(); ++sv1_iter){
-								if((hist_iter->first).find(sv1_iter->first) < (hist_iter->first).length() && (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length()){
-									if(label == label_iter->second && btag->SV1_loglikelihoodratio()>sv1_iter->second){
-										(hist_iter->second)->Fill(jet->pt()/GeV);
-									}
-								}
-							}
-						}
-					}
-					if((hist_iter->first).find("SV0_") < 1 && (hist_iter->first).find("matched") < (hist_iter->first).length()){
-					  float normdist=0;
-					  btag->taggerInfo(normdist, xAOD::SV0_normdist);	
-					  if( (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length() && label == label_iter->second && (hist_iter->first).find("_weight") < (hist_iter->first).length()){
-						if((hist_iter->first).find("_trackCuts") < (hist_iter->first).length()){
-								if(nGTinSvx0 > 0) (hist_iter->second)->Fill(normdist);
-						}
-						else (hist_iter->second)->Fill(normdist);
-					  }
-					  else{
-					    for(std::map<std::string, double>::const_iterator sv0_iter = m_SV0_workingPoints.begin(); sv0_iter != m_SV0_workingPoints.end(); ++sv0_iter){
-							  if((hist_iter->first).find(sv0_iter->first) < (hist_iter->first).length() && (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length()){
-							    if(label == label_iter->second && normdist>sv0_iter->second){
-	 									  (hist_iter->second)->Fill(jet->pt()/GeV);
-							    }
-							  }
-					    }
-					  }	
-					}
-					if((hist_iter->first).find("IP3DSV1_") < 1 && (hist_iter->first).find("matched") < (hist_iter->first).length()){						
-						if( (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length() && label == label_iter->second && (hist_iter->first).find("_weight") < (hist_iter->first).length()){
-							if((hist_iter->first).find("_trackCuts") < (hist_iter->first).length()){
-								if(nGTinSvx > 0 && nIP3DTracks > 0) 							(hist_iter->second)->Fill(btag->SV1plusIP3D_discriminant());
-							}
-							else (hist_iter->second)->Fill(btag->SV1plusIP3D_discriminant());
-						}
-						else{
-							for(std::map<std::string, double>::const_iterator ip3dsv1_iter = m_IP3DSV1_workingPoints.begin(); ip3dsv1_iter != 					          m_IP3DSV1_workingPoints.end(); ++ip3dsv1_iter){
-								if((hist_iter->first).find(ip3dsv1_iter->first) < (hist_iter->first).length() && (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length()){
-									if(label == label_iter->second && btag->SV1plusIP3D_discriminant()>ip3dsv1_iter->second){
-	 									  (hist_iter->second)->Fill(jet->pt()/GeV);
-									}
-								}
-							}
-						}	
-					}
-					if((hist_iter->first).find("JetFitter_") < 1 && (hist_iter->first).find("matched") < (hist_iter->first).length()){						
-						if( (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length() && label == label_iter->second && (hist_iter->first).find("_weight") < (hist_iter->first).length()){
-							if((hist_iter->first).find("_trackCuts") < (hist_iter->first).length()){
-							  if(nGTinSvx > 0 && nIP3DTracks > 0) 							(hist_iter->second)->Fill(btag->JetFitter_loglikelihoodratio());
-							}
-							else{
-						 		(hist_iter->second)->Fill(btag->JetFitter_loglikelihoodratio());
-							}
-						}
-						else{
-							for(std::map<std::string, double>::const_iterator ip3dsv1_iter = m_IP3DSV1_workingPoints.begin(); ip3dsv1_iter != 					          m_IP3DSV1_workingPoints.end(); ++ip3dsv1_iter){
-								if((hist_iter->first).find(ip3dsv1_iter->first) < (hist_iter->first).length() && (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length()){
-									if(label == label_iter->second && btag->SV1plusIP3D_discriminant()>ip3dsv1_iter->second){
-	 									  (hist_iter->second)->Fill(jet->pt()/GeV);
-									}
-								}
-							}
-						}	
-					}
-					if((hist_iter->first).find("MV") < 1 && (hist_iter->first).find("matched") < (hist_iter->first).length()){
-						for(std::vector<std::string>::const_iterator tag_iter = m_taggers.begin(); tag_iter != m_taggers.end(); 
-						  ++tag_iter){						
-							if( (hist_iter->first).find(*tag_iter+"_"+label_iter->first+"_") < (hist_iter->first).length() && label == label_iter->second && (hist_iter->first).find("_weight") < (hist_iter->first).length()){
-								if((hist_iter->first).find("_trackCuts") < (hist_iter->first).length()){
-									if(nGTinSvx > 0 && nIP3DTracks > 0){ 
-										double weight=-999;
-										btag->MVx_discriminant( *tag_iter,weight );
-										(hist_iter->second)->Fill(weight);
-									}
-								}
-								else{
-									double weight=-999;
-									btag->MVx_discriminant( *tag_iter,weight );
-									(hist_iter->second)->Fill(weight);
-								}
-							}	
-						}
-					}
-                		}
-			}
-		}
-	}  
-
-
- 	void BTaggingValidationPlots::finalizePlots(){
-
-		
-		std::string tmp_name_matched = "";
-		std::string tmp_name_eff = "";
-		std::string tmp_name_rej = "";
-		
-		for(std::map<std::string, TH1*>::const_iterator hist_iter=m_weight_histos.begin(); hist_iter!=m_weight_histos.end(); ++hist_iter){
-
-			if((hist_iter->first).find("matched")< (hist_iter->first).length() && (hist_iter->first).find("trackCuts") > (hist_iter->first).length()){
-				std::size_t found_matched = (hist_iter->first).find("matched");		
-				tmp_name_matched = (hist_iter->first);
-				tmp_name_eff = tmp_name_matched.replace(found_matched, 7, "eff");
-				std::map<std::string, TProfile*>::const_iterator eff_profile_iter = m_eff_profiles.find(tmp_name_eff);
-
-				if(eff_profile_iter != m_eff_profiles.end() && (eff_profile_iter->first).find("_pt") < (eff_profile_iter->first).length()){
-			 		makeEfficiencyVsPtPlot(hist_iter->second, eff_profile_iter->second);
-					(eff_profile_iter->second)->SetOption("E");
-				}
-				else if(eff_profile_iter != m_eff_profiles.end() && (eff_profile_iter->first).find("_weight") < (eff_profile_iter->first).length()){
-					makeEfficiencyPlot(hist_iter->second, eff_profile_iter->second);
-					std::size_t found_weight = tmp_name_eff.find("weight");
-					tmp_name_rej = tmp_name_eff.replace(found_weight, 6, "rej");
-					makeEfficiencyRejectionPlot(eff_profile_iter->second, m_eff_profiles.find(tmp_name_rej)->second);  
-				}
-			}
-		}
-	}
-
-
-	void BTaggingValidationPlots::makeEfficiencyVsPtPlot(TH1* hReco, TProfile* pEff){
-		TH1* hTruth=NULL;
-		std::string recoName = hReco->GetName();
-		if(recoName.find("_b_") < recoName.length()) hTruth = (TH1 *) m_truthPt_b->Clone();
-		else if(recoName.find("_c_") < recoName.length()) hTruth = (TH1 *) m_truthPt_c->Clone();
-		else if(recoName.find("_tau_") < recoName.length()) hTruth = (TH1 *) m_truthPt_tau->Clone();
-		else if(recoName.find("_u_") < recoName.length()) hTruth = (TH1 *) m_truthPt_u->Clone();
-		if (!hTruth || hTruth->GetNbinsX() != hReco->GetNbinsX() || hTruth->Integral() == 0) return;
-		else{
-			for (int bin_i=1; bin_i<= hTruth->GetNbinsX(); ++bin_i){ 
-				if(hTruth->GetBinContent(bin_i) == 0) continue;
-				double eff = hReco->GetBinContent(bin_i)/hTruth->GetBinContent(bin_i);
-				//double eff_err = sqrt(hReco->GetBinContent(bin_i)*(1-eff))/hTruth->GetBinContent(bin_i);		
-				double pt = hTruth->GetBinCenter(bin_i);	
-				pEff->Fill(pt,eff);
-			}
-		}
-  	}
-
-	void BTaggingValidationPlots::makeEfficiencyPlot(TH1* hReco, TProfile* pEff){
-//		double Ntrue = hReco->Integral();		
-		double Ntrue = hReco->Integral(0,hReco->GetNbinsX()+1);
-		std::string recoName =  hReco->GetName();
-		if(Ntrue == 0) return;
-		for (int bin_i=0; bin_i<= hReco->GetNbinsX()+1; ++bin_i){ 
-			double eff = hReco->Integral(bin_i, hReco->GetNbinsX())/Ntrue;
-			//double eff_err = sqrt(hReco->GetBinContent(bin_i)*(1-eff))/Ntrue;
-			double weight = hReco->GetBinCenter(bin_i);	
-			pEff->Fill(weight,eff);
-		}		
-	}
-
-	void BTaggingValidationPlots::makeEfficiencyRejectionPlot(TProfile* pLEff, TProfile* pEffRej){	
-		TProfile* pBEff=NULL;
-		//std::cout << "HIER NAME " << pEffRej->GetName() << std::endl;
-		std::string bEffName = pEffRej->GetName();
-		//std::cout << "name of rej vs eff histo " << pEffRej->GetName() << std::endl;
-		for(std::vector<std::string>::const_iterator tag_iter = m_taggers.begin(); tag_iter != m_taggers.end(); 
-			  ++tag_iter){
-		  if(bEffName.find(*tag_iter+"_") < 1) pBEff = (TProfile *) (m_eff_profiles.find(*tag_iter+"_b_eff_weight")->second)->Clone();
-			//std::cout << "name of used b-eff histo " << pBEff->GetName() << "\t name of used l-eff histo " << pLEff->GetName() << std::endl; }
-		}
-		if (!pBEff || pBEff->GetNbinsX() != pLEff->GetNbinsX()) return;
-		else{
-			for (int bin_i=1; bin_i<= pBEff->GetNbinsX(); ++bin_i){ 
-				double eff = pBEff->GetBinContent(bin_i);
-				double rej = 1/(pLEff->GetBinContent(bin_i));
-				//std::cout << "bin no.: " << bin_i << "\t b-bin: " << pBEff->GetBinCenter(bin_i) << "\t l-bin: " << pLEff->GetBinCenter(bin_i) << std::endl; 
-				//std::cout << "b-eff: " << eff << "\t l-eff: " << 1/rej << "\t rej: " << rej << std::endl;
-				pEffRej->Fill(eff,rej);
-			}		
-		}
-	}
-
-
-	void BTaggingValidationPlots::setTaggerInfos(){
-		m_taggers.push_back("IP3D");
-		m_taggers.push_back("IP2D");
-		m_taggers.push_back("SV1");
-		//m_taggers.push_back("SV0");
-		m_taggers.push_back("IP3DSV1");
-		m_taggers.push_back("JetFitter");
-		//m_taggers.push_back("JetFitterCombNN");
-		//m_taggers.push_back("MV1");
-		//m_taggers.push_back("MVb");	
-		//m_taggers.push_back("MV1c");
-		//m_taggers.push_back("MV2c00");
-		m_taggers.push_back("MV2c10");
-		//m_taggers.push_back("MV2c20");
-		m_taggers.push_back("MV2c10mu");
-		m_taggers.push_back("MV2c10rnn");
-		//To be added later
-		//m_taggers.push_back("DL1");
-		//m_taggers.push_back("DL1mu");
-		//m_taggers.push_back("DL1rnn");
-
-		m_truthLabels.insert(std::make_pair("b", 5));
-		m_truthLabels.insert(std::make_pair("c", 4));
-		m_truthLabels.insert(std::make_pair("u", 0));
-		m_truthLabels.insert(std::make_pair("tau", 15));
-		//rel. 16 MC10 Dec. 10
-		m_IP3D_workingPoints.insert(std::make_pair("50", 3.75));
-		m_IP3D_workingPoints.insert(std::make_pair("70", 1.2));
-		m_IP3D_workingPoints.insert(std::make_pair("80", -0.3));
-		//rel. 16 MC10 Dec. 10
-		m_IP2D_workingPoints.insert(std::make_pair("50", 2.9));
-		m_IP2D_workingPoints.insert(std::make_pair("70", 0.7));
-		m_IP2D_workingPoints.insert(std::make_pair("80", -0.5));
-		//rel 16 Mc10 Dec 10
-		m_SV1_workingPoints.insert(std::make_pair("40", 5.5));
-		m_SV1_workingPoints.insert(std::make_pair("50", 3.9));
-		m_SV1_workingPoints.insert(std::make_pair("60", 1.6));
-		//rel 17 MC12a Jul 12
-		m_SV0_workingPoints.insert(std::make_pair("40", 9.55));
-		m_SV0_workingPoints.insert(std::make_pair("50", 5.7));
-		//rel 17 Mc11b Dec. 11
-		m_IP3DSV1_workingPoints.insert(std::make_pair("50", 7.6));
-		m_IP3DSV1_workingPoints.insert(std::make_pair("70", 1.85));
-		m_IP3DSV1_workingPoints.insert(std::make_pair("80", -0.7));	
-		//self determined
-		m_JetFitter_workingPoints.insert(std::make_pair("50", 0.9));
-		m_JetFitter_workingPoints.insert(std::make_pair("70", -1.7));
-		m_JetFitter_workingPoints.insert(std::make_pair("80", -3.3));
-		//rel 17 Mc12a jul.12
-		//m_JetFitterCombNN_workingPoints.insert(std::make_pair("50", 2.1));
-		//m_JetFitterCombNN_workingPoints.insert(std::make_pair("70", -0.95));
-		//m_JetFitterCombNN_workingPoints.insert(std::make_pair("80", -2.6));	
-		//rel 17 Mc12a Nov. 12
-		//m_MV1_workingPoints.insert(std::make_pair("50", 0.992515446));
-		//m_MV1_workingPoints.insert(std::make_pair("70", 0.8119));
-		//m_MV1_workingPoints.insert(std::make_pair("80", 0.39));	
-		
-	}
-	
-	void BTaggingValidationPlots::bookEffHistos(){
-		setTaggerInfos();
-		for(std::vector<std::string>::const_iterator tag_iter = m_taggers.begin(); tag_iter != m_taggers.end(); 
-			  ++tag_iter){
-
-			for(std::map<std::string, int>::const_iterator label_iter = m_truthLabels.begin(); label_iter != m_truthLabels.end(); 
-			  ++label_iter){
-
-				std::string name_effRej = *tag_iter+"_"+label_iter->first+"_eff_rej";
-				TProfile* profile_effRej = PlotBase::BookTProfile(name_effRej, "rejection of "+label_iter->first+"-jets vs. b-efficiency; efficiency; rejection", 100, 0., 1, 0, 1000000., false);
-				m_eff_profiles.insert(std::make_pair(name_effRej, profile_effRej));
-
-				if((*tag_iter).find("MV") < 1){
-					std::string name_matched = *tag_iter+"_"+label_iter->first+"_matched_weight";
-					TH1* histo_matched = Book1D(name_matched, *tag_iter+" loglikelihoodratio of matched "+ m_sParticleType + " "+label_iter->first + "-jets; "+*tag_iter+"_loglikelihoodRatio;Events", 250, -1, 1.);	
-					m_weight_histos.insert(std::make_pair(name_matched, histo_matched));
-				}
-				else{
-					std::string name_matched = *tag_iter+"_"+label_iter->first+"_matched_weight";
-					TH1* histo_matched = Book1D(name_matched, *tag_iter+" loglikelihoodratio of matched "+ m_sParticleType + " "+label_iter->first + "-jets; "+*tag_iter+"_loglikelihoodRatio;Events", 250, -10, 40.);	
-					m_weight_histos.insert(std::make_pair(name_matched, histo_matched));
-				}
-
-				std::string name_trackCuts = *tag_iter+"_"+label_iter->first+"_matched_weight_trackCuts";
-				TH1* histo_trackCuts = Book1D(name_trackCuts, *tag_iter+" loglikelihoodratio of matched "+ m_sParticleType + " " +label_iter->first + "-jets with nTrack cuts; "+*tag_iter+"_loglikelihoodRatio;Events", 250, -10, 40.);	
-				m_weight_histos.insert(std::make_pair(name_trackCuts, histo_trackCuts));
-				
-				if((*tag_iter).find("MV") < 1){
-					std::string name_eff = *tag_iter+"_"+label_iter->first+"_eff_weight";
-					TProfile* profile_eff = BookTProfile(name_eff, "efficiency vs. "+*tag_iter+" loglikelihoodratio of "+ m_sParticleType + " " + label_iter->first + "-jets; "+*tag_iter+"_loglikelihoodRatio;efficiency", 250, -1, 1, 0., 1., false);	
-					m_eff_profiles.insert(std::make_pair(name_eff, profile_eff));
-				}
-				else{
-					std::string name_eff = *tag_iter+"_"+label_iter->first+"_eff_weight";
-					TProfile* profile_eff = BookTProfile(name_eff, "efficiency vs. "+*tag_iter+" loglikelihoodratio of "+ m_sParticleType + " " + label_iter->first + "-jets; "+*tag_iter+"_loglikelihoodRatio;efficiency", 250, -10, 40., 0., 1., false);
-					m_eff_profiles.insert(std::make_pair(name_eff, profile_eff));
-				}
-
-				if(*tag_iter == "IP3D"){
-					for(std::map<std::string, double>::const_iterator ip3d_iter = m_IP3D_workingPoints.begin(); ip3d_iter != 					   	m_IP3D_workingPoints.end(); ++ip3d_iter){
-
-						std::ostringstream str_tmp("");
-						str_tmp << ip3d_iter->second;
-						std::string name_matched = "IP3D_"+label_iter->first+"_"+ip3d_iter->first+"_matched_pt";
-						TH1* histo_matched = Book1D(name_matched, "p_{T} of matched "+ m_sParticleType +" for IP3D_loglikelihoodRatio > "+ str_tmp.str() + " " + label_iter->first + "-jets; p_{T} (GeV) ;Events", 100, 0., 1000.);
-						m_weight_histos.insert(std::make_pair(name_matched, histo_matched));
-						std::string name_eff = "IP3D_"+label_iter->first+"_"+ip3d_iter->first+"_eff_pt";
-						TProfile* profile_eff = BookTProfile(name_eff, "efficiency vs. p_{T} for IP3D_loglikelihoodRatio > " + str_tmp.str()+ " " + label_iter->first + "-jets; p_{T} (GeV) ;efficiency", 100, 0., 1000., 0, 1., false);
-						m_eff_profiles.insert(std::make_pair(name_eff, profile_eff));
-					}
-				}
-				if(*tag_iter == "IP2D"){
-					for(std::map<std::string, double>::const_iterator ip2d_iter = m_IP2D_workingPoints.begin(); ip2d_iter != 					   	m_IP2D_workingPoints.end(); ++ip2d_iter){
-
-						std::ostringstream str_tmp("");
-						str_tmp << ip2d_iter->second;
-						std::string name_matched = "IP2D_"+label_iter->first+"_"+ip2d_iter->first+"_matched_pt";
-						TH1* histo_matched = Book1D(name_matched, "p_{T} of matched "+ m_sParticleType +" for IP2D_loglikelihoodRatio > "+ str_tmp.str() + " " + label_iter->first + "-jets; p_{T} (GeV) ;Events", 100, 0., 1000.);
-						m_weight_histos.insert(std::make_pair(name_matched, histo_matched));
-						std::string name_eff = "IP2D_"+label_iter->first+"_"+ip2d_iter->first+"_eff_pt";
-						TProfile* profile_eff = BookTProfile(name_eff, "efficiency vs. p_{T} for IP2D_loglikelihoodRatio > " + str_tmp.str()+ " " + label_iter->first + "-jets; p_{T} (GeV) ;efficiency", 100, 0., 1000., 0, 1., false);
-						m_eff_profiles.insert(std::make_pair(name_eff, profile_eff));
-					}
-				}
-				if(*tag_iter == "SV1"){
-					for(std::map<std::string, double>::const_iterator sv1_iter = m_SV1_workingPoints.begin(); sv1_iter != 					   	m_SV1_workingPoints.end(); ++sv1_iter){
-						std::ostringstream str_tmp("");
-						str_tmp << sv1_iter->second;
-						std::string name_matched = "SV1_"+label_iter->first+"_"+sv1_iter->first+"_matched_pt";
-						TH1* histo_matched = Book1D(name_matched, "p_{T} of matched " + m_sParticleType + " for SV1_loglikelihoodRatio > " + str_tmp.str()+ " " + label_iter->first +"-jets; p_{T} (GeV) ;Events", 100, 0., 1000.);
-						m_weight_histos.insert(std::make_pair(name_matched, histo_matched));
-						std::string name_eff = "SV1_"+label_iter->first+"_"+sv1_iter->first+"_eff_pt";
-						TProfile* profile_eff = BookTProfile(name_eff, "efficiency vs. p_{T} for SV1_loglikelihoodRatio > " + str_tmp.str()+label_iter->first + " " + "-jets; p_{T} (GeV) ;efficiency", 100, 0., 1000., 0.,1., false);
-						m_eff_profiles.insert(std::make_pair(name_eff, profile_eff));
-					}
-				}
-				/*
-				if(*tag_iter == "SV0"){
-					for(std::map<std::string, double>::const_iterator sv0_iter = m_SV0_workingPoints.begin(); sv0_iter != 					   	m_SV0_workingPoints.end(); ++sv0_iter){
-						std::ostringstream str_tmp("");
-						str_tmp << sv0_iter->second;
-						std::string name_matched = "SV0_"+label_iter->first+"_"+sv0_iter->first+"_matched_pt";
-						TH1* histo_matched = Book1D(name_matched, "p_{T} of matched " + m_sParticleType + " for SV0_loglikelihoodRatio > " + str_tmp.str()+ " " + label_iter->first +"-jets; p_{T} (GeV) ;Events", 100, 0., 1000.);
-						m_weight_histos.insert(std::make_pair(name_matched, histo_matched));
-						std::string name_eff = "SV0_"+label_iter->first+"_"+sv0_iter->first+"_eff_pt";
-						TProfile* profile_eff = BookTProfile(name_eff, "efficiency vs. p_{T} for SV0_loglikelihoodRatio > " + str_tmp.str()+label_iter->first + " " + "-jets; p_{T} (GeV) ;efficiency", 100, 0., 1000., 0.,1., false);
-						m_eff_profiles.insert(std::make_pair(name_eff, profile_eff));
-					}
-				} // SV0
-				*/
-				if(*tag_iter == "IP3DSV1"){
-					for(std::map<std::string, double>::const_iterator ip3dsv1_iter = m_IP3DSV1_workingPoints.begin(); ip3dsv1_iter != 						m_IP3DSV1_workingPoints.end(); ++ip3dsv1_iter){
-						std::ostringstream str_tmp("");
-						str_tmp << ip3dsv1_iter->second;
-						std::string name_matched = "IP3DSV1_"+label_iter->first+"_"+ip3dsv1_iter->first+"_matched_pt";
-						TH1* histo_matched = Book1D(name_matched, "p_{T} of matched " + m_sParticleType + " for IP3D+SV1_loglikelihoodRatio > " + str_tmp.str() + " " + label_iter->first + "-jets; p_{T} (GeV) ;Events", 100, 0., 1000.);
-						m_weight_histos.insert(std::make_pair(name_matched, histo_matched));
-						std::string name_eff = "IP3DSV1_"+label_iter->first+"_"+ip3dsv1_iter->first+"_eff_pt";
-						TProfile* profile_eff = BookTProfile(name_eff, "efficiency vs. p_{T} for IP3D+SV1_loglikelihoodRatio > " + str_tmp.str() +" " + label_iter->first + "-jets; p_{T} (GeV) ;efficiency", 100, 0., 1000.,0.,1., false);
-						m_eff_profiles.insert(std::make_pair(name_eff, profile_eff));
-					}
-				} //IP3DSV
-				if(*tag_iter == "JetFitter"){
-					for(std::map<std::string, double>::const_iterator jetfitter_iter = m_JetFitter_workingPoints.begin(); jetfitter_iter != m_JetFitter_workingPoints.end(); ++jetfitter_iter){
-						std::ostringstream str_tmp("");
-						str_tmp << jetfitter_iter->second;
-						std::string name_matched = "JetFitter_"+label_iter->first+"_"+jetfitter_iter->first+"_matched_pt";
-						TH1* histo_matched = Book1D(name_matched, "p_{T} of matched " + m_sParticleType + " for JetFitter_loglikelihoodRatio > " + str_tmp.str() + " " + label_iter->first + "-jets; p_{T} (GeV) ;Events", 100, 0., 1000.);
-						m_weight_histos.insert(std::make_pair(name_matched, histo_matched));
-						std::string name_eff = "JetFitter_"+label_iter->first+"_"+jetfitter_iter->first+"_eff_pt";
-						TProfile* profile_eff = BookTProfile(name_eff, "efficiency vs. p_{T} for JetFitter_loglikelihoodRatio > " + str_tmp.str() +" " + label_iter->first + "-jets; p_{T} (GeV) ;efficiency", 100, 0., 1000.,0.,1., false);
-						m_eff_profiles.insert(std::make_pair(name_eff, profile_eff));
-					}
-				} // JetFitter
-				/*
-				if(*tag_iter == "JetFitterCombNN"){
-					for(std::map<std::string, double>::const_iterator jetfitter_iter = m_JetFitterCombNN_workingPoints.begin(); jetfitter_iter != m_JetFitterCombNN_workingPoints.end(); ++jetfitter_iter){
-						std::ostringstream str_tmp("");
-						str_tmp << jetfitter_iter->second;
-						std::string name_matched = "JetFitterCombNN_"+label_iter->first+"_"+jetfitter_iter->first+"_matched_pt";
-						TH1* histo_matched = Book1D(name_matched, "p_{T} of matched " + m_sParticleType + " for JetFitterCombNN_loglikelihoodRatio > " + str_tmp.str() + " " + label_iter->first + "-jets; p_{T} (GeV) ;Events", 100, 0., 1000.);
-						m_weight_histos.insert(std::make_pair(name_matched, histo_matched));
-						std::string name_eff = "JetFitterCombNN_"+label_iter->first+"_"+jetfitter_iter->first+"_eff_pt";
-						TProfile* profile_eff = BookTProfile(name_eff, "efficiency vs. p_{T} for JetFitterCombNN_loglikelihoodRatio > " + str_tmp.str() +" " + label_iter->first + "-jets; p_{T} (GeV) ;efficiency", 100, 0., 1000.,0.,1., false);
-						m_eff_profiles.insert(std::make_pair(name_eff, profile_eff));
-					}
-				} // JetFitterCombNN
-				*/
-				/*
-				if(*tag_iter == "MV1"){
-					for(std::map<std::string, double>::const_iterator mv1_iter = m_MV1_workingPoints.begin(); mv1_iter != m_MV1_workingPoints.end(); ++mv1_iter){
-						std::ostringstream str_tmp("");
-						str_tmp << mv1_iter->second;
-						std::string name_matched = "MV1_"+label_iter->first+"_"+mv1_iter->first+"_matched_pt";
-						TH1* histo_matched = Book1D(name_matched, "p_{T} of matched " + m_sParticleType + " for MV1_weight > " + str_tmp.str() + " " + label_iter->first + "-jets; p_{T} (GeV) ;Events", 100, 0., 1000.);
-						m_weight_histos.insert(std::make_pair(name_matched, histo_matched));
-						std::string name_eff = "MV1_"+label_iter->first+"_"+mv1_iter->first+"_eff_pt";
-						TProfile* profile_eff = BookTProfile(name_eff, "efficiency vs. p_{T} for MV1_weight > " + str_tmp.str() +" " + label_iter->first + "-jets; p_{T} (GeV) ;efficiency", 100, 0., 1000.,0.,1., false);
-						m_eff_profiles.insert(std::make_pair(name_eff, profile_eff));
-					}
-				} // MV1
-				*/
-			}
-		}
-	}
-		
+  // implement the setter function for the histogram definitions
+  void BTaggingValidationPlots::setHistogramDefinitions( std::map< std::string, std::vector< std::string > > HistogramDefinitions){
+    m_HistogramDefinitions = HistogramDefinitions;
+  }
+  
+  // implement the setter function for the cuts that can be set in the config
+  void BTaggingValidationPlots::setIsDataJVTCutsAndTMPCut(bool isData, float JVTCutAntiKt4EMTopoJets, float JVTCutLargerEtaAntiKt4EMTopoJets, float JVTCutAntiKt4EMPFlowJets, float truthMatchProbabilityCut){
+    m_isData = isData;
+    if (m_sParticleType=="antiKt4EMTopoJets"){ 
+      m_JVT_defined = true; 
+      m_JVT_cut = JVTCutAntiKt4EMTopoJets;
+      m_JVTLargerEta_defined = true;
+      m_JVTLargerEta_cut = JVTCutLargerEtaAntiKt4EMTopoJets;
+    }
+    if (m_sParticleType=="antiKt4EMPFlowJets"){
+      m_JVT_defined = true; 
+      m_JVT_cut = JVTCutAntiKt4EMPFlowJets;
+    }
+    m_truthMatchProbabilityCut = truthMatchProbabilityCut;
+  }
+  
+  // implement the bookHistogram function using the histogram definitions
+  TH1* BTaggingValidationPlots::bookHistogram(std::string histo_name, std::string var_name, std::string part, std::string prefix){
+    // check if the var is in the histogram definitions
+    if(m_HistogramDefinitions.find(var_name) == m_HistogramDefinitions.end()) {
+      throw std::invalid_argument("var_name " + var_name + " not in HistogramDefinitions.");
+    }
+    if(m_HistogramDefinitions.at(var_name)[histo_type] != "TH1D") {
+      throw std::invalid_argument("The variable " + var_name + " not defined as TH1D.");
+    }
+    // get the title
+    std::string title = ""; 
+    if(part != "") title += part + " - ";
+    if(prefix != "") title += prefix + " ";
+    title += m_HistogramDefinitions.at(var_name)[histo_title];
+    // add the category to the name
+    histo_name = m_HistogramDefinitions.at(var_name)[histo_path] + "_" + histo_name;
+    // get the bins
+    double xbins = std::stod(m_HistogramDefinitions.at(var_name)[histo_xbins]);
+    double xmin = std::stod(m_HistogramDefinitions.at(var_name)[histo_xmin]);
+    double xmax = std::stod(m_HistogramDefinitions.at(var_name)[histo_xmax]);
+    // book and return the histo
+    return Book1D(histo_name, title, xbins, xmin, xmax);
+  }
+   
+  // implement the bookProfile function using the histogram definitions
+  TProfile* BTaggingValidationPlots::bookProfile(std::string histo_name, std::string var_name, std::string part, std::string prefix){
+    // check if the var is in the histogram definitions
+    if(m_HistogramDefinitions.find(var_name) == m_HistogramDefinitions.end()) {
+      throw std::invalid_argument("var_name " + var_name + " not in HistogramDefinitions.");
+    }
+    if(m_HistogramDefinitions.at(var_name)[histo_type] != "TProfile") {
+      throw std::invalid_argument("The variable " + var_name + " not defined as TProfile.");
+    }
+    // get the title
+    std::string title = ""; 
+    if(part != "") title += part + " - ";
+    if(prefix != "") title += prefix + " ";
+    title += m_HistogramDefinitions.at(var_name)[histo_title];
+    // get the bins
+    double xbins = std::stod(m_HistogramDefinitions.at(var_name)[histo_xbins]);
+    double xmin = std::stod(m_HistogramDefinitions.at(var_name)[histo_xmin]);
+    double xmax = std::stod(m_HistogramDefinitions.at(var_name)[histo_xmax]);
+    double ymin = std::stod(m_HistogramDefinitions.at(var_name)[histo_ymin]);
+    double ymax = std::stod(m_HistogramDefinitions.at(var_name)[histo_ymax]);
+    // book and return the histo
+    return PlotBase::BookTProfile(histo_name, title, xbins, xmin, xmax, ymin, ymax, false);
+  }
+
+  // util function to get track values
+  int BTaggingValidationPlots::getTrackHits(const xAOD::TrackParticle& part, xAOD::SummaryType info) {
+    uint8_t val;
+    bool ok = part.summaryValue(val, info);
+    if (!ok) throw std::logic_error("Problem getting track summary value.");
+    return val;
+  }
+
+  // util function to fill the tagger discriminant related histograms
+  void BTaggingValidationPlots::fillDiscriminantHistograms(const std::string& tagger_name, const double& discriminant_value, const std::map<std::string, double>& working_points, const int& truth_label, std::map<std::string, TH1*>::const_iterator hist_iter, std::map<std::string, int>::const_iterator label_iter, const bool& pass_nTracksCut, const double& jet_pT, const double& jet_Lxy, const bool& onZprime, const xAOD::EventInfo* event){
+    // check if the current histogram is to be filled with this tagger discriminant
+    if((hist_iter->first).find(tagger_name) < 1 && (hist_iter->first).find("matched") < (hist_iter->first).length()){                        
+      // check if the current histograms is to be filled with the discrinimant and the current truth label
+      if( (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length() && truth_label == label_iter->second && (hist_iter->first).find("_weight") < (hist_iter->first).length()){
+   
+        // now fill it if it is the nTracksCut histogram
+        if((hist_iter->first).find("_trackCuts") < (hist_iter->first).length()){
+          if(pass_nTracksCut) (hist_iter->second)->Fill(discriminant_value, event->beamSpotWeight());
+        }
+        // else fill it without the nTracksCut
+        else{
+          (hist_iter->second)->Fill(discriminant_value, event->beamSpotWeight());
+        }
+      }
+      // if it's not to be filled with the discriminant it's the jet pT with discriminant cut selection
+      else if((hist_iter->first).find("_matched_pt") < (hist_iter->first).length()){
+        for(std::map<std::string, double>::const_iterator working_points_iter = working_points.begin(); working_points_iter != working_points.end(); ++working_points_iter){
+          // check if the current histogram is the right one
+          if((hist_iter->first).find(working_points_iter->first) < (hist_iter->first).length() && (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length()){
+            if(truth_label == label_iter->second && discriminant_value > working_points_iter->second){
+              // check if we're on a Zprime sample)
+              if((hist_iter->first).find("Zprime") < (hist_iter->first).length()){
+                if(onZprime) (hist_iter->second)->Fill(jet_pT/GeV, event->beamSpotWeight());
+              } else {
+                if(!onZprime) (hist_iter->second)->Fill(jet_pT/GeV, event->beamSpotWeight());
+              }
+            }
+          }
+        }
+      }    
+      else if((hist_iter->first).find("_matched_Lxy") < (hist_iter->first).length()){
+        for(std::map<std::string, double>::const_iterator working_points_iter = working_points.begin(); working_points_iter != working_points.end(); ++working_points_iter){
+          // check if the current histogram is the right one
+          if((hist_iter->first).find(working_points_iter->first) < (hist_iter->first).length() && (hist_iter->first).find("_"+label_iter->first+"_") < (hist_iter->first).length()){
+            if(truth_label == label_iter->second && discriminant_value > working_points_iter->second){
+              (hist_iter->second)->Fill(jet_Lxy, event->beamSpotWeight());
+            }
+          }
+        }
+      }    
+    }
+  }
+   
+
+  // util function to book the discriminant related vs pT plots
+  void BTaggingValidationPlots::bookDiscriminantVsPTAndLxyHistograms(const std::string& tagger_name, const std::map<std::string, double>& workingPoints, const bool& isOldTagger, std::map<std::string, int>::const_iterator label_iter, const std::string& sParticleType){
+    for(std::map<std::string, double>::const_iterator working_points_iter = workingPoints.begin(); working_points_iter != workingPoints.end(); ++working_points_iter){
+      // book pT histogram normal
+      std::string histo_name_matched = tagger_name + "_" + label_iter->first + "_" + working_points_iter->first + "_matched_pt_ttbar";
+      std::string var_name = "pT_llrCut";  
+      if(isOldTagger) var_name += "_old_taggers";
+      TH1* histo_matched = bookHistogram(histo_name_matched, var_name, sParticleType, label_iter->first + "-jets" + ", for " + tagger_name + " llr > "+ std::to_string(working_points_iter->second) + ": " );    
+      m_weight_histos.insert(std::make_pair(histo_name_matched, histo_matched));
+
+      // book pT histogram for Zprime
+      std::string histo_name_matched_Zprime = tagger_name + "_" + label_iter->first + "_" + working_points_iter->first + "_matched_pt_Zprime";
+      std::string var_name_Zprime = "pT_llrCut_Zprime";  
+      if(isOldTagger) var_name_Zprime += "_old_taggers";
+      TH1* histo_matched_Zprime = bookHistogram(histo_name_matched_Zprime, var_name_Zprime, sParticleType, label_iter->first + "-jets" + ", for " + tagger_name + " llr > "+ std::to_string(working_points_iter->second) + ": " );    
+      m_weight_histos.insert(std::make_pair(histo_name_matched_Zprime, histo_matched_Zprime));
+
+      // book eff vs pt profile
+      std::string profile_name_eff = tagger_name + "_" + label_iter->first + "_" + working_points_iter->first + "_eff_pt";
+      TProfile* profile_eff = bookProfile(profile_name_eff, "efficiency_vs_pT", sParticleType, label_iter->first + "-jets" + ", for " + tagger_name + " llr > "+ std::to_string(working_points_iter->second) + ": " );
+      m_eff_profiles.insert(std::make_pair(profile_name_eff, profile_eff));
+
+      // book Lxy histogram
+      std::string histo_name_matched_Lxy = tagger_name + "_" + label_iter->first + "_" + working_points_iter->first + "_matched_Lxy";
+      std::string var_name_Lxy = "Lxy_llrCut";  
+      if(isOldTagger) var_name_Lxy += "_old_taggers";
+      TH1* histo_matched_Lxy = bookHistogram(histo_name_matched_Lxy, var_name_Lxy, sParticleType, label_iter->first + "-jets" + ", for " + tagger_name + " llr > "+ std::to_string(working_points_iter->second) + ": " );    
+      m_weight_histos.insert(std::make_pair(histo_name_matched_Lxy, histo_matched_Lxy));
+
+    }
+  }
+
+
+  template <class T>
+  void BTaggingValidationPlots::fillHistoWithTruthCases(T value, TH1* histo_incl, TH1* histo_b, TH1* histo_c, TH1* histo_l, TH1* histo_muon, const int& truth_label, const bool& has_muon, const xAOD::EventInfo* event){
+
+      // the inclusive ones in any case
+      histo_incl -> Fill( value, event->beamSpotWeight() );
+
+      // truth cases
+      if(!m_isData && truth_label == 5) {
+        histo_b -> Fill( value, event->beamSpotWeight() );
+      }
+      else if(!m_isData && truth_label == 4) {
+        histo_c -> Fill( value, event->beamSpotWeight() );
+      }
+      else if(!m_isData && truth_label == 0) {
+        histo_l -> Fill( value, event->beamSpotWeight() );
+      }
+      
+      // muon
+      if(has_muon) {
+        histo_muon -> Fill( value, event->beamSpotWeight() );
+      }
+  }
+
+   
+  void BTaggingValidationPlots::initializePlots(){
+
+    bookEffHistos();        
+
+    // multiplicities
+    m_nJets = bookHistogram("nJets", "nJets", m_sParticleType);
+    m_nTracks = bookHistogram("nTracks", "nTracks", m_sParticleType);
+    m_nPrimVtx = bookHistogram("nPrimVtx", "nPrimVtx");
+    m_nTracksPrimVtx = bookHistogram("nTracksPrimVtx", "nTracksPrimVtx");
+    m_nJetsWithMuon = bookHistogram("nJetsWithMuon", "nJetsWithMuon", m_sParticleType);
+    m_nJetsWithSV = bookHistogram("nJetsWithSV", "nJetsWithSV", m_sParticleType);
+    m_fracJetsWithMuon = bookHistogram("fracJetsWithMuon", "fracJetsWithMuon", m_sParticleType);
+    m_fracJetsWithSV = bookHistogram("fracJetsWithSV", "fracJetsWithSV", m_sParticleType);
+
+    // PV vars
+    m_PV_x = bookHistogram("PV_x", "PV_x");
+    m_PV_y = bookHistogram("PV_y", "PV_y");
+    m_PV_z = bookHistogram("PV_z", "PV_z");
+
+    // jet kinematc vars
+    m_jet_e  = bookHistogram("jet_e", "jet_E", m_sParticleType);
+    m_jet_e_Zprime  = bookHistogram("jet_e_Zprime", "jet_E_Zprime", m_sParticleType);
+    m_jet_pt  = bookHistogram("jet_pt_ttbar", "jet_pT", m_sParticleType);
+    m_jet_pt_Zprime  = bookHistogram("jet_pt_Zprime", "jet_pT_Zprime", m_sParticleType);
+    m_jet_eta  = bookHistogram("jet_eta", "jet_eta", m_sParticleType);
+    m_jet_phi  = bookHistogram("jet_phi", "jet_phi", m_sParticleType);
+
+    // muon vars
+    m_muon_pT_frac = bookHistogram("muon_pT_frac", "muon_pT_frac", m_sParticleType); 
+
+    // truth info
+    m_truthLabel  = bookHistogram("truthLabel", "truth_label", m_sParticleType);
+
+    m_jet_pt_b  = bookHistogram("jet_pt_b_ttbar", "jet_pT", m_sParticleType, "b-jets - ");
+    m_jet_pt_c  = bookHistogram("jet_pt_c_ttbar", "jet_pT", m_sParticleType, "c-jets - ");
+    m_jet_pt_l  = bookHistogram("jet_pt_l_ttbar", "jet_pT", m_sParticleType, "l-jets - ");
+
+    m_jet_pt_Zprime_b  = bookHistogram("jet_pt_b_Zprime", "jet_pT_Zprime", m_sParticleType, "b-jets - ");
+    m_jet_pt_Zprime_c  = bookHistogram("jet_pt_c_Zprime", "jet_pT_Zprime", m_sParticleType, "c-jets - ");
+    m_jet_pt_Zprime_l  = bookHistogram("jet_pt_l_Zprime", "jet_pT_Zprime", m_sParticleType, "l-jets - ");
+
+    m_jet_eta_b  = bookHistogram("jet_eta_b", "jet_eta", m_sParticleType, "b-jets - ");
+    m_jet_eta_c  = bookHistogram("jet_eta_c", "jet_eta", m_sParticleType, "c-jets - ");
+    m_jet_eta_l  = bookHistogram("jet_eta_l", "jet_eta", m_sParticleType, "l-jets - ");
+
+    // SV1 related vars
+    m_SV1_numSVs_incl = bookHistogram("SV1_numSVs_incl", "SV1_numSVs", m_sParticleType);
+    m_SV1_masssvx_incl = bookHistogram("SV1_masssvx_incl", "SV1_masssvx", m_sParticleType);
+    m_SV1_N2Tpair_incl = bookHistogram("SV1_N2Tpair_incl", "SV1_N2Tpair", m_sParticleType);
+    m_SV1_efracsvx_incl = bookHistogram("SV1_efracsvx_incl", "SV1_efracsvx", m_sParticleType);
+    m_SV1_deltaR_incl = bookHistogram("SV1_deltaR_incl", "SV1_deltaR", m_sParticleType);
+    m_SV1_significance3d_incl = bookHistogram("SV1_significance3d_incl", "SV1_significance3d", m_sParticleType);
+    m_SV1_energyTrkInJet_incl = bookHistogram("SV1_energyTrkInJet_incl", "SV1_energyTrkInJet", m_sParticleType);
+    m_SV1_NGTinSvx_incl = bookHistogram("SV1_NGTinSvx_incl", "SV1_NGTinSvx", m_sParticleType);
+    m_SV1_Lxy_incl = bookHistogram("SV1_Lxy_incl", "SV1_Lxy", m_sParticleType);
+    m_SV1_purity_incl = bookHistogram("SV1_purity_incl", "SV1_purity", m_sParticleType);
+    m_SV1_fracTracks_fromB_incl = bookHistogram("SV1_fracTracks_fromB_incl", "SV1_fracTracks_from_B", m_sParticleType);
+    m_SV1_fracTracks_fromC_incl = bookHistogram("SV1_fracTracks_fromC_incl", "SV1_fracTracks_from_C", m_sParticleType);
+    m_SV1_fracTracks_fromFragmentation_incl = bookHistogram("SV1_fracTracks_fromFragmentation_incl", "SV1_fracTracks_from_Fragmentation", m_sParticleType);
+    m_SV1_fracTracks_fromSecondaries_incl = bookHistogram("SV1_fracTracks_fromSecondaries_incl", "SV1_fracTracks_from_Secondaries", m_sParticleType);
+    m_SV1_fracTracks_fromPileup_incl = bookHistogram("SV1_fracTracks_fromPileup_incl", "SV1_fracTracks_from_Pileup", m_sParticleType);
+    m_SV1_fracTracks_fromFake_incl = bookHistogram("SV1_fracTracks_fromFake_incl", "SV1_fracTracks_from_Fake", m_sParticleType);
+
+    m_SV1_numSVs_b = bookHistogram("SV1_numSVs_b", "SV1_numSVs", m_sParticleType, "b-jets - ");
+    m_SV1_masssvx_b = bookHistogram("SV1_masssvx_b", "SV1_masssvx", m_sParticleType, "b-jets - ");
+    m_SV1_N2Tpair_b = bookHistogram("SV1_N2Tpair_b", "SV1_N2Tpair", m_sParticleType, "b-jets - ");
+    m_SV1_efracsvx_b = bookHistogram("SV1_efracsvx_b", "SV1_efracsvx", m_sParticleType, "b-jets - ");
+    m_SV1_deltaR_b = bookHistogram("SV1_deltaR_b", "SV1_deltaR", m_sParticleType, "b-jets - ");
+    m_SV1_significance3d_b = bookHistogram("SV1_significance3d_b", "SV1_significance3d", m_sParticleType, "b-jets - ");
+    m_SV1_energyTrkInJet_b = bookHistogram("SV1_energyTrkInJet_b", "SV1_energyTrkInJet", m_sParticleType, "b-jets - ");
+    m_SV1_NGTinSvx_b = bookHistogram("SV1_NGTinSvx_b", "SV1_NGTinSvx", m_sParticleType, "b-jets - ");
+    m_SV1_Lxy_b = bookHistogram("SV1_Lxy_b", "SV1_Lxy", m_sParticleType, "b-jets - ");
+    m_SV1_purity_b = bookHistogram("SV1_purity_b", "SV1_purity", m_sParticleType, "b-jets - ");
+    m_SV1_fracTracks_fromB_b = bookHistogram("SV1_fracTracks_fromB_b", "SV1_fracTracks_from_B", m_sParticleType, "b-jets - ");
+    m_SV1_fracTracks_fromC_b = bookHistogram("SV1_fracTracks_fromC_b", "SV1_fracTracks_from_C", m_sParticleType, "b-jets - ");
+    m_SV1_fracTracks_fromFragmentation_b = bookHistogram("SV1_fracTracks_fromFragmentation_b", "SV1_fracTracks_from_Fragmentation", m_sParticleType, "b-jets - ");
+    m_SV1_fracTracks_fromSecondaries_b = bookHistogram("SV1_fracTracks_fromSecondaries_b", "SV1_fracTracks_from_Secondaries", m_sParticleType, "b-jets - ");
+    m_SV1_fracTracks_fromPileup_b = bookHistogram("SV1_fracTracks_fromPileup_b", "SV1_fracTracks_from_Pileup", m_sParticleType, "b-jets - ");
+    m_SV1_fracTracks_fromFake_b = bookHistogram("SV1_fracTracks_fromFake_b", "SV1_fracTracks_from_Fake", m_sParticleType, "b-jets - ");
+
+    m_SV1_numSVs_c = bookHistogram("SV1_numSVs_c", "SV1_numSVs", m_sParticleType, "c-jets - ");
+    m_SV1_masssvx_c = bookHistogram("SV1_masssvx_c", "SV1_masssvx", m_sParticleType, "c-jets - ");
+    m_SV1_N2Tpair_c = bookHistogram("SV1_N2Tpair_c", "SV1_N2Tpair", m_sParticleType, "c-jets - ");
+    m_SV1_efracsvx_c = bookHistogram("SV1_efracsvx_c", "SV1_efracsvx", m_sParticleType, "c-jets - ");
+    m_SV1_deltaR_c = bookHistogram("SV1_deltaR_c", "SV1_deltaR", m_sParticleType, "c-jets - ");
+    m_SV1_significance3d_c = bookHistogram("SV1_significance3d_c", "SV1_significance3d", m_sParticleType, "c-jets - ");
+    m_SV1_energyTrkInJet_c = bookHistogram("SV1_energyTrkInJet_c", "SV1_energyTrkInJet", m_sParticleType, "c-jets - ");
+    m_SV1_NGTinSvx_c = bookHistogram("SV1_NGTinSvx_c", "SV1_NGTinSvx", m_sParticleType, "c-jets - ");
+    m_SV1_Lxy_c = bookHistogram("SV1_Lxy_c", "SV1_Lxy", m_sParticleType, "c-jets - ");
+    m_SV1_purity_c = bookHistogram("SV1_purity_c", "SV1_purity", m_sParticleType, "c-jets - ");
+    m_SV1_fracTracks_fromB_c = bookHistogram("SV1_fracTracks_fromB_c", "SV1_fracTracks_from_B", m_sParticleType, "c-jets - ");
+    m_SV1_fracTracks_fromC_c = bookHistogram("SV1_fracTracks_fromC_c", "SV1_fracTracks_from_C", m_sParticleType, "c-jets - ");
+    m_SV1_fracTracks_fromFragmentation_c = bookHistogram("SV1_fracTracks_fromFragmentation_c", "SV1_fracTracks_from_Fragmentation", m_sParticleType, "c-jets - ");
+    m_SV1_fracTracks_fromSecondaries_c = bookHistogram("SV1_fracTracks_fromSecondaries_c", "SV1_fracTracks_from_Secondaries", m_sParticleType, "c-jets - ");
+    m_SV1_fracTracks_fromPileup_c = bookHistogram("SV1_fracTracks_fromPileup_c", "SV1_fracTracks_from_Pileup", m_sParticleType, "c-jets - ");
+    m_SV1_fracTracks_fromFake_c = bookHistogram("SV1_fracTracks_fromFake_c", "SV1_fracTracks_from_Fake", m_sParticleType, "c-jets - ");
+
+    m_SV1_numSVs_l = bookHistogram("SV1_numSVs_l", "SV1_numSVs", m_sParticleType, "l-jets - ");
+    m_SV1_masssvx_l = bookHistogram("SV1_masssvx_l", "SV1_masssvx", m_sParticleType, "l-jets - ");
+    m_SV1_N2Tpair_l = bookHistogram("SV1_N2Tpair_l", "SV1_N2Tpair", m_sParticleType, "l-jets - ");
+    m_SV1_efracsvx_l = bookHistogram("SV1_efracsvx_l", "SV1_efracsvx", m_sParticleType, "l-jets - ");
+    m_SV1_deltaR_l = bookHistogram("SV1_deltaR_l", "SV1_deltaR", m_sParticleType, "l-jets - ");
+    m_SV1_significance3d_l = bookHistogram("SV1_significance3d_l", "SV1_significance3d", m_sParticleType, "l-jets - ");
+    m_SV1_energyTrkInJet_l = bookHistogram("SV1_energyTrkInJet_l", "SV1_energyTrkInJet", m_sParticleType, "l-jets - ");
+    m_SV1_NGTinSvx_l = bookHistogram("SV1_NGTinSvx_l", "SV1_NGTinSvx", m_sParticleType, "l-jets - ");
+    m_SV1_Lxy_l = bookHistogram("SV1_Lxy_l", "SV1_Lxy", m_sParticleType, "l-jets - ");
+    m_SV1_purity_l = bookHistogram("SV1_purity_l", "SV1_purity", m_sParticleType, "l-jets - ");
+    m_SV1_fracTracks_fromB_l = bookHistogram("SV1_fracTracks_fromB_l", "SV1_fracTracks_from_B", m_sParticleType, "l-jets - ");
+    m_SV1_fracTracks_fromC_l = bookHistogram("SV1_fracTracks_fromC_l", "SV1_fracTracks_from_C", m_sParticleType, "l-jets - ");
+    m_SV1_fracTracks_fromFragmentation_l = bookHistogram("SV1_fracTracks_fromFragmentation_l", "SV1_fracTracks_from_Fragmentation", m_sParticleType, "l-jets - ");
+    m_SV1_fracTracks_fromSecondaries_l = bookHistogram("SV1_fracTracks_fromSecondaries_l", "SV1_fracTracks_from_Secondaries", m_sParticleType, "l-jets - ");
+    m_SV1_fracTracks_fromPileup_l = bookHistogram("SV1_fracTracks_fromPileup_l", "SV1_fracTracks_from_Pileup", m_sParticleType, "l-jets - ");
+    m_SV1_fracTracks_fromFake_l = bookHistogram("SV1_fracTracks_fromFake_l", "SV1_fracTracks_from_Fake", m_sParticleType, "l-jets - ");
+
+    m_SV1_numSVs_muon = bookHistogram("SV1_numSVs_muon", "SV1_numSVs", m_sParticleType, "jets with muon - ");
+    m_SV1_masssvx_muon = bookHistogram("SV1_masssvx_muon", "SV1_masssvx", m_sParticleType, "jets with muon - ");
+    m_SV1_N2Tpair_muon = bookHistogram("SV1_N2Tpair_muon", "SV1_N2Tpair", m_sParticleType, "jets with moun - ");
+    m_SV1_efracsvx_muon = bookHistogram("SV1_efracsvx_muon", "SV1_efracsvx", m_sParticleType, "jets with moun - ");
+    m_SV1_deltaR_muon = bookHistogram("SV1_deltaR_muon", "SV1_deltaR", m_sParticleType, "jets with moun - ");
+    m_SV1_significance3d_muon = bookHistogram("SV1_significance3d_muon", "SV1_significance3d", m_sParticleType, "jets with moun - ");
+    m_SV1_energyTrkInJet_muon = bookHistogram("SV1_energyTrkInJet_muon", "SV1_energyTrkInJet", m_sParticleType, "jets with moun - ");
+    m_SV1_NGTinSvx_muon = bookHistogram("SV1_NGTinSvx_muon", "SV1_NGTinSvx", m_sParticleType, "jets with moun - ");
+    m_SV1_Lxy_muon = bookHistogram("SV1_Lxy_muon", "SV1_Lxy", m_sParticleType, "jets with moun - ");
+    m_SV1_purity_muon = bookHistogram("SV1_purity_muon", "SV1_purity", m_sParticleType, "jets with moun - ");
+    m_SV1_fracTracks_fromB_muon = bookHistogram("SV1_fracTracks_fromB_muon", "SV1_fracTracks_from_B", m_sParticleType, "jets with moun - ");
+    m_SV1_fracTracks_fromC_muon = bookHistogram("SV1_fracTracks_fromC_muon", "SV1_fracTracks_from_C", m_sParticleType, "jets with moun - ");
+    m_SV1_fracTracks_fromFragmentation_muon = bookHistogram("SV1_fracTracks_fromFragmentation_muon", "SV1_fracTracks_from_Fragmentation", m_sParticleType, "jets with moun - ");
+    m_SV1_fracTracks_fromSecondaries_muon = bookHistogram("SV1_fracTracks_fromSecondaries_muon", "SV1_fracTracks_from_Secondaries", m_sParticleType, "jets with moun - ");
+    m_SV1_fracTracks_fromPileup_muon = bookHistogram("SV1_fracTracks_fromPileup_muon", "SV1_fracTracks_from_Pileup", m_sParticleType, "jets with moun - ");
+    m_SV1_fracTracks_fromFake_muon = bookHistogram("SV1_fracTracks_fromFake_muon", "SV1_fracTracks_from_Fake", m_sParticleType, "jets with moun - ");
+
+    m_SV1_fracHFTracksInJet_incl = bookHistogram("SV1_fracHFTracksInJet_incl", "SV1_fracHFTracksInJet", m_sParticleType);
+    m_SV1_fracHFTracksInJet_b = bookHistogram("SV1_fracHFTracksInJet_b", "SV1_fracHFTracksInJet", m_sParticleType, "b-jets - ");
+    m_SV1_fracHFTracksInJet_c = bookHistogram("SV1_fracHFTracksInJet_c", "SV1_fracHFTracksInJet", m_sParticleType, "c-jets - ");
+    m_SV1_fracHFTracksInJet_l = bookHistogram("SV1_fracHFTracksInJet_l", "SV1_fracHFTracksInJet", m_sParticleType, "l-jets - ");
+    m_SV1_fracHFTracksInJet_muon = bookHistogram("SV1_fracHFTracksInJet_muon", "SV1_fracHFTracksInJet", m_sParticleType, "jets with moun - ");
+
+    if(m_detailLevel > 10){
+      m_SV1_fracTracks_Secondaries_KshortDecay_incl = bookHistogram("SV1_fracTracks_Secondaries_KshortDecay_incl", "SV1_fracTracks_Secondaries_KshortDecay", m_sParticleType); 
+      m_SV1_fracTracks_Secondaries_KshortDecay_b = bookHistogram("SV1_fracTracks_Secondaries_KshortDecay_b", "SV1_fracTracks_Secondaries_KshortDecay", m_sParticleType, "b-jets -"); 
+      m_SV1_fracTracks_Secondaries_KshortDecay_c = bookHistogram("SV1_fracTracks_Secondaries_KshortDecay_c", "SV1_fracTracks_Secondaries_KshortDecay", m_sParticleType, "c-jets -"); 
+      m_SV1_fracTracks_Secondaries_KshortDecay_u = bookHistogram("SV1_fracTracks_Secondaries_KshortDecay_l", "SV1_fracTracks_Secondaries_KshortDecay", m_sParticleType, "l-jets -"); 
+      m_SV1_fracTracks_Secondaries_KshortDecay_muon = bookHistogram("SV1_fracTracks_Secondaries_KshortDecay_muon", "SV1_fracTracks_Secondaries_KshortDecay", m_sParticleType, "jets with muon -"); 
+
+      m_SV1_fracTracks_Secondaries_LambdaDecay_incl = bookHistogram("SV1_fracTracks_Secondaries_LambdaDecay_incl", "SV1_fracTracks_Secondaries_LambdaDecay", m_sParticleType); 
+      m_SV1_fracTracks_Secondaries_LambdaDecay_b = bookHistogram("SV1_fracTracks_Secondaries_LambdaDecay_b", "SV1_fracTracks_Secondaries_LambdaDecay", m_sParticleType, "b-jets -"); 
+      m_SV1_fracTracks_Secondaries_LambdaDecay_c = bookHistogram("SV1_fracTracks_Secondaries_LambdaDecay_c", "SV1_fracTracks_Secondaries_LambdaDecay", m_sParticleType, "c-jets -"); 
+      m_SV1_fracTracks_Secondaries_LambdaDecay_u = bookHistogram("SV1_fracTracks_Secondaries_LambdaDecay_l", "SV1_fracTracks_Secondaries_LambdaDecay", m_sParticleType, "l-jets -"); 
+      m_SV1_fracTracks_Secondaries_LambdaDecay_muon = bookHistogram("SV1_fracTracks_Secondaries_LambdaDecay_muon", "SV1_fracTracks_Secondaries_LambdaDecay", m_sParticleType, "jets with muon -"); 
+
+      m_SV1_fracTracks_Secondaries_GammaConversion_incl = bookHistogram("SV1_fracTracks_Secondaries_GammaConversion_incl", "SV1_fracTracks_Secondaries_GammaConversion", m_sParticleType); 
+      m_SV1_fracTracks_Secondaries_GammaConversion_b = bookHistogram("SV1_fracTracks_Secondaries_GammaConversion_b", "SV1_fracTracks_Secondaries_GammaConversion", m_sParticleType, "b-jets -"); 
+      m_SV1_fracTracks_Secondaries_GammaConversion_c = bookHistogram("SV1_fracTracks_Secondaries_GammaConversion_c", "SV1_fracTracks_Secondaries_GammaConversion", m_sParticleType, "c-jets -"); 
+      m_SV1_fracTracks_Secondaries_GammaConversion_u = bookHistogram("SV1_fracTracks_Secondaries_GammaConversion_l", "SV1_fracTracks_Secondaries_GammaConversion", m_sParticleType, "l-jets -"); 
+      m_SV1_fracTracks_Secondaries_GammaConversion_muon = bookHistogram("SV1_fracTracks_Secondaries_GammaConversion_muon", "SV1_fracTracks_Secondaries_GammaConversion", m_sParticleType, "jets with muon -"); 
+
+      m_SV1_fracTracks_Secondaries_OtherDecay_incl = bookHistogram("SV1_fracTracks_Secondaries_OtherDecay_incl", "SV1_fracTracks_Secondaries_OtherDecay", m_sParticleType); 
+      m_SV1_fracTracks_Secondaries_OtherDecay_b = bookHistogram("SV1_fracTracks_Secondaries_OtherDecay_b", "SV1_fracTracks_Secondaries_OtherDecay", m_sParticleType, "b-jets -"); 
+      m_SV1_fracTracks_Secondaries_OtherDecay_c = bookHistogram("SV1_fracTracks_Secondaries_OtherDecay_c", "SV1_fracTracks_Secondaries_OtherDecay", m_sParticleType, "c-jets -"); 
+      m_SV1_fracTracks_Secondaries_OtherDecay_u = bookHistogram("SV1_fracTracks_Secondaries_OtherDecay_l", "SV1_fracTracks_Secondaries_OtherDecay", m_sParticleType, "l-jets -"); 
+      m_SV1_fracTracks_Secondaries_OtherDecay_muon = bookHistogram("SV1_fracTracks_Secondaries_OtherDecay_muon", "SV1_fracTracks_Secondaries_OtherDecay", m_sParticleType, "jets with muon -"); 
+
+      m_SV1_fracTracks_Secondaries_HadronicInteraction_incl = bookHistogram("SV1_fracTracks_Secondaries_HadronicInteraction_incl", "SV1_fracTracks_Secondaries_HadronicInteraction", m_sParticleType); 
+      m_SV1_fracTracks_Secondaries_HadronicInteraction_b = bookHistogram("SV1_fracTracks_Secondaries_HadronicInteraction_b", "SV1_fracTracks_Secondaries_HadronicInteraction", m_sParticleType, "b-jets -"); 
+      m_SV1_fracTracks_Secondaries_HadronicInteraction_c = bookHistogram("SV1_fracTracks_Secondaries_HadronicInteraction_c", "SV1_fracTracks_Secondaries_HadronicInteraction", m_sParticleType, "c-jets -"); 
+      m_SV1_fracTracks_Secondaries_HadronicInteraction_u = bookHistogram("SV1_fracTracks_Secondaries_HadronicInteraction_l", "SV1_fracTracks_Secondaries_HadronicInteraction", m_sParticleType, "l-jets -"); 
+      m_SV1_fracTracks_Secondaries_HadronicInteraction_muon = bookHistogram("SV1_fracTracks_Secondaries_HadronicInteraction_muon", "SV1_fracTracks_Secondaries_HadronicInteraction", m_sParticleType, "jets with muon -"); 
+
+      m_SV1_fracTracks_Secondaries_OtherSecondary_incl = bookHistogram("SV1_fracTracks_Secondaries_OtherSecondary_incl", "SV1_fracTracks_Secondaries_OtherSecondary", m_sParticleType); 
+      m_SV1_fracTracks_Secondaries_OtherSecondary_b = bookHistogram("SV1_fracTracks_Secondaries_OtherSecondary_b", "SV1_fracTracks_Secondaries_OtherSecondary", m_sParticleType, "b-jets -"); 
+      m_SV1_fracTracks_Secondaries_OtherSecondary_c = bookHistogram("SV1_fracTracks_Secondaries_OtherSecondary_c", "SV1_fracTracks_Secondaries_OtherSecondary", m_sParticleType, "c-jets -"); 
+      m_SV1_fracTracks_Secondaries_OtherSecondary_u = bookHistogram("SV1_fracTracks_Secondaries_OtherSecondary_l", "SV1_fracTracks_Secondaries_OtherSecondary", m_sParticleType, "l-jets -"); 
+      m_SV1_fracTracks_Secondaries_OtherSecondary_muon = bookHistogram("SV1_fracTracks_Secondaries_OtherSecondary_muon", "SV1_fracTracks_Secondaries_OtherSecondary", m_sParticleType, "jets with muon -"); 
+
+      m_SV1_fracTracks_OtherOrigin_incl = bookHistogram("SV1_fracTracks_OtherOrigin_incl", "SV1_fracTracks_from_OtherOrigin", m_sParticleType); 
+      m_SV1_fracTracks_OtherOrigin_b = bookHistogram("SV1_fracTracks_OtherOrigin_b", "SV1_fracTracks_from_OtherOrigin", m_sParticleType, "b-jets -"); 
+      m_SV1_fracTracks_OtherOrigin_c = bookHistogram("SV1_fracTracks_OtherOrigin_c", "SV1_fracTracks_from_OtherOrigin", m_sParticleType, "c-jets -"); 
+      m_SV1_fracTracks_OtherOrigin_u = bookHistogram("SV1_fracTracks_OtherOrigin_l", "SV1_fracTracks_from_OtherOrigin", m_sParticleType, "l-jets -"); 
+      m_SV1_fracTracks_OtherOrigin_muon = bookHistogram("SV1_fracTracks_OtherOrigin_muon", "SV1_fracTracks_from_OtherOrigin", m_sParticleType, "jets with muon -"); 
+    }
+
+    // MSV related vars
+    m_MSV_nvsec_incl = bookHistogram("MSV_nvsec_incl", "MSV_nvsec", m_sParticleType);
+    m_MSV_N2Tpair_incl = bookHistogram("MSV_N2Tpair_incl", "MSV_N2Tpair", m_sParticleType);
+    m_MSV_energyTrkInJet_incl = bookHistogram("MSV_energyTrkInJet_incl", "MSV_energyTrkInJet", m_sParticleType);
+    m_MSV_normdist_incl = bookHistogram("MSV_normdist_incl", "MSV_normdist", m_sParticleType);
+    m_MSV_purity_incl = bookHistogram("MSV_purity_incl", "MSV_purity", m_sParticleType);
+    m_MSV_vtx_mass_incl = bookHistogram("MSV_vtx_mass_incl", "MSV_vtx_mass", m_sParticleType);
+    
+    m_MSV_nvsec_b = bookHistogram("MSV_nvsec_b", "MSV_nvsec", m_sParticleType, "b-jets");
+    m_MSV_N2Tpair_b = bookHistogram("MSV_N2Tpair_b", "MSV_N2Tpair", m_sParticleType, "b-jets");
+    m_MSV_energyTrkInJet_b = bookHistogram("MSV_energyTrkInJet_b", "MSV_energyTrkInJet", m_sParticleType, "b-jets - ");
+    m_MSV_normdist_b = bookHistogram("MSV_normdist_b", "MSV_normdist", m_sParticleType, "b-jets - ");
+    m_MSV_purity_b = bookHistogram("MSV_purity_b", "MSV_purity", m_sParticleType, "b-jets - ");
+    m_MSV_vtx_mass_b = bookHistogram("MSV_vtx_mass_b", "MSV_vtx_mass", m_sParticleType, "b-jets - ");
+
+    m_MSV_nvsec_c = bookHistogram("MSV_nvsec_c", "MSV_nvsec", m_sParticleType, "c-jets - ");
+    m_MSV_N2Tpair_c = bookHistogram("MSV_N2Tpair_c", "MSV_N2Tpair", m_sParticleType, "c-jets - ");
+    m_MSV_energyTrkInJet_c = bookHistogram("MSV_energyTrkInJet_c", "MSV_energyTrkInJet", m_sParticleType, "c-jets - ");
+    m_MSV_normdist_c = bookHistogram("MSV_normdist_c", "MSV_normdist", m_sParticleType, "c-jets - ");
+    m_MSV_purity_c = bookHistogram("MSV_purity_c", "MSV_purity", m_sParticleType, "c-jets - ");
+    m_MSV_vtx_mass_c = bookHistogram("MSV_vtx_mass_c", "MSV_vtx_mass", m_sParticleType, "c-jets - ");
+
+    m_MSV_nvsec_l = bookHistogram("MSV_nvsec_l", "MSV_nvsec", m_sParticleType, "l-jets - ");
+    m_MSV_N2Tpair_l = bookHistogram("MSV_N2Tpair_l", "MSV_N2Tpair", m_sParticleType, "l-jets - ");
+    m_MSV_energyTrkInJet_l = bookHistogram("MSV_energyTrkInJet_l", "MSV_energyTrkInJet", m_sParticleType, "l-jets - ");
+    m_MSV_normdist_l = bookHistogram("MSV_normdist_l", "MSV_normdist", m_sParticleType, "l-jets - ");
+    m_MSV_purity_l = bookHistogram("MSV_purity_l", "MSV_purity", m_sParticleType, "l-jets - ");
+    m_MSV_vtx_mass_l = bookHistogram("MSV_vtx_mass_l", "MSV_vtx_mass", m_sParticleType, "tau-jets - ");
+    
+    m_MSV_nvsec_muon = bookHistogram("MSV_nvsec_muon", "MSV_nvsec", m_sParticleType, "jets with moun - ");
+    m_MSV_N2Tpair_muon = bookHistogram("MSV_N2Tpair_muon", "MSV_N2Tpair", m_sParticleType, "jets with moun - ");
+    m_MSV_energyTrkInJet_muon = bookHistogram("MSV_energyTrkInJet_muon", "MSV_energyTrkInJet", m_sParticleType, "jets with moun - ");
+    m_MSV_normdist_muon = bookHistogram("MSV_normdist_muon", "MSV_normdist", m_sParticleType, "jets with moun - ");
+    m_MSV_purity_muon = bookHistogram("MSV_purity_muon", "MSV_purity", m_sParticleType, "jets with moun - ");
+    m_MSV_vtx_mass_muon = bookHistogram("MSV_vtx_mass_muon", "MSV_vtx_mass", m_sParticleType, "jets with moun - ");
+
+    // JetFitter related vars 
+    m_JetFitter_N2Tpair_incl = bookHistogram("JetFitter_N2Tpair_incl", "JetFitter_N2Tpair", m_sParticleType);
+    m_JetFitter_nVTX_incl = bookHistogram("JetFitter_nVTX_incl", "JetFitter_nVTX", m_sParticleType);
+    m_JetFitter_nSingleTracks_incl = bookHistogram("JetFitter_nSingleTracks_incl", "JetFitter_nSingleTracks", m_sParticleType);
+    m_JetFitter_nTracksAtVtx_incl = bookHistogram("JetFitter_nTracksAtVtx_incl", "JetFitter_nTracksAtVtx", m_sParticleType);
+    m_JetFitter_mass_incl = bookHistogram("JetFitter_mass_incl", "JetFitter_mass", m_sParticleType);
+    m_JetFitter_energyFraction_incl = bookHistogram("JetFitter_energyFraction_incl", "JetFitter_energyFraction", m_sParticleType);
+    m_JetFitter_significance3d_incl = bookHistogram("JetFitter_significance3d_incl", "JetFitter_significance3d", m_sParticleType);
+    m_JetFitter_purity_incl = bookHistogram("JetFitter_purity_incl", "JetFitter_purity", m_sParticleType);
+    
+    m_JetFitter_N2Tpair_b = bookHistogram("JetFitter_N2Tpair_b", "JetFitter_N2Tpair", m_sParticleType, "b-jets - ");
+    m_JetFitter_nVTX_b = bookHistogram("JetFitter_nVTX_b", "JetFitter_nVTX", m_sParticleType, "b-jets - ");
+    m_JetFitter_nSingleTracks_b = bookHistogram("JetFitter_nSingleTracks_b", "JetFitter_nSingleTracks", m_sParticleType, "b-jets - ");
+    m_JetFitter_nTracksAtVtx_b = bookHistogram("JetFitter_nTracksAtVtx_b", "JetFitter_nTracksAtVtx", m_sParticleType, "b-jets - ");
+    m_JetFitter_mass_b = bookHistogram("JetFitter_mass_b", "JetFitter_mass", m_sParticleType, "b-jets - ");
+    m_JetFitter_energyFraction_b = bookHistogram("JetFitter_energyFraction_b", "JetFitter_energyFraction", m_sParticleType, "b-jets - ");
+    m_JetFitter_significance3d_b = bookHistogram("JetFitter_significance3d_b", "JetFitter_significance3d", m_sParticleType, "b-jets - ");
+    m_JetFitter_purity_b = bookHistogram("JetFitter_purity_b", "JetFitter_purity", m_sParticleType, "b-jets - ");
+    
+    m_JetFitter_N2Tpair_c = bookHistogram("JetFitter_N2Tpair_c", "JetFitter_N2Tpair", m_sParticleType, "c-jets - ");
+    m_JetFitter_nVTX_c = bookHistogram("JetFitter_nVTX_c", "JetFitter_nVTX", m_sParticleType, "c-jets - ");
+    m_JetFitter_nSingleTracks_c = bookHistogram("JetFitter_nSingleTracks_c", "JetFitter_nSingleTracks", m_sParticleType, "c-jets - ");
+    m_JetFitter_nTracksAtVtx_c = bookHistogram("JetFitter_nTracksAtVtx_c", "JetFitter_nTracksAtVtx", m_sParticleType, "c-jets - ");
+    m_JetFitter_mass_c = bookHistogram("JetFitter_mass_c", "JetFitter_mass", m_sParticleType, "c-jets - ");
+    m_JetFitter_energyFraction_c = bookHistogram("JetFitter_energyFraction_c", "JetFitter_energyFraction", m_sParticleType, "c-jets - ");
+    m_JetFitter_significance3d_c = bookHistogram("JetFitter_significance3d_c", "JetFitter_significance3d", m_sParticleType, "c-jets - ");
+    m_JetFitter_purity_c = bookHistogram("JetFitter_purity_c", "JetFitter_purity", m_sParticleType, "c-jets - ");
+    
+    m_JetFitter_N2Tpair_l = bookHistogram("JetFitter_N2Tpair_l", "JetFitter_N2Tpair", m_sParticleType, "l-jets - ");
+    m_JetFitter_nVTX_l = bookHistogram("JetFitter_nVTX_l", "JetFitter_nVTX", m_sParticleType, "l-jets - ");
+    m_JetFitter_nSingleTracks_l = bookHistogram("JetFitter_nSingleTracks_l", "JetFitter_nSingleTracks", m_sParticleType, "l-jets - ");
+    m_JetFitter_nTracksAtVtx_l = bookHistogram("JetFitter_nTracksAtVtx_l", "JetFitter_nTracksAtVtx", m_sParticleType, "l-jets - ");
+    m_JetFitter_mass_l = bookHistogram("JetFitter_mass_l", "JetFitter_mass", m_sParticleType, "l-jets - ");
+    m_JetFitter_energyFraction_l = bookHistogram("JetFitter_energyFraction_l", "JetFitter_energyFraction", m_sParticleType, "l-jets - ");
+    m_JetFitter_significance3d_l = bookHistogram("JetFitter_significance3d_l", "JetFitter_significance3d", m_sParticleType, "l-jets - ");
+    m_JetFitter_purity_l = bookHistogram("JetFitter_purity_l", "JetFitter_purity", m_sParticleType, "l-jets - ");
+    
+    m_JetFitter_N2Tpair_muon = bookHistogram("JetFitter_N2Tpair_muon", "JetFitter_N2Tpair", m_sParticleType, "jets with moun - ");
+    m_JetFitter_nVTX_muon = bookHistogram("JetFitter_nVTX_muon", "JetFitter_nVTX", m_sParticleType, "jets with moun - ");
+    m_JetFitter_nSingleTracks_muon = bookHistogram("JetFitter_nSingleTracks_muon", "JetFitter_nSingleTracks", m_sParticleType, "jets with moun - ");
+    m_JetFitter_nTracksAtVtx_muon = bookHistogram("JetFitter_nTracksAtVtx_muon", "JetFitter_nTracksAtVtx", m_sParticleType, "jets with moun - ");
+    m_JetFitter_mass_muon = bookHistogram("JetFitter_mass_muon", "JetFitter_mass", m_sParticleType, "jets with moun - ");
+    m_JetFitter_energyFraction_muon = bookHistogram("JetFitter_energyFraction_muon", "JetFitter_energyFraction", m_sParticleType, "jets with moun - ");
+    m_JetFitter_significance3d_muon = bookHistogram("JetFitter_significance3d_muon", "JetFitter_significance3d", m_sParticleType, "jets with moun - ");
+    m_JetFitter_purity_muon = bookHistogram("JetFitter_purity_muon", "JetFitter_purity", m_sParticleType, "jets with moun - ");
+    
+
+    // SV1 related profiles
+    m_SV1_masssvx_vs_pT_incl = bookProfile("SV1_masssvx_vs_pT_incl", "SV1_masssvx_vs_pT", m_sParticleType);
+    m_SV1_N2Tpair_vs_pT_incl = bookProfile("SV1_N2Tpair_vs_pT_incl", "SV1_N2Tpair_vs_pT", m_sParticleType);
+    m_SV1_efracsvx_vs_pT_incl = bookProfile("SV1_efracsvx_vs_pT_incl", "SV1_efracsvx_vs_pT", m_sParticleType);
+    m_SV1_deltaR_vs_pT_incl = bookProfile("SV1_deltaR_vs_pT_incl", "SV1_deltaR_vs_pT", m_sParticleType);
+    m_SV1_masssvx_vs_pT_b = bookProfile("SV1_masssvx_vs_pT_b", "SV1_masssvx_vs_pT", m_sParticleType, "b-jets - ");
+    m_SV1_N2Tpair_vs_pT_b = bookProfile("SV1_N2Tpair_vs_pT_b", "SV1_N2Tpair_vs_pT", m_sParticleType, "b-jets - ");
+    m_SV1_efracsvx_vs_pT_b = bookProfile("SV1_efracsvx_vs_pT_b", "SV1_efracsvx_vs_pT", m_sParticleType, "b-jets - ");
+    m_SV1_deltaR_vs_pT_b = bookProfile("SV1_deltaR_vs_pT_b", "SV1_deltaR_vs_pT", m_sParticleType, "b-jets - ");
+    m_SV1_masssvx_vs_pT_c = bookProfile("SV1_masssvx_vs_pT_c", "SV1_masssvx_vs_pT", m_sParticleType, "c-jets - ");
+    m_SV1_N2Tpair_vs_pT_c = bookProfile("SV1_N2Tpair_vs_pT_c", "SV1_N2Tpair_vs_pT", m_sParticleType, "c-jets - ");
+    m_SV1_efracsvx_vs_pT_c = bookProfile("SV1_efracsvx_vs_pT_c", "SV1_efracsvx_vs_pT", m_sParticleType, "c-jets - ");
+    m_SV1_deltaR_vs_pT_c = bookProfile("SV1_deltaR_vs_pT_c", "SV1_deltaR_vs_pT", m_sParticleType, "c-jets - ");
+    m_SV1_masssvx_vs_pT_l = bookProfile("SV1_masssvx_vs_pT_l", "SV1_masssvx_vs_pT", m_sParticleType, "l-jets - ");
+    m_SV1_N2Tpair_vs_pT_l = bookProfile("SV1_N2Tpair_vs_pT_l", "SV1_N2Tpair_vs_pT", m_sParticleType, "l-jets - ");
+    m_SV1_efracsvx_vs_pT_l = bookProfile("SV1_efracsvx_vs_pT_l", "SV1_efracsvx_vs_pT", m_sParticleType, "l-jets - ");
+    m_SV1_deltaR_vs_pT_l = bookProfile("SV1_deltaR_vs_pT_l", "SV1_deltaR_vs_pT", m_sParticleType, "l-jets - ");
+
+    m_SV1_masssvx_vs_eta_incl = bookProfile("SV1_masssvx_vs_eta_incl", "SV1_masssvx_vs_eta", m_sParticleType);
+    m_SV1_N2Tpair_vs_eta_incl = bookProfile("SV1_N2Tpair_vs_eta_incl", "SV1_N2Tpair_vs_eta", m_sParticleType);
+    m_SV1_efracsvx_vs_eta_incl = bookProfile("SV1_efracsvx_vs_eta_incl", "SV1_efracsvx_vs_eta", m_sParticleType);
+    m_SV1_deltaR_vs_eta_incl = bookProfile("SV1_deltaR_vs_eta_incl", "SV1_deltaR_vs_eta", m_sParticleType);
+    m_SV1_masssvx_vs_eta_b = bookProfile("SV1_masssvx_vs_eta_b", "SV1_masssvx_vs_eta", m_sParticleType, "b-jets - ");
+    m_SV1_N2Tpair_vs_eta_b = bookProfile("SV1_N2Tpair_vs_eta_b", "SV1_N2Tpair_vs_eta", m_sParticleType, "b-jets - ");
+    m_SV1_efracsvx_vs_eta_b = bookProfile("SV1_efracsvx_vs_eta_b", "SV1_efracsvx_vs_eta", m_sParticleType, "b-jets - ");
+    m_SV1_deltaR_vs_eta_b = bookProfile("SV1_deltaR_vs_eta_b", "SV1_deltaR_vs_eta", m_sParticleType, "b-jets - ");
+    m_SV1_masssvx_vs_eta_c = bookProfile("SV1_masssvx_vs_eta_c", "SV1_masssvx_vs_eta", m_sParticleType, "c-jets - ");
+    m_SV1_N2Tpair_vs_eta_c = bookProfile("SV1_N2Tpair_vs_eta_c", "SV1_N2Tpair_vs_eta", m_sParticleType, "c-jets - ");
+    m_SV1_efracsvx_vs_eta_c = bookProfile("SV1_efracsvx_vs_eta_c", "SV1_efracsvx_vs_eta", m_sParticleType, "c-jets - ");
+    m_SV1_deltaR_vs_eta_c = bookProfile("SV1_deltaR_vs_eta_c", "SV1_deltaR_vs_eta", m_sParticleType, "c-jets - ");
+    m_SV1_masssvx_vs_eta_l = bookProfile("SV1_masssvx_vs_eta_l", "SV1_masssvx_vs_eta", m_sParticleType, "l-jets - ");
+    m_SV1_N2Tpair_vs_eta_l = bookProfile("SV1_N2Tpair_vs_eta_l", "SV1_N2Tpair_vs_eta", m_sParticleType, "l-jets - ");
+    m_SV1_efracsvx_vs_eta_l = bookProfile("SV1_efracsvx_vs_eta_l", "SV1_efracsvx_vs_eta", m_sParticleType, "l-jets - ");
+    m_SV1_deltaR_vs_eta_l = bookProfile("SV1_deltaR_vs_eta_l", "SV1_deltaR_vs_eta", m_sParticleType, "l-jets - ");
+
+    // IPs and IP significances
+    m_track_d0_incl = bookHistogram("d0_incl", "track_d0", m_sParticleType);
+    m_track_z0_incl = bookHistogram("z0_incl", "track_z0", m_sParticleType); 
+    m_track_sigd0_incl = bookHistogram("sigd0_incl", "track_sigd0", m_sParticleType);
+    m_track_sigz0_incl = bookHistogram("sigz0_incl", "track_sigz0", m_sParticleType); 
+
+    m_track_d0_b = bookHistogram("d0_b", "track_d0", m_sParticleType, "b-jets -");
+    m_track_z0_b = bookHistogram("z0_b", "track_z0", m_sParticleType, "b-jets -"); 
+    m_track_sigd0_b = bookHistogram("sigd0_b", "track_sigd0", m_sParticleType, "b-jets -");
+    m_track_sigz0_b = bookHistogram("sigz0_b", "track_sigz0", m_sParticleType, "b-jets -"); 
+    
+    m_track_d0_c = bookHistogram("d0_c", "track_d0", m_sParticleType, "c-jets -");
+    m_track_z0_c = bookHistogram("z0_c", "track_z0", m_sParticleType, "c-jets -"); 
+    m_track_sigd0_c = bookHistogram("sigd0_c", "track_sigd0", m_sParticleType, "c-jets -");
+    m_track_sigz0_c = bookHistogram("sigz0_c", "track_sigz0", m_sParticleType, "c-jets -"); 
+    
+    m_track_d0_u = bookHistogram("d0_l", "track_d0", m_sParticleType, "l-jets -");
+    m_track_z0_u = bookHistogram("z0_l", "track_z0", m_sParticleType, "l-jets -"); 
+    m_track_sigd0_u = bookHistogram("sigd0_l", "track_sigd0", m_sParticleType, "l-jets -");
+    m_track_sigz0_u = bookHistogram("sigz0_l", "track_sigz0", m_sParticleType, "l-jets -"); 
+    
+    m_track_d0_muon = bookHistogram("d0_muon", "track_d0", m_sParticleType, "jets with muon -");
+    m_track_z0_muon = bookHistogram("z0_muon", "track_z0", m_sParticleType, "jets with muon -"); 
+    m_track_sigd0_muon = bookHistogram("sigd0_muon", "track_sigd0", m_sParticleType, "jets with muon -");
+    m_track_sigz0_muon = bookHistogram("sigz0_muon", "track_sigz0", m_sParticleType, "jets with muon -"); 
+
+    // pT_frac
+    m_track_pT_frac_incl = bookHistogram("track_pT_frac_incl", "track_pT_frac", m_sParticleType); 
+    m_track_pT_frac_b = bookHistogram("track_pT_frac_b", "track_pT_frac", m_sParticleType, "b-jets -"); 
+    m_track_pT_frac_c = bookHistogram("track_pT_frac_c", "track_pT_frac", m_sParticleType, "c-jets -"); 
+    m_track_pT_frac_u = bookHistogram("track_pT_frac_l", "track_pT_frac", m_sParticleType, "l-jets -"); 
+    m_track_pT_frac_muon = bookHistogram("track_pT_frac_muon", "track_pT_frac", m_sParticleType, "jets with muon -"); 
+
+    // DeltaR_jet_track
+    m_DeltaR_jet_track_incl = bookHistogram("DeltaR_jet_track_incl", "DeltaR_jet_track", m_sParticleType); 
+    m_DeltaR_jet_track_b = bookHistogram("DeltaR_jet_track_b", "DeltaR_jet_track", m_sParticleType, "b-jets -"); 
+    m_DeltaR_jet_track_c = bookHistogram("DeltaR_jet_track_c", "DeltaR_jet_track", m_sParticleType, "c-jets -"); 
+    m_DeltaR_jet_track_u = bookHistogram("DeltaR_jet_track_l", "DeltaR_jet_track", m_sParticleType, "l-jets -"); 
+    m_DeltaR_jet_track_muon = bookHistogram("DeltaR_jet_track_muon", "DeltaR_jet_track", m_sParticleType, "jets with muon -"); 
+
+    // numTracks_perJet 
+    m_numTracks_perJet_incl = bookHistogram("numTracks_perJet_incl", "numTracks_perJet", m_sParticleType); 
+    m_numTracks_perJet_b = bookHistogram("numTracks_perJet_b", "numTracks_perJet", m_sParticleType, "b-jets -"); 
+    m_numTracks_perJet_c = bookHistogram("numTracks_perJet_c", "numTracks_perJet", m_sParticleType, "c-jets -"); 
+    m_numTracks_perJet_u = bookHistogram("numTracks_perJet_l", "numTracks_perJet", m_sParticleType, "l-jets -"); 
+    m_numTracks_perJet_muon = bookHistogram("numTracks_perJet_muon", "numTracks_perJet", m_sParticleType, "jets with muon -"); 
+
+    // book TProfile for pT vs. numTracks_perJet
+    m_numTracks_perJet_vs_pT_incl = bookProfile("numTracks_perJet_vs_pT_incl", "numTracks_perJet_vs_pT", m_sParticleType);
+    m_numTracks_perJet_vs_pT_b = bookProfile("numTracks_perJet_vs_pT_b", "numTracks_perJet_vs_pT", m_sParticleType, "b-jets -");
+    m_numTracks_perJet_vs_pT_c = bookProfile("numTracks_perJet_vs_pT_c", "numTracks_perJet_vs_pT", m_sParticleType, "c-jets -");
+    m_numTracks_perJet_vs_pT_u = bookProfile("numTracks_perJet_vs_pT_l", "numTracks_perJet_vs_pT", m_sParticleType, "l-jets -");
+    m_numTracks_perJet_vs_pT_muon = bookProfile("numTracks_perJet_vs_pT_muon", "numTracks_perJet_vs_pT", m_sParticleType, "jets with muon -");
+
+    // number of tracks from different origins
+    m_numTracks_B_incl = bookHistogram("numTracks_B_incl", "numTracks_B", m_sParticleType); 
+    m_numTracks_C_incl = bookHistogram("numTracks_C_incl", "numTracks_C", m_sParticleType); 
+    m_numTracks_Fragmentation_incl = bookHistogram("numTracks_Fragmentation_incl", "numTracks_Fragmentation", m_sParticleType); 
+    m_numTracks_Secondaries_incl = bookHistogram("numTracks_Secondaries_incl", "numTracks_Secondaries", m_sParticleType); 
+    m_numTracks_Pileup_incl = bookHistogram("numTracks_Pileup_incl", "numTracks_Pileup", m_sParticleType); 
+    m_numTracks_Fake_incl = bookHistogram("numTracks_Fake_incl", "numTracks_Fake", m_sParticleType); 
+
+    m_numTracks_B_b = bookHistogram("numTracks_B_b", "numTracks_B", m_sParticleType, "b-jets -"); 
+    m_numTracks_C_b = bookHistogram("numTracks_C_b", "numTracks_C", m_sParticleType, "b-jets -"); 
+    m_numTracks_Fragmentation_b = bookHistogram("numTracks_Fragmentation_b", "numTracks_Fragmentation", m_sParticleType, "b-jets -"); 
+    m_numTracks_Secondaries_b = bookHistogram("numTracks_Secondaries_b", "numTracks_Secondaries", m_sParticleType, "b-jets -"); 
+    m_numTracks_Pileup_b = bookHistogram("numTracks_Pileup_b", "numTracks_Pileup", m_sParticleType, "b-jets -"); 
+    m_numTracks_Fake_b = bookHistogram("numTracks_Fake_b", "numTracks_Fake", m_sParticleType, "b-jets -"); 
+
+    m_numTracks_B_c = bookHistogram("numTracks_B_c", "numTracks_B", m_sParticleType, "c-jets -"); 
+    m_numTracks_C_c = bookHistogram("numTracks_C_c", "numTracks_C", m_sParticleType, "c-jets -"); 
+    m_numTracks_Fragmentation_c = bookHistogram("numTracks_Fragmentation_c", "numTracks_Fragmentation", m_sParticleType, "c-jets -"); 
+    m_numTracks_Secondaries_c = bookHistogram("numTracks_Secondaries_c", "numTracks_Secondaries", m_sParticleType, "c-jets -"); 
+    m_numTracks_Pileup_c = bookHistogram("numTracks_Pileup_c", "numTracks_Pileup", m_sParticleType, "c-jets -"); 
+    m_numTracks_Fake_c = bookHistogram("numTracks_Fake_c", "numTracks_Fake", m_sParticleType, "c-jets -"); 
+
+    m_numTracks_B_u = bookHistogram("numTracks_B_l", "numTracks_B", m_sParticleType, "l-jets -"); 
+    m_numTracks_C_u = bookHistogram("numTracks_C_l", "numTracks_C", m_sParticleType, "l-jets -"); 
+    m_numTracks_Fragmentation_u = bookHistogram("numTracks_Fragmentation_l", "numTracks_Fragmentation", m_sParticleType, "l-jets -"); 
+    m_numTracks_Secondaries_u = bookHistogram("numTracks_Secondaries_l", "numTracks_Secondaries", m_sParticleType, "l-jets -"); 
+    m_numTracks_Pileup_u = bookHistogram("numTracks_Pileup_l", "numTracks_Pileup", m_sParticleType, "l-jets -"); 
+    m_numTracks_Fake_u = bookHistogram("numTracks_Fake_l", "numTracks_Fake", m_sParticleType, "l-jets -"); 
+
+    m_numTracks_B_muon = bookHistogram("numTracks_B_muon", "numTracks_B", m_sParticleType, "jets with muon -"); 
+    m_numTracks_C_muon = bookHistogram("numTracks_C_muon", "numTracks_C", m_sParticleType, "jets with muon -"); 
+    m_numTracks_Fragmentation_muon = bookHistogram("numTracks_Fragmentation_muon", "numTracks_Fragmentation", m_sParticleType, "jets with muon -"); 
+    m_numTracks_Secondaries_muon = bookHistogram("numTracks_Secondaries_muon", "numTracks_Secondaries", m_sParticleType, "jets with muon -"); 
+    m_numTracks_Pileup_muon = bookHistogram("numTracks_Pileup_muon", "numTracks_Pileup", m_sParticleType, "jets with muon -"); 
+    m_numTracks_Fake_muon = bookHistogram("numTracks_Fake_muon", "numTracks_Fake", m_sParticleType, "jets with muon -"); 
+
+    if(m_detailLevel > 10){
+      m_numTracks_Secondaries_KshortDecay_incl = bookHistogram("numTracks_Secondaries_KshortDecay_incl", "numTracks_Secondaries_KshortDecay", m_sParticleType); 
+      m_numTracks_Secondaries_KshortDecay_b = bookHistogram("numTracks_Secondaries_KshortDecay_b", "numTracks_Secondaries_KshortDecay", m_sParticleType, "b-jets -"); 
+      m_numTracks_Secondaries_KshortDecay_c = bookHistogram("numTracks_Secondaries_KshortDecay_c", "numTracks_Secondaries_KshortDecay", m_sParticleType, "c-jets -"); 
+      m_numTracks_Secondaries_KshortDecay_u = bookHistogram("numTracks_Secondaries_KshortDecay_l", "numTracks_Secondaries_KshortDecay", m_sParticleType, "l-jets -"); 
+      m_numTracks_Secondaries_KshortDecay_muon = bookHistogram("numTracks_Secondaries_KshortDecay_muon", "numTracks_Secondaries_KshortDecay", m_sParticleType, "jets with muon -"); 
+
+      m_numTracks_Secondaries_LambdaDecay_incl = bookHistogram("numTracks_Secondaries_LambdaDecay_incl", "numTracks_Secondaries_LambdaDecay", m_sParticleType); 
+      m_numTracks_Secondaries_LambdaDecay_b = bookHistogram("numTracks_Secondaries_LambdaDecay_b", "numTracks_Secondaries_LambdaDecay", m_sParticleType, "b-jets -"); 
+      m_numTracks_Secondaries_LambdaDecay_c = bookHistogram("numTracks_Secondaries_LambdaDecay_c", "numTracks_Secondaries_LambdaDecay", m_sParticleType, "c-jets -"); 
+      m_numTracks_Secondaries_LambdaDecay_u = bookHistogram("numTracks_Secondaries_LambdaDecay_l", "numTracks_Secondaries_LambdaDecay", m_sParticleType, "l-jets -"); 
+      m_numTracks_Secondaries_LambdaDecay_muon = bookHistogram("numTracks_Secondaries_LambdaDecay_muon", "numTracks_Secondaries_LambdaDecay", m_sParticleType, "jets with muon -"); 
+
+      m_numTracks_Secondaries_GammaConversion_incl = bookHistogram("numTracks_Secondaries_GammaConversion_incl", "numTracks_Secondaries_GammaConversion", m_sParticleType); 
+      m_numTracks_Secondaries_GammaConversion_b = bookHistogram("numTracks_Secondaries_GammaConversion_b", "numTracks_Secondaries_GammaConversion", m_sParticleType, "b-jets -"); 
+      m_numTracks_Secondaries_GammaConversion_c = bookHistogram("numTracks_Secondaries_GammaConversion_c", "numTracks_Secondaries_GammaConversion", m_sParticleType, "c-jets -"); 
+      m_numTracks_Secondaries_GammaConversion_u = bookHistogram("numTracks_Secondaries_GammaConversion_l", "numTracks_Secondaries_GammaConversion", m_sParticleType, "l-jets -"); 
+      m_numTracks_Secondaries_GammaConversion_muon = bookHistogram("numTracks_Secondaries_GammaConversion_muon", "numTracks_Secondaries_GammaConversion", m_sParticleType, "jets with muon -"); 
+
+      m_numTracks_Secondaries_OtherDecay_incl = bookHistogram("numTracks_Secondaries_OtherDecay_incl", "numTracks_Secondaries_OtherDecay", m_sParticleType); 
+      m_numTracks_Secondaries_OtherDecay_b = bookHistogram("numTracks_Secondaries_OtherDecay_b", "numTracks_Secondaries_OtherDecay", m_sParticleType, "b-jets -"); 
+      m_numTracks_Secondaries_OtherDecay_c = bookHistogram("numTracks_Secondaries_OtherDecay_c", "numTracks_Secondaries_OtherDecay", m_sParticleType, "c-jets -"); 
+      m_numTracks_Secondaries_OtherDecay_u = bookHistogram("numTracks_Secondaries_OtherDecay_l", "numTracks_Secondaries_OtherDecay", m_sParticleType, "l-jets -"); 
+      m_numTracks_Secondaries_OtherDecay_muon = bookHistogram("numTracks_Secondaries_OtherDecay_muon", "numTracks_Secondaries_OtherDecay", m_sParticleType, "jets with muon -"); 
+
+      m_numTracks_Secondaries_HadronicInteraction_incl = bookHistogram("numTracks_Secondaries_HadronicInteraction_incl", "numTracks_Secondaries_HadronicInteraction", m_sParticleType); 
+      m_numTracks_Secondaries_HadronicInteraction_b = bookHistogram("numTracks_Secondaries_HadronicInteraction_b", "numTracks_Secondaries_HadronicInteraction", m_sParticleType, "b-jets -"); 
+      m_numTracks_Secondaries_HadronicInteraction_c = bookHistogram("numTracks_Secondaries_HadronicInteraction_c", "numTracks_Secondaries_HadronicInteraction", m_sParticleType, "c-jets -"); 
+      m_numTracks_Secondaries_HadronicInteraction_u = bookHistogram("numTracks_Secondaries_HadronicInteraction_l", "numTracks_Secondaries_HadronicInteraction", m_sParticleType, "l-jets -"); 
+      m_numTracks_Secondaries_HadronicInteraction_muon = bookHistogram("numTracks_Secondaries_HadronicInteraction_muon", "numTracks_Secondaries_HadronicInteraction", m_sParticleType, "jets with muon -"); 
+
+      m_numTracks_Secondaries_OtherSecondary_incl = bookHistogram("numTracks_Secondaries_OtherSecondary_incl", "numTracks_Secondaries_OtherSecondary", m_sParticleType); 
+      m_numTracks_Secondaries_OtherSecondary_b = bookHistogram("numTracks_Secondaries_OtherSecondary_b", "numTracks_Secondaries_OtherSecondary", m_sParticleType, "b-jets -"); 
+      m_numTracks_Secondaries_OtherSecondary_c = bookHistogram("numTracks_Secondaries_OtherSecondary_c", "numTracks_Secondaries_OtherSecondary", m_sParticleType, "c-jets -"); 
+      m_numTracks_Secondaries_OtherSecondary_u = bookHistogram("numTracks_Secondaries_OtherSecondary_l", "numTracks_Secondaries_OtherSecondary", m_sParticleType, "l-jets -"); 
+      m_numTracks_Secondaries_OtherSecondary_muon = bookHistogram("numTracks_Secondaries_OtherSecondary_muon", "numTracks_Secondaries_OtherSecondary", m_sParticleType, "jets with muon -"); 
+
+      m_numTracks_OtherOrigin_incl = bookHistogram("numTracks_OtherOrigin_incl", "numTracks_OtherOrigin", m_sParticleType); 
+      m_numTracks_OtherOrigin_b = bookHistogram("numTracks_OtherOrigin_b", "numTracks_OtherOrigin", m_sParticleType, "b-jets -"); 
+      m_numTracks_OtherOrigin_c = bookHistogram("numTracks_OtherOrigin_c", "numTracks_OtherOrigin", m_sParticleType, "c-jets -"); 
+      m_numTracks_OtherOrigin_u = bookHistogram("numTracks_OtherOrigin_l", "numTracks_OtherOrigin", m_sParticleType, "l-jets -"); 
+      m_numTracks_OtherOrigin_muon = bookHistogram("numTracks_OtherOrigin_muon", "numTracks_OtherOrigin", m_sParticleType, "jets with muon -"); 
+    }
+
+    // tracker hits
+    m_nInnHits_incl = bookHistogram("nInnHits_incl", "nInnHits", m_sParticleType); 
+    m_nNextToInnHits_incl = bookHistogram("nNextToInnHits_incl", "nNextToInnHits", m_sParticleType);
+    m_nBLHits_incl = bookHistogram("nBLHits_incl", "nBLHits", m_sParticleType);
+    m_nsharedBLHits_incl = bookHistogram("nsharedBLHits_incl", "nsharedBLHits", m_sParticleType);
+    m_nsplitBLHits_incl = bookHistogram("nsplitBLHits_incl", "nsplitBLHits", m_sParticleType);
+    m_nPixHits_incl = bookHistogram("nPixHits_incl", "nPixHits", m_sParticleType);
+    m_nPixHoles_incl = bookHistogram("nPixHoles_incl", "nPixHoles", m_sParticleType);
+    m_nsharedPixHits_incl = bookHistogram("nsharedPixHits_incl", "nsharedPixHits", m_sParticleType);
+    m_nsplitPixHits_incl = bookHistogram("nsplitPixHits_incl", "nsplitPixHits", m_sParticleType);
+    m_nSCTHits_incl = bookHistogram("nSCTHits_incl", "nSCTHits", m_sParticleType);
+    m_nSCTHoles_incl = bookHistogram("nSCTHoles_incl", "nSCTHoles", m_sParticleType);
+    m_nsharedSCTHits_incl = bookHistogram("nsharedSCTHits_incl", "nsharedSCTHits", m_sParticleType);
+
+    m_nInnHits_b = bookHistogram("nInnHits_b", "nInnHits", m_sParticleType, "b-jets -"); 
+    m_nNextToInnHits_b = bookHistogram("nNextToInnHits_b", "nNextToInnHits", m_sParticleType, "b-jets -");
+    m_nBLHits_b = bookHistogram("nBLHits_b", "nBLHits", m_sParticleType, "b-jets -");
+    m_nsharedBLHits_b = bookHistogram("nsharedBLHits_b", "nsharedBLHits", m_sParticleType, "b-jets -");
+    m_nsplitBLHits_b = bookHistogram("nsplitBLHits_b", "nsplitBLHits", m_sParticleType, "b-jets -");
+    m_nPixHits_b = bookHistogram("nPixHits_b", "nPixHits", m_sParticleType, "b-jets -");
+    m_nPixHoles_b = bookHistogram("nPixHoles_b", "nPixHoles", m_sParticleType, "b-jets -");
+    m_nsharedPixHits_b = bookHistogram("nsharedPixHits_b", "nsharedPixHits", m_sParticleType, "b-jets -");
+    m_nsplitPixHits_b = bookHistogram("nsplitPixHits_b", "nsplitPixHits", m_sParticleType, "b-jets -");
+    m_nSCTHits_b = bookHistogram("nSCTHits_b", "nSCTHits", m_sParticleType, "b-jets -");
+    m_nSCTHoles_b = bookHistogram("nSCTHoles_b", "nSCTHoles", m_sParticleType, "b-jets -");
+    m_nsharedSCTHits_b = bookHistogram("nsharedSCTHits_b", "nsharedSCTHits", m_sParticleType, "b-jets -");
+
+    m_nInnHits_c = bookHistogram("nInnHits_c", "nInnHits", m_sParticleType, "c-jets -"); 
+    m_nNextToInnHits_c = bookHistogram("nNextToInnHits_c", "nNextToInnHits", m_sParticleType, "c-jets -");
+    m_nBLHits_c = bookHistogram("nBLHits_c", "nBLHits", m_sParticleType, "c-jets -");
+    m_nsharedBLHits_c = bookHistogram("nsharedBLHits_c", "nsharedBLHits", m_sParticleType, "c-jets -");
+    m_nsplitBLHits_c = bookHistogram("nsplitBLHits_c", "nsplitBLHits", m_sParticleType, "c-jets -");
+    m_nPixHits_c = bookHistogram("nPixHits_c", "nPixHits", m_sParticleType, "c-jets -");
+    m_nPixHoles_c = bookHistogram("nPixHoles_c", "nPixHoles", m_sParticleType, "c-jets -");
+    m_nsharedPixHits_c = bookHistogram("nsharedPixHits_c", "nsharedPixHits", m_sParticleType, "c-jets -");
+    m_nsplitPixHits_c = bookHistogram("nsplitPixHits_c", "nsplitPixHits", m_sParticleType, "c-jets -");
+    m_nSCTHits_c = bookHistogram("nSCTHits_c", "nSCTHits", m_sParticleType, "c-jets -");
+    m_nSCTHoles_c = bookHistogram("nSCTHoles_c", "nSCTHoles", m_sParticleType, "c-jets -");
+    m_nsharedSCTHits_c = bookHistogram("nsharedSCTHits_c", "nsharedSCTHits", m_sParticleType, "c-jets -");
+
+    m_nInnHits_u = bookHistogram("nInnHits_l", "nInnHits", m_sParticleType, "l-jets -"); 
+    m_nNextToInnHits_u = bookHistogram("nNextToInnHits_l", "nNextToInnHits", m_sParticleType, "l-jets -");
+    m_nBLHits_u = bookHistogram("nBLHits_l", "nBLHits", m_sParticleType, "l-jets -");
+    m_nsharedBLHits_u = bookHistogram("nsharedBLHits_l", "nsharedBLHits", m_sParticleType, "l-jets -");
+    m_nsplitBLHits_u = bookHistogram("nsplitBLHits_l", "nsplitBLHits", m_sParticleType, "l-jets -");
+    m_nPixHits_u = bookHistogram("nPixHits_l", "nPixHits", m_sParticleType, "l-jets -");
+    m_nPixHoles_u = bookHistogram("nPixHoles_l", "nPixHoles", m_sParticleType, "l-jets -");
+    m_nsharedPixHits_u = bookHistogram("nsharedPixHits_l", "nsharedPixHits", m_sParticleType, "l-jets -");
+    m_nsplitPixHits_u = bookHistogram("nsplitPixHits_l", "nsplitPixHits", m_sParticleType, "l-jets -");
+    m_nSCTHits_u = bookHistogram("nSCTHits_l", "nSCTHits", m_sParticleType, "l-jets -");
+    m_nSCTHoles_u = bookHistogram("nSCTHoles_l", "nSCTHoles", m_sParticleType, "l-jets -");
+    m_nsharedSCTHits_u = bookHistogram("nsharedSCTHits_l", "nsharedSCTHits", m_sParticleType, "l-jets -");
+
+    m_nInnHits_muon = bookHistogram("nInnHits_muon", "nInnHits", m_sParticleType, "jets with muon -"); 
+    m_nNextToInnHits_muon = bookHistogram("nNextToInnHits_muon", "nNextToInnHits", m_sParticleType, "jets with muon -");
+    m_nBLHits_muon = bookHistogram("nBLHits_muon", "nBLHits", m_sParticleType, "jets with muon -");
+    m_nsharedBLHits_muon = bookHistogram("nsharedBLHits_muon", "nsharedBLHits", m_sParticleType, "jets with muon -");
+    m_nsplitBLHits_muon = bookHistogram("nsplitBLHits_muon", "nsplitBLHits", m_sParticleType, "jets with muon -");
+    m_nPixHits_muon = bookHistogram("nPixHits_muon", "nPixHits", m_sParticleType, "jets with muon -");
+    m_nPixHoles_muon = bookHistogram("nPixHoles_muon", "nPixHoles", m_sParticleType, "jets with muon -");
+    m_nsharedPixHits_muon = bookHistogram("nsharedPixHits_muon", "nsharedPixHits", m_sParticleType, "jets with muon -");
+    m_nsplitPixHits_muon = bookHistogram("nsplitPixHits_muon", "nsplitPixHits", m_sParticleType, "jets with muon -");
+    m_nSCTHits_muon = bookHistogram("nSCTHits_muon", "nSCTHits", m_sParticleType, "jets with muon -");
+    m_nSCTHoles_muon = bookHistogram("nSCTHoles_muon", "nSCTHoles", m_sParticleType, "jets with muon -");
+    m_nsharedSCTHits_muon = bookHistogram("nsharedSCTHits_muon", "nsharedSCTHits", m_sParticleType, "jets with muon -");
+
+    // tagger
+    m_IP3D_pb = bookHistogram("IP3D_pb", "IP3D_pb", m_sParticleType);
+    m_IP3D_pc = bookHistogram("IP3D_pc", "IP3D_pc", m_sParticleType);
+    m_IP3D_pu = bookHistogram("IP3D_pu", "IP3D_pu", m_sParticleType);
+
+    m_RNNIP_pb = bookHistogram("RNNIP_pb", "RNNIP_pb", m_sParticleType);
+    m_RNNIP_pc = bookHistogram("RNNIP_pc", "RNNIP_pc", m_sParticleType);
+    m_RNNIP_pu = bookHistogram("RNNIP_pu", "RNNIP_pu", m_sParticleType);
+
+    m_SV1_pb = bookHistogram("SV1_pb", "SV1_pb", m_sParticleType);
+    m_SV1_pc = bookHistogram("SV1_pc", "SV1_pc", m_sParticleType);
+    m_SV1_pu = bookHistogram("SV1_pu", "SV1_pu", m_sParticleType);
+    
+    m_IP3D_nTracks_incl = bookHistogram("IP3D_NTracks_incl", "IP3D_nTracks", m_sParticleType);
+    m_IP3D_nTracks_b = bookHistogram("IP3D_NTracks_b", "IP3D_nTracks", m_sParticleType, "b-jets -");
+    m_IP3D_nTracks_c = bookHistogram("IP3D_NTracks_c", "IP3D_nTracks", m_sParticleType, "c-jets -");
+    m_IP3D_nTracks_l = bookHistogram("IP3D_NTracks_l", "IP3D_nTracks", m_sParticleType, "l-jets -");
+    m_IP3D_nTracks_muon = bookHistogram("IP3D_NTracks_muon", "IP3D_nTracks", m_sParticleType, "jets with moun -");
+
+    m_IP2D_nTracks_incl = bookHistogram("IP2D_NTracks_incl", "IP2D_nTracks", m_sParticleType);
+    m_IP2D_nTracks_b = bookHistogram("IP2D_NTracks_b", "IP2D_nTracks", m_sParticleType, "b-jets -");
+    m_IP2D_nTracks_c = bookHistogram("IP2D_NTracks_c", "IP2D_nTracks", m_sParticleType, "c-jets -");
+    m_IP2D_nTracks_l = bookHistogram("IP2D_NTracks_l", "IP2D_nTracks", m_sParticleType, "l-jets -");
+    m_IP2D_nTracks_muon = bookHistogram("IP2D_NTracks_muon", "IP2D_nTracks", m_sParticleType, "jets with moun -");
+
+    //m_SV0_NGTinSvx = bookHistogram("SV0_nGoodTracks", "SV0_nGoodTracks");        
+    m_nGTinSV1_incl = bookHistogram("SV1_nGoodTracks_incl", "SV1_nGoodTracks", m_sParticleType);
+    m_nGTinSV1_b = bookHistogram("SV1_nGoodTracks_b", "SV1_nGoodTracks", m_sParticleType, "b-jets -");
+    m_nGTinSV1_c = bookHistogram("SV1_nGoodTracks_c", "SV1_nGoodTracks", m_sParticleType, "c-jets -");
+    m_nGTinSV1_l = bookHistogram("SV1_nGoodTracks_l", "SV1_nGoodTracks", m_sParticleType, "l-jets -");
+    m_nGTinSV1_muon = bookHistogram("SV1_nGoodTracks_muon", "SV1_nGoodTracks", m_sParticleType, "jets with muon -");
+
+    m_DL1_pb = bookHistogram("DL1_pb", "DL1_pb", m_sParticleType);
+    m_DL1_pc = bookHistogram("DL1_pc", "DL1_pc", m_sParticleType);
+    m_DL1_pu = bookHistogram("DL1_pu", "DL1_pu", m_sParticleType);
+    m_DL1r_pb = bookHistogram("DL1r_pb", "DL1r_pb", m_sParticleType);
+    m_DL1r_pc = bookHistogram("DL1r_pc", "DL1r_pc", m_sParticleType);
+    m_DL1r_pu = bookHistogram("DL1r_pu", "DL1r_pu", m_sParticleType);
+
+    m_IP3D_gradeOfTracks_incl = bookHistogram("IP3D_gradeOfTracks_incl", "IP3D_gradeOfTracks", m_sParticleType);
+    m_IP2D_gradeOfTracks_incl = bookHistogram("IP2D_gradeOfTracks_incl", "IP2D_gradeOfTracks", m_sParticleType);
+    m_IP3D_gradeOfTracks_b = bookHistogram("IP3D_gradeOfTracks_b", "IP3D_gradeOfTracks", m_sParticleType, "b-jets -");
+    m_IP2D_gradeOfTracks_b = bookHistogram("IP2D_gradeOfTracks_b", "IP2D_gradeOfTracks", m_sParticleType, "b-jets -");
+    m_IP3D_gradeOfTracks_c = bookHistogram("IP3D_gradeOfTracks_c", "IP3D_gradeOfTracks", m_sParticleType, "c-jets -");
+    m_IP2D_gradeOfTracks_c = bookHistogram("IP2D_gradeOfTracks_c", "IP2D_gradeOfTracks", m_sParticleType, "c-jets -");
+    m_IP3D_gradeOfTracks_l = bookHistogram("IP3D_gradeOfTracks_l", "IP3D_gradeOfTracks", m_sParticleType, "l-jets -");
+    m_IP2D_gradeOfTracks_l = bookHistogram("IP2D_gradeOfTracks_l", "IP2D_gradeOfTracks", m_sParticleType, "l-jets -");
+    m_IP3D_gradeOfTracks_muon = bookHistogram("IP3D_gradeOfTracks_muon", "IP3D_gradeOfTracks", m_sParticleType, "jets with muon -");
+    m_IP2D_gradeOfTracks_muon = bookHistogram("IP2D_gradeOfTracks_muon", "IP2D_gradeOfTracks", m_sParticleType, "jets with muon -");
+
+    m_tmpD0 = bookHistogram("IP3D_valD0wrtPVofTracks", "IP3D_d0wrtPVOfTracks", m_sParticleType);
+    m_tmpZ0 = bookHistogram("IP3D_valZ0wrtPVofTracks", "IP3D_z0wrtPVOfTracks", m_sParticleType);
+    m_tmpD0sig = bookHistogram("IP3D_sigD0wrtPVofTracks", "IP3D_sigD0wrtPVOfTracks", m_sParticleType);
+    m_tmpZ0sig = bookHistogram("IP3D_sigZ0wrtPVofTracks", "IP3D_sigZ0wrtPVOfTracks", m_sParticleType);
+    m_IP3D_weightBofTracks = bookHistogram("IP3D_weightBofTracks", "IP3D_weightBOfTracks", m_sParticleType);
+    m_IP3D_weightCofTracks = bookHistogram("IP3D_weightCofTracks", "IP3D_weightCOfTracks", m_sParticleType);
+    m_IP3D_weightUofTracks = bookHistogram("IP3D_weightUofTracks", "IP3D_weightUOfTracks", m_sParticleType);
+    m_IP2D_weightBofTracks = bookHistogram("IP2D_weightBofTracks", "IP2D_weightBOfTracks", m_sParticleType);
+    m_IP2D_weightCofTracks = bookHistogram("IP2D_weightCofTracks", "IP2D_weightCOfTracks", m_sParticleType);
+    m_IP2D_weightUofTracks = bookHistogram("IP2D_weightUofTracks", "IP2D_weightUOfTracks", m_sParticleType);    
+
+    // B hadron Lxy
+    m_Truth_Lxy_b = bookHistogram("Truth_Lxy_b", "Truth_Lxy_b", m_sParticleType, "b-jets - ");
+    m_Truth_Lxy_c = bookHistogram("Truth_Lxy_c", "Truth_Lxy_c", m_sParticleType, "c-jets - ");
+
+    // B hadron deltaR wrt jet 
+    m_deltaR_truthBHadron_jet_b = bookHistogram("deltaR_truthBHadronJet_b", "deltaR_truthBHadronJet_b", m_sParticleType, "b-jets - ");
+    m_deltaR_truthCHadron_jet_c = bookHistogram("deltaR_truthCHadronJet_c", "deltaR_truthCHadronJet_c", m_sParticleType, "c-jets - ");
+
+  }
+
+
+  // a fill method for the multiplicities
+  void BTaggingValidationPlots::fillMultiplicities(const unsigned int& nJets, const unsigned int& nTracks, const int& nPrimVtx, const unsigned int& nTracksPrimVtx, const unsigned int& nJetsWithMuon, const unsigned int& nJetsWithSV, std::map<std::string, int>& nJetsThatPassedWPCuts, const xAOD::EventInfo* event){
+    m_nJets->Fill(nJets, event->beamSpotWeight());
+    m_nTracks->Fill(nTracks, event->beamSpotWeight());
+    m_nPrimVtx->Fill(nPrimVtx, event->beamSpotWeight());
+    m_nTracksPrimVtx->Fill(nTracksPrimVtx, event->beamSpotWeight());
+    m_nJetsWithMuon->Fill(nJetsWithMuon, event->beamSpotWeight());
+    m_nJetsWithSV->Fill(nJetsWithSV, event->beamSpotWeight());
+
+    double fracJetsWithMuon = static_cast<double>(nJetsWithMuon) / nJets;
+    double fracJetsWithSV = static_cast<double>(nJetsWithSV) / nJets;
+    m_fracJetsWithMuon->Fill(fracJetsWithMuon, event->beamSpotWeight());
+    m_fracJetsWithSV->Fill(fracJetsWithSV, event->beamSpotWeight());
+
+    fillNJetsThatPassedWPCutsHistos(nJetsThatPassedWPCuts, event);
+  }
+
+  // a fill method for the PV variables
+  void BTaggingValidationPlots::fillPVVariables(const double& PV_x, const double& PV_y, const double& PV_z, const xAOD::EventInfo* event){
+    m_PV_x->Fill(PV_x, event->beamSpotWeight());
+    m_PV_y->Fill(PV_y, event->beamSpotWeight());
+    m_PV_z->Fill(PV_z, event->beamSpotWeight());
+  }
+
+  // a fill method for the jet kinematic vars
+  void BTaggingValidationPlots::fillJetKinVars(const xAOD::Jet* jet, const int& truth_label, const bool& onZprime, const xAOD::EventInfo* event){
+    TH1* dummy = nullptr;
+    // jet kin vars
+    // pT
+    if(onZprime){
+      BTaggingValidationPlots::fillHistoWithTruthCases(jet->pt()/GeV, m_jet_pt_Zprime, m_jet_pt_Zprime_b, m_jet_pt_Zprime_c, m_jet_pt_Zprime_l, dummy, truth_label, false, event);
+      m_jet_e_Zprime->Fill(jet->e()/GeV, event->beamSpotWeight());
+    } else {
+      BTaggingValidationPlots::fillHistoWithTruthCases(jet->pt()/GeV, m_jet_pt, m_jet_pt_b, m_jet_pt_c, m_jet_pt_l, dummy, truth_label, false, event);
+      m_jet_e->Fill(jet->e()/GeV, event->beamSpotWeight());
+    }
+    // eta and phi
+    BTaggingValidationPlots::fillHistoWithTruthCases(jet->eta(), m_jet_eta, m_jet_eta_b, m_jet_eta_c, m_jet_eta_l, dummy, truth_label, false, event);
+    m_jet_phi->Fill(jet->phi(), event->beamSpotWeight());
+
+    // fill the truth label
+    m_truthLabel->Fill(truth_label, event->beamSpotWeight());
+  }
+
+
+  // a fill method for variables that have no other home
+  void BTaggingValidationPlots::fillOther(const xAOD::Jet* jet, const xAOD::BTagging* btag, bool& contains_muon, double& jet_Lxy, const int& truth_label, const xAOD::EventInfo* event){
+
+    // Lxy: take value of B hadron for b jets, of C hadron for c jets and the SV1 Lxy value for light jets
+    double Lxy(-1);
+    if(!m_isData){
+
+      // Lxy of B hadron for b jets
+      if(truth_label == 5){
+        // get the B hadrons
+        std::vector<const xAOD::TruthParticle*> BHadrons;
+        const std::string labelB = "ConeExclBHadronsFinal"; // = "GhostBHadronsFinal"; // alternative association scheme
+        jet->getAssociatedObjects<xAOD::TruthParticle>(labelB, BHadrons);
+        // get the Lxy
+        if(BHadrons.size() >= 1){
+          // get the Lxy
+          Lxy = BHadrons[0]->decayVtx()->perp();
+          m_Truth_Lxy_b ->Fill(Lxy, event->beamSpotWeight());
+          // get the deltaR wrt to the jet axis
+          double dR = jet->p4().DeltaR(BHadrons[0]->p4());
+          m_deltaR_truthBHadron_jet_b->Fill(dR, event->beamSpotWeight());
+        }
+      }
+  
+      // Lxy of C hadron for c jets
+      else if(truth_label == 4){
+        // get the C hadrons
+        std::vector<const xAOD::TruthParticle*> CHadrons;
+        const std::string labelC = "ConeExclCHadronsFinal"; // = "GhostCHadronsFinal"; // alternative association scheme
+        jet->getAssociatedObjects<xAOD::TruthParticle>(labelC, CHadrons);
+        // get the Lxy
+        if(CHadrons.size() >= 1){
+          // get the Lxy
+          Lxy = CHadrons[0]->decayVtx()->perp();
+          m_Truth_Lxy_c ->Fill(Lxy, event->beamSpotWeight());
+          // get the deltaR wrt to the jet axis
+          double dR = jet->p4().DeltaR(CHadrons[0]->p4());
+          m_deltaR_truthCHadron_jet_c->Fill(dR, event->beamSpotWeight());
+        }
+      }
+
+      // SV1 Lxy for light jets
+      else if(truth_label == 0){
+        Lxy = btag->auxdata<float>("SV1_Lxy");
+      }
+    }
+
+    // fill jet Lxy for the caller of the method
+    jet_Lxy = Lxy;
+
+    // check if there is a muon and store the relative muon pT
+    bool has_muon = false;
+    ElementLink<xAOD::MuonContainer> muonLink = btag->auxdata< ElementLink<xAOD::MuonContainer> >("SMT_mu_link");
+    if ( muonLink.isValid() ) {
+        const xAOD::Muon* muon=(*muonLink);
+        if ( muon != 0 ) {
+            has_muon = true;
+            double muon_pT_frac = muon->pt() / jet->pt();
+            m_muon_pT_frac->Fill(muon_pT_frac, event->beamSpotWeight());
+        }
+    }
+    // fill contains_muon for the caller of this function
+    contains_muon = has_muon;
+  }
+
+
+  // a fill method for track related vars
+  void BTaggingValidationPlots::fillTrackVariables(const xAOD::Jet* jet, const xAOD::BTagging* btag, const xAOD::Vertex *myVertex, std::map<const xAOD::TrackParticle*, int> track_truth_associations, const bool& has_muon, const int& truth_label, int& num_HF_tracks_in_jet, const xAOD::EventInfo* event){
+
+    // get the jet TLorentzVector
+    TLorentzVector jet_tlv;
+    jet_tlv.SetPtEtaPhiE(jet->pt(), jet->eta(), jet->phi(), jet->e());
+
+    // get the assocated tracks
+    std::vector< ElementLink< xAOD::TrackParticleContainer > > assocTracks = btag->auxdata<std::vector<ElementLink<xAOD::TrackParticleContainer> > >("BTagTrackToJetAssociator");
+
+    int numTracks_perJet = 0;
+    int numTracks_fromB = 0;
+    int numTracks_fromC = 0;
+    int numTracks_fromFragmentation = 0;
+    int numTracks_fromSecondaries = 0;
+    int numTracks_fromPileup = 0;
+    int numTracks_fromFake = 0;
+
+    // these are only filled for detail level above 10
+    int numTracks_Secondaries_KshortDecay = 0; 
+    int numTracks_Secondaries_LambdaDecay = 0; 
+    int numTracks_Secondaries_GammaConversion = 0; 
+    int numTracks_Secondaries_OtherDecay = 0; 
+    int numTracks_Secondaries_HadronicInteraction = 0; 
+    int numTracks_Secondaries_OtherSecondary = 0; 
+    int numTracks_OtherOrigin = 0; 
+
+    // loop over tracks
+    for (unsigned int iT=0; iT<assocTracks.size(); iT++) {
+      if (!assocTracks.at(iT).isValid()) continue;
+
+      // count the number of tracks per jet
+      numTracks_perJet++;
+
+      // get the curent track
+      const xAOD::TrackParticle* track = *(assocTracks.at(iT));         
+
+      // get the track origin
+      int track_origin = -1;
+      if(!m_isData){
+        track_origin = track_truth_associations.at(track);
+      }
+
+      // count the tracks sorted by origin (the TrkOrigin enum is defined here: https://gitlab.cern.ch/atlas/athena/-/blob/master/PhysicsAnalysis/TrackingID/InDetTrackSystematicsTools/InDetTrackSystematicsTools/InDetTrackTruthOriginDefs.h#L14)
+      if( InDet::TrkOrigin::isFromB(track_origin) ) numTracks_fromB++;
+      if( InDet::TrkOrigin::isFromD(track_origin) ) numTracks_fromC++;
+      if( InDet::TrkOrigin::isFragmentation(track_origin) ) numTracks_fromFragmentation++;
+      if( InDet::TrkOrigin::isSecondary(track_origin) ) numTracks_fromSecondaries++;
+      if( InDet::TrkOrigin::isPileup(track_origin) ) numTracks_fromPileup++;
+      if( InDet::TrkOrigin::isFake(track_origin) ) numTracks_fromFake++;
+
+      if(m_detailLevel > 10){
+        if( track_origin & (0x1 << InDet::TrkOrigin::KshortDecay) ) numTracks_Secondaries_KshortDecay++; 
+        if( track_origin & (0x1 << InDet::TrkOrigin::LambdaDecay) ) numTracks_Secondaries_LambdaDecay++; 
+        if( track_origin & (0x1 << InDet::TrkOrigin::GammaConversion) ) numTracks_Secondaries_GammaConversion++; 
+        if( track_origin & (0x1 << InDet::TrkOrigin::OtherDecay) ) numTracks_Secondaries_OtherDecay++; 
+        if( track_origin & (0x1 << InDet::TrkOrigin::HadronicInteraction) ) numTracks_Secondaries_HadronicInteraction++; 
+        if( track_origin & (0x1 << InDet::TrkOrigin::OtherSecondary) ) numTracks_Secondaries_OtherSecondary++; 
+        if( track_origin & (0x1 << InDet::TrkOrigin::OtherOrigin) ) numTracks_OtherOrigin++; 
+      }
+
+      // get the track also as TLorentzVector
+      TLorentzVector track_tlv;
+      track_tlv.SetPtEtaPhiE(track->pt(), track->eta(), track->phi(), track->e());
+
+      // get the DeltaR between the track and the jet
+      double DeltaR_jet_track = jet_tlv.DeltaR(track_tlv);
+
+      // get the IPs and IP significances
+      double d0(1000), z0(1000), sigma_d0(1000), sigma_z0(1000);                
+      d0 = track->d0();
+      z0 = track->z0() + track->vz() - myVertex->z(); //ANDREA: track->z0() is defined wrt the beam spot-> Get it wrt the PV
+      //z0 = track->z0(); //Naive z0 wrt the beam spot
+      sigma_d0 = sqrt(track->definingParametersCovMatrixVec().at(0)); 
+      sigma_z0 = sqrt(track->definingParametersCovMatrixVec().at(2));
+
+      // calculate pT_frac
+      double pT_frac(2), pT_jet(-1), pT_track(-1);
+      pT_jet = jet->pt();
+      pT_track = track->pt();
+      pT_frac = pT_track / pT_jet;
+
+      // get the tracker hits, following this approach: https://gitlab.cern.ch/atlas-flavor-tagging-tools/FlavourTagPerformanceFramework/-/blob/50e0d05c4d855935ebac2bf07622cccf709eea18/btagAnalysis/src/TrackBranches.cxx#L331
+      int nInnHits = getTrackHits(*track, xAOD::numberOfInnermostPixelLayerHits);
+      int nNextToInnHits = getTrackHits(*track, xAOD::numberOfNextToInnermostPixelLayerHits);
+      int nBLHits = getTrackHits(*track, xAOD::numberOfBLayerHits);
+      int nsharedBLHits = getTrackHits(*track, xAOD::numberOfBLayerSharedHits);
+      int nsplitBLHits = getTrackHits(*track, xAOD::numberOfBLayerSplitHits);
+      int nPixHits = getTrackHits(*track, xAOD::numberOfPixelHits);
+      int nPixHoles = getTrackHits(*track, xAOD::numberOfPixelHoles);
+      int nsharedPixHits = getTrackHits(*track, xAOD::numberOfPixelSharedHits);
+      int nsplitPixHits = getTrackHits(*track, xAOD::numberOfPixelSplitHits);
+      int nSCTHits = getTrackHits(*track, xAOD::numberOfSCTHits);
+      int nSCTHoles = getTrackHits(*track, xAOD::numberOfSCTHoles);
+      int nsharedSCTHits = getTrackHits(*track, xAOD::numberOfSCTSharedHits);
+
+      // fill the histogram
+      BTaggingValidationPlots::fillHistoWithTruthCases(d0, m_track_d0_incl, m_track_d0_b, m_track_d0_c, m_track_d0_u, m_track_d0_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(z0, m_track_z0_incl, m_track_z0_b, m_track_z0_c, m_track_z0_u, m_track_z0_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(d0/sigma_d0, m_track_sigd0_incl, m_track_sigd0_b, m_track_sigd0_c, m_track_sigd0_u, m_track_sigd0_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(z0/sigma_z0, m_track_sigz0_incl, m_track_sigz0_b, m_track_sigz0_c, m_track_sigz0_u, m_track_sigz0_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(pT_frac, m_track_pT_frac_incl, m_track_pT_frac_b, m_track_pT_frac_c, m_track_pT_frac_u, m_track_pT_frac_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(DeltaR_jet_track, m_DeltaR_jet_track_incl, m_DeltaR_jet_track_b, m_DeltaR_jet_track_c, m_DeltaR_jet_track_u, m_DeltaR_jet_track_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(nInnHits, m_nInnHits_incl, m_nInnHits_b, m_nInnHits_c, m_nInnHits_u, m_nInnHits_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(nNextToInnHits, m_nNextToInnHits_incl, m_nNextToInnHits_b, m_nNextToInnHits_c, m_nNextToInnHits_u, m_nNextToInnHits_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(nBLHits, m_nBLHits_incl, m_nBLHits_b, m_nBLHits_c, m_nBLHits_u, m_nBLHits_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(nsharedBLHits, m_nsharedBLHits_incl, m_nsharedBLHits_b, m_nsharedBLHits_c, m_nsharedBLHits_u, m_nsharedBLHits_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(nsplitBLHits, m_nsplitBLHits_incl, m_nsplitBLHits_b, m_nsplitBLHits_c, m_nsplitBLHits_u, m_nsplitBLHits_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(nPixHits, m_nPixHits_incl, m_nPixHits_b, m_nPixHits_c, m_nPixHits_u, m_nPixHits_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(nPixHoles, m_nPixHoles_incl, m_nPixHoles_b, m_nPixHoles_c, m_nPixHoles_u, m_nPixHoles_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(nsharedPixHits, m_nsharedPixHits_incl, m_nsharedPixHits_b, m_nsharedPixHits_c, m_nsharedPixHits_u, m_nsharedPixHits_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(nsplitPixHits, m_nsplitPixHits_incl, m_nsplitPixHits_b, m_nsplitPixHits_c, m_nsplitPixHits_u, m_nsplitPixHits_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(nSCTHits, m_nSCTHits_incl, m_nSCTHits_b, m_nSCTHits_c, m_nSCTHits_u, m_nSCTHits_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(nSCTHoles, m_nSCTHoles_incl, m_nSCTHoles_b, m_nSCTHoles_c, m_nSCTHoles_u, m_nSCTHoles_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(nsharedSCTHits, m_nsharedSCTHits_incl, m_nsharedSCTHits_b, m_nsharedSCTHits_c, m_nsharedSCTHits_u, m_nsharedSCTHits_muon, truth_label, has_muon, event);
+
+    }    // end loop over tracks
+
+    // store the number of tracks var
+    BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_perJet, m_numTracks_perJet_incl, m_numTracks_perJet_b, m_numTracks_perJet_c, m_numTracks_perJet_u, m_numTracks_perJet_muon, truth_label, has_muon, event);
+
+    if(!m_isData){
+      num_HF_tracks_in_jet = numTracks_fromB + numTracks_fromC;
+      BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_fromB, m_numTracks_B_incl, m_numTracks_B_b, m_numTracks_B_c, m_numTracks_B_u, m_numTracks_B_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_fromC, m_numTracks_C_incl, m_numTracks_C_b, m_numTracks_C_c, m_numTracks_C_u, m_numTracks_C_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_fromFragmentation, m_numTracks_Fragmentation_incl, m_numTracks_Fragmentation_b, m_numTracks_Fragmentation_c, m_numTracks_Fragmentation_u, m_numTracks_Fragmentation_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_fromSecondaries, m_numTracks_Secondaries_incl, m_numTracks_Secondaries_b, m_numTracks_Secondaries_c, m_numTracks_Secondaries_u, m_numTracks_Secondaries_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_fromPileup, m_numTracks_Pileup_incl, m_numTracks_Pileup_b, m_numTracks_Pileup_c, m_numTracks_Pileup_u, m_numTracks_Pileup_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_fromFake, m_numTracks_Fake_incl, m_numTracks_Fake_b, m_numTracks_Fake_c, m_numTracks_Fake_u, m_numTracks_Fake_muon, truth_label, has_muon, event);
+
+      if(m_detailLevel > 10){
+        BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_Secondaries_KshortDecay, m_numTracks_Secondaries_KshortDecay_incl, m_numTracks_Secondaries_KshortDecay_b, m_numTracks_Secondaries_KshortDecay_c, m_numTracks_Secondaries_KshortDecay_u, m_numTracks_Secondaries_KshortDecay_muon, truth_label, has_muon, event); 
+        BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_Secondaries_LambdaDecay, m_numTracks_Secondaries_LambdaDecay_incl, m_numTracks_Secondaries_LambdaDecay_b, m_numTracks_Secondaries_LambdaDecay_c, m_numTracks_Secondaries_LambdaDecay_u, m_numTracks_Secondaries_LambdaDecay_muon, truth_label, has_muon, event); 
+        BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_Secondaries_GammaConversion, m_numTracks_Secondaries_GammaConversion_incl, m_numTracks_Secondaries_GammaConversion_b, m_numTracks_Secondaries_GammaConversion_c, m_numTracks_Secondaries_GammaConversion_u, m_numTracks_Secondaries_GammaConversion_muon, truth_label, has_muon, event); 
+        BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_Secondaries_OtherDecay, m_numTracks_Secondaries_OtherDecay_incl, m_numTracks_Secondaries_OtherDecay_b, m_numTracks_Secondaries_OtherDecay_c, m_numTracks_Secondaries_OtherDecay_u, m_numTracks_Secondaries_OtherDecay_muon, truth_label, has_muon, event); 
+        BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_Secondaries_HadronicInteraction, m_numTracks_Secondaries_HadronicInteraction_incl, m_numTracks_Secondaries_HadronicInteraction_b, m_numTracks_Secondaries_HadronicInteraction_c, m_numTracks_Secondaries_HadronicInteraction_u, m_numTracks_Secondaries_HadronicInteraction_muon, truth_label, has_muon, event); 
+        BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_Secondaries_OtherSecondary, m_numTracks_Secondaries_OtherSecondary_incl, m_numTracks_Secondaries_OtherSecondary_b, m_numTracks_Secondaries_OtherSecondary_c, m_numTracks_Secondaries_OtherSecondary_u, m_numTracks_Secondaries_OtherSecondary_muon, truth_label, has_muon, event); 
+        BTaggingValidationPlots::fillHistoWithTruthCases(numTracks_OtherOrigin, m_numTracks_OtherOrigin_incl, m_numTracks_OtherOrigin_b, m_numTracks_OtherOrigin_c, m_numTracks_OtherOrigin_u, m_numTracks_OtherOrigin_muon, truth_label, has_muon, event); 
+      }
+    }
+
+    m_numTracks_perJet_vs_pT_incl ->Fill(jet->pt()/GeV, numTracks_perJet, event->beamSpotWeight());
+    if(!m_isData && truth_label == 5) {
+      m_numTracks_perJet_vs_pT_b ->Fill(jet->pt()/GeV, numTracks_perJet, event->beamSpotWeight());
+    }
+    else if(!m_isData && truth_label == 4) {
+      m_numTracks_perJet_vs_pT_c ->Fill(jet->pt()/GeV, numTracks_perJet, event->beamSpotWeight());
+    }
+    else if(!m_isData && truth_label == 0) {
+      m_numTracks_perJet_vs_pT_u ->Fill(jet->pt()/GeV, numTracks_perJet, event->beamSpotWeight());
+    }
+    if(has_muon) {
+      m_numTracks_perJet_vs_pT_muon ->Fill(jet->pt()/GeV, numTracks_perJet, event->beamSpotWeight());
+    }
+
+  }
+
+
+  // a fill method for SV related vars
+  void BTaggingValidationPlots::fillSVVariables(const xAOD::Jet* jet, const xAOD::BTagging* btag, std::map<const xAOD::TrackParticle*, int> track_truth_associations, const bool& has_muon, const int& truth_label, const int& num_HF_tracks_in_jet, bool& contains_SV, const xAOD::EventInfo* event){
+    // SV1
+
+    // SV1 mass of the SV
+    float SV1_masssvx;
+    try{ btag->taggerInfo(SV1_masssvx, xAOD::SV1_masssvx); }
+    catch(std::exception& exception){ SV1_masssvx = -1; }
+
+    // SV1 number of two-track vertices
+    int SV1_N2Tpair;
+    try{ btag->taggerInfo(SV1_N2Tpair, xAOD::SV1_N2Tpair); }
+    catch(std::exception& exception){ SV1_N2Tpair = -1; }
+
+    // SV1 energy fraction
+    float SV1_efracsvx;
+    try{ btag->taggerInfo(SV1_efracsvx, xAOD::SV1_efracsvx); }
+    catch(std::exception& exception){ SV1_efracsvx = -1; }
+
+    // SV1 deltaR jex axis - PV-SV
+    float SV1_deltaR = btag->auxdata<float>("SV1_deltaR");
+
+    // SV1 significance 3d
+    float SV1_significance3d = btag->auxdata<float>("SV1_significance3d");
+
+    // SV1 energyTrkInJet
+    float SV1_energyTrkInJet = btag->auxdata<float>("SV1_energyTrkInJet");
+
+    // SV1 NGTinSvx 
+    int SV1_NGTinSvx = btag->auxdata<int>("SV1_NGTinSvx");
+
+    // SV1 Lxy 
+    float SV1_Lxy = btag->auxdata<float>("SV1_Lxy");
+
+    // SV1 track origing related variables (have them double such that taking a fraction doesn't result in an int)
+    double SV1_numTracks = 0;
+    double SV1_numTracks_fromB = 0;
+    double SV1_numTracks_fromC = 0;
+    double SV1_numTracks_fromFragmentation = 0;
+    double SV1_numTracks_fromSecondaries = 0;
+    double SV1_numTracks_fromPileup = 0;
+    double SV1_numTracks_fromFake = 0;
+
+    // these are only filled for detail level above 10
+    double SV1_numTracks_Secondaries_KshortDecay = 0; 
+    double SV1_numTracks_Secondaries_LambdaDecay = 0; 
+    double SV1_numTracks_Secondaries_GammaConversion = 0; 
+    double SV1_numTracks_Secondaries_OtherDecay = 0; 
+    double SV1_numTracks_Secondaries_HadronicInteraction = 0; 
+    double SV1_numTracks_Secondaries_OtherSecondary = 0; 
+    double SV1_numTracks_OtherOrigin = 0; 
+
+    // get the SV1 vertex
+    std::vector< ElementLink< xAOD::VertexContainer > > SV1_vertex = btag->auxdata<std::vector< ElementLink< xAOD::VertexContainer > > >("SV1_vertices");
+
+    if(SV1_vertex.size() >= 1) contains_SV = true;
+    else contains_SV = false;
+
+    // loop over the vertices
+    for (unsigned int i = 0; i < SV1_vertex.size(); i++) {
+      if (!SV1_vertex.at(i).isValid()) continue;
+      const xAOD::Vertex* vtx = *(SV1_vertex.at(i));
+
+      // get the track links
+      std::vector<ElementLink<DataVector<xAOD::TrackParticle> > > tpLinks = vtx->trackParticleLinks();
+
+      // loop over the tracks
+      for (ElementLink<DataVector<xAOD::TrackParticle> > link : tpLinks) {
+        const xAOD::TrackParticle* track = (*link);
+
+        // get the track origin
+        int track_origin = -1;
+        if(!m_isData){
+          track_origin = track_truth_associations.at(track);
+        }
+
+        // count the tracks sorted by origin (the TrkOrigin enum is defined here: https://gitlab.cern.ch/atlas/athena/-/blob/master/PhysicsAnalysis/TrackingID/InDetTrackSystematicsTools/InDetTrackSystematicsTools/InDetTrackTruthOriginDefs.h#L14)
+        if( InDet::TrkOrigin::isFromB(track_origin) ) SV1_numTracks_fromB++;
+        if( InDet::TrkOrigin::isFromD(track_origin) ) SV1_numTracks_fromC++;
+        if( InDet::TrkOrigin::isFragmentation(track_origin) ) SV1_numTracks_fromFragmentation++;
+        if( InDet::TrkOrigin::isSecondary(track_origin) ) SV1_numTracks_fromSecondaries++;
+        if( InDet::TrkOrigin::isPileup(track_origin) ) SV1_numTracks_fromPileup++;
+        if( InDet::TrkOrigin::isFake(track_origin) ) SV1_numTracks_fromFake++;
+        
+        if(m_detailLevel > 10){
+          if( track_origin & (0x1 << InDet::TrkOrigin::KshortDecay) ) SV1_numTracks_Secondaries_KshortDecay++; 
+          if( track_origin & (0x1 << InDet::TrkOrigin::LambdaDecay) ) SV1_numTracks_Secondaries_LambdaDecay++; 
+          if( track_origin & (0x1 << InDet::TrkOrigin::GammaConversion) ) SV1_numTracks_Secondaries_GammaConversion++; 
+          if( track_origin & (0x1 << InDet::TrkOrigin::OtherDecay) ) SV1_numTracks_Secondaries_OtherDecay++; 
+          if( track_origin & (0x1 << InDet::TrkOrigin::HadronicInteraction) ) SV1_numTracks_Secondaries_HadronicInteraction++; 
+          if( track_origin & (0x1 << InDet::TrkOrigin::OtherSecondary) ) SV1_numTracks_Secondaries_OtherSecondary++; 
+          if( track_origin & (0x1 << InDet::TrkOrigin::OtherOrigin) ) SV1_numTracks_OtherOrigin++; 
+        }
+
+        // and count all tracks
+        SV1_numTracks++;
+      }
+    }
+
+    // fractions of tracks in the SV
+    double SV1_frac_HF_tracks_in_jet = -1;
+    double SV1_purity = -1;
+    double SV1_fracTracks_fromB = -1;
+    double SV1_fracTracks_fromC = -1;
+    double SV1_fracTracks_fromFragmentation = -1;
+    double SV1_fracTracks_fromSecondaries = -1;
+    double SV1_fracTracks_fromPileup = -1;
+    double SV1_fracTracks_fromFake = -1;
+
+    // these are only filled for detail level above 10
+    double SV1_fracTracks_Secondaries_KshortDecay = -1.; 
+    double SV1_fracTracks_Secondaries_LambdaDecay = -1.; 
+    double SV1_fracTracks_Secondaries_GammaConversion = -1.; 
+    double SV1_fracTracks_Secondaries_OtherDecay = -1.; 
+    double SV1_fracTracks_Secondaries_HadronicInteraction = -1.; 
+    double SV1_fracTracks_Secondaries_OtherSecondary = -1.; 
+    double SV1_fracTracks_OtherOrigin = -1.; 
+
+    if(!m_isData){
+      SV1_frac_HF_tracks_in_jet = (num_HF_tracks_in_jet != 0) ? ( SV1_numTracks_fromB + SV1_numTracks_fromC ) / num_HF_tracks_in_jet : -1;
+      SV1_purity = (SV1_numTracks != 0) ? (SV1_numTracks_fromB + SV1_numTracks_fromC) / SV1_numTracks : -1;
+      SV1_fracTracks_fromB = (SV1_numTracks != 0) ? SV1_numTracks_fromB / SV1_numTracks : -1.;
+      SV1_fracTracks_fromC = (SV1_numTracks != 0) ? SV1_numTracks_fromC / SV1_numTracks : -1.;
+      SV1_fracTracks_fromFragmentation = (SV1_numTracks != 0) ? SV1_numTracks_fromFragmentation / SV1_numTracks : -1.;
+      SV1_fracTracks_fromSecondaries = (SV1_numTracks != 0) ? SV1_numTracks_fromSecondaries / SV1_numTracks : -1.;
+      SV1_fracTracks_fromPileup = (SV1_numTracks != 0) ? SV1_numTracks_fromPileup / SV1_numTracks : -1.;
+      SV1_fracTracks_fromFake = (SV1_numTracks != 0) ? SV1_numTracks_fromFake / SV1_numTracks : -1.;
+
+      if(m_detailLevel > 10){
+        SV1_fracTracks_Secondaries_KshortDecay = (SV1_numTracks != 0) ? SV1_numTracks_Secondaries_KshortDecay / SV1_numTracks : -1.; 
+        SV1_fracTracks_Secondaries_LambdaDecay = (SV1_numTracks != 0) ? SV1_numTracks_Secondaries_LambdaDecay / SV1_numTracks : -1.; 
+        SV1_fracTracks_Secondaries_GammaConversion = (SV1_numTracks != 0) ? SV1_numTracks_Secondaries_GammaConversion / SV1_numTracks : -1.; 
+        SV1_fracTracks_Secondaries_OtherDecay = (SV1_numTracks != 0) ? SV1_numTracks_Secondaries_OtherDecay / SV1_numTracks : -1.; 
+        SV1_fracTracks_Secondaries_HadronicInteraction = (SV1_numTracks != 0) ? SV1_numTracks_Secondaries_HadronicInteraction / SV1_numTracks : -1.; 
+        SV1_fracTracks_Secondaries_OtherSecondary = (SV1_numTracks != 0) ? SV1_numTracks_Secondaries_OtherSecondary / SV1_numTracks : -1.; 
+        SV1_fracTracks_OtherOrigin = (SV1_numTracks != 0) ? SV1_numTracks_OtherOrigin / SV1_numTracks : -1.; 
+      }
+    }
+
+    // MSV
+
+    // MSV number of SVs in jet
+    int MSV_nvsec;
+    try { MSV_nvsec = btag->auxdata<int>("MSV_nvsec");}
+    catch(std::exception& exception) { MSV_nvsec = -1; }
+
+    // MSV N2Tpair
+    int MSV_N2Tpair;
+    try { MSV_N2Tpair = btag->auxdata<int>("MSV_N2Tpair"); }
+    catch(std::exception& exception) { MSV_N2Tpair = -1; }
+
+    // MSV track energy fraction
+    float MSV_energyTrkInJet;
+    try { MSV_energyTrkInJet = btag->auxdata<float>("MSV_energyTrkInJet"); }
+    catch(std::exception& exception) { MSV_energyTrkInJet = -1; }
+
+    // MSV normdist
+    float MSV_normdist;
+    try { MSV_normdist = btag->auxdata<float>("MSV_normdist"); }
+    catch(std::exception& exception) { MSV_normdist = -1; }
+
+    // MSV vertices
+    std::vector< ElementLink< xAOD::VertexContainer > > MSV_vertices;
+    try { MSV_vertices = btag->auxdata<std::vector< ElementLink< xAOD::VertexContainer > > >("MSV_vertices"); }
+    catch(std::exception& exception) {  }
+
+    std::vector<double> MSV_purity_perVertex;
+    std::vector<double> MSV_p4_sum_tracks_mass_perVertex;
+
+    // loop over the MSV vertices
+    for (unsigned int i = 0; i < MSV_vertices.size(); i++) {
+      if (!MSV_vertices.at(i).isValid()) continue;
+      const xAOD::Vertex* vtx = *(MSV_vertices.at(i));
+
+      double MSV_numTracks = 0;
+      double MSV_numTracks_fromHF = 0;
+      TLorentzVector p4_sum_tracks(0., 0., 0., 0.);
+
+      // get the track links
+      std::vector<ElementLink<DataVector<xAOD::TrackParticle> > > MSV_assocTracks = vtx->trackParticleLinks();
+
+      // loop over the tracks
+      for(unsigned int i = 0; i < MSV_assocTracks.size(); i++) {
+        if (!MSV_assocTracks.at(i).isValid()) continue;
+
+        // get the curent track
+        const xAOD::TrackParticle* track = *(MSV_assocTracks.at(i));  
+
+        // get the track origin
+        int track_origin = -1;
+        if(!m_isData){
+          track_origin = track_truth_associations.at(track);
+        }
+
+        // count the tracks from HF
+        if( (InDet::TrkOrigin::isFromB(track_origin)) || (InDet::TrkOrigin::isFromD(track_origin)) ) MSV_numTracks_fromHF++;
+        // and count all tracks
+        MSV_numTracks++;
+        // add the track to the 4-vector sum
+        p4_sum_tracks += track->p4();
+      }
+      
+      // fill the purity and the mass of the p4 sum of the tracks for the current vertex
+      MSV_purity_perVertex.push_back(MSV_numTracks_fromHF / MSV_numTracks);
+      MSV_p4_sum_tracks_mass_perVertex.push_back(p4_sum_tracks.M());
+    }
+
+    // get the average purity
+    double MSV_purity = -1.;
+    if(MSV_purity_perVertex.size() != 0) MSV_purity = std::accumulate(MSV_purity_perVertex.begin(), MSV_purity_perVertex.end(), 0.) / MSV_purity_perVertex.size();
+
+    // and the mass of the 4-vector sum
+    double MSV_p4_sum_tracks_mass = -1.;
+    if(MSV_p4_sum_tracks_mass_perVertex.size() != 0) MSV_p4_sum_tracks_mass = std::accumulate(MSV_p4_sum_tracks_mass_perVertex.begin(), MSV_p4_sum_tracks_mass_perVertex.end(), 0.) / MSV_p4_sum_tracks_mass_perVertex.size();
+
+
+    // JetFitter
+
+    // JetFitter N2Tpair
+    int JetFitter_N2Tpair = btag->auxdata<int>("JetFitter_N2Tpair");
+
+    // JetFitter nVTX 
+    int JetFitter_nVTX = btag->auxdata<int>("JetFitter_nVTX");
+
+    // JetFitter nSingleTracks
+    int JetFitter_nSingleTracks = btag->auxdata<int>("JetFitter_nSingleTracks");
+
+    // JetFitter nTracksAtVtx 
+    int JetFitter_nTracksAtVtx = btag->auxdata<int>("JetFitter_nTracksAtVtx");
+
+    // JetFitter mass
+    float JetFitter_mass = btag->auxdata<float>("JetFitter_mass");
+
+    // JetFitter energyFraction 
+    float JetFitter_energyFraction = btag->auxdata<float>("JetFitter_energyFraction");
+
+    // JetFitter significance3d 
+    float JetFitter_significance3d = btag->auxdata<float>("JetFitter_significance3d");
+
+    // get JetFitter vertices
+    std::vector< ElementLink< xAOD::BTagVertexContainer > > JetFitter_vertices = btag->auxdata<std::vector< ElementLink< xAOD::BTagVertexContainer > > >("JetFitter_JFvertices");
+    std::vector<double> JetFitter_purity_perVertex;
+
+    // loop over the JetFitter vertices
+    for (unsigned int i = 0; i < JetFitter_vertices.size(); i++) {
+      if (!JetFitter_vertices.at(i).isValid()) continue;
+      const xAOD::BTagVertex* vtx = *(JetFitter_vertices.at(i));
+
+      double JetFitter_numTracks = 0;
+      double JetFitter_numTracks_fromHF = 0;
+
+      // get the track links
+      std::vector<ElementLink<DataVector<xAOD::TrackParticle> > > tpLinks = vtx->track_links();
+
+      // loop over the tracks
+      for (ElementLink<DataVector<xAOD::TrackParticle> > link : tpLinks) {
+        const xAOD::TrackParticle* track = (*link);
+      
+        // get the track origin
+        int track_origin = -1;
+        if(!m_isData){
+          track_origin = track_truth_associations.at(track);
+        }
+
+        // count the tracks from HF
+        if( (InDet::TrkOrigin::isFromB(track_origin)) || (InDet::TrkOrigin::isFromD(track_origin)) ) JetFitter_numTracks_fromHF++;
+        // and count all tracks
+        JetFitter_numTracks++;
+      }
+
+      // get the purity of the current vertex
+      JetFitter_purity_perVertex.push_back(JetFitter_numTracks_fromHF / JetFitter_numTracks);
+    }
+
+    // get the average purity
+    double JetFitter_purity = std::accumulate(JetFitter_purity_perVertex.begin(), JetFitter_purity_perVertex.end(), 0.) / JetFitter_purity_perVertex.size();
+
+    BTaggingValidationPlots::fillHistoWithTruthCases(SV1_masssvx/GeV, m_SV1_masssvx_incl, m_SV1_masssvx_b, m_SV1_masssvx_c, m_SV1_masssvx_l, m_SV1_masssvx_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(SV1_N2Tpair, m_SV1_N2Tpair_incl, m_SV1_N2Tpair_b, m_SV1_N2Tpair_c, m_SV1_N2Tpair_l, m_SV1_N2Tpair_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(SV1_efracsvx, m_SV1_efracsvx_incl, m_SV1_efracsvx_b, m_SV1_efracsvx_c, m_SV1_efracsvx_l, m_SV1_efracsvx_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(SV1_deltaR, m_SV1_deltaR_incl, m_SV1_deltaR_b, m_SV1_deltaR_c, m_SV1_deltaR_l, m_SV1_deltaR_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(SV1_significance3d, m_SV1_significance3d_incl, m_SV1_significance3d_b, m_SV1_significance3d_c, m_SV1_significance3d_l, m_SV1_significance3d_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(SV1_energyTrkInJet/GeV, m_SV1_energyTrkInJet_incl, m_SV1_energyTrkInJet_b, m_SV1_energyTrkInJet_c, m_SV1_energyTrkInJet_l, m_SV1_energyTrkInJet_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(SV1_NGTinSvx, m_SV1_NGTinSvx_incl, m_SV1_NGTinSvx_b, m_SV1_NGTinSvx_c, m_SV1_NGTinSvx_l, m_SV1_NGTinSvx_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(SV1_Lxy, m_SV1_Lxy_incl, m_SV1_Lxy_b, m_SV1_Lxy_c, m_SV1_Lxy_l, m_SV1_Lxy_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(SV1_vertex.size(), m_SV1_numSVs_incl, m_SV1_numSVs_b, m_SV1_numSVs_c, m_SV1_numSVs_l, m_SV1_numSVs_muon, truth_label, has_muon, event);
+    if(!m_isData){
+      BTaggingValidationPlots::fillHistoWithTruthCases( SV1_frac_HF_tracks_in_jet, m_SV1_fracHFTracksInJet_incl, m_SV1_fracHFTracksInJet_b, m_SV1_fracHFTracksInJet_c, m_SV1_fracHFTracksInJet_l, m_SV1_fracHFTracksInJet_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases( SV1_purity, m_SV1_purity_incl, m_SV1_purity_b, m_SV1_purity_c, m_SV1_purity_l, m_SV1_purity_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases( SV1_fracTracks_fromB, m_SV1_fracTracks_fromB_incl, m_SV1_fracTracks_fromB_b, m_SV1_fracTracks_fromB_c, m_SV1_fracTracks_fromB_l, m_SV1_fracTracks_fromB_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases( SV1_fracTracks_fromC, m_SV1_fracTracks_fromC_incl, m_SV1_fracTracks_fromC_b, m_SV1_fracTracks_fromC_c, m_SV1_fracTracks_fromC_l, m_SV1_fracTracks_fromC_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases( SV1_fracTracks_fromFragmentation, m_SV1_fracTracks_fromFragmentation_incl, m_SV1_fracTracks_fromFragmentation_b, m_SV1_fracTracks_fromFragmentation_c, m_SV1_fracTracks_fromFragmentation_l, m_SV1_fracTracks_fromFragmentation_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases( SV1_fracTracks_fromSecondaries, m_SV1_fracTracks_fromSecondaries_incl, m_SV1_fracTracks_fromSecondaries_b, m_SV1_fracTracks_fromSecondaries_c, m_SV1_fracTracks_fromSecondaries_l, m_SV1_fracTracks_fromSecondaries_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases( SV1_fracTracks_fromPileup, m_SV1_fracTracks_fromPileup_incl, m_SV1_fracTracks_fromPileup_b, m_SV1_fracTracks_fromPileup_c, m_SV1_fracTracks_fromPileup_l, m_SV1_fracTracks_fromPileup_muon, truth_label, has_muon, event);
+      BTaggingValidationPlots::fillHistoWithTruthCases( SV1_fracTracks_fromFake, m_SV1_fracTracks_fromFake_incl, m_SV1_fracTracks_fromFake_b, m_SV1_fracTracks_fromFake_c, m_SV1_fracTracks_fromFake_l, m_SV1_fracTracks_fromFake_muon, truth_label, has_muon, event);
+
+      if(m_detailLevel > 10){
+        BTaggingValidationPlots::fillHistoWithTruthCases(SV1_fracTracks_Secondaries_KshortDecay, m_SV1_fracTracks_Secondaries_KshortDecay_incl, m_SV1_fracTracks_Secondaries_KshortDecay_b, m_SV1_fracTracks_Secondaries_KshortDecay_c, m_SV1_fracTracks_Secondaries_KshortDecay_u, m_SV1_fracTracks_Secondaries_KshortDecay_muon, truth_label, has_muon, event); 
+        BTaggingValidationPlots::fillHistoWithTruthCases(SV1_fracTracks_Secondaries_LambdaDecay, m_SV1_fracTracks_Secondaries_LambdaDecay_incl, m_SV1_fracTracks_Secondaries_LambdaDecay_b, m_SV1_fracTracks_Secondaries_LambdaDecay_c, m_SV1_fracTracks_Secondaries_LambdaDecay_u, m_SV1_fracTracks_Secondaries_LambdaDecay_muon, truth_label, has_muon, event); 
+        BTaggingValidationPlots::fillHistoWithTruthCases(SV1_fracTracks_Secondaries_GammaConversion, m_SV1_fracTracks_Secondaries_GammaConversion_incl, m_SV1_fracTracks_Secondaries_GammaConversion_b, m_SV1_fracTracks_Secondaries_GammaConversion_c, m_SV1_fracTracks_Secondaries_GammaConversion_u, m_SV1_fracTracks_Secondaries_GammaConversion_muon, truth_label, has_muon, event); 
+        BTaggingValidationPlots::fillHistoWithTruthCases(SV1_fracTracks_Secondaries_OtherDecay, m_SV1_fracTracks_Secondaries_OtherDecay_incl, m_SV1_fracTracks_Secondaries_OtherDecay_b, m_SV1_fracTracks_Secondaries_OtherDecay_c, m_SV1_fracTracks_Secondaries_OtherDecay_u, m_SV1_fracTracks_Secondaries_OtherDecay_muon, truth_label, has_muon, event); 
+        BTaggingValidationPlots::fillHistoWithTruthCases(SV1_fracTracks_Secondaries_HadronicInteraction, m_SV1_fracTracks_Secondaries_HadronicInteraction_incl, m_SV1_fracTracks_Secondaries_HadronicInteraction_b, m_SV1_fracTracks_Secondaries_HadronicInteraction_c, m_SV1_fracTracks_Secondaries_HadronicInteraction_u, m_SV1_fracTracks_Secondaries_HadronicInteraction_muon, truth_label, has_muon, event); 
+        BTaggingValidationPlots::fillHistoWithTruthCases(SV1_fracTracks_Secondaries_OtherSecondary, m_SV1_fracTracks_Secondaries_OtherSecondary_incl, m_SV1_fracTracks_Secondaries_OtherSecondary_b, m_SV1_fracTracks_Secondaries_OtherSecondary_c, m_SV1_fracTracks_Secondaries_OtherSecondary_u, m_SV1_fracTracks_Secondaries_OtherSecondary_muon, truth_label, has_muon, event); 
+        BTaggingValidationPlots::fillHistoWithTruthCases(SV1_fracTracks_OtherOrigin, m_SV1_fracTracks_OtherOrigin_incl, m_SV1_fracTracks_OtherOrigin_b, m_SV1_fracTracks_OtherOrigin_c, m_SV1_fracTracks_OtherOrigin_u, m_SV1_fracTracks_OtherOrigin_muon, truth_label, has_muon, event); 
+      }
+    }
+    BTaggingValidationPlots::fillHistoWithTruthCases(MSV_nvsec, m_MSV_nvsec_incl, m_MSV_nvsec_b, m_MSV_nvsec_c, m_MSV_nvsec_l, m_MSV_nvsec_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(MSV_N2Tpair, m_MSV_N2Tpair_incl, m_MSV_N2Tpair_b, m_MSV_N2Tpair_c, m_MSV_N2Tpair_l, m_MSV_N2Tpair_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(MSV_energyTrkInJet/GeV, m_MSV_energyTrkInJet_incl, m_MSV_energyTrkInJet_b, m_MSV_energyTrkInJet_c, m_MSV_energyTrkInJet_l, m_MSV_energyTrkInJet_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(MSV_normdist, m_MSV_normdist_incl, m_MSV_normdist_b, m_MSV_normdist_c, m_MSV_normdist_l, m_MSV_normdist_muon, truth_label, has_muon, event);
+    if(!m_isData){
+      BTaggingValidationPlots::fillHistoWithTruthCases(MSV_purity, m_MSV_purity_incl, m_MSV_purity_b, m_MSV_purity_c, m_MSV_purity_l, m_MSV_purity_muon, truth_label, has_muon, event);
+    }
+    BTaggingValidationPlots::fillHistoWithTruthCases(MSV_p4_sum_tracks_mass/GeV, m_MSV_vtx_mass_incl, m_MSV_vtx_mass_b, m_MSV_vtx_mass_c, m_MSV_vtx_mass_l, m_MSV_vtx_mass_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(JetFitter_N2Tpair, m_JetFitter_N2Tpair_incl, m_JetFitter_N2Tpair_b, m_JetFitter_N2Tpair_c, m_JetFitter_N2Tpair_l, m_JetFitter_N2Tpair_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(JetFitter_nVTX, m_JetFitter_nVTX_incl, m_JetFitter_nVTX_b, m_JetFitter_nVTX_c, m_JetFitter_nVTX_l, m_JetFitter_nVTX_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(JetFitter_nSingleTracks, m_JetFitter_nSingleTracks_incl, m_JetFitter_nSingleTracks_b, m_JetFitter_nSingleTracks_c, m_JetFitter_nSingleTracks_l, m_JetFitter_nSingleTracks_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(JetFitter_nTracksAtVtx, m_JetFitter_nTracksAtVtx_incl, m_JetFitter_nTracksAtVtx_b, m_JetFitter_nTracksAtVtx_c, m_JetFitter_nTracksAtVtx_l, m_JetFitter_nTracksAtVtx_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(JetFitter_mass/GeV, m_JetFitter_mass_incl, m_JetFitter_mass_b, m_JetFitter_mass_c, m_JetFitter_mass_l, m_JetFitter_mass_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(JetFitter_energyFraction, m_JetFitter_energyFraction_incl, m_JetFitter_energyFraction_b, m_JetFitter_energyFraction_c, m_JetFitter_energyFraction_l, m_JetFitter_energyFraction_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(JetFitter_significance3d, m_JetFitter_significance3d_incl, m_JetFitter_significance3d_b, m_JetFitter_significance3d_c, m_JetFitter_significance3d_l, m_JetFitter_significance3d_muon, truth_label, has_muon, event);
+    if(!m_isData){
+      BTaggingValidationPlots::fillHistoWithTruthCases(JetFitter_purity, m_JetFitter_purity_incl, m_JetFitter_purity_b, m_JetFitter_purity_c, m_JetFitter_purity_l, m_JetFitter_purity_muon, truth_label, has_muon, event);
+    }
+
+    // // fill the SV varaibles for the different jet labels
+    if(!m_isData && truth_label == 5) {
+      // vs pT and vs eta
+      m_SV1_masssvx_vs_pT_b->Fill(jet->pt()/GeV, SV1_masssvx/GeV), event->beamSpotWeight();
+      m_SV1_masssvx_vs_eta_b->Fill(jet->eta(), SV1_masssvx/GeV, event->beamSpotWeight());
+      m_SV1_N2Tpair_vs_pT_b->Fill(jet->pt()/GeV, SV1_N2Tpair, event->beamSpotWeight());
+      m_SV1_N2Tpair_vs_eta_b->Fill(jet->eta(), SV1_N2Tpair, event->beamSpotWeight());
+      m_SV1_efracsvx_vs_pT_b->Fill(jet->pt()/GeV, SV1_efracsvx, event->beamSpotWeight());
+      m_SV1_efracsvx_vs_eta_b->Fill(jet->eta(), SV1_efracsvx, event->beamSpotWeight());
+      m_SV1_deltaR_vs_pT_b->Fill(jet->pt()/GeV, SV1_deltaR, event->beamSpotWeight());
+      m_SV1_deltaR_vs_eta_b->Fill(jet->eta(), SV1_deltaR, event->beamSpotWeight());
+    }
+    else if(!m_isData && truth_label == 4) {
+      // vs pT and vs eta
+      m_SV1_masssvx_vs_pT_c->Fill(jet->pt()/GeV, SV1_masssvx/GeV, event->beamSpotWeight());
+      m_SV1_masssvx_vs_eta_c->Fill(jet->eta(), SV1_masssvx/GeV, event->beamSpotWeight());
+      m_SV1_N2Tpair_vs_pT_c->Fill(jet->pt()/GeV, SV1_N2Tpair, event->beamSpotWeight());
+      m_SV1_N2Tpair_vs_eta_c->Fill(jet->eta(), SV1_N2Tpair, event->beamSpotWeight());
+      m_SV1_efracsvx_vs_pT_c->Fill(jet->pt()/GeV, SV1_efracsvx, event->beamSpotWeight());
+      m_SV1_efracsvx_vs_eta_c->Fill(jet->eta(), SV1_efracsvx, event->beamSpotWeight());
+      m_SV1_deltaR_vs_pT_c->Fill(jet->pt()/GeV, SV1_deltaR, event->beamSpotWeight());
+      m_SV1_deltaR_vs_eta_c->Fill(jet->eta(), SV1_deltaR, event->beamSpotWeight());
+    }
+    else if(!m_isData && truth_label == 0) {
+      // vs pT and vs eta
+      m_SV1_masssvx_vs_pT_l->Fill(jet->pt()/GeV, SV1_masssvx/GeV, event->beamSpotWeight());
+      m_SV1_masssvx_vs_eta_l->Fill(jet->eta(), SV1_masssvx/GeV, event->beamSpotWeight());
+      m_SV1_N2Tpair_vs_pT_l->Fill(jet->pt()/GeV, SV1_N2Tpair, event->beamSpotWeight());
+      m_SV1_N2Tpair_vs_eta_l->Fill(jet->eta(), SV1_N2Tpair, event->beamSpotWeight());
+      m_SV1_efracsvx_vs_pT_l->Fill(jet->pt()/GeV, SV1_efracsvx, event->beamSpotWeight());
+      m_SV1_efracsvx_vs_eta_l->Fill(jet->eta(), SV1_efracsvx, event->beamSpotWeight());
+      m_SV1_deltaR_vs_pT_l->Fill(jet->pt()/GeV, SV1_deltaR, event->beamSpotWeight());
+      m_SV1_deltaR_vs_eta_l->Fill(jet->eta(), SV1_deltaR, event->beamSpotWeight());
+    }
+
+    
+
+  }
+
+
+  // a fill method for discriminant related vars
+  void BTaggingValidationPlots::fillDiscriminantVariables(const xAOD::BTagging* btag, const xAOD::Jet* jet, const double& jet_Lxy, const int& truth_label, const bool& has_muon, const bool& onZprime, std::map<std::string, int>& nJetsThatPassedWPCuts, const xAOD::EventInfo* event){
+
+    //// IPxD variables
+
+    // grade of tracks
+    std::vector<int> IP3D_gradeOfTracks = btag->auxdata<std::vector<int> >("IP3D_gradeOfTracks");
+    std::vector<int> IP2D_gradeOfTracks = btag->auxdata<std::vector<int> >("IP2D_gradeOfTracks");
+    // loop over the elements (i.e. tracks) and fill the histogram
+    for( unsigned int i=0; i<IP3D_gradeOfTracks.size(); i++){
+      BTaggingValidationPlots::fillHistoWithTruthCases(IP3D_gradeOfTracks.at(i), m_IP3D_gradeOfTracks_incl, m_IP3D_gradeOfTracks_b, m_IP3D_gradeOfTracks_c, m_IP3D_gradeOfTracks_l, m_IP3D_gradeOfTracks_muon, truth_label, has_muon, event);
+    }
+    for( unsigned int i=0; i<IP2D_gradeOfTracks.size(); i++){
+      BTaggingValidationPlots::fillHistoWithTruthCases(IP2D_gradeOfTracks.at(i), m_IP2D_gradeOfTracks_incl, m_IP2D_gradeOfTracks_b, m_IP2D_gradeOfTracks_c, m_IP2D_gradeOfTracks_l, m_IP2D_gradeOfTracks_muon, truth_label, has_muon, event);
+    }
+
+    // d0, z0 and significances
+    std::vector<float> tmpD0       = btag->auxdata<std::vector<float> >("IP3D_valD0wrtPVofTracks");
+    std::vector<float> tmpZ0       = btag->auxdata<std::vector<float> >("IP3D_valZ0wrtPVofTracks");
+    std::vector<float> tmpD0sig    = btag->auxdata<std::vector<float> >("IP3D_sigD0wrtPVofTracks");
+    std::vector<float> tmpZ0sig    = btag->auxdata<std::vector<float> >("IP3D_sigZ0wrtPVofTracks");
+    // loop over the elements (i.e. tracks) and fill the histogram
+    for( unsigned int i=0; i<tmpD0   .size(); i++) m_tmpD0   ->Fill(tmpD0.at(i), event->beamSpotWeight());
+    for( unsigned int i=0; i<tmpZ0   .size(); i++) m_tmpZ0   ->Fill(tmpZ0.at(i), event->beamSpotWeight());
+    for( unsigned int i=0; i<tmpD0sig.size(); i++) m_tmpD0sig->Fill(tmpD0sig.at(i), event->beamSpotWeight());
+    for( unsigned int i=0; i<tmpZ0sig.size(); i++) m_tmpZ0sig->Fill(tmpZ0sig.at(i), event->beamSpotWeight());
+  
+    // weight b and weight u of tracks
+    // IP3D
+    std::vector<float> IP3D_weightBofTracks = btag->auxdata<std::vector<float> >("IP3D_weightBofTracks");
+    std::vector<float> IP3D_weightCofTracks = btag->auxdata<std::vector<float> >("IP3D_weightCofTracks");
+    std::vector<float> IP3D_weightUofTracks = btag->auxdata<std::vector<float> >("IP3D_weightUofTracks");
+    // IP2D
+    std::vector<float> IP2D_weightBofTracks = btag->auxdata<std::vector<float> >("IP2D_weightBofTracks");
+    std::vector<float> IP2D_weightCofTracks = btag->auxdata<std::vector<float> >("IP2D_weightCofTracks");
+    std::vector<float> IP2D_weightUofTracks = btag->auxdata<std::vector<float> >("IP2D_weightUofTracks");
+    // loop over the elements (i.e. tracks) and fill the histogram
+    // IP3D
+    for( unsigned int i=0; i<IP3D_weightBofTracks.size(); i++) m_IP3D_weightBofTracks->Fill(IP3D_weightBofTracks.at(i), event->beamSpotWeight());
+    for( unsigned int i=0; i<IP3D_weightCofTracks.size(); i++) m_IP3D_weightCofTracks->Fill(IP3D_weightCofTracks.at(i), event->beamSpotWeight());
+    for( unsigned int i=0; i<IP3D_weightUofTracks.size(); i++) m_IP3D_weightUofTracks->Fill(IP3D_weightUofTracks.at(i), event->beamSpotWeight());
+    // IP2D
+    for( unsigned int i=0; i<IP2D_weightBofTracks.size(); i++) m_IP2D_weightBofTracks->Fill(IP2D_weightBofTracks.at(i), event->beamSpotWeight());
+    for( unsigned int i=0; i<IP2D_weightCofTracks.size(); i++) m_IP2D_weightCofTracks->Fill(IP2D_weightCofTracks.at(i), event->beamSpotWeight());
+    for( unsigned int i=0; i<IP2D_weightUofTracks.size(); i++) m_IP2D_weightUofTracks->Fill(IP2D_weightUofTracks.at(i), event->beamSpotWeight());
+
+
+    // number of IP2D & IP3D tracks
+    int nIP2DTracks(1000);
+    int nIP3DTracks(1000);
+    try{ nIP2DTracks = btag->nIP2D_TrackParticles(); }
+    catch(std::exception& exception){ nIP2DTracks = -1; }
+    try{ nIP3DTracks = btag->nIP3D_TrackParticles(); }
+    catch(std::exception& exception){ nIP3DTracks = -1; }
+
+    BTaggingValidationPlots::fillHistoWithTruthCases(nIP2DTracks, m_IP2D_nTracks_incl, m_IP2D_nTracks_b, m_IP2D_nTracks_c, m_IP2D_nTracks_l, m_IP2D_nTracks_muon, truth_label, has_muon, event);
+    BTaggingValidationPlots::fillHistoWithTruthCases(nIP3DTracks, m_IP3D_nTracks_incl, m_IP3D_nTracks_b, m_IP3D_nTracks_c, m_IP3D_nTracks_l, m_IP3D_nTracks_muon, truth_label, has_muon, event);
+
+    // pb, pu, pc 
+    m_IP3D_pb->Fill(btag->IP3D_pb(), event->beamSpotWeight());
+    m_IP3D_pc->Fill(btag->IP3D_pc(), event->beamSpotWeight());
+    m_IP3D_pu->Fill(btag->IP3D_pu(), event->beamSpotWeight());
+
+    
+    //// RNNIP variables
+
+    // pb, pu, pc 
+    double RNNIP_pb, RNNIP_pu, RNNIP_pc;
+    try{ RNNIP_pb = btag->auxdata<ftagfloat_t>("rnnip_pb"); }
+    catch(std::exception& exception){ RNNIP_pb = -1; }
+    try{ RNNIP_pu = btag->auxdata<ftagfloat_t>("rnnip_pu"); }
+    catch(std::exception& exception){ RNNIP_pu = -1; }
+    try{ RNNIP_pc = btag->auxdata<ftagfloat_t>("rnnip_pc"); }
+    catch(std::exception& exception){ RNNIP_pc = -1; }
+    m_RNNIP_pb->Fill(RNNIP_pb, event->beamSpotWeight());
+    m_RNNIP_pu->Fill(RNNIP_pu, event->beamSpotWeight());
+    m_RNNIP_pc->Fill(RNNIP_pc, event->beamSpotWeight());
+
+    double weight_RNNIP = log( RNNIP_pb / ( RNNIP_pc * m_RNNIP_fc + RNNIP_pu * (1-m_RNNIP_fc) ) );
+
+    //// SV1 variables
+
+    // number of good tracks
+    // int nGTinSvx0(1000);
+    int nGTinSV1(1000);
+    // try{ btag->taggerInfo(nGTinSvx0, xAOD::SV0_NGTinSvx); }
+    // catch(std::exception& exception){ nGTinSvx0 = -1; }
+    try{ btag->taggerInfo(nGTinSV1, xAOD::SV1_NGTinSvx); }
+    catch(std::exception& exception){ nGTinSV1 = -1; }
+    // m_SV0_NGTinSvx->Fill(nGTinSvx0, event->beamSpotWeight());
+    BTaggingValidationPlots::fillHistoWithTruthCases(nGTinSV1, m_nGTinSV1_incl, m_nGTinSV1_b, m_nGTinSV1_c, m_nGTinSV1_l, m_nGTinSV1_muon, truth_label, has_muon, event);
+
+    // pb, pu, pc 
+    m_SV1_pb->Fill(btag->SV1_pb(), event->beamSpotWeight());
+    m_SV1_pc->Fill(btag->SV1_pc(), event->beamSpotWeight());
+    m_SV1_pu->Fill(btag->SV1_pu(), event->beamSpotWeight());
+
+
+    //// high level tagger variables
+
+    // get the MVx discriminant values
+    double weight_MV2c10 = -999;
+    btag->MVx_discriminant("MV2c10", weight_MV2c10);
+
+    // get the DL1x vars
+    double DL1_pb = btag->auxdata<ftagfloat_t>("DL1_pb");
+    double DL1_pc = btag->auxdata<ftagfloat_t>("DL1_pc");
+    double DL1_pu = btag->auxdata<ftagfloat_t>("DL1_pu");
+    m_DL1_pb->Fill(DL1_pb, event->beamSpotWeight());
+    m_DL1_pu->Fill(DL1_pu, event->beamSpotWeight());
+    m_DL1_pc->Fill(DL1_pc, event->beamSpotWeight());
+
+    double DL1r_pb, DL1r_pu, DL1r_pc;
+    try{ DL1r_pb = btag->auxdata<ftagfloat_t>("DL1r_pb"); }
+    catch(std::exception& exception){ DL1r_pb = -1; }
+    try{ DL1r_pu = btag->auxdata<ftagfloat_t>("DL1r_pu"); }
+    catch(std::exception& exception){ DL1r_pu = -1; }
+    try{ DL1r_pc = btag->auxdata<ftagfloat_t>("DL1r_pc"); }
+    catch(std::exception& exception){ DL1r_pc = -1; }
+    m_DL1r_pb->Fill(DL1r_pb, event->beamSpotWeight());
+    m_DL1r_pu->Fill(DL1r_pu, event->beamSpotWeight());
+    m_DL1r_pc->Fill(DL1r_pc, event->beamSpotWeight());
+
+    // calculate the DL1 discriminant value
+    double weight_DL1 = log( DL1_pb / ( DL1_pc * m_DL1_fc + DL1_pu * (1-m_DL1_fc) ) );
+    double weight_DL1r = log( DL1r_pb / ( DL1r_pc * m_DL1r_fc + DL1r_pu * (1-m_DL1r_fc) ) );
+    
+    updateNJetsThatPassedWPCutsMap(nJetsThatPassedWPCuts, btag->IP3D_loglikelihoodratio(), btag->IP2D_loglikelihoodratio(), weight_RNNIP, btag->SV1_loglikelihoodratio(), btag->SV1plusIP3D_discriminant(), btag->JetFitter_loglikelihoodratio(), weight_MV2c10, weight_DL1, weight_DL1r);
+
+    // fill the histograms with the tagger discriminants
+    for(std::map<std::string, TH1*>::const_iterator hist_iter=m_weight_histos.begin(); hist_iter!=m_weight_histos.end(); ++hist_iter){
+      for(std::map<std::string, int>::const_iterator label_iter = m_truthLabels.begin(); label_iter != m_truthLabels.end(); ++label_iter){
+
+        // IP3D
+        bool pass_nTracksCut_IP3D = nIP3DTracks > 0;
+        BTaggingValidationPlots::fillDiscriminantHistograms("IP3D_", btag->IP3D_loglikelihoodratio(), m_IP3D_workingPoints, truth_label, hist_iter, label_iter, pass_nTracksCut_IP3D, jet->pt(), jet_Lxy, onZprime, event);
+
+        // IP2D
+        bool pass_nTracksCut_IP2D = nIP2DTracks > 0;
+        BTaggingValidationPlots::fillDiscriminantHistograms("IP2D_", btag->IP2D_loglikelihoodratio(), m_IP2D_workingPoints, truth_label, hist_iter, label_iter, pass_nTracksCut_IP2D, jet->pt(), jet_Lxy, onZprime, event);
+
+        // RNNIP
+        bool pass_nTracksCut_RNNIP = nIP3DTracks > 0;
+        BTaggingValidationPlots::fillDiscriminantHistograms("RNNIP_", weight_RNNIP, m_RNNIP_workingPoints, truth_label, hist_iter, label_iter, pass_nTracksCut_RNNIP, jet->pt(), jet_Lxy, onZprime, event);
+
+        // SV1
+        bool pass_nTracksCut_SV1 = nGTinSV1 > 0;
+        BTaggingValidationPlots::fillDiscriminantHistograms("SV1_", btag->SV1_loglikelihoodratio(), m_SV1_workingPoints, truth_label, hist_iter, label_iter, pass_nTracksCut_SV1, jet->pt(), jet_Lxy, onZprime, event);
+
+        // IP3DSV1
+        bool pass_nTracksCut_IP3DSV1 = nGTinSV1 > 0 && nIP3DTracks > 0;
+        BTaggingValidationPlots::fillDiscriminantHistograms("IP3DSV1_", btag->SV1plusIP3D_discriminant(), m_IP3DSV1_workingPoints, truth_label, hist_iter, label_iter, pass_nTracksCut_IP3DSV1, jet->pt(), jet_Lxy, onZprime, event);
+
+        // JetFitter
+        bool pass_nTracksCut_JetFitter = nGTinSV1 > 0 && nIP3DTracks > 0;
+        BTaggingValidationPlots::fillDiscriminantHistograms("JetFitter_", btag->JetFitter_loglikelihoodratio(), m_JetFitter_workingPoints, truth_label, hist_iter, label_iter, pass_nTracksCut_JetFitter, jet->pt(), jet_Lxy, onZprime, event);
+
+        // MV taggers
+        bool pass_nTracksCut_MV = nGTinSV1 > 0 && nIP3DTracks > 0;
+        BTaggingValidationPlots::fillDiscriminantHistograms("MV2c10_", weight_MV2c10, m_MV2c10_workingPoints, truth_label, hist_iter, label_iter, pass_nTracksCut_MV, jet->pt(), jet_Lxy, onZprime, event);
+
+        // DL1 taggers
+        bool pass_nTracksCut_DL1 = nGTinSV1 > 0 && nIP3DTracks > 0;
+        BTaggingValidationPlots::fillDiscriminantHistograms("DL1_", weight_DL1, m_DL1_workingPoints, truth_label, hist_iter, label_iter, pass_nTracksCut_DL1, jet->pt(), jet_Lxy, onZprime, event);
+        BTaggingValidationPlots::fillDiscriminantHistograms("DL1r_", weight_DL1r, m_DL1r_workingPoints, truth_label, hist_iter, label_iter, pass_nTracksCut_DL1, jet->pt(), jet_Lxy, onZprime, event);
+      }
+    }
+  }
+
+
+
+  void BTaggingValidationPlots::finalizePlots(){
+
+    std::string tmp_name_matched = "";
+    std::string tmp_name_eff = "";
+    std::string tmp_name_rej = "";
+    
+    for(std::map<std::string, TH1*>::const_iterator hist_iter=m_weight_histos.begin(); hist_iter!=m_weight_histos.end(); ++hist_iter){
+
+      if((hist_iter->first).find("matched")< (hist_iter->first).length() && (hist_iter->first).find("trackCuts") > (hist_iter->first).length()){
+        std::size_t found_matched = (hist_iter->first).find("matched");        
+        tmp_name_matched = (hist_iter->first);
+        tmp_name_eff = tmp_name_matched.replace(found_matched, 7, "eff");
+        std::map<std::string, TProfile*>::const_iterator eff_profile_iter = m_eff_profiles.find(tmp_name_eff);
+
+        if(eff_profile_iter != m_eff_profiles.end() && (eff_profile_iter->first).find("_pt") < (eff_profile_iter->first).length()){
+          makeEfficiencyVsPtPlot(hist_iter->second, eff_profile_iter->second);
+          (eff_profile_iter->second)->SetOption("E");
+        }
+        else if(eff_profile_iter != m_eff_profiles.end() && (eff_profile_iter->first).find("_weight") < (eff_profile_iter->first).length()){
+          makeEfficiencyPlot(hist_iter->second, eff_profile_iter->second);
+          std::size_t found_weight = tmp_name_eff.find("weight");
+          tmp_name_rej = tmp_name_eff.replace(found_weight, 6, "rej");
+          makeEfficiencyRejectionPlot(eff_profile_iter->second, m_eff_profiles.find(tmp_name_rej)->second);  
+        }
+      }
+    }
+  }
+
+
+// methods for the num b-tagged jets
+  void BTaggingValidationPlots::bookNJetsThatPassedWPCutsHistos(){
+    // loop over the taggers
+    for(std::vector<std::string>::const_iterator tag_iter = m_taggers.begin(); tag_iter != m_taggers.end(); ++tag_iter){
+      // get the right working points
+      std::map<std::string, double> workingPoints;
+      if(*tag_iter == "IP3D") workingPoints = m_IP3D_workingPoints;
+      else if(*tag_iter == "IP2D") workingPoints = m_IP2D_workingPoints;
+      else if(*tag_iter == "RNNIP") workingPoints = m_RNNIP_workingPoints;
+      else if(*tag_iter == "SV1") workingPoints = m_SV1_workingPoints;
+      else if(*tag_iter == "IP3DSV1") workingPoints = m_IP3DSV1_workingPoints;
+      else if(*tag_iter == "JetFitter") workingPoints = m_JetFitter_workingPoints;
+      else if(*tag_iter == "MV2c10") workingPoints = m_MV2c10_workingPoints;
+      else if(*tag_iter == "DL1") workingPoints = m_DL1_workingPoints;
+      else if(*tag_iter == "DL1r") workingPoints = m_DL1r_workingPoints;
+      // loop over the working points
+      for(std::map<std::string, double>::const_iterator working_points_iter = workingPoints.begin(); working_points_iter != workingPoints.end(); ++working_points_iter){
+        std::string name = "nJetsThatPassedWPCuts_" + *tag_iter + "_" + working_points_iter->first; 
+        // book the histo
+        TH1* histo = bookHistogram(name, "nJetsThatPassedWPCuts", m_sParticleType, "for " + *tag_iter + " discriminat > "+ std::to_string(working_points_iter->second) + ": " );     
+        // add the histo to map
+        m_nJetsThatPassedWPCutsHistos.insert( std::make_pair(name, histo) );
+      }
+    }
+  }
+
+  void BTaggingValidationPlots::initializeNJetsThatPassedWPCutsMap(std::map<std::string, int>& nJetsThatPassedWPCuts){
+    // loop over the taggers
+    for(std::vector<std::string>::const_iterator tag_iter = m_taggers.begin(); tag_iter != m_taggers.end(); ++tag_iter){
+      // get the right working points
+      std::map<std::string, double> workingPoints;
+      if(*tag_iter == "IP3D") workingPoints = m_IP3D_workingPoints;
+      else if(*tag_iter == "IP2D") workingPoints = m_IP2D_workingPoints;
+      else if(*tag_iter == "RNNIP") workingPoints = m_RNNIP_workingPoints;
+      else if(*tag_iter == "SV1") workingPoints = m_SV1_workingPoints;
+      else if(*tag_iter == "IP3DSV1") workingPoints = m_IP3DSV1_workingPoints;
+      else if(*tag_iter == "JetFitter") workingPoints = m_JetFitter_workingPoints;
+      else if(*tag_iter == "MV2c10") workingPoints = m_MV2c10_workingPoints;
+      else if(*tag_iter == "DL1") workingPoints = m_DL1_workingPoints;
+      else if(*tag_iter == "DL1r") workingPoints = m_DL1r_workingPoints;
+      // loop over the working points
+      for(std::map<std::string, double>::const_iterator working_points_iter = workingPoints.begin(); working_points_iter != workingPoints.end(); ++working_points_iter){
+        std::string name = "nJetsThatPassedWPCuts_" + *tag_iter + "_" + working_points_iter->first; 
+        // pre-fill the njets value with zero
+        nJetsThatPassedWPCuts.insert( std::make_pair(name, 0) );
+      }
+    }
+  }
+
+  void BTaggingValidationPlots::updateNJetsThatPassedWPCutsMap(std::map<std::string, int>& nJetsThatPassedWPCuts, const double& discr_IP3D, const double& discr_IP2D, const double& discr_RNNIP, const double& discr_SV1, const double& discr_IP3DSV1, const double& discr_JetFitter, const double& discr_MV2c10, const double& discr_DL1, const double& discr_DL1r){
+    // loop over the taggers
+    for(std::vector<std::string>::const_iterator tag_iter = m_taggers.begin(); tag_iter != m_taggers.end(); ++tag_iter){
+      // get the right working points and discriminant values
+      std::map<std::string, double> workingPoints;
+      double discriminant_value;
+      if(*tag_iter == "IP3D"){ workingPoints = m_IP3D_workingPoints; discriminant_value = discr_IP3D; }
+      else if(*tag_iter == "IP2D"){ workingPoints = m_IP2D_workingPoints; discriminant_value = discr_IP2D; }
+      else if(*tag_iter == "RNNIP"){ workingPoints = m_RNNIP_workingPoints; discriminant_value = discr_RNNIP; }
+      else if(*tag_iter == "SV1"){ workingPoints = m_SV1_workingPoints; discriminant_value = discr_SV1; }
+      else if(*tag_iter == "IP3DSV1"){ workingPoints = m_IP3DSV1_workingPoints; discriminant_value = discr_IP3DSV1; }
+      else if(*tag_iter == "JetFitter"){ workingPoints = m_JetFitter_workingPoints; discriminant_value = discr_JetFitter; }
+      else if(*tag_iter == "MV2c10"){ workingPoints = m_MV2c10_workingPoints; discriminant_value = discr_MV2c10; }
+      else if(*tag_iter == "DL1"){ workingPoints = m_DL1_workingPoints; discriminant_value = discr_DL1; }
+      else if(*tag_iter == "DL1r"){ workingPoints = m_DL1r_workingPoints; discriminant_value = discr_DL1r; }
+      // loop over the working points
+      for(std::map<std::string, double>::const_iterator working_points_iter = workingPoints.begin(); working_points_iter != workingPoints.end(); ++working_points_iter){
+        std::string name = "nJetsThatPassedWPCuts_" + *tag_iter + "_" + working_points_iter->first; 
+        // update the njets value if the wp cut is passed
+        if(discriminant_value > working_points_iter->second){
+          nJetsThatPassedWPCuts.at(name) += 1;
+        }
+      }
+    }
+  }
+
+  void BTaggingValidationPlots::fillNJetsThatPassedWPCutsHistos(std::map<std::string, int>& nJetsThatPassedWPCuts, const xAOD::EventInfo* event){
+    // loop over the taggers
+    for(std::vector<std::string>::const_iterator tag_iter = m_taggers.begin(); tag_iter != m_taggers.end(); ++tag_iter){
+      // get the right working points
+      std::map<std::string, double> workingPoints;
+      if(*tag_iter == "IP3D") workingPoints = m_IP3D_workingPoints;
+      else if(*tag_iter == "IP2D") workingPoints = m_IP2D_workingPoints;
+      else if(*tag_iter == "RNNIP") workingPoints = m_RNNIP_workingPoints;
+      else if(*tag_iter == "SV1") workingPoints = m_SV1_workingPoints;
+      else if(*tag_iter == "IP3DSV1") workingPoints = m_IP3DSV1_workingPoints;
+      else if(*tag_iter == "JetFitter") workingPoints = m_JetFitter_workingPoints;
+      else if(*tag_iter == "MV2c10") workingPoints = m_MV2c10_workingPoints;
+      else if(*tag_iter == "DL1") workingPoints = m_DL1_workingPoints;
+      else if(*tag_iter == "DL1r") workingPoints = m_DL1r_workingPoints;
+      // loop over the working points
+      for(std::map<std::string, double>::const_iterator working_points_iter = workingPoints.begin(); working_points_iter != workingPoints.end(); ++working_points_iter){
+        std::string name = "nJetsThatPassedWPCuts_" + *tag_iter + "_" + working_points_iter->first; 
+        // fill the histo
+        m_nJetsThatPassedWPCutsHistos.at(name)->Fill( nJetsThatPassedWPCuts.at(name), event->beamSpotWeight() );
+      }
+    }
+  }
+
+
+  void BTaggingValidationPlots::makeEfficiencyVsPtPlot(TH1* hReco, TProfile* pEff){
+    TH1* hTruth=NULL;
+    std::string recoName = hReco->GetName();
+    if(recoName.find("_b_") < recoName.length()) hTruth = (TH1 *) m_jet_pt_b->Clone();
+    else if(recoName.find("_c_") < recoName.length()) hTruth = (TH1 *) m_jet_pt_c->Clone();
+    else if(recoName.find("_u_") < recoName.length()) hTruth = (TH1 *) m_jet_pt_l->Clone();
+    if (!hTruth || hTruth->GetNbinsX() != hReco->GetNbinsX() || hTruth->Integral() == 0) return;
+    else{
+      for (int bin_i=1; bin_i<= hTruth->GetNbinsX(); ++bin_i){ 
+        if(hTruth->GetBinContent(bin_i) == 0) continue;
+        double eff = hReco->GetBinContent(bin_i)/hTruth->GetBinContent(bin_i);
+        //double eff_err = sqrt(hReco->GetBinContent(bin_i)*(1-eff))/hTruth->GetBinContent(bin_i);        
+        double pt = hTruth->GetBinCenter(bin_i);    
+        pEff->Fill(pt,eff);
+      }
+    }
+  }
+
+  void BTaggingValidationPlots::makeEfficiencyPlot(TH1* hReco, TProfile* pEff){
+    //double Ntrue = hReco->Integral();        
+    double Ntrue = hReco->Integral(0,hReco->GetNbinsX()+1);
+    std::string recoName =  hReco->GetName();
+    if(Ntrue == 0) return;
+    for (int bin_i=0; bin_i<= hReco->GetNbinsX()+1; ++bin_i){ 
+      double eff = hReco->Integral(bin_i, hReco->GetNbinsX())/Ntrue;
+      //double eff_err = sqrt(hReco->GetBinContent(bin_i)*(1-eff))/Ntrue;
+      double weight = hReco->GetBinCenter(bin_i);    
+      pEff->Fill(weight,eff);
+    }        
+  }
+
+  void BTaggingValidationPlots::makeEfficiencyRejectionPlot(TProfile* pLEff, TProfile* pEffRej){    
+    TProfile* pBEff=NULL;
+    //std::cout << "HIER NAME " << pEffRej->GetName() << std::endl;
+    std::string bEffName = pEffRej->GetName();
+    //std::cout << "name of rej vs eff histo " << pEffRej->GetName() << std::endl;
+    for(std::vector<std::string>::const_iterator tag_iter = m_taggers.begin(); tag_iter != m_taggers.end(); 
+          ++tag_iter){
+      if(bEffName.find(*tag_iter+"_") < 1) pBEff = (TProfile *) (m_eff_profiles.find(*tag_iter+"_b_eff_weight")->second)->Clone();
+        //std::cout << "name of used b-eff histo " << pBEff->GetName() << "\t name of used l-eff histo " << pLEff->GetName() << std::endl; }
+    }
+    if (!pBEff || pBEff->GetNbinsX() != pLEff->GetNbinsX()) return;
+    else{
+      for (int bin_i=1; bin_i<= pBEff->GetNbinsX(); ++bin_i){ 
+        double eff = pBEff->GetBinContent(bin_i);
+        double rej = 1/(pLEff->GetBinContent(bin_i));
+        //std::cout << "bin no.: " << bin_i << "\t b-bin: " << pBEff->GetBinCenter(bin_i) << "\t l-bin: " << pLEff->GetBinCenter(bin_i) << std::endl; 
+        //std::cout << "b-eff: " << eff << "\t l-eff: " << 1/rej << "\t rej: " << rej << std::endl;
+        pEffRej->Fill(eff,rej);
+      }        
+    }
+  }
+
+
+  void BTaggingValidationPlots::setTaggerInfos(){
+    // list of all taggers
+    m_taggers.push_back("IP3D");
+    m_taggers.push_back("IP2D");
+    m_taggers.push_back("RNNIP");
+    m_taggers.push_back("SV1");
+    m_taggers.push_back("IP3DSV1");
+    m_taggers.push_back("JetFitter");
+    m_taggers.push_back("MV2c10");
+    m_taggers.push_back("DL1");
+    m_taggers.push_back("DL1r");
+
+    // list of all truth labels
+    m_truthLabels.insert(std::make_pair("b", 5));
+    m_truthLabels.insert(std::make_pair("c", 4));
+    m_truthLabels.insert(std::make_pair("u", 0));
+    //m_truthLabels.insert(std::make_pair("tau", 15));
+
+    // -- all da WP definitions --
+    // IP3D (rel. 16 MC10 Dec. 10)
+    m_IP3D_workingPoints.insert(std::make_pair("70", 1.2));
+    if(m_detailLevel > 10){
+    m_IP3D_workingPoints.insert(std::make_pair("50", 3.75));
+    m_IP3D_workingPoints.insert(std::make_pair("80", -0.3));
+    }
+
+    // IP2D (rel. 16 MC10 Dec. 10)
+    m_IP2D_workingPoints.insert(std::make_pair("70", 0.7));
+    if(m_detailLevel > 10){
+    m_IP2D_workingPoints.insert(std::make_pair("50", 2.9));
+    m_IP2D_workingPoints.insert(std::make_pair("80", -0.5));
+    }
+    
+    // RNNIP (privately determined)
+    m_RNNIP_fc = 0.018;
+    m_RNNIP_workingPoints.insert(std::make_pair("70", 2.4996)); 
+    if(m_detailLevel > 10){
+    m_RNNIP_workingPoints.insert(std::make_pair("60", 3.8350)); 
+    m_RNNIP_workingPoints.insert(std::make_pair("77", 1.4370)); 
+    m_RNNIP_workingPoints.insert(std::make_pair("85", -0.0568)); 
+    }
+    //// these are the alternative WP values for a fc value of 0.07
+    //// m_RNNIP_fc = 0.07;
+    //// m_RNNIP_workingPoints.insert(std::make_pair("70", 2.3126)); 
+    //// if(m_detailLevel > 10){
+    ////   m_RNNIP_workingPoints.insert(std::make_pair("60", 3.4148)); 
+    ////   m_RNNIP_workingPoints.insert(std::make_pair("77", 1.3644)); 
+    ////   m_RNNIP_workingPoints.insert(std::make_pair("85", -0.0502)); 
+    //// }
+    
+    // SV1 (rel 16 Mc10 Dec 10)
+    m_SV1_workingPoints.insert(std::make_pair("60", 1.6));
+    if(m_detailLevel > 10){
+    m_SV1_workingPoints.insert(std::make_pair("40", 5.5));
+    m_SV1_workingPoints.insert(std::make_pair("50", 3.9));
+    }
+
+    // IP3DSV1 (rel 17 Mc11b Dec. 11)
+    m_IP3DSV1_workingPoints.insert(std::make_pair("70", 1.85));
+    if(m_detailLevel > 10){
+      m_IP3DSV1_workingPoints.insert(std::make_pair("50", 7.6));
+    m_IP3DSV1_workingPoints.insert(std::make_pair("80", -0.7));    
+    }
+
+    // JetFitter (self determined)
+    m_JetFitter_workingPoints.insert(std::make_pair("70", -1.7));
+    if(m_detailLevel > 10){
+      m_JetFitter_workingPoints.insert(std::make_pair("50", 0.9));
+    m_JetFitter_workingPoints.insert(std::make_pair("80", -3.3));
+    }
+      
+    if (m_sParticleType=="antiKt4EMPFlowJets"){ // these WP values were read from the CDI file 
+      // MV2c10   (PFlow 2018_10)
+      m_MV2c10_workingPoints.insert(std::make_pair("70", 0.826829));
+      if(m_detailLevel > 10){
+        m_MV2c10_workingPoints.insert(std::make_pair("60", 0.939187));
+        m_MV2c10_workingPoints.insert(std::make_pair("77", 0.629222));
+        m_MV2c10_workingPoints.insert(std::make_pair("85", 0.0722749));
+      }
+  
+      // DL1   (PFlow 2019_03)
+      m_DL1_fc = 0.018;
+      m_DL1_workingPoints.insert(std::make_pair("70", 3.095));
+      if(m_detailLevel > 10){
+        m_DL1_workingPoints.insert(std::make_pair("60", 4.415));
+        m_DL1_workingPoints.insert(std::make_pair("77", 2.015));
+        m_DL1_workingPoints.insert(std::make_pair("85", 0.365));
+      }
+
+      // DL1r   (PFlow 2019_03)
+      m_DL1r_fc = 0.018;
+      m_DL1r_workingPoints.insert(std::make_pair("70", 3.245));
+      if(m_detailLevel > 10){
+        m_DL1r_workingPoints.insert(std::make_pair("60", 4.565));
+        m_DL1r_workingPoints.insert(std::make_pair("77", 2.195));
+        m_DL1r_workingPoints.insert(std::make_pair("85", 0.665));
+      }
+    }
+      
+    else if (m_sParticleType=="antiKt4EMTopoJets"){ // these WP values were read from the CDI file 
+      // MV2c10   (EMTopo 2018_10)
+      m_MV2c10_workingPoints.insert(std::make_pair("70", 0.830283));
+      if(m_detailLevel > 10){
+        m_MV2c10_workingPoints.insert(std::make_pair("60", 0.939018));
+        m_MV2c10_workingPoints.insert(std::make_pair("77", 0.643362));
+        m_MV2c10_workingPoints.insert(std::make_pair("85", 0.108029));
+      }
+  
+      // DL1   (EMTopo 2018_10)
+      m_DL1_fc = 0.080;
+      m_DL1_workingPoints.insert(std::make_pair("70", 2.01505));
+      if(m_detailLevel > 10){
+        m_DL1_workingPoints.insert(std::make_pair("60", 2.73599));
+        m_DL1_workingPoints.insert(std::make_pair("77", 1.44686));
+        m_DL1_workingPoints.insert(std::make_pair("85", 0.463453));
+    }
+
+      // DL1r   (no WPs for EMTopo! use Pflow ones: PFlow 2019_03)
+      m_DL1r_fc = 0.018;
+      m_DL1r_workingPoints.insert(std::make_pair("70", 3.245));
+      if(m_detailLevel > 10){
+        m_DL1r_workingPoints.insert(std::make_pair("60", 4.565));
+        m_DL1r_workingPoints.insert(std::make_pair("77", 2.195));
+        m_DL1r_workingPoints.insert(std::make_pair("85", 0.665));
+      }
+    }
+
+    else if (m_sParticleType=="antiKt2PV0TrackJets"){ //  these WP values were taken from this twiki in Dec 2020: https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/BTaggingBenchmarksRelease21#DL1_tagger
+      // MV2c10
+      m_MV2c10_workingPoints.insert(std::make_pair("70", 0.66));
+      if(m_detailLevel > 10){
+      m_MV2c10_workingPoints.insert(std::make_pair("60", 0.86));
+      m_MV2c10_workingPoints.insert(std::make_pair("77", 0.38));
+      m_MV2c10_workingPoints.insert(std::make_pair("85", -0.15));
+      }
+  
+      // DL1
+      m_DL1_fc = 0.080;
+      m_DL1_workingPoints.insert(std::make_pair("70", 1.47));
+      if(m_detailLevel > 10){
+      m_DL1_workingPoints.insert(std::make_pair("60", 2.13));
+      m_DL1_workingPoints.insert(std::make_pair("77", 0.89));
+      m_DL1_workingPoints.insert(std::make_pair("85", 0.13));
+      }
+
+      // DL1r
+      m_DL1r_fc = 0.030;
+      m_DL1r_workingPoints.insert(std::make_pair("70", 2.17));
+      if(m_detailLevel > 10){
+      m_DL1r_workingPoints.insert(std::make_pair("60", 2.89));
+      m_DL1r_workingPoints.insert(std::make_pair("77", 1.79));
+      m_DL1r_workingPoints.insert(std::make_pair("85", 1.07));
+    }
+    }
+
+    else if (m_sParticleType=="antiKtVR30Rmax4Rmin02TrackJets"){ //  these WP values were taken from this twiki in Dec 2020: https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/BTaggingBenchmarksRelease21#DL1_tagger
+      // MV2c10
+      m_MV2c10_workingPoints.insert(std::make_pair("70", 0.79));
+      if(m_detailLevel > 10){
+      m_MV2c10_workingPoints.insert(std::make_pair("60", 0.92));
+      m_MV2c10_workingPoints.insert(std::make_pair("77", 0.58));
+      m_MV2c10_workingPoints.insert(std::make_pair("85", 0.05));
+      }
+  
+      // DL1
+      m_DL1_fc = 0.080;
+      m_DL1_workingPoints.insert(std::make_pair("70", 1.81));
+      if(m_detailLevel > 10){
+      m_DL1_workingPoints.insert(std::make_pair("60", 2.50));
+      m_DL1_workingPoints.insert(std::make_pair("77", 1.31));
+      m_DL1_workingPoints.insert(std::make_pair("85", 0.42));
+      }
+
+      // DL1r
+      m_DL1r_fc = 0.030;
+      m_DL1r_workingPoints.insert(std::make_pair("70", 2.71));
+      if(m_detailLevel > 10){
+      m_DL1r_workingPoints.insert(std::make_pair("60", 3.88));
+      m_DL1r_workingPoints.insert(std::make_pair("77", 2.06));
+      m_DL1r_workingPoints.insert(std::make_pair("85", 1.31));
+    }
+    }
+
+    else { // no WPs defined for this jet collection ... -- use the PFlow WPs // these WP values were read from the CDI file 
+      // MV2c10   (PFlow 2018_10)
+      m_MV2c10_workingPoints.insert(std::make_pair("70", 0.826829));
+      if(m_detailLevel > 10){
+        m_MV2c10_workingPoints.insert(std::make_pair("60", 0.939187));
+        m_MV2c10_workingPoints.insert(std::make_pair("77", 0.629222));
+        m_MV2c10_workingPoints.insert(std::make_pair("85", 0.0722749));
+      }
+  
+      // DL1   (PFlow 2019_03)
+      m_DL1_fc = 0.018;
+      m_DL1_workingPoints.insert(std::make_pair("70", 3.095));
+      if(m_detailLevel > 10){
+        m_DL1_workingPoints.insert(std::make_pair("60", 4.415));
+        m_DL1_workingPoints.insert(std::make_pair("77", 2.015));
+        m_DL1_workingPoints.insert(std::make_pair("85", 0.365));
+      }
+  
+      // DL1r   (PFlow 2019_03)
+      m_DL1r_fc = 0.018;
+      m_DL1r_workingPoints.insert(std::make_pair("70", 3.245));
+      if(m_detailLevel > 10){
+        m_DL1r_workingPoints.insert(std::make_pair("60", 4.565));
+        m_DL1r_workingPoints.insert(std::make_pair("77", 2.195));
+        m_DL1r_workingPoints.insert(std::make_pair("85", 0.665));
+      }
+    }
+  }
+  
+  void BTaggingValidationPlots::bookEffHistos(){
+    setTaggerInfos();
+    for(std::vector<std::string>::const_iterator tag_iter = m_taggers.begin(); tag_iter != m_taggers.end(); 
+        ++tag_iter){
+
+      for(std::map<std::string, int>::const_iterator label_iter = m_truthLabels.begin(); label_iter != m_truthLabels.end(); 
+        ++label_iter){
+
+        // book discriminant histograms
+        std::string histo_name_matched = *tag_iter+"_"+label_iter->first+"_matched_weight";
+        std::string var_name_matched = "llr";
+        if((*tag_iter).find("MV") < 1) var_name_matched += "_MV";
+        else if(*tag_iter == "IP2D" || *tag_iter == "IP3DSV1") var_name_matched += "_old_taggers";
+        TH1* histo_matched = bookHistogram(histo_name_matched, var_name_matched, m_sParticleType, label_iter->first + "-jets" + ", " + *tag_iter);    
+        m_weight_histos.insert(std::make_pair(histo_name_matched, histo_matched));
+
+        // book discriminant with nTracksCut histograms
+        std::string histo_name_trackCuts = *tag_iter+"_"+label_iter->first+"_matched_weight_trackCuts";
+        std::string var_name_trackCuts = "llr_nTracksCut";
+        if((*tag_iter).find("MV") < 1) var_name_trackCuts += "_MV";
+        else if(*tag_iter == "IP2D" || *tag_iter == "IP3DSV1") var_name_trackCuts += "_old_taggers";
+        TH1* histo_trackCuts = bookHistogram(histo_name_trackCuts, var_name_trackCuts, m_sParticleType, label_iter->first + "-jets" + ", " + *tag_iter);    
+        m_weight_histos.insert(std::make_pair(histo_name_trackCuts, histo_trackCuts));
+        
+        // book effieciency vs rejection profile
+        std::string profile_name_effRej = *tag_iter+"_"+label_iter->first+"_eff_rej";
+        TProfile* profile_effRej = bookProfile(profile_name_effRej, "efficiency_vs_rejection", m_sParticleType, "rejection of " + label_iter->first + "-jets" + " for " + *tag_iter);
+        m_eff_profiles.insert(std::make_pair(profile_name_effRej, profile_effRej));
+        
+        // book the eff vs llr profiles
+        std::string profile_name_effLlr = *tag_iter+"_"+label_iter->first+"_eff_weight";
+        std::string var_name_eff_vs_llr = "efficiency_vs_llr";
+        if((*tag_iter).find("MV") < 1) var_name_eff_vs_llr += "_MV";
+        TProfile* profile_effLlr = bookProfile(profile_name_effLlr, var_name_eff_vs_llr, m_sParticleType, label_iter->first + "-jets" + ", " + *tag_iter);
+        m_eff_profiles.insert(std::make_pair(profile_name_effLlr, profile_effLlr));
+
+        // book the vs pT profiles (the bool in the argument says if it is an old tagger (for sub-folder sorting later))
+        // IP3D
+        if(*tag_iter == "IP3D"){
+          bookDiscriminantVsPTAndLxyHistograms("IP3D", m_IP3D_workingPoints, false, label_iter, m_sParticleType);
+        }
+        // IP2D
+        else if(*tag_iter == "IP2D"){
+          bookDiscriminantVsPTAndLxyHistograms("IP2D", m_IP2D_workingPoints, true, label_iter, m_sParticleType);
+        }
+        // RNNIP
+        else if(*tag_iter == "RNNIP"){
+          bookDiscriminantVsPTAndLxyHistograms("RNNIP", m_RNNIP_workingPoints, false, label_iter, m_sParticleType);
+        }
+        // SV1
+        else if(*tag_iter == "SV1"){
+          bookDiscriminantVsPTAndLxyHistograms("SV1", m_SV1_workingPoints, false, label_iter, m_sParticleType);
+        }
+        // IP3DSV1
+        else if(*tag_iter == "IP3DSV1"){
+          bookDiscriminantVsPTAndLxyHistograms("IP3DSV1", m_IP3DSV1_workingPoints, true, label_iter, m_sParticleType);
+        } 
+        // JetFitter
+        else if(*tag_iter == "JetFitter"){
+          bookDiscriminantVsPTAndLxyHistograms("JetFitter", m_JetFitter_workingPoints, false, label_iter, m_sParticleType);
+        }
+        //MV2c10
+        else if(*tag_iter == "MV2c10"){
+          bookDiscriminantVsPTAndLxyHistograms("MV2c10", m_MV2c10_workingPoints, true, label_iter, m_sParticleType);
+        }
+        //Dl1
+        else if(*tag_iter == "DL1"){
+          bookDiscriminantVsPTAndLxyHistograms("DL1", m_DL1_workingPoints, false, label_iter, m_sParticleType);
+        }
+        //Dl1r
+        else if(*tag_iter == "DL1r"){
+          bookDiscriminantVsPTAndLxyHistograms("DL1r", m_DL1r_workingPoints, false, label_iter, m_sParticleType);
+        }
+
+      }
+    }
+
+    bookNJetsThatPassedWPCutsHistos();
+
+  }
+      
 }
diff --git a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/BTaggingValidationPlots.h b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/BTaggingValidationPlots.h
index 364f318fe197b05dcd167b259e3c7d2d53b34b62..836543efaa1ed5a0c5328e7d17f32f2faea15cd4 100644
--- a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/BTaggingValidationPlots.h
+++ b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/BTaggingValidationPlots.h
@@ -1,112 +1,655 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef JETTAGDQA_BTagPLOTS_H
 #define JETTAGDQA_BTagPLOTS_H
-	
+    
 #include "xAODBase/IParticle.h"
 #include "TrkValHistUtils/PlotBase.h"
 #include "CLHEP/Units/SystemOfUnits.h"
 #include "xAODBTagging/BTagging.h" 
+#include "xAODJet/JetContainer.h"
+#include "xAODTruth/TruthParticle.h"
+#include "xAODTruth/TruthParticleContainer.h"
+#include "xAODTruth/TruthVertex.h"
 #include "xAODJet/Jet.h"
+#include "xAODMuon/Muon.h"
+#include "xAODMuon/MuonContainer.h"
 //#include "GAFlavourLabel.h"
-	
+#include "xAODEventInfo/EventInfo.h"
+
+#include "InDetTrackSystematicsTools/InDetTrackTruthOriginDefs.h"
+
+    
 namespace JetTagDQA{
  
-	class BTaggingValidationPlots:public PlotBase {
-		public:
-		BTaggingValidationPlots(PlotBase* pParent, std::string sDir, std::string sParticleType);
-		void fill(const xAOD::BTagging* btag);
-		void fill(unsigned int nbtag);
-		void fill(int truthLabel);
-		void fill(const xAOD::Jet* jet);
-		//void fill(const xAOD::Jet* jet, const xAOD::BTagging* btag);
-		void fill(const xAOD::Jet* jet, const xAOD::BTagging* btag, const xAOD::Vertex *myVertex);
-
-		void makeEfficiencyVsPtPlot(TH1* hReco, TProfile* pEff);
-		void makeEfficiencyPlot(TH1* hReco, TProfile* pEff);
-		void makeEfficiencyRejectionPlot(TProfile* pLEff, TProfile* pEffRej);
-		void setTaggerInfos();	
-		void bookEffHistos();
-
-
-		// Reco only information
-		std::string m_sParticleType;
-
-		//JVT jet flag 
-		bool m_isJVT_defined;
-		float m_jvt_cut;
-
-		TH1* m_truthLabel = nullptr;
-//		TH1* m_GAFinalHadronLabel;
-//		TH1* m_GAInitialHadronLabel;
-//		TH1* m_GAFinalPartonLabel;
-
-//		TH1* m_GAFinalHadronC_dR;
-//		TH1* m_GAInitialHadronC_dR;
-//		TH1* m_GAFinalPartonC_dR;
-//		TH1* m_GAFinalHadronTau_dR;
-
-		TH1* m_truthPt_b = nullptr;
-		TH1* m_truthPt_u = nullptr;
-		TH1* m_truthPt_c = nullptr;
-		TH1* m_truthPt_tau = nullptr;
-
-		TH1* m_IP3D_pb = nullptr;
-		TH1* m_IP3D_pc = nullptr;
-		TH1* m_IP3D_pu = nullptr;
-
-		TH1* m_SV1_pb = nullptr;
-		TH1* m_SV1_pc = nullptr;
-		TH1* m_SV1_pu = nullptr;
-		
-		TH1* m_SV1_NGTinSvx = nullptr;
-		TH1* m_SV0_NGTinSvx = nullptr;
-		TH1* m_IP3D_nTracks = nullptr;
-		TH1* m_IP2D_nTracks = nullptr;
-
-		TH1* m_e = nullptr;
-		TH1* m_pt = nullptr;
-	      	TH1* m_eta = nullptr;
-	      	TH1* m_phi = nullptr;
-
-		//ANDREA --- Store tranking info
-		TH1* m_track_d0 = nullptr;
-		TH1* m_track_z0 = nullptr;
-		TH1* m_track_sigd0 = nullptr;
-		TH1* m_track_sigz0 = nullptr;
-
-		//ANDREA -- IPTag categories
-		TH1* m_IP3D_trackGrading = nullptr;
-		TH1* m_IP2D_trackGrading = nullptr;
-		TH1* m_tmpD0 = nullptr;
-		TH1* m_tmpZ0 = nullptr;
-		TH1* m_tmpD0sig = nullptr;
-		TH1* m_tmpZ0sig = nullptr;
-		TH1* m_tmpIP3DBwgt = nullptr;
-		TH1* m_tmpIP3DUwgt = nullptr;
-		TH1* m_tmpIP2DBwgt = nullptr;
-		TH1* m_tmpIP2DUwgt = nullptr;
-		
-		std::vector<std::string> m_taggers;
-		std::map<std::string, int> m_truthLabels;
-		std::map<std::string, double> m_IP3D_workingPoints;
-		std::map<std::string, double> m_IP2D_workingPoints;
-		std::map<std::string, double> m_SV1_workingPoints;
-		std::map<std::string, double> m_SV0_workingPoints;
-		std::map<std::string, double> m_IP3DSV1_workingPoints;
-		std::map<std::string, double> m_JetFitter_workingPoints;
-		std::map<std::string, double> m_JetFitterCombNN_workingPoints;
-		std::map<std::string, double> m_MV1_workingPoints;
-		std::map<std::string, TH1*> m_weight_histos; 
-		std::map<std::string, TProfile*> m_eff_profiles; 
-	
-		private:
-		virtual void initializePlots();     
-		virtual void finalizePlots(); 
-	};
-	
+  class BTaggingValidationPlots:public PlotBase {
+    public:
+      // constructor
+      BTaggingValidationPlots(PlotBase* pParent, std::string sDir, std::string sParticleType);
+
+      // fill methods
+      void fillJetKinVars(const xAOD::Jet* jet, const int& truth_label, const bool& onZprime, const xAOD::EventInfo* event);
+      void fillDiscriminantVariables(const xAOD::BTagging* btag, const xAOD::Jet* jet, const double& jet_Lxy, const int& truth_label, const bool& has_muon, const bool& onZprime, std::map<std::string, int>& nJetsThatPassedWPCuts, const xAOD::EventInfo* event);
+      void fillMultiplicities(const unsigned int& nJets, const unsigned int& nTracks, const int& nPrimVtx, const unsigned int& nTracksPrimVtx, const unsigned int& nJetsWithMuon, const unsigned int& nJetsWithSV, std::map<std::string, int>& nJetsThatPassedWPCuts, const xAOD::EventInfo* event);
+      void fillPVVariables(const double& PV_x, const double& PV_y, const double& PV_z, const xAOD::EventInfo* event);
+      void fillOther(const xAOD::Jet* jet, const xAOD::BTagging* btag, bool& contains_muon, double& jet_Lxy, const int& truth_label, const xAOD::EventInfo* event); 
+      void fillTrackVariables(const xAOD::Jet* jet, const xAOD::BTagging* btag, const xAOD::Vertex *myVertex, std::map<const xAOD::TrackParticle*, int> track_truth_associations, const bool& contains_muon, const int& truth_label, int& num_HF_tracks_in_jet, const xAOD::EventInfo* event); 
+      void fillSVVariables(const xAOD::Jet* jet, const xAOD::BTagging* btag, std::map<const xAOD::TrackParticle*, int> track_truth_associations, const bool& contains_muon, const int& truth_label, const int& num_HF_tracks_in_jet, bool& contains_SV, const xAOD::EventInfo* event); 
+
+      void bookNJetsThatPassedWPCutsHistos();
+      void initializeNJetsThatPassedWPCutsMap(std::map<std::string, int>& nJetsThatPassedWPCuts);
+      void updateNJetsThatPassedWPCutsMap(std::map<std::string, int>& nJetsThatPassedWPCuts, const double& discr_IP3D, const double& discr_IP2D, const double& discr_RNNIP, const double& discr_SV1, const double& discr_IP3DSV1, const double& discr_JetFitter, const double& discr_MV2c10, const double& discr_DL1, const double& discr_DL1r);
+      void fillNJetsThatPassedWPCutsHistos(std::map<std::string, int>& nJetsThatPassedWPCuts, const xAOD::EventInfo* event);
+
+      void makeEfficiencyVsPtPlot(TH1* hReco, TProfile* pEff);
+      void makeEfficiencyPlot(TH1* hReco, TProfile* pEff);
+      void makeEfficiencyRejectionPlot(TProfile* pLEff, TProfile* pEffRej);
+      void setTaggerInfos();    
+      void bookEffHistos();
+
+      // Reco only information
+      std::string m_sParticleType;
+
+      // multiplicities
+      TH1* m_nJets = nullptr;
+      TH1* m_nTracks = nullptr;
+      TH1* m_nPrimVtx = nullptr;
+      TH1* m_nTracksPrimVtx = nullptr;
+      TH1* m_nJetsWithMuon = nullptr;
+      TH1* m_nJetsWithSV = nullptr;
+      TH1* m_fracJetsWithMuon = nullptr;
+      TH1* m_fracJetsWithSV = nullptr;
+
+      // PV variables
+      TH1* m_PV_x = nullptr;
+      TH1* m_PV_y = nullptr;
+      TH1* m_PV_z = nullptr;
+
+      // jet kinematic variables
+      TH1* m_jet_e = nullptr;
+      TH1* m_jet_e_Zprime = nullptr;
+      TH1* m_jet_pt = nullptr;
+      TH1* m_jet_pt_Zprime = nullptr;
+      TH1* m_jet_eta = nullptr;
+      TH1* m_jet_phi = nullptr;
+
+      // muon vars
+      TH1* m_muon_pT_frac = nullptr;
+
+      // truth info
+      TH1* m_truthLabel = nullptr;
+
+      TH1* m_jet_pt_b = nullptr;
+      TH1* m_jet_pt_c = nullptr;
+      TH1* m_jet_pt_l = nullptr;
+      TH1* m_jet_pt_Zprime_b = nullptr;
+      TH1* m_jet_pt_Zprime_c = nullptr;
+      TH1* m_jet_pt_Zprime_l = nullptr;
+      TH1* m_jet_eta_b = nullptr;
+      TH1* m_jet_eta_c = nullptr;
+      TH1* m_jet_eta_l = nullptr;
+
+
+      // SV1 related vars
+      TH1* m_SV1_numSVs_incl = nullptr;
+      TH1* m_SV1_masssvx_incl = nullptr;
+      TH1* m_SV1_N2Tpair_incl = nullptr;
+      TH1* m_SV1_efracsvx_incl = nullptr;
+      TH1* m_SV1_deltaR_incl = nullptr;
+      TH1* m_SV1_significance3d_incl = nullptr;
+      TH1* m_SV1_energyTrkInJet_incl = nullptr;
+      TH1* m_SV1_NGTinSvx_incl = nullptr;
+      TH1* m_SV1_Lxy_incl = nullptr;
+      TH1* m_SV1_purity_incl = nullptr;
+      TH1* m_SV1_numSVs_b = nullptr;
+      TH1* m_SV1_masssvx_b = nullptr;
+      TH1* m_SV1_N2Tpair_b = nullptr;
+      TH1* m_SV1_efracsvx_b = nullptr;
+      TH1* m_SV1_deltaR_b = nullptr;
+      TH1* m_SV1_significance3d_b = nullptr;
+      TH1* m_SV1_energyTrkInJet_b = nullptr;
+      TH1* m_SV1_NGTinSvx_b = nullptr;
+      TH1* m_SV1_Lxy_b = nullptr;
+      TH1* m_SV1_purity_b = nullptr;
+      TH1* m_SV1_numSVs_c = nullptr;
+      TH1* m_SV1_masssvx_c = nullptr;
+      TH1* m_SV1_N2Tpair_c = nullptr;
+      TH1* m_SV1_efracsvx_c = nullptr;
+      TH1* m_SV1_deltaR_c = nullptr;
+      TH1* m_SV1_significance3d_c = nullptr;
+      TH1* m_SV1_energyTrkInJet_c = nullptr;
+      TH1* m_SV1_NGTinSvx_c = nullptr;
+      TH1* m_SV1_Lxy_c = nullptr;
+      TH1* m_SV1_purity_c = nullptr;
+      TH1* m_SV1_numSVs_l = nullptr;
+      TH1* m_SV1_masssvx_l = nullptr;
+      TH1* m_SV1_N2Tpair_l = nullptr;
+      TH1* m_SV1_efracsvx_l = nullptr;
+      TH1* m_SV1_deltaR_l = nullptr;
+      TH1* m_SV1_significance3d_l = nullptr;
+      TH1* m_SV1_energyTrkInJet_l = nullptr;
+      TH1* m_SV1_NGTinSvx_l = nullptr;
+      TH1* m_SV1_Lxy_l = nullptr;
+      TH1* m_SV1_purity_l = nullptr;
+      TH1* m_SV1_numSVs_muon = nullptr;
+      TH1* m_SV1_masssvx_muon = nullptr;
+      TH1* m_SV1_N2Tpair_muon = nullptr;
+      TH1* m_SV1_efracsvx_muon = nullptr;
+      TH1* m_SV1_deltaR_muon = nullptr;
+      TH1* m_SV1_significance3d_muon = nullptr;
+      TH1* m_SV1_energyTrkInJet_muon = nullptr;
+      TH1* m_SV1_NGTinSvx_muon = nullptr;
+      TH1* m_SV1_Lxy_muon = nullptr;
+      TH1* m_SV1_purity_muon = nullptr;
+
+      TH1* m_SV1_fracHFTracksInJet_incl = nullptr;
+      TH1* m_SV1_fracHFTracksInJet_b = nullptr;
+      TH1* m_SV1_fracHFTracksInJet_c = nullptr;
+      TH1* m_SV1_fracHFTracksInJet_l = nullptr;
+      TH1* m_SV1_fracHFTracksInJet_muon = nullptr;
+      
+      TH1* m_SV1_fracTracks_fromB_incl = nullptr;
+      TH1* m_SV1_fracTracks_fromB_b = nullptr;
+      TH1* m_SV1_fracTracks_fromB_c = nullptr;
+      TH1* m_SV1_fracTracks_fromB_l = nullptr;
+      TH1* m_SV1_fracTracks_fromB_muon = nullptr;
+      TH1* m_SV1_fracTracks_fromC_incl = nullptr;
+      TH1* m_SV1_fracTracks_fromC_b = nullptr;
+      TH1* m_SV1_fracTracks_fromC_c = nullptr;
+      TH1* m_SV1_fracTracks_fromC_l = nullptr;
+      TH1* m_SV1_fracTracks_fromC_muon = nullptr;
+      TH1* m_SV1_fracTracks_fromFragmentation_incl = nullptr;
+      TH1* m_SV1_fracTracks_fromFragmentation_b = nullptr;
+      TH1* m_SV1_fracTracks_fromFragmentation_c = nullptr;
+      TH1* m_SV1_fracTracks_fromFragmentation_l = nullptr;
+      TH1* m_SV1_fracTracks_fromFragmentation_muon = nullptr;
+      TH1* m_SV1_fracTracks_fromSecondaries_incl = nullptr;
+      TH1* m_SV1_fracTracks_fromSecondaries_b = nullptr;
+      TH1* m_SV1_fracTracks_fromSecondaries_c = nullptr;
+      TH1* m_SV1_fracTracks_fromSecondaries_l = nullptr;
+      TH1* m_SV1_fracTracks_fromSecondaries_muon = nullptr;
+      TH1* m_SV1_fracTracks_fromPileup_incl = nullptr;
+      TH1* m_SV1_fracTracks_fromPileup_b = nullptr;
+      TH1* m_SV1_fracTracks_fromPileup_c = nullptr;
+      TH1* m_SV1_fracTracks_fromPileup_l = nullptr;
+      TH1* m_SV1_fracTracks_fromPileup_muon = nullptr;
+      TH1* m_SV1_fracTracks_fromFake_incl = nullptr;
+      TH1* m_SV1_fracTracks_fromFake_b = nullptr;
+      TH1* m_SV1_fracTracks_fromFake_c = nullptr;
+      TH1* m_SV1_fracTracks_fromFake_l = nullptr;
+      TH1* m_SV1_fracTracks_fromFake_muon = nullptr;
+
+      // these are only filled for detail level above 10
+      TH1* m_SV1_fracTracks_Secondaries_KshortDecay_incl = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_KshortDecay_b = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_KshortDecay_c = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_KshortDecay_u = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_KshortDecay_muon = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_LambdaDecay_incl = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_LambdaDecay_b = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_LambdaDecay_c = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_LambdaDecay_u = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_LambdaDecay_muon = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_GammaConversion_incl = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_GammaConversion_b = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_GammaConversion_c = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_GammaConversion_u = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_GammaConversion_muon = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_OtherDecay_incl = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_OtherDecay_b = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_OtherDecay_c = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_OtherDecay_u = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_OtherDecay_muon = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_HadronicInteraction_incl = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_HadronicInteraction_b = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_HadronicInteraction_c = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_HadronicInteraction_u = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_HadronicInteraction_muon = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_OtherSecondary_incl = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_OtherSecondary_b = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_OtherSecondary_c = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_OtherSecondary_u = nullptr; 
+      TH1* m_SV1_fracTracks_Secondaries_OtherSecondary_muon = nullptr; 
+      TH1* m_SV1_fracTracks_OtherOrigin_incl = nullptr; 
+      TH1* m_SV1_fracTracks_OtherOrigin_b = nullptr; 
+      TH1* m_SV1_fracTracks_OtherOrigin_c = nullptr; 
+      TH1* m_SV1_fracTracks_OtherOrigin_u = nullptr; 
+      TH1* m_SV1_fracTracks_OtherOrigin_muon = nullptr; 
+
+      // MSV related vars 
+      TH1* m_MSV_nvsec_incl = nullptr;
+      TH1* m_MSV_N2Tpair_incl = nullptr;
+      TH1* m_MSV_energyTrkInJet_incl = nullptr;
+      TH1* m_MSV_normdist_incl = nullptr;
+      TH1* m_MSV_purity_incl = nullptr;
+      TH1* m_MSV_vtx_mass_incl = nullptr;
+      TH1* m_MSV_nvsec_b = nullptr;
+      TH1* m_MSV_N2Tpair_b = nullptr;
+      TH1* m_MSV_energyTrkInJet_b = nullptr;
+      TH1* m_MSV_normdist_b = nullptr;
+      TH1* m_MSV_purity_b = nullptr;
+      TH1* m_MSV_vtx_mass_b = nullptr;
+      TH1* m_MSV_nvsec_c = nullptr;
+      TH1* m_MSV_N2Tpair_c = nullptr;
+      TH1* m_MSV_energyTrkInJet_c = nullptr;
+      TH1* m_MSV_normdist_c = nullptr;
+      TH1* m_MSV_purity_c = nullptr;
+      TH1* m_MSV_vtx_mass_c = nullptr;
+      TH1* m_MSV_nvsec_l = nullptr;
+      TH1* m_MSV_N2Tpair_l = nullptr;
+      TH1* m_MSV_energyTrkInJet_l = nullptr;
+      TH1* m_MSV_normdist_l = nullptr;
+      TH1* m_MSV_purity_l = nullptr;
+      TH1* m_MSV_vtx_mass_l = nullptr;
+      TH1* m_MSV_nvsec_muon = nullptr;
+      TH1* m_MSV_N2Tpair_muon = nullptr;
+      TH1* m_MSV_energyTrkInJet_muon = nullptr;
+      TH1* m_MSV_normdist_muon = nullptr;
+      TH1* m_MSV_purity_muon = nullptr;
+      TH1* m_MSV_vtx_mass_muon = nullptr;
+
+      // JetFitter related vars
+      TH1* m_JetFitter_N2Tpair_incl = nullptr;
+      TH1* m_JetFitter_nVTX_incl = nullptr;
+      TH1* m_JetFitter_nSingleTracks_incl = nullptr;
+      TH1* m_JetFitter_nTracksAtVtx_incl = nullptr;
+      TH1* m_JetFitter_mass_incl = nullptr;
+      TH1* m_JetFitter_energyFraction_incl = nullptr;
+      TH1* m_JetFitter_significance3d_incl = nullptr;
+      TH1* m_JetFitter_purity_incl = nullptr;
+      TH1* m_JetFitter_N2Tpair_b = nullptr;
+      TH1* m_JetFitter_nVTX_b = nullptr;
+      TH1* m_JetFitter_nSingleTracks_b = nullptr;
+      TH1* m_JetFitter_nTracksAtVtx_b = nullptr;
+      TH1* m_JetFitter_mass_b = nullptr;
+      TH1* m_JetFitter_energyFraction_b = nullptr;
+      TH1* m_JetFitter_significance3d_b = nullptr;
+      TH1* m_JetFitter_purity_b = nullptr;
+      TH1* m_JetFitter_N2Tpair_c = nullptr;
+      TH1* m_JetFitter_nVTX_c = nullptr;
+      TH1* m_JetFitter_nSingleTracks_c = nullptr;
+      TH1* m_JetFitter_nTracksAtVtx_c = nullptr;
+      TH1* m_JetFitter_mass_c = nullptr;
+      TH1* m_JetFitter_energyFraction_c = nullptr;
+      TH1* m_JetFitter_significance3d_c = nullptr;
+      TH1* m_JetFitter_purity_c = nullptr;
+      TH1* m_JetFitter_N2Tpair_l = nullptr;
+      TH1* m_JetFitter_nVTX_l = nullptr;
+      TH1* m_JetFitter_nSingleTracks_l = nullptr;
+      TH1* m_JetFitter_nTracksAtVtx_l = nullptr;
+      TH1* m_JetFitter_mass_l = nullptr;
+      TH1* m_JetFitter_energyFraction_l = nullptr;
+      TH1* m_JetFitter_significance3d_l = nullptr;
+      TH1* m_JetFitter_purity_l = nullptr;
+      TH1* m_JetFitter_N2Tpair_muon = nullptr;
+      TH1* m_JetFitter_nVTX_muon = nullptr;
+      TH1* m_JetFitter_nSingleTracks_muon = nullptr;
+      TH1* m_JetFitter_nTracksAtVtx_muon = nullptr;
+      TH1* m_JetFitter_mass_muon = nullptr;
+      TH1* m_JetFitter_energyFraction_muon = nullptr;
+      TH1* m_JetFitter_significance3d_muon = nullptr;
+      TH1* m_JetFitter_purity_muon = nullptr;
+
+      // SV1 related Profiles
+      TProfile* m_SV1_masssvx_vs_pT_incl = nullptr;
+      TProfile* m_SV1_N2Tpair_vs_pT_incl = nullptr;
+      TProfile* m_SV1_efracsvx_vs_pT_incl = nullptr;
+      TProfile* m_SV1_deltaR_vs_pT_incl = nullptr;
+      TProfile* m_SV1_masssvx_vs_pT_b = nullptr;
+      TProfile* m_SV1_N2Tpair_vs_pT_b = nullptr;
+      TProfile* m_SV1_efracsvx_vs_pT_b = nullptr;
+      TProfile* m_SV1_deltaR_vs_pT_b = nullptr;
+      TProfile* m_SV1_masssvx_vs_pT_c = nullptr;
+      TProfile* m_SV1_N2Tpair_vs_pT_c = nullptr;
+      TProfile* m_SV1_efracsvx_vs_pT_c = nullptr;
+      TProfile* m_SV1_deltaR_vs_pT_c = nullptr;
+      TProfile* m_SV1_masssvx_vs_pT_l = nullptr;
+      TProfile* m_SV1_N2Tpair_vs_pT_l = nullptr;
+      TProfile* m_SV1_efracsvx_vs_pT_l = nullptr;
+      TProfile* m_SV1_deltaR_vs_pT_l = nullptr;
+
+      TProfile* m_SV1_masssvx_vs_eta_incl = nullptr;
+      TProfile* m_SV1_N2Tpair_vs_eta_incl = nullptr;
+      TProfile* m_SV1_efracsvx_vs_eta_incl = nullptr;
+      TProfile* m_SV1_deltaR_vs_eta_incl = nullptr;
+      TProfile* m_SV1_masssvx_vs_eta_b = nullptr;
+      TProfile* m_SV1_N2Tpair_vs_eta_b = nullptr;
+      TProfile* m_SV1_efracsvx_vs_eta_b = nullptr;
+      TProfile* m_SV1_deltaR_vs_eta_b = nullptr;
+      TProfile* m_SV1_masssvx_vs_eta_c = nullptr;
+      TProfile* m_SV1_N2Tpair_vs_eta_c = nullptr;
+      TProfile* m_SV1_efracsvx_vs_eta_c = nullptr;
+      TProfile* m_SV1_deltaR_vs_eta_c = nullptr;
+      TProfile* m_SV1_masssvx_vs_eta_l = nullptr;
+      TProfile* m_SV1_N2Tpair_vs_eta_l = nullptr;
+      TProfile* m_SV1_efracsvx_vs_eta_l = nullptr;
+      TProfile* m_SV1_deltaR_vs_eta_l = nullptr;
+
+      // IPs and IP significances
+      TH1* m_track_d0_incl = nullptr;
+      TH1* m_track_z0_incl = nullptr;
+      TH1* m_track_sigd0_incl = nullptr;
+      TH1* m_track_sigz0_incl = nullptr;
+
+      TH1* m_track_d0_b = nullptr;
+      TH1* m_track_z0_b = nullptr;
+      TH1* m_track_sigd0_b = nullptr;
+      TH1* m_track_sigz0_b = nullptr;
+
+      TH1* m_track_d0_c = nullptr;
+      TH1* m_track_z0_c = nullptr;
+      TH1* m_track_sigd0_c = nullptr;
+      TH1* m_track_sigz0_c = nullptr;
+
+      TH1* m_track_d0_u = nullptr;
+      TH1* m_track_z0_u = nullptr;
+      TH1* m_track_sigd0_u = nullptr;
+      TH1* m_track_sigz0_u = nullptr;
+
+      TH1* m_track_d0_muon = nullptr;
+      TH1* m_track_z0_muon = nullptr;
+      TH1* m_track_sigd0_muon = nullptr;
+      TH1* m_track_sigz0_muon = nullptr;
+
+      // pT_frac
+      TH1* m_track_pT_frac_incl = nullptr;
+      TH1* m_track_pT_frac_b = nullptr;
+      TH1* m_track_pT_frac_c = nullptr;
+      TH1* m_track_pT_frac_u = nullptr;
+      TH1* m_track_pT_frac_muon = nullptr;
+
+      // DeltaR_jet_track
+      TH1* m_DeltaR_jet_track_incl = nullptr;
+      TH1* m_DeltaR_jet_track_b = nullptr;
+      TH1* m_DeltaR_jet_track_c = nullptr;
+      TH1* m_DeltaR_jet_track_u = nullptr;
+      TH1* m_DeltaR_jet_track_muon = nullptr;
+
+      // numTracks_perJet
+      TH1* m_numTracks_perJet_incl = nullptr;
+      TH1* m_numTracks_perJet_b = nullptr;
+      TH1* m_numTracks_perJet_c = nullptr;
+      TH1* m_numTracks_perJet_u = nullptr;
+      TH1* m_numTracks_perJet_muon = nullptr;
+
+      // numTracks_perJet_vs_pT
+      TProfile* m_numTracks_perJet_vs_pT_incl = nullptr;
+      TProfile* m_numTracks_perJet_vs_pT_b = nullptr;
+      TProfile* m_numTracks_perJet_vs_pT_c = nullptr;
+      TProfile* m_numTracks_perJet_vs_pT_u = nullptr;
+      TProfile* m_numTracks_perJet_vs_pT_muon = nullptr;
+
+      // number of tracks variables
+      TH1* m_numTracks_B_incl = nullptr; 
+      TH1* m_numTracks_C_incl = nullptr; 
+      TH1* m_numTracks_Fragmentation_incl = nullptr; 
+      TH1* m_numTracks_Secondaries_incl = nullptr; 
+      TH1* m_numTracks_Pileup_incl = nullptr; 
+      TH1* m_numTracks_Fake_incl = nullptr; 
+
+      TH1* m_numTracks_B_b = nullptr; 
+      TH1* m_numTracks_C_b = nullptr; 
+      TH1* m_numTracks_Fragmentation_b = nullptr; 
+      TH1* m_numTracks_Secondaries_b = nullptr; 
+      TH1* m_numTracks_Pileup_b = nullptr; 
+      TH1* m_numTracks_Fake_b = nullptr; 
+
+      TH1* m_numTracks_B_c = nullptr; 
+      TH1* m_numTracks_C_c = nullptr; 
+      TH1* m_numTracks_Fragmentation_c = nullptr; 
+      TH1* m_numTracks_Secondaries_c = nullptr; 
+      TH1* m_numTracks_Pileup_c = nullptr; 
+      TH1* m_numTracks_Fake_c = nullptr; 
+
+      TH1* m_numTracks_B_u = nullptr; 
+      TH1* m_numTracks_C_u = nullptr; 
+      TH1* m_numTracks_Fragmentation_u = nullptr; 
+      TH1* m_numTracks_Secondaries_u = nullptr; 
+      TH1* m_numTracks_Pileup_u = nullptr; 
+      TH1* m_numTracks_Fake_u = nullptr; 
+
+      TH1* m_numTracks_B_muon = nullptr; 
+      TH1* m_numTracks_C_muon = nullptr; 
+      TH1* m_numTracks_Fragmentation_muon = nullptr; 
+      TH1* m_numTracks_Secondaries_muon = nullptr; 
+      TH1* m_numTracks_Pileup_muon = nullptr; 
+      TH1* m_numTracks_Fake_muon = nullptr; 
+
+      // these are only filled for detail level above 10
+      TH1* m_numTracks_Secondaries_KshortDecay_incl = nullptr; 
+      TH1* m_numTracks_Secondaries_KshortDecay_b = nullptr; 
+      TH1* m_numTracks_Secondaries_KshortDecay_c = nullptr; 
+      TH1* m_numTracks_Secondaries_KshortDecay_u = nullptr; 
+      TH1* m_numTracks_Secondaries_KshortDecay_muon = nullptr; 
+  
+      TH1* m_numTracks_Secondaries_LambdaDecay_incl = nullptr; 
+      TH1* m_numTracks_Secondaries_LambdaDecay_b = nullptr; 
+      TH1* m_numTracks_Secondaries_LambdaDecay_c = nullptr; 
+      TH1* m_numTracks_Secondaries_LambdaDecay_u = nullptr; 
+      TH1* m_numTracks_Secondaries_LambdaDecay_muon = nullptr; 
+  
+      TH1* m_numTracks_Secondaries_GammaConversion_incl = nullptr; 
+      TH1* m_numTracks_Secondaries_GammaConversion_b = nullptr; 
+      TH1* m_numTracks_Secondaries_GammaConversion_c = nullptr; 
+      TH1* m_numTracks_Secondaries_GammaConversion_u = nullptr; 
+      TH1* m_numTracks_Secondaries_GammaConversion_muon = nullptr; 
+  
+      TH1* m_numTracks_Secondaries_OtherDecay_incl = nullptr; 
+      TH1* m_numTracks_Secondaries_OtherDecay_b = nullptr; 
+      TH1* m_numTracks_Secondaries_OtherDecay_c = nullptr; 
+      TH1* m_numTracks_Secondaries_OtherDecay_u = nullptr; 
+      TH1* m_numTracks_Secondaries_OtherDecay_muon = nullptr; 
+  
+      TH1* m_numTracks_Secondaries_HadronicInteraction_incl = nullptr; 
+      TH1* m_numTracks_Secondaries_HadronicInteraction_b = nullptr; 
+      TH1* m_numTracks_Secondaries_HadronicInteraction_c = nullptr; 
+      TH1* m_numTracks_Secondaries_HadronicInteraction_u = nullptr; 
+      TH1* m_numTracks_Secondaries_HadronicInteraction_muon = nullptr; 
+  
+      TH1* m_numTracks_Secondaries_OtherSecondary_incl = nullptr; 
+      TH1* m_numTracks_Secondaries_OtherSecondary_b = nullptr; 
+      TH1* m_numTracks_Secondaries_OtherSecondary_c = nullptr; 
+      TH1* m_numTracks_Secondaries_OtherSecondary_u = nullptr; 
+      TH1* m_numTracks_Secondaries_OtherSecondary_muon = nullptr; 
+  
+      TH1* m_numTracks_OtherOrigin_incl = nullptr; 
+      TH1* m_numTracks_OtherOrigin_b = nullptr; 
+      TH1* m_numTracks_OtherOrigin_c = nullptr; 
+      TH1* m_numTracks_OtherOrigin_u = nullptr; 
+      TH1* m_numTracks_OtherOrigin_muon = nullptr; 
+
+      // tracker hits
+      TH1* m_nInnHits_incl = nullptr;
+      TH1* m_nNextToInnHits_incl = nullptr;
+      TH1* m_nBLHits_incl = nullptr;
+      TH1* m_nsharedBLHits_incl = nullptr;
+      TH1* m_nsplitBLHits_incl = nullptr;
+      TH1* m_nPixHits_incl = nullptr;
+      TH1* m_nPixHoles_incl = nullptr;
+      TH1* m_nsharedPixHits_incl = nullptr;
+      TH1* m_nsplitPixHits_incl = nullptr;
+      TH1* m_nSCTHits_incl = nullptr;
+      TH1* m_nSCTHoles_incl = nullptr;
+      TH1* m_nsharedSCTHits_incl = nullptr;
+
+      TH1* m_nInnHits_b = nullptr;
+      TH1* m_nNextToInnHits_b = nullptr;
+      TH1* m_nBLHits_b = nullptr;
+      TH1* m_nsharedBLHits_b = nullptr;
+      TH1* m_nsplitBLHits_b = nullptr;
+      TH1* m_nPixHits_b = nullptr;
+      TH1* m_nPixHoles_b = nullptr;
+      TH1* m_nsharedPixHits_b = nullptr;
+      TH1* m_nsplitPixHits_b = nullptr;
+      TH1* m_nSCTHits_b = nullptr;
+      TH1* m_nSCTHoles_b = nullptr;
+      TH1* m_nsharedSCTHits_b = nullptr;
+
+      TH1* m_nInnHits_c = nullptr;
+      TH1* m_nNextToInnHits_c = nullptr;
+      TH1* m_nBLHits_c = nullptr;
+      TH1* m_nsharedBLHits_c = nullptr;
+      TH1* m_nsplitBLHits_c = nullptr;
+      TH1* m_nPixHits_c = nullptr;
+      TH1* m_nPixHoles_c = nullptr;
+      TH1* m_nsharedPixHits_c = nullptr;
+      TH1* m_nsplitPixHits_c = nullptr;
+      TH1* m_nSCTHits_c = nullptr;
+      TH1* m_nSCTHoles_c = nullptr;
+      TH1* m_nsharedSCTHits_c = nullptr;
+
+      TH1* m_nInnHits_u = nullptr;
+      TH1* m_nNextToInnHits_u = nullptr;
+      TH1* m_nBLHits_u = nullptr;
+      TH1* m_nsharedBLHits_u = nullptr;
+      TH1* m_nsplitBLHits_u = nullptr;
+      TH1* m_nPixHits_u = nullptr;
+      TH1* m_nPixHoles_u = nullptr;
+      TH1* m_nsharedPixHits_u = nullptr;
+      TH1* m_nsplitPixHits_u = nullptr;
+      TH1* m_nSCTHits_u = nullptr;
+      TH1* m_nSCTHoles_u = nullptr;
+      TH1* m_nsharedSCTHits_u = nullptr;
+
+      TH1* m_nInnHits_muon = nullptr;
+      TH1* m_nNextToInnHits_muon = nullptr;
+      TH1* m_nBLHits_muon = nullptr;
+      TH1* m_nsharedBLHits_muon = nullptr;
+      TH1* m_nsplitBLHits_muon = nullptr;
+      TH1* m_nPixHits_muon = nullptr;
+      TH1* m_nPixHoles_muon = nullptr;
+      TH1* m_nsharedPixHits_muon = nullptr;
+      TH1* m_nsplitPixHits_muon = nullptr;
+      TH1* m_nSCTHits_muon = nullptr;
+      TH1* m_nSCTHoles_muon = nullptr;
+      TH1* m_nsharedSCTHits_muon = nullptr;
+
+      // tagger
+      TH1* m_IP3D_pb = nullptr;
+      TH1* m_IP3D_pc = nullptr;
+      TH1* m_IP3D_pu = nullptr;
+
+      TH1* m_RNNIP_pb = nullptr;
+      TH1* m_RNNIP_pc = nullptr;
+      TH1* m_RNNIP_pu = nullptr;
+
+      TH1* m_SV1_pb = nullptr;
+      TH1* m_SV1_pc = nullptr;
+      TH1* m_SV1_pu = nullptr;
+      
+      TH1* m_DL1_pb = nullptr;
+      TH1* m_DL1_pc = nullptr;
+      TH1* m_DL1_pu = nullptr;
+      TH1* m_DL1r_pb = nullptr;
+      TH1* m_DL1r_pc = nullptr;
+      TH1* m_DL1r_pu = nullptr;
+
+      // TH1* m_SV0_NGTinSvx = nullptr;
+      TH1* m_nGTinSV1_incl = nullptr;
+      TH1* m_nGTinSV1_b = nullptr;
+      TH1* m_nGTinSV1_c = nullptr;
+      TH1* m_nGTinSV1_l = nullptr;
+      TH1* m_nGTinSV1_muon = nullptr;
+
+      TH1* m_IP2D_nTracks_incl = nullptr;
+      TH1* m_IP2D_nTracks_b = nullptr;
+      TH1* m_IP2D_nTracks_c = nullptr;
+      TH1* m_IP2D_nTracks_l = nullptr;
+      TH1* m_IP2D_nTracks_muon = nullptr;
+
+      TH1* m_IP3D_nTracks_incl = nullptr;
+      TH1* m_IP3D_nTracks_b = nullptr;
+      TH1* m_IP3D_nTracks_c = nullptr;
+      TH1* m_IP3D_nTracks_l = nullptr;
+      TH1* m_IP3D_nTracks_muon = nullptr;
+
+      TH1* m_IP3D_gradeOfTracks_incl = nullptr;
+      TH1* m_IP2D_gradeOfTracks_incl = nullptr;
+      TH1* m_IP3D_gradeOfTracks_b = nullptr;
+      TH1* m_IP2D_gradeOfTracks_b = nullptr;
+      TH1* m_IP3D_gradeOfTracks_c = nullptr;
+      TH1* m_IP2D_gradeOfTracks_c = nullptr;
+      TH1* m_IP3D_gradeOfTracks_l = nullptr;
+      TH1* m_IP2D_gradeOfTracks_l = nullptr;
+      TH1* m_IP3D_gradeOfTracks_muon = nullptr;
+      TH1* m_IP2D_gradeOfTracks_muon = nullptr;
+
+      TH1* m_tmpD0 = nullptr;
+      TH1* m_tmpZ0 = nullptr;
+      TH1* m_tmpD0sig = nullptr;
+      TH1* m_tmpZ0sig = nullptr;
+      TH1* m_IP3D_weightBofTracks = nullptr;
+      TH1* m_IP3D_weightCofTracks = nullptr;
+      TH1* m_IP3D_weightUofTracks = nullptr;
+      TH1* m_IP2D_weightBofTracks = nullptr;
+      TH1* m_IP2D_weightCofTracks = nullptr;
+      TH1* m_IP2D_weightUofTracks = nullptr;
+
+      // B hadron Lxy
+      TH1* m_Truth_Lxy_b = nullptr;
+      TH1* m_Truth_Lxy_c = nullptr;
+      
+      // B hadron deltaR wrt jet 
+      TH1* m_deltaR_truthBHadron_jet_b = nullptr;
+      TH1* m_deltaR_truthCHadron_jet_c = nullptr;
+      
+      std::vector<std::string> m_taggers;
+      std::map<std::string, int> m_truthLabels;
+      std::map<std::string, double> m_IP3D_workingPoints;
+      std::map<std::string, double> m_IP2D_workingPoints;
+      std::map<std::string, double> m_RNNIP_workingPoints;
+      std::map<std::string, double> m_SV1_workingPoints;
+      std::map<std::string, double> m_IP3DSV1_workingPoints;
+      std::map<std::string, double> m_JetFitter_workingPoints;
+      std::map<std::string, double> m_MV2c10_workingPoints;
+      std::map<std::string, double> m_DL1_workingPoints;
+      std::map<std::string, double> m_DL1r_workingPoints;
+      double m_RNNIP_fc;
+      double m_DL1_fc;
+      double m_DL1r_fc;
+      std::map<std::string, TH1*> m_weight_histos; 
+      std::map<std::string, TProfile*> m_eff_profiles; 
+
+      std::map<std::string, TH1*> m_nJetsThatPassedWPCutsHistos; 
+
+      // detail level
+      void setDetailLevel(const unsigned int& detailLevel);
+
+      // a setter for the HistogramDefinitions and the jvt and TMP cuts
+      void setHistogramDefinitions( std::map< std::string, std::vector< std::string > > HistogramDefinitions);
+      void setIsDataJVTCutsAndTMPCut(bool isData, float JVTCutAntiKt4EMTopoJets, float JVTCutLargerEtaAntiKt4EMTopoJets, float JVTCutAntiKt4EMPFlowJets, float truthMatchProbabilityCut);
+
+      // jvt variables 
+      bool m_JVT_defined;
+      float m_JVT_cut;
+      bool m_JVTLargerEta_defined;
+      float m_JVTLargerEta_cut;
+
+    private:
+      virtual void initializePlots();     
+      virtual void finalizePlots(); 
+
+      // detail level
+      unsigned int m_detailLevel;
+
+      // map with histogram definitions and the corresponding enum
+      std::map< std::string, std::vector< std::string > > m_HistogramDefinitions;
+      enum position{histo_name, histo_title, histo_path, histo_xbins, histo_xmin, histo_xmax, histo_type, histo_ymin, histo_ymax};
+      float m_truthMatchProbabilityCut;
+      bool m_isData;
+      // some helper functions
+      TH1* bookHistogram(std::string histo_name, std::string var_name, std::string part = "", std::string prefix = "");
+      TProfile* bookProfile(std::string histo_name, std::string var_name, std::string part = "", std::string prefix = "");
+      int getTrackHits(const xAOD::TrackParticle& part, xAOD::SummaryType info);
+      void fillDiscriminantHistograms(const std::string& tagger_name, const double& discriminant_value, const std::map<std::string, double>& working_points, const int& truth_label, std::map<std::string, TH1*>::const_iterator hist_iter, std::map<std::string, int>::const_iterator label_iter, const bool& pass_nTracksCut, const double& jet_pT, const double& jet_Lxy, const bool& onZprime, const xAOD::EventInfo* event);
+      void bookDiscriminantVsPTAndLxyHistograms(const std::string& tagger_name, const std::map<std::string, double>& workingPoints, const bool& isOldTagger, std::map<std::string, int>::const_iterator label_iter, const std::string& m_sParticleType);
+      template <class T>
+      void fillHistoWithTruthCases(T value, TH1* histo_incl, TH1* histo_b, TH1* histo_c, TH1* histo_l, TH1* histo_muon, const int& truth_label, const bool& has_muon, const xAOD::EventInfo* event);
+
+  };
+    
 }
-	
+    
 #endif
diff --git a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/PhysValBTag.cxx b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/PhysValBTag.cxx
index a2f7d7f3e5e2f1fc39e0acf90d0c994bcfce2a23..d6355ca89ff23811451c6329a6b9cc98fe6b60b5 100644
--- a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/PhysValBTag.cxx
+++ b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/PhysValBTag.cxx
@@ -1,12 +1,13 @@
 ///////////////////////// -*- C++ -*- /////////////////////////////
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 // PhysValBTag.cxx
 // Implementation file for class PhysValBTag
 // Author: E.Schopf<elisabeth.schopf@cern.ch>
+// Updates: J.Hoefer <judith.hoefer@cern.ch>
 ///////////////////////////////////////////////////////////////////
 // JetTagDQA includes
 #include "PhysValBTag.h"
@@ -38,14 +39,12 @@ namespace JetTagDQA {
                             const std::string& name,
                             const IInterface* parent ) :
     ManagedMonitorToolBase( type, name, parent ),
-    //   m_jetPlots(0, "Summary/Jet/", "Jet"),
-    //    m_trkvtxPlots(0, "Summary/TrackAndVertex/"),
     m_isData(false),
-    m_antiKt2PV0TrackJetPlots             (0, "BTag/AntiKt2PV0TrackJets/"          , "antiKt2PV0TrackJets"),
-    m_antiKt4PV0TrackJetPlots             (0, "BTag/AntiKt4PV0TrackJets/"          , "antiKt4PV0TrackJets"),
-    m_antiKt4EMTopoPlots                  (0, "BTag/AntiKt4EMTopoJets/"            , "antiKt4EMTopoJets"),
-    m_antiKtVR30Rmax4Rmin02TrackJetsPlots (0, "BTag/AntiKtVR30Rmax4Rmin02TrackJets", "antiKtVR30Rmax4Rmin02TrackJets"),
-    m_antiKt4EMPFlowJetsPlots             (0, "BTag/AntiKt4EMPFlowJets"            , "antiKt4EMPFlowJets"),
+    m_antiKt2PV0TrackJetPlots             (0, "BTag/AntiKt2PV0TrackJets/"           , "antiKt2PV0TrackJets"),
+    m_antiKt4PV0TrackJetPlots             (0, "BTag/AntiKt4PV0TrackJets/"           , "antiKt4PV0TrackJets"),
+    m_antiKt4EMTopoPlots                  (0, "BTag/AntiKt4EMTopoJets/"             , "antiKt4EMTopoJets"),
+    m_antiKtVR30Rmax4Rmin02TrackJetsPlots (0, "BTag/AntiKtVR30Rmax4Rmin02TrackJets/", "antiKtVR30Rmax4Rmin02TrackJets"),
+    m_antiKt4EMPFlowJetsPlots             (0, "BTag/AntiKt4EMPFlowJets/"            , "antiKt4EMPFlowJets"),
     m_nevents(0)
   {
 
@@ -59,6 +58,15 @@ namespace JetTagDQA {
 
     declareProperty( "TrackContainerName", m_trackName = "InDetTrackParticles" );
     declareProperty( "VertexContainerName", m_vertexName = "PrimaryVertices" );
+
+    declareProperty( "HistogramDefinitionsVector", m_HistogramDefinitionsVector );
+    declareProperty( "JetPtCutTtbar", m_jetPtCutTtbar = 20000);
+    declareProperty( "JetPtCutZprime", m_jetPtCutZprime = 500000);
+    declareProperty( "JVTCutAntiKt4EMTopoJets", m_JVTCutAntiKt4EMTopoJets = 0.59);
+    declareProperty( "JVTCutLargerEtaAntiKt4EMTopoJets", m_JVTCutLargerEtaAntiKt4EMTopoJets = 0.11);
+    declareProperty( "JVTCutAntiKt4EMPFlowJets", m_JVTCutAntiKt4EMPFlowJets = 0.2);
+    declareProperty( "truthMatchProbabilityCut", m_truthMatchProbabilityCut = 0.75);
+
   }
 
   // Destructor
@@ -70,16 +78,46 @@ namespace JetTagDQA {
   ////////////////////////////
   StatusCode PhysValBTag::initialize()
   {
-	ATH_MSG_INFO ("Initializing " << name() << "...");
-	ATH_CHECK(ManagedMonitorToolBase::initialize());
-
-	m_btagplots.insert(std::make_pair(m_jetName1, m_antiKt2PV0TrackJetPlots));
-	m_btagplots.insert(std::make_pair(m_jetName2, m_antiKt4PV0TrackJetPlots));
-	m_btagplots.insert(std::make_pair(m_jetName3, m_antiKt4EMTopoPlots));
-	m_btagplots.insert(std::make_pair(m_jetName4, m_antiKtVR30Rmax4Rmin02TrackJetsPlots));
-	m_btagplots.insert(std::make_pair(m_jetName5, m_antiKt4EMPFlowJetsPlots));
+    ATH_MSG_INFO ("Initializing " << name() << "...");
+    ATH_CHECK(ManagedMonitorToolBase::initialize());
+
+    // initialize the truth-track-assoiation tool
+    ATH_CHECK(m_trackTruthOriginTool.retrieve( EnableTool {true} ));
+
+    // convert the HistogramDefinitions vector to a map 
+    for(unsigned int i = 0; i < m_HistogramDefinitionsVector.size(); i++){
+      std::string name = m_HistogramDefinitionsVector[i][0];
+      m_HistogramDefinitionsMap.insert(std::pair< std::string, std::vector< std::string > >(name, m_HistogramDefinitionsVector[i]));
+    }
+
+    // set the detail level
+    m_antiKt2PV0TrackJetPlots.setDetailLevel(m_detailLevel);
+    m_antiKt4PV0TrackJetPlots.setDetailLevel(m_detailLevel);
+    m_antiKt4EMTopoPlots.setDetailLevel(m_detailLevel);
+    m_antiKtVR30Rmax4Rmin02TrackJetsPlots.setDetailLevel(m_detailLevel);
+    m_antiKt4EMPFlowJetsPlots.setDetailLevel(m_detailLevel);
+
+    // give that map to the BTaggingValidationPlots
+    m_antiKt2PV0TrackJetPlots.setHistogramDefinitions(m_HistogramDefinitionsMap);
+    m_antiKt4PV0TrackJetPlots.setHistogramDefinitions(m_HistogramDefinitionsMap);
+    m_antiKt4EMTopoPlots.setHistogramDefinitions(m_HistogramDefinitionsMap);
+    m_antiKtVR30Rmax4Rmin02TrackJetsPlots.setHistogramDefinitions(m_HistogramDefinitionsMap);
+    m_antiKt4EMPFlowJetsPlots.setHistogramDefinitions(m_HistogramDefinitionsMap);
+
+    // set the isData key, the JVT and TMP cuts
+    m_antiKt2PV0TrackJetPlots.setIsDataJVTCutsAndTMPCut(m_isData, m_JVTCutAntiKt4EMTopoJets, m_JVTCutLargerEtaAntiKt4EMTopoJets, m_JVTCutAntiKt4EMPFlowJets, m_truthMatchProbabilityCut);
+    m_antiKt4PV0TrackJetPlots.setIsDataJVTCutsAndTMPCut(m_isData, m_JVTCutAntiKt4EMTopoJets, m_JVTCutLargerEtaAntiKt4EMTopoJets, m_JVTCutAntiKt4EMPFlowJets, m_truthMatchProbabilityCut);
+    m_antiKt4EMTopoPlots.setIsDataJVTCutsAndTMPCut(m_isData, m_JVTCutAntiKt4EMTopoJets, m_JVTCutLargerEtaAntiKt4EMTopoJets, m_JVTCutAntiKt4EMPFlowJets, m_truthMatchProbabilityCut);
+    m_antiKtVR30Rmax4Rmin02TrackJetsPlots.setIsDataJVTCutsAndTMPCut(m_isData, m_JVTCutAntiKt4EMTopoJets, m_JVTCutLargerEtaAntiKt4EMTopoJets, m_JVTCutAntiKt4EMPFlowJets, m_truthMatchProbabilityCut);
+    m_antiKt4EMPFlowJetsPlots.setIsDataJVTCutsAndTMPCut(m_isData, m_JVTCutAntiKt4EMTopoJets, m_JVTCutLargerEtaAntiKt4EMTopoJets, m_JVTCutAntiKt4EMPFlowJets, m_truthMatchProbabilityCut);
+
+    m_btagplots.insert(std::make_pair(m_jetName1, m_antiKt2PV0TrackJetPlots));
+    m_btagplots.insert(std::make_pair(m_jetName2, m_antiKt4PV0TrackJetPlots));
+    m_btagplots.insert(std::make_pair(m_jetName3, m_antiKt4EMTopoPlots));
+    m_btagplots.insert(std::make_pair(m_jetName4, m_antiKtVR30Rmax4Rmin02TrackJetsPlots));
+    m_btagplots.insert(std::make_pair(m_jetName5, m_antiKt4EMPFlowJetsPlots));
    
-        return StatusCode::SUCCESS;
+    return StatusCode::SUCCESS;
   }
 
   StatusCode PhysValBTag::book(PlotBase& plots)
@@ -98,15 +136,12 @@ namespace JetTagDQA {
   {
     ATH_MSG_INFO ("Booking hists " << name() << "...");
 
-    if (m_detailLevel >= 10) {
+    if (m_detailLevel < 10) return StatusCode::SUCCESS;
 
-      for(std::map<std::string,JetTagDQA::BTaggingValidationPlots>::iterator plot_i = m_btagplots.begin(); plot_i != m_btagplots.end(); ++plot_i){
-        //		ATH_CHECK(book(m_jetPlots));
-		ATH_CHECK(book(plot_i->second));
-        // 		ATH_CHECK(book(m_trkvtxPlots));
-      }
+    for(std::map<std::string,JetTagDQA::BTaggingValidationPlots>::iterator plot_i = m_btagplots.begin(); plot_i != m_btagplots.end(); ++plot_i){
+      ATH_CHECK(book(plot_i->second));
     }
-
+      
     return StatusCode::SUCCESS;
   }
 
@@ -117,9 +152,33 @@ namespace JetTagDQA {
     if (m_detailLevel < 10) return StatusCode::SUCCESS;
     
     ++m_nevents;
-    //int njets = 0;
     //std::cout << "Number of proccessed events = " << m_nevents << std::endl;
-    // primary vertex
+
+    // event info
+    const xAOD::EventInfo* event(0);
+    ATH_CHECK(evtStore()->retrieve(event, "EventInfo"));
+
+    // determine if the sample is ttbar or Zprime (on the first event, where the jetPtCut is still initial -1)
+    if(m_jetPtCut < 0){
+      // get the DSID
+      int dsid = event->mcChannelNumber();
+
+      // check if it is a ttbar or Zprime sample
+      if(dsid == 410000){
+        m_jetPtCut = m_jetPtCutTtbar;
+      }
+      else if(dsid == 427080) {
+        m_jetPtCut = m_jetPtCutZprime;
+        m_onZprime = true;
+      }
+      // if none applies give a warning and use the default cut
+      else {
+        ATH_MSG_WARNING("It is checked if the sample is ttbar (has dsid 410000) or Zprime (has dsid 427080). None applies (read dsid is " << dsid << "). Applying default pT cut of 20000 MeV now.");
+        m_jetPtCut = 20000;
+      }
+    }
+
+    // get the primary vertex
     const xAOD::VertexContainer *vertices = 0;
     CHECK( evtStore()->retrieve(vertices, "PrimaryVertices") );
     int npv(0);
@@ -128,21 +187,21 @@ namespace JetTagDQA {
     xAOD::VertexContainer::const_iterator vtx_itr = vertices->begin();
     xAOD::VertexContainer::const_iterator vtx_end = vertices->end();
     int count = -1;
+    // loop over the vertices
     for (; vtx_itr != vtx_end; ++vtx_itr) {
       count++;
       if ((*vtx_itr)->nTrackParticles() >= 2) {
-        //v_PVz->push_back(  (*vtx_itr)->z() );
         npv++;
         if ((*vtx_itr)->vertexType() == 1) {
-          if (PV_x != -999) ATH_MSG_WARNING( ".... second PV in the events ...!!!!!!");
+          if (m_PV_x != -999.) ATH_MSG_WARNING( ".... second PV in the events ...!!!!!!");
           indexPV = count;
           has_pv = true;
-          PV_x = (*vtx_itr)->x(); // ANDREA !!!!!!!!
-          PV_y = (*vtx_itr)->y(); // ANDREA !!!!!!!!
-          PV_z = (*vtx_itr)->z();
-        }   //if ((*vtx_itr)->vertexType() == 1) {
-      } //if ((*vtx_itr)->nTrackParticles() >= 2) {
-    }//for (; vtx_itr != vtx_end; ++vtx_itr) {
+          m_PV_x = (*vtx_itr)->x();
+          m_PV_y = (*vtx_itr)->y();
+          m_PV_z = (*vtx_itr)->z();
+        }
+      }
+    }
     if (!has_pv) {
       //ATH_MSG_WARNING( ".... rejecting the event due to missing PV!!!!");
       return StatusCode::SUCCESS;
@@ -150,59 +209,80 @@ namespace JetTagDQA {
     const xAOD::Vertex *myVertex = vertices->at(indexPV); // the (reco?) primary vertex
     //std::cout<<"z coordinate of PV: "<< myVertex->z() <<std::endl;
 
+    // get the tracks
+    const xAOD::TrackParticleContainer* tracks(0);
+    ATH_CHECK(evtStore()->retrieve(tracks, m_trackName));
+
+    // loop over the jet collections
     for(std::map<std::string,JetTagDQA::BTaggingValidationPlots>::iterator plot_i = m_btagplots.begin(); plot_i != m_btagplots.end(); ++plot_i){
       
-      //LOOP ON JETS
+      // get the jets
       const xAOD::JetContainer* jets(0);
-      // ATH_CHECK(evtStore()->retrieve(jets, plot_i->first));
       StatusCode jetException = evtStore()->retrieve(jets, plot_i->first);
       // If StatusCode is not SUCCESS, no jet collection with this name, continue loop
       if (jetException != StatusCode::SUCCESS) continue;
 
+      int nJets_withCut = 0;
+      int nJets_containing_moun = 0; 
+      int nJets_containing_SV = 0; 
+      std::map<std::string, int> nJetsThatPassedWPCuts;
+      (plot_i->second).initializeNJetsThatPassedWPCutsMap(nJetsThatPassedWPCuts);
+
+      // loop over the jets
       for (auto jet : *jets) {
 
-        //			++njets;
-        //     			m_jetPlots.fill(jet);
-        //std::cout << "number of processed jet: " << njets << std::endl;
+        // apply the jet pT eta and jvt cuts
+        if(jet->pt() <= m_jetPtCut) continue;
+        if(std::abs(jet->eta()) >= 2.5) continue;
+        //Arnaud: JVT cut to remove horns in jet eta 
+        if (((plot_i->second).m_JVT_defined) &&  (jet->getAttribute<float>("Jvt")) < ((plot_i->second).m_JVT_cut) && jet->pt() > 20e3 && jet->pt() < 60e3 && (std::abs(jet->eta()) < 2.4) ) continue;
+        if (((plot_i->second).m_JVTLargerEta_defined) &&  (jet->getAttribute<float>("Jvt")) < ((plot_i->second).m_JVTLargerEta_cut) && jet->pt() > 20e3 && jet->pt() < 60e3 && (std::abs(jet->eta()) > 2.4) && (std::abs(jet->eta()) < 2.5) ) continue;
 
-        //btagging
+        // get the btagging
         const xAOD::BTagging* btag = xAOD::BTaggingUtilities::getBTagging( *jet );
 
-        int label(1000);
-        //double dR(1000);
-
-	if(jet->pt() <= 20000) continue;
-	if(std::abs(jet->eta()) >= 2.5) continue;
-
-	//Arnaud: JVT cut to remove horns in jet eta 
-	if (((plot_i->second).m_isJVT_defined) &&  (jet->getAttribute<float>("Jvt")) < ((plot_i->second).m_jvt_cut) && jet->pt() > 20e3 && jet->pt() < 60e3 && (std::abs(jet->eta()) < 2.4) ) continue;
-
-        //if(jet->pt() > 20000 && std::abs(jet->eta()) < 2.5){
-          (plot_i->second).fill(jet);
-
-	  if(!m_isData) {
-	    //if(jet->isAvailable<int>("HadronConeExclTruthLabelID")) label = jetFlavourLabel(jet, xAOD::JetFlavourLabelType::GAFinalHadron);
-	    if(jet->isAvailable<int>("HadronConeExclTruthLabelID")) label = jetFlavourLabel(jet, xAOD::ConeFinalParton);
-	    else jet->getAttribute("TruthLabelID",label);
-	  }
-
-          (plot_i->second).fill(label);
-          if (btag){
-            (plot_i->second).fill(btag);
-            //(plot_i->second).fill(jet, btag);
-       	    (plot_i->second).fill(jet, btag, myVertex); //ANDREA: added xAOD::Vertex * as input to BTaggingValidationPlots.cxx
-          }
-	  //}
-      }//for (auto jet : *jets) {
-    }//for(std::map<std::string,JetTagDQA::BTaggingValidationPlots>::iterator plot_i = m_btagplots.begin(); plot_i != m_btagplots.end(); ++plot_i){
-
-    // Tracks/Vertices
-    //    const xAOD::TrackParticleContainer* trks(0);
-    //    ATH_CHECK(evtStore()->retrieve(trks, m_trackName));
-    //    const xAOD::VertexContainer* vtxs(0);
-    //    ATH_CHECK(evtStore()->retrieve(vtxs, m_vertexName));
-    //    for (auto vtx : *vtxs) m_trkvtxPlots.fill(vtx);
-    //    m_trkvtxPlots.fill(trks->size(), vtxs->size() /*, event->averageInteractionsPerCrossing() */);
+        // count the jets that pass the cuts
+        nJets_withCut++;
+
+        // get the jet truth label
+        int truth_label(1000);
+        if(!m_isData){
+          if(jet->isAvailable<int>("HadronConeExclTruthLabelID")) jet->getAttribute("HadronConeExclTruthLabelID", truth_label);
+          else jet->getAttribute("TruthLabelID",truth_label);    
+        }
+
+        // fill the jet related histograms
+        (plot_i->second).fillJetKinVars(jet, truth_label, m_onZprime, event);
+
+        // fill the jet, btag & vertex related plots
+        if (btag){
+          // fill other variables
+          bool contains_muon;
+          double jet_Lxy = -1;
+          (plot_i->second).fillOther(jet, btag, contains_muon, jet_Lxy, truth_label, event);
+          if(contains_muon) nJets_containing_moun++;
+
+          // get the track to truth associations
+          std::map<const xAOD::TrackParticle*, int> track_truth_associations = getTrackTruthAssociations(btag);
+
+          // fill track related variables
+          int num_HF_tracks_in_jet;
+          (plot_i->second).fillTrackVariables(jet, btag, myVertex, track_truth_associations, contains_muon, truth_label, num_HF_tracks_in_jet, event);
+          // fill SV related vars
+          bool contains_SV;
+          (plot_i->second).fillSVVariables(jet, btag, track_truth_associations, contains_muon, truth_label, num_HF_tracks_in_jet, contains_SV, event);
+          if(contains_SV) nJets_containing_SV++;
+          // fill discriminant related vars
+          (plot_i->second).fillDiscriminantVariables(btag, jet, jet_Lxy, truth_label, contains_muon, m_onZprime, nJetsThatPassedWPCuts, event);
+        }
+      }
+
+      // fill multiplicities
+      (plot_i->second).fillMultiplicities(nJets_withCut, tracks->size(), npv, myVertex->nTrackParticles(), nJets_containing_moun, nJets_containing_SV, nJetsThatPassedWPCuts, event);
+      // fill PV variables
+      (plot_i->second).fillPVVariables(m_PV_x, m_PV_y, m_PV_z, event);
+
+    }
 
     return StatusCode::SUCCESS;
   }
@@ -210,8 +290,10 @@ namespace JetTagDQA {
   StatusCode PhysValBTag::procHistograms()
   {
     ATH_MSG_INFO ("Finalising hists " << name() << "...");
+
     for(std::map<std::string,JetTagDQA::BTaggingValidationPlots>::iterator plot_i = m_btagplots.begin(); plot_i != m_btagplots.end(); ++plot_i){
       (plot_i->second).finalize();
+
     }
     return StatusCode::SUCCESS;
   }
@@ -220,6 +302,56 @@ namespace JetTagDQA {
   // Const methods:
   ///////////////////////////////////////////////////////////////////
 
+  std::map<const xAOD::TrackParticle*, int> PhysValBTag::getTrackTruthAssociations(const xAOD::BTagging* btag) const {
+
+    // define the return vector
+    std::map<const xAOD::TrackParticle*, int> truthValues;
+
+    // get the track links from te btag
+    std::vector< ElementLink< xAOD::TrackParticleContainer > > assocTracks = btag->auxdata<std::vector<ElementLink<xAOD::TrackParticleContainer> > >("BTagTrackToJetAssociator");
+
+    // loop over the tracks associated to the btag and get the truth values
+    for(unsigned int i = 0; i < assocTracks.size(); i++) {
+      if (!assocTracks.at(i).isValid()) continue;
+
+      // get the curent track
+      const xAOD::TrackParticle* track = *(assocTracks.at(i));  
+
+      // add the truth values to the vector
+      truthValues.insert( std::make_pair( track, m_trackTruthOriginTool->getTrackOrigin(track) ) );
+    }
+
+    // also loop over the tracks associated to the MSV vertices -> can be missing in the other track list
+    // get the MSV vertices
+    std::vector< ElementLink< xAOD::VertexContainer > > MSV_vertices;
+    try { MSV_vertices = btag->auxdata<std::vector< ElementLink< xAOD::VertexContainer > > >("MSV_vertices"); }
+    catch(std::exception& exception) {  }
+
+    // loop over the MSV vertices
+    for (unsigned int i = 0; i < MSV_vertices.size(); i++) {
+      if (!MSV_vertices.at(i).isValid()) continue;
+      const xAOD::Vertex* vtx = *(MSV_vertices.at(i));
+
+      // get the track links
+      std::vector<ElementLink<DataVector<xAOD::TrackParticle> > > MSV_assocTracks = vtx->trackParticleLinks();
+
+      // loop over the tracks
+      for(unsigned int i = 0; i < MSV_assocTracks.size(); i++) {
+        if (!MSV_assocTracks.at(i).isValid()) continue;
+
+        // get the curent track
+        const xAOD::TrackParticle* track = *(MSV_assocTracks.at(i));  
+        
+        // add the truth values to the vector
+        truthValues.insert( std::make_pair( track, m_trackTruthOriginTool->getTrackOrigin(track) ) );
+      }
+    }
+
+    // return
+    return truthValues;
+  }
+
+
   ///////////////////////////////////////////////////////////////////
   // Non-const methods:
   ///////////////////////////////////////////////////////////////////
diff --git a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/PhysValBTag.h b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/PhysValBTag.h
index 1f5027f2a427a7e8bd626b3d09aedcec65b9d437..2caaa92a3762517c2c36c418820e72faec3f6e89 100644
--- a/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/PhysValBTag.h
+++ b/PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/src/PhysValBTag.h
@@ -1,12 +1,13 @@
 ///////////////////////// -*- C++ -*- /////////////////////////////
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 // PhysValBTag.h
 // Header file for class PhysValBTag
 // Author: E.Schopf<elisabeth.schopf@cern.ch>
+// Updates: J.Hoefer <judith.hoefer@cern.ch>
 ///////////////////////////////////////////////////////////////////
 #ifndef JETTAGDQA_PHYSVALBTag_H
 #define JETTAGDQA_PHYSVALBTag_H 1
@@ -22,6 +23,8 @@
 #include "TrkValHistUtils/PlotBase.h"
 #include "BTaggingValidationPlots.h"
 
+#include "InDetTrackSystematicsTools/InDetTrackTruthOriginTool.h"
+
 // Root includes
 #include "TH1.h"
 
@@ -36,9 +39,9 @@ namespace JetTagDQA {
     // Public methods:
     ///////////////////////////////////////////////////////////////////
   public:
-    double PV_x;
-    double PV_y;
-    double PV_z;
+    double m_PV_x = -999.;
+    double m_PV_y = -999.;
+    double m_PV_z = -999.;
     // Copy constructor:
 
     /// Constructor with parameters:
@@ -59,6 +62,7 @@ namespace JetTagDQA {
     ///////////////////////////////////////////////////////////////////
     // Const methods:
     ///////////////////////////////////////////////////////////////////
+    std::map<const xAOD::TrackParticle*, int> getTrackTruthAssociations(const xAOD::BTagging* btag) const;
 
     ///////////////////////////////////////////////////////////////////
     // Non-const methods:
@@ -73,6 +77,8 @@ namespace JetTagDQA {
     /// Default constructor:
     PhysValBTag();
 
+    ToolHandle<InDet::IInDetTrackTruthOriginTool> m_trackTruthOriginTool{this, "trackTruthOriginTool", "InDet::InDetTrackTruthOriginTool"};
+
     // isData flag
     bool m_isData;
 
@@ -86,11 +92,22 @@ namespace JetTagDQA {
     std::string m_trackName;
     std::string m_vertexName;
 
-    // Hists
-    //  JetTagDQA::BTaggingValidationPlots m_jetPlots;
-    //  PhysVal::TrkAndVtxPlots m_trkvtxPlots;
-
     std::map<std::string, JetTagDQA::BTaggingValidationPlots> m_btagplots;
+    
+    // histogram definitions
+    // the first one is a vector because I can only pass vectors from the joboptions to the algs (and no maps)
+    Gaudi::Property< std::vector< std::vector< std::string > > > m_HistogramDefinitionsVector {this, "HistogramDefinitions", {}, "Map with histogram definitions"};
+    // have a useful map nevertheless
+    std::map< std::string, std::vector< std::string > > m_HistogramDefinitionsMap;
+
+    float m_jetPtCut = -1;
+    bool m_onZprime = false;
+    float m_jetPtCutTtbar;
+    float m_jetPtCutZprime;
+    float m_JVTCutAntiKt4EMTopoJets;
+    float m_JVTCutLargerEtaAntiKt4EMTopoJets;
+    float m_JVTCutAntiKt4EMPFlowJets;
+    float m_truthMatchProbabilityCut;
 
     JetTagDQA::BTaggingValidationPlots m_antiKt2PV0TrackJetPlots;
     JetTagDQA::BTaggingValidationPlots m_antiKt4PV0TrackJetPlots;
@@ -99,8 +116,6 @@ namespace JetTagDQA {
     JetTagDQA::BTaggingValidationPlots m_antiKt4EMPFlowJetsPlots;
 
     int m_nevents;
-    //int m_nTruthB;
-    //int m_nTruthNonB;
 
     StatusCode book(PlotBase& plots);
   };
diff --git a/PhysicsAnalysis/PhysicsValidation/PhysValMonitoring/python/PhysValUtils.py b/PhysicsAnalysis/PhysicsValidation/PhysValMonitoring/python/PhysValUtils.py
index a0be1eb29fe1cea72b1a3fc64cb4c31bab5a52aa..8162086225b0de3451d15089bd5decce119a9104 100644
--- a/PhysicsAnalysis/PhysicsValidation/PhysValMonitoring/python/PhysValUtils.py
+++ b/PhysicsAnalysis/PhysicsValidation/PhysValMonitoring/python/PhysValUtils.py
@@ -87,3 +87,83 @@ def addOriginCorrectedClusters(algseq,doLC,doEM):
         ctools += [jtm.JetConstitSeq_EMOrigin]
 
     return ctools
+
+################################################################################################
+
+def getHistogramDefinitions(fileName, usage, use_group):
+    import os.path
+    import json
+
+    # vars required in the input json
+    requiredKeys = ['title', 'xtitle', 'ytitle', 'path', 'xbins', 'xmin', 'xmax', 'type']
+    # define a order for the keys in the output list
+    position = {'name': 0, 'title': 1, 'path': 2, 'xbins': 3, 'xmin': 4, 'xmax': 5, 'type': 6, 'ymin': 7, 'ymax': 8}
+
+    # check if the path exists
+    if not os.path.isfile(fileName):
+        raise IOError("This path to the file does not exist:" + fileName)
+    
+    # read file
+    file_dict = {}
+    with open(fileName) as json_file:
+        file_dict = json.load(json_file)
+    
+    # check if the file has the right keys in the dict
+    for group in file_dict:
+        for var in file_dict[group]:
+            for required_key in requiredKeys:
+                if required_key not in file_dict[group][var]:
+                    raise IOError("The key " + required_key + " is missing in the dict for the variable " + var + ".")
+    
+    # read the right parts of the dict 
+    list = []
+    # loop over all groups
+    for group in file_dict:
+        # skip that group if it is not asked for
+        if not (use_group == 'ALL' or group == use_group) or group == 'template':
+            continue
+        # loop over all vars
+        for var in file_dict[group]:
+            # only fill the usage dict with this var if the usage exists in the 'path' dict
+            if usage in file_dict[group][var]['path']:
+                # if the dict has the key forEachTruthType -> expand the one dict into one for each type
+                if 'forEach' in file_dict[group][var]:
+                    for type in file_dict[group][var]['forEach']:
+                        var_list = ['', '', '', '', '', '', '', '', '']
+                        # adapt the new variable name
+                        new_var_name = var + '_' + type
+                        # fill the name
+                        var_list[position['name']] = str(new_var_name)
+                        # merge the tile keys
+                        var_list[position['title']] = str(file_dict[group][var]['title'] + ' ' + type + ';' + file_dict[group][var]['xtitle'] + ';' + file_dict[group][var]['ytitle'])
+                        # get the right path
+                        var_list[position['path']] = str(file_dict[group][var]['path'][usage])
+                        # just copy the rest
+                        for key in ['xbins', 'xmin', 'xmax', 'type']:
+                            var_list[position[key]] = str(file_dict[group][var][key])
+                        if(file_dict[group][var]['type'] == 'TProfile'):
+                            var_list[position['ymin']] = str(file_dict[group][var]['ymin'])
+                            var_list[position['ymax']] = str(file_dict[group][var]['ymax'])
+                        # append the current variable to the list
+                        list.append(var_list)
+                else:
+                    var_list = ['', '', '', '', '', '', '', '', '']
+                    # fill the name
+                    var_list[position['name']] = str(var)
+                    # merge the tile keys
+                    var_list[position['title']] = str(file_dict[group][var]['title'] + ';' + file_dict[group][var]['xtitle'] + ';' + file_dict[group][var]['ytitle'])
+                    # get the right path
+                    var_list[position['path']] = str(file_dict[group][var]['path'][usage])
+                    # just copy the rest
+                    for key in ['xbins', 'xmin', 'xmax', 'type']:
+                        var_list[position[key]] = str(file_dict[group][var][key])
+                    if(file_dict[group][var]['type'] == 'TProfile'):
+                        var_list[position['ymin']] = str(file_dict[group][var]['ymin'])
+                        var_list[position['ymax']] = str(file_dict[group][var]['ymax'])
+                    # append the current variable to the list
+                    list.append(var_list)
+    
+    return list
+
+
+
diff --git a/PhysicsAnalysis/PhysicsValidation/PhysValMonitoring/share/PhysValBtag_jobOptions.py b/PhysicsAnalysis/PhysicsValidation/PhysValMonitoring/share/PhysValBtag_jobOptions.py
index a80752ae56d1c3d3913166d3e11ed196584d0182..1af049cb84181f2abd599ba28f90f458ecba17fd 100644
--- a/PhysicsAnalysis/PhysicsValidation/PhysValMonitoring/share/PhysValBtag_jobOptions.py
+++ b/PhysicsAnalysis/PhysicsValidation/PhysValMonitoring/share/PhysValBtag_jobOptions.py
@@ -1,9 +1,26 @@
+from PhysValMonitoring.PhysValUtils import getHistogramDefinitions
+import os
+from RecExConfig.RecFlags import rec as recFlags
+
 from JetTagDQA.JetTagDQAConf import JetTagDQA__PhysValBTag
 tool1 = JetTagDQA__PhysValBTag()
 tool1.EnableLumi = False
 tool1.OutputLevel = WARNING
 tool1.DetailLevel = 10
-tool1.isData = True
+tool1.isData = not recFlags.doTruth()
+tool1.JetPtCutTtbar = 20000
+tool1.JetPtCutZprime = 500000
+tool1.JVTCutAntiKt4EMTopoJets = 0.59
+tool1.JVTCutLargerEtaAntiKt4EMTopoJets = 0.11
+tool1.JVTCutAntiKt4EMPFlowJets = 0.2
+tool1.truthMatchProbabilityCut = 0.75
+
+cmake_build_dir = ""
+if 'WorkDir_DIR' in os.environ:
+    cmake_build_dir = (os.environ['WorkDir_DIR'])
+
+path = cmake_build_dir + "/data/JetTagDQA/PhysValBtag_VariablesMenu.json"
+tool1.HistogramDefinitionsVector = getHistogramDefinitions(path, 'PHYSVAL', 'ALL')
 
 monMan = CfgMgr.AthenaMonManager("PhysValMonManager")
 monMan.AthenaMonTools += [ tool1 ]
diff --git a/Projects/AnalysisBase/version.txt b/Projects/AnalysisBase/version.txt
index 4445bce4316bce895a4265aa810260c83bf42e39..82b2fea7ffe6c4888aa388c3bfe0abf690c43764 100644
--- a/Projects/AnalysisBase/version.txt
+++ b/Projects/AnalysisBase/version.txt
@@ -1 +1 @@
-22.2.18
+22.2.19
diff --git a/Projects/AthAnalysis/version.txt b/Projects/AthAnalysis/version.txt
index 4445bce4316bce895a4265aa810260c83bf42e39..82b2fea7ffe6c4888aa388c3bfe0abf690c43764 100644
--- a/Projects/AthAnalysis/version.txt
+++ b/Projects/AthAnalysis/version.txt
@@ -1 +1 @@
-22.2.18
+22.2.19
diff --git a/Projects/AthDataQuality/version.txt b/Projects/AthDataQuality/version.txt
index 4d15ca0406c60c5d409bc33ab5858a0090feb7d2..2356062a8494f874cc3886c928776c55493535c7 100644
--- a/Projects/AthDataQuality/version.txt
+++ b/Projects/AthDataQuality/version.txt
@@ -1 +1 @@
-22.0.30
+22.0.32
diff --git a/Projects/AthSimulation/version.txt b/Projects/AthSimulation/version.txt
index 4d15ca0406c60c5d409bc33ab5858a0090feb7d2..2356062a8494f874cc3886c928776c55493535c7 100644
--- a/Projects/AthSimulation/version.txt
+++ b/Projects/AthSimulation/version.txt
@@ -1 +1 @@
-22.0.30
+22.0.32
diff --git a/Projects/Athena/version.txt b/Projects/Athena/version.txt
index e5078b479cf7c53b9a657a8440d822748ade1826..2356062a8494f874cc3886c928776c55493535c7 100644
--- a/Projects/Athena/version.txt
+++ b/Projects/Athena/version.txt
@@ -1 +1 @@
-22.0.31
+22.0.32
diff --git a/Projects/VP1Light/version.txt b/Projects/VP1Light/version.txt
index 4d15ca0406c60c5d409bc33ab5858a0090feb7d2..2356062a8494f874cc3886c928776c55493535c7 100644
--- a/Projects/VP1Light/version.txt
+++ b/Projects/VP1Light/version.txt
@@ -1 +1 @@
-22.0.30
+22.0.32
diff --git a/Reconstruction/Jet/JetCalibTools/JetCalibTools/CalibrationMethods/InsituDataCorrection.h b/Reconstruction/Jet/JetCalibTools/JetCalibTools/CalibrationMethods/InsituDataCorrection.h
index b002886676842e114bf5ed066471c28b529e4a10..d1c9957741a4e463df11955d2adcb3401ca5af99 100644
--- a/Reconstruction/Jet/JetCalibTools/JetCalibTools/CalibrationMethods/InsituDataCorrection.h
+++ b/Reconstruction/Jet/JetCalibTools/JetCalibTools/CalibrationMethods/InsituDataCorrection.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef JETCALIBTOOLS_INSITUDATACORRECTION_H
@@ -42,18 +42,21 @@ class InsituDataCorrection
 
  private:
   double getInsituCorr(double pt, double eta, std::string calibstep) const;
+  double getInsituCorr_JMS(double pt, double mass, double eta, std::string calibstep, bool isTAmass) const;
   TH2D * combineCalibration(TH2D *h2d, TH1D *h);
+  TH2D * invertHistogram(TH2D *h2d);
  
  private:
   TEnv * m_config;
   TString m_jetAlgo, m_calibAreaTag;
   bool m_dev;
 
-  TH2D * m_insituCorr;
-  double m_insituEtaMax, m_insituPtMin, m_insituPtMax;
+  std::unique_ptr<TH2D> m_insituCorr;
+  std::unique_ptr<TH2D> m_insituCorr_JMS;
+  std::unique_ptr<TH2D> m_insituCorr_JMS_TA;
+  double m_insituEtaMax, m_insituPtMin, m_insituPtMax, m_insituEtaMax_JMS, m_insituPtMin_JMS, m_insituPtMax_JMS, m_insituMassMin_JMS, m_insituMassMax_JMS;
   double m_relhistoPtMax, m_abshistoPtMax;
-
-  TH2D * m_insituCorr_ResidualMCbased;
+  std::unique_ptr<TH2D> m_insituCorr_ResidualMCbased;
   double m_insituEtaMax_ResidualMCbased, m_insituPtMin_ResidualMCbased, m_insituPtMax_ResidualMCbased;
 
   bool m_applyRelativeandAbsoluteInsitu;
@@ -62,6 +65,9 @@ class InsituDataCorrection
   bool m_applyResidualMCbasedInsitu;
   bool m_applyEtaRestrictionResidualMCbased;
 
+  bool m_applyInsituCaloTAjets;
+  bool m_applyInsituJMS;
+
 };
 
 #endif
diff --git a/Reconstruction/Jet/JetCalibTools/JetCalibTools/CalibrationMethods/JMSCorrection.h b/Reconstruction/Jet/JetCalibTools/JetCalibTools/CalibrationMethods/JMSCorrection.h
index f9c7ffe5c9defc1d755f819a1b0570f8983d7231..dab61091198551af89aa43016d0f41b68f4c00d3 100644
--- a/Reconstruction/Jet/JetCalibTools/JetCalibTools/CalibrationMethods/JMSCorrection.h
+++ b/Reconstruction/Jet/JetCalibTools/JetCalibTools/CalibrationMethods/JMSCorrection.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef JETCALIBTOOLS_JMSCORRECTION_H
@@ -81,6 +81,7 @@ class JMSCorrection
 
   bool m_combination; // Mass Combination of calo mass with track-assisted mass
   bool m_useCorrelatedWeights; 
+  bool m_onlyCombination; //mass combination using insitu calibrated inputs
 
   // Control the binning using a private class enum
   enum class BinningParam { pt_mass_eta, e_LOGmOe_eta, e_LOGmOet_eta, e_LOGmOpt_eta, et_LOGmOet_eta };
diff --git a/Reconstruction/Jet/JetCalibTools/JetCalibTools/JetCalibrationTool.h b/Reconstruction/Jet/JetCalibTools/JetCalibTools/JetCalibrationTool.h
index 711c8f1972dac7fa127d018a679fa31fb90e2a76..eed0f4ecb474c5bc60a21a17cc5a9c158745b725 100644
--- a/Reconstruction/Jet/JetCalibTools/JetCalibTools/JetCalibrationTool.h
+++ b/Reconstruction/Jet/JetCalibTools/JetCalibTools/JetCalibrationTool.h
@@ -119,10 +119,13 @@ private:
   std::vector<double>  m_runBins;
   bool m_doSetDetectorEta;
   std::string m_vertexContainerName;
+  bool m_insituCombMassCalib;
+  std::vector<TString> m_insituCombMassConfig;
 
   //TEnv to hold the global text config
   TEnv * m_globalConfig;
   std::vector<TEnv*> m_globalTimeDependentConfigs;
+  std::vector<TEnv*> m_globalInsituCombMassConfig;
 
   //Bools/enums to avoid string comparisons at run time
   jetScale m_jetScale;
@@ -145,6 +148,8 @@ private:
   std::vector<JetCalibrationToolBase*> m_insituTimeDependentCorr;
   JMSCorrection * m_jetMassCorr;
   JetSmearingCorrection* m_jetSmearCorr;
+  JMSCorrection *m_insituCombMassCorr_tmp;
+  std::vector<JetCalibrationToolBase*> m_insituCombMassCorr;
 
 }; 
 
diff --git a/Reconstruction/Jet/JetCalibTools/Root/InsituDataCorrection.cxx b/Reconstruction/Jet/JetCalibTools/Root/InsituDataCorrection.cxx
index 67cb11ddf3f7b7fb4aca666752fb8ef1935c4ee3..1f191a99527d4e0cce7c5875d6d91a211d9a8551 100644
--- a/Reconstruction/Jet/JetCalibTools/Root/InsituDataCorrection.cxx
+++ b/Reconstruction/Jet/JetCalibTools/Root/InsituDataCorrection.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "JetCalibTools/CalibrationMethods/InsituDataCorrection.h"
@@ -7,24 +7,39 @@
 
 InsituDataCorrection::InsituDataCorrection()
   : JetCalibrationToolBase::JetCalibrationToolBase("InsituDataCorrection::InsituDataCorrection"),
-    m_config(NULL), m_jetAlgo(""), m_calibAreaTag(""), m_dev(false), m_insituCorr(NULL), m_insituCorr_ResidualMCbased(NULL)
+    m_config(nullptr),
+    m_jetAlgo(""),
+    m_calibAreaTag(""),
+    m_dev(false),
+    m_insituCorr(nullptr),
+    m_insituCorr_JMS(nullptr),
+    m_insituCorr_ResidualMCbased(nullptr)
 { }
 
 InsituDataCorrection::InsituDataCorrection(const std::string& name)
   : JetCalibrationToolBase::JetCalibrationToolBase( name ),
-    m_config(NULL), m_jetAlgo(""), m_calibAreaTag(""), m_dev(false), m_insituCorr(NULL), m_insituCorr_ResidualMCbased(NULL)
+    m_config(nullptr),
+    m_jetAlgo(""),
+    m_calibAreaTag(""),
+    m_dev(false),
+    m_insituCorr(nullptr),
+    m_insituCorr_JMS(nullptr),
+    m_insituCorr_ResidualMCbased(nullptr)
 { }
 
 InsituDataCorrection::InsituDataCorrection(const std::string& name, TEnv * config, TString jetAlgo, TString calibAreaTag, bool dev)
   : JetCalibrationToolBase::JetCalibrationToolBase( name ),
-    m_config(config), m_jetAlgo(jetAlgo), m_calibAreaTag(calibAreaTag), m_dev(dev), m_insituCorr(NULL), m_insituCorr_ResidualMCbased(NULL)
+    m_config(config),
+    m_jetAlgo(jetAlgo),
+    m_calibAreaTag(calibAreaTag),
+    m_dev(dev),
+    m_insituCorr(nullptr),
+    m_insituCorr_JMS(nullptr),
+    m_insituCorr_ResidualMCbased(nullptr)
 { }
 
 InsituDataCorrection::~InsituDataCorrection() {
 
-  if(m_insituCorr) delete m_insituCorr;
-  if(m_insituCorr_ResidualMCbased) delete m_insituCorr_ResidualMCbased;
-
 }
 
 StatusCode InsituDataCorrection::initializeTool(const std::string&) {
@@ -53,6 +68,10 @@ StatusCode InsituDataCorrection::initializeTool(const std::string&) {
   double insitu_etarestriction_residualmcbased = m_config->GetValue("InsituEtaRestrictionResidualMCbased",0.8);
   //Retrieve the Eta restriction on the Relative and Absolute insitu calibration
   double insitu_etarestriction_relativeandabsolute = m_config->GetValue("InsituEtaRestrictionRelativeandAbsolute",0.8);
+  // Apply Insitu only to calo and TA mass calibrated jets (only for large jets)
+  m_applyInsituCaloTAjets = m_config->GetValue("ApplyInsituCaloTAJets", false);
+  // Apply in situ JMS:
+  m_applyInsituJMS = m_config->GetValue("ApplyInsituJMS", false);
 
   //Find the absolute path to the insitu root file
   if ( !insitu_filename.EqualTo("None") ){
@@ -82,14 +101,14 @@ StatusCode InsituDataCorrection::initializeTool(const std::string&) {
     m_relhistoPtMax = rel_histo->GetXaxis()->GetBinLowEdge(rel_histo->GetNbinsX()+1);
     m_abshistoPtMax = abs_histo->GetBinLowEdge(abs_histo->GetNbinsX()+1);
     // combine in situ calibrations
-    m_insituCorr = combineCalibration(rel_histo.get(),abs_histo.get());
+    m_insituCorr = std::unique_ptr<TH2D>(combineCalibration(rel_histo.get(),abs_histo.get()));
     m_insituEtaMax = m_insituCorr->GetYaxis()->GetBinLowEdge(m_insituCorr->GetNbinsY()+1);
     m_insituPtMin = m_insituCorr->GetXaxis()->GetBinLowEdge(1);
     m_insituPtMax = m_insituCorr->GetXaxis()->GetBinLowEdge(m_insituCorr->GetNbinsX()+1);
     if(m_applyEtaRestrictionRelativeandAbsolute) m_insituEtaMax = insitu_etarestriction_relativeandabsolute;
   }
   if(m_applyResidualMCbasedInsitu){
-    m_insituCorr_ResidualMCbased = (TH2D*)JetCalibUtils::GetHisto2(insitu_file,residualmcbased_histoname);
+    m_insituCorr_ResidualMCbased = std::unique_ptr<TH2D>((TH2D*)JetCalibUtils::GetHisto2(insitu_file,residualmcbased_histoname));
     if ( !m_insituCorr_ResidualMCbased ) {
       ATH_MSG_FATAL( "\n  Tool configured for the Residual MC based correction, but no residualmcbased in-situ histograms could be retrieved. Aborting..." );
       return StatusCode::FAILURE;
@@ -102,12 +121,79 @@ StatusCode InsituDataCorrection::initializeTool(const std::string&) {
     }
     if(m_applyEtaRestrictionResidualMCbased) m_insituEtaMax_ResidualMCbased = insitu_etarestriction_residualmcbased;
   }
-  if(!m_applyRelativeandAbsoluteInsitu & !m_applyResidualMCbasedInsitu){
+  if(!m_applyRelativeandAbsoluteInsitu && !m_applyResidualMCbasedInsitu){
     ATH_MSG_FATAL( "\n  Tool configured for Insitu correction, but no in-situ histograms could be retrieved. Aborting..." );
     return StatusCode::FAILURE;
   }
 
-  //insitu_file->Close();
+  //Large-R in situ JMS calibration  
+  if(m_applyInsituJMS){
+    //Retrieve the name of root files containing the in-situ calibration histograms from the config
+    TString insituJMS_filename = m_config->GetValue("InsituCalibrationFile_JMS","None");
+    //Retrieve the name of the histogram for the absolute in-situ calibration
+    TString abs_histoname_JMS = m_config->GetValue("AbsoluteInsituCalibrationHistogram_JMS","");
+    TString abs_histoname_JMS_TA = m_config->GetValue("AbsoluteInsituCalibrationHistogram_JMS_TA","");
+    //Retrieve the eta range for the in-situ JMS calibration
+    double insitu_etarestriction_JMS = m_config->GetValue("InsituEtaRestriction_JMS",2.0);
+
+    //Find the absolute path to the insitu root file Low and High Mass
+    if ( !insituJMS_filename.EqualTo("None")){
+      if(m_dev){
+        insituJMS_filename.Remove(0,32);
+        insituJMS_filename.Insert(0,"JetCalibTools/");
+      }
+      else{
+        insituJMS_filename.Insert(14,m_calibAreaTag);
+      }
+      insituJMS_filename=PathResolverFindCalibFile(insituJMS_filename.Data());
+    }
+
+    TFile *insituJMS_file = TFile::Open(insituJMS_filename);
+    if ( !insituJMS_file ) { ATH_MSG_FATAL( "Cannot open InsituJMSCalibrationFile: " << insituJMS_filename ); return StatusCode::FAILURE; }
+
+    ATH_MSG_INFO("Reading In-situ JMS correction factors from: " << insituJMS_filename);
+
+    abs_histoname_JMS.ReplaceAll("JETALGO",m_jetAlgo);
+    if(m_applyInsituCaloTAjets){
+      abs_histoname_JMS_TA.ReplaceAll("JETALGO",m_jetAlgo);
+    }
+
+    if(m_applyRelativeandAbsoluteInsitu){
+      std::unique_ptr<TH2D> abs_histo_JMS(dynamic_cast<TH2D*>(JetCalibUtils::GetHisto2(insituJMS_file,abs_histoname_JMS)));
+      if ( !abs_histo_JMS ) {
+        ATH_MSG_FATAL( "\n  Tool configured for data, but no in-situ JMS histogram could be retrieved. Aborting..." );
+        return StatusCode::FAILURE;
+      }
+      else {
+        gROOT->cd();
+        // combine in situ calibrations
+        m_insituCorr_JMS    = std::unique_ptr<TH2D>(invertHistogram(abs_histo_JMS.get()));
+        m_insituEtaMax_JMS  = insitu_etarestriction_JMS;
+        m_insituPtMin_JMS   = m_insituCorr_JMS->GetXaxis()->GetBinLowEdge(1);
+        m_insituPtMax_JMS   = m_insituCorr_JMS->GetXaxis()->GetBinLowEdge(m_insituCorr_JMS->GetNbinsX()+1);
+        m_insituMassMin_JMS = m_insituCorr_JMS->GetYaxis()->GetBinLowEdge(1);
+        m_insituMassMax_JMS = m_insituCorr_JMS->GetYaxis()->GetBinLowEdge((m_insituCorr_JMS->GetNbinsY()+1));
+
+        if(m_applyInsituCaloTAjets){
+
+	  std::unique_ptr<TH2D> abs_histo_JMS_TA(dynamic_cast<TH2D*>(JetCalibUtils::GetHisto2(insituJMS_file,abs_histoname_JMS_TA)));
+
+          if ( !abs_histo_JMS_TA ){
+            ATH_MSG_FATAL( "\n  Tool configured for data, but no in-situ JMS histogram for TA mass could be retrieved. Aborting..." );
+            return StatusCode::FAILURE;
+          }
+
+          gROOT->cd();
+          m_insituCorr_JMS_TA = std::unique_ptr<TH2D>(invertHistogram(abs_histo_JMS_TA.get()));
+        }
+      }
+    }
+    if(!m_applyRelativeandAbsoluteInsitu){
+      ATH_MSG_FATAL( "\n  Tool configured for Insitu correction, but no in-situ histograms could be retrieved. Aborting..." );
+      return StatusCode::FAILURE;
+    }
+  }
+
   ATH_MSG_INFO("Tool configured to calibrate data");
   ATH_MSG_INFO("In-situ correction to be applied: " << insitu_desc);
   return StatusCode::SUCCESS;
@@ -116,28 +202,117 @@ StatusCode InsituDataCorrection::initializeTool(const std::string&) {
 
 StatusCode InsituDataCorrection::calibrateImpl(xAOD::Jet& jet, JetEventInfo&) const {
 
-  xAOD::JetFourMom_t jetStartP4;
-  ATH_CHECK( setStartP4(jet) );
-  jetStartP4 = jet.jetP4();
-
   float detectorEta = jet.getAttribute<float>("DetectorEta");
 
-  xAOD::JetFourMom_t calibP4=jetStartP4;
+  // For small R jets or large-R jets without calo-TA combination
+  if(!m_applyInsituCaloTAjets){
+    xAOD::JetFourMom_t jetStartP4;
+    ATH_CHECK( setStartP4(jet) );
+    jetStartP4 = jet.jetP4();
+
+    xAOD::JetFourMom_t calibP4=jetStartP4;
   
-  if(m_applyResidualMCbasedInsitu) calibP4=calibP4*getInsituCorr( calibP4.pt(), fabs(detectorEta), "ResidualMCbased" );
+    if(m_applyResidualMCbasedInsitu) calibP4=calibP4*getInsituCorr( calibP4.pt(), fabs(detectorEta), "ResidualMCbased" );
+    
+    if(m_dev){
+      float insituFactor = getInsituCorr( jetStartP4.pt(), detectorEta, "RelativeAbs" );
+      jet.setAttribute<float>("JetRelativeAbsInsituCalibFactor",insituFactor);
+    }
 
-  if(m_dev){
-    float insituFactor = getInsituCorr( jetStartP4.pt(), detectorEta, "RelativeAbs" );
-    jet.setAttribute<float>("JetRelativeAbsInsituCalibFactor",insituFactor);
+    if(m_applyRelativeandAbsoluteInsitu) calibP4=calibP4*getInsituCorr( jetStartP4.pt(), detectorEta, "RelativeAbs" );
+
+    // Only for large R jets with insitu JMS but no combination
+    if(m_applyInsituJMS){
+      xAOD::JetFourMom_t calibP4_JMS;
+      calibP4_JMS = calibP4;
+
+      calibP4_JMS=calibP4*getInsituCorr_JMS( calibP4.pt(), calibP4.M(), detectorEta, "RelativeAbs", false );
+
+      // pT doesn't change while applying in situ JMS
+      TLorentzVector TLVjet;
+      TLVjet.SetPtEtaPhiM( calibP4.pt(), calibP4.eta(), calibP4.phi(), calibP4_JMS.M() );
+      calibP4.SetPxPyPzE( TLVjet.Px(), TLVjet.Py(), TLVjet.Pz(), TLVjet.E() );
+    }
+
+    //Transfer calibrated jet properties to the Jet object
+    jet.setAttribute<xAOD::JetFourMom_t>("JetInsituScaleMomentum",calibP4);
+    jet.setJetP4( calibP4 );
   }
 
-  if(m_applyRelativeandAbsoluteInsitu) calibP4=calibP4*getInsituCorr( jetStartP4.pt(), detectorEta, "RelativeAbs" );
+  // For large-R jets: insitu needs to be applied to calo mass and TA mass (by default it's only applied to combined mass)
+  if(m_applyInsituCaloTAjets){
+
+    // calo mass calibrated jets
+    xAOD::JetFourMom_t jetStartP4_calo;
+    xAOD::JetFourMom_t calibP4_calo;
+    if(jet.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumCalo",jetStartP4_calo)){
+      calibP4_calo=jetStartP4_calo;
+    }else{
+      ATH_MSG_FATAL( "Cannot retrieve JetJMSScaleMomentumCalo jets" );
+      return StatusCode::FAILURE;
+    }
+
+    if(m_applyResidualMCbasedInsitu) calibP4_calo=calibP4_calo*getInsituCorr( calibP4_calo.pt(), fabs(detectorEta), "ResidualMCbased" );
+
+    if(m_dev){
+      float insituFactor_calo = getInsituCorr( jetStartP4_calo.pt(), detectorEta, "RelativeAbs" );
+      jet.setAttribute<float>("JetRelativeAbsInsituCalibFactor_calo",insituFactor_calo);
+    }
+
+    if(m_applyRelativeandAbsoluteInsitu) calibP4_calo=calibP4_calo*getInsituCorr( jetStartP4_calo.pt(), detectorEta, "RelativeAbs" );
+
+    if(m_applyInsituJMS){
+      xAOD::JetFourMom_t calibP4_calo_JMS;
+      calibP4_calo_JMS = calibP4_calo;
+
+      calibP4_calo_JMS=calibP4_calo*getInsituCorr_JMS( calibP4_calo.pt(), calibP4_calo.M(), detectorEta, "RelativeAbs", false );
 
-  // If the jet mass calibration was applied the calibrated mass needs to be used!
+      // pT doesn't change while applying in situ JMS
+      TLorentzVector TLVjet_calo;
+      TLVjet_calo.SetPtEtaPhiM( calibP4_calo.pt(), calibP4_calo.eta(), calibP4_calo.phi(), calibP4_calo_JMS.M() );
+      calibP4_calo.SetPxPyPzE( TLVjet_calo.Px(), TLVjet_calo.Py(), TLVjet_calo.Pz(), TLVjet_calo.E() );
+    }
+
+    //Transfer calibrated jet properties to the Jet object
+    jet.setAttribute<xAOD::JetFourMom_t>("JetInsituScaleMomentumCalo",calibP4_calo);
+    jet.setJetP4( calibP4_calo );
+
+    // TA mass calibrated jets
+    xAOD::JetFourMom_t jetStartP4_ta;
+    xAOD::JetFourMom_t calibP4_ta;
+    if(jet.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumTA", jetStartP4_ta)){
+      calibP4_ta=jetStartP4_ta;
+    }else{
+      ATH_MSG_FATAL( "Cannot retrieve JetJMSScaleMomentumTA jets" );
+      return StatusCode::FAILURE;
+    }
 
-  //Transfer calibrated jet properties to the Jet object
-  jet.setAttribute<xAOD::JetFourMom_t>("JetInsituScaleMomentum",calibP4);
-  jet.setJetP4( calibP4 );
+    if(m_applyResidualMCbasedInsitu) calibP4_ta=calibP4_ta*getInsituCorr( calibP4_ta.pt(), fabs(detectorEta), "ResidualMCbased" );
+
+    if(m_dev){
+      float insituFactor_ta = getInsituCorr( jetStartP4_ta.pt(), detectorEta, "RelativeAbs" );
+      jet.setAttribute<float>("JetRelativeAbsInsituCalibFactor_ta",insituFactor_ta);
+    }
+
+    if(m_applyRelativeandAbsoluteInsitu) calibP4_ta=calibP4_ta*getInsituCorr( jetStartP4_ta.pt(), detectorEta, "RelativeAbs" );
+
+    if(m_applyInsituJMS){
+      xAOD::JetFourMom_t calibP4_ta_JMS;
+      calibP4_ta_JMS = calibP4_ta;
+
+      calibP4_ta_JMS=calibP4_ta*getInsituCorr_JMS( calibP4_ta.pt(), calibP4_ta.M(), detectorEta, "RelativeAbs", true );
+
+      // pT doesn't change while applying in situ JMS
+      TLorentzVector TLVjet_ta;
+      TLVjet_ta.SetPtEtaPhiM( calibP4_ta.pt(), calibP4_ta.eta(), calibP4_ta.phi(), calibP4_ta_JMS.M() );
+      calibP4_ta.SetPxPyPzE( TLVjet_ta.Px(), TLVjet_ta.Py(), TLVjet_ta.Pz(), TLVjet_ta.E() );
+    }
+
+    //Transfer calibrated jet properties to the Jet object
+    jet.setAttribute<xAOD::JetFourMom_t>("JetInsituScaleMomentumTA",calibP4_ta);
+    jet.setJetP4( calibP4_ta );
+
+  }
 
   return StatusCode::SUCCESS;
 }
@@ -175,6 +350,49 @@ double InsituDataCorrection::getInsituCorr(double pt, double eta, std::string ca
   return m_insituCorr->Interpolate(myPt,myEta);
 }
 
+double InsituDataCorrection::getInsituCorr_JMS(double pt, double mass, double eta, std::string calibstep, bool isTAmass) const {
+
+  if(!isTAmass){
+    if (!m_insituCorr_JMS) return 1.0;
+  }
+  else{
+    if (!m_insituCorr_JMS_TA) return 1.0;
+  }
+
+  double myEta = eta, myPt = pt/m_GeV, myMass = mass/m_GeV;
+
+  //eta and pt ranges depends on the insitu calibration
+  double etaMax  = m_insituEtaMax_JMS;
+  double ptMin   = m_insituPtMin_JMS;
+  double ptMax   = m_insituPtMax_JMS;
+  double massMin = m_insituMassMin_JMS;
+  double massMax = m_insituMassMax_JMS;
+
+  //protection against values outside the histogram range, snap back to the lowest/highest bin edge
+  if ( myPt <= ptMin ) myPt = ptMin + 1e-6;
+  else if ( myPt >= ptMax ) myPt = ptMax - 1e-6;
+  if (calibstep == "RelativeAbs" && m_applyEtaRestrictionRelativeandAbsolute) {
+    if(myEta>=etaMax) return 1.0;
+    else if(myEta<=-etaMax) return 1.0;
+  }
+  if (myEta <= -etaMax) myEta = 1e-6 - etaMax;
+  else if (myEta >= etaMax) myEta = etaMax - 1e-6;
+  if (myMass <= massMin ) myMass = massMin + 1e-6;
+  else if (myMass >= massMax ) myMass = massMax - 1e-6;
+
+  double calibFactor = 1.0;
+  if(!isTAmass){
+    calibFactor = m_insituCorr_JMS->Interpolate(myPt,myMass);
+  }
+  else{
+    calibFactor = m_insituCorr_JMS_TA->Interpolate(myPt,myMass);
+  }
+
+  return calibFactor;
+}
+
+
+
 TH2D * InsituDataCorrection::combineCalibration(TH2D *h2d, TH1D *h) {
   TH2D *prod = (TH2D*)h2d->Clone();
   for (int xi=1;xi<=prod->GetNbinsX();xi++) {
@@ -189,3 +407,14 @@ TH2D * InsituDataCorrection::combineCalibration(TH2D *h2d, TH1D *h) {
   }
   return prod;
 }
+
+TH2D * InsituDataCorrection::invertHistogram(TH2D *h2d){
+  TH2D *inv = (TH2D*)h2d->Clone();
+  for (int xi=1;xi<=inv->GetNbinsX();xi++) {
+    for (int yi=1;yi<=inv->GetNbinsY();yi++) {
+      inv->SetBinContent(xi,yi,1./h2d->GetBinContent(xi,yi));
+
+    }
+  }
+  return inv;
+}
diff --git a/Reconstruction/Jet/JetCalibTools/Root/JMSCorrection.cxx b/Reconstruction/Jet/JetCalibTools/Root/JMSCorrection.cxx
index 98144e15cbaac030b44f929efcff33d01279517e..2a5ee556e56eb5883199fc1e0c053bb45a5c0026 100644
--- a/Reconstruction/Jet/JetCalibTools/Root/JMSCorrection.cxx
+++ b/Reconstruction/Jet/JetCalibTools/Root/JMSCorrection.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 /*
@@ -66,7 +66,7 @@ StatusCode JMSCorrection::initializeTool(const std::string&) {
 
   if ( !m_config ) { ATH_MSG_FATAL("Config file not specified. Aborting."); return StatusCode::FAILURE; }
 
-  m_jetStartScale = m_config->GetValue("JMSStartingScale","JetGSCScaleMomentum");
+  m_jetStartScale = m_config->GetValue("JMSStartingScale","JetEtaJESScaleMomentum");
   m_jetOutScale = m_config->GetValue("JMSOutScale","JetJMSScaleMomentum");
   // Starting pT value to calibrate
   m_pTMinCorr = m_config->GetValue("MinpT",180); 
@@ -83,116 +83,116 @@ StatusCode JMSCorrection::initializeTool(const std::string&) {
   // *Note* that it is assumed the calo and TA masses use the same histogram dimensionality
   m_use3Dhisto = m_config->GetValue("MassCalibrationIs3D",false);
 
-
-
-  //find the ROOT file containing response histograms, path comes from the config file.
-  TString JMSFile = m_config->GetValue("MassCalibrationFile","empty");
-  if ( JMSFile.EqualTo("empty") ) { 
-    ATH_MSG_FATAL("NO JMSFactorsFile specified. Aborting.");
-    return StatusCode::FAILURE;
-  }
-  if(m_dev){
-    JMSFile.Remove(0,33);
-    JMSFile.Insert(0,"JetCalibTools/");
-  }
-  else{JMSFile.Insert(14,m_calibAreaTag);}
-  TString fileName = PathResolverFindCalibFile(JMSFile.Data());
-  TFile *inputFile = TFile::Open(fileName);
-  if (!inputFile){
-    ATH_MSG_FATAL("Cannot open JMS factors file" << fileName);
-    return StatusCode::FAILURE;
-  }
-
-  //ATH_MSG_INFO("  for " << m_jetAlgo << " jets\n\n");
-
-  if (!m_use3Dhisto) setMassEtaBins( JetCalibUtils::VectorizeD( m_config->GetValue("MassEtaBins","") ) );
-
-  //Get a TList of TKeys pointing to the histograms contained in the ROOT file
-  inputFile->cd();
-  TList *keys = inputFile->GetListOfKeys();
-  //fill the names of the TKeys into a vector of TStrings
-  TIter ikeys(keys);
-  while ( TKey *iterobj = (TKey*)ikeys() ) {
-    TString histoName = iterobj->GetName();
-    if ( histoName.Contains(m_jetAlgo) ) 
-    { 
-      if (m_use3Dhisto)
-        m_respFactorMass3D = dynamic_cast<TH3F*>(JetCalibUtils::GetHisto3(inputFile,histoName.Data()));
-      else
-        m_respFactorsMass.push_back( (TH2F*)JetCalibUtils::GetHisto2(inputFile,histoName.Data()) );
-    }
-  }
-
-  //Make sure we put something in the vector of TH2Fs or we filled the TH3F
-  if ( !m_use3Dhisto && m_respFactorsMass.size() < 3 ) {
-    ATH_MSG_FATAL("Vector of mass correction histograms may be empty. Please check your mass calibration file: " << JMSFile);
-    return StatusCode::FAILURE;
-  }
-  else if ( m_use3Dhisto && !m_respFactorMass3D)
-  {
-    ATH_MSG_FATAL("3D mass correction histogram may be missing.  Please check your mass calibration file: " << JMSFile);
-    return StatusCode::FAILURE;
-  }
-  else ATH_MSG_INFO("JMS Tool has been initialized with binning and eta fit factors from: " << fileName);
-
-  // Shoulb be applied the mass combination?
+  // Should the mass combination be applied?
   m_combination = m_config->GetValue("Combination",false); // true: turn on combination of calo mass with track-assisted mass
   m_useCorrelatedWeights = m_config->GetValue("UseCorrelatedWeights",false); // true: turn on combination of calo mass with track-assisted mass
+  // Should we only apply the combination (e.g after in situ calibration)
+  m_onlyCombination = m_config->GetValue("OnlyCombination",false);
 
-  // Track-Assisted Jet Mass correction
-  m_trackAssistedJetMassCorr = m_config->GetValue("TrackAssistedJetMassCorr",false);
-  TString JMS_TrackAssisted_File;
-  TString file_trkAssisted_Name;
-  TFile *inputFile_trkAssisted;
-  if(m_trackAssistedJetMassCorr || m_combination){
-    ATH_MSG_INFO("Track Assisted Jet Mass will be calibrated");
-    JMS_TrackAssisted_File = m_config->GetValue("TrackAssistedMassCalibrationFile","empty");
-    if ( JMS_TrackAssisted_File.EqualTo("empty") ) { 
-      ATH_MSG_FATAL("NO Track Assisted Mass Factors File specified. Aborting.");
+  //find the ROOT file containing response histograms, path comes from the config file.
+  TString JMSFile;
+
+  if(!m_onlyCombination){
+    JMSFile =  m_config->GetValue("MassCalibrationFile","empty");
+    if ( JMSFile.EqualTo("empty") ) { 
+      ATH_MSG_FATAL("NO JMSFactorsFile specified. Aborting.");
       return StatusCode::FAILURE;
     }
     if(m_dev){
-      JMS_TrackAssisted_File.Remove(0,33);
-      JMS_TrackAssisted_File.Insert(0,"JetCalibTools/");
+      JMSFile.Remove(0,33);
+      JMSFile.Insert(0,"JetCalibTools/");
     }
-    else{JMS_TrackAssisted_File.Insert(14,m_calibAreaTag);}
-    file_trkAssisted_Name = PathResolverFindCalibFile(JMS_TrackAssisted_File.Data());
-    inputFile_trkAssisted = TFile::Open(file_trkAssisted_Name);
-    if (!inputFile_trkAssisted){
-      ATH_MSG_FATAL("Cannot open Track Assisted Mass factors file" << fileName);
+    else{JMSFile.Insert(14,m_calibAreaTag);}
+    TString fileName = PathResolverFindCalibFile(JMSFile.Data());
+    TFile *inputFile = TFile::Open(fileName);
+    if (!inputFile){
+      ATH_MSG_FATAL("Cannot open JMS factors file" << fileName);
       return StatusCode::FAILURE;
     }
-
-    //setMassEtaBins( JetCalibUtils::VectorizeD( m_config->GetValue("MassEtaBins","") ) );
-
+    
+    if (!m_use3Dhisto) setMassEtaBins( JetCalibUtils::VectorizeD( m_config->GetValue("MassEtaBins","") ) );
+    
     //Get a TList of TKeys pointing to the histograms contained in the ROOT file
-    inputFile_trkAssisted->cd();
-    TList *keys_trkAssisted = inputFile_trkAssisted->GetListOfKeys();
+    inputFile->cd();
+    TList *keys = inputFile->GetListOfKeys();
     //fill the names of the TKeys into a vector of TStrings
-    TIter ikeys_trkAssisted(keys_trkAssisted);
-    while ( TKey *iterobj = (TKey*)ikeys_trkAssisted() ) {
+    TIter ikeys(keys);
+    while ( TKey *iterobj = (TKey*)ikeys() ) {
       TString histoName = iterobj->GetName();
       if ( histoName.Contains(m_jetAlgo) ) 
-      { 
-        if (m_use3Dhisto)
-          m_respFactorTrackAssistedMass3D = dynamic_cast<TH3F*>(JetCalibUtils::GetHisto3(inputFile_trkAssisted,histoName.Data()));
-        else
-          m_respFactorsTrackAssistedMass.push_back( (TH2F*)JetCalibUtils::GetHisto2(inputFile_trkAssisted,histoName.Data()) );
-      }
+	{ 
+	  if (m_use3Dhisto)
+	    m_respFactorMass3D = dynamic_cast<TH3F*>(JetCalibUtils::GetHisto3(inputFile,histoName.Data()));
+	  else
+	    m_respFactorsMass.push_back( (TH2F*)JetCalibUtils::GetHisto2(inputFile,histoName.Data()) );
+	}
     }
-
-    //Make sure we put something in the vector of TH2Fs
-    if ( !m_use3Dhisto && m_respFactorsTrackAssistedMass.size() < 3 ) {
-      ATH_MSG_FATAL("Vector of track assisted mass correction histograms may be empty. Please check your track assisted mass calibration file: " << JMSFile);
+    
+    //Make sure we put something in the vector of TH2Fs or we filled the TH3F
+    if ( !m_use3Dhisto && m_respFactorsMass.size() < 3 ) {
+      ATH_MSG_FATAL("Vector of mass correction histograms may be empty. Please check your mass calibration file: " << JMSFile);
       return StatusCode::FAILURE;
     }
-    else if ( m_use3Dhisto && !m_respFactorTrackAssistedMass3D)
-    {
-      ATH_MSG_FATAL("3D track assisted mass correction histogram may be missing.  Please check your mass calibration file: " << JMSFile);
-      return StatusCode::FAILURE;
+    else if ( m_use3Dhisto && !m_respFactorMass3D)
+      {
+	ATH_MSG_FATAL("3D mass correction histogram may be missing.  Please check your mass calibration file: " << JMSFile);
+	return StatusCode::FAILURE;
+      }
+    else ATH_MSG_INFO("JMS Tool has been initialized with binning and eta fit factors from: " << fileName);
+    
+    // Track-Assisted Jet Mass correction
+    m_trackAssistedJetMassCorr = m_config->GetValue("TrackAssistedJetMassCorr",false);
+    TString JMS_TrackAssisted_File;
+    TString file_trkAssisted_Name;
+    TFile *inputFile_trkAssisted;
+    if(m_trackAssistedJetMassCorr){
+      ATH_MSG_INFO("Track Assisted Jet Mass will be calibrated");
+      JMS_TrackAssisted_File = m_config->GetValue("TrackAssistedMassCalibrationFile","empty");
+      if ( JMS_TrackAssisted_File.EqualTo("empty") ) { 
+	ATH_MSG_FATAL("NO Track Assisted Mass Factors File specified. Aborting.");
+	return StatusCode::FAILURE;
+      }
+      if(m_dev){
+	JMS_TrackAssisted_File.Remove(0,33);
+	JMS_TrackAssisted_File.Insert(0,"JetCalibTools/");
+      }
+      else{JMS_TrackAssisted_File.Insert(14,m_calibAreaTag);}
+      file_trkAssisted_Name = PathResolverFindCalibFile(JMS_TrackAssisted_File.Data());
+      inputFile_trkAssisted = TFile::Open(file_trkAssisted_Name);
+      if (!inputFile_trkAssisted){
+	ATH_MSG_FATAL("Cannot open Track Assisted Mass factors file" << fileName);
+	return StatusCode::FAILURE;
+      }
+      
+      //Get a TList of TKeys pointing to the histograms contained in the ROOT file
+      inputFile_trkAssisted->cd();
+      TList *keys_trkAssisted = inputFile_trkAssisted->GetListOfKeys();
+      //fill the names of the TKeys into a vector of TStrings
+      TIter ikeys_trkAssisted(keys_trkAssisted);
+      while ( TKey *iterobj = (TKey*)ikeys_trkAssisted() ) {
+	TString histoName = iterobj->GetName();
+	if ( histoName.Contains(m_jetAlgo) ) 
+	  { 
+	    if (m_use3Dhisto)
+	      m_respFactorTrackAssistedMass3D = dynamic_cast<TH3F*>(JetCalibUtils::GetHisto3(inputFile_trkAssisted,histoName.Data()));
+	    else
+	      m_respFactorsTrackAssistedMass.push_back( (TH2F*)JetCalibUtils::GetHisto2(inputFile_trkAssisted,histoName.Data()) );
+	  }
+      }
+      
+      //Make sure we put something in the vector of TH2Fs
+      if ( !m_use3Dhisto && m_respFactorsTrackAssistedMass.size() < 3 ) {
+	ATH_MSG_FATAL("Vector of track assisted mass correction histograms may be empty. Please check your track assisted mass calibration file: " << JMSFile);
+	return StatusCode::FAILURE;
+      }
+      else if ( m_use3Dhisto && !m_respFactorTrackAssistedMass3D)
+	{
+	  ATH_MSG_FATAL("3D track assisted mass correction histogram may be missing.  Please check your mass calibration file: " << JMSFile);
+	  return StatusCode::FAILURE;
+	}
+      else ATH_MSG_INFO("JMS Tool has been initialized with binning and eta fit factors from: " << file_trkAssisted_Name);
     }
-    else ATH_MSG_INFO("JMS Tool has been initialized with binning and eta fit factors from: " << file_trkAssisted_Name);
-  }
+  } //!m_onlyCombination
 
   // Combination
   TString Combination_File;
@@ -212,8 +212,8 @@ StatusCode JMSCorrection::initializeTool(const std::string&) {
     else{Combination_File.Insert(14,m_calibAreaTag);}
     file_combination_Name = PathResolverFindCalibFile(Combination_File.Data());
     inputFile_combination = TFile::Open(file_combination_Name);
-    if (!inputFile_combination){
-      ATH_MSG_FATAL("Cannot open Mass Combination file" << fileName);
+    if (!inputFile_combination && !m_onlyCombination){
+      ATH_MSG_FATAL("Cannot open Mass Combination file" << inputFile_combination);
       return StatusCode::FAILURE;
     }
 
@@ -262,33 +262,36 @@ StatusCode JMSCorrection::initializeTool(const std::string&) {
     }
 
     //Make sure we put something in the vector of TH2Ds OR filled the TH3s
-    if ( !m_use3Dhisto)
-    {
-      if ( m_caloResolutionMassCombination.size() < 1 ) {
-        ATH_MSG_FATAL("Vector of mass combination histograms with calo factors may be empty. Please check your mass combination file: " << JMSFile);
-        return StatusCode::FAILURE;
-      }
-      else if ( m_taResolutionMassCombination.size() < 1 ) {
-        ATH_MSG_FATAL("Vector of mass combination histograms with trk-assisted factors may be empty. Please check your mass combination file: " << JMSFile);
-        return StatusCode::FAILURE;
-      }
-    }
-    else
-    {
-      if (!m_caloResolutionMassCombination3D)
-      {
-        ATH_MSG_FATAL("Mass combination 3D histogram with calo factors was not filled.  Please check your mass combination file: " << JMSFile);
-        return StatusCode::FAILURE;
-      }
-      else if (!m_taResolutionMassCombination3D)
-      {
-        ATH_MSG_FATAL("Mass combination 3D histogram with trk-assisted factors was not filled.  Please check your mass combination file: " << JMSFile);
-        return StatusCode::FAILURE;
-      }
-    }
-    
+    if(!m_onlyCombination){
+      if ( !m_use3Dhisto)
+	{
+	  if ( m_caloResolutionMassCombination.size() < 1 ) {
+	    ATH_MSG_FATAL("Vector of mass combination histograms with calo factors may be empty. Please check your mass combination file: " << JMSFile);
+	    return StatusCode::FAILURE;
+	  }
+	  else if ( m_taResolutionMassCombination.size() < 1 ) {
+	    ATH_MSG_FATAL("Vector of mass combination histograms with trk-assisted factors may be empty. Please check your mass combination file: " << JMSFile);
+	    return StatusCode::FAILURE;
+	  }
+	}
+      else
+	{
+	  if (!m_caloResolutionMassCombination3D)
+	    {
+	      ATH_MSG_FATAL("Mass combination 3D histogram with calo factors was not filled.  Please check your mass combination file: " << JMSFile);
+	      return StatusCode::FAILURE;
+	    }
+	  else if (!m_taResolutionMassCombination3D)
+	    {
+	      ATH_MSG_FATAL("Mass combination 3D histogram with trk-assisted factors was not filled.  Please check your mass combination file: " << JMSFile);
+	      return StatusCode::FAILURE;
+	    }
+	}
+    } //m_onlyCombination   
+   
     ATH_MSG_INFO("JMS Tool has been initialized with mass combination weights from: " << file_combination_Name);
-  }
+
+  }//m_combination
 
   // Determine the binning strategy
   // History is to use pt_mass_eta, with many past config files that don't specify
@@ -547,260 +550,314 @@ StatusCode JMSCorrection::calibrateImpl(xAOD::Jet& jet, JetEventInfo&) const {
 
   xAOD::JetFourMom_t calibP4 = jet.jetP4();
 
-  // For combination
-  float mass_ta;     // saving calibrated trk-assisted mass
-
   float mass_corr = jetStartP4.mass();
   double pT_corr = jetStartP4.pt();
 
-  // Determine mass eta bin to use (if using 2D histograms)
-  int etabin=-99;
-  if (!m_use3Dhisto && (m_massEtaBins.size()==0 || m_respFactorsMass.size() != m_massEtaBins.size()-1)){
-    ATH_MSG_FATAL("Please check that the mass correction eta binning is properly set in your config file");
-    return StatusCode::FAILURE;
-  }
-  else if (m_use3Dhisto && !m_respFactorMass3D)
-  {
-    ATH_MSG_FATAL("Please check that the mass correction 3D histogram is provided");
-    return StatusCode::FAILURE;
-  }
+  TLorentzVector caloCalibJet;
+  float mass_ta = 0;
 
-  // Originally was jet.getConstituents().size() > 1
-  // This essentially requires that the jet has a mass
-  // However, constituents are not stored now in rel21 (LCOrigTopoClusters are transient)
-  // Thus, getConstituents() breaks unless they are specifically written out
-  // Instead, this has been changed to require a non-zero mass
-  // Done by S. Schramm on Oct 21, 2017
+  if(!m_onlyCombination){
+    // Determine mass eta bin to use (if using 2D histograms)
+    int etabin=-99;
+    if (!m_use3Dhisto && (m_massEtaBins.size()==0 || m_respFactorsMass.size() != m_massEtaBins.size()-1)){
+      ATH_MSG_FATAL("Please check that the mass correction eta binning is properly set in your config file");
+      return StatusCode::FAILURE;
+    }
+    else if (m_use3Dhisto && !m_respFactorMass3D)
+      {
+	ATH_MSG_FATAL("Please check that the mass correction 3D histogram is provided");
+	return StatusCode::FAILURE;
+      }
 
-  if ( ( ( !m_use3Dhisto && absdetectorEta < m_massEtaBins.back() ) ||
-         (  m_use3Dhisto && absdetectorEta < m_respFactorMass3D->GetZaxis()->GetBinLowEdge(m_respFactorMass3D->GetNbinsZ()+1))
-       ) && jetStartP4.mass() != 0 ) { // Fiducial cuts
-    if (!m_use3Dhisto)
-    {
-        for (uint i=0; i<m_massEtaBins.size()-1; ++i) {
+    // Originally was jet.getConstituents().size() > 1
+    // This essentially requires that the jet has a mass
+    // However, constituents are not stored now in rel21 (LCOrigTopoClusters are transient)
+    // Thus, getConstituents() breaks unless they are specifically written out
+    // Instead, this has been changed to require a non-zero mass
+    // Done by S. Schramm on Oct 21, 2017
+    
+    if ( ( ( !m_use3Dhisto && absdetectorEta < m_massEtaBins.back() ) ||
+	   (  m_use3Dhisto && absdetectorEta < m_respFactorMass3D->GetZaxis()->GetBinLowEdge(m_respFactorMass3D->GetNbinsZ()+1))
+	   ) && jetStartP4.mass() != 0 ) { // Fiducial cuts
+      if (!m_use3Dhisto)
+	{
+	  for (uint i=0; i<m_massEtaBins.size()-1; ++i) {
             if(absdetectorEta >= m_massEtaBins[i] && absdetectorEta < m_massEtaBins[i+1]) etabin = i;
-        }
-        if (etabin< 0){
-          ATH_MSG_FATAL("There was a problem determining the eta bin to use for the mass correction");
-          return StatusCode::FAILURE;
-        }
-    }
+	  }
+	  if (etabin< 0){
+	    ATH_MSG_FATAL("There was a problem determining the eta bin to use for the mass correction");
+	    return StatusCode::FAILURE;
+	  }
+	}
     
-    // Use the correct histogram binning parametrisation when reading the corrected mass
-    double massFactor = 1;
-    switch (m_binParam)
-    {
-      case BinningParam::pt_mass_eta:
-        if (m_use3Dhisto)
+      // Use the correct histogram binning parametrisation when reading the corrected mass
+      double massFactor = 1;
+      switch (m_binParam)
+	{
+	case BinningParam::pt_mass_eta:
+	  if (m_use3Dhisto)
             massFactor = getMassCorr3D( jetStartP4.pt()/m_GeV, jetStartP4.mass()/m_GeV, absdetectorEta );
-        else
+	  else
             massFactor = getMassCorr( jetStartP4.pt()/m_GeV, jetStartP4.mass()/m_GeV, etabin );
-        break;
-      case BinningParam::e_LOGmOe_eta:
-        if (m_use3Dhisto)
+	  break;
+	case BinningParam::e_LOGmOe_eta:
+	  if (m_use3Dhisto)
             massFactor = getMassCorr3D( jetStartP4.e()/m_GeV, log(jetStartP4.mass() / jetStartP4.e()), absdetectorEta);
-        else
+	  else
             massFactor = getMassCorr( jetStartP4.e()/m_GeV, log(jetStartP4.mass() / jetStartP4.e()), etabin);
-        break;
-      case BinningParam::e_LOGmOet_eta:
-        if (m_use3Dhisto)
+	  break;
+	case BinningParam::e_LOGmOet_eta:
+	  if (m_use3Dhisto)
             massFactor = getMassCorr3D( jetStartP4.e()/m_GeV, log(jetStartP4.mass() / jetStartP4.Et()), absdetectorEta);
-        else
+	  else
             massFactor = getMassCorr( jetStartP4.e()/m_GeV, log(jetStartP4.mass() / jetStartP4.Et()), etabin);
-        break;
-      case BinningParam::e_LOGmOpt_eta:
-        if (m_use3Dhisto)
+	  break;
+	case BinningParam::e_LOGmOpt_eta:
+	  if (m_use3Dhisto)
             massFactor = getMassCorr3D( jetStartP4.e()/m_GeV, log(jetStartP4.mass() / jetStartP4.pt()), absdetectorEta);
-        else
+	  else
             massFactor = getMassCorr( jetStartP4.e()/m_GeV, log(jetStartP4.mass() / jetStartP4.pt()), etabin);
-        break;
-      case BinningParam::et_LOGmOet_eta:
-        if (m_use3Dhisto)
+	  break;
+	case BinningParam::et_LOGmOet_eta:
+	  if (m_use3Dhisto)
             massFactor = getMassCorr3D( jetStartP4.Et()/m_GeV, log(jetStartP4.mass() / jetStartP4.Et()), absdetectorEta);
-        else
+	  else
             massFactor = getMassCorr( jetStartP4.Et()/m_GeV, log(jetStartP4.mass() / jetStartP4.Et()), etabin);
-        break;
-      default:
-        ATH_MSG_FATAL("This should never be reached - if it happens, it's because a new BinningParam enum option was added, but how to handle it for the calo mass was not.  Please contact the tool developer(s) to fix this.");
-        return StatusCode::FAILURE;
-        break;
+	  break;
+	default:
+	  ATH_MSG_FATAL("This should never be reached - if it happens, it's because a new BinningParam enum option was added, but how to handle it for the calo mass was not.  Please contact the tool developer(s) to fix this.");
+	  return StatusCode::FAILURE;
+	  break;
+	}
+
+      mass_corr = jetStartP4.mass() / massFactor;
+    
+      if(!m_pTfixed) pT_corr = sqrt(jetStartP4.e()*jetStartP4.e()-mass_corr*mass_corr)/cosh( jetStartP4.eta() );
     }
 
-    mass_corr = jetStartP4.mass() / massFactor;
+    TLorentzVector caloCalibJet;
+    caloCalibJet.SetPtEtaPhiM(pT_corr, jetStartP4.eta(), jetStartP4.phi(), mass_corr);
     
-    if(!m_pTfixed) pT_corr = sqrt(jetStartP4.e()*jetStartP4.e()-mass_corr*mass_corr)/cosh( jetStartP4.eta() );
-  }
-
-  TLorentzVector caloCalibJet;
-  caloCalibJet.SetPtEtaPhiM(pT_corr, jetStartP4.eta(), jetStartP4.phi(), mass_corr);
-  
-  if(!m_combination){
-    calibP4.SetPxPyPzE( caloCalibJet.Px(), caloCalibJet.Py(), caloCalibJet.Pz(), caloCalibJet.E() );
+    if(!m_combination){
+      calibP4.SetPxPyPzE( caloCalibJet.Px(), caloCalibJet.Py(), caloCalibJet.Pz(), caloCalibJet.E() );
   
-    //Transfer calibrated jet properties to the Jet object
-    jet.setAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentum",calibP4);
-    jet.setJetP4( calibP4 );
-  }
-
-  // Track Assisted Mass Correction
-  if(m_trackAssistedJetMassCorr || m_combination ){
-
-    double E_corr = jetStartP4.e();
-
-    // Determine mass eta bin to use
-    if (!m_use3Dhisto)
-    {
-      etabin=-99;
-      if (m_massEtaBins.size()==0 || m_respFactorsTrackAssistedMass.size() != m_massEtaBins.size()-1){
-        ATH_MSG_FATAL("Please check that the mass correction eta binning is properly set in your config file");
-        if(m_combination) return StatusCode::FAILURE;
-      }
-    }
-    else if (m_use3Dhisto && !m_respFactorTrackAssistedMass3D)
-    {
-      ATH_MSG_FATAL("Please check that the track assisted mass correction 3D histogram is provided");
-      return StatusCode::FAILURE;
+      //Transfer calibrated jet properties to the Jet object
+      jet.setAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentum",calibP4);
+      jet.setJetP4( calibP4 );
     }
 
-    float trackSumMass;
-    std::string TrackSumMassStr = "TrackSumMass";
-    if(m_jetAlgo=="AntiKt4EMTopo" || m_jetAlgo=="AntiKt4LCTopo") TrackSumMassStr = "DFCommonJets_TrackSumMass";
-    std::string TrackSumPtStr = "TrackSumPt";
-    if(m_jetAlgo=="AntiKt4EMTopo" || m_jetAlgo=="AntiKt4LCTopo") TrackSumPtStr = "DFCommonJets_TrackSumPt";
-    if( !jet.getAttribute<float>(TrackSumMassStr,trackSumMass) ) {
-      if(!m_combination){
-        //ATH_MSG_WARNING("Failed to retrieve TrackSumMass! Track Assisted Mass Correction will NOT be applied\n\n");
-        if(m_warning_counter_mTACorr==0) ATH_MSG_WARNING("Failed to retrieve TrackSumMass! Track Assisted Mass Correction will NOT be applied");
-        m_warning_counter_mTACorr++;
-        return StatusCode::SUCCESS;
-      } else{
-        ATH_MSG_FATAL("Failed to retrieve TrackSumMass! Mass Combination can NOT be performed. Aborting.");
-	return StatusCode::FAILURE;
+    // Track Assisted Mass Correction
+    if(m_trackAssistedJetMassCorr || m_combination){
+
+      double E_corr = jetStartP4.e();
+      
+      // Determine mass eta bin to use
+      if (!m_use3Dhisto)
+	{
+	  etabin=-99;
+	  if (m_massEtaBins.size()==0 || m_respFactorsTrackAssistedMass.size() != m_massEtaBins.size()-1){
+	    ATH_MSG_FATAL("Please check that the mass correction eta binning is properly set in your config file");
+	    if(m_combination) return StatusCode::FAILURE;
+	  }
+	}
+      else if (m_use3Dhisto && !m_respFactorTrackAssistedMass3D)
+	{
+	  ATH_MSG_FATAL("Please check that the track assisted mass correction 3D histogram is provided");
+	  return StatusCode::FAILURE;
+	}
+
+      float trackSumMass;
+      std::string TrackSumMassStr = "TrackSumMass";
+      if(m_jetAlgo=="AntiKt4EMTopo" || m_jetAlgo=="AntiKt4LCTopo") TrackSumMassStr = "DFCommonJets_TrackSumMass";
+      std::string TrackSumPtStr = "TrackSumPt";
+      if(m_jetAlgo=="AntiKt4EMTopo" || m_jetAlgo=="AntiKt4LCTopo") TrackSumPtStr = "DFCommonJets_TrackSumPt";
+      if( !jet.getAttribute<float>(TrackSumMassStr,trackSumMass) ) {
+	if(!m_combination){
+	  //ATH_MSG_WARNING("Failed to retrieve TrackSumMass! Track Assisted Mass Correction will NOT be applied\n\n");
+	  if(m_warning_counter_mTACorr==0) ATH_MSG_WARNING("Failed to retrieve TrackSumMass! Track Assisted Mass Correction will NOT be applied");
+	  m_warning_counter_mTACorr++;
+	  return StatusCode::SUCCESS;
+	} else{
+	  ATH_MSG_FATAL("Failed to retrieve TrackSumMass! Mass Combination can NOT be performed. Aborting.");
+	  return StatusCode::FAILURE;
+	}
       }
-    }
-    float trackSumPt;
-    if( !jet.getAttribute<float>(TrackSumPtStr,trackSumPt) ) {
-      if(!m_combination){
-        //ATH_MSG_WARNING("Failed to retrieve TrackSumPt! Track Assisted Mass Correction will NOT be applied\n\n");
-        if(m_warning_counter_mTACorr==0) ATH_MSG_WARNING("Failed to retrieve TrackSumPt! Track Assisted Mass Correction will NOT be applied");
-        m_warning_counter_mTACorr++;
-        return StatusCode::SUCCESS;
-      } else{
-        ATH_MSG_FATAL("Failed to retrieve TrackSumPt! Mass Combination can NOT be performed. Aborting.");
-	return StatusCode::FAILURE;
+      float trackSumPt;
+      if( !jet.getAttribute<float>(TrackSumPtStr,trackSumPt) ) {
+	if(!m_combination){
+	  //ATH_MSG_WARNING("Failed to retrieve TrackSumPt! Track Assisted Mass Correction will NOT be applied\n\n");
+	  if(m_warning_counter_mTACorr==0) ATH_MSG_WARNING("Failed to retrieve TrackSumPt! Track Assisted Mass Correction will NOT be applied");
+	  m_warning_counter_mTACorr++;
+	  return StatusCode::SUCCESS;
+	} else{
+	  ATH_MSG_FATAL("Failed to retrieve TrackSumPt! Mass Combination can NOT be performed. Aborting.");
+	  return StatusCode::FAILURE;
+	}
       }
-    }
-    pT_corr = jetStartP4.pt();
-    float mTA;
-    if(trackSumPt==0) mTA = 0;
-    else{mTA = (jetStartP4.pt()/trackSumPt)*trackSumMass;}
-    if(mTA<0) mTA = 0;
-    mass_corr = mTA;
-    
-    if ( ( ( !m_use3Dhisto && absdetectorEta < m_massEtaBins.back() ) ||
-           (  m_use3Dhisto && absdetectorEta < m_respFactorMass3D->GetZaxis()->GetBinLowEdge(m_respFactorMass3D->GetNbinsZ()+1))
-         ) && jetStartP4.mass() != 0 ) { // Fiducial cuts
-      if (!m_use3Dhisto)
-      {
-          for (uint i=0; i<m_massEtaBins.size()-1; ++i) {
+      pT_corr = jetStartP4.pt();
+      float mTA;
+      if(trackSumPt==0) mTA = 0;
+      else{mTA = (jetStartP4.pt()/trackSumPt)*trackSumMass;}
+      if(mTA<0) mTA = 0;
+      mass_corr = mTA;
+      
+      if ( ( ( !m_use3Dhisto && absdetectorEta < m_massEtaBins.back() ) ||
+	     (  m_use3Dhisto && absdetectorEta < m_respFactorMass3D->GetZaxis()->GetBinLowEdge(m_respFactorMass3D->GetNbinsZ()+1))
+	     ) && jetStartP4.mass() != 0 ) { // Fiducial cuts
+	if (!m_use3Dhisto)
+	  {
+	    for (uint i=0; i<m_massEtaBins.size()-1; ++i) {
               if(absdetectorEta >= m_massEtaBins[i] && absdetectorEta < m_massEtaBins[i+1]) etabin = i;
-          }
-          if (etabin< 0){
-            ATH_MSG_FATAL("There was a problem determining the eta bin to use for the track assisted mass correction");
-            return StatusCode::FAILURE;
-          }
-      }
+	    }
+	    if (etabin< 0){
+	      ATH_MSG_FATAL("There was a problem determining the eta bin to use for the track assisted mass correction");
+	      return StatusCode::FAILURE;
+	    }
+	  }
       
-      double mTAFactor = 1;
-
-      if(mTA!=0){ // Read the calibration values from histograms only when this value is non-zero
-        // Use the correct histogram binning parametrisation when reading the corrected mass
-        switch (m_binParam)
-        {
-          case BinningParam::pt_mass_eta:
-            if (m_use3Dhisto)
-              mTAFactor = getTrackAssistedMassCorr3D( jetStartP4.pt()/m_GeV, mTA/m_GeV, absdetectorEta );
-            else
-              mTAFactor = getTrackAssistedMassCorr( jetStartP4.pt()/m_GeV, mTA/m_GeV, etabin );
-            break;
-          case BinningParam::e_LOGmOe_eta:
-            if (m_use3Dhisto)
-              mTAFactor = getTrackAssistedMassCorr3D( jetStartP4.e()/m_GeV, log(mTA / jetStartP4.e()), absdetectorEta);
-            else
-              mTAFactor = getTrackAssistedMassCorr( jetStartP4.e()/m_GeV, log(mTA / jetStartP4.e()), etabin);
-            break;
-          case BinningParam::e_LOGmOet_eta:
-            if (m_use3Dhisto)
-              mTAFactor = getTrackAssistedMassCorr3D( jetStartP4.e()/m_GeV, log(mTA / jetStartP4.Et()), absdetectorEta);
-            else
-              mTAFactor = getTrackAssistedMassCorr( jetStartP4.e()/m_GeV, log(mTA / jetStartP4.Et()), etabin);
-            break;
-          case BinningParam::e_LOGmOpt_eta:
-            if (m_use3Dhisto)
-              mTAFactor = getTrackAssistedMassCorr3D( jetStartP4.e()/m_GeV, log(mTA / jetStartP4.pt()), absdetectorEta);
-            else
-              mTAFactor = getTrackAssistedMassCorr( jetStartP4.e()/m_GeV, log(mTA / jetStartP4.pt()), etabin);
-            break;
-          case BinningParam::et_LOGmOet_eta:
-            if (m_use3Dhisto)
-              mTAFactor = getTrackAssistedMassCorr3D( jetStartP4.Et()/m_GeV, log(mTA / jetStartP4.Et()), absdetectorEta);
-            else
-              mTAFactor = getTrackAssistedMassCorr( jetStartP4.Et()/m_GeV, log(mTA / jetStartP4.Et()), etabin);
-            break;
-          default:
-            ATH_MSG_FATAL("This should never be reached - if it happens, it's because a new BinningParam enum option was added, but how to handle it for the TA mass was not.  Please contact the tool developer(s) to fix this.");
-            return StatusCode::FAILURE;
-            break;
-        }  
+	double mTAFactor = 1;
+
+	if(mTA!=0){ // Read the calibration values from histograms only when this value is non-zero
+	  // Use the correct histogram binning parametrisation when reading the corrected mass
+	  switch (m_binParam)
+	    {
+	    case BinningParam::pt_mass_eta:
+	      if (m_use3Dhisto)
+		mTAFactor = getTrackAssistedMassCorr3D( jetStartP4.pt()/m_GeV, mTA/m_GeV, absdetectorEta );
+	      else
+		mTAFactor = getTrackAssistedMassCorr( jetStartP4.pt()/m_GeV, mTA/m_GeV, etabin );
+	      break;
+	    case BinningParam::e_LOGmOe_eta:
+	      if (m_use3Dhisto)
+		mTAFactor = getTrackAssistedMassCorr3D( jetStartP4.e()/m_GeV, log(mTA / jetStartP4.e()), absdetectorEta);
+	      else
+		mTAFactor = getTrackAssistedMassCorr( jetStartP4.e()/m_GeV, log(mTA / jetStartP4.e()), etabin);
+	      break;
+	    case BinningParam::e_LOGmOet_eta:
+	      if (m_use3Dhisto)
+		mTAFactor = getTrackAssistedMassCorr3D( jetStartP4.e()/m_GeV, log(mTA / jetStartP4.Et()), absdetectorEta);
+	      else
+		mTAFactor = getTrackAssistedMassCorr( jetStartP4.e()/m_GeV, log(mTA / jetStartP4.Et()), etabin);
+	      break;
+	    case BinningParam::e_LOGmOpt_eta:
+	      if (m_use3Dhisto)
+		mTAFactor = getTrackAssistedMassCorr3D( jetStartP4.e()/m_GeV, log(mTA / jetStartP4.pt()), absdetectorEta);
+	      else
+		mTAFactor = getTrackAssistedMassCorr( jetStartP4.e()/m_GeV, log(mTA / jetStartP4.pt()), etabin);
+	      break;
+	    case BinningParam::et_LOGmOet_eta:
+	      if (m_use3Dhisto)
+		mTAFactor = getTrackAssistedMassCorr3D( jetStartP4.Et()/m_GeV, log(mTA / jetStartP4.Et()), absdetectorEta);
+	      else
+		mTAFactor = getTrackAssistedMassCorr( jetStartP4.Et()/m_GeV, log(mTA / jetStartP4.Et()), etabin);
+	      break;
+	    default:
+	      ATH_MSG_FATAL("This should never be reached - if it happens, it's because a new BinningParam enum option was added, but how to handle it for the TA mass was not.  Please contact the tool developer(s) to fix this.");
+	      return StatusCode::FAILURE;
+	      break;
+	    }  
+	}
+
+	if(mTAFactor!=0) mass_corr = mTA/mTAFactor;
+	else{
+	  ATH_MSG_FATAL("The calibration histogram may have a bad filling bin that is causing mTAFactor to be zero. This value should be different from zero in order to take the ratio. Please contact the tool developer to fix this since the calibration histogram may be corrupted. ");
+	  return StatusCode::FAILURE;
+	}
+	
+	if(!m_pTfixed) pT_corr = sqrt(jetStartP4.e()*jetStartP4.e()-mass_corr*mass_corr)/cosh( jetStartP4.eta() );
+	else{E_corr  = sqrt(jetStartP4.P()*jetStartP4.P()+mass_corr*mass_corr);}
       }
-
-      if(mTAFactor!=0) mass_corr = mTA/mTAFactor;
       else{
-        ATH_MSG_FATAL("The calibration histogram may have a bad filling bin that is causing mTAFactor to be zero. This value should be different from zero in order to take the ratio. Please contact the tool developer to fix this since the calibration histogram may be corrupted. ");
-        return StatusCode::FAILURE;
+	mTA       = 0;
+	mass_corr = 0;
+	if(!m_pTfixed) pT_corr = jetStartP4.e()/cosh( jetStartP4.eta() );
+	else{E_corr = jetStartP4.P();}
       }
 
-      if(!m_pTfixed) pT_corr = sqrt(jetStartP4.e()*jetStartP4.e()-mass_corr*mass_corr)/cosh( jetStartP4.eta() );
-      else{E_corr  = sqrt(jetStartP4.P()*jetStartP4.P()+mass_corr*mass_corr);}
-    }
-    else{
-      mTA       = 0;
-      mass_corr = 0;
-      if(!m_pTfixed) pT_corr = jetStartP4.e()/cosh( jetStartP4.eta() );
-      else{E_corr = jetStartP4.P();}
-    }
-
-    // For combination
-    mass_ta = mass_corr;
-
-    if(!m_combination){
+      TLorentzVector TACalibJet;
+      xAOD::JetFourMom_t TACalibJet_pTfixed = jet.jetP4();
+      if(!m_pTfixed){
+	TACalibJet.SetPtEtaPhiM(pT_corr, jetStartP4.eta(), jetStartP4.phi(), mass_corr);
+      }else{
+	TACalibJet_pTfixed.SetPxPyPzE( jetStartP4.Px(), jetStartP4.Py(), jetStartP4.Pz(), E_corr );}
+      
       //Transfer calibrated track assisted mass property to the Jet object
       jet.setAttribute<float>("JetTrackAssistedMassUnCalibrated",mTA);
       jet.setAttribute<float>("JetTrackAssistedMassCalibrated",mass_corr);
       if(!m_pTfixed) jet.setAttribute<float>("JetpTCorrByCalibratedTAMass",pT_corr);
       else{jet.setAttribute<float>("JetECorrByCalibratedTAMass",E_corr);}
-    }
 
-    if(m_combination){
-    
-      //Transfer calibrated track assisted mass property to the Jet object
+      //float mass_ta;
+      mass_ta = mass_corr;
+
+      // Store calo and TA calibrated jets separetely to further apply insitu:
+      //Transfer calibrated calo mass property to the Jet object
+      xAOD::JetFourMom_t calibP4_calo = jet.jetP4();
+      calibP4_calo.SetCoordinates( caloCalibJet.Pt(), jetStartP4.eta(), jetStartP4.phi(), caloCalibJet.M() );
+      jet.setAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumCalo",calibP4_calo);
+      
+      //Transfer calibrated TA mass property to the Jet object
       xAOD::JetFourMom_t calibP4_ta = jet.jetP4();
-      TLorentzVector TLVjet_ta;
-      TLVjet_ta.SetPtEtaPhiM( pT_corr, jetStartP4.eta(), jetStartP4.phi(), mass_corr );
-      calibP4_ta.SetPxPyPzE( TLVjet_ta.Px(), TLVjet_ta.Py(), TLVjet_ta.Pz(), TLVjet_ta.E() );
+      if(!m_pTfixed){
+	calibP4_ta.SetCoordinates( TACalibJet.Pt(), jetStartP4.eta(), jetStartP4.phi(), TACalibJet.M() );
+      }else{
+	calibP4_ta.SetPxPyPzE( TACalibJet_pTfixed.Px(), TACalibJet_pTfixed.Py(), TACalibJet_pTfixed.Pz(), TACalibJet_pTfixed.E() );}
       jet.setAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumTA",calibP4_ta);
+    } //m_trackAssistedJetMassCorr  
+  } //!m_onlyCombination
 
-      float  mass_comb  = caloCalibJet.M();  // combined mass
-      double pT_comb = caloCalibJet.Pt();
-
-      // if one of the mass is null, use the other one
-      if( (mass_comb==0) || (mass_corr==0) ) { 
-        mass_comb = mass_corr+mass_comb;
+  if(m_combination){
+    float  mass_calo;  
+    float  Mass_comb = 0.;
+    double pT_calo;
+    double E_calo;
+    double Et_calo;
+  
+    if(m_onlyCombination){ 
+      // Read input values (calo and TA insitu calibrated jets) for combination:
+ 
+      xAOD::JetFourMom_t jetInsituP4_calo;
+      xAOD::JetFourMom_t calibP4Insitu_calo;
+      if(jet.getAttribute<xAOD::JetFourMom_t>("JetInsituScaleMomentumCalo",jetInsituP4_calo)){
+	calibP4Insitu_calo=jetInsituP4_calo;
+      }else{
+	ATH_MSG_FATAL( "Cannot retrieve JetInsituScaleMomentumCalo jets" );
+	return StatusCode::FAILURE;
       }
-      else {
-        // Determine mass combination eta bin to use
-        int etabin=-99;
-        if (!m_use3Dhisto)
+      TLorentzVector TLVCaloInsituCalib;
+      TLVCaloInsituCalib.SetPtEtaPhiM(calibP4Insitu_calo.pt(), calibP4Insitu_calo.eta(), calibP4Insitu_calo.phi(), calibP4Insitu_calo.mass());
+      mass_calo  = TLVCaloInsituCalib.M();  
+      pT_calo = TLVCaloInsituCalib.Pt();
+      E_calo = TLVCaloInsituCalib.E();
+      Et_calo = TLVCaloInsituCalib.Et();
+      
+      xAOD::JetFourMom_t jetInsituP4_ta;
+      xAOD::JetFourMom_t calibP4Insitu_ta;
+      if(jet.getAttribute<xAOD::JetFourMom_t>("JetInsituScaleMomentumTA",jetInsituP4_ta)){
+	calibP4Insitu_ta=jetInsituP4_ta;
+      }else{
+	ATH_MSG_FATAL( "Cannot retrieve JetInsituScaleMomentumTA jets" );
+	return StatusCode::FAILURE;
+      }
+      TLorentzVector TLVTAInsituCalib;
+      TLVTAInsituCalib.SetPtEtaPhiM(calibP4Insitu_ta.pt(), calibP4Insitu_ta.eta(), calibP4Insitu_ta.phi(), calibP4Insitu_ta.mass());
+      mass_ta = TLVTAInsituCalib.M();
+    }else{
+      mass_calo = caloCalibJet.M();  // combined mass
+      pT_calo = caloCalibJet.Pt();
+      E_calo = caloCalibJet.E();
+      Et_calo = caloCalibJet.Et();
+      // mass_ta already defined above 
+    }
+
+    // if one of the mass is null, use the other one
+    if( (mass_calo==0) || (mass_ta==0) ) { 
+      Mass_comb = mass_ta+mass_calo;
+    }
+    else {
+      // Determine mass combination eta bin to use
+      int etabin=-99;
+      if (!m_use3Dhisto)
         {
           if (m_massCombinationEtaBins.size()==0 || m_caloResolutionMassCombination.size() != m_massCombinationEtaBins.size()-1){
 	    ATH_MSG_FATAL("Please check that the mass combination eta binning is properly set in your config file");
@@ -811,23 +868,21 @@ StatusCode JMSCorrection::calibrateImpl(xAOD::Jet& jet, JetEventInfo&) const {
 	    return StatusCode::FAILURE;
 	  }
         }
-        else if (m_use3Dhisto && !m_caloResolutionMassCombination3D)
+      else if (m_use3Dhisto && !m_caloResolutionMassCombination3D)
         {
           ATH_MSG_FATAL("Please check that the mass resolution 3D histogram is provided");
           return StatusCode::FAILURE;
         }
-        else if (m_use3Dhisto && !m_taResolutionMassCombination3D)
+      else if (m_use3Dhisto && !m_taResolutionMassCombination3D)
         {
           ATH_MSG_FATAL("Please check that the track assisted mass resolution 3D histogram is provided");
           return StatusCode::FAILURE;
         }
-
-    
     
-        if ( ( ( !m_use3Dhisto && absdetectorEta < m_massCombinationEtaBins.back() ) ||
-               (  m_use3Dhisto && absdetectorEta < m_caloResolutionMassCombination3D->GetZaxis()->GetBinLowEdge(m_caloResolutionMassCombination3D->GetNbinsZ()+1)) ) ) {
-
-          if (!m_use3Dhisto)
+      if ( ( ( !m_use3Dhisto && absdetectorEta < m_massCombinationEtaBins.back() ) ||
+	     (  m_use3Dhisto && absdetectorEta < m_caloResolutionMassCombination3D->GetZaxis()->GetBinLowEdge(m_caloResolutionMassCombination3D->GetNbinsZ()+1)) ) ) {
+	
+	if (!m_use3Dhisto)
           {
             for (uint i=0; i<m_massCombinationEtaBins.size()-1; ++i) {
               if(absdetectorEta >= m_massCombinationEtaBins[i] && absdetectorEta < m_massCombinationEtaBins[i+1]) etabin = i;
@@ -838,130 +893,129 @@ StatusCode JMSCorrection::calibrateImpl(xAOD::Jet& jet, JetEventInfo&) const {
 	    }
           }
 
-          
-          // Use the correct histogram binning parametrisation when reading the combined mass weights
-          double relCalo = 0;
-          double relTA = 0;
-          double rho = 0;
-          switch (m_binParam)
+	// Use the correct histogram binning parametrisation when reading the combined mass weights
+	double relCalo = 0;
+	double relTA = 0;
+	double rho = 0;
+	switch (m_binParam)
           {
-            case BinningParam::pt_mass_eta:
-              if (m_use3Dhisto)
+	  case BinningParam::pt_mass_eta:
+	    if (m_use3Dhisto)
               {
-                relCalo = getRelCalo3D( caloCalibJet.Pt()/m_GeV, caloCalibJet.M()/caloCalibJet.Pt(), absdetectorEta );
-                relTA   = getRelTA3D(   caloCalibJet.Pt()/m_GeV, mass_ta         /caloCalibJet.Pt(), absdetectorEta );
+                relCalo = getRelCalo3D( pT_calo/m_GeV, mass_calo/pT_calo, absdetectorEta );
+                relTA   = getRelTA3D( pT_calo/m_GeV, mass_ta/pT_calo, absdetectorEta );
                 if (m_useCorrelatedWeights)
-                    rho = getRho3D(     caloCalibJet.Pt()/m_GeV, caloCalibJet.M()/caloCalibJet.Pt(), absdetectorEta );
+		  rho = getRho3D( pT_calo/m_GeV, mass_calo/pT_calo, absdetectorEta );
               }
-              else
+	    else
               {
-                relCalo = getRelCalo(   caloCalibJet.Pt()/m_GeV, caloCalibJet.M()/caloCalibJet.Pt(), etabin );
-                relTA   = getRelTA(     caloCalibJet.Pt()/m_GeV, mass_ta         /caloCalibJet.Pt(), etabin );
+                relCalo = getRelCalo( pT_calo/m_GeV, mass_calo/pT_calo, etabin );
+                relTA   = getRelTA( pT_calo/m_GeV, mass_ta/pT_calo, etabin );
                 if (m_useCorrelatedWeights)
-                    rho = getRho(       caloCalibJet.Pt()/m_GeV, caloCalibJet.M()/caloCalibJet.Pt(), etabin );
+		  rho = getRho( pT_calo/m_GeV, mass_calo/pT_calo, etabin );
               }
-              break;
-            case BinningParam::e_LOGmOe_eta:
-              if (m_use3Dhisto)
+	    break;
+	  case BinningParam::e_LOGmOe_eta:
+	    if (m_use3Dhisto)
               {
-                relCalo = getRelCalo3D( caloCalibJet.E()/m_GeV, log(caloCalibJet.M()/caloCalibJet.E()), absdetectorEta );
-                relTA   = getRelTA3D(   caloCalibJet.E()/m_GeV, log(mass_ta         /caloCalibJet.E()), absdetectorEta );
+                relCalo = getRelCalo3D( E_calo/m_GeV, log(mass_calo/E_calo), absdetectorEta );
+                relTA   = getRelTA3D( E_calo/m_GeV, log(mass_ta/E_calo), absdetectorEta );
                 if (m_useCorrelatedWeights)
-                    rho = getRho3D(     caloCalibJet.E()/m_GeV, log(caloCalibJet.M()/caloCalibJet.E()), absdetectorEta );
+		  rho = getRho3D( E_calo/m_GeV, log(mass_calo/E_calo), absdetectorEta );
               }
-              else
+	    else
               {
-                relCalo = getRelCalo(   caloCalibJet.E()/m_GeV, log(caloCalibJet.M()/caloCalibJet.E()), etabin );
-                relTA   = getRelTA(     caloCalibJet.E()/m_GeV, log(mass_ta         /caloCalibJet.E()), etabin );
+                relCalo = getRelCalo( E_calo/m_GeV, log(mass_calo/E_calo), etabin );
+                relTA   = getRelTA( E_calo/m_GeV, log(mass_ta/E_calo), etabin );
                 if (m_useCorrelatedWeights)
-                    rho = getRho(       caloCalibJet.E()/m_GeV, log(caloCalibJet.M()/caloCalibJet.E()), etabin );
+		  rho = getRho( E_calo/m_GeV, log(mass_calo/E_calo), etabin );
               }
-              break;
-            case BinningParam::e_LOGmOet_eta:
-              if (m_use3Dhisto)
+	    break;
+	  case BinningParam::e_LOGmOet_eta:
+	    if (m_use3Dhisto)
               {
-                relCalo = getRelCalo3D( caloCalibJet.E()/m_GeV, log(caloCalibJet.M()/caloCalibJet.Et()), absdetectorEta );
-                relTA   = getRelTA3D(   caloCalibJet.E()/m_GeV, log(mass_ta         /caloCalibJet.Et()), absdetectorEta );
+                relCalo = getRelCalo3D( E_calo/m_GeV, log(mass_calo/Et_calo), absdetectorEta );
+                relTA   = getRelTA3D( E_calo/m_GeV, log(mass_ta/Et_calo), absdetectorEta );
                 if (m_useCorrelatedWeights)
-                    rho = getRho3D(     caloCalibJet.E()/m_GeV, log(caloCalibJet.M()/caloCalibJet.Et()), absdetectorEta );
+		  rho = getRho3D( E_calo/m_GeV, log(mass_calo/Et_calo), absdetectorEta );
               }
-              else
+	    else
               {
-                relCalo = getRelCalo(   caloCalibJet.E()/m_GeV, log(caloCalibJet.M()/caloCalibJet.Et()), etabin );
-                relTA   = getRelTA(     caloCalibJet.E()/m_GeV, log(mass_ta         /caloCalibJet.Et()), etabin );
+                relCalo = getRelCalo( E_calo/m_GeV, log(mass_calo/Et_calo), etabin );
+                relTA   = getRelTA( E_calo/m_GeV, log(mass_ta/Et_calo), etabin );
                 if (m_useCorrelatedWeights)
-                    rho = getRho(       caloCalibJet.E()/m_GeV, log(caloCalibJet.M()/caloCalibJet.Et()), etabin );
+		  rho = getRho( E_calo/m_GeV, log(mass_calo/Et_calo), etabin );
               }
-              break;
-            case BinningParam::e_LOGmOpt_eta:
-              if (m_use3Dhisto)
+	    break;
+	  case BinningParam::e_LOGmOpt_eta:
+	    if (m_use3Dhisto)
               {
-                relCalo = getRelCalo3D( caloCalibJet.E()/m_GeV, log(caloCalibJet.M()/caloCalibJet.Pt()), absdetectorEta );
-                relTA   = getRelTA3D(   caloCalibJet.E()/m_GeV, log(mass_ta         /caloCalibJet.Pt()), absdetectorEta );
+                relCalo = getRelCalo3D( E_calo/m_GeV, log(mass_calo/pT_calo), absdetectorEta );
+                relTA   = getRelTA3D( E_calo/m_GeV, log(mass_ta/pT_calo), absdetectorEta );
                 if (m_useCorrelatedWeights)
-                    rho = getRho3D(     caloCalibJet.E()/m_GeV, log(caloCalibJet.M()/caloCalibJet.Pt()), absdetectorEta );
+		  rho = getRho3D( E_calo/m_GeV, log(mass_calo/pT_calo), absdetectorEta );
               }
-              else
+	    else
               {
-                relCalo = getRelCalo(   caloCalibJet.E()/m_GeV, log(caloCalibJet.M()/caloCalibJet.Pt()), etabin );
-                relTA   = getRelTA(     caloCalibJet.E()/m_GeV, log(mass_ta         /caloCalibJet.Pt()), etabin );
+                relCalo = getRelCalo( E_calo/m_GeV, log(mass_calo/pT_calo), etabin );
+                relTA   = getRelTA( E_calo/m_GeV, log(mass_ta/pT_calo), etabin );
                 if (m_useCorrelatedWeights)
-                    rho = getRho(       caloCalibJet.E()/m_GeV, log(caloCalibJet.M()/caloCalibJet.Pt()), etabin );
+		  rho = getRho( E_calo/m_GeV, log(mass_calo/pT_calo), etabin );
               }
-              break;
-            case BinningParam::et_LOGmOet_eta:
-              if (m_use3Dhisto)
+	    break;
+	  case BinningParam::et_LOGmOet_eta:
+	    if (m_use3Dhisto)
               {
-                relCalo = getRelCalo3D( caloCalibJet.Et()/m_GeV, log(caloCalibJet.M()/caloCalibJet.Et()), absdetectorEta );
-                relTA   = getRelTA3D(   caloCalibJet.Et()/m_GeV, log(mass_ta         /caloCalibJet.Et()), absdetectorEta );
+                relCalo = getRelCalo3D( Et_calo/m_GeV, log(mass_calo/Et_calo), absdetectorEta );
+                relTA   = getRelTA3D( Et_calo/m_GeV, log(mass_ta/Et_calo), absdetectorEta );
                 if (m_useCorrelatedWeights)
-                    rho = getRho3D(     caloCalibJet.Et()/m_GeV, log(caloCalibJet.M()/caloCalibJet.Et()), absdetectorEta );
+		  rho = getRho3D( Et_calo/m_GeV, log(mass_calo/Et_calo), absdetectorEta );
               }
-              else
+	    else
               {
-                relCalo = getRelCalo(   caloCalibJet.Et()/m_GeV, log(caloCalibJet.M()/caloCalibJet.Et()), etabin );
-                relTA   = getRelTA(     caloCalibJet.Et()/m_GeV, log(mass_ta         /caloCalibJet.Et()), etabin );
+                relCalo = getRelCalo( Et_calo/m_GeV, log(mass_calo/Et_calo), etabin );
+                relTA   = getRelTA( Et_calo/m_GeV, log(mass_ta/Et_calo), etabin );
                 if (m_useCorrelatedWeights)
-                    rho = getRho(       caloCalibJet.Et()/m_GeV, log(caloCalibJet.M()/caloCalibJet.Et()), etabin );
+		  rho = getRho( Et_calo/m_GeV, log(mass_calo/Et_calo), etabin );
               }
-              break;
-            default:
-              ATH_MSG_FATAL("This should never be reached - if it happens, it's because a new BinningParam enum option was added, but how to handle it for the TA mass was not.  Please contact the tool developer(s) to fix this.");
-              return StatusCode::FAILURE;
-              break;
+	    break;
+	  default:
+	    ATH_MSG_FATAL("This should never be reached - if it happens, it's because a new BinningParam enum option was added, but how to handle it for the TA mass was not.  Please contact the tool developer(s) to fix this.");
+	    return StatusCode::FAILURE;
+	    break;
           }
-
-
           
-          // Watch for division by zero
-          if(m_useCorrelatedWeights && (relCalo*relCalo + relTA*relTA - 2 * rho* relCalo * relTA == 0)){
-            ATH_MSG_ERROR("Encountered division by zero when calculating mass combination weight using correlated weights");
-            return StatusCode::FAILURE;
-          }
-	  const double Weight = ( relTA*relTA - rho *relCalo*relTA ) / ( relCalo*relCalo + relTA*relTA - 2 * rho* relCalo * relTA );
-  	  mass_comb =  ( caloCalibJet.M() * Weight ) + ( mass_ta * ( 1 - Weight) );
-	  // Protection
-	  if(mass_comb>jetStartP4.e()) mass_comb = caloCalibJet.M();
-	  else if(!m_pTfixed) pT_comb = sqrt(jetStartP4.e()*jetStartP4.e()-mass_comb*mass_comb)/cosh( jetStartP4.eta() );
-        }
+	// Watch for division by zero
+	if(m_useCorrelatedWeights && (relCalo*relCalo + relTA*relTA - 2 * rho* relCalo * relTA == 0)){
+	  ATH_MSG_ERROR("Encountered division by zero when calculating mass combination weight using correlated weights");
+	  return StatusCode::FAILURE;
+	}
+	const double Weight = ( relTA*relTA - rho *relCalo*relTA ) / ( relCalo*relCalo + relTA*relTA - 2 * rho* relCalo * relTA );
+
+	// Zero should be only returned by resolution functions if jet mass is negative
+	if(relCalo == 0 && relTA == 0)
+	  Mass_comb = 0;
+	else if(relCalo == 0)
+	  Mass_comb = mass_ta;
+	else if(relTA == 0)
+	  Mass_comb = mass_calo;
+	else
+	  Mass_comb =  ( mass_calo * Weight ) + ( mass_ta * ( 1 - Weight) );
+	// Protection
+	if(Mass_comb>jetStartP4.e()) Mass_comb = mass_calo;
+	else if(!m_pTfixed) pT_calo = sqrt(jetStartP4.e()*jetStartP4.e()-mass_calo*mass_calo)/cosh( jetStartP4.eta() );
       }
-
-
-      TLorentzVector TLVjet;
-      TLVjet.SetPtEtaPhiM( pT_comb, jetStartP4.eta(), jetStartP4.phi(), mass_comb );
-      calibP4.SetPxPyPzE( TLVjet.Px(), TLVjet.Py(), TLVjet.Pz(), TLVjet.E() );
+    }
   
-      //Transfer calibrated jet properties to the Jet object
-      jet.setAttribute<xAOD::JetFourMom_t>(m_jetOutScale.Data(),calibP4);
-      jet.setJetP4( calibP4 );
-
-      //Transfer calibrated calo mass property to the Jet object
-      xAOD::JetFourMom_t calibP4_calo = jet.jetP4();
-      calibP4_calo.SetCoordinates( caloCalibJet.Pt(), jetStartP4.eta(), jetStartP4.phi(), caloCalibJet.M() );
-      jet.setAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumCalo",calibP4_calo);
+    TLorentzVector TLVjet;
+    TLVjet.SetPtEtaPhiM( pT_calo, jetStartP4.eta(), jetStartP4.phi(), Mass_comb );
+    calibP4.SetPxPyPzE( TLVjet.Px(), TLVjet.Py(), TLVjet.Pz(), TLVjet.E() );
+  
+    //Transfer calibrated jet properties to the Jet object
+    jet.setAttribute<xAOD::JetFourMom_t>(m_jetOutScale.Data(),calibP4);
+    jet.setJetP4( calibP4 );
 
-    }
-  }
+  } //m_combination
 
   return StatusCode::SUCCESS;
 
diff --git a/Reconstruction/Jet/JetCalibTools/Root/JetCalibrationTool.cxx b/Reconstruction/Jet/JetCalibTools/Root/JetCalibrationTool.cxx
index 0fd60ef6b9f8237daab1c9c927901b513fdae429..3b96f6fba078a0440872480644531be874794ce1 100644
--- a/Reconstruction/Jet/JetCalibTools/Root/JetCalibrationTool.cxx
+++ b/Reconstruction/Jet/JetCalibTools/Root/JetCalibrationTool.cxx
@@ -24,7 +24,8 @@ JetCalibrationTool::JetCalibrationTool(const std::string& name)
     m_rhkRhoKey(""),
     m_jetAlgo(""), m_config(""), m_calibSeq(""), m_calibAreaTag(""), m_originScale(""), m_devMode(false), m_isData(true), m_timeDependentCalib(false), m_rhoKey("auto"), m_dir(""), m_eInfoName(""), m_globalConfig(NULL),
     m_doJetArea(true), m_doResidual(true), m_doOrigin(true), m_doGSC(true), m_gscDepth("auto"),
-    m_jetPileupCorr(NULL), m_etaJESCorr(NULL), m_globalSequentialCorr(NULL), m_insituDataCorr(NULL), m_jetMassCorr(NULL), m_jetSmearCorr(NULL)
+    m_jetPileupCorr(NULL), m_etaJESCorr(NULL), m_globalSequentialCorr(NULL), m_insituDataCorr(NULL), 
+    m_jetMassCorr(NULL), m_jetSmearCorr(NULL), m_insituCombMassCorr_tmp(NULL)
 { 
 
   declareProperty( "JetCollection", m_jetAlgo = "AntiKt4LCTopo" );
@@ -54,6 +55,7 @@ JetCalibrationTool::~JetCalibrationTool() {
   if (m_insituDataCorr) delete m_insituDataCorr;
   if (m_jetMassCorr) delete m_jetMassCorr;
   if (m_jetSmearCorr) delete m_jetSmearCorr;
+  if (m_insituCombMassCorr_tmp) delete m_insituCombMassCorr_tmp;
 
 }
 
@@ -215,6 +217,26 @@ StatusCode JetCalibrationTool::initializeTool(const std::string& name) {
     }
   }
 
+  //Combined Mass Calibration:
+  m_insituCombMassCalib = m_globalConfig->GetValue("InsituCombinedMassCorrection",false);
+  if(m_insituCombMassCalib && calibSeq.Contains("InsituCombinedMass")){ // Read Combination Config
+    m_insituCombMassConfig = JetCalibUtils::Vectorize( m_globalConfig->GetValue("InsituCombinedMassCorrectionFile","") );
+    if(m_insituCombMassConfig.size()==0) ATH_MSG_ERROR("Please check there is a combination config");
+    for(unsigned int i=0;i<m_insituCombMassConfig.size();++i){
+
+      std::string configPath_comb = dir+m_insituCombMassConfig.at(i).Data(); // Full path
+      TString fn_comb =  PathResolverFindCalibFile(configPath_comb);
+
+      ATH_MSG_INFO("Reading combination settings from: " << m_insituCombMassConfig.at(i));
+      ATH_MSG_INFO("resolved in: " << fn_comb);
+
+      TEnv *globalInsituCombMass = new TEnv();
+      int status = globalInsituCombMass->ReadFile(fn_comb ,EEnvLevel(0));
+      if (status!=0) { ATH_MSG_FATAL("Cannot read config file " << fn_comb ); return StatusCode::FAILURE; }
+      m_globalInsituCombMassConfig.push_back(globalInsituCombMass);
+    }
+  }
+
   //Loop over the request calib sequence
   //Initialize derived classes for applying the requested calibrations and add them to a vector
   std::vector<TString> vecCalibSeq = JetCalibUtils::Vectorize(calibSeq,"_");
@@ -303,6 +325,21 @@ StatusCode JetCalibrationTool::getCalibClass(const std::string&name, TString cal
       m_calibClasses.push_back(m_jetMassCorr);
       return StatusCode::SUCCESS;
     }
+  } else if ( calibration.EqualTo("InsituCombinedMass") ){
+    ATH_MSG_INFO("Initializing Combined Mass Correction");
+    for(unsigned int i=0;i<m_insituCombMassConfig.size();++i){
+      suffix="_InsituCombinedMass"; suffix += "_"; suffix += std::to_string(i);
+      if(m_devMode) suffix+="_DEV";
+      m_insituCombMassCorr_tmp = new JMSCorrection(name+suffix,m_globalInsituCombMassConfig.at(i),jetAlgo,calibPath,m_devMode);
+      m_insituCombMassCorr_tmp->msg().setLevel( this->msg().level() );
+      if ( m_insituCombMassCorr_tmp->initializeTool(name+suffix).isFailure() ) {
+	ATH_MSG_FATAL("Couldn't initialize the Combined Mass correction. Aborting");
+	return StatusCode::FAILURE;
+      } else {
+	m_insituCombMassCorr.push_back(m_insituCombMassCorr_tmp);
+	return StatusCode::SUCCESS;
+      }
+    }
   } else if ( calibration.EqualTo("Insitu") ) {
     if(!m_timeDependentCalib){
       ATH_MSG_INFO("Initializing Insitu correction.");
@@ -576,6 +613,17 @@ StatusCode JetCalibrationTool::calibrateImpl(xAOD::Jet& jet, JetEventInfo& jetEv
       if(runNumber>m_runBins.at(i) && runNumber<=m_runBins.at(i+1)){ ATH_CHECK ( m_insituTimeDependentCorr.at(i)->calibrateImpl(jet,jetEventInfo) );}
     }
   }
+  if(CalibSeq.Contains("InsituCombinedMass") && m_insituCombMassCalib){
+    for(unsigned int i=0;i<m_insituCombMassConfig.size();++i){
+      //Retrive EventInfo container
+      const xAOD::EventInfo* eventInfo(nullptr);
+      if( evtStore()->retrieve(eventInfo,"EventInfo").isFailure() || !eventInfo ) {
+	ATH_MSG_ERROR("   JetCalibrationTool::calibrateImpl : Failed to retrieve EventInfo.");
+      }
+      ATH_CHECK ( m_insituCombMassCorr.at(i)->calibrateImpl(jet,jetEventInfo) );
+    }
+  }
+
   return StatusCode::SUCCESS; 
 }
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedStacoTagTool.h b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedStacoTagTool.h
index b8737f738a3cb6da98946cb456010276ff8ff745..91226ebe17c8cea7366eb5ff2a648bc44cfa7ca3 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedStacoTagTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedStacoTagTool.h
@@ -46,7 +46,7 @@ namespace MuonCombined {
     std::unique_ptr<const Trk::Perigee> theCombIdMu( const Trk::Perigee& indetPerigee, const Trk::Perigee& extrPerigee, double& chi2 ) const;
 
     ToolHandle<Muon::MuonEDMPrinterTool>        m_printer {this, "Printer", "Muon::MuonEDMPrinterTool/MuonEDMPrinterTool"};
-    ToolHandle<MuonCombined::IMuonTrackTagTool> m_tagTool {this, "TagTool", "MuonCombined::MuonTrackTagTestTool/MuonTrackTagTestTool"};
+    ToolHandle<MuonCombined::IMuonTrackTagTool> m_tagTool {this, "TagTool", ""}; //tool needs to be set up explicitly
     ToolHandle<Trk::IExtrapolator>              m_extrapolator {this, "Extrapolator", "Trk::Extrapolator/AtlasExtrapolator"};
     ToolHandle<Trk::IParticleCaloExtensionTool> m_caloExtTool {this, "ParticleCaloExtensionTool", "Trk::ParticleCaloExtensionTool/ParticleCaloExtensionTool"};
   };
diff --git a/Reconstruction/MuonIdentification/MuonCombinedConfig/CMakeLists.txt b/Reconstruction/MuonIdentification/MuonCombinedConfig/CMakeLists.txt
index 7548372a73ef414e3d604da811cd5943fd816c00..32337eb98891359e6f5dacd63801c93c93315ed3 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedConfig/CMakeLists.txt
+++ b/Reconstruction/MuonIdentification/MuonCombinedConfig/CMakeLists.txt
@@ -10,5 +10,5 @@ atlas_install_python_modules( python/*.py  )
 
 atlas_add_test( MuonCombinedRecoConfigTest
 SCRIPT python -m MuonCombinedConfig.MuonCombinedReconstructionConfig --run --threads=1
-PROPERTIES TIMEOUT 300
+PROPERTIES TIMEOUT 900
 POST_EXEC_SCRIPT nopost.sh )
diff --git a/Reconstruction/MuonIdentification/MuonCombinedConfig/python/MuonCombinedRecToolsConfig.py b/Reconstruction/MuonIdentification/MuonCombinedConfig/python/MuonCombinedRecToolsConfig.py
index 4514e9ae42e8fb2e036735e259253613388e3492..9100e16297406fb4e5441dee78cbc933caedc0da 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedConfig/python/MuonCombinedRecToolsConfig.py
+++ b/Reconstruction/MuonIdentification/MuonCombinedConfig/python/MuonCombinedRecToolsConfig.py
@@ -362,6 +362,9 @@ def MuonCombinedStacoTagToolCfg(flags, name="MuonCombinedStacoTagTool",**kwargs)
     result = ParticleCaloExtensionToolCfg(flags)
     kwargs.setdefault("ParticleCaloExtensionTool", result.getPrimary() )  
     kwargs.setdefault("Printer", MuonEDMPrinterTool(flags) )
+    acc = CombinedMuonTagTestToolCfg(flags)
+    kwargs.setdefault("TagTool", acc.popPrivateTools())
+    result.merge(acc)
     tool = CompFactory.MuonCombined.MuonCombinedStacoTagTool(name,**kwargs)
     result.setPrivateTools(tool)
     return result 
@@ -378,6 +381,13 @@ def MuidMaterialAllocatorCfg(flags, name='MuidMaterialAllocator', **kwargs):
     acc  = TrackingGeometrySvcCfg(flags)
     kwargs.setdefault("TrackingGeometrySvc", acc.getPrimary() )
     result.merge(acc)
+
+    from InDetRecExample.TrackingCommon import use_tracking_geometry_cond_alg
+    if use_tracking_geometry_cond_alg:
+      from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlgConfig import TrackingGeometryCondAlgCfg
+      result.merge( TrackingGeometryCondAlgCfg(flags) )
+      kwargs.setdefault("TrackingGeometryReadKey", "AtlasTrackingGeometry")
+
     tool = CompFactory.Trk.MaterialAllocator(name,**kwargs)
     result.setPrivateTools(tool)
     return result 
@@ -540,6 +550,11 @@ def MuonTrackQueryCfg(flags, name="MuonTrackQuery", **kwargs ):
     from MuonConfig.MuonRIO_OnTrackCreatorConfig import MdtDriftCircleOnTrackCreatorCfg
     result = MdtDriftCircleOnTrackCreatorCfg(flags)
     kwargs.setdefault("MdtRotCreator",   result.popPrivateTools() )
+    from InDetRecExample.TrackingCommon import use_tracking_geometry_cond_alg
+    if use_tracking_geometry_cond_alg:
+      from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlgConfig import TrackingGeometryCondAlgCfg
+      result.merge( TrackingGeometryCondAlgCfg(flags) )
+      kwargs.setdefault("TrackingGeometryReadKey", "AtlasTrackingGeometry")
 
     acc = iPatFitterCfg(flags)
     kwargs.setdefault("Fitter", acc.popPrivateTools() )
@@ -797,6 +812,11 @@ def CombinedMuonTagTestToolCfg(flags, name='CombinedMuonTagTestTool', **kwargs )
     kwargs.setdefault("TrackingGeometrySvc", acc.getPrimary() )
     result.merge(acc)
     kwargs.setdefault("Chi2Cut",50000.)
+    from InDetRecExample.TrackingCommon import use_tracking_geometry_cond_alg
+    if use_tracking_geometry_cond_alg:
+      from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlgConfig import TrackingGeometryCondAlgCfg
+      result.merge( TrackingGeometryCondAlgCfg(flags) )
+      kwargs.setdefault("TrackingGeometryReadKey", "AtlasTrackingGeometry")
     tool = CompFactory.MuonCombined.MuonTrackTagTestTool(name,**kwargs)
     result.setPrivateTools(tool)
     return result
diff --git a/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedFitTools.py b/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedFitTools.py
index 89a1822e686fa18b4f401a0bff56900208cfc752..9f1255b6b3050b3bd4a76d1fc0875554ad83fc46 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedFitTools.py
+++ b/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedFitTools.py
@@ -37,6 +37,16 @@ def MuidMaterialAllocator( name='MuidMaterialAllocator', **kwargs):
     kwargs.setdefault("AllowReordering",False)
     kwargs.setdefault("Extrapolator", getPublicTool('AtlasExtrapolator') )
     kwargs.setdefault("TrackingGeometrySvc", getService("AtlasTrackingGeometrySvc") )
+
+    from InDetRecExample.TrackingCommon import use_tracking_geometry_cond_alg
+    if use_tracking_geometry_cond_alg:
+      from AthenaCommon.AlgSequence import AthSequencer
+      condSeq = AthSequencer("AthCondSeq")
+      if not getattr (condSeq, 'AtlasTrackingGeometryCondAlg', None):
+        from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlg import ConfiguredTrackingGeometryCondAlg
+        condSeq += ConfiguredTrackingGeometryCondAlg()
+      kwargs.setdefault("TrackingGeometryReadKey",'AtlasTrackingGeometry')
+
     return CfgMgr.Trk__MaterialAllocator(name,**kwargs)
 
 # and the fitter
@@ -175,6 +185,15 @@ def MuonCombinedPropagator( name='MuonCombinedPropagator', **kwargs ):
 
 
 def MuonTrackQuery( name="MuonTrackQuery", **kwargs ):
+     from InDetRecExample.TrackingCommon import use_tracking_geometry_cond_alg
+     if use_tracking_geometry_cond_alg:
+       from AthenaCommon.AlgSequence import AthSequencer
+       condSeq = AthSequencer("AthCondSeq")
+       if not getattr (condSeq, 'AtlasTrackingGeometryCondAlg', None):
+         from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlg import ConfiguredTrackingGeometryCondAlg
+         condSeq += ConfiguredTrackingGeometryCondAlg()
+       kwargs.setdefault("TrackingGeometryReadKey", "AtlasTrackingGeometry")
+
      kwargs.setdefault("MdtRotCreator",   getPublicTool("MdtDriftCircleOnTrackCreator") )
      kwargs.setdefault("Fitter", getPublicTool("iPatFitter"))
      return CfgMgr.Rec__MuonTrackQuery(name,**kwargs)
@@ -426,5 +445,13 @@ def CombinedMuonTagTestTool( name='CombinedMuonTagTestTool', **kwargs ):
     kwargs.setdefault("ExtrapolatorTool",getPublicTool("AtlasExtrapolator") )
     kwargs.setdefault("TrackingGeometrySvc",  getService("AtlasTrackingGeometrySvc") )
     kwargs.setdefault("Chi2Cut",50000.)
+    from InDetRecExample.TrackingCommon import use_tracking_geometry_cond_alg
+    if use_tracking_geometry_cond_alg:
+      from AthenaCommon.AlgSequence import AthSequencer
+      condSeq = AthSequencer("AthCondSeq")
+      if not getattr (condSeq, 'AtlasTrackingGeometryCondAlg', None):
+        from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlg import ConfiguredTrackingGeometryCondAlg
+        condSeq += ConfiguredTrackingGeometryCondAlg()
+      kwargs.setdefault("TrackingGeometryReadKey", "AtlasTrackingGeometry")
     return CfgMgr.MuonCombined__MuonTrackTagTestTool(name,**kwargs)
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedTools.py b/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedTools.py
index 77ea848d032ebe2b887cf893103639b009419e9c..5d97c178d38350ac00de6774712ab3ab4c7292ca 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedTools.py
+++ b/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedTools.py
@@ -163,6 +163,8 @@ def MuonCombinedFitTagTool(name="MuonCombinedFitTagTool",**kwargs):
 
 def MuonCombinedStacoTagTool(name="MuonCombinedStacoTagTool",**kwargs):
     kwargs.setdefault("ParticleCaloExtensionTool",  getPublicTool("MuonParticleCaloExtensionTool") )
+    from MuonCombinedRecExample.MuonCombinedFitTools import CombinedMuonTagTestTool
+    kwargs.setdefault("TagTool", CombinedMuonTagTestTool())
 
     return CfgMgr.MuonCombined__MuonCombinedStacoTagTool(name,**kwargs)
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedTestTools/src/MuonTrackTagTestTool.cxx b/Reconstruction/MuonIdentification/MuonCombinedTestTools/src/MuonTrackTagTestTool.cxx
index dfcc26be88e293727610536d33a70e50ab0bfe47..7f7fa9b31f998dd808714b8d8db5a7996f2896ce 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedTestTools/src/MuonTrackTagTestTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedTestTools/src/MuonTrackTagTestTool.cxx
@@ -39,12 +39,13 @@ StatusCode
 MuonTrackTagTestTool::initialize()
 {
     ATH_CHECK(m_extrapolator.retrieve());
-    if (m_trackingGeometryReadKey.key().empty()) {
+    if (m_trackingGeometryReadKey.empty()) {
         ATH_CHECK(m_trackingGeometrySvc.retrieve());
         ATH_MSG_INFO( "  geometry Svc " << m_trackingGeometrySvc << " retrieved ");
     } else{
         ATH_CHECK(m_trackingGeometryReadKey.initialize());
-    }   
+    }
+    
 
     ATH_MSG_INFO( "Initialized successfully");
 
diff --git a/Reconstruction/MuonIdentification/MuonSegmentTaggers/MuonSegmentTaggerTools/CMakeLists.txt b/Reconstruction/MuonIdentification/MuonSegmentTaggers/MuonSegmentTaggerTools/CMakeLists.txt
index a1e8f46a908ac9db822a45d9eaf1899ea2d52426..5b3a5b33db94255282326160941301cc0f7bd96f 100644
--- a/Reconstruction/MuonIdentification/MuonSegmentTaggers/MuonSegmentTaggerTools/CMakeLists.txt
+++ b/Reconstruction/MuonIdentification/MuonSegmentTaggers/MuonSegmentTaggerTools/CMakeLists.txt
@@ -9,7 +9,7 @@ atlas_subdir( MuonSegmentTaggerTools )
 atlas_add_library( MuonSegmentTaggerToolsLib
                    src/*.cxx
                    NO_PUBLIC_HEADERS
-                   LINK_LIBRARIES GaudiKernel StoreGateLib SGtests MuonIdHelpersLib MuonRecHelperToolsLib
+                   LINK_LIBRARIES GaudiKernel StoreGateLib SGtests MuonIdHelpersLib MuonRecHelperToolsLib TrkDetDescrInterfaces
                    PRIVATE_LINK_LIBRARIES AthenaBaseComps Identifier EventPrimitives MuonReadoutGeometry MuonRIO_OnTrack MuonSegment MuonSegmentMakerUtils MuonCombinedEvent TrkGeometry TrkSurfaces TrkCompetingRIOsOnTrack TrkEventPrimitives TrkParameters TrkSegment TrkTrack TrkExInterfaces TrkToolInterfaces MuonSegmentTaggerToolInterfaces )
 
 atlas_add_component( MuonSegmentTaggerTools
diff --git a/Reconstruction/MuonIdentification/MuonSegmentTaggers/MuonSegmentTaggerTools/src/MuTagMatchingTool.cxx b/Reconstruction/MuonIdentification/MuonSegmentTaggers/MuonSegmentTaggerTools/src/MuTagMatchingTool.cxx
index 690f3b0b5df8a575c56bf713a6ec7702f6cc4e1c..7b491c8135b7765835c5d45db6f33a8b9325f17b 100644
--- a/Reconstruction/MuonIdentification/MuonSegmentTaggers/MuonSegmentTaggerTools/src/MuTagMatchingTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonSegmentTaggers/MuonSegmentTaggerTools/src/MuTagMatchingTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "MuTagMatchingTool.h"
@@ -25,26 +25,6 @@
 #include "TrkSurfaces/Surface.h"
 #include "TrkTrack/Track.h"
 
-namespace {
-// local helper functions
-#if 0
-  /** Limit deltaPhi between -pi < dPhi <= +pi */
-  inline double limit_deltaPhi(double deltaPhi) {
-    while (deltaPhi >  +M_PI) deltaPhi -= 2.*M_PI;
-    while (deltaPhi <= -M_PI) deltaPhi += 2.*M_PI;
-    return deltaPhi;
-  }
-
-  /** Limit deltaTheta between -pi/2 < dPhi <= +pi/2 */
-  inline double limit_deltaTheta(double deltaTheta) {
-    while (deltaTheta >  +M_PI/2.) deltaTheta -= M_PI;
-    while (deltaTheta <= -M_PI/2.) deltaTheta += M_PI;
-    return deltaTheta;
-  }
-#endif
-
-}  // namespace
-
 
 MuTagMatchingTool::MuTagMatchingTool(const std::string& t, const std::string& n, const IInterface* p)
     : AthAlgTool(t, n, p)
@@ -129,6 +109,13 @@ MuTagMatchingTool::initialize()
     ATH_CHECK(m_printer.retrieve());
     ATH_CHECK(m_pullCalculator.retrieve());
 
+    if (!m_trackingGeometryReadKey.empty()) {
+        ATH_CHECK(m_trackingGeometryReadKey.initialize());
+    } else {
+        ATH_CHECK(m_trackingGeometrySvc.retrieve());
+    }
+
+    
     return StatusCode::SUCCESS;
 }
 
@@ -230,31 +217,16 @@ MuTagMatchingTool::surfaceMatch(const Trk::TrackParameters* atSurface, const Muo
 const Trk::TrackParameters*
 MuTagMatchingTool::ExtrapolateTrktoMSEntrance(const Trk::Track* pTrack, Trk::PropDirection direction) const
 {
-    if (pTrack == 0) return 0;
-
-    StatusCode sc;
-
-    const Trk::TrackingGeometry* trackingGeometry = 0;
-
-
-    sc = detStore()->retrieve(trackingGeometry, "AtlasTrackingGeometry");
-    if (sc.isFailure()) {
-        ATH_MSG_FATAL("Could not find tracking geometry. Exiting.");
-        return 0;
-    }
+    if (!pTrack) return nullptr;
 
     const Trk::TrackParameters* exTrk            = nullptr;
-    const Trk::TrackingVolume*  MSEntranceVolume = trackingGeometry->trackingVolume("MuonSpectrometerEntrance");
-
-    //  if( m_extrapolatePerigee ){
-    exTrk =
-        p_IExtrapolator->extrapolateToVolume(*(pTrack->perigeeParameters()), *MSEntranceVolume, direction, Trk::muon);
-    //  } else { // using perigee parameters arbitrarily; to be changed if new extrapolateToVolume is available
-    //    exTrk = p_IExtrapolator->extrapolateToVolume( *( pTrack->trackParameters() ),
-    //						  *MSEntranceVolume,
-    //						  direction,
-    //						  Trk::muon ) ;
-    //  }
+    const Trk::TrackingVolume*  MSEntranceVolume = getVolume("MuonSpectrometerEntrance");
+    if (!MSEntranceVolume){
+        return nullptr;
+    }
+    
+    exTrk = p_IExtrapolator->extrapolateToVolume(*(pTrack->perigeeParameters()), *MSEntranceVolume, direction, Trk::muon);
+   
     if (!exTrk)
         ATH_MSG_DEBUG("Track could not be extrapolated to MS entrance...");
     else
@@ -385,11 +357,9 @@ MuTagMatchingTool::phiMatch(const Trk::TrackParameters* atSurface, const Muon::M
         } else
             ATH_MSG_DEBUG(" track not extrapolated to a disc ");
     }
-
+    if (std::abs(cosphi) > 1.) return false;
     double errPhi = std::hypot(PHI_CUT, sigma_phi);
-
     // if the difference between exTrk and Segment phi position falls within the errPhi, accept as rough match
-    //  if( std::acos(cosphi) < errPhi ) return true;
     if (std::acos(std::abs(cosphi)) < errPhi)
         return true;  // BRes: TEMPORARY - segment direction not sure, so I'm making this match symmetric wrt Pi/2
     //  else ATH_MSG_DEBUG( std::setw(30) << "roughPhi failed:  d_phi = " << std::setw(10) << std::acos(cosphi)
diff --git a/Reconstruction/MuonIdentification/MuonSegmentTaggers/MuonSegmentTaggerTools/src/MuTagMatchingTool.h b/Reconstruction/MuonIdentification/MuonSegmentTaggers/MuonSegmentTaggerTools/src/MuTagMatchingTool.h
index c245a95d62b1f68bdd9ae79853334d0a638ac622..c8fa62430601194df745f317b619d20549c17787 100644
--- a/Reconstruction/MuonIdentification/MuonSegmentTaggers/MuonSegmentTaggerTools/src/MuTagMatchingTool.h
+++ b/Reconstruction/MuonIdentification/MuonSegmentTaggers/MuonSegmentTaggerTools/src/MuTagMatchingTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef MuTagMatchingTool_H
@@ -24,6 +24,8 @@
 #include "TrkGeometry/TrackingGeometry.h"
 #include "TrkParameters/TrackParameters.h"
 #include "TrkToolInterfaces/IResidualPullCalculator.h"
+#include "TrkDetDescrInterfaces/ITrackingGeometrySvc.h"
+#include "TrkGeometry/TrackingGeometry.h"
 
 /**
    @class MuTagMatchingTool
@@ -163,7 +165,11 @@ class MuTagMatchingTool : virtual public IMuTagMatchingTool, public AthAlgTool {
         "MuonDetectorManager",
         "Key of input MuonDetectorManager condition data",
     };
-
+    
+    ServiceHandle<Trk::ITrackingGeometrySvc> m_trackingGeometrySvc { this, "TrackingGeometrySvc", "TrackingGeometrySvc/AtlasTrackingGeometrySvc" };
+    
+    SG::ReadCondHandleKey<Trk::TrackingGeometry> m_trackingGeometryReadKey { this, "TrackingGeometryReadKey", "", "Key of input TrackingGeometry" };
+        
     bool m_assumeLocalErrors;
     bool m_extrapolatePerigee;
 
@@ -190,6 +196,21 @@ class MuTagMatchingTool : virtual public IMuTagMatchingTool, public AthAlgTool {
 
     double m_chamberPullCut;
     double m_combinedPullCut;
+    
+    inline const Trk::TrackingVolume* getVolume(const std::string &vol_name) const {
+        /// Good old way of retrieving the volume via the geometry service
+        if (m_trackingGeometryReadKey.empty()) {
+                return m_trackingGeometrySvc->trackingGeometry()->trackingVolume(vol_name);
+        }
+        SG::ReadCondHandle < Trk::TrackingGeometry > handle(m_trackingGeometryReadKey, Gaudi::Hive::currentContext());
+        if (!handle.isValid()) {
+            ATH_MSG_WARNING("Could not retrieve a valid tracking geometry");
+                return nullptr;
+        }
+        return handle.cptr()->trackingVolume(vol_name);
+    }
+
+
 };
 
 
diff --git a/Reconstruction/RecJobTransforms/python/RecoSteering.py b/Reconstruction/RecJobTransforms/python/RecoSteering.py
index f911cfeed1fef0d7d8fa6c10d85c6f158b09bdf2..42a46413a6537e55a93239b001dc58535e9e1a30 100644
--- a/Reconstruction/RecJobTransforms/python/RecoSteering.py
+++ b/Reconstruction/RecJobTransforms/python/RecoSteering.py
@@ -44,15 +44,12 @@ def RecoSteering(flags):
     # pflow
 
     #setup output
-    # TODO - decide how we collect objects that need recording (the old way was a global & external list)
-    itemsToRecord = ["xAOD::EventInfo#EventInfo"]
-    from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
     if flags.Output.doWriteESD:
-        acc.merge(OutputStreamCfg(flags, "ESD", ItemList=itemsToRecord, disableEventTag=True))
+        log.info("ESD ItemList: %s", acc.getEventAlgo("OutputStreamESD").ItemList)
         log.info("---------- Configured ESD writing")
 
     if flags.Output.doWriteAOD:
-        acc.merge(OutputStreamCfg(flags, "AOD", ItemList=itemsToRecord, disableEventTag=True))
+        log.info("ESD ItemList: %s", acc.getEventAlgo("OutputStreamAOD").ItemList)
         log.info("---------- Configured AOD writing")
 
     return acc
@@ -74,6 +71,8 @@ def _run(input):
     flags.Detector.RecoSCT=True
     flags.Detector.RecoTRT=True
     flags.Calo.TopoCluster.doTopoClusterLocalCalib=False
+    flags.Output.ESDFileName="ESD.pool.root"
+    flags.Output.AODFileName="AOD.pool.root"
     parser = flags.getArgumentParser()
     args = flags.fillFromArgs(parser=parser)
 
@@ -91,7 +90,8 @@ def _run(input):
     acc.merge(RecoSteering(flags), sequenceName="AthAlgSeq")
     confStamp = datetime.datetime.now()
     log.info("configured in %d seconds", (confStamp-startStamp).seconds )
-
+    acc.getService("StoreGateSvc").Dump=True
+    acc.getEventAlgo("TrackParticleCnvAlg").OutputLevel=1
     acc.printConfig(withDetails=True)
     if args.configOnly:
         with open(args.configOnly, "wb") as confFile:
diff --git a/Reconstruction/RecoTools/TrackToCalo/src/PreselCaloExtensionBuilderAlg.cxx b/Reconstruction/RecoTools/TrackToCalo/src/PreselCaloExtensionBuilderAlg.cxx
index 36642822b6263526cbe13db7b3fbef769ee7ecc5..0dd600d6be2c5e82bcac019407be644cf4732352 100644
--- a/Reconstruction/RecoTools/TrackToCalo/src/PreselCaloExtensionBuilderAlg.cxx
+++ b/Reconstruction/RecoTools/TrackToCalo/src/PreselCaloExtensionBuilderAlg.cxx
@@ -41,7 +41,7 @@ namespace Trk {
       if (itrk->index() >= cache->size())
         // Handle the case where the above assumption does not hold
         cache->resize(itrk->index() + 1);
-      cache->at(itrk->index()) = std::move(m_particleCaloExtensionTool->caloExtension(ctx, *itrk));
+      cache->at(itrk->index()) = m_particleCaloExtensionTool->caloExtension(ctx, *itrk);
     }
     auto outputHandle = SG::makeHandle(m_outputCacheKey, ctx);
     ATH_CHECK(outputHandle.record(std::move(cache)));
diff --git a/Reconstruction/eflowRec/CMakeLists.txt b/Reconstruction/eflowRec/CMakeLists.txt
index 5e8c3e5ecc451804d8623b21ebbbe919d31af161..6bfb10d84893bca08ece88d6499b12ec74aff371 100644
--- a/Reconstruction/eflowRec/CMakeLists.txt
+++ b/Reconstruction/eflowRec/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( eflowRec )
@@ -11,7 +11,7 @@ atlas_add_component( eflowRec
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} CaloEvent CaloIdentifier CaloRecLib AthContainers AthLinks AthenaBaseComps CxxUtils AthenaKernel GeoPrimitives Identifier xAODBase xAODCaloEvent xAODCore xAODEgamma xAODMuon xAODPFlow xAODTau xAODTracking GaudiKernel InDetReadoutGeometry TRT_ReadoutGeometry Particle RecoToolInterfaces TrkParameters CaloDetDescrLib CaloUtilsLib StoreGateLib FourMomUtils PathResolver TrkCaloExtension TrkParametersIdentificationHelpers InDetTrackSelectionToolLib AthenaMonitoringKernelLib ICaloTrkMuIdTools)
+                     LINK_LIBRARIES ${ROOT_LIBRARIES} CaloEvent CaloIdentifier CaloRecLib AthContainers AthLinks AthenaBaseComps CxxUtils AthenaKernel GeoPrimitives Identifier xAODBase xAODCaloEvent xAODCore xAODEgamma xAODMuon xAODPFlow xAODTau xAODTracking GaudiKernel InDetReadoutGeometry TRT_ReadoutGeometry Particle RecoToolInterfaces TrkParameters CaloDetDescrLib CaloUtilsLib StoreGateLib FourMomUtils PathResolver TrkCaloExtension TrkParametersIdentificationHelpers InDetTrackSelectionToolLib AthenaMonitoringKernelLib ICaloTrkMuIdTools tauRecToolsLib)
 
 # Install files from the package:
 atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
diff --git a/Reconstruction/eflowRec/src/PFTauFlowElementAssoc.cxx b/Reconstruction/eflowRec/src/PFTauFlowElementAssoc.cxx
index cdd60bc234dee10b815fe4e95485e2d024c0fff8..d23d049840da27369e74024864c2c8f019b74d8c 100644
--- a/Reconstruction/eflowRec/src/PFTauFlowElementAssoc.cxx
+++ b/Reconstruction/eflowRec/src/PFTauFlowElementAssoc.cxx
@@ -1,5 +1,5 @@
 /*
- Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+ Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "eflowRec/PFTauFlowElementAssoc.h"
@@ -7,6 +7,7 @@
 #include "xAODTau/TauTrack.h"
 #include "xAODPFlow/FlowElementContainer.h"
 #include "xAODPFlow/FlowElement.h"
+#include "tauRecTools/HelperFunctions.h"
 
 typedef ElementLink<xAOD::TauJetContainer> TauJetLink_t;
 typedef ElementLink<xAOD::FlowElementContainer> FELink_t;
@@ -72,10 +73,16 @@ StatusCode PFTauFlowElementAssoc::execute(const EventContext &ctx) const {
 
     // Loop over the taus
     for (const xAOD::TauJet* tau : *tauNeutralFEWriteDecorHandle) {
+      // Get tau vertex
+      const xAOD::Vertex* tauVertex = tauRecTools::getTauVertex(*tau);
       // Get the clusters associated to the tau
-      std::vector< ElementLink<xAOD::IParticleContainer> > tauClusters = tau->clusterLinks();
-      for (auto clusLink : tauClusters) {
-        const xAOD::IParticle* clus = *clusLink;
+      std::vector<const xAOD::IParticle*> tauClusters = tau->clusters();
+      for (auto cluster : tauClusters) {
+        const xAOD::CaloCluster* clus = static_cast<const xAOD::CaloCluster*>(cluster);
+        // Correct cluster to tau vertex
+        xAOD::CaloVertexedTopoCluster vertexedClus(*clus, tauVertex->position());
+        // Check if the cluster is within R = 0.2 of tau axis
+        if (vertexedClus.p4().DeltaR(tau->p4(xAOD::TauJetParameters::IntermediateAxis)) > 0.2) continue;
         // Get the index of the cluster associated to the tau
         size_t tauClusterIndex = clus->index();
 
@@ -105,7 +112,7 @@ StatusCode PFTauFlowElementAssoc::execute(const EventContext &ctx) const {
     // Loop over the taus
     for (const xAOD::TauJet* tau : *tauChargedFEWriteDecorHandle) {
       // Get tau tracks associated to the tau
-      std::vector<const xAOD::TauTrack*> tauTracks = tau->tracks(xAOD::TauJetParameters::coreTrack);
+      std::vector<const xAOD::TauTrack*> tauTracks = tau->tracks();
       for (auto tauTrack : tauTracks) {
         // Get track associated to the tau track to use for matching
         const xAOD::TrackParticle* tauIDTrack = tauTrack->track();
diff --git a/Reconstruction/iPat/iPatRecExample/share/iPatRec_jobOptions.py b/Reconstruction/iPat/iPatRecExample/share/iPatRec_jobOptions.py
index 5465f4a2cf49067c0e55f796672d9eee1887f204..dfca0edd8f5d4fd473750eb34a610bef51814296 100755
--- a/Reconstruction/iPat/iPatRecExample/share/iPatRec_jobOptions.py
+++ b/Reconstruction/iPat/iPatRecExample/share/iPatRec_jobOptions.py
@@ -67,6 +67,16 @@ if DetFlags.detdescr.ID_on() and (DetFlags.haveRIO.pixel_on() or DetFlags.haveRI
         #AggregateMaterial         = True,
         Extrapolator              = iPatExtrapolator,
         TrackingGeometrySvc       = ServiceMgr.AtlasTrackingGeometrySvc)
+
+    from InDetRecExample.TrackingCommon import use_tracking_geometry_cond_alg
+    if use_tracking_geometry_cond_alg:
+      from AthenaCommon.AlgSequence import AthSequencer
+      condSeq = AthSequencer("AthCondSeq")
+      if not getattr (condSeq, 'AtlasTrackingGeometryCondAlg', None):
+        from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlg import ConfiguredTrackingGeometryCondAlg
+        condSeq += ConfiguredTrackingGeometryCondAlg()
+      iPatMaterialAllocator.TrackingGeometryReadKey='AtlasTrackingGeometry'
+
     ToolSvc += iPatMaterialAllocator
 
     from TrkiPatFitter.TrkiPatFitterConf import Trk__iPatFitter
diff --git a/Reconstruction/tauRec/python/tauRecFlags.py b/Reconstruction/tauRec/python/tauRecFlags.py
index 68195039e145c2e0948960ace54f4d16fe96b575..50fa8fd26ef5fb1c2327f84767880a4880346ef1 100644
--- a/Reconstruction/tauRec/python/tauRecFlags.py
+++ b/Reconstruction/tauRec/python/tauRecFlags.py
@@ -118,7 +118,7 @@ class tauRecDecayModeNNClassifierConfig(JobProperty):
     """
     statusOn=True
     allowedTypes=['string']
-    StoredValue='NNDecayModeWeights-20200625.json'
+    StoredValue='NNDecayMode_R22_v1.json'
 
 class tauRecCalibrateLCConfig(JobProperty):
     """Config file for TauCalibrateLC
diff --git a/Reconstruction/tauRecTools/Root/TauDecayModeNNClassifier.cxx b/Reconstruction/tauRecTools/Root/TauDecayModeNNClassifier.cxx
index 0abe3c721103ba3fd19b3a1904184698661d29fd..47db6f668bf98892d8012c70ad0e28ea13ae657a 100644
--- a/Reconstruction/tauRecTools/Root/TauDecayModeNNClassifier.cxx
+++ b/Reconstruction/tauRecTools/Root/TauDecayModeNNClassifier.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 // local include(s)
@@ -30,7 +30,7 @@ TauDecayModeNNClassifier::TauDecayModeNNClassifier(const std::string &name)
   declareProperty("OutputName", m_outputName = "NNDecayMode");
   declareProperty("ProbPrefix", m_probPrefix = "NNDecayModeProb_");
   declareProperty("WeightFile", m_weightFile = "");
-  declareProperty("MaxChargedPFOs", m_maxChargedPFOs = 3);
+  declareProperty("MaxTauTracks", m_maxTauTracks = 3);
   declareProperty("MaxNeutralPFOs", m_maxNeutralPFOs = 8);
   declareProperty("MaxShotPFOs", m_maxShotPFOs = 6);
   declareProperty("MaxConvTracks", m_maxConvTracks = 4);
@@ -92,7 +92,7 @@ StatusCode TauDecayModeNNClassifier::execute(xAOD::TauJet &xTau) const
   //
   InputMap inputMapDummy;
   InputSequenceMap inputSeqMap;
-  std::set<std::string> branches = {"ChargedPFO", "NeutralPFO", "ShotPFO", "ConvTrack"};
+  std::set<std::string> branches = {"TauTrack", "NeutralPFO", "ShotPFO", "ConvTrack"};
   DMHelper::initMapKeys(inputSeqMap, branches);
 
   ATH_CHECK(getInputs(xTau, inputSeqMap));
@@ -172,7 +172,7 @@ StatusCode TauDecayModeNNClassifier::finalize()
 
 StatusCode TauDecayModeNNClassifier::getInputs(const xAOD::TauJet &xTau, InputSequenceMap &inputSeqMap) const
 {
-  std::vector<PFOPtr> vChargedPFOs;
+  std::vector<TrkPtr> vTauTracks;
   std::vector<PFOPtr> vNeutralPFOs;
   std::vector<PFOPtr> vShotPFOs;
   std::vector<TrkPtr> vConvTracks;
@@ -180,12 +180,8 @@ StatusCode TauDecayModeNNClassifier::getInputs(const xAOD::TauJet &xTau, InputSe
   // set objects
   // -----------
 
-  // charged PFOs
-  for (std::size_t i = 0; i < xTau.nChargedPFOs(); ++i)
-  {
-    const auto pfo = xTau.chargedPFO(i);
-    vChargedPFOs.push_back(pfo);
-  }
+  // classified tau tracks
+  vTauTracks = xTau.tracks(xAOD::TauJetParameters::TauTrackFlag::classifiedCharged);
 
   // neutral PFOs
   for (std::size_t i = 0; i < xTau.nNeutralPFOs(); ++i)
@@ -217,10 +213,10 @@ StatusCode TauDecayModeNNClassifier::getInputs(const xAOD::TauJet &xTau, InputSe
     vShotPFOs.push_back(pfo);
   }
 
-  // conversion tracks
+  // classified conversion tracks
   vConvTracks = xTau.tracks(xAOD::TauJetParameters::TauTrackFlag::classifiedConversion);
 
-  DMHelper::sortAndKeep<PFOPtr>(vChargedPFOs, m_maxChargedPFOs);
+  DMHelper::sortAndKeep<TrkPtr>(vTauTracks, m_maxTauTracks);
   DMHelper::sortAndKeep<PFOPtr>(vNeutralPFOs, m_maxNeutralPFOs);
   DMHelper::sortAndKeep<PFOPtr>(vShotPFOs, m_maxShotPFOs);
   DMHelper::sortAndKeep<TrkPtr>(vConvTracks, m_maxConvTracks);
@@ -265,6 +261,14 @@ StatusCode TauDecayModeNNClassifier::getInputs(const xAOD::TauJet &xTau, InputSe
     in_seq_map["jetpt_log"].push_back(DMHelper::Log10Robust(tau_p4.Pt()));
   };
 
+  // a function to set the track impact parameter variables
+  auto setTrackIPVars = [](VectorMap &in_seq_map, const TrkPtr &trk) {
+    in_seq_map["d0TJVA"].push_back(trk->d0TJVA());
+    in_seq_map["d0SigTJVA"].push_back(trk->d0SigTJVA());
+    in_seq_map["z0sinthetaTJVA"].push_back(trk->z0sinthetaTJVA());
+    in_seq_map["z0sinthetaSigTJVA"].push_back(trk->z0sinthetaSigTJVA());
+  };
+
   // a function to set the neutral pfo variables
   auto setNeutralPFOVars = [](VectorMap &in_seq_map, const PFOPtr &pfo) {
     // get the attributes of a given PFO object
@@ -280,20 +284,23 @@ StatusCode TauDecayModeNNClassifier::getInputs(const xAOD::TauJet &xTau, InputSe
     in_seq_map["SECOND_ENG_DENS_log"].push_back(DMHelper::Log10Robust(getAttr(PFOAttributes::cellBased_SECOND_ENG_DENS), 1e-6f));
     in_seq_map["NPosECells_EM1"].push_back(getAttrInt(PFOAttributes::cellBased_NPosECells_EM1));
     in_seq_map["NPosECells_EM2"].push_back(getAttrInt(PFOAttributes::cellBased_NPosECells_EM2));
+    in_seq_map["energy_EM1"].push_back(getAttr(PFOAttributes::cellBased_energy_EM1));
+    in_seq_map["energy_EM2"].push_back(getAttr(PFOAttributes::cellBased_energy_EM2));
     in_seq_map["EM1CoreFrac"].push_back(getAttr(PFOAttributes::cellBased_EM1CoreFrac));
     in_seq_map["firstEtaWRTClusterPosition_EM1"].push_back(getAttr(PFOAttributes::cellBased_firstEtaWRTClusterPosition_EM1));
+    in_seq_map["firstEtaWRTClusterPosition_EM2"].push_back(getAttr(PFOAttributes::cellBased_firstEtaWRTClusterPosition_EM2));
     in_seq_map["secondEtaWRTClusterPosition_EM1_log"].push_back(DMHelper::Log10Robust(getAttr(PFOAttributes::cellBased_secondEtaWRTClusterPosition_EM1), 1e-6f));
     in_seq_map["secondEtaWRTClusterPosition_EM2_log"].push_back(DMHelper::Log10Robust(getAttr(PFOAttributes::cellBased_secondEtaWRTClusterPosition_EM2), 1e-6f));
-    in_seq_map["ptSubRatio_logabs"].push_back(DMHelper::Log10Robust(TMath::Abs(DMVar::ptSubRatio(pfo)), 1e-6f));
-    in_seq_map["energyfrac_EM2"].push_back(DMVar::energyFracEM2(pfo, getAttr(PFOAttributes::cellBased_energy_EM2)));
   };
 
-  // set Charged PFOs variables
-  VectorMap &chrg_map = inputSeqMap.at("ChargedPFO");
+  // set tau tracks variables
+  VectorMap &chrg_map = inputSeqMap.at("TauTrack");
   DMHelper::initMapKeys(chrg_map, DMVar::sCommonP4Vars);
-  for (const auto &pfo : vChargedPFOs)
+  DMHelper::initMapKeys(chrg_map, DMVar::sTrackIPVars);
+  for (const auto &trk : vTauTracks)
   {
-    setCommonP4Vars(chrg_map, pfo->p4());
+    setCommonP4Vars(chrg_map, trk->p4());
+    setTrackIPVars(chrg_map, trk);
   }
 
   // set Neutral PFOs variables
@@ -325,9 +332,11 @@ StatusCode TauDecayModeNNClassifier::getInputs(const xAOD::TauJet &xTau, InputSe
   // set Conversion tracks variables
   VectorMap &conv_map = inputSeqMap.at("ConvTrack");
   DMHelper::initMapKeys(conv_map, DMVar::sCommonP4Vars);
+  DMHelper::initMapKeys(conv_map, DMVar::sTrackIPVars);
   for (const auto &trk : vConvTracks)
   {
     setCommonP4Vars(conv_map, trk->p4());
+    setTrackIPVars(conv_map, trk);
   }
 
   return StatusCode::SUCCESS;
@@ -339,10 +348,14 @@ namespace tauRecTools
   const std::set<std::string> TauDecayModeNNVariable::sCommonP4Vars = {
       "dphiECal", "detaECal", "dphi", "deta", "pt_log", "jetpt_log"};
 
+  const std::set<std::string> TauDecayModeNNVariable::sTrackIPVars = {
+      "d0TJVA", "d0SigTJVA", "z0sinthetaTJVA", "z0sinthetaSigTJVA"};
+
   const std::set<std::string> TauDecayModeNNVariable::sNeutralPFOVars = {
       "FIRST_ETA", "SECOND_R_log", "DELTA_THETA", "CENTER_LAMBDA_log", "LONGITUDINAL", "ENG_FRAC_CORE",
-      "SECOND_ENG_DENS_log", "NPosECells_EM1", "NPosECells_EM2", "EM1CoreFrac", "firstEtaWRTClusterPosition_EM1",
-      "secondEtaWRTClusterPosition_EM1_log", "secondEtaWRTClusterPosition_EM2_log", "ptSubRatio_logabs", "energyfrac_EM2"};
+      "SECOND_ENG_DENS_log", "NPosECells_EM1", "NPosECells_EM2", "energy_EM1", "energy_EM2", "EM1CoreFrac", 
+      "firstEtaWRTClusterPosition_EM1", "firstEtaWRTClusterPosition_EM2", 
+      "secondEtaWRTClusterPosition_EM1_log", "secondEtaWRTClusterPosition_EM2_log"};
 
   const std::array<std::string, TauDecayModeNNVariable::nClasses> TauDecayModeNNVariable::sModeNames = {
       "1p0n", "1p1n", "1pXn", "3p0n", "3pXn"};
@@ -375,7 +388,7 @@ namespace tauRecTools
     T val{static_cast<T>(0)};
     if (!pfo->attribute(attr, val))
     {
-      throw std::runtime_error("Can not retrieve PFO attribute!");
+      throw std::runtime_error("Can not retrieve PFO attribute! enum = " + std::to_string(static_cast<unsigned>(attr)));
     }
     return val;
   }
diff --git a/Reconstruction/tauRecTools/tauRecTools/TauDecayModeNNClassifier.h b/Reconstruction/tauRecTools/tauRecTools/TauDecayModeNNClassifier.h
index a83cd9b0be870f48cfc3c1b892f8e26e051b9e8b..ef6e5ede2d7d2acc1821b2206d5b3878098cdd10 100644
--- a/Reconstruction/tauRecTools/tauRecTools/TauDecayModeNNClassifier.h
+++ b/Reconstruction/tauRecTools/tauRecTools/TauDecayModeNNClassifier.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TAURECTOOLS_TAUDECAYMODENNCLASSIFIER_H
@@ -46,7 +46,7 @@ private:
   std::string m_outputName;      //!
   std::string m_probPrefix;      //!
   std::string m_weightFile;      //!
-  std::size_t m_maxChargedPFOs;  //!
+  std::size_t m_maxTauTracks;  //!
   std::size_t m_maxNeutralPFOs;  //!
   std::size_t m_maxShotPFOs;     //!
   std::size_t m_maxConvTracks;   //!
@@ -78,6 +78,7 @@ namespace tauRecTools
     TauDecayModeNNVariable() = delete;
     static const std::size_t nClasses = 5;
     static const std::set<std::string> sCommonP4Vars;
+    static const std::set<std::string> sTrackIPVars;
     static const std::set<std::string> sNeutralPFOVars;
     static const std::array<std::string, nClasses> sModeNames;
     static float deltaPhi(const TLorentzVector &p4, const TLorentzVector &p4_tau);
diff --git a/Simulation/ISF/ISF_Acts/ISF_ActsTools/src/ActsFatrasSimTool.h b/Simulation/ISF/ISF_Acts/ISF_ActsTools/src/ActsFatrasSimTool.h
index 12c5719c7ef76a4cfe556e586b27b3eb237e6474..40b0140d2e913e4aef42be7fd22a2f043790d5ab 100644
--- a/Simulation/ISF/ISF_Acts/ISF_ActsTools/src/ActsFatrasSimTool.h
+++ b/Simulation/ISF/ISF_Acts/ISF_ActsTools/src/ActsFatrasSimTool.h
@@ -108,8 +108,8 @@ class ActsFatrasSimTool : public BaseSimulatorTool {
   virtual StatusCode initialize() override;
   virtual StatusCode simulate(const ISFParticle& isp, ISFParticleContainer&,
                               McEventCollection*) const override;
-  virtual StatusCode setupEvent() { return StatusCode::SUCCESS; };
-  virtual StatusCode releaseEvent() { return StatusCode::SUCCESS; };
+  virtual StatusCode setupEvent() override { return StatusCode::SUCCESS; };
+  virtual StatusCode releaseEvent() override { return StatusCode::SUCCESS; };
   virtual ISF::SimulationFlavor simFlavor() const override { return ISF::Fatras; };
 
   virtual ISF::ISFParticle* process(const ISFParticle& isp) const;
diff --git a/Simulation/ISF/ISF_Tracking/ISF_TrackingTools/src/TrkExtrapolator.h b/Simulation/ISF/ISF_Tracking/ISF_TrackingTools/src/TrkExtrapolator.h
index 64746e722c1d7e3f53734683f91b67a0672e3efc..6bf178ef21d9a6202e0190830c3c47de9f67c90e 100644
--- a/Simulation/ISF/ISF_Tracking/ISF_TrackingTools/src/TrkExtrapolator.h
+++ b/Simulation/ISF/ISF_Tracking/ISF_TrackingTools/src/TrkExtrapolator.h
@@ -61,7 +61,7 @@ namespace ISF {
     private:
 
       /** tracking geometry for geometry signature */
-      SG::ReadCondHandleKey<Trk::TrackingGeometry>      m_trackingGeometryReadKey{this, "TrackingGeometryReadKey", "AlignedTrackingGeometry", "Key of input TrackingGeometry"};  
+      SG::ReadCondHandleKey<Trk::TrackingGeometry>      m_trackingGeometryReadKey{this, "TrackingGeometryReadKey", "AtlasTrackingGeometry", "Key of input TrackingGeometry"};  
 
       /** extrapolation to calo entry */
       ToolHandle<Trk::IExtrapolator>       m_extrapolator;              //!< ToolHandle for track extrapolator
diff --git a/Tools/TrfTestsART/test/test_trf_data18_hybrid.sh b/Tools/TrfTestsART/test/test_trf_data18_hybrid.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c778f65c86eb1f0b906d1b4df544bb18cdded20a
--- /dev/null
+++ b/Tools/TrfTestsART/test/test_trf_data18_hybrid.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# art-description: Reco_tf.py q431 RAWtoALL in hybrid MT/MP mode: nprocs=2, threads=4
+# art-type: grid
+# art-include: master/Athena
+# art-athena-mt: 8
+
+timeout 43200 Reco_tf.py \
+  --inputBSFile=/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/Tier0ChainTests/data18_13TeV.00357750.physics_Main.daq.RAW/data18_13TeV.00357750.physics_Main.daq.RAW._lb0114._SFO-5._0003.data \
+  --outputAODFile=myAOD.pool.root \
+  --outputHISTFile=myHIST.root \
+  --outputDESDM_MCPFile=myDESDM_MCP.pool.root \
+  --outputDRAW_ZMUMUFile=myDRAW_ZMUMU.data \
+  --athenaopts="--nprocs=2 --threads=4" \
+  --preExec 'all:from AthenaMonitoring.DQMonFlags import DQMonFlags; DQMonFlags.doMonitoring=True; DQMonFlags.doNewMonitoring=True' \
+  --postExec 'FPEAuditor.NStacktracesOnFPE=10' \
+  --autoConfiguration='everything' \
+  --conditionsTag 'all:CONDBR2-BLKPA-RUN2-03' --geometryVersion='default:ATLAS-R2-2016-01-00-01' \
+  --runNumber='357750' --steering='doRAWtoALL' --maxEvents='-1'
+
+echo "art-result: $? Reco_tf_data18_hybrid"
diff --git a/Tools/TrfTestsART/test/test_trf_data18_mp.sh b/Tools/TrfTestsART/test/test_trf_data18_mp.sh
index 8b030dd2d4b41ae8478668d8f10ab639d5fd8801..a1ce30c2a482624fd2f6ef6ba931e75759421c79 100755
--- a/Tools/TrfTestsART/test/test_trf_data18_mp.sh
+++ b/Tools/TrfTestsART/test/test_trf_data18_mp.sh
@@ -1,10 +1,11 @@
 #!/bin/bash
 #
-# art-description: Reco_tf.py q431 RAWtoALL in MP mode
+# art-description: Reco_tf.py q431 RAWtoALL in MP mode, use 4 cores due to large memory usage of MP
 # art-type: grid
 # art-include: master/Athena
 # art-athena-mt: 8
 
+export ATHENA_CORE_NUMBER=4
 timeout 43200 Reco_tf.py \
   --inputBSFile=/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/Tier0ChainTests/data18_13TeV.00357750.physics_Main.daq.RAW/data18_13TeV.00357750.physics_Main.daq.RAW._lb0114._SFO-5._0003.data \
   --outputAODFile=myAOD.pool.root \
diff --git a/Tracking/TrkAlignment/TrkAlignGenTools/python/AlignmentTrackFitter.py b/Tracking/TrkAlignment/TrkAlignGenTools/python/AlignmentTrackFitter.py
index 871d35b6884bb88883698c48d8a633e4348edcdd..42d7267de358fe91743b957b36f9219eccdb7582 100644
--- a/Tracking/TrkAlignment/TrkAlignGenTools/python/AlignmentTrackFitter.py
+++ b/Tracking/TrkAlignment/TrkAlignGenTools/python/AlignmentTrackFitter.py
@@ -120,6 +120,17 @@ class AlignmentTrackFitter () :
             AggregateMaterial         = True,
             Extrapolator              = MuidExtrapolator,
             TrackingGeometrySvc       = svcMgr.AtlasTrackingGeometrySvc)
+
+
+        from InDetRecExample.TrackingCommon import use_tracking_geometry_cond_alg
+        if use_tracking_geometry_cond_alg:
+          from AthenaCommon.AlgSequence import AthSequencer
+          condSeq = AthSequencer("AthCondSeq")
+          if not getattr (condSeq, 'AtlasTrackingGeometryCondAlg', None):
+            from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlg import ConfiguredTrackingGeometryCondAlg
+            condSeq += ConfiguredTrackingGeometryCondAlg()
+          MuidMaterialAllocator.TrackingGeometryReadKey='AtlasTrackingGeometry'
+
         ToolSvc += MuidMaterialAllocator
         
         
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h b/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h
index 8cb72f154db3824f218f5fa15d68fa6e109e3e0b..d5d2e52564393a26360e8b749518fac947f0a501 100644
--- a/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h
@@ -37,7 +37,7 @@ public:
 private:
 
   /// Output conditions object.
-  SG::WriteCondHandleKey<TrackingGeometry> m_trackingGeometryWriteKey{this, "TrackingGeometryWriteKey", "AlignedTrackingGeometry", "Key of output of TrackingGeometry for ID"};
+  SG::WriteCondHandleKey<TrackingGeometry> m_trackingGeometryWriteKey{this, "TrackingGeometryWriteKey", "AtlasTrackingGeometry", "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 ;
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlg.py b/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlg.py
index 6b125336b1fd93a43c561672c3105f283a02833a..1a1450a5a5d8067c66bd14e25c44cc6772d816a3 100644
--- a/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlg.py
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlg.py
@@ -174,10 +174,11 @@ class ConfiguredTrackingGeometryCondAlg( Trk__TrackingGeometryCondAlg ) :
            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
+from AthenaCommon.AlgSequence import AthSequencer
+condSeq = AthSequencer("AthCondSeq")
+# test if TGCondAlg already in condSeq
+if not getattr(condSeq, 'AtlasTrackingGeometryCondAlg', None):
+  # now create the instance
+  AtlasTrackingGeometryCondAlg = ConfiguredTrackingGeometryCondAlg('AtlasTrackingGeometryCondAlg')
+  condSeq+= AtlasTrackingGeometryCondAlg
diff --git a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/CurvilinearParametersT.h b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/CurvilinearParametersT.h
index 4cbe21a82af9503affdcb85261ba7b9ac8a29beb..aa8593245a917ac3911873230439ea221baa88fd 100644
--- a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/CurvilinearParametersT.h
+++ b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/CurvilinearParametersT.h
@@ -14,8 +14,7 @@
 #include "EventPrimitives/EventPrimitives.h"
 #include "GeoPrimitives/GeoPrimitives.h"
 #include "TrkEventPrimitives/CurvilinearUVT.h"
-#include "TrkEventPrimitives/SurfaceUniquePtrT.h"
-
+#include "TrkSurfaces/Surface.h"
 #include <memory>
 class MsgStream;
 
@@ -48,6 +47,9 @@ template<int DIM, class T, class S>
 class CurvilinearParametersT final : public ParametersBase<DIM, T>
 {
 public:
+  static_assert(S::staticType == Surface::Plane,
+                "The surface type must be Plane");
+
   /** default constructor only for POOL */
   CurvilinearParametersT() = default;
 
@@ -117,10 +119,9 @@ public:
 
   /** Virtual clone */
   virtual CurvilinearParametersT<DIM, T, S>* clone() const override final;
-  
+
   /** Virtual clone returning unique_ptr*/
   std::unique_ptr<CurvilinearParametersT<DIM, T, S>> uniqueClone() const;
-  
 
   /** Return the ParametersType enum */
   virtual ParametersType type() const override final;
@@ -149,9 +150,9 @@ protected:
   using ParametersBase<DIM, T>::m_parameters;
   using ParametersBase<DIM, T>::m_covariance;
   using ParametersBase<DIM, T>::m_chargeDef;
-  Amg::Vector3D m_position;             //!< point on track
-  Amg::Vector3D m_momentum;             //!< momentum at this point on track
-  SurfaceUniquePtrT<const S> m_surface; //!< surface template
+  Amg::Vector3D m_position; //!< point on track
+  Amg::Vector3D m_momentum; //!< momentum at this point on track
+  S m_surface;              //!< surface template
   /** the curvilinear parameters identifier */
   unsigned int m_cIdentifier = 0;
   /*
diff --git a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/CurvilinearParametersT.icc b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/CurvilinearParametersT.icc
index eb7b9d2b12143cc27f7ace3e3fb221fdaf7cfd9b..4cfcf6694d303a9890cea20e8968b621d9d73bc6 100644
--- a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/CurvilinearParametersT.icc
+++ b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/CurvilinearParametersT.icc
@@ -22,7 +22,6 @@ Trk::CurvilinearParametersT<DIM, T, S>::CurvilinearParametersT(
   : ParametersBase<DIM, T>(covariance)
   , m_position(Amg::Vector3D(parameters[x], parameters[y], parameters[z]))
   , m_momentum(Amg::Vector3D(parameters[3], parameters[4], parameters[5]))
-  , m_surface{ nullptr }
   , m_cIdentifier(cIdentifier)
 {
 
@@ -39,7 +38,7 @@ Trk::CurvilinearParametersT<DIM, T, S>::CurvilinearParametersT(
   this->m_parameters[qOverP] = parameters[6] / this->momentum().mag();
 
   /* we need all the above to be there for the surfac*/
-  this->m_surface.reset(new S(this->m_position, curvilinearFrame()));
+  m_surface = S(this->m_position, curvilinearFrame());
 }
 
 // Constructor with TP arguments
@@ -52,7 +51,6 @@ CurvilinearParametersT<DIM, T, S>::CurvilinearParametersT(
   AmgSymMatrix(DIM) * cov,
   unsigned int cIdentifier)
   : ParametersBase<DIM, T>()
-  , m_surface{ nullptr }
   , m_cIdentifier(cIdentifier)
 {
   this->m_covariance.reset(cov);
@@ -73,11 +71,12 @@ CurvilinearParametersT<DIM, T, S>::CurvilinearParametersT(
 
   // make sure that the position & momentum are calculated
   double p = std::abs(1. / tqOverP);
-  this->m_momentum = Amg::Vector3D(
-    p * std::cos(tphi) * std::sin(ttheta), p * std::sin(tphi) * std::sin(ttheta), p * std::cos(ttheta));
+  this->m_momentum = Amg::Vector3D(p * std::cos(tphi) * std::sin(ttheta),
+                                   p * std::sin(tphi) * std::sin(ttheta),
+                                   p * std::cos(ttheta));
 
   /* we need all the above for the surface*/
-  this->m_surface.reset(new S(this->m_position, curvilinearFrame()));
+  m_surface= S(this->m_position, curvilinearFrame());
 }
 
 // full global constructor
@@ -89,7 +88,6 @@ CurvilinearParametersT<DIM, T, S>::CurvilinearParametersT(
   AmgSymMatrix(DIM) * cov,
   unsigned int cIdentifier)
   : ParametersBase<DIM, T>()
-  , m_surface{ nullptr }
   , m_cIdentifier(cIdentifier)
 {
   this->m_chargeDef.setCharge(charge);
@@ -110,7 +108,7 @@ CurvilinearParametersT<DIM, T, S>::CurvilinearParametersT(
   this->m_momentum = mom;
 
   // we need all the above to create the surface
-  this->m_surface.reset(new S(this->m_position, curvilinearFrame()));
+  m_surface = S(this->m_position, curvilinearFrame());
 }
 
 // Copy constructor
@@ -121,12 +119,9 @@ CurvilinearParametersT<DIM, T, S>::CurvilinearParametersT(
 
   , m_position(rhs.position())
   , m_momentum(rhs.momentum())
-  , m_surface(nullptr)
+  , m_surface(rhs.m_surface)
   , m_cIdentifier(rhs.m_cIdentifier)
 {
-  m_surface.reset((rhs.m_surface && rhs.m_surface->isFree()
-                     ? rhs.m_surface->clone()
-                     : rhs.m_surface.get()));
   if (rhs.covariance()) {
     m_covariance = std::make_unique<AmgSymMatrix(DIM)>(*rhs.covariance());
   }
@@ -145,9 +140,7 @@ CurvilinearParametersT<DIM, T, S>::operator=(
                      : nullptr;
     m_position = rhs.position();
     m_momentum = rhs.momentum();
-    m_surface.reset((rhs.m_surface && rhs.m_surface->isFree())
-                      ? rhs.m_surface->clone()
-                      : rhs.m_surface.get());
+    m_surface = rhs.m_surface;
     m_chargeDef = rhs.m_chargeDef;
     m_cIdentifier = rhs.m_cIdentifier;
   }
@@ -194,7 +187,7 @@ template<int DIM, class T, class S>
 bool
 CurvilinearParametersT<DIM, T, S>::hasSurface() const
 {
-  return m_surface != nullptr;
+  return true;
 }
 
 /** Access to the Surface method */
@@ -202,7 +195,7 @@ template<int DIM, class T, class S>
 const S&
 CurvilinearParametersT<DIM, T, S>::associatedSurface() const
 {
-  return *m_surface;
+  return m_surface;
 }
 
 // equality operator
@@ -371,7 +364,7 @@ Trk::CurvilinearParametersT<DIM, T, S>::updateParametersHelper(
       updatedParameters[Trk::loc2] * curvilinearFrame().curvV();
   }
   // Reset also the surface
-  this->m_surface.reset(new S(this->m_position, curvilinearFrame()));
+  m_surface = S(this->m_position, curvilinearFrame());
 }
 
 } // end of namespace Trk
diff --git a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersT.h b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersT.h
index 0c738abbcdb359e5bf3afe1f829798f83afa0de9..5f2f6c6518570b90dbc0931b496836701b71ba35 100644
--- a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersT.h
+++ b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersT.h
@@ -14,11 +14,6 @@
 #include "TrkEventPrimitives/SurfaceUniquePtrT.h"
 #include "TrkParametersBase/ParametersBase.h"
 #include "TrkSurfaces/Surface.h"
-/*
- * Needed for persistency
- * friends
- */
-
 namespace Trk {
 class MaterialEffectsEngine;
 
diff --git a/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/src/STEP_Propagator.cxx b/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/src/STEP_Propagator.cxx
index 55ac6193c8ca5f8de95ad6f04a4c1a0e1ba70227..84cc14c1bb026113cb2df850fbcc9991dd456ae6 100755
--- a/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/src/STEP_Propagator.cxx
+++ b/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/src/STEP_Propagator.cxx
@@ -645,7 +645,7 @@ Trk::STEP_Propagator::intersect (const EventContext&                 ctx,
   //Check inputvalues
   if (m_tolerance <= 0.) return nullptr;
   if (m_momentumCutOff < 0. ) return nullptr;
-  if (fabs( 1./trackParameters.parameters()[Trk::qOverP]) <= m_momentumCutOff) {
+  if (std::abs( 1./trackParameters.parameters()[Trk::qOverP]) <= m_momentumCutOff) {
     return nullptr;
   }
 
@@ -812,14 +812,14 @@ Trk::STEP_Propagator::globalPositions ( const EventContext&                 ctx,
   double       h = maxStepSize;                         // max step allowed
 
   // Test position of the track
-  if ((fabs(PP[2]) > zMax) || (radius2 > radius2Max)) return;
+  if ((std::abs(PP[2]) > zMax) || (radius2 > radius2Max)) return;
 
   //Store initial position
   Amg::Vector3D initialPosition(PP[0],PP[1],PP[2]);
   positionsList.push_back(initialPosition);
 
   bool perigee = false;
-  if (fabs(direction) < 0.00001) {
+  if (std::abs(direction) < 0.00001) {
     perigee = true;
   }
 
@@ -830,7 +830,7 @@ Trk::STEP_Propagator::globalPositions ( const EventContext&                 ctx,
     }
     double p[7] = {PP[0],PP[1],PP[2],PP[3],PP[4],PP[5],PP[6]};
 
-    while (fabs(path) < maxPath) {
+    while (std::abs(path) < maxPath) {
       //Do the step.
       if (!rungeKuttaStep( cache,false, h, p, dDir, BG1, firstStep, distanceStepped)) break;
       path = path + distanceStepped;
@@ -853,7 +853,7 @@ Trk::STEP_Propagator::globalPositions ( const EventContext&                 ctx,
 
       // Test position of the track
       radius2 = p[0]*p[0]+p[1]*p[1];
-      if ((fabs( p[2]) > zMax) || (radius2 > radius2Max)) break;
+      if ((std::abs( p[2]) > zMax) || (radius2 > radius2Max)) break;
 
       // Test perigee
       if ((p[0]*p[3] + p[1]*p[4])*direction < 0.) {
@@ -913,7 +913,7 @@ Trk::STEP_Propagator::propagateRungeKutta (Cache&                              c
     trackParameters.reset(inputTrackParameters.clone());
   }
 
-  if (fabs( 1./trackParameters->parameters()[Trk::qOverP]) <= m_momentumCutOff) {
+  if (std::abs( 1./trackParameters->parameters()[Trk::qOverP]) <= m_momentumCutOff) {
     return nullptr;
   }
 
@@ -1021,8 +1021,8 @@ Trk::STEP_Propagator::propagateRungeKutta (Cache&                              c
     AmgSymMatrix(5)* measurementCovariance = Trk::RungeKuttaUtils::newCovarianceMatrix(
                                                                                  Jacobian, *trackParameters->covariance());
 
-    if (cache.m_matPropOK && (m_multipleScattering || m_straggling) && fabs(path)>0. )
-      covarianceContribution( cache,trackParameters.get(), path, fabs( 1./cache.m_P[6]), measurementCovariance);
+    if (cache.m_matPropOK && (m_multipleScattering || m_straggling) && std::abs(path)>0. )
+      covarianceContribution( cache,trackParameters.get(), path, std::abs( 1./cache.m_P[6]), measurementCovariance);
 
     return std::make_unique<Trk::CurvilinearParameters>(gp,localp[2],localp[3],localp[4],measurementCovariance);
   }
@@ -1049,7 +1049,7 @@ Trk::STEP_Propagator::propagateRungeKutta (Cache&                              c
                                                                                Jacobian, *trackParameters->covariance());
 
   //Calculate multiple scattering and straggling covariance contribution.
-  if (cache.m_matPropOK && (m_multipleScattering || m_straggling) && fabs(path)>0. )
+  if (cache.m_matPropOK && (m_multipleScattering || m_straggling) && std::abs(path)>0. )
     covarianceContribution( cache,trackParameters.get(), path, onTargetSurf.get(), measurementCovariance);
 
   return targetSurface.createUniqueTrackParameters(localp[0],localp[1],localp[2],localp[3],localp[4],measurementCovariance);
@@ -1097,7 +1097,7 @@ Trk::STEP_Propagator::propagateRungeKutta ( Cache&
     trackParameters.reset(inputTrackParameters.clone());
   }
 
-  if (fabs( 1./trackParameters->parameters()[Trk::qOverP]) <= m_momentumCutOff) {
+  if (std::abs( 1./trackParameters->parameters()[Trk::qOverP]) <= m_momentumCutOff) {
     return nullptr;
   }
 
@@ -1164,8 +1164,8 @@ Trk::STEP_Propagator::propagateRungeKutta ( Cache&
         AmgSymMatrix(5)* measurementCovariance = Trk::RungeKuttaUtils::newCovarianceMatrix(Jacobian,
                                                                                      *trackParameters->covariance());
         //Calculate multiple scattering and straggling covariance contribution.
-        if (cache.m_matPropOK && (m_multipleScattering || m_straggling) && fabs(totalPath)>0.) {
-          covarianceContribution(cache, trackParameters.get(), totalPath, fabs( 1./cache.m_P[6]), measurementCovariance);
+        if (cache.m_matPropOK && (m_multipleScattering || m_straggling) && std::abs(totalPath)>0.) {
+          covarianceContribution(cache, trackParameters.get(), totalPath, std::abs( 1./cache.m_P[6]), measurementCovariance);
         }
         cPar = std::make_unique< Trk::CurvilinearParameters>(Amg::Vector3D(cache.m_P[0],cache.m_P[1],cache.m_P[2]),
                                               localp[2],localp[3],localp[4],
@@ -1175,7 +1175,7 @@ Trk::STEP_Propagator::propagateRungeKutta ( Cache&
       // collect material
       if ( cache.m_binMat && (cache.m_matstates ||
                               (errorPropagation && cache.m_extrapolationCache)) &&
-           fabs(totalPath-cache.m_matdump_lastpath)>1.) {
+           std::abs(totalPath-cache.m_matdump_lastpath)>1.) {
         dumpMaterialEffects( cache,cPar.get(), totalPath);
       }
       return cPar;
@@ -1232,9 +1232,9 @@ Trk::STEP_Propagator::propagateRungeKutta ( Cache&
                                                                                Jacobian, *trackParameters->covariance());
 
   //Calculate multiple scattering and straggling covariance contribution.
-  if (cache.m_matPropOK && (m_multipleScattering || m_straggling) && fabs(totalPath)>0.) {
+  if (cache.m_matPropOK && (m_multipleScattering || m_straggling) && std::abs(totalPath)>0.) {
     if (returnCurv || targetSurfaces[solutions[0]].first->type()==Trk::Surface::Cone)  {
-      covarianceContribution( cache,trackParameters.get(), totalPath, fabs( 1./cache.m_P[6]), measurementCovariance);
+      covarianceContribution( cache,trackParameters.get(), totalPath, std::abs( 1./cache.m_P[6]), measurementCovariance);
     } else {
       covarianceContribution( cache,trackParameters.get(), totalPath, onTargetSurf.get(), measurementCovariance);
     }
@@ -1292,30 +1292,30 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache&      cache,
   // Keep distanceTolerance within [1 nanometer, 10 microns].
   // This means that no final Taylor expansions beyond 10 microns and no
   // Runge-Kutta steps less than 1 nanometer are allowed.
-  double distanceTolerance = std::min( std::max( fabs( distanceToTarget) * m_tolerance, 1e-6), 1e-2);
+  double distanceTolerance = std::min( std::max( std::abs( distanceToTarget) * m_tolerance, 1e-6), 1e-2);
 
-  while (fabs( distanceToTarget) > distanceTolerance) { // Step until within tolerance
+  while (std::abs( distanceToTarget) > distanceTolerance) { // Step until within tolerance
     //Do the step. Stop the propagation if the energy goes below m_momentumCutOff
     if (!rungeKuttaStep( cache,errorPropagation, h, P, dDir, BG1, firstStep, distanceStepped)) return false;
     path += distanceStepped;
-    absolutePath += fabs( distanceStepped);
+    absolutePath += std::abs( distanceStepped);
 
-    if(fabs(distanceStepped)>0.001) {
-      cache.m_sigmaIoni = cache.m_sigmaIoni - cache.m_kazL*log(fabs(distanceStepped));// the non-linear term
+    if(std::abs(distanceStepped)>0.001) {
+      cache.m_sigmaIoni = cache.m_sigmaIoni - cache.m_kazL*log(std::abs(distanceStepped));// the non-linear term
     }
     // update straggling covariance
     if (errorPropagation && m_straggling) {
       double sigTot2 = cache.m_sigmaIoni*cache.m_sigmaIoni + cache.m_sigmaRad*cache.m_sigmaRad;
       // /(beta*beta*p*p*p*p) transforms Var(E) to Var(q/p)
-      mom = fabs(1./P[6]); beta = mom/std::sqrt(mom*mom+cache.m_particleMass*cache.m_particleMass);
+      mom = std::abs(1./P[6]); beta = mom/std::sqrt(mom*mom+cache.m_particleMass*cache.m_particleMass);
       double bp2 = beta*mom*mom;
       cache.m_stragglingVariance += sigTot2/(bp2*bp2)*distanceStepped*distanceStepped;
     }
     if (cache.m_matstates || errorPropagation)
-      cache.m_combinedEloss.update(cache.m_delIoni*distanceStepped,cache.m_sigmaIoni*fabs(distanceStepped),
-                             cache.m_delRad *distanceStepped,cache.m_sigmaRad *fabs(distanceStepped),m_MPV);
+      cache.m_combinedEloss.update(cache.m_delIoni*distanceStepped,cache.m_sigmaIoni*std::abs(distanceStepped),
+                             cache.m_delRad *distanceStepped,cache.m_sigmaRad *std::abs(distanceStepped),m_MPV);
     //Calculate new distance to target
-    previousDistance = fabs( distanceToTarget);
+    previousDistance = std::abs( distanceToTarget);
     distanceToTarget = distance( surfaceType, targetSurface, P, distanceEstimationSuccessful);
     if (!distanceEstimationSuccessful) return false;
 
@@ -1325,15 +1325,15 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache&      cache,
       targetPassed++;
     }
     //don't step beyond surface
-    if (fabs( h) > fabs( distanceToTarget)) h = distanceToTarget;
+    if (std::abs( h) > fabs( distanceToTarget)) h = distanceToTarget;
 
     //Abort if maxPath is reached or solution is diverging
-    if ((targetPassed > 3 && fabs( distanceToTarget) >= previousDistance) || (absolutePath > maxPath)) return false;
+    if ((targetPassed > 3 && std::abs( distanceToTarget) >= previousDistance) || (absolutePath > maxPath)) return false;
 
     if (steps++ > m_maxSteps) return false; //Too many steps, something is wrong
   }
 
-  if (cache.m_material && cache.m_material->x0()!=0.) cache.m_combinedThickness += fabs(path)/cache.m_material->x0();
+  if (cache.m_material && cache.m_material->x0()!=0.) cache.m_combinedThickness += std::abs(path)/cache.m_material->x0();
 
   //Use Taylor expansions to step the remaining distance (typically microns).
   path = path + distanceToTarget;
@@ -1429,7 +1429,7 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
     if (distSol.numberOfSolutions()>0 ) {
       distEst = distSol.first();
       dist1Est = distSol.first();
-      if ( distSol.numberOfSolutions()>1 && ( fabs(distEst) < tol ||
+      if ( distSol.numberOfSolutions()>1 && ( std::abs(distEst) < tol ||
                                               (propDir*distEst<-tol && propDir*distSol.second()>tol)) )
         distEst = distSol.second();
     }
@@ -1454,7 +1454,7 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
       cache.m_currentDist[iCurr]=std::pair<int,std::pair<double,double> >
         (-1,std::pair<double,double>(distSol.currentDistance(),distSol.currentDistance(true)));
     }
-    if(fabs(dist1Est)<tol) startSf = (int) iCurr;
+    if(std::abs(dist1Est)<tol) startSf = (int) iCurr;
     iCurr++;
   }
 
@@ -1477,7 +1477,7 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
       cache.m_currentLayerBin = cache.m_binMat->layerBin(position);
       binIDMat        = cache.m_binMat->material(position);
       std::pair<size_t,float> dist2next = lbu->distanceToNext(position,propDir*direction0);
-      if (dist2next.first < lbu->bins() && fabs(dist2next.second)>1. && fabs(dist2next.second)< fabs(h) ){
+      if (dist2next.first < lbu->bins() && std::abs(dist2next.second)>1. && fabs(dist2next.second)< fabs(h) ){
         h = dist2next.second*propDir;
       }
       if (binIDMat) cache.m_material = binIDMat->first;
@@ -1488,16 +1488,16 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
   // Keep distanceTolerance within [1 nanometer, 10 microns].
   // This means that no final Taylor expansions beyond 10 microns and no
   // Runge-Kutta steps less than 1 nanometer are allowed.
-  double distanceTolerance = std::min( std::max( fabs( distanceToTarget) * m_tolerance, 1e-6), 1e-2);
+  double distanceTolerance = std::min( std::max( std::abs( distanceToTarget) * m_tolerance, 1e-6), 1e-2);
 
   // bremstrahlung : sample if activated
   if (cache.m_brem) {
-    mom = fabs(1./P[6]);
+    mom = std::abs(1./P[6]);
     sampleBrem(cache,mom);
   }
 
-  while ( numSf > 0 && ( fabs( distanceToTarget) > distanceTolerance ||
-                         fabs(path+distanceStepped)<tol) ) { // Step until within tolerance
+  while ( numSf > 0 && ( std::abs( distanceToTarget) > distanceTolerance ||
+                         std::abs(path+distanceStepped)<tol) ) { // Step until within tolerance
     //Do the step. Stop the propagation if the energy goes below m_momentumCutOff
     if (!rungeKuttaStep(cache, errorPropagation, h, P, dDir, BG1, firstStep, distanceStepped)) {
       // emit brem photon before stopped ?
@@ -1515,11 +1515,11 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
       // collect material and update timing
       path = path + distanceStepped;
       // timing
-      mom = fabs(1./P[6]); beta = mom/std::sqrt(mom*mom+cache.m_particleMass*cache.m_particleMass);
+      mom = std::abs(1./P[6]); beta = mom/std::sqrt(mom*mom+cache.m_particleMass*cache.m_particleMass);
       cache.m_timeStep += distanceStepped/beta/CLHEP::c_light;
 
-      if(fabs(distanceStepped)>0.001) {
-        cache.m_sigmaIoni = cache.m_sigmaIoni - cache.m_kazL*log(fabs(distanceStepped));
+      if(std::abs(distanceStepped)>0.001) {
+        cache.m_sigmaIoni = cache.m_sigmaIoni - cache.m_kazL*log(std::abs(distanceStepped));
       }
       // update straggling covariance
       if (errorPropagation && m_straggling) {
@@ -1531,8 +1531,8 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
       }
       if (cache.m_matstates||errorPropagation){
         cache.m_combinedEloss.update(cache.m_delIoni*distanceStepped,
-                               cache.m_sigmaIoni*fabs(distanceStepped),
-                               cache.m_delRad *distanceStepped,cache.m_sigmaRad *fabs(distanceStepped),m_MPV);
+                               cache.m_sigmaIoni*std::abs(distanceStepped),
+                               cache.m_delRad *distanceStepped,cache.m_sigmaRad *std::abs(distanceStepped),m_MPV);
       }
       if (cache.m_material && cache.m_material->x0()!=0.) {
         cache.m_combinedThickness += propDir*distanceStepped/cache.m_material->x0();
@@ -1541,13 +1541,13 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
       return false;
     }
     path = path + distanceStepped;
-    absPath += fabs(distanceStepped);
+    absPath += std::abs(distanceStepped);
 
     // timing
-    mom = fabs(1./P[6]); beta = mom/std::sqrt(mom*mom+cache.m_particleMass*cache.m_particleMass);
+    mom = std::abs(1./P[6]); beta = mom/std::sqrt(mom*mom+cache.m_particleMass*cache.m_particleMass);
     cache.m_timeStep += distanceStepped/beta/Gaudi::Units::c_light;
 
-    if(fabs(distanceStepped)>0.001) cache.m_sigmaIoni = cache.m_sigmaIoni - cache.m_kazL*log(fabs(distanceStepped));
+    if(std::abs(distanceStepped)>0.001) cache.m_sigmaIoni = cache.m_sigmaIoni - cache.m_kazL*log(fabs(distanceStepped));
     // update straggling covariance
     if (errorPropagation && m_straggling) {
       // 15% of the Radition moves the MOP value thus only 85% is accounted for by the Mean-MOP shift
@@ -1557,8 +1557,8 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
       cache.m_stragglingVariance += sigTot2/(bp2*bp2)*distanceStepped*distanceStepped;
     }
     if (cache.m_matstates||errorPropagation){
-      cache.m_combinedEloss.update(cache.m_delIoni*distanceStepped,cache.m_sigmaIoni*fabs(distanceStepped),
-                                   cache.m_delRad *distanceStepped,cache.m_sigmaRad *fabs(distanceStepped),m_MPV);
+      cache.m_combinedEloss.update(cache.m_delIoni*distanceStepped,cache.m_sigmaIoni*std::abs(distanceStepped),
+                                   cache.m_delRad *distanceStepped,cache.m_sigmaRad *std::abs(distanceStepped),m_MPV);
     }
     if (cache.m_material && cache.m_material->x0()!=0.) {
       cache.m_combinedThickness += propDir*distanceStepped/cache.m_material->x0();
@@ -1571,8 +1571,8 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
 
     bool restart = false;
     // in case of problems, make shorter steps
-    if ( propDir*path < -tol || absPath-fabs(path)>10.) {
-      helpSoft = fabs(path)/absPath > 0.5 ? fabs(path)/absPath : 0.5;
+    if ( propDir*path < -tol || absPath-std::abs(path)>10.) {
+      helpSoft = std::abs(path)/absPath > 0.5 ? fabs(path)/absPath : 0.5;
     }
 
     Amg::Vector3D position(P[0],P[1],P[2]);
@@ -1635,7 +1635,7 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
             std::pair<size_t,float> d2n = lbu->distanceToNext(probe,propDir*direction);
             distanceToNextBin += d2n.second+h;
           }
-        } else if ( dist2next.first < lbu->bins() && std::fabs(distanceToNextBin) < 0.01 && h>0.01 ) {     // tolerance 10 microns ?
+        } else if ( dist2next.first < lbu->bins() && std::abs(distanceToNextBin) < 0.01 && h>0.01 ) {     // tolerance 10 microns ?
           double localp[5];
           Trk::RungeKuttaUtils::transformGlobalToLocal(P, localp);
           auto cPar =
@@ -1722,15 +1722,15 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
         helpSoft = 1.;
       }
       if ( (*vsIter).first != -1 && ( ic==nextSf || (*vsIter).first==1 || nextSf<0 ||
-                                      fabs((*vsIter).second.first) < 500. ||  fabs(path)>0.5*fabs((*vsIter).second.second) )  ) {
+                                      std::abs((*vsIter).second.first) < 500. ||  fabs(path)>0.5*fabs((*vsIter).second.second) )  ) {
         previousDistance = (*vsIter).second.first;
         Trk::DistanceSolution distSol = (*sIter).first->straightLineDistanceEstimate(position,propDir*direction);
         double distanceEst=-propDir*maxPath;
         if (distSol.numberOfSolutions()>0 ) {
           distanceEst = distSol.first();
           if (distSol.numberOfSolutions()>1 &&
-              fabs(distSol.first()*propDir+distanceStepped-previousDistance) >
-              fabs(distSol.second()*propDir+distanceStepped-previousDistance) ){
+              std::abs(distSol.first()*propDir+distanceStepped-previousDistance) >
+              std::abs(distSol.second()*propDir+distanceStepped-previousDistance) ){
             distanceEst = distSol.second();
           }
           // Peter Kluit: avoid jumping into other (distSol.first->second) distance solution for start surface with negative distance solution
@@ -1739,17 +1739,17 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
           if(ic==startSf&&distanceEst<0&&distSol.first()>0) distanceEst = distSol.first();
         }
         // eliminate close surface if path too small
-        if (ic==nextSf && fabs(distanceEst)<tol && fabs(path)<tol) {
+        if (ic==nextSf && std::abs(distanceEst)<tol && fabs(path)<tol) {
           (*vsIter).first=-1; vsIter=vsBeg; restart=true; distanceToTarget=maxPath; nextSf=-1;
           continue;
         }
 
         //If h and distance are in opposite directions, target is passed. Flip propagation direction
         //Verify if true intersection
-        // if (  h * propDir * distanceEst < 0. &&  fabs(distanceEst)>distanceTolerance ) {
-        if (  (*vsIter).second.first *propDir* distanceEst < 0. &&  fabs(distanceEst)>distanceTolerance ) {
+        // if (  h * propDir * distanceEst < 0. &&  std::abs(distanceEst)>distanceTolerance ) {
+        if (  (*vsIter).second.first *propDir* distanceEst < 0. &&  std::abs(distanceEst)>distanceTolerance ) {
           // verify change of sign in signedDistance ( after eliminating situations where this is meaningless )
-          if ( !distSol.signedDistance() || fabs(distSol.currentDistance(true))<tol || fabs((*vsIter).second.second)<tol
+          if ( !distSol.signedDistance() || std::abs(distSol.currentDistance(true))<tol || fabs((*vsIter).second.second)<tol
                || (*vsIter).second.second*distSol.currentDistance(true)<0) {   // true intersection
             if (ic==nextSf) {
               ((*vsIter).first)++;
@@ -1760,12 +1760,12 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
               }
               // take care of eliminating when number of flips even - otherwise it may end up at the start !
               if ((*vsIter).first>50 && h*propDir>0 ) {
-                // fabs(distanceEst) >= fabs(previousDistance) )  {
+                // std::abs(distanceEst) >= fabs(previousDistance) )  {
                 (*vsIter).first = -1; vsIter = vsBeg; restart = true;
                 continue;
               }
               if ((*vsIter).first!=-1) flipDirection = true;
-            } else if ( fabs((*vsIter).second.second)>tol && fabs(distSol.currentDistance(true))>tol ) {
+            } else if ( std::abs((*vsIter).second.second)>tol && fabs(distSol.currentDistance(true))>tol ) {
               // here we need to compare with distance from current closest
               if ( ic>nextSf ) {   // easy case, already calculated
                 if (propDir*distanceEst<(*(vsBeg+nextSf)).second.first-tol)  {
@@ -1799,12 +1799,12 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
         // mw	if ((*vsIter).first!=-1 && ( distanceEst>-tol || ic==nextSf ) ) {
         if ((*vsIter).first!=-1 && ( distanceEst > 0. || ic==nextSf ) ) {
           numSf++;
-          if ( distanceEst < fabs(distanceToTarget) ) {
+          if ( distanceEst < std::abs(distanceToTarget) ) {
             distanceToTarget = propDir*distanceEst;
             nextSfCand = ic;
           }
         }
-      } else if ( fabs(path) > fabs((*vsIter).second.second) || dev<0.985 || nextSf<0 ) {  // keep an eye on surfaces with negative distance; tracks are curved !
+      } else if ( std::abs(path) > fabs((*vsIter).second.second) || dev<0.985 || nextSf<0 ) {  // keep an eye on surfaces with negative distance; tracks are curved !
         Trk::DistanceSolution distSol = (*sIter).first->straightLineDistanceEstimate(position,propDir*direction);
         double distanceEst=-propDir*maxPath;
         if (distSol.numberOfSolutions()>0 ) {
@@ -1817,11 +1817,11 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
         if ( distanceEst > tol && distanceEst < maxPath ) {
           (*vsIter).first = 0;
         } else {
-          (*vsIter).second.first = distSol.currentDistance()+fabs(path);
+          (*vsIter).second.first = distSol.currentDistance()+std::abs(path);
         }
         if ((*vsIter).first!=-1 && distanceEst > 0.) {
           numSf++;
-          if ( distanceEst < fabs(distanceToTarget) ) {
+          if ( distanceEst < std::abs(distanceToTarget) ) {
             distanceToTarget = propDir*distanceEst;
             nextSfCand = ic;
           }
@@ -1830,7 +1830,7 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
       // additional protection - return to the same surface
       // eliminate the surface and restart the search
       // 04/10/10 ST:infinite loop due to distanceTolerance>tol fixed;
-      if ( fabs(distanceToTarget)<=distanceTolerance && path*propDir<distanceTolerance ) {
+      if ( std::abs(distanceToTarget)<=distanceTolerance && path*propDir<distanceTolerance ) {
         (*vsIter).first = -1; vsIter = vsBeg; restart = true;
         continue;
       }
@@ -1849,10 +1849,10 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
     }
 
     //don't step beyond surfaces - adjust step
-    if (fabs( h) > fabs( distanceToTarget)) h = distanceToTarget;
+    if (std::abs( h) > fabs( distanceToTarget)) h = distanceToTarget;
 
     //don't step beyond bin boundary - adjust step
-    if (cache.m_binMat && fabs( h) > std::fabs(distanceToNextBin)+0.001 ) {
+    if (cache.m_binMat && std::abs( h) > std::fabs(distanceToNextBin)+0.001 ) {
       if ( distanceToNextBin>0 ) {     // TODO : investigate source of negative distance in BinningData
         //std::cout <<"adjusting step because of bin boundary:"<< h<<"->"<< distanceToNextBin*propDir<< std::endl;
         h = distanceToNextBin*propDir;
@@ -1867,7 +1867,7 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
     //std::cout <<"current closest estimate: distanceToTarget: step size :"<< nextSf<<":"<< distanceToTarget <<":"<<h<< std::endl;
 
     //Abort if maxPath is reached
-    if (fabs( path) > maxPath) return false;
+    if (std::abs( path) > maxPath) return false;
 
     if (steps++ > m_maxSteps) return false; //Too many steps, something is wrong
 
@@ -1879,7 +1879,7 @@ Trk::STEP_Propagator::propagateWithJacobian (Cache& cache,
   path = path + distanceToTarget;
 
   // timing
-  mom = fabs(1./P[6]); beta = mom/std::sqrt(mom*mom+cache.m_particleMass*cache.m_particleMass);
+  mom = std::abs(1./P[6]); beta = mom/std::sqrt(mom*mom+cache.m_particleMass*cache.m_particleMass);
   cache.m_timeStep += distanceToTarget/beta/Gaudi::Units::c_light;
 
   //pos = pos + h*dir + 1/2*h*h*dDir. Second order Taylor expansion.
@@ -1957,7 +1957,7 @@ Trk::STEP_Propagator::rungeKuttaStep( Cache& cache,
   double     dL2=0.;
   double     dL3=0.;
   double     dL4=0.;    // factor used for calculating dCM/dCM, P[41], in the Jacobian.
-  double     initialMomentum = fabs( 1./P[6]);  // Set initial momentum
+  double     initialMomentum = std::abs( 1./P[6]);  // Set initial momentum
   Amg::Vector3D initialPos( P[0], P[1], P[2]);	// Set initial values for position
   Amg::Vector3D initialDir( P[3], P[4], P[5]);	// Set initial values for direction.
 // Directions at the different points. Used by the error propagation
@@ -2337,7 +2337,7 @@ double Trk::STEP_Propagator::dgdlambda( Cache& cache,double l) const
   if (cache.m_material->x0()==0 || cache.m_material->averageZ()==0) return 0.;
   if (cache.m_material->zOverAtimesRho()==0) return 0.;
 
-  double p     = fabs( 1./l);
+  double p     = std::abs( 1./l);
   double m     = s_particleMasses.mass[cache.m_particle];
   double me    = s_particleMasses.mass[Trk::electron];
   double E     = std::sqrt(p*p+m*m);
@@ -2498,7 +2498,7 @@ void Trk::STEP_Propagator::updateMaterialEffects( Cache& cache,
   double totalMomentumLoss = mom - cache.m_matupd_lastmom;
   double pathSinceLastUpdate = path - cache.m_matupd_lastpath;
 
-  double pathAbs = fabs(pathSinceLastUpdate);
+  double pathAbs = std::abs(pathSinceLastUpdate);
 
   if (pathAbs<1.e-03) return;
 
@@ -2522,12 +2522,16 @@ void Trk::STEP_Propagator::updateMaterialEffects( Cache& cache,
   double average_dEds = totalMomentumLoss/pathAbs;
 
   double cumulatedVariance = cache.m_inputThetaVariance + cache.m_combinedCovariance(3,3) + cache.m_covariance(3,3);
-
+  if (cumulatedVariance < 0) {
+    ATH_MSG_WARNING("Cumulated variance for material effects is "
+                    "negative. Setting to 0");
+    cumulatedVariance = 0;
+  }
   double cumulatedX0 = 0.;
 
   bool useCache =cache.m_extrapolationCache != nullptr;
   if(useCache)  {
-    double dX0 =  fabs(cache.m_combinedThickness) - pathAbs/matX0;
+    double dX0 =  std::abs(cache.m_combinedThickness) - pathAbs/matX0;
     if(dX0<0) dX0 = 0.;
     if(cache.m_extrapolationCache->x0tot()>0) cumulatedX0 = cache.m_extrapolationCache->x0tot() + dX0;
   }
diff --git a/Trigger/TrigAnalysis/TrigDecisionMaker/python/TrigDecisionMakerConfig.py b/Trigger/TrigAnalysis/TrigDecisionMaker/python/TrigDecisionMakerConfig.py
index 584d786a3a6c958ca4138bc0a60ac8c9940ffaaa..763e4ef81e2d2f0fb511b19d87d968fd67b825ea 100644
--- a/Trigger/TrigAnalysis/TrigDecisionMaker/python/TrigDecisionMakerConfig.py
+++ b/Trigger/TrigAnalysis/TrigDecisionMaker/python/TrigDecisionMakerConfig.py
@@ -11,8 +11,8 @@ class TrigDecisionMaker( TrigDec__TrigDecisionMaker ):
         super( TrigDecisionMaker, self ).__init__( name )
         log = logging.getLogger( 'TrigDecisionMaker' )
         from AthenaConfiguration.AllConfigFlags import ConfigFlags
-        log.info("Setting UseNewConfig to %s", ConfigFlags.Trigger.readLVL1FromJSON)
-        self.Lvl1ResultAccessTool.UseNewConfig = ConfigFlags.Trigger.readLVL1FromJSON
+        log.info("Setting UseNewConfig to %s (based off of ConfigFlags.Trigger.doEDMVersionConversion)", ConfigFlags.Trigger.doEDMVersionConversion)
+        self.Lvl1ResultAccessTool.UseNewConfig = ConfigFlags.Trigger.doEDMVersionConversion
         from AthenaCommon.AppMgr import ServiceMgr as svcMgr
         if hasattr(svcMgr,'DSConfigSvc'):
             # this case is still needed for reading Run 2 configuration from the TriggerDB
@@ -39,11 +39,6 @@ class TrigDecisionMakerMT( TrigDec__TrigDecisionMakerMT ):
         acc.merge( HLTPrescaleCondAlgCfg( ConfigFlags ) )
         appendCAtoAthena( acc )
         Configurable.configurableRun3Behavior -= 1
-        ###
-        from AthenaCommon.AppMgr import ServiceMgr as svcMgr
-        if hasattr(svcMgr,'DSConfigSvc'):
-            # this case is still needed for reading Run 2 configuration from the TriggerDB
-            self.Lvl1ResultAccessTool.LVL1ConfigSvc = "TrigConfigSvc"
 
 # Following not yet ported to the AthenaMT / Run 3 alg
 
diff --git a/Trigger/TrigAnalysis/TrigInDetAnalysisUser/share/TIDAdata_cuts-offline.dat b/Trigger/TrigAnalysis/TrigInDetAnalysisUser/share/TIDAdata_cuts-offline.dat
index 4c82e0425588c433b4f4945cb55c8e36ad0f5c6b..7f1ef044951b8bb412e58ac355307eea3d7f1b86 100644
--- a/Trigger/TrigAnalysis/TrigInDetAnalysisUser/share/TIDAdata_cuts-offline.dat
+++ b/Trigger/TrigAnalysis/TrigInDetAnalysisUser/share/TIDAdata_cuts-offline.dat
@@ -20,8 +20,6 @@ pT_rec  = 0;
 eta_rec = 5;
 Rmatch = 0.05;
 
-dumpflag = 1;
-
 #if defined(LRT)
 	a0v = 100.;
 	z0v = 300.5;
diff --git a/Trigger/TrigAnalysis/TrigInDetAnalysisUser/share/TIDAdata_cuts.dat b/Trigger/TrigAnalysis/TrigInDetAnalysisUser/share/TIDAdata_cuts.dat
index bb90e62aed098fdd4b0008e49dcae4857855cfc0..81280329c3d71d4e425ea2ecfe6eda3d85c87dce 100644
--- a/Trigger/TrigAnalysis/TrigInDetAnalysisUser/share/TIDAdata_cuts.dat
+++ b/Trigger/TrigAnalysis/TrigInDetAnalysisUser/share/TIDAdata_cuts.dat
@@ -24,7 +24,6 @@ pT_rec  = 0;
 eta_rec = 5;
 Rmatch = 0.05;
 
-dumpflag = 1;
 
 #if defined(LRT)
 	a0v = 100.;
diff --git a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
index 11504c3bdd0f3a5b97c00061503842b971fcaddb..2720e72a95eba9e4c132214d8f33e09dca6761bb 100644
--- a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
+++ b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
@@ -664,15 +664,16 @@ def addHLTNavigationToEDMList(edmList, allDecisions, hypoDecisions):
                 dynamic += '.PEBROBList.PEBSubDetList'
         typeName = 'xAOD::TrigCompositeContainer#{:s}'.format(decisionCollection)
         typeNameAux = 'xAOD::TrigCompositeAuxContainer#{:s}Aux{:s}'.format(decisionCollection, dynamic)
-        edmList.extend([
-            (typeName,    HLTNavEDMTargets, 'Steer'),
-            (typeNameAux, HLTNavEDMTargets, 'Steer')])
 
-        # Cost stream requires only filters and L1 seeded chains
+        # Cost monitoring only requires a sub-set of the navigation collections.
+        # (And CANNOT use any slimmed/merged collection, as the container names are important)
+        thisCollectionHLTNavEDMTargets = HLTNavEDMTargets
         if decisionCollection.startswith("HLTNav_FStep") or decisionCollection == "HLTNav_Summary" or decisionCollection.startswith("HLTNav_L1"):
-            edmList.extend([
-                (typeName,    'CostMonDS', 'Steer'),
-                (typeNameAux, 'CostMonDS', 'Steer')])
+            thisCollectionHLTNavEDMTargets += ' CostMonDS'
+
+        edmList.extend([
+            (typeName,    thisCollectionHLTNavEDMTargets, 'Steer'),
+            (typeNameAux, thisCollectionHLTNavEDMTargets, 'Steer')])
 
 def addExtraCollectionsToEDMList(edmList, extraList):
     """
diff --git a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigGetter.py b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigGetter.py
index 1920077623e1cfee9b90b6d6dd1e921ca7352cfe..fb5793aad61fdae1a9be4fc99afa57a8c263772a 100644
--- a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigGetter.py
+++ b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigGetter.py
@@ -242,6 +242,14 @@ class TriggerConfigGetter(Configured):
                 if not hasattr(svcMgr, 'xAODConfigSvc'):
                     from TrigConfxAOD.TrigConfxAODConf import TrigConf__xAODConfigSvc
                     svcMgr += TrigConf__xAODConfigSvc('xAODConfigSvc')
+            else: # Does not have xAODMeta
+                # Run-3 Trigger Configuration Services (just producing menu data)
+                from TrigConfigSvc.TrigConfigSvcCfg import getL1ConfigSvc, getHLTConfigSvc
+                from TrigConfigSvc.TrigConfigSvcConfig import TrigConfigSvc
+                svcMgr += getL1ConfigSvc(ConfigFlags)
+                svcMgr += getHLTConfigSvc(ConfigFlags)
+                svcMgr += TrigConfigSvc("TrigConfigSvc")
+                svcMgr.TrigConfigSvc.UseNewConfig = True
 
         else:
             # non-MT (Run-2) Trigger Configuration