diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Board.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Board.h index 1426611bfb004b08af1e43107f61ffa84a1dbb53..a96bdd6ae6876550bd03f62dc887ccac6bdd08ed 100644 --- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Board.h +++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Board.h @@ -23,7 +23,7 @@ namespace TrigConf { class L1Board final : public DataStructure { public: - enum class BoardType { CTPIN, TOPO, MUCTPI }; + enum class BoardType { CTPIN, TOPO, MUCTPI, MERGER }; /** Constructor */ L1Board(); diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1Board.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1Board.cxx index 059497974f3a80a74e7837a2d06d99353b803f08..94fff7c58bf7f96c777ff55ef1162581e50b1d86 100644 --- a/Trigger/TrigConfiguration/TrigConfData/src/L1Board.cxx +++ b/Trigger/TrigConfiguration/TrigConfData/src/L1Board.cxx @@ -43,6 +43,8 @@ TrigConf::L1Board::update() m_boardType = BoardType::CTPIN; } else if( boardType == "TOPO" ) { m_boardType = BoardType::TOPO; + } else if( boardType == "MERGER" ) { + m_boardType = BoardType::MERGER; } else { throw std::runtime_error("Unknown board type " + boardType); } @@ -76,6 +78,8 @@ TrigConf::L1Board::type() const return "MUCTPI"; case BoardType::TOPO: return "TOPO"; + case BoardType::MERGER: + return "MERGER"; } return ""; } diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1Connector.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1Connector.cxx index 6a016b7a86c9f6e516b004e5d25c6bd8b9bb63f1..3b206408e3d7953a6f366b24ab350321424b8d3e 100644 --- a/Trigger/TrigConfiguration/TrigConfData/src/L1Connector.cxx +++ b/Trigger/TrigConfiguration/TrigConfData/src/L1Connector.cxx @@ -42,16 +42,20 @@ TrigConf::L1Connector::update() } // triggerlines + bool hasMultipleFPGAs = ! hasChild("triggerlines.clock0"); // connector from merger board (no fpga) if(m_type == ConnectorType::ELECTRICAL) { - m_maxFpga = m_maxClock = 2; + m_maxClock = 2; + m_maxFpga = hasMultipleFPGAs ? 2 : 1; } for( size_t fpga = 0; fpga < m_maxFpga; ++fpga ) { for( size_t clock = 0; clock < m_maxClock; ++clock ) { std::string path = "triggerlines"; if( m_type == ConnectorType::ELECTRICAL ) { - path += ".fpga"; - path += std::to_string(fpga); + if(hasMultipleFPGAs) { + path += ".fpga"; + path += std::to_string(fpga); + } path += ".clock"; path += std::to_string(clock); } diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx index 014f8a7a368d23fa031146e95549a47a4567514e..52d4542057ad154596517f8b1916042ab9037dec 100644 --- a/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx +++ b/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx @@ -322,11 +322,16 @@ TrigConf::L1Menu::algorithmFromTriggerline(const std::string & triggerlineName) category = triggerlineName.substr(0,pos); outputName = triggerlineName.substr(pos+1); } + const static std::vector<string> topoTypes {"TOPO", "R2TOPO", "MULTTOPO", "MUTOPO"}; + if( std::none_of(cbegin(topoTypes), cend(topoTypes), [&category](const std::string & str){return str==category;}) ) { + std::string msg = "L1Menu::algorithmFromTriggerLine(" + triggerlineName + "): triggerline " + triggerlineName + " is not produced by a topo algorithm."; + throw std::runtime_error(msg); + } try { return * m_algorithmsByOutput.at(category).at(outputName); } catch(std::exception & ex) { - std::cerr << "No output " << outputName << " defined by any algorithm of category " << category << " in the L1 menu. (It was asked for " << triggerlineName << ")" << std::endl; + std::cerr << "L1Menu::algorithmFromTriggerLine(): No output " << outputName << " defined by any algorithm of category " << category << " in the L1 menu. (It was asked for " << triggerlineName << ")" << std::endl; throw; } } diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1ThresholdBase.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1ThresholdBase.cxx index ce80fe7f5c983f1e60fe54517a415e22457a2662..9afe50ca08dd85e521f5272c7dc8cd8c5431c77a 100644 --- a/Trigger/TrigConfiguration/TrigConfData/src/L1ThresholdBase.cxx +++ b/Trigger/TrigConfiguration/TrigConfData/src/L1ThresholdBase.cxx @@ -64,7 +64,7 @@ TrigConf::L1Threshold::createThreshold( const std::string & name, const std::str if( type == "internal" ) return std::make_shared<L1Threshold_internal>( name, type, extraInfo, data ); - static const std::string noSpecialImp[] = { "JET", "XS", "jJ", "gXE", "jXE", "TOPO", "MULTTOPO", "MUTOPO", "R2TOPO", "ZB" }; + static const std::string noSpecialImp[] = { "JET", "XS", "jJ", "gXE", "jXE", "TOPO", "MULTTOPO", "MUTOPO", "R2TOPO", "ZB", "ALFA" }; bool useBaseClass = std::find(std::begin(noSpecialImp), std::end(noSpecialImp),type) != std::end(noSpecialImp); diff --git a/Trigger/TrigConfiguration/TrigConfIO/test/testAllKeysReading.sh b/Trigger/TrigConfiguration/TrigConfIO/test/testAllKeysReading.sh new file mode 100755 index 0000000000000000000000000000000000000000..8d5a67f2f062b3cbc9bd13b9af650723717e0335 --- /dev/null +++ b/Trigger/TrigConfiguration/TrigConfIO/test/testAllKeysReading.sh @@ -0,0 +1,12 @@ +smk=1 +while ( [[ smk -le 1 ]] ) +do + cmd="TestTriggerMenuAccess --smk ${smk}" + echo "executing $cmd" + $cmd + #2>1 > /dev/null + STATUS=$status + + let smk++ +done + diff --git a/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx b/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx index 547375efe06246e2bc312fd5f38a7f08c3ded9b9..1c6b5f943f6822539d1f3b9aa8fac5f6fec1520c 100644 --- a/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx +++ b/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx @@ -7,6 +7,7 @@ #include <iomanip> #include "TrigConfIO/JsonFileLoader.h" +#include "TrigConfIO/TrigDBMenuLoader.h" #include "TrigConfData/HLTMenu.h" #include "TrigConfData/L1Menu.h" #include "TrigConfData/L1Threshold.h" @@ -98,7 +99,7 @@ testL1Menu_Boards(const TrigConf::L1Menu & l1menu) { cout << "Board " << boardName << " of type " << board.type() << " has " << board.size() << " connectors configured: "; for( auto & connName : board.connectorNames() ) { cout << connName << " "; } cout << endl; - return true; + return true; } @@ -118,6 +119,12 @@ testL1Menu_Connectors(const TrigConf::L1Menu & l1menu) { for( auto & tl : conn.triggerLines() ) { cout << " Triggerline " << tl.name() << " bits=[" << tl.startbit() << ".." << tl.endbit() << "] is a muon threshold " << endl; } + } else if( connName == "AlfaCtpin" ) { + for( size_t clock : { 0, 1 } ) { + for( auto & tl : conn.triggerLines(0, clock) ) { + cout << " Triggerline " << tl.name() << " (clock " << clock << ", bit " << tl.startbit() << ") is an ALFA threshold " << endl; + } + } } else if( conn.type() == TrigConf::L1Connector::ConnectorType::CTPIN ) { for( auto & tl : conn.triggerLines() ) { cout << " Triggerline " << tl.name() << " bits=[" << tl.startbit() << ".." << tl.endbit() << "] is a legacy threshold " << endl; @@ -130,8 +137,9 @@ testL1Menu_Connectors(const TrigConf::L1Menu & l1menu) { << "] is produced by topo algorithm " << topoAlg.name() << endl; } } else if( conn.type() == TrigConf::L1Connector::ConnectorType::ELECTRICAL ) { - for( size_t fpga : { 0 ,1 } ) { - for( size_t clock : { 0 ,1 } ) { + cout << "JOERG 3" << endl; + for( size_t fpga : { 0, 1 } ) { + for( size_t clock : { 0, 1 } ) { for( auto & tl : conn.triggerLines(fpga, clock) ) { const string & tlName = tl.name(); auto & topoAlg = l1menu.algorithmFromTriggerline(tlName); @@ -403,7 +411,7 @@ testL1Menu_Extrainfo(const TrigConf::L1Menu & l1menu) bool -testL1Menu(const string & filename, bool printdetail = false) +testL1Menu(const TrigConf::L1Menu & l1menu, bool printdetail = false) { cout << endl << "==========================" << endl @@ -414,9 +422,6 @@ testL1Menu(const string & filename, bool printdetail = false) cout << "Printing detail " << (printdetail ? "yes" : "no") << endl; section("Menu loading"); - TrigConf::L1Menu l1menu; - TrigConf::JsonFileLoader fileLoader; - fileLoader.loadFile( filename, l1menu); cout << "Loaded the L1 menu " << l1menu.name() << endl; bool result = true; @@ -431,7 +436,7 @@ testL1Menu(const string & filename, bool printdetail = false) -bool testHLTMenu(const string & filename) { +bool testHLTMenu(const TrigConf::HLTMenu & hltmenu) { cout << "===========================" << endl << "===== =====" << endl @@ -439,9 +444,6 @@ bool testHLTMenu(const string & filename) { << "===== =====" << endl << "===========================" << endl << endl; - TrigConf::HLTMenu hltmenu; - TrigConf::JsonFileLoader fileLoader; - fileLoader.loadFile( filename, hltmenu); cout << "Loaded the HLT menu " << hltmenu.name() << endl; cout << "Menu has " << hltmenu.size() << " chains, going to print the first 3." << endl; int np = 3; @@ -496,9 +498,83 @@ bool testHLTMenu(const string & filename) { Main function just to get the filename and which type */ +void usage() { + + cout << "The program needs to be run with the following specifications:\n\n"; + cout << "TestTriggerMenuAccess <options>\n"; + cout << "\n"; + cout << "[Input options]\n"; + cout << " -f|--file file1 ... input json file to test\n"; + cout << " --smk smk ... smk \n"; + cout << " --db dbalias ... dbalias (default TRIGGERDBDEV1) \n"; + cout << "[Other options]\n"; + cout << " -h|--help ... this help\n"; + cout << "\n"; + cout << "If no input is specified, the default LS2_v1 menu file will be taken from the release\n\n"; +} + int main(int argc, char** argv) { - string filename(""); - if(argc==1) { + bool help { false }; + string filename{""}; + unsigned int smk{0}; + std::string dbalias {"TRIGGERDBDEV1"}; + std::vector<std::string> knownParameters { "file", "f", "smk", "db", "help", "h" }; + + std::string currentParameter(""); + std::string listofUnknownParameters = ""; + std::string listofUnknownArguments = ""; + for(int i=1; i<argc; i++) { + + std::string currentWord(argv[i]); + bool isParam = currentWord[0]=='-'; // string starts with a '-', so it is a parameter name + + // get the parameter name + int firstChar = currentWord.find_first_not_of('-'); + string paramName = currentWord.substr(firstChar); + + // check if the parameter is known + if ( isParam && std::find(knownParameters.begin(), knownParameters.end(), paramName) == knownParameters.end() ) { + listofUnknownParameters += " " + currentWord; + continue; + } + + if(isParam) { + currentParameter = ""; + // check the boolean parameters + if(paramName == "h" || paramName == "help" ) { help = true; continue; } + currentParameter = paramName; + continue; + } + + // inputs + if(currentParameter == "file" || currentParameter == "f") { + filename = currentWord; + continue; + } + if(currentParameter == "smk") { + smk = stoul(currentWord); + continue; + } + if(currentParameter == "db") { + dbalias = currentWord; + continue; + } + listofUnknownArguments += " " + currentWord; + } + + if ( not listofUnknownParameters.empty() ) { + cerr << "Unknown parameter(s):" << listofUnknownParameters << endl; + usage(); + return 1; + } + + if ( not listofUnknownArguments.empty() ) { + cerr << "Unknown argument(s):" << listofUnknownArguments << endl; + usage(); + return 1; + } + + if( filename.empty() && smk==0 ) { // no filename specified, going to take the L1 menu from the release const char* env_AV = std::getenv("AtlasVersion"); const char* env_xmlpath = std::getenv("XMLPATH"); @@ -516,32 +592,41 @@ int main(int argc, char** argv) { } } if(filename == "") { - cout << "No filename specified and no default L1 menu file found in the release" << endl; - cout << "Please use " << argv[0] << " <filename.json>" << endl; - return 1; - } - } else if (argc==2) { - struct stat buffer; - if (stat (argv[1], &buffer) == 0) { - filename = string(argv[1]); - } - if(filename == "") { - cout << "Can't find file " << argv[1] << endl; + cout << "No filename or smk specified and no default L1 menu file found in the release" << endl; + usage(); return 1; } } - // file loader - TrigConf::JsonFileLoader fileLoader; - string filetype = fileLoader.getFileType( filename ); + if(help) { + usage(); + return 0; + } + bool success(false); - if(filetype == "l1menu") { - success = testL1Menu(filename); - } else if(filetype == "hltmenu") { - success = testHLTMenu(filename); + if(smk!=0) { + // load from db + TrigConf::L1Menu l1menu; + TrigConf::TrigDBMenuLoader dbLoader(dbalias); + dbLoader.loadL1Menu( smk, l1menu); + success = testL1Menu(l1menu); } else { - cout << "File " << filename << " is neither an L1 or an HLT menu json file" << endl; - } + // load from file + TrigConf::JsonFileLoader fileLoader; + string filetype = fileLoader.getFileType( filename ); + if(filetype == "l1menu") { + TrigConf::L1Menu l1menu; + fileLoader.loadFile( filename, l1menu); + success = testL1Menu(l1menu); + } else if(filetype == "hltmenu") { + TrigConf::HLTMenu hltmenu; + fileLoader.loadFile( filename, hltmenu); + success = testHLTMenu(hltmenu); + } else { + cout << "File " << filename << " is neither an L1 or an HLT menu json file" << endl; + } + } + cout << "Finished " << (success ? "successfully" : "with failures") << endl; return success ? 0 : 1; } diff --git a/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx b/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx index a7a80c4e96de03b2e8945ae4cffa1619e3ed126a..20e8be13a51551f27a2f8b69d0b7b678f3d6a550 100644 --- a/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx +++ b/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx @@ -33,7 +33,7 @@ public: unsigned int l1psk { 0 }; unsigned int hltpsk { 0 }; unsigned int bgsk { 0 }; - std::string dbalias { "TRIGGERDBDEV2" }; + std::string dbalias { "TRIGGERDBDEV1" }; // output bool write { false }; // flag to enable writing diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/CTP.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/CTP.py index 680ce6e150c2c7897488279851a36a7c0444143c..b97fbb2548715f836236062b536b51996dbe06fd 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/CTP.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/CTP.py @@ -17,8 +17,7 @@ class CTP(object): self.random = Random( names = ['Random0', 'Random1', 'Random2', 'Random3'], cuts = [1, 1, 1, 1] ) self.bunchGroupSet = BunchGroupSet() self.counters = MenuMonCountersCollection() # monitoring counters in the menu - - + def setBunchGroupSetName(self, name): self.bunchGroupSet.name = name return self.bunchGroupSet @@ -40,6 +39,19 @@ class CTP(object): MonitorDef.applyItemCounter( menuItems ) pass + def checkConnectorAvailability(self, availableConnectors, menuToLoad): + inputConnectorList = [] + inputConnectorList += self.inputConnectors["optical"].values() + inputConnectorList += self.inputConnectors["electrical"].values() + inputConnectorList += self.inputConnectors["ctpin"]["slot7"].values() + inputConnectorList += self.inputConnectors["ctpin"]["slot8"].values() + inputConnectorList += self.inputConnectors["ctpin"]["slot9"].values() + for connName in inputConnectorList: + if connName != '' and connName not in availableConnectors: + msg = "Connector '%s' requested in L1/Config/CTPConfig.py not defined as menu input. Please add it to L1/Menu/Menu_%s_inputs.py" % (connName, menuToLoad) + log.error(msg) + raise RuntimeError(msg) + def json(self): confObj = odict() confObj["inputs"] = self.inputConnectors diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/Connectors.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/Connectors.py index 04c47d93a27398f37dc0c611f12bb20c98fb5195..29ad08861f65dcababcad1067955833a2f00aea2 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/Connectors.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/Connectors.py @@ -35,6 +35,7 @@ class CType(Enum): class CFormat(Enum): MULT = (1, 'multiplicity') TOPO = (2, 'topological') + SIMPLE = (3, 'simple') def __init__(self, _, cformat ): self.cformat = cformat @@ -44,6 +45,8 @@ class CFormat(Enum): return CFormat.MULT elif label == 'topological': return CFormat.TOPO + elif label == 'simple': + return CFormat.SIMPLE else: raise NotImplementedError @@ -58,6 +61,9 @@ class MenuConnectorsCollection(object): def __iter__(self): return iter(self.connectors.values()) + def __contains__(self, name): + return name in self.connectors + def addConnector(self, connDef): name, cformat, ctype, legacy, boardName = map(connDef.__getitem__,["name", "format", "type", "legacy", "board"]) @@ -66,48 +72,11 @@ class MenuConnectorsCollection(object): log.debug("Adding connector %s, format %s, legacy set to %s, and connType %s", name, cformat, legacy, ctype) if CType.from_str(ctype) is CType.ELEC: - newConnector = ElectricalConnector(name, cformat, legacy) + newConnector = ElectricalConnector(name, cformat, legacy, connDef) else: - newConnector = Connector(name, cformat, ctype, legacy) + newConnector = OpticalConnector(name, cformat, ctype, legacy, connDef) self.connectors[name] = newConnector - - # treat differently depending on the "format", which can be: 'topological' or 'multiplicity' - if connDef["format"] == 'multiplicity': - # multiplicity connectors contain all the triggerlines in a flat "thresholds" list - startbit = 0 - for thrName in connDef["thresholds"]: - nbits = connDef["nbitsDefault"] - if type(thrName)==tuple: - (thrName,nbits) = thrName - if thrName is None: - startbit += nbits - continue - tl = TriggerLine( name = thrName, startbit = startbit, nbits = nbits) - startbit += nbits - newConnector.addTriggerLine(tl) - - elif connDef["format"] == 'topological': - # topological connectors when they are electrical - # connectors contain the triggerlines in up to four - # algorithm groups, each corresponding to a different (fpga,clock) setting - - currentTopoCategory = AlgCategory.getCategoryFromBoardName(boardName) - - if newConnector.ctype == CType.ELEC: - for thrG in connDef["algorithmGroups"]: - (newConnector.fpga, newConnector.clock) = map(thrG.__getitem__,["fpga","clock"]) - fpga,clock = map(thrG.__getitem__,["fpga","clock"]) - for topo in thrG["algorithms"]: - bit = topo.outputbits[0] if isinstance(topo.outputbits, tuple) else topo.outputbits - for (i, tl) in enumerate(topo.outputlines): - # for topoological triggerlines the names have to be prefixed as they are in the item definitions - tlname = currentTopoCategory.prefix + tl - newConnector.addTriggerLine( TriggerLine( name = tlname, startbit = bit+i, nbits = 1 ), fpga, clock ) - - else: - raise RuntimeError("Property 'format' of connector %s is '%s' but must be either 'multiplicity' or 'topological'") - if newConnector.ctype == CType.CTPIN: try: zbThr = connDef["zeroBias"] @@ -131,17 +100,19 @@ class MenuConnectorsCollection(object): class Connector(object): - __slots__ = [ 'name', 'cformat', 'ctype', 'legacy', 'triggerLines'] - def __init__(self, name, cformat, ctype, legacy): + __slots__ = [ 'name', 'cformat', 'ctype', 'legacy', 'boardName', 'triggerLines'] + def __init__(self, connDef): """ @param name name of the connector @param cformat can be 'topological' or 'multiplicity' @param ctype can be 'ctpin', 'electrical', or 'optical' """ + name, cformat, ctype, legacy, boardName = map(connDef.__getitem__,["name", "format", "type", "legacy", "board"]) self.name = name self.cformat = CFormat.from_str(cformat) self.ctype = CType.from_str(ctype) self.legacy = bool(legacy) + self.boardName = boardName self.triggerLines = [] def addTriggerLine(self, tl): @@ -162,15 +133,74 @@ class Connector(object): return confObj +class OpticalConnector(Connector): + __slots__ = [ 'name', 'cformat', 'ctype', 'legacy', 'triggerLines'] + def __init__(self, name, cformat, ctype, legacy, connDef): + """ + @param name name of the connector + @param cformat can be 'topological' or 'multiplicity' + @param ctype can be 'ctpin', 'electrical', or 'optical' + """ + super(OpticalConnector,self).__init__(connDef = connDef) + + # treat differently depending on the "format", which can be: 'topological' or 'multiplicity' + if connDef["format"] == 'multiplicity': + # multiplicity connectors contain all the triggerlines in a flat "thresholds" list + startbit = 0 + for thrName in connDef["thresholds"]: + nbits = connDef["nbitsDefault"] + if type(thrName)==tuple: + (thrName,nbits) = thrName + if thrName is None: + startbit += nbits + continue + tl = TriggerLine( name = thrName, startbit = startbit, nbits = nbits) + startbit += nbits + self.addTriggerLine(tl) + else: + raise RuntimeError("Property 'format' of connector %s is '%s' but must be either 'multiplicity' or 'topological'" % (name,connDef["format"])) + + class ElectricalConnector(Connector): - def __init__(self, name, cformat, legacy): + def __init__(self, name, cformat, legacy, connDef): """ @param name name of the connector @param cformat can be 'topological' or 'multiplicity' """ - super(ElectricalConnector,self).__init__(name = name, cformat = cformat, ctype = 'electrical', legacy = legacy) + super(ElectricalConnector,self).__init__(connDef = connDef) self.triggerLines = { 0 : {0:[],1:[]}, 1 : {0:[],1:[]} } + if self.cformat == CFormat.TOPO: + # topological connectors when they are electrical + # connectors contain the triggerlines in up to four + # algorithm groups, each corresponding to a different (fpga,clock) setting + currentTopoCategory = AlgCategory.getCategoryFromBoardName(self.boardName) + for thrG in connDef["algorithmGroups"]: + fpga,clock = map(thrG.__getitem__,["fpga","clock"]) + for topo in thrG["algorithms"]: + bit = topo.outputbits[0] if isinstance(topo.outputbits, tuple) else topo.outputbits + for (i, tl) in enumerate(topo.outputlines): + # for topoological triggerlines the names have to be prefixed as they are in the item definitions + tlname = currentTopoCategory.prefix + tl + self.addTriggerLine( TriggerLine( name = tlname, startbit = bit+i, nbits = 1 ), fpga, clock ) + elif self.cformat == CFormat.SIMPLE: + for sigG in connDef["signalGroups"]: + clock = sigG["clock"] + startbit = 0 + for signal in sigG["signals"]: + nbits = connDef["nbitsDefault"] + if type(signal)==tuple: + (signal,nbits) = signal + if signal is None: + startbit += nbits + continue + tl = TriggerLine( name = signal, startbit = startbit, nbits = nbits) + startbit += nbits + self.addTriggerLine(tl, 0, clock) + else: + raise RuntimeError("Property 'format' of connector %s is '%s' but must be either 'multiplicity' or 'topological'" % (name,connDef["format"])) + + def addTriggerLine(self, tl, fpga, clock): self.triggerLines[fpga][clock].append( tl ) @@ -184,12 +214,18 @@ class ElectricalConnector(Connector): if self.legacy: confObj["legacy"] = self.legacy confObj["triggerlines"] = odict() - for fpga in [0,1]: - fpgas = "fpga%i" % fpga - confObj["triggerlines"][fpgas] = odict() + if self.cformat == CFormat.TOPO: + for fpga in [0,1]: + fpgas = "fpga%i" % fpga + confObj["triggerlines"][fpgas] = odict() + for clock in [0,1]: + clocks = "clock%i" % clock + confObj["triggerlines"][fpgas][clocks] = [tl.json() for tl in self.triggerLines[fpga][clock]] + elif self.cformat == CFormat.SIMPLE: + confObj["triggerlines"] = odict() for clock in [0,1]: clocks = "clock%i" % clock - confObj["triggerlines"][fpgas][clocks] = [tl.json() for tl in self.triggerLines[fpga][clock]] + confObj["triggerlines"][clocks] = [tl.json() for tl in self.triggerLines[0][clock]] return confObj diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/Thresholds.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/Thresholds.py index fb8a2a6f2d1dac158c027f7624cd8766a8c8fb58..607f415ff1573930b07c948d653d04775ece8c84 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/Thresholds.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/Thresholds.py @@ -65,7 +65,7 @@ class MenuThresholdsCollection( object ): def json(self): confObj = odict() - for ttype in (ThrType.Run3Types() + ThrType.NIMTypes() + [ThrType.TOPO, ThrType.MUTOPO ]): + for ttype in (ThrType.Run3Types() + ThrType.NIMTypes() + [ThrType.TOPO, ThrType.MUTOPO] + [ThrType.ALFA]): confObj[ttype.name] = odict() confObj[ttype.name]["type"] = ttype.name confObj[ttype.name]["thresholds"] = odict() diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/CTPInputConfig.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/CTPInputConfig.py index 6ee7e5c975ec29caa48d09f44f0509b8da567737..d663ac6ebbbd430225a1f9fe9b330ef911a9d215 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/CTPInputConfig.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/CTPInputConfig.py @@ -14,12 +14,12 @@ class CTPInputConfig: def cablingLayout(): inputLayout = odict() inputLayout["optical"] = odict([ - ( "connector0", "Topo1" ), - ( "connector1", "Topo2" ), - ( "connector2", "MuctpiMult" ) + ( "connector0", "Topo1Opt0" ), + ( "connector1", "Topo1Opt1" ), + ( "connector2", "MuCTPiOpt0" ) ]) inputLayout["electrical"] = odict([ - ( "connector0", "Topo3" ), + ( "connector0", "Topo3El" ), ( "connector1", "LegacyTopo0" ), ( "connector2", "AlfaCtpin" ) ]) diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ThresholdDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ThresholdDef.py index a2e1133ad06c3237ae924ee31625a1798418efe4..f0245e030e61508608cf8872b05db8cf395499b0 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ThresholdDef.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Config/ThresholdDef.py @@ -1,6 +1,6 @@ # Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration -from ..Base.Thresholds import Threshold, MuonThreshold, EMThreshold, TauThreshold, JetThreshold, XEThreshold, MBTSThreshold, MBTSSIThreshold, NimThreshold, ThresholdValue +from ..Base.Thresholds import MuonThreshold, EMThreshold, TauThreshold, JetThreshold, XEThreshold, MBTSThreshold, MBTSSIThreshold, NimThreshold, ThresholdValue class ThresholdDef: @@ -262,8 +262,8 @@ class ThresholdDef: LUT5offset = 26 for i, alfa in enumerate( ['B7R1L', 'B7R1U', 'A7R1L', 'A7R1U', 'A7L1L', 'A7L1U', 'B7L1L', 'B7L1U'] ): phaseOffset = 32 * (i%2) - Threshold('ALFA_%s' % alfa, 'ALFA', mapping = LUT1offset + i/2 + phaseOffset, run = 3 ) - Threshold('ALFA2_%s' % alfa, 'ALFA', mapping = LUT2offset + i/2 + phaseOffset, run = 3 ) - Threshold('ALFA3_%s' % alfa, 'ALFA', mapping = LUT3offset + i/2 + phaseOffset, run = 3 ) - Threshold('ALFA4_%s' % alfa, 'ALFA', mapping = LUT4offset + i/2 + phaseOffset, run = 3 ) - Threshold('ALFA_%s_OD' % alfa, 'ALFA', mapping = LUT5offset + i/2 + phaseOffset, run = 3 ) + NimThreshold('ALFA_%s' % alfa, 'ALFA', mapping = LUT1offset + i/2 + phaseOffset ) + NimThreshold('ALFA2_%s' % alfa, 'ALFA', mapping = LUT2offset + i/2 + phaseOffset ) + NimThreshold('ALFA3_%s' % alfa, 'ALFA', mapping = LUT3offset + i/2 + phaseOffset ) + NimThreshold('ALFA4_%s' % alfa, 'ALFA', mapping = LUT4offset + i/2 + phaseOffset ) + NimThreshold('ALFA_%s_OD' % alfa, 'ALFA', mapping = LUT5offset + i/2 + phaseOffset ) diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/L1MenuConfig.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/L1MenuConfig.py index ce5cc26854a54e58ae12a45cde9a532c5ade7a17..108cafb81f1a374bb77774e73f2d18ec0569bd94 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/L1MenuConfig.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/L1MenuConfig.py @@ -255,21 +255,27 @@ class L1MenuConfig(object): log.info("Reading TriggerMenuMT.Menu.Menu_%s", self.menuToLoad) menumodule = __import__('TriggerMenuMT.L1.Menu.Menu_%s' % self.menuToLoad, globals(), locals(), ['defineMenu'], 0) menumodule.defineMenu() - log.info("... L1 menu '%s' contains:", self.menuToLoad) + log.info("... L1 menu '%s' contains %i items", self.menuToLoad, len(L1MenuFlags.items())) log.info("Reading TriggerMenuMT.Menu.Menu_%s_inputs", self.menuToLoad) topomenumodule = __import__('TriggerMenuMT.L1.Menu.Menu_%s_inputs' % self.menuToLoad, globals(), locals(), ['defineMenu'], 0) - topomenumodule.defineInputsMenu() + topomenumodule.defineInputsMenu() # this adds the inputs definition (boards) to L1MenuFlags.boards + connectorCount = 0 algoCount = 0 for boardName, boardDef in L1MenuFlags.boards().items(): if "connectors" in boardDef: + connectorCount += len(boardDef["connectors"]) for c in boardDef["connectors"]: if "thresholds" in c: algoCount += len(c["thresholds"]) - else: + elif "algorithmGroups" in c: for t in c["algorithmGroups"]: algoCount += len(t["algorithms"]) - log.info("... L1Topo menu '%s' contains %i algorithms", self.menuToLoad, algoCount) + else: + for t in c["signalGroups"]: + algoCount += len(t["signals"]) + log.info("... L1Topo menu '%s' contains %i boards (%s)", self.menuToLoad, len(L1MenuFlags.boards()), ', '.join(L1MenuFlags.boards().keys())) + log.info(" with %i connectors and %i input signals", connectorCount, algoCount) try: log.info("Reading TriggerMenuMT.Menu.Menu_%s_inputs_legacy", self.menuToLoad) @@ -483,10 +489,8 @@ class L1MenuConfig(object): list_of_undefined_thresholds = [] # new thresholds for (boardName, boardDef) in L1MenuFlags.boards().items(): - if boardName.startswith("Ctpin"): - continue for connDef in boardDef["connectors"]: - if connDef["format"] != "multiplicity": + if connDef["type"] == "ctpin" or connDef["format"] != "multiplicity": continue for thrName in connDef["thresholds"]: if type(thrName) == tuple: @@ -500,11 +504,29 @@ class L1MenuConfig(object): else: self.l1menu.addThreshold( threshold ) + # signals from merger boards like AlfaCtpin + for (boardName, boardDef) in L1MenuFlags.boards().items(): + for connDef in boardDef["connectors"]: + if connDef["format"] != "simple": + continue + for sGrp in connDef["signalGroups"]: + for thrName in sGrp["signals"]: + if type(thrName) == tuple: + (thrName, _) = thrName + if thrName is None or thrName in self.l1menu.thresholds: + continue + threshold = self.getDefinedThreshold(thrName) + if threshold is None: + log.error('Threshold %s is required in menu on board %s, connector %s, but it is not defined', (thrName, boardName, connDef['name']) ) + list_of_undefined_thresholds += [ thrName ] + else: + self.l1menu.addThreshold( threshold ) + # ctpin thresholds for (boardName, boardDef) in allBoards: - if not boardName.startswith("Ctpin"): - continue for connDef in boardDef["connectors"]: + if connDef["type"] != "ctpin": + continue for entry in connDef["thresholds"]: if type(entry) == dict: # section that defines topo legacy thresholds @@ -614,13 +636,17 @@ class L1MenuConfig(object): # assign mapping to thresholds according to their use in the menu self.mapThresholds() - # update the prescales that are not 1 - #self.updateItemPrescales() + # ------------------ + # CTP + # ------------------ + self.l1menu.ctp.checkConnectorAvailability(self.l1menu.connectors, self.menuToLoad) # set the ctp monitoring (only now after the menu is defined) self.l1menu.setupCTPMonitoring() + # ------------------ # final consistency check + # ------------------ self.l1menu.check() diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8.py index 4aadf7d0802bba1bbe8e1c6d492be369f2b77ddd..7fe12371ce13c288d92e7d3839f1c0151966ae80 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8.py @@ -383,7 +383,12 @@ def defineMenu(): #ATR-17320 'L1_CEP-CJ60', 'L1_CEP-CJ50' , - 'L1_CEP-CJ50.ETA21' + 'L1_CEP-CJ50.ETA21', + + 'L1_ALFA_ANY', + 'L1_ALFA_ELAST15', 'L1_ALFA_ELAST18', + 'L1_ALFA_B7L1U','L1_ALFA_B7L1L','L1_ALFA_A7L1U','L1_ALFA_A7L1L','L1_ALFA_A7R1U','L1_ALFA_A7R1L','L1_ALFA_B7R1U','L1_ALFA_B7R1L', # L1_ALFA_Calib + 'L1_ALFA_SYST9', 'L1_ALFA_SYST10', 'L1_ALFA_SYST11', 'L1_ALFA_SYST12', 'L1_ALFA_SYST17', 'L1_ALFA_SYST18', # L1_ALFA_SYS, L1_ALFA_SYS_Calib ] diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8_inputs.py b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8_inputs.py index 71c27e2df737ce43a016970c819164bedd0c0686..9ba531fffcf73034790ea34f8113dca2f93c364d 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8_inputs.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/L1/Menu/Menu_MC_pp_v8_inputs.py @@ -11,6 +11,7 @@ def defineInputsMenu(): ctpinBoards = odict() # Ctpin/Slot9 (CTPCAL, NIM1, NIM2) topoBoards = odict() # Topo1, Topo2, Topo3 muctpiBoard = odict() # MuCTPi + alfaBoard = odict() # ALFA #----------------------------------- @@ -320,6 +321,39 @@ def defineInputsMenu(): ] }) + + alfaBoard["AlfaCtpin"] = odict() + alfaBoard["AlfaCtpin"]["connectors"] = [] + alfaBoard["AlfaCtpin"]["connectors"].append({ + "name" : "AlfaCtpin", + "format" : "simple", + "nbitsDefault" : 1, + "type" : "electrical", + "legacy" : False, + "signalGroups" : [ + { + "clock" : 0, + "signals" : [ + (None,2), "ALFA_B7R1L", "ALFA_A7R1L", "ALFA_A7L1L", "ALFA_B7L1L", + (None,2), "ALFA2_B7R1L", "ALFA2_A7R1L", "ALFA2_A7L1L", "ALFA2_B7L1L", + (None,2), "ALFA3_B7R1L", "ALFA3_A7R1L", "ALFA3_A7L1L", "ALFA3_B7L1L", + (None,2), "ALFA4_B7R1L", "ALFA4_A7R1L", "ALFA4_A7L1L", "ALFA4_B7L1L" + ] + }, + { + "clock" : 1, + "signals" : [ + (None,2), "ALFA_B7R1U", "ALFA_A7R1U", "ALFA_A7L1U", "ALFA_B7L1U", + (None,2), "ALFA2_B7R1U", "ALFA2_A7R1U", "ALFA2_A7L1U", "ALFA2_B7L1U", + (None,2), "ALFA3_B7R1U", "ALFA3_A7R1U", "ALFA3_A7L1U", "ALFA3_B7L1U", + (None,2), "ALFA4_B7R1U", "ALFA4_A7R1U", "ALFA4_A7L1U", "ALFA4_B7L1U", + (None,2), "ALFA_B7R1U_OD", "ALFA_A7R1U_OD", "ALFA_A7L1U_OD", "ALFA_B7L1U_OD" + ] + } + ] + }) + + L1MenuFlags.boards().clear() L1MenuFlags.boards().update( topoBoards ) # Topo1, Topo2, Topo3 @@ -328,3 +362,5 @@ def defineInputsMenu(): L1MenuFlags.boards().update( ctpinBoards ) # CTPIN/Slot9 NIM1, NIM2, CALREQ + L1MenuFlags.boards().update( alfaBoard ) # ALFA +