From 5cda02fd7af653a7806682da1c1340f300b6ca5e Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Wed, 9 Sep 2020 21:53:41 +0200
Subject: [PATCH 1/4] TrigConfData improvements

---
 .../TrigConfData/TrigConfData/DataStructure.h |   2 +
 .../TrigConfData/TrigConfData/HLTChain.h      |   3 +-
 .../TrigConfData/TrigConfData/HLTMenu.h       |   6 +
 .../TrigConfData/HLTPrescalesSet.h            |   5 +
 .../TrigConfData/TrigConfData/L1Menu.h        |   5 +
 .../TrigConfData/L1PrescalesSet.h             |   5 +
 .../TrigConfData/L1ThrExtraInfo.h             |   7 +
 .../TrigConfData/TrigConfData/L1Threshold.h   |  12 ++
 .../TrigConfData/L1ThresholdBase.h            |   4 +-
 .../TrigConfData/TrigConfData/L1TopoOutput.h  |   5 +
 .../TrigConfData/src/DataStructure.cxx        |   7 +-
 .../TrigConfData/src/HLTChain.cxx             |  15 +-
 .../TrigConfData/src/HLTMenu.cxx              |  26 ++--
 .../TrigConfData/src/L1Menu.cxx               | 141 ++++++++++--------
 .../TrigConfData/src/L1ThrExtraInfo.cxx       |  16 +-
 .../TrigConfData/src/L1ThresholdBase.cxx      |   7 +-
 16 files changed, 177 insertions(+), 89 deletions(-)

diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/DataStructure.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/DataStructure.h
index b08be272fa36..29b2a9d3622f 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/DataStructure.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/DataStructure.h
@@ -51,7 +51,9 @@ namespace TrigConf {
        * @param data Reference to the data container 
        */
       DataStructure(const ptree & data);
+      DataStructure(const std::string & name, const ptree & data);
       DataStructure(ptree && data);
+      DataStructure(const std::string & name, ptree && data);
 
       /** Destructor */
       virtual ~DataStructure();
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTChain.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTChain.h
index c0755dda2697..6c3e26b34e26 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTChain.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTChain.h
@@ -25,6 +25,7 @@ namespace TrigConf {
        * @param data The data containing the HLT chain configuration 
        */      
       Chain(const boost::property_tree::ptree & data);
+      Chain(const std::string & name, const boost::property_tree::ptree & data);
 
       /** Destructor */
       virtual ~Chain();
@@ -57,7 +58,7 @@ namespace TrigConf {
 
    private:
       void update() override;
-
+      void load();
    };
 
 }
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTMenu.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTMenu.h
index ec4457006044..e5cd8fad4c67 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTMenu.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTMenu.h
@@ -32,6 +32,11 @@ namespace TrigConf {
       /** Destructor */
       ~HLTMenu();
 
+      // class name
+      virtual std::string className() const override {
+         return "HLTMenu";
+      }
+
       /** Accessor to the number of HLT chains */
       std::size_t size() const;
 
@@ -62,6 +67,7 @@ namespace TrigConf {
 
    private:
       void update() override;
+      void load();
 
       /** the supermasterkey */
       unsigned int m_smk {0};
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTPrescalesSet.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTPrescalesSet.h
index dc9305ad00dc..544bf8f9e99a 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTPrescalesSet.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTPrescalesSet.h
@@ -37,6 +37,11 @@ namespace TrigConf {
       /** Destructor */
       ~HLTPrescalesSet();
 
+      // class name
+      virtual std::string className() const override {
+         return "HLTPrescaleSet";
+      }
+
       /** number of HLT prescales */
       std::size_t size() const;
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h
index 41cdf90ea838..719e4ed293f3 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h
@@ -40,6 +40,11 @@ namespace TrigConf {
       /** Destructor */
       virtual ~L1Menu();
 
+      // class name
+      virtual std::string className() const override {
+         return "L1Menu";
+      }
+
       /** Accessor to the menu version */
       unsigned int version() const;
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1PrescalesSet.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1PrescalesSet.h
index 0303b2494937..041ec9e03419 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1PrescalesSet.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1PrescalesSet.h
@@ -40,6 +40,11 @@ namespace TrigConf {
       /** Destructor */
       virtual ~L1PrescalesSet();
 
+      // class name
+      virtual std::string className() const override {
+         return "L1PrescaleSet";
+      }
+
       /** number of L1 prescales */
       std::size_t size() const;
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThrExtraInfo.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThrExtraInfo.h
index 11991abdcda6..203fc5117367 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThrExtraInfo.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThrExtraInfo.h
@@ -78,6 +78,7 @@ namespace TrigConf {
       L1ThrExtraInfo_JETLegacy(const std::string & thrTypeName, const ptree & data) :
          L1ThrExtraInfoBase(thrTypeName, data) { load(); }
       virtual ~L1ThrExtraInfo_JETLegacy() = default;
+      virtual std::string className() const { return "L1ThrExtraInfo_JETLegacy"; }
       unsigned int jetScale() const { return 1000 / resolutionMeV(); }
       float ptMinToTopoLargeWindow() const { return m_ptMinToTopoLargeWindowMeV / 1000.0f; }
       float ptMinToTopoSmallWindow() const { return m_ptMinToTopoSmallWindowMeV / 1000.0f; }
@@ -99,6 +100,7 @@ namespace TrigConf {
       L1ThrExtraInfo_XSLegacy(const std::string & thrTypeName, const ptree & data) :
          L1ThrExtraInfoBase(thrTypeName, data) { load(); }
       virtual ~L1ThrExtraInfo_XSLegacy() = default;
+      virtual std::string className() const { return "L1ThrExtraInfo_XSLegacy"; }
       unsigned int xeMin() const { return m_xeMin; };
       unsigned int xeMax() const { return m_xeMax; };
       unsigned int teSqrtMin() const { return m_teSqrtMin; };
@@ -126,6 +128,7 @@ namespace TrigConf {
       L1ThrExtraInfo_eEMTAU(const std::string & thrTypeName, const ptree & data) :
          L1ThrExtraInfoBase(thrTypeName, data) { load(); }
       virtual ~L1ThrExtraInfo_eEMTAU() = default;
+      virtual std::string className() const { return "L1ThrExtraInfo_eEMTAU"; }
       float ptMinToTopo() const { return m_ptMinToTopoMeV/1000.0f; }
       unsigned int ptMinToTopoMeV() const { return m_ptMinToTopoMeV; }
       unsigned int ptMinToTopoCounts() const { return energyInCounts( m_ptMinToTopoMeV, resolutionMeV() ); }
@@ -145,6 +148,7 @@ namespace TrigConf {
       L1ThrExtraInfo_jJ(const std::string & thrTypeName, const ptree & data) :
          L1ThrExtraInfoBase(thrTypeName, data) { load(); }
       virtual ~L1ThrExtraInfo_jJ() = default;
+      virtual std::string className() const { return "L1ThrExtraInfo_jJ"; }
       float ptMinToTopoLarge(int eta = 0) const { return ptMinToTopoLargeMeV(eta) / 1000.0f; }
       float ptMinToTopoSmall(int eta = 0) const { return ptMinToTopoSmallMeV(eta) / 1000.0f; }
       unsigned int ptMinToTopoLargeMeV(int eta = 0) const { return m_ptMinToTopoLargeMeV.at(eta); }
@@ -167,6 +171,7 @@ namespace TrigConf {
       L1ThrExtraInfo_jTAU(const std::string & thrTypeName, const ptree & data) :
          L1ThrExtraInfoBase(thrTypeName, data) { load(); }
       virtual ~L1ThrExtraInfo_jTAU() = default;
+      virtual std::string className() const { return "L1ThrExtraInfo_jTAU"; }
       unsigned int ptMinToTopo() const { return m_ptMinToTopo; }
    private:
       /** Update the internal members */
@@ -181,6 +186,7 @@ namespace TrigConf {
       L1ThrExtraInfo_gXE(const std::string & thrTypeName, const ptree & data) :
          L1ThrExtraInfoBase(thrTypeName, data) { load(); }
       virtual ~L1ThrExtraInfo_gXE() = default;
+      virtual std::string className() const { return "L1ThrExtraInfo_gXE"; }
    private:
       /** Update the internal members */
       void load();
@@ -193,6 +199,7 @@ namespace TrigConf {
       L1ThrExtraInfo_MU(const std::string & thrTypeName, const ptree & data) :
          L1ThrExtraInfoBase(thrTypeName, data) { load(); }
       virtual ~L1ThrExtraInfo_MU() = default;
+      virtual std::string className() const { return "L1ThrExtraInfo_MU"; }
       unsigned int rpcIdxForPt(unsigned int pt) const;
       unsigned int tgcIdxForPt(unsigned int pt) const;
       std::vector<unsigned int> knownRpcPtValues() const;
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Threshold.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Threshold.h
index d407b6f88245..41418eeb3d15 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Threshold.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Threshold.h
@@ -19,6 +19,8 @@ namespace TrigConf {
       L1Threshold_EM( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
          L1Threshold_Calo(name, type, m_extraInfo, data) { load(); }
       virtual ~L1Threshold_EM() = default;
+      // class name
+      virtual std::string className() const override { return "L1Threshold_EM"; }
       uint16_t isolationMask(int eta) const { return m_isolationMask.at(eta); }
       void print(std::ostream & os = std::cout) const override;
    protected:
@@ -37,6 +39,7 @@ namespace TrigConf {
       L1Threshold_TAU( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
          L1Threshold_Calo(name, type, m_extraInfo, data) { load(); }
       virtual ~L1Threshold_TAU() = default;
+      virtual std::string className() const override { return "L1Threshold_TAU"; }
       // access functions
       uint16_t isolationMask() const { return m_isolationMask; }
    protected:
@@ -54,6 +57,7 @@ namespace TrigConf {
       L1Threshold_JET( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
          L1Threshold_Calo(name, type, m_extraInfo, data) {};
       virtual ~L1Threshold_JET() = default;
+      virtual std::string className() const override { return "L1Threshold_JET"; }
    };
 
    class L1Threshold_XE final : public L1Threshold_Calo {
@@ -61,6 +65,7 @@ namespace TrigConf {
       L1Threshold_XE( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
          L1Threshold_Calo(name, type, m_extraInfo, data) {};
       virtual ~L1Threshold_XE() = default;
+      virtual std::string className() const override { return "L1Threshold_XE"; }
    };
 
    class L1Threshold_XS final : public L1Threshold_Calo {
@@ -68,6 +73,7 @@ namespace TrigConf {
       L1Threshold_XS( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
          L1Threshold_Calo(name, type, m_extraInfo, data) {};
       virtual ~L1Threshold_XS() = default;
+      virtual std::string className() const override { return "L1Threshold_XS"; }
    };
 
    class L1Threshold_TE final : public L1Threshold_Calo {
@@ -75,6 +81,7 @@ namespace TrigConf {
       L1Threshold_TE( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
          L1Threshold_Calo(name, type, m_extraInfo, data) {};
       virtual ~L1Threshold_TE() = default;
+      virtual std::string className() const override { return "L1Threshold_TE"; }
    };
 
    /************************************
@@ -88,6 +95,7 @@ namespace TrigConf {
       L1Threshold_NIM( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
          L1Threshold(name, type, m_extraInfo, data) {};
       virtual ~L1Threshold_NIM() = default;
+      virtual std::string className() const override { return "L1Threshold_NIM"; }
    };
 
    class L1Threshold_internal final : public L1Threshold {
@@ -95,6 +103,7 @@ namespace TrigConf {
       L1Threshold_internal( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
          L1Threshold(name, type, m_extraInfo, data) {};
       virtual ~L1Threshold_internal() = default;
+      virtual std::string className() const override { return "L1Threshold_internal"; }
    };
 
    /************************************
@@ -107,6 +116,7 @@ namespace TrigConf {
       L1Threshold_eEM( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
          L1Threshold_Calo(name, type, m_extraInfo, data) { load(); }
       virtual ~L1Threshold_eEM() = default;
+      virtual std::string className() const override { return "L1Threshold_eEM"; }
       // access functions
       Isolation::WP reta() const { return m_reta; }
       Isolation::WP rhad() const { return m_rhad; }
@@ -129,6 +139,7 @@ namespace TrigConf {
       L1Threshold_eTAU( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
          L1Threshold_Calo(name, type, m_extraInfo, data) { load(); }
       virtual ~L1Threshold_eTAU() = default;
+      virtual std::string className() const override { return "L1Threshold_eTAU"; }
    protected:
       virtual void update() override {
          L1Threshold_Calo::update();
@@ -153,6 +164,7 @@ namespace TrigConf {
       L1Threshold_MU( const std::string & name, const std::string & type, std::weak_ptr<L1ThrExtraInfoBase> m_extraInfo, const ptree & data) :
          L1Threshold(name, type, m_extraInfo, data) { load(); }
       virtual ~L1Threshold_MU() = default;
+      virtual std::string className() const override { return "L1Threshold_MU"; }
 
       float thrValue(int eta = 0) const override;
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThresholdBase.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThresholdBase.h
index f943f2d31122..0e9c5088b809 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThresholdBase.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1ThresholdBase.h
@@ -89,14 +89,14 @@ namespace TrigConf {
 
       const std::string & thresholdTypeName() const;
 
-      bool hasExtraInfo() const;
+      bool hasExtraInfo( const std::string & key = "") const;
 
       unsigned int resolutionMeV() const { 
          return m_resolutionMeV;
       }
 
    protected:
-      virtual void upload() {
+      virtual void update() override {
          load();
       } 
       std::map<std::string, DataStructure> m_extraInfo{};
diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1TopoOutput.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1TopoOutput.h
index 4ecde5a0d142..379b5e0f5da6 100644
--- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1TopoOutput.h
+++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1TopoOutput.h
@@ -28,6 +28,11 @@ namespace TrigConf {
       /** Destructor */
       ~L1TopoOutput();
 
+      // class name
+      virtual std::string className() const override {
+         return "L1TopoOutput";
+      }
+
       /** Accessor to the algorithm name */
       const std::string & algName() const;
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/DataStructure.cxx b/Trigger/TrigConfiguration/TrigConfData/src/DataStructure.cxx
index 0aef851fa601..ec899fea0d8a 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/DataStructure.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/DataStructure.cxx
@@ -12,8 +12,13 @@ TrigConf::DataStructure::DataStructure()
 
 
 TrigConf::DataStructure::DataStructure(const ptree & data) :
+   DataStructure("",data)
+{}
+
+TrigConf::DataStructure::DataStructure(const std::string & name, const ptree & data) :
    m_initialized(true),
-   m_dataPtr(&data)
+   m_dataPtr(&data),
+   m_name(name)
 {}
 
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/HLTChain.cxx b/Trigger/TrigConfiguration/TrigConfData/src/HLTChain.cxx
index bfeeab956451..58aba26533b4 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/HLTChain.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/HLTChain.cxx
@@ -10,15 +10,28 @@ TrigConf::Chain::Chain()
 TrigConf::Chain::Chain(const boost::property_tree::ptree & data) 
    : DataStructure(data)
 {
-   update();
+   load();
+}
+
+TrigConf::Chain::Chain(const std::string & name, const boost::property_tree::ptree & data) 
+   : DataStructure(name, data)
+{
+   load();
 }
 
 void
 TrigConf::Chain::update()
+{
+   load();
+}
+
+void
+TrigConf::Chain::load()
 {
    if(! isInitialized() || empty() ) {
       return;
    }
+   m_name = getAttribute("name", true, m_name);
 }
 
 TrigConf::Chain::~Chain()
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/HLTMenu.cxx b/Trigger/TrigConfiguration/TrigConfData/src/HLTMenu.cxx
index f75ab64a14ed..4a18ea31735c 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/HLTMenu.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/HLTMenu.cxx
@@ -13,15 +13,20 @@ TrigConf::HLTMenu::HLTMenu()
 TrigConf::HLTMenu::HLTMenu(const boost::property_tree::ptree & data) 
    : DataStructure(data)
 {
-   update();
+   load();
 }
 
 TrigConf::HLTMenu::~HLTMenu()
 {}
 
-
 void
 TrigConf::HLTMenu::update()
+{
+   load();
+}
+
+void
+TrigConf::HLTMenu::load()
 {
    if(! isInitialized() || empty() ) {
       return;
@@ -49,7 +54,7 @@ TrigConf::HLTMenu::setSMK(unsigned int smk) {
 TrigConf::HLTMenu::const_iterator
 TrigConf::HLTMenu::begin() const
 {
-    return {data().get_child("chains"), 0,  [](auto & x){auto chain = Chain(x.second); chain.setName(x.first); return chain; }};
+   return {data().get_child("chains"), 0,  [](auto & x){auto chain = Chain(x.first, x.second); return chain; }};
 }
 
 TrigConf::HLTMenu::const_iterator
@@ -64,12 +69,13 @@ std::vector<TrigConf::DataStructure>
 TrigConf::HLTMenu::streams() const
 {
    std::vector<DataStructure> strlist;
-   const auto & streams = data().get_child("streams");
-   strlist.reserve(streams.size());
-
-   for( auto & strData : streams )
-      strlist.emplace_back( strData.second );
-
+   const auto & streams = data().get_child_optional("streams");
+   if(streams) {
+      strlist.reserve(streams->size());
+      for( auto & strData : *streams ) {
+         strlist.emplace_back( strData.second );
+      }
+   }
    return strlist;
 }
 
@@ -78,7 +84,7 @@ void
 TrigConf::HLTMenu::printMenu(bool full) const
 {
    cout << "HLT menu '" << name() << "'" << endl;
-   cout << "Streams: " << data().get_child("streams").size() << endl;
+   cout << "Streams: " << streams().size() << endl;
    cout << "Chains: " << size() << endl;
    if(full) {
       int c(0);
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx
index 52d4542057ad..59b5347cb3f9 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx
@@ -25,87 +25,92 @@ TrigConf::L1Menu::update()
    if(! isInitialized() || empty() ) {
       return;
    }
-   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;
-         if (thrType == "legacyCalo")
-            continue;
+   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;
+            if (thrType == "legacyCalo")
+               continue;
          
-         // first create the extraInfo object for this type of thresholds
-         auto extraInfo = m_thrExtraInfo.addExtraInfo(thrByType.first,thrByType.second);
-
-         auto & v = m_thresholdsByType[thrType] = std::vector<std::shared_ptr<TrigConf::L1Threshold>>();
-
-         if(thrType == "internal") {
-            for( auto & thr : data().get_child( path + ".internal.names") ) {
-               const std::string thrName = thr.second.data();
-               v.push_back( L1Threshold::createThreshold( thrName, thrType, extraInfo, thr.second ) );
+            // first create the extraInfo object for this type of thresholds
+            auto extraInfo = m_thrExtraInfo.addExtraInfo(thrByType.first,thrByType.second);
+
+            auto & v = m_thresholdsByType[thrType] = std::vector<std::shared_ptr<TrigConf::L1Threshold>>();
+
+            if(thrType == "internal") {
+               for( auto & thr : data().get_child( path + ".internal.names") ) {
+                  const std::string thrName = thr.second.data();
+                  v.push_back( L1Threshold::createThreshold( thrName, thrType, extraInfo, thr.second ) );
+               }
+            } else {
+               for( auto & thr : data().get_child( path + "." + thrType + ".thresholds") ) {
+                  const std::string thrName = thr.first;
+                  v.push_back( L1Threshold::createThreshold( thrName, thrType, extraInfo, thr.second ) );
+               }
             }
-         } else {
-            for( auto & thr : data().get_child( path + "." + thrType + ".thresholds") ) {
-               const std::string thrName = thr.first;
-               v.push_back( L1Threshold::createThreshold( thrName, thrType, extraInfo, thr.second ) );
+            for( auto & thr : v ) {
+               m_thresholdsByName[ thr->name() ] = thr;
             }
          }
-         for( auto & thr : v ) {
-            m_thresholdsByName[ thr->name() ] = thr;
-         }
-
       }
-   }
 
-   // boards
-   for( auto & board : data().get_child( "boards" ) ) {
-      m_boards.emplace( std::piecewise_construct,
-                        std::forward_as_tuple(board.first),
-                        std::forward_as_tuple(board.first, board.second) );
-   }
+      // boards
+      for( auto & board : data().get_child( "boards" ) ) {
+         m_boards.emplace( std::piecewise_construct,
+                           std::forward_as_tuple(board.first),
+                           std::forward_as_tuple(board.first, board.second) );
+      }
 
-   // connectors
-   for( auto & conn : data().get_child( "connectors" ) ) {
-      auto res = m_connectors.emplace( std::piecewise_construct,
-                                       std::forward_as_tuple(conn.first),
-                                       std::forward_as_tuple(conn.first, conn.second) );
+      // connectors
+      for( auto & conn : data().get_child( "connectors" ) ) {
+         auto res = m_connectors.emplace( std::piecewise_construct,
+                                          std::forward_as_tuple(conn.first),
+                                          std::forward_as_tuple(conn.first, conn.second) );
 
-      for( auto & tl : res.first->second.triggerLineNames() ) {
-         m_threshold2ConnectorName.emplace( std::piecewise_construct,
-                                            std::forward_as_tuple(tl),
-                                            std::forward_as_tuple(conn.first));
+         for( auto & tl : res.first->second.triggerLineNames() ) {
+            m_threshold2ConnectorName.emplace( std::piecewise_construct,
+                                               std::forward_as_tuple(tl),
+                                               std::forward_as_tuple(conn.first));
+         }
       }
-   }
 
-   // algorithms
-   for( const std::string & algoCategory : { "TOPO", "MULTTOPO", "MUTOPO", "R2TOPO" } ) {
-      auto & v = m_algorithmsByCategory[algoCategory] = std::vector<TrigConf::L1TopoAlgorithm>();
-      if(algoCategory == "MULTTOPO") {
-         for( auto & alg : data().get_child( "topoAlgorithms." + algoCategory + ".multiplicityAlgorithms" ) ) {
-            v.emplace_back( alg.first, L1TopoAlgorithm::AlgorithmType::MULTIPLICITY, algoCategory, alg.second );
-         }
-      } else {
-         for( L1TopoAlgorithm::AlgorithmType algoType : { L1TopoAlgorithm::AlgorithmType::DECISION, L1TopoAlgorithm::AlgorithmType::SORTING } ) {
-            std::string subpath = "topoAlgorithms." + algoCategory + (algoType==L1TopoAlgorithm::AlgorithmType::DECISION ? ".decisionAlgorithms" : ".sortingAlgorithms" );  
-            for( auto & algorithm : data().get_child( subpath ) ) {
-               v.emplace_back( algorithm.first, algoType, algoCategory, algorithm.second );
+      // algorithms
+      for( const std::string & algoCategory : { "TOPO", "MULTTOPO", "MUTOPO", "R2TOPO" } ) {
+         auto & v = m_algorithmsByCategory[algoCategory] = std::vector<TrigConf::L1TopoAlgorithm>();
+         if(algoCategory == "MULTTOPO") {
+            for( auto & alg : data().get_child( "topoAlgorithms." + algoCategory + ".multiplicityAlgorithms" ) ) {
+               v.emplace_back( alg.first, L1TopoAlgorithm::AlgorithmType::MULTIPLICITY, algoCategory, alg.second );
+            }
+         } else {
+            for( L1TopoAlgorithm::AlgorithmType algoType : { L1TopoAlgorithm::AlgorithmType::DECISION, L1TopoAlgorithm::AlgorithmType::SORTING } ) {
+               std::string subpath = "topoAlgorithms." + algoCategory + (algoType==L1TopoAlgorithm::AlgorithmType::DECISION ? ".decisionAlgorithms" : ".sortingAlgorithms" );  
+               for( auto & algorithm : data().get_child( subpath ) ) {
+                  v.emplace_back( algorithm.first, algoType, algoCategory, algorithm.second );
+               }
             }
          }
-      }
-      for( auto & algo : v ) {
-         if( m_algorithmsByName[algoCategory].count(algo.name()) > 0 ) {
-            std::cerr << "ERROR : Topo algorithm with name " << algo.name() << " and of type " << algoCategory << " already exists" << std::endl;
-            throw std::runtime_error("Found duplicate topo algorithm name " + algo.name() + " of type " + algoCategory);
-         }
-         m_algorithmsByName[ algoCategory ][ algo.name() ] = & algo;
-         for( const std::string & output : algo.outputs() ) {
-            if( m_algorithmsByOutput[algoCategory].count(output) > 0 ) {
-               std::cerr << "ERROR : Topo algorithm output " << output << " already exists" << std::endl;
-               throw std::runtime_error("Found duplicate topo algorithm output " + output + " of type " + algoCategory);
+         for( auto & algo : v ) {
+            if( m_algorithmsByName[algoCategory].count(algo.name()) > 0 ) {
+               std::cerr << "ERROR : Topo algorithm with name " << algo.name() << " and of type " << algoCategory << " already exists" << std::endl;
+               throw std::runtime_error("Found duplicate topo algorithm name " + algo.name() + " of type " + algoCategory);
+            }
+            m_algorithmsByName[ algoCategory ][ algo.name() ] = & algo;
+            for( const std::string & output : algo.outputs() ) {
+               if( m_algorithmsByOutput[algoCategory].count(output) > 0 ) {
+                  std::cerr << "ERROR : Topo algorithm output " << output << " already exists" << std::endl;
+                  throw std::runtime_error("Found duplicate topo algorithm output " + output + " of type " + algoCategory);
+               }
+               m_algorithmsByOutput[algoCategory][output] = & algo;
             }
-            m_algorithmsByOutput[algoCategory][output] = & algo;
          }
       }
    }
+   catch(std::exception & ex) {
+      std::cerr << "ERROR: problem when building L1 menu structure. " << ex.what() << std::endl;
+      throw;
+   }
 }
 
 unsigned int 
@@ -379,6 +384,12 @@ TrigConf::L1Menu::printMenu(bool full) const
 {
    cout << "L1 menu '" << name() << "'" << endl;
    cout << "Items: " << size() << endl;
+   if(full) {
+      int c(0);
+      for(const L1Item & item : *this ) {
+         cout << "  " << c++ << ": " << item.name() << endl;
+      }
+   }
    cout << "Thresholds: " << thresholds().size() << "(of " << thresholdTypes().size() << " different types)" << endl;
    if(full) {
       int c(0);
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1ThrExtraInfo.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1ThrExtraInfo.cxx
index ef30d09c6cb2..5dd54db85529 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1ThrExtraInfo.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1ThrExtraInfo.cxx
@@ -153,13 +153,15 @@ TrigConf::L1ThrExtraInfo_EMTAULegacy::load()
 void
 TrigConf::L1ThrExtraInfo_XSLegacy::load()
 {
-   auto sig = m_extraInfo["significance"];
-   m_xeMin = sig.getAttribute<unsigned int>("xeMin");
-   m_xeMax = sig.getAttribute<unsigned int>("xeMax");
-   m_teSqrtMin = sig.getAttribute<unsigned int>("teSqrtMin");
-   m_teSqrtMax = sig.getAttribute<unsigned int>("teSqrtMax");
-   m_xsSigmaScale = sig.getAttribute<unsigned int>("xsSigmaScale");
-   m_xsSigmaOffset = sig.getAttribute<unsigned int>("xsSigmaOffset");
+   if( hasExtraInfo("significance") ) {
+      auto & sig = m_extraInfo["significance"];
+      m_xeMin = sig.getAttribute<unsigned int>("xeMin");
+      m_xeMax = sig.getAttribute<unsigned int>("xeMax");
+      m_teSqrtMin = sig.getAttribute<unsigned int>("teSqrtMin");
+      m_teSqrtMax = sig.getAttribute<unsigned int>("teSqrtMax");
+      m_xsSigmaScale = sig.getAttribute<unsigned int>("xsSigmaScale");
+      m_xsSigmaOffset = sig.getAttribute<unsigned int>("xsSigmaOffset");
+   }
 }
 
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1ThresholdBase.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1ThresholdBase.cxx
index 9afe50ca08dd..d279f1c7d894 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1ThresholdBase.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1ThresholdBase.cxx
@@ -149,9 +149,12 @@ TrigConf::L1ThrExtraInfoBase::thresholdTypeName() const
 }
 
 bool
-TrigConf::L1ThrExtraInfoBase::hasExtraInfo() const
+TrigConf::L1ThrExtraInfoBase::hasExtraInfo(const std::string & key) const
 {
-   return m_extraInfo.size()>0;
+   if( key.empty() ) {
+      return m_extraInfo.size()>0;
+   }
+   return m_extraInfo.count(key)>0;
 }
 
 
-- 
GitLab


From 836213e3f9ebed835b789c71cb0c69ac880a783e Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Wed, 9 Sep 2020 21:55:01 +0200
Subject: [PATCH 2/4] DB loading using schema version

---
 .../TrigConfIO/TrigDBJobOptionsLoader.h       |   5 +
 .../TrigConfIO/TrigConfIO/TrigDBLoader.h      |  16 +-
 .../TrigConfIO/TrigConfIO/TrigDBMenuLoader.h  |   9 +
 .../TrigConfIO/src/TrigDBJobOptionsLoader.cxx | 136 +++++----
 .../TrigConfIO/src/TrigDBLoader.cxx           |  60 +++-
 .../TrigConfIO/src/TrigDBMenuLoader.cxx       | 279 +++++++++---------
 .../utils/TestTriggerMenuAccess.cxx           |   1 -
 .../TrigConfIO/utils/TriggerMenuRW.cxx        |  11 +-
 8 files changed, 291 insertions(+), 226 deletions(-)

diff --git a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBJobOptionsLoader.h b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBJobOptionsLoader.h
index 29c7a1835279..84c5a3ecd516 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBJobOptionsLoader.h
+++ b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBJobOptionsLoader.h
@@ -18,6 +18,8 @@
 
 #include "TrigConfIO/TrigDBLoader.h"
 
+#include <map>
+
 namespace TrigConf {
 
    /**
@@ -49,6 +51,9 @@ namespace TrigConf {
       bool loadJobOptions ( unsigned int smk,
                             DataStructure & jobOptions,
                             const std::string & outFileName = "") const;
+   private:
+      TrigConf::QueryDefinition getQueryDefinition(coral::ISessionProxy* session) const;
+      std::map<size_t, QueryDefinition> m_queries;
    };
 
 }
diff --git a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBLoader.h b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBLoader.h
index 4d675a88571e..a412bc84f03d 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBLoader.h
+++ b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBLoader.h
@@ -35,6 +35,12 @@ namespace TrigConf {
       /** Destructor */
       virtual ~TrigDBLoader();
 
+      /**@brief access to TriggerDB schema version
+         goes to the trigger db for the first call, every following call it returns the cached value
+         @return version of the DB schema (0 - not yet checked, >0 - schema version) 
+       */
+      size_t schemaVersion(coral::ISessionProxy* session) const;
+
       /** write data blob into file
           This can be used to write the DB content to file without going through a ptree
        */
@@ -52,11 +58,11 @@ namespace TrigConf {
    private:
 
       // private variables
-      std::string            m_connection {"TRIGGERDB"};
-      int                    m_retrialPeriod {0};
-      int                    m_retrialTimeout {0};
-      int                    m_connectionTimeout {0};
-
+      std::string    m_connection {"TRIGGERDB"};
+      int            m_retrialPeriod {0};
+      int            m_retrialTimeout {0};
+      int            m_connectionTimeout {0};
+      mutable size_t m_schemaVersion {0}; // version of the DB schema (0 - not yet checked, >0 - schema version) 
    };
 
 }
diff --git a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBMenuLoader.h b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBMenuLoader.h
index 2740ec5da98e..debfff51e83f 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBMenuLoader.h
+++ b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBMenuLoader.h
@@ -22,6 +22,8 @@
 
 namespace TrigConf {
 
+   class QueryDefinition;
+
    /**
     * @brief Loader of trigger menu configurations from the database
     */
@@ -75,6 +77,13 @@ namespace TrigConf {
       bool loadHLTMenu ( unsigned int smk,
                          HLTMenu & hltmenu,
                          const std::string & outFileName = "") const;
+   private:
+
+      TrigConf::QueryDefinition getL1QueryDefinition(coral::ISessionProxy* session) const;
+      TrigConf::QueryDefinition getHLTQueryDefinition(coral::ISessionProxy* session) const;
+
+      std::map<size_t, QueryDefinition> m_l1queries;
+      std::map<size_t, QueryDefinition> m_hltqueries;
       
    };
 
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBJobOptionsLoader.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBJobOptionsLoader.cxx
index d922546e23b4..8cabe16898c6 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBJobOptionsLoader.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBJobOptionsLoader.cxx
@@ -7,59 +7,66 @@
 
 TrigConf::TrigDBJobOptionsLoader::TrigDBJobOptionsLoader(const std::string & connection) : 
    TrigDBLoader("TrigDBJobOptionsLoader", connection)
-{}
+{
+   { // query for schema version 1
+      auto & q = m_queries[1];
+      // tables
+      q.addToTableList ( "SUPER_MASTER_TABLE", "SMT" );
+      q.addToTableList ( "JO_MASTER_TABLE", "JOMT" );
+      // bind vars
+      q.extendBinding<int>("smk");
+      // conditions
+      q.extendCondition("SMT.SMT_ID = :smk");
+      q.extendCondition(" AND SMT.SMT_JO_MASTER_TABLE_ID = JOMT.JO_ID");
+      // attributes
+      q.extendOutput<std::string>( "SMT.SMT_NAME" );
+      q.extendOutput<int>        ( "SMT.SMT_JO_MASTER_TABLE_ID" );
+      q.extendOutput<coral::Blob>( "JOMT.JO_CONTENT" );
+      // the field with the data
+      q.setDataName("JOMT.JO_CONTENT");
+   }
+   { // query for schema version 2
+      auto & q = m_queries[2];
+      // tables
+      q.addToTableList ( "SUPER_MASTER_TABLE", "SMT" );
+      q.addToTableList ( "HLT_JOBOPTIONS", "HJO" );
+      // bind vars
+      q.extendBinding<int>("smk");
+      // conditions
+      q.extendCondition("SMT.SMT_ID = :smk");
+      q.extendCondition("AND HJO.HJO_ID=SMT.SMT_HLT_JOBOPTIONS_ID");
+      // attributes
+      q.extendOutput<std::string>( "SMT.SMT_NAME" );
+      q.extendOutput<int>        ( "SMT.SMT_HLT_JOBOPTIONS_ID" );
+      q.extendOutput<coral::Blob>( "HJO.HJO_DATA" );
+      // the field with the data
+      q.setDataName("HJO.HJO_DATA");
+   }
+}
 
 TrigConf::TrigDBJobOptionsLoader::~TrigDBJobOptionsLoader()
 {}
 
-
-namespace {
-   std::vector<TrigConf::QueryDefinition>
-   getQueryDefinitions() {
-      std::vector<TrigConf::QueryDefinition> queries;
-
-      { // query for table dev1
-         queries.emplace_back();
-         auto & q = queries.back();
-         // tables
-         q.addToTableList ( "SUPER_MASTER_TABLE", "SMT" );
-         q.addToTableList ( "HLT_JOBOPTIONS", "HJO" );
-         // bind vars
-         q.extendBinding<int>("smk");
-         // conditions
-         q.extendCondition("SMT.SMT_ID = :smk");
-         q.extendCondition("AND HJO.HJO_ID=SMT.SMT_HLT_JOBOPTIONS_ID");
-         // attributes
-         q.extendOutput<std::string>( "SMT.SMT_NAME" );
-         q.extendOutput<int>        ( "SMT.SMT_HLT_JOBOPTIONS_ID" );
-         q.extendOutput<coral::Blob>( "HJO.HJO_DATA" );
-         // the field with the data
-         q.setDataName("HJO.HJO_DATA");
-      }
-
-      { // query for table dev2
-         queries.emplace_back();
-         auto & q = queries.back();
-         // tables
-         q.addToTableList ( "SUPER_MASTER_TABLE", "SMT" );
-         q.addToTableList ( "JO_MASTER_TABLE", "JOMT" );
-         // bind vars
-         q.extendBinding<int>("smk");
-         // conditions
-         q.extendCondition("SMT.SMT_ID = :smk");
-         q.extendCondition(" AND SMT.SMT_JO_MASTER_TABLE_ID = JOMT.JO_ID");
-         // attributes
-         q.extendOutput<std::string>( "SMT.SMT_NAME" );
-         q.extendOutput<int>        ( "SMT.SMT_JO_MASTER_TABLE_ID" );
-         q.extendOutput<coral::Blob>( "JOMT.JO_CONTENT" );
-         // the field with the data
-         q.setDataName("JOMT.JO_CONTENT");
+TrigConf::QueryDefinition
+TrigConf::TrigDBJobOptionsLoader::getQueryDefinition(coral::ISessionProxy* session) const
+{
+   size_t sv = schemaVersion( session );
+   // find the largest version key in the map of defined queries that is <= the schemaVersion 
+   size_t maxDefVersion = 0;
+   for(auto & entry : m_queries) {
+      size_t vkey = entry.first;
+      if(vkey>maxDefVersion and vkey<=sv) {
+         maxDefVersion = vkey;
       }
-      return queries;
    }
+   // if nothing found, throw an error
+   if( maxDefVersion==0 ) {
+      TRG_MSG_ERROR("When reading HLT Joboptions: no query for schema version " << sv << " defined" );
+      throw std::runtime_error( "TrigDBJobOptionsLoader: no query available for schema version" );      
+   }
+   return m_queries.at(maxDefVersion);
 }
 
-
 bool
 TrigConf::TrigDBJobOptionsLoader::loadJobOptions ( unsigned int smk,
                                                    boost::property_tree::ptree & jobOptions,
@@ -67,33 +74,22 @@ TrigConf::TrigDBJobOptionsLoader::loadJobOptions ( unsigned int smk,
 {
    auto session = createDBSession();
    session->transaction().start( /*bool readonly=*/ true);
-   bool querySuccess { false };
-   for( auto & qdef : getQueryDefinitions() ) {
-      try {
-         qdef.setBoundValue<int>("smk", smk);
-         auto q = qdef.createQuery( session.get() );
-         auto & cursor = q->execute();
-         querySuccess = true;
-         if ( ! cursor.next() ) {
-            throw std::runtime_error( "TrigDBMenuLoader: SuperMasterKey not available" );
-         }
-         const coral::AttributeList& row = cursor.currentRow();
-         const coral::Blob& dataBlob = row[qdef.dataName()].data<coral::Blob>();
-         writeRawFile( dataBlob, outFileName );
-         blobToPtree( dataBlob, jobOptions );
-         break;
-      }
-      catch(coral::QueryException & ex) {
-         TRG_MSG_INFO("Trying next query after coral::QueryException caught ( " << ex.what() <<" )" );
-         continue;
-      }
-      catch(std::exception & ex) {
-         TRG_MSG_INFO("Trying next query after std::exception caught ( " << ex.what() <<" )" );
-         continue;
+   QueryDefinition qdef = getQueryDefinition(session.get());
+   try {
+      qdef.setBoundValue<int>("smk", smk);
+      auto q = qdef.createQuery( session.get() );
+      auto & cursor = q->execute();
+      if ( ! cursor.next() ) {
+         TRG_MSG_ERROR("Tried reading HLT job options, but SuperMasterKey " << smk << " is not available" );
+         return false;
       }
+      const coral::AttributeList& row = cursor.currentRow();
+      const coral::Blob& dataBlob = row[qdef.dataName()].data<coral::Blob>();
+      writeRawFile( dataBlob, outFileName );
+      blobToPtree( dataBlob, jobOptions );
    }
-   if( ! querySuccess ) {
-      TRG_MSG_ERROR("Could not read the HLT JobOptions data from the database, all query attempts failed");
+   catch(coral::QueryException & ex) {
+      TRG_MSG_ERROR("When reading HLT job options for SMK " << smk << " a coral::QueryException was caught ( " << ex.what() <<" )" );
       return false;
    }
    return true;
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBLoader.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBLoader.cxx
index 9a77fc2e14df..6b1cb5e74f17 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBLoader.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBLoader.cxx
@@ -2,6 +2,7 @@
   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
+#include "./TrigDBHelper.h"
 #include "TrigConfIO/TrigDBLoader.h"
 
 #include "CoralBase/Exception.h"
@@ -10,9 +11,9 @@
 #include "RelationalAccess/ConnectionService.h"
 #include "RelationalAccess/IConnectionServiceConfiguration.h"
 #include "RelationalAccess/ISessionProxy.h"
+#include "RelationalAccess/ISchema.h"
 
 #include "boost/property_tree/ptree.hpp"
-
 #include <fstream>
 
 using ptree = boost::property_tree::ptree;
@@ -26,6 +27,60 @@ TrigConf::TrigDBLoader::TrigDBLoader(const std::string & loaderName, const std::
 TrigConf::TrigDBLoader::~TrigDBLoader()
 {}
 
+namespace {
+   bool startswith(const std::string& str, const std::string& sub) {
+      if(str.size()<sub.size())
+         return false;
+      return (str.compare(0,sub.size(),sub) == 0);
+   }
+}
+
+size_t
+TrigConf::TrigDBLoader::schemaVersion(coral::ISessionProxy* session) const {
+
+   static const std::string versionTagPrefix("Trigger-Run3-Schema-v");
+
+   // if schema version has been set, then return it
+   if(m_schemaVersion>0) {
+      TRG_MSG_INFO("TriggerDB schema version: " << m_schemaVersion);
+      return m_schemaVersion;
+   }
+
+   // if database has no schema version, then we return 0
+   if(! session->nominalSchema().existsTable("TRIGGER_SCHEMA") ) {
+      throw std::runtime_error( "Trigger schema has no schema version table" );
+   }
+   
+   TrigConf::QueryDefinition qdef;
+   // tables
+   qdef.addToTableList ( "TRIGGER_SCHEMA" );
+   // attributes
+   qdef.extendOutput<std::string>( "TS_TAG" );
+
+   auto query = qdef.createQuery( session );
+   auto & cursor = query->execute();
+   if ( ! cursor.next() ) {
+      throw std::runtime_error( "Trigger schema has schema version table but it is empty" );
+   }
+
+   const coral::AttributeList& row = cursor.currentRow();
+   std::string versionTag = row["TS_TAG"].data<std::string>();
+   if( ! startswith(versionTag, versionTagPrefix)) {
+      throw std::runtime_error( "Tag format error: Trigger schema version tag " + versionTag + "does not start with " + versionTagPrefix);      
+   }
+   
+   std::string vstr = versionTag.substr(versionTagPrefix.size()); // the part of the string containing the version 
+   try {
+      m_schemaVersion = std::stoi(vstr);
+   }
+   catch (const std::invalid_argument& ia) {
+      TRG_MSG_ERROR("Invalid argument when interpreting the version part " << vstr << " of schema tag " << versionTag << ". " << ia.what());
+      throw;
+   }
+
+   TRG_MSG_INFO("TriggerDB schema version: " << m_schemaVersion);
+   return m_schemaVersion;
+}
 
 bool
 TrigConf::TrigDBLoader::writeRawFile(const coral::Blob & data, const std::string & outFileName) const
@@ -37,11 +92,10 @@ TrigConf::TrigDBLoader::writeRawFile(const coral::Blob & data, const std::string
    outFile.open( outFileName, std::ofstream::binary );
    outFile.write( static_cast<const char*> ( data.startingAddress()), data.size() );
    outFile.close();
+   TRG_MSG_INFO("Wrote file " << outFileName);
    return true;
 }
 
-
-
 std::unique_ptr<coral::ISessionProxy>
 TrigConf::TrigDBLoader::createDBSession() const {
 
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBMenuLoader.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBMenuLoader.cxx
index e73569ab3aac..b5e093ab9933 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBMenuLoader.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBMenuLoader.cxx
@@ -5,103 +5,126 @@
 
 TrigConf::TrigDBMenuLoader::TrigDBMenuLoader(const std::string & connection) : 
    TrigDBLoader("TrigDBMenuLoader", connection)
-{}
-
-TrigConf::TrigDBMenuLoader::~TrigDBMenuLoader()
-{}
-
-
-namespace {
-   std::vector<TrigConf::QueryDefinition>
-   getL1QueryDefinitions() {
-      std::vector<TrigConf::QueryDefinition> queries;
-
-      { // query for table dev1
-         queries.emplace_back();
-         auto & q = queries.back();
-         // tables
-         q.addToTableList ( "SUPER_MASTER_TABLE", "SMT" );
-         q.addToTableList ( "L1_MENU", "L1TM" );
-         // bind vars
-         q.extendBinding<int>("smk");
-         // conditions
-         q.extendCondition("SMT.SMT_ID = :smk");
-         q.extendCondition(" AND SMT.SMT_L1_MENU_ID = L1TM.L1TM_ID");
-         // attributes
-         q.extendOutput<std::string>( "SMT.SMT_NAME" );
-         q.extendOutput<int>        ( "SMT.SMT_VERSION" );
+{
+   /*
+     L1 menu queries
+   */
+   { // for schema version 1
+      auto & q = m_l1queries[1];
+      // tables
+      q.addToTableList ( "SUPER_MASTER_TABLE", "SMT" );
+      q.addToTableList ( "L1_MASTER_TABLE", "L1MT" );
+      // bind vars
+      q.extendBinding<int>("smk");
+      // conditions
+      q.extendCondition("SMT.SMT_ID = :smk");
+      q.extendCondition(" AND SMT.SMT_L1_MASTER_TABLE_ID = L1MT.L1MT_ID");
+      // attributes
+      q.extendOutput<std::string>( "SMT.SMT_NAME" );
+      q.extendOutput<int>        ( "SMT.SMT_L1_MASTER_TABLE_ID" );
+      q.extendOutput<coral::Blob>( "L1MT.L1MT_MENU" );
+      // the field with the data
+      q.setDataName("L1MT.L1MT_MENU");
+   }
+   { // for schema version 2
+      auto & q = m_l1queries[2];
+      // tables
+      q.addToTableList ( "SUPER_MASTER_TABLE", "SMT" );
+      q.addToTableList ( "L1_MENU", "L1TM" );
+      // bind vars
+      q.extendBinding<int>("smk");
+      // conditions
+      q.extendCondition("SMT.SMT_ID = :smk");
+      q.extendCondition(" AND SMT.SMT_L1_MENU_ID = L1TM.L1TM_ID");
+      // attributes
+      q.extendOutput<std::string>( "SMT.SMT_NAME" );
+      q.extendOutput<int>        ( "SMT.SMT_VERSION" );
          q.extendOutput<int>        ( "SMT.SMT_L1_MENU_ID" );
          q.extendOutput<coral::Blob>( "L1TM.L1TM_DATA" );
          // the field with the data
          q.setDataName("L1TM.L1TM_DATA");
-      }
+   }
 
-      { // query for table dev2
-         queries.emplace_back();
-         auto & q = queries.back();
-         // tables
-         q.addToTableList ( "SUPER_MASTER_TABLE", "SMT" );
-         q.addToTableList ( "L1_MASTER_TABLE", "L1MT" );
-         // bind vars
-         q.extendBinding<int>("smk");
-         // conditions
-         q.extendCondition("SMT.SMT_ID = :smk");
-         q.extendCondition(" AND SMT.SMT_L1_MASTER_TABLE_ID = L1MT.L1MT_ID");
-         // attributes
-         q.extendOutput<std::string>( "SMT.SMT_NAME" );
-         q.extendOutput<int>        ( "SMT.SMT_L1_MASTER_TABLE_ID" );
-         q.extendOutput<coral::Blob>( "L1MT.L1MT_MENU" );
-         // the field with the data
-         q.setDataName("L1MT.L1MT_MENU");
-      }
-      return queries;
+   /*
+     HLT menu queries
+   */
+   { // for schema version 1
+      auto & q = m_hltqueries[1];
+      // tables
+      q.addToTableList ( "SUPER_MASTER_TABLE", "SMT" );
+      q.addToTableList ( "HLT_MASTER_TABLE", "HMT" );
+      // bind vars
+      q.extendBinding<int>("smk");
+      // conditions
+      q.extendCondition("SMT.SMT_ID = :smk");
+      q.extendCondition(" AND SMT.SMT_HLT_MASTER_TABLE_ID = HMT.HMT_ID");
+      // attributes
+      q.extendOutput<std::string>( "SMT.SMT_NAME" );
+      q.extendOutput<int>        ( "SMT.SMT_HLT_MASTER_TABLE_ID" );
+      q.extendOutput<coral::Blob>( "HMT.HMT_MENU" );
+      // the field with the data
+      q.setDataName("HMT.HMT_MENU");
    }
+   { // for schema version 2
+      auto & q = m_hltqueries[2];
+      // tables
+      q.addToTableList ( "SUPER_MASTER_TABLE", "SMT" );
+      q.addToTableList ( "HLT_MENU", "HTM" );
+      // bind vars
+      q.extendBinding<int>("smk");
+      // conditions
+      q.extendCondition("SMT.SMT_ID = :smk");
+      q.extendCondition(" AND SMT.SMT_HLT_MENU_ID = HTM.HTM_ID");
+      // attributes
+      q.extendOutput<std::string>( "SMT.SMT_NAME" );
+      q.extendOutput<int>        ( "SMT.SMT_VERSION" );
+      q.extendOutput<int>        ( "SMT.SMT_HLT_MENU_ID" );
+      q.extendOutput<coral::Blob>( "HTM.HTM_DATA" );
+      // the field with the data
+      q.setDataName("HTM.HTM_DATA");
+   }
+}
 
-   std::vector<TrigConf::QueryDefinition>
-   getHLTQueryDefinitions() {
-      std::vector<TrigConf::QueryDefinition> queries;
+TrigConf::TrigDBMenuLoader::~TrigDBMenuLoader() = default;
 
-      { // query for table dev1
-         queries.emplace_back();
-         auto & q = queries.back();
-         // tables
-         q.addToTableList ( "SUPER_MASTER_TABLE", "SMT" );
-         q.addToTableList ( "HLT_MENU", "HTM" );
-         // bind vars
-         q.extendBinding<int>("smk");
-         // conditions
-         q.extendCondition("SMT.SMT_ID = :smk");
-         q.extendCondition(" AND SMT.SMT_HLT_MENU_ID = HTM.HTM_ID");
-         // attributes
-         q.extendOutput<std::string>( "SMT.SMT_NAME" );
-         q.extendOutput<int>        ( "SMT.SMT_VERSION" );
-         q.extendOutput<int>        ( "SMT.SMT_HLT_MENU_ID" );
-         q.extendOutput<coral::Blob>( "HTM.HTM_DATA" );
-         // the field with the data
-         q.setDataName("HTM.HTM_DATA");
+TrigConf::QueryDefinition
+TrigConf::TrigDBMenuLoader::getL1QueryDefinition(coral::ISessionProxy* session) const
+{
+   size_t sv = schemaVersion( session );
+   // find the largest version key in the map of defined queries that is <= the schemaVersion 
+   size_t maxDefVersion = 0;
+   for(auto & entry : m_l1queries) {
+      size_t vkey = entry.first;
+      if(vkey>maxDefVersion and vkey<=sv) {
+         maxDefVersion = vkey;
       }
+   }
+   // if nothing found, throw an error
+   if( maxDefVersion==0 ) {
+      TRG_MSG_ERROR("When reading L1 menu: no L1Menu query for schema version " << sv << " defined" );
+      throw std::runtime_error( "TrigDBMenuLoader: no L1menu query available for schema version" );      
+   }
+   return m_l1queries.at(maxDefVersion);
+}
 
-      { // query for table dev2
-         queries.emplace_back();
-         auto & q = queries.back();
-         // tables
-         q.addToTableList ( "SUPER_MASTER_TABLE", "SMT" );
-         q.addToTableList ( "HLT_MASTER_TABLE", "HMT" );
-         // bind vars
-         q.extendBinding<int>("smk");
-         // conditions
-         q.extendCondition("SMT.SMT_ID = :smk");
-         q.extendCondition(" AND SMT.SMT_HLT_MASTER_TABLE_ID = HMT.HMT_ID");
-         // attributes
-         q.extendOutput<std::string>( "SMT.SMT_NAME" );
-         q.extendOutput<int>        ( "SMT.SMT_HLT_MASTER_TABLE_ID" );
-         q.extendOutput<coral::Blob>( "HMT.HMT_MENU" );
-         // the field with the data
-         q.setDataName("HMT.HMT_MENU");
+TrigConf::QueryDefinition
+TrigConf::TrigDBMenuLoader::getHLTQueryDefinition(coral::ISessionProxy* session) const
+{
+   size_t sv = schemaVersion( session );
+   // find the largest version key in the map of defined queries that is <= the schemaVersion 
+   size_t maxDefVersion = 0;
+   for(auto & entry : m_hltqueries) {
+      size_t vkey = entry.first;
+      if(vkey>maxDefVersion and vkey<=sv) {
+         maxDefVersion = vkey;
       }
-      return queries;
    }
-
+   // if nothing found, throw an error
+   if( maxDefVersion==0 ) {
+      TRG_MSG_ERROR("When reading HLT menu: no HLTMenu query for schema version " << sv << " defined" );
+      throw std::runtime_error( "TrigDBMenuLoader: no HLTmenu query available for schema version" );      
+   }
+   return m_hltqueries.at(maxDefVersion);
 }
 
 bool
@@ -109,45 +132,29 @@ TrigConf::TrigDBMenuLoader::loadL1Menu ( unsigned int smk,
                                          boost::property_tree::ptree & l1menu,
                                          const std::string & outFileName ) const
 {
-
    auto session = createDBSession();
    session->transaction().start( /*bool readonly=*/ true);
-   bool querySuccess { false };
-   for( auto & qdef : getL1QueryDefinitions() ) {
-      try {
-         qdef.setBoundValue<int>("smk", smk);
-         auto q = qdef.createQuery( session.get() );
-         auto & cursor = q->execute();
-         querySuccess = true;
-         if ( ! cursor.next() ) {
-            throw std::runtime_error( "TrigDBMenuLoader: SuperMasterKey not available" );
-         }
-         
-         const coral::AttributeList& row = cursor.currentRow();
-         const coral::Blob& dataBlob = row[qdef.dataName()].data<coral::Blob>();
-         writeRawFile( dataBlob, outFileName );
-         blobToPtree( dataBlob, l1menu );
-         break;
-      }
-      catch(coral::QueryException & ex) {
-         TRG_MSG_INFO("Trying next query after coral::QueryException caught ( " << ex.what() <<" )" );
-         continue;
-      }
-      catch(std::exception & ex) {
-         TRG_MSG_INFO("Trying next query after std::exception caught ( " << ex.what() <<" )" );
-         continue;
+   QueryDefinition qdef = getL1QueryDefinition(session.get());
+   try {
+      qdef.setBoundValue<int>("smk", smk);
+      auto q = qdef.createQuery( session.get() );
+      auto & cursor = q->execute();
+      if ( ! cursor.next() ) {
+         TRG_MSG_ERROR("Tried reading L1 menu, but SuperMasterKey " << smk << " is not available" );
+         return false;
       }
+      const coral::AttributeList& row = cursor.currentRow();
+      const coral::Blob& dataBlob = row[qdef.dataName()].data<coral::Blob>();
+      writeRawFile( dataBlob, outFileName );
+      blobToPtree( dataBlob, l1menu );
    }
-   if( ! querySuccess ) {
-      TRG_MSG_ERROR("Could not read the L1Menu data from the database, all query attempts failed");
+   catch(coral::QueryException & ex) {
+      TRG_MSG_ERROR("When reading L1 menu for SMK " << smk << " a coral::QueryException was caught ( " << ex.what() <<" )" );
       return false;
    }
-
    return true;
 }
 
-
-
 bool
 TrigConf::TrigDBMenuLoader::loadHLTMenu ( unsigned int smk,
                                           boost::property_tree::ptree & hltmenu,
@@ -155,41 +162,27 @@ TrigConf::TrigDBMenuLoader::loadHLTMenu ( unsigned int smk,
 {
    auto session = createDBSession();
    session->transaction().start( /*bool readonly=*/ true);
-   bool querySuccess { false };
-   for( auto & qdef : getHLTQueryDefinitions() ) {
-      try {
-         qdef.setBoundValue<int>("smk", smk);
-         auto q = qdef.createQuery( session.get() );
-         auto & cursor = q->execute();
-         querySuccess = true;
-         if ( ! cursor.next() ) {
-            throw std::runtime_error( "TrigDBMenuLoader: SuperMasterKey not available" );
-         }
-         const coral::AttributeList& row = cursor.currentRow();
-         const coral::Blob& dataBlob = row[qdef.dataName()].data<coral::Blob>();
-         writeRawFile( dataBlob, outFileName );
-         blobToPtree( dataBlob, hltmenu );
-         break;
-      }
-      catch(coral::QueryException & ex) {
-         TRG_MSG_INFO("Trying next query after coral::QueryException caught ( " << ex.what() <<" )" );
-         continue;
-      }
-      catch(std::exception & ex) {
-         TRG_MSG_INFO("Trying next query after std::exception caught ( " << ex.what() <<" )" );
-         continue;
+   QueryDefinition qdef = getHLTQueryDefinition(session.get());
+   try {
+      qdef.setBoundValue<int>("smk", smk);
+      auto q = qdef.createQuery( session.get() );
+      auto & cursor = q->execute();
+      if ( ! cursor.next() ) {
+         TRG_MSG_ERROR("Tried reading HLT menu, but SuperMasterKey " << smk << " is not available" );
+         return false;
       }
+      const coral::AttributeList& row = cursor.currentRow();
+      const coral::Blob& dataBlob = row[qdef.dataName()].data<coral::Blob>();
+      writeRawFile( dataBlob, outFileName );
+      blobToPtree( dataBlob, hltmenu );
    }
-   if( ! querySuccess ) {
-      TRG_MSG_ERROR("Could not read the HLTMenu data from the database, all query attempts failed");
+   catch(coral::QueryException & ex) {
+      TRG_MSG_ERROR("When reading HLT menu for SMK " << smk << " a coral::QueryException was caught ( " << ex.what() <<" )" );
       return false;
    }
-
    return true;
 }
 
-
-
 bool
 TrigConf::TrigDBMenuLoader::loadL1Menu( unsigned int smk, L1Menu & l1menu,
                                         const std::string & outFileName ) const
diff --git a/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx b/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx
index 1c6b5f943f68..754fc9065350 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/utils/TestTriggerMenuAccess.cxx
@@ -137,7 +137,6 @@ testL1Menu_Connectors(const TrigConf::L1Menu & l1menu) {
                  << "] is produced by topo algorithm " << topoAlg.name() << endl;
          }
       } else if( conn.type() == TrigConf::L1Connector::ConnectorType::ELECTRICAL ) {
-         cout << "JOERG 3" << endl;
          for( size_t fpga : { 0, 1 } ) {
             for( size_t clock : { 0, 1 } ) {
                for( auto & tl : conn.triggerLines(fpga, clock) ) {
diff --git a/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx b/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx
index 20e8be13a515..808bb316fe70 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx
@@ -267,26 +267,29 @@ int main(int argc, char** argv) {
       TrigConf::TrigDBMenuLoader dbloader(cfg.dbalias);
 
       TrigConf::L1Menu l1menu;
-      TrigConf::HLTMenu hltmenu;
-      
       dbloader.loadL1Menu( cfg.smk, l1menu, outputFileName("L1Menu", cfg) );
       if (l1menu) {
          cout << "Loaded L1 menu with " << l1menu.size() << " items" <<  endl;
-         l1menu.printMenu(cfg.detail);
+         if( cfg.detail ) {
+            l1menu.printMenu(true);
+         }
       } else {
          cout << "Did not load an L1 menu" << endl;
       }
 
+      TrigConf::HLTMenu hltmenu;
       dbloader.loadHLTMenu( cfg.smk, hltmenu, outputFileName("HLTMenu", cfg));
       if (hltmenu) {
          cout << "Loaded HLT menu with " << hltmenu.size() << " chains" << endl;
+         if( cfg.detail ) {
+            hltmenu.printMenu(true);
+         }
       } else {
          cout << "Did not load an HLT menu" << endl;
       }
 
       // db job options loader
       TrigConf::TrigDBJobOptionsLoader jodbloader(cfg.dbalias);
-
       TrigConf::DataStructure jo;
       jodbloader.loadJobOptions( cfg.smk, jo, outputFileName("HLTJobOptions", cfg) );
       if (jo) {
-- 
GitLab


From 2a61326ddac19f9d2dad18b176e31d80f58a4075 Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Thu, 10 Sep 2020 12:16:08 +0200
Subject: [PATCH 3/4] Added exceptions to signal loading result

---
 .../TrigConfData/src/DataStructure.cxx        |  3 +-
 .../TrigConfData/src/HLTPrescalesSet.cxx      |  3 +-
 .../TrigConfData/src/L1Menu.cxx               | 23 +++++-
 .../TrigConfData/src/L1ThrExtraInfo.cxx       | 20 +++--
 .../TrigConfIO/TrigConfIO/Exceptions.h        | 59 ++++++++++++++
 .../TrigConfIO/TrigDBHLTPrescalesSetLoader.h  |  2 +
 .../TrigConfIO/TrigDBJobOptionsLoader.h       |  1 -
 .../TrigConfIO/TrigDBL1BunchGroupSetLoader.h  |  4 +-
 .../TrigConfIO/TrigDBL1PrescalesSetLoader.h   |  2 +
 .../TrigConfIO/TrigConfIO/TrigDBLoader.h      |  6 ++
 .../TrigConfIO/TrigConfIO/TrigDBMenuLoader.h  |  5 --
 .../TrigConfIO/src/Exceptions.cxx             | 10 +++
 .../src/TrigDBHLTPrescalesSetLoader.cxx       | 71 ++++++++---------
 .../TrigConfIO/src/TrigDBJobOptionsLoader.cxx | 29 +------
 .../src/TrigDBL1BunchGroupSetLoader.cxx       | 70 ++++++++--------
 .../src/TrigDBL1PrescalesSetLoader.cxx        | 70 ++++++++--------
 .../TrigConfIO/src/TrigDBLoader.cxx           | 21 +++++
 .../TrigConfIO/src/TrigDBMenuLoader.cxx       | 78 ++++++------------
 .../TrigConfIO/utils/TriggerMenuRW.cxx        | 79 +++++++++++--------
 19 files changed, 310 insertions(+), 246 deletions(-)
 create mode 100644 Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/Exceptions.h
 create mode 100644 Trigger/TrigConfiguration/TrigConfIO/src/Exceptions.cxx

diff --git a/Trigger/TrigConfiguration/TrigConfData/src/DataStructure.cxx b/Trigger/TrigConfiguration/TrigConfData/src/DataStructure.cxx
index ec899fea0d8a..bdfbbd44fee0 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/DataStructure.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/DataStructure.cxx
@@ -60,7 +60,8 @@ void
 TrigConf::DataStructure::clear()
 {
    m_initialized = false;
-   update();
+   m_dataSPtr = nullptr;
+   m_dataPtr = nullptr;
 }
 
 
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/HLTPrescalesSet.cxx b/Trigger/TrigConfiguration/TrigConfData/src/HLTPrescalesSet.cxx
index 3886d1f821d3..a770afb8abc1 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/HLTPrescalesSet.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/HLTPrescalesSet.cxx
@@ -13,8 +13,7 @@ TrigConf::HLTPrescalesSet::HLTPrescalesSet(const boost::property_tree::ptree & d
    update();
 }
 
-TrigConf::HLTPrescalesSet::~HLTPrescalesSet()
-{}
+TrigConf::HLTPrescalesSet::~HLTPrescalesSet() = default;
 
 void
 TrigConf::HLTPrescalesSet::update()
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx
index 59b5347cb3f9..27660fb9a7e0 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1Menu.cxx
@@ -25,6 +25,7 @@ TrigConf::L1Menu::update()
    if(! isInitialized() || empty() ) {
       return;
    }
+
    try {
       m_name = getAttribute("name");
       // thresholds
@@ -38,7 +39,6 @@ TrigConf::L1Menu::update()
             auto extraInfo = m_thrExtraInfo.addExtraInfo(thrByType.first,thrByType.second);
 
             auto & v = m_thresholdsByType[thrType] = std::vector<std::shared_ptr<TrigConf::L1Threshold>>();
-
             if(thrType == "internal") {
                for( auto & thr : data().get_child( path + ".internal.names") ) {
                   const std::string thrName = thr.second.data();
@@ -55,27 +55,44 @@ TrigConf::L1Menu::update()
             }
          }
       }
+   }
+   catch(std::exception & ex) {
+      std::cerr << "ERROR: problem when building L1 menu structure (thresholds). " << ex.what() << std::endl;
+      throw;
+   }
 
+   try {
       // boards
       for( auto & board : data().get_child( "boards" ) ) {
          m_boards.emplace( std::piecewise_construct,
                            std::forward_as_tuple(board.first),
                            std::forward_as_tuple(board.first, board.second) );
       }
+   }
+   catch(std::exception & ex) {
+      std::cerr << "ERROR: problem when building L1 menu structure (boards). " << ex.what() << std::endl;
+      throw;
+   }
 
+   try {
       // connectors
       for( auto & conn : data().get_child( "connectors" ) ) {
          auto res = m_connectors.emplace( std::piecewise_construct,
                                           std::forward_as_tuple(conn.first),
                                           std::forward_as_tuple(conn.first, conn.second) );
-
          for( auto & tl : res.first->second.triggerLineNames() ) {
             m_threshold2ConnectorName.emplace( std::piecewise_construct,
                                                std::forward_as_tuple(tl),
                                                std::forward_as_tuple(conn.first));
          }
       }
+   }
+   catch(std::exception & ex) {
+      std::cerr << "ERROR: problem when building L1 menu structure (connectors). " << ex.what() << std::endl;
+      throw;
+   }
 
+   try {
       // algorithms
       for( const std::string & algoCategory : { "TOPO", "MULTTOPO", "MUTOPO", "R2TOPO" } ) {
          auto & v = m_algorithmsByCategory[algoCategory] = std::vector<TrigConf::L1TopoAlgorithm>();
@@ -108,7 +125,7 @@ TrigConf::L1Menu::update()
       }
    }
    catch(std::exception & ex) {
-      std::cerr << "ERROR: problem when building L1 menu structure. " << ex.what() << std::endl;
+      std::cerr << "ERROR: problem when building L1 menu structure (algorithms). " << ex.what() << std::endl;
       throw;
    }
 }
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/L1ThrExtraInfo.cxx b/Trigger/TrigConfiguration/TrigConfData/src/L1ThrExtraInfo.cxx
index 5dd54db85529..03e03f08807a 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/L1ThrExtraInfo.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/L1ThrExtraInfo.cxx
@@ -40,10 +40,16 @@ TrigConf::L1ThrExtraInfo::createExtraInfo(const std::string & thrTypeName, const
 
 std::weak_ptr<TrigConf::L1ThrExtraInfoBase>
 TrigConf::L1ThrExtraInfo::addExtraInfo(const std::string & thrTypeName, const boost::property_tree::ptree & data) {
-   if( auto extraInfo = L1ThrExtraInfo::createExtraInfo( thrTypeName, data) ) {
-      auto success = m_thrExtraInfo.emplace(thrTypeName, std::shared_ptr<TrigConf::L1ThrExtraInfoBase>(std::move(extraInfo)));
-      return std::weak_ptr<TrigConf::L1ThrExtraInfoBase>( success.first->second );
-   };
+   try {
+      if( auto extraInfo = L1ThrExtraInfo::createExtraInfo( thrTypeName, data) ) {
+         auto success = m_thrExtraInfo.emplace(thrTypeName, std::shared_ptr<TrigConf::L1ThrExtraInfoBase>(std::move(extraInfo)));
+         return std::weak_ptr<TrigConf::L1ThrExtraInfoBase>( success.first->second );
+      }
+   }
+   catch(std::exception & ex) {
+      std::cerr << "L1ThrExtraInfo::addExtraInfo: exception occured when building extra info for " << thrTypeName << std::endl;
+      throw;
+   }
    return std::weak_ptr<TrigConf::L1ThrExtraInfoBase>( m_emptyInfo );
 }
 
@@ -215,9 +221,9 @@ TrigConf::L1ThrExtraInfo_eEMTAU::load()
             auto wp = (y.first == "Loose") ? Isolation::WP::LOOSE : ( (y.first == "Medium") ? Isolation::WP::MEDIUM : Isolation::WP::TIGHT );
             auto & iso = m_isolation.emplace(wp, string("eEM_WP_" + y.first)).first->second;
             for(auto & c : y.second ) {
-               auto etamin = c.second.get_child("etamin").get_value<unsigned int>();
-               auto etamax = c.second.get_child("etamax").get_value<unsigned int>();
-               auto priority = c.second.get_optional<unsigned int>("priority").get_value_or(0);
+               int etamin = c.second.get_optional<int>("etamin").get_value_or(-49);
+               int etamax = c.second.get_optional<int>("etamax").get_value_or(49);
+               unsigned int priority = c.second.get_optional<unsigned int>("priority").get_value_or(0);
                iso.addRangeValue(Isolation(c.second), etamin, etamax, priority, /*symmetric=*/ false);
             }
          }
diff --git a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/Exceptions.h b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/Exceptions.h
new file mode 100644
index 000000000000..51152743c418
--- /dev/null
+++ b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/Exceptions.h
@@ -0,0 +1,59 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGCONFIO_TRIGCONFIOEXCEPTIONS_H
+#define TRIGCONFIO_TRIGCONFIOEXCEPTIONS_H
+
+#include <exception>
+#include <string>
+
+namespace TrigConf {
+
+   class IOException : public std::exception {
+   public:
+      IOException(std::string msg);
+      virtual const char* what() const noexcept;
+   private:
+      const std::string m_msg;
+   };
+
+   class QueryException : public IOException {
+   public:
+      QueryException(std::string msg) : IOException(std::move(msg)) {}
+   };
+
+   class NoQueryException : public IOException {
+   public:
+      NoQueryException(std::string msg) : IOException(std::move(msg)) {}
+   };
+
+   class NoSMKException : public IOException {
+   public:
+      NoSMKException(std::string msg) : IOException(std::move(msg)) {}
+   };
+
+   class NoL1PSKException : public IOException {
+   public:
+      NoL1PSKException(std::string msg) : IOException(std::move(msg)) {}
+   };
+
+   class NoHLTPSKException : public IOException {
+   public:
+      NoHLTPSKException(std::string msg) : IOException(std::move(msg)) {}
+   };
+
+   class NoBGSKException : public IOException {
+   public:
+      NoBGSKException(std::string msg) : IOException(std::move(msg)) {}
+   };
+
+   class ParsingException : public IOException {
+   public:
+      ParsingException(std::string msg) : IOException(std::move(msg)) {}
+   };
+
+
+}
+
+#endif
diff --git a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBHLTPrescalesSetLoader.h b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBHLTPrescalesSetLoader.h
index 5460a998daa2..bcbc99e31845 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBHLTPrescalesSetLoader.h
+++ b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBHLTPrescalesSetLoader.h
@@ -37,6 +37,8 @@ namespace TrigConf {
       bool loadHLTPrescales ( unsigned int hltpsk,
                               HLTPrescalesSet & hltpss,
                               const std::string & outFileName = "") const;
+   private:
+      std::map<size_t, QueryDefinition> m_queries;
 
    };
 
diff --git a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBJobOptionsLoader.h b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBJobOptionsLoader.h
index 84c5a3ecd516..0ffc638b9653 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBJobOptionsLoader.h
+++ b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBJobOptionsLoader.h
@@ -52,7 +52,6 @@ namespace TrigConf {
                             DataStructure & jobOptions,
                             const std::string & outFileName = "") const;
    private:
-      TrigConf::QueryDefinition getQueryDefinition(coral::ISessionProxy* session) const;
       std::map<size_t, QueryDefinition> m_queries;
    };
 
diff --git a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBL1BunchGroupSetLoader.h b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBL1BunchGroupSetLoader.h
index 54266e5d2ce4..de51b3049057 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBL1BunchGroupSetLoader.h
+++ b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBL1BunchGroupSetLoader.h
@@ -39,7 +39,9 @@ namespace TrigConf {
       bool loadBunchGroupSet ( unsigned int bgsk,
                                L1BunchGroupSet & bgs,
                                const std::string & outFileName = "") const;
-      
+
+   private:
+      std::map<size_t, QueryDefinition> m_queries;
 
    };
 
diff --git a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBL1PrescalesSetLoader.h b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBL1PrescalesSetLoader.h
index fe94ba8cacd2..b6c10a060869 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBL1PrescalesSetLoader.h
+++ b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBL1PrescalesSetLoader.h
@@ -40,6 +40,8 @@ namespace TrigConf {
                              L1PrescalesSet & l1pss,
                              const std::string & outFileName = "") const;
 
+   private:
+      std::map<size_t, QueryDefinition> m_queries;
    };
 
 }
diff --git a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBLoader.h b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBLoader.h
index a412bc84f03d..3c4ad97b54ce 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBLoader.h
+++ b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBLoader.h
@@ -13,8 +13,10 @@
 #define TRIGCONFIO_TRIGDBLOADER_H
 
 #include "TrigConfBase/TrigConfMessaging.h"
+#include "TrigConfIO/Exceptions.h"
 
 #include <memory>
+#include <map>
 
 namespace coral {
    class ISessionProxy;
@@ -23,6 +25,8 @@ namespace coral {
 
 namespace TrigConf {
 
+   class QueryDefinition;
+
    /**
     * @brief Loader of trigger configurations from Json files
     */
@@ -55,6 +59,8 @@ namespace TrigConf {
       /** @brief create (if needed) DB session and return the session proxy */
       std::unique_ptr<coral::ISessionProxy> createDBSession() const;
 
+      QueryDefinition getQueryDefinition(coral::ISessionProxy* session, const std::map<size_t, QueryDefinition> & queries) const;
+
    private:
 
       // private variables
diff --git a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBMenuLoader.h b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBMenuLoader.h
index debfff51e83f..91272895f40d 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBMenuLoader.h
+++ b/Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/TrigDBMenuLoader.h
@@ -78,13 +78,8 @@ namespace TrigConf {
                          HLTMenu & hltmenu,
                          const std::string & outFileName = "") const;
    private:
-
-      TrigConf::QueryDefinition getL1QueryDefinition(coral::ISessionProxy* session) const;
-      TrigConf::QueryDefinition getHLTQueryDefinition(coral::ISessionProxy* session) const;
-
       std::map<size_t, QueryDefinition> m_l1queries;
       std::map<size_t, QueryDefinition> m_hltqueries;
-      
    };
 
 }
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/Exceptions.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/Exceptions.cxx
new file mode 100644
index 000000000000..cbe24b5cb93c
--- /dev/null
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/Exceptions.cxx
@@ -0,0 +1,10 @@
+#include "TrigConfIO/Exceptions.h"
+
+TrigConf::IOException::IOException(std::string msg) : m_msg(std::move(msg))
+{}
+
+const char*
+TrigConf::IOException::what() const noexcept
+{
+   return m_msg.c_str();
+}
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBHLTPrescalesSetLoader.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBHLTPrescalesSetLoader.cxx
index f6cc338af02e..388646f0b913 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBHLTPrescalesSetLoader.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBHLTPrescalesSetLoader.cxx
@@ -5,66 +5,59 @@
 
 TrigConf::TrigDBHLTPrescalesSetLoader::TrigDBHLTPrescalesSetLoader(const std::string & connection) : 
    TrigDBLoader("TrigDBHLTPrescalesSetLoader", connection)
-{}
-
-TrigConf::TrigDBHLTPrescalesSetLoader::~TrigDBHLTPrescalesSetLoader()
-{}
-
-namespace {
-   std::vector<TrigConf::QueryDefinition>
-   getQueryDefinitions() {
-      std::vector<TrigConf::QueryDefinition> queries;
-      { // query for table dev1 and dev2
-         queries.emplace_back();
-         auto & q = queries.back();
-         // tables
-         q.addToTableList ( "HLT_PRESCALE_SET" );
-         // bind vars
-         q.extendBinding<int>("key");
-         // conditions
-         q.extendCondition("HPS_ID = :key");
-         // attributes
-         q.extendOutput<coral::Blob>( "HPS_DATA" );
-         // the field with the data
-         q.setDataName("HPS_DATA");
-      }
-      return queries;
+{
+   { // query for all schema versions
+      auto & q = m_queries[1];
+      // tables
+      q.addToTableList ( "HLT_PRESCALE_SET" );
+      // bind vars
+      q.extendBinding<int>("key");
+      // conditions
+      q.extendCondition("HPS_ID = :key");
+      // attributes
+      q.extendOutput<coral::Blob>( "HPS_DATA" );
+      // the field with the data
+      q.setDataName("HPS_DATA");
    }
 }
 
+TrigConf::TrigDBHLTPrescalesSetLoader::~TrigDBHLTPrescalesSetLoader() = default;
+
 bool
 TrigConf::TrigDBHLTPrescalesSetLoader::loadHLTPrescales ( unsigned int psk, TrigConf::HLTPrescalesSet & pss,
                                                           const std::string & outFileName ) const
 {
-   auto session = createDBSession();
-   session->transaction().start( /*bool readonly=*/ true);
-   bool querySuccess { false };
-   for( auto & qdef : getQueryDefinitions() ) {
+   boost::property_tree::ptree pt;
+   {
+      auto session = createDBSession();
+      session->transaction().start( /*bool readonly=*/ true);
+      QueryDefinition qdef = getQueryDefinition(session.get(), m_queries);
       try {
          qdef.setBoundValue<int>("key", psk);
          auto q = qdef.createQuery( session.get() );
          auto & cursor = q->execute();
-         querySuccess = true;
          if ( ! cursor.next() ) {
-            throw std::runtime_error( "TrigDBHLTPrescalesSetLoader: HLT presale key " + std::to_string(psk) + " not available" );
+            TRG_MSG_ERROR("Tried reading HLT prescales, but HLT prescale key " << psk << " is not available" );
+            throw TrigConf::NoHLTPSKException("TrigDBHLTPrescalesSetLoader: HLT PSK " + std::to_string(psk) + " not available");
          }
          const coral::AttributeList& row = cursor.currentRow();
          const coral::Blob& dataBlob = row[qdef.dataName()].data<coral::Blob>();
          writeRawFile( dataBlob, outFileName );
-         boost::property_tree::ptree pt;
          blobToPtree( dataBlob, pt );
-         pss.setData(std::move(pt));
-         pss.setPSK(psk);
-         break;
       }
       catch(coral::QueryException & ex) {
-         continue;
+         TRG_MSG_ERROR("When reading HLT prescales for HLT PSK " << psk << " a coral::QueryException was caught ( " << ex.what() <<" )" );
+         throw TrigConf::QueryException("TrigDBHLTPrescalesSetLoader: " + std::string(ex.what()));
       }
    }
-   if( ! querySuccess ) {
-      TRG_MSG_ERROR("Could not read the HLT prescale set data from the database, all query attempts failed");
-      return false;
+   try {
+      pss.setData(std::move(pt));
+      pss.setPSK(psk);
+   }
+   catch(std::exception & ex) {
+      pss.clear();
+      TRG_MSG_ERROR("When reading HLT prescales for HLT PSK " << psk << " a parsing error occured ( " << ex.what() <<" )" );
+      throw TrigConf::ParsingException("TrigDBHLTPrescalesSetLoader: parsing error " + std::string(ex.what()));
    }
-
    return true;
 }
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBJobOptionsLoader.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBJobOptionsLoader.cxx
index 8cabe16898c6..2dd360e2c419 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBJobOptionsLoader.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBJobOptionsLoader.cxx
@@ -44,28 +44,7 @@ TrigConf::TrigDBJobOptionsLoader::TrigDBJobOptionsLoader(const std::string & con
    }
 }
 
-TrigConf::TrigDBJobOptionsLoader::~TrigDBJobOptionsLoader()
-{}
-
-TrigConf::QueryDefinition
-TrigConf::TrigDBJobOptionsLoader::getQueryDefinition(coral::ISessionProxy* session) const
-{
-   size_t sv = schemaVersion( session );
-   // find the largest version key in the map of defined queries that is <= the schemaVersion 
-   size_t maxDefVersion = 0;
-   for(auto & entry : m_queries) {
-      size_t vkey = entry.first;
-      if(vkey>maxDefVersion and vkey<=sv) {
-         maxDefVersion = vkey;
-      }
-   }
-   // if nothing found, throw an error
-   if( maxDefVersion==0 ) {
-      TRG_MSG_ERROR("When reading HLT Joboptions: no query for schema version " << sv << " defined" );
-      throw std::runtime_error( "TrigDBJobOptionsLoader: no query available for schema version" );      
-   }
-   return m_queries.at(maxDefVersion);
-}
+TrigConf::TrigDBJobOptionsLoader::~TrigDBJobOptionsLoader() = default;
 
 bool
 TrigConf::TrigDBJobOptionsLoader::loadJobOptions ( unsigned int smk,
@@ -74,14 +53,14 @@ TrigConf::TrigDBJobOptionsLoader::loadJobOptions ( unsigned int smk,
 {
    auto session = createDBSession();
    session->transaction().start( /*bool readonly=*/ true);
-   QueryDefinition qdef = getQueryDefinition(session.get());
+   QueryDefinition qdef = getQueryDefinition(session.get(), m_queries);
    try {
       qdef.setBoundValue<int>("smk", smk);
       auto q = qdef.createQuery( session.get() );
       auto & cursor = q->execute();
       if ( ! cursor.next() ) {
          TRG_MSG_ERROR("Tried reading HLT job options, but SuperMasterKey " << smk << " is not available" );
-         return false;
+         throw TrigConf::NoSMKException("TrigDBJobOptionsLoader: SMK " + std::to_string(smk) + " not available");
       }
       const coral::AttributeList& row = cursor.currentRow();
       const coral::Blob& dataBlob = row[qdef.dataName()].data<coral::Blob>();
@@ -90,7 +69,7 @@ TrigConf::TrigDBJobOptionsLoader::loadJobOptions ( unsigned int smk,
    }
    catch(coral::QueryException & ex) {
       TRG_MSG_ERROR("When reading HLT job options for SMK " << smk << " a coral::QueryException was caught ( " << ex.what() <<" )" );
-      return false;
+      throw TrigConf::QueryException("TrigDBJobOptionsLoader: " + std::string(ex.what()));
    }
    return true;
 }
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBL1BunchGroupSetLoader.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBL1BunchGroupSetLoader.cxx
index 5837ee23a867..f8a14afa4f37 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBL1BunchGroupSetLoader.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBL1BunchGroupSetLoader.cxx
@@ -5,66 +5,60 @@
 
 TrigConf::TrigDBL1BunchGroupSetLoader::TrigDBL1BunchGroupSetLoader(const std::string & connection) : 
    TrigDBLoader("TrigDBL1BunchGroupSetLoader", connection)
-{}
-
-TrigConf::TrigDBL1BunchGroupSetLoader::~TrigDBL1BunchGroupSetLoader()
-{}
-
-namespace {
-   std::vector<TrigConf::QueryDefinition>
-   getQueryDefinitions() {
-      std::vector<TrigConf::QueryDefinition> queries;
-      { // query for table dev1 and dev2
-         queries.emplace_back();
-         auto & q = queries.back();
-         // tables
-         q.addToTableList ( "L1_BUNCH_GROUP_SET" );
-         // bind vars
-         q.extendBinding<int>("key");
-         // conditions
-         q.extendCondition("L1BGS_ID = :key");
-         // attributes
-         q.extendOutput<coral::Blob>( "L1BGS_DATA" );
-         // the field with the data
-         q.setDataName("L1BGS_DATA");
-      }
-      return queries;
+{
+   { // query for all schema versions
+      auto & q = m_queries[1];
+      // tables
+      q.addToTableList ( "L1_BUNCH_GROUP_SET" );
+      // bind vars
+      q.extendBinding<int>("key");
+      // conditions
+      q.extendCondition("L1BGS_ID = :key");
+      // attributes
+      q.extendOutput<coral::Blob>( "L1BGS_DATA" );
+      // the field with the data
+      q.setDataName("L1BGS_DATA");
    }
 }
 
+TrigConf::TrigDBL1BunchGroupSetLoader::~TrigDBL1BunchGroupSetLoader() = default;
+
 bool
 TrigConf::TrigDBL1BunchGroupSetLoader::loadBunchGroupSet ( unsigned int bgsk,
                                                            TrigConf::L1BunchGroupSet & bgs,
                                                            const std::string & outFileName ) const
 {
-   auto session = createDBSession();
-   session->transaction().start( /*bool readonly=*/ true);
-   bool querySuccess { false };
-   for( auto & qdef : getQueryDefinitions() ) {
+   boost::property_tree::ptree pt;
+   {
+      auto session = createDBSession();
+      session->transaction().start( /*bool readonly=*/ true);
+      QueryDefinition qdef = getQueryDefinition(session.get(), m_queries);
       try {
          qdef.setBoundValue<int>("key", bgsk);
          auto q = qdef.createQuery( session.get() );
          auto & cursor = q->execute();
-         querySuccess = true;
          if ( ! cursor.next() ) {
-            throw std::runtime_error( "TrigDBL1BunchGroupSetLoader: L1 bunchgroup key " + std::to_string(bgsk) + " not available" );
+            TRG_MSG_ERROR("Tried reading L1 bunchgroup set, but L1 bunchgroup key " << bgsk << " is not available" );
+            throw TrigConf::NoBGSKException("TrigDBL1BunchGroupSetLoader: L1 bunchgroup key " + std::to_string(bgsk) + " not available");
          }
          const coral::AttributeList& row = cursor.currentRow();
          const coral::Blob& dataBlob = row[qdef.dataName()].data<coral::Blob>();
          writeRawFile( dataBlob, outFileName );
-         boost::property_tree::ptree pt;
          blobToPtree( dataBlob, pt );
-         bgs.setData(std::move(pt));
-         bgs.setBGSK(bgsk);
-         break;
       }
       catch(coral::QueryException & ex) {
-         continue;
+         TRG_MSG_ERROR("When reading L1 bunchgroup set for L1 bunchgroup key " << bgsk << " a coral::QueryException was caught ( " << ex.what() <<" )" );
+         throw TrigConf::QueryException("TrigDBL1BunchGroupSetLoader: " + std::string(ex.what()));
       }
    }
-   if( ! querySuccess ) {
-      TRG_MSG_ERROR("Could not read the L1 bunchgroup set data from the database, all query attempts failed");
-      return false;
+   try {
+      bgs.setData(std::move(pt));
+      bgs.setBGSK(bgsk);
+   }
+   catch(std::exception & ex) {
+      bgs.clear();
+      TRG_MSG_ERROR("When reading L1 bunchgroup set for L1 BGSK " << bgsk << " a parsing error occured ( " << ex.what() <<" )" );
+      throw TrigConf::ParsingException("TrigDBL1BunchGroupSetLoader: parsing error " + std::string(ex.what()));
    }
 
    return true;
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBL1PrescalesSetLoader.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBL1PrescalesSetLoader.cxx
index b3c5d8616dac..f6cadaa254a2 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBL1PrescalesSetLoader.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBL1PrescalesSetLoader.cxx
@@ -5,65 +5,59 @@
 
 TrigConf::TrigDBL1PrescalesSetLoader::TrigDBL1PrescalesSetLoader(const std::string & connection) : 
    TrigDBLoader("TrigDBL1PrescalesSetLoader", connection)
-{}
-
-TrigConf::TrigDBL1PrescalesSetLoader::~TrigDBL1PrescalesSetLoader()
-{}
-
-namespace {
-   std::vector<TrigConf::QueryDefinition>
-   getQueryDefinitions() {
-      std::vector<TrigConf::QueryDefinition> queries;
-      { // query for table dev1 and dev2
-         queries.emplace_back();
-         auto & q = queries.back();
-         // tables
-         q.addToTableList ( "L1_PRESCALE_SET" );
-         // bind vars
-         q.extendBinding<int>("key");
-         // conditions
-         q.extendCondition("L1PS_ID = :key");
-         // attributes
-         q.extendOutput<coral::Blob>( "L1PS_DATA" );
-         // the field with the data
-         q.setDataName("L1PS_DATA");
-      }
-      return queries;
+{
+   { // query for all schema versions
+      auto & q = m_queries[1];
+      // tables
+      q.addToTableList ( "L1_PRESCALE_SET" );
+      // bind vars
+      q.extendBinding<int>("key");
+      // conditions
+      q.extendCondition("L1PS_ID = :key");
+      // attributes
+      q.extendOutput<coral::Blob>( "L1PS_DATA" );
+      // the field with the data
+      q.setDataName("L1PS_DATA");
    }
 }
 
+TrigConf::TrigDBL1PrescalesSetLoader::~TrigDBL1PrescalesSetLoader() = default;
+
 bool
 TrigConf::TrigDBL1PrescalesSetLoader::loadL1Prescales ( unsigned int psk, TrigConf::L1PrescalesSet & pss,
                                                         const std::string & outFileName ) const
 {
-   auto session = createDBSession();
-   session->transaction().start( /*bool readonly=*/ true);
-   bool querySuccess { false };
-   for( auto & qdef : getQueryDefinitions() ) {
+   boost::property_tree::ptree pt;
+   {
+      auto session = createDBSession();
+      session->transaction().start( /*bool readonly=*/ true);
+      QueryDefinition qdef = getQueryDefinition(session.get(), m_queries);
       try {
          qdef.setBoundValue<int>("key", psk);
          auto q = qdef.createQuery( session.get() );
          auto & cursor = q->execute();
-         querySuccess = true;
          if ( ! cursor.next() ) {
-            throw std::runtime_error( "TrigDBL1PrescalesSetLoader: L1 presale key " + std::to_string(psk) + " not available" );
+            TRG_MSG_ERROR("Tried reading L1 prescales, but L1 prescale key " << psk << " is not available" );
+            throw TrigConf::NoL1PSKException("TrigDBL1PrescalesSetLoader: L1 PSK " + std::to_string(psk) + " not available");
          }
          const coral::AttributeList& row = cursor.currentRow();
          const coral::Blob& dataBlob = row[qdef.dataName()].data<coral::Blob>();
          writeRawFile( dataBlob, outFileName );
-         boost::property_tree::ptree pt;
          blobToPtree( dataBlob, pt );
-         pss.setData(std::move(pt));
-         pss.setPSK(psk);
-         break;
       }
       catch(coral::QueryException & ex) {
-         continue;
+         TRG_MSG_ERROR("When reading L1 prescales for L1 PSK " << psk << " a coral::QueryException was caught ( " << ex.what() <<" )" );
+         throw TrigConf::QueryException("TrigDBL1PrescalesSetLoader: " + std::string(ex.what()));
       }
    }
-   if( ! querySuccess ) {
-      TRG_MSG_ERROR("Could not read the L1 prescale set data data from the database, all query attempts failed");
-      return false;
+   try {
+      pss.setData(std::move(pt));
+      pss.setPSK(psk);
+   }
+   catch(std::exception & ex) {
+      pss.clear();
+      TRG_MSG_ERROR("When reading L1 prescales for L1 PSK " << psk << " a parsing error occured ( " << ex.what() <<" )" );
+      throw TrigConf::ParsingException("TrigDBL1PrescalesSetLoader: parsing error " + std::string(ex.what()));
    }
 
    return true;
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBLoader.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBLoader.cxx
index 6b1cb5e74f17..f3c1f8607d77 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBLoader.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBLoader.cxx
@@ -122,3 +122,24 @@ TrigConf::TrigDBLoader::createDBSession() const {
 
    return proxy;
 }
+
+
+TrigConf::QueryDefinition
+TrigConf::TrigDBLoader::getQueryDefinition(coral::ISessionProxy* session, const std::map<size_t, TrigConf::QueryDefinition> & queries) const
+{
+   size_t sv = schemaVersion( session );
+   // find the largest version key in the map of defined queries that is <= the schemaVersion 
+   size_t maxDefVersion = 0;
+   for(auto & entry : queries) {
+      size_t vkey = entry.first;
+      if(vkey>maxDefVersion and vkey<=sv) {
+         maxDefVersion = vkey;
+      }
+   }
+   // if nothing found, throw an error
+   if( maxDefVersion==0 ) {
+      TRG_MSG_ERROR("No query for schema version " << sv << " defined" );
+      throw TrigConf::NoQueryException( "No query available for schema version" + std::to_string(sv) );      
+   }
+   return queries.at(maxDefVersion);
+}
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBMenuLoader.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBMenuLoader.cxx
index b5e093ab9933..108e29f6b388 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBMenuLoader.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBMenuLoader.cxx
@@ -85,47 +85,8 @@ TrigConf::TrigDBMenuLoader::TrigDBMenuLoader(const std::string & connection) :
    }
 }
 
-TrigConf::TrigDBMenuLoader::~TrigDBMenuLoader() = default;
-
-TrigConf::QueryDefinition
-TrigConf::TrigDBMenuLoader::getL1QueryDefinition(coral::ISessionProxy* session) const
-{
-   size_t sv = schemaVersion( session );
-   // find the largest version key in the map of defined queries that is <= the schemaVersion 
-   size_t maxDefVersion = 0;
-   for(auto & entry : m_l1queries) {
-      size_t vkey = entry.first;
-      if(vkey>maxDefVersion and vkey<=sv) {
-         maxDefVersion = vkey;
-      }
-   }
-   // if nothing found, throw an error
-   if( maxDefVersion==0 ) {
-      TRG_MSG_ERROR("When reading L1 menu: no L1Menu query for schema version " << sv << " defined" );
-      throw std::runtime_error( "TrigDBMenuLoader: no L1menu query available for schema version" );      
-   }
-   return m_l1queries.at(maxDefVersion);
-}
 
-TrigConf::QueryDefinition
-TrigConf::TrigDBMenuLoader::getHLTQueryDefinition(coral::ISessionProxy* session) const
-{
-   size_t sv = schemaVersion( session );
-   // find the largest version key in the map of defined queries that is <= the schemaVersion 
-   size_t maxDefVersion = 0;
-   for(auto & entry : m_hltqueries) {
-      size_t vkey = entry.first;
-      if(vkey>maxDefVersion and vkey<=sv) {
-         maxDefVersion = vkey;
-      }
-   }
-   // if nothing found, throw an error
-   if( maxDefVersion==0 ) {
-      TRG_MSG_ERROR("When reading HLT menu: no HLTMenu query for schema version " << sv << " defined" );
-      throw std::runtime_error( "TrigDBMenuLoader: no HLTmenu query available for schema version" );      
-   }
-   return m_hltqueries.at(maxDefVersion);
-}
+TrigConf::TrigDBMenuLoader::~TrigDBMenuLoader() = default;
 
 bool
 TrigConf::TrigDBMenuLoader::loadL1Menu ( unsigned int smk,
@@ -134,14 +95,14 @@ TrigConf::TrigDBMenuLoader::loadL1Menu ( unsigned int smk,
 {
    auto session = createDBSession();
    session->transaction().start( /*bool readonly=*/ true);
-   QueryDefinition qdef = getL1QueryDefinition(session.get());
+   QueryDefinition qdef = getQueryDefinition(session.get(), m_l1queries);
    try {
       qdef.setBoundValue<int>("smk", smk);
       auto q = qdef.createQuery( session.get() );
       auto & cursor = q->execute();
       if ( ! cursor.next() ) {
          TRG_MSG_ERROR("Tried reading L1 menu, but SuperMasterKey " << smk << " is not available" );
-         return false;
+         throw TrigConf::NoSMKException("TriggerDBMenuLoader (L1Menu): SMK " + std::to_string(smk) + " not available");
       }
       const coral::AttributeList& row = cursor.currentRow();
       const coral::Blob& dataBlob = row[qdef.dataName()].data<coral::Blob>();
@@ -150,11 +111,12 @@ TrigConf::TrigDBMenuLoader::loadL1Menu ( unsigned int smk,
    }
    catch(coral::QueryException & ex) {
       TRG_MSG_ERROR("When reading L1 menu for SMK " << smk << " a coral::QueryException was caught ( " << ex.what() <<" )" );
-      return false;
+      throw TrigConf::QueryException("TriggerDBMenuLoader (L1Menu): " + std::string(ex.what()));
    }
    return true;
 }
 
+
 bool
 TrigConf::TrigDBMenuLoader::loadHLTMenu ( unsigned int smk,
                                           boost::property_tree::ptree & hltmenu,
@@ -162,14 +124,14 @@ TrigConf::TrigDBMenuLoader::loadHLTMenu ( unsigned int smk,
 {
    auto session = createDBSession();
    session->transaction().start( /*bool readonly=*/ true);
-   QueryDefinition qdef = getHLTQueryDefinition(session.get());
+   QueryDefinition qdef = getQueryDefinition(session.get(), m_hltqueries);
    try {
       qdef.setBoundValue<int>("smk", smk);
       auto q = qdef.createQuery( session.get() );
       auto & cursor = q->execute();
       if ( ! cursor.next() ) {
          TRG_MSG_ERROR("Tried reading HLT menu, but SuperMasterKey " << smk << " is not available" );
-         return false;
+         throw TrigConf::NoSMKException("TriggerDBMenuLoader (HLTMenu): SMK " + std::to_string(smk) + " not available");
       }
       const coral::AttributeList& row = cursor.currentRow();
       const coral::Blob& dataBlob = row[qdef.dataName()].data<coral::Blob>();
@@ -178,37 +140,45 @@ TrigConf::TrigDBMenuLoader::loadHLTMenu ( unsigned int smk,
    }
    catch(coral::QueryException & ex) {
       TRG_MSG_ERROR("When reading HLT menu for SMK " << smk << " a coral::QueryException was caught ( " << ex.what() <<" )" );
-      return false;
+      throw TrigConf::QueryException("TriggerDBMenuLoader (HLTMenu): " + std::string(ex.what()));
    }
    return true;
 }
 
+
 bool
 TrigConf::TrigDBMenuLoader::loadL1Menu( unsigned int smk, L1Menu & l1menu,
                                         const std::string & outFileName ) const
 {
    boost::property_tree::ptree ptl1;
-   bool success = loadL1Menu( smk, ptl1, outFileName );
-   if(!success)
-      return false;
-   if( ! ptl1.empty() ) {
+   loadL1Menu( smk, ptl1, outFileName );
+   try {
       l1menu.setData(std::move(ptl1));
       l1menu.setSMK(smk);
    }
+   catch(std::exception & ex) {
+      l1menu.clear();
+      TRG_MSG_ERROR("When reading L1 menu for SMK " << smk << " a parsing error occured ( " << ex.what() <<" )" );
+      throw TrigConf::ParsingException("TrigDBMenuLoader: parsing error " + std::string(ex.what()));
+   }
    return true;
 }
 
+
 bool
 TrigConf::TrigDBMenuLoader::loadHLTMenu( unsigned int smk, HLTMenu & hltmenu,
                                          const std::string & outFileName ) const
 {
    boost::property_tree::ptree pthlt;
-   bool success = loadHLTMenu( smk, pthlt, outFileName );
-   if(!success)
-      return false;
-   if( ! pthlt.empty() ) {
+   loadHLTMenu( smk, pthlt, outFileName );
+   try {
       hltmenu.setData(std::move(pthlt));
       hltmenu.setSMK(smk);
    }
+   catch(std::exception & ex) {
+      hltmenu.clear();
+      TRG_MSG_ERROR("When reading HLT menu for SMK " << smk << " a parsing error occured ( " << ex.what() <<" )" );
+      throw TrigConf::ParsingException("TrigDBMenuLoader: parsing error " + std::string(ex.what()));
+   }
    return true;
 }
diff --git a/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx b/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx
index 808bb316fe70..e8eca7e0ef0c 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/utils/TriggerMenuRW.cxx
@@ -202,15 +202,10 @@ int main(int argc, char** argv) {
 
    if( cfg.inputFiles.size()>0 ) {
       // load config from files
-
-      // file loader
       TrigConf::JsonFileLoader fileLoader;
-
       for (const std::string & fn : cfg.inputFiles) {
-
          // check if the file is L1 or HLT
          std::string filetype = fileLoader.getFileType( fn );
-         
          if(filetype == "l1menu") {
             TrigConf::L1Menu l1menu;
             fileLoader.loadFile( fn, l1menu);
@@ -256,7 +251,6 @@ int main(int argc, char** argv) {
          } else {
             cerr << "File " << fn << " not recognized as being an L1 or HLT menu or prescale set or bunchgroup set" << endl;
          }
-
       }
    }
 
@@ -265,33 +259,48 @@ int main(int argc, char** argv) {
 
       // db menu loader
       TrigConf::TrigDBMenuLoader dbloader(cfg.dbalias);
-
+      
+      // L1 menu
       TrigConf::L1Menu l1menu;
-      dbloader.loadL1Menu( cfg.smk, l1menu, outputFileName("L1Menu", cfg) );
-      if (l1menu) {
+      try {
+         dbloader.loadL1Menu( cfg.smk, l1menu, outputFileName("L1Menu", cfg) );
+      }
+      catch(TrigConf::IOException & ex) {
+         cout << "Could not load L1 menu. An exception occurred: " << ex.what() << endl;
+      }
+      if(l1menu) {
          cout << "Loaded L1 menu with " << l1menu.size() << " items" <<  endl;
          if( cfg.detail ) {
             l1menu.printMenu(true);
          }
-      } else {
-         cout << "Did not load an L1 menu" << endl;
       }
+      cout << endl;
 
+      // HLT menu
       TrigConf::HLTMenu hltmenu;
-      dbloader.loadHLTMenu( cfg.smk, hltmenu, outputFileName("HLTMenu", cfg));
+      try {
+         dbloader.loadHLTMenu( cfg.smk, hltmenu, outputFileName("HLTMenu", cfg));
+      }
+      catch(TrigConf::IOException & ex) {
+         cout << "Could not load HLT menu. An exception occurred: " << ex.what() << endl;
+      }
       if (hltmenu) {
          cout << "Loaded HLT menu with " << hltmenu.size() << " chains" << endl;
          if( cfg.detail ) {
             hltmenu.printMenu(true);
          }
-      } else {
-         cout << "Did not load an HLT menu" << endl;
       }
+      cout << endl;
 
-      // db job options loader
+      // Job options
       TrigConf::TrigDBJobOptionsLoader jodbloader(cfg.dbalias);
       TrigConf::DataStructure jo;
-      jodbloader.loadJobOptions( cfg.smk, jo, outputFileName("HLTJobOptions", cfg) );
+      try {
+         jodbloader.loadJobOptions( cfg.smk, jo, outputFileName("HLTJobOptions", cfg) );
+      }
+      catch(TrigConf::IOException & ex) {
+         cout << "Could not load HLT job options. An exception occurred: " << ex.what() << endl;
+      }
       if (jo) {
          cout << "Loaded job options with " << jo.getObject("properties").getKeys().size() << " entries " << endl;
          if( cfg.detail ) {
@@ -302,8 +311,6 @@ int main(int argc, char** argv) {
                }
             }
          }
-      } else {
-         cout << "Did not load job options" << endl;
       }
    }
 
@@ -312,12 +319,14 @@ int main(int argc, char** argv) {
       // load L1 prescales set from DB
       TrigConf::TrigDBL1PrescalesSetLoader dbloader(cfg.dbalias);
       TrigConf::L1PrescalesSet l1pss;
-      
-      dbloader.loadL1Prescales( cfg.l1psk, l1pss, outputFileName("L1PrescalesSet", cfg) );
+      try {
+         dbloader.loadL1Prescales( cfg.l1psk, l1pss, outputFileName("L1PrescalesSet", cfg) );
+      }
+      catch(TrigConf::IOException & ex) {
+         cout << "Could not load L1 prescales. An exception occurred: " << ex.what() << endl;
+      }      
       if (l1pss) {
          cout << "Loaded L1 prescales set with " << l1pss.size() << " prescales" <<  endl;
-      } else {
-         cout << "Did not load an L1 prescales set" << endl;
       }
    }
 
@@ -325,13 +334,15 @@ int main(int argc, char** argv) {
    if( cfg.hltpsk != 0 ) {
       // load L1 prescales set from DB
       TrigConf::TrigDBHLTPrescalesSetLoader dbloader(cfg.dbalias);
-      TrigConf::HLTPrescalesSet hltpss;
-      
-      dbloader.loadHLTPrescales( cfg.hltpsk, hltpss, outputFileName("HLTPrescalesSet", cfg) );
+      TrigConf::HLTPrescalesSet hltpss;    
+      try {
+         dbloader.loadHLTPrescales( cfg.hltpsk, hltpss, outputFileName("HLTPrescalesSet", cfg) );
+      }
+      catch(TrigConf::IOException & ex) {
+         cout << "Could not load HLT prescales. An exception occurred: " << ex.what() << endl;
+      }      
       if (hltpss) {
          cout << "Loaded HLT prescales set with " << hltpss.size() << " prescales" <<  endl;
-      } else {
-         cout << "Did not load an HLT prescales set" << endl;
       }
    }
 
@@ -340,13 +351,17 @@ int main(int argc, char** argv) {
       // load L1 prescales set from DB
       TrigConf::TrigDBL1BunchGroupSetLoader dbloader(cfg.dbalias);
       TrigConf::L1BunchGroupSet bgs;
-
-      dbloader.loadBunchGroupSet( cfg.bgsk, bgs, outputFileName("BunchGroupSet", cfg) );
+      try {
+         dbloader.loadBunchGroupSet( cfg.bgsk, bgs, outputFileName("BunchGroupSet", cfg) );
+      }
+      catch(TrigConf::IOException & ex) {
+         cout << "Could not load bunchgroup set. An exception occurred: " << ex.what() << endl;
+      }      
       if (bgs) {
          cout << "Loaded L1 bunchgroup set with " << bgs.size() << " bunchgroups" <<  endl;
-         bgs.printSummary(cfg.detail);
-      } else {
-         cout << "Did not load an L1 bunchgroups set" << endl;
+         if( cfg.detail ) {
+            bgs.printSummary(true);
+         }
       }
    }
 
-- 
GitLab


From 2ff5b3c41d9f7b9b2a1f96206a1bde50f2f6b028 Mon Sep 17 00:00:00 2001
From: Joerg Stelzer <joerg.stelzer@cern.ch>
Date: Thu, 10 Sep 2020 21:04:05 +0200
Subject: [PATCH 4/4] Follow up on the software review

---
 .../TrigConfData/src/HLTMenu.cxx                 |  2 +-
 .../TrigConfIO/src/JsonFileLoader.cxx            |  1 -
 .../TrigConfIO/src/TrigDBJobOptionsLoader.cxx    | 16 ++++++++--------
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/Trigger/TrigConfiguration/TrigConfData/src/HLTMenu.cxx b/Trigger/TrigConfiguration/TrigConfData/src/HLTMenu.cxx
index 4a18ea31735c..63f71248972d 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/HLTMenu.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/HLTMenu.cxx
@@ -69,7 +69,7 @@ std::vector<TrigConf::DataStructure>
 TrigConf::HLTMenu::streams() const
 {
    std::vector<DataStructure> strlist;
-   const auto & streams = data().get_child_optional("streams");
+   auto streams = data().get_child_optional("streams");
    if(streams) {
       strlist.reserve(streams->size());
       for( auto & strData : *streams ) {
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileLoader.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileLoader.cxx
index 0682c7ffeb09..9b1935752f6a 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileLoader.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/JsonFileLoader.cxx
@@ -53,7 +53,6 @@ TrigConf::JsonFileLoader::findFile(const std::string & filename) const {
    std::string fnCopy(filename);
    char *token = std::strtok( &*fnCopy.begin(), ":");
    while ( token != nullptr ) {
-      std::cout << token << '\n';
       std::filesystem::path fullname(token); 
       fullname /= filename;
       if( std::filesystem::exists( fullname ) ) {
diff --git a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBJobOptionsLoader.cxx b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBJobOptionsLoader.cxx
index 2dd360e2c419..baab7381ff78 100644
--- a/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBJobOptionsLoader.cxx
+++ b/Trigger/TrigConfiguration/TrigConfIO/src/TrigDBJobOptionsLoader.cxx
@@ -82,15 +82,15 @@ TrigConf::TrigDBJobOptionsLoader::loadJobOptions ( unsigned int smk,
 {
 
    boost::property_tree::ptree ptJobOptions;
-
-   bool success = loadJobOptions( smk, ptJobOptions, outFileName );
-
-   if(!success)
-      return false;
-
-   if( ! ptJobOptions.empty() )
+   loadJobOptions( smk, ptJobOptions, outFileName );
+   try {
       jobOptions.setData(std::move(ptJobOptions));
-
+   }
+   catch(std::exception & ex) {
+      jobOptions.clear();
+      TRG_MSG_ERROR("When reading HLT job options for SMK " << smk << " a parsing error occured ( " << ex.what() <<" )" );
+      throw TrigConf::ParsingException("TrigDBJobOptionsLoader: parsing error " + std::string(ex.what()));
+   }
    return true;
 }
 
-- 
GitLab