From 67d7c4d8c4689c965a95af76cf3ce13e87befbe7 Mon Sep 17 00:00:00 2001
From: Tomasz Bold <tomasz.bold@gmail.com>
Date: Fri, 17 Sep 2021 19:07:10 +0200
Subject: [PATCH] Refactor of nav conversion for easier code analysis

---
 .../src/Run2ToRun3TrigNavConverter.cxx        | 623 +++++++++---------
 .../src/Run2ToRun3TrigNavConverter.h          |   6 +-
 2 files changed, 315 insertions(+), 314 deletions(-)

diff --git a/Trigger/TrigEvent/TrigNavTools/src/Run2ToRun3TrigNavConverter.cxx b/Trigger/TrigEvent/TrigNavTools/src/Run2ToRun3TrigNavConverter.cxx
index 75f1e62069a2..a786dc21771d 100644
--- a/Trigger/TrigEvent/TrigNavTools/src/Run2ToRun3TrigNavConverter.cxx
+++ b/Trigger/TrigEvent/TrigNavTools/src/Run2ToRun3TrigNavConverter.cxx
@@ -20,33 +20,28 @@
 #include <random>
 
 
-Run2ToRun3TrigNavConverter::Run2ToRun3TrigNavConverter(const std::string &name, ISvcLocator *pSvcLocator) : AthReentrantAlgorithm(name, pSvcLocator)
-{
-}
-
-Run2ToRun3TrigNavConverter::~Run2ToRun3TrigNavConverter()
-{
-}
+Run2ToRun3TrigNavConverter::Run2ToRun3TrigNavConverter(const std::string& name, ISvcLocator* pSvcLocator) : AthReentrantAlgorithm(name, pSvcLocator){}
 
-StatusCode Run2ToRun3TrigNavConverter::initialize()
-{
+Run2ToRun3TrigNavConverter::~Run2ToRun3TrigNavConverter(){}
 
+StatusCode Run2ToRun3TrigNavConverter::initialize() {
 
   ATH_CHECK(m_trigNavWriteKey.initialize());
   ATH_CHECK(m_configSvc.retrieve());
   ATH_CHECK(m_clidSvc.retrieve());
-  ATH_CHECK( m_tdt.empty() != m_trigNavKey.key().empty() ); //either of the two has to be enabled but not both
-  if ( !m_tdt.empty() ) {
+  ATH_CHECK(m_tdt.empty() != m_trigNavKey.key().empty()); //either of the two has to be enabled but not both
+  if (!m_tdt.empty()) {
     ATH_CHECK(m_tdt.retrieve());
-    ATH_MSG_INFO( "Will use Trigger Navigation from TrigDecisionTool");
-  } else { 
+    ATH_MSG_INFO("Will use Trigger Navigation from TrigDecisionTool");
+  }
+  else {
     ATH_CHECK(m_trigNavKey.initialize(SG::AllowEmpty));
-    ATH_MSG_INFO( "Will use Trigger Navigation decoded from TrigNavigation object");
+    ATH_MSG_INFO("Will use Trigger Navigation decoded from TrigNavigation object");
   }
   // retrievig CLID from names and storing to set
-  for (const auto &name : m_collectionsToSave)
+  for (const auto& name : m_collectionsToSave)
   {
-    CLID id{0};
+    CLID id{ 0 };
     ATH_CHECK(m_clidSvc->getIDOfTypeName(name, id));
     m_setCLID.insert(id);
   }
@@ -58,8 +53,6 @@ StatusCode Run2ToRun3TrigNavConverter::initialize()
   for (const auto& name : m_roisToSave) {
     m_setRoiName.push_back(name);
   }
-  
-
 
   ATH_CHECK(m_clidSvc->getIDOfTypeName("TrigRoiDescriptor", m_roIDescriptorCLID));
   ATH_CHECK(m_clidSvc->getIDOfTypeName("TrigRoiDescriptorCollection", m_roIDescriptorCollectionCLID));
@@ -75,114 +68,118 @@ StatusCode Run2ToRun3TrigNavConverter::initialize()
   return StatusCode::SUCCESS;
 }
 
-StatusCode Run2ToRun3TrigNavConverter::finalize()
-{
+StatusCode Run2ToRun3TrigNavConverter::finalize() {
   return StatusCode::SUCCESS;
 }
 
 
-StatusCode Run2ToRun3TrigNavConverter::execute(const EventContext &context) const
+StatusCode Run2ToRun3TrigNavConverter::execute(const EventContext& context) const
 {
-  const HLT::TrigNavStructure* navDecoderPtr = nullptr;
+  const HLT::TrigNavStructure* run2NavigationPtr = nullptr;
   HLT::StandaloneNavigation standaloneNav;
-  if (!m_trigNavKey.key().empty()) {    
+  if (!m_trigNavKey.key().empty()) {
     SG::ReadHandle navReadHandle(m_trigNavKey, context);
     ATH_CHECK(navReadHandle.isValid());
     standaloneNav.deserialize(navReadHandle->serialized());
-    navDecoderPtr = &standaloneNav;
-  } else {
-    navDecoderPtr = m_tdt->ExperimentalAndExpertMethods().getNavigation();
+    run2NavigationPtr = &standaloneNav;
   }
-  const HLT::TrigNavStructure& navDecoder = *navDecoderPtr;
+  else {
+    run2NavigationPtr = m_tdt->ExperimentalAndExpertMethods().getNavigation();
+  }
+  const HLT::TrigNavStructure& run2Navigation = *run2NavigationPtr;
 
 
   // string identifier for TE
   std::map< int, std::string > hash2string;
-  for (auto p : m_configSvc->chains()) { 
-    for (auto s_iter = p->signatures().begin(); s_iter != p->signatures().end(); ++s_iter) { 
-      for (auto te : (*s_iter)->outputTEs()) { 
-          int hash = TrigConf::HLTUtils::string2hash( te->name() );
-          hash2string[ hash ] = te->name();
+  for (auto p : m_configSvc->chains()) {
+    for (auto s_iter = p->signatures().begin(); s_iter != p->signatures().end(); ++s_iter) {
+      for (auto te : (*s_iter)->outputTEs()) {
+        int hash = TrigConf::HLTUtils::string2hash(te->name());
+        hash2string[hash] = te->name();
       }
     }
-  } 
+  }
 
   if (m_onlyFeaturePriting)
-    return printFeatures(navDecoder);
+    return printFeatures(run2Navigation);
 
   SG::WriteHandle<TrigCompositeUtils::DecisionContainer> outputNavigation = TrigCompositeUtils::createAndStore(m_trigNavWriteKey, context);
   auto decisionOutput = outputNavigation.ptr();
-  TrigCompositeUtils::Decision *passRawOutput = TrigCompositeUtils::newDecisionIn(decisionOutput, "HLTPassRaw");
+  TrigCompositeUtils::Decision* passRawOutput = TrigCompositeUtils::newDecisionIn(decisionOutput, "HLTPassRaw");
 
-  if (m_doPrint)
-  {
+  if (m_doPrint) {
     std::string dump;
-    navDecoder.printASCIIArt(dump);
+    run2Navigation.printASCIIArt(dump);
     ATH_MSG_INFO(dump);
   }
 
   // auxiliary random objects
+  /*
   std::random_device rd;
   std::mt19937_64 gen(rd());
   std::uniform_int_distribution<uint32_t> dis;
+  */
 
-  std::vector<HLT::TriggerElement *> tes;
-  TE_Decision_map mapTEtoDecision;                          // TE - Decision (xAOD::TrigComposite)
-  TE_Decision_map mapTEtoDecisionActive;                    // TE Active - Decision (xAOD::TrigComposite)
-  std::vector<TrigCompositeUtils::Decision *> decisionLast; // storing "last" decision in a chain
+  std::vector<HLT::TriggerElement*> tes;
+  TEDecisionMap mapTEtoHNodes;                          // TE - Decision (xAOD::TrigComposite)
+  TEDecisionMap mapTEtoIMNodes;                    // TE Active - Decision (xAOD::TrigComposite)
+  std::vector<TrigCompositeUtils::Decision*> decisionLast; // storing "last" decision in a chain
 
   DecisionObjMap decisionObj;
   DecisionObjStringMap decisionObjFeatureless;
   L1ObjMap l1Obj;
-  
+
   std::vector<HLT::TriggerElement::FeatureAccessHelper> featureRoI; // for keeping predecessing TE with RoI
 
   // @@@@@@@@@@@@@@@@@@@@@@@@@@ getDecisionObject @@@@@@@@@@@@@@@@@@@@@@@@@@
-  auto getDecisionObject = [&](const HLT::TriggerElement::FeatureAccessHelper &elemFE, size_t idx, TrigCompositeUtils::DecisionContainer *dOutput, size_t &kIn, HLT::TriggerElement* ptrTE = nullptr) {
-  // kIn: flag with the information about the decision objects (DO)
-  // 0: DO pair has been found and returned (no new pair created)
-  // 1: H node created for a feature unit from collection, IM retrieved (not created)
-  // 2: a new DO pair created (that is: H and IM node)
-    auto [sgKey, sgCLID, sgName] = getSgKey(navDecoder, elemFE);
-    auto it = decisionObj.find(sgKey + idx);
-    if (it != decisionObj.end())
-    {
-      kIn = 0;
-      return it->second;
-    }
+  auto getDecisionObject = [&](const HLT::TriggerElement::FeatureAccessHelper& elemFE,
+    size_t idx,
+    TrigCompositeUtils::DecisionContainer* dOutput,
+    size_t& kIn,
+    HLT::TriggerElement* ptrTE = nullptr) {
+      // kIn: flag with the information about the decision objects (DO)
+      // 0: DO pair has been found and returned (no new pair created)
+      // 1: H node created for a feature unit from collection, IM retrieved (not created)
+      // 2: a new DO pair created (that is: H and IM node)
+
+      auto [sgKey, sgCLID, sgName] = getSgKey(run2Navigation, elemFE);
+      auto it = decisionObj.find(sgKey + idx);
+      if (it != decisionObj.end()) {
+        kIn = 0;
+        ATH_MSG_DEBUG("Reusing = " << ptrTE << " IM " << it->second.second->index() << " H " << it->second.first->index());
+        return it->second;
+      }
 
-    kIn = 2;
-    if (idx == elemFE.getIndex().objectsBegin())
-    {
-      auto d2 = TrigCompositeUtils::newDecisionIn(dOutput); // IM
-      d2->setName(TrigCompositeUtils::inputMakerNodeName());
-      auto d1 = TrigCompositeUtils::newDecisionIn(dOutput); // H
-      d1->setName(TrigCompositeUtils::hypoAlgNodeName());
-      TrigCompositeUtils::linkToPrevious(d1, d2, context); // H low IM up
-      ATH_MSG_DEBUG("TE FE link creator H lower IM upper = " << ptrTE << " " << d1 << " " << d2);
-      ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[H creation] " << "(" << d1->index() << ")");
-      ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[IM creation] " << "(" << d2->index() << ")");
-      ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[H -> IM seed link] " << "(" << d1->index() << " -> " << d2->index() << ")");
-      return std::make_pair(d1, d2);
-    }
+      kIn = 2;
+      if (idx == elemFE.getIndex().objectsBegin()) {
+        auto imNode = TrigCompositeUtils::newDecisionIn(dOutput); // IM
+        imNode->setName(TrigCompositeUtils::inputMakerNodeName());
+        auto hNode = TrigCompositeUtils::newDecisionIn(dOutput); // H
+        hNode->setName(TrigCompositeUtils::hypoAlgNodeName());
+        TrigCompositeUtils::linkToPrevious(hNode, imNode, context); // H low IM up
+        ATH_MSG_DEBUG("TE FE link creator H lower IM upper = " << ptrTE << " " << hNode << " " << imNode);
+        ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[H creation] " << "(" << hNode->index() << ")");
+        ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[IM creation] " << "(" << imNode->index() << ")");
+        ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[H -> IM seed link] " << "(" << hNode->index() << " -> " << imNode->index() << ")");
+        return std::make_pair(hNode, imNode);
+      }
 
-    kIn = 1;
-    auto d1 = TrigCompositeUtils::newDecisionIn(dOutput); // H
-    d1->setName(TrigCompositeUtils::hypoAlgNodeName());
-    auto d2 = (decisionObj.find(sgKey + elemFE.getIndex().objectsBegin())->second).second;
-    ATH_MSG_DEBUG("TE FE link creator H lower IM upper = " << ptrTE << " " << d1 << " " << d2);
-    TrigCompositeUtils::linkToPrevious(d1, d2, context); // H low IM up
-    ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[H creation] " << "(" << d1->index() << ")");
-    ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[H -> IM seed link] " << "(" << d1->index() << " -> " << d2->index() << ")");
-    return std::make_pair(d1, d2);
+      kIn = 1;
+      auto hNode = TrigCompositeUtils::newDecisionIn(dOutput); // H
+      hNode->setName(TrigCompositeUtils::hypoAlgNodeName());
+      auto imNode = (decisionObj.find(sgKey + elemFE.getIndex().objectsBegin())->second).second;
+      ATH_MSG_DEBUG("TE FE link creator H lower IM upper = " << ptrTE << " " << hNode << " " << imNode);
+      TrigCompositeUtils::linkToPrevious(hNode, imNode, context); // H low IM up
+      ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[H creation] " << "(" << hNode->index() << ")");
+      ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[H -> IM seed link] " << "(" << hNode->index() << " -> " << imNode->index() << ")");
+      return std::make_pair(hNode, imNode);
   };
 
   // @@@@@@@@@@@@@@@@@@@@@@@@@@ getL1Object @@@@@@@@@@@@@@@@@@@@@@@@@@
-  auto getL1Object = [&](const HLT::TriggerElement::FeatureAccessHelper &elemFE, size_t idx, TrigCompositeUtils::DecisionContainer *dOutput, size_t &kIn) {
-    auto [sgKey, sgCLID, sgName] = getSgKey(navDecoder, elemFE);
+  auto getL1Object = [&](const HLT::TriggerElement::FeatureAccessHelper& elemFE, size_t idx, TrigCompositeUtils::DecisionContainer* dOutput, size_t& kIn) {
+    auto [sgKey, sgCLID, sgName] = getSgKey(run2Navigation, elemFE);
     auto it = l1Obj.find(sgKey + idx);
-    if (it != l1Obj.end())
-    {
+    if (it != l1Obj.end()) {
       kIn = 0;
       return it->second;
     }
@@ -202,25 +199,25 @@ StatusCode Run2ToRun3TrigNavConverter::execute(const EventContext &context) cons
       auto c = p;
       HLT::Identifier chainId = HLT::Identifier(chainName);
 
-        // @@@@@@@@@@@@@@@@@@@@@@@@@@ ordered_sorter @@@@@@@@@@@@@@@@@@@@@@@@@@
-        auto ordered_sorter = [&](const auto& left, const auto& right) {
-           return std::find(cbegin(m_setRoiName), cend(m_setRoiName), left) < std::find(cbegin(m_setRoiName), cend(m_setRoiName), right);
-        };
-        std::map<std::string, HLT::TriggerElement::FeatureAccessHelper, decltype(ordered_sorter)> mp(ordered_sorter);
-        // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+      // @@@@@@@@@@@@@@@@@@@@@@@@@@ ordered_sorter @@@@@@@@@@@@@@@@@@@@@@@@@@
+      auto ordered_sorter = [&](const auto& left, const auto& right) {
+        return std::find(cbegin(m_setRoiName), cend(m_setRoiName), left) < std::find(cbegin(m_setRoiName), cend(m_setRoiName), right);
+      };
+      std::map<std::string, HLT::TriggerElement::FeatureAccessHelper, decltype(ordered_sorter)> mp(ordered_sorter);
+      // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 
       ATH_MSG_DEBUG(" CHAIN name " << chainName);
-      bool kTErejection { false };
+      bool kTErejection{ false };
       for (auto s_iter = c->signatures().begin(), first_s_iter = s_iter; s_iter != c->signatures().end(); ++s_iter)
       {
         if (kTErejection) break;
-        std::vector<TrigCompositeUtils::Decision *> tempDecisionVector;
+        std::vector<TrigCompositeUtils::Decision*> tempDecisionVector;
         for (auto te : (*s_iter)->outputTEs())
         {
           tes.clear();
-          navDecoder.getAllOfType(te->id(), tes, false);
-          ATH_MSG_DEBUG(" TE size " << tes.size());
-          if (tes.size()==0) {
+          run2Navigation.getAllOfType(te->id(), tes, false);
+          ATH_MSG_DEBUG(" TE size " << tes.size() << " name " << hash2string[te->id()]);
+          if (tes.size() == 0) {
             kTErejection = true;
             break;
           }
@@ -233,73 +230,72 @@ StatusCode Run2ToRun3TrigNavConverter::execute(const EventContext &context) cons
 
             tempDecisionVector.clear();
 
-            auto vectorTEfeatures_ptr = getTEfeatures(teptr, navDecoder);
-            auto vectorTEROIfeatures_ptr = getTEROIfeatures( teptr, navDecoder );
+            auto vectorTEfeatures_ptr = getTEfeatures(teptr, run2Navigation);
+            auto vectorTEROIfeatures_ptr = getTEROIfeatures(teptr, run2Navigation);
             auto vectorTRACKfeatures_ptr = getTRACKfeatures(teptr);
 
             mp.clear();
 
             // @@@@@@@@@@@@@@@@@@@@@@@@@@ roiFinder @@@@@@@@@@@@@@@@@@@@@@@@@@
             std::function<void(HLT::TriggerElement*)> roiFinder = [&](HLT::TriggerElement* ptrTE) {
-                auto vecTEpred = navDecoder.getDirectPredecessors(ptrTE);
-                if (vecTEpred.empty()) {
-                  return nullptr;
-                } else {
+              auto vecTEpred = run2Navigation.getDirectPredecessors(ptrTE);
+              if (vecTEpred.empty()) {
+                return nullptr;
+              }
+              else {
+                for (auto pred : vecTEpred) { // vector predecessors TE
+                  auto vectorTEROIfeatures_ptr = getTEROIfeatures(pred, run2Navigation);
+                  if (vectorTEROIfeatures_ptr.empty() == false) {
+                    auto [sgKey, sgCLID, sgName] = getSgKey(run2Navigation, vectorTEROIfeatures_ptr.front());
+                    mp[sgName] = vectorTEROIfeatures_ptr.front();
+                  }
+                }
+                if (mp.empty()) {
                   for (auto pred : vecTEpred) { // vector predecessors TE
-                    auto vectorTEROIfeatures_ptr = getTEROIfeatures( pred, navDecoder );
-                    if (vectorTEROIfeatures_ptr.empty()==false) {
-                      auto [sgKey, sgCLID, sgName] = getSgKey(navDecoder,vectorTEROIfeatures_ptr.front());
-                      mp[sgName] = vectorTEROIfeatures_ptr.front();
-                    } 
-                  }        
-                  if (mp.empty()) {
-                    for (auto pred : vecTEpred) { // vector predecessors TE
-                      roiFinder(pred);
-                    }
+                    roiFinder(pred);
                   }
                 }
-                return nullptr; 
+              }
+              return nullptr;
             };
 
             // @@@@@@@@@@@@@@@@@@@@@@@@@@ featureFinder @@@@@@@@@@@@@@@@@@@@@@@@@@
-            std::function<uint32_t(HLT::TriggerElement*,uint32_t&)> featureFinder = [&](HLT::TriggerElement* ptrTE, uint32_t& deepLvl) {
-                auto vecTEpred = navDecoder.getDirectPredecessors(ptrTE);
-                if (vecTEpred.empty()==false)                     
-                {
-                  for (auto pred : vecTEpred) { // vector predecessors TE
-                    auto vectorTEfeatures_ptr = getTEfeatures( pred, navDecoder, false ); // any feature collection
-                    if (vectorTEfeatures_ptr.size()==1 && (vectorTEfeatures_ptr.front().getIndex().objectsBegin()==vectorTEfeatures_ptr.front().getIndex().objectsEnd())) {
+            std::function<uint32_t(HLT::TriggerElement*, uint32_t&)> featureFinder = [&](HLT::TriggerElement* ptrTE, uint32_t& deepLvl) {
+              auto vecTEpred = run2Navigation.getDirectPredecessors(ptrTE);
+              if (vecTEpred.empty() == false) {
+                for (auto pred : vecTEpred) { // vector predecessors TE
+                  auto vectorTEfeatures_ptr = getTEfeatures(pred, run2Navigation, false); // any feature collection
+                  if (vectorTEfeatures_ptr.size() == 1 && (vectorTEfeatures_ptr.front().getIndex().objectsBegin() == vectorTEfeatures_ptr.front().getIndex().objectsEnd())) {
                     //if (vectorTEfeatures_ptr.front().getIndex().objectsBegin()==vectorTEfeatures_ptr.front().getIndex().objectsEnd()) {
-                       break; // this is empty FE, treat it is as zero FE
-                    }
-                    if (vectorTEfeatures_ptr.empty()==false) 
-                    {
-                      auto featureBegin = 10000*vectorTEfeatures_ptr.front().getIndex().objectsBegin();
-                      auto [sgKey, sgCLID, sgName] = getSgKey(navDecoder,vectorTEfeatures_ptr.front());
-                      return sgKey+featureBegin+deepLvl; // first found 
-                    } 
+                    break; // this is empty FE, treat it is as zero FE
                   }
-                  // if no success after scan of TE predecessors we go one level up
-                  ++deepLvl;
-                  uint32_t keySearch { 0 };
-                  for (auto pred : vecTEpred) { 
-                    keySearch = featureFinder(pred,deepLvl); // recursive call
-                    if (keySearch != 0) return keySearch; // first found
+                  if (vectorTEfeatures_ptr.empty() == false) {                  
+                    auto featureBegin = 10000 * vectorTEfeatures_ptr.front().getIndex().objectsBegin();
+                    auto [sgKey, sgCLID, sgName] = getSgKey(run2Navigation, vectorTEfeatures_ptr.front());
+                    return sgKey + featureBegin + deepLvl; // first found 
                   }
                 }
-                return (uint32_t)0; // no TE predecessor, no FE at all or recursive search failed
+                // if no success after scan of TE predecessors we go one level up
+                ++deepLvl;
+                uint32_t keySearch{ 0 };
+                for (auto pred : vecTEpred) {
+                  keySearch = featureFinder(pred, deepLvl); // recursive call
+                  if (keySearch != 0) return keySearch; // first found
+                }
+              }
+              return (uint32_t)0; // no TE predecessor, no FE at all or recursive search failed
             };
 
             // @@@@@@@@@@@@@@@@@@@@@@@@@@ getTEObject @@@@@@@@@@@@@@@@@@@@@@@@@@
-            auto getTEObject = [&](HLT::TriggerElement* ptrTE, uint32_t& deepLevel, TrigCompositeUtils::DecisionContainer *dOutput) -> DecisionPair& {
-                // this is featureless case
-                std::string teName = hash2string[ ptrTE->getId() ];
-                if (teName != "") {
-                  auto it = decisionObjFeatureless.find(teName);
-                  if (it != decisionObjFeatureless.end()) return it->second;
-                }
+            auto getTEObject = [&](HLT::TriggerElement* ptrTE, uint32_t& deepLevel, TrigCompositeUtils::DecisionContainer* dOutput) -> DecisionPair& {
+              // this is featureless case
+              std::string teName = hash2string[ptrTE->getId()];
+              if (teName != "") {
+                auto it = decisionObjFeatureless.find(teName);
+                if (it != decisionObjFeatureless.end()) return it->second;
+              }
 
-                deepLevel = 0; // at this moment obsolte, but see below
+              deepLevel = 0; // at this moment obsolte, but see below
 /*
                 // THIS BLOCK is left intetionally here as an alternative approach.
 
@@ -313,60 +309,53 @@ StatusCode Run2ToRun3TrigNavConverter::execute(const EventContext &context) cons
                   sgKeyProxy = 1000000 + dis(gen); // let us random it
                 }
 */
-                auto d2 = TrigCompositeUtils::newDecisionIn(dOutput); // IM
-                d2->setName(TrigCompositeUtils::inputMakerNodeName());
-                auto d1 = TrigCompositeUtils::newDecisionIn(dOutput); // H
-                d1->setName(TrigCompositeUtils::hypoAlgNodeName());
-                TrigCompositeUtils::linkToPrevious(d1, d2, context);
-                ATH_MSG_DEBUG("TE link creator H lower IM upper = " << ptrTE << " " << d1 << " " << d2);
-                ATH_MSG_DEBUG("REGTEST " << "[TE featureless] " << "[H creation] " << "(" << d1->index() << ")");
-                ATH_MSG_DEBUG("REGTEST " << "[TE featureless] " << "[IM creation] " << "(" << d2->index() << ")");
-                ATH_MSG_DEBUG("REGTEST " << "[TE featureless] " << "[H -> IM seed link] " << "(" << d1->index() << " -> " << d2->index() << ")");
-                //return decisionObjFeatureless[sgKeyProxy] = std::make_pair(d1, d2); // intentionally left, see above
-                return decisionObjFeatureless[teName] = std::make_pair(d1, d2);
+              auto d2 = TrigCompositeUtils::newDecisionIn(dOutput); // IM
+              d2->setName(TrigCompositeUtils::inputMakerNodeName());
+              auto d1 = TrigCompositeUtils::newDecisionIn(dOutput); // H
+              d1->setName(TrigCompositeUtils::hypoAlgNodeName());
+              TrigCompositeUtils::linkToPrevious(d1, d2, context);
+              ATH_MSG_DEBUG("TE link creator H lower IM upper = " << ptrTE << " " << d1 << " " << d2);
+              ATH_MSG_DEBUG("REGTEST " << "[TE featureless] " << "[H creation] " << "(" << d1->index() << ")");
+              ATH_MSG_DEBUG("REGTEST " << "[TE featureless] " << "[IM creation] " << "(" << d2->index() << ")");
+              ATH_MSG_DEBUG("REGTEST " << "[TE featureless] " << "[H -> IM seed link] " << "(" << d1->index() << " -> " << d2->index() << ")");
+              //return decisionObjFeatureless[sgKeyProxy] = std::make_pair(d1, d2); // intentionally left, see above
+              return decisionObjFeatureless[teName] = std::make_pair(d1, d2);
             };
 
 
             if (vectorTEROIfeatures_ptr.empty()) {
               roiFinder(teptr);
-            } else {
-              auto [sgKey, sgCLID, sgName] = getSgKey(navDecoder,vectorTEROIfeatures_ptr.front());
+            }
+            else {
+              auto [sgKey, sgCLID, sgName] = getSgKey(run2Navigation, vectorTEROIfeatures_ptr.front());
               mp[sgName] = vectorTEROIfeatures_ptr.front();
             }
 
 
             // @@@@@@@@@@@@@@@@@@@@@@@@@@ vector TE - EMPTY @@@@@@@@@@@@@@@@@@@@@@@@@@
-            if ( vectorTEfeatures_ptr.empty() || 
-               ( /*vectorTEfeatures_ptr.size() == 1 && */ // alternative check
-                 (vectorTEfeatures_ptr[0].getIndex().objectsBegin() == vectorTEfeatures_ptr[0].getIndex().objectsEnd()) )
-               ) 
-            {
+            if (vectorTEfeatures_ptr.empty() || vectorTEfeatures_ptr[0].getIndex().objectsBegin() == vectorTEfeatures_ptr[0].getIndex().objectsEnd()) {
 
 
-              uint32_t dLevel { 1 };
-              auto [ decisionFeature, decisionPtr ] = getTEObject(teptr,dLevel,decisionOutput); // H IM
-              ATH_MSG_DEBUG("JUST AFTER " << "[TE] " << teptr <<  " [H] " << decisionFeature->index() << " [IM] " << decisionPtr->index() << " dLevel=" << dLevel);
-              auto decision = decisionPtr; // IM
+              uint32_t dLevel{ 1 };
+              auto [hNode, imNode] = getTEObject(teptr, dLevel, decisionOutput); // H IM
+              ATH_MSG_DEBUG("JUST AFTER " << "[TE] " << teptr << " [H] " << hNode->index() << " [IM] " << imNode->index() << " dLevel=" << dLevel);
+              auto decision = imNode; // IM
 
-              tempDecisionVector.push_back(decisionFeature);
+              tempDecisionVector.push_back(hNode);
 
               if (teptr->getActiveState()) {
-                TrigCompositeUtils::addDecisionID(chainId, decisionFeature); // H
-                ATH_MSG_DEBUG("REGTEST " << "[TE featureless] " << "[H Index] (" << decisionFeature->index() << ") [Chain ID] " << chainId);
+                TrigCompositeUtils::addDecisionID(chainId, hNode); // H
+                ATH_MSG_DEBUG("REGTEST " << "[TE featureless] " << "[H Index] (" << hNode->index() << ") [Chain ID] " << chainId);
               }
               TrigCompositeUtils::addDecisionID(chainId, decision); // IM
               ATH_MSG_DEBUG("REGTEST " << "[TE featureless] " << "[IM Index] (" << decision->index() << ") [Chain ID] " << chainId);
-              
-              ElementLink<xAOD::TrigCompositeContainer> linkToSelf = TrigCompositeUtils::decisionToElementLink(decisionFeature, context);
-              decisionFeature->setObjectLink<xAOD::TrigCompositeContainer>(TrigCompositeUtils::featureString(), linkToSelf);
-              if ( std::find(begin(mapTEtoDecision[teptr]),end(mapTEtoDecision[teptr]),decisionFeature) == mapTEtoDecision[teptr].end() ) {
-                mapTEtoDecision[teptr].push_back(decisionFeature); // H
-              }
-              if ( std::find(begin(mapTEtoDecisionActive[teptr]),end(mapTEtoDecisionActive[teptr]),decision) == mapTEtoDecisionActive[teptr].end() ) {
-                mapTEtoDecisionActive[teptr].push_back(decision); // IM
-              }
 
-              TrigCompositeUtils::Decision *l1_decision{nullptr};
+              ElementLink<xAOD::TrigCompositeContainer> linkToSelf = TrigCompositeUtils::decisionToElementLink(hNode, context);
+              hNode->setObjectLink<xAOD::TrigCompositeContainer>(TrigCompositeUtils::featureString(), linkToSelf);
+              ATH_CHECK(insertDecisionToTEMap(hNode, teptr,  mapTEtoHNodes));
+              ATH_CHECK(insertDecisionToTEMap(imNode, teptr, mapTEtoIMNodes));
+
+              TrigCompositeUtils::Decision* l1_decision{ nullptr };
               if (s_iter == first_s_iter)
               {
                 l1_decision = TrigCompositeUtils::newDecisionIn(decisionOutput);
@@ -379,32 +368,32 @@ StatusCode Run2ToRun3TrigNavConverter::execute(const EventContext &context) cons
 
 
               if (mp.empty() == false) {
-                ATH_CHECK(addTEROIfeatures(navDecoder, (mp.begin())->second, decision)); 
+                ATH_CHECK(addTEROIfeatures(run2Navigation, (mp.begin())->second, decision));
               }
 
-              for (const auto &rNodes : HLT::TrigNavStructure::getRoINodes(teptr))
+              for (const auto& rNodes : HLT::TrigNavStructure::getRoINodes(teptr))
               {
                 if (HLT::TrigNavStructure::isRoINode(rNodes))
                 {
-                  //////////////////auto vectorROIfeatures_ptr = getROIfeatures(rNodes, navDecoder);
-                  auto vectorROIfeatures_ptr = getTEROIfeatures(rNodes, navDecoder);
+                  //////////////////auto vectorROIfeatures_ptr = getROIfeatures(rNodes, run2Navigation);
+                  auto vectorROIfeatures_ptr = getTEROIfeatures(rNodes, run2Navigation);
                   for (auto featureRoI : vectorROIfeatures_ptr)
                   {
                     if (mp.empty()) {
-                      ATH_CHECK(addTEROIfeatures(navDecoder, featureRoI, decision)); // roi link to initialRoi
+                      ATH_CHECK(addTEROIfeatures(run2Navigation, featureRoI, decision)); // roi link to initialRoi
                     }
                   }
 
                   //### TRACKS ### check for track features and connect the same RoI
                   if (!vectorROIfeatures_ptr.empty())
-                    for (const auto &elemTRACK : vectorTRACKfeatures_ptr)
+                    for (const auto& elemTRACK : vectorTRACKfeatures_ptr)
                     {
-                      for (size_t i{elemTRACK.getIndex().objectsBegin()}; i < elemTRACK.getIndex().objectsEnd(); ++i)
+                      for (size_t i{ elemTRACK.getIndex().objectsBegin() }; i < elemTRACK.getIndex().objectsEnd(); ++i)
                       {
                         ElementLink<TrigRoiDescriptorCollection> ROIElementLink = decision->objectLink<TrigRoiDescriptorCollection>(TrigCompositeUtils::roiString());
                         if (ROIElementLink.isValid())
                         {
-                          ATH_CHECK(addTRACKfeatures(navDecoder, elemTRACK, decision, ROIElementLink));
+                          ATH_CHECK(addTRACKfeatures(run2Navigation, elemTRACK, decision, ROIElementLink));
                         }
                       }
                     }
@@ -413,100 +402,96 @@ StatusCode Run2ToRun3TrigNavConverter::execute(const EventContext &context) cons
             }
 
 
-           // @@@@@@@@@@@@@@@@@@@@@@@@@@ vector TE - FULL @@@@@@@@@@@@@@@@@@@@@@@@@@
-            if ( vectorTEfeatures_ptr.empty()==false &&
-                 vectorTEfeatures_ptr[0].getIndex().objectsBegin() < vectorTEfeatures_ptr[0].getIndex().objectsEnd() )
+            // @@@@@@@@@@@@@@@@@@@@@@@@@@ vector TE - FULL @@@@@@@@@@@@@@@@@@@@@@@@@@
+            if (vectorTEfeatures_ptr.empty() == false &&
+              vectorTEfeatures_ptr[0].getIndex().objectsBegin() < vectorTEfeatures_ptr[0].getIndex().objectsEnd())
             {
 
-            for (const auto &elemFE : vectorTEfeatures_ptr)
-            {
-              TrigCompositeUtils::Decision *decision{nullptr};
-
-              for (size_t i{elemFE.getIndex().objectsBegin()}; i < elemFE.getIndex().objectsEnd(); ++i)
+              for (const auto& elemFE : vectorTEfeatures_ptr)
               {
-                size_t kInsert{0};
-                auto [decisionFeature, decisionPtr] = getDecisionObject(elemFE, i, decisionOutput, kInsert, teptr); // H IM
-                decision = decisionPtr; // IM
+                TrigCompositeUtils::Decision* decision{ nullptr };
 
-                if (mp.empty() == false) {
-                      ATH_CHECK(addTEROIfeatures(navDecoder, (mp.begin())->second, decision)); // updated roi on the way
-                }
+                for (size_t objectIndex{ elemFE.getIndex().objectsBegin() }; objectIndex < elemFE.getIndex().objectsEnd(); ++objectIndex)
+                {
+                  size_t kInsert{ 0 };
+                  auto [hNode, imNode] = getDecisionObject(elemFE, objectIndex, decisionOutput, kInsert, teptr); // H IM
+                  decision = imNode; // IM
+
+                  if (mp.empty() == false) {
+                    ATH_CHECK(addTEROIfeatures(run2Navigation, (mp.begin())->second, imNode)); // updated roi on the way
+                  }
 
 
-                if (teptr->getActiveState()) {
-                  TrigCompositeUtils::addDecisionID(chainId, decisionFeature); // H
-                  ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[H Index] (" << decisionFeature->index() << ") [Chain ID] " << chainId);
-                }
-                TrigCompositeUtils::addDecisionID(chainId, decision); // IM
-                ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[IM Index] (" << decision->index() << ") [Chain ID] " << chainId);
+                  if (teptr->getActiveState()) {
+                    TrigCompositeUtils::addDecisionID(chainId, hNode); // H
+                    ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[H Index] (" << hNode->index() << ") [Chain ID] " << chainId);
+                  }
+                  TrigCompositeUtils::addDecisionID(chainId, imNode); // IM
+                  ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[IM Index] (" << imNode->index() << ") [Chain ID] " << chainId);
 
 
-                tempDecisionVector.push_back(decisionFeature);
+                  tempDecisionVector.push_back(hNode);
 
-                if (kInsert)
-                {
-                  auto mp = std::make_pair(decisionFeature, decision);
-                  ATH_CHECK(addTEfeatures(navDecoder, elemFE, mp, i, &decisionObj));
-                }
-                if ( std::find(begin(mapTEtoDecision[teptr]),end(mapTEtoDecision[teptr]),decisionFeature) == mapTEtoDecision[teptr].end() ) {
-                  mapTEtoDecision[teptr].push_back(decisionFeature); // H
-                }
-                if ( std::find(begin(mapTEtoDecisionActive[teptr]),end(mapTEtoDecisionActive[teptr]),decision) == mapTEtoDecisionActive[teptr].end() ) {
-                  mapTEtoDecisionActive[teptr].push_back(decision); // IM
+                  if (kInsert)
+                  {
+                    auto mp = std::make_pair(hNode, imNode);
+                    ATH_CHECK(addTEfeatures(run2Navigation, elemFE, mp, objectIndex, &decisionObj));
+                  }
+                  ATH_CHECK(insertDecisionToTEMap(hNode, teptr, mapTEtoHNodes));
+                  ATH_CHECK(insertDecisionToTEMap(imNode, teptr, mapTEtoIMNodes));
                 }
-              }
 
-              for (const auto &rNodes : HLT::TrigNavStructure::getRoINodes(teptr))
-              {
-                if (HLT::TrigNavStructure::isRoINode(rNodes))
+                for (const auto& rNodes : HLT::TrigNavStructure::getRoINodes(teptr))
                 {
-                  ///////////////auto vectorROIfeatures_ptr = getROIfeatures(rNodes,navDecoder);
-                  auto vectorROIfeatures_ptr = getTEROIfeatures(rNodes,navDecoder);
-                  for (auto featureRoI : vectorROIfeatures_ptr)
+                  if (HLT::TrigNavStructure::isRoINode(rNodes))
                   {
-                    if (s_iter == first_s_iter)
+                    ///////////////auto vectorROIfeatures_ptr = getROIfeatures(rNodes,run2Navigation);
+                    auto vectorROIfeatures_ptr = getTEROIfeatures(rNodes, run2Navigation);
+                    for (auto featureRoI : vectorROIfeatures_ptr)
                     {
-                      size_t kInsert{0};
-                      auto l1_decision = getL1Object(featureRoI, featureRoI.getIndex().objectsBegin(), decisionOutput, kInsert);
-                      TrigCompositeUtils::addDecisionID(chainId, l1_decision);
-                      if (kInsert)
+                      if (s_iter == first_s_iter)
                       {
-                        ATH_CHECK(addROIfeatures(navDecoder, featureRoI, l1_decision, -1, &l1Obj)); // test coding for initialRoi
-                      }
-                      // check for updated roi
-                      if (mp.empty()) {
-                        ATH_CHECK(addTEROIfeatures(navDecoder, featureRoI, decision)); // roi link to initialRoi
+                        size_t kInsert{ 0 };
+                        auto l1_decision = getL1Object(featureRoI, featureRoI.getIndex().objectsBegin(), decisionOutput, kInsert);
+                        TrigCompositeUtils::addDecisionID(chainId, l1_decision);
+                        if (kInsert)
+                        {
+                          ATH_CHECK(addROIfeatures(run2Navigation, featureRoI, l1_decision, -1, &l1Obj)); // test coding for initialRoi
+                        }
+                        // check for updated roi
+                        if (mp.empty()) {
+                          ATH_CHECK(addTEROIfeatures(run2Navigation, featureRoI, decision)); // roi link to initialRoi
+                        }
+                        TrigCompositeUtils::linkToPrevious(decision, l1_decision, context);
+                        ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[L1 creation] " << "(" << l1_decision->index() << ") [Chain ID] " << chainId);
+                        ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[IM -> L1 seed link] " << "(" << decision->index() << " -> " << l1_decision->index() << ")");
                       }
-                      TrigCompositeUtils::linkToPrevious(decision, l1_decision, context);
-                      ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[L1 creation] " << "(" << l1_decision->index() << ") [Chain ID] " << chainId);
-                      ATH_MSG_DEBUG("REGTEST " << "[TE feature] " << "[IM -> L1 seed link] " << "(" << decision->index() << " -> " << l1_decision->index() << ")");
-                    }
-                    else
-                    {
-                      // check for updated roi
-                      if (mp.empty()) {
-                        ATH_CHECK(addTEROIfeatures(navDecoder, featureRoI, decision)); // roi link to initialRoi
+                      else
+                      {
+                        // check for updated roi
+                        if (mp.empty()) {
+                          ATH_CHECK(addTEROIfeatures(run2Navigation, featureRoI, decision)); // roi link to initialRoi
+                        }
                       }
                     }
-                  }
-                  //### TRACKS ### check for track features and connect the same RoI
-                  if (!vectorROIfeatures_ptr.empty())
-                  for (const auto &elemTRACK : vectorTRACKfeatures_ptr)
-                  {
-                    for (size_t i{elemTRACK.getIndex().objectsBegin()}; i < elemTRACK.getIndex().objectsEnd(); ++i)
-                    {
-                        if (mp.empty()) {
+                    //### TRACKS ### check for track features and connect the same RoI
+                    if (!vectorROIfeatures_ptr.empty())
+                      for (const auto& elemTRACK : vectorTRACKfeatures_ptr)
+                      {
+                        for (size_t i{ elemTRACK.getIndex().objectsBegin() }; i < elemTRACK.getIndex().objectsEnd(); ++i)
+                        {
+                          if (mp.empty()) {
                             ElementLink<TrigRoiDescriptorCollection> ROIElementLink = decision->objectLink<TrigRoiDescriptorCollection>(TrigCompositeUtils::roiString());
                             if (ROIElementLink.isValid())
                             {
-                                ATH_CHECK(addTRACKfeatures(navDecoder, elemTRACK, decision, ROIElementLink));
+                              ATH_CHECK(addTRACKfeatures(run2Navigation, elemTRACK, decision, ROIElementLink));
                             }
+                          }
                         }
-                    }
+                      }
                   }
                 }
               }
-            }
             } // eof if - TE full
 
             decisionLast.insert(decisionLast.end(), tempDecisionVector.begin(), tempDecisionVector.end());
@@ -519,26 +504,26 @@ StatusCode Run2ToRun3TrigNavConverter::execute(const EventContext &context) cons
 
       //for (const auto &last : decisionLast)
       //{
-        if (decisionLast.empty()==false) {
-          auto last = decisionLast.back();
-          auto sf_decision = TrigCompositeUtils::newDecisionIn(decisionOutput);
-          sf_decision->setName("SF");
-          TrigCompositeUtils::addDecisionID(chainId, sf_decision);
-          TrigCompositeUtils::linkToPrevious(sf_decision, last, context);
-          TrigCompositeUtils::linkToPrevious(passRawOutput, sf_decision, context);
-          ATH_MSG_DEBUG("REGTEST " << "[SF creation] " << "(" << sf_decision->index() << ") [Chain ID] " << chainId);
-          ATH_MSG_DEBUG("REGTEST " << "[SF -> H seed link] " << "(" << sf_decision->index() << " -> " << last->index() << ")");
-          ATH_MSG_DEBUG("REGTEST " << "[RAW -> SF seed link] " << "(" << passRawOutput->index() << " -> " << sf_decision->index() << ")");
-        }
+      if (decisionLast.empty() == false) {
+        auto last = decisionLast.back();
+        auto sf_decision = TrigCompositeUtils::newDecisionIn(decisionOutput);
+        sf_decision->setName("SF");
+        TrigCompositeUtils::addDecisionID(chainId, sf_decision);
+        TrigCompositeUtils::linkToPrevious(sf_decision, last, context);
+        TrigCompositeUtils::linkToPrevious(passRawOutput, sf_decision, context);
+        ATH_MSG_DEBUG("REGTEST " << "[SF creation] " << "(" << sf_decision->index() << ") [Chain ID] " << chainId);
+        ATH_MSG_DEBUG("REGTEST " << "[SF -> H seed link] " << "(" << sf_decision->index() << " -> " << last->index() << ")");
+        ATH_MSG_DEBUG("REGTEST " << "[RAW -> SF seed link] " << "(" << passRawOutput->index() << " -> " << sf_decision->index() << ")");
+      }
       //}
-      
+
       TrigCompositeUtils::decisionIDs(passRawOutput).push_back(chainId);
     }
   }
 
 
-  for (auto &[teptr, decisions] : mapTEtoDecisionActive) {
-    if (decisions.size()==1) {
+  for (auto& [teptr, decisions] : mapTEtoIMNodes) {
+    if (decisions.size() == 1) {
       ATH_MSG_DEBUG("TE IMs = " << teptr << " IM Index=" << decisions[0]->index() << " " << decisions);
     }
     else {
@@ -547,8 +532,8 @@ StatusCode Run2ToRun3TrigNavConverter::execute(const EventContext &context) cons
     }
   }
 
-  for (auto &[teptr, decisions] : mapTEtoDecision) {
-    if (decisions.size()==1) {
+  for (auto& [teptr, decisions] : mapTEtoHNodes) {
+    if (decisions.size() == 1) {
       ATH_MSG_DEBUG("TE Hs = " << teptr << " H Index=" << decisions[0]->index() << " " << decisions);
     }
     else {
@@ -557,33 +542,36 @@ StatusCode Run2ToRun3TrigNavConverter::execute(const EventContext &context) cons
     }
   }
 
-  for (auto &[teptr, decisions] : mapTEtoDecisionActive) {
-    for (auto prep_ptr : navDecoder.getDirectPredecessors(teptr)) {
+  for (auto& [teptr, decisions] : mapTEtoIMNodes) {
+    for (auto prep_ptr : run2Navigation.getDirectPredecessors(teptr)) {
       ATH_MSG_DEBUG("TE predTE (from IM) = " << teptr << " " << prep_ptr);
     }
   }
 
   std::set<std::string> regtestSorted;
-  for (auto &[teptr, decisions] : mapTEtoDecisionActive)
+  for (auto& [tePtr, imNodes] : mapTEtoIMNodes)
   { // loop over all IM nodes
 
-    for (auto prep_ptr : navDecoder.getDirectPredecessors(teptr))
+    for (auto predtePtr : run2Navigation.getDirectPredecessors(tePtr))
     {
-      if (teptr != prep_ptr)
-      if (mapTEtoDecision.find(prep_ptr) != mapTEtoDecision.end())
-      {
-        for (auto& d : decisions)
-        { // this is IM loop
-          ATH_MSG_DEBUG("TE predTE linking pre = " << teptr << " " << prep_ptr << " " << d);
-          for (auto& pd : mapTEtoDecision[prep_ptr])
-          { // this is H loop
-            TrigCompositeUtils::linkToPrevious(d, pd, context);
-            ATH_MSG_DEBUG("TE predTE linking IM lower H upper = " << teptr << " " << prep_ptr << " " << d << " " << pd);
-            regtestSorted.insert("REGTEST [IM -> H seed link] (" + std::to_string(d->index()) + " -> " + std::to_string(pd->index()) + ")");
+      if (tePtr != predtePtr)
+        if (mapTEtoHNodes.find(predtePtr) != mapTEtoHNodes.end())
+        {
+          for (auto& imNode : imNodes)
+          { // this is IM loop
+            ATH_MSG_DEBUG("TE corresponding to IM = "
+              << tePtr << " " << hash2string[tePtr->getId()]
+              << " seeded by TE " << predtePtr << " " << hash2string[predtePtr->getId()]
+              << " IM node " << imNode);
+            for (auto& hNode : mapTEtoHNodes[predtePtr])
+            { // this is H loop
+              TrigCompositeUtils::linkToPrevious(imNode, hNode, context);
+              ATH_MSG_DEBUG("TE predTE linking IM lower H upper = " << tePtr << " " << predtePtr << " " << imNode << " " << hNode);
+              regtestSorted.insert("REGTEST [IM -> H seed link] (" + std::to_string(imNode->index()) + " -> " + std::to_string(hNode->index()) + ")");
+            }
           }
         }
-      }
-    } // for (auto prep_ptr : navDecoder....
+    } // for (auto prep_ptr : run2Navigation....
   }
   for (const auto& p : regtestSorted) {
     ATH_MSG_DEBUG(p);
@@ -613,23 +601,23 @@ std::tuple<uint32_t, CLID, std::string> Run2ToRun3TrigNavConverter::getSgKey(con
   }
 
   const auto sgStringKey = HLTNavDetails::formatSGkey("HLT", type_name, hltLabel);
-  const bool isAvailable = evtStore()->contains( saveCLID,  sgStringKey);
-  ATH_MSG_DEBUG(" Objects presence " << helper << " " << sgStringKey <<  (isAvailable? " present" : " absent"));
-  if ( ! isAvailable ) {
+  const bool isAvailable = evtStore()->contains(saveCLID, sgStringKey);
+  ATH_MSG_DEBUG(" Objects presence " << helper << " " << sgStringKey << (isAvailable ? " present" : " absent"));
+  if (!isAvailable) {
     return { 0, 0, "" };
   }
 
   const auto sgIntKey = evtStore()->stringToKey(sgStringKey, saveCLID);
 
-  ATH_MSG_DEBUG(" getSgKey: sgKey, sgCLID, sgName " << sgIntKey << " " <<  saveCLID << " " << hltLabel);
+  ATH_MSG_DEBUG(" getSgKey: sgKey, sgCLID, sgName " << sgIntKey << " " << saveCLID << " " << hltLabel);
   return { sgIntKey, saveCLID, hltLabel }; // sgKey, sgCLID, sgName
 }
 
 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ addTEROIfeatures @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-StatusCode Run2ToRun3TrigNavConverter::addTEROIfeatures(const HLT::TrigNavStructure &navigationDecoder, const HLT::TriggerElement::FeatureAccessHelper &helper, TrigCompositeUtils::Decision *&decisionPtr) const
+StatusCode Run2ToRun3TrigNavConverter::addTEROIfeatures(const HLT::TrigNavStructure& navigationDecoder, const HLT::TriggerElement::FeatureAccessHelper& helper, TrigCompositeUtils::Decision*& decisionPtr) const
 {
   auto [sgKey, sgCLID, sgName] = getSgKey(navigationDecoder, helper);
-  ATH_MSG_DEBUG("In addTEROIfeatures sgKey, sgCLID, sgName index-begin " << sgKey << " " <<  sgCLID << " " << sgName << " " << helper.getIndex().objectsBegin());
+  ATH_MSG_DEBUG("In addTEROIfeatures sgKey, sgCLID, sgName index-begin " << sgKey << " " << sgCLID << " " << sgName << " " << helper.getIndex().objectsBegin());
   if (sgKey != 0) {
     decisionPtr->typelessSetObjectLink(TrigCompositeUtils::roiString(), sgKey, sgCLID, helper.getIndex().objectsBegin());
   }
@@ -638,7 +626,7 @@ StatusCode Run2ToRun3TrigNavConverter::addTEROIfeatures(const HLT::TrigNavStruct
 }
 
 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ addROIfeatures @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-StatusCode Run2ToRun3TrigNavConverter::addROIfeatures(const HLT::TrigNavStructure &navigationDecoder, const HLT::TriggerElement::FeatureAccessHelper &helper, TrigCompositeUtils::Decision *&decisionPtr, int idx, L1ObjMap *om) const
+StatusCode Run2ToRun3TrigNavConverter::addROIfeatures(const HLT::TrigNavStructure& navigationDecoder, const HLT::TriggerElement::FeatureAccessHelper& helper, TrigCompositeUtils::Decision*& decisionPtr, int idx, L1ObjMap* om) const
 {
   auto [sgKey, sgCLID, sgName] = getSgKey(navigationDecoder, helper);
 
@@ -662,21 +650,21 @@ StatusCode Run2ToRun3TrigNavConverter::addROIfeatures(const HLT::TrigNavStructur
 }
 
 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ addTRACKfeatures @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-StatusCode Run2ToRun3TrigNavConverter::addTRACKfeatures(const HLT::TrigNavStructure &navigationDecoder, const HLT::TriggerElement::FeatureAccessHelper &helper, TrigCompositeUtils::Decision *&decisionPtr, ElementLink<TrigRoiDescriptorCollection> &rLink) const
+StatusCode Run2ToRun3TrigNavConverter::addTRACKfeatures(const HLT::TrigNavStructure& navigationDecoder, const HLT::TriggerElement::FeatureAccessHelper& helper, TrigCompositeUtils::Decision*& decisionPtr, ElementLink<TrigRoiDescriptorCollection>& rLink) const
 {
   SG::AuxElement::Decorator<ElementLink<TrigRoiDescriptorCollection>> viewBookkeeper("viewIndex");
   auto [sgKey, sgCLID, sgName] = getSgKey(navigationDecoder, helper);
   ATH_MSG_DEBUG("sgKey, sgCLID, sgName " << sgKey << " " << sgCLID << " " << sgName);
-  if (decisionPtr != nullptr && sgCLID==1287425431) // CLASS_DEF( xAOD::TrackParticleContainer, 1287425431, 1 )
+  if (decisionPtr != nullptr && sgCLID == 1287425431) // CLASS_DEF( xAOD::TrackParticleContainer, 1287425431, 1 )
   {
     decisionPtr->typelessSetObjectLink("TEMP_TRACKS", sgKey, sgCLID, helper.getIndex().objectsBegin(), helper.getIndex().objectsEnd());
     ElementLinkVector<xAOD::TrackParticleContainer> tracks = decisionPtr->objectCollectionLinks<xAOD::TrackParticleContainer>("TEMP_TRACKS");
     decisionPtr->removeObjectCollectionLinks("TEMP_TRACKS");
-    for (const ElementLink<xAOD::TrackParticleContainer> &track : tracks)
+    for (const ElementLink<xAOD::TrackParticleContainer>& track : tracks)
     {
       if (track.isValid())
       {
-        const xAOD::TrackParticle *t = *track;
+        const xAOD::TrackParticle* t = *track;
         viewBookkeeper(*t) = rLink;
       }
     }
@@ -685,7 +673,7 @@ StatusCode Run2ToRun3TrigNavConverter::addTRACKfeatures(const HLT::TrigNavStruct
 }
 
 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ addTEfeatures @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-StatusCode Run2ToRun3TrigNavConverter::addTEfeatures(const HLT::TrigNavStructure &navigationDecoder, const HLT::TriggerElement::FeatureAccessHelper &helper, std::pair<TrigCompositeUtils::Decision *, TrigCompositeUtils::Decision *> &decisionPtr, int idx, DecisionObjMap *om) const
+StatusCode Run2ToRun3TrigNavConverter::addTEfeatures(const HLT::TrigNavStructure& navigationDecoder, const HLT::TriggerElement::FeatureAccessHelper& helper, std::pair<TrigCompositeUtils::Decision*, TrigCompositeUtils::Decision*>& decisionPtr, int idx, DecisionObjMap* om) const
 {
   auto [sgKey, sgCLID, sgName] = getSgKey(navigationDecoder, helper);
 
@@ -707,7 +695,7 @@ StatusCode Run2ToRun3TrigNavConverter::addTEfeatures(const HLT::TrigNavStructure
 }
 
 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ getTEfeatures @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-const std::vector<HLT::TriggerElement::FeatureAccessHelper> Run2ToRun3TrigNavConverter::getTEfeatures(const HLT::TriggerElement *te_ptr, const HLT::TrigNavStructure &navigationDecoder, bool filterOnCLID) const
+const std::vector<HLT::TriggerElement::FeatureAccessHelper> Run2ToRun3TrigNavConverter::getTEfeatures(const HLT::TriggerElement* te_ptr, const HLT::TrigNavStructure& navigationDecoder, bool filterOnCLID) const
 {
   std::vector<HLT::TriggerElement::FeatureAccessHelper> ptrFAHelper;
   for (HLT::TriggerElement::FeatureAccessHelper helper : te_ptr->getFeatureAccessHelpers())
@@ -723,11 +711,11 @@ const std::vector<HLT::TriggerElement::FeatureAccessHelper> Run2ToRun3TrigNavCon
 }
 
 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ getTEROIfeatures @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-const std::vector<HLT::TriggerElement::FeatureAccessHelper> Run2ToRun3TrigNavConverter::getTEROIfeatures(const HLT::TriggerElement *te_ptr, const HLT::TrigNavStructure &navigationDecoder) const
+const std::vector<HLT::TriggerElement::FeatureAccessHelper> Run2ToRun3TrigNavConverter::getTEROIfeatures(const HLT::TriggerElement* te_ptr, const HLT::TrigNavStructure& navigationDecoder) const
 {
   // @@@@@@@@@@@@@@@@@@@@@@@@@@ ordered_sorter @@@@@@@@@@@@@@@@@@@@@@@@@@
   auto ordered_sorter = [&](const auto& left, const auto& right) -> bool {
-      return std::find(cbegin(m_setRoiName), cend(m_setRoiName), left) < std::find(cbegin(m_setRoiName), cend(m_setRoiName), right);
+    return std::find(cbegin(m_setRoiName), cend(m_setRoiName), left) < std::find(cbegin(m_setRoiName), cend(m_setRoiName), right);
   };
 
   std::map<std::string, HLT::TriggerElement::FeatureAccessHelper, decltype(ordered_sorter)> mp(ordered_sorter);
@@ -735,30 +723,30 @@ const std::vector<HLT::TriggerElement::FeatureAccessHelper> Run2ToRun3TrigNavCon
 
   for (HLT::TriggerElement::FeatureAccessHelper helper : te_ptr->getFeatureAccessHelpers())
   {
-    auto [sgKey, sgCLID, sgName] = getSgKey(navigationDecoder,helper);
+    auto [sgKey, sgCLID, sgName] = getSgKey(navigationDecoder, helper);
     ATH_MSG_DEBUG(" getTEROIfeatures name " << sgName);
-       if (std::find(m_setRoiName.begin(), m_setRoiName.end(), sgName) == m_setRoiName.end()) {
-       // do not filter continue;
-       continue;
-       }
-       ATH_MSG_DEBUG(" getTEROIfeatures name accepted " << sgName);
-      mp[sgName] = helper;
+    if (std::find(m_setRoiName.begin(), m_setRoiName.end(), sgName) == m_setRoiName.end()) {
+      // do not filter continue;
+      continue;
+    }
+    ATH_MSG_DEBUG(" getTEROIfeatures name accepted " << sgName);
+    mp[sgName] = helper;
   }
 
   for (const auto& p : mp) {
-    auto [sgKey, sgCLID, sgName] = getSgKey(navigationDecoder,p.second);
+    auto [sgKey, sgCLID, sgName] = getSgKey(navigationDecoder, p.second);
     ATH_MSG_DEBUG("CHECK getTEROIfeatures name accepted " << sgName);
   }
 
   std::vector<HLT::TriggerElement::FeatureAccessHelper> ptrFAHelper;
-  std::transform(cbegin(mp),cend(mp),back_inserter(ptrFAHelper),
-  [](const std::map<std::string, HLT::TriggerElement::FeatureAccessHelper>::value_type& p ){return p.second;});
+  std::transform(cbegin(mp), cend(mp), back_inserter(ptrFAHelper),
+    [](const std::map<std::string, HLT::TriggerElement::FeatureAccessHelper>::value_type& p) {return p.second;});
 
   return ptrFAHelper;
 }
 
 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ getTRACKfeatures @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-const std::vector<HLT::TriggerElement::FeatureAccessHelper> Run2ToRun3TrigNavConverter::getTRACKfeatures(const HLT::TriggerElement *te_ptr) const
+const std::vector<HLT::TriggerElement::FeatureAccessHelper> Run2ToRun3TrigNavConverter::getTRACKfeatures(const HLT::TriggerElement* te_ptr) const
 {
   std::vector<HLT::TriggerElement::FeatureAccessHelper> ptrFAHelper;
   for (HLT::TriggerElement::FeatureAccessHelper helper : te_ptr->getFeatureAccessHelpers())
@@ -772,7 +760,7 @@ const std::vector<HLT::TriggerElement::FeatureAccessHelper> Run2ToRun3TrigNavCon
 }
 
 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ getROIfeatures @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-const std::vector<HLT::TriggerElement::FeatureAccessHelper> Run2ToRun3TrigNavConverter::getROIfeatures(const HLT::TriggerElement *te_ptr, const HLT::TrigNavStructure &navigationDecoder) const
+const std::vector<HLT::TriggerElement::FeatureAccessHelper> Run2ToRun3TrigNavConverter::getROIfeatures(const HLT::TriggerElement* te_ptr, const HLT::TrigNavStructure& navigationDecoder) const
 {
 
   std::vector<HLT::TriggerElement::FeatureAccessHelper> ptrFAHelper;
@@ -791,7 +779,7 @@ const std::vector<HLT::TriggerElement::FeatureAccessHelper> Run2ToRun3TrigNavCon
 }
 
 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ printFeatures @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-StatusCode Run2ToRun3TrigNavConverter::printFeatures(const HLT::TrigNavStructure &nav) const
+StatusCode Run2ToRun3TrigNavConverter::printFeatures(const HLT::TrigNavStructure& nav) const
 {
   std::set<std::string> totset;
 
@@ -802,7 +790,7 @@ StatusCode Run2ToRun3TrigNavConverter::printFeatures(const HLT::TrigNavStructure
     {
       for (auto configTE : signature->outputTEs())
       {
-        std::vector<HLT::TriggerElement *> tes;
+        std::vector<HLT::TriggerElement*> tes;
         nav.getAllOfType(configTE->id(), tes, false);
         for (auto te : tes)
         {
@@ -828,3 +816,12 @@ StatusCode Run2ToRun3TrigNavConverter::printFeatures(const HLT::TrigNavStructure
 
   return StatusCode::SUCCESS;
 }
+
+
+StatusCode  Run2ToRun3TrigNavConverter::insertDecisionToTEMap( TrigCompositeUtils::Decision* d, const HLT::TriggerElement* te, TEDecisionMap& mapToFill) const { 
+  auto& entryToFill = mapToFill[te];
+  auto iter = std::find(entryToFill.begin(), entryToFill.end(), d);
+  if (iter == entryToFill.end() )
+    entryToFill.push_back(d);
+  return StatusCode::SUCCESS;
+}
diff --git a/Trigger/TrigEvent/TrigNavTools/src/Run2ToRun3TrigNavConverter.h b/Trigger/TrigEvent/TrigNavTools/src/Run2ToRun3TrigNavConverter.h
index cf40997e583e..0992eda6d664 100644
--- a/Trigger/TrigEvent/TrigNavTools/src/Run2ToRun3TrigNavConverter.h
+++ b/Trigger/TrigEvent/TrigNavTools/src/Run2ToRun3TrigNavConverter.h
@@ -68,6 +68,9 @@ private:
     using FElessObjMap = std::map<TrigCompositeUtils::Decision*,std::pair<TrigCompositeUtils::Decision*,const HLT::TriggerElement*>>; // decisionFeature-H no FE ->, decision,TEptr
     using L1ObjMap = std::map<uint32_t,TrigCompositeUtils::Decision*>; // L1decision
     using TEMap = std::map<const HLT::TriggerElement*, bool>; // map of TEs (true FE, false FE-less)
+    using TEDecisionMap = std::map<const HLT::TriggerElement*, std::vector<TrigCompositeUtils::Decision*>>;
+
+
 
     std::tuple<uint32_t,CLID,std::string> getSgKey(const HLT::TrigNavStructure &navigationDecoder, const HLT::TriggerElement::FeatureAccessHelper& helper) const;
     StatusCode addTEfeatures(const HLT::TrigNavStructure &navigationDecoder, const HLT::TriggerElement::FeatureAccessHelper& helper, DecisionPair&  decisionPtr, int idx, DecisionObjMap* om) const;
@@ -79,6 +82,8 @@ private:
     const std::vector<HLT::TriggerElement::FeatureAccessHelper> getROIfeatures(const HLT::TriggerElement *te_ptr, const HLT::TrigNavStructure &navigationDecoder) const;
     const std::vector<HLT::TriggerElement::FeatureAccessHelper> getTRACKfeatures(const HLT::TriggerElement *te_ptr) const;
 
+    StatusCode insertDecisionToTEMap( TrigCompositeUtils::Decision* d, const HLT::TriggerElement* te, TEDecisionMap& mapToFill) const;
+
 
     CLID m_roIDescriptorCLID { 0 };
     CLID m_roIDescriptorCollectionCLID { 0 };
@@ -92,7 +97,6 @@ private:
     CLID m_TauTrackContainerCLID { 0 };
 
 
-    using TE_Decision_map = std::map<HLT::TriggerElement*, std::vector<TrigCompositeUtils::Decision*>>;
     StatusCode printFeatures(const HLT::TrigNavStructure& ) const;
 };
 
-- 
GitLab