From 651e7ca18a7c5ae659c26cbc44a556a65c1fd9dd Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Mon, 1 Feb 2021 11:57:42 +0100
Subject: [PATCH 01/12] Setup L1Menu conversion structure

---
 .../TrigConfStorage/CMakeLists.txt            |   2 +-
 .../TrigConfStorage/src/test/ReadWrite.cxx    | 104 ++++++++-------
 .../src/test/Run2toRun3Converters.cxx         |  97 --------------
 .../src/test/Run2toRun3Converters.h           |   6 +-
 .../src/test/Run2toRun3ConvertersL1.cxx       | 122 ++++++++++++++++++
 .../src/test/Run2toRun3ConvertersL1.h         |   6 +
 6 files changed, 187 insertions(+), 150 deletions(-)
 create mode 100644 Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
 create mode 100644 Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h

diff --git a/Trigger/TrigConfiguration/TrigConfStorage/CMakeLists.txt b/Trigger/TrigConfiguration/TrigConfStorage/CMakeLists.txt
index ce1638de850d..77a58e5311cf 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/Run2toRun3Converters.cxx
                       LINK_LIBRARIES L1TopoConfig TrigConfJobOptData TrigConfStorage TrigConfData TrigConfIO TrigCompositeUtilsLib )
 
 atlas_add_executable( TrigConfCoolFix
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
index e30268258923..575a12431230 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
@@ -42,6 +42,7 @@
 #include "TrigConfHLTData/HLTPrescaleSet.h"
 #include "TrigConfJobOptData/JobOptionTable.h"
 
+#include "Run2toRun3ConvertersL1.h"
 #include "Run2toRun3Converters.h"
 
 #include "CoolKernel/DatabaseId.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";
       }
    }
 
@@ -684,11 +689,14 @@ int main( int argc, char* argv[] ) {
        * to JSON
        *-----------------*/
       // TODO add L1 menu
+      if(ctpc) {
+         convertRun2BunchGroupsToRun3(ctpc, gConfig.bgkJsonOutFile);
+         convertRun2L1PrescalesToRun3(ctpc, gConfig.l1PSJsonOutFile);
+         convertRun2L1MenuToRun3(ctpc, gConfig.l1JsonOutFile);
+      }
       if(hltFrame) {
          convertRun2HLTMenuToRun3(hltFrame, gConfig.hltJsonOutFile);
          convertRun2HLTPrescalesToRun3(hltFrame, gConfig.hltPSJsonOutFile);
-         convertRun2BunchGroupsToRun3(ctpc, gConfig.bgkJsonOutFile);
-         convertRun2L1PrescalesToRun3(ctpc, gConfig.l1PSJsonOutFile);
       }
 
    }
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.cxx
index d1c488d2821a..443e3cbe12e7 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.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) {
@@ -142,7 +133,6 @@ void convertRun2HLTMenuToRun3(const TrigConf::HLTFrame* frame, const std::string
 
 }
 
-
 void convertRun2HLTPrescalesToRun3(const TrigConf::HLTFrame* frame, const std::string& filename) {
    using ptree = boost::property_tree::ptree;
    ptree top;
@@ -170,90 +160,3 @@ void convertRun2HLTPrescalesToRun3(const TrigConf::HLTFrame* frame, const std::s
    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/Run2toRun3Converters.h b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.h
index a925168509a4..09a737af9704 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.h
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.h
@@ -1,11 +1,9 @@
 /*
-  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/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/Run2toRun3ConvertersL1.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
new file mode 100644
index 000000000000..7ba21b193c66
--- /dev/null
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
@@ -0,0 +1,122 @@
+// Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+
+#include <numeric>
+#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/BunchGroupSet.h"
+#include "TrigConfL1Data/BunchGroup.h"
+
+#include "TrigConfIO/JsonFileWriter.h"
+
+using ptree = boost::property_tree::ptree;
+
+/**
+ * Conversion of L1 menu
+ **/
+void
+convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string& filename) {
+   ptree top;
+   TrigConf::L1Menu menu(std::move(top));
+   TrigConf::JsonFileWriter writer;
+   std::cout << "Saving file: " << filename << std::endl;
+   writer.writeJsonFile(filename, menu);
+}
+
+
+
+/**
+ * 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) {
+   ptree top;
+   top.put("filetype", "bunchgroupset");
+   top.put("name", ctpConfig->bunchGroupSet().name());
+
+   ptree pGroups;
+   const std::vector<TrigConf::BunchGroup>& bgVec = ctpConfig->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, " + std::to_string(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);
+}
+
+/**
+ * Conversion of L1 prescales set
+ **/
+void
+convertRun2L1PrescalesToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string& filename) {
+   using ptree = boost::property_tree::ptree;
+   ptree top;
+   top.put("filetype", "l1prescale");
+   top.put("name", ctpConfig->prescaleSet().name());
+   ptree pCuts;
+   for (size_t id = 0; id < ctpConfig->prescaleSet().prescales_float().size(); ++id) {
+      ptree pCut;
+      auto itemPtr = ctpConfig->menu().item(id);
+      if ( itemPtr != nullptr ) {
+         pCut.put("cut", ctpConfig->prescaleSet().cuts().at(id));
+         pCut.put("enabled", ctpConfig->prescaleSet().prescales_float().at(id) > 0.0 );
+         pCut.put("info", "prescale: "+std::to_string(ctpConfig->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);
+}
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h
new file mode 100644
index 000000000000..9a00de762450
--- /dev/null
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h
@@ -0,0 +1,6 @@
+// Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+#include "TrigConfL1Data/CTPConfig.h"
+
+void convertRun2BunchGroupsToRun3(const TrigConf::CTPConfig* frame, const std::string& filename);
+void convertRun2L1MenuToRun3(const TrigConf::CTPConfig* frame, const std::string& filename);
+void convertRun2L1PrescalesToRun3(const TrigConf::CTPConfig* frame, const std::string& filename);
-- 
GitLab


From 5466c026cde5f3ae083382b08c45aa3f5bdc3da7 Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Mon, 1 Feb 2021 15:32:47 +0100
Subject: [PATCH 02/12] Starting with the core implementation

---
 .../src/test/Run2toRun3ConvertersL1.cxx       | 112 +++++++++++++++---
 1 file changed, 97 insertions(+), 15 deletions(-)

diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
index 7ba21b193c66..2ee8dea41726 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
@@ -1,17 +1,25 @@
 // Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 
 #include <numeric>
+#include <unordered_set>
+
 #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/BunchGroupSet.h"
 #include "TrigConfL1Data/BunchGroup.h"
 
 #include "TrigConfIO/JsonFileWriter.h"
 
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json; // to be changed to ordered_json
 using ptree = boost::property_tree::ptree;
 
 /**
@@ -19,11 +27,75 @@ using ptree = boost::property_tree::ptree;
  **/
 void
 convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string& filename) {
+
+   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();
+      // jItem["ctpid"] = item.ctpId();
+      // jItem["definition"] = item.definition();
+      // jItem["monitor"] = item.monitor();
+      // jItem["partition"] = item.partition();
+      // jItem["triggerType"] = item.triggerType();
+      // jItem["bunchgroups"] = json(item.bunchgroups());
+      // if(auto legacy = item.legacy() )
+      //    jItem["legacy"] = *legacy;
+      items[sourceItem->name()] = item;
+   };
+
+   // tresholds
+   json thresholds({});
+   // std::unordered_set<std::string> treatedTypes; // for keeping track of 
+   for( const TrigConf::TriggerThreshold * sourceThr : ctpConfig->menu().thresholdVector()) {
+      std::string thrType = sourceThr->type();
+      if(thrType=="MUON") {
+         thrType = "MU";
+      }
+      if(!thresholds.contains(thrType)) {
+         thresholds[thrType]["type"] = thrType;
+      }
+   }
+   for( const TrigConf::TriggerThreshold * sourceThr : ctpConfig->menu().thresholdVector()) {
+      std::string thrType = sourceThr->type();
+      if(thrType=="MUON") {
+         thrType = "MU";
+      }
+      json thr({});
+      thr["name"] = sourceThr->name();
+      if(thrType=="MU") {
+         thresholds["MU"][sourceThr->name()] = thr;
+      } else {
+         thresholds["legacyCalo"][thrType][sourceThr->name()] = thr;
+      }
+   }
+
+   // put the menu together
+   json menu({});
+   menu["filetype"] = "l1menu";
+   menu["name"] = ctpConfig->name();
+   menu["items"] = items;
+   menu["thresholds"] = thresholds;
+   // j["topoAlgorithms"] = jtopo;
+   // j["boards"] = boards;
+   // j["connectors"] = connectors;
+   // j["ctp"] = ctp;
+
+   std::ofstream outfile("tmp" + filename);
+   outfile << std::setw(4) << menu << std::endl;
+
+   std::stringstream ss;
+   ss << menu.dump();
    ptree top;
-   TrigConf::L1Menu menu(std::move(top));
+   boost::property_tree::read_json(ss, top);
+   TrigConf::L1Menu l1menu(std::move(top));
    TrigConf::JsonFileWriter writer;
-   std::cout << "Saving file: " << filename << std::endl;
-   writer.writeJsonFile(filename, menu);
+   writer.writeJsonFile(filename, l1menu);
 }
 
 
@@ -61,12 +133,19 @@ toRanges(const std::vector<int>& bunches) {
 
 void
 convertRun2BunchGroupsToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string& filename) {
+
+   const TrigConf::BunchGroupSet & bgs = ctpConfig->bunchGroupSet();
+   if(bgs.bunchGroups().size()==0) {
+      std::cout << "BunchgroupSet is empty, no file will be produced" << std::endl;
+      return;
+   }
+
    ptree top;
    top.put("filetype", "bunchgroupset");
-   top.put("name", ctpConfig->bunchGroupSet().name());
+   top.put("name", bgs.name());
 
    ptree pGroups;
-   const std::vector<TrigConf::BunchGroup>& bgVec = ctpConfig->bunchGroupSet().bunchGroups();
+   const std::vector<TrigConf::BunchGroup>& bgVec = bgs.bunchGroups();
    for (auto group : bgVec) {
       auto ranges = toRanges(group.bunches());
       ptree pGroup;
@@ -87,10 +166,9 @@ convertRun2BunchGroupsToRun3(const TrigConf::CTPConfig* ctpConfig, const std::st
       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::L1BunchGroupSet newbgs(std::move(top));
    TrigConf::JsonFileWriter writer;
-   std::cout << "Saving file: " << filename << std::endl;
-   writer.writeJsonFile(filename, bgs);
+   writer.writeJsonFile(filename, newbgs);
 }
 
 /**
@@ -98,18 +176,23 @@ convertRun2BunchGroupsToRun3(const TrigConf::CTPConfig* ctpConfig, const std::st
  **/
 void
 convertRun2L1PrescalesToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string& filename) {
-   using ptree = boost::property_tree::ptree;
+   const TrigConf::PrescaleSet & l1pss = ctpConfig->prescaleSet();
+   if(l1pss.isNull()) {
+      std::cout << "L1PrescaleSet is empty, no file will be produced" << std::endl;
+      return;
+   }
+
    ptree top;
    top.put("filetype", "l1prescale");
-   top.put("name", ctpConfig->prescaleSet().name());
+   top.put("name", l1pss.name());
    ptree pCuts;
-   for (size_t id = 0; id < ctpConfig->prescaleSet().prescales_float().size(); ++id) {
+   for (size_t id = 0; id < l1pss.prescales_float().size(); ++id) {
       ptree pCut;
       auto itemPtr = ctpConfig->menu().item(id);
       if ( itemPtr != nullptr ) {
-         pCut.put("cut", ctpConfig->prescaleSet().cuts().at(id));
-         pCut.put("enabled", ctpConfig->prescaleSet().prescales_float().at(id) > 0.0 );
-         pCut.put("info", "prescale: "+std::to_string(ctpConfig->prescaleSet().prescales_float().at(id)));
+         pCut.put("cut", l1pss.cuts().at(id));
+         pCut.put("enabled", l1pss.prescales_float().at(id) > 0.0 );
+         pCut.put("info", "prescale: "+std::to_string(l1pss.prescales_float().at(id)));
          pCuts.push_back(std::make_pair(itemPtr->name(), pCut));
       }
    }
@@ -117,6 +200,5 @@ convertRun2L1PrescalesToRun3(const TrigConf::CTPConfig* ctpConfig, const std::st
 
    TrigConf::L1PrescalesSet ps(std::move(top));
    TrigConf::JsonFileWriter writer;
-   std::cout << "Saving file: " << filename << std::endl;
    writer.writeJsonFile(filename, ps);
 }
-- 
GitLab


From 478925badffdbd85cb610612b27599d3af06459c Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Mon, 1 Feb 2021 17:48:05 +0100
Subject: [PATCH 03/12] Added items and thresholds

---
 .../TrigConfStorage/src/test/ReadWrite.cxx    | 16 +++---
 .../src/test/Run2toRun3ConvertersL1.cxx       | 54 ++++++++++++++-----
 2 files changed, 48 insertions(+), 22 deletions(-)

diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
index 575a12431230..e8d19f1f91e9 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
@@ -688,7 +688,6 @@ int main( int argc, char* argv[] ) {
       /*------------------
        * to JSON
        *-----------------*/
-      // TODO add L1 menu
       if(ctpc) {
          convertRun2BunchGroupsToRun3(ctpc, gConfig.bgkJsonOutFile);
          convertRun2L1PrescalesToRun3(ctpc, gConfig.l1PSJsonOutFile);
@@ -698,7 +697,6 @@ int main( int argc, char* argv[] ) {
          convertRun2HLTMenuToRun3(hltFrame, gConfig.hltJsonOutFile);
          convertRun2HLTPrescalesToRun3(hltFrame, gConfig.hltPSJsonOutFile);
       }
-
    }
 
    if ( (gConfig.output & JobConfig::COOL) != 0 ) {
@@ -714,18 +712,20 @@ 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/Run2toRun3ConvertersL1.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
index 2ee8dea41726..ecbff791ccc5 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
@@ -11,6 +11,8 @@
 #include "TrigConfL1Data/CTPConfig.h"
 #include "TrigConfL1Data/TriggerThreshold.h"
 #include "TrigConfL1Data/TriggerItem.h"
+#include "TrigConfL1Data/ClusterThresholdValue.h"
+
 
 #include "TrigConfL1Data/BunchGroupSet.h"
 #include "TrigConfL1Data/BunchGroup.h"
@@ -51,27 +53,51 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string&
 
    // tresholds
    json thresholds({});
-   // std::unordered_set<std::string> treatedTypes; // for keeping track of 
-   for( const TrigConf::TriggerThreshold * sourceThr : ctpConfig->menu().thresholdVector()) {
-      std::string thrType = sourceThr->type();
-      if(thrType=="MUON") {
-         thrType = "MU";
-      }
-      if(!thresholds.contains(thrType)) {
-         thresholds[thrType]["type"] = thrType;
-      }
-   }
    for( const TrigConf::TriggerThreshold * sourceThr : ctpConfig->menu().thresholdVector()) {
       std::string thrType = sourceThr->type();
       if(thrType=="MUON") {
          thrType = "MU";
       }
       json thr({});
-      thr["name"] = sourceThr->name();
+      size_t mapping = sourceThr->mapping();
+      thr["mapping"] = mapping;
       if(thrType=="MU") {
-         thresholds["MU"][sourceThr->name()] = thr;
-      } else {
-         thresholds["legacyCalo"][thrType][sourceThr->name()] = thr;
+         if(!thresholds.contains(thrType)) {
+            thresholds[thrType]["type"] = thrType;
+            thresholds[thrType]["exclusionLists"] = json::object_t({});
+            thresholds[thrType]["roads"]["rpc"] = json::object_t({});
+            thresholds[thrType]["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";
+         thresholds[thrType]["roads"]["rpc"][std::to_string(ptCut)] = mapping;
+         thresholds[thrType]["roads"]["tgc"][std::to_string(ptCut)] = mapping;
+         thresholds["MU"]["thresholds"][sourceThr->name()] = thr;
+      }
+      else
+      {
+         if(!thresholds.contains(thrType)) {
+            thresholds["legacyCalo"][thrType]["type"] = thrType;
+         }
+         if(thrType=="TAU") {
+            auto cl = dynamic_cast<const TrigConf::ClusterThresholdValue*>(sourceThr->triggerThresholdValue(0,0));
+            int ptCut = (int)cl->ptcut();
+            thr["value"] = ptCut;
+            thr["isobits"] = cl->isolationMask();
+         } else if(thrType=="ZB") {
+            thr["seed"] = sourceThr->zbSeedingThresholdName();
+            thr["seedMultiplicity"] = sourceThr->zbSeedingThresholdMulti();
+            thr["seedBcdelay"] = sourceThr->bcDelay();
+         }
+
+         thresholds["legacyCalo"][thrType]["thresholds"][sourceThr->name()] = thr;
       }
    }
 
-- 
GitLab


From 0db3374ec34355232db87e61f98991e81a2e25f0 Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Tue, 2 Feb 2021 15:27:38 +0100
Subject: [PATCH 04/12] Added thresholds, boards, connectors

---
 .../src/test/Run2toRun3ConvertersL1.cxx       | 177 ++++++++++++++++--
 1 file changed, 165 insertions(+), 12 deletions(-)

diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
index ecbff791ccc5..1e80b52e359c 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
@@ -2,6 +2,9 @@
 
 #include <numeric>
 #include <unordered_set>
+#include <boost/tokenizer.hpp>
+#include <tuple>
+#include <stdexcept>
 
 #include "TrigConfData/L1BunchGroupSet.h"
 #include "TrigConfData/DataStructure.h"
@@ -11,7 +14,10 @@
 #include "TrigConfL1Data/CTPConfig.h"
 #include "TrigConfL1Data/TriggerThreshold.h"
 #include "TrigConfL1Data/TriggerItem.h"
+#include "TrigConfL1Data/TriggerItemNode.h"
 #include "TrigConfL1Data/ClusterThresholdValue.h"
+#include "TrigConfL1Data/HelperFunctions.h"
+
 
 
 #include "TrigConfL1Data/BunchGroupSet.h"
@@ -24,6 +30,46 @@
 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
  **/
@@ -35,29 +81,47 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string&
       return;
    }
 
-   // items
+   /**
+    * items
+    **/
    json items({});
    for( const TrigConf::TriggerItem * sourceItem: ctpConfig->menu().items() ) {
       json item({});
       item["name"] = sourceItem->name();
-      // jItem["ctpid"] = item.ctpId();
-      // jItem["definition"] = item.definition();
-      // jItem["monitor"] = item.monitor();
-      // jItem["partition"] = item.partition();
-      // jItem["triggerType"] = item.triggerType();
-      // jItem["bunchgroups"] = json(item.bunchgroups());
-      // if(auto legacy = item.legacy() )
-      //    jItem["legacy"] = *legacy;
+      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;
    };
 
-   // tresholds
+   /**
+    * thresholds 
+    */
    json thresholds({});
    for( const TrigConf::TriggerThreshold * sourceThr : ctpConfig->menu().thresholdVector()) {
       std::string thrType = sourceThr->type();
+      if(thrType=="BGRP" || thrType=="RNDM") {
+         continue;
+      }
       if(thrType=="MUON") {
          thrType = "MU";
       }
+      if(thrType=="TOPO") {
+         thrType = "R2TOPO";
+      }
       json thr({});
       size_t mapping = sourceThr->mapping();
       thr["mapping"] = mapping;
@@ -101,6 +165,95 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string&
       }
    }
 
+   /**
+    * 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";
+      }
+      if(cableName=="TOPO1") {
+         cableName = "LegacyTopo0";
+      }
+      if(cableName=="TOPO2") {
+         cableName = "LegacyTopo1";
+      }
+      std::cout << sourceThr->name() << "  " << cableName << std::endl;
+      triggerlinesMap[cableName].push_back(sourceThr);
+   }
+
+   for( auto & [type, triggerlines] : triggerlinesMap) {
+      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;
+         }
+      }
+   }
+
+   /**
+    * algorithithms
+    */
+   json algorithms
+
+
    // put the menu together
    json menu({});
    menu["filetype"] = "l1menu";
@@ -108,8 +261,8 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string&
    menu["items"] = items;
    menu["thresholds"] = thresholds;
    // j["topoAlgorithms"] = jtopo;
-   // j["boards"] = boards;
-   // j["connectors"] = connectors;
+   menu["boards"] = boards;
+   menu["connectors"] = connectors;
    // j["ctp"] = ctp;
 
    std::ofstream outfile("tmp" + filename);
-- 
GitLab


From ea3727de5b8174717a1f8d9ae2b2e12556b3b333 Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Tue, 2 Feb 2021 19:05:02 +0100
Subject: [PATCH 05/12] Add L1Topo

---
 .../TrigConfStorage/src/test/ReadWrite.cxx    |  4 +-
 .../src/test/Run2toRun3ConvertersL1.cxx       | 93 +++++++++++++++++--
 .../src/test/Run2toRun3ConvertersL1.h         |  3 +-
 3 files changed, 89 insertions(+), 11 deletions(-)

diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
index e8d19f1f91e9..b02308041dbe 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
@@ -688,10 +688,10 @@ int main( int argc, char* argv[] ) {
       /*------------------
        * to JSON
        *-----------------*/
-      if(ctpc) {
+      if(ctpc && l1tm) {
          convertRun2BunchGroupsToRun3(ctpc, gConfig.bgkJsonOutFile);
          convertRun2L1PrescalesToRun3(ctpc, gConfig.l1PSJsonOutFile);
-         convertRun2L1MenuToRun3(ctpc, gConfig.l1JsonOutFile);
+         convertRun2L1MenuToRun3(ctpc, l1tm, gConfig.l1JsonOutFile);
       }
       if(hltFrame) {
          convertRun2HLTMenuToRun3(hltFrame, gConfig.hltJsonOutFile);
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
index 1e80b52e359c..722043787299 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
@@ -1,5 +1,6 @@
 // Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 
+#include "Run2toRun3ConvertersL1.h"
 #include <numeric>
 #include <unordered_set>
 #include <boost/tokenizer.hpp>
@@ -17,8 +18,7 @@
 #include "TrigConfL1Data/TriggerItemNode.h"
 #include "TrigConfL1Data/ClusterThresholdValue.h"
 #include "TrigConfL1Data/HelperFunctions.h"
-
-
+#include "TrigConfL1Data/CaloInfo.h"
 
 #include "TrigConfL1Data/BunchGroupSet.h"
 #include "TrigConfL1Data/BunchGroup.h"
@@ -74,7 +74,8 @@ namespace {
  * Conversion of L1 menu
  **/
 void
-convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string& filename) {
+convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoMenu* topoMenu, const std::string& filename)
+{
 
    if( !ctpConfig ) {
       std::cout << "No CTPConfig, no L1Menu file will be produced" << std::endl;
@@ -165,6 +166,38 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string&
       }
    }
 
+   /**
+    * 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;
+
+
    /**
     * boards
     */
@@ -199,7 +232,6 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string&
       if(cableName=="TOPO2") {
          cableName = "LegacyTopo1";
       }
-      std::cout << sourceThr->name() << "  " << cableName << std::endl;
       triggerlinesMap[cableName].push_back(sourceThr);
    }
 
@@ -249,10 +281,55 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string&
    }
 
    /**
-    * algorithithms
+    * algorithms
     */
-   json algorithms
+   json topo;
+   topo["TOPO"]["decisionAlgorithms"] = json::object_t();
+   topo["TOPO"]["sortingAlgorithms"] = json::object_t();
+   topo["MUTOPO"]["decisionAlgorithms"] = json::object_t();
+   topo["MUTOPO"]["sortingAlgorithms"] = json::object_t();
+   topo["MULTTOPO"]["multiplicityAlgorithms"] = json::object_t();
+   json decAlgos;
+   json sortAlgos;
+   for(const TXC::L1TopoConfigAlg & alg : topoMenu->getL1TopoConfigAlgs()) {
+      json jAlg;
+      jAlg["algId"] = alg.algoID();
+      jAlg["klass"] = alg.type();
+      jAlg["input"] = alg.getInputNames();
+      jAlg["fixedParameters"]["generics"] = json::object_t{};
+      size_t pos{0};
+      for(const TXC::FixedParameter & fixP : alg.getFixedParameters()) {
+         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", regP.value}};
+      }
+      if(alg.isSortAlg()) {
+         jAlg["output"] = alg.output();
+         sortAlgos[alg.name()] = jAlg;
+      } else if(alg.isDecAlg()) {
+         jAlg["output"] = alg.getOutputNames();
+         decAlgos[alg.name()] = jAlg;
+      }
+   }   
+   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["inputs"]["optical"] = json::object_t{};
+   ctp["monitoring"]["ctpmon"] = json::object_t{};
 
    // put the menu together
    json menu({});
@@ -260,10 +337,10 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string&
    menu["name"] = ctpConfig->name();
    menu["items"] = items;
    menu["thresholds"] = thresholds;
-   // j["topoAlgorithms"] = jtopo;
+   menu["topoAlgorithms"] = topo;
    menu["boards"] = boards;
    menu["connectors"] = connectors;
-   // j["ctp"] = ctp;
+   menu["ctp"] = ctp;
 
    std::ofstream outfile("tmp" + filename);
    outfile << std::setw(4) << menu << std::endl;
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h
index 9a00de762450..424e34b69505 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h
@@ -1,6 +1,7 @@
 // Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 #include "TrigConfL1Data/CTPConfig.h"
+#include "L1TopoConfig/L1TopoMenu.h"
 
+void convertRun2L1MenuToRun3(const TrigConf::CTPConfig* frame, const TXC::L1TopoMenu * topoMenu, const std::string& filename);
 void convertRun2BunchGroupsToRun3(const TrigConf::CTPConfig* frame, const std::string& filename);
-void convertRun2L1MenuToRun3(const TrigConf::CTPConfig* frame, const std::string& filename);
 void convertRun2L1PrescalesToRun3(const TrigConf::CTPConfig* frame, const std::string& filename);
-- 
GitLab


From 8a5fbd0e89431f79555d47ea759623aff11599d4 Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Wed, 3 Feb 2021 08:56:09 +0100
Subject: [PATCH 06/12] WIP making it R2 robust

---
 Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx    | 3 ++-
 .../TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx        | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx
index 2d397e3744ac..b1f727e06392 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx
@@ -36,7 +36,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({});
@@ -413,6 +413,7 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me
       };
 
       for( const std::string topoCat : {"TOPO", "MUTOPO", "MULTTOPO", "R2TOPO"} ) {
+         std::cout << "JOERG here " << topoCat << std::endl; 
          for(auto & algName : l1menu.topoAlgorithmNames(topoCat)) {
             json jalg = json::object_t({});
             auto & alg = l1menu.algorithm(algName,topoCat);
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
index 722043787299..665766084359 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
@@ -344,6 +344,7 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
 
    std::ofstream outfile("tmp" + filename);
    outfile << std::setw(4) << menu << std::endl;
+   std::cout << "Wrote tmp" << filename << std::endl;
 
    std::stringstream ss;
    ss << menu.dump();
-- 
GitLab


From ee925f4b67ee0f09807d3be7f8639f03e8997c9d Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Thu, 11 Feb 2021 10:49:37 +0100
Subject: [PATCH 07/12] Finalize L1Menu xml -> json run2 converter

---
 .../TrigConfData/TrigConfData/L1Menu.h        |   5 +-
 .../TrigConfData/src/L1CTP.cxx                |   7 +-
 .../TrigConfData/src/L1Menu.cxx               |  18 +-
 .../TrigConfIO/src/JsonFileWriter.cxx         |  33 ++--
 .../TrigConfStorage/src/MasterTableLoader.cxx |  16 +-
 .../TrigConfStorage/src/MasterTableLoader.h   |  10 +-
 .../TrigConfStorage/src/XMLMenuLoader.cxx     |   1 -
 .../src/test/Run2toRun3ConvertersL1.cxx       | 178 +++++++++++-------
 8 files changed, 166 insertions(+), 102 deletions(-)

diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h
index df05536f05a0..d2d5282eb2bf 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h
@@ -129,7 +129,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;
 
@@ -145,6 +144,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 */
@@ -153,6 +154,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 4a6b69032195..095d448ccb0d 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 282094b00735..ee1d7ff926eb 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;
@@ -60,8 +63,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),
@@ -73,8 +76,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),
@@ -91,9 +94,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" ) ) {
@@ -128,8 +132,8 @@ TrigConf::L1Menu::update()
       throw;
    }
 
+   // CTP
    try {
-      // CTP
       m_ctp.setData(data().get_child("ctp"));
    }
    catch(std::exception & ex) {
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx
index b1f727e06392..db604d5c0562 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx
@@ -93,6 +93,7 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me
             jThr["thrValues"] = json::array_t({});
             for(auto & rv : EMThr.thrValues()) {
                json jRV({});
+               jRV["value"] = (unsigned int)rv.value();
                jRV["etamin"] = rv.etaMin();
                jRV["etamax"] = rv.etaMax();
                jRV["phimin"] = 0; // never used, so not read 
@@ -104,7 +105,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 +114,13 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me
             jThr["thrValues"] = json::array_t({});
             for(auto & rv : JThr.thrValues()) {
                json jRV({});
+               jRV["value"] = (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 +130,10 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me
             //jThr["thrValues"] = json::array_t({});
             for(auto & rv : teThr.thrValues()) {
                json jRV({});
+               jRV["value"] = (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 +151,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"] = (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 +167,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 +208,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 +332,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 +341,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 +379,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,16 +405,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"} ) {
-         std::cout << "JOERG here " << topoCat << std::endl; 
+      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);
@@ -475,8 +475,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;
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/MasterTableLoader.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/MasterTableLoader.cxx
index 53f81e0f7e95..0182282f3055 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 ee4eb3da830d..5507a1ab0df8 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 3fd6b362df4b..aed8b5903fb6 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/Run2toRun3ConvertersL1.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
index 665766084359..f1d805570946 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
@@ -17,6 +17,7 @@
 #include "TrigConfL1Data/TriggerItem.h"
 #include "TrigConfL1Data/TriggerItemNode.h"
 #include "TrigConfL1Data/ClusterThresholdValue.h"
+#include "TrigConfL1Data/JetThresholdValue.h"
 #include "TrigConfL1Data/HelperFunctions.h"
 #include "TrigConfL1Data/CaloInfo.h"
 
@@ -82,10 +83,8 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
       return;
    }
 
-   /**
-    * items
-    **/
-   json items({});
+   // items
+   json items;
    for( const TrigConf::TriggerItem * sourceItem: ctpConfig->menu().items() ) {
       json item({});
       item["name"] = sourceItem->name();
@@ -108,10 +107,9 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
       items[sourceItem->name()] = item;
    };
 
-   /**
-    * thresholds 
-    */
-   json thresholds({});
+   // 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") {
@@ -123,15 +121,24 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
       if(thrType=="TOPO") {
          thrType = "R2TOPO";
       }
-      json thr({});
+
+      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(!thresholds.contains(thrType)) {
-            thresholds[thrType]["type"] = thrType;
-            thresholds[thrType]["exclusionLists"] = json::object_t({});
-            thresholds[thrType]["roads"]["rpc"] = json::object_t({});
-            thresholds[thrType]["roads"]["tgc"] = json::object_t({});
+         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;
@@ -142,33 +149,78 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
          thr["fwIdx"] = mapping;
          thr["tgcFlags"] = "";
          thr["region"] = "ALL";
-         thresholds[thrType]["roads"]["rpc"][std::to_string(ptCut)] = mapping;
-         thresholds[thrType]["roads"]["tgc"][std::to_string(ptCut)] = mapping;
-         thresholds["MU"]["thresholds"][sourceThr->name()] = thr;
+         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
+      else if (thrType == "TAU")
       {
-         if(!thresholds.contains(thrType)) {
-            thresholds["legacyCalo"][thrType]["type"] = thrType;
+         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';
+            }
          }
-         if(thrType=="TAU") {
-            auto cl = dynamic_cast<const TrigConf::ClusterThresholdValue*>(sourceThr->triggerThresholdValue(0,0));
-            int ptCut = (int)cl->ptcut();
-            thr["value"] = ptCut;
-            thr["isobits"] = cl->isolationMask();
-         } else if(thrType=="ZB") {
-            thr["seed"] = sourceThr->zbSeedingThresholdName();
-            thr["seedMultiplicity"] = sourceThr->zbSeedingThresholdMulti();
-            thr["seedBcdelay"] = sourceThr->bcDelay();
+         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;
          }
-
-         thresholds["legacyCalo"][thrType]["thresholds"][sourceThr->name()] = thr;
       }
+      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
-    */
+   // 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());
@@ -196,11 +248,11 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
    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
-    */
+   // boards
    json boards;
    boards["Ctpin7"] = json::object_t{ {"type", "CTPIN"}, {"legacy", true},
                                       {"connectors", std::vector<std::string>{"EM1", "EM2", "TAU1", "TAU2"}} };
@@ -213,9 +265,7 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
    boards["LegacyTopo1"] = json::object_t{ {"type", "TOPO"}, {"legacy", true},
                                            {"connectors", std::vector<std::string>{"LegacyTopo1"}} };
 
-   /**
-    * connectors
-    */
+   // connectors
    json connectors;
    std::map<std::string,std::vector<const TrigConf::TriggerThreshold*>> triggerlinesMap;
    for( const TrigConf::TriggerThreshold * sourceThr : ctpConfig->menu().thresholdVector()) {
@@ -234,8 +284,9 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
       }
       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") {
@@ -280,45 +331,45 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
       }
    }
 
-   /**
-    * algorithms
-    */
-   json topo;
-   topo["TOPO"]["decisionAlgorithms"] = json::object_t();
-   topo["TOPO"]["sortingAlgorithms"] = json::object_t();
-   topo["MUTOPO"]["decisionAlgorithms"] = json::object_t();
-   topo["MUTOPO"]["sortingAlgorithms"] = json::object_t();
-   topo["MULTTOPO"]["multiplicityAlgorithms"] = json::object_t();
+   // algorithms
    json decAlgos;
    json sortAlgos;
    for(const TXC::L1TopoConfigAlg & alg : topoMenu->getL1TopoConfigAlgs()) {
       json jAlg;
       jAlg["algId"] = alg.algoID();
       jAlg["klass"] = alg.type();
-      jAlg["input"] = alg.getInputNames();
       jAlg["fixedParameters"]["generics"] = json::object_t{};
       size_t pos{0};
       for(const TXC::FixedParameter & fixP : alg.getFixedParameters()) {
-         jAlg["fixedParameters"]["generics"][fixP.name] = json::object_t{{"value", fixP.value}, {"position", pos++}};
+         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();
+      jAlg["variableParameters"] = json::array_t{};
       for(const TXC::RegisterParameter & regP : alg.getParameters()) {
-         jAlg["variableParameters"] += json::object_t{{"name", regP.name}, {"selection", regP.selection}, {"value", regP.value}};
+         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 
-    */
+   // ctp
    json ctp;
    ctp["inputs"]["ctpin"]["slot7"] = json::object_t{{"connector0", "EM1"}, {"connector1", "EM2"}, 
                                                     {"connector2", "TAU1"}, {"connector3", "TAU2"}};
@@ -326,14 +377,13 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
                                                     {"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["inputs"]["optical"] = json::object_t{};
+   ctp["inputs"]["electrical"] = json::object_t{{"connector0", "AlfaCtpin"}, {"connector1", "LegacyTopo0"}, {"connector2", "LegacyTopo1"}};
    ctp["monitoring"]["ctpmon"] = json::object_t{};
 
-   // put the menu together
+   // putting the menu together
    json menu({});
    menu["filetype"] = "l1menu";
+   menu["run"] = 2;
    menu["name"] = ctpConfig->name();
    menu["items"] = items;
    menu["thresholds"] = thresholds;
@@ -355,8 +405,6 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
    writer.writeJsonFile(filename, l1menu);
 }
 
-
-
 /**
  * Conversion of bunchgroup set
  **/
-- 
GitLab


From f0cada6090a10c06d225dc63bc5700d820683ed8 Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Thu, 11 Feb 2021 15:43:58 +0100
Subject: [PATCH 08/12] Finalize L1Menu R23 converters, fix prescale set
 converter

---
 .../TrigConfData/src/L1PrescalesSet.cxx       |  2 +-
 .../TrigConfIO/src/JsonFileWriter.cxx         | 12 +--
 .../TrigConfStorage/CMakeLists.txt            |  2 +-
 .../TrigConfStorage/src/test/ReadWrite.cxx    |  6 +-
 ...erters.cxx => Run2toRun3ConvertersHLT.cxx} |  2 -
 ...Converters.h => Run2toRun3ConvertersHLT.h} |  0
 .../src/test/Run2toRun3ConvertersL1.cxx       | 93 +++++++++++--------
 .../src/test/Run2toRun3ConvertersL1.h         | 24 ++++-
 8 files changed, 88 insertions(+), 53 deletions(-)
 rename Trigger/TrigConfiguration/TrigConfStorage/src/test/{Run2toRun3Converters.cxx => Run2toRun3ConvertersHLT.cxx} (97%)
 rename Trigger/TrigConfiguration/TrigConfStorage/src/test/{Run2toRun3Converters.h => Run2toRun3ConvertersHLT.h} (100%)

diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1PrescalesSet.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1PrescalesSet.cxx
index c2d6e75ecdb8..61152f233e14 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/src/JsonFileWriter.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx
index db604d5c0562..208045155f48 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx
@@ -500,17 +500,17 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const L1Me
 bool 
 TrigConf::JsonFileWriter::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({});
@@ -529,12 +529,12 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const Trig
 }
 
 bool TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const TrigConf::L1PrescalesSet & l1ps) const {
-   json j({});
+   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/TrigConfStorage/CMakeLists.txt b/Trigger/TrigConfiguration/TrigConfStorage/CMakeLists.txt
index 77a58e5311cf..35b801d9ccbe 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/Run2toRun3ConvertersL1.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/test/ReadWrite.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
index b02308041dbe..cd021bede27f 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
@@ -43,7 +43,7 @@
 #include "TrigConfJobOptData/JobOptionTable.h"
 
 #include "Run2toRun3ConvertersL1.h"
-#include "Run2toRun3Converters.h"
+#include "Run2toRun3ConvertersHLT.h"
 
 #include "CoolKernel/DatabaseId.h"
 #include "CoolKernel/Exception.h"
@@ -689,9 +689,9 @@ int main( int argc, char* argv[] ) {
        * to JSON
        *-----------------*/
       if(ctpc && l1tm) {
-         convertRun2BunchGroupsToRun3(ctpc, gConfig.bgkJsonOutFile);
-         convertRun2L1PrescalesToRun3(ctpc, gConfig.l1PSJsonOutFile);
          convertRun2L1MenuToRun3(ctpc, l1tm, gConfig.l1JsonOutFile);
+         convertRun2L1PrescalesToRun3(ctpc, gConfig.l1PSJsonOutFile);
+         convertRun2BunchGroupsToRun3(ctpc, gConfig.bgkJsonOutFile);
       }
       if(hltFrame) {
          convertRun2HLTMenuToRun3(hltFrame, gConfig.hltJsonOutFile);
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersHLT.cxx
similarity index 97%
rename from Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.cxx
rename to Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersHLT.cxx
index 443e3cbe12e7..4cd45e01f635 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersHLT.cxx
@@ -128,7 +128,6 @@ 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);
 
 }
@@ -156,7 +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);
 }
 
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.h b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersHLT.h
similarity index 100%
rename from Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3Converters.h
rename to Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersHLT.h
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
index f1d805570946..1f049ad86ab8 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
@@ -75,7 +75,8 @@ namespace {
  * Conversion of L1 menu
  **/
 void
-convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoMenu* topoMenu, const std::string& filename)
+convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoMenu* topoMenu, 
+                        const std::string& filename, bool writeTmpFile)
 {
 
    if( !ctpConfig ) {
@@ -392,12 +393,13 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
    menu["connectors"] = connectors;
    menu["ctp"] = ctp;
 
-   std::ofstream outfile("tmp" + filename);
-   outfile << std::setw(4) << menu << std::endl;
-   std::cout << "Wrote tmp" << filename << std::endl;
-
+   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.dump();
+   ss << menu;
    ptree top;
    boost::property_tree::read_json(ss, top);
    TrigConf::L1Menu l1menu(std::move(top));
@@ -437,40 +439,46 @@ toRanges(const std::vector<int>& bunches) {
 }
 
 void
-convertRun2BunchGroupsToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string& filename) {
-
+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;
    }
 
-   ptree top;
-   top.put("filetype", "bunchgroupset");
-   top.put("name", bgs.name());
+   json bgset;
+   bgset["filetype"] ="bunchgroupset";
+   bgset["name"] = bgs.name();
 
-   ptree pGroups;
+   json jGroups;
    const std::vector<TrigConf::BunchGroup>& bgVec = bgs.bunchGroups();
-   for (auto group : bgVec) {
+   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, " + std::to_string(ranges.size()) + " groups" );
-
-      ptree pBCIDS;
+      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) {
-         ptree pTrain;
-         pTrain.put("first", start );
-         pTrain.put("length", 1+end-start );
-         pBCIDS.push_back(std::make_pair("", pTrain));
+         jBCIDS += json{{"first", start}, {"length", 1+end-start}};
       }
-      pGroup.push_back(std::make_pair("bcids", pBCIDS));
+      jGroup["bcids"] = jBCIDS;
+
+      jGroups[std::string("BGRP")+std::to_string(group.internalNumber())] = jGroup;
+   }
+   bgset["bunchGroups"] = jGroups;
 
-      pGroups.push_back(std::make_pair(std::string("BGRP")+std::to_string(group.internalNumber()), pGroup));
+   if(writeTmpFile) {
+      std::ofstream outfile("tmp" + filename);
+      outfile << std::setw(4) << bgset << std::endl;
+      std::cout << "Wrote tmp" << filename << std::endl;
    }
-   top.push_back(std::make_pair("bunchGroups", pGroups));
+   std::stringstream ss;
+   ss << bgset;
+   ptree top;
+   boost::property_tree::read_json(ss, top);
    TrigConf::L1BunchGroupSet newbgs(std::move(top));
    TrigConf::JsonFileWriter writer;
    writer.writeJsonFile(filename, newbgs);
@@ -480,29 +488,40 @@ convertRun2BunchGroupsToRun3(const TrigConf::CTPConfig* ctpConfig, const std::st
  * Conversion of L1 prescales set
  **/
 void
-convertRun2L1PrescalesToRun3(const TrigConf::CTPConfig* ctpConfig, const std::string& filename) {
+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;
    }
 
-   ptree top;
-   top.put("filetype", "l1prescale");
-   top.put("name", l1pss.name());
-   ptree pCuts;
+   json psset;
+   psset["filetype"] = "l1prescale";
+   psset["name"] = l1pss.name();
+   json jCuts;
    for (size_t id = 0; id < l1pss.prescales_float().size(); ++id) {
-      ptree pCut;
+      json jCut;
       auto itemPtr = ctpConfig->menu().item(id);
       if ( itemPtr != nullptr ) {
-         pCut.put("cut", l1pss.cuts().at(id));
-         pCut.put("enabled", l1pss.prescales_float().at(id) > 0.0 );
-         pCut.put("info", "prescale: "+std::to_string(l1pss.prescales_float().at(id)));
-         pCuts.push_back(std::make_pair(itemPtr->name(), pCut));
+         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;
       }
    }
-   top.push_back(std::make_pair("cutValues", pCuts));
+   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::JsonFileWriter writer;
    writer.writeJsonFile(filename, ps);
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h
index 424e34b69505..4580ea04ff62 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.h
@@ -2,6 +2,24 @@
 #include "TrigConfL1Data/CTPConfig.h"
 #include "L1TopoConfig/L1TopoMenu.h"
 
-void convertRun2L1MenuToRun3(const TrigConf::CTPConfig* frame, const TXC::L1TopoMenu * topoMenu, const std::string& filename);
-void convertRun2BunchGroupsToRun3(const TrigConf::CTPConfig* frame, const std::string& filename);
-void convertRun2L1PrescalesToRun3(const TrigConf::CTPConfig* frame, const std::string& filename);
+/** @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);
-- 
GitLab


From 2ce193d56e71142d7afabd0148b809635c9c386d Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Thu, 11 Feb 2021 15:57:37 +0100
Subject: [PATCH 09/12] Rename JsonFileWriter to JsonFileWriterL1 to match HLT

---
 .../{JsonFileWriter.h => JsonFileWriterL1.h}         |  8 ++++----
 .../TrigConfIO/src/JsonFileWriterHLT.cxx             |  4 ++--
 .../src/{JsonFileWriter.cxx => JsonFileWriterL1.cxx} | 12 ++++++------
 .../TrigConfIO/utils/TriggerMenuRW.cxx               |  4 ++--
 .../src/test/Run2toRun3ConvertersL1.cxx              |  8 ++++----
 5 files changed, 18 insertions(+), 18 deletions(-)
 rename Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/{JsonFileWriter.h => JsonFileWriterL1.h} (82%)
 rename Trigger/TrigConfiguration/TrigConfIO/src/{JsonFileWriter.cxx => JsonFileWriterL1.cxx} (97%)

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 dc654f4b47dc..d3a6a5accc68 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 cebb43cc8149..eb1a38ac4df2 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 97%
rename from Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx
rename to Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterL1.cxx
index 208045155f48..79b8d8dd9a83 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriter.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterL1.cxx
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
-#include "TrigConfIO/JsonFileWriter.h"
+#include "TrigConfIO/JsonFileWriterL1.h"
 
 #include <iomanip>
 #include <fstream>
@@ -13,13 +13,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({});
@@ -498,7 +498,7 @@ 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;
    j["filetype"] = "bunchgroupset";
@@ -528,7 +528,7 @@ TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const Trig
    return true;
 }
 
-bool TrigConf::JsonFileWriter::writeJsonFile(const std::string & filename, const TrigConf::L1PrescalesSet & l1ps) const {
+bool TrigConf::JsonFileWriterL1::writeJsonFile(const std::string & filename, const TrigConf::L1PrescalesSet & l1ps) const {
    json j;
    j["filetype"] = "l1prescale";
    j["name"]  = l1ps.name();
diff --git a/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx b/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx
index 02843ecb1412..2189df1e4345 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/src/test/Run2toRun3ConvertersL1.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
index 1f049ad86ab8..d36df089001c 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
@@ -24,7 +24,7 @@
 #include "TrigConfL1Data/BunchGroupSet.h"
 #include "TrigConfL1Data/BunchGroup.h"
 
-#include "TrigConfIO/JsonFileWriter.h"
+#include "TrigConfIO/JsonFileWriterL1.h"
 
 #include <nlohmann/json.hpp>
 
@@ -403,7 +403,7 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
    ptree top;
    boost::property_tree::read_json(ss, top);
    TrigConf::L1Menu l1menu(std::move(top));
-   TrigConf::JsonFileWriter writer;
+   TrigConf::JsonFileWriterL1 writer;
    writer.writeJsonFile(filename, l1menu);
 }
 
@@ -480,7 +480,7 @@ convertRun2BunchGroupsToRun3(const TrigConf::CTPConfig* ctpConfig, const std::st
    ptree top;
    boost::property_tree::read_json(ss, top);
    TrigConf::L1BunchGroupSet newbgs(std::move(top));
-   TrigConf::JsonFileWriter writer;
+   TrigConf::JsonFileWriterL1 writer;
    writer.writeJsonFile(filename, newbgs);
 }
 
@@ -523,6 +523,6 @@ convertRun2L1PrescalesToRun3(const TrigConf::CTPConfig* ctpConfig, const std::st
    ptree top;
    boost::property_tree::read_json(ss, top);
    TrigConf::L1PrescalesSet ps(std::move(top));
-   TrigConf::JsonFileWriter writer;
+   TrigConf::JsonFileWriterL1 writer;
    writer.writeJsonFile(filename, ps);
 }
-- 
GitLab


From 3fa055ef7379030d98202eac33d9e66c5a95ad2e Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Fri, 12 Feb 2021 13:41:09 +0100
Subject: [PATCH 10/12] Address comment from code review

---
 .../TrigConfIO/src/JsonFileWriterL1.cxx               |  2 +-
 .../TrigConfStorage/src/test/ReadWrite.cxx            |  5 +++--
 .../src/test/Run2toRun3ConvertersL1.cxx               | 11 ++++++-----
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterL1.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterL1.cxx
index 79b8d8dd9a83..c8526f1ea55a 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterL1.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterL1.cxx
@@ -93,7 +93,7 @@ TrigConf::JsonFileWriterL1::writeJsonFile(const std::string & filename, const L1
             jThr["thrValues"] = json::array_t({});
             for(auto & rv : EMThr.thrValues()) {
                json jRV({});
-               jRV["value"] = (unsigned int)rv.value();
+               jRV["value"] = static_cast<unsigned int>(rv.value());
                jRV["etamin"] = rv.etaMin();
                jRV["etamax"] = rv.etaMax();
                jRV["phimin"] = 0; // never used, so not read 
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
index cd021bede27f..55ebc06ccf56 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/ReadWrite.cxx
@@ -716,8 +716,9 @@ int main( int argc, char* argv[] ) {
          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";
diff --git a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
index d36df089001c..094ec340d9b7 100644
--- a/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
+++ b/Trigger/TrigConfiguration/TrigConfStorage/src/test/Run2toRun3ConvertersL1.cxx
@@ -118,8 +118,8 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
       }
       if(thrType=="MUON") {
          thrType = "MU";
-      }
-      if(thrType=="TOPO") {
+      } 
+      else if(thrType=="TOPO") {
          thrType = "R2TOPO";
       }
 
@@ -277,10 +277,10 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
       if(cableName=="ALFA") {
          cableName = "AlfaCtpin";
       }
-      if(cableName=="TOPO1") {
+      else if(cableName=="TOPO1") {
          cableName = "LegacyTopo0";
       }
-      if(cableName=="TOPO2") {
+      else if(cableName=="TOPO2") {
          cableName = "LegacyTopo1";
       }
       triggerlinesMap[cableName].push_back(sourceThr);
@@ -413,8 +413,9 @@ convertRun2L1MenuToRun3(const TrigConf::CTPConfig* ctpConfig, const TXC::L1TopoM
 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() )
+   if ( bunches.empty() ) {
       return {};
+   }
    if (bunches.size() == 1) {
       return { {bunches.front(), bunches.front()} };
    }
-- 
GitLab


From 4570ee7f3e58e390c95f90d7c972d12844aac4bc Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Sat, 13 Feb 2021 10:23:40 +0100
Subject: [PATCH 11/12] changed some casts per review comment

---
 Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx   |  2 +-
 .../TrigConfIO/src/JsonFileWriterL1.cxx                | 10 ++++------
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx
index 095d448ccb0d..99f25c23845b 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx
@@ -21,7 +21,7 @@ TrigConf::L1CTP::load()
       for(size_t conn=0; conn<4; ++conn) {
          m_ctpin[slot-7][conn] = inputs.get_optional<std::string>("ctpin.slot" + std::to_string(slot) + ".connector" + std::to_string(conn)).get_value_or("");
       }
-   }
+   }ø
    auto electrical = inputs.get_child("electrical");
    for(size_t i=0; i<3; ++i) {
       m_electrical[i] = electrical.get_optional<std::string>("connector" + std::to_string(i)).get_value_or("");
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterL1.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterL1.cxx
index c8526f1ea55a..ddbeb68508d5 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterL1.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileWriterL1.cxx
@@ -1,6 +1,4 @@
-/*
-  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/JsonFileWriterL1.h"
 
@@ -114,7 +112,7 @@ TrigConf::JsonFileWriterL1::writeJsonFile(const std::string & filename, const L1
             jThr["thrValues"] = json::array_t({});
             for(auto & rv : JThr.thrValues()) {
                json jRV({});
-               jRV["value"] = (unsigned int)rv.value();
+               jRV["value"] = static_cast<unsigned int>(rv.value());
                jRV["etamin"] = rv.etaMin();
                jRV["etamax"] = rv.etaMax();
                jRV["phimin"] = 0; // never used, so not read 
@@ -130,7 +128,7 @@ TrigConf::JsonFileWriterL1::writeJsonFile(const std::string & filename, const L1
             //jThr["thrValues"] = json::array_t({});
             for(auto & rv : teThr.thrValues()) {
                json jRV({});
-               jRV["value"] = (unsigned int)rv.value();
+               jRV["value"] = static_cast<unsigned int>(rv.value());
                jRV["etamin"] = rv.etaMin();
                jRV["etamax"] = rv.etaMax();
                jRV["priority"] = rv.priority();
@@ -154,7 +152,7 @@ TrigConf::JsonFileWriterL1::writeJsonFile(const std::string & filename, const L1
             jThr["thrValues"] = json::value_t::array;
             for(auto & rv : eEMThr.thrValues()) {
                json jRV({});
-               jRV["value"] = (unsigned int)rv.value();
+               jRV["value"] = static_cast<unsigned int>(rv.value());
                jRV["etamin"] = rv.etaMin();
                jRV["etamax"] = rv.etaMax();
                jRV["priority"] = rv.priority();
-- 
GitLab


From 9014d74988bbf45c4acf8585c44894c4bbbc00d0 Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Mon, 15 Feb 2021 10:16:46 +0100
Subject: [PATCH 12/12] Remove stray character

---
 Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx
index 99f25c23845b..095d448ccb0d 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1CTP.cxx
@@ -21,7 +21,7 @@ TrigConf::L1CTP::load()
       for(size_t conn=0; conn<4; ++conn) {
          m_ctpin[slot-7][conn] = inputs.get_optional<std::string>("ctpin.slot" + std::to_string(slot) + ".connector" + std::to_string(conn)).get_value_or("");
       }
-   }ø
+   }
    auto electrical = inputs.get_child("electrical");
    for(size_t i=0; i<3; ++i) {
       m_electrical[i] = electrical.get_optional<std::string>("connector" + std::to_string(i)).get_value_or("");
-- 
GitLab