diff --git a/DataQuality/dqm_algorithms/src/ZDCTestConstantVsLB.cxx b/DataQuality/dqm_algorithms/src/ZDCTestConstantVsLB.cxx
index 67b88b19026c026ee6feb51b9b9bceed5beb81a3..42cb764de4008727b9c4ae5ab362f7fbb6869b6c 100644
--- a/DataQuality/dqm_algorithms/src/ZDCTestConstantVsLB.cxx
+++ b/DataQuality/dqm_algorithms/src/ZDCTestConstantVsLB.cxx
@@ -105,6 +105,12 @@ namespace dqm_algorithms {
 		  }
 
 		TFitResultPtr fit_res = ge->Fit("pol0","QNS0");
+		if (!fit_res.Get())
+		  {
+		    result->status_ = dqm_core::Result::Yellow;
+		    return result;
+		  }
+		
 		double mean = fit_res->Value(0);
 
 		std::vector<int> yellowLBs;
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/CMakeLists.txt b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/CMakeLists.txt
index cdf0456f4949aeb2ea0ffdfe2346e5d8e647bcc0..d57fc517776f63fcc69f6c52510e1b2d9a71eee3 100644
--- a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/CMakeLists.txt
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/CMakeLists.txt
@@ -48,6 +48,7 @@ set(FTDSource
   Root/ConstituentsLoader.cxx
   Root/TracksLoader.cxx
   Root/IParticlesLoader.cxx
+  Root/HitsLoader.cxx
   Root/CustomGetterUtils.cxx
   Root/StringUtils.cxx
 )
@@ -99,6 +100,8 @@ if (NOT XAOD_STANDALONE)
     src/BTagTrackLinkCopyAlg.cxx
     src/BTaggingBuilderAlg.cxx
     src/PoorMansIpAugmenterAlg.cxx
+    src/HitDecoratorAlg.cxx
+    src/JetHitAssociationAlg.cxx
     src/BTagConditionalDecoratorAlg.cxx
     src/JetTagConditionalDecoratorAlg.cxx
     src/TruthDecoratorHelpers.cxx
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/ConstituentsLoader.h b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/ConstituentsLoader.h
index 05713974ec64abc3247073354be053f28136c3fa..24dd94623d90021e1a2877a5b6d3c2087e6f2861 100644
--- a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/ConstituentsLoader.h
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/ConstituentsLoader.h
@@ -47,7 +47,8 @@ namespace FlavorTagDiscriminants {
     };
     enum class ConstituentsType {
         IPARTICLE,
-        TRACK
+        TRACK,
+        HIT
     };
 
     struct InputVariableConfig {
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/CustomGetterUtils.h b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/CustomGetterUtils.h
index f3a96a0ca664b5819ca97dee926ff779170514cb..d3fb7b6c5919bf78a543f75fbf82f5aedd4e8c1a 100644
--- a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/CustomGetterUtils.h
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/CustomGetterUtils.h
@@ -27,6 +27,7 @@
 #include "xAODJet/JetFwd.h"
 #include "xAODTracking/TrackParticleFwd.h"
 #include "xAODBase/IParticle.h"
+#include "xAODTracking/TrackMeasurementValidationContainer.h"
 #include "AthContainers/AuxElement.h"
 #include "FlavorTagDiscriminants/DataPrepUtilities.h"
 
@@ -65,6 +66,7 @@ namespace FlavorTagDiscriminants {
      * It supports the following types of constituents:
      * - xAOD::IParticle
      * - xAOD::TrackParticle
+     * - xAOD::TrackMeasurementValidation
     */
     template <typename T>
     class SeqGetter {
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/GNN.h b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/GNN.h
index 8bc0245a4d98f670b9ebd0da75ebab917b8d6f7e..ed53dc2b33d6e3dccbd32a46bb47644a944a4070 100644
--- a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/GNN.h
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/GNN.h
@@ -20,6 +20,7 @@
 #include "FlavorTagDiscriminants/DataPrepUtilities.h"
 #include "FlavorTagDiscriminants/TracksLoader.h"
 #include "FlavorTagDiscriminants/IParticlesLoader.h"
+#include "FlavorTagDiscriminants/HitsLoader.h"
 
 // EDM includes
 #include "xAODBTagging/BTaggingFwd.h"
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/HitDecoratorAlg.h b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/HitDecoratorAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..912b99c3bbca985f4b1c9b537b88c4b74cf7db27
--- /dev/null
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/HitDecoratorAlg.h
@@ -0,0 +1,56 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef HIT_DECORATOR_ALG_HH
+#define HIT_DECORATOR_ALG_HH
+
+// FrameWork includes
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+
+// Containers
+#include "xAODEventInfo/EventInfo.h"
+#include "xAODTracking/TrackMeasurementValidationContainer.h"
+
+// Read and write handle keys
+#include "StoreGate/WriteDecorHandleKey.h"
+#include "StoreGate/ReadDecorHandleKey.h"
+
+
+
+namespace FlavorTagDiscriminants {
+
+  class HitDecoratorAlg: public AthReentrantAlgorithm {
+    
+    public:
+    
+      HitDecoratorAlg(const std::string& name,
+                            ISvcLocator* pSvcLocator );
+
+      virtual StatusCode initialize() override;
+      virtual StatusCode execute(const EventContext& ) const override;
+      virtual StatusCode finalize() override;
+
+
+    private:
+
+      // Read and write handle keys
+      SG::ReadHandleKey< xAOD::TrackMeasurementValidationContainer > m_HitContainerKey {
+        this,"hitContainer","PixelClusters","Key for hits"};
+
+      SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey {
+        this,"eventInfo","EventInfo","Key for EventInfo"};
+
+      SG::WriteDecorHandleKey< xAOD::TrackMeasurementValidationContainer > m_OutputHitXKey {
+        this, "hitsXRelToBeamspotDecorator", "HitsXRelToBeamspot", "Key for output hits x coordinate relative to beamspot"};
+
+      SG::WriteDecorHandleKey< xAOD::TrackMeasurementValidationContainer > m_OutputHitYKey {
+        this, "hitsYRelToBeamspotDecorator", "HitsYRelToBeamspot", "Key for output hits y coordinate relative to beamspot"};
+
+      SG::WriteDecorHandleKey< xAOD::TrackMeasurementValidationContainer > m_OutputHitZKey {
+        this, "hitsZRelToBeamspotDecorator", "HitsZRelToBeamspot", "Key for output hits z coordinate relative to beamspot"};
+
+  };
+}
+
+#endif
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/HitsLoader.h b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/HitsLoader.h
new file mode 100644
index 0000000000000000000000000000000000000000..e450d48fdb037430b9f38d418b284daa4448c2c4
--- /dev/null
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/HitsLoader.h
@@ -0,0 +1,70 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+
+  This is a subclass of IConstituentsLoader. It is used to load the general IParticles from the jet 
+  and extract their features for the NN evaluation. For now it supports only neutral flow objects.
+  Charged flow objects have experimental support and are not recommended for use.
+*/
+
+#ifndef HITS_LOADER_H
+#define HITS_LOADER_H
+
+// local includes
+#include "FlavorTagDiscriminants/ConstituentsLoader.h"
+#include "FlavorTagDiscriminants/CustomGetterUtils.h"
+
+// EDM includes
+#include "xAODJet/JetFwd.h"
+#include "xAODBase/IParticle.h"
+#include "xAODTracking/TrackMeasurementValidationContainer.h"
+
+// STL includes
+#include <string>
+#include <vector>
+#include <functional>
+#include <exception>
+#include <type_traits>
+#include <regex>
+
+namespace FlavorTagDiscriminants {
+
+    ConstituentsInputConfig createHitsLoaderConfig(
+      std::pair<std::string, std::vector<std::string>> hits_names
+    );
+    // Subclass for Hits loader inherited from abstract IConstituentsLoader class
+    class HitsLoader : public IConstituentsLoader {
+      public:
+        HitsLoader(ConstituentsInputConfig, const FTagOptions& options);
+        std::tuple<std::string, Inputs, std::vector<const xAOD::IParticle*>> getData(
+          const xAOD::Jet& jet, 
+          [[maybe_unused]] const SG::AuxElement& btag) const override ;
+        FTagDataDependencyNames getDependencies() const override;
+        std::set<std::string> getUsedRemap() const override;
+        std::string getName() const override;
+        ConstituentsType getType() const override;
+      protected:
+        // typedefs
+        typedef xAOD::Jet Jet;
+        typedef std::pair<std::string, double> NamedVar;
+        typedef std::pair<std::string, std::vector<double> > NamedSeq;
+        // hit typedefs
+        typedef std::vector<const xAOD::TrackMeasurementValidation*> Hits;
+
+        // getter function
+        typedef std::function<NamedSeq(const Jet&, const Hits&)> SeqFromHits;
+
+        // usings for Hits getter
+        using AE = SG::AuxElement;
+        using TMC = xAOD::TrackMeasurementValidationContainer;
+        using HitLinks = std::vector<ElementLink<TMC>>;
+        using TMVV = std::vector<const xAOD::TrackMeasurementValidation*>;
+
+        
+        std::vector<const xAOD::TrackMeasurementValidation*> getHitsFromJet(const xAOD::Jet& jet) const;
+
+        getter_utils::SeqGetter<xAOD::TrackMeasurementValidation> m_seqGetter;        
+        std::function<TMVV(const Jet&)> m_associator;
+    };
+}
+
+#endif
\ No newline at end of file
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/JetHitAssociationAlg.h b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/JetHitAssociationAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..1873d5985b9d205a9fd68b9e0d13235e77e26c2f
--- /dev/null
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/FlavorTagDiscriminants/JetHitAssociationAlg.h
@@ -0,0 +1,68 @@
+/*
+ Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef JET_HIT_ASSOCIATION_ALG_HH
+#define JET_HIT_ASSOCIATION_ALG_HH
+
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+
+// Containers
+#include "xAODJet/JetContainer.h"
+#include "xAODTracking/TrackMeasurementValidationContainer.h"
+#include "xAODEventInfo/EventInfo.h"
+
+// Read and write handles
+#include "StoreGate/WriteDecorHandleKey.h"
+#include "StoreGate/ReadDecorHandleKey.h"
+
+// Element links
+#include "AthLinks/ElementLink.h"
+
+
+namespace FlavorTagDiscriminants {
+
+  class JetHitAssociationAlg : public AthReentrantAlgorithm{
+    
+    public:
+      
+      JetHitAssociationAlg (const std::string& name,
+                        ISvcLocator* pSvcLocator);
+
+      virtual StatusCode initialize() override;
+      virtual StatusCode execute(const EventContext& ) const override;
+      virtual StatusCode finalize() override;
+    
+    
+    private:
+
+      SG::ReadHandleKey<xAOD::JetContainer> m_jetCollectionKey {
+        this,"jetContainer","tempEmtopoJets","Key for jets"};
+
+      SG::ReadHandleKey<xAOD::TrackMeasurementValidationContainer>  m_inputPixHitCollectionKey{
+        this,"hitContainer","PixelClusters","Key for hits"};
+
+      SG::ReadDecorHandleKey<xAOD::TrackMeasurementValidationContainer> m_HitsXRelToBeamspotKey{
+        this, "hitReaderX","HitsXRelToBeamspot","Key for output hits x coordinate relative to beamspot"};
+
+      SG::ReadDecorHandleKey<xAOD::TrackMeasurementValidationContainer> m_HitsYRelToBeamspotKey{
+        this, "hitReaderY","HitsYRelToBeamspot","Key for output hits y coordinate relative to beamspot"};
+
+      SG::WriteDecorHandleKey< xAOD::JetContainer > m_hitAssociationKey{
+        this,"hitAssociation","hitsAssociatedWithJet","Key for decorating links"};
+      
+      Gaudi::Property <float>  m_dPhiHitToJet{
+        this, "dphiHitToJet", 0.2, "Phi difference between hit and jet"};
+
+      Gaudi::Property <int>  m_maxHits{
+        this, "maxHits", 200, "Maximum number of hits"};
+      
+  };
+}
+
+#endif
\ No newline at end of file
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/ConstituentsLoader.cxx b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/ConstituentsLoader.cxx
index bd114ba0e1ca525373b3fcf17e6b6a8dd2081453..bf413619e9748626312f4d36ee2ca473eb1f13e8 100644
--- a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/ConstituentsLoader.cxx
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/ConstituentsLoader.cxx
@@ -77,6 +77,23 @@ namespace {
   }
 }
 
+  ConstituentsInputConfig get_hits_input_config(
+    const std::string& name,
+    const std::vector<std::string>& input_variables,
+    const TypeRegexes& type_regexes) {
+    ConstituentsInputConfig config;
+    config.name = name;
+    for (const auto& varname: input_variables) {
+      InputVariableConfig input;      
+      input.name = varname;
+      input.type = str::match_first(type_regexes, input.name,
+                                "hits type matching");
+      input.flip_sign = false;
+      config.inputs.push_back(input);
+    }
+    return config;
+  }
+
 namespace FlavorTagDiscriminants {
     //
     // Create a configuration for the constituents loaders
@@ -87,7 +104,11 @@ namespace FlavorTagDiscriminants {
       FlipTagConfig flip_config
     ){
       ConstituentsInputConfig config;
-
+      TypeRegexes hits_type_regexes {
+          // hits variables
+          // ConstituentsEDMType picked correspond to the first matching regex
+          {"(j|a|b)"_r, ConstituentsEDMType::CUSTOM_GETTER}
+      };
       TypeRegexes iparticle_type_regexes {
           // iparticle variables
           // ConstituentsEDMType picked correspond to the first matching regex
@@ -153,6 +174,13 @@ namespace FlavorTagDiscriminants {
         config.type = ConstituentsType::IPARTICLE;
         config.output_name = "flows";
       }
+      else if (name.find("hits") != std::string::npos){
+        config = get_hits_input_config(
+          name, input_variables,
+          hits_type_regexes);
+        config.type = ConstituentsType::HIT;
+        config.output_name = "hits";
+      }
       else{
         throw std::runtime_error(
           "Unknown constituent type: " + name + ". Only tracks and flows are supported."
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/CustomGetterUtils.cxx b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/CustomGetterUtils.cxx
index 1e567ea0aa922f0d7001d8a27b9c764dfb88b1c1..08cd1a8d8c9f07ab62ba6bb397d038a9db389e59 100644
--- a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/CustomGetterUtils.cxx
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/CustomGetterUtils.cxx
@@ -5,6 +5,8 @@
 #include "FlavorTagDiscriminants/CustomGetterUtils.h"
 
 #include <optional>
+#include <TVector3.h>
+#include "GeoPrimitives/GeoPrimitives.h"
 
 namespace {
 
@@ -229,6 +231,7 @@ namespace {
   getterFromIParticles(const std::string& name)
   {
     using Jet = xAOD::Jet;
+
     if (name == "pt") {
       return CustomSeqGetter<T>([](const T& p, const Jet&) {
         return p.pt();
@@ -302,6 +305,61 @@ namespace {
     return std::nullopt;
   }
 
+
+  // Eigen::Vector3d getJab(const Eigen::Vector3d local_hits, const xAOD::Jet& j)
+  Eigen::Vector3d getJab(const float local_hitX, const float local_hitY, const float local_hitZ, const xAOD::Jet& j)
+  {
+    // I want to compute jab coordinates: jet projection, adjacent
+    // projection, beamline projection. The "adjacent" projection
+    // is defined to be orthogonal to the jet and beam, but this
+    // isn't a fully orthogonal basis. 
+
+    auto p4 = j.p4();
+    Eigen::Vector3d local_hits (local_hitX, local_hitY, local_hitZ);
+    Eigen::Vector3d bhat(0,0,1);
+    Eigen::Vector3d jet (p4.X(), p4.Y(), p4.Z());
+    Eigen::Vector3d jhat = jet.normalized();
+    Eigen::Vector3d a = bhat.cross(jhat);
+    Eigen::Vector3d ahat = a.normalized();
+    // build the matrix m that maps the jab displacement such that m*jab = detector
+    Eigen::Matrix3d m;
+    m << jhat, ahat, bhat;
+    // now solve this for jab = m^-1 * detector
+    Eigen::Vector3d jab = m.inverse() * local_hits;
+    return jab;
+  }
+
+
+  // Getters from general xAOD::TrackMeasurementValidation and derived classes
+  std::optional<SequenceGetterFunc<xAOD::TrackMeasurementValidation>>
+  getterFromHits(const std::string& name)
+  {
+    using Tmv = xAOD::TrackMeasurementValidation;
+    using Jet = xAOD::Jet;
+    
+    SG::AuxElement::ConstAccessor<float> local_hitX("HitsXRelToBeamspot");
+    SG::AuxElement::ConstAccessor<float> local_hitY("HitsYRelToBeamspot");
+    SG::AuxElement::ConstAccessor<float> local_hitZ("HitsZRelToBeamspot");
+
+    if (name == "j") {
+      return CustomSeqGetter<Tmv>([local_hitX, local_hitY, local_hitZ](const Tmv& tmv, const Jet& j) {
+        return getJab(local_hitX(tmv), local_hitY(tmv), local_hitZ(tmv), j)(0);
+      });
+    }
+    else if (name == "a") {
+      return CustomSeqGetter<Tmv>([local_hitX, local_hitY, local_hitZ](const Tmv& tmv, const Jet& j) {
+        return getJab(local_hitX(tmv), local_hitY(tmv), local_hitZ(tmv), j)(1);
+      });
+    }
+    else if (name == "b") {
+      return CustomSeqGetter<Tmv>([local_hitX, local_hitY, local_hitZ](const Tmv& tmv, const Jet& j) {
+        return getJab(local_hitX(tmv), local_hitY(tmv), local_hitZ(tmv), j)(2);
+      });
+    }
+    return std::nullopt;
+  }
+
+
 }
   namespace FlavorTagDiscriminants {
   namespace getter_utils {
@@ -337,8 +395,17 @@ namespace {
           return {*getter, {}};
         }
       }
-      if (auto getter = getterFromIParticles<T>(name)){
-        return {*getter, {}};
+
+      if constexpr (std::is_base_of_v<xAOD::IParticle, T>){
+        if (auto getter = getterFromIParticles<T>(name)){
+          return {*getter, {}};
+        }
+      }
+
+      if constexpr (std::is_same_v<T, xAOD::TrackMeasurementValidation>) {
+        if (auto getter = getterFromHits(name)){
+          return {*getter, {"HitsXRelToBeamspot", "HitsYRelToBeamspot", "HitsZRelToBeamspot"}};
+        }
       }
       throw std::logic_error("no match for custom getter " + name);
     }
@@ -458,8 +525,9 @@ namespace {
     }
 
 
-    // Explicit instantiations of supported types (IParticle, TrackParticle)
+    // Explicit instantiations of supported types (IParticle, TrackParticle, TrackMeasurementValidation)
     template class SeqGetter<xAOD::IParticle>;
     template class SeqGetter<xAOD::TrackParticle>;
+    template class SeqGetter<xAOD::TrackMeasurementValidation>;
   }
 }
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/GNN.cxx b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/GNN.cxx
index 93969892c1131f1c44b5a729690bf00cfbd60b0b..fbaef128a346f343c49d26c69d8482204da10b0d 100644
--- a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/GNN.cxx
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/GNN.cxx
@@ -60,12 +60,16 @@ namespace FlavorTagDiscriminants {
         lwt_config, o.flip_config, o.variable_remapping, o.track_link_type);
     for (auto config : constituents_configs){
       switch (config.type){
-      case ConstituentsType::TRACK:
+      using enum ConstituentsType;
+      case TRACK:
         m_constituentsLoaders.push_back(std::make_shared<TracksLoader>(config, options));
         break;
-      case ConstituentsType::IPARTICLE:
+      case IPARTICLE:
         m_constituentsLoaders.push_back(std::make_shared<IParticlesLoader>(config, options));
         break;
+      case HIT:
+        m_constituentsLoaders.push_back(std::make_shared<HitsLoader>(config, options));
+        break;
       }
     }
 
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/HitsLoader.cxx b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/HitsLoader.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e4a2f4276ca16f7baa30809e27d128bea86d78af
--- /dev/null
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/HitsLoader.cxx
@@ -0,0 +1,68 @@
+/*
+Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "FlavorTagDiscriminants/HitsLoader.h"
+#include "xAODPFlow/FlowElement.h"
+#include "FlavorTagDiscriminants/StringUtils.h"
+
+namespace FlavorTagDiscriminants {
+    
+
+    HitsLoader::HitsLoader(
+        ConstituentsInputConfig cfg,
+        const FTagOptions& options
+    ):
+        IConstituentsLoader(cfg),
+        m_seqGetter(getter_utils::SeqGetter<xAOD::TrackMeasurementValidation>(
+          cfg.inputs, options))
+    {
+        SG::AuxElement::ConstAccessor<HitLinks> acc("hitsAssociatedWithJet");
+        m_associator = [acc](const xAOD::Jet& jet) -> TMVV {
+          TMVV hits;
+          for (const ElementLink<TMC>& link : acc(jet)){
+            if (!link.isValid()) {
+              throw std::logic_error("invalid hits link");
+            }
+            hits.push_back(*link);
+          }
+          return hits;
+        };
+
+        m_used_remap = m_seqGetter.getUsedRemap();
+        m_name = cfg.name;
+    }
+
+    std::vector<const xAOD::TrackMeasurementValidation*> HitsLoader::getHitsFromJet(
+        const xAOD::Jet& jet
+    ) const
+    {
+        std::vector<const xAOD::TrackMeasurementValidation*> hits;
+        for (const xAOD::TrackMeasurementValidation *tp : m_associator(jet)) {
+          hits.push_back(tp);
+        }
+        return hits;
+    }
+
+    std::tuple<std::string, Inputs, std::vector<const xAOD::IParticle*>> HitsLoader::getData(
+      const xAOD::Jet& jet, 
+      [[maybe_unused]] const SG::AuxElement& btag) const {
+        Hits sorted_hits = getHitsFromJet(jet);
+        std::vector<const xAOD::IParticle*> dummy;
+        return std::make_tuple(m_config.output_name, m_seqGetter.getFeats(jet, sorted_hits), dummy);
+    }
+
+    FTagDataDependencyNames HitsLoader::getDependencies() const {
+        return m_deps;
+    }
+    std::set<std::string> HitsLoader::getUsedRemap() const {
+        return m_used_remap;
+    }
+    std::string HitsLoader::getName() const {
+        return m_name;
+    }
+    ConstituentsType HitsLoader::getType() const {
+        return m_config.type;
+    }
+
+}
\ No newline at end of file
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/src/HitDecoratorAlg.cxx b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/src/HitDecoratorAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f40796ca82816a6819006bbd161110a5ac7fbd09
--- /dev/null
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/src/HitDecoratorAlg.cxx
@@ -0,0 +1,84 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+// Header file
+#include "FlavorTagDiscriminants/HitDecoratorAlg.h"
+
+// Read and write handles
+#include "StoreGate/WriteDecorHandle.h"
+#include "StoreGate/ReadDecorHandle.h"
+
+
+
+namespace FlavorTagDiscriminants {
+
+  HitDecoratorAlg::HitDecoratorAlg(
+    const std::string& name, ISvcLocator* loc )
+    : AthReentrantAlgorithm(name, loc) {}
+
+
+  StatusCode HitDecoratorAlg::initialize() {
+    ATH_MSG_INFO( "Initializing " << name());
+
+    // Initialize reader
+    ATH_CHECK( m_eventInfoKey.initialize() );
+    ATH_CHECK( m_HitContainerKey.initialize() );
+
+    // Initialize decorator
+    m_OutputHitXKey = m_HitContainerKey.key() + "." + m_OutputHitXKey.key();
+    CHECK( m_OutputHitXKey.initialize() );
+    m_OutputHitYKey = m_HitContainerKey.key() + "." + m_OutputHitYKey.key();
+    CHECK( m_OutputHitYKey.initialize() );
+    m_OutputHitZKey = m_HitContainerKey.key() + "." + m_OutputHitZKey.key();
+    CHECK( m_OutputHitZKey.initialize() );
+
+    return StatusCode::SUCCESS;
+  }
+
+
+  StatusCode HitDecoratorAlg::execute(const EventContext& ctx) const {
+    ATH_MSG_DEBUG( "Executing " << name());
+    // Read out event info
+    SG::ReadHandle<xAOD::EventInfo> event_info(m_eventInfoKey, ctx);
+    if ( !event_info.isValid() ) {
+      ATH_MSG_ERROR("Failed to retrieve event info container with key " << m_eventInfoKey.key() );
+      return StatusCode::FAILURE;
+    }
+
+    // Read out hits
+    SG::ReadHandle<xAOD::TrackMeasurementValidationContainer> hits (m_HitContainerKey, ctx);
+    if ( !hits.isValid() ) {
+      ATH_MSG_ERROR("Failed to retrieve hit container with key " << m_HitContainerKey.key() );
+      return StatusCode::FAILURE;
+    }
+
+    // Set up decorator
+    SG::WriteDecorHandle<xAOD::TrackMeasurementValidationContainer, float> correctedHitX (m_OutputHitXKey, ctx);
+    SG::WriteDecorHandle<xAOD::TrackMeasurementValidationContainer, float> correctedHitY (m_OutputHitYKey, ctx);
+    SG::WriteDecorHandle<xAOD::TrackMeasurementValidationContainer, float> correctedHitZ (m_OutputHitZKey, ctx);
+
+    // Construct beamspot vector
+    const xAOD::EventInfo& ei = *event_info;
+
+    // Calculate relative hit position to beamsport and decorate it to hits container
+    for (const auto *hit: *hits) {
+      float localX = hit->globalX() - ei.beamPosX();
+      float localY = hit->globalY() - ei.beamPosY();
+      float localZ = hit->globalZ() - ei.beamPosZ();
+      
+      correctedHitX(*hit) = localX;
+      correctedHitY(*hit) = localY;
+      correctedHitZ(*hit) = localZ;
+
+    }
+    
+    return StatusCode::SUCCESS;
+  }
+
+
+  StatusCode HitDecoratorAlg::finalize() {
+    return StatusCode::SUCCESS;
+  }
+}
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/src/JetHitAssociationAlg.cxx b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/src/JetHitAssociationAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2904f8ecff6984cf583fe500d79447343ecae015
--- /dev/null
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/src/JetHitAssociationAlg.cxx
@@ -0,0 +1,112 @@
+/*
+Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+//Include header file
+#include "FlavorTagDiscriminants/JetHitAssociationAlg.h"
+
+#include "StoreGate/WriteDecorHandle.h"
+#include "StoreGate/ReadDecorHandle.h"
+
+//Include some helpful ROOT objects here.
+#include "math.h"
+
+
+namespace FlavorTagDiscriminants {
+
+  JetHitAssociationAlg::JetHitAssociationAlg(const std::string& name, ISvcLocator* loc)
+    : AthReentrantAlgorithm(name, loc){}
+
+
+  StatusCode JetHitAssociationAlg::initialize() {
+    
+    ATH_MSG_INFO( "Initializing " << name() );
+
+    // Initialize reader
+    ATH_CHECK(m_inputPixHitCollectionKey.initialize());
+    ATH_CHECK(m_jetCollectionKey.initialize());
+
+    // Initialize decoration reader
+    m_HitsXRelToBeamspotKey = m_inputPixHitCollectionKey.key() + "." + m_HitsXRelToBeamspotKey.key();
+    ATH_CHECK(m_HitsXRelToBeamspotKey.initialize());
+    m_HitsYRelToBeamspotKey = m_inputPixHitCollectionKey.key() + "." + m_HitsYRelToBeamspotKey.key();
+    ATH_CHECK(m_HitsYRelToBeamspotKey.initialize());
+
+    // Initialize decorator
+    m_hitAssociationKey = m_jetCollectionKey.key() + "." + m_hitAssociationKey.key();
+    CHECK(m_hitAssociationKey.initialize());
+    
+    return StatusCode::SUCCESS;
+  }
+
+
+  StatusCode JetHitAssociationAlg::execute(const EventContext& ctx) const {
+    ATH_MSG_DEBUG( "Executing " << name());
+    
+    // Read out jets
+    SG::ReadHandle<xAOD::JetContainer> jetReadHandle(m_jetCollectionKey, ctx);
+    if ( !jetReadHandle.isValid() ) {
+      ATH_MSG_ERROR("Failed to retrieve jet container with key " << m_jetCollectionKey.key() );
+      return StatusCode::FAILURE;
+    }
+    
+    std::vector<const xAOD::Jet*> jets;
+    jets.reserve( jetReadHandle->size() );
+    for (const xAOD::Jet *jet : *jetReadHandle) {
+      jets.push_back(jet);
+    }
+
+    // Read out hits relative to beamspot
+    SG::ReadDecorHandle<xAOD::TrackMeasurementValidationContainer, float> HitsXRelToBeamspot(m_HitsXRelToBeamspotKey, ctx);
+    SG::ReadDecorHandle<xAOD::TrackMeasurementValidationContainer, float> HitsYRelToBeamspot(m_HitsYRelToBeamspotKey, ctx);
+    
+    // Calculate hit phi values
+    std::vector<std::pair<float, const xAOD::TrackMeasurementValidation*>> hitCoord;
+
+    for (const auto* hit : *HitsXRelToBeamspot) {
+        auto localX = HitsXRelToBeamspot(*hit);
+        auto localY = HitsYRelToBeamspot(*hit);
+        float phi = std::atan2(localY, localX);
+        hitCoord.emplace_back(phi,hit);
+    }
+
+    // Set up element link
+    SG::WriteDecorHandle<xAOD::JetContainer,std::vector< ElementLink<xAOD::TrackMeasurementValidationContainer> > > hitAssociation (m_hitAssociationKey, ctx);
+    
+    // Loop over jets
+    for (const xAOD::Jet *jet : jets) {
+      std::vector<std::pair<float, const xAOD::TrackMeasurementValidation*>> closeHits;
+      std::vector<ElementLink<xAOD::TrackMeasurementValidationContainer> > vectorEL; 
+      double jetPhi = jet->phi();
+
+      // Compare phi values of hits and jets
+      for (const auto& [hitPhi, hit]: hitCoord) {
+        float dPhi = std::abs(jetPhi-hitPhi);
+        while (dPhi > M_PI) {dPhi -= 2. * M_PI; dPhi = std::abs(dPhi);}
+
+        if (dPhi < m_dPhiHitToJet) {
+          closeHits.emplace_back(dPhi, hit);
+        }
+      }
+
+      // Sort hits by dPhi and associate maximal m_maxHits hits to each jet
+      std::sort(closeHits.begin(), closeHits.end(),[](const auto& p1, const auto& p2) { return p1 < p2; });
+      closeHits.resize(std::min(int(m_maxHits), int(closeHits.size())));
+
+      for (const auto& [phi, hit]: closeHits) {
+        vectorEL.push_back(ElementLink<xAOD::TrackMeasurementValidationContainer>(m_HitsXRelToBeamspotKey.key(), hit->index()));
+      }
+
+      // Decorate the ElementLinks of hits to jet
+      hitAssociation(*jet) = vectorEL;   
+    }
+
+    return StatusCode::SUCCESS;
+  }
+
+
+  StatusCode JetHitAssociationAlg::finalize() {  
+    return StatusCode::SUCCESS;
+  }
+
+}
diff --git a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/src/components/FlavorTagDiscriminants_entries.cxx b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/src/components/FlavorTagDiscriminants_entries.cxx
index 62cf4b8febe246d5aa6854f301f2a83947d9b8c6..494c89259ff70ab51191491c0d6d0652fc7b9228 100644
--- a/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/src/components/FlavorTagDiscriminants_entries.cxx
+++ b/PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/src/components/FlavorTagDiscriminants_entries.cxx
@@ -24,8 +24,10 @@
 #include "FlavorTagDiscriminants/SoftElectronDecoratorAlg.h"
 #include "FlavorTagDiscriminants/SoftElectronTruthDecoratorAlg.h"
 #include "FlavorTagDiscriminants/GNNAuxTaskDecoratorAlg.h"
-#include <FlavorTagDiscriminants/TrackClassifier.h>
+#include "FlavorTagDiscriminants/TrackClassifier.h"
 #include "FlavorTagDiscriminants/FTagGhostElectronAssociationAlg.h"
+#include "FlavorTagDiscriminants/HitDecoratorAlg.h"
+#include "FlavorTagDiscriminants/JetHitAssociationAlg.h"
 
 #include "src/FoldDecoratorAlg.h"
 #include "src/CountIParticleAlg.h"
@@ -65,3 +67,5 @@ DECLARE_COMPONENT(GNNAuxTaskDecoratorAlg)
 DECLARE_COMPONENT(CountIParticleAlg)
 DECLARE_COMPONENT(CountTrackParticleAlg)
 DECLARE_COMPONENT(FTagGhostElectronAssociationAlg)
+DECLARE_COMPONENT(HitDecoratorAlg)
+DECLARE_COMPONENT(JetHitAssociationAlg)
diff --git a/Trigger/TrigAlgorithms/TrigCaloRec/src/HLTCaloCellCorrector.cxx b/Trigger/TrigAlgorithms/TrigCaloRec/src/HLTCaloCellCorrector.cxx
index 2ddc90dd9cd24b1bf3ce24365688de1688f6ee0d..4b2c8f068c19e5b93fd35f8e017ca079faee1c89 100644
--- a/Trigger/TrigAlgorithms/TrigCaloRec/src/HLTCaloCellCorrector.cxx
+++ b/Trigger/TrigAlgorithms/TrigCaloRec/src/HLTCaloCellCorrector.cxx
@@ -64,9 +64,9 @@ StatusCode HLTCaloCellCorrector::execute(EventContext const& context) const {
     outputCells->push_back(std::move(copy));
   }
 
-  for (auto const id : { CaloCell_ID::LAREM, CaloCell_ID::LARHEC, CaloCell_ID::LARFCAL, CaloCell_ID::TILE, })
+  for (auto const id : { CaloCell_ID::LAREM, CaloCell_ID::LARHEC, CaloCell_ID::LARFCAL, CaloCell_ID::TILE })
     if (inputCellHandle->hasCalo(id))
-      outputCells->setHasCalo(CaloCell_ID::LAREM);
+      outputCells->setHasCalo(id);
 
   outputCells->updateCaloIterators();
 
diff --git a/Trigger/TrigMonitoring/TrigEgammaMonitoring/python/TrigEgammaMonitCategory.py b/Trigger/TrigMonitoring/TrigEgammaMonitoring/python/TrigEgammaMonitCategory.py
index e8af5254c5887d80293d1cfe1f1e45bfd6609d2f..67f55b9522afdb8555d2ba57c15817716ea961af 100644
--- a/Trigger/TrigMonitoring/TrigEgammaMonitoring/python/TrigEgammaMonitCategory.py
+++ b/Trigger/TrigMonitoring/TrigEgammaMonitoring/python/TrigEgammaMonitCategory.py
@@ -56,13 +56,10 @@ def mongroupsCfg(moniAccess, data_type):
 
 
         elif data_type is DQDataType.HeavyIon:
-                monitoring_electron_hi=['HLT_e13_etcut_ion_L1eEM12L','HLT_e15_lhmedium_nogsf_ion_L1eEM15']
-                monitoring_photon_hi=['HLT_g13_etcut_ion_L1eEM12L','HLT_g15_loose_ion_L1eEM15']
-                monitoring_bootstrap_hi = {'HLT_g18_etcut_L1EM10' : 'HLT_g18_etcut_L1EM10'}
-
-                mongroups['monitoring_electron_hi']     = monitoring_electron_hi + monitoring_electron
-                mongroups['monitoring_photon_hi']       = monitoring_photon_hi + monitoring_photon
-                mongroups['monitoring_bootstrap_hi']    = monitoring_bootstrap_hi
+                mongroups['monitoring_electron_hi'] = ['HLT_e15_etcut_ion_L1eEM15','HLT_e30_etcut_ion_L1eEM26','HLT_e15_lhloose_nogsf_ion_L1eEM15','HLT_e15_loose_nogsf_ion_L1eEM15']
+                mongroups['monitoring_electron_TP_hi'] = ['HLT_e20_lhloose_nogsf_ion_L1eEM18','HLT_e20_loose_nogsf_ion_L1eEM18']
+                mongroups['monitoring_photon_hi'] = ['HLT_g15_loose_ion_L1eEM12','HLT_g20_etcut_ion_L1eEM15','HLT_g50_loose_ion_L1eEM26']
+                mongroups['monitoring_bootstrap_hi']    = {'HLT_g18_etcut_ion_L1eEM12' : 'HLT_g18_etcut_ion_L1eEM12'}
 
         elif data_type is DQDataType.Cosmics:
                 monitoring_electron_cosmic=['HLT_e5_etcut_L1eEM5']
diff --git a/Trigger/TrigMonitoring/TrigEgammaMonitoring/python/TrigEgammaMonitoringConfig.py b/Trigger/TrigMonitoring/TrigEgammaMonitoring/python/TrigEgammaMonitoringConfig.py
index 4ce4d8aefdefc6a853eec630e1f5e0cc026f92e2..939647a031fd63c25321da0276e6c82f53d89b66 100644
--- a/Trigger/TrigMonitoring/TrigEgammaMonitoring/python/TrigEgammaMonitoringConfig.py
+++ b/Trigger/TrigMonitoring/TrigEgammaMonitoring/python/TrigEgammaMonitoringConfig.py
@@ -96,6 +96,7 @@ class TrigEgammaMonAlgBuilder:
         self.activate_photon=True
         self.activate_topo= False
     elif self.HI_mode or self.pPb_mode or self.cosmic_mode:
+      self.activate_zee=True
       self.activate_electron=True
       self.activate_photon=True
     else:
@@ -121,16 +122,20 @@ class TrigEgammaMonAlgBuilder:
 
     if self.data_type is DQDataType.MC:
       self.mc_mode = True
+      self.__logger.info('TrigEgammaMonitoring configured for mc_mode')
       return True
     elif self.data_type is DQDataType.Collisions:
       self.pp_mode = True
+      self.__logger.info('TrigEgammaMonitoring configured for pp_mode')
       return True
     elif self.data_type is DQDataType.HeavyIon:
       self.HI_mode = True
       self.pPb_mode = True
+      self.__logger.info('TrigEgammaMonitoring configured for hi_mode')
       return True
     elif self.data_type is DQDataType.Cosmics:
       self.cosmic_mode = True
+      self.__logger.info('TrigEgammaMonitoring configured for cosmic_mode')
       return True
     else:
       return False
@@ -144,13 +149,10 @@ class TrigEgammaMonAlgBuilder:
     if self.pp_mode:
       self.setDefaultProperties()
     elif self.cosmic_mode:
-      # This should be change in future
       self.setDefaultProperties()
     elif self.HI_mode or self.pPb_mode:
-      # This should be change in future
       self.setDefaultProperties()
     elif self.mc_mode:
-      # This should be change in future
       self.setDefaultProperties()
     else:
       self.__logger.info('No monitoring mode configured, use default')
@@ -190,6 +192,7 @@ class TrigEgammaMonAlgBuilder:
         self.bootstrapMap = mongroups['monitoring_bootstrap_cosmic']
     elif self.HI_mode or self.pPb_mode:
         self.electronList = mongroups['monitoring_electron_hi']
+        self.tpList       = mongroups['monitoring_electron_TP_hi']
         self.photonList   = mongroups['monitoring_photon_hi']
         self.bootstrapMap = mongroups['monitoring_bootstrap_hi']
     else:
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXForwardJetsAlgo.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXForwardJetsAlgo.h
index bde6121aa2df0f78edb6817864c7fdd2aba71818..a05a978ac92c9f8b30cc6180524b0fc4ea5640be 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXForwardJetsAlgo.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXForwardJetsAlgo.h
@@ -46,7 +46,9 @@ namespace LVL1 {
     virtual std::unordered_map<int, jFEXForwardJetsInfo> FcalJetsTowerIDLists(int seedThreshold) override;
     virtual std::unordered_map<int, jFEXForwardJetsInfo> calculateJetETs(int seedThreshold) override;
     virtual void setFPGAEnergy(std::unordered_map<int,std::vector<int> > et_map)  override;
-
+    
+    virtual int SumEtSeed(unsigned int TTID) override;
+    
   protected:
 
   private:
@@ -81,7 +83,7 @@ namespace LVL1 {
         
         StatusCode ReadfromFile(const std::string& , std::unordered_map<unsigned int, std::vector<unsigned int> >&);
         
-        int SumEtSeed(unsigned int TTID);
+        
         int getEt(unsigned int TTID);
         bool isLM(unsigned int TTID);
         bool isLMabove(unsigned int TTID);
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXSmallRJetAlgo.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXSmallRJetAlgo.h
index eabeac41901ab54b5d6fe2a49996b14ef4b22362..c48a47e9557ddfeb63db0e6af89ae01406549fbf 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXSmallRJetAlgo.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXSmallRJetAlgo.h
@@ -42,6 +42,7 @@ namespace LVL1 {
     virtual unsigned int getTTowerET(unsigned int TTID ) const override;
     virtual void buildSeeds() override; 
     virtual bool isSeedLocalMaxima(int seedThreshold) override; 
+    virtual unsigned int getSeedET() const override;
     virtual unsigned int getSmallClusterET() const override;
     virtual unsigned int getSmallETRing() const override;
     virtual unsigned int getTTIDcentre() const override;
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXSysSim.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXSysSim.h
index f071550cae123e822fc8f0f642322fb79f30db3d..ff213722abdab116936d6c0b98bf6029e325c6d9 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXSysSim.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXSysSim.h
@@ -18,6 +18,7 @@
 #include "L1CaloFEXCond/jFEXDBCondData.h"
 #include "StoreGate/ReadCondHandleKey.h"
 #include "StoreGate/ReadHandleKey.h"
+#include "StoreGate/WriteDecorHandle.h"
 
 #include "L1CaloFEXSim/jFEXSim.h"
 #include "L1CaloFEXSim/jTower.h"
@@ -103,6 +104,12 @@ namespace LVL1 {
     SG::WriteHandleKey< xAOD::jFexTauRoIContainer>   m_xTobOutKey_jTau {this,"Key_xTobOutKey_jTau" ,"L1_jFexTauxRoI"  ,"Output jFexEDM xTOBs tau container"};
     SG::WriteHandleKey< xAOD::jFexFwdElRoIContainer> m_xTobOutKey_jEM  {this,"Key_xTobOutKey_jEM"  ,"L1_jFexFwdElxRoI","Output jFexEDM xTOBs fwdEl container"};    
 
+    // decoration handles for sim-only quantities
+    SG::WriteDecorHandleKey<xAOD::jFexSRJetRoIContainer> m_TobDecorKey_jJ_seedET  { this, "Key_tobDecor_jJ_seedET"  , m_TobOutKey_jJ   , "seedETMeV"  , "jJet seed ET value in MeV" };
+    SG::WriteDecorHandleKey<xAOD::jFexSRJetRoIContainer> m_xTobDecorKey_jJ_seedET { this, "Key_xTobDecor_jJ_seedET" , m_xTobOutKey_jJ  , "seedETMeV"  , "jJet seed ET value in MeV" };
+    
+
+
     std::unordered_map<int,jTower> m_jTowersColl;
 
     std::unordered_map<uint8_t, std::vector<std::vector<std::vector<uint32_t>>> > m_allfwdElTobs;
@@ -115,12 +122,13 @@ namespace LVL1 {
     
     
     // Create and fill a new EDMs object
-    StatusCode fillSRJetEDM(uint8_t jFexNum, uint8_t fpgaNumber, uint32_t tobWord, char istob, int resolution, float_t eta, float_t phi, std::unique_ptr< xAOD::jFexSRJetRoIContainer > &jContainer) const;
-    StatusCode fillLRJetEDM(uint8_t jFexNum, uint8_t fpgaNumber, uint32_t tobWord, char istob, int resolution, float_t eta, float_t phi, std::unique_ptr< xAOD::jFexLRJetRoIContainer > &jContainer) const;
-    StatusCode fillTauEDM  (uint8_t jFexNum, uint8_t fpgaNumber, uint32_t tobWord, char istob, int resolution, float_t eta, float_t phi, std::unique_ptr< xAOD::jFexTauRoIContainer   > &jContainer) const;
-    StatusCode fillFwdElEDM(uint8_t jFexNum, uint8_t fpgaNumber, uint32_t tobWord, char istob, int resolution, float_t eta, float_t phi, std::unique_ptr< xAOD::jFexFwdElRoIContainer > &jContainer) const;
-    StatusCode fillSumEtEDM(uint8_t jFexNum, uint8_t fpgaNumber, uint32_t tobWord, int resolution, std::unique_ptr< xAOD::jFexSumETRoIContainer > &jContainer) const;
-    StatusCode fillMetEDM  (uint8_t jFexNum, uint8_t fpgaNumber, uint32_t tobWord, int resolution, std::unique_ptr< xAOD::jFexMETRoIContainer   > &jContainer) const;
+    
+    StatusCode fillSRJetEDM(const std::unique_ptr<jFEXTOB>& internalTob, char istob, float_t eta, float_t phi, SG::WriteHandle<xAOD::jFexSRJetRoIContainer> &jContainer) const;
+    StatusCode fillLRJetEDM(const std::unique_ptr<jFEXTOB>& internalTob, char istob, float_t eta, float_t phi, SG::WriteHandle< xAOD::jFexLRJetRoIContainer > &jContainer) const;
+    StatusCode fillTauEDM  (const std::unique_ptr<jFEXTOB>& internalTob, char istob, float_t eta, float_t phi, SG::WriteHandle< xAOD::jFexTauRoIContainer   > &jContainer) const;
+    StatusCode fillFwdElEDM(uint8_t jFexNum, uint8_t fpgaNumber, uint32_t tobWord, char istob, int resolution, float_t eta, float_t phi, SG::WriteHandle< xAOD::jFexFwdElRoIContainer > &jContainer) const; //for fwdEl no "internal" jFEXTOB is created, thus more plain signature
+    StatusCode fillSumEtEDM(const std::unique_ptr<jFEXTOB>& internalTob, SG::WriteHandle< xAOD::jFexSumETRoIContainer > &jContainer) const;
+    StatusCode fillMetEDM  (const std::unique_ptr<jFEXTOB>& internalTob, SG::WriteHandle< xAOD::jFexMETRoIContainer   > &jContainer) const;
        
   };
   
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXTOB.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXTOB.h
index e4574fa291b5b7d81b68d96e6516e710995be7a4..71b2e2e338d5a2c9974dfa1d8753220c507ac208 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXTOB.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXTOB.h
@@ -21,20 +21,21 @@ namespace LVL1 {
     jFEXTOB();
     ~jFEXTOB() {};
     
-    void initialize(uint8_t , uint8_t , uint32_t , uint , uint );
+    void initialize(uint8_t , uint8_t , uint32_t , uint , uint , int = -1 );
     
-    void setFpga(uint8_t  x){m_fpga = x;};
-    void setjFex(uint8_t  x){m_jfex = x;};
-    void setWord(uint32_t x){m_word = x;};
-    void setRes (uint     x){m_res  = x;};
-    void setTTID(uint     x){m_ttid = x;};
-    
-    uint8_t  getFpga(){return m_fpga;};
-    uint8_t  getjFex(){return m_jfex;};
-    uint32_t getWord(){return m_word;};
-    uint     getRes() {return m_res; };
-    uint     getTTID(){return m_ttid;};
+    void setFpga(uint8_t  x){m_fpga   = x;};
+    void setjFex(uint8_t  x){m_jfex   = x;};
+    void setWord(uint32_t x){m_word   = x;};
+    void setRes (uint     x){m_res    = x;};
+    void setTTID(uint     x){m_ttid   = x;};
+    void setSeedEt(int    x){m_seedEt = x;};
     
+    uint8_t  getFpga()  {return m_fpga;};
+    uint8_t  getjFex()  {return m_jfex;};
+    uint32_t getWord()  {return m_word;};
+    uint     getRes()   {return m_res; };
+    uint     getTTID()  {return m_ttid;};
+    int      getSeedEt(){return m_seedEt;};
 
   private:
     uint8_t  m_fpga;
@@ -42,6 +43,7 @@ namespace LVL1 {
     uint32_t m_word;
     uint     m_res;
     uint     m_ttid;
+    int      m_seedEt;
     
 
   };
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXFPGA.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXFPGA.cxx
index a7ebd12c4f19e2635f9cff6c2c1a1776f66466d6..fbe209534259d96ca45ee64710c1d153baf2dea6 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXFPGA.cxx
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXFPGA.cxx
@@ -248,6 +248,7 @@ StatusCode jFEXFPGA::execute(jFEXOutputCollection* inputOutputCollection, const
     
     int srJet_seedThresholdMeV = thr_jJ.seedThresholdMeV(m_jfex_string[m_jfexid]); //jFEX internal granularity, i.e., 25 MeV/count
     
+    
     //Central region algorithms
     if(m_jfexid > 0 && m_jfexid < 5) {
         m_jFEXSmallRJetAlgoTool->setFPGAEnergy(m_map_Etvalues_FPGA);
@@ -305,18 +306,20 @@ StatusCode jFEXFPGA::execute(jFEXOutputCollection* inputOutputCollection, const
                     //getting the energies
                     int SRj_Et = m_jFEXSmallRJetAlgoTool->getSmallClusterET();
                     int LRj_Et = m_jFEXLargeRJetAlgoTool->getLargeClusterET(SRj_Et,m_jFEXLargeRJetAlgoTool->getRingET());
+                    int seed_Et = m_jFEXSmallRJetAlgoTool->getSeedET();
                     
                     bool SRj_Sat = m_jFEXSmallRJetAlgoTool->getSRjetSat();
                     bool LRj_Sat = SRj_Sat || m_jFEXLargeRJetAlgoTool->getLRjetSat();
                     
                     int meta_LM = meta;
                     int mphi_LM = mphi;
-
+                    
+                    
                     //Creating SR TOB
                     uint32_t SRJet_tobword = m_IjFEXFormTOBsTool->formSRJetTOB(m_jfexid, mphi_LM, meta_LM, SRj_Et, SRj_Sat, thr_jJ.resolutionMeV(), thr_jJ.ptMinToTopoMeV(m_jfex_string[m_jfexid]), jetCalibrationParameters);
                     
                     std::unique_ptr<jFEXTOB> jJ_tob = std::make_unique<jFEXTOB>(); 
-                    jJ_tob->initialize(m_id,m_jfexid,SRJet_tobword,thr_jJ.resolutionMeV(),m_jTowersIDs_Thin[mphi_LM][meta_LM]);              
+                    jJ_tob->initialize(m_id,m_jfexid,SRJet_tobword,thr_jJ.resolutionMeV(),m_jTowersIDs_Thin[mphi_LM][meta_LM],seed_Et);              
                     if ( SRJet_tobword != 0 ){
                         m_SRJet_tobwords.push_back(std::move(jJ_tob));
                     } 
@@ -325,7 +328,7 @@ StatusCode jFEXFPGA::execute(jFEXOutputCollection* inputOutputCollection, const
                     uint32_t LRJet_tobword = m_IjFEXFormTOBsTool->formLRJetTOB(m_jfexid, mphi_LM, meta_LM, LRj_Et, LRj_Sat, thr_jLJ.resolutionMeV(), thr_jLJ.ptMinToTopoMeV(m_jfex_string[m_jfexid]));
 
                     std::unique_ptr<jFEXTOB> jLJ_tob = std::make_unique<jFEXTOB>(); 
-                    jLJ_tob->initialize(m_id,m_jfexid,LRJet_tobword,thr_jLJ.resolutionMeV(),m_jTowersIDs_Thin[mphi_LM][meta_LM]);              
+                    jLJ_tob->initialize(m_id,m_jfexid,LRJet_tobword,thr_jLJ.resolutionMeV(),m_jTowersIDs_Thin[mphi_LM][meta_LM],seed_Et);              
                     if ( LRJet_tobword != 0 ) m_LRJet_tobwords.push_back(std::move(jLJ_tob));                    
                     
                 }
@@ -374,13 +377,14 @@ StatusCode jFEXFPGA::execute(jFEXOutputCollection* inputOutputCollection, const
             int ieta = FCALJets.getCentreLocalTTEta();
             m_SRJetET = FCALJets.getSeedET() + FCALJets.getFirstEnergyRingET();
             m_LRJetET = m_SRJetET + FCALJets.getSecondEnergyRingET();
+            int seedET = FCALJets.getSeedET();
             
             bool SRJ_sat = FCALJets.getSRjetSat();
             
             uint32_t SRFCAL_Jet_tobword = m_IjFEXFormTOBsTool->formSRJetTOB(m_jfexid, iphi, ieta, m_SRJetET, SRJ_sat, thr_jJ.resolutionMeV(), thr_jJ.ptMinToTopoMeV(m_jfex_string[m_jfexid]), jetCalibrationParameters);
             
             std::unique_ptr<jFEXTOB> jJ_tob = std::make_unique<jFEXTOB>(); 
-            jJ_tob->initialize(m_id,m_jfexid,SRFCAL_Jet_tobword,thr_jJ.resolutionMeV(),TTID);   
+            jJ_tob->initialize(m_id,m_jfexid,SRFCAL_Jet_tobword,thr_jJ.resolutionMeV(),TTID,seedET);   
             
             if ( SRFCAL_Jet_tobword != 0 ){
                 m_SRJet_tobwords.push_back(std::move(jJ_tob));
@@ -568,6 +572,7 @@ std::vector <std::unique_ptr<jFEXTOB>> jFEXFPGA::getLargeRJetTOBs()
 
 }
 
+
   std::vector <std::vector <uint32_t>> jFEXFPGA::getFwdElTOBs()
   {
     auto tobsSort = m_FwdEl_tobwords;
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXSmallRJetAlgo.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXSmallRJetAlgo.cxx
index 07dd6a185edab00c3e1bd02faa8025693176037b..26b41f6479eec404a702b6e3495a9899294a06b2 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXSmallRJetAlgo.cxx
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXSmallRJetAlgo.cxx
@@ -148,6 +148,11 @@ bool LVL1::jFEXSmallRJetAlgo::isSeedLocalMaxima(int seedThreshold) {
     return false;
 }
 
+unsigned int LVL1::jFEXSmallRJetAlgo::getSeedET() const {
+  // only valid after calling buildSeeds() !
+  return m_jFEXalgoSearchWindowSeedET[2][2];
+}
+
 
 //in this clustering func, the central TT in jet is the parameters
 unsigned int LVL1::jFEXSmallRJetAlgo::getSmallClusterET() const {
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXSysSim.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXSysSim.cxx
index 827bd2b14d09eb64bbb18fb92ef2b6d8fcad1bf1..c8bbc7a8ee3d9a1fd3ec29aa5ab6ccb357e39e67 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXSysSim.cxx
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXSysSim.cxx
@@ -85,6 +85,10 @@ namespace LVL1 {
     ATH_CHECK(m_xTobOutKey_jTau.initialize());
     ATH_CHECK(m_xTobOutKey_jEM.initialize());    
     
+    // Decorations
+    ATH_CHECK(m_TobDecorKey_jJ_seedET.initialize());    
+    ATH_CHECK(m_xTobDecorKey_jJ_seedET.initialize());    
+    
     ATH_CHECK(m_l1MenuKey.initialize());
 
     return StatusCode::SUCCESS;
@@ -911,10 +915,23 @@ namespace LVL1 {
     std::unique_ptr< xAOD::jFexSRJetRoIAuxContainer > tobAuxContainer_jJ = std::make_unique<xAOD::jFexSRJetRoIAuxContainer> ();
     tobContainer_jJ->setStore(tobAuxContainer_jJ.get());
     
+    SG::WriteDecorHandle<xAOD::jFexSRJetRoIContainer, int > tobDec_jJ_seedET (m_TobDecorKey_jJ_seedET);
+    
     auto xtobContainer_jJ = std::make_unique<xAOD::jFexSRJetRoIContainer> ();
     std::unique_ptr< xAOD::jFexSRJetRoIAuxContainer > xtobAuxContainer_jJ = std::make_unique<xAOD::jFexSRJetRoIAuxContainer> ();
     xtobContainer_jJ->setStore(xtobAuxContainer_jJ.get());
     
+    SG::WriteDecorHandle<xAOD::jFexSRJetRoIContainer, int > xtobDec_jJ_seedET (m_xTobDecorKey_jJ_seedET);
+
+    
+    SG::WriteHandle<xAOD::jFexSRJetRoIContainer> output_Tob_jJ(m_TobOutKey_jJ/*, ctx*/);
+    ATH_MSG_DEBUG("  write: " << output_Tob_jJ.key() << " = " << "..." );
+    ATH_CHECK(output_Tob_jJ.record(std::move(tobContainer_jJ),std::move(tobAuxContainer_jJ)));
+    
+    SG::WriteHandle<xAOD::jFexSRJetRoIContainer> output_xTob_jJ(m_xTobOutKey_jJ/*, ctx*/);
+    ATH_MSG_DEBUG("  write: " << output_xTob_jJ.key() << " = " << "..." );
+    ATH_CHECK(output_xTob_jJ.record(std::move(xtobContainer_jJ),std::move(xtobAuxContainer_jJ)));
+    
     // iterate over all SRJEt Tobs and fill EDM with them   m_allSmallRJetTobs
     for( auto const& [jfex, fpga] : m_allSmallRJetTobs ) {
         for(auto const & tobs: fpga) {
@@ -930,22 +947,15 @@ namespace LVL1 {
                 // Just sending 7 SRjets to L1Topo and HLT chain
                 if(it<7){
                     istob = 1;
-                    ATH_CHECK(fillSRJetEDM(tobs.at(it)->getjFex(),tobs.at(it)->getFpga(),tobs.at(it)->getWord(),istob,tobs.at(it)->getRes(), eta, phi, tobContainer_jJ)); 
+                    ATH_CHECK(fillSRJetEDM(tobs.at(it), istob, eta, phi, output_Tob_jJ)); 
+                    tobDec_jJ_seedET( *(output_Tob_jJ->back()) ) = tobs.at(it)->getSeedEt();
                 }
-                ATH_CHECK(fillSRJetEDM(tobs.at(it)->getjFex(),tobs.at(it)->getFpga(),tobs.at(it)->getWord(),istob,tobs.at(it)->getRes(), eta, phi, xtobContainer_jJ));
-                
+                ATH_CHECK(fillSRJetEDM(tobs.at(it), istob, eta, phi, output_xTob_jJ));
+                xtobDec_jJ_seedET( *(output_xTob_jJ->back()) ) = tobs.at(it)->getSeedEt();
             }
         }
     }
     
-    SG::WriteHandle<xAOD::jFexSRJetRoIContainer_v1> output_Tob_jJ(m_TobOutKey_jJ/*, ctx*/);
-    ATH_MSG_DEBUG("  write: " << output_Tob_jJ.key() << " = " << "..." );
-    ATH_CHECK(output_Tob_jJ.record(std::move(tobContainer_jJ),std::move(tobAuxContainer_jJ)));
-    
-    SG::WriteHandle<xAOD::jFexSRJetRoIContainer_v1> output_xTob_jJ(m_xTobOutKey_jJ/*, ctx*/);
-    ATH_MSG_DEBUG("  write: " << output_xTob_jJ.key() << " = " << "..." );
-    ATH_CHECK(output_xTob_jJ.record(std::move(xtobContainer_jJ),std::move(xtobAuxContainer_jJ)));
-
     //---LRJet EDM
     auto tobContainer_jLJ = std::make_unique<xAOD::jFexLRJetRoIContainer> ();
     std::unique_ptr< xAOD::jFexLRJetRoIAuxContainer > tobAuxContainer_jLJ = std::make_unique<xAOD::jFexLRJetRoIAuxContainer> ();
@@ -955,6 +965,15 @@ namespace LVL1 {
     std::unique_ptr< xAOD::jFexLRJetRoIAuxContainer > xtobAuxContainer_jLJ = std::make_unique<xAOD::jFexLRJetRoIAuxContainer> ();
     xtobContainer_jLJ->setStore(xtobAuxContainer_jLJ.get());
     
+
+    SG::WriteHandle<xAOD::jFexLRJetRoIContainer_v1> output_Tob_jLJ(m_TobOutKey_jLJ/*, ctx*/);
+    ATH_MSG_DEBUG("  write: " << output_Tob_jLJ.key() << " = " << "..." );
+    ATH_CHECK(output_Tob_jLJ.record(std::move(tobContainer_jLJ),std::move(tobAuxContainer_jLJ)));
+
+    SG::WriteHandle<xAOD::jFexLRJetRoIContainer_v1> output_xTob_jLJ(m_xTobOutKey_jLJ/*, ctx*/);
+    ATH_MSG_DEBUG("  write: " << output_xTob_jLJ.key() << " = " << "..." );
+    ATH_CHECK(output_xTob_jLJ.record(std::move(xtobContainer_jLJ),std::move(xtobAuxContainer_jLJ)));
+    
     // iterate over all LRJEt Tobs and fill EDM with them
     for(auto const& [jfex, fpga] : m_allLargeRJetTobs ) {
         for(auto const& tobs: fpga) {
@@ -970,21 +989,12 @@ namespace LVL1 {
                 // Just sending 1 LRjets to L1Topo and HLT chain
                 if(it<1){
                     istob=1;
-                   ATH_CHECK(fillLRJetEDM(tobs.at(it)->getjFex(),tobs.at(it)->getFpga(),tobs.at(it)->getWord(),istob,tobs.at(it)->getRes(), eta, phi, tobContainer_jLJ)); 
+                   ATH_CHECK(fillLRJetEDM(tobs.at(it), istob, eta, phi, output_Tob_jLJ)); 
                 }
-                ATH_CHECK(fillLRJetEDM(tobs.at(it)->getjFex(),tobs.at(it)->getFpga(),tobs.at(it)->getWord(),istob,tobs.at(it)->getRes(), eta, phi, xtobContainer_jLJ));
+                ATH_CHECK(fillLRJetEDM(tobs.at(it), istob, eta, phi, output_xTob_jLJ));
             }
         }
     }
-
-    SG::WriteHandle<xAOD::jFexLRJetRoIContainer_v1> output_Tob_jLJ(m_TobOutKey_jLJ/*, ctx*/);
-    ATH_MSG_DEBUG("  write: " << output_Tob_jLJ.key() << " = " << "..." );
-    ATH_CHECK(output_Tob_jLJ.record(std::move(tobContainer_jLJ),std::move(tobAuxContainer_jLJ)));
-
-    SG::WriteHandle<xAOD::jFexLRJetRoIContainer_v1> output_xTob_jLJ(m_xTobOutKey_jLJ/*, ctx*/);
-    ATH_MSG_DEBUG("  write: " << output_xTob_jLJ.key() << " = " << "..." );
-    ATH_CHECK(output_xTob_jLJ.record(std::move(xtobContainer_jLJ),std::move(xtobAuxContainer_jLJ)));
-    
     //---Tau EDM
     auto tobContainer_jTau = std::make_unique<xAOD::jFexTauRoIContainer> ();
     std::unique_ptr< xAOD::jFexTauRoIAuxContainer > tobAuxContainer_jTau = std::make_unique<xAOD::jFexTauRoIAuxContainer> ();
@@ -993,6 +1003,15 @@ namespace LVL1 {
     auto xtobContainer_jTau = std::make_unique<xAOD::jFexTauRoIContainer> ();
     std::unique_ptr< xAOD::jFexTauRoIAuxContainer > xtobAuxContainer_jTau = std::make_unique<xAOD::jFexTauRoIAuxContainer> ();
     xtobContainer_jTau->setStore(xtobAuxContainer_jTau.get());
+    
+    SG::WriteHandle<xAOD::jFexTauRoIContainer_v1> output_Tob_jTau(m_TobOutKey_jTau/*, ctx*/);
+    ATH_MSG_DEBUG("  write: " << output_Tob_jTau.key() << " = " << "..." );
+    ATH_CHECK(output_Tob_jTau.record(std::move(tobContainer_jTau),std::move(tobAuxContainer_jTau)));
+
+    SG::WriteHandle<xAOD::jFexTauRoIContainer_v1> output_xTob_jTau(m_xTobOutKey_jTau/*, ctx*/);
+    ATH_MSG_DEBUG("  write: " << output_xTob_jTau.key() << " = " << "..." );
+    ATH_CHECK(output_xTob_jTau.record(std::move(xtobContainer_jTau),std::move(xtobAuxContainer_jTau)));
+        
     //iterate over all Tau Tobs and fill EDM with 
     for( auto const& [jfex, fpga] : m_alltauTobs ) {
         for(auto const& tobs : fpga){
@@ -1008,22 +1027,14 @@ namespace LVL1 {
                 // Just sending 6 Taus to L1Topo and HLT chain
                 if(it<6){
                     istob=1;
-                    ATH_CHECK(fillTauEDM(tobs.at(it)->getjFex() ,tobs.at(it)->getFpga() ,tobs.at(it)->getWord() ,istob ,tobs.at(it)->getRes(), eta, phi, tobContainer_jTau)); 
+                    ATH_CHECK(fillTauEDM(tobs.at(it), istob, eta, phi, output_Tob_jTau)); 
                 }
-                ATH_CHECK(fillTauEDM(tobs.at(it)->getjFex() ,tobs.at(it)->getFpga() ,tobs.at(it)->getWord() ,istob ,tobs.at(it)->getRes(), eta, phi, xtobContainer_jTau));           
+                ATH_CHECK(fillTauEDM(tobs.at(it), istob, eta, phi, output_xTob_jTau));           
             }
         }
 
     }
 
-    SG::WriteHandle<xAOD::jFexTauRoIContainer_v1> output_Tob_jTau(m_TobOutKey_jTau/*, ctx*/);
-    ATH_MSG_DEBUG("  write: " << output_Tob_jTau.key() << " = " << "..." );
-    ATH_CHECK(output_Tob_jTau.record(std::move(tobContainer_jTau),std::move(tobAuxContainer_jTau)));
-
-    SG::WriteHandle<xAOD::jFexTauRoIContainer_v1> output_xTob_jTau(m_xTobOutKey_jTau/*, ctx*/);
-    ATH_MSG_DEBUG("  write: " << output_xTob_jTau.key() << " = " << "..." );
-    ATH_CHECK(output_xTob_jTau.record(std::move(xtobContainer_jTau),std::move(xtobAuxContainer_jTau)));
-    
     //---Forward Elec EDM
     auto tobContainer_jEM = std::make_unique<xAOD::jFexFwdElRoIContainer> ();
     std::unique_ptr< xAOD::jFexFwdElRoIAuxContainer > tobAuxContainer_jEM = std::make_unique<xAOD::jFexFwdElRoIAuxContainer> ();
@@ -1033,6 +1044,14 @@ namespace LVL1 {
     std::unique_ptr< xAOD::jFexFwdElRoIAuxContainer > xtobAuxContainer_jEM = std::make_unique<xAOD::jFexFwdElRoIAuxContainer> ();
     xtobContainer_jEM->setStore(xtobAuxContainer_jEM.get());
 
+    SG::WriteHandle<xAOD::jFexFwdElRoIContainer_v1> output_Tob_jEM(m_TobOutKey_jEM/*, ctx*/);
+    ATH_MSG_DEBUG("  write: " << output_Tob_jEM.key() << " = " << "..." );
+    ATH_CHECK(output_Tob_jEM.record(std::move(tobContainer_jEM),std::move(tobAuxContainer_jEM)));
+
+    SG::WriteHandle<xAOD::jFexFwdElRoIContainer_v1> output_xTob_jEM(m_xTobOutKey_jEM/*, ctx*/);
+    ATH_MSG_DEBUG("  write: " << output_xTob_jEM.key() << " = " << "..." );
+    ATH_CHECK(output_xTob_jEM.record(std::move(xtobContainer_jEM),std::move(xtobAuxContainer_jEM)));
+    
     //iterate over all Forward Elec Tobs and fill EDM 
     for( auto const& [jfex, MODULE_tobs] : m_allfwdElTobs ) {
         const int fpga_map[4]={0,1,3,2}; // No FPGA info available in FWD EL TOB
@@ -1053,55 +1072,47 @@ namespace LVL1 {
                 
                 if(it<5){
                     istob=1;
-                    ATH_CHECK(fillFwdElEDM(jfex,fpga_map[fpgaNum], FPGA_tob.at(it).at(0),istob, jFwdElResolution, eta, phi, tobContainer_jEM));
+                    ATH_CHECK(fillFwdElEDM(jfex,fpga_map[fpgaNum], FPGA_tob.at(it).at(0),istob, jFwdElResolution, eta, phi, output_Tob_jEM));
                 }
-                ATH_CHECK(fillFwdElEDM(jfex,fpga_map[fpgaNum], FPGA_tob.at(it).at(0),istob, jFwdElResolution, eta, phi, xtobContainer_jEM));
+                ATH_CHECK(fillFwdElEDM(jfex,fpga_map[fpgaNum], FPGA_tob.at(it).at(0),istob, jFwdElResolution, eta, phi, output_xTob_jEM));
             }
             fpgaNum++;
         }
 
     }
 
-    SG::WriteHandle<xAOD::jFexFwdElRoIContainer_v1> output_Tob_jEM(m_TobOutKey_jEM/*, ctx*/);
-    ATH_MSG_DEBUG("  write: " << output_Tob_jEM.key() << " = " << "..." );
-    ATH_CHECK(output_Tob_jEM.record(std::move(tobContainer_jEM),std::move(tobAuxContainer_jEM)));
-
-    SG::WriteHandle<xAOD::jFexFwdElRoIContainer_v1> output_xTob_jEM(m_xTobOutKey_jEM/*, ctx*/);
-    ATH_MSG_DEBUG("  write: " << output_xTob_jEM.key() << " = " << "..." );
-    ATH_CHECK(output_xTob_jEM.record(std::move(xtobContainer_jEM),std::move(xtobAuxContainer_jEM)));
-    
     //---SumET EDM
     auto tobContainer_jTE = std::make_unique<xAOD::jFexSumETRoIContainer> ();
     std::unique_ptr< xAOD::jFexSumETRoIAuxContainer > tobAuxContainer_jTE = std::make_unique<xAOD::jFexSumETRoIAuxContainer> ();
     tobContainer_jTE->setStore(tobAuxContainer_jTE.get());    
     
+    SG::WriteHandle<xAOD::jFexSumETRoIContainer_v1> output_Tob_jTE(m_TobOutKey_jTE/*, ctx*/);
+    ATH_MSG_DEBUG("  write: " << output_Tob_jTE.key() << " = " << "..." );
+    ATH_CHECK(output_Tob_jTE.record(std::move(tobContainer_jTE),std::move(tobAuxContainer_jTE)));    
+    
     for( auto const& [jfex, tobs] : m_allsumEtTobs ) {
         
         for(auto const& t : tobs) {
-            ATH_CHECK(fillSumEtEDM(t->getjFex(),t->getFpga(),t->getWord(),t->getRes(),tobContainer_jTE));
+            ATH_CHECK(fillSumEtEDM(t, output_Tob_jTE));
         }
     } 
 
-    SG::WriteHandle<xAOD::jFexSumETRoIContainer_v1> output_Tob_jTE(m_TobOutKey_jTE/*, ctx*/);
-    ATH_MSG_DEBUG("  write: " << output_Tob_jTE.key() << " = " << "..." );
-    ATH_CHECK(output_Tob_jTE.record(std::move(tobContainer_jTE),std::move(tobAuxContainer_jTE)));    
-    
     //---MET EDM 
     auto tobContainer_jXE = std::make_unique<xAOD::jFexMETRoIContainer> ();
     std::unique_ptr< xAOD::jFexMETRoIAuxContainer > tobAuxContainer_jXE = std::make_unique<xAOD::jFexMETRoIAuxContainer> ();
     tobContainer_jXE->setStore(tobAuxContainer_jXE.get());    
 
+    SG::WriteHandle<xAOD::jFexMETRoIContainer_v1> output_Tob_jXE(m_TobOutKey_jXE/*, ctx*/);
+    ATH_MSG_DEBUG("  write: " << output_Tob_jXE.key() << " = " << "..." );
+    ATH_CHECK(output_Tob_jXE.record(std::move(tobContainer_jXE),std::move(tobAuxContainer_jXE)));   
+
     for( auto const& [jfex, tobs] : m_allMetTobs ) {
          
         for(auto const& t : tobs) {
-            ATH_CHECK(fillMetEDM(t->getjFex(),t->getFpga(),t->getWord(),t->getRes(),tobContainer_jXE));
+            ATH_CHECK(fillMetEDM(t, output_Tob_jXE));
         }       
     }     
 
-    SG::WriteHandle<xAOD::jFexMETRoIContainer_v1> output_Tob_jXE(m_TobOutKey_jXE/*, ctx*/);
-    ATH_MSG_DEBUG("  write: " << output_Tob_jXE.key() << " = " << "..." );
-    ATH_CHECK(output_Tob_jXE.record(std::move(tobContainer_jXE),std::move(tobAuxContainer_jXE)));   
-
 
 
     //Send TOBs to bytestream?
@@ -1114,32 +1125,32 @@ namespace LVL1 {
   }
 
 
-    StatusCode jFEXSysSim::fillSRJetEDM(uint8_t jFexNum, uint8_t fpgaNumber, uint32_t tobWord, char istob, int resolution, float_t eta, float_t phi, std::unique_ptr< xAOD::jFexSRJetRoIContainer > &jContainer) const {
+    StatusCode jFEXSysSim::fillSRJetEDM(const std::unique_ptr<jFEXTOB>& internalTob, char istob, float_t eta, float_t phi, SG::WriteHandle<xAOD::jFexSRJetRoIContainer_v1> &jContainer) const {
 
         xAOD::jFexSRJetRoI* my_EDM = new xAOD::jFexSRJetRoI();
         jContainer->push_back( my_EDM );
 
-        my_EDM->initialize(jFexNum, fpgaNumber, tobWord ,istob , resolution, eta, phi);
+        my_EDM->initialize(internalTob->getjFex(), internalTob->getFpga(), internalTob->getWord(), istob, internalTob->getRes(), eta, phi);
 
         ATH_MSG_DEBUG(" setting SRJet jFEX Number:  " << +my_EDM->jFexNumber() << " et: " << my_EDM->et() << " eta: " << my_EDM->eta() <<" / "<< eta <<  " phi: " << my_EDM->phi()<<" / "<< phi  );
-
+        
         return StatusCode::SUCCESS;
     }
       
       
-    StatusCode jFEXSysSim::fillTauEDM(uint8_t jFexNum,uint8_t fpgaNumber, uint32_t tobWord, char istob, int resolution, float_t eta, float_t phi, std::unique_ptr< xAOD::jFexTauRoIContainer > &jContainer) const {
+    StatusCode jFEXSysSim::fillTauEDM(const std::unique_ptr<jFEXTOB>& internalTob, char istob, float_t eta, float_t phi, SG::WriteHandle< xAOD::jFexTauRoIContainer > &jContainer) const {
 
         xAOD::jFexTauRoI* my_EDM = new xAOD::jFexTauRoI();
         jContainer->push_back( my_EDM );
 
-        my_EDM->initialize(jFexNum, fpgaNumber, tobWord ,istob , resolution, eta, phi);
+        my_EDM->initialize(internalTob->getjFex(), internalTob->getFpga(), internalTob->getWord(), istob, internalTob->getRes(), eta, phi);
 
         ATH_MSG_DEBUG(" setting tau jFEX Number:  " << +my_EDM->jFexNumber() << " et: " << my_EDM->et() << " eta: " << my_EDM->eta() <<" / "<< eta <<  " phi: " << my_EDM->phi()<<" / "<< phi  );
 
         return StatusCode::SUCCESS;
     }
 
-  StatusCode jFEXSysSim::fillFwdElEDM(uint8_t jFexNum,uint8_t fpgaNumber, uint32_t tobWord, char istob, int resolution, float_t eta, float_t phi, std::unique_ptr< xAOD::jFexFwdElRoIContainer > &jContainer) const {
+  StatusCode jFEXSysSim::fillFwdElEDM(uint8_t jFexNum,uint8_t fpgaNumber, uint32_t tobWord, char istob, int resolution, float_t eta, float_t phi, SG::WriteHandle< xAOD::jFexFwdElRoIContainer > &jContainer) const {
 
     xAOD::jFexFwdElRoI* my_EDM = new xAOD::jFexFwdElRoI();
     jContainer->push_back( my_EDM );
@@ -1151,36 +1162,36 @@ namespace LVL1 {
     return StatusCode::SUCCESS;
   }
 
-    StatusCode jFEXSysSim::fillLRJetEDM(uint8_t jFexNum, uint8_t fpgaNumber, uint32_t tobWord, char istob, int resolution, float_t eta, float_t phi, std::unique_ptr< xAOD::jFexLRJetRoIContainer > &jContainer) const {
+    StatusCode jFEXSysSim::fillLRJetEDM(const std::unique_ptr<jFEXTOB>& internalTob, char istob, float_t eta, float_t phi, SG::WriteHandle< xAOD::jFexLRJetRoIContainer > &jContainer) const {
 
         xAOD::jFexLRJetRoI* my_EDM = new xAOD::jFexLRJetRoI();
         jContainer->push_back( my_EDM );
 
-        my_EDM->initialize(jFexNum, fpgaNumber, tobWord ,istob , resolution, eta, phi);
+        my_EDM->initialize(internalTob->getjFex(), internalTob->getFpga(), internalTob->getWord(), istob, internalTob->getRes(), eta, phi);
 
         ATH_MSG_DEBUG(" setting LRJet jFEX Number:  " << +my_EDM->jFexNumber() << " et: " << my_EDM->et() << " eta: " << my_EDM->eta() <<" / "<< eta <<  " phi: " << my_EDM->phi()<<" / "<< phi  );
 
         return StatusCode::SUCCESS;
     }
 
-    StatusCode jFEXSysSim::fillSumEtEDM(uint8_t jFexNum,uint8_t fpgaNumber, uint32_t tobWord, int resolution, std::unique_ptr< xAOD::jFexSumETRoIContainer > &jContainer) const {
+    StatusCode jFEXSysSim::fillSumEtEDM(const std::unique_ptr<jFEXTOB>& internalTob, SG::WriteHandle< xAOD::jFexSumETRoIContainer > &jContainer) const {
 
         xAOD::jFexSumETRoI* my_EDM = new xAOD::jFexSumETRoI();
         jContainer->push_back( my_EDM );
         
-        my_EDM->initialize(jFexNum, fpgaNumber, tobWord, resolution);
+        my_EDM->initialize(internalTob->getjFex(), internalTob->getFpga(), internalTob->getWord(), internalTob->getRes());
         
         ATH_MSG_DEBUG(" setting SumET jFEX Number:  " << +my_EDM->jFexNumber() << " Et_up: " << my_EDM->tobEt_upper() << " Et_down: " << my_EDM->tobEt_lower() <<  " sat_up: " << my_EDM->tobSat_upper()<<  " sat_low: " << my_EDM->tobSat_lower());
         
         return StatusCode::SUCCESS;
     }
 
-    StatusCode jFEXSysSim::fillMetEDM(uint8_t jFexNum,uint8_t fpgaNumber, uint32_t tobWord, int resolution, std::unique_ptr< xAOD::jFexMETRoIContainer > &jContainer) const {
+    StatusCode jFEXSysSim::fillMetEDM(const std::unique_ptr<jFEXTOB>& internalTob, SG::WriteHandle< xAOD::jFexMETRoIContainer > &jContainer) const {
 
         xAOD::jFexMETRoI* my_EDM = new xAOD::jFexMETRoI();
         jContainer->push_back( my_EDM );
 
-        my_EDM->initialize(jFexNum, fpgaNumber, tobWord, resolution);
+        my_EDM->initialize(internalTob->getjFex(), internalTob->getFpga(), internalTob->getWord(), internalTob->getRes());
 
         ATH_MSG_DEBUG(" setting MET jFEX Number:  " << +my_EDM->jFexNumber() << " Et_x: " << my_EDM->tobEx() << " Et_y: " << my_EDM->tobEy() <<  " sat: " << my_EDM->tobSat()<<  " res: " << my_EDM->tobRes() );
         
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXTOB.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXTOB.cxx
index 247f4c6f1a526e269bdc09f3ae92068c340a4cb8..ace94c54f2f5d6f2d2293b475ad5e40e4f881895 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXTOB.cxx
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXTOB.cxx
@@ -17,17 +17,19 @@ jFEXTOB::jFEXTOB():
   m_jfex{0},
   m_word{0},
   m_res{0},
-  m_ttid{0}
+  m_ttid{0},
+  m_seedEt{0}
 {}
 
 
-void jFEXTOB::initialize(uint8_t fpga, uint8_t jfex, uint32_t word, uint res, uint ttid )
+void jFEXTOB::initialize(uint8_t fpga, uint8_t jfex, uint32_t word, uint res, uint ttid, int seedEt )
 {
-    setFpga (fpga);
-    setjFex (jfex);
-    setWord (word);
-    setRes  (res);
-    setTTID (ttid);
+    setFpga   (fpga);
+    setjFex   (jfex);
+    setWord   (word);
+    setRes    (res);
+    setTTID   (ttid);
+    setSeedEt (seedEt);
 
 }
     
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXForwardJetsAlgo.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXForwardJetsAlgo.h
index d7318b8917563ff1746a2ff9bfa440422124fe1a..d4d6546d7a37d34f0d0ec87c6cef3cf8a34699f0 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXForwardJetsAlgo.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXForwardJetsAlgo.h
@@ -32,6 +32,8 @@ namespace LVL1{
       virtual std::unordered_map<int, jFEXForwardJetsInfo> FcalJetsTowerIDLists(int seedThreshold) =0;
       virtual std::unordered_map<int, jFEXForwardJetsInfo> calculateJetETs(int seedThreshold) =0;
       virtual void setFPGAEnergy(std::unordered_map<int,std::vector<int> > et_map)   =0;
+      
+      virtual int SumEtSeed(unsigned int TTID) = 0;
 
    private:
 
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXSmallRJetAlgo.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXSmallRJetAlgo.h
index 90d22f8c1de4398b2bef09a685b844f0a585d8cb..559e645b0ba4f7d6500c16a6eb7aab418bcaeda7 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXSmallRJetAlgo.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXSmallRJetAlgo.h
@@ -26,6 +26,7 @@ namespace LVL1{
       virtual bool isSeedLocalMaxima(int seedThreshold) = 0;
       virtual void buildSeeds() = 0;
       virtual unsigned int getTTowerET(unsigned int TTID ) const = 0;
+      virtual unsigned int getSeedET() const = 0;
       virtual unsigned int getSmallClusterET() const = 0;
       virtual unsigned int getSmallETRing() const = 0;
       virtual unsigned int getTTIDcentre() const = 0;
diff --git a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
index 31e103d10d06e02533a2e84959ca5eb6a8ff0624..cf434d7040f57e78a02ae7a043151550da82a21b 100644
--- a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
+++ b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
@@ -18133,6 +18133,19 @@ HLT_mu14_ivarloose_tau35_mediumRNN_tracktwoMVA_03dRAB_L1cTAU30M_3DR28-MU8F-eTAU3
     2: 10
     3: 10
     4: 3
+HLT_mu14_ivarloose_tau35_mediumRNN_tracktwoMVA_03dRAB_L1cTAU30M_3DR30-MU8F-eTAU30:
+  eventCount: 0
+  stepCounts:
+    0: 6
+    1: 5
+    2: 5
+    3: 5
+  stepFeatures:
+    0: 16
+    1: 15
+    2: 12
+    3: 12
+    4: 4
 HLT_mu14_ivarloose_tau35_mediumRNN_tracktwoMVA_03dRAB_L1cTAU30M_3DR99-MU8F-eTAU30:
   eventCount: 0
   stepCounts:
diff --git a/Trigger/TrigValidation/TrigP1Test/share/ref_v1Dev_decodeBS_build.ref b/Trigger/TrigValidation/TrigP1Test/share/ref_v1Dev_decodeBS_build.ref
index 71bd7cff0e5e01577455966d07e04a957ccde2a9..bc1c198d9e4ee8032064f0877b5261149f720f31 100644
--- a/Trigger/TrigValidation/TrigP1Test/share/ref_v1Dev_decodeBS_build.ref
+++ b/Trigger/TrigValidation/TrigP1Test/share/ref_v1Dev_decodeBS_build.ref
@@ -10458,6 +10458,8 @@ HLT_mu14_ivarloose_tau35_mediumRNN_tracktwoMVA_03dRAB_L1MU8F_cTAU30M:
     0: 1
 HLT_mu14_ivarloose_tau35_mediumRNN_tracktwoMVA_03dRAB_L1cTAU30M_3DR28-MU8F-eTAU30:
   eventCount: 0
+HLT_mu14_ivarloose_tau35_mediumRNN_tracktwoMVA_03dRAB_L1cTAU30M_3DR30-MU8F-eTAU30:
+  eventCount: 0
 HLT_mu14_ivarloose_tau35_mediumRNN_tracktwoMVA_03dRAB_L1cTAU30M_3DR99-MU8F-eTAU30:
   eventCount: 0
   stepFeatures:
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLT/Menu/Dev_pp_run3_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLT/Menu/Dev_pp_run3_v1.py
index e2340bc756224f827947e3a339f4118f24b9bea6..f8c6ea116a9a9093847540cdb61d3ca76a8731c6 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLT/Menu/Dev_pp_run3_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLT/Menu/Dev_pp_run3_v1.py
@@ -883,6 +883,7 @@ def getDevSignatures():
 
         #ATR-30179
         ChainProp(name='HLT_mu14_ivarloose_tau35_mediumRNN_tracktwoMVA_03dRAB_L1cTAU30M_3DR99-MU8F-eTAU30', l1SeedThresholds=['MU8F','cTAU30M'], stream=[PhysicsStream], groups=SupportPhIGroup+MuonTauGroup),
+        ChainProp(name='HLT_mu14_ivarloose_tau35_mediumRNN_tracktwoMVA_03dRAB_L1cTAU30M_3DR30-MU8F-eTAU30', l1SeedThresholds=['MU8F','cTAU30M'], stream=[PhysicsStream], groups=SupportPhIGroup+MuonTauGroup),
         ChainProp(name='HLT_mu14_ivarloose_tau35_mediumRNN_tracktwoMVA_03dRAB_L1cTAU30M_3DR28-MU8F-eTAU30', l1SeedThresholds=['MU8F','cTAU30M'], stream=[PhysicsStream], groups=SupportPhIGroup+MuonTauGroup),
 
     ]
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/L1Menu.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/L1Menu.py
index 7b95135c79c4d6469494df377ba7fed56bcd4fc4..d3093247e1fa4068ad114552a9459b47aed2f114 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/L1Menu.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/L1Menu.py
@@ -50,12 +50,6 @@ class L1Menu(object):
             self.items.menuName = smk_psk_Name["smkName"]
             self.items.pssName  = smk_psk_Name["pskName"]
 
-    @staticmethod
-    def partitioning():
-        first = L1MenuFlags.MenuPartitioning()
-        last = first[1:] + [ Limits.MaxTrigItems ]
-        partitioning = dict( zip([1,2,3],zip(first,last)) )
-        return partitioning
 
     def setBunchGroupSplitting(self, v = True):
         MenuItemsCollection.splitBunchGroups = v
@@ -559,3 +553,13 @@ class L1Menu(object):
                 if thrName not in all_ctpin:
                     raise RuntimeError(
                         f'checkItemsHaveInputs: Threshold {thrName} used by {item.name} is not on a board connected to CTP')
+
+    def checkHFmonitoring(self):
+        requiredItems = [
+            "L1_BCM_2A_FIRSTINTRAIN",
+            "L1_BCM_2C_FIRSTINTRAIN"
+        ]
+        missingItems = [item for item in requiredItems if self.items.items[item].monitorsHF == 0]
+        if missingItems:
+            raise RuntimeError(
+                f'The HF monitoring flags for {", ".join(missingItems)} are missing')
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/L1MenuFlags.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/L1MenuFlags.py
index d751fa8d7636275c9e7d2c4953dfd138f01bf580..02ef0167cb61623679639d16bfe7c25fc017dbab 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/L1MenuFlags.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/L1MenuFlags.py
@@ -41,7 +41,6 @@ class L1MenuFlagsCont(object):
         "CTPVersion"              :  FlagArgs( int, 4,   val_check = lambda x: x in range(5), action = lambda x: Limits.setLimits(x) ),
         "BunchGroupPartitioning"  :  FlagArgs( Iterable, val_check = lambda x: len(list(filter(lambda y: y not in range(16), x)))==0 ),
         "BunchGroupNames"         :  FlagArgs( Iterable, val_check = lambda x: len(list(filter(lambda y: not isinstance(y, str), x)))==0),
-        "MenuPartitioning"        :  FlagArgs( Iterable, val_check = lambda x: len(list(filter(lambda y: y not in range(512), x)))==0 ),
         "items"                   :  FlagArgs( Iterable, val_check = lambda x: len(list(filter(lambda y: not isinstance(y, str), x)))==0),
         "boards"                  :  FlagArgs( OrderedDict, OrderedDict() ),
         "legacyBoards"            :  FlagArgs( OrderedDict, OrderedDict() ),
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ItemDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ItemDef.py
index 4106328314b6070f36a7f1ee335c819f0d3b87e2..96b5503dfe2d46257e1834ab9f0a4f36bb75734c 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ItemDef.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ItemDef.py
@@ -2125,6 +2125,7 @@ class ItemDef:
 
             #ATR-30179
             MenuItem('L1_cTAU30M_3DR99-MU8F-eTAU30').setLogic( d.cTAU30M & d.TOPO_3DR99_MU8Fab_eTAU30ab & physcond)
+            MenuItem('L1_cTAU30M_3DR30-MU8F-eTAU30').setLogic( d.cTAU30M & d.TOPO_3DR30_MU8Fab_eTAU30ab & physcond)
             MenuItem('L1_cTAU30M_3DR28-MU8F-eTAU30').setLogic( d.cTAU30M & d.TOPO_3DR28_MU8Fab_eTAU30ab & physcond)
 
             
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/MonitorDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/MonitorDef.py
index 8fdf72f542d59c5aaec4c4f2a5b8c571fc72a893..0b63933347cc4310bca16a032a7130d9159b8c01 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/MonitorDef.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/MonitorDef.py
@@ -388,17 +388,18 @@ class MonitorDef:
 
         # if any of the HF items are changed CTP and OLC shall be informed (via TrigOps)
         monItemsHF[TBP|TAP|TAV] = [
-            "L1_jJ30",
+            "L1_jJ30",          # beam-induced background measurements
             "L1_MBTS_1", "L1_MBTS_2", "L1_MBTS_1_1",
-            "L1_BCM_Wide", "L1_BCM_2A_FIRSTINTRAIN", "L1_BCM_2C_FIRSTINTRAIN"
+            "L1_BCM_Wide",      # beam-induced background measurements
+            "L1_BCM_2A_FIRSTINTRAIN", "L1_BCM_2C_FIRSTINTRAIN"  # beam-induced background measurements, used for SCT HV ramp
         ]
         # total number of items for HF monitoring doubled from 8 to 16 for HI and pp-ref
         if "HI" in menuName:
             monItemsHF[TBP|TAP|TAV].extend([
-                "L1_ZDC_A", "L1_ZDC_C", "L1_ZDC_A_C", 
-                "L1_ZDC_OR", "L1_ZDC_XOR", 
-                "L1_ZDC_C_VZDC_A", "L1_ZDC_A_VZDC_C", "L1_5ZDC_A_5ZDC_C",
-                "L1_eEM15"
+                "L1_ZDC_A", "L1_ZDC_C", "L1_ZDC_A_C", # luminosity measurements
+                "L1_ZDC_OR", "L1_ZDC_XOR",            # luminosity measurements
+                "L1_ZDC_C_VZDC_A", "L1_ZDC_A_VZDC_C", "L1_5ZDC_A_5ZDC_C", # luminosity measurements
+                "L1_eEM15"      # luminosity measurements
             ])
 
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TopoAlgoDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TopoAlgoDef.py
index 2677cad305524b362364775d2e8425656697c9c7..b4c6689e5fa8def79f670eeda52e3a34cace25e2 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TopoAlgoDef.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TopoAlgoDef.py
@@ -369,6 +369,7 @@ class TopoAlgoDef:
         #Mu+Tau dR cut
         algolist = [
             {"minDr": 3, "maxDr": 99, "mult": 1, "otype1" : "MU8Fab" ,  "otype2" : "eTAU", "ocut2" : 30, "olist2" : "ab",  }, #3DR99-MU8Fab-eTAU30ab
+            {"minDr": 3, "maxDr": 30, "mult": 1, "otype1" : "MU8Fab" ,  "otype2" : "eTAU", "ocut2" : 30, "olist2" : "ab",  }, #3DR30-MU8Fab-eTAU30ab
             {"minDr": 3, "maxDr": 28, "mult": 1, "otype1" : "MU8Fab" ,  "otype2" : "eTAU", "ocut2" : 30, "olist2" : "ab",  }, #3DR28-MU8Fab-eTAU30ab
         ]
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/L1MenuConfig.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/L1MenuConfig.py
index d52794c4d5e7cd6c6f7b276124e9c581bc563864..1aa5ebeeb306c6a47655cc27d08491fa472846b0 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/L1MenuConfig.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/L1MenuConfig.py
@@ -741,6 +741,10 @@ class L1MenuConfig(object):
         # check that every item in the menu is on a board connected to CTP
         self.l1menu.checkItemsHaveInputs()
 
+        # check that items essential for detector operations are monitored
+        if 'PhysicsP1' in self.menuFullName:
+            self.l1menu.checkHFmonitoring()
+
     def mapThresholds(self):
         """
         Set the correct mapping of thresholds according to the
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/MenuCommon.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/MenuCommon.py
index b10e175e9c4bd14cc92ed9affdbf99c55c74dfb0..df9e35c84ecaa2831093b2d4c8c2b5d12448a81a 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/MenuCommon.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/MenuCommon.py
@@ -10,7 +10,6 @@ def print_available(L1MenuFlags):
     unusedItemsWithCTPID = set(L1MenuFlags.CtpIdMap.value.keys()) - set(L1MenuFlags.items.value) # this should be empty, otherwise remove the items from the CtpIdMap
     available.sort()
     logging.info("There are %d available CTP IDs: %s", len(available), ",".join(map(str,available)))
-    logging.info("IDs >= 472 go in partition 2, IDs >= 492 go in partition 3")
     logging.info("There are %d free items", freeItems)
     logging.info("There are %d floating items: %s", len(floatingItems), ",".join(map(str,floatingItems)))
     logging.info("There are %d unused items with CTP ID: %s", len(unusedItemsWithCTPID), ",".join(map(str,unusedItemsWithCTPID)))
@@ -20,11 +19,9 @@ def defineCommonL1Flags(L1MenuFlags):
 
     L1MenuFlags.BunchGroupPartitioning = [1, 15, 15] # partition 1: 1-10, partition 2: empty (was 14), partition 3: 15 (note that BGRP0 is used by all items)
     L1MenuFlags.BunchGroupNames = ['BCRVeto', 'Paired', 'CalReq', 'Empty',
-                                   'IsolatedUnpaired', 'NonIsolatedUnpaired', 'EmptyAfterPaired', 'InTrain',
-                                   'AbortGapNotCalReq', 'VdM', 'ALFA', 'EmptyBeforePaired',
-                                   'EmptyAndPaired']
-
-    L1MenuFlags.MenuPartitioning = [0, 472, 492] # partition 1: ctpid 0-471, partition 2: ctpid 472-491, partition 3: ctpid 492-511
+                                   'IsolatedUnpaired', 'NonIsolatedUnpaired', 'EmptyBeforeAfterPaired', 'InTrain',
+                                   'FirstInTrain', 'AfterGlow', 'ALFA', 'EmptyBeforePaired',
+                                   'AllWithoutCalreq', 'UnpairedBeam1', 'UnpairedBeam2', 'PCC_AfterGlow']
 
 
 # Define here the list of triggers that should be in all L1 menus
@@ -72,21 +69,3 @@ RequiredL1Items = [
         
 
 ]
-
-FixedIDMap = {
-        # to be used to hardcode CTP IDs for specific items
-        # NB: 509-511 for the CALREQ triggers (at the moment, ATR-22654)
-
-        # High-frequency counters fixed to consecutive CTP IDs
-        # 8 items with the high frequency per-bunch monitoring counters (HF:111)
-        # should be in consecutive cpid, starting a ctpid number with ctpid%16 = 0
-        # ATR-23836
-        "L1_BCM_2A_FIRSTINTRAIN":480,
-        "L1_BCM_2C_FIRSTINTRAIN":481,
-        "L1_jJ30":482,
-        "L1_MBTS_1":483,
-        "L1_MBTS_2":484,
-        "L1_MBTS_1_1":485,
-        "L1_BCM_Wide":486,
-        # "":487,
-    }
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_AllCTPIn_run3_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_AllCTPIn_run3_v1.py
index 04ec342c0255197f3784c62ac5655713c20553e5..59fd7ce9c00fd7cae780a08e7544b0a88080e78e 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_AllCTPIn_run3_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_AllCTPIn_run3_v1.py
@@ -14,7 +14,6 @@ def print_available():
     unusedItemsWithCTPID = set(L1MenuFlags.CtpIdMap.value.keys()) - set(L1MenuFlags.items.value) # this should be empty, otherwise remove the items from the CtpIdMap
     available.sort()
     logging.info("There are %d available CTP IDs: %s", len(available), ",".join(map(str,available)))
-    logging.info("IDs >= 472 go in partition 2, IDs >= 492 go in partition 3")
     logging.info("There are %d free items", freeItems)
     logging.info("There are %d floating items: %s", len(floatingItems), ",".join(map(str,floatingItems)))
     logging.info("There are %d unused items with CTP ID: %s", len(unusedItemsWithCTPID), ",".join(map(str,unusedItemsWithCTPID)))
@@ -25,12 +24,6 @@ def defineMenu():
     L1MenuFlags.CTPVersion = 4 # new CTP
 
     L1MenuFlags.BunchGroupPartitioning = [1, 15, 15] # partition 1: 1-10, partition 2: empty (was 14), partition 3: 15 (note that BGRP0 is used by all items)
-    L1MenuFlags.BunchGroupNames = ['BCRVeto', 'Paired', 'CalReq', 'Empty', 
-                                   'IsolatedUnpaired', 'NonIsolatedUnpaired', 'EmptyAfterPaired', 'InTrain', 
-                                   'AbortGapNotCalReq', 'VdM', 'ALFA', 'EmptyBeforePaired',
-                                   'EmptyAndPaired']
-
-    L1MenuFlags.MenuPartitioning = [0, 472, 492] # partition 1: ctpid 0-471, partition 2: ctpid 472-491, partition 3: ctpid 492-511
 
     # Define one item per CTP connector
     L1MenuFlags.items = [
@@ -54,25 +47,6 @@ def defineMenu():
 
     ]
 
-    # CTP ID 509-511 are reserved for CALREQ
-    L1MenuFlags.CtpIdMap = {
-        # to be used to hardcode CTP IDs for specific items
-        # NB: 509-511 for the CALREQ triggers (at the moment, ATR-22654)
-
-        # High-frequency counters fixed to consecutive CTP IDs
-        # 8 items with the high frequency per-bunch monitoring counters (HF:111)
-        # should be in consecutive cpid, starting a ctpid number with ctpid%16 = 0
-        # ATR-23836
-        "L1_BCM_2A_FIRSTINTRAIN":480,
-        "L1_BCM_2C_FIRSTINTRAIN":481,
-        "L1_J12":482,
-        "L1_MBTS_1":483,
-        "L1_MBTS_2":484,
-        "L1_MBTS_1_1":485,
-        "L1_BCM_Wide":486,
-        # "":487,
-    }
-
 
 if __name__ == "__main__": print_available()
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_run3_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_run3_v1.py
index 55da772b7a06cff376de87c5707410d6d503a48d..7e926fac6571ac0246701df4350c75ba550ca546 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_run3_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_run3_v1.py
@@ -104,6 +104,7 @@ def defineMenu():
         'L1_MU8F_TAU20IM',
         #ATR-30179
         'L1_cTAU30M_3DR99-MU8F-eTAU30',
+        'L1_cTAU30M_3DR30-MU8F-eTAU30',
         'L1_cTAU30M_3DR28-MU8F-eTAU30',
         #
         'L1_TAU20IM_2TAU12IM_J25_2J20_3J12',
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_run3_v1_inputs.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_run3_v1_inputs.py
index e91fb51afe24607fdd7cfc54dc9e87ecece446f5..8681e3f2db16426919938ed14fdd6ffe783612ba 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_run3_v1_inputs.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_run3_v1_inputs.py
@@ -75,6 +75,7 @@ def defineInputsMenu():
                                 #                                                                                           '3DR28-MU8Fab-eTAU30ab' ]) #ATR-30170
                                     TopoMenuDef( '3DR99-MU8Fab-eTAU30ab', outputbits = 2),
                                     TopoMenuDef( '3DR28-MU8Fab-eTAU30ab', outputbits = 3),
+                                    TopoMenuDef( '3DR30-MU8Fab-eTAU30ab', outputbits = 4),
                             ]
 
     #----------------------------------------------
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_Physics_HI_run3_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_Physics_HI_run3_v1.py
index 6ee7379f7a702f213a3e30788490e8159ba5541e..62e06030461cac93e35e07b7f31aae7bf8c06331 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_Physics_HI_run3_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_Physics_HI_run3_v1.py
@@ -3,7 +3,7 @@
 # Run this file in order to print out the empty slots
 
 from TriggerMenuMT.L1.Base.L1MenuFlags import L1MenuFlags
-from TriggerMenuMT.L1.Menu.MenuCommon import print_available, RequiredL1Items, FixedIDMap, defineCommonL1Flags
+from TriggerMenuMT.L1.Menu.MenuCommon import print_available, RequiredL1Items, defineCommonL1Flags
 
 def defineMenu():
 
@@ -333,11 +333,6 @@ def defineMenu():
     ]
 
 
-
-# Run this file as python python/L1/Menu_MC_HI_run3_v1.py to print out available IDs
-    
-    L1MenuFlags.CtpIdMap = FixedIDMap
-
 if __name__ == "__main__":
     defineMenu()
     print_available(L1MenuFlags)
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_Physics_pp_run3_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_Physics_pp_run3_v1.py
index 85ed3de232cb410627917e9f2c1ec026442e8447..0074fb8dc7c751a40062c746fed2be79f47e961a 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_Physics_pp_run3_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_Physics_pp_run3_v1.py
@@ -3,7 +3,7 @@
 # Run this file in order to print out the empty slots
 
 from TriggerMenuMT.L1.Base.L1MenuFlags import L1MenuFlags
-from TriggerMenuMT.L1.Menu.MenuCommon import print_available, RequiredL1Items, FixedIDMap, defineCommonL1Flags
+from TriggerMenuMT.L1.Menu.MenuCommon import print_available, RequiredL1Items, defineCommonL1Flags
 
 def defineMenu():
 
@@ -338,7 +338,6 @@ def defineMenu():
         
         ]
 
-    L1MenuFlags.CtpIdMap = FixedIDMap
 
 if __name__ == "__main__":
     defineMenu()