CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/L1Trigger/GlobalTrigger/src/L1GtCaloCondition.cc

Go to the documentation of this file.
00001 
00017 // this class header
00018 #include "L1Trigger/GlobalTrigger/interface/L1GtCaloCondition.h"
00019 
00020 // system include files
00021 #include <iostream>
00022 #include <iomanip>
00023 
00024 #include <string>
00025 #include <vector>
00026 #include <algorithm>
00027 
00028 // user include files
00029 //   base classes
00030 #include "CondFormats/L1TObjects/interface/L1GtCaloTemplate.h"
00031 #include "L1Trigger/GlobalTrigger/interface/L1GtConditionEvaluation.h"
00032 
00033 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetupFwd.h"
00034 
00035 #include "DataFormats/L1GlobalCaloTrigger/interface/L1GctCand.h"
00036 #include "DataFormats/L1GlobalCaloTrigger/interface/L1GctEmCand.h"
00037 #include "DataFormats/L1GlobalCaloTrigger/interface/L1GctJetCand.h"
00038 
00039 #include "CondFormats/L1TObjects/interface/L1GtStableParameters.h"
00040 #include "CondFormats/DataRecord/interface/L1GtStableParametersRcd.h"
00041 
00042 #include "L1Trigger/GlobalTrigger/interface/L1GlobalTriggerFunctions.h"
00043 #include "L1Trigger/GlobalTrigger/interface/L1GlobalTriggerPSB.h"
00044 
00045 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00046 #include "FWCore/MessageLogger/interface/MessageDrop.h"
00047 
00048 // constructors
00049 //     default
00050 L1GtCaloCondition::L1GtCaloCondition() :
00051     L1GtConditionEvaluation() {
00052 
00053     m_ifCaloEtaNumberBits = -1;
00054 
00055 }
00056 
00057 //     from base template condition (from event setup usually)
00058 L1GtCaloCondition::L1GtCaloCondition(const L1GtCondition* caloTemplate, const L1GlobalTriggerPSB* ptrPSB,
00059         const int nrL1NoIsoEG,
00060         const int nrL1IsoEG,
00061         const int nrL1CenJet,
00062         const int nrL1ForJet,
00063         const int nrL1TauJet,
00064         const int ifCaloEtaNumberBits) :
00065     L1GtConditionEvaluation(),
00066     m_gtCaloTemplate(static_cast<const L1GtCaloTemplate*>(caloTemplate)),
00067     m_gtPSB(ptrPSB),
00068     m_ifCaloEtaNumberBits(ifCaloEtaNumberBits)
00069 {
00070 
00071     // maximum number of objects received for the evaluation of the condition
00072     // retrieved before from event setup
00073     // for a CondCalo, all objects ar of same type, hence it is enough to get the
00074     // type for the first object
00075 
00076     switch ((m_gtCaloTemplate->objectType())[0]) {
00077         case NoIsoEG:
00078             m_condMaxNumberObjects = nrL1NoIsoEG;
00079             break;
00080         case IsoEG:
00081             m_condMaxNumberObjects = nrL1IsoEG;
00082             break;
00083         case CenJet:
00084             m_condMaxNumberObjects = nrL1CenJet;
00085             break;
00086         case ForJet:
00087             m_condMaxNumberObjects = nrL1ForJet;
00088             break;
00089         case TauJet:
00090             m_condMaxNumberObjects = nrL1TauJet;
00091             break;
00092         default:
00093             m_condMaxNumberObjects = 0;
00094             break;
00095     }
00096 
00097 }
00098 
00099 // copy constructor
00100 void L1GtCaloCondition::copy(const L1GtCaloCondition &cp) {
00101 
00102     m_gtCaloTemplate = cp.gtCaloTemplate();
00103     m_gtPSB = cp.gtPSB();
00104 
00105     m_ifCaloEtaNumberBits = cp.gtIfCaloEtaNumberBits();
00106 
00107     m_condMaxNumberObjects = cp.condMaxNumberObjects();
00108     m_condLastResult = cp.condLastResult();
00109     m_combinationsInCond = cp.getCombinationsInCond();
00110 
00111     m_verbosity = cp.m_verbosity;
00112 
00113 }
00114 
00115 L1GtCaloCondition::L1GtCaloCondition(const L1GtCaloCondition& cp) :
00116     L1GtConditionEvaluation() {
00117 
00118     copy(cp);
00119 
00120 }
00121 
00122 // destructor
00123 L1GtCaloCondition::~L1GtCaloCondition() {
00124 
00125     // empty
00126 
00127 }
00128 
00129 // equal operator
00130 L1GtCaloCondition& L1GtCaloCondition::operator= (const L1GtCaloCondition& cp)
00131 {
00132     copy(cp);
00133     return *this;
00134 }
00135 
00136 // methods
00137 void L1GtCaloCondition::setGtCaloTemplate(const L1GtCaloTemplate* caloTempl) {
00138 
00139     m_gtCaloTemplate = caloTempl;
00140 
00141 }
00142 
00143 //   set the number of bits for eta of calorimeter objects
00144 void L1GtCaloCondition::setGtIfCaloEtaNumberBits(const int& ifCaloEtaNumberBitsValue) {
00145 
00146     m_ifCaloEtaNumberBits = ifCaloEtaNumberBitsValue;
00147 
00148 }
00149 
00151 void L1GtCaloCondition::setGtPSB(const L1GlobalTriggerPSB* ptrPSB) {
00152 
00153     m_gtPSB = ptrPSB;
00154 
00155 }
00156 
00157 // try all object permutations and check spatial correlations, if required
00158 const bool L1GtCaloCondition::evaluateCondition() const {
00159 
00160     // number of trigger objects in the condition
00161     int nObjInCond = m_gtCaloTemplate->nrObjects();
00162     //LogTrace("L1GtCaloCondition") << "  nObjInCond: " << nObjInCond
00163     //    << std::endl;
00164 
00165     // the candidates
00166 
00167     // objectType() gives the type for nrObjects() only,
00168     // but in a CondCalo all objects have the same type
00169     // take type from the type of the first object
00170 
00171     const std::vector<const L1GctCand*>* candVec;
00172 
00173     switch ((m_gtCaloTemplate->objectType())[0]) {
00174         case NoIsoEG:
00175             candVec = m_gtPSB->getCandL1NoIsoEG();
00176             break;
00177         case IsoEG:
00178             candVec = m_gtPSB->getCandL1IsoEG();
00179             break;
00180         case CenJet:
00181             candVec = m_gtPSB->getCandL1CenJet();
00182             break;
00183         case ForJet:
00184             candVec = m_gtPSB->getCandL1ForJet();
00185             break;
00186         case TauJet:
00187             candVec = m_gtPSB->getCandL1TauJet();
00188             break;
00189         default:
00190             return false;
00191             break;
00192     }
00193 
00194     int numberObjects = candVec->size();
00195     //LogTrace("L1GtCaloCondition") << "  numberObjects: " << numberObjects
00196     //    << std::endl;
00197     if (numberObjects < nObjInCond) {
00198         return false;
00199     }
00200 
00201     std::vector<int> index(numberObjects);
00202 
00203     for (int i = 0; i < numberObjects; ++i) {
00204         index[i] = i;
00205     }
00206 
00207     int jumpIndex = 1;
00208     int jump = factorial(numberObjects - nObjInCond);
00209 
00210     int totalLoops = 0;
00211     int passLoops = 0;
00212 
00213     // condition result condResult set to true if at least one permutation
00214     //     passes all requirements
00215     // all possible permutations are checked
00216     bool condResult = false;
00217 
00218     // store the indices of the calorimeter objects
00219     // from the combination evaluated in the condition
00220     SingleCombInCond objectsInComb;
00221     objectsInComb.reserve(nObjInCond);
00222 
00223     // clear the m_combinationsInCond vector
00224     (*m_combinationsInCond).clear();
00225 
00226     do {
00227 
00228         if (--jumpIndex)
00229             continue;
00230 
00231         jumpIndex = jump;
00232         totalLoops++;
00233 
00234         // clear the indices in the combination
00235         objectsInComb.clear();
00236 
00237         bool tmpResult = true;
00238 
00239         // check if there is a permutation that matches object-parameter requirements
00240         for (int i = 0; i < nObjInCond; i++) {
00241 
00242             tmpResult &= checkObjectParameter(i, *(*candVec)[index[i]]);
00243             objectsInComb.push_back(index[i]);
00244 
00245         }
00246 
00247         // if permutation does not match particle conditions
00248         // skip spatial correlations
00249         if (!tmpResult) {
00250 
00251             continue;
00252 
00253         }
00254 
00255         if (m_gtCaloTemplate->wsc()) {
00256 
00257             // wsc requirements have always nObjInCond = 2
00258             // one can use directly index[0] and index[1] to compute
00259             // eta and phi differences
00260             const int ObjInWscComb = 2;
00261             if (nObjInCond != ObjInWscComb) {
00262 
00263                 if (m_verbosity) {
00264                     edm::LogError("L1GtCaloCondition")
00265                         << "\n  Error: "
00266                         << "number of particles in condition with spatial correlation = "
00267                         << nObjInCond << "\n  it must be = " << ObjInWscComb
00268                         << std::endl;
00269                 }
00270 
00271                 continue;
00272             }
00273 
00274             L1GtCaloTemplate::CorrelationParameter corrPar =
00275                 *(m_gtCaloTemplate->correlationParameter());
00276 
00277             unsigned int candDeltaEta;
00278             unsigned int candDeltaPhi;
00279 
00280             // check candDeltaEta
00281 
00282             // get eta index and the sign bit of the eta index (MSB is the sign)
00283             //   signedEta[i] is the signed eta index of candVec[index[i]]
00284             int signedEta[ObjInWscComb];
00285             int signBit[ObjInWscComb] = { 0, 0 };
00286 
00287             int scaleEta = 1 << (m_ifCaloEtaNumberBits - 1);
00288 
00289             for (int i = 0; i < ObjInWscComb; ++i) {
00290                 signBit[i] = ((*candVec)[index[i]]->etaIndex() & scaleEta)
00291                     >>(m_ifCaloEtaNumberBits - 1);
00292                 signedEta[i] = ((*candVec)[index[i]]->etaIndex() )%scaleEta;
00293 
00294                 if (signBit[i] == 1) {
00295                     signedEta[i] = (-1)*signedEta[i];
00296                 }
00297 
00298             }
00299 
00300             // compute candDeltaEta - add 1 if signs are different (due to +0/-0 indices)
00301             candDeltaEta = static_cast<int> (std::abs(signedEta[1] - signedEta[0]))
00302                 + static_cast<int> (signBit[1]^signBit[0]);
00303 
00304             if ( !checkBit(corrPar.deltaEtaRange, candDeltaEta) ) {
00305                 continue;
00306             }
00307 
00308             // check candDeltaPhi
00309 
00310             // calculate absolute value of candDeltaPhi
00311             if ((*candVec)[index[0]]->phiIndex()> (*candVec)[index[1]]->phiIndex()) {
00312                 candDeltaPhi = (*candVec)[index[0]]->phiIndex() - (*candVec)[index[1]]->phiIndex();
00313             }
00314             else {
00315                 candDeltaPhi = (*candVec)[index[1]]->phiIndex() - (*candVec)[index[0]]->phiIndex();
00316             }
00317 
00318             // check if candDeltaPhi > 180 (via delta_phi_maxbits)
00319             // delta_phi contains bits for 0..180 (0 and 180 included)
00320             while (candDeltaPhi> corrPar.deltaPhiMaxbits) {
00321 
00322                 // candDeltaPhi > 180 ==> take 360 - candDeltaPhi
00323                 candDeltaPhi = (corrPar.deltaPhiMaxbits - 1)*2 - candDeltaPhi;
00324                 if (m_verbosity) {
00325                     LogTrace("L1GtCaloCondition")
00326                         << "  candDeltaPhi rescaled to: " << candDeltaPhi
00327                         << std::endl;
00328                 }
00329             }
00330 
00331             if (!checkBit(corrPar.deltaPhiRange, candDeltaPhi)) {
00332                 continue;
00333             }
00334 
00335         } // end wsc check
00336 
00337         // if we get here all checks were successfull for this combination
00338         // set the general result for evaluateCondition to "true"
00339 
00340         condResult = true;
00341         passLoops++;
00342         (*m_combinationsInCond).push_back(objectsInComb);
00343 
00344         //    } while ( std::next_permutation(index, index + nObj) );
00345     } while (std::next_permutation(index.begin(), index.end()) );
00346 
00347     //LogTrace("L1GtCaloCondition")
00348     //    << "\n  L1GtCaloCondition: total number of permutations found:          " << totalLoops
00349     //    << "\n  L1GtCaloCondition: number of permutations passing requirements: " << passLoops
00350     //    << "\n" << std::endl;
00351 
00352     return condResult;
00353 
00354 }
00355 
00356 // load calo candidates
00357 const L1GctCand* L1GtCaloCondition::getCandidate(const int indexCand) const {
00358 
00359     // objectType() gives the type for nrObjects() only,
00360     // but in a CondCalo all objects have the same type
00361     // take type from the type of the first object
00362     switch ((m_gtCaloTemplate->objectType())[0]) {
00363         case NoIsoEG:
00364             return (*(m_gtPSB->getCandL1NoIsoEG()))[indexCand];
00365             break;
00366         case IsoEG:
00367             return (*(m_gtPSB->getCandL1IsoEG()))[indexCand];
00368             break;
00369         case CenJet:
00370             return (*(m_gtPSB->getCandL1CenJet()))[indexCand];
00371             break;
00372         case ForJet:
00373             return (*(m_gtPSB->getCandL1ForJet()))[indexCand];
00374             break;
00375         case TauJet:
00376             return (*(m_gtPSB->getCandL1TauJet()))[indexCand];
00377             break;
00378         default:
00379             return 0;
00380             break;
00381     }
00382 
00383     return 0;
00384 }
00385 
00395 const bool L1GtCaloCondition::checkObjectParameter(const int iCondition, const L1GctCand& cand) const {
00396 
00397     // number of objects in condition
00398     int nObjInCond = m_gtCaloTemplate->nrObjects();
00399 
00400     if (iCondition >= nObjInCond || iCondition < 0) {
00401         return false;
00402     }
00403 
00404     // empty candidates can not be compared
00405     if (cand.empty()) {
00406         return false;
00407     }
00408 
00409     const L1GtCaloTemplate::ObjectParameter objPar = ( *(m_gtCaloTemplate->objectParameter()) )[iCondition];
00410 
00411     // check energy threshold
00412     if ( !checkThreshold(objPar.etThreshold, cand.rank(), m_gtCaloTemplate->condGEq()) ) {
00413         return false;
00414     }
00415 
00416     // check eta
00417     if (!checkBit(objPar.etaRange, cand.etaIndex())) {
00418         return false;
00419     }
00420 
00421     // check phi
00422 
00423     if (!checkBit(objPar.phiRange, cand.phiIndex())) {
00424         return false;
00425     }
00426 
00427     // particle matches if we get here
00428     //LogTrace("L1GtCaloCondition")
00429     //    << "  checkObjectParameter: calorimeter object OK, passes all requirements\n"
00430     //    << std::endl;
00431 
00432     return true;
00433 }
00434 
00435 void L1GtCaloCondition::print(std::ostream& myCout) const {
00436 
00437     m_gtCaloTemplate->print(myCout);
00438     L1GtConditionEvaluation::print(myCout);
00439 
00440 }
00441