diff --git a/Control/AthenaConfiguration/python/AllConfigFlags.py b/Control/AthenaConfiguration/python/AllConfigFlags.py
index 6e5f000a0696b62b58d9074eef774ff6aa09b3f8..55a9a8c721b4a250664afa818f95964b5d464299 100644
--- a/Control/AthenaConfiguration/python/AllConfigFlags.py
+++ b/Control/AthenaConfiguration/python/AllConfigFlags.py
@@ -163,7 +163,7 @@ def _createCfgFlags():
 
 #Simulation Flags:
     def __simulation():
-        from G4AtlasApps.SimConfigFlags import createSimConfigFlags
+        from SimulationConfig.SimConfigFlags import createSimConfigFlags
         return createSimConfigFlags()
     _addFlagsCategory (acf, "Sim", __simulation, 'G4AtlasApps' )
 
diff --git a/Event/xAOD/xAODTrigL1Calo/CMakeLists.txt b/Event/xAOD/xAODTrigL1Calo/CMakeLists.txt
index 6a2a6963d715c008cbd8331970d3470946c7c228..31a1d64c0d4c684ba7b48b6cdf89f7f45f6cff0d 100644
--- a/Event/xAOD/xAODTrigL1Calo/CMakeLists.txt
+++ b/Event/xAOD/xAODTrigL1Calo/CMakeLists.txt
@@ -30,6 +30,7 @@ atlas_add_xaod_smart_pointer_dicts(
               "xAOD::CPMTowerContainer_v2" "xAOD::CPMTobRoIContainer_v1"
               "xAOD::JEMEtSumsContainer_v2" "xAOD::JEMTobRoIContainer_v1"
               "xAOD::JetElementContainer_v2" "xAOD::L1TopoRawDataContainer_v1"
+              "xAOD::eFexTowerContainer_v1"
    OBJECTS "xAOD::CMMRoI_v1" )
 
 atlas_add_dictionary( xAODTrigL1CaloDict
diff --git a/Event/xAOD/xAODTrigL1Calo/Root/dict/ContainerProxies.cxx b/Event/xAOD/xAODTrigL1Calo/Root/dict/ContainerProxies.cxx
index a5c79bb7b59d4c00c3f00079a7807311e31e975b..55291e5500cf3f55dab22f31e112527d5511e332 100644
--- a/Event/xAOD/xAODTrigL1Calo/Root/dict/ContainerProxies.cxx
+++ b/Event/xAOD/xAODTrigL1Calo/Root/dict/ContainerProxies.cxx
@@ -47,6 +47,8 @@
 
 #include "xAODTrigL1Calo/versions/L1TopoRawDataContainer_v1.h"
 
+#include "xAODTrigL1Calo/versions/eFexTowerContainer_v1.h"
+
 // Set up the collection proxies:
 // Run 1
 ADD_NS_DV_PROXY( xAOD , JEMHitsContainer_v1 );
@@ -84,3 +86,5 @@ ADD_NS_DV_PROXY( xAOD , JEMTobRoIContainer_v1 );
 ADD_NS_DV_PROXY( xAOD , JetElementContainer_v2 );
 
 ADD_NS_DV_PROXY( xAOD , L1TopoRawDataContainer_v1 );
+
+ADD_NS_DV_PROXY( xAOD , eFexTowerContainer_v1 );
diff --git a/Event/xAOD/xAODTrigL1Calo/Root/eFexTowerAuxContainer_v1.cxx b/Event/xAOD/xAODTrigL1Calo/Root/eFexTowerAuxContainer_v1.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c236f0c5fdcdc8c2b033bf3748620b9dc088da38
--- /dev/null
+++ b/Event/xAOD/xAODTrigL1Calo/Root/eFexTowerAuxContainer_v1.cxx
@@ -0,0 +1,23 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+// Local include(s):
+#include "xAODTrigL1Calo/versions/eFexTowerAuxContainer_v1.h"
+
+namespace xAOD {
+
+  eFexTowerAuxContainer_v1::eFexTowerAuxContainer_v1() :
+    AuxContainerBase()
+    {
+    
+    AUX_VARIABLE( eta );           
+    AUX_VARIABLE( phi );
+    AUX_VARIABLE( module );
+    AUX_VARIABLE( fpga );
+    AUX_VARIABLE( et_count );
+    AUX_VARIABLE( em_status );
+    AUX_VARIABLE( had_status );
+    }
+
+} // namespace xAOD
diff --git a/Event/xAOD/xAODTrigL1Calo/Root/eFexTower_v1.cxx b/Event/xAOD/xAODTrigL1Calo/Root/eFexTower_v1.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ceef2b0bab2f9f55404daa9b2678811e1dfd755a
--- /dev/null
+++ b/Event/xAOD/xAODTrigL1Calo/Root/eFexTower_v1.cxx
@@ -0,0 +1,46 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+// EDM includes(s):
+#include "xAODCore/AuxStoreAccessorMacros.h"
+
+// Local include(s):
+#include "xAODTrigL1Calo/versions/eFexTower_v1.h"
+
+namespace xAOD{  
+
+  AUXSTORE_OBJECT_SETTER_AND_GETTER( eFexTower_v1 , std::vector<uint16_t> , et_count , setEt_count )
+  AUXSTORE_OBJECT_MOVE( eFexTower_v1 , std::vector<uint16_t> , et_count , setEt_count )
+  AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( eFexTower_v1, float , eta , setEta )
+  AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( eFexTower_v1, float , phi , setPhi )
+  AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( eFexTower_v1, uint32_t , module , setModule )
+  AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( eFexTower_v1, uint8_t , fpga , setFpga )
+  AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( eFexTower_v1, uint32_t , em_status , setEm_status )
+  AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( eFexTower_v1, uint32_t , had_status , setHad_status )  
+  
+  
+  /// initialize
+  void eFexTower_v1::initialize(const float Eta,const float Phi)
+  {
+    setEta( Eta );
+    setPhi( Phi );    
+  }
+  
+  void eFexTower_v1::initialize(const float Eta,const float Phi,
+                                   const std::vector<uint16_t>& Et_count,
+                                   const uint32_t Module,
+                                   const uint8_t Fpga,
+                                   const uint32_t Em_status,
+				   const uint32_t Had_status)
+  {
+    setEta( Eta );
+    setPhi( Phi );
+    setEt_count( Et_count );
+    setModule( Module );
+    setFpga( Fpga );
+    setEm_status( Em_status );
+    setHad_status( Had_status );
+  }
+
+} // namespace xAOD
diff --git a/Event/xAOD/xAODTrigL1Calo/Root/xAODTrigL1CaloCLIDs.cxx b/Event/xAOD/xAODTrigL1Calo/Root/xAODTrigL1CaloCLIDs.cxx
index e5119c99f924cd42c4408c89f9a15695c5f4f541..a73705a31955dfdae11adc86da90cf0b8debf16c 100644
--- a/Event/xAOD/xAODTrigL1Calo/Root/xAODTrigL1CaloCLIDs.cxx
+++ b/Event/xAOD/xAODTrigL1Calo/Root/xAODTrigL1CaloCLIDs.cxx
@@ -46,3 +46,5 @@
 #include "xAODTrigL1Calo/RODHeaderContainer.h"
 #include "xAODTrigL1Calo/TriggerTowerAuxContainer.h"
 #include "xAODTrigL1Calo/TriggerTowerContainer.h"
+#include "xAODTrigL1Calo/eFexTowerAuxContainer.h"
+#include "xAODTrigL1Calo/eFexTowerContainer.h"
diff --git a/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/eFexTower.h b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/eFexTower.h
new file mode 100644
index 0000000000000000000000000000000000000000..52b87533743173f42438e51d7764099176315ee6
--- /dev/null
+++ b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/eFexTower.h
@@ -0,0 +1,22 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef XAODTRIGL1CALO_EFEXTOWER_H
+#define XAODTRIGL1CALO_EFEXTOWER_H
+
+// Local include(s):
+#include "xAODTrigL1Calo/versions/eFexTower_v1.h"
+#include <map>
+
+/// Namespace holding all the xAOD EDM classes
+namespace xAOD {
+   /// Define the latest version of the TriggerTower class
+   typedef eFexTower_v1 eFexTower;
+
+}
+
+#include "xAODCore/CLASS_DEF.h"
+CLASS_DEF( xAOD::eFexTower , 143961138 , 1 )
+
+#endif // XAODTRIGL1CALO_EFEXTOWER_H
diff --git a/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/eFexTowerAuxContainer.h b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/eFexTowerAuxContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..54b1866ce7002f04ddba6d826bbff17be57bfa3a
--- /dev/null
+++ b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/eFexTowerAuxContainer.h
@@ -0,0 +1,19 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef XAODTRIGL1CALO_EFEXTOWERAUXCONTAINER_H
+#define XAODTRIGL1CALO_EFEXTOWERAUXCONTAINER_H
+
+// Local include(s):
+#include "xAODTrigL1Calo/versions/eFexTowerAuxContainer_v1.h"
+
+namespace xAOD {
+   /// Define the latest version of the TriggerTower auxiliary container
+   typedef eFexTowerAuxContainer_v1 eFexTowerAuxContainer;
+}
+
+#include "xAODCore/CLASS_DEF.h"
+CLASS_DEF( xAOD::eFexTowerAuxContainer , 1115941149 , 1 )
+
+#endif // XAODTRIGL1CALO_EFEXTOWERAUXCONTAINER_H
diff --git a/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/eFexTowerContainer.h b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/eFexTowerContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..2155504bfb41337abb95ab849d8fef9bc002306b
--- /dev/null
+++ b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/eFexTowerContainer.h
@@ -0,0 +1,20 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef XAODTRIGL1CALO_EFEXTOWERCONTAINER_H
+#define XAODTRIGL1CALO_EFEXTOWERCONTAINER_H
+
+// Local include(s):
+#include "xAODTrigL1Calo/eFexTower.h"
+#include "xAODTrigL1Calo/versions/eFexTowerContainer_v1.h"
+
+namespace xAOD {
+   /// Define the latest version of the TriggerTower container
+   typedef eFexTowerContainer_v1 eFexTowerContainer;
+}
+
+#include "xAODCore/CLASS_DEF.h"
+CLASS_DEF( xAOD::eFexTowerContainer , 1159375134 , 1 )
+
+#endif // XAODTRIGL1CALO_EFEXTOWERCONTAINER_H
diff --git a/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/selection.xml b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/selection.xml
index 59b25e1ecbc4cafe4a4300b03159fb53ff9ac4d2..a89299514405360deab3070d22acb7e7adaff7a6 100644
--- a/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/selection.xml
+++ b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/selection.xml
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -->
+<!-- Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration -->
 <lcgdict>
 
   <!-- Run1 EDM -->
@@ -375,4 +375,16 @@
   <typedef name="xAOD::L1TopoRawDataContainer" />
   <typedef name="xAOD::L1TopoRawDataAuxContainer" />
 
+  <!-- eFexTower -->
+  <typedef name="xAOD::eFexTower" />
+  <typedef name="xAOD::eFexTowerContainer" />
+  <typedef name="xAOD::eFexTowerAuxContainer" />
+
+  <class name="xAOD::eFexTower_v1" />
+  <class name="xAOD::eFexTowerContainer_v1"
+         id="A67E76AF-85DA-474F-B179-9AB6D8710492" />
+  <class name="xAOD::eFexTowerAuxContainer_v1"
+         id="09BA68B9-3BCB-47B0-8E6A-8E5E12897209" />
+
+
 </lcgdict>
diff --git a/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/versions/eFexTowerAuxContainer_v1.h b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/versions/eFexTowerAuxContainer_v1.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e022201bae95329421175f4501cbee02ca01604
--- /dev/null
+++ b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/versions/eFexTowerAuxContainer_v1.h
@@ -0,0 +1,43 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef XAODTRIGL1CALO_VERSIONS_EFEXTOWERAUXCONTAINER_V1_H
+#define XAODTRIGL1CALO_VERSIONS_EFEXTOWERAUXCONTAINER_V1_H
+
+// STL include(s):
+#include <vector>
+// System include(s):
+#include <stdint.h>
+
+// EDM include(s):
+#include "xAODCore/AuxContainerBase.h"
+
+namespace xAOD{
+
+  /// AuxContainer for eFexTower_v1
+
+  class eFexTowerAuxContainer_v1 : public AuxContainerBase {
+  public:
+    // Default constructor
+    eFexTowerAuxContainer_v1();
+    
+  private:   
+    
+    std::vector<float> eta;           
+    std::vector<float> phi; 
+    std::vector<uint32_t> module;
+    std::vector<uint8_t> fpga;
+
+    std::vector<std::vector<uint16_t> > et_count;
+
+    std::vector<uint32_t> em_status;
+    std::vector<uint32_t> had_status;
+    
+  }; // class eFexTowerAuxContainer_v1 
+} // namespace xAOD
+
+#include "xAODCore/BaseInfo.h"
+SG_BASE( xAOD::eFexTowerAuxContainer_v1, xAOD::AuxContainerBase );
+
+#endif // XAODTRIGL1CALO_VERSIONS_EFEXTOWERAUXCONTAINER_V1_H
diff --git a/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/versions/eFexTowerContainer_v1.h b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/versions/eFexTowerContainer_v1.h
new file mode 100644
index 0000000000000000000000000000000000000000..3376e5d6279cf342f8e51a7b8b55680688bab5ab
--- /dev/null
+++ b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/versions/eFexTowerContainer_v1.h
@@ -0,0 +1,19 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef XAODTRIGL1CALO_VERSIONS_EFEXTOWERCONTAINER_V1_H
+#define XAODTRIGL1CALO_VERSIONS_EFEXTOWERCONTAINER_V1_H
+
+// EDM include(s):
+#include "AthContainers/DataVector.h"
+
+// Local include(s):
+#include "xAODTrigL1Calo/versions/eFexTower_v1.h"
+
+namespace xAOD {
+   /// Define the TriggerTower as a simple DataVector
+   typedef DataVector< xAOD::eFexTower_v1 > eFexTowerContainer_v1;
+}
+
+#endif // XAODTRIGL1CALO_VERSIONS_EFEXTOWERCONTAINER_V1_H
diff --git a/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/versions/eFexTower_v1.h b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/versions/eFexTower_v1.h
new file mode 100644
index 0000000000000000000000000000000000000000..15f44044e2f01b6b6639a5540f4be9684fc481ca
--- /dev/null
+++ b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/versions/eFexTower_v1.h
@@ -0,0 +1,78 @@
+/*
+   Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+#ifndef XAODTRIGL1CALO_VERSIONS_EFEXTOWER_V1_H
+#define XAODTRIGL1CALO_VERSIONS_EFEXTOWER_V1_H
+
+// EDM include(s):
+#include "AthLinks/ElementLink.h"
+#include "AthContainers/AuxElement.h"
+
+// System include(s):
+#include <stdint.h>
+
+// ROOT include(s):
+#include "Math/Vector4D.h"
+
+namespace xAOD {
+
+   /// Class describing input data of a LVL1 eFEX
+   //  in the xAOD format.
+ 
+    class eFexTower_v1 : public SG::AuxElement{
+    public:
+
+      /// Inherit all of the base class's constructors 
+      using SG::AuxElement::AuxElement;
+
+      /// @brief The pseudorapidity (\f$\eta\f$)
+      float eta() const; /// getter for the global eta value (float)
+      void setEta(float); /// setter for the above
+
+      /// @brief The azimuthal angle (\f$\phi\f$)     
+      float phi() const; /// getter for the global phi value (float)
+      void setPhi(float); /// setter for the above
+
+      /// get module number
+      uint32_t module() const; /// getter for the module number [0-23] inclusive
+      /// set module number
+      void setModule(uint32_t); /// setter for the above
+
+      /// get fpga number
+      uint8_t fpga() const; /// getter for the fpga number [0-3] inclusive
+      ///  set fpga number
+      void setFpga(uint8_t); /// setter for the above
+      
+      /// get Energy Counts
+      const std::vector<uint16_t>& et_count() const; /// getter for the 11 energy counts
+      /// set Energy Counts
+      void setEt_count(const std::vector<uint16_t>&); /// setter for the above
+      void setEt_count(std::vector<uint16_t>&&); /// setter for the above
+
+      /// get em status bit
+      uint32_t em_status() const; /// getter for the electromagnetic status bit
+      /// set em status bit
+      void setEm_status(uint32_t); /// setter for the above
+      
+      /// get em status bit
+      uint32_t had_status() const; /// getter for hadronic status bit
+      /// set em status bit
+      void setHad_status(uint32_t); /// setter for the above
+
+      void initialize(const float Eta,const float Phi);
+      void initialize(const float Eta,const float Phi,
+                                   const std::vector<uint16_t>& Et_count,
+                                   const uint32_t Module,
+                                   const uint8_t Fpga,
+                                   const uint32_t Em_status,
+                                   const uint32_t Had_status);
+    
+    private:
+        
+  }; // class eFexTower_v1
+} // namespace xAOD
+
+// Declare the inheritance of the type:
+#include "xAODCore/BaseInfo.h"
+SG_BASE( xAOD::eFexTower_v1, SG::AuxElement );
+#endif // XAODTRIGL1CALO_VERSIONS_EFEXTOWER_V1_H
diff --git a/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/xAODTrigL1CaloDict.h b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/xAODTrigL1CaloDict.h
index 1fd5dff95c02dfbcb87f8f61cf6020d766684aee..262d607b612b94a88f97da286dee598d874b152e 100644
--- a/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/xAODTrigL1CaloDict.h
+++ b/Event/xAOD/xAODTrigL1Calo/xAODTrigL1Calo/xAODTrigL1CaloDict.h
@@ -1,6 +1,5 @@
-// Dear emacs, this is -*- c++ -*-
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 #ifndef XAODTRIGL1CALO_XAODTRIGL1CALOCALOEVENTDICT_H
 #define XAODTRIGL1CALO_XAODTRIGL1CALOCALOEVENTDICT_H
@@ -197,6 +196,12 @@
 #include "xAODTrigL1Calo/versions/GBlockContainer_v1.h"
 #include "xAODTrigL1Calo/versions/GBlockAuxContainer_v1.h"
 
+#include "xAODTrigL1Calo/eFexTower.h"
+#include "xAODTrigL1Calo/eFexTowerContainer.h"
+#include "xAODTrigL1Calo/eFexTowerAuxContainer.h"
+#include "xAODTrigL1Calo/versions/eFexTower_v1.h"
+#include "xAODTrigL1Calo/versions/eFexTowerContainer_v1.h"
+#include "xAODTrigL1Calo/versions/eFexTowerAuxContainer_v1.h"
 
 // EDM include(s).
 #include "xAODCore/tools/DictHelpers.h"
@@ -271,6 +276,8 @@ namespace {
     XAOD_INSTANTIATE_NS_CONTAINER_TYPES( xAOD, JGTowerContainer_v1 );
     // GBlock
     XAOD_INSTANTIATE_NS_CONTAINER_TYPES( xAOD, GBlockContainer_v1 );
+    // eFexTower
+    XAOD_INSTANTIATE_NS_CONTAINER_TYPES( xAOD, eFexTowerContainer_v1 );
   };
 }
 
diff --git a/Event/xAOD/xAODTrigL1CaloAthenaPool/CMakeLists.txt b/Event/xAOD/xAODTrigL1CaloAthenaPool/CMakeLists.txt
index 7708a7d594820d43ee63ba81805bfd68f3389cdf..cb57faa143a9d8a8ac924caf9ff61dcde592e88e 100644
--- a/Event/xAOD/xAODTrigL1CaloAthenaPool/CMakeLists.txt
+++ b/Event/xAOD/xAODTrigL1CaloAthenaPool/CMakeLists.txt
@@ -6,7 +6,7 @@ atlas_subdir( xAODTrigL1CaloAthenaPool )
 # Component(s) in the package:
 atlas_add_poolcnv_library( xAODTrigL1CaloAthenaPoolPoolCnv
                            src/*.cxx
-                           FILES xAODTrigL1Calo/JEMHitsContainer.h xAODTrigL1Calo/JEMHitsAuxContainer.h xAODTrigL1Calo/JEMEtSumsContainer.h xAODTrigL1Calo/JEMEtSumsAuxContainer.h xAODTrigL1Calo/JEMRoIContainer.h xAODTrigL1Calo/JEMRoIAuxContainer.h xAODTrigL1Calo/CPMHitsContainer.h xAODTrigL1Calo/CPMHitsAuxContainer.h xAODTrigL1Calo/CPMTowerContainer.h xAODTrigL1Calo/CPMTowerAuxContainer.h xAODTrigL1Calo/CPMRoIContainer.h xAODTrigL1Calo/CPMRoIAuxContainer.h xAODTrigL1Calo/CMMCPHitsContainer.h xAODTrigL1Calo/CMMCPHitsAuxContainer.h xAODTrigL1Calo/CMMEtSumsContainer.h xAODTrigL1Calo/CMMEtSumsAuxContainer.h xAODTrigL1Calo/CMMJetHitsContainer.h xAODTrigL1Calo/CMMJetHitsAuxContainer.h xAODTrigL1Calo/CMMRoI.h xAODTrigL1Calo/CMMRoIAuxInfo.h xAODTrigL1Calo/JetElementContainer.h xAODTrigL1Calo/JetElementAuxContainer.h xAODTrigL1Calo/RODHeaderContainer.h xAODTrigL1Calo/RODHeaderAuxContainer.h xAODTrigL1Calo/TriggerTowerContainer.h xAODTrigL1Calo/TriggerTowerAuxContainer.h xAODTrigL1Calo/CMXCPHitsContainer.h xAODTrigL1Calo/CMXCPHitsAuxContainer.h xAODTrigL1Calo/CMXCPTobContainer.h xAODTrigL1Calo/CMXCPTobAuxContainer.h xAODTrigL1Calo/CMXJetHitsContainer.h xAODTrigL1Calo/CMXJetHitsAuxContainer.h xAODTrigL1Calo/CMXJetTobContainer.h xAODTrigL1Calo/CMXJetTobAuxContainer.h xAODTrigL1Calo/CMXEtSumsContainer.h xAODTrigL1Calo/CMXEtSumsAuxContainer.h xAODTrigL1Calo/CMXRoIContainer.h xAODTrigL1Calo/CMXRoIAuxContainer.h xAODTrigL1Calo/CPMTobRoIContainer.h xAODTrigL1Calo/CPMTobRoIAuxContainer.h xAODTrigL1Calo/JEMTobRoIContainer.h xAODTrigL1Calo/JEMTobRoIAuxContainer.h xAODTrigL1Calo/L1TopoRawDataContainer.h xAODTrigL1Calo/L1TopoRawDataAuxContainer.h xAODTrigL1Calo/JGTowerContainer.h xAODTrigL1Calo/JGTowerAuxContainer.h xAODTrigL1Calo/GBlockContainer.h xAODTrigL1Calo/GBlockAuxContainer.h
-                           TYPES_WITH_NAMESPACE xAOD::JEMHitsContainer xAOD::JEMHitsAuxContainer xAOD::JEMEtSumsContainer xAOD::JEMEtSumsAuxContainer xAOD::JEMRoIContainer xAOD::JEMRoIAuxContainer xAOD::CPMHitsContainer xAOD::CPMHitsAuxContainer xAOD::CPMTowerContainer xAOD::CPMTowerAuxContainer xAOD::CPMRoIContainer xAOD::CPMRoIAuxContainer xAOD::CMMCPHitsContainer xAOD::CMMCPHitsAuxContainer xAOD::CMMEtSumsContainer xAOD::CMMEtSumsAuxContainer xAOD::CMMJetHitsContainer xAOD::CMMJetHitsAuxContainer xAOD::CMMRoI xAOD::CMMRoIAuxInfo xAOD::JetElementContainer xAOD::JetElementAuxContainer xAOD::RODHeaderContainer xAOD::RODHeaderAuxContainer xAOD::TriggerTowerContainer xAOD::TriggerTowerAuxContainer xAOD::CMXCPHitsContainer xAOD::CMXCPHitsAuxContainer xAOD::CMXCPTobContainer xAOD::CMXCPTobAuxContainer xAOD::CMXJetHitsContainer xAOD::CMXJetHitsAuxContainer xAOD::CMXJetTobContainer xAOD::CMXJetTobAuxContainer xAOD::CMXEtSumsContainer xAOD::CMXEtSumsAuxContainer xAOD::CMXRoIContainer xAOD::CMXRoIAuxContainer xAOD::CPMTobRoIContainer xAOD::CPMTobRoIAuxContainer xAOD::JEMTobRoIContainer xAOD::JEMTobRoIAuxContainer xAOD::L1TopoRawDataContainer xAOD::L1TopoRawDataAuxContainer xAOD::JGTowerContainer xAOD::JGTowerAuxContainer xAOD::GBlockContainer xAOD::GBlockAuxContainer
+                           FILES xAODTrigL1Calo/eFexTowerContainer.h xAODTrigL1Calo/eFexTowerAuxContainer.h xAODTrigL1Calo/JEMHitsContainer.h xAODTrigL1Calo/JEMHitsAuxContainer.h xAODTrigL1Calo/JEMEtSumsContainer.h xAODTrigL1Calo/JEMEtSumsAuxContainer.h xAODTrigL1Calo/JEMRoIContainer.h xAODTrigL1Calo/JEMRoIAuxContainer.h xAODTrigL1Calo/CPMHitsContainer.h xAODTrigL1Calo/CPMHitsAuxContainer.h xAODTrigL1Calo/CPMTowerContainer.h xAODTrigL1Calo/CPMTowerAuxContainer.h xAODTrigL1Calo/CPMRoIContainer.h xAODTrigL1Calo/CPMRoIAuxContainer.h xAODTrigL1Calo/CMMCPHitsContainer.h xAODTrigL1Calo/CMMCPHitsAuxContainer.h xAODTrigL1Calo/CMMEtSumsContainer.h xAODTrigL1Calo/CMMEtSumsAuxContainer.h xAODTrigL1Calo/CMMJetHitsContainer.h xAODTrigL1Calo/CMMJetHitsAuxContainer.h xAODTrigL1Calo/CMMRoI.h xAODTrigL1Calo/CMMRoIAuxInfo.h xAODTrigL1Calo/JetElementContainer.h xAODTrigL1Calo/JetElementAuxContainer.h xAODTrigL1Calo/RODHeaderContainer.h xAODTrigL1Calo/RODHeaderAuxContainer.h xAODTrigL1Calo/TriggerTowerContainer.h xAODTrigL1Calo/TriggerTowerAuxContainer.h xAODTrigL1Calo/CMXCPHitsContainer.h xAODTrigL1Calo/CMXCPHitsAuxContainer.h xAODTrigL1Calo/CMXCPTobContainer.h xAODTrigL1Calo/CMXCPTobAuxContainer.h xAODTrigL1Calo/CMXJetHitsContainer.h xAODTrigL1Calo/CMXJetHitsAuxContainer.h xAODTrigL1Calo/CMXJetTobContainer.h xAODTrigL1Calo/CMXJetTobAuxContainer.h xAODTrigL1Calo/CMXEtSumsContainer.h xAODTrigL1Calo/CMXEtSumsAuxContainer.h xAODTrigL1Calo/CMXRoIContainer.h xAODTrigL1Calo/CMXRoIAuxContainer.h xAODTrigL1Calo/CPMTobRoIContainer.h xAODTrigL1Calo/CPMTobRoIAuxContainer.h xAODTrigL1Calo/JEMTobRoIContainer.h xAODTrigL1Calo/JEMTobRoIAuxContainer.h xAODTrigL1Calo/L1TopoRawDataContainer.h xAODTrigL1Calo/L1TopoRawDataAuxContainer.h xAODTrigL1Calo/JGTowerContainer.h xAODTrigL1Calo/JGTowerAuxContainer.h xAODTrigL1Calo/GBlockContainer.h xAODTrigL1Calo/GBlockAuxContainer.h
+                           TYPES_WITH_NAMESPACE xAOD::eFexTowerContainer xAOD::eFexTowerAuxContainer xAOD::JEMHitsContainer xAOD::JEMHitsAuxContainer xAOD::JEMEtSumsContainer xAOD::JEMEtSumsAuxContainer xAOD::JEMRoIContainer xAOD::JEMRoIAuxContainer xAOD::CPMHitsContainer xAOD::CPMHitsAuxContainer xAOD::CPMTowerContainer xAOD::CPMTowerAuxContainer xAOD::CPMRoIContainer xAOD::CPMRoIAuxContainer xAOD::CMMCPHitsContainer xAOD::CMMCPHitsAuxContainer xAOD::CMMEtSumsContainer xAOD::CMMEtSumsAuxContainer xAOD::CMMJetHitsContainer xAOD::CMMJetHitsAuxContainer xAOD::CMMRoI xAOD::CMMRoIAuxInfo xAOD::JetElementContainer xAOD::JetElementAuxContainer xAOD::RODHeaderContainer xAOD::RODHeaderAuxContainer xAOD::TriggerTowerContainer xAOD::TriggerTowerAuxContainer xAOD::CMXCPHitsContainer xAOD::CMXCPHitsAuxContainer xAOD::CMXCPTobContainer xAOD::CMXCPTobAuxContainer xAOD::CMXJetHitsContainer xAOD::CMXJetHitsAuxContainer xAOD::CMXJetTobContainer xAOD::CMXJetTobAuxContainer xAOD::CMXEtSumsContainer xAOD::CMXEtSumsAuxContainer xAOD::CMXRoIContainer xAOD::CMXRoIAuxContainer xAOD::CPMTobRoIContainer xAOD::CPMTobRoIAuxContainer xAOD::JEMTobRoIContainer xAOD::JEMTobRoIAuxContainer xAOD::L1TopoRawDataContainer xAOD::L1TopoRawDataAuxContainer xAOD::JGTowerContainer xAOD::JGTowerAuxContainer xAOD::GBlockContainer xAOD::GBlockAuxContainer
                            CNV_PFX xAOD
                            LINK_LIBRARIES AthContainers AthenaKernel AthenaPoolCnvSvcLib GaudiKernel xAODTrigL1Calo )
diff --git a/Generators/TrackRecordGenerator/python/TrackRecordGeneratorConfigNew.py b/Generators/TrackRecordGenerator/python/TrackRecordGeneratorConfigNew.py
index 95e07a7c76e2ece3fa58ba4d7dfe6b3bce0809b3..05f4384d4c7c0f85933c28b6f151e35c7058a4aa 100644
--- a/Generators/TrackRecordGenerator/python/TrackRecordGeneratorConfigNew.py
+++ b/Generators/TrackRecordGenerator/python/TrackRecordGeneratorConfigNew.py
@@ -12,7 +12,7 @@ def Input_TrackRecordGeneratorCfg(ConfigFlags,name="TrackRecordGenerator", **kwa
     TrackRecordGenerator=CompFactory.TrackRecordGenerator
 
     kwargs = {}
-    from G4AtlasApps.SimEnums import CavernBackground
+    from SimulationConfig.SimEnums import CavernBackground
     if ConfigFlags.Sim.CavernBackground is CavernBackground.Read:
         kwargs.setdefault('TRSmearing', -1) #in millimeters, e.g. 10
         kwargs.setdefault('TRPSmearing', -1) #in radians, e.g. 0.01
diff --git a/LArCalorimeter/LArG4/LArG4SD/python/LArG4SDToolConfig.py b/LArCalorimeter/LArG4/LArG4SD/python/LArG4SDToolConfig.py
index 56d2e600459f3dab1bbd5b41ac9ccddc274069b1..040938c398cac42e32f12869f546b70f4970977e 100644
--- a/LArCalorimeter/LArG4/LArG4SD/python/LArG4SDToolConfig.py
+++ b/LArCalorimeter/LArG4/LArG4SD/python/LArG4SDToolConfig.py
@@ -2,7 +2,7 @@
 
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
-from G4AtlasApps.SimEnums import CalibrationRun, LArParameterization
+from SimulationConfig.SimEnums import CalibrationRun, LArParameterization
 from ISF_Algorithms.CollectionMergerConfig import CollectionMergerCfg
 
 #to be migrated: getCalibrationDefaultCalculator, getDeadMaterialCalibrationHitMerger
diff --git a/Projects/AthSimulation/package_filters.txt b/Projects/AthSimulation/package_filters.txt
index 33416ef16e261f093e4fc1a59167aa07f09da5ce..efe997f0b6439e580e54128ef52306212a316f85 100644
--- a/Projects/AthSimulation/package_filters.txt
+++ b/Projects/AthSimulation/package_filters.txt
@@ -342,6 +342,7 @@
 + Simulation/RunDependentSim/RunDependentSimData
 + Simulation/RunDependentSim/RunDependentSimComps
 + Simulation/SimuJobTransforms
++ Simulation/SimulationConfig
 + Simulation/SimulationJobOptions
 + Simulation/Tests/ISF_Validation
 + Simulation/Tests/SimExoticsTests
diff --git a/Simulation/Barcode/BarcodeServices/python/BarcodeServicesConfigNew.py b/Simulation/Barcode/BarcodeServices/python/BarcodeServicesConfigNew.py
index 4da8a0bc6155d7f8f9e8fcc4173023e4a1411d96..bb8b27fd558856b469df2bf8e0fc881e99323255 100644
--- a/Simulation/Barcode/BarcodeServices/python/BarcodeServicesConfigNew.py
+++ b/Simulation/Barcode/BarcodeServices/python/BarcodeServicesConfigNew.py
@@ -8,7 +8,7 @@ from AthenaConfiguration.ComponentFactory import CompFactory
 
 def BarcodeSvcCfg(ConfigFlags, **kwargs):
     """Return the MCxBarcodeSvcCfg config flagged by Sim.TruthStrategy"""
-    from G4AtlasApps.SimEnums import TruthStrategy
+    from SimulationConfig.SimEnums import TruthStrategy
     stratmap = {
         TruthStrategy.MC12: MC12BarcodeSvcCfg,
         TruthStrategy.MC12LLP: MC12LLPBarcodeSvcCfg,
diff --git a/Simulation/BeamEffects/python/BeamEffectsAlgConfig.py b/Simulation/BeamEffects/python/BeamEffectsAlgConfig.py
index 94dbd8dbe21306f8ebe6e5489cef2b9d9de6bfcc..c4a4d7c524d6bceae684ff732b014951065ae069 100755
--- a/Simulation/BeamEffects/python/BeamEffectsAlgConfig.py
+++ b/Simulation/BeamEffects/python/BeamEffectsAlgConfig.py
@@ -42,7 +42,7 @@ def GenEventVertexPositionerCfg(flags, name="GenEventVertexPositioner", **kwargs
 
     acc = ComponentAccumulator()
 
-    from G4AtlasApps.SimEnums import VertexSource
+    from SimulationConfig.SimEnums import VertexSource
     readVtxPosFromFile = flags.Sim.VertexSource in [VertexSource.VertexOverrideFile, VertexSource.VertexOverrideEventFile]
     if readVtxPosFromFile:
         kwargs.setdefault("VertexShifters", [acc.popToolsAndMerge(VertexPositionFromFileCfg(flags))])
@@ -111,7 +111,7 @@ def BeamEffectsAlgCfg(flags, name="BeamEffectsAlg", **kwargs):
     # Set (todo) the appropriate manipulator tools
     manipulators = []
     manipulators.append(acc.popToolsAndMerge(ValidityCheckerCfg(flags)))
-    from G4AtlasApps.SimEnums import CavernBackground
+    from SimulationConfig.SimEnums import CavernBackground
     if flags.Beam.Type is not BeamType.Cosmics and flags.Sim.CavernBackground is not CavernBackground.Read:
         manipulators.append(acc.popToolsAndMerge(GenEventVertexPositionerCfg(flags)))
     # manipulators.append(acc.popToolsAndMerge(GenEventBeamEffectBoosterCfg(flags))) # todo segmentation violation
@@ -187,7 +187,7 @@ if __name__ == "__main__":
     ConfigFlags.Output.HITSFileName = "myHITS.pool.root"
 
     #set the source of vertex positioning
-    from G4AtlasApps.SimEnums import VertexSource
+    from SimulationConfig.SimEnums import VertexSource
     #ConfigFlags.Sim.VertexSource = VertexSource.VertexOverrideFile
     ConfigFlags.Sim.VertexSource = VertexSource.CondDB
     #ConfigFlags.Sim.VertexSource = VertexSource.LongBeamspotVertexPositioner"
diff --git a/Simulation/G4Atlas/G4AtlasAlg/python/G4AtlasAlgConfigNew.py b/Simulation/G4Atlas/G4AtlasAlg/python/G4AtlasAlgConfigNew.py
index f3e0ea4ef82adf79a99ead24dceb220a91c7ec56..0272189909e8fe3f4e7e2dc7edb9720542142bb4 100644
--- a/Simulation/G4Atlas/G4AtlasAlg/python/G4AtlasAlgConfigNew.py
+++ b/Simulation/G4Atlas/G4AtlasAlg/python/G4AtlasAlgConfigNew.py
@@ -4,7 +4,7 @@ from ISF_Services.ISF_ServicesConfigNew import TruthServiceCfg, InputConverterCf
 from ISF_Services.ISF_ServicesCoreConfigNew import GeoIDSvcCfg
 from G4AtlasTools.G4AtlasToolsConfigNew import SensitiveDetectorMasterToolCfg, FastSimulationMasterToolCfg
 from G4AtlasServices.G4AtlasUserActionConfigNew import UserActionSvcCfg
-from G4AtlasApps.G4Atlas_MetadataNew import writeSimulationParametersMetadata
+from SimulationConfig.SimulationMetadata import writeSimulationParametersMetadata
 from AthenaConfiguration.ComponentFactory import CompFactory
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 
diff --git a/Simulation/G4Atlas/G4AtlasAlg/test/G4AtlasAlgConfigNew_Test.py b/Simulation/G4Atlas/G4AtlasAlg/test/G4AtlasAlgConfigNew_Test.py
index 639984c13755f176bd0215e5d93fc3fa70ff460b..fa8b29b437627ff167362e2530a680fe70e8bad9 100755
--- a/Simulation/G4Atlas/G4AtlasAlg/test/G4AtlasAlgConfigNew_Test.py
+++ b/Simulation/G4Atlas/G4AtlasAlg/test/G4AtlasAlgConfigNew_Test.py
@@ -35,7 +35,7 @@ if __name__ == '__main__':
     #Sim ConfigFlags
     #ConfigFlags.Sim.WorldRRange = 15000
     #ConfigFlags.Sim.WorldZRange = 27000 #change defaults?
-    from G4AtlasApps.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground
+    from SimulationConfig.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground
     ConfigFlags.Sim.CalibrationRun = CalibrationRun.Off
     ConfigFlags.Sim.RecordStepInfo = False
     ConfigFlags.Sim.CavernBackground = CavernBackground.Signal
diff --git a/Simulation/G4Atlas/G4AtlasServices/python/G4AtlasServicesConfigNew.py b/Simulation/G4Atlas/G4AtlasServices/python/G4AtlasServicesConfigNew.py
index 551ad7103794390703ef726871463752a8991879..dd6d7cf2367bf16d29727784f8d0a59f4f49798f 100644
--- a/Simulation/G4Atlas/G4AtlasServices/python/G4AtlasServicesConfigNew.py
+++ b/Simulation/G4Atlas/G4AtlasServices/python/G4AtlasServicesConfigNew.py
@@ -3,7 +3,7 @@ from AthenaConfiguration.ComponentFactory import CompFactory
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 
 from ExtraParticles.ExtraParticlesConfigNew import ExtraParticlesPhysicsToolCfg
-from G4AtlasApps.SimEnums import CavernBackground
+from SimulationConfig.SimEnums import CavernBackground
 from G4AtlasTools.G4GeometryToolConfig import G4AtlasDetectorConstructionToolCfg
 from G4ExtraProcesses.G4ExtraProcessesConfigNew import G4EMProcessesPhysicsToolCfg
 from G4StepLimitation.G4StepLimitationConfigNew import G4StepLimitationToolCfg
diff --git a/Simulation/G4Atlas/G4AtlasServices/python/G4AtlasUserActionConfigNew.py b/Simulation/G4Atlas/G4AtlasServices/python/G4AtlasUserActionConfigNew.py
index 04304f585c929b9faa5e1fd4854f39f76f631a68..e6b5f9c42dd609d53577aca17f8aa2e90d6f7cd3 100644
--- a/Simulation/G4Atlas/G4AtlasServices/python/G4AtlasUserActionConfigNew.py
+++ b/Simulation/G4Atlas/G4AtlasServices/python/G4AtlasUserActionConfigNew.py
@@ -5,7 +5,7 @@ from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
 from AthenaConfiguration.Enums import BeamType, LHCPeriod
 from CaloG4Sim.CaloG4SimConfigNew import CalibrationDefaultProcessingToolCfg
-from G4AtlasApps.SimEnums import CalibrationRun, CavernBackground, SimulationFlavour
+from SimulationConfig.SimEnums import CalibrationRun, CavernBackground, SimulationFlavour
 from G4CosmicFilter.G4CosmicFilterConfigNew import CosmicFilterToolCfg
 from G4UserActions.G4UserActionsConfigNew import (
     AthenaStackingActionToolCfg, AthenaTrackingActionToolCfg,
diff --git a/Simulation/G4Atlas/G4AtlasServices/test/G4AtlasServicesConfig_test.py b/Simulation/G4Atlas/G4AtlasServices/test/G4AtlasServicesConfig_test.py
index 240b6ecd6787fa6b054986042c8bc2e4f759dc6f..4070baba402ce41eaafedadce783035a85e3cbdf 100755
--- a/Simulation/G4Atlas/G4AtlasServices/test/G4AtlasServicesConfig_test.py
+++ b/Simulation/G4Atlas/G4AtlasServices/test/G4AtlasServicesConfig_test.py
@@ -27,7 +27,7 @@ if __name__ == '__main__':
   from AthenaConfiguration.DetectorConfigFlags import setupDetectorsFromList
   setupDetectorsFromList(ConfigFlags, detectors, toggle_geometry=True)
 
-  from G4AtlasApps.SimEnums import CavernBackground
+  from SimulationConfig.SimEnums import CavernBackground
   ConfigFlags.Sim.CavernBackground = CavernBackground.Signal  #for it to go via atlas?
   ConfigFlags.Sim.WorldRRange = 15000
   ConfigFlags.Sim.WorldZRange = 27000
diff --git a/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfigNew.py b/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfigNew.py
index 16a536a7cbf85b077ef7914ad234e029ffe5a7fb..9a2201bdd99d125c5eb2031b9771b3606de71471 100644
--- a/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfigNew.py
+++ b/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfigNew.py
@@ -2,7 +2,7 @@
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
 from AthenaConfiguration.Enums import BeamType
-from G4AtlasApps.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground, LArParameterization
+from SimulationConfig.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground, LArParameterization
 
 
 def FastSimulationToolListCfg(ConfigFlags):
diff --git a/Simulation/G4Atlas/G4AtlasTools/python/G4GeometryToolConfig.py b/Simulation/G4Atlas/G4AtlasTools/python/G4GeometryToolConfig.py
index a73f493aa1a76ccf982c0c3fff0b94a03f475588..3bd22b9d0360ec1ffd0309757ae147e9d92416c1 100644
--- a/Simulation/G4Atlas/G4AtlasTools/python/G4GeometryToolConfig.py
+++ b/Simulation/G4Atlas/G4AtlasTools/python/G4GeometryToolConfig.py
@@ -5,7 +5,7 @@ from AthenaConfiguration.Enums import BeamType, LHCPeriod
 
 from AthenaCommon import Logging
 
-from G4AtlasApps.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground, LArParameterization
+from SimulationConfig.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground, LArParameterization
 
 #the physics region tools
 from G4AtlasTools.G4PhysicsRegionConfigNew import SX1PhysicsRegionToolCfg, BedrockPhysicsRegionToolCfg, CavernShaftsConcretePhysicsRegionToolCfg, PixelPhysicsRegionToolCfg, SCTPhysicsRegionToolCfg, TRTPhysicsRegionToolCfg, TRT_ArPhysicsRegionToolCfg,ITkPixelPhysicsRegionToolCfg,ITkStripPhysicsRegionToolCfg,HGTDPhysicsRegionToolCfg,BeampipeFwdCutPhysicsRegionToolCfg, FWDBeamLinePhysicsRegionToolCfg, EMBPhysicsRegionToolCfg, EMECPhysicsRegionToolCfg, HECPhysicsRegionToolCfg, FCALPhysicsRegionToolCfg, FCAL2ParaPhysicsRegionToolCfg, EMECParaPhysicsRegionToolCfg, FCALParaPhysicsRegionToolCfg, PreSampLArPhysicsRegionToolCfg, DeadMaterialPhysicsRegionToolCfg
diff --git a/Simulation/G4Atlas/G4AtlasTools/python/G4PhysicsRegionConfigNew.py b/Simulation/G4Atlas/G4AtlasTools/python/G4PhysicsRegionConfigNew.py
index 968a6fd1634b93e4bde45aa341032cf07abca5b4..21c219fe6e3e9d910236432718a8ad6bd8e63d1b 100644
--- a/Simulation/G4Atlas/G4AtlasTools/python/G4PhysicsRegionConfigNew.py
+++ b/Simulation/G4Atlas/G4AtlasTools/python/G4PhysicsRegionConfigNew.py
@@ -1,7 +1,7 @@
 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 from AthenaConfiguration.ComponentFactory import CompFactory
 from AthenaConfiguration.Enums import LHCPeriod
-from G4AtlasApps.SimEnums import BeamPipeSimMode
+from SimulationConfig.SimEnums import BeamPipeSimMode
 
 RegionCreator=CompFactory.RegionCreator
 
@@ -288,7 +288,7 @@ def DriftWall2PhysicsRegionToolCfg(ConfigFlags, name='DriftWall2PhysicsRegionToo
 def MuonSystemFastPhysicsRegionToolCfg(ConfigFlags, name='MuonSystemFastPhysicsRegionTool', **kwargs):
     kwargs.setdefault("RegionName", 'MuonSystemFastRegion')
     volumeList = []
-    from G4AtlasApps.SimEnums import CavernBackground
+    from SimulationConfig.SimEnums import CavernBackground
     if ConfigFlags.Sim.CavernBackground in [CavernBackground.SignalWorld, CavernBackground.WriteWorld]:
         if ConfigFlags.GeoModel.Run < LHCPeriod.Run4:
             volumeList += ['BeamPipe::BeamPipe', 'IDET::IDET']
diff --git a/Simulation/G4Utilities/G4UserActions/python/G4UserActionsConfigNew.py b/Simulation/G4Utilities/G4UserActions/python/G4UserActionsConfigNew.py
index c8957fed01f465701d94849f7851757db610e4ac..946d1085a6766172ee4c3f3ecdebd4d61aa28a94 100644
--- a/Simulation/G4Utilities/G4UserActions/python/G4UserActionsConfigNew.py
+++ b/Simulation/G4Utilities/G4UserActions/python/G4UserActionsConfigNew.py
@@ -2,7 +2,7 @@
 
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
-from G4AtlasApps.SimEnums import CalibrationRun
+from SimulationConfig.SimEnums import CalibrationRun
 
 # this is a bit cumbersome, but it seems ike it is a lot easier to separate
 # the getter functionality from all the rest (i.e. adding the action).
diff --git a/Simulation/G4Utilities/TrackWriteFastSim/python/TrackWriteFastSimConfigNew.py b/Simulation/G4Utilities/TrackWriteFastSim/python/TrackWriteFastSimConfigNew.py
index bd98aeba7261fd64f85daf7d1ee566da5a744d12..7327f06274885b3d06ad795421f9d72ddc78c2a6 100644
--- a/Simulation/G4Utilities/TrackWriteFastSim/python/TrackWriteFastSimConfigNew.py
+++ b/Simulation/G4Utilities/TrackWriteFastSim/python/TrackWriteFastSimConfigNew.py
@@ -2,7 +2,7 @@
 
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
-from G4AtlasApps.SimEnums import CavernBackground
+from SimulationConfig.SimEnums import CavernBackground
 
 
 def TrackFastSimSDCfg(flags, name='TrackFastSimSD', **kwargs):
diff --git a/Simulation/ISF/ISF_Config/python/ISF_MainConfigNew.py b/Simulation/ISF/ISF_Config/python/ISF_MainConfigNew.py
index 17c74121f18f15cb7dc0a67b3b5db2d8727e85b2..6472819087656d4c8691c8407cd55ed947d2c70a 100644
--- a/Simulation/ISF/ISF_Config/python/ISF_MainConfigNew.py
+++ b/Simulation/ISF/ISF_Config/python/ISF_MainConfigNew.py
@@ -4,7 +4,7 @@ Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 """
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
-from G4AtlasApps.G4Atlas_MetadataNew import writeSimulationParametersMetadata
+from SimulationConfig.SimulationMetadata import writeSimulationParametersMetadata
 from ISF_Services.ISF_ServicesCoreConfigNew import GeoIDSvcCfg, AFIIGeoIDSvcCfg
 from ISF_Services.ISF_ServicesConfigNew import (
     InputConverterCfg, TruthServiceCfg,
@@ -408,7 +408,7 @@ def Kernel_ATLFAST3F_G4MSCfg(flags, name="ISF_Kernel_ATLFAST3F_G4MS", **kwargs):
 
 
 def ISF_KernelCfg(flags):
-    from G4AtlasApps.SimEnums import SimulationFlavour
+    from SimulationConfig.SimEnums import SimulationFlavour
 
     if flags.Sim.ISF.Simulator is SimulationFlavour.FullG4MT:
         return Kernel_FullG4MTCfg(flags)
diff --git a/Simulation/ISF/ISF_Config/test/ISF_MainConfigNew_Test.py b/Simulation/ISF/ISF_Config/test/ISF_MainConfigNew_Test.py
index bbf6b6bb165a1ffac38033fd06258b544178bbff..d09c323d41313ceb769a298e9e83ccdcd5a025c0 100644
--- a/Simulation/ISF/ISF_Config/test/ISF_MainConfigNew_Test.py
+++ b/Simulation/ISF/ISF_Config/test/ISF_MainConfigNew_Test.py
@@ -36,7 +36,7 @@ if __name__ == '__main__':
     #Sim ConfigFlags
     #ConfigFlags.Sim.WorldRRange = 15000
     #ConfigFlags.Sim.WorldZRange = 27000 #change defaults?
-    from G4AtlasApps.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground, LArParameterization, SimulationFlavour, TruthStrategy
+    from SimulationConfig.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground, LArParameterization, SimulationFlavour, TruthStrategy
     ConfigFlags.Sim.CalibrationRun = CalibrationRun.Off 
     ConfigFlags.Sim.RecordStepInfo = False
     ConfigFlags.Sim.CavernBackground = CavernBackground.Signal
diff --git a/Simulation/ISF/ISF_Core/ISF_Algorithms/python/CollectionMergerConfig.py b/Simulation/ISF/ISF_Core/ISF_Algorithms/python/CollectionMergerConfig.py
index 991e9623ce7f427fdebfa05316f186a7e0a81543..8483a6ca1f3063f1f85bfff854a4469e67c4f563 100644
--- a/Simulation/ISF/ISF_Core/ISF_Algorithms/python/CollectionMergerConfig.py
+++ b/Simulation/ISF/ISF_Core/ISF_Algorithms/python/CollectionMergerConfig.py
@@ -43,7 +43,7 @@ def ISFCollectionMergerCfg(flags,name="ISF_CollectionMerger", **kwargs):
                  .format(err))
         # FIXME: Digitization is not the AthSimulation project;
         # support for FastChain may need to be added in the future.
-    from G4AtlasApps.SimEnums import SimulationFlavour
+    from SimulationConfig.SimEnums import SimulationFlavour
     if flags.Detector.EnableBCM and flags.Sim.ISF.Simulator not in [SimulationFlavour.ATLFASTIIF_G4MS, SimulationFlavour.ATLFASTIIFMT, SimulationFlavour.ATLFAST3F_G4MS]:
         kwargs.setdefault( "OutputBCMHits",             hardscatterSG+"BCMHits"             )
         kwargs.setdefault( "OutputBLMHits",             hardscatterSG+"BLMHits"             )
diff --git a/Simulation/ISF/ISF_Core/ISF_Services/python/ISF_ServicesConfigNew.py b/Simulation/ISF/ISF_Core/ISF_Services/python/ISF_ServicesConfigNew.py
index 298121f1a76d177c1d57c3908a32a2addb4b288e..8802758d7bfa050e43467a38ea4cb896873063f4 100644
--- a/Simulation/ISF/ISF_Core/ISF_Services/python/ISF_ServicesConfigNew.py
+++ b/Simulation/ISF/ISF_Core/ISF_Services/python/ISF_ServicesConfigNew.py
@@ -5,7 +5,7 @@ Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
 from AthenaConfiguration.Enums import BeamType
-from G4AtlasApps.SimEnums import CavernBackground, TruthStrategy
+from SimulationConfig.SimEnums import CavernBackground, TruthStrategy
 from ISF_HepMC_Tools.ISF_HepMC_ToolsConfigNew import (
     ParticleFinalStateFilterCfg, ParticlePositionFilterDynamicCfg,
     EtaPhiFilterCfg, GenParticleInteractingFilterCfg,
diff --git a/Simulation/ISF/ISF_Core/ISF_Tools/python/ISF_ToolsConfigNew.py b/Simulation/ISF/ISF_Core/ISF_Tools/python/ISF_ToolsConfigNew.py
index 2341ebecf255ce64eaa3350354081e3490be8534..5e390e685d864a240714b481d7ea1cb6ce6ef925 100644
--- a/Simulation/ISF/ISF_Core/ISF_Tools/python/ISF_ToolsConfigNew.py
+++ b/Simulation/ISF/ISF_Core/ISF_Tools/python/ISF_ToolsConfigNew.py
@@ -23,7 +23,7 @@ def MemoryMonitorToolCfg(flags, name="ISF_MemoryMonitor", **kwargs):
 
 def EntryLayerFilterCfg(ConfigFlags, **kwargs):
     """Return the MCxEntryLayerFilterCfg config flagged by Sim.TruthStrategy"""
-    from G4AtlasApps.SimEnums import TruthStrategy
+    from SimulationConfig.SimEnums import TruthStrategy
     stratmap = {
         TruthStrategy.MC12: MC12EntryLayerFilterCfg,
         TruthStrategy.MC12LLP: MC12LLPEntryLayerFilterCfg,
diff --git a/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimServices/python/ISF_FastCaloSimServicesTestHelpers.py b/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimServices/python/ISF_FastCaloSimServicesTestHelpers.py
index 2b2d14e6ba751ed5cff9ee9aad158a3fb1115308..4b4a6178d3ae0f57b5af12ee037054335b589359 100644
--- a/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimServices/python/ISF_FastCaloSimServicesTestHelpers.py
+++ b/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimServices/python/ISF_FastCaloSimServicesTestHelpers.py
@@ -56,7 +56,7 @@ def defaultTestFlags(configFlags, args):
     configFlags.Common.ProductionStep = ProductionStep.Simulation
 
     # Sim configFlags
-    from G4AtlasApps.SimEnums import BeamPipeSimMode, CalibrationRun, LArParameterization, SimulationFlavour, TruthStrategy
+    from SimulationConfig.SimEnums import BeamPipeSimMode, CalibrationRun, LArParameterization, SimulationFlavour, TruthStrategy
     configFlags.Sim.TruthStrategy = TruthStrategy.MC15aPlus
     configFlags.Sim.PhysicsList = "FTFP_BERT_ATL"
     configFlags.Sim.CalibrationRun = CalibrationRun.Off 
diff --git a/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/python/ISF_Geant4ToolsConfigNew.py b/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/python/ISF_Geant4ToolsConfigNew.py
index 86092e4e6aae606f9358ee3ecac575239353e86f..c3ff0e5131f55409b2fa514dfa7a368804b92333 100644
--- a/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/python/ISF_Geant4ToolsConfigNew.py
+++ b/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/python/ISF_Geant4ToolsConfigNew.py
@@ -58,7 +58,7 @@ def Geant4ToolCfg(flags, name="ISF_Geant4Tool", **kwargs):
     kwargs.setdefault("PhysicsListSvc", acc.getPrimaryAndMerge(PhysicsListSvcCfg(flags)).name)
 
     # Workaround to keep other simulation flavours working while we migrate everything to be AthenaMT-compatible.
-    from G4AtlasApps.SimEnums import SimulationFlavour
+    from SimulationConfig.SimEnums import SimulationFlavour
     if flags.Sim.ISF.Simulator in [SimulationFlavour.FullG4MT, SimulationFlavour.FullG4MT_QS, SimulationFlavour.PassBackG4MT, SimulationFlavour.ATLFAST3MT, SimulationFlavour.ATLFAST3MT_QS]:
         acc.setPrivateTools(CompFactory.iGeant4.G4TransportTool(name, **kwargs))
     else:
diff --git a/Simulation/SimuJobTransforms/python/CommonSimulationSteering.py b/Simulation/SimuJobTransforms/python/CommonSimulationSteering.py
index 6374a37964a21ab54e925629803e306db17dfa2e..1f69e772822363a9e2f9f0dfcc9e44b75b0eca8f 100644
--- a/Simulation/SimuJobTransforms/python/CommonSimulationSteering.py
+++ b/Simulation/SimuJobTransforms/python/CommonSimulationSteering.py
@@ -17,7 +17,7 @@
 from PyJobTransforms.TransformUtils import executeFromFragment
 from AthenaConfiguration.ComponentFactory import CompFactory
 from AthenaConfiguration.Enums import BeamType
-from G4AtlasApps.SimEnums import CavernBackground
+from SimulationConfig.SimEnums import CavernBackground
 
 
 def specialConfigPreInclude(ConfigFlags):
diff --git a/Simulation/SimuJobTransforms/python/G4AtlasAlg_Skeleton.py b/Simulation/SimuJobTransforms/python/G4AtlasAlg_Skeleton.py
index 22c534f587824bd0cc20e1787d779dcf83b2f66f..ce738ff2a083fffc7601730d703151793d96377f 100644
--- a/Simulation/SimuJobTransforms/python/G4AtlasAlg_Skeleton.py
+++ b/Simulation/SimuJobTransforms/python/G4AtlasAlg_Skeleton.py
@@ -12,7 +12,7 @@ def defaultSimulationFlags(ConfigFlags, detectors):
     from AthenaConfiguration.Enums import ProductionStep
     ConfigFlags.Common.ProductionStep = ProductionStep.Simulation
     # Writing out CalibrationHits only makes sense if we are running FullG4 simulation without frozen showers
-    from G4AtlasApps.SimEnums import CalibrationRun, LArParameterization
+    from SimulationConfig.SimEnums import CalibrationRun, LArParameterization
     if ConfigFlags.Sim.LArParameterization is not LArParameterization.NoFrozenShowers:
         ConfigFlags.Sim.CalibrationRun = CalibrationRun.Off
 
@@ -40,7 +40,7 @@ def fromRunArgs(runArgs):
     log.info('**** Setting-up configuration flags')
     from AthenaConfiguration.AllConfigFlags import ConfigFlags
     from AthenaConfiguration.Enums import BeamType
-    from G4AtlasApps.SimEnums import CalibrationRun, CavernBackground, SimulationFlavour
+    from SimulationConfig.SimEnums import CalibrationRun, CavernBackground, SimulationFlavour
     commonRunArgsToFlags(runArgs, ConfigFlags)
 
     # Generate detector list
@@ -139,7 +139,7 @@ def fromRunArgs(runArgs):
     processPreExec(runArgs, ConfigFlags)
 
     # Common simulation runtime arguments
-    from G4AtlasApps.SimConfigFlags import simulationRunArgsToFlags
+    from SimulationConfig.SimConfigFlags import simulationRunArgsToFlags
     simulationRunArgsToFlags(runArgs, ConfigFlags)
 
     # Lock flags
diff --git a/Simulation/SimuJobTransforms/python/G4Optimizations.py b/Simulation/SimuJobTransforms/python/G4Optimizations.py
index a8d1a60c82fbe9fd0148fd8fc2c60d69fafe116c..8b7c63e09c920bd17e8fdfefe269a4fa060e4495 100644
--- a/Simulation/SimuJobTransforms/python/G4Optimizations.py
+++ b/Simulation/SimuJobTransforms/python/G4Optimizations.py
@@ -1,5 +1,5 @@
 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
-from G4AtlasApps.SimEnums import CalibrationRun
+from SimulationConfig.SimEnums import CalibrationRun
 
 
 def enableG4Optimizations(flags):
diff --git a/Simulation/SimuJobTransforms/python/ISF_Skeleton.py b/Simulation/SimuJobTransforms/python/ISF_Skeleton.py
index bf0cc525110dc764ee875dea0d4a95c35f8adaa3..b4d59d90449c7d51e2d5fb969d04d495667879b5 100644
--- a/Simulation/SimuJobTransforms/python/ISF_Skeleton.py
+++ b/Simulation/SimuJobTransforms/python/ISF_Skeleton.py
@@ -12,7 +12,7 @@ def defaultSimulationFlags(ConfigFlags, detectors):
     from AthenaConfiguration.Enums import ProductionStep
     ConfigFlags.Common.ProductionStep = ProductionStep.Simulation
     # Writing out CalibrationHits only makes sense if we are running FullG4 simulation without frozen showers
-    from G4AtlasApps.SimEnums import CalibrationRun, LArParameterization, SimulationFlavour
+    from SimulationConfig.SimEnums import CalibrationRun, LArParameterization, SimulationFlavour
     if ConfigFlags.Sim.ISF.Simulator not in [SimulationFlavour.FullG4MT, SimulationFlavour.FullG4MT_QS, SimulationFlavour.PassBackG4MT] \
         or ConfigFlags.Sim.LArParameterization is not LArParameterization.NoFrozenShowers:
         ConfigFlags.Sim.CalibrationRun = CalibrationRun.Off
@@ -48,7 +48,7 @@ def fromRunArgs(runArgs):
     log.info('**** Setting-up configuration flags')
     from AthenaConfiguration.AllConfigFlags import ConfigFlags
     from AthenaConfiguration.Enums import BeamType
-    from G4AtlasApps.SimEnums import CalibrationRun, CavernBackground, SimulationFlavour
+    from SimulationConfig.SimEnums import CalibrationRun, CavernBackground, SimulationFlavour
     commonRunArgsToFlags(runArgs, ConfigFlags)
 
     # Generate detector list
@@ -144,7 +144,7 @@ def fromRunArgs(runArgs):
     processPreExec(runArgs, ConfigFlags)
 
     # Common simulation runtime arguments
-    from G4AtlasApps.SimConfigFlags import simulationRunArgsToFlags
+    from SimulationConfig.SimConfigFlags import simulationRunArgsToFlags
     simulationRunArgsToFlags(runArgs, ConfigFlags)
 
     # Lock flags
diff --git a/Simulation/SimuJobTransforms/python/ReSimulation_Skeleton.py b/Simulation/SimuJobTransforms/python/ReSimulation_Skeleton.py
index 3bd681d5b51852e7eaaf200a7bf37292074250c1..1371524c0ba97d27d33fae2322389c22963c329c 100644
--- a/Simulation/SimuJobTransforms/python/ReSimulation_Skeleton.py
+++ b/Simulation/SimuJobTransforms/python/ReSimulation_Skeleton.py
@@ -28,7 +28,7 @@ def fromRunArgs(runArgs):
 
     log.info('**** Setting-up configuration flags')
     from AthenaConfiguration.AllConfigFlags import ConfigFlags
-    from G4AtlasApps.SimEnums import SimulationFlavour
+    from SimulationConfig.SimEnums import SimulationFlavour
     commonRunArgsToFlags(runArgs, ConfigFlags)
 
     # Generate detector list
@@ -63,7 +63,7 @@ def fromRunArgs(runArgs):
     processPreExec(runArgs, ConfigFlags)
 
     # Common simulation runtime arguments
-    from G4AtlasApps.SimConfigFlags import simulationRunArgsToFlags
+    from SimulationConfig.SimConfigFlags import simulationRunArgsToFlags
     simulationRunArgsToFlags(runArgs, ConfigFlags)
 
     # Lock flags
diff --git a/Simulation/SimuJobTransforms/python/SimOutputConfig.py b/Simulation/SimuJobTransforms/python/SimOutputConfig.py
index 0ee1c71e1eb97c5713e0a5fd588a3d8a4e3015a7..8e9cfe25b3374ddf5cff6d8cff6b6f3b6f04668f 100644
--- a/Simulation/SimuJobTransforms/python/SimOutputConfig.py
+++ b/Simulation/SimuJobTransforms/python/SimOutputConfig.py
@@ -6,7 +6,7 @@ def getStreamEVNT_TR_ItemList(ConfigFlags):
         "IOVMetaDataContainer#*",
         "EventInfo#*"
     ]
-    from G4AtlasApps.SimEnums import CavernBackground
+    from SimulationConfig.SimEnums import CavernBackground
     if ConfigFlags.Sim.CavernBackground in [CavernBackground.Write, CavernBackground.WriteWorld]:
         ItemList += ["TrackRecordCollection#NeutronBG"]
     else:
diff --git a/Simulation/SimuJobTransforms/python/SimulationHelpers.py b/Simulation/SimuJobTransforms/python/SimulationHelpers.py
index afd1c71044b712575e6ab38e59fda41434a07090..4dec39db9dc1601a58f82548ae639cfcf1596806 100644
--- a/Simulation/SimuJobTransforms/python/SimulationHelpers.py
+++ b/Simulation/SimuJobTransforms/python/SimulationHelpers.py
@@ -1,5 +1,5 @@
 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
-from G4AtlasApps.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground, LArParameterization
+from SimulationConfig.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground, LArParameterization
 
 
 def getDetectorsFromRunArgs(ConfigFlags, runArgs):
diff --git a/Simulation/SimulationConfig/CMakeLists.txt b/Simulation/SimulationConfig/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..465c912b82a7a908c9ebbebbb49314b245215cd3
--- /dev/null
+++ b/Simulation/SimulationConfig/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+
+# Declare the package name:
+atlas_subdir( SimulationConfig )
+
+# Install files from the package:
+#atlas_install_joboptions( share/*.py
+#                          POST_BUILD_CMD ${ATLAS_FLAKE8} )
+atlas_install_python_modules( python/*.py
+                              POST_BUILD_CMD ${ATLAS_FLAKE8} )
+#atlas_install_runtime( scripts/*.py )
+#atlas_install_runtime( test/OverlayTest.py )
+
+# Setup and run tests
+
+# TODO: temporarily disabling this test, will be fixed in a separate MR
+#atlas_add_test( OverlayTest_MC
+#                SCRIPT test/OverlayTest.py
+#                PROPERTIES TIMEOUT 900
+#                POST_EXEC_SCRIPT nopost.sh )
diff --git a/Simulation/G4Atlas/G4AtlasApps/python/SimConfigFlags.py b/Simulation/SimulationConfig/python/SimConfigFlags.py
similarity index 99%
rename from Simulation/G4Atlas/G4AtlasApps/python/SimConfigFlags.py
rename to Simulation/SimulationConfig/python/SimConfigFlags.py
index 69aa62f0830052dd1c02ea288521be41c3be73b5..92fd141b194f229ef45d6536bb73a6d701500a88 100644
--- a/Simulation/G4Atlas/G4AtlasApps/python/SimConfigFlags.py
+++ b/Simulation/SimulationConfig/python/SimConfigFlags.py
@@ -2,7 +2,7 @@
 
 from AthenaConfiguration.AthConfigFlags import AthConfigFlags
 from AthenaConfiguration.AutoConfigFlags import GetFileMD
-from G4AtlasApps.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground, \
+from SimulationConfig.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground, \
     LArParameterization, SimulationFlavour, TruthStrategy, VertexSource
 
 #todo? add in the explanatory text from previous implementation
diff --git a/Simulation/G4Atlas/G4AtlasApps/python/SimEnums.py b/Simulation/SimulationConfig/python/SimEnums.py
similarity index 100%
rename from Simulation/G4Atlas/G4AtlasApps/python/SimEnums.py
rename to Simulation/SimulationConfig/python/SimEnums.py
diff --git a/Simulation/G4Atlas/G4AtlasApps/python/G4Atlas_MetadataNew.py b/Simulation/SimulationConfig/python/SimulationMetadata.py
similarity index 100%
rename from Simulation/G4Atlas/G4AtlasApps/python/G4Atlas_MetadataNew.py
rename to Simulation/SimulationConfig/python/SimulationMetadata.py
diff --git a/Simulation/SimulationConfig/python/__init__.py b/Simulation/SimulationConfig/python/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/TileCalorimeter/TileExample/TileSimEx/share/jobOptions.G4Atlas_Tile.py b/TileCalorimeter/TileExample/TileSimEx/share/jobOptions.G4Atlas_Tile.py
index 8214ec8503c79feac21afb0a482ee6b10db0b2dd..59256a81b816e085f13dc34c71184488a45f31f5 100644
--- a/TileCalorimeter/TileExample/TileSimEx/share/jobOptions.G4Atlas_Tile.py
+++ b/TileCalorimeter/TileExample/TileSimEx/share/jobOptions.G4Atlas_Tile.py
@@ -12,14 +12,13 @@ if not 'OutputFile' in dir():
     OutputFile = '%s.pool.root' % File
 
 if not 'ConddbTag' in dir():
-    ConddbTag = 'OFLCOND-MC16-SDR-25'
+    ConddbTag = 'OFLCOND-MC21-SDR-RUN3-08'
 
 if not 'DetDescrVersion' in dir():
-    #DetDescrVersion = 'ATLAS-R2-2016-01-00-01'
-    DetDescrVersion = 'ATLAS-R2-2015-03-01-00'
+    DetDescrVersion = 'ATLAS-R3S-2021-03-00-00'
 
 if not 'TileVersionOverride' in dir():
-#    TileVersionOverride = 'TileCal-GEO-09'
+#    TileVersionOverride = 'TileCal-GEO-12'
     TileVersionOverride = ''
 
 ## Algorithm sequence
@@ -60,7 +59,7 @@ jobproperties.Global.ConditionsTag = ConddbTag
 ## Simulation flags
 from G4AtlasApps.SimFlags import simFlags
 simFlags.load_atlas_flags()
-simFlags.RunNumber = 310000
+simFlags.RunNumber = 410000
 
 ## Turns on calibration hits for Tile
 if 'CalibrationRun' in dir():
diff --git a/TileCalorimeter/TileExample/TileSimEx/share/jobOptions_Tile_Dig.py b/TileCalorimeter/TileExample/TileSimEx/share/jobOptions_Tile_Dig.py
index f51c9a3f6418db668740ebb8a91b3fa63de2f9ed..3f241c6543336857f00bd244c001f3fb286eb794 100755
--- a/TileCalorimeter/TileExample/TileSimEx/share/jobOptions_Tile_Dig.py
+++ b/TileCalorimeter/TileExample/TileSimEx/share/jobOptions_Tile_Dig.py
@@ -36,7 +36,7 @@ if not 'EvtMax' in dir():
     EvtMax = -1
 
 if not 'RunNumber' in dir():
-    RunNumber = 310000
+    RunNumber = 410000
 
 if not 'FileSuffix' in dir():
     FileSuffix = ''
@@ -120,7 +120,7 @@ if not 'doD3PDCell' in dir():
     doD3PDCell = False
 
 if not 'doD3PDCellInfo' in dir():
-    doD3PDCellInfo = True
+    doD3PDCellInfo = doD3PD
 
 if not 'doD3PDMBTS' in dir():
     doD3PDMBTS = False
@@ -243,7 +243,8 @@ if not TileTB:
 # jobproperties.Digitization.numberOfBeamGas=0.5
 # jobproperties.Digitization.beamGasInputCols=['', '']
 
-topSequence += CfgMgr.xAODMaker__EventInfoCnvAlg()
+if TileTB:
+    topSequence += CfgMgr.xAODMaker__EventInfoCnvAlg()
 
 if doD3PDHit or doD3PDDigit or doD3PDRawChannel or doD3PDCell or doD3PDCellInfo or doD3PDMBTS or doDigitsNtuple or doRawChannelNtuple or doTileNtuple or doRDO:
 
@@ -253,9 +254,13 @@ if doD3PDHit or doD3PDDigit or doD3PDRawChannel or doD3PDCell or doD3PDCellInfo
         # special settings for TileConditions, to make sure that COOL is not used
         if not 'TileUseCOOL' in dir():
             TileUseCOOL=False
-        elif TileUseCOOL:
+        if TileUseCOOL:
             jobproperties.Digitization.simRunNumber = RunNumber
             jobproperties.Digitization.dataRunNumber = RunNumber
+        else:
+            from TileConditions.TileCondToolConf import getTileCondToolEmscale, getTileCondToolNoiseSample
+            getTileCondToolEmscale('FILE')
+            getTileCondToolNoiseSample('FILE')
 
         # setting Fit and Opt2 method only
         from TileRecUtils.TileRecFlags import jobproperties
@@ -267,9 +272,9 @@ if doD3PDHit or doD3PDDigit or doD3PDRawChannel or doD3PDCell or doD3PDCellInfo
     if TileTB:
         jobproperties.TileRecFlags.TileRawChannelContainer = "TileRawChannelFit"
         # avoid MBTS hits
-        ToolSvc.TileHitVecToCntTool.TileHitVectors=['TileHitVec']
+        topSequence.StandardPileUpToolsAlg.PileUpTools['TileHitVecToCntTool'].TileHitVectors=['TileHitVec']
         # change threshold in fit method
-        ToolSvc.TileRawChannelBuilderFitFilter.NoiseThresholdRMS = 3.
+        topSequence.TileRChMaker.TileRawChannelBuilder['TileRawChannelBuilderFitFilter'].NoiseThresholdRMS = 3.
 
 else:
     include( "TileConditions/TileConditions_jobOptions.py" )
@@ -421,3 +426,7 @@ if doTileNtuple:
 # from TileSimAlgs.TileSimAlgsConf import *
 # theTilePulseForTileMuonReceiver=TilePulseForTileMuonReceiver()
 # topSequence += theTilePulseForTileMuonReceiver
+
+if TileTB:
+    # sampling fraction for Geant4 10.6 for all run numbers
+    conddb.addOverride("/TILE/OFL02/CALIB/SFR","TileOfl02CalibSfr-SIM-07")
diff --git a/Tools/Campaigns/python/MC16.py b/Tools/Campaigns/python/MC16.py
index e23dda870a85cde41c09975b15459167449c007a..69a60c54a1be343c845e4f9bfb7270621b160280 100644
--- a/Tools/Campaigns/python/MC16.py
+++ b/Tools/Campaigns/python/MC16.py
@@ -1,5 +1,5 @@
 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
-from G4AtlasApps.SimEnums import SimulationFlavour, TruthStrategy
+from SimulationConfig.SimEnums import SimulationFlavour, TruthStrategy
 from LArConfiguration.LArConfigRun2 import LArConfigRun2PileUp, LArConfigRun2NoPileUp
 
 
diff --git a/Tools/Campaigns/python/MC21.py b/Tools/Campaigns/python/MC21.py
index ba3849753fd88b57f84362290ee3c4861c197e9d..bd2ed515bcc3517b28cdfeeb35fac5dd138cfdfe 100644
--- a/Tools/Campaigns/python/MC21.py
+++ b/Tools/Campaigns/python/MC21.py
@@ -1,5 +1,5 @@
 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
-from G4AtlasApps.SimEnums import SimulationFlavour, TruthStrategy
+from SimulationConfig.SimEnums import SimulationFlavour, TruthStrategy
 from AthenaConfiguration.Enums import ProductionStep
 from LArConfiguration.LArConfigRun3 import LArConfigRun3PileUp, LArConfigRun3NoPileUp
 
diff --git a/Tools/Campaigns/python/PhaseII.py b/Tools/Campaigns/python/PhaseII.py
index 5d156f03e8e5b44c4d0bf35f5838e199d2c01b42..f2ae8416c654952e7ac2e02bcdf8febf58b430f5 100644
--- a/Tools/Campaigns/python/PhaseII.py
+++ b/Tools/Campaigns/python/PhaseII.py
@@ -1,5 +1,5 @@
 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
-from G4AtlasApps.SimEnums import TruthStrategy
+from SimulationConfig.SimEnums import TruthStrategy
 
 
 def PhaseIIPileUpBase(flags, collisions=200):
diff --git a/Tools/FullChainTransforms/python/FastChain_Skeleton.py b/Tools/FullChainTransforms/python/FastChain_Skeleton.py
index 8e19b5f41f9181fa1b2e34a14ab339c781a1c43b..7375663e70bd8737173afa9d3e3b9bacea2f39b4 100644
--- a/Tools/FullChainTransforms/python/FastChain_Skeleton.py
+++ b/Tools/FullChainTransforms/python/FastChain_Skeleton.py
@@ -21,7 +21,7 @@ def fromRunArgs(runArgs):
 
     log.info('**** Setting-up configuration flags')
     from AthenaConfiguration.AllConfigFlags import ConfigFlags
-    from G4AtlasApps.SimEnums import SimulationFlavour
+    from SimulationConfig.SimEnums import SimulationFlavour
     commonRunArgsToFlags(runArgs, ConfigFlags)
 
     # Autoconfigure enabled subdetectors
@@ -64,7 +64,7 @@ def fromRunArgs(runArgs):
         ConfigFlags.IOVDb.GlobalTag = runArgs.conditionsTag
 
     # Setup common simulation flags
-    from G4AtlasApps.SimConfigFlags import simulationRunArgsToFlags
+    from SimulationConfig.SimConfigFlags import simulationRunArgsToFlags
     simulationRunArgsToFlags(runArgs, ConfigFlags)
 
     from SimuJobTransforms.ISF_Skeleton import defaultSimulationFlags
diff --git a/Tools/TrfTestsART/test/test_trf_q445_aodmerge.sh b/Tools/TrfTestsART/test/test_trf_q445_aodmerge.sh
index c5810199a642ff6a7071f663ea0fa4481c51ba21..357350da257c9a6332019f43a3b763daaf182827 100755
--- a/Tools/TrfTestsART/test/test_trf_q445_aodmerge.sh
+++ b/Tools/TrfTestsART/test/test_trf_q445_aodmerge.sh
@@ -26,7 +26,7 @@ rc2=$?
 rc3=1
 if [[ $rc1 -eq 0 ]] && [[ $rc2 -eq 0 ]]; then
   # EventData
-  acmd diff-root --nan-equal myAOD.MT.pool.root Merged.MT.AOD.pool.root
+  acmd diff-root --nan-equal --order-trees myAOD.MT.pool.root Merged.MT.AOD.pool.root
   rc3=$?
 fi
 
diff --git a/Tracking/Acts/ActsGeantFollowing/share/ActsGeantFollowing_jobOptions_ITk.py b/Tracking/Acts/ActsGeantFollowing/share/ActsGeantFollowing_jobOptions_ITk.py
index 981c42b6d2596074c00fd3c74ad34ec25c6fe28b..5aac89e626619d24fbb6c7ba8d4ff02f45c3aa4d 100644
--- a/Tracking/Acts/ActsGeantFollowing/share/ActsGeantFollowing_jobOptions_ITk.py
+++ b/Tracking/Acts/ActsGeantFollowing/share/ActsGeantFollowing_jobOptions_ITk.py
@@ -54,7 +54,7 @@ def defaultTestFlags(configFlags, args):
     
     configFlags.Output.HITSFileName = args.outputhitsfile
 
-    from G4AtlasApps.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground
+    from SimulationConfig.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground
     configFlags.Sim.CalibrationRun = CalibrationRun.Off
     configFlags.Sim.RecordStepInfo = False
     configFlags.Sim.CavernBackground = CavernBackground.Signal
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlgConfig.py b/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlgConfig.py
index 024523872b6784244468fe566e3ad576af567fec..fccf30524c3a2bd6b314488119eec6af2d9f9ead 100644
--- a/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlgConfig.py
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlgConfig.py
@@ -158,7 +158,7 @@ def _getInDetTrackingGeometryBuilder(name, flags,
         # set the binning from bi-aequidistant to arbitrary for complex TRT volumes
         TRT_LayerBinning = 1
         from AthenaConfiguration.Enums import ProductionStep
-        from G4AtlasApps.SimEnums import SimulationFlavour
+        from SimulationConfig.SimEnums import SimulationFlavour
         if buildTrtStrawLayers or (flags.Common.ProductionStep in [ProductionStep.Simulation, ProductionStep.FastChain] and flags.Sim.ISF.Simulator not in [SimulationFlavour.ATLFASTIIMT]):
             TRT_LayerBinning = 2
             TRT_LayerBuilder.ModelLayersOnly = False
diff --git a/Tracking/TrkConfig/python/AtlasTrackingGeometrySvcConfig.py b/Tracking/TrkConfig/python/AtlasTrackingGeometrySvcConfig.py
index b4427e3c8b37e339f827a0d0ecbdcf32d5b2dce9..1fd3f90feea465bd40607069c12199c7457678ed 100644
--- a/Tracking/TrkConfig/python/AtlasTrackingGeometrySvcConfig.py
+++ b/Tracking/TrkConfig/python/AtlasTrackingGeometrySvcConfig.py
@@ -248,7 +248,7 @@ def TRT_LayerBuilderCfg(flags, namePrefix='', buildTrtStrawLayers = False):
     # TRT barrel specifications - assume defaults
     # TRT endcap specifications - assume defaults
 
-    from G4AtlasApps.SimEnums import SimulationFlavour
+    from SimulationConfig.SimEnums import SimulationFlavour
     if buildTrtStrawLayers or (flags.Common.ProductionStep in [ProductionStep.Simulation, ProductionStep.FastChain] and flags.Sim.ISF.Simulator not in [SimulationFlavour.ATLFASTIIMT]):
         TRT_LayerBuilder.ModelLayersOnly = False
     result.setPrivateTools(TRT_LayerBuilder)
@@ -299,7 +299,7 @@ def InDetTrackingGeometryBuilderCfg(name, flags, namePrefix='', setLayerAssociat
         # set the binning from bi-aequidistant to arbitrary for complex TRT volumes
         TRT_LayerBinning = 1
         from AthenaConfiguration.Enums import ProductionStep
-        from G4AtlasApps.SimEnums import SimulationFlavour
+        from SimulationConfig.SimEnums import SimulationFlavour
         if buildTrtStrawLayers or (flags.Common.ProductionStep in [ProductionStep.Simulation, ProductionStep.FastChain] and flags.Sim.ISF.Simulator not in [SimulationFlavour.ATLFASTIIMT]):
             TRT_LayerBinning = 2
         binnings += [ TRT_LayerBinning ]
diff --git a/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.cxx b/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.cxx
index ab2410dc34476a342ac8e7925c021da12a64ff84..92657f4321e64239e0bc49cab3d47b55abf5ef92 100644
--- a/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.cxx
+++ b/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.cxx
@@ -2974,10 +2974,8 @@ bool TrigFastTrackFinder::isPreselPassDisTrackBeforeRefit(Trk::Track* trk, doubl
    return true;
 }
 
-const Trk::Perigee* TrigFastTrackFinder::extrapolateDisTrackToBS(Trk::Track* t,
-								 const std::vector<double>& v_xvtx,
-								 const std::vector<double>& v_yvtx,
-								 const std::vector<double>& v_zvtx) const
+std::unique_ptr<const Trk::TrackParameters> TrigFastTrackFinder::extrapolateDisTrackToBS(
+   Trk::Track* t, const std::vector<double>& v_xvtx, const std::vector<double>& v_yvtx,  const std::vector<double>& v_zvtx) const
 {
    float vtx_x  = 0;
    float vtx_y  = 0;
@@ -2996,14 +2994,12 @@ const Trk::Perigee* TrigFastTrackFinder::extrapolateDisTrackToBS(Trk::Track* t,
 
    Amg::Vector3D gp(vtx_x, vtx_y, vtx_z);
    Trk::PerigeeSurface persf(gp);
-   const Trk::Perigee* vertexPerigee = nullptr;
-   const Trk::Perigee* trackparPerigee = t->perigeeParameters();
    std::unique_ptr<const Trk::TrackParameters> tmp =
-     m_extrapolator->extrapolateDirectly(Gaudi::Hive::currentContext(), (*trackparPerigee), persf);
+      m_extrapolator->extrapolateDirectly(Gaudi::Hive::currentContext(), (*(t->perigeeParameters())), persf);
    if (tmp && tmp->associatedSurface().type() == Trk::SurfaceType::Perigee) {
-     vertexPerigee = static_cast<const Trk::Perigee*>(tmp.release());
+      return tmp;
    }
-   return vertexPerigee;
+   return nullptr;
 }
 
 TrigFastTrackFinder::DisTrkCategory TrigFastTrackFinder::getDisTrkCategory(Trk::Track* trk) const
@@ -3033,13 +3029,13 @@ TrigFastTrackFinder::DisTrkCategory TrigFastTrackFinder::getDisTrkCategory(Trk::
    return cat;
 }
 
-void TrigFastTrackFinder::fillDisTrkCand(xAOD::TrigComposite* comp, const std::string& prefix, Trk::Track* trk, const Trk::Perigee* vertexPerigee) const
+void TrigFastTrackFinder::fillDisTrkCand(xAOD::TrigComposite* comp, const std::string& prefix, Trk::Track* trk, const std::unique_ptr<const Trk::TrackParameters>& vertexPerigee) const
 {
    std::vector<Trk::Track*> vtmp;
    fillDisTrkCand(comp,prefix,trk,vertexPerigee,false,vtmp);
 }
 
-void TrigFastTrackFinder::fillDisTrkCand(xAOD::TrigComposite* comp, const std::string& prefix, Trk::Track* trk, const Trk::Perigee* vertexPerigee,
+void TrigFastTrackFinder::fillDisTrkCand(xAOD::TrigComposite* comp, const std::string& prefix, Trk::Track* trk, const std::unique_ptr<const Trk::TrackParameters>& vertexPerigee,
 					 bool fillIso, std::vector<Trk::Track*>& tracksForIso) const
 {
    // category
@@ -3180,7 +3176,7 @@ int TrigFastTrackFinder::recoAndFillDisTrkCand(const std::string& base_prefix,
       if( ptrk->perigeeParameters()==nullptr ) continue;
 
       // extrapolate to vertex
-      const Trk::Perigee* vertexPerigee = extrapolateDisTrackToBS(ptrk,v_xvtx,v_yvtx,v_zvtx);
+      std::unique_ptr<const Trk::TrackParameters> vertexPerigee = extrapolateDisTrackToBS(ptrk,v_xvtx,v_yvtx,v_zvtx);
       double d0 = ptrk->perigeeParameters()->parameters()[Trk::d0];
       double z0 = ptrk->perigeeParameters()->parameters()[Trk::z0];
       double d0_wrtVtx = 0;
@@ -3206,7 +3202,7 @@ int TrigFastTrackFinder::recoAndFillDisTrkCand(const std::string& base_prefix,
       double refit_z0 = 0;
       double refit_d0_wrtVtx = 0;
       double refit_z0_wrtVtx = 0;
-      const Trk::Perigee* refitVertexPerigee = nullptr;
+      std::unique_ptr<const Trk::TrackParameters> refitVertexPerigee = nullptr;
       if( refit_trk != nullptr ) {
 	 refitVertexPerigee = extrapolateDisTrackToBS(refit_trk.get(),v_xvtx,v_yvtx,v_zvtx);
 	 if( refitVertexPerigee == nullptr ) {
diff --git a/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.h b/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.h
index 640bd682c42fc9f81d6074175b6d215581832622..60d13349f736aea64877dcd29ecd903e0efdf188 100644
--- a/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.h
+++ b/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.h
@@ -275,10 +275,10 @@ protected:
   bool isPreselPassDisTrackBeforeRefit(Trk::Track*, double, double) const;
   bool isPreselPassDisTrackAfterRefit(Trk::Track*, Trk::Track*, double, double) const;
   bool isGoodForDisTrackVertex(Trk::Track*) const;
-  const Trk::Perigee* extrapolateDisTrackToBS(Trk::Track*, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&) const;
+  std::unique_ptr<const Trk::TrackParameters> extrapolateDisTrackToBS(Trk::Track*, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&) const;
   void filterSharedDisTracks(std::vector<std::tuple<bool, double,Trk::Track*>>&) const;
-  void fillDisTrkCand(xAOD::TrigComposite*, const std::string&, Trk::Track*, const Trk::Perigee*) const;
-  void fillDisTrkCand(xAOD::TrigComposite*, const std::string&, Trk::Track*, const Trk::Perigee*, bool, std::vector<Trk::Track*>&) const;
+  void fillDisTrkCand(xAOD::TrigComposite*, const std::string&, Trk::Track*, const std::unique_ptr<const Trk::TrackParameters>&) const;
+  void fillDisTrkCand(xAOD::TrigComposite*, const std::string&, Trk::Track*, const std::unique_ptr<const Trk::TrackParameters>&, bool, std::vector<Trk::Track*>&) const;
   TrigFastTrackFinder::DisTrkCategory getDisTrkCategory(Trk::Track* trk) const;
   StatusCode findDisTracks(const EventContext&, TrackCollection&,
 			   std::vector<std::tuple<bool, double, Trk::Track*>>&,
diff --git a/Trigger/TrigAnalysis/TrigInDetAnalysisUser/share/TIDAdata-chains-run3.dat b/Trigger/TrigAnalysis/TrigInDetAnalysisUser/share/TIDAdata-chains-run3.dat
index 8514fdd2349a71c8998e3e0824a7c15b0965eebc..98f63cccb3f34fb772e93c4207b6652eb45b794e 100644
--- a/Trigger/TrigAnalysis/TrigInDetAnalysisUser/share/TIDAdata-chains-run3.dat
+++ b/Trigger/TrigAnalysis/TrigInDetAnalysisUser/share/TIDAdata-chains-run3.dat
@@ -115,5 +115,8 @@ testChains = {
     
     "HLT_j45_pf_ftf_preselj20_L1J15:HLT_IDTrack_FS_FTF:HLT_FSRoI:HLT_IDVertex_FS:post:rvtx=HLT_IDVertex_FS",
     "HLT_j45_pf_ftf_preselj20_L1J15:HLT_IDTrack_FS_FTF:HLT_FSRoI:HLT_IDVertex_FSJet:post:rvtx=HLT_IDVertex_FSJet"
-    
+
+    "HLT_j80_pf_ftf_preselj20b95_L1J20:HLT_IDTrack_JetSuper_FTF:HLT_Roi_JetSuper",
+    "HLT_j45_pf_ftf_preselj20_L1jJ40:HLT_IDTrack_JetSuper_FTF:HLT_Roi_JetSuper",
+    "HLT_j20_roiftf_preselj20_L1RD0_FILLED:HLT_IDTrack_JetSuper_FTF:HLT_Roi_JetSuper"    
 };
diff --git a/Trigger/TrigCost/RatesAnalysis/CMakeLists.txt b/Trigger/TrigCost/RatesAnalysis/CMakeLists.txt
index bda30c86e0821a6259388670b381df45af110f85..2f3eab6085b85affb21f953661769c2debff2a5c 100644
--- a/Trigger/TrigCost/RatesAnalysis/CMakeLists.txt
+++ b/Trigger/TrigCost/RatesAnalysis/CMakeLists.txt
@@ -26,4 +26,4 @@ atlas_add_test( RatesAnalysis_test
 
 # Install files from the package:
 atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
-atlas_install_scripts( share/RatesAnalysisFullMenu.py share/RatesEmulationExample.py share/RatesAnalysisPostProcessing.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
+atlas_install_scripts( share/RatesAnalysisFullMenu.py share/RatesEmulationExample.py share/RatesAnalysisPostProcessing.py share/RatesAnalysisOnlineProcessing.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
diff --git a/Trigger/TrigCost/RatesAnalysis/python/Util.py b/Trigger/TrigCost/RatesAnalysis/python/Util.py
index f44d883e707930a1565dd50f6d747491194f8c06..443b9ae6f03059c3d653f7ce5c8a3cbe6245ecb7 100644
--- a/Trigger/TrigCost/RatesAnalysis/python/Util.py
+++ b/Trigger/TrigCost/RatesAnalysis/python/Util.py
@@ -11,6 +11,18 @@
 from AthenaCommon.Logging import logging
 log = logging.getLogger('RatesPostProcessing')
 
+def getTableName(name):
+  tabName = "Table_Rate_"
+  if name == "HLT" or name == "L1":
+    tabName += "Chain" + name
+  else:
+    tabName += name
+
+  tabName += "_HLT_All.csv"
+
+  return tabName 
+
+
 def toCSV(fileName, metadata, HLTTriggers, readL1=False):
   import csv
 
diff --git a/Trigger/TrigCost/RatesAnalysis/share/RatesAnalysisOnlineProcessing.py b/Trigger/TrigCost/RatesAnalysis/share/RatesAnalysisOnlineProcessing.py
new file mode 100755
index 0000000000000000000000000000000000000000..fa299fd741f480f14e37eb62ebf9417df6435ded
--- /dev/null
+++ b/Trigger/TrigCost/RatesAnalysis/share/RatesAnalysisOnlineProcessing.py
@@ -0,0 +1,273 @@
+#!/usr/bin/env python
+#
+#  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+#
+
+'''
+@file RatesAnalysisOnlineProcessing.py
+@brief Script to create summaries with online P1 rates retrieved from pbeast, prescales and unprescaled.
+       Used for validation of Enhanced Bias weighting.
+       For the pbeast authentication use: export PBEAST_SERVER_SSO_SETUP_TYPE=AutoUpdateKerberos
+'''
+
+from AthenaCommon.Logging import logging
+log = logging.getLogger('RatesAnalysisOnlineProcessing')
+
+def readLbStartFromCool(runNumber, lb):
+    ''' 
+    Returns start of the lumiblock from given run in microseconds
+    '''
+    timestamp = readLbFromCool(runNumber, lb)["StartTime"]
+
+    # Returns value UTC nanoseconds since 1970  - convert to microseconds (used by IS)
+    return int(timestamp/1000) if timestamp else -1
+
+
+def readLbEndFromCool(runNumber, lb):
+    ''' 
+    Returns end of the lumiblock from given run in microseconds
+    '''
+    timestamp = readLbFromCool(runNumber, lb)["EndTime"]
+
+    # Returns value UTC nanoseconds since 1970  - convert to microseconds (used by IS)
+    return int(timestamp/1000) if timestamp else -1
+
+
+def readLbFromCool(runNumber, lb):
+    ''' 
+    Returns payload for a lumiblock from given run read from COOL database
+    Based on TriggerCoolUtil.getRunStartTime
+    '''
+    from TrigConfStorage.TriggerCoolUtil import TriggerCoolUtil
+    dbconn = TriggerCoolUtil.GetConnection("CONDBR2")
+    f = dbconn.getFolder( "/TRIGGER/LUMI/LBLB" )
+    limmin=(runNumber << 32)+0
+    limmax=((runNumber+1) << 32)+0
+
+    from PyCool import cool
+    objs = f.browseObjects( limmin, limmax, cool.ChannelSelection(0) )
+    counter = 1 # lumiblocks start indexing from 1
+    while objs.goToNext() and counter < lb:
+        counter+=1
+
+    if counter == lb:
+        return objs.currentRef().payload()
+    else:
+        log.error("Maximum lumiblock for run {0} is {1}".format(runNumber, lb))
+        return None
+
+
+def readChainsGroups(smkey="", dbAlias=""):
+    ''' 
+    Returns dictionary of chain and it's groups based on HLT Menu
+    '''
+    log.debug("Reading HLT menu from {0} {1}".format(smkey, dbAlias))
+    from TrigConfIO.HLTTriggerConfigAccess import HLTMenuAccess
+    hltChains = HLTMenuAccess(dbalias = dbAlias, smkey = smkey).chains()
+
+    groups = {}
+    for chainName in hltChains:
+        groups[chainName] = " ".join(hltChains[chainName]["groups"])
+
+    return groups
+
+
+def readHLTPrescales(pskey="", dbAlias=""):
+    ''' 
+    Returns dictionary of chain and it's prescale
+    '''
+    log.debug("Reading HLT prescales set from {0} {1}".format(pskey, dbAlias))
+    from TrigConfIO.HLTTriggerConfigAccess import HLTPrescalesSetAccess
+    prescalesSet = HLTPrescalesSetAccess(dbalias = dbAlias, hltpskey = pskey).prescales()
+
+    prescales = {}
+    for chainName in prescalesSet:
+        prescales[chainName] = prescalesSet[chainName]["prescale"]
+
+    return prescales
+
+
+def readL1Prescales(pskey="", dbAlias=""):
+    ''' 
+    Returns dictionary of item and it's prescale
+    '''
+    log.debug("Reading L1 prescales set from {0} {1}".format(pskey, dbAlias))
+    from TrigConfIO.L1TriggerConfigAccess import L1PrescalesSetAccess
+    prescalesAccess = L1PrescalesSetAccess(dbalias = dbAlias, l1pskey = pskey)
+
+    prescales = {}
+    for itemName in prescalesAccess.itemNames():
+        prescales[itemName] = prescalesAccess.prescale(itemName)
+
+    return prescales
+
+
+def getKeyForLimits(psk, lbStart, lbEnd):
+    ''' 
+    Retrieve prescale within given lumiblocks
+    '''
+    # Convert str to list of ntups
+    it = iter("".join(c for c in psk if c not in "()[] ").split(","))
+    pskList = [(int(x), int(y), int(z)) for x, y, z in zip(it, it, it)]
+
+    log.debug("Reading the key ranges for {0}".format(psk))
+
+    # COOL format of prescale entry is (key, lbStart, lbEnd)
+    foundKeys = []
+    for prescaleEntry in pskList:
+        if lbStart >= prescaleEntry[1] and lbEnd <= prescaleEntry[2]:
+            log.info("Found prescale key in the range: {0}".format(prescaleEntry))
+            foundKeys.append(prescaleEntry[0])
+
+    if not foundKeys:
+        log.error("Cannot find one prescale for lumiblocks {0} to {1}. Available values: {2}".format(lbStart, lbEnd, pskList))
+        return -1
+    elif len(foundKeys) > 1:
+        log.error("Found more than one prescale key! {0}".format(pskList))
+        return -1
+
+    return foundKeys[0]
+
+
+def toCSV(fileName, dirName, data):
+    ''' 
+    Save rates to csv file
+    '''
+    import csv, os
+
+    os.makedirs(dirName, exist_ok=True)
+    with open(dirName + '/' + fileName, mode='w') as outputCSV_file:
+        rates_csv_writer = csv.writer(outputCSV_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
+
+        rates_csv_writer.writerow(['Name','Group','Rate [Hz]','Rate Err [Hz]', 'Prescale'])
+        rates_csv_writer.writerow(['Trigger name','The group this chain belongs to','Online rate','Error on rate','The prescale of this chain. Only displayed for simple combinations'])
+
+        for trig in data:
+            rates_csv_writer.writerow(trig)
+    
+
+def main():
+    from argparse import ArgumentParser
+    parser = ArgumentParser()
+    parser.add_argument('--runNumber', required=True, type=int, 
+                        help='Number of run to process')
+    parser.add_argument('--lbStart', required=True, type=int, 
+                        help='First lumiblock to record Enhanced Bias data')
+    parser.add_argument('--lbEnd', required=True, type=int, 
+                        help='Last lumiblock to record Enhanced Bias data')
+    parser.add_argument('-s','--server', default='https://atlasop.cern.ch',
+                        help="Pbeast server url. For GPN: https://atlasop.cern.ch, for P1: http://pc-tdq-bst-05.cern.ch:8080")
+    parser.add_argument('--loglevel', type=int, default=3, 
+                        help='Verbosity level: 1 - VERBOSE, 2 - DEBUG, 3 - INFO')
+    args = parser.parse_args()
+    log.setLevel(args.loglevel)
+
+    startOfRange = readLbStartFromCool(args.runNumber, args.lbStart)
+    endOfRange = readLbEndFromCool(args.runNumber, args.lbEnd)
+
+    from time import ctime
+    log.info("Rates will be retrieved for lumiblocks {0}-{1}: {2} - {3}".format(args.lbStart, args.lbEnd, ctime(startOfRange/1E6), ctime(endOfRange/1E6)))
+    log.debug("Start and end timestamps: {0} {1}".format(startOfRange, endOfRange))
+
+    # Read prescales and groups to save in the csv summary
+    from TrigCostAnalysis.CostMetadataUtil import readHLTConfigKeysFromCOOL
+    configMetadata = readHLTConfigKeysFromCOOL(args.runNumber)
+    # TODO save metadata to metadata.json
+
+    hltPrescales = readHLTPrescales(getKeyForLimits(configMetadata[4]["HLTPSK"], args.lbStart, args.lbEnd), configMetadata[2]["DB"])
+    l1Prescales = readL1Prescales(getKeyForLimits(configMetadata[5]["LVL1PSK"], args.lbStart, args.lbEnd), configMetadata[2]["DB"])
+    chainGroups = readChainsGroups(configMetadata[1]["SMK"], configMetadata[2]["DB"])
+
+    # Read prescaled IS rates from pbeast and calculate unprescaled rates
+    # Queries are based on TRP grafana dashboard
+    try:
+        import libpbeastpy
+        pbeast = libpbeastpy.ServerProxy(args.server)
+        hltRates =  pbeast.get_data('ATLAS', 'HLT_Rate', 'Output', 'ISS_TRP.HLT_.*', True, startOfRange, endOfRange)[0].data
+        l1Rates =  pbeast.get_data('ATLAS', 'L1_Rate', 'TAV', 'ISS_TRP.L1_.*', True, startOfRange, endOfRange)[0].data
+        streamRates = pbeast.get_data('ATLAS', 'HLT_Rate', 'Output', 'ISS_TRP.str_.*', True, startOfRange, endOfRange)[0].data
+        groupRates = pbeast.get_data('ATLAS', 'HLT_Rate', 'Output', 'ISS_TRP.grp_.*', True, startOfRange, endOfRange)[0].data
+        recordingRates = pbeast.get_data('ATLAS', 'SFOngCounters', 'WritingEventRate', 'DF.TopMIG-IS:HLT.Counters.*', True, startOfRange, endOfRange)[0].data
+    except ImportError:
+        log.error("Exeption when reading the pbeast information. Remember to setup the tdaq release!")
+        return
+    except RuntimeError:
+        log.error("Exception when reading the pbeast information. Remeber to export the pbeast server sso!")
+        return
+
+    HLTChains = []
+    HLTChainsUnps = []
+    for chain in hltRates:
+        chainName = chain.replace("ISS_TRP.", "")
+        if chainName not in chainGroups:
+            log.debug("Chain {0} is missing from the current menu".format(chainName))
+            continue
+
+        meanRate = 0
+        meanCounter = 0
+        for dataPoint in hltRates[chain]:
+            meanRate += dataPoint.value
+            meanCounter += 1 if dataPoint.value > 0 else 0
+
+        l1Item = "L1_" + chainName.split("L1")[1]
+        l1psk = l1Prescales[l1Item] if l1Item in l1Prescales else "-"
+        rate = meanRate/meanCounter if meanCounter > 0 else 0
+        rateUn = rate * hltPrescales[chainName] * (l1Prescales[l1Item] if l1Item in l1Prescales else 1)
+
+        HLTChains.append([chainName, chainGroups[chainName],  round(rate, 3), "0", "L1:{0} HLT:{1}".format(l1psk, hltPrescales[chainName])])
+        HLTChainsUnps.append([chainName, chainGroups[chainName], round(rateUn, 3), "0", "L1:{0} HLT:{1}".format(l1psk, hltPrescales[chainName])])
+
+    L1Items = []
+    L1ItemsUnps = []
+    for item in l1Rates:
+        
+        meanRate = 0
+        meanCounter = 0
+        for dataPoint in l1Rates[item]:
+            meanRate += dataPoint.value
+            meanCounter += 1 if dataPoint.value > 0 else 0
+
+        itemName = item.replace("ISS_TRP.", "")
+        if "--enabled" not in itemName:
+            continue
+        else:
+            itemName = itemName.replace("--enabled", "")
+        rate = meanRate/meanCounter if meanCounter > 0 else 0
+        rateUn = rate * l1Prescales[itemName]
+
+        L1Items.append([itemName, "-", round(rate, 3), "0", "L1:{0}".format(l1Prescales[itemName])])
+        L1Items.append([itemName, "-", round(rateUn, 3), "0", "L1:{0}".format(l1Prescales[itemName])])
+
+    groups = []
+    groupRates = groupRates | streamRates | recordingRates
+    for group in groupRates:
+        meanRate = 0
+        for dataPoint in groupRates[group]:
+            meanRate += dataPoint.value
+        groupName = group.replace("ISS_TRP.", "") \
+                         .replace("grp", "RATE") \
+                         .replace("str", "STREAM") \
+                         .replace("DF.TopMIG-IS:HLT.Counters.", "HLT_recording_")
+        groups.append([groupName, "-", round(meanRate/len(groupRates[group]), 3), "0", "Multiple"])
+
+    # Save the results
+    from RatesAnalysis.Util import getTableName
+    L1Table = getTableName("L1")
+    HLTTable = getTableName("HLT")
+    GroupTable = getTableName("Group")
+
+
+    prescaledDirName = "costMonitoring_OnlineTRPRates-onlinePS-LB{0}-{1}_{2}/csv/".format(args.lbStart, args.lbEnd, args.runNumber)
+    unprescaledDirName = "costMonitoring_OnlineTRPRates-noPS-LB{0}-{1}_{2}/csv/".format(args.lbStart, args.lbEnd, args.runNumber)
+    log.info("Exporting " + HLTTable)
+    toCSV(HLTTable, prescaledDirName, HLTChains)
+    toCSV(HLTTable, unprescaledDirName, HLTChainsUnps)
+    log.info("Exporting " + L1Table)
+    toCSV(L1Table, prescaledDirName, L1Items)
+    toCSV(L1Table, unprescaledDirName, L1ItemsUnps)
+    log.info("Exporting " + GroupTable)
+    toCSV(GroupTable, prescaledDirName, groups)
+
+
+if __name__== "__main__":
+    main()
diff --git a/Trigger/TrigCost/RatesAnalysis/share/RatesAnalysisPostProcessing.py b/Trigger/TrigCost/RatesAnalysis/share/RatesAnalysisPostProcessing.py
index fe157ed2bff4d2f13d70a147fe3f8ee1a556b45e..3f6ea78a89a51eeb91dd123fbfa9a9fe599b6371 100755
--- a/Trigger/TrigCost/RatesAnalysis/share/RatesAnalysisPostProcessing.py
+++ b/Trigger/TrigCost/RatesAnalysis/share/RatesAnalysisPostProcessing.py
@@ -11,20 +11,10 @@
 '''
 
 import ROOT
-from RatesAnalysis.Util import getMetadata, populateTriggers, getGlobalGroup, toJson, toCSV
+from RatesAnalysis.Util import getTableName, getMetadata, populateTriggers, getGlobalGroup, toJson, toCSV
 from AthenaCommon.Logging import logging
 
 
-def getTableName(name):
-  tabName = "Table_Rate_"
-  if name == "HLT" or name == "L1":
-    tabName += "Chain" + name
-  else:
-    tabName += name
-
-  tabName += "_HLT_All.csv"
-
-  return tabName 
 
 def main():
   from argparse import ArgumentParser
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/ATLAS_CHECK_THREAD_SAFETY b/Trigger/TrigEmulation/TrigBtagEmulationTool/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..67a4178ecc12a91a07eaf9cb8193d3869fb298f9
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+Trigger/TrigEmulation/TrigBtagEmulationTool
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/CMakeLists.txt b/Trigger/TrigEmulation/TrigBtagEmulationTool/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c61c45da4b6c31d69a9795079809466147d2a597
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/CMakeLists.txt
@@ -0,0 +1,34 @@
+# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+
+# Declare the package name:
+atlas_subdir( TrigBtagEmulationTool )
+
+find_package( ROOT COMPONENTS Core )
+
+atlas_add_library(TrigBtagEmulationToolLib
+		  INTERFACE
+		  PUBLIC_HEADERS TrigBtagEmulationTool
+		  LINK_LIBRARIES GaudiKernel
+		  )
+
+atlas_add_component(TrigBtagEmulationTool
+		      src/*.cxx 
+		      src/*.h 
+		      src/components/*.cxx
+		    INCLUDE_DIRS 
+		      ${ROOT_INCLUDE_DIRS}
+		    LINK_LIBRARIES 
+		      ${ROOT_LIBRARIES}
+		      TrigBtagEmulationToolLib
+		      AthenaBaseComps
+		      StoreGateLib
+		      xAODJet
+		      xAODBTagging
+		      xAODTrigger
+		      TrigDecisionToolLib
+		      FlavorTagDiscriminants
+		    )
+
+# Install files from the package:
+atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
+atlas_install_scripts( test/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/TrigBtagEmulationTool/ITrigBtagEmulationTool.h b/Trigger/TrigEmulation/TrigBtagEmulationTool/TrigBtagEmulationTool/ITrigBtagEmulationTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..561ca9e84b7cf9378fb78a7b99a2ccbb30b2a50d
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/TrigBtagEmulationTool/ITrigBtagEmulationTool.h
@@ -0,0 +1,22 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef I_TRIGBTAGEMULATIONTOOL_H
+#define I_TRIGBTAGEMULATIONTOOL_H
+
+#include "GaudiKernel/IAlgTool.h"
+#include <string>
+
+namespace Trig {
+
+  class ITrigBtagEmulationTool 
+    : virtual public IAlgTool {
+  public:
+    virtual StatusCode populateJetManagersTriggerObjects() = 0;
+    virtual bool isPassed(const std::string& chain) const = 0;
+  };
+
+}
+
+#endif
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/python/TrigBtagEmulationToolConfig.py b/Trigger/TrigEmulation/TrigBtagEmulationTool/python/TrigBtagEmulationToolConfig.py
new file mode 100755
index 0000000000000000000000000000000000000000..989e3482354bda17451c635f1095407f52c964a8
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/python/TrigBtagEmulationToolConfig.py
@@ -0,0 +1,146 @@
+# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+
+from AthenaConfiguration.ComponentFactory import CompFactory
+from TriggerMenuMT.HLT.Config.Utility.DictFromChainName import dictFromChainName
+from TriggerMenuMT.HLT.Config.Utility.ChainDefInMenu import ChainProp
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from TrigDecisionTool.TrigDecisionToolConfig import TrigDecisionToolCfg
+
+# Jet Manager Tools
+def jetManagerToolCfg(flags,
+                      name: str,
+                      **kwargs) -> ComponentAccumulator:
+    assert isinstance(name, str), "JetManagerTool name must be a string"
+    acc = ComponentAccumulator()
+    tdt = acc.getPrimaryAndMerge(TrigDecisionToolCfg(flags))
+    kwargs.setdefault('TrigDecisionTool', tdt)
+    acc.setPrivateTools(CompFactory.Trig.JetManagerTool(name, **kwargs))
+    acc.addPublicTool(tdt)
+    return acc
+
+# CNT
+def jetEMTopoCNTManagerToolCfg(flags,
+                               **kwargs) -> ComponentAccumulator:
+    kwargs.setdefault('ChainName', 'HLT_j45_subjesgsc_ftf_L1J15')
+    kwargs.setdefault('JetContainerName', 'HLT_AntiKt4EMTopoJets_subjesIS')
+    return jetManagerToolCfg(flags, 
+                             name = "JM_EMTopo_CNT",
+                             **kwargs)
+
+def jetPFlowCNTManagerToolCfg(flags,
+                              **kwargs) -> ComponentAccumulator:
+    kwargs.setdefault('ChainName', 'HLT_j45_pf_subjesgsc_ftf_L1J15')
+    kwargs.setdefault('JetContainerName', 'HLT_AntiKt4EMPFlowJets_subjesIS')
+    return jetManagerToolCfg(flags,
+                             name = "JM_PFlow_CNT",
+                             **kwargs)
+
+# PRESEL
+def jetEMTopoPRESELManagerToolCfg(flags,
+                                  **kwargs) -> ComponentAccumulator:
+    kwargs.setdefault('JetContainerName', 'HLT_AntiKt4EMTopoJets_subjesIS')
+    return jetManagerToolCfg(flags, 
+                             name = "JM_EMTopo_PRESEL",
+                             **kwargs)
+
+# Emulation Tool                            
+def TrigBtagEmulationToolCfg(flags, 
+                             toBeEmulatedTriggers: list, 
+                             InputChain_EMTopo: str,
+                             InputJetContainer_EMTopo: str,
+                             InputJetContainer_EMTopoPresel: str,
+                             InputChain_PFlow: str,
+                             InputJetContainer_PFlow: str,
+                             InputJetContainer_PFlowPresel: str,
+                             **kwargs) -> ComponentAccumulator:
+    assert isinstance(toBeEmulatedTriggers, list)
+    assert isinstance(InputChain_EMTopo, str)
+    assert isinstance(InputJetContainer_EMTopo, str)
+    assert isinstance(InputJetContainer_EMTopoPresel, str)
+    assert isinstance(InputChain_PFlow, str)
+    assert isinstance(InputJetContainer_PFlow, str)
+    assert isinstance(InputJetContainer_PFlowPresel, str)
+
+    if len(InputChain_EMTopo) == 0:
+        InputChain_EMTopo = 'HLT_j45_subjesgsc_ftf_L1J15'
+    if len(InputJetContainer_EMTopo) == 0:
+        InputJetContainer_EMTopo = 'HLT_AntiKt4EMTopoJets_subjesIS'
+    if len(InputJetContainer_EMTopoPresel) == 0:
+        InputJetContainer_EMTopoPresel = 'HLT_AntiKt4EMTopoJets_subjesIS'
+    if len(InputChain_PFlow) == 0:
+        InputChain_PFlow = 'HLT_j[234][05]_.*pf_ftf_[0b].*[ft]_L1.*'
+    if len(InputJetContainer_PFlow) == 0:
+        InputJetContainer_PFlow = 'HLT_AntiKt4EMPFlowJets_subresjesgscIS_ftf'
+    if len(InputJetContainer_PFlowPresel) == 0:
+        InputJetContainer_PFlowPresel = 'HLT_AntiKt4EMPFlowJets_subresjesgscIS_ftf'
+
+    ### determine trigger thresholds from to be emulated chain names
+    chainDefinitions = {}
+    for chain in toBeEmulatedTriggers:
+        chainDict = dictFromChainName(chain)
+        chainParts = ['L1item:' + chainDict['L1item']]
+        for chainPart in chainDict['chainParts']:
+            # Gaudi::Property has limited support for nested structures, put everything in a long string and parse in C++
+            # and update TrigBtagEmulationChain::parseChainDefinition(...) accordingly
+            partDefinition = ''
+            partDefinition += 'L1threshold:' + chainPart['L1threshold']
+            partDefinition += '|name:' + chainPart['chainPartName']
+            partDefinition += '|multiplicity:' + chainPart['multiplicity']
+            partDefinition += '|threshold:' + chainPart['threshold']
+            partDefinition += '|etaRange:' + chainPart['etaRange']
+            partDefinition += '|jvt:' + (chainPart['jvt'] if chainPart['jvt'] else '-99999')
+            partDefinition += '|tagger:' + chainPart['bTag']
+            partDefinition += '|jetpresel:' + chainPart['trkpresel']
+            partDefinition += '|dijetmass:' + (chainPart['hypoScenario'][len('DJMASS'):] if ('DJMASS' in chainPart['hypoScenario']) else 'None')
+            partDefinition += '|isPFlow:' + ('True' if (chainPart['constitType'] == 'pf') else 'False')
+            partDefinition += '|isShared:' + ('True' if ('SHARED' in chainPart['chainPartName']) else 'False')
+            chainParts.append(partDefinition)
+        chainName = chain.name if isinstance(chain, ChainProp) else chain
+        chainDefinitions[chainName] = chainParts
+    ### all trigger thresholds parsed
+
+    # Component Accumulator
+    acc = ComponentAccumulator()
+
+    ### add TriggerDecisionTool
+    tdt = acc.getPrimaryAndMerge(TrigDecisionToolCfg(flags))
+    acc.addPublicTool(tdt)
+
+    ### set tool options
+    kwargs.setdefault('EmulatedChainDefinitions', chainDefinitions)
+    kwargs.setdefault('TrigDecisionTool', tdt)
+    kwargs.setdefault('InputChain', InputChain_PFlow)
+    
+    kwargs.setdefault('JM_EMTopo_CNT', acc.popToolsAndMerge(jetEMTopoCNTManagerToolCfg(flags,
+                                                                                       ChainName=InputChain_EMTopo,
+                                                                                       JetContainerName=InputJetContainer_EMTopo)))
+    kwargs.setdefault('JM_PFlow_CNT' , acc.popToolsAndMerge(jetPFlowCNTManagerToolCfg(flags,
+                                                                                      ChainName=InputChain_PFlow,
+                                                                                      JetContainerName=InputJetContainer_PFlow)))
+
+    kwargs.setdefault('JM_EMTopo_PRESEL', acc.popToolsAndMerge(jetEMTopoPRESELManagerToolCfg(flags,
+                                                                                             JetContainerName=InputJetContainer_EMTopoPresel)))
+
+    acc.setPrivateTools(CompFactory.Trig.TrigBtagEmulationTool('TrigBtagEmulationTool', **kwargs))
+    return acc
+
+def TrigBtagValidationTestCfg(flags,
+                              **kwargs) -> ComponentAccumulator:
+    acc = ComponentAccumulator()
+    histSvc = CompFactory.THistSvc()
+    histSvc.Output += ["VALIDATION DATAFILE='validation.root' OPT='RECREATE'"]
+    acc.addService(histSvc)
+
+    options = {}
+    options['EmulatedChains'] = [c.name for c in kwargs['toBeEmulatedTriggers']]
+
+    options['TrigBtagEmulationTool'] = acc.popToolsAndMerge( TrigBtagEmulationToolCfg(flags,
+                                                                                      **kwargs))
+
+    from TrigDecisionTool.TrigDecisionToolConfig import TrigDecisionToolCfg
+    tdt = acc.getPrimaryAndMerge(TrigDecisionToolCfg(flags))
+    acc.addPublicTool(tdt)
+    options['TrigDecisionTool'] = tdt
+
+    acc.addEventAlgo( CompFactory.Trig.TrigBtagValidationTest('TrigBtagValidation', **options) )
+    return acc
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/src/JetManagerTool.cxx b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/JetManagerTool.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..edbc5a609a45566d38dcabf105b986894f9b618c
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/JetManagerTool.cxx
@@ -0,0 +1,243 @@
+/*
+Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration 
+*/
+
+#include "src/JetManagerTool.h"
+
+namespace Trig {
+
+//**********************************************************************
+
+JetManagerTool::JetManagerTool(const std::string& type,	
+			       const std::string& name, 
+			       const IInterface* parent) 
+  : AthAlgTool(type, name, parent)
+{}
+  
+StatusCode JetManagerTool::initialize() {
+  ATH_MSG_DEBUG( "Initializing " << name() );
+  ATH_CHECK( m_trigDec.retrieve() );
+  
+  m_jet_Containers = std::make_unique<xAOD::JetContainer>();
+  m_jet_Containers_Aux = std::make_unique<xAOD::JetAuxContainer>();
+  m_jet_Containers->setStore( m_jet_Containers_Aux.get() );
+  ATH_CHECK(m_jetInputKey.initialize());
+
+  m_jetRoI_Containers = std::make_unique<xAOD::JetRoIContainer>();
+  m_jetRoI_Containers_Aux = std::make_unique<xAOD::JetRoIAuxContainer>();
+  m_jetRoI_Containers->setStore( m_jetRoI_Containers_Aux.get() );
+  ATH_CHECK(m_jetRoIInputKey.initialize());
+  
+  m_btagging_Containers = std::make_unique<xAOD::BTaggingContainer>();
+  m_btagging_Containers_Aux = std::make_unique<xAOD::BTaggingAuxContainer>();
+  m_btagging_Containers->setStore( m_btagging_Containers_Aux.get() );
+  
+  return StatusCode::SUCCESS;
+}
+
+StatusCode JetManagerTool::retrieveByNavigation() {
+  clear();
+  ATH_MSG_DEBUG( "Retrieving via Navigation ..." );
+  
+  if (m_trigDec->getNavigationFormat() == "TriggerElement") {
+    ATH_MSG_DEBUG( "Using Run 2 Navigation API." );
+    
+    Trig::FeatureContainer features = m_trigDec->features(m_chain);
+    const std::vector< Trig::Combination >& combinations = features.getCombinations();
+    
+    for ( Trig::Combination combo : combinations ) {
+      getFromCombo( m_jet_Containers, combo, m_jetKey);
+    }
+  }
+  else {
+    ATH_MSG_DEBUG( "Using Run 3 Navigation API." );
+    
+    const std::vector< TrigCompositeUtils::LinkInfo<xAOD::JetContainer> > fc_jet =
+      m_trigDec->features<xAOD::JetContainer>( m_chain );
+    
+    for(const auto& jetLinkInfo : fc_jet) {
+      if(jetLinkInfo.isValid()) {
+	const xAOD::Jet *jet = *(jetLinkInfo.link);
+	
+	bool unique = true;
+	for ( xAOD::Jet *storedJet : *m_jet_Containers.get() ) {
+	  if ( jet->pt() == storedJet->pt() &&
+	       jet->eta() == storedJet->eta() &&
+	       jet->phi() == storedJet->phi() ) {
+	    // if the duplicate has a btagging object linked to it, use that one instead
+	    if(xAOD::BTaggingUtilities::getBTagging(*jet)) {
+	      *storedJet = *jet;
+	    }
+	    
+	    unique = false;
+	    break;
+	  }
+	}
+	
+	if ( unique ) {
+	  m_jet_Containers->push_back( new xAOD::Jet( *jet ) ); // push back a copy of the jet
+	}
+      }
+    }
+  }
+  
+  jetCopy( m_jet_Containers );
+ 
+  return StatusCode::SUCCESS;
+}
+
+template<typename external_collection_t> 
+bool JetManagerTool::getFromCombo(std::unique_ptr< external_collection_t > &output,
+				  const Trig::Combination& combo,
+				  const std::string& key) {
+  using collection_t = typename std::remove_const< typename std::remove_pointer< typename external_collection_t::value_type >::type >::type;
+  const std::vector< Trig::Feature< external_collection_t > > tmpFeatures = combo.containerFeature< external_collection_t >( key.c_str() );
+  
+  for ( const Trig::Feature< external_collection_t >& feature : tmpFeatures ) {
+    const external_collection_t *tmpContainer = nullptr;
+    tmpContainer = feature.cptr();
+    
+    if (tmpContainer == nullptr) {
+      return false;
+    }
+    
+    collection_t* toBeAdded = new collection_t();
+    output->push_back( toBeAdded );
+    *toBeAdded = *tmpContainer->at(0);
+  }
+  
+  return true;
+}
+  
+void JetManagerTool::jetCopy( const std::unique_ptr< xAOD::JetContainer >& container ) 
+{
+  for ( const xAOD::Jet *theJet : *container.get() ) {
+    auto toAdd = std::make_shared< TrigBtagEmulationJet >(name() + ".TrigBtagEmulationJet", theJet);
+    toAdd->setLevel(msgLevel());
+    m_outputJets.push_back( toAdd );
+    m_sortedPreselJets.push_back({theJet->pt(), theJet->eta(), theJet->p4()});
+  }
+  
+  sort(m_sortedPreselJets.begin(), m_sortedPreselJets.end(), [](const auto& lhs, const auto& rhs){return (lhs.pt > rhs.pt);});
+  ATH_MSG_DEBUG( " - Ten largest jets:");
+  for(unsigned int i = 0; i < 10 && i < m_sortedPreselJets.size(); i++) {
+    ATH_MSG_DEBUG( " - pt=" << (m_sortedPreselJets[i].pt / Gaudi::Units::GeV) << " eta=" << m_sortedPreselJets[i].eta );
+  }
+}
+
+void JetManagerTool::jetCopy( const std::unique_ptr< xAOD::JetRoIContainer >& container ) {
+  for ( const xAOD::JetRoI *theJetRoI : *container.get() ) {
+    auto toAdd = std::make_shared< TrigBtagEmulationJet >( name() + ".TrigBtagEmulationJet", theJetRoI, m_uses4x4 );
+    toAdd->setLevel(msgLevel());
+    m_outputJets.push_back( toAdd );
+    
+  }
+}
+
+StatusCode JetManagerTool::retrieveByContainer() {
+  clear();
+  ATH_MSG_DEBUG( "Retrieving via Container ..." );
+  
+  // In case we want LVL1 Jet we shoud use jet RoIs
+  const xAOD::JetRoIContainer *theJetRoIContainer = nullptr;
+  const xAOD::JetContainer *theJetContainer = nullptr;
+  const std::string ilContainer = m_jetcontainer;
+  
+  // Get Jet Objects
+  if ( ilContainer == "LVL1JetRoIs" ) {
+    // We are retrieving xAOD::JetRoI object
+    m_jetRoIInputKey = ilContainer;
+    SG::ReadHandle< xAOD::JetRoIContainer > jetRoIContainerHandle = SG::makeHandle( m_jetRoIInputKey, Gaudi::Hive::currentContext() );
+    if(!jetRoIContainerHandle.isValid()) {
+      ATH_MSG_ERROR( "CANNOT RETRIEVE JET-ROI CONTAINER '" << m_jetRoIInputKey << "'" );
+      return StatusCode::FAILURE;
+    }
+    theJetRoIContainer = jetRoIContainerHandle.get();
+    
+    for ( const xAOD::JetRoI *jetRoI : *theJetRoIContainer ) {
+      bool unique = true;
+      for ( const xAOD::JetRoI *storedJetRoI : *m_jetRoI_Containers.get() ) {
+	if ( jetRoI->et4x4() == storedJetRoI->et4x4() &&
+	     jetRoI->et8x8() == storedJetRoI->et8x8() &&
+	     jetRoI->eta() == storedJetRoI->eta() &&
+	     jetRoI->phi() == storedJetRoI->phi() ) {
+	  unique = false;
+	}
+      }
+      
+      if (unique) { 
+	xAOD::JetRoI *toBeAdded = new xAOD::JetRoI();
+	m_jetRoI_Containers->push_back( toBeAdded );
+	*toBeAdded = *jetRoI;
+      }
+    }
+    
+    jetCopy( m_jetRoI_Containers );
+  }
+  else {
+    // We are retrieving xAOD::Jet object
+    m_jetInputKey = ilContainer;
+    SG::ReadHandle< xAOD::JetContainer > jetContainerHandle = SG::makeHandle( m_jetInputKey, Gaudi::Hive::currentContext() );
+    if(!jetContainerHandle.isValid()) {
+      ATH_MSG_ERROR( "Cannot retrieve jet container " << m_jetInputKey );
+      return StatusCode::FAILURE;
+    }
+    theJetContainer = jetContainerHandle.get();
+    
+    for ( const xAOD::Jet *jet : *theJetContainer ) {
+      bool unique = true;
+      for ( const xAOD::Jet *storedJet : *m_jet_Containers.get() ) {
+	if ( jet->pt() == storedJet->pt() &&
+	     jet->eta() == storedJet->eta() &&
+	     jet->phi() == storedJet->phi() ) {
+	  unique = false;
+	  break;
+	}
+      }
+      
+      if ( unique ) {
+	xAOD::Jet *toBeAdded = new xAOD::Jet();
+	m_jet_Containers->push_back( toBeAdded );
+	*toBeAdded = *jet;
+      }
+    }
+    
+    // and now the bjets, which will all overlap with the jets we already have
+    m_jetInputKey = ilContainer + "_bJets";
+    jetContainerHandle = SG::makeHandle( m_jetInputKey, Gaudi::Hive::currentContext() );
+    if(jetContainerHandle.isValid()) {
+      theJetContainer = jetContainerHandle.get();
+      
+      for ( const xAOD::Jet *jet : *theJetContainer ) {
+	for ( xAOD::Jet *storedJet : *m_jet_Containers.get() ) {
+	  if ( jet->pt() == storedJet->pt() &&
+	       jet->eta() == storedJet->eta() &&
+	       jet->phi() == storedJet->phi() ) {
+	    *storedJet = *jet; // deep copy
+	    break;
+	  }
+	}
+      }
+    }
+    else {
+      ATH_MSG_INFO( "Couldn't retrieve b-jet container " << m_jetInputKey << ", maybe no b-jet in the event? If there are, this is an ERROR");
+    }
+    
+    jetCopy( m_jet_Containers );
+  }
+  
+  return StatusCode::SUCCESS;
+}
+
+bool JetManagerTool::clear() {
+  m_jet_Containers->clear();
+  m_jetRoI_Containers->clear();
+  m_btagging_Containers->clear();
+  m_outputJets.clear();
+  m_sortedPreselJets.clear(); 
+  return true;
+}
+
+}
+
+//**********************************************************************
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/src/JetManagerTool.h b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/JetManagerTool.h
new file mode 100755
index 0000000000000000000000000000000000000000..16e0ee38e3cefc5a7a1d6fbc3a9cfdc9364a1513
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/JetManagerTool.h
@@ -0,0 +1,109 @@
+/*
+Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef Jet_Manager_H
+#define Jet_Manager_H
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "src/TrigBtagEmulationJet.h"
+
+#include "GaudiKernel/ToolHandle.h"
+#include "StoreGate/ReadHandleKey.h"
+
+#include "xAODTrigger/JetRoIContainer.h"
+#include "xAODJet/JetAttributes.h"
+#include "xAODJet/JetContainer.h"
+#include "xAODJet/JetAuxContainer.h"
+#include "xAODBTagging/BTaggingContainer.h"
+#include "xAODBTagging/BTaggingAuxContainer.h"
+#include "xAODBTagging/BTaggingUtilities.h"
+
+#include "TrigDecisionTool/TrigDecisionTool.h"
+
+#include "TLorentzVector.h"
+#include <string>
+#include <vector>
+
+namespace Trig {
+
+  class JetManagerTool : 
+    public AthAlgTool {
+  public:
+    JetManagerTool(const std::string& type, 
+		   const std::string& name, 
+		   const IInterface* parent);
+    virtual ~JetManagerTool() = default;
+    
+    virtual StatusCode initialize() override;
+        
+    StatusCode retrieveByNavigation();
+    StatusCode retrieveByContainer();
+    
+    const std::string& chainName() const;
+    const std::string& jetContainerName() const;    
+    unsigned int jetSize() const;
+    unsigned int jetRoISize() const;
+    unsigned int btaggingSize() const;
+    
+    struct PreselJet {
+      double pt;
+      double eta;
+      TLorentzVector p4;
+    };
+    
+    const std::vector< std::shared_ptr< TrigBtagEmulationJet > >& getJets() const;
+    const std::vector<PreselJet>& getSortedPreselJets() const;
+    
+  private:
+    
+    bool clear();
+
+    template<typename external_collection_t> 
+      bool getFromCombo(std::unique_ptr< external_collection_t >&, 
+			const Trig::Combination&,
+			const std::string& key = "");
+    
+    void jetCopy( const std::unique_ptr< xAOD::JetContainer >& );
+    void jetCopy( const std::unique_ptr< xAOD::JetRoIContainer>& );
+    
+  private:
+    PublicToolHandle< Trig::TrigDecisionTool > m_trigDec {this, "TrigDecisionTool", "","Trigger Decision Tool"};
+    SG::ReadHandleKey< xAOD::JetContainer > m_jetInputKey {this, "InputJets", "Unspecified", "Input Jet Collection Key, retrieved from reconstructed jets"};
+    SG::ReadHandleKey< xAOD::JetRoIContainer > m_jetRoIInputKey {this, "InputJetRoIs", "Unspecified", "Input Jet RoI Collection Key, retrieved from reconstructed jets"};
+
+    // Chain: source of unbiased b-jets 
+    Gaudi::Property<std::string> m_chain {this, "ChainName", "", "Chain: source of unbiased b-jets "};    
+    // Container
+    Gaudi::Property<std::string> m_jetcontainer {this, "JetContainerName", "", "Jet Container"};
+    // Keys for Navigation
+    Gaudi::Property<std::string> m_jetKey {this, "JetNavigationKey", ""};
+    Gaudi::Property<std::string> m_btagKey {this, "BtagNavigationKey", ""};
+    // For jetRoI, see if 4x4 should be used instead of 8x8
+    Gaudi::Property<bool> m_uses4x4 {this, "Use4x4", false};
+    
+    // Local containers
+    std::unique_ptr< xAOD::JetContainer > m_jet_Containers;
+    std::unique_ptr< xAOD::JetAuxContainer > m_jet_Containers_Aux;
+
+    std::unique_ptr< xAOD::JetRoIContainer > m_jetRoI_Containers;
+    std::unique_ptr< xAOD::JetRoIAuxContainer > m_jetRoI_Containers_Aux;
+
+    std::unique_ptr< xAOD::BTaggingContainer > m_btagging_Containers;
+    std::unique_ptr< xAOD::BTaggingAuxContainer > m_btagging_Containers_Aux;
+    
+    std::vector< std::shared_ptr< TrigBtagEmulationJet > > m_outputJets;
+    std::vector<PreselJet> m_sortedPreselJets;
+    
+  };
+
+  inline const std::string& JetManagerTool::chainName() const { return m_chain.value(); }
+  inline const std::string& JetManagerTool::jetContainerName() const { return m_jetcontainer.value(); }
+  inline unsigned int JetManagerTool::jetSize() const { return m_jet_Containers->size(); }
+  inline unsigned int JetManagerTool::jetRoISize() const { return m_jetRoI_Containers->size(); }
+  inline unsigned int JetManagerTool::btaggingSize() const { return m_btagging_Containers->size(); }
+  inline const std::vector< std::shared_ptr< TrigBtagEmulationJet > >& JetManagerTool::getJets() const { return m_outputJets; }
+  inline const std::vector<JetManagerTool::PreselJet>& JetManagerTool::getSortedPreselJets() const { return m_sortedPreselJets; }
+} // namespace
+
+#endif
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationChain.cxx b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationChain.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..1bb3cf602f5c25d607e6bf8b59cc8d263736b9c0
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationChain.cxx
@@ -0,0 +1,519 @@
+
+/*
+Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration 
+*/
+
+#include "src/TrigBtagEmulationChain.h"
+
+#define CHAINPART_VARSEP "|"
+#define CHAINPART_VARDEF ":"
+#define CHAINPART_INDEX(cp,v) ((cp).find(v) +strlen(v))
+#define CHAINPART_LENGTH(cp,v) ((cp).substr((cp).find(v) +strlen(v)).find(CHAINPART_VARSEP))
+#define CHAINPART_VARIABLE(cp,v) (cp).substr(CHAINPART_INDEX((cp), (std::string(CHAINPART_VARSEP) + v + CHAINPART_VARDEF).c_str()), \
+											CHAINPART_LENGTH((cp), (std::string(CHAINPART_VARSEP) + v + CHAINPART_VARDEF).c_str()))
+
+
+namespace Trig {
+
+TrigBtagEmulationChain::TrigBtagEmulationChain(const std::string& name,
+                                               const std::vector< std::string >& definition,
+                                               PublicToolHandle< Trig::TrigDecisionTool >& tdt )
+  : AthMessaging("TrigBtagEmulationChain." + name),
+    m_name( name ),
+    m_trigDec( tdt )
+{
+  parseChainDefinition(definition);
+}
+
+void TrigBtagEmulationChain::parseChainDefinition(const std::vector< std::string >& definition)
+{
+  if(definition.size() > 1) {
+    m_l1_requirement = definition[0].substr(7); // 7 -> strlen("L1item:")
+    ATH_MSG_DEBUG( name() << ":");
+    ATH_MSG_DEBUG( " -            L1 item: " << m_l1_requirement);
+
+    std::size_t n_def_size = definition.size();
+    m_chainPartName.reserve(n_def_size);
+    m_jet_multiplicity.reserve(n_def_size);
+    m_jet_pt.reserve(n_def_size);
+    m_jet_eta_min.reserve(n_def_size);
+    m_jet_eta_max.reserve(n_def_size);
+    m_jvt.reserve(n_def_size);
+    m_tagger.reserve(n_def_size);
+    m_is_PFlow.reserve(n_def_size);
+    
+    for(size_t chainPart_idx = 1; chainPart_idx < definition.size(); chainPart_idx++) {
+      // L1threshold:J20_multiplicity:1_threshold:45_etaRange:0eta290_tagger:bdl1r70_isPFlow:True
+      std::string chainPart = definition[chainPart_idx];
+      ATH_MSG_DEBUG( " > " << chainPart);
+      
+      std::string L1threshold = CHAINPART_VARIABLE(chainPart, "L1threshold");
+      int jet_multiplicity = std::stoi(CHAINPART_VARIABLE(chainPart, "multiplicity"));
+      std::string chainPartName = CHAINPART_VARIABLE(chainPart, "name");
+      double jet_pt = static_cast<double>( std::stoi(CHAINPART_VARIABLE(chainPart, "threshold")) * 1e3 );
+      std::string etaRange = CHAINPART_VARIABLE(chainPart, "etaRange");
+      double jvt = std::stod(CHAINPART_VARIABLE(chainPart, "jvt")) / 1e2;
+      std::string tagger = (CHAINPART_VARIABLE(chainPart, "tagger")).size() ? (CHAINPART_VARIABLE(chainPart, "tagger")).substr(1) : "";
+      std::string jetpresel = (CHAINPART_VARIABLE(chainPart, "jetpresel")).size() ? (CHAINPART_VARIABLE(chainPart, "jetpresel")).substr(6) : "";
+      std::string dijetmass = (CHAINPART_VARIABLE(chainPart, "dijetmass")).size() ? CHAINPART_VARIABLE(chainPart, "dijetmass") : "";
+      bool is_PFlow = (CHAINPART_VARIABLE(chainPart, "isPFlow") == "True");
+      bool is_shared = (CHAINPART_VARIABLE(chainPart, "isShared") == "True");
+      
+      double jet_eta_min = static_cast<double>( std::stoi(etaRange) / 100. );
+      double jet_eta_max = static_cast<double>( std::stoi(etaRange.substr(etaRange.find("eta") + 3)) / 100. ); // 3 -> strlen("eta")
+      
+      // jet preselection parsing
+      if(jetpresel == "el") { // nopresel (got cut to "el" by substr(6))
+	jetpresel = "";
+      }
+      else {
+	auto presel_separator = jetpresel.find("XX");
+	while(presel_separator != std::string::npos) {
+	  m_jet_presel.push_back(jetpresel.substr(0, presel_separator));
+	  jetpresel = jetpresel.substr(presel_separator + 2); // 2 -> strlen("XX")
+	  presel_separator = jetpresel.find("XX");
+	}
+	m_jet_presel.push_back(jetpresel);
+      }
+      
+      
+      ATH_MSG_DEBUG( " -       L1 threshold: " << L1threshold);
+      ATH_MSG_DEBUG( " -   jet multiplicity: " << jet_multiplicity);
+      ATH_MSG_DEBUG( " -      jet threshold: " << jet_pt);
+      ATH_MSG_DEBUG( " -          eta range: [" << jet_eta_min << "," << jet_eta_max << "]");
+      ATH_MSG_DEBUG( " -            JVT cut: " << jvt);
+      ATH_MSG_DEBUG( " - BTagging algorithm: " << tagger);
+      ATH_MSG_DEBUG( " -   Jet preselection: " << m_jet_presel);
+      ATH_MSG_DEBUG( " -         Dijet Mass: " << dijetmass);
+      ATH_MSG_DEBUG( " -           is PFlow: " << (is_PFlow ? "YES":"NO"));
+      
+      m_chainPartName.push_back(chainPartName);
+      m_jet_multiplicity.push_back(jet_multiplicity);
+      m_jet_pt.push_back(jet_pt);
+      m_jet_eta_min.push_back(jet_eta_min);
+      m_jet_eta_max.push_back(jet_eta_max);
+      m_jvt.push_back(jvt);
+      m_tagger.push_back(tagger);
+      m_is_PFlow.push_back(is_PFlow);
+      
+      if(is_shared) {
+	m_shared_idx = chainPart_idx;
+      }
+      
+      if(m_dijetmass.empty() || dijetmass != "None") {
+	m_dijetmass = dijetmass;
+      }
+    }
+    
+    ATH_MSG_DEBUG( " ^^^         DijetMass: " << m_dijetmass);
+    ATH_MSG_DEBUG( " ^^^         is SHARED: " << (m_shared_idx ? "YES":"NO"));
+  }
+  else {
+    ATH_MSG_ERROR( "Couldn't parse chain definition: " << definition[0] );
+  }
+}
+
+StatusCode TrigBtagEmulationChain::addJetManager(const std::string& name, 
+						 ToolHandle<Trig::JetManagerTool>& jm) 
+{
+  if (m_jetmanagers.find(name) != m_jetmanagers.end()) {
+    ATH_MSG_ERROR("Trying to store a JetManager that is already in storage!");
+    return StatusCode::FAILURE;
+  }
+
+  m_jetmanagers[name] = &jm;
+  return StatusCode::SUCCESS;
+}
+
+bool TrigBtagEmulationChain::isPassed() const {
+  return evaluate_L1() and evaluate_HLT();
+}
+
+bool TrigBtagEmulationChain::evaluate_L1() const {
+  // IMPROVE: simulate L1 as well, don't rely on TDT
+  bool res = tdt()->isPassed(m_l1_requirement);
+  ATH_MSG_DEBUG( name() << " passed L1: " << (res ? "YES":"NO") );
+  return res;
+}
+
+bool TrigBtagEmulationChain::evaluate_HLT() const
+{
+  bool res = false;
+  
+  bool is_all_PFlow = true;
+  for(const auto& is_chainPart_PFlow: m_is_PFlow) {
+    if(!is_chainPart_PFlow) {
+      is_all_PFlow = false;
+      break;
+    }
+  }
+  
+  if(is_all_PFlow) {
+    const auto& jm_pflow_cnt = *m_jetmanagers.at("JM_PFlow_CNT");
+    const auto& jm_emtopo_presel = *m_jetmanagers.at("JM_EMTopo_PRESEL");
+    
+    bool no_preselection_cut = (m_jet_presel.size() == 0);
+    bool no_dijetcut = (m_dijetmass == "None");
+    if(jm_pflow_cnt && (jm_emtopo_presel || (no_preselection_cut && no_dijetcut))) {
+      if((no_preselection_cut || evaluate_preselection(jm_emtopo_presel)) &&
+	 (no_dijetcut || evaluate_dijetmass(jm_pflow_cnt))) {
+	// if we got here, the preselection and dijet mass cuts are already satisfied
+	int nChainParts = static_cast<int>( m_jet_multiplicity.size() );
+	if(m_shared_idx) {
+	  // chain uses the shared operator, we basically have two chains to check
+	  std::vector<std::vector<bool>> chainPart_passedjets = evaluate_HLT_chainParts(jm_pflow_cnt, 0, m_shared_idx);
+	  std::vector<std::vector<bool>> chainPart_passedjets_btag = evaluate_HLT_chainParts(jm_pflow_cnt, m_shared_idx, nChainParts);
+	  
+	  std::vector<std::string> chainPartNames_leg1 = std::vector(m_chainPartName.begin(), m_chainPartName.begin() +m_shared_idx);
+	  std::vector<int> multiplicities_leg1 = std::vector(m_jet_multiplicity.begin(), m_jet_multiplicity.begin() +m_shared_idx);
+	  std::vector<std::string> chainPartNames_leg2 = std::vector(m_chainPartName.begin() +m_shared_idx, m_chainPartName.end());
+	  std::vector<int> multiplicities_leg2 = std::vector(m_jet_multiplicity.begin() +m_shared_idx, m_jet_multiplicity.end());
+	  
+	  res = allocate_jets_to_chainParts(chainPart_passedjets, chainPartNames_leg1, multiplicities_leg1) &&
+	    allocate_jets_to_chainParts(chainPart_passedjets_btag, chainPartNames_leg2, multiplicities_leg2);
+	}
+	else {
+	  std::vector<std::vector<bool>> chainPart_passedjets = evaluate_HLT_chainParts(jm_pflow_cnt, 0, nChainParts);
+	  
+	  std::vector<std::string> chainPartNames = std::vector(m_chainPartName.begin(), m_chainPartName.end());
+	  std::vector<int> multiplicities = std::vector(m_jet_multiplicity.begin(), m_jet_multiplicity.end());
+	  
+	  res = allocate_jets_to_chainParts(chainPart_passedjets, chainPartNames, multiplicities);
+	}
+      }
+    }
+    else {
+      ATH_MSG_ERROR( "Could not retrieve JetManagers" );
+    }
+  }
+  else {
+    ATH_MSG_ERROR( "Only PFlow jets are supported at this moment" );
+  }
+  
+  
+  return res;
+}
+
+
+bool TrigBtagEmulationChain::evaluate_preselection(const ToolHandle<Trig::JetManagerTool>& jm) const 
+{
+  bool res = false;
+  int presel_multiplicity = 1;
+  double presel_ptcut = 0.;
+  double presel_eta_min = 0.;
+  double presel_eta_max = 0.;
+  
+  if(m_jet_presel.size() == 1) {
+    // single preselection cut
+    std::string presel_part = m_jet_presel[0];
+    int preseljets_passed = 0;
+    
+    parse_preselection(presel_part, presel_multiplicity, presel_ptcut, presel_eta_min, presel_eta_max);
+    
+    for( const auto& preseljet: jm->getSortedPreselJets() ) {
+      if((preseljet.pt / Gaudi::Units::GeV) >= presel_ptcut &&
+	 presel_eta_min < std::fabs(preseljet.eta) && std::fabs(preseljet.eta) < presel_eta_max) {
+	
+	ATH_MSG_DEBUG( "   - Preselection jet pt=" << (preseljet.pt / Gaudi::Units::GeV) << " eta=" << preseljet.eta << " passed.");
+	preseljets_passed++;
+      }
+      else if((preseljet.pt / Gaudi::Units::GeV) < presel_ptcut) {
+	// no more Preselection jets left with high enough pt
+	break;
+      }
+      
+      if(preseljets_passed >= presel_multiplicity) {
+	res = true;
+	break;
+      }
+    }
+  }
+  else {
+    // multi-threshold preselection
+    std::vector<std::vector<bool>> chainPart_passedjets(m_jet_presel.size());
+    size_t chainPart_passedjets_lenmax = 0;
+    std::vector<int> multiplicities;
+    for(size_t chainPart_idx = 0; chainPart_idx < chainPart_passedjets.size(); chainPart_idx++) {
+      parse_preselection(m_jet_presel[chainPart_idx], presel_multiplicity, presel_ptcut, presel_eta_min, presel_eta_max);
+      multiplicities.push_back(presel_multiplicity);
+      
+      for( const auto& preseljet: jm->getSortedPreselJets() ) {
+	if((preseljet.pt / Gaudi::Units::GeV) >= presel_ptcut &&
+	   presel_eta_min < std::fabs(preseljet.eta) && std::fabs(preseljet.eta) < presel_eta_max) {
+	  // flag jet as passed this part of preselection
+	  chainPart_passedjets[chainPart_idx].push_back(true);
+	}
+	else {
+	  chainPart_passedjets[chainPart_idx].push_back(false);
+	}
+	
+	if((preseljet.pt / Gaudi::Units::GeV) < presel_ptcut) {
+	  // no more Preselection jets left with high enough pt
+	  if(chainPart_passedjets[chainPart_idx].size() > chainPart_passedjets_lenmax) {
+	    chainPart_passedjets_lenmax = chainPart_passedjets[chainPart_idx].size();
+	  }
+	  break;
+	}
+      }
+    }
+    
+    for(auto& chainPart_passedjets_row: chainPart_passedjets) {
+      // make all rows in the chainPart_jet_matrix equal length
+      while(chainPart_passedjets_row.size() < chainPart_passedjets_lenmax) {
+	chainPart_passedjets_row.push_back(false);
+      }
+    }
+    
+    res = allocate_jets_to_chainParts(chainPart_passedjets, m_jet_presel, multiplicities);
+  }
+  
+  return res;
+}
+
+bool TrigBtagEmulationChain::evaluate_dijetmass(const ToolHandle<Trig::JetManagerTool>& jm) const
+{
+  bool res = false;
+  double dijet_mass = 0.;
+  double dijet_minjetpt = 0.;
+  double dijet_dphi = -1.;
+  double dijet_deta = -1.;
+  parse_dijetmass(dijet_mass, dijet_minjetpt, dijet_dphi, dijet_deta);
+  
+  const auto& preselJets = jm->getSortedPreselJets();
+  for( const auto& jet1: preselJets ) {
+    if( (jet1.pt / Gaudi::Units::GeV) < dijet_minjetpt ) {
+      break;
+    }
+    
+    for( const auto& jet2: preselJets ) {
+      if( (jet2.pt / Gaudi::Units::GeV) < dijet_minjetpt ) {
+	break;
+      }
+      
+      double mass = (jet1.p4 + jet2.p4).M(); // MeV, since PreselJet pt is in MeV too
+      double adphi = std::abs(jet1.p4.DeltaPhi(jet2.p4));
+      double adeta = std::abs(jet1.eta - jet2.eta);
+      
+      if((mass / Gaudi::Units::GeV) >= dijet_mass &&
+	 (dijet_dphi < 0 || adphi < dijet_dphi) &&
+	 (dijet_deta < 0 || adeta > dijet_deta) ) {
+	ATH_MSG_DEBUG( "   - Dijet system " << (jet1.pt / Gaudi::Units::GeV) << " and " << (jet2.pt / Gaudi::Units::GeV) << " passed " << m_dijetmass );
+	res = true;
+	break;
+      }
+    }
+  }
+  
+  return res;
+}
+
+std::vector<std::vector<bool>> TrigBtagEmulationChain::evaluate_HLT_chainParts(const ToolHandle<Trig::JetManagerTool>& jm, 
+									       int idx_begin, 
+									       int idx_end) const {
+  std::vector<std::vector<bool>> chainPart_passedjets(idx_end - idx_begin);
+  
+  for(size_t chainPart_idx = 0; chainPart_idx < chainPart_passedjets.size(); chainPart_idx++) {
+    double jet_pt = m_jet_pt[chainPart_idx +idx_begin];
+    double jet_eta_min = m_jet_eta_min[chainPart_idx +idx_begin];
+    double jet_eta_max = m_jet_eta_max[chainPart_idx +idx_begin];
+    double jvtcut = m_jvt[chainPart_idx +idx_begin];
+    std::string tagger = m_tagger[chainPart_idx +idx_begin];
+    
+    ATH_MSG_DEBUG( ">-- " << m_chainPartName[chainPart_idx +idx_begin] << ":" );
+    for( const auto& jet: jm->getJets() ) {
+      float jvt = jet->jvt();
+      bool passedJvt = jvt > jvtcut ||
+	jet->pt() / Gaudi::Units::GeV > 120. ||
+	std::fabs(jet->eta()) > 2.5;
+      
+      if (tagger == "ewTagger") tagger = "newTagger";
+      bool is_bjet = (tagger != "") and (s_tagger_wp.find(tagger) != s_tagger_wp.end())
+	? jet->isPassedBTagger(tagger, s_tagger_wp.at(tagger)) 
+	: false;
+      
+      if(jet->pt() > jet_pt &&
+	 std::fabs(jet->eta()) > jet_eta_min &&
+	 std::fabs(jet->eta()) < jet_eta_max &&
+	 passedJvt &&
+	 ((tagger != "") ? is_bjet : true) ) {
+	// flag jet as passing current chainPart
+	chainPart_passedjets[chainPart_idx].push_back(true);
+      }
+      else {
+	chainPart_passedjets[chainPart_idx].push_back(false);
+      }
+      
+      ATH_MSG_DEBUG( " - pt:" << (jet->pt() / Gaudi::Units::GeV)
+		     << ", eta:" << jet->eta()
+		     << ", jvt:" << jvt
+		     << ((tagger != "") ? ", btag:" : "") << ((tagger != "") ? (is_bjet?"Y":"N") : "")
+		     << ", pass:" << (chainPart_passedjets[chainPart_idx].back()?"Y":"N")
+		     );
+    }
+  }
+  
+  return chainPart_passedjets;
+}
+
+bool TrigBtagEmulationChain::allocate_jets_to_chainParts(const std::vector<std::vector<bool>>& chainPart_jet_matrix, 
+							 const std::vector<std::string>& chainPartNames, 
+							 const std::vector<int>& multiplicities) const
+{
+  bool res = false;
+  std::vector<bool> chainPart_subset_passed;
+  
+  auto chainPartName_it = chainPartNames.begin();
+  for(const auto& chainPart_passedjets: chainPart_jet_matrix) {
+    std::string passedJets = "";
+    passedJets.reserve(chainPart_passedjets.size());
+    for(bool pass: chainPart_passedjets) {
+      passedJets += pass ? '1' : '0';
+      passedJets += !(passedJets.size() % 5) ? " " : "";
+    }
+    ATH_MSG_DEBUG( passedJets << " " << *(chainPartName_it++) );
+  }
+  
+  if(chainPart_jet_matrix.size() == 1) {
+    // simple single threshold chain
+    chainPart_subset_passed.push_back(false);
+    int njet_passed = 0;
+    for(bool pass: chainPart_jet_matrix[0]) {
+      if(pass) {
+	njet_passed++;
+	if(njet_passed >= multiplicities[0]) {
+	  chainPart_subset_passed.back() = true;
+	  break;
+	}
+      }
+    }
+  }
+  else {
+    // matrix looks something like this:
+    // chainPart0 (mult 1) | x    | pass | x    | x    | pass | x
+    // chainPart1 (mult 2) | x    | pass | pass | pass | x    | x
+    // chainPart2 (mult 3) | pass | pass | pass | x    | pass | pass
+    //                     | j0   | j1   | j2   | j3   | j4   | j5
+    //
+    // so it is easy to see that every chain _part_ passed, but not trivial to check if the _whole_ chain passed without checking all combinations
+    
+    // check for every subset in the powerset (chainPart0, ...., chainPartLast) if there are enough jets available that satisfy the subset's chainParts
+    for (int subset_bits = 1; subset_bits < (1 << chainPart_jet_matrix.size()); ++subset_bits) {
+      std::bitset<32> subset(subset_bits); // This limits the number of chain part to 32
+      std::vector<bool> subset_passedJets(chainPart_jet_matrix[0].size(), false);
+      int njets_required_subset = 0;
+      
+      std::string subset_str = "";
+      for(size_t chainPart_idx = 0; chainPart_idx < chainPart_jet_matrix.size(); ++chainPart_idx) {
+	if(subset[chainPart_idx]) {
+	  subset_str += std::to_string(chainPart_idx);
+	  njets_required_subset += multiplicities[chainPart_idx];
+	  
+	  for(size_t jet_idx = 0; jet_idx < chainPart_jet_matrix[chainPart_idx].size(); ++jet_idx) {
+	    if(chainPart_jet_matrix[chainPart_idx][jet_idx]) {
+	      subset_passedJets[jet_idx] = true;
+	    }
+	  }
+	}
+      }
+      
+      int njets_passed_subset = 0;
+      for(bool pass: subset_passedJets) {
+	if(pass) {
+	  njets_passed_subset++;
+	}
+      }
+      
+      ATH_MSG_DEBUG( "Subset {" << subset_str << "} requires " << njets_required_subset << " jets, and has " << njets_passed_subset << " jets passed." );
+      
+      if(njets_passed_subset < njets_required_subset) {
+	chainPart_subset_passed.push_back(false);
+	break;
+      }
+      else {
+	chainPart_subset_passed.push_back(true);
+      }
+    }
+  }
+  
+  
+  if(chainPart_subset_passed.size() == static_cast<size_t>(1 << chainPart_jet_matrix.size()) -1 && // -1 because we don't use the empty subset
+     !chainPart_subset_passed.empty()) {
+    // all chainpart subsets were checked, the result of the last is the overall result
+    res = chainPart_subset_passed.back();
+  }
+  else {
+    ATH_MSG_DEBUG( chainPart_subset_passed.size() << " out of " << (1 << chainPart_jet_matrix.size()) -1 << " chain part subsets checked" );
+  }
+  
+  return res;
+}
+
+void TrigBtagEmulationChain::parse_preselection(const std::string& presel_part, 
+						int& presel_multiplicity, 
+						double& presel_ptcut, 
+						double& presel_eta_min, 
+						double& presel_eta_max) const
+{
+  char presel_etarange = '?';
+  
+  presel_multiplicity = 1;
+  int tokenizer_offset = 0;
+  if('0' <= presel_part[0] && presel_part[0] <= '9') {
+    presel_multiplicity = (presel_part[0] - '0');
+    tokenizer_offset = 1;
+  }
+  presel_etarange = presel_part[tokenizer_offset];
+  presel_ptcut = static_cast<double>( std::stoi(&presel_part[1 +tokenizer_offset]) ); 
+  
+  switch(presel_etarange) {
+  case 'j':
+    presel_eta_max = 3.2;
+    break;
+  case 'a':
+    presel_eta_max = 4.9;
+    break;
+  case 'c':
+    presel_eta_max = 2.4;
+    break;
+  case 'f':
+    presel_eta_min = 3.2;
+    presel_eta_max = 4.9;
+    break;
+  default:
+    ATH_MSG_ERROR( "Unknown eta range in jet preselection cut." );
+    break;
+  }
+}
+
+void TrigBtagEmulationChain::parse_dijetmass(double& dijet_mass, 
+					     double& dijet_minjetpt, 
+					     double& dijet_dphi, 
+					     double& dijet_deta) const 
+{
+  // 'DJMASS500j35
+  // 'DJMASS700j35
+  // 'DJMASS1000j35
+  // 'DJMASS900j50
+  // 'DJMASS1000j50
+  // 'DJMASS1000j50dphi240
+  // 'DJMASS1000j50dphi200x400deta
+  dijet_mass = static_cast<double>( std::stoi(m_dijetmass) ); // stoi just parses until it finds a nonnumeric, provided is something like 1000j50dphi200x400deta
+  dijet_minjetpt = static_cast<double>( std::stoi(m_dijetmass.substr(m_dijetmass.find("j") +1)) );
+  
+  if(m_dijetmass.find("dphi") != std::string::npos) {
+    dijet_dphi = static_cast<double>( (std::stoi(m_dijetmass.substr(m_dijetmass.find("dphi") + 4)))) / 1e2 ; // 4 -> strlen("dphi")
+  }
+  
+  if(m_dijetmass.find("deta") != std::string::npos) {
+    std::string deta_str = m_dijetmass.substr(m_dijetmass.find("deta") -6);
+    dijet_deta = static_cast<double>( (std::stoi(m_dijetmass.substr(m_dijetmass.find("x") +1)))) / 1e2;
+  }
+  
+  ATH_MSG_DEBUG( "DijetMass parsing result: " << m_dijetmass << " ->"
+		 << " m:" << dijet_mass
+		 << " j:" << dijet_minjetpt
+		 << " dphi:" << dijet_dphi
+		 << " deta:" << dijet_deta);
+}
+
+}
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationChain.h b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationChain.h
new file mode 100755
index 0000000000000000000000000000000000000000..bfca4525978456078502e2de818ff28cde9d4468
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationChain.h
@@ -0,0 +1,118 @@
+/*
+Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration 
+*/
+
+#ifndef TRIGBTAGEMULATIONCHAIN_H
+#define TRIGBTAGEMULATIONCHAIN_H
+
+#include "AthenaBaseComps/AthMessaging.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "src/JetManagerTool.h"
+
+#include <string>
+#include <vector>
+#include <unordered_map>
+
+namespace Trig {
+
+class TrigBtagEmulationChain
+  : public AthMessaging {
+ public:
+  /// Constructors and Destructor                                                                                                                                                                                                                                                             
+  TrigBtagEmulationChain(const std::string& name,
+                         const std::vector< std::string >& definition,
+                         PublicToolHandle< Trig::TrigDecisionTool >& );
+  virtual ~TrigBtagEmulationChain() = default;
+
+  /// Name
+  const std::string& name() const;
+
+  /// JetManagers that will provide the jet and btagging objects
+  StatusCode addJetManager(const std::string& name, 
+			   ToolHandle<Trig::JetManagerTool>&);
+  
+  /// Chain evaluation 
+  bool isPassed() const;
+  
+private:
+  const PublicToolHandle< Trig::TrigDecisionTool >& tdt() const;
+
+  void parseChainDefinition(const std::vector<std::string>& definition);
+  
+  bool evaluate_L1() const;
+  bool evaluate_HLT() const;
+  
+  bool evaluate_preselection(const ToolHandle<Trig::JetManagerTool>& jm) const;
+  bool evaluate_dijetmass(const ToolHandle<Trig::JetManagerTool>& jm) const;
+  std::vector<std::vector<bool>> evaluate_HLT_chainParts(const ToolHandle<Trig::JetManagerTool>& jm, 
+							 int idx_begin, 
+							 int idx_end) const;
+  bool allocate_jets_to_chainParts(const std::vector<std::vector<bool>>& matrix, 
+				   const std::vector<std::string>& chainPartNames, 
+				   const std::vector<int>& multiplicities) const;
+  
+  void parse_preselection(const std::string& presel_part, 
+			  int& presel_multiplicity, 
+			  double& presel_ptcut, 
+			  double& presel_eta_min, 
+			  double& presel_eta_max) const;
+  void parse_dijetmass(double& dijet_mass, 
+		       double& dijet_minjetpt, 
+		       double& dijet_dphi, 
+		       double& dijet_deta) const;
+  
+  
+  // Chain name
+  std::string m_name;
+  
+  std::string m_l1_requirement = "";
+  std::vector<std::string> m_chainPartName {};
+  std::vector<int> m_jet_multiplicity {};
+  std::vector<double> m_jet_pt {};
+  std::vector<double> m_jet_eta_min {};
+  std::vector<double> m_jet_eta_max {};
+  std::vector<double> m_jvt {};
+  std::vector<bool> m_is_PFlow {};
+  std::vector<std::string> m_tagger {};
+  std::vector<std::string> m_jet_presel {};
+  std::string m_dijetmass = "";
+  int m_shared_idx = 0;
+
+
+  static const inline std::unordered_map<std::string, double> s_tagger_wp = {
+    {"dl1r60", 4.31},
+    {"dl1r70", 2.98},
+    {"dl1r77", 2.23},
+    {"dl1r85", 1.32},
+
+    {"dl1d40", 6.957},
+    {"dl1d45", 6.344},
+    {"dl1d50", 5.730},
+    {"dl1d55", 5.121},
+    {"dl1d60", 4.512},
+    {"dl1d65", 3.882},
+    {"dl1d70", 3.251},
+    {"dl1d72", 2.489},
+    {"dl1d75", 2.489},
+    {"dl1d77", 2.157},
+    {"dl1d80", 1.626},
+    {"dl1d82", 1.254},
+    {"dl1d85", 0.634},
+    {"dl1d90", -0.465},
+    {"dl1d95", -1.616},
+
+    {"newTagger", 1.234},
+    {"offperf", -999}
+  };
+  
+  PublicToolHandle< Trig::TrigDecisionTool >& m_trigDec;
+  
+  std::unordered_map< std::string, ToolHandle<Trig::JetManagerTool>* > m_jetmanagers;
+};
+
+ inline const std::string& TrigBtagEmulationChain::name() const { return m_name; }
+ inline const PublicToolHandle< Trig::TrigDecisionTool >& TrigBtagEmulationChain::tdt() const { return m_trigDec; }
+
+} //namespace
+
+#endif
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationJet.cxx b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationJet.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..4309c89332005cf6a3b7b7c4ff7695bf60ab6f36
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationJet.cxx
@@ -0,0 +1,90 @@
+/*
+Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration 
+*/
+
+#include "src/TrigBtagEmulationJet.h"
+#include "xAODBTagging/BTaggingUtilities.h"
+#include "FlavorTagDiscriminants/DL2HighLevel.h" 
+
+//**********************************************************************
+
+namespace Trig {
+
+TrigBtagEmulationJet::TrigBtagEmulationJet(const std::string& name,
+					   const xAOD::Jet *jet)
+  : AthMessaging(name),
+    m_jet(jet),
+    m_pt(jet->pt()),
+    m_eta(jet->eta()),
+    m_phi(jet->phi())
+{}
+
+TrigBtagEmulationJet::TrigBtagEmulationJet(const std::string& name,
+					   const xAOD::JetRoI *jetRoI, 
+					   bool isJJ) 
+  : AthMessaging(name),
+    m_pt(isJJ ? jetRoI->et4x4() * 0.001 : jetRoI->et8x8() * 0.001),
+    m_eta(jetRoI->eta()),
+    m_phi(jetRoI->phi())
+{}
+
+bool TrigBtagEmulationJet::isPassedBTagger(const std::string& btagger, 
+					   double workingPoint) const 
+{
+  if( btagger.substr(0, 7) == "offperf" ) { // 7 -> strlen("offperf")
+    ATH_MSG_DEBUG( "offperf tagger always passes");
+    return true;
+  }
+  
+  bool res = false;
+  const xAOD::BTagging *btag = xAOD::BTaggingUtilities::getBTagging( *m_jet );
+  if (not btag) {
+    ATH_MSG_DEBUG( "Couldn't retrieve BTagging for jet pt:" << pt() << ", eta:" << eta() << ", so not a bjet" );
+    return false;
+  }
+
+  if( btagger.substr(0, 4) == "dl1r" ) { // 4 -> strlen("dl1r")
+    res = satisfy("DL1r", btag, workingPoint);
+  } else if( btagger.substr(0, 4) == "dl1d" ) { // 4 -> strlen("dl1d")
+    res = satisfy("DL1d20211216", btag, workingPoint);
+  } else if( btagger.substr(0, 9) == "newTagger" ) { // 9 -> strlen("newTagger")
+    static const std::map<std::string, std::string> remapping
+      = {{"DL1d20210519r22_pu","DL1dEMUL_pu"},
+	 {"DL1d20210519r22_pc","DL1dEMUL_pc"},
+	 {"DL1d20210519r22_pb","DL1dEMUL_pb"}};
+    static const FlavorTagDiscriminants::DL2HighLevel dl2
+      = FlavorTagDiscriminants::DL2HighLevel("BTagging/20210519r22/dl1d/antikt4empflow/network.json",
+					     FlavorTagDiscriminants::FlipTagConfig::STANDARD,
+					     remapping);
+    dl2.decorate(*btag);
+    
+    res = satisfy("DL1dEMUL", btag, workingPoint);
+  } else {
+    ATH_MSG_WARNING( "Tagger " << btagger << " not supported." );
+  }
+  
+  return res;
+}
+
+bool TrigBtagEmulationJet::satisfy(const std::string& tagger_name,
+				   const xAOD::BTagging *btag,
+				   double workingPoint) const 
+{
+  double pu = -1;
+  double pb = -1;
+  double pc = -1;
+
+  btag->pu(tagger_name, pu); 
+  btag->pb(tagger_name, pb);
+  btag->pc(tagger_name, pc);
+
+  double tagger_weight = dl1r_weight(pu,pb,pc);
+  ATH_MSG_DEBUG( "jet pt:" << (pt() / Gaudi::Units::GeV) << ", " << tagger_name << " weight: " << tagger_weight << " (req " << workingPoint << ", pu:" << pu << " pb:" << pb << " pc:" << pc << ")" );
+
+  return tagger_weight > workingPoint;
+}
+
+}
+
+//**********************************************************************
+
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationJet.h b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationJet.h
new file mode 100755
index 0000000000000000000000000000000000000000..cc39e686144370d6bbf10e17d6cb2c7303819498
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationJet.h
@@ -0,0 +1,64 @@
+/*
+Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGBTAGEMULATION_JET_H
+#define TRIGBTAGEMULATION_JET_H
+
+#include "AthenaBaseComps/AthMessaging.h"
+
+#include "xAODJet/JetContainer.h"
+#include "xAODTrigger/JetRoIContainer.h"
+#include "xAODBTagging/BTaggingContainer.h"
+#include "xAODBTagging/BTaggingAuxContainer.h"
+
+#include <string>
+
+namespace Trig {
+
+class TrigBtagEmulationJet :
+    public AthMessaging {
+public:
+  TrigBtagEmulationJet() = delete;
+  TrigBtagEmulationJet(const std::string& name, const xAOD::Jet*);
+  TrigBtagEmulationJet(const std::string& name, const xAOD::JetRoI*, bool isJJ = false);
+  TrigBtagEmulationJet(const TrigBtagEmulationJet&) = delete;
+  TrigBtagEmulationJet& operator=(const TrigBtagEmulationJet&) = delete;
+  virtual ~TrigBtagEmulationJet() = default;
+  
+  double pt() const;
+  double eta() const;
+  double phi() const;
+  float jvt() const;
+  
+  bool isPassedBTagger(const std::string& btagger, 
+		       double workingPoint) const;
+  
+private:
+  double dl1r_weight(double pu, double pb, double pc) const;
+  bool satisfy(const std::string& tagger_name,
+	       const xAOD::BTagging *btag,
+	       double workingPoint) const;
+  
+private:
+  const xAOD::Jet *m_jet = nullptr;
+  
+  double m_pt;
+  double m_eta;    
+  double m_phi;
+  double m_dl1r_cFrac = 0.018;
+};
+
+ inline double TrigBtagEmulationJet::pt() const { return m_pt; }
+ inline double TrigBtagEmulationJet::eta() const  { return m_eta; };
+ inline double TrigBtagEmulationJet::phi() const { return m_phi; }
+ inline float TrigBtagEmulationJet::jvt() const {
+   static const SG::AuxElement::Accessor<float> JVT( "Jvt" );
+   return JVT(*m_jet);
+ }
+ inline double TrigBtagEmulationJet::dl1r_weight(double pu, double pb, double pc) const 
+ { return log( pb / ((pu * (1 - m_dl1r_cFrac)) + (m_dl1r_cFrac * pc)) ); }
+ 
+} //namespace
+
+#endif
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationTool.cxx b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationTool.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..cd8cc5edd674f980e264804604291bf1a91cb9d9
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationTool.cxx
@@ -0,0 +1,138 @@
+/*
+Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration 
+*/
+
+/**********************************************************************
+ * Authors:
+ *      Carlo Varni <carlo.varni@cern.ch>
+ *      Carlo Schiavi <carlo.schiavi@cern.ch>
+ *      Florencia Daneri <maria.florencia.daneri@cern.ch>
+ *      Gino Marceca <gino.marceca@cern.ch>
+ *      Lars Beemster <lars.beemster@cern.ch>
+ *
+ * Description:
+ *      Base tool class for bjet trigger emulation
+ **********************************************************************/
+
+#include "src/TrigBtagEmulationTool.h"
+
+namespace Trig {
+
+TrigBtagEmulationTool::TrigBtagEmulationTool(const std::string& type, 
+					     const std::string& name, 
+					     const IInterface* parent)
+  : base_class(type, name, parent) 
+{}
+
+
+StatusCode TrigBtagEmulationTool::initialize() {
+  ATH_MSG_INFO( "Initializing " << name() );
+
+  ATH_CHECK( m_trigDec.retrieve() );
+
+  ATH_CHECK( m_manager_EMTopo_cnt.retrieve() );
+  ATH_CHECK( m_manager_PFlow_cnt.retrieve() );
+  
+  ATH_CHECK( m_manager_EMTopo_presel.retrieve() );
+  
+  for(const auto& [chain_name, definition] : m_emulatedChainDefinitions) {
+    ATH_CHECK( addEmulatedChain(chain_name, definition) );
+  }
+  
+  return StatusCode::SUCCESS;
+}
+
+bool TrigBtagEmulationTool::isPassed(const std::string& chain) const 
+{
+  std::unordered_map< std::string, std::unique_ptr< TrigBtagEmulationChain >>::const_iterator itr = m_emulatedChains.find(chain);
+  if (itr == m_emulatedChains.end()) {
+    ATH_MSG_WARNING( "chain " << chain << " requested but not in the list of emulated chains" );
+    return false;
+  }
+  const std::unique_ptr< TrigBtagEmulationChain >& obj = itr->second;
+  return obj->isPassed();
+}
+
+
+//=================================================
+//		Utility functions
+//=================================================
+StatusCode TrigBtagEmulationTool::populateJetManagersTriggerObjects() {
+  // Check if input chain exists
+  ATH_CHECK( checkInputChainExists( m_inputChains_PFlow ) );
+  
+  // Retrieve input container vectors
+  ATH_CHECK( retrieveTriggerObjects( m_manager_EMTopo_cnt, /*useTriggerNavigation=*/false ) );
+  ATH_CHECK( retrieveTriggerObjects( m_manager_PFlow_cnt, /*useTriggerNavigation=*/false ) );
+    
+  ATH_CHECK( retrieveTriggerObjects( m_manager_EMTopo_presel, /*useTriggerNavigation=*/false ) );
+  
+  return StatusCode::SUCCESS;
+}
+
+StatusCode TrigBtagEmulationTool::retrieveTriggerObjects( ToolHandle< Trig::JetManagerTool >& manager, 
+							  bool useTriggerNavigation)
+{
+  StatusCode sc = useTriggerNavigation 
+    ? manager->retrieveByNavigation()
+    : manager->retrieveByContainer();
+  
+  if ( sc.isFailure() ) {
+    ATH_MSG_ERROR( "Could not retrieve Jets!" );
+    return StatusCode::FAILURE;
+  }
+  
+  const std::string& chainName = manager->chainName();
+  const std::string& jetContainerName = manager->jetContainerName();
+  
+  const unsigned int jetSize = manager->jetSize();
+  const unsigned int jetRoISize = manager->jetRoISize();
+  const unsigned int btaggingSize= manager->btaggingSize();
+  
+  if (useTriggerNavigation) {
+    ATH_MSG_DEBUG( "Size of input containers ['" << chainName << "'] :"
+		   << " jet=" << jetSize
+		   << " jetRoI=" << jetRoISize
+		   << " btag=" << btaggingSize);
+  }
+  else {
+    ATH_MSG_DEBUG( "Size of input containers ['" << jetContainerName << "'] :"
+		   << " jet=" << jetSize
+		   << " jetRoI=" << jetRoISize);
+  }
+  
+  return StatusCode::SUCCESS;
+}
+
+StatusCode TrigBtagEmulationTool::checkInputChainExists( const std::string &inputChain ) const 
+{
+  std::vector<std::string> listOfTriggers = m_trigDec->getChainGroup( inputChain )->getListOfTriggers();
+  if ( listOfTriggers.empty() ) {
+    ATH_MSG_ERROR( "Input Chain ('" << inputChain << "') is not in the list of available triggers: {" << m_trigDec->getListOfTriggers(".*") << "}" );
+    return StatusCode::FAILURE;
+  }
+  
+  ATH_MSG_INFO( "Triggers in configured ChainGroup " << inputChain << ":" );
+  for (const auto& cname: listOfTriggers) {
+    ATH_MSG_INFO( " â”” " << cname );
+  }
+  
+  return StatusCode::SUCCESS;
+}
+
+StatusCode TrigBtagEmulationTool::addEmulatedChain(const std::string& triggerName, 
+						   const std::vector<std::string>& definition) 
+{
+  std::unique_ptr< TrigBtagEmulationChain > chain = std::make_unique<TrigBtagEmulationChain>( triggerName, definition, m_trigDec );
+  chain->setLevel(msgLevel());
+
+  ATH_CHECK( chain->addJetManager(m_manager_EMTopo_cnt.name(), m_manager_EMTopo_cnt) );
+  ATH_CHECK( chain->addJetManager(m_manager_PFlow_cnt.name(), m_manager_PFlow_cnt) );
+  ATH_CHECK( chain->addJetManager(m_manager_EMTopo_presel.name(), m_manager_EMTopo_presel) );
+  
+  m_emulatedChains.insert( std::make_pair(triggerName, std::move(chain)) );
+  
+  return StatusCode::SUCCESS;
+}
+
+}
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationTool.h b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationTool.h
new file mode 100755
index 0000000000000000000000000000000000000000..8501c00ce0fd07705b881c3e8fcdd910fb2df93d
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagEmulationTool.h
@@ -0,0 +1,62 @@
+/*
+Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration 
+*/
+
+#ifndef TrigBtagEmulationTool_H
+#define TrigBtagEmulationTool_H
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "TrigBtagEmulationTool/ITrigBtagEmulationTool.h"
+#include "TrigDecisionTool/TrigDecisionTool.h"
+#include "GaudiKernel/ToolHandle.h"
+
+#include "src/JetManagerTool.h"
+#include "src/TrigBtagEmulationChain.h"
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <unordered_map>
+
+namespace Trig {
+
+class TrigBtagEmulationTool : 
+  public extends<AthAlgTool, Trig::ITrigBtagEmulationTool> {
+public:
+  TrigBtagEmulationTool(const std::string& type, 
+			const std::string& name, 
+			const IInterface* parent);
+  virtual ~TrigBtagEmulationTool() = default;
+	
+  virtual StatusCode initialize() override;
+  virtual StatusCode populateJetManagersTriggerObjects() override;  
+  virtual bool isPassed(const std::string& chain) const override;
+
+private:
+  StatusCode addEmulatedChain(const std::string& name, 
+			      const std::vector< std::string >& definition);
+
+  StatusCode checkInputChainExists(const std::string&) const;
+  StatusCode retrieveTriggerObjects(ToolHandle< Trig::JetManagerTool >&, 
+				    bool useTriggerNavigation);
+
+private:
+  PublicToolHandle<Trig::TrigDecisionTool> m_trigDec {this, "TrigDecisionTool", "",""};
+  
+  // Input properties
+  Gaudi::Property< std::string > m_inputChains_PFlow {this, "InputChain", "HLT_j45_pf_subjesgsc_ftf_L1J15", ""};
+    
+  // jet Managers
+  ToolHandle< Trig::JetManagerTool > m_manager_EMTopo_cnt {this, "JM_EMTopo_CNT", "",""};
+  ToolHandle< Trig::JetManagerTool > m_manager_PFlow_cnt {this, "JM_PFlow_CNT", "",""};
+  ToolHandle< Trig::JetManagerTool > m_manager_EMTopo_presel {this, "JM_EMTopo_PRESEL", "",""};
+  
+  // EMULATED CHAINS
+  Gaudi::Property< std::map< std::string, std::vector< std::string >>> m_emulatedChainDefinitions {this, "EmulatedChainDefinitions", {}, ""};
+
+  std::unordered_map< std::string, std::unique_ptr< TrigBtagEmulationChain >> m_emulatedChains;  
+};
+
+} // namespace
+
+#endif
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagValidationTest.cxx b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagValidationTest.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..58999c5802fd22567d4a029f64206d6492b3cc42
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagValidationTest.cxx
@@ -0,0 +1,59 @@
+/*
+Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration 
+*/
+
+#include "src/TrigBtagValidationTest.h"
+
+namespace Trig {
+
+TrigBtagValidationTest::TrigBtagValidationTest(const std::string& name, 
+					       ISvcLocator* pSvcLocator ) 
+  : AthAlgorithm(name, pSvcLocator) 
+{}
+
+StatusCode TrigBtagValidationTest::initialize() {
+  ATH_MSG_INFO("Initializing " << name() );
+
+  ATH_CHECK( m_histSvc.retrieve() );
+  ATH_CHECK( m_trigDec.retrieve() );
+
+  m_h_tdtpass = new TH1F( "h_tdtpass", "h_tdtpass", m_emulatedChains.size(), 0, m_emulatedChains.size());
+  m_h_tbetpass = new TH1F( "h_tbetpass", "h_tbetpass", m_emulatedChains.size(), 0, m_emulatedChains.size());
+  m_h_miss = new TH1F( "h_miss", "h_miss", m_emulatedChains.size(), 0, m_emulatedChains.size());
+  m_h_falsepositive = new TH1F( "h_falsepositive", "h_falsepositive", m_emulatedChains.size(), 0, m_emulatedChains.size());
+  ATH_CHECK( m_histSvc->regHist("/VALIDATION/h_tdtpass", m_h_tdtpass) );
+  ATH_CHECK( m_histSvc->regHist("/VALIDATION/h_tbetpass", m_h_tbetpass) );
+  ATH_CHECK( m_histSvc->regHist("/VALIDATION/h_miss", m_h_miss) );
+  ATH_CHECK( m_histSvc->regHist("/VALIDATION/h_falsepositive", m_h_falsepositive) );
+  
+  for(int i = 1; i <= (int)m_emulatedChains.size(); i++) {
+    m_h_tdtpass->GetXaxis()->SetBinLabel(i, m_emulatedChains[i-1].c_str());
+    m_h_miss->GetXaxis()->SetBinLabel(i, m_emulatedChains[i-1].c_str());
+    m_h_falsepositive->GetXaxis()->SetBinLabel(i, m_emulatedChains[i-1].c_str());
+  }
+  
+  return StatusCode::SUCCESS;
+}
+  
+StatusCode TrigBtagValidationTest::execute() 
+{
+  ATH_MSG_DEBUG("Executing " << name() );
+  ATH_CHECK( m_emulationTool->populateJetManagersTriggerObjects() );
+  int chain_idx = 0;
+  for(const auto& chain: m_emulatedChains) {
+    bool tbet_pass = m_emulationTool->isPassed(chain);
+    bool tdt_pass = m_trigDec->isPassed(chain);
+    ATH_MSG_DEBUG( chain << " TDT:" << (tdt_pass ? "PASS":"NO") << " TBET:" << (tbet_pass ? "PASS":"NO"));
+    
+    m_h_tdtpass->Fill( tdt_pass ? chain_idx +.5 : -1 );
+    m_h_tbetpass->Fill( tbet_pass ? chain_idx +.5 : -1 );
+    m_h_miss->Fill( (tdt_pass && !tbet_pass) ? chain_idx +.5 : -1 );
+    m_h_falsepositive->Fill( (!tdt_pass && tbet_pass) ? chain_idx +.5 : -1 );
+    
+    chain_idx++;
+  }
+  
+  return StatusCode::SUCCESS;
+}
+
+} // namespace
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagValidationTest.h b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagValidationTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..f40f0dc95ef593de9025edf13a6cff2c77fb62d2
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/TrigBtagValidationTest.h
@@ -0,0 +1,49 @@
+/*
+Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TrigBtagValidationTest_H
+#define TrigBtagValidationTest_H
+
+#include "TrigBtagEmulationTool/ITrigBtagEmulationTool.h"
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "TrigDecisionTool/TrigDecisionTool.h"
+#include "GaudiKernel/ITHistSvc.h"
+
+#include "TH1.h"
+
+
+namespace Trig {
+
+class TrigBtagValidationTest : 
+  public AthAlgorithm {
+public:
+  /// Constructor with parameters:
+  TrigBtagValidationTest(const std::string& name, ISvcLocator* pSvcLocator);
+  
+  /// Destructor:
+  virtual ~TrigBtagValidationTest() = default;
+  
+  /// Athena algorithm's Hooks
+  virtual StatusCode initialize() override;
+  virtual StatusCode execute() override;
+  virtual unsigned int cardinality() const override { return 1; }
+  
+private:
+  ServiceHandle<ITHistSvc> m_histSvc {this, "THistSvc", "THistSvc", "Histogramming svc" };
+  ToolHandle<Trig::ITrigBtagEmulationTool> m_emulationTool {this, "TrigBtagEmulationTool", "", ""};
+  PublicToolHandle< Trig::TrigDecisionTool > m_trigDec {this, "TrigDecisionTool", "",""};
+  
+  Gaudi::Property< std::vector< std::string >> m_emulatedChains {this, "EmulatedChains", {}, ""};
+  
+  TH1F *m_h_tdtpass = nullptr;
+  TH1F *m_h_tbetpass = nullptr;
+  TH1F *m_h_miss = nullptr;
+  TH1F *m_h_falsepositive = nullptr;
+};
+
+} // namespace
+
+#endif
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/src/components/TrigBtagEmulationTool_entries.cxx b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/components/TrigBtagEmulationTool_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d69ba58d1414a47fe1363341ebb323c8a34b6975
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/src/components/TrigBtagEmulationTool_entries.cxx
@@ -0,0 +1,11 @@
+/*
+Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "src/TrigBtagEmulationTool.h"
+#include "src/JetManagerTool.h"
+#include "src/TrigBtagValidationTest.h"
+
+DECLARE_COMPONENT(Trig::TrigBtagEmulationTool)
+DECLARE_COMPONENT(Trig::JetManagerTool)
+DECLARE_COMPONENT(Trig::TrigBtagValidationTest)
diff --git a/Trigger/TrigEmulation/TrigBtagEmulationTool/test/testTrigBtagValidation.py b/Trigger/TrigEmulation/TrigBtagEmulationTool/test/testTrigBtagValidation.py
new file mode 100755
index 0000000000000000000000000000000000000000..0beff2574436b52901a8777767bac9648a6811d8
--- /dev/null
+++ b/Trigger/TrigEmulation/TrigBtagEmulationTool/test/testTrigBtagValidation.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+
+def main():
+    EvtMax = 20
+    inputFiles = ['/global/homes/c/cvarni/Athena/TrigBtagEmulationToolLayout/data/TrigAnalysisTest.2022-05-09T2101.test_trigAna_RDOtoADO_v1Dev_grid.AOD.pool.root']
+    
+    # for validation compare the decisions of a single chain, or all the chains in the menu 
+    jetcoll_name_mapping = {
+        "a10sd_cssk_pf_jes_ftf": "HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_jes_ftf", # 0
+        "a10sd_cssk_pf_nojcalib_ftf": "HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_nojcalib_ftf:", # 1
+        "a10sd_pf_nojcalib_ftf": "HLT_AntiKt10EMPFlowSoftDropBeta100Zcut10Jets_nojcalib_ftf", # 2
+        "a10r_subjesIS_ftf": "HLT_AntiKt10EMTopoRCJets_subjesIS", # 3
+        "a10_lcw_subjes": "HLT_AntiKt10LCTopoJets_subjes", # 4
+        "a10sd_lcw_nojcalib": "HLT_AntiKt10LCTopoSoftDropBeta100Zcut10Jets_nojcalib", # 5
+        "a10t_lcw_jes": "HLT_AntiKt10LCTopoTrimmedPtFrac4SmallR20Jets_jes", # 6
+        "a4_cssk_pf_nojcalib_ftf": "HLT_AntiKt4EMPFlowCSSKJets_nojcalib_ftf", # 7
+        "a4_pf_nojcalib_ftf": "HLT_AntiKt4EMPFlowJets_nojcalib_ftf", # 8
+        "a4_pf_subjesgscIS_ftf": "HLT_AntiKt4EMPFlowJets_subjesgscIS_ftf", # 9
+        "a4_pf_subresjesgscIS_ftf": "HLT_AntiKt4EMPFlowJets_subresjesgscIS_ftf", # 10
+        "a4_subjesIS": "HLT_AntiKt4EMTopoJets_subjesIS", # 11
+        "a4_subjesgscIS_ftf": "HLT_AntiKt4EMTopoJets_subjesgscIS_ftf", # 12
+    }
+
+    trigger_slice = ['Jet', 'Bjet'][1]
+    jetcontainer_EMTopo = ''
+    jetcontainer_PFlow = ''
+    validation_singlechain = ''
+    jetcoll_emul = list(jetcoll_name_mapping.keys())[0] # only used for Jet slice, bjet slice uses a4_pf_subresjesgscIS_ftf [10]
+
+    from TriggerMenuMT.HLT.Menu.Physics_pp_run3_v1 import setupMenu
+    chains_phys_pp_run3_v1 = setupMenu()
+    if validation_singlechain:
+        emulatedChains = [cp for cp in chains_phys_pp_run3_v1[trigger_slice] if cp.name == validation_singlechain]
+    else:
+        if trigger_slice == 'Jet':
+            jetcontainer_EMTopo = jetcoll_name_mapping[jetcoll_emul]
+            emulatedChains = [cp for cp in chains_phys_pp_run3_v1[trigger_slice] if jetcoll_emul in cp.name]
+        elif trigger_slice == 'Bjet':
+            emulatedChains = [cp for cp in chains_phys_pp_run3_v1[trigger_slice] if '_pf_' in cp.name and '_HT' not in cp.name and 'dl1d85bb' not in cp.name]
+
+        # retagging example, DL1d from BTagging/20210519r22/dl1d/antikt4empflow/network.json (needs to be coded in TrigBtagEmulationJet.cxx as well)
+        if trigger_slice[0] == 'B':
+            from TriggerMenuMT.HLT.Config.Utility.ChainDefInMenu import ChainProp
+            from TriggerMenuMT.HLT.Menu.Physics_pp_run3_v1 import SingleBjetGroup, PrimaryLegGroup
+            emulatedChains += [ChainProp(name='HLT_j45_0eta290_020jvt_pf_ftf_newTagger_L1J20', l1SeedThresholds=['FSNOSEED'], groups=PrimaryLegGroup+SingleBjetGroup)]
+
+            from TriggerMenuMT.HLT.Menu.SignatureDicts import JetChainParts
+            JetChainParts['bTag'] += ['newTagger']
+
+
+    from AthenaCommon.Configurable import ConfigurableRun3Behavior
+    with ConfigurableRun3Behavior():
+        from AthenaConfiguration.AllConfigFlags import ConfigFlags
+        ConfigFlags.Scheduler.ShowDataDeps = True
+        ConfigFlags.Scheduler.ShowDataFlow = True
+        ConfigFlags.Scheduler.ShowControlFlow = True
+        ConfigFlags.Input.Files = inputFiles 
+        ConfigFlags.Exec.MaxEvents = EvtMax
+
+        ConfigFlags.lock()
+        ConfigFlags.dump()
+
+        from AthenaConfiguration.MainServicesConfig import MainServicesCfg
+        from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
+        acc = MainServicesCfg( ConfigFlags )
+        acc.merge( PoolReadCfg( ConfigFlags ) )
+        acc.getService("MessageSvc").Format = "% F%80W%S%7W%R%T %0W%M"
+        acc.getService("MessageSvc").defaultLimit = 2147483647
+    
+        from TrigBtagEmulationTool.TrigBtagEmulationToolConfig import TrigBtagValidationTestCfg
+        acc.merge(TrigBtagValidationTestCfg(ConfigFlags,
+                                            toBeEmulatedTriggers = emulatedChains,
+                                            InputChain_EMTopo = '',
+                                            InputJetContainer_EMTopo = jetcontainer_EMTopo,
+                                            InputJetContainer_EMTopoPresel = '',
+                                            InputChain_PFlow = validation_singlechain,
+                                            InputJetContainer_PFlow = jetcontainer_PFlow,
+                                            InputJetContainer_PFlowPresel = '' ))
+        
+        acc.printConfig(withDetails = True, summariseProps = True)
+        acc.store( open('TrigBtagValidationConfig.pkl','wb') )
+
+        acc.run()
+
+if __name__ == "__main__":
+    main()
diff --git a/Trigger/TrigHypothesis/TrigTauHypo/python/TrigTauHypoTool.py b/Trigger/TrigHypothesis/TrigTauHypo/python/TrigTauHypoTool.py
index 195133fa51b500746afcd946aca41958511a0020..7c9b6517ff83508f62bb785ba7174f2daf7e8cee 100644
--- a/Trigger/TrigHypothesis/TrigTauHypo/python/TrigTauHypoTool.py
+++ b/Trigger/TrigHypothesis/TrigTauHypo/python/TrigTauHypoTool.py
@@ -95,7 +95,7 @@ def TrigEFTauMVHypoToolFromDict( chainDict ):
 
            # define quantities to be monitored
            monTool.defineHistogram("CutCounter", path='EXPERT',type='TH1I',title=';CutCounter; Entries', xbins=10, xmin=0.,xmax=10.) 
-           monTool.defineHistogram("ptAccepted", path='EXPERT',type='TH1F',title=';ptAccepted; Entries', xbins=50, xmin=0.,xmax=500.)
+           monTool.defineHistogram("ptAccepted", path='EXPERT',type='TH1F',title=';ptAccepted; Entries', xbins=80, xmin=0.,xmax=800.)
            monTool.defineHistogram("nTrackAccepted", path='EXPERT',type='TH1F',title=';nTrackAccepted; Entries', xbins=10, xmin=0.,xmax=10.)
            monTool.defineHistogram("nWideTrackAccepted", path='EXPERT',type='TH1F',title=';nWideTrackAccepted; Entries', xbins=10, xmin=0.,xmax=10.)       
            monTool.defineHistogram("nInputTaus", path='EXPERT',type='TH1F',title=';nInputTaus; Entries', xbins=10, xmin=0.,xmax=10.) 
diff --git a/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorAnalysisAlgorithm.cxx b/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorAnalysisAlgorithm.cxx
index 18a18b34a8858aaa8df8cb8d3f71e7b3aa272ad1..a9fcc296497fac75da2e2ccf8f53aa42e39f65cd 100644
--- a/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorAnalysisAlgorithm.cxx
+++ b/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorAnalysisAlgorithm.cxx
@@ -79,7 +79,7 @@ void TrigEgammaMonitorAnalysisAlgorithm::fillEfficiencies( const std::vector< st
         auto acceptData = m_emulatorTool->emulate( pairObj.second, info.trigger , valid);
         // skip this probe since the emulation is not possible. Avoid diff denominators between emulation and efficiecy
         if(!valid) {
-            ATH_MSG_WARNING("Emulation fail. Skip this probe...");
+            ATH_MSG_DEBUG("Emulation fail. Skip this probe...");
             continue;
         } 
         emu_accept_vec.push_back( acceptData );
diff --git a/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorElectronAlgorithm.cxx b/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorElectronAlgorithm.cxx
index eaa7530dd394e4428891e725000c3fc9fe1ba97c..c106fd0c787d0ec2b88e67ff8a129dfa5fd99f9e 100644
--- a/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorElectronAlgorithm.cxx
+++ b/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorElectronAlgorithm.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TrigEgammaMonitorElectronAlgorithm.h"
@@ -26,7 +26,7 @@ StatusCode TrigEgammaMonitorElectronAlgorithm::initialize()
   for(auto& trigName : m_trigInputList)
   {
     if(getTrigInfoMap().count(trigName) != 0){
-      ATH_MSG_WARNING("Trigger already booked, removing from trigger list " << trigName);
+      ATH_MSG_DEBUG("Trigger already booked, removing from trigger list " << trigName);
     }else {
       m_trigList.push_back(trigName);
       setTrigInfo(trigName);
@@ -45,7 +45,7 @@ StatusCode TrigEgammaMonitorElectronAlgorithm::fillHistograms( const EventContex
     ATH_MSG_DEBUG("Executing TrigEgammaMonitorElectronAlgorithm");
 
     if(isHLTTruncated()){
-        ATH_MSG_WARNING("HLTResult truncated, skip trigger analysis");
+        ATH_MSG_DEBUG("HLTResult truncated, skip trigger analysis");
         return StatusCode::SUCCESS; 
     }
     
@@ -61,7 +61,7 @@ StatusCode TrigEgammaMonitorElectronAlgorithm::fillHistograms( const EventContex
         std::vector< std::pair<std::shared_ptr<const xAOD::Egamma>, const TrigCompositeUtils::Decision*>> pairObjs;
         if ( executeNavigation( ctx, info.trigger,info.etthr,info.pidname, pairObjs).isFailure() ) 
         {
-            ATH_MSG_WARNING("executeNavigation Fails");
+            ATH_MSG_DEBUG("executeNavigation Fails");
             return StatusCode::SUCCESS;
         }
 
@@ -102,7 +102,7 @@ StatusCode TrigEgammaMonitorElectronAlgorithm::executeNavigation( const EventCon
 
   if(!offElectrons.isValid())
   {
-    ATH_MSG_WARNING("Failed to retrieve offline Electrons ");
+    ATH_MSG_DEBUG("Failed to retrieve offline Electrons ");
 	  return StatusCode::FAILURE;
   }
 
diff --git a/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorPhotonAlgorithm.cxx b/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorPhotonAlgorithm.cxx
index acdee480693ab925532cb6886d7394d11038b745..de165af0c23884b1f3fcba979bd31c97aca06bf1 100644
--- a/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorPhotonAlgorithm.cxx
+++ b/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorPhotonAlgorithm.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TrigEgammaMonitorPhotonAlgorithm.h"
@@ -28,7 +28,7 @@ StatusCode TrigEgammaMonitorPhotonAlgorithm::initialize()
   for(auto& trigName : m_trigInputList)
   {
     if(getTrigInfoMap().count(trigName) != 0){
-      ATH_MSG_WARNING("Trigger already booked, removing from trigger list " << trigName);
+      ATH_MSG_DEBUG("Trigger already booked, removing from trigger list " << trigName);
     }else {
       m_trigList.push_back(trigName);
       setTrigInfo(trigName);
@@ -47,7 +47,7 @@ StatusCode TrigEgammaMonitorPhotonAlgorithm::fillHistograms( const EventContext&
 
 
     if(isHLTTruncated()){
-        ATH_MSG_WARNING("HLTResult truncated, skip trigger analysis");
+        ATH_MSG_DEBUG("HLTResult truncated, skip trigger analysis");
         return StatusCode::SUCCESS; 
     }
     
@@ -64,7 +64,7 @@ StatusCode TrigEgammaMonitorPhotonAlgorithm::fillHistograms( const EventContext&
     
         if ( executeNavigation( ctx, info.trigger,info.etthr,info.pidname,pairObjs).isFailure() ) 
         {
-            ATH_MSG_WARNING("executeNavigation Fails");
+            ATH_MSG_DEBUG("executeNavigation Fails");
             return StatusCode::SUCCESS;
         }
 
@@ -101,7 +101,7 @@ StatusCode TrigEgammaMonitorPhotonAlgorithm::executeNavigation( const EventConte
 
   if(!offPhotons.isValid())
   {
-    ATH_MSG_WARNING("Failed to retrieve offline Electrons ");
+    ATH_MSG_DEBUG("Failed to retrieve offline photons ");
 	  return StatusCode::FAILURE;
   }
  
diff --git a/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorTagAndProbeAlgorithm.cxx b/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorTagAndProbeAlgorithm.cxx
index bb1562bdba0f3aa1f81e98993049d5e88a93957a..2bd098472743a1bf447afad045d70d046386db52 100644
--- a/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorTagAndProbeAlgorithm.cxx
+++ b/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorTagAndProbeAlgorithm.cxx
@@ -1,11 +1,12 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 /**********************************************************************
  * AsgTool: TrigEgammaNavTPBaseTool
  * Authors:
  *      Joao Victor Pinto <jodafons@cern.ch>
+ *      Edmar de Souza <edmar.egidio@cern.ch>
  * Description:
  *      Trigger e/gamma Zee Tag&Probe Base tool class. Inherits from TrigEgammaAnalysisBaseTool.
  *      Provides methods for selecting T&P pairs, 
@@ -53,7 +54,7 @@ StatusCode TrigEgammaMonitorTagAndProbeAlgorithm::initialize() {
     for(auto& trigName : m_trigInputList)
     {
       if(getTrigInfoMap().count(trigName) != 0){
-        ATH_MSG_WARNING("Trigger already booked, removing from trigger list " << trigName);
+        ATH_MSG_DEBUG("Trigger already booked, removing from trigger list " << trigName);
       }else {
         m_trigList.push_back(trigName);
         setTrigInfo(trigName);
@@ -81,7 +82,7 @@ StatusCode TrigEgammaMonitorTagAndProbeAlgorithm::fillHistograms( const EventCon
 
     // Check HLTResult
     if(isHLTTruncated()){
-        ATH_MSG_WARNING("HLTResult truncated, skip trigger analysis");
+        ATH_MSG_DEBUG("HLTResult truncated, skip trigger analysis");
         return StatusCode::SUCCESS;
     }
 
@@ -130,13 +131,13 @@ bool TrigEgammaMonitorTagAndProbeAlgorithm::executeTandP( const EventContext& ct
 
     SG::ReadHandle<xAOD::EventInfo> eventInfo = GetEventInfo (ctx);
     if( !eventInfo.isValid() ){
-      ATH_MSG_WARNING("Failed to retrieve EventInfo");
+      ATH_MSG_DEBUG("Failed to retrieve EventInfo");
       return false;
     }
 
 
     if (eventInfo->errorState(xAOD::EventInfo::LAr) == xAOD::EventInfo::Error) {
-        ATH_MSG_WARNING("Event not passing LAr");
+        ATH_MSG_DEBUG("Event not passing LAr");
         return false;
     }
 
@@ -148,7 +149,7 @@ bool TrigEgammaMonitorTagAndProbeAlgorithm::executeTandP( const EventContext& ct
 
     if(!offElectrons.isValid())
     {
-      ATH_MSG_WARNING("Failed to retrieve offline Electrons ");
+      ATH_MSG_DEBUG("Failed to retrieve offline Electrons ");
 	    return false;
     }
 
@@ -173,7 +174,7 @@ bool TrigEgammaMonitorTagAndProbeAlgorithm::executeTandP( const EventContext& ct
     
     SG::ReadHandle<xAOD::JetContainer> jets(m_jetKey,ctx);
     if(!jets.isValid() && m_applyJetNearProbeSelection){
-      ATH_MSG_WARNING("Failed to retrieve JetContainer");
+      ATH_MSG_DEBUG("Failed to retrieve JetContainer");
       return false;
     }
 
diff --git a/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorTopoAlgorithm.cxx b/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorTopoAlgorithm.cxx
index b0a31e8f210e116c259df1b1c9ae085048b86ec2..7b20f87adff9d9f6df91dce4cc80788340817c10 100644
--- a/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorTopoAlgorithm.cxx
+++ b/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorTopoAlgorithm.cxx
@@ -42,7 +42,7 @@ StatusCode TrigEgammaMonitorTopoAlgorithm::fillHistograms( const EventContext& c
     ATH_MSG_DEBUG("Executing TrigEgammaMonitorTopoAlgorithm");
 
     if(isHLTTruncated()){
-        ATH_MSG_WARNING("HLTResult truncated, skip trigger analysis");
+        ATH_MSG_DEBUG("HLTResult truncated, skip trigger analysis");
         return StatusCode::SUCCESS; 
     }
     
@@ -52,13 +52,13 @@ StatusCode TrigEgammaMonitorTopoAlgorithm::fillHistograms( const EventContext& c
 
     if(!offElectrons.isValid())
     {
-      ATH_MSG_WARNING("Failed to retrieve offline Electrons ");
+      ATH_MSG_DEBUG("Failed to retrieve offline Electrons ");
       return StatusCode::SUCCESS;
     }
 
     if(!offPhotons.isValid())
     {
-      ATH_MSG_WARNING("Failed to retrieve offline Photons ");
+      ATH_MSG_DEBUG("Failed to retrieve offline Photons ");
       return StatusCode::SUCCESS;
     }
     
diff --git a/Trigger/TrigValidation/TrigInDetValidation/python/TrigInDetArtSteps.py b/Trigger/TrigValidation/TrigInDetValidation/python/TrigInDetArtSteps.py
index 5413b7f702fbb195e57b24cb28b88e9214b46684..94889fbd5524bea9a5c1188fcb9b631033fe4815 100644
--- a/Trigger/TrigValidation/TrigInDetValidation/python/TrigInDetArtSteps.py
+++ b/Trigger/TrigValidation/TrigInDetValidation/python/TrigInDetArtSteps.py
@@ -118,6 +118,9 @@ class TrigInDetReco(ExecStep):
                 chains +=  "'HLT_tau25_idperf_mediumRNN_trackLRT_L1TAU12IM',"
                 flags += 'doTauSlice=True;'
             if (i=='bjet') :
+#               chains += "'HLT_j80_pf_ftf_preselj20b95_L1J20',"
+                chains += "'HLT_j20_roiftf_preselj20_L1RD0_FILLED',"
+                chains += "'HLT_j45_pf_ftf_preselj20_L1jJ40',"
 #               chains += "'HLT_j45_subjesgscIS_ftf_boffperf_split_L1J20',"
                 chains += "'HLT_j45_0eta290_020jvt_boffperf_pf_ftf_L1J20',"
                 flags  += 'doBjetSlice=True;'
diff --git a/Trigger/TrigValidation/TrigInDetValidation/share/TrigInDetValidation_AODtoTrkNtuple.py b/Trigger/TrigValidation/TrigInDetValidation/share/TrigInDetValidation_AODtoTrkNtuple.py
index ee45cd2470808adbe42a389bbc1f5e2bec3f916c..ad19fe6fe17e2aa57c3a3aaa146ae3e1a067b966 100644
--- a/Trigger/TrigValidation/TrigInDetValidation/share/TrigInDetValidation_AODtoTrkNtuple.py
+++ b/Trigger/TrigValidation/TrigInDetValidation/share/TrigInDetValidation_AODtoTrkNtuple.py
@@ -165,7 +165,12 @@ if ( True ) :
 
     "HLT_j45_subjesgscIS_ftf_boffperf_split_L1J20:key=HLT_IDTrack_Bjet_FTF",
     "HLT_j45_subjesgscIS_ftf_boffperf_split_L1J20:key=HLT_IDTrack_Bjet_IDTrig",
+
     "HLT_j45_ftf_subjesgscIS_boffperf_split_L1J20:key=HLT_IDTrack_FS_FTF:roi=HLT_FSRoI:vtx=HLT_IDVertex_FS",
+
+    "HLT_j.*_presel_.*:key=HLT_IDTrack_JetSuper_FTF:roi=HLT_Roi_JetSuper",
+    "HLT_j.*_presel_.*:key=HLT_IDTrack_JetSuper_FTF:roi=HLT_Roi_JetSuper:vtx=HLT_IDVertex_JetSuper",
+
     "HLT_j45_0eta290_020jvt_boffperf_pf_ftf_L1J20:key=HLT_IDTrack_Bjet_IDTrig:roi=HLT_Roi_Bjet:vtx=HLT_AntiKt4EMPFlowJets_subresjesgscIS_ftf_BTaggingSecVtx",
     # don't use FSJet any longer
     # "HLT_j45_ftf_subjesgscIS_boffperf_split_L1J20:key=HLT_IDTrack_FS_FTF:roi=HLT_FSRoI:vtx=HLT_IDVertex_FSJet",
diff --git a/Trigger/TrigValidation/TrigInDetValidation/share/comparitor.json b/Trigger/TrigValidation/TrigInDetValidation/share/comparitor.json
index 25d5dc8e610bdb52940cd9a01407ba51fea0cdd5..b30e375660747ad5f4ddf7bce129c81c218a793e 100644
--- a/Trigger/TrigValidation/TrigInDetValidation/share/comparitor.json
+++ b/Trigger/TrigValidation/TrigInDetValidation/share/comparitor.json
@@ -55,7 +55,7 @@
         "chains" : "HLT_tau25_idperf_tracktwoMVA_L1TAU12IM:HLT_IDTrack_Tau_IDTrig:HLT_Roi_TauIso:HLT_IDVertex_Tau/HLT_IDVertex_Tau"
     },
     "L2bjet":{
-        "chains" : "HLT_j45_0eta290_020jvt_boffperf_pf_ftf_L1J20:HLT_IDTrack_Bjet_FTF"
+        "chains" : "HLT_j45_0eta290_020jvt_boffperf_pf_ftf_L1J20:HLT_IDTrack_Bjet_FTF HLT_j80_pf_ftf_preselj20b95_L1J20:HLT_IDTrack_JetSuper_FTF:HLT_Roi_JetSuper HLT_j20_roiftf_preselj20_L1RD0_FILLED:HLT_IDTrack_JetSuper_FTF:HLT_Roi_JetSuper"
     },
     "EFbjet":{
         "chains" : "HLT_j45_0eta290_020jvt_boffperf_pf_ftf_L1J20:HLT_IDTrack_Bjet_FTF HLT_j45_0eta290_020jvt_boffperf_pf_ftf_L1J20:HLT_IDTrack_Bjet_IDTrig"