Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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