CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/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   public:
00069     //helper struct to store event-wide variables
00070     struct EventData {
00071       int NVertex;
00072     };
00073 
00074   private:
00075     const reco::GsfElectron* gsfEle_; //pointers to the underlying electron (we do not own this)
00076 
00077     ClusShapeData clusShapeData_;
00078     IsolData isolData_;
00079     HLTData hltData_;
00080     EventData eventData_;
00081 
00082     //these are bit-packed words telling me which cuts the electron fail (ie 0x0 is passed all cuts)
00083     int cutCode_;
00084     int looseCutCode_;
00085     //the idea is that these are user definable cuts meant to be idenital to the specified trigger
00086     //it is probably clear to the reader that I havent decided on the most efficient way to do this
00087     std::vector<std::pair<TrigCodes::TrigBitSet,int> > trigCutsCutCodes_; //unsorted vector (may sort if have performance issues)
00088   
00089     //and these are the trigger bits stored
00090     //note that the trigger bits are defined at the begining of each job
00091     //and do not necessaryly map between jobs
00092     TrigCodes::TrigBitSet trigBits_;
00093     
00094   public:
00095     
00096     OffEle(const reco::GsfElectron& ele,const ClusShapeData& shapeData,const IsolData& isolData,const HLTData& hltData,const EventData& eventData):
00097       gsfEle_(&ele),clusShapeData_(shapeData),isolData_(isolData),hltData_(hltData),eventData_(eventData),
00098       cutCode_(int(EgCutCodes::INVALID)),looseCutCode_(int(EgCutCodes::INVALID)){}
00099     ~OffEle(){}
00100     
00101 
00102     //modifiers  
00103     int NVertex()const{return eventData_.NVertex;}
00104     void setCutCode(int code){cutCode_=code;}
00105     void setLooseCutCode(int code){looseCutCode_=code;} 
00106     //slightly inefficient way, think I can afford it and its a lot easier to just make the sorted vector outside the class
00107     void setTrigCutsCutCodes(const std::vector<std::pair<TrigCodes::TrigBitSet,int> > trigCutsCutCodes){trigCutsCutCodes_=trigCutsCutCodes;}
00108     void setTrigBits(TrigCodes::TrigBitSet bits){trigBits_=bits;}
00109     
00110     const reco::GsfElectron* gsfEle()const{return gsfEle_;}
00111 
00112     //kinematic and geometric methods
00113     float et()const{return gsfEle_->et();} 
00114     // float et()const{return etSC();}
00115     float energy()const{return gsfEle_->energy();}
00116     float eta()const{return gsfEle_->eta();}
00117     float phi()const{return gsfEle_->phi();}
00118     float etSC()const{return gsfEle_->superCluster()->position().rho()/gsfEle_->superCluster()->position().r()*caloEnergy();}
00119     float caloEnergy()const{return gsfEle_->caloEnergy();}
00120     float etaSC()const{return gsfEle_->superCluster()->eta();}
00121     float detEta()const{return etaSC();}
00122     float phiSC()const{return gsfEle_->superCluster()->phi();}
00123     float zVtx()const{return gsfEle_->TrackPositionAtVtx().z();}
00124     const math::XYZTLorentzVector& p4()const{return gsfEle_->p4();}
00125     
00126     //classification (couldnt they have just named it 'type')
00127     int classification()const{return gsfEle_->classification();}
00128     bool isGap()const{return gsfEle_->isEBGap() || gsfEle_->isEEGap() || gsfEle_->isEBEEGap();}
00129     
00130     //track methods
00131     int charge()const{return gsfEle_->charge();}
00132     float pVtx()const{return gsfEle_->trackMomentumAtVtx().R();}
00133     float pCalo()const{return gsfEle_->trackMomentumAtCalo().R();}
00134     float ptVtx()const{return gsfEle_->trackMomentumAtVtx().rho();}
00135     float ptCalo()const{return gsfEle_->trackMomentumAtCalo().rho();}
00136     
00137     
00138     //abreviations of overly long GsfElectron methods, I'm sorry but if you cant figure out what hOverE() means, you shouldnt be using this class
00139     float hOverE()const{return gsfEle_->hadronicOverEm();}
00140     float dEtaIn()const{return gsfEle_->deltaEtaSuperClusterTrackAtVtx();}
00141     float dPhiIn()const{return gsfEle_->deltaPhiSuperClusterTrackAtVtx();}
00142     float dPhiOut()const{return gsfEle_->deltaPhiSeedClusterTrackAtCalo();} 
00143     float dEtaOut()const{return gsfEle_->deltaEtaSeedClusterTrackAtCalo();}
00144     float epIn()const{return gsfEle_->eSuperClusterOverP();}
00145     float epOut()const{return gsfEle_->eSeedClusterOverPout();}
00146     
00147     //variables with no direct method
00148     float sigmaEtaEta()const;
00149     float sigmaEtaEtaUnCorr()const{return clusShapeData_.sigmaEtaEta;}
00150     float sigmaIEtaIEta()const{return clusShapeData_.sigmaIEtaIEta;}                                    
00151     float sigmaPhiPhi()const{return clusShapeData_.sigmaPhiPhi;}
00152     //float sigmaIPhiIPhi()const{return clusShapeData_.sigmaIPhiIPhi;}
00153     float e2x5MaxOver5x5()const{return clusShapeData_.e2x5MaxOver5x5;}
00154     float e1x5Over5x5()const{return clusShapeData_.e1x5Over5x5;}
00155                                                                         
00156     float r9()const{return clusShapeData_.r9;}
00157     //float sigmaPhiPhi()const{return clusShape_!=NULL ? sqrt(clusShape_->covPhiPhi()) : 999;}
00158     float bremFrac()const{return (pVtx()-pCalo())/pVtx();}
00159     float invEInvP()const{return gsfEle_->caloEnergy()!=0 && gsfEle_->trackMomentumAtVtx().R()!=0. ? 1./gsfEle_->caloEnergy() - 1./gsfEle_->trackMomentumAtVtx().R() : -999;}
00160     //float e9OverE25()const{return clusShape_!=NULL ? clusShape_->e3x3()/clusShape_->e5x5() : -999;}
00161     
00162     //isolation
00163     float isolEm()const{return isolData_.em;}
00164     float isolHad()const{return isolHadDepth1()+isolHadDepth2();}
00165     float isolHadDepth1()const{return isolData_.hadDepth1;}
00166     float isolHadDepth2()const{return isolData_.hadDepth2;}
00167     float isolPtTrks()const{return isolData_.ptTrks;}
00168     int isolNrTrks()const{return isolData_.nrTrks;}
00169     float hltIsolTrksEle()const{return isolData_.hltTrksEle;}
00170     float hltIsolTrksPho()const{return isolData_.hltTrksPho;}
00171     float hltIsolHad()const{return isolData_.hltHad;}
00172     float hltIsolEm()const{return isolData_.hltEm;}
00173     
00174     //some hlt id variables (note these are reco approximations)
00175     float hltDEtaIn()const{return hltData_.dEtaIn;}
00176     float hltDPhiIn()const{return hltData_.dPhiIn;}
00177     float hltInvEInvP()const{return hltData_.invEInvP;}
00178 
00179     //ctf track accessor and validatity checker
00180     reco::TrackRef ctfTrack()const{return gsfEle_->closestCtfTrackRef();} //in theory lightweight (if they follow good design),return by value
00181     //track is only valid if it exists and track extra exists (track extra is only stored in reco)
00182     bool validCTFTrack()const{return gsfEle_->closestCtfTrackRef().isNonnull() && gsfEle_->closestCtfTrackRef()->extra().isNonnull();}
00183     
00184 
00185     //ctf track varibles, used as hlt uses this algo
00186     float ctfTrkP()const{return validCTFTrack() ? ctfTrack()->p() : -999.;}
00187     float ctfTrkPt()const{return validCTFTrack() ? ctfTrack()->pt() : -999.;}
00188     float ctfTrkEta()const{return validCTFTrack() ? ctfTrack()->eta() : -999.;}
00189     float ctfTrkChi2()const{return validCTFTrack() ? ctfTrack()->chi2() : 999.;}
00190     float ctfTrkNDof()const{return validCTFTrack() ? ctfTrack()->ndof() : 999.;} //this will give chi2/ndof a valid value, perhaps rethink
00191     float ctfTrkPtOuter()const{return validCTFTrack() ?  ctfTrack()->outerMomentum().Perp2() : -999.;}
00192     float ctfTrkPtInner()const{return validCTFTrack() ?  ctfTrack()->innerMomentum().Perp2() : -999.;}
00193     float ctfTrkInnerRadius()const{return validCTFTrack() ? ctfTrack()->innerPosition().Rho() : 999.;}
00194     float ctfTrkOuterRadius()const{return validCTFTrack() ? ctfTrack()->outerPosition().Rho() : -999.;}
00195     int ctfTrkHitsFound()const{return validCTFTrack() ? static_cast<int>(ctfTrack()->found()) : -999;}
00196     int ctfTrkHitsLost()const{return validCTFTrack() ? static_cast<int>(ctfTrack()->lost()) : -999;}
00197     int ctfTrkNrHits()const{return validCTFTrack() ? static_cast<int>(ctfTrack()->recHitsSize()) : -999;}
00198 
00199     //selection cuts
00200     int cutCode()const{return cutCode_;}
00201     int looseCutCode()const{return looseCutCode_;}
00202    
00203     
00204     //trigger codes are just used as a unique identifier of the trigger, it is an error to specify more than a single bit
00205     //the idea here is to allow an arbitary number of electron triggers
00206     int trigCutsCutCode(const TrigCodes::TrigBitSet& trigger)const; 
00207     //trigger
00208     TrigCodes::TrigBitSet trigBits()const{return trigBits_;}
00209     
00210     
00211   };
00212 
00213 }
00214 
00215 
00216 
00217 #endif