Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:04:49

0001 #ifndef ParticleFlowCandidate_PFCandidate_h
0002 #define ParticleFlowCandidate_PFCandidate_h
0003 /** \class reco::PFCandidate
0004  *
0005  * particle candidate from particle flow
0006  *
0007  */
0008 
0009 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
0010 #include <atomic>
0011 #endif
0012 #include <iosfwd>
0013 #include <array>
0014 
0015 #include "DataFormats/Math/interface/Point3D.h"
0016 
0017 #include "DataFormats/Candidate/interface/CompositeCandidate.h"
0018 #include "DataFormats/ParticleFlowReco/interface/PFBlockFwd.h"
0019 #include "DataFormats/TrackReco/interface/TrackFwd.h"
0020 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
0021 #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
0022 #include "DataFormats/MuonReco/interface/Muon.h"
0023 #include "DataFormats/MuonReco/interface/MuonFwd.h"
0024 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
0025 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateElectronExtraFwd.h"
0026 #include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h"
0027 #include "DataFormats/ParticleFlowReco/interface/PFDisplacedVertexFwd.h"
0028 #include "DataFormats/EgammaCandidates/interface/ConversionFwd.h"
0029 #include "DataFormats/Candidate/interface/VertexCompositeCandidate.h"
0030 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidatePhotonExtraFwd.h"
0031 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateEGammaExtraFwd.h"
0032 #include "DataFormats/EgammaCandidates/interface/PhotonFwd.h"
0033 namespace reco {
0034   /**\class PFCandidate
0035      \brief Particle reconstructed by the particle flow algorithm.
0036           
0037      \author Colin Bernet
0038      \date   February 2007
0039   */
0040 
0041   class PFCandidate : public CompositeCandidate {
0042   public:
0043     /// particle types
0044     enum ParticleType {
0045       X = 0,     // undefined
0046       h,         // charged hadron
0047       e,         // electron
0048       mu,        // muon
0049       gamma,     // photon
0050       h0,        // neutral hadron
0051       h_HF,      // HF tower identified as a hadron
0052       egamma_HF  // HF tower identified as an EM particle
0053     };
0054 
0055     enum Flags {
0056       NORMAL = 0,
0057       E_PHI_SMODULES,
0058       E_ETA_0,
0059       E_ETA_MODULES,
0060       E_BARREL_ENDCAP,
0061       E_PRESHOWER_EDGE,
0062       E_PRESHOWER,
0063       E_ENDCAP_EDGE,
0064       H_ETA_0,
0065       H_BARREL_ENDCAP,
0066       H_ENDCAP_VFCAL,
0067       H_VFCAL_EDGE,
0068       T_TO_DISP,
0069       T_FROM_DISP,
0070       T_FROM_V0,
0071       T_FROM_GAMMACONV,
0072       GAMMA_TO_GAMMACONV
0073     };
0074 
0075     enum PFVertexType {
0076       kCandVertex = 0,
0077       kTrkVertex = 1,
0078       kComMuonVertex = 2,
0079       kSAMuonVertex = 3,
0080       kTrkMuonVertex = 4,
0081       kGSFVertex = 5,
0082       kTPFMSMuonVertex = 6,
0083       kPickyMuonVertex = 7,
0084       kDYTMuonVertex = 8
0085     };
0086 
0087     /// default constructor
0088     PFCandidate();
0089 
0090     /// constructor from a reference (keeps track of source relationship)
0091     PFCandidate(const PFCandidatePtr& sourcePtr);
0092 
0093     /*     PFCandidate( Charge q,  */
0094     /*                  const LorentzVector & p4,  */
0095     /*                  ParticleType particleId,  */
0096     /*                  reco::PFBlockRef blockRef ); */
0097     PFCandidate(Charge q, const LorentzVector& p4, ParticleType particleId);
0098 
0099     /// copy constructor
0100     PFCandidate(const PFCandidate&);
0101 
0102     /// destructor
0103     ~PFCandidate() override;
0104 
0105     PFCandidate& operator=(PFCandidate const&);
0106 
0107     /// return a clone
0108     PFCandidate* clone() const override;
0109 
0110     /*    /// set source ref */
0111     /*     void setSourceRef(const PFCandidateRef& ref) { sourceRef_ = ref; } */
0112 
0113     /*     size_type numberOfSourceCandidateRefs() const {return 1;} */
0114 
0115     /*     CandidateBaseRef sourceCandidateRef( size_type i ) const { */
0116     /*       return  CandidateBaseRef(sourceRef_); */
0117     /*     } */
0118 
0119     using reco::Candidate::setSourceCandidatePtr;
0120     void setSourceCandidatePtr(const PFCandidatePtr& ptr) { sourcePtr_ = ptr; }
0121 
0122     size_t numberOfSourceCandidatePtrs() const override { return 1; }
0123 
0124     CandidatePtr sourceCandidatePtr(size_type i) const override { return sourcePtr_; }
0125 
0126     /// returns the pdg id corresponding to the particle type.
0127     /// the particle type could be removed at some point to gain some space.
0128     /// low priority
0129     int translateTypeToPdgId(ParticleType type) const;
0130     ParticleType translatePdgIdToType(int pdgid) const;
0131 
0132     /// set Particle Type
0133     void setParticleType(ParticleType type);
0134 
0135     /// add an element to the current PFCandidate
0136     /*     void addElement( const reco::PFBlockElement* element ); */
0137 
0138     /// add element in block
0139     void addElementInBlock(const reco::PFBlockRef& blockref, unsigned elementIndex);
0140 
0141     /// set track reference
0142     void setTrackRef(const reco::TrackRef& ref);
0143 
0144     /// return a reference to the corresponding track, if charged.
0145     /// otherwise, return a null reference
0146     reco::TrackRef trackRef() const;
0147 
0148     /// return a pointer to the best track, if available.
0149     /// otherwise, return a null pointer
0150     const reco::Track* bestTrack() const override {
0151       if ((abs(pdgId()) == 11 || pdgId() == 22) && gsfTrackRef().isNonnull() && gsfTrackRef().isAvailable())
0152         return &(*gsfTrackRef());
0153       else if (trackRef().isNonnull() && trackRef().isAvailable())
0154         return &(*trackRef());
0155       else
0156         return nullptr;
0157     }
0158     /// uncertainty on dz
0159     float dzError() const override {
0160       const Track* tr = bestTrack();
0161       if (tr != nullptr)
0162         return tr->dzError();
0163       else
0164         return 0;
0165     }
0166     /// uncertainty on dxy
0167     float dxyError() const override {
0168       const Track* tr = bestTrack();
0169       if (tr != nullptr)
0170         return tr->dxyError();
0171       else
0172         return 0;
0173     }
0174 
0175     /// set gsftrack reference
0176     void setGsfTrackRef(const reco::GsfTrackRef& ref);
0177 
0178     /// return a reference to the corresponding GSF track, if an electron.
0179     /// otherwise, return a null reference
0180     reco::GsfTrackRef gsfTrackRef() const;
0181 
0182     /// set muon reference
0183     void setMuonRef(const reco::MuonRef& ref);
0184 
0185     /// return a reference to the corresponding muon, if a muon.
0186     /// otherwise, return a null reference
0187     reco::MuonRef muonRef() const;
0188 
0189     /// set displaced vertex reference
0190     void setDisplacedVertexRef(const reco::PFDisplacedVertexRef& ref, Flags flag);
0191 
0192     /// return a reference to the corresponding displaced vertex,
0193     /// otherwise, return a null reference
0194     reco::PFDisplacedVertexRef displacedVertexRef(Flags type) const;
0195 
0196     /// set ref to original reco conversion
0197     void setConversionRef(const reco::ConversionRef& ref);
0198 
0199     /// return a reference to the original conversion
0200     reco::ConversionRef conversionRef() const;
0201 
0202     /// set ref to original reco conversion
0203     void setV0Ref(const reco::VertexCompositeCandidateRef& ref);
0204 
0205     /// return a reference to the original conversion
0206     reco::VertexCompositeCandidateRef v0Ref() const;
0207 
0208     /// return a reference to the corresponding GsfElectron if any
0209     reco::GsfElectronRef gsfElectronRef() const;
0210 
0211     /// return a reference to the electron extra
0212     reco::PFCandidateElectronExtraRef electronExtraRef() const;
0213 
0214     /// set corrected Ecal energy
0215     void setEcalEnergy(float eeRaw, float eeCorr) {
0216       rawEcalEnergy_ = eeRaw;
0217       ecalERatio_ = std::abs(eeRaw) < 1.e-6 ? 1.0 : eeCorr / eeRaw;
0218     }
0219 
0220     /// return corrected Ecal energy
0221     double ecalEnergy() const { return ecalERatio_ * rawEcalEnergy_; }
0222 
0223     /// return corrected Ecal energy
0224     double rawEcalEnergy() const { return rawEcalEnergy_; }
0225 
0226     /// set corrected Hcal energy
0227     void setHcalEnergy(float ehRaw, float ehCorr) {
0228       rawHcalEnergy_ = ehRaw;
0229       hcalERatio_ = std::abs(ehRaw) < 1.e-6 ? 1.0 : ehCorr / ehRaw;
0230     }
0231 
0232     /// return corrected Hcal energy
0233     double hcalEnergy() const { return hcalERatio_ * rawHcalEnergy_; }
0234 
0235     /// return raw Hcal energy
0236     double rawHcalEnergy() const { return rawHcalEnergy_; }
0237 
0238     /// set corrected Hcal energy
0239     void setHoEnergy(float eoRaw, float eoCorr) {
0240       rawHoEnergy_ = eoRaw;
0241       hoERatio_ = std::abs(eoRaw) < 1.e-6 ? 1.0 : eoCorr / eoRaw;
0242     }
0243 
0244     /// return corrected Hcal energy
0245     double hoEnergy() const { return hoERatio_ * rawHoEnergy_; }
0246 
0247     /// return raw Hcal energy
0248     double rawHoEnergy() const { return rawHoEnergy_; }
0249 
0250     /// set GsfElectronRef
0251     void setGsfElectronRef(const reco::GsfElectronRef& ref);
0252 
0253     void setSuperClusterRef(const reco::SuperClusterRef& scRef);
0254 
0255     /// return a reference to the corresponding SuperCluster if any
0256     reco::SuperClusterRef superClusterRef() const;
0257 
0258     /// set ref to the corresponding reco::Photon if any
0259     void setPhotonRef(const reco::PhotonRef& phRef);
0260 
0261     /// return a reference to the corresponding Photon if any
0262     reco::PhotonRef photonRef() const;
0263 
0264     /// set the PF Photon Extra Ref
0265     void setPFPhotonExtraRef(const reco::PFCandidatePhotonExtraRef& ref);
0266 
0267     /// return a reference to the photon extra
0268     reco::PFCandidatePhotonExtraRef photonExtraRef() const;
0269 
0270     /// set the PF EGamma Extra Ref
0271     void setPFEGammaExtraRef(const reco::PFCandidateEGammaExtraRef& ref);
0272 
0273     /// return a reference to the EGamma extra
0274     reco::PFCandidateEGammaExtraRef egammaExtraRef() const;
0275 
0276     /// set corrected PS1 energy
0277     void setPs1Energy(float e1) { ps1Energy_ = e1; }
0278 
0279     /// return corrected PS1 energy
0280     double pS1Energy() const { return ps1Energy_; }
0281 
0282     /// set corrected PS2 energy
0283     void setPs2Energy(float e2) { ps2Energy_ = e2; }
0284 
0285     /// return corrected PS2 energy
0286     double pS2Energy() const { return ps2Energy_; }
0287 
0288     /// particle momentum *= rescaleFactor
0289     void rescaleMomentum(double rescaleFactor);
0290 
0291     /// set a given flag
0292     void setFlag(Flags theFlag, bool value);
0293 
0294     /// return a given flag
0295     bool flag(Flags theFlag) const;
0296 
0297     /// set uncertainty on momentum
0298     void setDeltaP(double dp) { deltaP_ = dp; }
0299 
0300     /// uncertainty on 3-momentum
0301     double deltaP() const { return deltaP_; }
0302 
0303     //  int pdgId() const { return translateTypeToPdgId( particleId_ ); }
0304 
0305     /// set mva for electron-pion discrimination.
0306     /// For charged particles, this variable is set
0307     ///   to 0 for particles that are not preided
0308     ///   to 1 otherwise
0309     /// For neutral particles, it is set to the default value
0310 
0311     void set_mva_Isolated(float mvaI) { mva_Isolated_ = mvaI; }
0312     // mva for isolated electrons
0313     float mva_Isolated() const { return mva_Isolated_; }
0314 
0315     void set_mva_e_pi(float mvaNI) { mva_e_pi_ = mvaNI; }
0316     /// mva for electron-pion discrimination
0317     float mva_e_pi() const { return mva_e_pi_; }
0318 
0319     /// set mva for electron-muon discrimination
0320     void set_mva_e_mu(float mva) { mva_e_mu_ = mva; }
0321 
0322     /// mva for electron-muon discrimination
0323     float mva_e_mu() const { return mva_e_mu_; }
0324 
0325     /// set mva for pi-muon discrimination
0326     void set_mva_pi_mu(float mva) { mva_pi_mu_ = mva; }
0327 
0328     /// mva for pi-muon discrimination
0329     float mva_pi_mu() const { return mva_pi_mu_; }
0330 
0331     /// set mva for gamma detection
0332     void set_mva_nothing_gamma(float mva) { mva_nothing_gamma_ = mva; }
0333 
0334     /// mva for gamma detection
0335     float mva_nothing_gamma() const { return mva_nothing_gamma_; }
0336 
0337     /// set mva for neutral hadron detection
0338     void set_mva_nothing_nh(float mva) { mva_nothing_nh_ = mva; }
0339 
0340     /// mva for neutral hadron detection
0341     float mva_nothing_nh() const { return mva_nothing_nh_; }
0342 
0343     /// set mva for neutral hadron - gamma discrimination
0344     void set_mva_gamma_nh(float mva) { mva_gamma_nh_ = mva; }
0345 
0346     // set DNN for electron PFID
0347     // mva for ele PFID DNN sigIsolated class
0348     float dnn_e_sigIsolated() const { return dnn_e_sigIsolated_; }
0349     void set_dnn_e_sigIsolated(float mva) { dnn_e_sigIsolated_ = mva; }
0350 
0351     // mva for ele PFID DNN sigNonIsolated class
0352     float dnn_e_sigNonIsolated() const { return dnn_e_sigNonIsolated_; }
0353     void set_dnn_e_sigNonIsolated(float mva) { dnn_e_sigNonIsolated_ = mva; }
0354 
0355     // mva for ele PFID DNN bkgNonIsolated class
0356     float dnn_e_bkgNonIsolated() const { return dnn_e_bkgNonIsolated_; }
0357     void set_dnn_e_bkgNonIsolated(float mva) { dnn_e_bkgNonIsolated_ = mva; }
0358 
0359     // mva for ele PFID DNN bkgTau class
0360     float dnn_e_bkgTau() const { return dnn_e_bkgTau_; }
0361     void set_dnn_e_bkgTau(float mva) { dnn_e_bkgTau_ = mva; }
0362 
0363     // mva for ele PFID DNN bkgPhoton class
0364     float dnn_e_bkgPhoton() const { return dnn_e_bkgPhoton_; }
0365     void set_dnn_e_bkgPhoton(float mva) { dnn_e_bkgPhoton_ = mva; }
0366 
0367     // set DNN for gamma PFID
0368     float dnn_gamma() const { return dnn_gamma_; }
0369     void set_dnn_gamma(float mva) { dnn_gamma_ = mva; }
0370 
0371     /// mva for neutral hadron - gamma discrimination
0372     float mva_gamma_nh() const { return mva_gamma_nh_; }
0373 
0374     /// set position at ECAL entrance
0375     void setPositionAtECALEntrance(const math::XYZPointF& pos) { positionAtECALEntrance_ = pos; }
0376 
0377     /// set the PF Electron Extra Ref
0378     void setPFElectronExtraRef(const reco::PFCandidateElectronExtraRef& ref);
0379 
0380     /// set the Best Muon Track Ref
0381     void setMuonTrackType(const reco::Muon::MuonTrackType& type) { muonTrackType_ = type; }
0382 
0383     /// get the Best Muon Track Ref
0384 
0385     const reco::Muon::MuonTrackType bestMuonTrackType() const { return muonTrackType_; }
0386 
0387     /// \return position at ECAL entrance
0388     const math::XYZPointF& positionAtECALEntrance() const { return positionAtECALEntrance_; }
0389 
0390     /// particle identification code
0391     /// \todo use Particle::pdgId_ and remove this data member
0392     virtual ParticleType particleId() const { return translatePdgIdToType(pdgId()); }
0393 
0394     /// return indices of elements used in the block
0395     /*     const std::vector<unsigned>& elementIndices() const {  */
0396     /*       return elementIndices_; */
0397     /*     } */
0398     /// return elements
0399     /*     const edm::OwnVector< reco::PFBlockElement >& elements() const  */
0400     /*       {return elements_;} */
0401 
0402     /// return elements in blocks
0403     typedef std::pair<reco::PFBlockRef, unsigned> ElementInBlock;
0404     typedef std::vector<ElementInBlock> ElementsInBlocks;
0405 
0406     typedef edm::RefVector<reco::PFBlockCollection> Blocks;
0407     typedef std::vector<unsigned> Elements;
0408 
0409     const ElementsInBlocks& elementsInBlocks() const;
0410 
0411     static constexpr float bigMva_ = -999.;
0412 
0413     friend std::ostream& operator<<(std::ostream& out, const PFCandidate& c);
0414 
0415     const Point& vertex() const override;
0416     double vx() const override { return vertex().x(); }
0417     double vy() const override { return vertex().y(); }
0418     double vz() const override { return vertex().z(); }
0419 
0420     /// do we have a valid time information
0421     bool isTimeValid() const { return timeError_ >= 0.f; }
0422     /// \return the timing
0423     float time() const { return time_; }
0424     /// \return the timing uncertainty
0425     float timeError() const { return timeError_; }
0426     /// \set the timing information
0427     void setTime(float time, float timeError = 0.f) {
0428       time_ = time;
0429       timeError_ = timeError;
0430     }
0431 
0432     /// fraction of hcal energy at a given depth  (depth = 1 .. 7)
0433     float hcalDepthEnergyFraction(unsigned int depth) const { return hcalDepthEnergyFractions_[depth - 1]; }
0434     /// fraction of hcal energy at a given depth (index 0..6 for depth 1..7)
0435     const std::array<float, 7>& hcalDepthEnergyFractions() const { return hcalDepthEnergyFractions_; }
0436     /// set the fraction of hcal energy as function of depth (index 0..6 for depth 1..7)
0437     void setHcalDepthEnergyFractions(const std::array<float, 7>& fracs) { hcalDepthEnergyFractions_ = fracs; }
0438 
0439   private:
0440     //function used before PR #31456, retained for backwards compatibility with old AOD where the vertex was not embedded
0441     const math::XYZPoint& vertexLegacy(PFCandidate::PFVertexType vertexType) const;
0442 
0443     /// Polymorphic overlap
0444     bool overlap(const Candidate&) const override;
0445 
0446     void setFlag(unsigned shift, unsigned flag, bool value);
0447 
0448     bool flag(unsigned shift, unsigned flag) const;
0449 
0450 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
0451     mutable std::atomic<ElementsInBlocks*> elementsInBlocks_;
0452 #else
0453     mutable ElementsInBlocks* elementsInBlocks_;
0454 #endif
0455     Blocks blocksStorage_;
0456     Elements elementsStorage_;
0457 
0458     /// reference to the source PFCandidate, if any
0459     /*     PFCandidateRef sourceRef_; */
0460     PFCandidatePtr sourcePtr_;
0461 
0462     ///Reference to the best track if it is a muon
0463     ///pF is allowed to switch the default muon track
0464     reco::Muon::MuonTrackType muonTrackType_;
0465 
0466     /// corrected ECAL energy ratio (corrected/raw)
0467     float ecalERatio_;
0468 
0469     /// corrected HCAL energy ratio (corrected/raw)
0470     float hcalERatio_;
0471 
0472     /// corrected HO energy ratio (corrected/raw)
0473     float hoERatio_;
0474 
0475     /// raw ECAL energy
0476     float rawEcalEnergy_;
0477 
0478     /// raw HCAL energy
0479     float rawHcalEnergy_;
0480 
0481     /// raw HO energy
0482     float rawHoEnergy_;
0483 
0484     /// corrected PS1 energy
0485     float ps1Energy_;
0486 
0487     /// corrected PS2 energy
0488     float ps2Energy_;
0489 
0490     /// all flags, packed (ecal regional, hcal regional, tracking)
0491     unsigned flags_;
0492 
0493     /// uncertainty on 3-momentum
0494     float deltaP_;
0495 
0496     //legacy vertex type to read AOD created before PR #31456
0497     PFVertexType vertexType_;
0498 
0499     // mva for isolated electrons
0500     float mva_Isolated_;
0501 
0502     /// mva for electron-pion discrimination
0503     float mva_e_pi_;
0504 
0505     /// mva for electron-muon discrimination
0506     float mva_e_mu_;
0507 
0508     /// mva for pi-muon discrimination
0509     float mva_pi_mu_;
0510 
0511     /// mva for gamma detection
0512     float mva_nothing_gamma_;
0513 
0514     /// mva for neutral hadron detection
0515     float mva_nothing_nh_;
0516 
0517     /// mva for neutral hadron - gamma discrimination
0518     float mva_gamma_nh_;
0519 
0520     /// DNN for electron PFid: isolated signal
0521     float dnn_e_sigIsolated_;
0522 
0523     /// DNN for electron PFid: non-isolated signal
0524     float dnn_e_sigNonIsolated_;
0525 
0526     /// DNN for electron PFid: non-isolated bkg
0527     float dnn_e_bkgNonIsolated_;
0528 
0529     /// DNN for electron PFid: tau bkg
0530     float dnn_e_bkgTau_;
0531 
0532     /// DNN for electron PFid: photon bkg
0533     float dnn_e_bkgPhoton_;
0534 
0535     // DNN for gamma PFid
0536     float dnn_gamma_;
0537 
0538     /// position at ECAL entrance, from the PFRecTrack
0539     math::XYZPointF positionAtECALEntrance_;
0540 
0541     //more efficiently stored refs
0542     void storeRefInfo(unsigned int iMask,
0543                       unsigned int iBit,
0544                       bool iIsValid,
0545                       const edm::RefCore& iCore,
0546                       size_t iKey,
0547                       const edm::EDProductGetter*);
0548     bool getRefInfo(
0549         unsigned int iMask, unsigned int iBit, edm::ProductID& oProdID, size_t& oIndex, size_t& aIndex) const;
0550 
0551     const edm::EDProductGetter* getter_;  //transient
0552     unsigned short storedRefsBitPattern_;
0553     std::vector<unsigned long long> refsInfo_;
0554     std::vector<const void*> refsCollectionCache_;
0555 
0556     /// timing information (valid if timeError_ >= 0)
0557     float time_;
0558     /// timing information uncertainty (<0 if timing not available)
0559     float timeError_;
0560 
0561     std::array<float, 7> hcalDepthEnergyFractions_;
0562   };
0563 
0564   /// particle ID component tag
0565   struct PFParticleIdTag {};
0566 
0567   /// get default PFBlockRef component
0568   /// as: pfcand->get<PFBlockRef>();
0569   /*   GET_DEFAULT_CANDIDATE_COMPONENT( PFCandidate, PFBlockRef, block ); */
0570 
0571   /// get int component
0572   /// as: pfcand->get<int, PFParticleIdTag>();
0573   GET_CANDIDATE_COMPONENT(PFCandidate, PFCandidate::ParticleType, particleId, PFParticleIdTag);
0574 
0575   std::ostream& operator<<(std::ostream& out, const PFCandidate& c);
0576 
0577 }  // namespace reco
0578 
0579 #endif