CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/DQMOffline/Trigger/interface/EgHLTOffEle.h

Go to the documentation of this file.
00001 #ifndef DQMOFFLINE_TRIGGER_EGHLTOFFELE
00002 #define DQMOFFLINE_TRIGGER_EGHLTOFFELE
00003 
00004 //class: EgHLTOffEle
00005 //
00006 //author: Sam Harper (July 2008)
00007 //
00008 //
00009 //aim: to allow easy access to electron ID variables
00010 //     currently the CMSSW electron classes are a mess with key electron selection variables not being accessable from GsfElectron
00011 //     this a stop gap to produce a simple electron class with all variables easily accessable via methods 
00012 //     note as this is meant for HLT Offline DQM, I do not want the overhead of converting to pat
00013 //
00014 //implimentation: aims to be a wrapper for GsfElectron methods, it is hoped that in time these methods will be directly added to GsfElectron and so
00015 //                make this class obsolute
00016 //                unfortunately can not be a pure wrapper as needs to store isol and cluster shape
00017 //
00018 
00019 
00020 #include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h"
00021 #include "DataFormats/EgammaReco/interface/ClusterShapeFwd.h"
00022 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
00023 #include "DataFormats/EgammaReco/interface/ClusterShape.h"
00024 #include "DataFormats/TrackReco/interface/Track.h"
00025 
00026 #include "DQMOffline/Trigger/interface/EgHLTEgCutCodes.h"
00027 #include "DQMOffline/Trigger/interface/EgHLTTrigCodes.h"
00028 
00029 namespace egHLT {
00030   class OffEle { 
00031     
00032   public:
00033     //helper struct to store the isolations
00034     struct IsolData {
00035       float em;
00036       float hadDepth1;
00037       float hadDepth2;
00038       float ptTrks;
00039       int nrTrks;
00040       //possibly going to move these to hlt data
00041       float hltHad;
00042       float hltTrksEle;
00043       float hltTrksPho;
00044       float hltEm;
00045     };
00046     
00047   public:
00048     //helper struct to store the cluster shapes
00049     struct ClusShapeData {
00050       float sigmaEtaEta;
00051       float sigmaIEtaIEta;  
00052       float sigmaPhiPhi;
00053       float sigmaIPhiIPhi; 
00054       float e1x5Over5x5;
00055       float e2x5MaxOver5x5;
00056       float r9;
00057     
00058     };
00059     
00060   public:
00061     //helper struct to store reco approximations of variables made by HLT
00062     struct HLTData {
00063       float dEtaIn;
00064       float dPhiIn;  
00065       float invEInvP;
00066     };
00067     
00068   private:
00069     const reco::GsfElectron* gsfEle_; //pointers to the underlying electron (we do not own this)
00070 
00071     ClusShapeData clusShapeData_;
00072     IsolData isolData_;
00073     HLTData hltData_;
00074     
00075     //these are bit-packed words telling me which cuts the electron fail (ie 0x0 is passed all cuts)
00076     int cutCode_;
00077     int looseCutCode_;
00078     //the idea is that these are user definable cuts meant to be idenital to the specified trigger
00079     //it is probably clear to the reader that I havent decided on the most efficient way to do this
00080     std::vector<std::pair<TrigCodes::TrigBitSet,int> > trigCutsCutCodes_; //unsorted vector (may sort if have performance issues)
00081   
00082     //and these are the trigger bits stored
00083     //note that the trigger bits are defined at the begining of each job
00084     //and do not necessaryly map between jobs
00085     TrigCodes::TrigBitSet trigBits_;
00086     
00087   public:
00088     
00089     OffEle(const reco::GsfElectron& ele,const ClusShapeData& shapeData,const IsolData& isolData,const HLTData& hltData):
00090       gsfEle_(&ele),clusShapeData_(shapeData),isolData_(isolData),hltData_(hltData),
00091       cutCode_(int(EgCutCodes::INVALID)),looseCutCode_(int(EgCutCodes::INVALID)){}
00092     ~OffEle(){}
00093     
00094     //modifiers  
00095     void setCutCode(int code){cutCode_=code;}
00096     void setLooseCutCode(int code){looseCutCode_=code;} 
00097     //slightly inefficient way, think I can afford it and its a lot easier to just make the sorted vector outside the class
00098     void setTrigCutsCutCodes(const std::vector<std::pair<TrigCodes::TrigBitSet,int> > trigCutsCutCodes){trigCutsCutCodes_=trigCutsCutCodes;}
00099     void setTrigBits(TrigCodes::TrigBitSet bits){trigBits_=bits;}
00100     
00101     const reco::GsfElectron* gsfEle()const{return gsfEle_;}
00102 
00103     //kinematic and geometric methods
00104     float et()const{return gsfEle_->et();} 
00105     // float et()const{return etSC();}
00106     float energy()const{return gsfEle_->energy();}
00107     float eta()const{return gsfEle_->eta();}
00108     float phi()const{return gsfEle_->phi();}
00109     float etSC()const{return gsfEle_->superCluster()->position().rho()/gsfEle_->superCluster()->position().r()*caloEnergy();}
00110     float caloEnergy()const{return gsfEle_->caloEnergy();}
00111     float etaSC()const{return gsfEle_->superCluster()->eta();}
00112     float detEta()const{return etaSC();}
00113     float phiSC()const{return gsfEle_->superCluster()->phi();}
00114     float zVtx()const{return gsfEle_->TrackPositionAtVtx().z();}
00115     const math::XYZTLorentzVector& p4()const{return gsfEle_->p4();}
00116     
00117     //classification (couldnt they have just named it 'type')
00118     int classification()const{return gsfEle_->classification();}
00119     bool isGap()const{return gsfEle_->isEBGap() || gsfEle_->isEEGap() || gsfEle_->isEBEEGap();}
00120     
00121     //track methods
00122     int charge()const{return gsfEle_->charge();}
00123     float pVtx()const{return gsfEle_->trackMomentumAtVtx().R();}
00124     float pCalo()const{return gsfEle_->trackMomentumAtCalo().R();}
00125     float ptVtx()const{return gsfEle_->trackMomentumAtVtx().rho();}
00126     float ptCalo()const{return gsfEle_->trackMomentumAtCalo().rho();}
00127     
00128     
00129     //abreviations of overly long GsfElectron methods, I'm sorry but if you cant figure out what hOverE() means, you shouldnt be using this class
00130     float hOverE()const{return gsfEle_->hadronicOverEm();}
00131     float dEtaIn()const{return gsfEle_->deltaEtaSuperClusterTrackAtVtx();}
00132     float dPhiIn()const{return gsfEle_->deltaPhiSuperClusterTrackAtVtx();}
00133     float dPhiOut()const{return gsfEle_->deltaPhiSeedClusterTrackAtCalo();} 
00134     float dEtaOut()const{return gsfEle_->deltaEtaSeedClusterTrackAtCalo();}
00135     float epIn()const{return gsfEle_->eSuperClusterOverP();}
00136     float epOut()const{return gsfEle_->eSeedClusterOverPout();}
00137     
00138     //variables with no direct method
00139     float sigmaEtaEta()const;
00140     float sigmaEtaEtaUnCorr()const{return clusShapeData_.sigmaEtaEta;}
00141     float sigmaIEtaIEta()const{return clusShapeData_.sigmaIEtaIEta;}                                    
00142     float sigmaPhiPhi()const{return clusShapeData_.sigmaPhiPhi;}
00143     //float sigmaIPhiIPhi()const{return clusShapeData_.sigmaIPhiIPhi;}
00144     float e2x5MaxOver5x5()const{return clusShapeData_.e2x5MaxOver5x5;}
00145     float e1x5Over5x5()const{return clusShapeData_.e1x5Over5x5;}
00146                                                                         
00147     float r9()const{return clusShapeData_.r9;}
00148     //float sigmaPhiPhi()const{return clusShape_!=NULL ? sqrt(clusShape_->covPhiPhi()) : 999;}
00149     float bremFrac()const{return (pVtx()-pCalo())/pVtx();}
00150     float invEInvP()const{return gsfEle_->caloEnergy()!=0 && gsfEle_->trackMomentumAtVtx().R()!=0. ? 1./gsfEle_->caloEnergy() - 1./gsfEle_->trackMomentumAtVtx().R() : -999;}
00151     //float e9OverE25()const{return clusShape_!=NULL ? clusShape_->e3x3()/clusShape_->e5x5() : -999;}
00152     
00153     //isolation
00154     float isolEm()const{return isolData_.em;}
00155     float isolHad()const{return isolHadDepth1()+isolHadDepth2();}
00156     float isolHadDepth1()const{return isolData_.hadDepth1;}
00157     float isolHadDepth2()const{return isolData_.hadDepth2;}
00158     float isolPtTrks()const{return isolData_.ptTrks;}
00159     int isolNrTrks()const{return isolData_.nrTrks;}
00160     float hltIsolTrksEle()const{return isolData_.hltTrksEle;}
00161     float hltIsolTrksPho()const{return isolData_.hltTrksPho;}
00162     float hltIsolHad()const{return isolData_.hltHad;}
00163     float hltIsolEm()const{return isolData_.hltEm;}
00164     
00165     //some hlt id variables (note these are reco approximations)
00166     float hltDEtaIn()const{return hltData_.dEtaIn;}
00167     float hltDPhiIn()const{return hltData_.dPhiIn;}
00168     float hltInvEInvP()const{return hltData_.invEInvP;}
00169 
00170     //ctf track accessor and validatity checker
00171     reco::TrackRef ctfTrack()const{return gsfEle_->closestCtfTrackRef();} //in theory lightweight (if they follow good design),return by value
00172     //track is only valid if it exists and track extra exists (track extra is only stored in reco)
00173     bool validCTFTrack()const{return gsfEle_->closestCtfTrackRef().isNonnull() && gsfEle_->closestCtfTrackRef()->extra().isNonnull();}
00174     
00175 
00176     //ctf track varibles, used as hlt uses this algo
00177     float ctfTrkP()const{return validCTFTrack() ? ctfTrack()->p() : -999.;}
00178     float ctfTrkPt()const{return validCTFTrack() ? ctfTrack()->pt() : -999.;}
00179     float ctfTrkEta()const{return validCTFTrack() ? ctfTrack()->eta() : -999.;}
00180     float ctfTrkChi2()const{return validCTFTrack() ? ctfTrack()->chi2() : 999.;}
00181     float ctfTrkNDof()const{return validCTFTrack() ? ctfTrack()->ndof() : 999.;} //this will give chi2/ndof a valid value, perhaps rethink
00182     float ctfTrkPtOuter()const{return validCTFTrack() ?  ctfTrack()->outerMomentum().Perp2() : -999.;}
00183     float ctfTrkPtInner()const{return validCTFTrack() ?  ctfTrack()->innerMomentum().Perp2() : -999.;}
00184     float ctfTrkInnerRadius()const{return validCTFTrack() ? ctfTrack()->innerPosition().Rho() : 999.;}
00185     float ctfTrkOuterRadius()const{return validCTFTrack() ? ctfTrack()->outerPosition().Rho() : -999.;}
00186     int ctfTrkHitsFound()const{return validCTFTrack() ? static_cast<int>(ctfTrack()->found()) : -999;}
00187     int ctfTrkHitsLost()const{return validCTFTrack() ? static_cast<int>(ctfTrack()->lost()) : -999;}
00188     int ctfTrkNrHits()const{return validCTFTrack() ? static_cast<int>(ctfTrack()->recHitsSize()) : -999;}
00189 
00190     //selection cuts
00191     int cutCode()const{return cutCode_;}
00192     int looseCutCode()const{return looseCutCode_;}
00193    
00194     
00195     //trigger codes are just used as a unique identifier of the trigger, it is an error to specify more than a single bit
00196     //the idea here is to allow an arbitary number of electron triggers
00197     int trigCutsCutCode(const TrigCodes::TrigBitSet& trigger)const; 
00198     //trigger
00199     TrigCodes::TrigBitSet trigBits()const{return trigBits_;}
00200     
00201     
00202   };
00203 
00204 }
00205 
00206 
00207 
00208 #endif