Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-07-02 00:53:53

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             etaWindows.push_back({cut.getMinimum().index, cut.getMaximum().index});
1238           } else {
1239             edm::LogError("TriggerMenuParser")
1240                 << "Too Many Eta Cuts for muon-condition (" << particle << ")" << std::endl;
1241             return false;
1242           }
1243         } break;
1244 
1245         case esCutType::Phi: {
1246           if (cntPhi == 0) {
1247             phiWindow1Lower = cut.getMinimum().index;
1248             phiWindow1Upper = cut.getMaximum().index;
1249           } else if (cntPhi == 1) {
1250             phiWindow2Lower = cut.getMinimum().index;
1251             phiWindow2Upper = cut.getMaximum().index;
1252           } else {
1253             edm::LogError("TriggerMenuParser")
1254                 << "Too Many Phi Cuts for muon-condition (" << particle << ")" << std::endl;
1255             return false;
1256           }
1257           cntPhi++;
1258 
1259         } break;
1260 
1261         case esCutType::Charge:
1262           if (cut.getData() == "positive")
1263             charge = 0;
1264           else if (cut.getData() == "negative")
1265             charge = 1;
1266           else
1267             charge = -1;
1268           break;
1269         case esCutType::Quality:
1270 
1271           qualityLUT = l1tstr2int(cut.getData());
1272 
1273           break;
1274         case esCutType::Isolation: {
1275           isolationLUT = l1tstr2int(cut.getData());
1276 
1277         } break;
1278 
1279         case esCutType::Index: {
1280           tfMuonIndexWindows.push_back({cut.getMinimum().index, cut.getMaximum().index});
1281         } break;
1282 
1283         default:
1284           break;
1285       }  //end switch
1286 
1287     }  //end loop over cuts
1288 
1289     // Set the parameter cuts
1290     objParameter[cnt].unconstrainedPtHigh = upperUnconstrainedPtInd;
1291     objParameter[cnt].unconstrainedPtLow = lowerUnconstrainedPtInd;
1292     objParameter[cnt].impactParameterHigh = upperImpactParameterInd;
1293     objParameter[cnt].impactParameterLow = lowerImpactParameterInd;
1294     objParameter[cnt].impactParameterLUT = impactParameterLUT;
1295 
1296     objParameter[cnt].ptHighThreshold = upperThresholdInd;
1297     objParameter[cnt].ptLowThreshold = lowerThresholdInd;
1298 
1299     objParameter[cnt].indexHigh = upperIndexInd;
1300     objParameter[cnt].indexLow = lowerIndexInd;
1301 
1302     objParameter[cnt].etaWindows = etaWindows;
1303 
1304     objParameter[cnt].phiWindow1Lower = phiWindow1Lower;
1305     objParameter[cnt].phiWindow1Upper = phiWindow1Upper;
1306     objParameter[cnt].phiWindow2Lower = phiWindow2Lower;
1307     objParameter[cnt].phiWindow2Upper = phiWindow2Upper;
1308 
1309     // BLW TO DO: Do we need these anymore?  Drop them?
1310     objParameter[cnt].enableMip = false;   //tmpMip[i];
1311     objParameter[cnt].enableIso = false;   //tmpEnableIso[i];
1312     objParameter[cnt].requestIso = false;  //tmpRequestIso[i];
1313 
1314     objParameter[cnt].charge = charge;
1315     objParameter[cnt].qualityLUT = qualityLUT;
1316     objParameter[cnt].isolationLUT = isolationLUT;
1317 
1318     objParameter[cnt].tfMuonIndexWindows = tfMuonIndexWindows;
1319 
1320     cnt++;
1321   }  //end loop over objects
1322 
1323   // object types - all muons
1324   std::vector<GlobalObject> objType(nrObj, gtMu);
1325 
1326   // now create a new CondMuonition
1327   MuonTemplate muonCond(name);
1328 
1329   muonCond.setCondType(cType);
1330   muonCond.setObjectType(objType);
1331   muonCond.setCondGEq(gEq);
1332   muonCond.setCondChipNr(chipNr);
1333   muonCond.setCondRelativeBx(relativeBx);
1334 
1335   muonCond.setConditionParameter(objParameter, corrParameter);
1336 
1337   if (edm::isDebugEnabled()) {
1338     std::ostringstream myCoutStream;
1339     muonCond.print(myCoutStream);
1340     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
1341   }
1342 
1343   // insert condition into the map and into muon template vector
1344   if (!insertConditionIntoMap(muonCond, chipNr)) {
1345     edm::LogError("TriggerMenuParser") << "    Error: duplicate condition (" << name << ")" << std::endl;
1346     return false;
1347   } else {
1348     LogDebug("TriggerMenuParser") << "Added Condition " << name << " to the ConditionMap" << std::endl;
1349     if (corrFlag) {
1350       (m_corMuonTemplate[chipNr]).push_back(muonCond);
1351     } else {
1352       LogDebug("TriggerMenuParser") << "Added Condition " << name << " to the vecMuonTemplate vector" << std::endl;
1353       (m_vecMuonTemplate[chipNr]).push_back(muonCond);
1354     }
1355   }
1356 
1357   //
1358   return true;
1359 }
1360 
1361 bool l1t::TriggerMenuParser::parseMuonCorr(const L1TUtmObject* corrMu, unsigned int chipNr) {
1362   //    XERCES_CPP_NAMESPACE_USE
1363   using namespace tmeventsetup;
1364 
1365   // get condition, particle name (must be muon) and type name
1366   std::string condition = "muon";
1367   std::string particle = "muon";  //l1t2string( condMu.objectType() );
1368   std::string type = l1t2string(corrMu->getType());
1369   std::string name = l1t2string(corrMu->getName());
1370   int nrObj = 1;
1371   type = "1_s";
1372   GtConditionType cType = l1t::Type1s;
1373 
1374   if (nrObj < 0) {
1375     edm::LogError("TriggerMenuParser") << "Unknown type for muon-condition (" << type << ")"
1376                                        << "\nCan not determine number of trigger objects. " << std::endl;
1377     return false;
1378   }
1379 
1380   LogDebug("TriggerMenuParser") << "\n ****************************************** "
1381                                 << "\n      parseMuon  "
1382                                 << "\n condition = " << condition << "\n particle  = " << particle
1383                                 << "\n type      = " << type << "\n name      = " << name << std::endl;
1384 
1385   //     // get values
1386 
1387   // temporary storage of the parameters
1388   std::vector<MuonTemplate::ObjectParameter> objParameter(nrObj);
1389 
1390   // Do we need this?
1391   MuonTemplate::CorrelationParameter corrParameter;
1392 
1393   // need at least two values for deltaPhi
1394   std::vector<uint64_t> tmpValues((nrObj > 2) ? nrObj : 2);
1395   tmpValues.reserve(nrObj);
1396 
1397   // BLW TO DO: How do we deal with these in the new format
1398   //    std::string str_chargeCorrelation = l1t2string( condMu.requestedChargeCorr() );
1399   std::string str_chargeCorrelation = "ig";
1400   unsigned int chargeCorrelation = 0;
1401   if (str_chargeCorrelation == "ig")
1402     chargeCorrelation = 1;
1403   else if (str_chargeCorrelation == "ls")
1404     chargeCorrelation = 2;
1405   else if (str_chargeCorrelation == "os")
1406     chargeCorrelation = 4;
1407 
1408   //getXMLHexTextValue("1", dst);
1409   corrParameter.chargeCorrelation = chargeCorrelation;  //tmpValues[0];
1410 
1411   // BLW TO DO: These needs to the added to the object rather than the whole condition.
1412   int relativeBx = 0;
1413   bool gEq = false;
1414 
1415   //const esObject* object = condMu;
1416   gEq = (corrMu->getComparisonOperator() == esComparisonOperator::GE);
1417 
1418   //  BLW TO DO: This needs to be added to the Object Parameters
1419   relativeBx = corrMu->getBxOffset();
1420 
1421   //  Loop over the cuts for this object
1422   int upperUnconstrainedPtInd = -1;  // Added for displaced muons
1423   int lowerUnconstrainedPtInd = 0;   // Added for displaced muons
1424   int upperImpactParameterInd = -1;  // Added for displaced muons
1425   int lowerImpactParameterInd = 0;   // Added for displaced muons
1426   int impactParameterLUT = 0xF;      // Added for displaced muons, default is to ignore unless specified
1427   int upperThresholdInd = -1;
1428   int lowerThresholdInd = 0;
1429   int upperIndexInd = -1;
1430   int lowerIndexInd = 0;
1431   int cntPhi = 0;
1432   unsigned int phiWindow1Lower = -1, phiWindow1Upper = -1, phiWindow2Lower = -1, phiWindow2Upper = -1;
1433   int isolationLUT = 0xF;   //default is to ignore unless specified.
1434   int charge = -1;          //defaut is to ignore unless specified
1435   int qualityLUT = 0xFFFF;  //default is to ignore unless specified.
1436 
1437   std::vector<MuonTemplate::Window> etaWindows;
1438   std::vector<MuonTemplate::Window> tfMuonIndexWindows;
1439 
1440   const std::vector<L1TUtmCut>& cuts = corrMu->getCuts();
1441   for (size_t kk = 0; kk < cuts.size(); kk++) {
1442     const L1TUtmCut& cut = cuts.at(kk);
1443 
1444     switch (cut.getCutType()) {
1445       case esCutType::UnconstrainedPt:  // Added for displaced muons
1446         lowerUnconstrainedPtInd = cut.getMinimum().index;
1447         upperUnconstrainedPtInd = cut.getMaximum().index;
1448         break;
1449 
1450       case esCutType::ImpactParameter:  // Added for displaced muons
1451         lowerImpactParameterInd = cut.getMinimum().index;
1452         upperImpactParameterInd = cut.getMaximum().index;
1453         impactParameterLUT = l1tstr2int(cut.getData());
1454         break;
1455 
1456       case esCutType::Threshold:
1457         lowerThresholdInd = cut.getMinimum().index;
1458         upperThresholdInd = cut.getMaximum().index;
1459         break;
1460 
1461       case esCutType::Slice:
1462         lowerIndexInd = int(cut.getMinimum().value);
1463         upperIndexInd = int(cut.getMaximum().value);
1464         break;
1465 
1466       case esCutType::Eta: {
1467         if (etaWindows.size() < 5) {
1468           etaWindows.push_back({cut.getMinimum().index, cut.getMaximum().index});
1469         } else {
1470           edm::LogError("TriggerMenuParser")
1471               << "Too Many Eta Cuts for muon-condition (" << particle << ")" << std::endl;
1472           return false;
1473         }
1474       } break;
1475 
1476       case esCutType::Phi: {
1477         if (cntPhi == 0) {
1478           phiWindow1Lower = cut.getMinimum().index;
1479           phiWindow1Upper = cut.getMaximum().index;
1480         } else if (cntPhi == 1) {
1481           phiWindow2Lower = cut.getMinimum().index;
1482           phiWindow2Upper = cut.getMaximum().index;
1483         } else {
1484           edm::LogError("TriggerMenuParser")
1485               << "Too Many Phi Cuts for muon-condition (" << particle << ")" << std::endl;
1486           return false;
1487         }
1488         cntPhi++;
1489 
1490       } break;
1491 
1492       case esCutType::Charge:
1493         if (cut.getData() == "positive")
1494           charge = 0;
1495         else if (cut.getData() == "negative")
1496           charge = 1;
1497         else
1498           charge = -1;
1499         break;
1500       case esCutType::Quality:
1501 
1502         qualityLUT = l1tstr2int(cut.getData());
1503 
1504         break;
1505       case esCutType::Isolation: {
1506         isolationLUT = l1tstr2int(cut.getData());
1507 
1508       } break;
1509 
1510       case esCutType::Index: {
1511         tfMuonIndexWindows.push_back({cut.getMinimum().index, cut.getMaximum().index});
1512       } break;
1513 
1514       default:
1515         break;
1516     }  //end switch
1517 
1518   }  //end loop over cuts
1519 
1520   // Set the parameter cuts
1521   objParameter[0].unconstrainedPtHigh = upperUnconstrainedPtInd;  // Added for displacd muons
1522   objParameter[0].unconstrainedPtLow = lowerUnconstrainedPtInd;   // Added for displacd muons
1523   objParameter[0].impactParameterHigh = upperImpactParameterInd;  // Added for displacd muons
1524   objParameter[0].impactParameterLow = lowerImpactParameterInd;   // Added for displacd muons
1525   objParameter[0].impactParameterLUT = impactParameterLUT;        // Added for displacd muons
1526 
1527   objParameter[0].ptHighThreshold = upperThresholdInd;
1528   objParameter[0].ptLowThreshold = lowerThresholdInd;
1529 
1530   objParameter[0].indexHigh = upperIndexInd;
1531   objParameter[0].indexLow = lowerIndexInd;
1532 
1533   objParameter[0].etaWindows = etaWindows;
1534 
1535   objParameter[0].phiWindow1Lower = phiWindow1Lower;
1536   objParameter[0].phiWindow1Upper = phiWindow1Upper;
1537   objParameter[0].phiWindow2Lower = phiWindow2Lower;
1538   objParameter[0].phiWindow2Upper = phiWindow2Upper;
1539 
1540   // BLW TO DO: Do we need these anymore?  Drop them?
1541   objParameter[0].enableMip = false;   //tmpMip[i];
1542   objParameter[0].enableIso = false;   //tmpEnableIso[i];
1543   objParameter[0].requestIso = false;  //tmpRequestIso[i];
1544 
1545   objParameter[0].charge = charge;
1546   objParameter[0].qualityLUT = qualityLUT;
1547   objParameter[0].isolationLUT = isolationLUT;
1548 
1549   objParameter[0].tfMuonIndexWindows = tfMuonIndexWindows;
1550 
1551   // object types - all muons
1552   std::vector<GlobalObject> objType(nrObj, gtMu);
1553 
1554   // now create a new CondMuonition
1555   MuonTemplate muonCond(name);
1556 
1557   muonCond.setCondType(cType);
1558   muonCond.setObjectType(objType);
1559   muonCond.setCondGEq(gEq);
1560   muonCond.setCondChipNr(chipNr);
1561   muonCond.setCondRelativeBx(relativeBx);
1562   muonCond.setConditionParameter(objParameter, corrParameter);
1563 
1564   if (edm::isDebugEnabled()) {
1565     std::ostringstream myCoutStream;
1566     muonCond.print(myCoutStream);
1567     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
1568   }
1569 
1570   /*
1571     // insert condition into the map and into muon template vector
1572     if ( !insertConditionIntoMap(muonCond, chipNr)) {
1573         edm::LogError("TriggerMenuParser")
1574                 << "    Error: duplicate condition (" << name << ")"
1575                 << std::endl;
1576         return false;
1577     }
1578     else {
1579         LogDebug("TriggerMenuParser") << "Added Condition " << name << " to the ConditionMap" << std::endl;
1580             (m_corMuonTemplate[chipNr]).push_back(muonCond);
1581     }
1582 */
1583   (m_corMuonTemplate[chipNr]).push_back(muonCond);
1584 
1585   //
1586   return true;
1587 }
1588 
1589 /**
1590  * parseMuonShower Parse a muonShower condition and insert an entry to the conditions map
1591  *
1592  * @param node The corresponding node.
1593  * @param name The name of the condition.
1594  * @param chipNr The number of the chip this condition is located.
1595  *
1596  * @return "true" if succeeded, "false" if an error occurred.
1597  *
1598  */
1599 
1600 bool l1t::TriggerMenuParser::parseMuonShower(L1TUtmCondition condMu, unsigned int chipNr, const bool corrFlag) {
1601   using namespace tmeventsetup;
1602 
1603   // get condition, particle name (must be muon) and type name
1604   std::string condition = "muonShower";
1605   std::string particle = "muonShower";  //l1t2string( condMu.objectType() );
1606   std::string type = l1t2string(condMu.getType());
1607   std::string name = l1t2string(condMu.getName());
1608   // the number of muon shower objects is always 1
1609   int nrObj = 1;
1610 
1611   // condition type is always 1 particle, thus Type1s
1612   GtConditionType cType = l1t::Type1s;
1613 
1614   // temporary storage of the parameters
1615   std::vector<MuonShowerTemplate::ObjectParameter> objParameter(nrObj);
1616 
1617   if (int(condMu.getObjects().size()) != nrObj) {
1618     edm::LogError("TriggerMenuParser") << " condMu objects: nrObj = " << nrObj
1619                                        << "condMu.getObjects().size() = " << condMu.getObjects().size() << std::endl;
1620     return false;
1621   }
1622 
1623   // Get the muon shower object
1624   L1TUtmObject object = condMu.getObjects().at(0);
1625   int relativeBx = object.getBxOffset();
1626 
1627   if (condMu.getType() == esConditionType::MuonShower0) {
1628     objParameter[0].MuonShower0 = true;
1629   } else if (condMu.getType() == esConditionType::MuonShower1) {
1630     objParameter[0].MuonShower1 = true;
1631   } else if (condMu.getType() == esConditionType::MuonShower2) {
1632     objParameter[0].MuonShower2 = true;
1633   } else if (condMu.getType() == esConditionType::MuonShowerOutOfTime0) {
1634     objParameter[0].MuonShowerOutOfTime0 = true;
1635   } else if (condMu.getType() == esConditionType::MuonShowerOutOfTime1) {
1636     objParameter[0].MuonShowerOutOfTime1 = true;
1637   }
1638 
1639   // object types - all muons
1640   std::vector<GlobalObject> objType(nrObj, gtMuShower);
1641 
1642   // now create a new CondMuonition
1643   MuonShowerTemplate muonShowerCond(name);
1644   muonShowerCond.setCondType(cType);
1645   muonShowerCond.setObjectType(objType);
1646   muonShowerCond.setCondChipNr(chipNr);
1647   muonShowerCond.setCondRelativeBx(relativeBx);
1648 
1649   muonShowerCond.setConditionParameter(objParameter);
1650 
1651   if (edm::isDebugEnabled()) {
1652     std::ostringstream myCoutStream;
1653     muonShowerCond.print(myCoutStream);
1654   }
1655 
1656   // insert condition into the map and into muon template vector
1657   if (!insertConditionIntoMap(muonShowerCond, chipNr)) {
1658     edm::LogError("TriggerMenuParser") << "    Error: duplicate condition (" << name << ")" << std::endl;
1659     return false;
1660   } else {
1661     (m_vecMuonShowerTemplate[chipNr]).push_back(muonShowerCond);
1662   }
1663 
1664   return true;
1665 }
1666 
1667 /**
1668  * parseCalo Parse a calo condition and insert an entry to the conditions map
1669  *
1670  * @param node The corresponding node.
1671  * @param name The name of the condition.
1672  * @param chipNr The number of the chip this condition is located.
1673  *
1674  * @return "true" if succeeded, "false" if an error occurred.
1675  *
1676  */
1677 
1678 bool l1t::TriggerMenuParser::parseCalo(L1TUtmCondition condCalo, unsigned int chipNr, const bool corrFlag) {
1679   //    XERCES_CPP_NAMESPACE_USE
1680   using namespace tmeventsetup;
1681 
1682   // get condition, particle name and type name
1683 
1684   std::string condition = "calo";
1685   std::string particle = "test-fix";
1686   std::string type = l1t2string(condCalo.getType());
1687   std::string name = l1t2string(condCalo.getName());
1688 
1689   LogDebug("TriggerMenuParser") << "\n ****************************************** "
1690                                 << "\n      (in parseCalo) "
1691                                 << "\n condition = " << condition << "\n particle  = " << particle
1692                                 << "\n type      = " << type << "\n name      = " << name << std::endl;
1693 
1694   GtConditionType cType = l1t::TypeNull;
1695 
1696   // determine object type type
1697   // BLW TO DO:  Can this object type wait and be done later in the parsing. Or done differently completely..
1698   GlobalObject caloObjType;
1699   int nrObj = -1;
1700 
1701   if (condCalo.getType() == esConditionType::SingleEgamma) {
1702     caloObjType = gtEG;
1703     type = "1_s";
1704     cType = l1t::Type1s;
1705     nrObj = 1;
1706   } else if (condCalo.getType() == esConditionType::DoubleEgamma) {
1707     caloObjType = gtEG;
1708     type = "2_s";
1709     cType = l1t::Type2s;
1710     nrObj = 2;
1711   } else if (condCalo.getType() == esConditionType::TripleEgamma) {
1712     caloObjType = gtEG;
1713     cType = l1t::Type3s;
1714     type = "3";
1715     nrObj = 3;
1716   } else if (condCalo.getType() == esConditionType::QuadEgamma) {
1717     caloObjType = gtEG;
1718     cType = l1t::Type4s;
1719     type = "4";
1720     nrObj = 4;
1721   } else if (condCalo.getType() == esConditionType::SingleJet) {
1722     caloObjType = gtJet;
1723     cType = l1t::Type1s;
1724     type = "1_s";
1725     nrObj = 1;
1726   } else if (condCalo.getType() == esConditionType::DoubleJet) {
1727     caloObjType = gtJet;
1728     cType = l1t::Type2s;
1729     type = "2_s";
1730     nrObj = 2;
1731   } else if (condCalo.getType() == esConditionType::TripleJet) {
1732     caloObjType = gtJet;
1733     cType = l1t::Type3s;
1734     type = "3";
1735     nrObj = 3;
1736   } else if (condCalo.getType() == esConditionType::QuadJet) {
1737     caloObjType = gtJet;
1738     cType = l1t::Type4s;
1739     type = "4";
1740     nrObj = 4;
1741   } else if (condCalo.getType() == esConditionType::SingleTau) {
1742     caloObjType = gtTau;
1743     cType = l1t::Type1s;
1744     type = "1_s";
1745     nrObj = 1;
1746   } else if (condCalo.getType() == esConditionType::DoubleTau) {
1747     caloObjType = gtTau;
1748     cType = l1t::Type2s;
1749     type = "2_s";
1750     nrObj = 2;
1751   } else if (condCalo.getType() == esConditionType::TripleTau) {
1752     caloObjType = gtTau;
1753     cType = l1t::Type3s;
1754     type = "3";
1755     nrObj = 3;
1756   } else if (condCalo.getType() == esConditionType::QuadTau) {
1757     caloObjType = gtTau;
1758     cType = l1t::Type4s;
1759     type = "4";
1760     nrObj = 4;
1761   } else {
1762     edm::LogError("TriggerMenuParser") << "Wrong particle for calo-condition (" << particle << ")" << std::endl;
1763     return false;
1764   }
1765 
1766   //    std::string str_etComparison = l1t2string( condCalo.comparison_operator() );
1767 
1768   if (nrObj < 0) {
1769     edm::LogError("TriggerMenuParser") << "Unknown type for calo-condition (" << type << ")"
1770                                        << "\nCan not determine number of trigger objects. " << std::endl;
1771     return false;
1772   }
1773 
1774   // get values
1775 
1776   // temporary storage of the parameters
1777   std::vector<CaloTemplate::ObjectParameter> objParameter(nrObj);
1778 
1779   //BLW TO DO:  Can this be dropped?
1780   CaloTemplate::CorrelationParameter corrParameter;
1781 
1782   // need at least one value for deltaPhiRange
1783   std::vector<uint64_t> tmpValues((nrObj > 1) ? nrObj : 1);
1784   tmpValues.reserve(nrObj);
1785 
1786   if (int(condCalo.getObjects().size()) != nrObj) {
1787     edm::LogError("TriggerMenuParser") << " condCalo objects: nrObj = " << nrObj
1788                                        << "condCalo.getObjects().size() = " << condCalo.getObjects().size()
1789                                        << std::endl;
1790     return false;
1791   }
1792 
1793   //    std::string str_condCalo = "";
1794   //    uint64_t tempUIntH, tempUIntL;
1795   //    uint64_t dst;
1796   int cnt = 0;
1797 
1798   // BLW TO DO: These needs to the added to the object rather than the whole condition.
1799   int relativeBx = 0;
1800   bool gEq = false;
1801 
1802   // Loop over objects and extract the cuts on the objects
1803   const std::vector<L1TUtmObject>& objects = condCalo.getObjects();
1804   for (size_t jj = 0; jj < objects.size(); jj++) {
1805     const L1TUtmObject& object = objects.at(jj);
1806     gEq = (object.getComparisonOperator() == esComparisonOperator::GE);
1807 
1808     //  BLW TO DO: This needs to be added to the Object Parameters
1809     relativeBx = object.getBxOffset();
1810 
1811     //  Loop over the cuts for this object
1812     int upperThresholdInd = -1;
1813     int lowerThresholdInd = 0;
1814     int upperIndexInd = -1;
1815     int lowerIndexInd = 0;
1816     int cntPhi = 0;
1817     unsigned int phiWindow1Lower = -1, phiWindow1Upper = -1, phiWindow2Lower = -1, phiWindow2Upper = -1;
1818     int isolationLUT = 0xF;  //default is to ignore isolation unless specified.
1819     int qualityLUT = 0xF;    //default is to ignore quality unless specified.
1820     int displacedLUT = 0x0;  // Added for LLP Jets: single bit LUT: { 0 = noLLP default, 1 = LLP }
1821                              // Note: Currently assumes that the LSB from hwQual() getter in L1Candidate provides the
1822                              // (single bit) information for the displacedLUT
1823 
1824     std::vector<CaloTemplate::Window> etaWindows;
1825 
1826     const std::vector<L1TUtmCut>& cuts = object.getCuts();
1827     for (size_t kk = 0; kk < cuts.size(); kk++) {
1828       const L1TUtmCut& cut = cuts.at(kk);
1829 
1830       switch (cut.getCutType()) {
1831         case esCutType::Threshold:
1832           lowerThresholdInd = cut.getMinimum().index;
1833           upperThresholdInd = cut.getMaximum().index;
1834           break;
1835         case esCutType::Slice:
1836           lowerIndexInd = int(cut.getMinimum().value);
1837           upperIndexInd = int(cut.getMaximum().value);
1838           break;
1839         case esCutType::Eta: {
1840           if (etaWindows.size() < 5) {
1841             etaWindows.push_back({cut.getMinimum().index, cut.getMaximum().index});
1842           } else {
1843             edm::LogError("TriggerMenuParser")
1844                 << "Too Many Eta Cuts for calo-condition (" << particle << ")" << std::endl;
1845             return false;
1846           }
1847         } break;
1848 
1849         case esCutType::Phi: {
1850           if (cntPhi == 0) {
1851             phiWindow1Lower = cut.getMinimum().index;
1852             phiWindow1Upper = cut.getMaximum().index;
1853           } else if (cntPhi == 1) {
1854             phiWindow2Lower = cut.getMinimum().index;
1855             phiWindow2Upper = cut.getMaximum().index;
1856           } else {
1857             edm::LogError("TriggerMenuParser")
1858                 << "Too Many Phi Cuts for calo-condition (" << particle << ")" << std::endl;
1859             return false;
1860           }
1861           cntPhi++;
1862 
1863         } break;
1864 
1865         case esCutType::Charge: {
1866           edm::LogError("TriggerMenuParser") << "No charge cut for calo-condition (" << particle << ")" << std::endl;
1867           return false;
1868 
1869         } break;
1870         case esCutType::Quality: {
1871           qualityLUT = l1tstr2int(cut.getData());
1872 
1873         } break;
1874         case esCutType::Displaced: {  // Added for LLP Jets
1875           displacedLUT = l1tstr2int(cut.getData());
1876 
1877         } break;
1878         case esCutType::Isolation: {
1879           isolationLUT = l1tstr2int(cut.getData());
1880 
1881         } break;
1882         default:
1883           break;
1884       }  //end switch
1885 
1886     }  //end loop over cuts
1887 
1888     // Fill the object parameters
1889     objParameter[cnt].etHighThreshold = upperThresholdInd;
1890     objParameter[cnt].etLowThreshold = lowerThresholdInd;
1891     objParameter[cnt].indexHigh = upperIndexInd;
1892     objParameter[cnt].indexLow = lowerIndexInd;
1893     objParameter[cnt].etaWindows = etaWindows;
1894     objParameter[cnt].phiWindow1Lower = phiWindow1Lower;
1895     objParameter[cnt].phiWindow1Upper = phiWindow1Upper;
1896     objParameter[cnt].phiWindow2Lower = phiWindow2Lower;
1897     objParameter[cnt].phiWindow2Upper = phiWindow2Upper;
1898     objParameter[cnt].isolationLUT = isolationLUT;
1899     objParameter[cnt].qualityLUT = qualityLUT;      //TO DO: Must add
1900     objParameter[cnt].displacedLUT = displacedLUT;  // Added for LLP Jets
1901 
1902     // Output for debugging
1903     {
1904       std::ostringstream oss;
1905       oss << "\n      Calo ET high thresholds (hex) for calo object " << caloObjType << " " << cnt << " = " << std::hex
1906           << objParameter[cnt].etLowThreshold << " - " << objParameter[cnt].etHighThreshold;
1907       for (const auto& window : objParameter[cnt].etaWindows) {
1908         oss << "\n      etaWindow Lower / Upper for calo object " << cnt << " = 0x" << window.lower << " / 0x"
1909             << window.upper;
1910       }
1911       oss << "\n      phiWindow Lower / Upper for calo object " << cnt << " = 0x" << objParameter[cnt].phiWindow1Lower
1912           << " / 0x" << objParameter[cnt].phiWindow1Upper << "\n      phiWindowVeto Lower / Upper for calo object "
1913           << cnt << " = 0x" << objParameter[cnt].phiWindow2Lower << " / 0x" << objParameter[cnt].phiWindow2Upper
1914           << "\n      Isolation LUT for calo object " << cnt << " = 0x" << objParameter[cnt].isolationLUT
1915           << "\n      Quality LUT for calo object " << cnt << " = 0x" << objParameter[cnt].qualityLUT
1916           << "\n      LLP DISP LUT for calo object " << cnt << " = 0x" << objParameter[cnt].displacedLUT;
1917       LogDebug("TriggerMenuParser") << oss.str() << std::endl;
1918     }
1919 
1920     cnt++;
1921   }  //end loop over objects
1922 
1923   // object types - all same caloObjType
1924   std::vector<GlobalObject> objType(nrObj, caloObjType);
1925 
1926   // now create a new calo condition
1927   CaloTemplate caloCond(name);
1928 
1929   caloCond.setCondType(cType);
1930   caloCond.setObjectType(objType);
1931 
1932   //BLW TO DO: This needs to be added to the object rather than the whole condition
1933   caloCond.setCondGEq(gEq);
1934   caloCond.setCondChipNr(chipNr);
1935 
1936   //BLW TO DO: This needs to be added to the object rather than the whole condition
1937   caloCond.setCondRelativeBx(relativeBx);
1938 
1939   caloCond.setConditionParameter(objParameter, corrParameter);
1940 
1941   if (edm::isDebugEnabled()) {
1942     std::ostringstream myCoutStream;
1943     caloCond.print(myCoutStream);
1944     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
1945   }
1946 
1947   // insert condition into the map
1948   if (!insertConditionIntoMap(caloCond, chipNr)) {
1949     edm::LogError("TriggerMenuParser") << "    Error: duplicate condition (" << name << ")" << std::endl;
1950 
1951     return false;
1952   } else {
1953     if (corrFlag) {
1954       (m_corCaloTemplate[chipNr]).push_back(caloCond);
1955     } else {
1956       (m_vecCaloTemplate[chipNr]).push_back(caloCond);
1957     }
1958   }
1959 
1960   //
1961   return true;
1962 }
1963 
1964 /**
1965  * parseCalo Parse a calo condition and insert an entry to the conditions map
1966  *
1967  * @param node The corresponding node.
1968  * @param name The name of the condition.
1969  * @param chipNr The number of the chip this condition is located.
1970  *
1971  * @return "true" if succeeded, "false" if an error occurred.
1972  *
1973  */
1974 
1975 bool l1t::TriggerMenuParser::parseCaloCorr(const L1TUtmObject* corrCalo, unsigned int chipNr) {
1976   //    XERCES_CPP_NAMESPACE_USE
1977   using namespace tmeventsetup;
1978 
1979   // get condition, particle name and type name
1980 
1981   std::string condition = "calo";
1982   std::string particle = "test-fix";
1983   std::string type = l1t2string(corrCalo->getType());
1984   std::string name = l1t2string(corrCalo->getName());
1985 
1986   LogDebug("TriggerMenuParser") << "\n ****************************************** "
1987                                 << "\n      (in parseCalo) "
1988                                 << "\n condition = " << condition << "\n particle  = " << particle
1989                                 << "\n type      = " << type << "\n name      = " << name << std::endl;
1990 
1991   // determine object type type
1992   // BLW TO DO:  Can this object type wait and be done later in the parsing. Or done differently completely..
1993   GlobalObject caloObjType;
1994   int nrObj = 1;
1995   type = "1_s";
1996   GtConditionType cType = l1t::Type1s;
1997 
1998   if (corrCalo->getType() == esObjectType::Egamma) {
1999     caloObjType = gtEG;
2000   } else if (corrCalo->getType() == esObjectType::Jet) {
2001     caloObjType = gtJet;
2002   } else if (corrCalo->getType() == esObjectType::Tau) {
2003     caloObjType = gtTau;
2004   } else {
2005     edm::LogError("TriggerMenuParser") << "Wrong particle for calo-condition (" << particle << ")" << std::endl;
2006     return false;
2007   }
2008 
2009   //    std::string str_etComparison = l1t2string( condCalo.comparison_operator() );
2010 
2011   if (nrObj < 0) {
2012     edm::LogError("TriggerMenuParser") << "Unknown type for calo-condition (" << type << ")"
2013                                        << "\nCan not determine number of trigger objects. " << std::endl;
2014     return false;
2015   }
2016 
2017   // get values
2018 
2019   // temporary storage of the parameters
2020   std::vector<CaloTemplate::ObjectParameter> objParameter(nrObj);
2021 
2022   //BLW TO DO:  Can this be dropped?
2023   CaloTemplate::CorrelationParameter corrParameter;
2024 
2025   // need at least one value for deltaPhiRange
2026   std::vector<uint64_t> tmpValues((nrObj > 1) ? nrObj : 1);
2027   tmpValues.reserve(nrObj);
2028 
2029   // BLW TO DO: These needs to the added to the object rather than the whole condition.
2030   int relativeBx = 0;
2031   bool gEq = false;
2032 
2033   gEq = (corrCalo->getComparisonOperator() == esComparisonOperator::GE);
2034 
2035   //  BLW TO DO: This needs to be added to the Object Parameters
2036   relativeBx = corrCalo->getBxOffset();
2037 
2038   //  Loop over the cuts for this object
2039   int upperThresholdInd = -1;
2040   int lowerThresholdInd = 0;
2041   int upperIndexInd = -1;
2042   int lowerIndexInd = 0;
2043   int cntPhi = 0;
2044   unsigned int phiWindow1Lower = -1, phiWindow1Upper = -1, phiWindow2Lower = -1, phiWindow2Upper = -1;
2045   int isolationLUT = 0xF;  //default is to ignore isolation unless specified.
2046   int qualityLUT = 0xF;    //default is to ignore quality unless specified.
2047   int displacedLUT = 0x0;  // Added for LLP Jets:  single bit LUT:  { 0 = noLLP default, 1 = LLP }
2048                            // Note:  Currently assume that the hwQual() getter in L1Candidate provides the
2049                            //        (single bit) information for the displacedLUT
2050 
2051   std::vector<CaloTemplate::Window> etaWindows;
2052 
2053   const std::vector<L1TUtmCut>& cuts = corrCalo->getCuts();
2054   for (size_t kk = 0; kk < cuts.size(); kk++) {
2055     const L1TUtmCut& cut = cuts.at(kk);
2056 
2057     switch (cut.getCutType()) {
2058       case esCutType::Threshold:
2059         lowerThresholdInd = cut.getMinimum().index;
2060         upperThresholdInd = cut.getMaximum().index;
2061         break;
2062       case esCutType::Slice:
2063         lowerIndexInd = int(cut.getMinimum().value);
2064         upperIndexInd = int(cut.getMaximum().value);
2065         break;
2066       case esCutType::Eta: {
2067         if (etaWindows.size() < 5) {
2068           etaWindows.push_back({cut.getMinimum().index, cut.getMaximum().index});
2069         } else {
2070           edm::LogError("TriggerMenuParser")
2071               << "Too Many Eta Cuts for calo-condition (" << particle << ")" << std::endl;
2072           return false;
2073         }
2074       } break;
2075 
2076       case esCutType::Phi: {
2077         if (cntPhi == 0) {
2078           phiWindow1Lower = cut.getMinimum().index;
2079           phiWindow1Upper = cut.getMaximum().index;
2080         } else if (cntPhi == 1) {
2081           phiWindow2Lower = cut.getMinimum().index;
2082           phiWindow2Upper = cut.getMaximum().index;
2083         } else {
2084           edm::LogError("TriggerMenuParser")
2085               << "Too Many Phi Cuts for calo-condition (" << particle << ")" << std::endl;
2086           return false;
2087         }
2088         cntPhi++;
2089 
2090       } break;
2091 
2092       case esCutType::Charge: {
2093         edm::LogError("TriggerMenuParser") << "No charge cut for calo-condition (" << particle << ")" << std::endl;
2094         return false;
2095 
2096       } break;
2097       case esCutType::Quality: {
2098         qualityLUT = l1tstr2int(cut.getData());
2099 
2100       } break;
2101       case esCutType::Displaced: {  // Added for LLP Jets
2102         displacedLUT = l1tstr2int(cut.getData());
2103 
2104       } break;
2105       case esCutType::Isolation: {
2106         isolationLUT = l1tstr2int(cut.getData());
2107 
2108       } break;
2109       default:
2110         break;
2111     }  //end switch
2112 
2113   }  //end loop over cuts
2114 
2115   // Fill the object parameters
2116   objParameter[0].etLowThreshold = lowerThresholdInd;
2117   objParameter[0].etHighThreshold = upperThresholdInd;
2118   objParameter[0].indexHigh = upperIndexInd;
2119   objParameter[0].indexLow = lowerIndexInd;
2120   objParameter[0].etaWindows = etaWindows;
2121   objParameter[0].phiWindow1Lower = phiWindow1Lower;
2122   objParameter[0].phiWindow1Upper = phiWindow1Upper;
2123   objParameter[0].phiWindow2Lower = phiWindow2Lower;
2124   objParameter[0].phiWindow2Upper = phiWindow2Upper;
2125   objParameter[0].isolationLUT = isolationLUT;
2126   objParameter[0].qualityLUT = qualityLUT;      //TO DO: Must add
2127   objParameter[0].displacedLUT = displacedLUT;  // Added for LLP Jets
2128 
2129   // Output for debugging
2130   {
2131     std::ostringstream oss;
2132     oss << "\n      Calo ET high threshold (hex) for calo object " << caloObjType << " "
2133         << " = " << std::hex << objParameter[0].etLowThreshold << " - " << objParameter[0].etHighThreshold;
2134     for (const auto& window : objParameter[0].etaWindows) {
2135       oss << "\n      etaWindow Lower / Upper for calo object "
2136           << " = 0x" << window.lower << " / 0x" << window.upper;
2137     }
2138     oss << "\n      phiWindow Lower / Upper for calo object "
2139         << " = 0x" << objParameter[0].phiWindow1Lower << " / 0x" << objParameter[0].phiWindow1Upper
2140         << "\n      phiWindowVeto Lower / Upper for calo object "
2141         << " = 0x" << objParameter[0].phiWindow2Lower << " / 0x" << objParameter[0].phiWindow2Upper
2142         << "\n      Isolation LUT for calo object "
2143         << " = 0x" << objParameter[0].isolationLUT << "\n      Quality LUT for calo object "
2144         << " = 0x" << objParameter[0].qualityLUT << "\n      LLP DISP LUT for calo object "
2145         << " = 0x" << objParameter[0].displacedLUT;
2146     LogDebug("TriggerMenuParser") << oss.str() << std::endl;
2147   }
2148 
2149   // object types - all same caloObjType
2150   std::vector<GlobalObject> objType(nrObj, caloObjType);
2151 
2152   // now create a new calo condition
2153   CaloTemplate caloCond(name);
2154 
2155   caloCond.setCondType(cType);
2156   caloCond.setObjectType(objType);
2157 
2158   //BLW TO DO: This needs to be added to the object rather than the whole condition
2159   caloCond.setCondGEq(gEq);
2160   caloCond.setCondChipNr(chipNr);
2161 
2162   //BLW TO DO: This needs to be added to the object rather than the whole condition
2163   caloCond.setCondRelativeBx(relativeBx);
2164 
2165   caloCond.setConditionParameter(objParameter, corrParameter);
2166 
2167   if (edm::isDebugEnabled()) {
2168     std::ostringstream myCoutStream;
2169     caloCond.print(myCoutStream);
2170     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
2171   }
2172 
2173   /*
2174     // insert condition into the map
2175     if ( !insertConditionIntoMap(caloCond, chipNr)) {
2176 
2177         edm::LogError("TriggerMenuParser")
2178                 << "    Error: duplicate condition (" << name << ")"
2179                 << std::endl;
2180 
2181         return false;
2182     }
2183     else {
2184             (m_corCaloTemplate[chipNr]).push_back(caloCond);
2185     }
2186 */
2187   (m_corCaloTemplate[chipNr]).push_back(caloCond);
2188 
2189   //
2190   return true;
2191 }
2192 
2193 /**
2194  * parseEnergySum Parse an "energy sum" condition and insert an entry to the conditions map
2195  *
2196  * @param node The corresponding node.
2197  * @param name The name of the condition.
2198  * @param chipNr The number of the chip this condition is located.
2199  *
2200  * @return "true" if succeeded, "false" if an error occurred.
2201  *
2202  */
2203 
2204 bool l1t::TriggerMenuParser::parseEnergySum(L1TUtmCondition condEnergySum, unsigned int chipNr, const bool corrFlag) {
2205   //    XERCES_CPP_NAMESPACE_USE
2206   using namespace tmeventsetup;
2207 
2208   // get condition, particle name and type name
2209 
2210   std::string condition = "calo";
2211   std::string type = l1t2string(condEnergySum.getType());
2212   std::string name = l1t2string(condEnergySum.getName());
2213 
2214   LogDebug("TriggerMenuParser") << "\n ****************************************** "
2215                                 << "\n      (in parseEnergySum) "
2216                                 << "\n condition = " << condition << "\n type      = " << type
2217                                 << "\n name      = " << name << std::endl;
2218 
2219   // determine object type type
2220   GlobalObject energySumObjType;
2221   GtConditionType cType;
2222 
2223   if (condEnergySum.getType() == esConditionType::MissingEt) {
2224     energySumObjType = GlobalObject::gtETM;
2225     cType = TypeETM;
2226   } else if (condEnergySum.getType() == esConditionType::TotalEt) {
2227     energySumObjType = GlobalObject::gtETT;
2228     cType = TypeETT;
2229   } else if (condEnergySum.getType() == esConditionType::TotalEtEM) {
2230     energySumObjType = GlobalObject::gtETTem;
2231     cType = TypeETTem;
2232   } else if (condEnergySum.getType() == esConditionType::TotalHt) {
2233     energySumObjType = GlobalObject::gtHTT;
2234     cType = TypeHTT;
2235   } else if (condEnergySum.getType() == esConditionType::MissingHt) {
2236     energySumObjType = GlobalObject::gtHTM;
2237     cType = TypeHTM;
2238   } else if (condEnergySum.getType() == esConditionType::MissingEtHF) {
2239     energySumObjType = GlobalObject::gtETMHF;
2240     cType = TypeETMHF;
2241   } else if (condEnergySum.getType() == esConditionType::MissingHtHF) {
2242     energySumObjType = GlobalObject::gtHTMHF;
2243     cType = TypeHTMHF;
2244   } else if (condEnergySum.getType() == esConditionType::TowerCount) {
2245     energySumObjType = GlobalObject::gtTowerCount;
2246     cType = TypeTowerCount;
2247   } else if (condEnergySum.getType() == esConditionType::MinBiasHFP0) {
2248     energySumObjType = GlobalObject::gtMinBiasHFP0;
2249     cType = TypeMinBiasHFP0;
2250   } else if (condEnergySum.getType() == esConditionType::MinBiasHFM0) {
2251     energySumObjType = GlobalObject::gtMinBiasHFM0;
2252     cType = TypeMinBiasHFM0;
2253   } else if (condEnergySum.getType() == esConditionType::MinBiasHFP1) {
2254     energySumObjType = GlobalObject::gtMinBiasHFP1;
2255     cType = TypeMinBiasHFP1;
2256   } else if (condEnergySum.getType() == esConditionType::MinBiasHFM1) {
2257     energySumObjType = GlobalObject::gtMinBiasHFM1;
2258     cType = TypeMinBiasHFM1;
2259   } else if (condEnergySum.getType() == esConditionType::AsymmetryEt) {
2260     energySumObjType = GlobalObject::gtAsymmetryEt;
2261     cType = TypeAsymEt;
2262   } else if (condEnergySum.getType() == esConditionType::AsymmetryHt) {
2263     energySumObjType = GlobalObject::gtAsymmetryHt;
2264     cType = TypeAsymHt;
2265   } else if (condEnergySum.getType() == esConditionType::AsymmetryEtHF) {
2266     energySumObjType = GlobalObject::gtAsymmetryEtHF;
2267     cType = TypeAsymEtHF;
2268   } else if (condEnergySum.getType() == esConditionType::AsymmetryHtHF) {
2269     energySumObjType = GlobalObject::gtAsymmetryHtHF;
2270     cType = TypeAsymHtHF;
2271   } else if (condEnergySum.getType() == esConditionType::Centrality0) {
2272     energySumObjType = GlobalObject::gtCentrality0;
2273     cType = TypeCent0;
2274   } else if (condEnergySum.getType() == esConditionType::Centrality1) {
2275     energySumObjType = GlobalObject::gtCentrality1;
2276     cType = TypeCent1;
2277   } else if (condEnergySum.getType() == esConditionType::Centrality2) {
2278     energySumObjType = GlobalObject::gtCentrality2;
2279     cType = TypeCent2;
2280   } else if (condEnergySum.getType() == esConditionType::Centrality3) {
2281     energySumObjType = GlobalObject::gtCentrality3;
2282     cType = TypeCent3;
2283   } else if (condEnergySum.getType() == esConditionType::Centrality4) {
2284     energySumObjType = GlobalObject::gtCentrality4;
2285     cType = TypeCent4;
2286   } else if (condEnergySum.getType() == esConditionType::Centrality5) {
2287     energySumObjType = GlobalObject::gtCentrality5;
2288     cType = TypeCent5;
2289   } else if (condEnergySum.getType() == esConditionType::Centrality6) {
2290     energySumObjType = GlobalObject::gtCentrality6;
2291     cType = TypeCent6;
2292   } else if (condEnergySum.getType() == esConditionType::Centrality7) {
2293     energySumObjType = GlobalObject::gtCentrality7;
2294     cType = TypeCent7;
2295   } else {
2296     edm::LogError("TriggerMenuParser") << "Wrong type for energy-sum condition (" << type << ")" << std::endl;
2297     return false;
2298   }
2299 
2300   // global object
2301   int nrObj = 1;
2302 
2303   //    std::string str_etComparison = l1t2string( condEnergySum.comparison_operator() );
2304 
2305   // get values
2306 
2307   // temporary storage of the parameters
2308   std::vector<EnergySumTemplate::ObjectParameter> objParameter(nrObj);
2309 
2310   int cnt = 0;
2311 
2312   // BLW TO DO: These needs to the added to the object rather than the whole condition.
2313   int relativeBx = 0;
2314   bool gEq = false;
2315 
2316   //    l1t::EnergySumsObjectRequirement objPar = condEnergySum.objectRequirement();
2317 
2318   // Loop over objects and extract the cuts on the objects
2319   const std::vector<L1TUtmObject>& objects = condEnergySum.getObjects();
2320   for (size_t jj = 0; jj < objects.size(); jj++) {
2321     const L1TUtmObject& object = objects.at(jj);
2322     gEq = (object.getComparisonOperator() == esComparisonOperator::GE);
2323 
2324     //  BLW TO DO: This needs to be added to the Object Parameters
2325     relativeBx = object.getBxOffset();
2326 
2327     //  Loop over the cuts for this object
2328     int lowerThresholdInd = 0;
2329     int upperThresholdInd = -1;
2330     int cntPhi = 0;
2331     unsigned int phiWindow1Lower = -1, phiWindow1Upper = -1, phiWindow2Lower = -1, phiWindow2Upper = -1;
2332 
2333     const std::vector<L1TUtmCut>& cuts = object.getCuts();
2334     for (size_t kk = 0; kk < cuts.size(); kk++) {
2335       const L1TUtmCut& cut = cuts.at(kk);
2336 
2337       switch (cut.getCutType()) {
2338         case esCutType::Threshold:
2339           lowerThresholdInd = cut.getMinimum().index;
2340           upperThresholdInd = cut.getMaximum().index;
2341           break;
2342 
2343         case esCutType::Eta:
2344           break;
2345 
2346         case esCutType::Phi: {
2347           if (cntPhi == 0) {
2348             phiWindow1Lower = cut.getMinimum().index;
2349             phiWindow1Upper = cut.getMaximum().index;
2350           } else if (cntPhi == 1) {
2351             phiWindow2Lower = cut.getMinimum().index;
2352             phiWindow2Upper = cut.getMaximum().index;
2353           } else {
2354             edm::LogError("TriggerMenuParser") << "Too Many Phi Cuts for esum-condition (" << type << ")" << std::endl;
2355             return false;
2356           }
2357           cntPhi++;
2358 
2359         } break;
2360 
2361         case esCutType::Count:
2362           lowerThresholdInd = cut.getMinimum().index;
2363           upperThresholdInd = 0xffffff;
2364           break;
2365 
2366         default:
2367           break;
2368       }  //end switch
2369 
2370     }  //end loop over cuts
2371 
2372     // Fill the object parameters
2373     objParameter[cnt].etLowThreshold = lowerThresholdInd;
2374     objParameter[cnt].etHighThreshold = upperThresholdInd;
2375     objParameter[cnt].phiWindow1Lower = phiWindow1Lower;
2376     objParameter[cnt].phiWindow1Upper = phiWindow1Upper;
2377     objParameter[cnt].phiWindow2Lower = phiWindow2Lower;
2378     objParameter[cnt].phiWindow2Upper = phiWindow2Upper;
2379 
2380     // Output for debugging
2381     LogDebug("TriggerMenuParser") << "\n      EnergySum ET high threshold (hex) for energy sum object " << cnt << " = "
2382                                   << std::hex << objParameter[cnt].etLowThreshold << " - "
2383                                   << objParameter[cnt].etHighThreshold
2384                                   << "\n      phiWindow Lower / Upper for calo object " << cnt << " = 0x"
2385                                   << objParameter[cnt].phiWindow1Lower << " / 0x" << objParameter[cnt].phiWindow1Upper
2386                                   << "\n      phiWindowVeto Lower / Upper for calo object " << cnt << " = 0x"
2387                                   << objParameter[cnt].phiWindow2Lower << " / 0x" << objParameter[cnt].phiWindow2Upper
2388                                   << std::dec << std::endl;
2389 
2390     cnt++;
2391   }  //end loop over objects
2392 
2393   // object types - all same energySumObjType
2394   std::vector<GlobalObject> objType(nrObj, energySumObjType);
2395 
2396   // now create a new energySum condition
2397 
2398   EnergySumTemplate energySumCond(name);
2399 
2400   energySumCond.setCondType(cType);
2401   energySumCond.setObjectType(objType);
2402   energySumCond.setCondGEq(gEq);
2403   energySumCond.setCondChipNr(chipNr);
2404   energySumCond.setCondRelativeBx(relativeBx);
2405 
2406   energySumCond.setConditionParameter(objParameter);
2407 
2408   if (edm::isDebugEnabled()) {
2409     std::ostringstream myCoutStream;
2410     energySumCond.print(myCoutStream);
2411     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
2412   }
2413 
2414   // insert condition into the map
2415   if (!insertConditionIntoMap(energySumCond, chipNr)) {
2416     edm::LogError("TriggerMenuParser") << "    Error: duplicate condition (" << name << ")" << std::endl;
2417 
2418     return false;
2419   } else {
2420     if (corrFlag) {
2421       (m_corEnergySumTemplate[chipNr]).push_back(energySumCond);
2422 
2423     } else {
2424       (m_vecEnergySumTemplate[chipNr]).push_back(energySumCond);
2425     }
2426   }
2427 
2428   //
2429   return true;
2430 }
2431 
2432 /**
2433  * parseEnergySumZdc Parse an "energy sum" condition from the ZDC subsystem and insert an entry to the conditions map
2434  *
2435  * @param node The corresponding node.
2436  * @param name The name of the condition.
2437  * @param chipNr The number of the chip this condition is located.
2438  *
2439  * @return "true" if succeeded, "false" if an error occurred.
2440  *
2441  */
2442 
2443 bool l1t::TriggerMenuParser::parseEnergySumZdc(L1TUtmCondition condEnergySumZdc,
2444                                                unsigned int chipNr,
2445                                                const bool corrFlag) {
2446   //    XERCES_CPP_NAMESPACE_USE
2447   using namespace tmeventsetup;
2448 
2449   // get condition, particle name and type name
2450 
2451   std::string condition = "calo";
2452   std::string type = l1t2string(condEnergySumZdc.getType());
2453   std::string name = l1t2string(condEnergySumZdc.getName());
2454 
2455   LogDebug("TriggerMenuParser")
2456       << "\n ******************************************\n      (in parseEnergySumZdc)\n condition = " << condition
2457       << "\n type      = " << type << "\n name      = " << name;
2458 
2459   // determine object type
2460   GlobalObject energySumObjType;
2461   GtConditionType cType;
2462 
2463   if (condEnergySumZdc.getType() == esConditionType::ZDCPlus) {
2464     LogDebug("TriggerMenuParser") << "ZDC signals: esConditionType::ZDCPlus " << std::endl;
2465     energySumObjType = GlobalObject::gtZDCP;
2466     cType = TypeZDCP;
2467   } else if (condEnergySumZdc.getType() == esConditionType::ZDCMinus) {
2468     LogDebug("TriggerMenuParser") << "ZDC signals: esConditionType::ZDCMinus " << std::endl;
2469     energySumObjType = GlobalObject::gtZDCM;
2470     cType = TypeZDCM;
2471   } else {
2472     edm::LogError("TriggerMenuParser") << "Wrong type for ZDC energy-sum condition (" << type << ")" << std::endl;
2473     return false;
2474   }
2475 
2476   // global object
2477   int nrObj = 1;
2478 
2479   // temporary storage of the parameters
2480   std::vector<EnergySumZdcTemplate::ObjectParameter> objParameter(nrObj);
2481 
2482   //  Loop over the cuts for this object
2483   int lowerThresholdInd = 0;
2484   int upperThresholdInd = -1;
2485 
2486   int cnt = 0;
2487 
2488   // BLW TO DO: These needs to the added to the object rather than the whole condition.
2489   int relativeBx = 0;
2490   bool gEq = false;
2491 
2492   //    l1t::EnergySumsObjectRequirement objPar = condEnergySumZdc.objectRequirement();
2493 
2494   // Loop over objects and extract the cuts on the objects
2495   const std::vector<L1TUtmObject>& objects = condEnergySumZdc.getObjects();
2496   for (size_t jj = 0; jj < objects.size(); jj++) {
2497     const L1TUtmObject& object = objects.at(jj);
2498     gEq = (object.getComparisonOperator() == esComparisonOperator::GE);
2499 
2500     //  BLW TO DO: This needs to be added to the Object Parameters
2501     relativeBx = object.getBxOffset();
2502 
2503     //  Loop over the cuts for this object
2504     const std::vector<L1TUtmCut>& cuts = object.getCuts();
2505     for (size_t kk = 0; kk < cuts.size(); kk++) {
2506       const L1TUtmCut& cut = cuts.at(kk);
2507 
2508       switch (cut.getCutType()) {
2509         case esCutType::Threshold:
2510           lowerThresholdInd = cut.getMinimum().index;
2511           upperThresholdInd = cut.getMaximum().index;
2512           break;
2513 
2514         case esCutType::Count:
2515           lowerThresholdInd = cut.getMinimum().index;
2516           upperThresholdInd = 0xffffff;
2517           break;
2518 
2519         default:
2520           break;
2521       }  //end switch
2522 
2523     }  //end loop over cuts
2524 
2525     // Fill the object parameters
2526     objParameter[cnt].etLowThreshold = lowerThresholdInd;
2527     objParameter[cnt].etHighThreshold = upperThresholdInd;
2528 
2529     // Output for debugging
2530     LogDebug("TriggerMenuParser") << "\n      EnergySumZdc ET high threshold (hex) for energy sum object " << cnt
2531                                   << " = " << std::hex << objParameter[cnt].etLowThreshold << " - "
2532                                   << objParameter[cnt].etHighThreshold << std::dec;
2533 
2534     cnt++;
2535   }  //end loop over objects
2536 
2537   // object types - all same energySumObjType
2538   std::vector<GlobalObject> objType(nrObj, energySumObjType);
2539 
2540   // now create a new energySum condition
2541 
2542   EnergySumZdcTemplate energySumCond(name);
2543 
2544   energySumCond.setCondType(cType);
2545   energySumCond.setObjectType(objType);
2546   energySumCond.setCondGEq(gEq);
2547   energySumCond.setCondChipNr(chipNr);
2548   energySumCond.setCondRelativeBx(relativeBx);
2549 
2550   energySumCond.setConditionParameter(objParameter);
2551 
2552   if (edm::isDebugEnabled()) {
2553     std::ostringstream myCoutStream;
2554     energySumCond.print(myCoutStream);
2555     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
2556   }
2557 
2558   // insert condition into the map
2559   if (!insertConditionIntoMap(energySumCond, chipNr)) {
2560     edm::LogError("TriggerMenuParser") << "    Error: duplicate condition (" << name << ")" << std::endl;
2561 
2562     return false;
2563   } else {
2564     (m_vecEnergySumZdcTemplate[chipNr]).push_back(energySumCond);
2565   }
2566   //
2567   return true;
2568 }
2569 
2570 /**
2571  * parseEnergySumCorr Parse an "energy sum" correlation condition and insert an entry to the conditions map
2572  *
2573  * @param node The corresponding node.
2574  * @param name The name of the condition.
2575  * @param chipNr The number of the chip this condition is located.
2576  *
2577  * @return "true" if succeeded, "false" if an error occurred.
2578  *
2579  */
2580 
2581 bool l1t::TriggerMenuParser::parseEnergySumCorr(const L1TUtmObject* corrESum, unsigned int chipNr) {
2582   //    XERCES_CPP_NAMESPACE_USE
2583   using namespace tmeventsetup;
2584 
2585   // get condition, particle name and type name
2586 
2587   std::string condition = "calo";
2588   std::string type = l1t2string(corrESum->getType());
2589   std::string name = l1t2string(corrESum->getName());
2590 
2591   LogDebug("TriggerMenuParser") << "\n ****************************************** "
2592                                 << "\n      (in parseEnergySum) "
2593                                 << "\n condition = " << condition << "\n type      = " << type
2594                                 << "\n name      = " << name << std::endl;
2595 
2596   // determine object type type
2597   GlobalObject energySumObjType;
2598   GtConditionType cType;
2599 
2600   if (corrESum->getType() == esObjectType::ETM) {
2601     energySumObjType = GlobalObject::gtETM;
2602     cType = TypeETM;
2603   } else if (corrESum->getType() == esObjectType::HTM) {
2604     energySumObjType = GlobalObject::gtHTM;
2605     cType = TypeHTM;
2606   } else if (corrESum->getType() == esObjectType::ETMHF) {
2607     energySumObjType = GlobalObject::gtETMHF;
2608     cType = TypeETMHF;
2609   } else if (corrESum->getType() == esObjectType::HTMHF) {
2610     energySumObjType = GlobalObject::gtHTMHF;
2611     cType = TypeHTMHF;
2612   } else if (corrESum->getType() == esObjectType::TOWERCOUNT) {
2613     energySumObjType = GlobalObject::gtTowerCount;
2614     cType = TypeTowerCount;
2615   } else {
2616     edm::LogError("TriggerMenuParser") << "Wrong type for energy-sum correclation condition (" << type << ")"
2617                                        << std::endl;
2618     return false;
2619   }
2620 
2621   // global object
2622   int nrObj = 1;
2623 
2624   //    std::string str_etComparison = l1t2string( condEnergySum.comparison_operator() );
2625 
2626   // get values
2627 
2628   // temporary storage of the parameters
2629   std::vector<EnergySumTemplate::ObjectParameter> objParameter(nrObj);
2630 
2631   int cnt = 0;
2632 
2633   // BLW TO DO: These needs to the added to the object rather than the whole condition.
2634   int relativeBx = 0;
2635   bool gEq = false;
2636 
2637   //    l1t::EnergySumsObjectRequirement objPar = condEnergySum.objectRequirement();
2638 
2639   gEq = (corrESum->getComparisonOperator() == esComparisonOperator::GE);
2640 
2641   //  BLW TO DO: This needs to be added to the Object Parameters
2642   relativeBx = corrESum->getBxOffset();
2643 
2644   //  Loop over the cuts for this object
2645   int lowerThresholdInd = 0;
2646   int upperThresholdInd = -1;
2647   int cntPhi = 0;
2648   unsigned int phiWindow1Lower = -1, phiWindow1Upper = -1, phiWindow2Lower = -1, phiWindow2Upper = -1;
2649 
2650   const std::vector<L1TUtmCut>& cuts = corrESum->getCuts();
2651   for (size_t kk = 0; kk < cuts.size(); kk++) {
2652     const L1TUtmCut& cut = cuts.at(kk);
2653 
2654     switch (cut.getCutType()) {
2655       case esCutType::Threshold:
2656         lowerThresholdInd = cut.getMinimum().index;
2657         upperThresholdInd = cut.getMaximum().index;
2658         break;
2659 
2660       case esCutType::Eta:
2661         break;
2662 
2663       case esCutType::Phi: {
2664         if (cntPhi == 0) {
2665           phiWindow1Lower = cut.getMinimum().index;
2666           phiWindow1Upper = cut.getMaximum().index;
2667         } else if (cntPhi == 1) {
2668           phiWindow2Lower = cut.getMinimum().index;
2669           phiWindow2Upper = cut.getMaximum().index;
2670         } else {
2671           edm::LogError("TriggerMenuParser") << "Too Many Phi Cuts for esum-condition (" << type << ")" << std::endl;
2672           return false;
2673         }
2674         cntPhi++;
2675 
2676       } break;
2677 
2678       default:
2679         break;
2680     }  //end switch
2681 
2682   }  //end loop over cuts
2683 
2684   // Fill the object parameters
2685   objParameter[0].etLowThreshold = lowerThresholdInd;
2686   objParameter[0].etHighThreshold = upperThresholdInd;
2687   objParameter[0].phiWindow1Lower = phiWindow1Lower;
2688   objParameter[0].phiWindow1Upper = phiWindow1Upper;
2689   objParameter[0].phiWindow2Lower = phiWindow2Lower;
2690   objParameter[0].phiWindow2Upper = phiWindow2Upper;
2691 
2692   // Output for debugging
2693   LogDebug("TriggerMenuParser") << "\n      EnergySum ET high threshold (hex) for energy sum object " << cnt << " = "
2694                                 << std::hex << objParameter[0].etLowThreshold << " - " << objParameter[0].etLowThreshold
2695                                 << "\n      phiWindow Lower / Upper for calo object " << cnt << " = 0x"
2696                                 << objParameter[0].phiWindow1Lower << " / 0x" << objParameter[0].phiWindow1Upper
2697                                 << "\n      phiWindowVeto Lower / Upper for calo object " << cnt << " = 0x"
2698                                 << objParameter[0].phiWindow2Lower << " / 0x" << objParameter[0].phiWindow2Upper
2699                                 << std::dec << std::endl;
2700 
2701   // object types - all same energySumObjType
2702   std::vector<GlobalObject> objType(nrObj, energySumObjType);
2703 
2704   // now create a new energySum condition
2705 
2706   EnergySumTemplate energySumCond(name);
2707 
2708   energySumCond.setCondType(cType);
2709   energySumCond.setObjectType(objType);
2710   energySumCond.setCondGEq(gEq);
2711   energySumCond.setCondChipNr(chipNr);
2712   energySumCond.setCondRelativeBx(relativeBx);
2713 
2714   energySumCond.setConditionParameter(objParameter);
2715 
2716   if (edm::isDebugEnabled()) {
2717     std::ostringstream myCoutStream;
2718     energySumCond.print(myCoutStream);
2719     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
2720   }
2721   /*
2722     // insert condition into the map
2723     if ( !insertConditionIntoMap(energySumCond, chipNr)) {
2724 
2725         edm::LogError("TriggerMenuParser")
2726                 << "    Error: duplicate condition (" << name << ")"
2727                 << std::endl;
2728 
2729         return false;
2730     }
2731     else {
2732 
2733        (m_corEnergySumTemplate[chipNr]).push_back(energySumCond);
2734 
2735     }
2736 */
2737   (m_corEnergySumTemplate[chipNr]).push_back(energySumCond);
2738 
2739   //
2740   return true;
2741 }
2742 
2743 /**                                                                                                                                                            
2744  * parseEnergySumCorr Parse an "energy sum" correlation condition and insert an entry to the conditions map                                                    
2745  *                                                                                                                                                             
2746  * @param node The corresponding node.                                                                                                                        
2747  * @param name The name of the condition.                                                                                                                      
2748  * @param chipNr The number of the chip this condition is located.                                                                                             
2749  *                                                                                                                                                             
2750  * @return "true" if succeeded, "false" if an error occurred.                                                                                                  
2751  *                                                                                                                                                             
2752  */
2753 
2754 bool l1t::TriggerMenuParser::parseAXOL1TL(L1TUtmCondition condAXOL1TL, unsigned int chipNr) {
2755   using namespace tmeventsetup;
2756 
2757   // get condition, particle name and particle type
2758   std::string condition = "axol1tl";
2759   std::string type = l1t2string(condAXOL1TL.getType());
2760   std::string name = l1t2string(condAXOL1TL.getName());
2761 
2762   LogDebug("TriggerMenuParser") << " ****************************************** " << std::endl
2763                                 << "     (in parseAXOL1TL) " << std::endl
2764                                 << " condition = " << condition << std::endl
2765                                 << " type      = " << type << std::endl
2766                                 << " name      = " << name << std::endl;
2767 
2768   const int nrObj = 1;
2769   GtConditionType cType = TypeAXOL1TL;
2770 
2771   std::vector<AXOL1TLTemplate::ObjectParameter> objParameter(nrObj);
2772 
2773   if (int(condAXOL1TL.getObjects().size()) != nrObj) {
2774     edm::LogError("TriggerMenuParser") << " condAXOL1TL objects: nrObj = " << nrObj
2775                                        << "condAXOL1TL.getObjects().size() = " << condAXOL1TL.getObjects().size()
2776                                        << std::endl;
2777     return false;
2778   }
2779 
2780   // Get the axol1tl object
2781   L1TUtmObject object = condAXOL1TL.getObjects().at(0);
2782   int relativeBx = object.getBxOffset();
2783   bool gEq = (object.getComparisonOperator() == esComparisonOperator::GE);
2784 
2785   //Loop over cuts for this  object
2786   int lowerThresholdInd = 0;
2787   int upperThresholdInd = -1;
2788 
2789   //save model and threshold
2790   std::string model = "";
2791 
2792   // for UTM v12+
2793   if (object.getType() == tmeventsetup::Axol1tl) {
2794     const std::vector<L1TUtmCut>& cuts = object.getCuts();
2795     for (size_t kk = 0; kk < cuts.size(); kk++) {
2796       const L1TUtmCut& cut = cuts.at(kk);
2797 
2798       //save model
2799       if (cut.getCutType() == tmeventsetup::Model) {
2800         model = cut.getData();
2801       }
2802       //save score
2803       else if (cut.getCutType() == esCutType::Score) {
2804         lowerThresholdInd = cut.getMinimum().value;
2805         upperThresholdInd = cut.getMaximum().value;
2806       }  //end else if
2807     }    //end cut loop
2808   }      //end if getType
2809   // LEGACY
2810   // for UTM pre v12
2811   else if (condAXOL1TL.getType() == esConditionType::AnomalyDetectionTrigger) {
2812     // hard-code model version for legacy Menu
2813     model = "v3";
2814 
2815     const std::vector<L1TUtmCut>& cuts = object.getCuts();
2816     for (size_t kk = 0; kk < cuts.size(); kk++) {
2817       const L1TUtmCut& cut = cuts.at(kk);
2818       if (cut.getCutType() == esCutType::AnomalyScore) {
2819         lowerThresholdInd = cut.getMinimum().value;
2820         upperThresholdInd = cut.getMaximum().value;
2821         break;
2822       }
2823     }  //end cut loop
2824   } else {
2825     edm::LogError("TriggerMenuParser") << "    Error: not a proper AXOL1TL condition" << std::endl;
2826     return false;
2827   }
2828 
2829   // check model version is not empty
2830   if (model == "") {
2831     edm::LogError("TriggerMenuParser") << "    Error: AXOL1TL movel version is empty" << std::endl;
2832     return false;
2833   }
2834 
2835   //fill object params
2836   objParameter[0].minAXOL1TLThreshold = lowerThresholdInd;
2837   objParameter[0].maxAXOL1TLThreshold = upperThresholdInd;
2838 
2839   // create a new AXOL1TL  condition
2840   AXOL1TLTemplate axol1tlCond(name);
2841   axol1tlCond.setCondType(cType);
2842   axol1tlCond.setCondGEq(gEq);
2843   axol1tlCond.setCondChipNr(chipNr);
2844   axol1tlCond.setCondRelativeBx(relativeBx);
2845   axol1tlCond.setConditionParameter(objParameter);
2846   axol1tlCond.setModelVersion(model);
2847 
2848   if (edm::isDebugEnabled()) {
2849     std::ostringstream myCoutStream;
2850     axol1tlCond.print(myCoutStream);
2851     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
2852   }
2853 
2854   // check that the condition does not exist already in the map
2855   if (!insertConditionIntoMap(axol1tlCond, chipNr)) {
2856     edm::LogError("TriggerMenuParser") << "    Error: duplicate AXOL1TL condition (" << name << ")" << std::endl;
2857     return false;
2858   }
2859 
2860   (m_vecAXOL1TLTemplate[chipNr]).push_back(axol1tlCond);
2861 
2862   return true;
2863 }
2864 
2865 /**
2866  * parseExternal Parse an External condition and
2867  * insert an entry to the conditions map
2868  *
2869  * @param node The corresponding node.
2870  * @param name The name of the condition.
2871  * @param chipNr The number of the chip this condition is located.
2872  *
2873  * @return "true" if succeeded, "false" if an error occurred.
2874  *
2875  */
2876 
2877 bool l1t::TriggerMenuParser::parseExternal(L1TUtmCondition condExt, unsigned int chipNr) {
2878   using namespace tmeventsetup;
2879   // get condition, particle name and type name
2880   std::string condition = "ext";
2881   std::string particle = "test-fix";
2882   std::string type = l1t2string(condExt.getType());
2883   std::string name = l1t2string(condExt.getName());
2884 
2885   LogDebug("TriggerMenuParser") << "\n ****************************************** "
2886                                 << "\n      (in parseExternal) "
2887                                 << "\n condition = " << condition << "\n particle  = " << particle
2888                                 << "\n type      = " << type << "\n name      = " << name << std::endl;
2889 
2890   // object type and condition type
2891   // object type - irrelevant for External conditions
2892   GtConditionType cType = TypeExternal;
2893   GlobalObject extSignalType = GlobalObject::gtExternal;
2894   int nrObj = 1;  //only one object for these conditions
2895 
2896   int relativeBx = 0;
2897   unsigned int channelID = 0;
2898 
2899   // Get object for External conditions
2900   const std::vector<L1TUtmObject>& objects = condExt.getObjects();
2901   for (size_t jj = 0; jj < objects.size(); jj++) {
2902     const L1TUtmObject& object = objects.at(jj);
2903     if (object.getType() == esObjectType::EXT) {
2904       relativeBx = object.getBxOffset();
2905       channelID = object.getExternalChannelId();
2906     }
2907   }
2908 
2909   // set the boolean value for the ge_eq mode - irrelevant for External conditions
2910   bool gEq = false;
2911 
2912   //object types - all same for external conditions
2913   std::vector<GlobalObject> objType(nrObj, extSignalType);
2914 
2915   // now create a new External condition
2916   ExternalTemplate externalCond(name);
2917 
2918   externalCond.setCondType(cType);
2919   externalCond.setObjectType(objType);
2920   externalCond.setCondGEq(gEq);
2921   externalCond.setCondChipNr(chipNr);
2922   externalCond.setCondRelativeBx(relativeBx);
2923   externalCond.setExternalChannel(channelID);
2924 
2925   LogTrace("TriggerMenuParser") << externalCond << "\n" << std::endl;
2926 
2927   // insert condition into the map
2928   if (!insertConditionIntoMap(externalCond, chipNr)) {
2929     edm::LogError("TriggerMenuParser") << "    Error: duplicate condition (" << name << ")" << std::endl;
2930 
2931     return false;
2932   } else {
2933     (m_vecExternalTemplate[chipNr]).push_back(externalCond);
2934   }
2935 
2936   return true;
2937 }
2938 
2939 // Parse the CICADA condition and insert the entry into the conditions mapping
2940 bool l1t::TriggerMenuParser::parseCICADA(L1TUtmCondition condCICADA, unsigned int chipNr) {
2941   using namespace tmeventsetup;
2942 
2943   std::string condition = "cicada";
2944   std::string type = l1t2string(condCICADA.getType());
2945   std::string name = l1t2string(condCICADA.getName());
2946 
2947   LogDebug("TriggerMenuParser") << " ****************************************** " << std::endl
2948                                 << "     (in parseCICADA) " << std::endl
2949                                 << " condition = " << condition << std::endl
2950                                 << " type      = " << type << std::endl
2951                                 << " name      = " << name << std::endl;
2952   const int nrObj = 1;
2953   GtConditionType cType = TypeCICADA;
2954 
2955   std::vector<CICADATemplate::ObjectParameter> objParameter(nrObj);
2956 
2957   if (int(condCICADA.getObjects().size()) != nrObj) {
2958     edm::LogError("TriggerMenuParser") << " condCICADA objects: nrObj = " << nrObj
2959                                        << "condCICADA.getObjects().size() = " << condCICADA.getObjects().size()
2960                                        << std::endl;
2961     return false;
2962   }
2963 
2964   L1TUtmObject object = condCICADA.getObjects().at(0);
2965   int relativeBx = object.getBxOffset();
2966   bool gEq = (object.getComparisonOperator() == esComparisonOperator::GE);
2967 
2968   float lowerThresholdInd = 0;  //May need to be float to match CICADA?
2969   float upperThresholdInd = -1;
2970 
2971   const std::vector<L1TUtmCut>& cuts = object.getCuts();
2972   for (size_t kk = 0; kk < cuts.size(); kk++) {
2973     const L1TUtmCut& cut = cuts.at(kk);
2974 
2975     switch (cut.getCutType()) {
2976       case esCutType::CicadaScore:
2977         lowerThresholdInd = cut.getMinimum().value;
2978         upperThresholdInd = cut.getMaximum().value;
2979     }
2980   }
2981 
2982   objParameter[0].minCICADAThreshold = lowerThresholdInd;
2983   objParameter[0].maxCICADAThreshold = upperThresholdInd;
2984 
2985   CICADATemplate cicadaCond(name);
2986   cicadaCond.setCondType(cType);
2987   cicadaCond.setCondGEq(gEq);
2988   cicadaCond.setCondChipNr(chipNr);
2989   cicadaCond.setCondRelativeBx(relativeBx);
2990   cicadaCond.setConditionParameter(objParameter);
2991 
2992   if (edm::isDebugEnabled()) {
2993     std::ostringstream myCoutStream;
2994     cicadaCond.print(myCoutStream);
2995     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
2996   }
2997 
2998   if (!insertConditionIntoMap(cicadaCond, chipNr)) {
2999     edm::LogError("TriggerMenuParser") << "   Error: duplicate CICADA condition (" << name << ")" << std::endl;
3000     return false;
3001   }
3002 
3003   (m_vecCICADATemplate[chipNr]).push_back(cicadaCond);
3004 
3005   return true;
3006 }
3007 
3008 /**
3009  * parseCorrelation Parse a correlation condition and
3010  * insert an entry to the conditions map
3011  *
3012  * @param node The corresponding node.
3013  * @param name The name of the condition.
3014  * @param chipNr The number of the chip this condition is located.
3015  *
3016  * @return "true" if succeeded, "false" if an error occurred.
3017  *
3018  */
3019 
3020 bool l1t::TriggerMenuParser::parseCorrelation(L1TUtmCondition corrCond, unsigned int chipNr) {
3021   using namespace tmeventsetup;
3022   std::string condition = "corr";
3023   std::string particle = "test-fix";
3024   std::string type = l1t2string(corrCond.getType());
3025   std::string name = l1t2string(corrCond.getName());
3026 
3027   LogDebug("TriggerMenuParser") << " ****************************************** " << std::endl
3028                                 << "     (in parseCorrelation) " << std::endl
3029                                 << " condition = " << condition << std::endl
3030                                 << " particle  = " << particle << std::endl
3031                                 << " type      = " << type << std::endl
3032                                 << " name      = " << name << std::endl;
3033 
3034   // create a new correlation condition
3035   CorrelationTemplate correlationCond(name);
3036 
3037   // check that the condition does not exist already in the map
3038   if (!insertConditionIntoMap(correlationCond, chipNr)) {
3039     edm::LogError("TriggerMenuParser") << "    Error: duplicate correlation condition (" << name << ")" << std::endl;
3040 
3041     return false;
3042   }
3043 
3044   // Define some of the quantities to store the parased information
3045 
3046   // condition type BLW  (Do we change this to the type of correlation condition?)
3047   GtConditionType cType = l1t::Type2cor;
3048 
3049   // two objects (for sure)
3050   const int nrObj = 2;
3051 
3052   // object types and greater equal flag - filled in the loop
3053   int intGEq[nrObj] = {-1, -1};
3054   std::vector<GlobalObject> objType(nrObj);           //BLW do we want to define these as a different type?
3055   std::vector<GtConditionCategory> condCateg(nrObj);  //BLW do we want to change these categories
3056 
3057   // correlation flag and index in the cor*vector
3058   const bool corrFlag = true;
3059   int corrIndexVal[nrObj] = {-1, -1};
3060 
3061   // Storage of the correlation selection
3062   CorrelationTemplate::CorrelationParameter corrParameter;
3063   corrParameter.chargeCorrelation = 1;  //ignore charge correlation
3064 
3065   // Get the correlation Cuts on the legs
3066   int cutType = 0;
3067   const std::vector<L1TUtmCut>& cuts = corrCond.getCuts();
3068   for (size_t jj = 0; jj < cuts.size(); jj++) {
3069     const L1TUtmCut& cut = cuts.at(jj);
3070 
3071     if (cut.getCutType() == esCutType::ChargeCorrelation) {
3072       if (cut.getData() == "ls")
3073         corrParameter.chargeCorrelation = 2;
3074       else if (cut.getData() == "os")
3075         corrParameter.chargeCorrelation = 4;
3076       else
3077         corrParameter.chargeCorrelation = 1;  //ignore charge correlation
3078     } else {
3079       //
3080       //  Until utm has method to calculate these, do the integer value calculation with precision.
3081       //
3082       double minV = cut.getMinimum().value;
3083       double maxV = cut.getMaximum().value;
3084 
3085       //Scale down very large numbers out of xml
3086       if (maxV > 1.0e8)
3087         maxV = 1.0e8;
3088 
3089       if (cut.getCutType() == esCutType::DeltaEta) {
3090         LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tDeltaEta Cut minV = " << minV
3091                                       << " Max = " << maxV << " precMin = " << cut.getMinimum().index
3092                                       << " precMax = " << cut.getMaximum().index << std::endl;
3093         corrParameter.minEtaCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3094         corrParameter.maxEtaCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3095         corrParameter.precEtaCut = cut.getMinimum().index;
3096         cutType = cutType | 0x1;
3097       } else if (cut.getCutType() == esCutType::DeltaPhi) {
3098         LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tDeltaPhi Cut minV = " << minV
3099                                       << " Max = " << maxV << " precMin = " << cut.getMinimum().index
3100                                       << " precMax = " << cut.getMaximum().index << std::endl;
3101         corrParameter.minPhiCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3102         corrParameter.maxPhiCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3103         corrParameter.precPhiCut = cut.getMinimum().index;
3104         cutType = cutType | 0x2;
3105       } else if (cut.getCutType() == esCutType::DeltaR) {
3106         LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tDeltaR Cut minV = " << minV
3107                                       << " Max = " << maxV << " precMin = " << cut.getMinimum().index
3108                                       << " precMax = " << cut.getMaximum().index << std::endl;
3109         corrParameter.minDRCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3110         corrParameter.maxDRCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3111         corrParameter.precDRCut = cut.getMinimum().index;
3112         cutType = cutType | 0x4;
3113       } else if (cut.getCutType() == esCutType::TwoBodyPt) {
3114         corrParameter.minTBPTCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3115         corrParameter.maxTBPTCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3116         corrParameter.precTBPTCut = cut.getMinimum().index;
3117         LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tTPBT Cut minV = " << minV
3118                                       << " Max = " << maxV << " precMin = " << cut.getMinimum().index
3119                                       << " precMax = " << cut.getMaximum().index << std::endl;
3120         cutType = cutType | 0x20;
3121       } else if ((cut.getCutType() == esCutType::Mass) ||
3122                  (cut.getCutType() == esCutType::MassDeltaR)) {  //Invariant Mass, MassOverDeltaR
3123         LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tMass Cut minV = " << minV
3124                                       << " Max = " << maxV << " precMin = " << cut.getMinimum().index
3125                                       << " precMax = " << cut.getMaximum().index << std::endl;
3126         corrParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3127         corrParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3128         corrParameter.precMassCut = cut.getMinimum().index;
3129         // cutType = cutType | 0x8;
3130         if (corrCond.getType() == esConditionType::TransverseMass) {
3131           cutType = cutType | 0x10;
3132         } else if (corrCond.getType() == esConditionType::InvariantMassDeltaR) {
3133           cutType = cutType | 0x80;
3134         } else {
3135           cutType = cutType | 0x8;
3136         }
3137       } else if (cut.getCutType() == esCutType::MassUpt) {  // Added for displaced muons
3138         LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tMass Cut minV = " << minV
3139                                       << " Max = " << maxV << " precMin = " << cut.getMinimum().index
3140                                       << " precMax = " << cut.getMaximum().index << std::endl;
3141         corrParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3142         corrParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3143         corrParameter.precMassCut = cut.getMinimum().index;
3144         cutType = cutType | 0x40;  // Note:    0x40 (MassUpt) is next available bit after 0x20 (TwoBodyPt)
3145       }                            // Careful: cutType carries same info as esCutType, but is hard coded!!
3146     }                              //          This seems like a historical hack, which may be error prone.
3147   }                                //          cutType is defined here, for use later in CorrCondition.cc
3148   corrParameter.corrCutType = cutType;
3149 
3150   // Get the two objects that form the legs
3151   const std::vector<L1TUtmObject>& objects = corrCond.getObjects();
3152   if (objects.size() != 2) {
3153     edm::LogError("TriggerMenuParser") << "incorrect number of objects for the correlation condition " << name
3154                                        << " corrFlag " << corrFlag << std::endl;
3155     return false;
3156   }
3157 
3158   // loop over legs
3159   for (size_t jj = 0; jj < objects.size(); jj++) {
3160     const L1TUtmObject& object = objects.at(jj);
3161     LogDebug("TriggerMenuParser") << "      obj name = " << object.getName() << "\n";
3162     LogDebug("TriggerMenuParser") << "      obj type = " << object.getType() << "\n";
3163     LogDebug("TriggerMenuParser") << "      obj op = " << object.getComparisonOperator() << "\n";
3164     LogDebug("TriggerMenuParser") << "      obj bx = " << object.getBxOffset() << "\n";
3165 
3166     // check the leg type
3167     if (object.getType() == esObjectType::Muon) {
3168       // we have a muon
3169 
3170       /*
3171           //BLW Hold on to this code we may need to go back to it at some point.
3172       // Now we are putting ALL leg conditions into the vector (so there are duplicates)
3173       // This is potentially a place to slim down the code.  Note: We currently evaluate the
3174       // conditions every time, so even if we put the condition in the vector once, we would
3175       // still evaluate it multiple times.  This is a place for optimization.
3176           {
3177 
3178               parseMuonCorr(&object,chipNr);
3179           corrIndexVal[jj] = (m_corMuonTemplate[chipNr]).size() - 1;
3180 
3181           } else {
3182          LogDebug("TriggerMenuParser") << "Not Adding Correlation Muon Condition to Map...looking for the condition in Muon Cor Vector" << std::endl;
3183          bool found = false;
3184          int index = 0;
3185          while(!found && index<(int)((m_corMuonTemplate[chipNr]).size()) ) {
3186              if( (m_corMuonTemplate[chipNr]).at(index).condName() == object.getName() ) {
3187             LogDebug("TriggerMenuParser") << "Found condition " << object.getName() << " in vector at index " << index << std::endl;
3188             found = true;
3189          } else {
3190             index++;
3191          }
3192          }
3193          if(found) {
3194             corrIndexVal[jj] = index;
3195          } else {
3196            edm::LogError("TriggerMenuParser") << "FAILURE: Condition " << object.getName() << " is in map but not in cor. vector " << std::endl;
3197          }
3198 
3199       }
3200 */
3201       parseMuonCorr(&object, chipNr);
3202       corrIndexVal[jj] = (m_corMuonTemplate[chipNr]).size() - 1;
3203 
3204       //Now set some flags for this subCondition
3205       intGEq[jj] = (object.getComparisonOperator() == esComparisonOperator::GE);
3206       objType[jj] = gtMu;
3207       condCateg[jj] = CondMuon;
3208 
3209     } else if (object.getType() == esObjectType::Egamma || object.getType() == esObjectType::Jet ||
3210                object.getType() == esObjectType::Tau) {
3211       // we have an Calo object
3212       parseCaloCorr(&object, chipNr);
3213       corrIndexVal[jj] = (m_corCaloTemplate[chipNr]).size() - 1;
3214 
3215       //Now set some flags for this subCondition
3216       intGEq[jj] = (object.getComparisonOperator() == esComparisonOperator::GE);
3217       switch (object.getType()) {
3218         case esObjectType::Egamma: {
3219           objType[jj] = gtEG;
3220         } break;
3221         case esObjectType::Jet: {
3222           objType[jj] = gtJet;
3223         } break;
3224         case esObjectType::Tau: {
3225           objType[jj] = gtTau;
3226         } break;
3227         default: {
3228         } break;
3229       }
3230       condCateg[jj] = CondCalo;
3231 
3232     } else if (object.getType() == esObjectType::ETM || object.getType() == esObjectType::ETMHF ||
3233                object.getType() == esObjectType::HTMHF || object.getType() == esObjectType::TOWERCOUNT ||
3234                object.getType() == esObjectType::HTM) {
3235       // we have Energy Sum
3236       parseEnergySumCorr(&object, chipNr);
3237       corrIndexVal[jj] = (m_corEnergySumTemplate[chipNr]).size() - 1;
3238 
3239       //Now set some flags for this subCondition
3240       intGEq[jj] = (object.getComparisonOperator() == esComparisonOperator::GE);
3241       switch (object.getType()) {
3242         case esObjectType::ETM: {
3243           objType[jj] = GlobalObject::gtETM;
3244         } break;
3245         case esObjectType::HTM: {
3246           objType[jj] = GlobalObject::gtHTM;
3247         } break;
3248         case esObjectType::ETMHF: {
3249           objType[jj] = GlobalObject::gtETMHF;
3250         } break;
3251         case esObjectType::HTMHF: {
3252           objType[jj] = GlobalObject::gtHTMHF;
3253         } break;
3254         case esObjectType::TOWERCOUNT: {
3255           objType[jj] = GlobalObject::gtTowerCount;
3256         } break;
3257         default: {
3258         } break;
3259       }
3260       condCateg[jj] = CondEnergySum;
3261 
3262     } else {
3263       edm::LogError("TriggerMenuParser") << "Illegal Object Type " << object.getType()
3264                                          << " for the correlation condition " << name << std::endl;
3265       return false;
3266 
3267     }  //if block on leg types
3268 
3269   }  //loop over legs
3270 
3271   // get greater equal flag for the correlation condition
3272   bool gEq = true;
3273   if (intGEq[0] != intGEq[1]) {
3274     edm::LogError("TriggerMenuParser") << "Inconsistent GEq flags for sub-conditions "
3275                                        << " for the correlation condition " << name << std::endl;
3276     return false;
3277 
3278   } else {
3279     gEq = (intGEq[0] != 0);
3280   }
3281 
3282   // fill the correlation condition
3283   correlationCond.setCondType(cType);
3284   correlationCond.setObjectType(objType);
3285   correlationCond.setCondGEq(gEq);
3286   correlationCond.setCondChipNr(chipNr);
3287 
3288   correlationCond.setCond0Category(condCateg[0]);
3289   correlationCond.setCond1Category(condCateg[1]);
3290 
3291   correlationCond.setCond0Index(corrIndexVal[0]);
3292   correlationCond.setCond1Index(corrIndexVal[1]);
3293 
3294   correlationCond.setCorrelationParameter(corrParameter);
3295 
3296   if (edm::isDebugEnabled()) {
3297     std::ostringstream myCoutStream;
3298     correlationCond.print(myCoutStream);
3299     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
3300   }
3301 
3302   // insert condition into the map
3303   // condition is not duplicate, check was done at the beginning
3304 
3305   (m_vecCorrelationTemplate[chipNr]).push_back(correlationCond);
3306 
3307   //
3308   return true;
3309 }
3310 
3311 //////////////////////////////////////////////////////////////////////////////////////
3312 /**
3313  * parseCorrelationThreeBody Parse a correlation condition between three objects and
3314  * insert an entry to the conditions map
3315  *
3316  * @param node The corresponding node.
3317  * @param name The name of the condition.
3318  * @param chipNr The number of the chip this condition is located.
3319  *
3320  * @return "true" if succeeded, "false" if an error occurred.
3321  *
3322  */
3323 
3324 bool l1t::TriggerMenuParser::parseCorrelationThreeBody(L1TUtmCondition corrCond, unsigned int chipNr) {
3325   using namespace tmeventsetup;
3326   std::string condition = "corrThreeBody";
3327   std::string particle = "muon";
3328   std::string type = l1t2string(corrCond.getType());
3329   std::string name = l1t2string(corrCond.getName());
3330 
3331   LogDebug("TriggerMenuParser") << " ****************************************** " << std::endl
3332                                 << "     (in parseCorrelationThreeBody) " << std::endl
3333                                 << " condition = " << condition << std::endl
3334                                 << " particle  = " << particle << std::endl
3335                                 << " type      = " << type << std::endl
3336                                 << " name      = " << name << std::endl;
3337 
3338   // create a new correlation condition
3339   CorrelationThreeBodyTemplate correlationThreeBodyCond(name);
3340 
3341   // check that the condition does not exist already in the map
3342   if (!insertConditionIntoMap(correlationThreeBodyCond, chipNr)) {
3343     edm::LogError("TriggerMenuParser") << "    Error: duplicate correlation condition (" << name << ")" << std::endl;
3344     return false;
3345   }
3346 
3347   // Define some of the quantities to store the parsed information
3348   GtConditionType cType = l1t::Type3s;
3349 
3350   // three objects (for sure)
3351   const int nrObj = 3;
3352 
3353   // object types and greater equal flag - filled in the loop
3354   std::vector<GlobalObject> objType(nrObj);
3355   std::vector<GtConditionCategory> condCateg(nrObj);
3356 
3357   // correlation flag and index in the cor*vector
3358   const bool corrFlag = true;
3359   int corrIndexVal[nrObj] = {-1, -1, -1};
3360 
3361   // Storage of the correlation selection
3362   CorrelationThreeBodyTemplate::CorrelationThreeBodyParameter corrThreeBodyParameter;
3363   // Set charge correlation parameter
3364   //corrThreeBodyParameter.chargeCorrelation = chargeCorrelation;  //tmpValues[0];
3365   //corrThreeBodyParameter.chargeCorrelation = 1;  //ignore charge correlation for corr-legs
3366 
3367   // Get the correlation cuts on the legs
3368   int cutType = 0;
3369   const std::vector<L1TUtmCut>& cuts = corrCond.getCuts();
3370   for (size_t lll = 0; lll < cuts.size(); lll++) {  // START esCut lll
3371     const L1TUtmCut& cut = cuts.at(lll);
3372 
3373     if (cut.getCutType() == esCutType::ChargeCorrelation) {
3374       if (cut.getData() == "ls")
3375         corrThreeBodyParameter.chargeCorrelation = 2;
3376       else if (cut.getData() == "os")
3377         corrThreeBodyParameter.chargeCorrelation = 4;
3378       else
3379         corrThreeBodyParameter.chargeCorrelation = 1;  //ignore charge correlation
3380     }
3381 
3382     //
3383     //  Until utm has method to calculate these, do the integer value calculation with precision.
3384     //
3385     double minV = cut.getMinimum().value;
3386     double maxV = cut.getMaximum().value;
3387     //Scale down very large numbers out of xml
3388     if (maxV > 1.0e8)
3389       maxV = 1.0e8;
3390 
3391     if (cut.getCutType() == esCutType::Mass) {
3392       LogDebug("TriggerMenuParser") << "CutType: " << cut.getCutType() << "\tMass Cut minV = " << minV
3393                                     << "\tMass Cut maxV = " << maxV << " precMin = " << cut.getMinimum().index
3394                                     << " precMax = " << cut.getMaximum().index << std::endl;
3395       corrThreeBodyParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3396       corrThreeBodyParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3397       corrThreeBodyParameter.precMassCut = cut.getMinimum().index;
3398       cutType = cutType | 0x8;
3399     } else if (cut.getCutType() == esCutType::MassDeltaR) {
3400       corrThreeBodyParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3401       corrThreeBodyParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3402       corrThreeBodyParameter.precMassCut = cut.getMinimum().index;
3403       cutType = cutType | 0x80;
3404     }
3405   }  // END esCut lll
3406   corrThreeBodyParameter.corrCutType = cutType;
3407 
3408   // Get the three objects that form the legs
3409   const std::vector<L1TUtmObject>& objects = corrCond.getObjects();
3410   if (objects.size() != 3) {
3411     edm::LogError("TriggerMenuParser") << "incorrect number of objects for the correlation condition " << name
3412                                        << " corrFlag " << corrFlag << std::endl;
3413     return false;
3414   }
3415 
3416   // Loop over legs
3417   for (size_t lll = 0; lll < objects.size(); lll++) {
3418     const L1TUtmObject& object = objects.at(lll);
3419     LogDebug("TriggerMenuParser") << "      obj name = " << object.getName() << "\n";
3420     LogDebug("TriggerMenuParser") << "      obj type = " << object.getType() << "\n";
3421     LogDebug("TriggerMenuParser") << "      obj bx = " << object.getBxOffset() << "\n";
3422 
3423     // check the leg type
3424     if (object.getType() == esObjectType::Muon) {
3425       // we have a muon
3426       parseMuonCorr(&object, chipNr);
3427       corrIndexVal[lll] = (m_corMuonTemplate[chipNr]).size() - 1;
3428 
3429       //Now set some flags for this subCondition
3430       objType[lll] = gtMu;
3431       condCateg[lll] = CondMuon;
3432 
3433     } else {
3434       edm::LogError("TriggerMenuParser") << "Checked the object Type " << object.getType()
3435                                          << " for the correlation condition " << name
3436                                          << ": no three muons in the event!" << std::endl;
3437     }
3438   }  // End loop over legs
3439 
3440   // fill the three-body correlation condition
3441   correlationThreeBodyCond.setCondType(cType);
3442   correlationThreeBodyCond.setObjectType(objType);
3443   correlationThreeBodyCond.setCondChipNr(chipNr);
3444 
3445   correlationThreeBodyCond.setCond0Category(condCateg[0]);
3446   correlationThreeBodyCond.setCond1Category(condCateg[1]);
3447   correlationThreeBodyCond.setCond2Category(condCateg[2]);
3448 
3449   correlationThreeBodyCond.setCond0Index(corrIndexVal[0]);
3450   correlationThreeBodyCond.setCond1Index(corrIndexVal[1]);
3451   correlationThreeBodyCond.setCond2Index(corrIndexVal[2]);
3452 
3453   correlationThreeBodyCond.setCorrelationThreeBodyParameter(corrThreeBodyParameter);
3454 
3455   if (edm::isDebugEnabled()) {
3456     std::ostringstream myCoutStream;
3457     correlationThreeBodyCond.print(myCoutStream);
3458     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
3459   }
3460 
3461   // insert condition into the map
3462   // condition is not duplicate, check was done at the beginning
3463 
3464   (m_vecCorrelationThreeBodyTemplate[chipNr]).push_back(correlationThreeBodyCond);
3465 
3466   //
3467   return true;
3468 }
3469 
3470 ////////////////////////////////////////////////////////////////////////////////////
3471 /**
3472  * parseCorrelationWithOverlapRemoval Parse a correlation condition and
3473  * insert an entry to the conditions map
3474  *
3475  * @param node The corresponding node.
3476  * @param name The name of the condition.
3477  * @param chipNr The number of the chip this condition is located.
3478  *
3479  * @return "true" if succeeded, "false" if an error occurred.
3480  *
3481  */
3482 
3483 bool l1t::TriggerMenuParser::parseCorrelationWithOverlapRemoval(const L1TUtmCondition& corrCond, unsigned int chipNr) {
3484   using namespace tmeventsetup;
3485   std::string condition = "corrWithOverlapRemoval";
3486   std::string particle = "test-fix";
3487   std::string type = l1t2string(corrCond.getType());
3488   std::string name = l1t2string(corrCond.getName());
3489 
3490   LogDebug("TriggerMenuParser") << " ****************************************** " << std::endl
3491                                 << "     (in parseCorrelationWithOverlapRemoval) " << std::endl
3492                                 << " condition = " << condition << std::endl
3493                                 << " particle  = " << particle << std::endl
3494                                 << " type      = " << type << std::endl
3495                                 << " name      = " << name << std::endl;
3496 
3497   // create a new correlation condition
3498   CorrelationWithOverlapRemovalTemplate correlationWORCond(name);
3499 
3500   // check that the condition does not exist already in the map
3501   if (!insertConditionIntoMap(correlationWORCond, chipNr)) {
3502     edm::LogError("TriggerMenuParser") << "    Error: duplicate correlation condition (" << name << ")" << std::endl;
3503 
3504     return false;
3505   }
3506 
3507   // Define some of the quantities to store the parased information
3508 
3509   // condition type BLW  (Do we change this to the type of correlation condition?)
3510   GtConditionType cType = l1t::Type2corWithOverlapRemoval;
3511 
3512   // three objects (for sure)
3513   const int nrObj = 3;
3514 
3515   // object types and greater equal flag - filled in the loop
3516   int intGEq[nrObj] = {-1, -1, -1};
3517   std::vector<GlobalObject> objType(nrObj);           //BLW do we want to define these as a different type?
3518   std::vector<GtConditionCategory> condCateg(nrObj);  //BLW do we want to change these categories
3519 
3520   // correlation flag and index in the cor*vector
3521   const bool corrFlag = true;
3522   int corrIndexVal[nrObj] = {-1, -1, -1};
3523 
3524   // Storage of the correlation selection
3525   CorrelationWithOverlapRemovalTemplate::CorrelationWithOverlapRemovalParameter corrParameter;
3526   corrParameter.chargeCorrelation = 1;  //ignore charge correlation for corr-legs
3527 
3528   // Get the correlation Cuts on the legs
3529   int cutType = 0;
3530   const std::vector<L1TUtmCut>& cuts = corrCond.getCuts();
3531   for (size_t jj = 0; jj < cuts.size(); jj++) {
3532     const L1TUtmCut& cut = cuts.at(jj);
3533 
3534     if (cut.getCutType() == esCutType::ChargeCorrelation) {
3535       if (cut.getData() == "ls")
3536         corrParameter.chargeCorrelation = 2;
3537       else if (cut.getData() == "os")
3538         corrParameter.chargeCorrelation = 4;
3539       else
3540         corrParameter.chargeCorrelation = 1;  //ignore charge correlation
3541     } else {
3542       //
3543       //  Unitl utm has method to calculate these, do the integer value calculation with precision.
3544       //
3545       double minV = cut.getMinimum().value;
3546       double maxV = cut.getMaximum().value;
3547 
3548       //Scale down very large numbers out of xml
3549       if (maxV > 1.0e8)
3550         maxV = 1.0e8;
3551 
3552       if (cut.getCutType() == esCutType::DeltaEta) {
3553         //std::cout << "DeltaEta Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3554         corrParameter.minEtaCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3555         corrParameter.maxEtaCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3556         corrParameter.precEtaCut = cut.getMinimum().index;
3557         cutType = cutType | 0x1;
3558       } else if (cut.getCutType() == esCutType::DeltaPhi) {
3559         //std::cout << "DeltaPhi Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3560         corrParameter.minPhiCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3561         corrParameter.maxPhiCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3562         corrParameter.precPhiCut = cut.getMinimum().index;
3563         cutType = cutType | 0x2;
3564       } else if (cut.getCutType() == esCutType::DeltaR) {
3565         //std::cout << "DeltaR Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3566         corrParameter.minDRCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3567         corrParameter.maxDRCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3568         corrParameter.precDRCut = cut.getMinimum().index;
3569         cutType = cutType | 0x4;
3570       } else if (cut.getCutType() == esCutType::Mass) {
3571         //std::cout << "Mass Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3572         corrParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3573         corrParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3574         corrParameter.precMassCut = cut.getMinimum().index;
3575         cutType = cutType | 0x8;
3576       } else if (cut.getCutType() == esCutType::MassDeltaR) {
3577         corrParameter.minMassCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3578         corrParameter.maxMassCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3579         corrParameter.precMassCut = cut.getMinimum().index;
3580         cutType = cutType | 0x80;
3581       }
3582       if (cut.getCutType() == esCutType::OvRmDeltaEta) {
3583         //std::cout << "OverlapRemovalDeltaEta Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3584         corrParameter.minOverlapRemovalEtaCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3585         corrParameter.maxOverlapRemovalEtaCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3586         corrParameter.precOverlapRemovalEtaCut = cut.getMinimum().index;
3587         cutType = cutType | 0x10;
3588       } else if (cut.getCutType() == esCutType::OvRmDeltaPhi) {
3589         //std::cout << "OverlapRemovalDeltaPhi Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3590         corrParameter.minOverlapRemovalPhiCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3591         corrParameter.maxOverlapRemovalPhiCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3592         corrParameter.precOverlapRemovalPhiCut = cut.getMinimum().index;
3593         cutType = cutType | 0x20;
3594       } else if (cut.getCutType() == esCutType::OvRmDeltaR) {
3595         //std::cout << "DeltaR Cut minV = " << minV << " Max = " << maxV << " precMin = " << cut.getMinimum().index << " precMax = " << cut.getMaximum().index << std::endl;
3596         corrParameter.minOverlapRemovalDRCutValue = (long long)(minV * pow(10., cut.getMinimum().index));
3597         corrParameter.maxOverlapRemovalDRCutValue = (long long)(maxV * pow(10., cut.getMaximum().index));
3598         corrParameter.precOverlapRemovalDRCut = cut.getMinimum().index;
3599         cutType = cutType | 0x40;
3600       }
3601     }
3602   }
3603   corrParameter.corrCutType = cutType;
3604 
3605   // Get the two objects that form the legs
3606   const std::vector<L1TUtmObject>& objects = corrCond.getObjects();
3607   if (objects.size() != 3) {
3608     edm::LogError("TriggerMenuParser")
3609         << "incorrect number of objects for the correlation condition with overlap removal " << name << " corrFlag "
3610         << corrFlag << std::endl;
3611     return false;
3612   }
3613 
3614   // Loop over legs
3615   for (size_t jj = 0; jj < objects.size(); jj++) {
3616     const L1TUtmObject& object = objects.at(jj);
3617     LogDebug("TriggerMenuParser") << "      obj name = " << object.getName() << "\n";
3618     LogDebug("TriggerMenuParser") << "      obj type = " << object.getType() << "\n";
3619     LogDebug("TriggerMenuParser") << "      obj op = " << object.getComparisonOperator() << "\n";
3620     LogDebug("TriggerMenuParser") << "      obj bx = " << object.getBxOffset() << "\n";
3621     LogDebug("TriggerMenuParser") << "type = done" << std::endl;
3622 
3623     // check the leg type
3624     if (object.getType() == esObjectType::Muon) {
3625       // we have a muon
3626 
3627       /*
3628           //BLW Hold on to this code we may need to go back to it at some point.
3629       // Now we are putting ALL leg conditions into the vector (so there are duplicates)
3630       // This is potentially a place to slim down the code.  Note: We currently evaluate the
3631       // conditions every time, so even if we put the condition in the vector once, we would
3632       // still evaluate it multiple times.  This is a place for optimization.
3633           {
3634 
3635               parseMuonCorr(&object,chipNr);
3636           corrIndexVal[jj] = (m_corMuonTemplate[chipNr]).size() - 1;
3637 
3638           } else {
3639          LogDebug("TriggerMenuParser") << "Not Adding Correlation Muon Condition to Map...looking for the condition in Muon Cor Vector" << std::endl;
3640          bool found = false;
3641          int index = 0;
3642          while(!found && index<(int)((m_corMuonTemplate[chipNr]).size()) ) {
3643              if( (m_corMuonTemplate[chipNr]).at(index).condName() == object.getName() ) {
3644             LogDebug("TriggerMenuParser") << "Found condition " << object.getName() << " in vector at index " << index << std::endl;
3645             found = true;
3646          } else {
3647             index++;
3648          }
3649          }
3650          if(found) {
3651             corrIndexVal[jj] = index;
3652          } else {
3653            edm::LogError("TriggerMenuParser") << "FAILURE: Condition " << object.getName() << " is in map but not in cor. vector " << std::endl;
3654          }
3655 
3656       }
3657 */
3658       parseMuonCorr(&object, chipNr);
3659       corrIndexVal[jj] = (m_corMuonTemplate[chipNr]).size() - 1;
3660 
3661       //Now set some flags for this subCondition
3662       intGEq[jj] = (object.getComparisonOperator() == esComparisonOperator::GE);
3663       objType[jj] = gtMu;
3664       condCateg[jj] = CondMuon;
3665 
3666     } else if (object.getType() == esObjectType::Egamma || object.getType() == esObjectType::Jet ||
3667                object.getType() == esObjectType::Tau) {
3668       // we have an Calo object
3669       parseCaloCorr(&object, chipNr);
3670       corrIndexVal[jj] = (m_corCaloTemplate[chipNr]).size() - 1;
3671 
3672       //Now set some flags for this subCondition
3673       intGEq[jj] = (object.getComparisonOperator() == esComparisonOperator::GE);
3674       switch (object.getType()) {
3675         case esObjectType::Egamma: {
3676           objType[jj] = gtEG;
3677         } break;
3678         case esObjectType::Jet: {
3679           objType[jj] = gtJet;
3680         } break;
3681         case esObjectType::Tau: {
3682           objType[jj] = gtTau;
3683         } break;
3684         default: {
3685         } break;
3686       }
3687       condCateg[jj] = CondCalo;
3688 
3689     } else if (object.getType() == esObjectType::ETM || object.getType() == esObjectType::ETMHF ||
3690                object.getType() == esObjectType::HTMHF || object.getType() == esObjectType::TOWERCOUNT ||
3691                object.getType() == esObjectType::HTM) {
3692       // we have Energy Sum
3693       parseEnergySumCorr(&object, chipNr);
3694       corrIndexVal[jj] = (m_corEnergySumTemplate[chipNr]).size() - 1;
3695 
3696       //Now set some flags for this subCondition
3697       intGEq[jj] = (object.getComparisonOperator() == esComparisonOperator::GE);
3698       switch (object.getType()) {
3699         case esObjectType::ETM: {
3700           objType[jj] = GlobalObject::gtETM;
3701         } break;
3702         case esObjectType::HTM: {
3703           objType[jj] = GlobalObject::gtHTM;
3704         } break;
3705         case esObjectType::ETMHF: {
3706           objType[jj] = GlobalObject::gtETMHF;
3707         } break;
3708         case esObjectType::HTMHF: {
3709           objType[jj] = GlobalObject::gtHTMHF;
3710         } break;
3711         case esObjectType::TOWERCOUNT: {
3712           objType[jj] = GlobalObject::gtTowerCount;
3713         } break;
3714         default: {
3715         } break;
3716       }
3717       condCateg[jj] = CondEnergySum;
3718 
3719     } else {
3720       edm::LogError("TriggerMenuParser") << "Illegal Object Type " << object.getType()
3721                                          << " for the correlation condition " << name << std::endl;
3722       return false;
3723 
3724     }  //if block on leg types
3725 
3726   }  //loop over legs
3727 
3728   // get greater equal flag for the correlation condition
3729   bool gEq = true;
3730   if (intGEq[0] != intGEq[1]) {
3731     edm::LogError("TriggerMenuParser") << "Inconsistent GEq flags for sub-conditions "
3732                                        << " for the correlation condition " << name << std::endl;
3733     return false;
3734 
3735   } else {
3736     gEq = (intGEq[0] != 0);
3737   }
3738 
3739   // fill the correlation condition
3740   correlationWORCond.setCondType(cType);
3741   correlationWORCond.setObjectType(objType);
3742   correlationWORCond.setCondGEq(gEq);
3743   correlationWORCond.setCondChipNr(chipNr);
3744 
3745   correlationWORCond.setCond0Category(condCateg[0]);
3746   correlationWORCond.setCond1Category(condCateg[1]);
3747   correlationWORCond.setCond2Category(condCateg[2]);
3748 
3749   correlationWORCond.setCond0Index(corrIndexVal[0]);
3750   correlationWORCond.setCond1Index(corrIndexVal[1]);
3751   correlationWORCond.setCond2Index(corrIndexVal[2]);
3752 
3753   correlationWORCond.setCorrelationWithOverlapRemovalParameter(corrParameter);
3754 
3755   if (edm::isDebugEnabled()) {
3756     std::ostringstream myCoutStream;
3757     correlationWORCond.print(myCoutStream);
3758     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
3759   }
3760 
3761   // insert condition into the map
3762   // condition is not duplicate, check was done at the beginning
3763 
3764   (m_vecCorrelationWithOverlapRemovalTemplate[chipNr]).push_back(correlationWORCond);
3765 
3766   //
3767   return true;
3768 }
3769 
3770 /**
3771  * workAlgorithm - parse the algorithm and insert it into algorithm map.
3772  *
3773  * @param node The corresponding node to the algorithm.
3774  * @param name The name of the algorithm.
3775  * @param chipNr The number of the chip the conditions for that algorithm are located on.
3776  *
3777  * @return "true" on success, "false" if an error occurred.
3778  *
3779  */
3780 
3781 bool l1t::TriggerMenuParser::parseAlgorithm(L1TUtmAlgorithm algorithm, unsigned int chipNr) {
3782   // get alias
3783   std::string algAlias = algorithm.getName();
3784   const std::string& algName = algorithm.getName();
3785 
3786   if (algAlias.empty()) {
3787     algAlias = algName;
3788     LogDebug("TriggerMenuParser") << "\n    No alias defined for algorithm. Alias set to algorithm name."
3789                                   << "\n    Algorithm name:  " << algName << "\n    Algorithm alias: " << algAlias
3790                                   << std::endl;
3791   } else {
3792     //LogDebug("TriggerMenuParser")
3793     LogDebug("TriggerMenuParser") << "\n    Alias defined for algorithm."
3794                                   << "\n    Algorithm name:  " << algName << "\n    Algorithm alias: " << algAlias
3795                                   << std::endl;
3796   }
3797 
3798   // get the logical expression
3799   const std::string& logExpression = algorithm.getExpressionInCondition();
3800 
3801   LogDebug("TriggerMenuParser") << "      Logical expression: " << logExpression
3802                                 << "      Chip number:        " << chipNr << std::endl;
3803 
3804   // determine output pin
3805   int outputPin = algorithm.getIndex();
3806 
3807   //LogTrace("TriggerMenuParser")
3808   LogDebug("TriggerMenuParser") << "      Output pin:         " << outputPin << std::endl;
3809 
3810   // compute the bit number from chip number, output pin and order of the chips
3811   // pin numbering start with 1, bit numbers with 0
3812   int bitNumber = outputPin;  // + (m_orderConditionChip[chipNr] -1)*m_pinsOnConditionChip -1;
3813 
3814   //LogTrace("TriggerMenuParser")
3815   LogDebug("TriggerMenuParser") << "      Bit number:         " << bitNumber << std::endl;
3816 
3817   // create a new algorithm and insert it into algorithm map
3818   GlobalAlgorithm alg(algName, logExpression, bitNumber);
3819   alg.setAlgoChipNumber(static_cast<int>(chipNr));
3820   alg.setAlgoAlias(algAlias);
3821 
3822   if (edm::isDebugEnabled()) {
3823     std::ostringstream myCoutStream;
3824     alg.print(myCoutStream);
3825     LogTrace("TriggerMenuParser") << myCoutStream.str() << "\n" << std::endl;
3826   }
3827 
3828   // insert algorithm into the map
3829   if (!insertAlgorithmIntoMap(alg)) {
3830     return false;
3831   }
3832 
3833   return true;
3834 }
3835 // static class members