Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-08 05:11:47

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