From 3e865b2bd2e470d62fabbae8c4b08bb2266cd3e0 Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Fri, 4 Dec 2020 14:59:42 +0000
Subject: [PATCH] Enable new L1 menu format in L1Topo and CTP simulation (II)

---
 .../share/TrigL1TopoWriteValData.py           |   8 +-
 .../TrigConfData/TrigConfData/L1Connector.h   |   6 +-
 .../TrigConfData/src/L1Connector.cxx          |  10 +-
 .../python/TrigConfigSvcConfig.py             |  20 +-
 .../L1Topo/L1TopoCoreSim/CMakeLists.txt       |   6 +-
 .../L1TopoCoreSim/DecisionConnector.h         |   9 +-
 .../L1TopoCoreSim/GlobalDecision.h            |  33 +-
 .../L1TopoCoreSim/TopoCoreSimResult.h         |   4 +-
 .../L1TopoCoreSim/TopoSteering.h              |  20 +-
 .../L1TopoCoreSim/TopoSteeringStructure.h     |   5 +-
 .../L1TopoCoreSim/Root/DecisionConnector.cxx  |   8 +-
 .../L1TopoCoreSim/Root/GlobalDecision.cxx     | 109 +++--
 .../L1TopoCoreSim/Root/TopoCoreSimResult.cxx  |  28 +-
 .../L1TopoCoreSim/Root/TopoSteering.cxx       |  91 ++--
 .../Root/TopoSteeringStructure.cxx            | 422 ++++++++++++------
 .../L1TopoCoreSim/src/test/TopoStandAlone.cxx |  34 +-
 .../src/test/TopoTestSteeringConfig.cxx       |  19 +-
 .../L1Topo/L1TopoSimulation/CMakeLists.txt    |   2 +-
 .../python/L1TopoSimulationConfig.py          |   7 +-
 .../share/L1TopoSimulationTest.py             |  11 +-
 .../L1TopoSimulation/src/L1TopoSimulation.cxx | 163 +++----
 .../L1TopoSimulation/src/L1TopoSimulation.h   | 103 ++---
 .../src/test/L1TopoSimulationTest.cxx         |  45 +-
 .../src/test/L1TopoSimulationTest.h           |   2 +
 .../TrigT1/TrigT1CTP/src/CTPSimulation.cxx    | 189 +++++---
 Trigger/TrigT1/TrigT1CTP/src/CTPSimulation.h  |   2 +-
 .../TrigT1/TrigT1CTP/src/CTPTriggerItem.cxx   |  14 +-
 .../TrigT1/TrigT1CTP/src/ResultBuilder.cxx    |   5 +-
 Trigger/TrigT1/TrigT1CTP/src/ThresholdMap.cxx |   7 +-
 .../python/Lvl1SimulationConfig.py            |  26 +-
 .../TriggerMenuMT/python/L1/Config/ItemDef.py |  13 +-
 .../python/L1/Menu/MenuMapping.py             |   1 +
 32 files changed, 843 insertions(+), 579 deletions(-)

diff --git a/HLT/Trigger/TrigMonitoring/TrigOnlineMonitor/share/TrigL1TopoWriteValData.py b/HLT/Trigger/TrigMonitoring/TrigOnlineMonitor/share/TrigL1TopoWriteValData.py
index cbf3c84a238..8388b47ca14 100755
--- a/HLT/Trigger/TrigMonitoring/TrigOnlineMonitor/share/TrigL1TopoWriteValData.py
+++ b/HLT/Trigger/TrigMonitoring/TrigOnlineMonitor/share/TrigL1TopoWriteValData.py
@@ -55,10 +55,10 @@ else:
 
 
 # Add an instance of TrigL1TopoWriteValData to the sequence
-from AthenaCommon import CfgMgr
-l1topoWriteValData = CfgMgr.TrigL1TopoWriteValData("l1topoWriteValData")
-topSequence += l1topoWriteValData
-log.debug("added l1topoWriteValData to topSequence")
+#from AthenaCommon import CfgMgr
+#l1topoWriteValData = CfgMgr.TrigL1TopoWriteValData("l1topoWriteValData")
+#topSequence += l1topoWriteValData
+#log.debug("added l1topoWriteValData to topSequence")
 #l1topoWriteValData.OutputLevel=1
 
 #--------------------------------------------------------------
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Connector.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Connector.h
index 69cd439b7ec..5b85a067afa 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Connector.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Connector.h
@@ -20,8 +20,8 @@ namespace TrigConf {
     */
    class TriggerLine {
    public:
-      TriggerLine(const std::string & name, unsigned int startbit, unsigned int nbits, unsigned int fpga=0, unsigned int clock=0) :
-         m_name(name), m_startbit(startbit), m_nbits(nbits), m_fpga(fpga), m_clock(clock)
+   TriggerLine(const std::string & name, unsigned int startbit, unsigned int nbits, unsigned int fpga=0, unsigned int clock=0, const std::string & connName="") :
+     m_name(name), m_startbit(startbit), m_nbits(nbits), m_fpga(fpga), m_clock(clock), m_connName(connName)
       {}
       const std::string & name() const { return m_name; }
       unsigned int startbit() const { return  m_startbit; }
@@ -29,12 +29,14 @@ namespace TrigConf {
       unsigned int nbits() const { return m_nbits; }
       unsigned int fpga() const { return m_fpga; }
       unsigned int clock() const { return m_clock; }
+      const std::string & connName() const { return m_connName; }
    private:
       std::string m_name{""};      // the name of the threshold whose multiplicity is transmitted
       unsigned int m_startbit{0};  // the location on the cable - first bit
       unsigned int m_nbits{0};     // the location on the cable - number of bits used to encode the multiplicity
       unsigned int m_fpga{0};      // for electrical signals from L1Topo boards only: the fpga the signal is coming from
       unsigned int m_clock{0};     // for electrical signals from L1Topo boards only: the clock of the signal
+      std::string m_connName{""};  // the name of the connector where the triggerline is allocated
    };
 
    /** @brief L1 connectors configuration */
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1Connector.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1Connector.cxx
index 3d7de39fe71..7a08959afc2 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1Connector.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1Connector.cxx
@@ -52,10 +52,10 @@ TrigConf::L1Connector::update()
       for( size_t clock = 0; clock < m_maxClock; ++clock ) {
          std::string path = "triggerlines";
          if( m_type == ConnectorType::ELECTRICAL ) {
-            if(hasMultipleFPGAs) {
-               path += ".fpga";
-               path += std::to_string(fpga);
-            }
+	    if(hasMultipleFPGAs) {
+ 	       path += ".fpga";
+	       path += std::to_string(fpga);
+	    }
             path += ".clock";
             path += std::to_string(clock);
          }
@@ -66,7 +66,7 @@ TrigConf::L1Connector::update()
             m_triggerLines[fpga][clock].emplace_back( name,
                                                       tl.second.get_child("startbit").get_value<unsigned int>(),
                                                       tl.second.get_child("nbits").get_value<unsigned int>(),
-                                                      fpga, clock);
+                                                      fpga, clock, m_name);
             m_lineByName[name] = & m_triggerLines[fpga][clock].back();
          }
       }
diff --git a/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcConfig.py b/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcConfig.py
index 59b620da651..fbf5759f4bd 100755
--- a/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcConfig.py
+++ b/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcConfig.py
@@ -364,9 +364,27 @@ class SetupTrigConfigSvc(object):
                     self.mlog.info( "Will not setup HLTConfigSvc, since TriggerFlags doLVL2(), doEF(), and doHLT() are all False" )
                     self.states[self.states.index("xml")] = "xmll1"
 
-                self.mlog.info( "setup LVL1ConfigSvc and add instance to ServiceMgr (xml file="+self.l1XmlFile+")" )
+                # generating a json L1 menu for Physics_pp_v7_primaries
+                # is needed for a transition period where we still have jobs
+                # running on this old menu, but the software expects a
+                # json-style L1 menu
+                menuName = TriggerFlags.triggerMenuSetup()
+                doGenerateJsonMenuForRun2Menu = (menuName == "Physics_pp_v7_primaries")
+                if doGenerateJsonMenuForRun2Menu:
+                    self.mlog.info("Generating L1 menu %s", menuName)
+                    from TriggerMenuMT.L1.L1MenuConfig import L1MenuConfig
+                    l1cfg = L1MenuConfig(menuName = menuName) # create menu
+                    fileName = 'L1Menu_' + menuName + '.json'
+                    l1JsonFileName = l1cfg.writeJSON(outputFile = fileName) # write menu
+                self.mlog.info("setup LVL1 ConfigSvc and add instance to ServiceMgr")
+                self.mlog.info("xml file = %s", self.l1XmlFile)
+                if doGenerateJsonMenuForRun2Menu:
+                    self.mlog.info("json file= %s", l1JsonFileName)
                 l1 = LVL1ConfigSvc("LVL1ConfigSvc")
                 l1.XMLMenuFile = self.l1XmlFile
+                if doGenerateJsonMenuForRun2Menu:
+                    l1.JsonFileName = l1JsonFileName
+
                 ServiceMgr += l1
 
                 self.mlog.info( "setup L1TopoConfigSvc and add instance to ServiceMgr (xml file="+self.l1topoXmlFile+")" )
diff --git a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/CMakeLists.txt b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/CMakeLists.txt
index dd086bcc87c..39c5b7d102e 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/CMakeLists.txt
+++ b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/CMakeLists.txt
@@ -13,13 +13,13 @@ atlas_add_library( L1TopoCoreSim
                    Root/*.cxx
                    PUBLIC_HEADERS L1TopoCoreSim
                    PRIVATE_INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS}
-                   LINK_LIBRARIES ${ROOT_LIBRARIES} L1TopoCommon L1TopoConfig L1TopoEvent L1TopoInterfaces TrigConfBase
+                   LINK_LIBRARIES ${ROOT_LIBRARIES} L1TopoCommon L1TopoConfig L1TopoEvent L1TopoInterfaces TrigConfBase TrigConfData
                    PRIVATE_LINK_LIBRARIES L1TopoHardware L1TopoAlgorithms )
 
 atlas_add_executable( TrigConfTopoStandAlone
                       src/test/TopoStandAlone.cxx
-                      LINK_LIBRARIES L1TopoCoreSim TrigConfBase )
+                      LINK_LIBRARIES L1TopoCoreSim TrigConfBase TrigConfIO TrigConfData)
 
 atlas_add_executable( TrigConfTopoTestSteeringConfig
                       src/test/TopoTestSteeringConfig.cxx
-                      LINK_LIBRARIES L1TopoCoreSim )
+                      LINK_LIBRARIES L1TopoCoreSim TrigConfBase TrigConfIO TrigConfData)
diff --git a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/DecisionConnector.h b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/DecisionConnector.h
index cf6143617d6..f66de22f6e4 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/DecisionConnector.h
+++ b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/DecisionConnector.h
@@ -1,4 +1,6 @@
-// Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
 
 #ifndef L1TopoCoreSim_DecisionConnector
 #define L1TopoCoreSim_DecisionConnector
@@ -7,6 +9,7 @@
 
 #include "L1TopoInterfaces/Decision.h"
 #include "L1TopoConfig/L1TopoConfigOutputList.h"
+#include "TrigConfData/L1Connector.h"
 
 #include <vector>
 #include <string>
@@ -37,7 +40,7 @@ namespace TCS {
 
       bool decision(const std::string & trigger) const;
 
-      const std::vector<TXC::TriggerLine> & triggers() const { return m_triggers; }
+      const std::vector<TrigConf::TriggerLine> & triggers() const { return m_triggers; }
 
       // output data
       void attachOutputData(const std::vector<TOBArray *>&);
@@ -62,7 +65,7 @@ namespace TCS {
 
       TCS::DecisionAlg* m_decisionAlgorithm;
 
-      std::vector<TXC::TriggerLine> m_triggers;
+      std::vector<TrigConf::TriggerLine> m_triggers;
 
       // attached output data
       std::vector<TOBArray const *>  m_outputData;
diff --git a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/GlobalDecision.h b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/GlobalDecision.h
index 31903997479..b50a84421f5 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/GlobalDecision.h
+++ b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/GlobalDecision.h
@@ -1,4 +1,7 @@
-// Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
 
 #ifndef L1TopoCoreSim_GlobalDecision
 #define L1TopoCoreSim_GlobalDecision
@@ -8,6 +11,8 @@
 #include "L1TopoCommon/StatusCode.h"
 #include "L1TopoConfig/L1TopoConfigOutputList.h"
 
+#include "TrigConfData/L1Connector.h"
+
 #include <iostream>
 #include <vector>
 #include <set>
@@ -29,22 +34,22 @@ namespace TCS {
 
    class GlobalDecision : public TrigConf::TrigConfMessaging {
    public:
-      GlobalDecision();
+      GlobalDecision(const std::string & name = "L1TopoGlobalDecision");
 
-      uint64_t decision(unsigned int module) const { return m_decision[module]; }
+      uint64_t decision_field(const std::string & connName) const { return m_decision.find(connName)->second; }
 
-      uint32_t decision(unsigned int module, unsigned int clock) const;
+      uint32_t decision_field(std::string connName, unsigned int clock) const;
 
-      bool passed(unsigned int module, unsigned int bit) const { return ( ( (uint64_t)0x1 << bit) & m_decision[module]) != 0; }
-      uint64_t overflow(unsigned int module) const { return m_overflow[module]; }
-      uint32_t overflow(unsigned int module, unsigned int clock) const;
-      bool overflowed(unsigned int module, unsigned int bit) const { return ( ( (uint64_t)0x1 << bit) & m_overflow[module]) != 0; }
+      bool passed(std::string connName, unsigned int bit) const { return ( ( (uint64_t)0x1 << bit) & m_decision.find(connName)->second) != 0; }
+      uint64_t overflow_field(std::string connName) const { return m_overflow.find(connName)->second; }
+      uint32_t overflow_field(std::string connName, unsigned int clock) const;
+      bool overflowed(std::string connName, unsigned int bit) const { return ( ( (uint64_t)0x1 << bit) & m_overflow.find(connName)->second) != 0; }
 
       const Decision & decision(const std::string & algName) const;
 
       bool isValid() const { return m_valid; }
 
-      void setTriggerLines(const std::vector<TXC::TriggerLine> & triggers) { m_triggers = triggers; }
+      void setTriggerLines(const std::vector<TrigConf::TriggerLine> & triggers);
 
       StatusCode collectDecision(const std::set<DecisionConnector*> & outconn);
 
@@ -54,16 +59,16 @@ namespace TCS {
    private:
       friend std::ostream& operator<<(std::ostream&, const TCS::GlobalDecision &);
 
-      // 64 bit decision bit field
-      uint64_t m_decision[3] {0,0,0};
-      // 64 bit overflow bit field
-      uint64_t m_overflow[3] {0,0,0};
+      // 64 bit decision bit field - map connector name-decision field
+      std::map<std::string,uint64_t> m_decision;
+      // 64 bit overflow bit field - map connector name-overflow field
+      std::map<std::string,uint64_t> m_overflow;
       // flags if the decision field is up to date
       // set by @collectDecision(), unset by @resetDecision()
       bool m_valid {false};
 
       // trigger lines
-      std::vector<TXC::TriggerLine> m_triggers;
+      std::vector<TrigConf::TriggerLine> m_triggers;
    };
 
 }
diff --git a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/TopoCoreSimResult.h b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/TopoCoreSimResult.h
index 88aecb9e2eb..de178edb679 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/TopoCoreSimResult.h
+++ b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/TopoCoreSimResult.h
@@ -10,6 +10,8 @@
 
 #include "TrigConfBase/TrigConfMessaging.h"
 
+#include "TrigConfData/L1Menu.h"
+
 #include <iostream>
 #include "L1TopoCommon/StatusCode.h"
 #include "L1TopoCoreSim/GlobalDecision.h"
@@ -43,7 +45,7 @@ namespace TCS {
 
       const std::vector<const TCS::TOBArray*> & output(const std::string & connName) const;
 
-      StatusCode setupFromMenu(const TXC::L1TopoMenu & menu, const std::map<std::string, TCS::DecisionConnector*>& outputConnectorMap);
+      StatusCode setupFromMenu(const std::map<std::string, TCS::DecisionConnector*>& outputConnectorMap);
 
       StatusCode collectResult(TCS::DecisionConnector* outputConn = nullptr );
 
diff --git a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/TopoSteering.h b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/TopoSteering.h
index 042c4e20b00..0f035f6597e 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/TopoSteering.h
+++ b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/TopoSteering.h
@@ -1,4 +1,6 @@
-// Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
 
 #ifndef L1TopoCoreSim_TopoSteering
 #define L1TopoCoreSim_TopoSteering
@@ -17,6 +19,9 @@
 #include "L1TopoCoreSim/TopoCoreSimResult.h"
 #include "L1TopoCoreSim/TopoSteeringStructure.h"
 
+// Menu related dependencies
+#include "TrigConfData/L1Menu.h"
+
 namespace TXC {
    class L1TopoMenu;
 }
@@ -48,16 +53,20 @@ namespace TCS {
 
       const TopoCoreSimResult & simulationResult() const { return m_simulationResult; }
 
+
       // @brief: build the execution structure and parameterspace from
       // the configuration
       StatusCode setupFromConfiguration(const TXC::L1TopoMenu& menu);
-     
+
+      StatusCode setupFromConfiguration(const TrigConf::L1Menu& l1menu);
+
       void setUseBitwise(bool useBitwise) { m_useBitwise = useBitwise; }
  
       // @brief: call the initialize function of the algorithms
       // will be called after the parameters are set and before the event loop starts
       StatusCode initializeAlgorithms();
 
+
       // run the topo simulation
       StatusCode executeEvent();
       
@@ -149,8 +158,9 @@ namespace TCS {
 
       std::bitset<numberOfL1TopoBits> m_triggerHdwBits;
       std::bitset<numberOfL1TopoBits> m_ovrflowHdwBits;
-
    };
-}
 
-#endif
+   
+} 
+
+#endif 
diff --git a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/TopoSteeringStructure.h b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/TopoSteeringStructure.h
index 119c899410a..8aac19c35c5 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/TopoSteeringStructure.h
+++ b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/L1TopoCoreSim/TopoSteeringStructure.h
@@ -3,6 +3,9 @@
 */
 #include "L1TopoCommon/StatusCode.h"
 
+#include "TrigConfData/L1Menu.h"
+#include "TrigConfData/L1TopoAlgorithm.h"
+
 #include <vector>
 #include <map>
 #include <string>
@@ -28,7 +31,7 @@ namespace TCS {
 
       ~TopoSteeringStructure();
 
-      StatusCode setupFromMenu(const TXC::L1TopoMenu& menu, bool debug = false);
+      StatusCode setupFromMenu(const TrigConf::L1Menu& l1menu, bool debug = false, bool legacy = false);
 
       // accessors
       bool isConfigured() const { return m_isConfigured; }
diff --git a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/DecisionConnector.cxx b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/DecisionConnector.cxx
index 1dba9be38b4..ee648be0973 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/DecisionConnector.cxx
+++ b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/DecisionConnector.cxx
@@ -1,4 +1,6 @@
-// Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
 
 #include "L1TopoCoreSim/DecisionConnector.h"
 
@@ -24,7 +26,7 @@ DecisionConnector::~DecisionConnector() {
 bool
 TCS::DecisionConnector::decision(const std::string & trigger) const {
    unsigned int index(0);
-   for(const TXC::TriggerLine & tl : m_triggers) {
+   for(const TrigConf::TriggerLine & tl : m_triggers) {
       if(tl.name() == trigger)
          return m_decision.bit(index);
       ++index;
@@ -37,7 +39,7 @@ TCS::DecisionConnector::decision(const std::string & trigger) const {
 TCS::TOBArray const *
 TCS::DecisionConnector::output(const std::string & trigger) const {
    unsigned int index(0);
-   for(const TXC::TriggerLine & tl : m_triggers) {
+   for(const TrigConf::TriggerLine & tl : m_triggers) {
       if(tl.name() == trigger)
          return m_outputData[index];
       ++index;
diff --git a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/GlobalDecision.cxx b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/GlobalDecision.cxx
index 5c59db40692..e6068f8b508 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/GlobalDecision.cxx
+++ b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/GlobalDecision.cxx
@@ -1,4 +1,6 @@
-// Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
 
 #include <iomanip>
 
@@ -10,33 +12,53 @@
 using namespace std;
 using namespace TCS;
 
+void
+GlobalDecision::setTriggerLines(const vector<TrigConf::TriggerLine> & triggers) {
+
+  m_triggers = triggers;
+  vector<string> connNames = {};
+  for (const TrigConf::TriggerLine & trigger : triggers){
+    auto it = find(connNames.begin(), connNames.end(), trigger.connName());
+    if (it == connNames.end()){
+      connNames.push_back(trigger.connName());
+      m_decision[trigger.connName()] = 0;
+    }
+  }
+}
+  
 uint32_t
-GlobalDecision::decision(unsigned int module, unsigned int clock) const {
-   if(clock==0) {
-      // lower 32 bit
-      return (uint32_t) (m_decision[module] & 0xffffffff);
-   } else {
-      // upper 32 bit
-      uint64_t clock1 = m_decision[module] & 0xffffffff00000000;
-      return (uint32_t) (clock1 >> 32);
+GlobalDecision::decision_field(string connName, unsigned int clock) const {
+   try {
+      if(clock==0) {
+         // lower 32 bit
+         return (uint32_t) (m_decision.at(connName) & 0xffffffff);
+      } else {
+         // upper 32 bit
+         uint64_t clock1 = m_decision.at(connName) & 0xffffffff00000000;
+         return (uint32_t) (clock1 >> 32);
+      }
+   }
+   catch(std::exception &) {
+      TRG_MSG_ERROR("Connector name " << connName << " unknown");
+      throw;
    }
 }
 
 uint32_t
-GlobalDecision::overflow(unsigned int module, unsigned int clock) const {
+GlobalDecision::overflow_field(string connName, unsigned int clock) const {
    if(clock==0) {
       // lower 32 bit
-      return (uint32_t) (m_overflow[module] & 0xffffffff);
+      return (uint32_t) (m_overflow.find(connName)->second & 0xffffffff);
    } else {
       // upper 32 bit
-      uint64_t clock1 = m_overflow[module] & 0xffffffff00000000;
+      uint64_t clock1 = m_overflow.find(connName)->second & 0xffffffff00000000;
       return (uint32_t) (clock1 >> 32);
    }
 }
 
 
-GlobalDecision::GlobalDecision() :
-   TrigConfMessaging("L1TopoGlobalDecision")
+GlobalDecision::GlobalDecision(const std::string &name) :
+   TrigConfMessaging(name)
 {}
 
 /****************************************************************
@@ -47,7 +69,7 @@ GlobalDecision::GlobalDecision() :
  *
  ****************************************************************/
 
-StatusCode
+TCS::StatusCode
 GlobalDecision::collectDecision(const set<DecisionConnector*> & outconn) {
    resetDecision();
 
@@ -56,34 +78,34 @@ GlobalDecision::collectDecision(const set<DecisionConnector*> & outconn) {
       const Decision& dec = conn->decision();
 
       unsigned int pos = 0; // for multi-output algorithms pos is the output index
-      for(const TXC::TriggerLine & trigger : conn->triggers() ) {
-
-         unsigned int bit = trigger.counter() % 64;  // trigger bit in module
+      for(const TrigConf::TriggerLine & trigger : conn->triggers() ) {
          
-         uint64_t & moduleDec = m_decision[trigger.module()];
-         uint64_t & moduleOvf = m_overflow[trigger.module()];
-         uint64_t mask(0x1);
+	      unsigned int position = trigger.startbit() + 32*trigger.fpga() + 16*trigger.clock();
 
-         //std::cout << "JOERG GlobalDecision::collectDecision: trigger line " << trigger.name() << " [counter="<<trigger.counter()<<"] on module " << trigger.module() << " and bit [0-63] " << bit << " -> dec " << dec << std::endl;
+         uint64_t & connectorDec = m_decision[trigger.connName()];
+         uint64_t & connectorOvf = m_overflow[trigger.connName()];
+         uint64_t mask(0x1);
 
          if( dec.bit(pos++) )  // bit set?
-            moduleDec |= (mask << bit);
+            connectorDec |= (mask << position);
          if( dec.overflow())
-            moduleOvf |= (mask << bit);
+            connectorOvf |= (mask << position);
       }
 
    }
    m_valid = true;
-   return StatusCode::SUCCESS;
+   return TCS::StatusCode::SUCCESS;
 }
 
 
-StatusCode
+TCS::StatusCode
 GlobalDecision::resetDecision() {
-   m_decision[0] = m_decision[1] = m_decision[2] = 0;
-   m_overflow[0] = m_overflow[1] = m_overflow[2] = 0;
+   for(auto const& dec : m_decision)
+     m_decision[dec.first] = 0;
+   for(auto const& ovf : m_overflow)
+     m_overflow[ovf.first] = 0;
    m_valid = false;
-   return StatusCode::SUCCESS;
+   return TCS::StatusCode::SUCCESS;
 }
 
 
@@ -96,18 +118,17 @@ operator<<(std::ostream& o, const TCS::GlobalDecision & dec) {
    if(!dec.isValid()) 
       o << "Note that the overall decision has not been calculated" << endl;
 
-   for(unsigned int module = 0; module<3; ++module)
-      o << "Overall decision module " << module << ": 0x" << right << hex << setfill('0') << setw(16) << dec.decision(module) << std::dec << setfill(' ') << endl;
-
+   for(auto const& itdec : dec.m_decision)
+      o << "Overall decision for connector " << itdec.first << ": 0x" << right << hex << setfill('0') << setw(16) << dec.decision_field(itdec.first) << std::dec << setfill(' ') << endl;
    
    if(dec.isValid()) {
-      for(const TXC::TriggerLine & trigger : dec.m_triggers)
-         o << "  " << setw(30) << left << trigger.name() << "  " << (dec.passed(trigger.module(), trigger.counter() % 64) ? "pass" : "fail") << endl;
+     for(const TrigConf::TriggerLine & trigger : dec.m_triggers){
+	 unsigned int position = trigger.startbit() + 32*trigger.fpga() + 16*trigger.clock();
+	 o << "  " << setw(30) << left << trigger.name() << "  " << (dec.passed(trigger.connName(), position) ? "pass" : "fail") << endl;}
    } else {
-      for(const TXC::TriggerLine & trigger : dec.m_triggers)
-         o << "  " << setw(30) << left << trigger.name() << "  unset" << endl;
+      for(const TrigConf::TriggerLine & trigger : dec.m_triggers)
+	o << "  " << setw(30) << left << trigger.name() << "  unset" << endl;
    }
-   
    return o;
 }
 //----------------------------------------------------------
@@ -117,17 +138,17 @@ GlobalDecision::print() const {
    if(!isValid()) 
       TRG_MSG_INFO("Note that the overall decision has not been calculated");
 
-   for(unsigned int module = 0; module<3; ++module)
-      TRG_MSG_INFO("Overall decision module " << module << ": 0x" << right << hex << setfill('0') << setw(16) << decision(module) << std::dec << setfill(' '));
+   for(auto const& dec : m_decision)
+      TRG_MSG_INFO("Overall decision from connector " << dec.first << ": 0x" << right << hex << setfill('0') << setw(16) << decision_field(dec.first) << std::dec << setfill(' '));
 
-   
    if(isValid()) {
-      for(const TXC::TriggerLine & trigger : m_triggers)
-         TRG_MSG_INFO("      " << setw(30) << left << trigger.name() << "  " << (passed(trigger.module(), trigger.counter() % 64) ? "pass" : "fail") );
+      for(const TrigConf::TriggerLine & trigger : m_triggers){
+	 unsigned int position = trigger.startbit() + 32*trigger.fpga() + 16*trigger.clock();
+ 	 TRG_MSG_INFO("      " << setw(30) << left << trigger.name() << "  " << (passed(trigger.connName(), position) ? "pass" : "fail") );}
    } else {
-      for(const TXC::TriggerLine & trigger : m_triggers)
+      for(const TrigConf::TriggerLine & trigger : m_triggers)
          TRG_MSG_INFO("      " << setw(30) << left << trigger.name() << "  unset" );
    }
-   
 }
+
 }
diff --git a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/TopoCoreSimResult.cxx b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/TopoCoreSimResult.cxx
index f1dcd5ee539..fe17f5cfeaf 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/TopoCoreSimResult.cxx
+++ b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/TopoCoreSimResult.cxx
@@ -15,6 +15,8 @@
 
 #include "L1TopoCommon/Exception.h"
 
+#include "TrigConfData/L1Menu.h"
+
 #include <algorithm>
 
 using namespace std;
@@ -46,9 +48,9 @@ TopoCoreSimResult::triggerOutput(const std::string & triggerName) const {
 
 
 
-StatusCode
+TCS::StatusCode
 TopoCoreSimResult::collectResult(TCS::DecisionConnector* outputConn) {
-   StatusCode sc = StatusCode::SUCCESS;
+   TCS::StatusCode sc = TCS::StatusCode::SUCCESS;
    if (outputConn == nullptr ) {
       sc = m_globalDecision.collectDecision(m_outputConnectors);
    } else {
@@ -59,31 +61,33 @@ TopoCoreSimResult::collectResult(TCS::DecisionConnector* outputConn) {
 }
 
 
-StatusCode
+TCS::StatusCode
 TopoCoreSimResult::reset() {
    return m_globalDecision.resetDecision();
 }
 
 
-StatusCode
-TopoCoreSimResult::setupFromMenu(const TXC::L1TopoMenu & menu, 
-                                 const std::map<std::string, TCS::DecisionConnector*>& outputConnectorMap) {
+TCS::StatusCode
+TopoCoreSimResult::setupFromMenu(const std::map<std::string, TCS::DecisionConnector*>& outputConnectorMap) {
 
    m_outputConnectorMap = outputConnectorMap;
 
+   vector<TrigConf::TriggerLine> triggerLines;
+
    for(auto & x : m_outputConnectorMap) {
       // fill the set
       m_outputConnectors.insert(x.second);
 
       // fill the trigger line map (trigger name --> (TCS::DecisionConnector*,unsigned int index) )
-      for( const TXC::TriggerLine & trigger : x.second->triggers() ) {
+      for( const TrigConf::TriggerLine & trigger : x.second->triggers() ) {
          m_triggerLocation[trigger.name()] = x.second;
+	 triggerLines.push_back(trigger);
       }
    }
 
-   m_globalDecision.setTriggerLines(menu.getL1TopoConfigOutputList().getTriggerLines());
+   m_globalDecision.setTriggerLines(triggerLines);
 
-   return StatusCode::SUCCESS;
+   return TCS::StatusCode::SUCCESS;
 }
 
 
@@ -112,9 +116,9 @@ operator<<(std::ostream& o, const TCS::TopoCoreSimResult & simRes) {
 
    for( const DecisionConnector * conn : simRes.m_outputConnectors ) {
       o << conn->name() << endl;
-      for(const TXC::TriggerLine & trigger : conn->triggers()) {
-         o << "  " << trigger << endl;
-      }
+   //   for(const TrigConf::TriggerLine & trigger : conn->triggers()) {
+	//         o << "  " << trigger << endl;
+   //   }
       for(const TCS::TOBArray* output : conn->outputData())
          o << "  output " << output << endl;
    }
diff --git a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/TopoSteering.cxx b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/TopoSteering.cxx
index 007bfc2f624..a7e609b804d 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/TopoSteering.cxx
+++ b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/TopoSteering.cxx
@@ -1,8 +1,11 @@
-// Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
 
 #include "L1TopoInterfaces/AlgFactory.h" 
 #include "L1TopoInterfaces/IL1TopoHistSvc.h"
 
+
 #include "L1TopoInterfaces/ConfigurableAlg.h"
 #include "L1TopoInterfaces/ParameterSpace.h"
 #include "L1TopoInterfaces/SortingAlg.h"
@@ -41,22 +44,31 @@ TopoSteering::~TopoSteering() {
    AlgFactory::destroy_instance();
 }
 
-StatusCode
-TopoSteering::setupFromConfiguration(const TXC::L1TopoMenu& menu) {
-   
-   if(m_useBitwise){ TRG_MSG_INFO("Will be using bitwise implementation of algorithms");}
-   else{TRG_MSG_INFO("Will NOT be using bitwise implementation of algorithms");}
+TCS::StatusCode
+TopoSteering::setupFromConfiguration(const TXC::L1TopoMenu&){
+  
+  // Keep this method to avoid crashes. TO-DO: Switch menu loading in L1TopoSimulation.cxx
+  TRG_MSG_WARNING("Cannot configure simulation from XML. Use JSON format");
 
+  return TCS::StatusCode::SUCCESS;
 
-   StatusCode sc = m_structure.setupFromMenu( menu );
+}
 
-   // configure layout of the simulation result
-   sc &= m_simulationResult.setupFromMenu( menu, m_structure.outputConnectors() );
 
-   return sc;
+TCS::StatusCode
+TopoSteering::setupFromConfiguration(const TrigConf::L1Menu& l1menu){
+
+
+  TCS::StatusCode sc = m_structure.setupFromMenu( l1menu );
+  
+  // configure layout of the simulation result
+  sc &= m_simulationResult.setupFromMenu( m_structure.outputConnectors() );
+
+  return sc;
+
 }
 
-StatusCode
+TCS::StatusCode
 TopoSteering::reset() {
 
    ClusterTOB::clearHeap();
@@ -74,11 +86,11 @@ TopoSteering::reset() {
 
    m_simulationResult.reset();
    
-   return StatusCode::SUCCESS;
+   return TCS::StatusCode::SUCCESS;
 }
 
 
-StatusCode
+TCS::StatusCode
 TopoSteering::initializeAlgorithms() {
    TRG_MSG_INFO("initializing algorithms");
    if( ! structure().isConfigured() ) {
@@ -101,7 +113,7 @@ TopoSteering::initializeAlgorithms() {
 }
 
 
-StatusCode
+TCS::StatusCode
 TopoSteering::setHistSvc(std::shared_ptr<IL1TopoHistSvc> histSvc) {
    TRG_MSG_INFO("setting L1TopoHistSvc ");
    m_histSvc = histSvc;
@@ -109,7 +121,7 @@ TopoSteering::setHistSvc(std::shared_ptr<IL1TopoHistSvc> histSvc) {
 }
 
 
-StatusCode
+TCS::StatusCode
 TopoSteering::saveHist() {
    if(m_histSvc) {
       m_histSvc->save();
@@ -120,7 +132,7 @@ TopoSteering::saveHist() {
 }
 
 
-StatusCode
+TCS::StatusCode
 TopoSteering::executeEvent() {
 
 
@@ -135,7 +147,7 @@ TopoSteering::executeEvent() {
    inputEvent().print();
 
    // execute all connectors
-   StatusCode sc = StatusCode::SUCCESS;
+   TCS::StatusCode sc = TCS::StatusCode::SUCCESS;
    TRG_MSG_INFO("Going to execute " << m_structure.outputConnectors().size() << " connectors");
    for(auto outConn: m_structure.outputConnectors()) {
       TRG_MSG_INFO("executing trigger line " << outConn.first);
@@ -148,19 +160,19 @@ TopoSteering::executeEvent() {
    m_simulationResult.globalDecision().print();
 
    TRG_MSG_INFO("finished executing event " << m_evtCounter++);
-   return StatusCode::SUCCESS;
+   return TCS::StatusCode::SUCCESS;
 }
 
 
 
-StatusCode
+TCS::StatusCode
 TopoSteering::executeTrigger(const std::string & TrigName) {
    if( ! structure().isConfigured() )
       TCS_EXCEPTION("TopoSteering has not been configured, can't run");
    
    DecisionConnector * outConn = m_structure.outputConnector(TrigName);
 
-   StatusCode sc = executeConnector(outConn);
+   TCS::StatusCode sc = executeConnector(outConn);
 
    m_simulationResult.collectResult(outConn);
 
@@ -168,18 +180,22 @@ TopoSteering::executeTrigger(const std::string & TrigName) {
 }
 
 
-StatusCode
+
+
+
+
+TCS::StatusCode
 TopoSteering::executeConnector(TCS::Connector *conn) {
 
    if (conn == NULL) {
-     return StatusCode::FAILURE;
+     return TCS::StatusCode::FAILURE;
    }
 
    // caching
    if(conn->isExecuted())
       return conn->executionStatusCode();
   
-   StatusCode sc(StatusCode::SUCCESS);
+   TCS::StatusCode sc(TCS::StatusCode::SUCCESS);
 
    if(conn->isInputConnector()) {
       //TRG_MSG_DEBUG("  ... executing input connector '" << conn->name() << "'");
@@ -200,14 +216,14 @@ TopoSteering::executeConnector(TCS::Connector *conn) {
 
 
 
-StatusCode
+TCS::StatusCode
 TopoSteering::executeInputConnector(TCS::InputConnector *conn) {
 
    if (conn == NULL) {
-     return StatusCode::FAILURE;
+     return TCS::StatusCode::FAILURE;
    }
 
-   StatusCode sc(StatusCode::SUCCESS);
+   TCS::StatusCode sc(TCS::StatusCode::SUCCESS);
 
    // attaching data from inputEvent to input connector, depending on the configured input type
 
@@ -223,14 +239,14 @@ TopoSteering::executeInputConnector(TCS::InputConnector *conn) {
 
 
 
-StatusCode
+TCS::StatusCode
 TopoSteering::executeSortingConnector(TCS::SortingConnector *conn) {
 
    if (conn == NULL) {
      return StatusCode::FAILURE;
    }
 
-   StatusCode sc = StatusCode::SUCCESS;
+   TCS::StatusCode sc = TCS::StatusCode::SUCCESS;
   
    // execute all the prior connectors
    for( TCS::Connector* inputConn: conn->inputConnectors() ){
@@ -253,14 +269,14 @@ TopoSteering::executeSortingConnector(TCS::SortingConnector *conn) {
 
 
 
-StatusCode
+TCS::StatusCode
 TopoSteering::executeDecisionConnector(TCS::DecisionConnector *conn) {
 
    if (conn == NULL) {
-     return StatusCode::FAILURE;
+     return TCS::StatusCode::FAILURE;
    }
 
-   StatusCode sc = StatusCode::SUCCESS;
+   TCS::StatusCode sc = TCS::StatusCode::SUCCESS;
   
    // execute all the prior connectors
    for( TCS::Connector* inputConn: conn->inputConnectors() ){
@@ -305,7 +321,7 @@ TopoSteering::executeDecisionConnector(TCS::DecisionConnector *conn) {
 
 
 
-StatusCode
+TCS::StatusCode
 TopoSteering::executeSortingAlgorithm(TCS::SortingAlg *alg,
                                       TCS::InputConnector* inputConnector,
                                       TCS::TOBArray * & sortedOutput) {
@@ -318,12 +334,12 @@ TopoSteering::executeSortingAlgorithm(TCS::SortingAlg *alg,
    if(m_useBitwise) alg->sortBitCorrect(*input, *sortedOutput);
    else alg->sort(*input, *sortedOutput);
 
-   return StatusCode::SUCCESS;
+   return TCS::StatusCode::SUCCESS;
 }
 
 
 
-StatusCode
+TCS::StatusCode
 TopoSteering::executeDecisionAlgorithm(TCS::DecisionAlg *alg,
                                        const std::vector<Connector*> & inputConnectors,
                                        const std::vector<TCS::TOBArray *> & output,
@@ -357,10 +373,11 @@ TopoSteering::executeDecisionAlgorithm(TCS::DecisionAlg *alg,
    else alg->process( input, output, decision );
    //TRG_MSG_ALWAYS("[XS1234sz]L1Topo Steering alg " << alg->name() << " has decision " << decision.decision());
      
-   return StatusCode::SUCCESS;
+   return TCS::StatusCode::SUCCESS;
 }
 
 
+
 void
 TopoSteering::printDebugInfo() {
    TRG_MSG_INFO("Number of ClusterTOB  : " << ClusterTOB::heap().size());
@@ -422,8 +439,8 @@ void TopoSteering::propagateHardwareBitsToAlgos()
        TCS::DecisionConnector *outCon = connector.second;
         outCon->decisionAlgorithm()->resetHardwareBits();
         unsigned int pos = 0; // for multi-output algorithms pos is the output index
-        for(const TXC::TriggerLine &trigger : outCon->triggers()){
-            unsigned int bitNumber = trigger.counter();
+        for(const TrigConf::TriggerLine &trigger : outCon->triggers()){
+	    unsigned int bitNumber = trigger.startbit() + 32*trigger.fpga() + 16*clock();
             outCon->decisionAlgorithm()->setHardwareBits(pos,
                                                          m_triggerHdwBits[bitNumber],
                                                          m_ovrflowHdwBits[bitNumber]);
diff --git a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/TopoSteeringStructure.cxx b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/TopoSteeringStructure.cxx
index e7b1fd48d0e..e0623628224 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/TopoSteeringStructure.cxx
+++ b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/Root/TopoSteeringStructure.cxx
@@ -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
 */
 #include "L1TopoCoreSim/TopoSteeringStructure.h"
 
@@ -20,6 +20,8 @@
 
 #include "L1TopoHardware/L1TopoHardware.h"
 
+#include "TrigConfData/L1Menu.h"
+
 #include <set>
 #include <iomanip>
 #include <boost/lexical_cast.hpp>
@@ -72,11 +74,11 @@ TopoSteeringStructure::~TopoSteeringStructure() {
 }
 
 
-StatusCode
+TCS::StatusCode
 TopoSteeringStructure::reset() {
    for(Connector* conn: m_connectors)
       conn->reset();
-   return StatusCode::SUCCESS;
+   return TCS::StatusCode::SUCCESS;
 }
 
 
@@ -117,189 +119,319 @@ TCS::TopoSteeringStructure::printParameters(std::ostream & o) const {
 }
 
 
-
-
 TCS::StatusCode
-TCS::TopoSteeringStructure::setupFromMenu(const TXC::L1TopoMenu& menu, bool debug) {
+TCS::TopoSteeringStructure::setupFromMenu(const TrigConf::L1Menu& l1menu, bool debug, bool legacy) {
 
    if(debug)
       cout << "/***************************************************************************/" << endl
            << "           L1Topo steering structure: configuring from L1 Topo Menu          " << endl
            << "/***************************************************************************/" << endl;
 
-   set<TCS::inputTOBType_t> neededInputs;
-   if(debug)
-      cout << "... building sorting connectors" << endl;
-
-   for( const TXC::L1TopoConfigAlg & configalgo: menu.getL1TopoConfigAlgs() ) {   
-
-      if(!configalgo.isSortAlg()) continue;
-      
-      // Input
-      for(string & algoInput : configalgo.getInputNames()) {
-         TCS::inputTOBType_t en = inputType(algoInput);
-         neededInputs.insert(en);
-      }
-
-      // create connector
-      SortingConnector * conn = new SortingConnector(configalgo.getInputNames()[0], configalgo.fullname(), configalgo.output());
-      if(debug)
-         cout << "Adding sorting connector " << "[" << *conn << "]" << endl;
-      addSortingConnector( conn );
-   }
-
-
+   //   set<TCS::inputTOBType_t> neededInputs; // Stores inputs for DecisionConnectors
+   vector<string> storedConn; // Stores decision connectors in order to avoid double counting
+   vector<vector<string>> confAlgorithms; // Stores algorithm name/category that have been configured in L1Menu to be used for setting the parameters
+   // Loop over boards in L1Menu and skip the ones that are not TOPO. Use Run-2 boards if legacy flag is on
+   for (const string & boardName : l1menu.boardNames() ){
+     
+     auto & l1board = l1menu.board(boardName);
+
+     if (l1board.type() != "TOPO") continue;
+     if (l1board.legacy() != legacy) continue;
+
+     // Access the connectors in the boards
+
+     for (const string & connName : l1board.connectorNames() ){
+
+       auto & l1conn = l1menu.connector(connName);
+
+       // All topo decision algorithms are configured in boards with electrical connection to CTP - Add optical connectors when adding multiplicity algorithms
+       // Look at all Topo algorithms in each connector, and get inputs from each algorithm to configure SortingConnectors
+       if ( ! (l1conn.connectorType() == TrigConf::L1Connector::ConnectorType::ELECTRICAL ) ) continue;
+
+       for( size_t fpga : { 0, 1} ) {
+	 for( size_t clock : { 0, 1} ) {
+	   for( auto & tl : l1conn.triggerLines(fpga, clock) ) {
+	     
+	     const string & tlName = tl.name();
+	     auto & algo = l1menu.algorithmFromTriggerline(tlName);
+
+	     // One algorithm can have multiple trigger lines. Check the connector/algorithm has not been stored already
+	     auto it = find(storedConn.begin(), storedConn.end(), algo.name());
+	     if (it == storedConn.end()) { // Algorithm/Connector does not exist: create and store it
+
+	       storedConn.push_back(algo.name());
+	       vector<string> inputNames;
+	       for( auto & input : algo.inputs() ) {
+		 if( sortingConnector(input) == 0 ) { // if connector does not exist, create it
+		   if(debug) 
+		     cout << "L1TopoSteering: Decision algo( " << algo.name() << " ) input is not defined: " << input << ". Creating sortingConnector" << endl;
+		   
+		   auto & sortAlgo = l1menu.algorithm(input, algo.category());
+		   if(!(sortAlgo.type() == TrigConf::L1TopoAlgorithm::AlgorithmType::SORTING ) )
+		     TCS_EXCEPTION("L1TopoSteering: Decision algo " << algo.name() << ") has as input " << input << " which is not associated to a sorting algorithm");
+
+		   //		   TCS::inputTOBType_t en = inputType(sortAlgo.inputs().at(0));
+		   //		   neededInputs.insert(en);
+
+		   // Create connector
+		   SortingConnector * sortConn = new SortingConnector(sortAlgo.inputs().at(0), sortAlgo.klass()+"/"+input, sortAlgo.outputs().at(0));
+		   if(debug)
+		     cout << "Adding sorting connector " << "[" << *sortConn << "]" << endl;
+		   addSortingConnector( sortConn );
+		   confAlgorithms.push_back({sortAlgo.name(), sortAlgo.category()});
+
+		 } // if connector does not exist
+		 
+		 inputNames.push_back(input);
+
+	       } // loop over inputs
+
+	       DecisionConnector * conn = new DecisionConnector(algo.name(), inputNames, algo.klass()+"/"+algo.name(), algo.outputs());
+	       conn->m_decision.setNBits( algo.outputs().size() );
+
+	       if(tl.name() != "UNDEF")
+		 conn->m_triggers.push_back(tl);
+
+	       if(debug)
+		 cout << "Adding decision connector " << "[" << *conn << "]" << endl;
+	       addDecisionConnector( conn );
+	       confAlgorithms.push_back({algo.name(), algo.category()});
+
+	     } else { // Connector already exists: look for it and add the trigger line
+	       for(auto out : algo.outputs()){
+		 auto c = m_outputLookup.find(out);
+		 if (c != m_outputLookup.end()){
+		   auto conn = c->second;
+		   if(tl.name() != "UNDEF")
+		     conn->m_triggers.push_back(tl);
+		   break;
+		 }
+	       }
+	     }
+
+	   } // Trigger Line
+
+	 } // Clock
+
+       } // FPGA
+       
+     } // Connector in l1board
 
+   } // Board in l1menu
 
+   /*
    if(debug)
-      cout << "... building output connectors" << endl;
-   for( const TXC::L1TopoConfigAlg & configalgo: menu.getL1TopoConfigAlgs() ) {     
+     cout << "... building sorting connectors" << endl;
 
-      if(!configalgo.isDecAlg()) continue;
+   std::string categories[] = { "TOPO" };
 
-      for( const TXC::InputElement & input : configalgo.getInputs() ) {
-         if( sortingConnector(input.value) == 0 ) {
-            TCS_EXCEPTION("L1TopoSteering: Decision algo ( " << configalgo.fullname() << " ) input is not defined: " << input.value);
-         }
-      }
-
-      DecisionConnector * conn = new DecisionConnector(configalgo.name(), configalgo.getInputNames(), configalgo.fullname(), configalgo.getOutputNames());
-      conn->m_decision.setNBits( configalgo.getOutputs().size() );
-
-      for(const std::string & output: conn->outputNames()) {
-         const TXC::TriggerLine & trigger = menu.getL1TopoConfigOutputList().getTrigger(output);
-         if(trigger.name()!="UNDEF")
-            conn->m_triggers.push_back(trigger);
-      }
-      if(debug)
-         cout << "Adding decision connector " << "[" << *conn << "]" << endl;
-      addDecisionConnector( conn );
+   for( auto & category : categories ){
+   
+     for( auto & name : l1menu.topoAlgorithmNames(category)) {
+       
+       auto & algo = l1menu.algorithm(name, category);
+       
+       if(!(algo.type() == TrigConf::L1TopoAlgorithm::AlgorithmType::SORTING ) ) continue;
+       
+       TCS::inputTOBType_t en = inputType(algo.inputs().at(0));
+       neededInputs.insert(en);
+       
+       // create connector
+       SortingConnector * conn = new SortingConnector(algo.inputs().at(0), algo.klass()+"/"+name, algo.outputs().at(0));
+       if(debug)
+	 cout << "Adding sorting connector " << "[" << *conn << "]" << endl;
+       addSortingConnector( conn );
+     }
 
    }
+     
 
+   
+   if(debug)
+     cout << "... building output connectors" << endl;
+
+   // All topo decision algorithms are configured in boards with electrical connection to CTP
+   // Create all DecisionConnectors from L1Connectors of type ELECTRICAL
+   std::vector<std::string> storedConn;
+   for ( const string & connName : l1menu.connectorNames() ){
+
+     auto & l1conn = l1menu.connector(connName);
+
+     if ( ! (l1conn.type() == TrigConf::L1Connector::ConnectorType::ELECTRICAL ) ) continue;
+     if ( l1conn.isLegacy() ) continue;
+
+     for( size_t fpga : { 0 ,1 } ) {
+       for( size_t clock : { 0 ,1 } ) {
+	 for( auto & tl : l1conn.triggerLines(fpga, clock) ) {
+	   
+	   const string & tlName = tl.name();
+	   auto & algo = l1menu.algorithmFromTriggerline(tlName);
+	   
+	   // One algorithm can have multiple trigger lines. Check the connector/algorithm has not been stored already
+	   auto it = std::find(storedConn.begin(), storedConn.end(), algo.name());
+	   if (it == storedConn.end()) { // Algorithm/Connector do not exist: create and store it
+
+	     storedConn.push_back(algo.name());
+
+	     std::vector<std::string> inputNames;
+	     for( auto & input : algo.inputs() ) {
+	       if( sortingConnector(input) == 0 ) {
+		 TCS_EXCEPTION("L1TopoSteering: Decision algo ( " << algo.name() << " ) input is not defined: " << input);
+	       }
+	       inputNames.push_back(input);
+	     }
+
+	     DecisionConnector * conn = new DecisionConnector(algo.name(), inputNames, algo.klass()+"/"+algo.name(), algo.outputs());
+	     conn->m_decision.setNBits( algo.outputs().size() );
+	   
+	     if(tl.name() != "UNDEF")
+	       conn->m_triggers.push_back(tl);
+
+	     if(debug)
+	       cout << "Adding decision connector " << "[" << *conn << "]" << endl;
+	     addDecisionConnector( conn );
+
+	   } else { // Connector already exists: look for it and add the trigger line
+	     for(auto out : algo.outputs()){
+	       auto c = m_outputLookup.find(out);
+	       if (c != m_outputLookup.end()){
+		 auto conn = c->second;
+		 if(tl.name() != "UNDEF")
+		   conn->m_triggers.push_back(tl);
+		 break;
+	       }
+	     }
+	   }
+	 } // Trigger Line
+       } // Clock
+     } // FPGA
+   } // L1Connectors
+
+   */
 
    if(debug)
-      cout << "... building input connectors" << endl;
+     cout << "... building input connectors" << endl;
    for(auto sortConn : m_sortedLookup) {
-      const string & in = sortConn.second->inputNames()[0]; // name of input
-
-      if( m_inputLookup.count(in) > 0 ) continue; // InputConnector already exists
-
-      InputConnector * conn = new InputConnector(in);
-      m_connectors.push_back(conn);
-      m_inputLookup[in] = conn;
-      if(debug)
-         cout << "Adding input connector " << "[" << *conn << "]" << endl;
+     const string & in = sortConn.second->inputNames()[0]; // name of input
+     
+     if( m_inputLookup.count(in) > 0 ) continue; // InputConnector already exists
+
+     InputConnector * conn = new InputConnector(in);
+     m_connectors.push_back(conn);
+     m_inputLookup[in] = conn;
+     if(debug)
+       cout << "Adding input connector " << "[" << *conn << "]" << endl;
    }
 
-   
    // link the connector objects together
-   StatusCode sc = linkConnectors();
-   
+   TCS::StatusCode sc = linkConnectors();
+
    // instantiate the algorithms from the algorithm names in the connectors
    if(debug)
-      cout << "... instantiating algorithms" << endl;
+     cout << "... instantiating algorithms" << endl;
    sc &= instantiateAlgorithms(debug);
-   
 
-   // iterate through OutputList elements
-   if(debug) {
-      cout << "... checking output list" << endl;
-      cout << menu.getL1TopoConfigOutputList().getOutputList().size() << " output algorithms for " 
-           << menu.getL1TopoConfigOutputList().getTriggerLines().size() << " trigger lines." << endl;
-   }
-   
+
    // set algorithm parameters
    if(debug)
-      cout << "... setting algorithm parameters" << endl;
-   
-   for( const TXC::L1TopoConfigAlg & configalgo: menu.getL1TopoConfigAlgs() ) {
+     cout << "... setting algorithm parameters" << endl;
 
-      ConfigurableAlg * alg = AlgFactory::instance().algorithm(configalgo.name());
-
-      alg->setAlgoId( configalgo.algoID() );
-
-      if(debug)
-         cout << "Algorithm " << alg->name() << endl << "  (reading parameters)" << endl;
-
-      if(alg->isDecisionAlg())
-         ((DecisionAlg *) alg)->setNumberOutputBits(configalgo.getOutputs().size());
-
-      // create ParameterSpace for this algorithm
-      ParameterSpace * ps = new ParameterSpace(alg->name());
-
-      for(TXC::RegisterParameter pe: configalgo.getParameters()) {
-         
-         string   name = pe.name;
-         uint32_t val = lexical_cast<uint32_t, string>(pe.value);
-         uint32_t pos  = pe.position;
-         uint32_t sel  = pe.selection;
-         
-         if(debug)
-            cout << "  parameter " << pos << ": " << setw(20) << left << name << " value = " << setw(3) << left << val << " (selection " << sel << ")" << endl;
-         ps->addParameter( name, val, sel);
-      }
-
-
-      for(TXC::FixedParameter pe: configalgo.getFixedParameters()) {
-         
-         string   name = pe.name;
-         uint32_t val = interpretGenericParam(pe.value);
-         if(name=="NumResultBits") {
-            if(val != configalgo.getOutputs().size()) {
-               TCS_EXCEPTION("Algorithm " << name << " parameter OutputBits (" << val << ") is different from output size (" << configalgo.getOutputs().size() << ")");
-            }
-            continue; // ignore this, because it is defined through the output list
-         }
-         if(debug)
-            cout << "  fixed parameter : " << setw(20) << left << name << " value = " << setw(3) << left << val << endl;
-         ps->addParameter( name, val);
-      }
-
-
-      if(debug)
-         cout << "  (setting parameters)" << endl;
-      alg->setParameters( *ps );
-
-      if( alg->isDecisionAlg() ) {
-         if( m_parameters[alg->algoId()] != nullptr ) {
-            TCS_EXCEPTION("Decision algorithm " << alg->name() << " has algoId " << alg->algoId() << " which is already used");
-         }
-         m_parameters[alg->algoId()] = ps;
-      } else if( alg->isSortingAlg() ) {
-         if( m_parameters[alg->algoId() + LayoutConstraints::maxComponents()] != nullptr ) {
-            TCS_EXCEPTION("Sorting algorithm " << alg->name() << " has algoId " << alg->algoId() << " which is already used");
-         }
-         m_parameters[alg->algoId() + LayoutConstraints::maxComponents()] = ps;
-      } else {
-	// newed parameters unused so delete to avoid memory leak
-	delete ps;
-	ps=0;
-      }
+   for ( auto & confAlgo : confAlgorithms ) {
+     
+     auto & l1algo = l1menu.algorithm(confAlgo.at(0), confAlgo.at(1));
+       
+     ConfigurableAlg * alg = AlgFactory::instance().algorithm(l1algo.name());
+     alg->setAlgoId( l1algo.algId() );
+     
+     if(debug)
+       cout << "Algorithm " << alg->name() << " has algoId " << alg->algoId() <<  endl << " (reading parameters)" << endl;
+     
+     if(alg->isDecisionAlg())
+       ((DecisionAlg *) alg)->setNumberOutputBits(l1algo.outputs().size());
+
+     // create ParameterSpace for this algorithm
+     ParameterSpace * ps = new ParameterSpace(alg->name());
+
+     for(auto & pe : l1algo.parameters()) {
+	 
+       auto & pname = pe.name();
+       uint32_t val = pe.value();
+       uint32_t sel = pe.selection();
+
+       if(debug)
+	 cout << " parameter " << ": " << setw(20) << left << pname << " value = " << setw(3) << left << val << " (selection " << sel << ")" << endl;
+       ps->addParameter( pname, val, sel);
+	 
+     }
+       
+     for(auto & gen : l1algo.generics().getKeys()) {
+	 
+       auto pe = l1algo.generics().getObject(gen);
+       string pname = gen;
+       uint32_t val = interpretGenericParam(pe.getAttribute("value"));
+       if (pname == "NumResultBits"){
+	 if(val != l1algo.outputs().size()) {
+	   TCS_EXCEPTION("Algorithm " << pname << " parameter OutputBits (" << val << ") is different from output size (" << l1algo.outputs().size() << ")");
+	 }
+	 continue; // ignore this, because it is defined through the output list
+       }
+       if(debug)
+	 cout << " fixed parameter : " << setw(20) << left << pname << " value = " << setw(3) << left << val << endl;
+       ps->addParameter( pname, val );
+	 
+     }
+       
+       
+     if(debug)
+       cout << " (setting parameters)";
+     alg->setParameters( *ps );
+       
+     if(debug)
+       cout << " --> (parameters set)";
+       
+     if( alg->isDecisionAlg() ) {
+       if( m_parameters[alg->algoId()] != nullptr ) {
+	 //	   TCS_EXCEPTION("Decision algorithm " << alg->name() << " has algoId " << alg->algoId() << " which is already used");
+       }
+       m_parameters[alg->algoId()] = ps;
+     } else if (alg->isSortingAlg() ) {
+       if( m_parameters[alg->algoId() + LayoutConstraints::maxComponents()] != nullptr ) {
+	 //	   TCS_EXCEPTION("Sorting algorithm " << alg->name() << " has algoId " << alg->algoId() << " which is already used");
+       }
+       m_parameters[alg->algoId() + LayoutConstraints::maxComponents()] = ps;
+     } else {
+       // newed parameters usued so delete to avoid memory leak
+       delete ps;
+       ps=0;
+     }
+
+     if(debug)
+       cout << " --> (parameters stored)" << endl;
    }
-
+   
    m_isConfigured = true;
-
+   
    if(debug)
-      cout << "... L1TopoSteering successfully configured" << endl;
+     cout << "... L1TopoSteering successfully configured" << endl;
    
    return sc;
 }
 
+
 TCS::StatusCode
 TopoSteeringStructure::addSortingConnector(SortingConnector * conn) {
    m_connectors.push_back(conn);
    for( const string & output : conn->outputNames() )
       m_sortedLookup[output] = conn;
-   return StatusCode::SUCCESS;
+   return TCS::StatusCode::SUCCESS;
 }
 
 TCS::StatusCode
 TopoSteeringStructure::addDecisionConnector(DecisionConnector * conn) {
-   m_connectors.push_back(conn);
+   m_connectors.push_back(conn); 
    for( const string & output : conn->outputNames() )
-      m_outputLookup[output] = conn;
-   return StatusCode::SUCCESS;
+     m_outputLookup[output] = conn;     
+   return TCS::StatusCode::SUCCESS;
 }
 
 
@@ -310,7 +442,7 @@ TopoSteeringStructure::linkConnectors() {
       for(const std::string & inconn: conn->inputNames())
          conn->inputConnectors().push_back( connector(inconn) );
 
-   return StatusCode::SUCCESS;
+   return TCS::StatusCode::SUCCESS;
 }
 
 
@@ -340,7 +472,7 @@ TCS::TopoSteeringStructure::instantiateAlgorithms(bool debug) {
       }
       conn->setAlgorithm(algInstance);
    }
-   return StatusCode::SUCCESS;
+   return TCS::StatusCode::SUCCESS;
 }
 
 
@@ -366,9 +498,7 @@ TopoSteeringStructure::sortingConnector(const std::string & connectorName) const
          }
       }
    }
-   if(sc==nullptr) {
-      TCS_EXCEPTION("TopoSteeringStructure: can not find SortingConnector of name " << connectorName << ". Need to abort!");
-   }
+   
    return sc;
 }
 
diff --git a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/src/test/TopoStandAlone.cxx b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/src/test/TopoStandAlone.cxx
index 64eb5b92b03..bb8081cf368 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/src/test/TopoStandAlone.cxx
+++ b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/src/test/TopoStandAlone.cxx
@@ -7,6 +7,8 @@
 #include <stdint.h>
 
 #include "TrigConfBase/TrigConfMessaging.h"
+#include "TrigConfIO/JsonFileLoader.h"
+#include "TrigConfData/L1Menu.h"
 
 #include "L1TopoConfig/L1TopoXMLParser.h"
 #include "L1TopoCoreSim/TopoSteering.h"
@@ -27,7 +29,7 @@ using namespace std;
 
 int printHelp(const char * exeName) {
    cout << "Please specify menu and data file and optionally the message levels for the framework and the algorithms:" << endl << endl;
-   cout << exeName << " <menu.xml> <data.txt> [INFO|DEBUG|WARNING] [INFO|DEBUG|WARNING] [filename.root] [optional arguments]" << endl << endl;
+   cout << exeName << " <menu.json> <data.txt> [INFO|DEBUG|WARNING] [INFO|DEBUG|WARNING] [filename.root] [optional arguments]" << endl << endl;
    cout << "optional arguments:" << endl
         << "   -o|--outfile <filename.root>" << endl
         << "   -n|--nevt <#events>" << endl
@@ -97,15 +99,14 @@ int run(int argc, const char* argv[]) {
    msg.setLevel( msgLvl );
 
    // read the menu
-   TXC::L1TopoXMLParser XMLParser;
-   XMLParser.msg().setLevel( msgLvl );
-   XMLParser.readConfiguration(argv[1]);
-   XMLParser.parseConfiguration();
-
-   //XMLParser.menu().print();
+   TrigConf::L1Menu l1menu;
+   TrigConf::JsonFileLoader fileLoader;
+fileLoader.loadFile(argv[1], l1menu);
 
 
    //TFile *f = new TFile(argc>=4 ? argv[3] : "L1TopoSimulation.root","RECREATE");
+
+   /* Change once the final number of bits per module is fixed
    TH1* h[3];
    h[0] = new TH1F("Decision/DecisionModule1", "L1 Topo Decision (Module 1)", 64, 0, 64);
    h[1] = new TH1F("Decision/DecisionModule2", "L1 Topo Decision (Module 2)", 64, 0, 64);
@@ -117,21 +118,21 @@ int run(int argc, const char* argv[]) {
    }
    for(uint i=0; i<3; ++i)
       h[i]->SetLabelSize(0.025);
-
+   */
 
    // instantiate steering
    TCS::TopoSteering steering;
    steering.setUseBitwise(false);
-   steering.setupFromConfiguration(XMLParser.takeMenu());
+   steering.setupFromConfiguration(l1menu);
 
    steering.setMsgLevel( msgLvl );
 
    steering.setAlgMsgLevel( algMsgLvl );
 
    std::shared_ptr<IL1TopoHistSvc> topoHistSvc = std::shared_ptr<IL1TopoHistSvc>( new StandaloneL1TopoHistSvc() );
-   topoHistSvc->setBaseDir("L1TopoSimulation.root:");
-   for(int i = 0; i < 3; i++ )
-      topoHistSvc->registerHist(h[i]);
+   //   topoHistSvc->setBaseDir("L1TopoSimulation.root:");
+   //   for(int i = 0; i < 3; i++ )
+   //      topoHistSvc->registerHist(h[i]);
 
    steering.setHistSvc(topoHistSvc);
 
@@ -164,14 +165,15 @@ int run(int argc, const char* argv[]) {
 
       steering.executeEvent();
 
-      const TCS::GlobalDecision & globalDec = steering.simulationResult().globalDecision();
-
+      // const TCS::GlobalDecision & globalDec = 
+      steering.simulationResult().globalDecision();
+      /*
       for(unsigned int module=0; module<3; ++module)
          for(unsigned int trigger=0; trigger<64; ++trigger)
             if( globalDec.passed(module, trigger) ) h[module]->Fill(trigger);
-
+      */
       steering.reset();
-
+     
    }
    msg << TrigConf::MSGTC::INFO << "=======================================================" << TrigConf::endmsgtc;
   
diff --git a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/src/test/TopoTestSteeringConfig.cxx b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/src/test/TopoTestSteeringConfig.cxx
index 7717d75645e..4f6a5ef5008 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoCoreSim/src/test/TopoTestSteeringConfig.cxx
+++ b/Trigger/TrigT1/L1Topo/L1TopoCoreSim/src/test/TopoTestSteeringConfig.cxx
@@ -8,36 +8,37 @@
 #include "L1TopoCoreSim/TopoSteering.h"
 #include "L1TopoConfig/L1TopoXMLParser.h"
 
+#include "TrigConfIO/JsonFileLoader.h"
+#include "TrigConfData/L1Menu.h"
+
 using namespace std;
 
 int run(int argc, const char * argv[]) {
 
    if(argc<2) {
-      cout << "Please specify topo menu input XML file:\n" << argv[0] << " -v <menu.xml>" << endl;
+      cout << "Please specify topo menu input JSON file:\n" << argv[0] << " -v <menu.json>" << endl;
       return 1;
    }
 
    bool verbose = (string(argv[1])=="-v");
 
+   TrigConf::L1Menu l1menu;
+   TrigConf::JsonFileLoader fileLoader;
 
-   TXC::L1TopoXMLParser parser;
-   parser.readConfiguration(argv[argc-1]);
    try {
-      parser.parseConfiguration();
+      fileLoader.loadFile( argv[0], l1menu);
    }
    catch(std::exception & e) {
-      cout << "TopoTestSteeringConfig: Caught exception from the topo menu parser, no topo menu will be available! Exception message: " << e.what() << endl;
+      cout << "TopoTestSteeringConfig: Caught exception from the topo menu loader, no topo menu will be available! Exception message: " << e.what() << endl;
       return 1;
    }
 
-   TXC::L1TopoMenu menu = parser.takeMenu();  // since parser goes out of scope, we take the menu
-
    if (verbose)
-      menu.print();
+      l1menu.printMenu(true);
 
    TCS::TopoSteering steering;
    try {
-      steering.setupFromConfiguration( menu );
+      steering.setupFromConfiguration(l1menu);
    } catch(exception & e) {
       cerr << "TopoTestSteeringConfig: Caught exception when configuring topo steering from menu: " << endl << e.what() << endl;
       return 1;
diff --git a/Trigger/TrigT1/L1Topo/L1TopoSimulation/CMakeLists.txt b/Trigger/TrigT1/L1Topo/L1TopoSimulation/CMakeLists.txt
index 44e9340ac2e..f6b3339bd02 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoSimulation/CMakeLists.txt
+++ b/Trigger/TrigT1/L1Topo/L1TopoSimulation/CMakeLists.txt
@@ -24,7 +24,7 @@ atlas_add_component( L1TopoSimulation
 atlas_add_component( L1TopoSimulationTest
    src/test/*.h src/test/*.cxx src/test/components/*.cxx src/AthenaL1TopoHistSvc.h src/AthenaL1TopoHistSvc.cxx
    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaBaseComps AthenaMonitoringLib GaudiKernel L1TopoConfig L1TopoCoreSim L1TopoEvent L1TopoInterfaces StoreGateLib TrigConfBase TrigConfInterfaces )
+   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaBaseComps AthenaMonitoringLib GaudiKernel L1TopoConfig L1TopoCoreSim L1TopoEvent L1TopoInterfaces StoreGateLib TrigConfBase TrigConfInterfaces TrigConfData TrigConfIO)
 
 # Install files from the package:
 atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
diff --git a/Trigger/TrigT1/L1Topo/L1TopoSimulation/python/L1TopoSimulationConfig.py b/Trigger/TrigT1/L1Topo/L1TopoSimulation/python/L1TopoSimulationConfig.py
index 8339ca2dacb..2ac3701a60a 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoSimulation/python/L1TopoSimulationConfig.py
+++ b/Trigger/TrigT1/L1Topo/L1TopoSimulation/python/L1TopoSimulationConfig.py
@@ -9,7 +9,12 @@ class L1TopoSimulation ( LVL1__L1TopoSimulation ):
 
         from L1TopoSimulation.L1TopoSimulationMonitoring import L1TopoSimulationMonitoring
         self.AthenaMonTools += [ L1TopoSimulationMonitoring() ]
-
+        enableDebugOutput = False
+        if enableDebugOutput:
+            from AthenaCommon.Constants import DEBUG
+            self.OutputLevel = DEBUG
+            self.TopoOutputLevel = DEBUG
+            self.TopoSteeringOutputLevel = DEBUG
 
 class RoiB2TopoInputDataCnv ( LVL1__RoiB2TopoInputDataCnv ):
 
diff --git a/Trigger/TrigT1/L1Topo/L1TopoSimulation/share/L1TopoSimulationTest.py b/Trigger/TrigT1/L1Topo/L1TopoSimulation/share/L1TopoSimulationTest.py
index b9a4f1ddca2..ada857a1351 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoSimulation/share/L1TopoSimulationTest.py
+++ b/Trigger/TrigT1/L1Topo/L1TopoSimulation/share/L1TopoSimulationTest.py
@@ -8,8 +8,10 @@ from AthenaCommon.Logging import logging
 log = logging.getLogger('L1TopoSimulationTest.py')
          
 fmenu ,fTOBs = 'L1Topoconfig_MC_pp_v8_NewNaming.xml','eventdump_new.txt'
+fjson = 'L1Menu_LS2_v1_22.0.17.json'
 
 print ('File for menu :',fmenu)
+print ('File for menu (json):', fjson)
 print ('File for TOBs :',fTOBs)
    
 from AthenaCommon.AppMgr import ServiceMgr as svcMgr, theApp
@@ -61,6 +63,8 @@ from L1TopoSimulation.L1TopoSimulationTestConfig import L1TopoSimulationTest
 topSequence += L1TopoSimulationTest()
 topSequence.L1TopoSimulationTest.InputASCIIFile = fTOBs
 topSequence.L1TopoSimulationTest.InputXMLFile = fmenu
+topSequence.L1TopoSimulationTest.InputJSONFile = fjson
+
 
 from GaudiSvc.GaudiSvcConf import THistSvc
 svcMgr += THistSvc()
@@ -71,15 +75,16 @@ svcMgr.THistSvc.Output += ["EXPERT DATAFILE='expert-monitoring.root' OPT='RECREA
 
 #  set algCardinality = 1 to disable cloning for all Algs
 algCardinality = nThreads
+
 #  Cloning can be disable for any alg  
 
-if (algCardinality > 1):
+if (algCardinality > 1):   
    for alg in topSequence:      
       name = alg.name()
-      if name in ["L1TopoSimulation"] :
+      if name in ["SGInputLoader"] :
          # suppress INFO message about Alg unclonability
          # set alg.Cardinality = 1 to disable cloning for specific Alg
-         alg.Cardinality = 1
+         alg.Cardinality = nThreads
       else:
          alg.Cardinality = algCardinality
 
diff --git a/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/L1TopoSimulation.cxx b/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/L1TopoSimulation.cxx
index c3578f93e54..bd46c92c83a 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/L1TopoSimulation.cxx
+++ b/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/L1TopoSimulation.cxx
@@ -3,22 +3,11 @@
 */
 
 #include "./L1TopoSimulation.h"
-#include "./AthenaL1TopoHistSvc.h"
-
-#include "TH1F.h"
 
-#include "AthenaMonitoring/IMonitorToolBase.h"
-
-#include "L1TopoCoreSim/TopoSteering.h"
 #include "L1TopoConfig/L1TopoMenu.h"
 #include "L1TopoEvent/TopoInputEvent.h"
 
-#include "L1TopoSimulation/IInputTOBConverter.h"
-#include "TrigConfInterfaces/IL1TopoConfigSvc.h"
-#include "GaudiKernel/ITHistSvc.h"
-
 #include "L1TopoInterfaces/IL1TopoHistSvc.h"
-#include "TrigT1Interfaces/TrigT1StoreGateKeys.h"
 #include "TrigT1Interfaces/TrigT1CaloDefs.h"
 #include "TrigT1CaloEvent/EmTauROI_ClassDEF.h"
 
@@ -28,93 +17,61 @@
 #include "L1TopoRDO/L1TopoTOB.h"
 #include "L1TopoRDO/L1TopoRDOCollection.h"
 
-#include "./PeriodicScaler.h"
-
+#include "./AthenaL1TopoHistSvc.h"
 
-using namespace std;
+// using namespace std;
 using namespace LVL1;
 
-
 namespace {
    // needed for monitoring
    class TopoResultBit : public IMonitoredAlgo::IGetter {
    public:
     
       //! constructor
-      TopoResultBit(const TCS::GlobalDecision & decision, unsigned int module) :
+      TopoResultBit(const TCS::GlobalDecision & decision, std::string connName) :
          m_decision(decision),
-         m_module(module)
+         m_connName(connName)
       {}
 
       //! return size of data
-      virtual unsigned int size() const { return 64; }
+      virtual unsigned int size() const { return 64; } // Change this when implementing multiplicity algorithms (size could change for Topo1)
 
       //! indexed access to data
-      virtual double get(unsigned pos) const { return m_decision.passed(m_module, pos) ? pos : -1.; }
+      virtual double get(unsigned pos) const { return m_decision.passed(m_connName, pos) ? pos : -1.; }
 
    private:
       const TCS::GlobalDecision & m_decision;
-      unsigned int m_module;
+      std::string m_connName;
    };
 }
 
 
-
 L1TopoSimulation::L1TopoSimulation(const std::string &name, ISvcLocator *pSvcLocator) :
    AthAlgorithm(name, pSvcLocator),
-   m_l1topoConfigSvc("TrigConf::TrigConfigSvc/TrigConfigSvc", name),
-   m_histSvc( "THistSvc/THistSvc", name),
-   m_monitors(this),
-   m_emtauInputProvider("LVL1::EMTauInputProvider/EMTauInputProvider", this),
-   m_jetInputProvider("LVL1::JetInputProvider/JetInputProvider", this),
-   m_energyInputProvider("LVL1::EnergyInputProvider/EnergyInputProvider", this),
-   m_muonInputProvider("LVL1::MuonInputProvider/MuonInputProvider", this),
-   m_topoSteering( unique_ptr<TCS::TopoSteering>(new TCS::TopoSteering()) )
+   m_topoSteering( std::make_unique<TCS::TopoSteering>() ),
+   m_scaler( std::make_unique<LVL1::PeriodicScaler>() )
 {
-   declareProperty( "TrigConfigSvc", m_l1topoConfigSvc, "Service to provide the L1Topo menu");
-   declareProperty( "HistSvc", m_histSvc, "Histogramming service for L1Topo algorithms");
-   declareProperty( "EMTAUInputProvider", m_emtauInputProvider, "Tool to fill the EMTAU TOBs of the topo input event");
-   declareProperty( "JetInputProvider", m_jetInputProvider, "Tool to fill the Jet TOBs of the topo input event");
-   declareProperty( "EnergyInputProvider", m_energyInputProvider, "Tool to fill the energy and MET TOBs of the topo input event");
-   declareProperty( "MuonInputProvider", m_muonInputProvider, "Tool to fill the muon TOBs of the topo input event");
-   declareProperty( "AthenaMonTools", m_monitors, "List of monitoring tools to be run with this instance, if incorrect then tool is silently skipped.");
-   declareProperty( "MonHistBaseDir", m_histBaseDir = "L1TopoAlgorithms", "Base directory for monitoring histograms will be /EXPERT/<MonHistBaseDir>" );
-   declareProperty( "EnableInputDump", m_enableInputDump, "Boolean to enable writing of input data for standalone running");
-   declareProperty( "UseBitwise", m_enableBitwise, "Boolean to enable the bitwise version of software algorithms");
-   declareProperty("FillHistoBasedOnHardware", m_fillHistogramsBasedOnHardwareDecision=true,
-                   "Boolean to fill accept/reject histograms based on hdw; default based on sim");
-   declareProperty( "InputDumpFile", m_inputDumpFile, "File name for dumping input data");
-   declareProperty( "TopoCTPLocation", m_topoCTPLocation = LVL1::DEFAULT_L1TopoCTPLocation, "StoreGate key of topo decision output for CTP" );
-   declareProperty( "TopoOverflowCTPLocation", m_topoOverflowCTPLocation = LVL1::DEFAULT_L1TopoOverflowCTPLocation, "StoreGate key of topo overflow output for CTP" );
-   declareProperty( "TopoOutputLevel", m_topoOutputLevel, "OutputLevel for L1Topo algorithms" );
-   declareProperty( "TopoSteeringOutputLevel", m_topoSteeringOutputLevel, "OutputLevel for L1Topo steering" );
-   declareProperty("Prescale", m_prescale = 1, "Internal prescale factor for this algorithm, implemented with a periodic scaler: so 1 means run every time, N means run every 1 in N times it is called; the other times it will exit without doing anything");
-   declareProperty("PrescaleDAQROBAccess", m_prescaleForDAQROBAccess = 4, "Prescale factor for requests for DAQ ROBs: can be used to avoid overloading ROS. Zero means disabled, 1 means always, N means sample only 1 in N events");
-
-
-   const TCS::GlobalDecision & dec = m_topoSteering->simulationResult().globalDecision();
-   declareMonitoredCustomVariable("DecisionModule1", new TopoResultBit(dec, 0));
-   declareMonitoredCustomVariable("DecisionModule2", new TopoResultBit(dec, 1));
-   declareMonitoredCustomVariable("DecisionModule3", new TopoResultBit(dec, 2));
-   m_scaler = new LVL1::PeriodicScaler();
-   
+   // const TCS::GlobalDecision & dec = m_topoSteering->simulationResult().globalDecision();
+   // declareMonitoredCustomVariable("DecisionModule1", new TopoResultBit(dec, 0));
+   // declareMonitoredCustomVariable("DecisionModule2", new TopoResultBit(dec, 1));
+   // declareMonitoredCustomVariable("DecisionModule3", new TopoResultBit(dec, 2));
 }
 
 
-LVL1::L1TopoSimulation::~L1TopoSimulation()
+L1TopoSimulation::~L1TopoSimulation()
 {}
 
 bool
-LVL1::L1TopoSimulation::isClonable() const
+L1TopoSimulation::isClonable() const
 {
    return true;
 }
 
 StatusCode
-LVL1::L1TopoSimulation::initialize() {
+L1TopoSimulation::initialize() {
    ATH_MSG_INFO("initialize");
 
-   m_topoSteering->setMsgLevel( TrigConf::MSGTC::Level(m_topoSteeringOutputLevel) );
+   m_topoSteering->setMsgLevel( TrigConf::MSGTC::Level((int)m_topoSteeringOutputLevel) );
 
    ATH_MSG_DEBUG("retrieving " << m_monitors);
    CHECK( m_monitors.retrieve() );
@@ -154,26 +111,22 @@ LVL1::L1TopoSimulation::initialize() {
    ATH_MSG_DEBUG("Output trigger key property " << m_topoCTPLocation);
    ATH_MSG_DEBUG("Output overflow key property " << m_topoOverflowCTPLocation);
 
-   const TXC::L1TopoMenu* menu = m_l1topoConfigSvc->menu();
-   if(menu == nullptr) {
-      ATH_MSG_FATAL("No L1 Topo menu from " << m_l1topoConfigSvc->name());
-      return StatusCode::FAILURE;
-   }
+   const TrigConf::L1Menu * l1menu = nullptr;
+   ATH_CHECK( detStore()->retrieve(l1menu) ); 
+   ATH_MSG_INFO( "initialize(): retrieving new-style L1 trigger menu from Detector Store" );
 
    m_topoSteering->setUseBitwise(m_enableBitwise);
-   std::cout << "Calling m_topoSteering->setupFromConfiguration(*menu)" << endl;
    try {
-      m_topoSteering->setupFromConfiguration(*menu);
+      m_topoSteering->setupFromConfiguration(*l1menu);
    }
-   catch(exception & e) {
+   catch(std::exception & e) {
       ATH_MSG_FATAL("Caught exception when configuring topo steering from menu: " << e.what() );
       return StatusCode::FAILURE;
    }
 
-   m_topoSteering->setAlgMsgLevel( TrigConf::MSGTC::Level(m_topoOutputLevel) );
+   m_topoSteering->setAlgMsgLevel( TrigConf::MSGTC::Level((int)m_topoOutputLevel) );
    m_topoSteering->setOutputAlgosFillBasedOnHardware(m_fillHistogramsBasedOnHardwareDecision);
 
-
    std::shared_ptr<IL1TopoHistSvc> topoHistSvc = std::shared_ptr<IL1TopoHistSvc>( new AthenaL1TopoHistSvc(m_histSvc) );
    topoHistSvc->setBaseDir("/EXPERT/" + m_histBaseDir.value());
 
@@ -184,34 +137,33 @@ LVL1::L1TopoSimulation::initialize() {
 
 // Exectued once per offline job and for every new run online
 StatusCode
-LVL1::L1TopoSimulation::stop() {
+L1TopoSimulation::stop() {
    ATH_MSG_DEBUG("stop");
 
    // monitoring
    for (auto mt : m_monitors )
       mt->finalHists().ignore();
 
-
    return StatusCode::SUCCESS;
 }
                            
 
 // Exectued once per offline job and for every new run online
 StatusCode
-LVL1::L1TopoSimulation::start() {
+L1TopoSimulation::start() {
    ATH_MSG_DEBUG("start");
 
    m_scaler->reset();
 
-   // monitoring : book histogram
-   for (auto mt : m_monitors )
-      CHECK( mt->bookHists() );
+   // TODO monitoring : book histogram
+   //   for (auto mt : m_monitors )
+   //      CHECK( mt->bookHists() );
 
 
    try {
       m_topoSteering->initializeAlgorithms();
    }
-   catch(exception & e) {
+   catch(std::exception & e) {
       ATH_MSG_FATAL("Caught exception when initializing topo algorithms" << e.what() );
       return StatusCode::FAILURE;
    }
@@ -227,7 +179,7 @@ LVL1::L1TopoSimulation::start() {
 
 
 StatusCode
-LVL1::L1TopoSimulation::execute() {
+L1TopoSimulation::execute() {
    const EventContext& ctx = Gaudi::Hive::currentContext();
 
    if (m_prescale>1 && not m_scaler->decision(m_prescale)){
@@ -282,7 +234,7 @@ LVL1::L1TopoSimulation::execute() {
    // execute the toposteering
    m_topoSteering->executeEvent();
 
-   ATH_MSG_DEBUG("" << m_topoSteering->simulationResult().globalDecision());
+   ATH_MSG_DEBUG("Global Decision:\n" << m_topoSteering->simulationResult().globalDecision());
    
 
    /**
@@ -294,49 +246,60 @@ LVL1::L1TopoSimulation::execute() {
     *
     */
 
+   // Format for CTP still undecided
+
    const TCS::GlobalDecision & dec = m_topoSteering->simulationResult().globalDecision();
    auto topoDecision2CTP = std::make_unique< LVL1::FrontPanelCTP >();
    auto topoOverflow2CTP = std::make_unique< LVL1::FrontPanelCTP >();
-   for(unsigned int clock=0; clock<2; ++clock) {
-      topoDecision2CTP->setCableWord0( clock, 0 ); // ALFA
-      topoDecision2CTP->setCableWord1( clock, dec.decision( 0, clock) );  // TOPO 0
-      topoDecision2CTP->setCableWord2( clock, dec.decision( 1, clock) );  // TOPO 1
-      topoOverflow2CTP->setCableWord0( clock, 0 ); // ALFA
-      topoOverflow2CTP->setCableWord1( clock, dec.overflow( 0, clock) );  // TOPO 0
-      topoOverflow2CTP->setCableWord2( clock, dec.overflow( 1, clock) );  // TOPO 1
-   } 
+
+   const TrigConf::L1Menu * l1menu = nullptr;
+   ATH_CHECK( detStore()->retrieve(l1menu) );
+
+   if( m_isLegacyTopo ) {
+      // to be implemented
+   } else {
+      // set electrical connectors
+      std::string conn1 = l1menu->board("Topo2").connectorNames()[0];
+      std::string conn2 = l1menu->board("Topo3").connectorNames()[0];
+      for(unsigned int clock=0; clock<2; ++clock) {
+         topoDecision2CTP->setCableWord0( clock, 0 ); // ALFA
+         ATH_MSG_DEBUG("Word 1 " << conn1 << " clock " << clock << "  " << dec.decision_field( conn1, clock) );
+         topoDecision2CTP->setCableWord1( clock, dec.decision_field( conn1, clock) );  // TOPO 0
+         ATH_MSG_DEBUG("Word 2 " << conn2 << " clock " << clock << "  " << dec.decision_field( conn2, clock) );
+         topoDecision2CTP->setCableWord2( clock, dec.decision_field( conn2, clock) );  // TOPO 1
+         // topoOverflow2CTP->setCableWord0( clock, 0 ); // ALFA
+         // topoOverflow2CTP->setCableWord1( clock, dec.overflow( 0, clock) );  // TOPO 0
+         // topoOverflow2CTP->setCableWord2( clock, dec.overflow( 1, clock) );  // TOPO 1
+      }    
+   }
+
    
    CHECK(SG::makeHandle(m_topoCTPLocation)        .record(std::move(topoDecision2CTP)));
    CHECK(SG::makeHandle(m_topoOverflowCTPLocation).record(std::move(topoOverflow2CTP)));
-   
+
 
    // TODO: get the output combination data and put into SG
 
    // fill histograms
    // Commenting out temporarily to avoid crash 
-   //when L1TopoSimulation run without menu confifuration.
-   //for (auto mt : m_monitors )
-   //   if ( ! mt->preSelector() ) 
-   //      mt->fillHists().ignore();
+   // when L1TopoSimulation run without menu confifuration. 
+   //   for (auto mt : m_monitors )
+   //      if ( ! mt->preSelector() ) 
+   //         mt->fillHists().ignore();
 
    return StatusCode::SUCCESS;
 }
 
 
-
-
 StatusCode
-LVL1::L1TopoSimulation::finalize() {
+L1TopoSimulation::finalize() {
    m_topoSteering->inputEvent().dumpFinish();
-
-   delete m_scaler;
-   m_scaler=0;
-
    return StatusCode::SUCCESS;
 }
 
+
 StatusCode
-LVL1::L1TopoSimulation::retrieveHardwareDecision()
+L1TopoSimulation::retrieveHardwareDecision()
 {
     // some duplication with L1TopoRDO::Helpers
     // getDecisionAndOverflowBits() ?
diff --git a/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/L1TopoSimulation.h b/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/L1TopoSimulation.h
index c49166093cb..909c66cf4c2 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/L1TopoSimulation.h
+++ b/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/L1TopoSimulation.h
@@ -5,41 +5,32 @@
 #ifndef L1Topo_L1TopoSimulation
 #define L1Topo_L1TopoSimulation
 
-#include "TrigConfBase/MsgStream.h"
+#include "L1TopoCoreSim/TopoSteering.h"
 
+#include "L1TopoSimulation/IInputTOBConverter.h"
 
-#include "AthenaBaseComps/AthAlgorithm.h"
+#include "PeriodicScaler.h"
+#include "TrigConfBase/MsgStream.h"
 #include "TrigInterfaces/IMonitoredAlgo.h"
-
-#include "GaudiKernel/ServiceHandle.h"
-#include "GaudiKernel/ToolHandle.h"
-
-#include <memory>
-
+#include "TrigConfInterfaces/IL1TopoConfigSvc.h"
+#include "TrigT1Interfaces/TrigT1StoreGateKeys.h"
+#include "TrigConfData/L1Menu.h"
 #include "TrigT1Interfaces/FrontPanelCTP.h"
 
 #include "StoreGate/ReadHandleKey.h"
 
-class TH1;
-class IMonitorToolBase;
-class ITHistSvc;
-
-namespace LVL1 {
-   class PeriodicScaler;
-}
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "AthenaMonitoring/IMonitorToolBase.h"
 
-namespace TCS {
-   class TopoSteering;
-}
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ITHistSvc.h"
 
-namespace TrigConf {
-   class IL1TopoConfigSvc;
-}
+#include "TH1F.h"
+#include <memory>
 
 namespace LVL1 {
 
-   class IInputTOBConverter;
-
    class L1TopoSimulation : public AthAlgorithm, public IMonitoredAlgo {
    public:
       L1TopoSimulation(const std::string &name, ISvcLocator *pSvcLocator);
@@ -68,41 +59,37 @@ namespace LVL1 {
 
    private:
 
-      //! \brief Alg handles to tools and services
-      //! @{
-      ServiceHandle<TrigConf::IL1TopoConfigSvc> m_l1topoConfigSvc;
-
-      ServiceHandle<ITHistSvc> m_histSvc;
-
-      ToolHandleArray < IMonitorToolBase > m_monitors;
-
-      ToolHandle<IInputTOBConverter> m_emtauInputProvider;
-
-      ToolHandle<IInputTOBConverter> m_jetInputProvider;
-
-      ToolHandle<IInputTOBConverter> m_energyInputProvider;
-
-      ToolHandle<IInputTOBConverter> m_muonInputProvider;
-
-      //! @}
-
-      BooleanProperty m_enableInputDump { false }; // for enabling input dumping
-      BooleanProperty m_enableBitwise { false }; // for enabling bitwise algorithms
-      StringProperty  m_inputDumpFile { "inputdump.txt" }; // input dump file
-      SG::WriteHandleKey<LVL1::FrontPanelCTP>  m_topoCTPLocation { "" }; ///< SG key of decision bits for CTP
-      SG::WriteHandleKey<LVL1::FrontPanelCTP>  m_topoOverflowCTPLocation { "" }; ///< SG key of overflow bits for CTP
-      int m_topoOutputLevel{TrigConf::MSGTC::WARNING};                                  // property to set the outputlevel of the topo algorithms
-      int m_topoSteeringOutputLevel{TrigConf::MSGTC::WARNING};                          // property to set the outputlevel of the topo steering
-
-      std::unique_ptr<TCS::TopoSteering>  m_topoSteering; //!< the topo steering 
-
-      BooleanProperty m_fillHistogramsBasedOnHardwareDecision { false }; // default: fill based on simulation
-      UnsignedIntegerProperty m_prescaleForDAQROBAccess {4}; ///< read hdw bits every N events (used only when m_fillHistogramsBasedOnHardwareDecision is true)
-      UnsignedIntegerProperty m_prescale; //! property for prescale factor
-      LVL1::PeriodicScaler* m_scaler; //! prescale decision tool
-
-      StringProperty m_histBaseDir; //! sets base dir for monitoring histograms
-  };
+      std::unique_ptr<TCS::TopoSteering>  m_topoSteering; //!< the topo steering
+      std::unique_ptr<LVL1::PeriodicScaler> m_scaler {nullptr}; //! prescale decision tool
+
+
+      // Services and input tools
+      ServiceHandle<TrigConf::IL1TopoConfigSvc> m_l1topoConfigSvc { this, "TrigConfigSvc", "TrigConf::TrigConfigSvc/TrigConfigSvc", "Service to provide the L1Topo menu" };
+      ServiceHandle<ITHistSvc> m_histSvc { this, "HistSvc", "THistSvc/THistSvc", "Histogramming service for L1Topo algorithms" };
+
+      ToolHandleArray < IMonitorToolBase > m_monitors { this, "AthenaMonTools", {}, "Monitoring tools"};
+      ToolHandle<IInputTOBConverter> m_emtauInputProvider  { this, "EMTAUInputProvider",  "LVL1::EMTauInputProvider/EMTauInputProvider",   "Tool to fill the EMTAU TOBs of the topo input event"         };
+      ToolHandle<IInputTOBConverter> m_jetInputProvider    { this, "JetInputProvider",    "LVL1::JetInputProvider/JetInputProvider",       "Tool to fill the Jet TOBs of the topo input event"           };
+      ToolHandle<IInputTOBConverter> m_energyInputProvider { this, "EnergyInputProvider", "LVL1::EnergyInputProvider/EnergyInputProvider", "Tool to fill the energy and MET TOBs of the topo input event"};
+      ToolHandle<IInputTOBConverter> m_muonInputProvider   { this, "MuonInputProvider",   "LVL1::MuonInputProvider/MuonInputProvider",     "Tool to fill the muon TOBs of the topo input event"          };
+
+      // outputs
+      SG::WriteHandleKey<LVL1::FrontPanelCTP>  m_topoCTPLocation { this, "TopoCTPLocation", LVL1::DEFAULT_L1TopoCTPLocation, "StoreGate key of topo decision output for CTP"}; ///< SG key of decision bits for CTP
+      SG::WriteHandleKey<LVL1::FrontPanelCTP>  m_topoOverflowCTPLocation { this, "TopoOverflowCTPLocation", LVL1::DEFAULT_L1TopoOverflowCTPLocation, "StoreGate key of topo overflow output for CTP"}; ///< SG key of overflow bits for CTP
+
+      Gaudi::Property<bool> m_isLegacyTopo { this, "IsLegacyTopo", false, "Simulation of Legacy L1Topo boards" };
+      Gaudi::Property<bool> m_enableInputDump { this, "EnableInputDump", false, "Enable writing of input data for standalone running" };
+      Gaudi::Property<bool> m_enableBitwise { this, "UseBitwise", false, "Boolean to enable the bitwise version of software algorithms"}; 
+      Gaudi::Property<std::string> m_inputDumpFile { this, "InputDumpFile", "inputdump.txt", "File name for dumping input data" };
+      Gaudi::Property<int> m_topoOutputLevel { this, "TopoOutputLevel", TrigConf::MSGTC::WARNING, "OutputLevel for L1Topo algorithms"};
+      Gaudi::Property<int> m_topoSteeringOutputLevel { this, "TopoSteeringOutputLevel", TrigConf::MSGTC::WARNING, "OutputLevel for L1Topo steering"};
+
+      // Properties for hardware monitoring
+      Gaudi::Property<bool> m_fillHistogramsBasedOnHardwareDecision { this, "FillHistoBasedOnHardware", true, "Fill accept/reject histograms based on hdw; default based on sim" };
+      Gaudi::Property<unsigned int> m_prescaleForDAQROBAccess { this, "PrescaleDAQROBAccess", 4, "Prescale factor for requests for DAQ ROBs: can be used to avoid overloading ROS. Zero means disabled, 1 means always, N means sample only 1 in N events"}; 
+      Gaudi::Property<unsigned int> m_prescale { this, "Prescale", 1, "Internal prescale factor for this algorithm, implemented with a periodic scaler: so 1 means run every time, N means run every 1 in N times it is called; the other times it will exit without doing anything"};
+      Gaudi::Property<std::string> m_histBaseDir { this, "MonHistBaseDir", "L1/L1TopoAlgorithms", "Base directory for monitoring histograms will be /EXPERT/<MonHistBaseDir>"}; 
+   };
 
 }
 #endif
diff --git a/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/test/L1TopoSimulationTest.cxx b/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/test/L1TopoSimulationTest.cxx
index e801348c30e..b3aa08ef47f 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/test/L1TopoSimulationTest.cxx
+++ b/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/test/L1TopoSimulationTest.cxx
@@ -13,6 +13,11 @@
 
 #include "GaudiKernel/ITHistSvc.h"
 
+// Dependencies for new menu format
+#include "TrigConfIO/JsonFileLoader.h"
+#include "TrigConfData/L1Menu.h"
+#include "TrigConfData/L1Threshold.h"
+#include "TrigConfData/L1Connector.h"
 
 using namespace std;
 
@@ -23,6 +28,7 @@ LVL1::L1TopoSimulationTest::L1TopoSimulationTest(const std::string &name, ISvcLo
    m_OfftopoSteering( unique_ptr<TCS::TopoSteering>(new TCS::TopoSteering()) )
 {
    declareProperty( "InputXMLFile", m_OffinputXMLFile, "File name for menu XML");
+   declareProperty( "InputJSONFile", m_OffinputJSONFile, "File name for menu JSON");
    declareProperty( "InputASCIIFile", m_OffinputASCIIFile, "File name for ASCII TOB vector");
    declareProperty( "HistSvc", m_OffhistSvc, "Histogramming service for L1Topo algorithms");
    declareProperty( "MonHistBaseDir", m_OffhistBaseDir = "L1TopoAlgorithms", "Base directory for monitoring histograms will be /EXPERT/<MonHistBaseDir>" );
@@ -43,22 +49,27 @@ LVL1::L1TopoSimulationTest::isClonable() const
 
 StatusCode
 LVL1::L1TopoSimulationTest::initialize() {
-   m_OfftopoSteering->setMsgLevel( TrigConf::MSGTC::Level(m_OfftopoSteeringOutputLevel) );
 
-   if (m_OffinputXMLFile.empty()){
-      ATH_MSG_FATAL("No L1 Topo menu from XML " << m_OffinputXMLFile);
-      return StatusCode::FAILURE;
-   }
-   TXC::L1TopoXMLParser XMLParser;
-   XMLParser.msg().setLevel( TrigConf::MSGTC::Level(m_OfftopoOutputLevel) );
-   XMLParser.readConfiguration(m_OffinputXMLFile);
-   XMLParser.parseConfiguration();
+  m_OfftopoSteering->setMsgLevel( TrigConf::MSGTC::Level(m_OfftopoSteeringOutputLevel) );
+
+  ATH_MSG_INFO("initialize");
+
+  if (m_OffinputXMLFile.empty() || m_OffinputJSONFile.empty()){
+    ATH_MSG_FATAL("No L1 Topo menu from JSON " << m_OffinputJSONFile);
+    return StatusCode::FAILURE;
+  }
+
+  TrigConf::L1Menu l1menu;
+  TrigConf::JsonFileLoader fileLoader;
+  fileLoader.loadFile( m_OffinputJSONFile, l1menu);
+  m_OfftopoSteering->setupFromConfiguration(l1menu);
+    
 
-   m_OfftopoSteering->setupFromConfiguration(XMLParser.takeMenu());
-   m_OfftopoSteering->setAlgMsgLevel( TrigConf::MSGTC::Level(m_OfftopoOutputLevel) );
+  // ----------------------------------------------------
+  m_OfftopoSteering->setAlgMsgLevel( TrigConf::MSGTC::Level(m_OfftopoOutputLevel) );
 
   
-   std::shared_ptr<IL1TopoHistSvc> topoHistSvc = std::shared_ptr<IL1TopoHistSvc>( new AthenaL1TopoHistSvc(m_OffhistSvc) );
+  std::shared_ptr<IL1TopoHistSvc> topoHistSvc = std::shared_ptr<IL1TopoHistSvc>( new AthenaL1TopoHistSvc(m_OffhistSvc) );
    topoHistSvc->setBaseDir("/EXPERT/" + m_OffhistBaseDir.value());
   
    
@@ -88,15 +99,25 @@ LVL1::L1TopoSimulationTest::initialize() {
 StatusCode
 LVL1::L1TopoSimulationTest::execute() {
 
+  cout << "Reseting TopoSteering" << endl;
+
    // reset input and internal state
    m_OfftopoSteering->reset();
 
+   cout << "Getting next event from dump txt" << endl;
+
    // Obtain next events in the dump txt
    m_Offreader.getNextEvent();
 
+   cout << "Executing even in TopoSteering" << endl;
+
    // execute the toposteering
    m_OfftopoSteering->executeEvent();
 
+   // Printout the decision bits
+   cout << "Printing out decisions" << endl;
+   cout << m_OfftopoSteering->simulationResult().globalDecision();
+
    return StatusCode::SUCCESS;
 }
 
diff --git a/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/test/L1TopoSimulationTest.h b/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/test/L1TopoSimulationTest.h
index 21360f1df2f..cb84a5bfaaf 100644
--- a/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/test/L1TopoSimulationTest.h
+++ b/Trigger/TrigT1/L1Topo/L1TopoSimulation/src/test/L1TopoSimulationTest.h
@@ -43,6 +43,7 @@ namespace LVL1 {
     // make algorithm is clonable
     virtual bool isClonable() const override;
 
+
   private:
 
     TCS::TopoASCIIReader m_Offreader;
@@ -55,6 +56,7 @@ namespace LVL1 {
     StringProperty  m_OffhistBaseDir; //! sets base dir for monitoring histograms
     StringProperty  m_OffinputASCIIFile { "" }; // input dump file
     StringProperty  m_OffinputXMLFile { "" }; // XML file can be register in case of enabling the ASCII file read for validation purposes
+    StringProperty  m_OffinputJSONFile { "" }; // JSON file for menu
 
     std::unique_ptr<TCS::TopoSteering>  m_OfftopoSteering; //!< the topo steering
      
diff --git a/Trigger/TrigT1/TrigT1CTP/src/CTPSimulation.cxx b/Trigger/TrigT1/TrigT1CTP/src/CTPSimulation.cxx
index 355395511b1..23c408107df 100644
--- a/Trigger/TrigT1/TrigT1CTP/src/CTPSimulation.cxx
+++ b/Trigger/TrigT1/TrigT1CTP/src/CTPSimulation.cxx
@@ -47,7 +47,7 @@ const std::function< CLHEP::HepRandomEngine*(void) > CTPSimRanluxFactory = [](vo
 
 
 LVL1CTP::CTPSimulation::CTPSimulation( const std::string& name, ISvcLocator* pSvcLocator ) :
-   AthReentrantAlgorithm ( name, pSvcLocator ), 
+   AthReentrantAlgorithm ( name, pSvcLocator ),
    m_RNGEngines( CTPSimRanluxFactory, SG::getNSlots() ),
    m_decoder( new LVL1::CPRoIDecoder() ),
    m_jetDecoder( new LVL1::JEPRoIDecoder() )
@@ -103,14 +103,14 @@ LVL1CTP::CTPSimulation::start() {
 
    const TrigConf::L1Menu * l1menu = nullptr;
    if( m_useNewConfig ) {
-      ATH_CHECK( m_detStore->retrieve(l1menu) ); 
-      ATH_MSG_INFO( "start(): use L1 trigger menu from detector store" );
+      ATH_CHECK( detStore()->retrieve(l1menu) );
+      ATH_MSG_INFO( "start(): use new-style L1 menu (json)" );
       if(l1menu == nullptr) { // if no L1 configuration is available yet
          delayConfig = true;
       }
    } else {
-      ATH_MSG_INFO( "start(): use L1 trigger menu from L1ConfigSvc" );
-      if( (m_configSvc->ctpConfig()==nullptr) || 
+      ATH_MSG_INFO( "start(): use old-style L1 menu (xml))" );
+      if( (m_configSvc->ctpConfig()==nullptr) ||
           (m_configSvc->ctpConfig()->menu().itemVector().size() == 0) ) { // if no L1 configuration is available yet
          delayConfig = true;
       }
@@ -120,7 +120,7 @@ LVL1CTP::CTPSimulation::start() {
    if( ! delayConfig ) {
       // configure the CTP ResultBuilder
       // currently both types of configuration can be given (transition period towards Run 3)
-      std::call_once(m_onceflag, [this, l1menu]{ 
+      std::call_once(m_onceflag, [this, l1menu]{
             m_resultBuilder->setConfiguration( m_configSvc->ctpConfig(), l1menu ).ignore();
             setHistLabels().ignore();
          });
@@ -137,7 +137,7 @@ LVL1CTP::CTPSimulation::execute( const EventContext& context ) const {
    std::call_once(m_onceflag, [this]{
          const TrigConf::L1Menu * l1menu = nullptr;
          if( m_useNewConfig ) {
-            m_detStore->retrieve(l1menu).ignore(); 
+            detStore()->retrieve(l1menu).ignore();
          }
          m_resultBuilder->setConfiguration( m_configSvc->ctpConfig(), l1menu ).ignore();
          setHistLabels().ignore();
@@ -154,8 +154,6 @@ LVL1CTP::CTPSimulation::execute( const EventContext& context ) const {
    return StatusCode::SUCCESS;
 }
 
-
-
 StatusCode
 LVL1CTP::CTPSimulation::createMultiplicityHist(const std::string & type, unsigned int maxMult ) const {
 
@@ -186,7 +184,6 @@ LVL1CTP::CTPSimulation::createMultiplicityHist(const std::string & type, unsigne
    return sc;
 }
 
-
 StatusCode
 LVL1CTP::CTPSimulation::setMultiplicityHistLabels(const ConfigSource & cfgSrc, const std::string & type, TrigConf::L1DataDef::TriggerType tt ) const {
    StatusCode sc;
@@ -305,7 +302,7 @@ LVL1CTP::CTPSimulation::setHistLabels() const {
 
    const TrigConf::L1Menu * l1menu = nullptr;
    if( m_useNewConfig ) {
-      ATH_CHECK( m_detStore->retrieve(l1menu) ); 
+      ATH_CHECK( detStore()->retrieve(l1menu) );
       ATH_MSG_DEBUG("setHistLabels(). L1 menu " << l1menu->size() << " items" );
    } else {
       ATH_MSG_DEBUG("setHistLabels(). ConfigSvc with " << m_configSvc->ctpConfig()->menu().itemVector().size() << " items");
@@ -321,24 +318,21 @@ LVL1CTP::CTPSimulation::setHistLabels() const {
    ATH_CHECK ( setMultiplicityHistLabels( cfgSrc, "tau",  L1DataDef::TAU ) );
 
    // Topo
-   auto hTopo0 = *get1DHist("/input/topo/l1topo0");
-   auto hTopo1 = *get1DHist("/input/topo/l1topo1");
    if ( l1menu ) {
-      // to be implemented
-   } else {
-      for(const TIP * tip : m_configSvc->ctpConfig()->menu().tipVector() ) {
-         if ( tip->tipNumber() < 384 )
+      std::vector<std::string> connNames = l1menu->connectorNames();
+      for( const std::string connName : {"LegacyTopo0", "LegacyTopo1", "Topo1El", "Topo2El", "Topo3El"}) {
+         if( find(connNames.begin(), connNames.end(), connName) == connNames.end() ) {
             continue;
-         unsigned int tipNumber = (unsigned int) ( tip->tipNumber() - 384 );
-         switch(tipNumber / 64) {
-         case 0:
-            hTopo0->GetXaxis()->SetBinLabel(1+ tipNumber % 64, tip->thresholdName().c_str() );
-            break;
-         case 1:
-            hTopo1->GetXaxis()->SetBinLabel(1+ tipNumber % 64, tip->thresholdName().c_str() );
-            break;
-         default:
-            break;
+         }
+         auto hTopo = *get1DHist("/input/topo/" + connName);
+         for(uint fpga : {0,1}) {
+            for(uint clock : {0,1}) {
+               for(auto & tl : l1menu->connector(connName).triggerLines(fpga,clock)) {
+                  //uint flatIndex = 32*tl.fpga() + 2*tl.startbit() + tl.clock(); // activate later
+                  uint flatIndex = 32*tl.fpga() + tl.startbit() + 16*tl.clock();
+                  hTopo->GetXaxis()->SetBinLabel(flatIndex+1,tl.name().c_str());
+               }         
+            }
          }
       }
    }
@@ -385,7 +379,6 @@ LVL1CTP::CTPSimulation::setHistLabels() const {
    return StatusCode::SUCCESS;
 }
 
-
 StatusCode
 LVL1CTP::CTPSimulation::bookHists() const {
 
@@ -426,10 +419,10 @@ LVL1CTP::CTPSimulation::bookHists() const {
    ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("jJets","Number of jets (jJ)", 40, 0, 40) ));
    ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("jLJets","Number of jets (jLJ)", 40, 0, 40) ));
    ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("gJets","Number of jets (gJ)", 40, 0, 40) ));
-   ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("muons","Number of muons", 10, 0, 10) ));  
+   ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("muons","Number of muons", 10, 0, 10) ));
    ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("emcluster","Number of EM clusters", 20, 0, 20) ));
    ATH_CHECK ( hbook( "/input/counts/", std::make_unique<TH1I>("taus","Number of TAU candidates", 20, 0, 20) ));
- 
+
    // threshold multiplicities
    ATH_CHECK ( createMultiplicityHist( "muon" ) );
    ATH_CHECK ( createMultiplicityHist( "jet" ) );
@@ -443,8 +436,12 @@ LVL1CTP::CTPSimulation::bookHists() const {
    ATH_CHECK ( hbook( "/multi/all", (std::unique_ptr<TH2>)std::make_unique<TH2I>("R3Mult", "New thresholds multiplicity", 1, 0, 1, 10, 0, 10) ));
 
    // Topo
-   ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("l1topo0","L1Topo Decision Cable 0", 64, 0, 64) ));
-   ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("l1topo1","L1Topo Decision Cable 1", 64, 0, 64) ));
+   ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("LegacyTopo0","L1Topo Decision (Legacy 0)", 64, 0, 64) ));
+   ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("LegacyTopo1","L1Topo Decision (Legacy 1)", 64, 0, 64) ));
+   ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("Topo1El","L1Topo Decision (Topo 1 electrical)", 64, 0, 64) ));
+   ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("Topo2El","L1Topo Decision (Topo 2 electrical)", 64, 0, 64) ));
+   ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("Topo3El","L1Topo Decision (Topo 3 electrical)", 64, 0, 64) ));
+   ATH_CHECK( hbook( "/input/topo/", std::make_unique<TH1I>("Topo1Opt0","L1Topo Decision (Topo 1 optical 0)", 90, 0, 90) ));
 
    // item decision
    ATH_CHECK ( hbook( "/output/", std::make_unique<TH1I>("tbpById", "Items decision (tbp)", 512, 0, 512) ));
@@ -461,7 +458,6 @@ LVL1CTP::CTPSimulation::bookHists() const {
    return StatusCode::SUCCESS;
 }
 
-
 StatusCode
 LVL1CTP::CTPSimulation::fillInputHistograms(const EventContext& context) const {
 
@@ -581,24 +577,43 @@ LVL1CTP::CTPSimulation::fillInputHistograms(const EventContext& context) const {
    }
 
    // topo
+   auto legacyTopoInput = SG::makeHandle( m_iKeyLegacyTopo, context );
+   if(legacyTopoInput.isValid()) {
+      ATH_MSG_DEBUG("Retrieved input from L1Topo from StoreGate with key " << m_iKeyTopo);
+      ATH_MSG_DEBUG("L1TopoLegacy0 word 0 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << legacyTopoInput->cableWord1(0));
+      ATH_MSG_DEBUG("L1TopoLegacy0 word 1 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << legacyTopoInput->cableWord1(1));
+      ATH_MSG_DEBUG("L1TopoLegacy1 word 0 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << legacyTopoInput->cableWord2(0));
+      ATH_MSG_DEBUG("L1TopoLegacy1 word 1 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << legacyTopoInput->cableWord2(1));
+      auto h0 = *get1DHist("/input/topo/LegacyTopo0");
+      auto h1 = *get1DHist("/input/topo/LegacyTopo1");
+      for(unsigned int i=0; i<32; ++i) {
+         uint32_t mask = 0x1; mask <<= i;
+         if( (legacyTopoInput->cableWord1(0) & mask) != 0 ) h0->Fill(i); // cable 0, clock 0
+         if( (legacyTopoInput->cableWord1(1) & mask) != 0 ) h0->Fill(32 + i); // cable 0, clock 1
+         if( (legacyTopoInput->cableWord2(0) & mask) != 0 ) h1->Fill(i); // cable 1, clock 0
+         if( (legacyTopoInput->cableWord2(1) & mask) != 0 ) h1->Fill(32 + i); // cable 1, clock 1
+      }
+   }
+
    auto topoInput = SG::makeHandle( m_iKeyTopo, context );
    if(topoInput.isValid()) {
       ATH_MSG_DEBUG("Retrieved input from L1Topo from StoreGate with key " << m_iKeyTopo);
-      ATH_MSG_DEBUG("L1Topo0 word 0 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << topoInput->cableWord1(0));
-      ATH_MSG_DEBUG("L1Topo0 word 1 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << topoInput->cableWord1(1));
-      ATH_MSG_DEBUG("L1Topo1 word 0 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << topoInput->cableWord2(0));
-      ATH_MSG_DEBUG("L1Topo1 word 1 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << topoInput->cableWord2(1));
-      auto h0 = *get1DHist("/input/topo/l1topo0");
-      auto h1 = *get1DHist("/input/topo/l1topo1");
+      ATH_MSG_DEBUG("L1Topo 2 word 0 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << topoInput->cableWord1(0));
+      ATH_MSG_DEBUG("L1Topo 2 word 1 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << topoInput->cableWord1(1));
+      ATH_MSG_DEBUG("L1Topo 3 word 0 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << topoInput->cableWord2(0));
+      ATH_MSG_DEBUG("L1Topo 3 word 1 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << topoInput->cableWord2(1));
+      auto h0 = *get1DHist("/input/topo/Topo1El");
+      auto h1 = *get1DHist("/input/topo/Topo2El");
+      auto h2 = *get1DHist("/input/topo/Topo3El");
       for(unsigned int i=0; i<32; ++i) {
          uint32_t mask = 0x1; mask <<= i;
-         if( (topoInput->cableWord1(0) & mask) != 0 ) h0->Fill(i); // cable 0, clock 0
-         if( (topoInput->cableWord1(1) & mask) != 0 ) h0->Fill(32 + i); // cable 0, clock 1
-         if( (topoInput->cableWord2(0) & mask) != 0 ) h1->Fill(i); // cable 1, clock 0
-         if( (topoInput->cableWord2(1) & mask) != 0 ) h1->Fill(32 + i); // cable 1, clock 1
+         if( (topoInput->cableWord0(0) & mask) != 0 ) h0->Fill(i); // cable 0, clock 0
+         if( (topoInput->cableWord0(1) & mask) != 0 ) h0->Fill(32 + i); // cable 0, clock 1
+         if( (topoInput->cableWord1(0) & mask) != 0 ) h1->Fill(i); // cable 0, clock 0
+         if( (topoInput->cableWord1(1) & mask) != 0 ) h1->Fill(32 + i); // cable 0, clock 1
+         if( (topoInput->cableWord2(0) & mask) != 0 ) h2->Fill(i); // cable 1, clock 0
+         if( (topoInput->cableWord2(1) & mask) != 0 ) h2->Fill(32 + i); // cable 1, clock 1
       }
-   } else {
-      ATH_MSG_DEBUG("No collection " << m_iKeyTopo);
    }
 
    // bcid
@@ -619,13 +634,66 @@ LVL1CTP::CTPSimulation::extractMultiplicities(std::map<std::string, unsigned int
 
    const TrigConf::L1Menu * l1menu = nullptr;
    if( m_useNewConfig ) {
-      ATH_CHECK( m_detStore->retrieve(l1menu) );
+      ATH_CHECK( detStore()->retrieve(l1menu) );
    }
 
    thrMultiMap.clear();
 
    if( l1menu ) {
+      std::vector<std::string> connNames = l1menu->connectorNames();
+      for( const std::string connName : {"LegacyTopo0", "LegacyTopo1", "Topo1El", "Topo2El", "Topo3El"}) {
+         if( find(connNames.begin(), connNames.end(), connName) == connNames.end() ) {
+            continue;
+         }
+         uint64_t cable {0};
+         if (connName.find("Legacy")==0) { // legacy topo
+            auto topoInput = SG::makeHandle( m_iKeyLegacyTopo, context );
+            if (not topoInput.isValid()) {
+               continue;
+            }
+            if(connName == "LegacyTopo0") {
+               cable = ( (uint64_t)topoInput->cableWord1( 1 ) << 32) + topoInput->cableWord1( 0 );
+            } else if (connName == "LegacyTopo1") {
+               cable = ( (uint64_t)topoInput->cableWord2( 1 ) << 32) + topoInput->cableWord2( 0 );
+            }
+         } else { // new topo
+            auto topoInput = SG::makeHandle( m_iKeyTopo, context );
+            if (not topoInput.isValid()) {
+               continue;
+            }
+            if(connName == "Topo1El") {
+               cable = ( (uint64_t)topoInput->cableWord0( 1 ) << 32) + topoInput->cableWord0( 0 );
+            } else if(connName == "Topo2El") {
+               cable = ( (uint64_t)topoInput->cableWord1( 1 ) << 32) + topoInput->cableWord1( 0 );
+            } else if (connName == "Topo3El") {
+               cable = ( (uint64_t)topoInput->cableWord2( 1 ) << 32) + topoInput->cableWord2( 0 );
+            }
+         }
+         auto & conn = l1menu->connector(connName);
+         for(uint fpga : {0,1}) {
+            for(uint clock : {0,1}) {
+               for(auto & tl : conn.triggerLines(fpga,clock)) {
+                  //uint flatIndex = 32*tl.fpga() + 2*tl.startbit() + tl.clock(); // activate later
+                  uint flatIndex = 32*tl.fpga() + tl.startbit() + 16*tl.clock();
+                  uint pass = (cable & (uint64_t(0x1) << flatIndex)) == 0 ? 0 : 1;
+                  if(size_t pos = tl.name().find('['); pos == std::string::npos) {
+                     thrMultiMap[tl.name()] = pass;
+                     ATH_MSG_DEBUG(tl.name() << " MULT calculated mult for topo " << pass);
+                  } else {
+                     auto thrName = tl.name().substr(0,pos);
+                     int bit = std::stoi(tl.name().substr(pos+1));
+                     thrMultiMap.try_emplace(thrName, 0);
+                     thrMultiMap[thrName] += (pass << bit);
+                     ATH_MSG_DEBUG(thrName << " MULT updated mult for topo " << pass);
+                  }
+               }
+            }
+         }
+      }
       for ( auto & thr : l1menu->thresholds() ) {
+         if(thr->type() == "TOPO" or thr->type()== "R2TOPO" or thr->type() == "MULTTOPO" or thr->type() == "MUTOPO") {
+            continue; 
+         }
          // get the multiplicity for each threshold
          unsigned int multiplicity = calculateMultiplicity( *thr, l1menu, context );
          // and record in threshold--> multiplicity map (to be used for item decision)
@@ -672,7 +740,6 @@ LVL1CTP::CTPSimulation::extractMultiplicities(std::map<std::string, unsigned int
 }
 
 
-
 unsigned int
 LVL1CTP::CTPSimulation::calculateJetMultiplicity( const TrigConf::L1Threshold & confThr, const TrigConf::L1Menu * l1menu, const EventContext& context ) const {
    unsigned int multiplicity = 0;
@@ -740,7 +807,6 @@ LVL1CTP::CTPSimulation::calculateJetMultiplicity( const TrigConf::L1Threshold &
 }
 
 
-
 unsigned int
 LVL1CTP::CTPSimulation::calculateJetMultiplicity( const TrigConf::TriggerThreshold * confThr, const EventContext& context ) const {
    unsigned int multiplicity = 0;
@@ -752,7 +818,7 @@ LVL1CTP::CTPSimulation::calculateJetMultiplicity( const TrigConf::TriggerThresho
          } else if ( confThr->cableName() == "JEP2" || confThr->cableName() == "JET2" ) {
             multiplicity = CTPUtil::getMult( ctpinJet->cableWord1(), confThr->cableStart(), confThr->cableEnd() );
          }
-      } 
+      }
    } else {
       // Run-3 threshold
       const SG::ReadHandleKey< xAOD::JetRoIContainer > * rhk { nullptr };
@@ -831,11 +897,10 @@ LVL1CTP::CTPSimulation::calculateEMMultiplicity( const TrigConf::L1Threshold & c
 }
 
 
-
 unsigned int
 LVL1CTP::CTPSimulation::calculateEMMultiplicity( const TrigConf::TriggerThreshold * confThr, const EventContext& context ) const {
    unsigned int multiplicity (0);
-   if ( confThr->name()[0]=='e' ) { 
+   if ( confThr->name()[0]=='e' ) {
       // new EM threshold from eFEX
       auto eFexCluster = SG::makeHandle( m_iKeyEFexCluster, context );
       for ( const auto & cl : *eFexCluster ) {
@@ -904,7 +969,7 @@ LVL1CTP::CTPSimulation::calculateTauMultiplicity( const TrigConf::L1Threshold &
 unsigned int
 LVL1CTP::CTPSimulation::calculateTauMultiplicity( const TrigConf::TriggerThreshold * confThr, const EventContext& context ) const {
    unsigned int multiplicity = 0;
-   if ( confThr->name()[0]=='e' ) { 
+   if ( confThr->name()[0]=='e' ) {
       // new TAU threshold from eFEX
       auto eFexTaus  = SG::makeHandle( m_iKeyEFexTau, context );
       const static SG::AuxElement::ConstAccessor<float> accR3ClET ("R3ClusterET");
@@ -938,7 +1003,6 @@ LVL1CTP::CTPSimulation::calculateTauMultiplicity( const TrigConf::TriggerThresho
 }
 
 
-
 unsigned int
 LVL1CTP::CTPSimulation::calculateMETMultiplicity( const TrigConf::L1Threshold & confThr, const TrigConf::L1Menu * l1menu, const EventContext& context ) const {
    unsigned int multiplicity = 0;
@@ -987,7 +1051,6 @@ LVL1CTP::CTPSimulation::calculateMETMultiplicity( const TrigConf::L1Threshold &
 }
 
 
-
 unsigned int
 LVL1CTP::CTPSimulation::calculateMETMultiplicity( const TrigConf::TriggerThreshold * confThr, const EventContext& context ) const {
    unsigned int multiplicity = 0;
@@ -1002,7 +1065,7 @@ LVL1CTP::CTPSimulation::calculateMETMultiplicity( const TrigConf::TriggerThresho
          }
       }
    } else if ( confThr->name().find("TE")==0 ) {
-      // old TE 
+      // old TE
       auto ctpinEnergy = SG::makeHandle( m_iKeyCtpinXE, context );
       if ( ctpinEnergy.isValid() ) {
          if ( confThr->cableName() == "JEP3" || confThr->cableName() == "EN1") {
@@ -1128,10 +1191,10 @@ LVL1CTP::CTPSimulation::calculateTopoMultiplicity( const TrigConf::TriggerThresh
 unsigned int
 LVL1CTP::CTPSimulation::calculateMultiplicity( const TrigConf::TriggerThreshold * confThr, const EventContext& context ) const {
    unsigned int multiplicity = 0;
-   if( confThr->cableName() == "CTPCAL" || 
-       confThr->cableName() == "ALFA" || 
-       confThr->cableName() == "NIM1" || 
-       confThr->cableName() == "NIM2" || 
+   if( confThr->cableName() == "CTPCAL" ||
+       confThr->cableName() == "ALFA" ||
+       confThr->cableName() == "NIM1" ||
+       confThr->cableName() == "NIM2" ||
        confThr->type() == "NIM") {
       return 0;
    }
@@ -1168,8 +1231,6 @@ LVL1CTP::CTPSimulation::calculateMultiplicity( const TrigConf::L1Threshold & con
          multiplicity = calculateJetMultiplicity( confThr, l1menu, context );
       } else if ( confThr.type() == "MU" ) {
          multiplicity = calculateMuonMultiplicity( confThr, l1menu, context );
-      } else if ( confThr.type() == "TOPO" ) {
-         multiplicity = calculateTopoMultiplicity( confThr, l1menu, context );
       }
    }
    catch(std::exception & ex) {
@@ -1238,7 +1299,7 @@ LVL1CTP::CTPSimulation::finalize() {
 
    const TrigConf::L1Menu * l1menu = nullptr;
    if( m_useNewConfig ) {
-      ATH_CHECK( m_detStore->retrieve(l1menu) );
+      ATH_CHECK( detStore()->retrieve(l1menu) );
    }
 
    constexpr unsigned int sizeOfCTPOutput = 512;
@@ -1297,7 +1358,7 @@ LVL1CTP::CTPSimulation::finalize() {
       } else {
          thrHists = { "em/em", "muon/muon", "tau/tau", "jet/jet", "xe/xe", "te/te", "xs/xs" };
       }
-      auto hist = * get2DHist( "/multi/all/LegacyMult" ); 
+      auto hist = * get2DHist( "/multi/all/LegacyMult" );
       for(const std::string & histpath : thrHists) {
          auto h = * get2DHist( "/multi/" + histpath + "Mult" );
          auto xaxis = h->GetXaxis();
@@ -1319,7 +1380,7 @@ LVL1CTP::CTPSimulation::finalize() {
    {
       // run 3 thresholds
       if( l1menu ) {
-         auto hist = * get2DHist( "/multi/all/R3Mult" ); 
+         auto hist = * get2DHist( "/multi/all/R3Mult" );
          std::vector<std::string> thrHists = { "em/eEM", "muon/MU", "tau/eTAU", "jet/jJ", "jet/gJ", "xe/gXE", "xe/jXE" };
          for(const std::string & histpath : thrHists) {
             auto h = * get2DHist( "/multi/" + histpath + "Mult" );
diff --git a/Trigger/TrigT1/TrigT1CTP/src/CTPSimulation.h b/Trigger/TrigT1/TrigT1CTP/src/CTPSimulation.h
index d6efae27b3b..efb96d92223 100644
--- a/Trigger/TrigT1/TrigT1CTP/src/CTPSimulation.h
+++ b/Trigger/TrigT1/TrigT1CTP/src/CTPSimulation.h
@@ -133,7 +133,7 @@ namespace LVL1CTP {
       // Needed services and tools
       ServiceHandle<ITHistSvc> m_histSvc { this, "THistSvc", "THistSvc/THistSvc", "Histogramming svc" };
       ServiceHandle<TrigConf::ILVL1ConfigSvc> m_configSvc { this, "TrigConfigSvc", "TrigConf::TrigConfigSvc/TrigConfigSvc", "Trigger configuration service" };
-      ServiceHandle<StoreGateSvc> m_detStore { this, "DetectorStore", "StoreGateSvc/DetectorStore", "Detector store to get the menu" };
+      // ServiceHandle<StoreGateSvc> m_detStore { this, "DetectorStore", "StoreGateSvc/DetectorStore", "Detector store to get the menu" };
       ToolHandle<LVL1CTP::ResultBuilder> m_resultBuilder { this, "ResultBuilder", "LVL1CTP__ResultBuilder/ResultBuilder", "Builds the CTP result" };
 
       // random engine for calculating prescales
diff --git a/Trigger/TrigT1/TrigT1CTP/src/CTPTriggerItem.cxx b/Trigger/TrigT1/TrigT1CTP/src/CTPTriggerItem.cxx
index b3456445b6f..253c69230d2 100644
--- a/Trigger/TrigT1/TrigT1CTP/src/CTPTriggerItem.cxx
+++ b/Trigger/TrigT1/TrigT1CTP/src/CTPTriggerItem.cxx
@@ -2,12 +2,11 @@
   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
+#include "./CTPTriggerItem.h"
 #include "TrigConfData/LogicParser.h"
-
 #include "TrigConfL1Data/TriggerItem.h"
 
-#include "./CTPTriggerItem.h"
-
+#include <exception>
 
 LVL1CTP::CTPTriggerItem::CTPTriggerItem()
 {}
@@ -88,8 +87,13 @@ LVL1CTP::CTPTriggerItem::evaluate( const std::map<std::string, unsigned int> & t
       if( dec && (! m_bunchGroups.empty()) ) {
          // apply bunchgroups, if set (if not set, it is part of the logic)
          for( auto & bgName : m_bunchGroups ) {
-            if( thrDecMap.at(bgName) == 0 ) {
-               dec = false; break;
+            try {
+               if( thrDecMap.at(bgName) == 0 ) {
+                  dec = false; break;
+               }
+            }
+            catch(std::exception &) {
+               throw std::runtime_error( "Problem accessing decision for bunchgroup " + bgName);
             }
          }
       }
diff --git a/Trigger/TrigT1/TrigT1CTP/src/ResultBuilder.cxx b/Trigger/TrigT1/TrigT1CTP/src/ResultBuilder.cxx
index e277d51d912..890651d8809 100644
--- a/Trigger/TrigT1/TrigT1CTP/src/ResultBuilder.cxx
+++ b/Trigger/TrigT1/TrigT1CTP/src/ResultBuilder.cxx
@@ -118,7 +118,6 @@ StatusCode
 LVL1CTP::ResultBuilder::constructTIPVector( const std::map<std::string, unsigned int> & thrMultiMap,
                                             std::vector<uint32_t> & tip ) const
 {
-
    tip.resize( m_ctpDataFormat->getTIPwords(), 0 );
    
    for( auto & entry : thrMultiMap ) {
@@ -184,7 +183,7 @@ LVL1CTP::ResultBuilder::buildItemDecision( const std::map<std::string, unsigned
    itemDecisionMap.clear();
 
    try {
-      for( auto itemName : m_itemConfigMap->itemNames() ) {
+      for( const auto & itemName : m_itemConfigMap->itemNames() ) {
          auto ctpItem = m_itemConfigMap->getItem(itemName);
 
          bool pass_beforePrescale =  ctpItem->evaluate(thrMultiMap);
@@ -246,7 +245,7 @@ LVL1CTP::ResultBuilder::constructResultVectors( const std::map<std::string, unsi
       ATH_MSG_DEBUG( "  --> Trigger item " << itemName << 
                      " is " << ( !passBP ? "INACTIVE" : ( passAV ? "ACTIVE" : "ACTIVE (but PRESCALED)" ) ) );
    }
-   ATH_MSG_DEBUG( "REGTEST - " << "TriggerType byte is: 0x" << std::hex << std::setw( 2 ) << std::setfill( '0' ) << triggerType );
+   ATH_MSG_DEBUG( "REGTEST - " << "TriggerType byte is: 0x" << std::setw( 2 ) << std::setfill( '0' ) << std::hex << int(triggerType) );
 
    return StatusCode::SUCCESS;
 }
diff --git a/Trigger/TrigT1/TrigT1CTP/src/ThresholdMap.cxx b/Trigger/TrigT1/TrigT1CTP/src/ThresholdMap.cxx
index 4d40dadc4bc..901103b9f5c 100644
--- a/Trigger/TrigT1/TrigT1CTP/src/ThresholdMap.cxx
+++ b/Trigger/TrigT1/TrigT1CTP/src/ThresholdMap.cxx
@@ -98,6 +98,11 @@ LVL1CTP::ThresholdMap::getThresholdNames() const {
 
 const LVL1CTP::CTPTriggerThreshold &
 LVL1CTP::ThresholdMap::getCTPThreshold( const std::string & thrName ) const {
-   return * m_mapByName.at( thrName );
+   try {
+      return * m_mapByName.at( thrName );
+   }
+   catch(std::exception&) {
+      throw std::runtime_error("Threshold " + thrName + " not present in CTPSimulation's internal threshold map");
+   }
 }
 
diff --git a/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1SimulationConfig.py b/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1SimulationConfig.py
index 463e2b07dc4..614fc876588 100644
--- a/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1SimulationConfig.py
+++ b/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1SimulationConfig.py
@@ -187,22 +187,20 @@ def Lvl1SimulationSequence( flags = None ):
     ##################################################
 
     l1TopoSim = None
+    from L1TopoSimulation.L1TopoSimulationConfig import L1TopoSimulation
+    l1TopoSim = L1TopoSimulation()
+    l1TopoSim.MuonInputProvider.ROIBResultLocation = "" #disable input from RoIBResult
     if flags.Trigger.enableL1Phase1:
-        log.info("No phase1 configuration for L1Topo simulation is available")
+        l1TopoSim.MuonInputProvider.MuctpiSimTool = ToolSvc.MUCTPI_AthTool
     else:
-        from L1TopoSimulation.L1TopoSimulationConfig import L1TopoSimulation
-        l1TopoSim = L1TopoSimulation()
-
-        l1TopoSim.MuonInputProvider.ROIBResultLocation = "" #disable input from RoIBResult
         l1TopoSim.MuonInputProvider.MuctpiSimTool = ToolSvc.L1MuctpiTool
-
-        # enable the reduced (coarse) granularity topo simulation
-        # currently only for MC
-        from AthenaCommon.GlobalFlags  import globalflags
-        if globalflags.DataSource()!='data':
-            l1TopoSim.MuonInputProvider.MuonEncoding = 1
-        else:
-            l1TopoSim.MuonInputProvider.MuonEncoding = 0
+    # enable the reduced (coarse) granularity topo simulation
+    # currently only for MC
+    from AthenaCommon.GlobalFlags  import globalflags
+    if globalflags.DataSource()!='data':
+        l1TopoSim.MuonInputProvider.MuonEncoding = 1
+    else:
+        l1TopoSim.MuonInputProvider.MuonEncoding = 0
 
     ##################################################
     # CTP
@@ -213,7 +211,7 @@ def Lvl1SimulationSequence( flags = None ):
     ctp.DoLUCID     = False
     ctp.DoBCM       = False
     ctp.DoL1Topo    = not flags.Trigger.enableL1Phase1
-    ctp.UseCondL1Menu = False
+    ctp.UseNewConfig = True
     ctp.TrigConfigSvc = svcMgr.LVL1ConfigSvc
     ctpSim      = seqAND("ctpSim", [ctp])
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ItemDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ItemDef.py
index 8cb186e920f..404df6fa2ad 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ItemDef.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ItemDef.py
@@ -1654,12 +1654,8 @@ class ItemDef:
             MenuItem('L1_LFV-MU6').setLogic( d.TOPO_0DR15_2MU6ab & d.MU6.x(2) & physcond)
             MenuItem('L1_LFV-MU').setLogic( d.R2TOPO_0DR10_MU10ab_MU6ab & d.MU10 & d.MU6.x(2) & physcond)
 
-            if isV8 or isHIV5 or isPhaseII:
-                MenuItem('L1_LFV-EM8I').setLogic( d.TOPO_0DETA04_EM8abi_MU10ab & d.TOPO_0DPHI03_EM8abi_MU10ab & d.MU10 & physcond) #ATR-14282
-                MenuItem('L1_LFV-EM15I').setLogic( d.TOPO_0DETA04_EM15abi_MUab & d.TOPO_0DPHI03_EM15abi_MUab & physcond) #ATR-14282
-            else:
-                MenuItem('L1_LFV-EM8I').setLogic( d.TOPO_0DETA04_0DPHI03_EM8abi_MU10ab & physcond)
-                MenuItem('L1_LFV-EM15I').setLogic( d.TOPO_0DETA04_0DPHI03_EM15abi_MUab & physcond)
+            MenuItem('L1_LFV-EM8I').setLogic( d.TOPO_0DETA04_EM8abi_MU10ab & d.TOPO_0DPHI03_EM8abi_MU10ab & d.MU10 & physcond) #ATR-14282
+            MenuItem('L1_LFV-EM15I').setLogic( d.TOPO_0DETA04_EM15abi_MUab & d.TOPO_0DPHI03_EM15abi_MUab & physcond) #ATR-14282
                 
             MenuItem('L1_DPHI-J20s2XE50').setLogic( d.TOPO_10MINDPHI_J20s2_XE50 & physcond)
             MenuItem('L1_DPHI-J20XE50').setLogic( d.R2TOPO_10MINDPHI_J20ab_XE50 & physcond)
@@ -1708,10 +1704,7 @@ class ItemDef:
             MenuItem('L1_DR-TAU20ITAU12I').setLogic( d.TOPO_0DR28_TAU20abi_TAU12abi & physcond)
             MenuItem('L1_BOX-TAU20ITAU12I').setLogic( d.R2TOPO_0DETA20_0DPHI20_TAU20abi_TAU12abi & physcond)
 
-            if isV8:
-                MenuItem('L1_DR-TAU20ITAU12I-J25').setLogic( d.TOPO_2DISAMB_J25ab_0DR28_TAU20abi_TAU12abi & physcond)
-            else:
-                MenuItem('L1_DR-TAU20ITAU12I-J25').setLogic( d.TOPO_1DISAMB_J25ab_0DR28_TAU20abi_TAU12abi & physcond)
+            MenuItem('L1_DR-TAU20ITAU12I-J25').setLogic( d.TOPO_2DISAMB_J25ab_0DR28_TAU20abi_TAU12abi & physcond)
 
             MenuItem('L1_DR25-TAU20ITAU12I-J25').setLogic( d.R2TOPO_1DISAMB_J25ab_0DR25_TAU20abi_TAU12abi & physcond)
             MenuItem('L1_LAR-EM').setLogic( d.R2TOPO_LAR_EM20shi1 & physcond).setTriggerType( TT.lardemo ) # LAr demo (ATR-11897)
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/MenuMapping.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/MenuMapping.py
index a2a7168ed47..0b641377b92 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/MenuMapping.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/MenuMapping.py
@@ -8,6 +8,7 @@ The resolved name is also being used in the L1/Config/ItemDef.py and L1/Config/T
 """
 
 menuMap = {
+    "Physics_pp_v7" : "MC_pp_v8",
     "LS2_v1" : "MC_pp_v8",
     "Physics_pp_run3_v1" : "MC_pp_v8",
     "MC_pp_run3_v1" : "MC_pp_v8",
-- 
GitLab