Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 23:29:59

0001 #ifndef DQMOFFLINE_TRIGGER_EGHLTDQMCUT
0002 #define DQMOFFLINE_TRIGGER_EGHLTDQMCUT
0003 
0004 //class: EgHLTDQMCut
0005 //
0006 //author: Sam Harper (June 2008)
0007 //
0008 //WARNING: interface is NOT final, please dont use this class for now without clearing it with me
0009 //         as I will change it and possibly break all your code
0010 //
0011 //aim: to allow the user to place a cut on the electron using it or the event
0012 //
0013 //implimentation:
0014 
0015 #include "DQMOffline/Trigger/interface/EgHLTOffEvt.h"
0016 #include "DQMOffline/Trigger/interface/EgHLTTrigCodes.h"
0017 
0018 #include "DataFormats/Math/interface/deltaR.h"
0019 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0020 
0021 //this is a pure virtual struct which defines the interface to the cut objects
0022 //it is also currently uncopyable
0023 
0024 namespace egHLT {
0025 
0026   template <class T>
0027   struct EgHLTDQMCut {
0028   private:
0029     //disabling copy and assignment for all objects
0030     EgHLTDQMCut& operator=(const EgHLTDQMCut& rhs) { return *this; }
0031 
0032   protected:
0033     //only derived classes can call the copy constructor (needed for clone...)
0034     EgHLTDQMCut(const EgHLTDQMCut& rhs) = default;
0035 
0036   public:
0037     EgHLTDQMCut() = default;
0038     virtual ~EgHLTDQMCut() = default;
0039     virtual bool pass(const T& obj, const OffEvt& evt) const = 0;
0040     virtual EgHLTDQMCut<T>* clone() const = 0;  //caller owns the pointer
0041   };
0042 
0043   template <class T>
0044   struct EgHLTDQMVarCut : public EgHLTDQMCut<T> {
0045   private:
0046     int cutsToPass_;  //the cuts whose eff we are measuring
0047     int (T::*cutCodeFunc_)() const;
0048 
0049   public:
0050     EgHLTDQMVarCut(int cutsToPass, int (T::*cutCodeFunc)() const)
0051         : cutsToPass_(cutsToPass), cutCodeFunc_(cutCodeFunc) {}
0052     ~EgHLTDQMVarCut() override = default;
0053 
0054     bool pass(const T& obj, const OffEvt& evt) const override;
0055     EgHLTDQMCut<T>* clone() const override { return new EgHLTDQMVarCut(*this); }  //default copy constructor is fine
0056   };
0057 
0058   //to understand this you need to know about
0059   //1) templates
0060   //2) inheritance (sort of)
0061   //3) function pointers
0062   //4) bitwise operations
0063   //All it does is get the bitword corresponding to the cuts the electron failed and the mask the bits which correspond to cuts we dont care about and then see if any bits are still set
0064   template <class T>
0065   bool EgHLTDQMVarCut<T>::pass(const T& obj, const OffEvt& evt) const {
0066     if (((obj.*cutCodeFunc_)() & cutsToPass_) == 0)
0067       return true;
0068     else
0069       return false;
0070   }
0071 
0072   //now this is similar to EgHLTDQMVarCut except that it allows a key to specified to the cut code function
0073   template <class T, class Key>
0074   struct EgHLTDQMUserVarCut : public EgHLTDQMCut<T> {
0075   private:
0076     int (T::*cutCodeFunc_)(const Key&) const;
0077     const Key key_;
0078     int cutsNotToMask_;
0079 
0080   public:
0081     EgHLTDQMUserVarCut(int (T::*cutCodeFunc)(const Key&) const, const Key& key, int cutsNotToMask = ~0x0)
0082         : cutCodeFunc_(cutCodeFunc), key_(key), cutsNotToMask_(cutsNotToMask) {}
0083     ~EgHLTDQMUserVarCut() override = default;
0084 
0085     bool pass(const T& obj, const OffEvt& evt) const override;
0086     EgHLTDQMCut<T>* clone() const override { return new EgHLTDQMUserVarCut(*this); }  //default copy constructor is fine
0087   };
0088 
0089   template <class T, class Key>
0090   bool EgHLTDQMUserVarCut<T, Key>::pass(const T& obj, const OffEvt& evt) const {
0091     if (((obj.*cutCodeFunc_)(key_)&cutsNotToMask_) == 0)
0092       return true;
0093     else
0094       return false;
0095   }
0096 
0097   template <class T, typename varType>
0098   struct EgGreaterCut : public EgHLTDQMCut<T> {
0099   private:
0100     varType cutValue_;
0101     varType (T::*varFunc_)() const;
0102 
0103   public:
0104     EgGreaterCut(varType cutValue, varType (T::*varFunc)() const) : cutValue_(cutValue), varFunc_(varFunc) {}
0105 
0106     bool pass(const T& obj, const OffEvt& evt) const override { return (obj.*varFunc_)() > cutValue_; }
0107     EgHLTDQMCut<T>* clone() const override { return new EgGreaterCut(*this); }  //default copy constructor is fine
0108   };
0109 
0110   //this struct allows multiple cuts to be strung together
0111   //now I could quite simply have a link to the next cut defined in the base class
0112   //and the operator<< defined there also but I dont for the following reason
0113   //1) I'm concerned about a circular chain of cuts (hence why you cant do a EgMultiCut << EgMultiCut)
0114   //2) it requires all cuts to multi cut aware in the pass function
0115   //in the future I may change it so this class isnt required
0116   template <class T>
0117   struct EgMultiCut : public EgHLTDQMCut<T> {
0118   private:
0119     std::vector<const EgHLTDQMCut<T>*> cuts_;  //all the points to the cuts we own
0120 
0121   public:
0122     EgMultiCut() = default;
0123     EgMultiCut(const EgMultiCut<T>& rhs);
0124     ~EgMultiCut() override {
0125       for (size_t i = 0; i < cuts_.size(); i++)
0126         delete cuts_[i];
0127     }
0128 
0129     //we own any cut given to use this way
0130     EgMultiCut<T>& operator<<(const EgHLTDQMCut<T>* inputCut);
0131 
0132     //basically an AND of all the cuts using short circuit evaluation, starting with the first cut
0133     //if no cuts present, will default to true
0134     bool pass(const T& obj, const OffEvt& evt) const override;
0135     EgHLTDQMCut<T>* clone() const override { return new EgMultiCut(*this); }
0136   };
0137 
0138   template <class T>
0139   EgMultiCut<T>::EgMultiCut(const EgMultiCut<T>& rhs) {
0140     for (size_t cutNr = 0; cutNr < rhs.cuts_.size(); cutNr++) {
0141       cuts_.push_back(rhs.cuts_[cutNr]->clone());
0142     }
0143   }
0144 
0145   template <class T>
0146   EgMultiCut<T>& EgMultiCut<T>::operator<<(const EgHLTDQMCut<T>* inputCut) {
0147     if (typeid(*inputCut) == typeid(EgMultiCut)) {
0148       edm::LogError("EgMultiCut") << " Error can not currently load an EgMultiCut inside a EgMultiCut, the practical "
0149                                      "upshot is that the selection you think is being loaded isnt ";
0150     } else if (inputCut == nullptr) {
0151       edm::LogError("EgMultiCut") << "Error, cut being loaded is null, ignoring";
0152     } else
0153       cuts_.push_back(inputCut);
0154     return *this;
0155   }
0156 
0157   template <class T>
0158   bool EgMultiCut<T>::pass(const T& obj, const OffEvt& evt) const {
0159     for (size_t i = 0; i < cuts_.size(); i++) {
0160       if (!cuts_[i]->pass(obj, evt))
0161         return false;
0162     }
0163     return true;
0164   }
0165 
0166   //pass in which bits you want the trigger to pass
0167   //how this works
0168   //1) you specify the trigger bits you want to pass
0169   //2) you then specify whether you require all to be passed (AND) or just 1 (OR). It assumes OR by default
0170   //3) optionally, you can then specify any trigger bits you want to ensure fail. If any of these trigger bits
0171   //   are passed (OR), then the cut fails, you can also specify only to fail if all are passed (AND)
0172   template <class T>
0173   struct EgObjTrigCut : public EgHLTDQMCut<T> {
0174   public:
0175     enum CutLogic { AND, OR };
0176 
0177   private:
0178     //currently fine for default copy construction
0179     TrigCodes::TrigBitSet bitsToPass_;
0180     CutLogic passLogic_;
0181     TrigCodes::TrigBitSet bitsToFail_;
0182     CutLogic failLogic_;
0183 
0184   public:
0185     EgObjTrigCut(TrigCodes::TrigBitSet bitsToPass,
0186                  CutLogic passLogic = OR,
0187                  TrigCodes::TrigBitSet bitsToFail = TrigCodes::TrigBitSet(),
0188                  CutLogic failLogic = AND)
0189         : bitsToPass_(bitsToPass), passLogic_(passLogic), bitsToFail_(bitsToFail), failLogic_(failLogic) {}
0190     ~EgObjTrigCut() override = default;
0191 
0192     bool pass(const T& obj, const OffEvt& evt) const override;
0193     EgHLTDQMCut<T>* clone() const override { return new EgObjTrigCut(*this); }
0194   };
0195 
0196   template <class T>
0197   bool EgObjTrigCut<T>::pass(const T& obj, const OffEvt& evt) const {
0198     TrigCodes::TrigBitSet passMasked = bitsToPass_ & obj.trigBits();
0199     TrigCodes::TrigBitSet failMasked = bitsToFail_ & obj.trigBits();
0200 
0201     bool passResult = passLogic_ == AND ? passMasked == bitsToPass_ : passMasked != 0x0;
0202     bool failResult = failLogic_ == AND ? failMasked == bitsToFail_ : failMasked != 0x0;
0203     if (bitsToFail_ == 0x0)
0204       failResult = false;  //ensuring it has no effect if bits not specified
0205     return passResult && !failResult;
0206   }
0207 
0208   //pass in which bits you want the trigger to pass
0209   //can either specify to pass all of the bits (AND) or any of the bits (OR)
0210   template <class T>
0211   struct EgEvtTrigCut : public EgHLTDQMCut<T> {
0212   public:
0213     enum CutLogic { AND, OR };
0214 
0215   private:
0216     //currently default copy constructor is fine
0217     TrigCodes::TrigBitSet bitsToPass_;
0218     CutLogic passLogic_;
0219 
0220   public:
0221     EgEvtTrigCut(TrigCodes::TrigBitSet bitsToPass, CutLogic passLogic = OR)
0222         : bitsToPass_(bitsToPass), passLogic_(passLogic) {}
0223     ~EgEvtTrigCut() = default;
0224 
0225     bool pass(const T& obj, const OffEvt& evt) const;
0226     EgHLTDQMCut<T>* clone() const { return new EgEvtTrigCut(*this); }
0227   };
0228 
0229   template <class T>
0230   bool EgEvtTrigCut<T>::pass(const T& obj, const OffEvt& evt) const {
0231     TrigCodes::TrigBitSet passMasked = bitsToPass_ & evt.evtTrigBits();
0232     return passLogic_ == AND ? passMasked == bitsToPass_ : passMasked != 0x0;
0233   }
0234 
0235   //nots the cut, ie makes it return false instead of true
0236   template <class T>
0237   struct EgNotCut : public EgHLTDQMCut<T> {
0238   private:
0239     EgHLTDQMCut<T>* cut_;  //we own it
0240 
0241   public:
0242     EgNotCut(EgHLTDQMCut<T>* cut) : cut_(cut) {}
0243     EgNotCut(const EgNotCut<T>& rhs) : cut_(rhs.cut_->clone()) {}
0244     ~EgNotCut() { delete cut_; }
0245 
0246     bool pass(const T& obj, const OffEvt& evt) const { return !cut_->pass(obj, evt); }
0247     EgHLTDQMCut<T>* clone() const { return new EgNotCut(*this); }
0248   };
0249 
0250   //cut on the charge of the electron
0251   template <class T>
0252   struct ChargeCut : public EgHLTDQMCut<T> {
0253   private:
0254     int charge_;
0255 
0256   public:
0257     ChargeCut(int charge) : charge_(charge) {}
0258     ~ChargeCut() override = default;
0259 
0260     bool pass(const T& obj, const OffEvt& evt) const override { return obj.charge() == charge_; }
0261     EgHLTDQMCut<T>* clone() const override { return new ChargeCut(*this); }
0262   };
0263 
0264   //this askes if an object statifies the probe criteria and that another electron in the event statisfies the tag
0265   //although templated, its hard to think of this working for anything else other then an electron
0266   template <class T>
0267   struct EgTagProbeCut : public EgHLTDQMCut<T> {
0268   private:
0269     int probeCutCode_;
0270     int (T::*probeCutCodeFunc_)() const;
0271     int tagCutCode_;
0272     int (OffEle::*tagCutCodeFunc_)() const;
0273     float minMass_;
0274     float maxMass_;
0275 
0276   public:
0277     EgTagProbeCut(int probeCutCode,
0278                   int (T::*probeCutCodeFunc)() const,
0279                   int tagCutCode,
0280                   int (OffEle::*tagCutCodeFunc)() const,
0281                   float minMass = 81.,
0282                   float maxMass = 101.)
0283         : probeCutCode_(probeCutCode),
0284           probeCutCodeFunc_(probeCutCodeFunc),
0285           tagCutCode_(tagCutCode),
0286           tagCutCodeFunc_(tagCutCodeFunc),
0287           minMass_(minMass),
0288           maxMass_(maxMass) {}
0289     ~EgTagProbeCut() override = default;
0290 
0291     bool pass(const T& obj, const OffEvt& evt) const override;
0292     EgHLTDQMCut<T>* clone() const override { return new EgTagProbeCut(*this); }
0293   };
0294 
0295   template <class T>
0296   bool EgTagProbeCut<T>::pass(const T& obj, const OffEvt& evt) const {
0297     int nrTags = 0;
0298     const OffEle* tagEle = nullptr;
0299     const std::vector<OffEle>& eles = evt.eles();
0300     //we are looking for an *additional* tag
0301     for (const auto& ele : eles) {
0302       if (((ele.*tagCutCodeFunc_)() & tagCutCode_) == 0x0) {
0303         //now a check that the tag is not the same as the probe
0304         if (reco::deltaR2(obj.eta(), obj.phi(), ele.eta(), ele.phi()) >
0305             0.1 * 0.1) {  //not in a cone of 0.1 of probe object
0306           nrTags++;
0307           tagEle = &ele;
0308         }
0309       }
0310     }
0311     if (nrTags ==
0312         1) {  //we are requiring one and only one additional tag (the obj is automatically excluded from the tag list)
0313       if (((obj.*probeCutCodeFunc_)() & probeCutCode_) == 0x0) {  //passes probe requirements, lets check the mass
0314         float mass = (obj.p4() + tagEle->p4()).mag();
0315         if (mass > minMass_ && mass < maxMass_)
0316           return true;  //mass requirements
0317       }
0318     }
0319     return false;
0320   }
0321 
0322   template <class T>
0323   struct EgJetTagProbeCut : public EgHLTDQMCut<T> {
0324   private:
0325     int probeCutCode_;
0326     int (OffEle::*probeCutCodeFunc_)() const;
0327 
0328     float minDPhi_;
0329     float maxDPhi_;
0330 
0331   public:
0332     EgJetTagProbeCut(int probeCutCode, int (T::*probeCutCodeFunc)() const, float minDPhi = -M_PI, float maxDPhi = M_PI)
0333         : probeCutCode_(probeCutCode), probeCutCodeFunc_(probeCutCodeFunc), minDPhi_(minDPhi), maxDPhi_(maxDPhi) {}
0334     bool pass(const T& obj, const OffEvt& evt) const override;
0335     EgHLTDQMCut<T>* clone() const override { return new EgJetTagProbeCut(*this); }
0336   };
0337 
0338   template <class T>
0339   bool EgJetTagProbeCut<T>::pass(const T& obj, const OffEvt& evt) const {
0340     int nrProbes = 0;
0341     const std::vector<OffEle>& eles = evt.eles();
0342     for (const auto& ele : eles) {
0343       if (((ele.*probeCutCodeFunc_)() & probeCutCode_) == 0x0) {
0344         nrProbes++;
0345       }
0346     }
0347     bool b2bJet = false;
0348     const std::vector<reco::CaloJet>& jets = evt.jets();
0349     for (const auto& jet : jets) {
0350       if (reco::deltaR2(obj.eta(), obj.phi(), jet.eta(), jet.phi()) >
0351           0.1 * 0.1) {  //not in a cone of 0.1 of probe object
0352         float dPhi = reco::deltaPhi(obj.phi(), jet.phi());
0353         if (dPhi > minDPhi_ && dPhi < maxDPhi_)
0354           b2bJet = true;
0355       }
0356     }
0357 
0358     return nrProbes == 1 && b2bJet;
0359   }
0360 
0361   template <class T>
0362   struct EgJetB2BCut : public EgHLTDQMCut<T> {
0363   private:
0364     float minDPhi_;
0365     float maxDPhi_;
0366     float ptRelDiff_;
0367 
0368   public:
0369     EgJetB2BCut(float minDPhi = -M_PI, float maxDPhi = M_PI, float ptRelDiff = 999)
0370         : minDPhi_(minDPhi), maxDPhi_(maxDPhi), ptRelDiff_(ptRelDiff) {}
0371     bool pass(const T& obj, const OffEvt& evt) const;
0372     EgHLTDQMCut<T>* clone() const { return new EgJetB2BCut(*this); }
0373   };
0374 
0375   template <class T>
0376   bool EgJetB2BCut<T>::pass(const T& obj, const OffEvt& evt) const {
0377     bool b2bJet = false;
0378     const std::vector<reco::CaloJet>& jets = evt.jets();
0379     for (const auto& jet : jets) {
0380       if (reco::deltaR2(obj.eta(), obj.phi(), jet.eta(), jet.phi()) >
0381           0.1 * 0.1) {  //not in a cone of 0.1 of probe object
0382         float dPhi = reco::deltaPhi(obj.phi(), jet.phi());
0383         if (dPhi > minDPhi_ && dPhi < maxDPhi_ && fabs(1 - jet.pt() / obj.pt()) < ptRelDiff_)
0384           b2bJet = true;
0385       }
0386     }
0387     return b2bJet;
0388   }
0389 
0390   //requires the the passed in electron and another in the event passes the specified cuts
0391   struct EgDiEleCut : public EgHLTDQMCut<OffEle> {
0392   private:
0393     int cutCode_;
0394     int (OffEle::*cutCodeFunc_)() const;
0395 
0396   public:
0397     EgDiEleCut(int cutCode, int (OffEle::*cutCodeFunc)() const) : cutCode_(cutCode), cutCodeFunc_(cutCodeFunc) {}
0398     bool pass(const OffEle& obj, const OffEvt& evt) const override;
0399     EgHLTDQMCut<OffEle>* clone() const override { return new EgDiEleCut(*this); }
0400   };
0401 
0402   //requires the the passed in electron and another in the event passes the specified cuts
0403   template <class Key>
0404   struct EgDiEleUserCut : public EgHLTDQMCut<OffEle> {
0405   private:
0406     int (OffEle::*cutCodeFunc_)(const Key&) const;
0407     const Key& key_;
0408     int cutsNotToMask_;
0409 
0410   public:
0411     EgDiEleUserCut(int (OffEle::*cutCodeFunc)(const Key&) const, const Key& key, int cutsNotToMask = ~0x0)
0412         : cutCodeFunc_(cutCodeFunc), key_(key), cutsNotToMask_(cutsNotToMask) {}
0413     ~EgDiEleUserCut() override = default;
0414 
0415     bool pass(const OffEle& obj, const OffEvt& evt) const override;
0416     EgHLTDQMCut<OffEle>* clone() const override {
0417       return new EgDiEleUserCut(*this);
0418     }  //default copy constructor is fine
0419   };
0420 
0421   template <class Key>
0422   bool EgDiEleUserCut<Key>::pass(const OffEle& obj, const OffEvt& evt) const {
0423     const std::vector<OffEle>& eles = evt.eles();
0424     for (const auto& ele : eles) {
0425       if (&ele != &obj) {  //different electrons
0426         int diEleCutCode = (obj.*cutCodeFunc_)(key_) | (ele.*cutCodeFunc_)(key_);
0427         if ((diEleCutCode & cutsNotToMask_) == 0x0)
0428           return true;
0429       }
0430     }
0431     return false;
0432   }
0433 
0434   //requires the the passed in photon and another in the event passes the specified cuts
0435   struct EgDiPhoCut : public EgHLTDQMCut<OffPho> {
0436   private:
0437     int cutCode_;
0438     int (OffPho::*cutCodeFunc_)() const;
0439 
0440   public:
0441     EgDiPhoCut(int cutCode, int (OffPho::*cutCodeFunc)() const) : cutCode_(cutCode), cutCodeFunc_(cutCodeFunc) {}
0442     bool pass(const OffPho& obj, const OffEvt& evt) const override;
0443     EgHLTDQMCut<OffPho>* clone() const override { return new EgDiPhoCut(*this); }
0444   };
0445 
0446   //requires passed photon and another in the event passes the specified cuts
0447   template <class Key>
0448   struct EgDiPhoUserCut : public EgHLTDQMCut<OffPho> {
0449   private:
0450     int (OffPho::*cutCodeFunc_)(const Key&) const;
0451     const Key& key_;
0452     int cutsNotToMask_;
0453 
0454   public:
0455     EgDiPhoUserCut(int (OffPho::*cutCodeFunc)(const Key&) const, const Key& key, int cutsNotToMask = ~0x0)
0456         : cutCodeFunc_(cutCodeFunc), key_(key), cutsNotToMask_(cutsNotToMask) {}
0457     ~EgDiPhoUserCut() override = default;
0458 
0459     bool pass(const OffPho& obj, const OffEvt& evt) const override;
0460     EgHLTDQMCut<OffPho>* clone() const override {
0461       return new EgDiPhoUserCut(*this);
0462     }  //default copy constructor is fine
0463   };
0464 
0465   template <class Key>
0466   bool EgDiPhoUserCut<Key>::pass(const OffPho& obj, const OffEvt& evt) const {
0467     const std::vector<OffPho>& phos = evt.phos();
0468     for (const auto& pho : phos) {
0469       if (&pho != &obj) {  //different phoctrons
0470 
0471         int diPhoCutCode = (obj.*cutCodeFunc_)(key_) | (pho.*cutCodeFunc_)(key_);
0472         if ((diPhoCutCode & cutsNotToMask_) == 0x0)
0473           return true;
0474       }
0475     }
0476     return false;
0477   }
0478 
0479   //a trigger tag and probe cut
0480   //basically we require the electron to pass some cuts
0481   //and then do tag and probe on the trigger
0482   //removing templates as it makes no sense
0483   struct EgTrigTagProbeCut : public EgHLTDQMCut<OffEle> {
0484   private:
0485     TrigCodes::TrigBitSet bitsToPass_;
0486     int cutCode_;
0487     int (OffEle::*cutCodeFunc_)() const;
0488     float minMass_;
0489     float maxMass_;
0490 
0491   public:
0492     EgTrigTagProbeCut(TrigCodes::TrigBitSet bitsToPass,
0493                       int cutCode,
0494                       int (OffEle::*cutCodeFunc)() const,
0495                       float minMass = 81.,
0496                       float maxMass = 101.)
0497         : bitsToPass_(bitsToPass), cutCode_(cutCode), cutCodeFunc_(cutCodeFunc), minMass_(minMass), maxMass_(maxMass) {}
0498     ~EgTrigTagProbeCut() override = default;
0499 
0500     bool pass(const OffEle& ele, const OffEvt& evt) const override;
0501     EgHLTDQMCut<OffEle>* clone() const override { return new EgTrigTagProbeCut(*this); }
0502   };
0503 
0504   //----Morse----
0505   //new tag and probe cut
0506   //require two wp80 electrons
0507   struct EgTrigTagProbeCut_New : public EgHLTDQMCut<OffEle> {
0508   private:
0509     TrigCodes::TrigBitSet bit1ToPass_;
0510     TrigCodes::TrigBitSet bit2ToPass_;
0511     int cutCode_;
0512     int (OffEle::*cutCodeFunc_)() const;
0513     float minMass_;
0514     float maxMass_;
0515 
0516   public:
0517     EgTrigTagProbeCut_New(TrigCodes::TrigBitSet bit1ToPass,
0518                           TrigCodes::TrigBitSet bit2ToPass,
0519                           int cutCode,
0520                           int (OffEle::*cutCodeFunc)() const,
0521                           float minMass = 81.,
0522                           float maxMass = 101.)
0523         : bit1ToPass_(bit1ToPass),
0524           bit2ToPass_(bit2ToPass),
0525           cutCode_(cutCode),
0526           cutCodeFunc_(cutCodeFunc),
0527           minMass_(minMass),
0528           maxMass_(maxMass) {}
0529     ~EgTrigTagProbeCut_New() override = default;
0530 
0531     bool pass(const OffEle& ele, const OffEvt& evt) const override;
0532     EgHLTDQMCut<OffEle>* clone() const override { return new EgTrigTagProbeCut_New(*this); }
0533   };
0534   //same for photons
0535   struct EgTrigTagProbeCut_NewPho : public EgHLTDQMCut<OffPho> {
0536   private:
0537     TrigCodes::TrigBitSet bit1ToPass_;
0538     TrigCodes::TrigBitSet bit2ToPass_;
0539     int cutCode_;
0540     int (OffPho::*cutCodeFunc_)() const;
0541     float minMass_;
0542     float maxMass_;
0543 
0544   public:
0545     EgTrigTagProbeCut_NewPho(TrigCodes::TrigBitSet bit1ToPass,
0546                              TrigCodes::TrigBitSet bit2ToPass,
0547                              int cutCode,
0548                              int (OffPho::*cutCodeFunc)() const,
0549                              float minMass = 81.,
0550                              float maxMass = 101.)
0551         : bit1ToPass_(bit1ToPass),
0552           bit2ToPass_(bit2ToPass),
0553           cutCode_(cutCode),
0554           cutCodeFunc_(cutCodeFunc),
0555           minMass_(minMass),
0556           maxMass_(maxMass) {}
0557     ~EgTrigTagProbeCut_NewPho() override = default;
0558 
0559     bool pass(const OffPho& pho, const OffEvt& evt) const override;
0560     EgHLTDQMCut<OffPho>* clone() const override { return new EgTrigTagProbeCut_NewPho(*this); }
0561   };
0562 
0563 }  // namespace egHLT
0564 #endif