Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 //
0002 //
0003 
0004 #ifndef DataFormats_PatCandidates_Jet_h
0005 #define DataFormats_PatCandidates_Jet_h
0006 
0007 /**
0008   \class    pat::Jet Jet.h "DataFormats/PatCandidates/interface/Jet.h"
0009   \brief    Analysis-level calorimeter jet class
0010 
0011    Jet implements the analysis-level calorimeter jet class within the
0012    'pat' namespace
0013 
0014   \author   Steven Lowette, Giovanni Petrucciani, Roger Wolf, Christian Autermann
0015 */
0016 
0017 #include "DataFormats/JetReco/interface/CaloJet.h"
0018 #include "DataFormats/JetReco/interface/BasicJet.h"
0019 #include "DataFormats/JetReco/interface/JPTJet.h"
0020 #include "DataFormats/JetReco/interface/PFJet.h"
0021 #include "DataFormats/CaloTowers/interface/CaloTower.h"
0022 #include "DataFormats/JetReco/interface/GenJet.h"
0023 #include "DataFormats/Candidate/interface/Particle.h"
0024 #include "DataFormats/TrackReco/interface/Track.h"
0025 #include "DataFormats/TrackReco/interface/TrackFwd.h"
0026 #include "DataFormats/BTauReco/interface/JetTag.h"
0027 #include "DataFormats/PatCandidates/interface/PATObject.h"
0028 #include "DataFormats/BTauReco/interface/CandIPTagInfo.h"
0029 #include "DataFormats/BTauReco/interface/TrackIPTagInfo.h"
0030 #include "DataFormats/BTauReco/interface/TrackProbabilityTagInfo.h"
0031 #include "DataFormats/BTauReco/interface/TrackCountingTagInfo.h"
0032 #include "DataFormats/BTauReco/interface/CandSoftLeptonTagInfo.h"
0033 #include "DataFormats/BTauReco/interface/SoftLeptonTagInfo.h"
0034 #include "DataFormats/JetMatching/interface/JetFlavourInfo.h"
0035 #include "DataFormats/BTauReco/interface/PixelClusterTagInfo.h"
0036 #include "DataFormats/BTauReco/interface/CandSecondaryVertexTagInfo.h"
0037 #include "DataFormats/BTauReco/interface/SecondaryVertexTagInfo.h"
0038 #include "DataFormats/BTauReco/interface/BoostedDoubleSVTagInfo.h"
0039 #include "DataFormats/PatCandidates/interface/JetCorrFactors.h"
0040 #include "DataFormats/JetReco/interface/JetID.h"
0041 
0042 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
0043 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0044 
0045 #include "DataFormats/Common/interface/Ptr.h"
0046 #include "DataFormats/Common/interface/OwnVector.h"
0047 #include "DataFormats/Common/interface/AtomicPtrCache.h"
0048 
0049 #include <numeric>
0050 
0051 // Define typedefs for convenience
0052 namespace pat {
0053   class Jet;
0054   typedef std::vector<Jet> JetCollection;
0055   typedef edm::Ref<JetCollection> JetRef;
0056   typedef edm::RefVector<JetCollection> JetRefVector;
0057 }  // namespace pat
0058 
0059 namespace reco {
0060   /// pipe operator (introduced to use pat::Jet with PFTopProjectors)
0061   std::ostream& operator<<(std::ostream& out, const pat::Jet& obj);
0062 }  // namespace reco
0063 
0064 // Class definition
0065 namespace pat {
0066 
0067   class PATJetSlimmer;
0068 
0069   typedef reco::CaloJet::Specific CaloSpecific;
0070   typedef reco::JPTJet::Specific JPTSpecific;
0071   typedef reco::PFJet::Specific PFSpecific;
0072   typedef std::vector<edm::FwdPtr<reco::BaseTagInfo> > TagInfoFwdPtrCollection;
0073   typedef std::vector<edm::FwdPtr<reco::PFCandidate> > PFCandidateFwdPtrCollection;
0074   typedef std::vector<edm::FwdPtr<CaloTower> > CaloTowerFwdPtrCollection;
0075   typedef std::vector<edm::Ptr<pat::Jet> > JetPtrCollection;
0076 
0077   class Jet : public PATObject<reco::Jet> {
0078     /// make friends with PATJetProducer so that it can set the an initial
0079     /// jet energy scale unequal to raw calling the private initializeJEC
0080     /// function, which should be non accessible to any other user
0081     friend class PATJetProducer;
0082     friend class PATJetSlimmer;
0083     friend class PATJetUpdater;
0084 
0085   public:
0086     /// default constructor
0087     Jet();
0088     /// constructor from a reco::Jet
0089     Jet(const reco::Jet& aJet);
0090     /// constructor from ref to reco::Jet
0091     Jet(const edm::RefToBase<reco::Jet>& aJetRef);
0092     /// constructor from ref to reco::Jet
0093     Jet(const edm::Ptr<reco::Jet>& aJetRef);
0094     /// constructure from ref to pat::Jet
0095     Jet(const edm::RefToBase<pat::Jet>& aJetRef);
0096     /// constructure from ref to pat::Jet
0097     Jet(const edm::Ptr<pat::Jet>& aJetRef);
0098     /// destructor
0099     ~Jet() override;
0100     /// required reimplementation of the Candidate's clone method
0101     Jet* clone() const override { return new Jet(*this); }
0102 
0103     /// ---- methods for MC matching ----
0104 
0105     /// return the matched generated parton
0106     const reco::GenParticle* genParton() const { return genParticle(); }
0107     /// return the matched generated jet
0108     const reco::GenJet* genJet() const;
0109     /// return the parton-based flavour of the jet
0110     int partonFlavour() const;
0111     /// return the hadron-based flavour of the jet
0112     int hadronFlavour() const;
0113     /// return the JetFlavourInfo of the jet
0114     const reco::JetFlavourInfo& jetFlavourInfo() const;
0115 
0116   public:
0117     /// ---- methods for jet corrections ----
0118 
0119     /// returns the labels of all available sets of jet energy corrections
0120     const std::vector<std::string> availableJECSets() const;
0121     // returns the available JEC Levels for a given jecSet
0122     const std::vector<std::string> availableJECLevels(const int& set = 0) const;
0123     // returns the available JEC Levels for a given jecSet
0124     const std::vector<std::string> availableJECLevels(const std::string& set) const {
0125       return availableJECLevels(jecSet(set));
0126     };
0127     /// returns true if the jet carries jet energy correction information
0128     /// at all
0129     bool jecSetsAvailable() const { return !jec_.empty(); }
0130     /// returns true if the jet carries a set of jet energy correction
0131     /// factors with the given label
0132     bool jecSetAvailable(const std::string& set) const { return (jecSet(set) >= 0); };
0133     /// returns true if the jet carries a set of jet energy correction
0134     /// factors with the given label
0135     bool jecSetAvailable(const unsigned int& set) const { return (set < jec_.size()); };
0136     /// returns the label of the current set of jet energy corrections
0137     std::string currentJECSet() const {
0138       return currentJECSet_ < jec_.size() ? jec_.at(currentJECSet_).jecSet() : std::string("ERROR");
0139     }
0140     /// return the name of the current step of jet energy corrections
0141     std::string currentJECLevel() const {
0142       return currentJECSet_ < jec_.size() ? jec_.at(currentJECSet_).jecLevel(currentJECLevel_) : std::string("ERROR");
0143     };
0144     /// return flavour of the current step of jet energy corrections
0145     JetCorrFactors::Flavor currentJECFlavor() const { return currentJECFlavor_; };
0146     /// correction factor to the given level for a specific set
0147     /// of correction factors, starting from the current level
0148     float jecFactor(const std::string& level, const std::string& flavor = "none", const std::string& set = "") const;
0149     /// correction factor to the given level for a specific set
0150     /// of correction factors, starting from the current level
0151     float jecFactor(const unsigned int& level,
0152                     const JetCorrFactors::Flavor& flavor = JetCorrFactors::NONE,
0153                     const unsigned int& set = 0) const;
0154     /// copy of the jet corrected up to the given level for the set
0155     /// of jet energy correction factors, which is currently in use
0156     Jet correctedJet(const std::string& level, const std::string& flavor = "none", const std::string& set = "") const;
0157     /// copy of the jet corrected up to the given level for the set
0158     /// of jet energy correction factors, which is currently in use
0159     Jet correctedJet(const unsigned int& level,
0160                      const JetCorrFactors::Flavor& flavor = JetCorrFactors::NONE,
0161                      const unsigned int& set = 0) const;
0162     /// p4 of the jet corrected up to the given level for the set
0163     /// of jet energy correction factors, which is currently in use
0164     const LorentzVector correctedP4(const std::string& level,
0165                                     const std::string& flavor = "none",
0166                                     const std::string& set = "") const {
0167       return correctedJet(level, flavor, set).p4();
0168     };
0169     /// p4 of the jet corrected up to the given level for the set
0170     /// of jet energy correction factors, which is currently in use
0171     const LorentzVector correctedP4(const unsigned int& level,
0172                                     const JetCorrFactors::Flavor& flavor = JetCorrFactors::NONE,
0173                                     const unsigned int& set = 0) const {
0174       return correctedJet(level, flavor, set).p4();
0175     };
0176     /// Scale energy and correspondingly adjust raw jec factors
0177     void scaleEnergy(double fScale) override { scaleEnergy(fScale, "Unscaled"); }
0178     void scaleEnergy(double fScale, const std::string& level);
0179 
0180   private:
0181     /// index of the set of jec factors with given label; returns -1 if no set
0182     /// of jec factors exists with the given label
0183     int jecSet(const std::string& label) const;
0184     /// update the current JEC set; used by correctedJet
0185     void currentJECSet(const unsigned int& set) { currentJECSet_ = set; };
0186     /// update the current JEC level; used by correctedJet
0187     void currentJECLevel(const unsigned int& level) { currentJECLevel_ = level; };
0188     /// update the current JEC flavor; used by correctedJet
0189     void currentJECFlavor(const JetCorrFactors::Flavor& flavor) { currentJECFlavor_ = flavor; };
0190     /// add more sets of energy correction factors
0191     void addJECFactors(const JetCorrFactors& jec) { jec_.push_back(jec); };
0192     /// initialize the jet to a given JEC level during creation starting from Uncorrected
0193     void initializeJEC(unsigned int level,
0194                        const JetCorrFactors::Flavor& flavor = JetCorrFactors::NONE,
0195                        unsigned int set = 0);
0196 
0197   public:
0198     /// ---- methods for accessing b-tagging info ----
0199 
0200     /// get b discriminant from label name
0201     float bDiscriminator(const std::string& theLabel) const;
0202     /// get vector of paire labelname-disciValue
0203     const std::vector<std::pair<std::string, float> >& getPairDiscri() const;
0204     /// get list of tag info labels
0205     std::vector<std::string> const& tagInfoLabels() const { return tagInfoLabels_; }
0206     /// check to see if the given tag info is nonzero
0207     bool hasTagInfo(const std::string label) const { return tagInfo(label) != nullptr; }
0208     /// get a tagInfo with the given name, or NULL if none is found.
0209     /// You should omit the 'TagInfos' part from the label
0210     const reco::BaseTagInfo* tagInfo(const std::string& label) const;
0211     /// get a tagInfo with the given name and type or NULL if none is found.
0212     /// If the label is empty or not specified, it returns the first tagInfo of that type (if any one exists)
0213     /// you should omit the 'TagInfos' part from the label
0214     const reco::CandIPTagInfo* tagInfoCandIP(const std::string& label = "") const;
0215     const reco::TrackIPTagInfo* tagInfoTrackIP(const std::string& label = "") const;
0216     /// get a tagInfo with the given name and type or NULL if none is found.
0217     /// If the label is empty or not specified, it returns the first tagInfo of that type (if any one exists)
0218     /// you should omit the 'TagInfos' part from the label
0219     const reco::CandSoftLeptonTagInfo* tagInfoCandSoftLepton(const std::string& label = "") const;
0220     const reco::SoftLeptonTagInfo* tagInfoSoftLepton(const std::string& label = "") const;
0221     /// get a tagInfo with the given name and type or NULL if none is found.
0222     /// If the label is empty or not specified, it returns the first tagInfo of that type (if any one exists)
0223     /// you should omit the 'TagInfos' part from the label
0224     const reco::CandSecondaryVertexTagInfo* tagInfoCandSecondaryVertex(const std::string& label = "") const;
0225     const reco::SecondaryVertexTagInfo* tagInfoSecondaryVertex(const std::string& label = "") const;
0226     const reco::BoostedDoubleSVTagInfo* tagInfoBoostedDoubleSV(const std::string& label = "") const;
0227     /// get a tagInfo with the given name and type or NULL if none is found.
0228     /// If the label is empty or not specified, it returns the first tagInfo of that type (if any one exists)
0229     /// you should omit the 'TagInfos' part from the label
0230     const reco::PixelClusterTagInfo* tagInfoPixelCluster(const std::string& label = "") const;
0231     /// method to add a algolabel-discriminator pair
0232     void addBDiscriminatorPair(const std::pair<std::string, float>& thePair);
0233     /// sets a tagInfo with the given name from an edm::Ptr<T> to it.
0234     /// If the label ends with 'TagInfos', the 'TagInfos' is stripped out.
0235     void addTagInfo(const std::string& label, const TagInfoFwdPtrCollection::value_type& info);
0236 
0237     // ---- track related methods ----
0238 
0239     /// method to return the JetCharge computed when creating the Jet
0240     float jetCharge() const;
0241     /// method to return a vector of refs to the tracks associated to this jet
0242     const reco::TrackRefVector& associatedTracks() const;
0243     /// method to set the jet charge
0244     void setJetCharge(float jetCharge);
0245     /// method to set the vector of refs to the tracks associated to this jet
0246     void setAssociatedTracks(const reco::TrackRefVector& tracks);
0247 
0248     // ---- methods for content embedding ----
0249 
0250     /// method to store the CaloJet constituents internally
0251     void setCaloTowers(const CaloTowerFwdPtrCollection& caloTowers);
0252     /// method to store the PFCandidate constituents internally
0253     void setPFCandidates(const PFCandidateFwdPtrCollection& pfCandidates);
0254     /// method to set the matched parton
0255     void setGenParton(const reco::GenParticleRef& gp, bool embed = false) { setGenParticleRef(gp, embed); }
0256     /// method to set the matched generated jet reference, embedding if requested
0257     void setGenJetRef(const edm::FwdRef<reco::GenJetCollection>& gj);
0258     /// method to set the parton-based flavour of the jet
0259     void setPartonFlavour(int partonFl);
0260     /// method to set the hadron-based flavour of the jet
0261     void setHadronFlavour(int hadronFl);
0262     /// method to set the JetFlavourInfo of the jet
0263     void setJetFlavourInfo(const reco::JetFlavourInfo& jetFlavourInfo);
0264 
0265     /// methods for jet ID
0266     void setJetID(reco::JetID const& id) { jetID_ = id; }
0267 
0268     // ---- jet specific methods ----
0269 
0270     /// check to see if the jet is a reco::CaloJet
0271     bool isCaloJet() const { return !specificCalo_.empty() && !isJPTJet(); }
0272     /// check to see if the jet is a reco::JPTJet
0273     bool isJPTJet() const { return !specificJPT_.empty(); }
0274     /// check to see if the jet is a reco::PFJet
0275     bool isPFJet() const { return !specificPF_.empty(); }
0276     /// check to see if the jet is no more than a reco::BasicJet
0277     bool isBasicJet() const { return !(isCaloJet() || isPFJet() || isJPTJet()); }
0278     /// retrieve the calo specific part of the jet
0279     const CaloSpecific& caloSpecific() const {
0280       if (specificCalo_.empty())
0281         throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a CaloJet.\n";
0282       return specificCalo_[0];
0283     }
0284     /// retrieve the jpt specific part of the jet
0285     const JPTSpecific& jptSpecific() const {
0286       if (specificJPT_.empty())
0287         throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet.\n";
0288       return specificJPT_[0];
0289     }
0290     /// check to see if the PFSpecific object is stored
0291     bool hasPFSpecific() const { return !specificPF_.empty(); }
0292     /// retrieve the pf specific part of the jet
0293     const PFSpecific& pfSpecific() const {
0294       if (specificPF_.empty())
0295         throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a PFJet.\n";
0296       return specificPF_[0];
0297     }
0298     /// set the calo specific part of the jet
0299     void setCaloSpecific(const CaloSpecific& newCaloSpecific) {
0300       if (specificCalo_.empty())
0301         throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a CaloJet.\n";
0302       specificCalo_[0] = newCaloSpecific;
0303     }
0304     /// set the jpt specific part of the jet
0305     void setJPTSpecific(const JPTSpecific& newJPTSpecific) {
0306       if (specificJPT_.empty())
0307         throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet.\n";
0308       specificJPT_[0] = newJPTSpecific;
0309     }
0310     /// set the pf specific part of the jet
0311     void setPFSpecific(const PFSpecific& newPFSpecific) {
0312       if (specificPF_.empty())
0313         throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a PFJet.\n";
0314       specificPF_[0] = newPFSpecific;
0315     }
0316 
0317     // ---- Calo Jet specific information ----
0318 
0319     /// returns the maximum energy deposited in ECAL towers
0320     float maxEInEmTowers() const { return caloSpecific().mMaxEInEmTowers; }
0321     /// returns the maximum energy deposited in HCAL towers
0322     float maxEInHadTowers() const { return caloSpecific().mMaxEInHadTowers; }
0323     /// returns the jet hadronic energy fraction
0324     float energyFractionHadronic() const { return caloSpecific().mEnergyFractionHadronic; }
0325     /// returns the jet electromagnetic energy fraction
0326     float emEnergyFraction() const { return caloSpecific().mEnergyFractionEm; }
0327     /// returns the jet hadronic energy in HB
0328     float hadEnergyInHB() const { return caloSpecific().mHadEnergyInHB; }
0329     /// returns the jet hadronic energy in HO
0330     float hadEnergyInHO() const { return caloSpecific().mHadEnergyInHO; }
0331     /// returns the jet hadronic energy in HE
0332     float hadEnergyInHE() const { return caloSpecific().mHadEnergyInHE; }
0333     /// returns the jet hadronic energy in HF
0334     float hadEnergyInHF() const { return caloSpecific().mHadEnergyInHF; }
0335     /// returns the jet electromagnetic energy in EB
0336     float emEnergyInEB() const { return caloSpecific().mEmEnergyInEB; }
0337     /// returns the jet electromagnetic energy in EE
0338     float emEnergyInEE() const { return caloSpecific().mEmEnergyInEE; }
0339     /// returns the jet electromagnetic energy extracted from HF
0340     float emEnergyInHF() const { return caloSpecific().mEmEnergyInHF; }
0341     /// returns area of contributing towers
0342     float towersArea() const { return caloSpecific().mTowersArea; }
0343     /// returns the number of constituents carrying a 90% of the total Jet energy*/
0344     int n90() const { return nCarrying(0.9); }
0345     /// returns the number of constituents carrying a 60% of the total Jet energy*/
0346     int n60() const { return nCarrying(0.6); }
0347 
0348     /// convert generic constituent to specific type
0349     //  static CaloTowerPtr caloTower (const reco::Candidate* fConstituent);
0350     /// get specific constituent of the CaloJet.
0351     /// if the caloTowers were embedded, this reference is transient only and must not be persisted
0352     CaloTowerPtr getCaloConstituent(unsigned fIndex) const;
0353     /// get the constituents of the CaloJet.
0354     /// If the caloTowers were embedded, these reference are transient only and must not be persisted
0355     std::vector<CaloTowerPtr> const& getCaloConstituents() const;
0356 
0357     // ---- JPT Jet specific information ----
0358 
0359     /// pions fully contained in cone
0360     const reco::TrackRefVector& pionsInVertexInCalo() const { return jptSpecific().pionsInVertexInCalo; }
0361     /// pions that curled out
0362     const reco::TrackRefVector& pionsInVertexOutCalo() const { return jptSpecific().pionsInVertexOutCalo; }
0363     /// pions that curled in
0364     const reco::TrackRefVector& pionsOutVertexInCalo() const { return jptSpecific().pionsOutVertexInCalo; }
0365     /// muons fully contained in cone
0366     const reco::TrackRefVector& muonsInVertexInCalo() const { return jptSpecific().muonsInVertexInCalo; }
0367     /// muons that curled out
0368     const reco::TrackRefVector& muonsInVertexOutCalo() const { return jptSpecific().muonsInVertexOutCalo; }
0369     /// muons that curled in
0370     const reco::TrackRefVector& muonsOutVertexInCalo() const { return jptSpecific().muonsOutVertexInCalo; }
0371     /// electrons fully contained in cone
0372     const reco::TrackRefVector& elecsInVertexInCalo() const { return jptSpecific().elecsInVertexInCalo; }
0373     /// electrons that curled out
0374     const reco::TrackRefVector& elecsInVertexOutCalo() const { return jptSpecific().elecsInVertexOutCalo; }
0375     /// electrons that curled in
0376     const reco::TrackRefVector& elecsOutVertexInCalo() const { return jptSpecific().elecsOutVertexInCalo; }
0377     /// chargedMultiplicity
0378     float elecMultiplicity() const {
0379       return jptSpecific().elecsInVertexInCalo.size() + jptSpecific().elecsInVertexOutCalo.size();
0380     }
0381 
0382     // ---- JPT or PF Jet specific information ----
0383 
0384     /// muonMultiplicity
0385     int muonMultiplicity() const;
0386     /// chargedMultiplicity
0387     int chargedMultiplicity() const;
0388     /// chargedEmEnergy
0389     float chargedEmEnergy() const;
0390     /// neutralEmEnergy
0391     float neutralEmEnergy() const;
0392     /// chargedHadronEnergy
0393     float chargedHadronEnergy() const;
0394     /// neutralHadronEnergy
0395     float neutralHadronEnergy() const;
0396 
0397     /// chargedHadronEnergyFraction (relative to uncorrected jet energy)
0398     float chargedHadronEnergyFraction() const {
0399       return chargedHadronEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0400     }
0401     /// neutralHadronEnergyFraction (relative to uncorrected jet energy)
0402     float neutralHadronEnergyFraction() const {
0403       return neutralHadronEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0404     }
0405     /// chargedEmEnergyFraction (relative to uncorrected jet energy)
0406     float chargedEmEnergyFraction() const {
0407       return chargedEmEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0408     }
0409     /// neutralEmEnergyFraction (relative to uncorrected jet energy)
0410     float neutralEmEnergyFraction() const {
0411       return neutralEmEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0412     }
0413 
0414     // ---- PF Jet specific information ----
0415     /// photonEnergy
0416     float photonEnergy() const { return pfSpecific().mPhotonEnergy; }
0417     /// photonEnergyFraction (relative to corrected jet energy)
0418     float photonEnergyFraction() const {
0419       return photonEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0420     }
0421     /// electronEnergy
0422     float electronEnergy() const { return pfSpecific().mElectronEnergy; }
0423     /// electronEnergyFraction (relative to corrected jet energy)
0424     float electronEnergyFraction() const {
0425       return electronEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0426     }
0427     /// muonEnergy
0428     float muonEnergy() const { return pfSpecific().mMuonEnergy; }
0429     /// muonEnergyFraction (relative to corrected jet energy)
0430     float muonEnergyFraction() const { return muonEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy()); }
0431     /// HFHadronEnergy
0432     float HFHadronEnergy() const { return pfSpecific().mHFHadronEnergy; }
0433     /// HFHadronEnergyFraction (relative to corrected jet energy)
0434     float HFHadronEnergyFraction() const {
0435       return HFHadronEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0436     }
0437     /// HFEMEnergy
0438     float HFEMEnergy() const { return pfSpecific().mHFEMEnergy; }
0439     /// HFEMEnergyFraction (relative to corrected jet energy)
0440     float HFEMEnergyFraction() const { return HFEMEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy()); }
0441 
0442     /// chargedHadronMultiplicity
0443     int chargedHadronMultiplicity() const { return pfSpecific().mChargedHadronMultiplicity; }
0444     /// neutralHadronMultiplicity
0445     int neutralHadronMultiplicity() const { return pfSpecific().mNeutralHadronMultiplicity; }
0446     /// photonMultiplicity
0447     int photonMultiplicity() const { return pfSpecific().mPhotonMultiplicity; }
0448     /// electronMultiplicity
0449     int electronMultiplicity() const { return pfSpecific().mElectronMultiplicity; }
0450 
0451     /// HFHadronMultiplicity
0452     int HFHadronMultiplicity() const { return pfSpecific().mHFHadronMultiplicity; }
0453     /// HFEMMultiplicity
0454     int HFEMMultiplicity() const { return pfSpecific().mHFEMMultiplicity; }
0455 
0456     /// chargedMuEnergy
0457     float chargedMuEnergy() const { return pfSpecific().mChargedMuEnergy; }
0458     /// chargedMuEnergyFraction
0459     float chargedMuEnergyFraction() const {
0460       return chargedMuEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0461     }
0462 
0463     /// neutralMultiplicity
0464     int neutralMultiplicity() const { return pfSpecific().mNeutralMultiplicity; }
0465 
0466     /// hoEnergy
0467     float hoEnergy() const { return pfSpecific().mHOEnergy; }
0468     /// hoEnergyFraction (relative to corrected jet energy)
0469     float hoEnergyFraction() const { return hoEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy()); }
0470     /// convert generic constituent to specific type
0471 
0472     //  static CaloTowerPtr caloTower (const reco::Candidate* fConstituent);
0473     /// get specific constituent of the CaloJet.
0474     /// if the caloTowers were embedded, this reference is transient only and must not be persisted
0475     reco::PFCandidatePtr getPFConstituent(unsigned fIndex) const;
0476     /// get the constituents of the CaloJet.
0477     /// If the caloTowers were embedded, these reference are transient only and must not be persisted
0478     std::vector<reco::PFCandidatePtr> const& getPFConstituents() const;
0479 
0480     /// get a pointer to a Candididate constituent of the jet
0481     ///    If using refactorized PAT, return that. (constituents size > 0)
0482     ///    Else check the old version of PAT (embedded constituents size > 0)
0483     ///    Else return the reco Jet number of constituents
0484     const reco::Candidate* daughter(size_t i) const override;
0485 
0486     reco::CandidatePtr daughterPtr(size_t i) const override;
0487     const reco::CompositePtrCandidate::daughters& daughterPtrVector() const override;
0488 
0489     using reco::LeafCandidate::daughter;  // avoid hiding the base implementation
0490 
0491     /// Return number of daughters:
0492     ///    If using refactorized PAT, return that. (constituents size > 0)
0493     ///    Else check the old version of PAT (embedded constituents size > 0)
0494     ///    Else return the reco Jet number of constituents
0495     size_t numberOfDaughters() const override;
0496 
0497     /// clear daughter references
0498     void clearDaughters() override {
0499       PATObject<reco::Jet>::clearDaughters();
0500       daughtersTemp_.reset();  // need to reset daughtersTemp_ as well
0501     }
0502 
0503     /// accessing Jet ID information
0504     reco::JetID const& jetID() const { return jetID_; }
0505 
0506     /// Access to bare FwdPtr collections
0507     CaloTowerFwdPtrVector const& caloTowersFwdPtr() const { return caloTowersFwdPtr_; }
0508     reco::PFCandidateFwdPtrVector const& pfCandidatesFwdPtr() const { return pfCandidatesFwdPtr_; }
0509     edm::FwdRef<reco::GenJetCollection> const& genJetFwdRef() const { return genJetFwdRef_; }
0510     TagInfoFwdPtrCollection const& tagInfosFwdPtr() const { return tagInfosFwdPtr_; }
0511 
0512     /// Update bare FwdPtr and FwdRef "forward" pointers while keeping the
0513     /// "back" pointers the same (i.e. the ref "forwarding")
0514     void updateFwdCaloTowerFwdPtr(unsigned int index, const edm::Ptr<CaloTower>& updateFwd) {
0515       if (index < caloTowersFwdPtr_.size()) {
0516         caloTowersFwdPtr_[index] = CaloTowerFwdPtrVector::value_type(updateFwd, caloTowersFwdPtr_[index].backPtr());
0517       } else {
0518         throw cms::Exception("OutOfRange") << "Index " << index << " is out of range" << std::endl;
0519       }
0520     }
0521 
0522     void updateFwdPFCandidateFwdPtr(unsigned int index, const edm::Ptr<reco::PFCandidate>& updateFwd) {
0523       if (index < pfCandidatesFwdPtr_.size()) {
0524         pfCandidatesFwdPtr_[index] =
0525             reco::PFCandidateFwdPtrVector::value_type(updateFwd, pfCandidatesFwdPtr_[index].backPtr());
0526       } else {
0527         throw cms::Exception("OutOfRange") << "Index " << index << " is out of range" << std::endl;
0528       }
0529     }
0530 
0531     void updateFwdTagInfoFwdPtr(unsigned int index, const edm::Ptr<reco::BaseTagInfo>& updateFwd) {
0532       if (index < tagInfosFwdPtr_.size()) {
0533         tagInfosFwdPtr_[index] = TagInfoFwdPtrCollection::value_type(updateFwd, tagInfosFwdPtr_[index].backPtr());
0534       } else {
0535         throw cms::Exception("OutOfRange") << "Index " << index << " is out of range" << std::endl;
0536       }
0537     }
0538 
0539     void updateFwdGenJetFwdRef(edm::Ref<reco::GenJetCollection> updateRef) {
0540       genJetFwdRef_ = edm::FwdRef<reco::GenJetCollection>(updateRef, genJetFwdRef_.backRef());
0541     }
0542 
0543     /// pipe operator (introduced to use pat::Jet with PFTopProjectors)
0544     friend std::ostream& reco::operator<<(std::ostream& out, const pat::Jet& obj);
0545 
0546     /// Access to subjet list
0547     pat::JetPtrCollection const& subjets(unsigned int index = 0) const;
0548 
0549     /// String access to subjet list
0550     pat::JetPtrCollection const& subjets(std::string const& label) const;
0551 
0552     /// Add new set of subjets
0553     void addSubjets(pat::JetPtrCollection const& pieces, std::string const& label = "");
0554 
0555     /// Check to see if the subjet collection exists
0556     bool hasSubjets(std::string const& label) const {
0557       return find(subjetLabels_.begin(), subjetLabels_.end(), label) != subjetLabels_.end();
0558     }
0559 
0560     /// Number of subjet collections
0561     unsigned int nSubjetCollections() const { return subjetCollections_.size(); }
0562 
0563     /// Subjet collection names
0564     std::vector<std::string> const& subjetCollectionNames() const { return subjetLabels_; }
0565 
0566     /// Access to mass of subjets
0567     double groomedMass(unsigned int index = 0) const {
0568       auto const& sub = subjets(index);
0569       return nSubjetCollections() > index && !sub.empty()
0570                  ? std::accumulate(
0571                        sub.begin(),
0572                        sub.end(),
0573                        reco::Candidate::LorentzVector(),
0574                        [](reco::Candidate::LorentzVector const& a, reco::CandidatePtr const& b) { return a + b->p4(); })
0575                        .mass()
0576                  : -1.0;
0577     }
0578     double groomedMass(std::string const& label) const {
0579       auto const& sub = subjets(label);
0580       return hasSubjets(label) && !sub.empty()
0581                  ? std::accumulate(
0582                        sub.begin(),
0583                        sub.end(),
0584                        reco::Candidate::LorentzVector(),
0585                        [](reco::Candidate::LorentzVector const& a, reco::CandidatePtr const& b) { return a + b->p4(); })
0586                        .mass()
0587                  : -1.0;
0588     }
0589 
0590   protected:
0591     // ---- for content embedding ----
0592 
0593     bool embeddedCaloTowers_;
0594     edm::AtomicPtrCache<std::vector<CaloTowerPtr> > caloTowersTemp_;  // to simplify user interface
0595     CaloTowerCollection caloTowers_;                                  // Compatibility embedding
0596     CaloTowerFwdPtrVector caloTowersFwdPtr_;                          // Refactorized content embedding
0597 
0598     bool embeddedPFCandidates_;
0599     edm::AtomicPtrCache<std::vector<reco::PFCandidatePtr> > pfCandidatesTemp_;  // to simplify user interface
0600     reco::PFCandidateCollection pfCandidates_;                                  // Compatibility embedding
0601     reco::PFCandidateFwdPtrVector pfCandidatesFwdPtr_;                          // Refactorized content embedding
0602 
0603     // ---- Jet Substructure ----
0604     std::vector<pat::JetPtrCollection> subjetCollections_;
0605     std::vector<std::string> subjetLabels_;
0606     edm::AtomicPtrCache<std::vector<reco::CandidatePtr> > daughtersTemp_;
0607 
0608     // ---- MC info ----
0609 
0610     std::vector<reco::GenJet> genJet_;
0611     reco::GenJetRefVector genJetRef_;
0612     edm::FwdRef<reco::GenJetCollection> genJetFwdRef_;
0613     reco::JetFlavourInfo jetFlavourInfo_;
0614 
0615     // ---- energy scale correction factors ----
0616 
0617     // energy scale correction factors; the string carries a potential label if
0618     // more then one set of correction factors is embedded. The label corresponds
0619     // to the label of the jetCorrFactors module that has been embedded.
0620     std::vector<pat::JetCorrFactors> jec_;
0621     // currently applied set of jet energy correction factors (i.e. the index in
0622     // jetEnergyCorrections_)
0623     unsigned int currentJECSet_;
0624     // currently applied jet energy correction level
0625     unsigned int currentJECLevel_;
0626     // currently applied jet energy correction flavor (can be NONE, GLUON, UDS,
0627     // CHARM or BOTTOM)
0628     JetCorrFactors::Flavor currentJECFlavor_;
0629 
0630     // ---- b-tag related members ----
0631 
0632     std::vector<std::pair<std::string, float> > pairDiscriVector_;
0633     std::vector<std::string> tagInfoLabels_;
0634     edm::OwnVector<reco::BaseTagInfo> tagInfos_;  // Compatibility embedding
0635     TagInfoFwdPtrCollection tagInfosFwdPtr_;      // Refactorized embedding
0636 
0637     // ---- track related members ----
0638 
0639     float jetCharge_;
0640     reco::TrackRefVector associatedTracks_;
0641 
0642     // ---- specific members ----
0643 
0644     std::vector<CaloSpecific> specificCalo_;
0645     std::vector<JPTSpecific> specificJPT_;
0646     std::vector<PFSpecific> specificPF_;
0647 
0648     // ---- id functions ----
0649     reco::JetID jetID_;
0650 
0651   private:
0652     // ---- helper functions ----
0653 
0654     void tryImportSpecific(const reco::Jet& source);
0655 
0656     template <typename T>
0657     const T* tagInfoByType() const {
0658       // First check the factorized PAT version
0659       for (size_t i = 0, n = tagInfosFwdPtr_.size(); i < n; ++i) {
0660         TagInfoFwdPtrCollection::value_type const& val = tagInfosFwdPtr_[i];
0661         reco::BaseTagInfo const* baseTagInfo = val.get();
0662         if (typeid(*baseTagInfo) == typeid(T)) {
0663           return static_cast<const T*>(baseTagInfo);
0664         }
0665       }
0666       // Then check compatibility version
0667       for (size_t i = 0, n = tagInfos_.size(); i < n; ++i) {
0668         edm::OwnVector<reco::BaseTagInfo>::value_type const& val = tagInfos_[i];
0669         reco::BaseTagInfo const* baseTagInfo = &val;
0670         if (typeid(*baseTagInfo) == typeid(T)) {
0671           return static_cast<const T*>(baseTagInfo);
0672         }
0673       }
0674       return nullptr;
0675     }
0676 
0677     template <typename T>
0678     const T* tagInfoByTypeOrLabel(const std::string& label = "") const {
0679       return (label.empty() ? tagInfoByType<T>() : dynamic_cast<const T*>(tagInfo(label)));
0680     }
0681 
0682     /// return the jet correction factors of a different set, for systematic studies
0683     const JetCorrFactors* corrFactors_(const std::string& set) const;
0684     /// return the correction factor for this jet. Throws if they're not available.
0685     const JetCorrFactors* corrFactors_() const;
0686 
0687     /// cache calo towers
0688     void cacheCaloTowers() const;
0689     void cachePFCandidates() const;
0690     void cacheDaughters() const;
0691   };
0692 }  // namespace pat
0693 
0694 inline float pat::Jet::chargedHadronEnergy() const {
0695   if (isPFJet()) {
0696     return pfSpecific().mChargedHadronEnergy;
0697   } else if (isJPTJet()) {
0698     return jptSpecific().mChargedHadronEnergy;
0699   } else {
0700     throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet nor from PFJet.\n";
0701   }
0702 }
0703 
0704 inline float pat::Jet::neutralHadronEnergy() const {
0705   if (isPFJet()) {
0706     return pfSpecific().mNeutralHadronEnergy;
0707   } else {
0708     throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet nor from PFJet.\n";
0709   }
0710 }
0711 
0712 inline float pat::Jet::chargedEmEnergy() const {
0713   if (isPFJet()) {
0714     return pfSpecific().mChargedEmEnergy;
0715   } else if (isJPTJet()) {
0716     return jptSpecific().mChargedEmEnergy;
0717   } else {
0718     throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet nor from PFJet.\n";
0719   }
0720 }
0721 
0722 inline float pat::Jet::neutralEmEnergy() const {
0723   if (isPFJet()) {
0724     return pfSpecific().mNeutralEmEnergy;
0725   } else {
0726     throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet nor from PFJet.\n";
0727   }
0728 }
0729 
0730 inline int pat::Jet::muonMultiplicity() const {
0731   if (isPFJet()) {
0732     return pfSpecific().mMuonMultiplicity;
0733   } else if (isJPTJet()) {
0734     return jptSpecific().muonsInVertexInCalo.size() + jptSpecific().muonsInVertexOutCalo.size();
0735   } else {
0736     throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet nor from PFJet.\n";
0737   }
0738 }
0739 
0740 inline int pat::Jet::chargedMultiplicity() const {
0741   if (isPFJet()) {
0742     return pfSpecific().mChargedMultiplicity;
0743   } else if (isJPTJet()) {
0744     return jptSpecific().muonsInVertexInCalo.size() + jptSpecific().muonsInVertexOutCalo.size() +
0745            jptSpecific().pionsInVertexInCalo.size() + jptSpecific().pionsInVertexOutCalo.size() +
0746            jptSpecific().elecsInVertexInCalo.size() + jptSpecific().elecsInVertexOutCalo.size();
0747   } else {
0748     throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet nor from PFJet.\n";
0749   }
0750 }
0751 
0752 #endif