diff --git a/Trigger/TrigT1/L1Topo/L1TopoSimulation/python/L1TopoSimulationConfig.py b/Trigger/TrigT1/L1Topo/L1TopoSimulation/python/L1TopoSimulationConfig.py index 7bc12799907ba95cda6046f41615bf09d2fc28e9..c9daf9272ca6ef71946f40ef9e3f963aec5a54d8 100644 --- a/Trigger/TrigT1/L1Topo/L1TopoSimulation/python/L1TopoSimulationConfig.py +++ b/Trigger/TrigT1/L1Topo/L1TopoSimulation/python/L1TopoSimulationConfig.py @@ -24,19 +24,30 @@ def L1TopoSimulationMCCfg(flags): from AthenaConfiguration.ComponentFactory import CompFactory acc = ComponentAccumulator() - #TODO - add varaint to support phase I - from TrigT1Muctpi.TrigT1MuctpiConfig import L1MuctpiToolRDOCfg - muctpiToolAcc = L1MuctpiToolRDOCfg(flags) - muctpiTool = muctpiToolAcc.getPrimary() - acc.merge(muctpiToolAcc) - + #Grab the MUCTPI tool + if flags.Trigger.enableL1Phase1: + from TrigT1MuctpiPhase1.TrigT1MuctpiPhase1Config import MUCTPI_AthToolCfg + muctpiTool = MUCTPI_AthToolCfg("MUCTPI_AthTool") + acc.addPublicTool(muctpiTool, primary=True) + else: + from TrigT1Muctpi.TrigT1MuctpiConfig import L1MuctpiToolRDOCfg + muctpiToolAcc = L1MuctpiToolRDOCfg(flags) + muctpiTool = muctpiToolAcc.getPrimary() + acc.merge(muctpiToolAcc) + + #Configure the MuonInputProvider muProvider = CompFactory.LVL1.MuonInputProvider("MuonInputProvider", ROIBResultLocation = "", #disable input from RoIBResult MuctpiSimTool = muctpiTool, MuonEncoding = 1 if flags.Input.isMC else 0, UseNewConfig = flags.Trigger.readLVL1FromJSON) - emtauProvider = CompFactory.LVL1.EMTauInputProvider("EMTauInputProvider") + #Configure the MuonRoiTools for the MIP + from TrigT1MuonRecRoiTool.TrigT1MuonRecRoiToolConfig import getRun3RPCRecRoiTool, getRun3TGCRecRoiTool + muProvider.RecRpcRoiTool = getRun3RPCRecRoiTool("RPCRecRoiTool", useRun3Config = flags.Trigger.enableL1Phase1) + muProvider.RecTgcRoiTool = getRun3TGCRecRoiTool("TGCRecRoiTool", useRun3Config = flags.Trigger.enableL1Phase1) + + emtauProvider = CompFactory.LVL1.EMTauInputProvider("EMTauInputProvider") topoSimAlg = CompFactory.LVL1.L1TopoSimulation("L1TopoSimulation", MuonInputProvider = muProvider, diff --git a/Trigger/TrigT1/TrigT1CTP/src/CTPUtil.cxx b/Trigger/TrigT1/TrigT1CTP/src/CTPUtil.cxx index 4f2f93bd06e342a2c1c7796554551a281b8e848e..37289935fa7c6442aad9ad06f8dd445446ad177d 100644 --- a/Trigger/TrigT1/TrigT1CTP/src/CTPUtil.cxx +++ b/Trigger/TrigT1/TrigT1CTP/src/CTPUtil.cxx @@ -70,7 +70,7 @@ namespace LVL1CTP { int CTPUtil::getMult( const std::vector<unsigned int>& words, unsigned int startbit, unsigned int endbit ) { std::bitset<256> bits = convertToBitset(words); std::bitset<256> mask = pow( 2, endbit - startbit + 1 ) - 1; - bits >>= startbit; + bits >>= (startbit-1); return static_cast<int>((bits&mask).to_ulong()); } @@ -94,8 +94,8 @@ namespace LVL1CTP { for (size_t i(0); i < words.size(); ++i) { std::bitset<256> bs = words[i]; - bs <<= (i * 32); - bitset |= bs; + bs <<= (i * 32); + bitset |= bs; } return bitset; diff --git a/Trigger/TrigT1/TrigT1MuctpiPhase1/TrigT1MuctpiPhase1/MuonSectorProcessor.h b/Trigger/TrigT1/TrigT1MuctpiPhase1/TrigT1MuctpiPhase1/MuonSectorProcessor.h index 1aaa6e3c47be4d4fd20c9b913fedba5d4af54fa7..ed1dcb349868028ad16120b9c7aa3b3192b1ea92 100644 --- a/Trigger/TrigT1/TrigT1MuctpiPhase1/TrigT1MuctpiPhase1/MuonSectorProcessor.h +++ b/Trigger/TrigT1/TrigT1MuctpiPhase1/TrigT1MuctpiPhase1/MuonSectorProcessor.h @@ -8,8 +8,10 @@ #define TRIGT1MUCTPIPHASE1_MUONSECTORPROCESSOR_H -#include <map> #include <string> +#include <map> +#include <unordered_map> +#include <vector> namespace LVL1MUONIF { class Lvl1MuCTPIInputPhase1; @@ -19,6 +21,10 @@ namespace LVL1 { class MuCTPIL1Topo; } +namespace TrigConf { + class L1Menu; +} + namespace LVL1MUCTPIPHASE1 { class OverlapHelper; class L1TopoLUT; @@ -30,22 +36,28 @@ namespace LVL1MUCTPIPHASE1 { MuonSectorProcessor(bool side /*1=A,0=C*/); ~MuonSectorProcessor(); - + + void setMenu(const TrigConf::L1Menu* l1menu); void setL1TopoLUT(const L1TopoLUT* l1topoLUT) {m_l1topoLUT=l1topoLUT;} void configureOverlapRemoval(const std::string& lutFile); + bool configurePtEncoding(); void setInput(LVL1MUONIF::Lvl1MuCTPIInputPhase1* input); void runOverlapRemoval(int bcid); - void makeL1TopoData(int bcid); + std::string makeL1TopoData(int bcid); LVL1::MuCTPIL1Topo* getL1TopoData(int bcid); LVL1MUONIF::Lvl1MuCTPIInputPhase1* getOutput(); private: LVL1MUONIF::Lvl1MuCTPIInputPhase1* m_muctpiInput; - std::map<int, LVL1::MuCTPIL1Topo*> m_bcid_to_l1topo; + std::unordered_map<int, LVL1::MuCTPIL1Topo*> m_bcid_to_l1topo; OverlapHelper* m_overlapHelper; + const TrigConf::L1Menu* m_l1menu; const L1TopoLUT* m_l1topoLUT; bool m_side; + + //encoding between threshold index and pt value in barrel, endcap, and forward regions + std::vector<std::map<int, int> > m_ptEncoding; }; } diff --git a/Trigger/TrigT1/TrigT1MuctpiPhase1/TrigT1MuctpiPhase1/SimController.h b/Trigger/TrigT1/TrigT1MuctpiPhase1/TrigT1MuctpiPhase1/SimController.h index b7184e592c955dd46760a6983048a812cadfa713..8c506de2cf7a381dbb71d914babf33d93ea6189c 100644 --- a/Trigger/TrigT1/TrigT1MuctpiPhase1/TrigT1MuctpiPhase1/SimController.h +++ b/Trigger/TrigT1/TrigT1MuctpiPhase1/TrigT1MuctpiPhase1/SimController.h @@ -38,14 +38,14 @@ namespace LVL1MUCTPIPHASE1 { const std::string& ecfFileName, const std::string& side0LUTFileName, const std::string& side1LUTFileName); - void configureOverlapRemoval(const std::string& lutFile); - bool processData(LVL1MUONIF::Lvl1MuCTPIInputPhase1* input, int bcid=0); + std::string processData(LVL1MUONIF::Lvl1MuCTPIInputPhase1* input, int bcid=0); void setConfiguration( const Configuration& conf ); LVL1::MuCTPIL1Topo getL1TopoData(int bcid); TriggerProcessor* getTriggerProcessor(); + std::vector<MuonSectorProcessor*>& getMuonSectorProcessors(); private: diff --git a/Trigger/TrigT1/TrigT1MuctpiPhase1/TrigT1MuctpiPhase1/TriggerProcessor.h b/Trigger/TrigT1/TrigT1MuctpiPhase1/TrigT1MuctpiPhase1/TriggerProcessor.h index 247a62f2d26d72d17a8ca989ed5034861b0ca45a..455913a8218295f8c4cb0c2ebcb4b02b55aa2884 100644 --- a/Trigger/TrigT1/TrigT1MuctpiPhase1/TrigT1MuctpiPhase1/TriggerProcessor.h +++ b/Trigger/TrigT1/TrigT1MuctpiPhase1/TrigT1MuctpiPhase1/TriggerProcessor.h @@ -48,9 +48,9 @@ namespace LVL1MUCTPIPHASE1 { void setMenu(const TrigConf::L1Menu* l1menu); void setTrigTool(LVL1::TrigThresholdDecisionTool& tool) {m_trigThresholdDecisionTool=&tool;} - bool mergeInputs(std::vector<LVL1MUONIF::Lvl1MuCTPIInputPhase1*> inputs); - bool computeMultiplicities(int bcid); - bool makeTopoSelections(); + void mergeInputs(std::vector<LVL1MUONIF::Lvl1MuCTPIInputPhase1*> inputs); + std::string computeMultiplicities(int bcid); + void makeTopoSelections(); const std::vector<unsigned int>& getCTPData() const; //subsystem - daq word pairs diff --git a/Trigger/TrigT1/TrigT1MuctpiPhase1/python/TrigT1MuctpiPhase1Config.py b/Trigger/TrigT1/TrigT1MuctpiPhase1/python/TrigT1MuctpiPhase1Config.py index 080c2ff08a1b4a94dc996deccf4a64c448b9e0e2..4cb39a94750de39bbb90b34dbbd393869e9fc099 100644 --- a/Trigger/TrigT1/TrigT1MuctpiPhase1/python/TrigT1MuctpiPhase1Config.py +++ b/Trigger/TrigT1/TrigT1MuctpiPhase1/python/TrigT1MuctpiPhase1Config.py @@ -4,8 +4,7 @@ from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator from AthenaCommon.Logging import logging #Muon RecRoiTools -from TrigT1MuonRecRoiTool.TrigT1MuonRecRoiToolConfig import getRun3RPCRecRoiTool -from TrigT1MuonRecRoiTool.TrigT1MuonRecRoiToolConfig import getRun3TGCRecRoiTool +from TrigT1MuonRecRoiTool.TrigT1MuonRecRoiToolConfig import getRun3RPCRecRoiTool, getRun3TGCRecRoiTool # Local (generated) configurable(s): from TrigT1MuctpiPhase1.TrigT1MuctpiPhase1Conf import LVL1MUCTPIPHASE1__MUCTPI_AthAlg @@ -65,6 +64,8 @@ class DefaultL1MuctpiPhase1( LVL1MUCTPIPHASE1__MUCTPI_AthAlg ): LVL1MUCTPIPHASE1__MUCTPI_AthAlg.__init__( self, name ) + self.MUCTPI_AthTool = MUCTPI_AthToolCfg("MUCTPI_AthTool") + class L1MuctpiPhase1( DefaultL1MuctpiPhase1 ): @@ -77,7 +78,6 @@ class L1MuctpiPhase1( DefaultL1MuctpiPhase1 ): DefaultL1MuctpiPhase1.__init__( self, name ) - self.MUCTPI_AthTool = MUCTPI_AthToolCfg("MUCTPI_AthTool") class L1MuctpiPhase1_on_RDO( DefaultL1MuctpiPhase1 ): @@ -161,6 +161,11 @@ class DefaultL1MuctpiPhase1Tool( LVL1MUCTPIPHASE1__MUCTPI_AthTool ): self.MultiplicityStrategyName = "INCLUSIVE" self.GeometryXMLFile = "TrigConfMuctpi/L1MuonGeometry_20200629.xml" + # Set the TGC, RPC, and TrigDecision tools + self.RPCRecRoiTool = getRun3RPCRecRoiTool("RPCRecRoiTool", useRun3Config=True) + self.TGCRecRoiTool = getRun3TGCRecRoiTool("TGCRecRoiTool", useRun3Config=True) + self.TrigThresholdDecisionTool = getTrigThresholdDecisionTool("TrigThresholdDecisionTool") + # Decide which LUT to use, based on which run we are simulating: #from AtlasGeoModel.CommonGMJobProperties import CommonGeometryFlags as commonGeoFlags #from AtlasGeoModel.InDetGMJobProperties import InDetGeometryFlags as geoFlags diff --git a/Trigger/TrigT1/TrigT1MuctpiPhase1/src/MUCTPI_AthTool.cxx b/Trigger/TrigT1/TrigT1MuctpiPhase1/src/MUCTPI_AthTool.cxx index acc9f547789e8e3f86dffdf6a8136b030fe50d6d..d16c81d2cdf785ea4a23c0f61c99d49a861f09f4 100644 --- a/Trigger/TrigT1/TrigT1MuctpiPhase1/src/MUCTPI_AthTool.cxx +++ b/Trigger/TrigT1/TrigT1MuctpiPhase1/src/MUCTPI_AthTool.cxx @@ -6,6 +6,7 @@ #include "TrigT1MuctpiPhase1/MUCTPI_AthTool.h" #include "TrigT1MuctpiPhase1/SimController.h" #include "TrigT1MuctpiPhase1/TriggerProcessor.h" +#include "TrigT1MuctpiPhase1/MuonSectorProcessor.h" #include "TrigT1MuctpiPhase1/Configuration.h" #include "TrigT1MuctpiPhase1/TrigThresholdDecisionTool.h" @@ -43,10 +44,10 @@ namespace LVL1MUCTPIPHASE1 { const std::string MUCTPI_AthTool::m_DEFAULT_L1MuctpiStoreLocationTGC = "/Event/L1MuctpiStoreTGC"; const std::string MUCTPI_AthTool::m_DEFAULT_AODLocID = "LVL1_ROI"; const std::string MUCTPI_AthTool::m_DEFAULT_RDOLocID = "MUCTPI_RDO"; - const std::string MUCTPI_AthTool::m_DEFAULT_barrelRoIFile = "TrigConfMuctpi/Data_ROI_Mapping_Barrel.txt"; - const std::string MUCTPI_AthTool::m_DEFAULT_ecfRoIFile = "TrigConfMuctpi/Data_RoI_Mapping_EF.txt"; - const std::string MUCTPI_AthTool::m_DEFAULT_side0LUTFile = "TrigConfMuctpi/lookup_0.json"; - const std::string MUCTPI_AthTool::m_DEFAULT_side1LUTFile = "TrigConfMuctpi/lookup_1.json"; + const std::string MUCTPI_AthTool::m_DEFAULT_barrelRoIFile = "TrigConfMuctpi/Data_ROI_Mapping_Barrel_20201214.txt"; + const std::string MUCTPI_AthTool::m_DEFAULT_ecfRoIFile = "TrigConfMuctpi/Data_RoI_Mapping_EF_20201214.txt"; + const std::string MUCTPI_AthTool::m_DEFAULT_side0LUTFile = "TrigConfMuctpi/lookup_0_20201214.json"; + const std::string MUCTPI_AthTool::m_DEFAULT_side1LUTFile = "TrigConfMuctpi/lookup_1_20201214.json"; MUCTPI_AthTool::MUCTPI_AthTool(const std::string& type, const std::string& name, const IInterface* parent) @@ -159,7 +160,10 @@ namespace LVL1MUCTPIPHASE1 { const std::string fullFileName = PathResolverFindCalibFile( m_lutXMLFile ); ATH_MSG_DEBUG( "Full path to XML LUT file: " << fullFileName ); - m_theMuctpi->configureOverlapRemoval(fullFileName); + for (unsigned i=0;i<m_theMuctpi->getMuonSectorProcessors().size();i++) + { + m_theMuctpi->getMuonSectorProcessors()[i]->configureOverlapRemoval(fullFileName); + } } else { @@ -188,10 +192,9 @@ namespace LVL1MUCTPIPHASE1 { m_MuCTPIL1TopoKey_p2 = m_MuCTPIL1TopoKey.key()+std::to_string(2); ATH_CHECK(m_MuCTPIL1TopoKey_p2.initialize()); - CHECK( m_rpcTool.retrieve() ); - CHECK( m_tgcTool.retrieve() ); - CHECK( m_trigThresholdDecisionTool.retrieve() ); - m_theMuctpi->getTriggerProcessor()->setTrigTool(*m_trigThresholdDecisionTool); + ATH_CHECK( m_rpcTool.retrieve() ); + ATH_CHECK( m_tgcTool.retrieve() ); + ATH_CHECK( m_trigThresholdDecisionTool.retrieve() ); return StatusCode::SUCCESS; } @@ -202,11 +205,21 @@ namespace LVL1MUCTPIPHASE1 { ATH_MSG_INFO( "Start for Phase1 MUCTPI_AthTool" ); ATH_MSG_INFO( "=======================================" ); - ATH_MSG_INFO( "initialize(): use L1 trigger menu from detector store" ); const TrigConf::L1Menu * l1menu = nullptr; ATH_CHECK( m_detStore->retrieve(l1menu) ); + m_theMuctpi->getTriggerProcessor()->setTrigTool(*m_trigThresholdDecisionTool); m_theMuctpi->getTriggerProcessor()->setMenu(l1menu); + for (unsigned i=0;i<m_theMuctpi->getMuonSectorProcessors().size();i++) + { + m_theMuctpi->getMuonSectorProcessors()[i]->setMenu(l1menu); + if (!m_theMuctpi->getMuonSectorProcessors()[i]->configurePtEncoding()) + { + REPORT_ERROR( StatusCode::FAILURE ) + << "Couldn't configure pt encoding in MuonSectorProcessor " << i; + return StatusCode::FAILURE; + } + } return StatusCode::SUCCESS; } @@ -280,11 +293,11 @@ namespace LVL1MUCTPIPHASE1 { //always process the central slice, which defaults to bcidOffset = 0 // process the input in the MUCTPI simulation - bool success = m_theMuctpi->processData( &mergedInput ); - if (!success) + std::string ret = m_theMuctpi->processData( &mergedInput ); + if (ret != "") { REPORT_ERROR( StatusCode::FAILURE ) - << "Error while processing MUCTPI data"; + << "Error while processing MUCTPI data: " << ret; return StatusCode::FAILURE; } // Save the output of the simulation @@ -306,7 +319,7 @@ namespace LVL1MUCTPIPHASE1 { CHECK( saveOutput( (*it) ) ); } } - } + } return StatusCode::SUCCESS; } diff --git a/Trigger/TrigT1/TrigT1MuctpiPhase1/src/MuonSectorProcessor.cxx b/Trigger/TrigT1/TrigT1MuctpiPhase1/src/MuonSectorProcessor.cxx index c8ca28783e03307242bd538db5360b2112717c12..ca4b7d104218dd085de8788456ed8dd27c59b56f 100644 --- a/Trigger/TrigT1/TrigT1MuctpiPhase1/src/MuonSectorProcessor.cxx +++ b/Trigger/TrigT1/TrigT1MuctpiPhase1/src/MuonSectorProcessor.cxx @@ -12,6 +12,8 @@ #include "TrigT1Interfaces/Lvl1MuSectorLogicConstantsPhase1.h" #include "TrigT1Interfaces/MuCTPIL1Topo.h" #include "TrigConfMuctpi/MuctpiXMLHelper.h" +#include "TrigConfData/L1Menu.h" +#include "TrigConfData/L1Threshold.h" // Headers from external packages. #include <boost/property_tree/ptree.hpp> @@ -25,7 +27,7 @@ #include <set> #include <array> #include <vector> - +#include <utility> using boost::property_tree::ptree; @@ -225,6 +227,7 @@ namespace LVL1MUCTPIPHASE1 { : m_muctpiInput(nullptr), m_overlapHelper(new OverlapHelper), + m_l1menu(nullptr), m_l1topoLUT(nullptr), m_side(side) { @@ -237,10 +240,72 @@ namespace LVL1MUCTPIPHASE1 { } + void MuonSectorProcessor::setMenu(const TrigConf::L1Menu* l1menu) + { + m_l1menu = l1menu; + } + void MuonSectorProcessor::configureOverlapRemoval(const std::string& lutFile) { m_overlapHelper->configure(lutFile); } + + bool MuonSectorProcessor::configurePtEncoding() + { + if (!m_l1menu) return false; + + m_ptEncoding.clear(); + m_ptEncoding = std::vector<std::map<int, int> >(3, std::map<int, int>()); + + //build the map between index and pt threshold. + //the index is the 3- or 4-bit pt word, and has a different + //pt threshold meaning depending on the subsystem. + //the value part of the map is the pt value for the 3 subsystems, + //and the key is the index for an arbitrary subsystem. + //not all indices will be covered by all subsystems since + //barrel only has 3 bits, so initialize the value tuple with -1 + const std::vector<std::shared_ptr<TrigConf::L1Threshold> >* thresholds = &m_l1menu->thresholds("MU"); + for (auto itr=thresholds->begin();itr!=thresholds->end();++itr) + { + std::shared_ptr<TrigConf::L1Threshold_MU> thr = std::static_pointer_cast<TrigConf::L1Threshold_MU>(*itr); + + std::vector<std::pair<int, int> > values; + values.push_back(std::make_pair(thr->idxBarrel()+1, thr->ptBarrel())); + values.push_back(std::make_pair(thr->idxEndcap()+1, thr->ptEndcap())); + values.push_back(std::make_pair(thr->idxForward()+1, thr->ptForward())); + + for (unsigned i=0;i<3;i++) m_ptEncoding[i][values[i].first] = values[i].second; + } + + //for the indices that weren't filled, add the next highest value. + //reverse iterate over the encoded values, check if the previous value + //is empty for each subsys, and fill it with the next highest value if so. + for (unsigned isub=0;isub<3;isub++) + { + std::map<int, int> filledEncoding = m_ptEncoding[isub]; + for (auto itr = m_ptEncoding[isub].rbegin();itr != m_ptEncoding[isub].rend(); ++itr) + { + int idx = itr->first; + int thr = itr->second; + + //fill from the N-1 index until either 0 or we've reached the next lowest encoded value + for (int previous_idx=idx-1; previous_idx >= 0; previous_idx--) + { + //stop if we've reached the next lowest filled encoding + if (m_ptEncoding[isub].find(previous_idx) != m_ptEncoding[isub].end()) break; + + //fill + filledEncoding[previous_idx] = thr; + } + + //set the member variable to the now-filled encoding + } + m_ptEncoding[isub] = filledEncoding; + } + + return true; + } + void MuonSectorProcessor::setInput(LVL1MUONIF::Lvl1MuCTPIInputPhase1* input) { @@ -273,7 +338,7 @@ namespace LVL1MUCTPIPHASE1 { if (isys == 0) sectorName="B"; else if (isys == 1) sectorName="E"; else if (isys == 2) sectorName="F"; - + int roiID = sectorData->roi(icand); if (roiID < 0) continue; int ptword = sectorData->pt(icand); @@ -297,7 +362,7 @@ namespace LVL1MUCTPIPHASE1 { } } - void MuonSectorProcessor::makeL1TopoData(int bcid) + std::string MuonSectorProcessor::makeL1TopoData(int bcid) { if (m_bcid_to_l1topo[bcid]) delete m_bcid_to_l1topo[bcid]; m_bcid_to_l1topo[bcid] = new LVL1::MuCTPIL1Topo(); @@ -313,35 +378,33 @@ namespace LVL1MUCTPIPHASE1 { { if (isub != (unsigned short)(m_side)) continue; const LVL1MUONIF::Lvl1MuSectorLogicDataPhase1* sectorData = &m_muctpiInput->getSectorLogicData(isys, isub, isec, bcid); - if (!sectorData) + if (!sectorData) continue; + + //build the sector name + std::stringstream sectorName; + if (isys == 0) sectorName<<"B"; + else if (isys == 1) sectorName<<"E"; + else if (isys == 2) sectorName<<"F"; + + LVL1MUONIF::Lvl1MuCTPIInputPhase1::MuonSubSystem side = static_cast<LVL1MUONIF::Lvl1MuCTPIInputPhase1::MuonSubSystem>(isub); + if (isys == 0) + { + int sectorNumber=isec; + if (side == LVL1MUONIF::Lvl1MuCTPIInputPhase1::idSideC()) sectorNumber += 32; + if (sectorNumber < 10) sectorName << "0"; + sectorName << sectorNumber; + } + else { - continue; + if (side == LVL1MUONIF::Lvl1MuCTPIInputPhase1::idSideA()) sectorName << "A"; + else sectorName << "C"; + if (isec < 10) sectorName << "0"; + sectorName << isec; } + for (unsigned int icand=0;icand<LVL1MUONIF::NCAND[isys];icand++) { - //build the sector name - std::stringstream sectorName; - if (isys == 0) sectorName<<"B"; - else if (isys == 1) sectorName<<"E"; - else if (isys == 2) sectorName<<"F"; - - LVL1MUONIF::Lvl1MuCTPIInputPhase1::MuonSubSystem side = static_cast<LVL1MUONIF::Lvl1MuCTPIInputPhase1::MuonSubSystem>(isub); - if (isys == 0) - { - int sectorNumber=isec; - if (side == LVL1MUONIF::Lvl1MuCTPIInputPhase1::idSideC()) sectorNumber += 32; - if (sectorNumber < 10) sectorName << "0"; - sectorName << sectorNumber; - } - else - { - if (side == LVL1MUONIF::Lvl1MuCTPIInputPhase1::idSideA()) sectorName << "A"; - else sectorName << "C"; - if (isec < 10) sectorName << "0"; - sectorName << isec; - } - //find the eta/phi int roiID = sectorData->roi(icand); if (roiID < 0) continue; @@ -350,22 +413,45 @@ namespace LVL1MUCTPIPHASE1 { L1TopoCoordinates coord = m_l1topoLUT->getCoordinates(isub, isec, isys, roiID); - unsigned int ptThresholdID=0; - unsigned int ptL1TopoCode=0; - unsigned int ptValue=0; + int ptValue = 0; + auto enc = m_ptEncoding[isub].find(ptword); + if (enc == m_ptEncoding[isub].end()) + { + auto last_enc = m_ptEncoding[isub].rbegin(); + if (last_enc != m_ptEncoding[isub].rend() && ptword > last_enc->first) + { + ptValue = m_ptEncoding[isub].rbegin()->second; + } + else + { + std::stringstream err; + err << "Pt threshold not found in L1Topo encoding. Thr: " << ptword << ", subsys: " << isys; + return err.str(); + } + } + else ptValue=enc->second; - int etacode=0; // no longer needed, but keep for backwards compat - int phicode = 0; // no longer needed, but keep for backwards compat - unsigned int mioctID = 0; // no longer needed, but keep for backwards compat + if (ptValue < 0) + { + std::stringstream err; + err << "Default value returned for pt encoding. Thr: " << ptword << ", isys: " << isys; + return err.str(); + } + + // no longer needed, but keep for backwards compatibility + int etacode=0; + int phicode = 0; + unsigned int mioctID = 0; + unsigned int ptCode=0; LVL1::MuCTPIL1TopoCandidate cand; cand.setCandidateData(sectorName.str(), roiID, bcid, - ptThresholdID, - ptL1TopoCode, - ptValue, + (unsigned int)ptword, + ptCode, + (unsigned int)ptValue, coord.eta, coord.phi, etacode, @@ -391,6 +477,7 @@ namespace LVL1MUCTPIPHASE1 { } } } + return ""; } LVL1MUONIF::Lvl1MuCTPIInputPhase1* MuonSectorProcessor::getOutput() diff --git a/Trigger/TrigT1/TrigT1MuctpiPhase1/src/SimController.cxx b/Trigger/TrigT1/TrigT1MuctpiPhase1/src/SimController.cxx index aadfb16a564faf4d457b015abc4a4db95988f62f..8ae0b6ab6e55436d1fcfcdab0290056bbec2fd2b 100644 --- a/Trigger/TrigT1/TrigT1MuctpiPhase1/src/SimController.cxx +++ b/Trigger/TrigT1/TrigT1MuctpiPhase1/src/SimController.cxx @@ -44,11 +44,6 @@ namespace LVL1MUCTPIPHASE1 { for (int i=0;i<(int)m_muonSectorProcessors.size();i++) m_muonSectorProcessors[i]->setL1TopoLUT(&m_l1topoLUT); } - void SimController::configureOverlapRemoval(const std::string& lutFile) - { - for (int i=0;i<(int)m_muonSectorProcessors.size();i++) m_muonSectorProcessors[i]->configureOverlapRemoval(lutFile); - } - // set Configuration void SimController::setConfiguration ( const Configuration &conf ) { @@ -67,26 +62,25 @@ namespace LVL1MUCTPIPHASE1 { m_candBcidOffset = conf.getCandBcidOffset(); } - bool SimController::processData(LVL1MUONIF::Lvl1MuCTPIInputPhase1* input, int bcid) + std::string SimController::processData(LVL1MUONIF::Lvl1MuCTPIInputPhase1* input, int bcid) { - bool success = true; - + std::string ret = ""; std::vector<LVL1MUONIF::Lvl1MuCTPIInputPhase1*> processedInputs; int nMSP = m_muonSectorProcessors.size(); for (int i=0;i<nMSP;i++) { m_muonSectorProcessors[i]->setInput(input); m_muonSectorProcessors[i]->runOverlapRemoval(bcid); - m_muonSectorProcessors[i]->makeL1TopoData(bcid); + if ((ret = m_muonSectorProcessors[i]->makeL1TopoData(bcid)) != "") return ret; processedInputs.push_back(m_muonSectorProcessors[i]->getOutput()); } //Run the trigger processor algorithms - success = success && m_triggerProcessor->mergeInputs(processedInputs); - success = success && m_triggerProcessor->computeMultiplicities(bcid); - success = success && m_triggerProcessor->makeTopoSelections(); - return success; + m_triggerProcessor->mergeInputs(processedInputs); + if ((ret = m_triggerProcessor->computeMultiplicities(bcid)) != "") return ret; + m_triggerProcessor->makeTopoSelections(); + return ""; } LVL1::MuCTPIL1Topo SimController::getL1TopoData(int bcid) @@ -96,7 +90,7 @@ namespace LVL1MUCTPIPHASE1 { for (int i=0;i<nMSP;i++) { LVL1::MuCTPIL1Topo* l1topo_ptr = m_muonSectorProcessors[i]->getL1TopoData(bcid); - if (l1topo_ptr) l1topo + *l1topo_ptr; + if (l1topo_ptr) l1topo += *l1topo_ptr; } return l1topo; } @@ -106,5 +100,10 @@ namespace LVL1MUCTPIPHASE1 { return m_triggerProcessor; } + std::vector<MuonSectorProcessor*>& SimController::getMuonSectorProcessors() + { + return m_muonSectorProcessors; + } + } diff --git a/Trigger/TrigT1/TrigT1MuctpiPhase1/src/TrigThresholdDecisionTool.cxx b/Trigger/TrigT1/TrigT1MuctpiPhase1/src/TrigThresholdDecisionTool.cxx index e27f5056e82ec7794ab6dc820a86db0e3039b71d..92c07f975f9b7128afd3208e2c1eb4d8cab9a327 100644 --- a/Trigger/TrigT1/TrigT1MuctpiPhase1/src/TrigThresholdDecisionTool.cxx +++ b/Trigger/TrigT1/TrigT1MuctpiPhase1/src/TrigThresholdDecisionTool.cxx @@ -24,14 +24,22 @@ namespace LVL1 StatusCode TrigThresholdDecisionTool::initialize() { + ATH_MSG_INFO( "========================================" ); + ATH_MSG_INFO( "Initialize for TrigThresholdDecisionTool" ); + ATH_MSG_INFO( "========================================" ); + + ATH_CHECK( m_rpcTool.retrieve() ); + ATH_CHECK( m_tgcTool.retrieve() ); + ATH_CHECK( m_detStore->retrieve(m_l1menu) ); return StatusCode::SUCCESS; } StatusCode TrigThresholdDecisionTool::start() { - CHECK( m_rpcTool.retrieve() ); - CHECK( m_tgcTool.retrieve() ); - ATH_CHECK( m_detStore->retrieve(m_l1menu) ); + ATH_MSG_INFO( "==========================================" ); + ATH_MSG_INFO( "Start for Phase1 TrigThresholdDecisionTool" ); + ATH_MSG_INFO( "==========================================" ); + //front-load the TGC flag parsing and all possible 3-bit decisions for the menu const std::vector<std::shared_ptr<TrigConf::L1Threshold>>* thresholds = &m_l1menu->thresholds("MU"); @@ -51,9 +59,7 @@ namespace LVL1 bool C=flags&0b010; bool H=flags&0b001; makeTGCDecision(tgcFlags, F, C, H); - } - } return StatusCode::SUCCESS; @@ -67,23 +73,22 @@ namespace LVL1 if (system == LVL1::ITrigT1MuonRecRoiTool::Barrel) roiTool = &(*m_rpcTool); else roiTool = &(*m_tgcTool); - //the object that will be returned: pairs of thresholds and pass/fail decisions std::vector<std::pair<std::shared_ptr<TrigConf::L1Threshold>, bool> > threshold_decisions; //buffer the some information unsigned isub = roiTool->getBitMaskValue(&dataWord, roiTool->SubSysIDMask()); LVL1MUONIF::Lvl1MuCTPIInputPhase1::MuonSubSystem side = static_cast<LVL1MUONIF::Lvl1MuCTPIInputPhase1::MuonSubSystem>(isub); - unsigned pt_threshold = roiTool->getBitMaskValue(&dataWord, roiTool->ThresholdMask()); + unsigned ptword = roiTool->getBitMaskValue(&dataWord, roiTool->ThresholdMask()); unsigned roi, sectorID; if (system == LVL1::ITrigT1MuonRecRoiTool::Barrel) { - roi = roiTool->getBitMaskValue(&dataWord, roiTool->BarrelRoIMask()); + roi = roiTool->getBitMaskValue(&dataWord, roiTool->BarrelRoIMask()); sectorID = roiTool->getBitMaskValue(&dataWord, roiTool->BarrelSectorIDMask()); } else if (system == LVL1::ITrigT1MuonRecRoiTool::Endcap) { - roi = roiTool->getBitMaskValue(&dataWord, roiTool->EndcapRoIMask()); - sectorID = roiTool->getBitMaskValue(&dataWord, roiTool->ForwardSectorIDMask()); + roi = roiTool->getBitMaskValue(&dataWord, roiTool->EndcapRoIMask()); + sectorID = roiTool->getBitMaskValue(&dataWord, roiTool->EndcapSectorIDMask()); } else { // Forward - roi = roiTool->getBitMaskValue(&dataWord, roiTool->ForwardRoIMask()); + roi = roiTool->getBitMaskValue(&dataWord, roiTool->ForwardRoIMask()); sectorID = roiTool->getBitMaskValue(&dataWord, roiTool->ForwardSectorIDMask()); } @@ -113,9 +118,9 @@ namespace LVL1 thr->region().find("BA") == std::string::npos) continue; //veto this candidate from this multiplicity if it's part of the excluded ROI list - if (isExcludedRPCROI(thr->rpcExclROIList(), roi, sectorID, side == LVL1MUONIF::Lvl1MuCTPIInputPhase1::idSideC())) continue; - - if (thr->idxBarrel()+1 >= pt_threshold) passed=true; + bool pass = !isExcludedRPCROI(thr->rpcExclROIList(), roi, sectorID, side == LVL1MUONIF::Lvl1MuCTPIInputPhase1::idSideC()); + if (!pass) continue; + if (ptword >= thr->idxBarrel()+1) passed=true; } else // Endcap or Forward { @@ -124,20 +129,19 @@ namespace LVL1 //skip the threshold with regions not corresponding to ALL or endcap if (thr->region().find("ALL") == std::string::npos && thr->region().find("EC") == std::string::npos) continue; - if (thr->idxEndcap()+1 >= pt_threshold) passed=true; + if (ptword >= thr->idxEndcap()+1) passed=true; } else // Forward { //skip the threshold with regions not corresponding to ALL or forward if (thr->region().find("ALL") == std::string::npos && thr->region().find("FW") == std::string::npos) continue; - if (thr->idxForward()+1 >= pt_threshold) passed=true; + if (ptword >= thr->idxForward()+1) passed=true; } bool pass = getTGCDecision(thr->tgcFlags(), F, C, H); if (!pass) continue; } // end Endcap or Forward - threshold_decisions[ithresh].second = passed; } // N Thresholds @@ -197,6 +201,7 @@ namespace LVL1 TGCFlagDecision decision(F,C,H); auto previous_decisions = m_tgcFlag_decisions.find(tgcFlags); if (previous_decisions == m_tgcFlag_decisions.end()) return false; + auto previous_decision_itr = previous_decisions->second.find(decision); if (previous_decision_itr != previous_decisions->second.end()) return previous_decision_itr->pass; return false; @@ -209,6 +214,10 @@ namespace LVL1 auto previous_decisions = &m_tgcFlag_decisions[tgcFlags]; auto previous_decision_itr = previous_decisions->find(decision); if (previous_decision_itr != previous_decisions->end()) return; + else if (tgcFlags == "") { + decision.pass=true; + previous_decisions->insert(decision); + } else { // make the decision //check the quality based on the flags. @@ -227,7 +236,6 @@ namespace LVL1 } passedFlags = passedFlags || passedAnd; } - //buffer the decision decision.pass = passedFlags; previous_decisions->insert(decision); diff --git a/Trigger/TrigT1/TrigT1MuctpiPhase1/src/TriggerProcessor.cxx b/Trigger/TrigT1/TrigT1MuctpiPhase1/src/TriggerProcessor.cxx index c322db93364cdcdb330a10a3648e90f2d64bc934..0396ba5dd046283a2ff1448bf7f7da0e71fa0a83 100644 --- a/Trigger/TrigT1/TrigT1MuctpiPhase1/src/TriggerProcessor.cxx +++ b/Trigger/TrigT1/TrigT1MuctpiPhase1/src/TriggerProcessor.cxx @@ -44,15 +44,14 @@ namespace LVL1MUCTPIPHASE1 { m_l1menu = l1menu; } - bool TriggerProcessor::mergeInputs(std::vector<LVL1MUONIF::Lvl1MuCTPIInputPhase1*> inputs) + void TriggerProcessor::mergeInputs(std::vector<LVL1MUONIF::Lvl1MuCTPIInputPhase1*> inputs) { m_mergedInputs->clearAll(); int nrInputs = inputs.size(); for (int i=0;i<nrInputs;i++) m_mergedInputs->merge(*inputs[i]); - return true; } - bool TriggerProcessor::computeMultiplicities(int bcid) + std::string TriggerProcessor::computeMultiplicities(int bcid) { m_ctp_words.clear(); m_daq_data.clear(); @@ -152,7 +151,6 @@ namespace LVL1MUCTPIPHASE1 { std::vector<std::pair<std::shared_ptr<TrigConf::L1Threshold>, bool> > decisions = m_trigThresholdDecisionTool->getThresholdDecisions(daq_word); m_daq_data.push_back(DAQData(daq_word, decisions)); - // // Perform multiplicity counting // @@ -161,15 +159,18 @@ namespace LVL1MUCTPIPHASE1 { if (sectorData->veto(icand)) continue; //basic check that the size vectors are equal - if (decisions.size() != thresholds->size()) return false; + if (decisions.size() != thresholds->size()) return "Threshold vector different size than decision vector"; //loop over each muon threshold passed and see if this candidate satisfies it. //if so, increment the multiplicity of this threshold for (unsigned ithresh=0;ithresh<decisions.size();ithresh++) { //check that the pointers are ordered correctly - if (decisions[ithresh].first != (*thresholds)[ithresh]) return false; - if (decisions[ithresh].second) ++multiplicities[ithresh]; + if (decisions[ithresh].first != (*thresholds)[ithresh]) return "Invalid threshold ordering"; + if (decisions[ithresh].second) + { + ++multiplicities[ithresh]; + } } } // N Cand } // N Subsys @@ -200,13 +201,12 @@ namespace LVL1MUCTPIPHASE1 { full_ctp_word >>= 32; } - return true; + return ""; } - bool TriggerProcessor::makeTopoSelections() + void TriggerProcessor::makeTopoSelections() { //reserved for topo selection functionality - return true; } diff --git a/Trigger/TrigT1/TrigT1MuonRecRoiTool/python/TrigT1MuonRecRoiToolConfig.py b/Trigger/TrigT1/TrigT1MuonRecRoiTool/python/TrigT1MuonRecRoiToolConfig.py index 71e4d402f5a9525f3461c04b4ce43d31b49e7152..d4262cff27649aa63f70d891746129d92dffdb5d 100644 --- a/Trigger/TrigT1/TrigT1MuonRecRoiTool/python/TrigT1MuonRecRoiToolConfig.py +++ b/Trigger/TrigT1/TrigT1MuonRecRoiTool/python/TrigT1MuonRecRoiToolConfig.py @@ -1,16 +1,12 @@ # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration - - -# Local (generated) configurable(s): -from TrigT1MuonRecRoiTool.TrigT1MuonRecRoiToolConf import LVL1__TrigT1RPCRecRoiTool -from TrigT1MuonRecRoiTool.TrigT1MuonRecRoiToolConf import LVL1__TrigT1TGCRecRoiTool +from AthenaConfiguration.ComponentFactory import CompFactory def getRun3RPCRecRoiTool(name = "RPCRecRoiTool", useRun3Config=True): - tool = LVL1__TrigT1RPCRecRoiTool(name) + tool = CompFactory.getComp("LVL1::TrigT1RPCRecRoiTool")(name) tool.UseRun3Config=useRun3Config return tool def getRun3TGCRecRoiTool(name = "TGCRecRoiTool", useRun3Config=True): - tool = LVL1__TrigT1TGCRecRoiTool(name) + tool = CompFactory.getComp("LVL1::TrigT1TGCRecRoiTool")(name) tool.UseRun3Config=useRun3Config return tool diff --git a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref index 77f67066608cd547ca9241c7dc3ec434b735f704..13331615b3cbdce864d8cab4961390a4cd380695 100644 --- a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref +++ b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref @@ -932,6 +932,8 @@ HLT_e10_lhmedium_ivarloose_j70_0eta320_j50_0eta490_j0_dijetSEP50j12etSEP900djmas 4: 1 HLT_e12_lhloose_2mu10_L12MU10: eventCount: 0 + stepFeatures: + 0: 2 HLT_e140_lhloose_L1EM22VHI: eventCount: 0 HLT_e140_lhloose_nod0_L1EM22VHI: @@ -1876,7 +1878,7 @@ HLT_g15_loose_2mu10_msonly_L12MU10: 1: 1 2: 1 stepFeatures: - 0: 1 + 0: 3 1: 1 2: 1 HLT_g20_loose_L1EM15VH: @@ -3056,7 +3058,7 @@ HLT_mu10_ivarmedium_mu10_10invm70_L12MU10: 3: 2 4: 2 stepFeatures: - 0: 10 + 0: 24 1: 8 2: 8 3: 8 @@ -3070,7 +3072,7 @@ HLT_mu11_mu6_bBmumu_L1MU11_2MU6: 1: 1 2: 1 stepFeatures: - 0: 13 + 0: 25 1: 11 2: 6 3: 4 @@ -3082,7 +3084,7 @@ HLT_mu11_mu6_bDimu2700_L1MU11_2MU6: 1: 1 2: 1 stepFeatures: - 0: 13 + 0: 25 1: 11 2: 6 3: 4 @@ -3094,7 +3096,7 @@ HLT_mu11_mu6_bDimu_L1MU11_2MU6: 1: 1 2: 1 stepFeatures: - 0: 13 + 0: 25 1: 11 2: 6 3: 4 @@ -3106,7 +3108,7 @@ HLT_mu11_mu6_bJpsimumu_L1MU11_2MU6: 1: 1 2: 1 stepFeatures: - 0: 13 + 0: 25 1: 11 2: 6 3: 4 @@ -3118,7 +3120,7 @@ HLT_mu11_mu6_bPhi_L1MU11_2MU6: 1: 1 2: 1 stepFeatures: - 0: 13 + 0: 25 1: 11 2: 6 3: 4 @@ -3130,7 +3132,7 @@ HLT_mu11_mu6_bTau_L1MU11_2MU6: 1: 1 2: 1 stepFeatures: - 0: 13 + 0: 25 1: 11 2: 6 3: 4 @@ -3142,7 +3144,7 @@ HLT_mu11_mu6_bUpsimumu_L1MU11_2MU6: 1: 1 2: 1 stepFeatures: - 0: 13 + 0: 25 1: 11 2: 6 3: 4 @@ -3565,8 +3567,12 @@ HLT_mu60_L1MU20: 3: 1 HLT_mu6_2mu4_bDimu2700_L1MU6_3MU4: eventCount: 0 + stepFeatures: + 0: 13 HLT_mu6_2mu4_bDimu6000_L1MU6_3MU4: eventCount: 0 + stepFeatures: + 0: 13 HLT_mu6_L1MU6: eventCount: 10 stepCounts: @@ -3642,7 +3648,7 @@ HLT_mu6_mu4_L12MU4: 2: 2 3: 2 stepFeatures: - 0: 14 + 0: 28 1: 11 2: 10 3: 8 diff --git a/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1MuonSimulationConfigOldStyle.py b/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1MuonSimulationConfigOldStyle.py index f2d36350beaa059c802b87cc14c3ef0b8ff1be1a..8856a1772943ea0730e4dc9615bf7e0b2e62e9dd 100644 --- a/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1MuonSimulationConfigOldStyle.py +++ b/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1MuonSimulationConfigOldStyle.py @@ -259,6 +259,9 @@ def Lvl1MuctpiConfig(flags): muctpiTool.InputSource = 'DIGITIZATION' muctpiTool.RPCRecRoiTool = rpcRecRoiTool muctpiTool.TGCRecRoiTool = tgcRecRoiTool + muctpiTool.TrigThresholdDecisionTool = CompFactory.LVL1__TrigThresholdDecisionTool(name="TrigThresholdDecisionTool") + muctpiTool.TrigThresholdDecisionTool.RPCRecRoiTool = rpcRecRoiTool + muctpiTool.TrigThresholdDecisionTool.TGCRecRoiTool = tgcRecRoiTool muctpi = CompFactory.LVL1MUCTPIPHASE1__MUCTPI_AthAlg(name="MUCTPI_AthAlg", MUCTPI_AthTool = muctpiTool) return muctpi diff --git a/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1SimulationConfig.py b/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1SimulationConfig.py index e8a0d1634293b54e843114571a5adf29170a3dc9..62b709503a9e1fd22cc18e9bc5c19f7c41eda794 100644 --- a/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1SimulationConfig.py +++ b/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1SimulationConfig.py @@ -217,6 +217,9 @@ def Lvl1SimulationSequence_MC( ConfigFlags ): from TrigT1MuctpiPhase1.TrigT1MuctpiPhase1Config import L1MuctpiPhase1Tool ToolSvc += L1MuctpiPhase1Tool("MUCTPI_AthTool") l1TopoSim.MuonInputProvider.MuctpiSimTool = ToolSvc.MUCTPI_AthTool + from TrigT1MuonRecRoiTool.TrigT1MuonRecRoiToolConfig import getRun3RPCRecRoiTool, getRun3TGCRecRoiTool + l1TopoSim.MuonInputProvider.RecRpcRoiTool = getRun3RPCRecRoiTool(useRun3Config=True) + l1TopoSim.MuonInputProvider.RecTgcRoiTool = getRun3TGCRecRoiTool(useRun3Config=True) l1TopoSim.EMTAUInputProvider = 'LVL1::EMTauInputProviderFEX/EMTauInputProviderFEX' else: from TrigT1Muctpi.TrigT1MuctpiConfig import L1MuctpiTool diff --git a/Trigger/TriggerCommon/TriggerJobOpts/python/Modifiers.py b/Trigger/TriggerCommon/TriggerJobOpts/python/Modifiers.py index ded655d55191ebcb70d21d3656729892443902a0..d661ecf2486888b4288cf40d34ae377c5f63e831 100644 --- a/Trigger/TriggerCommon/TriggerJobOpts/python/Modifiers.py +++ b/Trigger/TriggerCommon/TriggerJobOpts/python/Modifiers.py @@ -472,6 +472,10 @@ class rerunLVL1(_modifier): from AthenaCommon.AppMgr import ToolSvc ToolSvc += L1MuctpiTool() topSequence.L1TopoSimulation.MuonInputProvider.MuctpiSimTool = L1MuctpiTool() + from TrigT1MuonRecRoiTool.TrigT1MuonRecRoiToolConfig import getRun3RPCRecRoiTool, getRun3TGCRecRoiTool + topSequence.L1TopoSimulation.MuonInputProvider.RecRpcRoiTool = getRun3RPCRecRoiTool(useRun3Config=True) + topSequence.L1TopoSimulation.MuonInputProvider.RecTgcRoiTool = getRun3TGCRecRoiTool(useRun3Config=True) + # enable the reduced (coarse) granularity topo simulation # currently only for MC