CMS 3D CMS Logo

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