CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/DQMOffline/Trigger/interface/EgHLTDQMCut.h

Go to the documentation of this file.
00001 #ifndef DQMOFFLINE_TRIGGER_EGHLTDQMCUT
00002 #define DQMOFFLINE_TRIGGER_EGHLTDQMCUT 
00003 
00004 //class: EgHLTDQMCut
00005 //
00006 //author: Sam Harper (June 2008)
00007 //
00008 //WARNING: interface is NOT final, please dont use this class for now without clearing it with me
00009 //         as I will change it and possibly break all your code
00010 //
00011 //aim: to allow the user to place a cut on the electron using it or the event
00012 //
00013 //implimentation:
00014 
00015 #include "DQMOffline/Trigger/interface/EgHLTOffEvt.h"
00016 #include "DQMOffline/Trigger/interface/EgHLTTrigCodes.h"
00017 
00018 #include "DataFormats/Math/interface/deltaR.h"
00019 
00020 //this is a pure virtual struct which defines the interface to the cut objects
00021 //it is also currently uncopyable
00022 
00023 namespace egHLT {
00024 
00025   template<class T> struct EgHLTDQMCut { 
00026     
00027     private: 
00028     //disabling copy and assignment for all objects
00029     EgHLTDQMCut& operator=(const EgHLTDQMCut& rhs){return *this;}
00030       protected:
00031       //only derived classes can call the copy constructor (needed for clone...)
00032       EgHLTDQMCut(const EgHLTDQMCut& rhs){}
00033     
00034     public:
00035     EgHLTDQMCut(){}
00036     virtual ~EgHLTDQMCut(){}
00037     virtual bool pass(const T& obj,const OffEvt& evt)const=0;
00038     virtual EgHLTDQMCut<T>* clone()const=0; //caller owns the pointer
00039   };
00040   
00041   
00042   
00043   
00044   template<class T> struct EgHLTDQMVarCut : public EgHLTDQMCut<T> {
00045     private:
00046     int cutsToPass_; //the cuts whose eff we are measuring
00047     int (T::*cutCodeFunc_)()const;
00048     
00049     public:
00050     EgHLTDQMVarCut(int cutsToPass,int (T::*cutCodeFunc)()const):cutsToPass_(cutsToPass),cutCodeFunc_(cutCodeFunc){}
00051     ~EgHLTDQMVarCut(){}
00052     
00053     bool pass(const T& obj,const OffEvt& evt)const;
00054     EgHLTDQMCut<T>* clone()const{return new EgHLTDQMVarCut(*this);} //default copy constructor is fine
00055     
00056   };
00057   
00058   //to understand this you need to know about
00059   //1) templates
00060   //2) inheritance (sort of)
00061   //3) function pointers
00062   //4) bitwise operations
00063   //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
00064   template<class T> bool EgHLTDQMVarCut<T>::pass(const T& obj,const OffEvt& evt)const
00065     {
00066       if(((obj.*cutCodeFunc_)() & cutsToPass_)==0) return true;
00067       else return false;
00068     }
00069   
00070   
00071   //now this is similar to EgHLTDQMVarCut except that it allows a key to specified to the cut code function
00072   template<class T,class Key> struct EgHLTDQMUserVarCut : public EgHLTDQMCut<T> {
00073     private:
00074     
00075     int (T::*cutCodeFunc_)(const Key&)const;   
00076     const Key key_;
00077     int cutsNotToMask_;
00078     
00079     public:
00080     EgHLTDQMUserVarCut(int (T::*cutCodeFunc)(const Key&)const,const Key& key,int cutsNotToMask=~0x0):cutCodeFunc_(cutCodeFunc),key_(key),cutsNotToMask_(cutsNotToMask){}
00081     ~EgHLTDQMUserVarCut(){}
00082     
00083     bool pass(const T& obj,const OffEvt& evt)const;
00084     EgHLTDQMCut<T>* clone()const{return new EgHLTDQMUserVarCut(*this);} //default copy constructor is fine
00085     
00086   };
00087   
00088   template<class T,class Key> bool EgHLTDQMUserVarCut<T,Key>::pass(const T& obj,const OffEvt& evt)const
00089     { 
00090       if(((obj.*cutCodeFunc_)(key_) & cutsNotToMask_)==0) return true;
00091       else return false;
00092     }
00093   
00094   template<class T,typename varType> struct EgGreaterCut : public EgHLTDQMCut<T> {
00095     private:
00096     varType cutValue_;
00097     varType (T::*varFunc_)()const;
00098  
00099     public:
00100     
00101     EgGreaterCut(varType cutValue,varType (T::*varFunc)()const):
00102       cutValue_(cutValue),varFunc_(varFunc){}
00103     
00104     bool pass(const T& obj,const OffEvt& evt)const{return (obj.*varFunc_)()>cutValue_;}
00105     EgHLTDQMCut<T>* clone()const{return new EgGreaterCut(*this);} //default copy constructor is fine
00106   };
00107   
00108   //this struct allows multiple cuts to be strung together
00109   //now I could quite simply have a link to the next cut defined in the base class 
00110   //and the operator<< defined there also but I dont for the following reason
00111   //1) I'm concerned about a circular chain of cuts (hence why you cant do a EgMultiCut << EgMultiCut)
00112   //2) it requires all cuts to multi cut aware in the pass function
00113   //in the future I may change it so this class isnt required
00114   template<class T> struct EgMultiCut : public EgHLTDQMCut<T> {
00115     private:
00116     std::vector<const EgHLTDQMCut<T>*> cuts_;//all the points to the cuts we own 
00117     
00118     public:
00119     EgMultiCut(){}  
00120     EgMultiCut(const EgMultiCut<T>& rhs);
00121     ~EgMultiCut(){for(size_t i=0;i<cuts_.size();i++) delete cuts_[i];}
00122     
00123     //we own any cut given to use this way
00124     EgMultiCut<T>& operator<<(const EgHLTDQMCut<T>* inputCut);
00125     
00126     
00127     //basically an AND of all the cuts using short circuit evaluation, starting with the first cut
00128     //if no cuts present, will default to true
00129     bool pass(const T& obj,const OffEvt& evt)const;
00130     EgHLTDQMCut<T>* clone()const{return new EgMultiCut(*this);}
00131   };
00132   
00133   template<class T> EgMultiCut<T>::EgMultiCut(const EgMultiCut<T>& rhs)
00134     {
00135       for(size_t cutNr=0;cutNr<rhs.cuts_.size();cutNr++){
00136         cuts_.push_back(rhs.cuts_[cutNr]->clone());
00137       }
00138     }
00139   
00140   
00141   template<class T> EgMultiCut<T>& EgMultiCut<T>::operator<<(const EgHLTDQMCut<T>* inputCut)
00142     {
00143       if(typeid(*inputCut)==typeid(EgMultiCut)){
00144         edm::LogError("EgMultiCut") <<" Error can not currently load an EgMultiCut inside a EgMultiCut, the practical upshot is that the selection you think is being loaded isnt ";
00145       }else if(inputCut==NULL){
00146         edm::LogError("EgMultiCut") << "Error, cut being loaded is null, ignoring";
00147       }else cuts_.push_back(inputCut);
00148       return *this;
00149     }
00150   
00151   template<class T> bool EgMultiCut<T>::pass(const T& obj,const OffEvt& evt)const
00152     {
00153       for(size_t i=0;i<cuts_.size();i++){
00154         if(!cuts_[i]->pass(obj,evt)) return false;
00155       }
00156       return true;
00157     
00158     }
00159   
00160   //pass in which bits you want the trigger to pass
00161   //how this works
00162   //1) you specify the trigger bits you want to pass
00163   //2) you then specify whether you require all to be passed (AND) or just 1 (OR). It assumes OR by default
00164   //3) optionally, you can then specify any trigger bits you want to ensure fail. If any of these trigger bits 
00165   //   are passed (OR), then the cut fails, you can also specify only to fail if all are passed (AND)
00166   template<class T> struct EgObjTrigCut : public EgHLTDQMCut<T> {
00167     public:
00168     enum CutLogic{AND,OR};
00169     
00170     private:
00171     //currently fine for default copy construction
00172     TrigCodes::TrigBitSet bitsToPass_; 
00173     CutLogic passLogic_;
00174     TrigCodes::TrigBitSet bitsToFail_;
00175     CutLogic failLogic_;                                        
00176     
00177     public:
00178     EgObjTrigCut( TrigCodes::TrigBitSet bitsToPass,CutLogic passLogic=OR,TrigCodes::TrigBitSet bitsToFail=TrigCodes::TrigBitSet(),CutLogic failLogic=AND):
00179       bitsToPass_(bitsToPass),passLogic_(passLogic),bitsToFail_(bitsToFail),failLogic_(failLogic){}
00180     ~EgObjTrigCut(){}
00181     
00182     bool pass(const T& obj,const OffEvt& evt)const;
00183     EgHLTDQMCut<T>* clone()const{return new EgObjTrigCut(*this);}
00184   };
00185   
00186   template<class T> bool EgObjTrigCut<T>::pass(const T& obj,const OffEvt& evt)const
00187     {
00188       TrigCodes::TrigBitSet passMasked = bitsToPass_&obj.trigBits();
00189       TrigCodes::TrigBitSet failMasked = bitsToFail_&obj.trigBits();
00190     
00191       bool passResult = passLogic_==AND ? passMasked==bitsToPass_ : passMasked!=0x0;
00192       bool failResult = failLogic_==AND ? failMasked==bitsToFail_ : failMasked!=0x0;
00193       if(bitsToFail_==0x0) failResult=false; //ensuring it has no effect if bits not specified
00194       return passResult && !failResult;
00195     
00196     }
00197   
00198   
00199   
00200   //pass in which bits you want the trigger to pass
00201   //can either specify to pass all of the bits (AND) or any of the bits (OR)
00202   template<class T> struct EgEvtTrigCut : public EgHLTDQMCut<T> {
00203     public:
00204     enum CutLogic{AND,OR};
00205     private:
00206     //currently default copy constructor is fine
00207     TrigCodes::TrigBitSet bitsToPass_;
00208     CutLogic passLogic_;
00209     
00210     public:
00211     EgEvtTrigCut( TrigCodes::TrigBitSet bitsToPass,CutLogic passLogic=OR):bitsToPass_(bitsToPass),passLogic_(passLogic){}
00212     ~EgEvtTrigCut(){}
00213     
00214     bool pass(const T& obj,const OffEvt& evt)const; 
00215     EgHLTDQMCut<T>* clone()const{return new EgEvtTrigCut(*this);}
00216   };
00217   
00218   template<class T> bool EgEvtTrigCut<T>::pass(const T& obj,const OffEvt& evt)const
00219     {
00220       TrigCodes::TrigBitSet passMasked = bitsToPass_&evt.evtTrigBits();
00221       return passLogic_==AND ? passMasked==bitsToPass_ : passMasked!=0x0;
00222     }
00223   
00224   //nots the cut, ie makes it return false instead of true
00225   template<class T> struct EgNotCut : public EgHLTDQMCut<T> {
00226     private:
00227     EgHLTDQMCut<T>* cut_; //we own it
00228     
00229     public:
00230     EgNotCut(EgHLTDQMCut<T>* cut):cut_(cut){}
00231     EgNotCut(const EgNotCut<T>& rhs):cut_(rhs.cut_->clone()){}
00232     ~EgNotCut(){delete cut_;}
00233     
00234     bool pass(const T& obj,const OffEvt& evt)const{return !cut_->pass(obj,evt);}
00235     EgHLTDQMCut<T>* clone()const{return new EgNotCut(*this);}
00236   };
00237   
00238   //cut on the charge of the electron
00239   template<class T> struct ChargeCut : public EgHLTDQMCut<T> {
00240     private:
00241     int charge_;
00242     
00243     public:
00244     ChargeCut(int charge):charge_(charge){}
00245     ~ChargeCut(){}
00246     
00247     bool pass(const T& obj,const OffEvt& evt)const{return obj.charge()==charge_;}
00248     EgHLTDQMCut<T>* clone()const{return new ChargeCut(*this);}
00249   };
00250   
00251   //this askes if an object statifies the probe criteria and that another electron in the event statisfies the tag
00252   //although templated, its hard to think of this working for anything else other then an electron
00253   template<class T> struct EgTagProbeCut : public EgHLTDQMCut<T> {
00254     private:
00255     int probeCutCode_; 
00256     int (T::*probeCutCodeFunc_)()const;
00257     int tagCutCode_;
00258     int (OffEle::*tagCutCodeFunc_)()const;
00259     float minMass_;
00260     float maxMass_;
00261     public:
00262     EgTagProbeCut(int probeCutCode,int (T::*probeCutCodeFunc)()const,int tagCutCode,int (OffEle::*tagCutCodeFunc)()const,float minMass=81.,float maxMass=101.):probeCutCode_(probeCutCode),probeCutCodeFunc_(probeCutCodeFunc),tagCutCode_(tagCutCode),tagCutCodeFunc_(tagCutCodeFunc),minMass_(minMass),maxMass_(maxMass){}
00263     ~EgTagProbeCut(){}
00264     
00265     bool pass(const T& obj,const OffEvt& evt)const;
00266     EgHLTDQMCut<T>* clone()const{return new EgTagProbeCut(*this);}
00267   };
00268   
00269   template<class T> bool EgTagProbeCut<T>::pass(const T& obj,const OffEvt& evt)const
00270     {
00271       int nrTags=0;
00272       const OffEle* tagEle=NULL;
00273       const std::vector<OffEle>& eles = evt.eles();
00274       //we are looking for an *additional* tag
00275       for(size_t eleNr=0;eleNr<eles.size();eleNr++){
00276         if( ((eles[eleNr].*tagCutCodeFunc_)() & tagCutCode_)==0x0){
00277           //now a check that the tag is not the same as the probe
00278           if(reco::deltaR2(obj.eta(),obj.phi(),eles[eleNr].eta(),eles[eleNr].phi())>0.1*0.1){//not in a cone of 0.1 of probe object
00279             nrTags++;
00280             tagEle = &eles[eleNr];
00281           }
00282         }
00283       }
00284       if(nrTags==1){ //we are requiring one and only one additional tag (the obj is automatically excluded from the tag list)
00285         if(((obj.*probeCutCodeFunc_)() & probeCutCode_)==0x0){ //passes probe requirements, lets check the mass
00286           float mass = (obj.p4()+tagEle->p4()).mag();
00287           if(mass>minMass_ && mass<maxMass_) return true; //mass requirements
00288         }
00289       }
00290       return false; 
00291     }
00292   
00293   template<class T> struct EgJetTagProbeCut : public EgHLTDQMCut<T>{
00294     private:
00295     int probeCutCode_;
00296     int (OffEle::*probeCutCodeFunc_)()const;
00297 
00298     float minDPhi_;
00299     float maxDPhi_;
00300     public:
00301     EgJetTagProbeCut(int probeCutCode,int (T::*probeCutCodeFunc)()const,float minDPhi=-M_PI,float maxDPhi=M_PI):
00302       probeCutCode_(probeCutCode),probeCutCodeFunc_(probeCutCodeFunc),minDPhi_(minDPhi),maxDPhi_(maxDPhi){}
00303     bool pass(const T& obj,const OffEvt& evt)const;
00304     EgHLTDQMCut<T>* clone()const{return new EgJetTagProbeCut(*this);}
00305     
00306   };
00307   
00308   
00309   template<class T> bool EgJetTagProbeCut<T>::pass(const T& obj,const OffEvt& evt)const
00310     {
00311       int nrProbes=0;
00312       const std::vector<OffEle>& eles = evt.eles();
00313       for(size_t eleNr=0;eleNr<eles.size();eleNr++){
00314         if( ((eles[eleNr].*probeCutCodeFunc_)() & probeCutCode_)==0x0){
00315           nrProbes++;
00316         }
00317       }
00318       bool b2bJet=false;
00319       const std::vector<reco::CaloJet>& jets =evt.jets();
00320       for(size_t jetNr=0;jetNr<jets.size();jetNr++){
00321         if(reco::deltaR2(obj.eta(),obj.phi(),jets[jetNr].eta(),jets[jetNr].phi())>0.1*0.1){//not in a cone of 0.1 of probe object
00322           float dPhi = reco::deltaPhi(obj.phi(),jets[jetNr].phi());
00323           if(dPhi>minDPhi_ && dPhi<maxDPhi_) b2bJet=true;
00324         }
00325       }
00326     
00327       return nrProbes==1 && b2bJet;
00328     
00329     }
00330   
00331   
00332   template<class T> struct EgJetB2BCut : public EgHLTDQMCut<T>{
00333     private:
00334     
00335     float minDPhi_;
00336     float maxDPhi_;
00337     float ptRelDiff_;
00338     
00339     public:
00340     EgJetB2BCut(float minDPhi=-M_PI,float maxDPhi=M_PI,float ptRelDiff=999):
00341       minDPhi_(minDPhi),maxDPhi_(maxDPhi),ptRelDiff_(ptRelDiff){}
00342     bool pass(const T& obj,const OffEvt& evt)const;
00343     EgHLTDQMCut<T>* clone()const{return new EgJetB2BCut(*this);}
00344     
00345   };
00346   
00347 
00348   template<class T> bool EgJetB2BCut<T>::pass(const T& obj,const OffEvt& evt)const
00349     {
00350     
00351       bool b2bJet=false;
00352       const std::vector<reco::CaloJet>& jets =evt.jets();
00353       for(size_t jetNr=0;jetNr<jets.size();jetNr++){
00354         if(reco::deltaR2(obj.eta(),obj.phi(),jets[jetNr].eta(),jets[jetNr].phi())>0.1*0.1){//not in a cone of 0.1 of probe object
00355           float dPhi = reco::deltaPhi(obj.phi(),jets[jetNr].phi());
00356           if(dPhi>minDPhi_ && dPhi<maxDPhi_ && fabs(1-jets[jetNr].pt()/obj.pt()) < ptRelDiff_) b2bJet=true;
00357         }
00358       }
00359       return b2bJet;
00360     
00361     }
00362   
00363   
00364   //requires the the passed in electron and another in the event passes the specified cuts
00365   struct EgDiEleCut : public EgHLTDQMCut<OffEle> {
00366     private:
00367     int cutCode_;
00368     int (OffEle::*cutCodeFunc_)()const;
00369     
00370     public:
00371     EgDiEleCut(int cutCode,int (OffEle::*cutCodeFunc)()const):cutCode_(cutCode),cutCodeFunc_(cutCodeFunc){}
00372     bool pass(const OffEle& obj,const OffEvt& evt)const;
00373     EgHLTDQMCut<OffEle>* clone()const{return new EgDiEleCut(*this);}
00374   };
00375   
00376   //requires the the passed in electron and another in the event passes the specified cuts
00377   template<class Key> struct EgDiEleUserCut : public EgHLTDQMCut<OffEle> {
00378     private:
00379     int (OffEle::*cutCodeFunc_)(const Key&)const;   
00380     const Key& key_;
00381     int cutsNotToMask_;
00382     public:
00383     EgDiEleUserCut(int (OffEle::*cutCodeFunc)(const Key&)const,const Key& key,int cutsNotToMask=~0x0):cutCodeFunc_(cutCodeFunc),key_(key),cutsNotToMask_(cutsNotToMask){}
00384     ~EgDiEleUserCut(){}
00385     
00386     bool pass(const OffEle& obj,const OffEvt& evt)const;
00387     EgHLTDQMCut<OffEle>* clone()const{return new EgDiEleUserCut(*this);} //default copy constructor is fine
00388     
00389   };
00390   
00391   template<class Key> bool EgDiEleUserCut<Key>::pass(const OffEle& obj,const OffEvt& evt)const
00392     { 
00393       const std::vector<OffEle>& eles = evt.eles();
00394       for(size_t eleNr=0;eleNr<eles.size();eleNr++){
00395         if(&eles[eleNr]!=&obj){ //different electrons
00396           int diEleCutCode = (obj.*cutCodeFunc_)(key_) | (eles[eleNr].*cutCodeFunc_)(key_);  
00397           if( (diEleCutCode & cutsNotToMask_)==0x0) return true;
00398         }
00399       }
00400       return false;
00401     }
00402 
00403   
00404   //requires the the passed in photon and another in the event passes the specified cuts
00405   struct EgDiPhoCut : public EgHLTDQMCut<OffPho> {
00406     private:
00407     int cutCode_;
00408     int (OffPho::*cutCodeFunc_)()const;
00409     
00410     public:
00411     EgDiPhoCut(int cutCode,int (OffPho::*cutCodeFunc)()const):cutCode_(cutCode),cutCodeFunc_(cutCodeFunc){}
00412     bool pass(const OffPho& obj,const OffEvt& evt)const;
00413     EgHLTDQMCut<OffPho>* clone()const{return new EgDiPhoCut(*this);}
00414   };
00415   
00416   
00417   //requires passed photon and another in the event passes the specified cuts
00418   template<class Key> struct EgDiPhoUserCut : public EgHLTDQMCut<OffPho> {
00419     private:
00420     int (OffPho::*cutCodeFunc_)(const Key&)const;   
00421     const Key& key_;
00422     int cutsNotToMask_;
00423     public:
00424     EgDiPhoUserCut(int (OffPho::*cutCodeFunc)(const Key&)const,const Key& key,int cutsNotToMask=~0x0):cutCodeFunc_(cutCodeFunc),key_(key),cutsNotToMask_(cutsNotToMask){}
00425     ~EgDiPhoUserCut(){}
00426     
00427     bool pass(const OffPho& obj,const OffEvt& evt)const;
00428     EgHLTDQMCut<OffPho>* clone()const{return new EgDiPhoUserCut(*this);} //default copy constructor is fine
00429     
00430   };
00431   
00432   template<class Key> bool EgDiPhoUserCut<Key>::pass(const OffPho& obj,const OffEvt& evt)const
00433     { 
00434       const std::vector<OffPho>& phos = evt.phos();
00435       for(size_t phoNr=0;phoNr<phos.size();phoNr++){
00436         if(&phos[phoNr]!=&obj){ //different phoctrons
00437         
00438           int diPhoCutCode = (obj.*cutCodeFunc_)(key_) | (phos[phoNr].*cutCodeFunc_)(key_);
00439           if( (diPhoCutCode & cutsNotToMask_)==0x0) return true;
00440         }
00441       }
00442       return false;
00443     }
00444   
00445   //a trigger tag and probe cut
00446   //basically we require the electron to pass some cuts
00447   //and then do tag and probe on the trigger
00448   //removing templates as it makes no sense
00449   struct EgTrigTagProbeCut : public EgHLTDQMCut<OffEle> {
00450     private:
00451     TrigCodes::TrigBitSet bitsToPass_;
00452     int cutCode_;
00453     int (OffEle::*cutCodeFunc_)()const;
00454     float minMass_;
00455     float maxMass_;
00456     public:
00457     EgTrigTagProbeCut(TrigCodes::TrigBitSet bitsToPass,int cutCode,int (OffEle::*cutCodeFunc)()const,float minMass=81.,float maxMass=101.):bitsToPass_(bitsToPass),cutCode_(cutCode),cutCodeFunc_(cutCodeFunc),minMass_(minMass),maxMass_(maxMass){}
00458     ~EgTrigTagProbeCut(){}
00459     
00460     bool pass(const OffEle& ele,const OffEvt& evt)const;
00461     EgHLTDQMCut<OffEle>* clone()const{return new EgTrigTagProbeCut(*this);} 
00462     
00463   };
00464   
00465   //----Morse----
00466   //new tag and probe cut
00467   //require two wp80 electrons
00468   struct EgTrigTagProbeCut_New : public EgHLTDQMCut<OffEle> {
00469     private:
00470     TrigCodes::TrigBitSet bit1ToPass_;
00471     TrigCodes::TrigBitSet bit2ToPass_;
00472     int cutCode_;
00473     int (OffEle::*cutCodeFunc_)()const;
00474     float minMass_;
00475     float maxMass_;
00476     public:
00477     EgTrigTagProbeCut_New(TrigCodes::TrigBitSet bit1ToPass,TrigCodes::TrigBitSet bit2ToPass,int cutCode,int (OffEle::*cutCodeFunc)()const,float minMass=81.,float maxMass=101.):bit1ToPass_(bit1ToPass),bit2ToPass_(bit2ToPass),cutCode_(cutCode),cutCodeFunc_(cutCodeFunc),minMass_(minMass),maxMass_(maxMass){}
00478     ~EgTrigTagProbeCut_New(){}
00479     
00480     bool pass(const OffEle& ele,const OffEvt& evt)const;
00481     EgHLTDQMCut<OffEle>* clone()const{return new EgTrigTagProbeCut_New(*this);} 
00482     
00483   };
00484   //same for photons
00485   struct EgTrigTagProbeCut_NewPho : public EgHLTDQMCut<OffPho> {
00486     private:
00487     TrigCodes::TrigBitSet bit1ToPass_;
00488     TrigCodes::TrigBitSet bit2ToPass_;
00489     int cutCode_;
00490     int (OffPho::*cutCodeFunc_)()const;
00491     float minMass_;
00492     float maxMass_;
00493     public:
00494     EgTrigTagProbeCut_NewPho(TrigCodes::TrigBitSet bit1ToPass,TrigCodes::TrigBitSet bit2ToPass,int cutCode,int (OffPho::*cutCodeFunc)()const,float minMass=81.,float maxMass=101.):bit1ToPass_(bit1ToPass),bit2ToPass_(bit2ToPass),cutCode_(cutCode),cutCodeFunc_(cutCodeFunc),minMass_(minMass),maxMass_(maxMass){}
00495     ~EgTrigTagProbeCut_NewPho(){}
00496     
00497     bool pass(const OffPho& pho,const OffEvt& evt)const;
00498     EgHLTDQMCut<OffPho>* clone()const{return new EgTrigTagProbeCut_NewPho(*this);} 
00499     
00500   };
00501 
00502 }//end of namespace
00503 #endif