Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:22:24

0001 #include <strings.h>  // strcasecmp
0002 #include <iostream>
0003 #include <fstream>
0004 #include <stdexcept>
0005 #include <unordered_map>
0006 #include <utility>
0007 
0008 #include "tmEventSetup/tmEventSetup.hh"
0009 #include "tmEventSetup/esTriggerMenu.hh"
0010 #include "tmEventSetup/esAlgorithm.hh"
0011 #include "tmEventSetup/esCondition.hh"
0012 #include "tmEventSetup/esObject.hh"
0013 #include "tmEventSetup/esCut.hh"
0014 #include "tmEventSetup/esScale.hh"
0015 #include "tmGrammar/Algorithm.hh"
0016 
0017 #include "CondFormats/L1TObjects/interface/L1TUtmTriggerMenu.h"
0018 
0019 #include "CondTools/L1TriggerExt/interface/L1ConfigOnlineProdBaseExt.h"
0020 #include "CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetosFract.h"
0021 #include "CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractRcd.h"
0022 #include "CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractO2ORcd.h"
0023 #include "L1Trigger/L1TGlobal/interface/PrescalesVetosFractHelper.h"
0024 #include "L1Trigger/L1TCommon/interface/TriggerSystem.h"
0025 #include "L1Trigger/L1TCommon/interface/XmlConfigParser.h"
0026 #include "OnlineDBqueryHelper.h"
0027 
0028 class L1TGlobalPrescalesVetosOnlineProd
0029     : public L1ConfigOnlineProdBaseExt<L1TGlobalPrescalesVetosFractO2ORcd, L1TGlobalPrescalesVetosFract> {
0030 private:
0031   bool transactionSafe;
0032 
0033 public:
0034   std::unique_ptr<const L1TGlobalPrescalesVetosFract> newObject(
0035       const std::string &objectKey, const L1TGlobalPrescalesVetosFractO2ORcd &record) override;
0036 
0037   L1TGlobalPrescalesVetosOnlineProd(const edm::ParameterSet &);
0038   ~L1TGlobalPrescalesVetosOnlineProd(void) override {}
0039 };
0040 
0041 L1TGlobalPrescalesVetosOnlineProd::L1TGlobalPrescalesVetosOnlineProd(const edm::ParameterSet &iConfig)
0042     : L1ConfigOnlineProdBaseExt<L1TGlobalPrescalesVetosFractO2ORcd, L1TGlobalPrescalesVetosFract>(iConfig) {
0043   wrappedSetWhatProduced(iConfig);
0044   transactionSafe = iConfig.getParameter<bool>("transactionSafe");
0045 }
0046 
0047 std::unique_ptr<const L1TGlobalPrescalesVetosFract> L1TGlobalPrescalesVetosOnlineProd::newObject(
0048     const std::string &objectKey, const L1TGlobalPrescalesVetosFractO2ORcd &record) {
0049   edm::LogInfo("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0050       << "Producing L1TGlobalPrescalesVetos with TSC:RS key = " << objectKey;
0051 
0052   if (objectKey.empty()) {
0053     if (transactionSafe)
0054       throw std::runtime_error("SummaryForFunctionManager: uGTrs | Faulty  | Empty objectKey");
0055     else {
0056       edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0057           << "returning empty L1TGlobalPrescalesVetosFract object";
0058       return std::make_unique<const L1TGlobalPrescalesVetosFract>();
0059     }
0060   }
0061 
0062   unsigned int m_numberPhysTriggers = 512;
0063 
0064   // dictionary that maps algorithm name to it's index
0065   std::unordered_map<std::string, int, std::hash<std::string>> algoName2bit;
0066 
0067   std::string uGTtscKey = objectKey.substr(0, objectKey.find(':'));
0068   std::string uGTrsKey = objectKey.substr(objectKey.find(':') + 1, std::string::npos);
0069 
0070   std::string stage2Schema = "CMS_TRG_L1_CONF";
0071 
0072   std::string l1_menu_key;
0073   std::vector<std::string> queryStrings;
0074   queryStrings.push_back("L1_MENU");
0075 
0076   // select L1_MENU from CMS_TRG_L1_CONF.UGT_KEYS where ID = objectKey ;
0077   l1t::OMDSReader::QueryResults queryResult = m_omdsReader.basicQuery(
0078       queryStrings, stage2Schema, "UGT_KEYS", "UGT_KEYS.ID", m_omdsReader.singleAttribute(uGTtscKey));
0079 
0080   if (queryResult.queryFailed() || queryResult.numberRows() != 1) {
0081     edm::LogError("L1-O2O") << "Cannot get UGT_KEYS.L1_MENU for ID = " << uGTtscKey << " ";
0082     if (transactionSafe)
0083       throw std::runtime_error("SummaryForFunctionManager: uGTrs | Faulty  | Broken key");
0084     else {
0085       edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0086           << "returning empty L1TGlobalPrescalesVetosFract object";
0087       return std::make_unique<const L1TGlobalPrescalesVetosFract>();
0088     }
0089   }
0090 
0091   if (!queryResult.fillVariable("L1_MENU", l1_menu_key))
0092     l1_menu_key = "";
0093 
0094   edm::LogInfo("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") << "Producing L1TUtmTriggerMenu with key =" << l1_menu_key;
0095 
0096   if (uGTtscKey.empty()) {
0097     edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") << "TSC key is empty, returning";
0098     if (transactionSafe)
0099       throw std::runtime_error("SummaryForFunctionManager: uGTrs | Faulty  | Empty objectKey");
0100     else {
0101       edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0102           << "returning empty L1TGlobalPrescalesVetosFract object";
0103       return std::make_unique<const L1TGlobalPrescalesVetosFract>();
0104     }
0105   }
0106 
0107   std::vector<std::string> queryColumns;
0108   queryColumns.push_back("CONF");
0109 
0110   queryResult = m_omdsReader.basicQuery(
0111       queryColumns, stage2Schema, "UGT_L1_MENU", "UGT_L1_MENU.ID", m_omdsReader.singleAttribute(l1_menu_key));
0112 
0113   if (queryResult.queryFailed() || queryResult.numberRows() != 1) {
0114     edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0115         << "Cannot get UGT_L1_MENU.CONF for ID = " << l1_menu_key;
0116     if (transactionSafe)
0117       throw std::runtime_error("SummaryForFunctionManager: uGTrs | Faulty  | Broken key");
0118     else {
0119       edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0120           << "returning empty L1TGlobalPrescalesVetosFract object";
0121       return std::make_unique<const L1TGlobalPrescalesVetosFract>();
0122     }
0123   }
0124 
0125   std::string l1Menu;
0126   queryResult.fillVariable("CONF", l1Menu);
0127   ///
0128   std::istringstream iss(l1Menu);
0129 
0130   std::shared_ptr<L1TUtmTriggerMenu> pMenu(
0131       const_cast<L1TUtmTriggerMenu *>(reinterpret_cast<const L1TUtmTriggerMenu *>(tmeventsetup::getTriggerMenu(iss))));
0132 
0133   for (const auto &algo : pMenu->getAlgorithmMap())
0134     algoName2bit[algo.first] = algo.second.getIndex();
0135 
0136   ///std::vector< std::string > queryColumns;
0137   queryColumns.clear();
0138   queryColumns.push_back("ALGOBX_MASK");
0139   queryColumns.push_back("ALGO_FINOR_MASK");
0140   queryColumns.push_back("ALGO_FINOR_VETO");
0141   queryColumns.push_back("ALGO_PRESCALE");
0142 
0143   std::string prescale_key, bxmask_key, mask_key, vetomask_key;
0144   std::string xmlPayload_prescale, xmlPayload_mask_algobx, xmlPayload_mask_finor, xmlPayload_mask_veto;
0145   try {
0146     std::map<std::string, std::string> subKeys =
0147         l1t::OnlineDBqueryHelper::fetch(queryColumns, "UGT_RS_KEYS", uGTrsKey, m_omdsReader);
0148     prescale_key = subKeys["ALGO_PRESCALE"];
0149     bxmask_key = subKeys["ALGOBX_MASK"];
0150     mask_key = subKeys["ALGO_FINOR_MASK"];
0151     vetomask_key = subKeys["ALGO_FINOR_VETO"];
0152     xmlPayload_prescale = l1t::OnlineDBqueryHelper::fetch({"CONF"}, "UGT_RS_CLOBS", prescale_key, m_omdsReader)["CONF"];
0153     xmlPayload_mask_algobx =
0154         l1t::OnlineDBqueryHelper::fetch({"CONF"}, "UGT_RS_CLOBS", bxmask_key, m_omdsReader)["CONF"];
0155     xmlPayload_mask_finor = l1t::OnlineDBqueryHelper::fetch({"CONF"}, "UGT_RS_CLOBS", mask_key, m_omdsReader)["CONF"];
0156     xmlPayload_mask_veto =
0157         l1t::OnlineDBqueryHelper::fetch({"CONF"}, "UGT_RS_CLOBS", vetomask_key, m_omdsReader)["CONF"];
0158   } catch (std::runtime_error &e) {
0159     edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") << e.what();
0160     if (transactionSafe)
0161       throw std::runtime_error(std::string("SummaryForFunctionManager: uGTrs | Faulty  | ") + e.what());
0162     else {
0163       edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0164           << "returning empty L1TGlobalPrescalesVetosFract object";
0165       return std::make_unique<const L1TGlobalPrescalesVetosFract>();
0166     }
0167   }
0168 
0169   // for debugging purposes dump the payloads to /tmp
0170   std::ofstream output1(std::string("/tmp/").append(prescale_key.substr(0, prescale_key.find('/'))).append(".xml"));
0171   output1 << xmlPayload_prescale;
0172   output1.close();
0173   std::ofstream output2(std::string("/tmp/").append(mask_key.substr(0, mask_key.find('/'))).append(".xml"));
0174   output2 << xmlPayload_mask_finor;
0175   output2.close();
0176   std::ofstream output3(std::string("/tmp/").append(bxmask_key.substr(0, bxmask_key.find('/'))).append(".xml"));
0177   output3 << xmlPayload_mask_algobx;
0178   output3.close();
0179   std::ofstream output4(std::string("/tmp/").append(vetomask_key.substr(0, vetomask_key.find('/'))).append(".xml"));
0180   output4 << xmlPayload_mask_veto;
0181   output4.close();
0182 
0183   //////////////////
0184 
0185   std::vector<std::vector<double>> prescales;
0186   std::vector<unsigned int> triggerMasks;
0187   std::vector<int> triggerVetoMasks;
0188   std::map<int, std::vector<int>> triggerAlgoBxMaskAlgoTrig;
0189 
0190   // Prescales
0191   try {
0192     l1t::XmlConfigParser xmlReader_prescale;
0193     l1t::TriggerSystem ts_prescale;
0194     ts_prescale.addProcessor("uGtProcessor", "uGtProcessor", "-1", "-1");
0195 
0196     // run the parser
0197     xmlReader_prescale.readDOMFromString(xmlPayload_prescale);  // initialize it
0198     xmlReader_prescale.readRootElement(ts_prescale, "uGT");     // extract all of the relevant context
0199     ts_prescale.setConfigured();
0200 
0201     const std::map<std::string, l1t::Parameter> &settings_prescale = ts_prescale.getParameters("uGtProcessor");
0202     std::map<std::string, unsigned int> prescaleColumns = settings_prescale.at("prescales").getColumnIndices();
0203 
0204     unsigned int numColumns_prescale = prescaleColumns.size();
0205     int nPrescaleSets = numColumns_prescale - 1;
0206     std::vector<std::string> algoNames =
0207         settings_prescale.at("prescales").getTableColumn<std::string>("algo/prescale-index");
0208 
0209     if (nPrescaleSets > 0) {
0210       // Fill default prescale set
0211       for (int iSet = 0; iSet < nPrescaleSets; iSet++) {
0212         prescales.push_back(std::vector<double>());
0213         for (unsigned int iBit = 0; iBit < m_numberPhysTriggers; ++iBit) {
0214           double inputDefaultPrescale = 0;  // only prescales that are set in the block below are used
0215           prescales[iSet].push_back(inputDefaultPrescale);
0216         }
0217       }
0218 
0219       for (auto &col : prescaleColumns) {
0220         if (col.second < 1)
0221           continue;  // we don't care for the algorithms' indicies in 0th column
0222         int iSet = col.second - 1;
0223         std::vector<double> prescalesForSet =
0224             settings_prescale.at("prescales").getTableColumn<double>(col.first.c_str());
0225         for (unsigned int row = 0; row < prescalesForSet.size(); row++) {
0226           double prescale = prescalesForSet[row];
0227           std::string algoName = algoNames[row];
0228           unsigned int algoBit = algoName2bit[algoName];
0229           prescales[iSet][algoBit] = prescale;
0230         }
0231       }
0232     }
0233   } catch (std::runtime_error &e) {
0234     if (transactionSafe)
0235       throw std::runtime_error(std::string("SummaryForFunctionManager: uGTrs | Faulty  | ") + e.what());
0236     else {
0237       edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0238           << "returning empty L1TGlobalPrescalesVetosFract object";
0239       return std::make_unique<const L1TGlobalPrescalesVetosFract>();
0240     }
0241   }
0242 
0243   ///////////////////////////////////////////////////////////////////////////////////////////////////////////
0244 
0245   // finor mask
0246   try {
0247     l1t::XmlConfigParser xmlReader_mask_finor;
0248     l1t::TriggerSystem ts_mask_finor;
0249     ts_mask_finor.addProcessor("uGtProcessor", "uGtProcessor", "-1", "-1");
0250 
0251     // run the parser
0252     xmlReader_mask_finor.readDOMFromString(xmlPayload_mask_finor);  // initialize it
0253     xmlReader_mask_finor.readRootElement(ts_mask_finor, "uGT");     // extract all of the relevant context
0254     ts_mask_finor.setConfigured();
0255 
0256     const std::map<std::string, l1t::Parameter> &settings_mask_finor = ts_mask_finor.getParameters("uGtProcessor");
0257 
0258     std::vector<std::string> algo_mask_finor = settings_mask_finor.at("finorMask").getTableColumn<std::string>("algo");
0259     std::vector<unsigned int> mask_mask_finor =
0260         settings_mask_finor.at("finorMask").getTableColumn<unsigned int>("mask");
0261 
0262     // mask (default=1 - unmask)
0263     unsigned int default_finor_mask = 1;
0264     auto default_finor_row = std::find_if(algo_mask_finor.cbegin(), algo_mask_finor.cend(), [](const std::string &s) {
0265       // simpler than overweight std::tolower(s[], std::locale()) POSIX solution (thx to BA):
0266       return strcasecmp("all", s.c_str()) == 0;
0267     });
0268     if (default_finor_row == algo_mask_finor.cend()) {
0269       edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0270           << "\nWarning: No default found in FinOR mask xml, use 1 (unmasked) as default" << std::endl;
0271     } else {
0272       default_finor_mask = mask_mask_finor[std::distance(algo_mask_finor.cbegin(), default_finor_row)];
0273     }
0274 
0275     for (unsigned int iAlg = 0; iAlg < m_numberPhysTriggers; iAlg++)
0276       triggerMasks.push_back(default_finor_mask);
0277 
0278     for (unsigned int row = 0; row < algo_mask_finor.size(); row++) {
0279       std::string algoName = algo_mask_finor[row];
0280       if (strcasecmp("all", algoName.c_str()) == 0)
0281         continue;
0282       unsigned int algoBit = algoName2bit[algoName];
0283       unsigned int mask = mask_mask_finor[row];
0284       if (algoBit < m_numberPhysTriggers)
0285         triggerMasks[algoBit] = mask;
0286     }
0287   } catch (std::runtime_error &e) {
0288     if (transactionSafe)
0289       throw std::runtime_error(std::string("SummaryForFunctionManager: uGTrs | Faulty  | ") + e.what());
0290     else {
0291       edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0292           << "returning empty L1TGlobalPrescalesVetosFract object";
0293       return std::make_unique<const L1TGlobalPrescalesVetosFract>();
0294     }
0295   }
0296 
0297   ///////////////////////////////////////////////////////////////////////////////////////////////////////////
0298 
0299   // veto mask
0300   try {
0301     l1t::XmlConfigParser xmlReader_mask_veto;
0302     l1t::TriggerSystem ts_mask_veto;
0303     ts_mask_veto.addProcessor("uGtProcessor", "uGtProcessor", "-1", "-1");
0304 
0305     // run the parser
0306     xmlReader_mask_veto.readDOMFromString(xmlPayload_mask_veto);  // initialize it
0307     xmlReader_mask_veto.readRootElement(ts_mask_veto, "uGT");     // extract all of the relevant context
0308     ts_mask_veto.setConfigured();
0309 
0310     const std::map<std::string, l1t::Parameter> &settings_mask_veto = ts_mask_veto.getParameters("uGtProcessor");
0311     std::vector<std::string> algo_mask_veto = settings_mask_veto.at("vetoMask").getTableColumn<std::string>("algo");
0312     std::vector<unsigned int> veto_mask_veto = settings_mask_veto.at("vetoMask").getTableColumn<unsigned int>("veto");
0313 
0314     // veto mask (default=0 - no veto)
0315     unsigned int default_veto_mask = 1;
0316     auto default_veto_row = std::find_if(algo_mask_veto.cbegin(), algo_mask_veto.cend(), [](const std::string &s) {
0317       // simpler than overweight std::tolower(s[], std::locale()) POSIX solution (thx to BA):
0318       return strcasecmp("all", s.c_str()) == 0;
0319     });
0320     if (default_veto_row == algo_mask_veto.cend()) {
0321       edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0322           << "\nWarning: No default found in Veto mask xml, use 0 (unvetoed) as default" << std::endl;
0323     } else {
0324       default_veto_mask = veto_mask_veto[std::distance(algo_mask_veto.cbegin(), default_veto_row)];
0325     }
0326 
0327     for (unsigned int iAlg = 0; iAlg < m_numberPhysTriggers; iAlg++)
0328       triggerVetoMasks.push_back(default_veto_mask);
0329 
0330     for (unsigned int row = 0; row < algo_mask_veto.size(); row++) {
0331       std::string algoName = algo_mask_veto[row];
0332       if (strcasecmp("all", algoName.c_str()) == 0)
0333         continue;
0334       unsigned int algoBit = algoName2bit[algoName];
0335       unsigned int veto = veto_mask_veto[row];
0336       if (algoBit < m_numberPhysTriggers)
0337         triggerVetoMasks[algoBit] = int(veto);
0338     }
0339   } catch (std::runtime_error &e) {
0340     if (transactionSafe)
0341       throw std::runtime_error(std::string("SummaryForFunctionManager: uGTrs | Faulty  | ") + e.what());
0342     else {
0343       edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0344           << "returning empty L1TGlobalPrescalesVetosFract object";
0345       return std::make_unique<const L1TGlobalPrescalesVetosFract>();
0346     }
0347   }
0348 
0349   ///////////////////////////////////////////////////////////////////////////////////////////////////////////
0350 
0351   // Algo bx mask
0352   unsigned int m_bx_mask_default = 1;
0353 
0354   std::vector<std::string> bx_algo_name;
0355   std::vector<std::string> bx_range;
0356   std::vector<unsigned int> bx_mask;
0357 
0358   try {
0359     l1t::XmlConfigParser xmlReader_mask_algobx;
0360     l1t::TriggerSystem ts_mask_algobx;
0361     ts_mask_algobx.addProcessor("uGtProcessor", "uGtProcessor", "-1", "-1");
0362 
0363     // run the parser
0364     xmlReader_mask_algobx.readDOMFromString(xmlPayload_mask_algobx);  // initialize it
0365     xmlReader_mask_algobx.readRootElement(ts_mask_algobx, "uGT");     // extract all of the relevant context
0366     ts_mask_algobx.setConfigured();
0367 
0368     const std::map<std::string, l1t::Parameter> &settings_mask_algobx = ts_mask_algobx.getParameters("uGtProcessor");
0369     bx_algo_name = settings_mask_algobx.at("algorithmBxMask").getTableColumn<std::string>("algo");
0370     bx_range = settings_mask_algobx.at("algorithmBxMask").getTableColumn<std::string>("range");
0371     bx_mask = settings_mask_algobx.at("algorithmBxMask").getTableColumn<unsigned int>("mask");
0372   } catch (std::runtime_error &e) {
0373     if (transactionSafe)
0374       throw std::runtime_error(std::string("SummaryForFunctionManager: uGTrs | Faulty  | ") + e.what());
0375     else {
0376       edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0377           << "returning empty L1TGlobalPrescalesVetosFract object";
0378       return std::make_unique<const L1TGlobalPrescalesVetosFract>();
0379     }
0380   }
0381 
0382   int default_bxmask_row = -1;
0383   typedef std::pair<unsigned long, unsigned long> Range_t;
0384   // auto comp = [] (Range_t a, Range_t b){ return a.first < b.first; };
0385   struct RangeComp_t {
0386     bool operator()(const Range_t &a, const Range_t &b) const { return a.first < b.first; }
0387   };
0388   std::map<std::string, std::set<Range_t, RangeComp_t>> non_default_bx_ranges;
0389 
0390   for (unsigned int row = 0; row < bx_algo_name.size(); row++) {
0391     const std::string &s1 = bx_algo_name[row];
0392     const std::string &s2 = bx_range[row];
0393     // find "all" broadcast keywords
0394     bool broadcastAlgo = false;
0395     bool broadcastRange = false;
0396     if (strcasecmp("all", s1.c_str()) == 0)
0397       broadcastAlgo = true;
0398     if (strcasecmp("all", s2.c_str()) == 0)
0399       broadcastRange = true;
0400     // ALL-ALL-default:
0401     if (broadcastAlgo && broadcastRange) {
0402       if (row != 0) {
0403         edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0404             << "\nWarning: ALL-ALL row is not the first one, ignore it assuming 1 (unmasked) as the default"
0405             << std::endl;
0406         continue;
0407       }
0408       if (default_bxmask_row >= 0) {
0409         edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0410             << "\nWarning: multiple ALL-ALL rows found, using the first" << std::endl;
0411         continue;
0412       }
0413       default_bxmask_row = row;
0414       m_bx_mask_default = bx_mask[row];
0415       continue;
0416     }
0417     // interpret the range
0418     unsigned long first = 0, last = 0;
0419     if (broadcastRange) {
0420       first = 0;
0421       last = 3563;
0422     } else {
0423       char *dash = nullptr;
0424       first = strtoul(s2.data(), &dash, 0);
0425       while (*dash != '\0' && *dash != '-')
0426         ++dash;
0427       last = (*dash != '\0' ? strtoul(++dash, &dash, 0) : first);
0428       if (first == 3564)
0429         first = 0;
0430       if (last == 3564)
0431         last = 0;
0432       // what could possibly go wrong?
0433       if (*dash != '\0') {
0434         edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0435             << "\nWarning: parsing " << s2 << " as [" << first << "," << last << "] range" << std::endl;
0436       }
0437       if (first > 3563) {
0438         edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0439             << "\nWarning: start of interval is out of range: " << s2 << ", skipping the row" << std::endl;
0440         continue;
0441       }
0442       if (last > 3563) {
0443         last = 3563;
0444         edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0445             << "\nWarning: end of interval is out of range: " << s2 << ", force [" << first << "," << last << "] range"
0446             << std::endl;
0447       }
0448       if (first > last) {
0449         edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0450             << "\nWarning: inverse/spillover range " << s2 << ", accounting for circular orbit as [0," << last
0451             << "] & [" << first << ",3563]" << std::endl;
0452       }
0453     }
0454     // {algo,ALL}-{range,ALL}-{0,1}:
0455     std::vector<std::string> algos;
0456     std::vector<std::pair<unsigned long, unsigned long>> orderedRanges;
0457     if (first <= last) {
0458       if (!broadcastAlgo) {
0459         algos.push_back(bx_algo_name[row]);
0460         orderedRanges.push_back(std::make_pair(first, last));
0461       } else {
0462         for (const auto &i : non_default_bx_ranges) {
0463           algos.push_back(i.first);
0464           orderedRanges.push_back(std::make_pair(first, last));
0465         }
0466       }
0467     } else {
0468       if (!broadcastAlgo) {
0469         algos.push_back(bx_algo_name[row]);
0470         algos.push_back(bx_algo_name[row]);
0471         orderedRanges.push_back(std::make_pair(0, last));
0472         orderedRanges.push_back(std::make_pair(first, 3563));
0473       } else {
0474         for (const auto &i : non_default_bx_ranges) {
0475           algos.push_back(i.first);
0476           algos.push_back(i.first);
0477           orderedRanges.push_back(std::make_pair(0, last));
0478           orderedRanges.push_back(std::make_pair(first, 3563));
0479         }
0480       }
0481     }
0482 
0483     for (unsigned int item = 0; item < algos.size(); item++) {
0484       const std::string &algoName = algos[item];
0485       unsigned int first = orderedRanges[item].first;
0486       unsigned int last = orderedRanges[item].second;
0487 
0488       std::set<Range_t, RangeComp_t> &ranges = non_default_bx_ranges[algoName];
0489       //           .insert
0490       //           (
0491       //               std::pair< std::string, std::set<Range_t,RangeComp_t> >
0492       //               (
0493       //                   algoName,  std::set<Range_t,RangeComp_t>()
0494       //               )
0495       //           ).first->second; // I don't care if insert was successfull or if I've got a hold on existing range
0496 
0497       // current range may or may not overlap with the already present ranges
0498       // if end of the predecessor starts before begin of the current range and begin
0499       //  of the successor starts after end of the current range there is no overlap
0500       //  and I save this range only if it has mask different from the default
0501       //  otherwise modify predecessor/successor ranges accordingly
0502       std::set<Range_t>::iterator curr = ranges.end();  // inserted range
0503       std::set<Range_t>::iterator succ =
0504           ranges.lower_bound(std::make_pair(first, last));  // successor starts at current or later
0505       std::set<Range_t>::iterator pred = succ;
0506       if (pred != ranges.begin())
0507         pred--;
0508       else
0509         pred = ranges.end();
0510 
0511       if ((pred == ranges.end() || pred->second < first) && (succ == ranges.end() || succ->first > last)) {
0512         // no overlap
0513         if (m_bx_mask_default != bx_mask[row])
0514           curr = ranges.insert(std::make_pair(first, last)).first;
0515         // do nothing if this is a default-mask interval
0516       } else {
0517         // pred/succ iterators are read-only, create intermediate adjusted copies
0518         Range_t newPred, newSucc;
0519         bool modifiedPred = false, gapInPred = false, modifiedSucc = false, dropSucc = false;
0520         // overlap found with predecessor range
0521         if (pred != ranges.end() && pred->second >= first && pred->second <= last) {
0522           if (m_bx_mask_default != bx_mask[row]) {
0523             if (last == pred->second) {
0524               // both ranges end in the same place - nothing to do
0525               modifiedPred = false;
0526             } else {
0527               // extend predecessor range
0528               newPred.first = pred->first;
0529               newPred.second = last;
0530               modifiedPred = true;
0531             }
0532           } else {
0533             // shrink predecessor range
0534             newPred.first = pred->first;
0535             newPred.second = first - 1;  // non-negative for the predecessor by design
0536             // by design pred->first < first, so the interval above is always valid
0537             modifiedPred = true;
0538           }
0539         }
0540         // current range is fully contained in predecessor
0541         if (pred != ranges.end() && pred->second > first && pred->second > last) {
0542           if (m_bx_mask_default != bx_mask[row]) {
0543             // no change to the predecessor range
0544             modifiedPred = false;
0545           } else {
0546             // make a "gap" in predecessor range
0547             newPred.first = first;
0548             newPred.second = last;
0549             gapInPred = true;
0550             modifiedPred = true;
0551           }
0552         }
0553         // overlap found with successor range
0554         if (succ != ranges.end() && succ->first <= last) {
0555           if (m_bx_mask_default != bx_mask[row]) {
0556             // extend successor range
0557             newSucc.first = first;
0558             newSucc.second = succ->second;
0559           } else {
0560             // shrink successor range
0561             newSucc.first = last + 1;
0562             newSucc.second = succ->second;
0563             if (newSucc.first > 3563 || newSucc.first > newSucc.second)
0564               dropSucc = true;
0565           }
0566           modifiedSucc = true;
0567         }
0568         // overlap found with both, predecessor and successor, such that I need to merge them
0569         if (modifiedPred && modifiedSucc && newPred.second >= newSucc.first) {
0570           // make newPred and newSucc identical just in case
0571           newPred.second = newSucc.second;
0572           newSucc.first = newPred.first;
0573           ranges.erase(pred, ++succ);
0574           curr = ranges.insert(newPred).first;
0575         } else {
0576           // merging is not the case, but I still need to propagate the new ranges back to the source
0577           if (modifiedPred) {
0578             if (!gapInPred) {
0579               ranges.erase(pred);
0580               curr = ranges.insert(newPred).first;
0581             } else {
0582               // make a gap by splitting predecessor into two ranges
0583               Range_t r1(pred->first, newPred.first - 1);  // non-negative for the predecessor by design
0584               Range_t r2(newPred.second + 1, pred->second);
0585               ranges.erase(pred);
0586               ranges.insert(r1);
0587               ranges.insert(r2);
0588               curr = ranges.end();  // gap cannot cover any additional ranges
0589             }
0590           }
0591           if (modifiedSucc) {
0592             ranges.erase(succ);
0593             if (!dropSucc)
0594               curr = ranges.insert(newSucc).first;
0595           }
0596         }
0597       }
0598       // if current range spans over few more ranges after the successor
0599       //  remove those from the consideration up until the last covered range
0600       //  that may or may not extend beyond the current range end
0601       if (curr != ranges.end()) {  // insertion took place
0602         std::set<Range_t, RangeComp_t>::iterator last_covered = ranges.upper_bound(std::make_pair(curr->second, 0));
0603         if (last_covered != ranges.begin())
0604           last_covered--;
0605         else
0606           last_covered = ranges.end();
0607 
0608         if (last_covered != ranges.end() && last_covered->first != curr->first) {
0609           // ranges is not empty and last_covered is not current itself (i.e. it is different)
0610           if (curr->second < last_covered->second) {
0611             // the range needs to be extended
0612             Range_t newRange(curr->first, last_covered->second);
0613             ranges.erase(curr);
0614             curr = ranges.insert(newRange).first;
0615           }
0616           ranges.erase(++curr, last_covered);
0617         }
0618       }
0619     }
0620   }
0621 
0622   if (default_bxmask_row < 0) {
0623     edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0624         << "\nWarning: No default found in BX mask xml, used 1 (unmasked) as default" << std::endl;
0625   }
0626 
0627   for (auto &algo : non_default_bx_ranges) {
0628     const std::string &algoName = algo.first;
0629     unsigned int algoBit = algoName2bit[algoName];
0630     for (auto range : algo.second)
0631       for (unsigned int bx = range.first; bx <= range.second; bx++) {
0632         triggerAlgoBxMaskAlgoTrig[bx].push_back(algoBit);
0633       }
0634   }
0635 
0636   // Set prescales to zero if masked
0637   for (unsigned int iSet = 0; iSet < prescales.size(); iSet++) {
0638     for (unsigned int iBit = 0; iBit < prescales[iSet].size(); iBit++) {
0639       // Add protection in case prescale table larger than trigger mask size
0640       if (iBit >= triggerMasks.size()) {
0641         edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0642             << "\nWarning: algoBit in prescale table >= triggerMasks.size() "
0643             << "\nWarning: no information on masking bit or not, setting as unmasked " << std::endl;
0644       } else {
0645         prescales[iSet][iBit] *= triggerMasks[iBit];
0646       }
0647     }
0648   }
0649 
0650   /////////////
0651 
0652   l1t::PrescalesVetosFractHelper data_(new L1TGlobalPrescalesVetosFract());
0653 
0654   data_.setBxMaskDefault(m_bx_mask_default);
0655   data_.setPrescaleFactorTable(prescales);
0656   data_.setTriggerMaskVeto(triggerVetoMasks);
0657   data_.setTriggerAlgoBxMask(triggerAlgoBxMaskAlgoTrig);
0658 
0659   auto payload = std::make_unique<const L1TGlobalPrescalesVetosFract>(*data_.getWriteInstance());
0660 
0661   edm::LogInfo("L1-O2O: L1TGlobalPrescalesVetosOnlineProd")
0662       << "SummaryForFunctionManager: uGTrs | OK      | All looks good";
0663 
0664   return payload;
0665 }
0666 
0667 //define this as a plug-in
0668 DEFINE_FWK_EVENTSETUP_MODULE(L1TGlobalPrescalesVetosOnlineProd);