Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-03-25 10:58:18

0001 #ifndef L1Trigger_L1TGlobal_ConditionEvaluation_h
0002 #define L1Trigger_L1TGlobal_ConditionEvaluation_h
0003 
0004 /**
0005  * \class ConditionEvaluation
0006  *
0007  *
0008  * Description: Base class for evaluation of the L1 Global Trigger object templates.
0009  *
0010  * Implementation:
0011  *    <TODO: enter implementation details>
0012  *
0013  * \author: Vasile Mihai Ghete   - HEPHY Vienna
0014  *          Vladimir Rekovic - extend for indexing
0015  *
0016  *
0017  */
0018 
0019 // system include files
0020 #include <iostream>
0021 
0022 #include <string>
0023 #include <vector>
0024 
0025 // user include files
0026 
0027 //   base class
0028 
0029 //
0030 #include "DataFormats/L1TGlobal/interface/GlobalObjectMapFwd.h"
0031 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0032 #include <cstdint>
0033 
0034 // forward declarations
0035 
0036 namespace l1t {
0037 
0038   // class interface
0039   class ConditionEvaluation {
0040   public:
0041     /// constructor
0042     ConditionEvaluation() : m_condMaxNumberObjects(0), m_condLastResult(false), m_verbosity(0) {}
0043 
0044     /// destructor
0045     virtual ~ConditionEvaluation() {}
0046 
0047   public:
0048     /// get / set the maximum number of objects received for the
0049     /// evaluation of the condition
0050     inline int condMaxNumberObjects() const { return m_condMaxNumberObjects; }
0051 
0052     inline void setCondMaxNumberObjects(int condMaxNumberObjectsValue) {
0053       m_condMaxNumberObjects = condMaxNumberObjectsValue;
0054     }
0055 
0056     /// get the latest result for the condition
0057     inline bool condLastResult() const { return m_condLastResult; }
0058 
0059     /// call evaluateCondition and save last result
0060     inline void evaluateConditionStoreResult(const int bxEval) { m_condLastResult = evaluateCondition(bxEval); }
0061 
0062     /// the core function to check if the condition matches
0063     virtual const bool evaluateCondition(const int bxEval) const = 0;
0064 
0065     /// get numeric expression
0066     virtual std::string getNumericExpression() const {
0067       if (m_condLastResult) {
0068         return "1";
0069       } else {
0070         return "0";
0071       }
0072     }
0073 
0074     /// get all the object combinations evaluated to true in the condition
0075     inline CombinationsInCond const& getCombinationsInCond() const { return m_combinationsInCond; }
0076 
0077     /// print condition
0078     virtual void print(std::ostream& myCout) const;
0079 
0080     inline void setVerbosity(const int verbosity) { m_verbosity = verbosity; }
0081 
0082   protected:
0083     /// get all the object combinations (to fill it...)
0084     inline CombinationsInCond& combinationsInCond() const { return m_combinationsInCond; }
0085 
0086     /// check if a value is greater than a threshold or
0087     /// greater-or-equal depending on the value of the condGEqValue flag
0088     template <class Type1, class Type2>
0089     const bool checkThreshold(const Type1& thresholdL,
0090                               const Type1& thresholdH,
0091                               const Type2& value,
0092                               bool condGEqValue) const;
0093 
0094     /// check if a value is greater than a threshold or
0095     /// greater-or-equal depending on the value of the condGEqValue flag
0096     /// Added by Rick Cavanaugh for Displaced Muons:
0097     ///       Above checkThreshold fails when value overflows or threshold window is invalid
0098     ///       Below checkUnconstrainedPt allows value to overflow and only evaluates cut if threshold window is valid
0099     template <class Type1, class Type2>
0100     const bool checkUnconstrainedPt(const Type1& thresholdL,
0101                                     const Type1& thresholdH,
0102                                     const Type2& value,
0103                                     bool condGEqValue) const;
0104 
0105     /// check if a index is in a given range
0106     template <class Type1>
0107     const bool checkIndex(const Type1& indexLo, const Type1& indexHi, const unsigned int index) const;
0108 
0109     /// check if a bit with a given number is set in a mask
0110     template <class Type1>
0111     const bool checkBit(const Type1& mask, const unsigned int bitNumber) const;
0112 
0113     /// check if a value is in a given range and outside of a veto range
0114     template <class Type1>
0115     const bool checkRangeEta(const unsigned int bitNumber,
0116                              const Type1& W1beginR,
0117                              const Type1& W1endR,
0118                              const Type1& W2beginR,
0119                              const Type1& W2endR,
0120                              const unsigned int nEtaBits) const;
0121 
0122     /// check if a value is in a given range and outside of a veto range
0123     template <class Type1>
0124     const bool checkRangePhi(const unsigned int bitNumber,
0125                              const Type1& W1beginR,
0126                              const Type1& W1endR,
0127                              const Type1& W2beginR,
0128                              const Type1& W2endR) const;
0129 
0130     /// check if a value is in a given range
0131     template <class Type1>
0132     const bool checkRangeDeltaEta(const unsigned int obj1Eta,
0133                                   const unsigned int obj2Eta,
0134                                   const Type1& lowerR,
0135                                   const Type1& upperR,
0136                                   const unsigned int nEtaBits) const;
0137 
0138     /// check if a value is in a given range
0139     template <class Type1>
0140     const bool checkRangeDeltaPhi(const unsigned int obj1Phi,
0141                                   const unsigned int obj2Phi,
0142                                   const Type1& lowerR,
0143                                   const Type1& upperR) const;
0144 
0145   protected:
0146     /// maximum number of objects received for the evaluation of the condition
0147     /// usually retrieved from event setup
0148     int m_condMaxNumberObjects;
0149 
0150     /// the last result of evaluateCondition()
0151     bool m_condLastResult;
0152 
0153     /// store all the object combinations evaluated to true in the condition
0154     mutable CombinationsInCond m_combinationsInCond;
0155 
0156     /// verbosity level
0157     int m_verbosity;
0158   };
0159 
0160   // define templated methods
0161 
0162   // check if a value is greater than a threshold or
0163   // greater-or-equal depending on the value of the condGEqValue flag
0164   template <class Type1, class Type2>
0165   const bool ConditionEvaluation::checkThreshold(const Type1& thresholdL,
0166                                                  const Type1& thresholdH,
0167                                                  const Type2& value,
0168                                                  const bool condGEqValue) const {
0169     if (value > 0) {
0170       LogTrace("L1GlobalTrigger") << "  checkThreshold check for condGEqValue = " << condGEqValue
0171                                   << "\n    hex: " << std::hex << "threshold = " << thresholdL << " - " << thresholdH
0172                                   << " value = " << value << "\n    dec: " << std::dec << "threshold = " << thresholdL
0173                                   << " - " << thresholdH << " value = " << value << std::endl;
0174     }
0175 
0176     if (condGEqValue) {
0177       if (value >= (Type2)thresholdL && (Type1)value < thresholdH) {
0178         //LogTrace("L1GlobalTrigger") << "    condGEqValue: value >= threshold"
0179         //    << std::endl;
0180 
0181         return true;
0182       }
0183 
0184       return false;
0185 
0186     } else {
0187       if (value == (Type2)thresholdL) {
0188         //LogTrace("L1GlobalTrigger") << "    condGEqValue: value = threshold"
0189         //    << std::endl;
0190 
0191         return true;
0192       }
0193 
0194       return false;
0195     }
0196   }
0197 
0198   // check if a value is greater than a threshold or
0199   // greater-or-equal depending on the value of the condGEqValue flag
0200   /// Added by Rick Cavanaugh for Displaced Muons:
0201   ///       Above checkThreshold fails when value overflows or threshold window is invalid
0202   ///       Below checkUnconstrainedPt allows value to overflow and only evaluates cut if threshold window is valid
0203   template <class Type1, class Type2>
0204   const bool ConditionEvaluation::checkUnconstrainedPt(const Type1& thresholdL,
0205                                                        const Type1& thresholdH,
0206                                                        const Type2& value,
0207                                                        const bool condGEqValue) const {
0208     if (value > 0) {
0209       LogTrace("L1GlobalTrigger") << "  checkUnconstrainedPt check for condGEqValue = " << condGEqValue
0210                                   << "\n    hex: " << std::hex << "threshold = " << thresholdL << " - " << thresholdH
0211                                   << " value = " << value << "\n    dec: " << std::dec << "threshold = " << thresholdL
0212                                   << " - " << thresholdH << " value = " << value << std::endl;
0213     }
0214     if (thresholdH > 0)  // Only evaluate cut if threshold window is valid
0215     {
0216       if (condGEqValue) {
0217         if (value >= (Type2)thresholdL && (Type1)value <= thresholdH) {
0218           return true;
0219         }
0220         return false;
0221       } else {
0222         if (value == (Type2)thresholdL) {
0223           return true;
0224         }
0225         return false;
0226       }
0227     } else  // If invalid threshold window, do not evaluate cut (ie. pass through)
0228       return true;
0229   }
0230 
0231   // check if a index in a given range
0232   template <class Type1>
0233   const bool ConditionEvaluation::checkIndex(const Type1& indexLo,
0234                                              const Type1& indexHi,
0235                                              const unsigned int index) const {
0236     LogDebug("l1t|Global") << "\n l1t::ConditionEvaluation"
0237                            << "\n\t indexLo = " << indexLo << "\n\t indexHi = " << indexHi << "\n\t index = " << index
0238                            << std::endl;
0239 
0240     // set condtion to false if indexLo > indexHi
0241     if (indexLo > indexHi) {
0242       return false;
0243     }
0244     if (index >= indexLo && index <= indexHi) {
0245       return true;
0246     }
0247 
0248     return false;
0249   }
0250 
0251   // check if a bit with a given number is set in a mask
0252   template <class Type1>
0253   const bool ConditionEvaluation::checkBit(const Type1& mask, const unsigned int bitNumber) const {
0254     uint64_t oneBit = 1ULL;
0255 
0256     if (bitNumber >= (sizeof(oneBit) * 8)) {
0257       if (m_verbosity) {
0258         LogTrace("L1GlobalTrigger") << "    checkBit "
0259                                     << "\n     Bit number = " << bitNumber << " larger than maximum allowed "
0260                                     << sizeof(oneBit) * 8 << std::endl;
0261       }
0262 
0263       return false;
0264     }
0265 
0266     oneBit <<= bitNumber;
0267 
0268     //LogTrace("L1GlobalTrigger") << "    checkBit " << "\n     mask address = " << &mask
0269     //    << std::dec << "\n     dec: " << "mask = " << mask << " oneBit = " << oneBit
0270     //    << " bitNumber = " << bitNumber << std::hex << "\n     hex: " << "mask = " << mask
0271     //    << " oneBit = " << oneBit << " bitNumber = " << bitNumber << std::dec
0272     //    << "\n     mask & oneBit result = " << bool ( mask & oneBit ) << std::endl;
0273 
0274     return (mask & oneBit);
0275   }
0276 
0277   /// check if a value is in a given range and outside of a veto range
0278   template <class Type1>
0279   const bool ConditionEvaluation::checkRangeEta(const unsigned int bitNumber,
0280                                                 const Type1& W1beginR,
0281                                                 const Type1& W1endR,
0282                                                 const Type1& W2beginR,
0283                                                 const Type1& W2endR,
0284                                                 const unsigned int nEtaBits) const {
0285     // set condtion to true if beginR==endR = default -1
0286     if (W1beginR == W1endR && W1beginR == (Type1)-1) {
0287       return true;
0288     }
0289 
0290     unsigned int W1diff1 = W1endR - W1beginR;
0291     unsigned int W1diff2 = bitNumber - W1beginR;
0292     unsigned int W1diff3 = W1endR - bitNumber;
0293 
0294     bool W1cond1 = ((W1diff1 >> nEtaBits) & 1) ? false : true;
0295     bool W1cond2 = ((W1diff2 >> nEtaBits) & 1) ? false : true;
0296     bool W1cond3 = ((W1diff3 >> nEtaBits) & 1) ? false : true;
0297 
0298     // check if value is in range
0299     // for begin <= end takes [begin, end]
0300     // for begin >= end takes [begin, end] over zero angle!
0301     bool passWindow1 = false;
0302     if (W1cond1 && (W1cond2 && W1cond3))
0303       passWindow1 = true;
0304     else if (!W1cond1 && (W1cond2 || W1cond3))
0305       passWindow1 = true;
0306     else {
0307       passWindow1 = false;
0308     }
0309 
0310     LogDebug("l1t|Global") << "\n l1t::ConditionEvaluation"
0311                            << "\n\t bitNumber = " << bitNumber << "\n\t W1beginR = " << W1beginR
0312                            << "\n\t W1endR   = " << W1endR << "\n\t W1diff1 = " << W1diff1
0313                            << "\n\t W1cond1 = " << W1cond1 << "\n\t W1diff2 = " << W1diff2
0314                            << "\n\t W1cond2 = " << W1cond2 << "\n\t W1diff3 = " << W1diff3
0315                            << "\n\t W1cond3 = " << W1cond3 << "\n\t passWindow1 = " << passWindow1 << std::endl;
0316 
0317     if (W2beginR == W2endR && W2beginR == (Type1)-1) {
0318       return passWindow1;
0319     }
0320 
0321     unsigned int W2diff1 = W2endR - W2beginR;
0322     unsigned int W2diff2 = bitNumber - W2beginR;
0323     unsigned int W2diff3 = W2endR - bitNumber;
0324 
0325     bool W2cond1 = ((W2diff1 >> nEtaBits) & 1) ? false : true;
0326     bool W2cond2 = ((W2diff2 >> nEtaBits) & 1) ? false : true;
0327     bool W2cond3 = ((W2diff3 >> nEtaBits) & 1) ? false : true;
0328 
0329     bool passWindow2 = false;
0330     if (W2cond1 && (W2cond2 && W2cond3))
0331       passWindow2 = true;
0332     else if (!W2cond1 && (W2cond2 || W2cond3))
0333       passWindow2 = true;
0334     else {
0335       passWindow2 = false;
0336     }
0337 
0338     LogDebug("l1t|Global") << "\n\t W2beginR = " << W2beginR << "\n\t W2endR   = " << W2endR
0339                            << "\n\t W2diff1 = " << W2diff1 << "\n\t W2cond1 = " << W2cond1
0340                            << "\n\t W2diff2 = " << W2diff2 << "\n\t W2cond2 = " << W2cond2
0341                            << "\n\t W2diff3 = " << W2diff3 << "\n\t W2cond3 = " << W2cond3
0342                            << "\n\t passWindow2 = " << passWindow2
0343                            << "\n\t pass W1 || W2 = " << (passWindow1 || passWindow2) << std::endl;
0344 
0345     if (passWindow1 || passWindow2) {
0346       return true;
0347     } else {
0348       return false;
0349     }
0350   }
0351 
0352   /// check if a value is in a given range and outside of a veto range
0353   template <class Type1>
0354   const bool ConditionEvaluation::checkRangePhi(const unsigned int bitNumber,
0355                                                 const Type1& W1beginR,
0356                                                 const Type1& W1endR,
0357                                                 const Type1& W2beginR,
0358                                                 const Type1& W2endR) const {
0359     // set condtion to true if beginR==endR = default -1
0360     if (W1beginR == W1endR && W1beginR == (Type1)-1) {
0361       return true;
0362     }
0363 
0364     int W1diff1 = W1endR - W1beginR;
0365     int W1diff2 = bitNumber - W1beginR;
0366     int W1diff3 = W1endR - bitNumber;
0367 
0368     bool W1cond1 = (W1diff1 < 0) ? false : true;
0369     bool W1cond2 = (W1diff2 < 0) ? false : true;
0370     bool W1cond3 = (W1diff3 < 0) ? false : true;
0371 
0372     // check if value is in range
0373     // for begin <= end takes [begin, end]
0374     // for begin >= end takes [begin, end] over zero angle!
0375     bool passWindow1 = false;
0376     if (W1cond1 && (W1cond2 && W1cond3))
0377       passWindow1 = true;
0378     else if (!W1cond1 && (W1cond2 || W1cond3))
0379       passWindow1 = true;
0380     else {
0381       passWindow1 = false;
0382     }
0383 
0384     LogDebug("l1t|Global") << "\n l1t::ConditionEvaluation"
0385                            << "\n\t bitNumber = " << bitNumber << "\n\t W1beginR = " << W1beginR
0386                            << "\n\t W1endR   = " << W1endR << "\n\t W1diff1 = " << W1diff1
0387                            << "\n\t W1cond1 = " << W1cond1 << "\n\t W1diff2 = " << W1diff2
0388                            << "\n\t W1cond2 = " << W1cond2 << "\n\t W1diff3 = " << W1diff3
0389                            << "\n\t W1cond3 = " << W1cond3 << std::endl;
0390 
0391     if (W2beginR == W2endR && W2beginR == (Type1)-1) {
0392       return passWindow1;
0393     }
0394 
0395     int W2diff1 = W2endR - W2beginR;
0396     int W2diff2 = bitNumber - W2beginR;
0397     int W2diff3 = W2endR - bitNumber;
0398 
0399     bool W2cond1 = (W2diff1 < 0) ? false : true;
0400     bool W2cond2 = (W2diff2 < 0) ? false : true;
0401     bool W2cond3 = (W2diff3 < 0) ? false : true;
0402 
0403     // check if value is in range
0404     // for begin <= end takes [begin, end]
0405     // for begin >= end takes [begin, end] over zero angle!
0406     bool passWindow2 = false;
0407     if (W2cond1 && (W2cond2 && W2cond3))
0408       passWindow2 = true;
0409     else if (!W2cond1 && (W2cond2 || W2cond3))
0410       passWindow2 = true;
0411     else {
0412       passWindow2 = false;
0413     }
0414 
0415     if (passWindow1 || passWindow2) {
0416       return true;
0417     } else {
0418       return false;
0419     }
0420   }
0421 
0422   template <class Type1>
0423   const bool ConditionEvaluation::checkRangeDeltaEta(const unsigned int obj1Eta,
0424                                                      const unsigned int obj2Eta,
0425                                                      const Type1& lowerR,
0426                                                      const Type1& upperR,
0427                                                      const unsigned int nEtaBits) const {
0428     /*   // set condtion to true if beginR==endR = default -1 */
0429     /*   if( beginR==endR && beginR==-1 ){ */
0430     /*     return true; */
0431     /*   } */
0432 
0433     unsigned int compare = obj1Eta - obj2Eta;
0434     bool cond = ((compare >> nEtaBits) & 1) ? false : true;
0435 
0436     unsigned int larger, smaller;
0437     if (cond) {
0438       larger = obj1Eta;
0439       smaller = obj2Eta;
0440     } else {
0441       larger = obj2Eta;
0442       smaller = obj1Eta;
0443     }
0444 
0445     unsigned int diff = ((larger + ((~smaller + 1) & 255)) & 255);
0446 
0447     unsigned int diff1 = upperR - lowerR;
0448     unsigned int diff2 = diff - lowerR;
0449     unsigned int diff3 = upperR - diff;
0450 
0451     bool cond1 = ((diff1 >> nEtaBits) & 1) ? false : true;
0452     bool cond2 = ((diff2 >> nEtaBits) & 1) ? false : true;
0453     bool cond3 = ((diff3 >> nEtaBits) & 1) ? false : true;
0454 
0455     LogDebug("l1t|Global") << "\n l1t::ConditionEvaluation"
0456                            << "\n\t obj1Eta = " << obj1Eta << "\n\t obj2Eta = " << obj2Eta << "\n\t lowerR = " << lowerR
0457                            << "\n\t upperR = " << upperR << "\n\t compare = " << compare << "\n\t cond = " << cond
0458                            << "\n\t diff = " << diff << "\n\t diff1 = " << diff1 << "\n\t cond1 = " << cond1
0459                            << "\n\t diff2 = " << diff2 << "\n\t cond2 = " << cond2 << "\n\t diff3 = " << diff3
0460                            << "\n\t cond3 = " << cond3 << std::endl;
0461 
0462     if (cond1 && (cond2 && cond3))
0463       return true;
0464     else if (!cond1 && (cond2 || cond3))
0465       return true;
0466     else {
0467       return false;
0468     }
0469   }
0470 
0471   template <class Type1>
0472   const bool ConditionEvaluation::checkRangeDeltaPhi(const unsigned int obj1Phi,
0473                                                      const unsigned int obj2Phi,
0474                                                      const Type1& lowerR,
0475                                                      const Type1& upperR) const {
0476     int deltaPhi = abs(int(obj1Phi) - int(obj2Phi));
0477     if (deltaPhi > 71)
0478       deltaPhi = 143 - deltaPhi + 1;  // Add +1 if the calculation is over 0
0479 
0480     int diff1 = upperR - lowerR;
0481     int diff2 = deltaPhi - lowerR;
0482     int diff3 = upperR - deltaPhi;
0483 
0484     bool cond1 = (diff1 < 0) ? false : true;
0485     bool cond2 = (diff2 < 0) ? false : true;
0486     bool cond3 = (diff3 < 0) ? false : true;
0487 
0488     LogDebug("l1t|Global") << "\n l1t::ConditionEvaluation"
0489                            << "\n\t obj1Phi = " << obj1Phi << "\n\t obj2Phi = " << obj2Phi
0490                            << "\n\t deltaPhi = " << deltaPhi << "\n\t lowerR = " << lowerR << "\n\t upperR = " << upperR
0491                            << "\n\t diff1 = " << diff1 << "\n\t cond1 = " << cond1 << "\n\t diff2 = " << diff2
0492                            << "\n\t cond2 = " << cond2 << "\n\t diff3 = " << diff3 << "\n\t cond3 = " << cond3
0493                            << std::endl;
0494 
0495     // check if value is in range
0496     // for begin <= end takes [begin, end]
0497     // for begin >= end takes [begin, end] over zero angle!
0498     if (cond1 && (cond2 && cond3))
0499       return true;
0500     else if (!cond1 && (cond2 || cond3))
0501       return true;
0502     else {
0503       return false;
0504     }
0505   }
0506 
0507 }  // namespace l1t
0508 #endif