Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:50:17

0001 #ifndef HeavyFlavorAnalysis_RecoDecay_BPHTrackReference_h
0002 #define HeavyFlavorAnalysis_RecoDecay_BPHTrackReference_h
0003 /** \class BPHTrackReference
0004  *
0005  *  Description: 
0006  *     class to have uniform access to reco::Track
0007  *     for different particle objects
0008  *
0009  *  \author Paolo Ronchese INFN Padova
0010  *
0011  */
0012 
0013 //----------------------
0014 // Base Class Headers --
0015 //----------------------
0016 
0017 //------------------------------------
0018 // Collaborating Class Declarations --
0019 //------------------------------------
0020 #include "DataFormats/TrackReco/interface/Track.h"
0021 #include "DataFormats/RecoCandidate/interface/RecoCandidate.h"
0022 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0023 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0024 #include "DataFormats/PatCandidates/interface/GenericParticle.h"
0025 #include "DataFormats/PatCandidates/interface/Muon.h"
0026 #include "DataFormats/PatCandidates/interface/Electron.h"
0027 
0028 //---------------
0029 // C++ Headers --
0030 //---------------
0031 
0032 //              ---------------------
0033 //              -- Class Interface --
0034 //              ---------------------
0035 
0036 class BPHTrackReference {
0037 public:
0038   typedef pat::PackedCandidate candidate;
0039 
0040   /** Only static functions, no data member
0041    */
0042 
0043   /** Operations
0044    */
0045   /// get associated reco::Track calling a sequence of functions
0046   /// until a track is found; the list of functions to call is given
0047   /// as a string where each character identify a function:
0048   /// c :  reco ::       Candidate ::        get<reco::TrackRef> ()
0049   /// f :  reco ::     PFCandidate ::                  trackRef  ()
0050   /// h :   pat :: GenericParticle ::                  track     ()
0051   /// b :  reco ::       Candidate ::              bestTrack     ()
0052   /// p :   pat :: PackedCandidate ::            pseudoTrack     ()
0053   /// m :   pat ::            Muon ::pfCandidateRef()::trackRef  ()
0054   /// n :   pat ::            Muon ::          muonBestTrack     ()
0055   /// i :   pat ::            Muon ::             innerTrack     ()
0056   /// g :   pat ::            Muon ::            globalTrack     ()
0057   /// s :   pat ::            Muon ::             standAloneMuon ()
0058   /// e :   pat ::        Electron ::pfCandidateRef()::trackRef  ()
0059   /// t :   pat ::        Electron ::        closestCtfTrackRef  ()
0060   static const reco::Track* getTrack(const reco::Candidate& rc,
0061                                      const char* modeList = "cfhbpmnigset",
0062                                      char* modeFlag = nullptr) {
0063     if (rc.charge() == 0)
0064       return nullptr;
0065     const char* mptr = modeList;
0066     char c;
0067     if (modeFlag == nullptr)
0068       modeFlag = &c;
0069     char& mode = *modeFlag;
0070     const reco::Track* tkp = nullptr;
0071     while ((mode = *mptr++)) {
0072       switch (mode) {
0073         case 'c':
0074           if ((tkp = getFromRC(rc)) != nullptr)
0075             return tkp;
0076           break;
0077         case 'f':
0078           if ((tkp = getFromPF(rc)) != nullptr)
0079             return tkp;
0080           break;
0081         case 'h':
0082           if ((tkp = getFromGP(rc)) != nullptr)
0083             return tkp;
0084           break;
0085         case 'b':
0086           if ((tkp = getFromBT(rc)) != nullptr)
0087             return tkp;
0088           break;
0089         case 'p':
0090           if ((tkp = getFromPC(rc)) != nullptr)
0091             return tkp;
0092           break;
0093         case 'm':
0094           if ((tkp = getMuonPF(rc)) != nullptr)
0095             return tkp;
0096           break;
0097         case 'n':
0098           if ((tkp = getMuonBT(rc)) != nullptr)
0099             return tkp;
0100           break;
0101         case 'i':
0102           if ((tkp = getMuonIT(rc)) != nullptr)
0103             return tkp;
0104           break;
0105         case 'g':
0106           if ((tkp = getMuonGT(rc)) != nullptr)
0107             return tkp;
0108           break;
0109         case 's':
0110           if ((tkp = getMuonSA(rc)) != nullptr)
0111             return tkp;
0112           break;
0113         case 'e':
0114           if ((tkp = getElecPF(rc)) != nullptr)
0115             return tkp;
0116           break;
0117         case 't':
0118           if ((tkp = getElecTC(rc)) != nullptr)
0119             return tkp;
0120           break;
0121       }
0122     }
0123     return nullptr;
0124   }
0125 
0126   static const reco::Track* getFromRC(const reco::Candidate& rc) {
0127     try {
0128       const reco::TrackRef& tkr = rc.get<reco::TrackRef>();
0129       if (tkr.isNonnull() && tkr.isAvailable())
0130         return tkr.get();
0131     } catch (edm::Exception const&) {
0132     }
0133     return nullptr;
0134   }
0135   static const reco::Track* getFromPF(const reco::Candidate& rc) {
0136     const reco::PFCandidate* pf = dynamic_cast<const reco::PFCandidate*>(&rc);
0137     if (pf == nullptr)
0138       return nullptr;
0139     try {
0140       const reco::TrackRef& tkr = pf->trackRef();
0141       if (tkr.isNonnull() && tkr.isAvailable())
0142         return tkr.get();
0143     } catch (edm::Exception const&) {
0144     }
0145     return nullptr;
0146   }
0147   static const reco::Track* getFromGP(const reco::Candidate& rc) {
0148     const pat::GenericParticle* gp = dynamic_cast<const pat::GenericParticle*>(&rc);
0149     if (gp == nullptr)
0150       return nullptr;
0151     try {
0152       const reco::TrackRef& tkr = gp->track();
0153       if (tkr.isNonnull() && tkr.isAvailable())
0154         return tkr.get();
0155     } catch (edm::Exception const&) {
0156     }
0157     return nullptr;
0158   }
0159   static const reco::Track* getFromBT(const reco::Candidate& rc) {
0160     try {
0161       const reco::Track* trk = rc.bestTrack();
0162       return trk;
0163     } catch (edm::Exception const&) {
0164     }
0165     return nullptr;
0166   }
0167   static const reco::Track* getFromPC(const reco::Candidate& rc) {
0168     const pat::PackedCandidate* pp = dynamic_cast<const pat::PackedCandidate*>(&rc);
0169     if (pp == nullptr)
0170       return nullptr;
0171     try {
0172       const reco::Track* trk = &pp->pseudoTrack();
0173       return trk;
0174     } catch (edm::Exception const&) {
0175     }
0176     return nullptr;
0177   }
0178   static const reco::Track* getMuonPF(const reco::Candidate& rc) {
0179     const pat::Muon* mu = dynamic_cast<const pat::Muon*>(&rc);
0180     if (mu == nullptr)
0181       return nullptr;
0182     return getMuonPF(mu);
0183   }
0184   static const reco::Track* getMuonPF(const pat::Muon* mu) {
0185     try {
0186       const reco::PFCandidateRef& pcr = mu->pfCandidateRef();
0187       if (pcr.isNonnull() && pcr.isAvailable()) {
0188         const reco::TrackRef& tkr = pcr->trackRef();
0189         if (tkr.isNonnull() && tkr.isAvailable())
0190           return tkr.get();
0191       }
0192     } catch (edm::Exception const&) {
0193     }
0194     return nullptr;
0195   }
0196   static const reco::Track* getMuonBT(const reco::Candidate& rc) {
0197     const reco::Muon* mu = dynamic_cast<const reco::Muon*>(&rc);
0198     if (mu == nullptr)
0199       return nullptr;
0200     return getMuonBT(mu);
0201   }
0202   static const reco::Track* getMuonBT(const reco::Muon* mu) {
0203     try {
0204       const reco::TrackRef& tkr = mu->muonBestTrack();
0205       if (tkr.isNonnull() && tkr.isAvailable())
0206         return tkr.get();
0207     } catch (edm::Exception const&) {
0208     }
0209     return nullptr;
0210   }
0211   static const reco::Track* getMuonIT(const reco::Candidate& rc) {
0212     const pat::Muon* mu = dynamic_cast<const pat::Muon*>(&rc);
0213     if (mu == nullptr)
0214       return nullptr;
0215     return getMuonIT(mu);
0216   }
0217   static const reco::Track* getMuonIT(const pat::Muon* mu) {
0218     if (!mu->isTrackerMuon())
0219       return nullptr;
0220     try {
0221       const reco::TrackRef& mit = mu->innerTrack();
0222       if (mit.isNonnull() && mit.isAvailable())
0223         return mit.get();
0224     } catch (edm::Exception const&) {
0225     }
0226     return nullptr;
0227   }
0228   static const reco::Track* getMuonGT(const reco::Candidate& rc) {
0229     const pat::Muon* mu = dynamic_cast<const pat::Muon*>(&rc);
0230     if (mu == nullptr)
0231       return nullptr;
0232     return getMuonGT(mu);
0233   }
0234   static const reco::Track* getMuonGT(const pat::Muon* mu) {
0235     if (!mu->isGlobalMuon())
0236       return nullptr;
0237     try {
0238       const reco::TrackRef& mgt = mu->globalTrack();
0239       if (mgt.isNonnull() && mgt.isAvailable())
0240         return mgt.get();
0241     } catch (edm::Exception const&) {
0242     }
0243     return nullptr;
0244   }
0245   static const reco::Track* getMuonSA(const reco::Candidate& rc) {
0246     const pat::Muon* mu = dynamic_cast<const pat::Muon*>(&rc);
0247     if (mu == nullptr)
0248       return nullptr;
0249     return getMuonSA(mu);
0250   }
0251   static const reco::Track* getMuonSA(const pat::Muon* mu) {
0252     if (!mu->isStandAloneMuon())
0253       return nullptr;
0254     try {
0255       const reco::TrackRef& msa = mu->standAloneMuon();
0256       if (msa.isNonnull() && msa.isAvailable())
0257         return msa.get();
0258     } catch (edm::Exception const&) {
0259     }
0260     return nullptr;
0261   }
0262   static const reco::Track* getElecPF(const reco::Candidate& rc) {
0263     const pat::Electron* el = dynamic_cast<const pat::Electron*>(&rc);
0264     if (el == nullptr)
0265       return nullptr;
0266     return getElecPF(el);
0267   }
0268   static const reco::Track* getElecPF(const pat::Electron* el) {
0269     try {
0270       const reco::PFCandidateRef& pcr = el->pfCandidateRef();
0271       if (pcr.isNonnull() && pcr.isAvailable()) {
0272         const reco::TrackRef& tkr = pcr->trackRef();
0273         if (tkr.isNonnull() && tkr.isAvailable())
0274           return tkr.get();
0275       }
0276     } catch (edm::Exception const&) {
0277     }
0278     return nullptr;
0279   }
0280   static const reco::Track* getElecTC(const reco::Candidate& rc) {
0281     const pat::Electron* el = dynamic_cast<const pat::Electron*>(&rc);
0282     if (el == nullptr)
0283       return nullptr;
0284     return getElecTC(el);
0285   }
0286   static const reco::Track* getElecTC(const pat::Electron* el) {
0287     try {
0288       // Return the ctftrack closest to the electron
0289       const reco::TrackRef& tkr = el->closestCtfTrackRef();
0290       if (tkr.isNonnull() && tkr.isAvailable())
0291         return tkr.get();
0292     } catch (edm::Exception const&) {
0293     }
0294     return nullptr;
0295   }
0296 };
0297 
0298 #endif