diff --git a/Control/AthenaMonitoring/python/AthMonitorCfgHelper.py b/Control/AthenaMonitoring/python/AthMonitorCfgHelper.py
index 227b9d99cb2dc10ddf8b990a9ee3ae36b13576dd..955aeb00492a2f92cdcc694debe122cd4c11bae1 100644
--- a/Control/AthenaMonitoring/python/AthMonitorCfgHelper.py
+++ b/Control/AthenaMonitoring/python/AthMonitorCfgHelper.py
@@ -146,7 +146,7 @@ class AthMonitorCfgHelper(object):
         Finalize the creation of the set of monitoring algorithms.
 
         Returns:
-        (resobj, monSeq) -- a tuple with a ComponentAccumulator and an AthSequencer
+        resobj -- a ComponentAccumulator 
         '''
         self.resobj.addSequence(self.monSeq)
         return self.resobj
diff --git a/Control/AthenaMonitoringKernel/AthenaMonitoringKernel/GenericMonitoringTool.h b/Control/AthenaMonitoringKernel/AthenaMonitoringKernel/GenericMonitoringTool.h
index b152e39e4b5b91f525e46da4f454deb27e3bc8cb..f643f8b31e4606f41b720eaa103bf857bee3b9a2 100644
--- a/Control/AthenaMonitoringKernel/AthenaMonitoringKernel/GenericMonitoringTool.h
+++ b/Control/AthenaMonitoringKernel/AthenaMonitoringKernel/GenericMonitoringTool.h
@@ -72,7 +72,8 @@ public:
   virtual uint32_t lumiBlock();
 
 private:
-
+  void invokeFillersDebug(const std::shared_ptr<Monitored::HistogramFiller>& filler,
+                          const std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>>& monitoredVariables) const;
   
   /// THistSvc (do NOT fix the service type (only the name) to allow for a different implementation online
   ServiceHandle<ITHistSvc> m_histSvc { this, "THistSvc", "THistSvc", "Histogramming svc" };
@@ -83,9 +84,9 @@ private:
   BooleanProperty m_useCache { this, "UseCache", true, "Cache filler lookups" };
 
   std::vector<std::shared_ptr<Monitored::HistogramFiller>> m_fillers; //!< plain list of fillers
-  mutable std::mutex m_fillMutex;
-  mutable Monitored::HistogramFiller::VariablesPack m_vars ATLAS_THREAD_SAFE;
-  mutable std::map<std::vector<std::string>,std::vector<std::shared_ptr<Monitored::HistogramFiller>>,std::less<>> m_fillerCacheMap ATLAS_THREAD_SAFE; //!< lookup map to speed up filler searches
+  mutable std::map<std::vector<std::string>,std::unique_ptr<std::vector<std::shared_ptr<Monitored::HistogramFiller>>>,std::less<>> m_fillerCacheMap ATLAS_THREAD_SAFE; //!< lookup map to speed up filler searches
+  mutable std::mutex m_cacheMutex;
+
 };
 
 /**
diff --git a/Control/AthenaMonitoringKernel/AthenaMonitoringKernel/HistogramFiller.h b/Control/AthenaMonitoringKernel/AthenaMonitoringKernel/HistogramFiller.h
index 7e9e7e8c8e71e078f305f84c1e0e27f0a1292928..0a074d164ac39f11d1c418da088b1c38db0d7722 100644
--- a/Control/AthenaMonitoringKernel/AthenaMonitoringKernel/HistogramFiller.h
+++ b/Control/AthenaMonitoringKernel/AthenaMonitoringKernel/HistogramFiller.h
@@ -129,6 +129,10 @@ namespace Monitored {
       return m_histDef->cutMask;
     }
 
+    const std::unique_lock<std::mutex> getLock() const {
+      return std::unique_lock(m_lock);
+    }
+
   protected:
     template <class H>
     H* histogram() const {
@@ -179,6 +183,7 @@ namespace Monitored {
 
     std::shared_ptr<HistogramDef> m_histDef;
     std::shared_ptr<IHistogramProvider> m_histogramProvider;
+    mutable std::mutex m_lock;
 
   private:
     HistogramFiller& operator=(HistogramFiller const&) = delete;
diff --git a/Control/AthenaMonitoringKernel/src/GenericMonitoringTool.cxx b/Control/AthenaMonitoringKernel/src/GenericMonitoringTool.cxx
index ea0575f4a1001711d7f6385c6380f569f6451e2e..cafa55610621caea1296aa5a6147e0bfa907f3ca 100644
--- a/Control/AthenaMonitoringKernel/src/GenericMonitoringTool.cxx
+++ b/Control/AthenaMonitoringKernel/src/GenericMonitoringTool.cxx
@@ -125,37 +125,48 @@ namespace std {
   }
 }
 
+namespace {
+  // this exists to avoid reallocating memory on every invokeFillers call
+  thread_local Monitored::HistogramFiller::VariablesPack tl_vars ATLAS_THREAD_SAFE;
+}
+
 void GenericMonitoringTool::invokeFillers(const std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>>& monitoredVariables) const {
-  std::scoped_lock guard(m_fillMutex);
   // This is the list of fillers to consider in the invocation.
   // If we are using the cache then this may be a proper subset of m_fillers; otherwise will just be m_fillers
   const std::vector<std::shared_ptr<Monitored::HistogramFiller>>* fillerList{nullptr};
   // do we need to update the cache?
   bool makeCache = false;
-  // list of matched fillers, if we need to update the cache
-  std::vector<std::shared_ptr<Monitored::HistogramFiller>> matchedFillerList;
+  // pointer to list of matched fillers, if we need to update the cache (default doesn't create the vector)
+  std::unique_ptr<std::vector<std::shared_ptr<Monitored::HistogramFiller>>> matchedFillerList;
   if (m_useCache) {
+    // lock the cache during lookup
+    std::scoped_lock cacheguard(m_cacheMutex);
     const auto match = m_fillerCacheMap.find(monitoredVariables);
     if (match != m_fillerCacheMap.end()) {
-      fillerList = &(match->second);
+      fillerList = match->second.get();
     } else {
       fillerList = &m_fillers;
+      matchedFillerList = std::make_unique<std::vector<std::shared_ptr<Monitored::HistogramFiller>>>();
       makeCache = true;
     }
   } else {
     fillerList = &m_fillers;
   }
+
   for ( auto filler: *fillerList ) {
-    m_vars.reset();
+    tl_vars.reset();
     const int fillerCardinality = filler->histogramVariablesNames().size() + (filler->histogramWeightName().empty() ? 0: 1) + (filler->histogramCutMaskName().empty() ? 0 : 1);
 
     if ( fillerCardinality == 1 ) { // simplest case, optimising this to be super fast
       for ( auto& var: monitoredVariables ) {
         if ( var.get().name().compare( filler->histogramVariablesNames()[0] ) == 0 )  {
-          m_vars.var[0] = &var.get();
-          filler->fill( m_vars );
+          tl_vars.var[0] = &var.get();
+          {
+            auto guard{filler->getLock()};
+            filler->fill( tl_vars );
+          }
           if (makeCache) { 
-            matchedFillerList.push_back(filler); 
+            matchedFillerList->push_back(filler); 
           }
           break;
         }
@@ -166,7 +177,7 @@ void GenericMonitoringTool::invokeFillers(const std::vector<std::reference_wrapp
         bool matched = false;
         for ( unsigned fillerVarIndex = 0; fillerVarIndex < filler->histogramVariablesNames().size(); ++fillerVarIndex ) {
           if ( var.get().name().compare( filler->histogramVariablesNames()[fillerVarIndex] ) == 0 ) {
-            m_vars.set(fillerVarIndex, &var.get());
+            tl_vars.set(fillerVarIndex, &var.get());
             matched = true;
             matchesCount++;
             break;
@@ -175,51 +186,65 @@ void GenericMonitoringTool::invokeFillers(const std::vector<std::reference_wrapp
         if ( matchesCount == fillerCardinality ) break;
         if ( not matched ) { // may be a weight or cut variable still
           if ( var.get().name().compare( filler->histogramWeightName() ) == 0 )  {
-            m_vars.weight = &var.get();
+            tl_vars.weight = &var.get();
             matchesCount ++;
           } else if ( var.get().name().compare( filler->histogramCutMaskName() ) == 0 )  {
-            m_vars.cut = &var.get();
+            tl_vars.cut = &var.get();
             matchesCount++;
          }
         }
         if ( matchesCount == fillerCardinality ) break;
       }
       if ( matchesCount == fillerCardinality ) {
-        filler->fill( m_vars );
+        {
+          auto guard{filler->getLock()};
+          filler->fill( tl_vars );
+        }
         if (makeCache) { 
-          matchedFillerList.push_back(filler); 
+          matchedFillerList->push_back(filler); 
         }
       } else if ( ATH_UNLIKELY( matchesCount != 0 ) ) { // something has matched, but not all, worth informing user
-        bool reasonFound = false;
-        if (ATH_UNLIKELY(!filler->histogramWeightName().empty() && !m_vars.weight)) {
-          reasonFound = true;
-          ATH_MSG_DEBUG("Filler weight not found in monitoredVariables:"
-            << "\n  Filler weight               : " << filler->histogramWeightName()
-            << "\n  Asked to fill from mon. vars: " << monitoredVariables);
-        }
-        if (ATH_UNLIKELY(!filler->histogramCutMaskName().empty() && !m_vars.cut)) {
-          reasonFound = true;
-          ATH_MSG_DEBUG("Filler cut mask not found in monitoredVariables:"
-            << "\n  Filler cut mask             : " << filler->histogramCutMaskName()
-            << "\n  Asked to fill from mon. vars: " << monitoredVariables);
-        }
-        if ( not reasonFound ) {
-          ATH_MSG_DEBUG("Filler has different variables than monitoredVariables:"
-            << "\n  Filler variables            : " << filler->histogramVariablesNames()
-            << "\n  Asked to fill from mon. vars: " << monitoredVariables
-            << "\n  Selected monitored variables: " << m_vars.names() );
-        }
+        invokeFillersDebug(filler, monitoredVariables);
       }
     }
   }
 
   if (makeCache) {
-    std::vector<std::string> key;
-    key.reserve(monitoredVariables.size());
-    for (const auto& mv : monitoredVariables) {
-      key.push_back(mv.get().name());
+    // we may hit this multiple times. If another thread has updated the cache in the meanwhile, don't update
+    // (or we might delete the fillerList under another thread)
+    std::scoped_lock cacheguard(m_cacheMutex);
+    const auto match = m_fillerCacheMap.find(monitoredVariables);
+    if (match == m_fillerCacheMap.end()) {
+      std::vector<std::string> key;
+      key.reserve(monitoredVariables.size());
+      for (const auto& mv : monitoredVariables) {
+        key.push_back(mv.get().name());
+      }
+      m_fillerCacheMap[key].swap(matchedFillerList);
     }
-    m_fillerCacheMap[key] = matchedFillerList;
+  }
+}
+
+void GenericMonitoringTool::invokeFillersDebug(const std::shared_ptr<Monitored::HistogramFiller>& filler,
+                                               const std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>>& monitoredVariables) const {
+  bool reasonFound = false;
+  if (ATH_UNLIKELY(!filler->histogramWeightName().empty() && !tl_vars.weight)) {
+    reasonFound = true;
+    ATH_MSG_DEBUG("Filler weight not found in monitoredVariables:"
+      << "\n  Filler weight               : " << filler->histogramWeightName()
+      << "\n  Asked to fill from mon. tl_vars: " << monitoredVariables);
+  }
+  if (ATH_UNLIKELY(!filler->histogramCutMaskName().empty() && !tl_vars.cut)) {
+    reasonFound = true;
+    ATH_MSG_DEBUG("Filler cut mask not found in monitoredVariables:"
+      << "\n  Filler cut mask             : " << filler->histogramCutMaskName()
+      << "\n  Asked to fill from mon. tl_vars: " << monitoredVariables);
+  }
+  if ( not reasonFound ) {
+    ATH_MSG_DEBUG("Filler has different variables than monitoredVariables:"
+      << "\n  Filler variables            : " << filler->histogramVariablesNames()
+      << "\n  Asked to fill from mon. tl_vars: " << monitoredVariables
+      << "\n  Selected monitored variables: " << tl_vars.names() );
   }
 }
 
diff --git a/Database/IOVDbSvc/python/CondDB.py b/Database/IOVDbSvc/python/CondDB.py
index 9dd4aebc60b7449e7135d2a67be33db2de67a881..8f78b362cffd0088335b58dea632e75ea419dbcc 100644
--- a/Database/IOVDbSvc/python/CondDB.py
+++ b/Database/IOVDbSvc/python/CondDB.py
@@ -314,6 +314,9 @@ This allows the possibility of later adding a new IOV using IOVSvc::setRange."""
                 if (ix2!=-1):
                     xmltag=(folderstr[ix+1:ix2]).strip()
                     ix=ix2+1
+                    if xmltag[-1] == '/':
+                        xmltag=""
+                        ix=ix+1
             elif (folderstr[ix:ix+2]=='</' and xmltag!=""):
                 ix2=folderstr.find('>',ix)
                 if (ix2!=-1):
diff --git a/Event/xAOD/xAODMissingET/Root/MissingETAssociationMap_v1.cxx b/Event/xAOD/xAODMissingET/Root/MissingETAssociationMap_v1.cxx
index f3169e7bd1353626f3ac78437a34beb1b6fc8397..b7c030203a55fcf8d72967c75356a06db06cb58d 100644
--- a/Event/xAOD/xAODMissingET/Root/MissingETAssociationMap_v1.cxx
+++ b/Event/xAOD/xAODMissingET/Root/MissingETAssociationMap_v1.cxx
@@ -5,6 +5,7 @@
 #include "xAODMissingET/versions/MissingETAssociationMap_v1.h"
 
 #include "xAODTracking/TrackParticle.h"
+#include "xAODPFlow/FlowElement.h"
 #include "xAODJet/JetAttributes.h"
 
 #include "xAODBase/IParticleContainer.h"
@@ -222,6 +223,7 @@ const xAOD::IParticleContainer* MissingETAssociationMap_v1::getUniqueSignals(con
       else {continue;}
     case MissingETBase::UsageHandler::ParticleFlow:
       if((*iSig)->type()==xAOD::Type::ParticleFlow) {break;}
+      else if((*iSig)->type()==xAOD::Type::FlowElement && ((static_cast<const xAOD::FlowElement*>(*iSig))->signalType() & xAOD::FlowElement::PFlow)) {break;}
       else {continue;}
     case MissingETBase::UsageHandler::TruthParticle:
       if((*iSig)->type()==xAOD::Type::TruthParticle) {break;}
@@ -229,7 +231,7 @@ const xAOD::IParticleContainer* MissingETAssociationMap_v1::getUniqueSignals(con
     case MissingETBase::UsageHandler::AllCalo:
       if((*iSig)->type()!=xAOD::Type::TrackParticle) {break;}
       else {continue;}
-    default: continue;
+    default: {continue;}
     }
 
     size_t assocIndex = findIndexByJetConst(*iSig);
diff --git a/Event/xAOD/xAODMissingET/Root/MissingETAssociation_v1.cxx b/Event/xAOD/xAODMissingET/Root/MissingETAssociation_v1.cxx
index ca0755adeb1db6bac4ae679e7ac88d724dcc9dbf..7b15541dee16289431eb641dfdb797c5818af885 100644
--- a/Event/xAOD/xAODMissingET/Root/MissingETAssociation_v1.cxx
+++ b/Event/xAOD/xAODMissingET/Root/MissingETAssociation_v1.cxx
@@ -7,6 +7,7 @@
 #include "xAODJet/JetContainer.h"
 #include "xAODTruth/TruthParticle.h"
 #include "xAODPFlow/PFO.h"
+#include "xAODPFlow/FlowElement.h"
 
 #include <iterator>
 #include <cstdio>
@@ -138,32 +139,32 @@ namespace xAOD {
     // found - add const vectors
     if ( idx != MissingETBase::Numerical::invalidIndex() )
       { 
-	m_objConstLinks[idx].clear();
-	m_objConstLinks[idx].reserve(constlist.size());
-	for(const auto& signal : constlist) {
-	  const IParticleContainer* pCont = static_cast<const IParticleContainer*>(signal->container());
-	  MissingETBase::Types::objlink_t el(*pCont,signal->index());
-	  m_objConstLinks[idx].push_back(el);
-	}
-	return false; }
+        m_objConstLinks[idx].clear();
+        m_objConstLinks[idx].reserve(constlist.size());
+        for(const auto& signal : constlist) {
+          const IParticleContainer* pCont = static_cast<const IParticleContainer*>(signal->container());
+          MissingETBase::Types::objlink_t el(*pCont,signal->index());
+          m_objConstLinks[idx].push_back(el);
+        }
+        return false; }
     // new object
     else
       {
-	MissingETBase::Types::objlink_t oLnk; f_setObject<IParticle,MissingETBase::Types::objlink_t>(pPart,oLnk); 
-	// add to stores
-	this->f_objectLinks().push_back(oLnk);
-	vector<MissingETBase::Types::objlink_t > linklist;
-	linklist.reserve(constlist.size());
-	for(const auto& signal : constlist) {
-	  const IParticleContainer* pCont = static_cast<const IParticleContainer*>(signal->container());
-	  MissingETBase::Types::objlink_t el(*pCont,signal->index());
-	  linklist.push_back(el);
-	}
-	m_objConstLinks.push_back(linklist);
-	this->f_overlapIndices().push_back(vector<size_t>(0));
-	this->f_overlapTypes().push_back(vector<unsigned char>(0));
-	bool linkset = f_setLink<MissingETBase::Types::objlink_t>(oLnk);
-	return linkset;
+        MissingETBase::Types::objlink_t oLnk; f_setObject<IParticle,MissingETBase::Types::objlink_t>(pPart,oLnk); 
+        // add to stores
+        this->f_objectLinks().push_back(oLnk);
+        vector<MissingETBase::Types::objlink_t > linklist;
+        linklist.reserve(constlist.size());
+        for(const auto& signal : constlist) {
+          const IParticleContainer* pCont = static_cast<const IParticleContainer*>(signal->container());
+          MissingETBase::Types::objlink_t el(*pCont,signal->index());
+          linklist.push_back(el);
+        }
+        m_objConstLinks.push_back(linklist);
+        this->f_overlapIndices().push_back(vector<size_t>(0));
+        this->f_overlapTypes().push_back(vector<unsigned char>(0));
+        bool linkset = f_setLink<MissingETBase::Types::objlink_t>(oLnk);
+        return linkset;
       }
   }
 
@@ -173,7 +174,7 @@ namespace xAOD {
   //   static SG::AuxElement::Accessor<MissingETBase::Types::objlink_vector_t> acc("objectLinks");
   //   if(acc.isAvailableWritable(*this)) {
   //     for ( auto& link : this->f_objectLinks() ) { 
-  // 	link.toPersistent();
+  //         link.toPersistent();
   //     } 
   //   }
   // }
@@ -182,9 +183,9 @@ namespace xAOD {
   //   if(!this->isMisc()) {
   //     static SG::AuxElement::Accessor<MissingETBase::Types::jetlink_t> acc("jetLink");
   //     if(acc.isAvailableWritable(*this)) {
-  // 	if(f_setLink<MissingETBase::Types::jetlink_t>(this->f_jetLink())) {
-  // 	  this->f_jetLink().toPersistent();
-  // 	}
+  //         if(f_setLink<MissingETBase::Types::jetlink_t>(this->f_jetLink())) {
+  //           this->f_jetLink().toPersistent();
+  //         }
   //     }
   //   }
   // }
@@ -499,13 +500,13 @@ namespace xAOD {
     for ( size_t idx(0); idx < this->sizeTrk(); idx++) trkVecs[idx] = constvec_t(this->trkpx(idx),this->trkpy(idx),this->trkpz(idx),this->trke(idx),this->trksumpt(idx));
     return pVec;
   }
-										   
+                                                                                   
   std::vector<const IParticle*> MissingETAssociation_v1::objects(const std::vector<double>*& calpxPtr,const std::vector<double>*& calpyPtr,
-								 const std::vector<double>*& calpzPtr,const std::vector<double>*& calePtr,
-								 const std::vector<double>*& calsumptPtr,
-								 const std::vector<double>*& trkpxPtr,const std::vector<double>*& trkpyPtr,
-								 const std::vector<double>*& trkpzPtr,const std::vector<double>*& trkePtr,
-								 const std::vector<double>*& trksumptPtr) const
+                                                                 const std::vector<double>*& calpzPtr,const std::vector<double>*& calePtr,
+                                                                 const std::vector<double>*& calsumptPtr,
+                                                                 const std::vector<double>*& trkpxPtr,const std::vector<double>*& trkpyPtr,
+                                                                 const std::vector<double>*& trkpzPtr,const std::vector<double>*& trkePtr,
+                                                                 const std::vector<double>*& trksumptPtr) const
   {
     calpxPtr = &(this->calpx()); calpyPtr = &(this->calpy()); calpzPtr = &(this->calpz()); calePtr = &(this->cale()); calsumptPtr = &(this->calsumpt());
     trkpxPtr = &(this->trkpx()); trkpyPtr = &(this->trkpy()); trkpzPtr = &(this->trkpz()); trkePtr = &(this->trke()); trksumptPtr = &(this->trksumpt());
@@ -521,7 +522,7 @@ namespace xAOD {
     MissingETBase::Types::constvec_t totalvec;
     for (size_t iKey = 0; iKey < this->sizeCal(); iKey++) {
       if (this->calkey(iKey) & getObjMask(this->findIndex(pPart)))
-	totalvec+=this->calVec(iKey);
+        totalvec+=this->calVec(iKey);
     }
     return totalvec;
   }
@@ -531,7 +532,7 @@ namespace xAOD {
     MissingETBase::Types::constvec_t totalvec;
     for (size_t iKey = 0; iKey < this->sizeTrk(); iKey++) {
       if (this->trkkey(iKey) & getObjMask(this->findIndex(pPart)))
-	totalvec+=this->trkVec(iKey);
+        totalvec+=this->trkVec(iKey);
     }
     return totalvec;
   }
@@ -590,29 +591,48 @@ namespace xAOD {
       const IParticle* obj = *objpair.first;
       MissingETBase::Types::bitmask_t bm = objpair.second;
       if (obj->type()==xAOD::Type::TrackParticle) trkOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
+      else if (obj->type()==xAOD::Type::FlowElement) {
+        const xAOD::FlowElement* fe = static_cast<const xAOD::FlowElement*>(obj);
+        // Assume this FlowElement represents a PFO
+        if(fe->isCharged()) {
+          // apply cPFO weight if present, only for the inclusive PFO sum
+          if (m_override.find(obj)!=m_override.end()) {
+            calOverlaps[bm] += m_override[obj];
+          } else {
+            calOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
+          }
+          trkOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
+        } else {
+          if (m_override.find(obj)!=m_override.end()) {
+            calOverlaps[bm] += m_override[obj];
+          } else {
+            calOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
+          } // gets ignored otherwise?
+        }
+      }
       else if (obj->type()==xAOD::Type::ParticleFlow) {
-	const PFO* pfo = static_cast<const PFO*>(obj);
-	if(pfo->isCharged()) {
-	  // apply cPFO weight if present, only for the inclusive PFO sum
-	  if (m_override.find(obj)!=m_override.end()) {
-	    calOverlaps[bm] += m_override[obj];
-	  } else {
-	    calOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
-	  }
-	  trkOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
-	} else {
-	  if (m_override.find(obj)!=m_override.end()) {
-	    calOverlaps[bm] += m_override[obj];
-	  } else {
-	    calOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
-	  } // gets ignored otherwise?
-	}
+        const PFO* pfo = static_cast<const PFO*>(obj);
+        if(pfo->isCharged()) {
+          // apply cPFO weight if present, only for the inclusive PFO sum
+          if (m_override.find(obj)!=m_override.end()) {
+            calOverlaps[bm] += m_override[obj];
+          } else {
+            calOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
+          }
+          trkOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
+        } else {
+          if (m_override.find(obj)!=m_override.end()) {
+            calOverlaps[bm] += m_override[obj];
+          } else {
+            calOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
+          } // gets ignored otherwise?
+        }
       } else if(obj->type()==xAOD::Type::TruthParticle) {
-	const TruthParticle* tp = static_cast<const TruthParticle*>(obj);
-	if(fabs(tp->charge())>0.)
-	  trkOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
-	if(!tp->isMuon())
-	  calOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
+        const TruthParticle* tp = static_cast<const TruthParticle*>(obj);
+        if(fabs(tp->charge())>0.)
+          trkOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
+        if(!tp->isMuon())
+          calOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
       }
       else calOverlaps[bm] += MissingETBase::Types::constvec_t(*obj);
     }
@@ -648,25 +668,25 @@ namespace xAOD {
       unsigned char overlapTypes(0);
       // if we somehow already recorded an overlap for this one, skip
       for(vector<size_t>::const_iterator iOverlap=myOverlaps.begin();
-	  iOverlap!=myOverlaps.end() && !overlapFound; ++iOverlap) {
-	overlapFound = (*iOverlap) == iTargetObj;
+          iOverlap!=myOverlaps.end() && !overlapFound; ++iOverlap) {
+        overlapFound = (*iOverlap) == iTargetObj;
       }
       if(overlapFound) continue;
       // otherwise, compare constituents to check if any match
       for(const auto& mine : myConst) {
-	for(const auto& target : checkConst) {
-	  overlapFound |= ( mine == target );
-	  if(mine == target) {
-	    if((*mine)->type()==xAOD::Type::TruthParticle) overlapTypes |= 1;
-	    else if((*mine)->type()==xAOD::Type::Other) overlapTypes |= 1 << xAOD::Type::NeutralParticle;
-	    else overlapTypes |= 1 << (*mine)->type();
-	  }
-	}
+        for(const auto& target : checkConst) {
+          overlapFound |= ( mine == target );
+          if(mine == target) {
+            if((*mine)->type()==xAOD::Type::TruthParticle) overlapTypes |= 1;
+            else if((*mine)->type()==xAOD::Type::Other) overlapTypes |= 1 << xAOD::Type::NeutralParticle;
+            else overlapTypes |= 1 << (*mine)->type();
+          }
+        }
       }
       // record the overlap
       if(overlapFound) {
-	this->addOverlap(objIdx,iTargetObj,overlapTypes);
-	this->addOverlap(iTargetObj,objIdx,overlapTypes);
+        this->addOverlap(objIdx,iTargetObj,overlapTypes);
+        this->addOverlap(iTargetObj,objIdx,overlapTypes);
       }
     }
     return overlapIndices(objIdx).size()>0;
@@ -680,29 +700,31 @@ namespace xAOD {
     vector<unsigned char> types = this->overlapTypes(objIdx);
     for(size_t iOL=0; iOL<indices.size(); ++iOL) {
       if(helper->objSelected(this, indices[iOL])) {
-	// printf("Test object %lu for overlaps: OL type %i\n",indices[iOL],(int)types[iOL]);
-	switch(p) {
-	case MissingETBase::UsageHandler::TrackCluster:      
-	  if((types[iOL] & 1<<xAOD::Type::CaloCluster) || (types[iOL] & 1<<xAOD::Type::TrackParticle)) {break;}
-	  else {continue;}
-	case MissingETBase::UsageHandler::OnlyCluster:
-	  if(types[iOL] & 1<<xAOD::Type::CaloCluster) {break;}
-	  else {continue;}
-	case MissingETBase::UsageHandler::OnlyTrack:
-	  if(types[iOL] & 1<<xAOD::Type::TrackParticle) {break;}
-	  else {continue;}
-	case MissingETBase::UsageHandler::ParticleFlow:
-	  if(types[iOL] & 1<<xAOD::Type::ParticleFlow) {break;}
-	  else {continue;}
-	case MissingETBase::UsageHandler::TruthParticle:
-	  if(types[iOL] & 1) {break;}
-	  else {continue;}
-	case MissingETBase::UsageHandler::AllCalo:
-	  if(types[iOL] & ~(1<<xAOD::Type::TrackParticle)) {break;}
-	  else {continue;}
-	default: continue;
-	}
-	return true;
+        // printf("Test object %lu for overlaps: OL type %i\n",indices[iOL],(int)types[iOL]);
+        switch(p) {
+        case MissingETBase::UsageHandler::TrackCluster:      
+          if((types[iOL] & 1<<xAOD::Type::CaloCluster) || (types[iOL] & 1<<xAOD::Type::TrackParticle)) {break;}
+          else {continue;}
+        case MissingETBase::UsageHandler::OnlyCluster:
+          if(types[iOL] & 1<<xAOD::Type::CaloCluster) {break;}
+          else {continue;}
+        case MissingETBase::UsageHandler::OnlyTrack:
+          if(types[iOL] & 1<<xAOD::Type::TrackParticle) {break;}
+          else {continue;}
+        case MissingETBase::UsageHandler::ParticleFlow:
+          if(types[iOL] & 1<<xAOD::Type::ParticleFlow) {break;}
+          //TODO: Check with TJ that this is OK
+          if(types[iOL] & 1<<xAOD::Type::FlowElement) {break;}
+          else {continue;}
+        case MissingETBase::UsageHandler::TruthParticle:
+          if(types[iOL] & 1) {break;}
+          else {continue;}
+        case MissingETBase::UsageHandler::AllCalo:
+          if(types[iOL] & ~(1<<xAOD::Type::TrackParticle)) {break;}
+          else {continue;}
+        default: continue;
+        }
+        return true;
       }
     }
     return false;
@@ -752,9 +774,9 @@ namespace xAOD {
   {
     for(const auto& link : this->objectLinks()) {
       if(link.isValid()) {
-	if(pPhys == *link) {
-	  return true;
-	}
+        if(pPhys == *link) {
+          return true;
+        }
       }
     }
     return false;
@@ -764,11 +786,11 @@ namespace xAOD {
   {
     for(size_t iObj=0; iObj<this->objectLinks().size(); ++iObj) {
       for(const auto& link : m_objConstLinks[iObj]) {
-	if(link.isValid()) {
-	  if(pSig == *link) {
-	    return true;
-	  }
-	}
+        if(link.isValid()) {
+          if(pSig == *link) {
+            return true;
+          }
+        }
       }
     }
     return false;
@@ -836,7 +858,7 @@ namespace xAOD {
     switch(p) {
     case MissingETBase::UsageHandler::TrackCluster:      
       if(type==xAOD::Type::CaloCluster
-	 || type==xAOD::Type::TrackParticle) {return true;}
+         || type==xAOD::Type::TrackParticle) {return true;}
       else {return false;}
     case MissingETBase::UsageHandler::OnlyCluster:
       if(type==xAOD::Type::CaloCluster) {return true;}
@@ -846,6 +868,7 @@ namespace xAOD {
       else {return false;}
     case MissingETBase::UsageHandler::ParticleFlow:
       if(type==xAOD::Type::ParticleFlow) {return true;}
+      if(type==xAOD::Type::FlowElement) {return true;}
       else {return false;}
     case MissingETBase::UsageHandler::AllCalo:
       if(type!=xAOD::Type::TrackParticle) {return true;}
diff --git a/InnerDetector/InDetConditions/PixelConditionsTools/src/PixelConditionsSummaryTool.cxx b/InnerDetector/InDetConditions/PixelConditionsTools/src/PixelConditionsSummaryTool.cxx
index ad9f03b2f11b76f905887a0a230d41013d3db6b3..9b983ac600737eab76202e62dbbf3427247b1e77 100644
--- a/InnerDetector/InDetConditions/PixelConditionsTools/src/PixelConditionsSummaryTool.cxx
+++ b/InnerDetector/InDetConditions/PixelConditionsTools/src/PixelConditionsSummaryTool.cxx
@@ -87,7 +87,7 @@ PixelConditionsSummaryTool::IDCCacheEntry* PixelConditionsSummaryTool::getCacheE
 uint64_t PixelConditionsSummaryTool::getBSErrorWord(const IdentifierHash& moduleHash, const EventContext& ctx) const {
   if (!m_useByteStream) { return 0; }
 
-  std::lock_guard<std::mutex> lock{m_cacheMutex};
+  std::scoped_lock<std::mutex> lock{*m_cacheMutex.get(ctx)};
   auto idcCachePtr = getCacheEntry(ctx)->IDCCache;
   if (idcCachePtr==nullptr) {
     ATH_MSG_ERROR("PixelConditionsSummaryTool No cache! " );
diff --git a/InnerDetector/InDetConditions/PixelConditionsTools/src/PixelConditionsSummaryTool.h b/InnerDetector/InDetConditions/PixelConditionsTools/src/PixelConditionsSummaryTool.h
index cd02679876eb8e2830c4e2180dcd02b3635bd5fb..d69ca0c34aa44143776bd52f7557c6f115225dd9 100644
--- a/InnerDetector/InDetConditions/PixelConditionsTools/src/PixelConditionsSummaryTool.h
+++ b/InnerDetector/InDetConditions/PixelConditionsTools/src/PixelConditionsSummaryTool.h
@@ -102,7 +102,7 @@ class PixelConditionsSummaryTool: public AthAlgTool, public IInDetConditionsTool
 
     const uint64_t m_missingErrorInfo{std::numeric_limits<uint64_t>::max()-3000000000};
 
-    mutable std::mutex m_cacheMutex{};
+    mutable SG::SlotSpecificObj<std::mutex> m_cacheMutex ATLAS_THREAD_SAFE;
 
     struct IDCCacheEntry {
       EventContext::ContextEvt_t eventId = EventContext::INVALID_CONTEXT_EVT; // invalid event ID for the start
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsTools/src/SCT_ByteStreamErrorsTool.cxx b/InnerDetector/InDetConditions/SCT_ConditionsTools/src/SCT_ByteStreamErrorsTool.cxx
index 8bdca590b7b8a9c8612b7aef1e87c5955217d284..d505c4fae7246d15da58fe170948dab629aa1ab0 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsTools/src/SCT_ByteStreamErrorsTool.cxx
+++ b/InnerDetector/InDetConditions/SCT_ConditionsTools/src/SCT_ByteStreamErrorsTool.cxx
@@ -102,7 +102,7 @@ SCT_ByteStreamErrorsTool::IDCCacheEntry* SCT_ByteStreamErrorsTool::getCacheEntry
 bool
 SCT_ByteStreamErrorsTool::isGood(const IdentifierHash& elementIdHash, const EventContext& ctx) const {
   {
-    std::lock_guard<std::mutex> lock{m_cacheMutex};
+    std::scoped_lock<std::mutex> lock{*m_cacheMutex.get(ctx)};
     ATH_MSG_VERBOSE("SCT_ByteStreamErrorsTool isGood called for " << elementIdHash);
     auto idcCachePtr{getCacheEntry(ctx)->IDCCache};
     if (idcCachePtr == nullptr) {
@@ -351,7 +351,7 @@ SCT_ByteStreamErrorsTool::fillData(const EventContext& ctx) const {
 
 unsigned int SCT_ByteStreamErrorsTool::tempMaskedChips(const Identifier& moduleId, const EventContext& ctx) const {
   ATH_MSG_VERBOSE("SCT_ByteStreamErrorsTool tempMaskedChips");
-  std::lock_guard<std::mutex> lock{m_cacheMutex};
+  std::scoped_lock<std::mutex> lock{*m_cacheMutex.get(ctx)};
   auto cacheEntry{getCacheEntry(ctx)};
   if (cacheEntry->IDCCache == nullptr) return 0;
 
@@ -370,7 +370,7 @@ unsigned int SCT_ByteStreamErrorsTool::tempMaskedChips(const Identifier& moduleI
 
 unsigned int SCT_ByteStreamErrorsTool::abcdErrorChips(const Identifier& moduleId, const EventContext& ctx) const {
   ATH_MSG_VERBOSE("SCT_ByteStreamErrorsTool abcdErrorChips");
-  std::lock_guard<std::mutex> lock{m_cacheMutex};
+  std::scoped_lock<std::mutex> lock{*m_cacheMutex.get(ctx)};
   auto cacheEntry{getCacheEntry(ctx)};
   if (cacheEntry->IDCCache == nullptr) return 0;
 
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsTools/src/SCT_ByteStreamErrorsTool.h b/InnerDetector/InDetConditions/SCT_ConditionsTools/src/SCT_ByteStreamErrorsTool.h
index e5c3d21e235bec1bc9eb8f521ba76ae2b50133e2..029d346dd93dc860c80a37557504cb41908f2919 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsTools/src/SCT_ByteStreamErrorsTool.h
+++ b/InnerDetector/InDetConditions/SCT_ConditionsTools/src/SCT_ByteStreamErrorsTool.h
@@ -37,7 +37,6 @@
 #include <atomic>
 #include <functional>
 #include <unordered_map>
-#include <mutex>
 #include <vector>
 
 /** forward declarations */
@@ -101,7 +100,7 @@ private:
   const SCT_ID* m_sct_id{nullptr};
   IdContext m_cntx_sct;
 
-  mutable std::mutex m_cacheMutex{};
+  mutable SG::SlotSpecificObj<std::mutex> m_cacheMutex ATLAS_THREAD_SAFE;
   struct IDCCacheEntry {
     EventContext::ContextEvt_t eventId{EventContext::INVALID_CONTEXT_EVT}; // invalid event ID for the start
     const IDCInDetBSErrContainer_Cache* IDCCache{nullptr};
@@ -125,7 +124,7 @@ private:
     }
     
   };
-  mutable SG::SlotSpecificObj<IDCCacheEntry> m_eventCache ATLAS_THREAD_SAFE; // Guarded by m_cacheMutex
+  mutable SG::SlotSpecificObj<IDCCacheEntry> m_eventCache ATLAS_THREAD_SAFE;
 
   /**
    * Obtains container form the SG, if it is missing it will complain (hard-coded 3 times per job) and return nullptr
diff --git a/InnerDetector/InDetExample/InDetRecExample/share/InDetRec_jobOptions.py b/InnerDetector/InDetExample/InDetRecExample/share/InDetRec_jobOptions.py
index ef83516a4e1206bd80bddd944de86639a76a7f54..4d708e98c4e6d6997c4792f0b5334e5e5f5f6f06 100755
--- a/InnerDetector/InDetExample/InDetRecExample/share/InDetRec_jobOptions.py
+++ b/InnerDetector/InDetExample/InDetRecExample/share/InDetRec_jobOptions.py
@@ -1066,7 +1066,7 @@ else:
                                                               OutputTracksLocation    = InDetKeys.UnslimmedTracks(),
                                                               AssociationTool         = getInDetPRDtoTrackMapToolGangedPixels(),
                                                               AssociationMapName      = "PRDtoTrackMap" + InDetKeys.UnslimmedTracks(),
-                                                              UpdateSharedHitsOnly    = False,
+                                                              UpdateSharedHits        = True,
                                                               UpdateAdditionalInfo    = True,
                                                               SummaryTool             = merger_track_summary_tool)
         topSequence += TrkTrackCollectionMerger
@@ -1113,7 +1113,7 @@ else:
                                                                  TracksLocation          = DummyCollection,
                                                                  OutputTracksLocation    = InDetKeys.DisappearingTracks(),
                                                                  AssociationTool         = getInDetPRDtoTrackMapToolGangedPixels(),
-                                                                 UpdateSharedHitsOnly    = False,
+                                                                 UpdateSharedHits        = True,
                                                                  UpdateAdditionalInfo    = True,
                                                                  SummaryTool             = merger_track_summary_tool)
        #TrkTrackCollectionMerger_pix.OutputLevel = VERBOSE
diff --git a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/CMakeLists.txt b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/CMakeLists.txt
index 61820cf9cf6f04d203969159cf12da894a51acdc..80f48d09090a698b610ec00f8235baf3a6dcb1d6 100644
--- a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/CMakeLists.txt
+++ b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/CMakeLists.txt
@@ -5,26 +5,13 @@
 
 # Declare the package name:
 atlas_subdir( TRTMonitoringRun3 )
-
-# External dependencies:
-find_package( Eigen )
-find_package( GeoModelCore )
-find_package( CORAL COMPONENTS CoralBase CoralKernel RelationalAccess )
-find_package( ROOT COMPONENTS Tree Hist RIO pthread MathCore Core Graf Graf3d Gpad Html Postscript Gui GX11TTF GX11)
-
-atlas_add_library( TRTMonitoringRun3Lib
-                   src/*.cxx
-                   PUBLIC_HEADERS TRTMonitoringRun3
-                   INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS} ${GEOMODELCORE_INCLUDE_DIRS}
-                   PRIVATE_INCLUDE_DIRS ${CORAL_INCLUDE_DIRS}
-                   LINK_LIBRARIES ${ROOT_LIBRARIES} ${EIGEN_LIBRARIES} ${GEOMODELCORE_LIBRARIES} AthenaBaseComps xAODEventInfo InDetPrepRawData GaudiKernel TRT_ConditionsServicesLib InDetReadoutGeometry TRT_ReadoutGeometry InDetRawData TrkTrack TrkToolInterfaces AthenaMonitoringLib CommissionEvent TrkSpacePoint MagFieldInterfaces InDetByteStreamErrors
-                   PRIVATE_LINK_LIBRARIES ${CORAL_LIBRARIES} AthenaKernel SGTools SGAudCore AthenaPoolUtilities LumiBlockCompsLib EventInfo LWHists TrkTrackSummary InDetRIO_OnTrack InDetIdentifier TrkRIO_OnTrack TrkParameters TrkMeasurementBase TrkEventUtils TrkSurfaces PathResolver EventPrimitives Identifier AtlasDetDescr AthContainers TRT_DriftFunctionToolLib )
-                   
+                  
 atlas_add_component( TRTMonitoringRun3
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CORAL_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS} ${GEOMODELCORE_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${EIGEN_LIBRARIES} ${GEOMODELCORE_LIBRARIES} TRTMonitoringRun3Lib AthenaMonitoringLib SGAudCore SGTools AthenaPoolUtilities GaudiKernel EventInfo InDetRawData InDetPrepRawData LumiBlockCompsLib CommissionEvent AthContainers AtlasDetDescr Identifier xAODEventInfo EventPrimitives TRT_ConditionsServicesLib InDetReadoutGeometry TRT_ReadoutGeometry InDetRIO_OnTrack LWHists TrkTrack TrkTrackSummary TrkToolInterfaces AthenaKernel InDetIdentifier MagFieldInterfaces PathResolver TrkSurfaces TrkEventUtils TrkMeasurementBase TrkParameters TrkRIO_OnTrack TrkSpacePoint TRT_DriftFunctionToolLib )
+                     LINK_LIBRARIES AthenaMonitoringLib TrkToolInterfaces CommissionEvent TRT_DriftFunctionToolLib TRT_ConditionsServicesLib MagFieldInterfaces InDetByteStreamErrors InDetRIO_OnTrack
+                     )
                    
 # Install files from the package:
 atlas_install_python_modules( python/*.py )
diff --git a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/TRTMonitoringRun3RAW_Alg.h b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/TRTMonitoringRun3RAW_Alg.h
index 5fa1277d71477372ce802e2f44cf80fcc9e7c367..c73a34741ef0101a4e1f46b55a78be315a848916 100644
--- a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/TRTMonitoringRun3RAW_Alg.h
+++ b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/TRTMonitoringRun3/TRTMonitoringRun3RAW_Alg.h
@@ -27,6 +27,7 @@
 #include "TrkToolInterfaces/ITrackHoleSearchTool.h"
 #include "TRT_DriftFunctionTool/ITRT_DriftFunctionTool.h"
 #include "TRT_ConditionsServices/ITRT_CalDbTool.h"
+#include "TRT_ConditionsServices/ITRT_StrawNeighbourSvc.h"
 
 #include "MagFieldInterfaces/IMagFieldSvc.h"
 
@@ -113,6 +114,7 @@ private:
 
     // Services
     ToolHandle<ITRT_StrawStatusSummaryTool> m_sumTool;
+    ServiceHandle<ITRT_StrawNeighbourSvc> m_TRTStrawNeighbourSvc;
 
     // Data handles
     SG::ReadHandleKey<TRT_RDO_Container>   m_rdoContainerKey{this,       "TRTRawDataObjectName",   "TRT_RDOs",      "Name of TRT RDOs container"};
diff --git a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/python/TRTMonitoringRun3RAW_Alg.py b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/python/TRTMonitoringRun3RAW_Alg.py
index 4ff8ded4e02d4821e7d50d05f8ffbeb456df2eb7..386b2a49ba2d314d0a6a1d62ddcefc57e7de49e6 100644
--- a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/python/TRTMonitoringRun3RAW_Alg.py
+++ b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/python/TRTMonitoringRun3RAW_Alg.py
@@ -55,33 +55,33 @@ def TRTMonitoringRun3RAW_AlgConfig(inputFlags):
                 elif i >= numberOfStacks[ibe]:
                     oss = 'TRT/EndcapC/Sector' + str(i + 1 - 32)
 
-            rdoStackGroup.defineHistogram('HitWMapS_passed,HitWMapS;hHitWMapS',type='TEfficiency',title='Leading Edge in Time Window: Straws;Straw Number in Stack;Probability per Event',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
-            rdoStackGroup.defineHistogram('HitTrWMapS_x,HitTrWMapS_y;hHitTrWMapS',type='TProfile',title='Mean Trailing Edge in Time Window: Straws;Straw Number in Stack;Time (ns)',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
-            rdoStackGroup.defineHistogram('HitTrMapS_x,HitTrMapS_y;hHitTrMapS',type='TProfile',title='Mean Trailing Edge: Straws;Straw Number in Stack;Time (ns)',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
-            rdoStackGroup.defineHistogram('HitAWMapS_passed,HitAWMapS;hHitAWMapS',type='TEfficiency',title='LL in Time Window: Straws;Straw Number in Stack;Probability',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
-            rdoStackGroup.defineHistogram('HitAMapS_passed,HitAMapS;hHitAMapS',type='TEfficiency',title='Any LL Bit: Straws;Straw Number in Stack;Probability',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
+            rdoStackGroup.defineHistogram('HitWMapS_passed,strawNumber;hHitWMapS',type='TEfficiency',title='Leading Edge in Time Window: Straws;Straw Number in Stack;Probability per Event',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
+            rdoStackGroup.defineHistogram('strawNumber,HitTrMapS_y;hHitTrWMapS',cutmask='HitTrWMapS_cut',type='TProfile',title='Mean Trailing Edge in Time Window: Straws;Straw Number in Stack;Time (ns)',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
+            rdoStackGroup.defineHistogram('strawNumber,HitTrMapS_y;hHitTrMapS',type='TProfile',title='Mean Trailing Edge: Straws;Straw Number in Stack;Time (ns)',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
+            rdoStackGroup.defineHistogram('HitAWMapS_passed,strawNumber;hHitAWMapS',type='TEfficiency',title='LL in Time Window: Straws;Straw Number in Stack;Probability',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
+            rdoStackGroup.defineHistogram('HitAMapS_passed,strawNumber;hHitAMapS',type='TEfficiency',title='Any LL Bit: Straws;Straw Number in Stack;Probability',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
             rdoStackGroup.defineHistogram('StrawOcc_passed,StrawOcc;hOccupancyS',type='TEfficiency',title='Straw Occupancy Distribution: Straws;Occupancy;Number of Straws',path=oss,xbins=201,xmin=0,xmax=1.005)
-            rdoStackGroup.defineHistogram('HitToTMapS_x,HitToTMapS_y;hHitToTMapS',type='TProfile',title='Mean ToT: Straws;Straw Number in Stack;Time (ns)',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
-            rdoStackGroup.defineHistogram('HitToTLongMapS_x,HitToTLongMapS_y;hHitToTLongMapS',type='TProfile',title='Mean ToT for Straws with ToT > LongToTCut: Straws;Straw Number in Stack;Time (ns)',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
-            rdoStackGroup.defineHistogram('HitToTLongTrMapS_x,HitToTLongTrMapS_y;hHitToTLongTrMapS',type='TProfile',title='Mean Trailing Edge for Straws with ToT > LongToTCut: Straws;Straw Number in Stack;Probability',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
-            rdoStackGroup.defineHistogram('HitHMapS_passed,HitHMapS;hHitHMapS',type='TEfficiency',title='Any HL Bit: Straws;Straw Number in Stack;Probability',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
-            rdoStackGroup.defineHistogram('HitHWMapS_passed,HitHWMapS;hHitHWMapS',type='TEfficiency',title='HL in Time Window: Straws;Straw Number in Stack;Probability',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
+            rdoStackGroup.defineHistogram('strawNumber,HitToTMapS_y;hHitToTMapS',type='TProfile',title='Mean ToT: Straws;Straw Number in Stack;Time (ns)',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
+            rdoStackGroup.defineHistogram('strawNumber,HitToTMapS_y;hHitToTLongMapS',cutmask='HitToTLong_cut',type='TProfile',title='Mean ToT for Straws with ToT > LongToTCut: Straws;Straw Number in Stack;Time (ns)',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
+            rdoStackGroup.defineHistogram('strawNumber,HitTrMapS_y;hHitToTLongTrMapS',cutmask='HitToTLong_cut',type='TProfile',title='Mean Trailing Edge for Straws with ToT > LongToTCut: Straws;Straw Number in Stack;Probability',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
+            rdoStackGroup.defineHistogram('HitHMapS_passed,strawNumber;hHitHMapS',type='TEfficiency',title='Any HL Bit: Straws;Straw Number in Stack;Probability',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
+            rdoStackGroup.defineHistogram('HitHWMapS_passed,strawNumber;hHitHWMapS',type='TEfficiency',title='HL in Time Window: Straws;Straw Number in Stack;Probability',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
             rdoStackGroup.defineHistogram('HtoLMapS_passed,HtoLMapS;hHtoLMapS',type='TEfficiency',title='HL/LL Ratio: Straws;Straw Number in Stack;Probability',path=oss,xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
 
-            rdoStackGroup.defineHistogram('HitWMapC_passed,HitWMapC;hHitWMapC',type='TEfficiency',title='Leading Edge in Time Window: Chips;Chip Number in Stack;Probability',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
-            rdoStackGroup.defineHistogram('HitTrMapC_x,HitTrMapC_y;hHitTrMapC',type='TProfile',title='Mean Trailing Edge: Chips;Chip Number in Stack;Time (ns)',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
-            rdoStackGroup.defineHistogram('HitTrWMapC_x,HitTrWMapC_y;hHitTrWMapC',type='TProfile',title='Mean Trailing Edge in Time Window: Chips;Chip Number in Stack;Time (ns)',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
-            rdoStackGroup.defineHistogram('HitAWMapC_passed,HitAWMapC;hHitAWMapC',type='TEfficiency',title='LL in Time Window: Chips;Chip Number in Stack;Probability',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
-            rdoStackGroup.defineHistogram('HitAMapC_passed,HitAMapC;hHitAMapC',type='TEfficiency',title='Any LL Bit: Chips;Chip Number in Stack;Probability',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
+            rdoStackGroup.defineHistogram('HitWMapC_passed,chipNumber;hHitWMapC',type='TEfficiency',title='Leading Edge in Time Window: Chips;Chip Number in Stack;Probability',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
+            rdoStackGroup.defineHistogram('chipNumber,HitTrMapC_y;hHitTrMapC',type='TProfile',title='Mean Trailing Edge: Chips;Chip Number in Stack;Time (ns)',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
+            rdoStackGroup.defineHistogram('chipNumber,HitTrMapC_y;hHitTrWMapC',cutmask='HitTrWMapC_cut',type='TProfile',title='Mean Trailing Edge in Time Window: Chips;Chip Number in Stack;Time (ns)',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
+            rdoStackGroup.defineHistogram('HitAWMapC_passed,chipNumber;hHitAWMapC',type='TEfficiency',title='LL in Time Window: Chips;Chip Number in Stack;Probability',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
+            rdoStackGroup.defineHistogram('HitAMapC_passed,chipNumber;hHitAMapC',type='TEfficiency',title='Any LL Bit: Chips;Chip Number in Stack;Probability',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
             rdoStackGroup.defineHistogram('OccupancyC_passed,OccupancyC;hChipOcc',type='TEfficiency',title='Chip Occupancy Distribution;Occupancy;Number of Chips',path=oss,xbins=201,xmin=0,xmax=1.005)
-            rdoStackGroup.defineHistogram('HitToTMapC_x,HitToTMapC_y;hHitToTMapC',type='TProfile',title='Mean ToT: Chips;Chip Number in Stack;Time (ns)',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
-            rdoStackGroup.defineHistogram('HitHMapC_passed,HitHMapC;hHitHMapC',type='TEfficiency',title='Any HL Bit: Chips;Chip Number in Stack;Probability',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
-            rdoStackGroup.defineHistogram('HitHWMapC_passed,HitHWMapC;hHitHWMapC',type='TEfficiency',title='HL in Time Window: Chips;Chip Number in Stack;Probability',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
+            rdoStackGroup.defineHistogram('chipNumber,HitToTMapC_y;hHitToTMapC',type='TProfile',title='Mean ToT: Chips;Chip Number in Stack;Time (ns)',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
+            rdoStackGroup.defineHistogram('HitHMapC_passed,chipNumber;hHitHMapC',type='TEfficiency',title='Any HL Bit: Chips;Chip Number in Stack;Probability',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
+            rdoStackGroup.defineHistogram('HitHWMapC_passed,chipNumber;hHitHWMapC',type='TEfficiency',title='HL in Time Window: Chips;Chip Number in Stack;Probability',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
             rdoStackGroup.defineHistogram('HtoLMapC_passed,HtoLMapC;hHtoLMapC',type='TEfficiency',title='HL/LL Ratio: Chips;Chip Number in Stack;Probability',path=oss,xbins=iChipMax[ibe],xmin=0,xmax=iChipMax[ibe])
-            rdoStackGroup.defineHistogram('HtoBCMapC_x,HtoBCMapC_y;hHtoBCMapC',type='TH2F',title='HL in BC: Chips;Bunch Crossing ID;Chip Number in Stack',path=oss,xbins=3,xmin=0,xmax=3,ybins=iChipMax[ibe],ymin=0,ymax=iChipMax[ibe])
+            rdoStackGroup.defineHistogram('HtoBCMapC_x,chipNumber;hHtoBCMapC',cutmask='HtoBCMap_cut',type='TH2F',title='HL in BC: Chips;Bunch Crossing ID;Chip Number in Stack',path=oss,xbins=3,xmin=0,xmax=3,ybins=iChipMax[ibe],ymin=0,ymax=iChipMax[ibe])
 
-            if   ibe == 0: rdoStackGroup.defineHistogram('HtoBCMapB_x,HtoBCMapB_y;hHtoBCMapB',type='TH2F',title='HL in BC: Boards;Bunch Crossing ID;Board Number in Stack',path=oss,xbins=3,xmin=0,xmax=3,ybins=9,ymin=0,ymax=9)
-            elif ibe == 1: rdoStackGroup.defineHistogram('HtoBCMapB_x,HtoBCMapB_y;hHtoBCMapB',type='TH2F',title='HL in BC: Boards;Bunch Crossing ID;Board Number in Stack',path=oss,xbins=3,xmin=0,xmax=3,ybins=20,ymin=-0.5,ymax=19.5)
+            if   ibe == 0: rdoStackGroup.defineHistogram('HtoBCMapB_x,HtoBCMapB_y;hHtoBCMapB',cutmask='HtoBCMap_cut',type='TH2F',title='HL in BC: Boards;Bunch Crossing ID;Board Number in Stack',path=oss,xbins=3,xmin=0,xmax=3,ybins=9,ymin=0,ymax=9)
+            elif ibe == 1: rdoStackGroup.defineHistogram('HtoBCMapB_x,HtoBCMapB_y;hHtoBCMapB',cutmask='HtoBCMap_cut',type='TH2F',title='HL in BC: Boards;Bunch Crossing ID;Board Number in Stack',path=oss,xbins=3,xmin=0,xmax=3,ybins=20,ymin=-0.5,ymax=19.5)
 
     ### Registering Collisions Histograms ###
     rdoShiftSmryGroup = helper.addGroup(algTRTMonitoringRun3RAW,'RDOShiftSmryHistograms')
@@ -109,15 +109,15 @@ def TRTMonitoringRun3RAW_AlgConfig(inputFlags):
         rdoGroup = helper.addGroup(algTRTMonitoringRun3RAW,'RDOHistograms{0}'.format(ibe))
         rdoGroup.defineHistogram('BCIDvsOcc_x,BCIDvsOcc_y;hBCIDvsOcc',type='TProfile',title='Avg. Occupancy vs BCID{0};Bunch Crossing ID;Occupancy'.format(regionTag),path='TRT/{0}/Expert'.format(barrelOrEndcap[ibe]),xbins=3564,xmin=0,xmax=3564)
         if ibe == 0:
-            rdoGroup.defineHistogram('HitWMap_passed,HitWMap;hHitWMap',type='TEfficiency',title='Leading Edge in Time Window: Xenon Straws (Barrel);Straw Number in Stack;Probability',path='TRT/Shift/{0}'.format(str(barrelOrEndcap[ibe])),xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
-            rdoGroup.defineHistogram('HitWMap_Ar_passed,HitWMap_Ar;hHitWMap_Ar',type='TEfficiency',title='Leading Edge in Time Window: Argon Straws (Barrel);Straw Number in Stack;Probability',path='TRT/Shift/{0}'.format(barrelOrEndcap[ibe]),xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
+            rdoGroup.defineHistogram('HitWMap_passed,strawNumber;hHitWMap',cutmask='isNotAr',type='TEfficiency',title='Leading Edge in Time Window: Xenon Straws (Barrel);Straw Number in Stack;Probability',path='TRT/Shift/{0}'.format(str(barrelOrEndcap[ibe])),xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
+            rdoGroup.defineHistogram('HitWMap_passed,strawNumber;hHitWMap_Ar',cutmask='isAr',type='TEfficiency',title='Leading Edge in Time Window: Argon Straws (Barrel);Straw Number in Stack;Probability',path='TRT/Shift/{0}'.format(barrelOrEndcap[ibe]),xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
             rdoGroup.defineHistogram('OccAll;hOccAll',type='TH1F',title='Occupancy per Event;Occupancy;Events',path='TRT/Shift/{0}'.format(barrelOrEndcap[ibe]),xbins=400,xmin=0.0,xmax=1.0)
         elif ibe == 1:
             for iside in range(2):
                 side = ('A', 'C')
                 rdoEndcapGroup = helper.addGroup(algTRTMonitoringRun3RAW,'RDOHistograms1{0}'.format(iside))
-                rdoEndcapGroup.defineHistogram('HitWMap_passed,HitWMap;hHitWMap_{0}'.format(side[iside]),type='TEfficiency',title='Leading Edge in Time Window: Xenon Straws (E{0});Straw Number in Stack;Probability'.format(side[iside]),path='TRT/Shift/{0}'.format(barrelOrEndcap[ibe]),xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
-                rdoEndcapGroup.defineHistogram('HitWMap_Ar_passed,HitWMap_Ar;hHitWMap_Ar_{0}'.format(side[iside]),type='TEfficiency',title='Leading Edge in Time Window: Argon Straws (E{0});Straw Number in Stack;Probability'.format(side[iside]),path='TRT/Shift/{0}'.format(barrelOrEndcap[ibe]),xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])   
+                rdoEndcapGroup.defineHistogram('HitWMap_passed,strawNumber;hHitWMap_{0}'.format(side[iside]),cutmask='isNotAr',type='TEfficiency',title='Leading Edge in Time Window: Xenon Straws (E{0});Straw Number in Stack;Probability'.format(side[iside]),path='TRT/Shift/{0}'.format(barrelOrEndcap[ibe]),xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])
+                rdoEndcapGroup.defineHistogram('HitWMap_passed,strawNumber;hHitWMap_Ar_{0}'.format(side[iside]),cutmask='isAr',type='TEfficiency',title='Leading Edge in Time Window: Argon Straws (E{0});Straw Number in Stack;Probability'.format(side[iside]),path='TRT/Shift/{0}'.format(barrelOrEndcap[ibe]),xbins=strawMax[ibe],xmin=0,xmax=strawMax[ibe])   
         for iside in range(2):
             regionTag = ' (' + beId[ibe] + sideId[iside] + ')'
             regionMarker = (beId[ibe] + sideId[iside]) if isOnline is True else (sideId[iside])
diff --git a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/src/TRTMonitoringRun3RAW_Alg.cxx b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/src/TRTMonitoringRun3RAW_Alg.cxx
index 6638d12341b2a47cb06d1a52a0b293008f57f7c9..ec918c8c40358953331c297c0af94cf30e633bb6 100644
--- a/InnerDetector/InDetMonitoring/TRTMonitoringRun3/src/TRTMonitoringRun3RAW_Alg.cxx
+++ b/InnerDetector/InDetMonitoring/TRTMonitoringRun3/src/TRTMonitoringRun3RAW_Alg.cxx
@@ -41,6 +41,7 @@ TRTMonitoringRun3RAW_Alg::TRTMonitoringRun3RAW_Alg( const std::string& name, ISv
 ,m_minTRThits(10)
 ,m_minP(0)
 ,m_sumTool("TRT_StrawStatusSummaryTool", this)
+,m_TRTStrawNeighbourSvc("TRT_StrawNeighbourSvc", name)
 ,m_isCosmics(false)
 ,m_EventBurstCut(-1)
 {
@@ -124,6 +125,80 @@ StatusCode TRTMonitoringRun3RAW_Alg::initialize() {
     ATH_CHECK( m_trackCollectionKey.initialize() );
     ATH_CHECK( m_bsErrContKey.initialize(SG::AllowEmpty) );
 
+    // initialize chip lookup maps
+    ATH_CHECK( m_TRTStrawNeighbourSvc.retrieve() );
+
+    //loop over straw hash index to create straw number mapping for TRTViewer
+    unsigned int maxHash = m_pTRTHelper->straw_layer_hash_max();
+
+    for (int ibe = 0; ibe < 2; ibe++) { // ibe=0(barrel), ibe=1(endcap)
+        for (unsigned int index = 0; index < maxHash; index++) {
+            IdentifierHash idHash = index;
+            Identifier id = m_pTRTHelper->layer_id(idHash);
+            int idBarrelEndcap = m_pTRTHelper->barrel_ec(id);
+            int idLayerWheel   = m_pTRTHelper->layer_or_wheel(id);
+            int idPhiModule    = m_pTRTHelper->phi_module(id);
+            int idStrawLayer   = m_pTRTHelper->straw_layer(id);
+            bool isBarrel = m_pTRTHelper->is_barrel(id);
+            int idSide;
+            int sectorflag = 0;
+            const InDetDD::TRT_BaseElement *element = nullptr;
+
+            if (ibe == 0) { // barrel
+                idSide = idBarrelEndcap ? 1 : -1;
+
+                if (isBarrel && (idBarrelEndcap == -1)) {
+                    sectorflag = 1;
+                    element = m_mgr->getBarrelElement(idSide, idLayerWheel, idPhiModule, idStrawLayer);
+                }
+            } else if (ibe == 1) { // endcap
+                idSide = idBarrelEndcap ? 1 : 0;
+
+                if (!isBarrel && ((idBarrelEndcap == -2) || (idBarrelEndcap == 2))) {
+                    sectorflag = 1;
+                    element = m_mgr->getEndcapElement(idSide, idLayerWheel, idStrawLayer, idPhiModule);//, idStrawLayer_ec);
+                }
+            }
+
+            if (sectorflag == 1) {
+                if (!element) continue;
+
+                for (unsigned int istraw = 0; istraw < element->nStraws(); istraw++) {
+                    std::vector<Identifier> neighbourIDs;
+                    Identifier strawID = m_pTRTHelper->straw_id(id, int(istraw));
+                    int i_chip, i_pad;
+                    m_TRTStrawNeighbourSvc->getChip(strawID, i_chip);
+                    m_TRTStrawNeighbourSvc->getPad(id, i_pad);
+
+                    if (ibe == 0) { //barrel
+                        if (idLayerWheel == 1) i_chip += 21;
+
+                        if (idLayerWheel == 2) i_chip += 54;
+
+                        int tempStrawNumber = strawNumber(istraw, idStrawLayer, idLayerWheel);
+
+                        if (tempStrawNumber < 0 || tempStrawNumber > (s_Straw_max[ibe] - 1)) {
+                            ATH_MSG_WARNING("Found tempStrawNumber = " << tempStrawNumber << " out of range.");
+                        } else {
+                            m_mat_chip_B[idPhiModule][tempStrawNumber]    = i_chip;
+                            m_mat_chip_B[idPhiModule + 32][tempStrawNumber] = i_chip;
+                        }
+                    } else if (ibe == 1) { //endcap
+                        ++i_chip -= 104;
+                        int tempStrawNumber = strawNumberEndCap(istraw, idStrawLayer, idLayerWheel, idPhiModule, idSide);
+
+                        if (tempStrawNumber < 0 || tempStrawNumber > (s_Straw_max[ibe] - 1)) {
+                            ATH_MSG_WARNING("Found tempStrawNumber = " << tempStrawNumber << " out of range.");
+                        } else {
+                            m_mat_chip_E[idPhiModule][tempStrawNumber]    = i_chip;
+                            m_mat_chip_E[idPhiModule + 32][tempStrawNumber] = i_chip;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     return StatusCode::SUCCESS;
 }
 
@@ -450,6 +525,40 @@ float TRTMonitoringRun3RAW_Alg::radToDegrees(float radValue) const{
 	return degreeValue;
 }
 
+struct straw_struct {
+    int strawNumber;
+    bool HitWMapS_passed;
+    bool HitAWMapS_passed;
+    bool HitAMapS_passed;
+    bool HitHMapS_passed;
+    bool HitHWMapS_passed;
+    float HitTrMapS_y;
+    float HitToTMapS_y;
+    bool HitToTLong_cut;
+    bool HitTrWMapS_cut;
+};
+
+struct chip_struct {
+    int chipNumber;
+    bool HitWMapC_passed;
+    bool HitAWMapC_passed;
+    bool HitAMapC_passed;
+    bool HitHMapC_passed;
+    bool HitHWMapC_passed;
+    float HitTrMapC_y;
+    bool HitTrWMapC_cut;
+    float HitToTMapC_y;
+    int HtoBCMapC_x;
+    int HtoBCMapB_x;
+    int HtoBCMapB_y;
+    bool HtoBCMap_cut;
+};
+
+struct straw_shifter_struct {
+    int strawNumber;
+    bool isAr;
+    bool HitWMap_passed;
+};
 
 //Fill the TRT RDO Histograms
 //----------------------------------------------------------------------------------//
@@ -460,22 +569,10 @@ StatusCode TRTMonitoringRun3RAW_Alg::fillTRTRDOs(const TRT_RDO_Container& rdoCon
     ATH_MSG_DEBUG("Filling TRT RDO Histograms");
     
     // TProfile
-    auto HitTrWMapS_x         = Monitored::Scalar<float>("HitTrWMapS_x", 0.0);
-    auto HitTrWMapS_y         = Monitored::Scalar<float>("HitTrWMapS_y", 0.0);
-    auto HitTrWMapC_x         = Monitored::Scalar<float>("HitTrWMapC_x", 0.0);
-    auto HitTrWMapC_y         = Monitored::Scalar<float>("HitTrWMapC_y", 0.0);     
-    auto HitTrMapC_x          = Monitored::Scalar<float>("HitTrMapC_x", 0.0);
-    auto HitTrMapC_y          = Monitored::Scalar<float>("HitTrMapC_y", 0.0);
     auto HitToTLongTrMapS_x   = Monitored::Scalar<float>("HitToTLongTrMapS_x", 0.0);
     auto HitToTLongTrMapS_y   = Monitored::Scalar<float>("HitToTLongTrMapS_y", 0.0);
-    auto HitToTMapC_x         = Monitored::Scalar<float>("HitToTMapC_x", 0.0);
-    auto HitToTMapC_y         = Monitored::Scalar<float>("HitToTMapC_y", 0.0);
-    auto HitTrMapS_x          = Monitored::Scalar<float>("HitTrMapS_x", 0.0);
-    auto HitTrMapS_y          = Monitored::Scalar<float>("HitTrMapS_y", 0.0);
     auto HitToTLongMapS_x     = Monitored::Scalar<float>("HitToTLongMapS_x", 0.0);
     auto HitToTLongMapS_y     = Monitored::Scalar<float>("HitToTLongMapS_y", 0.0);
-    auto HitToTMapS_x         = Monitored::Scalar<float>("HitToTMapS_x", 0.0);
-    auto HitToTMapS_y         = Monitored::Scalar<float>("HitToTMapS_y", 0.0);
     auto BCIDvsOcc_x          = Monitored::Scalar<float>("BCIDvsOcc_x", 0.0);
     auto BCIDvsOcc_y          = Monitored::Scalar<float>("BCIDvsOcc_y", 0.0);
     auto AvgHLOcc_side_x      = Monitored::Scalar<float>("AvgHLOcc_side_x", 0.0);
@@ -497,30 +594,10 @@ StatusCode TRTMonitoringRun3RAW_Alg::fillTRTRDOs(const TRT_RDO_Container& rdoCon
     auto SummaryWeight        = Monitored::Scalar<float>("SummaryWeight", 0.0);
     
     // TH2F
-    auto HtoBCMapC_x          = Monitored::Scalar<float>("HtoBCMapC_x", 0.0);
-    auto HtoBCMapC_y          = Monitored::Scalar<float>("HtoBCMapC_y", 0.0);
-    auto HtoBCMapB_x          = Monitored::Scalar<float>("HtoBCMapB_x", 0.0);
-    auto HtoBCMapB_y          = Monitored::Scalar<float>("HtoBCMapB_y", 0.0);
     
     // TEfficiency
-    auto HitWMapS             = Monitored::Scalar<float>("HitWMapS", 0.0);
-    auto HitWMapS_passed      = Monitored::Scalar<bool>("HitWMapS_passed", false);
-    auto HitAWMapS            = Monitored::Scalar<float>("HitAWMapS", 0.0);
-    auto HitAWMapS_passed     = Monitored::Scalar<bool>("HitAWMapS_passed", false);
-    auto HitAMapS             = Monitored::Scalar<float>("HitAMapS", 0.0);
-    auto HitAMapS_passed      = Monitored::Scalar<bool>("HitAMapS_passed", false);
-    auto HitHMapS             = Monitored::Scalar<float>("HitHMapS", 0.0);
-    auto HitHMapS_passed      = Monitored::Scalar<bool>("HitHMapS_passed", false);
-    auto HitHWMapS            = Monitored::Scalar<float>("HitHWMapS", 0.0);
-    auto HitHWMapS_passed     = Monitored::Scalar<bool>("HitHWMapS_passed", false);
     auto HtoLMapS             = Monitored::Scalar<float>("HtoLMapS", 0.0);
     auto HtoLMapS_passed      = Monitored::Scalar<bool>("HtoLMapS_passed", false);
-    auto HitWMapC             = Monitored::Scalar<float>("HitWMapC", 0.0);
-    auto HitWMapC_passed      = Monitored::Scalar<bool>("HitWMapC_passed", false);
-    auto HitAWMapC            = Monitored::Scalar<float>("HitAWMapC", 0.0);
-    auto HitAWMapC_passed     = Monitored::Scalar<bool>("HitAWMapC_passed", false);
-    auto HitAMapC             = Monitored::Scalar<float>("HitAMapC", 0.0);
-    auto HitAMapC_passed      = Monitored::Scalar<bool>("HitAMapC_passed", false);
     auto HitWMap_A            = Monitored::Scalar<float>("HitWMap_A", 0.0);
     auto HitWMap_A_passed     = Monitored::Scalar<bool>("HitWMap_A_passed", false);
     auto HitWMap_C            = Monitored::Scalar<float>("HitWMap_C", 0.0);
@@ -529,16 +606,8 @@ StatusCode TRTMonitoringRun3RAW_Alg::fillTRTRDOs(const TRT_RDO_Container& rdoCon
     auto HitWMap_Ar_A_passed  = Monitored::Scalar<bool>("HitWMap_Ar_A_passed", false);
     auto HitWMap_Ar_C         = Monitored::Scalar<float>("HitWMap_Ar_C", 0.0);
     auto HitWMap_Ar_C_passed  = Monitored::Scalar<bool>("HitWMap_Ar_C_passed", false);
-    auto HitHMapC             = Monitored::Scalar<float>("HitHMapC", 0.0);
-    auto HitHMapC_passed      = Monitored::Scalar<bool>("HitHMapC_passed", false);
-    auto HitHWMapC            = Monitored::Scalar<float>("HitHWMapC", 0.0);
-    auto HitHWMapC_passed     = Monitored::Scalar<bool>("HitHWMapC_passed", false);
     auto HtoLMapC             = Monitored::Scalar<float>("HtoLMapC", 0.0);
     auto HtoLMapC_passed      = Monitored::Scalar<bool>("HtoLMapC_passed", false);
-    auto HitWMap              = Monitored::Scalar<float>("HitWMap", 0.0);
-    auto HitWMap_passed       = Monitored::Scalar<bool>("HitWMap_passed", false);
-    auto HitWMap_Ar           = Monitored::Scalar<float>("HitWMap_Ar", 0.0);
-    auto HitWMap_Ar_passed    = Monitored::Scalar<bool>("HitWMap_Ar_passed", false);
     auto OccupancyC           = Monitored::Scalar<float>("OccupancyC", 0.0);
     auto OccupancyC_passed    = Monitored::Scalar<bool>("OccupancyC_passed", false);
     auto IntLum               = Monitored::Scalar<float>("IntLum", 0.0);
@@ -626,6 +695,10 @@ StatusCode TRTMonitoringRun3RAW_Alg::fillTRTRDOs(const TRT_RDO_Container& rdoCon
 
     int nhitsall = 0;
 
+    std::map<int,std::map<int, std::vector<straw_struct>>> straw_map;
+    std::map<int,std::map<int, std::vector<chip_struct>>> chip_map;
+    std::map<int,std::vector<straw_shifter_struct>> straw_shifter_map;
+
     for (; RDO_CollectionBegin != RDO_CollectionEnd; ++RDO_CollectionBegin) {
         const InDetRawDataCollection<TRT_RDORawData> *TRT_Collection(*RDO_CollectionBegin);
 
@@ -730,18 +803,15 @@ StatusCode TRTMonitoringRun3RAW_Alg::fillTRTRDOs(const TRT_RDO_Container& rdoCon
             } else if (iside == 1) {
                 iphi_module = phi_module + 32;
             }
-            if (ibe == 0) {
-                nTRTHits[ibe]++;
 
-                if (m_doStraws) {
-                    if (isArgonStraw) {
-                        HitWMap_Ar = thisStrawNumber;
-                        fill("RDOHistograms0", HitWMap_Ar_passed, HitWMap_Ar);
-                    } else {
-                        HitWMap = thisStrawNumber;
-                        fill("RDOHistograms0", HitWMap_passed, HitWMap);
-                    }
-                }
+            if (m_doStraws) {
+                    straw_shifter_struct& this_struct = straw_shifter_map[barrel_ec].emplace_back();
+                    this_struct.strawNumber = thisStrawNumber;
+                    this_struct.isAr = isArgonStraw;
+                    this_struct.HitWMap_passed = false;
+            }
+            nTRTHits[ibe]++;
+            if (ibe == 0) {
 
                 if (m_doShift) {
 //                    m_nHitsperLB_B++;
@@ -753,16 +823,6 @@ StatusCode TRTMonitoringRun3RAW_Alg::fillTRTRDOs(const TRT_RDO_Container& rdoCon
             } else if (ibe == 1) {
                 nTRTHits[ibe]++;
 
-                if (m_doStraws) {
-                    if (isArgonStraw) {
-                        HitWMap_Ar = thisStrawNumber;
-                        fill("RDOHistograms1"+std::to_string(iside), HitWMap_Ar_passed, HitWMap_Ar);
-                    } else {
-                        HitWMap = thisStrawNumber;
-                        fill("RDOHistograms1"+std::to_string(iside), HitWMap_passed, HitWMap);
-                    }
-                }
-
                 if (m_doShift) {
 //                    m_nHitsperLB_E[iside]++;
 
@@ -772,196 +832,54 @@ StatusCode TRTMonitoringRun3RAW_Alg::fillTRTRDOs(const TRT_RDO_Container& rdoCon
                 }
             }
 
-            if (m_doExpert) {
-                if (m_doStraws) { // Experimental
-                    HitWMapS = thisStrawNumber;
-                    HitWMapS_passed = 0.0;
-                    fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitWMapS_passed, HitWMapS);
-                }
-                if (m_doChips) { // Experimental
-                    HitWMapC = chip - 1;
-                    HitWMapC_passed = 0.0;
-                    fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitWMapC_passed, HitWMapC);
-                }
-                if ( (driftTimeBin > 2) && (driftTimeBin < 17) ) {
-                    if (m_doStraws) {
-                        HitWMapS = thisStrawNumber;
-                        HitWMapS_passed = 1.0;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitWMapS_passed, HitWMapS);
-                    }
-                    if (m_doChips) {
-                        HitWMapC = chip - 1;
-                        HitWMapC_passed = 1.0;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitWMapC_passed, HitWMapC);
-                    }
-                }
 
+            if (m_doExpert) {
                 float trailingEdgeScaled = (trailingEdge + 1)*3.125;
 
-                if ((trailingEdge < 23) && !lastBinHigh && !firstBinHigh) {
-                    if (m_doStraws) {
-                        HitTrWMapS_x = thisStrawNumber;
-                        HitTrWMapS_y = trailingEdgeScaled;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitTrWMapS_x, HitTrWMapS_y);
-                    }
-                    if (m_doChips) {
-                        HitTrWMapC_x = chip - 1;
-                        HitTrWMapC_y = trailingEdgeScaled;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitTrWMapC_x, HitTrWMapC_y);
-                    }
-                }
-                if (m_doStraws) {
-                    HitTrMapS_x = thisStrawNumber;
-                    HitTrMapS_y = trailingEdgeScaled;
-                    fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitTrMapS_x, HitTrMapS_y);
-                }
-                if (m_doChips) {
-                        HitTrMapC_x = chip - 1;
-                        HitTrMapC_y = trailingEdgeScaled;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitTrMapC_x, HitTrMapC_y);
-                    }
-
                 if (m_doStraws) { // Experimental
-                    HitHMapS = thisStrawNumber;
-                    HitHMapS_passed = 0.0;
-                    fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitHMapS_passed, HitHMapS);
+                    straw_struct& this_struct = straw_map[ibe][iphi_module].emplace_back();
+                    this_struct.strawNumber=thisStrawNumber;
+                    this_struct.HitWMapS_passed=((driftTimeBin > 2) && (driftTimeBin < 17) ? 1 : 0);
+                    this_struct.HitHMapS_passed=highlevel;
+                    this_struct.HitHWMapS_passed=(highlevel && is_middleHTbit_high);
+                    this_struct.HitTrMapS_y=trailingEdgeScaled;
+                    this_struct.HitAMapS_passed=((firstBinHigh || lastBinHigh || driftTimeBin > 0 || trailingEdge < 23) ? 1 : 0);
+                    this_struct.HitAWMapS_passed=(is_anybininVgate_high ? 1 : 0);
+                    this_struct.HitToTMapS_y = timeOverThreshold;
+                    this_struct.HitToTLong_cut = (timeOverThreshold > m_longToTCut);
+                    this_struct.HitTrWMapS_cut = (trailingEdge < 23) && !lastBinHigh && !firstBinHigh;
                 }
                 if (m_doChips) { // Experimental
-                    HitHMapC = chip - 1;
-                    HitHMapC_passed = 0.0;
-                    fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitHMapC_passed, HitHMapC);
-                }
-                if (highlevel) {
-                    if (m_doStraws) {
-                        HitHMapS = thisStrawNumber;
-                        HitHMapS_passed = 1.0;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitHMapS_passed, HitHMapS);
-                    }
-                    if (m_doChips) {
-                        HitHMapC = chip - 1;
-                        HitHMapC_passed = 1.0;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitHMapC_passed, HitHMapC);
-                    }
-
-                    if (m_doStraws) { // Experimental
-                        HitHWMapS = thisStrawNumber;
-                        HitHWMapS_passed = 0.0;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitHWMapS_passed, HitHWMapS);
-                    }
-                    if (m_doChips) { // Experimental
-                        HitHWMapC = chip - 1;
-                        HitHWMapC_passed = 0.0;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitHWMapC_passed, HitHWMapC);
-                    }
-                    if (is_middleHTbit_high) {
-                        if (m_doStraws) {
-                            HitHWMapS = thisStrawNumber;
-                            HitHWMapS_passed = 1.0;
-                            fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitHWMapS_passed, HitHWMapS);
-                        }
-                    if (m_doChips) {
-                        HitHWMapC = chip - 1;
-                        HitHWMapC_passed = 1.0;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitHWMapC_passed, HitHWMapC);
-                    }
-                    }
-                }
-                
-                if (m_doStraws) { // Experimental
-                    HitAMapS = thisStrawNumber;
-                    HitAMapS_passed = 0.0;
-                    fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitAMapS_passed, HitAMapS);
-                }
-                if (m_doChips) {// Experimental
-                    HitAMapC = chip - 1;
-                    HitAMapC_passed = 0.0;
-                    fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitAMapC_passed, HitAMapC);
-                }
-
-                if (firstBinHigh || lastBinHigh || driftTimeBin > 0 || trailingEdge < 23) {
-                    if (m_doStraws) {
-                        HitAMapS = thisStrawNumber;
-                        HitAMapS_passed = 1.0;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitAMapS_passed, HitAMapS);
-                    }
-                    if (m_doChips) {
-                        HitAMapC = chip - 1;
-                        HitAMapC_passed = 1.0;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitAMapC_passed, HitAMapC);
-                    }
-                }
-
-                if (m_doStraws) {// Experimental
-                    HitAWMapS = thisStrawNumber;
-                    HitAWMapS_passed = 0.0;
-                    fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitAWMapS_passed, HitAWMapS);
-                }
-                if (m_doChips) {// Experimental
-                    HitAWMapC = chip - 1;
-                    HitAWMapC_passed = 0.0;
-                    fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitAWMapC_passed, HitAWMapC);
-                }
-
-                if ( is_anybininVgate_high) {
-                    if (m_doStraws) {
-                        HitAWMapS = thisStrawNumber;
-HitAWMapS_passed = 1.0;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitAWMapS_passed, HitAWMapS);
-                    }
-                    if (m_doChips) {
-                        HitAWMapC = chip - 1;
-HitAWMapC_passed = 1.0;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitAWMapC_passed, HitAWMapC);
-                    }
-                }
-        
-                if (m_doStraws) {
-                    HitToTMapS_x = thisStrawNumber;
-                    HitToTMapS_y = timeOverThreshold;
-                    fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitToTMapS_x, HitToTMapS_y);
-
-                    if (timeOverThreshold > m_longToTCut) {
-                        HitToTLongMapS_x = thisStrawNumber;
-                        HitToTLongMapS_y = timeOverThreshold;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitToTLongMapS_x, HitToTLongMapS_y);
-                        HitToTLongTrMapS_x = thisStrawNumber;
-                        HitToTLongTrMapS_y = trailingEdgeScaled;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitToTLongTrMapS_x, HitToTLongTrMapS_y);
-                    }
-                }
-
-                if (m_doChips) {
-                    HitToTMapC_x = chip - 1;
-                    HitToTMapC_y = timeOverThreshold;
-                    fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HitToTMapC_x, HitToTMapC_y);
-                }
-
-                if (m_doChips) {
+                    chip_struct& this_struct = chip_map[ibe][iphi_module].emplace_back();
+                    this_struct.chipNumber = chip - 1;
+                    this_struct.HitWMapC_passed = (driftTimeBin > 2) && (driftTimeBin < 17) ? 1 : 0;
+                    this_struct.HitHMapC_passed = highlevel;
+                    this_struct.HitHWMapC_passed = highlevel && is_middleHTbit_high;
+                    this_struct.HitTrMapC_y = trailingEdgeScaled;
+                    this_struct.HitAMapC_passed = ((firstBinHigh || lastBinHigh || driftTimeBin > 0 || trailingEdge < 23) ? 1 : 0);
+                    this_struct.HitAWMapC_passed = is_anybininVgate_high ? 1 : 0;
+                    this_struct.HitToTMapC_y = timeOverThreshold;
+                    this_struct.HitTrWMapC_cut = (trailingEdge < 23) && !lastBinHigh && !firstBinHigh;
+                    this_struct.HtoBCMap_cut=false;
+                    this_struct.HtoBCMapB_y = board - 1;
+                    this_struct.HtoBCMapC_x = -1;
+                    this_struct.HtoBCMapB_x = -1;
                     if (p_lolum->highLevel(1)) {
-                        HtoBCMapC_x = 0.;
-                        HtoBCMapC_y = chip - 1;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HtoBCMapC_x, HtoBCMapC_y);
-                        HtoBCMapB_x = 0.;
-                        HtoBCMapB_y = board - 1;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HtoBCMapB_x, HtoBCMapB_y);
+                        this_struct.HtoBCMapC_x = 0.;
+                        this_struct.HtoBCMapB_x = 0.;
+                        this_struct.HtoBCMap_cut=true;
                     }
 
                     if (p_lolum->highLevel(2)) {
-                        HtoBCMapC_x = 1.;
-                        HtoBCMapC_y = chip - 1;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HtoBCMapC_x, HtoBCMapC_y);
-                        HtoBCMapB_x = 1.;
-                        HtoBCMapB_y = board - 1;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HtoBCMapB_x, HtoBCMapB_y);
+                        this_struct.HtoBCMapC_x = 1.;
+                        this_struct.HtoBCMapB_x = 1.;
+                        this_struct.HtoBCMap_cut=true;
                     }
 
                     if (p_lolum->highLevel(3)) {
-                        HtoBCMapC_x = 2.;
-                        HtoBCMapC_y = chip - 1;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HtoBCMapC_x, HtoBCMapC_y);
-                        HtoBCMapB_x = 2.;
-                        HtoBCMapB_y = board - 1;
-                        fill("RDOStackHistograms"+std::to_string(ibe)+std::to_string(iphi_module), HtoBCMapB_x, HtoBCMapB_y);
+                        this_struct.HtoBCMapC_x = 2.;
+                        this_struct.HtoBCMapB_x = 2.;
+                        this_struct.HtoBCMap_cut=true;
                     }
                 }
             }
@@ -1015,6 +933,63 @@ HitAWMapC_passed = 1.0;
         }
     }
 
+    for (const auto& ibarrel_ecpair : straw_shifter_map) {
+        int ibe = abs(ibarrel_ecpair.first) - 1;
+        int iside = ibarrel_ecpair.first > 0 ? 0 : 1;
+        auto strawNumber          = Monitored::Collection("strawNumber", ibarrel_ecpair.second, [](const auto& s){return s.strawNumber;});
+        auto HitWMap_passed       = Monitored::Collection("HitWMap_passed", ibarrel_ecpair.second, [](const auto& s){return s.HitWMap_passed;});
+        auto isAr    = Monitored::Collection("isAr", ibarrel_ecpair.second, [](const auto& s){return s.isAr;});
+        auto isNotAr    = Monitored::Collection("isNotAr", ibarrel_ecpair.second, [](const auto& s){return not s.isAr;});
+        if (ibe == 0) {
+            fill("RDOHistograms0", strawNumber, HitWMap_passed, isAr, isNotAr);
+        } else if (ibe == 1) {
+            fill("RDOHistograms1"+std::to_string(iside), strawNumber, HitWMap_passed, isAr, isNotAr);
+        }
+    }
+
+    for (const auto& ibepair : straw_map) {
+        for (const auto& iphi_modulepair : ibepair.second ) {
+            auto strawNumber          = Monitored::Collection("strawNumber", iphi_modulepair.second, [](const auto& s){return s.strawNumber;});
+            auto HitWMapS_passed      = Monitored::Collection("HitWMapS_passed", iphi_modulepair.second, [](const auto& s){return s.HitWMapS_passed;});
+            auto HitAWMapS_passed     = Monitored::Collection("HitAWMapS_passed", iphi_modulepair.second, [](const auto& s){return s.HitAWMapS_passed;});
+            auto HitAMapS_passed      = Monitored::Collection("HitAMapS_passed", iphi_modulepair.second, [](const auto& s){return s.HitAMapS_passed;});
+            auto HitHMapS_passed      = Monitored::Collection("HitHMapS_passed", iphi_modulepair.second, [](const auto& s){return s.HitHMapS_passed;});
+            auto HitHWMapS_passed     = Monitored::Collection("HitHWMapS_passed", iphi_modulepair.second, [](const auto& s){return s.HitHWMapS_passed;});
+            auto HitTrMapS_y          = Monitored::Collection("HitTrMapS_y", iphi_modulepair.second, [](const auto& s){return s.HitTrMapS_y;});
+            auto HitToTMapS_y         = Monitored::Collection("HitToTMapS_y", iphi_modulepair.second, [](const auto& s){return s.HitToTMapS_y;});
+            auto HitToTLong_cut       = Monitored::Collection("HitToTLong_cut", iphi_modulepair.second, [](const auto& s){return s.HitToTLong_cut;});
+            auto HitTrWMapS_cut       = Monitored::Collection("HitTrWMapS_cut", iphi_modulepair.second, [](const auto& s){return s.HitTrWMapS_cut;});
+
+            fill("RDOStackHistograms"+std::to_string(ibepair.first)+std::to_string(iphi_modulepair.first), strawNumber,
+                 HitWMapS_passed, HitHWMapS_passed, HitHMapS_passed, HitAMapS_passed, HitAWMapS_passed,
+                 HitTrMapS_y, HitToTMapS_y, HitToTLong_cut, HitTrWMapS_cut);
+        }
+    }
+
+    for (const auto& ibepair : chip_map) {
+        for (const auto& iphi_modulepair : ibepair.second ) {
+            auto chipNumber           = Monitored::Collection("chipNumber", iphi_modulepair.second, [](const auto& s){return s.chipNumber;});
+            auto HitWMapC_passed      = Monitored::Collection("HitWMapC_passed", iphi_modulepair.second, [](const auto& s){return s.HitWMapC_passed;});
+            auto HitAWMapC_passed     = Monitored::Collection("HitAWMapC_passed", iphi_modulepair.second, [](const auto& s){return s.HitAWMapC_passed;});
+            auto HitAMapC_passed      = Monitored::Collection("HitAMapC_passed", iphi_modulepair.second, [](const auto& s){return s.HitAMapC_passed;});
+            auto HitHMapC_passed      = Monitored::Collection("HitHMapC_passed", iphi_modulepair.second, [](const auto& s){return s.HitHMapC_passed;});
+            auto HitHWMapC_passed     = Monitored::Collection("HitHWMapC_passed", iphi_modulepair.second, [](const auto& s){return s.HitHWMapC_passed;});
+            auto HitTrMapC_y          = Monitored::Collection("HitTrMapC_y", iphi_modulepair.second, [](const auto& s){return s.HitTrMapC_y;});
+            auto HitToTMapC_y         = Monitored::Collection("HitToTMapC_y", iphi_modulepair.second, [](const auto& s){return s.HitToTMapC_y;});
+            auto HtoBCMapC_x          = Monitored::Collection("HtoBCMapC_x", iphi_modulepair.second, [](const auto& s){return s.HtoBCMapC_x;});
+            auto HtoBCMapB_x          = Monitored::Collection("HtoBCMapB_x", iphi_modulepair.second, [](const auto& s){return s.HtoBCMapB_x;});
+            auto HtoBCMapB_y          = Monitored::Collection("HtoBCMapB_y", iphi_modulepair.second, [](const auto& s){return s.HtoBCMapB_y;});
+            auto HtoBCMap_cut = Monitored::Collection("HtoBCMap_cut", iphi_modulepair.second, [](const auto& s){return s.HtoBCMap_cut;});
+            auto HitTrWMapC_cut = Monitored::Collection("HitTrWMapC_cut", iphi_modulepair.second, [](const auto& s){return s.HitTrWMapC_cut;});
+
+            fill("RDOStackHistograms"+std::to_string(ibepair.first)+std::to_string(iphi_modulepair.first), 
+                 chipNumber, HitWMapC_passed, HitHWMapC_passed, HitHMapC_passed,
+                 HitAMapC_passed, HitAWMapC_passed, HitTrMapC_y, HitToTMapC_y, 
+                 HtoBCMapC_x, HtoBCMapB_x, HtoBCMapB_y,
+                 HtoBCMap_cut, HitTrWMapC_cut);
+        }
+    }
+
     OccAll = nhitsall/350848.;
     fill("RDOHistograms0", OccAll);
 
@@ -1064,16 +1039,12 @@ HitAWMapC_passed = 1.0;
 //                            m_LLOcc[ibe][LLocc_index] += occLL;
                             AvgLLOcc_side_x = i - (32 * nclass);
                             AvgLLOcc_side_y = occLL;
-                            fill("RDOLLHLOccHistograms"+std::to_string(ibe)+std::to_string(iside), AvgLLOcc_side_x, AvgLLOcc_side_y);
                             AvgHLOcc_side_x = i - (32 * nclass);
                             AvgHLOcc_side_y = occHL;
-                            fill("RDOLLHLOccHistograms"+std::to_string(ibe)+std::to_string(iside), AvgHLOcc_side_x, AvgHLOcc_side_y);
                             AvgLLOccMod_side_x = i;
                             AvgLLOccMod_side_y = occLL;
-                            fill("RDOLLHLOccHistograms"+std::to_string(ibe)+std::to_string(iside), AvgLLOccMod_side_x, AvgLLOccMod_side_y);
                             AvgHLOccMod_side_x = i;
                             AvgHLOccMod_side_y = occHL;
-                            fill("RDOLLHLOccHistograms"+std::to_string(ibe)+std::to_string(iside), AvgHLOccMod_side_x, AvgHLOccMod_side_y);
                         } else if (ibe == 1) {
                             float occLL = float(moduleHits_E[modulenum_tmp]) / float(numberOfStrawsWheel[nclass]);
                             float occHL = float(HLmoduleHits_E[modulenum_tmp]) / float(numberOfStrawsWheel[nclass]);
@@ -1085,17 +1056,15 @@ HitAWMapC_passed = 1.0;
                             }
                             AvgLLOcc_side_x = i - (32 * nclass);
                             AvgLLOcc_side_y = occLL;
-                            fill("RDOLLHLOccHistograms"+std::to_string(ibe)+std::to_string(iside), AvgLLOcc_side_x, AvgLLOcc_side_y);
                             AvgHLOcc_side_x = i - (32 * nclass);
                             AvgHLOcc_side_y = occHL;
-                            fill("RDOLLHLOccHistograms"+std::to_string(ibe)+std::to_string(iside), AvgHLOcc_side_x, AvgHLOcc_side_y);
                             AvgLLOccMod_side_x = i;
                             AvgLLOccMod_side_y = occLL;
-                            fill("RDOLLHLOccHistograms"+std::to_string(ibe)+std::to_string(iside), AvgLLOccMod_side_x, AvgLLOccMod_side_y);
                             AvgHLOccMod_side_x = i;
                             AvgHLOccMod_side_y = occHL;
-                            fill("RDOLLHLOccHistograms"+std::to_string(ibe)+std::to_string(iside), AvgHLOccMod_side_x, AvgHLOccMod_side_y);
                         }
+                        fill("RDOLLHLOccHistograms"+std::to_string(ibe)+std::to_string(iside), AvgLLOcc_side_x, AvgLLOcc_side_y, AvgHLOcc_side_x, AvgHLOcc_side_y,
+                                AvgLLOccMod_side_x, AvgLLOccMod_side_y, AvgHLOccMod_side_x, AvgHLOccMod_side_y);
                     }
                 }
             }
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/CMakeLists.txt b/MuonSpectrometer/MuonReconstruction/MuonRecExample/CMakeLists.txt
index 46587464553de049b69024350f0a1bea758ea7c2..1ea44ff32d6448a1909ed4c79ad479465797f175 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/CMakeLists.txt
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/CMakeLists.txt
@@ -6,6 +6,6 @@
 atlas_subdir( MuonRecExample )
 
 # Install files from the package:
-atlas_install_python_modules( python/*.py )
+atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
 atlas_install_joboptions( share/*.py )
 
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/ConfiguredMuonRec.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/ConfiguredMuonRec.py
index 2918cb5eb6b4a62ac34a0050157ea096172b328e..08fa13e62601b26617dd8f2ee0aa2241fe16515e 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/ConfiguredMuonRec.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/ConfiguredMuonRec.py
@@ -6,7 +6,6 @@ __all__ = [ 'ConfiguredMuonRec', 'GetMuonRec', 'CompositeMuonRec' ]
 import os
 
 from AthenaCommon.AlgSequence import AlgSequence
-from AthenaCommon.AppMgr import ToolSvc
 from AthenaCommon.ConfigurableDb import getConfigurable
 from AthenaCommon.Logging import logging
 
@@ -172,7 +171,7 @@ class ConfiguredMuonRec(object):
         if gaudiType != 'Algorithm':        
             raise TypeError( '%r is not an Algorithm, but an %s' % (alg,gaudiType) )
         # add to local dictionary
-        if not alg in self._algs:
+        if alg not in self._algs:
             self._algs.append( alg )
             # add to own dict for direct access: self.AlgName
             self.__dict__[ alg.getName() ] = alg
@@ -309,14 +308,14 @@ class ConfiguredMuonRec(object):
 
     def outputKey(self,name):
         """Return value of output key"""
-        return self_.outputKeys[name]
+        return self._outputKeys[name]
 
     def hasOutputKey(self,name):
         return name in self._outputKeys
 
     def inputKey(self,name):
         """Return value of output key"""
-        return self_.inputKeys[name]
+        return self._inputKeys[name]
 
     def hasInputKey(self,name):
         return name in self._inputKeys
@@ -389,6 +388,7 @@ class ConfiguredMuonRec(object):
         """Add all algorithms to topSequence, if not already in.
         Only needs to be called if it was disabled in the first place, but want to use anyway.
         BEWARE: as this adds to the end of topSequence, total order in topSequence may not be correct!!!"""
+        global topSequence
         self._enabled = True
         for alg in self._algs:
             if not hasattr(topSequence,alg.getName()):
@@ -568,7 +568,7 @@ class CompositeMuonRec(ConfiguredMuonRec):
     def propagateDataKeys(self,keys=None):
         """Propagate the date keys to the registered properties"""
         if keys is None: keys = self.dataKeys()
-        ConfigurableMuonRec.propagateDataKeys(self,keys)
+        ConfiguredMuonRec.propagateDataKeys(self,keys)
         for c in self.allConfigs():
             c.propagateDataKeys(keys)
 
@@ -707,7 +707,7 @@ class ParallelMuonRec(CompositeMuonRec):
         for c in self.allConfigs():
             try:
                 c.configure(keys)
-            except:
+            except Exception:
                 if self._applyResilience:
                    import traceback
                    traceback.print_exc()
@@ -781,7 +781,7 @@ def GetMuonRec(configTag,doConfigure=True,applyResilience=False, **kwargs):
             # store for later reference ('singleton')
             _muonRecInstances[configInfo.fullTag] = theInstance
             return theInstance
-        except:
+        except Exception:
             if applyResilience:
                 import traceback
                 traceback.print_exc()
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/CscTools.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/CscTools.py
index ea453983eef3a230b6e9c83c75cff879d2277cc3..073f12134ea746f04da4fca9e60adf3603a4ae4c 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/CscTools.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/CscTools.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 __doc__ = """Configuration of tools for CSC reconstruction"""
 
@@ -10,29 +10,14 @@ __doc__ = """Configuration of tools for CSC reconstruction"""
 from AthenaCommon.Logging import logging
 logging.getLogger().info("Importing %s", __name__)
 
-import copy
-
-from AthenaCommon.AppMgr import ServiceMgr,ToolSvc
 from AthenaCommon.GlobalFlags import globalflags
 from AthenaCommon.BeamFlags import jobproperties
 beamFlags = jobproperties.Beam
 from AthenaCommon import CfgMgr
+from AthenaCommon.CfgGetter import getPublicTool, getPrivateTool
 
-from RecExConfig.RecFlags import rec
-
-from AthenaCommon.CfgGetter import getPrivateTool,getPrivateToolClone,getPublicTool,getPublicToolClone,getService,getServiceClone
-
-from AthenaCommon.ConfiguredFactory import getProperty
-
-from MuonRecExample.MuonRecUtils import logMuon,ConfiguredBase,ExtraFlags
 from MuonRecExample.MuonAlignFlags import muonAlignFlags
 
-from AthenaCommon.CfgGetter import addTool, addToolClone, addService, addAlgorithm, \
-     addTypesToExcludeIfDefaultValue, addNamesToExcludeIfDefaultValue, addFullNamesToExcludeIfDefaultValue, \
-     addPropertiesToExcludeIfDefault, \
-     addTypesToSkipIfNotAvailable, addNamesToSkipIfNotAvailable, addFullNamesToSkipIfNotAvailable, \
-     addTypesOnlyToSkip
-
 
 def CscAlignmentTool(name="CscAlignmentTool",extraFlags=None,**kwargs):
     etaposAlignConsts = [ # 1st, 2nd, 3rd, 4th layer 
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MooreTools.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MooreTools.py
index f4426e2f13f3da6ca939a782aa7c42ae6307b7a4..8933cfd7901349ca2bb701f496a68c91bab99d74 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MooreTools.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MooreTools.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 __doc__ = """Configuration of tools for Moore muon reconstruction"""
 
@@ -10,9 +10,7 @@ __doc__ = """Configuration of tools for Moore muon reconstruction"""
 from AthenaCommon.Logging import logging
 logging.getLogger().info("Importing %s", __name__)
 
-import copy
-
-from AthenaCommon.AppMgr import ServiceMgr,ToolSvc
+from AthenaCommon.AppMgr import ServiceMgr
 from AthenaCommon.GlobalFlags import globalflags
 from AthenaCommon.BeamFlags import jobproperties
 beamFlags = jobproperties.Beam
@@ -20,17 +18,15 @@ from AthenaCommon.BFieldFlags import jobproperties
 from AthenaCommon import CfgMgr
 from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
 
-from RecExConfig.RecFlags import rec
-
-from AthenaCommon.CfgGetter import getPrivateTool,getPrivateToolClone,getPublicTool,getPublicToolClone,getService,getServiceClone
+from AthenaCommon.CfgGetter import getPublicTool, getPublicToolClone, getPrivateTool
 
 from AthenaCommon.ConfiguredFactory import getProperty
 from IOVDbSvc.CondDB import conddb
 
 from MuonCnvExample.MuonCnvUtils import mdtCalibWindowNumber
 
-from .MuonRecTools import MuonExtrapolator, MuonChi2TrackFitter, MdtDriftCircleOnTrackCreator, MuonRK_Propagator
-from .MuonRecUtils import logMuon,ConfiguredBase,ExtraFlags
+from .MuonRecTools import MuonExtrapolator, MuonChi2TrackFitter
+from .MuonRecUtils import ConfiguredBase,ExtraFlags
 
 
 from .MuonRecFlags import muonRecFlags
@@ -258,7 +254,7 @@ def MooTrackBuilder(name="MooTrackBuilderTemplate",
         newMatchingToolName = namePrefix+oldMatchingToolName+namePostfix
         builder.CandidateMatchingTool = getPublicToolClone(newMatchingToolName,oldMatchingToolName,extraFlags=extraFlags)
 
-    import MuonCombinedRecExample.CombinedMuonTrackSummary
+    import MuonCombinedRecExample.CombinedMuonTrackSummary  # noqa: F401
     from AthenaCommon.AppMgr import ToolSvc
     kwargs.setdefault("TrackSummaryTool", ToolSvc.CombinedMuonTrackSummary)
     
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuPatTools.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuPatTools.py
index 91ebcde3aa1b936e1c6034e48c1596ec8229a84f..21c120eec547f75669d49f39ae7730f72509219e 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuPatTools.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuPatTools.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 __doc__ = """Configuration of tools for muon track reconstruction"""
 
@@ -8,21 +8,15 @@ __doc__ = """Configuration of tools for muon track reconstruction"""
 #
 #==============================================================
 
-from AthenaCommon.AppMgr import ServiceMgr
-from AthenaCommon.GlobalFlags import globalflags
 from AthenaCommon.BeamFlags import jobproperties
 beamFlags = jobproperties.Beam
 from AthenaCommon.BFieldFlags import jobproperties
 from AthenaCommon import CfgMgr
 
-from RecExConfig.RecFlags import rec
-
 from .MuonRecFlags import muonRecFlags
-from .MuonStandaloneFlags import muonStandaloneFlags
-
-from .MuonRecUtils import logMuon,ConfiguredBase
+from .MuonRecUtils import ConfiguredBase
 
-from AthenaCommon.CfgGetter import getPrivateTool,getPrivateToolClone,getPublicTool,getPublicToolClone,getService,getServiceClone
+from AthenaCommon.CfgGetter import getPublicTool
 from AtlasGeoModel.MuonGMJobProperties import MuonGeometryFlags
 
 #==============================================================
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonAlignConfig.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonAlignConfig.py
index 8660ab43458ebb82f41fc9c00ed29282fdcf0ff2..891823bc45e42bcdc23a08a33d038d32de505138 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonAlignConfig.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonAlignConfig.py
@@ -3,7 +3,6 @@
 #
 # read alignment constants from DB to update MuonGeoModel
 #
-from AthenaCommon.AppMgr import ToolSvc
 from AthenaCommon.GlobalFlags import globalflags
 
 from AthenaCommon.AlgSequence import AthSequencer
@@ -28,7 +27,6 @@ muonAlignFlags.setDefaults()
 ###############################################################
 
 
-import re
 logMuon.info("Reading alignment constants from DB")
 conddb.addFolderSplitOnline('MUONALIGN','/MUONALIGN/Onl/MDT/BARREL','/MUONALIGN/MDT/BARREL',className='CondAttrListCollection')
 conddb.addFolderSplitOnline('MUONALIGN','/MUONALIGN/Onl/MDT/ENDCAP/SIDEA','/MUONALIGN/MDT/ENDCAP/SIDEA',className='CondAttrListCollection')
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonAlignFlags.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonAlignFlags.py
index 7758518739b59ff1fa6631fadc32c7485c83457f..e54cc17c84366912dfa17bc2d6a22ce89df404af 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonAlignFlags.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonAlignFlags.py
@@ -1,10 +1,7 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
-from AthenaCommon.DetFlags import DetFlags
 from AthenaCommon.JobProperties import JobProperty,JobPropertyContainer,jobproperties
 from AthenaCommon.GlobalFlags import globalflags
-from AthenaCommon.DetFlags import DetFlags
 from AthenaCommon.Logging import logging
 import re 
 logMuon = logging.getLogger("MuonAlign")
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonCablingConfig.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonCablingConfig.py
index 1b634b4dd5c135dbe9f4554fb27b774fe25e0bda..20967895133359ee9189b9ecafe38b75dd1b423b 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonCablingConfig.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonCablingConfig.py
@@ -1,5 +1,5 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 from MuonRecExample.MuonRecUtils import logMuon
 logMuon.warning("MuonRecExample.MuonCablingConfig is deprecated. Use instead: import MuonCnvExample.MuonCablingConfig")
-import MuonCnvExample.MuonCablingConfig
+import MuonCnvExample.MuonCablingConfig  # noqa: F401
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonPrdProviderToolsConfig.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonPrdProviderToolsConfig.py
index b87693472b6e1616ea9f9337c0a77bc55c5e9121..edd0358ebe330792d03092db6a750495b75d68ab 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonPrdProviderToolsConfig.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonPrdProviderToolsConfig.py
@@ -1,35 +1,23 @@
 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-from AthenaCommon.Include import include
-
 from AthenaCommon.GlobalFlags import globalflags
 from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
 
-source = globalflags.DataSource()
-
-from AthenaCommon.DetFlags import DetFlags
-from AthenaCommon.AppMgr import ToolSvc
-from AthenaCommon.CfgGetter import getService,getPrivateTool
-from RecExConfig.RecAlgsFlags import recAlgs
-
-
 def RpcPrepDataProviderTool(name="RpcPrepDataProviderTool",**kwargs):
-  global source
-
   # setup dependencies which are not yet in C++
-  import MuonCnvExample.MuonCablingConfig
+  import MuonCnvExample.MuonCablingConfig  # noqa: F401
 
-  if source == 'data':
+  if globalflags.DataSource.is_data():
     kwargs["reduceCablingOverlap"] = True
     kwargs["produceRpcCoinDatafromTriggerWords"] = True
     kwargs["overlap_timeTolerance"] = 1000
     kwargs["solvePhiAmbiguities"] = True
     kwargs["etaphi_coincidenceTime"] = 1000
-  elif source == 'geant4':
+  elif globalflags.DataSource.is_geant4():
     pass
   #kwargs["etaphi_coincidenceTime"] = 100
   else:
-    raise ValueError( "RpcPrepDataProviderTool: unsupported dataSource %s" % source )
+    raise ValueError( "RpcPrepDataProviderTool: unsupported dataSource %s" % globalflags.DataSource() )
 
   from MuonRPC_CnvTools.MuonRPC_CnvToolsConf import Muon__RpcRdoToPrepDataToolMT
   if athenaCommonFlags.isOnline: 
@@ -38,16 +26,15 @@ def RpcPrepDataProviderTool(name="RpcPrepDataProviderTool",**kwargs):
 
 
 def MdtPrepDataProviderTool(name="MdtPrepDataProviderTool", **kwargs):
-  global source,include,getService,getPrivateTool
-
   # setup dependencies which are not yet in C++
-  import MuonCnvExample.MuonCablingConfig
-  from MuonRecExample import MuonAlignConfig
-  from MuonCnvExample import MuonCalibConfig
+  import MuonCnvExample.MuonCablingConfig     # noqa: F401
+  from MuonRecExample import MuonAlignConfig  # noqa: F401
+  from MuonCnvExample import MuonCalibConfig  # noqa: F401
+  from AthenaCommon.Include import include
   MuonCalibConfig.setupMdtCondDB()
   include("AmdcAth/AmdcAth_jobOptions.py")
   
-  if source == 'data':
+  if globalflags.DataSource.is_data():
     kwargs.setdefault("UseTwin", True)
 
   from MuonMDT_CnvTools.MuonMDT_CnvToolsConf import Muon__MdtRdoToPrepDataToolMT
@@ -56,7 +43,7 @@ def MdtPrepDataProviderTool(name="MdtPrepDataProviderTool", **kwargs):
 
 def TgcPrepDataProviderTool(name="TgcPrepDataProviderTool", **kwargs):
   # setup dependencies which are not yet in C++  
-  import MuonCnvExample.MuonCablingConfig
+  import MuonCnvExample.MuonCablingConfig  # noqa: F401
 
   from MuonTGC_CnvTools.MuonTGC_CnvToolsConf import Muon__TgcRdoToPrepDataToolMT
   return Muon__TgcRdoToPrepDataToolMT(name, **kwargs)
@@ -64,7 +51,7 @@ def TgcPrepDataProviderTool(name="TgcPrepDataProviderTool", **kwargs):
   
 def CscPrepDataProviderTool(name="CscPrepDataProviderTool", **kwargs):
   # setup dependencies which are not yet in C++
-  import MuonCnvExample.MuonCablingConfig
+  import MuonCnvExample.MuonCablingConfig  # noqa: F401
 
   from MuonCSC_CnvTools.MuonCSC_CnvToolsConf import Muon__CscRdoToCscPrepDataToolMT
   return Muon__CscRdoToCscPrepDataToolMT(name, **kwargs)
@@ -95,19 +82,3 @@ def STGC_PrepDataProviderTool(name="STGC_PrepDataProviderTool", **kwargs):
   return Muon__sTgcRdoToPrepDataTool(name,**kwargs)
 
 ### algorithms for other technologies can use C++ defaults
-
-
-### TODO: remove following backwards compat as soon as all clients have migrated to using CfgGetter
-from AthenaCommon.CfgGetter import getPrivateTool,getPrivateToolClone,getPublicTool,getPublicToolClone,getService,getServiceClone
-
-#if DetFlags.haveRDO.CSC_on() or DetFlags.digitize.CSC_on():
-#  CscRdoToPrepDataTool = getPublicTool("CscPrepDataProviderTool")
-
-#if DetFlags.haveRDO.MDT_on() or DetFlags.digitize.MDT_on():
-#  MdtRdoToPrepDataTool = getPublicTool("MdtPrepDataProviderTool")
-
-#if DetFlags.haveRDO.RPC_on() or DetFlags.digitize.RPC_on():
-#  RpcRdoToPrepDataTool = getPublicTool("RpcPrepDataProviderTool")
-
-#if DetFlags.haveRDO.TGC_on() or DetFlags.digitize.TGC_on():
-#  TgcRdoToPrepDataTool = getPublicTool("TgcPrepDataProviderTool")
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonReadBSConfig.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonReadBSConfig.py
deleted file mode 100644
index d15ff6cc742054533bea595523bd6720ca5ec0c8..0000000000000000000000000000000000000000
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonReadBSConfig.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
-# Tools and Algorithms are now defined in module MuonCnvExample.MuonBSConfig via ConfiguredFactory
-#
-# This file is for backwards compat - FILE TO BE REMOVED as soon as all clients get these tools via AthenaCommon.CfgGetter
-#
-from AthenaCommon.CfgGetter import getPublicTool
-if DetFlags.readRDOBS.MDT_on():
-    MuonMdtRawDataProviderTool = getPublicTool("MdtRawDataProviderTool")
-else:
-    MuonMdtRawDataProviderTool = None
-
-if DetFlags.readRDOBS.RPC_on():
-    MuonRpcRawDataProviderTool = getPublicTool("RpcRawDataProviderTool")
-else:
-    MuonRpcRawDataProviderTool = None
-
-if DetFlags.readRDOBS.TGC_on():
-    MuonTgcRawDataProviderTool = getPublicTool("TgcRawDataProviderTool")
-else:
-    MuonTgcRawDataProviderTool = None
-
-if DetFlags.readRDOBS.CSC_on():
-    MuonCscRawDataProviderTool = getPublicTool("CscRawDataProviderTool")
-else:
-    MuonCscRawDataProviderTool = None
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonReadCalib.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonReadCalib.py
index 9fd0975139fc517258b3972ca83fd9c85d379650..a098cba9f51d0eeded63190c5c9b80bd79542e10 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonReadCalib.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonReadCalib.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # MDT Calibration tools/services are defined in MuonCnvExample/python/MuonCalibConfig.py
 # For backwards compatibility, they are instantiated here, but this whole module
@@ -6,7 +6,7 @@
 from AthenaCommon.Logging import logging
 logging.getLogger().info("Importing %s", __name__)
 
-from AthenaCommon.CfgGetter import getPublicTool,getService,getPrivateTool,getAlgorithm
+from AthenaCommon.CfgGetter import getPublicTool
 from MuonRecExample.MuonRecFlags import muonRecFlags
 muonRecFlags.setDefaults()
 
@@ -14,6 +14,6 @@ if muonRecFlags.doCSCs():
     CscCalibTool = getPublicTool("CscCalibTool")
 
 if muonRecFlags.doMDTs():
-    from MuonRecExample import MuonAlignConfig
+    from MuonRecExample import MuonAlignConfig  # noqa: F401
     from MuonCnvExample import MuonCalibConfig
     MuonCalibConfig.setupMdtCondDB()
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRec.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRec.py
index eddc4632a0a239d2f164951d8f2e161a1f25e48b..ec677aec740034c688dc19f56c9ddbe9233dc91d 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRec.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRec.py
@@ -1,12 +1,9 @@
 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-from __future__ import print_function
-
 from .MuonRecFlags import muonRecFlags
 from .MuonStandaloneFlags import muonStandaloneFlags
 
 from .ConfiguredMuonRec import ParallelMuonRec
-from AthenaCommon.Logging import logging
 from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
 
 muonRecFlags.setDefaults()
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecExampleConfigDb.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecExampleConfigDb.py
index 10482c797a4214109e2ead74025908a71932a5fc..43d50649688b27f84eb03ccddd33d77dc04d2f11 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecExampleConfigDb.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecExampleConfigDb.py
@@ -1,13 +1,6 @@
 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-from AthenaCommon.CfgGetter import addTool, addToolClone, addService, addAlgorithm, \
-     addTypesToExcludeIfDefaultValue, addNamesToExcludeIfDefaultValue, addFullNamesToExcludeIfDefaultValue, \
-     addPropertiesToExcludeIfDefault, \
-     addTypesToSkipIfNotAvailable, addNamesToSkipIfNotAvailable, addFullNamesToSkipIfNotAvailable, \
-     addTypesOnlyToSkip
-
-from AthenaCommon.Constants import *  # FATAL,ERROR etc.
-
+from AthenaCommon.CfgGetter import addTool, addToolClone, addService, addAlgorithm, addNamesToSkipIfNotAvailable, addTypesOnlyToSkip
 from AtlasGeoModel.CommonGMJobProperties import CommonGeometryFlags
 from AtlasGeoModel.MuonGMJobProperties import MuonGeometryFlags
 
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecFlags.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecFlags.py
index b709d5e41bdac00ad811f2325b04cd08bd22d326..9caa24722af6672dd583d4e68b8138ed0dbc8279 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecFlags.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecFlags.py
@@ -1,24 +1,20 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 ## @file MuonRecFlags.py Flags to steer Muon Standalone Reconstruction
 
 ## @namespace python::MuonRecFlags @copydoc MuonRecFlags.py
 
-from AthenaCommon.JobProperties import JobProperty,JobPropertyContainer,jobproperties
-from AthenaCommon.Logging import logging
+from AthenaCommon.JobProperties import JobProperty,JobPropertyContainer
 from AthenaCommon.GlobalFlags import globalflags
 from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
 from AthenaCommon.DetFlags import DetFlags
 from AthenaCommon.BeamFlags import jobproperties
 beamFlags = jobproperties.Beam
 from RecExConfig.RecFlags import rec
-from MuonRecExample.MuonRecUtils import logMuon,logMuonResil,RecConfigInfo,fillJobPropertyContainer,SummaryJobProperty
+from MuonRecExample.MuonRecUtils import logMuon,fillJobPropertyContainer,SummaryJobProperty
 
-from MuonRecExample.MuonStandaloneFlags import muonStandaloneFlags
-
-from MuonCnvExample.MuonCalibFlags import mdtCalibFlags
-
-import copy
+from MuonRecExample.MuonStandaloneFlags import muonStandaloneFlags  # noqa: F401
+from MuonCnvExample.MuonCalibFlags import mdtCalibFlags   # noqa: F401
 
 logMuon.info("Importing %s", __name__)
 
@@ -550,12 +546,12 @@ class MuonRec(JobPropertyContainer):
 
 
         # do sync per technology for selected flags
-        MDT_on = self.doMDTs()
-        RPC_on = self.doRPCs()
-        CSC_on = self.doCSCs()
-        TGC_on = self.doTGCs()
-        sTGC_on = self.dosTGCs()
-        Micromegas_on = self.doMicromegas()
+        MDT_on = self.doMDTs()                # noqa: F841
+        RPC_on = self.doRPCs()                # noqa: F841
+        CSC_on = self.doCSCs()                # noqa: F841
+        TGC_on = self.doTGCs()                # noqa: F841
+        sTGC_on = self.dosTGCs()              # noqa: F841
+        Micromegas_on = self.doMicromegas()   # noqa: F841
         techList = technologies.split(',')
         for f in flagsOn:
             for tech in techList:
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecStandaloneOnlySetup.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecStandaloneOnlySetup.py
index f276a3ff0083d4bbe1ce26c6a451308d56810928..29e2b2d8caf4529bde26063c85e7c6d7fa440dd1 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecStandaloneOnlySetup.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecStandaloneOnlySetup.py
@@ -1,16 +1,14 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 __doc__ = """Set up the flags (for RecExCommon) so that only Muon Standalone Reconstruction is run.
 It sets default values for muonRecFlags, recFlags, globalflags, DetFlags."""
 
 from MuonRecExample.MuonRecFlags import muonRecFlags
-from MuonRecExample.MuonRecUtils import logMuon,logMuonResil
-from AthenaCommon.DetFlags import DetFlags 
+from AthenaCommon.DetFlags import DetFlags
 from AthenaCommon.GlobalFlags import globalflags
 from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
 from RecExConfig.RecFlags import rec as recFlags
 from RecExConfig.RecAlgsFlags import recAlgs as recAlgsFlags
-from RecExConfig.RecConfFlags import recConfFlags
 from MuonCombinedRecExample.MuonCombinedRecFlags import muonCombinedRecFlags
 
 import os
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecTools.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecTools.py
index f967c9556df00edbce6a1156d2dfa54f22ef99ad..49b060b6f8860aef4b2b687b615db173df969d10 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecTools.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecTools.py
@@ -3,8 +3,6 @@
 from AthenaCommon.Logging import logging
 logging.getLogger().info("Importing %s", __name__)
 
-from AthenaCommon.AppMgr import ToolSvc,ServiceMgr
-from AthenaCommon.Constants import *
 from AthenaCommon.GlobalFlags import globalflags
 from AthenaCommon.DetFlags import DetFlags
 from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
@@ -13,7 +11,7 @@ from AthenaCommon.BeamFlags import jobproperties
 beamFlags = jobproperties.Beam
 
 from MuonCnvExample.MuonCnvUtils import mdtCalibWindowNumber
-from MuonRecExample.MuonRecUtils import logMuon,ConfiguredBase,uglyHackedInclude,ExtraFlags
+from MuonRecExample.MuonRecUtils import logMuon,ConfiguredBase,ExtraFlags
 
 from MuonRecExample.MuonRecFlags import muonRecFlags
 muonRecFlags.setDefaults()
@@ -23,13 +21,7 @@ muonStandaloneFlags.setDefaults()
 
 from RecExConfig.RecFlags import rec
 
-
-from AthenaCommon.CfgGetter import getPrivateTool,getPrivateToolClone,getPublicTool,getPublicToolClone,\
-     getService,getServiceClone,getAlgorithm,getAlgorithmClone
-
-# temporarily for backwards compat. TO BE REMOVED
-from AthenaCommon.CfgGetter import addTool,addToolClone,addService
-
+from AthenaCommon.CfgGetter import getPrivateTool, getPrivateToolClone, getPublicTool, getService
 from AtlasGeoModel.MuonGMJobProperties import MuonGeometryFlags
 from TriggerJobOpts.TriggerFlags import TriggerFlags
 
@@ -50,6 +42,7 @@ def MMClusterOnTrackCreator(name="MMClusterOnTrackCreator",**kwargs):
 
 def getMuonRIO_OnTrackErrorScalingCondAlg() :
     error_scaling_def=["CSCRIO_OnTrackErrorScaling:/MUON/TrkErrorScalingCSC"]
+    from InDetRecExample.TrackingCommon import getRIO_OnTrackErrorScalingCondAlg
     return getRIO_OnTrackErrorScalingCondAlg( name                = "MuonRIO_OnTrackErrorScalingCondAlg",
                                               ReadKey             = "/MUON/TrkErrorScaling",
                                               CondDataAssociation = error_scaling_def)
@@ -59,7 +52,7 @@ def CscClusterOnTrackCreator(name="CscClusterOnTrackCreator",**kwargs):
     kwargs.setdefault("CscClusterFitter", getPrivateTool("QratCscClusterFitter") )
     kwargs.setdefault("CscClusterUtilTool", getPrivateTool("CscClusterUtilTool") )
     if False  : # enable CscClusterOnTrack error scaling :
-        from InDetRecExample.TrackingCommon import getRIO_OnTrackErrorScalingCondAlg,createAndAddCondAlg
+        from InDetRecExample.TrackingCommon import createAndAddCondAlg
         createAndAddCondAlg(getMuonRIO_OnTrackErrorScalingCondAlg,'RIO_OnTrackErrorScalingCondAlg')
 
         kwargs.setdefault("CSCErrorScalingKey","/MUON/TrkErrorScalingCSC")
@@ -77,8 +70,8 @@ def CscBroadClusterOnTrackCreator(name="CscBroadClusterOnTrackCreator",**kwargs)
 
 def MdtDriftCircleOnTrackCreator(name="MdtDriftCircleOnTrackCreator",**kwargs):
     # setup dependencies missing in C++. TODO: fix in C++
-    from MuonRecExample import MuonAlignConfig
-    from MuonCnvExample import MuonCalibConfig
+    from MuonRecExample import MuonAlignConfig  # noqa: F401
+    from MuonCnvExample import MuonCalibConfig  # noqa: F401
     MuonCalibConfig.setupMdtCondDB()
     from MuonCnvExample.MuonCalibFlags import mdtCalibFlags
     mdtCalibFlags.setDefaults()
@@ -191,7 +184,7 @@ def MuonHoughPatternFinderTool(name="MuonHoughPatternFinderTool",**kwargs):
 # combined tracking geometry service
 def AtlasTrackingGeometrySvc(name="AtlasTrackingGeometrySvc",**kwargs):
     global ServiceMgr
-    from TrkDetDescrSvc.AtlasTrackingGeometrySvc import AtlasTrackingGeometrySvc
+    from TrkDetDescrSvc.AtlasTrackingGeometrySvc import AtlasTrackingGeometrySvc  # noqa: F401
     return ServiceMgr.AtlasTrackingGeometrySvc
 
 
@@ -353,8 +346,8 @@ def MuonSegmentMomentum(name="MuonSegmentMomentum",**kwargs):
 
 def MdtSegmentT0Fitter(name="MdtSegmentT0Fitter",**kwargs):
     # setup dependencies missing in C++. TODO: fix in C++
-    from MuonRecExample import MuonAlignConfig
-    from MuonCnvExample import MuonCalibConfig
+    from MuonRecExample import MuonAlignConfig  # noqa: F401
+    from MuonCnvExample import MuonCalibConfig  # noqa: F401
     MuonCalibConfig.setupMdtCondDB()
     return CfgMgr.TrkDriftCircleMath__MdtSegmentT0Fitter(name,**kwargs)
 
@@ -390,7 +383,7 @@ def MuonClusterSegmentFinder(name="MuonClusterSegmentFinder", extraFlags=None,**
 
 def MuonClusterSegmentFinderTool(name="MuonClusterSegmentFinderTool", extraFlags=None,**kwargs):
     kwargs.setdefault("SLFitter","Trk::GlobalChi2Fitter/MCTBSLFitterMaterialFromTrack")
-    import MuonCombinedRecExample.CombinedMuonTrackSummary
+    import MuonCombinedRecExample.CombinedMuonTrackSummary  # noqa: F401
     from AthenaCommon.AppMgr import ToolSvc
     if TriggerFlags.MuonSlice.doTrigMuonConfig:
         kwargs.setdefault("TrackSummaryTool", "MuonTrackSummaryTool" )
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecUtils.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecUtils.py
index c1529c4ea9e7369903508b36870f181c078e6072..7333f6ced1156a7ba21c7a6e8c8777b3961399d1 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecUtils.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonRecUtils.py
@@ -5,19 +5,17 @@ logging.getLogger().info("Importing %s", __name__)
 
 from six import with_metaclass
 
-from GaudiKernel.GaudiHandles import \
-     GaudiHandle,GaudiHandleArray,\
-     PublicToolHandle,PublicToolHandleArray,\
-     PrivateToolHandle,PrivateToolHandleArray,\
-     ServiceHandle
+from GaudiKernel.GaudiHandles import (PublicToolHandle,PublicToolHandleArray,
+                                      PrivateToolHandle,PrivateToolHandleArray,
+                                      ServiceHandle )
 
 from AthenaCommon.JobProperties import JobProperty,jobproperties
 
 
-import os,sys,copy,re,subprocess
+import sys,copy
 
 # for backwards compat of clients. TO BE REMOVED !!!
-from AthenaCommon.ConfiguredFactory import getProperty
+from AthenaCommon.ConfiguredFactory import getProperty  # noqa: F401
 
 # logger to use for normal output
 logMuon = logging.getLogger("MuonRec")
@@ -498,7 +496,7 @@ def syncFlags( toProp, fromProp, logger = logMuon, ignoreLock = False ):
 def syncWinningFlag( prop1, prop2, logger = logMuon, ignoreLock = False ):
     if prop1.get_Value() != prop2.get_Value():
         contest = _whoWins( prop1, prop2, logger )
-        _syncFlags( contest.loser, contest.winner, logger, ignoreLock )
+        syncFlags( contest.loser, contest.winner, logger, ignoreLock )
 
 
 
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonStandalone.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonStandalone.py
index 4973cdd69fd064b5da8f423e16b011acc7d27f97..bed770e06a53e2f156b0ee2129f4ca02d511e6b4 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonStandalone.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonStandalone.py
@@ -13,16 +13,11 @@ from .MuonStandaloneFlags import muonStandaloneFlags,MoorelikeStrategy
 from .MuonRecFlags import muonRecFlags
 from .ConfiguredMuonRec import ConfiguredMuonRec
 
-from .MuonRecUtils import logMuon,ExtraFlags
+from .MuonRecUtils import ExtraFlags
 
-from RecExConfig.RecFlags import rec
-from AthenaCommon.DetFlags import DetFlags
-
-from AthenaCommon.CfgGetter import getPublicTool,getPublicToolClone,getPrivateTool
+from AthenaCommon.CfgGetter import getPublicTool,getPublicToolClone
 from RecExConfig.ObjKeyStore                  import cfgKeyStore
 
-import sys
-
 from AtlasGeoModel.MuonGMJobProperties import MuonGeometryFlags
 
 from TriggerJobOpts.TriggerFlags import TriggerFlags
@@ -151,8 +146,6 @@ class MuonStandalone(ConfiguredMuonRec):
         super(MuonStandalone,self).configure(keys)
         if not self.isEnabled(): return
 
-        from AthenaCommon.BeamFlags import jobproperties
-        beamFlags = jobproperties.Beam 
         SegmentLocation = "MuonSegments"
         if muonStandaloneFlags.segmentOrigin == 'TruthTracking':
             SegmentLocation = "ThirdChainSegments"
@@ -234,6 +227,6 @@ class MuonStandalone(ConfiguredMuonRec):
                  'tracksKey'        : tracksKey,
                  'doPhi'            : muonStandaloneFlags.trackBuilder == 'Moore',
                  'segmentAuthor'    : 5,
-		 'trackAuthor'	   : 200
+                 'trackAuthor'     : 200
                  }
                   
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonStandaloneFlags.py b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonStandaloneFlags.py
index cf6ec53a015c4280d034806b19c454eb37df8aee..fffe526be764c2a93f7941f9b206161aed1d9cba 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonStandaloneFlags.py
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecExample/python/MuonStandaloneFlags.py
@@ -1,12 +1,11 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 ## @file StandaloneFlags.py Flags for configuring the %Standalone muon reconstruction algorithm
 
 ## @namespace python::StandaloneFlags @copydoc StandaloneFlags.py
 
-from AthenaCommon.JobProperties import JobProperty,JobPropertyContainer,jobproperties
+from AthenaCommon.JobProperties import JobProperty,JobPropertyContainer
 from MuonRecExample.MuonRecUtils import fillJobPropertyContainer
-from AthenaCommon.GlobalFlags import globalflags
 from AthenaCommon.BeamFlags import jobproperties
 beamFlags = jobproperties.Beam
 
diff --git a/MuonSpectrometer/MuonValidation/MuonDQA/MuonRawDataMonitoring/MdtRawDataMonitoring/src/MdtRawDataMonAlg.cxx b/MuonSpectrometer/MuonValidation/MuonDQA/MuonRawDataMonitoring/MdtRawDataMonitoring/src/MdtRawDataMonAlg.cxx
index 9d0df654342e6b918637829f99048b778174608b..8315c90638439c88e0f44035be0b61efa2c9a61d 100755
--- a/MuonSpectrometer/MuonValidation/MuonDQA/MuonRawDataMonitoring/MdtRawDataMonitoring/src/MdtRawDataMonAlg.cxx
+++ b/MuonSpectrometer/MuonValidation/MuonDQA/MuonRawDataMonitoring/MdtRawDataMonitoring/src/MdtRawDataMonAlg.cxx
@@ -296,35 +296,39 @@ StatusCode MdtRawDataMonAlg::fillHistograms(const EventContext& ctx) const
   int lumiblock = -1;
   SG::ReadHandle<xAOD::EventInfo> evt(m_eventInfo, ctx);
   lumiblock = evt->lumiBlock();
-  
-  ATH_MSG_DEBUG("MdtRawDataMonAlg::MDT RawData Monitoring Histograms being filled" );
+
+  ATH_MSG_DEBUG("MdtRawDataMonAlg::MDT RawData Monitoring Histograms being filled");
 
   // Retrieve the LVL1 Muon RoIs:
   bool trig_BARREL = false;
   bool trig_ENDCAP = false;
-  if (!m_l1RoiKey.empty()) {
+  if (!m_l1RoiKey.empty())
+  {
     SG::ReadHandle<xAOD::MuonRoIContainer> muonRoIs(m_l1RoiKey, ctx);
-    if(!muonRoIs.isValid()){
-      ATH_MSG_ERROR("evtStore() does not contain muon L1 ROI Collection with name "<< m_l1RoiKey);
+    if (!muonRoIs.isValid())
+    {
+      ATH_MSG_ERROR("evtStore() does not contain muon L1 ROI Collection with name " << m_l1RoiKey);
     }
     //DEV still needed ? does not compile
-    if(muonRoIs.isPresent() && muonRoIs.isValid()){
-      ATH_MSG_VERBOSE( "Retrieved LVL1MuonRoIs object with key: " << m_l1RoiKey.key() ); 
-      trig_BARREL = std::any_of(muonRoIs->begin(), muonRoIs->end(), 
-                                [](const auto& i){return i->getSource() == xAOD::MuonRoI::RoISource::Barrel;});
-      trig_ENDCAP = std::any_of(muonRoIs->begin(), muonRoIs->end(), 
-                                [](const auto& i){return i->getSource() == xAOD::MuonRoI::RoISource::Endcap;});
+    if (muonRoIs.isPresent() && muonRoIs.isValid())
+    {
+      ATH_MSG_VERBOSE("Retrieved LVL1MuonRoIs object with key: " << m_l1RoiKey.key());
+      trig_BARREL = std::any_of(muonRoIs->begin(), muonRoIs->end(),
+                                [](const auto &i) { return i->getSource() == xAOD::MuonRoI::RoISource::Barrel; });
+      trig_ENDCAP = std::any_of(muonRoIs->begin(), muonRoIs->end(),
+                                [](const auto &i) { return i->getSource() == xAOD::MuonRoI::RoISource::Endcap; });
     }
   }
 
-  //declare MDT stuff 
+  //declare MDT stuff
   SG::ReadHandle<Muon::MdtPrepDataContainer> mdt_container(m_key_mdt, ctx);
-  if(!mdt_container.isValid()){
-    ATH_MSG_ERROR("evtStore() does not contain mdt prd Collection with name "<< m_key_mdt);
+  if (!mdt_container.isValid())
+  {
+    ATH_MSG_ERROR("evtStore() does not contain mdt prd Collection with name " << m_key_mdt);
     return StatusCode::FAILURE;
   }
 
-  ATH_MSG_DEBUG("****** mdtContainer->size() : " << mdt_container->size());  
+  ATH_MSG_DEBUG("****** mdtContainer->size() : " << mdt_container->size());
 
   int nColl = 0;        // Number of MDT chambers with hits
   int nColl_ADCCut = 0; // Number of MDT chambers with hits above ADC cut
@@ -333,8 +337,9 @@ StatusCode MdtRawDataMonAlg::fillHistograms(const EventContext& ctx) const
 
   //declare RPC stuff
   SG::ReadHandle<Muon::RpcPrepDataContainer> rpc_container(m_key_rpc, ctx);
-  if(!rpc_container.isValid()){
-    ATH_MSG_ERROR("evtStore() does not contain rpc prd Collection with name "<< m_key_rpc);
+  if (!rpc_container.isValid())
+  {
+    ATH_MSG_ERROR("evtStore() does not contain rpc prd Collection with name " << m_key_rpc);
     return StatusCode::FAILURE;
   }
 
@@ -343,160 +348,193 @@ StatusCode MdtRawDataMonAlg::fillHistograms(const EventContext& ctx) const
   Muon::RpcPrepDataContainer::const_iterator containerIt;
 
   /////////////////////////////this is the important plot!
-  float Nhitsrpc = 0 ;
-  for (containerIt = rpc_container->begin() ; containerIt != rpc_container->end() ; ++containerIt)
+  float Nhitsrpc = 0;
+  for (containerIt = rpc_container->begin(); containerIt != rpc_container->end(); ++containerIt)
   {
-    for (Muon::RpcPrepDataCollection::const_iterator rpcPrd = (*containerIt)->begin(); rpcPrd!=(*containerIt)->end(); ++rpcPrd)
+    for (Muon::RpcPrepDataCollection::const_iterator rpcPrd = (*containerIt)->begin(); rpcPrd != (*containerIt)->end(); ++rpcPrd)
     {
-      ++Nhitsrpc ;
-    }}
-  float Nhitsmdt = 0 ;
+      ++Nhitsrpc;
+    }
+  }
+  float Nhitsmdt = 0;
   bool isNoiseBurstCandidate = false;
-  Muon::MdtPrepDataContainer::const_iterator MdtcontainerIt ;
-  for (MdtcontainerIt = mdt_container->begin() ; MdtcontainerIt != mdt_container->end() ; ++MdtcontainerIt)
+  Muon::MdtPrepDataContainer::const_iterator MdtcontainerIt;
+  for (MdtcontainerIt = mdt_container->begin(); MdtcontainerIt != mdt_container->end(); ++MdtcontainerIt)
   {
-    for (Muon::MdtPrepDataCollection::const_iterator mdtCollection=(*MdtcontainerIt)->begin(); mdtCollection!=(*MdtcontainerIt)->end(); ++mdtCollection )
+    for (Muon::MdtPrepDataCollection::const_iterator mdtCollection = (*MdtcontainerIt)->begin(); mdtCollection != (*MdtcontainerIt)->end(); ++mdtCollection)
     {
-      ++Nhitsmdt ;
+      ++Nhitsmdt;
     }
   }
 
-  if(Nhitsmdt > m_HighOccThreshold) isNoiseBurstCandidate = true;
-  std::string type="MDT";
+  if (Nhitsmdt > m_HighOccThreshold)
+    isNoiseBurstCandidate = true;
+  std::string type = "MDT";
   std::string hardware_name;
 
-  std::map<std::string,int> evnt_hitsperchamber_map;
-  std::set<std::string>  chambers_from_tracks;
+  std::map<std::string, int> evnt_hitsperchamber_map;
+  std::set<std::string> chambers_from_tracks;
 
-  if (m_doMdtESD==true) { 
+  if (m_doMdtESD == true)
+  {
     //DEV this shouls be done in some other way, in AthenaMonManager there is
     // Gaudi::Property<std::string> m_environmentStr {this,"Environment","user"}; ///< Environment string pulled from the job option and converted to enum
     //per il momento commento...
     //    if(m_environment == AthenaMonManager::tier0 || m_environment == AthenaMonManager::tier0ESD || m_environment == AthenaMonManager::online) {
-    if(true) { //DEV to be updated
+    if (true)
+    { //DEV to be updated
 
       SG::ReadHandle<xAOD::MuonContainer> muons(m_muonKey, ctx);
-      if(!muons.isValid()){
-	ATH_MSG_ERROR("evtStore() does not contain muon Collection with name "<< m_muonKey);
-	return StatusCode::FAILURE;
+      if (!muons.isValid())
+      {
+        ATH_MSG_ERROR("evtStore() does not contain muon Collection with name " << m_muonKey);
+        return StatusCode::FAILURE;
       }
-      for(const auto mu : *muons){
-
-	if(! (mu->muonType() == xAOD::Muon::Combined)) continue;
-	xAOD::Muon::Quality quality = m_muonSelectionTool->getQuality(*mu);
-	if (!(quality <= xAOD::Muon::Medium)) continue;
-	const   xAOD::TrackParticle* tp = mu->primaryTrackParticle();
-	if(tp){
-	  const Trk::Track * trk= tp->track();
-	  //this work only if tp are available
-	  if(!trk)  continue;	  
-	  //
-	  uint8_t ntri_eta=0;
-	  uint8_t n_phi=0; 
-	  tp->summaryValue(ntri_eta, xAOD::numberOfTriggerEtaLayers); 
-	  tp->summaryValue(n_phi, xAOD::numberOfPhiLayers); 
-	  if(ntri_eta+n_phi==0) continue;
-	}
+      for (const auto mu : *muons)
+      {
+
+        if (!(mu->muonType() == xAOD::Muon::Combined))
+          continue;
+        xAOD::Muon::Quality quality = m_muonSelectionTool->getQuality(*mu);
+        if (!(quality <= xAOD::Muon::Medium))
+          continue;
+        const xAOD::TrackParticle *tp = mu->primaryTrackParticle();
+        if (tp)
+        {
+          const Trk::Track *trk = tp->track();
+          //this work only if tp are available
+          if (!trk)
+            continue;
+          //
+          uint8_t ntri_eta = 0;
+          uint8_t n_phi = 0;
+          tp->summaryValue(ntri_eta, xAOD::numberOfTriggerEtaLayers);
+          tp->summaryValue(n_phi, xAOD::numberOfPhiLayers);
+          if (ntri_eta + n_phi == 0)
+            continue;
+        }
       }
 
       MDTOverviewHistogramStruct overviewPlots;
       MDTSummaryHistogramStruct summaryPlots[4][4][16][4][4]; // [region][layer][phi][crate_region][crate]
       //loop in MdtPrepDataContainer
-      for (Muon::MdtPrepDataContainer::const_iterator containerIt = mdt_container->begin(); containerIt != mdt_container->end(); ++containerIt) {
-        if (containerIt == mdt_container->end() || (*containerIt)->size()==0) continue;  //check if there are counts  
+      std::vector<std::string> v_hit_in_chamber_allphi;
+      std::map<std::string, std::vector<std::string>> v_hit_in_chamber;
+      for (Muon::MdtPrepDataContainer::const_iterator containerIt = mdt_container->begin(); containerIt != mdt_container->end(); ++containerIt)
+      {
+        if (containerIt == mdt_container->end() || (*containerIt)->size() == 0)
+          continue; //check if there are counts
         nColl++;
-        
+
         bool isHit_above_ADCCut = false;
         // loop over hits
-        for (Muon::MdtPrepDataCollection::const_iterator mdtCollection=(*containerIt)->begin(); mdtCollection!=(*containerIt)->end(); ++mdtCollection ) 
+        for (Muon::MdtPrepDataCollection::const_iterator mdtCollection = (*containerIt)->begin(); mdtCollection != (*containerIt)->end(); ++mdtCollection)
         {
           nPrd++;
 
-
           float adc = (*mdtCollection)->adc();
-	  hardware_name = getChamberName(*mdtCollection);
-          if(hardware_name.substr(0,3) == "BMG") adc /= 4.;
-          if( adc > m_ADCCut ) 
+          hardware_name = getChamberName(*mdtCollection);
+          if (hardware_name.substr(0, 3) == "BMG")
+            adc /= 4.;
+          if (adc > m_ADCCut)
           {
             nPrdcut++;
             isHit_above_ADCCut = true;
-	    std::string phi=hardware_name.substr( hardware_name.length() - 2); 
-	    auto hit_in_chamber = Monitored::Scalar<std::string>("hits_phi_"+phi,hardware_name); 
-	    if(m_do_mdtchamberstatphislice)    fill("MdtMonitor",hit_in_chamber);    
-	    auto hit_in_chamber_allphi = Monitored::Scalar<std::string>("hits_allphi",hardware_name); 
-	    fill("MdtMonitor",hit_in_chamber_allphi);                                                                                   
+            if (m_do_mdtchamberstatphislice)
+            {
+              std::string phi = hardware_name.substr(hardware_name.length() - 2);
+              v_hit_in_chamber[phi].push_back(hardware_name);
+            }
+            v_hit_in_chamber_allphi.push_back(hardware_name);
           }
           fillMDTOverviewVects(*mdtCollection, isNoiseBurstCandidate, overviewPlots);
-	  //=======================================================================
-	  //=======================================================================
-	  //=======================================================================
-
-	  ATH_CHECK(fillMDTSummaryVects(*mdtCollection, chambers_from_tracks, isNoiseBurstCandidate, trig_BARREL, trig_ENDCAP, summaryPlots));
-
-	  //=======================================================================
-	  //=======================================================================
-	  //=======================================================================
-	  if(m_doChamberHists){
-	    ATH_CHECK(fillMDTHistograms(*mdtCollection));
-	  }      
-
-          std::map<std::string,int>::iterator iter_hitsperchamber = evnt_hitsperchamber_map.find(hardware_name);
-          if ( iter_hitsperchamber == evnt_hitsperchamber_map.end() ) { 
-            evnt_hitsperchamber_map.insert( make_pair( hardware_name, 1 ) );
-          } 
-          else {
+          //=======================================================================
+          //=======================================================================
+          //=======================================================================
+
+          ATH_CHECK(fillMDTSummaryVects(*mdtCollection, chambers_from_tracks, isNoiseBurstCandidate, trig_BARREL, trig_ENDCAP, summaryPlots));
+
+          //=======================================================================
+          //=======================================================================
+          //=======================================================================
+          if (m_doChamberHists)
+          {
+            ATH_CHECK(fillMDTHistograms(*mdtCollection));
+          }
+
+          std::map<std::string, int>::iterator iter_hitsperchamber = evnt_hitsperchamber_map.find(hardware_name);
+          if (iter_hitsperchamber == evnt_hitsperchamber_map.end())
+          {
+            evnt_hitsperchamber_map.insert(make_pair(hardware_name, 1));
+          }
+          else
+          {
             iter_hitsperchamber->second += 1;
-          }     
+          }
 
         } // for loop over hits mdtcollection
-        if( isHit_above_ADCCut ) 
+        if (isHit_above_ADCCut)
           nColl_ADCCut++;
       } //loop in MdtPrepDataContainer
+      if (m_do_mdtchamberstatphislice)
+      {
+        for (const auto &phiitem : v_hit_in_chamber)
+        {
+          auto hit_in_chamber = Monitored::Collection("hits_phi_" + phiitem.first, phiitem.second);
+          fill("MdtMonitor", hit_in_chamber);
+        }
+      }
+      auto hit_in_chamber_allphi = Monitored::Collection("hits_allphi", v_hit_in_chamber_allphi);
+      fill("MdtMonitor", hit_in_chamber_allphi);
 
       fillMDTOverviewHistograms(overviewPlots);
 
-      ATH_CHECK( fillMDTSummaryHistograms(summaryPlots, lumiblock) );
-      
+      ATH_CHECK(fillMDTSummaryHistograms(summaryPlots, lumiblock));
+
       int nHighOccChambers = 0;
-      for(const auto& iterstat: evnt_hitsperchamber_map) {
-	const auto iter_tubesperchamber = m_tubesperchamber_map.find(iterstat.first);
-	if (ATH_UNLIKELY(iter_tubesperchamber == m_tubesperchamber_map.end())) { // indicates software error
-	  ATH_MSG_ERROR("Unable to find chamber " << iterstat.first);
-	  continue;
-	}
-	float nTubes = iter_tubesperchamber->second;
-	float hits = iterstat.second;
-	float occ = hits/nTubes;
-	if ( occ > 0.1 ) nHighOccChambers++;
+      for (const auto &iterstat : evnt_hitsperchamber_map)
+      {
+        const auto iter_tubesperchamber = m_tubesperchamber_map.find(iterstat.first);
+        if (ATH_UNLIKELY(iter_tubesperchamber == m_tubesperchamber_map.end()))
+        { // indicates software error
+          ATH_MSG_ERROR("Unable to find chamber " << iterstat.first);
+          continue;
+        }
+        float nTubes = iter_tubesperchamber->second;
+        float hits = iterstat.second;
+        float occ = hits / nTubes;
+        if (occ > 0.1)
+          nHighOccChambers++;
       }
-      
+
       auto nHighOccChambers_mon = Monitored::Scalar<float>("nHighOccChambers_mon", nHighOccChambers);
 
       auto nPrd_mon = Monitored::Scalar<int>("nPrd_mon", nPrd);
       auto nPrdcut_mon = Monitored::Scalar<int>("nPrdcut_mon", nPrdcut);
       auto Nhitsrpc_mon = Monitored::Scalar<int>("Nhitsrpc_mon", Nhitsrpc);
-      auto nColl_mon = Monitored::Scalar<int>("nColl_mon", nColl);      
+      auto nColl_mon = Monitored::Scalar<int>("nColl_mon", nColl);
       auto nColl_ADCCut_mon = Monitored::Scalar<int>("nColl_ADCCut_mon", nColl_ADCCut);
-      
-      fill("MdtMonitor",nHighOccChambers_mon,nPrd_mon,Nhitsrpc_mon,nPrdcut_mon, nColl_mon, nColl_ADCCut_mon);
+
+      fill("MdtMonitor", nHighOccChambers_mon, nPrd_mon, Nhitsrpc_mon, nPrdcut_mon, nColl_mon, nColl_ADCCut_mon);
 
       //        if (m_mdtglobalhitstime) m_mdtglobalhitstime->Fill(m_time - m_firstTime);
 
-    }  //m_environment == AthenaMonManager::tier0 || m_environment == AthenaMonManager::tier0ESD   
-  } //m_doMdtESD==true
+    } //m_environment == AthenaMonManager::tier0 || m_environment == AthenaMonManager::tier0ESD
+  }   //m_doMdtESD==true
 
-  SG::ReadHandle<Trk::SegmentCollection> segms(m_segm_type, ctx);                                                                                                   
-  if(!segms.isValid()){                                                                                                                                                                     
-    ATH_MSG_ERROR("evtStore() does not contain mdt segms Collection with name "<< m_segm_type);                                                                                        
-    return StatusCode::FAILURE;                                                                                                                                                                
-  }                                  
+  SG::ReadHandle<Trk::SegmentCollection> segms(m_segm_type, ctx);
+  if (!segms.isValid())
+  {
+    ATH_MSG_ERROR("evtStore() does not contain mdt segms Collection with name " << m_segm_type);
+    return StatusCode::FAILURE;
+  }
 
-  MDTSegmentHistogramStruct   segsPlots[4][4][16]; // [region][layer][phi]
-  ATH_CHECK(handleEvent_effCalc_fillVects( segms.cptr(), segsPlots ));    
+  MDTSegmentHistogramStruct segsPlots[4][4][16]; // [region][layer][phi]
+  ATH_CHECK(handleEvent_effCalc_fillVects(segms.cptr(), segsPlots));
   ATH_CHECK(fillMDTSegmentHistograms(segsPlots));
 
   return StatusCode::SUCCESS;
-} 
+}
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
 
 void MdtRawDataMonAlg::fillMDTOverviewVects( const Muon::MdtPrepData* mdtCollection, bool &isNoiseBurstCandidate, MDTOverviewHistogramStruct& vects ) const {
@@ -828,20 +866,15 @@ StatusCode MdtRawDataMonAlg::fillMDTSummaryHistograms( const MDTSummaryHistogram
 	    
 	    auto adc_mon =  Monitored::Collection("adc_mon", thisVects.adc_mon); 
 	    auto tdc_mon =  Monitored::Collection("tdc_mon", thisVects.tdc_mon); 
-	    fill(MDT_regionGroup, adc_mon, tdc_mon);
 	    
 	    auto tdc_mon_nb2 =  Monitored::Collection("tdc_mon_nb2", thisVects.tdc_mon_nb2); 
 	    auto adc_mon_nb2 =  Monitored::Collection("adc_mon_nb2", thisVects.adc_mon_nb2); 
-	    fill(MDT_regionGroup, tdc_mon_nb2, adc_mon_nb2);
 	    
 	    auto tdc_mon_nb1 =  Monitored::Collection("tdc_mon_nb1", thisVects.tdc_mon_nb1); 
 	    auto adc_mon_nb1 =  Monitored::Collection("adc_mon_nb1", thisVects.adc_mon_nb1); 
-	    fill(MDT_regionGroup, tdc_mon_nb1, adc_mon_nb1);
 	    
 	    auto adc_mon_adccut =  Monitored::Collection("adc_mon_adccut", thisVects.adc_mon_adccut);
 	    auto tdc_mon_adccut =  Monitored::Collection("tdc_mon_adccut", thisVects.tdc_mon_adccut);
-	    //	    fill(MDT_regionGroup, stationEta, tdc_mon_adccut, adc_mon_adccut);
-	    fill(MDT_regionGroup, tdc_mon_adccut, adc_mon_adccut);
 	    
 	    std::string varx = iregion < 2 ? "x_mon_barrel" : "x_mon_endcap";
 	    std::string vary = iregion < 2 ? "y_mon_barrel" : "y_mon_endcap";
@@ -850,19 +883,17 @@ StatusCode MdtRawDataMonAlg::fillMDTSummaryHistograms( const MDTSummaryHistogram
 	    
 	    auto x_mon =  Monitored::Collection(varx, thisVects.x_mon);
 	    auto y_mon =  Monitored::Collection(vary, thisVects.y_mon);
-	    fill("MdtMonitor",x_mon,y_mon);
 	    auto x_mon_noise =  Monitored::Collection(varx_noise, thisVects.x_mon_noise);
 	    auto y_mon_noise =  Monitored::Collection(vary_noise, thisVects.y_mon_noise);
-	    fill("MdtMonitor",x_mon_noise,y_mon_noise);
+	    fill("MdtMonitor",x_mon,y_mon,x_mon_noise,y_mon_noise);
 	    auto tdc_mon_nb3 =  Monitored::Collection("tdc_mon_nb3", thisVects.tdc_mon_nb3); 
-	    fill(MDT_regionGroup, tdc_mon_nb3);
+
 	    
 	    varx = "x_mon_"+region[iregion]+"_"+layer[ilayer];
 	    vary = "y_mon_"+region[iregion]+"_"+layer[ilayer];
 	    
 	    auto x_bin_perML =   Monitored::Collection(varx, thisVects.x_bin_perML);//get the right bin!!!! 
 	    auto y_bin_perML =   Monitored::Collection(vary, thisVects.y_bin_perML);
-	    fill(MDT_regionGroup,x_bin_perML,y_bin_perML);
 	    
 	    if(layer[ilayer]!="Extra"){
 	      varx="x_mon_"+layer[ilayer];
@@ -886,7 +917,9 @@ StatusCode MdtRawDataMonAlg::fillMDTSummaryHistograms( const MDTSummaryHistogram
 	    auto biny_name_bycrate_ontrack = "y_mon_bin_bycrate_ontrack_"+region[crate_region]+"_"+crate[icrate]; //y-axis of these histograms not yet defined
 	    auto biny_var_bycrate_ontrack = Monitored::Collection(biny_name_bycrate_ontrack, thisVects.biny_vslb_bycrate_ontrack); 
 
-	    fill(MDT_regionGroup,tdc_mon_rpc,tdc_mon_tgc,biny_var,lb_mon, biny_var, biny_var_bycrate, biny_var_bycrate_ontrack);
+	    fill(MDT_regionGroup, adc_mon, tdc_mon, tdc_mon_nb2, adc_mon_nb2, tdc_mon_adccut, adc_mon_adccut, tdc_mon_adccut, adc_mon_adccut,
+           tdc_mon_nb3, x_bin_perML, y_bin_perML, tdc_mon_rpc,tdc_mon_tgc,biny_var,lb_mon, 
+           biny_var, biny_var_bycrate, biny_var_bycrate_ontrack);
 
 	    
     //DEV to DO
diff --git a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTagRun3Config.py b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTagRun3Config.py
index a223f6da0499d46e9876923fb63c77754bf8c0b1..32e075b6e6017079c9599133483cae4db9ed05aa 100644
--- a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTagRun3Config.py
+++ b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTagRun3Config.py
@@ -273,11 +273,6 @@ def JetBTaggerSplitAlgsCfg(inputFlags, JetCollection="", TaggerList=[], SecVerte
         ]
     }
 
-    if jet in postTagDL2JetToTrainingMap:
-        #Remove DL1 and RNNIP from taggers list, those taggers are run with HighLevelBTagAlg
-        TaggerList.remove('RNNIP')
-        TaggerList.remove('DL1')
-
     #Track Association
     TrackToJetAssociators = list(set(SecVertexingAndAssociators.values()))
 
diff --git a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfigFlags.py b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfigFlags.py
index aac662b631f99284b55a10a19a6ad235c2abe770..ac81f5186b83e919fecd434598bb2e83ef81bb53 100644
--- a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfigFlags.py
+++ b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfigFlags.py
@@ -5,9 +5,9 @@ from AthenaConfiguration.AthConfigFlags import AthConfigFlags
 def createBTaggingConfigFlags():
     btagcf = AthConfigFlags()
 
-    btagcf.addFlag("BTagging.run2TaggersList", ['IP2D','IP3D','SV1','SoftMu','JetFitterNN','MV2c10','MV2c10mu','MV2c10rnn','MV2c100','MV2cl100','RNNIP','DL1','DL1mu','DL1rnn'])
+    btagcf.addFlag("BTagging.run2TaggersList", ['IP2D','IP3D','SV1','SoftMu','JetFitterNN','MV2c10'])
     btagcf.addFlag("BTagging.Run2TrigTaggers", ['IP2D','IP3D','SV1','JetFitterNN','MV2c10'])
-    btagcf.addFlag("BTagging.Run3NewTrigTaggers", ['RNNIP','DL1','DL1rnn'])
+    btagcf.addFlag("BTagging.Run3NewTrigTaggers", [])
     # Disable JetVertexCharge ATLASRECTS-4506
     btagcf.addFlag("BTagging.RunModus", "analysis") # reference mode used in FlavourTagPerformanceFramework (RetagFragment.py)
     btagcf.addFlag("BTagging.ReferenceType", "ALL") # reference type for IP and SV taggers (B, UDSG, ALL)
diff --git a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration.py b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration.py
index bdd0e39487fb3df279baf0361069a18d079edd40..7fa23ccd205515dec64c53716c485df1c97c2c89 100644
--- a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration.py
+++ b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration.py
@@ -42,7 +42,6 @@ from BTagging.BTaggingConfiguration_IP3DNegTag import *
 from BTagging.BTaggingConfiguration_IP3DTag import *
 from BTagging.BTaggingConfiguration_IP3DTrigTag import *
 from BTagging.BTaggingConfiguration_IP3DTrigHybridTag import *
-from BTagging.BTaggingConfiguration_RNNIPTag import *
 
 # Jet fitter taggers
 #from BTagging.BTaggingConfiguration_JetFitterCOMB import *
@@ -107,27 +106,18 @@ from BTagging.BTaggingConfiguration_MV2c100Tag import *
 from BTagging.BTaggingConfiguration_MV2c100FlipTag import *
 from BTagging.BTaggingConfiguration_MV2cl100Tag import *
 from BTagging.BTaggingConfiguration_MV2cl100FlipTag import *
-from BTagging.BTaggingConfiguration_MV2mTag import *
-from BTagging.BTaggingConfiguration_MV2mFlipTag import *
 from BTagging.BTaggingConfiguration_MV2c10hpTag import *
 from BTagging.BTaggingConfiguration_MV2c10hpFlipTag import *
 
 #JetVertexCharge tool
 from BTagging.BTaggingConfiguration_JetVertexCharge import *
 
-#ExKtbb tool
-from BTagging.BTaggingConfiguration_ExKtbbTag import *
-
 # MultivariateTagManager
 from BTagging.BTaggingConfiguration_MultivariateTagManager import *
 from BTagging.BTaggingConfiguration_MultivariateTrigTagManager import *
 from BTagging.BTaggingConfiguration_MultivariateFlipTagManager import *
 from BTagging.BTaggingConfiguration_MultiTrigHybridTagManager import *
 
-# DL1 tagger
-from BTagging.BTaggingConfiguration_DL1Tag import *
-from BTagging.BTaggingConfiguration_DL1FlipTag import *
-
 # TagNtupleDumper
 from BTagging.BTaggingConfiguration_TagNtupleDumper import *
 
diff --git a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_ExKtbbTag.py b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_ExKtbbTag.py
deleted file mode 100644
index 7ec236efc3f75cdee7c8bc7eb166138f7348bead..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_ExKtbbTag.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
-# Configuration functions for ExKtbbTag
-# Author: Qi Zeng (2015)
-
-from BTagging.BTaggingFlags import BTaggingFlags
-
-metaExKtbb_Hbb_MV2OnlyTag = { 'IsATagger'         : True,
-                              'xAODBaseName'      : 'ExKtbb',
-                              'DependsOn'         : ['MV2c20Tag',
-                                                     'BTagCalibrationBrokerTool'],
-                              'CalibrationTaggers' :['ExKtbb',],
-                              'PassByPointer'     : {'calibrationTool' : 'BTagCalibrationBrokerTool'},
-                              'ToolCollection'    : 'ExKtbbTag',
-                            }
-
-metaExKtbb_Hbb_MV2andJFDRSigTag = { 'IsATagger'         : True,
-                              'xAODBaseName'      : 'ExKtbb',
-                              'DependsOn'         : ['MV2c20Tag',
-                                                     'BTagCalibrationBrokerTool'],
-                              'CalibrationTaggers' :['ExKtbb',],
-                              'PassByPointer'     : {'calibrationTool' : 'BTagCalibrationBrokerTool'},
-                              'ToolCollection'    : 'ExKtbbTag',
-                               }
-
-metaExKtbb_Hbb_MV2andToposTag = { 'IsATagger'         : True,
-                              'xAODBaseName'      : 'ExKtbb',
-                              'DependsOn'         : ['MV2c20Tag',
-                                                     'BTagCalibrationBrokerTool'],
-                              'CalibrationTaggers' :['ExKtbb',],
-                              'PassByPointer'     : {'calibrationTool' : 'BTagCalibrationBrokerTool'},
-                              'ToolCollection'    : 'ExKtbbTag',
-                            }
-
-def toolExKtbb_Hbb_MV2OnlyTag(name, useBTagFlagsDefaults = True, **options):
-    """Sets up a ExKtbbTag tool and returns it.
-
-    The following options have BTaggingFlags defaults:
-
-    see below
-
-    input:             name: The name of the tool (should be unique).
-      useBTagFlagsDefaults : Whether to use BTaggingFlags defaults for options that are not specified.
-                  **options: Python dictionary with options for the tool.
-    output: The actual tool, which can then by added to ToolSvc via ToolSvc += output."""
-    if useBTagFlagsDefaults:
-        defaults = { 'OutputLevel'                      : BTaggingFlags.OutputLevel,
-                     'Runmodus'                         : BTaggingFlags.Runmodus,
-                     'tagMode'                          : 'Hbb',
-                     'BDTMode'                          : 'MV2Only',
-                     'taggerNameBase'                   : 'ExKtbb',
-                     'ForceCalibrationChannel'          : 'Default',
-                     'debug'                            : False,
-
-                     'SubJetLabel'                      : 'ExKt2SubJets',
-                     'JFOnlyVtx'                        : False,
-                   }
-        for option in defaults:
-            options.setdefault(option, defaults[option])
-    options['name'] = name
-    from JetTagTools.JetTagToolsConf import Analysis__ExKtbbTag
-    return Analysis__ExKtbbTag(**options)
-
-def toolExKtbb_Hbb_MV2andJFDRSigTag(name, useBTagFlagsDefaults = True, **options):
-    """Sets up a ExKtbbTag tool and returns it.
-
-    The following options have BTaggingFlags defaults:
-
-    see below
-
-    input:             name: The name of the tool (should be unique).
-      useBTagFlagsDefaults : Whether to use BTaggingFlags defaults for options that are not specified.
-                  **options: Python dictionary with options for the tool.
-    output: The actual tool, which can then by added to ToolSvc via ToolSvc += output."""
-    if useBTagFlagsDefaults:
-        defaults = { 'OutputLevel'                      : BTaggingFlags.OutputLevel,
-                     'Runmodus'                         : BTaggingFlags.Runmodus,
-                     'tagMode'                          : 'Hbb',
-                     'BDTMode'                          : 'MV2andJFDRSig',
-                     'taggerNameBase'                   : 'ExKtbb',
-                     'ForceCalibrationChannel'          : 'Default',
-                     'debug'                            : False,
-
-                     'SubJetLabel'                      : 'ExKt2SubJets',
-                     'JFOnlyVtx'                        : False,
-                   }
-        for option in defaults:
-            options.setdefault(option, defaults[option])
-    options['name'] = name
-    from JetTagTools.JetTagToolsConf import Analysis__ExKtbbTag
-    return Analysis__ExKtbbTag(**options)
-
-def toolExKtbb_Hbb_MV2andToposTag(name, useBTagFlagsDefaults = True, **options):
-    """Sets up a ExKtbbTag tool and returns it.
-
-    The following options have BTaggingFlags defaults:
-
-    see below
-
-    input:             name: The name of the tool (should be unique).
-      useBTagFlagsDefaults : Whether to use BTaggingFlags defaults for options that are not specified.
-                  **options: Python dictionary with options for the tool.
-    output: The actual tool, which can then by added to ToolSvc via ToolSvc += output."""
-    if useBTagFlagsDefaults:
-        defaults = { 'OutputLevel'                      : BTaggingFlags.OutputLevel,
-                     'Runmodus'                         : BTaggingFlags.Runmodus,
-                     'tagMode'                          : 'Hbb',
-                     'BDTMode'                          : 'MV2andTopos',
-                     'taggerNameBase'                   : 'ExKtbb',
-                     'ForceCalibrationChannel'          : 'Default',
-                     'debug'                            : False,
-
-                     'SubJetLabel'                      : 'ExKt2SubJets',
-                     'JFOnlyVtx'                        : False,
-                   }
-        for option in defaults:
-            options.setdefault(option, defaults[option])
-    options['name'] = name
-    from JetTagTools.JetTagToolsConf import Analysis__ExKtbbTag
-    return Analysis__ExKtbbTag(**options)
-
diff --git a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_IP3DTrigTag.py b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_IP3DTrigTag.py
index e0b1afbe5803aaecdae00540768215fd43becdd9..b8131a3a656e976d83e400b87852dd533057f68b 100644
--- a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_IP3DTrigTag.py
+++ b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_IP3DTrigTag.py
@@ -77,7 +77,6 @@ def toolIP3DTag_Trig(name, useBTagFlagsDefaults = True, **options):
         trackGradeFactory= toolIP3DDetailedTrackGradeFactory('IP3DDetailedTrackGradeFactory')
         trackSelectorTool = toolIP3DTrackSelector('IP3DTrackSelector')
         inDetTrackSelectionTool = toolInDetTrackSelector('InDetTrackSelector')
-        trackVertexAssociationTool = toolSpecialTrackAssociator('SpecialTrackAssociator')
         likelihood = toolIP3DNewLikelihoodTool('IP3DNewLikelihoodTool')
         defaults = { 'OutputLevel'                      : BTaggingFlags.OutputLevel,
                      'Runmodus'                         : BTaggingFlags.Runmodus,
@@ -103,7 +102,6 @@ def toolIP3DTag_Trig(name, useBTagFlagsDefaults = True, **options):
                      'SVForIPTool'                      : svForIPTool,
                      'trackGradeFactory'                : trackGradeFactory,
                      'TrackToVertexIPEstimator'         : trackToVertexIPEstimator,
-                     'TrackVertexAssociationTool'       : trackVertexAssociationTool,
                      }
         for option in defaults:
             options.setdefault(option, defaults[option])
diff --git a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_LoadTools.py b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_LoadTools.py
index 42e036c80fa9622e55a2b4694644d5597db7e5b4..fe39ce6866b47a5003a47406844624c5df2caea0 100644
--- a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_LoadTools.py
+++ b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_LoadTools.py
@@ -195,7 +195,7 @@ def SetupConditionAlgorithm(ConfInstance=None):
       if globalflags.DataSource()=='data':
           readkeycalibpath = readkeycalibpath.replace("/GLOBAL/BTagCalib","/GLOBAL/Onl/BTagCalib")
           connSchema = "GLOBAL"
-      Taggers = ['IP2D','IP3D','SV1','SoftMu','JetFitterNN','MV2c10','MV2c10mu','MV2c10rnn','MV2c100','MV2cl100','RNNIP','DL1','DL1mu','DL1rnn']
+      Taggers = ['IP2D','IP3D','SV1','SoftMu','JetFitterNN','MV2c10']
       #JetVertexCharge disable ATLASRECTS-4506
       histoskey = "JetTagCalibHistosKey"
       conddb.addFolder(connSchema, readkeycalibpath, className='CondAttrListCollection')
@@ -368,10 +368,6 @@ def SetupJetCollectionDefault(JetCollection, TaggerList, ConfInstance = None):
 #            addTool('IP2DSpcNegTag', ToolSvc, 'BTagTrackToJetAssociator', JetCollection, Verbose = BTaggingFlags.OutputLevel < 3)
   if 'IP3D' in TaggerList:
     ConfInstance.addTool('IP3DTag', ToolSvc, 'BTagTrackToJetAssociator', JetCollection, Verbose = BTaggingFlags.OutputLevel < 3)
-  if 'RNNIP' in TaggerList:
-    ConfInstance.addTool('RNNIPTag', ToolSvc, 'BTagTrackToJetAssociator', JetCollection, Verbose = BTaggingFlags.OutputLevel)
-  if 'RNNIPNeg' in TaggerList:
-    ConfInstance.addTool('RNNIPNegTag', ToolSvc, 'BTagTrackToJetAssociator', JetCollection, Verbose = BTaggingFlags.OutputLevel)
 
 #          if BTaggingFlags.IP3DFlip:
 #            addTool('IP3DFlipTag', ToolSvc, 'BTagTrackToJetAssociator', JetCollection, Verbose = BTaggingFlags.OutputLevel < 3)
diff --git a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_MV2mFlipTag.py b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_MV2mFlipTag.py
deleted file mode 100644
index 3e9eb3be45bc7c4822341db9caf20de05172764d..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_MV2mFlipTag.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
-# Configuration functions for MV2mFlipTag
-# Author: Wouter van den Wollenberg (2013-2014)
-from BTagging.BTaggingFlags import BTaggingFlags
-
-metaMV2mFlipTag = { 'IsATagger'          : False,#True,
-                  'xAODBaseName'       : 'MV2mFlip',
-                  'DependsOn'          : ['AtlasExtrapolator',
-                                          'BTagCalibrationBrokerTool',
-                                          'BTagTrackToVertexTool'],
-                  'CalibrationTaggers' : ['MV2m',],
-                  'PassByPointer'      : {'calibrationTool' : 'BTagCalibrationBrokerTool'},
-                  'ToolCollection'     : 'MV2mFlipTag'}
-
-def toolMV2mFlipTag(name, useBTagFlagsDefaults = True, **options):
-    """Sets up a MV2mTag tool and returns it.
-
-    The following options have BTaggingFlags defaults:
-
-    OutputLevel                         default: BTaggingFlags.OutputLevel
-    Runmodus                            default: BTaggingFlags.Runmodus
-    taggerName                          default: "MV2mFlip"
-    taggerNameBase                      default: "MV2m"
-    forceMV2CalibrationAlias            default: BTaggingFlags.ForceMV2CalibrationAlias
-    MV2CalibAlias                       default: BTaggingFlags.MV2CalibAlias
-
-    input:             name: The name of the tool (should be unique).
-      useBTagFlagsDefaults : Whether to use BTaggingFlags defaults for options that are not specified.
-                  **options: Python dictionary with options for the tool.
-    output: The actual tool, which can then by added to ToolSvc via ToolSvc += output."""
-    from BTagging.MV2defaultValues import default_values
-    from BTagging.MV2defaultValues import MVTM_varNames
-
-    if useBTagFlagsDefaults:
-        defaults = { 'OutputLevel'                      : BTaggingFlags.OutputLevel,
-                     'Runmodus'                         : BTaggingFlags.Runmodus,
-                     'taggerName'                       : 'MV2mFlip',
-                     'taggerNameBase'                   : 'MV2m',
-                     'forceMV2CalibrationAlias'         : BTaggingFlags.ForceMV2CalibrationAlias,
-                     'MV2CalibAlias'                    : BTaggingFlags.MV2CalibAlias,
-                     'defaultvals'                      : default_values,
-                     'MVTMvariableNames'                : MVTM_varNames,
-                     }
-        for option in defaults:
-            options.setdefault(option, defaults[option])
-    options['name'] = name
-    from JetTagTools.JetTagToolsConf import Analysis__MV2Tag
-    return Analysis__MV2Tag(**options)
diff --git a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_MV2mTag.py b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_MV2mTag.py
deleted file mode 100644
index 0faf182adc80e91930755f0892bba7fda64b3259..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_MV2mTag.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
-# Configuration functions for MV2mTag
-# Author: Wouter van den Wollenberg (2013-2014)
-from BTagging.BTaggingFlags import BTaggingFlags
-
-metaMV2mTag = { 'IsATagger'          : False,#True,
-                  'xAODBaseName'       : 'MV2m',
-                  'DependsOn'          : ['AtlasExtrapolator',
-                                          'BTagCalibrationBrokerTool',
-                                          'BTagTrackToVertexTool'],
-                  'CalibrationTaggers' : ['MV2m',],
-                  'PassByPointer'      : {'calibrationTool' : 'BTagCalibrationBrokerTool'},
-                  'ToolCollection'     : 'MV2mTag'}
-
-def toolMV2mTag(name, useBTagFlagsDefaults = True, **options):
-    """Sets up a MV2mTag tool and returns it.
-
-    The following options have BTaggingFlags defaults:
-
-    OutputLevel                         default: BTaggingFlags.OutputLevel
-    Runmodus                            default: BTaggingFlags.Runmodus
-    taggerName                          default: "MV2m"
-    taggerNameBase                      default: "MV2m"
-    forceMV2CalibrationAlias            default: BTaggingFlags.ForceMV2CalibrationAlias
-    MV2CalibAlias                       default: BTaggingFlags.MV2CalibAlias
-
-    input:             name: The name of the tool (should be unique).
-      useBTagFlagsDefaults : Whether to use BTaggingFlags defaults for options that are not specified.
-                  **options: Python dictionary with options for the tool.
-    output: The actual tool, which can then by added to ToolSvc via ToolSvc += output."""
-    from BTagging.MV2defaultValues import default_values
-    from BTagging.MV2defaultValues import MVTM_varNames
-
-    if useBTagFlagsDefaults:
-        defaults = { 'OutputLevel'                      : BTaggingFlags.OutputLevel,
-                     'Runmodus'                         : BTaggingFlags.Runmodus,
-                     'taggerName'                       : 'MV2m',
-                     'taggerNameBase'                   : 'MV2m',
-                     'forceMV2CalibrationAlias'         : BTaggingFlags.ForceMV2CalibrationAlias,
-                     'MV2CalibAlias'                    : BTaggingFlags.MV2CalibAlias,
-                     'defaultvals'                      : default_values,
-                     'MVTMvariableNames'                : MVTM_varNames,
-                     }
-        for option in defaults:
-            options.setdefault(option, defaults[option])
-    options['name'] = name
-    from JetTagTools.JetTagToolsConf import Analysis__MV2Tag
-    return Analysis__MV2Tag(**options)
diff --git a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_RNNIPTag.py b/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_RNNIPTag.py
deleted file mode 100644
index f7a4353f3775e6abd4c9a9ed30891e4414fb4509..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagAlgs/BTagging/python/BTaggingConfiguration_RNNIPTag.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-
-# Configuration for RNNIP
-#
-# Note that a lot of tools and settings are borrowed from IP3D, so
-# this probably won't work without IP3D also turned on.  We'll need an
-# expter to figure out how to make taggers independant.
-from BTagging.BTaggingFlags import BTaggingFlags
-
-def buildRNNIP(basename, is_flipped=False, calibration=None):
-    cal_dir = calibration or basename
-    meta = {'IsATagger'         : True,
-            'xAODBaseName'      : basename,
-            'CalibrationTaggers' : [cal_dir],
-            'DependsOn'         : [#'AtlasExtrapolator',
-                                   #'BTagTrackToVertexTool',
-                                   #'InDetVKalVxInJetTool',
-                                   #'BTagTrackToVertexIPEstimator',
-                                   #'IP3DTrackSelector',
-                                   #'InDetTrackSelector',
-                                   #'SpecialTrackAssociator',
-                                   #'SVForIPTool_IP3D',
-                                   #'IP3DBasicTrackGradeFactory',
-                                   #'IP3DDetailedTrackGradeFactory'],
-                                   ],
-            'PassByPointer'     : {
-                #'SVForIPTool'                : 'SVForIPTool_IP3D',
-                #'trackSelectorTool'          : 'IP3DTrackSelector',
-                #'trackGradeFactory'          : 'IP3DDetailedTrackGradeFactory'},
-                #'TrackToVertexIPEstimator'   : 'BTagTrackToVertexIPEstimator'},
-                                 },
-            'PassTracksAs'      : 'trackAssociationName',
-            'ToolCollection'    : 'IP3DTag' }
-
-    def tool(name, useBTagFlagsDefaults = True, **options):
-        """Sets up a IP3DTag tool and returns it.
-
-        The following options have BTaggingFlags defaults:
-
-        """
-        if useBTagFlagsDefaults:
-            grades= [ "0HitIn0HitNInExp2","0HitIn0HitNInExpIn","0HitIn0HitNInExpNIn","0HitIn0HitNIn",
-                      "0HitInExp", "0HitIn",
-                      "0HitNInExp", "0HitNIn",
-                      "InANDNInShared", "PixShared", "SctShared",
-                      "InANDNInSplit", "PixSplit",
-                      "Good"]
-
-            from BTagging.BTaggingConfiguration_CommonTools import toolBTagTrackToVertexIPEstimator as toolBTagTrackToVertexIPEstimator
-            trackToVertexIPEstimator = toolBTagTrackToVertexIPEstimator('TrkToVxIPEstimator')
-            from BTagging.BTaggingConfiguration_IP3DTag import toolSVForIPTool_IP3D as toolSVForIPTool_IP3D
-            svForIPTool = toolSVForIPTool_IP3D('SVForIPTool')
-            from BTagging.BTaggingConfiguration_IP3DTag import toolIP3DDetailedTrackGradeFactory as toolIP3DDetailedTrackGradeFactory
-            trackGradeFactory = toolIP3DDetailedTrackGradeFactory('RNNIPDetailedTrackGradeFactory')
-            from BTagging.BTaggingConfiguration_IP3DTag import toolIP3DTrackSelector as toolIP3DTrackSelector
-            trackSelectorTool = toolIP3DTrackSelector('IP3DTrackSelector')
-            defaults = {
-                'OutputLevel'               : BTaggingFlags.OutputLevel,
-                'trackGradePartitions'      : grades ,
-                'RejectBadTracks'           : True,
-                'originalTPCollectionName'  : BTaggingFlags.TrackParticleCollectionName,
-                'NetworkConfig'             : BTaggingFlags.RNNIPConfig,
-                'unbiasIPEstimation'        : False,
-                #'trackAssociation'          : "Tracks" }
-                'SecVxFinderName'           : 'SV1',
-                'calibration_directory'     : cal_dir,
-                'writeInputsToBtagObject'   : BTaggingFlags.WriteRNNInputs,
-                'trackSelectorTool'         : trackSelectorTool,
-                'SVForIPTool'               : svForIPTool,
-                'trackGradeFactory'         : trackGradeFactory,
-                'TrackToVertexIPEstimator'  : trackToVertexIPEstimator,
-            }
-            if is_flipped:
-                defaults.update({
-                    'flipIPSign' : True,
-                    'usePosIP'   : True,
-                    'useNegIP'   : False,
-                })
-            for option in defaults:
-                options.setdefault(option, defaults[option])
-        options['name'] = name
-        from JetTagTools.JetTagToolsConf import Analysis__RNNIPTag
-        return Analysis__RNNIPTag(**options)
-
-    return tool, meta
-
-
-toolRNNIPTag, metaRNNIPTag = buildRNNIP('RNNIP')
-toolRNNIPNegTag, metaRNNIPNegTag = buildRNNIP(
-    'RNNIPNegTag', is_flipped=True, calibration='RNNIP')
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/CMakeLists.txt b/PhysicsAnalysis/JetTagging/JetTagTools/CMakeLists.txt
index d51a90313acf8d447eb6d2d58526b0e1dd22f18a..2d29de37c055219c33831612971471dc96992967 100644
--- a/PhysicsAnalysis/JetTagging/JetTagTools/CMakeLists.txt
+++ b/PhysicsAnalysis/JetTagging/JetTagTools/CMakeLists.txt
@@ -57,7 +57,6 @@ find_package( Boost COMPONENTS filesystem thread system )
 find_package( CLHEP )
 #find_package( Eigen )
 find_package( lwtnn )
-find_package( FastJet )
 find_package( ROOT COMPONENTS TMVA Core Tree MathCore Hist RIO pthread
     MathMore Minuit Minuit2 Matrix Physics HistPainter Rint RooFitCore RooFit )
 
@@ -81,12 +80,12 @@ atlas_add_library( JetTagToolsLib
     src/MV1Tag.cxx src/MV2Tag.cxx
     src/JetFitterVariablesFactory.cxx src/MSVVariablesFactory.cxx
     src/MultiSVTag.cxx src/SoftMuonTag.cxx
-    src/ExKtbbTagTool.cxx src/MultivariateTagManager.cxx
+    src/MultivariateTagManager.cxx
     src/DL1Tag.cxx src/TagNtupleDumper.cxx src/RNNIPTag.cxx
 
     PUBLIC_HEADERS JetTagTools
     INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${LWTNN_INCLUDE_DIRS}
-    PRIVATE_INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${FASTJET_INCLUDE_DIRS}
+    PRIVATE_INCLUDE_DIRS ${Boost_INCLUDE_DIRS}
     DEFINITIONS ${CLHEP_DEFINITIONS}
 
     LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} ${LWTNN_LIBRARIES}
@@ -97,7 +96,7 @@ atlas_add_library( JetTagToolsLib
     MuonSelectorToolsLib MuonMomentumCorrectionsLib TrkNeuralNetworkUtilsLib
     InDetSVWithMuonToolLib ITrackToVertex
 
-    PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES} ${FASTJET_LIBRARIES} AthenaKernel
+    PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES} AthenaKernel
     Navigation xAODMuon JetEDM Particle ITrackToVertex TrkEventPrimitives
     TrkLinks TrkTrack TrkTrackSummary VxJetVertex VxVertex VxSecVertex
     TrkVertexFitterInterfaces InDetTrackSelectionToolLib
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/BTagVariables.h b/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/BTagVariables.h
index de9ef3046dceb968e65a9f68daacd96b1a2c97a4..959e4638c5bfa358e46448b54ce599582293f634 100644
--- a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/BTagVariables.h
+++ b/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/BTagVariables.h
@@ -69,19 +69,6 @@ namespace btagvar {
   static const char* JF_DETA   = "jf_deta";
   static const char* JF_SIG3D  = "jf_sig3d";
 
-  static const char* JF_NTRK_VTX1         = "nTrk_vtx1";//"jf_ntrk_vtx1";
-  static const char* JF_MASS_VTX1         = "mass_first_vtx";//"jf_m_vtx1";
-  static const char* JF_E_VTX1            = "e_first_vtx";//"jf_e_vtx1";
-  static const char* JF_E_FRAC_VTX1       = "e_frac_vtx1";//"jf_efc_vtx1";
-  static const char* JF_L3D_VTX1          = "closestVtx_L3D";//"jf_L3d_vtx1";
-  static const char* JF_Lxy_VTX1          = "JF_Lxy1";//"jf_Lxy_vtx1";
-  static const char* JF_RAPIDITY_VTX1_MAX = "vtx1_MaxTrkRapidity_jf_path";//"jf_trky_max_vtx1";
-  static const char* JF_RAPIDITY_VTX1_AVG = "vtx1_AvgTrkRapidity_jf_path";//"jf_trky_avg_vtx1";
-  static const char* JF_RAPIDITY_VTX1_MIN = "vtx1_MinTrkRapidity_jf_path";//"jf_trky_min_vtx1";
-  static const char* JF_RAPIDITY_MAX      = "MaxTrkRapidity_jf_path";//"jf_trky_max";
-  static const char* JF_RAPIDITY_MIN      = "MinTrkRapidity_jf_path";//"jf_trky_min";
-  static const char* JF_RAPIDITY_AVG      = "AvgTrkRapidity_jf_path";//"jf_trky_avg";
-
   static const char* TRKSUM_NTRK   = "trkSum_ntrk";
   static const char* TRKSUM_SPT    = "trkSum_sPt";
   static const char* TRKSUM_VPT    = "trkSum_vPt";
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/DL1Tag.h b/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/DL1Tag.h
deleted file mode 100644
index 7ff88f2a49ddc0bce498ab2650800fb86b697826..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/DL1Tag.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef BTAGTOOLS_DL1TAG_C
-#define BTAGTOOLS_DL1TAG_C
-
-/******************************************************
-    @class DL1Tag
-    Package : JetTagTools
-    Created : September 2015
-    DESCRIPTION:
-    This class computes the Neural Network probability for being b-jet,
-    c-jet or uds-jet for a single event.
-    @authors Dan Guest, Luke de Oliveira, Marie Lanfermann
-********************************************************/
-#include "AthenaBaseComps/AthAlgTool.h"
-#include "JetTagTools/IMultivariateJetTagger.h"
-#include "JetTagCalibration/JetTagCalibCondData.h"
-
-#include <vector>
-#include <istream>
-#include <atomic>
-
-namespace xAOD {
-  class Vertex_v1;
-  typedef Vertex_v1 Vertex;
-}
-
-namespace lwt {
-  class LightweightNeuralNetwork;
-}
-
-namespace Analysis {
-
-  class DL1Tag : public extends<AthAlgTool, IMultivariateJetTagger>
-  {
-  public:
-    DL1Tag(const std::string& name,
-	   const std::string& n,
-	   const IInterface*);
-
-    virtual ~DL1Tag();
-    virtual StatusCode initialize() override;
-    virtual StatusCode finalize() override;
-
-    virtual
-    void assignProbability(xAOD::BTagging* BTag,
-                           const std::map<std::string,double>& inputs,
-                           const std::string& jetauthor) const override;
-
-  private:
-    typedef std::map<std::string, double> var_map;
-
-    /** Key of calibration data: */
-    SG::ReadCondHandleKey<JetTagCalibCondData> m_readKey{this, "HistosKey", "JetTagCalibHistosKey", "Key of input (derived) JetTag calibration data"};
-    std::unique_ptr<const lwt::LightweightNeuralNetwork>
-    load_calibration(const std::string& jetauthor,
-                     std::vector<lwt::Input>& variables,
-                     var_map& defaults) const;
-
-    std::unique_ptr<const lwt::LightweightNeuralNetwork>
-    build_nn(std::istream& nn_config_istream,
-             std::vector<lwt::Input>& variables,
-             var_map& defaults) const;
-    void fill_outputs(xAOD::BTagging* BTag, var_map outputs) const;
-
-    std::string m_calibrationDirectory;
-    std::string m_calibrationSubDirectory;
-    std::string m_xAODBaseName;
-    bool m_forceDL1CalibrationAlias;
-    std::string m_DL1CalibAlias;
-
-    std::unique_ptr<const lwt::LightweightNeuralNetwork> m_localNN;
-    var_map m_local_defaults;
-    std::vector<lwt::Input> m_local_variables;
-
-    //error checking
-    mutable std::atomic<int> m_n_compute_errors;
-
-    std::string m_LocalNNConfigFile;
-
-    /** This switch is needed to indicate what to do. The algorithm can be run to produce
-	reference histograms from the given MC files (m_runModus=0) or to work in analysis mode
-	(m_runModus=1) where already made reference histograms are read.*/
-    std::string    m_runModus;          //!< 0=Do not read histos, 1=Read referece histos (analysis mode)
-  }; // end class
-
-}// end Analysis namespace
-
-#endif
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/ExKtbbTag.h b/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/ExKtbbTag.h
deleted file mode 100644
index 5be2fea17730cdd30214484497e554c7c4601d14..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/ExKtbbTag.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef JETTAGTOOLS_EXKTBBTAG_H
-#define JETTAGTOOLS_EXKTBBTAG_H
-
-/******************************************************
-    @class ExKtbbTag
-    Identification of double b-hadron jets
-    @ author Qi Zeng
-********************************************************/
-
-#include "AthenaBaseComps/AthAlgTool.h"
-#include "GaudiKernel/ToolHandle.h"
-#include "JetTagTools/ITagTool.h"
-
-// std
-#include <string>
-
-// xAOD EDM
-#include "xAODTracking/VertexContainer.h"
-#include "xAODJet/JetContainer.h"
-#include "xAODBTagging/BTaggingContainer.h"
-#include "xAODBTagging/BTagVertexContainer.h"
-
-// ROOT
-#include "TLorentzVector.h"
-
-// TMVA
-#include "TMVA/IMethod.h"
-#include "TMVA/MethodBase.h"
-namespace TMVA { class Reader; }
-
-// CalibrationBroker
-namespace Analysis { class CalibrationBroker; }
-
-typedef Eigen::Matrix<double, 3, 3, 0, 3, 3> AmgSymMatrix3D;
-
-namespace Analysis { 
-
-  class ExKtbbTag : public AthAlgTool , virtual public ITagTool {
-   
-  public:
-    ExKtbbTag(const std::string&,const std::string&,const IInterface*);
-      
-    /**
-       Implementations of the methods defined in the abstract base class
-    */
-    virtual ~ExKtbbTag();
-    StatusCode initialize();
-    StatusCode finalize();
-      
-    /** Set the primary vertex. TODO: This is temporary ! The primary vertex should
-  	be part of the JetTag IParticle interface implementation. The trouble with 
-  	ElementLink and persistency has to be solved for that. Revisit ... */
-    void setOrigin(const xAOD::Vertex* priVtx);
-      
-    StatusCode tagJet(xAOD::Jet& jetToTag, xAOD::BTagging* BTag, const std::string &jetName);
-
-    void finalizeHistos() {};
-
-  private:      
-
-    // global variables //
-
-    std::string m_runModus;            // "reference" means to produce variables for performance study; "analysis" means output weight with given reference histogram
-    std::string m_tagMode;             // "Hbb", or "gbb"
-    std::string m_BDTMode;             // "MV2Only", "MV2andJFDRSig", or "MV2andTopos"
-    std::string m_taggerNameBase;      // prefix in BTaggingContainer -- mostly used in code
-    std::string m_xAODBaseName;        // something required by base class
-    std::string m_ForceCalibChannel;   // force to use this jet channel in calibration broker. Empty means default jet author. "Default" means "AntiKt10LCTopoTrimmedPtFrac5SmallR20" in "Hbb" tagMode and "AntiKt4LCTopo" in "gbb" tagMode
-    bool        m_debug;
-
-    // variables for tagger //
-
-    std::string m_SubJetLabel;         // label to access subjet information
-    bool        m_JFOnlyVtx;           // whether we insist JF should have at least one vtx with at least 2 tracks
-      
-    /** Storage for the primary vertex. Can be removed when JetTag provides origin(). */
-    // this pointer does not need to be deleted in the destructor (because it
-    // points to something in storegate)
-    const xAOD::Vertex* m_priVtx = 0;
-
-    ///////////////////////////////////////////////
-    // Functions related to variable calculation //
-    ///////////////////////////////////////////////
-
-    // high-level functionality //
-
-    bool CalculateInputVariables(xAOD::Jet& jetToTag, xAOD::BTagging* BTag);
-
-    bool JetTagAnalysisMode(xAOD::Jet& jetToTag, xAOD::BTagging* BTag);
-    bool JetTagReferenceMode(xAOD::Jet& jetToTag, xAOD::BTagging* BTag);
-
-    // medium-level functionality//
-
-    double GetDoubleMV2c20(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2);
-    double GetSingleMV2c20(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2);
-
-    int GetSV1NtrksDiff(const xAOD::BTagging* bjet, const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool doValidDualSV1);
-    int GetJFNtrksDiff(const xAOD::BTagging* bjet, const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool doValidDualJF, bool onlyVtx);
-
-    double GetSV1CombMass(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool doValidDualSV1);
-    double GetJFCombMass(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool doValidDualJF, bool onlyVtx, bool doNeutralCorrection);
-
-    double GetSV1DRSignificance(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, double& DR, double& DR_error);
-    double GetJFDRSignificance(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool onlyVtx, double& DR, double& DR_error);
-
-    double GetSV1DR3DSignificance(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, double& dR3D, double& dR3D_error);
-
-    double GetSV1DLSignificance(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, double& dL, double& dL_error);
-    double GetJFDLSignificance(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool onlyVtx, double& dL, double& dL_error);
-
-    // low-level functionality //
-
-    static bool SortPt(const xAOD::Jet* j1, const xAOD::Jet* j2) {return j1->pt() > j2->pt();}
-
-    std::vector<const xAOD::Vertex*> GetSV1vertices(const xAOD::BTagging* bjet);
-    bool IsValidSV1(std::vector<const xAOD::Vertex*> input);
-    bool SV1DualValid(std::vector<const xAOD::Vertex*> vtx1, std::vector<const xAOD::Vertex*> vtx2);
-
-    std::vector<const xAOD::BTagVertex*> GetJFVertices(const xAOD::BTagging* bjet);
-    std::vector<float> GetJFfittedPosition(const xAOD::BTagging* bjet, std::vector<float>& JFfittedCov);
-    bool IsValidJF(const xAOD::BTagging* bjet, bool onlyVtx);
-    bool JFDualValid(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool onlyVtx);
-    int JFntrk(const xAOD::BTagging* bjet, bool onlyVtx);
-    TLorentzVector JFMomentum(const xAOD::BTagging* bjet, bool onlyVtx, bool doNeutralCorrection);
-    double JFEffectiveDecayLength(const xAOD::BTagging* bjet, bool onlyVtx, double& error);
-
-    double LimitUpperBound(double input, double start, double limit){
-      if(input > start) return start + (limit-start)/TMath::Pi()*2.*TMath::ATan(TMath::Pi()/2./(limit-start)*(input-start));
-      else              return input;
-    }
-
-    std::vector<Amg::Vector3D> GetVtxEigenVariation(Amg::Vector3D vtxPosition, AmgSymMatrix3D vtxCovMatrix);
-    double GeneralDRSignificance3D(Amg::Vector3D vtx1, AmgSymMatrix3D vtx1_CovMatrix, Amg::Vector3D vtx2, AmgSymMatrix3D vtx2_CovMatrix, double& dR3D, double& dR3D_error);
-
-    ////////////////////////////////////
-    // Functions related to final BDT //
-    ////////////////////////////////////
-
-    std::string m_taggerName;          // actual taggerName
-
-    ToolHandle<CalibrationBroker> m_calibrationTool;
-
-    std::map<std::string, TMVA::Reader*>     m_tmvaReaders;       // key should be alias + m_taggerCalibName
-    std::map<std::string, TMVA::MethodBase*> m_tmvaMethod;        // key should be alias + m_taggerCalibName
-    std::vector<std::string>                 m_undefinedReaders;
-
-    std::string GetPtBin(const xAOD::Jet* jetToTag);
-    
-    std::map<std::string, float*>    m_tmvaVariables;             // key should be the same as those used in BDT 
-    bool                             InitTMVAVariables(std::string BDTMode);
-    bool                             FillTMVAVariables(std::string BDTMode, const xAOD::Jet* jetToTag, const xAOD::BTagging* BTag);
-    bool                             BundleTMVAVariables(std::string BDTMode, TMVA::Reader* tmvaReader);
-
-    std::vector<double>  m_ptbinlist;
-
-
-  }; // End class
-
-  inline void ExKtbbTag::setOrigin(const xAOD::Vertex* priVtx) { m_priVtx = priVtx; }
-
-} // End namespace 
-
-#endif
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/ExKtbbTagTool.h b/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/ExKtbbTagTool.h
deleted file mode 100644
index 13f639fb112d074efc7645d0b97d3e05d0ed5c21..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/ExKtbbTagTool.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef JETTAGTOOLS_EXKTBBTAGTOOL_H
-#define JETTAGTOOLS_EXKTBBTAGTOOL_H
-
-/*
-  Author  : Qi Zeng
-  Email   : qzeng@cern.ch
-  
-  This is a Tool based on JetModifierBase, to run exclusive kt algorithm on any existing jet collection
-  Many thanks to Giordon Stark and Miles Wu who actually implement the exclusive kt subjet finder in JetEtMiss pkg
-  and help me setup this in b-tagging pkg
-
-  This tool is supposed to be called by a stand-alone algorithm that will call in the jet collection from event store and 
-  load JetModifiers. It should be run before the b-tagging, but after jet finding
-
-  This is basically just an interface to call SubjetFinderTool. However, we need to overwrite some subjet collection information,
-  which might be important for b-tagging purpose
-*/
-
-#include "JetRec/JetModifierBase.h"
-#include "AsgTools/ToolHandle.h"
-#include "JetSubStructureMomentTools/SubjetRecorderTool.h"
-#include "JetSubStructureUtils/SubjetFinder.h"
-
-namespace Analysis{
-
-class ExKtbbTagTool : public JetModifierBase {
-  ASG_TOOL_CLASS(ExKtbbTagTool, IJetModifier)
-
-  public:
-    // Constructor from tool name.
-    ExKtbbTagTool(std::string myname);
-
-    virtual StatusCode initialize();
-
-    // Inherited method to modify a jet.
-    virtual int modifyJet(xAOD::Jet& jet) const;
-
-  private:
-    // subjet finding parameter
-    std::string m_JetAlgorithm;
-    float       m_JetRadius;
-    float       m_PtMin;
-    int         m_ExclusiveNJets;
-
-    // related to subjet recording
-    std::string m_InputJetContainerName;             // Mainly used to build correct link from subjet to parent jet
-    ToolHandle<ISubjetRecorderTool> m_SubjetRecorderTool;     
-
-
-    std::string m_SubjetLabel;                       // must be exactly the same label as the one used by SubjetRecorder inside SubjetFinder. 
-                                                     // At this moment, there is no way to figure out this name given SubjetFinderTool
-    std::string m_SubjetContainerName;               // must be exactly the same container name as the one used by SubjetRecorder inside SubjetFinder.
-                                                     // At this moment, there is no way to figure out this name given SubjetFinderTool
-    std::string m_SubjetAlgorithm_BTAG;
-    float       m_SubjetRadius_BTAG;
-
-    std::vector<fastjet::PseudoJet> constituentPseudoJets(xAOD::Jet& jet) const;
-};
-
-}
-
-#endif
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/IPTag.h b/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/IPTag.h
index 1bae284ddb9660df937ec4b571a6e278951c2f60..9a9b0ef2fa2da2d0f78598ad3952891eafac8563 100644
--- a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/IPTag.h
+++ b/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/IPTag.h
@@ -24,7 +24,6 @@ namespace Reco { class ITrackToVertex; }
 namespace Trk  { class ITrackToVertexIPEstimator; }
 // following two are temporary (to be moved to a separate Tool)
 namespace InDet { class IInDetTrackSelectionTool; }
-namespace CP { class ITrackVertexAssociationTool;}
 
 namespace Analysis { 
 
@@ -162,10 +161,6 @@ namespace Analysis {
     /** InDetTrackSelectorTool (temporary: to be moved to a separate Tool) */
     ToolHandle< InDet::IInDetTrackSelectionTool > m_InDetTrackSelectorTool;
 
-    /** TrackVertex associator (temporary: to be moved to a separate Tool) */
-    ToolHandle< CP::ITrackVertexAssociationTool > m_TightTrackVertexAssociationTool;
-      
-
     // VD: for debugging
     mutable std::atomic<int> m_nbjet;
     mutable std::atomic<int> m_ncjet;
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/MultivariateTagManager.h b/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/MultivariateTagManager.h
index dad842cb602620ede8b8e7e7255d3327b4a0785f..22bdbfc75b207f1847e2fa457f4e7c5d4b679474 100644
--- a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/MultivariateTagManager.h
+++ b/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/MultivariateTagManager.h
@@ -57,7 +57,6 @@ namespace Analysis {
     void fill_sv1(var_map& inputs, xAOD::BTagging& BTag) const;
     void fill_jetfitter(var_map& inputs, xAOD::BTagging& BTag) const;
     void fill_mvb(var_map& inputs, xAOD::Jet& jet, xAOD::BTagging& BTag) const;
-    void fill_mv2cl100(var_map& inputs, xAOD::BTagging& BTag) const;
     void fill_trkSum(var_map& inputs, xAOD::BTagging& BTag) const;
     void fill_softmuon(var_map& inputs, xAOD::BTagging& BTag) const;
 
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/RNNIPTag.h b/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/RNNIPTag.h
deleted file mode 100644
index bf571e5354f350325cbcd8774be426cc8e3c9273..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/RNNIPTag.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef JETTAGTOOLS_RNNIPTAG_H
-#define JETTAGTOOLS_RNNIPTAG_H
-
-/******************************************************
-    @class RNNIPTag
-    b-jet tagger based on 2D or 3D impact parameter
-    @author CPPM Marseille
-********************************************************/
-
-#include "AthenaBaseComps/AthAlgTool.h"
-#include "GaudiKernel/ToolHandle.h"
-#include "CxxUtils/checker_macros.h"
-#include "JetTagTools/ITagTool.h"
-#include "JetTagCalibration/JetTagCalibCondData.h"
-
-#include "xAODTracking/TrackParticleContainerFwd.h"
-
-#include <vector>
-#include <functional>
-#include <memory>
-#include <sstream>
-#include <mutex>
-
-namespace Reco { class ITrackToVertex; }
-namespace Trk  { class ITrackToVertexIPEstimator; }
-// following two are temporary (to be moved to a separate Tool)
-namespace InDet { class IInDetTrackSelectionTool; }
-namespace CP { class ITrackVertexAssociationTool;}
-
-namespace lwt {
-  class LightweightRNN;
-  struct JSONConfig;
-  typedef std::map<std::string, double> ValueMap;
-}
-
-namespace Analysis {
-
-
-  class IPInfo;
-  class TrackSelector;
-  class TrackGrade;
-  class GradedTrack;
-  class TrackGradePartition;
-  class SVForIPTool;
-  class ITrackGradeFactory;
-
-  // track struct, and sorting functions
-  struct IPxDInfo;
-  typedef std::function<bool(const IPxDInfo&, const IPxDInfo&)> TrackSorter;
-
-  class RNNIPTag : public extends<AthAlgTool, ITagTool>
-  {
-  public:
-    RNNIPTag(const std::string&,const std::string&,const IInterface*);
-
-    /**
-       Implementations of the methods defined in the abstract base class
-    */
-    virtual ~RNNIPTag();
-    virtual StatusCode initialize() override;
-    virtual StatusCode finalize() override;
-
-    virtual StatusCode tagJet(const xAOD::Vertex& priVtx,
-                              const xAOD::Jet& jetToTag,
-                              xAOD::BTagging& BTag,
-                              const std::string &jetName) const override;
-
-    virtual void finalizeHistos() override {}
-
-  private:
-
-    std::vector<IPxDInfo> get_track_info(
-      const xAOD::Vertex& priVtx,
-      const std::vector<GradedTrack>&,
-      const Amg::Vector3D& unit,
-      const std::vector<const xAOD::TrackParticle*>& v0_tracks) const;
-
-    void add_tags(xAOD::BTagging& tag, const std::string& author,
-                  std::vector<IPxDInfo>& tracks) const;
-
-    /** base name string for persistification in xaod */
-    std::string m_xAODBaseName;
-
-    /// VD: bool switches
-    bool m_flipIP;              // reverse impact parameter signs for
-                                // negative tag calibration method
-    bool m_flipZIP;             // reverse Z impact parameter signs
-                                // for negative tag calibration method
-    bool m_usePosIP;            // use tracks with positive impact
-                                // parameter for tagging
-    bool m_useNegIP;            // use tracks with negative impact
-                                // parameter for tagging
-    bool m_useZIPSignForPosNeg; // use Z impact parameter sign as well
-                                // to select Pos and Neg tracks
-    bool m_use2DSignForIP3D;    // force to use 2D IP sign even for IP3D IP
-    bool m_useD0SignForZ0;      // force to use transverse IP sign for
-                                // Z impact parameter for IP3D
-    bool m_rejectBadTracks;     // TODO: Do we need this?
-    // bool m_SignWithSvx;
-    bool m_unbiasIPEstimation;  // remove track from vertex when computing IP
-
-    // we can save the sorted inputs for each tagger for debugging and
-    // optimization
-    bool m_writeInputsToBtagObject;
-    bool m_writeTrackLinks;
-
-    //// VD: other (non-bool) configurables
-    /** Name of the track-to-jet association in the BTagging object */
-    std::string m_trackAssociationName;
-
-    /** Key of calibration data: */
-    SG::ReadCondHandleKey<JetTagCalibCondData> m_readKey{this, "HistosKey", "JetTagCalibHistosKey", "Key of input (derived) JetTag calibration data"};
-    /** forcing the calibration folder of a given collection */
-    std::string m_ForcedCalibName;
-
-    // Initalize with a config name and path to a network If the
-    // network path is empty we read from the calib db Note that this
-    // won't support reading different local files for different jet
-    // collections.
-    std::map<std::string, std::string > m_network_cfg;
-
-    // At runtime, we can run a list of networks for each track
-    // sorting. Networks include the configuration name, which is used
-    // for the DB lookup and to name the saved output.
-    //
-    // This structure also owns the network instance.
-    struct Network {
-      Network(const std::string& name, const lwt::JSONConfig&);
-      std::string name;
-      std::shared_ptr<lwt::LightweightRNN> network;
-      std::vector<std::string> outputs;
-    };
-    typedef std::vector<Network> Networks;
-
-    // Each network list is grouped with its sort function.
-    typedef std::vector<std::pair<TrackSorter, Networks> > SortGroups;
-    mutable std::map<std::string, SortGroups > m_networks ATLAS_THREAD_SAFE;
-    // Serialize access to m_networks.
-    mutable std::mutex m_networksMutex ATLAS_THREAD_SAFE;
-
-    // load the calibration file from the COOL db
-    const SortGroups& get_networks_for(const std::string& author) const;
-    //void register_hist(const std::string& name = "/rnnip");
-    std::string get_calib_string(
-      const std::string& author,
-      const std::string& name = "/rnnip") const;
-    std::string m_calibrationDirectory;
-
-    /** names of fools for getting the secondary vertex information */
-    std::string m_secVxFinderNameForV0Removal;
-    std::string m_secVxFinderNameForIPSign;
-    std::string m_secVxFinderName;
-
-    //// VD: auxiliary information to be stored
-    /** information to persistify: */
-    std::string m_originalTPCollectionName;
-    //const xAOD::TrackParticleContainer* m_originalTPCollection;
-    /** track classification. */
-    std::vector<std::string>          m_trackGradePartitionsDefinition;
-    std::vector<TrackGradePartition*> m_trackGradePartitions;
-
-    //// VD: list of tools below
-    /** Track selection cuts for IPTagging */
-    ToolHandle< TrackSelector >        m_trackSelectorTool;
-
-    /** Pointer to the SV tool */
-    ToolHandle< SVForIPTool >          m_SVForIPTool;
-
-    /** ToolHandle for the ITrackGradeFactory tool */
-    ToolHandle< ITrackGradeFactory > m_trackGradeFactory;
-
-    /** GP: Tool for the estimation of the IPs to the Vertex */
-    ToolHandle< Trk::ITrackToVertexIPEstimator > m_trackToVertexIPEstimator;
-
-    // VD: for debugging
-    //int m_nbjet;
-    //int m_ncjet;
-    //int m_nljet;
-
-  }; // End class
-
-} // End namespace
-
-#endif
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/SVTag.h b/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/SVTag.h
index 731c86cf9a06a64407919b7ed67cbc5167596425..86b20365b75ad975dfa88762df6db0168fa3bddd 100644
--- a/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/SVTag.h
+++ b/PhysicsAnalysis/JetTagging/JetTagTools/JetTagTools/SVTag.h
@@ -99,6 +99,7 @@ namespace Analysis
       // flag to turn ON/OFF the use of \DeltaR(jet,PV-SV) in the likelihood
       bool m_useDRJPVSV;    
       bool m_isFlipped; // true if tagger is configured in flipped mode. in that case adjusts DRJPVSV computation
+      bool m_save_probabilities;
 
     }; // End class
 
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/python/DL1TagConfig.py b/PhysicsAnalysis/JetTagging/JetTagTools/python/DL1TagConfig.py
deleted file mode 100644
index eb8b81c993d616ebe197c4c049a2a67129539cd0..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagTools/python/DL1TagConfig.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-
-from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
-from AthenaConfiguration.ComponentFactory import CompFactory
-
-# import the DL1Tag configurable
-Analysis__DL1Tag=CompFactory.Analysis.DL1Tag
-
-# define the class
-def DL1TagCfg(flags, name = 'DL1', scheme = '', useBTagFlagsDefaults = True, **options):
-    """Sets up a DL1Tag tool and returns it.
-
-    The following options have BTaggingFlags defaults:
-
-    Runmodus                            default: BTagging.RunModus
-    taggerName                          default: "DL1"
-    taggerNameBase                      default: "DL1"
-    forceDL1CalibrationAlias            default: BTaggingFlags.ForceDL1CalibrationAlias
-    DL1CalibAlias                       default: BTaggingFlags.DL1CalibAlias
-
-    input:             name: The name of the tool (should be unique).
-          useBTagFlagsDefaults : Whether to use BTaggingFlags defaults for options that are not specified.
-                  **options: Python dictionary with options for the tool.
-    output: The actual tool"""
-    acc = ComponentAccumulator()
-    options['name'] = name + 'Tag'
-    basename = name
-    DL1LocalNNConfig = ''
-    ForceDL1CalibrationAlias = True
-    DL1CalibAlias = 'AntiKt4EMTopo'
-    options['xAODBaseName'] = basename
-    options['LocalNNConfigurationFile'] = DL1LocalNNConfig
-    if scheme == 'Trig':
-        options['HistosKey'] = 'JetTagTrigCalibHistosKey'
- 
-    if useBTagFlagsDefaults:
-        defaults = { 'Runmodus'                         : flags.BTagging.RunModus,
-                     'forceDL1CalibrationAlias'         : ForceDL1CalibrationAlias,
-                     'DL1CalibAlias'                    : DL1CalibAlias,
-                     'calibration_directory'            : basename,
-                     }
-        for option in defaults:
-                options.setdefault(option, defaults[option])
-    acc.setPrivateTools(Analysis__DL1Tag(**options))
-
-    return acc
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/python/IP3DTagConfig.py b/PhysicsAnalysis/JetTagging/JetTagTools/python/IP3DTagConfig.py
index 52c8d9d768a0ca2a7c473ea462c2bfe359516e03..67e32dd93f4d6f2909f82a6bc56bfe2caa7ae3b7 100644
--- a/PhysicsAnalysis/JetTagging/JetTagTools/python/IP3DTagConfig.py
+++ b/PhysicsAnalysis/JetTagging/JetTagTools/python/IP3DTagConfig.py
@@ -8,7 +8,6 @@ from JetTagTools.IPDetailedTrackGradeFactoryConfig import IPDetailedTrackGradeFa
 from JetTagTools.IPTrackSelectorConfig import IPTrackSelectorCfg
 from JetTagTools.NewLikelihoodToolConfig import NewLikelihoodToolCfg
 from JetTagTools.InDetTrackSelectorConfig import InDetTrackSelectorCfg
-from JetTagTools.SpecialTrackAssociatorConfig import SpecialTrackAssociatorCfg
 
 # import the IPTag configurable
 Analysis__IPTag=CompFactory.Analysis.IPTag
@@ -44,7 +43,6 @@ def IP3DTagCfg( flags, name = 'IP3DTag', PrimaryVertexCollectionName="", scheme
         trackSelectorTool = acc.popToolsAndMerge(IPTrackSelectorCfg(flags, 'IP3DTrackSelector'))
         likelihood = acc.popToolsAndMerge(NewLikelihoodToolCfg(flags, 'IP3DNewLikelihoodTool', 'IP3D', scheme))
         inDetTrackSelectionTool = acc.popToolsAndMerge(InDetTrackSelectorCfg('InDetTrackSelector'))
-        trackVertexAssociationTool = acc.popToolsAndMerge(SpecialTrackAssociatorCfg('SpecialTrackAssociator', PrimaryVertexCollectionName))
 
         defaults = { 'Runmodus'                         : flags.BTagging.RunModus,
                      'referenceType'                    : flags.BTagging.ReferenceType,
@@ -65,7 +63,6 @@ def IP3DTagCfg( flags, name = 'IP3DTag', PrimaryVertexCollectionName="", scheme
                      'trackGradeFactory'                : trackGradeFactory,
                      'TrackToVertexIPEstimator'         : trackToVertexIPEstimator,
                      'InDetTrackSelectionTool'          : inDetTrackSelectionTool,
-                     'TrackVertexAssociationTool'       : trackVertexAssociationTool,
                      }
         for option in defaults:
             options.setdefault(option, defaults[option])
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/python/MultivariateTagManagerConfig.py b/PhysicsAnalysis/JetTagging/JetTagTools/python/MultivariateTagManagerConfig.py
index 312896d3ab795722a887f6a218199b0d052ed0a3..2a5c963d3a5279be4886c5d7da10593b9775bd5f 100644
--- a/PhysicsAnalysis/JetTagging/JetTagTools/python/MultivariateTagManagerConfig.py
+++ b/PhysicsAnalysis/JetTagging/JetTagTools/python/MultivariateTagManagerConfig.py
@@ -2,7 +2,6 @@
 
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
-from JetTagTools.DL1TagConfig import DL1TagCfg
 from JetTagTools.MV2TagConfig import MV2TagCfg
 
 # import the MultivariateTagManager configurable
@@ -26,23 +25,11 @@ def MultivariateTagManagerCfg(flags, name = 'MultivariateTagManager', TaggerList
     MultivariateTagManagerAuxBranches = []
     MultivariateTagManagerAuxBranches += ['SMT_discriminant'] #ATLASRECTS-5381
 
-    if 'DL1rnn' in TaggerList or 'MV2c10rnn' in TaggerList:
+    if 'MV2c10rnn' in TaggerList:
         #RNNIP output variables are needed
         rnnip_outputs = ['b','c','u','tau']
         MultivariateTagManagerAuxBranches += ['rnnip_p' + x for x in rnnip_outputs]
 
-    if 'DL1' in TaggerList:
-        dl1 = acc.popToolsAndMerge(DL1TagCfg(flags, 'DL1', scheme))
-        mvtagtoollist.append(dl1)
-
-    if 'DL1mu' in TaggerList:
-        dl1 = acc.popToolsAndMerge(DL1TagCfg(flags, 'DL1mu', scheme))
-        mvtagtoollist.append(dl1)
-
-    if 'DL1rnn' in TaggerList:
-        dl1 = acc.popToolsAndMerge(DL1TagCfg(flags, 'DL1rnn', scheme))
-        mvtagtoollist.append(dl1)
-
     if 'MV2c10' in TaggerList:
         mv2 = acc.popToolsAndMerge(MV2TagCfg(flags, 'MV2c10', scheme))
         mvtagtoollist.append(mv2)
@@ -55,15 +42,6 @@ def MultivariateTagManagerCfg(flags, name = 'MultivariateTagManager', TaggerList
         mv2 = acc.popToolsAndMerge(MV2TagCfg(flags, 'MV2c10rnn', scheme))
         mvtagtoollist.append(mv2)
 
-    if 'MV2c100' in TaggerList:
-        mv2 = acc.popToolsAndMerge(MV2TagCfg(flags, 'MV2c100', scheme))
-        mvtagtoollist.append(mv2)
-
-
-    if 'MV2cl100' in TaggerList:
-        mv2 = acc.popToolsAndMerge(MV2TagCfg(flags, 'MV2cl100', scheme))
-        mvtagtoollist.append(mv2)
-
     #Check if input has been scheduled
     #if IP2D not added ....
 
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/python/RNNIPTagConfig.py b/PhysicsAnalysis/JetTagging/JetTagTools/python/RNNIPTagConfig.py
deleted file mode 100644
index 94133fd92a528657f0cf4dadc0aa22405ffcbe35..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagTools/python/RNNIPTagConfig.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-
-from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
-from AthenaConfiguration.ComponentFactory import CompFactory
-from JetTagTools.BTagTrackToVertexIPEstimatorConfig import BTagTrackToVertexIPEstimatorCfg
-from JetTagTools.SVForIPToolConfig import SVForIPToolCfg
-from JetTagTools.IPDetailedTrackGradeFactoryConfig import IPDetailedTrackGradeFactoryCfg
-from JetTagTools.IPTrackSelectorConfig import IPTrackSelectorCfg
-
-# import the IPTag configurable
-Analysis__RNNIPTag=CompFactory.Analysis.RNNIPTag
-
-def RNNIPTagCfg( flags, name = 'RNNIP', scheme = '', calibration=None, useBTagFlagsDefaults = True, **options ):
-    """Sets up a RNNIPTag tool and returns it.
-
-    The following options have BTaggingFlags defaults:
-
-    trackGradePartitions                default: [ "Good", "BlaShared", "PixShared", "SctShared", "0HitBLayer" ]
-    RejectBadTracks                     default: False
-    SecVxFinderName                     default: "SV1"
-
-    input:             name: The name of the tool (should be unique).
-          useBTagFlagsDefaults : Whether to use BTaggingFlags defaults for options that are not specified.
-                  **options: Python dictionary with options for the tool.
-    output: The actual tool."""
-
-    acc = ComponentAccumulator()   
-    options['name'] = name
-    basename = 'RNNIP'
-    RNNIPConfig = {'rnnip':''}
-    WriteRNNInputs = False
-    options['xAODBaseName'] = basename
-    options['trackAssociationName'] = 'BTagTrackToJetAssociator'
-    if scheme == 'Trig':
-        options['HistosKey'] = 'JetTagTrigCalibHistosKey'
-    cal_dir = calibration or basename
-    is_flipped=False
-    if (scheme == "Flip"):
-        is_flipped=True
-
-    if useBTagFlagsDefaults:
-        trackToVertexIPEstimator = acc.popToolsAndMerge(BTagTrackToVertexIPEstimatorCfg(flags, 'TrkToVxIPEstimator'))
-        svForIPTool = acc.popToolsAndMerge(SVForIPToolCfg('SVForIPTool'))
-        trackGradeFactory = acc.popToolsAndMerge(IPDetailedTrackGradeFactoryCfg('RNNIPDetailedTrackGradeFactory'))
-        trackSelectorTool = acc.popToolsAndMerge(IPTrackSelectorCfg(flags, 'RNNIPTrackSelector'))
-
-        defaults = {
-                'trackGradePartitions'      : flags.BTagging.Grades,
-                'RejectBadTracks'           : True,
-                'NetworkConfig'             : RNNIPConfig,
-                'unbiasIPEstimation'        : False,
-                'SecVxFinderName'           : 'SV1',
-                'calibration_directory'     : cal_dir,
-                'writeInputsToBtagObject'   : WriteRNNInputs,
-                'trackSelectorTool'         : trackSelectorTool,
-                'SVForIPTool'               : svForIPTool,
-                'trackGradeFactory'         : trackGradeFactory,
-                'TrackToVertexIPEstimator'  : trackToVertexIPEstimator,
-            }
-        if is_flipped:
-            defaults.update({
-                    'flipIPSign' : True,
-                    'usePosIP'   : True,
-                    'useNegIP'   : False,
-                })
-
-        for option in defaults:
-            options.setdefault(option, defaults[option])
-
-    acc.setPrivateTools(Analysis__RNNIPTag( **options))
-
-    return acc
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/src/DL1Tag.cxx b/PhysicsAnalysis/JetTagging/JetTagTools/src/DL1Tag.cxx
deleted file mode 100644
index 908f1a7982bff94fb8c0ff8279fed4b4b3956566..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagTools/src/DL1Tag.cxx
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-*/
-
-//////////////////////////////////////////////////////////////////////////////
-/// Name    : DL1Tag
-/// Package : JetTagTools
-/// Author  : Marie Lanfermann (Universite de Geneve), Dan Guest (UC Irvine)
-/// Created : 2015
-///
-/// DESCRIPTION:
-///
-/// This class computes the Neural Network probability for being b-jet,
-/// c-jet or uds-jet for a single event. The NN is constructed outside Atheana
-/// using standard Data Science libraries, i.e. Keras (Theano or TensorFlow backend)
-/// for the actual training.
-///
-/////////////////////////////////////////////////////////////////////////////
-
-#include "GaudiKernel/IToolSvc.h"
-#include "xAODTracking/TrackParticle.h"
-
-#include "JetTagTools/DL1Tag.h"
-
-#include "xAODBTagging/BTagging.h"
-#include "xAODJet/Jet.h"
-
-#include "TObjString.h"
-
-#include <fstream>
-#include <sstream>
-#include <algorithm>
-#include <iostream>
-#include <limits>
-#include <cmath>
-
-namespace{
-  // copy the inputs, but with NaN replaced with default values. Don't
-  // do anything with NaN values with no defined default.
-  std::map<std::string, double> replace_nan_with_defaults(
-							  const std::map<std::string, double>& inputs,
-							  const std::map<std::string, double>& defaults);
-
-  std::map<std::string, double> add_check_variables(
-						const std::map<std::string, double>& inputs);
-
-  // use this value when an output isn't defined by the NN
-  const double missing_weight = 0.;
-}
-
-namespace Analysis {
-
-  DL1Tag::DL1Tag(const std::string& name, const std::string& n, const IInterface* p):
-    base_class(name, n,p),
-    m_calibrationDirectory("DL1"),
-    m_n_compute_errors(0),
-    m_runModus("analysis")
-  {
-    // access to JSON NN configuration file from COOL:
-    declareProperty("calibration_directory", m_calibrationDirectory);
-    declareProperty("forceDL1CalibrationAlias", m_forceDL1CalibrationAlias = true);
-    declareProperty("DL1CalibAlias", m_DL1CalibAlias = "AntiKt4TopoEM");
-    declareProperty("xAODBaseName", m_xAODBaseName);
-
-    // global configuration
-    declareProperty("Runmodus", m_runModus);
-    declareProperty("LocalNNConfigurationFile", m_LocalNNConfigFile);
-  }
-
-  DL1Tag::~DL1Tag() {
-  }
-
-  StatusCode DL1Tag::initialize() {
-    // prepare readKey for calibration data:
-    ATH_CHECK(m_readKey.initialize());
-
-    // Read in the configuration of the neural net for DL1:
-    if (m_LocalNNConfigFile.size() != 0) { // retrieve map of NN config and default values from local JSON file
-      std::ifstream nn_config_ifstream(m_LocalNNConfigFile);
-      m_localNN = build_nn(nn_config_ifstream,
-                           m_local_variables,
-                           m_local_defaults);
-    }
-    else { // done in condition algorithm
-    }
-
-    ATH_MSG_DEBUG(" Initialization of DL1Tag successful" );
-    return StatusCode::SUCCESS;
-  }
-
-
-  std::unique_ptr<const lwt::LightweightNeuralNetwork>
-  DL1Tag::build_nn(std::istream& nn_config_istream,
-                   std::vector<lwt::Input>& variables,
-                   var_map& defaults) const
-  {
-    lwt::JSONConfig nn_config = lwt::parse_json(nn_config_istream);
-    ATH_MSG_DEBUG("#BTAG# making NN with " << nn_config.layers.size() << " layers");
-
-    if (!(std::find((nn_config.outputs).begin(), (nn_config.outputs).end(), "bottom") != (nn_config.outputs).end())) {
-      ATH_MSG_WARNING( "#BTAG# b-tagger without b-tagging option 'bottom' - please check the NN output naming convention.");
-    }
-
-    defaults = std::move(nn_config.defaults);
-    variables = std::move(nn_config.inputs);
-    return std::make_unique<lwt::LightweightNeuralNetwork>(variables, nn_config.layers, nn_config.outputs);
-  }
-
-  std::unique_ptr<const lwt::LightweightNeuralNetwork>
-  DL1Tag::load_calibration(const std::string& jetauthor,
-                           std::vector<lwt::Input>& variables,
-                           var_map& defaults) const
-  {
-    SG::ReadCondHandle<JetTagCalibCondData> readCdo(m_readKey);
-    lwt::JSONConfig nn_config = readCdo->retrieveDL1NN(m_calibrationDirectory , jetauthor);
-
-    if (nn_config.layers.size() == 0){  //catch if no NN config was found
-      std::string fuller_name = m_calibrationDirectory + "/" +
-      jetauthor + "/net_configuration";
-      throw std::logic_error("Cannot retrieve NN config build from string: " + fuller_name);
-    }
-
-    ATH_MSG_DEBUG("#BTAG# making NN with " << nn_config.layers.size() << " layers");
-
-    if (!(std::find((nn_config.outputs).begin(), (nn_config.outputs).end(), "bottom") != (nn_config.outputs).end())) {
-      ATH_MSG_WARNING( "#BTAG# b-tagger without b-tagging option 'bottom' - please check the NN output naming convention.");
-    }
-    defaults = std::move(nn_config.defaults);
-    variables = std::move(nn_config.inputs);
-    return std::make_unique<lwt::LightweightNeuralNetwork>(variables, nn_config.layers, nn_config.outputs);
-  }
-
-  StatusCode DL1Tag::finalize() { // all taken care of in destructor
-    if (m_n_compute_errors > 0) {
-      ATH_MSG_WARNING("Neural network was unable to compute. Number of errors: "+ std::to_string(m_n_compute_errors));
-    }
-
-    ATH_MSG_DEBUG(" #BTAG# Finalization of DL1Tag successfull" );
-    return StatusCode::SUCCESS;
-  }
-
-  void DL1Tag::fill_outputs(xAOD::BTagging *BTag, var_map outputs) const {
-    if(m_runModus=="analysis") {
-      if (!outputs.count("charm")) {
-	BTag->setVariable<double>(m_xAODBaseName, "pc", missing_weight);
-      }
-      else if (outputs.count("charm")) {
-	BTag->setVariable<double>(m_xAODBaseName, "pc", outputs.at("charm"));
-      }
-
-      if (!outputs.count("light") && !outputs.count("bottom")) {
-	BTag->setVariable<double>(m_xAODBaseName, "pu", missing_weight);
-      }
-      else if (outputs.count("light")) {
-	BTag->setVariable<double>(m_xAODBaseName, "pu", outputs.at("light"));
-      }
-
-      if (outputs.count("bottom")) {
-	BTag->setVariable<double>(m_xAODBaseName, "pb", outputs.at("bottom"));
-	if (!outputs.count("light")) {
-	  BTag->setVariable<double>(m_xAODBaseName, "pu", 1.-outputs.at("bottom"));
-	}
-      }
-      else if (!outputs.count("bottom")) {
-	BTag->setVariable<double>(m_xAODBaseName, "pb", missing_weight);
-	ATH_MSG_WARNING( "#BTAG# b-tagger without b-tagging option: " << outputs.at("bottom"));
-      }
-      ATH_MSG_DEBUG("#BTAG# NN output b: " << outputs.at("bottom") <<
-		    " c: " << outputs.at("charm") << " u: " <<  outputs.at("light"));
-    }
-  }
-
-  void DL1Tag::assignProbability(xAOD::BTagging *BTag,
-				 const var_map &inputs,
-				 const std::string& assigned_jet_author) const
-  {
-    std::string jetauthor = assigned_jet_author;
-
-    std::unique_ptr<const lwt::LightweightNeuralNetwork> nn;
-    const lwt::LightweightNeuralNetwork* nn_ptr = nullptr;
-
-    var_map defaults;
-    const var_map* defaults_ptr;
-
-    std::vector<lwt::Input> variables;
-    const std::vector<lwt::Input>* variables_ptr;
-
-    if (m_LocalNNConfigFile.size()==0) {
-      if (m_forceDL1CalibrationAlias) {
-	jetauthor = m_DL1CalibAlias;
-      }
-      ATH_MSG_DEBUG("#BTAG# Jet author set (via forceDL1CalibrationAlias) to: " << jetauthor );
-      if ( jetauthor.empty() ) {
-	ATH_MSG_WARNING(" #BTAG# Hypothesis or jetauthor is empty."
-			" No likelihood value given back. ");
-      }
-      try {
-	nn = load_calibration(jetauthor, variables, defaults);
-        nn_ptr = nn.get();
-        defaults_ptr = &defaults;
-        variables_ptr = &variables;
-      } catch (std::exception& e) {
-	ATH_MSG_WARNING(
-	  "problem loading calibration for " + jetauthor +
-	  " (" + e.what() + "), skipping this jet");
-	return;
-      }
-    }
-    else {
-      jetauthor = "local";
-      nn_ptr = m_localNN.get();
-      defaults_ptr = &m_local_defaults;
-      variables_ptr = &m_local_variables;
-    }
-
-    var_map complete_inputs = add_check_variables(inputs);
-    var_map cleaned_inputs = replace_nan_with_defaults(complete_inputs, *defaults_ptr);
-
-    for (const lwt::Input& var : *variables_ptr) {
-      if (cleaned_inputs.count(var.name) && std::isnan(cleaned_inputs.at(var.name))) {
-        ATH_MSG_WARNING( "#BTAG# 'nan' input for variable " + var.name + " --> will result in 'nan' classification output. Check NN configuration file for default settings.");
-      }
-    }
-
-    var_map outputs;
-    try {
-      outputs = nn_ptr->compute(cleaned_inputs);
-    } catch (lwt::NNEvaluationException& e) {
-      ATH_MSG_WARNING("Can't compute outputs, probably missing input values");
-      m_n_compute_errors++;
-      return;
-    }
-
-    fill_outputs(BTag, outputs);
-  } //end assign_probability
-}
-
-namespace {
-  std::map<std::string, double> replace_nan_with_defaults(
-							  const std::map<std::string, double>& inputs,
-							  const std::map<std::string, double>& defaults) {
-    // return a new map with the NaN values replaced where possible.
-    std::map<std::string, double> outputs;
-
-    // loop over all inputs and create map of cleaned inputs
-    for (const auto& in: inputs) {
-      if (std::isnan(in.second) && defaults.count(in.first)) {
-	outputs[in.first] = defaults.at(in.first);
-      } else {
-	outputs[in.first] = in.second;
-      }
-    }
-    return outputs;
-  } // end replace_nan_with_defaults
-
-  std::map<std::string, double> add_check_variables(
-						const std::map<std::string, double>& inputs) {
-    // return a new map with additional binary variables for each input variable
-    std::map<std::string, double> complete_inputs;
-
-    for (const auto& in: inputs) {
-      // copy everything from the inputs map
-      complete_inputs.insert(std::make_pair(in.first, in.second));
-      // add binary check variables
-      if (std::isnan(in.second)) {
-	complete_inputs.insert(std::make_pair(in.first + "_check", 1.));
-      }
-      else {
-	complete_inputs.insert(std::make_pair(in.first + "_check", 0.));
-      }
-    }
-    return complete_inputs;
-  }// end add_check_variables
-} // end namespace
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/src/ExKtbbTag.cxx b/PhysicsAnalysis/JetTagging/JetTagTools/src/ExKtbbTag.cxx
deleted file mode 100644
index e6d2f803b6d19390f93215f951eeaaf7336d33da..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagTools/src/ExKtbbTag.cxx
+++ /dev/null
@@ -1,1187 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#include "JetTagTools/ExKtbbTag.h"
-
-#include "GaudiKernel/IToolSvc.h"
-#include "xAODBTagging/SecVtxHelper.h"   // extract SV information
-#include "xAODTracking/TrackParticleContainer.h"
-
-#include <algorithm>
-#include "TVector3.h"
-#include "TMath.h"
-#include "TList.h"
-#include "TMVA/Reader.h"
-
-#include "JetTagCalibration/CalibrationBroker.h"
-
-
-namespace Analysis {
-
-/** 
-    @class ExKtbbTag 
-    Identification of double b-hadron jets ( g->bb or H->bb jets) through exclusive kt subjet b-tagging
-    @author Qi. Zeng
-
-    Input variables ("reference") are all computed in MeV
-    However, they are all converted to GeV when feeding into BDT, as the training was done in GeV
-*/
-
-ExKtbbTag::ExKtbbTag(const std::string& t, const std::string& n, const IInterface* p)
-  : AthAlgTool(t,n,p),
-    m_runModus("analysis"),
-    m_tagMode("Hbb"),
-    m_BDTMode("MV2andJFDRSig"),
-    m_taggerNameBase("ExKtbb"),
-    m_xAODBaseName("ExKtbb"),
-    m_ForceCalibChannel(""),
-    m_debug(false),
-    m_SubJetLabel("ExKt2SubJets"),
-    m_JFOnlyVtx(false),
-    m_calibrationTool("BTagCalibrationBroker")
-{
-  declareInterface<ITagTool>(this);
-
-  // global configuration
-  declareProperty("Runmodus",                 m_runModus);
-  declareProperty("calibrationTool",          m_calibrationTool);
-  declareProperty("tagMode",                  m_tagMode);
-  declareProperty("BDTMode",                  m_BDTMode);
-  declareProperty("taggerNameBase",           m_taggerNameBase);
-  declareProperty("xAODBaseName",             m_xAODBaseName);
-  declareProperty("ForceCalibrationChannel",  m_ForceCalibChannel);
-  declareProperty("debug",                    m_debug);
-
-  // variables for tagger
-  declareProperty("SubJetLabel",              m_SubJetLabel);
-  declareProperty("JFOnlyVtx",                m_JFOnlyVtx);
-
-  m_priVtx = 0;
-}
-
-
-ExKtbbTag::~ExKtbbTag() {
-  // empty for now //
-}
-
-
-StatusCode ExKtbbTag::initialize() {
-
-  // Actual tagger name //
-
-  m_taggerName = m_taggerNameBase + "_" + m_tagMode;
-
-  // PtBinList // 
-
-  m_ptbinlist = { // in GeV
-    400.,        
-    800.,        
-    1250.,       
-    2000.,       
-    3000.,    
-  };
-
-  // Calibration Broker Initialization //
-
-  StatusCode sc = m_calibrationTool.retrieve();
-  if ( sc.isFailure() ) {
-    ATH_MSG_FATAL("#BTAG# Failed to retrieve tool " << m_calibrationTool);
-    return sc;
-  } else {
-    ATH_MSG_DEBUG("#BTAG# Retrieved tool " << m_calibrationTool);
-  }
-
-  for(unsigned int index = 0; index < m_ptbinlist.size()-1; index++){
-    TString tmp = TString::Format("PtBin%i", int(index));
-    m_calibrationTool->registerHistogram(m_taggerNameBase, m_taggerNameBase + "Calib_" + m_tagMode + "_" + m_BDTMode + "_" + tmp.Data());
-  }
-
-  // clear relevant maps/vectors //
-
-  m_tmvaReaders.clear();
-  m_tmvaMethod.clear();
-  m_undefinedReaders.clear();
-
-  // Initialize BDT variables //
-
-  if(!InitTMVAVariables(m_BDTMode)){
-    ATH_MSG_ERROR("#BTAG# Unable to initialize TMVA variables for ExKtbbTag");
-    return StatusCode::FAILURE;
-  }
-
-  return StatusCode::SUCCESS;
-}
-
-
-StatusCode ExKtbbTag::finalize() {
-  
-  // delete readers //
-
-  std::map<std::string, TMVA::Reader*>::iterator pos = m_tmvaReaders.begin();
-  for( ; pos != m_tmvaReaders.end(); ++pos ) delete pos->second;
-  std::map<std::string, TMVA::MethodBase*>::iterator posm = m_tmvaMethod.begin();
-  for( ; posm != m_tmvaMethod.end(); ++posm ) delete posm->second;
-
-  // delete BDT variables //
-
-  std::map<std::string, float*>::iterator posv = m_tmvaVariables.begin();
-  for( ; posv != m_tmvaVariables.end(); ++posv ) delete posv->second;
-  
-  return StatusCode::SUCCESS;
-}
-
-StatusCode ExKtbbTag::tagJet(xAOD::Jet& jetToTag, xAOD::BTagging* BTag, const std::string &jetName) {
-
-  // set jet author information //
-
-  if(m_ForceCalibChannel.empty()){
-    std::string alias = m_calibrationTool->channelAlias(jetname);
-
-    m_ForceCalibChannel = alias;
-  }
-  else if(m_ForceCalibChannel == "Default"){
-    if(m_tagMode == "Hbb") m_ForceCalibChannel = "AntiKt10LCTopoTrimmedPtFrac5SmallR20";
-    else if(m_tagMode == "gbb") m_ForceCalibChannel = "AntiKt4LCTopo";
-    else{
-      ATH_MSG_ERROR("#BTAG# Undefined tag mode: " << m_tagMode.data());
-      return StatusCode::FAILURE;
-    }
-  }
-  else{
-    // empty //
-  }
-  
-  if(!CalculateInputVariables(jetToTag, BTag)){
-    ATH_MSG_ERROR("Error in CalculateInputVariables()!");
-    return StatusCode::FAILURE;
-  }
-
-  if(m_runModus == "reference"){
-    if(!JetTagReferenceMode(jetToTag, BTag)){
-      ATH_MSG_ERROR("Error in JetTagReferenceMode()!");
-      return StatusCode::FAILURE;
-    }
-  }
-  else if(m_runModus == "analysis"){
-    if(!JetTagAnalysisMode(jetToTag, BTag)){
-      ATH_MSG_ERROR("Error in JetTagAnalysisMode()!");
-      return StatusCode::FAILURE;
-    }
-  }
-  else{
-    ATH_MSG_ERROR("Unidentified run mode: " << m_runModus.c_str());
-    return StatusCode::FAILURE;
-  }
-
-  return StatusCode::SUCCESS;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-bool ExKtbbTag::CalculateInputVariables(xAOD::Jet& jetToTag, xAOD::BTagging* BTag){
-  if(m_debug) ATH_MSG_INFO("Entering CalculateInputVariables");
-
-  // Initialization
-  BTag->setVariable<double>(m_taggerName, "DoubleMV2c20", -1.1);
-  BTag->setVariable<double>(m_taggerName, "SingleMV2c20", -1.1);
-  
-  BTag->setVariable<int>(m_taggerName, "SV1NtrksDiff", -20);
-  BTag->setVariable<int>(m_taggerName, "JFNtrksDiff", -20);
-  
-  BTag->setVariable<double>(m_taggerName, "SV1CombMass", -1.);
-  BTag->setVariable<double>(m_taggerName, "JFCombMass", -1.);
-
-  BTag->setVariable<double>(m_taggerName, "SV1DR", -1.);
-  BTag->setVariable<double>(m_taggerName, "SV1DRError", -1.);
-  BTag->setVariable<double>(m_taggerName, "SV1DRSignificance", -1.);
-
-  BTag->setVariable<double>(m_taggerName, "JFDR", -1.);
-  BTag->setVariable<double>(m_taggerName, "JFDRError", -1.);
-  BTag->setVariable<double>(m_taggerName, "JFDRSignificance", -1.);
-
-  BTag->setVariable<double>(m_taggerName, "SV1DR3D", -1.);
-  BTag->setVariable<double>(m_taggerName, "SV1DR3DError", -1.);
-  BTag->setVariable<double>(m_taggerName, "SV1DR3DSignificance", -1.);
-
-  BTag->setVariable<double>(m_taggerName, "SV1DL", -1.);
-  BTag->setVariable<double>(m_taggerName, "SV1DLError", -1.);
-  BTag->setVariable<double>(m_taggerName, "SV1DLSignificance", -1.);
-
-  BTag->setVariable<double>(m_taggerName, "JFDL", -1.);
-  BTag->setVariable<double>(m_taggerName, "JFDLError", -1.);
-  BTag->setVariable<double>(m_taggerName, "JFDLSignificance", -1.);
-
-  if(m_debug) ATH_MSG_INFO("Fetching subjets");
-
-  // Bug fix in 20.7. Rebuild the link to subjet. 
-
-  auto SubjetContainer = evtStore()->tryRetrieve<xAOD::JetContainer>(jetToTag.auxdata<std::string>(m_SubJetLabel + "_ContainerName"));
-  if(SubjetContainer == 0){
-    ATH_MSG_ERROR("Unable to get subjet container " << m_SubJetLabel << "_ContainerName !");
-    return false;
-  }
-
-  auto SubjetIndexList = jetToTag.auxdata<std::vector<int> >(m_SubJetLabel + "_IndexList");
-  std::vector<const xAOD::Jet*> ExKtSubJets;
-  for(auto index : SubjetIndexList){
-    ExKtSubJets.push_back(SubjetContainer->at(index));
-  }
-
-  // overwrite the original subjet link built in subjetrecorder, since it might be broken after b-tagging deep-copy
-
-  jetToTag.setAssociatedObjects(m_SubJetLabel, ExKtSubJets);
-
-  if(m_debug) ATH_MSG_INFO("Check if subjets ptr is valid");
-
-  // check if each subjet is valid
-  for(auto subjet : ExKtSubJets){
-    if(!subjet){
-      ATH_MSG_ERROR("Empty ptr to subjet! You will crash soon...");
-      return false;
-    }
-  }
-
-  if(m_debug) ATH_MSG_INFO("Sort subjets by pT");
-
-  std::sort(ExKtSubJets.begin(), ExKtSubJets.end(), ExKtbbTag::SortPt);
-
-  if(m_debug) ATH_MSG_INFO("Begin computing inputs");
-
-  // validity check
-  if(ExKtSubJets.size() == 2){
-    const xAOD::BTagging* bjet_LeadExKtSubJet = xAOD::BTaggingUtilities::getBTagging( *ExKtSubJets[0] );
-    const xAOD::BTagging* bjet_SubLeadExKtSubJet = xAOD::BTaggingUtilities::getBTagging( *ExKtSubJets[1] );
-
-
-    if( (!bjet_LeadExKtSubJet) || (!bjet_SubLeadExKtSubJet) ){
-      ATH_MSG_ERROR("Exclusive kt subjet is not well b-tagged!");
-      return false;
-    }
-
-    BTag->setVariable<double>(m_taggerName, "DoubleMV2c20", GetDoubleMV2c20(bjet_LeadExKtSubJet, bjet_SubLeadExKtSubJet));
-    BTag->setVariable<double>(m_taggerName, "SingleMV2c20", GetSingleMV2c20(bjet_LeadExKtSubJet, bjet_SubLeadExKtSubJet));
-  
-    BTag->setVariable<int>(m_taggerName, "SV1NtrksDiff", GetSV1NtrksDiff(BTag, bjet_LeadExKtSubJet, bjet_SubLeadExKtSubJet, true));
-    BTag->setVariable<int>(m_taggerName, "JFNtrksDiff", GetJFNtrksDiff(BTag, bjet_LeadExKtSubJet, bjet_SubLeadExKtSubJet, true, m_JFOnlyVtx));
-    
-    BTag->setVariable<double>(m_taggerName, "SV1CombMass", GetSV1CombMass(bjet_LeadExKtSubJet, bjet_SubLeadExKtSubJet, true));
-    BTag->setVariable<double>(m_taggerName, "JFCombMass", GetJFCombMass(bjet_LeadExKtSubJet, bjet_SubLeadExKtSubJet, true, m_JFOnlyVtx, true));
-
-    double SV1DR, SV1DRError;
-    BTag->setVariable<double>(m_taggerName, "SV1DRSignificance", GetSV1DRSignificance(bjet_LeadExKtSubJet, bjet_SubLeadExKtSubJet, SV1DR, SV1DRError));
-    BTag->setVariable<double>(m_taggerName, "SV1DR", SV1DR);
-    BTag->setVariable<double>(m_taggerName, "SV1DRError", SV1DRError);
-
-    double JFDR, JFDRError;
-    BTag->setVariable<double>(m_taggerName, "JFDRSignificance", GetJFDRSignificance(bjet_LeadExKtSubJet, bjet_SubLeadExKtSubJet, m_JFOnlyVtx, JFDR, JFDRError));
-    BTag->setVariable<double>(m_taggerName, "JFDR", JFDR);
-    BTag->setVariable<double>(m_taggerName, "JFDRError", JFDRError);
-
-    double SV1DR3D, SV1DR3DError;
-    BTag->setVariable<double>(m_taggerName, "SV1DR3DSignificance", GetSV1DR3DSignificance(bjet_LeadExKtSubJet, bjet_SubLeadExKtSubJet, SV1DR3D, SV1DR3DError));
-    BTag->setVariable<double>(m_taggerName, "SV1DR3D", SV1DR3D);
-    BTag->setVariable<double>(m_taggerName, "SV1DR3DError", SV1DR3DError);
-
-    double SV1DL, SV1DLError;
-    BTag->setVariable<double>(m_taggerName, "SV1DLSignificance", GetSV1DLSignificance(bjet_LeadExKtSubJet, bjet_SubLeadExKtSubJet, SV1DL, SV1DLError));
-    BTag->setVariable<double>(m_taggerName, "SV1DL", SV1DL);
-    BTag->setVariable<double>(m_taggerName, "SV1DLError", SV1DLError);
-
-    double JFDL, JFDLError;
-    BTag->setVariable<double>(m_taggerName, "JFDLSignificance", GetJFDLSignificance(bjet_LeadExKtSubJet, bjet_SubLeadExKtSubJet, m_JFOnlyVtx, JFDL, JFDLError));
-    BTag->setVariable<double>(m_taggerName, "JFDL", JFDL);
-    BTag->setVariable<double>(m_taggerName, "JFDLError", JFDLError);
-  }
-  else if(ExKtSubJets.size() == 3){
-    ATH_MSG_WARNING("Exclusive kt with N=3 is not supported yet! Jet will be skipped");
-    return true;
-  }
-  else{
-    ATH_MSG_WARNING("Unable to process Exclusive kt with N=" << ExKtSubJets.size() <<". Jet will be skipped");
-    return true;
-  }
-
-
-  if(m_debug) ATH_MSG_INFO("Leaving CalculateInputVariables");
-
-  return true;
-}
-
-bool ExKtbbTag::JetTagAnalysisMode(xAOD::Jet& jetToTag, xAOD::BTagging* BTag){
-  if(m_debug) ATH_MSG_INFO("Entering JetTagAnalysisMode");
-
-  // Retrieve correct calibration file
-  std::string taggerCalibName = m_taggerNameBase + "Calib_" + m_tagMode + "_" + m_BDTMode + "_" + GetPtBin(&jetToTag);
-  std::pair<TList*, bool> calib = m_calibrationTool->retrieveTObject<TList>(m_taggerNameBase, m_ForceCalibChannel, taggerCalibName);
-
-  // keyname for TMVAReader cache
-  std::string keyname = m_ForceCalibChannel + "/" + taggerCalibName;
-
-  bool calibHasChanged = calib.second;
-  if(calibHasChanged){ // initiate TMVA
-
-    if(!calib.first){ // catch exception
-      ATH_MSG_WARNING("#BTAG# TList cannot be retrieved -> no calibration for " << m_taggerNameBase << "/" << m_ForceCalibChannel << "/" << taggerCalibName);
-      BTag->setVariable<double>(m_taggerName, m_BDTMode, -100);
-      return true;
-    }
-
-    m_calibrationTool->updateHistogramStatus(m_taggerNameBase, m_ForceCalibChannel, taggerCalibName, false);
-
-    TList* list = calib.first; 
-
-    std::ostringstream iss;
-    for(int i=0; i<list->GetSize(); ++i) {
-      TObjString* ss = (TObjString*)list->At(i);
-      std::string sss = ss->String().Data();
-      //KM: if it doesn't find "<" in the string, it starts from non-space character
-      int posi = sss.find('<')!=std::string::npos ? sss.find('<') : sss.find_first_not_of(" ");
-      std::string tmp = sss.erase(0,posi);
-      iss << tmp.data(); 
-    }
-
-    TMVA::Reader* tmvaReader = new TMVA::Reader();
-    BundleTMVAVariables(m_BDTMode, tmvaReader);
-
-    TMVA::IMethod* method = tmvaReader->BookMVA(TMVA::Types::kBDT, iss.str().data());
-    TMVA::MethodBase* methodBase = dynamic_cast<TMVA::MethodBase*>(method);
-
-    // overwrite to the map or reader now
-    auto pos = m_tmvaReaders.find(keyname);
-    if(pos != m_tmvaReaders.end()){
-      delete pos->second;
-      m_tmvaReaders.erase(pos);
-    }
-
-    auto posMethod = m_tmvaMethod.find(keyname);
-    if(posMethod != m_tmvaMethod.end()){
-      delete posMethod->second;
-      m_tmvaMethod.erase(posMethod);
-    }
-
-    m_tmvaReaders.insert( std::make_pair(keyname, tmvaReader) );
-    m_tmvaMethod.insert( std::make_pair(keyname, methodBase) );
-  }
-
-  // assign values to BDT variables
-  FillTMVAVariables(m_BDTMode, &jetToTag, BTag);
-
-  // Finally compute the weight
-  double FinalWeight = -100.;
-  auto posReader = m_tmvaReaders.find(keyname);
-  if(posReader == m_tmvaReaders.end()){
-    int alreadyWarned = std::count(m_undefinedReaders.begin(), m_undefinedReaders.end(), keyname);
-    if(alreadyWarned == 0){
-      ATH_MSG_WARNING("#BTAG# no TMVA reader defined for " << keyname);
-      m_undefinedReaders.push_back(keyname);
-    }
-  }
-  else{
-    auto posMethod = m_tmvaMethod.find(keyname);
-    if(posMethod->second != 0){
-      FinalWeight = posReader->second->EvaluateMVA(posMethod->second);
-    }
-    else{
-      ATH_MSG_WARNING("#BTAG# Empty TMVA::Method for " << keyname);
-    }
-  }
-
-  BTag->setVariable<double>(m_taggerName, m_BDTMode, FinalWeight);
-
-  if(m_debug) ATH_MSG_INFO("Leaving JetTagAnalysisMode");
-
-  return true;
-}
-
-bool ExKtbbTag::JetTagReferenceMode(xAOD::Jet& /*jetToTag*/, xAOD::BTagging* /*BTag*/){
-  if(m_debug) ATH_MSG_INFO("Entering JetTagReferenceMode");
-
-  // No need to do anything, since all reference variable has been computed earlier //
-
-  if(m_debug) ATH_MSG_INFO("Leaving JetTagReferenceMode");
-
-  return true;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////
-
-double ExKtbbTag::GetDoubleMV2c20(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2){
-  double FirstMV2c20 = bjet1->auxdata<double>("MV2c20_discriminant");
-  double SecondMV2c20 = bjet2->auxdata<double>("MV2c20_discriminant");
-
-  return std::min(FirstMV2c20, SecondMV2c20);  
-}
-
-double ExKtbbTag::GetSingleMV2c20(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2){
-  double FirstMV2c20 = bjet1->auxdata<double>("MV2c20_discriminant");
-  double SecondMV2c20 = bjet2->auxdata<double>("MV2c20_discriminant");
-
-  return std::max(FirstMV2c20, SecondMV2c20);  
-}
-
-int ExKtbbTag::GetSV1NtrksDiff(const xAOD::BTagging* bjet, const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool doValidDualSV1){
-  auto SV1vertices_bjet = GetSV1vertices(bjet);
-  auto SV1vertices_bjet1 = GetSV1vertices(bjet1);
-  auto SV1vertices_bjet2 = GetSV1vertices(bjet2);
-
-  bool isValidDualSV1 = SV1DualValid(SV1vertices_bjet1, SV1vertices_bjet2);
-
-  if( (doValidDualSV1) && (!isValidDualSV1) ) return -20;
-
-  return (IsValidSV1(SV1vertices_bjet1) ? SV1vertices_bjet1[0]->nTrackParticles() : 0) + (IsValidSV1(SV1vertices_bjet2) ? SV1vertices_bjet2[0]->nTrackParticles() : 0) - (IsValidSV1(SV1vertices_bjet) ? SV1vertices_bjet[0]->nTrackParticles() : 0);
-}
-
-int ExKtbbTag::GetJFNtrksDiff(const xAOD::BTagging* bjet, const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool doValidDualJF, bool onlyVtx){
-  bool isValidDualJF = JFDualValid(bjet1, bjet2, onlyVtx);
-
-  if( (doValidDualJF) && (!isValidDualJF) ) return -20;
-
-  return IsValidJF(bjet1, onlyVtx) * JFntrk(bjet1, onlyVtx) + IsValidJF(bjet2, onlyVtx) * JFntrk(bjet2, onlyVtx) - IsValidJF(bjet, onlyVtx) * JFntrk(bjet, onlyVtx);
-}
-
-double ExKtbbTag::GetSV1CombMass(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool doValidDualSV1){
-  auto SV1vertices_bjet1 = GetSV1vertices(bjet1);
-  auto SV1vertices_bjet2 = GetSV1vertices(bjet2);
-
-  bool isValidDualSV1 = SV1DualValid(SV1vertices_bjet1, SV1vertices_bjet2);
-
-  if( (doValidDualSV1) && (!isValidDualSV1) ) return -1.;
-
-  std::vector<ElementLink<xAOD::TrackParticleContainer> > SV1Tracks_bjet1 = bjet1->SV1_TrackParticleLinks();
-  std::vector<ElementLink<xAOD::TrackParticleContainer> > SV1Tracks_bjet2 = bjet2->SV1_TrackParticleLinks();
-
-  std::vector<ElementLink<xAOD::TrackParticleContainer> > SV1Tracks_Comb = SV1Tracks_bjet1;
-  SV1Tracks_Comb.insert(SV1Tracks_Comb.end(), SV1Tracks_bjet2.begin(), SV1Tracks_bjet2.end());
-
-  TLorentzVector SumSV1TracksP4;
-  for(auto el_track : SV1Tracks_Comb){
-    if(!el_track.isValid()){
-      ATH_MSG_WARNING("Invalid element link to SV1_TrackParticles. It will be skipped");
-      continue;
-    }
-
-    if(*el_track == 0){
-      ATH_MSG_WARNING("Null ptr returned for SV1_TrackParticles. It will be skipped");
-      continue;
-    }
-
-    SumSV1TracksP4 += ((*el_track)->p4());
-  }
-
-  // return SumSV1TracksP4.M()/1000.;    // MeV->GeV
-  return SumSV1TracksP4.M();
-}
-
-double ExKtbbTag::GetJFCombMass(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool doValidDualJF, bool onlyVtx, bool doNeutralCorrection){
-  bool isValidDualJF = JFDualValid(bjet1, bjet2, onlyVtx);
-
-  if( (doValidDualJF) && (!isValidDualJF) ) return -1.;
-
-  TLorentzVector SumP4 = JFMomentum(bjet1, onlyVtx, doNeutralCorrection) + JFMomentum(bjet2, onlyVtx, doNeutralCorrection);
-  // return SumP4.M()/1000.;    // MeV->GeV
-  return SumP4.M();
-}
-
-double ExKtbbTag::GetSV1DRSignificance(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, double& DR, double& DR_error){
-  DR = -1.;
-  DR_error = -1.;
-
-  auto SV1vertices_bjet1 = GetSV1vertices(bjet1);
-  auto SV1vertices_bjet2 = GetSV1vertices(bjet2);
-
-  if(!SV1DualValid(SV1vertices_bjet1, SV1vertices_bjet2)) return -1.;
-
-  auto FirstSV1 = SV1vertices_bjet1[0];
-  auto SecondSV1 = SV1vertices_bjet2[0];
-
-  // calculate DR
-  auto function_SV1DR = [](Amg::Vector3D vtx1, Amg::Vector3D vtx2, Amg::Vector3D PV)->double{
-    TVector3 vtx1_pv(vtx1(0) - PV(0), vtx1(1) - PV(1), vtx1(2) - PV(2));
-    TVector3 vtx2_pv(vtx2(0) - PV(0), vtx2(1) - PV(1), vtx2(2) - PV(2));
-
-    return vtx1_pv.DeltaR(vtx2_pv);
-  };
-
-  DR = function_SV1DR(FirstSV1->position(), SecondSV1->position(), m_priVtx->position());
-
-  // calculate error on DR
-  auto FirstSV1_variations  = GetVtxEigenVariation(FirstSV1->position(), FirstSV1->covariancePosition());
-  auto SecondSV1_variations = GetVtxEigenVariation(SecondSV1->position(), SecondSV1->covariancePosition());
-  auto PV_variations = GetVtxEigenVariation(m_priVtx->position(), m_priVtx->covariancePosition());
-
-  double sumerror2_FirstSV1 = 0.;
-  double sumerror2_SecondSV1 = 0.;
-  double sumerror2_PV = 0.;
-  for(unsigned int index = 0; index < 3; index++){
-    double error_FirstSV1 = std::max( fabs(function_SV1DR(FirstSV1_variations[2*index], SecondSV1->position(), m_priVtx->position()) - DR), fabs(function_SV1DR(FirstSV1_variations[2*index+1], SecondSV1->position(), m_priVtx->position()) - DR) );
-    sumerror2_FirstSV1 += (error_FirstSV1 * error_FirstSV1);
-
-    double error_SecondSV1 = std::max( fabs(function_SV1DR(FirstSV1->position(), SecondSV1_variations[2*index], m_priVtx->position()) - DR), fabs(function_SV1DR(FirstSV1->position(), SecondSV1_variations[2*index+1], m_priVtx->position()) - DR) );
-    sumerror2_SecondSV1 += (error_SecondSV1 * error_SecondSV1);
-
-    double error_PV = std::max( fabs(function_SV1DR(FirstSV1->position(), SecondSV1->position(), PV_variations[2*index]) - DR), fabs(function_SV1DR(FirstSV1->position(), SecondSV1->position(), PV_variations[2*index+1]) - DR) );
-    sumerror2_PV += (error_PV * error_PV);
-  }
-
-  DR_error = TMath::Sqrt(sumerror2_FirstSV1 + sumerror2_SecondSV1 + sumerror2_PV);
-
-  double output = 0.;
-  if(DR_error == 0.){
-    ATH_MSG_WARNING("Zero error obtained in GetSV1DRSignificance, which is very unlikely");
-    output = 999.;
-  }
-  else{
-    output = DR/DR_error;
-  }
-
-  return LimitUpperBound(output, 50, 100);
-}
-
-double ExKtbbTag::GetJFDRSignificance(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool onlyVtx, double& DR, double& DR_error){
-  DR = -1.;
-  DR_error = -1.;
-
-  if(!JFDualValid(bjet1, bjet2, onlyVtx)) return -1.;
-
-  std::vector<float> fittedPosition_bjet1;
-  std::vector<float> fittedCov_bjet1;
-  fittedPosition_bjet1 = GetJFfittedPosition(bjet1, fittedCov_bjet1);
-
-  std::vector<float> fittedPosition_bjet2;
-  std::vector<float> fittedCov_bjet2;
-  fittedPosition_bjet2 = GetJFfittedPosition(bjet2, fittedCov_bjet2);
-
-  // get DR
-  auto function_JFAxis3D = [](double theta, double phi)->TVector3{
-    TVector3 axis;
-    axis.SetMagThetaPhi(1., theta, phi);
-    return axis;
-  };
-
-  auto function_JFDR = [](TVector3 axis1, TVector3 axis2)->double{
-    return axis1.DeltaR(axis2);
-  };
-
-  double theta_bjet1 = fittedPosition_bjet1[4];
-  double phi_bjet1 = fittedPosition_bjet1[3];
-  double theta_bjet2 = fittedPosition_bjet2[4];
-  double phi_bjet2 = fittedPosition_bjet2[3];
-  DR = function_JFDR(function_JFAxis3D(theta_bjet1, phi_bjet1), function_JFAxis3D(theta_bjet2, phi_bjet2));
-
-  // get error
-  double Error_theta_bjet1 = std::max( fabs(function_JFDR(function_JFAxis3D(theta_bjet1 + TMath::Sqrt(fittedCov_bjet1[4]), phi_bjet1), function_JFAxis3D(theta_bjet2, phi_bjet2)) - DR),  fabs(function_JFDR(function_JFAxis3D(theta_bjet1 - TMath::Sqrt(fittedCov_bjet1[4]), phi_bjet1), function_JFAxis3D(theta_bjet2, phi_bjet2)) - DR) );
-  double Error_phi_bjet1 = std::max( fabs(function_JFDR(function_JFAxis3D(theta_bjet1, phi_bjet1 + TMath::Sqrt(fittedCov_bjet1[3])), function_JFAxis3D(theta_bjet2, phi_bjet2)) - DR),  fabs(function_JFDR(function_JFAxis3D(theta_bjet1, phi_bjet1 - TMath::Sqrt(fittedCov_bjet1[3])), function_JFAxis3D(theta_bjet2, phi_bjet2)) - DR) );
-  double Error_theta_bjet2 = std::max( fabs(function_JFDR(function_JFAxis3D(theta_bjet1, phi_bjet1), function_JFAxis3D(theta_bjet2 + TMath::Sqrt(fittedCov_bjet2[4]), phi_bjet2)) - DR),  fabs(function_JFDR(function_JFAxis3D(theta_bjet1, phi_bjet1), function_JFAxis3D(theta_bjet2 - TMath::Sqrt(fittedCov_bjet2[4]), phi_bjet2)) - DR) );
-  double Error_phi_bjet2 = std::max( fabs(function_JFDR(function_JFAxis3D(theta_bjet1, phi_bjet1), function_JFAxis3D(theta_bjet2, phi_bjet2 + TMath::Sqrt(fittedCov_bjet2[3]))) - DR),  fabs(function_JFDR(function_JFAxis3D(theta_bjet1, phi_bjet1), function_JFAxis3D(theta_bjet2, phi_bjet2 - TMath::Sqrt(fittedCov_bjet2[3]))) - DR) );
-
-  DR_error = TMath::Sqrt( Error_theta_bjet1*Error_theta_bjet1 + Error_phi_bjet1*Error_phi_bjet1 + Error_theta_bjet2*Error_theta_bjet2 + Error_phi_bjet2*Error_phi_bjet2 );
-
-  double output = 0.;
-  if(DR_error == 0.){
-    ATH_MSG_WARNING("Zero error obtained in GetJFDRSignificance, which is very unlikely");
-    output = 999.;
-  }
-  else{
-    output = DR/DR_error;
-  }
-
-  return LimitUpperBound(output, 50, 100);
-}
-
-double ExKtbbTag::GetSV1DR3DSignificance(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, double& dR3D, double& dR3D_error){
-  dR3D = -1.;
-  dR3D_error = -1;
-
-  auto SV1vertices_bjet1 = GetSV1vertices(bjet1);
-  auto SV1vertices_bjet2 = GetSV1vertices(bjet2);
-
-  if(!SV1DualValid(SV1vertices_bjet1, SV1vertices_bjet2)) return -1.;
-
-  auto FirstSV1 = SV1vertices_bjet1[0];
-  auto SecondSV1 = SV1vertices_bjet2[0];
-
-  return GeneralDRSignificance3D(FirstSV1->position(), FirstSV1->covariancePosition(), SecondSV1->position(), SecondSV1->covariancePosition(), dR3D, dR3D_error);
-}
-
-double ExKtbbTag::GetSV1DLSignificance(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, double& dL, double& dL_error){
-  dL = -1.;
-  dL_error = -1.;
-
-  auto SV1vertices_bjet1 = GetSV1vertices(bjet1);
-  auto SV1vertices_bjet2 = GetSV1vertices(bjet2);
-
-  if(!SV1DualValid(SV1vertices_bjet1, SV1vertices_bjet2)) return -1.;
-
-  auto FirstSV1 = SV1vertices_bjet1[0];
-  auto SecondSV1 = SV1vertices_bjet2[0];
-
-  // calculate dL
-  auto function_GetDL = [](Amg::Vector3D vtx1, Amg::Vector3D vtx2, Amg::Vector3D pv)->double{
-    double l1 = TMath::Sqrt((vtx1 - pv).dot(vtx1 - pv));
-    double l2 = TMath::Sqrt((vtx2 - pv).dot(vtx2 - pv));
-
-    return fabs(l1-l2);
-  };
-
-  dL = function_GetDL(FirstSV1->position(), SecondSV1->position(), m_priVtx->position());
-
-  // Calculate Error
-  std::vector<Amg::Vector3D> FirstSV1_variations = GetVtxEigenVariation(FirstSV1->position(), FirstSV1->covariancePosition());
-  std::vector<Amg::Vector3D> SecondSV1_variations = GetVtxEigenVariation(SecondSV1->position(), SecondSV1->covariancePosition());
-  std::vector<Amg::Vector3D> PV_variations = GetVtxEigenVariation(m_priVtx->position(), m_priVtx->covariancePosition());
-
-  double sumerror2_FirstSV1 = 0.;
-  double sumerror2_SecondSV1 = 0.;
-  double sumerror2_PV = 0.;
-
-  for(unsigned int index = 0; index < 3; index++){
-    double error_FirstSV1 = std::max(fabs(function_GetDL(FirstSV1_variations[2*index], SecondSV1->position(), m_priVtx->position()) - dL), fabs(function_GetDL(FirstSV1_variations[2*index+1], SecondSV1->position(), m_priVtx->position()) - dL));
-    sumerror2_FirstSV1 += (error_FirstSV1 * error_FirstSV1);
-
-    double error_SecondSV1 = std::max(fabs(function_GetDL(FirstSV1->position(), SecondSV1_variations[2*index], m_priVtx->position()) - dL), fabs(function_GetDL(FirstSV1->position(), SecondSV1_variations[2*index+1], m_priVtx->position()) - dL));
-    sumerror2_SecondSV1 += (error_SecondSV1 * error_SecondSV1);
-
-    double error_PV = std::max(fabs(function_GetDL(FirstSV1->position(), SecondSV1->position(), PV_variations[2*index]) - dL), fabs(function_GetDL(FirstSV1->position(), SecondSV1->position(), PV_variations[2*index+1]) - dL));
-    sumerror2_PV += (error_PV * error_PV); 
-  }
-
-  dL_error = TMath::Sqrt(sumerror2_FirstSV1 + sumerror2_SecondSV1 + sumerror2_PV);
-
-  double output = 0.;
-  if(dL_error == 0.){
-    ATH_MSG_WARNING("Zero error obtained in GetSV1DLSignificance, which is very unlikely");
-    output = 999.;
-  }
-  else{
-    output = dL/dL_error;
-  }
-
-  return LimitUpperBound(output, 50, 100);
-}
-
-double ExKtbbTag::GetJFDLSignificance(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool onlyVtx, double& dL, double& dL_error){
-  dL = -1.;
-  dL_error = -1.;
-
-  if(!JFDualValid(bjet1, bjet2, onlyVtx)) return -1.;
-
-  std::vector<float> fittedPosition_bjet1;
-  std::vector<float> fittedCov_bjet1;
-  fittedPosition_bjet1 = GetJFfittedPosition(bjet1, fittedCov_bjet1);
-
-  std::vector<float> fittedPosition_bjet2;
-  std::vector<float> fittedCov_bjet2;
-  fittedPosition_bjet2 = GetJFfittedPosition(bjet2, fittedCov_bjet2);
-
-  // get dL
-  auto function_GetDL = [](double l1, double l2)->double{
-    return fabs(l1-l2);
-  };
-
-  double l1,l1_error;
-  l1 = JFEffectiveDecayLength(bjet1, onlyVtx, l1_error);
-
-  double l2,l2_error;
-  l2 = JFEffectiveDecayLength(bjet2, onlyVtx, l2_error);
-
-  dL = function_GetDL(l1, l2);
-
-  double error_l1 = std::max(fabs(function_GetDL(l1 + l1_error, l2) - dL), fabs(function_GetDL(l1 - l1_error, l2) - dL));
-  double error_l2 = std::max(fabs(function_GetDL(l1, l2 + l2_error) - dL), fabs(function_GetDL(l1, l2 - l2_error) - dL));
-
-  dL_error = TMath::Sqrt(error_l1*error_l1 + error_l2*error_l2);
-
-  double output = 0.;
-  if(dL_error == 0.){
-    ATH_MSG_WARNING("Zero error obtained in GetJFDLSignificance, which is very unlikely");
-    output = 999.;
-  }
-  else{
-    output = dL/dL_error;
-  }
-
-  return LimitUpperBound(output, 50, 100);
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////
-
-std::vector<const xAOD::Vertex*> ExKtbbTag::GetSV1vertices(const xAOD::BTagging* bjet){
-  std::vector<ElementLink<xAOD::VertexContainer> > SV1vertices;
-  try{
-    SV1vertices = bjet->auxdata<std::vector<ElementLink<xAOD::VertexContainer> > >("SV1_vertices");
-  }
-  catch(...){
-    ATH_MSG_WARNING("Unable to get \"SV1_vertices\" from bjet");
-  }
-
-  std::vector<const xAOD::Vertex*> output;
-  for(auto el_vtx : SV1vertices){
-    if(!el_vtx.isValid()){
-      ATH_MSG_WARNING("Invalid element link to SV1 vtx. It will be skipped");
-      continue;
-    }
-
-    const xAOD::Vertex* vtx = (*el_vtx);
-    if(vtx == 0){
-      ATH_MSG_WARNING("Null ptr returned for SV1 vtx. It will be skipped");
-      continue;
-    }
-
-    output.push_back(vtx);
-  }
-
-  return output;
-}
-
-bool ExKtbbTag::IsValidSV1(std::vector<const xAOD::Vertex*> input){
-  if(input.size() > 1){
-    ATH_MSG_WARNING("Get more than 1 SV1 vtx! Only first one will be used.");
-  }
-
-  return input.size() > 0;
-}
-
-bool ExKtbbTag::SV1DualValid(std::vector<const xAOD::Vertex*> vtx1, std::vector<const xAOD::Vertex*> vtx2){
-  return IsValidSV1(vtx1) && IsValidSV1(vtx2);
-}
-
-std::vector<const xAOD::BTagVertex*> ExKtbbTag::GetJFVertices(const xAOD::BTagging* bjet){
-  std::vector<ElementLink<xAOD::BTagVertexContainer> > jfvertices;
-  try{
-    jfvertices = bjet->auxdata<std::vector<ElementLink<xAOD::BTagVertexContainer> > >("JetFitter_JFvertices");
-  } catch(...){
-    ATH_MSG_WARNING("Unable to get \"JetFitter_JFvertices\"");
-  }
-
-  std::vector<const xAOD::BTagVertex*> output;
-  for(auto el_vtx : jfvertices){
-    if(!el_vtx.isValid()){
-      ATH_MSG_WARNING("Invalid element link to JF vertices. It will be skipped");
-      continue;
-    }
-
-    const xAOD::BTagVertex* vtx = (*el_vtx);
-    if(vtx == 0){
-      ATH_MSG_WARNING("Null ptr returned for JF vertices. It will be skipped");
-      continue;
-    }
-
-    output.push_back(vtx);
-  }
-
-  return output;
-}
-
-std::vector<float> ExKtbbTag::GetJFfittedPosition(const xAOD::BTagging* bjet, std::vector<float>& JFfittedCov){
-  std::vector<float> JFfittedPosition;
-  JFfittedCov.clear();
-
-  try{
-    JFfittedPosition = bjet->auxdata<std::vector<float> >("JetFitter_fittedPosition");
-    JFfittedCov      = bjet->auxdata<std::vector<float> >("JetFitter_fittedCov");
-  }
-  catch(...){
-    ATH_MSG_WARNING("Unable to get \"JetFitter_fittedCov\" and/or \"JetFitter_fittedCov\"");
-  }
-
-  return JFfittedPosition;
-}
-
-bool ExKtbbTag::IsValidJF(const xAOD::BTagging* bjet, bool onlyVtx){
-  int JFnvtx = 0;         bjet->taggerInfo(JFnvtx, xAOD::JetFitter_nVTX);
-  int JFnsingletrks = 0;  bjet->taggerInfo(JFnsingletrks, xAOD::JetFitter_nSingleTracks);
-
-  if(onlyVtx) return JFnvtx > 0;
-  else        return (JFnvtx > 0) || (JFnsingletrks > 0); 
-}
-
-bool ExKtbbTag::JFDualValid(const xAOD::BTagging* bjet1, const xAOD::BTagging* bjet2, bool onlyVtx){
-  return IsValidJF(bjet1, onlyVtx) && IsValidJF(bjet2, onlyVtx);
-}
-
-int ExKtbbTag::JFntrk(const xAOD::BTagging* bjet, bool onlyVtx){
-  if(!IsValidJF(bjet, onlyVtx)){
-    return -1;
-  }
-  else{
-    int JFnvtxtrk = 0;     bjet->taggerInfo(JFnvtxtrk, xAOD::JetFitter_nTracksAtVtx);
-    int JFnsingletrks = 0; bjet->taggerInfo(JFnsingletrks, xAOD::JetFitter_nSingleTracks);
-
-    if(onlyVtx) return JFnvtxtrk;
-    else        return JFnvtxtrk + JFnsingletrks;
-  }
-}
-
-TLorentzVector ExKtbbTag::JFMomentum(const xAOD::BTagging* bjet, bool onlyVtx, bool doNeutralCorrection){
-  // Initialization
-  TLorentzVector SumChargeP4(0., 0., 0., 0.);
-  TLorentzVector SumNeutralP4(0., 0., 0., 0.);
-  double SumPtAdd = 0.;
-
-  // quit for invalid jF
-  if(!IsValidJF(bjet, onlyVtx)) return SumChargeP4;
-
-  // get necessary ingredient
-  std::vector<const xAOD::BTagVertex*> jfvertices = GetJFVertices(bjet);
-  
-  std::vector<float> fittedPosition; std::vector<float> fittedCov;
-  fittedPosition = GetJFfittedPosition(bjet, fittedCov);
-
-  // fitted direction
-  TVector3 JFDir(1., 1., 1.);
-  JFDir.SetMagThetaPhi(1., fittedPosition[4], fittedPosition[3]);
-
-  // number of vtx (with at least 2 tracks)
-  int nVtx = 0;
-  bjet->taggerInfo(nVtx, xAOD::JetFitter_nVTX);
-
-  // loop over vertices
-  for(unsigned int ivtx = 0; ivtx < jfvertices.size(); ivtx++){
-    auto JFVtx = jfvertices[ivtx];
-
-    // reject negative vtx
-    if(fittedPosition[5+ivtx] < 0) continue;
-
-    // loop over tracks on vtx
-    TLorentzVector TrackOnVtxP4(0., 0., 0., 0.);
-    for(auto el_track : JFVtx->track_links()){
-      if(!el_track.isValid()){
-        ATH_MSG_WARNING("Missing link to tracks associated to JF vtx. It will be skipped");
-        continue;
-      }
-
-      auto track = (*el_track);
-
-      TrackOnVtxP4 += track->p4();
-    }
-
-    // get neutral momentum
-    TVector3 JFDir_scale; JFDir_scale.SetMagThetaPhi(TrackOnVtxP4.Vect().Dot(JFDir), JFDir.Theta(), JFDir.Phi());
-    TVector3 NeutralOnVtxP3 = JFDir_scale - TrackOnVtxP4.Vect();
-    TLorentzVector NeutralOnVtxP4; NeutralOnVtxP4.SetVectM(NeutralOnVtxP3, 0.);
-
-    // summation
-    if(!onlyVtx){
-      SumChargeP4 += TrackOnVtxP4;
-      SumNeutralP4 += NeutralOnVtxP4;
-      SumPtAdd += TrackOnVtxP4.Perp(JFDir);
-    }
-    else{
-      if( (nVtx > 0 && JFVtx->track_links().size() > 1) || (nVtx == 0) ){ 
-        SumChargeP4 += TrackOnVtxP4;
-        SumNeutralP4 += NeutralOnVtxP4;
-        SumPtAdd += TrackOnVtxP4.Perp(JFDir);
-      }
-    }
-    
-  }
-
-  if(doNeutralCorrection){
-    return SumChargeP4 + SumNeutralP4;
-  }
-  else{
-    return SumChargeP4;
-  }
-}
-
-double ExKtbbTag::JFEffectiveDecayLength(const xAOD::BTagging* bjet, bool onlyVtx, double& error){
-  double decaylength = -1.;
-  error = -1.;
-
-  if(!IsValidJF(bjet, onlyVtx)) return decaylength;
-
-  auto jfvertices = GetJFVertices(bjet);
-  std::vector<float> fittedPosition;
-  std::vector<float> fittedCov;
-  fittedPosition = GetJFfittedPosition(bjet, fittedCov);
-
-  // number of vtx (with at least 2 tracks)
-  int nVtx = 0;
-  bjet->taggerInfo(nVtx, xAOD::JetFitter_nVTX);
-
-  // loop over vertices
-  double sum_l = 0.;
-  double sum_inverror2 = 0.;
-  for(unsigned int ivtx = 0; ivtx < jfvertices.size(); ivtx++){
-    auto JFVtx = jfvertices[ivtx];
-
-    // reject negative vtx
-    if(fittedPosition[5+ivtx] < 0) continue;
-
-    double l = fittedPosition[5+ivtx];
-    double error2 = fittedCov[5+ivtx];
-
-    if(error2 == 0.){
-      ATH_MSG_WARNING("Get 0 error for a fitted vtx decay length");
-      continue;
-    }
-
-    if(!onlyVtx){
-      sum_l += (l/error2);
-      sum_inverror2 += (1./error2);
-    }
-    else{
-      if( (nVtx > 0 && JFVtx->track_links().size() > 1) || (nVtx == 0) ){
-        sum_l += (l/error2);
-        sum_inverror2 += (1./error2);
-      }
-    }
-  }
-
-  // get result
-  decaylength = sum_l/sum_inverror2;
-  error = 1./TMath::Sqrt(sum_inverror2);
-
-  return decaylength;
-}
-
-// calculate all eigen variation of vtx position
-std::vector<Amg::Vector3D> ExKtbbTag::GetVtxEigenVariation(Amg::Vector3D vtxPosition, AmgSymMatrix3D vtxCovMatrix){
-  std::vector<Amg::Vector3D> output;
-
-  // solve eigen system
-  Eigen::SelfAdjointEigenSolver<AmgSymMatrix3D> EigenSolver(vtxCovMatrix);
-  if(EigenSolver.info() != Eigen::Success){
-    ATH_MSG_WARNING("Input matrix is not Hermitian, which should be impossible for covariant matrix!");
-    return output;
-  }
-
-  auto EigenValues = EigenSolver.eigenvalues();
-  auto EigenVectors = EigenSolver.eigenvectors();
-
-  // get variation
-  for(unsigned int index = 0; index < 3; index++){
-    Amg::Vector3D vtxPositionVariation_Up;
-    vtxPositionVariation_Up(0) = vtxPosition(0) + TMath::Sqrt(EigenValues(index)) * EigenVectors(0, index);
-    vtxPositionVariation_Up(1) = vtxPosition(1) + TMath::Sqrt(EigenValues(index)) * EigenVectors(1, index);
-    vtxPositionVariation_Up(2) = vtxPosition(2) + TMath::Sqrt(EigenValues(index)) * EigenVectors(2, index);
-
-    Amg::Vector3D vtxPositionVariation_Down;
-    vtxPositionVariation_Down(0) = vtxPosition(0) - TMath::Sqrt(EigenValues(index)) * EigenVectors(0, index);
-    vtxPositionVariation_Down(1) = vtxPosition(1) - TMath::Sqrt(EigenValues(index)) * EigenVectors(1, index);
-    vtxPositionVariation_Down(2) = vtxPosition(2) - TMath::Sqrt(EigenValues(index)) * EigenVectors(2, index);
-
-    output.push_back(vtxPositionVariation_Up);
-    output.push_back(vtxPositionVariation_Down);
-  }          
-
-  return output;
-}
-
-double ExKtbbTag::GeneralDRSignificance3D(Amg::Vector3D vtx1, AmgSymMatrix3D vtx1_CovMatrix, Amg::Vector3D vtx2, AmgSymMatrix3D vtx2_CovMatrix, double& dR3D, double& dR3D_error){
-  dR3D = -1.;
-  dR3D_error = -1.;
-
-  std::vector<Amg::Vector3D> vtx1_variations = GetVtxEigenVariation(vtx1, vtx1_CovMatrix);
-  std::vector<Amg::Vector3D> vtx2_variations = GetVtxEigenVariation(vtx2, vtx2_CovMatrix);
-
-  auto function_GetdR3D = [](Amg::Vector3D input1, Amg::Vector3D input2)->double{
-    return TMath::Sqrt((input1 - input2).dot(input1 - input2));
-  };
-
-  dR3D = function_GetdR3D(vtx1, vtx2);
-
-  double sumerror_vtx1 = 0.;
-  double sumerror_vtx2 = 0.;
-  for(unsigned int index = 0; index < 3; index++){
-    double error_vtx1 = std::max(fabs(function_GetdR3D(vtx1_variations[2*index], vtx2) - dR3D), fabs(function_GetdR3D(vtx1_variations[2*index+1], vtx2) - dR3D));
-    sumerror_vtx1 += (error_vtx1 * error_vtx1);
-
-    double error_vtx2 = std::max(fabs(function_GetdR3D(vtx1, vtx2_variations[2*index]) - dR3D), fabs(function_GetdR3D(vtx1, vtx2_variations[2*index+1]) - dR3D));
-    sumerror_vtx2 += (error_vtx2 * error_vtx2);
-  }
-
-  double sumerror = sumerror_vtx1 + sumerror_vtx2;
-  dR3D_error = TMath::Sqrt(sumerror);
-
-  double significance = 0.;
-  if(dR3D_error == 0.){
-    ATH_MSG_WARNING("Zero error obtained in GeneralDRSignificance3D, which is very unlikely.");
-    significance = 999.;
-  }
-  else{
-    significance = dR3D/dR3D_error;
-  }
-
-  significance = LimitUpperBound(significance, 50, 100);
-  return significance;
-}
-
-std::string ExKtbbTag::GetPtBin(const xAOD::Jet* jetToTag){
-  double pt = jetToTag->pt()/1000.;    // MeV -> GeV
-  
-  if(pt < m_ptbinlist.front()){ // underflow bin -- first pt bin
-    pt = m_ptbinlist.front() + 1;
-  }
-
-  if(pt >= m_ptbinlist.back()){ // overflow bin -- last pt bin
-    pt = m_ptbinlist.back() - 1;
-  }
-
-  for(unsigned int index = 0; index < m_ptbinlist.size()-1; index++){
-    double ptmin = m_ptbinlist[index];
-    double ptmax = m_ptbinlist[index+1];
-
-    if( (pt >= ptmin) && (pt < ptmax) ) return TString::Format("PtBin%i", int(index)).Data();
-  }
-
-  ATH_MSG_WARNING("How can you reach this line?!");
-  return "PtBin-1";
-}
-
-bool ExKtbbTag::InitTMVAVariables(std::string BDTMode){
-  m_tmvaVariables.clear();
-
-  // common variables
-  m_tmvaVariables["JetPt"] = new float(0.);
-  m_tmvaVariables["JetEta"] = new float(0.);
-
-  if(BDTMode == "MV2Only"){
-    m_tmvaVariables["ExKt_DoubleMV2c20"] = new float(0.);
-    m_tmvaVariables["ExKt_SingleMV2c20"] = new float(0.);
-  }
-  else if(BDTMode == "MV2andJFDRSig"){
-    m_tmvaVariables["ExKt_DoubleMV2c20"] = new float(0.);
-    m_tmvaVariables["ExKt_SingleMV2c20"] = new float(0.);
-    m_tmvaVariables["ExKt_JFDRSignificance"] = new float(0.);
-  }
-  else if(BDTMode == "MV2andTopos"){
-    m_tmvaVariables["ExKt_DoubleMV2c20"] = new float(0.);
-    m_tmvaVariables["ExKt_SingleMV2c20"] = new float(0.);
-    m_tmvaVariables["ExKt_SV1CombMass_ValidDualSV1 := (ExKt_ValidDualSV1 ? ExKt_SV1CombMass : -1.)"] = new float(0.);
-    m_tmvaVariables["ExKt_JFNtrksDiff_ValidDualJF := (ExKt_ValidDualJF ? ExKt_JFNtrksDiff : -20.)"] = new float(0.);
-    m_tmvaVariables["ExKt_JFDRSignificance"] = new float(0.);
-    m_tmvaVariables["ExKt_JFDLSignificance"] = new float(0.);
-  }
-  else{
-    ATH_MSG_ERROR("#BTAG# Undefined BDTMode " << BDTMode);
-    return false;
-  }
-
-  return true;
-}
-
-bool ExKtbbTag::FillTMVAVariables(std::string BDTMode, const xAOD::Jet* jetToTag, const xAOD::BTagging* BTag){
-  // common variables
-  // unit in GeV
-
-  *(m_tmvaVariables["JetPt"]) = jetToTag->pt()/1000.; // MeV->GeV
-  *(m_tmvaVariables["JetEta"]) = jetToTag->eta();
-
-  if(BDTMode == "MV2Only"){
-    double DoubleMV2c20;
-    if(!BTag->variable<double>(m_taggerName, "DoubleMV2c20", DoubleMV2c20)) ATH_MSG_WARNING("#BTAG# Unable to get \"DoubleMV2c20\"");
-    double SingleMV2c20;
-    if(!BTag->variable<double>(m_taggerName, "SingleMV2c20", SingleMV2c20)) ATH_MSG_WARNING("#BTAG# Unable to get \"SingleMV2c20\"");
-
-    *(m_tmvaVariables["ExKt_DoubleMV2c20"]) = DoubleMV2c20;
-    *(m_tmvaVariables["ExKt_SingleMV2c20"]) = SingleMV2c20;
-  }
-  else if(BDTMode == "MV2andJFDRSig"){
-    double DoubleMV2c20;
-    if(!BTag->variable<double>(m_taggerName, "DoubleMV2c20", DoubleMV2c20)) ATH_MSG_WARNING("#BTAG# Unable to get \"DoubleMV2c20\"");
-    double SingleMV2c20;
-    if(!BTag->variable<double>(m_taggerName, "SingleMV2c20", SingleMV2c20)) ATH_MSG_WARNING("#BTAG# Unable to get \"SingleMV2c20\"");
-    double JFDRSignificance;
-    if(!BTag->variable<double>(m_taggerName, "JFDRSignificance", JFDRSignificance)) ATH_MSG_WARNING("#BTAG# Unable to get \"JFDRSignificance\"");
-
-    *(m_tmvaVariables["ExKt_DoubleMV2c20"]) = DoubleMV2c20;
-    *(m_tmvaVariables["ExKt_SingleMV2c20"]) = SingleMV2c20;
-    *(m_tmvaVariables["ExKt_JFDRSignificance"]) = JFDRSignificance;
-  }
-  else if(BDTMode == "MV2andTopos"){
-    double DoubleMV2c20;
-    if(!BTag->variable<double>(m_taggerName, "DoubleMV2c20", DoubleMV2c20)) ATH_MSG_WARNING("#BTAG# Unable to get \"DoubleMV2c20\"");
-    double SingleMV2c20;
-    if(!BTag->variable<double>(m_taggerName, "SingleMV2c20", SingleMV2c20)) ATH_MSG_WARNING("#BTAG# Unable to get \"SingleMV2c20\"");
-    double SV1CombMass;
-    if(!BTag->variable<double>(m_taggerName, "SV1CombMass", SV1CombMass)) ATH_MSG_WARNING("#BTAG# Unable to get \"SV1CombMass\"");
-    int JFNtrksDiff = 0;
-    if(!BTag->variable<int>(m_taggerName, "JFNtrksDiff", JFNtrksDiff)) ATH_MSG_WARNING("#BTAG# Unable to get\"JFNtrksDiff\"");
-    double JFDRSignificance;
-    if(!BTag->variable<double>(m_taggerName, "JFDRSignificance", JFDRSignificance)) ATH_MSG_WARNING("#BTAG# Unable to get \"JFDRSignificance\"");
-    double JFDLSignificance;
-    if(!BTag->variable<double>(m_taggerName, "JFDLSignificance", JFDLSignificance)) ATH_MSG_WARNING("#BTAG# Unable to get \"JFDLSignificance\"");
-
-    *(m_tmvaVariables["ExKt_DoubleMV2c20"]) = DoubleMV2c20;
-    *(m_tmvaVariables["ExKt_SingleMV2c20"]) = SingleMV2c20;
-    *(m_tmvaVariables["ExKt_SV1CombMass_ValidDualSV1 := (ExKt_ValidDualSV1 ? ExKt_SV1CombMass : -1.)"]) = (SV1CombMass < 0. ? -1 : SV1CombMass/1000.); // MeV->GeV
-    *(m_tmvaVariables["ExKt_JFNtrksDiff_ValidDualJF := (ExKt_ValidDualJF ? ExKt_JFNtrksDiff : -20.)"]) = JFNtrksDiff*1.0; // double->int
-    *(m_tmvaVariables["ExKt_JFDRSignificance"]) = JFDRSignificance;
-    *(m_tmvaVariables["ExKt_JFDLSignificance"]) = JFDLSignificance;
-  }
-  else{
-    ATH_MSG_ERROR("#BTAG# Undefined BDTMode " << BDTMode);
-    return false;
-  }
-
-  return true;
-}
-
-bool ExKtbbTag::BundleTMVAVariables(std::string BDTMode, TMVA::Reader* tmvaReader){
-  if(!tmvaReader){
-    ATH_MSG_ERROR("#BTAG# Null ptr to tmvaReader!");
-    return false;
-  }
-
-  // Cannot do this simple trick, as TMVA reuqires the order to be exactly same!!
-  // Stupid!
-  // for(auto iter = m_tmvaVariables.begin(); iter != m_tmvaVariables.end(); iter++){
-  //   tmvaReader->AddVariable(iter->first, iter->second);
-  // }
-
-  std::vector<std::string> OrderedInputs;
-
-  if(BDTMode == "MV2Only"){
-    OrderedInputs = {
-      "JetPt",
-      "JetEta",
-      "ExKt_DoubleMV2c20",
-      "ExKt_SingleMV2c20",
-    };
-  }
-  else if(BDTMode == "MV2andJFDRSig"){
-    OrderedInputs = {
-      "JetPt",
-      "JetEta",
-      "ExKt_DoubleMV2c20",
-      "ExKt_SingleMV2c20",
-      "ExKt_JFDRSignificance",
-    };
-  }
-  else if(BDTMode == "MV2andTopos"){
-    OrderedInputs = {
-      "JetPt",
-      "JetEta",
-      "ExKt_DoubleMV2c20",
-      "ExKt_SingleMV2c20",
-      "ExKt_SV1CombMass_ValidDualSV1 := (ExKt_ValidDualSV1 ? ExKt_SV1CombMass : -1.)",
-      "ExKt_JFNtrksDiff_ValidDualJF := (ExKt_ValidDualJF ? ExKt_JFNtrksDiff : -20.)",
-      "ExKt_JFDRSignificance",
-      "ExKt_JFDLSignificance",
-    };
-  }
-  else{
-    ATH_MSG_ERROR("#BTAG# Undefined BDTMode " << BDTMode);
-    return false;
-  }
-
-  for(auto iter = OrderedInputs.begin(); iter != OrderedInputs.end(); iter++){
-    std::string key = *iter;
-    if(m_tmvaVariables.find(key) == m_tmvaVariables.end()){
-      ATH_MSG_WARNING("#BTAG# Variable " << key << " not initialized! This is not supposed to happen. Initializing it here.");
-      m_tmvaVariables[key] = new float(0.);
-    }
-
-    tmvaReader->AddVariable(key, m_tmvaVariables[key]);
-  }
-
-  return true;
-}
-
-}//end namespace
-
-
-
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/src/ExKtbbTagTool.cxx b/PhysicsAnalysis/JetTagging/JetTagTools/src/ExKtbbTagTool.cxx
deleted file mode 100644
index 65b35e08c914635c72adee6cdc51b1ee2f1be7b2..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagTools/src/ExKtbbTagTool.cxx
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#include "JetTagTools/ExKtbbTagTool.h"
-
-#include "xAODJet/JetContainer.h"
-#include "xAODJet/JetContainerInfo.h"
-#include "JetEDM/IConstituentUserInfo.h"
-#include "JetEDM/FastJetUtils.h"
-
-namespace Analysis{
-
-ExKtbbTagTool::ExKtbbTagTool(std::string myname):
-  JetModifierBase(myname),
-  m_JetAlgorithm(""),
-  m_JetRadius(0.),
-  m_PtMin(0.),
-  m_ExclusiveNJets(0),
-  m_InputJetContainerName(""),
-  m_SubjetRecorderTool("SubjetRecorderTool"),
-  m_SubjetLabel(""),
-  m_SubjetContainerName(""),
-  m_SubjetAlgorithm_BTAG(""),
-  m_SubjetRadius_BTAG(0.)
-{
-  declareProperty("JetAlgorithm", m_JetAlgorithm);
-  declareProperty("JetRadius", m_JetRadius);
-  declareProperty("PtMin", m_PtMin);
-  declareProperty("ExclusiveNJets", m_ExclusiveNJets);
-
-  declareProperty("InputJetContainerName", m_InputJetContainerName);
-  declareProperty("SubjetRecorder", m_SubjetRecorderTool);
-  declareProperty("SubjetLabel", m_SubjetLabel);
-  declareProperty("SubjetContainerName", m_SubjetContainerName);
-  declareProperty("SubjetAlgorithm_BTAG", m_SubjetAlgorithm_BTAG);
-  declareProperty("SubjetRadius_BTAG", m_SubjetRadius_BTAG);
-}
-
-StatusCode ExKtbbTagTool::initialize(){
-  if(m_SubjetRecorderTool.retrieve().isFailure()){
-    ATH_MSG_ERROR("#BTAG# Unable to retrieve SubjetRecorder Tool");
-    return StatusCode::FAILURE;
-  }
-  else{
-    ATH_MSG_INFO("#BTAG# Successfully retrieve SubjetRecorder Tool");
-  }
-
-  return StatusCode::SUCCESS;
-}
-
-int ExKtbbTagTool::modifyJet(xAOD::Jet& jet) const {
-
-  // run subjet finding //
-
-  xAOD::JetAlgorithmType::ID ialg = xAOD::JetAlgorithmType::algId(m_JetAlgorithm);
-  fastjet::JetAlgorithm fjalg = xAOD::JetAlgorithmType::fastJetDef(ialg);
-
-  JetSubStructureUtils::SubjetFinder subjetFinder(fjalg, m_JetRadius, m_PtMin, m_ExclusiveNJets);
-  std::vector<fastjet::PseudoJet> constituents_pj = constituentPseudoJets(jet);
-  // std::vector<fastjet::PseudoJet> constituents = jet::JetConstituentFiller::constituentPseudoJets(jet);
-  fastjet::PseudoJet sum_constituents_pj = fastjet::join(constituents_pj);
-  std::vector<fastjet::PseudoJet> subjets_pj = subjetFinder.result(sum_constituents_pj);
-
-  // record subjets //
-
-  auto subjets_nonconst = m_SubjetRecorderTool->recordSubjets(subjets_pj, jet);   // since we are using customized constituent pseudo-jet, constituents information will not be stored here
-
-  // store the subjet container name and index //
-
-  // We do this since ElementLink to the subjet could be broken after the deep-copy in b-tagging part. This was not a problem before 20.7. The reason behind it is still unknown.
-  // Assuming the subjet container order is un-changed during b-tagging deep-copy, which SHOULD be valid.
-
-  std::vector<const xAOD::Jet*> ExKtSubJets;
-  if(!jet.getAssociatedObjects<xAOD::Jet>(m_SubjetLabel.c_str(), ExKtSubJets)){
-    ATH_MSG_WARNING("Unable to fetch subjet collection in ExKtbbTagTool::modifyJet : " << m_SubjetLabel.c_str());
-    ATH_MSG_WARNING("Nothing to be done for this problem. But you might crash very soon.");
-  }
-
-  jet.auxdata<std::string>(m_SubjetLabel + "_ContainerName") = m_SubjetContainerName;
-
-  std::vector<int> SubjetIndexVector;
-  for(auto subjet : ExKtSubJets){
-    SubjetIndexVector.push_back(subjet->index());
-  }
-  jet.auxdata<std::vector<int> >(m_SubjetLabel + "_IndexList") = SubjetIndexVector;
-
-  // overwrite something / store constituents //
-
-  for(unsigned int index_subjet = 0; index_subjet < subjets_nonconst.size(); index_subjet++){
-    auto subjet_nonconst = subjets_nonconst[index_subjet];
-    auto subjet_pj = subjets_pj[index_subjet];
-
-    // jet finding 
-    subjet_nonconst->setAlgorithmType(xAOD::JetAlgorithmType::algId(m_SubjetAlgorithm_BTAG));
-    subjet_nonconst->setSizeParameter(m_SubjetRadius_BTAG);
-
-    // jet input type
-    subjet_nonconst->setInputType(jet.getInputType());
-
-    // setup constituents
-
-    // check if constituents has been filled before
-    if(subjet_nonconst->numConstituents() == 0){
-
-      for(auto pj_constituent : subjet_pj.constituents()){
-        int index_constituent = pj_constituent.user_index();  // index in parent jet constituent vector
-
-        auto el_constituent = jet.constituentLinks()[index_constituent];
-
-        if(!el_constituent.isValid()){
-          ATH_MSG_WARNING("#BTAG# Element link to jet constituent is inValid! It will still be stored anyway ... ");
-        }
-
-        subjet_nonconst->addConstituent(el_constituent, 1.0);
-      }
-
-    }
-    else{
-      ATH_MSG_WARNING("#BTAG# Constituent link to subjet is already built, which is NOT expected!");
-    }
-
-    // set correct constituent signal state
-    subjet_nonconst->setConstituentsSignalState(jet.getConstituentsSignalState());
-
-    // add parent jet information, in case the "parent" link is broken
-    auto el_parent = subjet_nonconst->auxdata<ElementLink<xAOD::JetContainer> >("Parent");
-    if(!el_parent.isValid()){
-      ATH_MSG_WARNING("#BTAG# Element link from ExKtSubjet to parent jet is invalid! No backup parent link information will be stored.");
-    }
-    else{
-      subjet_nonconst->auxdata<std::string>("Parent_ContainerName") = m_InputJetContainerName;
-      subjet_nonconst->auxdata<int>("Parent_Index") = jet.index();
-    }
-
-  }
-
-  // for(auto subjet : ExKtSubJets){
-  //   if(!subjet){
-  //     std::cout << "Empty ptr to subjet in ExKtbbTagTool::modifyJet at position 2!" << std::endl;
-  //   }
-  // }
-
-  return 0;
-}
-
-std::vector<fastjet::PseudoJet> ExKtbbTagTool::constituentPseudoJets(xAOD::Jet& jet) const{
-  // code adapted from JetConstituentFiller.cxx
-  // Cannot use JetConstituentFiller utils due to code crash from unknown reason
-  // It seems the fastjet link is broken after a deep copy of parent jet
-  // but anyway ... 
-
-  std::vector<fastjet::PseudoJet> constituents;
-
-  xAOD::JetConstituentVector constituents_tmp = jet.getConstituents();
-  xAOD::JetConstituentVector::iterator it = constituents_tmp.begin();
-  xAOD::JetConstituentVector::iterator itE = constituents_tmp.end();
-
-  int index = 0;
-  for( ; it !=itE; ++it){
-    fastjet::PseudoJet constituent_pj = fastjet::PseudoJet( it->Px(), it->Py(), it->Pz(), it->E() );    // this is guaranteed to be the scale used in jet finding
-    constituent_pj.set_user_index(index);        // each constituent_pj will store index in parent jet constituent ve tor
-    constituents.push_back( constituent_pj );
-
-    index++;
-  }
-
-  return constituents;
-}
-
-}
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/src/IPTag.cxx b/PhysicsAnalysis/JetTagging/JetTagTools/src/IPTag.cxx
index 5579c147db251f152939bc9bab159eb86948fca4..0819e0e040970e1844318e93ef7f3dabee2f6588 100644
--- a/PhysicsAnalysis/JetTagging/JetTagTools/src/IPTag.cxx
+++ b/PhysicsAnalysis/JetTagging/JetTagTools/src/IPTag.cxx
@@ -25,7 +25,6 @@
 #include "TrkVertexFitterInterfaces/ITrackToVertexIPEstimator.h"
 #include "ParticleJetTools/JetFlavourInfo.h"
 #include "InDetTrackSelectionTool/IInDetTrackSelectionTool.h"
-#include "TrackVertexAssociationTool/ITrackVertexAssociationTool.h"
 #include "TH1.h"
 #include <cmath>
 #include <sstream>
@@ -92,8 +91,7 @@ namespace Analysis {
       m_SVForIPTool("Analysis::SVForIPTool", this),
       m_trackGradeFactory("Analysis::BasicTrackGradeFactory", this),
       m_trackToVertexIPEstimator(this),
-      m_InDetTrackSelectorTool("InDet::InDetTrackSelectionTool", this),
-      m_TightTrackVertexAssociationTool("CP::TrackVertexAssociationTool", this)
+      m_InDetTrackSelectorTool("InDet::InDetTrackSelectionTool", this)
   {
     // global configuration:
     declareProperty("Runmodus"      , m_runModus);
@@ -147,7 +145,6 @@ namespace Analysis {
     declareProperty("trackGradeFactory"         , m_trackGradeFactory              );
     declareProperty("TrackToVertexIPEstimator"  , m_trackToVertexIPEstimator       );
     declareProperty("InDetTrackSelectionTool"   , m_InDetTrackSelectorTool         ); //
-    declareProperty("TrackVertexAssociationTool", m_TightTrackVertexAssociationTool); //
   }
 
   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -351,16 +348,9 @@ namespace Analysis {
       } else {
 	ATH_MSG_DEBUG("#BTAG# Retrieved tool " <<  m_InDetTrackSelectorTool);
       }
-      if ( m_TightTrackVertexAssociationTool.retrieve().isFailure() )  {
-	ATH_MSG_FATAL("#BTAG# Failed to retrieve tool " <<  m_TightTrackVertexAssociationTool);
-	return StatusCode::FAILURE;
-      } else {
-	ATH_MSG_DEBUG("#BTAG# Retrieved tool " <<  m_TightTrackVertexAssociationTool);
-      }
     }
     else {
       m_InDetTrackSelectorTool.disable();
-      m_TightTrackVertexAssociationTool.disable();
     }
 
     return StatusCode::SUCCESS;
@@ -448,8 +438,7 @@ namespace Analysis {
     int nbTrak = 0;
     std::vector< ElementLink< xAOD::TrackParticleContainer > > associationLinks = 
       BTag.auxdata<std::vector<ElementLink<xAOD::TrackParticleContainer> > >(m_trackAssociationName);
-    double sumTrkpT = 0; unsigned ntrk=0;
-    TLorentzVector pseudoTrackJet(0,0,0,0);
+    double sumTrkpT = 0;
     if( associationLinks.size() == 0 ) {
         ATH_MSG_VERBOSE("#BTAG#  Could not find tracks associated with BTagging object as " << m_trackAssociationName);
     } else {
@@ -460,15 +449,6 @@ namespace Analysis {
       for( trkIter = associationLinks.begin(); trkIter != associationLinks.end() ; ++trkIter ) {
 	const xAOD::TrackParticle* aTemp = **trkIter;
 	
-	if (m_impactParameterView=="3D") { 
-	  if (m_InDetTrackSelectorTool->accept(*aTemp, &priVtx) ) {
-	    if (m_TightTrackVertexAssociationTool->isCompatible(*aTemp, priVtx)) {
-	      TLorentzVector tmpTrack(0,0,0,0);
-	      tmpTrack.SetPtEtaPhiM(  aTemp->pt(), aTemp->eta(), aTemp->phi(),0);
-	      pseudoTrackJet+=tmpTrack; ntrk++;
-	    }
-	  }
-	}
 
 	if (m_trackSelectorTool->selectTrack(priVtx.position(),
                                              aTemp))
@@ -503,14 +483,6 @@ namespace Analysis {
         }
       }
     }
-    // temporary: storing these variables (which aren't IP3D-specific) ought to be moved to a separate Tool
-    if (m_xAODBaseName == "IP3D") { 
-      BTag.auxdata<unsigned>("trkSum_ntrk") = ntrk;
-      BTag.auxdata<float>("trkSum_SPt") = sumTrkpT;
-      BTag.auxdata<float>("trkSum_VPt") = pseudoTrackJet.Pt();
-      BTag.auxdata<float>("trkSum_VEta") = (pseudoTrackJet.Pt() != 0) ? pseudoTrackJet.Eta() : 1000;
-    }
-
 
     ATH_MSG_VERBOSE("#BTAG# #tracks = " << nbTrak);
     ATH_MSG_VERBOSE("#BTAG# the z of the primary = " << priVtx.position().z());
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/src/MultivariateTagManager.cxx b/PhysicsAnalysis/JetTagging/JetTagTools/src/MultivariateTagManager.cxx
index dd4dc2013de363394891af7fa34134528922b238..618b3c4677a6f7b2f38b0bab681163161d85d386 100644
--- a/PhysicsAnalysis/JetTagging/JetTagTools/src/MultivariateTagManager.cxx
+++ b/PhysicsAnalysis/JetTagging/JetTagTools/src/MultivariateTagManager.cxx
@@ -120,7 +120,6 @@ namespace Analysis {
     fill_jetfitter(inputs, BTag);    // fill JetFitter variables
     fill_sv0(priVtx, inputs, BTag);          // fill sv0 variables
     fill_sv1(inputs, BTag);          // fill sv1 variables
-    fill_mv2cl100(inputs, BTag); // fill MV2cl100 variables
     fill_trkSum(inputs,BTag);
     fill_softmuon(inputs,BTag);
 
@@ -565,167 +564,6 @@ namespace Analysis {
     inputs[btagvar::SV1_DISTMATLAY]    = sv1_distmatlay;
   }
 
-  void MultivariateTagManager::fill_mv2cl100(var_map& inputs, xAOD::BTagging& BTag) const {
-    // Generating MV2cl100 variables
-    std::vector< ElementLink< xAOD::TrackParticleContainer > > assocTracks;
-    try{
-      assocTracks = BTag.auxdata<std::vector<ElementLink<xAOD::TrackParticleContainer> > >("BTagTrackToJetAssociator");
-    } catch (std::exception& e) {
-      ATH_MSG_WARNING("problem loading associated tracks,"
-          "skipping this jet");
-      return;
-    }
-
-    std::vector<ElementLink<xAOD::BTagVertexContainer> > jfvertices;
-    try {
-      jfvertices =  BTag.auxdata<std::vector<ElementLink<xAOD::BTagVertexContainer> > >("JetFitter_JFvertices");
-    } catch (std::exception& e) {
-      ATH_MSG_WARNING("problem loading JF vertices,"
-          " skipping this jet");
-    }
-
-    std::vector<float> fittedPosition = BTag.auxdata<std::vector<float> >("JetFitter_fittedPosition");
-
-    //MV2cl100 default values
-    int nTrk_vtx1 = INT_MISSING;
-    float mass_first_vtx = NAN;
-    float e_first_vtx = NAN;
-    float e_frac_vtx1 = NAN;
-    float closestVtx_L3D = NAN;
-    float JF_Lxy1 = NAN;
-    float vtx1_MaxTrkRapidity_jf_path = NAN;
-    float vtx1_AvgTrkRapidity_jf_path = NAN;
-    float vtx1_MinTrkRapidity_jf_path = NAN;
-    float MaxTrkRapidity_jf_path = NAN;
-    float MinTrkRapidity_jf_path = NAN;
-    float AvgTrkRapidity_jf_path = NAN;
-
-    if (assocTracks.size() > 0 && fittedPosition.size() > 0) {
-
-      ATH_MSG_VERBOSE("#BTAG# MV2: calculating MV2cl100 inputs.");
-
-      float jf_phi = fittedPosition[3];
-      float jf_theta = fittedPosition[4];
-      TVector3 flightDir(0,0,0);
-      flightDir.SetMagThetaPhi(1., jf_theta, jf_phi ); //flight directon of JF decay chain
-
-      //loop over position of JF vertices, find index of secondary vertex
-      int secondary_vertex_index = INT_MISSING;
-      for (unsigned int jfv = 0; jfv < jfvertices.size(); jfv++) {
-
-  float tmpL3D = fittedPosition[jfv + 5];
-
-
-  if (tmpL3D > 0 && (std::isnan(closestVtx_L3D) || closestVtx_L3D > tmpL3D) ){
-
-    closestVtx_L3D = tmpL3D;
-    secondary_vertex_index = jfv;
-  }
-      }
-
-      //loop over tracks, collect total 4 momentum, and 4 momentum of secondary vertex, calculate pseudo rapidity of track
-      TLorentzVector tracksTot4Mom(0,0,0,0);
-      TLorentzVector tracksTot4Mom_firstVtx(0,0,0,0);
-      float sumTrackRapidity = 0;
-      float vtx1_sumTrackRapidity = 0;
-      int vtx1_first_track =0;
-      float track_mass = 139.570;
-      int trkIndex=0;
-      //track loop
-      for(auto trkIter = assocTracks.begin(); trkIter != assocTracks.end(); ++trkIter) {
-         const xAOD::TrackParticle* aTemp = **trkIter;
-         uint8_t getInt(0);
-         aTemp->summaryValue(getInt, xAOD::numberOfPixelHits);
-         int nSi = getInt;
-         aTemp->summaryValue(getInt, xAOD::numberOfSCTHits);
-         nSi += getInt;
-         if (nSi < 2) continue;
-
-  TLorentzVector trk;
-  trk.SetPtEtaPhiM(aTemp->pt(), aTemp->eta(), aTemp->phi(), track_mass);
-  tracksTot4Mom += trk;
-
-  TVector3 trkvector(0,0,0);
-  trkvector = trk.Vect();
-
-  float trackRapidity = (trkvector.Mag2()>0 ? tan( 0.5*trkvector.Angle(flightDir) ) : 0); // steps to protect against log(0)
-
-  trackRapidity = (trackRapidity < 0.000001 ? (-1)*log(0.000001) : (-1)*log(trackRapidity) ); // value of 0.000001 should provide enough margin for typical values of trackRapidity
-
-
-  sumTrackRapidity += trackRapidity;
-
-  if(trkIndex==0){
-    MaxTrkRapidity_jf_path = trackRapidity;
-    MinTrkRapidity_jf_path = trackRapidity;
-  }else{
-    MaxTrkRapidity_jf_path = trackRapidity > MaxTrkRapidity_jf_path ? trackRapidity : MaxTrkRapidity_jf_path;
-    MinTrkRapidity_jf_path = trackRapidity < MinTrkRapidity_jf_path ? trackRapidity : MinTrkRapidity_jf_path;
-  }
-
-  if(secondary_vertex_index >= 0){
-    //get track links to secondary vertex
-    const xAOD::BTagVertex *tmpVertex = *(jfvertices.at(secondary_vertex_index));
-    const std::vector< ElementLink<xAOD::TrackParticleContainer> > tmpVect = tmpVertex->track_links();
-    //check association to JF vertex
-    int particleInCollection = 0;
-
-    for (unsigned int iT = 0; iT < tmpVect.size(); iT++) {
-      if (aTemp == *(tmpVect.at(iT))) particleInCollection=1;
-    }
-      if (particleInCollection){
-
-        if(nTrk_vtx1 < 0){
-          nTrk_vtx1 = 0;
-        }
-        nTrk_vtx1 += 1;
-
-        tracksTot4Mom_firstVtx += trk;
-        vtx1_sumTrackRapidity += trackRapidity;
-
-        if(!vtx1_first_track){
-          vtx1_MaxTrkRapidity_jf_path = trackRapidity;
-          vtx1_MinTrkRapidity_jf_path = trackRapidity;
-          vtx1_first_track=1;
-        }else{
-          vtx1_MaxTrkRapidity_jf_path = trackRapidity > vtx1_MaxTrkRapidity_jf_path ? trackRapidity : vtx1_MaxTrkRapidity_jf_path;
-          vtx1_MinTrkRapidity_jf_path = trackRapidity < vtx1_MinTrkRapidity_jf_path ? trackRapidity : vtx1_MinTrkRapidity_jf_path;
-        }
-
-      }
-  }
-
-  trkIndex++;
-      } //end of trk loop
-
-        // assign the remaining MV2cl100 variables
-      AvgTrkRapidity_jf_path = trkIndex > 0 ? sumTrackRapidity/trkIndex : 0;
-
-    if(nTrk_vtx1 > 0){
-      JF_Lxy1 = closestVtx_L3D*sin(jf_theta);
-      mass_first_vtx = tracksTot4Mom_firstVtx.M();
-      e_first_vtx = tracksTot4Mom_firstVtx.E();
-      e_frac_vtx1 = e_first_vtx/tracksTot4Mom.E();
-      vtx1_AvgTrkRapidity_jf_path = vtx1_sumTrackRapidity/nTrk_vtx1;
-    }
-
-    } // end of if (assocTracks.size() > 0 && fittedPosition.size() > 0
-
-    inputs[btagvar::JF_NTRK_VTX1]           = nan_if_placeholder(nTrk_vtx1);
-    inputs[btagvar::JF_MASS_VTX1 ]          = mass_first_vtx ;
-    inputs[btagvar::JF_E_VTX1 ]             = e_first_vtx ;
-    inputs[btagvar::JF_E_FRAC_VTX1 ]        = e_frac_vtx1;
-    inputs[btagvar::JF_L3D_VTX1 ]           = closestVtx_L3D ;
-    inputs[btagvar::JF_Lxy_VTX1 ]           = JF_Lxy1 ;
-    inputs[btagvar::JF_RAPIDITY_VTX1_MAX ]  = vtx1_MaxTrkRapidity_jf_path;
-    inputs[btagvar::JF_RAPIDITY_VTX1_AVG ]  = vtx1_AvgTrkRapidity_jf_path;
-    inputs[btagvar::JF_RAPIDITY_VTX1_MIN ]  = vtx1_MinTrkRapidity_jf_path;
-    inputs[btagvar::JF_RAPIDITY_MAX ]       = MaxTrkRapidity_jf_path;
-    inputs[btagvar::JF_RAPIDITY_MIN ]       = MinTrkRapidity_jf_path;
-    inputs[btagvar::JF_RAPIDITY_AVG ]       = AvgTrkRapidity_jf_path;
-
-  } // end of fill_mv2cl100
-
   void MultivariateTagManager::fill_arbitrary_aux_data(
     var_map& inputs, xAOD::BTagging& BTag) const {
 
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/src/RNNIPTag.cxx b/PhysicsAnalysis/JetTagging/JetTagTools/src/RNNIPTag.cxx
deleted file mode 100644
index f093904bd03e57df9de854cf357b47220e58d9ea..0000000000000000000000000000000000000000
--- a/PhysicsAnalysis/JetTagging/JetTagTools/src/RNNIPTag.cxx
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-*/
-
-#include "JetTagTools/RNNIPTag.h"
-#include "lwtnn/LightweightNeuralNetwork.hh"
-#include "lwtnn/parse_json.hh"
-#include "lwtnn/Exceptions.hh"
-
-#include "JetTagTools/TrackSelector.h"
-#include "JetTagTools/GradedTrack.h"
-#include "JetTagTools/SVForIPTool.h"
-#include "JetTagTools/ITrackGradeFactory.h"
-
-#include "JetTagInfo/TrackGrade.h"
-#include "JetTagInfo/TrackGradesDefinition.h"
-
-#include "TrkVertexFitterInterfaces/ITrackToVertexIPEstimator.h"
-
-#include "xAODTracking/TrackParticle.h"
-#include "xAODTracking/TrackParticleContainer.h"
-
-#include "ITrackToVertex/ITrackToVertex.h"
-
-#include "CLHEP/Vector/LorentzVector.h"
-#include "GeoPrimitives/GeoPrimitives.h"
-#include "GeoPrimitives/GeoPrimitivesHelpers.h"
-#include "GaudiKernel/IToolSvc.h"
-
-#include <cmath>
-#include <fstream>
-#include <algorithm>
-#include <vector>
-#include <string>
-
-// locally used functions and typedefs
-namespace {
-  using namespace Analysis;
-  typedef std::map<std::string, std::vector<double> > VectorMap;
-  VectorMap get_nn_inputs(const std::vector<IPxDInfo>&);
-  size_t fill_posteriors(xAOD::BTagging&,
-                         const std::string& author,
-                         const std::vector<std::string>& names,
-                         const lwt::ValueMap& = lwt::ValueMap());
-  void fill_inputs(xAOD::BTagging&,
-                   const std::string& author,
-                   const lwt::VectorMap& inputs);
-
-  typedef std::vector<ElementLink<xAOD::TrackParticleContainer> > TrackLinks;
-
-  // keys to lookup track sorting info
-  const std::string SORT_BY = "sort_by";
-  const std::string UNKNOWN_SORT = "unknown_sort";
-  std::string get_sort_name(const lwt::JSONConfig& cfg);
-  TrackSorter get_sort_function(const std::string& key);
-
-struct TrackSorterFunctional
-{
-  TrackSorterFunctional (const TrackSorter& sorter)
-    : m_sorter (sorter) {}
-  bool operator() (const IPxDInfo& a, const IPxDInfo& b) const
-  {
-    return m_sorter (a, b);
-  }
-
-  const TrackSorter& m_sorter;
-};
-
-}
-
-// Track variable names, for both the NN inputs and for writing to the
-// xAOD EDM.
-namespace trkvar {
-  const std::string D0 = "d0";
-  const std::string D0_SIG = "d0sig";
-  const std::string Z0 = "z0";
-  const std::string Z0_SIG = "z0sig";
-  const std::string D0Z0_SIG = "d0z0sig";
-  const std::string GRADE = "grade";
-  const std::string FROM_V0 = "fromV0";
-  const std::string PT = "pt";
-  const std::string DPHI = "dPhi";
-  const std::string ABS_ETA = "absEta";
-  const std::string DETA = "dEta";
-  const std::string CHARGE = "charge";
-
-  const std::string PT_FRAC = "pTFrac";
-  const std::string DR = "dR";
-
-  // hit info
-  const std::string CHI2 = "chi2";
-  const std::string N_INN_HITS = "nInnHits";
-  const std::string N_NEXT_TO_INN_HITS = "nNextToInnHits";
-  const std::string N_BL_HITS = "nBLHits";
-  const std::string N_SHARED_BL_HITS = "nsharedBLHits";
-  const std::string N_SPLIT_BL_HITS = "nsplitBLHits";
-  const std::string N_PIX_HITS = "nPixHits";
-  const std::string N_SHARED_PIX_HITS = "nsharedPixHits";
-  const std::string N_SPLIT_PIX_HITS = "nsplitPixHits";
-  const std::string N_SCT_HITS = "nSCTHits";
-  const std::string N_SHARED_SCT_HITS = "nsharedSCTHits";
-  const std::string EXPECT_BL_HIT = "expectInnermostPixelLayerHit";
-  const std::string EXPECT_INNERMOST_PIX_HIT =
-    "expectInnermostPixelLayerHit";
-  const std::string EXPECT_NEXT_TO_INNERMOST_PIX_HIT =
-    "expectNextToInnermostPixelLayerHit";
-}
-
-namespace Analysis {
-  struct IPxDInfo {
-    ElementLink<xAOD::TrackParticleContainer> trk;
-    double d0;
-    double d0sig;
-    double z0;
-    double z0sig;
-    double dphi;
-    double ptfrac;
-    double dr;
-    double deta;
-    TrackGrade grade;
-    const xAOD::TrackParticle* trkP;
-    bool fromV0;
-  } ;
-
-  bool StructPTsorting(const IPxDInfo& objA, const IPxDInfo& objB) {
-    return (objA.trkP)->pt() > (objB.trkP)->pt();
-  }
-
-  bool StructD0Sigsorting(const IPxDInfo& objA, const IPxDInfo& objB) {
-    return fabs(objA.d0sig) > fabs(objB.d0sig);
-  }
-
-  bool StructZ0D0Sigsorting(const IPxDInfo& objA, const IPxDInfo& objB) {
-    double a = pow(objA.d0sig,2)+pow(objA.z0sig,2);
-    double b = pow(objB.d0sig,2)+pow(objB.z0sig,2);
-    return a > b;
-  }
-
-
-  /**
-      @class RNNIPTag
-      b-jet tagger based on 2D or 3D impact parameter
-      @author CPPM Marseille
-  */
-
-
-  RNNIPTag::RNNIPTag(const std::string& t,
-                     const std::string& n,
-                     const IInterface* p)
-    : base_class(t,n,p),
-      m_unbiasIPEstimation(true),
-      m_calibrationDirectory("RNNIP"),
-      m_secVxFinderName("InDetVKalVxInJetTool"),
-      m_trackSelectorTool("Analysis::TrackSelector", this),
-      m_SVForIPTool("Analysis::SVForIPTool", this),
-      m_trackGradeFactory("Analysis::BasicTrackGradeFactory", this),
-      m_trackToVertexIPEstimator(this)
-  {
-    // global configuration:
-    declareProperty("xAODBaseName"  , m_xAODBaseName);
-
-    declareProperty("flipIPSign"          , m_flipIP              = false);
-    declareProperty("flipZIPSign"         , m_flipZIP             = false);
-    declareProperty("usePosIP"            , m_usePosIP            = true);
-    declareProperty("useNegIP"            , m_useNegIP            = true);
-    declareProperty("useZIPSignForPosNeg" , m_useZIPSignForPosNeg = false);
-    declareProperty("use2DSignForIP3D"    , m_use2DSignForIP3D    = false);
-    declareProperty("useD0SignForZ0"      , m_useD0SignForZ0      = false);
-    declareProperty("RejectBadTracks"     , m_rejectBadTracks     = true);
-    declareProperty("unbiasIPEstimation"  , m_unbiasIPEstimation);
-    declareProperty("writeInputsToBtagObject",
-                    m_writeInputsToBtagObject = false);
-    declareProperty("writeTrackLinks",
-                    m_writeTrackLinks = false);
-
-    declareProperty("trackAssociationName"    ,
-                    m_trackAssociationName = "BTagTrackToJetAssociator");
-    declareProperty("originalTPCollectionName",
-                    m_originalTPCollectionName = "InDetTrackParticles");
-    declareProperty("ForcedCalibrationName"   , m_ForcedCalibName = "AntiKt4EMTopo");
-    declareProperty("NetworkConfig"           , m_network_cfg);
-
-    declareProperty("trackGradePartitions"    ,
-                    m_trackGradePartitionsDefinition);
-    m_trackGradePartitionsDefinition.push_back("Good");
-
-    declareProperty("SecVxFinderName"         ,m_secVxFinderName);
-
-    // tools:
-    declareProperty("trackSelectorTool"         , m_trackSelectorTool     );
-    declareProperty("SVForIPTool"               , m_SVForIPTool           );
-    declareProperty("trackGradeFactory"         , m_trackGradeFactory      );
-    declareProperty("TrackToVertexIPEstimator"  , m_trackToVertexIPEstimator);
-    declareProperty("calibration_directory", m_calibrationDirectory);
-  }
-
-
-  RNNIPTag::~RNNIPTag() {
-    for (size_t i = 0; i < m_trackGradePartitions.size(); i++)
-      delete m_trackGradePartitions[i];
-
-    // Networks are owned by the structure they are created in
-  }
-
-
-  StatusCode RNNIPTag::initialize() {
-
-    // FF: comment out V0 finding
-    if (m_SVForIPTool.retrieve().isFailure() )  {
-       ATH_MSG_FATAL("#BTAG# Failed to retrieve tool " << m_SVForIPTool);
-       return StatusCode::FAILURE;
-    } else {
-       ATH_MSG_DEBUG("#BTAG# Retrieved tool " << m_SVForIPTool);
-    }
-    if (m_trackToVertexIPEstimator.retrieve().isFailure() ) {
-      ATH_MSG_FATAL("#BTAG# Failed to retrieve tool " <<
-                    m_trackToVertexIPEstimator);
-      return StatusCode::FAILURE;
-    } else {
-      ATH_MSG_DEBUG("#BTAG# Retrieved tool " << m_trackToVertexIPEstimator);
-    }
-
-
-    /** creation of TrackSelector: (private instance) */
-    if ( m_trackSelectorTool.retrieve().isFailure() ) {
-      ATH_MSG_FATAL("#BTAG# Failed to retrieve tool " << m_trackSelectorTool);
-      return StatusCode::FAILURE;
-    } else {
-      ATH_MSG_DEBUG("#BTAG# Retrieved tool " << m_trackSelectorTool);
-    }
-
-    /** retrieving the track grade factory */
-    if ( m_trackGradeFactory.retrieve().isFailure() ) {
-      ATH_MSG_FATAL("#BTAG# Failed to retrieve tool " << m_trackGradeFactory);
-      return StatusCode::FAILURE;
-    } else {
-      ATH_MSG_DEBUG("#BTAG# Retrieved tool " << m_trackGradeFactory);
-    }
-
-    /** prepare the track partitions: */
-    int nbPart = m_trackGradePartitionsDefinition.size();
-    ATH_MSG_DEBUG("#BTAG# Defining " << nbPart <<" track partitions: ");
-    for(int i=0;i<nbPart;i++) {
-      TrackGradePartition* part = nullptr;
-      try {
-        part = new TrackGradePartition(m_trackGradePartitionsDefinition[i],
-                                       *m_trackGradeFactory);
-      }
-      catch (std::string error) {
-        ATH_MSG_ERROR("#BTAG# Reported error " << error);
-        ATH_MSG_ERROR("#BTAG# List of categories provided to IPTag by jO : ");
-        for (int l=0;l<nbPart;l++) {
-          ATH_MSG_ERROR(
-            "#BTAG#  string " << m_trackGradePartitionsDefinition[l]);
-        }
-        ATH_MSG_ERROR("#BTAG# List of categories provided by the"
-                      " TrackGradeFactory " << m_trackGradeFactory);
-
-        if (msgLvl(MSG::ERROR)) {
-          const auto& grades = m_trackGradeFactory->getTrackGradesDefinition();
-          for (const auto& grade: grades.getList() ) {
-            ATH_MSG_ERROR("#BTAG# n. " << grade.gradeNumber() <<
-                          " string " << grade.gradeString());
-          }
-        }
-        ATH_MSG_ERROR("#BTAG# Terminating now... ");
-        return StatusCode::FAILURE;
-      }
-      ATH_MSG_DEBUG((*part));
-      m_trackGradePartitions.push_back(part);
-    }
-
-    // prepare readKey for calibration data:
-    ATH_CHECK(m_readKey.initialize());
-
-    return StatusCode::SUCCESS;
-  }
-
-
-  StatusCode RNNIPTag::finalize() {
-    return StatusCode::SUCCESS;
-  }
-
-
-  StatusCode RNNIPTag::tagJet(const xAOD::Vertex& priVtx,
-                              const xAOD::Jet& jetToTag,
-                              xAOD::BTagging& BTag,
-                              const std::string &jetName) const
-  {
-    /** author to know which jet algorithm: */
-    std::string author = jetName;
-    if (m_ForcedCalibName.size() > 0) author = m_ForcedCalibName;
-    ATH_MSG_VERBOSE("#BTAG# Using jet type " << author << " for calibrations");
-
-    std::vector<GradedTrack> tracksInJet;
-    int nbPart = m_trackGradePartitionsDefinition.size();
-
-    std::vector<const xAOD::TrackParticle*> TrkFromV0;
-
-    // bad tracks from V0s, conversions, interactions:
-    m_SVForIPTool->getTrkFromV0FromSecondaryVertexInfo(
-      TrkFromV0,//output
-      &BTag,m_secVxFinderName);//input
-
-    ATH_MSG_VERBOSE("#BTAG# VALERIO TrkFromV0 : number of reconstructed"
-                    " bad tracks: " << TrkFromV0.size());
-    if (TrkFromV0.size()!=0)  ATH_MSG_DEBUG(
-      "#BTAG# TrkFromV0 : number of reconstructed bad tracks: " <<
-      TrkFromV0.size());
-
-    /** extract the TrackParticles from the jet and apply track selection: */
-    int nbTrak = 0;
-
-    const auto& associationLinks = BTag.auxdata<TrackLinks>(
-      m_trackAssociationName);
-    double sumTrkpT = 0;
-    if( associationLinks.size() == 0 ) {
-      ATH_MSG_VERBOSE("#BTAG#  Could not find tracks associated with"
-                      " BTagging object as " << m_trackAssociationName);
-    } else {
-
-      // We loop over the tracks twice: the first time is to compute
-      // the summed pt of all tracks satisfying the "normal" criteria;
-      // the second time a possibly tighter pt cut may be applied
-      for(const auto& trk: associationLinks) {
-        const xAOD::TrackParticle* aTemp = *trk;
-        if (m_trackSelectorTool->selectTrack(priVtx.position(), aTemp))
-        {
-          sumTrkpT += aTemp->pt();
-        }
-      }
-      // m_trackSelectorTool->setSumTrkPt(sumTrkpT);
-
-      for(const auto& trk: associationLinks) {
-        const xAOD::TrackParticle* aTemp = *trk;
-        nbTrak++;
-        if( m_trackSelectorTool->selectTrack(priVtx.position(), aTemp, sumTrkpT) ) {
-          TrackGrade* theGrade = m_trackGradeFactory->getGrade(
-            *aTemp, jetToTag.p4() );
-          ATH_MSG_VERBOSE("#BTAG#  result of selectTrack is OK, grade= "
-                          << theGrade->gradeString() );
-          bool tobeUsed = false;
-          for(int i=0;i<nbPart;i++) {
-            if( std::find( (m_trackGradePartitions[i]->grades()).begin(),
-                           (m_trackGradePartitions[i]->grades()).end(),
-                           *theGrade )
-                != (m_trackGradePartitions[i]->grades()).end() ){
-              tobeUsed = true;
-            }
-          }
-          // is it a bad track ?
-          if( std::find(TrkFromV0.begin(),TrkFromV0.end(),aTemp)
-              != TrkFromV0.end() ) {
-            ATH_MSG_VERBOSE("#BTAG# Bad track in jet, pt = " << aTemp->pt() <<
-                            " eta = " << aTemp->eta() << " phi = " <<
-                            aTemp->phi() );
-            if (m_rejectBadTracks) tobeUsed = false;
-          }
-          // check required IP sign:
-          if (tobeUsed) tracksInJet.push_back(GradedTrack(trk, *theGrade));
-          delete theGrade;
-          theGrade=0;
-        }
-      }
-    }
-
-    ATH_MSG_VERBOSE("#BTAG# #tracks = " << nbTrak);
-    ATH_MSG_VERBOSE("#BTAG# the z of the primary = " <<
-                    priVtx.position().z());
-
-    /** jet direction: */
-    Amg::Vector3D jetDirection(jetToTag.px(),jetToTag.py(),jetToTag.pz());
-
-    /** prepare vectors with all track information: TP links,
-     * i.p. significances, track grade, etc */
-    auto track_info = get_track_info(priVtx, tracksInJet, jetDirection, TrkFromV0);
-
-    // add the tags
-    add_tags(BTag, author, track_info);
-
-    if (m_writeTrackLinks) {
-      TrackLinks ip_tracks;
-      for (const auto& trk: track_info) {
-        ip_tracks.push_back( trk.trk );
-      }
-
-      // specific fast accessors for mainstream instances of IPTag: IP3D, IP2D
-      //// need to handle to persistify for dynamic values before adding this
-      BTag.setVariable<TrackLinks> (
-        m_xAODBaseName, "TrackParticleLinks", ip_tracks );
-      BTag.setDynTPELName( m_xAODBaseName, "TrackParticleLinks");
-    }
-
-    return StatusCode::SUCCESS;
-  }
-
-  // ___________________________________________________________
-  // apply tags loop
-  void RNNIPTag::add_tags(xAOD::BTagging& tag, const std::string& author,
-                          std::vector<IPxDInfo>& track_info) const {
-
-    // first loop is over the different sorting functions
-    for (const auto& sort_group: get_networks_for(author)) {
-      const auto& sort_func = sort_group.first;
-      const auto& networks = sort_group.second;
-      // This doesn't compile with clang 3.8 and gcc 6.1
-      //std::sort( track_info.begin(), track_info.end(), sort_func);
-      TrackSorterFunctional sorter (sort_func);
-      std::sort( track_info.begin(), track_info.end(), sorter);
-      const auto inputs = get_nn_inputs(track_info);
-
-      // inner loop is over the networks that use this sort function
-      for (const auto& network: networks) {
-        if (track_info.size() == 0) {
-          ATH_MSG_DEBUG("no tracks, filling with defaults");
-          fill_posteriors(tag, network.name, network.outputs);
-          continue;
-        }
-        try {
-          lwt::ValueMap out = network.network->reduce(inputs);
-          fill_posteriors(tag, network.name, network.outputs, out);
-          if (msgLvl(MSG::DEBUG)) {
-            std::string op = "output for " + network.name + ": ";
-            for (const auto& pr: out) {
-              op.append(pr.first + " = " + std::to_string(pr.second) + ", ");
-            }
-            ATH_MSG_DEBUG(op);
-          }
-        } catch (lwt::NNEvaluationException& e) {
-          ATH_MSG_WARNING(e.what() << " tagging with " + network.name
-                          + ", will fill with defaults");
-          fill_posteriors(tag, network.name, network.outputs);
-        }
-      } // end loop over networks
-      // for each sorting, store inputs
-      if (networks.size() > 0) {
-        if (m_writeInputsToBtagObject) {
-          fill_inputs(tag, networks.front().name, inputs);
-        }
-      } else {
-        ATH_MSG_ERROR("Found sorting function in RNNIP with no accompanying"
-                      " inputs. This should not happen.");
-      }
-    } // end loop over sorting functions
-
-  }
-
-  RNNIPTag::Network::Network(const std::string& net_name,
-                             const lwt::JSONConfig& cf):
-    name(net_name),
-    network(new lwt::LightweightRNN(cf.inputs, cf.layers, cf.outputs)),
-    outputs(cf.outputs)
-  {
-  }
-
-  std::string RNNIPTag::get_calib_string(const std::string& author,
-                                         const std::string& name) const
-  {
-    // if we have an override we ignore the author and just read from
-    // a text file
-    if (m_network_cfg.at(name).size() > 0) {
-      ATH_MSG_DEBUG("Reading from local file");
-      std::ifstream file(m_network_cfg.at(name));
-      std::stringstream out;
-      out << file.rdbuf();
-      return out.str();
-    } else {
-      ATH_MSG_DEBUG("reading out from DB");
-    }
-
-    SG::ReadCondHandle<JetTagCalibCondData> readCdo(m_readKey); 
-    return readCdo->retrieveIPRNN(m_calibrationDirectory , author);
-  }
-
-
-
-  const RNNIPTag::SortGroups&
-  RNNIPTag::get_networks_for(const std::string& author) const {
-    using std::map;
-    using std::string;
-    using std::pair;
-    using std::vector;
-    using namespace lwt;
-
-    std::lock_guard<std::mutex> lock (m_networksMutex);
-
-    // TODO: delete networks if they've gone out of the IOV, needs
-    // some calibration broker code. On the other hand, we've never
-    // had an IOV end within a job. Will we?
-    auto it = m_networks.find(author);
-    if (it != m_networks.end()) {
-      return it->second;
-    }
-    SortGroups& groups = m_networks[author];
-
-    // order the networks we need to build by the sort function
-    typedef map<string, vector<pair<string, JSONConfig > > > NWBySort;
-    NWBySort nw_by_sort_func;
-    for (const auto& cfg: m_network_cfg) {
-      const auto& cfg_name = cfg.first;
-      std::string calstring = get_calib_string(author, cfg_name);
-      if (calstring.size() == 0) {
-        ATH_MSG_WARNING("cant load '" + cfg_name + "' for '" + author + "'");
-        continue;
-      }
-      ATH_MSG_DEBUG("calstring for " + author + ", " + cfg_name + ": "
-                    << calstring.size() << " characters");
-      std::stringstream stream(calstring);
-      try {
-        lwt::JSONConfig nncfg = lwt::parse_json(stream);
-        auto sort_name = get_sort_name(nncfg);
-        nw_by_sort_func[sort_name].emplace_back(cfg_name, nncfg);
-      } catch (std::exception& e) {
-        ATH_MSG_WARNING(e.what() << ", will not run '" + cfg_name
-                        + "' for '" + author + "' jets");
-      }
-    }
-
-    // build the groups for this author
-    for (const auto& sf_nw: nw_by_sort_func) {
-      // TODO: add more sort func
-      TrackSorter sort = get_sort_function(sf_nw.first);
-      groups.emplace_back(sort, Networks());
-      for (const auto& name_and_network_conf: sf_nw.second) {
-        const auto& nw_config = name_and_network_conf.second;
-        const auto& nw_name = name_and_network_conf.first;
-        ATH_MSG_DEBUG(nw_name + ": " << nw_config.layers.size() << " layers");
-        auto& nw_group = groups.back().second;
-        try {
-          nw_group.emplace_back(nw_name, nw_config);
-        } catch (lwt::NNConfigurationException& e) {
-          ATH_MSG_WARNING(nw_name + " init failure: " + e.what());
-        }
-      }
-    }
-
-    return groups;
-  }
-
-  // ____________________________________________________________
-  // Get track info vector
-
-  std::vector<IPxDInfo> RNNIPTag::get_track_info(
-    const xAOD::Vertex& priVtx,
-    const std::vector<GradedTrack>& tracksInJet,
-    const Amg::Vector3D& jetDirection,
-    const std::vector<const xAOD::TrackParticle*>& TrkFromV0) const {
-    Amg::Vector3D unit = jetDirection.unit();
-    double jet_pt = std::hypot(jetDirection.x(), jetDirection.y());
-
-    std::vector<IPxDInfo> track_info;
-
-    for (std::vector<GradedTrack>::const_iterator trkItr = tracksInJet.begin();
-         trkItr != tracksInJet.end(); ++trkItr) {
-
-      const xAOD::TrackParticle* trk = *(trkItr->track);
-      const auto& trk4 = trk->p4();
-      const Amg::Vector3D trk_momentum(trk4.Px(), trk4.Py(), trk4.Pz());
-
-      bool isFromV0 = (
-        std::find(TrkFromV0.begin(),TrkFromV0.end(),trk) != TrkFromV0.end());
-
-      /** track parameters defined at the primary vertex: */
-      double d0wrtPriVtx(0.);
-      double z0wrtPriVtx(0.);
-      double d0ErrwrtPriVtx(1.);
-      double z0ErrwrtPriVtx(1.);
-
-      /** use new Tool for "unbiased" IP estimation */
-      const Trk::ImpactParametersAndSigma* myIPandSigma(0);
-      if (m_trackToVertexIPEstimator) {
-        myIPandSigma = m_trackToVertexIPEstimator->estimate(
-          trk, &priVtx, m_unbiasIPEstimation);
-      }
-      if(0==myIPandSigma) {
-        ATH_MSG_WARNING("#BTAG# IPTAG: trackToVertexIPEstimator failed !");
-      } else {
-        d0wrtPriVtx=myIPandSigma->IPd0;
-        d0ErrwrtPriVtx=myIPandSigma->sigmad0;
-        z0wrtPriVtx=myIPandSigma->IPz0SinTheta;
-        z0ErrwrtPriVtx=myIPandSigma->sigmaz0SinTheta;
-        delete myIPandSigma;
-        myIPandSigma=0;
-      }
-
-      /** sign of the impact parameter */
-      double signOfIP(1.);
-      if ( m_use2DSignForIP3D ) {
-        signOfIP=m_trackToVertexIPEstimator->get2DLifetimeSignOfTrack(
-          trk->perigeeParameters(),unit, priVtx);
-      } else {
-        signOfIP=m_trackToVertexIPEstimator->get3DLifetimeSignOfTrack(
-          trk->perigeeParameters(), unit, priVtx);
-      }
-      double signOfZIP = m_trackToVertexIPEstimator->getZLifetimeSignOfTrack(
-        trk->perigeeParameters(), unit, priVtx);
-
-      if (m_useD0SignForZ0) signOfZIP = signOfIP;
-
-      /** option to flip signs for negative tag method */
-      if(m_flipIP  )  signOfIP = -signOfIP;
-      if(m_flipZIP ) signOfZIP = -signOfZIP;
-
-      /** select according to sign: skip tracks if not ok */
-      if(signOfIP>0 && !m_usePosIP) continue;
-      if(signOfIP<0 && !m_useNegIP) continue;
-      if( m_useZIPSignForPosNeg ) {
-        if(signOfZIP>0 && !m_usePosIP) continue;
-        if(signOfZIP<0 && !m_useNegIP) continue;
-      }
-
-      /** significances */
-      double sIP         = signOfIP*fabs(d0wrtPriVtx);
-      double significance= signOfIP*fabs(d0wrtPriVtx/d0ErrwrtPriVtx);
-      double szIP        = signOfZIP*fabs(z0wrtPriVtx);
-      double z0Sig       = signOfZIP*fabs(z0wrtPriVtx/z0ErrwrtPriVtx);
-
-      // VD: I know that this is ugly but I want to minimise the
-      // changes as much as I can
-      IPxDInfo tmpObj;
-      tmpObj.trk=trkItr->track;
-      tmpObj.d0   =sIP;
-      tmpObj.d0sig=significance;
-      tmpObj.z0   =szIP;
-      tmpObj.z0sig=z0Sig;
-      tmpObj.grade=trkItr->grade;
-      tmpObj.trkP =trk;
-      tmpObj.fromV0=isFromV0;
-      tmpObj.dphi = Amg::deltaPhi(trk_momentum, unit);
-      tmpObj.dr = Amg::deltaR(trk_momentum, unit);
-      tmpObj.deta = trk_momentum.eta() - unit.eta();
-      tmpObj.ptfrac = trk->pt() / jet_pt;
-      track_info.push_back(tmpObj);
-    }
-    return track_info;
-  }
-
-}//end namespace
-
-namespace {
-  double val(const xAOD::TrackParticle& tp, const xAOD::SummaryType& prop) {
-    uint8_t val;
-    tp.summaryValue(val, prop);
-    return val;
-  }
-
-  VectorMap get_nn_inputs(const std::vector<IPxDInfo>& tracks) {
-    using namespace trkvar;
-    const std::vector<std::string> inputs{
-      D0, D0_SIG, Z0, Z0_SIG, D0Z0_SIG, GRADE, FROM_V0, PT, DPHI, ABS_ETA,
-        PT_FRAC, DR, DETA, CHARGE,
-        CHI2, N_INN_HITS, N_NEXT_TO_INN_HITS, N_BL_HITS, N_SHARED_BL_HITS,
-        N_SPLIT_BL_HITS, N_PIX_HITS, N_SHARED_PIX_HITS, N_SPLIT_PIX_HITS,
-        N_SCT_HITS, N_SHARED_SCT_HITS, EXPECT_BL_HIT,
-        EXPECT_INNERMOST_PIX_HIT, EXPECT_NEXT_TO_INNERMOST_PIX_HIT};
-    VectorMap out;
-    for (const auto& input: inputs) {
-      out.emplace(input, std::vector<double>());
-    }
-    for (const auto& tk: tracks) {
-      out.at(D0).push_back(tk.d0);
-      out.at(D0_SIG).push_back(tk.d0sig);
-      out.at(Z0).push_back(tk.z0);
-      out.at(Z0_SIG).push_back(tk.z0sig);
-      out.at(D0Z0_SIG).push_back(std::hypot(tk.z0sig, tk.d0sig));
-      out.at(GRADE).push_back(tk.grade);
-      out.at(FROM_V0).push_back(tk.fromV0);
-      out.at(PT).push_back(tk.trkP->pt());
-      out.at(DPHI).push_back(tk.dphi);
-      out.at(ABS_ETA).push_back(std::abs(tk.trkP->eta()));
-      out.at(PT_FRAC).push_back(tk.ptfrac);
-      out.at(DR).push_back(tk.dr);
-      out.at(DETA).push_back(tk.deta);
-      out.at(CHARGE).push_back(tk.trkP->charge());
-
-      const auto& tp = *tk.trkP;
-      out.at(CHI2).push_back(tp.chiSquared());
-      out.at(N_INN_HITS).push_back(
-        val(tp,xAOD::numberOfInnermostPixelLayerHits));
-      out.at(N_NEXT_TO_INN_HITS).push_back(
-        val(tp, xAOD::numberOfNextToInnermostPixelLayerHits));
-      out.at(N_BL_HITS).push_back(
-        val(tp, xAOD::numberOfInnermostPixelLayerHits));
-      out.at(N_SHARED_BL_HITS).push_back(
-        val(tp, xAOD::numberOfInnermostPixelLayerSharedHits));
-      out.at(N_SPLIT_BL_HITS).push_back(
-        val(tp, xAOD::numberOfInnermostPixelLayerSplitHits));
-      out.at(N_PIX_HITS).push_back(
-        val(tp, xAOD::numberOfPixelHits));
-      out.at(N_SHARED_PIX_HITS).push_back(
-        val(tp, xAOD::numberOfPixelSharedHits));
-      out.at(N_SPLIT_PIX_HITS).push_back(
-        val(tp, xAOD::numberOfPixelSplitHits));
-      out.at(N_SCT_HITS).push_back(
-        val(tp, xAOD::numberOfSCTHits));
-      out.at(N_SHARED_SCT_HITS).push_back(
-        val(tp, xAOD::numberOfSCTSharedHits));
-      out.at(EXPECT_BL_HIT).push_back(
-        val(tp, xAOD::expectInnermostPixelLayerHit));
-      out.at(EXPECT_INNERMOST_PIX_HIT).push_back(
-        val(tp, xAOD::expectInnermostPixelLayerHit));
-      out.at(EXPECT_NEXT_TO_INNERMOST_PIX_HIT).push_back(
-        val(tp, xAOD::expectNextToInnermostPixelLayerHit));
-    }
-    return out;
-  }
-
-  size_t fill_posteriors(xAOD::BTagging& tag,
-                         const std::string& author,
-                         const std::vector<std::string>& outputs,
-                         const lwt::ValueMap& vals) {
-    size_t found = 0;
-    for (const auto& out: outputs) {
-      double val = 0;         // was NaN, see jira: AFT-194, ATLASRECTS-3897
-      bool is_valid = false;
-      if (vals.count(out)) {
-        val = vals.at(out);
-        found++;
-        is_valid = true;
-      }
-      tag.setVariable<double>(author, out, val);
-      std::string valid_key = out + "IsValid";
-      tag.setVariable<char>(author, valid_key, is_valid);
-    }
-    return found;
-  }
-  void fill_inputs(xAOD::BTagging& tag,
-                   const std::string& author,
-                   const lwt::VectorMap& inputs) {
-    // cast to float to save space
-    typedef std::vector<float> OutVector;
-    for (const auto& in: inputs) {
-      OutVector outvec(in.second.begin(), in.second.end());
-      tag.setVariable<OutVector>(author, in.first, outvec);
-    }
-  }
-
-  std::string get_sort_name(const lwt::JSONConfig& cfg) {
-    if (!cfg.miscellaneous.count(SORT_BY)) {
-      throw std::logic_error("sort function not given");
-    }
-    return cfg.miscellaneous.at(SORT_BY);
-  }
-
-  Analysis::TrackSorter get_sort_function(const std::string& key) {
-    using namespace trkvar;
-    using namespace Analysis;
-    if (key == D0_SIG) return StructD0Sigsorting;
-    if (key == PT) return StructPTsorting;
-    if (key == D0Z0_SIG) return StructZ0D0Sigsorting;
-    throw std::logic_error("sort by " + key + " is not defined");
-  }
-
-}
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/src/SVTag.cxx b/PhysicsAnalysis/JetTagging/JetTagTools/src/SVTag.cxx
index 9e2e6791e1a911496b58f569714ef9bbea3af09f..f4421ab5403725c94c3d13d3bed51f0712ef65a6 100644
--- a/PhysicsAnalysis/JetTagging/JetTagTools/src/SVTag.cxx
+++ b/PhysicsAnalysis/JetTagging/JetTagTools/src/SVTag.cxx
@@ -53,6 +53,7 @@ namespace Analysis
     declareProperty("UseDRJetPvSv", m_useDRJPVSV = true);
     declareProperty("UseCHypo", m_useCHypo=true);
     declareProperty("UseSV2Pt", m_usePtSV2=false);
+    declareProperty("SaveProbabilities", m_save_probabilities=false);
 
   }
 
@@ -446,9 +447,11 @@ namespace Analysis
 	  }
 	}
 
+  if (m_save_probabilities) {
 	BTag.setVariable<double>(m_xAODBaseName, "pb", probi[0]);
 	BTag.setVariable<double>(m_xAODBaseName, "pu", probi[1]);
 	if (m_useCHypo) BTag.setVariable<double>(m_xAODBaseName, "pc", probi[2]);
+  }
 	
       }
 
diff --git a/PhysicsAnalysis/JetTagging/JetTagTools/src/components/JetTagTools_entries.cxx b/PhysicsAnalysis/JetTagging/JetTagTools/src/components/JetTagTools_entries.cxx
index 8d6e7c6da50a08c2e1eccee50879657f9489f7e3..d7e16237c41e2b35be95c44c0e9fd051f78891d9 100644
--- a/PhysicsAnalysis/JetTagging/JetTagTools/src/components/JetTagTools_entries.cxx
+++ b/PhysicsAnalysis/JetTagging/JetTagTools/src/components/JetTagTools_entries.cxx
@@ -1,5 +1,4 @@
 #include "JetTagTools/IPTag.h"
-#include "JetTagTools/RNNIPTag.h"
 #include "JetTagTools/SVTag.h"
 #include "JetTagTools/MultiSVTag.h"
 
@@ -14,7 +13,6 @@
 #include "JetTagTools/MSVVariablesFactory.h"
 
 #include "JetTagTools/MultivariateTagManager.h"
-#include "JetTagTools/DL1Tag.h"
 #include "JetTagTools/TagNtupleDumper.h"
 #include "JetTagTools/JetFitterNNTool.h"
 #include "JetTagTools/JetFitterDummyClassifier.h"
@@ -27,11 +25,8 @@
 #include "JetTagTools/MV1Tag.h"
 #include "JetTagTools/MV2Tag.h"
 
-#include "JetTagTools/ExKtbbTagTool.h"
-
 
 DECLARE_COMPONENT( Analysis::IPTag )
-DECLARE_COMPONENT( Analysis::RNNIPTag )
 DECLARE_COMPONENT( Analysis::SVTag )
 DECLARE_COMPONENT( Analysis::MultiSVTag )
 DECLARE_COMPONENT( Analysis::SoftMuonTag )
@@ -41,7 +36,6 @@ DECLARE_COMPONENT( Analysis::JetFitterTag )
 DECLARE_COMPONENT( Analysis::JetFitterNtupleWriter )
 DECLARE_COMPONENT( Analysis::JetFitterVariablesFactory )
 DECLARE_COMPONENT( Analysis::MSVVariablesFactory )
-DECLARE_COMPONENT( Analysis::DL1Tag )
 DECLARE_COMPONENT( Analysis::TagNtupleDumper )
 DECLARE_COMPONENT( Analysis::MultivariateTagManager )
 DECLARE_COMPONENT( Analysis::JetFitterNNTool )
@@ -52,4 +46,4 @@ DECLARE_COMPONENT( Analysis::BasicTrackGradeFactory )
 DECLARE_COMPONENT( Analysis::DetailedTrackGradeFactory )
 DECLARE_COMPONENT( Analysis::MV1Tag )
 DECLARE_COMPONENT( Analysis::MV2Tag )
-DECLARE_COMPONENT( Analysis::ExKtbbTagTool )
+
diff --git a/Projects/AnalysisBase/version.txt b/Projects/AnalysisBase/version.txt
index 0398faf11c23a7b4f71ebf50cfb8ce6d4b0b4b99..637c2a164398da8cb2fd7460803515b49a29fcfa 100644
--- a/Projects/AnalysisBase/version.txt
+++ b/Projects/AnalysisBase/version.txt
@@ -1 +1 @@
-22.2.1
+22.2.2
diff --git a/Reconstruction/Jet/JetValidation/test/test_jet.sh b/Reconstruction/Jet/JetValidation/test/test_jet.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1ce0bd15815be4dd09dfc967f0f11d73f736313c
--- /dev/null
+++ b/Reconstruction/Jet/JetValidation/test/test_jet.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+# art-description: ART test job HITS to AOD
+# art-type: grid
+# art-input: mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.simul.HITS.e6337_s3126
+# art-include: master/Athena
+# art-output: *.root
+
+ART_PATH="/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/Tier0ChainTests/"
+ART_FILE="mc16_13TeV.410470.PhPy8EG_A14_ttbar_hdamp258p75_nonallhad.simul.HITS.e6337_s3126/HITS.12860054._032508.pool.root.1"
+HITSFile="${ART_PATH}${ART_FILE}"
+echo "Input HITS file for    : ${HITSFile}"
+
+Nevents=3000
+echo "Number of test events  : ${Nevents}"
+
+ART_AOD="nightly_jet.AOD.pool.root"
+echo "Output AOD file        : ${ART_AOD}"
+
+ART_Validation="nightly_jet.PHYSVAL.root"
+echo "Output Validation file : ${ART_Validation}"
+
+echo "Submitting Reconstruction ..."
+
+Reco_tf.py \
+    --maxEvents ${Nevents} \
+    --inputHITSFile=${HITSFile} \
+    --outputAODFile=${ART_AOD} \
+    --outputNTUP_PHYSVALFile ${ART_Validation} \
+    --validationFlags noExample \
+    --autoConfiguration everything \
+    --preExec 'from RecExConfig.RecFlags import rec;rec.doTrigger=False' \
+    direct
+
+echo "art-result: $? Reco"
diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METAssociator.h
index 9619c27fde221005683bd374e7f884698d369e53..010e74dbe5d9df4b6500f83cd06cf1c9d5dabb48 100644
--- a/Reconstruction/MET/METReconstruction/METReconstruction/METAssociator.h
+++ b/Reconstruction/MET/METReconstruction/METReconstruction/METAssociator.h
@@ -35,9 +35,9 @@
 
 #include "xAODTracking/TrackParticleContainer.h"
 #include "xAODTracking/Vertex.h"
-//#include "xAODCaloEvent/CaloClusterContainer.h"
 #include "xAODPFlow/PFOContainer.h"
 #include "xAODPFlow/PFO.h"
+#include "xAODPFlow/FlowElementContainer.h"
 
 namespace InDet {
   class IInDetTrackSelectionTool;
@@ -64,6 +64,7 @@ namespace met {
       // Use IParticleContainer for flexibility e.g. if combining clusters & towers
       const xAOD::IParticleContainer* tcCont = 0;
       const xAOD::PFOContainer* pfoCont = 0;
+      const xAOD::FlowElementContainer* feCont = 0;
       const xAOD::Vertex* pv = 0;
     };
 
@@ -95,6 +96,7 @@ namespace met {
     SG::ReadHandleKey<xAOD::IParticleContainer>  m_clcollKey;
     SG::ReadHandleKey<xAOD::TrackParticleContainer>  m_trkcollKey;
     SG::ReadHandleKey<xAOD::PFOContainer>  m_pfcollKey{this,"PFlowColl","CHSParticleFlowObjects","PFO Collection"};
+    SG::ReadHandleKey<xAOD::FlowElementContainer>  m_fecollKey{this,"FlowElementCollection","","FlowElement Collection (overrides PFO if not empty)"};
     SG::ReadHandleKey<xAOD::IParticleContainer>  m_forcollKey;
     SG::ReadHandleKey<xAOD::IParticleContainer>  m_hybridContKey;
 
@@ -122,17 +124,21 @@ namespace met {
     bool isGoodEoverP(const xAOD::TrackParticle* trk) const;
 
     virtual StatusCode fillAssocMap(xAOD::MissingETAssociationMap* metMap,
-				    const xAOD::IParticleContainer* hardObjs) const;
+                                    const xAOD::IParticleContainer* hardObjs) const;
     virtual StatusCode extractPFO(const xAOD::IParticle* obj,
-				  std::vector<const xAOD::IParticle*>& pfolist,
-				  const met::METAssociator::ConstitHolder& constits,
-				  std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const = 0;
+                                  std::vector<const xAOD::IParticle*>& pfolist,
+                                  const met::METAssociator::ConstitHolder& constits,
+                                  std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const = 0;
+    virtual StatusCode extractFE(const xAOD::IParticle* obj,
+                                 std::vector<const xAOD::IParticle*>& felist,
+                                 const met::METAssociator::ConstitHolder& constits,
+                                 std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const = 0;
     virtual StatusCode extractTracks(const xAOD::IParticle* obj,
-				     std::vector<const xAOD::IParticle*>& constlist,
-				     const met::METAssociator::ConstitHolder& constits) const = 0;
+                                     std::vector<const xAOD::IParticle*>& constlist,
+                                     const met::METAssociator::ConstitHolder& constits) const = 0;
     virtual StatusCode extractTopoClusters(const xAOD::IParticle* obj,
-					   std::vector<const xAOD::IParticle*>& tclist,
-					   const met::METAssociator::ConstitHolder& constits) const = 0;
+                                           std::vector<const xAOD::IParticle*>& tclist,
+                                           const met::METAssociator::ConstitHolder& constits) const = 0;
     static inline bool greaterPt(const xAOD::IParticle* part1, const xAOD::IParticle* part2) {
       return part1->pt()>part2->pt();
     }
@@ -142,6 +148,11 @@ namespace met {
       if (part1->charge()==0 && part2->charge()==0) return part1->ptEM()>part2->ptEM();
       return part1->pt()>part2->pt();
     }
+    static inline bool greaterPtFE(const xAOD::FlowElement* part1, const xAOD::FlowElement* part2) {
+      if (!(part1->isCharged()) && part2->isCharged()) return false;
+      if (part1->isCharged() && !(part2->isCharged())) return true;
+      return part1->pt() > part2->pt();
+    }
     ///////////////////////////////////////////////////////////////////
     // Private methods:
     ///////////////////////////////////////////////////////////////////
diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h
index 6be2a69aa0531b34f145f86506a8d7c35a7e1dd5..a5639d0d599470e231a553160bd0559a13b7342a 100644
--- a/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h
+++ b/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h
@@ -56,25 +56,30 @@ namespace met{
     protected: 
 
     StatusCode extractTopoClusters(const xAOD::IParticle* obj,
-				   std::vector<const xAOD::IParticle*>& tclist,
-				   const met::METAssociator::ConstitHolder& constits) const final;
+                                   std::vector<const xAOD::IParticle*>& tclist,
+                                   const met::METAssociator::ConstitHolder& constits) const final;
 
     StatusCode extractPFO(const xAOD::IParticle* obj,
-			  std::vector<const xAOD::IParticle*>& pfolist,
-			  const met::METAssociator::ConstitHolder& constits,
-			  std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final;
+                          std::vector<const xAOD::IParticle*>& pfolist,
+                          const met::METAssociator::ConstitHolder& constits,
+                          std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final;
+
+    StatusCode extractFE(const xAOD::IParticle* obj,
+                         std::vector<const xAOD::IParticle*>& felist,
+                         const met::METAssociator::ConstitHolder& constits,
+                         std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final;
 
     StatusCode extractTracks(const xAOD::IParticle* obj,
-			     std::vector<const xAOD::IParticle*>& constlist,
-			     const met::METAssociator::ConstitHolder& constits) const final;
+                             std::vector<const xAOD::IParticle*>& constlist,
+                             const met::METAssociator::ConstitHolder& constits) const final;
 
     StatusCode selectEgammaClusters(const xAOD::CaloCluster *swclus,
-				    const std::vector<const xAOD::IParticle*>& inputTC,
-				    std::vector<const xAOD::IParticle*>& tclist) const;
+                                    const std::vector<const xAOD::IParticle*>& inputTC,
+                                    std::vector<const xAOD::IParticle*>& tclist) const;
 
     StatusCode selectEgammaTracks(const xAOD::Egamma* el,
-				  const xAOD::TrackParticleContainer* trkCont,
-				  std::set<const xAOD::TrackParticle*>& tracklist) const;
+                                  const xAOD::TrackParticleContainer* trkCont,
+                                  std::set<const xAOD::TrackParticle*>& tracklist) const;
 
     double m_tcMatch_dR;
     double m_tcMatch_maxRat;
diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METJetAssocTool.h b/Reconstruction/MET/METReconstruction/METReconstruction/METJetAssocTool.h
index fe8d1c71b2800d4f1ab976f3a51a956728e7285f..d47674488760229ddad5cf305ec3cd778d9ada68 100644
--- a/Reconstruction/MET/METReconstruction/METReconstruction/METJetAssocTool.h
+++ b/Reconstruction/MET/METReconstruction/METReconstruction/METJetAssocTool.h
@@ -57,17 +57,22 @@ namespace met{
     StatusCode executeTool(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap) const;
 
     StatusCode extractPFO(const xAOD::IParticle*,
-			  std::vector<const xAOD::IParticle*>&,
-			  const met::METAssociator::ConstitHolder&,
-			  std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t>&) const
+                          std::vector<const xAOD::IParticle*>&,
+                          const met::METAssociator::ConstitHolder&,
+                          std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t>&) const
+    {return StatusCode::FAILURE;} // should not be called
+    StatusCode extractFE(const xAOD::IParticle*,
+                         std::vector<const xAOD::IParticle*>&,
+                         const met::METAssociator::ConstitHolder&,
+                         std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t>&) const
     {return StatusCode::FAILURE;} // should not be called
     StatusCode extractTracks(const xAOD::IParticle*,
-			     std::vector<const xAOD::IParticle*>&,
-			     const met::METAssociator::ConstitHolder&) const
+                             std::vector<const xAOD::IParticle*>&,
+                             const met::METAssociator::ConstitHolder&) const
     {return StatusCode::FAILURE;} // should not be called
     StatusCode extractTopoClusters(const xAOD::IParticle*,
-				   std::vector<const xAOD::IParticle*>&,
-				   const met::METAssociator::ConstitHolder&) const
+                                   std::vector<const xAOD::IParticle*>&,
+                                   const met::METAssociator::ConstitHolder&) const
     {return StatusCode::FAILURE;} // should not be called
 
     private:
diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h
index 177feca2ed5db78e7989c621e122285b8b85a3be..60cacc269128f24f2a4ac90091dcaf762f9f36bd 100644
--- a/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h
+++ b/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h
@@ -54,15 +54,19 @@ namespace met{
     
     StatusCode executeTool(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap) const final;
     StatusCode extractTopoClusters(const xAOD::IParticle* obj,
-				   std::vector<const xAOD::IParticle*>& tclist,
-				   const met::METAssociator::ConstitHolder& constits) const final;
+                                   std::vector<const xAOD::IParticle*>& tclist,
+                                   const met::METAssociator::ConstitHolder& constits) const final;
     StatusCode extractPFO(const xAOD::IParticle* obj,
-			  std::vector<const xAOD::IParticle*>& pfolist,
-			  const met::METAssociator::ConstitHolder& constits,
-			  std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final;
+                          std::vector<const xAOD::IParticle*>& pfolist,
+                          const met::METAssociator::ConstitHolder& constits,
+                          std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final;
+    StatusCode extractFE(const xAOD::IParticle* obj,
+                         std::vector<const xAOD::IParticle*>& felist,
+                         const met::METAssociator::ConstitHolder& constits,
+                         std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final;
     StatusCode extractTracks(const xAOD::IParticle* obj,
-			     std::vector<const xAOD::IParticle*>& constlist,
-			     const met::METAssociator::ConstitHolder& constits) const final;
+                             std::vector<const xAOD::IParticle*>& constlist,
+                             const met::METAssociator::ConstitHolder& constits) const final;
 
     private:
 
diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METSoftAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METSoftAssociator.h
index e371d63cfea9af763b090dcefd3b0585cfecd90f..d833630d07dfb8e40bdcb1fb91c0647c4caf101f 100644
--- a/Reconstruction/MET/METReconstruction/METReconstruction/METSoftAssociator.h
+++ b/Reconstruction/MET/METReconstruction/METReconstruction/METSoftAssociator.h
@@ -54,17 +54,22 @@ namespace met{
     StatusCode executeTool(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap) const final;
 
     StatusCode extractPFO(const xAOD::IParticle*,
-			  std::vector<const xAOD::IParticle*>&,
-			  const met::METAssociator::ConstitHolder&,
-			  std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t>&) const final
+                          std::vector<const xAOD::IParticle*>&,
+                          const met::METAssociator::ConstitHolder&,
+                          std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t>&) const final
+    {return StatusCode::FAILURE;} // should not be called
+    StatusCode extractFE(const xAOD::IParticle*,
+                         std::vector<const xAOD::IParticle*>&,
+                         const met::METAssociator::ConstitHolder&,
+                         std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t>&) const final
     {return StatusCode::FAILURE;} // should not be called
     StatusCode extractTracks(const xAOD::IParticle*,
-			     std::vector<const xAOD::IParticle*>&,
-			     const met::METAssociator::ConstitHolder&) const final
+                             std::vector<const xAOD::IParticle*>&,
+                             const met::METAssociator::ConstitHolder&) const final
     {return StatusCode::FAILURE;} // should not be called
     StatusCode extractTopoClusters(const xAOD::IParticle*,
-				   std::vector<const xAOD::IParticle*>&,
-				   const met::METAssociator::ConstitHolder&) const final
+                                   std::vector<const xAOD::IParticle*>&,
+                                   const met::METAssociator::ConstitHolder&) const final
     {return StatusCode::FAILURE;} // should not be called
 
     private:
diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METSoftTermsTool.h b/Reconstruction/MET/METReconstruction/METReconstruction/METSoftTermsTool.h
index b206bb0aef81681a9e0b5b85b59b2f2fa66e0dc7..58432ce9c00e0987c9bdce89f981585ba4fa8455 100644
--- a/Reconstruction/MET/METReconstruction/METReconstruction/METSoftTermsTool.h
+++ b/Reconstruction/MET/METReconstruction/METReconstruction/METSoftTermsTool.h
@@ -1,7 +1,7 @@
 ///////////////////////// -*- C++ -*- /////////////////////////////
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // METSoftTermsTool.h 
@@ -10,6 +10,9 @@
 // This is a scheduler for the MET Reconstruction, and sets up
 // the sequence in which the individual terms are constructed.
 //
+// Note that this tool is now quite outdated and should be used only
+// for basic monitoring purposes.
+//
 //  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 //
 // Author: P Loch, S Resconi, TJ Khoo
@@ -26,14 +29,10 @@
 //Framework includes
 #include "StoreGate/DataHandle.h"
 
-// Forward declaration
-#include "xAODCaloEvent/CaloClusterFwd.h"
-#include "xAODTracking/TrackParticleFwd.h"
-
-// PFlow EDM and helpers
-#include "xAODPFlow/PFOContainer.h"
-#include "PFlowUtils/IRetrievePFOTool.h"
-
+//#include "xAODCaloEvent/CaloClusterFwd.h"
+#include "xAODCaloEvent/CaloClusterContainer.h"
+//#include "xAODTracking/TrackParticleFwd.h"
+#include "xAODTracking/TrackParticleContainer.h"
 
 namespace met{
 
@@ -43,11 +42,7 @@ namespace met{
     // This macro defines the constructor with the interface declaration
     ASG_TOOL_CLASS(METSoftTermsTool, IMETToolBase)
 
-
-    /////////////////////////////////////////////////////////////////// 
-    // Public methods: 
-    /////////////////////////////////////////////////////////////////// 
-    public: 
+  public: 
 
     // Constructor with name (does this have to be a non-const
     // std::string and not a const reference?)
@@ -58,24 +53,12 @@ namespace met{
     StatusCode  initialize();
     StatusCode  finalize();
 
-    /////////////////////////////////////////////////////////////////// 
-    // Const methods: 
-    ///////////////////////////////////////////////////////////////////
-
-    /////////////////////////////////////////////////////////////////// 
-    // Non-const methods: 
-    /////////////////////////////////////////////////////////////////// 
-
-    /////////////////////////////////////////////////////////////////// 
-    // Private data: 
-    /////////////////////////////////////////////////////////////////// 
   protected: 
     StatusCode  executeTool(xAOD::MissingET* metTerm, xAOD::MissingETComponentMap* metMap) const;
     // Accept functions
     bool accept            (const xAOD::IParticle* object) const;
     bool accept            (const xAOD::CaloCluster* clus) const;
     bool accept            (const xAOD::TrackParticle* trk) const;
-    bool accept            (const xAOD::PFO* pfo, const xAOD::Vertex* pv) const;
     // Overlap resolver function
     bool resolveOverlap    (const xAOD::IParticle* object,
                             xAOD::MissingETComponentMap* metMap,
@@ -89,27 +72,15 @@ namespace met{
     METSoftTermsTool();
     // Use Case - Clusters OR Tracks OR PFOs
     std::string m_inputType;
-    unsigned short m_st_objtype{0}; // should make this an enum somewhere
+    xAOD::Type::ObjectType m_st_objtype;
     // Cluster selection
     bool m_cl_vetoNegE;
     bool m_cl_onlyNegE;
-    // temporary, until a track-vertex association tool is available
-    //std::string m_pv_inputkey;
-    SG::ReadHandleKey<xAOD::VertexContainer>  m_pv_inputkey{this,"InputPVKey","PrimaryVertices",""};
     SG::ReadHandleKey<xAOD::CaloClusterContainer>  m_caloClusterKey{""};
     SG::ReadHandleKey<xAOD::TrackParticleContainer>  m_trackParticleKey{""};
 
-    ToolHandle<CP::IRetrievePFOTool> m_pfotool{this,"PFOTool","",""};
   }; 
 
 }
 
-// I/O operators
-//////////////////////
-
-/////////////////////////////////////////////////////////////////// 
-// Inline methods: 
-/////////////////////////////////////////////////////////////////// 
-
-
 #endif //> !METRECONSTRUCTION_METSOFTTERMSTOOL_H
diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h
index ade7512f6307086d897659b39e1d7c0d4ca6bc77..1a41e1a510d5f0ac56545b68af8ec7658e0362fb 100644
--- a/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h
+++ b/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h
@@ -56,17 +56,22 @@ namespace met{
 
     StatusCode executeTool(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap) const final;
     StatusCode extractTopoClusters(const xAOD::IParticle* obj,
-				   std::vector<const xAOD::IParticle*>& tclist,
-				   const met::METAssociator::ConstitHolder& constits) const final;
+                                   std::vector<const xAOD::IParticle*>& tclist,
+                                   const met::METAssociator::ConstitHolder& constits) const final;
 
     StatusCode extractPFO(const xAOD::IParticle* obj,
-			  std::vector<const xAOD::IParticle*>& pfolist,
-			  const met::METAssociator::ConstitHolder& constits,
-			  std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final;
+                          std::vector<const xAOD::IParticle*>& pfolist,
+                          const met::METAssociator::ConstitHolder& constits,
+                          std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final;
+
+    StatusCode extractFE(const xAOD::IParticle* obj,
+                         std::vector<const xAOD::IParticle*>& felist,
+                         const met::METAssociator::ConstitHolder& constits,
+                         std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final;
     
     StatusCode extractTracks(const xAOD::IParticle* obj,
-			     std::vector<const xAOD::IParticle*>& constlist,
-			     const met::METAssociator::ConstitHolder& constits) const final;
+                             std::vector<const xAOD::IParticle*>& constlist,
+                             const met::METAssociator::ConstitHolder& constits) const final;
 
     private:
  
diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METTruthAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METTruthAssociator.h
index 093c518d5ba42573cc3a6ad54ceda496ec77bec7..d25652b0ba60328c02cc9c1779c33aae10240ec5 100644
--- a/Reconstruction/MET/METReconstruction/METReconstruction/METTruthAssociator.h
+++ b/Reconstruction/MET/METReconstruction/METReconstruction/METTruthAssociator.h
@@ -57,36 +57,41 @@ namespace met{
     protected: 
 
     StatusCode fillAssocMap(xAOD::MissingETAssociationMap* metMap,
-			    const xAOD::IParticleContainer* hardObjs) const final;
+                            const xAOD::IParticleContainer* hardObjs) const final;
     StatusCode executeTool(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap) const;
     //
     StatusCode associateJets(xAOD::MissingETAssociationMap* metMap) const;
     //
     StatusCode extractTruthParticles(const xAOD::IParticle* obj,
-				     std::vector<const xAOD::IParticle*>& truthlist) const;
+                                     std::vector<const xAOD::IParticle*>& truthlist) const;
     StatusCode extractTruthFromElectron(const xAOD::IParticle* obj,
-					std::vector<const xAOD::IParticle*>& truthlist) const;
+                                        std::vector<const xAOD::IParticle*>& truthlist) const;
     StatusCode extractTruthFromPhoton(const xAOD::IParticle* obj,
-				      std::vector<const xAOD::IParticle*>& truthlist) const;
+                                      std::vector<const xAOD::IParticle*>& truthlist) const;
     StatusCode extractTruthFromMuon(const xAOD::IParticle* obj,
-				    std::vector<const xAOD::IParticle*>& truthlist) const;
+                                    std::vector<const xAOD::IParticle*>& truthlist) const;
     StatusCode extractTruthFromTau(const xAOD::IParticle* obj,
-				     std::vector<const xAOD::IParticle*>& truthlist) const;
+                                     std::vector<const xAOD::IParticle*>& truthlist) const;
     //
     StatusCode computeSoftTerms(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap) const;
     //
     StatusCode extractPFO(const xAOD::IParticle*,
-			  std::vector<const xAOD::IParticle*>&,
-			  const met::METAssociator::ConstitHolder&,
-			  std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t>&) const final
+                          std::vector<const xAOD::IParticle*>&,
+                          const met::METAssociator::ConstitHolder&,
+                          std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t>&) const final
+    {return StatusCode::FAILURE;} // should not be called
+    StatusCode extractFE(const xAOD::IParticle*,
+                         std::vector<const xAOD::IParticle*>&,
+                         const met::METAssociator::ConstitHolder&,
+                         std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t>&) const final
     {return StatusCode::FAILURE;} // should not be called
     StatusCode extractTracks(const xAOD::IParticle*,
-			     std::vector<const xAOD::IParticle*>&,
-			     const met::METAssociator::ConstitHolder&) const final
+                             std::vector<const xAOD::IParticle*>&,
+                             const met::METAssociator::ConstitHolder&) const final
     {return StatusCode::FAILURE;} // should not be called
     StatusCode extractTopoClusters(const xAOD::IParticle*,
-				   std::vector<const xAOD::IParticle*>&,
-				   const met::METAssociator::ConstitHolder&) const final
+                                   std::vector<const xAOD::IParticle*>&,
+                                   const met::METAssociator::ConstitHolder&) const final
     {return StatusCode::FAILURE;} // should not be called
 
     private:
diff --git a/Reconstruction/MET/METReconstruction/Root/METAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METAssociator.cxx
index 20b1a7a925a7243bdcd78f74a52d3887a9a84856..a26caa214dd30ee10571b65d75227589298cd926 100644
--- a/Reconstruction/MET/METReconstruction/Root/METAssociator.cxx
+++ b/Reconstruction/MET/METReconstruction/Root/METAssociator.cxx
@@ -61,7 +61,7 @@ namespace met {
     declareProperty( "PrimVxColl",         m_pvcoll      = "PrimaryVertices"     );
     declareProperty( "TrkColl",            m_trkcoll     = "InDetTrackParticles" );
     declareProperty( "ClusColl",           m_clcoll      = "CaloCalTopoClusters" );
-    declareProperty( "UseModifiedClus",    m_useModifiedClus = false            );
+    declareProperty( "UseModifiedClus",    m_useModifiedClus = false             );
     declareProperty( "UseTracks",          m_useTracks   = true                  );
     declareProperty( "PFlow",              m_pflow       = false                 );
     declareProperty( "UseRapidity",        m_useRapidity = false                 );
@@ -69,7 +69,7 @@ namespace met {
     declareProperty( "TrackIsolationTool", m_trkIsolationTool                    );
     declareProperty( "CaloIsolationTool",  m_caloIsolationTool                   );
     declareProperty( "IgnoreJetConst",     m_skipconst = false                   );
-    declareProperty( "ForwardColl",        m_forcoll   = ""                       );
+    declareProperty( "ForwardColl",        m_forcoll   = ""                      );
     declareProperty( "ForwardDef",         m_foreta    = 2.5                     );
     declareProperty( "CentralTrackPtThr",  m_cenTrackPtThr = 30e+3               );
     declareProperty( "ForwardTrackPtThr",  m_forTrackPtThr = 30e+3               );
@@ -93,17 +93,17 @@ namespace met {
 
     if(m_clcoll == "CaloCalTopoClusters") {
       if(m_useModifiedClus) {
-	ATH_MSG_ERROR("Configured to use modified topocluster collection but \"CaloCalTopoClusters\" collection specified!");
-	return StatusCode::FAILURE;
+        ATH_MSG_ERROR("Configured to use modified topocluster collection but \"CaloCalTopoClusters\" collection specified!");
+        return StatusCode::FAILURE;
       } else {
-	ATH_MSG_INFO("Configured to use standard topocluster collection.");
+        ATH_MSG_INFO("Configured to use standard topocluster collection.");
       }
     } else {
       if(m_useModifiedClus) {
-	ATH_MSG_INFO("Configured to use modified topocluster collection \"" << m_clcoll << "\".");
+        ATH_MSG_INFO("Configured to use modified topocluster collection \"" << m_clcoll << "\".");
       } else {
-	ATH_MSG_ERROR("Configured to use topocluster collection \"" << m_clcoll << "\", but modified clusters flag not set!");
-	return StatusCode::FAILURE;
+        ATH_MSG_ERROR("Configured to use topocluster collection \"" << m_clcoll << "\", but modified clusters flag not set!");
+        return StatusCode::FAILURE;
       }
     }
 
@@ -114,7 +114,11 @@ namespace met {
       ATH_CHECK( m_trkcollKey.assign(m_trkcoll));
       ATH_CHECK( m_trkcollKey.initialize());
     }
-    if(m_pflow){
+    if(!m_fecollKey.key().empty()){
+      ATH_CHECK(m_fecollKey.initialize());
+      ATH_MSG_INFO("Configured to use FlowElement collection \"" << m_fecollKey.key() << "\".");
+    }
+    else if(m_pflow){
       ATH_CHECK( m_pfcollKey.initialize());
       if(m_pfcollKey.key() == "JetETMissParticleFlowObjects") {
         ATH_MSG_ERROR("Configured to use standard pflow collection \"" << m_pfcollKey.key() << "\".");
@@ -151,8 +155,8 @@ namespace met {
       ATH_MSG_WARNING("Invalid pointer to MissingETAssociationMap supplied! Abort.");
       return StatusCode::FAILURE;
     }
-    if(m_pflow && !m_useTracks ){
-      ATH_MSG_WARNING("Attempting to build PFlow without a track collection.");
+    if((m_pflow || !m_fecollKey.key().empty())&& !m_useTracks ){
+      ATH_MSG_WARNING("Attempting to build PFlow/FlowElement MET without a track collection.");
       return StatusCode::FAILURE;
     }
 
@@ -231,8 +235,8 @@ namespace met {
     }else{
       SG::ReadHandle<VertexContainer> vxCont(m_pvcollKey);
       if (!vxCont.isValid()) {
-	ATH_MSG_WARNING("Unable to retrieve primary vertex container " << m_pvcoll);
-	//this is actually really bad.  If it's empty that's okay
+        ATH_MSG_WARNING("Unable to retrieve primary vertex container " << m_pvcoll);
+        //this is actually really bad.  If it's empty that's okay
         return StatusCode::FAILURE;
       }
 
@@ -240,31 +244,41 @@ namespace met {
       ATH_MSG_DEBUG("Container holds " << vxCont->size() << " vertices");
 
       for(const auto& vx : *vxCont) {
-	ATH_MSG_VERBOSE( "Testing vertex " << vx->index() );
-	if(vx->vertexType()==VxType::PriVtx)
-	  {constits.pv = vx; break;}
+        ATH_MSG_VERBOSE( "Testing vertex " << vx->index() );
+        if(vx->vertexType()==VxType::PriVtx)
+          {constits.pv = vx; break;}
       }
       if(!constits.pv) {
-	ATH_MSG_DEBUG("Failed to find primary vertex! Reject all tracks.");
+        ATH_MSG_DEBUG("Failed to find primary vertex! Reject all tracks.");
       } else {
-	ATH_MSG_VERBOSE("Primary vertex has z = " << constits.pv->z());
+        ATH_MSG_VERBOSE("Primary vertex has z = " << constits.pv->z());
       }
 
       constits.trkCont=0;
       ATH_MSG_DEBUG("Retrieving Track collection " << m_trkcoll);
       SG::ReadHandle<TrackParticleContainer> trCont(m_trkcollKey);
       if (!trCont.isValid()) {
-	ATH_MSG_WARNING("Unable to retrieve track particle container");
+        ATH_MSG_WARNING("Unable to retrieve track particle container");
         return StatusCode::FAILURE;
       }
       constits.trkCont=trCont.cptr();
 
-      if(m_pflow) {
-	ATH_MSG_DEBUG("Retrieving PFlow collection " << m_pfcollKey.key());
-	constits.pfoCont = 0;
+      if(!m_fecollKey.key().empty()){
+        ATH_MSG_DEBUG("Retrieving FlowElement collection " << m_fecollKey.key());
+        constits.feCont = 0;
+        SG::ReadHandle<xAOD::FlowElementContainer> feCont(m_fecollKey);
+        if (!feCont.isValid()) {
+          ATH_MSG_ERROR("Unable to retrieve FlowElement container");
+          return StatusCode::FAILURE;
+        }
+        constits.feCont=feCont.cptr();
+      }
+      else if(m_pflow) {
+        ATH_MSG_DEBUG("Retrieving PFlow collection " << m_pfcollKey.key());
+        constits.pfoCont = 0;
         SG::ReadHandle<PFOContainer> pfCont(m_pfcollKey);
         if (!pfCont.isValid()) {
-	  ATH_MSG_WARNING("Unable to PFlow object container");
+          ATH_MSG_WARNING("Unable to PFlow object container");
           return StatusCode::FAILURE;
         }
         constits.pfoCont=pfCont.cptr();
@@ -285,7 +299,7 @@ namespace met {
   ///////////////////////////////////////////////////////////////////
 
   StatusCode METAssociator::fillAssocMap(xAOD::MissingETAssociationMap* metMap,
-					 const xAOD::IParticleContainer* hardObjs) const
+                                         const xAOD::IParticleContainer* hardObjs) const
   {
     ConstitHolder constits;
 
@@ -306,28 +320,37 @@ namespace met {
       if(obj->pt()<5e3 && obj->type()!=xAOD::Type::Muon) continue;
       constlist.clear();
       ATH_MSG_VERBOSE( "Object type, pt, eta, phi = " << obj->type() << ", " << obj->pt() << ", " << obj->eta() << "," << obj->phi() );
-      if (m_pflow) {
-	if(!m_useTracks){
-	  ATH_MSG_DEBUG("Attempting to build PFlow without a track collection.");
-	  return StatusCode::FAILURE;
-	}else{
-	  std::map<const IParticle*,MissingETBase::Types::constvec_t> momentumOverride;
-	  ATH_CHECK( this->extractPFO(obj,constlist,constits,momentumOverride) );
-	  MissingETComposition::insert(metMap,obj,constlist,momentumOverride);
-	}
+      if(!m_fecollKey.key().empty()){
+        if(!m_useTracks){
+          ATH_MSG_ERROR("Attempting to build FlowElement MET without a track collection.");
+          return StatusCode::FAILURE;
+        }
+        std::map<const IParticle*, MissingETBase::Types::constvec_t> momentumOverride;
+        ATH_CHECK( this->extractFE(obj, constlist, constits, momentumOverride) );
+        MissingETComposition::insert(metMap, obj, constlist, momentumOverride);
+      }
+      else if (m_pflow) {
+        if(!m_useTracks){
+          ATH_MSG_DEBUG("Attempting to build PFlow without a track collection.");
+          return StatusCode::FAILURE;
+        }else{
+          std::map<const IParticle*,MissingETBase::Types::constvec_t> momentumOverride;
+          ATH_CHECK( this->extractPFO(obj,constlist,constits,momentumOverride) );
+          MissingETComposition::insert(metMap,obj,constlist,momentumOverride);
+        }
       } else {
-	std::vector<const IParticle*> tclist;
-	tclist.reserve(20);
+        std::vector<const IParticle*> tclist;
+        tclist.reserve(20);
         ATH_CHECK( this->extractTopoClusters(obj,tclist,constits) );
-	if(m_useModifiedClus) {
-	  for(const auto& cl : tclist) {
-	    // use index-parallelism to identify shallow copied constituents
-	    constlist.push_back((*constits.tcCont)[cl->index()]);
-	  }
-	} else {
-	  constlist = tclist;
-	}
-	if(m_useTracks) ATH_CHECK( this->extractTracks(obj,constlist,constits) );
+        if(m_useModifiedClus) {
+          for(const auto& cl : tclist) {
+            // use index-parallelism to identify shallow copied constituents
+            constlist.push_back((*constits.tcCont)[cl->index()]);
+          }
+        } else {
+          constlist = tclist;
+        }
+        if(m_useTracks) ATH_CHECK( this->extractTracks(obj,constlist,constits) );
         MissingETComposition::insert(metMap,obj,constlist);
       }
     }
@@ -348,7 +371,7 @@ namespace met {
   {
 
     if( (fabs(trk->eta())<1.5 && trk->pt()>m_cenTrackPtThr) ||
-	(fabs(trk->eta())>=1.5 && trk->pt()>m_forTrackPtThr) ) {
+        (fabs(trk->eta())>=1.5 && trk->pt()>m_forTrackPtThr) ) {
 
       // Get relative error on qoverp
       float Rerr = Amg::error(trk->definingParametersCovMatrix(),4)/fabs(trk->qOverP());
@@ -363,9 +386,9 @@ namespace met {
       xAOD::TrackCorrection trkIsoCorr;
       trkIsoCorr.trackbitset.set(xAOD::Iso::IsolationTrackCorrection::coreTrackPtr); 
       m_trkIsolationTool->trackIsolation(trkIsoResult,
-					 *trk,
-					 trkIsoCones,
-					 trkIsoCorr);
+                                         *trk,
+                                         trkIsoCones,
+                                         trkIsoCorr);
       ptcone20 = trkIsoResult.ptcones.size() > 0 ? trkIsoResult.ptcones[0] : 0;
       isolfrac = ptcone20/trk->pt();
       // etcone
@@ -378,15 +401,15 @@ namespace met {
       xAOD::CaloCorrection caloIsoCorr_coreCone;
       caloIsoCorr_coreCone.calobitset.set(xAOD::Iso::IsolationCaloCorrection::coreCone); // this is etcone10
       m_caloIsolationTool->caloTopoClusterIsolation(caloIsoResult,
-						    *trk,
-						    caloIsoCones,
-						    caloIsoCorr_coreCone);
+                                                    *trk,
+                                                    caloIsoCones,
+                                                    caloIsoCorr_coreCone);
       if(caloIsoResult.etcones.size() > 0) {
-	// retrieve the correction value for the core cone
-	etcone10 = caloIsoResult.coreCorrections[xAOD::Iso::IsolationCaloCorrection::coreCone][xAOD::Iso::IsolationCorrectionParameter::coreEnergy];
+        // retrieve the correction value for the core cone
+        etcone10 = caloIsoResult.coreCorrections[xAOD::Iso::IsolationCaloCorrection::coreCone][xAOD::Iso::IsolationCorrectionParameter::coreEnergy];
       } else {
-	ATH_MSG_WARNING("isGoodEoverP: Failed to retrieve the isolation core correction (etcone10)! Setting etcone10=0");
-	etcone10 = 0.;
+        ATH_MSG_WARNING("isGoodEoverP: Failed to retrieve the isolation core correction (etcone10)! Setting etcone10=0");
+        etcone10 = 0.;
       }
       EoverP   =  etcone10/trk->pt(); 
       /////////////////////////////////////////////////////////////////////////
@@ -394,13 +417,13 @@ namespace met {
       ATH_MSG_VERBOSE( "Track E/P = " << EoverP );
 
       if(isolfrac<0.1) {
-	    // isolated track cuts
-	    if(Rerr>0.4) return false;
-	    else if (EoverP<0.65 && ((EoverP>0.1 && Rerr>0.05) || Rerr>0.1)) return false;
+            // isolated track cuts
+            if(Rerr>0.4) return false;
+            else if (EoverP<0.65 && ((EoverP>0.1 && Rerr>0.05) || Rerr>0.1)) return false;
       } else {
-	    // non-isolated track cuts
-	    float trkptsum = ptcone20+trk->pt();
-	    if(etcone10/trkptsum<0.6 && trk->pt()/trkptsum>0.6) return false;
+            // non-isolated track cuts
+            float trkptsum = ptcone20+trk->pt();
+            if(etcone10/trkptsum<0.6 && trk->pt()/trkptsum>0.6) return false;
       }
     }
     return true;
diff --git a/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx
index c69c6977dba2625f59972293a9d100d394e20804..92f077f6ae757949ed488e2e346c68a7ef442b9e 100644
--- a/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx
+++ b/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx
@@ -88,8 +88,8 @@ namespace met {
   //**********************************************************************
   // Get Egamma constituents
   StatusCode METEgammaAssociator::extractTopoClusters(const xAOD::IParticle* obj,
-						      std::vector<const xAOD::IParticle*>& tclist,
-						      const met::METAssociator::ConstitHolder& constits) const
+                                                      std::vector<const xAOD::IParticle*>& tclist,
+                                                      const met::METAssociator::ConstitHolder& constits) const
   {
     const Egamma *eg = static_cast<const Egamma*>(obj);
     // safe to assume a single SW cluster?
@@ -104,11 +104,11 @@ namespace met {
     
     if(m_tcMatch_method==DeltaR) {
       for(const auto& cl : *constits.tcCont) {
-	// this can probably be done more elegantly
-	if(P4Helpers::isInDeltaR(*swclus,*cl,m_tcMatch_dR,m_useRapidity) && cl->e()>FLT_MIN) {
-	  // could consider also requirements on the EM fraction or depth
-	  inputTC.push_back(cl);
-	} // match TC in a cone around SW cluster
+        // this can probably be done more elegantly
+        if(P4Helpers::isInDeltaR(*swclus,*cl,m_tcMatch_dR,m_useRapidity) && cl->e()>FLT_MIN) {
+          // could consider also requirements on the EM fraction or depth
+          inputTC.push_back(cl);
+        } // match TC in a cone around SW cluster
       }
       ATH_MSG_VERBOSE("Found " << inputTC.size() << " nearby topoclusters");
       std::sort(inputTC.begin(),inputTC.end(),greaterPt);
@@ -116,7 +116,7 @@ namespace met {
       static const SG::AuxElement::ConstAccessor<std::vector<ElementLink<CaloClusterContainer> > > tcLinkAcc("constituentClusterLinks");
       // Fill a vector of vectors
       for(const auto& el : tcLinkAcc(*swclus)) {
-	inputTC.push_back(*el);
+        inputTC.push_back(*el);
       }
       ATH_MSG_VERBOSE("Found " << inputTC.size() << " linked topoclusters");
     } else {
@@ -131,24 +131,24 @@ namespace met {
 
 
   StatusCode METEgammaAssociator::extractTracks(const xAOD::IParticle* obj,
-						std::vector<const xAOD::IParticle*>& constlist,
-						const met::METAssociator::ConstitHolder& constits) const
+                                                std::vector<const xAOD::IParticle*>& constlist,
+                                                const met::METAssociator::ConstitHolder& constits) const
   {
     const xAOD::Egamma *eg = static_cast<const xAOD::Egamma*>(obj);
     std::set<const xAOD::TrackParticle*> trackset; // use a set for duplicate-free retrieval
     ATH_CHECK( selectEgammaTracks(eg, constits.trkCont, trackset) );
     for(const auto& track : trackset) {
       if(acceptTrack(track,constits.pv) && isGoodEoverP(track)) {
-	constlist.push_back(track);
+        constlist.push_back(track);
       }
     }
     return StatusCode::SUCCESS;
   }
 
   StatusCode METEgammaAssociator::extractPFO(const xAOD::IParticle* obj,
-					     std::vector<const xAOD::IParticle*>& pfolist,
-					     const met::METAssociator::ConstitHolder& constits,
-					     std::map<const IParticle*,MissingETBase::Types::constvec_t> &/*momenta*/) const
+                                             std::vector<const xAOD::IParticle*>& pfolist,
+                                             const met::METAssociator::ConstitHolder& constits,
+                                             std::map<const IParticle*,MissingETBase::Types::constvec_t> &/*momenta*/) const
   {
     const xAOD::Egamma *eg = static_cast<const xAOD::Egamma*>(obj);
     // safe to assume a single SW cluster?
@@ -160,15 +160,15 @@ namespace met {
     nearbyPFO.reserve(20);
     for(const auto& pfo : *constits.pfoCont) {
       if(P4Helpers::isInDeltaR(*pfo, *swclus, 0.4, m_useRapidity)) {
-	// We set a small -ve pt for cPFOs that were rejected
-	// by the ChargedHadronSubtractionTool
-	const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");	
-	if( ( !pfo->isCharged() && pfo->e() > FLT_MIN ) ||
-	    ( pfo->isCharged() && PVMatchedAcc(*pfo)
-	      && ( !m_cleanChargedPFO || isGoodEoverP(pfo->track(0)) ) )
-	    ) {
-	  nearbyPFO.push_back(pfo);
-	} // retain +ve E neutral PFOs and charged PFOs passing PV association
+        // We set a small -ve pt for cPFOs that were rejected
+        // by the ChargedHadronSubtractionTool
+        const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");        
+        if( ( !pfo->isCharged() && pfo->e() > FLT_MIN ) ||
+            ( pfo->isCharged() && PVMatchedAcc(*pfo)
+              && ( !m_cleanChargedPFO || isGoodEoverP(pfo->track(0)) ) )
+            ) {
+          nearbyPFO.push_back(pfo);
+        } // retain +ve E neutral PFOs and charged PFOs passing PV association
       } // DeltaR check
     } // PFO loop
     ATH_MSG_VERBOSE("Found " << nearbyPFO.size() << " nearby pfos");
@@ -177,9 +177,9 @@ namespace met {
     ATH_CHECK( selectEgammaTracks(eg, constits.trkCont, trackset) );
     for(const auto& track : trackset) {
       for(const auto& pfo : nearbyPFO) {
-	if(pfo->isCharged() && pfo->track(0) == track) {
-	  pfolist.push_back(pfo);
-	} // PFO/track match
+        if(pfo->isCharged() && pfo->track(0) == track) {
+          pfolist.push_back(pfo);
+        } // PFO/track match
       } // PFO loop
     } // Track loop
     double eg_cl_e = swclus->e();
@@ -200,35 +200,118 @@ namespace met {
       // skip cluster if it's above our bad match threshold or outside the matching radius
       if(pfo_e>m_tcMatch_maxRat*eg_cl_e) {
         ATH_MSG_VERBOSE("Reject topocluster in sum. Ratio vs eg cluster: " << (pfo_e/eg_cl_e));
-    	if( !bestbadmatch || (fabs(pfo_e/eg_cl_e-1.) < fabs(bestbadmatch->e()/eg_cl_e-1.)) ) bestbadmatch = pfo;
-	continue;
+            if( !bestbadmatch || (fabs(pfo_e/eg_cl_e-1.) < fabs(bestbadmatch->e()/eg_cl_e-1.)) ) bestbadmatch = pfo;
+        continue;
       }
 
       ATH_MSG_VERBOSE("E match with new nPFO: " << fabs(sumE_pfo+pfo_e - eg_cl_e) / eg_cl_e);
       if( (doSum = fabs(sumE_pfo+pfo_e-eg_cl_e) < fabs(sumE_pfo - eg_cl_e)) ) {
-	pfolist.push_back(pfo);
-	sumE_pfo += pfo_e;
-    	ATH_MSG_VERBOSE("Accept pfo with pt " << pfo->pt() << ", e " << pfo->e() << " in sum.");
-    	ATH_MSG_VERBOSE("Energy ratio of nPFO to eg: " << pfo_e / eg_cl_e);
-    	ATH_MSG_VERBOSE("E match with new PFO: " << fabs(sumE_pfo+pfo_e - eg_cl_e) / eg_cl_e);
+        pfolist.push_back(pfo);
+        sumE_pfo += pfo_e;
+            ATH_MSG_VERBOSE("Accept pfo with pt " << pfo->pt() << ", e " << pfo->e() << " in sum.");
+            ATH_MSG_VERBOSE("Energy ratio of nPFO to eg: " << pfo_e / eg_cl_e);
+            ATH_MSG_VERBOSE("E match with new PFO: " << fabs(sumE_pfo+pfo_e - eg_cl_e) / eg_cl_e);
       } // if we will retain the topocluster
       else {break;}
     } // loop over nearby clusters
     if(sumE_pfo<FLT_MIN && bestbadmatch) {
       ATH_MSG_VERBOSE("No better matches found -- add bad match topocluster with pt "
-    		      << bestbadmatch->pt() << ", e " << bestbadmatch->e() << ".");
+                          << bestbadmatch->pt() << ", e " << bestbadmatch->e() << ".");
       pfolist.push_back(bestbadmatch);
     }
 
     return StatusCode::SUCCESS;
   }
 
+  StatusCode METEgammaAssociator::extractFE(const xAOD::IParticle* obj,
+                                            std::vector<const xAOD::IParticle*>& felist,
+                                            const met::METAssociator::ConstitHolder& constits,
+                                            std::map<const IParticle*,MissingETBase::Types::constvec_t> &/*momenta*/) const
+  {
+    const xAOD::Egamma *eg = static_cast<const xAOD::Egamma*>(obj);
+    // safe to assume a single SW cluster?
+    // will do so for now...
+    const xAOD::IParticle* swclus = eg->caloCluster();
+
+    // Preselect PFOs based on proximity: dR<0.4
+    std::vector<const xAOD::FlowElement*> nearbyFE;
+    nearbyFE.reserve(20);
+    for(const xAOD::FlowElement* fe : *constits.feCont) {
+      if(!(fe->signalType() & xAOD::FlowElement::PFlow)){
+        ATH_MSG_ERROR("Attempted to extract non-PFlow FlowElements. This is not supported!");
+        return StatusCode::FAILURE;
+      }
+      if(P4Helpers::isInDeltaR(*fe, *swclus, 0.4, m_useRapidity)) {
+        // We set a small -ve pt for cPFOs that were rejected
+        // by the ChargedHadronSubtractionTool
+        const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");        
+        if( ( !fe->isCharged() && fe->e() > FLT_MIN ) ||
+            ( fe->isCharged() && PVMatchedAcc(*fe)
+              && ( !m_cleanChargedPFO || isGoodEoverP(static_cast<const xAOD::TrackParticle*>(fe->chargedObject(0))) ) )
+            ) {
+          nearbyFE.push_back(fe);
+        } // retain +ve E neutral PFOs and charged PFOs passing PV association
+      } // DeltaR check
+    } // PFO loop
+    ATH_MSG_VERBOSE("Found " << nearbyFE.size() << " nearby FlowElements (PFOs)");
+
+    std::set<const xAOD::TrackParticle*> trackset; // use a set for duplicate-free retrieval
+    ATH_CHECK( selectEgammaTracks(eg, constits.trkCont, trackset) );
+    for(const xAOD::TrackParticle* track : trackset) {
+      for(const xAOD::FlowElement* fe : nearbyFE) {
+        if(fe->isCharged() && fe->chargedObject(0) == track) {
+          felist.push_back(fe);
+        } // PFO/track match
+      } // PFO loop
+    } // Track loop
+    double eg_cl_e = swclus->e();
+
+    // the matching strategy depends on how the cluster container is sorted
+    // easier if it's sorted in descending pt order
+    // ideally this should be done using cell matching, but we can't use the links from topoclusters reliably
+    // because some PFOs don't correspond to the original TC
+    bool doSum = true;
+    double sumE_pfo = 0.;
+    const IParticle* bestbadmatch = 0;
+    std::sort(nearbyFE.begin(),nearbyFE.end(),greaterPtFE);
+    for(const xAOD::FlowElement* fe : nearbyFE) {
+      // Skip charged PFOs, as we already matched them
+      if(fe->isCharged() || !P4Helpers::isInDeltaR(*fe, *swclus, m_tcMatch_dR, m_useRapidity)) continue;
+      // Handle neutral PFOs like topoclusters
+      // TODO: Use EM-scale energy here in the future? No way to access from FlowElement in general.
+      double pfo_e = fe->e();
+      // skip cluster if it's above our bad match threshold or outside the matching radius
+      if(pfo_e > m_tcMatch_maxRat*eg_cl_e) {
+        ATH_MSG_VERBOSE("Reject topocluster in sum. Ratio vs eg cluster: " << (pfo_e/eg_cl_e));
+        if( !bestbadmatch || (fabs(pfo_e/eg_cl_e-1.) < fabs(bestbadmatch->e()/eg_cl_e-1.)) ) bestbadmatch = fe;
+        continue;
+      }
+
+      ATH_MSG_VERBOSE("E match with new nPFO: " << fabs(sumE_pfo+pfo_e - eg_cl_e) / eg_cl_e);
+      if( (doSum = fabs(sumE_pfo+pfo_e-eg_cl_e) < fabs(sumE_pfo - eg_cl_e)) ) {
+        felist.push_back(fe);
+        sumE_pfo += pfo_e;
+        ATH_MSG_VERBOSE("Accept pfo with pt " << fe->pt() << ", e " << fe->e() << " in sum.");
+        ATH_MSG_VERBOSE("Energy ratio of nPFO to eg: " << pfo_e / eg_cl_e);
+        ATH_MSG_VERBOSE("E match with new PFO: " << fabs(sumE_pfo+pfo_e - eg_cl_e) / eg_cl_e);
+      } // if we will retain the topocluster
+      else break;
+    } // loop over nearby clusters
+    if(sumE_pfo<FLT_MIN && bestbadmatch) {
+      ATH_MSG_VERBOSE("No better matches found -- add bad match topocluster with pt "
+                          << bestbadmatch->pt() << ", e " << bestbadmatch->e() << ".");
+      felist.push_back(bestbadmatch);
+    }
+
+    return StatusCode::SUCCESS;
+  }
+
   //**********************************************************************
   // Select Egamma tracks & clusters
 
   StatusCode METEgammaAssociator::selectEgammaClusters(const xAOD::CaloCluster* swclus,
-						       const std::vector<const IParticle*>& inputTC,
-						       std::vector<const xAOD::IParticle*>& tclist) const
+                                                       const std::vector<const IParticle*>& inputTC,
+                                                       std::vector<const xAOD::IParticle*>& tclist) const
   {    
     double eg_cl_e = swclus->e();
 
@@ -240,38 +323,38 @@ namespace met {
       // skip cluster if it's above our bad match threshold
       // retain pointer of the closest matching cluster in case no better is found
       if(tcl_e>m_tcMatch_maxRat*eg_cl_e) {
-    	ATH_MSG_VERBOSE("Reject topocluster in sum. Ratio vs eg cluster: " << (tcl_e/eg_cl_e));
-    	if( !bestbadmatch || (fabs(tcl_e/eg_cl_e-1.) < fabs(bestbadmatch->e()/eg_cl_e-1.)) ) bestbadmatch = cl;
-    	continue;
+            ATH_MSG_VERBOSE("Reject topocluster in sum. Ratio vs eg cluster: " << (tcl_e/eg_cl_e));
+            if( !bestbadmatch || (fabs(tcl_e/eg_cl_e-1.) < fabs(bestbadmatch->e()/eg_cl_e-1.)) ) bestbadmatch = cl;
+            continue;
       }
 
       ATH_MSG_VERBOSE("E match with new cluster: " << fabs(sumE_tc+tcl_e - eg_cl_e) / eg_cl_e);
       if( (doSum = (fabs(sumE_tc+tcl_e - eg_cl_e) < fabs(sumE_tc - eg_cl_e))) ) {
-    	ATH_MSG_VERBOSE("Accept topocluster with pt " << cl->pt() << ", e " << cl->e() << " in sum.");
-    	ATH_MSG_VERBOSE("Energy ratio of nPFO to eg: " << tcl_e / eg_cl_e);
-    	ATH_MSG_VERBOSE("E match with new cluster: " << fabs(sumE_tc+tcl_e - eg_cl_e) / eg_cl_e);
-    	tclist.push_back(cl);
-    	sumE_tc += tcl_e;
+            ATH_MSG_VERBOSE("Accept topocluster with pt " << cl->pt() << ", e " << cl->e() << " in sum.");
+            ATH_MSG_VERBOSE("Energy ratio of nPFO to eg: " << tcl_e / eg_cl_e);
+            ATH_MSG_VERBOSE("E match with new cluster: " << fabs(sumE_tc+tcl_e - eg_cl_e) / eg_cl_e);
+            tclist.push_back(cl);
+            sumE_tc += tcl_e;
       } // if we will retain the topocluster
     } // loop over nearby clusters
     if(sumE_tc<FLT_MIN && bestbadmatch) {
       ATH_MSG_VERBOSE("No better matches found -- add bad match topocluster with pt "
-    		      << bestbadmatch->pt() << ", e " << bestbadmatch->e() << ".");
+                          << bestbadmatch->pt() << ", e " << bestbadmatch->e() << ".");
       tclist.push_back(bestbadmatch);
     }
     return StatusCode::SUCCESS;
   }
 
   StatusCode METEgammaAssociator::selectEgammaTracks(const xAOD::Egamma* eg,
-						     const xAOD::TrackParticleContainer* trkCont,
-						     std::set<const xAOD::TrackParticle*>& tracklist) const
+                                                     const xAOD::TrackParticleContainer* trkCont,
+                                                     std::set<const xAOD::TrackParticle*>& tracklist) const
   {
     // switch to using egamma helpers for track extraction
     // set ensures that there's no duplication
     const std::set<const xAOD::TrackParticle*> egtracks = EgammaHelpers::getTrackParticles(eg);
     for(const auto& track : egtracks) {
-	ATH_MSG_VERBOSE("Accept " << eg->type() << " track " << track << " px, py = " << track->p4().Px() << ", " << track->p4().Py());
-	tracklist.insert(track);
+        ATH_MSG_VERBOSE("Accept " << eg->type() << " track " << track << " px, py = " << track->p4().Px() << ", " << track->p4().Py());
+        tracklist.insert(track);
     } // end initial egamma track loop
 
     // for objects with ambiguous author, grab the tracks matched to the counterpart ambiguous object too
@@ -279,44 +362,44 @@ namespace met {
     if (eg->author() & xAOD::EgammaParameters::AuthorAmbiguous && eg->ambiguousObject()) {
       const std::set<const xAOD::TrackParticle*> ambitracks = EgammaHelpers::getTrackParticles(eg->ambiguousObject());
       for(const auto& track : egtracks) {
-	ATH_MSG_VERBOSE("Accept ambiguous " << eg->type() << " track " << track << " px, py = " << track->p4().Px() << ", " << track->p4().Py());
-	tracklist.insert(track);
+        ATH_MSG_VERBOSE("Accept ambiguous " << eg->type() << " track " << track << " px, py = " << track->p4().Px() << ", " << track->p4().Py());
+        tracklist.insert(track);
       }
     } // end ambiguous track case
 
     // in a small dR window, also accept tracks without an IBL hit
     for(const auto& track : *trkCont) {
       if(P4Helpers::isInDeltaR(*track, *eg, m_extraTrkMatch_dR, m_useRapidity)) {
-	// dR check should be faster than track summary retrieval
-	uint8_t expect_innermostHit(false);
-	uint8_t N_innermostHit(false);
-	uint8_t expect_nextToInnermostHit(false);
-	uint8_t N_nextToInnermostHit(false);
-	if( !track->summaryValue(expect_innermostHit, expectInnermostPixelLayerHit)
-	    || !track->summaryValue(expect_nextToInnermostHit, expectNextToInnermostPixelLayerHit)) {
-	  ATH_MSG_WARNING("Track summary retrieval failed for 'expect(NextTo)InnermostPixelLayerHit'");
-	  return StatusCode::FAILURE;
-	}
-	if(expect_innermostHit) {
-	  if( !track->summaryValue(N_innermostHit, numberOfInnermostPixelLayerHits) ) {
-	    ATH_MSG_WARNING("Track summary retrieval failed for 'numberOfInnermostPixelLayerHits'");
-	    return StatusCode::FAILURE;
-	    if(N_innermostHit==0 ) {
-	      ATH_MSG_VERBOSE("Accept nearby track w/o innermost hit");
-	      tracklist.insert(track);
-	    }
-	  }
-	} else if(expect_nextToInnermostHit) {
-	  if( !track->summaryValue(N_nextToInnermostHit, numberOfNextToInnermostPixelLayerHits) ) {
-	    ATH_MSG_WARNING("Track summary retrieval failed for 'numberOfNextToInnermostPixelLayerHits'");
-	    return StatusCode::FAILURE;
-	    if(N_nextToInnermostHit==0 ) {
-	      ATH_MSG_VERBOSE("Accept nearby track w/o next-to-innermost hit");
-	      tracklist.insert(track);
-	    }
-	  }
-	}
-	
+        // dR check should be faster than track summary retrieval
+        uint8_t expect_innermostHit(false);
+        uint8_t N_innermostHit(false);
+        uint8_t expect_nextToInnermostHit(false);
+        uint8_t N_nextToInnermostHit(false);
+        if( !track->summaryValue(expect_innermostHit, expectInnermostPixelLayerHit)
+            || !track->summaryValue(expect_nextToInnermostHit, expectNextToInnermostPixelLayerHit)) {
+          ATH_MSG_WARNING("Track summary retrieval failed for 'expect(NextTo)InnermostPixelLayerHit'");
+          return StatusCode::FAILURE;
+        }
+        if(expect_innermostHit) {
+          if( !track->summaryValue(N_innermostHit, numberOfInnermostPixelLayerHits) ) {
+            ATH_MSG_WARNING("Track summary retrieval failed for 'numberOfInnermostPixelLayerHits'");
+            return StatusCode::FAILURE;
+            if(N_innermostHit==0 ) {
+              ATH_MSG_VERBOSE("Accept nearby track w/o innermost hit");
+              tracklist.insert(track);
+            }
+          }
+        } else if(expect_nextToInnermostHit) {
+          if( !track->summaryValue(N_nextToInnermostHit, numberOfNextToInnermostPixelLayerHits) ) {
+            ATH_MSG_WARNING("Track summary retrieval failed for 'numberOfNextToInnermostPixelLayerHits'");
+            return StatusCode::FAILURE;
+            if(N_nextToInnermostHit==0 ) {
+              ATH_MSG_VERBOSE("Accept nearby track w/o next-to-innermost hit");
+              tracklist.insert(track);
+            }
+          }
+        }
+        
       } // end dR check
     } // end extra track loop
     return StatusCode::SUCCESS;
diff --git a/Reconstruction/MET/METReconstruction/Root/METJetAssocTool.cxx b/Reconstruction/MET/METReconstruction/Root/METJetAssocTool.cxx
index 04f995d3105c570ad9299d0133f1180a071316b4..8fb15c6b2061e321999355753c3d7d90a0d72abc 100644
--- a/Reconstruction/MET/METReconstruction/Root/METJetAssocTool.cxx
+++ b/Reconstruction/MET/METReconstruction/Root/METJetAssocTool.cxx
@@ -1,7 +1,7 @@
 ///////////////////////// -*- C++ -*- /////////////////////////////
 
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // METJetAssocTool.cxx
@@ -72,20 +72,6 @@ namespace met {
     return StatusCode::SUCCESS;
   }
 
-  ///////////////////////////////////////////////////////////////////
-  // Const methods:
-  ///////////////////////////////////////////////////////////////////
-
-  ///////////////////////////////////////////////////////////////////
-  // Non-const methods:
-  ///////////////////////////////////////////////////////////////////
-
-  ///////////////////////////////////////////////////////////////////
-  // Protected methods:
-  ///////////////////////////////////////////////////////////////////
-
-  // executeTool
-  ////////////////
   StatusCode METJetAssocTool::executeTool(xAOD::MissingETContainer* /*metCont*/, xAOD::MissingETAssociationMap* metMap) const
   {
     ATH_MSG_VERBOSE ("In execute: " << name() << "...");
@@ -113,30 +99,43 @@ namespace met {
     // Create jet associations
     for(const auto& jet : *jetCont) {
       std::vector<const IParticle*> selectedTracks;
-      bool mismatchedPFlow = m_pflow && jet->rawConstituent(0)->type()!=xAOD::Type::ParticleFlow;
+      bool mismatchedPFlow = m_pflow && (jet->rawConstituent(0)->type()!=xAOD::Type::ParticleFlow && jet->rawConstituent(0)->type()!=xAOD::Type::FlowElement);
       bool mismatchedState = !m_skipconst && !m_pflow && jet->rawConstituent(0)->type()==xAOD::Type::CaloCluster && ((static_cast<const xAOD::CaloCluster*>(jet->rawConstituent(0))->signalState()==xAOD::CaloCluster::CALIBRATED && jet->getConstituentsSignalState()==xAOD::UncalibratedJetConstituent) || (static_cast<const xAOD::CaloCluster*>(jet->rawConstituent(0))->signalState()==xAOD::CaloCluster::UNCALIBRATED && jet->getConstituentsSignalState()==xAOD::CalibratedJetConstituent));
       bool newConstVec = m_skipconst || mismatchedPFlow || mismatchedState;
       if (m_pflow && !mismatchedPFlow) {
-        for (size_t consti = 0; consti < jet->numConstituents(); consti++) {
-          const xAOD::PFO *pfo = static_cast<const xAOD::PFO*>(jet->rawConstituent(consti));
-	  ATH_MSG_VERBOSE("Jet constituent PFO, pt :" << pfo->pt() << ", charge: " << pfo->charge());
-          if (pfo->isCharged() && (!m_cleanChargedPFO || isGoodEoverP(pfo->track(0)))) {
-	    ATH_MSG_VERBOSE("  Accepted charged PFO, pt " << pfo->pt());
-	    selectedTracks.push_back(pfo);
-	  }
+        if(jet->rawConstituent(0)->type() == xAOD::Type::FlowElement){
+          for (size_t consti = 0; consti < jet->numConstituents(); consti++) {
+            const xAOD::FlowElement *pfo = static_cast<const xAOD::FlowElement*>(jet->rawConstituent(consti));
+            ATH_MSG_VERBOSE("Jet constituent PFO, pt :" << pfo->pt() << ", charge: " << pfo->charge());
+            if ((pfo->isCharged()) && (!m_cleanChargedPFO || isGoodEoverP(static_cast<const xAOD::TrackParticle*>(pfo->chargedObject(0))))) {
+              ATH_MSG_VERBOSE("  Accepted charged PFO, pt " << pfo->pt());
+              selectedTracks.push_back(pfo);
+            }
+          }
+        }
+        else{
+          // constituents are xAOD::PFO
+          for (size_t consti = 0; consti < jet->numConstituents(); consti++) {
+            const xAOD::PFO *pfo = static_cast<const xAOD::PFO*>(jet->rawConstituent(consti));
+            ATH_MSG_VERBOSE("Jet constituent PFO, pt :" << pfo->pt() << ", charge: " << pfo->charge());
+            if (pfo->isCharged() && (!m_cleanChargedPFO || isGoodEoverP(pfo->track(0)))) {
+              ATH_MSG_VERBOSE("  Accepted charged PFO, pt " << pfo->pt());
+              selectedTracks.push_back(pfo);
+            }
+          }
         }
       } else {
         std::vector<const IParticle*> jettracks;
         jet->getAssociatedObjects<IParticle>(JetAttribute::GhostTrack,jettracks);
 
-	selectedTracks.reserve(jettracks.size());
-	for(const auto& trk : jettracks) {
-	  const TrackParticle* pTrk = static_cast<const TrackParticle*>(trk);
+        selectedTracks.reserve(jettracks.size());
+        for(const auto& trk : jettracks) {
+          const TrackParticle* pTrk = static_cast<const TrackParticle*>(trk);
           if(acceptTrack(pTrk,constits.pv) && isGoodEoverP(pTrk)) {
-	    selectedTracks.push_back(trk);
-	    ATH_MSG_VERBOSE("Accept track " << trk << " px, py = " << trk->p4().Px() << ", " << trk->p4().Py());
-	  }
-	}
+            selectedTracks.push_back(trk);
+            ATH_MSG_VERBOSE("Accept track " << trk << " px, py = " << trk->p4().Px() << ", " << trk->p4().Py());
+          }
+        }
       }
       std::vector<const IParticle*> consts;
       std::map<const IParticle*,MissingETBase::Types::constvec_t> momenta;
@@ -157,44 +156,74 @@ namespace met {
   }
 
   void METJetAssocTool::getPFOs(const xAOD::Jet *jet,
-				std::vector<const xAOD::IParticle*> &consts,
-				const met::METAssociator::ConstitHolder& constits,
-				std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const {
+                                std::vector<const xAOD::IParticle*> &consts,
+                                const met::METAssociator::ConstitHolder& constits,
+                                std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const {
 
     std::vector<const IParticle*> jettracks;
     jet->getAssociatedObjects<IParticle>(JetAttribute::GhostTrack,jettracks);
 
-    for(const auto& pfo : *constits.pfoCont) {
-      if (pfo->isCharged()) {
-	const TrackParticle* pfotrk = pfo->track(0);
-	for(const auto& trk : jettracks) {
-	  if (trk==pfotrk) {
-	    consts.push_back(pfo);
-	    break;
-	  }
-	}
-      } else {
-        bool marked = false;
-        for (size_t consti = 0; consti < jet->numConstituents(); consti++) if (pfo->p4().DeltaR(jet->rawConstituent(consti)->p4())<0.05) marked = true;
-        if (marked) {
-          consts.push_back(pfo);
-          TLorentzVector momentum = pfo->p4();
-          momenta[pfo] = MissingETBase::Types::constvec_t(momentum.Px(),momentum.Py(),momentum.Pz(),
-							  momentum.E(),momentum.Pt());
+    if(constits.feCont != nullptr){
+      // We have PFOs in FlowElement format
+      for(const xAOD::FlowElement* pfo : *constits.feCont) {
+        if (pfo->isCharged()) {
+          const TrackParticle* pfotrk = static_cast<const xAOD::TrackParticle*>(pfo->chargedObject(0));
+          for(const xAOD::IParticle* track : jettracks) {
+            const TrackParticle* jettrk = static_cast<const xAOD::TrackParticle*>(track);
+            if (jettrk==pfotrk) {
+              consts.push_back(pfo);
+              break;
+            }
+          }
+        }
+        else {
+          bool marked = false;
+          for (size_t consti = 0; consti < jet->numConstituents(); consti++){
+            if (pfo->p4().DeltaR(jet->rawConstituent(consti)->p4())<0.05) marked = true;
+          }
+          if (marked) {
+            consts.push_back(pfo);
+            TLorentzVector momentum = pfo->p4();
+            momenta[pfo] = MissingETBase::Types::constvec_t(momentum.Px(),momentum.Py(),momentum.Pz(),
+                                                            momentum.E(),momentum.Pt());
+          }
+        }
+      }
+    }
+    else{
+      // No FlowElements, assume xAOD::PFO format
+      for(const auto& pfo : *constits.pfoCont) {
+        if (pfo->isCharged()) {
+          const TrackParticle* pfotrk = pfo->track(0);
+          for(const auto& trk : jettracks) {
+            if (trk==pfotrk) {
+              consts.push_back(pfo);
+              break;
+            }
+          }
+        } else {
+          bool marked = false;
+          for (size_t consti = 0; consti < jet->numConstituents(); consti++) if (pfo->p4().DeltaR(jet->rawConstituent(consti)->p4())<0.05) marked = true;
+          if (marked) {
+            consts.push_back(pfo);
+            TLorentzVector momentum = pfo->p4();
+            momenta[pfo] = MissingETBase::Types::constvec_t(momentum.Px(),momentum.Py(),momentum.Pz(),
+                                                            momentum.E(),momentum.Pt());
+          }
         }
       }
     }
   }
 
   void METJetAssocTool::getClus(const xAOD::Jet *jet,
-				std::vector<const xAOD::IParticle*> &consts) const {
+                                std::vector<const xAOD::IParticle*> &consts) const {
     std::vector<ElementLink<IParticleContainer> > jetconst = jet->constituentLinks();
     for(const auto& clus : jetconst) consts.push_back(*clus);
   }
 
   void METJetAssocTool::getOther(const xAOD::Jet *jet,
-				 std::vector<const xAOD::IParticle*> &consts,
-				 std::set<const xAOD::IParticle*> *newConst) const {
+                                 std::vector<const xAOD::IParticle*> &consts,
+                                 std::set<const xAOD::IParticle*> *newConst) const {
     std::vector<ElementLink<IParticleContainer> > jetconst = jet->constituentLinks();
     for(const auto& clus : *newConst) if (clus->container()!=jet->rawConstituent(0)->container() && clus->e()>0 && xAOD::P4Helpers::isInDeltaR(*jet,*clus,m_matchRadius,m_useRapidity)) consts.push_back(clus);
     //for(const auto& clus : *newConst) if (clus->type()!=jet->rawConstituent(0)->type() && clus->e()>0 && xAOD::P4Helpers::isInDeltaR(*jet,*clus,m_matchRadius,m_useRapidity)) consts.push_back(clus);
diff --git a/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx
index 4b87255a851c07b4713ca33b9dfc83e3ef9a79a5..7d00b4456544d38828796d906a5840303b07d4ec 100644
--- a/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx
+++ b/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx
@@ -99,32 +99,32 @@ namespace met {
   //*********************************************************************************************************
   // Get constituents
   StatusCode METMuonAssociator::extractTopoClusters(const xAOD::IParticle* obj,
-						    std::vector<const xAOD::IParticle*>& tclist,
-						    const met::METAssociator::ConstitHolder& /*constits*/) const
+                                                    std::vector<const xAOD::IParticle*>& tclist,
+                                                    const met::METAssociator::ConstitHolder& /*constits*/) const
   {
     const xAOD::Muon *mu = static_cast<const xAOD::Muon*>(obj);
     const CaloCluster* muclus = mu->cluster();
     if(muclus && m_doMuonClusterMatch) {
       ATH_MSG_VERBOSE("Muon " << mu->index() << " with pt " << mu->pt()
-		   << ", eta "   << mu->eta()
-		   << ", phi " << mu->phi()
-		   << " has cluster with "
-		   << "eta "   << muclus->calEta()
-		   << ", phi " << muclus->calPhi()
-		   << ", E "   << muclus->calE()
-		   << " formed of " << muclus->size() << " cells.");
+                   << ", eta "   << mu->eta()
+                   << ", phi " << mu->phi()
+                   << " has cluster with "
+                   << "eta "   << muclus->calEta()
+                   << ", phi " << muclus->calPhi()
+                   << ", E "   << muclus->calE()
+                   << " formed of " << muclus->size() << " cells.");
       ATH_MSG_VERBOSE("Muon Eloss type: " << mu->energyLossType()
-		   << " Eloss: " << mu->floatParameter(xAOD::Muon::EnergyLoss)
-		   << " MeasuredEloss: " << mu->floatParameter(xAOD::Muon::MeasEnergyLoss)
-		   << " FSR E: " << mu->floatParameter(xAOD::Muon::FSR_CandidateEnergy) );
+                   << " Eloss: " << mu->floatParameter(xAOD::Muon::EnergyLoss)
+                   << " MeasuredEloss: " << mu->floatParameter(xAOD::Muon::MeasEnergyLoss)
+                   << " FSR E: " << mu->floatParameter(xAOD::Muon::FSR_CandidateEnergy) );
       
       SG::ReadDecorHandle<CaloClusterContainer, std::vector<ElementLink<CaloClusterContainer> > > tcLinkAcc(m_elementLinkName); 
       for(const auto& matchel : tcLinkAcc(*muclus)) {
-	if(!matchel.isValid()) {continue;} // In case of thinned cluster collection
-	ATH_MSG_VERBOSE("Tool found cluster " << (*matchel)->index() << " with pt " << (*matchel)->pt() );
-	if((*matchel)->e()>1e-9) { // +ve E
-	  tclist.push_back(*matchel);
-	}
+        if(!matchel.isValid()) {continue;} // In case of thinned cluster collection
+        ATH_MSG_VERBOSE("Tool found cluster " << (*matchel)->index() << " with pt " << (*matchel)->pt() );
+        if((*matchel)->e()>1e-9) { // +ve E
+          tclist.push_back(*matchel);
+        }
       }
     } // muon has linked cluster
     
@@ -132,8 +132,8 @@ namespace met {
   }
 
   StatusCode METMuonAssociator::extractTracks(const xAOD::IParticle *obj,
-					      std::vector<const xAOD::IParticle*>& constlist,
-					      const met::METAssociator::ConstitHolder& constits) const
+                                              std::vector<const xAOD::IParticle*>& constlist,
+                                              const met::METAssociator::ConstitHolder& constits) const
   {
     const xAOD::Muon *mu = static_cast<const xAOD::Muon*>(obj);
     const TrackParticle* idtrack = mu->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
@@ -152,61 +152,123 @@ namespace met {
   //*********************************************************************************************************
   // Get constituents
   StatusCode METMuonAssociator::extractPFO(const xAOD::IParticle* obj,
-					   std::vector<const xAOD::IParticle*>& pfolist,
-					   const met::METAssociator::ConstitHolder& constits,
-					   std::map<const IParticle*,MissingETBase::Types::constvec_t>& /*momenta*/) const
+                                           std::vector<const xAOD::IParticle*>& pfolist,
+                                           const met::METAssociator::ConstitHolder& constits,
+                                           std::map<const IParticle*,MissingETBase::Types::constvec_t>& /*momenta*/) const
   {  
     const xAOD::Muon *mu = static_cast<const xAOD::Muon*>(obj);
     const TrackParticle* idtrack = mu->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
     const CaloCluster* muclus = mu->cluster();
 
     ATH_MSG_VERBOSE("Muon " << mu->index() << " with pt " << mu->pt()
-		    << ", eta "   << mu->eta()
-		    << ", phi " << mu->phi());
+                    << ", eta "   << mu->eta()
+                    << ", phi " << mu->phi());
     if(muclus) {
       ATH_MSG_VERBOSE(" has cluster with "
-		      << "eta "   << muclus->calEta()
-		      << ", phi " << muclus->calPhi()
-		      << ", E "   << muclus->calE()
-		      << " formed of " << muclus->size() << " cells.");
+                      << "eta "   << muclus->calEta()
+                      << ", phi " << muclus->calPhi()
+                      << ", E "   << muclus->calE()
+                      << " formed of " << muclus->size() << " cells.");
     }
     ATH_MSG_VERBOSE("Muon Eloss type: " << mu->energyLossType()
-		    << " Eloss: " << mu->floatParameter(xAOD::Muon::EnergyLoss)
-		    << " MeasuredEloss: " << mu->floatParameter(xAOD::Muon::MeasEnergyLoss)
-		    << " FSR E: " << mu->floatParameter(xAOD::Muon::FSR_CandidateEnergy) );
+                    << " Eloss: " << mu->floatParameter(xAOD::Muon::EnergyLoss)
+                    << " MeasuredEloss: " << mu->floatParameter(xAOD::Muon::MeasEnergyLoss)
+                    << " FSR E: " << mu->floatParameter(xAOD::Muon::FSR_CandidateEnergy) );
 
     // One loop over PFOs
     for(const auto& pfo : *constits.pfoCont) {
       if(pfo->isCharged()) {
-	// get charged PFOs by matching the muon ID track
-	// We set a small -ve pt for cPFOs that were rejected
-	// by the ChargedHadronSubtractionTool
-	const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");
-	if(idtrack && pfo->track(0) == idtrack && PVMatchedAcc(*pfo) &&
-	   ( !m_cleanChargedPFO || isGoodEoverP(pfo->track(0)) )
-	   ) {
-	  ATH_MSG_VERBOSE("Accept muon PFO " << pfo << " px, py = " << pfo->p4().Px() << ", " << pfo->p4().Py());
-	  ATH_MSG_VERBOSE("Muon PFO index: " << pfo->index() << ", pt: " << pfo->pt() << ", eta: " << pfo->eta() << ", phi: " << pfo->phi() );
-	  ATH_MSG_VERBOSE("Muon ID Track index: " << idtrack->index() << ", pt: " << idtrack->pt() << ", eta: " << idtrack->eta() << ", phi: " << idtrack->phi() );
-	  pfolist.push_back(pfo);
-	  break;
-	} // track match
+        // get charged PFOs by matching the muon ID track
+        // We set a small -ve pt for cPFOs that were rejected
+        // by the ChargedHadronSubtractionTool
+        const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");
+        if(idtrack && pfo->track(0) == idtrack && PVMatchedAcc(*pfo) &&
+           ( !m_cleanChargedPFO || isGoodEoverP(pfo->track(0)) )
+           ) {
+          ATH_MSG_VERBOSE("Accept muon PFO " << pfo << " px, py = " << pfo->p4().Px() << ", " << pfo->p4().Py());
+          ATH_MSG_VERBOSE("Muon PFO index: " << pfo->index() << ", pt: " << pfo->pt() << ", eta: " << pfo->eta() << ", phi: " << pfo->phi() );
+          ATH_MSG_VERBOSE("Muon ID Track index: " << idtrack->index() << ", pt: " << idtrack->pt() << ", eta: " << idtrack->eta() << ", phi: " << idtrack->phi() );
+          pfolist.push_back(pfo);
+          break;
+        } // track match
       } else {
-      	// get neutral PFOs by matching the muon cluster
-      	if(muclus && m_doMuonClusterMatch) {
-
-	  SG::ReadDecorHandle<CaloClusterContainer, std::vector<ElementLink<CaloClusterContainer> > > tcLinkAcc(m_elementLinkName); 
-      	  for(const auto& matchel : tcLinkAcc(*muclus)) {
-	    if(!matchel.isValid()) {
-	      ATH_MSG_DEBUG("Invalid muon-cluster elementLink");
-	    } else {
-	      if((*matchel)->e()>FLT_MIN && pfo->cluster(0) == *matchel) { // +ve E && matches cluster
-		ATH_MSG_VERBOSE("Tool found cluster " << (*matchel)->index() << " with pt " << (*matchel)->pt() );
-		pfolist.push_back(pfo);
-	      }
-	    }
-      	  }
-      	} // muon has linked cluster
+        // get neutral PFOs by matching the muon cluster
+        if(muclus && m_doMuonClusterMatch) {
+
+          SG::ReadDecorHandle<CaloClusterContainer, std::vector<ElementLink<CaloClusterContainer> > > tcLinkAcc(m_elementLinkName); 
+                for(const auto& matchel : tcLinkAcc(*muclus)) {
+            if(!matchel.isValid()) {
+              ATH_MSG_DEBUG("Invalid muon-cluster elementLink");
+            } else {
+              if((*matchel)->e()>FLT_MIN && pfo->cluster(0) == *matchel) { // +ve E && matches cluster
+                ATH_MSG_VERBOSE("Tool found cluster " << (*matchel)->index() << " with pt " << (*matchel)->pt() );
+                pfolist.push_back(pfo);
+              }
+            }
+          }
+        } // muon has linked cluster
+      } 
+    } // end of cluster loop
+
+    return StatusCode::SUCCESS;
+  }
+
+  StatusCode METMuonAssociator::extractFE(const xAOD::IParticle* obj,
+                                          std::vector<const xAOD::IParticle*>& felist,
+                                          const met::METAssociator::ConstitHolder& constits,
+                                          std::map<const IParticle*,MissingETBase::Types::constvec_t>& /*momenta*/) const
+  {  
+    const xAOD::Muon *mu = static_cast<const xAOD::Muon*>(obj);
+    const TrackParticle* idtrack = mu->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
+    const CaloCluster* muclus = mu->cluster();
+
+    ATH_MSG_VERBOSE("Muon " << mu->index() << " with pt " << mu->pt()
+                    << ", eta "   << mu->eta()
+                    << ", phi " << mu->phi());
+    if(muclus) {
+      ATH_MSG_VERBOSE(" has cluster with "
+                      << "eta "   << muclus->calEta()
+                      << ", phi " << muclus->calPhi()
+                      << ", E "   << muclus->calE()
+                      << " formed of " << muclus->size() << " cells.");
+    }
+    ATH_MSG_VERBOSE("Muon Eloss type: " << mu->energyLossType()
+                    << " Eloss: " << mu->floatParameter(xAOD::Muon::EnergyLoss)
+                    << " MeasuredEloss: " << mu->floatParameter(xAOD::Muon::MeasEnergyLoss)
+                    << " FSR E: " << mu->floatParameter(xAOD::Muon::FSR_CandidateEnergy) );
+
+    // One loop over PFOs
+    for(const xAOD::FlowElement* fe : *constits.feCont) {
+      if(fe->isCharged()) {
+        // get charged FEs by matching the muon ID track
+        // We set a small -ve pt for cPFOs that were rejected
+        // by the ChargedHadronSubtractionTool
+        const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");
+        if(idtrack && fe->chargedObject(0) == idtrack && PVMatchedAcc(*fe) &&
+           ( !m_cleanChargedPFO || isGoodEoverP(static_cast<const xAOD::TrackParticle*>(fe->chargedObject(0))) )
+           ) {
+          ATH_MSG_VERBOSE("Accept muon PFO (FE) " << fe << " px, py = " << fe->p4().Px() << ", " << fe->p4().Py());
+          ATH_MSG_VERBOSE("Muon PFO index: " << fe->index() << ", pt: " << fe->pt() << ", eta: " << fe->eta() << ", phi: " << fe->phi() );
+          ATH_MSG_VERBOSE("Muon ID Track index: " << idtrack->index() << ", pt: " << idtrack->pt() << ", eta: " << idtrack->eta() << ", phi: " << idtrack->phi() );
+          felist.push_back(fe);
+          break;
+        } // track match
+      } else {
+        // get neutral PFOs by matching the muon cluster
+        if(muclus && m_doMuonClusterMatch) {
+
+          SG::ReadDecorHandle<CaloClusterContainer, std::vector<ElementLink<CaloClusterContainer> > > tcLinkAcc(m_elementLinkName); 
+          for(const auto& matchel : tcLinkAcc(*muclus)) {
+            if(!matchel.isValid()) {
+              ATH_MSG_DEBUG("Invalid muon-cluster elementLink");
+            } else {
+              if((*matchel)->e()>FLT_MIN && fe->otherObject(0) == *matchel) { // +ve E && matches cluster
+                ATH_MSG_VERBOSE("Tool found cluster " << (*matchel)->index() << " with pt " << (*matchel)->pt() );
+                felist.push_back(fe);
+              }
+            }
+          }
+        } // muon has linked cluster
       } 
     } // end of cluster loop
 
diff --git a/Reconstruction/MET/METReconstruction/Root/METSoftAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METSoftAssociator.cxx
index 0681270d3d11e5c475753cdbac7a15bfc8e459dd..ee4a4e315ca09972bbed3ef7b82976adf7d52b48 100644
--- a/Reconstruction/MET/METReconstruction/Root/METSoftAssociator.cxx
+++ b/Reconstruction/MET/METReconstruction/Root/METSoftAssociator.cxx
@@ -89,7 +89,45 @@ namespace met {
       return StatusCode::FAILURE;
     }
 
-    if (m_pflow) {
+    if(!m_fecollKey.key().empty()){
+      // PFOs have been provided as FlowElements
+      const IParticleContainer* uniquePFOs = metMap->getUniqueSignals(constits.pfoCont,MissingETBase::UsageHandler::Policy::ParticleFlow);
+      if(m_decorateSoftTermConst) {
+        dec_softConst(*metCoreTrk) = std::vector<ElementLink<IParticleContainer> >();
+        dec_softConst(*metCoreTrk).reserve(uniquePFOs->size());
+        dec_softConst(*metCoreCl) = std::vector<ElementLink<IParticleContainer> >();
+        dec_softConst(*metCoreCl).reserve(uniquePFOs->size());
+      }
+      for(const IParticle* sig : *uniquePFOs) {
+        const xAOD::FlowElement *pfo = static_cast<const xAOD::FlowElement*>(sig);
+        if (pfo->isCharged()) { // Charged PFOs
+          // We set a small -ve pt for cPFOs that were rejected
+          // by the ChargedHadronSubtractionTool
+          const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");        
+          if (PVMatchedAcc(*pfo) && ( !m_cleanChargedPFO || isGoodEoverP(static_cast<const xAOD::TrackParticle*>(pfo->chargedObject(0))) ) ) {
+            // For the TST, we add the track pt, as this need not be
+            // corrected for nearby energy in the calo
+            *metCoreTrk += pfo->chargedObject(0);
+            // For CST we add the PFO pt, which is weighted down
+            // to account for energy in the calo that may not have
+            // been subtracted
+            *metCoreCl  += sig;
+            if(m_decorateSoftTermConst) {
+              dec_softConst(*metCoreTrk).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(sig->container()),sig->index()));
+              dec_softConst(*metCoreCl).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(sig->container()),sig->index()));
+            }
+          }
+        } else { // Neutral PFOs
+          if (pfo->e()>FLT_MIN) {
+            // This is a non-issue; just add the four-vector
+             *metCoreCl += sig;
+             if(m_decorateSoftTermConst) dec_softConst(*metCoreCl).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(sig->container()),sig->index()));
+          }
+        }
+      }
+      delete uniquePFOs;
+    }
+    else if (m_pflow) {
       const IParticleContainer* uniquePFOs = metMap->getUniqueSignals(constits.pfoCont,MissingETBase::UsageHandler::Policy::ParticleFlow);
       if(m_decorateSoftTermConst) {
         dec_softConst(*metCoreTrk) = std::vector<ElementLink<IParticleContainer> >();
@@ -98,31 +136,31 @@ namespace met {
         dec_softConst(*metCoreCl).reserve(uniquePFOs->size());
       }
       for(const auto& sig : *uniquePFOs) {
-	const PFO *pfo = static_cast<const PFO*>(sig);
-	if (pfo->isCharged()) { // Charged PFOs
-	  // We set a small -ve pt for cPFOs that were rejected
-	  // by the ChargedHadronSubtractionTool
-	  const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");	
-	  if (PVMatchedAcc(*pfo) && ( !m_cleanChargedPFO || isGoodEoverP(pfo->track(0)) ) ) {
-	    // For the TST, we add the track pt, as this need not be
-	    // corrected for nearby energy in the calo
-	    *metCoreTrk += pfo->track(0);
-	    // For CST we add the PFO pt, which is weighted down
-	    // to account for energy in the calo that may not have
-	    // been subtracted
-	    *metCoreCl  += sig;
-	    if(m_decorateSoftTermConst) {
-	      dec_softConst(*metCoreTrk).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(sig->container()),sig->index()));
-	      dec_softConst(*metCoreCl).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(sig->container()),sig->index()));
-	    }
-	  }
-	} else { // Neutral PFOs
-	  if (pfo->e()>FLT_MIN) {
-	    // This is a non-issue; just add the four-vector
- 	    *metCoreCl += sig;
- 	    if(m_decorateSoftTermConst) dec_softConst(*metCoreCl).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(sig->container()),sig->index()));
-	  }
-	}
+        const PFO *pfo = static_cast<const PFO*>(sig);
+        if (pfo->isCharged()) { // Charged PFOs
+          // We set a small -ve pt for cPFOs that were rejected
+          // by the ChargedHadronSubtractionTool
+          const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");        
+          if (PVMatchedAcc(*pfo) && ( !m_cleanChargedPFO || isGoodEoverP(pfo->track(0)) ) ) {
+            // For the TST, we add the track pt, as this need not be
+            // corrected for nearby energy in the calo
+            *metCoreTrk += pfo->track(0);
+            // For CST we add the PFO pt, which is weighted down
+            // to account for energy in the calo that may not have
+            // been subtracted
+            *metCoreCl  += sig;
+            if(m_decorateSoftTermConst) {
+              dec_softConst(*metCoreTrk).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(sig->container()),sig->index()));
+              dec_softConst(*metCoreCl).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(sig->container()),sig->index()));
+            }
+          }
+        } else { // Neutral PFOs
+          if (pfo->e()>FLT_MIN) {
+            // This is a non-issue; just add the four-vector
+             *metCoreCl += sig;
+             if(m_decorateSoftTermConst) dec_softConst(*metCoreCl).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(sig->container()),sig->index()));
+          }
+        }
       }
       delete uniquePFOs;
     } else {
@@ -140,44 +178,44 @@ namespace met {
       SG::ReadHandle<xAOD::CaloClusterContainer> emtc(m_emmodclus_key);
 
       for(const auto& cl : *uniqueClusters) {
-	if (cl->e()>FLT_MIN) {
-	  if(m_useModifiedClus) {
-	    if(lctc.isValid() && emtc.isValid()) {
-	      size_t cl_idx(cl->index());
-	      // clusters at LC scale
-	      *metCoreCl += (*lctc)[cl_idx];
-	      if(m_decorateSoftTermConst) dec_softConst(*metCoreCl).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(lctc.cptr()),cl->index()));
-	      // clusters at EM scale
-	      *metCoreEMCl += (*emtc)[cl_idx];
-	    } else {
-	      ATH_MSG_WARNING("Invalid LC/EM modified cluster collections -- cannot add cluster to soft term!");
-	    }
-	  } else {
-	    // clusters at LC scale
-	    if (cl->type()==xAOD::Type::CaloCluster) {
+        if (cl->e()>FLT_MIN) {
+          if(m_useModifiedClus) {
+            if(lctc.isValid() && emtc.isValid()) {
+              size_t cl_idx(cl->index());
+              // clusters at LC scale
+              *metCoreCl += (*lctc)[cl_idx];
+              if(m_decorateSoftTermConst) dec_softConst(*metCoreCl).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(lctc.cptr()),cl->index()));
+              // clusters at EM scale
+              *metCoreEMCl += (*emtc)[cl_idx];
+            } else {
+              ATH_MSG_WARNING("Invalid LC/EM modified cluster collections -- cannot add cluster to soft term!");
+            }
+          } else {
+            // clusters at LC scale
+            if (cl->type()==xAOD::Type::CaloCluster) {
         CaloVertexedClusterBase stateClLC(*(static_cast<const CaloCluster*>(cl)),xAOD::CaloCluster::CALIBRATED);
-	      *metCoreCl += (&stateClLC);
-	    } else *metCoreCl += cl;
-	    if(m_decorateSoftTermConst) dec_softConst(*metCoreCl).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(cl->container()),cl->index()));
-	    // clusters at EM scale
-	    if (cl->type()==xAOD::Type::CaloCluster) {
+              *metCoreCl += (&stateClLC);
+            } else *metCoreCl += cl;
+            if(m_decorateSoftTermConst) dec_softConst(*metCoreCl).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(cl->container()),cl->index()));
+            // clusters at EM scale
+            if (cl->type()==xAOD::Type::CaloCluster) {
         CaloVertexedClusterBase stateClEM( *(static_cast<const CaloCluster*>(cl)),xAOD::CaloCluster::UNCALIBRATED);
         *metCoreEMCl += (&stateClEM);
-	    } else *metCoreEMCl += cl;
-	  }
-	}
+            } else *metCoreEMCl += cl;
+          }
+        }
       }
 
       if(constits.pv) {
-	for(const auto& trk : *uniqueTracks) {
-	  ATH_MSG_VERBOSE("Test core track with pt " << trk->pt());
-	  if(acceptTrack(static_cast<const TrackParticle*>(trk),constits.pv) && isGoodEoverP(static_cast<const TrackParticle*>(trk))) {
-	    ATH_MSG_VERBOSE("Add core track with pt " << trk->pt());
-	    *metCoreTrk += trk;
-	    if(m_decorateSoftTermConst) dec_softConst(*metCoreTrk).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(trk->container()),trk->index()));
-
-	  }
-	}
+        for(const auto& trk : *uniqueTracks) {
+          ATH_MSG_VERBOSE("Test core track with pt " << trk->pt());
+          if(acceptTrack(static_cast<const TrackParticle*>(trk),constits.pv) && isGoodEoverP(static_cast<const TrackParticle*>(trk))) {
+            ATH_MSG_VERBOSE("Add core track with pt " << trk->pt());
+            *metCoreTrk += trk;
+            if(m_decorateSoftTermConst) dec_softConst(*metCoreTrk).push_back(ElementLink<IParticleContainer>(*static_cast<const IParticleContainer*>(trk->container()),trk->index()));
+
+          }
+        }
       }
       delete uniqueClusters;
       delete uniqueTracks;
diff --git a/Reconstruction/MET/METReconstruction/Root/METSoftTermsTool.cxx b/Reconstruction/MET/METReconstruction/Root/METSoftTermsTool.cxx
index 9364356484b7ea07157d8be9fcc3457a4a93e29a..84d4eee35b2ef912bfe7ca504c21a374b29afdce 100644
--- a/Reconstruction/MET/METReconstruction/Root/METSoftTermsTool.cxx
+++ b/Reconstruction/MET/METReconstruction/Root/METSoftTermsTool.cxx
@@ -30,7 +30,6 @@
 // Calo helpers
 #include "xAODCaloEvent/CaloVertexedClusterBase.h"
 
-
 namespace met {
 
   using std::vector;
@@ -44,26 +43,18 @@ namespace met {
   using xAOD::CaloCluster;
   using xAOD::CaloClusterContainer;
   //
-  using xAOD::PFO;
-  using xAOD::PFOContainer;
-  //
   using xAOD::MissingET;
   using xAOD::MissingETComposition;
   using xAOD::MissingETComponent;
   using xAOD::MissingETComponentMap;
 
-  /////////////////////////////////////////////////////////////////// 
-  // Public methods: 
-  /////////////////////////////////////////////////////////////////// 
-
   // Constructors
   ////////////////
   METSoftTermsTool::METSoftTermsTool(const std::string& name) : 
     AsgTool(name),
     METBuilderTool(name)
   {
-    declareProperty( "InputComposition", m_inputType = "Clusters" ); // Options : Clusters (default) OR Tracks OR PFOs
-    //declareProperty( "InputPVKey",      m_pv_inputkey = "PrimaryVertices"    );
+    declareProperty( "InputComposition", m_inputType = "Clusters" ); // Options : Clusters (default) OR Tracks
     declareProperty( "VetoNegEClus",     m_cl_vetoNegE = true     );
     declareProperty( "OnlyNegEClus",     m_cl_onlyNegE = false    );
   }
@@ -81,29 +72,20 @@ namespace met {
     ATH_MSG_VERBOSE ("Initializing " << name() << "...");
 
     // use string property and convert to int?
-    if(m_inputType == "Clusters")    m_st_objtype = 0;
-    else if(m_inputType == "Tracks") m_st_objtype = 1;
-    else if(m_inputType == "PFlow") {
-      m_st_objtype = 2;
-      if( m_pfotool.retrieve().isFailure() ) {
-	ATH_MSG_FATAL("Failed to retrieve tool: " << m_pfotool->name());
-	return StatusCode::FAILURE;
-      };
-    }
+    if(m_inputType == "Clusters")    m_st_objtype = xAOD::Type::CaloCluster;
+    else if(m_inputType == "Tracks") m_st_objtype = xAOD::Type::TrackParticle;
     else {
       ATH_MSG_FATAL("Invalid input collection type " << m_inputType << " supplied!");
     }
-    // ReadHandleKey(s)
 
-    ATH_CHECK( m_pv_inputkey.initialize() );
-    if(m_st_objtype==0){
+    // ReadHandleKey(s)
+    if(m_st_objtype==xAOD::Type::CaloCluster){
       ATH_CHECK( m_caloClusterKey.assign(m_input_data_key));
       ATH_CHECK( m_caloClusterKey.initialize());
     }
-    else if(m_st_objtype==1){
+    else if(m_st_objtype==xAOD::Type::TrackParticle){
       ATH_CHECK( m_trackParticleKey.assign(m_input_data_key));
       ATH_CHECK( m_trackParticleKey.initialize());
-
     }
     return StatusCode::SUCCESS;
   }
@@ -115,54 +97,30 @@ namespace met {
     return StatusCode::SUCCESS;
   }
 
-  /////////////////////////////////////////////////////////////////// 
-  // Const methods: 
-  ///////////////////////////////////////////////////////////////////
-
-  /////////////////////////////////////////////////////////////////// 
-  // Non-const methods: 
-  /////////////////////////////////////////////////////////////////// 
-
-  /////////////////////////////////////////////////////////////////// 
-  // Protected methods: 
-  /////////////////////////////////////////////////////////////////// 
-
   // Will need to have different treatments here for clusters and tracks
   bool METSoftTermsTool::accept(const xAOD::IParticle* object) const
   {
+
+    if(object->type() != m_st_objtype){
+      ATH_MSG_WARNING("Type mismatch: Expected " << m_st_objtype << ", given " << object->type());
+      return false;
+    }
+
     // Apply cuts 
-    if ( m_st_objtype==0 ) {
+    if ( m_st_objtype == xAOD::Type::CaloCluster ) {
       ATH_MSG_VERBOSE("Check if cluster is accepted");
 
-      if(object->type()!=xAOD::Type::CaloCluster) {
-	ATH_MSG_WARNING("Expected CaloCluster, given " << object->type());
-	return false;
-      }
       const xAOD::CaloCluster* clus = static_cast<const xAOD::CaloCluster*>(object);
       return (clus) ? accept(clus) : false;
 
     } // end of if using clusters 
-    else if (  m_st_objtype==1 ) {
+    else if (  m_st_objtype == xAOD::Type::TrackParticle ) {
       ATH_MSG_VERBOSE("Check if track is accepted");
 
-      if(object->type()!=xAOD::Type::TrackParticle) {
-	ATH_MSG_WARNING("Expected TrackParticle, given " << object->type());
-	return false;
-      }
       const xAOD::TrackParticle* track = static_cast<const xAOD::TrackParticle*>(object);
       return (track) ? accept(track) : false;
 
     } // end of if using tracks
-    else if (  m_st_objtype==2 ) {
-      ATH_MSG_VERBOSE("Check if PFO is accepted");
-
-      if(object->type()!=xAOD::Type::ParticleFlow) {
-	ATH_MSG_WARNING("Expected PFlow Object, given " << object->type());
-	return false;
-      }
-
-      ATH_MSG_ERROR("Should use PFO accept() overload with PV check.");
-    } // end of if using PFOs
     
     return false; // Default 
   }
@@ -192,33 +150,22 @@ namespace met {
     return true;
   }
 
-  bool METSoftTermsTool::accept(const xAOD::PFO* pfo, const xAOD::Vertex* pv) const
-  {
-    if(!pfo->isCharged()) return true;
-    if(fabs(pfo->track(0)->z0() - pv->z())>2) return false;
-    return true;
-  }
-
   bool METSoftTermsTool::resolveOverlap(const xAOD::IParticle* /*object*/,
-				        xAOD::MissingETComponentMap* metMap,
-				        std::vector<const xAOD::IParticle*>& acceptedSignals,
-				        MissingETBase::Types::weight_t& /*objWeight*/) const
+                                        xAOD::MissingETComponentMap* metMap,
+                                        std::vector<const xAOD::IParticle*>& acceptedSignals,
+                                        MissingETBase::Types::weight_t& /*objWeight*/) const
   {
 
     // Check/Resolve overlap
     bool objsused = false;
-    if( m_st_objtype==0 ) {
+    if( m_st_objtype == xAOD::Type::CaloCluster ) {
       ATH_MSG_DEBUG("Check for used clusters");
       objsused = metMap->checkUsage(acceptedSignals,MissingETBase::UsageHandler::OnlyCluster);
     }
-    else if( m_st_objtype==1 ) { 
+    else if( m_st_objtype == xAOD::Type::TrackParticle ) { 
       ATH_MSG_DEBUG("Check for used tracks");
       objsused = metMap->checkUsage(acceptedSignals,MissingETBase::UsageHandler::OnlyTrack);
     }
-    else if( m_st_objtype==2 ) { 
-      ATH_MSG_DEBUG("Check for used PFOs: DUMMY");
-      //      objsused = metMap->checkUsage(acceptedSignals,MissingETBase::UsageHandler::OnlyTrack);
-    }
     if(!objsused) {
       ATH_MSG_DEBUG("No objects used.");
     }
@@ -230,7 +177,7 @@ namespace met {
 
   // overload for convenience
   bool METSoftTermsTool::resolveOverlap(xAOD::MissingETComponentMap* metMap,
-				        std::vector<const xAOD::IParticle*>& acceptedSignals) const
+                                        std::vector<const xAOD::IParticle*>& acceptedSignals) const
   {
     const xAOD::IParticle* dummyObject = 0;                  // Just a dummy object
     MissingETBase::Types::weight_t dummyObjWeight(1.,1.,1.); // Currently use a default value
@@ -242,11 +189,8 @@ namespace met {
 
     ATH_MSG_DEBUG ("In execute: " << name() << "...");
 
-    // First retrieve the necessary container
-    // Currently rely on only one: either CaloClusterContainer or TrackParticleContainer
-    const PFOContainer* pfoCont = 0;
-     vector<const IParticle*> signalList;
-    if( m_st_objtype == 0 ) {
+    vector<const IParticle*> signalList;
+    if( m_st_objtype == xAOD::Type::CaloCluster ) {
       // Retrieve the calo container
       SG::ReadHandle<xAOD::CaloClusterContainer> caloClusCont(m_caloClusterKey);
       if (!caloClusCont.isValid()) {
@@ -279,7 +223,7 @@ namespace met {
       ATH_MSG_DEBUG("Selected " << signalList.size() << " topoclusters for soft MET");
 
     } // end if Clusters
-    else if( m_st_objtype == 1 ) {
+    else if( m_st_objtype == xAOD::Type::TrackParticle ) {
 
       // Retrieve the track container
       SG::ReadHandle<xAOD::TrackParticleContainer> trackParCont(m_trackParticleKey);
@@ -293,8 +237,8 @@ namespace met {
 
       MissingETComponentMap::iterator iter = MissingETComposition::find(metMap,metTerm);
       if(iter==metMap->end()) {
-	ATH_MSG_WARNING("Could not find current METComponent in MET Map!");
-	return StatusCode::SUCCESS;
+        ATH_MSG_WARNING("Could not find current METComponent in MET Map!");
+        return StatusCode::SUCCESS;
       }
       MissingETComponent* newComp = *iter;
       newComp->setStatusWord(MissingETBase::Status::contributedSoftTerm());
@@ -303,62 +247,14 @@ namespace met {
       for( TrackParticleContainer::const_iterator iTrk=trackParCont->begin(); iTrk!=trackParCont->end(); ++iTrk ) {
         // Check if track satisfies the requirements
         if( this->accept(*iTrk) ) {
-	  // Add the selected track particles to the list
-	  signalList.push_back(*iTrk);
-	}
+          // Add the selected track particles to the list
+          signalList.push_back(*iTrk);
+        }
       } // end loop over tracks
 
       ATH_MSG_DEBUG("Selected " << signalList.size() << " tracks for soft MET");
 
     }  // end if Tracks
-    else if( m_st_objtype == 2 ) {
-      // Retrieve the pfo container
-      pfoCont = m_pfotool->retrievePFO(CP::EM, CP::all);
-      if(!pfoCont) {
-        ATH_MSG_WARNING("Unable to retrieve input pfo container");
-        return StatusCode::SUCCESS;
-      }
-      SG::ReadHandle<xAOD::VertexContainer> pv_cont(m_pv_inputkey);
-      if (!pv_cont.isValid()) {
-        ATH_MSG_WARNING("Unable to retrieve input primary vertex container");
-        return StatusCode::SUCCESS;
-      }
-      const xAOD::Vertex* pv(0);
-      for(const auto& vx : *pv_cont) {
-	if(vx->vertexType()==xAOD::VxType::PriVtx) {pv = vx; break;}
-      }
-      if(pv) {
-	ATH_MSG_DEBUG("Main primary vertex has z = " << pv->z());
-      } else{
-	ATH_MSG_WARNING("Event has no primary vertices");
-	return StatusCode::SUCCESS;
-      }
-
-      signalList.reserve(pfoCont->size());
-
-      MissingETBase::Types::bitmask_t source = MissingETBase::Source::SoftEvent; // need to add PFlow source tag
-      metTerm->setSource(source);
-
-      MissingETComponentMap::iterator iter = MissingETComposition::find(metMap,metTerm);
-      if(iter==metMap->end()) {
-	ATH_MSG_WARNING("Could not find current METComponent in MET Map!");
-	return StatusCode::SUCCESS;
-      }
-      MissingETComponent* newComp = *iter;
-      newComp->setStatusWord(MissingETBase::Status::contributedSoftTerm());
-
-      // Loop over all pfos
-      for( PFOContainer::const_iterator iPfo=pfoCont->begin(); iPfo!=pfoCont->end(); ++iPfo ) {
-        // Check if pfo satisfies the requirements
-        if( this->accept(*iPfo,pv) ) {
-	  // Add the selected pfo particles to the list
-	  signalList.push_back(*iPfo);
-	}
-      } // end loop over pfos
-
-      ATH_MSG_DEBUG("Selected " << signalList.size() << " pfos for soft MET");
-
-    }  // end if PFOs
 
     // Resolve overlap: signalList is accessed by reference and updated w/ content that is not
     // associated to any object. True if signalList size 0, i.e. nothing to add to MET
@@ -368,46 +264,12 @@ namespace met {
     vector<const IParticle*> dummyList;
     MissingETBase::Types::weight_t unitWeight(1.,1.,1.);
 
-    if(m_st_objtype == 2) {
-      for( vector<const IParticle*>::const_iterator iPart=signalList.begin();
-	   iPart!=signalList.end(); ++iPart) {
-	const PFO* pfo = dynamic_cast<const PFO*>(*iPart);
-        if(pfo) {
-	    metTerm->add(pfo->ptEM()*cos(pfo->phiEM()),
-		         pfo->ptEM()*sin(pfo->phiEM()),
-		         pfo->ptEM());
-	  } else {
-	  // In principle for the charged PFOs we should perhaps add the weights
-	  // but this shouldn't happen if we don't have a jet. 
-	  if(!pfo->isCharged()) {
-	    metTerm->add(pfo->pt()*cos(pfo->phi()),
-		         pfo->pt()*sin(pfo->phi()),
-		         pfo->pt());
-	  }
-
-	  MissingETComposition::insert(metMap,metTerm,pfo,dummyList,unitWeight);
-        }
-      }
-    } else {
-      for( vector<const IParticle*>::const_iterator iPart=signalList.begin();
-           iPart!=signalList.end(); ++iPart) {
-        this->addToMET(*iPart,dummyList,metTerm,metMap,unitWeight);
-      }
-    }
+    for(const IParticle* part : signalList) this->addToMET(part,dummyList,metTerm,metMap,unitWeight);
 
     ATH_MSG_DEBUG( "Map contains " << (*MissingETComposition::find(metMap,metTerm))->objects().size() << " soft signals" );
 
-    if(pfoCont) delete pfoCont;
     return StatusCode::SUCCESS;
   }
 
-  /////////////////////////////////////////////////////////////////// 
-  // Const methods: 
-  ///////////////////////////////////////////////////////////////////
-
-  /////////////////////////////////////////////////////////////////// 
-  // Non-const methods: 
-  /////////////////////////////////////////////////////////////////// 
-
 }
 
diff --git a/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx
index fa51d52c50cd55cf0f9da668554b697640e9a098..cfafb090b375c531bd022679f1a6648b14150860 100644
--- a/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx
+++ b/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx
@@ -103,23 +103,23 @@ namespace met {
   //*********************************************************************************************************
   // Get tau constituents
   StatusCode METTauAssociator::extractTopoClusters(const xAOD::IParticle *obj,
-						   std::vector<const xAOD::IParticle*>& tclist,
-				        	   const met::METAssociator::ConstitHolder& /*tcCont*/) const
+                                                   std::vector<const xAOD::IParticle*>& tclist,
+                                                   const met::METAssociator::ConstitHolder& /*tcCont*/) const
   {
     const TauJet* tau = static_cast<const TauJet*>(obj);
     for( ElementLink< xAOD::IParticleContainer > cluster_link : tau->clusterLinks() ){
       const xAOD::IParticle* ipart = *cluster_link;
       if (ipart->type() == xAOD::Type::ParticleFlow){
-	// If using PFO, get cluster
+        // If using PFO, get cluster
         const xAOD::PFO *pfo = static_cast<const xAOD::PFO*>(ipart);
-	if (pfo->isCharged()){ continue; }
-	else {
-	  ipart = pfo->cluster(0);
-	}
+        if (pfo->isCharged()){ continue; }
+        else {
+          ipart = pfo->cluster(0);
+        }
       }
       if(ipart->type() != xAOD::Type::CaloCluster) {
-    	ATH_MSG_WARNING("Unexpected jet constituent type " << ipart->type() << " received! Skip.");
-	continue;
+            ATH_MSG_WARNING("Unexpected jet constituent type " << ipart->type() << " received! Skip.");
+        continue;
       }      
       // Link set in Reconstruction/tauRecTools/src/TauAxisSetter.cxx
       // Internal defaults are m_clusterCone = 0.2, m_doCellCorrection = false, m_doAxisCorrection = True
@@ -132,8 +132,8 @@ namespace met {
 
 
   StatusCode METTauAssociator::extractTracks(const xAOD::IParticle *obj,
-					     std::vector<const xAOD::IParticle*>& constlist,
-					     const met::METAssociator::ConstitHolder& constits) const
+                                             std::vector<const xAOD::IParticle*>& constlist,
+                                             const met::METAssociator::ConstitHolder& constits) const
   {
     const TauJet* tau = static_cast<const TauJet*>(obj);
     for( const xAOD::TauTrack* tauTrk : tau->tracks(xAOD::TauJetParameters::coreTrack) ){//all tracks dR<0.2 regardless of quality
@@ -149,9 +149,9 @@ namespace met {
   //*********************************************************************************************************
   // Get tau constituents
   StatusCode METTauAssociator::extractPFO(const xAOD::IParticle* obj,
-					  std::vector<const xAOD::IParticle*>& pfolist,
-					  const met::METAssociator::ConstitHolder& constits,
-					  std::map<const IParticle*,MissingETBase::Types::constvec_t> &/*momenta*/) const
+                                          std::vector<const xAOD::IParticle*>& pfolist,
+                                          const met::METAssociator::ConstitHolder& constits,
+                                          std::map<const IParticle*,MissingETBase::Types::constvec_t> &/*momenta*/) const
   {
     const TauJet* tau = static_cast<const TauJet*>(obj);
     const Jet* seedjet = *tau->jetLink();
@@ -159,26 +159,62 @@ namespace met {
     for(const auto& pfo : *constits.pfoCont) {
       bool match = false;
       if (!pfo->isCharged()) {
-	if(xAOD::P4Helpers::isInDeltaR(*seedjet,*pfo,0.2,m_useRapidity) && pfo->eEM()>0) {
-	  ATH_MSG_VERBOSE("Found nPFO with dR " << seedjet->p4().DeltaR(pfo->p4EM()));
-	  match = true;
-	}
+        if(xAOD::P4Helpers::isInDeltaR(*seedjet,*pfo,0.2,m_useRapidity) && pfo->eEM()>0) {
+          ATH_MSG_VERBOSE("Found nPFO with dR " << seedjet->p4().DeltaR(pfo->p4EM()));
+          match = true;
+        }
       }
       else {
         const TrackParticle* pfotrk = pfo->track(0);
         for( const xAOD::TauTrack* ttrk : tau->tracks(xAOD::TauJetParameters::coreTrack) ){//all tracks <0.2, no quality
           const TrackParticle* tautrk = ttrk->track();
           if(tautrk==pfotrk) {
-	    ATH_MSG_VERBOSE("Found cPFO with dR " << seedjet->p4().DeltaR(ttrk->p4()));
-	    // We set a small -ve pt for cPFOs that were rejected
-	    // by the ChargedHadronSubtractionTool
-	    const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");	
-	    if(PVMatchedAcc(*pfo) && ( !m_cleanChargedPFO || isGoodEoverP(pfotrk) )) match = true;
+            ATH_MSG_VERBOSE("Found cPFO with dR " << seedjet->p4().DeltaR(ttrk->p4()));
+            // We set a small -ve pt for cPFOs that were rejected
+            // by the ChargedHadronSubtractionTool
+            const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");        
+            if(PVMatchedAcc(*pfo) && ( !m_cleanChargedPFO || isGoodEoverP(pfotrk) )) match = true;
+          }
+        }
+      }
+      if(match) {
+        pfolist.push_back(pfo);
+      }
+    }
+    return StatusCode::SUCCESS;
+  }
+
+  StatusCode METTauAssociator::extractFE(const xAOD::IParticle* obj,
+                                         std::vector<const xAOD::IParticle*>& felist,
+                                         const met::METAssociator::ConstitHolder& constits,
+                                         std::map<const IParticle*,MissingETBase::Types::constvec_t> &/*momenta*/) const
+  {
+    const TauJet* tau = static_cast<const TauJet*>(obj);
+    const Jet* seedjet = *tau->jetLink();
+    TLorentzVector momentum;
+    for(const xAOD::FlowElement* pfo : *constits.feCont) {
+      bool match = false;
+      if (!pfo->isCharged()) {
+        if(xAOD::P4Helpers::isInDeltaR(*seedjet,*pfo,0.2,m_useRapidity) && pfo->e()>0) {
+          ATH_MSG_VERBOSE("Found nPFO with dR " << seedjet->p4().DeltaR(pfo->p4()));
+          match = true;
+        }
+      }
+      else {
+        const TrackParticle* pfotrk = static_cast<const xAOD::TrackParticle*>(pfo->chargedObject(0));
+        for( const xAOD::TauTrack* ttrk : tau->tracks(xAOD::TauJetParameters::coreTrack) ){//all tracks <0.2, no quality
+          const TrackParticle* tautrk = ttrk->track();
+          if(tautrk==pfotrk) {
+            ATH_MSG_VERBOSE("Found cPFO with dR " << seedjet->p4().DeltaR(ttrk->p4()));
+            // We set a small -ve pt for cPFOs that were rejected
+            // by the ChargedHadronSubtractionTool
+            const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");        
+            if(PVMatchedAcc(*pfo) && ( !m_cleanChargedPFO || isGoodEoverP(pfotrk) )) match = true;
           }
         }
       }
       if(match) {
-	pfolist.push_back(pfo);
+        felist.push_back(pfo);
       }
     }
     return StatusCode::SUCCESS;
diff --git a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig.py b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig.py
index 5dc91c5fb16a796938e7f6f73b0b7ab36287e247..6f2972858f92f1534b1ce2b0f9911e4a3d50f75d 100644
--- a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig.py
+++ b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig.py
@@ -15,11 +15,13 @@ defaultInputKey = {
    'LCJet'     :'AntiKt4LCTopoJets',
    'EMJet'     :'AntiKt4EMTopoJets',
    'PFlowJet'  :'AntiKt4EMPFlowJets',
+   'PFlowFEJet':'AntiKt4EMPFlowFEJets',
    'Muon'      :'Muons',
    'Soft'      :'',
    'Clusters'  :'CaloCalTopoClusters',
    'Tracks'    :'InDetTrackParticles',
    'PFlowObj'  :'CHSParticleFlowObjects',
+   'PFlowObjFE':'CHSFlowElements',
    'PrimVxColl':'PrimaryVertices',
    'Truth'     :'TruthEvents',
    }
@@ -63,6 +65,8 @@ def getAssociator(config,suffix,doPFlow=False,
         tool = CfgMgr.met__METJetAssocTool('MET_EMJetAssocTool_'+suffix)
     if config.objType == 'PFlowJet':
         tool = CfgMgr.met__METJetAssocTool('MET_PFlowJetAssocTool_'+suffix)
+    if config.objType == 'PFlowFEJet':
+        tool = CfgMgr.met__METJetAssocTool('MET_PFlowFEJetAssocTool_'+suffix)
     if config.objType == 'Muon':
         tool = CfgMgr.met__METMuonAssociator('MET_MuonAssociator_'+suffix)
     if config.objType == 'Soft':
@@ -74,9 +78,14 @@ def getAssociator(config,suffix,doPFlow=False,
     if config.objType == 'Truth':
         tool = CfgMgr.met__METTruthAssociator('MET_TruthAssociator_'+suffix)
         tool.RecoJetKey = config.inputKey
+
+    from METReconstruction.METRecoFlags import metFlags
     if doPFlow:
         tool.PFlow = True
-        tool.PFlowColl = modConstKey if modConstKey!="" else defaultInputKey["PFlowObj"]
+        if metFlags.UseFlowElements() :
+            tool.FlowElementCollection = modConstKey if modConstKey!="" else defaultInputKey["PFlowObjFE"]
+        else:
+            tool.PFlowColl = modConstKey if modConstKey!="" else defaultInputKey["PFlowObj"]
     else:
         tool.UseModifiedClus = doModClus
     # set input/output key names
@@ -146,7 +155,11 @@ class METAssocConfig:
         modConstKey_tmp = modConstKey
         modClusColls_tmp = modClusColls
         if doPFlow:
-            if modConstKey_tmp == "": modConstKey_tmp = "CHSParticleFlowObjects"
+            from METReconstruction.METRecoFlags import metFlags
+            if metFlags.UseFlowElements():
+                if modConstKey_tmp == "": modConstKey_tmp = "CHSFlowElements"
+            else:
+                if modConstKey_tmp == "": modConstKey_tmp = "CHSParticleFlowObjects"
         else:
             if modConstKey_tmp == "": modConstKey_tmp = "OriginCorr"
             if modClusColls_tmp == {}: modClusColls_tmp = {'LCOriginCorrClusters':'LCOriginTopoClusters',
diff --git a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig_readAOD.py b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig_readAOD.py
index 0257b283e2ee31f1c069067be3046c8872dc3ca0..61b3897355cc0e8d590bad07fb7b25c82bb0e378 100644
--- a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig_readAOD.py
+++ b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig_readAOD.py
@@ -21,6 +21,7 @@ defaultInputKey = {
    'LCJet'     :'AntiKt4LCTopoJets',
    'EMJet'     :'AntiKt4EMTopoJets',
    'PFlowJet'  :'AntiKt4EMPFlowJets',
+   'PFlowFEJet':'AntiKt4EMPFlowFEJets',
    'Muon'      :'Muons',
    'Soft'      :'',
    'ClusColl'  :'CaloCalTopoClusters',
@@ -82,6 +83,8 @@ def getAssociator(config,suffix,doPFlow=False,
         tool = CfgMgr.met__METJetAssocTool('MET_EMJetAssocTool_'+suffix)
     if config.objType == 'PFlowJet':
         tool = CfgMgr.met__METJetAssocTool('MET_PFlowJetAssocTool_'+suffix)
+    if config.objType == 'PFlowFEJet':
+        tool = CfgMgr.met__METJetAssocTool('MET_PFlowFEJetAssocTool_'+suffix)
     if config.objType == 'Muon':
         tool = CfgMgr.met__METMuonAssociator('MET_MuonAssociator_'+suffix,DoClusterMatch=False)
     if config.objType == 'Soft':
@@ -94,9 +97,6 @@ def getAssociator(config,suffix,doPFlow=False,
         ToolSvc == tool
         tool.RecoJetKey = config.inputKey
     if doPFlow:
-        pfotool = CfgMgr.CP__RetrievePFOTool('MET_PFOTool_'+suffix)
-        ToolSvc += pfotool
-        tool.PFOTool = pfotool
         tool.PFlow = True
     else:
         tool.UseModifiedClus = doOriginCorrClus
diff --git a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METConfig_Associator.py b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METConfig_Associator.py
index 600e5e9b69102bbb6298a3d0fe4fa5c7403df9cb..de6c00f8784d0b986e836194e497096bee7197b4 100644
--- a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METConfig_Associator.py
+++ b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METConfig_Associator.py
@@ -70,3 +70,23 @@ if metFlags.DoPFlow() and metFlags.UseTracks():
 
     metFlags.METAssocConfigs()[cfg_akt4pf.suffix] = cfg_akt4pf
     metFlags.METAssocOutputList().append(cfg_akt4pf.suffix)
+
+
+############################################################################
+# PFlow (FlowElement)
+if metFlags.DoPFlow() and metFlags.UseTracks() and metFlags.UseFlowElements():
+    JetType = 'PFlowFEJet'
+    
+    associators = [AssocConfig(JetType),
+                   AssocConfig('Muon'),
+                   AssocConfig('Ele'),
+                   AssocConfig('Gamma'),
+                   AssocConfig('Tau'),
+                   AssocConfig('Soft')]
+    cfg_akt4pffe = METAssocConfig('AntiKt4EMPFlowFE',
+                                  associators,
+                                  doPFlow=True
+                                  )
+
+    metFlags.METAssocConfigs()[cfg_akt4pffe.suffix] = cfg_akt4pffe
+    metFlags.METAssocOutputList().append(cfg_akt4pffe.suffix)
\ No newline at end of file
diff --git a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoConfig.py b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoConfig.py
index 01a0c21dc61f775bb5af306a809f5e43e4c3079d..a689ef77774f9aac7a59c829c99a9aba7eb11f7f 100644
--- a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoConfig.py
+++ b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoConfig.py
@@ -26,7 +26,6 @@ defaultInputKey = {
    'Muon'     :'Muons',
    'SoftTrk'  :'InDetTrackParticles',
    'SoftClus' :'CaloCalTopoClusters',
-   'SoftPFlow':'JetETMissNeutralParticleFlowObjects',
    'PrimaryVx':'PrimaryVertices',
    'Truth'    :'TruthEvents',
    'Calo'     :'AllCalo',
@@ -42,7 +41,6 @@ defaultOutputKey = {
     'Muon'     :'Muons',
     'SoftTrk'  :'SoftTrk',
     'SoftClus' :'SoftClus',
-    'SoftPFlow':'SoftPFlow',
     'Total'    :'Final',
     'Truth'    :'Truth',
     'Calo'     :'Calo'
@@ -86,11 +84,6 @@ def getBuilder(config,suffix,doTracks,doCells,doTriggerMET,doOriginCorrClus):
     if config.objType.endswith('SoftClus'):
         tool = CfgMgr.met__METSoftTermsTool('MET_SoftClusTool_'+suffix)
         tool.InputComposition = 'Clusters'
-    if config.objType == 'SoftPFlow':
-        tool = CfgMgr.met__METSoftTermsTool('MET_SoftPFlowTool_'+suffix)
-        tool.InputComposition = 'PFlow'
-        pfotool = CfgMgr.CP__RetrievePFOTool('MET_PFOTool_'+suffix)
-        tool.PFOTool = pfotool
     if suffix == 'Truth':
         tool = CfgMgr.met__METTruthTool('MET_TruthTool_'+config.objType)
         tool.InputComposition = config.objType
diff --git a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoFlags.py b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoFlags.py
index 462fb16051c5e1daa444e94edd93d0634e07cf1e..99b0482d4042531a1c7f1e61341f2d525ecb9e5d 100644
--- a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoFlags.py
+++ b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoFlags.py
@@ -16,6 +16,11 @@ class DoPFlow(JobProperty):
     allowedTypes = ['bool'] 
     StoredValue  = True
 
+class UseFlowElements(JobProperty):
+    statusOn = True
+    allowedTypes = ['bool'] 
+    StoredValue  = False
+
 class UseTracks(JobProperty):
     statusOn = True
     allowedTypes = ['bool']
@@ -65,6 +70,7 @@ jobproperties.add_Container(METRecoFlags)
 
 jobproperties.METRecoFlags.add_JobProperty(DoRegions)
 jobproperties.METRecoFlags.add_JobProperty(DoPFlow)
+jobproperties.METRecoFlags.add_JobProperty(UseFlowElements)
 jobproperties.METRecoFlags.add_JobProperty(UseTracks)
 jobproperties.METRecoFlags.add_JobProperty(DecorateSoftConst)
 jobproperties.METRecoFlags.add_JobProperty(AllowOverwrite)
diff --git a/Reconstruction/PFlow/PFlowUtils/PFlowUtils/IRetrievePFOTool.h b/Reconstruction/PFlow/PFlowUtils/PFlowUtils/IRetrievePFOTool.h
deleted file mode 100644
index 1cc02f589ea0f59bfa5f84f7b67b3b914d05d51c..0000000000000000000000000000000000000000
--- a/Reconstruction/PFlow/PFlowUtils/PFlowUtils/IRetrievePFOTool.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef IRETRIEVEPFOTOOL_H
-#define IRETRIEVEPFOTOOL_H
-
-/** Simple class to retrieve PFO for jets and met in the two possible configurations we provide */
-
-#include "AsgTools/IAsgTool.h"
-
-#include "xAODPFlow/PFOContainer.h"
-#include "PFlowUtils/PFODefs.h"
-
-namespace CP {
-
-  class IRetrievePFOTool : public virtual asg::IAsgTool {
-
-    /** Declare the interface that the class provides */
-    ASG_TOOL_INTERFACE( CP::IRetrievePFOTool )
-      
-    public:
-
-    /** Fills theContainer with PFO from EM or LC mode in eflowRec */
-    virtual const xAOD::PFOContainer* retrievePFO(const CP::PFO_JetMETConfig_inputScale& theScale) const = 0;
-    
-     /** Fills theContainer with PFO from EM or LC mode in eflowRec - additionally allows to choose one of charged, neutral or all PFO configurations */
-    virtual const xAOD::PFOContainer* retrievePFO(const CP::PFO_JetMETConfig_inputScale& theScale, const CP::PFO_JetMETConfig_charge& theCharge) const = 0;
-
-  };
-
-}
-#endif
diff --git a/Reconstruction/PFlow/PFlowUtils/PFlowUtils/RetrievePFOTool.h b/Reconstruction/PFlow/PFlowUtils/PFlowUtils/RetrievePFOTool.h
deleted file mode 100644
index 4c5cc906609783748713b01832c595897e523be9..0000000000000000000000000000000000000000
--- a/Reconstruction/PFlow/PFlowUtils/PFlowUtils/RetrievePFOTool.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef RETRIEVEPFOTOOL_H
-#define RETRIEVEPFOTOOL_H
-
-/** Simple class to retrieve PFO for jets and met in the two possible configurations we provide */
-
-#include "AsgTools/AsgTool.h"
-
-#include "PFlowUtils/IRetrievePFOTool.h"
-
-#include <string>
-
-namespace CP {
-
-  class RetrievePFOTool : public virtual IRetrievePFOTool, public asg::AsgTool {
-
-    /** Athena constructor */
-    ASG_TOOL_CLASS( RetrievePFOTool, IRetrievePFOTool )
-
-  public:
-    /** Rootcore constructor */
-    RetrievePFOTool(const std::string& name);
-    
-    /** Fills theContainer with PFO from EM or LC mode in eflowRec - the client owns theContainer */
-    virtual const xAOD::PFOContainer* retrievePFO(const CP::PFO_JetMETConfig_inputScale& theScale) const override;
-
-    /** Fills theContainer with PFO from EM or LC mode in eflowRec - additionally allows to choose one of charged, neutral or all PFO configurations - the client owns theContainer */
-    virtual const xAOD::PFOContainer* retrievePFO(const CP::PFO_JetMETConfig_inputScale& theScale, const CP::PFO_JetMETConfig_charge& theCharge) const override; 
-
-  private:
-
-    /** Fills theContainer with neutral PFO from EM or LC mode in eflowRec */
-    StatusCode retrieve_neutralPFO(const CP::PFO_JetMETConfig_inputScale& theScale, xAOD::PFOContainer* theContainer) const;
-
-    /** This retrieves a PFO container with theName and adds the PFO* to newContainer */
-    StatusCode fillPFOContainer( xAOD::PFOContainer* newContainer, const std::string& theName) const;
-
-    std::string m_inCharged;
-    std::string m_inNeutral;
-
-  };
-
-}
-#endif
diff --git a/Reconstruction/PFlow/PFlowUtils/Root/RetrievePFOTool.cxx b/Reconstruction/PFlow/PFlowUtils/Root/RetrievePFOTool.cxx
deleted file mode 100644
index a5ce20b1bf6ea9abf2082deee809a60a66efabed..0000000000000000000000000000000000000000
--- a/Reconstruction/PFlow/PFlowUtils/Root/RetrievePFOTool.cxx
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#include "PFlowUtils/RetrievePFOTool.h"
-
-namespace CP {
-
-  RetrievePFOTool::RetrievePFOTool(const std::string& name) : asg::AsgTool( name ) {     
-    declareProperty("ChargedInputContainer", m_inCharged="");
-    declareProperty("NeutralInputContainer", m_inNeutral="");
-}
-
-  const xAOD::PFOContainer* RetrievePFOTool::retrievePFO(const CP::PFO_JetMETConfig_inputScale& theScale) const {
-    return this->retrievePFO(theScale, CP::all);
-  }
-
-  const xAOD::PFOContainer* RetrievePFOTool::retrievePFO(const CP::PFO_JetMETConfig_inputScale& theScale, const CP::PFO_JetMETConfig_charge& theCharge) const {
-    
-    //This is a new VIEW container that we will fill with the clients chosen PFO - the client owns this object, and should delete it
-    xAOD::PFOContainer* newContainer = new xAOD::PFOContainer(SG::VIEW_ELEMENTS);
-
-    StatusCode sc;
-    //Then we retrieve the charged PFO - this is the same for both EM and LC modes
-    if (CP::charged == theCharge || CP::all == theCharge) {
-      if(m_inCharged!="") sc = this->fillPFOContainer(newContainer, m_inCharged);
-      else sc = this->fillPFOContainer(newContainer, "JetETMissChargedParticleFlowObjects");
-      if (sc.isFailure()) ATH_MSG_WARNING( " could not fill charged pfo container ");
-    }
-
-    //Then we retrieve the neutral PFO - thu is different in the EM and LC modes
-    if (CP::neutral == theCharge || CP::all == theCharge) {
-      sc = this->retrieve_neutralPFO(theScale,newContainer);
-      if (sc.isFailure()) ATH_MSG_WARNING(" could not fill neutral pfo container ");
-    }
-
-    //The client is only allowed a const pointer, to prevent them modifying the PFO
-    const xAOD::PFOContainer* newPFO = const_cast<xAOD::PFOContainer*>(newContainer);
-
-    return newPFO;
-
-  }
-
-  StatusCode RetrievePFOTool::retrieve_neutralPFO(const CP::PFO_JetMETConfig_inputScale& theScale, xAOD::PFOContainer* theContainer) const {
-
-    if (CP::EM == theScale) {
-      //Get neutral PFO for EM mode - stored in one container
-      if(m_inNeutral!="") ATH_CHECK(this->fillPFOContainer(theContainer, m_inNeutral));
-      else ATH_CHECK(this->fillPFOContainer(theContainer, "JetETMissNeutralParticleFlowObjects"));
-    }// EM mode
-    else if (CP::LC == theScale){
-      //Get neutral PFO for LC mode - stored in two containers
-      if(m_inNeutral!="")
-        ATH_CHECK(this->fillPFOContainer(theContainer, m_inNeutral));
-      else{
-        //Get neutral PFO for LC mode - stored in two containers
-        ATH_CHECK(this->fillPFOContainer(theContainer, "JetETMissLCNeutralParticleFlowObjects"));
-        ATH_CHECK(this->fillPFOContainer(theContainer, "JetETMissLCNonModifiedNeutralParticleFlowObjects"));
-      }
-    }//LC mode
-
-    return StatusCode::SUCCESS;
-
-  }
-
-
-  StatusCode RetrievePFOTool::fillPFOContainer( xAOD::PFOContainer* newContainer, const std::string& theName) const {
-
-    const xAOD::PFOContainer* thePFO = NULL;
-    ATH_CHECK( evtStore()->retrieve(thePFO, theName));
-      
-    xAOD::PFOContainer::const_iterator firstPFO = thePFO->begin();
-    xAOD::PFOContainer::const_iterator lastPFO = thePFO->end();
-
-    for (; firstPFO != lastPFO; ++firstPFO) {
-      xAOD::PFO* thePFO = const_cast<xAOD::PFO*>(*firstPFO);
-      newContainer->push_back(thePFO);
-    }//PFO loop
-
-    return StatusCode::SUCCESS;
-  }
-
-}
diff --git a/Reconstruction/PFlow/PFlowUtils/python/DefaultTools.py b/Reconstruction/PFlow/PFlowUtils/python/DefaultTools.py
index ea54bb2f515ef0b378b7632d58f039592c7e6203..f7d399db7e9051ffb77fe83f36d55ed4256df436 100644
--- a/Reconstruction/PFlow/PFlowUtils/python/DefaultTools.py
+++ b/Reconstruction/PFlow/PFlowUtils/python/DefaultTools.py
@@ -1,77 +1,11 @@
 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-
-from PFlowUtils.PFlowUtilsConf import CP__RetrievePFOTool as RetrievePFOTool
 from PFlowUtils.PFlowUtilsConf import CP__WeightPFOTool as WeightPFOTool
 
 def declareDefaultTools():
 
-  from JetRecConfig.JetRecFlags import jetFlags
   from JetRecConfig.JetRecStandardToolManager import jtm
-  from JetRecTools.JetRecToolsConf import PFlowPseudoJetGetter
-  from eflowRec.eflowRecFlags import jobproperties
-
-  # Retriever for pflow objects.
-  jtm += RetrievePFOTool("pflowretriever")
 
   # Weight tool for charged pflow objects.
   jtm += WeightPFOTool("pflowweighter")
   jtm += WeightPFOTool("pflowweighter_LC",NeutralPFOScale="LC")
-
-  useVertices = True
-  if False is jetFlags.useVertices:
-    useVertices = False
-
-  if True is jobproperties.eflowRecFlags.useUpdated2015ChargedShowerSubtraction:
-    useChargedWeights = True
-  else:
-    useChargedWeights = False
-
-  useTrackVertexTool = False
-  if True is jetFlags.useTrackVertexTool:
-    useTrackVertexTool = True
-
-  # EM-scale pflow.
-  jtm += PFlowPseudoJetGetter(
-    "empflowget",
-    Label = "EMPFlow",
-    OutputContainer = "PseudoJetEMPFlow",
-    RetrievePFOTool = jtm.pflowretriever,
-    WeightPFOTool = jtm.pflowweighter,
-    InputIsEM = True,
-    CalibratePFO = False,
-    SkipNegativeEnergy = True,
-    UseChargedWeights = useChargedWeights,
-    UseVertices = useVertices,
-    UseTrackToVertexTool = useTrackVertexTool
-  )
-
-  # Calibrated EM-scale pflow.
-  jtm += PFlowPseudoJetGetter(
-    "emcpflowget",
-    Label = "EMCPFlow",
-    OutputContainer = "PseudoJetEMCPFlow",
-    RetrievePFOTool = jtm.pflowretriever,
-    WeightPFOTool = jtm.pflowweighter_LC,
-    InputIsEM = True,
-    CalibratePFO = True,
-    SkipNegativeEnergy = True,
-    UseChargedWeights = useChargedWeights,
-    UseVertices = useVertices,
-    UseTrackToVertexTool = useTrackVertexTool
-  )
-
-  # LC-scale pflow.
-  jtm += PFlowPseudoJetGetter(
-    "lcpflowget",
-    Label = "LCPFlow",
-    OutputContainer = "PseudoJetLCPFlow",
-    RetrievePFOTool = jtm.pflowretriever,
-    WeightPFOTool = jtm.pflowweighter_LC,
-    InputIsEM = False,
-    CalibratePFO = False,
-    SkipNegativeEnergy = True,
-    UseChargedWeights = useChargedWeights,
-    UseVertices = useVertices,
-    UseTrackToVertexTool = useTrackVertexTool
-  )
diff --git a/Reconstruction/PFlow/PFlowUtils/src/components/PFlowUtils_entries.cxx b/Reconstruction/PFlow/PFlowUtils/src/components/PFlowUtils_entries.cxx
index bacff888094dd73f1deec60ccbc899acd9acbb9f..3dfc7d7d6e6284c2e6e9b174f10f358af444659e 100644
--- a/Reconstruction/PFlow/PFlowUtils/src/components/PFlowUtils_entries.cxx
+++ b/Reconstruction/PFlow/PFlowUtils/src/components/PFlowUtils_entries.cxx
@@ -1,10 +1,8 @@
-#include "PFlowUtils/RetrievePFOTool.h"
 #include "PFlowUtils/WeightPFOTool.h"
 #include "../ParticleFlowEventFilter_r207.h"
 #include "../CombinePFO.h"
 #include "../PFlowCalibPFODecoratorAlgorithm.h"
 
-DECLARE_COMPONENT( CP::RetrievePFOTool )
 DECLARE_COMPONENT( CP::WeightPFOTool )
 DECLARE_COMPONENT( ParticleFlowEventFilter_r207 )
 DECLARE_COMPONENT( CombinePFO )
diff --git a/Reconstruction/eflowRec/eflowRec/PFLeptonSelector.h b/Reconstruction/eflowRec/eflowRec/PFLeptonSelector.h
index 2d7fff9852af57847ed5af42ea06d57ba6ef4b57..54040b98c4e366c77e665e618769afa0d0591538 100644
--- a/Reconstruction/eflowRec/eflowRec/PFLeptonSelector.h
+++ b/Reconstruction/eflowRec/eflowRec/PFLeptonSelector.h
@@ -68,8 +68,16 @@ private:
 
   Gaudi::Property<std::string> m_electronID{this,"electronID","LHMedium","Select electron ID"};
 
+  /** Toggle to determine whether we select any electrons or not - if selected then tracks matched to those electrons
+  * in PFTrackSelector are not used in particle flow. If not selected then an empty electron container is created,
+  * and hence PFTrackSelector won't find any electrons to match its selected tracks to.
+  */
   Gaudi::Property<bool> m_selectElectrons{this,"selectElectrons",true,"Toggle usage of electron ID"};
 
-  
+  /** Toggle to determine whether we select any muons or not - if selected then tracks matched to those muons
+  * in PFTrackSelector are not used in particle flow. If not selected then an empty muon container is created,
+  * and hence PFTrackSelector won't find any muons to match its selected tracks to.
+  */
+  Gaudi::Property<bool> m_selectMuons{this,"selectMuons",true,"Toggle usage of muon ID"};
 };
 #endif
diff --git a/Reconstruction/eflowRec/src/PFLeptonSelector.cxx b/Reconstruction/eflowRec/src/PFLeptonSelector.cxx
index b3ee9d91127818afac82b36b178891c8e2f750fb..c4d955a9d58fe621619731dafd14952a6949abf6 100644
--- a/Reconstruction/eflowRec/src/PFLeptonSelector.cxx
+++ b/Reconstruction/eflowRec/src/PFLeptonSelector.cxx
@@ -38,9 +38,11 @@ StatusCode PFLeptonSelector::execute(){
   }
 
   /* Select  muons */
-  StatusCode sc = this->selectMuons(selectedMuonsWriteHandle,leptonCaloCellsWriteHandle);
-   //if fail to select muons issue warning, but carry on processing event
-  if (sc.isFailure()) ATH_MSG_WARNING("Problem selecting muons ");
+  if (m_selectMuons){
+    StatusCode sc = this->selectMuons(selectedMuonsWriteHandle,leptonCaloCellsWriteHandle);
+     //if fail to select muons issue warning, but carry on processing event
+    if (sc.isFailure()) ATH_MSG_WARNING("Problem selecting muons ");
+  } 
 
   return StatusCode::SUCCESS;
 }
diff --git a/Reconstruction/tauRecTools/Root/HelperFunctions.cxx b/Reconstruction/tauRecTools/Root/HelperFunctions.cxx
index b77abacca7598aca734a4b9ec6bd91a5ba596e53..d364dd756bda011e81b046b86ff38845fd308c2e 100644
--- a/Reconstruction/tauRecTools/Root/HelperFunctions.cxx
+++ b/Reconstruction/tauRecTools/Root/HelperFunctions.cxx
@@ -148,6 +148,29 @@ std::unique_ptr<MVAUtils::BDT> tauRecTools::configureMVABDT(std::vector<TString>
 
 
 
+TLorentzVector tauRecTools::GetConstituentP4(const xAOD::JetConstituent& constituent) {
+  using namespace tauRecTools::msgHelperFunction;
+
+  TLorentzVector constituentP4;
+
+  if( constituent->type() == xAOD::Type::CaloCluster ) {
+    const xAOD::CaloCluster* cluster = static_cast<const xAOD::CaloCluster*>( constituent->rawConstituent() );
+    constituentP4 = cluster->p4();
+  }
+  else if ( constituent->type() == xAOD::Type::ParticleFlow ) {
+    const xAOD::PFO* pfo = static_cast<const xAOD::PFO*>( constituent->rawConstituent() );
+    constituentP4 = pfo->p4();
+  }
+  else {
+    ANA_MSG_ERROR("GetJetConstCluster: Seed jet constituent type not supported!");
+    constituentP4.SetPtEtaPhiE(constituent.pt(), constituent.eta(), constituent.phi(), constituent.e());
+  }
+
+  return constituentP4;
+}
+
+
+
 const StatusCode tauRecTools::GetJetClusterList(const xAOD::Jet* jet, std::vector<const xAOD::CaloCluster*> &clusterList, bool useSubtractedCluster) {
   using namespace tauRecTools::msgHelperFunction;
 
diff --git a/Reconstruction/tauRecTools/src/TauAxisSetter.cxx b/Reconstruction/tauRecTools/src/TauAxisSetter.cxx
index 582a0ab44e5fba1285db9ca7a9d68ee8c2c00e3d..ad87dbd4f4fd27d337ee6a469733f50ffae35fea 100644
--- a/Reconstruction/tauRecTools/src/TauAxisSetter.cxx
+++ b/Reconstruction/tauRecTools/src/TauAxisSetter.cxx
@@ -41,8 +41,7 @@ StatusCode TauAxisSetter::execute(xAOD::TauJet& pTau) const {
   
   xAOD::JetConstituentVector constituents = jetSeed->getConstituents();
   for (const xAOD::JetConstituent* constituent : constituents) {
-    TLorentzVector constituentP4;
-    constituentP4.SetPtEtaPhiE(constituent->pt(), constituent->eta(), constituent->phi(), constituent->e());
+    TLorentzVector constituentP4 = tauRecTools::GetConstituentP4(*constituent);
     baryCenter += constituentP4;
   }
   
@@ -53,8 +52,7 @@ StatusCode TauAxisSetter::execute(xAOD::TauJet& pTau) const {
   int nConstituents = 0;
 
   for (const xAOD::JetConstituent* constituent : constituents) {
-    TLorentzVector constituentP4;
-    constituentP4.SetPtEtaPhiE(constituent->pt(), constituent->eta(), constituent->phi(), constituent->e());
+    TLorentzVector constituentP4 = tauRecTools::GetConstituentP4(*constituent);
     
     double dR = baryCenter.DeltaR(constituentP4);
     if (dR > m_clusterCone) continue;
diff --git a/Reconstruction/tauRecTools/tauRecTools/HelperFunctions.h b/Reconstruction/tauRecTools/tauRecTools/HelperFunctions.h
index 67abf144f3896d46299a44c4101349e732915d8f..2812210037140d55a8fefd513055d71576211da8 100644
--- a/Reconstruction/tauRecTools/tauRecTools/HelperFunctions.h
+++ b/Reconstruction/tauRecTools/tauRecTools/HelperFunctions.h
@@ -24,6 +24,8 @@ namespace tauRecTools
 {
   ANA_MSG_HEADER(msgHelperFunction)
 
+  TLorentzVector GetConstituentP4(const xAOD::JetConstituent& constituent);
+
   const StatusCode GetJetClusterList(const xAOD::Jet* jet, std::vector<const xAOD::CaloCluster*> &clusterList, bool useSubtractedCluster);
 
   xAOD::TauTrack::TrackFlagType isolateClassifiedBits(xAOD::TauTrack::TrackFlagType flag);
diff --git a/TileCalorimeter/TileMonitoring/CMakeLists.txt b/TileCalorimeter/TileMonitoring/CMakeLists.txt
index c2ef7632ef60f0c1a6a7098c86642cbf36a4f19d..a61a13156653328d8c62dece635701af1f233921 100644
--- a/TileCalorimeter/TileMonitoring/CMakeLists.txt
+++ b/TileCalorimeter/TileMonitoring/CMakeLists.txt
@@ -94,6 +94,16 @@ atlas_add_test( TileRODMonitorAlgorithm_test
                 PROPERTIES TIMEOUT 600
                 POST_EXEC_SCRIPT nopost.sh)
 
+atlas_add_test( TileTMDBMonitorAlgorithm_test
+                SCRIPT python -m TileMonitoring.TileTMDBMonitorAlgorithm
+                PROPERTIES TIMEOUT 600
+                POST_EXEC_SCRIPT nopost.sh)
+
+atlas_add_test( TileTMDBDigitsMonitorAlgorithm_test
+                SCRIPT python -m TileMonitoring.TileTMDBDigitsMonitorAlgorithm
+                PROPERTIES TIMEOUT 600
+                POST_EXEC_SCRIPT nopost.sh)
+
 atlas_add_test( TileMonitoringConfig_test
                 SCRIPT python -m TileMonitoring.TileMonitoringConfig
                 PROPERTIES TIMEOUT 300
diff --git a/TileCalorimeter/TileMonitoring/python/TileCellMonitorAlgorithm.py b/TileCalorimeter/TileMonitoring/python/TileCellMonitorAlgorithm.py
index 2df7342756236637caddb4d698e4e948b7e2abe9..90e021939a9106965adac40d129eec603b710970 100644
--- a/TileCalorimeter/TileMonitoring/python/TileCellMonitorAlgorithm.py
+++ b/TileCalorimeter/TileMonitoring/python/TileCellMonitorAlgorithm.py
@@ -136,6 +136,12 @@ def TileCellMonitoringConfig(flags, **kwargs):
                                   title = 'Occupancy Map Over Threshod 300 GeV', path = 'Tile/Cell',
                                   subDirectory = True, run = run, triggers = l1Triggers, separator = '_')
 
+    # ) Configure histograms with Tile cell energy difference maps per partition
+    addTileModuleChannelMapsArray(helper, tileCellMonAlg, name = 'TileCellEneDiffChanMod',
+                                  title = 'Tile Cell energy difference between PMTs [MeV]', path = 'Tile/Cell',
+                                  subDirectory = True, type = 'TProfile2D', value = 'energyDiff',
+                                  run = run, triggers = l1Triggers, separator = '_')
+
     # 11) Configure histograms with occupancy maps over threshold per partition
     addTileModuleChannelMapsArray(helper, tileCellMonAlg, name = 'TileCellDetailOccMapOvThrGain',
                                   weight = 'weight', title = titleMapOvThr, path = 'Tile/Cell', subDirectory = True,
@@ -313,6 +319,8 @@ if __name__=='__main__':
     ConfigFlags.Output.HISTFileName = 'TileCellMonitorOutput.root'
     ConfigFlags.DQ.useTrigger = False
     ConfigFlags.DQ.enableLumiAccess = False
+    ConfigFlags.Exec.MaxEvents = 3
+    ConfigFlags.fillFromArgs()
     ConfigFlags.lock()
 
     # Initialize configuration object, add accumulator, merge, and run.
@@ -333,7 +341,7 @@ if __name__=='__main__':
 
     cfg.store( open('TileCellMonitorAlgorithm.pkl','wb') )
 
-    sc = cfg.run(maxEvents=3)
+    sc = cfg.run()
 
     import sys
     # Success should be 0
diff --git a/TileCalorimeter/TileMonitoring/python/TileMonitoringCfgHelper.py b/TileCalorimeter/TileMonitoring/python/TileMonitoringCfgHelper.py
index 72312f926ff4945d6447c5080348ad8c542f8754..4ba90944b8ee28c571f61d91671070b3e2c7268a 100644
--- a/TileCalorimeter/TileMonitoring/python/TileMonitoringCfgHelper.py
+++ b/TileCalorimeter/TileMonitoring/python/TileMonitoringCfgHelper.py
@@ -6,7 +6,6 @@
 @brief Helper functions for Run 3 Tile monitoring algorithm configuration
 '''
 from TileCalibBlobObjs.Classes import TileCalibUtils as Tile
-
 _cellNameEB = ['E3', 'E4', 'D4', 'D4', 'C10', 'C10', 'A12', 'A12', 'B11', 'B11', 'A13', 'A13',
                'E1', 'E2', 'B12', 'B12', 'D5', 'D5', 'E3*', 'E4*', 'A14', 'A14', 'B13', 'B13',
                '',   '',    '',    '',   '',   '', 'B14', 'A15', 'A15',    '',    '', 'B14',
@@ -331,7 +330,7 @@ def addTile2DHistogramsArray(helper, algorithm, name = '', xvalue = '', yvalue =
         fullTitle = getTileHistogramTitle(title = title, run = run, **kwargs)
 
         tool.defineHistogram( fullName, path = fullPath, type = type, title = fullTitle,
-                              xlabels = nxlabels, ylabels = nylabels, 
+                              xlabels = nxlabels, ylabels = nylabels,
                               xbins = xbins, xmin = xmin, xmax = xmax,
                               ybins = ybins, ymin = ymin, ymax = ymax, weight = weight)
 
@@ -340,7 +339,7 @@ def addTile2DHistogramsArray(helper, algorithm, name = '', xvalue = '', yvalue =
 
 def addTileModuleChannelMapsArray(helper, algorithm, name, title, path, weight = '',
                                   subDirectory = False, type = 'TH2D', value = '',
-                                  run = '', triggers = [], perGain = False, separator = ''):
+                                  run = '', triggers = [], perGain = False, separator = '_'):
     '''
     This function configures 2D histograms (maps) with Tile monitored value vs module and channel per partition.
 
@@ -372,7 +371,7 @@ def addTileModuleChannelMapsArray(helper, algorithm, name, title, path, weight =
 
 def addTileModuleCorrelionMapsArray(helper, algorithm, name, title, path, weight = '',
                                     subDirectory = False, type = 'TH2D', value = '', run = '',
-                                    triggers = [], perGain = False, allPartitions = False, separator = ''):
+                                    triggers = [], perGain = False, allPartitions = False, separator = '_'):
     '''
     This function configures 2D histograms (maps) with Tile monitored value vs module and channel per partition.
 
@@ -406,7 +405,7 @@ def addTileModuleCorrelionMapsArray(helper, algorithm, name, title, path, weight
 
 def addTileModulePartitionMapsArray(helper, algorithm, name, title, path, weight = '',
                                     type = 'TH2D', value = '', run = '', triggers = [],
-                                    perGain = False, separator = ''):
+                                    perGain = False, separator = '_'):
     '''
     This function configures 2D histograms (maps) with Tile monitored value vs module and partition.
 
@@ -439,7 +438,7 @@ def addTileModulePartitionMapsArray(helper, algorithm, name, title, path, weight
 
 def addTileModuleDigitizerMapsArray(helper, algorithm, name, title, path, weight = '',
                                     subDirectory = False, type = 'TH2D', value = '',
-                                    run = '', triggers = [], perGain = False, separator = ''):
+                                    run = '', triggers = [], perGain = False, separator = '_'):
     '''
     This function configures 2D histograms (maps) with Tile monitored value vs module and digitizer per partition.
 
@@ -470,7 +469,7 @@ def addTileModuleDigitizerMapsArray(helper, algorithm, name, title, path, weight
 
 
 def addTileEtaPhiMapsArray(helper, algorithm, name, title, path, weight = '', type = 'TH2D', value = '',
-                           run = '', triggers = [], perSample = True, perGain = False, separator = '',
+                           run = '', triggers = [], perSample = True, perGain = False, separator = '_',
                            etaTitle= '#eta', etabins = 21, etamin = -2.025, etamax = 2.025,
                            phiTitle = '#phi', phibins = Tile.MAX_DRAWER, phimin = -3.15, phimax = 3.15):
     '''
@@ -589,44 +588,50 @@ def addTileModuleArray(helper, algorithm, name, title, path,
 
 
 def addTileTMDB_2DHistogramsArray(helper, algorithm, name = '', value = '',
-                                    title = '', path = '', type = 'TH2D', run = ''):
+                                  title = '', path = '', type = 'TH2D', run = ''):
 
     array = helper.addArray([int(Tile.MAX_ROS - 1)], algorithm, name)
     for postfix, tool in array.Tools.items():
         ros = int(postfix.split('_').pop()) + 1
-        
+
         partition = getPartitionName(ros)
         nxlabels = getModuleLabels(partition)
         nylabels = getCellChannelTMDB_Labels(partition)
         ybins = len(nylabels)
-                    
+
         fullName = 'module,channel' + (',' + value if 'Profile' in type else '') + ';'
         fullName += getTileHistogramName(name, partition = partition)
-        
+
         fullTitle = getTileHistogramTitle(title, run = run, partition = partition)
-        
+
         tool.defineHistogram( fullName, path = path, type = type, title = fullTitle,
                                 xlabels = nxlabels, ylabels = nylabels,
                                 xbins = Tile.MAX_DRAWER, xmin = -0.5, xmax = Tile.MAX_DRAWER - 0.5,
                                 ybins = ybins, ymin = -0.5, ymax = ybins - 0.5)
 
 
-
 def addTileTMDB_1DHistogramsArray(helper, algorithm, name = '', xvalue = '', value = '', title = '',
-                                path = '', xbins = 0, xmin = 0, xmax = 0, type = 'TH1D', run = ''):
+                                  path = '', xbins = 0, xmin = 0, xmax = 0, type = 'TH1D', run = '',
+                                  perModule = False):
 
     for ros in range(1, Tile.MAX_ROS):
         partition = getPartitionName(ros)
-        histName = "{}_{}".format(name, partition)
+        baseName = "{}_{}".format(name, partition)
         nChannels = len(_cellNameTMDB_LB) if partition.startswith('L') else len(_cellNameTMDB_EB)
-        array = helper.addArray([nChannels], algorithm,  histName)
+        dimensions = [int(Tile.MAX_DRAWER), nChannels] if perModule else [nChannels]
+        array = helper.addArray(dimensions, algorithm,  baseName, topPath = 'Tile')
         for postfix, tool in array.Tools.items():
-            channel = int(postfix.split('_').pop())
+            elements = postfix.split('_')
+            channel = int(elements.pop())
+            cell = getCellNameTMDB(partition, channel)
+            module = '{}'.format(int(elements.pop()) + 1).rjust(2,'0') if perModule else ''
 
-            fullName = xvalue + (',' + value if 'Profile' in type else '') + ';'
-            fullName += histName + '_' + getCellNameTMDB(partition, channel)
+            fullName = '{}{};{}{}_{}'.format(xvalue, (',' + value if 'Profile' in type else ''),
+                                             baseName, (module if perModule else ''), cell)
 
-            fullTitle = getTileHistogramTitle(title, run = run, partition = partition)
+            moduleOrPartition = 'Module ' + partition + module if perModule else 'Partition ' + partition
+            fullTitle = 'Run {} {} TMDB {}: {}'.format(run, moduleOrPartition, cell, title)
+            fullPath = path.replace('Tile/', '') if  path.startswith('Tile/') else path
 
-            tool.defineHistogram( fullName, path = path, type = type, title = fullTitle,
-                                 xbins = xbins, xmin = xmin, xmax = xmax)
\ No newline at end of file
+            tool.defineHistogram(fullName, path = fullPath, type = type, title = fullTitle,
+                                 xbins = xbins, xmin = xmin, xmax = xmax)
diff --git a/TileCalorimeter/TileMonitoring/python/TileTMDBDigitsMonitorAlgorithm.py b/TileCalorimeter/TileMonitoring/python/TileTMDBDigitsMonitorAlgorithm.py
index e056dc41f0c1e03ec141033a19787e2ee7a6f5af..d7cdc1cdfbd2cb0d4861ac838c531803ebfefcde 100644
--- a/TileCalorimeter/TileMonitoring/python/TileTMDBDigitsMonitorAlgorithm.py
+++ b/TileCalorimeter/TileMonitoring/python/TileTMDBDigitsMonitorAlgorithm.py
@@ -1,7 +1,6 @@
 #
 #  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 #
-
 '''@file TileTMDBDigitsMonitorAlgorithm.py
 @author
 @date
@@ -32,30 +31,30 @@ def TileTMDBDigitsMonitoringConfig(flags):
 
 
 
-    addTileTMDB_2DHistogramsArray(helper, tileTMDBDigitsMonAlg, name = 'TMDBDigitsPedestal',
+    addTileTMDB_2DHistogramsArray(helper, tileTMDBDigitsMonAlg, name = 'TMDB_DigitsPedestal',
                                   value = 'pedestal', title = 'Mean pedestal (sample[0])',
-                                  path = 'Tile/TMDBDigits', type='TProfile2D', run = run)   
-    
-    addTileTMDB_2DHistogramsArray(helper, tileTMDBDigitsMonAlg, name = 'TMDBDigitsAmplitude',
+                                  path = 'Tile/TMDBDigits', type='TProfile2D', run = run)
+
+    addTileTMDB_2DHistogramsArray(helper, tileTMDBDigitsMonAlg, name = 'TMDB_DigitsAmplitude',
                                   value = 'amplitude', title = 'Difference between maximum and minimum sample',
                                   path = 'Tile/TMDBDigits', type='TProfile2D', run = run)
-                                    
-    addTileTMDB_2DHistogramsArray(helper, tileTMDBDigitsMonAlg, name = 'TMDBDigitsHFN',
+
+    addTileTMDB_2DHistogramsArray(helper, tileTMDBDigitsMonAlg, name = 'TMDB_DigitsHFN',
                                   value = 'HFN', title = 'Mean RMS of 7 samples (HFN)',
-                                  path = 'Tile/TMDBDigits', type='TProfile2D', run = run)                                     
-     
+                                  path = 'Tile/TMDBDigits', type='TProfile2D', run = run)
 
-    addTileTMDB_1DHistogramsArray(helper, tileTMDBDigitsMonAlg, name = 'TMDBDigitsCellPedestal', 
-                                    xvalue = 'pedestal', title = 'Pedestal (sample[0]);[ADC]', 
+
+    addTileTMDB_1DHistogramsArray(helper, tileTMDBDigitsMonAlg, name = 'TMDB_DigitsCellPedestal',
+                                    xvalue = 'pedestal', title = 'Pedestal (sample[0]);[ADC]',
                                     path = 'Tile/TMDBDigits', type='TH1D', run = run,
                                     xbins = 101, xmin = -0.5, xmax = 100.5)
 
-    addTileTMDB_1DHistogramsArray(helper, tileTMDBDigitsMonAlg, name = 'TMDBDigitsCellHFN',
-                                    xvalue = 'HFN', title = 'Mean RMS (HFN);[ADC]', 
+    addTileTMDB_1DHistogramsArray(helper, tileTMDBDigitsMonAlg, name = 'TMDB_DigitsCellHFN',
+                                    xvalue = 'HFN', title = 'Mean RMS (HFN);[ADC]',
                                     path = 'Tile/TMDBDigits', type='TH1D', run = run,
                                     xbins = 41, xmin = -0.5, xmax = 40.5)
 
-    addTileTMDB_1DHistogramsArray(helper, tileTMDBDigitsMonAlg, name = 'TMDBDigitsCellAmplitude', 
+    addTileTMDB_1DHistogramsArray(helper, tileTMDBDigitsMonAlg, name = 'TMDB_DigitsCellAmplitude',
                                     xvalue = 'amplitude', title = 'Difference between maximum and minimum sample;[ADC]',
                                     path = 'Tile/TMDBDigits', type='TH1D', run = run,
                                     xbins = 101, xmin = -0.5, xmax = 100.5)
@@ -85,11 +84,12 @@ if __name__=='__main__':
     ConfigFlags.Output.HISTFileName = 'TileTMDBDigitsMonitorOutput.root'
     ConfigFlags.DQ.useTrigger = False
     ConfigFlags.DQ.enableLumiAccess = False
-
+    ConfigFlags.Exec.MaxEvents = 3
+    ConfigFlags.fillFromArgs()
     ConfigFlags.lock()
 
     # Initialize configuration object, add accumulator, merge, and run.
-    from AthenaConfiguration.MainServicesConfig import MainServicesCfg 
+    from AthenaConfiguration.MainServicesConfig import MainServicesCfg
     cfg = MainServicesCfg(ConfigFlags)
 
 
@@ -97,7 +97,7 @@ if __name__=='__main__':
     tileTypeNames = ['TileDigitsContainer/MuRcvDigitsCnt']
     cfg.merge( ByteStreamReadCfg(ConfigFlags, type_names = tileTypeNames) )
 
-  
+
 
     tileTMDBDigitsMonitorAccumulator  = TileTMDBDigitsMonitoringConfig(ConfigFlags)
 
@@ -106,10 +106,10 @@ if __name__=='__main__':
     cfg.printConfig(withDetails = True, summariseProps = True)
     ConfigFlags.dump()
 
-    
+
     cfg.store( open('TileTMDBDigitsMonitorAlgorithm.pkl','wb') )
 
-    sc = cfg.run(maxEvents=-1)
+    sc = cfg.run()
 
     import sys
     sys.exit(not sc.isSuccess())
diff --git a/TileCalorimeter/TileMonitoring/python/TileTMDBMonitorAlgorithm.py b/TileCalorimeter/TileMonitoring/python/TileTMDBMonitorAlgorithm.py
new file mode 100644
index 0000000000000000000000000000000000000000..8f2a57a9675072fa400008033daa1a7f9b4572ed
--- /dev/null
+++ b/TileCalorimeter/TileMonitoring/python/TileTMDBMonitorAlgorithm.py
@@ -0,0 +1,122 @@
+#
+#  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+#
+'''
+@file TileTMDBMonitorAlgorithm.py
+@brief Python configuration of TileTMDBMonitorAlgorithm algorithm for the Run III
+'''
+
+def TileTMDBMonitoringConfig(flags, **kwargs):
+    ''' Function to configure TileTMDBMonitorAlgorithm algorithm in the monitoring system.'''
+
+    # Define one top-level monitoring algorithm. The new configuration
+    # framework uses a component accumulator.
+    from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+    result = ComponentAccumulator()
+
+    from TileConditions.TileCablingSvcConfig import TileCablingSvcCfg
+    result.merge( TileCablingSvcCfg(flags) )
+
+    from TileConditions.TileTMDBConfig import TileTMDBCondAlgCfg
+    result.merge( TileTMDBCondAlgCfg(flags) )
+
+    kwargs.setdefault('fillDetailedHistograms', False)
+    #fillDetailedHistograms = kwargs['fillDetailedHistograms']
+
+    # The following class will make a sequence, configure algorithms, and link
+    # them to GenericMonitoringTools
+    from AthenaMonitoring import AthMonitorCfgHelper
+    helper = AthMonitorCfgHelper(flags,'TileTMDBMonitoring')
+
+    # Adding an TileTMDBMonitorAlgorithm algorithm to the helper
+    from AthenaConfiguration.ComponentFactory import CompFactory
+    tileTMDBMonAlg = helper.addAlgorithm(CompFactory.TileTMDBMonitorAlgorithm, 'TileTMDBMonAlg')
+
+    for k, v in kwargs.items():
+        setattr(tileTMDBMonAlg, k, v)
+
+    run = str(flags.Input.RunNumber[0])
+
+    # Configure histogram with TileTMDBMonAlg algorithm execution time
+    executeTimeGroup = helper.addGroup(tileTMDBMonAlg, 'TileTMDBMonExecuteTime', 'Tile/')
+    executeTimeGroup.defineHistogram('TIME_execute', path = 'TMDB', type='TH1F',
+                                     title = 'Time for execute TileTMDBMonAlg algorithm;time [#ms]',
+                                     xbins = 100, xmin = 0, xmax = 100000)
+
+    from TileMonitoring.TileMonitoringCfgHelper import addTileTMDB_1DHistogramsArray
+
+    addTileTMDB_1DHistogramsArray(helper, tileTMDBMonAlg, name = 'TMDB_MeanPulse',
+                                  xvalue = 'sampleNumber', value = 'sample', path = 'Tile/TMDB/MeanPulse',
+                                  title = 'Mean pulse shape in TMDB;#sample;[ADC]', type = 'TProfile',
+                                  run = run, xbins = 7, xmin = -0.5, xmax = 6.5, perModule = True)
+
+    addTileTMDB_1DHistogramsArray(helper, tileTMDBMonAlg, name = 'TMDB_Energy',
+                                  xvalue = 'energy', path = 'Tile/TMDB/NoiseAnalysis',
+                                  title = 'Energy in TMDB;E_{TMDB} [MeV]', type = 'TH1D', run = run,
+                                  xbins = 101, xmin = -1010, xmax = 1010, perModule = True)
+
+    errorTitle = 'Energy difference between TMDB and correspoding Tile Cell (D) PMT;E_{D_PMT} - E_{TMDB} [MeV]'
+    addTileTMDB_1DHistogramsArray(helper, tileTMDBMonAlg, name = 'TMDB_CalibrationError',
+                                  xvalue = 'error', path = 'Tile/TMDB/CalibError',
+                                  title = errorTitle, type = 'TH1D', run = run,
+                                  xbins = 101, xmin = -1010, xmax = 1010, perModule = True)
+
+    from TileMonitoring.TileMonitoringCfgHelper import addTileTMDB_2DHistogramsArray
+
+    addTileTMDB_2DHistogramsArray(helper, tileTMDBMonAlg, name = 'TMDB_Energy',
+                                  value = 'energy', title = 'Energy [MeV] in TMDB',
+                                  path = 'Tile/TMDB', type='TProfile2D', run = run)
+
+    addTileTMDB_2DHistogramsArray(helper, tileTMDBMonAlg, name = 'TMDB_PeakPosition',
+                                  value = 'peakPosition', title = 'Position of peak sample in TMDB',
+                                  path = 'Tile/TMDB', type='TProfile2D', run = run)
+
+    accumalator = helper.result()
+    result.merge(accumalator)
+    return result
+
+if __name__=='__main__':
+
+    # Setup the Run III behavior
+    from AthenaCommon.Configurable import Configurable
+    Configurable.configurableRun3Behavior = True
+
+    # Setup logs
+    from AthenaCommon.Logging import log
+    from AthenaCommon.Constants import INFO
+    log.setLevel(INFO)
+
+    # Set the Athena configuration flags
+    from AthenaConfiguration.AllConfigFlags import ConfigFlags
+
+    from AthenaConfiguration.TestDefaults import defaultTestFiles
+    ConfigFlags.Input.Files = defaultTestFiles.RAW
+    ConfigFlags.Output.HISTFileName = 'TileTMDBMonitorOutput.root'
+    ConfigFlags.DQ.useTrigger = False
+    ConfigFlags.DQ.enableLumiAccess = False
+    ConfigFlags.Exec.MaxEvents = 3
+    ConfigFlags.fillFromArgs()
+    ConfigFlags.lock()
+
+    # Initialize configuration object, add accumulator, merge, and run.
+    from AthenaConfiguration.MainServicesConfig import MainServicesCfg
+    cfg = MainServicesCfg(ConfigFlags)
+
+    from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
+    tileTypeNames = ['TileRawChannelContainer/TileRawChannelCnt',
+                     'TileRawChannelContainer/MuRcvRawChCnt',
+                     'TileDigitsContainer/MuRcvDigitsCnt']
+    cfg.merge( ByteStreamReadCfg(ConfigFlags, type_names = tileTypeNames) )
+
+    cfg.merge( TileTMDBMonitoringConfig(ConfigFlags) )
+
+    cfg.printConfig(withDetails = True, summariseProps = True)
+    ConfigFlags.dump()
+
+    cfg.store( open('TileTMDBMonitorAlgorithm.pkl','wb') )
+
+    sc = cfg.run()
+
+    import sys
+    # Success should be 0
+    sys.exit(not sc.isSuccess())
diff --git a/TileCalorimeter/TileMonitoring/src/TileCellMonitorAlgorithm.cxx b/TileCalorimeter/TileMonitoring/src/TileCellMonitorAlgorithm.cxx
index 8fe1238535fde0035dfb90ef0d3d242af89ee095..24f94da51c625ceccf3323d382dc778bffed86cb 100644
--- a/TileCalorimeter/TileMonitoring/src/TileCellMonitorAlgorithm.cxx
+++ b/TileCalorimeter/TileMonitoring/src/TileCellMonitorAlgorithm.cxx
@@ -75,6 +75,9 @@ StatusCode TileCellMonitorAlgorithm::initialize() {
   m_overThr300GeVOccupGroups = buildToolMap<std::vector<int>>(m_tools, "TileCellDetailOccMapOvThr300GeV",
                                                               Tile::MAX_ROS - 1, nL1Triggers);
 
+  m_eneDiffChanModGroups = buildToolMap<std::vector<int>>(m_tools, "TileCellEneDiffChanMod",
+                                                          Tile::MAX_ROS - 1, nL1Triggers);
+
   m_overThrOccupGainGroups = buildToolMap<std::vector<std::vector<int>>>(m_tools, "TileCellDetailOccMapOvThrGain",
                                                                          Tile::MAX_ROS - 1, Tile::MAX_GAIN, nL1Triggers);
 
@@ -105,6 +108,7 @@ StatusCode TileCellMonitorAlgorithm::initialize() {
   m_timeBalGroups = buildToolMap<int>(m_tools, "TileCellTimeBalance", Tile::MAX_ROS - 1);
   m_energyBalGroups = buildToolMap<int>(m_tools, "TileCellEnergyBalance", Tile::MAX_ROS - 1);
 
+
   return TileMonitorAlgorithm::initialize();
 }
 
@@ -194,6 +198,10 @@ StatusCode TileCellMonitorAlgorithm::fillHistograms( const EventContext& ctx ) c
   std::vector<int> overThr300GeVOccupModule[Tile::MAX_ROS - 1];
   std::vector<int> overThr300GeVOccupChannel[Tile::MAX_ROS - 1];
 
+  std::vector<int> eneDiff[Tile::MAX_ROS - 1];
+  std::vector<int> eneDiffChannel[Tile::MAX_ROS - 1];
+  std::vector<int> eneDiffModule[Tile::MAX_ROS - 1];
+
   std::vector<int> maskedOnFlyDrawers[Tile::MAX_ROS - 1];
   std::vector<int> maskedOnFlyChannel[Tile::MAX_ROS - 1];
 
@@ -560,6 +568,14 @@ StatusCode TileCellMonitorAlgorithm::fillHistograms( const EventContext& ctx ) c
             energyBal[partition1].push_back(energyRatio);
             energyBalModule[partition1].push_back(module);
 
+            eneDiff[partition1].push_back(energyDiff);
+            eneDiffChannel[partition1].push_back(channel1);
+            eneDiffModule[partition1].push_back(module);
+
+            eneDiff[partition2].push_back(-1.0 * energyDiff);
+            eneDiffChannel[partition2].push_back(channel2);
+            eneDiffModule[partition2].push_back(module);
+
             if (fillEneAndTimeDiff) {
               sampEnergyDiff[partition1][sample].push_back(energyDiff);
             }
@@ -786,6 +802,15 @@ StatusCode TileCellMonitorAlgorithm::fillHistograms( const EventContext& ctx ) c
       }
     }
 
+    if (!eneDiff[partition].empty()) {
+      auto monEnergyDiff = Monitored::Collection("energyDiff", eneDiff[partition]);
+      auto monModule = Monitored::Collection("module", eneDiffModule[partition]);
+      auto monChannel = Monitored::Collection("channel", eneDiffChannel[partition]);
+      for (int l1TriggerIdx : l1TriggersIndices) {
+        fill(m_tools[m_eneDiffChanModGroups[partition][l1TriggerIdx]], monModule, monChannel, monEnergyDiff);
+      }
+    }
+
     for (unsigned int gain = 0; gain < Tile::MAX_GAIN; ++gain) {
       if (!overThrOccupGainModule[partition][gain].empty()) {
         auto monModule = Monitored::Collection("module", overThrOccupGainModule[partition][gain]);
diff --git a/TileCalorimeter/TileMonitoring/src/TileCellMonitorAlgorithm.h b/TileCalorimeter/TileMonitoring/src/TileCellMonitorAlgorithm.h
index a0b6a507c07e3bd192fee8137d04ba2133efbdcb..4814f13d1576ef9678092af436e5fa46404e2384 100644
--- a/TileCalorimeter/TileMonitoring/src/TileCellMonitorAlgorithm.h
+++ b/TileCalorimeter/TileMonitoring/src/TileCellMonitorAlgorithm.h
@@ -117,6 +117,7 @@ class TileCellMonitorAlgorithm : public TileMonitorAlgorithm {
     std::vector<std::vector<int>> m_overThrOccupGroups;
     std::vector<std::vector<int>> m_overThr30GeVOccupGroups;
     std::vector<std::vector<int>> m_overThr300GeVOccupGroups;
+    std::vector<std::vector<int>> m_eneDiffChanModGroups;
     std::vector<std::vector<std::vector<int>>> m_overThrOccupGainGroups;
 
     std::vector<std::vector<std::vector<int>>> m_chanTimeSampGroups;
diff --git a/TileCalorimeter/TileMonitoring/src/TileTMDBDigitsMonitorAlgorithm.cxx b/TileCalorimeter/TileMonitoring/src/TileTMDBDigitsMonitorAlgorithm.cxx
index 26ce59a572b403a9bd84dfd32bfe1dc595ac7b33..82a4305b5c36af25d727ba2df930b52bab67519b 100644
--- a/TileCalorimeter/TileMonitoring/src/TileTMDBDigitsMonitorAlgorithm.cxx
+++ b/TileCalorimeter/TileMonitoring/src/TileTMDBDigitsMonitorAlgorithm.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // Tile includes
@@ -7,7 +7,7 @@
 #include "TileIdentifier/TileHWID.h"
 #include "TileCalibBlobObjs/TileCalibUtils.h"
 
-#include <math.h> 
+#include <math.h>
 // Athena includes
 #include "StoreGate/ReadHandle.h"
 
@@ -36,9 +36,9 @@ StatusCode TileTMDBDigitsMonitorAlgorithm::initialize() {
   using Tile = TileCalibUtils;
   using namespace Monitored;
 
-  m_hfnGroups = buildToolMap<int>(m_tools, "TMDBDigitsHFN", Tile::MAX_ROS - 1);
-  m_pedGroups = buildToolMap<int>(m_tools, "TMDBDigitsPedestal", Tile::MAX_ROS - 1);    
-  m_ampGroups = buildToolMap<int>(m_tools, "TMDBDigitsAmplitude", Tile::MAX_ROS - 1);
+  m_hfnGroups = buildToolMap<int>(m_tools, "TMDB_DigitsHFN", Tile::MAX_ROS - 1);
+  m_pedGroups = buildToolMap<int>(m_tools, "TMDB_DigitsPedestal", Tile::MAX_ROS - 1);
+  m_ampGroups = buildToolMap<int>(m_tools, "TMDB_DigitsAmplitude", Tile::MAX_ROS - 1);
 
 
     if (m_nChannels.size() != (Tile::MAX_ROS - 1)) {
@@ -49,16 +49,15 @@ StatusCode TileTMDBDigitsMonitorAlgorithm::initialize() {
     std::vector<std::string> partitionName = {"LBA", "LBC", "EBA", "EBC"}; // ROS - 1 to partition name map
     for (unsigned int partition = 0; partition < Tile::MAX_ROS-1; ++partition) {
       m_cellPedGroups.push_back(buildToolMap<int>(m_tools,
-                                                  "TMDBDigitsCellPedestal_" + partitionName[partition],
+                                                  "TMDB_DigitsCellPedestal_" + partitionName[partition],
                                                   m_nChannels[partition]));
       m_cellHFNGroups.push_back(buildToolMap<int>(m_tools,
-                                                  "TMDBDigitsCellHFN_" + partitionName[partition],
+                                                  "TMDB_DigitsCellHFN_" + partitionName[partition],
                                                   m_nChannels[partition]));
       m_cellAmpGroups.push_back(buildToolMap<int>(m_tools,
-                                                  "TMDBDigitsCellAmplitude_" + partitionName[partition],
-                                                  m_nChannels[partition]));                                                                                        
+                                                  "TMDB_DigitsCellAmplitude_" + partitionName[partition],
+                                                  m_nChannels[partition]));
     }
-    
 
   return StatusCode::SUCCESS;
 }
@@ -83,7 +82,7 @@ StatusCode TileTMDBDigitsMonitorAlgorithm::fillHistograms( const EventContext& c
 
   for (IdentifierHash hash : digitsContainer->GetAllCurrentHashes()) {
     const TileDigitsCollection* digitsCollection = digitsContainer->indexFindPtr (hash);
- 
+
     int fragId = digitsCollection->identify();
     unsigned int drawer = (fragId & 0x3F);
     unsigned int ros = fragId >> 8;
@@ -110,7 +109,7 @@ StatusCode TileTMDBDigitsMonitorAlgorithm::fillHistograms( const EventContext& c
 
         double ped = digits[0];
         pedestals[partition].push_back(ped);
-  
+
         mean_samp /= n_digits;
         rms_samp = rms_samp / n_digits - mean_samp * mean_samp;
         rms_samp = (rms_samp > 0.0) ? sqrt(rms_samp * n_digits / (n_digits - 1)) : 0.0;
@@ -132,7 +131,7 @@ StatusCode TileTMDBDigitsMonitorAlgorithm::fillHistograms( const EventContext& c
          cellAmplitudes[partition][channel].push_back(amplitude);
         }
 
-      } 
+      }
     }
   }
 
@@ -146,27 +145,27 @@ StatusCode TileTMDBDigitsMonitorAlgorithm::fillHistograms( const EventContext& c
 
       auto monHFN = Monitored::Collection("HFN", hfns[partition]);
       fill(m_tools[m_hfnGroups[partition]], monModule, monChannel, monHFN);
-    
+
       auto monAmplitude = Monitored::Collection("amplitude", amplitudes[partition]);
-      fill(m_tools[m_ampGroups[partition]], monModule, monChannel, monAmplitude);   
+      fill(m_tools[m_ampGroups[partition]], monModule, monChannel, monAmplitude);
 
       for (int channel = 0; channel < int(m_nChannels[partition]); ++channel) {
         if (!cellPedestals[partition][channel].empty()) {
           auto monPedestal = Monitored::Collection("pedestal", cellPedestals[partition][channel]);
-          fill(m_tools[m_cellPedGroups[partition][channel]], monPedestal);          
+          fill(m_tools[m_cellPedGroups[partition][channel]], monPedestal);
         }
         if (!cellHFNs[partition][channel].empty()) {
           auto monHFN = Monitored::Collection("HFN", cellHFNs[partition][channel]);
-          fill(m_tools[m_cellHFNGroups[partition][channel]], monHFN);          
+          fill(m_tools[m_cellHFNGroups[partition][channel]], monHFN);
         }
         if (!cellAmplitudes[partition][channel].empty()) {
           auto monAmplitude = Monitored::Collection("amplitude", cellAmplitudes[partition][channel]);
-          fill(m_tools[m_cellAmpGroups[partition][channel]], monAmplitude);          
+          fill(m_tools[m_cellAmpGroups[partition][channel]], monAmplitude);
         }
-      }      
+      }
     }
-  }   
+  }
+
 
-    
   return StatusCode::SUCCESS;
 }
diff --git a/TileCalorimeter/TileMonitoring/src/TileTMDBMonitorAlgorithm.cxx b/TileCalorimeter/TileMonitoring/src/TileTMDBMonitorAlgorithm.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a06b73cf5adb1cf569c54a85115a9ea777edd8b3
--- /dev/null
+++ b/TileCalorimeter/TileMonitoring/src/TileTMDBMonitorAlgorithm.cxx
@@ -0,0 +1,208 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TileTMDBMonitorAlgorithm.h"
+#include "TileIdentifier/TileHWID.h"
+
+
+#include "StoreGate/ReadHandle.h"
+#include "StoreGate/ReadCondHandle.h"
+
+StatusCode TileTMDBMonitorAlgorithm::initialize() {
+
+  ATH_MSG_DEBUG("in initialize()");
+
+  // initialize superclass
+  ATH_CHECK( AthMonitorAlgorithm::initialize() );
+
+  ATH_CHECK( detStore()->retrieve(m_tileHWID) );
+
+  ATH_CHECK( m_cablingSvc.retrieve() );
+  m_cabling = m_cablingSvc->cablingService();
+
+  ATH_CHECK( m_rawChannelContainerKey.initialize() );
+  ATH_CHECK( m_muRcvRawChannelContainerKey.initialize() );
+  ATH_CHECK( m_muRcvDigitsContainerKey.initialize() );
+  ATH_CHECK( m_tileCondToolTMDB.retrieve() );
+
+  if (m_pulseEnergyRange.size() != 2) {
+    ATH_MSG_FATAL( "Size of PulseEnergyRange should be 2 (from,to), but is " << m_pulseEnergyRange.size() );
+    return StatusCode::FAILURE;
+  }
+
+  if (m_energyRange.size() != 2) {
+    ATH_MSG_FATAL( "Size of EnergyRange should be 2 (from,to), but is " << m_energyRange.size() );
+    return StatusCode::FAILURE;
+  }
+
+  using namespace Monitored;
+
+  m_peakGroups = buildToolMap<int>(m_tools, "TMDB_PeakPosition", Tile::MAX_ROS - 1);
+  m_energyGroups = buildToolMap<int>(m_tools, "TMDB_Energy", Tile::MAX_ROS - 1);
+
+  std::vector<std::string> partitionName = {"LBA", "LBC", "EBA", "EBC"}; // ROS - 1 to partition name map
+  int nChannels[] = {8, 8, 4, 4};
+  for (unsigned int partition = 0; partition < Tile::MAX_ROS - 1; ++partition) {
+
+    m_pulseGroups.push_back(buildToolMap<std::vector<int>>(m_tools,
+                                                           "TMDB_MeanPulse_" + partitionName[partition],
+                                                           Tile::MAX_DRAWER, nChannels[partition]));
+
+    m_chanEnergyGroups.push_back(buildToolMap<std::vector<int>>(m_tools,
+                                                                "TMDB_Energy_" + partitionName[partition],
+                                                                Tile::MAX_DRAWER, nChannels[partition]));
+
+    m_calibErrorGroups.push_back(buildToolMap<std::vector<int>>(m_tools,
+                                                                "TMDB_CalibrationError_" + partitionName[partition],
+                                                                Tile::MAX_DRAWER, nChannels[partition]));
+
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode TileTMDBMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
+
+  //  using Tile = TileCalibUtils;
+
+  // In case you want to measure the execution time
+  auto timer = Monitored::Timer("TIME_execute");
+
+  float referenceEnergies[Tile::MAX_ROS - 1][Tile::MAX_DRAWER][8] = {{{0}}};
+
+  SG::ReadHandle<TileRawChannelContainer> rawChannelContainer(m_rawChannelContainerKey, ctx);
+  ATH_CHECK( rawChannelContainer.isValid() );
+
+  for (const TileRawChannelCollection* rawChannelCollection : *rawChannelContainer) {
+    if (rawChannelCollection->empty() ) continue;
+
+    int fragId = rawChannelCollection->identify();
+    int drawer = fragId & 0x3F;
+    int ros = fragId >> 8;
+    int partition = ros - 1;
+
+    for (const TileRawChannel* rawChannel : *rawChannelCollection) {
+
+      HWIdentifier adc_id = rawChannel->adc_HWID();
+      int channel = m_tileHWID->channel(adc_id);
+      float energy = rawChannel->amplitude();
+
+      std::map<int, int>::const_iterator it = m_cellTMDB[partition].get().find(channel);
+      if (it != m_cellTMDB[partition].get().end()) {
+        int channelTMDB = (*it).second;
+        if ((ros < 3) && (drawer % 2 == 0)) {
+          ++channelTMDB; // In LB TMDB channels in even drawers are shifted by one
+        }
+        referenceEnergies[partition][drawer][channelTMDB] = energy;
+      }
+
+    }
+  }
+
+  std::vector<float> energies[Tile::MAX_ROS - 1];
+  std::vector<int> energyDrawers[Tile::MAX_ROS - 1];
+  std::vector<int> energyChannels[Tile::MAX_ROS - 1];
+
+  SG::ReadHandle<TileRawChannelContainer> muRcvRawChannelContainer(m_muRcvRawChannelContainerKey, ctx);
+  ATH_CHECK( muRcvRawChannelContainer.isValid() );
+
+  for (const TileRawChannelCollection* muRcvRawChannelCollection : *muRcvRawChannelContainer) {
+    if (muRcvRawChannelCollection->empty() ) continue;
+
+    int fragId = muRcvRawChannelCollection->identify();
+    int drawer = fragId & 0x3F;
+    int ros = fragId >> 8;
+    unsigned int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
+    int partition = ros - 1;
+
+    for (const TileRawChannel* muRcvRawChannel : *muRcvRawChannelCollection) {
+      HWIdentifier adc_id = muRcvRawChannel->adc_HWID();
+      int channel = m_tileHWID->channel(adc_id);
+      float amplitude = muRcvRawChannel->amplitude();
+      float energy = m_tileCondToolTMDB->channelCalib(drawerIdx, channel, amplitude);
+
+      energyDrawers[partition].push_back(drawer);
+      energyChannels[partition].push_back(channel);
+      energies[partition].push_back(energy);
+
+      auto monEnergy = Monitored::Scalar<float>("energy", energy);
+      fill(m_tools[m_chanEnergyGroups[partition][drawer][channel]], monEnergy);
+
+      auto monCalibError = Monitored::Scalar<float>("error", referenceEnergies[partition][drawer][channel] - energy);
+      fill(m_tools[m_calibErrorGroups[partition][drawer][channel]], monCalibError);
+
+      ATH_MSG_VERBOSE(Tile::getDrawerString(ros, drawer)
+                      << " TMDB channel " << channel
+                      << ": energy [MeV] = " << energy);
+    }
+  }
+
+
+  std::vector<float> peakPositions[Tile::MAX_ROS - 1];
+  std::vector<int> peakPositionDrawers[Tile::MAX_ROS - 1];
+  std::vector<int> peakPositionChannels[Tile::MAX_ROS - 1];
+
+  SG::ReadHandle<TileDigitsContainer> muRcvDigitsContainer(m_muRcvDigitsContainerKey, ctx);
+  ATH_CHECK( muRcvDigitsContainer.isValid() );
+
+  for (const TileDigitsCollection* muRcvDigitsCollection : *muRcvDigitsContainer) {
+    if (muRcvDigitsCollection->empty() ) continue;
+
+    int fragId = muRcvDigitsCollection->identify();
+    int drawer = fragId & 0x3F;
+    int ros = fragId >> 8;
+    int partition = ros - 1;
+
+    for (const TileDigits* muRcvDigits : *muRcvDigitsCollection) {
+      HWIdentifier adc_id = muRcvDigits->adc_HWID();
+      int channel = m_tileHWID->channel(adc_id);
+
+      float energy = referenceEnergies[partition][drawer][channel];
+      if ((energy > m_pulseEnergyRange[0]) && (energy < m_pulseEnergyRange[1])) {
+        peakPositionDrawers[partition].push_back(drawer);
+        peakPositionChannels[partition].push_back(channel);
+
+        std::vector<float> samples = muRcvDigits->samples();
+        unsigned int nSamples = samples.size();
+        std::vector<int> sampleNumbers(nSamples, 0);
+        std::iota(sampleNumbers.begin(), sampleNumbers.end(), 0);
+
+        auto monSample = Monitored::Collection("sample", samples);
+        auto monSampleNumber = Monitored::Collection("sampleNumber", sampleNumbers);
+
+        fill(m_tools[m_pulseGroups[partition][drawer][channel]], monSampleNumber, monSample);
+
+        int peakPosition = std::distance(samples.begin(), std::max_element(samples.begin(), samples.end()));
+        peakPositions[partition].push_back(peakPosition);
+        ATH_MSG_VERBOSE(Tile::getDrawerString(ros, drawer)
+                        << " TMDB channel " << channel
+                        << ": peak position = " << peakPosition);
+      }
+    }
+  }
+
+
+
+  for (unsigned int partition = 0; partition < Tile::MAX_ROS - 1; ++partition) {
+    if (!energies[partition].empty()) {
+      auto monModule = Monitored::Collection("module", energyDrawers[partition]);
+      auto monChannel = Monitored::Collection("channel", energyChannels[partition]);
+      auto monEnergy = Monitored::Collection("energy", energies[partition]);
+      fill(m_tools[m_energyGroups[partition]], monModule, monChannel, monEnergy);
+    }
+
+    if (!peakPositions[partition].empty()) {
+      auto monModule = Monitored::Collection("module", peakPositionDrawers[partition]);
+      auto monChannel = Monitored::Collection("channel", peakPositionChannels[partition]);
+      auto monPeakPosition = Monitored::Collection("peakPosition", peakPositions[partition]);
+      fill(m_tools[m_peakGroups[partition]], monModule, monChannel, monPeakPosition);
+    }
+  }
+
+
+  fill("TileTMDBMonExecuteTime", timer);
+
+  return StatusCode::SUCCESS;
+}
diff --git a/TileCalorimeter/TileMonitoring/src/TileTMDBMonitorAlgorithm.h b/TileCalorimeter/TileMonitoring/src/TileTMDBMonitorAlgorithm.h
new file mode 100644
index 0000000000000000000000000000000000000000..f7f604bb510ee3870278c1ec581116c3a6e07969
--- /dev/null
+++ b/TileCalorimeter/TileMonitoring/src/TileTMDBMonitorAlgorithm.h
@@ -0,0 +1,94 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TILEMONITORING_TILETMDBMONITORALGORITHM_H
+#define TILEMONITORING_TILETMDBMONITORALGORITHM_H
+
+#include "TileEvent/TileDigitsContainer.h"
+#include "TileEvent/TileRawChannelContainer.h"
+#include "TileConditions/ITileCondToolTMDB.h"
+#include "TileConditions/TileCablingSvc.h"
+#include "TileCalibBlobObjs/TileCalibUtils.h"
+
+#include "AthenaMonitoring/AthMonitorAlgorithm.h"
+#include "AthenaMonitoringKernel/Monitored.h"
+#include "StoreGate/ReadHandleKey.h"
+#include "StoreGate/ReadCondHandleKey.h"
+
+class TileHWID;
+class TileCablingService;
+
+/** @class TileTMDBMonitorAlgorithm
+ *  @brief Class for Tile TMDB based monitoring
+ */
+
+class TileTMDBMonitorAlgorithm: public AthMonitorAlgorithm {
+
+  public:
+
+    using  AthMonitorAlgorithm::AthMonitorAlgorithm;
+    virtual ~TileTMDBMonitorAlgorithm() = default;
+    virtual StatusCode initialize() override;
+    virtual StatusCode fillHistograms(const EventContext& ctx) const override;
+
+  private:
+
+    Gaudi::Property<std::vector<float>> m_pulseEnergyRange{this,
+        "PulseEnergyRange", {1000.0F, 5000.F}, "Energy [MeV] range for pulse shape"};
+
+    Gaudi::Property<std::vector<float>> m_energyRange{this,
+        "EnergyRange", {100.0F, 10000.F}, "Energy [MeV] range for pulse shape"};
+
+    Gaudi::Property<bool> m_fillDetailedHistograms{this,
+        "fillDetailedHistograms", false, "Fill monitoring histograms per TMDB channel"};
+
+    SG::ReadHandleKey<TileRawChannelContainer> m_rawChannelContainerKey{this,
+        "TileRawChannelContainer", "TileRawChannelCnt", "Input Tile raw channel container key"};
+
+    SG::ReadHandleKey<TileRawChannelContainer> m_muRcvRawChannelContainerKey{this,
+        "MuonReceiverRawChannelContainer", "MuRcvRawChCnt", "Input Tile muon receiver raw channel container key"};
+
+    SG::ReadHandleKey<TileDigitsContainer> m_muRcvDigitsContainerKey{this,
+        "MuonReceiverDigitsContainer", "MuRcvDigitsCnt", "Input Tile muon receiver digits container key"};
+
+    ToolHandle<ITileCondToolTMDB> m_tileCondToolTMDB{this,
+        "TileCondToolTMDB", "TileCondToolTMDB", "Tile TMDB conditions tool"};
+
+    /**
+     * @brief Name of Tile cabling service
+     */
+    ServiceHandle<TileCablingSvc> m_cablingSvc{ this,
+        "TileCablingSvc", "TileCablingSvc", "The Tile cabling service"};
+
+    const TileHWID* m_tileHWID{nullptr};
+    const TileCablingService* m_cabling{nullptr};
+
+    std::vector<int> m_peakGroups;
+    std::vector<int> m_energyGroups;
+
+    std::vector<std::vector<std::vector<int>>> m_chanEnergyGroups;
+    std::vector<std::vector<std::vector<int>>> m_calibErrorGroups;
+    std::vector<std::vector<std::vector<int>>> m_pulseGroups;
+
+    using Tile = TileCalibUtils;
+
+    // Mapping from Tile raw channels to TMDB in LB for odd modules,
+    // in even modules TMDB channels are shifted by 1
+    const std::map<int, int> m_cellTMDB_LB{{0, 0 /*D0*/},
+                                           {13, 1 /*D1L*/}, {14, 2 /*D1R*/},
+                                           {24, 3 /*D2R*/}, {25, 4 /*D2L*/},
+                                           {41, 5 /*D3L*/}, {44, 6 /*D3R*/}};
+
+    // Mapping from Tile raw channels to TMDB in EB
+    const std::map<int, int> m_cellTMDB_EB{{16, 0 /*D5R*/}, {17, 1 /*D5L*/},
+                                           {37, 2 /*D6L*/}, {38, 3 /*D6R*/}};
+
+    std::reference_wrapper<const std::map<int, int>> m_cellTMDB[Tile::MAX_ROS - 1] = {m_cellTMDB_LB,
+                                                                                      m_cellTMDB_LB,
+                                                                                      m_cellTMDB_EB,
+                                                                                      m_cellTMDB_EB};
+};
+
+
+#endif // TILEMONITORING_TILETMDBMONITORALGORITHM_H
diff --git a/TileCalorimeter/TileMonitoring/src/components/TileMonitoring_entries.cxx b/TileCalorimeter/TileMonitoring/src/components/TileMonitoring_entries.cxx
index 6b42257bfd6fc082b30f323166ea0a535b76ab26..af8940d7f307e49b32971cf86043199c580ff5da 100644
--- a/TileCalorimeter/TileMonitoring/src/components/TileMonitoring_entries.cxx
+++ b/TileCalorimeter/TileMonitoring/src/components/TileMonitoring_entries.cxx
@@ -37,6 +37,7 @@
 #include "../TileMuonFitMonitorAlgorithm.h"
 #include "../TileRODMonitorAlgorithm.h"
 #include "../TileTMDBDigitsMonitorAlgorithm.h"
+#include "../TileTMDBMonitorAlgorithm.h"
 
 DECLARE_COMPONENT( TileFatherMonTool )
 DECLARE_COMPONENT( TilePaterMonTool )
@@ -77,3 +78,4 @@ DECLARE_COMPONENT( TileRawChannelNoiseMonitorAlgorithm )
 DECLARE_COMPONENT( TileMuonFitMonitorAlgorithm )
 DECLARE_COMPONENT( TileRODMonitorAlgorithm )
 DECLARE_COMPONENT( TileTMDBDigitsMonitorAlgorithm )
+DECLARE_COMPONENT( TileTMDBMonitorAlgorithm )
diff --git a/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileDigitsContByteStreamTool.h b/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileDigitsContByteStreamTool.h
index 288f01833424c58455b8132252f6e718fbe2911b..46a14fb572374351e3c9864562fb9b50e8373568 100644
--- a/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileDigitsContByteStreamTool.h
+++ b/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileDigitsContByteStreamTool.h
@@ -59,6 +59,7 @@ class TileDigitsContByteStreamTool: public AthAlgTool {
     bool m_verbose;
     bool m_doFragType1;
     bool m_doFragType5;
+    int  m_runPeriod;
 };
 
 #endif
diff --git a/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileMuRcvContByteStreamTool.h b/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileMuRcvContByteStreamTool.h
index 5aa481e6928e6c5fd8e58695f2df7207c345e874..2347ea923c2c621ab401c47165e37613ac1fd942 100644
--- a/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileMuRcvContByteStreamTool.h
+++ b/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileMuRcvContByteStreamTool.h
@@ -62,7 +62,7 @@ class TileMuRcvContByteStreamTool: public AthAlgTool {
 
   const TileHid2RESrcID* m_hid2re;
 
-  //bool m_verbose;
+  int m_runPeriod;
 };
 
 #endif
diff --git a/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Decoder.h b/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Decoder.h
index fb00fc0f4ab96eb5465c64881e6a1efe825ff12e..f724cb0807e4367b2f37c823977f0d2d6e2deea5 100644
--- a/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Decoder.h
+++ b/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Decoder.h
@@ -578,6 +578,7 @@ class TileROD_Decoder: public AthAlgTool {
 
     unsigned int m_maxChannels;
     bool m_checkMaskedDrawers;
+    int m_runPeriod;
 
     const uint32_t * get_data(const ROBData * rob) const {
       const uint32_t * p;
diff --git a/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Encoder.h b/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Encoder.h
index a5395dd9dcd602dafd008d105b4d3599cdd4852d..92485ba25fb93c9a41dc705d04e385137033c898 100644
--- a/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Encoder.h
+++ b/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Encoder.h
@@ -53,7 +53,7 @@ class TileROD_Encoder
     /** set all necessary parameters for the encoder
      */
     void setTileHWID(const TileHWID* tileHWID, bool verbose, unsigned int type = 4);
-    void setTileHWID(const TileHWID* tileHWID);
+    void setTileHWID(const TileHWID* tileHWID, int m_runPeriod);
 
     /** set OF algorigtm type and amplitude units for a drawer
      */
@@ -147,6 +147,7 @@ class TileROD_Encoder
     unsigned int m_rChUnit;
 
     int m_maxChannels;
+    int m_runPeriod;
 };
 
 #endif
diff --git a/TileCalorimeter/TileSvc/TileByteStream/src/TileDigitsContByteStreamTool.cxx b/TileCalorimeter/TileSvc/TileByteStream/src/TileDigitsContByteStreamTool.cxx
index b4338560885265252374c177bdedfb4f6c8b04ac..63184382aaa0c757e37dc1a163ce0f2efe6ffeac 100644
--- a/TileCalorimeter/TileSvc/TileByteStream/src/TileDigitsContByteStreamTool.cxx
+++ b/TileCalorimeter/TileSvc/TileByteStream/src/TileDigitsContByteStreamTool.cxx
@@ -36,6 +36,7 @@ TileDigitsContByteStreamTool::TileDigitsContByteStreamTool( const std::string& t
   , m_tileHWID(0)
   , m_hid2re(0)
   , m_verbose(false)
+  , m_runPeriod(0)
 {
   declareInterface< TileDigitsContByteStreamTool >( this );
   declareProperty("DoFragType1", m_doFragType1 = false);
@@ -56,6 +57,8 @@ StatusCode TileDigitsContByteStreamTool::initialize() {
   ATH_CHECK( dec.retrieve() );
 
   m_hid2re = dec->getHid2reHLT();
+  TileCablingService *cabling = TileCablingService::getInstance();
+  m_runPeriod = cabling->runPeriod();
 
   return StatusCode::SUCCESS;
 }
@@ -85,7 +88,7 @@ StatusCode TileDigitsContByteStreamTool::convert(DIGITS* digitsContainer, FullEv
 
     if (isTMDB){  
        reid = m_hid2re->getRodTileMuRcvID(frag_id);
-       mapEncoder[reid].setTileHWID(m_tileHWID);
+       mapEncoder[reid].setTileHWID(m_tileHWID,m_runPeriod);
     } else {
        reid = m_hid2re->getRodID(frag_id);
        mapEncoder[reid].setTileHWID(m_tileHWID, m_verbose, 1);
diff --git a/TileCalorimeter/TileSvc/TileByteStream/src/TileMuRcvContByteStreamTool.cxx b/TileCalorimeter/TileSvc/TileByteStream/src/TileMuRcvContByteStreamTool.cxx
index 7c17a17b6de0a0eeb17d60fd7a7f9b442dcf5e84..a81d7fb48185dcd6447e91e502d18c1696ce4227 100644
--- a/TileCalorimeter/TileSvc/TileByteStream/src/TileMuRcvContByteStreamTool.cxx
+++ b/TileCalorimeter/TileSvc/TileByteStream/src/TileMuRcvContByteStreamTool.cxx
@@ -47,7 +47,7 @@ TileMuRcvContByteStreamTool::TileMuRcvContByteStreamTool(const std::string& type
   : AthAlgTool(type, name, parent)
   , m_tileHWID(0)
   , m_hid2re(0)
-    //, m_verbose(false)
+  , m_runPeriod(0)
 {
   declareInterface<TileMuRcvContByteStreamTool>(this);
 }
@@ -67,6 +67,8 @@ StatusCode TileMuRcvContByteStreamTool::initialize() {
   ATH_CHECK( dec.retrieve() );
 
   m_hid2re = dec->getHid2reHLT();
+  TileCablingService *cabling = TileCablingService::getInstance();
+  m_runPeriod = cabling->runPeriod();
 
   return StatusCode::SUCCESS;
 }
@@ -98,7 +100,7 @@ StatusCode TileMuRcvContByteStreamTool::convert(TileMuonReceiverContainer* cont,
       n++;
       frag_id = (*it_cont)->identify();
       reid = m_hid2re->getRodTileMuRcvID(frag_id);
-      mapEncoder[reid].setTileHWID(m_tileHWID);
+      mapEncoder[reid].setTileHWID(m_tileHWID,m_runPeriod);
       const TileMuonReceiverObj* tileMuRcv = *it_cont;	
       mapEncoder[reid].addTileMuRcvObj(tileMuRcv);
     }                                                            
diff --git a/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Decoder.cxx b/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Decoder.cxx
index c327a68020480d7ad3dadb60ecc36d35d423cd3b..022f301511933147e857e5dd99d7cd149342fe2f 100644
--- a/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Decoder.cxx
+++ b/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Decoder.cxx
@@ -43,8 +43,12 @@ TileROD_Decoder::TileROD_Decoder(const std::string& type, const std::string& nam
   , m_hid2reHLT(nullptr)
   , m_maxChannels(TileCalibUtils::MAX_CHAN)
   , m_checkMaskedDrawers(false)
-{
+  , m_runPeriod(0){
+
   declareInterface<TileROD_Decoder>(this);
+
+  m_WarningCounter = 0;
+  m_ErrorCounter = 0;
  
   for (std::atomic<const uint32_t*>& p : m_OFPtrs) {
     p = nullptr;
@@ -130,7 +134,9 @@ StatusCode TileROD_Decoder::initialize() {
     ATH_CHECK( m_tileBadChanTool.retrieve() );
   }
 
-  m_maxChannels = TileCablingService::getInstance()->getMaxChannels();
+  const TileCablingService *cablingService = TileCablingService::getInstance();
+  m_maxChannels    = cablingService->getMaxChannels();
+  m_runPeriod      = cablingService->runPeriod();
 
   m_Rw2Cell[0].reserve(m_maxChannels);
   m_Rw2Cell[1].reserve(m_maxChannels);
@@ -4469,6 +4475,7 @@ void TileROD_Decoder::unpack_frag41( uint32_t collid, uint32_t version, const ui
 
 void TileROD_Decoder::unpack_frag42( uint32_t sourceid, uint32_t version, const uint32_t* p, int datasize, TileMuonReceiverContainer &v ) const {
 
+  // == RUN 2 ==
   // results are hold in 3 16-bit words.
   //
   //    32nd bit -> |        results2       ||        results1       | <- 1st bit
@@ -4486,36 +4493,67 @@ void TileROD_Decoder::unpack_frag42( uint32_t sourceid, uint32_t version, const
   // bit-2        .
   // bit-1        .
   // bit-0 -> result.at(3)
+  //
+  // == RUN 3 ==
+  // results are hold in 3 16-bit words.
+  //
+  //               32nd bit -> |         results2 [16:31]            ||           results1 [0:15]           | <- 1st bit
+  //               32nd bit -> |            0x0   [16:31]            ||           results3 [0:15]           | <- 1st bit
+  //
+  //               32nd bit -> | 0x0 [12:15] | m-5 | m-4 | m-3 | m-2 || 0x0 [12:15] | m-3 | m-2 | m-1 | m-0 | <- 1st bit
+  //                           |          0x0 [16:31]                || 0x0 [12:15] | m-7 | m-6 | m-5 | m-4 |
+  //
+  // For each module m-X there is a 3-bit word with the results for a threshold
+  //
+  //                    |  d5+d6  |  d6   |  d5  |
+  //                    |   bit2  |  bit1 | bit0 |
+  //
+
+  int nbit=0;
+  int nmod=0;
+  uint32_t word=0x0;
 
-  int nbit,nmod;
-  uint32_t word;
   int drawer = (sourceid & 0xf0000) >> 8; // get ROS number from source ID
   if (drawer<0x300) { // barrel
     nbit = 4;
     nmod = 4;
     drawer |= ((sourceid & 0x0000f) << 2);
     word = (datasize > 0) ? p[0] : 0; // just use first word, although expect all zeros for the moment
-  } else {
+  } else { // extended barrel
     nbit = 4;
     nmod = 8;
     drawer |= ((sourceid & 0x0000f) << 3);
-    word = (datasize > 1) ? (p[1] << 20) | ((p[0] >> 8) & 0xff000) | ((p[0] >> 4) & 0xfff) : 0;
+    if (m_runPeriod<=2) {
+       word = (datasize > 1) ? (p[1] << 20) | ((p[0] >> 8) & 0xff000) | ((p[0] >> 4) & 0xfff) : 0;
+    } else {
+       word = (datasize > 1) ? (p[1] << 12) | (p[0] & 0xfff) : 0;
+    }
   }
 
   std::vector<bool> result(nbit);
   for (int j = 0; j < nmod; ++j) { // loop over modules
     for (int k = nbit-1; k >= 0; --k) { // loop over bits of one module in inversed order
-      result[k] = ((word & 1) != 0);
-      word >>= 1;
+      if (m_runPeriod<=2) {
+          result[k] = (word & 1);
+	  word >>= 1;
+      } else {
+          if (k==0) {
+	     result[k]=0;
+	  } else {
+	     result[k] = (word & 1);
+	     word >>= 1;
+	  }
+      }
     }
-
     TileMuonReceiverObj * obj = new TileMuonReceiverObj(drawer, result);
     v.push_back(obj);
-
     ++drawer;
   }
-  
+
   if (msgLvl(MSG::DEBUG)) {
+    if (m_runPeriod<=2) msg(MSG::DEBUG) << "TMDB version for RUN2 simulation (2014)" <<endmsg;
+    else msg(MSG::DEBUG) << "TMDB version for RUN3 simulation (2020)" <<endmsg;
+
     msg(MSG::DEBUG) << " TileROD_Decoder::unpack_frag42  source ID: 0x" << MSG::hex << sourceid << MSG::dec
                     << " version: " << version << endmsg;
 
diff --git a/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Encoder.cxx b/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Encoder.cxx
index 937d2dba637ed6fbe79d9432048c2660451fddf2..f46c6aa53b82372af5dad19ff9b86c3e6826f991 100644
--- a/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Encoder.cxx
+++ b/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Encoder.cxx
@@ -28,7 +28,8 @@ TileROD_Encoder::TileROD_Encoder():
   m_type(0), 
   m_unitType(0),
   m_rChUnit(0),
-  m_maxChannels(TileCalibUtils::MAX_CHAN) {
+  m_maxChannels(TileCalibUtils::MAX_CHAN),
+  m_runPeriod(0){
 }
 
 
@@ -56,8 +57,9 @@ void TileROD_Encoder::setTileHWID(const TileHWID* tileHWID, bool verbose, unsign
   }
 }
 
-void TileROD_Encoder::setTileHWID(const TileHWID* tileHWID) {
+void TileROD_Encoder::setTileHWID(const TileHWID* tileHWID, int runPeriod) {
    m_tileHWID = tileHWID;
+   m_runPeriod = runPeriod;
 }
 
 void TileROD_Encoder::setTypeAndUnit(TileFragHash::TYPE type, TileRawChannelUnit::UNIT unit) {
@@ -764,23 +766,20 @@ void TileROD_Encoder::fillRODTileMuRcvObj(std::vector<uint32_t>& v) {
 
   // this is the subfragment type 0x42	
 
-  ATH_MSG_DEBUG( "TMDB encoding sub-fragment 0x42: loop over " << m_vTileMuRcvObj.size() << " objects" );
+  ATH_MSG_INFO( "TMDB encoding sub-fragment 0x42: loop over " << m_vTileMuRcvObj.size() << " objects" );
 
   // sub-fragment marker
   //
   v.push_back(0xff1234ff);
 
-  // sub-fragment size
+  // type & version
   //
   v.push_back(5);
   uint savepos = v.size()-1;
-
-  // type & version
-  //
   uint32_t verfrag      = 0x500;
   uint32_t type_version = (0x42 << 16) + verfrag;
   v.push_back(type_version);
-  
+
   // counters and temporary words
   //
   int wc = 0;
@@ -789,71 +788,141 @@ void TileROD_Encoder::fillRODTileMuRcvObj(std::vector<uint32_t>& v) {
   uint32_t result2      = 0x0;
   uint32_t result3      = 0x0;
 
-  for (const TileMuonReceiverObj* tmurcv : m_vTileMuRcvObj) {
-
-    // results are hold in 3 16-bit words.
-    // 
-    //     32nd bit -> |        results2       || results1       | <- 1st bit
-    //                 |          0x0          ||        results3 |
-    // 
-    //     32nd bit -> | m-5 | m-4 | m-3 | m-2 || m-2 | m-1 | m-0 | 0x0 | <- 1st bit
-    //                 |          0x0          || 0x0 | m-7 | m-6 | m-5 |
-    //                 
-    // each 4 bit word is
-    //
-    //                 0      1      2     3    <-- in Obj
-    //              | d56h | d56l | d6h | d6l |
-    //                bit3   bit2  bit1  bit0
-    //   
+  switch (m_runPeriod) {
+
+	  case 2:// RUN2
   
-    int modid = tmurcv->identify() & 0xff;  
-
-    const std::vector<bool> & slin = tmurcv->GetDecision();
-    int imax = std::min((int)slin.size(),4);
-    uint32_t word4b = 0x0;
-    for (int i=0;i<imax;++i){
-      // slin   d56h d56l  d6h  d6l
-      // word4b bit3 bit2 bit1 bit0
-      if (slin[i]) word4b |= 1 << (3-i);
-    }
+	     msg(MSG::INFO) << "Going trough RUN2 encoding procedure for TMDB data" << endmsg;
+
+             for (const TileMuonReceiverObj* tmurcv : m_vTileMuRcvObj) {
+
+                // VERSION RUN2: results are hold in 3 16-bit words. Two 32 bit words.
+                //
+                //     32nd bit -> |        results2       ||       results1        | <- 1st bit
+                //                 |          0x0          ||       results3        |
+                //
+		//     32nd bit -> | m-5 | m-4 | m-3 | m-2 || m-2 | m-1 | m-0 | 0x0 | <- 1st bit
+		//                 |          0x0          || 0x0 | m-7 | m-6 | m-5 |
+		//
+                // each 4 bit word is
+		//
+		//                 0      1      2     3    <-- in Obj
+		//              | d56h | d56l | d6h | d6l |
+		//                bit3   bit2  bit1  bit0
+		//
+
+                int modid = tmurcv->identify() & 0xff;
+
+                const std::vector<bool> & slin = tmurcv->GetDecision();
+                int imax = std::min((int)slin.size(),4);
+                uint32_t word4b = 0x0;
+                for (int i=0;i<imax;++i){
+                   if (slin[i]) word4b |= 1 << (3-i);
+                }
     
-    if (msgLvl(MSG::DEBUG)) {
-      std::stringstream ss;
-      for (const auto & val : slin) {
-          ss<<std::setw(2)<<val;
-      }
-      msg(MSG::DEBUG) << "Result for module: "<<modid<<" in TMDB board "<<modid%8<<MSG::hex<<": 0x"<<word4b<<MSG::dec<<" from "<<ss.str() << endmsg; 
-    }
+                if (msgLvl(MSG::INFO)) {
+                   std::stringstream ss;
+                   for (const auto & val : slin) {
+                      ss<<std::setw(2)<<val;
+                   }
+                   msg(MSG::INFO) << "Result for module: "<<modid<<" in TMDB board "<<modid%8<<MSG::hex<<": 0x"<<word4b<<MSG::dec<<" from "<<ss.str() << endmsg; 
+                }
     
-    switch (modid%8) {
-    case 0: result1 |= word4b << 4  ; break;
-    case 1: result1 |= word4b << 8  ; break;
-    case 2: result1 |= word4b << 12 ; result2 |= word4b; break;
-    case 3: result2 |= word4b << 4  ; break; 
-    case 4: result2 |= word4b << 8  ; break;
-    case 5: result2 |= word4b << 12 ; result3 |= word4b; break;
-    case 6: result3 |= word4b << 4  ; break;
-    case 7: result3 |= word4b << 8  ; break;
-    }
-    ++chc;
-  }
-
-  ATH_MSG_DEBUG( "Summary : "<<MSG::hex<<" Results 1: 0x"<<result1<<" Results 2: 0x"<<result2<<" Results 3: 0x"<<result3<< MSG::dec );
-
-  v.push_back( result1 | (result2 << 16) ); ++wc;// | 5 4 3 2 | 2 1 0 - |
-  v.push_back( result3 ); ++wc;                  // | - - - - | - 7 6 5 | '-' means free/not set/0x0
-  v.at(savepos)=3+wc;
+		switch (modid%8) {
+                    case 0: result1 |= word4b << 4  ; break;
+                    case 1: result1 |= word4b << 8  ; break;
+                    case 2: result1 |= word4b << 12 ; result2 |= word4b; break;
+                    case 3: result2 |= word4b << 4  ; break;
+                    case 4: result2 |= word4b << 8  ; break;
+                    case 5: result2 |= word4b << 12 ; result3 |= word4b; break;
+                    case 6: result3 |= word4b << 4  ; break;
+                    case 7: result3 |= word4b << 8  ; break;
+                }
+                ++chc;
+             }
+
+             ATH_MSG_INFO( "Summary : "<<MSG::hex<<" Results 1: 0x"<<result1<<" Results 2: 0x"<<result2<<" Results 3: 0x"<<result3<< MSG::dec );
+
+             v.push_back( result1 | (result2 << 16) ); ++wc;// | 5 4 3 2 | 2 1 0 - |
+             v.push_back( result3 ); ++wc;                  // | - - - - | - 7 6 5 | '-' means free/not set/0x0
+             v.at(savepos)=3+wc;
+
+	     break;
+
+          case 3:// RUN3
+
+             msg(MSG::INFO) << "Going trough RUN3 encoding procedure for TMDB data" << endmsg;
+
+             for (const TileMuonReceiverObj* tmurcv : m_vTileMuRcvObj) {
+                // VERSION RUN3: results are hold in two 32-bit word to cover a TMDB board holding 8 TileCal modules.
+                //
+		//               32nd bit -> |         results2 [16:31]            ||           results1 [0:15]           | <- 1st bit
+                //               32nd bit -> |            0x0 [16:31]              ||           results3 [0:15]           | <- 1st bit
+                //
+		//               32nd bit -> | 0x0 [12:15] | m-5 | m-4 | m-3 | m-2 || 0x0 [12:15] | m-3 | m-2 | m-1 | m-0 | <- 1st bit
+		//                           |          0x0 [16:31]                || 0x0 [12:15] | m-7 | m-6 | m-5 | m-4 |
+		//
+		//               For each module m-X there is a 3-bit word with the result for a threshold
+		//
+		//                    |  d5+d6  |  d6   |  d5  |
+		//                    |   bit2  |  bit1 | bit0 |
+		//
+
+                // counters and temporary words
+                //
 
-  ATH_MSG_DEBUG( "Check version and counters: "<<MSG::hex<< verfrag <<MSG::dec<<" "<< chc <<" "<< wc <<" save in position: "<< savepos );
-
-  if (msgLvl(MSG::VERBOSE)) {
-    msg(MSG::VERBOSE) << "Check content of ROD fragment after including sub-fragment (0x42)... " << v.size() << endmsg;
-    for (size_t i=0; i<v.size(); ++i) {
-      msg(MSG::VERBOSE) << i << "\t" << v.at(i) << MSG::hex << " 0x" << v.at(i) << MSG::dec << endmsg;
-    }
-  }
-  
-  return;	
+/*
+ *
+ * Comment on implementation...
+ * In Athena the  container size is kept to 4. It is fully used for run2 but for run3 the first position is left empty.
+ * The most significative bit is placed in first position [0] of a container so the position reverse while encoding.
+ *
+ * */
+
+		int modid = tmurcv->identify() & 0xff;
+		const std::vector<bool> & slin = tmurcv->GetDecision();
+		int imax  = std::min((int)slin.size(),4);
+                uint32_t word3b = 0x0;
+                for (int i=1;i<imax;++i) {
+                   // slin    d56  d6   d5
+                   // word3b bit2 bit1 bit0
+                   // bit 4 is always 0 since iteration starts at 1
+                   if (slin[i]) word3b |= 1 << (3-i);
+                }
+
+		switch (modid%8) {
+		    case 0: result1 |= word3b   ; break;
+                    case 1: result1 |= word3b << 3  ; break;
+                    case 2: result1 |= word3b << 6  ; result2 |= word3b      ; break;
+                    case 3: result1 |= word3b << 9  ; result2 |= word3b << 3 ; break;
+                    case 4: result2 |= word3b << 6  ; result3 |= word3b      ; break;
+                    case 5: result2 |= word3b << 9  ; result3 |= word3b << 3 ; break;
+                    case 6: result3 |= word3b << 6  ; break;
+                    case 7: result3 |= word3b << 9  ; break;
+                }
+                ++chc;
+             }
+
+             ATH_MSG_INFO( "Summary : "<<MSG::hex<<" Results 1: 0x"<<result1<<" Results 2: 0x"<<result2<<" Results 3: 0x"<<result3<< MSG::dec );
+
+             v.push_back( result1 | (result2 << 16) ); ++wc;
+             v.push_back( result3 ); ++wc;
+             v.at(savepos) = 3+wc;
+
+	     break;
+
+	  case 0://not defined
+	     ATH_MSG_INFO("Tile Muon Decision Board (TMDB) fragment versions are only available for RUN2 and RUN3");
+	     break;
+          }
+          if (msgLvl(MSG::INFO)){
+             msg(MSG::INFO) << "Check version and counters: "<<MSG::hex<<verfrag<<MSG::dec<<" "<<chc<<" "<<wc<<" save in position: "<<savepos<<endmsg;
+	     msg(MSG::INFO) << "Check content of ROD fragment after including sub-fragment (0x42)... " << v.size() << endmsg;
+	     for (size_t i=0; i<v.size(); ++i) {
+	         msg(MSG::INFO) << i << "\t" << v.at(i) << MSG::hex << " 0x" << v.at(i) << MSG::dec << endmsg;
+	     }
+	  }
+  return;
 }
 
 // == END of TMDB Encoders
diff --git a/Tools/PROCTools/python/comparexAODDigest.py b/Tools/PROCTools/python/comparexAODDigest.py
new file mode 100755
index 0000000000000000000000000000000000000000..30165a8f6830b561189dd2722ff64ad84994ca30
--- /dev/null
+++ b/Tools/PROCTools/python/comparexAODDigest.py
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+import sys
+
+def extractData(filename):
+    
+    result=dict()
+
+    rein=open(filename)
+    for line in rein:
+        l=line.split()
+        if l[0]=='run':
+            header=l
+        else:
+            run=int(l[0])
+            evt=int(l[1])
+            result[(run,evt)]=[int(s) for s in l[2:]]
+    rein.close()
+    return result,header
+
+
+def compare2Files(file1,file2):
+
+    res1,h1=extractData(file1)
+    res2,h2=extractData(file2)
+
+    
+    if (h1 != h2):
+        print("ERROR, headers don't match")
+        print(h1)
+        print(h2)
+        return -1
+
+
+    if len(res1) != len (res2):
+        print("ERROR, not the same number of events")
+        return -1 
+
+    diffCounter=dict()
+    for h in h1[2:]:
+        diffCounter[h]=0
+
+    # Loop over events:
+    for runEvt,values1 in res1.items():
+        values2=res2[runEvt]
+        for i,name in enumerate(h1[2:]):
+            #print (name,i,len(values1),len(values2))
+            if values1[i] != values2[i]:
+                print ("Diff: Run {} Evt {} {} {} -> {}".format(runEvt[0],runEvt[1],name,values1[i],values2[i]))
+                diffCounter[name]+=1
+                pass
+            pass
+        pass
+
+    print("Summary of differences:")
+    noChanges=""
+    nEvt=len(res1)
+    for (name,count) in diffCounter.items():
+        if (count>0):
+            #print (name,":",count,"(of ",nEvt,")")
+            print ("{}: {} events (out of {})".format(name,count,nEvt))
+        else:
+            noChanges+=" "+name
+    print("No changes for:",noChanges)
+
+
+def compareDigest(filelist):
+    if len(filelist)<2:
+        print("Got only %i files. Can't compare")
+        return None
+    
+    runevtset=set()
+    
+    summary=dict() #key is the datestamp
+    
+    for f in filelist:
+        datestamp=f.split('/')[9]
+        print("Fond file for %s" % datestamp)
+        header=None
+        if datestamp in summary: 
+            print("ERROR, duplicate date-stamp %s" % datestamp) 
+            continue
+        
+        res,hdr=extractData(f)
+        if header is None:
+            header=hdr
+        elif (header!=hdr):
+            print("ERROR, headers of file %s doesn't match!" % f)
+            continue
+
+        summary[datestamp]=res
+        runevtset |= set(res.keys())
+        pass
+
+
+    #collected all data, now invert the matrix, sort per run/event
+    nValues=len(header)-2
+
+    perEvt=dict()
+    for runevt in runevtset:
+        perEvt[runevt]=[]
+        for i in range(nValues):
+            perEvt[runevt].append(set())
+
+    for day,data in summary.items():
+        for runevt,v in data.items():
+            for i in range(nValues):
+                perEvt[runevt][i].add(v[i])
+
+                
+    row_format ="{:>12}" * len(header)
+    #row_format+=os.linesep
+    print (row_format.format(*header))
+    for runevt,v in perEvt.items():
+        updates=[runevt[0],runevt[1]]
+        updates+=[len(x)-1 for x in v]
+        print (row_format.format(*updates))
+
+
+if __name__ == "__main__":
+
+    if len(sys.argv)!=3:
+        print("comparexAODDigest.py: A script to compare 2 xAODDigest files")
+        print("Usage:")
+        print("{} <file1> <file2>".format(sys.argv[0].split("/")[-1]))
+    else:
+        compare2Files(sys.argv[1],sys.argv[2])
diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/TrkTrackCollectionMerger/TrackCollectionMerger.h b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/TrkTrackCollectionMerger/TrackCollectionMerger.h
index b4e3b5863c608ced00021e6ec16cf270e658279e..d69e3ad775fbde10ef6abb61f962ac6494eaa546 100644
--- a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/TrkTrackCollectionMerger/TrackCollectionMerger.h
+++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/TrkTrackCollectionMerger/TrackCollectionMerger.h
@@ -27,10 +27,6 @@ namespace Trk {
   /** @brief Class-algorithm for track collection merging and removalof potential duplicate tracks. */
   class TrackCollectionMerger : public AthAlgorithm
     {
-    
-      ///////////////////////////////////////////////////////////////////
-      /** @brief Public methods:                                       */
-      ///////////////////////////////////////////////////////////////////
       
     public:
       
@@ -44,13 +40,6 @@ namespace Trk {
       StatusCode execute();
       StatusCode finalize();
 
-      ///////////////////////////////////////////////////////////////////
-      /** @brief Print internal tool parameters and status.            */
-      ///////////////////////////////////////////////////////////////////
-
-      MsgStream&    dump     (MsgStream&    out) const;
-      std::ostream& dump     (std::ostream& out) const;
-
     protected:
 
       ///////////////////////////////////////////////////////////////////
@@ -75,20 +64,15 @@ namespace Trk {
                                Trk::PRDtoTrackMap *pPrdToTrackMap,
                                TrackCollection* outputCol);
 
-      MsgStream&    dumptools(MsgStream&    out) const;
-      MsgStream&    dumpevent(MsgStream&    out) const;
-
     private:
       bool  m_createViewCollection;     //!< option to create a view collection and not deep-copy tracks
      
-      bool m_updateSharedHitsOnly; //!< do not create the track summary again, but only update shared hits
+      bool m_updateSharedHits; //!< do not create the track summary again, but only update shared hits
 
       bool  m_updateAdditionalInfo;     //!< do not create the track summary again, but only update necessary things
 
 
     };
     
-    MsgStream&    operator << (MsgStream&   ,const TrackCollectionMerger&);
-    std::ostream& operator << (std::ostream&,const TrackCollectionMerger&); 
 }
 #endif // TrackCollectionMerger_H
diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/TrackCollectionMerger.cxx b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/TrackCollectionMerger.cxx
index 9e01f0dba3ad01d603333f235b20f303cf46cecb..f72e148fad2646b8727f28e61f0ecb38a2d97229 100644
--- a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/TrackCollectionMerger.cxx
+++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/TrackCollectionMerger.cxx
@@ -1,12 +1,11 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
 //   Implementation file for class Trk::TrackCollectionMerger
 ///////////////////////////////////////////////////////////////////
-// (c) ATLAS Detector software
-///////////////////////////////////////////////////////////////////
+
 ///////////////////////////////////////////////////////////////////
 // Version 1.0 11/26/2007 Thomas Koffas
 ///////////////////////////////////////////////////////////////////
@@ -23,7 +22,7 @@ Trk::TrackCollectionMerger::TrackCollectionMerger
 (const std::string& name, ISvcLocator* pSvcLocator  ) :
   AthAlgorithm(name, pSvcLocator ),
   m_createViewCollection(true),
-  m_updateSharedHitsOnly(true),
+  m_updateSharedHits(true),
   m_updateAdditionalInfo(false)
 {
   m_outtracklocation         = "CombinedInDetTracks"    ;
@@ -32,7 +31,7 @@ Trk::TrackCollectionMerger::TrackCollectionMerger
   declareProperty("OutputTracksLocation",           m_outtracklocation       ); 
   declareProperty("SummaryTool" ,                   m_trkSummaryTool         );
   declareProperty("CreateViewColllection" ,         m_createViewCollection   );
-  declareProperty("UpdateSharedHitsOnly" ,          m_updateSharedHitsOnly);
+  declareProperty("UpdateSharedHits" ,              m_updateSharedHits);
   declareProperty("UpdateAdditionalInfo" ,          m_updateAdditionalInfo);
 }
 
@@ -44,12 +43,6 @@ StatusCode Trk::TrackCollectionMerger::initialize()
 {
 
   ATH_MSG_DEBUG("Initializing TrackCollectionMerger");
-
-  if( m_updateSharedHitsOnly &&  m_updateAdditionalInfo){
-    msg(MSG::WARNING) << "Both UpdateAdditionalInfo and UpdateSharedHitsOnly set true - UpdateAdditionalInfo includes a shared hits update. " << endmsg;
-    msg(MSG::WARNING) << "If you *only* want to update shared hits, set UpdateAdditionalInfo=False and UpdateSharedHitsOnly=True" << endmsg;
-  }
-
   ATH_CHECK(  m_tracklocation.initialize() );
   ATH_CHECK( m_outtracklocation.initialize() );
   if (not m_trkSummaryTool.name().empty()) ATH_CHECK( m_trkSummaryTool.retrieve() );
@@ -93,11 +86,13 @@ Trk::TrackCollectionMerger::execute(){
     ATH_MSG_DEBUG("Update summaries");  
     // now loop over all tracks and update summaries with new shared hit counts
     // @TODO magic! tracks are now non-const !??
+    const bool createTrackSummary = not (m_updateAdditionalInfo or m_updateSharedHits);
     for (Trk::Track* trk : *outputCol) {
-      if (m_updateAdditionalInfo)  m_trkSummaryTool->updateAdditionalInfo(*trk, pPrdToTrackMap.get());
-      else if (m_updateSharedHitsOnly) m_trkSummaryTool->updateSharedHitCount(*trk, pPrdToTrackMap.get());
-      else  {
+      if (createTrackSummary){
          m_trkSummaryTool->computeAndReplaceTrackSummary(*trk, pPrdToTrackMap.get(), false /* DO NOT suppress hole search*/);
+      } else {
+        if (m_updateAdditionalInfo)  m_trkSummaryTool->updateAdditionalInfo(*trk);
+        if (m_updateSharedHits) m_trkSummaryTool->updateSharedHitCount(*trk, pPrdToTrackMap.get());
       }
     }
   } else {
@@ -113,7 +108,6 @@ Trk::TrackCollectionMerger::execute(){
      }
   }
   //Print common event information
-  ATH_MSG_DEBUG(*this);
   ATH_MSG_DEBUG("Done !");  
   return StatusCode::SUCCESS;
 }
@@ -127,63 +121,6 @@ StatusCode Trk::TrackCollectionMerger::finalize()
    return StatusCode::SUCCESS;
 }
 
-///////////////////////////////////////////////////////////////////
-// Dumps relevant information into the MsgStream
-///////////////////////////////////////////////////////////////////
-
-MsgStream&  Trk::TrackCollectionMerger::dump( MsgStream& out ) const
-{
-  out<<std::endl;
-  if(msgLvl(MSG::DEBUG))  return dumpevent(out);
-  return dumptools(out);
-}
-
-///////////////////////////////////////////////////////////////////
-// Dumps conditions information into the MsgStream
-///////////////////////////////////////////////////////////////////
-
-MsgStream& Trk::TrackCollectionMerger::dumptools( MsgStream& out ) const
-{
-  return out;
-}
-
-///////////////////////////////////////////////////////////////////
-// Dumps event information into the MsgStream
-///////////////////////////////////////////////////////////////////
-
-MsgStream& Trk::TrackCollectionMerger::dumpevent( MsgStream& out ) const
-{
-  return out;
-}
-
-///////////////////////////////////////////////////////////////////
-// Dumps relevant information into the ostream
-///////////////////////////////////////////////////////////////////
-
-std::ostream& Trk::TrackCollectionMerger::dump( std::ostream& out ) const
-{
-  return out;
-}
-
-///////////////////////////////////////////////////////////////////
-// Overload of << operator MsgStream
-///////////////////////////////////////////////////////////////////
-
-MsgStream& Trk::operator    << 
-  (MsgStream& sl,const Trk::TrackCollectionMerger& se)
-{ 
-  return se.dump(sl); 
-}
-
-///////////////////////////////////////////////////////////////////
-// Overload of << operator std::ostream
-///////////////////////////////////////////////////////////////////
-
-std::ostream& Trk::operator << 
-  (std::ostream& sl,const Trk::TrackCollectionMerger& se)
-{
-  return se.dump(sl); 
-}   
 
 
 ///////////////////////////////////////////////////////////////////
diff --git a/Tracking/TrkFitter/TrkDeterministicAnnealingFilter/src/DAF_SimpleWeightCalculator.cxx b/Tracking/TrkFitter/TrkDeterministicAnnealingFilter/src/DAF_SimpleWeightCalculator.cxx
index 99d8efc3d9cf5911555c7f3411a1aec80fafbe77..0e315ec6877d2658eb4f44fd665fa3dbf0f256b6 100755
--- a/Tracking/TrkFitter/TrkDeterministicAnnealingFilter/src/DAF_SimpleWeightCalculator.cxx
+++ b/Tracking/TrkFitter/TrkDeterministicAnnealingFilter/src/DAF_SimpleWeightCalculator.cxx
@@ -141,7 +141,7 @@ Trk::DAF_SimpleWeightCalculator::normalize (
 
     // copy given assgnProbs to new vector
     ATH_MSG_DEBUG("copy vector<AssignmentProb> to a new one");
-    auto newAssgnProbs  = new std::vector< Trk::CompetingRIOsOnTrack::AssignmentProb >(*assgnProbs);
+    auto *newAssgnProbs  = new std::vector< Trk::CompetingRIOsOnTrack::AssignmentProb >(*assgnProbs);
     //*newAssgnProbs = *assgnProbs;
     ATH_MSG_DEBUG("call other normalize()");
     Trk::DAF_SimpleWeightCalculator::normalize( *newAssgnProbs, ROTs, beta, cutValue );
diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMeasurementUpdator.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMeasurementUpdator.cxx
index fac1ac7aa72a8be09458dabe92836ad1d8e870da..b3d2f52d74e0c347066d3d61ca782efe977a2c29 100644
--- a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMeasurementUpdator.cxx
+++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMeasurementUpdator.cxx
@@ -21,7 +21,6 @@ Trk::GsfMeasurementUpdator::update(
   Trk::MultiComponentState&& stateBeforeUpdate,
   const Trk::MeasurementBase& measurement) const
 {
-  MultiComponentState updatedState{};
   // Check all components have associated error matricies
   Trk::MultiComponentState::iterator component = stateBeforeUpdate.begin();
   bool rebuildStateWithErrors = false;
@@ -36,16 +35,12 @@ Trk::GsfMeasurementUpdator::update(
     Trk::MultiComponentState stateWithInsertedErrors =
       rebuildState(std::move(stateBeforeUpdate));
     // Perform the measurement update with the modified state
-    updatedState =
-      calculateFilterStep(std::move(stateWithInsertedErrors), measurement, 1);
-    return updatedState;
+    return calculateFilterStep(std::move(stateWithInsertedErrors), measurement, 1);
   }
 
   // Perform the measurement update
-  updatedState =
-    calculateFilterStep(std::move(stateBeforeUpdate), measurement, 1);
+   return  calculateFilterStep(std::move(stateBeforeUpdate), measurement, 1);
 
-  return updatedState;
 }
 
 Trk::MultiComponentState
@@ -54,8 +49,6 @@ Trk::GsfMeasurementUpdator::update(Trk::MultiComponentState&& stateBeforeUpdate,
                                    FitQualityOnSurface& fitQoS) const
 {
 
-  Trk::MultiComponentState updatedState{};
-
   // Check all components have associated error matricies
   Trk::MultiComponentState::iterator component = stateBeforeUpdate.begin();
 
@@ -72,7 +65,8 @@ Trk::GsfMeasurementUpdator::update(Trk::MultiComponentState&& stateBeforeUpdate,
     Trk::MultiComponentState stateWithInsertedErrors =
       rebuildState(std::move(stateBeforeUpdate));
     // Perform the measurement update with the modified state
-    updatedState = calculateFilterStep(
+
+    Trk::MultiComponentState updatedState = calculateFilterStep(
       std::move(stateWithInsertedErrors), measurement, fitQoS);
     if (updatedState.empty()) {
       return {};
@@ -81,7 +75,7 @@ Trk::GsfMeasurementUpdator::update(Trk::MultiComponentState&& stateBeforeUpdate,
   }
 
   // Perform the measurement update
-  updatedState =
+  Trk::MultiComponentState updatedState=
     calculateFilterStep(std::move(stateBeforeUpdate), measurement, fitQoS);
 
   if (updatedState.empty()) {
@@ -247,7 +241,7 @@ bool
 Trk::GsfMeasurementUpdator::invalidComponent(
   const Trk::TrackParameters* trackParameters) const
 {
-  const auto *measuredCov = trackParameters->covariance();
+  const auto* measuredCov = trackParameters->covariance();
   bool rebuildCov = false;
   if (!measuredCov) {
     rebuildCov = true;
diff --git a/Tracking/TrkFitter/TrkGlobalChi2Fitter/TrkGlobalChi2Fitter/GlobalChi2Fitter.h b/Tracking/TrkFitter/TrkGlobalChi2Fitter/TrkGlobalChi2Fitter/GlobalChi2Fitter.h
index eb0d98f5298dbec23b65b6737f928ff80e99bef4..86c15ba531082ce137e43a41f21bafb96e00c86c 100755
--- a/Tracking/TrkFitter/TrkGlobalChi2Fitter/TrkGlobalChi2Fitter/GlobalChi2Fitter.h
+++ b/Tracking/TrkFitter/TrkGlobalChi2Fitter/TrkGlobalChi2Fitter/GlobalChi2Fitter.h
@@ -675,7 +675,7 @@ namespace Trk {
       const TrackParameters &,
       const GXFTrackState &,
       PropDirection,
-      MagneticFieldProperties,
+      const MagneticFieldProperties&,
       bool,
       bool
     ) const;
@@ -725,7 +725,7 @@ namespace Trk {
       const TrackParameters &,
       const GXFTrackState &,
       PropDirection,
-      MagneticFieldProperties,
+      const MagneticFieldProperties&,
       bool,
       bool
     ) const;
@@ -840,7 +840,7 @@ namespace Trk {
       const TrackParameters *,
       const Surface *,
       PropDirection,
-      const MagneticFieldProperties
+      const MagneticFieldProperties&
     ) const;
 
     virtual int iterationsOfLastFit() const;
diff --git a/Tracking/TrkFitter/TrkGlobalChi2Fitter/src/GlobalChi2Fitter.cxx b/Tracking/TrkFitter/TrkGlobalChi2Fitter/src/GlobalChi2Fitter.cxx
index 14727f1955b4531ed814a595d238d8f063193588..c168976cfe8877b02c387e863eaf94f65417c2a3 100644
--- a/Tracking/TrkFitter/TrkGlobalChi2Fitter/src/GlobalChi2Fitter.cxx
+++ b/Tracking/TrkFitter/TrkGlobalChi2Fitter/src/GlobalChi2Fitter.cxx
@@ -294,7 +294,7 @@ namespace Trk {
     bool muonisstraight = muontrack->info().trackProperties(TrackInfo::StraightTrack);
     bool measphi = false;
 
-    for (auto i : *(muontrack->measurementsOnTrack())) {
+    for (const auto *i : *(muontrack->measurementsOnTrack())) {
       const CompetingRIOsOnTrack *crot = dynamic_cast<const CompetingRIOsOnTrack *>(i);
       const RIO_OnTrack *rot = nullptr;
       
@@ -678,7 +678,7 @@ namespace Trk {
     std::vector<const TrackStateOnSurface *> tmp_matvec;
 
     if ((matvec != nullptr) && !matvec->empty()) {
-      tmp_matvec = std::move(*matvec);
+      tmp_matvec = *matvec;
       delete tmp_matvec.back();
       tmp_matvec.pop_back();
       
@@ -2256,7 +2256,7 @@ namespace Trk {
     ATH_MSG_DEBUG("--> entering GlobalChi2Fitter::fit(PRDS,TP,)");
     MeasurementSet rots;
 
-    for (auto prd : prds) {
+    for (const auto *prd : prds) {
       const Surface & prdsurf = (*prd).detectorElement()->surface((*prd).identify());
       const RIO_OnTrack *rot = nullptr;
       const PlaneSurface *plsurf = nullptr;
@@ -2433,7 +2433,7 @@ namespace Trk {
     MeasurementSet rots;
     const TrackParameters *hitparam = intrk.trackParameters()->back();
 
-    for (auto prd : prds) {
+    for (const auto *prd : prds) {
       const Surface & prdsurf = (*prd).detectorElement()->surface((*prd).identify());
 
       Amg::VectorX parameterVector = hitparam->parameters();
@@ -2494,7 +2494,7 @@ namespace Trk {
 
     bool need_to_correct = false;
 
-    for (auto itSet : rots_in) {
+    for (const auto *itSet : rots_in) {
       if (
         (itSet != nullptr) &&
         itSet->associatedSurface().associatedDetectorElementIdentifier().is_valid() &&
@@ -2508,7 +2508,7 @@ namespace Trk {
     if (need_to_correct) {
       MeasurementSet rots_new;
 
-      for (auto itSet : rots_in) {
+      for (const auto *itSet : rots_in) {
         if (itSet == nullptr) {
           ATH_MSG_WARNING( "There is an empty MeasurementBase object in the track! Skip this object.." );
           continue;
@@ -2544,7 +2544,7 @@ namespace Trk {
       rots = rots_in;
     }
 
-    for (auto itSet : rots) {
+    for (const auto *itSet : rots) {
       if (itSet == nullptr) {
         ATH_MSG_WARNING("There is an empty MeasurementBase object in the track! Skip this object..");
       } else {
@@ -4248,7 +4248,7 @@ namespace Trk {
         matvec_used=false;
 
         if (matvec && !matvec->empty()) {
-          for (auto & i : *matvec) {
+          for (const auto & i : *matvec) {
             const Trk::MaterialEffectsBase * meb = i->materialEffectsOnTrack();
             
             if (meb != nullptr) {
@@ -7625,7 +7625,7 @@ namespace Trk {
      * but this is more performant compared to removing them properly.
      */
     if (
-      rv.size() > 0 && (
+      !rv.empty() && (
         &rv.front()->associatedSurface() == dst.surface() ||
         &rv.front()->associatedSurface() == &src.associatedSurface() ||
         trackParametersClose(*rv.front(), src, 0.001) ||
@@ -7659,7 +7659,7 @@ namespace Trk {
     const TrackParameters & prev,
     const GXFTrackState & ts,
     PropDirection propdir,
-    MagneticFieldProperties bf,
+    const MagneticFieldProperties& bf,
     bool calcderiv,
     bool holesearch
   ) const {
@@ -7702,7 +7702,7 @@ namespace Trk {
     const TrackParameters & prev,
     const GXFTrackState & ts,
     PropDirection propdir,
-    MagneticFieldProperties bf,
+    const MagneticFieldProperties& bf,
     bool calcderiv,
     bool holesearch
   ) const {
@@ -8292,7 +8292,7 @@ namespace Trk {
     const TrackParameters* prevpar,
     const Surface* surf,
     PropDirection propdir,
-    const MagneticFieldProperties fieldprop) const
+    const MagneticFieldProperties& fieldprop) const
   {
     ParamDefsAccessor paraccessor;
     double J[25] = {
diff --git a/Tracking/TrkFitter/TrkKalmanFitter/src/KalmanSmoother.cxx b/Tracking/TrkFitter/TrkKalmanFitter/src/KalmanSmoother.cxx
index 8f673684ca0bfed386950fe44fc57c1290f5ac9b..5dda04214df033816f858db57cbb777818f6c98a 100755
--- a/Tracking/TrkFitter/TrkKalmanFitter/src/KalmanSmoother.cxx
+++ b/Tracking/TrkFitter/TrkKalmanFitter/src/KalmanSmoother.cxx
@@ -35,8 +35,8 @@
 #include <iomanip>
 
 // InterfaceID
-// const InterfaceID& Trk::KalmanSmoother::interfaceID() { 
-//	return InterfaceID_KalmanSmoother; 
+// const InterfaceID& Trk::KalmanSmoother::interfaceID() {
+//	return InterfaceID_KalmanSmoother;
 //}
 
 // constructor
@@ -64,7 +64,7 @@ Trk::KalmanSmoother::KalmanSmoother(const std::string& t,const std::string& n,co
   // the extrapolation engine
   declareProperty("ExtrapolationEngine",      m_extrapolationEngine);
   declareProperty("UseExtrapolationEngine",   m_useExEngine);
-  
+
   declareInterface<IKalmanSmoother>( this );
 }
 
@@ -96,7 +96,7 @@ StatusCode Trk::KalmanSmoother::finalize()
 {
     delete m_utility;
     if (msgLvl(MSG::INFO)) {
-        
+
         int iw=9;
         std::stringstream ss;
         ss << "-------------------------------------------------------------------------------" << std::endl;
@@ -130,7 +130,7 @@ StatusCode Trk::KalmanSmoother::finalize()
     ATH_MSG_INFO ("finalize() successful in " << name());
     return StatusCode::SUCCESS;
 }
-		
+
 // configure the Kalman Smoother
 // needs:   Propagator				- define which track model to be used for extrapolating tracks
 //			Updator				    - defines the statistics for updating the estimator
@@ -158,8 +158,8 @@ StatusCode Trk::KalmanSmoother::configureWithTools(IExtrapolator* extrap,
 
   if (m_dynamicNoiseAdjustor) {
     ATH_MSG_INFO ("tool for DNA present, so dyn. noise adjustment inside Si detectors will be active!");
-  }  
-  
+  }
+
   m_initialErrors = m_updator->initialErrors();
   ATH_MSG_DEBUG ("queried current Updator for fitter initialisation. Result:");
   ATH_MSG_DEBUG ( m_initialErrors[0] << ", " << m_initialErrors[1]
@@ -179,7 +179,7 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fit(Trk::Trajectory&              tra
                                           const Trk::KalmanMatEffectsController& kalMec) const
 {
   ATH_MSG_VERBOSE ("--> enter KalmanSmoother::fit");
-  
+
   // protection against being unconfigured
   if (!m_updator) {
     ATH_MSG_ERROR ("need to first configure with updator");
@@ -205,10 +205,10 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fit(Trk::Trajectory&              tra
   }
   double chi2Increment = 0.f;
   int    ndofIncrement = -5;  // five free parameters
- 
+
   ////////////////////////////////////////////////////////////////////////////////////
-  // get last MeasurementBase and perform the missing update 
-  
+  // get last MeasurementBase and perform the missing update
+
   /*-- careful with STL reverse iterator: the underlying normal iterator points to
     a different element which is off by one, otherwise couldn't access rbegin() etc.
     Transformation (rit constructor or rit's base() method) needs offset by +/- 1.
@@ -221,7 +221,7 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fit(Trk::Trajectory&              tra
   ATH_MSG_VERBOSE ("create smoothed state at end of track by adding the last meas't");
   std::unique_ptr<const TrackParameters> smooPar;
   double smooPar_eta_for_monitoring=1000.;
-  if (!fittableMeasurement || !forwardTPar) 
+  if (!fittableMeasurement || !forwardTPar)
     m_utility->dumpTrajectory(trajectory, "DAF-inconsistency");
   // first smoothed TrkParameter is last forward prediction updated with last MBase
   else smooPar.reset(  m_updator->addToState(*forwardTPar,
@@ -253,12 +253,12 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fit(Trk::Trajectory&              tra
 
   ////////////////////////////////////////////////////////////////////////////////////
   // start backward filtering
-  
+
   // use result of forward kalman filter as initial prediction, but scale error matrix.
 
   AmgSymMatrix(5)* firstErrMtx = initialiseSmoother(*(lastPredictedState->smoothedTrackParameters())->covariance());
   const AmgVector(5)& par = lastPredictedState->smoothedTrackParameters()->parameters();
-  std::unique_ptr<const TrackParameters> predPar( CREATE_PARAMETERS(*(lastPredictedState->smoothedTrackParameters()),par,firstErrMtx) ); 
+  std::unique_ptr<const TrackParameters> predPar( CREATE_PARAMETERS(*(lastPredictedState->smoothedTrackParameters()),par,firstErrMtx) );
   // The first step of backward-filtering is done before any loop because of the
   // specially formed prediction (from the last forward parameters).
   std::unique_ptr<const TrackParameters> updatedPar( m_updator->addToState(*predPar,
@@ -273,31 +273,29 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fit(Trk::Trajectory&              tra
   lastPredictedState->backwardStateChiSquared(trackQualityIncrement->chiSquared());
   addChi2IncrementAndDelete(trackQualityIncrement,chi2Increment,ndofIncrement);
   //    Trk::Surface& testSf = fittableMeasurement->associatedSurface();
-  
-  
+
+
   ////////////////////////////////////////////////////////////////////////////////////
   // now do the rest of the forward trajectory by means of a reverse iterated loop
-  
+
   Trk::Trajectory::reverse_iterator rit = lastPredictedState + 1;
   Trk::Trajectory::reverse_iterator lastSmoothableState
-    = Trk::Trajectory::reverse_iterator(m_utility->firstFittableState(trajectory)) - 1; // this takes outliers into account  
+    = Trk::Trajectory::reverse_iterator(m_utility->firstFittableState(trajectory)) - 1; // this takes outliers into account
   for( ; rit!=trajectory.rend(); rit++) {
     if (!rit->isOutlier()) {
       smooPar_eta_for_monitoring = 1000.;
 
       fittableMeasurement = rit->measurement();
-      
+
       if (msgLvl(MSG::DEBUG)) {
         printGlobalParams(previousStatePosOnTraj, " start", updatedPar.get() );
         // ATH_MSG_VERBOSE << "    Now trying to hit surface " << fittableMeasurement->associatedSurface() << endmsg;
         BoundaryCheck trackWithinSurface = true;
-        //        if ( ! testSf.isOnSurface( updatedPar->position(), trackWithinSurface) ) 
+        //        if ( ! testSf.isOnSurface( updatedPar->position(), trackWithinSurface) )
         //  ATH_MSG_VERBOSE << "    previous updated parameters are outside surface bounds!" << endmsg;
         if ( ! fittableMeasurement->associatedSurface().isOnSurface( rit->forwardTrackParameters()->position(),
                                                                      trackWithinSurface) ) {
           ATH_MSG_VERBOSE ("    for information: forward-filtered pars are outside surface bounds!");
-          if (msgLvl(MSG::INFO)) monitorTrackFits( ForwParOutsideSurfaceBounds, ( updatedPar ? updatedPar->eta() : 1000. ) );
-          // ATH_MSG_VERBOSE (fittableMeasurement->associatedSurface());
         }
     }
     previousStatePosOnTraj = rit->positionOnTrajectory();
@@ -308,7 +306,7 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fit(Trk::Trajectory&              tra
 
       // now propagate updated TrkParameters to surface of ROT
       if (!m_useExEngine)
-	predPar.reset(  m_extrapolator->extrapolate(*updatedPar, sf,
+        predPar.reset(  m_extrapolator->extrapolate(*updatedPar, sf,
                                                     Trk::oppositeMomentum, // reverse filtering
                                                     false,                 // no boundary check
                                                     kalMec.particleType()) );
@@ -317,13 +315,13 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fit(Trk::Trajectory&              tra
 	Trk::ExtrapolationCell <Trk::TrackParameters> ecc(*updatedPar, Trk::oppositeMomentum);
 	ecc.setParticleHypothesis(kalMec.particleType());
 	Trk::ExtrapolationCode eCode =  m_extrapolationEngine->extrapolate(ecc, &sf, false);
-        
+
 	if (eCode.isSuccess() && ecc.endParameters) {
 	  ATH_MSG_DEBUG ("Smoother Kalman Fitter --> extrapolation engine success");
 	  predPar.reset(ecc.endParameters);
 	} else {
 	  ATH_MSG_WARNING ("Smoother Kalman Fitter --> extrapolation engine did not succeed");
-	}    
+	}
       }
 
       if(!predPar) {
@@ -349,14 +347,14 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fit(Trk::Trajectory&              tra
       ////////////////////////////////////////////////////////////////////
       // adjust the momentum + error according to target measurement (brem fit)
       const Trk::DNA_MaterialEffects* detectedMomentumNoise = nullptr;
-      Trk::Trajectory::reverse_iterator stateWithNoise 
+      Trk::Trajectory::reverse_iterator stateWithNoise
         = m_utility->previousFittableState(trajectory, rit);
       if (kalMec.doDNA() && stateWithNoise!=trajectory.rend()) {
 
         const TrackParameters *predPar_temp=predPar.release();
         const TrackParameters *updatedPar_temp=updatedPar.release();
 
-        detectedMomentumNoise = 
+        detectedMomentumNoise =
           m_dynamicNoiseAdjustor->DNA_Adjust(predPar_temp, // change according to where meas is
                                              updatedPar_temp, // previous state's pars (start)
                                              fittableMeasurement, // the meas't
@@ -373,7 +371,7 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fit(Trk::Trajectory&              tra
       updatedPar.reset(  m_updator->addToState(*predPar, fittableMeasurement->localParameters(),
                                                fittableMeasurement->localCovariance(),
                                                trackQualityIncrement) );
-      
+
       if (!updatedPar || !trackQualityIncrement) {
         if (msgLvl(MSG::INFO)) monitorTrackFits( UpdateFailure, predPar->eta() );
         ATH_MSG_INFO ("could not update Track Parameters, reject track");
@@ -390,7 +388,7 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fit(Trk::Trajectory&              tra
 
       // smoothed parameters = combination of predicted (!) forward and updated (!) backward state
       // remember: first TrkParameter on ForwardTrajectory has no error matrix !!!
-      
+
       if (rit == lastSmoothableState) { // at the last don't do state combination.
         ATH_MSG_VERBOSE ("Identified state" << (rit->positionOnTrajectory()>9? " " : " 0")<<
                          rit->positionOnTrajectory() << " as last fittable state.");
@@ -405,7 +403,6 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fit(Trk::Trajectory&              tra
       }
       if (!smooPar) {
         ATH_MSG_INFO ("could not combine Track Parameters, reject track");
-        if (msgLvl(MSG::INFO)) monitorTrackFits( CombineStatesFailure, ( updatedPar ? updatedPar->eta() : 1000. ) );
         return FitterStatusCode::CombineStatesFailure;
       }
       // get FitQualityOnSurface
@@ -432,12 +429,12 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fit(Trk::Trajectory&              tra
         stateWithNoise->checkinDNA_MaterialEffects(detectedMomentumNoise);
       }
     } // end if not an outlier
-    
+
   } // end loop over trajectory states
-  
+
   ATH_MSG_VERBOSE ("-S- smoothed trajectory created ");
-  
-  
+
+
   // we made it
   trackFitQuality = new Trk::FitQuality(chi2Increment,ndofIncrement);
   if (msgLvl(MSG::INFO)) monitorTrackFits( Success, smooPar_eta_for_monitoring) ;
@@ -468,10 +465,10 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fitWithReference(Trk::Trajectory&
   }
   double chi2Increment = 0.0;
   int    ndofIncrement = -5;  // five free parameters
- 
+
   ////////////////////////////////////////////////////////////////////////////////////
-  // get last MeasurementBase and perform the missing update 
-  
+  // get last MeasurementBase and perform the missing update
+
   /*-- careful with STL reverse iterator: the underlying normal iterator points to
     a different element which is off by one, otherwise couldn't access rbegin() etc.
     Transformation (rit constructor or rit's base() method) needs offset by +/- 1.
@@ -504,7 +501,7 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fitWithReference(Trk::Trajectory&
   if (msgLvl(MSG::INFO)) monitorTrackFits( Call, ( smooPar ? smooPar->eta() : 1000. ) );
   if (!smooPar || !fitQual) {
     ATH_MSG_WARNING ("first smoother update failed, reject track");
-    if (msgLvl(MSG::INFO)) monitorTrackFits( UpdateFailure, 
+    if (msgLvl(MSG::INFO)) monitorTrackFits( UpdateFailure,
                                              lastPredictedState->referenceParameters()->eta() );
     delete fitQual;
     return FitterStatusCode::UpdateFailure;
@@ -522,7 +519,7 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fitWithReference(Trk::Trajectory&
   // specially formed prediction: result of FKF with scaled error matrix
   AmgSymMatrix(5)* firstErrMtx = initialiseSmoother(*(lastPredictedState->smoothedTrackParameters()->covariance()));
   AmgVector(5)     firstDiff   = updatedDifference->first; // make copy and delete
-  updatedDifference.reset( 
+  updatedDifference.reset(
     m_updator->updateParameterDifference(firstDiff, *firstErrMtx,
 					 *(lastPredictedState->measurementDifference()),
 					 lastMeasurement->localCovariance(),
@@ -536,7 +533,7 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fitWithReference(Trk::Trajectory&
   }
   lastPredictedState->backwardStateChiSquared(trackQualityIncrement->chiSquared());
   addChi2IncrementAndDelete(trackQualityIncrement,chi2Increment,ndofIncrement);
-  
+
   double smooPar_eta_for_monitoring=1000.;
   ////////////////////////////////////////////////////////////////////////////////////
   // now do the rest of the forward trajectory by means of a reverse iterated loop
@@ -544,7 +541,7 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fitWithReference(Trk::Trajectory&
   Trk::Trajectory::reverse_iterator lastSmoothableState
     = Trk::Trajectory::reverse_iterator(m_utility->firstFittableState(trajectory)) - 1; // this takes outliers into account
   for( ; rit!=trajectory.rend(); rit++) {
-      
+
     smooPar_eta_for_monitoring=1000.;
 
     ATH_MSG_VERBOSE ("Now inverting Jacobian... (pointer is "<<(rit->jacobian()?"OK":"NULL")<<")");
@@ -568,10 +565,10 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fitWithReference(Trk::Trajectory&
                 << ", qOverP_diff=" << (predDiffPar)(Trk::qOverP)
                 << ", sigmaDeltaE=" << rit->materialEffects()->sigmaDeltaE()
                 << ", sigmaDeltaQoverP=" << sqrt(sigmaDeltaQoverPsquared) << std::fixed);//std::defaultfloat);
-      ATH_MSG_VERBOSE ("Added material effects.");      
+      ATH_MSG_VERBOSE ("Added material effects.");
     }
     /* possibly check quality of backward "extrapolation", if not good return a
-       monitorTrackFits( FitterStatusCode::ExtrapolationFailure, eta) or 
+       monitorTrackFits( FitterStatusCode::ExtrapolationFailure, eta) or
        monitorTrackFits( ExtrapolationFailureDueToSmallMomentum, TP->eta())
      */
     updatedDifference.reset();
@@ -586,7 +583,7 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fitWithReference(Trk::Trajectory&
     if (!fittableMeasurement || rit->isOutlier() ) { // pure material state or outlier
       updatedDifference = std::make_unique<std::pair<AmgVector(5),AmgSymMatrix(5)>>(  std::make_pair(predDiffPar,predCov) );
     } else {
-      updatedDifference.reset( 
+      updatedDifference.reset(
         m_updator->updateParameterDifference(predDiffPar, predCov,
                                                *(rit->measurementDifference()),
                                                fittableMeasurement->localCovariance(),
@@ -626,7 +623,7 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fitWithReference(Trk::Trajectory&
 
     // smoothed parameters = combination of predicted (!) forward and updated (!) backward state
     // remember: first TrkParameter on ForwardTrajectory has no error matrix !!!
-      
+
     if (rit == lastSmoothableState) { // at the last don't do state combination.
       ATH_MSG_VERBOSE ("Identified state" << (rit->positionOnTrajectory()>9? " " : " 0")<<
                        rit->positionOnTrajectory() << " as last fittable state.");
@@ -676,11 +673,11 @@ Trk::FitterStatusCode Trk::KalmanSmoother::fitWithReference(Trk::Trajectory&
     if (rit== lastSmoothableState) break; // if first state is outlier, loop will malfunction
 
   } // end loop over trajectory states
-  
+
   ATH_MSG_VERBOSE ("-S- smoothed trajectory created ");
-  
+
   // cleanup
-  
+
   // we made it
   trackFitQuality = new Trk::FitQuality(chi2Increment,ndofIncrement);
   if (msgLvl(MSG::INFO)) monitorTrackFits( Success, smooPar_eta_for_monitoring );
@@ -759,7 +756,7 @@ void Trk::KalmanSmoother::printGlobalParams(int istate, const std::string& ptype
 {
   char tt[80]; sprintf(tt,"T%.2u",istate);
   if (not (msgLvl(MSG::VERBOSE))) return;
-  msg(MSG::VERBOSE) << tt << ptype << " GP:" 
+  msg(MSG::VERBOSE) << tt << ptype << " GP:"
         << std::setiosflags(std::ios::fixed | std::ios::showpoint | std::ios::right )
         << std::setw(9) << std::setprecision(2) << param->position()[0]
         << std::setw(9) << std::setprecision(2) << param->position()[1]
diff --git a/Tracking/TrkFitter/TrkiPatFitterUtils/src/FitProcedure.cxx b/Tracking/TrkFitter/TrkiPatFitterUtils/src/FitProcedure.cxx
index 917a8a8f4eaa944824b3cd0f2bff53c5b8a8c2c7..2deacb83a8783a2a02f23fdba169b061338d6975 100755
--- a/Tracking/TrkFitter/TrkiPatFitterUtils/src/FitProcedure.cxx
+++ b/Tracking/TrkFitter/TrkiPatFitterUtils/src/FitProcedure.cxx
@@ -165,7 +165,7 @@ FitProcedure::constructTrack (const std::vector<FitMeasurement*>&		measurements,
     }
     
     // then append the fitted TSOS
-    for (auto m : measurements)
+    for (auto *m : measurements)
     {
 	if (m->isMaterialDelimiter()) continue;
 	
@@ -796,7 +796,7 @@ FitProcedure::calculateChiSq(std::vector<FitMeasurement*>& measurements)
     m_chiSq		= 0.;
     double driftResidual= 0.;
     double DSqMax	= 0.;
-    for (auto m : measurements)
+    for (auto *m : measurements)
     {
 	if (! m->numberDoF()) continue;
 	// if (m->isPerigee())
@@ -922,7 +922,7 @@ FitProcedure::calculateChiSq(std::vector<FitMeasurement*>& measurements)
 
 	(**measurements.begin()).printHeading(*m_log);
 	int n = 0;
-	for (auto m : measurements)
+	for (auto *m : measurements)
 	{
 	    *m_log << std::setiosflags(std::ios::fixed)
 		   << std::setw(3) << ++n;
diff --git a/Tracking/TrkFitter/TrkiPatFitterUtils/src/MeasurementProcessor.cxx b/Tracking/TrkFitter/TrkiPatFitterUtils/src/MeasurementProcessor.cxx
index b8ab5df68803ea7eae6bd33eb1498152e6ce6068..659c4b7b2eaf0426c624a604facb5882e08e1ccd 100755
--- a/Tracking/TrkFitter/TrkiPatFitterUtils/src/MeasurementProcessor.cxx
+++ b/Tracking/TrkFitter/TrkiPatFitterUtils/src/MeasurementProcessor.cxx
@@ -75,7 +75,7 @@ MeasurementProcessor::MeasurementProcessor (bool				asymmetricCaloEnergy,
     if(m_useStepPropagator==2)  m_stepField = Trk::MagneticFieldProperties(Trk::FastField);
 
     
-    for (auto m : m_measurements)
+    for (auto *m : m_measurements)
     {
 	if (! m->numberDoF())		continue;
 	if (m->isAlignment()) m_alignments.push_back(m);
@@ -178,7 +178,7 @@ MeasurementProcessor::calculateDerivatives(void)
     }
 
     // loop over measurements to compute derivatives:
-    for (auto m : m_measurements)
+    for (auto *m : m_measurements)
     {
 	// strip detector types
 	if (m->isCluster())
@@ -339,7 +339,7 @@ MeasurementProcessor::calculateResiduals(void)
 {
     int nAlign		= 0;
     int nScat		= 0;
-    for (auto m : m_measurements)
+    for (auto *m : m_measurements)
     {
 	if (! (*m).numberDoF())	continue;
 
@@ -638,7 +638,7 @@ MeasurementProcessor::propagationDerivatives(void)
 {
     // compute additional derivatives when needed for covariance propagation.
     //   loop over measurements:
-  for (auto m : m_measurements)
+  for (auto *m : m_measurements)
     {
 	// compute the D0 and Z0 derivs that don't already exist
 	if (! m->isPositionMeasurement() || m->numberDoF() > 1) continue;
diff --git a/Tracking/TrkTools/TrkMaterialProvider/src/TrkMaterialProviderTool.cxx b/Tracking/TrkTools/TrkMaterialProvider/src/TrkMaterialProviderTool.cxx
index 87ac7c1ed8331b205d73ab0bb0011dc5dfbd3beb..3607f5e1b0c5ff11f74435934e689865e7f7321b 100644
--- a/Tracking/TrkTools/TrkMaterialProvider/src/TrkMaterialProviderTool.cxx
+++ b/Tracking/TrkTools/TrkMaterialProvider/src/TrkMaterialProviderTool.cxx
@@ -744,7 +744,7 @@ Trk::TrkMaterialProviderTool::getCaloTSOS (const Trk::TrackParameters&	parm,
   double ElossID = 0.; 
   double ElossCalo = 0.; 
   double ElossMS = 0.; 
-  for(auto m : *caloTSOS) {
+  for(const auto *m : *caloTSOS) {
     if(m->materialEffectsOnTrack()) {
       const Trk::MaterialEffectsOnTrack* meot = dynamic_cast<const Trk::MaterialEffectsOnTrack*>(m->materialEffectsOnTrack());
       if(meot) {
@@ -1434,7 +1434,7 @@ Trk::TrkMaterialProviderTool::modifyTSOSvector(const std::vector<const Trk::Trac
   typePatternDeposit.set(Trk::TrackStateOnSurface::CaloDeposit);
   //typePatternDeposit.set(Trk::TrackStateOnSurface::Scatterer);
 
-  for(auto m : *matvec) {
+  for(const auto *m : *matvec) {
 
     if(!m->trackParameters()) {
       ATH_MSG_WARNING("No trackparameters on TrackStateOnSurface ");
@@ -1839,7 +1839,7 @@ void Trk::TrkMaterialProviderTool::getMopAndIoniEnergyLoss(const std::vector<con
   double deltaE_rad_tot = 0.; 
   double sigmaDeltaE_rad_tot =0.;
 
-  for(auto m : *matvec) {    
+  for(const auto *m : *matvec) {    
     if(!m->trackParameters()) {
       ATH_MSG_WARNING("No trackparameters on TrackStateOnSurface ");
       continue;
diff --git a/Tracking/TrkTools/TrkParticleCreator/src/TrackParticleCreatorTool.cxx b/Tracking/TrkTools/TrkParticleCreator/src/TrackParticleCreatorTool.cxx
index 3cfad1df30fe154ad8daf28751266315cd1b1b68..c46db14d84887bf1c2f68aeb8b7d367667a3a8ee 100644
--- a/Tracking/TrkTools/TrkParticleCreator/src/TrackParticleCreatorTool.cxx
+++ b/Tracking/TrkTools/TrkParticleCreator/src/TrackParticleCreatorTool.cxx
@@ -549,7 +549,7 @@ TrackParticleCreatorTool::TrackParticleCreatorTool(const std::string& t, const s
         summary = updated_summary.get();
       } else if (m_computeAdditionalInfo) {
         updated_summary = std::make_unique<Trk::TrackSummary>(*track.trackSummary());
-        m_trackSummaryTool->updateAdditionalInfo(track, prd_to_track_map, *updated_summary);
+        m_trackSummaryTool->updateAdditionalInfo(track, *updated_summary);
         summary = updated_summary.get();
       }
     } else {
@@ -824,7 +824,7 @@ TrackParticleCreatorTool::TrackParticleCreatorTool(const std::string& t, const s
     // Attempt to fill the position enums - will necessarily be a bit of a hack, since we don't have all the information.
     std::vector< xAOD::ParameterPosition> positions;
     bool firstMeasurement = false;
-    for (auto parameter : trackParticle.trackParameters()){
+    for (const auto *parameter : trackParticle.trackParameters()){
       if (!firstMeasurement && parameter && !parameter->associatedSurface().isFree()){
         // if the surface isn't free, it must belong to a detector element => measurement
         firstMeasurement=true;
@@ -926,7 +926,7 @@ TrackParticleCreatorTool::TrackParticleCreatorTool(const std::string& t, const s
       setNumberOfUsedHits(*trackparticle,summary->numberOfUsedHitsdEdx());
       setNumberOfOverflowHits(*trackparticle,summary->numberOfOverflowHitsdEdx());
     }
-    auto beamspot = CacheBeamSpotData(Gaudi::Hive::currentContext());
+    const auto *beamspot = CacheBeamSpotData(Gaudi::Hive::currentContext());
     if (beamspot) {
       setTilt(*trackparticle,beamspot->beamTilt(0),beamspot->beamTilt(1));
     }
@@ -987,7 +987,7 @@ TrackParticleCreatorTool::TrackParticleCreatorTool(const std::string& t, const s
     MagField::AtlasFieldCache fieldCache;
     fieldCondObj->getInitializedCache (fieldCache);
 
-    for ( auto param : parameters ){
+    for ( const auto *param : parameters ){
       std::vector<float>& values = parametersVec[numParam];
       values.resize(6);
       const Amg::Vector3D & pos = param->position();
diff --git a/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/IExtendedTrackSummaryTool.h b/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/IExtendedTrackSummaryTool.h
index 8837a91c0bf9404d094bb18ba1be45a95669fc87..7e2510cc2dfb1019e59a8a9de0d2cb979ccf09ef 100644
--- a/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/IExtendedTrackSummaryTool.h
+++ b/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/IExtendedTrackSummaryTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRKIEXTENDEDTRACKSUMMARYTOOL_H
@@ -108,12 +108,9 @@ public:
    * summary is owned by the track.
    */
   virtual void updateAdditionalInfo(const Track& track,
-                                    const Trk::PRDtoTrackMap* prd_to_track_map,
                                     TrackSummary& summary) const = 0;
 
-  virtual void updateAdditionalInfo(
-    Track& track,
-    const Trk::PRDtoTrackMap* prd_to_track_map) const = 0;
+  virtual void updateAdditionalInfo(Track& track) const = 0;
 };
 
 inline const InterfaceID&
diff --git a/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackSummaryTool.h b/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackSummaryTool.h
index 7417ae0e0a3e0323a1c837533edba1ec437ca219..102a1f8b1cd7e178a9bc7c392eacfe65443c6345 100755
--- a/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackSummaryTool.h
+++ b/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackSummaryTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRKITRACKSUMMARYTOOL_H
diff --git a/Tracking/TrkTools/TrkTrackSummaryTool/TrkTrackSummaryTool/TrackSummaryTool.h b/Tracking/TrkTools/TrkTrackSummaryTool/TrkTrackSummaryTool/TrackSummaryTool.h
index 405062de0b3912b34cd1b4476ddf14d710fe2c5a..2c3ca7d0363977c10f1490071dfd1b19456a9c89 100755
--- a/Tracking/TrkTools/TrkTrackSummaryTool/TrkTrackSummaryTool/TrackSummaryTool.h
+++ b/Tracking/TrkTools/TrkTrackSummaryTool/TrkTrackSummaryTool/TrackSummaryTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRKTRACKSUMMARYTOOL_H
@@ -133,12 +133,6 @@ public:
     Track& track,
     const Trk::PRDtoTrackMap* prd_to_track_map) const override;
 
-  /** method to update additional information (PID,shared hits, dEdX), this is
-   * optimised for track collection merging.
-   */
-  virtual void updateAdditionalInfo(
-    Track& track,
-    const Trk::PRDtoTrackMap* prd_to_track_map) const override;
 
   /** Update the shared hit count of the given track summary.
    * @param summary the summary to be updated i.e. a copy of the track summary
@@ -173,7 +167,6 @@ public:
    * summary is owned by the track.
    */
   virtual void updateAdditionalInfo(const Track& track,
-                                    const Trk::PRDtoTrackMap* prd_to_track_map,
                                     TrackSummary& summary) const override;
 
   /** method to update additional information (PID,shared hits, dEdX), this is
@@ -200,7 +193,6 @@ private:
                      bool suppress_hole_search) const;
   
   void updateAdditionalInfo(const Track& track,
-                            const Trk::PRDtoTrackMap* prd_to_track_map,
                             TrackSummary& summary,
                             bool initialise_to_zero) const;
 
diff --git a/Tracking/TrkTools/TrkTrackSummaryTool/TrkTrackSummaryTool/TrackSummaryTool.icc b/Tracking/TrkTools/TrkTrackSummaryTool/TrkTrackSummaryTool/TrackSummaryTool.icc
index 2323c82101e68cf6fa0e3a8b3c8f90fbe305e6cb..7b9924eba8867edb1423dea5158f6381768b636e 100644
--- a/Tracking/TrkTools/TrkTrackSummaryTool/TrkTrackSummaryTool/TrackSummaryTool.icc
+++ b/Tracking/TrkTools/TrkTrackSummaryTool/TrkTrackSummaryTool/TrackSummaryTool.icc
@@ -40,22 +40,6 @@ TrackSummaryTool::updateSharedHitCount(
   }
 }
 
-inline void
-TrackSummaryTool::updateAdditionalInfo(
-  Track& track,
-  const Trk::PRDtoTrackMap* prd_to_track_map) const
-{
-  if (!track.trackSummary()) {
-    computeAndReplaceTrackSummary(
-      track, prd_to_track_map, false /*DO NOT suppress hole search*/);
-  } else {
-    updateAdditionalInfo(
-      track,
-      prd_to_track_map,
-      *track.trackSummary(),
-      true); // @TODO set to false; true for backward compatibility
-  }
-}
 
 inline void
 TrackSummaryTool::updateSharedHitCount(Track& track) const
@@ -71,10 +55,9 @@ TrackSummaryTool::updateSharedHitCount(Track& track) const
 inline void
 TrackSummaryTool::updateAdditionalInfo(
   const Track& track,
-  const Trk::PRDtoTrackMap* prd_to_track_map,
   TrackSummary& summary) const
 {
-  updateAdditionalInfo(track, prd_to_track_map, summary, false);
+  updateAdditionalInfo(track, summary, false);
 }
 
 inline void
@@ -86,7 +69,6 @@ TrackSummaryTool::updateAdditionalInfo(Track& track) const
   } else {
     updateAdditionalInfo(
       track,
-      nullptr,
       *track.trackSummary(),
       true); // @TODO set to false; true for backward compatibility
   }
diff --git a/Tracking/TrkTools/TrkTrackSummaryTool/src/TrackSummaryTool.cxx b/Tracking/TrkTools/TrkTrackSummaryTool/src/TrackSummaryTool.cxx
index 7b4ae59a39dd9ff7245b252ca1cb3c58f3f6182f..52ccbbc735384acada6d42944c93166f8a4c6a8d 100755
--- a/Tracking/TrkTools/TrkTrackSummaryTool/src/TrackSummaryTool.cxx
+++ b/Tracking/TrkTools/TrkTrackSummaryTool/src/TrackSummaryTool.cxx
@@ -44,9 +44,7 @@ Trk::TrackSummaryTool::~TrackSummaryTool()
 StatusCode
   Trk::TrackSummaryTool::initialize()
 {
-    // StatusCode sc=StatusCode::SUCCESS;
-    //StatusCode sc = AlgTool::initialize();
-    //if (sc.isFailure()) return sc;
+
 
     ATH_CHECK( detStore()->retrieve(m_detID, "AtlasID" ));
 
@@ -360,7 +358,7 @@ void Trk::TrackSummaryTool::updateSharedHitCount(const Track& track, const Trk::
   m_idTool->updateSharedHitCount(track, prd_to_track_map, summary);
 }
 
-void Trk::TrackSummaryTool::updateAdditionalInfo(const Track& track, const Trk::PRDtoTrackMap *prd_to_track_map, TrackSummary &summary, bool initialise_to_zero) const
+void Trk::TrackSummaryTool::updateAdditionalInfo(const Track& track, TrackSummary &summary, bool initialise_to_zero) const
 {
   unsigned int numberOfeProbabilityTypes = Trk::numberOfeProbabilityTypes+1;
   std::vector<float> eProbability(numberOfeProbabilityTypes,0.5);
@@ -397,8 +395,6 @@ void Trk::TrackSummaryTool::updateAdditionalInfo(const Track& track, const Trk::
 
   m_idTool->updateAdditionalInfo(summary, eProbability,dedx, nhitsuseddedx,noverflowhitsdedx);
 
-  m_idTool->updateSharedHitCount(track, prd_to_track_map, summary);
-
   m_idTool->updateExpectedHitInfo(track, summary);
 
   if (m_addInDetDetailedSummary) m_idTool->addDetailedTrackSummary(track,summary);
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastSteering.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastSteering.cxx
index 3169847a8bc76a9c45e85aaca886c9806e76ba8c..93af085417960d865919c1441657785eca2b1d90 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastSteering.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastSteering.cxx
@@ -321,7 +321,7 @@ StatusCode MuFastSteering::execute()
 
   for (size_t size=0; size<roiCollection->size(); size++){
     const LVL1::RecMuonRoI* recRoI = matchingRecRoI( roiCollection->at(size)->roiWord(),  *recRoiCollection );
-    CHECK( recRoI != nullptr );
+    if( recRoI == nullptr ) continue;
     recRoIVector.push_back(recRoI);
     ATH_MSG_DEBUG("REGTEST: " << m_recRoiCollectionKey.key() << " eta/phi = " << (recRoI)->eta() << "/" << (recRoI)->phi());
     ATH_MSG_DEBUG("REGTEST: " << m_recRoiCollectionKey.key() << " size = " << recRoIVector.size());
@@ -1842,7 +1842,8 @@ bool MuFastSteering::storeMSRoiDescriptor(const TrigRoiDescriptor*
     const float phiHalfWidth = 0.1;
     const float etaHalfWidth = 0.1;
 
-    TrigRoiDescriptor* MSroiDescriptor = new TrigRoiDescriptor(roids->l1Id(),
+    TrigRoiDescriptor* MSroiDescriptor = new TrigRoiDescriptor(roids->roiWord(),
+                                                               roids->l1Id(),
                                                                roids->roiId(),
                                                                pattern.etaMap,
                                                                pattern.etaMap - etaHalfWidth,
@@ -1909,7 +1910,8 @@ bool MuFastSteering::storeIDRoiDescriptor(const TrigRoiDescriptor*
     if (pattern.isTgcFailure || pattern.isRpcFailure) 
       phiHalfWidth *= scalePhiWidthForFailure;
 
-    TrigRoiDescriptor* IDroiDescriptor = new TrigRoiDescriptor(roids->l1Id(),
+    TrigRoiDescriptor* IDroiDescriptor = new TrigRoiDescriptor(roids->roiWord(),
+                                                               roids->l1Id(),
                                                                roids->roiId(),
                                                                pattern.etaVtx,
                                                                pattern.etaVtx - etaHalfWidth,
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/DataStructure.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/DataStructure.h
index 33dbd009dc9bf801b1b60fea729b20e5c2b15864..da6a9fe0fb60992d3db8dec258d78ce79ea34bd4 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/DataStructure.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/DataStructure.h
@@ -102,6 +102,15 @@ namespace TrigConf {
          return data().get_value<T>();
       }
 
+      /** @brief access to content of the note
+       * Will return false if the value could not be converted into @c T
+       */
+      template<class T>
+      std::optional<T> getValue_optional() const {
+         auto v = data().get_value_optional<T>();
+         return v ? std::optional<T>(std::move(*v)) : std::nullopt;
+      }
+
       /** Check for attribute
        * @param key The path to the attribute name, relative to the current one in form "path.to.child"
        * @return true if path @c key exists and is an attribute
@@ -136,6 +145,16 @@ namespace TrigConf {
          return obj.get().get_value<T>();
       }
 
+      template<class T>
+      std::optional<T> getAttribute_optional(const std::string & key) const {
+         const auto & obj = data().get_child_optional(key);
+         if( ! obj ) {
+            return std::nullopt;
+         }
+         auto v = obj.get().get_value_optional<T>();
+         return v ? std::optional(std::move(*v)) : std::nullopt;
+      }
+
       const std::string & getAttribute(const std::string & key, bool ignoreIfMissing = false, const std::string & def = "") const;
 
       /** Access to array structure
@@ -147,6 +166,8 @@ namespace TrigConf {
        */
       std::vector<DataStructure> getList(const std::string & pathToChild, bool ignoreIfMissing = false) const;
 
+      std::optional<std::vector<DataStructure> > getList_optional(const std::string & pathToChild) const;
+
       /** Access to configuration object 
        * @param pathToChild The path to the configuration child, relative to the current one
        * @param ignoreIfMissing Controls the behavior in case of missing configuration child
@@ -162,6 +183,9 @@ namespace TrigConf {
        **/
       DataStructure getObject(const std::string & pathToChild, bool ignoreIfMissing = false) const;
 
+      std::optional<TrigConf::DataStructure>
+      getObject_optional(const std::string & pathToChild) const;
+
 
       /** Access to the keys of an DataStructure which presents a dictionary 
        *
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1CTP.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1CTP.h
new file mode 100644
index 0000000000000000000000000000000000000000..7f47669c86026cc321a6f3e5ffa4e3cf7aef6f1b
--- /dev/null
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1CTP.h
@@ -0,0 +1,60 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGCONFDATA_L1CTP_H
+#define TRIGCONFDATA_L1CTP_H
+
+#include "TrigConfData/DataStructure.h"
+
+#include <map>
+
+namespace TrigConf {
+
+   /** @brief a TriggerLine entry describes the location of a threshold multiplicity on a cable (connector)
+    *
+    * for electrical connections from L1Topo boards it also knows
+    * which fpga they come from and which clock signal they have (those signals run on doubled clock)
+    */
+
+   /** @brief L1 board configuration */
+   class L1CTP final : public DataStructure {
+   public:
+
+      L1CTP() = default;
+      /** Constructor initialized with configuration data 
+       * @param data The data containing the L1 CTP configuration 
+       */
+      L1CTP(const std::string & name, const ptree & data);
+
+      L1CTP(const L1CTP &) = delete;
+      L1CTP& operator=(const L1CTP&) = delete;
+      L1CTP(L1CTP&&) = delete;
+
+      ~L1CTP() = default;
+
+      /** @brief name of ctpin connector
+       * @param slot CTPIN board 7..9 
+       * @param conn CTPIN connector 0..3 on each board
+       */
+      const std::string & ctpin(size_t slot, size_t conn) const;
+
+      const std::string & electrical(size_t conn) const;
+
+      const std::string & optical(size_t conn) const;
+
+      const std::map<std::string, std::pair<size_t,std::string>> ctpMon() const { return m_ctpmon; }
+
+   private:
+
+      virtual void update() { load(); };
+      void load();
+      std::string m_ctpin[3][4];
+      std::string m_electrical[3];
+      std::string m_optical[12];
+
+      std::map<std::string, std::pair<size_t,std::string>> m_ctpmon;
+   };
+}
+
+#endif
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Connector.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Connector.h
index 7cb5f6fe1e3b827a93623fc052c5cc782427081c..69cd439b7ec972f06603675d78524a47c9b696d0 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Connector.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Connector.h
@@ -63,8 +63,10 @@ namespace TrigConf {
       /** Accessor to the number of trigger lines */
       std::size_t size() const;
 
+      std::string type() const;
+
       /** Accessor to the connector type */
-      ConnectorType type() const;
+      ConnectorType connectorType() const;
 
       /** names of all trigger lines */
       std::vector<std::string> triggerLineNames() const;
@@ -84,7 +86,14 @@ namespace TrigConf {
 
       const TrigConf::TriggerLine & triggerLine( const std::string & lineName ) const;
 
+      bool legacy() const { return m_isLegacy; }
+      
+      [[deprecated("Use legacy() instead.")]]
       bool isLegacy() const { return m_isLegacy; }
+      
+      std::size_t maxFpga() const { return m_maxFpga; }
+
+      std::size_t maxClock() const { return m_maxClock; }
 
    private:
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Item.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Item.h
index 6870b781f86f5ce3760fad5821b0b652449e4023..26ea08d19cbbfcb7f9782ec6f59646a35501b9b3 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Item.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Item.h
@@ -62,6 +62,10 @@ namespace TrigConf {
        */
       unsigned char triggerTypeAsUChar() const;
 
+      /** Accessor to the item legacy flag
+       */
+      std::optional<bool> legacy() const;
+
       /** Accessor to the item logic
        *
        * The current description of the logic is rather complex and
@@ -72,7 +76,8 @@ namespace TrigConf {
    private:
 
       /** Update the internal data after modification of the data object */
-      virtual void update();
+      virtual void update() { load(); };
+      void load();
 
       std::vector<std::string> m_bunchgroups{};
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h
index 8bf39b073a6f486b60c60d2ce6cf9acf086bde8a..ec42d396b55c919998c5f3a1cde9dc83fd9c8305 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h
@@ -13,6 +13,7 @@
 #include "TrigConfData/L1TopoAlgorithm.h"
 #include "TrigConfData/L1Threshold.h"
 #include "TrigConfData/L1ThrExtraInfo.h"
+#include "TrigConfData/L1CTP.h"
 
 #include <vector>
 #include <map>
@@ -140,6 +141,9 @@ namespace TrigConf {
       /** Name of connector from name of threshold or triggerline */
       const std::string & connectorNameFromThreshold(const std::string & thresholdName) const;
 
+      /** the CTP configuration */
+      const TrigConf::L1CTP & ctp() const { return m_ctp; }
+
       /** print overview of L1 Menu */
       void printMenu(bool full = false) const;
 
@@ -171,6 +175,8 @@ namespace TrigConf {
       std::map<std::string, std::map<std::string, TrigConf::L1TopoAlgorithm*>> m_algorithmsByName{}; // map from category and algorithm name to algorithm 
       std::map<std::string, std::map<std::string, TrigConf::L1TopoAlgorithm*>> m_algorithmsByOutput{}; // map from category and output name to algorithm
 
+      TrigConf::L1CTP m_ctp;
+
    };
 
 }
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThrExtraInfo.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThrExtraInfo.h
index 203fc5117367d20f1bed70ae54e5015018a8aee3..3c0541334cffdfd99a3bed60b84fb882101da659 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThrExtraInfo.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThrExtraInfo.h
@@ -18,7 +18,8 @@ namespace TrigConf {
    class L1ThrExtraInfo_EMTAULegacy;
    class L1ThrExtraInfo_JETLegacy;
    class L1ThrExtraInfo_XSLegacy;
-   class L1ThrExtraInfo_eEMTAU;
+   class L1ThrExtraInfo_eEM;
+   class L1ThrExtraInfo_eTAU;
    class L1ThrExtraInfo_jJ;
    class L1ThrExtraInfo_jTAU;
    class L1ThrExtraInfo_gXE;
@@ -34,8 +35,8 @@ namespace TrigConf {
       const L1ThrExtraInfo_EMTAULegacy & TAU() const;
       const L1ThrExtraInfo_JETLegacy & JET() const;
       const L1ThrExtraInfo_XSLegacy & XS() const;
-      const L1ThrExtraInfo_eEMTAU & eEM() const;
-      const L1ThrExtraInfo_eEMTAU & eTAU() const;
+      const L1ThrExtraInfo_eEM & eEM() const;
+      const L1ThrExtraInfo_eTAU & eTAU() const;
       const L1ThrExtraInfo_jJ & jJ() const;
       const L1ThrExtraInfo_jTAU & jTAU() const;
       const L1ThrExtraInfo_gXE & gXE() const;
@@ -80,8 +81,8 @@ namespace TrigConf {
       virtual ~L1ThrExtraInfo_JETLegacy() = default;
       virtual std::string className() const { return "L1ThrExtraInfo_JETLegacy"; }
       unsigned int jetScale() const { return 1000 / resolutionMeV(); }
-      float ptMinToTopoLargeWindow() const { return m_ptMinToTopoLargeWindowMeV / 1000.0f; }
-      float ptMinToTopoSmallWindow() const { return m_ptMinToTopoSmallWindowMeV / 1000.0f; }
+      double ptMinToTopoLargeWindow() const { return m_ptMinToTopoLargeWindowMeV / 1000.0; }
+      double ptMinToTopoSmallWindow() const { return m_ptMinToTopoSmallWindowMeV / 1000.0; }
       unsigned int ptMinToTopoLargeWindowMeV() const { return m_ptMinToTopoLargeWindowMeV; }
       unsigned int ptMinToTopoSmallWindowMeV() const { return m_ptMinToTopoSmallWindowMeV; }
       unsigned int ptMinToTopoLargeWindowCounts() const { return energyInCounts( m_ptMinToTopoLargeWindowMeV, resolutionMeV() ); }
@@ -123,46 +124,95 @@ namespace TrigConf {
    /***********************************
     * Extra info for new thresholds
     ***********************************/
-   class L1ThrExtraInfo_eEMTAU final : public L1ThrExtraInfoBase {
+   class L1ThrExtraInfo_eEM final : public L1ThrExtraInfoBase {
    public:
-      L1ThrExtraInfo_eEMTAU(const std::string & thrTypeName, const ptree & data) :
+      class WorkingPoints_eEM {
+      public:
+         WorkingPoints_eEM() = default;
+         WorkingPoints_eEM( const boost::property_tree::ptree & );
+         bool isDefined() const { return m_isDefined; } 
+         int reta()       const { return m_reta; } 
+         int wstot()      const { return m_wstot; }
+         int rhad()       const { return m_rhad; }
+         int had()        const { return m_rhad; }
+         unsigned int maxEt()  const { return m_maxEt; }
+         double reta_d()       const { return m_reta/100.; } 
+         double wstot_d()     const { return m_wstot/100.; }
+         double rhad_d()       const { return m_rhad/100.; }
+      private:
+         bool m_isDefined { false };
+         int m_reta { 0 };
+         int m_wstot { 0 };
+         int m_rhad { 0 };
+         unsigned int m_maxEt { 0 };
+      };
+      L1ThrExtraInfo_eEM(const std::string & thrTypeName, const ptree & data) :
          L1ThrExtraInfoBase(thrTypeName, data) { load(); }
-      virtual ~L1ThrExtraInfo_eEMTAU() = default;
-      virtual std::string className() const { return "L1ThrExtraInfo_eEMTAU"; }
+      virtual ~L1ThrExtraInfo_eEM() = default;
+      virtual std::string className() const { return "L1ThrExtraInfo_eEM"; }
       float ptMinToTopo() const { return m_ptMinToTopoMeV/1000.0f; }
       unsigned int ptMinToTopoMeV() const { return m_ptMinToTopoMeV; }
       unsigned int ptMinToTopoCounts() const { return energyInCounts( m_ptMinToTopoMeV, resolutionMeV() ); }
-      const TrigConf::Isolation & isolation(TrigConf::Isolation::WP wp, int eta) const;
-      const ValueWithEtaDependence<TrigConf::Isolation> & isolation(TrigConf::Isolation::WP wp) const;
+      const WorkingPoints_eEM & isolation(TrigConf::Selection::WP wp, int eta) const { return m_isolation.at(wp).at(eta); }
+      const ValueWithEtaDependence<WorkingPoints_eEM> & isolation(TrigConf::Selection::WP wp) const { return m_isolation.at(wp); }
    private:
       /** Update the internal members */
       void load();
       /** eEM specific data */
       unsigned int m_ptMinToTopoMeV{0};
-      std::map<TrigConf::Isolation::WP, ValueWithEtaDependence<Isolation>> m_isolation{};
+      std::map<TrigConf::Selection::WP, ValueWithEtaDependence<WorkingPoints_eEM>> m_isolation{};
    };
+   std::ostream & operator<<(std::ostream & os, const TrigConf::L1ThrExtraInfo_eEM::WorkingPoints_eEM & iso);
 
 
+
+   class L1ThrExtraInfo_eTAU final : public L1ThrExtraInfoBase {
+   public:
+      class WorkingPoints_eTAU {
+      public:
+         WorkingPoints_eTAU( const boost::property_tree::ptree & );
+         int isolation() const { return m_isolation; }
+         double isolation_d() const { return m_isolation/100.; }
+         unsigned int maxEt() const { return m_maxEt; }
+      private:
+         int m_isolation {0};
+         unsigned int m_maxEt { 0 };
+      };
+      L1ThrExtraInfo_eTAU(const std::string & thrTypeName, const ptree & data) :
+         L1ThrExtraInfoBase(thrTypeName, data) { load(); }
+      virtual ~L1ThrExtraInfo_eTAU() = default;
+      virtual std::string className() const { return "L1ThrExtraInfo_eTAU"; }
+      float ptMinToTopo() const { return m_ptMinToTopoMeV/1000.0f; }
+      unsigned int ptMinToTopoMeV() const { return m_ptMinToTopoMeV; }
+      unsigned int ptMinToTopoCounts() const { return energyInCounts( m_ptMinToTopoMeV, resolutionMeV() ); }
+      const WorkingPoints_eTAU & isolation(TrigConf::Selection::WP wp, int eta) const { return m_isolation.at(wp).at(eta); }
+      const ValueWithEtaDependence<WorkingPoints_eTAU> & isolation(TrigConf::Selection::WP wp) const  { return m_isolation.at(wp); }
+   private:
+      /** Update the internal members */
+      void load();
+      /** eEM specific data */
+      unsigned int m_ptMinToTopoMeV{0};
+      std::map<TrigConf::Selection::WP, ValueWithEtaDependence<WorkingPoints_eTAU>> m_isolation{};
+   };
+
    class L1ThrExtraInfo_jJ final : public L1ThrExtraInfoBase {
    public:
       L1ThrExtraInfo_jJ(const std::string & thrTypeName, const ptree & data) :
          L1ThrExtraInfoBase(thrTypeName, data) { load(); }
       virtual ~L1ThrExtraInfo_jJ() = default;
       virtual std::string className() const { return "L1ThrExtraInfo_jJ"; }
-      float ptMinToTopoLarge(int eta = 0) const { return ptMinToTopoLargeMeV(eta) / 1000.0f; }
-      float ptMinToTopoSmall(int eta = 0) const { return ptMinToTopoSmallMeV(eta) / 1000.0f; }
-      unsigned int ptMinToTopoLargeMeV(int eta = 0) const { return m_ptMinToTopoLargeMeV.at(eta); }
-      unsigned int ptMinToTopoSmallMeV(int eta = 0) const { return m_ptMinToTopoSmallMeV.at(eta); }
+      double ptMinToTopoLarge(int eta = 0) const { return ptMinToTopoLargeMeV(eta) / 1000.0; }
+      double ptMinToTopoSmall(int eta = 0) const { return ptMinToTopoSmallMeV(eta) / 1000.0; }
+      unsigned int ptMinToTopoLargeMeV(int eta = 0) const { return m_ptMinToTopoMeV.at(eta).second; }
+      unsigned int ptMinToTopoSmallMeV(int eta = 0) const { return m_ptMinToTopoMeV.at(eta).first; }
       unsigned int ptMinToTopoLargeCounts(int eta = 0) const { return energyInCounts( ptMinToTopoLargeMeV(eta), resolutionMeV() ); }
       unsigned int ptMinToTopoSmallCounts(int eta = 0) const { return energyInCounts( ptMinToTopoSmallMeV(eta), resolutionMeV() ); }
+      const ValueWithEtaDependence<std::pair<unsigned int,unsigned int>> & ptMinToTopoMeV() const { return m_ptMinToTopoMeV; }
    private:
       /** Update the internal members */
       void load();
       /** jJ specific data */
-      ValueWithEtaDependence<unsigned int> m_ptMinToTopoSmallMeV{"jJptMinTopoLarge"};
-      ValueWithEtaDependence<unsigned int> m_ptMinToTopoLargeMeV{"jJptMinTopoSmall"};
-      //std::map<std::pair<int,int>,unsigned int> m_ptMinToTopoSmallMeV{};
-      //std::map<std::pair<int,int>,unsigned int> m_ptMinToTopoLargeMeV{};
+      ValueWithEtaDependence<std::pair<unsigned int,unsigned int>> m_ptMinToTopoMeV{"jJptMinTopo"};
    };
 
 
@@ -205,7 +255,7 @@ namespace TrigConf {
       std::vector<unsigned int> knownRpcPtValues() const;
       std::vector<unsigned int> knownTgcPtValues() const;
       std::vector<std::string> exclusionListNames() const;
-      const std::map<std::string, std::vector<unsigned int>> & exlusionList(const std::string & listName) const;
+      const std::map<std::string, std::vector<unsigned int>> & exclusionList(const std::string & listName) const;
    private:
       /** Update the internal members */
       void load();
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Threshold.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Threshold.h
index 41418eeb3d15c5fc55f2a4cf83d58240619b3575..3058f9dac82f62b03fb30a4390baf407c37e6962 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Threshold.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Threshold.h
@@ -16,8 +16,8 @@ namespace TrigConf {
     ************************************/
    class L1Threshold_EM final : public L1Threshold_Calo {
    public:
-      L1Threshold_EM( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
-         L1Threshold_Calo(name, type, m_extraInfo, data) { load(); }
+      L1Threshold_EM( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> extraInfo, const ptree & data) :
+         L1Threshold_Calo(name, type, extraInfo, data) { load(); }
       virtual ~L1Threshold_EM() = default;
       // class name
       virtual std::string className() const override { return "L1Threshold_EM"; }
@@ -36,8 +36,8 @@ namespace TrigConf {
 
    class L1Threshold_TAU final : public L1Threshold_Calo {
    public:
-      L1Threshold_TAU( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
-         L1Threshold_Calo(name, type, m_extraInfo, data) { load(); }
+      L1Threshold_TAU( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> extraInfo, const ptree & data) :
+         L1Threshold_Calo(name, type, extraInfo, data) { load(); }
       virtual ~L1Threshold_TAU() = default;
       virtual std::string className() const override { return "L1Threshold_TAU"; }
       // access functions
@@ -54,54 +54,80 @@ namespace TrigConf {
 
    class L1Threshold_JET final : public L1Threshold_Calo {
    public:
-      L1Threshold_JET( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
-         L1Threshold_Calo(name, type, m_extraInfo, data) {};
+      L1Threshold_JET( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> extraInfo, const ptree & data) :
+         L1Threshold_Calo(name, type, extraInfo, data) { load(); };
       virtual ~L1Threshold_JET() = default;
       virtual std::string className() const override { return "L1Threshold_JET"; }
+      unsigned int window(int eta = 0) const;
+   protected:
+      virtual void update() override {
+         L1Threshold_Calo::update();
+         load();
+      }
+   private:
+      ValueWithEtaDependence<unsigned int> m_etaDepWindow{""}; ///< eta-dependent threshold value in MeV
+      void load();
    };
 
    class L1Threshold_XE final : public L1Threshold_Calo {
    public:
-      L1Threshold_XE( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
-         L1Threshold_Calo(name, type, m_extraInfo, data) {};
+      L1Threshold_XE( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> extraInfo, const ptree & data) :
+         L1Threshold_Calo(name, type, extraInfo, data) {};
       virtual ~L1Threshold_XE() = default;
       virtual std::string className() const override { return "L1Threshold_XE"; }
    };
 
    class L1Threshold_XS final : public L1Threshold_Calo {
    public:
-      L1Threshold_XS( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
-         L1Threshold_Calo(name, type, m_extraInfo, data) {};
+      L1Threshold_XS( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> extraInfo, const ptree & data) :
+         L1Threshold_Calo(name, type, extraInfo, data) {};
       virtual ~L1Threshold_XS() = default;
       virtual std::string className() const override { return "L1Threshold_XS"; }
    };
 
    class L1Threshold_TE final : public L1Threshold_Calo {
    public:
-      L1Threshold_TE( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
-         L1Threshold_Calo(name, type, m_extraInfo, data) {};
+      L1Threshold_TE( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> extraInfo, const ptree & data) :
+         L1Threshold_Calo(name, type, extraInfo, data) {};
       virtual ~L1Threshold_TE() = default;
       virtual std::string className() const override { return "L1Threshold_TE"; }
    };
 
    /************************************
     *
-    *  NIM and internal thresholds
+    *  ZB, NIM and internal thresholds
     *
     ************************************/
+   class L1Threshold_ZB final : public L1Threshold {
+   public:
+      L1Threshold_ZB( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> extraInfo, const ptree & data) :
+         L1Threshold(name, type, extraInfo, data) { load(); };
+      virtual ~L1Threshold_ZB() = default;
+      virtual std::string className() const override { return "L1Threshold_ZB"; }
+      const std::string & seed() const { return m_seed; }
+      unsigned int seedBcdelay() const { return m_seedBcdelay; }
+      unsigned int seedMultiplicity() const { return m_seedMultiplicity; }
+   protected:
+      virtual void update() override { load(); }
+   private:
+      std::string m_seed{""};
+      unsigned int m_seedBcdelay{0};
+      unsigned int m_seedMultiplicity{1};
+      void load();
+   };
 
    class L1Threshold_NIM final : public L1Threshold {
    public:
-      L1Threshold_NIM( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
-         L1Threshold(name, type, m_extraInfo, data) {};
+      L1Threshold_NIM( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> extraInfo, const ptree & data) :
+         L1Threshold(name, type, extraInfo, data) {};
       virtual ~L1Threshold_NIM() = default;
       virtual std::string className() const override { return "L1Threshold_NIM"; }
    };
 
    class L1Threshold_internal final : public L1Threshold {
    public:
-      L1Threshold_internal( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
-         L1Threshold(name, type, m_extraInfo, data) {};
+      L1Threshold_internal( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> extraInfo, const ptree & data) :
+         L1Threshold(name, type, extraInfo, data) {};
       virtual ~L1Threshold_internal() = default;
       virtual std::string className() const override { return "L1Threshold_internal"; }
    };
@@ -113,14 +139,14 @@ namespace TrigConf {
     ************************************/
    class L1Threshold_eEM final : public L1Threshold_Calo {
    public:
-      L1Threshold_eEM( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
-         L1Threshold_Calo(name, type, m_extraInfo, data) { load(); }
+      L1Threshold_eEM( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> extraInfo, const ptree & data) :
+         L1Threshold_Calo(name, type, extraInfo, data) { load(); }
       virtual ~L1Threshold_eEM() = default;
       virtual std::string className() const override { return "L1Threshold_eEM"; }
       // access functions
-      Isolation::WP reta() const { return m_reta; }
-      Isolation::WP rhad() const { return m_rhad; }
-      Isolation::WP wstot() const { return m_wstot; }      
+      Selection::WP reta() const { return m_reta; }
+      Selection::WP rhad() const { return m_rhad; }
+      Selection::WP wstot() const { return m_wstot; }
    protected:
       virtual void update() override {
          L1Threshold_Calo::update();
@@ -129,15 +155,15 @@ namespace TrigConf {
    private:
       void load();
       // the isolation requirement
-      Isolation::WP m_reta { Isolation::WP::NONE };
-      Isolation::WP m_rhad { Isolation::WP::NONE };
-      Isolation::WP m_wstot { Isolation::WP::NONE };
+      Selection::WP m_reta { Selection::WP::NONE };
+      Selection::WP m_rhad { Selection::WP::NONE };
+      Selection::WP m_wstot { Selection::WP::NONE };
    };
 
    class L1Threshold_eTAU final : public L1Threshold_Calo {
    public:
-      L1Threshold_eTAU( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
-         L1Threshold_Calo(name, type, m_extraInfo, data) { load(); }
+      L1Threshold_eTAU( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> extraInfo, const ptree & data) :
+         L1Threshold_Calo(name, type, extraInfo, data) { load(); }
       virtual ~L1Threshold_eTAU() = default;
       virtual std::string className() const override { return "L1Threshold_eTAU"; }
    protected:
@@ -149,9 +175,20 @@ namespace TrigConf {
       void load();
    };
 
-
-
-
+   class L1Threshold_jJ final : public L1Threshold_Calo {
+   public:
+      L1Threshold_jJ( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> extraInfo, const ptree & data) :
+         L1Threshold_Calo(name, type, extraInfo, data) { load(); }
+      virtual ~L1Threshold_jJ() = default;
+      virtual std::string className() const override { return "L1Threshold_jJ"; }
+   protected:
+      virtual void update() override {
+         L1Threshold_Calo::update();
+         load();
+      }
+   private:
+      void load();
+   };
 
 
    /************************************
@@ -161,8 +198,8 @@ namespace TrigConf {
     ************************************/
    class L1Threshold_MU final : public L1Threshold {
    public:
-      L1Threshold_MU( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
-         L1Threshold(name, type, m_extraInfo, data) { load(); }
+      L1Threshold_MU( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> extraInfo, const ptree & data) :
+         L1Threshold(name, type, extraInfo, data) { load(); }
       virtual ~L1Threshold_MU() = default;
       virtual std::string className() const override { return "L1Threshold_MU"; }
 
@@ -175,8 +212,11 @@ namespace TrigConf {
       unsigned int idxEndcap() const { return m_idxEndcap; }
       unsigned int idxForward() const { return m_idxForward; }
       const std::string & region() const { return m_region; }
-      const std::string & tgcFlag() const { return m_tgcFlag; }
+      const std::string & tgcFlags() const { return m_tgcFlags; }
       const std::string & rpcExclROIList() const { return m_rpcExclROIList; }
+      std::optional<std::string> rpcExclROIList_optional() const {
+         return m_rpcExclROIList.empty() ? std::nullopt : std::optional<std::string>{m_rpcExclROIList};
+      }
    protected:
       virtual void update() override {
          L1Threshold::update();
@@ -193,7 +233,7 @@ namespace TrigConf {
       unsigned int m_idxForward{0};
       // the isolation requirement
       std::string m_region{""}; ///< comma-separated list of BA, EC, FW or the string ALL
-      std::string m_tgcFlag{""}; ///< a logical expression like 'F & C | F & H | C & H'
+      std::string m_tgcFlags{""}; ///< a logical expression like 'F & C | F & H | C & H'
       std::string m_rpcExclROIList{""}; ///< a string sepcifying the list of ROIs to be excluded (the lists are defined in the extraInfo_MU)
    };
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThresholdBase.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThresholdBase.h
index 0e9c5088b8099d82169236e02ea6207acc4a2577..02b993ee6fe8adde49c128216e45ab676802bf25 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThresholdBase.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThresholdBase.h
@@ -9,6 +9,7 @@
 
 #include <map>
 #include <vector>
+#include <optional>
 
 namespace TrigConf {
 
@@ -54,12 +55,15 @@ namespace TrigConf {
       bool empty() const;
       size_t size() const;
       const T & at(int eta) const;
+      std::optional<std::reference_wrapper<const T>> outsideRangeValue() const;
       const_iterator begin() const noexcept;
       const_iterator end() const noexcept;
       void addRangeValue(const T & value, int etaMin, int etaMax, unsigned int priority, bool symmetric = true);
+      void setOutsideRangeValue(const T & value);
    private:
       const std::string m_name {""};
       std::vector<RangeValue> m_rangeValues{};
+      std::optional<T> m_outsideRangeValue {std::nullopt};
    };
 
 
@@ -91,6 +95,9 @@ namespace TrigConf {
 
       bool hasExtraInfo( const std::string & key = "") const;
 
+      std::optional<std::reference_wrapper<const TrigConf::DataStructure>>
+      getExtraInfo( const std::string & key) const;
+
       unsigned int resolutionMeV() const { 
          return m_resolutionMeV;
       }
@@ -245,11 +252,6 @@ namespace TrigConf {
       void load();
    };
 
-
-
-
-
-
    /******************************************
     * Isolation for legacy L1Calo thresholds
     ******************************************/
@@ -281,25 +283,14 @@ namespace TrigConf {
 
 
    /**************************************
-    * Isolation for new L1Calo thresholds
+    * Selection points for L1Calo thresholds
     **************************************/
-   class Isolation {
+   class Selection {
    public:
       enum class WP { NONE = 0, LOOSE = 1, MEDIUM = 2, TIGHT = 3 };
-      Isolation() = default;
-      Isolation( const boost::property_tree::ptree & );
-      bool isDefined() const { return m_isDefined; } 
-      int reta()       const { return m_reta; } 
-      int wstot()      const { return m_wstot; }
-      int had()        const { return m_had; }
-   private:
-      bool m_isDefined { false };
-      int m_reta { 0 };
-      int m_wstot { 0 };
-      int m_had { 0 };
+      static std::string wpToString(WP);
+      static WP stringToWP(const std::string &);
    };
-   std::ostream & operator<<(std::ostream & os, const TrigConf::Isolation & iso);
-
 }
 
 #include "TrigConfData/L1ThresholdBase.icc"
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThresholdBase.icc b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThresholdBase.icc
index b73913f9b29c8e77129690f31dd421e863765c28..3e19b1fc218c40c5ea1dfaa56d247522ca22fc00 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThresholdBase.icc
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThresholdBase.icc
@@ -44,6 +44,19 @@ namespace TrigConf {
       m_rangeValues.emplace_back( std::move(rv) );
    }
 
+
+   template<class T>
+   void ValueWithEtaDependence<T>::setOutsideRangeValue(const T & value) {
+      m_outsideRangeValue = value;
+   }
+
+   template<class T>
+   std::optional<std::reference_wrapper<const T>> 
+   ValueWithEtaDependence<T>::outsideRangeValue() const {
+      return m_outsideRangeValue;
+   }
+
+
    template<class T>
    const T & ValueWithEtaDependence<T>::at(int eta) const {
       // the ranges are by definition such that the lower boundary is inclusive, while the upper boundary is exclusive
@@ -65,8 +78,10 @@ namespace TrigConf {
       }
       if( retVal ) {
          return * retVal;
+      } else if(m_outsideRangeValue) {
+         return *m_outsideRangeValue;
       } else {
-         throw std::runtime_error(name() + ": no value found with eta = " + std::to_string(eta));
+         throw std::out_of_range(name() + ": no value found with eta = " + std::to_string(eta));
       }
    }
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1TopoAlgorithm.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1TopoAlgorithm.h
index bc172ebd8f9653722d73807a4aca23f961eb24ad..0f4f761634e3e5cde1dcc95a1f3257de9d500d45 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1TopoAlgorithm.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1TopoAlgorithm.h
@@ -7,6 +7,7 @@
 
 #include "TrigConfData/DataStructure.h"
 #include <vector>
+#include <optional>
 
 namespace TrigConf {
 
@@ -22,11 +23,17 @@ namespace TrigConf {
       enum class AlgorithmType { SORTING, DECISION, MULTIPLICITY, UNKNOWN };
 
       struct VariableParameter {
-      VariableParameter(const std::string & _name, int _value, unsigned int _selection) 
-      : name(_name), value(_value), selection(_selection) {}
-         std::string name{""};
-         int value{0};
-         unsigned int selection{0};
+      public:
+         VariableParameter(const std::string & name, int value, std::optional<unsigned int> selection = std::nullopt)
+            : m_name(name), m_value(value), m_selection(selection) {}
+         const std::string & name() const { return m_name; }
+         int value() const { return m_value; }
+         unsigned int selection() const { return m_selection.value_or(0); }
+         std::optional<unsigned int> selection_optional() const { return m_selection; }
+      private:
+         std::string m_name{""};
+         int m_value{0};
+         std::optional<unsigned int> m_selection{};
       };
 
       /** Constructor */
@@ -83,10 +90,14 @@ namespace TrigConf {
       /** print main info */
       void print(std::ostream & os = std::cout) const override;
 
+   protected:
+
+      virtual void update() override { load(); }
+
    private:
 
       /** Update the internal data after modification of the data object */
-      virtual void update() override;
+      void load();
 
       AlgorithmType m_type{ AlgorithmType::UNKNOWN };
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/DataStructure.cxx b/Trigger/TrigConfiguration/TrigConfData/src/DataStructure.cxx
index bdfbbd44fee04617743dff5b389c58574a7651ed..2ce2ff8533bad99427c9c94f5c90e596580e3757 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/DataStructure.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/DataStructure.cxx
@@ -178,6 +178,16 @@ TrigConf::DataStructure::getList(const std::string & pathToChild, bool ignoreIfM
 }
 
 
+std::optional<std::vector<TrigConf::DataStructure> >
+TrigConf::DataStructure::getList_optional(const std::string & pathToChild) const
+{
+   if(data().find(pathToChild) == data().not_found()) {
+      return std::nullopt;
+   }
+   return std::optional<std::vector<TrigConf::DataStructure> >(getList(pathToChild));
+}
+
+
 TrigConf::DataStructure
 TrigConf::DataStructure::getObject(const std::string & pathToChild, bool ignoreIfMissing) const
 {
@@ -199,6 +209,17 @@ TrigConf::DataStructure::getObject(const std::string & pathToChild, bool ignoreI
 }
 
 
+std::optional<TrigConf::DataStructure>
+TrigConf::DataStructure::getObject_optional(const std::string & pathToChild) const
+{
+   if(data().find(pathToChild) == data().not_found()) {
+      return std::nullopt;
+   }
+   return std::optional<TrigConf::DataStructure>(getObject(pathToChild));
+}
+
+
+
 std::vector<std::string>
 TrigConf::DataStructure::getKeys() const 
 {
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4a6b69032195aa403e0a4992dc3b1465b5762729
--- /dev/null
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx
@@ -0,0 +1,73 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TrigConfData/L1CTP.h"
+
+TrigConf::L1CTP::L1CTP(const std::string & name, const boost::property_tree::ptree & data) 
+   : DataStructure(name,data)
+{
+   load();
+}
+
+void
+TrigConf::L1CTP::load()
+{
+   if(! isInitialized() || empty() ) {
+      return;
+   }
+   auto inputs = data().get_child("inputs");
+   for(size_t slot = 7; slot<=9; ++slot) {
+      for(size_t conn=0; conn<4; ++conn) {
+         m_ctpin[slot-7][conn] = inputs.get_optional<std::string>("ctpin.slot" + std::to_string(slot) + ".connector" + std::to_string(conn)).get_value_or("");
+      }
+   }
+   auto electrical = inputs.get_child("electrical");
+   for(size_t i=0; i<3; ++i) {
+      m_electrical[i] = electrical.get_optional<std::string>("connector" + std::to_string(i)).get_value_or("");
+   }
+   auto optical = inputs.get_child("optical");
+   for(size_t i=0; i<12; ++i) {
+      m_optical[i] = optical.get_optional<std::string>("connector" + std::to_string(i)).get_value_or("");
+   }
+   for( auto & mon : data().get_child("monitoring.ctpmon") ) {
+      std::string monName = mon.first;
+      size_t multiplicity = mon.second.get_child("multiplicity").get_value<size_t>();
+      std::string thr = mon.second.get_child("thr").get_value<std::string>();
+      m_ctpmon.emplace( std::piecewise_construct,
+                        std::forward_as_tuple(monName),
+                        std::forward_as_tuple(multiplicity, thr)
+                        );
+   }
+   
+
+}
+
+const std::string &
+TrigConf::L1CTP::ctpin(size_t slot, size_t conn) const
+{
+   if(slot<7 or slot>9) {
+      throw std::runtime_error("CTPIN slot must be between 7 and 9, but " + std::to_string(slot) + "was specified");
+   }
+   if(conn>3) {
+      throw std::runtime_error("CTPIN connector must be between 0 and 3, but " + std::to_string(conn) + "was specified");
+   }
+   return m_ctpin[slot-7][conn];
+}
+
+
+const std::string &
+TrigConf::L1CTP::electrical(size_t conn) const {
+   if(conn>2) {
+      throw std::runtime_error("Electrical connector must be between 0 and 2, but " + std::to_string(conn) + "was specified");
+   }
+   return m_electrical[conn];
+}
+
+const std::string &
+TrigConf::L1CTP::optical(size_t conn) const {
+   if(conn>11) {
+      throw std::runtime_error("Optical connector must be between 0 and 11, but " + std::to_string(conn) + "was specified");
+   }
+   return m_optical[conn];
+}
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1Connector.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1Connector.cxx
index 3b206408e3d7953a6f366b24ab350321424b8d3e..3d7de39fe718199f18ac10d63949e17473a802ee 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1Connector.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1Connector.cxx
@@ -57,7 +57,7 @@ TrigConf::L1Connector::update()
                path += std::to_string(fpga);
             }
             path += ".clock";
-            path += std::to_string(clock);            
+            path += std::to_string(clock);
          }
          const auto & triggerlines = data().get_child(path);
          m_triggerLines[fpga][clock].reserve(triggerlines.size());
@@ -75,8 +75,22 @@ TrigConf::L1Connector::update()
 }
 
 
-TrigConf::L1Connector::ConnectorType
+std::string
 TrigConf::L1Connector::type() const 
+{
+   switch( m_type ) {
+   case ConnectorType::ELECTRICAL:
+      return "electrical";
+   case ConnectorType::OPTICAL:
+      return "optical";
+   case ConnectorType::CTPIN:
+      return "ctpin";
+   }
+   return "";
+}
+
+TrigConf::L1Connector::ConnectorType
+TrigConf::L1Connector::connectorType() const 
 {
    return m_type;
 }
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1Item.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1Item.cxx
index e9288a4022bf7f6302b6e168598e59a8c40df05d..a4a6587d8f384dd37b7c7065bf429ede4276a967 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1Item.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1Item.cxx
@@ -10,7 +10,7 @@ TrigConf::L1Item::L1Item()
 TrigConf::L1Item::L1Item(const boost::property_tree::ptree & data) 
    : DataStructure(data)
 {
-   update();
+   load();
 }
 
 TrigConf::L1Item::~L1Item()
@@ -22,7 +22,7 @@ TrigConf::L1Item::className() const {
 }
 
 void
-TrigConf::L1Item::update()
+TrigConf::L1Item::load()
 {
    if(! isInitialized() || empty() ) {
       return;
@@ -74,6 +74,12 @@ TrigConf::L1Item::triggerType() const
    return getAttribute("triggerType");
 }
 
+std::optional<bool>
+TrigConf::L1Item::legacy() const
+{
+   return hasAttribute("legacy") ? std::optional<bool>{getAttribute<bool>("legacy")} : std::nullopt;
+}
+
 unsigned char
 TrigConf::L1Item::triggerTypeAsUChar() const
 {
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx
index 27660fb9a7e0694fdb6f3367148b655a9a3e7ea8..3becff35226048a63f09857195565f11dcb2c7b7 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx
@@ -25,7 +25,6 @@ TrigConf::L1Menu::update()
    if(! isInitialized() || empty() ) {
       return;
    }
-
    try {
       m_name = getAttribute("name");
       // thresholds
@@ -128,6 +127,15 @@ TrigConf::L1Menu::update()
       std::cerr << "ERROR: problem when building L1 menu structure (algorithms). " << ex.what() << std::endl;
       throw;
    }
+
+   try {
+      // CTP
+      m_ctp.setData(data().get_child("ctp"));
+   }
+   catch(std::exception & ex) {
+      std::cerr << "ERROR: problem when building L1 menu structure (CTP). " << ex.what() << std::endl;
+      throw;
+   }
 }
 
 unsigned int 
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1ThrExtraInfo.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1ThrExtraInfo.cxx
index 03e03f08807aedb6837b2e0c6946cb8d5b530ff8..8cc9ce6cfbffd6495b3199c6453646f9d0e7ca4a 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1ThrExtraInfo.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1ThrExtraInfo.cxx
@@ -28,8 +28,11 @@ TrigConf::L1ThrExtraInfo::createExtraInfo(const std::string & thrTypeName, const
    if( thrTypeName == "MU" )
       return std::make_unique<L1ThrExtraInfo_MU>(thrTypeName, data);
 
-   if( thrTypeName == "eEM" or thrTypeName == "eTAU" )
-      return std::make_unique<L1ThrExtraInfo_eEMTAU>(thrTypeName, data);
+   if( thrTypeName == "eEM" )
+      return std::make_unique<L1ThrExtraInfo_eEM>(thrTypeName, data);
+
+   if( thrTypeName == "eTAU" )
+      return std::make_unique<L1ThrExtraInfo_eTAU>(thrTypeName, data);
 
    if( thrTypeName == "jJ" )
       return std::make_unique<L1ThrExtraInfo_jJ>(thrTypeName, data);      
@@ -79,14 +82,14 @@ TrigConf::L1ThrExtraInfo::JET() const {
    return dynamic_cast<const TrigConf::L1ThrExtraInfo_JETLegacy&>( * m_thrExtraInfo.at("JET") );
 }
 
-const TrigConf::L1ThrExtraInfo_eEMTAU &
+const TrigConf::L1ThrExtraInfo_eEM &
 TrigConf::L1ThrExtraInfo::eEM() const {
-   return dynamic_cast<const TrigConf::L1ThrExtraInfo_eEMTAU&>( * m_thrExtraInfo.at("eEM") );
+   return dynamic_cast<const TrigConf::L1ThrExtraInfo_eEM&>( * m_thrExtraInfo.at("eEM") );
 }
 
-const TrigConf::L1ThrExtraInfo_eEMTAU &
+const TrigConf::L1ThrExtraInfo_eTAU &
 TrigConf::L1ThrExtraInfo::eTAU() const {
-   return dynamic_cast<const TrigConf::L1ThrExtraInfo_eEMTAU&>( * m_thrExtraInfo.at("eTAU") );
+   return dynamic_cast<const TrigConf::L1ThrExtraInfo_eTAU&>( * m_thrExtraInfo.at("eTAU") );
 }
 
 const TrigConf::L1ThrExtraInfo_jJ &
@@ -127,6 +130,10 @@ TrigConf::L1ThrExtraInfo::thrExtraInfo(const std::string & thrTypeName) const
 const TrigConf::IsolationLegacy &
 TrigConf::L1ThrExtraInfo_EMTAULegacy::isolation(const std::string & thrType, size_t bit) const
 {
+   if(bit<1 or bit>5) {
+      throw std::out_of_range("When accessing the legacy L1Calo EM or TAU isolation bit must be between 1 and 5, but bit=" 
+                              + std::to_string(bit) + " was requested");
+   }
    try {
       return m_isolation.at(thrType)[bit-1];
    }
@@ -197,34 +204,65 @@ TrigConf::L1ThrExtraInfo_JETLegacy::load()
 /*******
  * eEM
  *******/
-const TrigConf::Isolation &
-TrigConf::L1ThrExtraInfo_eEMTAU::isolation(TrigConf::Isolation::WP wp, int eta) const
-{
-   return m_isolation.at(wp).at(eta);
+TrigConf::L1ThrExtraInfo_eEM::WorkingPoints_eEM::WorkingPoints_eEM( const boost::property_tree::ptree & pt ) {
+   m_isDefined = true;
+   m_reta  = lround(100 * pt.get_optional<float>("reta").get_value_or(0));
+   m_wstot = lround(100 * pt.get_optional<float>("wstot").get_value_or(0));
+   m_rhad  = lround(100 * pt.get_optional<float>("rhad").get_value_or(0));
+   m_maxEt = pt.get_optional<unsigned int>("maxEt").get_value_or(0);
 }
 
-const TrigConf::ValueWithEtaDependence<TrigConf::Isolation> &
-TrigConf::L1ThrExtraInfo_eEMTAU::isolation(TrigConf::Isolation::WP wp) const
+std::ostream &
+TrigConf::operator<<(std::ostream & os, const TrigConf::L1ThrExtraInfo_eEM::WorkingPoints_eEM & iso) {
+   os << "reta=" << iso.reta() << ", wstot=" << iso.wstot() << ", rhad=" << iso.rhad();
+   return os;
+}
+
+void
+TrigConf::L1ThrExtraInfo_eEM::load()
 {
-   return m_isolation.at(wp);
+   for( auto & x : m_extraInfo ) {
+      if( x.first == "ptMinToTopo" ) {
+         m_ptMinToTopoMeV = lround(1000 * x.second.getValue<float>());
+      } else if( x.first == "workingPoints" ) {
+         for( auto & y : x.second.data() ) {
+            auto wp = Selection::stringToWP(y.first);
+            auto & iso = m_isolation.emplace(wp, string("eEM_WP_" + y.first)).first->second;
+            for(auto & c : y.second ) {
+               int etamin = c.second.get_optional<int>("etamin").get_value_or(-49);
+               int etamax = c.second.get_optional<int>("etamax").get_value_or(49);
+               unsigned int priority = c.second.get_optional<unsigned int>("priority").get_value_or(0);
+               iso.addRangeValue(WorkingPoints_eEM(c.second), etamin, etamax, priority, /*symmetric=*/ false);
+            }
+         }
+      }
+   }
 }
 
 
+/*******
+ * eTAU
+ *******/
+TrigConf::L1ThrExtraInfo_eTAU::WorkingPoints_eTAU::WorkingPoints_eTAU( const boost::property_tree::ptree & pt ) {
+   m_isolation = lround(100 * pt.get_optional<float>("isolation").get_value_or(0));
+   m_maxEt = pt.get_optional<unsigned int>("maxEt").get_value_or(0);
+}
+
 void
-TrigConf::L1ThrExtraInfo_eEMTAU::load()
+TrigConf::L1ThrExtraInfo_eTAU::load()
 {
    for( auto & x : m_extraInfo ) {
       if( x.first == "ptMinToTopo" ) {
          m_ptMinToTopoMeV = lround(1000 * x.second.getValue<float>());
       } else if( x.first == "workingPoints" ) {
          for( auto & y : x.second.data() ) {
-            auto wp = (y.first == "Loose") ? Isolation::WP::LOOSE : ( (y.first == "Medium") ? Isolation::WP::MEDIUM : Isolation::WP::TIGHT );
+            auto wp = TrigConf::Selection::stringToWP(y.first);
             auto & iso = m_isolation.emplace(wp, string("eEM_WP_" + y.first)).first->second;
             for(auto & c : y.second ) {
                int etamin = c.second.get_optional<int>("etamin").get_value_or(-49);
                int etamax = c.second.get_optional<int>("etamax").get_value_or(49);
                unsigned int priority = c.second.get_optional<unsigned int>("priority").get_value_or(0);
-               iso.addRangeValue(Isolation(c.second), etamin, etamax, priority, /*symmetric=*/ false);
+               iso.addRangeValue(WorkingPoints_eTAU(c.second), etamin, etamax, priority, /*symmetric=*/ false);
             }
          }
       }
@@ -232,6 +270,9 @@ TrigConf::L1ThrExtraInfo_eEMTAU::load()
 }
 
 
+
+
+
 /*******
  * jJ
  *******/
@@ -246,8 +287,8 @@ TrigConf::L1ThrExtraInfo_jJ::load()
             auto small = k.second.get_child("small").get_value<float>();
             auto large = k.second.get_child("large").get_value<float>();
             auto priority = k.second.get_optional<unsigned int>("priority").get_value_or(0);            
-            m_ptMinToTopoSmallMeV.addRangeValue( lround(1000*small), etamin, etamax, priority, /*symmetric=*/ false);
-            m_ptMinToTopoLargeMeV.addRangeValue( lround(1000*large), etamin, etamax, priority, /*symmetric=*/ false);
+            m_ptMinToTopoMeV.addRangeValue( std::make_pair<unsigned int, unsigned int>(lround(1000*small),lround(1000*large)),
+                                            etamin, etamax, priority, /*symmetric=*/ false);
          }
       }
    }
@@ -336,7 +377,7 @@ TrigConf::L1ThrExtraInfo_MU::exclusionListNames() const
 
 
 const std::map<std::string, std::vector<unsigned int> > &
-TrigConf::L1ThrExtraInfo_MU::exlusionList(const std::string & listName) const
+TrigConf::L1ThrExtraInfo_MU::exclusionList(const std::string & listName) const
 {
    try {
       return m_roiExclusionLists.at(listName);
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1Threshold.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1Threshold.cxx
index 070e107bae45056866553c2edb5e34d8182269d0..f2846b3496a170f6b51eb7f7da73a778c66842b0 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1Threshold.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1Threshold.cxx
@@ -62,6 +62,47 @@ TrigConf::L1Threshold_TAU::load()
    }
 }
 
+/**
+ * JET
+ */
+void
+TrigConf::L1Threshold_JET::load()
+{
+   // allowed values for eta-range boundaries are 0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.9, 2.1, 2.3, 2.5, 2.8, 3.1, 4.9 and their negatives
+
+   static const std::vector<int> allowedBoundaries{0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 28, 31, 49};
+   if( const auto & thrVs = data().get_child_optional("thrValues") ) {
+      for( auto & x : thrVs.get() ) {
+         auto etamin = x.second.get_child("etamin").get_value<int>();
+         if(std::find(begin(allowedBoundaries), end(allowedBoundaries), abs(etamin)) == allowedBoundaries.end()) {
+            throw std::runtime_error(name() + ": etamin value " + std::to_string(etamin) + " not an allowed value for legacy JETs");
+         }
+         auto etamax = x.second.get_child("etamax").get_value<int>();
+         if(std::find(begin(allowedBoundaries), end(allowedBoundaries), abs(etamax)) == allowedBoundaries.end()) {
+            throw std::runtime_error(name() + ": etamax value " + std::to_string(etamax) + " not an allowed value for legacy JETs");
+         }
+         auto priority = x.second.get_child("priority").get_value<unsigned int>();
+         auto window = x.second.get_child("window").get_value<unsigned int>();
+         m_etaDepWindow.addRangeValue(window, etamin, etamax, priority, /*symmetric=*/ false);
+      }
+   }
+}
+unsigned int
+TrigConf::L1Threshold_JET::window(int eta) const {
+   return m_etaDepWindow.at(eta);
+}
+
+/**
+ * ZB
+ */
+void
+TrigConf::L1Threshold_ZB::load()
+{
+   m_seed = getAttribute("seed");
+   m_seedBcdelay = getAttribute<unsigned int>("seedBcdelay");
+   m_seedMultiplicity = getAttribute<unsigned int>("seedMultiplicity");
+}
+
 /******************************************
  *
  *  New L1Calo thresholds
@@ -74,19 +115,19 @@ TrigConf::L1Threshold_TAU::load()
 void
 TrigConf::L1Threshold_eEM::load()
 {
-   auto translate = [](const std::string &wp) { return wp=="Loose" ? Isolation::WP::LOOSE : 
-                                                ( wp=="Medium" ? Isolation::WP::MEDIUM : 
-                                                  ( wp=="Tight" ? Isolation::WP::TIGHT : Isolation::WP::NONE ) ); };
    // read the isolation requirements
-   m_reta = translate(getAttribute("reta"));
-   m_rhad = translate(getAttribute("rhad"));
-   m_wstot = translate(getAttribute("wstot"));
+   m_reta  = Selection::stringToWP(getAttribute("reta"));
+   m_rhad  = Selection::stringToWP(getAttribute("rhad"));
+   m_wstot = Selection::stringToWP(getAttribute("wstot"));
 }
 
 void
 TrigConf::L1Threshold_eTAU::load()
 {}
 
+void
+TrigConf::L1Threshold_jJ::load()
+{}
 
 /******************************************
  *
@@ -116,7 +157,7 @@ TrigConf::L1Threshold_MU::load()
    m_idxForward = muInfo->tgcIdxForPt(m_ptForward);
 
    m_rpcExclROIList = getAttribute("rpcExclROIList", true, "");
-   m_tgcFlag = getAttribute("tgcFlags");
+   m_tgcFlags = getAttribute("tgcFlags");
    m_region = getAttribute("region");
 }
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1ThresholdBase.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1ThresholdBase.cxx
index d279f1c7d894aac9d5a7167dab72036657770bff..d88335f97986db6f0d46c8a78eee2ddf79b375c2 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1ThresholdBase.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1ThresholdBase.cxx
@@ -2,6 +2,7 @@
 
 #include <algorithm>
 #include <cmath>
+#include <limits>
 
 
 #include "TrigConfData/L1ThresholdBase.h"
@@ -51,9 +52,15 @@ TrigConf::L1Threshold::createThreshold( const std::string & name, const std::str
    if( type == "eTAU" )
       return std::make_shared<L1Threshold_eTAU>( name, type, extraInfo, data );
 
+   if( type == "jJ" )
+      return std::make_shared<L1Threshold_jJ>( name, type, extraInfo, data );
+
    if( type == "MU" )
       return std::make_shared<L1Threshold_MU>( name, type, extraInfo, data );
 
+   if( type == "ZB" )
+      return std::make_shared<L1Threshold_ZB>( name, type, extraInfo, data );
+
    static const std::string NIMtypes[] = { "BCM", "BCMCMB", "LUCID", "ZDC", "BPTX", "CALREQ", "MBTS", "MBTSSI", "NIM" };
    bool isNIMtype = std::find(std::begin(NIMtypes), std::end(NIMtypes), type) !=
      std::end(NIMtypes);
@@ -64,7 +71,14 @@ TrigConf::L1Threshold::createThreshold( const std::string & name, const std::str
    if( type == "internal" )
       return std::make_shared<L1Threshold_internal>( name, type, extraInfo, data );
 
-   static const std::string noSpecialImp[] = { "JET", "XS", "jJ", "gXE", "jXE", "TOPO", "MULTTOPO", "MUTOPO", "R2TOPO", "ZB", "ALFA" };
+   static const std::string caloBaseImp[] = { "gXE", "jXE" };
+   bool useCaloBaseClass = std::find(std::begin(caloBaseImp), std::end(caloBaseImp),type) !=
+     std::end(caloBaseImp);
+
+   if( useCaloBaseClass )
+      return std::make_shared<L1Threshold_Calo>( name, type, extraInfo, data );
+
+   static const std::string noSpecialImp[] = { "JET", "XS", "TOPO", "MULTTOPO", "MUTOPO", "R2TOPO", "ALFA" };
    bool useBaseClass = std::find(std::begin(noSpecialImp), std::end(noSpecialImp),type) !=
      std::end(noSpecialImp);
 
@@ -121,9 +135,9 @@ TrigConf::L1ThrExtraInfoBase::load()
    if(! isInitialized() || empty() )
       return;
 
-   if( m_name == "internal" ) { // internal trigger have no extra info
-      return;
-   }
+   // if( m_name == "internal" ) { // internal trigger have no extra info
+   //    return;
+   // }
    for( auto & content : data() ) {
       if( content.first == "type" ||
           content.first == "thresholds" ) {
@@ -157,6 +171,12 @@ TrigConf::L1ThrExtraInfoBase::hasExtraInfo(const std::string & key) const
    return m_extraInfo.count(key)>0;
 }
 
+std::optional<std::reference_wrapper<const TrigConf::DataStructure>>
+TrigConf::L1ThrExtraInfoBase::getExtraInfo( const std::string & key) const
+{
+   bool hasKey = m_extraInfo.count(key)>0;
+   return hasKey ? std::optional<std::reference_wrapper<const TrigConf::DataStructure>>{m_extraInfo.at(key)} : std::nullopt;
+}
 
 
 
@@ -210,6 +230,14 @@ TrigConf::L1Threshold_Calo::load()
          m_etaDepThrValue.addRangeValue(value, etamin, etamax, priority, /*symmetric=*/ false);
       }
    }
+   if( const auto & ranges = data().get_child_optional("ranges") ) {
+      m_etaDepThrValue.setOutsideRangeValue(getAttribute("maxValue", true, std::numeric_limits<unsigned int>::max()));
+      for( auto & x : ranges.get() ) {
+         auto etamin = x.second.get_child("etamin").get_value<unsigned int>();
+         auto etamax = x.second.get_child("etamax").get_value<unsigned int>();
+         m_etaDepThrValue.addRangeValue(m_thrValue, etamin, etamax, /*priority=*/ 1, /*symmetric=*/ false);
+      }
+   }
 }
 
 /*
@@ -257,9 +285,6 @@ TrigConf::L1Threshold_Calo::thrValuesCounts() const {
    return thrValuesCounts;
 }
 
-
-
-
 TrigConf::IsolationLegacy::IsolationLegacy( const boost::property_tree::ptree & pt ) {
    m_isDefined = true;
    m_isobit = pt.get_child("isobit").get_value<int>();
@@ -280,16 +305,30 @@ TrigConf::operator<<(std::ostream & os, const TrigConf::IsolationLegacy & iso) {
    return os;
 }
 
-TrigConf::Isolation::Isolation( const boost::property_tree::ptree & pt ) {
-   m_isDefined = true;
-   m_reta = pt.get_child("reta").get_value<int>();
-   m_wstot = pt.get_child("wstot").get_value<int>();
-   m_had = pt.get_child("had").get_value<int>();
+std::string
+TrigConf::Selection::wpToString(TrigConf::Selection::WP wp)
+{
+   if (wp == Selection::WP::NONE)
+      return "None";
+   if (wp == Selection::WP::LOOSE)
+      return "Loose";
+   if (wp == Selection::WP::MEDIUM)
+      return "Medium";
+   if (wp == Selection::WP::TIGHT)
+      return "Tight";
+   throw std::runtime_error("Unknown working point " + std::to_string(int(wp)));
 }
 
-std::ostream &
-TrigConf::operator<<(std::ostream & os, const TrigConf::Isolation & iso) {
-   os << "reta=" << iso.reta() << ", wstot=" << iso.wstot() << ", had=" << iso.had();
-   return os;
+TrigConf::Selection::WP
+TrigConf::Selection::stringToWP(const std::string & wpStr)
+{
+   if (wpStr == "None")
+      return Selection::WP::NONE;
+   if (wpStr == "Loose")
+      return Selection::WP::LOOSE;
+   if (wpStr == "Medium")
+      return Selection::WP::MEDIUM;
+   if (wpStr == "Tight")
+      return Selection::WP::TIGHT;
+   throw std::runtime_error("Unknown working point name " + wpStr);
 }
-
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1TopoAlgorithm.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1TopoAlgorithm.cxx
index 08ad0c1fed737772e9d85531061b48c62dbaf502..ed6842cb36520008bcb2c9e2824301890a4b1e88 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1TopoAlgorithm.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1TopoAlgorithm.cxx
@@ -14,7 +14,7 @@ TrigConf::L1TopoAlgorithm::L1TopoAlgorithm(const std::string & algoName, Algorit
       throw std::runtime_error("Algorithm category must be TOPO, R2TOPO, MUTOPO or MULTTOPO, but is '" + algoCategory + "'");
    }
    m_name = algoName;
-   update();
+   load();
 }
 
 TrigConf::L1TopoAlgorithm::~L1TopoAlgorithm()
@@ -26,7 +26,7 @@ TrigConf::L1TopoAlgorithm::className() const {
 }
 
 void
-TrigConf::L1TopoAlgorithm::update()
+TrigConf::L1TopoAlgorithm::load()
 {
    if(! isInitialized() || empty() ) {
       return;
@@ -45,7 +45,9 @@ TrigConf::L1TopoAlgorithm::update()
          m_outputs.push_back(o.getValue());
       }
    } else if( m_type == AlgorithmType::MULTIPLICITY ) { // MULTIPLICITY algo
-      m_inputs.push_back(getAttribute("input"));
+      if(auto & input = getAttribute("input"); input!="null") {
+         m_inputs.push_back(input);
+      }
       m_outputs.push_back(getAttribute("output"));
    } else { // SORTING algo
       if( hasAttribute("input") ) {
@@ -62,7 +64,7 @@ TrigConf::L1TopoAlgorithm::update()
 
    if( m_type == AlgorithmType::DECISION || m_type == AlgorithmType::SORTING ) {
       for( auto & p : getList("variableParameters") ) {
-         m_parameters.emplace_back(p["name"], p.getAttribute<int>("value"), p.getAttribute<unsigned int>("selection", /*ignore-if-missing*/true, 0));
+         m_parameters.emplace_back(p["name"], p.getAttribute<int>("value"), p.getAttribute_optional<unsigned int>("selection"));
       }
    }
 
@@ -166,7 +168,7 @@ TrigConf::L1TopoAlgorithm::print(std::ostream & os) const
       auto pars = parameters();
       unsigned int idx{0};
       for( auto & p : pars ) {
-         os << "    " << idx++ << "  " << p.name << "[" << p.selection << "]  ==>  " <<  p.value << std::endl;
+         os << "    " << idx++ << "  " << p.name() << "[" << p.selection() << "]  ==>  " <<  p.value() << std::endl;
       }
    }
    os << std::endl;
diff --git a/Trigger/TrigConfiguration/TrigConfIO/CMakeLists.txt b/Trigger/TrigConfiguration/TrigConfIO/CMakeLists.txt
index f384ed7f3dadfc79ed974139a3c7100191ac7aaa..e8bf3c027ef8c03bd1b93f280b49decac76e53c6 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/CMakeLists.txt
+++ b/Trigger/TrigConfiguration/TrigConfIO/CMakeLists.txt
@@ -5,6 +5,7 @@ atlas_subdir( TrigConfIO )
 
 # External dependencies:
 find_package( Boost )
+find_package( nlohmann_json )
 find_package( CORAL COMPONENTS CoralBase CoralKernel RelationalAccess )
 
 # Component(s) in the package:
@@ -14,7 +15,7 @@ atlas_add_library( TrigConfIO
   INCLUDE_DIRS ${Boost_INCLUDE_DIRS}
   PRIVATE_INCLUDE_DIRS ${CORAL_INCLUDE_DIRS}
   LINK_LIBRARIES TrigConfData TrigConfBase
-  PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES} ${CORAL_LIBRARIES} -lstdc++fs
+  PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES} ${CORAL_LIBRARIES} nlohmann_json::nlohmann_json -lstdc++fs
   )
 
 atlas_add_library( TrigConfIOSA
@@ -24,7 +25,7 @@ atlas_add_library( TrigConfIOSA
   PRIVATE_INCLUDE_DIRS ${CORAL_INCLUDE_DIRS}
   LINK_LIBRARIES TrigConfDataSA TrigConfBase
   DEFINITIONS -DTRIGCONF_STANDALONE
-  PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES} ${CORAL_LIBRARIES} -lstdc++fs
+  PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES} ${CORAL_LIBRARIES} nlohmann_json::nlohmann_json -lstdc++fs
   )
 
 atlas_add_executable( TestTriggerMenuAccess utils/TestTriggerMenuAccess.cxx 
diff --git a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/JsonFileWriter.h b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/JsonFileWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..c62892c45e5af9f8b8f19601ab8a1376d51fc61e
--- /dev/null
+++ b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/JsonFileWriter.h
@@ -0,0 +1,31 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @brief Write Json file from L1Menu object
+ * To validate correct loading of the L1 menu
+ */
+
+#ifndef TRIGCONFSTORAGE_JSONFILEWRITER_H
+#define TRIGCONFSTORAGE_JSONFILEWRITER_H
+
+#include "TrigConfBase/TrigConfMessaging.h"
+#include "TrigConfData/L1Menu.h"
+
+namespace TrigConf {
+
+   /**
+    * @brief Loader of trigger configurations from Json files
+    */
+   class JsonFileWriter : public TrigConfMessaging {
+   public:
+
+      /** Constructor */
+      JsonFileWriter();
+
+      bool writeJsonFile(const std::string & filename, const L1Menu & l1menu) const;
+   };
+
+}
+#endif
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..870de3386f59f50ae9029251a92ddc8ff0abe2d2
--- /dev/null
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx
@@ -0,0 +1,493 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TrigConfIO/JsonFileWriter.h"
+
+#include <iomanip>
+#include <fstream>
+#include <algorithm>
+
+#include <nlohmann/json.hpp>
+using json = nlohmann::json;
+
+using namespace std;
+
+TrigConf::JsonFileWriter::JsonFileWriter() : 
+   TrigConfMessaging( "JsonFileWriter")
+{}
+
+
+bool
+TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Menu & l1menu) const
+{
+
+   json items({});
+   for( auto & item : l1menu ) {
+      json jItem({});
+      jItem["name"] = item.name();
+      jItem["ctpid"] = item.ctpId();
+      jItem["definition"] = item.definition();
+      jItem["monitor"] = item.monitor();
+      jItem["partition"] = item.partition();
+      jItem["triggerType"] = item.triggerType();
+      jItem["bunchgroups"] = json(item.bunchgroups());
+      if(auto legacy = item.legacy() )
+         jItem["legacy"] = *legacy;
+      items[item.name()] = jItem;
+   };
+ 
+   json thresholds({});
+   for(const std::string & thrType : l1menu.thresholdTypes()) {
+      json jThresholsByType({});
+      // first the thresholds of this type
+      for(auto & thr : l1menu.thresholds(thrType)) {
+         json jThr({});
+         jThr["mapping"] = thr->mapping();
+
+         if(thr->hasChild("sectors")) { // for MBTS_A and MBTS_C
+            std::vector<std::string> sectors; 
+            for(auto & s : thr->getList("sectors")) {
+               sectors.push_back(s.getValue());
+            }
+            jThr["sectors"] = sectors;
+         } 
+         if(thr->hasAttribute("voltage")) { // for MBTSII
+            jThr["voltage"] = thr->getAttribute<float>("voltage");
+         }
+
+         try {
+            if(thr->hasAttribute("value")) {
+               auto & caloThr = dynamic_cast<const TrigConf::L1Threshold_Calo &>(*thr); // for MBTSII
+               jThr["value"] = int(caloThr.thrValue());
+            }
+         } catch(std::bad_cast&) {};
+
+         try {
+            auto muThr = dynamic_cast<const TrigConf::L1Threshold_MU &>(*thr);
+            jThr["baThr"] = muThr.ptBarrel();
+            jThr["ecThr"] = muThr.ptEndcap();
+            jThr["fwThr"] = muThr.ptForward(); 
+            jThr["baIdx"] = muThr.idxBarrel();
+            jThr["ecIdx"] = muThr.idxEndcap();
+            jThr["fwIdx"] = muThr.idxForward();
+            jThr["region"] = muThr.region();
+            jThr["tgcFlags"] = muThr.tgcFlags();
+            if(const std::string & roiExcl = muThr.rpcExclROIList(); !roiExcl.empty()) {
+               jThr["rpcExclROIList"] = roiExcl;
+            }
+         } catch(std::bad_cast&) {};
+
+         try {
+            auto tauThr = dynamic_cast<const TrigConf::L1Threshold_TAU &>(*thr);
+            std::string isobits = "00000";
+            auto isomask = tauThr.isolationMask();
+            for(size_t b=0; b<5; ++b) {
+               if(isomask & (1<<b)) { isobits[4-b] = '1'; }
+            }
+            jThr["isobits"] = isobits;
+         } catch(std::bad_cast&) {};
+
+         try {
+            auto EMThr = dynamic_cast<const TrigConf::L1Threshold_EM &>(*thr);
+            jThr["thrValues"] = json::array_t({});
+            for(auto & rv : EMThr.thrValues()) {
+               json jRV({});
+               jRV["etamin"] = rv.etaMin();
+               jRV["etamax"] = rv.etaMax();
+               jRV["phimin"] = 0; // never used, so not read 
+               jRV["phimax"] = 64; // never used, so not read
+               std::string isobits = "00000";
+               auto isomask = EMThr.isolationMask(rv.etaMin());
+               for(size_t b=0; b<5; ++b) {
+                  if(isomask & (1<<b)) { isobits[4-b] = '1'; }
+               }
+               jRV["isobits"] = isobits;
+               jRV["priority"] = rv.priority();
+               jRV["value"] = (unsigned int)rv.value();
+               jThr["thrValues"] += jRV;
+            }
+         } catch(std::bad_cast&) {};
+
+         try {
+            auto JThr = dynamic_cast<const TrigConf::L1Threshold_JET &>(*thr);
+            jThr["thrValues"] = json::array_t({});
+            for(auto & rv : JThr.thrValues()) {
+               json jRV({});
+               jRV["etamin"] = rv.etaMin();
+               jRV["etamax"] = rv.etaMax();
+               jRV["phimin"] = 0; // never used, so not read 
+               jRV["phimax"] = 64; // never used, so not read
+               jRV["priority"] = rv.priority();
+               jRV["window"] = JThr.window(0);
+               jRV["value"] = (unsigned int)rv.value();
+               jThr["thrValues"] += jRV;
+            }
+         } catch(std::bad_cast&) {};
+
+         try {
+            auto teThr = dynamic_cast<const TrigConf::L1Threshold_TE &>(*thr);
+            //jThr["thrValues"] = json::array_t({});
+            for(auto & rv : teThr.thrValues()) {
+               json jRV({});
+               jRV["etamin"] = rv.etaMin();
+               jRV["etamax"] = rv.etaMax();
+               jRV["priority"] = rv.priority();
+               jRV["value"] = (unsigned int)rv.value();
+               jThr["thrValues"] += jRV;
+            }
+         } catch(std::bad_cast&) {};
+
+         try {
+            auto zbThr = dynamic_cast<const TrigConf::L1Threshold_ZB &>(*thr);
+            jThr["seed"] = zbThr.seed();
+            jThr["seedBcdelay"] = zbThr.seedBcdelay();
+            jThr["seedMultiplicity"] = zbThr.seedMultiplicity();
+         } catch(std::bad_cast&) {};
+
+
+         try {
+            auto eEMThr = dynamic_cast<const TrigConf::L1Threshold_eEM &>(*thr);
+            jThr["reta"] = TrigConf::Selection::wpToString(eEMThr.reta());
+            jThr["rhad"] = TrigConf::Selection::wpToString(eEMThr.rhad());
+            jThr["wstot"] = TrigConf::Selection::wpToString(eEMThr.wstot());
+            jThr["thrValues"] = json::array_t({});
+            for(auto & rv : eEMThr.thrValues()) {
+               json jRV({});
+               jRV["etamin"] = rv.etaMin();
+               jRV["etamax"] = rv.etaMax();
+               jRV["priority"] = rv.priority();
+               jRV["value"] = (unsigned int)rv.value();
+               jThr["thrValues"] += jRV;
+            }
+         } catch(std::bad_cast&) {};
+
+         try {
+            auto jJThr = dynamic_cast<const TrigConf::L1Threshold_jJ &>(*thr);
+            jThr["ranges"] = json::array_t({});
+            for(auto & rv : jJThr.thrValues()) {
+               json jRV({});
+               jRV["etamin"] = rv.etaMin();
+               jRV["etamax"] = rv.etaMax();
+               jThr["ranges"] += jRV;
+               jThr["value"] = int(jJThr.thrValue(rv.etaMin()));
+            }
+         } catch(std::bad_cast&) {};
+
+         jThresholsByType[thr->name()] = jThr;
+      };
+      json jThrType({});
+      if(thrType != "internal") {
+         jThrType["thresholds"] = jThresholsByType;
+      }
+      jThrType["type"] = thrType;
+
+      // extra info 
+      auto & extraInfo = l1menu.thrExtraInfo().thrExtraInfo(thrType);
+      if(extraInfo.hasAttribute("ptMinToTopo")) { // for MBTSII
+         jThrType["ptMinToTopo"] = extraInfo.getAttribute<unsigned int>("ptMinToTopo");
+      }
+      if(extraInfo.hasAttribute("resolutionMeV")) { // for MBTSII
+         jThrType["resolutionMeV"] = extraInfo.getAttribute<unsigned int>("resolutionMeV");
+      }
+
+      // extra info using type specific accessors
+      if(thrType == "internal") {
+         jThrType["names"] = json::array_t({});
+         for(auto & thr : l1menu.thresholds(thrType)) {
+            jThrType["names"] += thr->name();
+         }
+         auto & extInfo = l1menu.thrExtraInfo().thrExtraInfo("internal");
+         if(auto randoms = extInfo.getExtraInfo("randoms")) {
+            for(size_t rc=0; rc<4; ++rc) {
+               jThrType["randoms"]["RNDM" + std::to_string(rc)]["cut"] = 
+                  randoms->get().getAttribute<unsigned int>("RNDM" + std::to_string(rc)+".cut");
+            }
+         }
+      }
+
+      if(thrType == "MU") {
+         auto & muinfo = l1menu.thrExtraInfo().MU();
+         for(auto & listName : muinfo.exclusionListNames()) {
+            jThrType["exclusionLists"][listName] = json::array_t({});
+            for(auto & x : muinfo.exclusionList(listName)) {
+               jThrType["exclusionLists"][listName] += json({ {"sectorName", x.first}, {"rois", x.second}});
+            }
+         }
+         for(auto & rpcPt : muinfo.knownRpcPtValues()) {
+            jThrType["roads"]["rpc"][std::to_string(rpcPt)] = muinfo.rpcIdxForPt(rpcPt);
+         }
+         for(auto & tgcPt : muinfo.knownTgcPtValues()) {
+            jThrType["roads"]["tgc"][std::to_string(tgcPt)] = muinfo.tgcIdxForPt(tgcPt);
+         }
+      }
+
+      if(thrType == "EM") {
+         auto & eminfo = l1menu.thrExtraInfo().EM();
+         for(const std::string & isoSet : { "EMIsoForEMthr", "HAIsoForEMthr" }) {
+            jThrType["isolation"][isoSet]["thrtype"] = isoSet;
+            jThrType["isolation"][isoSet]["Parametrization"] = json::array_t({});
+            for(size_t bit = 1; bit<=5; ++bit) {
+               auto & iso = eminfo.isolation(isoSet,bit);
+               json jIso({});
+               jIso["etamax"] = iso.etamax();
+               jIso["etamin"] = iso.etamin();
+               jIso["isobit"] = iso.isobit();
+               jIso["mincut"] = iso.mincut();
+               jIso["offset"] = iso.offset();
+               jIso["priority"] = iso.priority();
+               jIso["slope"] = iso.slope();
+               jIso["upperlimit"] = iso.upperlimit();
+               jThrType["isolation"][isoSet]["Parametrization"] += jIso;
+            }
+         }
+      }
+
+      if(thrType == "TAU") {
+         auto & tauinfo = l1menu.thrExtraInfo().TAU();
+         const std::string isoSet{ "EMIsoForTAUthr" };
+         jThrType["isolation"][isoSet]["thrtype"] = isoSet;
+         jThrType["isolation"][isoSet]["Parametrization"] = json::array_t({});
+         for(size_t bit = 1; bit<=5; ++bit) {
+            auto & iso = tauinfo.isolation(isoSet,bit);
+            json jIso({});
+            jIso["etamax"] = iso.etamax();
+            jIso["etamin"] = iso.etamin();
+            jIso["isobit"] = iso.isobit();
+            jIso["mincut"] = iso.mincut();
+            jIso["offset"] = iso.offset();
+            jIso["priority"] = iso.priority();
+            jIso["slope"] = iso.slope();
+            jIso["upperlimit"] = iso.upperlimit();
+            jThrType["isolation"][isoSet]["Parametrization"] += jIso;
+         }
+      }
+
+      if(thrType == "JET") {
+         auto & jetinfo = l1menu.thrExtraInfo().JET();
+         jThrType["ptMinToTopoSmallWindow"] = (int)jetinfo.ptMinToTopoSmallWindow();
+         jThrType["ptMinToTopoLargeWindow"] = (int)jetinfo.ptMinToTopoLargeWindow();
+      }
+
+      if(thrType == "XS") {
+         auto & xsinfo = l1menu.thrExtraInfo().XS();
+         jThrType["significance"]["xeMin"] = xsinfo.xeMin();
+         jThrType["significance"]["xeMax"] = xsinfo.xeMax();
+         jThrType["significance"]["teSqrtMin"] = xsinfo.teSqrtMin();
+         jThrType["significance"]["teSqrtMax"] = xsinfo.teSqrtMax();
+         jThrType["significance"]["xsSigmaScale"] = xsinfo.xsSigmaScale();
+         jThrType["significance"]["xsSigmaOffset"] = xsinfo.xsSigmaOffset();
+      }
+
+      if(thrType == "eEM") {
+         auto & eeminfo = l1menu.thrExtraInfo().eEM();
+         for( auto wp : {TrigConf::Selection::WP::LOOSE, TrigConf::Selection::WP::MEDIUM, TrigConf::Selection::WP::TIGHT} ) {
+            auto wpstr = TrigConf::Selection::wpToString(wp);
+            jThrType["workingPoints"][wpstr] = json::array_t({});
+            for(auto & iso : eeminfo.isolation(wp)) {
+               json jWPIso({});
+               jWPIso["reta"] = iso.value().reta_d();
+               jWPIso["rhad"] = iso.value().rhad_d();
+               jWPIso["wstot"] = iso.value().wstot_d();
+               jWPIso["maxEt"] = iso.value().maxEt();
+               jThrType["workingPoints"][wpstr] += jWPIso;
+            }
+         }
+      }
+
+      if(thrType == "eTAU") {
+         auto & eeminfo = l1menu.thrExtraInfo().eTAU();
+         for( auto wp : {TrigConf::Selection::WP::LOOSE, TrigConf::Selection::WP::MEDIUM, TrigConf::Selection::WP::TIGHT} ) {
+            auto wpstr = TrigConf::Selection::wpToString(wp);
+            jThrType["workingPoints"][wpstr] = json::array_t({});
+            for(auto & iso : eeminfo.isolation(wp)) {
+               json jWPIso({});
+               jWPIso["isolation"] = (int)iso.value().isolation_d();
+               jWPIso["maxEt"] = iso.value().maxEt();
+               jThrType["workingPoints"][wpstr] += jWPIso;
+            }
+         }
+      }
+
+      if(thrType == "jJ") {
+         auto & ei = l1menu.thrExtraInfo().jJ();
+         jThrType["ptMinToTopo"] = json::array_t({});
+         for(auto & x : ei.ptMinToTopoMeV() ) {
+            jThrType["ptMinToTopo"] += json({
+                  {"etamin",x.etaMin()},
+                  {"etamax",x.etaMax()},
+                  {"small",int(x.value().first/1000.)},
+                  {"large",int(x.value().second/1000.)}
+               });
+         }
+      }
+
+      std::vector<std::string> legacyCalo = {"EM", "JET", "TAU", "XE", "TE", "XS", "ZB", "R2TOPO"};
+      if( std::any_of(begin(legacyCalo), end(legacyCalo), [&thrType](const std::string &c) { return c==thrType; }) ) {
+         thresholds["legacyCalo"][thrType] = jThrType;
+      } else {
+         thresholds[thrType] = jThrType;
+      }
+   };
+
+
+   json boards{};
+   for( auto & bname : l1menu.boardNames() ) {
+      auto & bdef = l1menu.board(bname);
+      boards[bname] = json{ {"connectors", bdef.connectorNames()}, {"type", bdef.type()} };
+      if(bdef.legacy())
+         boards[bname]["legacy"] = true;
+   };
+
+
+   json connectors{};
+   for( auto & cname : l1menu.connectorNames() ) {
+      auto jConn = json{};
+      auto & cdef = l1menu.connector(cname);
+      jConn["type"] = cdef.type();
+      if(cdef.legacy())
+         jConn["legacy"] = true;
+      if(cdef.maxFpga() == 2) {
+         for(size_t fpga = 0; fpga<2; ++fpga) {
+            std::string fName = "fpga" + std::to_string(fpga);
+            for(size_t clock = 0; clock<2; ++clock) {
+               std::string cName = "clock" + std::to_string(clock);
+               jConn["triggerlines"][fName][cName] = json::array_t();
+               for(auto & tl : cdef.triggerLines(fpga, clock)) {
+                  jConn["triggerlines"][fName][cName] += json({ {"name", tl.name()}, {"nbits",tl.nbits()}, {"startbit", tl.startbit()} });
+               }
+            }
+         }
+      } else {
+         if(cdef.maxClock() == 2) {
+            // merger boards
+            for(size_t clock = 0; clock<cdef.maxClock(); ++clock) {
+               std::string cName = "clock" + std::to_string(clock);
+               jConn["triggerlines"][cName] = json::array_t();
+               for(auto & tl : cdef.triggerLines(0, clock)) {
+                  jConn["triggerlines"][cName] += json({ {"name", tl.name()}, {"nbits",tl.nbits()}, {"startbit", tl.startbit()} });
+               }
+            }            
+         } else {
+            jConn["triggerlines"] = json::array_t();
+            for(auto & tl : cdef.triggerLines()) {
+               jConn["triggerlines"] += json({ {"name", tl.name()}, {"nbits",tl.nbits()}, {"startbit", tl.startbit()} });
+            }
+         }
+      }
+      connectors[cname] = jConn;
+   }
+
+   json ctp({});
+   {
+      for(size_t slot=7; slot<=9; ++slot) {
+         std::string sName = "slot" + std::to_string(slot);
+         ctp["inputs"]["ctpin"][sName] = json({});
+         for(size_t conn=0; conn<=3; ++conn) {
+            ctp["inputs"]["ctpin"][sName]["connector" + std::to_string(conn)] = l1menu.ctp().ctpin(slot,conn);
+         }
+      }
+      for(size_t conn=0; conn<3; ++conn) {
+         if(l1menu.ctp().electrical(conn)=="")
+            continue;
+         ctp["inputs"]["electrical"]["connector" + std::to_string(conn)] = l1menu.ctp().electrical(conn);
+      }
+      for(size_t conn=0; conn<12; ++conn) {
+         if(l1menu.ctp().optical(conn)=="")
+            continue;
+         ctp["inputs"]["optical"]["connector" + std::to_string(conn)] = l1menu.ctp().optical(conn);
+      }
+      auto ctpmon = json({});
+      for(auto & mon : l1menu.ctp().ctpMon()) {
+         ctpmon[mon.first] = json({{"multiplicity",mon.second.first},{"thr",mon.second.second}});
+      }
+      ctp["monitoring"] = json({{"ctpmon",ctpmon}});
+   }
+
+   json jtopo({});
+   {
+      std::map<L1TopoAlgorithm::AlgorithmType,std::string> algTypeNames = {
+         {L1TopoAlgorithm::AlgorithmType::SORTING, "sortingAlgorithms"},
+         {L1TopoAlgorithm::AlgorithmType::DECISION, "decisionAlgorithms"},
+         {L1TopoAlgorithm::AlgorithmType::MULTIPLICITY, "multiplicityAlgorithms"}
+      };
+
+      for( const std::string & topoCat : {"TOPO", "MUTOPO", "MULTTOPO", "R2TOPO"} ) {
+         for(auto & algName : l1menu.topoAlgorithmNames(topoCat)) {
+            json jalg = json::object_t({});
+            auto & alg = l1menu.algorithm(algName,topoCat);
+            jalg["algId"]     = alg.algId();
+            jalg["klass"]     = alg.klass();
+            // input
+            if(alg.type()==L1TopoAlgorithm::AlgorithmType::MULTIPLICITY) {
+               if(alg.inputs().size()>0) {
+                  jalg["input"] = alg.inputs()[0];
+               } else {
+                  jalg["input"] = nullptr;
+               }
+            } else if(alg.type()==L1TopoAlgorithm::AlgorithmType::SORTING) {
+               jalg["input"] = alg.inputs()[0];
+            } else {
+               jalg["input"] = alg.inputs();
+            }
+            // output
+            if( alg.type() == L1TopoAlgorithm::AlgorithmType::DECISION ) {
+               jalg["output"] = alg.outputs();
+            } else {
+               jalg["output"] = alg.outputs()[0];
+            }
+            // generic parameters
+            if(topoCat == "MULTTOPO") {
+               jalg["nbits"] = alg.getAttribute<unsigned int>("nbits");
+               jalg["threshold"] = alg.getAttribute("threshold");
+            } else {
+               auto ds = alg.generics();
+               for(auto & gpname : ds.getKeys()) {
+                  auto gp = ds.getObject(gpname);
+                  {
+                     if(gp.hasAttribute("position")) {
+                        jalg["fixedParameters"]["generics"][gpname]["position"] = gp.getAttribute<unsigned int>("position");
+                     }
+                     std::string pval = alg.genericParameter(gpname);
+                     try{
+                        int pvali = std::stoi(pval);
+                        jalg["fixedParameters"]["generics"][gpname]["value"] = pvali;
+                     } catch(std::invalid_argument &) {
+                        jalg["fixedParameters"]["generics"][gpname]["value"] = pval;
+                     }
+                  }
+               }
+            }
+            // variable parameters
+            if(topoCat != "MULTTOPO") {
+               jalg["variableParameters"] = json::array_t({});
+               for(const L1TopoAlgorithm::VariableParameter & vpar : alg.parameters()) {
+                  json jVPar({});
+                  jVPar["name"] = vpar.name();
+                  jVPar["value"] = vpar.value();
+                  if(auto sel = vpar.selection_optional()) { jVPar["selection"] = *sel; }
+                  jalg["variableParameters"] += jVPar;
+               }
+            }
+            jtopo[topoCat][algTypeNames[alg.type()]][algName] = jalg;
+         }
+      }
+   }
+
+   json j({});
+   j["filetype"] = "l1menu";
+   j["name"] = l1menu.name();
+   j["items"] = items;
+   j["thresholds"] = thresholds;
+   j["topoAlgorithms"] = jtopo;
+   j["boards"] = boards;
+   j["connectors"] = connectors;
+   j["ctp"] = ctp;
+
+
+   std::ofstream outfile(filename);
+   outfile << std::setw(4) << j << std::endl;
+
+   TRG_MSG_INFO("Saved file " << filename);
+   return true;
+}
diff --git a/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx b/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx
index 754fc90653503dc8e7b7d1d1e283f71e0239c3b6..0d323dcb9b47e507c3fe94129b34227b22c713e2 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx
@@ -46,9 +46,9 @@ exampleL1Calo(const string & filename) {
    for( int ieta : { -30, -20, -10, 0, 10, 20, 30 } ) {
       unsigned int ptMinToTopo = ei_eEM.ptMinToTopo(); // the minimum energy to send to topo (not eta dependent yet)
       cout << "ptmin=" << ptMinToTopo << endl;
-      auto iso_loose  = ei_eEM.isolation(TrigConf::Isolation::WP::LOOSE, ieta);
-      auto iso_medium = ei_eEM.isolation(TrigConf::Isolation::WP::MEDIUM, ieta);
-      auto iso_tight  = ei_eEM.isolation(TrigConf::Isolation::WP::TIGHT, ieta);
+      auto iso_loose  = ei_eEM.isolation(TrigConf::Selection::WP::LOOSE, ieta);
+      auto iso_medium = ei_eEM.isolation(TrigConf::Selection::WP::MEDIUM, ieta);
+      auto iso_tight  = ei_eEM.isolation(TrigConf::Selection::WP::TIGHT, ieta);
       int reta_loose = iso_loose.reta(); 
       int had_loose = iso_loose.had(); 
       int wstot_loose = iso_loose.wstot(); 
@@ -114,7 +114,7 @@ testL1Menu_Connectors(const TrigConf::L1Menu & l1menu) {
    cout << "L1 menu has " << l1menu.connectorNames().size() << " connectors configured" << endl;
    for( const string & connName : l1menu.connectorNames() ) {
       auto & conn = l1menu.connector(connName);
-      cout << "Connector " << connName << (conn.isLegacy() ? " (legacy)": "") << " has " << conn.size() << " trigger lines configured:" << endl;
+      cout << "Connector " << connName << (conn.legacy() ? " (legacy)": "") << " has " << conn.size() << " trigger lines configured:" << endl;
       if( connName == "MuCTPiOpt0" ) {
          for( auto & tl : conn.triggerLines() ) {
             cout << "   Triggerline " << tl.name() << " bits=["  << tl.startbit() << ".." << tl.endbit() << "] is a muon threshold " << endl;            
@@ -125,18 +125,18 @@ testL1Menu_Connectors(const TrigConf::L1Menu & l1menu) {
                cout << "   Triggerline " << tl.name() << " (clock " << clock << ", bit "  << tl.startbit() << ") is an ALFA threshold " << endl;
             }
          }
-      } else if( conn.type() == TrigConf::L1Connector::ConnectorType::CTPIN ) {
+      } else if( conn.connectorType() == TrigConf::L1Connector::ConnectorType::CTPIN ) {
          for( auto & tl : conn.triggerLines() ) {
             cout << "   Triggerline " << tl.name() << " bits=["  << tl.startbit() << ".." << tl.endbit() << "] is a legacy threshold " << endl;            
          }
-      } else if( conn.type() == TrigConf::L1Connector::ConnectorType::OPTICAL ) {
+      } else if( conn.connectorType() == TrigConf::L1Connector::ConnectorType::OPTICAL ) {
          for( auto & tl : conn.triggerLines() ) {
             const string & tlName = tl.name();
             auto & topoAlg = l1menu.algorithmFromTriggerline(tlName);
             cout << "   Triggerline " << tlName << " bits=["  << tl.startbit() << ".." << tl.endbit() 
                  << "] is produced by topo algorithm " << topoAlg.name() << endl;
          }
-      } else if( conn.type() == TrigConf::L1Connector::ConnectorType::ELECTRICAL ) {
+      } else if( conn.connectorType() == TrigConf::L1Connector::ConnectorType::ELECTRICAL ) {
          for( size_t fpga : { 0, 1 } ) {
             for( size_t clock : { 0, 1 } ) {
                for( auto & tl : conn.triggerLines(fpga, clock) ) {
@@ -332,25 +332,25 @@ testL1Menu_Extrainfo(const TrigConf::L1Menu & l1menu)
       cout << "    ptMinToTopo (MeV) " << ex.ptMinToTopoMeV() << endl;
       cout << "    ptMinToTopo (counts)" << ex.ptMinToTopoCounts() << endl;
       cout << "    working point Loose" << endl;
-      for(auto & iso : ex.isolation(TrigConf::Isolation::WP::LOOSE)) {
+      for(auto & iso : ex.isolation(TrigConf::Selection::WP::LOOSE)) {
          cout << "      range etaMin=" << iso.etaMin() << ", etaMax=" << iso.etaMax() 
               << ", priority=" << iso.priority() << ", symmetric=" << (iso.symmetric() ? "yes" : "no")
               << ", isolation=" << iso.value() << endl;
       }
       cout << "    working point Medium" << endl;
-      for(auto & iso : ex.isolation(TrigConf::Isolation::WP::MEDIUM)) {
+      for(auto & iso : ex.isolation(TrigConf::Selection::WP::MEDIUM)) {
          cout << "      range etaMin=" << iso.etaMin() << ", etaMax=" << iso.etaMax() 
               << ", priority=" << iso.priority() << ", symmetric=" << (iso.symmetric() ? "yes" : "no")
               << ", isolation=" << iso.value() << endl;
       }
       cout << "    working point Tight" << endl;
-      for(auto & iso : ex.isolation(TrigConf::Isolation::WP::TIGHT)) {
+      for(auto & iso : ex.isolation(TrigConf::Selection::WP::TIGHT)) {
          cout << "      range etaMin=" << iso.etaMin() << ", etaMax=" << iso.etaMax() 
               << ", priority=" << iso.priority() << ", symmetric=" << (iso.symmetric() ? "yes" : "no")
               << ", isolation=" << iso.value() << endl;
       }
-      //cout << "    working point Medium at eta = -20:" << ex.isolation(TrigConf::Isolation::WP::MEDIUM,-20) << endl;
-      cout << "    working point Medium at eta = 20:" << ex.isolation(TrigConf::Isolation::WP::MEDIUM,20) << endl;
+      //cout << "    working point Medium at eta = -20:" << ex.isolation(TrigConf::Selection::WP::MEDIUM,-20) << endl;
+      cout << "    working point Medium at eta = 20:" << ex.isolation(TrigConf::Selection::WP::MEDIUM,20) << endl;
    }
    {
       auto & ex = l1menu.thrExtraInfo().jJ();
@@ -371,22 +371,22 @@ testL1Menu_Extrainfo(const TrigConf::L1Menu & l1menu)
       cout << "    ptMinToTopo (MeV) " << ex.ptMinToTopoMeV() << endl;
       cout << "    ptMinToTopo (counts)" << ex.ptMinToTopoCounts() << endl;
       cout << "    working point Loose" << endl;
-      for(auto & iso : ex.isolation(TrigConf::Isolation::WP::LOOSE)) {
+      for(auto & iso : ex.isolation(TrigConf::Selection::WP::LOOSE)) {
          cout << "      range etaMin=" << iso.etaMin() << ", etaMax=" << iso.etaMax() 
               << ", priority=" << iso.priority() << ", symmetric=" << (iso.symmetric() ? "yes" : "no")
-              << ", isolation=" << iso.value() << endl;
+              << ", isolation=" << iso.value().isolation() << endl;
       }
       cout << "    working point Medium" << endl;
-      for(auto & iso : ex.isolation(TrigConf::Isolation::WP::MEDIUM)) {
+      for(auto & iso : ex.isolation(TrigConf::Selection::WP::MEDIUM)) {
          cout << "      range etaMin=" << iso.etaMin() << ", etaMax=" << iso.etaMax() 
               << ", priority=" << iso.priority() << ", symmetric=" << (iso.symmetric() ? "yes" : "no")
-              << ", isolation=" << iso.value() << endl;
+              << ", isolation=" << iso.value().isolation() << endl;
       }
       cout << "    working point Tight" << endl;
-      for(auto & iso : ex.isolation(TrigConf::Isolation::WP::TIGHT)) {
+      for(auto & iso : ex.isolation(TrigConf::Selection::WP::TIGHT)) {
          cout << "      range etaMin=" << iso.etaMin() << ", etaMax=" << iso.etaMax() 
               << ", priority=" << iso.priority() << ", symmetric=" << (iso.symmetric() ? "yes" : "no")
-              << ", isolation=" << iso.value() << endl;
+              << ", isolation=" << iso.value().isolation() << endl;
       }
    }
 
@@ -399,7 +399,7 @@ testL1Menu_Extrainfo(const TrigConf::L1Menu & l1menu)
    cout << endl;
    if( const auto & list = exMU.exclusionListNames(); std::find(list.begin(), list.end(), "rpcFeet")!=list.end() ) {
       cout << "    exclusionList 'rpcFeet'" << endl;
-      for(auto & x : exMU.exlusionList("rpcFeet")) {
+      for(auto & x : exMU.exclusionList("rpcFeet")) {
          cout << "     sector " << x.first << ": ";
          for( auto roi : x.second ) cout << roi << " ";
          cout << endl;
diff --git a/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx b/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx
index e8eca7e0ef0c2f7f22bc4366b69dd39e528527b7..c4eb23b808104d25d50dbd88c86baeec17456ac2 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx
@@ -6,6 +6,7 @@
 #include <vector>
 
 #include "TrigConfIO/JsonFileLoader.h"
+#include "TrigConfIO/JsonFileWriter.h"
 #include "TrigConfIO/TrigDBMenuLoader.h"
 #include "TrigConfIO/TrigDBJobOptionsLoader.h"
 #include "TrigConfIO/TrigDBL1PrescalesSetLoader.h"
@@ -24,7 +25,7 @@ public:
    ~Config(){}
    Config(){}
 
-   std::vector<std::string> knownParameters { "file", "f", "smk", "l1psk", "hltpsk", "bgsk", "db", "write", "w", "help", "h", "detail", "d" };
+   std::vector<std::string> knownParameters { "file", "f", "smk", "l1psk", "hltpsk", "bgsk", "db", "write", "w", "Write", "W", "help", "h", "detail", "d" };
 
    // parameters
    // input
@@ -37,6 +38,7 @@ public:
 
    // output
    bool         write { false }; // flag to enable writing
+   bool         writeFromDataStructure { false }; // flag to enable writing of the L1Menu structure (if available)
    std::string  base { "" };
 
    // other
@@ -68,6 +70,7 @@ void Config::usage() {
   cout << "  --db                  dbalias                       ... dbalias (default " << dbalias << ") \n";
   cout << "[Output options]\n";
   cout << "  -w|--write            [base]                        ... to write out json files, e.g. L1menu[_<base>].json. base is optional.\n";
+  cout << "  -W|--Write            [base]                        ... to write out json files from the internal structure (only for L1Menu), e.g. L1menu[_<base>].json. base is optional.\n";
   cout << "[Other options]\n";
   cout << "  -h|--help                                           ... this help\n";
   cout << "  -d|--detail                                         ... prints detailed job options\n";
@@ -104,6 +107,7 @@ Config::parseProgramOptions(int argc, char* argv[]) {
          if(paramName == "h" || paramName == "help" ) { help = true; continue; }
          if(paramName == "d" || paramName == "detail" ) { detail = true; continue; }
          if(paramName == "w" || paramName == "write" ) { write = true; }
+         if(paramName == "W" || paramName == "Write" ) { writeFromDataStructure = true; }
          currentParameter = paramName;
          continue;
       }
@@ -137,7 +141,7 @@ Config::parseProgramOptions(int argc, char* argv[]) {
       }
 
       // output
-      if(currentParameter == "write" || currentParameter == "w") {
+      if(currentParameter == "write" || currentParameter == "w" || currentParameter == "Write" || currentParameter == "W") {
          base = currentWord;
          continue; 
       }
@@ -158,16 +162,24 @@ Config::parseProgramOptions(int argc, char* argv[]) {
 namespace {
    bool
    writeJsonFile(const TrigConf::DataStructure & ds, const std::string & kind, const Config & cfg) {
-      if( ! cfg.write )
-         return true;
-
-      std::string filename = kind;
-      if ( cfg.base != "" ) {
-         filename += "_" + cfg.base;
+      if( cfg.write ) {
+         std::string filename = kind;
+         if ( cfg.base != "" ) {
+            filename += "_" + cfg.base;
+         }
+         filename += ".json";
+         TrigConf::JsonFileLoader fileLoader;
+         return fileLoader.saveFile(filename, ds); 
+      } else if ( cfg.writeFromDataStructure && kind=="L1Menu" ) {
+         std::string filename = kind;
+         if ( cfg.base != "" ) {
+            filename += "_" + cfg.base;
+         }
+         filename += ".fromDS.json";
+         TrigConf::JsonFileWriter fileWriter;
+         const auto & l1menu = dynamic_cast<const TrigConf::L1Menu &>(ds);
+         return fileWriter.writeJsonFile(filename, l1menu); 
       }
-      filename += ".json";
-      TrigConf::JsonFileLoader fileLoader;
-      fileLoader.saveFile(filename, ds);
       return true;
    }
 
diff --git a/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfFrontier.py b/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfFrontier.py
index 3d4f3270f5225ad6682798363fe653d338c7b77a..15c0a7a7f93d80c6f9c4216396d2feac4ad82e81 100755
--- a/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfFrontier.py
+++ b/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfFrontier.py
@@ -16,16 +16,78 @@ from AthenaCommon.Logging import logging
 import time
 import sys
 
-def getFrontierCursor(url, schema, loglevel = logging.INFO):
-    log = logging.getLogger( "TrigConfFrontier.py" )
-    log.setLevel(loglevel)
+
+# useFrontierClient 
+# True: one uses the python bindings of frontier_client from the TrigConfDBConnection package
+# False: one uses a purely python-based implementation
+useFrontierClient = False
+
+
+def getServerUrls(frontier_servers):
+    """
+    turns
+    '(serverurl=http://atlasfrontier-local.cern.ch:8000/atlr)(serverurl=http://atlasfrontier-ai.cern.ch:8000/atlr)'
+    into
+    ['http://atlasfrontier-local.cern.ch:8000/atlr','http://atlasfrontier-ai.cern.ch:8000/atlr']
+    """
+    from re import findall
+    return findall(r'\(serverurl=(.*?)\)',frontier_servers)
+
+
+def testUrl(url):
+    import urllib.request, urllib.error, urllib.parse
     try:
-        from TrigConfDBConnection import frontier_client  # noqa: F401
+        urllib.request.urlopen(url)
+    except urllib.error.URLError:
+        return False
+    return True
+
+def getFrontierCursor(url, schema):
+    if useFrontierClient:
+        log.info("Using frontier_client from TrigConfDBConnection")
         return FrontierCursor2( url = url, schema = schema)
-    except Exception:
-        log.warning("Couldn't import frontier_client from TrigConfDBConnection, falling back to pure python implementation without proper url resolution")
+    else:
+        log.info("Using a pure python implementation of frontier")
         return FrontierCursor( url = url, schema = schema)
         
+# used by FrontierCursor2
+def resolvebindvars(query, bindvars):
+    """Replaces the bound variables :xyz with a ? in the query and
+    adding the value behind a : at the end"""
+    log = logging.getLogger( "TrigConfFrontier.py" )
+    log.info("Query: %s", query)
+    log.info("bound variables: %r", bindvars)
+    import re
+    varsextract = re.findall(':([A-z0-9]*)',query)
+    values = list(map(bindvars.get, varsextract))
+    log.debug("Resolving bound variable %r with %r", varsextract,values)
+    appendix = ":".join([str(v) for v in values])
+    queryWithQuestionMarks = re.sub(':[A-z0-9]*','?', query)
+    query = queryWithQuestionMarks + ':' + appendix
+    log.info("Resolved query new style: %s", query)
+    return query
+
+# used by FrontierCursor
+def replacebindvars(query, bindvars):
+    """Replaces the bound variables with the specified values,
+    disables variable binding
+    """
+    log = logging.getLogger( "TrigConfFrontier.py" )
+    from builtins import int
+    for var,val in list(bindvars.items()):
+        if query.find(":%s" % var)<0:
+            raise NameError("variable '%s' is not a bound variable in this query: %s" % (var, query) )
+        if isinstance (val, int):
+            query = query.replace(":%s" % var,"%s" % val)
+        else:
+            query = query.replace(":%s" % var,"%r" % val)
+        log.debug("Resolving bound variable '%s' with %r", var,val)
+    log.debug("Resolved query: %s", query)
+    return query
+
+
+            
+
 
 class FrontierCursor2(object):
     def __init__(self, url, schema, refreshFlag=False):
@@ -39,41 +101,10 @@ class FrontierCursor2(object):
         log.debug("Schema            : %s", self.schema)
         log.debug("Refresh cache     : %s", self.refreshFlag)
 
-    @classmethod
-    def resolvebindvars(cls, query, bindvars):
-        """Replaces the bound variables :xyz with a ? in the query and
-        adding the value behind a : at the end"""
-        log = logging.getLogger( "TrigConfFrontier.py" )
-        import re
-        varsextract = re.findall(':([A-z0-9]*)',query)
-        values = list(map(bindvars.get, varsextract))
-        log.debug("Resolving bound variable %r with %r", varsextract,values)
-        appendix = ":".join([str(v) for v in values])
-        queryWithQuestionMarks = re.sub(':[A-z0-9]*','?', query)
-        query = queryWithQuestionMarks + ':' + appendix
-        return query
-
-    @classmethod
-    def replacebindvars(cls, query, bindvars):
-        """Replaces the bound variables with the specified values,
-        disables variable binding
-        """
-        log = logging.getLogger( "TrigConfFrontier.py" )
-        from builtins import int
-        for var,val in list(bindvars.items()):
-            if query.find(":%s" % var)<0:
-                raise NameError("variable '%s' is not a bound variable in this query: %s" % (var, query) )
-            if isinstance (val, int):
-                query = query.replace(":%s" % var,"%s" % val)
-            else:
-                query = query.replace(":%s" % var,"%r" % val)
-            log.debug("Resolving bound variable '%s' with %r", var,val)
-        log.debug("Resolved query: %s", query)
-        return query
 
     def execute(self, query, bindvars={}):
         if len(bindvars)>0:
-            query = FrontierCursor2.resolvebindvars(query,bindvars)
+            query = resolvebindvars(query,bindvars)
             
         from TrigConfDBConnection import frontier_client as fc
         log = logging.getLogger( "TrigConfFrontier.py" )
@@ -116,54 +147,37 @@ class FrontierCursor2(object):
         return self.result
 
     def __str__(self):
-        return """FrontierCursor2:
-Using Frontier URL: %s
-Schema: %s
-Refresh cache:  %s""" % (self.url, self.schema, self.refreshFlag)
+        s =  "FrontierCursor2:\n"
+        s += "Using Frontier URL: %s\n" % self.url
+        s += "Schema: %s\n" % self.schema
+        s += "Refresh cache:  %s" % self.refreshFlag
+        return s
 
 
 
     
 class FrontierCursor(object):
     def __init__(self, url, schema, refreshFlag=False, doDecode=True, retrieveZiplevel="zip"):
-        if url.startswith('('):
-            self.servertype, self.url  = FrontierCursor.getServerUrls(url)[0]
-            self.url += "/Frontier"
-        else:
-            self.url = url
+        self.url = url + "/Frontier"
         self.schema = schema
         self.refreshFlag = refreshFlag
         self.retrieveZiplevel = retrieveZiplevel
         self.doDecode = doDecode
-        # connstr='frontier://ATLF/%s;schema=%s;dbname=TRIGCONF' % (connectionParameters['url'],connectionParameters["schema"])
 
     def __str__(self):
-        return """FrontierCursor:
-Using Frontier URL: %s
-Refresh cache:  %s""" % (self.url, self.refreshFlag)
-
-    @classmethod
-    def getServerUrls(cls, frontier_servers):
-        from re import findall
-        return findall(r'\((serverurl)=(.*?)\)',frontier_servers)
-
-    @classmethod
-    def testUrl(cls, url):
-        import urllib.request, urllib.error, urllib.parse
-        try:
-            urllib.request.urlopen(url)
-        except urllib.error.URLError:
-            import traceback
-            traceback.print_exc()
-            
+        s = "Using Frontier URL: %s\n" % self.url
+        s += "Schema: %s\n" % self.schema
+        s += "Refresh cache:  %s" % self.refreshFlag
+        return s
+
     def execute(self, query, bindvars={}):
         if len(bindvars)>0:
-            query = FrontierCursor2.replacebindvars(query,bindvars)
+            query = replacebindvars(query,bindvars)
         
         log = logging.getLogger( "TrigConfFrontier.py" )
-        log.debug("Using Frontier URL: %s", self.url)
-        log.debug("Refresh cache     : %s", self.refreshFlag)
-        log.debug("Query             : %s", query)
+        log.debug("Frontier URL  : %s", self.url)
+        log.debug("Refresh cache : %s", self.refreshFlag)
+        log.debug("Query         : %s", query)
         
         import base64, zlib, urllib.request, urllib.error, urllib.parse, time
 
@@ -185,6 +199,8 @@ Refresh cache:  %s""" % (self.url, self.refreshFlag)
         queryStart = time.localtime()
         log.debug("Query started: %s", time.strftime("%m/%d/%y %H:%M:%S %Z", queryStart))
 
+        print(request)
+
         t1 = time.time()
         result = urllib.request.urlopen(request,None,10).read().decode()
         t2 = time.time()
@@ -261,10 +277,10 @@ Refresh cache:  %s""" % (self.url, self.refreshFlag)
                 import re
                 row_h = row_h.replace("\x07\x06",'.nNn.\x06')
 
-#                pattern = re.compile("\x06\x00\x00\x00.",flags=re.S)
-#replace pattern above  more restrictive version, as longerstrings in the results
-#have a size variable in the column separate that becomes visible if the string
-#is large enough - this then broke the prevous  decoding
+                #                pattern = re.compile("\x06\x00\x00\x00.",flags=re.S)
+                #replace pattern above  more restrictive version, as longerstrings in the results
+                #have a size variable in the column separate that becomes visible if the string
+                #is large enough - this then broke the prevous  decoding
                 pattern = re.compile("\x06\x00\x00..",flags=re.S)
                 row_h = pattern.sub('.xXx.',row_h)
                 row_h = row_h.replace("\x86", '.xXx.')
@@ -281,40 +297,46 @@ Refresh cache:  %s""" % (self.url, self.refreshFlag)
         self.result = result
 
 
-def testConnection():
-    log = logging.getLogger( "TrigConfFrontier.py::testConnection()" )
-    log.setLevel(logging.DEBUG)
 
+
+def testQuery(query, bindvars):
+    log = logging.getLogger( "TrigConfFrontier.py" )
     from TriggerJobOpts.TriggerFlags import TriggerFlags as tf
     tf.triggerUseFrontier = True
 
     from TrigConfigSvc.TrigConfigSvcUtils import interpretConnection
     connectionParameters = interpretConnection("TRIGGERDBMC")
-
-    cursor = FrontierCursor( url = connectionParameters['url'], schema = connectionParameters['schema'])
-
-    query = "select distinct HPS.HPS_NAME from ATLAS_CONF_TRIGGER_RUN2_MC.HLT_PRESCALE_SET HPS where HPS.HPS_ID = '260'"
-
-    cursor.execute(query)
-    print(cursor.result)
-    cursor.decodeResult()
-    print(cursor.result[0][0])
-    assert cursor.result[0][0] == 'MC_pp_v7'
-
+    for url in getServerUrls( connectionParameters['url'] ):
+        if not testUrl(url):
+            log.info("Skipping %s (failing connection test)", url)
+            continue
+        log.info("Testing %s", url)
+        cursor = getFrontierCursor( url = url, schema = connectionParameters['schema'])
+        cursor.execute(query, bindvars)
+        log.info("Raw response:")
+        print(cursor.result)
+        cursor.decodeResult()
+        log.info("Decoded response:")
+        log.info(cursor.result[0][0])        
+        if cursor.result[0][0] != 'MC_pp_v7':
+            return 1
+        break
     return 0
 
 
-def testBindVarResolution():
-    query = "SELECT :bar WHERE :foo = :bar sort by :ups asc, :foo"
-    bindvars = {"foo": 500, "bar": 8, "ups": 42 }
-    print("Query")
-    print(query)
-    print("is translated to")
-    print(FrontierCursor2.resolvebindvars(query, bindvars))
+def testBindVarResolution(query, bindvars):
+    resolvebindvars(query, bindvars)
     return 0
 
     
 if __name__=="__main__":
-    res = testBindVarResolution()
-    res = max(res, testConnection())
+    log = logging.getLogger( "TrigConfFrontier.py" )
+    log.setLevel(logging.DEBUG)
+
+    dbalias = "TRIGGERDBMC"
+    query = "select distinct HPS.HPS_NAME from ATLAS_CONF_TRIGGER_RUN2_MC.HLT_PRESCALE_SET HPS where HPS.HPS_ID = :psk"
+    bindvars = { "psk": 260 }
+
+    res = testBindVarResolution(query, bindvars) # query resolution for c++ frontier client
+    res = max(res, testQuery(query, bindvars)) # pure python frontier query
     sys.exit(res)
diff --git a/Trigger/TrigSteer/DecisionHandling/python/EmuStepProcessingConfig.py b/Trigger/TrigSteer/DecisionHandling/python/EmuStepProcessingConfig.py
index 2bbde0df3d29d700743405ed1c8769474bfe83e3..0d80f0e9ddbc3f5132e09a37b0cbe64071a8d35a 100644
--- a/Trigger/TrigSteer/DecisionHandling/python/EmuStepProcessingConfig.py
+++ b/Trigger/TrigSteer/DecisionHandling/python/EmuStepProcessingConfig.py
@@ -177,9 +177,7 @@ def generateEmuEvents():
 
 ###########################################################################    
 def generateChainsManually():
-    from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import ChainStep
-    from DecisionHandling.TestUtils import makeChain
-    
+    from DecisionHandling.TestUtils import makeChain, makeChainStep    
 
     doMuon     = True
     doElectron = True
@@ -203,21 +201,21 @@ def generateChainsManually():
         #step4
         mu41 = muMenuSequence(step="4",reconame="v1", hyponame="v1")
 
-        step_mu11  = ChainStep("Step1_mu11", [mu11])
-        step_mu21  = ChainStep("Step2_mu21", [mu21] )
-        step_mu22  = ChainStep("Step2_mu22", [mu22] )
-        step_mu31  = ChainStep("Step3_mu31", [mu31] )
-        step_mu32  = ChainStep("Step3_mu32", [mu32] )
-        step_mu41  = ChainStep("Step4_mu41", [mu41] )
+        step_mu11  = makeChainStep("Step1_mu11", [mu11] )
+        step_mu21  = makeChainStep("Step2_mu21", [mu21] )
+        step_mu22  = makeChainStep("Step2_mu22", [mu22] )
+        step_mu31  = makeChainStep("Step3_mu31", [mu31] )
+        step_mu32  = makeChainStep("Step3_mu32", [mu32] )
+        step_mu41  = makeChainStep("Step4_mu41", [mu41] )
         
-        step_empy= ChainStep("Step2_mu1empty", multiplicity=[])
+        step_empy= makeChainStep("Step2_mu1empty", multiplicity=[])
 
         MuChains  = [
-            makeChain(name='HLT_TestChain8_muv1step_L1MU6',  L1Thresholds=["MU6"],   ChainSteps=[step_mu11]),
+            makeChain(name='HLT_TestChain8_muv1step_L1MU6', L1Thresholds=["MU6"],    ChainSteps=[step_mu11]),
             makeChain(name='HLT_TestChain8_muv1_L1MU10',    L1Thresholds=["MU10"],   ChainSteps=[step_mu11 , step_mu21 , step_mu31, step_mu41] ),
             makeChain(name='HLT_TestChain20_muv1_L1MU10',   L1Thresholds=["MU10"],   ChainSteps=[step_mu11 , step_mu21 , step_mu31, step_mu41] ),
             makeChain(name='HLT_TestChain10_muv2_L1MU10',   L1Thresholds=["MU10"],   ChainSteps=[step_mu11 , step_mu22 , step_mu31] ), 
-            makeChain(name='HLT_TestChain6_muEmpty2_L1MU6',  L1Thresholds=["MU6"],   ChainSteps=[step_mu11 , step_empy , step_mu32, step_mu41] ), 
+            makeChain(name='HLT_TestChain6_muEmpty2_L1MU6', L1Thresholds=["MU6"],    ChainSteps=[step_mu11 , step_empy , step_mu32, step_mu41] ), 
             ]
             
 
@@ -238,11 +236,11 @@ def generateChainsManually():
         gamm11 = gamMenuSequence("1", reconame="v1", hyponame="v1")
     
         ElChains  = [
-            makeChain(name='HLT_TestChain5_ev1_L1EM3', L1Thresholds=["EM3"], ChainSteps=[ ChainStep("Step1_em11", [el11]), ChainStep("Step2_em21",  [el21]), ChainStep("Step3_em31",  [el31])] ),
-            makeChain(name='HLT_TestChain8_ev1_L1EM5', L1Thresholds=["EM5"], ChainSteps=[ ChainStep("Step1_em11", [el11]), ChainStep("Step2_em21",  [el21]), ChainStep("Step3_em31",  [el31]) ] ),
-            makeChain(name='HLT_TestChain5_ev2_L1EM7', L1Thresholds=["EM7"], ChainSteps=[ ChainStep("Step1_em11", [el11]), ChainStep("Step2_em22",  [el22]) ] ),
-            makeChain(name='HLT_TestChain5_ev3_L1EM7', L1Thresholds=["EM7"], ChainSteps=[ ChainStep("Step1_em11", [el11]), ChainStep("Step2_em23",  [el23]) ] ),
-            makeChain(name='HLT_TestChain5_gv1_L1EM7', L1Thresholds=["EM7"], ChainSteps=[ ChainStep("Step1_gam11", [gamm11]) ] )
+            makeChain(name='HLT_TestChain5_ev1_L1EM3', L1Thresholds=["EM3"], ChainSteps=[ makeChainStep("Step1_em11", [el11]), makeChainStep("Step2_em21",  [el21]), makeChainStep("Step3_em31",  [el31])] ),
+            makeChain(name='HLT_TestChain8_ev1_L1EM5', L1Thresholds=["EM5"], ChainSteps=[ makeChainStep("Step1_em11", [el11]), makeChainStep("Step2_em21",  [el21]), makeChainStep("Step3_em31",  [el31]) ] ),
+            makeChain(name='HLT_TestChain5_ev2_L1EM7', L1Thresholds=["EM7"], ChainSteps=[ makeChainStep("Step1_em11", [el11]), makeChainStep("Step2_em22",  [el22]) ] ),
+            makeChain(name='HLT_TestChain5_ev3_L1EM7', L1Thresholds=["EM7"], ChainSteps=[ makeChainStep("Step1_em11", [el11]), makeChainStep("Step2_em23",  [el23]) ] ),
+            makeChain(name='HLT_TestChain5_gv1_L1EM7', L1Thresholds=["EM7"], ChainSteps=[ makeChainStep("Step1_gam11", [gamm11]) ] )
         ]
 
         HLTChains += ElChains
@@ -283,52 +281,52 @@ def generateChainsManually():
         CombChains =[
             # This is an example of a chain running in "serial"
             makeChain(name='HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5',  L1Thresholds=["MU6","EM5"], ChainSteps=[
-                ChainStep("Step1_mu_em_serial", [mu11, emptySeq1], multiplicity=[1,1]),
-                ChainStep("Step2_mu_em_serial", [emptySeq2, el21], multiplicity=[1,1]),
-                ChainStep("Step3_mu_em_serial", multiplicity=[]),
-                ChainStep("Step4_mu_em_serial", [mu41, el41],  multiplicity=[1,1])] ),
+                makeChainStep("Step1_mu_em_serial", [mu11, emptySeq1], multiplicity=[1,1]),
+                makeChainStep("Step2_mu_em_serial", [emptySeq2, el21], multiplicity=[1,1]),
+                makeChainStep("Step3_mu_em_serial", multiplicity=[]),
+                makeChainStep("Step4_mu_em_serial", [mu41, el41],  multiplicity=[1,1])] ),
 
             makeChain(name='HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5', L1Thresholds=["MU6","EM5"], ChainSteps=[
-                ChainStep("Step1_mu2_em", [mu12, el11], multiplicity=[1,1]),
-                ChainStep("Step2_mu_em", [mu21, el21], multiplicity=[1,1])] ),
+                makeChainStep("Step1_mu2_em", [mu12, el11], multiplicity=[1,1]),
+                makeChainStep("Step2_mu_em", [mu21, el21], multiplicity=[1,1])] ),
 
             makeChain(name='HLT_TestChain5_ev1_TestChain8_ev1_L12EM3',   L1Thresholds=["EM3","EM3"], ChainSteps=[ #norun
-                ChainStep("Step1_2emAs",   [el11, el11], multiplicity=[1,1]),
-                ChainStep("Step2_2emAs",   [el21, el21], multiplicity=[1,1]) ]),
+                makeChainStep("Step1_2emAs",   [el11, el11], multiplicity=[1,1]),
+                makeChainStep("Step2_2emAs",   [el21, el21], multiplicity=[1,1]) ]),
                 
             makeChain(name='HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_L1EM5_L12MU6',   L1Thresholds=["EM3","EM5","MU6"], ChainSteps=[
-                ChainStep("Step1_2em_2mu",   [el11,el11,mu11], multiplicity=[1,1,2]),
-                ChainStep("Step2_2em_2mu",   [el21,el21,mu21], multiplicity=[1,1,2]) ]),
+                makeChainStep("Step1_2em_2mu",   [el11,el11,mu11], multiplicity=[1,1,2]),
+                makeChainStep("Step2_2em_2mu",   [el21,el21,mu21], multiplicity=[1,1,2]) ]),
 
             makeChain(name='HLT_2TestChain6_muv1_L12MU6',       L1Thresholds=["MU6"], ChainSteps=[
-                ChainStep("Step1_2mu",   [mu11], multiplicity=[2]),
-                ChainStep("Step2_2mu",   [mu21], multiplicity=[2]) ]),
+                makeChainStep("Step1_2mu",   [mu11], multiplicity=[2]),
+                makeChainStep("Step2_2mu",   [mu21], multiplicity=[2]) ]),
 
             makeChain(name='HLT_3TestChain6_muv1_L12MU6',       L1Thresholds=["MU6"], ChainSteps=[
-                ChainStep("Step1_2mu",   [mu11], multiplicity=[3]),
-                ChainStep("Step2_2mu",   [mu21], multiplicity=[3]) ]),
+                makeChainStep("Step1_2mu",   [mu11], multiplicity=[3]),
+                makeChainStep("Step2_2mu",   [mu21], multiplicity=[3]) ]),
 
             makeChain(name='HLT_TestChain6_muv1_TestChain10_muv1_L12MU6',       L1Thresholds=["MU6", "MU6"], ChainSteps=[
-                ChainStep("Step1_2muAs",   [mu11,mu11], multiplicity=[1,1]),
-                ChainStep("Step2_2muAs",   [mu21,mu21], multiplicity=[1,1]) ]),
+                makeChainStep("Step1_2muAs",   [mu11,mu11], multiplicity=[1,1]),
+                makeChainStep("Step2_2muAs",   [mu21,mu21], multiplicity=[1,1]) ]),
                 
             makeChain(name='HLT_2TestChain6_muEmpty1_L12MU6',   L1Thresholds=["MU6"], ChainSteps=[
-                ChainStep("Step1_2mu_empty",  multiplicity=[]),#[2]
-                ChainStep("Step2_2mu", [mu21], multiplicity=[2]) ]),
+                makeChainStep("Step1_2mu_empty",  multiplicity=[]),#[2]
+                makeChainStep("Step2_2mu", [mu21], multiplicity=[2]) ]),
 
             makeChain(name='HLT_TestChain6_muv1_TestChain5_ev1dr_L12MU6',  L1Thresholds=["MU6","EM5"], ChainSteps=[
-                ChainStep("Step1_mu_em", [mu11, el11], multiplicity=[1,1], comboToolConfs=[dimuDrComboHypoTool]),
-                ChainStep("Step2_mu_em", [mu21, el21], multiplicity=[1,1], comboToolConfs=[dimuDrComboHypoTool])] ),
+                makeChainStep("Step1_mu_em", [mu11, el11], multiplicity=[1,1], comboToolConfs=[dimuDrComboHypoTool]),
+                makeChainStep("Step2_mu_em", [mu21, el21], multiplicity=[1,1], comboToolConfs=[dimuDrComboHypoTool])] ),
                                                                                        
             makeChain(name='HLT_2TestChain4_muv1dr_L12MU6', L1Thresholds=["MU6"], ChainSteps=[
-                ChainStep("Step1_2mu",    [mu11], multiplicity=[2], comboToolConfs=[dimuDrComboHypoTool]),
-                ChainStep("Step2_2mu22",  [mu22], multiplicity=[2]) ] ),
+                makeChainStep("Step1_2mu",    [mu11], multiplicity=[2], comboToolConfs=[dimuDrComboHypoTool]),
+                makeChainStep("Step2_2mu22",  [mu22], multiplicity=[2]) ] ),
 
             # FSNOSEED not implemented in emulation
             #  L1Thresholds=["MU6", "MU6"],
             makeChain(name='HLT_TestChain10_muEmpty1_TestChain6_muEmpty1_L12MU6', L1Thresholds=["MU6", "MU6"],  ChainSteps=[
-                ChainStep("Step1_2muAs_empty", multiplicity=[]),
-                ChainStep("Step2_2muAs",   [mu21, mu21], multiplicity=[1,1]) ])
+                makeChainStep("Step1_2muAs_empty", multiplicity=[]),
+                makeChainStep("Step2_2muAs",   [mu21, mu21], multiplicity=[1,1]) ])
         
                                                                               
             ]
diff --git a/Trigger/TrigSteer/DecisionHandling/python/TestUtils.py b/Trigger/TrigSteer/DecisionHandling/python/TestUtils.py
index 2ae87b96f41ca1f63b71536a632095a0070d807f..5d2773af6f44308906516b61f93c92d8163f034f 100644
--- a/Trigger/TrigSteer/DecisionHandling/python/TestUtils.py
+++ b/Trigger/TrigSteer/DecisionHandling/python/TestUtils.py
@@ -69,8 +69,16 @@ class L1EmulationTest(L1Decoder):
 
         self.L1DecoderSummaryKey = "L1DecoderSummary"
 
-
-
+from DecisionHandling.DecisionHandlingConfig import ComboHypoCfg
+class makeChainStep(object):
+    """ Used to store the step info, regardless of the chainDict"""
+    def __init__(self, name, seq=[], multiplicity=[1], comboHypoCfg=ComboHypoCfg, comboToolConfs=[]):
+        self.name=name
+        self.seq=seq
+        self.mult=multiplicity
+        self.comboToolConfs=comboToolConfs
+        self.comboHypoCfg=comboHypoCfg
+    
 
 chainsCounter = 0
 
@@ -83,6 +91,7 @@ def makeChain( name, L1Thresholds, ChainSteps, Streams="physics:Main", Groups=["
     prop = ChainProp( name=name,  l1SeedThresholds=L1Thresholds, groups=Groups )
 
     from TriggerMenuMT.HLTMenuConfig.Menu.TriggerConfigHLT import TriggerConfigHLT
+    from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import ChainStep
 
     from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import dictFromChainName
     chainDict = dictFromChainName( prop )
@@ -93,8 +102,17 @@ def makeChain( name, L1Thresholds, ChainSteps, Streams="physics:Main", Groups=["
     #set default chain prescale
     chainDict['prescale'] = 1
 
+    from TriggerMenuMT.HLTMenuConfig.Menu.ChainDictTools import splitChainDictInLegs
+
+    listOfChainDicts = splitChainDictInLegs(chainDict)
+    
+    # create the ChainSteps, with the chaindict
+    StepConfig = []
+    for step in ChainSteps:
+        StepConfig+=[ChainStep(step.name, step.seq,  multiplicity=step.mult, chainDicts=listOfChainDicts, comboHypoCfg=step.comboHypoCfg, comboToolConfs=step.comboToolConfs)]
+
     from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import Chain
-    chainConfig = Chain( name=name, L1Thresholds=L1Thresholds, ChainSteps=ChainSteps )
+    chainConfig = Chain( name=name, L1Thresholds=L1Thresholds, ChainSteps=StepConfig )
 
     TriggerConfigHLT.registerChain( chainDict, chainConfig )
 
diff --git a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
index 84c4a2cfdf47fbcc20761261396cac2a9e64da14..e24c0745848058c4d5cf8789cc3dd542d3d6afac 100644
--- a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
+++ b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
@@ -241,6 +241,9 @@ TrigSignatureMoniMT                                 INFO -- #2442891649 Features
 TrigSignatureMoniMT                                 INFO HLT_e26_etcut_L1EM22VHI #1703681121
 TrigSignatureMoniMT                                 INFO -- #1703681121 Events         6          6          6          6          6          -          -          -          -          -          -          -          -          -          -          6
 TrigSignatureMoniMT                                 INFO -- #1703681121 Features                             7          136        7          -          -          -          -          -          -          -          -          -          -
+TrigSignatureMoniMT                                 INFO HLT_e26_lhmedium_mu8noL1_L1EM22VHI #4270718007
+TrigSignatureMoniMT                                 INFO -- #4270718007 Events         6          6          5          5          5          4          0          0          0          0          0          0          0          2          2          2
+TrigSignatureMoniMT                                 INFO -- #4270718007 Features                             5          64         8          4          0          0          0          0          0          0          0          2          2
 TrigSignatureMoniMT                                 INFO HLT_e26_lhtight_L1EM22VHI #1995263521
 TrigSignatureMoniMT                                 INFO -- #1995263521 Events         6          6          5          5          5          4          -          -          -          -          -          -          -          -          -          4
 TrigSignatureMoniMT                                 INFO -- #1995263521 Features                             5          64         8          4          -          -          -          -          -          -          -          -          -
@@ -367,6 +370,9 @@ TrigSignatureMoniMT                                 INFO -- #3939387897 Features
 TrigSignatureMoniMT                                 INFO HLT_g35_medium_g25_medium_L12EM20VH #1158879722
 TrigSignatureMoniMT                                 INFO -- #1158879722 Events         2          2          0          0          0          0          -          -          -          -          -          -          -          -          -          0
 TrigSignatureMoniMT                                 INFO -- #1158879722 Features                             0          0          0          0          -          -          -          -          -          -          -          -          -
+TrigSignatureMoniMT                                 INFO HLT_g35_tight_icalotight_mu18noL1_L1EM22VHI #2789346459
+TrigSignatureMoniMT                                 INFO -- #2789346459 Events         6          6          5          5          5          0          0          0          0          0          0          0          0          0          0          0
+TrigSignatureMoniMT                                 INFO -- #2789346459 Features                             5          5          8          0          0          0          0          0          0          0          0          0          0
 TrigSignatureMoniMT                                 INFO HLT_g5_etcut_L1EM3 #471243435
 TrigSignatureMoniMT                                 INFO -- #471243435 Events          20         20         20         20         20         -          -          -          -          -          -          -          -          -          -          20
 TrigSignatureMoniMT                                 INFO -- #471243435 Features                              137        137        190        -          -          -          -          -          -          -          -          -          -
@@ -551,8 +557,8 @@ TrigSignatureMoniMT                                 INFO HLT_j80_L1J15 #24408723
 TrigSignatureMoniMT                                 INFO -- #2440872308 Events         20         20         0          0          0          0          0          0          0          0          0          13         -          -          -          13
 TrigSignatureMoniMT                                 INFO -- #2440872308 Features                             0          0          0          0          0          0          0          0          0          23         -          -          -
 TrigSignatureMoniMT                                 INFO HLT_j80_j60_L1J15 #582699527
-TrigSignatureMoniMT                                 INFO -- #582699527 Events          20         20         0          0          0          0          0          0          0          0          0          0          -          -          -          0
-TrigSignatureMoniMT                                 INFO -- #582699527 Features                              0          0          0          0          0          0          0          0          0          0          -          -          -
+TrigSignatureMoniMT                                 INFO -- #582699527 Events          20         20         0          0          0          0          0          0          0          0          0          8          -          -          -          8
+TrigSignatureMoniMT                                 INFO -- #582699527 Features                              0          0          0          0          0          0          0          0          0          24         -          -          -
 TrigSignatureMoniMT                                 INFO HLT_j85_L1J20 #510475538
 TrigSignatureMoniMT                                 INFO -- #510475538 Events          19         19         0          0          0          0          0          0          0          0          0          13         -          -          -          13
 TrigSignatureMoniMT                                 INFO -- #510475538 Features                              0          0          0          0          0          0          0          0          0          21         -          -          -
@@ -607,6 +613,9 @@ TrigSignatureMoniMT                                 INFO -- #1696906927 Features
 TrigSignatureMoniMT                                 INFO HLT_mu20_2mu4noL1_L1MU20 #1029128679
 TrigSignatureMoniMT                                 INFO -- #1029128679 Events         8          8          0          0          0          0          8          5          5          5          0          0          0          1          1          1
 TrigSignatureMoniMT                                 INFO -- #1029128679 Features                             0          0          0          0          10         6          6          6          0          0          0          2          2
+TrigSignatureMoniMT                                 INFO HLT_mu20_ivarmedium_mu4noL1_10invm70_L1MU20 #2942530653
+TrigSignatureMoniMT                                 INFO -- #2942530653 Events         8          8          0          0          0          0          8          5          5          5          3          0          0          2          2          2
+TrigSignatureMoniMT                                 INFO -- #2942530653 Features                             0          0          0          0          10         6          6          6          3          0          0          2          2
 TrigSignatureMoniMT                                 INFO HLT_mu20_ivarmedium_mu8noL1_L1MU20 #3249386942
 TrigSignatureMoniMT                                 INFO -- #3249386942 Events         8          8          0          0          0          0          8          5          5          5          3          0          0          1          1          1
 TrigSignatureMoniMT                                 INFO -- #3249386942 Features                             0          0          0          0          10         6          6          6          3          0          0          1          1
@@ -677,8 +686,8 @@ TrigSignatureMoniMT                                 INFO HLT_mu6_ivarmedium_L1MU
 TrigSignatureMoniMT                                 INFO -- #1012713062 Events         10         10         0          0          0          0          10         10         10         9          6          -          -          -          -          6
 TrigSignatureMoniMT                                 INFO -- #1012713062 Features                             0          0          0          0          13         12         13         12         6          -          -          -          -
 TrigSignatureMoniMT                                 INFO HLT_mu6_j45_nojcalib_L1J20 #2114129685
-TrigSignatureMoniMT                                 INFO -- #2114129685 Events         19         19         0          0          0          0          0          0          0          0          0          0          -          -          -          0
-TrigSignatureMoniMT                                 INFO -- #2114129685 Features                             0          0          0          0          0          0          0          0          0          0          -          -          -
+TrigSignatureMoniMT                                 INFO -- #2114129685 Events         19         19         0          0          0          0          9          9          9          8          0          0          -          -          -          0
+TrigSignatureMoniMT                                 INFO -- #2114129685 Features                             0          0          0          0          11         10         11         10         0          0          -          -          -
 TrigSignatureMoniMT                                 INFO HLT_mu6_msonly_L1MU6 #3895421032
 TrigSignatureMoniMT                                 INFO -- #3895421032 Events         10         10         0          0          0          0          10         0          10         -          -          -          -          -          -          10
 TrigSignatureMoniMT                                 INFO -- #3895421032 Features                             0          0          0          0          13         0          13         -          -          -          -          -          -
@@ -689,8 +698,8 @@ TrigSignatureMoniMT                                 INFO HLT_mu6_mu6noL1_L1MU6 #
 TrigSignatureMoniMT                                 INFO -- #451489897 Events          10         10         0          0          0          0          10         10         10         9          0          0          0          4          3          3
 TrigSignatureMoniMT                                 INFO -- #451489897 Features                              0          0          0          0          13         12         13         12         0          0          0          6          5
 TrigSignatureMoniMT                                 INFO HLT_mu6_xe30_mht_L1XE10 #3192713675
-TrigSignatureMoniMT                                 INFO -- #3192713675 Events         19         19         0          0          0          0          0          0          0          0          0          0          -          -          -          0
-TrigSignatureMoniMT                                 INFO -- #3192713675 Features                             0          0          0          0          0          0          0          0          0          0          -          -          -
+TrigSignatureMoniMT                                 INFO -- #3192713675 Events         19         19         0          0          0          0          9          9          9          8          0          8          -          -          -          8
+TrigSignatureMoniMT                                 INFO -- #3192713675 Features                             0          0          0          0          12         11         12         11         0          10         -          -          -
 TrigSignatureMoniMT                                 INFO HLT_mu80_L1MU20 #387900377
 TrigSignatureMoniMT                                 INFO -- #387900377 Events          8          8          0          0          0          0          8          5          1          0          -          -          -          -          -          0
 TrigSignatureMoniMT                                 INFO -- #387900377 Features                              0          0          0          0          10         6          1          0          -          -          -          -          -
@@ -914,11 +923,11 @@ TrigSignatureMoniMT                                 INFO HLT_tau0_perf_ptonly_L1
 TrigSignatureMoniMT                                 INFO -- #2342716369 Events         0          0          0          0          0          0          0          0          -          -          -          -          -          -          -          0
 TrigSignatureMoniMT                                 INFO -- #2342716369 Features                             0          0          0          0          0          0          -          -          -          -          -          -          -
 TrigSignatureMoniMT                                 INFO HLT_tau0_perf_ptonly_L1TAU12 #372992233
-TrigSignatureMoniMT                                 INFO -- #372992233 Events          18         18         18         18         0          0          0          0          -          -          -          -          -          -          -          0
-TrigSignatureMoniMT                                 INFO -- #372992233 Features                              42         27         0          0          0          0          -          -          -          -          -          -          -
+TrigSignatureMoniMT                                 INFO -- #372992233 Events          18         18         18         18         0          0          18         18         -          -          -          -          -          -          -          18
+TrigSignatureMoniMT                                 INFO -- #372992233 Features                              42         27         0          0          27         27         -          -          -          -          -          -          -
 TrigSignatureMoniMT                                 INFO HLT_tau0_perf_ptonly_L1TAU60 #1376650121
-TrigSignatureMoniMT                                 INFO -- #1376650121 Events         5          5          5          3          0          0          0          0          -          -          -          -          -          -          -          0
-TrigSignatureMoniMT                                 INFO -- #1376650121 Features                             6          3          0          0          0          0          -          -          -          -          -          -          -
+TrigSignatureMoniMT                                 INFO -- #1376650121 Events         5          5          5          3          0          0          3          3          -          -          -          -          -          -          -          3
+TrigSignatureMoniMT                                 INFO -- #1376650121 Features                             6          3          0          0          3          3          -          -          -          -          -          -          -
 TrigSignatureMoniMT                                 INFO HLT_tau160_idperf_track_L1TAU100 #714660857
 TrigSignatureMoniMT                                 INFO -- #714660857 Events          0          0          0          0          0          0          0          0          -          -          -          -          -          -          -          0
 TrigSignatureMoniMT                                 INFO -- #714660857 Features                              0          0          0          0          0          0          -          -          -          -          -          -          -
diff --git a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
index 7659ab8e42e302955f520f745bdf18f9d85b0105..901b687c7d98a85e211e07f7136dd38fb2c25787 100644
--- a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
+++ b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
@@ -241,6 +241,9 @@ TrigSignatureMoniMT                                 INFO -- #2442891649 Features
 TrigSignatureMoniMT                                 INFO HLT_e26_etcut_L1EM22VHI #1703681121
 TrigSignatureMoniMT                                 INFO -- #1703681121 Events         20         20         1          1          0          -          -          -          -          -          -          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #1703681121 Features                             1          2          0          -          -          -          -          -          -          -          -          -          -          
+TrigSignatureMoniMT                                 INFO HLT_e26_lhmedium_mu8noL1_L1EM22VHI #4270718007
+TrigSignatureMoniMT                                 INFO -- #4270718007 Events         20         20         0          0          0          0          0          0          0          0          0          0          0          0          0          0          
+TrigSignatureMoniMT                                 INFO -- #4270718007 Features                             0          0          0          0          0          0          0          0          0          0          0          0          0          
 TrigSignatureMoniMT                                 INFO HLT_e26_lhtight_L1EM22VHI #1995263521
 TrigSignatureMoniMT                                 INFO -- #1995263521 Events         20         20         0          0          0          0          -          -          -          -          -          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #1995263521 Features                             0          0          0          0          -          -          -          -          -          -          -          -          -          
@@ -367,6 +370,9 @@ TrigSignatureMoniMT                                 INFO -- #3939387897 Features
 TrigSignatureMoniMT                                 INFO HLT_g35_medium_g25_medium_L12EM20VH #1158879722
 TrigSignatureMoniMT                                 INFO -- #1158879722 Events         20         20         0          0          0          0          -          -          -          -          -          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #1158879722 Features                             0          0          0          0          -          -          -          -          -          -          -          -          -          
+TrigSignatureMoniMT                                 INFO HLT_g35_tight_icalotight_mu18noL1_L1EM22VHI #2789346459
+TrigSignatureMoniMT                                 INFO -- #2789346459 Events         20         20         0          0          0          0          0          0          0          0          0          0          0          0          0          0          
+TrigSignatureMoniMT                                 INFO -- #2789346459 Features                             0          0          0          0          0          0          0          0          0          0          0          0          0          
 TrigSignatureMoniMT                                 INFO HLT_g5_etcut_L1EM3 #471243435
 TrigSignatureMoniMT                                 INFO -- #471243435 Events          20         20         13         13         13         -          -          -          -          -          -          -          -          -          -          13         
 TrigSignatureMoniMT                                 INFO -- #471243435 Features                              41         41         50         -          -          -          -          -          -          -          -          -          -          
@@ -607,6 +613,9 @@ TrigSignatureMoniMT                                 INFO -- #1696906927 Features
 TrigSignatureMoniMT                                 INFO HLT_mu20_2mu4noL1_L1MU20 #1029128679
 TrigSignatureMoniMT                                 INFO -- #1029128679 Events         20         20         0          0          0          0          1          1          0          0          0          0          0          0          0          0          
 TrigSignatureMoniMT                                 INFO -- #1029128679 Features                             0          0          0          0          1          1          0          0          0          0          0          0          0          
+TrigSignatureMoniMT                                 INFO HLT_mu20_ivarmedium_mu4noL1_10invm70_L1MU20 #2942530653
+TrigSignatureMoniMT                                 INFO -- #2942530653 Events         20         20         0          0          0          0          1          1          0          0          0          0          0          0          0          0          
+TrigSignatureMoniMT                                 INFO -- #2942530653 Features                             0          0          0          0          1          1          0          0          0          0          0          0          0          
 TrigSignatureMoniMT                                 INFO HLT_mu20_ivarmedium_mu8noL1_L1MU20 #3249386942
 TrigSignatureMoniMT                                 INFO -- #3249386942 Events         20         20         0          0          0          0          1          1          0          0          0          0          0          0          0          0          
 TrigSignatureMoniMT                                 INFO -- #3249386942 Features                             0          0          0          0          1          1          0          0          0          0          0          0          0          
@@ -689,8 +698,8 @@ TrigSignatureMoniMT                                 INFO HLT_mu6_mu6noL1_L1MU6 #
 TrigSignatureMoniMT                                 INFO -- #451489897 Events          20         20         0          0          0          0          1          1          0          0          0          0          0          0          0          0          
 TrigSignatureMoniMT                                 INFO -- #451489897 Features                              0          0          0          0          1          1          0          0          0          0          0          0          0          
 TrigSignatureMoniMT                                 INFO HLT_mu6_xe30_mht_L1XE10 #3192713675
-TrigSignatureMoniMT                                 INFO -- #3192713675 Events         20         20         0          0          0          0          0          0          0          0          0          0          -          -          -          0          
-TrigSignatureMoniMT                                 INFO -- #3192713675 Features                             0          0          0          0          0          0          0          0          0          0          -          -          -          
+TrigSignatureMoniMT                                 INFO -- #3192713675 Events         20         20         0          0          0          0          1          1          0          0          0          0          -          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #3192713675 Features                             0          0          0          0          1          1          0          0          0          0          -          -          -          
 TrigSignatureMoniMT                                 INFO HLT_mu80_L1MU20 #387900377
 TrigSignatureMoniMT                                 INFO -- #387900377 Events          20         20         0          0          0          0          1          1          0          0          -          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #387900377 Features                              0          0          0          0          1          1          0          0          -          -          -          -          -          
@@ -914,8 +923,8 @@ TrigSignatureMoniMT                                 INFO HLT_tau0_perf_ptonly_L1
 TrigSignatureMoniMT                                 INFO -- #2342716369 Events         20         20         0          0          0          0          0          0          -          -          -          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #2342716369 Features                             0          0          0          0          0          0          -          -          -          -          -          -          -          
 TrigSignatureMoniMT                                 INFO HLT_tau0_perf_ptonly_L1TAU12 #372992233
-TrigSignatureMoniMT                                 INFO -- #372992233 Events          20         20         4          4          0          0          0          0          -          -          -          -          -          -          -          0          
-TrigSignatureMoniMT                                 INFO -- #372992233 Features                              5          5          0          0          0          0          -          -          -          -          -          -          -          
+TrigSignatureMoniMT                                 INFO -- #372992233 Events          20         20         4          4          0          0          4          4          -          -          -          -          -          -          -          4          
+TrigSignatureMoniMT                                 INFO -- #372992233 Features                              5          5          0          0          4          4          -          -          -          -          -          -          -          
 TrigSignatureMoniMT                                 INFO HLT_tau0_perf_ptonly_L1TAU60 #1376650121
 TrigSignatureMoniMT                                 INFO -- #1376650121 Events         20         20         0          0          0          0          0          0          -          -          -          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #1376650121 Features                             0          0          0          0          0          0          -          -          -          -          -          -          -          
@@ -1073,17 +1082,17 @@ TrigSignatureMoniMT                                 INFO HLT_xe30_mht_L1XE10 #36
 TrigSignatureMoniMT                                 INFO -- #3626903018 Events         20         20         0          0          0          0          0          0          0          0          0          14         -          -          -          14         
 TrigSignatureMoniMT                                 INFO -- #3626903018 Features                             0          0          0          0          0          0          0          0          0          14         -          -          -          
 TrigSignatureMoniMT                                 INFO HLT_xe30_mhtpufit_em_subjesgscIS_L1XE10 #689201557
-TrigSignatureMoniMT                                 INFO -- #689201557 Events          20         20         0          0          0          0          0          0          0          0          0          7          -          -          -          7          
-TrigSignatureMoniMT                                 INFO -- #689201557 Features                              0          0          0          0          0          0          0          0          0          7          -          -          -          
+TrigSignatureMoniMT                                 INFO -- #689201557 Events          20         20         0          0          0          0          0          0          0          0          0          7          -          -          -          7 
+TrigSignatureMoniMT                                 INFO -- #689201557 Features                              0          0          0          0          0          0          0          0          0          7          -          -          - 
 TrigSignatureMoniMT                                 INFO HLT_xe30_mhtpufit_pf_subjesgscIS_L1XE10 #1886909707
-TrigSignatureMoniMT                                 INFO -- #1886909707 Events         20         20         0          0          0          0          0          0          0          0          0          5          -          -          -          5          
-TrigSignatureMoniMT                                 INFO -- #1886909707 Features                             0          0          0          0          0          0          0          0          0          5          -          -          -          
+TrigSignatureMoniMT                                 INFO -- #1886909707 Events         20         20         0          0          0          0          0          0          0          0          0          5          -          -          -          5 
+TrigSignatureMoniMT                                 INFO -- #1886909707 Features                             0          0          0          0          0          0          0          0          0          5          -          -          - 
 TrigSignatureMoniMT                                 INFO HLT_xe30_pfopufit_L1XE10 #2252641537
-TrigSignatureMoniMT                                 INFO -- #2252641537 Events         20         20         0          0          0          0          0          0          0          0          0          4          -          -          -          4          
-TrigSignatureMoniMT                                 INFO -- #2252641537 Features                             0          0          0          0          0          0          0          0          0          4          -          -          -          
+TrigSignatureMoniMT                                 INFO -- #2252641537 Events         20         20         0          0          0          0          0          0          0          0          0          4          -          -          -          4 
+TrigSignatureMoniMT                                 INFO -- #2252641537 Features                             0          0          0          0          0          0          0          0          0          4          -          -          - 
 TrigSignatureMoniMT                                 INFO HLT_xe30_pfsum_L1XE10 #998713382
-TrigSignatureMoniMT                                 INFO -- #998713382 Events          20         20         0          0          0          0          0          0          0          0          0          7          -          -          -          7          
-TrigSignatureMoniMT                                 INFO -- #998713382 Features                              0          0          0          0          0          0          0          0          0          7          -          -          -          
+TrigSignatureMoniMT                                 INFO -- #998713382 Events          20         20         0          0          0          0          0          0          0          0          0          7          -          -          -          7 
+TrigSignatureMoniMT                                 INFO -- #998713382 Features                              0          0          0          0          0          0          0          0          0          7          -          -          - 
 TrigSignatureMoniMT                                 INFO HLT_xe30_tcpufit_L1XE10 #1583719916
 TrigSignatureMoniMT                                 INFO -- #1583719916 Events         20         20         0          0          0          0          0          0          0          0          0          6          -          -          -          6          
 TrigSignatureMoniMT                                 INFO -- #1583719916 Features                             0          0          0          0          0          0          0          0          0          6          -          -          -          
diff --git a/Trigger/TrigValidation/TriggerTest/test/test_trig_data_newJO_build.py b/Trigger/TrigValidation/TriggerTest/test/test_trig_data_newJO_build.py
index 4610b7726757ee33114a52e7f01402d434f05f80..7c2f4d1f1f67cb183d6fdde062977b9348cd412a 100755
--- a/Trigger/TrigValidation/TriggerTest/test/test_trig_data_newJO_build.py
+++ b/Trigger/TrigValidation/TriggerTest/test/test_trig_data_newJO_build.py
@@ -7,7 +7,7 @@
 # Skipping art-output which has no effect for build tests.
 # If you create a grid version, check art-output in existing grid tests.
 
-from TrigValTools.TrigValSteering import Test, Step, ExecStep, CheckSteps
+from TrigValTools.TrigValSteering import Test, Step, ExecStep, CheckSteps, Input
 
 # Copy the job options to the working directory
 copy_jo = ExecStep.ExecStep('CopyJO')
@@ -19,29 +19,23 @@ copy_jo.prmon = False
 copy_jo.auto_report_result = False  # Do not set art-result for this step
 copy_jo.output_stream = Step.Step.OutputStream.STDOUT_ONLY  # Do not create a log file for this step
 
-# Generate configuration pickle file
-pickle = ExecStep.ExecStep('GeneratePickle')
-pickle.type = 'other'
-pickle.input = ''
-pickle.executable = 'python'
-pickle.args = 'runHLT_standalone_newJO.py'
-pickle.prmon = False
-
-# The main job running athena from pickle
-run_athena = ExecStep.ExecStep('newJO')
-run_athena.type = 'athena'
-run_athena.use_pickle = True
-run_athena.job_options = 'runHLT_standalone_newJO.py'
-run_athena.input = ''
+# Generate configuration run file
+run = ExecStep.ExecStep('athena')
+run.type = 'other'
+run.input = 'data'
+run.executable = 'python'
+run.args = 'runHLT_standalone_newJO.py'
+run.args += ' --filesInput='+Input.get_input('data').paths[0]
+run.prmon = False
+
 
 # The full test configuration
 test = Test.Test()
 test.art_type = 'build'
-#test.exec_steps = [copy_jo, pickle, run_athena]
 #test.check_steps = CheckSteps.default_check_steps(test)
-test.exec_steps = [copy_jo, pickle]
+test.exec_steps = [copy_jo, run]
 check_log = CheckSteps.CheckLogStep('CheckLog')
-check_log.log_file = pickle.get_log_file_name()
+check_log.log_file = run.get_log_file_name()
 test.check_steps = [check_log]
 
 # Change RegTest pattern
diff --git a/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone_newJO.py b/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone_newJO.py
index 56efb6bc4cf9669f493b93fb5a04c2ad7b2244c8..d1b5c884a5d072dca4095fe57ed3ca980b9b619e 100644
--- a/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone_newJO.py
+++ b/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone_newJO.py
@@ -10,7 +10,6 @@ from AthenaCommon.Configurable import Configurable
 Configurable.configurableRun3Behavior=1
 
 
-
 flags.Detector.GeometryPixel = True
 flags.Detector.GeometrySCT   = True
 flags.Detector.GeometryTRT   = True
@@ -53,7 +52,6 @@ flags.needFlagsCategory('Trigger')
 setupMenuModule.setupMenu(flags)
 flags.Exec.MaxEvents=50
 flags.Input.isMC = False
-flags.Input.Files= ["/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/TrigP1Test/data17_13TeV.00327265.physics_EnhancedBias.merge.RAW._lb0100._SFO-1._0001.1"]
 
 
 flags.Concurrency.NumThreads=1
@@ -62,6 +60,12 @@ flags.Concurrency.NumConcurrentEvents=1
 flags.InDet.useSctDCS=False
 flags.InDet.usePixelDCS=False
 
+# command line handling
+# options that are defined in: AthConfigFlags are handled here
+# they override values from above
+parser = flags.getArgumentParser()
+flags.fillFromArgs(parser=parser)
+
 flags.lock()
 
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/BeamspotChainConfiguration.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/BeamspotChainConfiguration.py
index a41eca3160cc8a1cc0603c196f806adff47a8743..41fce5817ef833cce87552861c5a0d3095423e5e 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/BeamspotChainConfiguration.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/BeamspotChainConfiguration.py
@@ -84,25 +84,30 @@ class BeamspotChainConfiguration(ChainConfigurationBase):
     def assembleChain(self):                            
         chainSteps = []
         log.debug("Assembling chain for " + self.chainName)
-        # --------------------
-        # define here the names of the steps and obtain the chainStep configuration 
-        # --------------------
-        stepDictionary = {
-            "allTE_trkfast":[self.getAllTEStep()],
-            #"activeTE_trkfast":[self.activeTE_trkfast()],
-            "trkFS_trkfast":[self.getTrkFSStep()],
-        }
 
+        stepDictionary = self.getStepDictionary()
+      
         #key = self.chainPart['EFrecoAlg']
         key = self.chainPart['addInfo'][0] + "_" + self.chainPart['l2IDAlg'][0]#TODO: hardcoded index
         steps=stepDictionary[key]
         for step in steps:
-            chainSteps+=[step]
+            chainstep = getattr(self, step)()
+            chainSteps+=[chainstep]
             
         myChain = self.buildChain(chainSteps)
         return myChain
 
-   
+    def getStepDictionary(self):
+        # --------------------
+        # define here the names of the steps and obtain the chainStep configuration 
+        # --------------------
+        stepDictionary = {
+            "allTE_trkfast":['getAllTEStep'],
+            #"activeTE_trkfast":[self.activeTE_trkfast()],
+            "trkFS_trkfast":['getTrkFSStep']
+        }
+        return stepDictionary
+       
     # --------------------
     # Configuration of costmonitor (costmonitor ?? but isn't this is the actua chain configuration ??)
     # --------------------
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/EnhancedBiasChainConfiguration.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/EnhancedBiasChainConfiguration.py
index b2e020da2dc5287e14638e31702bb0fd32942a59..53fa0c40e0a6ad840025941f2c35ddd3aec4b0a1 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/EnhancedBiasChainConfiguration.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/EnhancedBiasChainConfiguration.py
@@ -3,7 +3,7 @@
 from TrigHypoCommonTools.TrigHypoCommonToolsConf import L1InfoHypo, L1InfoHypoTool
 
 from TriggerMenuMT.HLTMenuConfig.Menu.ChainConfigurationBase import ChainConfigurationBase
-from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import ChainStep, MenuSequence, RecoFragmentsPool
+from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence, RecoFragmentsPool
 from DecisionHandling.DecisionHandlingConf import InputMakerForRoI, ViewCreatorInitialROITool
 from AthenaCommon.CFElements import seqAND
 
@@ -84,22 +84,12 @@ def enhancedBiasAthSequence(ConfigFlags):
 
         return (enhancedBiasAthSequence, inputMakerAlg, enhancedBiasSequence)
 
-class EnhancedBiasChainConfiguration(ChainConfigurationBase):
-    def __init__(self, chainDict):
-        ChainConfigurationBase.__init__(self, chainDict)
-
-
-    def assembleChain(self):
-        chainSteps = []
-        log.debug("Assembling chain for " + self.chainName)
-
-        ebSeq = self.enhancedBiasMenuSequence()
-        chainSteps.append( ChainStep(name='Step1_EnhancedBias', Sequences=[ebSeq]) )
 
-        return self.buildChain(chainSteps)
+def enahncedBiasSequence_Cfg(flags):
+    return enhancedBiasMenuSequence()
 
 
-    def enhancedBiasMenuSequence(self):
+def enhancedBiasMenuSequence():
         # InputMaker and sequence
         (_, inputMakerAlg, enhancedBiasSequence) = RecoFragmentsPool.retrieve(enhancedBiasAthSequence, None)
 
@@ -123,3 +113,17 @@ class EnhancedBiasChainConfiguration(ChainConfigurationBase):
                             Maker       = inputMakerAlg,
                             Hypo        = hypoAlg,
                             HypoToolGen = EnhancedBiasHypoToolGen )
+
+
+class EnhancedBiasChainConfiguration(ChainConfigurationBase):
+    def __init__(self, chainDict):
+        ChainConfigurationBase.__init__(self, chainDict)
+
+
+    def assembleChain(self):
+        chainSteps = []
+        log.debug("Assembling chain for " + self.chainName)
+
+        chainSteps.append( self.getStep(1,"EnhancedBias", [enahncedBiasSequence_Cfg]) )
+
+        return self.buildChain(chainSteps)
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/MonitorChainConfiguration.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/MonitorChainConfiguration.py
index 404aa8e7ec49b8ffb111832e18a402195593ae27..97f82f80bc9c3ce9b4076ca13b085f2182eea23b 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/MonitorChainConfiguration.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/MonitorChainConfiguration.py
@@ -5,7 +5,7 @@ logging.getLogger().info("Importing %s",__name__)
 log = logging.getLogger("TriggerMenuMT.HLTMenuConfig.CalibCosmicMon.MonitorChainConfiguration")
 
 from TriggerMenuMT.HLTMenuConfig.Menu.ChainConfigurationBase import ChainConfigurationBase
-from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import ChainStep, MenuSequence
+from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence
 from DecisionHandling.DecisionHandlingConf import InputMakerForRoI, ViewCreatorInitialROITool
 from AthenaCommon.CFElements import seqAND
 from TrigGenericAlgs.TrigGenericAlgsConfig import TimeBurnerCfg, TimeBurnerHypoToolGen
@@ -15,6 +15,24 @@ from AthenaConfiguration.ComponentAccumulator import conf2toConfigurable
 # fragments generating configuration will be functions in New JO, 
 # so let's make them functions already now
 #----------------------------------------------------------------
+def TimeBurnerSequenceCfg(flags):
+        # Input maker - required by the framework, but inputs don't matter for TimeBurner
+        inputMaker = InputMakerForRoI("IM_TimeBurner")
+        inputMaker.RoITool = ViewCreatorInitialROITool()
+        inputMaker.RoIs="TimeBurnerInputRoIs"
+        inputMakerSeq = seqAND("TimeBurnerSequence", [inputMaker])
+
+        # TimeBurner alg works as a reject-all hypo
+        hypoAlg = conf2toConfigurable(TimeBurnerCfg())
+        hypoAlg.SleepTimeMillisec = 200
+
+        return MenuSequence(
+            Sequence    = inputMakerSeq,
+            Maker       = inputMaker,
+            Hypo        = hypoAlg,
+            HypoToolGen = TimeBurnerHypoToolGen)
+
+
 
 #----------------------------------------------------------------
 # Class to configure chain
@@ -45,21 +63,5 @@ class MonitorChainConfiguration(ChainConfigurationBase):
     # --------------------
     # TimeBurner configuration
     # --------------------
-    def getTimeBurnerStep(self):
-        # Input maker - required by the framework, but inputs don't matter for TimeBurner
-        inputMaker = InputMakerForRoI("IM_TimeBurner")
-        inputMaker.RoITool = ViewCreatorInitialROITool()
-        inputMaker.RoIs="TimeBurnerInputRoIs"
-        inputMakerSeq = seqAND("TimeBurnerSequence", [inputMaker])
-
-        # TimeBurner alg works as a reject-all hypo
-        hypoAlg = conf2toConfigurable(TimeBurnerCfg())
-        hypoAlg.SleepTimeMillisec = 200
-
-        seq = MenuSequence(
-            Sequence    = inputMakerSeq,
-            Maker       = inputMaker,
-            Hypo        = hypoAlg,
-            HypoToolGen = TimeBurnerHypoToolGen)
-
-        return ChainStep(name='Step1_TimeBurner', Sequences=[seq])
+    def getTimeBurnerStep(self):      
+        return self.getStep(1,'TimeBurner',[TimeBurnerSequenceCfg])
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/EventBuildingSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/EventBuildingSequenceSetup.py
index a64911614ac7f27304f3f7b71e4eb2b8e8973d8f..c9223001f7be982ae0a86ca46108f56ac9299855 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/EventBuildingSequenceSetup.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/EventBuildingSequenceSetup.py
@@ -14,7 +14,7 @@ from AthenaCommon.Logging import logging
 log = logging.getLogger('EventBuildingSequenceSetup')
 
 
-def addEventBuildingSequence(chain, eventBuildType):
+def addEventBuildingSequence(chain, eventBuildType, chainDict):
     '''
     Add an extra ChainStep to a Chain object with a PEBInfoWriter sequence configured for the eventBuildType
     '''
@@ -36,7 +36,7 @@ def addEventBuildingSequence(chain, eventBuildType):
         HypoToolGen = pebInfoWriterToolGenerator)
 
     step_name = 'Step{:d}_PEBInfoWriter_{:s}'.format(len(chain.steps)+1, eventBuildType)
-    step = ChainStep(name=step_name, Sequences=[seq])
+    step = ChainStep(name=step_name, Sequences=[seq], chainDicts=[chainDict])
     chain.steps.append(step)
 
 
@@ -163,4 +163,4 @@ def alignEventBuildingSteps(all_chains):
         if pebStepPosition < maxPebStepPosition[ebt]:
             numStepsNeeded = maxPebStepPosition[ebt] - pebStepPosition
             log.debug('Aligning PEB step for chain %s by adding %d empty steps', chainDict['chainName'], numStepsNeeded)
-            chainConfig.insertEmptySteps(chainDict,'EmptyPEBAlign', numStepsNeeded, pebStepPosition-1)
+            chainConfig.insertEmptySteps('EmptyPEBAlign', numStepsNeeded, pebStepPosition-1)
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Electron/generateElectron.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Electron/generateElectron.py
index 553fbbb9de38512dbbdf12b145a75a9c8620c9e3..213ae8b8304f12b10a05acab4b536a08245438f9 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Electron/generateElectron.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Electron/generateElectron.py
@@ -44,8 +44,9 @@ def generateChains( flags,  chainDict ):
                                      CA = accCalo)
 
     accCalo.printConfig()
-
+    # this cannot work for asymmetric combined chains....FP
     fastCaloStep = ChainStep(name=firstStepName, Sequences=[fastCaloSequence], chainDicts=[chainDict], multiplicity=getChainMultFromDict(chainDict))
+    
 
 
     secondStepName = 'ElectronFTF'
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainDictTools.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainDictTools.py
index eadbcb44b6f8147790f5877dd795f0f59c6655ad..8f92069262badb3f004d8fc5ffb218adced909b0 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainDictTools.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainDictTools.py
@@ -86,7 +86,7 @@ def splitInterSignatureChainDict(chainDict):
 
     return listOfSplitChainDicts
 
-# maybe obsolete?
+
 def splitChainDict(chainDict):
     listOfChainDicts = []
     for chainPart in chainDict['chainParts']:
@@ -95,10 +95,22 @@ def splitChainDict(chainDict):
         listOfChainDicts += [newChainDict]
     return listOfChainDicts
 
+def splitChainDictInLegs(chainDict):
+      from TrigCompositeUtils.TrigCompositeUtils import legName
+      if len(chainDict['chainParts']) ==1:
+            return [chainDict]
 
+      chainName= chainDict['chainName']
+      listOfChainDicts = []     
+      for count, chainDictPart in enumerate(chainDict['chainParts']):
+            onePartChainDict = deepcopy( chainDict )
+            onePartChainDict['chainParts'] = [ chainDictPart ]
+            onePartChainDict['chainName'] = legName(chainName, count)            
+            listOfChainDicts += [onePartChainDict]
+      return listOfChainDicts
 
 
-def splitChainInDict(chainName):
+def splitChainInLegs(chainName):
       from TriggerMenuMT.HLTMenuConfig.Menu.TriggerConfigHLT import TriggerConfigHLT
       from TrigCompositeUtils.TrigCompositeUtils import legName
       chainDict = TriggerConfigHLT.getChainDictFromChainName(chainName)
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py
index 9b9ee59d0ae2c7b5fc795089f19771fbfaea73e8..d0e5832554b1a68d3b789f5b7700bce9641be7eb 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py
@@ -140,7 +140,7 @@ def serial_zip(allSteps, chainName, chainDefList):
                 if emptyStep is None:
                     seqName = getEmptySeqName(step.name, chain_index, step_index+1, chainDefList[0].alignmentGroups[0])
                     emptySeq =  RecoFragmentsPool.retrieve(getEmptyMenuSequence, flags=None, name=seqName)
-                    stepList[step_index2] = ChainStep( seqName, Sequences=[emptySeq], chainDicts=step.chainDicts)            
+                    stepList[step_index2] = ChainStep( seqName, Sequences=[emptySeq], chainDicts=step.stepDicts)            
             
             newsteps.append(stepList)
     log.debug('After serial_zip')
@@ -219,7 +219,7 @@ def makeCombinedStep(steps, stepNumber, chainDefList):
             stepSeq.append(emptySeq)
             stepMult.append(1)
             # we need a chain dict here, use the one corresponding to this leg of the chain
-            stepDicts.append(deepcopy(chainDefList[chain_index].steps[-1].chainDicts[-1]))
+            stepDicts.append(deepcopy(chainDefList[chain_index].steps[-1].stepDicts[-1]))
         else:
             # Standard step, append it to the combined step
             log.debug("  step %s, multiplicity  = %s", step.name, str(step.multiplicity))
@@ -242,7 +242,7 @@ def makeCombinedStep(steps, stepNumber, chainDefList):
             stepMult.append(sum(step.multiplicity))
             comboHypoTools.extend(step.comboToolConfs)
             # update the chain dict list for the combined step with the chain dict from this step
-            stepDicts += deepcopy(step.chainDicts)
+            stepDicts += deepcopy(step.stepDicts)
 
 
         # the step naming for combined chains needs to be revisted!!
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/DictFromChainName.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/DictFromChainName.py
index 0b03fa560f1eed361c666d2825532ae775b5d55e..057d6f7eef225344288f6875251663b97bbdf2ca 100755
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/DictFromChainName.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/DictFromChainName.py
@@ -148,6 +148,7 @@ def getChainMultFromDict(chainDict):
     Look for all multiplicities stored in chains
     """
     allMultis = []
+   
     for cpart in chainDict['chainParts']:
         if cpart['multiplicity'] != '':
             allMultis.append( int(cpart['multiplicity']))
@@ -230,6 +231,7 @@ def analyseChainName(chainName, L1thresholds, L1item):
                      'trigType': sigToken, 'extra': ''}
         mdicts.append( groupdict )
 
+       
     log.debug("chain parts: %s", cparts)
     for cpart in cparts:
 
@@ -252,13 +254,13 @@ def analyseChainName(chainName, L1thresholds, L1item):
                 if theMultiChainIndex not in multichainindex:
                     multichainindex.append(theMultiChainIndex)
 
-            log.debug("HLTChainName: %s", hltChainName)
-            log.debug("HLTChainNameShort: %s", hltChainNameShort)
-            log.debug("cpart: %s", cpart)
-            log.debug("groupdict: %s", groupdict)
-            log.debug("multichainindex: %s", multichainindex)
+                    log.debug("HLTChainName: %s", hltChainName)
+                    log.debug("HLTChainNameShort: %s", hltChainNameShort)
+                    log.debug("cpart: %s", cpart)
+                    log.debug("groupdict: %s", groupdict)
+                    log.debug("multichainindex: %s", multichainindex)
 
-            sName = getSignatureNameFromToken(cpart)
+                sName = getSignatureNameFromToken(cpart)
             
             groupdict['signature'] = sName
             groupdict['alignmentGroup'] = getAlignmentGroupFromPattern(sName, groupdict['extra'])
@@ -501,7 +503,7 @@ def dictFromChainName(chainInfo):
         mergingOffset   = chainInfo.mergingOffset
         mergingOrder    = chainInfo.mergingOrder
         topoStartFrom   = chainInfo.topoStartFrom
-
+        
     else:
         assert True, "Format of chainInfo passed to genChainDict not known"
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py
index f60279990189dfce42b2952e8bdb11ceb9b74a9e..e67017394db74b71353750ba8319288a414aba0f 100755
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py
@@ -460,7 +460,7 @@ class GenerateMenuMT(object):
         eventBuildType = mainChainDict['eventBuildType']
         if eventBuildType:
             log.debug('Configuring event building sequence %s for chain %s', eventBuildType, mainChainDict['chainName'])
-            EventBuildingSequenceSetup.addEventBuildingSequence(theChainConfig, eventBuildType)
+            EventBuildingSequenceSetup.addEventBuildingSequence(theChainConfig, eventBuildType, mainChainDict)
 
         log.debug('ChainConfigs  %s ', theChainConfig)
         return theChainConfig,lengthOfChainConfigs
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTCFConfig.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTCFConfig.py
index 8cb1cb454e15cb34937d47a02aa9895b36a8e518..ec70259e6dde23460acb921ae7180c127533f1fd 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTCFConfig.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTCFConfig.py
@@ -377,10 +377,11 @@ def createDataFlow(chains, allDicts):
         log.debug("\n Configuring chain %s with %d steps: \n   - %s ", chain.name,len(chain.steps),'\n   - '.join(map(str, [{step.name:step.multiplicity} for step in chain.steps])))
 
         lastCFseq = None
+        lastDecisions = []
         for nstep, chainStep in enumerate( chain.steps ):
             log.debug("\n************* Start connecting step %d %s for chain %s", nstep+1, chainStep.name, chain.name)
 
-            filterInput = chain.L1decisions if nstep == 0 else lastCFseq.decisions
+            filterInput = chain.L1decisions if nstep == 0 else lastDecisions
             log.debug("Seeds added; having in the filter now: %s", filterInput)
 
 
@@ -392,8 +393,9 @@ def createDataFlow(chains, allDicts):
             sequenceFilter= None
             filterName = CFNaming.filterName(chainStep.name)
             filterOutput =[ CFNaming.filterOutName(filterName, inputName) for inputName in filterInput ]
-            log.debug("Filter outputps: %s", filterOutput)
+#            log.debug("Filter outputps: %s", filterOutput)
 
+# note: can use 
             (foundFilter, foundCFSeq) = findCFSequences(filterName, CFseqList[nstep])
             log.debug("Found %d CF sequences with filter name %s", foundFilter, filterName)
              # add error if more than one
@@ -402,23 +404,28 @@ def createDataFlow(chains, allDicts):
                 CFseq = CFSequence( ChainStep=chainStep, FilterAlg=sequenceFilter)
                 CFseq.connect(filterOutput)
                 CFseqList[nstep].append(CFseq)
+                lastDecisions=CFseq.decisions
                 lastCFseq=CFseq
             else:
                 if len(foundCFSeq) > 1:
                     log.error("Found more than one seuqences containig this filter %s", filterName)
                 lastCFseq=foundCFSeq[0]
                 sequenceFilter=lastCFseq.filter
-                lastCFseq.connect(filterOutput)
+                #lastCFseq.connect(filterOutput)
                 [ sequenceFilter.addInput(inputName) for inputName in filterInput ]
                 [ sequenceFilter.addOutput(outputName) for outputName in  filterOutput ]
-
+                lastCFseq.connect(filterOutput)
+                if chainStep.isEmpty:
+                    lastDecisions=filterOutput
+                else:
+                    lastDecisions=lastCFseq.decisions
 
             # add chains to the filter:
-            chainLegs = chain.getChainLegs()
+            chainLegs = chainStep.getChainLegs()
             for leg in chainLegs:
                 sequenceFilter.addChain(leg)
                 log.debug("Adding chain %s to %s", leg, sequenceFilter.Alg.name())
-            log.debug("Now Filter has chains: %s", sequenceFilter.getChains())
+#            log.debug("Now Filter has chains: %s", sequenceFilter.getChains())
 
             if chainStep.isCombo:
                 if chainStep.combo is not None:
@@ -427,7 +434,7 @@ def createDataFlow(chains, allDicts):
 
             if len(chain.steps) == nstep+1:
                 log.debug("Adding finalDecisions for chain %s at step %d:", chain.name, nstep+1)
-                for dec in lastCFseq.decisions:
+                for dec in lastDecisions:
                     finalDecisions[nstep].append(dec)
                     log.debug(dec)
                     
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTCFConfig_newJO.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTCFConfig_newJO.py
index 7e2c2389efc8c8dfc386cab8cd3f4743a90455b4..2e2d2bd671a390eb29e6e4dcf9fcfd7ec8339eba 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTCFConfig_newJO.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTCFConfig_newJO.py
@@ -4,7 +4,7 @@ from AthenaCommon.CFElements import findAllAlgorithms, parOR, seqAND, isSequence
 from AthenaCommon.Logging import logging
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
-from TriggerMenuMT.HLTMenuConfig.Menu.ChainDictTools import splitChainInDict
+from TriggerMenuMT.HLTMenuConfig.Menu.ChainDictTools import splitChainInLegs
 from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import (isComboHypoAlg,
                                                              isFilterAlg,
                                                              isHypoAlg,
@@ -380,8 +380,8 @@ def generateDecisionTree(chains):
                     hypoAlg.HypoTools.append( step.sequences[sequenceCounter]._hypoToolConf.confAndCreate( chainDict ) )
                 pass
 
-            chainDictLegs = splitChainInDict( chain.name )
-            # possible cases: A) number of seqeunces == number of chain parts, e5_mu10 or just e3 type of chain
+            chainDictLegs = splitChainInLegs( chain.name )
+            # possible cases: A) number of seqeunces == number of chain parts, e5_mu10 or just e3 type of chain 
             # ([0, 1], [0, 1]) is the set of indices
             indices = zip( range( len( step.sequences ) ), range( len( chainDictLegs ) ) )# case A
             # B) number of sequences == 1 && number of chain parts > 1 for single signature assymetric combined chains e5_e3 type chain
@@ -408,6 +408,7 @@ def generateDecisionTree(chains):
                     for comboToolConf in step.comboToolConfs:
                         comboHypoAlg.ComboHypoTools.append( comboToolConf.confAndCreate( TriggerConfigHLT.getChainDictFromChainName( chain.name ) ) )
 
+
     for chain in chains:
         log.info( "CF algorithms for chain {}".format(chain.name))
         for stepCounter, step in enumerate( chain.steps, 1 ):
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTCFDot.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTCFDot.py
index 4b26e7a96473f90d660f5bee971a6cf489dd24a7..2838ac1a876a5269941d0219d877fbffd84c4ffa 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTCFDot.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTCFDot.py
@@ -139,7 +139,9 @@ def all_DataFlow_to_dot(name, step_list):
                 file.write('  }\n')              
                 file.write(findConnections(cfseq_algs))
                 file.write('\n')
-               
+
+#            print ("Step connections: ")
+#            print (step_connections)
             file.write(findConnections(step_connections))
             nstep+=1
 
@@ -208,7 +210,7 @@ def findConnections(alg_list):
         if len(dataIntersection) > 0:
             for line in dataIntersection:
                 lineconnect+=addConnection(compName(nodeA.Alg), compName(nodeB.Alg), line)
-#                print "Data connections between %s and %s: %s"%(nodeA.Alg.getName(), nodeB.Alg.getName(), line)
+#                print ("Data connections between ", compName(nodeA.Alg)," and ",compName(nodeB.Alg) ,": ", line)
 
     return lineconnect
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTMenuJSON.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTMenuJSON.py
index 974b487c5df17f95abf8a3a1861408e7b16e7f1d..c3503455125a5bac748dce4e4cd420730b8f0243 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTMenuJSON.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTMenuJSON.py
@@ -95,6 +95,7 @@ def __generateJSON( chainDicts, chainConfigs, HLTAllSteps, menuName, fileName ):
 
         # Find L1 Threshold information for current chain
         l1Thresholds  = []
+        
         [ l1Thresholds.append(p['L1threshold']) for p in chain['chainParts'] ]
 
         # Now have all information to write the chain to the menu dictionary
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_emu_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_emu_v1.py
index ff1bf431be0d9fca50faa4faba99600170e95b2d..76de91628711dbf65ed6846589f2c1bfc8eb136d 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_emu_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_emu_v1.py
@@ -43,15 +43,15 @@ def setupMenu():
         ChainProp(name='HLT_TestChain5_gv1_L1EM7', stream=['Main'], groups=['RATE:Test','BW:Other'] ),
 
         # combined
-        ChainProp(name='HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5', stream=['Main'], groups=['RATE:Test','BW:Other'], mergingStrategy = 'parallel' ),         
-        ChainProp(name='HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5',  stream=['Main'], groups=['RATE:Test','BW:Other'], mergingStrategy = 'parallel' ),
+        ChainProp(name='HLT_TestChain6_muv1_TestChain10_ev1_L1MU6_EM5', stream=['Main'], groups=['RATE:Test','BW:Other'], mergingStrategy = 'parallel'), 
+        ChainProp(name='HLT_TestChain6_muv2_TestChain8_ev2_L1MU6_EM5',  stream=['Main'], groups=['RATE:Test','BW:Other'], mergingStrategy = 'parallel'),
         ChainProp(name='HLT_TestChain5_ev1_TestChain8_ev1_L12EM3',      stream=['Main'], groups=['RATE:Test','BW:Other'], mergingStrategy = 'parallel'),
 #        ChainProp(name='HLT_TestChain5_ev1_TestChain8_ev1_2TestChain6_muv1_L1EM3_L1EM5_L12MU6', stream=['Main'], groups=['RATE:Test','BW:Other']   ),
         ChainProp(name='HLT_2TestChain6_muv1_L12MU6',                   stream=['Main'], groups=['RATE:Test','BW:Other']   ),
         ChainProp(name='HLT_3TestChain6_muv1_L12MU6',                   stream=['Main'], groups=['RATE:Test','BW:Other']   ),
-        ChainProp(name='HLT_TestChain6_muv1_TestChain10_muv1_L12MU6',   stream=['Main'], groups=['RATE:Test','BW:Other'], mergingStrategy = 'parallel'  ),        
-        ChainProp(name='HLT_2TestChain6_muEmpty1_L12MU6',               stream=['Main'], groups=['RATE:Test','BW:Other'], mergingStrategy = 'parallel'), #may differ from manual
-        ChainProp(name='HLT_TestChain6_muv1_TestChain5_ev1dr_L1MU6_EM5',   stream=['Main'], groups=['RATE:Test','BW:Other'], mergingStrategy = 'parallel' ), 
+        ChainProp(name='HLT_TestChain6_muv1_TestChain10_muv1_L12MU6',   stream=['Main'], groups=['RATE:Test','BW:Other'], mergingStrategy = 'parallel' ),        
+        ChainProp(name='HLT_2TestChain6_muEmpty1_L12MU6',               stream=['Main'], groups=['RATE:Test','BW:Other']), #may differ from manual
+        ChainProp(name='HLT_TestChain6_muv1_TestChain5_ev1dr_L1MU6_EM5',   stream=['Main'], groups=['RATE:Test','BW:Other'], mergingStrategy = 'parallel'), 
         ChainProp(name='HLT_2TestChain4_muv1dr_L12MU6', stream=['Main'], groups=['RATE:Test','BW:Other'] ),
 
         # FSNOSEED not implemented in emulation
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
index d37f57a5f7b8930a357ddf471133f372d262d4d1..a3fa68e0d9546f67975f3b084027778aac91cdbe 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
@@ -13,7 +13,8 @@ from TriggerMenuMT.HLTMenuConfig.Menu.ChainDefInMenu import ChainProp
 import TriggerMenuMT.HLTMenuConfig.Menu.MC_pp_run3_v1 as mc_menu
 import TriggerMenuMT.HLTMenuConfig.Menu.PhysicsP1_pp_run3_v1 as p1_menu
 
-from TriggerMenuMT.HLTMenuConfig.Menu.Physics_pp_run3_v1 import PhysicsStream,SingleMuonGroup,MultiMuonGroup,SingleElectronGroup,MultiElectronGroup,SinglePhotonGroup,MultiPhotonGroup,SingleMETGroup,MultiMETGroup,SingleJetGroup,MultiJetGroup,SingleBjetGroup,SingleTauGroup,MultiTauGroup,BphysicsGroup,MinBiasGroup
+# this is not the best option, due to flake violation, this list has to be changed when some groups are removed
+from TriggerMenuMT.HLTMenuConfig.Menu.Physics_pp_run3_v1 import PhysicsStream,SingleMuonGroup,MultiMuonGroup,SingleElectronGroup,MultiElectronGroup,SinglePhotonGroup,MultiPhotonGroup,SingleMETGroup,MultiMETGroup,SingleJetGroup,MultiJetGroup,SingleBjetGroup,SingleTauGroup,MultiTauGroup,BphysicsGroup,EgammaMuonGroup,MuonJetGroup,MuonMETGroup 
 
 def setupMenu():
 
@@ -34,6 +35,9 @@ def setupMenu():
         ChainProp(name='HLT_mu6_mu6noL1_L1MU6', l1SeedThresholds=['MU6','FSNOSEED'], groups=MultiMuonGroup),
         ChainProp(name='HLT_mu20_ivarmedium_mu8noL1_L1MU20', l1SeedThresholds=['MU20','FSNOSEED'], groups=MultiMuonGroup),
 
+        #ATR-22107
+        ChainProp(name='HLT_mu20_ivarmedium_mu4noL1_10invm70_L1MU20', l1SeedThresholds=['MU20','FSNOSEED'], groups=MultiMuonGroup),
+
         #test chains
         ChainProp(name='HLT_mu6_L1MU6',     groups=SingleMuonGroup),
 
@@ -353,15 +357,15 @@ def setupMenu():
     TriggerFlags.CombinedSlice.signatures = TriggerFlags.CombinedSlice.signatures() + [
         # groups need to be properly assigned here later
         # Primary e-mu chains
-        ChainProp(name='HLT_e17_lhloose_mu14_L1EM15VH_MU10', l1SeedThresholds=['EM15VH','MU10'], stream=[PhysicsStream], groups=MultiElectronGroup),
-        ChainProp(name='HLT_e7_lhmedium_mu24_L1MU20',l1SeedThresholds=['EM3','MU20'],  stream=[PhysicsStream], groups=MultiElectronGroup),
-        ChainProp(name='HLT_e12_lhloose_2mu10_L12MU10', l1SeedThresholds=['EM8VH','MU10'], stream=[PhysicsStream], groups=MultiElectronGroup),
-        ChainProp(name='HLT_2e12_lhloose_mu10_L12EM8VH_MU10', l1SeedThresholds=['EM8VH','MU10'], stream=[PhysicsStream], groups=MultiElectronGroup),
+        ChainProp(name='HLT_e17_lhloose_mu14_L1EM15VH_MU10', l1SeedThresholds=['EM15VH','MU10'], stream=[PhysicsStream], groups=EgammaMuonGroup),
+        ChainProp(name='HLT_e7_lhmedium_mu24_L1MU20',l1SeedThresholds=['EM3','MU20'],  stream=[PhysicsStream], groups=EgammaMuonGroup),
+        ChainProp(name='HLT_e12_lhloose_2mu10_L12MU10', l1SeedThresholds=['EM8VH','MU10'], stream=[PhysicsStream], groups=EgammaMuonGroup),
+        ChainProp(name='HLT_2e12_lhloose_mu10_L12EM8VH_MU10', l1SeedThresholds=['EM8VH','MU10'], stream=[PhysicsStream], groups=EgammaMuonGroup),
 
         # Primary g-mu chains
-        ChainProp(name='HLT_g25_medium_mu24_ivarmedium_L1MU20',l1SeedThresholds=['EM15VH','MU20'], stream=[PhysicsStream], groups=MultiElectronGroup),
-        ChainProp(name='HLT_g35_loose_mu18_L1EM24VHI', l1SeedThresholds=['EM24VHI','MU10'], stream=[PhysicsStream], groups=MultiElectronGroup),
-        ChainProp(name='HLT_2g10_loose_mu20_L1MU20', l1SeedThresholds=['EM7','MU20'], stream=[PhysicsStream], groups=MultiElectronGroup), # unsure what EM seed should be    
+        ChainProp(name='HLT_g25_medium_mu24_ivarmedium_L1MU20',l1SeedThresholds=['EM15VH','MU20'], stream=[PhysicsStream], groups=EgammaMuonGroup),
+        ChainProp(name='HLT_g35_loose_mu18_L1EM24VHI', l1SeedThresholds=['EM24VHI','MU10'], stream=[PhysicsStream], groups=EgammaMuonGroup),
+        ChainProp(name='HLT_2g10_loose_mu20_L1MU20', l1SeedThresholds=['EM7','MU20'], stream=[PhysicsStream], groups=EgammaMuonGroup), # unsure what EM seed should be
 
         # Primary e-g chains: electron + photon stay in the same step - these need to be parallel merged!
         # test
@@ -371,8 +375,15 @@ def setupMenu():
         ChainProp(name='HLT_e24_lhmedium_2g12_loose_L1EM20VH_3EM10VH', l1SeedThresholds=['EM20VH','EM10VH'], stream=[PhysicsStream], groups=MultiElectronGroup), # unsure about l1SeedThresholds
 
         # Test chains for muon + jet/MET merging/aligning
-        ChainProp(name='HLT_mu6_xe30_mht_L1XE10', l1SeedThresholds=['MU6','XE10'], stream=[PhysicsStream], groups=SingleMETGroup),
-        ChainProp(name='HLT_mu6_j45_nojcalib_L1J20', l1SeedThresholds=['MU6','J20'], stream=[PhysicsStream], groups=SingleMETGroup),    
+        ChainProp(name='HLT_mu6_xe30_mht_L1XE10', l1SeedThresholds=['MU6','XE10'], stream=[PhysicsStream], groups=MuonMETGroup),
+        ChainProp(name='HLT_mu6_j45_nojcalib_L1J20', l1SeedThresholds=['MU6','J20'], stream=[PhysicsStream], groups=MuonJetGroup),
+
+        #ATR-22107
+        ChainProp(name='HLT_e26_lhmedium_mu8noL1_L1EM22VHI', l1SeedThresholds=['EM22VHI','FSNOSEED'], stream=[PhysicsStream], groups=EgammaMuonGroup),
+#        ChainProp(name='HLT_e9_lhvloose_mu20_mu8noL1_L1MU20', l1SeedThresholds=['EM3','MU20','FSNOSEED'], stream=[PhysicsStream], groups=EgammaMuonGroup),
+#        ChainProp(name='HLT_g35_loose_mu15_mu2noL1_L1EM22VHI', l1SeedThresholds=['EM22VHI','MU6','FSNOSEED'], stream=[PhysicsStream], groups=EgammaMuonGroup),
+        ChainProp(name='HLT_g35_tight_icalotight_mu18noL1_L1EM22VHI', l1SeedThresholds=['EM22VHI','FSNOSEED'], stream=[PhysicsStream], groups=EgammaMuonGroup),
+        #        ChainProp(name='HLT_g35_tight_icalotight_mu15noL1_mu2noL1_L1EM22VHI', l1SeedThresholds=['EM22VHI','FSNOSEED','FSNOSEED'], stream=[PhysicsStream], groups=EgammaMuonGroup),
     
     ]
     TriggerFlags.HeavyIonSlice.signatures  = TriggerFlags.HeavyIonSlice.signatures() + []
@@ -392,8 +403,6 @@ def setupMenu():
     TriggerFlags.StreamingSlice.signatures = TriggerFlags.StreamingSlice.signatures() + [
         #ChainProp(name='HLT_noalg_mb_L1RD2_EMPTY', l1SeedThresholds=['FSNOSEED'], stream=['MinBias'], groups=MinBiasGroup),
         #ChainProp(name='HLT_noalg_zb_L1ZB', l1SeedThresholds=['FSNOSEED'], stream=['ZeroBias'], groups=ZeroBiasGroup),
-        ChainProp(name='HLT_noalg_L1MBTS_2_EMPTY', l1SeedThresholds=['FSNOSEED'], stream=['MinBias'], groups=MinBiasGroup), #ATR-21999
-        ChainProp(name='HLT_noalg_L1MBTS_1_1_EMPTY', l1SeedThresholds=['FSNOSEED'], stream=['MinBias'], groups=MinBiasGroup), #ATR-21999
         ChainProp(name='HLT_noalg_L1All', l1SeedThresholds=['FSNOSEED'], stream=[PhysicsStream], groups=['RATE:SeededStreamers', 'BW:Other']), # ATR-22072, for rates in MC. To move to MC menu once good nightly in LS2_v1.
     ]
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1_newJO.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1_newJO.py
index 0a7a417ca28766c2c0236b7cb09d5f18ba3bc273..1e95b4e6f7087133c734d574701bb0ba72279945 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1_newJO.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1_newJO.py
@@ -52,7 +52,8 @@ def setupMenu(flags):
     flags.Trigger.menu.electron = [
         ChainProp(name='HLT_e3_etcut_L1EM3', groups=SingleElectronGroup),
         ChainProp(name='HLT_2e3_etcut_L12EM3', groups=MultiElectronGroup),
-        ChainProp(name='HLT_e5_etcut_e3_etcut_L12EM3', groups=MultiElectronGroup),
+# this chain does not work yet        
+   #     ChainProp(name='HLT_e5_etcut_e3_etcut_L12EM3', groups=MultiElectronGroup),
         ChainProp(name='HLT_e5_etcut_L1EM3', groups=SingleElectronGroup),
         ChainProp(name='HLT_e7_etcut_L1EM7', groups=SingleElectronGroup)
     ]
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuAlignmentTools.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuAlignmentTools.py
index 7ec9ed562c2443cdfac1903a93f97c90249aabdc..4ec9960baa200040c759335b03260a11aeff39fd 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuAlignmentTools.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuAlignmentTools.py
@@ -193,7 +193,7 @@ class MenuAlignment():
         aligngroups_set.reverse()
                       
         for align_grp_to_align in aligngroups_set:
-            chainConfig.insertEmptySteps(chainDict,'Empty'+align_grp_to_align+'Align',self.length_of_configs[align_grp_to_align],0)         
+            chainConfig.insertEmptySteps('Empty'+align_grp_to_align+'Align',self.length_of_configs[align_grp_to_align],0)         
             log.debug("Finished with retrieving chain configuration for chain %s", chainDict['chainName'])
             chainConfig.numberAllSteps()
 
@@ -233,7 +233,7 @@ class MenuAlignment():
            if length_firstgrp < max_length_firstgrp:
                #too short! need to add padding steps between two alignment groups...
                needed_steps = max_length_firstgrp - length_firstgrp
-               chainConfig.insertEmptySteps(chainDict,'Empty'+self.sets_to_align[alignment_grps[0]][0]+'Align',needed_steps,length_firstgrp) 
+               chainConfig.insertEmptySteps('Empty'+self.sets_to_align[alignment_grps[0]][0]+'Align',needed_steps,length_firstgrp) 
       
            elif length_firstgrp > max_length_firstgrp:
                log.error("%s first signature length %d is greater than the max calculated, %d",chainDict.name,length_firstgrp, max_length_firstgrp)     
@@ -279,11 +279,11 @@ class MenuAlignment():
                         #too short! gotta add padding steps between two alignmentGroups...
                         needed_steps = max_length_grp - length_in_chain
                         start_step = n_steps_before_grp + length_in_chain
-                        chainConfig.insertEmptySteps(chainDict,'Empty'+align_grp+'Align',needed_steps,start_step) 
+                        chainConfig.insertEmptySteps('Empty'+align_grp+'Align',needed_steps,start_step) 
                 else:
                     # this sig isn't in the chain, but we still will need empty steps for it
                     # always add them to the start, because we're running in reverse order
-                    chainConfig.insertEmptySteps(chainDict,'Empty'+align_grp+'Align',self.length_of_configs[align_grp],n_steps_before_grp) 
+                    chainConfig.insertEmptySteps('Empty'+align_grp+'Align',self.length_of_configs[align_grp],n_steps_before_grp) 
         else:
              log.error("Should never reach this point. alignmentGroups: %s, sets_to_align: %s",alignment_grps,self.sets_to_align)
              raise Exception("MenuAlignment.multi_align() needs checking, this should never happen.")
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
index a03c5f1820fec691f667ea407ef5aef7a004a304..f21f12636640ad92e714ccb80070a4d5b16974ce 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
@@ -176,8 +176,6 @@ class HypoAlgNode(AlgNode):
             log.error("Hypo " + self.name +" has already %s as configured output: you may want to duplicate the Hypo!" + outputs[0])
 
 
-
-
     def addHypoTool (self, hypoToolConf):
         log.debug("   Adding HypoTool %s to %s", hypoToolConf.chainDict['chainName'], compName(self.Alg))
         if hypoToolConf.chainDict['chainName'] not in self.tools:
@@ -274,14 +272,16 @@ class ComboMaker(AlgNode):
 
 
     def createComboHypoTools(self, chainDict, comboToolConfs):
-        """Created the ComboHypoTools"""
-        if not len(comboToolConfs):
-            return
-        confs = [ HypoToolConf( tool ) for tool in comboToolConfs ]
-        log.debug("ComboMaker.createComboHypoTools for chain %s, Alg %s with %d tools", chainDict["chainName"],self.Alg.getName(), len(comboToolConfs))        
-        for conf in confs:
-            tools = self.Alg.ComboHypoTools
-            self.Alg.ComboHypoTools = tools + [ conf.confAndCreate( chainDict ) ]
+         """Created the ComboHypoTools"""
+         if not len(comboToolConfs):
+             return
+         confs = [ HypoToolConf( tool ) for tool in comboToolConfs ]
+         log.debug("ComboMaker.createComboHypoTools for chain %s, Alg %s with %d tools", chainDict["chainName"],self.Alg.getName(), len(comboToolConfs))        
+         for conf in confs:
+             tools = self.Alg.ComboHypoTools
+             self.Alg.ComboHypoTools = tools + [ conf.confAndCreate( chainDict ) ]
+ 
+   
 
 
 #########################################################
@@ -531,6 +531,7 @@ class Chain(object):
         self.alignmentGroups = alignmentGroups
         self.vseeds=L1Thresholds
 
+
         from L1Decoder.L1DecoderConfig import mapThresholdToL1DecisionCollection
         # L1decisions are used to set the seed type (EM, MU,JET), removing the actual threshold
         # in practice it is the L1Decoder Decision output
@@ -558,7 +559,7 @@ class Chain(object):
                 step.name = 'Step%d_'%(stepID+1)+step_name
         return
 
-    def insertEmptySteps(self, chainDict, empty_step_name, n_new_steps, start_position):
+    def insertEmptySteps(self, empty_step_name, n_new_steps, start_position):
         #start position indexed from 0. if start position is 3 and length is 2, it works like:
         # [old1,old2,old3,old4,old5,old6] ==> [old1,old2,old3,empty1,empty2,old4,old5,old6]
         import re
@@ -575,24 +576,29 @@ class Chain(object):
 
         next_step_name = ''
         prev_step_name = ''
+        # copy the same dictionary as the last step, which else?
+        prev_chain_dict = []
         if start_position == 0:
             next_step_name = chain_steps_post_split[0].name
             if re.search('^Step[0-9]_',next_step_name):
                 next_step_name = next_step_name[6:]
             prev_step_name = 'empty_'+str(len(self.L1decisions))+'L1in'
+            prev_chain_dict = chain_steps_post_split[0].stepDicts
         else:
             if len(chain_steps_post_split) == 0:
                 log.error("Adding empty steps to the end of a chain - why would you do this?")
             else:
                 prev_step_name = chain_steps_pre_split[-1].name
                 next_step_name = chain_steps_post_split[0].name
+            prev_chain_dict = chain_steps_pre_split[-1].stepDicts
+
 
         steps_to_add = []
         for stepID in range(1,n_new_steps+1):
             new_step_name =  prev_step_name+'_'+empty_step_name+'%d_'%stepID+next_step_name
 
             log.debug("Configuring empty step " + new_step_name)
-            steps_to_add += [ChainStep(new_step_name, [], [], [chainDict], comboHypoCfg=ComboHypoCfg)]
+            steps_to_add += [ChainStep(new_step_name, [], [], chainDicts=prev_chain_dict, comboHypoCfg=ComboHypoCfg)]
         
         self.steps = chain_steps_pre_split + steps_to_add + chain_steps_post_split
 
@@ -628,58 +634,21 @@ class Chain(object):
                     seq.setSeed( seed )
                     log.debug( "setSeedsToSequences: Chain %s adding seed %s to sequence in step %s", self.name, seed, step.name )
 
-    def getChainLegs(self):
-        """ This is extrapolating the chain legs from the chain dictionary"""
-        from TriggerMenuMT.HLTMenuConfig.Menu.ChainDictTools import splitChainInDict
-        listOfChainDictsLegs = splitChainInDict(self.name)
-        legs = [part['chainName'] for part in listOfChainDictsLegs]      
-        return legs
-
-
+    
     def createHypoTools(self):
         """ This is extrapolating the hypotool configuration from the chain name"""
-        log.debug("createHypoTools for chain %s", self.name)
-        from TriggerMenuMT.HLTMenuConfig.Menu.ChainDictTools import splitChainInDict
-
-        # this spliting is only needed for chains which don't yet attach
-        # the dictionaries to the chain steps. It should be removed
-        # later once that migration is done.
-        listOfChainDictsLegs = splitChainInDict(self.name)
+        log.debug("createHypoTools for chain %s", self.name)        
+        
         for step in self.steps:
-            log.debug("createHypoTools for Step %s", step.name)
             if len(step.sequences) == 0:
                 continue
-            
-            if sum(step.multiplicity) >1 and not step.isCombo:
-                log.error("This should be an error, because step mult > 1 (%d), but step is not combo", sum(step.multiplicity))
-
-            if len(step.chainDicts) > 0:
-                # new way to configure hypo tools, works if the chain dictionaries have been attached to the steps
-                log.debug('%s in new hypo tool creation method, step mult= %d, isCombo=%d', self.name, sum(step.multiplicity), step.isCombo)
-                log.debug("N(seq)=%d, N(chainDicts)=%d", len(step.sequences), len(step.chainDicts))
-
-                assert len(step.sequences)==len(step.chainDicts), "createHypoTools only makes sense if number of sequences == number of chain dicts"
-                for seq, onePartChainDict in zip(step.sequences, step.chainDicts):
-                    log.debug('    seq: %s, onePartChainDict:', seq.name)
-                    log.debug('    ' + str(onePartChainDict))
-                    seq.createHypoTools( onePartChainDict )              
-
-            else:
-                # legacy way, to be removed once all signatures pass the chainDicts to the steps
-                step_mult = [str(m) for m in step.multiplicity]
-                log.debug('%s in old hypo tool creation method', self.name)
-                menu_mult = [ part['chainParts'][0]['multiplicity'] for part in listOfChainDictsLegs ]
-                if step_mult != menu_mult:
-                    # Probably this shouldn't happen, but it currently does
-                    log.warning("Got multiplicty %s from chain parts, but have %s multiplicity in this step. This is expected only for jet chains, but it has happened for %s, using the first chain dict", menu_mult, step.multiplicity, self.name)
-                    firstChainDict = listOfChainDictsLegs[0]
-                    firstChainDict['chainName']= self.name # rename the chaindict to remove the leg name
-                    for seq in step.sequences:
-                        seq.createHypoTools( firstChainDict )
-                else:
-                    # add one hypotool per sequence and chain part
-                    for seq, onePartChainDict in zip(step.sequences, listOfChainDictsLegs):
-                        seq.createHypoTools( onePartChainDict )
+            log.debug("createHypoTools for Step %s", step.name)
+            log.debug('%s in new hypo tool creation method, step mult= %d, isCombo=%d', self.name, sum(step.multiplicity), step.isCombo)
+            log.debug("N(seq)=%d, N(chainDicts)=%d", len(step.sequences), len(step.stepDicts))
+            for seq, onePartChainDict in zip(step.sequences, step.stepDicts):
+                log.debug('    seq: %s, onePartChainDict:', seq.name)
+                log.debug('    ' + str(onePartChainDict))
+                seq.createHypoTools( onePartChainDict )
 
             step.createComboHypoTools(self.name) 
 
@@ -773,6 +742,7 @@ class StepComponent(object):
         self.multiplicity=multiplicity
         self.empty=empty
 
+# next:  can we remove multiplicity array, if it can be retrieved from the ChainDict?
 class ChainStep(object):
     """Class to describe one step of a chain; if multiplicity is greater than 1, the step is combo/combined.  Set one multiplicity value per sequence"""
     def __init__(self, name,  Sequences=[], multiplicity=[1], chainDicts=[], comboHypoCfg=ComboHypoCfg, comboToolConfs=[]):
@@ -780,24 +750,27 @@ class ChainStep(object):
         # include cases of emtpy steps with multiplicity = [] or multiplicity=[0,0,0///]
         if sum(multiplicity)==0:
             multiplicity=[]
-        
-        # This check is commented out (temporarily before can be removed completely) to support signatures wiht one sequence and multiplicty > 1, e.g. HLT_2e3
-        # In such case there is only one sequence, however the multiplicty is == 2 
-        # sanity check on inputs
-        #if len(Sequences) != len(multiplicity):
-        #    raise RuntimeError("Tried to configure a ChainStep %s with %i Sequences and %i multiplicities. These lists must have the same size" % (name, len(Sequences), len(multiplicity)) )
+        else:
+            # sanity check on inputs, excluding empty steps
+            if len(Sequences) != len(multiplicity):
+                raise RuntimeError("Tried to configure a ChainStep %s with %i Sequences and %i multiplicities. These lists must have the same size" % (name, len(Sequences), len(multiplicity)) )
+
+            if len(Sequences) != len(chainDicts):
+                raise RuntimeError("Tried to configure a ChainStep %s with %i Sequences and %i dictionaries. These lists must have the same size" % (name, len(Sequences), len(chainDicts)) )
 
         self.name = name
         self.sequences=Sequences
         self.multiplicity = multiplicity
         self.comboHypoCfg=comboHypoCfg
         self.comboToolConfs=comboToolConfs
+        self.stepDicts = chainDicts # one dict per leg
         self.isCombo=sum(multiplicity)>1
+        self.isEmpty=sum(multiplicity)==0
         self.combo=None
-        self.chainDicts = chainDicts
         if self.isCombo:
             self.makeCombo()
-
+   
+         
     def addComboHypoTools(self,  tools):
         self.comboToolConfs.append(tools)
 
@@ -812,6 +785,11 @@ class ChainStep(object):
             from TriggerMenuMT.HLTMenuConfig.Menu.TriggerConfigHLT import TriggerConfigHLT
             chainDict = TriggerConfigHLT.getChainDictFromChainName(chainName)
             self.combo.createComboHypoTools(chainDict, self.comboToolConfs)
+            
+    def getChainLegs(self):
+        """ This is extrapolating the chain legs from the step dictionaries"""      
+        legs = [part['chainName'] for part in self.stepDicts]
+        return legs
 
     def getChainNames(self):
         if not self.isCombo:
@@ -821,20 +799,17 @@ class ChainStep(object):
         
     def __repr__(self):
         if len(self.sequences) == 0:
-            return "--- ChainStep %s ---\n is Empty, ChainDict = %s "%(self.name,  ' '.join(map(str, [dic['chainName'] for dic in self.chainDicts])) )
-        if not self.isCombo:
-            return "--- ChainStep %s ---\n , multiplicity = %d  ChainDict = %s \n + MenuSequences = %s "%(self.name,  sum(self.multiplicity), ' '.join(map(str, [dic['chainName'] for dic in self.chainDicts])), ' '.join(map(str, [seq.name for seq in self.sequences]) ))
-        else:
-            if self.combo:
-                calg = self.combo.Alg.name()
-            else:
-                calg = 'NONE'
-            return "--- ChainStep %s ---\n + isCombo, multiplicity = %d  ChainDict = %s \n + MenuSequences = %s  \n + ComboHypo = %s,  ComboHypoTools = %s" %\
-                   (self.name,  sum(self.multiplicity),
-                    ' '.join(map(str, [dic['chainName'] for dic in self.chainDicts])),
-                    ' '.join(map(str, [seq.name for seq in self.sequences]) ),
-                    calg,
+            return "--- ChainStep %s ---\n is Empty, ChainDict = %s "%(self.name,  ' '.join(map(str, [dic['chainName'] for dic in self.stepDicts])) )
+        
+        repr_string= "--- ChainStep %s ---\n , multiplicity = %s  ChainDict = %s \n + MenuSequences = %s "%\
+          (self.name,  ' '.join(map(str,[mult for mult in self.multiplicity])),
+             ' '.join(map(str, [dic['chainName'] for dic in self.stepDicts])),
+             ' '.join(map(str, [seq.name for seq in self.sequences]) ))
+        if self.isCombo:
+            repr_string += "\n+ ComboHypo = %s,  ComboHypoTools = %s" %\
+                   (self.combo.Alg.name(),
                     ' '.join(map(str, [tool.__name__ for tool in self.comboToolConfs])))
+        return repr_string
 
 
 def createComboAlg(dummyFlags, name, multiplicity, comboHypoCfg):
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/PhysicsP1_pp_run3_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/PhysicsP1_pp_run3_v1.py
index 6720436a81f9b23cee3683fd88c468c550d13e49..c8fffc17ee4b9a60a4e9f2c44cd8ceb2922e6050 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/PhysicsP1_pp_run3_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/PhysicsP1_pp_run3_v1.py
@@ -136,6 +136,9 @@ def addP1Signatures():
         ChainProp(name='HLT_noalg_L1MBTS_1_EMPTY', l1SeedThresholds=['FSNOSEED'], stream=['MinBias'], groups=MinBiasGroup), #ATR-21740
         ChainProp(name='HLT_noalg_mb_L1RD2_EMPTY', l1SeedThresholds=['FSNOSEED'], stream=['MinBias'], groups=MinBiasGroup), # ATR-21367
         ChainProp(name='HLT_noalg_zb_L1ZB',        l1SeedThresholds=['FSNOSEED'], stream=['ZeroBias'],groups=ZeroBiasGroup),# ATR-21367
+        ChainProp(name='HLT_noalg_L1MBTS_2_EMPTY', l1SeedThresholds=['FSNOSEED'], stream=['MinBias'], groups=MinBiasGroup), #ATR-21999
+        ChainProp(name='HLT_noalg_L1MBTS_1_1_EMPTY', l1SeedThresholds=['FSNOSEED'], stream=['MinBias'], groups=MinBiasGroup), #ATR-21999
+
     ]
     TriggerFlags.MonitorSlice.signatures   = TriggerFlags.MonitorSlice.signatures() + [
           ChainProp(name='HLT_costmonitor_CostMonDS_L1All',        l1SeedThresholds=['FSNOSEED'], stream=['CostMonitoring'], groups=['RATE:Monitoring','BW:Other']),
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/Physics_pp_run3_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/Physics_pp_run3_v1.py
index 71ffa6d55b8f07499c4d27587d8fa36a9137cbe7..b0682052773a985ce6238b66ea4bdd2e442737a6 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/Physics_pp_run3_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/Physics_pp_run3_v1.py
@@ -25,6 +25,15 @@ SingleBjetGroup = ['RATE:SingleBJet', 'BW:BJet']
 SingleTauGroup = ['RATE:SingleTau', 'BW:Tau']
 MultiTauGroup = ['RATE:MultiTau', 'BW:Tau']
 BphysicsGroup = ['RATE:Bphysics', 'BW:Bphysics']
+EgammaMuonGroup = ['RATE:EgammaMuon', 'BW:Egamma', 'BW:Muon']
+EgammaMETGroup = ['RATE:EgammaMET', 'BW:Egamma', 'BW:MET']
+MuonJetGroup =['RATE:MuonJet','BW:Muon', 'BW:Jet']
+MuonTauGroup =['RATE:MuonTau', 'BW:Tau', 'BW:Muon']
+TauMETGroup =['RATE:TauMET', 'BW:Tau']
+MuonMETGroup =['RATE:MuonMET', 'BW:Muon']
+EgammaJetGroup = ['RATE:EgammaJet', 'BW:Egamma']
+TauGammaGroup =['RATE:TauGamma', 'BW:Tau', 'BW:Egamma']
+JetMETGroup = ['RATE:JetMET', 'BW:Jet']
 MinBiasGroup = ['RATE:MinBias', 'BW:MinBias']
 ZeroBiasGroup = ['RATE:ZeroBias', 'BW:ZeroBias']
 EgammaStreamersGroup = ['RATE:SeededStreamers', 'BW:Egamma']
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MinBias/MinBiasChainConfiguration.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MinBias/MinBiasChainConfiguration.py
index f1ca0df55f1b844173d307f46e479f31c08b4f70..1214b696d22898e61c114707bddad089ae1e1e9a 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MinBias/MinBiasChainConfiguration.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MinBias/MinBiasChainConfiguration.py
@@ -6,143 +6,35 @@ log = logging.getLogger( __name__ )
 
 
 from TriggerMenuMT.HLTMenuConfig.Menu.ChainConfigurationBase import ChainConfigurationBase
-from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence
-from AthenaCommon.CFElements import parOR
-from AthenaCommon.CFElements import seqAND
-from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import ChainStep
-from TrigInDetConfig.InDetSetup import makeInDetAlgs
-from TrigEDMConfig.TriggerEDMRun3 import recordable
-from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm
-from DecisionHandling.DecisionHandlingConf import ViewCreatorInitialROITool
-from AthenaCommon.GlobalFlags import globalflags
-from TrigInDetConfig.ConfigSettings import getInDetTrigConfig
+from TriggerMenuMT.HLTMenuConfig.MinBias.MinBiasMenuSequences import MinBiasSPSequence, MinBiasTrkSequence
+
 #----------------------------------------------------------------
 # fragments generating configuration will be functions in New JO,
 # so let's make them functions already now
 #----------------------------------------------------------------
+def MinBiasSPSequenceCfg(flags):
+    return MinBiasSPSequence()
+
+def MinBiasTrkSequenceCfg(flags):
+    return MinBiasTrkSequence()
+
+
 class MinBiasChainConfig(ChainConfigurationBase):
 
     def __init__(self, chainDict):
         ChainConfigurationBase.__init__(self,chainDict)
 
-                # ----------------------
-                # Assemble the chain depending on information from chainName
-                # ----------------------
+    # ----------------------
+    # Assemble the chain depending on information from chainName
+    # ----------------------
     def assembleChain(self):
         log.debug("Assembling chain for " + self.chainName)
         SpStep = self.getMinBiasSpStep()
         TrkStep = self.getMinBiasTrkStep()
-
         return self.buildChain([SpStep,TrkStep])
+    
     def getMinBiasSpStep(self):
-        """ Use the reco-dict to construct a single MinBias step """
-        def generateSPCountHypo(chainDict):
-                hypo = SPCountHypoTool(chainDict["chainName"])
-                if "hmt" in chainDict["chainName"]:
-                    hypo.totNumSctSP = int( chainDict["chainParts"][0]["hypoL2Info"].strip("sp") )
-                if "mb_sptrk" in chainDict["chainName"]:
-                    hypo.totNumPixSP  = 2
-                    hypo.totNumSctSP  = 3
-                # will set here thresholds
-                return hypo
-        SpList = []
-        from TrigT2MinBias.TrigT2MinBiasConf import TrigCountSpacePointsMT, SPCountHypoAlgMT, SPCountHypoTool
-
-
-        SPInputMakerAlg = EventViewCreatorAlgorithm("IM_SPEventViewCreator")
-        SPInputMakerAlg.ViewFallThrough = True
-        SPInputMakerAlg.RoITool = ViewCreatorInitialROITool()
-        SPInputMakerAlg.InViewRoIs = "InputRoI"
-        SPInputMakerAlg.Views = "SPView"
-
-        IDTrigConfig = getInDetTrigConfig( 'minBias' )
-        idAlgs, verifier = makeInDetAlgs(  config = IDTrigConfig, rois=SPInputMakerAlg.InViewRoIs, viewVerifier='SPViewDataVerifier' )
-        verifier.DataObjects += [( 'TrigRoiDescriptorCollection' , 'StoreGateSvc+InputRoI' ),
-                                 ( 'SCT_ID' , 'DetectorStore+SCT_ID' ),
-                                 ( 'PixelID' , 'DetectorStore+PixelID' ),
-                                 ( 'TagInfo' , 'DetectorStore+ProcessingTags' )]
-
-        # Make sure required objects are still available at whole-event level
-        from AthenaCommon.AlgSequence import AlgSequence
-        topSequence = AlgSequence()
-        topSequence.SGInputLoader.Load += [( 'SCT_ID' , 'DetectorStore+SCT_ID' ),
-                                           ( 'PixelID' , 'DetectorStore+PixelID' ),
-                                           ( 'TagInfo' , 'DetectorStore+ProcessingTags' )]
-
-        SpList = idAlgs[:-2]
-
-        SpCount=TrigCountSpacePointsMT()
-        SpCount.SpacePointsKey=recordable("HLT_SpacePointCounts")
-        
-        from TrigT2MinBias.TrigT2MinBiasMonitoringMT import SpCountMonitoring
-        SpCount.MonTool = SpCountMonitoring()
-
-        SPrecoSeq = parOR("SPrecoSeq", SpList + [ SpCount ])
-        SPSequence = seqAND("SPSequence", [SPInputMakerAlg, SPrecoSeq])
-        SPInputMakerAlg.ViewNodeName = SPrecoSeq.name()
-
-
-        SpCountHypo =SPCountHypoAlgMT()
-        SpCountHypo.SpacePointsKey=recordable("HLT_SpacePointCounts")
-
-        Step1_SPCount = ChainStep( "Step1_SPCount",  [MenuSequence( Sequence    = SPSequence,
-                          Maker       = SPInputMakerAlg,
-                          Hypo        = SpCountHypo,
-                          HypoToolGen = generateSPCountHypo )] )
-
-        return Step1_SPCount
+        return self.getStep(1,'SPCount',[MinBiasSPSequenceCfg])
 
     def getMinBiasTrkStep(self):
-        """ Use the reco-dict to construct a single MinBias step """
-        def generateTrackCountHypo(chainDict):
-                hypo = TrackCountHypoTool(chainDict["chainName"])
-                if "hmt" in chainDict["chainName"]:
-                    hypo.required_ntrks = int( chainDict["chainParts"][0]["hypoEFInfo"].strip("trk") )
-                if "mb_sptrk" in chainDict["chainName"]:
-                    hypo.min_pt  = 0.2
-                    hypo.max_z0  = 401
-
-                # will set here cuts
-                return hypo
-        from TrigMinBias.TrigMinBiasConf import TrackCountHypoAlgMT, TrackCountHypoTool
-
-        TrkInputMakerAlg = EventViewCreatorAlgorithm("IM_TrkEventViewCreator")
-        TrkInputMakerAlg.ViewFallThrough = True
-        TrkInputMakerAlg.RoITool = ViewCreatorInitialROITool()
-        TrkInputMakerAlg.InViewRoIs = "InputRoI" # contract with the consumer
-        TrkInputMakerAlg.Views = "TrkView"
-        TrkInputMakerAlg.RequireParentView = True
-        TrkInputMakerAlg.ViewNodeName = "TrkCountHypoAlgMTNode"
-
-        # prepare algorithms to run in views, first, inform scheduler that input data is available in parent view (has to be done by hand)
-        IDTrigConfig = getInDetTrigConfig( 'minBias' )
-        idAlgs, verifier = makeInDetAlgs( config = IDTrigConfig, rois=TrkInputMakerAlg.InViewRoIs, viewVerifier='TrkrecoSeqDataVerifier')
-        verifier.DataObjects += [( 'TrigRoiDescriptorCollection' , 'StoreGateSvc+InputRoI' ),
-                                 ( 'IDCInDetBSErrContainer' , 'StoreGateSvc+SCT_FlaggedCondData_TRIG' ),
-                                 ( 'InDet::SCT_ClusterContainer' , 'StoreGateSvc+SCT_TrigClusters' ),
-                                 ( 'SpacePointContainer' , 'StoreGateSvc+SCT_TrigSpacePoints' ),
-                                 ( 'InDet::PixelClusterContainer' , 'StoreGateSvc+PixelTrigClusters' ),
-                                 ( 'SpacePointContainer' , 'StoreGateSvc+PixelTrigSpacePoints' )]
-
-        if globalflags.InputFormat.is_bytestream():
-          verifier.DataObjects += [( 'IDCInDetBSErrContainer' , 'StoreGateSvc+PixelByteStreamErrs' ),
-                                   ( 'IDCInDetBSErrContainer' , 'StoreGateSvc+SCT_ByteStreamErrs' )]
-
-
-        TrkList = idAlgs[-2:] # FTF and Track to xAOD::TrackParticle conversion alg
-        TrackCountHypo=TrackCountHypoAlgMT()
-        TrackCountHypo.trackCountKey=recordable("HLT_TrackCount")
-        TrackCountHypo.tracksKey=recordable("HLT_IDTrack_MinBias_FTF")
-
-        from TrigMinBias.TrackCountMonitoringMT import TrackCountMonitoring
-        TrackCountHypo.MonTool = TrackCountMonitoring()
-
-        TrkrecoSeq = parOR("TrkrecoSeq", [verifier]+TrkList)
-        TrkSequence = seqAND("TrkSequence", [TrkInputMakerAlg, TrkrecoSeq])
-        TrkInputMakerAlg.ViewNodeName = TrkrecoSeq.name()
-
-        Step2_TrkCount = ChainStep( "Step2_TrkCount",  [MenuSequence( Sequence    = TrkSequence,
-                            Maker       = TrkInputMakerAlg,
-                            Hypo        = TrackCountHypo,
-                            HypoToolGen = generateTrackCountHypo )] )
-        return Step2_TrkCount
+        return self.getStep(2,'TrkCount',[MinBiasTrkSequenceCfg])
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MinBias/MinBiasMenuSequences.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MinBias/MinBiasMenuSequences.py
index e9b8d2628bd56427e52b9da620663054f7a33f8c..1f3adb4398edb76e73b19ffae563340c750bfc4b 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MinBias/MinBiasMenuSequences.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MinBias/MinBiasMenuSequences.py
@@ -1,40 +1,170 @@
 #
-#  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+#  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 #
-from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence, RecoFragmentsPool
-from AthenaConfiguration.AllConfigFlags import ConfigFlags
+from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence
+from AthenaCommon.CFElements import parOR
+from AthenaCommon.CFElements import seqAND
+from TrigInDetConfig.InDetSetup import makeInDetAlgs
+from TrigEDMConfig.TriggerEDMRun3 import recordable
+from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm
+from DecisionHandling.DecisionHandlingConf import ViewCreatorInitialROITool
+from AthenaCommon.GlobalFlags import globalflags
+from TrigInDetConfig.ConfigSettings import getInDetTrigConfig
 
-from TrigMinBiasHypo.TrigMinBiasHypoConfigMT import TrigMinBiasHypoToolFromDict
-from TrigMinBiasHypo.TrigMinBiasHypoConf import MbCountHypoAlgMT
 
+########
+# to move into TrigMinBiasHypoConfigMT?
 
-def minbiasSpacePointMenuSequence():
-    # menu components
-    # retrieve the reco seuqnece
-    from TriggerMenuMT.HLTMenuConfig.MinBias.MinBiasSPRecoSequences import minbiasSpacePointAthSequence
-    ( minbiasSpacePointSequence, InputMakerAlg, sequenceOut) = RecoFragmentsPool.retrieve(minbiasSpacePointAthSequence,ConfigFlags)
+def SPCountHypoToolGen(chainDict):        
+    from TrigT2MinBias.TrigT2MinBiasConf import SPCountHypoTool
+    hypo = SPCountHypoTool(chainDict["chainName"])
+    if "hmt" in chainDict["chainName"]:
+        hypo.totNumSctSP = int( chainDict["chainParts"][0]["hypoL2Info"].strip("sp") )
+    if "mb_sptrk" in chainDict["chainName"]:
+        hypo.totNumPixSP  = 2
+        hypo.totNumSctSP  = 3
+            # will set here thresholds
+    return hypo
 
-    #hypo
-    mbHypoAlg = MbCountHypoAlgMT("MinBiasHypoAlg_sp")
-    mbHypoAlg.MinBiasContainerKey=sequenceOut
 
-    return  MenuSequence( Sequence    = minbiasSpacePointSequence,
-                          Maker       = InputMakerAlg,
-                          Hypo        = mbHypoAlg,
-                          HypoToolGen = TrigMinBiasHypoToolFromDict )
 
+def TrackCountHypoToolGen(chainDict):
+    from TrigMinBias.TrigMinBiasConf import  TrackCountHypoTool
+    hypo = TrackCountHypoTool(chainDict["chainName"])
+    if "hmt" in chainDict["chainName"]:
+        hypo.required_ntrks = int( chainDict["chainParts"][0]["hypoEFInfo"].strip("trk") )
+    if "mb_sptrk" in chainDict["chainName"]:
+        hypo.min_pt  = 0.2
+        hypo.max_z0  = 401
+        # will set here cuts
+    return hypo
 
-def minbiasTrackMenuSequence():
-    # menu components
-    # retrieve the reco seuqnece
-    from TriggerMenuMT.HLTMenuConfig.MinBias.MinBiasTrkRecoSequences import minbiasTrackAthSequence
-    (minbiasTrackSequence, InputMakerAlg, sequenceOut) = RecoFragmentsPool.retrieve(minbiasTrackAthSequence,ConfigFlags)
 
-    #hypo
-    mbHypoAlg = MbCountHypoAlgMT("MinBiasHypoAlg_trk")
-    mbHypoAlg.MinBiasContainerKey=sequenceOut
+### Now the sequences
+
+# These are obsoletee and can probably be deleted. Leeft here commented as need feedback fomr experts
+
+## def minbiasSpacePointMenuSequence():
+##     # menu components
+##     # retrieve the reco seuqnece
+##     from TriggerMenuMT.HLTMenuConfig.MinBias.MinBiasSPRecoSequences import minbiasSpacePointAthSequence
+##     ( minbiasSpacePointSequence, InputMakerAlg, sequenceOut) = RecoFragmentsPool.retrieve(minbiasSpacePointAthSequence,ConfigFlags)
+
+##     #hypo
+##     mbHypoAlg = MbCountHypoAlgMT("MinBiasHypoAlg_sp")
+##     mbHypoAlg.MinBiasContainerKey=sequenceOut
+
+##     return  MenuSequence( Sequence    = minbiasSpacePointSequence,
+##                           Maker       = InputMakerAlg,
+##                           Hypo        = mbHypoAlg,
+##                           HypoToolGen = TrigMinBiasHypoToolFromDict )
+
+
+## #obsolete?
+## def minbiasTrackMenuSequence():
+##     # menu components
+##     # retrieve the reco seuqnece
+##     from TriggerMenuMT.HLTMenuConfig.MinBias.MinBiasTrkRecoSequences import minbiasTrackAthSequence
+##     (minbiasTrackSequence, InputMakerAlg, sequenceOut) = RecoFragmentsPool.retrieve(minbiasTrackAthSequence,ConfigFlags)
+
+##     #hypo
+##     mbHypoAlg = MbCountHypoAlgMT("MinBiasHypoAlg_trk")
+##     mbHypoAlg.MinBiasContainerKey=sequenceOut
+
+##     return  MenuSequence( Sequence    = minbiasTrackSequence,
+##                           Maker       = InputMakerAlg,
+##                           Hypo        = mbHypoAlg,
+##                           HypoToolGen = TrigMinBiasHypoToolFromDict )
+
+
+# NEW:
+def MinBiasSPSequence():
+    SpList = []
+    from TrigT2MinBias.TrigT2MinBiasConf import TrigCountSpacePointsMT, SPCountHypoAlgMT
+
+    SPInputMakerAlg = EventViewCreatorAlgorithm("IM_SPEventViewCreator")
+    SPInputMakerAlg.ViewFallThrough = True
+    SPInputMakerAlg.RoITool = ViewCreatorInitialROITool()
+    SPInputMakerAlg.InViewRoIs = "InputRoI"
+    SPInputMakerAlg.Views = "SPView"
+
+    IDTrigConfig = getInDetTrigConfig( 'minBias' )
+    idAlgs, verifier = makeInDetAlgs(  config = IDTrigConfig, rois=SPInputMakerAlg.InViewRoIs, viewVerifier='SPViewDataVerifier' )
+    verifier.DataObjects += [( 'TrigRoiDescriptorCollection' , 'StoreGateSvc+InputRoI' ),
+                                 ( 'SCT_ID' , 'DetectorStore+SCT_ID' ),
+                                 ( 'PixelID' , 'DetectorStore+PixelID' ),
+                                 ( 'TagInfo' , 'DetectorStore+ProcessingTags' )]
+
+    # Make sure required objects are still available at whole-event level
+    from AthenaCommon.AlgSequence import AlgSequence
+    topSequence = AlgSequence()
+    topSequence.SGInputLoader.Load += [( 'SCT_ID' , 'DetectorStore+SCT_ID' ),
+                                           ( 'PixelID' , 'DetectorStore+PixelID' ),
+                                           ( 'TagInfo' , 'DetectorStore+ProcessingTags' )]
+    
+    SpList = idAlgs[:-2]
+    
+    SpCount=TrigCountSpacePointsMT()
+    SpCount.SpacePointsKey=recordable("HLT_SpacePointCounts")
+    
+    from TrigT2MinBias.TrigT2MinBiasMonitoringMT import SpCountMonitoring
+    SpCount.MonTool = SpCountMonitoring()
+    
+    SPrecoSeq = parOR("SPrecoSeq", SpList + [ SpCount ])
+    SPSequence = seqAND("SPSequence", [SPInputMakerAlg, SPrecoSeq])
+    SPInputMakerAlg.ViewNodeName = SPrecoSeq.name()
+    
+    
+    SpCountHypo =SPCountHypoAlgMT()
+    SpCountHypo.SpacePointsKey=recordable("HLT_SpacePointCounts")
+    
+    return MenuSequence( Sequence   = SPSequence,
+                        Maker       = SPInputMakerAlg,
+                        Hypo        = SpCountHypo,
+                        HypoToolGen = SPCountHypoToolGen )
+
+
+def MinBiasTrkSequence():
+        from TrigMinBias.TrigMinBiasConf import TrackCountHypoAlgMT
+
+        TrkInputMakerAlg = EventViewCreatorAlgorithm("IM_TrkEventViewCreator")
+        TrkInputMakerAlg.ViewFallThrough = True
+        TrkInputMakerAlg.RoITool = ViewCreatorInitialROITool()
+        TrkInputMakerAlg.InViewRoIs = "InputRoI" # contract with the consumer
+        TrkInputMakerAlg.Views = "TrkView"
+        TrkInputMakerAlg.RequireParentView = True
+        TrkInputMakerAlg.ViewNodeName = "TrkCountHypoAlgMTNode"
+
+        # prepare algorithms to run in views, first, inform scheduler that input data is available in parent view (has to be done by hand)
+        IDTrigConfig = getInDetTrigConfig( 'minBias' )
+        idAlgs, verifier = makeInDetAlgs( config = IDTrigConfig, rois=TrkInputMakerAlg.InViewRoIs, viewVerifier='TrkrecoSeqDataVerifier')
+        verifier.DataObjects += [( 'TrigRoiDescriptorCollection' , 'StoreGateSvc+InputRoI' ),
+                                 ( 'IDCInDetBSErrContainer' , 'StoreGateSvc+SCT_FlaggedCondData_TRIG' ),
+                                 ( 'InDet::SCT_ClusterContainer' , 'StoreGateSvc+SCT_TrigClusters' ),
+                                 ( 'SpacePointContainer' , 'StoreGateSvc+SCT_TrigSpacePoints' ),
+                                 ( 'InDet::PixelClusterContainer' , 'StoreGateSvc+PixelTrigClusters' ),
+                                 ( 'SpacePointContainer' , 'StoreGateSvc+PixelTrigSpacePoints' )]
+
+        if globalflags.InputFormat.is_bytestream():
+          verifier.DataObjects += [( 'IDCInDetBSErrContainer' , 'StoreGateSvc+PixelByteStreamErrs' ),
+                                   ( 'IDCInDetBSErrContainer' , 'StoreGateSvc+SCT_ByteStreamErrs' )]
+
+
+        TrkList = idAlgs[-2:] # FTF and Track to xAOD::TrackParticle conversion alg
+        TrackCountHypo=TrackCountHypoAlgMT()
+        TrackCountHypo.trackCountKey=recordable("HLT_TrackCount")
+        TrackCountHypo.tracksKey=recordable("HLT_IDTrack_MinBias_FTF")
+
+        from TrigMinBias.TrackCountMonitoringMT import TrackCountMonitoring
+        TrackCountHypo.MonTool = TrackCountMonitoring()
+
+        TrkrecoSeq = parOR("TrkrecoSeq", [verifier]+TrkList)
+        TrkSequence = seqAND("TrkSequence", [TrkInputMakerAlg, TrkrecoSeq])
+        TrkInputMakerAlg.ViewNodeName = TrkrecoSeq.name()
+
+        return MenuSequence( Sequence   = TrkSequence,
+                            Maker       = TrkInputMakerAlg,
+                            Hypo        = TrackCountHypo,
+                            HypoToolGen = TrackCountHypoToolGen )
+
 
-    return  MenuSequence( Sequence    = minbiasTrackSequence,
-                          Maker       = InputMakerAlg,
-                          Hypo        = mbHypoAlg,
-                          HypoToolGen = TrigMinBiasHypoToolFromDict )
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py
index 1db463f1684e2daf14f10ccf80d1f2a96d8c1aff..125532d328340ff32086b37537e09e17e6040498 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py
@@ -142,7 +142,7 @@ def muCombAlgSequence(ConfigFlags):
     # muCombIDSequence = parOR("l2muCombIDSequence", [muFastIDRecoSequence, muCombFilterSequence])
 
     # for Inside-out L2SA
-    muFastIORecoSequence, sequenceOutL2SAIO = muFastRecoSequence( "MURoIs", doFullScanID=False, InsideOutMode=True )
+    muFastIORecoSequence, sequenceOutL2SAIO = muFastRecoSequence( l2muCombViewsMaker.InViewRoIs, doFullScanID=False, InsideOutMode=True )
     insideoutMuonChainFilter = MuonChainFilterAlg("FilterInsideOutMuonChains")
     insideoutMuonChains = getInsideOutMuonChainNames()
     insideoutMuonChainFilter.ChainsToFilter = insideoutMuonChains
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSetup.py
index 57209cf03234fb7814026744cf7a34e1c17278e8..a4e2acacb564f197c17ac2c24ccd6a05136166f9 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSetup.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSetup.py
@@ -347,29 +347,26 @@ def muFastRecoSequence( RoIs, doFullScanID = False, InsideOutMode=False ):
   muFastRecoSequence = parOR("l2Mu"+postFix+"ViewNode")
 
   # In insideout mode, need to inherit muon decoding objects for TGC, RPC, MDT, CSC
+  import AthenaCommon.CfgMgr as CfgMgr
+  ViewVerify = CfgMgr.AthViews__ViewDataVerifier("muFastRecoVDV"+postFix)
   if InsideOutMode:
-    import AthenaCommon.CfgMgr as CfgMgr
-    ViewVerify = CfgMgr.AthViews__ViewDataVerifier("muFastIOmodeViewDataVerifier")
     ViewVerify.DataObjects = [('Muon::TgcPrepDataContainer','StoreGateSvc+TGC_Measurements'),
                               ('TgcRdoContainer' , 'StoreGateSvc+TGCRDO'),
                               ('Muon::RpcPrepDataContainer','StoreGateSvc+RPC_Measurements'),
-                              ('Muon::MdtPrepDataContainer','StoreGateSvc+MDT_DriftCircles'),
-                              ('TrigRoiDescriptorCollection','StoreGateSvc+MURoIs')]
+                              ('Muon::MdtPrepDataContainer','StoreGateSvc+MDT_DriftCircles')]
     if MuonGeometryFlags.hasCSC():
       ViewVerify.DataObjects += [('Muon::CscPrepDataContainer','StoreGateSvc+CSC_Clusters')]
     if MuonGeometryFlags.hasSTGC():
       ViewVerify.DataObjects += [('Muon::sTgcPrepDataContainer','StoreGateSvc+STGC_Measurements')]
     if MuonGeometryFlags.hasMM():
       ViewVerify.DataObjects += [('Muon::MMPrepDataContainer','StoreGateSvc+MM_Measurements')]
-    muFastRecoSequence+=ViewVerify
-
-  import AthenaCommon.CfgMgr as CfgMgr
-  muFastRecoVDV = CfgMgr.AthViews__ViewDataVerifier("muFastRecoVDV")
-  muFastRecoVDV.DataObjects = [( 'TrigRoiDescriptorCollection' , 'StoreGateSvc+'+RoIs ),
-                               ( 'xAOD::EventInfo' , 'StoreGateSvc+EventInfo' ),
-                               ( 'DataVector< LVL1::RecMuonRoI >' , 'StoreGateSvc+HLT_RecMURoIs' )]
+    #muFastRecoSequence+=ViewVerify
+  else:
+    ViewVerify.DataObjects += [( 'TrigRoiDescriptorCollection' , 'StoreGateSvc+'+RoIs )]
+  ViewVerify.DataObjects += [( 'xAOD::EventInfo' , 'StoreGateSvc+EventInfo' ),
+                             ( 'DataVector< LVL1::RecMuonRoI >' , 'StoreGateSvc+HLT_RecMURoIs' )]
 
-  muFastRecoSequence += muFastRecoVDV
+  muFastRecoSequence += ViewVerify
 
   if MuonGeometryFlags.hasCSC():
     # Configure the L2 CSC data preparator - we can turn off the data decoding here
@@ -480,7 +477,9 @@ def muFastRecoSequence( RoIs, doFullScanID = False, InsideOutMode=False ):
   muFastAlg.FILL_FSIDRoI = doFullScanID
   muFastAlg.InsideOutMode = InsideOutMode
   muFastAlg.TrackParticlesContainerName = TrackParticlesName
-
+  #Do not run topo road and inside-out mode at the same time
+  if InsideOutMode:
+    muFastAlg.topoRoad = False
   muFastRecoSequence += muFastAlg
   sequenceOut = muFastAlg.MuonL2SAInfo
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Photon/generatePhoton.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Photon/generatePhoton.py
index 074285b1c74dbd86f8959c9e030178f095e86311..acdc24d9714e7275f5e622cc829f01f4601cda7c 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Photon/generatePhoton.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Photon/generatePhoton.py
@@ -40,7 +40,7 @@ def generateChains(flags, chainDict):
                                      HypoToolGen = TrigEgammaFastCaloHypoToolFromDict,
                                      CA = accCalo )
 
-    fastCaloStep = ChainStep(firstStepName, [fastCaloSequence])
+    fastCaloStep = ChainStep(firstStepName, [fastCaloSequence], multiplicity=[1],chainDicts=[chainDict] )
 
 
     secondStepName = 'FastPhoton'
@@ -64,7 +64,7 @@ def generateChains(flags, chainDict):
                                      HypoToolGen = TrigEgammaFastPhotonHypoToolFromDict,
                                      CA = accPhoton )
 
-    l2PhotonStep = ChainStep(secondStepName, [l2PhotonSequence])
+    l2PhotonStep = ChainStep(secondStepName, [l2PhotonSequence], multiplicity=[1],chainDicts=[chainDict] )
 
 
     l1Thresholds=[]
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/Thresholds.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/Thresholds.py
index 607f415ff1573930b07c948d653d04775ece8c84..c02a03c2a082c8f36697f897660f4479373da3b6 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/Thresholds.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/Thresholds.py
@@ -230,8 +230,8 @@ class LegacyThreshold( Threshold ):
                     ("isobits", thrV.isobits),
                     ("etamin", thrV.etamin),
                     ("etamax", thrV.etamax),
-                    ("phimin", thrV.phimax),
-                    ("phimax", thrV.phimin),
+                    ("phimin", thrV.phimin),
+                    ("phimax", thrV.phimax),
                     ("priority", thrV.priority)
                 ]) )
         elif self.ttype == ThrType.TAU:
@@ -244,8 +244,8 @@ class LegacyThreshold( Threshold ):
                     ("value", thrV.value),
                     ("etamin", thrV.etamin),
                     ("etamax", thrV.etamax),
-                    ("phimin", thrV.phimax),
-                    ("phimax", thrV.phimin),
+                    ("phimin", thrV.phimin),
+                    ("phimax", thrV.phimax),
                     ("window", thrV.window),
                     ("priority", thrV.priority)
                 ]) )
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ItemDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ItemDef.py
index 846421800e0cf9a4e680641c2ce533c42fd30568..8cb186e920ff2b57a94352b2f0d4afa7c1f5e211 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ItemDef.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ItemDef.py
@@ -636,7 +636,7 @@ class ItemDef:
         MenuItem('L1_J40.0ETA25_2J15.31ETA49' ).setLogic( d.J400ETA25 & d.J1531ETA49.x(2)    & physcond).setTriggerType(TT.calo)
         MenuItem('L1_J40.0ETA25_2J25_J20.31ETA49' ).setLogic( d.J400ETA25 & d.J25.x(2) & d.J2031ETA49   & physcond).setTriggerType(TT.calo)
         MenuItem('L1_J40.0ETA25_2J30_J20.31ETA49' ).setLogic( d.J400ETA25 & d.J30.x(2) & d.J2031ETA49   & physcond).setTriggerType(TT.calo)
-        MenuItem('L1_J45.0ETA20_3J15.0ETA25'  ).setLogic( d.J450ETA20 & d.J150ETA25.x(3) & physcond).setTriggerType(TT.calo)
+        MenuItem('L1_J45.0ETA23_3J15.0ETA25'  ).setLogic( d.J450ETA23 & d.J150ETA25.x(3) & physcond).setTriggerType(TT.calo)
         MenuItem('L1_J50_2J40.0ETA25_3J15.0ETA25'  ).setLogic( d.J50 & d.J400ETA25.x(2) & d.J150ETA25.x(3) & physcond).setTriggerType(TT.calo)
 
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ThresholdDefLegacy.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ThresholdDefLegacy.py
index c8bc26fb2624afd078e418d97e5d577097d4e1e1..e1c9903f3ed027f91bd10a38d0df502697b46ede 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ThresholdDefLegacy.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ThresholdDefLegacy.py
@@ -261,7 +261,7 @@ class ThresholdDefLegacy:
             LegacyThreshold('J%iA' % thrV, 'JET').addThrValue(CL.JetOff).addThrValue( thrV, etamin = 15,  etamax = 23, priority=1)
             LegacyThreshold('J%iC' % thrV, 'JET').addThrValue(CL.JetOff).addThrValue( thrV, etamin = -23,  etamax = -15, priority=1)          
         # Central jet
-        for (thrV, etamax) in [(12,23), (12,28), (15,25), (17,22), (20,28), (25,23), (35,23), (20,49), (30,49), (40,25), (45,20)]:
+        for (thrV, etamax) in [(12,23), (12,28), (15,25), (17,22), (20,28), (25,23), (35,23), (20,49), (30,49), (40,25), (45,23)]:
             LegacyThreshold('J%i.0ETA%i'  % (thrV, etamax), 'JET').addThrValue(CL.JetOff).addThrValue( thrV, etamin = -etamax,  etamax = etamax, priority=1)  
 
         # Standard forward jet
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TopoAlgoDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TopoAlgoDef.py
index f87b3af90d3f9144bfbffa541a5b853ca90db4df..2a3d6a326959c051d0697b69a0a616ff29e312f7 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TopoAlgoDef.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TopoAlgoDef.py
@@ -17,12 +17,6 @@ class TopoAlgoDef:
 
         _etamax = 49
         _minet = 0
-
-        usev7 = False
-        usev8 = True
-        log.debug("usev7 %r", usev7)
-        log.debug("usev8 %r", usev8)
-
         _emscale_for_decision = 1000 / getTypeWideThresholdConfig("EM")["resolutionMeV"]
 
         alg = AlgConf.ClusterNoSort( name = 'EMall', inputs = 'ClusterTobArray', outputs = 'EMall' ) 
@@ -87,8 +81,7 @@ class TopoAlgoDef:
         alg.addvariable('IsoMask', 0)
         alg.addvariable('MinEta', 0)
         alg.addvariable('MaxEta', _etamax) 
-        alg.addgeneric('DoIsoCut', '0')
-        #alg.addgeneric('DoEtaCut', '1')
+        alg.addgeneric('DoIsoCut', 0)
         tm.registerTopoAlgo(alg) 
 
         
@@ -99,8 +92,7 @@ class TopoAlgoDef:
         alg.addvariable('IsoMask', 3) 
         alg.addvariable('MinEta', 0)
         alg.addvariable('MaxEta', _etamax)
-        alg.addgeneric('DoIsoCut', '1')
-        #alg.addgeneric('DoEtaCut', '1')
+        alg.addgeneric('DoIsoCut', 1)
         tm.registerTopoAlgo(alg)
 
 
@@ -111,8 +103,7 @@ class TopoAlgoDef:
         alg.addvariable('IsoMask', 2) 
         alg.addvariable('MinEta', 0)
         alg.addvariable('MaxEta', _etamax)
-        alg.addgeneric('DoIsoCut', '1')
-        #alg.addgeneric('DoEtaCut', '1')
+        alg.addgeneric('DoIsoCut', 1)
         tm.registerTopoAlgo(alg)
 
         
@@ -131,7 +122,6 @@ class TopoAlgoDef:
 
 
         # for 0MATCH-4AJ20-4AJj15
-        #if not usev8:
         alg = AlgConf.JetNoSortMatch( name = 'AJMatchall', inputs = 'JetTobArray', outputs = 'AJMatchall' ) 
         alg.addgeneric('InputWidth', HW.InputWidthJET)
         alg.addgeneric('OutputWidth', HW.InputWidthJET)
@@ -181,27 +171,25 @@ class TopoAlgoDef:
 
 
         #input list needed for ATR-18824
-        if usev8:
-            alg = AlgConf.JetSort( name = 'FJjs23ETA49', inputs = 'JetTobArray', outputs = 'FJjs23ETA49')
+        alg = AlgConf.JetSort( name = 'FJjs23ETA49', inputs = 'JetTobArray', outputs = 'FJjs23ETA49')
+        alg.addgeneric('InputWidth',  HW.InputWidthJET)
+        alg.addgeneric('InputWidth1stStage', HW.InputWidth1stStageSortJET )
+        alg.addgeneric('OutputWidth', HW.OutputWidthSortJET )
+        alg.addgeneric('JetSize', 1 if HW.DefaultJetSize.value==2 else 2)
+        alg.addvariable('MinEta', 23)
+        alg.addvariable('MaxEta', _etamax)
+        alg.addgeneric('DoEtaCut', 1)
+        tm.registerTopoAlgo(alg)
 
-            alg.addgeneric('InputWidth',  HW.InputWidthJET)
-            alg.addgeneric('InputWidth1stStage', HW.InputWidth1stStageSortJET )
-            alg.addgeneric('OutputWidth', HW.OutputWidthSortJET )
-            alg.addgeneric('JetSize', 1 if HW.DefaultJetSize.value==2 else 2)
-            alg.addvariable('MinEta', 23)
-            alg.addvariable('MaxEta', _etamax)
-            alg.addgeneric('DoEtaCut', 1)
-            tm.registerTopoAlgo(alg)
-            
-        
-            alg = AlgConf.JetSort( name = 'CJsETA21', inputs = 'JetTobArray', outputs = 'CJsETA21')
-            alg.addgeneric('InputWidth',  HW.InputWidthJET)
-            alg.addgeneric('InputWidth1stStage', HW.InputWidth1stStageSortJET )
-            alg.addgeneric('OutputWidth', HW.OutputWidthSortJET )
-            alg.addgeneric('JetSize', HW.DefaultJetSize.value)
-            alg.addvariable('MinEta', 0)
-            alg.addvariable('MaxEta', 21)
-            tm.registerTopoAlgo(alg)
+
+        alg = AlgConf.JetSort( name = 'CJsETA21', inputs = 'JetTobArray', outputs = 'CJsETA21')
+        alg.addgeneric('InputWidth',  HW.InputWidthJET)
+        alg.addgeneric('InputWidth1stStage', HW.InputWidth1stStageSortJET )
+        alg.addgeneric('OutputWidth', HW.OutputWidthSortJET )
+        alg.addgeneric('JetSize', HW.DefaultJetSize.value)
+        alg.addvariable('MinEta', 0)
+        alg.addvariable('MaxEta', 21)
+        tm.registerTopoAlgo(alg)
 
         # Sorted J lists:
         for jet_type in ['AJ', 'FJ']:
@@ -343,135 +331,55 @@ class TopoAlgoDef:
         # Decision algorithms
         
         # VBF items
-        if usev8:
-            invm_aj_highmass_map = {"algoname": 'INVM_AJ_HighMass', "Threlist": [ 700], "maxInvm": 9999, "otype" : "AJ", "ocut1" : 30, "olist" : "s", "nleading1" : 6, "inputwidth1": HW.OutputWidthSortJET, "ocut2" : 20, "nleading2" : 6}
-        else:
-            invm_aj_highmass_map = {"algoname": 'INVM_AJ_HighMass', "Threlist": [ 900, 800, 700, 500 ], "maxInvm": 9999, "otype" : "AJ", "ocut1" : 30, "olist" : "s", "nleading1" : 6, "inputwidth1": HW.OutputWidthSortJET, "ocut2" : 20, "nleading2" : 6}
+        invm_aj_highmass_map = { "algoname": 'INVM_AJ_HighMass', "Threlist": [ 700], "maxInvm": 9999, 
+                                 "otype" : "AJ", "ocut1" : 30, "olist" : "s", "nleading1" : 6, 
+                                 "inputwidth1": HW.OutputWidthSortJET, "ocut2" : 20, "nleading2" : 6}
 
-        if usev8:
-            invm_aj_lowmass_map = {"algoname": 'INVM_AJ_LowMass',  "Threlist": [ 300], "maxInvm": 9999, "otype" : "AJ", "ocut1" : 30, "olist" : "s", "nleading1" : 6, "inputwidth1": HW.OutputWidthSortJET, "ocut2" : 20, "nleading2" : 6}
-        else:
-            invm_aj_lowmass_map = {"algoname": 'INVM_AJ_LowMass',  "Threlist": [ 400, 300, 200, 100 ], "maxInvm": 9999, "otype" : "AJ", "ocut1" : 30, "olist" : "s", "nleading1" : 6, "inputwidth1": HW.OutputWidthSortJET, "ocut2" : 20, "nleading2" : 6}
+        invm_aj_lowmass_map = { "algoname": 'INVM_AJ_LowMass',  "Threlist": [ 300], "maxInvm": 9999,
+                                "otype" : "AJ", "ocut1" : 30, "olist" : "s", "nleading1" : 6,
+                                "inputwidth1": HW.OutputWidthSortJET, "ocut2" : 20, "nleading2" : 6}
 
-        for x in [invm_aj_highmass_map, invm_aj_lowmass_map,
-            ]:
-            
+        for x in [invm_aj_highmass_map, invm_aj_lowmass_map ]:
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
             inputList = d.otype + d.olist
             toponames=[]
-
             for minInvm in d.Threlist:
                 toponame = "%iINVM%i-%s%s%s%s-%s%s%s%s"  % (minInvm, d.maxInvm,
                                                             d.otype, str(d.ocut1) , d.olist, str(d.nleading1) if d.olist=="s" else "",
                                                             d.otype, str(d.ocut2) , d.olist, str(d.nleading2) if d.olist=="s" else "")
                 toponames.append(toponame)
-
             alg = AlgConf.InvariantMassInclusive1( name = d.algoname, inputs = inputList, outputs = toponames)
-
             alg.addgeneric('InputWidth', d.inputwidth1)
             alg.addgeneric('MaxTob', d.nleading1)
             alg.addgeneric('NumResultBits', len(toponames))
-
             for bitid, minInvm in enumerate(d.Threlist):
                 alg.addvariable('MinET1', d.ocut1, bitid)
                 alg.addvariable('MinET2', d.ocut2, bitid)
                 alg.addvariable('MinMSqr', minInvm * minInvm, bitid)
                 alg.addvariable('MaxMSqr', d.maxInvm * d.maxInvm, bitid)
-
             tm.registerTopoAlgo(alg)
 
-        # dimu INVM items
-
-        if not usev8:
-            listofalgos=[
-
-            #{"minInvm": 1, "maxInvm": 19, "mult": 2, "otype1" : "MU", "ocut1": 4, "olist" : "ab", "otype2" : "",  "ocut2" : 0, "onebarrel": 0},#1INVM19-2MU4ab 
-            {"minInvm": 2, "maxInvm": 8, "mult": 2, "otype1" : "MU", "ocut1": 4, "olist" : "ab", "otype2" : "",  "ocut2" : 0, "onebarrel": 0}, #2INVM8-2MU4ab 
-            {"minInvm": 2, "maxInvm": 9, "mult": 2, "otype1" : "MU", "ocut1": 4, "olist" : "ab", "otype2" : "",  "ocut2" : 0, "onebarrel": 0}, #2INVM9-2MU4ab 
-            {"minInvm": 8, "maxInvm": 15, "mult": 1, "otype1" : "MU", "ocut1": 6, "olist" : "ab", "otype2" : "MU","ocut2" : 4, "onebarrel": 0}, #8INVM15-MU6ab-MU4ab
-            {"minInvm": 2, "maxInvm": 8, "mult": 1, "otype1" : "MU", "ocut1": 6, "olist" : "ab", "otype2" : "MU","ocut2" : 4, "onebarrel": 0}, #2INVM8-MU6ab-MU4ab
-            {"minInvm": 2, "maxInvm": 9, "mult": 1, "otype1" : "MU", "ocut1": 6, "olist" : "ab", "otype2" : "MU","ocut2" : 4, "onebarrel": 0}, #2INVM9-MU6ab-MU4ab
-            {"minInvm": 8, "maxInvm": 15, "mult": 2, "otype1" : "MU", "ocut1": 6, "olist" : "ab", "otype2" : "",  "ocut2" : 0, "onebarrel": 0}, #8INVM15-2MU6ab
-            {"minInvm": 2, "maxInvm": 9, "mult": 2, "otype1" : "MU", "ocut1": 6, "olist" : "ab", "otype2" : "",  "ocut2" : 0, "onebarrel": 0},  #2INVM9-2MU6ab 
-            {"minInvm": 7, "maxInvm": 15, "mult": 2, "otype1" : "MU", "ocut1": 4, "olist" : "ab", "otype2" : "",  "ocut2" : 0, "onebarrel": 0}, #7INVM15-2MU4ab 
-
-            ]
-        if usev8:
-            listofalgos=[]
-
-        for x in listofalgos:
-            class d:
-                pass
-            for k in x:
-                setattr (d, k, x[k])
- 
-            obj1 = "%s%s%s%s" % ((str(d.mult) if d.mult>1 else ""), d.otype1, str(d.ocut1), d.olist)
-            obj2 = "-%s%s%s" % (d.otype2, str(d.ocut2), d.olist)
-            toponame = "%iINVM%i-%s%s%s"  % (d.minInvm, d.maxInvm, "ONEBARREL-" if d.onebarrel==1 else "", obj1, "" if d.mult>1 else obj2)
-
-            log.debug("Define %s", toponame)
-
-
-            inputList = [d.otype1 + d.olist] if (d.mult>1 or d.otype1==d.otype2) else [d.otype1 + d.olist, d.otype2 + d.olist]
-            algoname = AlgConf.InvariantMassInclusive1 if (d.mult>1 or d.otype1==d.otype2) else AlgConf.InvariantMassInclusive2
-            alg = algoname( name = toponame,  inputs = inputList, outputs = [ toponame ])
-
-            if (d.mult>1 or d.otype1==d.otype2):
-                alg.addgeneric('InputWidth', HW.OutputWidthSelectMU) 
-                alg.addgeneric('MaxTob', HW.OutputWidthSelectMU)
-                alg.addgeneric('RequireOneBarrel', d.onebarrel)
-            else:
-                alg.addgeneric('InputWidth1', HW.OutputWidthSelectMU)
-                alg.addgeneric('InputWidth2', HW.OutputWidthSelectMU) 
-                alg.addgeneric('MaxTob1', HW.OutputWidthSelectMU)
-                alg.addgeneric('MaxTob2', HW.OutputWidthSelectMU)
 
-            alg.addgeneric('NumResultBits', 1)
-            alg.addvariable('MinET1', d.ocut1)
-            alg.addvariable('MinET2', d.ocut2 if d.ocut2>0 else d.ocut1)
-            alg.addvariable('MinMSqr', d.minInvm * d.minInvm)
-            alg.addvariable('MaxMSqr', d.maxInvm * d.maxInvm)
-            tm.registerTopoAlgo(alg)
 
         # dimu DR items
-        if usev8:
-            listofalgos=[  
+        listofalgos=[  
             {"minDr": 0, "maxDr": 15, "mult": 2, "otype1" : "MU", "ocut1": 6,  "olist" : "ab", "otype2" : "",   "ocut2": 6, "onebarrel": 0}, #0DR15-2MU6ab  
-            ]
-        else:
-            listofalgos=[
-            {"minDr": 2, "maxDr": 99, "mult": 2, "otype1" : "MU" ,"ocut1": 4,  "olist" : "ab", "otype2" : "",   "ocut2": 4, "onebarrel": 0}, # SM Y  x, 2DR99-2MU4ab
-            {"minDr": 0, "maxDr": 10, "mult": 1, "otype1" : "MU" ,"ocut1": 10, "olist" : "ab", "otype2" : "MU", "ocut2": 6, "onebarrel": 0}, # Exotic LFV x, 0DR10-MU10ab-MU6ab
-            {"minDr": 2, "maxDr": 15, "mult": 2, "otype1" : "MU" ,"ocut1": 6,  "olist" : "ab", "otype2" : "",   "ocut2": 6, "onebarrel": 0},   #x, 2DR15-2MU6ab
-            {"minDr": 0, "maxDr": 15, "mult": 2, "otype1" : "MU" ,"ocut1": 4,  "olist" : "ab", "otype2" : "",   "ocut2": 4, "onebarrel": 0}, #0DR15-2MU4ab
-            {"minDr": 0, "maxDr": 15, "mult": 1, "otype1" : "MU", "ocut1": 6,  "olist" : "ab", "otype2" : "MU", "ocut2": 4, "onebarrel": 0}, #0DR15-MU6ab-MU4ab
-            {"minDr": 0, "maxDr": 34, "mult": 2, "otype1" : "MU" ,"ocut1": 4,  "olist" : "ab", "otype2" : "",   "ocut2": 4, "onebarrel": 0}, #0DR34-2MU4ab 
-            {"minDr": 0, "maxDr": 24, "mult": 2, "otype1" : "MU" ,"ocut1": 4,  "olist" : "ab", "otype2" : "",   "ocut2": 4, "onebarrel": 0}, #0DR24-2MU4ab 
-            {"minDr": 0, "maxDr": 22, "mult": 2, "otype1" : "MU" ,"ocut1": 6,  "olist" : "ab", "otype2" : "",   "ocut2": 6, "onebarrel": 0}, #0DR22-2MU6ab
-            {"minDr": 0, "maxDr": 22, "mult": 1, "otype1" : "MU", "ocut1": 6,  "olist" : "ab", "otype2" : "MU", "ocut2": 4, "onebarrel": 0}, #0DR22-MU6ab-MU4ab
-            {"minDr": 0, "maxDr": 15, "mult": 2, "otype1" : "MU", "ocut1": 6,  "olist" : "ab", "otype2" : "",   "ocut2": 6, "onebarrel": 0}, #0DR15-2MU6ab  
-            ]
-
+        ]
         for x in listofalgos:
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
             obj1 = "%s%s%s%s" % ((str(d.mult) if d.mult>1 else ""), d.otype1, str(d.ocut1), d.olist)
             obj2 = "-%s%s%s" % (d.otype2, str(d.ocut2), d.olist)
             toponame = "%iDR%i-%s%s%s"  % (d.minDr, d.maxDr, "ONEBARREL-" if d.onebarrel==1 else "", obj1, "" if d.mult>1 else obj2)
-
             log.debug("Define %s", toponame)
-
             inputList = [d.otype1 + d.olist] if (d.mult>1 or d.otype1==d.otype2) else [d.otype1 + d.olist, d.otype2 + d.olist]
             algoname = AlgConf.DeltaRSqrIncl1 if (d.mult>1 or d.otype1==d.otype2) else AlgConf.DeltaRSqrIncl2
-            alg = algoname( name = toponame,  inputs = inputList, outputs = [ toponame ])
- 
+            alg = algoname( name = toponame,  inputs = inputList, outputs = [ toponame ]) 
             if (d.mult>1 or d.otype1==d.otype2):
                 alg.addgeneric('InputWidth', HW.OutputWidthSelectMU)
                 alg.addgeneric('MaxTob', HW.OutputWidthSelectMU)
@@ -481,8 +389,6 @@ class TopoAlgoDef:
                 alg.addgeneric('InputWidth2', HW.OutputWidthSelectMU) 
                 alg.addgeneric('MaxTob1', HW.OutputWidthSelectMU)
                 alg.addgeneric('MaxTob2', HW.OutputWidthSelectMU)
-
-
             alg.addgeneric('NumResultBits', 1)
             alg.addvariable('MinET1', d.ocut1)
             alg.addvariable('MinET2', d.ocut2)
@@ -493,32 +399,23 @@ class TopoAlgoDef:
             
         # deta-dphi with ab+ab
         algolist=[
-        {"minDeta": 5, "maxDeta": 99, "minDphi": 5, "maxDphi": 99, "mult": 1, "otype1" : "MU", "ocut1": 6, "olist1" : "ab", "nleading1": HW.OutputWidthSelectMU, "otype2" : "MU", "ocut2": 4, "olist2": "ab", "nleading2": HW.OutputWidthSelectMU}, #5DETA99-5DPHI99-MU6ab-MU4ab
-        {"minDeta": 5, "maxDeta": 99, "minDphi": 5, "maxDphi": 99, "mult": 2, "otype1" : "MU", "ocut1": 6, "olist1" : "ab", "nleading1": HW.OutputWidthSelectMU, "otype2" : "", "ocut2": 6, "olist2": "", "nleading2": HW.OutputWidthSelectMU}, #5DETA99-5DPHI99-2MU6ab           
-        ]            
-        if usev8:
-            algolist += [
+            {"minDeta": 5, "maxDeta": 99, "minDphi": 5, "maxDphi": 99, "mult": 1, "otype1" : "MU", "ocut1": 6, "olist1" : "ab", "nleading1": HW.OutputWidthSelectMU, "otype2" : "MU", "ocut2": 4, "olist2": "ab", "nleading2": HW.OutputWidthSelectMU}, #5DETA99-5DPHI99-MU6ab-MU4ab
+            {"minDeta": 5, "maxDeta": 99, "minDphi": 5, "maxDphi": 99, "mult": 2, "otype1" : "MU", "ocut1": 6, "olist1" : "ab", "nleading1": HW.OutputWidthSelectMU, "otype2" : "", "ocut2": 6, "olist2": "", "nleading2": HW.OutputWidthSelectMU}, #5DETA99-5DPHI99-2MU6ab           
             {"minDeta": 5, "maxDeta": 99, "minDphi": 5, "maxDphi": 99, "mult": 2, "otype1" : "MU", "ocut1": 4, "olist1" : "ab", "nleading1": HW.OutputWidthSelectMU, "otype2" : "", "ocut2": 4, "olist2": "", "nleading2": HW.OutputWidthSelectMU}, #5DETA99-5DPHI99-2MU4ab
-            ]
-        for x in algolist:
-            
+        ]
+        for x in algolist:            
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
             obj1 = "%s%s%s%s" % ((str(d.mult) if d.mult>1 else ""), d.otype1, str(d.ocut1), d.olist1)
             obj2 = "-%s%s%s" % (d.otype2, str(d.ocut2) if d.ocut2>0 else "", d.olist2)
-            toponame = "%sDETA%s-%sDPHI%s-%s%s"  % (d.minDeta, d.maxDeta, d.minDphi, d.maxDphi, obj1, "" if d.mult>1 else obj2)
-            
-            log.debug("Define %s", toponame)
-            
+            toponame = "%sDETA%s-%sDPHI%s-%s%s"  % (d.minDeta, d.maxDeta, d.minDphi, d.maxDphi, obj1, "" if d.mult>1 else obj2)            
+            log.debug("Define %s", toponame)            
             inputList = [d.otype1 + d.olist1] if (d.mult>1 or d.otype1==d.otype2) else [d.otype1 + d.olist1, d.otype2 + d.olist2]
             algoname = AlgConf.DeltaEtaPhiIncl1 if (d.mult>1 or d.otype1==d.otype2) else AlgConf.DeltaEtaPhiIncl2
             alg = algoname( name = toponame, inputs = inputList, outputs = [ toponame ])
-            alg.addgeneric('NumResultBits', 1)                        
-
-            
+            alg.addgeneric('NumResultBits', 1)            
             if (d.mult>1 or d.otype1==d.otype2):
                 alg.addgeneric('InputWidth', d.nleading1)
                 alg.addgeneric('MaxTob', d.nleading1)
@@ -538,36 +435,33 @@ class TopoAlgoDef:
                 alg.addvariable('DeltaPhiMin', d.minDphi)
                 alg.addvariable('DeltaPhiMax', d.maxDphi)
                 alg.addvariable('MinET1', d.ocut1)
-                alg.addvariable('MinET2', d.ocut2)
-            
+                alg.addvariable('MinET2', d.ocut2)            
             tm.registerTopoAlgo(alg)
 
 
         algolist=[
-               {"minDr": 0, "maxDr": 28, "otype1" : "MU" ,"ocut1": 10, "olist1" : "ab", "nleading1": HW.OutputWidthSelectMU, "inputwidth1": HW.OutputWidthSelectMU, "otype2" : "TAU", "ocut2": 12, "olist2" : "abi", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU},   # 0DR28-MU10ab-TAU12abi
-               {"minDr": 0, "maxDr": 28, "otype1" : "TAU" ,"ocut1": 20, "olist1" : "abi","nleading1": HW.OutputWidthSelectTAU, "inputwidth1": HW.OutputWidthSelectTAU,"otype2" : "TAU", "ocut2": 12, "olist2" : "abi", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU}, # 0DR28-TAU20abi-TAU12abi
-               {"minDr": 0, "maxDr": 25, "otype1" : "TAU" ,"ocut1": 20, "olist1" : "abi","nleading1": HW.OutputWidthSelectTAU, "inputwidth1": HW.OutputWidthSelectTAU,"otype2" : "TAU", "ocut2": 12, "olist2" : "abi", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU}, # 0DR25-TAU20abi-TAU12abi
-            ] 
-
-
+            { "minDr": 0, "maxDr": 28, "otype1" : "MU" ,"ocut1": 10, "olist1" : "ab",
+              "nleading1": HW.OutputWidthSelectMU, "inputwidth1": HW.OutputWidthSelectMU, "otype2" : "TAU", "ocut2": 12, "olist2" : "abi",
+              "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU},   # 0DR28-MU10ab-TAU12abi
+            { "minDr": 0, "maxDr": 28, "otype1" : "TAU" ,"ocut1": 20, "olist1" : "abi",
+              "nleading1": HW.OutputWidthSelectTAU, "inputwidth1": HW.OutputWidthSelectTAU,"otype2" : "TAU", "ocut2": 12, "olist2" : "abi",
+              "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU}, # 0DR28-TAU20abi-TAU12abi
+            { "minDr": 0, "maxDr": 25, "otype1" : "TAU" ,"ocut1": 20, "olist1" : "abi",
+              "nleading1": HW.OutputWidthSelectTAU, "inputwidth1": HW.OutputWidthSelectTAU,"otype2" : "TAU", "ocut2": 12, "olist2" : "abi",
+              "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU}, # 0DR25-TAU20abi-TAU12abi
+        ]
         for x in algolist:
-
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
             obj1 = "%s%s%s" % (d.otype1, str(d.ocut1), d.olist1)
             obj2 = "-%s%s%s" % (d.otype2, str(d.ocut2), d.olist2)
             toponame = "%iDR%i-%s%s"  % (d.minDr, d.maxDr, obj1, obj2)
-
             log.debug("Define %s", toponame)
-            
             inputList = [d.otype1 + d.olist1] if d.otype1==d.otype2 else [d.otype1 + d.olist1, d.otype2 + d.olist2]
             algoname = AlgConf.DeltaRSqrIncl1 if d.otype1==d.otype2 else AlgConf.DeltaRSqrIncl2
             alg = algoname( name = toponame,  inputs = inputList, outputs = [ toponame ])
-
-                            
             if d.otype1==d.otype2:
                 alg.addgeneric('InputWidth', d.inputwidth1)
                 alg.addgeneric('MaxTob', d.nleading1)
@@ -576,9 +470,7 @@ class TopoAlgoDef:
                 alg.addgeneric('InputWidth2', d.inputwidth2)
                 alg.addgeneric('MaxTob1', d.nleading1)
                 alg.addgeneric('MaxTob2', d.nleading2)
-
             alg.addgeneric('NumResultBits', 1)
-
             if d.otype1==d.otype2:
                 alg.addvariable('MinET1', d.ocut1)
                 alg.addvariable('MinET2', d.ocut2)
@@ -588,41 +480,24 @@ class TopoAlgoDef:
                 alg.addvariable('MinET1', d.ocut1, 0)
                 alg.addvariable('MinET2', d.ocut2, 0)
                 alg.addvariable('DeltaRMin', d.minDr*d.minDr, 0)
-                alg.addvariable('DeltaRMax', d.maxDr*d.maxDr, 0)
-                
+                alg.addvariable('DeltaRMax', d.maxDr*d.maxDr, 0)                
             tm.registerTopoAlgo(alg)        
             
+
         # (ATR-8194) L1Topo HT Trigger
-        if usev8:
-            algoList = [
-            {"minHT": 150, "otype" : "J", "ocut" : 20, "olist" : "s",   "nleading" : 5, "inputwidth": HW.OutputWidthSortJET, "oeta" : 31}, #HT150-J20s5pETA31
-            {"minHT": 190, "otype" : "J", "ocut" : 15, "olist" : "s",   "nleading" : 5, "inputwidth": HW.OutputWidthSortJET, "oeta" : 21}, #HT190-J15s5pETA21
-            ]
-        else:
-            algoList = [
+        algoList = [
             {"minHT": 150, "otype" : "J", "ocut" : 20, "olist" : "s",   "nleading" : 5, "inputwidth": HW.OutputWidthSortJET, "oeta" : 31}, #HT150-J20s5pETA31
             {"minHT": 190, "otype" : "J", "ocut" : 15, "olist" : "s",   "nleading" : 5, "inputwidth": HW.OutputWidthSortJET, "oeta" : 21}, #HT190-J15s5pETA21
-            {"minHT": 190, "otype" : "AJ", "ocut" : 15, "olist" : "all", "nleading" : HW.InputWidthJET, "inputwidth": HW.InputWidthJET, "oeta" : 21}, #HT190-AJ15allpETA21
-            {"minHT": 150, "otype" : "AJ", "ocut" : 20, "olist" : "all", "nleading" : HW.InputWidthJET, "inputwidth": HW.InputWidthJET, "oeta" : 31}, #HT150-AJ20allpETA31
-            {"minHT": 150, "otype" : "AJj","ocut" : 15, "olist" : "all", "nleading" : HW.InputWidthJET, "inputwidth": HW.InputWidthJET, "oeta" : 49}, #HT150-AJj15allpETA49
-            {"minHT": 20,  "otype" : "AJj","ocut" : 15,  "olist" : "all", "nleading" : HW.InputWidthJET, "inputwidth": HW.InputWidthJET, "oeta" : 49}, #HT20-AJj15allpETA49
-            ]
-        for x in algoList:
-            
+        ]
+        for x in algoList:            
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-                
             toponame = "HT%d-%s%s%s%spETA%s" % (d.minHT, d.otype, str(d.ocut), d.olist, str(d.nleading) if d.olist=="s" else "", str(d.oeta))
-            
             log.debug("Define %s", toponame)
-            
             inputList = d.otype + d.olist
-
             alg = AlgConf.JetHT( name = toponame, inputs = inputList, outputs = [toponame] )
-
-
             alg.addgeneric('InputWidth', d.inputwidth)
             alg.addgeneric('MaxTob', d.nleading)
             alg.addgeneric('NumRegisters', 2 if d.olist=="all" else 0)
@@ -633,30 +508,21 @@ class TopoAlgoDef:
             alg.addvariable('MinHt', d.minHT)
             tm.registerTopoAlgo(alg)  
 
-        # INVM_EM for Jpsi
-        if usev8:    
-            invm_map = {"algoname": 'INVM_EMs6' , "ocutlist": [ 7, 12 ], "minInvm": 1, "maxInvm": 5, "otype" : "EM", "olist" : "s", "nleading" : 1, "inputwidth": HW.OutputWidthSortEM}
-        else:
-            invm_map = {"algoname": 'INVM_EMs6' , "ocutlist": [ 0, 7, 12 ], "minInvm": 1, "maxInvm": 5, "otype" : "EM", "olist" : "s", "nleading" : 1, "inputwidth": HW.OutputWidthSortEM}
 
-        for x in [ invm_map,
-            ]:
-            
+        # INVM_EM for Jpsi
+        invm_map = { "algoname": 'INVM_EMs6' , "ocutlist": [ 7, 12 ], "minInvm": 1, "maxInvm": 5, "otype" : "EM", "olist" : "s",
+                     "nleading" : 1, "inputwidth": HW.OutputWidthSortEM}
+        for x in [ invm_map ]:
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
             inputList = d.otype + d.olist
             toponames=[]
-
             for ocut in d.ocutlist:
-                toponame = "%iINVM%i-%s%s%s%s-EMs6"   % (d.minInvm, d.maxInvm, d.otype, str(ocut) if ocut > 0 else "", d.olist, str(d.nleading) if d.olist=="s" else "")
+                toponame = "%iINVM%i-%s%s%s%s-EMs6" % (d.minInvm, d.maxInvm, d.otype, str(ocut) if ocut > 0 else "", d.olist, str(d.nleading) if d.olist=="s" else "")
                 toponames.append(toponame)
-
             alg = AlgConf.InvariantMassInclusive2( name = d.algoname, inputs = [inputList, 'EMs'], outputs = toponames)
-
-
             alg.addgeneric('InputWidth1', d.inputwidth)
             #alg.addgeneric('InputWidth2', HW.InputWidthEM)
             alg.addgeneric('InputWidth2', HW.OutputWidthSortEM)
@@ -664,109 +530,30 @@ class TopoAlgoDef:
             #alg.addgeneric('MaxTob2', HW.InputWidthEM)
             alg.addgeneric('MaxTob2', HW.OutputWidthSortEM)
             alg.addgeneric('NumResultBits', len(toponames))
-
             for bitid, ocut in enumerate(d.ocutlist):
                 alg.addvariable('MinET1', ocut, bitid)
                 alg.addvariable('MinET2', 0, bitid)
                 alg.addvariable('MinMSqr', (d.minInvm * _emscale_for_decision)*(d.minInvm * _emscale_for_decision), bitid)
                 alg.addvariable('MaxMSqr', (d.maxInvm * _emscale_for_decision)*(d.maxInvm * _emscale_for_decision), bitid)
-                
-            tm.registerTopoAlgo(alg)
-
-        # W T&P: MINDPHI(J, XE0), (EM, XE0)
-
-
-        if not usev8:
-            alglist = [
-                {"minDPhi":  5, "otype" : "AJj", "ocut" : 10, "olist" : "s", "nleading" : 6, "inputwidth": HW.OutputWidthSortJET},
-                {"minDPhi": 10, "otype" : "AJj", "ocut" : 10, "olist" : "s", "nleading" : 6, "inputwidth": HW.OutputWidthSortJET},
-                {"minDPhi": 15, "otype" : "AJj", "ocut" : 10, "olist" : "s", "nleading" : 6, "inputwidth": HW.OutputWidthSortJET},
-                {"minDPhi":  5, "otype" : "EM",  "ocut" : 12, "olist" : "s", "nleading" : 6, "inputwidth": HW.OutputWidthSortEM},#new
-                #{"minDPhi": 10, "otype" : "EM",  "ocut" : 12, "olist" : "s", "nleading" : 6, "inputwidth": HW.OutputWidthSortEM},#new
-                {"minDPhi":  5, "otype" : "EM",  "ocut" : 15, "olist" : "s", "nleading" : 6, "inputwidth": HW.OutputWidthSortEM},#same
-            ]
-        if usev8:
-            alglist = []
-
-        for x in alglist:
-            
-            class d:
-                pass
-            for k in x:
-                setattr (d, k, x[k])
-                
-            toponame = "%02dMINDPHI-%s%s%s%s-XE0"  % (d.minDPhi, d.otype, str(d.ocut) if d.ocut > 0 else "", d.olist, str(d.nleading) if d.olist=="s" else "")
-            log.debug("Define %s", toponame)
-
-            inputList = d.otype + d.olist
-
-            alg = AlgConf.MinDeltaPhiIncl2( name = toponame, inputs = [ inputList, 'XE'], outputs = [ toponame ] )
-
-
-            alg.addgeneric('InputWidth1', d.inputwidth)
-            alg.addgeneric('InputWidth2', 1) 
-            alg.addgeneric('MaxTob1', d.nleading)
-            alg.addgeneric('MaxTob2', 1)
-            alg.addgeneric('NumResultBits', 1)
-            alg.addvariable('MinET1', d.ocut)
-            alg.addvariable('MinET2', 0)
-            alg.addvariable('DeltaPhiMin', d.minDPhi, 0)
             tm.registerTopoAlgo(alg)
 
-        # W T&P MT
-
-        if not usev8:
-            alglistmt = [
-                {"minMT": 25, "otype" : "EM", "ocut" : "12", "olist" : "s", "nleading" : 6, "inputwidth": HW.OutputWidthSortEM},
-                {"minMT": 35, "otype" : "EM", "ocut" : "15", "olist" : "s", "nleading" : 6, "inputwidth": HW.OutputWidthSortEM},
-            ]
-        if usev8:
-            alglistmt = []
-        for x in alglistmt:
-            class d:
-                pass
-            for k in x:
-                setattr (d, k, x[k])
-
-            toponame = "%iMT-%s%s%s%s-XE0"  % (d.minMT, d.otype, str(d.ocut) if d.ocut > 0 else "", d.olist, str(d.nleading) if d.olist=="s" else "")
-            log.debug("Define %s", toponame)
-
-            inputList = d.otype + d.olist
-            
-            alg = AlgConf.TransverseMassInclusive1( name = toponame, inputs = [ inputList, 'XE'], outputs = [ toponame ] )
-
-
-
-            alg.addgeneric('InputWidth', HW.OutputWidthSortEM)
-            alg.addgeneric('MaxTob', str(d.nleading))
-            alg.addgeneric('NumResultBits', 1)
-            alg.addvariable('MinET1', str(d.ocut))
-            alg.addvariable('MinET2', 0)
-            alg.addvariable('MinMTSqr', d.minMT*d.minMT)
-            tm.registerTopoAlgo(alg)
-            
-        # VBF deta    
 
+        # VBF deta
         algoList = [
-            {"minDeta": 0,  "maxDeta": 20, "otype" : "J",  "ocut1" : 50,  "olist" : "s", "nleading1" : 1, "inputwidth1": HW.OutputWidthSortJET, "ocut2" : 0, "nleading2": 2}, #0DETA20-J50s1-Js2
+            { "minDeta": 0,  "maxDeta": 20, "otype" : "J",  "ocut1" : 50,  "olist" : "s", 
+              "nleading1" : 1, "inputwidth1": HW.OutputWidthSortJET, "ocut2" : 0, "nleading2": 2}, #0DETA20-J50s1-Js2
         ]
         for x in algoList:                 
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
             toponame = "%iDETA%i-%s%s%s%s-%s%s%s%s"  % (d.minDeta, d.maxDeta,
-                                                        d.otype, str(d.ocut1) if d.ocut1 > 0 else "", d.olist, str(d.nleading1) if d.olist=="s" else "",
-                                                        d.otype, str(d.ocut2) if d.ocut2 > 0 else "", d.olist, str(d.nleading2) if d.olist=="s" else "")
-            
+                                                        d.otype, d.ocut1 if d.ocut1 > 0 else "", d.olist, d.nleading1 if d.olist=="s" else "",
+                                                        d.otype, d.ocut2 if d.ocut2 > 0 else "", d.olist, d.nleading2 if d.olist=="s" else "")            
             log.debug("Define %s", toponame)
-            inputList = d.otype + d.olist
-            
+            inputList = d.otype + d.olist            
             alg = AlgConf.DeltaEtaIncl1( name = toponame, inputs = inputList, outputs = toponame )
-
-
-
             alg.addgeneric('InputWidth', d.inputwidth1)
             alg.addgeneric('MaxTob', d.nleading2)
             alg.addgeneric('NumResultBits', 1)                        
@@ -775,37 +562,24 @@ class TopoAlgoDef:
             alg.addvariable('MinDeltaEta', d.minDeta, 0)
             alg.addvariable('MaxDeltaEta', d.maxDeta, 0)
             tm.registerTopoAlgo(alg)
-            
-        # ZH Trigger
-
-        if usev8:
-            supportedalgolist = [
-               {"minDPhi": 10, "otype" : "J", "ocut" : 20, "olist" : "s", "nleading" : 2, "inputwidth": HW.OutputWidthSortJET, "ocut2": 30 }, #10MINDPHI-J20s2-XE30
-               {"minDPhi": 10, "otype" : "J", "ocut" : 20, "olist" : "s", "nleading" : 2, "inputwidth": HW.OutputWidthSortJET, "ocut2": 50 }, #10MINDPHI-J20s2-XE50
-            ]
-        else:
-            supportedalgolist = [
-               #{"minDPhi": 10, "otype" : "J", "ocut" : 0,  "olist" : "s", "nleading" : 2, "inputwidth": HW.OutputWidthSortJET, "ocut2": 50 },
-               {"minDPhi": 10, "otype" : "J", "ocut" : 20, "olist" : "s", "nleading" : 2, "inputwidth": HW.OutputWidthSortJET, "ocut2": 50 }, #10MINDPHI-J20s2-XE50
-               {"minDPhi": 10, "otype" : "J", "ocut" : 20, "olist" : "ab", "nleading" : HW.OutputWidthSelectJET, "inputwidth": HW.OutputWidthSelectJET, "ocut2": 50}, #10MINDPHI-J20ab-XE50
-               {"minDPhi": 10, "otype" : "CJ","ocut" : 20, "olist" : "ab", "nleading" : HW.OutputWidthSelectJET, "inputwidth": HW.OutputWidthSelectJET, "ocut2": 50}, #10MINDPHI-CJ20ab-XE50
-               {"minDPhi": 10, "otype" : "J", "ocut" : 20, "olist" : "s", "nleading" : 2, "inputwidth": HW.OutputWidthSortJET, "ocut2": 30 }, #10MINDPHI-J20s2-XE30
-            ]
 
-        for x in supportedalgolist:
             
+        # ZH Trigger
+        supportedalgolist = [
+            { "minDPhi": 10, "otype" : "J", "ocut" : 20, "olist" : "s",
+              "nleading" : 2, "inputwidth": HW.OutputWidthSortJET, "ocut2": 30 }, #10MINDPHI-J20s2-XE30
+            { "minDPhi": 10, "otype" : "J", "ocut" : 20, "olist" : "s",
+              "nleading" : 2, "inputwidth": HW.OutputWidthSortJET, "ocut2": 50 }, #10MINDPHI-J20s2-XE50
+        ]
+        for x in supportedalgolist:            
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-                
             toponame = "%iMINDPHI-%s%s%s%s-XE%i"  % (d.minDPhi, d.otype, str(d.ocut) if d.ocut > 0 else "", d.olist, str(d.nleading) if d.olist=="s" else "",d.ocut2)
             log.debug("Define %s", toponame)
-            
             inputList = d.otype + d.olist
-
             alg = AlgConf.MinDeltaPhiIncl2( name = toponame, inputs = [inputList, 'XE'], outputs = [ toponame ] )
-
             alg.addgeneric('InputWidth1', d.inputwidth)
             alg.addgeneric('InputWidth2', 1)  
             alg.addgeneric('MaxTob1', d.nleading)
@@ -815,36 +589,22 @@ class TopoAlgoDef:
             alg.addvariable('MinET2', d.ocut2)
             alg.addvariable('DeltaPhiMin', d.minDPhi, 0)
             tm.registerTopoAlgo(alg)
+
             
         # added for muon-jet:
-        if not usev8:
-            algoList = [
-              {"minDr": 0, "maxDr": 4, "otype1" : "MU" ,"ocut1": 4,  "olist1" : "ab", "otype2" : "CJ", "ocut2": 15, "olist2" : "ab"}, #0DR04-MU4ab-CJ15ab
-              {"minDr": 0, "maxDr": 4, "otype1" : "MU" ,"ocut1": 4,  "olist1" : "ab", "otype2" : "CJ", "ocut2": 30, "olist2" : "ab"}, #0DR04-MU4ab-CJ30ab
-              {"minDr": 0, "maxDr": 4, "otype1" : "MU" ,"ocut1": 6,  "olist1" : "ab", "otype2" : "CJ", "ocut2": 20, "olist2" : "ab"}, #0DR04-MU4ab-CJ20ab
-              {"minDr": 0, "maxDr": 4, "otype1" : "MU" ,"ocut1": 6,  "olist1" : "ab", "otype2" : "CJ", "ocut2": 25, "olist2" : "ab"}, #0DR04-MU6ab-CJ25ab
-              {"minDr": 0, "maxDr": 4, "otype1" : "MU" ,"ocut1": 4,  "olist1" : "ab", "otype2" : "CJ", "ocut2": 20, "olist2" : "ab"}, #0DR04-MU6ab-CJ20ab
-            ]
-        if usev8:
-            algoList = [
-              {"minDr": 0, "maxDr": 4, "otype1" : "MU" ,"ocut1": 4,  "olist1" : "ab", "otype2" : "CJ", "ocut2": 15, "olist2" : "ab"}, #0DR04-MU4ab-CJ15ab
-              {"minDr": 0, "maxDr": 4, "otype1" : "MU" ,"ocut1": 6,  "olist1" : "ab", "otype2" : "CJ", "ocut2": 20, "olist2" : "ab"}, #0DR04-MU6ab-CJ20ab
-            ]
-
+        algoList = [
+            {"minDr": 0, "maxDr": 4, "otype1" : "MU" ,"ocut1": 4,  "olist1" : "ab", "otype2" : "CJ", "ocut2": 15, "olist2" : "ab"}, #0DR04-MU4ab-CJ15ab
+            {"minDr": 0, "maxDr": 4, "otype1" : "MU" ,"ocut1": 6,  "olist1" : "ab", "otype2" : "CJ", "ocut2": 20, "olist2" : "ab"}, #0DR04-MU6ab-CJ20ab
+        ]
         for x in algoList:
-
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
             toponame = "%iDR%02d-%s%s%s-%s%s%s"  % (d.minDr, d.maxDr, d.otype1, str(d.ocut1), d.olist1, d.otype2, str(d.ocut2), d.olist2)
             log.debug("Define %s", toponame)
-
             inputList = [d.otype1 + d.olist1, d.otype2 + d.olist2]
-
             alg = AlgConf.DeltaRSqrIncl2( name = toponame, inputs = inputList, outputs = [ toponame ])
-
             alg.addgeneric('InputWidth1', HW.OutputWidthSelectMU)
             alg.addgeneric('InputWidth2', HW.OutputWidthSelectJET)
             alg.addgeneric('MaxTob1', HW.OutputWidthSelectMU)
@@ -858,10 +618,11 @@ class TopoAlgoDef:
 
 
         # MULT-BIT            
-        for x in [
-            {"otype1" : "CMU" ,"ocut1": 4, "olist1" : "ab", "nleading1": HW.OutputWidthSelectMU, "inputwidth1": HW.OutputWidthSelectMU}, #MULT-CMU4ab
-            {"otype1" : "CMU" ,"ocut1": 6, "olist1" : "ab", "nleading1": HW.OutputWidthSelectMU, "inputwidth1": HW.OutputWidthSelectMU}, #MULT-CMU6ab
-            ]:
+        algoList = [
+                {"otype1" : "CMU" ,"ocut1": 4, "olist1" : "ab", "nleading1": HW.OutputWidthSelectMU, "inputwidth1": HW.OutputWidthSelectMU}, #MULT-CMU4ab
+                {"otype1" : "CMU" ,"ocut1": 6, "olist1" : "ab", "nleading1": HW.OutputWidthSelectMU, "inputwidth1": HW.OutputWidthSelectMU}, #MULT-CMU6ab
+        ]
+        for x in algoList:
             class d:
                 pass
             for k in x:
@@ -892,208 +653,50 @@ class TopoAlgoDef:
         tm.registerTopoAlgo(alg)
 
 
-        if not usev8:
-            algolist=[
-                {"minInvm": 2, "maxInvm": 8, "mult": 1, "otype1" : "CMU","ocut1": 4, "olist" : "ab", "otype2" :"MU", "ocut2" : 4, "onebarrel": 0}, #2INVM8-CMU4ab-MU4ab
-                {"minInvm": 2, "maxInvm": 8, "mult": 1, "otype1" : "MU", "ocut1": 6, "olist" : "ab", "otype2" : "MU","ocut2" : 4, "onebarrel": 1}, #2INVM8-ONEBARREL-MU6ab-MU4ab
-            ]
-        if usev8:
-            algolist=[]
-
-        for x in algolist:
-
+        # LFV DETA ATR-14282
+        algoList = [
+            { "minDeta": 0, "maxDeta": "04", "mult": 1, "otype1" : "EM", "ocut1": 8, "olist1" : "abi",
+              "nleading1": HW.OutputWidthSelectEM, "otype2" : "MU", "ocut2": 10, "olist2": "ab",
+              "nleading2": HW.OutputWidthSelectMU}, #0DETA04-EM8abi-MU10ab
+            { "minDeta": 0, "maxDeta": "04", "mult": 1,
+              "otype1" : "EM", "ocut1": 15, "olist1" : "abi", "nleading1": HW.OutputWidthSelectEM,
+              "otype2" : "MU", "ocut2": 0, "olist2": "ab", "nleading2": HW.OutputWidthSelectMU}, #0DETA04-EM15abi-MUab
+        ]
+        for x in algoList:
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
-            obj1 = "%s%s%s%s" % ((str(d.mult) if d.mult>1 else ""), d.otype1, str(d.ocut1), d.olist)
-            obj2 = "-%s%s%s" % (d.otype2, str(d.ocut2), d.olist)
-            toponame = "%iINVM%i-%s%s%s"  % (d.minInvm, d.maxInvm, "ONEBARREL-" if d.onebarrel==1 else "", obj1, "" if d.mult>1 else obj2)
-
+            toponame = "%sDETA%s-%s%i%s-%s%s%s"  % (d.minDeta, d.maxDeta, d.otype1, d.ocut1, d.olist1, d.otype2, str(d.ocut2) if d.ocut2>0 else "", d.olist2)
             log.debug("Define %s", toponame)
-
-
-            inputList = [d.otype1 + d.olist] if (d.mult>1 or d.otype1==d.otype2) else [d.otype1 + d.olist, d.otype2 + d.olist]
-            algoname = AlgConf.InvariantMassInclusive1 if (d.mult>1 or d.otype1==d.otype2) else AlgConf.InvariantMassInclusive2
-            alg = algoname( name = toponame,  inputs = inputList, outputs = [ toponame ])
-            if (d.mult>1 or d.otype1==d.otype2):
-                alg.addgeneric('InputWidth', HW.OutputWidthSelectMU) 
-                alg.addgeneric('MaxTob', HW.OutputWidthSelectMU)
-                alg.addgeneric('RequireOneBarrel', d.onebarrel)
-            else:
-                alg.addgeneric('InputWidth1', HW.OutputWidthSelectMU)
-                alg.addgeneric('InputWidth2', HW.OutputWidthSelectMU) 
-                alg.addgeneric('MaxTob1', HW.OutputWidthSelectMU)
-                alg.addgeneric('MaxTob2', HW.OutputWidthSelectMU)
-
+            inputList = [d.otype1 + d.olist1, d.otype2 + d.olist2]
+            alg = AlgConf.DeltaEtaIncl2( name = toponame, inputs = inputList, outputs = [ toponame ])
             alg.addgeneric('NumResultBits', 1)
-            alg.addvariable('MinET1', d.ocut1)
-            alg.addvariable('MinET2', d.ocut2 if d.ocut2>0 else d.ocut1)
-            alg.addvariable('MinMSqr', d.minInvm * d.minInvm)
-            alg.addvariable('MaxMSqr', d.maxInvm * d.maxInvm)
+            alg.addgeneric('InputWidth1', d.nleading1)
+            alg.addgeneric('InputWidth2', d.nleading2)
+            alg.addgeneric('MaxTob1', d.nleading1)
+            alg.addgeneric('MaxTob2', d.nleading2)
+            alg.addvariable('MinET1', d.ocut1, 0)
+            alg.addvariable('MinET2', d.ocut2, 0)
+            alg.addvariable('MinDeltaEta', d.minDeta, 0)
+            alg.addvariable('MaxDeltaEta', d.maxDeta, 0)
             tm.registerTopoAlgo(alg)
 
-        # dimu DR items
-        if not usev8:
-            algolist=[#            {"minDr": 2, "maxDr": 15, "mult": 1, "otype1" : "CMU","ocut1": 4,  "olist" : "ab", "otype2" : "MU", "ocut2": 4, "onebarrel": 0},
-                #            {"minDr": 2, "maxDr": 15, "mult": 2, "otype1" : "CMU","ocut1": 4,  "olist" : "ab", "otype2" : "",   "ocut2": 4, "onebarrel": 0},
-                #            {"minDr": 2, "maxDr": 15, "mult": 1, "otype1" : "MU", "ocut1": 6,  "olist" : "ab", "otype2" : "MU","ocut2": 4, "onebarrel": 1},            
-                #            {"minDr": 2, "maxDr": 15, "mult": 1, "otype1" : "CMU","ocut1": 6,  "olist" : "ab", "otype2" : "CMU","ocut2": 4, "onebarrel": 0},
-
-                #SX
-                {"minDr": 0, "maxDr": 24, "mult": 2, "otype1" : "CMU","ocut1": 4,  "olist" : "ab", "otype2" : "",   "ocut2": 4, "onebarrel": 0}, #0DR24-2CMU4ab
-                {"minDr": 0, "maxDr": 24, "mult": 1, "otype1" : "CMU","ocut1": 4,  "olist" : "ab", "otype2" : "MU","ocut2": 4, "onebarrel": 0}, #0DR24-CMU4ab-MU4ab  
-            ]
-        if usev8:
-            algolist=[]
 
-        for x in algolist : 
+        algoList = [
+            {"minDphi": 0, "maxDphi": "03", "mult": 1, "otype1" : "EM", "ocut1": 8, "olist1" : "abi", "nleading1": HW.OutputWidthSelectEM, "otype2" : "MU", "ocut2": 10, "olist2": "ab", "nleading2": HW.OutputWidthSelectMU}, #0DPHI03-EM8abi-MU10ab
+            {"minDphi": 0, "maxDphi": "03", "mult": 1, "otype1" : "EM", "ocut1": 15, "olist1" : "abi", "nleading1": HW.OutputWidthSelectEM, "otype2" : "MU", "ocut2": 0, "olist2": "ab", "nleading2": HW.OutputWidthSelectMU}, #0DPHI03-EM15abi-MUab
+            ]
+        for x in algoList:
             class d:
                 pass
             for k in x:
-                setattr (d, k, x[k])
-
-            obj1 = "%s%s%s%s" % ((str(d.mult) if d.mult>1 else ""), d.otype1, str(d.ocut1), d.olist)
-            obj2 = "-%s%s%s" % (d.otype2, str(d.ocut2), d.olist)
-            toponame = "%iDR%i-%s%s%s"  % (d.minDr, d.maxDr, "ONEBARREL-" if d.onebarrel==1 else "", obj1, "" if d.mult>1 else obj2)
-
+                setattr (d, k, x[k])            
+            toponame = "%sDPHI%s-%s%s%s-%s%s%s"  % (d.minDphi, d.maxDphi, d.otype1, str(d.ocut1), d.olist1, d.otype2, str(d.ocut2) if d.ocut2>0 else "", d.olist2) 
             log.debug("Define %s", toponame)
-
-            inputList = [d.otype1 + d.olist] if (d.mult>1 or d.otype1==d.otype2) else [d.otype1 + d.olist, d.otype2 + d.olist]
-            algoname = AlgConf.DeltaRSqrIncl1 if (d.mult>1 or d.otype1==d.otype2) else AlgConf.DeltaRSqrIncl2
-            alg = algoname( name = toponame,  inputs = inputList, outputs = [ toponame ])
-            if (d.mult>1 or d.otype1==d.otype2):
-                alg.addgeneric('InputWidth', HW.OutputWidthSelectMU)
-                alg.addgeneric('MaxTob', HW.OutputWidthSelectMU)
-                alg.addgeneric('RequireOneBarrel', d.onebarrel)
-            else:
-                alg.addgeneric('InputWidth1', HW.OutputWidthSelectMU)
-                alg.addgeneric('InputWidth2', HW.OutputWidthSelectMU) 
-                alg.addgeneric('MaxTob1', HW.OutputWidthSelectMU)
-                alg.addgeneric('MaxTob2', HW.OutputWidthSelectMU)
-
-
-            alg.addgeneric('NumResultBits', 1)
-            alg.addvariable('MinET1', d.ocut1)
-            alg.addvariable('MinET2', d.ocut2)
-            alg.addvariable('DeltaRMin', d.minDr*d.minDr)
-            alg.addvariable('DeltaRMax', d.maxDr*d.maxDr)
-            tm.registerTopoAlgo(alg)
-
-        # deta-dphi with ab+ab
-        if usev8:
-            algoList = []
-#               {"minDeta": 0, "maxDeta": "04", "minDphi": 0, "maxDphi": "03", "mult": 1, "otype1" : "EM", "ocut1": 8, "olist1" : "abi", "nleading1": HW.OutputWidthSelectEM, "otype2" : "MU", "ocut2": 10, "olist2": "ab", "nleading2": HW.OutputWidthSelectMU},
-#               {"minDeta": 0, "maxDeta": "04", "minDphi": 0, "maxDphi": "03", "mult": 1, "otype1" : "EM", "ocut1": 15, "olist1" : "abi", "nleading1": HW.OutputWidthSelectEM, "otype2" : "MU", "ocut2": 0, "olist2": "ab", "nleading2": HW.OutputWidthSelectMU},
-#            ]
-        else:
-            algoList = [
-               {"minDeta": 0, "maxDeta": "04", "minDphi": 0, "maxDphi": "03", "mult": 1, "otype1" : "EM", "ocut1": 8, "olist1" : "abi", "nleading1": HW.OutputWidthSelectEM, "otype2" : "MU", "ocut2": 10, "olist2": "ab", "nleading2": HW.OutputWidthSelectMU},
-               {"minDeta": 0, "maxDeta": "04", "minDphi": 0, "maxDphi": "03", "mult": 1, "otype1" : "EM", "ocut1": 15, "olist1" : "abi", "nleading1": HW.OutputWidthSelectEM, "otype2" : "MU", "ocut2": 0, "olist2": "ab", "nleading2": HW.OutputWidthSelectMU},
-               {"minDeta": 0, "maxDeta": 20, "minDphi": 0, "maxDphi": 20, "mult": 1, "otype1" : "TAU", "ocut1": 20, "olist1" : "abi", "nleading1": HW.OutputWidthSelectTAU, "otype2" : "TAU", "ocut2": 12, "olist2": "abi", "nleading2": HW.OutputWidthSelectTAU}, #0DETA20-0DPHI20-TAU20abi-TAU12abi
-            ]
-
-        for x in algoList:                 
-            class d:
-                pass
-            for k in x:
-                setattr (d, k, x[k])
-
-            obj1 = "%s%s%s%s" % ((str(d.mult) if d.mult>1 else ""), d.otype1, str(d.ocut1), d.olist1)
-            obj2 = "-%s%s%s" % (d.otype2, str(d.ocut2) if d.ocut2>0 else "", d.olist2)
-            toponame = "%sDETA%s-%sDPHI%s-%s%s"  % (d.minDeta, d.maxDeta, d.minDphi, d.maxDphi, obj1, "" if d.mult>1 else obj2)
-            
-            log.debug("Define %s", toponame)
-            
-            inputList = [d.otype1 + d.olist1] if (d.mult>1 or d.otype1==d.otype2) else [d.otype1 + d.olist1, d.otype2 + d.olist2]
-            algoname = AlgConf.DeltaEtaPhiIncl1 if (d.mult>1 or d.otype1==d.otype2) else AlgConf.DeltaEtaPhiIncl2
-            
-            alg = algoname( name = toponame, inputs = inputList, outputs = [ toponame ])
-            alg.addgeneric('NumResultBits', 1)                        
-            
-            if (d.mult>1 or d.otype1==d.otype2):
-                alg.addgeneric('InputWidth', d.nleading1)
-                alg.addgeneric('MaxTob', d.nleading1)
-                alg.addvariable('MinET1', d.ocut1, 0)
-                alg.addvariable('MinET2', d.ocut2, 0)
-                alg.addvariable('MinDeltaEta', d.minDeta, 0)
-                alg.addvariable('MaxDeltaEta', d.maxDeta, 0)
-                alg.addvariable('MinDeltaPhi', d.minDphi, 0)
-                alg.addvariable('MaxDeltaPhi', d.maxDphi, 0)
-            else:
-                alg.addgeneric('InputWidth1', d.nleading1)
-                alg.addgeneric('InputWidth2', d.nleading2)
-                alg.addgeneric('MaxTob1', d.nleading1)
-                alg.addgeneric('MaxTob2', d.nleading2)
-                alg.addvariable('MinET1', d.ocut1, 0)
-                alg.addvariable('MinET2', d.ocut2, 0)
-                alg.addvariable('DeltaEtaMin', d.minDeta, 0)
-                alg.addvariable('DeltaEtaMax', d.maxDeta, 0)
-                alg.addvariable('DeltaPhiMin', d.minDphi, 0)
-                alg.addvariable('DeltaPhiMax', d.maxDphi, 0)
-
-            
-            tm.registerTopoAlgo(alg)
-
-        # LFV DETA ATR-14282
-        if usev7 or usev8:
-            algoList = [
-                {"minDeta": 0, "maxDeta": "04", "mult": 1, "otype1" : "EM", "ocut1": 8, "olist1" : "abi", "nleading1": HW.OutputWidthSelectEM, "otype2" : "MU", "ocut2": 10, "olist2": "ab", "nleading2": HW.OutputWidthSelectMU}, #0DETA04-EM8abi-MU10ab
-                {"minDeta": 0, "maxDeta": "04", "mult": 1, "otype1" : "EM", "ocut1": 15, "olist1" : "abi", "nleading1": HW.OutputWidthSelectEM, "otype2" : "MU", "ocut2": 0, "olist2": "ab", "nleading2": HW.OutputWidthSelectMU}, #0DETA04-EM15abi-MUab
-                ]
-        else:
-            algoList = []
-
-        for x in algoList:
-
-            class d:
-                pass
-            for k in x:
-                setattr (d, k, x[k])
-
-            toponame = "%sDETA%s-%s%s%s-%s%s%s"  % (d.minDeta, d.maxDeta, d.otype1, str(d.ocut1), d.olist1, d.otype2, str(d.ocut2) if d.ocut2>0 else "", d.olist2)
- 
-            log.debug("Define %s", toponame)
-
-            inputList = [d.otype1 + d.olist1, d.otype2 + d.olist2]
-            alg = AlgConf.DeltaEtaIncl2( name = toponame, inputs = inputList, outputs = [ toponame ])
-            alg.addgeneric('NumResultBits', 1)
-
-            alg.addgeneric('InputWidth1', d.nleading1)
-            alg.addgeneric('InputWidth2', d.nleading2)
-            alg.addgeneric('MaxTob1', d.nleading1)
-            alg.addgeneric('MaxTob2', d.nleading2)
-            alg.addvariable('MinET1', d.ocut1, 0)
-            alg.addvariable('MinET2', d.ocut2, 0)
-            alg.addvariable('MinDeltaEta', d.minDeta, 0)
-            alg.addvariable('MaxDeltaEta', d.maxDeta, 0)
-
-            tm.registerTopoAlgo(alg)
-
-        if usev7 or usev8:
-            algoList = [
-                {"minDphi": 0, "maxDphi": "03", "mult": 1, "otype1" : "EM", "ocut1": 8, "olist1" : "abi", "nleading1": HW.OutputWidthSelectEM, "otype2" : "MU", "ocut2": 10, "olist2": "ab", "nleading2": HW.OutputWidthSelectMU}, #0DPHI03-EM8abi-MU10ab
-                {"minDphi": 0, "maxDphi": "03", "mult": 1, "otype1" : "EM", "ocut1": 15, "olist1" : "abi", "nleading1": HW.OutputWidthSelectEM, "otype2" : "MU", "ocut2": 0, "olist2": "ab", "nleading2": HW.OutputWidthSelectMU}, #0DPHI03-EM15abi-MUab
-                ]
-        else:
-            algoList = []
-
-        for x in algoList:
-
-            class d:
-                pass
-            for k in x:
-                setattr (d, k, x[k])
-            
-            toponame = "%sDPHI%s-%s%s%s-%s%s%s"  % (d.minDphi, d.maxDphi, d.otype1, str(d.ocut1), d.olist1, d.otype2, str(d.ocut2) if d.ocut2>0 else "", d.olist2)
- 
-            log.debug("Define %s", toponame)
-
             inputList = [d.otype1 + d.olist1, d.otype2 + d.olist2]
             alg = AlgConf.DeltaPhiIncl2( name = toponame, inputs = inputList, outputs = [ toponame ])
-            alg.addgeneric('NumResultBits', 1)
-            
+            alg.addgeneric('NumResultBits', 1)            
             alg.addgeneric('InputWidth1', d.nleading1)
             alg.addgeneric('InputWidth2', d.nleading2)
             alg.addgeneric('MaxTob1', d.nleading1)
@@ -1102,97 +705,9 @@ class TopoAlgoDef:
             alg.addvariable('MinET2', d.ocut2, 0)
             alg.addvariable('MinDeltaPhi', d.minDphi, 0)
             alg.addvariable('MaxDeltaPhi', d.maxDphi, 0)
-
             tm.registerTopoAlgo(alg)
             
-        # JetMatch
-        if not usev8:
-            toponame = "0MATCH-4AJ20pETA31-4AJj15pETA31"
-            alg = AlgConf.MultiplicityCustom( name = toponame, inputs = [ 'AJMatchall' ], outputs = [ toponame ] )
-            alg.addgeneric('InputWidth', HW.InputWidthJET)
-            alg.addgeneric('NumResultBits', 1)
-            alg.addvariable('MinET', 0)
-            alg.addvariable('MinEta', 0)
-            alg.addvariable('MaxEta', 31)
-            alg.addvariable('MinMultiplicity', 4)
-            tm.registerTopoAlgo(alg)
-        
-        # NoMatch for W T&P
-        if not usev8:        
-            toponame = "NOT-02MATCH-EM10s1-AJj15allpETA49"
-            alg = AlgConf.NotMatch( name = toponame, inputs = [ 'EMs', 'AJjall'], outputs = [ toponame ] )
-            alg.addgeneric('InputWidth1', HW.OutputWidthSortEM)
-            alg.addgeneric('InputWidth2', HW.InputWidthJET)
-            alg.addgeneric('MaxTob1', 1)
-            alg.addgeneric('MaxTob2', HW.InputWidthJET)
-            alg.addgeneric('NumResultBits', 1)
-            alg.addvariable('MinET1', 10)
-            alg.addvariable('MinET2', 15)
-            alg.addvariable('EtaMin1', 0)
-            alg.addvariable('EtaMax1', 49)
-            alg.addvariable('EtaMin2', 0)
-            alg.addvariable('EtaMax2', 49)
-            alg.addvariable('DRCut', 4)
-            tm.registerTopoAlgo(alg)
 
-        # RATIO SUM for W T&P 
-        #toponame = "05RATIO-XE0-SUM0-EM10s1-HT0-AJj15allpETA49"
-        #alg = AlgConf.RatioSum( name = toponame, inputs = ['XE', 'AJjall', 'EMs'], outputs = [ toponame ] );
-        #alg.addgeneric('InputWidth1', 1)
-        #alg.addgeneric('InputWidth2', HW.InputWidthJET) 
-        #alg.addgeneric('InputWidth3', HW.OutputWidthSortEM) 
-        #alg.addgeneric('MaxTob1', 1)
-        #alg.addgeneric('MaxTob2', HW.InputWidthJET)
-        #alg.addgeneric('MaxTob3', 1)
-        #alg.addgeneric('NumResultBits', 1)
-        #alg.addgeneric('UseCluster05Granularity', 1)
-        #alg.addvariable('MinET2', 15)
-        #alg.addvariable('EtaMin2', 0)
-        #alg.addvariable('EtaMax2', 49)
-        #alg.addvariable('MinET3', 10)
-        #alg.addvariable('EtaMin3', 0)
-        #alg.addvariable('EtaMax3', 49)
-        #alg.addvariable('MinMET', 0)
-        #alg.addvariable('HT', 0)
-        #alg.addvariable('SUM', 0)
-        #alg.addvariable('Ratio', 5, 0)
-        #tm.registerTopoAlgo(alg)
-
-        # RATIO for W T&P
-        if not usev8:
-            algolist = [
-            {"minRatio": 5, "ocut" : 15, "Ratio": "RATIO"},
-            {"minRatio": 90, "ocut" : 15, "Ratio": "RATIO2"},
-            {"minRatio": 250, "ocut" : 15, "Ratio": "RATIO2"},
-            ]
-        if usev8:
-            algolist = []
-
-        for x in algolist:
-            
-            class d:
-                pass
-            for k in x:
-                setattr (d, k, x[k]) 
-                
-            toponame = "%02d%s-XE0-HT0-AJj%sallpETA49"  % (d.minRatio, d.Ratio, str(d.ocut))
-            log.debug("Define %s", toponame)
-            
-            alg = AlgConf.Ratio( name = toponame, inputs = ['XE', 'AJjall'], outputs = [ toponame ] ) 
-            alg.addgeneric('InputWidth1', 1) 
-            alg.addgeneric('InputWidth2', HW.InputWidthJET) 
-            alg.addgeneric('MaxTob1', 1)
-            alg.addgeneric('MaxTob2', HW.InputWidthJET)
-            alg.addgeneric('NumResultBits', 1)
-            alg.addgeneric('isXE2', 1 if d.Ratio=="RATIO2" else 0)
-            alg.addvariable('MinET2', str(d.ocut))
-            alg.addvariable('EtaMin', 0)
-            alg.addvariable('EtaMax', 49)
-            alg.addvariable('MinET1', 0)                        
-            alg.addvariable('HT', 0)
-            alg.addvariable('Ratio', str(d.minRatio))
-            tm.registerTopoAlgo(alg)
-            
         # RATIO MATCH dedicated to Exotic 
         toponame = '100RATIO-0MATCH-TAU30si2-EMall'
         alg = AlgConf.RatioMatch( name = toponame, inputs = [ 'TAUsi', 'EMall'], outputs = [ toponame ] )
@@ -1206,6 +721,7 @@ class TopoAlgoDef:
         alg.addvariable('Ratio', 100, 0)
         tm.registerTopoAlgo(alg)        
 
+
         # NOT MATCH dedicated to Exotic
         toponame = 'NOT-0MATCH-TAU30si1-EMall'
         alg = AlgConf.NotMatch( name = toponame, inputs = [ 'TAUsi', 'EMall'], outputs = [ toponame ] )
@@ -1223,6 +739,7 @@ class TopoAlgoDef:
         alg.addvariable('DRCut', 0)
         tm.registerTopoAlgo(alg)        
 
+
         # DISAMB 1 and  2 lists
         algolist=[
             { "disamb": 1, "otype1" : "TAU", "ocut1": 12, "olist1" : "abi", "nleading1": HW.OutputWidthSelectTAU,
@@ -1254,71 +771,41 @@ class TopoAlgoDef:
             tm.registerTopoAlgo(alg)
 
         
-        # DISAMB 3 lists
-        if not usev8:
-            algoList = [
-              {"disamb": 1, "otype1" : "EM",  "ocut1": 15, "olist1": "shi","nleading1": 2, "inputwidth1": HW.OutputWidthSortEM, "otype2" : "TAU", "ocut2": 12, "olist2": "abi", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU, "otype3" : "J", "ocut3": 25, "olist3": "ab", "nleading3": HW.OutputWidthSelectJET, "inputwidth3": HW.OutputWidthSelectJET}, #1DISAMB-EM15his2-TAU12abi-J25ab
-              {"disamb": 1, "otype1" : "TAU", "ocut1": 20, "olist1": "abi","nleading1": HW.OutputWidthSelectTAU, "inputwidth1": HW.OutputWidthSelectTAU, "otype2" : "TAU", "ocut2": 12, "olist2": "abi", "nleading2": HW.OutputWidthSelectTAU, "otype3" : "J", "ocut3": 25, "olist3": "ab", "nleading3": HW.OutputWidthSelectTAU}, #1DISAMB-TAU20abi-TAU12abi-J25ab
-            ]
-        if usev8:
-            algoList = []
-
-        for x in algoList:     
-            
-            class d:
-                pass
-            for k in x:
-                setattr (d, k, x[k])
-
-            obj1 = "%s%s%s"  % (d.otype1, str(d.ocut1), d.olist1.replace('shi','his') + (str(d.nleading1) if d.olist1.find('s')>=0 else ""))
-            obj2 = "-%s%s%s" % (d.otype2, str(d.ocut2), d.olist2.replace('shi','his') + (str(d.nleading2) if d.olist2.find('s')>=0 else ""))
-            obj3 = "-%s%s%s" % (d.otype3, str(d.ocut3), d.olist3)
-            toponame = "%sDISAMB-%s%s%s"  % ( d.disamb if d.disamb>0 else "", obj1, obj2, obj3)
-            
-            log.debug("Define %s", toponame)
-            
-            inputList = [d.otype1 + d.olist1, d.otype2 + d.olist2, d.otype3 + d.olist3]
-            alg = AlgConf.DisambiguationIncl3( name = toponame, inputs = inputList, outputs = [ toponame ])
-            alg.addgeneric('InputWidth1', d.inputwidth1)
-            alg.addgeneric('InputWidth2', d.inputwidth2)
-            alg.addgeneric('InputWidth3', d.inputwidth3)
-            alg.addgeneric('MaxTob1', d.nleading1)
-            alg.addgeneric('MaxTob2', d.nleading2)
-            alg.addgeneric('MaxTob3', d.nleading3)
-            alg.addgeneric('NumResultBits', 1)
-            alg.addgeneric('ApplyDR', 0)
-            alg.addvariable('MinET1', d.ocut1, 0)
-            alg.addvariable('MinET2', d.ocut2, 0)
-            alg.addvariable('MinET3', d.ocut3, 0)
-            alg.addvariable('DisambDRSqr', d.disamb*d.disamb, 0) # DisambDR
-            tm.registerTopoAlgo(alg)         
 
 
         # DISAMB 3 lists with DR cut to 2nd and 3rd lists
         algolist=[
-            { "disamb": 1, "otype1" : "EM",  "ocut1": 15, "olist1": "shi","nleading1": 2, "inputwidth1": HW.OutputWidthSortEM, "otype2" : "TAU", "ocut2": 12, "olist2": "abi", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU, "otype3" : "J", "ocut3": 25, "olist3": "ab", "nleading3": HW.OutputWidthSelectJET, "inputwidth3": HW.OutputWidthSelectJET, "drcutmin": 0, "drcutmax": 28}, #1DISAMB-J25ab-0DR28-EM15his2-TAU12abi                
-            { "disamb": 2, "otype1" : "EM",  "ocut1": 15, "olist1": "shi","nleading1": 2, "inputwidth1": HW.OutputWidthSortEM, "otype2" : "TAU", "ocut2": 12,
-              "olist2": "abi", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU, "otype3" : "J", "ocut3": 25, "olist3": "ab",
-              "nleading3": HW.OutputWidthSelectJET, "inputwidth3": HW.OutputWidthSelectJET, "drcutmin": 0, "drcutmax": 28}, #2DISAMB-J25ab-0DR28-EM15his2-TAU12abi
-            { "disamb": 2, "otype1" : "TAU",  "ocut1": 20, "olist1": "abi","nleading1": HW.OutputWidthSelectTAU, "inputwidth1": HW.OutputWidthSelectTAU, "otype2" : "TAU", "ocut2": 12, "olist2": "abi", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU, "otype3" : "J", "ocut3": 25, "olist3": "ab", "nleading3": HW.OutputWidthSelectJET, "inputwidth3": HW.OutputWidthSelectJET, "drcutmin": 0, "drcutmax": 28}, # 2DISAMB-J25ab-0DR28-TAU20abi-TAU12abi
-            { "disamb": 2, "otype1" : "TAU",  "ocut1": 20, "olist1": "abi","nleading1": HW.OutputWidthSelectTAU, "inputwidth1": HW.OutputWidthSelectTAU,
+            { "disamb": 1, "otype1" : "EM",
+              "ocut1": 15, "olist1": "shi","nleading1": 2, "inputwidth1": HW.OutputWidthSortEM, "otype2" : "TAU",
+              "ocut2": 12, "olist2": "abi", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU,
+              "otype3" : "J", "ocut3": 25, "olist3": "ab", "nleading3": HW.OutputWidthSelectJET, "inputwidth3": HW.OutputWidthSelectJET,
+              "drcutmin": 0, "drcutmax": 28}, #1DISAMB-J25ab-0DR28-EM15his2-TAU12abi                
+            { "disamb": 2,
+              "otype1" : "EM", "ocut1": 15, "olist1": "shi","nleading1": 2, "inputwidth1": HW.OutputWidthSortEM,
               "otype2" : "TAU", "ocut2": 12, "olist2": "abi", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU,
-              "otype3" : "J", "ocut3": 25, "olist3": "ab", "nleading3": HW.OutputWidthSelectJET, "inputwidth3": HW.OutputWidthSelectJET, "drcutmin": 0, "drcutmax": 25}, # 2DISAMB-J25ab-0DR25-TAU20abi-TAU12abi
+              "otype3" : "J", "ocut3": 25, "olist3": "ab", "nleading3": HW.OutputWidthSelectJET, "inputwidth3": HW.OutputWidthSelectJET,
+              "drcutmin": 0, "drcutmax": 28}, #2DISAMB-J25ab-0DR28-EM15his2-TAU12abi
+            { "disamb": 2,
+              "otype1" : "TAU",  "ocut1": 20, "olist1": "abi","nleading1": HW.OutputWidthSelectTAU, "inputwidth1": HW.OutputWidthSelectTAU,
+              "otype2" : "TAU", "ocut2": 12, "olist2": "abi", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU,
+              "otype3" : "J", "ocut3": 25, "olist3": "ab", "nleading3": HW.OutputWidthSelectJET, "inputwidth3": HW.OutputWidthSelectJET,
+              "drcutmin": 0, "drcutmax": 28}, # 2DISAMB-J25ab-0DR28-TAU20abi-TAU12abi
+            { "disamb": 2,
+              "otype1" : "TAU",  "ocut1": 20, "olist1": "abi","nleading1": HW.OutputWidthSelectTAU, "inputwidth1": HW.OutputWidthSelectTAU,
+              "otype2" : "TAU", "ocut2": 12, "olist2": "abi", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU,
+              "otype3" : "J", "ocut3": 25, "olist3": "ab", "nleading3": HW.OutputWidthSelectJET, "inputwidth3": HW.OutputWidthSelectJET,
+              "drcutmin": 0, "drcutmax": 25}, # 2DISAMB-J25ab-0DR25-TAU20abi-TAU12abi
         ]
         for x in algolist:
-
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
             obj1 = "-%s%s%s"  % (d.otype1, str(d.ocut1), d.olist1.replace('shi','his') + (str(d.nleading1) if d.olist1.find('s')>=0 else ""))
             obj2 = "-%s%s%s" % (d.otype2, str(d.ocut2), d.olist2.replace('shi','his') + (str(d.nleading2) if d.olist2.find('s')>=0 else ""))
             obj3 = "%s%s%s" % (d.otype3, str(d.ocut3), d.olist3)
             toponame = "%sDISAMB-%s-%dDR%d%s%s"  % ( str(d.disamb) if d.disamb>0 else "", obj3, d.drcutmin, d.drcutmax, obj1, obj2)
-
-            log.debug("Define %s", toponame)
-            
+            log.debug("Define %s", toponame)            
             inputList = [d.otype1 + d.olist1, d.otype2 + d.olist2, d.otype3 + d.olist3]
             alg = AlgConf.DisambiguationDRIncl3( name = toponame, inputs = inputList, outputs = [ toponame ])
             alg.addgeneric('InputWidth1', d.inputwidth1)
@@ -1337,198 +824,25 @@ class TopoAlgoDef:
             tm.registerTopoAlgo(alg)            
 
 
-        # LAR  0<eta<1.4 and 9/16pi<phi<11/16pi for FE crate IO6 
-        if not usev8:
-            algoList = [
-            {"minEta": 1, "maxEta": 15, "minPhi": 17, "maxPhi": 23, "otype" : "EM", "ocut" : 20,  "olist" : "shi", "inputwidth": HW.OutputWidthSortEM}, #LAR-EM20shi1
-            {"minEta": 1, "maxEta": 14, "minPhi": 17, "maxPhi": 23, "otype" : "J", "ocut" : 100,  "olist" : "s", "inputwidth": HW.OutputWidthSortJET},  #LAR-J100s1
-            ]
-        if usev8:
-            algoList = []
-
-        for x in algoList:
-
-            class d:
-                pass
-            for k in x:
-                setattr (d, k, x[k])
-
-            toponame = "LAR-%s%s%s1"  % ( d.otype, str(d.ocut), d.olist )
-
-            log.debug("Define %s", toponame)
-            
-            inputList = d.otype + d.olist
-
-            alg = AlgConf.EtaPhiWindow( name = toponame, inputs = inputList, outputs = toponame )
-            alg.addgeneric('InputWidth', d.inputwidth)
-            alg.addgeneric('MaxTob', 0)
-            alg.addgeneric('NumResultBits', 1)
-            alg.addvariable('MinET', str(d.ocut))
-            alg.addvariable('EtaMin', d.minEta)
-            alg.addvariable('EtaMax', d.maxEta)
-            alg.addvariable('PhiMin', d.minPhi)
-            alg.addvariable('PhiMax', d.maxPhi)
-            tm.registerTopoAlgo(alg)
-
-
-
         xemap = [{"etcut": 0, "Threlist": [ 40, 50, 55, 60, 65, 75 ]}]
-        for x in xemap:
-                
+        for x in xemap:                
             class d:
                 pass
             for k in x:
-                setattr (d, k, x[k])
-            
-            log.debug("Define %s", toponame)
-            
+                setattr (d, k, x[k])            
+            log.debug("Define %s", toponame)            
             inputList = ['XENoSort', 'AJall']
             toponames=[]
-
             for minxe in d.Threlist:
-                toponames.append("KF-XE%s-AJall"  % (minxe))
-            
+                toponames.append("KF-XE%s-AJall"  % (minxe))            
             alg = AlgConf.KalmanMETCorrection( name = "KF-XE-AJall", inputs = inputList, outputs = toponames )
             alg.addgeneric('InputWidth', HW.InputWidthJET)
             alg.addgeneric('NumResultBits', len(toponames))
             alg.addvariable('MinET', 0)
             for bitid,minxe in enumerate(d.Threlist):
-                alg.addvariable('KFXE', str(minxe), bitid)
-            
-            tm.registerTopoAlgo(alg)
-
-        # W T&P: MINDPHI(J, XE0), (EM, XE0)
-
-        if not usev8:
-            alglist = [
-                {"minDPhi": 15, "otype" : "EM",  "ocut" : 12, "olist" : "s", "nleading" : 6, "inputwidth": HW.OutputWidthSortEM},
-                {"minDPhi": 15, "otype" : "EM",  "ocut" : 15, "olist" : "s", "nleading" : 6, "inputwidth": HW.OutputWidthSortEM},
-            ]
-        else:
-            alglist = []
-
-        for x in alglist:
-            
-            class d:
-                pass
-            for k in x:
-                setattr (d, k, x[k])
-                
-            toponame = "%02dMINDPHI-%s%s%s%s-XE0"  % (d.minDPhi, d.otype, str(d.ocut) if d.ocut > 0 else "", d.olist, str(d.nleading) if d.olist=="s" else "")
-            log.debug("Define %s", toponame)
-
-            inputList = d.otype + d.olist
-
-            alg = AlgConf.MinDeltaPhiIncl2( name = toponame, inputs = [ inputList, 'XE'], outputs = [ toponame ] )
-
-
-            alg.addgeneric('InputWidth1', d.inputwidth)
-            alg.addgeneric('InputWidth2', 1) 
-            alg.addgeneric('MaxTob1', d.nleading)
-            alg.addgeneric('MaxTob2', 1)
-            alg.addgeneric('NumResultBits', 1)
-            alg.addvariable('MinET1', d.ocut)
-            alg.addvariable('MinET2', 0)
-            alg.addvariable('DeltaPhiMin', d.minDPhi, 0)
+                alg.addvariable('KFXE', str(minxe), bitid)            
             tm.registerTopoAlgo(alg)
 
-            
-        # W T&P MT
-
-        if not usev8:
-            alglistmt = [
-                {"minMT": 35, "otype" : "EM", "ocut" : "12", "olist" : "s", "nleading" : 6, "inputwidth": HW.OutputWidthSortEM},
-            ]
-        else:
-            alglistmt = []
-        for x in alglistmt:
-            class d:
-                pass
-            for k in x:
-                setattr (d, k, x[k])
-
-            toponame = "%iMT-%s%s%s%s-XE0"  % (d.minMT, d.otype, str(d.ocut) if d.ocut > 0 else "", d.olist, str(d.nleading) if d.olist=="s" else "")
-            log.debug("Define %s", toponame)
-
-            inputList = d.otype + d.olist
-            
-            alg = AlgConf.TransverseMassInclusive1( name = toponame, inputs = [ inputList, 'XE'], outputs = [ toponame ] )
-
-
-
-            alg.addgeneric('InputWidth', HW.OutputWidthSortEM)
-            alg.addgeneric('MaxTob', str(d.nleading))
-            alg.addgeneric('NumResultBits', 1)
-            alg.addvariable('MinET1', str(d.ocut))
-            alg.addvariable('MinET2', 0)
-            alg.addvariable('MinMTSqr', d.minMT*d.minMT)
-            tm.registerTopoAlgo(alg)
-
-        # DISAMB 2 lists with DR cut between objects in two lists
-        if not usev8:
-            algoList=[
-              {"disamb": 0, "otype1" : "EM",  "ocut1": 15, "olist1": "shi","nleading1": 2, "inputwidth1": HW.OutputWidthSortEM, "otype2" : "TAU", "ocut2": 12, "olist2": "abi", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU, "drcutmin": 0, "drcutmax": 28},          
-            ]
-        if usev8:
-            algoList=[] 
-
-        for x in algoList:     
-
-            class d:
-                pass
-            for k in x:
-                setattr (d, k, x[k])
-
-            obj1 = "-%s%s%s"  % (d.otype1, str(d.ocut1), d.olist1.replace('shi','his') + (str(d.nleading1) if d.olist1.find('s')>=0 else ""))
-            obj2 = "-%s%s%s" % (d.otype2, str(d.ocut2), d.olist2.replace('shi','his') + (str(d.nleading2) if d.olist2.find('s')>=0 else ""))
-            toponame = "%sDISAMB-%dDR%d%s%s"  % ( str(d.disamb) if d.disamb>0 else "", d.drcutmin, d.drcutmax, obj1, obj2)
-
-            log.debug("Define %s", toponame)
-
-            inputList = [d.otype1 + d.olist1, d.otype2 + d.olist2]
-            alg = AlgConf.DisambiguationDRIncl2( name = toponame, inputs = inputList, outputs = [ toponame ])
-            alg.addgeneric('InputWidth1', d.inputwidth1)
-            alg.addgeneric('InputWidth2', d.inputwidth2)
-            alg.addgeneric('MaxTob1', d.nleading1)
-            alg.addgeneric('MaxTob2', d.nleading2)
-            alg.addgeneric('NumResultBits', 1)
-            alg.addvariable('MinET1', d.ocut1, 0)
-            alg.addvariable('MinET2', d.ocut2, 0)
-            alg.addvariable('DisambDRSqrMin', d.drcutmin*d.drcutmin, 0)
-            alg.addvariable('DisambDRSqrMax', d.drcutmax*d.drcutmax, 0)
-            tm.registerTopoAlgo(alg)   
-
-        # ZH Trigger
-        if not usev8:
-            supportedalgolist = [
-              {"minDPhi": 10, "otype" : "AJ", "ocut" : 20,  "olist" : "s", "nleading" : 2, "inputwidth": HW.OutputWidthSortJET},
-            ]
-        if usev8:
-            supportedalgolist = []
-           
-        for x in supportedalgolist:
-            
-            class d:
-                pass
-            for k in x:
-                setattr (d, k, x[k])
-                
-            toponame = "%iMINDPHI-%s%s%s%s-XE50"  % (d.minDPhi, d.otype, str(d.ocut) if d.ocut > 0 else "", d.olist, str(d.nleading) if d.olist=="s" else "")
-            log.debug("Define %s", toponame)
-            
-            inputList = d.otype + d.olist
-
-            alg = AlgConf.MinDeltaPhiIncl2( name = toponame, inputs = [inputList, 'XE'], outputs = [ toponame ] )
-
-            alg.addgeneric('InputWidth1', d.inputwidth)
-            alg.addgeneric('InputWidth2', 1)  
-            alg.addgeneric('MaxTob1', d.nleading)
-            alg.addgeneric('MaxTob2', 1)
-            alg.addgeneric('NumResultBits', 1)
-            alg.addvariable('MinET1', d.ocut)
-            alg.addvariable('MinET2', 50)
-            alg.addvariable('DeltaPhiMin', d.minDPhi, 0)
-            tm.registerTopoAlgo(alg)
                 
         # LATE MUON : LATE-MU10s1
         for x in [     
@@ -1556,193 +870,125 @@ class TopoAlgoDef:
             
 
         # (ATR-12748) fat jet trigger with Simple Cone algo
-        if not usev8:
-            algoList = [
-              {"minHT": 111, "otype" : "CJ", "ocut" : 15, "olist" : "ab", "nleading" : HW.OutputWidthSelectJET, "inputwidth": HW.OutputWidthSelectJET, "oeta" : 26}, #SC111-CJ15abpETA26
-              {"minHT": 85, "otype" : "CJ", "ocut" : 15, "olist" : "ab", "nleading" : HW.OutputWidthSelectJET, "inputwidth": HW.OutputWidthSelectJET, "oeta" : 26},  #SC85-CJ15abpETA26
-        ]
-        if usev8:
-            algoList = [
-              {"minHT": 111, "otype" : "CJ", "ocut" : 15, "olist" : "ab", "nleading" : HW.OutputWidthSelectJET, "inputwidth": HW.OutputWidthSelectJET, "oeta" : 26}, #SC111-CJ15abpETA26
+        algoList = [
+            {"minHT": 111, "otype" : "CJ", "ocut" : 15, "olist" : "ab", "nleading" : HW.OutputWidthSelectJET, "inputwidth": HW.OutputWidthSelectJET, "oeta" : 26}, #SC111-CJ15abpETA26
         ]
-        for x in algoList:            
-
+        for x in algoList:
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
             toponame = "SC%d-%s%s%s%spETA%s" % (d.minHT, d.otype, str(d.ocut), d.olist, str(d.nleading) if d.olist=="s" else "", str(d.oeta))
-
             log.debug("Define %s", toponame)
-
             inputList = d.otype + d.olist
-
             alg = AlgConf.SimpleCone( name = toponame, inputs = inputList, outputs = [toponame] )
-
-
             alg.addgeneric('InputWidth', d.inputwidth)
             alg.addvariable('MinET', d.ocut)
             alg.addvariable('MinSumET', d.minHT)
             alg.addvariable('MaxRSqr', 10*10)                        
             tm.registerTopoAlgo(alg)  
 
-        # DISAMB-INVM
-
-        for x in [
-                {"disamb": 0, "minInvm": 30, "maxInvm": 9999,"otype1" : "EM",  "ocut1": 20, "olist1": "shi","nleading1": 2, "inputwidth1": HW.OutputWidthSortEM, "otype2" : "TAU", "ocut2": 12, "olist2": "ab", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU}, # DISAMB-30INVM-EM20his2-TAU12ab
-                ]:
-            
-                class d:
-                    pass
-                for k in x:
-                    setattr (d, k, x[k])
-
-                obj1 = "%s%s%s"  % (d.otype1, str(d.ocut1), d.olist1.replace('shi','his') + (str(d.nleading1) if d.olist1.find('s')>=0 else ""))
-                obj2 = "-%s%s%s" % (d.otype2, str(d.ocut2), d.olist2)
-                toponame = "%sDISAMB-%iINVM%s-%s%s"  % ( d.disamb if d.disamb>0 else "", d.minInvm, str(d.maxInvm) if d.maxInvm<9999 else "", obj1, obj2)
-
-                log.debug("Define %s", toponame)
-                inputList = [d.otype1 + d.olist1, d.otype2 + d.olist2]
-                alg = AlgConf.DisambiguationInvmIncl2( name = toponame, inputs = inputList, outputs = toponame)
-    
-                alg.addgeneric('InputWidth1', d.inputwidth1)
-                alg.addgeneric('InputWidth2', d.inputwidth2)
-                alg.addgeneric('MaxTob1', d.nleading1)
-                alg.addgeneric('MaxTob2', d.nleading2)
-                alg.addgeneric('NumResultBits', 1)
-            
-                alg.addvariable('MinET1', d.ocut1)
-                alg.addvariable('MinET2', d.ocut2)
-                alg.addvariable('MinMSqr', d.minInvm * d.minInvm)
-                alg.addvariable('MaxMSqr', d.maxInvm * d.maxInvm)
-                
-                tm.registerTopoAlgo(alg)
-
-
-        for x in [
-                {  "minInvm": 400, "maxInvm": 9999, "otype1" : "AJ", "ocut1": 30, "olist1" : "s", "nleading1" : 6, "inputwidth1": HW.OutputWidthSortJET,
-                   "otype2" : "AJ", "ocut2": 20, "olist2" : "s", "nleading2" : 6, "inputwidth2": HW.OutputWidthSortJET, "applyEtaCut":1,
-                   "minEta1": 0 ,"maxEta1": 31 , "minEta2": 31 ,"maxEta2": 49 , }, #400INVM9999-AJ30s6pETA31-AJ20s6p31ETA49
-                ]:
-            
-                class d:
-                    pass
-                for k in x:
-                    setattr (d, k, x[k])
-
-                obj1 = "%s%s%sp%sETA%i"  % (d.otype1, str(d.ocut1), d.olist1 + (str(d.nleading1) if d.olist1.find('s')>=0 else ""),str(d.minEta1) if d.minEta1>0 else "", d.maxEta1)
-                obj2 = "-%s%s%sp%sETA%i"  % (d.otype2, str(d.ocut2), d.olist2 + (str(d.nleading2) if d.olist2.find('s')>=0 else ""),str(d.minEta2) if d.minEta2>0 else "", d.maxEta2)
-            
-                inputList = [d.otype1 + d.olist1, d.otype2 + d.olist2]
-                        
-                toponame = "%iINVM%i-%s%s"   % (d.minInvm, d.maxInvm, obj1, obj2)
-                alg = AlgConf.InvariantMassInclusive2( name = toponame, inputs = inputList, outputs = toponame)
-
-
-                alg.addgeneric('InputWidth1', d.inputwidth1)
-                alg.addgeneric('InputWidth2', d.inputwidth2)
-                alg.addgeneric('MaxTob1', d.nleading1)
-                alg.addgeneric('MaxTob2', d.nleading2)
-                alg.addgeneric('NumResultBits', 1)
-                if (d.applyEtaCut>0):
-                    alg.addgeneric('ApplyEtaCut', d.applyEtaCut)
-
-                alg.addvariable('MinET1', d.ocut1)
-                alg.addvariable('MinET2', d.ocut2)
-                alg.addvariable('MinMSqr', d.minInvm * d.minInvm )
-                alg.addvariable('MaxMSqr', d.maxInvm * d.maxInvm )
-                if (d.applyEtaCut>0):
-                    alg.addvariable('MinEta1', d.minEta1)
-                    alg.addvariable('MaxEta1', d.maxEta1)
-                    alg.addvariable('MinEta2', d.minEta2)
-                    alg.addvariable('MaxEta2', d.maxEta2)
-
-                tm.registerTopoAlgo(alg)
-
- 
-      # LAR  ZEE
-        if not usev8:
-            algoList = [
-            {"otype" : "EM", "ocut1" : 20,  "ocut2" : 20, "olist" : "shi", "nleading1" : 2, "minInvm" : 60, "maxInvm" : 100, "inputwidth": HW.OutputWidthSortEM},
-            ]
-        if usev8:
-            algoList = []
-
-        for x in algoList:
 
+        # DISAMB-INVM
+        algoList = [
+            { "disamb": 0, "minInvm": 30, "maxInvm": 9999,
+              "otype1" : "EM",  "ocut1": 20, "olist1": "shi","nleading1": 2, "inputwidth1": HW.OutputWidthSortEM,
+              "otype2" : "TAU", "ocut2": 12, "olist2": "ab", "nleading2": HW.OutputWidthSelectTAU, "inputwidth2": HW.OutputWidthSelectTAU}, # DISAMB-30INVM-EM20his2-TAU12ab
+        ]
+        for x in algoList:            
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
-            toponame = 'ZEE-EM20shi2'
-
+            obj1 = "%s%s%s"  % (d.otype1, str(d.ocut1), d.olist1.replace('shi','his') + (str(d.nleading1) if d.olist1.find('s')>=0 else ""))
+            obj2 = "-%s%s%s" % (d.otype2, str(d.ocut2), d.olist2)
+            toponame = "%sDISAMB-%iINVM%s-%s%s"  % ( d.disamb if d.disamb>0 else "", d.minInvm, str(d.maxInvm) if d.maxInvm<9999 else "", obj1, obj2)
             log.debug("Define %s", toponame)
+            inputList = [d.otype1 + d.olist1, d.otype2 + d.olist2]
+            alg = AlgConf.DisambiguationInvmIncl2( name = toponame, inputs = inputList, outputs = toponame)
+            alg.addgeneric('InputWidth1', d.inputwidth1)
+            alg.addgeneric('InputWidth2', d.inputwidth2)
+            alg.addgeneric('MaxTob1', d.nleading1)
+            alg.addgeneric('MaxTob2', d.nleading2)
+            alg.addgeneric('NumResultBits', 1)
+            alg.addvariable('MinET1', d.ocut1)
+            alg.addvariable('MinET2', d.ocut2)
+            alg.addvariable('MinMSqr', d.minInvm * d.minInvm)
+            alg.addvariable('MaxMSqr', d.maxInvm * d.maxInvm)
+            tm.registerTopoAlgo(alg)
 
-            inputList = d.otype + d.olist
-
-
-            alg = AlgConf.InvariantMassInclusive1( name = toponame, inputs = inputList, outputs = toponame)
 
-            alg.addgeneric('InputWidth', d.inputwidth)
-            alg.addgeneric('MaxTob', d.nleading1)
+        algoList = [
+            {  "minInvm": 400, "maxInvm": 9999, "otype1" : "AJ", "ocut1": 30, "olist1" : "s", "nleading1" : 6, "inputwidth1": HW.OutputWidthSortJET,
+               "otype2" : "AJ", "ocut2": 20, "olist2" : "s", "nleading2" : 6, "inputwidth2": HW.OutputWidthSortJET, "applyEtaCut":1,
+               "minEta1": 0 ,"maxEta1": 31 , "minEta2": 31 ,"maxEta2": 49 , }, #400INVM9999-AJ30s6pETA31-AJ20s6p31ETA49
+        ]
+        for x in algoList:
+            class d:
+                pass
+            for k in x:
+                setattr (d, k, x[k])
+            obj1 = "%s%s%sp%sETA%i"  % (d.otype1, str(d.ocut1), d.olist1 + (str(d.nleading1) if d.olist1.find('s')>=0 else ""),str(d.minEta1) if d.minEta1>0 else "", d.maxEta1)
+            obj2 = "-%s%s%sp%sETA%i"  % (d.otype2, str(d.ocut2), d.olist2 + (str(d.nleading2) if d.olist2.find('s')>=0 else ""),str(d.minEta2) if d.minEta2>0 else "", d.maxEta2)
+            inputList = [d.otype1 + d.olist1, d.otype2 + d.olist2]
+            toponame = "%iINVM%i-%s%s"   % (d.minInvm, d.maxInvm, obj1, obj2)
+            alg = AlgConf.InvariantMassInclusive2( name = toponame, inputs = inputList, outputs = toponame)
+            alg.addgeneric('InputWidth1', d.inputwidth1)
+            alg.addgeneric('InputWidth2', d.inputwidth2)
+            alg.addgeneric('MaxTob1', d.nleading1)
+            alg.addgeneric('MaxTob2', d.nleading2)
             alg.addgeneric('NumResultBits', 1)
-            
+            if (d.applyEtaCut>0):
+                alg.addgeneric('ApplyEtaCut', d.applyEtaCut)
             alg.addvariable('MinET1', d.ocut1)
             alg.addvariable('MinET2', d.ocut2)
-            alg.addvariable('MinMSqr', (d.minInvm * _emscale_for_decision)*(d.minInvm * _emscale_for_decision))
-            alg.addvariable('MaxMSqr', (d.maxInvm * _emscale_for_decision)*(d.maxInvm * _emscale_for_decision))
-        
+            alg.addvariable('MinMSqr', d.minInvm * d.minInvm )
+            alg.addvariable('MaxMSqr', d.maxInvm * d.maxInvm )
+            if (d.applyEtaCut>0):
+                alg.addvariable('MinEta1', d.minEta1)
+                alg.addvariable('MaxEta1', d.maxEta1)
+                alg.addvariable('MinEta2', d.minEta2)
+                alg.addvariable('MaxEta2', d.maxEta2)
             tm.registerTopoAlgo(alg)
 
-
+ 
         #  0INVM9-EM7ab-EMab 
-        for x in [
+        algoList = [
             {"minInvm" : 0, "maxInvm": 9, "otype" : "EM", "ocut1" : 7, "olist" : "ab", "inputwidth": HW.OutputWidthSelectEM, "ocut2" : 0},
-            ]:
-            
+        ]
+        for x in algoList:
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
             inputList = d.otype + d.olist
             toponame = "%iINVM%i-%s%s%s-%s%s"  % (d.minInvm, d.maxInvm,
                                                   d.otype, str(d.ocut1) , d.olist,
                                                   d.otype, d.olist)
-
             alg = AlgConf.InvariantMassInclusive1( name = toponame, inputs = inputList, outputs = toponame)
             alg.addgeneric('InputWidth', d.inputwidth)
             alg.addgeneric('MaxTob', HW.OutputWidthSelectEM)
             alg.addgeneric('NumResultBits', 1)
-
             alg.addvariable('MinET1', d.ocut1)
             alg.addvariable('MinET2', d.ocut2)
             alg.addvariable('MinMSqr', (d.minInvm * _emscale_for_decision)*(d.minInvm * _emscale_for_decision))
             alg.addvariable('MaxMSqr', (d.maxInvm * _emscale_for_decision)*(d.maxInvm * _emscale_for_decision))
-
             tm.registerTopoAlgo(alg)
 
 
-
         # added for b-phys, 0DR03-EM7ab-CJ15ab
-        for x in [  
+        algoList = [  
             {"minDr": 0, "maxDr": 3, "otype1" : "EM" ,"ocut1": 7,  "olist1" : "ab", "otype2" : "CJ", "ocut2": 15, "olist2" : "ab"} 
-            ]:
-
+        ]
+        for x in algoList:
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
             toponame = "%iDR%02d-%s%s%s-%s%s%s"  % (d.minDr, d.maxDr, d.otype1, str(d.ocut1), d.olist1, d.otype2, str(d.ocut2), d.olist2)
             log.debug("Define %s", toponame)
-
             inputList = [d.otype1 + d.olist1, d.otype2 + d.olist2]
-
             alg = AlgConf.DeltaRSqrIncl2( name = toponame, inputs = inputList, outputs = [ toponame ])
-
             alg.addgeneric('InputWidth1', HW.OutputWidthSelectEM)
             alg.addgeneric('InputWidth2', HW.OutputWidthSelectJET)
             alg.addgeneric('MaxTob1', HW.OutputWidthSelectEM)
@@ -1756,39 +1002,27 @@ class TopoAlgoDef:
 
 
         # VBF items INVM_NFF
-        if usev8:
-            invm_nff_map = {"algoname": 'INVM_NFF', "Threlist": [ 500 ], "maxInvm": 9999, "otype1" : "J", "ocut1" : 30, "olist1" : "s", "nleading1" : 6, "inputwidth": HW.OutputWidthSortJET,  "otype2" : "AJ", "ocut2" : 20, "olist2" : "s", "nleading2" : 6 }
-        else:
-            invm_nff_map = {"algoname": 'INVM_NFF', "Threlist": [ 600, 500, 400, 200 ], "maxInvm": 9999, "otype1" : "J", "ocut1" : 30, "olist1" : "s", "nleading1" : 6, "inputwidth": HW.OutputWidthSortJET,  "otype2" : "AJ", "ocut2" : 20, "olist2" : "s", "nleading2" : 6 }
-
-        for x in [ invm_nff_map,
-            ]:
-            
+        invm_nff_map = { "algoname": 'INVM_NFF', "Threlist": [ 500 ], "maxInvm": 9999,
+                         "otype1" : "J", "ocut1" : 30, "olist1" : "s", "nleading1" : 6, "inputwidth": HW.OutputWidthSortJET, 
+                         "otype2" : "AJ", "ocut2" : 20, "olist2" : "s", "nleading2" : 6 }
+        for x in [ invm_nff_map ]:
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
             inputList = [d.otype1 + d.olist1, d.otype2 + d.olist1]
             toponames=[]
-
-
             for minInvm in d.Threlist:
                 toponame = "%iINVM%i-%s%s%s%s-%s%s%s%s"  % (minInvm, d.maxInvm,
                                                             d.otype1, str(d.ocut1) , d.olist1, str(d.nleading1) if d.olist1=="s" else "",
                                                             d.otype2, str(d.ocut2) , d.olist2, str(d.nleading2) if d.olist2=="s" else "")
                 toponames.append(toponame)
-
-                
             alg = AlgConf.InvariantMassInclusive2( name = d.algoname, inputs = inputList, outputs = toponames)
-
-
             alg.addgeneric('InputWidth1', d.inputwidth)
             alg.addgeneric('InputWidth2', d.inputwidth)
             alg.addgeneric('MaxTob1', d.nleading1)
             alg.addgeneric('MaxTob2', d.nleading2)
             alg.addgeneric('NumResultBits', len(toponames))
-
             for bitid, minInvm in enumerate(d.Threlist):
                 alg.addvariable('MinET1', d.ocut1, bitid)
                 alg.addvariable('MinET2', d.ocut2, bitid)
@@ -1797,31 +1031,23 @@ class TopoAlgoDef:
             tm.registerTopoAlgo(alg)
 
 
+
         # Axion 2EM DPHI  
         #27DPHI32-EMs1-EMs6
-
-        if usev7 or usev8:
-            algoList = [
-                {"minDphi": 27,  "maxDphi": 32, "otype" : "EM",  "ocut1" : 0,  "olist" : "s", "nleading1" : 1, "inputwidth1": HW.OutputWidthSortEM, "ocut2" : 0, "nleading2": 6},
-            ]
-        else:
-            algoList = []
-
+        algoList = [
+            {"minDphi": 27,  "maxDphi": 32, "otype" : "EM",  "ocut1" : 0,  "olist" : "s", "nleading1" : 1, "inputwidth1": HW.OutputWidthSortEM, "ocut2" : 0, "nleading2": 6},
+        ]
         for x in algoList:                 
             class d:
                 pass
             for k in x:
                 setattr (d, k, x[k])
-
             toponame = "%iDPHI%i-%s%s%s%s-%s%s%s%s"  % (d.minDphi, d.maxDphi,
                                                         d.otype, str(d.ocut1) if d.ocut1 > 0 else "", d.olist, str(d.nleading1) if d.olist=="s" else "",
                                                         d.otype, str(d.ocut2) if d.ocut2 > 0 else "", d.olist, str(d.nleading2) if d.olist=="s" else "")
-            
             log.debug("Define %s", toponame)
-            inputList = d.otype + d.olist
-            
+            inputList = d.otype + d.olist            
             alg = AlgConf.DeltaPhiIncl1( name = toponame, inputs = inputList, outputs = toponame )
-
             alg.addgeneric('InputWidth', d.inputwidth1)
             alg.addgeneric('MaxTob', d.nleading2)
             alg.addgeneric('NumResultBits', 1)                        
@@ -1833,9 +1059,11 @@ class TopoAlgoDef:
 
 
         # VBF items INVM_NFF + DPHI
-        NFFDphimap = [ { "minInvm": 400 , "maxInvm": 9999, "minDphi": 0, "maxDphiList": [26, 24, 22, 20],
+        NFFDphimap = [
+            { "minInvm": 400 , "maxInvm": 9999, "minDphi": 0, "maxDphiList": [26, 24, 22, 20],
                          "otype1" : "J", "ocut1" : 30, "olist1" : "s", "nleading1" : 6, "inputwidth": HW.OutputWidthSortJET,
-                         "otype2" : "AJ", "ocut2" : 20, "olist2" : "s", "nleading2" : 6 }]
+                         "otype2" : "AJ", "ocut2" : 20, "olist2" : "s", "nleading2" : 6 }
+        ]
         for x in NFFDphimap:
             class d:
                 pass
@@ -2095,18 +1323,6 @@ class TopoAlgoDef:
         tm.registerTopoAlgo(alg)
 
 
-        # CEP-CJ50s6, CEP-CJ60s6
-        #for x in [50,60]:
-        #    toponame = "CEP-CJ%is6" % x 
-        #    log.debug("Define %s", toponame)
-        #    inputList = ['CJs']
-        #    alg = AlgConf.ExclusiveJets( name = toponame, inputs = inputList, outputs = toponame)
-        #    alg.addvariable('MinET1', x)
-        #    alg.addvariable('MinXi', 13000.0*0.02)
-        #    alg.addvariable('MaxXi', 13000.0*0.05)
-        #    tm.registerTopoAlgo(alg)
-
-
         # CEP-CJ50s6pETA21
         x = 50
         toponame = "CEP-CJ%is6pETA21" % x 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TopoAlgoDefLegacy.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TopoAlgoDefLegacy.py
index 3bb0583614b3b8e861c2e27ab99496474f891dce..e4b95f0d621739707109dc92e5b49bb65942223c 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TopoAlgoDefLegacy.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TopoAlgoDefLegacy.py
@@ -79,8 +79,7 @@ class TopoAlgoDefLegacy:
         alg.addvariable('IsoMask', 0)
         alg.addvariable('MinEta', 0)
         alg.addvariable('MaxEta', _etamax) 
-        alg.addgeneric('DoIsoCut', '0')
-        #alg.addgeneric('DoEtaCut', '1')
+        alg.addgeneric('DoIsoCut', 0)
         tm.registerTopoAlgo(alg) 
 
         
@@ -91,8 +90,7 @@ class TopoAlgoDefLegacy:
         alg.addvariable('IsoMask', 3) 
         alg.addvariable('MinEta', 0)
         alg.addvariable('MaxEta', _etamax)
-        alg.addgeneric('DoIsoCut', '1')
-        #alg.addgeneric('DoEtaCut', '1')
+        alg.addgeneric('DoIsoCut', 1)
         tm.registerTopoAlgo(alg)
 
 
@@ -103,8 +101,7 @@ class TopoAlgoDefLegacy:
         alg.addvariable('IsoMask', 2) 
         alg.addvariable('MinEta', 0)
         alg.addvariable('MaxEta', _etamax)
-        alg.addgeneric('DoIsoCut', '1')
-        #alg.addgeneric('DoEtaCut', '1')
+        alg.addgeneric('DoIsoCut', 1)
         tm.registerTopoAlgo(alg)
 
         
@@ -595,7 +592,7 @@ class TopoAlgoDefLegacy:
             alg = AlgConf.TransverseMassInclusive1( name = toponame, inputs = [ inputList, 'XE'], outputs = [ toponame ], algoId = currentAlgoId )
             currentAlgoId += 1
             alg.addgeneric('InputWidth', HW.OutputWidthSortEM)
-            alg.addgeneric('MaxTob', str(d.nleading))
+            alg.addgeneric('MaxTob', d.nleading)
             alg.addgeneric('NumResultBits', 1)
             alg.addvariable('MinET1', str(d.ocut))
             alg.addvariable('MinET2', 0)
@@ -1177,7 +1174,7 @@ class TopoAlgoDefLegacy:
             alg = AlgConf.TransverseMassInclusive1( name = toponame, inputs = [ inputList, 'XE'], outputs = [ toponame ], algoId = currentAlgoId )
             currentAlgoId += 1
             alg.addgeneric('InputWidth', HW.OutputWidthSortEM)
-            alg.addgeneric('MaxTob', str(d.nleading))
+            alg.addgeneric('MaxTob', d.nleading)
             alg.addgeneric('NumResultBits', 1)
             alg.addvariable('MinET1', str(d.ocut))
             alg.addvariable('MinET2', 0)
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TypeWideThresholdConfig.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TypeWideThresholdConfig.py
index 1609bb0130d1da8eb24b97f098db924eeeb76a8a..0fe451494a081dece84f43723913021bae7e3f3c 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TypeWideThresholdConfig.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/TypeWideThresholdConfig.py
@@ -48,16 +48,13 @@ def getConfig_eEM():
     confObj = odict()
     confObj["workingPoints"] = odict()
     confObj["workingPoints"]["Loose"] = [
-        odict([("etamin",0),("etamax",21), ("reta", 16), ("wstot", 15), ("had", 30)]),
-        odict([("etamin",21),("etamax",49), ("reta", 20), ("wstot", 25), ("had", 35)])
+        odict([("reta", 0.12), ("wstot", 0.79), ("rhad", 0.31), ("maxEt", 60)]),
     ]
     confObj["workingPoints"]["Medium"] = [
-        odict([("etamin",0),("etamax",21), ("reta", 17), ("wstot", 20), ("had", 30)]),
-        odict([("etamin",21),("etamax",49), ("reta", 21), ("wstot", 25), ("had", 35)])
+        odict([("reta", 0.09), ("wstot", 0.65), ("rhad", 0.20), ("maxEt", 60)]),
     ]
     confObj["workingPoints"]["Tight"] = [
-        odict([("etamin",0),("etamax",21), ("reta", 18), ("wstot", 22), ("had", 30)]),
-        odict([("etamin",21),("etamax",49), ("reta", 22), ("wstot", 25), ("had", 35)])
+        odict([("reta", 0.08), ("wstot", 0.52), ("rhad", 0.19), ("maxEt", 60)]),
     ]
     confObj["ptMinToTopo"] = 3
     confObj["resolutionMeV"] = 100
@@ -68,16 +65,13 @@ def getConfig_eTAU():
     confObj = odict()
     confObj["workingPoints"] = odict()
     confObj["workingPoints"]["Loose"] = [
-        odict([("etamin",0),("etamax",21), ("reta", 16), ("wstot", 15), ("had", 30)]),
-        odict([("etamin",21),("etamax",49), ("reta", 20), ("wstot", 25), ("had", 35)])
+        odict([("isolation", 16), ("maxEt", 25)]),
     ]
     confObj["workingPoints"]["Medium"] = [
-        odict([("etamin",0),("etamax",21), ("reta", 17), ("wstot", 20), ("had", 30)]),
-        odict([("etamin",21),("etamax",49), ("reta", 21), ("wstot", 25), ("had", 35)])
+        odict([("isolation", 17), ("maxEt", 25)]),
     ]
     confObj["workingPoints"]["Tight"] = [
-        odict([("etamin",0),("etamax",21), ("reta", 18), ("wstot", 22), ("had", 30)]),
-        odict([("etamin",21),("etamax",49), ("reta", 22), ("wstot", 25), ("had", 35)])
+        odict([("isolation", 18), ("maxEt", 25)]),
     ]
     confObj["ptMinToTopo"] = 6
     confObj["resolutionMeV"] = 100
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8.py
index aa8f7cadff8189e2c950099df0fc9ccaab52861d..d44ccffe4ccbbb0d6bf38c4f4af73b2d9df0761a 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8.py
@@ -141,7 +141,7 @@ def defineMenu():
        
         
         # multi jet
-        'L1_J45.0ETA20_3J15.0ETA25',
+        'L1_J45.0ETA23_3J15.0ETA25',
         'L1_J50_2J40.0ETA25_3J15.0ETA25',
         'L1_3J50', 'L1_4J15', 'L1_4J20',
         'L1_3J15.0ETA25_XE40',
@@ -479,7 +479,7 @@ def defineMenu():
         'L1_4J15' : 131,
         'L1_4J20' : 132,
         'L1_3J15.0ETA25_XE40' : 184,
-        'L1_J45.0ETA20_3J15.0ETA25' : 86,
+        'L1_J45.0ETA23_3J15.0ETA25' : 86,
         'L1_J50_2J40.0ETA25_3J15.0ETA25' : 87,
  
         'L1_6J15' : 135,
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8_inputs_legacy.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8_inputs_legacy.py
index fd2b604629615485b614a736f92ddac46a6cc4cb..63f19ce04d6d5276f2b281f3093c3def18137f7d 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8_inputs_legacy.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8_inputs_legacy.py
@@ -85,7 +85,7 @@ def defineLegacyInputsMenu():
             "legacy" : True,
             "thresholds" : [
                 'J30.0ETA49', 'J35.0ETA23', 'J40.0ETA25', # 3 x central Jet
-                'J40', 'J50', 'J75', 'J85', 'J100', 'J45.0ETA20', 'J400', # 6 jets + 1 central jet
+                'J40', 'J50', 'J75', 'J85', 'J100', 'J45.0ETA23', 'J400', # 6 jets + 1 central jet
                 'J15.31ETA49', 'J20.31ETA49', 'J30.31ETA49', 'J50.31ETA49', 'J75.31ETA49', # 6 x FJ
             ]
         },
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/share/full_menu_cf.py b/Trigger/TriggerCommon/TriggerMenuMT/share/full_menu_cf.py
index 155328bdfd8d59ccfe691da50dafc36f9ca5c07c..78cbf0474981eb672ad672ee60e5ee33a85bc6c1 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/share/full_menu_cf.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/share/full_menu_cf.py
@@ -14,7 +14,7 @@
 
 def generateChains():
     from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import Chain, ChainStep, RecoFragmentsPool
-    from DecisionHandling.TestUtils import makeChain
+    from DecisionHandling.TestUtils import makeChain, makeChainStep
     
     testChains = []
     ##################################################################
@@ -26,9 +26,9 @@ def generateChains():
         electronSeq = RecoFragmentsPool.retrieve( fastElectronSequenceCfg, None )
         precisionCaloSeq = RecoFragmentsPool.retrieve( precisionCaloSequenceCfg, None )
         
-        FastCaloStep = ChainStep("ElectronFastCaloStep", [fastCaloSeq])
-        FastElectronStep = ChainStep("ElectronFastTrackStep", [electronSeq])
-        PrecisionCaloStep = ChainStep("ElectronPrecisionCaloStep", [precisionCaloSeq])
+        FastCaloStep = makeChainStep("ElectronFastCaloStep", [fastCaloSeq])
+        FastElectronStep = makeChainStep("ElectronFastTrackStep", [electronSeq])
+        PrecisionCaloStep = makeChainStep("ElectronPrecisionCaloStep", [precisionCaloSeq])
         
         electronChains  = [
             makeChain(name='HLT_e3_etcut1step_L1EM3',  L1Thresholds=["EM3"],  ChainSteps=[FastCaloStep]  ),
@@ -43,9 +43,9 @@ def generateChains():
         fastPhotonSeq = RecoFragmentsPool.retrieve( fastPhotonSequenceCfg, None )
         precisionCaloPhotonSeq = RecoFragmentsPool.retrieve( precisionPhotonCaloSequenceCfg, None)
         
-        FastCaloStep = ChainStep("PhotonFastCaloStep", [fastCaloSeq])
-        fastPhotonStep = ChainStep("PhotonStep2", [fastPhotonSeq])
-        precisionCaloPhotonStep = ChainStep("precisionCaloPhotonStep", [precisionCaloPhotonSeq])
+        FastCaloStep = makeChainStep("PhotonFastCaloStep", [fastCaloSeq])
+        fastPhotonStep = makeChainStep("PhotonStep2", [fastPhotonSeq])
+        precisionCaloPhotonStep = makeChainStep("precisionCaloPhotonStep", [precisionCaloPhotonSeq])
         
         photonChains = [
             makeChain(name='HLT_g5_etcut_L1EM3',    L1Thresholds=["EM3"],  ChainSteps=[ FastCaloStep,  fastPhotonStep, precisionCaloPhotonStep]  )
@@ -62,18 +62,19 @@ def generateChains():
         MuonChains  = []
         # step1
         mufastS= muFastSequence()
-        step1mufast=ChainStep("Step1_muFast", [ mufastS ])
+        step1mufast=makeChainStep("Step1_muFast", [ mufastS ])
         # step2
         mucombS = muCombSequence()
-        step2muComb=ChainStep("Step2_muComb", [ mucombS ])
+        step2muComb=makeChainStep("Step2_muComb", [ mucombS ])
         # step3
         muEFSAS = muEFSASequence()
-        step3muEFSA=ChainStep("Step3_muEFSA", [ muEFSAS ])
+        step3muEFSA=makeChainStep("Step3_muEFSA", [ muEFSAS ])
+        #/step3muIso =makeChainStep("Step3_muIso",  [ muIsoSequence() ])
         # step4
         muEFCBS = muEFCBSequence()
-        step4muEFCB=ChainStep("Step4_muEFCB", [ muEFCBS ])
+        step4muEFCB=makeChainStep("Step4_muEFCB", [ muEFCBS ])
 
-        emptyStep=ChainStep("Step2_empty", multiplicity=[])
+        emptyStep=makeChainStep("Step2_empty", multiplicity=[])
 
         ## single muon trigger  
         MuonChains += [ makeChain(name='HLT_mu6fast_L1MU6',     L1Thresholds=["MU6"], ChainSteps=[ step1mufast ])]
@@ -83,20 +84,20 @@ def generateChains():
 
         # multi muon trigger
         # 2muons symmetric
-        step1_2mufast_sym= ChainStep("Step1_2muFast_sym", [ mufastS], multiplicity=[2])
-        step2_2muComb_sym= ChainStep("Step2_2muComb_sym", [ mucombS], multiplicity=[2])
+        step1_2mufast_sym= makeChainStep("Step1_2muFast_sym", [ mufastS], multiplicity=[2])
+        step2_2muComb_sym= makeChainStep("Step2_2muComb_sym", [ mucombS], multiplicity=[2])
     
-        step3_2muEFSA_sym= ChainStep("Step3_2muEFSA_sym", [ muEFSAS], multiplicity=[2])
-        step4_2muEFCB_sym= ChainStep("Step4_2muEFCB_sym", [ muEFCBS], multiplicity=[2])
+        step3_2muEFSA_sym= makeChainStep("Step3_2muEFSA_sym", [ muEFSAS], multiplicity=[2])
+        step4_2muEFCB_sym= makeChainStep("Step4_2muEFCB_sym", [ muEFCBS], multiplicity=[2])
  
         MuonChains += [ makeChain(name='HLT_2mu6Comb_L12MU6',  L1Thresholds=["MU6"], ChainSteps=[ step1_2mufast_sym, step2_2muComb_sym ])]
 
         # 2muons asymmetric (this will change): 2 sequences, 2 seeds
-        step1_2mufast_asym= ChainStep("Step1_2muFast_asym", [ mufastS, mufastS], multiplicity=[1,1])
-        step2_2muComb_asym= ChainStep("Step1_2muComb_asym", [ mucombS, mucombS], multiplicity=[1,1])
+        step1_2mufast_asym= makeChainStep("Step1_2muFast_asym", [ mufastS, mufastS], multiplicity=[1,1])
+        step2_2muComb_asym= makeChainStep("Step1_2muComb_asym", [ mucombS, mucombS], multiplicity=[1,1])
     
-        step3_2muEFSA_asym= ChainStep("Step3_2muEFSA_asym", [ muEFSAS, muEFSAS], multiplicity=[1,1])
-        step4_2muEFCB_asym= ChainStep("Step4_2muEFCB_asym", [ muEFCBS, muEFCBS], multiplicity=[1,1])
+        step3_2muEFSA_asym= makeChainStep("Step3_2muEFSA_asym", [ muEFSAS, muEFSAS], multiplicity=[1,1])
+        step4_2muEFCB_asym= makeChainStep("Step4_2muEFCB_asym", [ muEFCBS, muEFCBS], multiplicity=[1,1])
         
     
         MuonChains += [ makeChain(name='HLT_mu6_mu4_L12MU4',
@@ -106,8 +107,8 @@ def generateChains():
         
         #FS Muon trigger
         # Full scan MS tracking step
-        stepFSmuEFSA=ChainStep("Step_FSmuEFSA", [muEFSAFSSequence()])
-        stepFSmuEFCB=ChainStep("Step_FSmuEFCB", [muEFCBFSSequence()])
+        stepFSmuEFSA=makeChainStep("Step_FSmuEFSA", [muEFSAFSSequence()])
+        stepFSmuEFCB=makeChainStep("Step_FSmuEFCB", [muEFCBFSSequence()])
         MuonChains += [ makeChain(name='HLT_mu6noL1_L1MU6', L1Thresholds=["FSNOSEED"],  ChainSteps=[stepFSmuEFSA, stepFSmuEFCB])] 
         
         testChains += MuonChains
@@ -121,23 +122,23 @@ def generateChains():
 
         # small-R jets, different calibrations HLT_AntiKt4EMTopoJets_subjesIS
         jetSeq_a4_tc_em = jetMenuSequenceFromString("a4_tc_em_subjesIS")
-        step_a4_tc_em =ChainStep("Step_jet_a4_tc_em", [jetSeq_a4_tc_em])
+        step_a4_tc_em =makeChainStep("Step_jet_a4_tc_em", [jetSeq_a4_tc_em])
         
         jetSeq_a4_tc_em_subjes = jetMenuSequenceFromString("a4_tc_em_subjes")
-        step_a4_tc_em_subjes = ChainStep("Step_jet_a4_subjes_tc_em", [jetSeq_a4_tc_em_subjes])
+        step_a4_tc_em_subjes = makeChainStep("Step_jet_a4_subjes_tc_em", [jetSeq_a4_tc_em_subjes])
         
         jetSeq_a4_tc_em_nocalib = jetMenuSequenceFromString("a4_tc_em_nojcalib")
-        step_a4_tc_em_nocalib=ChainStep("Step_jet_a4_nojcalib_tc_em", [jetSeq_a4_tc_em_nocalib])
+        step_a4_tc_em_nocalib=makeChainStep("Step_jet_a4_nojcalib_tc_em", [jetSeq_a4_tc_em_nocalib])
         
         #    jetSeq_a4_tc_lcw = jetMenuSequenceFromString("a10_tc_lcw_subjesIS")
         #    step_a4_tc_lcw=ChainStep("Step_jet_a10_tc_lcw", [jetSeq_a4_tc_lcw])
     
         # large-R jets
         jetSeq_a10_tc_lcw_subjes = jetMenuSequenceFromString("a10_tc_lcw_subjes")
-        step_a10_tc_lcw_subjes=ChainStep("Step_jet_a10_subjes_tc_lcw", [jetSeq_a10_tc_lcw_subjes])
+        step_a10_tc_lcw_subjes=makeChainStep("Step_jet_a10_subjes_tc_lcw", [jetSeq_a10_tc_lcw_subjes])
         
         jetSeq_a10r = jetMenuSequenceFromString("a10r_tc_em_subjesIS")
-        step_a10r=ChainStep("Step_jet_a10r", [jetSeq_a10r])
+        step_a10r=makeChainStep("Step_jet_a10r", [jetSeq_a10r])
         
         jetChains  = [
             makeChain(name='HLT_j45_L1J20',  L1Thresholds=["J20"], ChainSteps=[step_a4_tc_em]  ),
@@ -164,8 +165,8 @@ def generateChains():
 
         jetSequence = jetMenuSequenceFromString("a4_tc_em_subjesgscIS_ftf")
         
-        step1 = ChainStep("Step1_bjet", [jetSequence] )
-        step2 = ChainStep("Step2_bjet", [getBJetSequence()])
+        step1 = makeChainStep("Step1_bjet", [jetSequence] )
+        step2 = makeChainStep("Step2_bjet", [getBJetSequence()])
         
         bjetChains  = [
             makeChain(name='HLT_j45_ftf_subjesgscIS_boffperf_split_L1J20' , L1Thresholds=["J20"], ChainSteps=[step1,step2] ),
@@ -181,14 +182,14 @@ def generateChains():
     if opt.doTauSlice == True and False:
         from TriggerMenuMT.HLTMenuConfig.Tau.TauMenuSequences import getTauSequence
 
-        step1=ChainStep("Step1_tau", [getTauSequence('calo')])
-        step1MVA=ChainStep("Step1MVA_tau", [getTauSequence('calo_mva')])
+        step1=makeChainStep("Step1_tau", [getTauSequence('calo')])
+        step1MVA=makeChainStep("Step1MVA_tau", [getTauSequence('calo_mva')])
 
         #This runs the tau-preselection(TP) step
-        step2TP=ChainStep("Step2TP_tau", [getTauSequence('track_core')])
+        step2TP=makeChainStep("Step2TP_tau", [getTauSequence('track_core')])
 
         #This runs the EFTauMV hypo on top of fast tracks 
-        step2PT=ChainStep("Step2PT_tau", [getTauSequence('precision')])    
+        step2PT=makeChainStep("Step2PT_tau", [getTauSequence('precision')])    
   
         tauChains  = [
             makeChain(name='HLT_tau0_perf_ptonly_L1TAU12',              L1Thresholds=["TAU12"], ChainSteps=[step1, step2] ),
@@ -211,9 +212,9 @@ def generateChains():
         pufitRecoDict = extractMETRecoDict({'EFrecoAlg': "tcpufit"})
         metClusterPufitSeq = metMenuSequence(None, **pufitRecoDict)
         
-        metCellStep = ChainStep("Step1_met_cell", [metCellSeq])
-        metClusterPufitStep          = ChainStep("Step1_met_clusterpufit", [metClusterPufitSeq])
-        comboStep_cell_clusterpufit  = ChainStep("Step1_combo_cell_clusterpufit", [metCellSeq, metClusterPufitSeq], multiplicity=[1,1])
+        metCellStep = makeChainStep("Step1_met_cell", [metCellSeq])
+        metClusterPufitStep          = makeChainStep("Step1_met_clusterpufit", [metClusterPufitSeq])
+        comboStep_cell_clusterpufit  = makeChainStep("Step1_combo_cell_clusterpufit", [metCellSeq, metClusterPufitSeq], multiplicity=[1,1])
 
         metChains = [
             makeChain(name="HLT_xe65_L1XE50",         L1Thresholds=["XE50"], ChainSteps=[metCellStep]),
@@ -231,10 +232,10 @@ def generateChains():
         from TriggerMenuMT.HLTMenuConfig.Muon.MuonSequenceSetup import muFastSequence, muCombSequence, muEFSASequence, muEFCBSequence
         from TrigBphysHypo.TrigMultiTrkComboHypoConfig import DimuL2ComboHypoCfg, DimuEFComboHypoCfg
         
-        step1_dimufast=ChainStep("Step1_dimuFast", [muFastSequence()], multiplicity=[2])
-        step2_dimuComb=ChainStep("Step2_dimuComb", [muCombSequence()], multiplicity=[2], comboHypoCfg=DimuL2ComboHypoCfg)
-        step3_dimuEFSA=ChainStep("Step3_dimuEFSA", [muEFSASequence()], multiplicity=[2])
-        step4_dimuEFCB=ChainStep("Step4_dimuEFCB", [muEFCBSequence()], multiplicity=[2], comboHypoCfg=DimuEFComboHypoCfg)
+        step1_dimufast=makeChainStep("Step1_dimuFast", [muFastSequence()], multiplicity=[2])
+        step2_dimuComb=makeChainStep("Step2_dimuComb", [muCombSequence()], multiplicity=[2], comboHypoCfg=DimuL2ComboHypoCfg)
+        step3_dimuEFSA=makeChainStep("Step3_dimuEFSA", [muEFSASequence()], multiplicity=[2])
+        step4_dimuEFCB=makeChainStep("Step4_dimuEFCB", [muEFCBSequence()], multiplicity=[2], comboHypoCfg=DimuEFComboHypoCfg)
         steps = [step1_dimufast, step2_dimuComb, step3_dimuEFSA, step4_dimuEFCB]
         
         BphysChains = [
@@ -256,8 +257,8 @@ def generateChains():
         
         from TriggerMenuMT.HLTMenuConfig.Muon.MuonSequenceSetup import muFastSequence
         
-        comboStep_et_mufast           = ChainStep("Step1_et_mufast", [fastCaloSeq, muFastSequence()], multiplicity=[1,1])
-        comboStep_mufast_etcut1_step1 = ChainStep("Step1_mufast_etcut1", [muFastSequence(), fastCaloSeq], multiplicity=[1,1])
+        comboStep_et_mufast           = makeChainStep("Step1_et_mufast", [fastCaloSeq, muFastSequence()], multiplicity=[1,1])
+        comboStep_mufast_etcut1_step1 = makeChainStep("Step1_mufast_etcut1", [muFastSequence(), fastCaloSeq], multiplicity=[1,1])
         
         comboChains =  [ makeChain(name='HLT_e3_etcut_mu6_L1EM8I_MU10', L1Thresholds=["EM8I", "MU10"],  ChainSteps=[comboStep_et_mufast ])]
     #   comboChains += [Chain(name='HLT_mu8fast_e8_etcut1step',   ChainSteps=[ comboStep_mufast_etcut1_step1 ])]