Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-12-20 03:13:55

0001 /**
0002  * \class TriggerMenuParser
0003  *
0004  *
0005  * Description: Xerces-C XML parser for the L1 Trigger menu.
0006  *
0007  * Implementation:
0008  *    <TODO: enter implementation details>
0009  *
0010  * \orig author: Vasile Mihai Ghete - HEPHY Vienna
0011  *
0012  * \new features: Vladimir Rekovic
0013  *                - indexing
0014  *                - correlations with overlap object removal
0015  * \new features: Richard Cavanaugh
0016  *                - LLP displaced muons
0017  *                - LLP displaced jets
0018  * \new features: Elisa Fontanesi
0019  *                - extended for three-body correlation conditions
0020  * \new features: Dragana Pilipovic
0021  *                - updated for invariant mass over delta R condition
0022  * \new features: Bernhard Arnold, Elisa Fontanesi
0023  *                - extended for muon track finder index feature (used for Run 3 muon monitoring seeds)
0024  *                - checkRangeEta function allows to use up to five eta cuts in L1 algorithms
0025  * \new features: Elisa Fontanesi
0026  *                - extended for Zero Degree Calorimeter triggers (used for Run 3 HI data-taking)
0027  * \new features: Melissa Quinnan, Elisa Fontanesi
0028  *                - extended for AXOL1TL anomaly detection triggers (used for Run 3 data-taking)
0029  * \new features: Elisa Fontanesi
0030  *                - extended for HTMHF triggers (introduced for the Run 3 2024 data-taking)
0031  *
0032  * $Date$
0033  * $Revision$
0034  *
0035  */
0036 
0037 // this class header
0038 #include "TriggerMenuParser.h"
0039 
0040 // system include files
0041 #include <string>
0042 #include <vector>
0043 
0044 #include <iostream>
0045 #include <fstream>
0046 #include <iomanip>
0047 #include <cmath>
0048 
0049 #include "L1Trigger/L1TGlobal/interface/GlobalCondition.h"
0050 
0051 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0052 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0053 
0054 #include "tmEventSetup/tmEventSetup.hh"
0055 #include "tmEventSetup/esTypes.hh"
0056 
0057 #include "CondFormats/L1TObjects/interface/L1TUtmTriggerMenu.h"
0058 #include "CondFormats/L1TObjects/interface/L1TUtmAlgorithm.h"
0059 #include "CondFormats/L1TObjects/interface/L1TUtmCondition.h"
0060 #include "CondFormats/L1TObjects/interface/L1TUtmObject.h"
0061 #include "CondFormats/L1TObjects/interface/L1TUtmCut.h"
0062 #include "CondFormats/L1TObjects/interface/L1TUtmScale.h"
0063 #include "tmGrammar/Algorithm.hh"
0064 
0065 #include <cstdint>
0066 
0067 // constructor
0068 l1t::TriggerMenuParser::TriggerMenuParser()
0069     : m_triggerMenuInterface("NULL"),
0070       m_triggerMenuName("NULL"),
0071       m_triggerMenuImplementation(0x0),
0072       m_scaleDbKey("NULL")
0073 
0074 {
0075   // menu names, scale key initialized to NULL due to ORACLE treatment of strings
0076 
0077   // empty
0078 }
0079 
0080 // destructor
0081 l1t::TriggerMenuParser::~TriggerMenuParser() { clearMaps(); }
0082 
0083 // set the number of condition chips in GTL
0084 void l1t::TriggerMenuParser::setGtNumberConditionChips(const unsigned int& numberConditionChipsValue) {
0085   m_numberConditionChips = numberConditionChipsValue;
0086 }
0087 
0088 // set the number of pins on the GTL condition chips
0089 void l1t::TriggerMenuParser::setGtPinsOnConditionChip(const unsigned int& pinsOnConditionChipValue) {
0090   m_pinsOnConditionChip = pinsOnConditionChipValue;
0091 }
0092 
0093 // set the correspondence "condition chip - GTL algorithm word"
0094 // in the hardware
0095 void l1t::TriggerMenuParser::setGtOrderConditionChip(const std::vector<int>& orderConditionChipValue) {
0096   m_orderConditionChip = orderConditionChipValue;
0097 }
0098 
0099 // set the number of physics trigger algorithms
0100 void l1t::TriggerMenuParser::setGtNumberPhysTriggers(const unsigned int& numberPhysTriggersValue) {
0101   m_numberPhysTriggers = numberPhysTriggersValue;
0102 }
0103 
0104 // set the condition maps
0105 void l1t::TriggerMenuParser::setGtConditionMap(const std::vector<ConditionMap>& condMap) { m_conditionMap = condMap; }
0106 
0107 // set the trigger menu name
0108 void l1t::TriggerMenuParser::setGtTriggerMenuInterface(const std::string& menuInterface) {
0109   m_triggerMenuInterface = menuInterface;
0110 }
0111 
0112 // set the trigger menu uuid
0113 void l1t::TriggerMenuParser::setGtTriggerMenuUUID(const int uuid) { m_triggerMenuUUID = uuid; }
0114 
0115 void l1t::TriggerMenuParser::setGtTriggerMenuName(const std::string& menuName) { m_triggerMenuName = menuName; }
0116 
0117 void l1t::TriggerMenuParser::setGtTriggerMenuImplementation(const unsigned long& menuImplementation) {
0118   m_triggerMenuImplementation = menuImplementation;
0119 }
0120 
0121 // set menu associated scale key
0122 void l1t::TriggerMenuParser::setGtScaleDbKey(const std::string& scaleKey) { m_scaleDbKey = scaleKey; }
0123 
0124 // set the vectors containing the conditions
0125 void l1t::TriggerMenuParser::setVecMuonTemplate(const std::vector<std::vector<MuonTemplate> >& vecMuonTempl) {
0126   m_vecMuonTemplate = vecMuonTempl;
0127 }
0128 
0129 void l1t::TriggerMenuParser::setVecMuonShowerTemplate(
0130     const std::vector<std::vector<MuonShowerTemplate> >& vecMuonShowerTempl) {
0131   m_vecMuonShowerTemplate = vecMuonShowerTempl;
0132 }
0133 
0134 void l1t::TriggerMenuParser::setVecCaloTemplate(const std::vector<std::vector<CaloTemplate> >& vecCaloTempl) {
0135   m_vecCaloTemplate = vecCaloTempl;
0136 }
0137 
0138 void l1t::TriggerMenuParser::setVecEnergySumTemplate(
0139     const std::vector<std::vector<EnergySumTemplate> >& vecEnergySumTempl) {
0140   m_vecEnergySumTemplate = vecEnergySumTempl;
0141 }
0142 
0143 void l1t::TriggerMenuParser::setVecEnergySumZdcTemplate(
0144     const std::vector<std::vector<EnergySumZdcTemplate> >& vecEnergySumZdcTempl) {
0145   m_vecEnergySumZdcTemplate = vecEnergySumZdcTempl;
0146 }
0147 
0148 void l1t::TriggerMenuParser::setVecAXOL1TLTemplate(const std::vector<std::vector<AXOL1TLTemplate> >& vecAXOL1TLTempl) {
0149   m_vecAXOL1TLTemplate = vecAXOL1TLTempl;
0150 }
0151 
0152 void l1t::TriggerMenuParser::setVecCICADATemplate(const std::vector<std::vector<CICADATemplate> >& vecCICADATempl) {
0153   m_vecCICADATemplate = vecCICADATempl;
0154 }
0155 
0156 void l1t::TriggerMenuParser::setVecExternalTemplate(
0157     const std::vector<std::vector<ExternalTemplate> >& vecExternalTempl) {
0158   m_vecExternalTemplate = vecExternalTempl;
0159 }
0160 
0161 void l1t::TriggerMenuParser::setVecCorrelationTemplate(
0162     const std::vector<std::vector<CorrelationTemplate> >& vecCorrelationTempl) {
0163   m_vecCorrelationTemplate = vecCorrelationTempl;
0164 }
0165 
0166 void l1t::TriggerMenuParser::setVecCorrelationThreeBodyTemplate(
0167     const std::vector<std::vector<CorrelationThreeBodyTemplate> >& vecCorrelationThreeBodyTempl) {
0168   m_vecCorrelationThreeBodyTemplate = vecCorrelationThreeBodyTempl;
0169 }
0170 
0171 void l1t::TriggerMenuParser::setVecCorrelationWithOverlapRemovalTemplate(
0172     const std::vector<std::vector<CorrelationWithOverlapRemovalTemplate> >& vecCorrelationWithOverlapRemovalTempl) {
0173   m_vecCorrelationWithOverlapRemovalTemplate = vecCorrelationWithOverlapRemovalTempl;
0174 }
0175 
0176 // set the vectors containing the conditions for correlation templates
0177 //
0178 void l1t::TriggerMenuParser::setCorMuonTemplate(const std::vector<std::vector<MuonTemplate> >& corMuonTempl) {
0179   m_corMuonTemplate = corMuonTempl;
0180 }
0181 
0182 void l1t::TriggerMenuParser::setCorCaloTemplate(const std::vector<std::vector<CaloTemplate> >& corCaloTempl) {
0183   m_corCaloTemplate = corCaloTempl;
0184 }
0185 
0186 void l1t::TriggerMenuParser::setCorEnergySumTemplate(
0187     const std::vector<std::vector<EnergySumTemplate> >& corEnergySumTempl) {
0188   m_corEnergySumTemplate = corEnergySumTempl;
0189 }
0190 
0191 // set the algorithm map (by algorithm names)
0192 void l1t::TriggerMenuParser::setGtAlgorithmMap(const AlgorithmMap& algoMap) { m_algorithmMap = algoMap; }
0193 
0194 // set the algorithm map (by algorithm aliases)
0195 void l1t::TriggerMenuParser::setGtAlgorithmAliasMap(const AlgorithmMap& algoMap) { m_algorithmAliasMap = algoMap; }
0196 
0197 std::map<std::string, unsigned int> l1t::TriggerMenuParser::getExternalSignals(const L1TUtmTriggerMenu* utmMenu) {
0198   using namespace tmeventsetup;
0199   const std::map<std::string, L1TUtmCondition>& condMap = utmMenu->getConditionMap();
0200 
0201   std::map<std::string, unsigned int> extBitMap;
0202 
0203   //loop over the algorithms
0204   for (const auto& cit : condMap) {
0205     const L1TUtmCondition& condition = cit.second;
0206     if (condition.getType() == esConditionType::Externals) {
0207       // Get object for External conditions
0208       const std::vector<L1TUtmObject>& objects = condition.getObjects();
0209       for (const auto& object : objects) {
0210         if (object.getType() == esObjectType::EXT) {
0211           unsigned int channelID = object.getExternalChannelId();
0212           std::string name = object.getExternalSignalName();
0213 
0214           if (extBitMap.count(name) == 0)
0215             extBitMap.insert(std::map<std::string, unsigned int>::value_type(name, channelID));
0216         }
0217       }
0218     }
0219   }
0220 
0221   return extBitMap;
0222 }
0223 
0224 // parse def.xml file
0225 void l1t::TriggerMenuParser::parseCondFormats(const L1TUtmTriggerMenu* utmMenu) {
0226   // resize the vector of condition maps
0227   // the number of condition chips should be correctly set before calling parseXmlFile
0228   m_conditionMap.resize(m_numberConditionChips);
0229 
0230   m_vecMuonTemplate.resize(m_numberConditionChips);
0231   m_vecMuonShowerTemplate.resize(m_numberConditionChips);
0232   m_vecCaloTemplate.resize(m_numberConditionChips);
0233   m_vecEnergySumTemplate.resize(m_numberConditionChips);
0234   m_vecEnergySumZdcTemplate.resize(m_numberConditionChips);
0235   m_vecAXOL1TLTemplate.resize(m_numberConditionChips);
0236   m_vecCICADATemplate.resize(m_numberConditionChips);
0237   m_vecExternalTemplate.resize(m_numberConditionChips);
0238 
0239   m_vecCorrelationTemplate.resize(m_numberConditionChips);
0240   m_vecCorrelationThreeBodyTemplate.resize(m_numberConditionChips);
0241   m_vecCorrelationWithOverlapRemovalTemplate.resize(m_numberConditionChips);
0242   m_corMuonTemplate.resize(m_numberConditionChips);
0243   m_corCaloTemplate.resize(m_numberConditionChips);
0244   m_corEnergySumTemplate.resize(m_numberConditionChips);
0245 
0246   using namespace tmeventsetup;
0247   using namespace Algorithm;
0248 
0249   //get the meta data
0250   m_triggerMenuDescription = utmMenu->getComment();
0251   m_triggerMenuDate = utmMenu->getDatetime();
0252   m_triggerMenuImplementation = (getMmHashN(utmMenu->getFirmwareUuid()) & 0xFFFFFFFF);  //make sure we only have 32 bits
0253   m_triggerMenuName = utmMenu->getName();
0254   m_triggerMenuInterface = utmMenu->getVersion();                     //BLW: correct descriptor?
0255   m_triggerMenuUUID = (getMmHashN(utmMenu->getName()) & 0xFFFFFFFF);  //make sure we only have 32 bits
0256 
0257   const std::map<std::string, L1TUtmAlgorithm>& algoMap = utmMenu->getAlgorithmMap();
0258   const std::map<std::string, L1TUtmCondition>& condMap = utmMenu->getConditionMap();
0259   //We use es types for scale map to use auxiliary functions without having to duplicate code
0260   const std::map<std::string, tmeventsetup::esScale> scaleMap(std::begin(utmMenu->getScaleMap()),
0261                                                               std::end(utmMenu->getScaleMap()));
0262 
0263   // parse the scales
0264   m_gtScales.setScalesName(utmMenu->getScaleSetName());
0265   parseScales(scaleMap);
0266 
0267   //loop over the algorithms
0268   for (const auto& cit : algoMap) {
0269     //condition chip (artifact)  TO DO: Update
0270     int chipNr = 0;
0271 
0272     //get algorithm
0273     const L1TUtmAlgorithm& algo = cit.second;
0274 
0275     //parse the algorithm
0276     parseAlgorithm(algo, chipNr);  //blw
0277 
0278     //get conditions for this algorithm
0279     const std::vector<std::string>& rpn_vec = algo.getRpnVector();
0280     for (size_t ii = 0; ii < rpn_vec.size(); ii++) {
0281       const std::string& token = rpn_vec.at(ii);
0282       if (isGate(token))
0283         continue;
0284       //      long hash = getHash(token);
0285       const L1TUtmCondition& condition = condMap.find(token)->second;
0286 
0287       //check to see if this condtion already exists
0288       if ((m_conditionMap[chipNr]).count(condition.getName()) == 0) {
0289         // parse Calo Conditions (EG, Jets, Taus)
0290         if (condition.getType() == esConditionType::SingleEgamma ||
0291             condition.getType() == esConditionType::DoubleEgamma ||
0292             condition.getType() == esConditionType::TripleEgamma ||
0293             condition.getType() == esConditionType::QuadEgamma || condition.getType() == esConditionType::SingleTau ||
0294             condition.getType() == esConditionType::DoubleTau || condition.getType() == esConditionType::TripleTau ||
0295             condition.getType() == esConditionType::QuadTau || condition.getType() == esConditionType::SingleJet ||
0296             condition.getType() == esConditionType::DoubleJet || condition.getType() == esConditionType::TripleJet ||
0297             condition.getType() == esConditionType::QuadJet) {
0298           parseCalo(condition, chipNr, false);
0299 
0300           // parse Energy Sums (and HI trigger objects, treated as energy sums or counters)
0301         } else if (condition.getType() == esConditionType::TotalEt ||
0302                    condition.getType() == esConditionType::TotalEtEM ||
0303                    condition.getType() == esConditionType::TotalHt ||
0304                    condition.getType() == esConditionType::MissingEt ||
0305                    condition.getType() == esConditionType::MissingHt ||
0306                    condition.getType() == esConditionType::MissingEtHF ||
0307                    condition.getType() == esConditionType::MissingHtHF ||
0308                    condition.getType() == esConditionType::TowerCount ||
0309                    condition.getType() == esConditionType::MinBiasHFP0 ||
0310                    condition.getType() == esConditionType::MinBiasHFM0 ||
0311                    condition.getType() == esConditionType::MinBiasHFP1 ||
0312                    condition.getType() == esConditionType::MinBiasHFM1 ||
0313                    condition.getType() == esConditionType::AsymmetryEt ||
0314                    condition.getType() == esConditionType::AsymmetryHt ||
0315                    condition.getType() == esConditionType::AsymmetryEtHF ||
0316                    condition.getType() == esConditionType::AsymmetryHtHF ||
0317                    condition.getType() == esConditionType::Centrality0 ||
0318                    condition.getType() == esConditionType::Centrality1 ||
0319                    condition.getType() == esConditionType::Centrality2 ||
0320                    condition.getType() == esConditionType::Centrality3 ||
0321                    condition.getType() == esConditionType::Centrality4 ||
0322                    condition.getType() == esConditionType::Centrality5 ||
0323                    condition.getType() == esConditionType::Centrality6 ||
0324                    condition.getType() == esConditionType::Centrality7) {
0325           parseEnergySum(condition, chipNr, false);
0326 
0327           // parse ZDC Energy Sums (NOTE: HI trigger objects are treated as energy sums or counters)
0328         } else if (condition.getType() == esConditionType::ZDCPlus ||
0329                    condition.getType() == esConditionType::ZDCMinus) {
0330           parseEnergySumZdc(condition, chipNr, false);
0331 
0332           //parse AXOL1TL
0333         } else if (condition.getType() == esConditionType::Axol1tlTrigger ||
0334                    condition.getType() == esConditionType::AnomalyDetectionTrigger) {
0335           parseAXOL1TL(condition, chipNr);
0336 
0337           //parse CICADA
0338         } else if (condition.getType() == esConditionType::CicadaTrigger) {
0339           parseCICADA(condition, chipNr);
0340           //parse Muons
0341         } else if (condition.getType() == esConditionType::SingleMuon ||
0342                    condition.getType() == esConditionType::DoubleMuon ||
0343                    condition.getType() == esConditionType::TripleMuon ||
0344                    condition.getType() == esConditionType::QuadMuon) {
0345           parseMuon(condition, chipNr, false);
0346 
0347         } else if (condition.getType() == esConditionType::MuonShower0 ||
0348                    condition.getType() == esConditionType::MuonShower1 ||
0349                    condition.getType() == esConditionType::MuonShower2 ||
0350                    condition.getType() == esConditionType::MuonShowerOutOfTime0 ||
0351                    condition.getType() == esConditionType::MuonShowerOutOfTime1) {
0352           parseMuonShower(condition, chipNr, false);
0353 
0354           //parse Correlation Conditions
0355         } else if (condition.getType() == esConditionType::MuonMuonCorrelation ||
0356                    condition.getType() == esConditionType::MuonEsumCorrelation ||
0357                    condition.getType() == esConditionType::CaloMuonCorrelation ||
0358                    condition.getType() == esConditionType::CaloCaloCorrelation ||
0359                    condition.getType() == esConditionType::CaloEsumCorrelation ||
0360                    condition.getType() == esConditionType::InvariantMass ||
0361                    condition.getType() == esConditionType::InvariantMassDeltaR ||
0362                    condition.getType() == esConditionType::TransverseMass ||
0363                    condition.getType() == esConditionType::InvariantMassUpt) {  // Added for displaced muons
0364           parseCorrelation(condition, chipNr);
0365 
0366           //parse three-body Correlation Conditions
0367         } else if (condition.getType() == esConditionType::InvariantMass3) {
0368           parseCorrelationThreeBody(condition, chipNr);
0369 
0370           //parse Externals
0371         } else if (condition.getType() == esConditionType::Externals) {
0372           parseExternal(condition, chipNr);
0373 
0374           //parse CorrelationWithOverlapRemoval
0375         } else if (condition.getType() == esConditionType::CaloCaloCorrelationOvRm ||
0376                    condition.getType() == esConditionType::InvariantMassOvRm ||
0377                    condition.getType() == esConditionType::TransverseMassOvRm ||
0378                    condition.getType() == esConditionType::DoubleJetOvRm ||
0379                    condition.getType() == esConditionType::DoubleTauOvRm) {
0380           parseCorrelationWithOverlapRemoval(condition, chipNr);
0381 
0382         } else if (condition.getType() == esConditionType::SingleEgammaOvRm ||
0383                    condition.getType() == esConditionType::DoubleEgammaOvRm ||
0384                    condition.getType() == esConditionType::TripleEgammaOvRm ||
0385                    condition.getType() == esConditionType::QuadEgammaOvRm ||
0386                    condition.getType() == esConditionType::SingleTauOvRm ||
0387                    condition.getType() == esConditionType::TripleTauOvRm ||
0388                    condition.getType() == esConditionType::QuadTauOvRm ||
0389                    condition.getType() == esConditionType::SingleJetOvRm ||
0390                    condition.getType() == esConditionType::TripleJetOvRm ||
0391                    condition.getType() == esConditionType::QuadJetOvRm) {
0392           edm::LogError("TriggerMenuParser") << std::endl
0393                                              << "\n SingleEgammaOvRm"
0394                                              << "\n DoubleEgammaOvRm"
0395                                              << "\n TripleEgammaOvRm"
0396                                              << "\n QuadEgammaOvRm"
0397                                              << "\n SingleTauOvRm"
0398                                              << "\n TripleTauOvRm"
0399                                              << "\n QuadTauOvRm"
0400                                              << "\n SingleJetOvRm"
0401                                              << "\n TripleJetOvRm"
0402                                              << "\n QuadJetOvRm"
0403                                              << "\n The above conditions types OvRm are not implemented yet in the "
0404                                                 "parser. Please remove alogrithms that "
0405                                                 "use this type of condtion from L1T Menu!"
0406                                              << std::endl;
0407         }
0408 
0409       }  //if condition is a new one
0410     }  //loop over conditions
0411   }  //loop over algorithms
0412 
0413   return;
0414 }
0415 
0416 //
0417 
0418 void l1t::TriggerMenuParser::setGtTriggerMenuInterfaceDate(const std::string& val) { m_triggerMenuInterfaceDate = val; }
0419 
0420 void l1t::TriggerMenuParser::setGtTriggerMenuInterfaceAuthor(const std::string& val) {
0421   m_triggerMenuInterfaceAuthor = val;
0422 }
0423 
0424 void l1t::TriggerMenuParser::setGtTriggerMenuInterfaceDescription(const std::string& val) {
0425   m_triggerMenuInterfaceDescription = val;
0426 }
0427 
0428 void l1t::TriggerMenuParser::setGtTriggerMenuDate(const std::string& val) { m_triggerMenuDate = val; }
0429 
0430 void l1t::TriggerMenuParser::setGtTriggerMenuAuthor(const std::string& val) { m_triggerMenuAuthor = val; }
0431 
0432 void l1t::TriggerMenuParser::setGtTriggerMenuDescription(const std::string& val) { m_triggerMenuDescription = val; }
0433 
0434 void l1t::TriggerMenuParser::setGtAlgorithmImplementation(const std::string& val) { m_algorithmImplementation = val; }
0435 
0436 // methods for conditions and algorithms
0437 
0438 // clearMaps - delete all conditions and algorithms in
0439 // the maps and clear the maps.
0440 void l1t::TriggerMenuParser::clearMaps() {
0441   // loop over condition maps (one map per condition chip)
0442   // then loop over conditions in the map
0443   for (std::vector<ConditionMap>::iterator itCondOnChip = m_conditionMap.begin(); itCondOnChip != m_conditionMap.end();
0444        itCondOnChip++) {
0445     // the conditions in the maps are deleted in L1uGtTriggerMenu, not here
0446 
0447     itCondOnChip->clear();
0448   }
0449 
0450   // the algorithms in the maps are deleted in L1uGtTriggerMenu, not here
0451   m_algorithmMap.clear();
0452 }
0453 
0454 // insertConditionIntoMap - safe insert of condition into condition map.
0455 // if the condition name already exists, do not insert it and return false
0456 bool l1t::TriggerMenuParser::insertConditionIntoMap(GlobalCondition& cond, const int chipNr) {
0457   std::string cName = cond.condName();
0458   LogTrace("TriggerMenuParser") << "    Trying to insert condition \"" << cName << "\" in the condition map."
0459                                 << std::endl;
0460 
0461   // no condition name has to appear twice!
0462   if ((m_conditionMap[chipNr]).count(cName) != 0) {
0463     LogTrace("TriggerMenuParser") << "      Condition " << cName << " already exists - not inserted!" << std::endl;
0464     return false;
0465   }
0466 
0467   (m_conditionMap[chipNr])[cName] = &cond;
0468   LogTrace("TriggerMenuParser") << "      OK - condition inserted!" << std::endl;
0469 
0470   return true;
0471 }
0472 
0473 // insert an algorithm into algorithm map
0474 bool l1t::TriggerMenuParser::insertAlgorithmIntoMap(const GlobalAlgorithm& alg) {
0475   std::string algName = alg.algoName();
0476   const std::string& algAlias = alg.algoAlias();
0477   //LogTrace("TriggerMenuParser")
0478   //<< "    Trying to insert algorithm \"" << algName << "\" in the algorithm map." ;
0479 
0480   // no algorithm name has to appear twice!
0481   if (m_algorithmMap.count(algName) != 0) {
0482     LogTrace("TriggerMenuParser") << "      Algorithm \"" << algName
0483                                   << "\"already exists in the algorithm map- not inserted!" << std::endl;
0484     return false;
0485   }
0486 
0487   if (m_algorithmAliasMap.count(algAlias) != 0) {
0488     LogTrace("TriggerMenuParser") << "      Algorithm alias \"" << algAlias
0489                                   << "\"already exists in the algorithm alias map- not inserted!" << std::endl;
0490     return false;
0491   }
0492 
0493   // bit number less than zero or greater than maximum number of algorithms
0494   int bitNumber = alg.algoBitNumber();
0495   if ((bitNumber < 0) || (bitNumber >= static_cast<int>(m_numberPhysTriggers))) {
0496     LogTrace("TriggerMenuParser") << "      Bit number " << bitNumber << " outside allowed range [0, "
0497                                   << m_numberPhysTriggers << ") - algorithm not inserted!" << std::endl;
0498     return false;
0499   }
0500 
0501   // maximum number of algorithms
0502   if (m_algorithmMap.size() >= m_numberPhysTriggers) {
0503     LogTrace("TriggerMenuParser") << "      More than maximum allowed " << m_numberPhysTriggers
0504                                   << " algorithms in the algorithm map - not inserted!" << std::endl;
0505     return false;
0506   }
0507 
0508   // chip number outside allowed values
0509   int chipNr = alg.algoChipNumber(
0510       static_cast<int>(m_numberConditionChips), static_cast<int>(m_pinsOnConditionChip), m_orderConditionChip);
0511 
0512   if ((chipNr < 0) || (chipNr > static_cast<int>(m_numberConditionChips))) {
0513     LogTrace("TriggerMenuParser") << "      Chip number " << chipNr << " outside allowed range [0, "
0514                                   << m_numberConditionChips << ") - algorithm not inserted!" << std::endl;
0515     return false;
0516   }
0517 
0518   // output pin outside allowed values
0519   int outputPin = alg.algoOutputPin(
0520       static_cast<int>(m_numberConditionChips), static_cast<int>(m_pinsOnConditionChip), m_orderConditionChip);
0521 
0522   if ((outputPin < 0) || (outputPin > static_cast<int>(m_pinsOnConditionChip))) {
0523     LogTrace("TriggerMenuParser") << "      Output pin " << outputPin << " outside allowed range [0, "
0524                                   << m_pinsOnConditionChip << "] - algorithm not inserted!" << std::endl;
0525     return false;
0526   }
0527 
0528   // no two algorithms on the same chip can have the same output pin
0529   for (CItAlgo itAlgo = m_algorithmMap.begin(); itAlgo != m_algorithmMap.end(); itAlgo++) {
0530     int iPin = (itAlgo->second)
0531                    .algoOutputPin(static_cast<int>(m_numberConditionChips),
0532                                   static_cast<int>(m_pinsOnConditionChip),
0533                                   m_orderConditionChip);
0534     std::string iName = itAlgo->first;
0535     int iChip = (itAlgo->second)
0536                     .algoChipNumber(static_cast<int>(m_numberConditionChips),
0537                                     static_cast<int>(m_pinsOnConditionChip),
0538                                     m_orderConditionChip);
0539 
0540     if ((outputPin == iPin) && (chipNr == iChip)) {
0541       LogTrace("TriggerMenuParser") << "      Output pin " << outputPin << " is the same as for algorithm " << iName
0542                                     << "\n      from the same chip number " << chipNr << " - algorithm not inserted!"
0543                                     << std::endl;
0544       return false;
0545     }
0546   }
0547 
0548   // insert algorithm
0549   m_algorithmMap[algName] = alg;
0550   m_algorithmAliasMap[algAlias] = alg;
0551 
0552   //LogTrace("TriggerMenuParser")
0553   //<< "      OK - algorithm inserted!"
0554   //<< std::endl;
0555 
0556   return true;
0557 }
0558 
0559 template <typename T>
0560 std::string l1t::TriggerMenuParser::l1t2string(T data) {
0561   std::stringstream ss;
0562   ss << data;
0563   return ss.str();
0564 }
0565 int l1t::TriggerMenuParser::l1tstr2int(const std::string data) {
0566   std::stringstream ss;
0567   ss << data;
0568   int value;
0569   ss >> value;
0570   return value;
0571 }
0572 
0573 /**
0574  * parseScales Parse Et, Eta, and Phi Scales
0575  *
0576  * @return "true" if succeeded, "false" if an error occurred.
0577  *
0578  */
0579 
0580 bool l1t::TriggerMenuParser::parseScales(std::map<std::string, tmeventsetup::esScale> scaleMap) {
0581   using namespace tmeventsetup;
0582 
0583   //  Setup ScaleParameter to hold information from parsing
0584   GlobalScales::ScaleParameters muScales;
0585   GlobalScales::ScaleParameters egScales;
0586   GlobalScales::ScaleParameters tauScales;
0587   GlobalScales::ScaleParameters jetScales;
0588   GlobalScales::ScaleParameters ettScales;
0589   GlobalScales::ScaleParameters ettEmScales;
0590   GlobalScales::ScaleParameters etmScales;
0591   GlobalScales::ScaleParameters etmHfScales;
0592   GlobalScales::ScaleParameters htmHfScales;
0593   GlobalScales::ScaleParameters httScales;
0594   GlobalScales::ScaleParameters htmScales;
0595   GlobalScales::ScaleParameters zdcScales;
0596 
0597   // Start by parsing the Scale Map
0598   for (std::map<std::string, tmeventsetup::esScale>::const_iterator cit = scaleMap.begin(); cit != scaleMap.end();
0599        cit++) {
0600     const tmeventsetup::esScale& scale = cit->second;
0601 
0602     GlobalScales::ScaleParameters* scaleParam;
0603     if (scale.getObjectType() == esObjectType::Muon)
0604       scaleParam = &muScales;
0605     else if (scale.getObjectType() == esObjectType::Egamma)
0606       scaleParam = &egScales;
0607     else if (scale.getObjectType() == esObjectType::Tau)
0608       scaleParam = &tauScales;
0609     else if (scale.getObjectType() == esObjectType::Jet)
0610       scaleParam = &jetScales;
0611     else if (scale.getObjectType() == esObjectType::ETT)
0612       scaleParam = &ettScales;
0613     else if (scale.getObjectType() == esObjectType::ETTEM)
0614       scaleParam = &ettEmScales;
0615     else if (scale.getObjectType() == esObjectType::ETM)
0616       scaleParam = &etmScales;
0617     else if (scale.getObjectType() == esObjectType::ETMHF)
0618       scaleParam = &etmHfScales;
0619     else if (scale.getObjectType() == esObjectType::HTMHF)
0620       scaleParam = &htmHfScales;
0621     else if (scale.getObjectType() == esObjectType::HTT)
0622       scaleParam = &httScales;
0623     else if (scale.getObjectType() == esObjectType::HTM)
0624       scaleParam = &htmScales;
0625     else if (scale.getObjectType() == esObjectType::ZDCP || scale.getObjectType() == esObjectType::ZDCM)
0626       scaleParam = &zdcScales;
0627     else
0628       scaleParam = nullptr;
0629 
0630     if (scaleParam != nullptr) {
0631       switch (scale.getScaleType()) {
0632         case esScaleType::EtScale: {
0633           scaleParam->etMin = scale.getMinimum();
0634           scaleParam->etMax = scale.getMaximum();
0635           scaleParam->etStep = scale.getStep();
0636 
0637           //Get bin edges
0638           const std::vector<tmeventsetup::esBin>& binsV = scale.getBins();
0639           for (unsigned int i = 0; i < binsV.size(); i++) {
0640             const tmeventsetup::esBin& bin = binsV.at(i);
0641             std::pair<double, double> binLimits(bin.minimum, bin.maximum);
0642             scaleParam->etBins.push_back(binLimits);
0643           }
0644 
0645           // If this is an energy sum fill dummy values for eta and phi
0646           // There are no scales for these in the XML so the other case statements will not be seen....do it here.
0647           if (scale.getObjectType() == esObjectType::ETT || scale.getObjectType() == esObjectType::HTT ||
0648               scale.getObjectType() == esObjectType::ETM || scale.getObjectType() == esObjectType::HTM ||
0649               scale.getObjectType() == esObjectType::ETTEM || scale.getObjectType() == esObjectType::ETMHF ||
0650               scale.getObjectType() == esObjectType::HTMHF) {
0651             scaleParam->etaMin = -1.;
0652             scaleParam->etaMax = -1.;
0653             scaleParam->etaStep = -1.;
0654             if (scale.getObjectType() == esObjectType::ETT || scale.getObjectType() == esObjectType::HTT ||
0655                 scale.getObjectType() == esObjectType::ETTEM) {
0656               //           if(scale.getObjectType() == esObjectType::ETT || scale.getObjectType() == esObjectType::HTT) {
0657               scaleParam->phiMin = -1.;
0658               scaleParam->phiMax = -1.;
0659               scaleParam->phiStep = -1.;
0660             }
0661           }
0662         } break;
0663         case esScaleType::UnconstrainedPtScale: {  // Added for displaced muons
0664           scaleParam->uptMin = scale.getMinimum();
0665           scaleParam->uptMax = scale.getMaximum();
0666           scaleParam->uptStep = scale.getStep();
0667 
0668           //Get bin edges
0669           const std::vector<tmeventsetup::esBin>& binsV = scale.getBins();
0670           for (unsigned int i = 0; i < binsV.size(); i++) {
0671             const tmeventsetup::esBin& bin = binsV.at(i);
0672             std::pair<double, double> binLimits(bin.minimum, bin.maximum);
0673             scaleParam->uptBins.push_back(binLimits);
0674           }
0675         } break;
0676         case esScaleType::EtaScale: {
0677           scaleParam->etaMin = scale.getMinimum();
0678           scaleParam->etaMax = scale.getMaximum();
0679           scaleParam->etaStep = scale.getStep();
0680 
0681           //Get bin edges
0682           const std::vector<tmeventsetup::esBin>& binsV = scale.getBins();
0683           scaleParam->etaBins.resize(pow(2, scale.getNbits()));
0684           for (unsigned int i = 0; i < binsV.size(); i++) {
0685             const tmeventsetup::esBin& bin = binsV.at(i);
0686             std::pair<double, double> binLimits(bin.minimum, bin.maximum);
0687             scaleParam->etaBins.at(bin.hw_index) = binLimits;
0688           }
0689         } break;
0690         case esScaleType::PhiScale: {
0691           scaleParam->phiMin = scale.getMinimum();
0692           scaleParam->phiMax = scale.getMaximum();
0693           scaleParam->phiStep = scale.getStep();
0694 
0695           //Get bin edges
0696           const std::vector<tmeventsetup::esBin>& binsV = scale.getBins();
0697           scaleParam->phiBins.resize(pow(2, scale.getNbits()));
0698           for (unsigned int i = 0; i < binsV.size(); i++) {
0699             const tmeventsetup::esBin& bin = binsV.at(i);
0700             std::pair<double, double> binLimits(bin.minimum, bin.maximum);
0701             scaleParam->phiBins.at(bin.hw_index) = binLimits;
0702           }
0703         } break;
0704         default:
0705 
0706           break;
0707       }  //end switch
0708     }  //end valid scale
0709   }  //end loop over scaleMap
0710 
0711   // put the ScaleParameters into the class
0712   m_gtScales.setMuonScales(muScales);
0713   m_gtScales.setEGScales(egScales);
0714   m_gtScales.setTauScales(tauScales);
0715   m_gtScales.setJetScales(jetScales);
0716   m_gtScales.setETTScales(ettScales);
0717   m_gtScales.setETTEmScales(ettEmScales);
0718   m_gtScales.setETMScales(etmScales);
0719   m_gtScales.setETMHfScales(etmHfScales);
0720   m_gtScales.setHTMHfScales(htmHfScales);
0721   m_gtScales.setHTTScales(httScales);
0722   m_gtScales.setHTMScales(htmScales);
0723   m_gtScales.setHTMScales(zdcScales);
0724 
0725   // Setup the LUT for the Scale Conversions
0726   bool hasPrecision = false;
0727   std::map<std::string, unsigned int> precisions;
0728   getPrecisions(precisions, scaleMap);
0729   for (std::map<std::string, unsigned int>::const_iterator cit = precisions.begin(); cit != precisions.end(); cit++) {
0730     hasPrecision = true;
0731   }
0732 
0733   if (hasPrecision) {
0734     //Start with the Cal - Muon Eta LUTS
0735     //----------------------------------
0736     parseCalMuEta_LUTS(scaleMap, "EG", "MU");
0737     parseCalMuEta_LUTS(scaleMap, "JET", "MU");
0738     parseCalMuEta_LUTS(scaleMap, "TAU", "MU");
0739 
0740     //Now the Cal - Muon Phi LUTS
0741     //-------------------------------------
0742     parseCalMuPhi_LUTS(scaleMap, "EG", "MU");
0743     parseCalMuPhi_LUTS(scaleMap, "JET", "MU");
0744     parseCalMuPhi_LUTS(scaleMap, "TAU", "MU");
0745     parseCalMuPhi_LUTS(scaleMap, "HTM", "MU");
0746     parseCalMuPhi_LUTS(scaleMap, "ETM", "MU");
0747     parseCalMuPhi_LUTS(scaleMap, "ETMHF", "MU");
0748     parseCalMuPhi_LUTS(scaleMap, "HTMHF", "MU");
0749 
0750     // Now the Pt LUTs  (??? more combinations needed ??)
0751     // ---------------
0752     parsePt_LUTS(scaleMap, "Mass", "EG", precisions["PRECISION-EG-MU-MassPt"]);
0753     parsePt_LUTS(scaleMap, "Mass", "MU", precisions["PRECISION-EG-MU-MassPt"]);
0754     parseUpt_LUTS(scaleMap, "Mass", "MU", precisions["PRECISION-EG-MU-MassPt"]);  // Added for displaced muons
0755     parsePt_LUTS(scaleMap, "Mass", "JET", precisions["PRECISION-EG-JET-MassPt"]);
0756     parsePt_LUTS(scaleMap, "Mass", "TAU", precisions["PRECISION-EG-TAU-MassPt"]);
0757     parsePt_LUTS(scaleMap, "Mass", "ETM", precisions["PRECISION-EG-ETM-MassPt"]);
0758     parsePt_LUTS(scaleMap, "Mass", "ETMHF", precisions["PRECISION-EG-ETMHF-MassPt"]);
0759     parsePt_LUTS(scaleMap, "Mass", "HTMHF", precisions["PRECISION-EG-HTMHF-MassPt"]);
0760     parsePt_LUTS(scaleMap, "Mass", "HTM", precisions["PRECISION-EG-HTM-MassPt"]);
0761 
0762     // Now the Pt LUTs  for TBPT calculation (??? CCLA following what was done for MASS pt LUTs for now ??)
0763     // ---------------
0764     parsePt_LUTS(scaleMap, "TwoBody", "EG", precisions["PRECISION-EG-MU-TwoBodyPt"]);
0765     parsePt_LUTS(scaleMap, "TwoBody", "MU", precisions["PRECISION-EG-MU-TwoBodyPt"]);
0766     parsePt_LUTS(scaleMap, "TwoBody", "JET", precisions["PRECISION-EG-JET-TwoBodyPt"]);
0767     parsePt_LUTS(scaleMap, "TwoBody", "TAU", precisions["PRECISION-EG-TAU-TwoBodyPt"]);
0768     parsePt_LUTS(scaleMap, "TwoBody", "ETM", precisions["PRECISION-EG-ETM-TwoBodyPt"]);
0769     parsePt_LUTS(scaleMap, "TwoBody", "ETMHF", precisions["PRECISION-EG-ETMHF-TwoBodyPt"]);
0770     parsePt_LUTS(scaleMap, "TwoBody", "HTMHF", precisions["PRECISION-EG-HTMHF-TwoBodyPt"]);
0771     parsePt_LUTS(scaleMap, "TwoBody", "HTM", precisions["PRECISION-EG-HTM-TwoBodyPt"]);
0772 
0773     // Now the Delta Eta/Cosh LUTs (must be done in groups)
0774     // ----------------------------------------------------
0775     parseDeltaEta_Cosh_LUTS(
0776         scaleMap, "EG", "EG", precisions["PRECISION-EG-EG-Delta"], precisions["PRECISION-EG-EG-Math"]);
0777     parseDeltaEta_Cosh_LUTS(
0778         scaleMap, "EG", "JET", precisions["PRECISION-EG-JET-Delta"], precisions["PRECISION-EG-JET-Math"]);
0779     parseDeltaEta_Cosh_LUTS(
0780         scaleMap, "EG", "TAU", precisions["PRECISION-EG-TAU-Delta"], precisions["PRECISION-EG-TAU-Math"]);
0781     parseDeltaEta_Cosh_LUTS(
0782         scaleMap, "EG", "MU", precisions["PRECISION-EG-MU-Delta"], precisions["PRECISION-EG-MU-Math"]);
0783 
0784     parseDeltaEta_Cosh_LUTS(
0785         scaleMap, "JET", "JET", precisions["PRECISION-JET-JET-Delta"], precisions["PRECISION-JET-JET-Math"]);
0786     parseDeltaEta_Cosh_LUTS(
0787         scaleMap, "JET", "TAU", precisions["PRECISION-JET-TAU-Delta"], precisions["PRECISION-JET-TAU-Math"]);
0788     parseDeltaEta_Cosh_LUTS(
0789         scaleMap, "JET", "MU", precisions["PRECISION-JET-MU-Delta"], precisions["PRECISION-JET-MU-Math"]);
0790 
0791     parseDeltaEta_Cosh_LUTS(
0792         scaleMap, "TAU", "TAU", precisions["PRECISION-TAU-TAU-Delta"], precisions["PRECISION-TAU-TAU-Math"]);
0793     parseDeltaEta_Cosh_LUTS(
0794         scaleMap, "TAU", "MU", precisions["PRECISION-TAU-MU-Delta"], precisions["PRECISION-TAU-MU-Math"]);
0795 
0796     parseDeltaEta_Cosh_LUTS(
0797         scaleMap, "MU", "MU", precisions["PRECISION-MU-MU-Delta"], precisions["PRECISION-MU-MU-Math"]);
0798 
0799     // Now the Delta Phi/Cos LUTs (must be done in groups)
0800     // ----------------------------------------------------
0801     parseDeltaPhi_Cos_LUTS(
0802         scaleMap, "EG", "EG", precisions["PRECISION-EG-EG-Delta"], precisions["PRECISION-EG-EG-Math"]);
0803     parseDeltaPhi_Cos_LUTS(
0804         scaleMap, "EG", "JET", precisions["PRECISION-EG-JET-Delta"], precisions["PRECISION-EG-JET-Math"]);
0805     parseDeltaPhi_Cos_LUTS(
0806         scaleMap, "EG", "TAU", precisions["PRECISION-EG-TAU-Delta"], precisions["PRECISION-EG-TAU-Math"]);
0807     parseDeltaPhi_Cos_LUTS(
0808         scaleMap, "EG", "ETM", precisions["PRECISION-EG-ETM-Delta"], precisions["PRECISION-EG-ETM-Math"]);
0809     parseDeltaPhi_Cos_LUTS(
0810         scaleMap, "EG", "ETMHF", precisions["PRECISION-EG-ETMHF-Delta"], precisions["PRECISION-EG-ETMHF-Math"]);
0811     parseDeltaPhi_Cos_LUTS(
0812         scaleMap, "EG", "HTMHF", precisions["PRECISION-EG-HTMHF-Delta"], precisions["PRECISION-EG-HTMHF-Math"]);
0813     parseDeltaPhi_Cos_LUTS(
0814         scaleMap, "EG", "HTM", precisions["PRECISION-EG-HTM-Delta"], precisions["PRECISION-EG-HTM-Math"]);
0815     parseDeltaPhi_Cos_LUTS(
0816         scaleMap, "EG", "MU", precisions["PRECISION-EG-MU-Delta"], precisions["PRECISION-EG-MU-Math"]);
0817 
0818     parseDeltaPhi_Cos_LUTS(
0819         scaleMap, "JET", "JET", precisions["PRECISION-JET-JET-Delta"], precisions["PRECISION-JET-JET-Math"]);
0820     parseDeltaPhi_Cos_LUTS(
0821         scaleMap, "JET", "TAU", precisions["PRECISION-JET-TAU-Delta"], precisions["PRECISION-JET-TAU-Math"]);
0822     parseDeltaPhi_Cos_LUTS(
0823         scaleMap, "JET", "ETM", precisions["PRECISION-JET-ETM-Delta"], precisions["PRECISION-JET-ETM-Math"]);
0824     parseDeltaPhi_Cos_LUTS(
0825         scaleMap, "JET", "ETMHF", precisions["PRECISION-JET-ETMHF-Delta"], precisions["PRECISION-JET-ETMHF-Math"]);
0826     parseDeltaPhi_Cos_LUTS(
0827         scaleMap, "JET", "HTMHF", precisions["PRECISION-JET-HTMHF-Delta"], precisions["PRECISION-JET-HTMHF-Math"]);
0828     parseDeltaPhi_Cos_LUTS(
0829         scaleMap, "JET", "HTM", precisions["PRECISION-JET-HTM-Delta"], precisions["PRECISION-JET-HTM-Math"]);
0830     parseDeltaPhi_Cos_LUTS(
0831         scaleMap, "JET", "MU", precisions["PRECISION-JET-MU-Delta"], precisions["PRECISION-JET-MU-Math"]);
0832 
0833     parseDeltaPhi_Cos_LUTS(
0834         scaleMap, "TAU", "TAU", precisions["PRECISION-TAU-TAU-Delta"], precisions["PRECISION-TAU-TAU-Math"]);
0835     parseDeltaPhi_Cos_LUTS(
0836         scaleMap, "TAU", "ETM", precisions["PRECISION-TAU-ETM-Delta"], precisions["PRECISION-TAU-ETM-Math"]);
0837     parseDeltaPhi_Cos_LUTS(
0838         scaleMap, "TAU", "ETMHF", precisions["PRECISION-TAU-ETMHF-Delta"], precisions["PRECISION-TAU-ETMHF-Math"]);
0839     parseDeltaPhi_Cos_LUTS(
0840         scaleMap, "TAU", "HTMHF", precisions["PRECISION-TAU-HTMHF-Delta"], precisions["PRECISION-TAU-HTMHF-Math"]);
0841     parseDeltaPhi_Cos_LUTS(
0842         scaleMap, "TAU", "HTM", precisions["PRECISION-TAU-HTM-Delta"], precisions["PRECISION-TAU-HTM-Math"]);
0843     parseDeltaPhi_Cos_LUTS(
0844         scaleMap, "TAU", "MU", precisions["PRECISION-TAU-MU-Delta"], precisions["PRECISION-TAU-MU-Math"]);
0845 
0846     parseDeltaPhi_Cos_LUTS(
0847         scaleMap, "MU", "ETM", precisions["PRECISION-MU-ETM-Delta"], precisions["PRECISION-MU-ETM-Math"]);
0848     parseDeltaPhi_Cos_LUTS(
0849         scaleMap, "MU", "ETMHF", precisions["PRECISION-MU-ETMHF-Delta"], precisions["PRECISION-MU-ETMHF-Math"]);
0850     parseDeltaPhi_Cos_LUTS(
0851         scaleMap, "MU", "HTMHF", precisions["PRECISION-MU-HTMHF-Delta"], precisions["PRECISION-MU-HTMHF-Math"]);
0852     parseDeltaPhi_Cos_LUTS(
0853         scaleMap, "MU", "HTM", precisions["PRECISION-MU-HTM-Delta"], precisions["PRECISION-MU-HTM-Math"]);
0854     parseDeltaPhi_Cos_LUTS(
0855         scaleMap, "MU", "MU", precisions["PRECISION-MU-MU-Delta"], precisions["PRECISION-MU-MU-Math"]);
0856 
0857     parsePhi_Trig_LUTS(scaleMap, "EG", l1t::COS, precisions["PRECISION-EG-EG-Math"]);
0858     parsePhi_Trig_LUTS(scaleMap, "JET", l1t::COS, precisions["PRECISION-JET-JET-Math"]);
0859     parsePhi_Trig_LUTS(scaleMap, "TAU", l1t::COS, precisions["PRECISION-TAU-TAU-Math"]);
0860     parsePhi_Trig_LUTS(scaleMap, "MU", l1t::COS, precisions["PRECISION-MU-MU-Math"]);
0861 
0862     parsePhi_Trig_LUTS(scaleMap, "EG", l1t::SIN, precisions["PRECISION-EG-EG-Math"]);
0863     parsePhi_Trig_LUTS(scaleMap, "JET", l1t::SIN, precisions["PRECISION-JET-JET-Math"]);
0864     parsePhi_Trig_LUTS(scaleMap, "TAU", l1t::SIN, precisions["PRECISION-TAU-TAU-Math"]);
0865     parsePhi_Trig_LUTS(scaleMap, "MU", l1t::SIN, precisions["PRECISION-MU-MU-Math"]);
0866 
0867     //CCLA
0868     //m_gtScales.dumpAllLUTs(std::cout);
0869     //m_gtScales.print(std::cout);
0870   }
0871 
0872   return true;
0873 }
0874 
0875 void l1t::TriggerMenuParser::parseCalMuEta_LUTS(std::map<std::string, tmeventsetup::esScale> scaleMap,
0876                                                 std::string obj1,
0877                                                 std::string obj2) {
0878   using namespace tmeventsetup;
0879 
0880   // First Delta Eta for this set
0881   std::string scLabel1 = obj1;
0882   scLabel1 += "-ETA";
0883   std::string scLabel2 = obj2;
0884   scLabel2 += "-ETA";
0885 
0886   //This LUT does not exist in L1 Menu file, don't fill it
0887   if (scaleMap.find(scLabel1) == scaleMap.end() || scaleMap.find(scLabel2) == scaleMap.end())
0888     return;
0889 
0890   const tmeventsetup::esScale* scale1 = &scaleMap.find(scLabel1)->second;
0891   const tmeventsetup::esScale* scale2 = &scaleMap.find(scLabel2)->second;
0892 
0893   std::vector<long long> lut_cal_2_mu_eta;
0894   getCaloMuonEtaConversionLut(lut_cal_2_mu_eta, scale1, scale2);
0895 
0896   std::string lutName = obj1;
0897   lutName += "-";
0898   lutName += obj2;
0899   m_gtScales.setLUT_CalMuEta(lutName, lut_cal_2_mu_eta);
0900 }
0901 
0902 void l1t::TriggerMenuParser::parseCalMuPhi_LUTS(std::map<std::string, tmeventsetup::esScale> scaleMap,
0903                                                 std::string obj1,
0904                                                 std::string obj2) {
0905   using namespace tmeventsetup;
0906 
0907   // First Delta Eta for this set
0908   std::string scLabel1 = obj1;
0909   scLabel1 += "-PHI";
0910   std::string scLabel2 = obj2;
0911   scLabel2 += "-PHI";
0912 
0913   //This LUT does not exist in L1 Menu file, don't fill it
0914   if (scaleMap.find(scLabel1) == scaleMap.end() || scaleMap.find(scLabel2) == scaleMap.end())
0915     return;
0916 
0917   const tmeventsetup::esScale* scale1 = &scaleMap.find(scLabel1)->second;
0918   const tmeventsetup::esScale* scale2 = &scaleMap.find(scLabel2)->second;
0919 
0920   std::vector<long long> lut_cal_2_mu_phi;
0921   getCaloMuonPhiConversionLut(lut_cal_2_mu_phi, scale1, scale2);
0922 
0923   std::string lutName = obj1;
0924   lutName += "-";
0925   lutName += obj2;
0926   m_gtScales.setLUT_CalMuPhi(lutName, lut_cal_2_mu_phi);
0927 }
0928 
0929 void l1t::TriggerMenuParser::parsePt_LUTS(std::map<std::string, tmeventsetup::esScale> scaleMap,
0930                                           std::string lutpfx,
0931                                           std::string obj1,
0932                                           unsigned int prec) {
0933   using namespace tmeventsetup;
0934 
0935   // First Delta Eta for this set
0936   std::string scLabel1 = obj1;
0937   scLabel1 += "-ET";
0938 
0939   //This LUT does not exist in L1 Menu file, don't fill it
0940   if (scaleMap.find(scLabel1) == scaleMap.end())
0941     return;
0942 
0943   const tmeventsetup::esScale* scale1 = &scaleMap.find(scLabel1)->second;
0944 
0945   std::vector<long long> lut_pt;
0946   getLut(lut_pt, scale1, prec);
0947 
0948   m_gtScales.setLUT_Pt(lutpfx + "_" + scLabel1, lut_pt, prec);
0949 }
0950 
0951 // Added for displaced muons
0952 void l1t::TriggerMenuParser::parseUpt_LUTS(std::map<std::string, tmeventsetup::esScale> scaleMap,
0953                                            std::string lutpfx,
0954                                            std::string obj1,
0955                                            unsigned int prec) {
0956   using namespace tmeventsetup;
0957 
0958   // First Delta Eta for this set
0959   std::string scLabel1 = obj1;
0960   scLabel1 += "-UPT";
0961 
0962   //This LUT does not exist in L1 Menu file, don't fill it
0963   if (scaleMap.find(scLabel1) == scaleMap.end())
0964     return;
0965 
0966   const tmeventsetup::esScale* scale1 = &scaleMap.find(scLabel1)->second;
0967 
0968   std::vector<long long> lut_pt;
0969   getLut(lut_pt, scale1, prec);
0970 
0971   m_gtScales.setLUT_Upt(lutpfx + "_" + scLabel1, lut_pt, prec);
0972 }
0973 
0974 void l1t::TriggerMenuParser::parseDeltaEta_Cosh_LUTS(std::map<std::string, tmeventsetup::esScale> scaleMap,
0975                                                      std::string obj1,
0976                                                      std::string obj2,
0977                                                      unsigned int prec1,
0978                                                      unsigned int prec2) {
0979   using namespace tmeventsetup;
0980 
0981   // First Delta Eta for this set
0982   std::string scLabel1 = obj1;
0983   scLabel1 += "-ETA";
0984   std::string scLabel2 = obj2;
0985   scLabel2 += "-ETA";
0986 
0987   //This LUT does not exist in L1 Menu file, don't fill it
0988   if (scaleMap.find(scLabel1) == scaleMap.end() || scaleMap.find(scLabel2) == scaleMap.end())
0989     return;
0990 
0991   const tmeventsetup::esScale* scale1 = &scaleMap.find(scLabel1)->second;
0992   const tmeventsetup::esScale* scale2 = &scaleMap.find(scLabel2)->second;
0993   std::vector<double> val_delta_eta;
0994   std::vector<long long> lut_delta_eta;
0995   size_t n = getDeltaVector(val_delta_eta, scale1, scale2);
0996   setLut(lut_delta_eta, val_delta_eta, prec1);
0997   std::string lutName = obj1;
0998   lutName += "-";
0999   lutName += obj2;
1000   m_gtScales.setLUT_DeltaEta(lutName, lut_delta_eta, prec1);
1001 
1002   // Second Get the Cosh for this delta Eta Set
1003   std::vector<long long> lut_cosh;
1004   applyCosh(val_delta_eta, n);
1005   setLut(lut_cosh, val_delta_eta, prec2);
1006   m_gtScales.setLUT_Cosh(lutName, lut_cosh, prec2);
1007 }
1008 
1009 void l1t::TriggerMenuParser::parseDeltaPhi_Cos_LUTS(const std::map<std::string, tmeventsetup::esScale>& scaleMap,
1010                                                     const std::string& obj1,
1011                                                     const std::string& obj2,
1012                                                     unsigned int prec1,
1013                                                     unsigned int prec2) {
1014   using namespace tmeventsetup;
1015 
1016   // First Delta phi for this set
1017   std::string scLabel1 = obj1;
1018   scLabel1 += "-PHI";
1019   std::string scLabel2 = obj2;
1020   scLabel2 += "-PHI";
1021 
1022   //This LUT does not exist in L1 Menu file, don't fill it
1023   if (scaleMap.find(scLabel1) == scaleMap.end() || scaleMap.find(scLabel2) == scaleMap.end())
1024     return;
1025 
1026   const tmeventsetup::esScale* scale1 = &scaleMap.find(scLabel1)->second;
1027   const tmeventsetup::esScale* scale2 = &scaleMap.find(scLabel2)->second;
1028   std::vector<double> val_delta_phi;
1029   std::vector<long long> lut_delta_phi;
1030   size_t n = getDeltaVector(val_delta_phi, scale1, scale2);
1031   setLut(lut_delta_phi, val_delta_phi, prec1);
1032   std::string lutName = obj1;
1033   lutName += "-";
1034   lutName += obj2;
1035   m_gtScales.setLUT_DeltaPhi(lutName, lut_delta_phi, prec1);
1036 
1037   // Second Get the Cosh for this delta phi Set
1038   std::vector<long long> lut_cos;
1039   applyCos(val_delta_phi, n);
1040   setLut(lut_cos, val_delta_phi, prec2);
1041   m_gtScales.setLUT_Cos(lutName, lut_cos, prec2);
1042 }
1043 
1044 void l1t::TriggerMenuParser::parsePhi_Trig_LUTS(const std::map<std::string, tmeventsetup::esScale>& scaleMap,
1045                                                 const std::string& obj,
1046                                                 l1t::TrigFunc_t func,
1047                                                 unsigned int prec) {
1048   using namespace tmeventsetup;
1049 
1050   std::string scLabel = obj;
1051   scLabel += "-PHI";
1052 
1053   //This LUT does not exist in L1 Menu file, don't fill it
1054   if (scaleMap.find(scLabel) == scaleMap.end())
1055     return;
1056   if (func != l1t::SIN and func != l1t::COS)
1057     return;
1058 
1059   const tmeventsetup::esScale* scale = &scaleMap.find(scLabel)->second;
1060 
1061   const double step = scale->getStep();
1062   const double range = scale->getMaximum() - scale->getMinimum();
1063   const size_t n = std::ceil(range / step);
1064   const size_t bitwidth = std::ceil(std::log10(n) / std::log10(2));
1065 
1066   std::vector<double> array(std::pow(2, bitwidth), 0);
1067 
1068   for (size_t ii = 0; ii < n; ii++) {
1069     array.at(ii) = step * ii;
1070   }
1071 
1072   const std::string& lutName = obj;
1073   std::vector<long long> lut;
1074   if (func == l1t::SIN) {
1075     applySin(array, n);
1076     setLut(lut, array, prec);
1077     m_gtScales.setLUT_Sin(lutName, lut, prec);
1078   } else if (func == l1t::COS) {
1079     applyCos(array, n);
1080     setLut(lut, array, prec);
1081     m_gtScales.setLUT_Cos(lutName, lut, prec);
1082   }
1083 }
1084 
1085 /**
1086  * parseMuon Parse a muon condition and insert an entry to the conditions map
1087  *
1088  * @param node The corresponding node.
1089  * @param name The name of the condition.
1090  * @param chipNr The number of the chip this condition is located.
1091  *
1092  * @return "true" if succeeded, "false" if an error occurred.
1093  *
1094  */
1095 
1096 bool l1t::TriggerMenuParser::parseMuon(L1TUtmCondition condMu, unsigned int chipNr, const bool corrFlag) {
1097   using namespace tmeventsetup;
1098   // get condition, particle name (must be muon) and type name
1099   std::string condition = "muon";
1100   std::string particle = "muon";  //l1t2string( condMu.objectType() );
1101   std::string type = l1t2string(condMu.getType());
1102   std::string name = l1t2string(condMu.getName());
1103   int nrObj = -1;
1104 
1105   GtConditionType cType = l1t::TypeNull;
1106 
1107   if (condMu.getType() == esConditionType::SingleMuon) {
1108     type = "1_s";
1109     cType = l1t::Type1s;
1110     nrObj = 1;
1111   } else if (condMu.getType() == esConditionType::DoubleMuon) {
1112     type = "2_s";
1113     cType = l1t::Type2s;
1114     nrObj = 2;
1115   } else if (condMu.getType() == esConditionType::TripleMuon) {
1116     type = "3";
1117     cType = l1t::Type3s;
1118     nrObj = 3;
1119   } else if (condMu.getType() == esConditionType::QuadMuon) {
1120     type = "4";
1121     cType = l1t::Type4s;
1122     nrObj = 4;
1123   } else {
1124     edm::LogError("TriggerMenuParser") << "Wrong type for muon-condition (" << type << ")" << std::endl;
1125     return false;
1126   }
1127 
1128   if (nrObj < 0) {
1129     edm::LogError("TriggerMenuParser") << "Unknown type for muon-condition (" << type << ")"
1130                                        << "\nCan not determine number of trigger objects. " << std::endl;
1131     return false;
1132   }
1133 
1134   LogDebug("TriggerMenuParser") << "\n ****************************************** "
1135                                 << "\n      parseMuon  "
1136                                 << "\n condition = " << condition << "\n particle  = " << particle
1137                                 << "\n type      = " << type << "\n name      = " << name << std::endl;
1138 
1139   //     // get values
1140 
1141   // temporary storage of the parameters
1142   std::vector<MuonTemplate::ObjectParameter> objParameter(nrObj);
1143 
1144   // Do we need this?
1145   MuonTemplate::CorrelationParameter corrParameter;
1146 
1147   // need at least two values for deltaPhi
1148   std::vector<uint64_t> tmpValues((nrObj > 2) ? nrObj : 2);
1149   tmpValues.reserve(nrObj);
1150 
1151   if (int(condMu.getObjects().size()) != nrObj) {
1152     edm::LogError("TriggerMenuParser") << " condMu objects: nrObj = " << nrObj
1153                                        << "condMu.getObjects().size() = " << condMu.getObjects().size() << std::endl;
1154     return false;
1155   }
1156 
1157   //  Look for cuts on the objects in the condition
1158   unsigned int chargeCorrelation = 1;
1159   const std::vector<L1TUtmCut>& cuts = condMu.getCuts();
1160   for (size_t jj = 0; jj < cuts.size(); jj++) {
1161     const L1TUtmCut& cut = cuts.at(jj);
1162     if (cut.getCutType() == esCutType::ChargeCorrelation) {
1163       if (cut.getData() == "ls")
1164         chargeCorrelation = 2;
1165       else if (cut.getData() == "os")
1166         chargeCorrelation = 4;
1167       else
1168         chargeCorrelation = 1;  //ignore correlation
1169     }
1170   }
1171 
1172   //set charge correlation parameter
1173   corrParameter.chargeCorrelation = chargeCorrelation;  //tmpValues[0];
1174 
1175   int cnt = 0;
1176 
1177   // BLW TO DO: These needs to the added to the object rather than the whole condition.
1178   int relativeBx = 0;
1179   bool gEq = false;
1180 
1181   // Loop over objects and extract the cuts on the objects
1182   const std::vector<L1TUtmObject>& objects = condMu.getObjects();
1183   for (size_t jj = 0; jj < objects.size(); jj++) {
1184     const L1TUtmObject& object = objects.at(jj);
1185     gEq = (object.getComparisonOperator() == esComparisonOperator::GE);
1186 
1187     //  BLW TO DO: This needs to be added to the Object Parameters
1188     relativeBx = object.getBxOffset();
1189 
1190     //  Loop over the cuts for this object
1191     int upperUnconstrainedPtInd = -1;
1192     int lowerUnconstrainedPtInd = 0;
1193     int upperImpactParameterInd = -1;
1194     int lowerImpactParameterInd = 0;
1195     int upperThresholdInd = -1;
1196     int lowerThresholdInd = 0;
1197     int upperIndexInd = -1;
1198     int lowerIndexInd = 0;
1199     int cntPhi = 0;
1200     unsigned int phiWindow1Lower = -1, phiWindow1Upper = -1, phiWindow2Lower = -1, phiWindow2Upper = -1;
1201     int isolationLUT = 0xF;        //default is to ignore unless specified.
1202     int impactParameterLUT = 0xF;  //default is to ignore unless specified
1203     int charge = -1;               //default value is to ignore unless specified
1204     int qualityLUT = 0xFFFF;       //default is to ignore unless specified.
1205 
1206     std::vector<MuonTemplate::Window> etaWindows;
1207     std::vector<MuonTemplate::Window> tfMuonIndexWindows;
1208 
1209     const std::vector<L1TUtmCut>& cuts = object.getCuts();
1210     for (size_t kk = 0; kk < cuts.size(); kk++) {
1211       const L1TUtmCut& cut = cuts.at(kk);
1212 
1213       switch (cut.getCutType()) {
1214         case esCutType::UnconstrainedPt:
1215           lowerUnconstrainedPtInd = cut.getMinimum().index;
1216           upperUnconstrainedPtInd = cut.getMaximum().index;
1217           break;
1218 
1219         case esCutType::ImpactParameter:
1220           lowerImpactParameterInd = cut.getMinimum().index;
1221           upperImpactParameterInd = cut.getMaximum().index;
1222           impactParameterLUT = l1tstr2int(cut.getData());
1223           break;
1224 
1225         case esCutType::Threshold:
1226           lowerThresholdInd = cut.getMinimum().index;
1227           upperThresholdInd = cut.getMaximum().index;
1228           break;
1229 
1230         case esCutType::Slice:
1231           lowerIndexInd = int(cut.getMinimum().value);
1232           upperIndexInd = int(cut.getMaximum().value);
1233           break;
1234 
1235         case esCutType::Eta: {
1236           if (etaWindows.size() < 5) {
1237             if ((cut.getMinimum().index <= cut.getMaximum().index) ^
1238                 ((cut.getMinimum().index <= 255) ^ (cut.getMaximum().index <= 255))) {
1239               etaWindows.push_back({cut.getMinimum().index, cut.getMaximum().index});
1240             } else {
1241               edm::LogError("TriggerMenuParser")
1242                   << "Invalid Eta Window for muon-condition (" << name << ")" << std::endl;
1243             }
1244           } else {
1245             edm::LogError("TriggerMenuParser")
1246                 << "Too Many Eta Cuts for muon-condition (" << particle << ")" << std::endl;
1247             return false;
1248           }
1249         } break;
1250 
1251         case esCutType::Phi: {
1252           if (cntPhi == 0) {
1253             phiWindow1Lower = cut.getMinimum().index;
1254             phiWindow1Upper = cut.getMaximum().index;
1255           } else if (cntPhi == 1) {
1256             phiWindow2Lower = cut.getMinimum().index;
1257             phiWindow2Upper = cut.getMaximum().index;
1258           } else {
1259             edm::LogError("TriggerMenuParser")
1260                 << "Too Many Phi Cuts for muon-condition (" << particle << ")" << std::endl;
1261             return false;
1262           }
1263           cntPhi++;
1264 
1265         } break;
1266 
1267         case esCutType::Charge:
1268           if (cut.getData() == "positive")
1269             charge = 0;
1270           else if (cut.getData() == "negative")
1271             charge = 1;
1272           else
1273             charge = -1;
1274           break;
1275         case esCutType::Quality:
1276 
1277           qualityLUT = l1tstr2int(cut.getData());
1278 
1279           break;
1280         case esCutType::Isolation: {
1281           isolationLUT = l1tstr2int(cut.getData());
1282 
1283         } break;
1284 
1285         case esCutType::Index: {
1286           tfMuonIndexWindows.push_back({cut.getMinimum().index, cut.getMaximum().index});
1287         } break;
1288 
1289         default:
1290           break;
1291       }  //end switch
1292 
1293     }  //end loop over cuts
1294 
1295     // Set the parameter cuts
1296     objParameter[cnt].unconstrainedPtHigh = upperUnconstrainedPtInd;
1297     objParameter[cnt].unconstrainedPtLow = lowerUnconstrainedPtInd;
1298     objParameter[cnt].impactParameterHigh = upperImpactParameterInd;
1299     objParameter[cnt].impactParameterLow = lowerImpactParameterInd;
1300     objParameter[cnt].impactParameterLUT = impactParameterLUT;
1301 
1302     objParameter[cnt].ptHighThreshold = upperThresholdInd;
1303     objParameter[cnt].ptLowThreshold = lowerThresholdInd;
1304 
1305     objParameter[cnt].indexHigh = upperIndexInd;
1306     objParameter[cnt].indexLow = lowerIndexInd;
1307 
1308     objParameter[cnt].etaWindows = etaWindows;
1309 
1310     objParameter[cnt].phiWindow1Lower = phiWindow1Lower;
1311     objParameter[cnt].phiWindow1Upper = phiWindow1Upper;
1312     objParameter[cnt].phiWindow2Lower = phiWindow2Lower;
1313     objParameter[cnt].phiWindow2Upper = phiWindow2Upper;
1314 
1315     // BLW TO DO: Do we need these anymore?  Drop them?
1316     objParameter[cnt].enableMip = false;   //tmpMip[i];
1317     objParameter[cnt].enableIso = false;   //tmpEnableIso[i];
1318     objParameter[cnt].requestIso = false;  //tmpRequestIso[i];
1319 
1320     objParameter[cnt].charge = charge;
1321     objParameter[cnt].qualityLUT = qualityLUT;
1322     objParameter[cnt].isolationLUT = isolationLUT;
1323 
1324     objParameter[cnt].tfMuonIndexWindows = tfMuonIndexWindows;
1325 
1326     cnt++;
1327   }  //end loop over objects
1328 
1329   // object types - all muons
1330   std::vector<GlobalObject> objType(nrObj, gtMu);
1331 
1332   // now create a new CondMuonition
1333   MuonTemplate muonCond(name);
1334 
1335   muonCond.setCondType(cType);
1336   muonCond.setObjectType(objType);
1337   muonCond.setCondGEq(gEq);
1338   muonCond.setCondChipNr(chipNr);
1339   muonCond.setCondRelativeBx(relativeBx);
1340 
1341   muonCond.setConditionParameter(objParameter, corrParameter);
1342 
1343   if (edm::isDebugEnabled()) {
1344     std::ostringstream myCoutStream;
1345     muonCond.print(myCoutStream);
1346     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
1347   }
1348 
1349   // insert condition into the map and into muon template vector
1350   if (!insertConditionIntoMap(muonCond, chipNr)) {
1351     edm::LogError("TriggerMenuParser") << "    Error: duplicate condition (" << name << ")" << std::endl;
1352     return false;
1353   } else {
1354     LogDebug("TriggerMenuParser") << "Added Condition " << name << " to the ConditionMap" << std::endl;
1355     if (corrFlag) {
1356       (m_corMuonTemplate[chipNr]).push_back(muonCond);
1357     } else {
1358       LogDebug("TriggerMenuParser") << "Added Condition " << name << " to the vecMuonTemplate vector" << std::endl;
1359       (m_vecMuonTemplate[chipNr]).push_back(muonCond);
1360     }
1361   }
1362 
1363   //
1364   return true;
1365 }
1366 
1367 bool l1t::TriggerMenuParser::parseMuonCorr(const L1TUtmObject* corrMu, unsigned int chipNr) {
1368   //    XERCES_CPP_NAMESPACE_USE
1369   using namespace tmeventsetup;
1370 
1371   // get condition, particle name (must be muon) and type name
1372   std::string condition = "muon";
1373   std::string particle = "muon";  //l1t2string( condMu.objectType() );
1374   std::string type = l1t2string(corrMu->getType());
1375   std::string name = l1t2string(corrMu->getName());
1376   int nrObj = 1;
1377   type = "1_s";
1378   GtConditionType cType = l1t::Type1s;
1379 
1380   if (nrObj < 0) {
1381     edm::LogError("TriggerMenuParser") << "Unknown type for muon-condition (" << type << ")"
1382                                        << "\nCan not determine number of trigger objects. " << std::endl;
1383     return false;
1384   }
1385 
1386   LogDebug("TriggerMenuParser") << "\n ****************************************** "
1387                                 << "\n      parseMuon  "
1388                                 << "\n condition = " << condition << "\n particle  = " << particle
1389                                 << "\n type      = " << type << "\n name      = " << name << std::endl;
1390 
1391   //     // get values
1392 
1393   // temporary storage of the parameters
1394   std::vector<MuonTemplate::ObjectParameter> objParameter(nrObj);
1395 
1396   // Do we need this?
1397   MuonTemplate::CorrelationParameter corrParameter;
1398 
1399   // need at least two values for deltaPhi
1400   std::vector<uint64_t> tmpValues((nrObj > 2) ? nrObj : 2);
1401   tmpValues.reserve(nrObj);
1402 
1403   // BLW TO DO: How do we deal with these in the new format
1404   //    std::string str_chargeCorrelation = l1t2string( condMu.requestedChargeCorr() );
1405   std::string str_chargeCorrelation = "ig";
1406   unsigned int chargeCorrelation = 0;
1407   if (str_chargeCorrelation == "ig")
1408     chargeCorrelation = 1;
1409   else if (str_chargeCorrelation == "ls")
1410     chargeCorrelation = 2;
1411   else if (str_chargeCorrelation == "os")
1412     chargeCorrelation = 4;
1413 
1414   //getXMLHexTextValue("1", dst);
1415   corrParameter.chargeCorrelation = chargeCorrelation;  //tmpValues[0];
1416 
1417   // BLW TO DO: These needs to the added to the object rather than the whole condition.
1418   int relativeBx = 0;
1419   bool gEq = false;
1420 
1421   //const esObject* object = condMu;
1422   gEq = (corrMu->getComparisonOperator() == esComparisonOperator::GE);
1423 
1424   //  BLW TO DO: This needs to be added to the Object Parameters
1425   relativeBx = corrMu->getBxOffset();
1426 
1427   //  Loop over the cuts for this object
1428   int upperUnconstrainedPtInd = -1;  // Added for displaced muons
1429   int lowerUnconstrainedPtInd = 0;   // Added for displaced muons
1430   int upperImpactParameterInd = -1;  // Added for displaced muons
1431   int lowerImpactParameterInd = 0;   // Added for displaced muons
1432   int impactParameterLUT = 0xF;      // Added for displaced muons, default is to ignore unless specified
1433   int upperThresholdInd = -1;
1434   int lowerThresholdInd = 0;
1435   int upperIndexInd = -1;
1436   int lowerIndexInd = 0;
1437   int cntPhi = 0;
1438   unsigned int phiWindow1Lower = -1, phiWindow1Upper = -1, phiWindow2Lower = -1, phiWindow2Upper = -1;
1439   int isolationLUT = 0xF;   //default is to ignore unless specified.
1440   int charge = -1;          //defaut is to ignore unless specified
1441   int qualityLUT = 0xFFFF;  //default is to ignore unless specified.
1442 
1443   std::vector<MuonTemplate::Window> etaWindows;
1444   std::vector<MuonTemplate::Window> tfMuonIndexWindows;
1445 
1446   const std::vector<L1TUtmCut>& cuts = corrMu->getCuts();
1447   for (size_t kk = 0; kk < cuts.size(); kk++) {
1448     const L1TUtmCut& cut = cuts.at(kk);
1449 
1450     switch (cut.getCutType()) {
1451       case esCutType::UnconstrainedPt:  // Added for displaced muons
1452         lowerUnconstrainedPtInd = cut.getMinimum().index;
1453         upperUnconstrainedPtInd = cut.getMaximum().index;
1454         break;
1455 
1456       case esCutType::ImpactParameter:  // Added for displaced muons
1457         lowerImpactParameterInd = cut.getMinimum().index;
1458         upperImpactParameterInd = cut.getMaximum().index;
1459         impactParameterLUT = l1tstr2int(cut.getData());
1460         break;
1461 
1462       case esCutType::Threshold:
1463         lowerThresholdInd = cut.getMinimum().index;
1464         upperThresholdInd = cut.getMaximum().index;
1465         break;
1466 
1467       case esCutType::Slice:
1468         lowerIndexInd = int(cut.getMinimum().value);
1469         upperIndexInd = int(cut.getMaximum().value);
1470         break;
1471 
1472       case esCutType::Eta: {
1473         if (etaWindows.size() < 5) {
1474           if ((cut.getMinimum().index <= cut.getMaximum().index) ^
1475               ((cut.getMinimum().index <= 255) ^ (cut.getMaximum().index <= 255))) {
1476             etaWindows.push_back({cut.getMinimum().index, cut.getMaximum().index});
1477           } else {
1478             edm::LogError("TriggerMenuParser") << "Invalid Eta Window for muon-condition (" << name << ")" << std::endl;
1479           }
1480         } else {
1481           edm::LogError("TriggerMenuParser")
1482               << "Too Many Eta Cuts for muon-condition (" << particle << ")" << std::endl;
1483           return false;
1484         }
1485       } break;
1486 
1487       case esCutType::Phi: {
1488         if (cntPhi == 0) {
1489           phiWindow1Lower = cut.getMinimum().index;
1490           phiWindow1Upper = cut.getMaximum().index;
1491         } else if (cntPhi == 1) {
1492           phiWindow2Lower = cut.getMinimum().index;
1493           phiWindow2Upper = cut.getMaximum().index;
1494         } else {
1495           edm::LogError("TriggerMenuParser")
1496               << "Too Many Phi Cuts for muon-condition (" << particle << ")" << std::endl;
1497           return false;
1498         }
1499         cntPhi++;
1500 
1501       } break;
1502 
1503       case esCutType::Charge:
1504         if (cut.getData() == "positive")
1505           charge = 0;
1506         else if (cut.getData() == "negative")
1507           charge = 1;
1508         else
1509           charge = -1;
1510         break;
1511       case esCutType::Quality:
1512 
1513         qualityLUT = l1tstr2int(cut.getData());
1514 
1515         break;
1516       case esCutType::Isolation: {
1517         isolationLUT = l1tstr2int(cut.getData());
1518 
1519       } break;
1520 
1521       case esCutType::Index: {
1522         tfMuonIndexWindows.push_back({cut.getMinimum().index, cut.getMaximum().index});
1523       } break;
1524 
1525       default:
1526         break;
1527     }  //end switch
1528 
1529   }  //end loop over cuts
1530 
1531   // Set the parameter cuts
1532   objParameter[0].unconstrainedPtHigh = upperUnconstrainedPtInd;  // Added for displacd muons
1533   objParameter[0].unconstrainedPtLow = lowerUnconstrainedPtInd;   // Added for displacd muons
1534   objParameter[0].impactParameterHigh = upperImpactParameterInd;  // Added for displacd muons
1535   objParameter[0].impactParameterLow = lowerImpactParameterInd;   // Added for displacd muons
1536   objParameter[0].impactParameterLUT = impactParameterLUT;        // Added for displacd muons
1537 
1538   objParameter[0].ptHighThreshold = upperThresholdInd;
1539   objParameter[0].ptLowThreshold = lowerThresholdInd;
1540 
1541   objParameter[0].indexHigh = upperIndexInd;
1542   objParameter[0].indexLow = lowerIndexInd;
1543 
1544   objParameter[0].etaWindows = etaWindows;
1545 
1546   objParameter[0].phiWindow1Lower = phiWindow1Lower;
1547   objParameter[0].phiWindow1Upper = phiWindow1Upper;
1548   objParameter[0].phiWindow2Lower = phiWindow2Lower;
1549   objParameter[0].phiWindow2Upper = phiWindow2Upper;
1550 
1551   // BLW TO DO: Do we need these anymore?  Drop them?
1552   objParameter[0].enableMip = false;   //tmpMip[i];
1553   objParameter[0].enableIso = false;   //tmpEnableIso[i];
1554   objParameter[0].requestIso = false;  //tmpRequestIso[i];
1555 
1556   objParameter[0].charge = charge;
1557   objParameter[0].qualityLUT = qualityLUT;
1558   objParameter[0].isolationLUT = isolationLUT;
1559 
1560   objParameter[0].tfMuonIndexWindows = tfMuonIndexWindows;
1561 
1562   // object types - all muons
1563   std::vector<GlobalObject> objType(nrObj, gtMu);
1564 
1565   // now create a new CondMuonition
1566   MuonTemplate muonCond(name);
1567 
1568   muonCond.setCondType(cType);
1569   muonCond.setObjectType(objType);
1570   muonCond.setCondGEq(gEq);
1571   muonCond.setCondChipNr(chipNr);
1572   muonCond.setCondRelativeBx(relativeBx);
1573   muonCond.setConditionParameter(objParameter, corrParameter);
1574 
1575   if (edm::isDebugEnabled()) {
1576     std::ostringstream myCoutStream;
1577     muonCond.print(myCoutStream);
1578     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
1579   }
1580 
1581   /*
1582     // insert condition into the map and into muon template vector
1583     if ( !insertConditionIntoMap(muonCond, chipNr)) {
1584         edm::LogError("TriggerMenuParser")
1585                 << "    Error: duplicate condition (" << name << ")"
1586                 << std::endl;
1587         return false;
1588     }
1589     else {
1590         LogDebug("TriggerMenuParser") << "Added Condition " << name << " to the ConditionMap" << std::endl;
1591             (m_corMuonTemplate[chipNr]).push_back(muonCond);
1592     }
1593 */
1594   (m_corMuonTemplate[chipNr]).push_back(muonCond);
1595 
1596   //
1597   return true;
1598 }
1599 
1600 /**
1601  * parseMuonShower Parse a muonShower condition and insert an entry to the conditions map
1602  *
1603  * @param node The corresponding node.
1604  * @param name The name of the condition.
1605  * @param chipNr The number of the chip this condition is located.
1606  *
1607  * @return "true" if succeeded, "false" if an error occurred.
1608  *
1609  */
1610 
1611 bool l1t::TriggerMenuParser::parseMuonShower(L1TUtmCondition condMu, unsigned int chipNr, const bool corrFlag) {
1612   using namespace tmeventsetup;
1613 
1614   // get condition, particle name (must be muon) and type name
1615   std::string condition = "muonShower";
1616   std::string particle = "muonShower";  //l1t2string( condMu.objectType() );
1617   std::string type = l1t2string(condMu.getType());
1618   std::string name = l1t2string(condMu.getName());
1619   // the number of muon shower objects is always 1
1620   int nrObj = 1;
1621 
1622   // condition type is always 1 particle, thus Type1s
1623   GtConditionType cType = l1t::Type1s;
1624 
1625   // temporary storage of the parameters
1626   std::vector<MuonShowerTemplate::ObjectParameter> objParameter(nrObj);
1627 
1628   if (int(condMu.getObjects().size()) != nrObj) {
1629     edm::LogError("TriggerMenuParser") << " condMu objects: nrObj = " << nrObj
1630                                        << "condMu.getObjects().size() = " << condMu.getObjects().size() << std::endl;
1631     return false;
1632   }
1633 
1634   // Get the muon shower object
1635   L1TUtmObject object = condMu.getObjects().at(0);
1636   int relativeBx = object.getBxOffset();
1637 
1638   if (condMu.getType() == esConditionType::MuonShower0) {
1639     objParameter[0].MuonShower0 = true;
1640   } else if (condMu.getType() == esConditionType::MuonShower1) {
1641     objParameter[0].MuonShower1 = true;
1642   } else if (condMu.getType() == esConditionType::MuonShower2) {
1643     objParameter[0].MuonShower2 = true;
1644   } else if (condMu.getType() == esConditionType::MuonShowerOutOfTime0) {
1645     objParameter[0].MuonShowerOutOfTime0 = true;
1646   } else if (condMu.getType() == esConditionType::MuonShowerOutOfTime1) {
1647     objParameter[0].MuonShowerOutOfTime1 = true;
1648   }
1649 
1650   // object types - all muons
1651   std::vector<GlobalObject> objType(nrObj, gtMuShower);
1652 
1653   // now create a new CondMuonition
1654   MuonShowerTemplate muonShowerCond(name);
1655   muonShowerCond.setCondType(cType);
1656   muonShowerCond.setObjectType(objType);
1657   muonShowerCond.setCondChipNr(chipNr);
1658   muonShowerCond.setCondRelativeBx(relativeBx);
1659 
1660   muonShowerCond.setConditionParameter(objParameter);
1661 
1662   if (edm::isDebugEnabled()) {
1663     std::ostringstream myCoutStream;
1664     muonShowerCond.print(myCoutStream);
1665   }
1666 
1667   // insert condition into the map and into muon template vector
1668   if (!insertConditionIntoMap(muonShowerCond, chipNr)) {
1669     edm::LogError("TriggerMenuParser") << "    Error: duplicate condition (" << name << ")" << std::endl;
1670     return false;
1671   } else {
1672     (m_vecMuonShowerTemplate[chipNr]).push_back(muonShowerCond);
1673   }
1674 
1675   return true;
1676 }
1677 
1678 /**
1679  * parseCalo Parse a calo condition and insert an entry to the conditions map
1680  *
1681  * @param node The corresponding node.
1682  * @param name The name of the condition.
1683  * @param chipNr The number of the chip this condition is located.
1684  *
1685  * @return "true" if succeeded, "false" if an error occurred.
1686  *
1687  */
1688 
1689 bool l1t::TriggerMenuParser::parseCalo(L1TUtmCondition condCalo, unsigned int chipNr, const bool corrFlag) {
1690   //    XERCES_CPP_NAMESPACE_USE
1691   using namespace tmeventsetup;
1692 
1693   // get condition, particle name and type name
1694 
1695   std::string condition = "calo";
1696   std::string particle = "test-fix";
1697   std::string type = l1t2string(condCalo.getType());
1698   std::string name = l1t2string(condCalo.getName());
1699 
1700   LogDebug("TriggerMenuParser") << "\n ****************************************** "
1701                                 << "\n      (in parseCalo) "
1702                                 << "\n condition = " << condition << "\n particle  = " << particle
1703                                 << "\n type      = " << type << "\n name      = " << name << std::endl;
1704 
1705   GtConditionType cType = l1t::TypeNull;
1706 
1707   // determine object type type
1708   // BLW TO DO:  Can this object type wait and be done later in the parsing. Or done differently completely..
1709   GlobalObject caloObjType;
1710   int nrObj = -1;
1711 
1712   if (condCalo.getType() == esConditionType::SingleEgamma) {
1713     caloObjType = gtEG;
1714     type = "1_s";
1715     cType = l1t::Type1s;
1716     nrObj = 1;
1717   } else if (condCalo.getType() == esConditionType::DoubleEgamma) {
1718     caloObjType = gtEG;
1719     type = "2_s";
1720     cType = l1t::Type2s;
1721     nrObj = 2;
1722   } else if (condCalo.getType() == esConditionType::TripleEgamma) {
1723     caloObjType = gtEG;
1724     cType = l1t::Type3s;
1725     type = "3";
1726     nrObj = 3;
1727   } else if (condCalo.getType() == esConditionType::QuadEgamma) {
1728     caloObjType = gtEG;
1729     cType = l1t::Type4s;
1730     type = "4";
1731     nrObj = 4;
1732   } else if (condCalo.getType() == esConditionType::SingleJet) {
1733     caloObjType = gtJet;
1734     cType = l1t::Type1s;
1735     type = "1_s";
1736     nrObj = 1;
1737   } else if (condCalo.getType() == esConditionType::DoubleJet) {
1738     caloObjType = gtJet;
1739     cType = l1t::Type2s;
1740     type = "2_s";
1741     nrObj = 2;
1742   } else if (condCalo.getType() == esConditionType::TripleJet) {
1743     caloObjType = gtJet;
1744     cType = l1t::Type3s;
1745     type = "3";
1746     nrObj = 3;
1747   } else if (condCalo.getType() == esConditionType::QuadJet) {
1748     caloObjType = gtJet;
1749     cType = l1t::Type4s;
1750     type = "4";
1751     nrObj = 4;
1752   } else if (condCalo.getType() == esConditionType::SingleTau) {
1753     caloObjType = gtTau;
1754     cType = l1t::Type1s;
1755     type = "1_s";
1756     nrObj = 1;
1757   } else if (condCalo.getType() == esConditionType::DoubleTau) {
1758     caloObjType = gtTau;
1759     cType = l1t::Type2s;
1760     type = "2_s";
1761     nrObj = 2;
1762   } else if (condCalo.getType() == esConditionType::TripleTau) {
1763     caloObjType = gtTau;
1764     cType = l1t::Type3s;
1765     type = "3";
1766     nrObj = 3;
1767   } else if (condCalo.getType() == esConditionType::QuadTau) {
1768     caloObjType = gtTau;
1769     cType = l1t::Type4s;
1770     type = "4";
1771     nrObj = 4;
1772   } else {
1773     edm::LogError("TriggerMenuParser") << "Wrong particle for calo-condition (" << particle << ")" << std::endl;
1774     return false;
1775   }
1776 
1777   //    std::string str_etComparison = l1t2string( condCalo.comparison_operator() );
1778 
1779   if (nrObj < 0) {
1780     edm::LogError("TriggerMenuParser") << "Unknown type for calo-condition (" << type << ")"
1781                                        << "\nCan not determine number of trigger objects. " << std::endl;
1782     return false;
1783   }
1784 
1785   // get values
1786 
1787   // temporary storage of the parameters
1788   std::vector<CaloTemplate::ObjectParameter> objParameter(nrObj);
1789 
1790   //BLW TO DO:  Can this be dropped?
1791   CaloTemplate::CorrelationParameter corrParameter;
1792 
1793   // need at least one value for deltaPhiRange
1794   std::vector<uint64_t> tmpValues((nrObj > 1) ? nrObj : 1);
1795   tmpValues.reserve(nrObj);
1796 
1797   if (int(condCalo.getObjects().size()) != nrObj) {
1798     edm::LogError("TriggerMenuParser") << " condCalo objects: nrObj = " << nrObj
1799                                        << "condCalo.getObjects().size() = " << condCalo.getObjects().size()
1800                                        << std::endl;
1801     return false;
1802   }
1803 
1804   //    std::string str_condCalo = "";
1805   //    uint64_t tempUIntH, tempUIntL;
1806   //    uint64_t dst;
1807   int cnt = 0;
1808 
1809   // BLW TO DO: These needs to the added to the object rather than the whole condition.
1810   int relativeBx = 0;
1811   bool gEq = false;
1812 
1813   // Loop over objects and extract the cuts on the objects
1814   const std::vector<L1TUtmObject>& objects = condCalo.getObjects();
1815   for (size_t jj = 0; jj < objects.size(); jj++) {
1816     const L1TUtmObject& object = objects.at(jj);
1817     gEq = (object.getComparisonOperator() == esComparisonOperator::GE);
1818 
1819     //  BLW TO DO: This needs to be added to the Object Parameters
1820     relativeBx = object.getBxOffset();
1821 
1822     //  Loop over the cuts for this object
1823     int upperThresholdInd = -1;
1824     int lowerThresholdInd = 0;
1825     int upperIndexInd = -1;
1826     int lowerIndexInd = 0;
1827     int cntPhi = 0;
1828     unsigned int phiWindow1Lower = -1, phiWindow1Upper = -1, phiWindow2Lower = -1, phiWindow2Upper = -1;
1829     int isolationLUT = 0xF;  //default is to ignore isolation unless specified.
1830     int qualityLUT = 0xF;    //default is to ignore quality unless specified.
1831     int displacedLUT = 0x0;  // Added for LLP Jets: single bit LUT: { 0 = noLLP default, 1 = LLP }
1832                              // Note: Currently assumes that the LSB from hwQual() getter in L1Candidate provides the
1833                              // (single bit) information for the displacedLUT
1834 
1835     std::vector<CaloTemplate::Window> etaWindows;
1836 
1837     const std::vector<L1TUtmCut>& cuts = object.getCuts();
1838     for (size_t kk = 0; kk < cuts.size(); kk++) {
1839       const L1TUtmCut& cut = cuts.at(kk);
1840 
1841       switch (cut.getCutType()) {
1842         case esCutType::Threshold:
1843           lowerThresholdInd = cut.getMinimum().index;
1844           upperThresholdInd = cut.getMaximum().index;
1845           break;
1846         case esCutType::Slice:
1847           lowerIndexInd = int(cut.getMinimum().value);
1848           upperIndexInd = int(cut.getMaximum().value);
1849           break;
1850         case esCutType::Eta: {
1851           if (etaWindows.size() < 5) {
1852             if ((cut.getMinimum().index <= cut.getMaximum().index) ^
1853                 ((cut.getMinimum().index <= 127) ^ (cut.getMaximum().index <= 127))) {
1854               etaWindows.push_back({cut.getMinimum().index, cut.getMaximum().index});
1855             } else {
1856               edm::LogError("TriggerMenuParser")
1857                   << "Invalid Eta Window for calo-conditioni (" << name << ")" << std::endl;
1858             }
1859           } else {
1860             edm::LogError("TriggerMenuParser")
1861                 << "Too Many Eta Cuts for calo-condition (" << particle << ")" << std::endl;
1862             return false;
1863           }
1864         } break;
1865 
1866         case esCutType::Phi: {
1867           if (cntPhi == 0) {
1868             phiWindow1Lower = cut.getMinimum().index;
1869             phiWindow1Upper = cut.getMaximum().index;
1870           } else if (cntPhi == 1) {
1871             phiWindow2Lower = cut.getMinimum().index;
1872             phiWindow2Upper = cut.getMaximum().index;
1873           } else {
1874             edm::LogError("TriggerMenuParser")
1875                 << "Too Many Phi Cuts for calo-condition (" << particle << ")" << std::endl;
1876             return false;
1877           }
1878           cntPhi++;
1879 
1880         } break;
1881 
1882         case esCutType::Charge: {
1883           edm::LogError("TriggerMenuParser") << "No charge cut for calo-condition (" << particle << ")" << std::endl;
1884           return false;
1885 
1886         } break;
1887         case esCutType::Quality: {
1888           qualityLUT = l1tstr2int(cut.getData());
1889 
1890         } break;
1891         case esCutType::Displaced: {  // Added for LLP Jets
1892           displacedLUT = l1tstr2int(cut.getData());
1893 
1894         } break;
1895         case esCutType::Isolation: {
1896           isolationLUT = l1tstr2int(cut.getData());
1897 
1898         } break;
1899         default:
1900           break;
1901       }  //end switch
1902 
1903     }  //end loop over cuts
1904 
1905     // Fill the object parameters
1906     objParameter[cnt].etHighThreshold = upperThresholdInd;
1907     objParameter[cnt].etLowThreshold = lowerThresholdInd;
1908     objParameter[cnt].indexHigh = upperIndexInd;
1909     objParameter[cnt].indexLow = lowerIndexInd;
1910     objParameter[cnt].etaWindows = etaWindows;
1911     objParameter[cnt].phiWindow1Lower = phiWindow1Lower;
1912     objParameter[cnt].phiWindow1Upper = phiWindow1Upper;
1913     objParameter[cnt].phiWindow2Lower = phiWindow2Lower;
1914     objParameter[cnt].phiWindow2Upper = phiWindow2Upper;
1915     objParameter[cnt].isolationLUT = isolationLUT;
1916     objParameter[cnt].qualityLUT = qualityLUT;      //TO DO: Must add
1917     objParameter[cnt].displacedLUT = displacedLUT;  // Added for LLP Jets
1918 
1919     // Output for debugging
1920     {
1921       std::ostringstream oss;
1922       oss << "\n      Calo ET high thresholds (hex) for calo object " << caloObjType << " " << cnt << " = " << std::hex
1923           << objParameter[cnt].etLowThreshold << " - " << objParameter[cnt].etHighThreshold;
1924       for (const auto& window : objParameter[cnt].etaWindows) {
1925         oss << "\n      etaWindow Lower / Upper for calo object " << cnt << " = 0x" << window.lower << " / 0x"
1926             << window.upper;
1927       }
1928       oss << "\n      phiWindow Lower / Upper for calo object " << cnt << " = 0x" << objParameter[cnt].phiWindow1Lower
1929           << " / 0x" << objParameter[cnt].phiWindow1Upper << "\n      phiWindowVeto Lower / Upper for calo object "
1930           << cnt << " = 0x" << objParameter[cnt].phiWindow2Lower << " / 0x" << objParameter[cnt].phiWindow2Upper
1931           << "\n      Isolation LUT for calo object " << cnt << " = 0x" << objParameter[cnt].isolationLUT
1932           << "\n      Quality LUT for calo object " << cnt << " = 0x" << objParameter[cnt].qualityLUT
1933           << "\n      LLP DISP LUT for calo object " << cnt << " = 0x" << objParameter[cnt].displacedLUT;
1934       LogDebug("TriggerMenuParser") << oss.str() << std::endl;
1935     }
1936 
1937     cnt++;
1938   }  //end loop over objects
1939 
1940   // object types - all same caloObjType
1941   std::vector<GlobalObject> objType(nrObj, caloObjType);
1942 
1943   // now create a new calo condition
1944   CaloTemplate caloCond(name);
1945 
1946   caloCond.setCondType(cType);
1947   caloCond.setObjectType(objType);
1948 
1949   //BLW TO DO: This needs to be added to the object rather than the whole condition
1950   caloCond.setCondGEq(gEq);
1951   caloCond.setCondChipNr(chipNr);
1952 
1953   //BLW TO DO: This needs to be added to the object rather than the whole condition
1954   caloCond.setCondRelativeBx(relativeBx);
1955 
1956   caloCond.setConditionParameter(objParameter, corrParameter);
1957 
1958   if (edm::isDebugEnabled()) {
1959     std::ostringstream myCoutStream;
1960     caloCond.print(myCoutStream);
1961     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
1962   }
1963 
1964   // insert condition into the map
1965   if (!insertConditionIntoMap(caloCond, chipNr)) {
1966     edm::LogError("TriggerMenuParser") << "    Error: duplicate condition (" << name << ")" << std::endl;
1967 
1968     return false;
1969   } else {
1970     if (corrFlag) {
1971       (m_corCaloTemplate[chipNr]).push_back(caloCond);
1972     } else {
1973       (m_vecCaloTemplate[chipNr]).push_back(caloCond);
1974     }
1975   }
1976 
1977   //
1978   return true;
1979 }
1980 
1981 /**
1982  * parseCalo Parse a calo condition and insert an entry to the conditions map
1983  *
1984  * @param node The corresponding node.
1985  * @param name The name of the condition.
1986  * @param chipNr The number of the chip this condition is located.
1987  *
1988  * @return "true" if succeeded, "false" if an error occurred.
1989  *
1990  */
1991 
1992 bool l1t::TriggerMenuParser::parseCaloCorr(const L1TUtmObject* corrCalo, unsigned int chipNr) {
1993   //    XERCES_CPP_NAMESPACE_USE
1994   using namespace tmeventsetup;
1995 
1996   // get condition, particle name and type name
1997 
1998   std::string condition = "calo";
1999   std::string particle = "test-fix";
2000   std::string type = l1t2string(corrCalo->getType());
2001   std::string name = l1t2string(corrCalo->getName());
2002 
2003   LogDebug("TriggerMenuParser") << "\n ****************************************** "
2004                                 << "\n      (in parseCalo) "
2005                                 << "\n condition = " << condition << "\n particle  = " << particle
2006                                 << "\n type      = " << type << "\n name      = " << name << std::endl;
2007 
2008   // determine object type type
2009   // BLW TO DO:  Can this object type wait and be done later in the parsing. Or done differently completely..
2010   GlobalObject caloObjType;
2011   int nrObj = 1;
2012   type = "1_s";
2013   GtConditionType cType = l1t::Type1s;
2014 
2015   if (corrCalo->getType() == esObjectType::Egamma) {
2016     caloObjType = gtEG;
2017   } else if (corrCalo->getType() == esObjectType::Jet) {
2018     caloObjType = gtJet;
2019   } else if (corrCalo->getType() == esObjectType::Tau) {
2020     caloObjType = gtTau;
2021   } else {
2022     edm::LogError("TriggerMenuParser") << "Wrong particle for calo-condition (" << particle << ")" << std::endl;
2023     return false;
2024   }
2025 
2026   //    std::string str_etComparison = l1t2string( condCalo.comparison_operator() );
2027 
2028   if (nrObj < 0) {
2029     edm::LogError("TriggerMenuParser") << "Unknown type for calo-condition (" << type << ")"
2030                                        << "\nCan not determine number of trigger objects. " << std::endl;
2031     return false;
2032   }
2033 
2034   // get values
2035 
2036   // temporary storage of the parameters
2037   std::vector<CaloTemplate::ObjectParameter> objParameter(nrObj);
2038 
2039   //BLW TO DO:  Can this be dropped?
2040   CaloTemplate::CorrelationParameter corrParameter;
2041 
2042   // need at least one value for deltaPhiRange
2043   std::vector<uint64_t> tmpValues((nrObj > 1) ? nrObj : 1);
2044   tmpValues.reserve(nrObj);
2045 
2046   // BLW TO DO: These needs to the added to the object rather than the whole condition.
2047   int relativeBx = 0;
2048   bool gEq = false;
2049 
2050   gEq = (corrCalo->getComparisonOperator() == esComparisonOperator::GE);
2051 
2052   //  BLW TO DO: This needs to be added to the Object Parameters
2053   relativeBx = corrCalo->getBxOffset();
2054 
2055   //  Loop over the cuts for this object
2056   int upperThresholdInd = -1;
2057   int lowerThresholdInd = 0;
2058   int upperIndexInd = -1;
2059   int lowerIndexInd = 0;
2060   int cntPhi = 0;
2061   unsigned int phiWindow1Lower = -1, phiWindow1Upper = -1, phiWindow2Lower = -1, phiWindow2Upper = -1;
2062   int isolationLUT = 0xF;  //default is to ignore isolation unless specified.
2063   int qualityLUT = 0xF;    //default is to ignore quality unless specified.
2064   int displacedLUT = 0x0;  // Added for LLP Jets:  single bit LUT:  { 0 = noLLP default, 1 = LLP }
2065                            // Note:  Currently assume that the hwQual() getter in L1Candidate provides the
2066                            //        (single bit) information for the displacedLUT
2067 
2068   std::vector<CaloTemplate::Window> etaWindows;
2069 
2070   const std::vector<L1TUtmCut>& cuts = corrCalo->getCuts();
2071   for (size_t kk = 0; kk < cuts.size(); kk++) {
2072     const L1TUtmCut& cut = cuts.at(kk);
2073 
2074     switch (cut.getCutType()) {
2075       case esCutType::Threshold:
2076         lowerThresholdInd = cut.getMinimum().index;
2077         upperThresholdInd = cut.getMaximum().index;
2078         break;
2079       case esCutType::Slice:
2080         lowerIndexInd = int(cut.getMinimum().value);
2081         upperIndexInd = int(cut.getMaximum().value);
2082         break;
2083       case esCutType::Eta: {
2084         if (etaWindows.size() < 5) {
2085           if ((cut.getMinimum().index <= cut.getMaximum().index) ^
2086               ((cut.getMinimum().index <= 127) ^ (cut.getMaximum().index <= 127))) {
2087             etaWindows.push_back({cut.getMinimum().index, cut.getMaximum().index});
2088           } else {
2089             edm::LogError("TriggerMenuParser") << "Invalid Eta Window for calo-condition (" << name << ")" << std::endl;
2090           }
2091         } else {
2092           edm::LogError("TriggerMenuParser")
2093               << "Too Many Eta Cuts for calo-condition (" << particle << ")" << std::endl;
2094           return false;
2095         }
2096       } break;
2097 
2098       case esCutType::Phi: {
2099         if (cntPhi == 0) {
2100           phiWindow1Lower = cut.getMinimum().index;
2101           phiWindow1Upper = cut.getMaximum().index;
2102         } else if (cntPhi == 1) {
2103           phiWindow2Lower = cut.getMinimum().index;
2104           phiWindow2Upper = cut.getMaximum().index;
2105         } else {
2106           edm::LogError("TriggerMenuParser")
2107               << "Too Many Phi Cuts for calo-condition (" << particle << ")" << std::endl;
2108           return false;
2109         }
2110         cntPhi++;
2111 
2112       } break;
2113 
2114       case esCutType::Charge: {
2115         edm::LogError("TriggerMenuParser") << "No charge cut for calo-condition (" << particle << ")" << std::endl;
2116         return false;
2117 
2118       } break;
2119       case esCutType::Quality: {
2120         qualityLUT = l1tstr2int(cut.getData());
2121 
2122       } break;
2123       case esCutType::Displaced: {  // Added for LLP Jets
2124         displacedLUT = l1tstr2int(cut.getData());
2125 
2126       } break;
2127       case esCutType::Isolation: {
2128         isolationLUT = l1tstr2int(cut.getData());
2129 
2130       } break;
2131       default:
2132         break;
2133     }  //end switch
2134 
2135   }  //end loop over cuts
2136 
2137   // Fill the object parameters
2138   objParameter[0].etLowThreshold = lowerThresholdInd;
2139   objParameter[0].etHighThreshold = upperThresholdInd;
2140   objParameter[0].indexHigh = upperIndexInd;
2141   objParameter[0].indexLow = lowerIndexInd;
2142   objParameter[0].etaWindows = etaWindows;
2143   objParameter[0].phiWindow1Lower = phiWindow1Lower;
2144   objParameter[0].phiWindow1Upper = phiWindow1Upper;
2145   objParameter[0].phiWindow2Lower = phiWindow2Lower;
2146   objParameter[0].phiWindow2Upper = phiWindow2Upper;
2147   objParameter[0].isolationLUT = isolationLUT;
2148   objParameter[0].qualityLUT = qualityLUT;      //TO DO: Must add
2149   objParameter[0].displacedLUT = displacedLUT;  // Added for LLP Jets
2150 
2151   // Output for debugging
2152   {
2153     std::ostringstream oss;
2154     oss << "\n      Calo ET high threshold (hex) for calo object " << caloObjType << " "
2155         << " = " << std::hex << objParameter[0].etLowThreshold << " - " << objParameter[0].etHighThreshold;
2156     for (const auto& window : objParameter[0].etaWindows) {
2157       oss << "\n      etaWindow Lower / Upper for calo object "
2158           << " = 0x" << window.lower << " / 0x" << window.upper;
2159     }
2160     oss << "\n      phiWindow Lower / Upper for calo object "
2161         << " = 0x" << objParameter[0].phiWindow1Lower << " / 0x" << objParameter[0].phiWindow1Upper
2162         << "\n      phiWindowVeto Lower / Upper for calo object "
2163         << " = 0x" << objParameter[0].phiWindow2Lower << " / 0x" << objParameter[0].phiWindow2Upper
2164         << "\n      Isolation LUT for calo object "
2165         << " = 0x" << objParameter[0].isolationLUT << "\n      Quality LUT for calo object "
2166         << " = 0x" << objParameter[0].qualityLUT << "\n      LLP DISP LUT for calo object "
2167         << " = 0x" << objParameter[0].displacedLUT;
2168     LogDebug("TriggerMenuParser") << oss.str() << std::endl;
2169   }
2170 
2171   // object types - all same caloObjType
2172   std::vector<GlobalObject> objType(nrObj, caloObjType);
2173 
2174   // now create a new calo condition
2175   CaloTemplate caloCond(name);
2176 
2177   caloCond.setCondType(cType);
2178   caloCond.setObjectType(objType);
2179 
2180   //BLW TO DO: This needs to be added to the object rather than the whole condition
2181   caloCond.setCondGEq(gEq);
2182   caloCond.setCondChipNr(chipNr);
2183 
2184   //BLW TO DO: This needs to be added to the object rather than the whole condition
2185   caloCond.setCondRelativeBx(relativeBx);
2186 
2187   caloCond.setConditionParameter(objParameter, corrParameter);
2188 
2189   if (edm::isDebugEnabled()) {
2190     std::ostringstream myCoutStream;
2191     caloCond.print(myCoutStream);
2192     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
2193   }
2194 
2195   /*
2196     // insert condition into the map
2197     if ( !insertConditionIntoMap(caloCond, chipNr)) {
2198 
2199         edm::LogError("TriggerMenuParser")
2200                 << "    Error: duplicate condition (" << name << ")"
2201                 << std::endl;
2202 
2203         return false;
2204     }
2205     else {
2206             (m_corCaloTemplate[chipNr]).push_back(caloCond);
2207     }
2208 */
2209   (m_corCaloTemplate[chipNr]).push_back(caloCond);
2210 
2211   //
2212   return true;
2213 }
2214 
2215 /**
2216  * parseEnergySum Parse an "energy sum" condition and insert an entry to the conditions map
2217  *
2218  * @param node The corresponding node.
2219  * @param name The name of the condition.
2220  * @param chipNr The number of the chip this condition is located.
2221  *
2222  * @return "true" if succeeded, "false" if an error occurred.
2223  *
2224  */
2225 
2226 bool l1t::TriggerMenuParser::parseEnergySum(L1TUtmCondition condEnergySum, unsigned int chipNr, const bool corrFlag) {
2227   //    XERCES_CPP_NAMESPACE_USE
2228   using namespace tmeventsetup;
2229 
2230   // get condition, particle name and type name
2231 
2232   std::string condition = "calo";
2233   std::string type = l1t2string(condEnergySum.getType());
2234   std::string name = l1t2string(condEnergySum.getName());
2235 
2236   LogDebug("TriggerMenuParser") << "\n ****************************************** "
2237                                 << "\n      (in parseEnergySum) "
2238                                 << "\n condition = " << condition << "\n type      = " << type
2239                                 << "\n name      = " << name << std::endl;
2240 
2241   // determine object type type
2242   GlobalObject energySumObjType;
2243   GtConditionType cType;
2244 
2245   if (condEnergySum.getType() == esConditionType::MissingEt) {
2246     energySumObjType = GlobalObject::gtETM;
2247     cType = TypeETM;
2248   } else if (condEnergySum.getType() == esConditionType::TotalEt) {
2249     energySumObjType = GlobalObject::gtETT;
2250     cType = TypeETT;
2251   } else if (condEnergySum.getType() == esConditionType::TotalEtEM) {
2252     energySumObjType = GlobalObject::gtETTem;
2253     cType = TypeETTem;
2254   } else if (condEnergySum.getType() == esConditionType::TotalHt) {
2255     energySumObjType = GlobalObject::gtHTT;
2256     cType = TypeHTT;
2257   } else if (condEnergySum.getType() == esConditionType::MissingHt) {
2258     energySumObjType = GlobalObject::gtHTM;
2259     cType = TypeHTM;
2260   } else if (condEnergySum.getType() == esConditionType::MissingEtHF) {
2261     energySumObjType = GlobalObject::gtETMHF;
2262     cType = TypeETMHF;
2263   } else if (condEnergySum.getType() == esConditionType::MissingHtHF) {
2264     energySumObjType = GlobalObject::gtHTMHF;
2265     cType = TypeHTMHF;
2266   } else if (condEnergySum.getType() == esConditionType::TowerCount) {
2267     energySumObjType = GlobalObject::gtTowerCount;
2268     cType = TypeTowerCount;
2269   } else if (condEnergySum.getType() == esConditionType::MinBiasHFP0) {
2270     energySumObjType = GlobalObject::gtMinBiasHFP0;
2271     cType = TypeMinBiasHFP0;
2272   } else if (condEnergySum.getType() == esConditionType::MinBiasHFM0) {
2273     energySumObjType = GlobalObject::gtMinBiasHFM0;
2274     cType = TypeMinBiasHFM0;
2275   } else if (condEnergySum.getType() == esConditionType::MinBiasHFP1) {
2276     energySumObjType = GlobalObject::gtMinBiasHFP1;
2277     cType = TypeMinBiasHFP1;
2278   } else if (condEnergySum.getType() == esConditionType::MinBiasHFM1) {
2279     energySumObjType = GlobalObject::gtMinBiasHFM1;
2280     cType = TypeMinBiasHFM1;
2281   } else if (condEnergySum.getType() == esConditionType::AsymmetryEt) {
2282     energySumObjType = GlobalObject::gtAsymmetryEt;
2283     cType = TypeAsymEt;
2284   } else if (condEnergySum.getType() == esConditionType::AsymmetryHt) {
2285     energySumObjType = GlobalObject::gtAsymmetryHt;
2286     cType = TypeAsymHt;
2287   } else if (condEnergySum.getType() == esConditionType::AsymmetryEtHF) {
2288     energySumObjType = GlobalObject::gtAsymmetryEtHF;
2289     cType = TypeAsymEtHF;
2290   } else if (condEnergySum.getType() == esConditionType::AsymmetryHtHF) {
2291     energySumObjType = GlobalObject::gtAsymmetryHtHF;
2292     cType = TypeAsymHtHF;
2293   } else if (condEnergySum.getType() == esConditionType::Centrality0) {
2294     energySumObjType = GlobalObject::gtCentrality0;
2295     cType = TypeCent0;
2296   } else if (condEnergySum.getType() == esConditionType::Centrality1) {
2297     energySumObjType = GlobalObject::gtCentrality1;
2298     cType = TypeCent1;
2299   } else if (condEnergySum.getType() == esConditionType::Centrality2) {
2300     energySumObjType = GlobalObject::gtCentrality2;
2301     cType = TypeCent2;
2302   } else if (condEnergySum.getType() == esConditionType::Centrality3) {
2303     energySumObjType = GlobalObject::gtCentrality3;
2304     cType = TypeCent3;
2305   } else if (condEnergySum.getType() == esConditionType::Centrality4) {
2306     energySumObjType = GlobalObject::gtCentrality4;
2307     cType = TypeCent4;
2308   } else if (condEnergySum.getType() == esConditionType::Centrality5) {
2309     energySumObjType = GlobalObject::gtCentrality5;
2310     cType = TypeCent5;
2311   } else if (condEnergySum.getType() == esConditionType::Centrality6) {
2312     energySumObjType = GlobalObject::gtCentrality6;
2313     cType = TypeCent6;
2314   } else if (condEnergySum.getType() == esConditionType::Centrality7) {
2315     energySumObjType = GlobalObject::gtCentrality7;
2316     cType = TypeCent7;
2317   } else {
2318     edm::LogError("TriggerMenuParser") << "Wrong type for energy-sum condition (" << type << ")" << std::endl;
2319     return false;
2320   }
2321 
2322   // global object
2323   int nrObj = 1;
2324 
2325   //    std::string str_etComparison = l1t2string( condEnergySum.comparison_operator() );
2326 
2327   // get values
2328 
2329   // temporary storage of the parameters
2330   std::vector<EnergySumTemplate::ObjectParameter> objParameter(nrObj);
2331 
2332   int cnt = 0;
2333 
2334   // BLW TO DO: These needs to the added to the object rather than the whole condition.
2335   int relativeBx = 0;
2336   bool gEq = false;
2337 
2338   //    l1t::EnergySumsObjectRequirement objPar = condEnergySum.objectRequirement();
2339 
2340   // Loop over objects and extract the cuts on the objects
2341   const std::vector<L1TUtmObject>& objects = condEnergySum.getObjects();
2342   for (size_t jj = 0; jj < objects.size(); jj++) {
2343     const L1TUtmObject& object = objects.at(jj);
2344     gEq = (object.getComparisonOperator() == esComparisonOperator::GE);
2345 
2346     //  BLW TO DO: This needs to be added to the Object Parameters
2347     relativeBx = object.getBxOffset();
2348 
2349     //  Loop over the cuts for this object
2350     int lowerThresholdInd = 0;
2351     int upperThresholdInd = -1;
2352     int cntPhi = 0;
2353     unsigned int phiWindow1Lower = -1, phiWindow1Upper = -1, phiWindow2Lower = -1, phiWindow2Upper = -1;
2354 
2355     const std::vector<L1TUtmCut>& cuts = object.getCuts();
2356     for (size_t kk = 0; kk < cuts.size(); kk++) {
2357       const L1TUtmCut& cut = cuts.at(kk);
2358 
2359       switch (cut.getCutType()) {
2360         case esCutType::Threshold:
2361           lowerThresholdInd = cut.getMinimum().index;
2362           upperThresholdInd = cut.getMaximum().index;
2363           break;
2364 
2365         case esCutType::Eta:
2366           break;
2367 
2368         case esCutType::Phi: {
2369           if (cntPhi == 0) {
2370             phiWindow1Lower = cut.getMinimum().index;
2371             phiWindow1Upper = cut.getMaximum().index;
2372           } else if (cntPhi == 1) {
2373             phiWindow2Lower = cut.getMinimum().index;
2374             phiWindow2Upper = cut.getMaximum().index;
2375           } else {
2376             edm::LogError("TriggerMenuParser") << "Too Many Phi Cuts for esum-condition (" << type << ")" << std::endl;
2377             return false;
2378           }
2379           cntPhi++;
2380 
2381         } break;
2382 
2383         case esCutType::Count:
2384           lowerThresholdInd = cut.getMinimum().index;
2385           upperThresholdInd = 0xffffff;
2386           break;
2387 
2388         default:
2389           break;
2390       }  //end switch
2391 
2392     }  //end loop over cuts
2393 
2394     // Fill the object parameters
2395     objParameter[cnt].etLowThreshold = lowerThresholdInd;
2396     objParameter[cnt].etHighThreshold = upperThresholdInd;
2397     objParameter[cnt].phiWindow1Lower = phiWindow1Lower;
2398     objParameter[cnt].phiWindow1Upper = phiWindow1Upper;
2399     objParameter[cnt].phiWindow2Lower = phiWindow2Lower;
2400     objParameter[cnt].phiWindow2Upper = phiWindow2Upper;
2401 
2402     // Output for debugging
2403     LogDebug("TriggerMenuParser") << "\n      EnergySum ET high threshold (hex) for energy sum object " << cnt << " = "
2404                                   << std::hex << objParameter[cnt].etLowThreshold << " - "
2405                                   << objParameter[cnt].etHighThreshold
2406                                   << "\n      phiWindow Lower / Upper for calo object " << cnt << " = 0x"
2407                                   << objParameter[cnt].phiWindow1Lower << " / 0x" << objParameter[cnt].phiWindow1Upper
2408                                   << "\n      phiWindowVeto Lower / Upper for calo object " << cnt << " = 0x"
2409                                   << objParameter[cnt].phiWindow2Lower << " / 0x" << objParameter[cnt].phiWindow2Upper
2410                                   << std::dec << std::endl;
2411 
2412     cnt++;
2413   }  //end loop over objects
2414 
2415   // object types - all same energySumObjType
2416   std::vector<GlobalObject> objType(nrObj, energySumObjType);
2417 
2418   // now create a new energySum condition
2419 
2420   EnergySumTemplate energySumCond(name);
2421 
2422   energySumCond.setCondType(cType);
2423   energySumCond.setObjectType(objType);
2424   energySumCond.setCondGEq(gEq);
2425   energySumCond.setCondChipNr(chipNr);
2426   energySumCond.setCondRelativeBx(relativeBx);
2427 
2428   energySumCond.setConditionParameter(objParameter);
2429 
2430   if (edm::isDebugEnabled()) {
2431     std::ostringstream myCoutStream;
2432     energySumCond.print(myCoutStream);
2433     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
2434   }
2435 
2436   // insert condition into the map
2437   if (!insertConditionIntoMap(energySumCond, chipNr)) {
2438     edm::LogError("TriggerMenuParser") << "    Error: duplicate condition (" << name << ")" << std::endl;
2439 
2440     return false;
2441   } else {
2442     if (corrFlag) {
2443       (m_corEnergySumTemplate[chipNr]).push_back(energySumCond);
2444 
2445     } else {
2446       (m_vecEnergySumTemplate[chipNr]).push_back(energySumCond);
2447     }
2448   }
2449 
2450   //
2451   return true;
2452 }
2453 
2454 /**
2455  * parseEnergySumZdc Parse an "energy sum" condition from the ZDC subsystem and insert an entry to the conditions map
2456  *
2457  * @param node The corresponding node.
2458  * @param name The name of the condition.
2459  * @param chipNr The number of the chip this condition is located.
2460  *
2461  * @return "true" if succeeded, "false" if an error occurred.
2462  *
2463  */
2464 
2465 bool l1t::TriggerMenuParser::parseEnergySumZdc(L1TUtmCondition condEnergySumZdc,
2466                                                unsigned int chipNr,
2467                                                const bool corrFlag) {
2468   //    XERCES_CPP_NAMESPACE_USE
2469   using namespace tmeventsetup;
2470 
2471   // get condition, particle name and type name
2472 
2473   std::string condition = "calo";
2474   std::string type = l1t2string(condEnergySumZdc.getType());
2475   std::string name = l1t2string(condEnergySumZdc.getName());
2476 
2477   LogDebug("TriggerMenuParser")
2478       << "\n ******************************************\n      (in parseEnergySumZdc)\n condition = " << condition
2479       << "\n type      = " << type << "\n name      = " << name;
2480 
2481   // determine object type
2482   GlobalObject energySumObjType;
2483   GtConditionType cType;
2484 
2485   if (condEnergySumZdc.getType() == esConditionType::ZDCPlus) {
2486     LogDebug("TriggerMenuParser") << "ZDC signals: esConditionType::ZDCPlus " << std::endl;
2487     energySumObjType = GlobalObject::gtZDCP;
2488     cType = TypeZDCP;
2489   } else if (condEnergySumZdc.getType() == esConditionType::ZDCMinus) {
2490     LogDebug("TriggerMenuParser") << "ZDC signals: esConditionType::ZDCMinus " << std::endl;
2491     energySumObjType = GlobalObject::gtZDCM;
2492     cType = TypeZDCM;
2493   } else {
2494     edm::LogError("TriggerMenuParser") << "Wrong type for ZDC energy-sum condition (" << type << ")" << std::endl;
2495     return false;
2496   }
2497 
2498   // global object
2499   int nrObj = 1;
2500 
2501   // temporary storage of the parameters
2502   std::vector<EnergySumZdcTemplate::ObjectParameter> objParameter(nrObj);
2503 
2504   //  Loop over the cuts for this object
2505   int lowerThresholdInd = 0;
2506   int upperThresholdInd = -1;
2507 
2508   int cnt = 0;
2509 
2510   // BLW TO DO: These needs to the added to the object rather than the whole condition.
2511   int relativeBx = 0;
2512   bool gEq = false;
2513 
2514   //    l1t::EnergySumsObjectRequirement objPar = condEnergySumZdc.objectRequirement();
2515 
2516   // Loop over objects and extract the cuts on the objects
2517   const std::vector<L1TUtmObject>& objects = condEnergySumZdc.getObjects();
2518   for (size_t jj = 0; jj < objects.size(); jj++) {
2519     const L1TUtmObject& object = objects.at(jj);
2520     gEq = (object.getComparisonOperator() == esComparisonOperator::GE);
2521 
2522     //  BLW TO DO: This needs to be added to the Object Parameters
2523     relativeBx = object.getBxOffset();
2524 
2525     //  Loop over the cuts for this object
2526     const std::vector<L1TUtmCut>& cuts = object.getCuts();
2527     for (size_t kk = 0; kk < cuts.size(); kk++) {
2528       const L1TUtmCut& cut = cuts.at(kk);
2529 
2530       switch (cut.getCutType()) {
2531         case esCutType::Threshold:
2532           lowerThresholdInd = cut.getMinimum().index;
2533           upperThresholdInd = cut.getMaximum().index;
2534           break;
2535 
2536         case esCutType::Count:
2537           lowerThresholdInd = cut.getMinimum().index;
2538           upperThresholdInd = 0xffffff;
2539           break;
2540 
2541         default:
2542           break;
2543       }  //end switch
2544 
2545     }  //end loop over cuts
2546 
2547     // Fill the object parameters
2548     objParameter[cnt].etLowThreshold = lowerThresholdInd;
2549     objParameter[cnt].etHighThreshold = upperThresholdInd;
2550 
2551     // Output for debugging
2552     LogDebug("TriggerMenuParser") << "\n      EnergySumZdc ET high threshold (hex) for energy sum object " << cnt
2553                                   << " = " << std::hex << objParameter[cnt].etLowThreshold << " - "
2554                                   << objParameter[cnt].etHighThreshold << std::dec;
2555 
2556     cnt++;
2557   }  //end loop over objects
2558 
2559   // object types - all same energySumObjType
2560   std::vector<GlobalObject> objType(nrObj, energySumObjType);
2561 
2562   // now create a new energySum condition
2563 
2564   EnergySumZdcTemplate energySumCond(name);
2565 
2566   energySumCond.setCondType(cType);
2567   energySumCond.setObjectType(objType);
2568   energySumCond.setCondGEq(gEq);
2569   energySumCond.setCondChipNr(chipNr);
2570   energySumCond.setCondRelativeBx(relativeBx);
2571 
2572   energySumCond.setConditionParameter(objParameter);
2573 
2574   if (edm::isDebugEnabled()) {
2575     std::ostringstream myCoutStream;
2576     energySumCond.print(myCoutStream);
2577     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
2578   }
2579 
2580   // insert condition into the map
2581   if (!insertConditionIntoMap(energySumCond, chipNr)) {
2582     edm::LogError("TriggerMenuParser") << "    Error: duplicate condition (" << name << ")" << std::endl;
2583 
2584     return false;
2585   } else {
2586     (m_vecEnergySumZdcTemplate[chipNr]).push_back(energySumCond);
2587   }
2588   //
2589   return true;
2590 }
2591 
2592 /**
2593  * parseEnergySumCorr Parse an "energy sum" correlation condition and insert an entry to the conditions map
2594  *
2595  * @param node The corresponding node.
2596  * @param name The name of the condition.
2597  * @param chipNr The number of the chip this condition is located.
2598  *
2599  * @return "true" if succeeded, "false" if an error occurred.
2600  *
2601  */
2602 
2603 bool l1t::TriggerMenuParser::parseEnergySumCorr(const L1TUtmObject* corrESum, unsigned int chipNr) {
2604   //    XERCES_CPP_NAMESPACE_USE
2605   using namespace tmeventsetup;
2606 
2607   // get condition, particle name and type name
2608 
2609   std::string condition = "calo";
2610   std::string type = l1t2string(corrESum->getType());
2611   std::string name = l1t2string(corrESum->getName());
2612 
2613   LogDebug("TriggerMenuParser") << "\n ****************************************** "
2614                                 << "\n      (in parseEnergySum) "
2615                                 << "\n condition = " << condition << "\n type      = " << type
2616                                 << "\n name      = " << name << std::endl;
2617 
2618   // determine object type type
2619   GlobalObject energySumObjType;
2620   GtConditionType cType;
2621 
2622   if (corrESum->getType() == esObjectType::ETM) {
2623     energySumObjType = GlobalObject::gtETM;
2624     cType = TypeETM;
2625   } else if (corrESum->getType() == esObjectType::HTM) {
2626     energySumObjType = GlobalObject::gtHTM;
2627     cType = TypeHTM;
2628   } else if (corrESum->getType() == esObjectType::ETMHF) {
2629     energySumObjType = GlobalObject::gtETMHF;
2630     cType = TypeETMHF;
2631   } else if (corrESum->getType() == esObjectType::HTMHF) {
2632     energySumObjType = GlobalObject::gtHTMHF;
2633     cType = TypeHTMHF;
2634   } else if (corrESum->getType() == esObjectType::TOWERCOUNT) {
2635     energySumObjType = GlobalObject::gtTowerCount;
2636     cType = TypeTowerCount;
2637   } else {
2638     edm::LogError("TriggerMenuParser") << "Wrong type for energy-sum correclation condition (" << type << ")"
2639                                        << std::endl;
2640     return false;
2641   }
2642 
2643   // global object
2644   int nrObj = 1;
2645 
2646   //    std::string str_etComparison = l1t2string( condEnergySum.comparison_operator() );
2647 
2648   // get values
2649 
2650   // temporary storage of the parameters
2651   std::vector<EnergySumTemplate::ObjectParameter> objParameter(nrObj);
2652 
2653   int cnt = 0;
2654 
2655   // BLW TO DO: These needs to the added to the object rather than the whole condition.
2656   int relativeBx = 0;
2657   bool gEq = false;
2658 
2659   //    l1t::EnergySumsObjectRequirement objPar = condEnergySum.objectRequirement();
2660 
2661   gEq = (corrESum->getComparisonOperator() == esComparisonOperator::GE);
2662 
2663   //  BLW TO DO: This needs to be added to the Object Parameters
2664   relativeBx = corrESum->getBxOffset();
2665 
2666   //  Loop over the cuts for this object
2667   int lowerThresholdInd = 0;
2668   int upperThresholdInd = -1;
2669   int cntPhi = 0;
2670   unsigned int phiWindow1Lower = -1, phiWindow1Upper = -1, phiWindow2Lower = -1, phiWindow2Upper = -1;
2671 
2672   const std::vector<L1TUtmCut>& cuts = corrESum->getCuts();
2673   for (size_t kk = 0; kk < cuts.size(); kk++) {
2674     const L1TUtmCut& cut = cuts.at(kk);
2675 
2676     switch (cut.getCutType()) {
2677       case esCutType::Threshold:
2678         lowerThresholdInd = cut.getMinimum().index;
2679         upperThresholdInd = cut.getMaximum().index;
2680         break;
2681 
2682       case esCutType::Eta:
2683         break;
2684 
2685       case esCutType::Phi: {
2686         if (cntPhi == 0) {
2687           phiWindow1Lower = cut.getMinimum().index;
2688           phiWindow1Upper = cut.getMaximum().index;
2689         } else if (cntPhi == 1) {
2690           phiWindow2Lower = cut.getMinimum().index;
2691           phiWindow2Upper = cut.getMaximum().index;
2692         } else {
2693           edm::LogError("TriggerMenuParser") << "Too Many Phi Cuts for esum-condition (" << type << ")" << std::endl;
2694           return false;
2695         }
2696         cntPhi++;
2697 
2698       } break;
2699 
2700       default:
2701         break;
2702     }  //end switch
2703 
2704   }  //end loop over cuts
2705 
2706   // Fill the object parameters
2707   objParameter[0].etLowThreshold = lowerThresholdInd;
2708   objParameter[0].etHighThreshold = upperThresholdInd;
2709   objParameter[0].phiWindow1Lower = phiWindow1Lower;
2710   objParameter[0].phiWindow1Upper = phiWindow1Upper;
2711   objParameter[0].phiWindow2Lower = phiWindow2Lower;
2712   objParameter[0].phiWindow2Upper = phiWindow2Upper;
2713 
2714   // Output for debugging
2715   LogDebug("TriggerMenuParser") << "\n      EnergySum ET high threshold (hex) for energy sum object " << cnt << " = "
2716                                 << std::hex << objParameter[0].etLowThreshold << " - " << objParameter[0].etLowThreshold
2717                                 << "\n      phiWindow Lower / Upper for calo object " << cnt << " = 0x"
2718                                 << objParameter[0].phiWindow1Lower << " / 0x" << objParameter[0].phiWindow1Upper
2719                                 << "\n      phiWindowVeto Lower / Upper for calo object " << cnt << " = 0x"
2720                                 << objParameter[0].phiWindow2Lower << " / 0x" << objParameter[0].phiWindow2Upper
2721                                 << std::dec << std::endl;
2722 
2723   // object types - all same energySumObjType
2724   std::vector<GlobalObject> objType(nrObj, energySumObjType);
2725 
2726   // now create a new energySum condition
2727 
2728   EnergySumTemplate energySumCond(name);
2729 
2730   energySumCond.setCondType(cType);
2731   energySumCond.setObjectType(objType);
2732   energySumCond.setCondGEq(gEq);
2733   energySumCond.setCondChipNr(chipNr);
2734   energySumCond.setCondRelativeBx(relativeBx);
2735 
2736   energySumCond.setConditionParameter(objParameter);
2737 
2738   if (edm::isDebugEnabled()) {
2739     std::ostringstream myCoutStream;
2740     energySumCond.print(myCoutStream);
2741     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
2742   }
2743   /*
2744     // insert condition into the map
2745     if ( !insertConditionIntoMap(energySumCond, chipNr)) {
2746 
2747         edm::LogError("TriggerMenuParser")
2748                 << "    Error: duplicate condition (" << name << ")"
2749                 << std::endl;
2750 
2751         return false;
2752     }
2753     else {
2754 
2755        (m_corEnergySumTemplate[chipNr]).push_back(energySumCond);
2756 
2757     }
2758 */
2759   (m_corEnergySumTemplate[chipNr]).push_back(energySumCond);
2760 
2761   //
2762   return true;
2763 }
2764 
2765 /**                                                                                                                                                            
2766  * parseEnergySumCorr Parse an "energy sum" correlation condition and insert an entry to the conditions map                                                    
2767  *                                                                                                                                                             
2768  * @param node The corresponding node.                                                                                                                        
2769  * @param name The name of the condition.                                                                                                                      
2770  * @param chipNr The number of the chip this condition is located.                                                                                             
2771  *                                                                                                                                                             
2772  * @return "true" if succeeded, "false" if an error occurred.                                                                                                  
2773  *                                                                                                                                                             
2774  */
2775 
2776 bool l1t::TriggerMenuParser::parseAXOL1TL(L1TUtmCondition condAXOL1TL, unsigned int chipNr) {
2777   using namespace tmeventsetup;
2778 
2779   // get condition, particle name and particle type
2780   std::string condition = "axol1tl";
2781   std::string type = l1t2string(condAXOL1TL.getType());
2782   std::string name = l1t2string(condAXOL1TL.getName());
2783 
2784   LogDebug("TriggerMenuParser") << " ****************************************** " << std::endl
2785                                 << "     (in parseAXOL1TL) " << std::endl
2786                                 << " condition = " << condition << std::endl
2787                                 << " type      = " << type << std::endl
2788                                 << " name      = " << name << std::endl;
2789 
2790   const int nrObj = 1;
2791   GtConditionType cType = TypeAXOL1TL;
2792 
2793   std::vector<AXOL1TLTemplate::ObjectParameter> objParameter(nrObj);
2794 
2795   if (int(condAXOL1TL.getObjects().size()) != nrObj) {
2796     edm::LogError("TriggerMenuParser") << " condAXOL1TL objects: nrObj = " << nrObj
2797                                        << "condAXOL1TL.getObjects().size() = " << condAXOL1TL.getObjects().size()
2798                                        << std::endl;
2799     return false;
2800   }
2801 
2802   // Get the axol1tl object
2803   L1TUtmObject object = condAXOL1TL.getObjects().at(0);
2804   int relativeBx = object.getBxOffset();
2805   bool gEq = (object.getComparisonOperator() == esComparisonOperator::GE);
2806 
2807   //Loop over cuts for this  object
2808   int lowerThresholdInd = 0;
2809   int upperThresholdInd = -1;
2810 
2811   //save model and threshold
2812   std::string model = "";
2813 
2814   // for UTM v12+
2815   if (object.getType() == tmeventsetup::Axol1tl) {
2816     const std::vector<L1TUtmCut>& cuts = object.getCuts();
2817     for (size_t kk = 0; kk < cuts.size(); kk++) {
2818       const L1TUtmCut& cut = cuts.at(kk);
2819 
2820       //save model
2821       if (cut.getCutType() == tmeventsetup::Model) {
2822         model = cut.getData();
2823       }
2824       //save score
2825       else if (cut.getCutType() == esCutType::Score) {
2826         lowerThresholdInd = cut.getMinimum().value;
2827         upperThresholdInd = cut.getMaximum().value;
2828       }  //end else if
2829     }  //end cut loop
2830   }  //end if getType
2831   // LEGACY
2832   // for UTM pre v12
2833   else if (condAXOL1TL.getType() == esConditionType::AnomalyDetectionTrigger) {
2834     // hard-code model version for legacy Menu
2835     model = "v3";
2836 
2837     const std::vector<L1TUtmCut>& cuts = object.getCuts();
2838     for (size_t kk = 0; kk < cuts.size(); kk++) {
2839       const L1TUtmCut& cut = cuts.at(kk);
2840       if (cut.getCutType() == esCutType::AnomalyScore) {
2841         lowerThresholdInd = cut.getMinimum().value;
2842         upperThresholdInd = cut.getMaximum().value;
2843         break;
2844       }
2845     }  //end cut loop
2846   } else {
2847     edm::LogError("TriggerMenuParser") << "    Error: not a proper AXOL1TL condition" << std::endl;
2848     return false;
2849   }
2850 
2851   // check model version is not empty
2852   if (model.empty()) {
2853     edm::LogError("TriggerMenuParser") << "    Error: AXOL1TL movel version is empty" << std::endl;
2854     return false;
2855   }
2856 
2857   //fill object params
2858   objParameter[0].minAXOL1TLThreshold = lowerThresholdInd;
2859   objParameter[0].maxAXOL1TLThreshold = upperThresholdInd;
2860 
2861   // create a new AXOL1TL  condition
2862   AXOL1TLTemplate axol1tlCond(name);
2863   axol1tlCond.setCondType(cType);
2864   axol1tlCond.setCondGEq(gEq);
2865   axol1tlCond.setCondChipNr(chipNr);
2866   axol1tlCond.setCondRelativeBx(relativeBx);
2867   axol1tlCond.setConditionParameter(objParameter);
2868   axol1tlCond.setModelVersion(model);
2869 
2870   if (edm::isDebugEnabled()) {
2871     std::ostringstream myCoutStream;
2872     axol1tlCond.print(myCoutStream);
2873     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
2874   }
2875 
2876   // check that the condition does not exist already in the map
2877   if (!insertConditionIntoMap(axol1tlCond, chipNr)) {
2878     edm::LogError("TriggerMenuParser") << "    Error: duplicate AXOL1TL condition (" << name << ")" << std::endl;
2879     return false;
2880   }
2881 
2882   (m_vecAXOL1TLTemplate[chipNr]).push_back(axol1tlCond);
2883 
2884   return true;
2885 }
2886 
2887 /**
2888  * parseExternal Parse an External condition and
2889  * insert an entry to the conditions map
2890  *
2891  * @param node The corresponding node.
2892  * @param name The name of the condition.
2893  * @param chipNr The number of the chip this condition is located.
2894  *
2895  * @return "true" if succeeded, "false" if an error occurred.
2896  *
2897  */
2898 
2899 bool l1t::TriggerMenuParser::parseExternal(L1TUtmCondition condExt, unsigned int chipNr) {
2900   using namespace tmeventsetup;
2901   // get condition, particle name and type name
2902   std::string condition = "ext";
2903   std::string particle = "test-fix";
2904   std::string type = l1t2string(condExt.getType());
2905   std::string name = l1t2string(condExt.getName());
2906 
2907   LogDebug("TriggerMenuParser") << "\n ****************************************** "
2908                                 << "\n      (in parseExternal) "
2909                                 << "\n condition = " << condition << "\n particle  = " << particle
2910                                 << "\n type      = " << type << "\n name      = " << name << std::endl;
2911 
2912   // object type and condition type
2913   // object type - irrelevant for External conditions
2914   GtConditionType cType = TypeExternal;
2915   GlobalObject extSignalType = GlobalObject::gtExternal;
2916   int nrObj = 1;  //only one object for these conditions
2917 
2918   int relativeBx = 0;
2919   unsigned int channelID = 0;
2920 
2921   // Get object for External conditions
2922   const std::vector<L1TUtmObject>& objects = condExt.getObjects();
2923   for (size_t jj = 0; jj < objects.size(); jj++) {
2924     const L1TUtmObject& object = objects.at(jj);
2925     if (object.getType() == esObjectType::EXT) {
2926       relativeBx = object.getBxOffset();
2927       channelID = object.getExternalChannelId();
2928     }
2929   }
2930 
2931   // set the boolean value for the ge_eq mode - irrelevant for External conditions
2932   bool gEq = false;
2933 
2934   //object types - all same for external conditions
2935   std::vector<GlobalObject> objType(nrObj, extSignalType);
2936 
2937   // now create a new External condition
2938   ExternalTemplate externalCond(name);
2939 
2940   externalCond.setCondType(cType);
2941   externalCond.setObjectType(objType);
2942   externalCond.setCondGEq(gEq);
2943   externalCond.setCondChipNr(chipNr);
2944   externalCond.setCondRelativeBx(relativeBx);
2945   externalCond.setExternalChannel(channelID);
2946 
2947   LogTrace("TriggerMenuParser") << externalCond << "\n" << std::endl;
2948 
2949   // insert condition into the map
2950   if (!insertConditionIntoMap(externalCond, chipNr)) {
2951     edm::LogError("TriggerMenuParser") << "    Error: duplicate condition (" << name << ")" << std::endl;
2952 
2953     return false;
2954   } else {
2955     (m_vecExternalTemplate[chipNr]).push_back(externalCond);
2956   }
2957 
2958   return true;
2959 }
2960 
2961 // Parse the CICADA condition and insert the entry into the conditions mapping
2962 bool l1t::TriggerMenuParser::parseCICADA(L1TUtmCondition condCICADA, unsigned int chipNr) {
2963   using namespace tmeventsetup;
2964 
2965   std::string condition = "cicada";
2966   std::string type = l1t2string(condCICADA.getType());
2967   std::string name = l1t2string(condCICADA.getName());
2968 
2969   LogDebug("TriggerMenuParser") << " ****************************************** " << std::endl
2970                                 << "     (in parseCICADA) " << std::endl
2971                                 << " condition = " << condition << std::endl
2972                                 << " type      = " << type << std::endl
2973                                 << " name      = " << name << std::endl;
2974   const int nrObj = 1;
2975   GtConditionType cType = TypeCICADA;
2976 
2977   std::vector<CICADATemplate::ObjectParameter> objParameter(nrObj);
2978 
2979   if (int(condCICADA.getObjects().size()) != nrObj) {
2980     edm::LogError("TriggerMenuParser") << " condCICADA objects: nrObj = " << nrObj
2981                                        << "condCICADA.getObjects().size() = " << condCICADA.getObjects().size()
2982                                        << std::endl;
2983     return false;
2984   }
2985 
2986   L1TUtmObject object = condCICADA.getObjects().at(0);
2987   int relativeBx = object.getBxOffset();
2988   bool gEq = (object.getComparisonOperator() == esComparisonOperator::GE);
2989 
2990   float lowerThresholdInd = 0;  //May need to be float to match CICADA?
2991   float upperThresholdInd = -1;
2992 
2993   const std::vector<L1TUtmCut>& cuts = object.getCuts();
2994   for (size_t kk = 0; kk < cuts.size(); kk++) {
2995     const L1TUtmCut& cut = cuts.at(kk);
2996 
2997     switch (cut.getCutType()) {
2998       case esCutType::CicadaScore:
2999         lowerThresholdInd = cut.getMinimum().value;
3000         upperThresholdInd = cut.getMaximum().value;
3001     }
3002   }
3003 
3004   objParameter[0].minCICADAThreshold = lowerThresholdInd;
3005   objParameter[0].maxCICADAThreshold = upperThresholdInd;
3006 
3007   CICADATemplate cicadaCond(name);
3008   cicadaCond.setCondType(cType);
3009   cicadaCond.setCondGEq(gEq);
3010   cicadaCond.setCondChipNr(chipNr);
3011   cicadaCond.setCondRelativeBx(relativeBx);
3012   cicadaCond.setConditionParameter(objParameter);
3013 
3014   if (edm::isDebugEnabled()) {
3015     std::ostringstream myCoutStream;
3016     cicadaCond.print(myCoutStream);
3017     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
3018   }
3019 
3020   if (!insertConditionIntoMap(cicadaCond, chipNr)) {
3021     edm::LogError("TriggerMenuParser") << "   Error: duplicate CICADA condition (" << name << ")" << std::endl;
3022     return false;
3023   }
3024 
3025   (m_vecCICADATemplate[chipNr]).push_back(cicadaCond);
3026 
3027   return true;
3028 }
3029 
3030 /**
3031  * parseCorrelation Parse a correlation condition and
3032  * insert an entry to the conditions map
3033  *
3034  * @param node The corresponding node.
3035  * @param name The name of the condition.
3036  * @param chipNr The number of the chip this condition is located.
3037  *
3038  * @return "true" if succeeded, "false" if an error occurred.
3039  *
3040  */
3041 
3042 bool l1t::TriggerMenuParser::parseCorrelation(L1TUtmCondition corrCond, unsigned int chipNr) {
3043   using namespace tmeventsetup;
3044   std::string condition = "corr";
3045   std::string particle = "test-fix";
3046   std::string type = l1t2string(corrCond.getType());
3047   std::string name = l1t2string(corrCond.getName());
3048 
3049   LogDebug("TriggerMenuParser") << " ****************************************** " << std::endl
3050                                 << "     (in parseCorrelation) " << std::endl
3051                                 << " condition = " << condition << std::endl
3052                                 << " particle  = " << particle << std::endl
3053                                 << " type      = " << type << std::endl
3054                                 << " name      = " << name << std::endl;
3055 
3056   // create a new correlation condition
3057   CorrelationTemplate correlationCond(name);
3058 
3059   // check that the condition does not exist already in the map
3060   if (!insertConditionIntoMap(correlationCond, chipNr)) {
3061     edm::LogError("TriggerMenuParser") << "    Error: duplicate correlation condition (" << name << ")" << std::endl;
3062 
3063     return false;
3064   }
3065 
3066   // Define some of the quantities to store the parased information
3067 
3068   // condition type BLW  (Do we change this to the type of correlation condition?)
3069   GtConditionType cType = l1t::Type2cor;
3070 
3071   // two objects (for sure)
3072   const int nrObj = 2;
3073 
3074   // object types and greater equal flag - filled in the loop
3075   int intGEq[nrObj] = {-1, -1};
3076   std::vector<GlobalObject> objType(nrObj);           //BLW do we want to define these as a different type?
3077   std::vector<GtConditionCategory> condCateg(nrObj);  //BLW do we want to change these categories
3078 
3079   // correlation flag and index in the cor*vector
3080   const bool corrFlag = true;
3081   int corrIndexVal[nrObj] = {-1, -1};
3082 
3083   // Storage of the correlation selection
3084   CorrelationTemplate::CorrelationParameter corrParameter;
3085   corrParameter.chargeCorrelation = 1;  //ignore charge correlation
3086 
3087   // Get the correlation Cuts on the legs
3088   int cutType = 0;
3089   const std::vector<L1TUtmCut>& cuts = corrCond.getCuts();
3090   for (size_t jj = 0; jj < cuts.size(); jj++) {
3091     const L1TUtmCut& cut = cuts.at(jj);
3092 
3093     if (cut.getCutType() == esCutType::ChargeCorrelation) {
3094       if (cut.getData() == "ls")
3095         corrParameter.chargeCorrelation = 2;
3096       else if (cut.getData() == "os")
3097         corrParameter.chargeCorrelation = 4;
3098       else
3099         corrParameter.chargeCorrelation = 1;  //ignore charge correlation
3100     } else {
3101       //
3102       //  Until utm has method to calculate these, do the integer value calculation with precision.
3103       //
3104       double minV = cut.getMinimum().value;
3105       double maxV = cut.getMaximum().value;
3106 
3107       //Scale down very large numbers out of xml
3108       if (maxV > 1.0e8)
3109         maxV = 1.0e8;
3110 
3111       if (cut.getCutType() == esCutType::DeltaEta) {
3112         LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tDeltaEta Cut minV = " << minV
3113                                       << " Max = " << maxV << " precMin = " << cut.getMinimum().index
3114                                       << " precMax = " << cut.getMaximum().index << std::endl;
3115         corrParameter.minEtaCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3116         corrParameter.maxEtaCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3117         corrParameter.precEtaCut = cut.getMinimum().index;
3118         cutType = cutType | 0x1;
3119       } else if (cut.getCutType() == esCutType::DeltaPhi) {
3120         LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tDeltaPhi Cut minV = " << minV
3121                                       << " Max = " << maxV << " precMin = " << cut.getMinimum().index
3122                                       << " precMax = " << cut.getMaximum().index << std::endl;
3123         corrParameter.minPhiCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3124         corrParameter.maxPhiCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3125         corrParameter.precPhiCut = cut.getMinimum().index;
3126         cutType = cutType | 0x2;
3127       } else if (cut.getCutType() == esCutType::DeltaR) {
3128         LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tDeltaR Cut minV = " << minV
3129                                       << " Max = " << maxV << " precMin = " << cut.getMinimum().index
3130                                       << " precMax = " << cut.getMaximum().index << std::endl;
3131         corrParameter.minDRCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3132         corrParameter.maxDRCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3133         corrParameter.precDRCut = cut.getMinimum().index;
3134         cutType = cutType | 0x4;
3135       } else if (cut.getCutType() == esCutType::TwoBodyPt) {
3136         corrParameter.minTBPTCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3137         corrParameter.maxTBPTCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3138         corrParameter.precTBPTCut = cut.getMinimum().index;
3139         LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tTPBT Cut minV = " << minV
3140                                       << " Max = " << maxV << " precMin = " << cut.getMinimum().index
3141                                       << " precMax = " << cut.getMaximum().index << std::endl;
3142         cutType = cutType | 0x20;
3143       } else if ((cut.getCutType() == esCutType::Mass) ||
3144                  (cut.getCutType() == esCutType::MassDeltaR)) {  //Invariant Mass, MassOverDeltaR
3145         LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tMass Cut minV = " << minV
3146                                       << " Max = " << maxV << " precMin = " << cut.getMinimum().index
3147                                       << " precMax = " << cut.getMaximum().index << std::endl;
3148         corrParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3149         corrParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3150         corrParameter.precMassCut = cut.getMinimum().index;
3151         // cutType = cutType | 0x8;
3152         if (corrCond.getType() == esConditionType::TransverseMass) {
3153           cutType = cutType | 0x10;
3154         } else if (corrCond.getType() == esConditionType::InvariantMassDeltaR) {
3155           cutType = cutType | 0x80;
3156         } else {
3157           cutType = cutType | 0x8;
3158         }
3159       } else if (cut.getCutType() == esCutType::MassUpt) {  // Added for displaced muons
3160         LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tMass Cut minV = " << minV
3161                                       << " Max = " << maxV << " precMin = " << cut.getMinimum().index
3162                                       << " precMax = " << cut.getMaximum().index << std::endl;
3163         corrParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3164         corrParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3165         corrParameter.precMassCut = cut.getMinimum().index;
3166         cutType = cutType | 0x40;  // Note:    0x40 (MassUpt) is next available bit after 0x20 (TwoBodyPt)
3167       }  // Careful: cutType carries same info as esCutType, but is hard coded!!
3168     }  //          This seems like a historical hack, which may be error prone.
3169   }  //          cutType is defined here, for use later in CorrCondition.cc
3170   corrParameter.corrCutType = cutType;
3171 
3172   // Get the two objects that form the legs
3173   const std::vector<L1TUtmObject>& objects = corrCond.getObjects();
3174   if (objects.size() != 2) {
3175     edm::LogError("TriggerMenuParser") << "incorrect number of objects for the correlation condition " << name
3176                                        << " corrFlag " << corrFlag << std::endl;
3177     return false;
3178   }
3179 
3180   // loop over legs
3181   for (size_t jj = 0; jj < objects.size(); jj++) {
3182     const L1TUtmObject& object = objects.at(jj);
3183     LogDebug("TriggerMenuParser") << "      obj name = " << object.getName() << "\n";
3184     LogDebug("TriggerMenuParser") << "      obj type = " << object.getType() << "\n";
3185     LogDebug("TriggerMenuParser") << "      obj op = " << object.getComparisonOperator() << "\n";
3186     LogDebug("TriggerMenuParser") << "      obj bx = " << object.getBxOffset() << "\n";
3187 
3188     // check the leg type
3189     if (object.getType() == esObjectType::Muon) {
3190       // we have a muon
3191 
3192       /*
3193           //BLW Hold on to this code we may need to go back to it at some point.
3194       // Now we are putting ALL leg conditions into the vector (so there are duplicates)
3195       // This is potentially a place to slim down the code.  Note: We currently evaluate the
3196       // conditions every time, so even if we put the condition in the vector once, we would
3197       // still evaluate it multiple times.  This is a place for optimization.
3198           {
3199 
3200               parseMuonCorr(&object,chipNr);
3201           corrIndexVal[jj] = (m_corMuonTemplate[chipNr]).size() - 1;
3202 
3203           } else {
3204          LogDebug("TriggerMenuParser") << "Not Adding Correlation Muon Condition to Map...looking for the condition in Muon Cor Vector" << std::endl;
3205          bool found = false;
3206          int index = 0;
3207          while(!found && index<(int)((m_corMuonTemplate[chipNr]).size()) ) {
3208              if( (m_corMuonTemplate[chipNr]).at(index).condName() == object.getName() ) {
3209             LogDebug("TriggerMenuParser") << "Found condition " << object.getName() << " in vector at index " << index << std::endl;
3210             found = true;
3211          } else {
3212             index++;
3213          }
3214          }
3215          if(found) {
3216             corrIndexVal[jj] = index;
3217          } else {
3218            edm::LogError("TriggerMenuParser") << "FAILURE: Condition " << object.getName() << " is in map but not in cor. vector " << std::endl;
3219          }
3220 
3221       }
3222 */
3223       parseMuonCorr(&object, chipNr);
3224       corrIndexVal[jj] = (m_corMuonTemplate[chipNr]).size() - 1;
3225 
3226       //Now set some flags for this subCondition
3227       intGEq[jj] = (object.getComparisonOperator() == esComparisonOperator::GE);
3228       objType[jj] = gtMu;
3229       condCateg[jj] = CondMuon;
3230 
3231     } else if (object.getType() == esObjectType::Egamma || object.getType() == esObjectType::Jet ||
3232                object.getType() == esObjectType::Tau) {
3233       // we have an Calo object
3234       parseCaloCorr(&object, chipNr);
3235       corrIndexVal[jj] = (m_corCaloTemplate[chipNr]).size() - 1;
3236 
3237       //Now set some flags for this subCondition
3238       intGEq[jj] = (object.getComparisonOperator() == esComparisonOperator::GE);
3239       switch (object.getType()) {
3240         case esObjectType::Egamma: {
3241           objType[jj] = gtEG;
3242         } break;
3243         case esObjectType::Jet: {
3244           objType[jj] = gtJet;
3245         } break;
3246         case esObjectType::Tau: {
3247           objType[jj] = gtTau;
3248         } break;
3249         default: {
3250         } break;
3251       }
3252       condCateg[jj] = CondCalo;
3253 
3254     } else if (object.getType() == esObjectType::ETM || object.getType() == esObjectType::ETMHF ||
3255                object.getType() == esObjectType::HTMHF || object.getType() == esObjectType::TOWERCOUNT ||
3256                object.getType() == esObjectType::HTM) {
3257       // we have Energy Sum
3258       parseEnergySumCorr(&object, chipNr);
3259       corrIndexVal[jj] = (m_corEnergySumTemplate[chipNr]).size() - 1;
3260 
3261       //Now set some flags for this subCondition
3262       intGEq[jj] = (object.getComparisonOperator() == esComparisonOperator::GE);
3263       switch (object.getType()) {
3264         case esObjectType::ETM: {
3265           objType[jj] = GlobalObject::gtETM;
3266         } break;
3267         case esObjectType::HTM: {
3268           objType[jj] = GlobalObject::gtHTM;
3269         } break;
3270         case esObjectType::ETMHF: {
3271           objType[jj] = GlobalObject::gtETMHF;
3272         } break;
3273         case esObjectType::HTMHF: {
3274           objType[jj] = GlobalObject::gtHTMHF;
3275         } break;
3276         case esObjectType::TOWERCOUNT: {
3277           objType[jj] = GlobalObject::gtTowerCount;
3278         } break;
3279         default: {
3280         } break;
3281       }
3282       condCateg[jj] = CondEnergySum;
3283 
3284     } else {
3285       edm::LogError("TriggerMenuParser") << "Illegal Object Type " << object.getType()
3286                                          << " for the correlation condition " << name << std::endl;
3287       return false;
3288 
3289     }  //if block on leg types
3290 
3291   }  //loop over legs
3292 
3293   // get greater equal flag for the correlation condition
3294   bool gEq = true;
3295   if (intGEq[0] != intGEq[1]) {
3296     edm::LogError("TriggerMenuParser") << "Inconsistent GEq flags for sub-conditions "
3297                                        << " for the correlation condition " << name << std::endl;
3298     return false;
3299 
3300   } else {
3301     gEq = (intGEq[0] != 0);
3302   }
3303 
3304   // fill the correlation condition
3305   correlationCond.setCondType(cType);
3306   correlationCond.setObjectType(objType);
3307   correlationCond.setCondGEq(gEq);
3308   correlationCond.setCondChipNr(chipNr);
3309 
3310   correlationCond.setCond0Category(condCateg[0]);
3311   correlationCond.setCond1Category(condCateg[1]);
3312 
3313   correlationCond.setCond0Index(corrIndexVal[0]);
3314   correlationCond.setCond1Index(corrIndexVal[1]);
3315 
3316   correlationCond.setCorrelationParameter(corrParameter);
3317 
3318   if (edm::isDebugEnabled()) {
3319     std::ostringstream myCoutStream;
3320     correlationCond.print(myCoutStream);
3321     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
3322   }
3323 
3324   // insert condition into the map
3325   // condition is not duplicate, check was done at the beginning
3326 
3327   (m_vecCorrelationTemplate[chipNr]).push_back(correlationCond);
3328 
3329   //
3330   return true;
3331 }
3332 
3333 //////////////////////////////////////////////////////////////////////////////////////
3334 /**
3335  * parseCorrelationThreeBody Parse a correlation condition between three objects and
3336  * insert an entry to the conditions map
3337  *
3338  * @param node The corresponding node.
3339  * @param name The name of the condition.
3340  * @param chipNr The number of the chip this condition is located.
3341  *
3342  * @return "true" if succeeded, "false" if an error occurred.
3343  *
3344  */
3345 
3346 bool l1t::TriggerMenuParser::parseCorrelationThreeBody(L1TUtmCondition corrCond, unsigned int chipNr) {
3347   using namespace tmeventsetup;
3348   std::string condition = "corrThreeBody";
3349   std::string particle = "muon";
3350   std::string type = l1t2string(corrCond.getType());
3351   std::string name = l1t2string(corrCond.getName());
3352 
3353   LogDebug("TriggerMenuParser") << " ****************************************** " << std::endl
3354                                 << "     (in parseCorrelationThreeBody) " << std::endl
3355                                 << " condition = " << condition << std::endl
3356                                 << " particle  = " << particle << std::endl
3357                                 << " type      = " << type << std::endl
3358                                 << " name      = " << name << std::endl;
3359 
3360   // create a new correlation condition
3361   CorrelationThreeBodyTemplate correlationThreeBodyCond(name);
3362 
3363   // check that the condition does not exist already in the map
3364   if (!insertConditionIntoMap(correlationThreeBodyCond, chipNr)) {
3365     edm::LogError("TriggerMenuParser") << "    Error: duplicate correlation condition (" << name << ")" << std::endl;
3366     return false;
3367   }
3368 
3369   // Define some of the quantities to store the parsed information
3370   GtConditionType cType = l1t::Type3s;
3371 
3372   // three objects (for sure)
3373   const int nrObj = 3;
3374 
3375   // object types and greater equal flag - filled in the loop
3376   std::vector<GlobalObject> objType(nrObj);
3377   std::vector<GtConditionCategory> condCateg(nrObj);
3378 
3379   // correlation flag and index in the cor*vector
3380   const bool corrFlag = true;
3381   int corrIndexVal[nrObj] = {-1, -1, -1};
3382 
3383   // Storage of the correlation selection
3384   CorrelationThreeBodyTemplate::CorrelationThreeBodyParameter corrThreeBodyParameter;
3385   // Set charge correlation parameter
3386   //corrThreeBodyParameter.chargeCorrelation = chargeCorrelation;  //tmpValues[0];
3387   //corrThreeBodyParameter.chargeCorrelation = 1;  //ignore charge correlation for corr-legs
3388 
3389   // Get the correlation cuts on the legs
3390   int cutType = 0;
3391   const std::vector<L1TUtmCut>& cuts = corrCond.getCuts();
3392   for (size_t lll = 0; lll < cuts.size(); lll++) {  // START esCut lll
3393     const L1TUtmCut& cut = cuts.at(lll);
3394 
3395     if (cut.getCutType() == esCutType::ChargeCorrelation) {
3396       if (cut.getData() == "ls")
3397         corrThreeBodyParameter.chargeCorrelation = 2;
3398       else if (cut.getData() == "os")
3399         corrThreeBodyParameter.chargeCorrelation = 4;
3400       else
3401         corrThreeBodyParameter.chargeCorrelation = 1;  //ignore charge correlation
3402     }
3403 
3404     //
3405     //  Until utm has method to calculate these, do the integer value calculation with precision.
3406     //
3407     double minV = cut.getMinimum().value;
3408     double maxV = cut.getMaximum().value;
3409     //Scale down very large numbers out of xml
3410     if (maxV > 1.0e8)
3411       maxV = 1.0e8;
3412 
3413     if (cut.getCutType() == esCutType::Mass) {
3414       LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tMass Cut minV = " << minV
3415                                     << "\tMass Cut maxV = " << maxV << " precMin = " << cut.getMinimum().index
3416                                     << " precMax = " << cut.getMaximum().index << std::endl;
3417       corrThreeBodyParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3418       corrThreeBodyParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3419       corrThreeBodyParameter.precMassCut = cut.getMinimum().index;
3420       cutType = cutType | 0x8;
3421     } else if (cut.getCutType() == esCutType::MassDeltaR) {
3422       corrThreeBodyParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3423       corrThreeBodyParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3424       corrThreeBodyParameter.precMassCut = cut.getMinimum().index;
3425       cutType = cutType | 0x80;
3426     }
3427   }  // END esCut lll
3428   corrThreeBodyParameter.corrCutType = cutType;
3429 
3430   // Get the three objects that form the legs
3431   const std::vector<L1TUtmObject>& objects = corrCond.getObjects();
3432   if (objects.size() != 3) {
3433     edm::LogError("TriggerMenuParser") << "incorrect number of objects for the correlation condition " << name
3434                                        << " corrFlag " << corrFlag << std::endl;
3435     return false;
3436   }
3437 
3438   // Loop over legs
3439   for (size_t lll = 0; lll < objects.size(); lll++) {
3440     const L1TUtmObject& object = objects.at(lll);
3441     LogDebug("TriggerMenuParser") << "      obj name = " << object.getName() << "\n";
3442     LogDebug("TriggerMenuParser") << "      obj type = " << object.getType() << "\n";
3443     LogDebug("TriggerMenuParser") << "      obj bx = " << object.getBxOffset() << "\n";
3444 
3445     // check the leg type
3446     if (object.getType() == esObjectType::Muon) {
3447       // we have a muon
3448       parseMuonCorr(&object, chipNr);
3449       corrIndexVal[lll] = (m_corMuonTemplate[chipNr]).size() - 1;
3450 
3451       //Now set some flags for this subCondition
3452       objType[lll] = gtMu;
3453       condCateg[lll] = CondMuon;
3454 
3455     } else {
3456       edm::LogError("TriggerMenuParser") << "Checked the object Type " << object.getType()
3457                                          << " for the correlation condition " << name
3458                                          << ": no three muons in the event!" << std::endl;
3459     }
3460   }  // End loop over legs
3461 
3462   // fill the three-body correlation condition
3463   correlationThreeBodyCond.setCondType(cType);
3464   correlationThreeBodyCond.setObjectType(objType);
3465   correlationThreeBodyCond.setCondChipNr(chipNr);
3466 
3467   correlationThreeBodyCond.setCond0Category(condCateg[0]);
3468   correlationThreeBodyCond.setCond1Category(condCateg[1]);
3469   correlationThreeBodyCond.setCond2Category(condCateg[2]);
3470 
3471   correlationThreeBodyCond.setCond0Index(corrIndexVal[0]);
3472   correlationThreeBodyCond.setCond1Index(corrIndexVal[1]);
3473   correlationThreeBodyCond.setCond2Index(corrIndexVal[2]);
3474 
3475   correlationThreeBodyCond.setCorrelationThreeBodyParameter(corrThreeBodyParameter);
3476 
3477   if (edm::isDebugEnabled()) {
3478     std::ostringstream myCoutStream;
3479     correlationThreeBodyCond.print(myCoutStream);
3480     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
3481   }
3482 
3483   // insert condition into the map
3484   // condition is not duplicate, check was done at the beginning
3485 
3486   (m_vecCorrelationThreeBodyTemplate[chipNr]).push_back(correlationThreeBodyCond);
3487 
3488   //
3489   return true;
3490 }
3491 
3492 ////////////////////////////////////////////////////////////////////////////////////
3493 /**
3494  * parseCorrelationWithOverlapRemoval Parse a correlation condition and
3495  * insert an entry to the conditions map
3496  *
3497  * @param node The corresponding node.
3498  * @param name The name of the condition.
3499  * @param chipNr The number of the chip this condition is located.
3500  *
3501  * @return "true" if succeeded, "false" if an error occurred.
3502  *
3503  */
3504 
3505 bool l1t::TriggerMenuParser::parseCorrelationWithOverlapRemoval(const L1TUtmCondition& corrCond, unsigned int chipNr) {
3506   using namespace tmeventsetup;
3507   std::string condition = "corrWithOverlapRemoval";
3508   std::string particle = "test-fix";
3509   std::string type = l1t2string(corrCond.getType());
3510   std::string name = l1t2string(corrCond.getName());
3511 
3512   LogDebug("TriggerMenuParser") << " ****************************************** " << std::endl
3513                                 << "     (in parseCorrelationWithOverlapRemoval) " << std::endl
3514                                 << " condition = " << condition << std::endl
3515                                 << " particle  = " << particle << std::endl
3516                                 << " type      = " << type << std::endl
3517                                 << " name      = " << name << std::endl;
3518 
3519   // create a new correlation condition
3520   CorrelationWithOverlapRemovalTemplate correlationWORCond(name);
3521 
3522   // check that the condition does not exist already in the map
3523   if (!insertConditionIntoMap(correlationWORCond, chipNr)) {
3524     edm::LogError("TriggerMenuParser") << "    Error: duplicate correlation condition (" << name << ")" << std::endl;
3525 
3526     return false;
3527   }
3528 
3529   // Define some of the quantities to store the parased information
3530 
3531   // condition type BLW  (Do we change this to the type of correlation condition?)
3532   GtConditionType cType = l1t::Type2corWithOverlapRemoval;
3533 
3534   // three objects (for sure)
3535   const int nrObj = 3;
3536 
3537   // object types and greater equal flag - filled in the loop
3538   int intGEq[nrObj] = {-1, -1, -1};
3539   std::vector<GlobalObject> objType(nrObj);           //BLW do we want to define these as a different type?
3540   std::vector<GtConditionCategory> condCateg(nrObj);  //BLW do we want to change these categories
3541 
3542   // correlation flag and index in the cor*vector
3543   const bool corrFlag = true;
3544   int corrIndexVal[nrObj] = {-1, -1, -1};
3545 
3546   // Storage of the correlation selection
3547   CorrelationWithOverlapRemovalTemplate::CorrelationWithOverlapRemovalParameter corrParameter;
3548   corrParameter.chargeCorrelation = 1;  //ignore charge correlation for corr-legs
3549 
3550   // Get the correlation Cuts on the legs
3551   int cutType = 0;
3552   const std::vector<L1TUtmCut>& cuts = corrCond.getCuts();
3553   for (size_t jj = 0; jj < cuts.size(); jj++) {
3554     const L1TUtmCut& cut = cuts.at(jj);
3555 
3556     if (cut.getCutType() == esCutType::ChargeCorrelation) {
3557       if (cut.getData() == "ls")
3558         corrParameter.chargeCorrelation = 2;
3559       else if (cut.getData() == "os")
3560         corrParameter.chargeCorrelation = 4;
3561       else
3562         corrParameter.chargeCorrelation = 1;  //ignore charge correlation
3563     } else {
3564       //
3565       //  Unitl utm has method to calculate these, do the integer value calculation with precision.
3566       //
3567       double minV = cut.getMinimum().value;
3568       double maxV = cut.getMaximum().value;
3569 
3570       //Scale down very large numbers out of xml
3571       if (maxV > 1.0e8)
3572         maxV = 1.0e8;
3573 
3574       if (cut.getCutType() == esCutType::DeltaEta) {
3575         //std::cout << "DeltaEta Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3576         corrParameter.minEtaCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3577         corrParameter.maxEtaCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3578         corrParameter.precEtaCut = cut.getMinimum().index;
3579         cutType = cutType | 0x1;
3580       } else if (cut.getCutType() == esCutType::DeltaPhi) {
3581         //std::cout << "DeltaPhi Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3582         corrParameter.minPhiCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3583         corrParameter.maxPhiCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3584         corrParameter.precPhiCut = cut.getMinimum().index;
3585         cutType = cutType | 0x2;
3586       } else if (cut.getCutType() == esCutType::DeltaR) {
3587         //std::cout << "DeltaR Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3588         corrParameter.minDRCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3589         corrParameter.maxDRCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3590         corrParameter.precDRCut = cut.getMinimum().index;
3591         cutType = cutType | 0x4;
3592       } else if (cut.getCutType() == esCutType::Mass) {
3593         //std::cout << "Mass Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3594         corrParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3595         corrParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3596         corrParameter.precMassCut = cut.getMinimum().index;
3597         cutType = cutType | 0x8;
3598       } else if (cut.getCutType() == esCutType::MassDeltaR) {
3599         corrParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3600         corrParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3601         corrParameter.precMassCut = cut.getMinimum().index;
3602         cutType = cutType | 0x80;
3603       }
3604       if (cut.getCutType() == esCutType::OvRmDeltaEta) {
3605         //std::cout << "OverlapRemovalDeltaEta Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3606         corrParameter.minOverlapRemovalEtaCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3607         corrParameter.maxOverlapRemovalEtaCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3608         corrParameter.precOverlapRemovalEtaCut = cut.getMinimum().index;
3609         cutType = cutType | 0x10;
3610       } else if (cut.getCutType() == esCutType::OvRmDeltaPhi) {
3611         //std::cout << "OverlapRemovalDeltaPhi Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3612         corrParameter.minOverlapRemovalPhiCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3613         corrParameter.maxOverlapRemovalPhiCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3614         corrParameter.precOverlapRemovalPhiCut = cut.getMinimum().index;
3615         cutType = cutType | 0x20;
3616       } else if (cut.getCutType() == esCutType::OvRmDeltaR) {
3617         //std::cout << "DeltaR Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3618         corrParameter.minOverlapRemovalDRCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3619         corrParameter.maxOverlapRemovalDRCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3620         corrParameter.precOverlapRemovalDRCut = cut.getMinimum().index;
3621         cutType = cutType | 0x40;
3622       }
3623     }
3624   }
3625   corrParameter.corrCutType = cutType;
3626 
3627   // Get the two objects that form the legs
3628   const std::vector<L1TUtmObject>& objects = corrCond.getObjects();
3629   if (objects.size() != 3) {
3630     edm::LogError("TriggerMenuParser")
3631         << "incorrect number of objects for the correlation condition with overlap removal " << name << " corrFlag "
3632         << corrFlag << std::endl;
3633     return false;
3634   }
3635 
3636   // Loop over legs
3637   for (size_t jj = 0; jj < objects.size(); jj++) {
3638     const L1TUtmObject& object = objects.at(jj);
3639     LogDebug("TriggerMenuParser") << "      obj name = " << object.getName() << "\n";
3640     LogDebug("TriggerMenuParser") << "      obj type = " << object.getType() << "\n";
3641     LogDebug("TriggerMenuParser") << "      obj op = " << object.getComparisonOperator() << "\n";
3642     LogDebug("TriggerMenuParser") << "      obj bx = " << object.getBxOffset() << "\n";
3643     LogDebug("TriggerMenuParser") << "type = done" << std::endl;
3644 
3645     // check the leg type
3646     if (object.getType() == esObjectType::Muon) {
3647       // we have a muon
3648 
3649       /*
3650           //BLW Hold on to this code we may need to go back to it at some point.
3651       // Now we are putting ALL leg conditions into the vector (so there are duplicates)
3652       // This is potentially a place to slim down the code.  Note: We currently evaluate the
3653       // conditions every time, so even if we put the condition in the vector once, we would
3654       // still evaluate it multiple times.  This is a place for optimization.
3655           {
3656 
3657               parseMuonCorr(&object,chipNr);
3658           corrIndexVal[jj] = (m_corMuonTemplate[chipNr]).size() - 1;
3659 
3660           } else {
3661          LogDebug("TriggerMenuParser") << "Not Adding Correlation Muon Condition to Map...looking for the condition in Muon Cor Vector" << std::endl;
3662          bool found = false;
3663          int index = 0;
3664          while(!found && index<(int)((m_corMuonTemplate[chipNr]).size()) ) {
3665              if( (m_corMuonTemplate[chipNr]).at(index).condName() == object.getName() ) {
3666             LogDebug("TriggerMenuParser") << "Found condition " << object.getName() << " in vector at index " << index << std::endl;
3667             found = true;
3668          } else {
3669             index++;
3670          }
3671          }
3672          if(found) {
3673             corrIndexVal[jj] = index;
3674          } else {
3675            edm::LogError("TriggerMenuParser") << "FAILURE: Condition " << object.getName() << " is in map but not in cor. vector " << std::endl;
3676          }
3677 
3678       }
3679 */
3680       parseMuonCorr(&object, chipNr);
3681       corrIndexVal[jj] = (m_corMuonTemplate[chipNr]).size() - 1;
3682 
3683       //Now set some flags for this subCondition
3684       intGEq[jj] = (object.getComparisonOperator() == esComparisonOperator::GE);
3685       objType[jj] = gtMu;
3686       condCateg[jj] = CondMuon;
3687 
3688     } else if (object.getType() == esObjectType::Egamma || object.getType() == esObjectType::Jet ||
3689                object.getType() == esObjectType::Tau) {
3690       // we have an Calo object
3691       parseCaloCorr(&object, chipNr);
3692       corrIndexVal[jj] = (m_corCaloTemplate[chipNr]).size() - 1;
3693 
3694       //Now set some flags for this subCondition
3695       intGEq[jj] = (object.getComparisonOperator() == esComparisonOperator::GE);
3696       switch (object.getType()) {
3697         case esObjectType::Egamma: {
3698           objType[jj] = gtEG;
3699         } break;
3700         case esObjectType::Jet: {
3701           objType[jj] = gtJet;
3702         } break;
3703         case esObjectType::Tau: {
3704           objType[jj] = gtTau;
3705         } break;
3706         default: {
3707         } break;
3708       }
3709       condCateg[jj] = CondCalo;
3710 
3711     } else if (object.getType() == esObjectType::ETM || object.getType() == esObjectType::ETMHF ||
3712                object.getType() == esObjectType::HTMHF || object.getType() == esObjectType::TOWERCOUNT ||
3713                object.getType() == esObjectType::HTM) {
3714       // we have Energy Sum
3715       parseEnergySumCorr(&object, chipNr);
3716       corrIndexVal[jj] = (m_corEnergySumTemplate[chipNr]).size() - 1;
3717 
3718       //Now set some flags for this subCondition
3719       intGEq[jj] = (object.getComparisonOperator() == esComparisonOperator::GE);
3720       switch (object.getType()) {
3721         case esObjectType::ETM: {
3722           objType[jj] = GlobalObject::gtETM;
3723         } break;
3724         case esObjectType::HTM: {
3725           objType[jj] = GlobalObject::gtHTM;
3726         } break;
3727         case esObjectType::ETMHF: {
3728           objType[jj] = GlobalObject::gtETMHF;
3729         } break;
3730         case esObjectType::HTMHF: {
3731           objType[jj] = GlobalObject::gtHTMHF;
3732         } break;
3733         case esObjectType::TOWERCOUNT: {
3734           objType[jj] = GlobalObject::gtTowerCount;
3735         } break;
3736         default: {
3737         } break;
3738       }
3739       condCateg[jj] = CondEnergySum;
3740 
3741     } else {
3742       edm::LogError("TriggerMenuParser") << "Illegal Object Type " << object.getType()
3743                                          << " for the correlation condition " << name << std::endl;
3744       return false;
3745 
3746     }  //if block on leg types
3747 
3748   }  //loop over legs
3749 
3750   // get greater equal flag for the correlation condition
3751   bool gEq = true;
3752   if (intGEq[0] != intGEq[1]) {
3753     edm::LogError("TriggerMenuParser") << "Inconsistent GEq flags for sub-conditions "
3754                                        << " for the correlation condition " << name << std::endl;
3755     return false;
3756 
3757   } else {
3758     gEq = (intGEq[0] != 0);
3759   }
3760 
3761   // fill the correlation condition
3762   correlationWORCond.setCondType(cType);
3763   correlationWORCond.setObjectType(objType);
3764   correlationWORCond.setCondGEq(gEq);
3765   correlationWORCond.setCondChipNr(chipNr);
3766 
3767   correlationWORCond.setCond0Category(condCateg[0]);
3768   correlationWORCond.setCond1Category(condCateg[1]);
3769   correlationWORCond.setCond2Category(condCateg[2]);
3770 
3771   correlationWORCond.setCond0Index(corrIndexVal[0]);
3772   correlationWORCond.setCond1Index(corrIndexVal[1]);
3773   correlationWORCond.setCond2Index(corrIndexVal[2]);
3774 
3775   correlationWORCond.setCorrelationWithOverlapRemovalParameter(corrParameter);
3776 
3777   if (edm::isDebugEnabled()) {
3778     std::ostringstream myCoutStream;
3779     correlationWORCond.print(myCoutStream);
3780     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
3781   }
3782 
3783   // insert condition into the map
3784   // condition is not duplicate, check was done at the beginning
3785 
3786   (m_vecCorrelationWithOverlapRemovalTemplate[chipNr]).push_back(correlationWORCond);
3787 
3788   //
3789   return true;
3790 }
3791 
3792 /**
3793  * workAlgorithm - parse the algorithm and insert it into algorithm map.
3794  *
3795  * @param node The corresponding node to the algorithm.
3796  * @param name The name of the algorithm.
3797  * @param chipNr The number of the chip the conditions for that algorithm are located on.
3798  *
3799  * @return "true" on success, "false" if an error occurred.
3800  *
3801  */
3802 
3803 bool l1t::TriggerMenuParser::parseAlgorithm(L1TUtmAlgorithm algorithm, unsigned int chipNr) {
3804   // get alias
3805   std::string algAlias = algorithm.getName();
3806   const std::string& algName = algorithm.getName();
3807 
3808   if (algAlias.empty()) {
3809     algAlias = algName;
3810     LogDebug("TriggerMenuParser") << "\n    No alias defined for algorithm. Alias set to algorithm name."
3811                                   << "\n    Algorithm name:  " << algName << "\n    Algorithm alias: " << algAlias
3812                                   << std::endl;
3813   } else {
3814     //LogDebug("TriggerMenuParser")
3815     LogDebug("TriggerMenuParser") << "\n    Alias defined for algorithm."
3816                                   << "\n    Algorithm name:  " << algName << "\n    Algorithm alias: " << algAlias
3817                                   << std::endl;
3818   }
3819 
3820   // get the logical expression
3821   const std::string& logExpression = algorithm.getExpressionInCondition();
3822 
3823   LogDebug("TriggerMenuParser") << "      Logical expression: " << logExpression
3824                                 << "      Chip number:        " << chipNr << std::endl;
3825 
3826   // determine output pin
3827   int outputPin = algorithm.getIndex();
3828 
3829   //LogTrace("TriggerMenuParser")
3830   LogDebug("TriggerMenuParser") << "      Output pin:         " << outputPin << std::endl;
3831 
3832   // compute the bit number from chip number, output pin and order of the chips
3833   // pin numbering start with 1, bit numbers with 0
3834   int bitNumber = outputPin;  // + (m_orderConditionChip[chipNr] -1)*m_pinsOnConditionChip -1;
3835 
3836   //LogTrace("TriggerMenuParser")
3837   LogDebug("TriggerMenuParser") << "      Bit number:         " << bitNumber << std::endl;
3838 
3839   // create a new algorithm and insert it into algorithm map
3840   GlobalAlgorithm alg(algName, logExpression, bitNumber);
3841   alg.setAlgoChipNumber(static_cast<int>(chipNr));
3842   alg.setAlgoAlias(algAlias);
3843 
3844   if (edm::isDebugEnabled()) {
3845     std::ostringstream myCoutStream;
3846     alg.print(myCoutStream);
3847     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
3848   }
3849 
3850   // insert algorithm into the map
3851   if (!insertAlgorithmIntoMap(alg)) {
3852     return false;
3853   }
3854 
3855   return true;
3856 }
3857 // static class members