Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-01-14 23:17:00

0001 /**
0002  * \class CorrWithOverlapRemovalCondition
0003  *
0004  *
0005  * Description: evaluation of a correlation-with-overlap-removal condition.
0006  *
0007  *
0008  * Implementation:
0009  *
0010  *  The central method of the class is evaluateCondition().
0011  *  Correlation cuts inherited from the original CorrCondition class.
0012  *
0013  *  v1 Logic:
0014  *  - Define 3 GtConditionCategories: (1st & 2nd correlation legs, and overlap-removal leg)
0015  *
0016  *  - Loop leg1: over all objects of 1st correlation leg
0017  *
0018  *    - Retrive its coordinates, and do conversions depending on the types
0019  *
0020  *    - Loop over all objects of leg3 (overlap-removal leg)
0021  *      - Retrive its coodrinates, and do conversions depending on the types
0022  *      - Check for matching with overlap-removal object.
0023  *    - If metched with any overlap object, next leg1 object.
0024  *
0025  *    - Loop leg2: over all object of 2nd correlation leg
0026  *      - Retrive its coordinates, and do conversion depending on the types
0027  *      - Loop over all objects of leg3 (overlap-removal leg)
0028  *        - Retrive its coodrinates, and do conversions depending on the types
0029  *        - Check for matching with any overlap-removal object.
0030  *      - If metched with any overlap object, next leg2 object.
0031  *      - Check for dEta, dPhi, dR, and mass (and charge) correlation with 1st leg object.
0032  *        If any correlation cut pass, save leg1-leg2 object combination.
0033  *    - End loop leg2
0034  *
0035  *  - End loop leg1
0036  *
0037  *  - Return true, if saved at least one leg1-leg2 combintation
0038  *
0039  *
0040  * \author: Vladimir Rekovic
0041  *
0042  */
0043 
0044 // this class header
0045 #include "L1Trigger/L1TGlobal/interface/CorrWithOverlapRemovalCondition.h"
0046 
0047 // system include files
0048 #include <iostream>
0049 #include <iomanip>
0050 
0051 #include <string>
0052 #include <vector>
0053 #include <algorithm>
0054 
0055 // user include files
0056 //   base classes
0057 #include "L1Trigger/L1TGlobal/interface/CorrelationWithOverlapRemovalTemplate.h"
0058 #include "L1Trigger/L1TGlobal/interface/ConditionEvaluation.h"
0059 
0060 #include "L1Trigger/L1TGlobal/interface/MuCondition.h"
0061 #include "L1Trigger/L1TGlobal/interface/CaloCondition.h"
0062 #include "L1Trigger/L1TGlobal/interface/EnergySumCondition.h"
0063 #include "L1Trigger/L1TGlobal/interface/MuonTemplate.h"
0064 #include "L1Trigger/L1TGlobal/interface/CaloTemplate.h"
0065 #include "L1Trigger/L1TGlobal/interface/EnergySumTemplate.h"
0066 #include "L1Trigger/L1TGlobal/interface/GlobalScales.h"
0067 
0068 #include "DataFormats/L1Trigger/interface/L1Candidate.h"
0069 
0070 #include "L1Trigger/L1TGlobal/interface/GlobalBoard.h"
0071 
0072 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0073 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0074 
0075 // constructors
0076 //     default
0077 l1t::CorrWithOverlapRemovalCondition::CorrWithOverlapRemovalCondition() : ConditionEvaluation() {}
0078 
0079 //     from base template condition (from event setup usually)
0080 l1t::CorrWithOverlapRemovalCondition::CorrWithOverlapRemovalCondition(const GlobalCondition* corrTemplate,
0081                                                                       const GlobalCondition* cond0Condition,
0082                                                                       const GlobalCondition* cond1Condition,
0083                                                                       const GlobalCondition* cond2Condition,
0084                                                                       const GlobalBoard* ptrGTB,
0085                                                                       const GlobalScales* ptrGS)
0086     : ConditionEvaluation(),
0087       m_gtCorrelationWithOverlapRemovalTemplate(
0088           static_cast<const CorrelationWithOverlapRemovalTemplate*>(corrTemplate)),
0089       m_gtCond0(cond0Condition),
0090       m_gtCond1(cond1Condition),
0091       m_gtCond2(cond2Condition),
0092       m_uGtB(ptrGTB),
0093       m_gtScales(ptrGS) {}
0094 
0095 // copy constructor
0096 void l1t::CorrWithOverlapRemovalCondition::copy(const l1t::CorrWithOverlapRemovalCondition& cp) {
0097   m_gtCorrelationWithOverlapRemovalTemplate = cp.gtCorrelationWithOverlapRemovalTemplate();
0098   m_uGtB = cp.getuGtB();
0099   m_gtScales = cp.getScales();
0100 
0101   m_condMaxNumberObjects = cp.condMaxNumberObjects();
0102   m_condLastResult = cp.condLastResult();
0103   m_combinationsInCond = cp.getCombinationsInCond();
0104 
0105   m_verbosity = cp.m_verbosity;
0106 }
0107 
0108 l1t::CorrWithOverlapRemovalCondition::CorrWithOverlapRemovalCondition(const l1t::CorrWithOverlapRemovalCondition& cp)
0109     : ConditionEvaluation() {
0110   copy(cp);
0111 }
0112 
0113 // destructor
0114 l1t::CorrWithOverlapRemovalCondition::~CorrWithOverlapRemovalCondition() {
0115   // empty
0116 }
0117 
0118 // equal operator
0119 l1t::CorrWithOverlapRemovalCondition& l1t::CorrWithOverlapRemovalCondition::operator=(
0120     const l1t::CorrWithOverlapRemovalCondition& cp) {
0121   copy(cp);
0122   return *this;
0123 }
0124 
0125 // methods
0126 void l1t::CorrWithOverlapRemovalCondition::setGtCorrelationWithOverlapRemovalTemplate(
0127     const CorrelationWithOverlapRemovalTemplate* caloTempl) {
0128   m_gtCorrelationWithOverlapRemovalTemplate = caloTempl;
0129 }
0130 
0131 ///   set the pointer to uGT GlobalBoard
0132 void l1t::CorrWithOverlapRemovalCondition::setuGtB(const GlobalBoard* ptrGTB) { m_uGtB = ptrGTB; }
0133 
0134 void l1t::CorrWithOverlapRemovalCondition::setScales(const GlobalScales* sc) { m_gtScales = sc; }
0135 
0136 // try all object permutations and check spatial correlations, if required
0137 const bool l1t::CorrWithOverlapRemovalCondition::evaluateCondition(const int bxEval) const {
0138   // std::cout << "m_isDebugEnabled = " << m_isDebugEnabled << std::endl;
0139   // std::cout << "m_verbosity = " << m_verbosity << std::endl;
0140 
0141   //std::ostringstream myCout;
0142   //m_gtCorrelationWithOverlapRemovalTemplate->print(myCout);
0143   //LogDebug("L1TGlobal")
0144   //   << "CorrelationWithOverlapRemoval Condition Evaluation \n" << myCout.str() << std::endl;
0145 
0146   bool condResult = false;
0147   bool reqObjResult = false;
0148 
0149   // number of objects in condition (it is 3, no need to retrieve from
0150   // condition template) and their type
0151   int nObjInCond = 3;
0152   std::vector<GlobalObject> cndObjTypeVec(nObjInCond);
0153 
0154   // evaluate first the two sub-conditions (Type1s)
0155 
0156   const GtConditionCategory cond0Categ = m_gtCorrelationWithOverlapRemovalTemplate->cond0Category();
0157   const GtConditionCategory cond1Categ = m_gtCorrelationWithOverlapRemovalTemplate->cond1Category();
0158   const GtConditionCategory cond2Categ = m_gtCorrelationWithOverlapRemovalTemplate->cond2Category();
0159 
0160   //Decide if we have a mixed (muon + cal) condition
0161   bool convertCaloScales = false;
0162   if ((cond0Categ == CondMuon && (cond1Categ == CondCalo || cond1Categ == CondEnergySum)) ||
0163       (cond1Categ == CondMuon && (cond0Categ == CondCalo || cond0Categ == CondEnergySum)))
0164     convertCaloScales = true;
0165 
0166   bool convertCaloScalesForOverlapRemovalFromLeg0 = false;
0167   if ((cond0Categ == CondMuon && (cond2Categ == CondCalo || cond2Categ == CondEnergySum)) ||
0168       (cond2Categ == CondMuon && (cond0Categ == CondCalo || cond0Categ == CondEnergySum)))
0169     convertCaloScalesForOverlapRemovalFromLeg0 = true;
0170 
0171   bool convertCaloScalesForOverlapRemovalFromLeg1 = false;
0172   if ((cond1Categ == CondMuon && (cond2Categ == CondCalo || cond2Categ == CondEnergySum)) ||
0173       (cond2Categ == CondMuon && (cond1Categ == CondCalo || cond1Categ == CondEnergySum)))
0174     convertCaloScalesForOverlapRemovalFromLeg1 = true;
0175 
0176   const MuonTemplate* corrMuon = nullptr;
0177   const CaloTemplate* corrCalo = nullptr;
0178   const EnergySumTemplate* corrEnergySum = nullptr;
0179 
0180   // FIXME copying is slow...
0181   CombinationsWithBxInCond cond0Comb{};
0182   CombinationsWithBxInCond cond1Comb{};
0183   CombinationsWithBxInCond cond2Comb{};
0184 
0185   switch (cond0Categ) {
0186     case CondMuon: {
0187       corrMuon = static_cast<const MuonTemplate*>(m_gtCond0);
0188       MuCondition muCondition(
0189           corrMuon, m_uGtB, 0, 0);  //BLW these are counts that don't seem to be used...perhaps remove
0190 
0191       muCondition.evaluateConditionStoreResult(bxEval);
0192       reqObjResult = muCondition.condLastResult();
0193 
0194       cond0Comb = (muCondition.getCombinationsInCond());
0195 
0196       cndObjTypeVec[0] = (corrMuon->objectType())[0];
0197 
0198       if (m_verbosity) {
0199         std::ostringstream myCout;
0200         muCondition.print(myCout);
0201 
0202         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0203       }
0204     } break;
0205     case CondCalo: {
0206       corrCalo = static_cast<const CaloTemplate*>(m_gtCond0);
0207 
0208       CaloCondition caloCondition(
0209           corrCalo, m_uGtB, 0, 0, 0, 0);  //BLW these are counters that don't seem to be used...perhaps remove.
0210 
0211       caloCondition.evaluateConditionStoreResult(bxEval);
0212       reqObjResult = caloCondition.condLastResult();
0213 
0214       cond0Comb = caloCondition.getCombinationsInCond();
0215 
0216       cndObjTypeVec[0] = (corrCalo->objectType())[0];
0217 
0218       if (m_verbosity) {
0219         std::ostringstream myCout;
0220         caloCondition.print(myCout);
0221 
0222         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0223       }
0224     } break;
0225     case CondEnergySum: {
0226       corrEnergySum = static_cast<const EnergySumTemplate*>(m_gtCond0);
0227       EnergySumCondition eSumCondition(corrEnergySum, m_uGtB);
0228 
0229       eSumCondition.evaluateConditionStoreResult(bxEval);
0230       reqObjResult = eSumCondition.condLastResult();
0231 
0232       cond0Comb = eSumCondition.getCombinationsInCond();
0233 
0234       cndObjTypeVec[0] = (corrEnergySum->objectType())[0];
0235 
0236       if (m_verbosity) {
0237         std::ostringstream myCout;
0238         eSumCondition.print(myCout);
0239 
0240         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0241       }
0242     } break;
0243     default: {
0244       // should not arrive here, there are no correlation conditions defined for this object
0245       return false;
0246     } break;
0247   }
0248 
0249   // return if first subcondition is false
0250   if (!reqObjResult) {
0251     LogDebug("L1TGlobal") << "\n  First sub-condition false, second sub-condition not evaluated and not printed."
0252                           << std::endl;
0253     return false;
0254   }
0255 
0256   // second object
0257   switch (cond1Categ) {
0258     case CondMuon: {
0259       corrMuon = static_cast<const MuonTemplate*>(m_gtCond1);
0260       MuCondition muCondition(
0261           corrMuon, m_uGtB, 0, 0);  //BLW these are counts that don't seem to be used...perhaps remove
0262 
0263       muCondition.evaluateConditionStoreResult(bxEval);
0264       reqObjResult = muCondition.condLastResult();
0265 
0266       cond1Comb = muCondition.getCombinationsInCond();
0267 
0268       cndObjTypeVec[1] = (corrMuon->objectType())[0];
0269 
0270       if (m_verbosity) {
0271         std::ostringstream myCout;
0272         muCondition.print(myCout);
0273 
0274         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0275       }
0276     } break;
0277     case CondCalo: {
0278       corrCalo = static_cast<const CaloTemplate*>(m_gtCond1);
0279       CaloCondition caloCondition(
0280           corrCalo, m_uGtB, 0, 0, 0, 0);  //BLW these are counters that don't seem to be used...perhaps remove.
0281 
0282       caloCondition.evaluateConditionStoreResult(bxEval);
0283       reqObjResult = caloCondition.condLastResult();
0284 
0285       cond1Comb = caloCondition.getCombinationsInCond();
0286 
0287       cndObjTypeVec[1] = (corrCalo->objectType())[0];
0288 
0289       if (m_verbosity) {
0290         std::ostringstream myCout;
0291         caloCondition.print(myCout);
0292 
0293         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0294       }
0295 
0296     } break;
0297     case CondEnergySum: {
0298       corrEnergySum = static_cast<const EnergySumTemplate*>(m_gtCond1);
0299 
0300       EnergySumCondition eSumCondition(corrEnergySum, m_uGtB);
0301 
0302       eSumCondition.evaluateConditionStoreResult(bxEval);
0303       reqObjResult = eSumCondition.condLastResult();
0304 
0305       cond1Comb = eSumCondition.getCombinationsInCond();
0306 
0307       cndObjTypeVec[1] = (corrEnergySum->objectType())[0];
0308 
0309       if (m_verbosity) {
0310         std::ostringstream myCout;
0311         eSumCondition.print(myCout);
0312 
0313         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0314       }
0315     } break;
0316     default: {
0317       // should not arrive here, there are no correlation conditions defined for this object
0318       return false;
0319     } break;
0320   }
0321 
0322   // return if second sub-condition is false
0323   if (!reqObjResult) {
0324     return false;
0325   } else {
0326     LogDebug("L1TGlobal") << "\n"
0327                           << "    Both sub-conditions true for object requirements."
0328                           << "    Evaluate correlation requirements.\n"
0329                           << std::endl;
0330   }
0331 
0332   // third object (used for overlap removal)
0333   switch (cond2Categ) {
0334     case CondMuon: {
0335       corrMuon = static_cast<const MuonTemplate*>(m_gtCond2);
0336       MuCondition muCondition(
0337           corrMuon, m_uGtB, 0, 0);  //BLW these are counts that don't seem to be used...perhaps remove
0338 
0339       muCondition.evaluateConditionStoreResult(bxEval);
0340       reqObjResult = muCondition.condLastResult();
0341 
0342       cond2Comb = muCondition.getCombinationsInCond();
0343 
0344       cndObjTypeVec[2] = (corrMuon->objectType())[0];
0345 
0346       if (m_verbosity) {
0347         std::ostringstream myCout;
0348         muCondition.print(myCout);
0349 
0350         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0351       }
0352     } break;
0353     case CondCalo: {
0354       corrCalo = static_cast<const CaloTemplate*>(m_gtCond2);
0355       CaloCondition caloCondition(
0356           corrCalo, m_uGtB, 0, 0, 0, 0);  //BLW these are counters that don't seem to be used...perhaps remove.
0357 
0358       caloCondition.evaluateConditionStoreResult(bxEval);
0359       reqObjResult = caloCondition.condLastResult();
0360 
0361       cond2Comb = caloCondition.getCombinationsInCond();
0362 
0363       cndObjTypeVec[2] = (corrCalo->objectType())[0];
0364 
0365       if (m_verbosity) {
0366         std::ostringstream myCout;
0367         caloCondition.print(myCout);
0368 
0369         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0370       }
0371 
0372     } break;
0373     case CondEnergySum: {
0374       corrEnergySum = static_cast<const EnergySumTemplate*>(m_gtCond2);
0375 
0376       EnergySumCondition eSumCondition(corrEnergySum, m_uGtB);
0377 
0378       eSumCondition.evaluateConditionStoreResult(bxEval);
0379       reqObjResult = eSumCondition.condLastResult();
0380 
0381       cond2Comb = eSumCondition.getCombinationsInCond();
0382 
0383       cndObjTypeVec[2] = (corrEnergySum->objectType())[0];
0384 
0385       if (m_verbosity) {
0386         std::ostringstream myCout;
0387         eSumCondition.print(myCout);
0388 
0389         LogDebug("L1TGlobal") << myCout.str() << std::endl;
0390       }
0391     } break;
0392     default: {
0393       // should not arrive here, there are no correlation conditions defined for this object
0394       return false;
0395     } break;
0396   }
0397 
0398   // if third sub-condition is false, effectively there will no overlap removal
0399   if (!reqObjResult) {
0400     LogDebug("L1TGlobal") << "\n"
0401                           << "    Third sub-condtion false for object requirements."
0402                           << "    Algorithm returning false.\n"
0403                           << std::endl;
0404     return false;
0405   } else {
0406     LogDebug("L1TGlobal") << "\n"
0407                           << "    All three sub-conditions true for object requirements."
0408                           << "    Evaluate correlation requirements and overlap removal.\n"
0409                           << std::endl;
0410   }
0411 
0412   // since we have two good legs and overlap-removal let, get the correlation parameters
0413   CorrelationWithOverlapRemovalTemplate::CorrelationWithOverlapRemovalParameter corrPar =
0414       *(m_gtCorrelationWithOverlapRemovalTemplate->correlationParameter());
0415 
0416   // vector to store the indices of the calorimeter objects
0417   // from the combination evaluated in the condition
0418   SingleCombWithBxInCond objectsInComb;
0419   objectsInComb.reserve(nObjInCond);
0420 
0421   // clear the m_combinationsInCond vector
0422   (combinationsInCond()).clear();
0423 
0424   // pointers to objects
0425   const BXVector<const l1t::Muon*>* candMuVec = nullptr;
0426   const BXVector<const l1t::L1Candidate*>* candCaloVec = nullptr;
0427   const BXVector<const l1t::EtSum*>* candEtSumVec = nullptr;
0428 
0429   bool etSumCond = false;
0430 
0431   // make the conversions of the indices, depending on the combination of objects involved
0432   // (via pair index)
0433 
0434   int phiIndex0 = 0;
0435   int phiIndex1 = 0;
0436   int phiORIndex0 = 0;  // hold phi index transformed in case of need with overlap-removal
0437   int phiORIndex1 = 0;  // hold phi index transformed in case of need with overlap-removal
0438   double phi0Phy = 0.;
0439   double phi1Phy = 0.;
0440 
0441   int etaIndex0 = 0;
0442   int etaIndex1 = 0;
0443   int etaORIndex0 = 0;
0444   int etaORIndex1 = 0;
0445   double eta0Phy = 0.;
0446   double eta1Phy = 0.;
0447   int etaBin0 = 0;
0448   int etaBin1 = 0;
0449 
0450   int etIndex0 = 0;
0451   int etIndex1 = 0;
0452   int etBin0 = 0;
0453   int etBin1 = 0;
0454   double et0Phy = 0.;
0455   double et1Phy = 0.;
0456 
0457   int chrg0 = -1;
0458   int chrg1 = -1;
0459 
0460   // make the conversions of the indices, depending on the combination of objects involved in overlap-removal
0461   int phiIndex2 = 0;
0462   int etaIndex2 = 0;
0463   double phi2Phy = 0.;
0464   double eta2Phy = 0.;
0465   int etaBin2 = 0;
0466   //int etIndex2  = 0;
0467   //int etBin2    = 0;
0468 
0469   // Determine the number of phi bins to get cutoff at pi
0470   int phiBound = 0;
0471   if (cond0Categ == CondMuon || cond1Categ == CondMuon || cond2Categ == CondMuon) {
0472     GlobalScales::ScaleParameters par = m_gtScales->getMUScales();
0473     //phiBound = par.phiBins.size()/2;
0474     phiBound = (int)((par.phiMax - par.phiMin) / par.phiStep) / 2;
0475   } else {
0476     //Assumes all calorimeter objects are on same phi scale
0477     GlobalScales::ScaleParameters par = m_gtScales->getEGScales();
0478     //phiBound = par.phiBins.size()/2;
0479     phiBound = (int)((par.phiMax - par.phiMin) / par.phiStep) / 2;
0480   }
0481   LogDebug("L1TGlobal") << "Phi Bound = " << phiBound << std::endl;
0482 
0483   // Keep track of objects for LUTS
0484   std::string lutObj0 = "NULL";
0485   std::string lutObj1 = "NULL";
0486   std::string lutObj2 = "NULL";
0487 
0488   LogTrace("L1TGlobal") << "  Sub-condition 0: std::vector<SingleCombInCond> size: " << (cond0Comb.size()) << std::endl;
0489   LogTrace("L1TGlobal") << "  Sub-condition 1: std::vector<SingleCombInCond> size: " << (cond1Comb.size()) << std::endl;
0490   LogTrace("L1TGlobal") << "  Sub-condition 2: std::vector<SingleCombInCond> size: " << (cond2Comb.size()) << std::endl;
0491 
0492   // ///////////////////////////////////////////////////////////////////////////////////////////
0493   // loop over all combinations which produced individually "true" as Type1s
0494   // ///////////////////////////////////////////////////////////////////////////////////////////
0495   // BLW: Optimization issue: potentially making the same comparison twice
0496   //                          if both legs are the same object type.
0497   // ///////////////////////////////////////////////////////////////////////////////////////////
0498   for (auto const& it0Comb : cond0Comb) {
0499     // Type1s: there is 1 object only, no need for a loop, index 0 should be OK in it0Comb[0]
0500     // ... but add protection to not crash
0501     if (it0Comb.empty()) {
0502       LogTrace("L1TGlobal") << "\n  SingleCombWithBxCond it0Comb.size() " << it0Comb.size();
0503       return false;
0504     }
0505 
0506     auto const cond0bx = it0Comb[0].first;
0507     auto const obj0Index = it0Comb[0].second;
0508 
0509     // Collect the information on the first leg of the correlation
0510     switch (cond0Categ) {
0511       case CondMuon: {
0512         lutObj0 = "MU";
0513         candMuVec = m_uGtB->getCandL1Mu();
0514         auto const* mu0 = candMuVec->at(cond0bx, obj0Index);
0515         phiIndex0 = mu0->hwPhi();  //mu0->phiIndex();
0516         etaIndex0 = mu0->hwEta();
0517         etIndex0 = mu0->hwPt();
0518         chrg0 = mu0->hwCharge();
0519         int etaBin0 = etaIndex0;
0520         if (etaBin0 < 0)
0521           etaBin0 = m_gtScales->getMUScales().etaBins.size() + etaBin0;  //twos complement
0522         //      LogDebug("L1TGlobal") << "Muon phi" << phiIndex0 << " eta " << etaIndex0 << " etaBin0 = " << etaBin0  << " et " << etIndex0 << std::endl;
0523         //
0524 
0525         etBin0 = etIndex0;
0526         int ssize = m_gtScales->getMUScales().etBins.size();
0527         if (etBin0 >= ssize) {
0528           etBin0 = ssize - 1;
0529           LogTrace("L1TGlobal") << "muon0 hw et" << etBin0 << " out of scale range.  Setting to maximum.";
0530         }
0531 
0532         // Determine Floating Pt numbers for floating point caluclation
0533         std::pair<double, double> binEdges = m_gtScales->getMUScales().phiBins.at(phiIndex0);
0534         phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0535         binEdges = m_gtScales->getMUScales().etaBins.at(etaBin0);
0536         eta0Phy = 0.5 * (binEdges.second + binEdges.first);
0537         binEdges = m_gtScales->getMUScales().etBins.at(etBin0);
0538         et0Phy = 0.5 * (binEdges.second + binEdges.first);
0539 
0540         LogDebug("L1TGlobal") << "Found all quantities for the muon 0" << std::endl;
0541       } break;
0542 
0543         // Calorimeter Objects (EG, Jet, Tau)
0544       case CondCalo: {
0545         switch (cndObjTypeVec[0]) {
0546           case gtEG: {
0547             lutObj0 = "EG";
0548             candCaloVec = m_uGtB->getCandL1EG();
0549             phiIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwPhi();
0550             etaIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwEta();
0551             etIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwPt();
0552             etaBin0 = etaIndex0;
0553             if (etaBin0 < 0)
0554               etaBin0 = m_gtScales->getEGScales().etaBins.size() + etaBin0;
0555             //          LogDebug("L1TGlobal") << "EG0 phi" << phiIndex0 << " eta " << etaIndex0 << " etaBin0 = " << etaBin0 << " et " << etIndex0 << std::endl;
0556 
0557             etBin0 = etIndex0;
0558             int ssize = m_gtScales->getEGScales().etBins.size();
0559             if (etBin0 >= ssize) {
0560               etBin0 = ssize - 1;
0561               LogTrace("L1TGlobal") << "EG0 hw et" << etBin0 << " out of scale range.  Setting to maximum.";
0562             }
0563 
0564             // Determine Floating Pt numbers for floating point caluclation
0565             std::pair<double, double> binEdges = m_gtScales->getEGScales().phiBins.at(phiIndex0);
0566             phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0567             binEdges = m_gtScales->getEGScales().etaBins.at(etaBin0);
0568             eta0Phy = 0.5 * (binEdges.second + binEdges.first);
0569             binEdges = m_gtScales->getEGScales().etBins[etBin0];
0570             et0Phy = 0.5 * (binEdges.second + binEdges.first);
0571 
0572           } break;
0573           case gtJet: {
0574             lutObj0 = "JET";
0575             candCaloVec = m_uGtB->getCandL1Jet();
0576             phiIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwPhi();
0577             etaIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwEta();
0578             etIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwPt();
0579             etaBin0 = etaIndex0;
0580             if (etaBin0 < 0)
0581               etaBin0 = m_gtScales->getJETScales().etaBins.size() + etaBin0;
0582 
0583             etBin0 = etIndex0;
0584             int ssize = m_gtScales->getJETScales().etBins.size();
0585             if (etBin0 >= ssize) {
0586               //edm::LogWarning("L1TGlobal")
0587               //<< "jet0 hw et" << etBin0 << " out of scale range.  Setting to maximum.";
0588               etBin0 = ssize - 1;
0589             }
0590 
0591             // Determine Floating Pt numbers for floating point caluclation
0592             std::pair<double, double> binEdges = m_gtScales->getJETScales().phiBins.at(phiIndex0);
0593             phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0594             binEdges = m_gtScales->getJETScales().etaBins.at(etaBin0);
0595             eta0Phy = 0.5 * (binEdges.second + binEdges.first);
0596             binEdges = m_gtScales->getJETScales().etBins.at(etBin0);
0597             et0Phy = 0.5 * (binEdges.second + binEdges.first);
0598 
0599           } break;
0600           case gtTau: {
0601             candCaloVec = m_uGtB->getCandL1Tau();
0602             phiIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwPhi();
0603             etaIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwEta();
0604             etIndex0 = (candCaloVec->at(cond0bx, obj0Index))->hwPt();
0605             etaBin0 = etaIndex0;
0606             if (etaBin0 < 0)
0607               etaBin0 = m_gtScales->getTAUScales().etaBins.size() + etaBin0;
0608 
0609             etBin0 = etIndex0;
0610             int ssize = m_gtScales->getTAUScales().etBins.size();
0611             if (etBin0 >= ssize) {
0612               etBin0 = ssize - 1;
0613               LogTrace("L1TGlobal") << "tau0 hw et" << etBin0 << " out of scale range.  Setting to maximum.";
0614             }
0615 
0616             // Determine Floating Pt numbers for floating point caluclation
0617             std::pair<double, double> binEdges = m_gtScales->getTAUScales().phiBins.at(phiIndex0);
0618             phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0619             binEdges = m_gtScales->getTAUScales().etaBins.at(etaBin0);
0620             eta0Phy = 0.5 * (binEdges.second + binEdges.first);
0621             binEdges = m_gtScales->getTAUScales().etBins.at(etBin0);
0622             et0Phy = 0.5 * (binEdges.second + binEdges.first);
0623             lutObj0 = "TAU";
0624           } break;
0625           default: {
0626           } break;
0627         }  //end switch on calo type.
0628 
0629         phiORIndex0 = phiIndex0;
0630         etaORIndex0 = etaIndex0;
0631 
0632         //If needed convert calo scales to muon scales for comparison
0633         if (convertCaloScales) {
0634           std::string lutName = lutObj0;
0635           lutName += "-MU";
0636           long long tst = m_gtScales->getLUT_CalMuEta(lutName, etaBin0);
0637           LogDebug("L1TGlobal") << lutName << "  EtaCal = " << etaIndex0 << " etaBin0 = " << etaBin0
0638                                 << " EtaMu = " << tst << std::endl;
0639           etaIndex0 = tst;
0640           tst = m_gtScales->getLUT_CalMuPhi(lutName, phiIndex0);
0641           LogDebug("L1TGlobal") << lutName << "  PhiCal = " << phiIndex0 << " PhiMu = " << tst << std::endl;
0642           phiIndex0 = tst;
0643         }
0644 
0645         //If needed convert calo scales to muon scales for comparison
0646         if (convertCaloScalesForOverlapRemovalFromLeg0) {
0647           phiORIndex0 = phiIndex0;
0648           etaORIndex0 = etaIndex0;
0649         }
0650 
0651       } break;
0652 
0653       // Energy Sums
0654       case CondEnergySum: {
0655         etSumCond = true;
0656         //Stupid mapping between enum types for energy sums.
0657         l1t::EtSum::EtSumType type;
0658 
0659         switch (cndObjTypeVec[0]) {
0660           case gtETM:
0661             type = l1t::EtSum::EtSumType::kMissingEt;
0662             lutObj0 = "ETM";
0663             break;
0664           case gtETT:
0665             type = l1t::EtSum::EtSumType::kTotalEt;
0666             lutObj0 = "ETT";
0667             break;
0668           case gtETTem:
0669             type = l1t::EtSum::EtSumType::kTotalEtEm;
0670             lutObj0 =
0671                 "ETTem";  //should this be just ETT (share LUTs?) Can't be used for CorrCond anyway since now directional information
0672             break;
0673           case gtHTM:
0674             type = l1t::EtSum::EtSumType::kMissingHt;
0675             lutObj0 = "HTM";
0676             break;
0677           case gtHTT:
0678             type = l1t::EtSum::EtSumType::kTotalHt;
0679             lutObj0 = "HTT";
0680             break;
0681           case gtETMHF:
0682             type = l1t::EtSum::EtSumType::kMissingEtHF;
0683             lutObj0 = "ETMHF";
0684             break;
0685           case gtMinBiasHFP0:
0686           case gtMinBiasHFM0:
0687           case gtMinBiasHFP1:
0688           case gtMinBiasHFM1:
0689             type = l1t::EtSum::EtSumType::kMinBiasHFP0;
0690             lutObj0 =
0691                 "MinBias";  //??Fix?? Not a valid LUT type Can't be used for CorrCond anyway since now directional information
0692             break;
0693           default:
0694             edm::LogError("L1TGlobal") << "\n  Error: "
0695                                        << "Unmatched object type from template to EtSumType, cndObjTypeVec[0] = "
0696                                        << cndObjTypeVec[0] << std::endl;
0697             type = l1t::EtSum::EtSumType::kTotalEt;
0698             break;
0699         }
0700 
0701         candEtSumVec = m_uGtB->getCandL1EtSum();
0702 
0703         for (int iEtSum = 0; iEtSum < (int)candEtSumVec->size(cond0bx); iEtSum++) {
0704           if ((candEtSumVec->at(cond0bx, iEtSum))->getType() == type) {
0705             phiIndex0 = (candEtSumVec->at(cond0bx, iEtSum))->hwPhi();
0706             etaIndex0 = (candEtSumVec->at(cond0bx, iEtSum))->hwEta();
0707             etIndex0 = (candEtSumVec->at(cond0bx, iEtSum))->hwPt();
0708 
0709             //  Get the floating point numbers
0710             if (cndObjTypeVec[0] == gtETM) {
0711               std::pair<double, double> binEdges = m_gtScales->getETMScales().phiBins.at(phiIndex0);
0712               phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0713               eta0Phy = 0.;  //No Eta for Energy Sums
0714 
0715               etBin0 = etIndex0;
0716               int ssize = m_gtScales->getETMScales().etBins.size();
0717               assert(ssize > 0);
0718               if (etBin0 >= ssize) {
0719                 etBin0 = ssize - 1;
0720               }
0721 
0722               binEdges = m_gtScales->getETMScales().etBins.at(etBin0);
0723               et0Phy = 0.5 * (binEdges.second + binEdges.first);
0724             } else if (cndObjTypeVec[0] == gtHTM) {
0725               std::pair<double, double> binEdges = m_gtScales->getHTMScales().phiBins.at(phiIndex0);
0726               phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0727               eta0Phy = 0.;  //No Eta for Energy Sums
0728 
0729               etBin0 = etIndex0;
0730               int ssize = m_gtScales->getHTMScales().etBins.size();
0731               assert(ssize > 0);
0732               if (etBin0 >= ssize) {
0733                 etBin0 = ssize - 1;
0734               }
0735 
0736               binEdges = m_gtScales->getHTMScales().etBins.at(etBin0);
0737               et0Phy = 0.5 * (binEdges.second + binEdges.first);
0738             } else if (cndObjTypeVec[0] == gtETMHF) {
0739               std::pair<double, double> binEdges = m_gtScales->getETMHFScales().phiBins.at(phiIndex0);
0740               phi0Phy = 0.5 * (binEdges.second + binEdges.first);
0741               eta0Phy = 0.;  //No Eta for Energy Sums
0742 
0743               etBin0 = etIndex0;
0744               int ssize = m_gtScales->getETMHFScales().etBins.size();
0745               assert(ssize > 0);
0746               if (etBin0 >= ssize) {
0747                 etBin0 = ssize - 1;
0748               }
0749 
0750               binEdges = m_gtScales->getETMHFScales().etBins.at(etBin0);
0751               et0Phy = 0.5 * (binEdges.second + binEdges.first);
0752             }
0753 
0754             phiORIndex0 = phiIndex0;
0755             etaORIndex0 = etaIndex0;
0756 
0757             //If needed convert calo scales to muon scales for comparison (only phi for energy sums)
0758             if (convertCaloScales) {
0759               std::string lutName = lutObj0;
0760               lutName += "-MU";
0761               long long tst = m_gtScales->getLUT_CalMuPhi(lutName, phiIndex0);
0762               LogDebug("L1TGlobal") << lutName << "  PhiCal = " << phiIndex0 << " PhiMu = " << tst << std::endl;
0763               phiIndex0 = tst;
0764             }
0765 
0766             //If needed convert calo scales to muon scales for comparison (only phi for energy sums)
0767             if (convertCaloScalesForOverlapRemovalFromLeg0) {
0768               phiORIndex0 = phiIndex0;
0769             }
0770 
0771           }  //check it is the EtSum we want
0772         }  // loop over Etsums
0773 
0774       }  // end case CondEnergySum
0775       break;
0776 
0777       default: {
0778         // should not arrive here, there are no correlation conditions defined for this object
0779         LogDebug("L1TGlobal") << "Error could not find the Cond Category for Leg 0" << std::endl;
0780         return false;
0781       } break;
0782     }  //end switch on first leg type
0783 
0784     LogDebug("L1TGlobal") << "lutObj0 = " << lutObj0 << std::endl;
0785 
0786     // ///////////////////////////////////////////////////////////////////////////////////////////
0787     // Now loop over the second leg to get its information
0788     // ///////////////////////////////////////////////////////////////////////////////////////////
0789     for (auto const& it1Comb : cond1Comb) {
0790       LogDebug("L1TGlobal") << "Looking at second Condition" << std::endl;
0791       // Type1s: there is 1 object only, no need for a loop it1Comb[0]
0792       // ... but add protection to not crash
0793       if (it1Comb.empty()) {
0794         LogTrace("L1TGlobal") << "\n  SingleCombWithBxCond it1Comb.size() " << it1Comb.size();
0795         return false;
0796       }
0797 
0798       auto const cond1bx = it1Comb[0].first;
0799       auto const obj1Index = it1Comb[0].second;
0800 
0801       //If we are dealing with the same object type avoid the two legs
0802       // either being the same object
0803       if (cndObjTypeVec[0] == cndObjTypeVec[1] && obj0Index == obj1Index && cond0bx == cond1bx) {
0804         LogDebug("L1TGlobal") << "Corr Condition looking at same leg...skip" << std::endl;
0805         continue;
0806       }
0807 
0808       switch (cond1Categ) {
0809         case CondMuon: {
0810           lutObj1 = "MU";
0811           candMuVec = m_uGtB->getCandL1Mu();
0812           phiIndex1 = (candMuVec->at(cond1bx, obj1Index))->hwPhi();  //(*candMuVec)[obj0Index]->phiIndex();
0813           etaIndex1 = (candMuVec->at(cond1bx, obj1Index))->hwEta();
0814           etIndex1 = (candMuVec->at(cond1bx, obj1Index))->hwPt();
0815           chrg1 = (candMuVec->at(cond1bx, obj1Index))->hwCharge();
0816           etaBin1 = etaIndex1;
0817           if (etaBin1 < 0)
0818             etaBin1 = m_gtScales->getMUScales().etaBins.size() + etaBin1;
0819           //           LogDebug("L1TGlobal") << "Muon phi" << phiIndex1 << " eta " << etaIndex1 << " etaBin1 = " << etaBin1  << " et " << etIndex1 << std::endl;
0820           etBin1 = etIndex1;
0821           int ssize = m_gtScales->getMUScales().etBins.size();
0822 
0823           if (etBin1 >= ssize) {
0824             LogTrace("L1TGlobal") << "muon2 hw et" << etBin1 << " out of scale range.  Setting to maximum.";
0825             etBin1 = ssize - 1;
0826           }
0827 
0828           // Determine Floating Pt numbers for floating point caluclation
0829           std::pair<double, double> binEdges = m_gtScales->getMUScales().phiBins.at(phiIndex1);
0830           phi1Phy = 0.5 * (binEdges.second + binEdges.first);
0831           binEdges = m_gtScales->getMUScales().etaBins.at(etaBin1);
0832           eta1Phy = 0.5 * (binEdges.second + binEdges.first);
0833           binEdges = m_gtScales->getMUScales().etBins.at(etBin1);
0834           et1Phy = 0.5 * (binEdges.second + binEdges.first);
0835 
0836         } break;
0837 
0838         case CondCalo: {
0839           switch (cndObjTypeVec[1]) {
0840             case gtEG: {
0841               candCaloVec = m_uGtB->getCandL1EG();
0842               phiIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwPhi();
0843               etaIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwEta();
0844               etIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwPt();
0845               etaBin1 = etaIndex1;
0846               if (etaBin1 < 0)
0847                 etaBin1 = m_gtScales->getEGScales().etaBins.size() + etaBin1;
0848 
0849               etBin1 = etIndex1;
0850               int ssize = m_gtScales->getEGScales().etBins.size();
0851               if (etBin1 >= ssize) {
0852                 LogTrace("L1TGlobal") << "EG1 hw et" << etBin1 << " out of scale range.  Setting to maximum.";
0853                 etBin1 = ssize - 1;
0854               }
0855 
0856               // Determine Floating Pt numbers for floating point caluclation
0857               std::pair<double, double> binEdges = m_gtScales->getEGScales().phiBins.at(phiIndex1);
0858               phi1Phy = 0.5 * (binEdges.second + binEdges.first);
0859               binEdges = m_gtScales->getEGScales().etaBins.at(etaBin1);
0860               eta1Phy = 0.5 * (binEdges.second + binEdges.first);
0861               binEdges = m_gtScales->getEGScales().etBins.at(etBin1);
0862               et1Phy = 0.5 * (binEdges.second + binEdges.first);
0863               lutObj1 = "EG";
0864             } break;
0865 
0866             case gtJet: {
0867               candCaloVec = m_uGtB->getCandL1Jet();
0868               phiIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwPhi();
0869               etaIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwEta();
0870               etIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwPt();
0871               etaBin1 = etaIndex1;
0872               if (etaBin1 < 0)
0873                 etaBin1 = m_gtScales->getJETScales().etaBins.size() + etaBin1;
0874               etBin1 = etIndex1;
0875               int ssize = m_gtScales->getJETScales().etBins.size();
0876               assert(ssize);
0877               if (etBin1 >= ssize) {
0878                 //edm::LogWarning("L1TGlobal")
0879                 //<< "jet2 hw et" << etBin1 << " out of scale range.  Setting to maximum.";
0880                 etBin1 = ssize - 1;
0881               }
0882 
0883               // Determine Floating Pt numbers for floating point caluclation
0884               std::pair<double, double> binEdges = m_gtScales->getJETScales().phiBins.at(phiIndex1);
0885               phi1Phy = 0.5 * (binEdges.second + binEdges.first);
0886               binEdges = m_gtScales->getJETScales().etaBins.at(etaBin1);
0887               eta1Phy = 0.5 * (binEdges.second + binEdges.first);
0888 
0889               binEdges = m_gtScales->getJETScales().etBins.at(etBin1);
0890               et1Phy = 0.5 * (binEdges.second + binEdges.first);
0891               lutObj1 = "JET";
0892             } break;
0893 
0894             case gtTau: {
0895               candCaloVec = m_uGtB->getCandL1Tau();
0896               phiIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwPhi();
0897               etaIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwEta();
0898               etIndex1 = (candCaloVec->at(cond1bx, obj1Index))->hwPt();
0899               etaBin1 = etaIndex1;
0900               if (etaBin1 < 0)
0901                 etaBin1 = m_gtScales->getTAUScales().etaBins.size() + etaBin1;
0902               etBin1 = etIndex1;
0903               int ssize = m_gtScales->getTAUScales().etBins.size();
0904               if (etBin1 >= ssize) {
0905                 LogTrace("L1TGlobal") << "tau2 hw et" << etBin1 << " out of scale range.  Setting to maximum.";
0906                 etBin1 = ssize - 1;
0907               }
0908 
0909               // Determine Floating Pt numbers for floating point caluclation
0910               std::pair<double, double> binEdges = m_gtScales->getTAUScales().phiBins.at(phiIndex1);
0911               phi1Phy = 0.5 * (binEdges.second + binEdges.first);
0912               binEdges = m_gtScales->getTAUScales().etaBins.at(etaBin1);
0913               eta1Phy = 0.5 * (binEdges.second + binEdges.first);
0914               binEdges = m_gtScales->getTAUScales().etBins.at(etBin1);
0915               et1Phy = 0.5 * (binEdges.second + binEdges.first);
0916               lutObj1 = "TAU";
0917             } break;
0918             default: {
0919             } break;
0920           }  //end switch on calo type.
0921 
0922           phiORIndex1 = phiIndex1;
0923           etaORIndex1 = etaIndex1;
0924 
0925           //If needed convert calo scales to muon scales for comparison
0926           if (convertCaloScales) {
0927             std::string lutName = lutObj1;
0928             lutName += "-MU";
0929             long long tst = m_gtScales->getLUT_CalMuEta(lutName, etaBin1);
0930             LogDebug("L1TGlobal") << lutName << "  EtaCal = " << etaIndex1 << " EtaMu = " << tst << std::endl;
0931             etaIndex1 = tst;
0932             tst = m_gtScales->getLUT_CalMuPhi(lutName, phiIndex1);
0933             LogDebug("L1TGlobal") << lutName << "  PhiCal = " << phiIndex1 << " PhiMu = " << tst << std::endl;
0934             phiIndex1 = tst;
0935           }
0936 
0937           //If needed convert calo scales to muon scales for comparison
0938           if (convertCaloScalesForOverlapRemovalFromLeg1) {
0939             phiORIndex1 = phiIndex1;
0940             etaORIndex1 = etaIndex1;
0941           }
0942 
0943         }  // end case CondCalo
0944         break;
0945         case CondEnergySum: {
0946           LogDebug("L1TGlobal") << "Looking at second Condition as Energy Sum: " << cndObjTypeVec[1] << std::endl;
0947           etSumCond = true;
0948 
0949           //Stupid mapping between enum types for energy sums.
0950           l1t::EtSum::EtSumType type;
0951 
0952           switch (cndObjTypeVec[1]) {
0953             case gtETM:
0954               type = l1t::EtSum::EtSumType::kMissingEt;
0955               lutObj1 = "ETM";
0956               break;
0957             case gtETT:
0958               type = l1t::EtSum::EtSumType::kTotalEt;
0959               lutObj1 = "ETT";
0960               break;
0961             case gtETTem:
0962               type = l1t::EtSum::EtSumType::kTotalEtEm;
0963               lutObj1 = "ETTem";
0964               break;
0965             case gtHTM:
0966               type = l1t::EtSum::EtSumType::kMissingHt;
0967               lutObj1 = "HTM";
0968               break;
0969             case gtHTT:
0970               type = l1t::EtSum::EtSumType::kTotalHt;
0971               lutObj1 = "HTT";
0972               break;
0973             case gtETMHF:
0974               type = l1t::EtSum::EtSumType::kMissingEtHF;
0975               lutObj1 = "ETMHF";
0976               break;
0977             case gtMinBiasHFP0:
0978             case gtMinBiasHFM0:
0979             case gtMinBiasHFP1:
0980             case gtMinBiasHFM1:
0981               type = l1t::EtSum::EtSumType::kMinBiasHFP0;
0982               lutObj1 = "MinBias";
0983               break;
0984             default:
0985               edm::LogError("L1TGlobal") << "\n  Error: "
0986                                          << "Unmatched object type from template to EtSumType, cndObjTypeVec[1] = "
0987                                          << cndObjTypeVec[1] << std::endl;
0988               type = l1t::EtSum::EtSumType::kTotalEt;
0989               break;
0990           }
0991 
0992           candEtSumVec = m_uGtB->getCandL1EtSum();
0993 
0994           LogDebug("L1TGlobal") << "obj " << lutObj1 << " Vector Size " << candEtSumVec->size(cond1bx) << std::endl;
0995           for (int iEtSum = 0; iEtSum < (int)candEtSumVec->size(cond1bx); iEtSum++) {
0996             if ((candEtSumVec->at(cond1bx, iEtSum))->getType() == type) {
0997               phiIndex1 = (candEtSumVec->at(cond1bx, iEtSum))->hwPhi();
0998               etaIndex1 = (candEtSumVec->at(cond1bx, iEtSum))->hwEta();
0999               etIndex1 = (candEtSumVec->at(cond1bx, iEtSum))->hwPt();
1000 
1001               // Determine Floating Pt numbers for floating point caluclation
1002 
1003               if (cndObjTypeVec[1] == gtETM) {
1004                 std::pair<double, double> binEdges = m_gtScales->getETMScales().phiBins.at(phiIndex1);
1005                 phi1Phy = 0.5 * (binEdges.second + binEdges.first);
1006                 eta1Phy = 0.;  //No Eta for Energy Sums
1007 
1008                 etBin1 = etIndex1;
1009                 int ssize = m_gtScales->getETMScales().etBins.size();
1010                 assert(ssize > 0);
1011                 if (etBin1 >= ssize) {
1012                   etBin1 = ssize - 1;
1013                 }
1014 
1015                 binEdges = m_gtScales->getETMScales().etBins.at(etBin1);
1016                 et1Phy = 0.5 * (binEdges.second + binEdges.first);
1017               } else if (cndObjTypeVec[1] == gtHTM) {
1018                 std::pair<double, double> binEdges = m_gtScales->getHTMScales().phiBins.at(phiIndex1);
1019                 phi1Phy = 0.5 * (binEdges.second + binEdges.first);
1020                 eta1Phy = 0.;  //No Eta for Energy Sums
1021 
1022                 etBin1 = etIndex1;
1023                 int ssize = m_gtScales->getHTMScales().etBins.size();
1024                 assert(ssize > 0);
1025                 if (etBin1 >= ssize) {
1026                   etBin1 = ssize - 1;
1027                 }
1028 
1029                 binEdges = m_gtScales->getHTMScales().etBins.at(etBin1);
1030                 et1Phy = 0.5 * (binEdges.second + binEdges.first);
1031               } else if (cndObjTypeVec[1] == gtETMHF) {
1032                 std::pair<double, double> binEdges = m_gtScales->getETMHFScales().phiBins.at(phiIndex1);
1033                 phi1Phy = 0.5 * (binEdges.second + binEdges.first);
1034                 eta1Phy = 0.;  //No Eta for Energy Sums
1035                 etBin1 = etIndex1;
1036                 int ssize = m_gtScales->getETMHFScales().etBins.size();
1037                 assert(ssize > 0);
1038                 if (etBin1 >= ssize) {
1039                   etBin1 = ssize - 1;
1040                 }
1041                 binEdges = m_gtScales->getETMHFScales().etBins.at(etBin1);
1042                 et1Phy = 0.5 * (binEdges.second + binEdges.first);
1043               }
1044 
1045               phiORIndex1 = phiIndex1;
1046               etaORIndex1 = etaIndex1;
1047 
1048               //If needed convert calo scales to muon scales for comparison (only phi for energy sums)
1049               if (convertCaloScales) {
1050                 std::string lutName = lutObj1;
1051                 lutName += "-MU";
1052                 long long tst = m_gtScales->getLUT_CalMuPhi(lutName, phiIndex1);
1053                 LogDebug("L1TGlobal") << lutName << "  PhiCal = " << phiIndex1 << " PhiMu = " << tst << std::endl;
1054                 phiIndex1 = tst;
1055               }
1056 
1057               //If needed convert calo scales to muon scales for comparison (only phi for energy sums)
1058               if (convertCaloScalesForOverlapRemovalFromLeg1) {
1059                 phiORIndex1 = phiIndex1;
1060               }
1061 
1062             }  //check it is the EtSum we want
1063           }  // loop over Etsums
1064 
1065         }  // end case EnergySum
1066         break;
1067         default: {
1068           // should not arrive here, there are no correlation conditions defined for this object
1069           LogDebug("L1TGlobal") << "Error could not find the Cond Category for Leg 0" << std::endl;
1070           return false;
1071         } break;
1072       }  //end switch on second leg
1073 
1074       if (m_verbosity) {
1075         LogDebug("L1TGlobal") << "    Correlation pair [" << l1t::GlobalObjectEnumToString(cndObjTypeVec[0]) << ", "
1076                               << l1t::GlobalObjectEnumToString(cndObjTypeVec[1]) << "] with collection indices ["
1077                               << obj0Index << ", " << obj1Index << "] "
1078                               << " has: \n"
1079                               << "     Et  value   = [" << etIndex0 << ", " << etIndex1 << "]\n"
1080                               << "     phi indices = [" << phiIndex0 << ", " << phiIndex1 << "]\n"
1081                               << "     eta indices = [" << etaIndex0 << ", " << etaIndex1 << "]\n"
1082                               << "     chrg        = [" << chrg0 << ", " << chrg1 << "]\n";
1083       }
1084 
1085       // Now perform the desired correlation on these two objects. Assume true until we find a contradition
1086       bool reqResult = true;
1087 
1088       // if we get here all checks were successful for this combination
1089       // set the general result for evaluateCondition to "true"
1090 
1091       // These all require some delta eta and phi calculations.  Do them first...for now real calculation but need to
1092       // revise this to line up with firmware calculations.
1093       double deltaPhiPhy = fabs(phi1Phy - phi0Phy);
1094       if (deltaPhiPhy > M_PI)
1095         deltaPhiPhy = 2. * M_PI - deltaPhiPhy;
1096       double deltaEtaPhy = fabs(eta1Phy - eta0Phy);
1097 
1098       // Determine the integer based delta eta and delta phi
1099       int deltaPhiFW = abs(phiIndex0 - phiIndex1);
1100       if (deltaPhiFW >= phiBound)
1101         deltaPhiFW = 2 * phiBound - deltaPhiFW;
1102       std::string lutName = lutObj0;
1103       lutName += "-";
1104       lutName += lutObj1;
1105       long long deltaPhiLUT = m_gtScales->getLUT_DeltaPhi(lutName, deltaPhiFW);
1106       unsigned int precDeltaPhiLUT = m_gtScales->getPrec_DeltaPhi(lutName);
1107 
1108       int deltaEtaFW = abs(etaIndex0 - etaIndex1);
1109       long long deltaEtaLUT = 0;
1110       unsigned int precDeltaEtaLUT = 0;
1111       if (!etSumCond) {
1112         deltaEtaLUT = m_gtScales->getLUT_DeltaEta(lutName, deltaEtaFW);
1113         precDeltaEtaLUT = m_gtScales->getPrec_DeltaEta(lutName);
1114       }
1115 
1116       //
1117       LogDebug("L1TGlobal") << "Obj0 phiFW = " << phiIndex0 << " Obj1 phiFW = " << phiIndex1 << "\n"
1118                             << "    DeltaPhiFW = " << deltaPhiFW << "\n"
1119                             << "    LUT Name = " << lutName << " Prec = " << precDeltaPhiLUT
1120                             << "  DeltaPhiLUT = " << deltaPhiLUT << "\n"
1121                             << "Obj0 etaFW = " << etaIndex0 << " Obj1 etaFW = " << etaIndex1 << "\n"
1122                             << "    DeltaEtaFW = " << deltaEtaFW << "\n"
1123                             << "    LUT Name = " << lutName << " Prec = " << precDeltaEtaLUT
1124                             << "  DeltaEtaLUT = " << deltaEtaLUT << std::endl;
1125 
1126       // If there is a delta eta, check it.
1127       if (corrPar.corrCutType & 0x1) {
1128         unsigned int preShift = precDeltaEtaLUT - corrPar.precEtaCut;
1129         LogDebug("L1TGlobal") << "    Testing Delta Eta Cut (" << lutObj0 << "," << lutObj1 << ") ["
1130                               << (long long)(corrPar.minEtaCutValue * pow(10, preShift)) << ","
1131                               << (long long)(corrPar.maxEtaCutValue * pow(10, preShift))
1132                               << "] with precision = " << corrPar.precEtaCut << "\n"
1133                               << "    deltaEtaLUT = " << deltaEtaLUT << "\n"
1134                               << "    Precision Shift = " << preShift << "\n"
1135                               << "    deltaEta (shift)= " << (deltaEtaLUT / pow(10, preShift + corrPar.precEtaCut))
1136                               << "\n"
1137                               << "    deltaEtaPhy = " << deltaEtaPhy << std::endl;
1138 
1139         //if(preShift>0) deltaEtaLUT /= pow(10,preShift);
1140         if (deltaEtaLUT >= (long long)(corrPar.minEtaCutValue * pow(10, preShift)) &&
1141             deltaEtaLUT <= (long long)(corrPar.maxEtaCutValue * pow(10, preShift))) {
1142           LogDebug("L1TGlobal") << "    Passed Delta Eta Cut ["
1143                                 << (long long)(corrPar.minEtaCutValue * pow(10, preShift)) << ","
1144                                 << (long long)(corrPar.maxEtaCutValue * pow(10, preShift)) << "]" << std::endl;
1145 
1146         } else {
1147           LogDebug("L1TGlobal") << "    Failed Delta Eta Cut ["
1148                                 << (long long)(corrPar.minEtaCutValue * pow(10, preShift)) << ","
1149                                 << (long long)(corrPar.maxEtaCutValue * pow(10, preShift)) << "]" << std::endl;
1150           reqResult = false;
1151         }
1152       }
1153 
1154       //if there is a delta phi check it.
1155       if (corrPar.corrCutType & 0x2) {
1156         unsigned int preShift = precDeltaPhiLUT - corrPar.precPhiCut;
1157         LogDebug("L1TGlobal") << "    Testing Delta Phi Cut (" << lutObj0 << "," << lutObj1 << ") ["
1158                               << (long long)(corrPar.minPhiCutValue * pow(10, preShift)) << ","
1159                               << (long long)(corrPar.maxPhiCutValue * pow(10, preShift))
1160                               << "] with precision = " << corrPar.precPhiCut << "\n"
1161                               << "    deltaPhiLUT = " << deltaPhiLUT << "\n"
1162                               << "    Precision Shift = " << preShift << "\n"
1163                               << "    deltaPhi (shift)= " << (deltaPhiLUT / pow(10, preShift + corrPar.precPhiCut))
1164                               << "\n"
1165                               << "    deltaPhiPhy = " << deltaPhiPhy << std::endl;
1166 
1167         //if(preShift>0) deltaPhiLUT /= pow(10,preShift);
1168         if (deltaPhiLUT >= (long long)(corrPar.minPhiCutValue * pow(10, preShift)) &&
1169             deltaPhiLUT <= (long long)(corrPar.maxPhiCutValue * pow(10, preShift))) {
1170           LogDebug("L1TGlobal") << "    Passed Delta Phi Cut ["
1171                                 << (long long)(corrPar.minPhiCutValue * pow(10, preShift)) << ","
1172                                 << (long long)(corrPar.maxPhiCutValue * pow(10, preShift)) << "]" << std::endl;
1173 
1174         } else {
1175           LogDebug("L1TGlobal") << "    Failed Delta Phi Cut ["
1176                                 << (long long)(corrPar.minPhiCutValue * pow(10, preShift)) << ","
1177                                 << (long long)(corrPar.maxPhiCutValue * pow(10, preShift)) << "]" << std::endl;
1178           reqResult = false;
1179         }
1180       }
1181 
1182       if (corrPar.corrCutType & 0x4) {
1183         //Assumes Delta Eta and Delta Phi LUTs have the same precision
1184         unsigned int preShift = 2 * precDeltaPhiLUT - corrPar.precDRCut;
1185         double deltaRSqPhy = deltaPhiPhy * deltaPhiPhy + deltaEtaPhy * deltaEtaPhy;
1186         long long deltaRSq = deltaEtaLUT * deltaEtaLUT + deltaPhiLUT * deltaPhiLUT;
1187 
1188         LogDebug("L1TGlobal") << "    Testing Delta R Cut (" << lutObj0 << "," << lutObj1 << ") ["
1189                               << (long long)(corrPar.minDRCutValue * pow(10, preShift)) << ","
1190                               << (long long)(corrPar.maxDRCutValue * pow(10, preShift))
1191                               << "] with precision = " << corrPar.precDRCut << "\n"
1192                               << "    deltaPhiLUT = " << deltaPhiLUT << "\n"
1193                               << "    deltaEtaLUT = " << deltaEtaLUT << "\n"
1194                               << "    deltaRSqLUT = " << deltaRSq << "\n"
1195                               << "    Precision Shift = " << preShift << "\n"
1196                               << "    deltaRSqLUT (shift)= " << (deltaRSq / pow(10, preShift + corrPar.precDRCut))
1197                               << "\n"
1198                               << "    deltaRSqPhy = " << deltaRSqPhy << std::endl;
1199 
1200         //if(preShift>0) deltaRSq /= pow(10,preShift);
1201         if (deltaRSq >= (long long)(corrPar.minDRCutValue * pow(10, preShift)) &&
1202             deltaRSq <= (long long)(corrPar.maxDRCutValue * pow(10, preShift))) {
1203           LogDebug("L1TGlobal") << "    Passed Delta R Cut [" << (long long)(corrPar.minDRCutValue * pow(10, preShift))
1204                                 << "," << (long long)(corrPar.maxDRCutValue * pow(10, preShift)) << "]" << std::endl;
1205 
1206         } else {
1207           LogDebug("L1TGlobal") << "    Failed Delta R Cut [" << (int)(corrPar.minDRCutValue * pow(10, preShift)) << ","
1208                                 << (long long)(corrPar.maxDRCutValue * pow(10, preShift)) << "]" << std::endl;
1209           reqResult = false;
1210         }
1211       }
1212 
1213       if (corrPar.corrCutType & 0x20) {
1214         // Two body pt: pt^2 = pt1^2+pt2^2+2*pt1*pt2*(cos(phi1)*cos(phi2)+sin(phi1)*sin(phi2)).
1215 
1216         LogDebug("L1TGlobal") << " corrPar.corrCutType: " << corrPar.corrCutType << "\n";
1217 
1218         //calculate math sins and cosines for debugging
1219         double cosPhi1Phy = cos(phi0Phy);
1220         double sinPhi1Phy = sin(phi0Phy);
1221         double cosPhi2Phy = cos(phi1Phy);
1222         double sinPhi2Phy = sin(phi1Phy);
1223 
1224         double tbptSqPhy = et0Phy * et0Phy + et1Phy * et1Phy +
1225                            2 * et0Phy * et1Phy * (cosPhi1Phy * cosPhi2Phy + sinPhi1Phy * sinPhi2Phy);
1226         // get values from LUT's
1227 
1228         const std::string& lutName0 = lutObj0;
1229         unsigned int precCosLUT0 = m_gtScales->getPrec_Cos(lutName0);
1230         unsigned int precSinLUT0 = m_gtScales->getPrec_Sin(lutName0);
1231 
1232         const std::string& lutName1 = lutObj1;
1233         unsigned int precCosLUT1 = m_gtScales->getPrec_Cos(lutName1);
1234         unsigned int precSinLUT1 = m_gtScales->getPrec_Sin(lutName1);
1235 
1236         if (precCosLUT0 - precCosLUT1 != 0)
1237           LogDebug("L1TGlobal") << "Warning: Cos LUTs for TwoBodyPt on different Precision" << std::endl;
1238         if (precSinLUT0 - precSinLUT1 != 0)
1239           LogDebug("L1TGlobal") << "Warning: Sin LUTs for TwoBodyPt on different Precision" << std::endl;
1240         if (precSinLUT0 - precCosLUT1 != 0)
1241           LogDebug("L1TGlobal") << "Warning: Sin and Cos LUTs for TwoBodyPt on different Precision" << std::endl;
1242         if (precSinLUT1 - precCosLUT0 != 0)
1243           LogDebug("L1TGlobal") << "Warning: Sin and Cos LUTs for TwoBodyPt on different Precision" << std::endl;
1244 
1245         long long cosPhi1LUT = m_gtScales->getLUT_Cos(lutName0, phiIndex0);
1246         long long sinPhi1LUT = m_gtScales->getLUT_Sin(lutName0, phiIndex0);
1247 
1248         long long cosPhi2LUT = m_gtScales->getLUT_Cos(lutName1, phiIndex1);
1249         long long sinPhi2LUT = m_gtScales->getLUT_Sin(lutName1, phiIndex1);
1250 
1251         // now get pt LUTs
1252         std::string lutName = lutObj0;
1253         lutName += "-ET";
1254         long long ptObj0 = m_gtScales->getLUT_Pt("TwoBody_" + lutName, etIndex0);
1255         unsigned int precPtLUTObj0 = m_gtScales->getPrec_Pt("TwoBody_" + lutName);
1256 
1257         lutName = lutObj1;
1258         lutName += "-ET";
1259         long long ptObj1 = m_gtScales->getLUT_Pt("TwoBody_" + lutName, etIndex1);
1260         unsigned int precPtLUTObj1 = m_gtScales->getPrec_Pt("TwoBody_" + lutName);
1261 
1262         LogTrace("L1TGlobal") << " TBPT Trig precisions:\t " << precCosLUT0 << "\t" << precCosLUT1 << "\t"
1263                               << precSinLUT0 << "\t" << precSinLUT1;
1264         LogTrace("L1TGlobal") << " TBPT Pt precisions:\t " << precPtLUTObj0 << "\t" << precPtLUTObj1;
1265         LogTrace("L1TGlobal") << " TBPT Pt cut:\t " << corrPar.minTBPTCutValue << "\tPrecTBPTCut\t"
1266                               << corrPar.precTBPTCut;
1267         LogTrace("L1TGlobal") << " TBPT Pt1*Pt1 -- Phys:\t " << et0Phy * et0Phy << "\tHW:\t"
1268                               << ptObj0 * ptObj0 * (pow(10, 6));
1269         LogTrace("L1TGlobal") << " TBPT Pt2*Pt2 -- Phys:\t " << et1Phy * et1Phy << "\tHW:\t"
1270                               << ptObj1 * ptObj1 * (pow(10, 6));
1271         LogTrace("L1TGlobal") << " TBPT 2Pt1*Pt2 -- Phys:\t " << 2 * et0Phy * et1Phy << "\tHW:\t"
1272                               << 2 * (ptObj0 * pow(10, 0)) * (ptObj1 * pow(10, 0));
1273         LogTrace("L1TGlobal") << " TBPT Trig -- Phys:\t " << cosPhi1Phy * cosPhi2Phy + sinPhi1Phy * sinPhi2Phy
1274                               << "\tHW:\t" << cosPhi1LUT * cosPhi2LUT + sinPhi1LUT * sinPhi2LUT;
1275 
1276         //double tbptSqPhy =   et0Phy*et0Phy             + et1Phy*et1Phy + 2*et0Phy*et1Phy*(cosPhi1Phy*cosPhi2Phy + sinPhi1Phy*sinPhi2Phy);
1277         long long tbptSqHW = ptObj0 * ptObj0 * (pow(10, 2 * precCosLUT0)) +
1278                              ptObj1 * ptObj1 * (pow(10, 2 * precCosLUT0)) +
1279                              2 * ptObj0 * ptObj1 * (cosPhi1LUT * cosPhi2LUT + sinPhi1LUT * sinPhi2LUT);
1280 
1281         unsigned int preShift = precPtLUTObj0 + precPtLUTObj1 + 2 * precCosLUT0;
1282 
1283         LogTrace("L1TGlobal") << "TBPT Result -- Phys: " << tbptSqPhy << "\tHW: " << tbptSqHW << "\tShifted\t"
1284                               << tbptSqHW / pow(10, preShift) << std::endl;
1285 
1286         preShift = preShift - corrPar.precTBPTCut;
1287 
1288         LogDebug("L1TGlobal")
1289             << "    Testing Two Body Pt Cut (" << lutObj0 << "," << lutObj1 << ") ["
1290             << (long long)(corrPar.minTBPTCutValue * pow(10, preShift)) << ","
1291             << (long long)(corrPar.maxTBPTCutValue * pow(10, preShift)) << "] with precision = " << corrPar.precTBPTCut
1292             << "\n"
1293             << "    etIndex0     = " << etIndex0 << "    pt0LUT      = " << ptObj0 << " PhyEt0 = " << et0Phy << "\n"
1294             << "    etIndex1     = " << etIndex1 << "    pt1LUT      = " << ptObj1 << " PhyEt1 = " << et1Phy << "\n"
1295             << "    Precision Shift = " << preShift << "\n"
1296             << "    Sin(phi1): LUT/Phys\t " << sinPhi1LUT << " / " << sinPhi1Phy << "\n"
1297             << "    Sin(phi2): LUT/Phys\t " << sinPhi2LUT << " / " << sinPhi2Phy << "\n"
1298             << "    Cos(phi1): LUT/Phys\t " << cosPhi1LUT << " / " << cosPhi1Phy << "\n"
1299             << "    Cos(phi2): LUT/Phys\t " << cosPhi2LUT << " / " << cosPhi2Phy
1300             << "\n"
1301 
1302             //    << "    deltaPhiLUT = " << deltaPhiLUT << "\n"
1303             //    << "    deltaEtaLUT = " << deltaEtaLUT << "\n"
1304             //    << "    deltaRSqLUT = " << deltaRSq <<  "\n"
1305             //    << "    Precision Shift = " << preShift << "\n"
1306             //    << "    deltaRSqLUT (shift)= " << (deltaRSq/pow(10,preShift+corrPar.precDRCut)) << "\n"
1307             //    << "    deltaRSqPhy = " << deltaRSqPhy
1308             << std::endl;
1309 
1310         if (tbptSqHW > 0. && tbptSqHW >= (long long)(corrPar.minTBPTCutValue * pow(10, preShift))) {
1311           LogDebug("L1TGlobal") << "    Passed Two Body pT Cut ["
1312                                 << (long long)(corrPar.minTBPTCutValue * pow(10, preShift)) << "]"
1313                                 << "\twith value: " << tbptSqHW << "\n"
1314                                 << "\tPhysics Cut[" << corrPar.minTBPTCutValue / pow(10, corrPar.precTBPTCut)
1315                                 << "]\tPhysics Value: " << tbptSqPhy << std::endl;
1316 
1317         } else {
1318           LogDebug("L1TGlobal") << "    Failed Two Body pT Cut ["
1319                                 << (long long)(corrPar.minTBPTCutValue * pow(10, preShift)) << "]"
1320                                 << "\t with value: " << tbptSqHW << "\n"
1321                                 << "\tPhysics Cut[" << corrPar.minTBPTCutValue / pow(10, corrPar.precTBPTCut)
1322                                 << "]\tPhysics Value: " << tbptSqPhy << std::endl;
1323           reqResult = false;
1324         }
1325       }
1326 
1327       if (corrPar.corrCutType & 0x8 || corrPar.corrCutType & 0x10) {
1328         //invariant mass calculation based on
1329         // M = sqrt(2*p1*p2(cosh(eta1-eta2) - cos(phi1 - phi2)))
1330         // but we calculate (1/2)M^2
1331         //
1332         double cosDeltaPhiPhy = cos(deltaPhiPhy);
1333         double coshDeltaEtaPhy = cosh(deltaEtaPhy);
1334         if (corrPar.corrCutType & 0x10)
1335           coshDeltaEtaPhy = 1.;
1336         double massSqPhy = et0Phy * et1Phy * (coshDeltaEtaPhy - cosDeltaPhiPhy);
1337 
1338         long long cosDeltaPhiLUT = m_gtScales->getLUT_DeltaPhi_Cos(lutName, deltaPhiFW);
1339         unsigned int precCosLUT = m_gtScales->getPrec_DeltaPhi_Cos(lutName);
1340 
1341         long long coshDeltaEtaLUT;
1342         if (corrPar.corrCutType & 0x10) {
1343           coshDeltaEtaLUT = 1 * pow(10, precCosLUT);
1344         } else {
1345           coshDeltaEtaLUT = m_gtScales->getLUT_DeltaEta_Cosh(lutName, deltaEtaFW);
1346           unsigned int precCoshLUT = m_gtScales->getPrec_DeltaEta_Cosh(lutName);
1347           if (precCoshLUT - precCosLUT != 0)
1348             LogDebug("L1TGlobal") << "Warning: Cos and Cosh LUTs on different Precision" << std::endl;
1349         }
1350 
1351         std::string lutName = lutObj0;
1352         lutName += "-ET";
1353         long long ptObj0 = m_gtScales->getLUT_Pt("Mass_" + lutName, etIndex0);
1354         unsigned int precPtLUTObj0 = m_gtScales->getPrec_Pt("Mass_" + lutName);
1355 
1356         lutName = lutObj1;
1357         lutName += "-ET";
1358         long long ptObj1 = m_gtScales->getLUT_Pt("Mass_" + lutName, etIndex1);
1359         unsigned int precPtLUTObj1 = m_gtScales->getPrec_Pt("Mass_" + lutName);
1360 
1361         // Pt and Angles are at different precission.
1362         long long massSq = ptObj0 * ptObj1 * (coshDeltaEtaLUT - cosDeltaPhiLUT);
1363 
1364         //Note: There is an assumption here that Cos and Cosh have the same precission
1365         unsigned int preShift = precPtLUTObj0 + precPtLUTObj1 + precCosLUT - corrPar.precMassCut;
1366 
1367         LogDebug("L1TGlobal") << "    Testing Invariant Mass (" << lutObj0 << "," << lutObj1 << ") ["
1368                               << (long long)(corrPar.minMassCutValue * pow(10, preShift)) << ","
1369                               << (long long)(corrPar.maxMassCutValue * pow(10, preShift))
1370                               << "] with precision = " << corrPar.precMassCut << "\n"
1371                               << "    deltaPhiLUT  = " << deltaPhiLUT << "  cosLUT  = " << cosDeltaPhiLUT << "\n"
1372                               << "    deltaEtaLUT  = " << deltaEtaLUT << "  coshLUT = " << coshDeltaEtaLUT << "\n"
1373                               << "    etIndex0     = " << etIndex0 << "    pt0LUT      = " << ptObj0
1374                               << " PhyEt0 = " << et0Phy << "\n"
1375                               << "    etIndex1     = " << etIndex1 << "    pt1LUT      = " << ptObj1
1376                               << " PhyEt1 = " << et1Phy << "\n"
1377                               << "    massSq/2     = " << massSq << "\n"
1378                               << "    Precision Shift = " << preShift << "\n"
1379                               << "    massSq   (shift)= " << (massSq / pow(10, preShift + corrPar.precMassCut)) << "\n"
1380                               << "    deltaPhiPhy  = " << deltaPhiPhy << "  cos() = " << cosDeltaPhiPhy << "\n"
1381                               << "    deltaEtaPhy  = " << deltaEtaPhy << "  cosh()= " << coshDeltaEtaPhy << "\n"
1382                               << "    massSqPhy/2  = " << massSqPhy
1383                               << "  sqrt(|massSq|) = " << sqrt(fabs(2. * massSqPhy)) << std::endl;
1384 
1385         //if(preShift>0) massSq /= pow(10,preShift);
1386         if (massSq >= 0 && massSq >= (long long)(corrPar.minMassCutValue * pow(10, preShift)) &&
1387             massSq <= (long long)(corrPar.maxMassCutValue * pow(10, preShift))) {
1388           LogDebug("L1TGlobal") << "    Passed Invariant Mass Cut ["
1389                                 << (long long)(corrPar.minMassCutValue * pow(10, preShift)) << ","
1390                                 << (long long)(corrPar.maxMassCutValue * pow(10, preShift)) << "]" << std::endl;
1391 
1392         } else {
1393           LogDebug("L1TGlobal") << "    Failed Invariant Mass Cut ["
1394                                 << (long long)(corrPar.minMassCutValue * pow(10, preShift)) << ","
1395                                 << (long long)(corrPar.maxMassCutValue * pow(10, preShift)) << "]" << std::endl;
1396           reqResult = false;
1397         }
1398       }
1399 
1400       // For Muon-Muon Correlation Check the Charge Correlation if requested
1401       bool chrgCorrel = true;
1402       if (cond0Categ == CondMuon && cond1Categ == CondMuon) {
1403         // Check for like-sign
1404         if (corrPar.chargeCorrelation == 2 && chrg0 != chrg1)
1405           chrgCorrel = false;
1406         // Check for opp-sign
1407         if (corrPar.chargeCorrelation == 4 && chrg0 == chrg1)
1408           chrgCorrel = false;
1409       }
1410 
1411       if (!reqResult || !chrgCorrel)
1412         continue;
1413 
1414       // ///////////////////////////////////////////////////////////////////////////////////////////
1415       // loop over overlap-removal leg combination which produced individually "true" as Type1s
1416       // ///////////////////////////////////////////////////////////////////////////////////////////
1417       for (auto const& it2Comb : cond2Comb) {
1418         // Type1s: there is 1 object only, no need for a loop, index 0 should be OK in it2Comb[0]
1419         // ... but add protection to not crash
1420         if (it2Comb.empty()) {
1421           LogTrace("L1TGlobal") << "\n  SingleCombWithBxCond it2Comb.size() " << it2Comb.size();
1422           return false;
1423         }
1424 
1425         auto const cond2bx = it2Comb[0].first;
1426         auto const obj2Index = it2Comb[0].second;
1427 
1428         // Collect the information on the overlap-removal leg
1429         switch (cond2Categ) {
1430           case CondMuon: {
1431             lutObj2 = "MU";
1432             candMuVec = m_uGtB->getCandL1Mu();
1433             phiIndex2 = (candMuVec->at(cond2bx, obj2Index))->hwPhi();  //(*candMuVec)[obj2Index]->phiIndex();
1434             etaIndex2 = (candMuVec->at(cond2bx, obj2Index))->hwEta();
1435             int etaBin2 = etaIndex2;
1436             if (etaBin2 < 0)
1437               etaBin2 = m_gtScales->getMUScales().etaBins.size() + etaBin2;  //twos complement
1438             //LogDebug("L1TGlobal") << "Muon phi" << phiIndex2 << " eta " << etaIndex2 << " etaBin2 = " << etaBin2  << " et " << etIndex2 << std::endl;
1439 
1440             // Determine Floating Pt numbers for floating point caluclation
1441             std::pair<double, double> binEdges = m_gtScales->getMUScales().phiBins.at(phiIndex2);
1442             phi2Phy = 0.5 * (binEdges.second + binEdges.first);
1443             binEdges = m_gtScales->getMUScales().etaBins.at(etaBin2);
1444             eta2Phy = 0.5 * (binEdges.second + binEdges.first);
1445 
1446             LogDebug("L1TGlobal") << "Found all quantities for the muon 0" << std::endl;
1447           } break;
1448 
1449           // Calorimeter Objects (EG, Jet, Tau)
1450           case CondCalo: {
1451             switch (cndObjTypeVec[2]) {
1452               case gtEG: {
1453                 lutObj2 = "EG";
1454                 candCaloVec = m_uGtB->getCandL1EG();
1455                 phiIndex2 = (candCaloVec->at(cond2bx, obj2Index))->hwPhi();
1456                 etaIndex2 = (candCaloVec->at(cond2bx, obj2Index))->hwEta();
1457                 if (etaBin2 < 0)
1458                   etaBin2 = m_gtScales->getEGScales().etaBins.size() + etaBin2;
1459                 //LogDebug("L1TGlobal") << "EG0 phi" << phiIndex2 << " eta " << etaIndex2 << " etaBin2 = " << etaBin2 << " et " << etIndex2 << std::endl;
1460 
1461                 // Determine Floating Pt numbers for floating point caluclation
1462                 std::pair<double, double> binEdges = m_gtScales->getEGScales().phiBins.at(phiIndex2);
1463                 phi2Phy = 0.5 * (binEdges.second + binEdges.first);
1464                 binEdges = m_gtScales->getEGScales().etaBins.at(etaBin2);
1465                 eta2Phy = 0.5 * (binEdges.second + binEdges.first);
1466               } break;
1467 
1468               case gtJet: {
1469                 lutObj2 = "JET";
1470                 candCaloVec = m_uGtB->getCandL1Jet();
1471                 phiIndex2 = (candCaloVec->at(cond2bx, obj2Index))->hwPhi();
1472                 etaIndex2 = (candCaloVec->at(cond2bx, obj2Index))->hwEta();
1473                 etaBin2 = etaIndex2;
1474                 if (etaBin2 < 0)
1475                   etaBin2 = m_gtScales->getJETScales().etaBins.size() + etaBin2;
1476                 // Determine Floating Pt numbers for floating point caluclation
1477                 std::pair<double, double> binEdges = m_gtScales->getJETScales().phiBins.at(phiIndex2);
1478                 phi2Phy = 0.5 * (binEdges.second + binEdges.first);
1479                 binEdges = m_gtScales->getJETScales().etaBins.at(etaBin2);
1480                 eta2Phy = 0.5 * (binEdges.second + binEdges.first);
1481               } break;
1482               case gtTau: {
1483                 candCaloVec = m_uGtB->getCandL1Tau();
1484                 phiIndex2 = (candCaloVec->at(cond2bx, obj2Index))->hwPhi();
1485                 etaIndex2 = (candCaloVec->at(cond2bx, obj2Index))->hwEta();
1486                 if (etaBin2 < 0)
1487                   etaBin2 = m_gtScales->getTAUScales().etaBins.size() + etaBin2;
1488 
1489                 // Determine Floating Pt numbers for floating point caluclation
1490                 std::pair<double, double> binEdges = m_gtScales->getTAUScales().phiBins.at(phiIndex2);
1491                 phi2Phy = 0.5 * (binEdges.second + binEdges.first);
1492                 binEdges = m_gtScales->getTAUScales().etaBins.at(etaBin2);
1493                 eta2Phy = 0.5 * (binEdges.second + binEdges.first);
1494                 lutObj2 = "TAU";
1495               } break;
1496               default: {
1497               } break;
1498             }  //end switch on calo type.
1499 
1500             //If needed convert calo scales to muon scales for comparison
1501             if (convertCaloScales) {
1502               std::string lutName = lutObj2;
1503               lutName += "-MU";
1504               long long tst = m_gtScales->getLUT_CalMuEta(lutName, etaBin2);
1505               LogDebug("L1TGlobal") << lutName << "  EtaCal = " << etaIndex2 << " etaBin2 = " << etaBin2
1506                                     << " EtaMu = " << tst << std::endl;
1507               etaIndex2 = tst;
1508 
1509               tst = m_gtScales->getLUT_CalMuPhi(lutName, phiIndex2);
1510               LogDebug("L1TGlobal") << lutName << "  PhiCal = " << phiIndex2 << " PhiMu = " << tst << std::endl;
1511               phiIndex2 = tst;
1512             }
1513 
1514           } break;
1515 
1516           // Energy Sums
1517           case CondEnergySum: {
1518             etSumCond = true;
1519             //Stupid mapping between enum types for energy sums.
1520             l1t::EtSum::EtSumType type;
1521             switch (cndObjTypeVec[2]) {
1522               case gtETM:
1523                 type = l1t::EtSum::EtSumType::kMissingEt;
1524                 lutObj2 = "ETM";
1525                 break;
1526               case gtETT:
1527                 type = l1t::EtSum::EtSumType::kTotalEt;
1528                 lutObj2 = "ETT";
1529                 break;
1530               case gtETTem:
1531                 type = l1t::EtSum::EtSumType::kTotalEtEm;
1532                 lutObj2 =
1533                     "ETTem";  //should this be just ETT (share LUTs?) Can't be used for CorrCond anyway since now directional information
1534                 break;
1535               case gtHTM:
1536                 type = l1t::EtSum::EtSumType::kMissingHt;
1537                 lutObj2 = "HTM";
1538                 break;
1539               case gtHTT:
1540                 type = l1t::EtSum::EtSumType::kTotalHt;
1541                 lutObj2 = "HTT";
1542                 break;
1543               case gtETMHF:
1544                 type = l1t::EtSum::EtSumType::kMissingEtHF;
1545                 lutObj2 = "ETMHF";
1546                 break;
1547               case gtMinBiasHFP0:
1548               case gtMinBiasHFM0:
1549               case gtMinBiasHFP1:
1550               case gtMinBiasHFM1:
1551                 type = l1t::EtSum::EtSumType::kMinBiasHFP0;
1552                 lutObj2 =
1553                     "MinBias";  //??Fix?? Not a valid LUT type Can't be used for CorrCond anyway since now directional information
1554                 break;
1555               default:
1556                 edm::LogError("L1TGlobal")
1557                     << "\n  Error: "
1558                     << "Unmatched object type from template to EtSumType, cndObjTypeVec[2] = " << cndObjTypeVec[2]
1559                     << std::endl;
1560                 type = l1t::EtSum::EtSumType::kTotalEt;
1561                 break;
1562             }
1563 
1564             candEtSumVec = m_uGtB->getCandL1EtSum();
1565 
1566             for (int iEtSum = 0; iEtSum < (int)candEtSumVec->size(cond2bx); iEtSum++) {
1567               if ((candEtSumVec->at(cond2bx, iEtSum))->getType() == type) {
1568                 phiIndex2 = (candEtSumVec->at(cond2bx, iEtSum))->hwPhi();
1569                 etaIndex2 = (candEtSumVec->at(cond2bx, iEtSum))->hwEta();
1570 
1571                 //  Get the floating point numbers
1572                 if (cndObjTypeVec[2] == gtETM) {
1573                   std::pair<double, double> binEdges = m_gtScales->getETMScales().phiBins.at(phiIndex2);
1574                   phi2Phy = 0.5 * (binEdges.second + binEdges.first);
1575                   eta2Phy = 0.;  //No Eta for Energy Sums
1576 
1577                 } else if (cndObjTypeVec[2] == gtHTM) {
1578                   std::pair<double, double> binEdges = m_gtScales->getHTMScales().phiBins.at(phiIndex2);
1579                   phi2Phy = 0.5 * (binEdges.second + binEdges.first);
1580                   eta2Phy = 0.;  //No Eta for Energy Sums
1581 
1582                 } else if (cndObjTypeVec[2] == gtETMHF) {
1583                   std::pair<double, double> binEdges = m_gtScales->getETMHFScales().phiBins.at(phiIndex2);
1584                   phi2Phy = 0.5 * (binEdges.second + binEdges.first);
1585                   eta2Phy = 0.;  //No Eta for Energy Sums
1586                 }
1587 
1588                 //If needed convert calo scales to muon scales for comparison (only phi for energy sums)
1589                 if (convertCaloScales) {
1590                   std::string lutName = lutObj2;
1591                   lutName += "-MU";
1592                   long long tst = m_gtScales->getLUT_CalMuPhi(lutName, phiIndex2);
1593                   LogDebug("L1TGlobal") << lutName << "  PhiCal = " << phiIndex2 << " PhiMu = " << tst << std::endl;
1594                   phiIndex2 = tst;
1595                 }
1596 
1597               }  //check it is the EtSum we want
1598             }  // loop over Etsums
1599 
1600           }  // end case CondEnerySum
1601           break;
1602           default: {
1603             // should not arrive here, there are no correlation conditions defined for this object
1604             LogDebug("L1TGlobal") << "Error could not find the Cond Category for Leg 3" << std::endl;
1605             return false;
1606           } break;
1607         }  //end switch on overlap-removal leg type
1608 
1609         // /////////////////////////////////////////////////////////////////////////////////////////
1610         //
1611         // here check if there is a match of 1st leg with overlap removal object, and store result
1612         //
1613         // /////////////////////////////////////////////////////////////////////////////////////////
1614         // These all require some delta eta and phi calculations.  Do them first...for now real calculation but need to
1615         // revise this to line up with firmware calculations.
1616         deltaPhiPhy = fabs(phi2Phy - phi0Phy);
1617         if (deltaPhiPhy > M_PI)
1618           deltaPhiPhy = 2. * M_PI - deltaPhiPhy;
1619         deltaEtaPhy = fabs(eta2Phy - eta0Phy);
1620 
1621         // Deter the integer based delta eta and delta phi
1622         deltaPhiFW = abs(phiORIndex0 - phiIndex2);
1623         if (deltaPhiFW >= phiBound)
1624           deltaPhiFW = 2 * phiBound - deltaPhiFW;
1625         lutName = lutObj0;
1626         lutName += "-";
1627         lutName += lutObj2;
1628         deltaPhiLUT = m_gtScales->getLUT_DeltaPhi(lutName, deltaPhiFW);
1629         precDeltaPhiLUT = m_gtScales->getPrec_DeltaPhi(lutName);
1630 
1631         deltaEtaFW = abs(etaORIndex0 - etaIndex2);
1632         deltaEtaLUT = 0;
1633         precDeltaEtaLUT = 0;
1634         if (!etSumCond) {
1635           deltaEtaLUT = m_gtScales->getLUT_DeltaEta(lutName, deltaEtaFW);
1636           precDeltaEtaLUT = m_gtScales->getPrec_DeltaEta(lutName);
1637         }
1638 
1639         LogDebug("L1TGlobal") << "Obj0 phiFW = " << phiORIndex0 << " Obj2 phiFW = " << phiIndex2 << "\n"
1640                               << "    DeltaPhiFW = " << deltaPhiFW << "\n"
1641                               << "    LUT Name = " << lutName << " Prec = " << precDeltaPhiLUT
1642                               << "  DeltaPhiLUT = " << deltaPhiLUT << "\n"
1643                               << "Obj0 etaFW = " << etaIndex0 << " Obj2 etaFW = " << etaIndex2 << "\n"
1644                               << "    DeltaEtaFW = " << deltaEtaFW << "\n"
1645                               << "    LUT Name = " << lutName << " Prec = " << precDeltaEtaLUT
1646                               << "  DeltaEtaLUT = " << deltaEtaLUT << std::endl;
1647 
1648         // If there is a OverlapRemovalDeltaEta cut, check it.
1649         if (corrPar.corrCutType & 0x10) {
1650           unsigned int preShift = precDeltaEtaLUT - corrPar.precOverlapRemovalEtaCut;
1651           LogDebug("L1TGlobal") << "    Testing Leg1 Overlap Removal Delta Eta Cut (" << lutObj0 << "," << lutObj2
1652                                 << ") [" << (long long)(corrPar.minOverlapRemovalEtaCutValue * pow(10, preShift)) << ","
1653                                 << (long long)(corrPar.maxOverlapRemovalEtaCutValue * pow(10, preShift))
1654                                 << "] with precision = " << corrPar.precOverlapRemovalEtaCut << "\n"
1655                                 << "    deltaEtaLUT = " << deltaEtaLUT << "\n"
1656                                 << "    Precision Shift = " << preShift << "\n"
1657                                 << "    deltaEta (shift)= "
1658                                 << (deltaEtaLUT / pow(10, preShift + corrPar.precOverlapRemovalEtaCut)) << "\n"
1659                                 << "    deltaEtaPhy = " << deltaEtaPhy << std::endl;
1660 
1661           //if(preShift>0) deltaEtaLUT /= pow(10,preShift);
1662           if (deltaEtaLUT >= (long long)(corrPar.minOverlapRemovalEtaCutValue * pow(10, preShift)) &&
1663               deltaEtaLUT <= (long long)(corrPar.maxOverlapRemovalEtaCutValue * pow(10, preShift))) {
1664             LogDebug("L1TGlobal") << "    Satified Leg1 Overlap Removal Delta Eta Cut ["
1665                                   << (long long)(corrPar.minOverlapRemovalEtaCutValue * pow(10, preShift)) << ","
1666                                   << (long long)(corrPar.maxOverlapRemovalEtaCutValue * pow(10, preShift)) << "]"
1667                                   << std::endl;
1668             // next leg3 object
1669             continue;
1670 
1671           } else {
1672             LogDebug("L1TGlobal") << "    Failed Leg1 Overlap Removal Delta Eta Cut ["
1673                                   << (long long)(corrPar.minOverlapRemovalEtaCutValue * pow(10, preShift)) << ","
1674                                   << (long long)(corrPar.maxOverlapRemovalEtaCutValue * pow(10, preShift)) << "]"
1675                                   << std::endl;
1676           }
1677         }
1678 
1679         //if there is a OverlapRemovalDeltaPhi cut, check it.
1680         if (corrPar.corrCutType & 0x20) {
1681           unsigned int preShift = precDeltaPhiLUT - corrPar.precOverlapRemovalPhiCut;
1682           LogDebug("L1TGlobal") << "    Testing Leg1 Overlap Removal Delta Phi Cut (" << lutObj0 << "," << lutObj2
1683                                 << ") [" << (long long)(corrPar.minOverlapRemovalPhiCutValue * pow(10, preShift)) << ","
1684                                 << (long long)(corrPar.maxOverlapRemovalPhiCutValue * pow(10, preShift))
1685                                 << "] with precision = " << corrPar.precOverlapRemovalPhiCut << "\n"
1686                                 << "    deltaPhiLUT = " << deltaPhiLUT << "\n"
1687                                 << "    Precision Shift = " << preShift << "\n"
1688                                 << "    deltaPhi (shift)= "
1689                                 << (deltaPhiLUT / pow(10, preShift + corrPar.precOverlapRemovalPhiCut)) << "\n"
1690                                 << "    deltaPhiPhy = " << deltaPhiPhy << std::endl;
1691 
1692           //if(preShift>0) deltaPhiLUT /= pow(10,preShift);
1693           if (deltaPhiLUT >= (long long)(corrPar.minOverlapRemovalPhiCutValue * pow(10, preShift)) &&
1694               deltaPhiLUT <= (long long)(corrPar.maxOverlapRemovalPhiCutValue * pow(10, preShift))) {
1695             LogDebug("L1TGlobal") << "    Satisfied Leg1 Overlap Removal Delta Phi Cut ["
1696                                   << (long long)(corrPar.minOverlapRemovalPhiCutValue * pow(10, preShift)) << ","
1697                                   << (long long)(corrPar.maxOverlapRemovalPhiCutValue * pow(10, preShift)) << "]"
1698                                   << std::endl;
1699             // next leg3 object
1700             continue;
1701 
1702           } else {
1703             LogDebug("L1TGlobal") << "    Failed Leg1 Overlap Removal Delta Phi Cut ["
1704                                   << (long long)(corrPar.minOverlapRemovalPhiCutValue * pow(10, preShift)) << ","
1705                                   << (long long)(corrPar.maxOverlapRemovalPhiCutValue * pow(10, preShift)) << "]"
1706                                   << std::endl;
1707           }
1708         }
1709 
1710         //if there is a OverlapRemovalDeltaR cut, check it.
1711         if (corrPar.corrCutType & 0x40) {
1712           //Assumes Delta Eta and Delta Phi LUTs have the same precision
1713           unsigned int preShift = 2 * precDeltaPhiLUT - corrPar.precOverlapRemovalDRCut;
1714           double deltaRSqPhy = deltaPhiPhy * deltaPhiPhy + deltaEtaPhy * deltaEtaPhy;
1715           long long deltaRSq = deltaEtaLUT * deltaEtaLUT + deltaPhiLUT * deltaPhiLUT;
1716 
1717           LogDebug("L1TGlobal") << "    Testing Leg1 Overlap Removal Delta R Cut (" << lutObj0 << "," << lutObj2
1718                                 << ") [" << (long long)(corrPar.minOverlapRemovalDRCutValue * pow(10, preShift)) << ","
1719                                 << (long long)(corrPar.maxOverlapRemovalDRCutValue * pow(10, preShift))
1720                                 << "] with precision = " << corrPar.precOverlapRemovalDRCut << "\n"
1721                                 << "    deltaPhiLUT = " << deltaPhiLUT << "\n"
1722                                 << "    deltaEtaLUT = " << deltaEtaLUT << "\n"
1723                                 << "    deltaRSqLUT = " << deltaRSq << "\n"
1724                                 << "    Precision Shift = " << preShift << "\n"
1725                                 << "    deltaRSqLUT (shift)= " << (deltaRSq / pow(10, preShift + corrPar.precDRCut))
1726                                 << "\n"
1727                                 << "    deltaRSqPhy = " << deltaRSqPhy << std::endl;
1728 
1729           //if(preShift>0) deltaRSq /= pow(10,preShift);
1730           if (deltaRSq >= (long long)(corrPar.minOverlapRemovalDRCutValue * pow(10, preShift)) &&
1731               deltaRSq <= (long long)(corrPar.maxOverlapRemovalDRCutValue * pow(10, preShift))) {
1732             LogDebug("L1TGlobal") << "    Satified Leg1 Overlap Removal Delta R Cut ["
1733                                   << (long long)(corrPar.minOverlapRemovalDRCutValue * pow(10, preShift)) << ","
1734                                   << (long long)(corrPar.maxOverlapRemovalDRCutValue * pow(10, preShift)) << "]"
1735                                   << std::endl;
1736             // next leg3 object
1737             continue;
1738 
1739           } else {
1740             LogDebug("L1TGlobal") << "    Failed Leg1 Overlap Removal Delta R Cut ["
1741                                   << (int)(corrPar.minOverlapRemovalDRCutValue * pow(10, preShift)) << ","
1742                                   << (long long)(corrPar.maxOverlapRemovalDRCutValue * pow(10, preShift)) << "]"
1743                                   << std::endl;
1744           }
1745         }
1746 
1747         // /////////////////////////////////////////////////////////////////////////////////////////
1748         //
1749         // here check if there is a match of 2st leg with overlap removal object ...if yes, continue
1750         //
1751         // /////////////////////////////////////////////////////////////////////////////////////////
1752         // These all require some delta eta and phi calculations.  Do them first...for now real calculation but need to
1753         // revise this to line up with firmware calculations.
1754         deltaPhiPhy = fabs(phi2Phy - phi1Phy);
1755         if (deltaPhiPhy > M_PI)
1756           deltaPhiPhy = 2. * M_PI - deltaPhiPhy;
1757         deltaEtaPhy = fabs(eta2Phy - eta1Phy);
1758 
1759         // Deter the integer based delta eta and delta phi
1760         deltaPhiFW = abs(phiORIndex1 - phiIndex2);
1761         if (deltaPhiFW >= phiBound)
1762           deltaPhiFW = 2 * phiBound - deltaPhiFW;
1763         lutName = lutObj1;
1764         lutName += "-";
1765         lutName += lutObj2;
1766         deltaPhiLUT = m_gtScales->getLUT_DeltaPhi(lutName, deltaPhiFW);
1767         precDeltaPhiLUT = m_gtScales->getPrec_DeltaPhi(lutName);
1768 
1769         deltaEtaFW = abs(etaORIndex1 - etaIndex2);
1770         deltaEtaLUT = 0;
1771         precDeltaEtaLUT = 0;
1772         if (!etSumCond) {
1773           deltaEtaLUT = m_gtScales->getLUT_DeltaEta(lutName, deltaEtaFW);
1774           precDeltaEtaLUT = m_gtScales->getPrec_DeltaEta(lutName);
1775         }
1776 
1777         LogDebug("L1TGlobal") << "Obj1 phiFW = " << phiORIndex1 << " Obj2 phiFW = " << phiIndex2 << "\n"
1778                               << "    DeltaPhiFW = " << deltaPhiFW << "\n"
1779                               << "    LUT Name = " << lutName << " Prec = " << precDeltaPhiLUT
1780                               << "  DeltaPhiLUT = " << deltaPhiLUT << "\n"
1781                               << "Obj1 etaFW = " << etaIndex1 << " Obj1 etaFW = " << etaIndex1 << "\n"
1782                               << "    DeltaEtaFW = " << deltaEtaFW << "\n"
1783                               << "    LUT Name = " << lutName << " Prec = " << precDeltaEtaLUT
1784                               << "  DeltaEtaLUT = " << deltaEtaLUT << std::endl;
1785 
1786         // If there is a OverlapRemovalDeltaEta cut, check it.
1787         // /////////////////////////////////////////////////
1788         if (corrPar.corrCutType & 0x10) {
1789           unsigned int preShift = precDeltaEtaLUT - corrPar.precOverlapRemovalEtaCut;
1790           LogDebug("L1TGlobal") << "    Testing Leg2 Overlap Removal Delta Eta Cut (" << lutObj1 << "," << lutObj2
1791                                 << ") [" << (long long)(corrPar.minOverlapRemovalEtaCutValue * pow(10, preShift)) << ","
1792                                 << (long long)(corrPar.maxOverlapRemovalEtaCutValue * pow(10, preShift))
1793                                 << "] with precision = " << corrPar.precOverlapRemovalEtaCut << "\n"
1794                                 << "    deltaEtaLUT = " << deltaEtaLUT << "\n"
1795                                 << "    Precision Shift = " << preShift << "\n"
1796                                 << "    deltaEta (shift)= "
1797                                 << (deltaEtaLUT / pow(10, preShift + corrPar.precOverlapRemovalEtaCut)) << "\n"
1798                                 << "    deltaEtaPhy = " << deltaEtaPhy << std::endl;
1799 
1800           //if(preShift>0) deltaEtaLUT /= pow(10,preShift);
1801           if (deltaEtaLUT >= (long long)(corrPar.minOverlapRemovalEtaCutValue * pow(10, preShift)) &&
1802               deltaEtaLUT <= (long long)(corrPar.maxOverlapRemovalEtaCutValue * pow(10, preShift))) {
1803             LogDebug("L1TGlobal") << "    Satisfied Leg2 Overlap Removal Delta Eta Cut ["
1804                                   << (long long)(corrPar.minOverlapRemovalEtaCutValue * pow(10, preShift)) << ","
1805                                   << (long long)(corrPar.maxOverlapRemovalEtaCutValue * pow(10, preShift)) << "]"
1806                                   << std::endl;
1807             // next leg3 object
1808             continue;
1809 
1810           } else {
1811             LogDebug("L1TGlobal") << "    Failed Leg2 Overlap Removal Delta Eta Cut ["
1812                                   << (long long)(corrPar.minOverlapRemovalEtaCutValue * pow(10, preShift)) << ","
1813                                   << (long long)(corrPar.maxOverlapRemovalEtaCutValue * pow(10, preShift)) << "]"
1814                                   << std::endl;
1815           }
1816         }
1817         // If there is a OverlapRemovalDeltaPhi cut, check it.
1818         // /////////////////////////////////////////////////
1819         if (corrPar.corrCutType & 0x20) {
1820           unsigned int preShift = precDeltaPhiLUT - corrPar.precOverlapRemovalPhiCut;
1821           LogDebug("L1TGlobal") << "    Testing Delta Phi Cut (" << lutObj1 << "," << lutObj2 << ") ["
1822                                 << (long long)(corrPar.minOverlapRemovalPhiCutValue * pow(10, preShift)) << ","
1823                                 << (long long)(corrPar.maxOverlapRemovalPhiCutValue * pow(10, preShift))
1824                                 << "] with precision = " << corrPar.precOverlapRemovalPhiCut << "\n"
1825                                 << "    deltaPhiLUT = " << deltaPhiLUT << "\n"
1826                                 << "    Precision Shift = " << preShift << "\n"
1827                                 << "    deltaPhi (shift)= "
1828                                 << (deltaPhiLUT / pow(10, preShift + corrPar.precOverlapRemovalPhiCut)) << "\n"
1829                                 << "    deltaPhiPhy = " << deltaPhiPhy << std::endl;
1830 
1831           //if(preShift>0) deltaPhiLUT /= pow(10,preShift);
1832           if (deltaPhiLUT >= (long long)(corrPar.minOverlapRemovalPhiCutValue * pow(10, preShift)) &&
1833               deltaPhiLUT <= (long long)(corrPar.maxOverlapRemovalPhiCutValue * pow(10, preShift))) {
1834             LogDebug("L1TGlobal") << "    Satisfied Leg2 Overlap Removal Delta Phi Cut ["
1835                                   << (long long)(corrPar.minOverlapRemovalPhiCutValue * pow(10, preShift)) << ","
1836                                   << (long long)(corrPar.maxOverlapRemovalPhiCutValue * pow(10, preShift)) << "]"
1837                                   << std::endl;
1838             // next leg3 object
1839             continue;
1840 
1841           } else {
1842             LogDebug("L1TGlobal") << "    Failed Leg2 Overlap Removal Delta Phi Cut ["
1843                                   << (long long)(corrPar.minOverlapRemovalPhiCutValue * pow(10, preShift)) << ","
1844                                   << (long long)(corrPar.maxOverlapRemovalPhiCutValue * pow(10, preShift)) << "]"
1845                                   << std::endl;
1846           }
1847         }
1848 
1849         //if there is a OverlapRemovalDeltaR cut, check it.
1850         // /////////////////////////////////////////////////
1851         if (corrPar.corrCutType & 0x40) {
1852           //Assumes Delta Eta and Delta Phi LUTs have the same precision
1853           unsigned int preShift = 2 * precDeltaPhiLUT - corrPar.precOverlapRemovalDRCut;
1854           double deltaRSqPhy = deltaPhiPhy * deltaPhiPhy + deltaEtaPhy * deltaEtaPhy;
1855           long long deltaRSq = deltaEtaLUT * deltaEtaLUT + deltaPhiLUT * deltaPhiLUT;
1856 
1857           LogDebug("L1TGlobal") << "    Testing Leg2 Overlap Removal Delta R Cut (" << lutObj1 << "," << lutObj2
1858                                 << ") [" << (long long)(corrPar.minOverlapRemovalDRCutValue * pow(10, preShift)) << ","
1859                                 << (long long)(corrPar.maxOverlapRemovalDRCutValue * pow(10, preShift))
1860                                 << "] with precision = " << corrPar.precOverlapRemovalDRCut << "\n"
1861                                 << "    deltaPhiLUT = " << deltaPhiLUT << "\n"
1862                                 << "    deltaEtaLUT = " << deltaEtaLUT << "\n"
1863                                 << "    deltaRSqLUT = " << deltaRSq << "\n"
1864                                 << "    Precision Shift = " << preShift << "\n"
1865                                 << "    deltaRSqLUT (shift)= " << (deltaRSq / pow(10, preShift + corrPar.precDRCut))
1866                                 << "\n"
1867                                 << "    deltaRSqPhy = " << deltaRSqPhy << std::endl;
1868 
1869           //if(preShift>0) deltaRSq /= pow(10,preShift);
1870           if (deltaRSq >= (long long)(corrPar.minOverlapRemovalDRCutValue * pow(10, preShift)) &&
1871               deltaRSq <= (long long)(corrPar.maxOverlapRemovalDRCutValue * pow(10, preShift))) {
1872             LogDebug("L1TGlobal") << "    Satisfied Leg2 Overlap Removal Delta R Cut ["
1873                                   << (long long)(corrPar.minOverlapRemovalDRCutValue * pow(10, preShift)) << ","
1874                                   << (long long)(corrPar.maxOverlapRemovalDRCutValue * pow(10, preShift)) << "]"
1875                                   << std::endl;
1876             // next leg3 object
1877             continue;
1878 
1879           } else {
1880             LogDebug("L1TGlobal") << "    Failed Leg2 Overlap Removal Delta R Cut ["
1881                                   << (int)(corrPar.minOverlapRemovalDRCutValue * pow(10, preShift)) << ","
1882                                   << (long long)(corrPar.maxOverlapRemovalDRCutValue * pow(10, preShift)) << "]"
1883                                   << std::endl;
1884           }
1885         }
1886 
1887         condResult = true;
1888 
1889         // clear the indices in the combination
1890         objectsInComb.clear();
1891         objectsInComb.emplace_back(cond0bx, obj0Index);
1892         objectsInComb.emplace_back(cond1bx, obj1Index);
1893         objectsInComb.emplace_back(cond2bx, obj2Index);
1894 
1895         (combinationsInCond()).push_back(objectsInComb);
1896 
1897       }  // end loop over combinations in overlap-removal leg.
1898 
1899     }  //end loop over second leg
1900 
1901   }  //end loop over first leg
1902 
1903   if (m_verbosity && condResult) {
1904     LogDebug("L1TGlobal") << " pass(es) the correlation condition.\n" << std::endl;
1905   }
1906 
1907   return condResult;
1908 }
1909 
1910 // load calo candidates
1911 const l1t::L1Candidate* l1t::CorrWithOverlapRemovalCondition::getCandidate(const int bx, const int indexCand) const {
1912   // objectType() gives the type for nrObjects() only,
1913   // but in a CondCalo all objects have the same type
1914   // take type from the type of the first object
1915   switch ((m_gtCorrelationWithOverlapRemovalTemplate->objectType())[0]) {
1916     case gtEG:
1917       return (m_uGtB->getCandL1EG())->at(bx, indexCand);
1918       break;
1919 
1920     case gtJet:
1921       return (m_uGtB->getCandL1Jet())->at(bx, indexCand);
1922       break;
1923 
1924     case gtTau:
1925       return (m_uGtB->getCandL1Tau())->at(bx, indexCand);
1926       break;
1927     default:
1928       return nullptr;
1929       break;
1930   }
1931 
1932   return nullptr;
1933 }
1934 
1935 /**
1936  * checkObjectParameter - Compare a single particle with a numbered condition.
1937  *
1938  * @param iCondition The number of the condition.
1939  * @param cand The candidate to compare.
1940  *
1941  * @return The result of the comparison (false if a condition does not exist).
1942  */
1943 
1944 const bool l1t::CorrWithOverlapRemovalCondition::checkObjectParameter(const int iCondition,
1945                                                                       const l1t::L1Candidate& cand) const {
1946   return true;
1947 }
1948 
1949 void l1t::CorrWithOverlapRemovalCondition::print(std::ostream& myCout) const {
1950   myCout << "Dummy Print for CorrWithOverlapRemovalCondition" << std::endl;
1951   m_gtCorrelationWithOverlapRemovalTemplate->print(myCout);
1952 
1953   ConditionEvaluation::print(myCout);
1954 }