Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:09:50

0001 #ifndef DQMOFFLINE_TRIGGER_EGHLTOFFELE
0002 #define DQMOFFLINE_TRIGGER_EGHLTOFFELE
0003 
0004 //class: EgHLTOffEle
0005 //
0006 //author: Sam Harper (July 2008)
0007 //
0008 //
0009 //aim: to allow easy access to electron ID variables
0010 //     currently the CMSSW electron classes are a mess with key electron selection variables not being accessable from GsfElectron
0011 //     this a stop gap to produce a simple electron class with all variables easily accessable via methods
0012 //     note as this is meant for HLT Offline DQM, I do not want the overhead of converting to pat
0013 //
0014 //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
0015 //                make this class obsolute
0016 //                unfortunately can not be a pure wrapper as needs to store isol and cluster shape
0017 //
0018 
0019 #include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h"
0020 #include "DataFormats/EgammaReco/interface/ClusterShapeFwd.h"
0021 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
0022 #include "DataFormats/EgammaReco/interface/ClusterShape.h"
0023 #include "DataFormats/TrackReco/interface/Track.h"
0024 
0025 #include "DQMOffline/Trigger/interface/EgHLTEgCutCodes.h"
0026 #include "DQMOffline/Trigger/interface/EgHLTTrigCodes.h"
0027 
0028 namespace egHLT {
0029   class OffEle {
0030   public:
0031     //helper struct to store the isolations
0032     struct IsolData {
0033       float em;
0034       float hadDepth1;
0035       float hadDepth2;
0036       float ptTrks;
0037       int nrTrks;
0038       //possibly going to move these to hlt data
0039       float hltHad;
0040       float hltTrksEle;
0041       float hltTrksPho;
0042       float hltEm;
0043     };
0044 
0045   public:
0046     //helper struct to store the cluster shapes
0047     struct ClusShapeData {
0048       float sigmaEtaEta;
0049       float sigmaIEtaIEta;
0050       float sigmaPhiPhi;
0051       float sigmaIPhiIPhi;
0052       float e1x5Over5x5;
0053       float e2x5MaxOver5x5;
0054       float r9;
0055     };
0056 
0057   public:
0058     //helper struct to store reco approximations of variables made by HLT - and HLT p4 to get eta,phi
0059     struct HLTData {
0060       float dEtaIn;
0061       float dPhiIn;
0062       float invEInvP;
0063       //math::XYZTLorentzVector p4;
0064       float HLTeta;
0065       float HLTphi;
0066       float HLTenergy;
0067     };
0068 
0069   public:
0070     //helper struct to store event-wide variables
0071     struct EventData {
0072       int NVertex;
0073     };
0074 
0075   private:
0076     const reco::GsfElectron* gsfEle_;  //pointers to the underlying electron (we do not own this)
0077 
0078     ClusShapeData clusShapeData_;
0079     IsolData isolData_;
0080     HLTData hltData_;
0081     EventData eventData_;
0082 
0083     //these are bit-packed words telling me which cuts the electron fail (ie 0x0 is passed all cuts)
0084     int cutCode_;
0085     int looseCutCode_;
0086     //the idea is that these are user definable cuts meant to be idenital to the specified trigger
0087     //it is probably clear to the reader that I havent decided on the most efficient way to do this
0088     std::vector<std::pair<TrigCodes::TrigBitSet, int> >
0089         trigCutsCutCodes_;  //unsorted vector (may sort if have performance issues)
0090 
0091     //and these are the trigger bits stored
0092     //note that the trigger bits are defined at the begining of each job
0093     //and do not necessaryly map between jobs
0094     TrigCodes::TrigBitSet trigBits_;
0095 
0096   public:
0097     OffEle(const reco::GsfElectron& ele,
0098            const ClusShapeData& shapeData,
0099            const IsolData& isolData,
0100            const HLTData& hltData,
0101            const EventData& eventData)
0102         : gsfEle_(&ele),
0103           clusShapeData_(shapeData),
0104           isolData_(isolData),
0105           hltData_(hltData),
0106           eventData_(eventData),
0107           cutCode_(int(EgCutCodes::INVALID)),
0108           looseCutCode_(int(EgCutCodes::INVALID)) {}
0109     ~OffEle() = default;
0110 
0111     //modifiers
0112     int NVertex() const { return eventData_.NVertex; }
0113     void setCutCode(int code) { cutCode_ = code; }
0114     void setLooseCutCode(int code) { looseCutCode_ = code; }
0115     //slightly inefficient way, think I can afford it and its a lot easier to just make the sorted vector outside the class
0116     void setTrigCutsCutCodes(const std::vector<std::pair<TrigCodes::TrigBitSet, int> >& trigCutsCutCodes) {
0117       trigCutsCutCodes_ = trigCutsCutCodes;
0118     }
0119     void setTrigBits(TrigCodes::TrigBitSet bits) { trigBits_ = bits; }
0120 
0121     const reco::GsfElectron* gsfEle() const { return gsfEle_; }
0122 
0123     //kinematic and geometric methods
0124     float et() const { return gsfEle_->et(); }
0125     // float et()const{return etSC();}
0126     float energy() const { return gsfEle_->energy(); }
0127     float eta() const { return gsfEle_->eta(); }
0128     float phi() const { return gsfEle_->phi(); }
0129     float etSC() const {
0130       return gsfEle_->superCluster()->position().rho() / gsfEle_->superCluster()->position().r() * caloEnergy();
0131     }
0132     float caloEnergy() const { return gsfEle_->caloEnergy(); }
0133     float etaSC() const { return gsfEle_->superCluster()->eta(); }
0134     float detEta() const { return etaSC(); }
0135     float phiSC() const { return gsfEle_->superCluster()->phi(); }
0136     float zVtx() const { return gsfEle_->TrackPositionAtVtx().z(); }
0137     const math::XYZTLorentzVector& p4() const { return gsfEle_->p4(); }
0138 
0139     //classification (couldnt they have just named it 'type')
0140     int classification() const { return gsfEle_->classification(); }
0141     bool isGap() const { return gsfEle_->isEBGap() || gsfEle_->isEEGap() || gsfEle_->isEBEEGap(); }
0142 
0143     //track methods
0144     int charge() const { return gsfEle_->charge(); }
0145     float pVtx() const { return gsfEle_->trackMomentumAtVtx().R(); }
0146     float pCalo() const { return gsfEle_->trackMomentumAtCalo().R(); }
0147     float ptVtx() const { return gsfEle_->trackMomentumAtVtx().rho(); }
0148     float ptCalo() const { return gsfEle_->trackMomentumAtCalo().rho(); }
0149 
0150     //abreviations of overly long GsfElectron methods, I'm sorry but if you cant figure out what hOverE() means, you shouldnt be using this class
0151     float hOverE() const { return gsfEle_->hadronicOverEm(); }
0152     float dEtaIn() const { return gsfEle_->deltaEtaSuperClusterTrackAtVtx(); }
0153     float dPhiIn() const { return gsfEle_->deltaPhiSuperClusterTrackAtVtx(); }
0154     float dPhiOut() const { return gsfEle_->deltaPhiSeedClusterTrackAtCalo(); }
0155     float dEtaOut() const { return gsfEle_->deltaEtaSeedClusterTrackAtCalo(); }
0156     float epIn() const { return gsfEle_->eSuperClusterOverP(); }
0157     float epOut() const { return gsfEle_->eSeedClusterOverPout(); }
0158 
0159     //variables with no direct method
0160     float sigmaEtaEta() const;
0161     float sigmaEtaEtaUnCorr() const { return clusShapeData_.sigmaEtaEta; }
0162     float sigmaIEtaIEta() const { return clusShapeData_.sigmaIEtaIEta; }
0163     float sigmaPhiPhi() const { return clusShapeData_.sigmaPhiPhi; }
0164     //float sigmaIPhiIPhi()const{return clusShapeData_.sigmaIPhiIPhi;}
0165     float e2x5MaxOver5x5() const { return clusShapeData_.e2x5MaxOver5x5; }
0166     float e1x5Over5x5() const { return clusShapeData_.e1x5Over5x5; }
0167 
0168     float r9() const { return clusShapeData_.r9; }
0169     //float sigmaPhiPhi()const{return clusShape_!=NULL ? sqrt(clusShape_->covPhiPhi()) : 999;}
0170     float bremFrac() const { return (pVtx() - pCalo()) / pVtx(); }
0171     float invEInvP() const {
0172       return gsfEle_->caloEnergy() != 0 && gsfEle_->trackMomentumAtVtx().R() != 0.
0173                  ? 1. / gsfEle_->caloEnergy() - 1. / gsfEle_->trackMomentumAtVtx().R()
0174                  : -999;
0175     }
0176     //float e9OverE25()const{return clusShape_!=NULL ? clusShape_->e3x3()/clusShape_->e5x5() : -999;}
0177 
0178     //isolation
0179     float isolEm() const { return isolData_.em; }
0180     float isolHad() const { return isolHadDepth1() + isolHadDepth2(); }
0181     float isolHadDepth1() const { return isolData_.hadDepth1; }
0182     float isolHadDepth2() const { return isolData_.hadDepth2; }
0183     float isolPtTrks() const { return isolData_.ptTrks; }
0184     int isolNrTrks() const { return isolData_.nrTrks; }
0185     float hltIsolTrksEle() const { return isolData_.hltTrksEle; }
0186     float hltIsolTrksPho() const { return isolData_.hltTrksPho; }
0187     float hltIsolHad() const { return isolData_.hltHad; }
0188     float hltIsolEm() const { return isolData_.hltEm; }
0189 
0190     //some hlt id variables (note these are reco approximations)
0191     float hltDEtaIn() const { return hltData_.dEtaIn; }
0192     float hltDPhiIn() const { return hltData_.dPhiIn; }
0193     float hltInvEInvP() const { return hltData_.invEInvP; }
0194     //hlt position - not a reco approximation, taken from triggerobject
0195     //const math::XYZTLorentzVector& HLTp4()const{return hltData_.p4;}
0196     float hltPhi() const { return hltData_.HLTphi; }
0197     float hltEta() const { return hltData_.HLTeta; }
0198     float hltEnergy() const { return hltData_.HLTenergy; }
0199     //Diference between HLT Et and reco SC Et
0200     float DeltaE() const { return (hltEnergy() - caloEnergy()); }
0201 
0202     //ctf track accessor and validatity checker
0203     reco::TrackRef ctfTrack() const {
0204       return gsfEle_->closestCtfTrackRef();
0205     }  //in theory lightweight (if they follow good design),return by value
0206     //track is only valid if it exists and track extra exists (track extra is only stored in reco)
0207     bool validCTFTrack() const {
0208       return gsfEle_->closestCtfTrackRef().isNonnull() && gsfEle_->closestCtfTrackRef()->extra().isNonnull();
0209     }
0210 
0211     //ctf track varibles, used as hlt uses this algo
0212     float ctfTrkP() const { return validCTFTrack() ? ctfTrack()->p() : -999.; }
0213     float ctfTrkPt() const { return validCTFTrack() ? ctfTrack()->pt() : -999.; }
0214     float ctfTrkEta() const { return validCTFTrack() ? ctfTrack()->eta() : -999.; }
0215     float ctfTrkChi2() const { return validCTFTrack() ? ctfTrack()->chi2() : 999.; }
0216     float ctfTrkNDof() const {
0217       return validCTFTrack() ? ctfTrack()->ndof() : 999.;
0218     }  //this will give chi2/ndof a valid value, perhaps rethink
0219     float ctfTrkPtOuter() const { return validCTFTrack() ? ctfTrack()->outerMomentum().Perp2() : -999.; }
0220     float ctfTrkPtInner() const { return validCTFTrack() ? ctfTrack()->innerMomentum().Perp2() : -999.; }
0221     float ctfTrkInnerRadius() const { return validCTFTrack() ? ctfTrack()->innerPosition().Rho() : 999.; }
0222     float ctfTrkOuterRadius() const { return validCTFTrack() ? ctfTrack()->outerPosition().Rho() : -999.; }
0223     int ctfTrkHitsFound() const { return validCTFTrack() ? static_cast<int>(ctfTrack()->found()) : -999; }
0224     int ctfTrkHitsLost() const { return validCTFTrack() ? static_cast<int>(ctfTrack()->lost()) : -999; }
0225     int ctfTrkNrHits() const { return validCTFTrack() ? static_cast<int>(ctfTrack()->recHitsSize()) : -999; }
0226 
0227     //selection cuts
0228     int cutCode() const { return cutCode_; }
0229     int looseCutCode() const { return looseCutCode_; }
0230 
0231     //trigger codes are just used as a unique identifier of the trigger, it is an error to specify more than a single bit
0232     //the idea here is to allow an arbitary number of electron triggers
0233     int trigCutsCutCode(const TrigCodes::TrigBitSet& trigger) const;
0234     //trigger
0235     TrigCodes::TrigBitSet trigBits() const { return trigBits_; }
0236   };
0237 
0238 }  // namespace egHLT
0239 
0240 #endif