diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h index 8e7f9217a131f4e1f84aa9388373b68f124c53e9..05dccca5f200c3814d9a8c50925245503a499246 100644 --- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h +++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h @@ -132,7 +132,6 @@ namespace TrigConf { /** Board names */ std::vector<std::string> boardNames() const; - /** Access to connector by name */ const TrigConf::L1Connector & connector(const std::string & connectorName) const; @@ -148,6 +147,8 @@ namespace TrigConf { /** print overview of L1 Menu */ void printMenu(bool full = false) const; + bool isRun2() const { return m_run<3; } + private: /** Update the internal data after modification of the data object */ @@ -156,6 +157,8 @@ namespace TrigConf { /** the supermasterkey */ unsigned int m_smk {0}; + unsigned int m_run{3}; // this variable is set to 2 for L1 menus from Run 2 which have a much reduced content + /** connector by name */ std::map<std::string, TrigConf::L1Connector> m_connectors{}; diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx index 4a6b69032195aa403e0a4992dc3b1465b5762729..095d448ccb0deacb9cdb7f7e64d1d3a3b9d304c4 100644 --- a/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx +++ b/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx @@ -26,9 +26,10 @@ TrigConf::L1CTP::load() for(size_t i=0; i<3; ++i) { m_electrical[i] = electrical.get_optional<std::string>("connector" + std::to_string(i)).get_value_or(""); } - auto optical = inputs.get_child("optical"); - for(size_t i=0; i<12; ++i) { - m_optical[i] = optical.get_optional<std::string>("connector" + std::to_string(i)).get_value_or(""); + if(auto optical = inputs.get_child_optional("optical")) { + for(size_t i=0; i<12; ++i) { + m_optical[i] = optical->get_optional<std::string>("connector" + std::to_string(i)).get_value_or(""); + } } for( auto & mon : data().get_child("monitoring.ctpmon") ) { std::string monName = mon.first; diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx index 47786a9c510087d429bcc696c246f5ec561b9004..f8bd3fa463e36562ca415b15e9224dca259906ec 100644 --- a/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx +++ b/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration */ #include "TrigConfData/L1Menu.h" @@ -25,9 +25,12 @@ TrigConf::L1Menu::update() if(! isInitialized() || empty() ) { return; } + + m_run = getAttribute_optional<int>("run").value_or(3); + + // thresholds try { m_name = getAttribute("name"); - // thresholds for( const std::string path : {"thresholds", "thresholds.legacyCalo" } ) { for( auto & thrByType : data().get_child( path ) ) { const std::string & thrType = thrByType.first; @@ -63,8 +66,8 @@ TrigConf::L1Menu::update() throw; } + // boards try { - // boards for( auto & board : data().get_child( "boards" ) ) { m_boards.emplace( std::piecewise_construct, std::forward_as_tuple(board.first), @@ -76,8 +79,8 @@ TrigConf::L1Menu::update() throw; } + // connectors try { - // connectors for( auto & conn : data().get_child( "connectors" ) ) { auto res = m_connectors.emplace( std::piecewise_construct, std::forward_as_tuple(conn.first), @@ -94,9 +97,10 @@ TrigConf::L1Menu::update() throw; } + // algorithms try { - // algorithms - for( const std::string algoCategory : { "TOPO", "MULTTOPO", "MUTOPO", "R2TOPO" } ) { + auto topoCategories = isRun2() ? std::vector<std::string> {"R2TOPO"} : std::vector<std::string> {"TOPO", "MUTOPO", "MULTTOPO", "R2TOPO"}; + for( const std::string algoCategory : topoCategories ) { auto & v = m_algorithmsByCategory[algoCategory] = std::vector<TrigConf::L1TopoAlgorithm>(); if(algoCategory == "MULTTOPO") { for( auto & alg : data().get_child( "topoAlgorithms." + algoCategory + ".multiplicityAlgorithms" ) ) { @@ -131,8 +135,8 @@ TrigConf::L1Menu::update() throw; } + // CTP try { - // CTP m_ctp.setData(data().get_child("ctp")); } catch(std::exception & ex) { diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1PrescalesSet.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1PrescalesSet.cxx index c2d6e75ecdb870e3aa6a246f17d39f0176fcce0f..61152f233e14a9f2f82e83a23a5d26afc0d97f90 100644 --- a/Trigger/TrigConfiguration/TrigConfData/src/L1PrescalesSet.cxx +++ b/Trigger/TrigConfiguration/TrigConfData/src/L1PrescalesSet.cxx @@ -68,6 +68,6 @@ TrigConf::L1PrescalesSet::prescales() const { */ double TrigConf::L1PrescalesSet::getPrescaleFromCut(uint32_t cut) const { - return 0xFFFFFF / ( 0x1000000 - cut ); + return static_cast<double>(0xFFFFFF) / ( 0x1000000 - cut ); } diff --git a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/JsonFileWriter.h b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/JsonFileWriterL1.h similarity index 82% rename from Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/JsonFileWriter.h rename to Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/JsonFileWriterL1.h index dc654f4b47dc2b172fd2c301da86f2dba979f5e5..d3a6a5accc68dfc02124cedddb2855e8497aa962 100644 --- a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/JsonFileWriter.h +++ b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/JsonFileWriterL1.h @@ -7,8 +7,8 @@ * To validate correct loading of the L1 menu */ -#ifndef TRIGCONFSTORAGE_JSONFILEWRITER_H -#define TRIGCONFSTORAGE_JSONFILEWRITER_H +#ifndef TRIGCONFSTORAGE_JSONFILEWRITERL1_H +#define TRIGCONFSTORAGE_JSONFILEWRITERL1_H #include "TrigConfBase/TrigConfMessaging.h" #include "TrigConfData/L1Menu.h" @@ -20,11 +20,11 @@ namespace TrigConf { /** * @brief Loader of trigger configurations from Json files */ - class JsonFileWriter : public TrigConfMessaging { + class JsonFileWriterL1 : public TrigConfMessaging { public: /** Constructor */ - JsonFileWriter(); + JsonFileWriterL1(); bool writeJsonFile(const std::string & filename, const L1Menu & l1menu) const; bool writeJsonFile(const std::string & filename, const L1BunchGroupSet & l1bgs) const; diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterHLT.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterHLT.cxx index cebb43cc81499002d2474bf9b9d6a0514d99cbdb..eb1a38ac4df2ce1828164220ae420cd850cde807 100644 --- a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterHLT.cxx +++ b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterHLT.cxx @@ -14,7 +14,7 @@ using json = nlohmann::json; using namespace std; TrigConf::JsonFileWriterHLT::JsonFileWriterHLT() : - TrigConfMessaging( "JsonFileWriter") + TrigConfMessaging( "JsonFileWriterHLT") {} @@ -87,4 +87,4 @@ TrigConf::JsonFileWriterHLT::writeJsonFile(const std::string & filename, const H TRG_MSG_INFO("Saved file " << filename); return true; -} \ No newline at end of file +} diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterL1.cxx similarity index 93% rename from Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx rename to Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterL1.cxx index 2d397e3744ac39c8b9df7beabca7d7d7efcdb88b..ddbeb68508d5d20004f1e6413688e46bbabffad3 100644 --- a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx +++ b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterL1.cxx @@ -1,8 +1,6 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ +// Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration -#include "TrigConfIO/JsonFileWriter.h" +#include "TrigConfIO/JsonFileWriterL1.h" #include <iomanip> #include <fstream> @@ -13,13 +11,13 @@ using json = nlohmann::json; using namespace std; -TrigConf::JsonFileWriter::JsonFileWriter() : - TrigConfMessaging( "JsonFileWriter") +TrigConf::JsonFileWriterL1::JsonFileWriterL1() : + TrigConfMessaging( "JsonFileWriterL1") {} bool -TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Menu & l1menu) const +TrigConf::JsonFileWriterL1::writeJsonFile(const std::string & filename, const L1Menu & l1menu) const { json items({}); @@ -36,7 +34,7 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me jItem["legacy"] = *legacy; items[item.name()] = jItem; }; - + json thresholds({}); for(const std::string & thrType : l1menu.thresholdTypes()) { json jThresholsByType({}); @@ -93,6 +91,7 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me jThr["thrValues"] = json::array_t({}); for(auto & rv : EMThr.thrValues()) { json jRV({}); + jRV["value"] = static_cast<unsigned int>(rv.value()); jRV["etamin"] = rv.etaMin(); jRV["etamax"] = rv.etaMax(); jRV["phimin"] = 0; // never used, so not read @@ -104,7 +103,6 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me } jRV["isobits"] = isobits; jRV["priority"] = rv.priority(); - jRV["value"] = (unsigned int)rv.value(); jThr["thrValues"] += jRV; } } catch(std::bad_cast&) {}; @@ -114,13 +112,13 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me jThr["thrValues"] = json::array_t({}); for(auto & rv : JThr.thrValues()) { json jRV({}); + jRV["value"] = static_cast<unsigned int>(rv.value()); jRV["etamin"] = rv.etaMin(); jRV["etamax"] = rv.etaMax(); jRV["phimin"] = 0; // never used, so not read jRV["phimax"] = 64; // never used, so not read - jRV["priority"] = rv.priority(); jRV["window"] = JThr.window(0); - jRV["value"] = (unsigned int)rv.value(); + jRV["priority"] = rv.priority(); jThr["thrValues"] += jRV; } } catch(std::bad_cast&) {}; @@ -130,10 +128,10 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me //jThr["thrValues"] = json::array_t({}); for(auto & rv : teThr.thrValues()) { json jRV({}); + jRV["value"] = static_cast<unsigned int>(rv.value()); jRV["etamin"] = rv.etaMin(); jRV["etamax"] = rv.etaMax(); jRV["priority"] = rv.priority(); - jRV["value"] = (unsigned int)rv.value(); jThr["thrValues"] += jRV; } } catch(std::bad_cast&) {}; @@ -151,13 +149,13 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me jThr["reta"] = TrigConf::Selection::wpToString(eEMThr.reta()); jThr["rhad"] = TrigConf::Selection::wpToString(eEMThr.rhad()); jThr["wstot"] = TrigConf::Selection::wpToString(eEMThr.wstot()); - jThr["thrValues"] = json::array_t({}); + jThr["thrValues"] = json::value_t::array; for(auto & rv : eEMThr.thrValues()) { json jRV({}); + jRV["value"] = static_cast<unsigned int>(rv.value()); jRV["etamin"] = rv.etaMin(); jRV["etamax"] = rv.etaMax(); jRV["priority"] = rv.priority(); - jRV["value"] = (unsigned int)rv.value(); jThr["thrValues"] += jRV; } } catch(std::bad_cast&) {}; @@ -167,10 +165,10 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me jThr["ranges"] = json::array_t({}); for(auto & rv : jJThr.thrValues()) { json jRV({}); + jThr["value"] = int(jJThr.thrValue(rv.etaMin())); jRV["etamin"] = rv.etaMin(); jRV["etamax"] = rv.etaMax(); jThr["ranges"] += jRV; - jThr["value"] = int(jJThr.thrValue(rv.etaMin())); } } catch(std::bad_cast&) {}; @@ -208,6 +206,7 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me if(thrType == "MU") { auto & muinfo = l1menu.thrExtraInfo().MU(); + jThrType["exclusionLists"] = json::value_t::object; for(auto & listName : muinfo.exclusionListNames()) { jThrType["exclusionLists"][listName] = json::array_t({}); for(auto & x : muinfo.exclusionList(listName)) { @@ -331,7 +330,7 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me }; - json boards{}; + json boards; for( auto & bname : l1menu.boardNames() ) { auto & bdef = l1menu.board(bname); boards[bname] = json{ {"connectors", bdef.connectorNames()}, {"type", bdef.type()} }; @@ -340,7 +339,7 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me }; - json connectors{}; + json connectors; for( auto & cname : l1menu.connectorNames() ) { auto jConn = json{}; auto & cdef = l1menu.connector(cname); @@ -378,7 +377,7 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me connectors[cname] = jConn; } - json ctp({}); + json ctp; { for(size_t slot=7; slot<=9; ++slot) { std::string sName = "slot" + std::to_string(slot); @@ -404,15 +403,15 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me ctp["monitoring"] = json({{"ctpmon",ctpmon}}); } - json jtopo({}); + json jtopo; { std::map<L1TopoAlgorithm::AlgorithmType,std::string> algTypeNames = { {L1TopoAlgorithm::AlgorithmType::SORTING, "sortingAlgorithms"}, {L1TopoAlgorithm::AlgorithmType::DECISION, "decisionAlgorithms"}, {L1TopoAlgorithm::AlgorithmType::MULTIPLICITY, "multiplicityAlgorithms"} }; - - for( const std::string topoCat : {"TOPO", "MUTOPO", "MULTTOPO", "R2TOPO"} ) { + auto topoCategories = l1menu.isRun2() ? std::vector<std::string> {"R2TOPO"} : std::vector<std::string> {"TOPO", "MUTOPO", "MULTTOPO", "R2TOPO"}; + for( const std::string topoCat : topoCategories ) { for(auto & algName : l1menu.topoAlgorithmNames(topoCat)) { json jalg = json::object_t({}); auto & alg = l1menu.algorithm(algName,topoCat); @@ -474,8 +473,11 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me } } - json j({}); + json j; j["filetype"] = "l1menu"; + if(l1menu.isRun2()) { + j["run"] = 2; + } j["name"] = l1menu.name(); j["items"] = items; j["thresholds"] = thresholds; @@ -494,19 +496,19 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me bool -TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const TrigConf::L1BunchGroupSet & l1bgs) const { +TrigConf::JsonFileWriterL1::writeJsonFile(const std::string & filename, const TrigConf::L1BunchGroupSet & l1bgs) const { - json j({}); + json j; j["filetype"] = "bunchgroupset"; j["name"] = l1bgs.name(); - json groups({}); + json groups; for (size_t i = 0 ; i< l1bgs.size(); ++i) { auto group = l1bgs.getBunchGroup(i); json jgroup({}); jgroup["name"] = group->name(); jgroup["id"] = group->id(); - jgroup["info"] = std::to_string(group->size()) + "bunchs, " + std::to_string(group->nGroups()) + " groups"; + jgroup["info"] = std::to_string(group->size()) + " bunches, " + std::to_string(group->nGroups()) + " groups"; json trains = json::array(); for (auto [first, len]: group->trains()) { json train({}); @@ -524,13 +526,13 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const Trig return true; } -bool TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const TrigConf::L1PrescalesSet & l1ps) const { - json j({}); +bool TrigConf::JsonFileWriterL1::writeJsonFile(const std::string & filename, const TrigConf::L1PrescalesSet & l1ps) const { + json j; j["filetype"] = "l1prescale"; j["name"] = l1ps.name(); - json cuts({}); + json cuts; for ( auto [itemName, ps]: l1ps.prescales()){ - json cut({}); + json cut; cut["cut"] = ps.cut; cut["enabled"] = ps.enabled; cut["info"] = "prescale: " + std::to_string(ps.prescale); diff --git a/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx b/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx index 02843ecb141269843d33b8fd310f836b9e84a7ac..2189df1e4345b1a72c2315dbb29a9011f0328202 100644 --- a/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx +++ b/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx @@ -6,7 +6,7 @@ #include <vector> #include "TrigConfIO/JsonFileLoader.h" -#include "TrigConfIO/JsonFileWriter.h" +#include "TrigConfIO/JsonFileWriterL1.h" #include "TrigConfIO/JsonFileWriterHLT.h" #include "TrigConfIO/TrigDBMenuLoader.h" #include "TrigConfIO/TrigDBJobOptionsLoader.h" @@ -178,7 +178,7 @@ namespace { } filename += ".fromDS.json"; if ( kind=="L1Menu" ) { - TrigConf::JsonFileWriter fileWriter; + TrigConf::JsonFileWriterL1 fileWriter; const auto & l1menu = dynamic_cast<const TrigConf::L1Menu &>(ds); return fileWriter.writeJsonFile(filename, l1menu); } else if ( kind == "HLTMenu") { diff --git a/Trigger/TrigConfiguration/TrigConfStorage/CMakeLists.txt b/Trigger/TrigConfiguration/TrigConfStorage/CMakeLists.txt index ce1638de850de11d8ef2e4c9ed999c5af6151e57..35b801d9ccbe7e74f89767bc412514c523e19024 100644 --- a/Trigger/TrigConfiguration/TrigConfStorage/CMakeLists.txt +++ b/Trigger/TrigConfiguration/TrigConfStorage/CMakeLists.txt @@ -27,7 +27,7 @@ atlas_add_executable( TrigConfConsistencyChecker LINK_LIBRARIES TrigConfStorage ) atlas_add_executable( TrigConfReadWrite - src/test/ReadWrite.cxx src/test/Run2toRun3Converters.cxx + src/test/ReadWrite.cxx src/test/Run2toRun3ConvertersL1.cxx src/test/Run2toRun3ConvertersHLT.cxx LINK_LIBRARIES L1TopoConfig TrigConfJobOptData TrigConfStorage TrigConfData TrigConfIO TrigCompositeUtilsLib ) atlas_add_executable( TrigConfCoolFix diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/MasterTableLoader.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/MasterTableLoader.cxx index 53f81e0f7e95dcc34609611d55f0a62987f69ab1..0182282f3055f17f406336f3ae3fd2bc48d8f534 100755 --- a/Trigger/TrigConfiguration/TrigConfStorage/src/MasterTableLoader.cxx +++ b/Trigger/TrigConfiguration/TrigConfStorage/src/MasterTableLoader.cxx @@ -18,7 +18,7 @@ using namespace std; bool -TrigConf::MasterTableLoader::loadMasterKeys(int SuperMasterKey, int& Lvl1MasterKey) { +TrigConf::MasterTableLoader::loadMasterKeys(int SuperMasterKey, int& Lvl1MasterKey, std::string & menuName) { try { startSession(); @@ -36,8 +36,10 @@ TrigConf::MasterTableLoader::loadMasterKeys(int SuperMasterKey, int& Lvl1MasterK //Output data and types coral::AttributeList attList; attList.extend<int>( "SMT_L1_MASTER_TABLE_ID" ); + attList.extend<std::string>( "SMT_NAME" ); query->defineOutput(attList); query->addToOutputList( "SMT_L1_MASTER_TABLE_ID" ); + query->addToOutputList( "SMT_NAME" ); coral::ICursor& cursor = query->execute(); @@ -50,6 +52,7 @@ TrigConf::MasterTableLoader::loadMasterKeys(int SuperMasterKey, int& Lvl1MasterK const coral::AttributeList& row = cursor.currentRow(); Lvl1MasterKey = row["SMT_L1_MASTER_TABLE_ID"].data<int>(); + menuName = row["SMT_NAME"].data<std::string>(); delete query; commitSession(); @@ -81,7 +84,8 @@ TrigConf::MasterTableLoader::load(ThresholdConfig& thrcfg) { return false; } int Lvl1MasterKey(0); - loadMasterKeys(SuperMasterKey, Lvl1MasterKey); + std::string menuName{""}; + loadMasterKeys(SuperMasterKey, Lvl1MasterKey, menuName); thrcfg.setLvl1MasterTableId(Lvl1MasterKey); } try { @@ -109,12 +113,13 @@ TrigConf::MasterTableLoader::load(CTPConfig& ctpc) { int Lvl1MasterKey(0); msg() << "Load L1 master key" << std::endl; - - loadMasterKeys(SuperMasterKey, Lvl1MasterKey); + std::string menuName{""}; + loadMasterKeys(SuperMasterKey, Lvl1MasterKey, menuName); msg() << "Loaded L1 master key" << Lvl1MasterKey << std::endl; ctpc.setLvl1MasterTableId(Lvl1MasterKey); + ctpc.setName(menuName); } try { CTPConfigLoader& ctpLoader = @@ -144,7 +149,8 @@ TrigConf::MasterTableLoader::load(Muctpi& m) { return false; } int Lvl1MasterKey(0); - loadMasterKeys(SuperMasterKey, Lvl1MasterKey); + std::string menuName{""}; + loadMasterKeys(SuperMasterKey, Lvl1MasterKey, menuName); m.setLvl1MasterTableId(Lvl1MasterKey); } try { diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/MasterTableLoader.h b/Trigger/TrigConfiguration/TrigConfStorage/src/MasterTableLoader.h index ee4eb3da830da8e2c7ab32d7b54f769e8129d064..5507a1ab0df8908d3906228918bcfcf540dc4b1f 100644 --- a/Trigger/TrigConfiguration/TrigConfStorage/src/MasterTableLoader.h +++ b/Trigger/TrigConfiguration/TrigConfStorage/src/MasterTableLoader.h @@ -1,15 +1,14 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration */ #ifndef TrigConf_MasterTableLoader #define TrigConf_MasterTableLoader -/* - MasterTableLoader.h -*/ + #include "TrigConfStorage/IMasterTableLoader.h" #include "TrigConfStorage/DBLoader.h" +#include <string> namespace TrigConf { @@ -34,7 +33,8 @@ namespace TrigConf { bool load(CTPConfig& ctpc); bool load(Muctpi& muctpi); bool load(TXC::L1TopoMenu& l1topo); - bool loadMasterKeys(int SuperMasterKey, int& Lvl1MasterKey); + private: + bool loadMasterKeys(int SuperMasterKey, int& Lvl1MasterKey, std::string & menuName); /**@brief next run configuration key (depreciated)*/ int mt_id_for_next_run(); diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/XMLMenuLoader.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/XMLMenuLoader.cxx index 3fd6b362df4b6bee5a90f333d7e9bce0a5e0fb1c..aed8b5903fb6e321f65df2e805989baa62a08b64 100755 --- a/Trigger/TrigConfiguration/TrigConfStorage/src/XMLMenuLoader.cxx +++ b/Trigger/TrigConfiguration/TrigConfStorage/src/XMLMenuLoader.cxx @@ -74,7 +74,6 @@ TrigConf::XMLMenuLoader::load(Menu& menu) { if(sval.find("TAP") != string::npos) monMask |= TAP; if(sval.find("TAV") != string::npos) monMask |= TAV; } - //cout << "JOERG " << sval << " ==> " << monMask << endl; item->setMonitor( monMask ); } diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx index e30268258923c407922a61383a3d3dbf0b3af5bd..55ebc06ccf567afce6223370b51b76d120a1c1d4 100644 --- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx +++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx @@ -42,7 +42,8 @@ #include "TrigConfHLTData/HLTPrescaleSet.h" #include "TrigConfJobOptData/JobOptionTable.h" -#include "Run2toRun3Converters.h" +#include "Run2toRun3ConvertersL1.h" +#include "Run2toRun3ConvertersHLT.h" #include "CoolKernel/DatabaseId.h" #include "CoolKernel/Exception.h" @@ -68,48 +69,48 @@ using namespace std; using namespace TrigConf; void printhelp(std::ostream & o, std::ostream& (*lineend) ( std::ostream& os )) { - o << "================================================================================\n"; - o << "The program needs to be run with the following specifications:\n" << lineend; - o << "TrigConfReadWrite <options>\n"; - o << "\n"; - o << "[Global options]\n"; - o << " -i|--input input [input [input]] ... source of configuration, format see below (mandatory)\n"; - o << " -2|--comp input [input [input]] ... source of a second configuration for comparison\n"; - o << " -o|--output xml|r3json|cool [output[;cooldb]] [run] ... output format, name (for cool optional run number)\n"; - o << " ... absolute output file name must contain '/', cooldb can be appended COMP200|OFLP200\n"; - o << " -v|--loglevel <string> ... log level [NIL, VERBOSE, DEBUG, INFO, WARNING, ERROR, FATAL, ALWAYS]\n"; - o << " -l|--log <string> ... name of a log file\n"; - o << " --jo ... read and write job options where possible\n"; - o << " --fw ... read ctp firmware\n"; - o << " -p|--print <int> ... print configuration with detail 0...5 (default 1)\n"; - o << " -h|--help ... this output\n"; - o << " --nomerge ... internally don't merge L2 and EF (by default merge is enabled)\n"; - o << "\n\n"; - o << "Input can be specified the following\n"; - o << " -i [l1menu.xml] [hltmenu2.xml] ... to read L1 and/or HLT menu from XML [file names must end with '.xml'\n"; - o << " -i <TRIGDB_ALIAS>|<TRIGDB_connection> smk[,l1psk,hltpsk,bgsk] ... to read the menu from a trigger db via alias or explicit connection specification (ORACLE or SQlite)\n"; - o << " -i <COOLDB_ALIAS>|<COOLDB_connection>|cool.db run[,lb] ... to read the menu from COOL for a certain run and possibly LB [file names must end with '.db']\n"; - o << "\n"; - o << "The cool dbconnection can be specified as one of the following\n"; - o << " - via alias : COOLONL_TRIGGER (use COOLONL_TRIGGER/COMP200 for Run 1 data)"; - o << " - from sqlite : cool.db (use cool.db;COMP200 for Run 1 data)"; - o << "\n"; - o << "\n"; - o << "Input for comparison can be specified the same way, using the '-2' or '--comp' option\n"; - o << "\n"; - o << "\n"; - o << "Output formats can be xml or cool. In case a second input is specified for comparison, the output will be on screen or an xml file with the differences\n"; - o << " -o xml test ... will produce LVL1config_test.xml and/or HLTconfig_test.xml. When\n"; - o << " comparing two menus this will produce Diff_test.xml. In this case the\n"; - o << " specification of '-o test' is sufficient\n"; - o << " -o r3json test ... will produce Run3 JSON LVL1Menu_test.json and HLTMenu_test.json\n"; - o << " -o cool ... will produce trig_cool.db with cool db instance CONDBR2 and infinite IOV\n"; - o << " -o cool 200000 ... will produce trig_cool.db with cool db instance CONDBR2 and run number 200000\n"; - o << " -o cool test [200000] ... will produce trig_cool_test.db with cool db instance CONDBR2 [and run number 200000]\n"; - o << " -o cool ../test.db [200000] ... will produce ../test.db with cool db instance CONDBR2 [and run number 200000]\n"; - o << " -o cool 'test;COMP200' [200000] ... will produce Menu_test.db with cool db instance COMP200 [and run number 200000]\n"; - o << "\n"; - o << "================================================================================\n"; + o << "================================================================================\n"; + o << "The program needs to be run with the following specifications:\n" << lineend; + o << "TrigConfReadWrite <options>\n"; + o << "\n"; + o << "[Global options]\n"; + o << " -i|--input input [input [input]] ... source of configuration, format see below (mandatory)\n"; + o << " -2|--comp input [input [input]] ... source of a second configuration for comparison\n"; + o << " -o|--output xml|r3json|cool [output[;cooldb]] [run] ... output format, name (for cool optional run number)\n"; + o << " ... absolute output file name must contain '/', cooldb can be appended COMP200|OFLP200\n"; + o << " -v|--loglevel <string> ... log level [NIL, VERBOSE, DEBUG, INFO, WARNING, ERROR, FATAL, ALWAYS]\n"; + o << " -l|--log <string> ... name of a log file\n"; + o << " --jo ... read and write job options where possible\n"; + o << " --fw ... read ctp firmware\n"; + o << " -p|--print <int> ... print configuration with detail 0...5 (default 1)\n"; + o << " -h|--help ... this output\n"; + o << " --nomerge ... internally don't merge L2 and EF (by default merge is enabled)\n"; + o << "\n\n"; + o << "Input can be specified the following\n"; + o << " -i [l1menu.xml] [hltmenu2.xml] ... to read L1 and/or HLT menu from XML [file names must end with '.xml'\n"; + o << " -i <TRIGDB_ALIAS>|<TRIGDB_connection> smk[,l1psk,hltpsk,bgsk] ... to read the menu from a trigger db via alias or explicit connection specification (ORACLE or SQlite)\n"; + o << " -i <COOLDB_ALIAS>|<COOLDB_connection>|cool.db run[,lb] ... to read the menu from COOL for a certain run and possibly LB [file names must end with '.db']\n"; + o << "\n"; + o << "The cool dbconnection can be specified as one of the following\n"; + o << " - via alias : COOLONL_TRIGGER (use COOLONL_TRIGGER/COMP200 for Run 1 data)"; + o << " - from sqlite : cool.db (use cool.db;COMP200 for Run 1 data)"; + o << "\n"; + o << "\n"; + o << "Input for comparison can be specified the same way, using the '-2' or '--comp' option\n"; + o << "\n"; + o << "\n"; + o << "Output formats can be xml or cool. In case a second input is specified for comparison, the output will be on screen or an xml file with the differences\n"; + o << " -o xml [<test>] ... will produce LVL1config_test.xml and/or HLTconfig_test.xml. When\n"; + o << " comparing two menus this will produce Diff_test.xml. In this case the\n"; + o << " specification of '-o test' is sufficient\n"; + o << " -o r3json [<test>] ... will produce Run 3 config files L1PrescalesSet[_<test>].json, BunchGroups[_<test>].json, L1Menu[_<test>].json, HLTPrescalesSet[_<test>].json, and HLTMenu[_<test>].json\n"; + o << " -o cool ... will produce trig_cool.db with cool db instance CONDBR2 and infinite IOV\n"; + o << " -o cool 200000 ... will produce trig_cool.db with cool db instance CONDBR2 and run number 200000\n"; + o << " -o cool test [200000] ... will produce trig_cool_test.db with cool db instance CONDBR2 [and run number 200000]\n"; + o << " -o cool ../test.db [200000] ... will produce ../test.db with cool db instance CONDBR2 [and run number 200000]\n"; + o << " -o cool 'test;COMP200' [200000] ... will produce Menu_test.db with cool db instance COMP200 [and run number 200000]\n"; + o << "\n"; + o << "================================================================================\n"; } class JobConfig { @@ -130,10 +131,12 @@ public: string l1xmlOutFile { "LVL1Config.xml" }; string l1topoOutFile { "L1TopoConfig.xml" }; string hltxmlOutFile { "HLTConfig.xml" }; + + string l1JsonOutFile {"L1Menu.json"}; + string bgkJsonOutFile {"BunchGroups.json"}; + string l1PSJsonOutFile { "L1PrescalesSet.json" }; string hltJsonOutFile { "HLTMenu.json" }; string hltPSJsonOutFile { "HLTPrescalesSet.json" }; - string bgkJsonOutFile {"BunchGroups.json"}; - string l1PSJsonOutFile {"L1PrescalesSet.json"}; string coolInputConnection { "" }; string coolOutputConnection { "" }; @@ -322,10 +325,12 @@ JobConfig::parseProgramOptions(int argc, char* argv[]) { l1xmlOutFile = "LVL1config_" + outBase + ".xml"; l1topoOutFile = "L1TopoConfig_" + outBase + ".xml"; hltxmlOutFile = "HLTconfig_" + outBase + ".xml"; + + l1JsonOutFile = "L1Menu_" + outBase + ".json"; + bgkJsonOutFile = "BunchGroups_" + outBase + ".json"; + l1PSJsonOutFile = "L1PrescaleSet_" + outBase + ".json"; hltJsonOutFile = "HLTMenu_" + outBase + ".json"; hltPSJsonOutFile = "HLTPrescalesSet_" + outBase + ".json"; - bgkJsonOutFile = "BunchGroups_" + outBase + ".json"; - l1PSJsonOutFile = "L1PrescaleSet_" + outBase + ".json"; } } @@ -683,14 +688,15 @@ int main( int argc, char* argv[] ) { /*------------------ * to JSON *-----------------*/ - // TODO add L1 menu + if(ctpc && l1tm) { + convertRun2L1MenuToRun3(ctpc, l1tm, gConfig.l1JsonOutFile); + convertRun2L1PrescalesToRun3(ctpc, gConfig.l1PSJsonOutFile); + convertRun2BunchGroupsToRun3(ctpc, gConfig.bgkJsonOutFile); + } if(hltFrame) { convertRun2HLTMenuToRun3(hltFrame, gConfig.hltJsonOutFile); convertRun2HLTPrescalesToRun3(hltFrame, gConfig.hltPSJsonOutFile); - convertRun2BunchGroupsToRun3(ctpc, gConfig.bgkJsonOutFile); - convertRun2L1PrescalesToRun3(ctpc, gConfig.l1PSJsonOutFile); } - } if ( (gConfig.output & JobConfig::COOL) != 0 ) { @@ -706,18 +712,21 @@ int main( int argc, char* argv[] ) { unsigned int runNr = gConfig.coolOutputRunNr; if(runNr == 0) { runNr = 0x80000000; } // infinite range - if(ctpc) + if(ctpc) { coolWriter->writeL1Payload(runNr, *ctpc); + } try{ - if(hltFrame) - coolWriter->writeHLTPayload(runNr, *hltFrame, configSource); + if(hltFrame) { + coolWriter->writeHLTPayload(runNr, *hltFrame, configSource); + } } catch(const cool::StorageTypeStringTooLong& e){ - log << "FATAL: Unable to write data to COOL"; - exit(1); + log << "FATAL: Unable to write data to COOL"; + exit(1); } - if(mck) + if(mck) { coolWriter->writeMCKPayload(runNr, mck, release, info); + } } delete ctpc; diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.h b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.h deleted file mode 100644 index a925168509a4d560ffca50e44c7bb6672b7ffbb8..0000000000000000000000000000000000000000 --- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TrigConfData/HLTMenu.h" -#include "TrigConfHLTData/HLTFrame.h" -#include "TrigConfL1Data/CTPConfig.h" -void convertRun2HLTMenuToRun3(const TrigConf::HLTFrame* frame, const std::string& filename); -void convertRun2HLTPrescalesToRun3(const TrigConf::HLTFrame* frame, const std::string& filename); -void convertRun2BunchGroupsToRun3(const TrigConf::CTPConfig* frame, const std::string& filename); -void convertRun2L1PrescalesToRun3(const TrigConf::CTPConfig* frame, const std::string& filename); \ No newline at end of file diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersHLT.cxx similarity index 60% rename from Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.cxx rename to Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersHLT.cxx index d1c488d2821acbe53afb9537b60130e5a9c86843..4cd45e01f635af2f1a3041fd761a5526addbbc81 100644 --- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.cxx +++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersHLT.cxx @@ -4,9 +4,7 @@ #include <numeric> #include "TrigConfData/HLTMenu.h" -#include "TrigConfData/L1BunchGroupSet.h" #include "TrigConfData/DataStructure.h" -#include "TrigConfData/L1PrescalesSet.h" #include "TrigCompositeUtils/HLTIdentifier.h" #define BOOST_BIND_GLOBAL_PLACEHOLDERS // Needed to silence Boost pragma message #include <boost/property_tree/json_parser.hpp> @@ -15,15 +13,8 @@ #include "TrigConfHLTData/HLTStreamTag.h" #include "TrigConfHLTData/HLTSignature.h" #include "TrigConfHLTData/HLTTriggerElement.h" -#include "TrigConfL1Data/CTPConfig.h" -#include "TrigConfL1Data/BunchGroupSet.h" -#include "TrigConfL1Data/BunchGroup.h" - #include "TrigConfIO/JsonFileWriterHLT.h" -#include "TrigConfIO/JsonFileWriter.h" - - template<typename COLL> boost::property_tree::ptree asArray( const COLL& data) { @@ -137,12 +128,10 @@ void convertRun2HLTMenuToRun3(const TrigConf::HLTFrame* frame, const std::string convertHLTMenu(frame, menu); TrigConf::JsonFileWriterHLT writer; - std::cout << "Saving file: " << filename << std::endl; writer.writeJsonFile(filename, menu); } - void convertRun2HLTPrescalesToRun3(const TrigConf::HLTFrame* frame, const std::string& filename) { using ptree = boost::property_tree::ptree; ptree top; @@ -166,94 +155,6 @@ void convertRun2HLTPrescalesToRun3(const TrigConf::HLTFrame* frame, const std::s convertHLTMenu(frame, menu); TrigConf::JsonFileWriterHLT writer; - std::cout << "Saving file: " << filename << std::endl; writer.writeJsonFile(filename, menu, psk); } -std::vector<std::pair<int, int>> toRanges(const std::vector<int>& bunches) { - // converts sequence of bunches into the pairs of continous ranges - if ( bunches.empty() ) - return {}; - if (bunches.size() == 1) { - return { {bunches.front(), bunches.front()} }; - } - - // nontrival ranges - std::vector<std::pair<int, int>> ranges; - std::vector<int> sorted = bunches; - std::sort(sorted.begin(), sorted.end()); - - std::vector<int> differences; - std::adjacent_difference( sorted.begin(), sorted.end(), std::back_inserter(differences)); - - int start = sorted.front(); - - for (size_t i = 1; i < differences.size(); ++i) { - if (differences[i] == 1) continue; - ranges.emplace_back( std::pair(start, sorted[i-1]) ); - start = sorted[i]; - } - ranges.emplace_back( std::pair(start, sorted.back()) ); - return ranges; -} - - -void convertRun2BunchGroupsToRun3(const TrigConf::CTPConfig* frame, const std::string& filename) { - using ptree = boost::property_tree::ptree; - ptree top; - top.put("filetype", "bunchgroupset"); - top.put("name", frame->bunchGroupSet().name()); - - ptree pGroups; - const std::vector<TrigConf::BunchGroup>& bgVec = frame->bunchGroupSet().bunchGroups(); - for (auto group : bgVec) { - auto ranges = toRanges(group.bunches()); - ptree pGroup; - pGroup.put("name", group.name()); - pGroup.put("id", group.internalNumber()); - pGroup.put("info", std::to_string(group.bunches().size()) + " bunches, " + ranges.size() + " groups" ); - - ptree pBCIDS; - - for ( auto [start, end] : ranges) { - ptree pTrain; - pTrain.put("first", start ); - pTrain.put("length", 1+end-start ); - pBCIDS.push_back(std::make_pair("", pTrain)); - } - pGroup.push_back(std::make_pair("bcids", pBCIDS)); - - pGroups.push_back(std::make_pair(std::string("BGRP")+std::to_string(group.internalNumber()), pGroup)); - } - top.push_back(std::make_pair("bunchGroups", pGroups)); - TrigConf::L1BunchGroupSet bgs(std::move(top)); - TrigConf::JsonFileWriter writer; - std::cout << "Saving file: " << filename << std::endl; - writer.writeJsonFile(filename, bgs); - - -} - -void convertRun2L1PrescalesToRun3(const TrigConf::CTPConfig* frame, const std::string& filename) { - using ptree = boost::property_tree::ptree; - ptree top; - top.put("filetype", "l1prescale"); - top.put("name", frame->prescaleSet().name()); - ptree pCuts; - for (size_t id = 0; id < frame->prescaleSet().prescales_float().size(); ++id) { - ptree pCut; - auto itemPtr = frame->menu().item(id); - if ( itemPtr != nullptr ) { - pCut.put("cut", frame->prescaleSet().cuts().at(id)); - pCut.put("enabled", frame->prescaleSet().prescales_float().at(id) > 0.0 ); - pCut.put("info", "prescale: "+std::to_string(frame->prescaleSet().prescales_float().at(id))); - pCuts.push_back(std::make_pair(itemPtr->name(), pCut)); - } - } - top.push_back(std::make_pair("cutValues", pCuts)); - - TrigConf::L1PrescalesSet ps(std::move(top)); - TrigConf::JsonFileWriter writer; - std::cout << "Saving file: " << filename << std::endl; - writer.writeJsonFile(filename, ps); -} \ No newline at end of file diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersHLT.h b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersHLT.h new file mode 100644 index 0000000000000000000000000000000000000000..09a737af97043221f861fd357c831789285bd77b --- /dev/null +++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersHLT.h @@ -0,0 +1,9 @@ +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TrigConfData/HLTMenu.h" +#include "TrigConfHLTData/HLTFrame.h" + +void convertRun2HLTMenuToRun3(const TrigConf::HLTFrame* frame, const std::string& filename); +void convertRun2HLTPrescalesToRun3(const TrigConf::HLTFrame* frame, const std::string& filename); diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx new file mode 100644 index 0000000000000000000000000000000000000000..094ec340d9b7434b575f8dca5ba4f10bfacc48f9 --- /dev/null +++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx @@ -0,0 +1,529 @@ +// Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + +#include "Run2toRun3ConvertersL1.h" +#include <numeric> +#include <unordered_set> +#include <boost/tokenizer.hpp> +#include <tuple> +#include <stdexcept> + +#include "TrigConfData/L1BunchGroupSet.h" +#include "TrigConfData/DataStructure.h" +#include "TrigConfData/L1PrescalesSet.h" +#define BOOST_BIND_GLOBAL_PLACEHOLDERS // Needed to silence Boost pragma message +#include <boost/property_tree/json_parser.hpp> +#include "TrigConfL1Data/CTPConfig.h" +#include "TrigConfL1Data/TriggerThreshold.h" +#include "TrigConfL1Data/TriggerItem.h" +#include "TrigConfL1Data/TriggerItemNode.h" +#include "TrigConfL1Data/ClusterThresholdValue.h" +#include "TrigConfL1Data/JetThresholdValue.h" +#include "TrigConfL1Data/HelperFunctions.h" +#include "TrigConfL1Data/CaloInfo.h" + +#include "TrigConfL1Data/BunchGroupSet.h" +#include "TrigConfL1Data/BunchGroup.h" + +#include "TrigConfIO/JsonFileWriterL1.h" + +#include <nlohmann/json.hpp> + +using json = nlohmann::json; // to be changed to ordered_json +using ptree = boost::property_tree::ptree; + +namespace { + std::tuple<std::string, std::vector<std::string>> + decodeItemDefinition(const TrigConf::TriggerItem * item) { + std::string definition{""}; + std::vector<std::string> bgps; + const TrigConf::TriggerItemNode * topNode = item->topNode(); + std::vector<const TrigConf::TriggerItemNode*> nodes; + topNode->getAllFinalNodes(nodes); + std::map<unsigned int, const TrigConf::TriggerItemNode*> nodeMap; + for(auto * node : nodes) { + nodeMap[node->position()] = node; + } + // build tokens with separators ()&|! and <space>. Keeps all separators except <space> in the list of tokens + for ( auto & tok : boost::tokenizer<boost::char_separator<char> > (item->definition(), boost::char_separator<char>(" ", "()&|!")) ) { + if(isdigit(tok[0])) { + // replace by threshold + int idx = std::stoi(tok); + const TrigConf::TriggerItemNode* node = nodeMap[idx]; + if(node->triggerThreshold()->type()=="BGRP") { + bgps.push_back(node->thresholdName()); + if(definition.back()=='&') { + definition.pop_back(); + } + } else { + definition += node->thresholdName() + "[x" + std::to_string(node->multiplicity()) + "]"; + } + } else { + // keep token ()&|! + definition += tok; + } + } + // remove outer parentheses + if(definition.front()=='(' and definition.back()==')') { + definition = definition.substr(1,definition.size()-2); + } + return make_tuple(definition, bgps); + } +} + + +/** + * Conversion of L1 menu + **/ +void +convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoMenu* topoMenu, + const std::string& filename, bool writeTmpFile) +{ + + if( !ctpConfig ) { + std::cout << "No CTPConfig, no L1Menu file will be produced" << std::endl; + return; + } + + // items + json items; + for( const TrigConf::TriggerItem * sourceItem: ctpConfig->menu().items() ) { + json item({}); + item["name"] = sourceItem->name(); + item["legacy"] = true; + item["ctpid"] = sourceItem->ctpId(); + auto [definition, bunchgroups] = decodeItemDefinition(sourceItem); + item["definition"] = definition; + item["bunchgroups"] = bunchgroups; + item["triggerType"] = TrigConf::uint2bin(sourceItem->triggerType(),8); + item["partition"] = sourceItem->partition(); + std::string smon("LF:"); + smon += (sourceItem->monitor() & 0x04 ? '1' : '0'); + smon += (sourceItem->monitor() & 0x02 ? '1' : '0'); + smon += (sourceItem->monitor() & 0x01 ? '1' : '0'); + smon += "|HF:"; + smon += (sourceItem->monitor() & 0x20 ? '1' : '0'); + smon += (sourceItem->monitor() & 0x10 ? '1' : '0'); + smon += (sourceItem->monitor() & 0x08 ? '1' : '0'); + item["monitor"] = smon; + items[sourceItem->name()] = item; + }; + + // thresholds + json thresholds; + std::unordered_set<std::string> legacyThrTypes{"EM", "TAU", "JET", "XE", "XS", "TE", "ZB", "R2TOPO"}; + for( const TrigConf::TriggerThreshold * sourceThr : ctpConfig->menu().thresholdVector()) { + std::string thrType = sourceThr->type(); + if(thrType=="BGRP" || thrType=="RNDM") { + continue; + } + if(thrType=="MUON") { + thrType = "MU"; + } + else if(thrType=="TOPO") { + thrType = "R2TOPO"; + } + + bool isLegacyCalo = legacyThrTypes.count(thrType) > 0; + json &jThisType = isLegacyCalo ? thresholds["legacyCalo"][thrType] : thresholds[thrType]; + bool firstOfItsType = jThisType.empty(); + if (firstOfItsType) + { + jThisType["type"] = thrType; + } + json thr; + size_t mapping = sourceThr->mapping(); + thr["mapping"] = mapping; + if(thrType=="MU") { + if (firstOfItsType) + { + jThisType["type"] = "MU"; + jThisType["exclusionLists"] = json::object_t{}; + jThisType["roads"]["rpc"] = json::object_t{}; + jThisType["roads"]["tgc"] = json::object_t{}; + } + int ptCut = sourceThr->triggerThresholdValue(0,0)->ptCutCount(); + thr["baThr"] = ptCut; + thr["ecThr"] = ptCut; + thr["fwThr"] = ptCut; + thr["baIdx"] = mapping; + thr["ecIdx"] = mapping; + thr["fwIdx"] = mapping; + thr["tgcFlags"] = ""; + thr["region"] = "ALL"; + jThisType["roads"]["rpc"][std::to_string(ptCut)] = mapping; + jThisType["roads"]["tgc"][std::to_string(ptCut)] = mapping; + } + else if (thrType == "EM") + { + thr["thrValues"] = json::array_t{}; + for (const TrigConf::TriggerThresholdValue *tv : sourceThr->thresholdValueVector()) + { + auto cl = dynamic_cast<const TrigConf::ClusterThresholdValue *>(tv); + json jtv; + jtv["value"] = static_cast<unsigned int>(tv->ptcut()); + std::string isobits = "00000"; + auto isomask = cl->isolationMask(); + for (size_t b = 0; b < 5; ++b) + { + if (isomask & (1 << b)) + { + isobits[4 - b] = '1'; + } + } + jtv["isobits"] = isobits; + jtv["etamin"] = tv->etamin(); + jtv["etamax"] = tv->etamax(); + jtv["phimin"] = tv->phimin(); + jtv["phimax"] = tv->phimax(); + jtv["priority"] = static_cast<unsigned int>(tv->priority()); + thr["thrValues"] += jtv; + } + } + else if (thrType == "TAU") + { + auto cl = dynamic_cast<const TrigConf::ClusterThresholdValue*>(sourceThr->triggerThresholdValue(0,0)); + int ptCut = (int)cl->ptcut(); + thr["value"] = ptCut; + std::string isobits = "00000"; + auto isomask = cl->isolationMask(); + for (size_t b = 0; b < 5; ++b) + { + if (isomask & (1 << b)) + { + isobits[4 - b] = '1'; + } + } + thr["isobits"] = isobits; + } + else if (thrType == "JET") + { + thr["thrValues"] = json::array_t{}; + for (const TrigConf::TriggerThresholdValue *tv : sourceThr->thresholdValueVector()) + { + auto jetThrVal = dynamic_cast<const TrigConf::JetThresholdValue *>(sourceThr->triggerThresholdValue(0, 0)); + json jtv; + jtv["value"] = static_cast<unsigned int>(tv->ptcut()); + jtv["etamin"] = tv->etamin(); + jtv["etamax"] = tv->etamax(); + jtv["phimin"] = tv->phimin(); + jtv["phimax"] = tv->phimax(); + jtv["window"] = jetThrVal->windowSize() == TrigConf::JetWindowSize::SMALL ? 4 : 8; // 4 and 8 are the two possible jet window sizes + jtv["priority"] = static_cast<unsigned int>(tv->priority()); + thr["thrValues"] += jtv; + } + } + else if (thrType == "ZB") + { + thr["seed"] = sourceThr->zbSeedingThresholdName(); + thr["seedMultiplicity"] = sourceThr->zbSeedingThresholdMulti(); + thr["seedBcdelay"] = sourceThr->bcDelay(); + } + jThisType["thresholds"][sourceThr->name()] = thr; + } + + // exra info for thresholds + const TrigConf::CaloInfo& ci = ctpConfig->menu().caloInfo(); + thresholds["legacyCalo"]["EM"]["ptMinToTopo"] = ci.minTobEM().ptmin; + thresholds["legacyCalo"]["EM"]["resolutionMeV"] = (int)(1000/ci.globalEmScale()); + thresholds["legacyCalo"]["TAU"]["ptMinToTopo"] = ci.minTobTau().ptmin; + thresholds["legacyCalo"]["JET"]["ptMinToTopoSmallWindow"] = ci.minTobJetSmall().ptmin; + thresholds["legacyCalo"]["JET"]["ptMinToTopoLargeWindow"] = ci.minTobJetLarge().ptmin; + json isoHAforEM{ {"thrtype", "HAIsoForEMthr"}, {"Parametrization", json::array_t{}} }; + json isoEMforEM{ {"thrtype", "EMIsoForEMthr"}, {"Parametrization", json::array_t{}} }; + json isoEMforTAU{ {"thrtype", "EMIsoForTAUthr"}, {"Parametrization", json::array_t{}} }; + for(const TrigConf::IsolationParam & iso : ci.isolationHAIsoForEMthr()) { + json p{ {"etamax", iso.etamax()}, {"etamin", iso.etamin()}, {"isobit", iso.isobit()}, {"mincut", iso.mincut()}, + {"offset", iso.offset()}, {"priority", iso.priority()}, {"slope", iso.slope()}, {"upperlimit", iso.upperlimit()} }; + isoHAforEM["Parametrization"] += p; + } + for(const TrigConf::IsolationParam & iso : ci.isolationEMIsoForEMthr()) { + json p{ {"etamax", iso.etamax()}, {"etamin", iso.etamin()}, {"isobit", iso.isobit()}, {"mincut", iso.mincut()}, + {"offset", iso.offset()}, {"priority", iso.priority()}, {"slope", iso.slope()}, {"upperlimit", iso.upperlimit()} }; + isoEMforEM["Parametrization"] += p; + } + for(const TrigConf::IsolationParam & iso : ci.isolationEMIsoForTAUthr()) { + json p{ {"etamax", iso.etamax()}, {"etamin", iso.etamin()}, {"isobit", iso.isobit()}, {"mincut", iso.mincut()}, + {"offset", iso.offset()}, {"priority", iso.priority()}, {"slope", iso.slope()}, {"upperlimit", iso.upperlimit()} }; + isoEMforTAU["Parametrization"] += p; + } + thresholds["legacyCalo"]["EM"]["isolation"]["HAIsoForEMthr"] = isoHAforEM; + thresholds["legacyCalo"]["EM"]["isolation"]["EMIsoForEMthr"] = isoEMforEM; + thresholds["legacyCalo"]["TAU"]["isolation"]["EMIsoForTAUthr"] = isoEMforTAU; + const TrigConf::METSigParam &xs = ci.metSigParam(); + thresholds["legacyCalo"]["XS"]["significance"] = json::object_t{ + {"xsSigmaScale", xs.xsSigmaScale()}, {"xsSigmaOffset", xs.xsSigmaOffset()}, {"xeMin", xs.xeMin()}, {"xeMax", xs.xeMax()}, {"teSqrtMin", xs.teSqrtMin()}, {"teSqrtMax", xs.teSqrtMax()}}; + + // boards + json boards; + boards["Ctpin7"] = json::object_t{ {"type", "CTPIN"}, {"legacy", true}, + {"connectors", std::vector<std::string>{"EM1", "EM2", "TAU1", "TAU2"}} }; + boards["Ctpin8"] = json::object_t{ {"type", "CTPIN"}, {"legacy", true}, + {"connectors", std::vector<std::string>{"JET1", "JET2", "EN1", "EN2"}} }; + boards["Ctpin9"] = json::object_t{ {"type", "CTPIN"}, {"legacy", true}, + {"connectors", std::vector<std::string>{"MUCTPI", "CTPCAL", "NIM1", "NIM2"}} }; + boards["LegacyTopo0"] = json::object_t{ {"type", "TOPO"}, {"legacy", true}, + {"connectors", std::vector<std::string>{"LegacyTopo0"}} }; + boards["LegacyTopo1"] = json::object_t{ {"type", "TOPO"}, {"legacy", true}, + {"connectors", std::vector<std::string>{"LegacyTopo1"}} }; + + // connectors + json connectors; + std::map<std::string,std::vector<const TrigConf::TriggerThreshold*>> triggerlinesMap; + for( const TrigConf::TriggerThreshold * sourceThr : ctpConfig->menu().thresholdVector()) { + if(sourceThr->isInternal()) { + continue; + } + std::string cableName = sourceThr->cableName(); + if(cableName=="ALFA") { + cableName = "AlfaCtpin"; + } + else if(cableName=="TOPO1") { + cableName = "LegacyTopo0"; + } + else if(cableName=="TOPO2") { + cableName = "LegacyTopo1"; + } + triggerlinesMap[cableName].push_back(sourceThr); + } + for( auto & [type, triggerlines] : triggerlinesMap) { + std::sort(std::begin(triggerlines), std::end(triggerlines), + [](const TrigConf::TriggerThreshold *a, const TrigConf::TriggerThreshold *b) { return a->cableStart() < b->cableStart(); }); + for( const TrigConf::TriggerThreshold * thr : triggerlines) { + if(!connectors.contains(type)) { + if(thr->input()=="ctpcore") { + connectors[type]["type"] = "electrical"; + if(type=="AlfaCtpin") { + connectors[type]["triggerlines"]["clock0"] = json::array_t{}; + connectors[type]["triggerlines"]["clock1"] = json::array_t{}; + } else { + connectors[type]["triggerlines"]["fpga0"]["clock0"] = json::array_t{}; + connectors[type]["triggerlines"]["fpga0"]["clock1"] = json::array_t{}; + connectors[type]["triggerlines"]["fpga1"]["clock0"] = json::array_t{}; + connectors[type]["triggerlines"]["fpga1"]["clock1"] = json::array_t{}; + } + } else if(thr->input()=="ctpin") { + connectors[type]["type"] = "ctpin"; + connectors[type]["triggerlines"] = json::array_t{}; + } else { + throw std::runtime_error("Unknown connector type" + thr->input()); + } + connectors[type]["legacy"] = true; + } + size_t start = thr->cableStart(); + size_t nbits = thr->cableEnd() - thr->cableStart() + 1; + if(thr->input()=="ctpcore") { + unsigned int clock = thr->clock(); + if(type=="AlfaCtpin") { + json tl{{"name", thr->name()}, {"startbit", start}, {"nbits", nbits}}; + connectors[type]["triggerlines"]["clock" + std::to_string(clock)] += tl; + } else { + size_t fpga = 0; + if(start>=16) { + start -= 16; + fpga++; + } + json tl{{"name", "R2TOPO_" + thr->name()}, {"startbit", start}, {"nbits", nbits}}; + connectors[type]["triggerlines"]["fpga" + std::to_string(fpga)]["clock" + std::to_string(clock)] += tl; + } + } else { + json tl{{"name", thr->name()}, {"startbit", start}, {"nbits", nbits}}; + connectors[type]["triggerlines"] += tl; + } + } + } + + // algorithms + json decAlgos; + json sortAlgos; + for(const TXC::L1TopoConfigAlg & alg : topoMenu->getL1TopoConfigAlgs()) { + json jAlg; + jAlg["algId"] = alg.algoID(); + jAlg["klass"] = alg.type(); + jAlg["fixedParameters"]["generics"] = json::object_t{}; + size_t pos{0}; + for(const TXC::FixedParameter & fixP : alg.getFixedParameters()) { + try + { + auto vInt = std::stoi(fixP.value); + jAlg["fixedParameters"]["generics"][fixP.name] = json::object_t{{"value", vInt}, {"position", pos++}}; + } + catch (std::invalid_argument &) + { + jAlg["fixedParameters"]["generics"][fixP.name] = json::object_t{{"value", fixP.value}, {"position", pos++}}; + } + } + jAlg["variableParameters"] = json::array_t{}; + for(const TXC::RegisterParameter & regP : alg.getParameters()) { + jAlg["variableParameters"] += json::object_t{{"name", regP.name}, {"selection", regP.selection}, {"value", std::stoi(regP.value)}}; + } + if(alg.isSortAlg()) { + jAlg["input"] = alg.getInputNames()[0]; + jAlg["output"] = alg.output(); + sortAlgos[alg.name()] = jAlg; + } else if(alg.isDecAlg()) { + jAlg["input"] = alg.getInputNames(); + jAlg["output"] = alg.getOutputNames(); + decAlgos[alg.name()] = jAlg; + } + } + json topo; + topo["R2TOPO"]["decisionAlgorithms"] = decAlgos; + topo["R2TOPO"]["sortingAlgorithms"] = sortAlgos; + + // ctp + json ctp; + ctp["inputs"]["ctpin"]["slot7"] = json::object_t{{"connector0", "EM1"}, {"connector1", "EM2"}, + {"connector2", "TAU1"}, {"connector3", "TAU2"}}; + ctp["inputs"]["ctpin"]["slot8"] = json::object_t{{"connector0", "JET1"}, {"connector1", "JET2"}, + {"connector2", "EN1"}, {"connector3", "EN2"}}; + ctp["inputs"]["ctpin"]["slot9"] = json::object_t{{"connector0", "MUCTPI"}, {"connector1", "CTPCAL"}, + {"connector2", "NIM1"}, {"connector3", "NIM2"}}; + ctp["inputs"]["electrical"] = json::object_t{{"connector0", "AlfaCtpin"}, {"connector1", "LegacyTopo0"}, {"connector2", "LegacyTopo1"}}; + ctp["monitoring"]["ctpmon"] = json::object_t{}; + + // putting the menu together + json menu({}); + menu["filetype"] = "l1menu"; + menu["run"] = 2; + menu["name"] = ctpConfig->name(); + menu["items"] = items; + menu["thresholds"] = thresholds; + menu["topoAlgorithms"] = topo; + menu["boards"] = boards; + menu["connectors"] = connectors; + menu["ctp"] = ctp; + + if(writeTmpFile) { + std::ofstream outfile("tmp" + filename); + outfile << std::setw(4) << menu << std::endl; + std::cout << "Wrote tmp" << filename << std::endl; + } + std::stringstream ss; + ss << menu; + ptree top; + boost::property_tree::read_json(ss, top); + TrigConf::L1Menu l1menu(std::move(top)); + TrigConf::JsonFileWriterL1 writer; + writer.writeJsonFile(filename, l1menu); +} + +/** + * Conversion of bunchgroup set + **/ +std::vector<std::pair<int, int>> +toRanges(const std::vector<int>& bunches) { + // converts sequence of bunches into the pairs of continous ranges + if ( bunches.empty() ) { + return {}; + } + if (bunches.size() == 1) { + return { {bunches.front(), bunches.front()} }; + } + + // nontrival ranges + std::vector<std::pair<int, int>> ranges; + std::vector<int> sorted = bunches; + std::sort(sorted.begin(), sorted.end()); + + std::vector<int> differences; + std::adjacent_difference( sorted.begin(), sorted.end(), std::back_inserter(differences)); + + int start = sorted.front(); + + for (size_t i = 1; i < differences.size(); ++i) { + if (differences[i] == 1) continue; + ranges.emplace_back( std::pair(start, sorted[i-1]) ); + start = sorted[i]; + } + ranges.emplace_back( std::pair(start, sorted.back()) ); + return ranges; +} + +void +convertRun2BunchGroupsToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string& filename, bool writeTmpFile) +{ + const TrigConf::BunchGroupSet & bgs = ctpConfig->bunchGroupSet(); + if(bgs.bunchGroups().size()==0) { + std::cout << "BunchgroupSet is empty, no file will be produced" << std::endl; + return; + } + + json bgset; + bgset["filetype"] ="bunchgroupset"; + bgset["name"] = bgs.name(); + + json jGroups; + const std::vector<TrigConf::BunchGroup>& bgVec = bgs.bunchGroups(); + for (auto & group : bgVec) { + auto ranges = toRanges(group.bunches()); + json jGroup; + jGroup["name"] =group.name(); + jGroup["id"] =group.internalNumber(); + jGroup["info"] = std::to_string(group.bunches().size()) + " bunches, " + std::to_string(ranges.size()) + " groups"; + + json jBCIDS = json::array_t{}; + for ( auto [start, end] : ranges) { + jBCIDS += json{{"first", start}, {"length", 1+end-start}}; + } + jGroup["bcids"] = jBCIDS; + + jGroups[std::string("BGRP")+std::to_string(group.internalNumber())] = jGroup; + } + bgset["bunchGroups"] = jGroups; + + if(writeTmpFile) { + std::ofstream outfile("tmp" + filename); + outfile << std::setw(4) << bgset << std::endl; + std::cout << "Wrote tmp" << filename << std::endl; + } + std::stringstream ss; + ss << bgset; + ptree top; + boost::property_tree::read_json(ss, top); + TrigConf::L1BunchGroupSet newbgs(std::move(top)); + TrigConf::JsonFileWriterL1 writer; + writer.writeJsonFile(filename, newbgs); +} + +/** + * Conversion of L1 prescales set + **/ +void +convertRun2L1PrescalesToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string& filename, bool writeTmpFile) { + const TrigConf::PrescaleSet & l1pss = ctpConfig->prescaleSet(); + if(l1pss.isNull()) { + std::cout << "L1PrescaleSet is empty, no file will be produced" << std::endl; + return; + } + + json psset; + psset["filetype"] = "l1prescale"; + psset["name"] = l1pss.name(); + json jCuts; + for (size_t id = 0; id < l1pss.prescales_float().size(); ++id) { + json jCut; + auto itemPtr = ctpConfig->menu().item(id); + if ( itemPtr != nullptr ) { + int32_t cut = l1pss.cuts().at(id); + jCut["cut"] = abs(cut); + jCut["enabled"] = cut > 0; + double ps = static_cast<double>(0xFFFFFF) / ( 0x1000000 - cut ); + jCut["info"] = "prescale: "+std::to_string(ps); + jCuts[itemPtr->name()] = jCut; + } + } + psset["cutValues"] = jCuts; + + if(writeTmpFile) { + std::ofstream outfile("tmp" + filename); + outfile << std::setw(4) << psset << std::endl; + std::cout << "Wrote tmp" << filename << std::endl; + } + std::stringstream ss; + ss << psset; + ptree top; + boost::property_tree::read_json(ss, top); + TrigConf::L1PrescalesSet ps(std::move(top)); + TrigConf::JsonFileWriterL1 writer; + writer.writeJsonFile(filename, ps); +} diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h new file mode 100644 index 0000000000000000000000000000000000000000..4580ea04ff62e0e0620c64b856022660b407e5fb --- /dev/null +++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h @@ -0,0 +1,25 @@ +// Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +#include "TrigConfL1Data/CTPConfig.h" +#include "L1TopoConfig/L1TopoMenu.h" + +/** @brief Run 2 to Run 3 L1 menu converter + * Converts Run 2 L1 menu and L1Topo menu into run 3 format and writes out a json file + * @param ctpConfig pointer to L1 menu + * @param topoMenu pointer to L1Topo menu (can be empty) + * @param filename name of the output json file + * @param writeTmpFile writes out a temporary version of the json file (before filling the L1Menu structure) + */ +void convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoMenu * topoMenu, + const std::string& filename, bool writeTmpFile = false); + +/** @brief Run 2 to Run 3 bunchgroup converter + * @param ctpConfig pointer to L1 menu (which contains the bunchgroups) + * @param filename name of the output json file + */ +void convertRun2BunchGroupsToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string& filename, bool writeTmpFile = false); + +/** @brief Run 2 to Run 3 L1 prescale converter + * @param ctpConfig pointer to L1 menu (which contains the prescales) + * @param filename name of the output json file + */ +void convertRun2L1PrescalesToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string& filename, bool writeTmpFile = false);