Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-03-24 03:14:42

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     /// zero suppression correction
0378     const float& zspCorrection() const { return jptSpecific().mZSPCor; }
0379     /// chargedMultiplicity
0380     float elecMultiplicity() const {
0381       return jptSpecific().elecsInVertexInCalo.size() + jptSpecific().elecsInVertexOutCalo.size();
0382     }
0383 
0384     // ---- JPT or PF Jet specific information ----
0385 
0386     /// muonMultiplicity
0387     int muonMultiplicity() const;
0388     /// chargedMultiplicity
0389     int chargedMultiplicity() const;
0390     /// chargedEmEnergy
0391     float chargedEmEnergy() const;
0392     /// neutralEmEnergy
0393     float neutralEmEnergy() const;
0394     /// chargedHadronEnergy
0395     float chargedHadronEnergy() const;
0396     /// neutralHadronEnergy
0397     float neutralHadronEnergy() const;
0398 
0399     /// chargedHadronEnergyFraction (relative to uncorrected jet energy)
0400     float chargedHadronEnergyFraction() const {
0401       return chargedHadronEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0402     }
0403     /// neutralHadronEnergyFraction (relative to uncorrected jet energy)
0404     float neutralHadronEnergyFraction() const {
0405       return neutralHadronEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0406     }
0407     /// chargedEmEnergyFraction (relative to uncorrected jet energy)
0408     float chargedEmEnergyFraction() const {
0409       return chargedEmEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0410     }
0411     /// neutralEmEnergyFraction (relative to uncorrected jet energy)
0412     float neutralEmEnergyFraction() const {
0413       return neutralEmEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0414     }
0415 
0416     // ---- PF Jet specific information ----
0417     /// photonEnergy
0418     float photonEnergy() const { return pfSpecific().mPhotonEnergy; }
0419     /// photonEnergyFraction (relative to corrected jet energy)
0420     float photonEnergyFraction() const {
0421       return photonEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0422     }
0423     /// electronEnergy
0424     float electronEnergy() const { return pfSpecific().mElectronEnergy; }
0425     /// electronEnergyFraction (relative to corrected jet energy)
0426     float electronEnergyFraction() const {
0427       return electronEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0428     }
0429     /// muonEnergy
0430     float muonEnergy() const { return pfSpecific().mMuonEnergy; }
0431     /// muonEnergyFraction (relative to corrected jet energy)
0432     float muonEnergyFraction() const { return muonEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy()); }
0433     /// HFHadronEnergy
0434     float HFHadronEnergy() const { return pfSpecific().mHFHadronEnergy; }
0435     /// HFHadronEnergyFraction (relative to corrected jet energy)
0436     float HFHadronEnergyFraction() const {
0437       return HFHadronEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0438     }
0439     /// HFEMEnergy
0440     float HFEMEnergy() const { return pfSpecific().mHFEMEnergy; }
0441     /// HFEMEnergyFraction (relative to corrected jet energy)
0442     float HFEMEnergyFraction() const { return HFEMEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy()); }
0443 
0444     /// chargedHadronMultiplicity
0445     int chargedHadronMultiplicity() const { return pfSpecific().mChargedHadronMultiplicity; }
0446     /// neutralHadronMultiplicity
0447     int neutralHadronMultiplicity() const { return pfSpecific().mNeutralHadronMultiplicity; }
0448     /// photonMultiplicity
0449     int photonMultiplicity() const { return pfSpecific().mPhotonMultiplicity; }
0450     /// electronMultiplicity
0451     int electronMultiplicity() const { return pfSpecific().mElectronMultiplicity; }
0452 
0453     /// HFHadronMultiplicity
0454     int HFHadronMultiplicity() const { return pfSpecific().mHFHadronMultiplicity; }
0455     /// HFEMMultiplicity
0456     int HFEMMultiplicity() const { return pfSpecific().mHFEMMultiplicity; }
0457 
0458     /// chargedMuEnergy
0459     float chargedMuEnergy() const { return pfSpecific().mChargedMuEnergy; }
0460     /// chargedMuEnergyFraction
0461     float chargedMuEnergyFraction() const {
0462       return chargedMuEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy());
0463     }
0464 
0465     /// neutralMultiplicity
0466     int neutralMultiplicity() const { return pfSpecific().mNeutralMultiplicity; }
0467 
0468     /// hoEnergy
0469     float hoEnergy() const { return pfSpecific().mHOEnergy; }
0470     /// hoEnergyFraction (relative to corrected jet energy)
0471     float hoEnergyFraction() const { return hoEnergy() / ((jecSetsAvailable() ? jecFactor(0) : 1.) * energy()); }
0472     /// convert generic constituent to specific type
0473 
0474     //  static CaloTowerPtr caloTower (const reco::Candidate* fConstituent);
0475     /// get specific constituent of the CaloJet.
0476     /// if the caloTowers were embedded, this reference is transient only and must not be persisted
0477     reco::PFCandidatePtr getPFConstituent(unsigned fIndex) const;
0478     /// get the constituents of the CaloJet.
0479     /// If the caloTowers were embedded, these reference are transient only and must not be persisted
0480     std::vector<reco::PFCandidatePtr> const& getPFConstituents() const;
0481 
0482     /// get a pointer to a Candididate constituent of the jet
0483     ///    If using refactorized PAT, return that. (constituents size > 0)
0484     ///    Else check the old version of PAT (embedded constituents size > 0)
0485     ///    Else return the reco Jet number of constituents
0486     const reco::Candidate* daughter(size_t i) const override;
0487 
0488     reco::CandidatePtr daughterPtr(size_t i) const override;
0489     const reco::CompositePtrCandidate::daughters& daughterPtrVector() const override;
0490 
0491     using reco::LeafCandidate::daughter;  // avoid hiding the base implementation
0492 
0493     /// Return number of daughters:
0494     ///    If using refactorized PAT, return that. (constituents size > 0)
0495     ///    Else check the old version of PAT (embedded constituents size > 0)
0496     ///    Else return the reco Jet number of constituents
0497     size_t numberOfDaughters() const override;
0498 
0499     /// clear daughter references
0500     void clearDaughters() override {
0501       PATObject<reco::Jet>::clearDaughters();
0502       daughtersTemp_.reset();  // need to reset daughtersTemp_ as well
0503     }
0504 
0505     /// accessing Jet ID information
0506     reco::JetID const& jetID() const { return jetID_; }
0507 
0508     /// Access to bare FwdPtr collections
0509     CaloTowerFwdPtrVector const& caloTowersFwdPtr() const { return caloTowersFwdPtr_; }
0510     reco::PFCandidateFwdPtrVector const& pfCandidatesFwdPtr() const { return pfCandidatesFwdPtr_; }
0511     edm::FwdRef<reco::GenJetCollection> const& genJetFwdRef() const { return genJetFwdRef_; }
0512     TagInfoFwdPtrCollection const& tagInfosFwdPtr() const { return tagInfosFwdPtr_; }
0513 
0514     /// Update bare FwdPtr and FwdRef "forward" pointers while keeping the
0515     /// "back" pointers the same (i.e. the ref "forwarding")
0516     void updateFwdCaloTowerFwdPtr(unsigned int index, const edm::Ptr<CaloTower>& updateFwd) {
0517       if (index < caloTowersFwdPtr_.size()) {
0518         caloTowersFwdPtr_[index] = CaloTowerFwdPtrVector::value_type(updateFwd, caloTowersFwdPtr_[index].backPtr());
0519       } else {
0520         throw cms::Exception("OutOfRange") << "Index " << index << " is out of range" << std::endl;
0521       }
0522     }
0523 
0524     void updateFwdPFCandidateFwdPtr(unsigned int index, const edm::Ptr<reco::PFCandidate>& updateFwd) {
0525       if (index < pfCandidatesFwdPtr_.size()) {
0526         pfCandidatesFwdPtr_[index] =
0527             reco::PFCandidateFwdPtrVector::value_type(updateFwd, pfCandidatesFwdPtr_[index].backPtr());
0528       } else {
0529         throw cms::Exception("OutOfRange") << "Index " << index << " is out of range" << std::endl;
0530       }
0531     }
0532 
0533     void updateFwdTagInfoFwdPtr(unsigned int index, const edm::Ptr<reco::BaseTagInfo>& updateFwd) {
0534       if (index < tagInfosFwdPtr_.size()) {
0535         tagInfosFwdPtr_[index] = TagInfoFwdPtrCollection::value_type(updateFwd, tagInfosFwdPtr_[index].backPtr());
0536       } else {
0537         throw cms::Exception("OutOfRange") << "Index " << index << " is out of range" << std::endl;
0538       }
0539     }
0540 
0541     void updateFwdGenJetFwdRef(edm::Ref<reco::GenJetCollection> updateRef) {
0542       genJetFwdRef_ = edm::FwdRef<reco::GenJetCollection>(updateRef, genJetFwdRef_.backRef());
0543     }
0544 
0545     /// pipe operator (introduced to use pat::Jet with PFTopProjectors)
0546     friend std::ostream& reco::operator<<(std::ostream& out, const pat::Jet& obj);
0547 
0548     /// Access to subjet list
0549     pat::JetPtrCollection const& subjets(unsigned int index = 0) const;
0550 
0551     /// String access to subjet list
0552     pat::JetPtrCollection const& subjets(std::string const& label) const;
0553 
0554     /// Add new set of subjets
0555     void addSubjets(pat::JetPtrCollection const& pieces, std::string const& label = "");
0556 
0557     /// Check to see if the subjet collection exists
0558     bool hasSubjets(std::string const& label) const {
0559       return find(subjetLabels_.begin(), subjetLabels_.end(), label) != subjetLabels_.end();
0560     }
0561 
0562     /// Number of subjet collections
0563     unsigned int nSubjetCollections() const { return subjetCollections_.size(); }
0564 
0565     /// Subjet collection names
0566     std::vector<std::string> const& subjetCollectionNames() const { return subjetLabels_; }
0567 
0568     /// Access to mass of subjets
0569     double groomedMass(unsigned int index = 0) const {
0570       auto const& sub = subjets(index);
0571       return nSubjetCollections() > index && !sub.empty()
0572                  ? std::accumulate(
0573                        sub.begin(),
0574                        sub.end(),
0575                        reco::Candidate::LorentzVector(),
0576                        [](reco::Candidate::LorentzVector const& a, reco::CandidatePtr const& b) { return a + b->p4(); })
0577                        .mass()
0578                  : -1.0;
0579     }
0580     double groomedMass(std::string const& label) const {
0581       auto const& sub = subjets(label);
0582       return hasSubjets(label) && !sub.empty()
0583                  ? std::accumulate(
0584                        sub.begin(),
0585                        sub.end(),
0586                        reco::Candidate::LorentzVector(),
0587                        [](reco::Candidate::LorentzVector const& a, reco::CandidatePtr const& b) { return a + b->p4(); })
0588                        .mass()
0589                  : -1.0;
0590     }
0591 
0592   protected:
0593     // ---- for content embedding ----
0594 
0595     bool embeddedCaloTowers_;
0596     edm::AtomicPtrCache<std::vector<CaloTowerPtr> > caloTowersTemp_;  // to simplify user interface
0597     CaloTowerCollection caloTowers_;                                  // Compatibility embedding
0598     CaloTowerFwdPtrVector caloTowersFwdPtr_;                          // Refactorized content embedding
0599 
0600     bool embeddedPFCandidates_;
0601     edm::AtomicPtrCache<std::vector<reco::PFCandidatePtr> > pfCandidatesTemp_;  // to simplify user interface
0602     reco::PFCandidateCollection pfCandidates_;                                  // Compatibility embedding
0603     reco::PFCandidateFwdPtrVector pfCandidatesFwdPtr_;                          // Refactorized content embedding
0604 
0605     // ---- Jet Substructure ----
0606     std::vector<pat::JetPtrCollection> subjetCollections_;
0607     std::vector<std::string> subjetLabels_;
0608     edm::AtomicPtrCache<std::vector<reco::CandidatePtr> > daughtersTemp_;
0609 
0610     // ---- MC info ----
0611 
0612     std::vector<reco::GenJet> genJet_;
0613     reco::GenJetRefVector genJetRef_;
0614     edm::FwdRef<reco::GenJetCollection> genJetFwdRef_;
0615     reco::JetFlavourInfo jetFlavourInfo_;
0616 
0617     // ---- energy scale correction factors ----
0618 
0619     // energy scale correction factors; the string carries a potential label if
0620     // more then one set of correction factors is embedded. The label corresponds
0621     // to the label of the jetCorrFactors module that has been embedded.
0622     std::vector<pat::JetCorrFactors> jec_;
0623     // currently applied set of jet energy correction factors (i.e. the index in
0624     // jetEnergyCorrections_)
0625     unsigned int currentJECSet_;
0626     // currently applied jet energy correction level
0627     unsigned int currentJECLevel_;
0628     // currently applied jet energy correction flavor (can be NONE, GLUON, UDS,
0629     // CHARM or BOTTOM)
0630     JetCorrFactors::Flavor currentJECFlavor_;
0631 
0632     // ---- b-tag related members ----
0633 
0634     std::vector<std::pair<std::string, float> > pairDiscriVector_;
0635     std::vector<std::string> tagInfoLabels_;
0636     edm::OwnVector<reco::BaseTagInfo> tagInfos_;  // Compatibility embedding
0637     TagInfoFwdPtrCollection tagInfosFwdPtr_;      // Refactorized embedding
0638 
0639     // ---- track related members ----
0640 
0641     float jetCharge_;
0642     reco::TrackRefVector associatedTracks_;
0643 
0644     // ---- specific members ----
0645 
0646     std::vector<CaloSpecific> specificCalo_;
0647     std::vector<JPTSpecific> specificJPT_;
0648     std::vector<PFSpecific> specificPF_;
0649 
0650     // ---- id functions ----
0651     reco::JetID jetID_;
0652 
0653   private:
0654     // ---- helper functions ----
0655 
0656     void tryImportSpecific(const reco::Jet& source);
0657 
0658     template <typename T>
0659     const T* tagInfoByType() const {
0660       // First check the factorized PAT version
0661       for (size_t i = 0, n = tagInfosFwdPtr_.size(); i < n; ++i) {
0662         TagInfoFwdPtrCollection::value_type const& val = tagInfosFwdPtr_[i];
0663         reco::BaseTagInfo const* baseTagInfo = val.get();
0664         if (typeid(*baseTagInfo) == typeid(T)) {
0665           return static_cast<const T*>(baseTagInfo);
0666         }
0667       }
0668       // Then check compatibility version
0669       for (size_t i = 0, n = tagInfos_.size(); i < n; ++i) {
0670         edm::OwnVector<reco::BaseTagInfo>::value_type const& val = tagInfos_[i];
0671         reco::BaseTagInfo const* baseTagInfo = &val;
0672         if (typeid(*baseTagInfo) == typeid(T)) {
0673           return static_cast<const T*>(baseTagInfo);
0674         }
0675       }
0676       return nullptr;
0677     }
0678 
0679     template <typename T>
0680     const T* tagInfoByTypeOrLabel(const std::string& label = "") const {
0681       return (label.empty() ? tagInfoByType<T>() : dynamic_cast<const T*>(tagInfo(label)));
0682     }
0683 
0684     /// return the jet correction factors of a different set, for systematic studies
0685     const JetCorrFactors* corrFactors_(const std::string& set) const;
0686     /// return the correction factor for this jet. Throws if they're not available.
0687     const JetCorrFactors* corrFactors_() const;
0688 
0689     /// cache calo towers
0690     void cacheCaloTowers() const;
0691     void cachePFCandidates() const;
0692     void cacheDaughters() const;
0693   };
0694 }  // namespace pat
0695 
0696 inline float pat::Jet::chargedHadronEnergy() const {
0697   if (isPFJet()) {
0698     return pfSpecific().mChargedHadronEnergy;
0699   } else if (isJPTJet()) {
0700     return jptSpecific().mChargedHadronEnergy;
0701   } else {
0702     throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet nor from PFJet.\n";
0703   }
0704 }
0705 
0706 inline float pat::Jet::neutralHadronEnergy() const {
0707   if (isPFJet()) {
0708     return pfSpecific().mNeutralHadronEnergy;
0709   } else if (isJPTJet()) {
0710     return jptSpecific().mNeutralHadronEnergy;
0711   } else {
0712     throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet nor from PFJet.\n";
0713   }
0714 }
0715 
0716 inline float pat::Jet::chargedEmEnergy() const {
0717   if (isPFJet()) {
0718     return pfSpecific().mChargedEmEnergy;
0719   } else if (isJPTJet()) {
0720     return jptSpecific().mChargedEmEnergy;
0721   } else {
0722     throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet nor from PFJet.\n";
0723   }
0724 }
0725 
0726 inline float pat::Jet::neutralEmEnergy() const {
0727   if (isPFJet()) {
0728     return pfSpecific().mNeutralEmEnergy;
0729   } else if (isJPTJet()) {
0730     return jptSpecific().mNeutralEmEnergy;
0731   } else {
0732     throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet nor from PFJet.\n";
0733   }
0734 }
0735 
0736 inline int pat::Jet::muonMultiplicity() const {
0737   if (isPFJet()) {
0738     return pfSpecific().mMuonMultiplicity;
0739   } else if (isJPTJet()) {
0740     return jptSpecific().muonsInVertexInCalo.size() + jptSpecific().muonsInVertexOutCalo.size();
0741   } else {
0742     throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet nor from PFJet.\n";
0743   }
0744 }
0745 
0746 inline int pat::Jet::chargedMultiplicity() const {
0747   if (isPFJet()) {
0748     return pfSpecific().mChargedMultiplicity;
0749   } else if (isJPTJet()) {
0750     return jptSpecific().muonsInVertexInCalo.size() + jptSpecific().muonsInVertexOutCalo.size() +
0751            jptSpecific().pionsInVertexInCalo.size() + jptSpecific().pionsInVertexOutCalo.size() +
0752            jptSpecific().elecsInVertexInCalo.size() + jptSpecific().elecsInVertexOutCalo.size();
0753   } else {
0754     throw cms::Exception("Type Mismatch") << "This PAT jet was not made from a JPTJet nor from PFJet.\n";
0755   }
0756 }
0757 
0758 #endif