CMS 3D CMS Logo

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