Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-01-14 23:16:59

0001 /**
0002  * \class CorrCondition
0003  *
0004  *
0005  * Description: evaluation of a correlation condition.
0006  *
0007  * Implementation:
0008  *    <TODO: enter implementation details>
0009  *
0010  *\new features: Dragana Pilipovic
0011  *                - updated for invariant mass over delta R condition*
0012  */
0013 
0014 // this class header
0015 #include "L1Trigger/L1TGlobal/interface/CorrCondition.h"
0016 
0017 // system include files
0018 #include <iostream>
0019 #include <iomanip>
0020 
0021 #include <string>
0022 #include <vector>
0023 #include <algorithm>
0024 
0025 // user include files
0026 //   base classes
0027 #include "L1Trigger/L1TGlobal/interface/CorrelationTemplate.h"
0028 #include "L1Trigger/L1TGlobal/interface/ConditionEvaluation.h"
0029 
0030 #include "L1Trigger/L1TGlobal/interface/MuCondition.h"
0031 #include "L1Trigger/L1TGlobal/interface/CaloCondition.h"
0032 #include "L1Trigger/L1TGlobal/interface/EnergySumCondition.h"
0033 #include "L1Trigger/L1TGlobal/interface/MuonTemplate.h"
0034 #include "L1Trigger/L1TGlobal/interface/CaloTemplate.h"
0035 #include "L1Trigger/L1TGlobal/interface/EnergySumTemplate.h"
0036 #include "L1Trigger/L1TGlobal/interface/GlobalScales.h"
0037 
0038 #include "DataFormats/L1Trigger/interface/L1Candidate.h"
0039 
0040 #include "L1Trigger/L1TGlobal/interface/GlobalBoard.h"
0041 
0042 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0043 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0044 
0045 // constructors
0046 //     default
0047 l1t::CorrCondition::CorrCondition() : ConditionEvaluation() {}
0048 
0049 //     from base template condition (from event setup usually)
0050 l1t::CorrCondition::CorrCondition(const GlobalCondition* corrTemplate,
0051                                   const GlobalCondition* cond0Condition,
0052                                   const GlobalCondition* cond1Condition,
0053                                   const GlobalBoard* ptrGTB,
0054                                   const GlobalScales* ptrGS)
0055     : ConditionEvaluation(),
0056       m_gtCorrelationTemplate(static_cast<const CorrelationTemplate*>(corrTemplate)),
0057       m_gtCond0(cond0Condition),
0058       m_gtCond1(cond1Condition),
0059       m_uGtB(ptrGTB),
0060       m_gtScales(ptrGS) {}
0061 
0062 // copy constructor
0063 void l1t::CorrCondition::copy(const l1t::CorrCondition& cp) {
0064   m_gtCorrelationTemplate = cp.gtCorrelationTemplate();
0065   m_uGtB = cp.getuGtB();
0066   m_gtScales = cp.getScales();
0067 
0068   m_condMaxNumberObjects = cp.condMaxNumberObjects();
0069   m_condLastResult = cp.condLastResult();
0070   m_combinationsInCond = cp.getCombinationsInCond();
0071 
0072   m_verbosity = cp.m_verbosity;
0073 }
0074 
0075 l1t::CorrCondition::CorrCondition(const l1t::CorrCondition& cp) : ConditionEvaluation() { copy(cp); }
0076 
0077 // destructor
0078 l1t::CorrCondition::~CorrCondition() {
0079   // empty
0080 }
0081 
0082 // equal operator
0083 l1t::CorrCondition& l1t::CorrCondition::operator=(const l1t::CorrCondition& cp) {
0084   copy(cp);
0085   return *this;
0086 }
0087 
0088 // methods
0089 void l1t::CorrCondition::setGtCorrelationTemplate(const CorrelationTemplate* caloTempl) {
0090   m_gtCorrelationTemplate = caloTempl;
0091 }
0092 
0093 ///   set the pointer to uGT GlobalBoard
0094 void l1t::CorrCondition::setuGtB(const GlobalBoard* ptrGTB) { m_uGtB = ptrGTB; }
0095 
0096 void l1t::CorrCondition::setScales(const GlobalScales* sc) { m_gtScales = sc; }
0097 
0098 // try all object permutations and check spatial correlations, if required
0099 const bool l1t::CorrCondition::evaluateCondition(const int bxEval) const {
0100   // std::cout << "m_isDebugEnabled = " << m_isDebugEnabled << std::endl;
0101   // std::cout << "m_verbosity = " << m_verbosity << std::endl;
0102 
0103   //std::ostringstream myCout;
0104   //m_gtCorrelationTemplate->print(myCout);
0105   //LogDebug("L1TGlobal")
0106   //   << "Correlation Condition Evaluation \n" << myCout.str() << std::endl;
0107 
0108   bool condResult = false;
0109   bool reqObjResult = false;
0110 
0111   // number of objects in condition (it is 2, no need to retrieve from
0112   // condition template) and their type
0113   int nObjInCond = 2;
0114   std::vector<GlobalObject> cndObjTypeVec(nObjInCond);
0115 
0116   // evaluate first the two sub-conditions (Type1s)
0117 
0118   const GtConditionCategory cond0Categ = m_gtCorrelationTemplate->cond0Category();
0119   const GtConditionCategory cond1Categ = m_gtCorrelationTemplate->cond1Category();
0120 
0121   //Decide if we have a mixed (muon + cal) condition
0122   bool convertCaloScales = false;
0123   if ((cond0Categ == CondMuon && (cond1Categ == CondCalo || cond1Categ == CondEnergySum)) ||
0124       (cond1Categ == CondMuon && (cond0Categ == CondCalo || cond0Categ == CondEnergySum)))
0125     convertCaloScales = true;
0126 
0127   const MuonTemplate* corrMuon = nullptr;
0128   const CaloTemplate* corrCalo = nullptr;
0129   const EnergySumTemplate* corrEnergySum = nullptr;
0130 
0131   // FIXME copying is slow...
0132   CombinationsWithBxInCond cond0Comb{};
0133   CombinationsWithBxInCond cond1Comb{};
0134 
0135   switch (cond0Categ) {
0136     case CondMuon: {
0137       corrMuon = static_cast<const MuonTemplate*>(m_gtCond0);
0138       MuCondition muCondition(
0139           corrMuon, m_uGtB, 0, 0);  //BLW these are counts that don't seem to be used...perhaps remove
0140 
0141       muCondition.evaluateConditionStoreResult(bxEval);
0142       reqObjResult = muCondition.condLastResult();
0143 
0144       cond0Comb = (muCondition.getCombinationsInCond());
0145 
0146       cndObjTypeVec[0] = (corrMuon->objectType())[0];
0147 
0148       if (m_verbosity) {
0149         std::ostringstream myCout;
0150         muCondition.print(myCout);
0151 
0152         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0153       }
0154     } break;
0155     case CondCalo: {
0156       corrCalo = static_cast<const CaloTemplate*>(m_gtCond0);
0157 
0158       CaloCondition caloCondition(
0159           corrCalo, m_uGtB, 0, 0, 0, 0);  //BLW these are counters that don't seem to be used...perhaps remove.
0160 
0161       caloCondition.evaluateConditionStoreResult(bxEval);
0162       reqObjResult = caloCondition.condLastResult();
0163 
0164       cond0Comb = (caloCondition.getCombinationsInCond());
0165 
0166       cndObjTypeVec[0] = (corrCalo->objectType())[0];
0167 
0168       if (m_verbosity) {
0169         std::ostringstream myCout;
0170         caloCondition.print(myCout);
0171 
0172         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0173       }
0174     } break;
0175     case CondEnergySum: {
0176       corrEnergySum = static_cast<const EnergySumTemplate*>(m_gtCond0);
0177       EnergySumCondition eSumCondition(corrEnergySum, m_uGtB);
0178 
0179       eSumCondition.evaluateConditionStoreResult(bxEval);
0180       reqObjResult = eSumCondition.condLastResult();
0181 
0182       cond0Comb = (eSumCondition.getCombinationsInCond());
0183 
0184       cndObjTypeVec[0] = (corrEnergySum->objectType())[0];
0185 
0186       if (m_verbosity) {
0187         std::ostringstream myCout;
0188         eSumCondition.print(myCout);
0189 
0190         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0191       }
0192     } break;
0193     default: {
0194       // should not arrive here, there are no correlation conditions defined for this object
0195       return false;
0196     } break;
0197   }
0198 
0199   // return if first subcondition is false
0200   if (!reqObjResult) {
0201     LogDebug("L1TGlobal") << "\n  First sub-condition false, second sub-condition not evaluated and not printed."
0202                           << std::endl;
0203     return false;
0204   }
0205 
0206   // second object
0207   switch (cond1Categ) {
0208     case CondMuon: {
0209       corrMuon = static_cast<const MuonTemplate*>(m_gtCond1);
0210       MuCondition muCondition(
0211           corrMuon, m_uGtB, 0, 0);  //BLW these are counts that don't seem to be used...perhaps remove
0212 
0213       muCondition.evaluateConditionStoreResult(bxEval);
0214       reqObjResult = muCondition.condLastResult();
0215 
0216       cond1Comb = (muCondition.getCombinationsInCond());
0217 
0218       cndObjTypeVec[1] = (corrMuon->objectType())[0];
0219 
0220       if (m_verbosity) {
0221         std::ostringstream myCout;
0222         muCondition.print(myCout);
0223 
0224         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0225       }
0226     } break;
0227     case CondCalo: {
0228       corrCalo = static_cast<const CaloTemplate*>(m_gtCond1);
0229       CaloCondition caloCondition(
0230           corrCalo, m_uGtB, 0, 0, 0, 0);  //BLW these are counters that don't seem to be used...perhaps remove.
0231 
0232       caloCondition.evaluateConditionStoreResult(bxEval);
0233       reqObjResult = caloCondition.condLastResult();
0234 
0235       cond1Comb = (caloCondition.getCombinationsInCond());
0236 
0237       cndObjTypeVec[1] = (corrCalo->objectType())[0];
0238 
0239       if (m_verbosity) {
0240         std::ostringstream myCout;
0241         caloCondition.print(myCout);
0242 
0243         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0244       }
0245 
0246     } break;
0247     case CondEnergySum: {
0248       corrEnergySum = static_cast<const EnergySumTemplate*>(m_gtCond1);
0249 
0250       EnergySumCondition eSumCondition(corrEnergySum, m_uGtB);
0251 
0252       eSumCondition.evaluateConditionStoreResult(bxEval);
0253       reqObjResult = eSumCondition.condLastResult();
0254 
0255       cond1Comb = (eSumCondition.getCombinationsInCond());
0256 
0257       cndObjTypeVec[1] = (corrEnergySum->objectType())[0];
0258 
0259       if (m_verbosity) {
0260         std::ostringstream myCout;
0261         eSumCondition.print(myCout);
0262 
0263         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0264       }
0265     } break;
0266     default: {
0267       // should not arrive here, there are no correlation conditions defined for this object
0268       return false;
0269     } break;
0270   }
0271 
0272   // return if second sub-condition is false
0273   if (!reqObjResult) {
0274     return false;
0275   } else {
0276     LogDebug("L1TGlobal") << "\n"
0277                           << "    Both sub-conditions true for object requirements."
0278                           << "    Evaluate correlation requirements.\n"
0279                           << std::endl;
0280   }
0281 
0282   // since we have two good legs get the correlation parameters
0283   CorrelationTemplate::CorrelationParameter corrPar = *(m_gtCorrelationTemplate->correlationParameter());
0284 
0285   // vector to store the indices of the calorimeter objects
0286   // from the combination evaluated in the condition
0287   SingleCombWithBxInCond objectsInComb;
0288   objectsInComb.reserve(nObjInCond);
0289 
0290   // clear the m_combinationsInCond vector
0291   (combinationsInCond()).clear();
0292 
0293   // pointers to objects
0294   const BXVector<const l1t::Muon*>* candMuVec = nullptr;
0295   const BXVector<const l1t::L1Candidate*>* candCaloVec = nullptr;
0296   const BXVector<const l1t::EtSum*>* candEtSumVec = nullptr;
0297 
0298   bool etSumCond = false;
0299 
0300   // make the conversions of the indices, depending on the combination of objects involved
0301   // (via pair index)
0302 
0303   int phiIndex0 = 0;
0304   double phi0Phy = 0.;
0305   int phiIndex1 = 0;
0306   double phi1Phy = 0.;
0307 
0308   int etaIndex0 = 0;
0309   double eta0Phy = 0.;
0310   int etaIndex1 = 0;
0311   double eta1Phy = 0.;
0312   int etaBin0 = 0;
0313   int etaBin1 = 0;
0314 
0315   int etIndex0 = 0;
0316   int etBin0 = 0;
0317   double et0Phy = 0.;
0318   int etIndex1 = 0;
0319   int etBin1 = 0;
0320   double et1Phy = 0.;
0321 
0322   int uptIndex0 = 0;     // Added displaced muons
0323   int uptBin0 = 0;       // Added displaced muons
0324   double upt0Phy = 0.0;  // Added displaced muons
0325   int uptIndex1 = 0;     // Added displaced muons
0326   int uptBin1 = 0;       // Added displaced muons
0327   double upt1Phy = 0.0;  // Added displaced muons
0328 
0329   int chrg0 = -1;
0330   int chrg1 = -1;
0331 
0332   // Determine the number of phi bins to get cutoff at pi
0333   int phiBound = 0;
0334   if (cond0Categ == CondMuon || cond1Categ == CondMuon) {
0335     const GlobalScales::ScaleParameters& par = m_gtScales->getMUScales();
0336     //phiBound = par.phiBins.size()/2;
0337     phiBound = (int)((par.phiMax - par.phiMin) / par.phiStep) / 2;
0338   } else {
0339     //Assumes all calorimeter objects are on same phi scale
0340     const GlobalScales::ScaleParameters& par = m_gtScales->getEGScales();
0341     //phiBound = par.phiBins.size()/2;
0342     phiBound = (int)((par.phiMax - par.phiMin) / par.phiStep) / 2;
0343   }
0344   LogDebug("L1TGlobal") << "Phi Bound = " << phiBound << std::endl;
0345 
0346   //          BUILD THE 1/dR2 LUT BASED ON CONDITION
0347   int iRSq = 0;
0348   int jRSq = 0;
0349   int iRSqmax = 227;
0350   int jRSqmax = 145;
0351   double tempRsq = 0.0;
0352   double tempdiffeta = 0.0435;
0353   double tempdiffphi = 0.02181661564992912;
0354   double resolution = 1.0;
0355   unsigned int precInvRsq = 0x5;
0356   if (cond0Categ == CondMuon || cond1Categ == CondMuon) {
0357     LogTrace("L1TGlobal") << "  Building 1/dR2 for Muon " << std::endl;
0358     tempdiffeta = tempdiffeta / 2.0;
0359     resolution = 0.5;
0360   } else {
0361     LogTrace("L1TGlobal") << "  Building 1/dR2 for Calo " << std::endl;
0362     iRSqmax = 231;
0363     jRSqmax = 73;
0364     tempdiffphi = 0.04363323129985824;
0365   }
0366   long long InvDeltaRSqLUT[iRSqmax][jRSqmax];
0367   double temp_InvDeltaRSq[iRSqmax][jRSqmax];
0368   if (corrPar.corrCutType & 0x80) {  //Only build the 1/dR2 LUT if necessary
0369     for (iRSq = 0; iRSq < iRSqmax; iRSq = iRSq + 1) {
0370       for (jRSq = 0; jRSq < jRSqmax; jRSq = jRSq + 1) {
0371         tempRsq = (tempdiffeta * iRSq) * (tempdiffeta * iRSq) + (tempdiffphi * jRSq) * (tempdiffphi * jRSq);
0372         if (tempRsq > 0.0) {
0373           temp_InvDeltaRSq[iRSq][jRSq] = 1.0 / tempRsq;
0374           InvDeltaRSqLUT[iRSq][jRSq] = (long long)round(pow(10, precInvRsq) * temp_InvDeltaRSq[iRSq][jRSq]);
0375         } else {
0376           temp_InvDeltaRSq[iRSq][jRSq] = 0.0;
0377           InvDeltaRSqLUT[iRSq][jRSq] = (long long)0;
0378         }
0379       }
0380     }
0381   }
0382 
0383   // Keep track of objects for LUTS
0384   std::string lutObj0 = "NULL";
0385   std::string lutObj1 = "NULL";
0386 
0387   LogTrace("L1TGlobal") << "  Sub-condition 0: std::vector<SingleCombWithBxInCond> size: " << cond0Comb.size();
0388   LogTrace("L1TGlobal") << "  Sub-condition 1: std::vector<SingleCombWithBxInCond> size: " << cond1Comb.size();
0389 
0390   // loop over all combinations which produced individually "true" as Type1s
0391   //
0392   // BLW: Optimization issue: potentially making the same comparison twice
0393   //                          if both legs are the same object type.
0394   for (auto const& it0Comb : cond0Comb) {
0395     // Type1s: there is 1 object only, no need for a loop, index 0 should be OK in it0Comb[0]
0396     // ... but add protection to not crash
0397     if (it0Comb.empty()) {
0398       LogTrace("L1TGlobal") << "\n  SingleCombWithBxInCond it0Comb.size() " << it0Comb.size();
0399       return false;
0400     }
0401 
0402     auto const cond0bx = it0Comb[0].first;
0403     auto const obj0Index = it0Comb[0].second;
0404 
0405     // Collect the information on the first leg of the correlation
0406     switch (cond0Categ) {
0407       case CondMuon: {
0408         lutObj0 = "MU";
0409         candMuVec = m_uGtB->getCandL1Mu();
0410         phiIndex0 = (candMuVec->at(cond0bx, obj0Index))->hwPhiAtVtx();  //(*candMuVec)[obj0Index]->phiIndex();
0411         etaIndex0 = (candMuVec->at(cond0bx, obj0Index))->hwEtaAtVtx();
0412         etIndex0 = (candMuVec->at(cond0bx, obj0Index))->hwPt();
0413         uptIndex0 = (candMuVec->at(cond0bx, obj0Index))->hwPtUnconstrained();  // Added for displaced muons
0414         chrg0 = (candMuVec->at(cond0bx, obj0Index))->hwCharge();
0415         int etaBin0 = etaIndex0;
0416         if (etaBin0 < 0)
0417           etaBin0 = m_gtScales->getMUScales().etaBins.size() + etaBin0;  //twos complement
0418 
0419         etBin0 = etIndex0;
0420         uptBin0 = uptIndex0;  // Added for displaced muons
0421         int ssize = m_gtScales->getMUScales().etBins.size();
0422         if (etBin0 >= ssize) {
0423           etBin0 = ssize - 1;
0424           LogTrace("L1TGlobal") << "muon0 hw et" << etBin0 << " out of scale range.  Setting to maximum.";
0425         }
0426 
0427         // Determine Floating Pt numbers for floating point caluclation
0428         std::pair<double, double> binEdges = m_gtScales->getMUScales().phiBins.at(phiIndex0);
0429         phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0430         binEdges = m_gtScales->getMUScales().etaBins.at(etaBin0);
0431         eta0Phy = 0.5 * (binEdges.second + binEdges.first);
0432         binEdges = m_gtScales->getMUScales().etBins.at(etBin0);
0433         et0Phy = 0.5 * (binEdges.second + binEdges.first);
0434         if (corrPar.corrCutType & 0x40)  // Added for displaced muons
0435         {
0436           binEdges = m_gtScales->getMUScales().uptBins.at(uptBin0);
0437           upt0Phy = 0.5 * (binEdges.second + binEdges.first);
0438         }
0439         LogDebug("L1TGlobal") << "Found all quantities for the muon 0" << std::endl;
0440       } break;
0441 
0442         // Calorimeter Objects (EG, Jet, Tau)
0443       case CondCalo: {
0444         switch (cndObjTypeVec[0]) {
0445           case gtEG: {
0446             lutObj0 = "EG";
0447             candCaloVec = m_uGtB->getCandL1EG();
0448             phiIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwPhi();
0449             etaIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwEta();
0450             etIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwPt();
0451             etaBin0 = etaIndex0;
0452             if (etaBin0 < 0)
0453               etaBin0 = m_gtScales->getEGScales().etaBins.size() + etaBin0;
0454             //          LogDebug("L1TGlobal") << "EG0 phi" << phiIndex0 << " eta " << etaIndex0 << " etaBin0 = " << etaBin0 << " et " << etIndex0 << std::endl;
0455 
0456             etBin0 = etIndex0;
0457             int ssize = m_gtScales->getEGScales().etBins.size();
0458             if (etBin0 >= ssize) {
0459               etBin0 = ssize - 1;
0460               LogTrace("L1TGlobal") << "EG0 hw et" << etBin0 << " out of scale range.  Setting to maximum.";
0461             }
0462 
0463             // Determine Floating Pt numbers for floating point caluclation
0464             std::pair<double, double> binEdges = m_gtScales->getEGScales().phiBins.at(phiIndex0);
0465             phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0466             binEdges = m_gtScales->getEGScales().etaBins.at(etaBin0);
0467             eta0Phy = 0.5 * (binEdges.second + binEdges.first);
0468             binEdges = m_gtScales->getEGScales().etBins[etBin0];
0469             et0Phy = 0.5 * (binEdges.second + binEdges.first);
0470 
0471           } break;
0472           case gtJet: {
0473             lutObj0 = "JET";
0474             candCaloVec = m_uGtB->getCandL1Jet();
0475             phiIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwPhi();
0476             etaIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwEta();
0477             etIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwPt();
0478             etaBin0 = etaIndex0;
0479             if (etaBin0 < 0)
0480               etaBin0 = m_gtScales->getJETScales().etaBins.size() + etaBin0;
0481 
0482             etBin0 = etIndex0;
0483             int ssize = m_gtScales->getJETScales().etBins.size();
0484             if (etBin0 >= ssize) {
0485               //edm::LogWarning("L1TGlobal")
0486               //<< "jet0 hw et" << etBin0 << " out of scale range.  Setting to maximum.";
0487               etBin0 = ssize - 1;
0488             }
0489 
0490             // Determine Floating Pt numbers for floating point caluclation
0491             std::pair<double, double> binEdges = m_gtScales->getJETScales().phiBins.at(phiIndex0);
0492             phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0493             binEdges = m_gtScales->getJETScales().etaBins.at(etaBin0);
0494             eta0Phy = 0.5 * (binEdges.second + binEdges.first);
0495             binEdges = m_gtScales->getJETScales().etBins.at(etBin0);
0496             et0Phy = 0.5 * (binEdges.second + binEdges.first);
0497 
0498           } break;
0499           case gtTau: {
0500             candCaloVec = m_uGtB->getCandL1Tau();
0501             phiIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwPhi();
0502             etaIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwEta();
0503             etIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwPt();
0504             etaBin0 = etaIndex0;
0505             if (etaBin0 < 0)
0506               etaBin0 = m_gtScales->getTAUScales().etaBins.size() + etaBin0;
0507 
0508             etBin0 = etIndex0;
0509             int ssize = m_gtScales->getTAUScales().etBins.size();
0510             if (etBin0 >= ssize) {
0511               etBin0 = ssize - 1;
0512               LogTrace("L1TGlobal") << "tau0 hw et" << etBin0 << " out of scale range.  Setting to maximum.";
0513             }
0514 
0515             // Determine Floating Pt numbers for floating point caluclation
0516             std::pair<double, double> binEdges = m_gtScales->getTAUScales().phiBins.at(phiIndex0);
0517             phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0518             binEdges = m_gtScales->getTAUScales().etaBins.at(etaBin0);
0519             eta0Phy = 0.5 * (binEdges.second + binEdges.first);
0520             binEdges = m_gtScales->getTAUScales().etBins.at(etBin0);
0521             et0Phy = 0.5 * (binEdges.second + binEdges.first);
0522             lutObj0 = "TAU";
0523           } break;
0524           default: {
0525           } break;
0526         }  //end switch on calo type.
0527 
0528         //If needed convert calo scales to muon scales for comparison
0529         if (convertCaloScales) {
0530           std::string lutName = lutObj0;
0531           lutName += "-MU";
0532           long long tst = m_gtScales->getLUT_CalMuEta(lutName, etaBin0);
0533           LogDebug("L1TGlobal") << lutName << "  EtaCal = " << etaIndex0 << " etaBin0 = " << etaBin0
0534                                 << " EtaMu = " << tst << std::endl;
0535           etaIndex0 = tst;
0536 
0537           tst = m_gtScales->getLUT_CalMuPhi(lutName, phiIndex0);
0538           LogDebug("L1TGlobal") << lutName << "  PhiCal = " << phiIndex0 << " PhiMu = " << tst << std::endl;
0539           phiIndex0 = tst;
0540         }
0541 
0542       } break;
0543 
0544         // Energy Sums
0545       case CondEnergySum: {
0546         etSumCond = true;
0547         //Stupid mapping between enum types for energy sums.
0548         l1t::EtSum::EtSumType type;
0549         switch (cndObjTypeVec[0]) {
0550           case gtETM:
0551             type = l1t::EtSum::EtSumType::kMissingEt;
0552             lutObj0 = "ETM";
0553             break;
0554           case gtETT:
0555             type = l1t::EtSum::EtSumType::kTotalEt;
0556             lutObj0 = "ETT";
0557             break;
0558           case gtETTem:
0559             type = l1t::EtSum::EtSumType::kTotalEtEm;
0560             lutObj0 =
0561                 "ETTem";  //should this be just ETT (share LUTs?) Can't be used for CorrCond anyway since now directional information
0562             break;
0563           case gtHTM:
0564             type = l1t::EtSum::EtSumType::kMissingHt;
0565             lutObj0 = "HTM";
0566             break;
0567           case gtHTT:
0568             type = l1t::EtSum::EtSumType::kTotalHt;
0569             lutObj0 = "HTT";
0570             break;
0571           case gtETMHF:
0572             type = l1t::EtSum::EtSumType::kMissingEtHF;
0573             lutObj0 = "ETMHF";
0574             break;
0575           case gtHTMHF:
0576             type = l1t::EtSum::EtSumType::kMissingHtHF;
0577             lutObj0 = "HTMHF";
0578             break;
0579           case gtMinBiasHFP0:
0580           case gtMinBiasHFM0:
0581           case gtMinBiasHFP1:
0582           case gtMinBiasHFM1:
0583             type = l1t::EtSum::EtSumType::kMinBiasHFP0;
0584             lutObj0 =
0585                 "MinBias";  //??Fix?? Not a valid LUT type Can't be used for CorrCond anyway since now directional information
0586             break;
0587           default:
0588             edm::LogError("L1TGlobal") << "\n  Error: "
0589                                        << "Unmatched object type from template to EtSumType, cndObjTypeVec[0] = "
0590                                        << cndObjTypeVec[0] << std::endl;
0591             type = l1t::EtSum::EtSumType::kTotalEt;
0592             break;
0593         }
0594 
0595         candEtSumVec = m_uGtB->getCandL1EtSum();
0596 
0597         for (int iEtSum = 0; iEtSum < (int)candEtSumVec->size(cond0bx); iEtSum++) {
0598           if ((candEtSumVec->at(cond0bx, iEtSum))->getType() == type) {
0599             phiIndex0 = (candEtSumVec->at(cond0bx, iEtSum))->hwPhi();
0600             etaIndex0 = (candEtSumVec->at(cond0bx, iEtSum))->hwEta();
0601             etIndex0 = (candEtSumVec->at(cond0bx, iEtSum))->hwPt();
0602 
0603             //  Get the floating point numbers
0604             if (cndObjTypeVec[0] == gtETM) {
0605               std::pair<double, double> binEdges = m_gtScales->getETMScales().phiBins.at(phiIndex0);
0606               phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0607               eta0Phy = 0.;  //No Eta for Energy Sums
0608 
0609               etBin0 = etIndex0;
0610               int ssize = m_gtScales->getETMScales().etBins.size();
0611               assert(ssize > 0);
0612               if (etBin0 >= ssize) {
0613                 etBin0 = ssize - 1;
0614               }
0615 
0616               binEdges = m_gtScales->getETMScales().etBins.at(etBin0);
0617               et0Phy = 0.5 * (binEdges.second + binEdges.first);
0618             } else if (cndObjTypeVec[0] == gtHTM) {
0619               std::pair<double, double> binEdges = m_gtScales->getHTMScales().phiBins.at(phiIndex0);
0620               phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0621               eta0Phy = 0.;  //No Eta for Energy Sums
0622 
0623               etBin0 = etIndex0;
0624               int ssize = m_gtScales->getHTMScales().etBins.size();
0625               assert(ssize > 0);
0626               if (etBin0 >= ssize) {
0627                 etBin0 = ssize - 1;
0628               }
0629 
0630               binEdges = m_gtScales->getHTMScales().etBins.at(etBin0);
0631               et0Phy = 0.5 * (binEdges.second + binEdges.first);
0632             } else if (cndObjTypeVec[0] == gtETMHF) {
0633               std::pair<double, double> binEdges = m_gtScales->getETMHFScales().phiBins.at(phiIndex0);
0634               phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0635               eta0Phy = 0.;  //No Eta for Energy Sums
0636 
0637               etBin0 = etIndex0;
0638               int ssize = m_gtScales->getETMHFScales().etBins.size();
0639               assert(ssize > 0);
0640               if (etBin0 >= ssize) {
0641                 etBin0 = ssize - 1;
0642               }
0643 
0644               binEdges = m_gtScales->getETMHFScales().etBins.at(etBin0);
0645               et0Phy = 0.5 * (binEdges.second + binEdges.first);
0646             } else if (cndObjTypeVec[0] == gtHTMHF) {
0647               std::pair<double, double> binEdges = m_gtScales->getHTMHFScales().phiBins.at(phiIndex0);
0648               phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0649               eta0Phy = 0.;  //No Eta for Energy Sums
0650 
0651               etBin0 = etIndex0;
0652               int ssize = m_gtScales->getHTMHFScales().etBins.size();
0653               assert(ssize > 0);
0654               if (etBin0 >= ssize) {
0655                 etBin0 = ssize - 1;
0656               }
0657 
0658               binEdges = m_gtScales->getHTMHFScales().etBins.at(etBin0);
0659               et0Phy = 0.5 * (binEdges.second + binEdges.first);
0660             }
0661 
0662             //If needed convert calo scales to muon scales for comparison (only phi for energy sums)
0663             if (convertCaloScales) {
0664               std::string lutName = lutObj0;
0665               lutName += "-MU";
0666               long long tst = m_gtScales->getLUT_CalMuPhi(lutName, phiIndex0);
0667               LogDebug("L1TGlobal") << lutName << "  PhiCal = " << phiIndex0 << " PhiMu = " << tst << std::endl;
0668               phiIndex0 = tst;
0669             }
0670 
0671           }  //check it is the EtSum we want
0672         }  // loop over Etsums
0673 
0674       } break;
0675 
0676       default: {
0677         // should not arrive here, there are no correlation conditions defined for this object
0678         LogDebug("L1TGlobal") << "Error could not find the Cond Category for Leg 0" << std::endl;
0679         return false;
0680       } break;
0681     }  //end switch on first leg type
0682 
0683     // Now loop over the second leg to get its information
0684     for (auto const& it1Comb : cond1Comb) {
0685       LogDebug("L1TGlobal") << "Looking at second Condition";
0686       // Type1s: there is 1 object only, no need for a loop it1Comb[0]
0687       // ... but add protection to not crash
0688       if (it1Comb.empty()) {
0689         LogTrace("L1TGlobal") << "\n  SingleCombWithBxInCond it1Comb.size() " << it1Comb.size();
0690         return false;
0691       }
0692 
0693       auto const cond1bx = it1Comb[0].first;
0694       auto const obj1Index = it1Comb[0].second;
0695 
0696       //If we are dealing with the same object type avoid the two legs
0697       // either being the same object
0698       if (cndObjTypeVec[0] == cndObjTypeVec[1] && obj0Index == obj1Index && cond0bx == cond1bx) {
0699         LogDebug("L1TGlobal") << "Corr Condition looking at same leg...skip" << std::endl;
0700         continue;
0701       }
0702 
0703       switch (cond1Categ) {
0704         case CondMuon: {
0705           lutObj1 = "MU";
0706           candMuVec = m_uGtB->getCandL1Mu();
0707           phiIndex1 = (candMuVec->at(cond1bx, obj1Index))->hwPhiAtVtx();  //(*candMuVec)[obj0Index]->phiIndex();
0708           etaIndex1 = (candMuVec->at(cond1bx, obj1Index))->hwEtaAtVtx();
0709           etIndex1 = (candMuVec->at(cond1bx, obj1Index))->hwPt();
0710           uptIndex1 = (candMuVec->at(cond1bx, obj1Index))->hwPtUnconstrained();  // Added for displaced muons
0711           chrg1 = (candMuVec->at(cond1bx, obj1Index))->hwCharge();
0712           etaBin1 = etaIndex1;
0713           if (etaBin1 < 0)
0714             etaBin1 = m_gtScales->getMUScales().etaBins.size() + etaBin1;
0715           //           LogDebug("L1TGlobal") << "Muon phi" << phiIndex1 << " eta " << etaIndex1 << " etaBin1 = " << etaBin1  << " et " << etIndex1 << std::endl;
0716 
0717           etBin1 = etIndex1;
0718           uptBin1 = uptIndex1;  // Added for displaced muons
0719           int ssize = m_gtScales->getMUScales().etBins.size();
0720           if (etBin1 >= ssize) {
0721             LogTrace("L1TGlobal") << "muon2 hw et" << etBin1 << " out of scale range.  Setting to maximum.";
0722             etBin1 = ssize - 1;
0723           }
0724 
0725           // Determine Floating Pt numbers for floating point caluclation
0726           std::pair<double, double> binEdges = m_gtScales->getMUScales().phiBins.at(phiIndex1);
0727           phi1Phy = 0.5 * (binEdges.second + binEdges.first);
0728           binEdges = m_gtScales->getMUScales().etaBins.at(etaBin1);
0729           eta1Phy = 0.5 * (binEdges.second + binEdges.first);
0730           binEdges = m_gtScales->getMUScales().etBins.at(etBin1);
0731           et1Phy = 0.5 * (binEdges.second + binEdges.first);
0732           if (corrPar.corrCutType & 0x40)  // Added for displaced muons
0733           {
0734             binEdges = m_gtScales->getMUScales().uptBins.at(uptBin1);
0735             upt1Phy = 0.5 * (binEdges.second + binEdges.first);
0736           }
0737           LogDebug("L1TGlobal") << "Found all quantities for the muon 1" << std::endl;
0738         } break;
0739         case CondCalo: {
0740           switch (cndObjTypeVec[1]) {
0741             case gtEG: {
0742               candCaloVec = m_uGtB->getCandL1EG();
0743               phiIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwPhi();
0744               etaIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwEta();
0745               etIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwPt();
0746               etaBin1 = etaIndex1;
0747               if (etaBin1 < 0)
0748                 etaBin1 = m_gtScales->getEGScales().etaBins.size() + etaBin1;
0749 
0750               etBin1 = etIndex1;
0751               int ssize = m_gtScales->getEGScales().etBins.size();
0752               if (etBin1 >= ssize) {
0753                 LogTrace("L1TGlobal") << "EG1 hw et" << etBin1 << " out of scale range.  Setting to maximum.";
0754                 etBin1 = ssize - 1;
0755               }
0756 
0757               // Determine Floating Pt numbers for floating point caluclation
0758               std::pair<double, double> binEdges = m_gtScales->getEGScales().phiBins.at(phiIndex1);
0759               phi1Phy = 0.5 * (binEdges.second + binEdges.first);
0760               binEdges = m_gtScales->getEGScales().etaBins.at(etaBin1);
0761               eta1Phy = 0.5 * (binEdges.second + binEdges.first);
0762               binEdges = m_gtScales->getEGScales().etBins.at(etBin1);
0763               et1Phy = 0.5 * (binEdges.second + binEdges.first);
0764               lutObj1 = "EG";
0765             } break;
0766             case gtJet: {
0767               candCaloVec = m_uGtB->getCandL1Jet();
0768               phiIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwPhi();
0769               etaIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwEta();
0770               etIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwPt();
0771               etaBin1 = etaIndex1;
0772               if (etaBin1 < 0)
0773                 etaBin1 = m_gtScales->getJETScales().etaBins.size() + etaBin1;
0774 
0775               etBin1 = etIndex1;
0776               int ssize = m_gtScales->getJETScales().etBins.size();
0777               assert(ssize);
0778               if (etBin1 >= ssize) {
0779                 //edm::LogWarning("L1TGlobal")
0780                 //<< "jet2 hw et" << etBin1 << " out of scale range.  Setting to maximum.";
0781                 etBin1 = ssize - 1;
0782               }
0783 
0784               // Determine Floating Pt numbers for floating point caluclation
0785               std::pair<double, double> binEdges = m_gtScales->getJETScales().phiBins.at(phiIndex1);
0786               phi1Phy = 0.5 * (binEdges.second + binEdges.first);
0787               binEdges = m_gtScales->getJETScales().etaBins.at(etaBin1);
0788               eta1Phy = 0.5 * (binEdges.second + binEdges.first);
0789               //CRASHES HERE:
0790               binEdges = m_gtScales->getJETScales().etBins.at(etBin1);
0791               et1Phy = 0.5 * (binEdges.second + binEdges.first);
0792               lutObj1 = "JET";
0793             } break;
0794             case gtTau: {
0795               candCaloVec = m_uGtB->getCandL1Tau();
0796               phiIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwPhi();
0797               etaIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwEta();
0798               etIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwPt();
0799               etaBin1 = etaIndex1;
0800               if (etaBin1 < 0)
0801                 etaBin1 = m_gtScales->getTAUScales().etaBins.size() + etaBin1;
0802 
0803               etBin1 = etIndex1;
0804               int ssize = m_gtScales->getTAUScales().etBins.size();
0805               if (etBin1 >= ssize) {
0806                 LogTrace("L1TGlobal") << "tau2 hw et" << etBin1 << " out of scale range.  Setting to maximum.";
0807                 etBin1 = ssize - 1;
0808               }
0809 
0810               // Determine Floating Pt numbers for floating point caluclation
0811               std::pair<double, double> binEdges = m_gtScales->getTAUScales().phiBins.at(phiIndex1);
0812               phi1Phy = 0.5 * (binEdges.second + binEdges.first);
0813               binEdges = m_gtScales->getTAUScales().etaBins.at(etaBin1);
0814               eta1Phy = 0.5 * (binEdges.second + binEdges.first);
0815               binEdges = m_gtScales->getTAUScales().etBins.at(etBin1);
0816               et1Phy = 0.5 * (binEdges.second + binEdges.first);
0817               lutObj1 = "TAU";
0818             } break;
0819             default: {
0820             } break;
0821           }  //end switch on calo type.
0822 
0823           //If needed convert calo scales to muon scales for comparison
0824           if (convertCaloScales) {
0825             std::string lutName = lutObj1;
0826             lutName += "-MU";
0827             long long tst = m_gtScales->getLUT_CalMuEta(lutName, etaBin1);
0828             LogDebug("L1TGlobal") << lutName << "  EtaCal = " << etaIndex1 << " EtaMu = " << tst << std::endl;
0829             etaIndex1 = tst;
0830 
0831             tst = m_gtScales->getLUT_CalMuPhi(lutName, phiIndex1);
0832             LogDebug("L1TGlobal") << lutName << "  PhiCal = " << phiIndex1 << " PhiMu = " << tst << std::endl;
0833             phiIndex1 = tst;
0834           }
0835 
0836         } break;
0837         case CondEnergySum: {
0838           LogDebug("L1TGlobal") << "Looking at second Condition as Energy Sum: " << cndObjTypeVec[1] << std::endl;
0839           etSumCond = true;
0840 
0841           //Stupid mapping between enum types for energy sums.
0842           l1t::EtSum::EtSumType type;
0843           switch (cndObjTypeVec[1]) {
0844             case gtETM:
0845               type = l1t::EtSum::EtSumType::kMissingEt;
0846               lutObj1 = "ETM";
0847               break;
0848             case gtETT:
0849               type = l1t::EtSum::EtSumType::kTotalEt;
0850               lutObj1 = "ETT";
0851               break;
0852             case gtETTem:
0853               type = l1t::EtSum::EtSumType::kTotalEtEm;
0854               lutObj1 = "ETTem";
0855               break;
0856             case gtHTM:
0857               type = l1t::EtSum::EtSumType::kMissingHt;
0858               lutObj1 = "HTM";
0859               break;
0860             case gtHTT:
0861               type = l1t::EtSum::EtSumType::kTotalHt;
0862               lutObj1 = "HTT";
0863               break;
0864             case gtETMHF:
0865               type = l1t::EtSum::EtSumType::kMissingEtHF;
0866               lutObj1 = "ETMHF";
0867               break;
0868             case gtHTMHF:
0869               type = l1t::EtSum::EtSumType::kMissingHtHF;
0870               lutObj1 = "HTMHF";
0871               break;
0872             case gtMinBiasHFP0:
0873             case gtMinBiasHFM0:
0874             case gtMinBiasHFP1:
0875             case gtMinBiasHFM1:
0876               type = l1t::EtSum::EtSumType::kMinBiasHFP0;
0877               lutObj1 = "MinBias";
0878               break;
0879             default:
0880               edm::LogError("L1TGlobal") << "\n  Error: "
0881                                          << "Unmatched object type from template to EtSumType, cndObjTypeVec[1] = "
0882                                          << cndObjTypeVec[1] << std::endl;
0883               type = l1t::EtSum::EtSumType::kTotalEt;
0884               break;
0885           }
0886 
0887           candEtSumVec = m_uGtB->getCandL1EtSum();
0888 
0889           LogDebug("L1TGlobal") << "obj " << lutObj1 << " Vector Size " << candEtSumVec->size(cond1bx) << std::endl;
0890           for (int iEtSum = 0; iEtSum < (int)candEtSumVec->size(cond1bx); iEtSum++) {
0891             if ((candEtSumVec->at(cond1bx, iEtSum))->getType() == type) {
0892               phiIndex1 = (candEtSumVec->at(cond1bx, iEtSum))->hwPhi();
0893               etaIndex1 = (candEtSumVec->at(cond1bx, iEtSum))->hwEta();
0894               etIndex1 = (candEtSumVec->at(cond1bx, iEtSum))->hwPt();
0895 
0896               // Determine Floating Pt numbers for floating point caluclation
0897 
0898               if (cndObjTypeVec[1] == gtETM) {
0899                 std::pair<double, double> binEdges = m_gtScales->getETMScales().phiBins.at(phiIndex1);
0900                 phi1Phy = 0.5 * (binEdges.second + binEdges.first);
0901                 eta1Phy = 0.;  //No Eta for Energy Sums
0902 
0903                 etBin1 = etIndex1;
0904                 int ssize = m_gtScales->getETMScales().etBins.size();
0905                 assert(ssize > 0);
0906                 if (etBin1 >= ssize) {
0907                   etBin1 = ssize - 1;
0908                 }
0909 
0910                 binEdges = m_gtScales->getETMScales().etBins.at(etBin1);
0911                 et1Phy = 0.5 * (binEdges.second + binEdges.first);
0912               } else if (cndObjTypeVec[1] == gtHTM) {
0913                 std::pair<double, double> binEdges = m_gtScales->getHTMScales().phiBins.at(phiIndex1);
0914                 phi1Phy = 0.5 * (binEdges.second + binEdges.first);
0915                 eta1Phy = 0.;  //No Eta for Energy Sums
0916 
0917                 etBin1 = etIndex1;
0918                 int ssize = m_gtScales->getHTMScales().etBins.size();
0919                 assert(ssize > 0);
0920                 if (etBin1 >= ssize) {
0921                   etBin1 = ssize - 1;
0922                 }
0923 
0924                 binEdges = m_gtScales->getHTMScales().etBins.at(etBin1);
0925                 et1Phy = 0.5 * (binEdges.second + binEdges.first);
0926               } else if (cndObjTypeVec[1] == gtETMHF) {
0927                 std::pair<double, double> binEdges = m_gtScales->getETMHFScales().phiBins.at(phiIndex1);
0928                 phi1Phy = 0.5 * (binEdges.second + binEdges.first);
0929                 eta1Phy = 0.;  //No Eta for Energy Sums
0930 
0931                 etBin1 = etIndex1;
0932                 int ssize = m_gtScales->getETMHFScales().etBins.size();
0933                 assert(ssize > 0);
0934                 if (etBin1 >= ssize) {
0935                   etBin1 = ssize - 1;
0936                 }
0937 
0938                 binEdges = m_gtScales->getETMHFScales().etBins.at(etBin1);
0939                 et1Phy = 0.5 * (binEdges.second + binEdges.first);
0940               } else if (cndObjTypeVec[1] == gtHTMHF) {
0941                 std::pair<double, double> binEdges = m_gtScales->getHTMHFScales().phiBins.at(phiIndex1);
0942                 phi1Phy = 0.5 * (binEdges.second + binEdges.first);
0943                 eta1Phy = 0.;  //No Eta for Energy Sums
0944 
0945                 etBin1 = etIndex1;
0946                 int ssize = m_gtScales->getHTMHFScales().etBins.size();
0947                 assert(ssize > 0);
0948                 if (etBin1 >= ssize) {
0949                   etBin1 = ssize - 1;
0950                 }
0951 
0952                 binEdges = m_gtScales->getHTMHFScales().etBins.at(etBin1);
0953                 et1Phy = 0.5 * (binEdges.second + binEdges.first);
0954               }
0955 
0956               //If needed convert calo scales to muon scales for comparison (only phi for energy sums)
0957               if (convertCaloScales) {
0958                 std::string lutName = lutObj1;
0959                 lutName += "-MU";
0960                 long long tst = m_gtScales->getLUT_CalMuPhi(lutName, phiIndex1);
0961                 LogDebug("L1TGlobal") << lutName << "  PhiCal = " << phiIndex1 << " PhiMu = " << tst << std::endl;
0962                 phiIndex1 = tst;
0963               }
0964 
0965             }  //check it is the EtSum we want
0966           }  // loop over Etsums
0967 
0968         } break;
0969         default: {
0970           // should not arrive here, there are no correlation conditions defined for this object
0971           LogDebug("L1TGlobal") << "Error could not find the Cond Category for Leg 0" << std::endl;
0972           return false;
0973         } break;
0974       }  //end switch on second leg
0975 
0976       if (m_verbosity) {
0977         LogDebug("L1TGlobal") << "    Correlation pair [" << l1t::GlobalObjectEnumToString(cndObjTypeVec[0]) << ", "
0978                               << l1t::GlobalObjectEnumToString(cndObjTypeVec[1]) << "] with collection indices ["
0979                               << obj0Index << ", " << obj1Index << "] "
0980                               << " has: \n"
0981                               << "     Et  value   = [" << etIndex0 << ", " << etIndex1 << "]\n"
0982                               << "     phi indices = [" << phiIndex0 << ", " << phiIndex1 << "]\n"
0983                               << "     eta indices = [" << etaIndex0 << ", " << etaIndex1 << "]\n"
0984                               << "     chrg        = [" << chrg0 << ", " << chrg1 << "]\n";
0985       }
0986 
0987       // Now perform the desired correlation on these two objects. Assume true until we find a contradition
0988       bool reqResult = true;
0989 
0990       // clear the indices in the combination
0991       objectsInComb.clear();
0992 
0993       objectsInComb.emplace_back(cond0bx, obj0Index);
0994       objectsInComb.emplace_back(cond1bx, obj1Index);
0995 
0996       // if we get here all checks were successful for this combination
0997       // set the general result for evaluateCondition to "true"
0998 
0999       // These all require some delta eta and phi calculations.  Do them first...for now real calculation but need to
1000       // revise this to line up with firmware calculations.
1001       double deltaPhiPhy = fabs(phi1Phy - phi0Phy);
1002       if (deltaPhiPhy > M_PI)
1003         deltaPhiPhy = 2. * M_PI - deltaPhiPhy;
1004       double deltaEtaPhy = fabs(eta1Phy - eta0Phy);
1005 
1006       // Determine the integer based delta eta and delta phi
1007       int deltaPhiFW = abs(phiIndex0 - phiIndex1);
1008       if (deltaPhiFW >= phiBound)
1009         deltaPhiFW = 2 * phiBound - deltaPhiFW;
1010       std::string lutName = lutObj0;
1011       lutName += "-";
1012       lutName += lutObj1;
1013       long long deltaPhiLUT = m_gtScales->getLUT_DeltaPhi(lutName, deltaPhiFW);
1014       unsigned int precDeltaPhiLUT = m_gtScales->getPrec_DeltaPhi(lutName);
1015 
1016       int deltaEtaFW = abs(etaIndex0 - etaIndex1);
1017       long long deltaEtaLUT = 0;
1018       unsigned int precDeltaEtaLUT = 0;
1019       if (!etSumCond) {
1020         deltaEtaLUT = m_gtScales->getLUT_DeltaEta(lutName, deltaEtaFW);
1021         precDeltaEtaLUT = m_gtScales->getPrec_DeltaEta(lutName);
1022       }
1023 
1024       //
1025       LogDebug("L1TGlobal") << "Obj0 phiFW = " << phiIndex0 << " Obj1 phiFW = " << phiIndex1 << "\n"
1026                             << "    DeltaPhiFW = " << deltaPhiFW << "\n"
1027                             << "    LUT Name = " << lutName << " Prec = " << precDeltaPhiLUT
1028                             << "  DeltaPhiLUT = " << deltaPhiLUT << "\n"
1029                             << "Obj0 etaFW = " << etaIndex0 << " Obj1 etaFW = " << etaIndex1 << "\n"
1030                             << "    DeltaEtaFW = " << deltaEtaFW << "\n"
1031                             << "    LUT Name = " << lutName << " Prec = " << precDeltaEtaLUT
1032                             << "  DeltaEtaLUT = " << deltaEtaLUT << std::endl;
1033 
1034       // If there is a delta eta, check it.
1035       if (corrPar.corrCutType & 0x1) {
1036         unsigned int preShift = precDeltaEtaLUT - corrPar.precEtaCut;
1037         LogDebug("L1TGlobal") << "    Testing Delta Eta Cut (" << lutObj0 << "," << lutObj1 << ") ["
1038                               << (long long)(corrPar.minEtaCutValue * pow(10, preShift)) << ","
1039                               << (long long)(corrPar.maxEtaCutValue * pow(10, preShift))
1040                               << "] with precision = " << corrPar.precEtaCut << "\n"
1041                               << "    deltaEtaLUT = " << deltaEtaLUT << "\n"
1042                               << "    Precision Shift = " << preShift << "\n"
1043                               << "    deltaEta (shift)= " << (deltaEtaLUT / pow(10, preShift + corrPar.precEtaCut))
1044                               << "\n"
1045                               << "    deltaEtaPhy = " << deltaEtaPhy << std::endl;
1046 
1047         //if(preShift>0) deltaEtaLUT /= pow(10,preShift);
1048         if (deltaEtaLUT >= (long long)(corrPar.minEtaCutValue * pow(10, preShift)) &&
1049             deltaEtaLUT <= (long long)(corrPar.maxEtaCutValue * pow(10, preShift))) {
1050           LogDebug("L1TGlobal") << "    Passed Delta Eta Cut ["
1051                                 << (long long)(corrPar.minEtaCutValue * pow(10, preShift)) << ","
1052                                 << (long long)(corrPar.maxEtaCutValue * pow(10, preShift)) << "]" << std::endl;
1053 
1054         } else {
1055           LogDebug("L1TGlobal") << "    Failed Delta Eta Cut ["
1056                                 << (long long)(corrPar.minEtaCutValue * pow(10, preShift)) << ","
1057                                 << (long long)(corrPar.maxEtaCutValue * pow(10, preShift)) << "]" << std::endl;
1058           reqResult = false;
1059         }
1060       }
1061 
1062       //if there is a delta phi check it.
1063       if (corrPar.corrCutType & 0x2) {
1064         unsigned int preShift = precDeltaPhiLUT - corrPar.precPhiCut;
1065         LogDebug("L1TGlobal") << "    Testing Delta Phi Cut (" << lutObj0 << "," << lutObj1 << ") ["
1066                               << (long long)(corrPar.minPhiCutValue * pow(10, preShift)) << ","
1067                               << (long long)(corrPar.maxPhiCutValue * pow(10, preShift))
1068                               << "] with precision = " << corrPar.precPhiCut << "\n"
1069                               << "    deltaPhiLUT = " << deltaPhiLUT << "\n"
1070                               << "    Precision Shift = " << preShift << "\n"
1071                               << "    deltaPhi (shift)= " << (deltaPhiLUT / pow(10, preShift + corrPar.precPhiCut))
1072                               << "\n"
1073                               << "    deltaPhiPhy = " << deltaPhiPhy << std::endl;
1074 
1075         //if(preShift>0) deltaPhiLUT /= pow(10,preShift);
1076         if (deltaPhiLUT >= (long long)(corrPar.minPhiCutValue * pow(10, preShift)) &&
1077             deltaPhiLUT <= (long long)(corrPar.maxPhiCutValue * pow(10, preShift))) {
1078           LogDebug("L1TGlobal") << "    Passed Delta Phi Cut ["
1079                                 << (long long)(corrPar.minPhiCutValue * pow(10, preShift)) << ","
1080                                 << (long long)(corrPar.maxPhiCutValue * pow(10, preShift)) << "]" << std::endl;
1081 
1082         } else {
1083           LogDebug("L1TGlobal") << "    Failed Delta Phi Cut ["
1084                                 << (long long)(corrPar.minPhiCutValue * pow(10, preShift)) << ","
1085                                 << (long long)(corrPar.maxPhiCutValue * pow(10, preShift)) << "]" << std::endl;
1086           reqResult = false;
1087         }
1088       }
1089 
1090       if (corrPar.corrCutType & 0x4) {
1091         //Assumes Delta Eta and Delta Phi LUTs have the same precision
1092         unsigned int preShift = 2 * precDeltaPhiLUT - corrPar.precDRCut;
1093         double deltaRSqPhy = deltaPhiPhy * deltaPhiPhy + deltaEtaPhy * deltaEtaPhy;
1094         long long deltaRSq = deltaEtaLUT * deltaEtaLUT + deltaPhiLUT * deltaPhiLUT;
1095 
1096         LogDebug("L1TGlobal") << "    Testing Delta R Cut (" << lutObj0 << "," << lutObj1 << ") ["
1097                               << (long long)(corrPar.minDRCutValue * pow(10, preShift)) << ","
1098                               << (long long)(corrPar.maxDRCutValue * pow(10, preShift))
1099                               << "] with precision = " << corrPar.precDRCut << "\n"
1100                               << "    deltaPhiLUT = " << deltaPhiLUT << "\n"
1101                               << "    deltaEtaLUT = " << deltaEtaLUT << "\n"
1102                               << "    deltaRSqLUT = " << deltaRSq << "\n"
1103                               << "    Precision Shift = " << preShift << "\n"
1104                               << "    deltaRSqLUT (shift)= " << (deltaRSq / pow(10, preShift + corrPar.precDRCut))
1105                               << "\n"
1106                               << "    deltaRSqPhy = " << deltaRSqPhy << std::endl;
1107 
1108         //if(preShift>0) deltaRSq /= pow(10,preShift);
1109         if (deltaRSq >= (long long)(corrPar.minDRCutValue * pow(10, preShift)) &&
1110             deltaRSq <= (long long)(corrPar.maxDRCutValue * pow(10, preShift))) {
1111           LogDebug("L1TGlobal") << "    Passed Delta R Cut [" << (long long)(corrPar.minDRCutValue * pow(10, preShift))
1112                                 << "," << (long long)(corrPar.maxDRCutValue * pow(10, preShift)) << "]" << deltaRSq
1113                                 << std::endl;
1114 
1115         } else {
1116           LogDebug("L1TGlobal") << "    Failed Delta R Cut [" << (int)(corrPar.minDRCutValue * pow(10, preShift)) << ","
1117                                 << (long long)(corrPar.maxDRCutValue * pow(10, preShift)) << "]" << deltaRSq
1118                                 << std::endl;
1119           reqResult = false;
1120         }
1121       }
1122 
1123       if (corrPar.corrCutType & 0x20) {
1124         // Two body pt: pt^2 = pt1^2+pt2^2+2*pt1*pt2*(cos(phi1)*cos(phi2)+sin(phi1)*sin(phi2)).
1125 
1126         LogDebug("L1TGlobal") << " corrPar.corrCutType: " << corrPar.corrCutType << "\n";
1127 
1128         //calculate math sins and cosines for debugging
1129         double cosPhi1Phy = cos(phi0Phy);
1130         double sinPhi1Phy = sin(phi0Phy);
1131         double cosPhi2Phy = cos(phi1Phy);
1132         double sinPhi2Phy = sin(phi1Phy);
1133 
1134         double tbptSqPhy = et0Phy * et0Phy + et1Phy * et1Phy +
1135                            2 * et0Phy * et1Phy * (cosPhi1Phy * cosPhi2Phy + sinPhi1Phy * sinPhi2Phy);
1136         // get values from LUT's
1137 
1138         const std::string& lutName0 = lutObj0;
1139         unsigned int precCosLUT0 = m_gtScales->getPrec_Cos(lutName0);
1140         unsigned int precSinLUT0 = m_gtScales->getPrec_Sin(lutName0);
1141 
1142         const std::string& lutName1 = lutObj1;
1143         unsigned int precCosLUT1 = m_gtScales->getPrec_Cos(lutName1);
1144         unsigned int precSinLUT1 = m_gtScales->getPrec_Sin(lutName1);
1145 
1146         if (precCosLUT0 - precCosLUT1 != 0)
1147           LogDebug("L1TGlobal") << "Warning: Cos LUTs for TwoBodyPt on different Precision" << std::endl;
1148         if (precSinLUT0 - precSinLUT1 != 0)
1149           LogDebug("L1TGlobal") << "Warning: Sin LUTs for TwoBodyPt on different Precision" << std::endl;
1150         if (precSinLUT0 - precCosLUT1 != 0)
1151           LogDebug("L1TGlobal") << "Warning: Sin and Cos LUTs for TwoBodyPt on different Precision" << std::endl;
1152         if (precSinLUT1 - precCosLUT0 != 0)
1153           LogDebug("L1TGlobal") << "Warning: Sin and Cos LUTs for TwoBodyPt on different Precision" << std::endl;
1154 
1155         long long cosPhi1LUT = m_gtScales->getLUT_Cos(lutName0, phiIndex0);
1156         long long sinPhi1LUT = m_gtScales->getLUT_Sin(lutName0, phiIndex0);
1157 
1158         long long cosPhi2LUT = m_gtScales->getLUT_Cos(lutName1, phiIndex1);
1159         long long sinPhi2LUT = m_gtScales->getLUT_Sin(lutName1, phiIndex1);
1160 
1161         // now get pt LUTs
1162         std::string lutName = lutObj0;
1163         lutName += "-ET";
1164         long long ptObj0 = m_gtScales->getLUT_Pt("TwoBody_" + lutName, etIndex0);
1165         unsigned int precPtLUTObj0 = m_gtScales->getPrec_Pt("TwoBody_" + lutName);
1166 
1167         lutName = lutObj1;
1168         lutName += "-ET";
1169         long long ptObj1 = m_gtScales->getLUT_Pt("TwoBody_" + lutName, etIndex1);
1170         unsigned int precPtLUTObj1 = m_gtScales->getPrec_Pt("TwoBody_" + lutName);
1171 
1172         LogTrace("L1TGlobal") << " TBPT Trig precisions:\t " << precCosLUT0 << "\t" << precCosLUT1 << "\t"
1173                               << precSinLUT0 << "\t" << precSinLUT1;
1174         LogTrace("L1TGlobal") << " TBPT Pt precisions:\t " << precPtLUTObj0 << "\t" << precPtLUTObj1;
1175         LogTrace("L1TGlobal") << " TBPT Pt cut:\t " << corrPar.minTBPTCutValue << "\tPrecTBPTCut\t"
1176                               << corrPar.precTBPTCut;
1177         LogTrace("L1TGlobal") << " TBPT Pt1*Pt1 -- Phys:\t " << et0Phy * et0Phy << "\tHW:\t"
1178                               << ptObj0 * ptObj0 * (pow(10, 6));
1179         LogTrace("L1TGlobal") << " TBPT Pt2*Pt2 -- Phys:\t " << et1Phy * et1Phy << "\tHW:\t"
1180                               << ptObj1 * ptObj1 * (pow(10, 6));
1181         LogTrace("L1TGlobal") << " TBPT 2Pt1*Pt2 -- Phys:\t " << 2 * et0Phy * et1Phy << "\tHW:\t"
1182                               << 2 * (ptObj0 * pow(10, 0)) * (ptObj1 * pow(10, 0));
1183         LogTrace("L1TGlobal") << " TBPT Trig -- Phys:\t " << cosPhi1Phy * cosPhi2Phy + sinPhi1Phy * sinPhi2Phy
1184                               << "\tHW:\t" << cosPhi1LUT * cosPhi2LUT + sinPhi1LUT * sinPhi2LUT;
1185 
1186         //double tbptSqPhy =   et0Phy*et0Phy             + et1Phy*et1Phy + 2*et0Phy*et1Phy*(cosPhi1Phy*cosPhi2Phy + sinPhi1Phy*sinPhi2Phy);
1187         long long tbptSqHW = ptObj0 * ptObj0 * (pow(10, 2 * precCosLUT0)) +
1188                              ptObj1 * ptObj1 * (pow(10, 2 * precCosLUT0)) +
1189                              2 * ptObj0 * ptObj1 * (cosPhi1LUT * cosPhi2LUT + sinPhi1LUT * sinPhi2LUT);
1190 
1191         unsigned int preShift = precPtLUTObj0 + precPtLUTObj1 + 2 * precCosLUT0;
1192 
1193         LogTrace("L1TGlobal") << "TBPT Result -- Phys: " << tbptSqPhy << "\tHW: " << tbptSqHW << "\tShifted\t"
1194                               << tbptSqHW / pow(10, preShift) << std::endl;
1195 
1196         preShift = preShift - corrPar.precTBPTCut;
1197 
1198         LogDebug("L1TGlobal")
1199             << "    Testing Two Body Pt Cut (" << lutObj0 << "," << lutObj1 << ") ["
1200             << (long long)(corrPar.minTBPTCutValue * pow(10, preShift)) << ","
1201             << (long long)(corrPar.maxTBPTCutValue * pow(10, preShift)) << "] with precision = " << corrPar.precTBPTCut
1202             << "\n"
1203             << "    etIndex0     = " << etIndex0 << "    pt0LUT      = " << ptObj0 << " PhyEt0 = " << et0Phy << "\n"
1204             << "    etIndex1     = " << etIndex1 << "    pt1LUT      = " << ptObj1 << " PhyEt1 = " << et1Phy << "\n"
1205             << "    Precision Shift = " << preShift << "\n"
1206             << "    Sin(phi1): LUT/Phys\t " << sinPhi1LUT << " / " << sinPhi1Phy << "\n"
1207             << "    Sin(phi2): LUT/Phys\t " << sinPhi2LUT << " / " << sinPhi2Phy << "\n"
1208             << "    Cos(phi1): LUT/Phys\t " << cosPhi1LUT << " / " << cosPhi1Phy << "\n"
1209             << "    Cos(phi2): LUT/Phys\t " << cosPhi2LUT << " / " << cosPhi2Phy
1210             << "\n"
1211 
1212             //    << "    deltaPhiLUT = " << deltaPhiLUT << "\n"
1213             //    << "    deltaEtaLUT = " << deltaEtaLUT << "\n"
1214             //    << "    deltaRSqLUT = " << deltaRSq <<  "\n"
1215             //    << "    Precision Shift = " << preShift << "\n"
1216             //    << "    deltaRSqLUT (shift)= " << (deltaRSq/pow(10,preShift+corrPar.precDRCut))   << "\n"
1217             //    << "    deltaRSqPhy = " << deltaRSqPhy
1218             << std::endl;
1219 
1220         if (tbptSqHW > 0. && tbptSqHW >= (long long)(corrPar.minTBPTCutValue * pow(10, preShift))) {
1221           LogDebug("L1TGlobal") << "    Passed Two Body pT Cut ["
1222                                 << (long long)(corrPar.minTBPTCutValue * pow(10, preShift)) << "]"
1223                                 << "\twith value: " << tbptSqHW << "\n"
1224                                 << "\tPhysics Cut[" << corrPar.minTBPTCutValue / pow(10, corrPar.precTBPTCut)
1225                                 << "]\tPhysics Value: " << tbptSqPhy << std::endl;
1226 
1227         } else {
1228           LogDebug("L1TGlobal") << "    Failed Two Body pT Cut ["
1229                                 << (long long)(corrPar.minTBPTCutValue * pow(10, preShift)) << "]"
1230                                 << "\t with value: " << tbptSqHW << "\n"
1231                                 << "\tPhysics Cut[" << corrPar.minTBPTCutValue / pow(10, corrPar.precTBPTCut)
1232                                 << "]\tPhysics Value: " << tbptSqPhy << std::endl;
1233           reqResult = false;
1234         }
1235       }
1236 
1237       if (corrPar.corrCutType & 0x8 || corrPar.corrCutType & 0x10 || corrPar.corrCutType & 0x40 ||
1238           corrPar.corrCutType & 0x80) {  // added 0x40 for massUpt; added 0x80 for mass/dR
1239         //invariant mass calculation based on
1240         // M = sqrt(2*p1*p2(cosh(eta1-eta2) - cos(phi1 - phi2)))
1241         // but we calculate (1/2)M^2
1242         //
1243         double cosDeltaPhiPhy = cos(deltaPhiPhy);
1244         double coshDeltaEtaPhy = cosh(deltaEtaPhy);
1245         if (corrPar.corrCutType & 0x10)
1246           coshDeltaEtaPhy = 1.;
1247         double massSqPhy = et0Phy * et1Phy * (coshDeltaEtaPhy - cosDeltaPhiPhy);
1248         if (corrPar.corrCutType & 0x40)  // Added for displaced muons
1249           massSqPhy = upt0Phy * upt1Phy * (coshDeltaEtaPhy - cosDeltaPhiPhy);
1250 
1251         long long cosDeltaPhiLUT = m_gtScales->getLUT_DeltaPhi_Cos(lutName, deltaPhiFW);
1252         unsigned int precCosLUT = m_gtScales->getPrec_DeltaPhi_Cos(lutName);
1253 
1254         long long coshDeltaEtaLUT;
1255         if (corrPar.corrCutType & 0x10) {
1256           coshDeltaEtaLUT = 1 * pow(10, precCosLUT);
1257         } else {
1258           coshDeltaEtaLUT = m_gtScales->getLUT_DeltaEta_Cosh(lutName, deltaEtaFW);
1259           unsigned int precCoshLUT = m_gtScales->getPrec_DeltaEta_Cosh(lutName);
1260           if (precCoshLUT - precCosLUT != 0)
1261             LogDebug("L1TGlobal") << "Warning: Cos and Cosh LUTs on different Precision" << std::endl;
1262         }
1263         // if (corrPar.corrCutType & 0x10) coshDeltaEtaLUT=1*pow(10,precCosLUT);
1264 
1265         std::string lutName = lutObj0;
1266         lutName += "-ET";
1267         long long ptObj0 = m_gtScales->getLUT_Pt("Mass_" + lutName, etIndex0);
1268         unsigned int precPtLUTObj0 = m_gtScales->getPrec_Pt("Mass_" + lutName);
1269 
1270         lutName = lutObj1;
1271         lutName += "-ET";
1272         long long ptObj1 = m_gtScales->getLUT_Pt("Mass_" + lutName, etIndex1);
1273         unsigned int precPtLUTObj1 = m_gtScales->getPrec_Pt("Mass_" + lutName);
1274 
1275         if (corrPar.corrCutType & 0x40)  // Added for displaced muons
1276         {
1277           lutName = lutObj0;
1278           lutName += "-UPT";
1279           ptObj0 = m_gtScales->getLUT_Upt("Mass_" + lutName, uptIndex0);
1280           precPtLUTObj0 = m_gtScales->getPrec_Upt("Mass_" + lutName);
1281 
1282           lutName = lutObj1;
1283           lutName += "-UPT";
1284           ptObj1 = m_gtScales->getLUT_Upt("Mass_" + lutName, uptIndex1);
1285           precPtLUTObj1 = m_gtScales->getPrec_Upt("Mass_" + lutName);
1286         }
1287 
1288         // Pt and Angles are at different precission.
1289         long long massSq = ptObj0 * ptObj1 * (coshDeltaEtaLUT - cosDeltaPhiLUT);
1290 
1291         //Note: There is an assumption here that Cos and Cosh have the same precission
1292         unsigned int preShift = precPtLUTObj0 + precPtLUTObj1 + precCosLUT - corrPar.precMassCut;
1293 
1294         LogDebug("L1TGlobal") << "    Testing Invariant Mass (" << lutObj0 << "," << lutObj1 << ") ["
1295                               << (long long)(corrPar.minMassCutValue * pow(10, preShift)) << ","
1296                               << (long long)(corrPar.maxMassCutValue * pow(10, preShift))
1297                               << "] with precision = " << corrPar.precMassCut << "\n"
1298                               << "    deltaPhiLUT  = " << deltaPhiLUT << "  cosLUT  = " << cosDeltaPhiLUT << "\n"
1299                               << "    deltaEtaLUT  = " << deltaEtaLUT << "  coshLUT = " << coshDeltaEtaLUT << "\n"
1300                               << "    etIndex0     = " << etIndex0 << "    pt0LUT      = " << ptObj0
1301                               << " PhyEt0 = " << et0Phy << "\n"
1302                               << "    etIndex1     = " << etIndex1 << "    pt1LUT      = " << ptObj1
1303                               << " PhyEt1 = " << et1Phy << "\n"
1304                               << "    massSq/2     = " << massSq << "\n"
1305                               << "    Precision Shift = " << preShift << "\n"
1306                               << "    massSq   (shift)= " << (massSq / pow(10, preShift + corrPar.precMassCut)) << "\n"
1307                               << "    deltaPhiPhy  = " << deltaPhiPhy << "  cos() = " << cosDeltaPhiPhy << "\n"
1308                               << "    deltaEtaPhy  = " << deltaEtaPhy << "  cosh()= " << coshDeltaEtaPhy << "\n"
1309                               << "    massSqPhy/2  = " << massSqPhy
1310                               << "  sqrt(|massSq|) = " << sqrt(fabs(2. * massSqPhy)) << std::endl;
1311 
1312         //if(preShift>0) massSq /= pow(10,preShift);
1313         if (corrPar.corrCutType & 0x80) {  //deal with the Invariant Mass Over Delta R cut
1314           // The following is the most precise indexing for 1/dr2 LUT iEta and jPhi - it is based on the physical VALUES for deta and dphi:
1315           //             unsigned int inverseDeltaRIndexEta = int(round(abs(deltaEtaPhy / tempdiffeta)));
1316           //             unsigned int inverseDeltaRIndexPhi = int(round(abs(deltaPhiPhy/ tempdiffphi)));
1317           // To match the FW we instead must use these INDIVIDUAL indecies for eta and phi:
1318           // (NOTE: The following treatment of delta eta and delta phi indecies matches the most precise case above):
1319           int iEta0 = int(trunc(etaIndex0 * resolution));
1320           int iEta1 = int(trunc(etaIndex1 * resolution));
1321           unsigned int inverseDeltaRIndexEta = abs(iEta0 - iEta1);
1322           int jPhi0 = int(trunc(phiIndex0 * resolution));
1323           int jPhi1 = int(trunc(phiIndex1 * resolution));
1324           unsigned int inverseDeltaRIndexPhi = abs(jPhi0 - jPhi1);
1325           if (abs(phiIndex0 - phiIndex1) >= phiBound)
1326             inverseDeltaRIndexPhi = int(trunc(2 * phiBound * resolution)) - inverseDeltaRIndexPhi;
1327           unsigned int precInvDRSqLUT = 0x5;
1328           long long LInverseDeltaRSqLUT = 0x0;
1329           if (inverseDeltaRIndexEta + inverseDeltaRIndexPhi > 0)
1330             LInverseDeltaRSqLUT = InvDeltaRSqLUT[inverseDeltaRIndexEta][inverseDeltaRIndexPhi];
1331           long long massSqOverDeltaRSq =
1332               (long long)massSq * LInverseDeltaRSqLUT;  // keep full precision, do not '/pow(10,precInvDRSqLUT);'
1333           if ((inverseDeltaRIndexEta + inverseDeltaRIndexPhi == 0) ||
1334               ((massSqOverDeltaRSq >= 0) &&
1335                (massSqOverDeltaRSq >=
1336                 (long long)(corrPar.minMassCutValue * pow(10, preShift) *
1337                             pow(10, precInvDRSqLUT))))) {  // only check for the minimum threshold in case of invMass/dR
1338             LogDebug("L1TGlobal") << "    Passed Invariant Mass Over Delta R  Cut ["
1339                                   << (long long)(corrPar.minMassCutValue * pow(10, preShift) * pow(10, precInvDRSqLUT))
1340                                   << ","
1341                                   << (long long)(corrPar.maxMassCutValue * pow(10, preShift) * pow(10, precInvDRSqLUT))
1342                                   << "]     massSqOverDeltaRSq " << massSqOverDeltaRSq << std::endl;
1343           } else {
1344             LogDebug("L1TGlobal") << "    Failed Invariant Mass OverDeltaR Cut ["
1345                                   << (long long)(corrPar.minMassCutValue * pow(10, preShift) * pow(10, precInvDRSqLUT))
1346                                   << ","
1347                                   << (long long)(corrPar.maxMassCutValue * pow(10, preShift) * pow(10, precInvDRSqLUT))
1348                                   << "]     massSqOverDeltaRSq " << massSqOverDeltaRSq << std::endl;
1349             reqResult = false;
1350           }
1351           //Done with Invariant Mass Over Delta R vs Mass Cut choice
1352         } else {  //do the InvMassCut choice
1353           if (massSq >= 0 && massSq >= (long long)(corrPar.minMassCutValue * pow(10, preShift)) &&
1354               massSq <= (long long)(corrPar.maxMassCutValue * pow(10, preShift))) {
1355             LogDebug("L1TGlobal") << "    Passed Invariant Mass Cut ["
1356                                   << (long long)(corrPar.minMassCutValue * pow(10, preShift)) << ","
1357                                   << (long long)(corrPar.maxMassCutValue * pow(10, preShift)) << "]" << std::endl;
1358           } else {
1359             LogDebug("L1TGlobal") << "    Failed Invariant Mass Cut ["
1360                                   << (long long)(corrPar.minMassCutValue * pow(10, preShift)) << ","
1361                                   << (long long)(corrPar.maxMassCutValue * pow(10, preShift)) << "]" << std::endl;
1362             reqResult = false;
1363           }  //Done with Invariant Mass Cut
1364         }  //Done with choice of Invariant Mass Cut vs InvMass/dR
1365       }  //Done with any type of Mass Cut
1366 
1367       // For Muon-Muon Correlation Check the Charge Correlation if requested
1368       bool chrgCorrel = true;
1369       if (cond0Categ == CondMuon && cond1Categ == CondMuon) {
1370         // Check for like-sign
1371         if (corrPar.chargeCorrelation == 2 && chrg0 != chrg1)
1372           chrgCorrel = false;
1373         // Check for opp-sign
1374         if (corrPar.chargeCorrelation == 4 && chrg0 == chrg1)
1375           chrgCorrel = false;
1376       }
1377 
1378       if (reqResult & chrgCorrel) {
1379         condResult = true;
1380         (combinationsInCond()).push_back(objectsInComb);
1381       }
1382 
1383     }  //end loop over second leg
1384 
1385   }  //end loop over first leg
1386 
1387   if (m_verbosity && condResult) {
1388     LogDebug("L1TGlobal") << " pass(es) the correlation condition.\n" << std::endl;
1389   }
1390 
1391   return condResult;
1392 }
1393 
1394 // load calo candidates
1395 const l1t::L1Candidate* l1t::CorrCondition::getCandidate(const int bx, const int indexCand) const {
1396   // objectType() gives the type for nrObjects() only,
1397   // but in a CondCalo all objects have the same type
1398   // take type from the type of the first object
1399   switch ((m_gtCorrelationTemplate->objectType())[0]) {
1400     case gtEG:
1401       return (m_uGtB->getCandL1EG())->at(bx, indexCand);
1402       break;
1403 
1404     case gtJet:
1405       return (m_uGtB->getCandL1Jet())->at(bx, indexCand);
1406       break;
1407 
1408     case gtTau:
1409       return (m_uGtB->getCandL1Tau())->at(bx, indexCand);
1410       break;
1411     default:
1412       return nullptr;
1413       break;
1414   }
1415 
1416   return nullptr;
1417 }
1418 
1419 /**
1420  * checkObjectParameter - Compare a single particle with a numbered condition.
1421  *
1422  * @param iCondition The number of the condition.
1423  * @param cand The candidate to compare.
1424  *
1425  * @return The result of the comparison (false if a condition does not exist).
1426  */
1427 
1428 const bool l1t::CorrCondition::checkObjectParameter(const int iCondition, const l1t::L1Candidate& cand) const {
1429   return true;
1430 }
1431 
1432 void l1t::CorrCondition::print(std::ostream& myCout) const {
1433   myCout << "Dummy Print for CorrCondition" << std::endl;
1434   m_gtCorrelationTemplate->print(myCout);
1435 
1436   ConditionEvaluation::print(myCout);
1437 }