Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-08-28 03:59:09

0001 /**
0002   \class    pat::PATJetProducer PATJetProducer.h "PhysicsTools/PatAlgos/interface/PATJetProducer.h"
0003   \brief    Produces pat::Jet's
0004 
0005    The PATJetProducer produces analysis-level pat::Jet's starting from
0006    a collection of objects of JetType.
0007 
0008   \author   Steven Lowette, Jeremy Andrea
0009   \version  $Id: PATJetProducer.h,v 1.26 2010/08/09 18:13:54 srappocc Exp $
0010 */
0011 
0012 #include "CommonTools/Utils/interface/PtComparator.h"
0013 #include "DataFormats/BTauReco/interface/JetTag.h"
0014 #include "DataFormats/BTauReco/interface/SecondaryVertexTagInfo.h"
0015 #include "DataFormats/BTauReco/interface/SoftLeptonTagInfo.h"
0016 #include "DataFormats/BTauReco/interface/TrackCountingTagInfo.h"
0017 #include "DataFormats/BTauReco/interface/TrackIPTagInfo.h"
0018 #include "DataFormats/BTauReco/interface/TrackProbabilityTagInfo.h"
0019 #include "DataFormats/Candidate/interface/CandAssociation.h"
0020 #include "DataFormats/Candidate/interface/CandMatchMap.h"
0021 #include "DataFormats/Common/interface/Association.h"
0022 #include "DataFormats/Common/interface/ValueMap.h"
0023 #include "DataFormats/Common/interface/View.h"
0024 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
0025 #include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h"
0026 #include "DataFormats/JetMatching/interface/JetFlavourInfoMatching.h"
0027 #include "DataFormats/JetMatching/interface/JetFlavourMatching.h"
0028 #include "DataFormats/JetReco/interface/JetTracksAssociation.h"
0029 #include "DataFormats/Math/interface/deltaR.h"
0030 #include "DataFormats/PatCandidates/interface/Electron.h"
0031 #include "DataFormats/PatCandidates/interface/Jet.h"
0032 #include "DataFormats/PatCandidates/interface/JetCorrFactors.h"
0033 #include "DataFormats/PatCandidates/interface/Muon.h"
0034 #include "DataFormats/PatCandidates/interface/UserData.h"
0035 #include "FWCore/Framework/interface/Event.h"
0036 #include "FWCore/Framework/interface/stream/EDProducer.h"
0037 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0038 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0039 #include "FWCore/ParameterSet/interface/FileInPath.h"
0040 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0041 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0042 #include "FWCore/Utilities/interface/InputTag.h"
0043 #include "FWCore/Utilities/interface/transform.h"
0044 #include "PhysicsTools/PatAlgos/interface/EfficiencyLoader.h"
0045 #include "PhysicsTools/PatAlgos/interface/KinResolutionsLoader.h"
0046 #include "PhysicsTools/PatAlgos/interface/PATUserDataHelper.h"
0047 
0048 #include <algorithm>
0049 #include <memory>
0050 #include <vector>
0051 
0052 class JetFlavourIdentifier;
0053 
0054 namespace pat {
0055 
0056   class PATJetProducer : public edm::stream::EDProducer<> {
0057   public:
0058     explicit PATJetProducer(const edm::ParameterSet &iConfig);
0059     ~PATJetProducer() override;
0060 
0061     void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override;
0062 
0063     static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
0064 
0065   private:
0066     // configurables
0067     edm::EDGetTokenT<edm::View<reco::Jet>> jetsToken_;
0068     bool embedCaloTowers_;
0069     bool embedPFCandidates_;
0070     bool getJetMCFlavour_;
0071     bool useLegacyJetMCFlavour_;
0072     bool addJetFlavourInfo_;
0073     edm::EDGetTokenT<reco::JetFlavourMatchingCollection> jetPartonMapToken_;
0074     edm::EDGetTokenT<reco::JetFlavourInfoMatchingCollection> jetFlavourInfoToken_;
0075     bool addGenPartonMatch_;
0076     bool embedGenPartonMatch_;
0077     edm::EDGetTokenT<edm::Association<reco::GenParticleCollection>> genPartonToken_;
0078     bool addGenJetMatch_;
0079     bool embedGenJetMatch_;
0080     edm::EDGetTokenT<edm::Association<reco::GenJetCollection>> genJetToken_;
0081     bool addPartonJetMatch_;
0082     //       edm::EDGetTokenT<edm::View<reco::SomePartonJetType> > partonJetToken_;
0083     bool addJetCorrFactors_;
0084     std::vector<edm::EDGetTokenT<edm::ValueMap<JetCorrFactors>>> jetCorrFactorsTokens_;
0085 
0086     bool addBTagInfo_;
0087     bool addDiscriminators_;
0088     std::vector<edm::InputTag> discriminatorTags_;
0089     std::vector<edm::EDGetTokenT<reco::JetFloatAssociation::Container>> discriminatorTokens_;
0090     std::vector<std::string> discriminatorLabels_;
0091     bool addTagInfos_;
0092     std::vector<edm::InputTag> tagInfoTags_;
0093     std::vector<edm::EDGetTokenT<edm::View<reco::BaseTagInfo>>> tagInfoTokens_;
0094     std::vector<std::string> tagInfoLabels_;
0095     bool addAssociatedTracks_;
0096     edm::EDGetTokenT<reco::JetTracksAssociation::Container> trackAssociationToken_;
0097     bool addJetCharge_;
0098     edm::EDGetTokenT<reco::JetFloatAssociation::Container> jetChargeToken_;
0099     bool addJetID_;
0100     edm::EDGetTokenT<reco::JetIDValueMap> jetIDMapToken_;
0101     // tools
0102     GreaterByPt<Jet> pTComparator_;
0103     GreaterByPt<CaloTower> caloPTComparator_;
0104 
0105     bool addEfficiencies_;
0106     pat::helper::EfficiencyLoader efficiencyLoader_;
0107 
0108     bool addResolutions_;
0109     pat::helper::KinResolutionsLoader resolutionLoader_;
0110 
0111     bool useUserData_;
0112     pat::PATUserDataHelper<pat::Jet> userDataHelper_;
0113     //
0114     bool printWarning_;  // this is introduced to issue warnings only once per job
0115   };
0116 
0117 }  // namespace pat
0118 
0119 using namespace pat;
0120 
0121 PATJetProducer::PATJetProducer(const edm::ParameterSet &iConfig)
0122     : useUserData_(iConfig.exists("userData")), printWarning_(true) {
0123   // initialize configurables
0124   jetsToken_ = consumes<edm::View<reco::Jet>>(iConfig.getParameter<edm::InputTag>("jetSource"));
0125   embedCaloTowers_ = false;  // parameter is optional
0126   if (iConfig.exists("embedCaloTowers")) {
0127     embedCaloTowers_ = iConfig.getParameter<bool>("embedCaloTowers");
0128   }
0129   embedPFCandidates_ = iConfig.getParameter<bool>("embedPFCandidates");
0130   getJetMCFlavour_ = iConfig.getParameter<bool>("getJetMCFlavour");
0131   useLegacyJetMCFlavour_ = iConfig.getParameter<bool>("useLegacyJetMCFlavour");
0132   addJetFlavourInfo_ = (useLegacyJetMCFlavour_ ? false : iConfig.getParameter<bool>("addJetFlavourInfo"));
0133   if (getJetMCFlavour_ && useLegacyJetMCFlavour_)
0134     jetPartonMapToken_ =
0135         consumes<reco::JetFlavourMatchingCollection>(iConfig.getParameter<edm::InputTag>("JetPartonMapSource"));
0136   else if (getJetMCFlavour_ && !useLegacyJetMCFlavour_)
0137     jetFlavourInfoToken_ =
0138         consumes<reco::JetFlavourInfoMatchingCollection>(iConfig.getParameter<edm::InputTag>("JetFlavourInfoSource"));
0139   addGenPartonMatch_ = iConfig.getParameter<bool>("addGenPartonMatch");
0140   embedGenPartonMatch_ = iConfig.getParameter<bool>("embedGenPartonMatch");
0141   if (addGenPartonMatch_)
0142     genPartonToken_ =
0143         consumes<edm::Association<reco::GenParticleCollection>>(iConfig.getParameter<edm::InputTag>("genPartonMatch"));
0144   addGenJetMatch_ = iConfig.getParameter<bool>("addGenJetMatch");
0145   embedGenJetMatch_ = iConfig.getParameter<bool>("embedGenJetMatch");
0146   if (addGenJetMatch_)
0147     genJetToken_ =
0148         consumes<edm::Association<reco::GenJetCollection>>(iConfig.getParameter<edm::InputTag>("genJetMatch"));
0149   addPartonJetMatch_ = iConfig.getParameter<bool>("addPartonJetMatch");
0150   //   partonJetToken_ = mayConsume<reco::SomePartonJetType>(iConfig.getParameter<edm::InputTag>( "partonJetSource" ));
0151   addJetCorrFactors_ = iConfig.getParameter<bool>("addJetCorrFactors");
0152   if (addJetCorrFactors_) {
0153     jetCorrFactorsTokens_ = edm::vector_transform(
0154         iConfig.getParameter<std::vector<edm::InputTag>>("jetCorrFactorsSource"),
0155         [this](edm::InputTag const &tag) { return consumes<edm::ValueMap<JetCorrFactors>>(tag); });
0156   }
0157   addBTagInfo_ = iConfig.getParameter<bool>("addBTagInfo");
0158   addDiscriminators_ = iConfig.getParameter<bool>("addDiscriminators");
0159   discriminatorTags_ = iConfig.getParameter<std::vector<edm::InputTag>>("discriminatorSources");
0160   discriminatorTokens_ = edm::vector_transform(discriminatorTags_, [this](edm::InputTag const &tag) {
0161     return mayConsume<reco::JetFloatAssociation::Container>(tag);
0162   });
0163   addTagInfos_ = iConfig.getParameter<bool>("addTagInfos");
0164   tagInfoTags_ = iConfig.getParameter<std::vector<edm::InputTag>>("tagInfoSources");
0165   tagInfoTokens_ = edm::vector_transform(
0166       tagInfoTags_, [this](edm::InputTag const &tag) { return mayConsume<edm::View<reco::BaseTagInfo>>(tag); });
0167   addAssociatedTracks_ = iConfig.getParameter<bool>("addAssociatedTracks");
0168   if (addAssociatedTracks_)
0169     trackAssociationToken_ =
0170         consumes<reco::JetTracksAssociation::Container>(iConfig.getParameter<edm::InputTag>("trackAssociationSource"));
0171   addJetCharge_ = iConfig.getParameter<bool>("addJetCharge");
0172   if (addJetCharge_)
0173     jetChargeToken_ =
0174         consumes<reco::JetFloatAssociation::Container>(iConfig.getParameter<edm::InputTag>("jetChargeSource"));
0175   addJetID_ = iConfig.getParameter<bool>("addJetID");
0176   if (addJetID_)
0177     jetIDMapToken_ = consumes<reco::JetIDValueMap>(iConfig.getParameter<edm::InputTag>("jetIDMap"));
0178   // Efficiency configurables
0179   addEfficiencies_ = iConfig.getParameter<bool>("addEfficiencies");
0180   if (addEfficiencies_) {
0181     efficiencyLoader_ =
0182         pat::helper::EfficiencyLoader(iConfig.getParameter<edm::ParameterSet>("efficiencies"), consumesCollector());
0183   }
0184   // Resolution configurables
0185   addResolutions_ = iConfig.getParameter<bool>("addResolutions");
0186   if (addResolutions_) {
0187     resolutionLoader_ =
0188         pat::helper::KinResolutionsLoader(iConfig.getParameter<edm::ParameterSet>("resolutions"), consumesCollector());
0189   }
0190   if (discriminatorTags_.empty()) {
0191     addDiscriminators_ = false;
0192   } else {
0193     for (std::vector<edm::InputTag>::const_iterator it = discriminatorTags_.begin(), ed = discriminatorTags_.end();
0194          it != ed;
0195          ++it) {
0196       std::string label = it->label();
0197       std::string::size_type pos = label.find("JetTags");
0198       if ((pos != std::string::npos) && (pos != label.length() - 7)) {
0199         label.erase(pos + 7);  // trim a tail after "JetTags"
0200       }
0201       if (!it->instance().empty()) {
0202         label = (label + std::string(":") + it->instance());
0203       }
0204       discriminatorLabels_.push_back(label);
0205     }
0206   }
0207   if (tagInfoTags_.empty()) {
0208     addTagInfos_ = false;
0209   } else {
0210     for (std::vector<edm::InputTag>::const_iterator it = tagInfoTags_.begin(), ed = tagInfoTags_.end(); it != ed;
0211          ++it) {
0212       std::string label = it->label();
0213       std::string::size_type pos = label.find("TagInfos");
0214       if ((pos != std::string::npos) && (pos != label.length() - 8)) {
0215         label.erase(pos + 8);  // trim a tail after "TagInfos"
0216       }
0217       tagInfoLabels_.push_back(label);
0218     }
0219   }
0220   if (!addBTagInfo_) {
0221     addDiscriminators_ = false;
0222     addTagInfos_ = false;
0223   }
0224   // Check to see if the user wants to add user data
0225   if (useUserData_) {
0226     userDataHelper_ = PATUserDataHelper<Jet>(iConfig.getParameter<edm::ParameterSet>("userData"), consumesCollector());
0227   }
0228   // produces vector of jets
0229   produces<std::vector<Jet>>();
0230   produces<reco::GenJetCollection>("genJets");
0231   produces<std::vector<CaloTower>>("caloTowers");
0232   produces<reco::PFCandidateCollection>("pfCandidates");
0233   produces<edm::OwnVector<reco::BaseTagInfo>>("tagInfos");
0234 }
0235 
0236 PATJetProducer::~PATJetProducer() {}
0237 
0238 void PATJetProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
0239   // check whether dealing with MC or real data
0240   if (iEvent.isRealData()) {
0241     getJetMCFlavour_ = false;
0242     useLegacyJetMCFlavour_ = false;
0243     addJetFlavourInfo_ = false;
0244     addGenPartonMatch_ = false;
0245     addGenJetMatch_ = false;
0246     addPartonJetMatch_ = false;
0247   }
0248 
0249   // Get the vector of jets
0250   edm::Handle<edm::View<reco::Jet>> jets;
0251   iEvent.getByToken(jetsToken_, jets);
0252 
0253   if (efficiencyLoader_.enabled())
0254     efficiencyLoader_.newEvent(iEvent);
0255   if (resolutionLoader_.enabled())
0256     resolutionLoader_.newEvent(iEvent, iSetup);
0257 
0258   // for jet flavour
0259   edm::Handle<reco::JetFlavourMatchingCollection> jetFlavMatch;
0260   edm::Handle<reco::JetFlavourInfoMatchingCollection> jetFlavInfoMatch;
0261   if (getJetMCFlavour_ && useLegacyJetMCFlavour_)
0262     iEvent.getByToken(jetPartonMapToken_, jetFlavMatch);
0263   else if (getJetMCFlavour_ && !useLegacyJetMCFlavour_)
0264     iEvent.getByToken(jetFlavourInfoToken_, jetFlavInfoMatch);
0265 
0266   // Get the vector of generated particles from the event if needed
0267   edm::Handle<edm::Association<reco::GenParticleCollection>> partonMatch;
0268   if (addGenPartonMatch_)
0269     iEvent.getByToken(genPartonToken_, partonMatch);
0270   // Get the vector of GenJets from the event if needed
0271   edm::Handle<edm::Association<reco::GenJetCollection>> genJetMatch;
0272   if (addGenJetMatch_)
0273     iEvent.getByToken(genJetToken_, genJetMatch);
0274   /* TO BE IMPLEMENTED FOR >= 1_5_X
0275   // Get the vector of PartonJets from the event if needed
0276   edm::Handle<edm::View<reco::SomePartonJetType> > partonJets;
0277   if (addPartonJetMatch_) iEvent.getByToken(partonJetToken_, partonJets);
0278 */
0279 
0280   // read in the jet correction factors ValueMap
0281   std::vector<edm::ValueMap<JetCorrFactors>> jetCorrs;
0282   if (addJetCorrFactors_) {
0283     for (size_t i = 0; i < jetCorrFactorsTokens_.size(); ++i) {
0284       edm::Handle<edm::ValueMap<JetCorrFactors>> jetCorr;
0285       iEvent.getByToken(jetCorrFactorsTokens_[i], jetCorr);
0286       jetCorrs.push_back(*jetCorr);
0287     }
0288   }
0289 
0290   // Get the vector of jet tags with b-tagging info
0291   std::vector<edm::Handle<reco::JetFloatAssociation::Container>> jetDiscriminators;
0292   if (addBTagInfo_ && addDiscriminators_) {
0293     jetDiscriminators.resize(discriminatorTokens_.size());
0294     for (size_t i = 0; i < discriminatorTokens_.size(); ++i) {
0295       iEvent.getByToken(discriminatorTokens_[i], jetDiscriminators[i]);
0296     }
0297   }
0298   std::vector<edm::Handle<edm::View<reco::BaseTagInfo>>> jetTagInfos;
0299   if (addBTagInfo_ && addTagInfos_) {
0300     jetTagInfos.resize(tagInfoTokens_.size());
0301     for (size_t i = 0; i < tagInfoTokens_.size(); ++i) {
0302       iEvent.getByToken(tagInfoTokens_[i], jetTagInfos[i]);
0303     }
0304   }
0305 
0306   // tracks Jet Track Association
0307   edm::Handle<reco::JetTracksAssociation::Container> hTrackAss;
0308   if (addAssociatedTracks_)
0309     iEvent.getByToken(trackAssociationToken_, hTrackAss);
0310   edm::Handle<reco::JetFloatAssociation::Container> hJetChargeAss;
0311   if (addJetCharge_)
0312     iEvent.getByToken(jetChargeToken_, hJetChargeAss);
0313 
0314   // jet ID handle
0315   edm::Handle<reco::JetIDValueMap> hJetIDMap;
0316   if (addJetID_)
0317     iEvent.getByToken(jetIDMapToken_, hJetIDMap);
0318 
0319   // loop over jets
0320   auto patJets = std::make_unique<std::vector<Jet>>();
0321 
0322   auto genJetsOut = std::make_unique<reco::GenJetCollection>();
0323   auto caloTowersOut = std::make_unique<std::vector<CaloTower>>();
0324   auto pfCandidatesOut = std::make_unique<reco::PFCandidateCollection>();
0325   auto tagInfosOut = std::make_unique<edm::OwnVector<reco::BaseTagInfo>>();
0326 
0327   edm::RefProd<reco::GenJetCollection> h_genJetsOut = iEvent.getRefBeforePut<reco::GenJetCollection>("genJets");
0328   edm::RefProd<std::vector<CaloTower>> h_caloTowersOut = iEvent.getRefBeforePut<std::vector<CaloTower>>("caloTowers");
0329   edm::RefProd<reco::PFCandidateCollection> h_pfCandidatesOut =
0330       iEvent.getRefBeforePut<reco::PFCandidateCollection>("pfCandidates");
0331   edm::RefProd<edm::OwnVector<reco::BaseTagInfo>> h_tagInfosOut =
0332       iEvent.getRefBeforePut<edm::OwnVector<reco::BaseTagInfo>>("tagInfos");
0333 
0334   for (edm::View<reco::Jet>::const_iterator itJet = jets->begin(); itJet != jets->end(); itJet++) {
0335     // construct the Jet from the ref -> save ref to original object
0336     unsigned int idx = itJet - jets->begin();
0337     edm::RefToBase<reco::Jet> jetRef = jets->refAt(idx);
0338     edm::Ptr<reco::Jet> jetPtr = jets->ptrAt(idx);
0339     Jet ajet(jetRef);
0340 
0341     // add the FwdPtrs to the CaloTowers
0342     if ((ajet.isCaloJet() || ajet.isJPTJet()) && embedCaloTowers_) {
0343       const reco::CaloJet *cj = nullptr;
0344       const reco::JPTJet *jptj = nullptr;
0345       if (ajet.isCaloJet())
0346         cj = dynamic_cast<const reco::CaloJet *>(jetRef.get());
0347       else {
0348         jptj = dynamic_cast<const reco::JPTJet *>(jetRef.get());
0349         cj = dynamic_cast<const reco::CaloJet *>(jptj->getCaloJetRef().get());
0350       }
0351       pat::CaloTowerFwdPtrCollection itowersRef;
0352       std::vector<CaloTowerPtr> itowers = cj->getCaloConstituents();
0353       for (std::vector<CaloTowerPtr>::const_iterator towBegin = itowers.begin(),
0354                                                      towEnd = itowers.end(),
0355                                                      itow = towBegin;
0356            itow != towEnd;
0357            ++itow) {
0358         if (itow->isAvailable() && itow->isNonnull()) {
0359           caloTowersOut->push_back(**itow);
0360           // set the "forward" ref to the thinned collection
0361           edm::Ref<std::vector<CaloTower>> caloTowerRef(h_caloTowersOut, caloTowersOut->size() - 1);
0362           edm::Ptr<CaloTower> caloForwardRef(h_caloTowersOut.id(), caloTowerRef.key(), h_caloTowersOut.productGetter());
0363           // set the "backward" ref to the original collection for association
0364           edm::Ptr<CaloTower> caloBackRef(*itow);
0365           // add to the list of FwdPtr's
0366           itowersRef.push_back(pat::CaloTowerFwdPtrCollection::value_type(caloForwardRef, caloBackRef));
0367         }
0368       }
0369       ajet.setCaloTowers(itowersRef);
0370     }
0371 
0372     // add the FwdPtrs to the PFCandidates
0373     if (ajet.isPFJet() && embedPFCandidates_) {
0374       const reco::PFJet *cj = dynamic_cast<const reco::PFJet *>(jetRef.get());
0375       pat::PFCandidateFwdPtrCollection iparticlesRef;
0376       std::vector<reco::PFCandidatePtr> iparticles = cj->getPFConstituents();
0377       for (std::vector<reco::PFCandidatePtr>::const_iterator partBegin = iparticles.begin(),
0378                                                              partEnd = iparticles.end(),
0379                                                              ipart = partBegin;
0380            ipart != partEnd;
0381            ++ipart) {
0382         pfCandidatesOut->push_back(**ipart);
0383         // set the "forward" ref to the thinned collection
0384         edm::Ref<reco::PFCandidateCollection> pfCollectionRef(h_pfCandidatesOut, pfCandidatesOut->size() - 1);
0385         edm::Ptr<reco::PFCandidate> pfForwardRef(
0386             h_pfCandidatesOut.id(), pfCollectionRef.key(), h_pfCandidatesOut.productGetter());
0387         // set the "backward" ref to the original collection for association
0388         edm::Ptr<reco::PFCandidate> pfBackRef(*ipart);
0389         // add to the list of FwdPtr's
0390         iparticlesRef.push_back(pat::PFCandidateFwdPtrCollection::value_type(pfForwardRef, pfBackRef));
0391       }
0392       ajet.setPFCandidates(iparticlesRef);
0393     }
0394 
0395     if (addJetCorrFactors_) {
0396       // add additional JetCorrs to the jet
0397       for (unsigned int i = 0; i < jetCorrFactorsTokens_.size(); ++i) {
0398         const JetCorrFactors &jcf = jetCorrs[i][jetRef];
0399         // uncomment for debugging
0400         // jcf.print();
0401         ajet.addJECFactors(jcf);
0402       }
0403       std::vector<std::string> levels = jetCorrs[0][jetRef].correctionLabels();
0404       if (std::find(levels.begin(), levels.end(), "L2L3Residual") != levels.end()) {
0405         ajet.initializeJEC(jetCorrs[0][jetRef].jecLevel("L2L3Residual"));
0406       } else if (std::find(levels.begin(), levels.end(), "L3Absolute") != levels.end()) {
0407         ajet.initializeJEC(jetCorrs[0][jetRef].jecLevel("L3Absolute"));
0408       } else {
0409         ajet.initializeJEC(jetCorrs[0][jetRef].jecLevel("Uncorrected"));
0410         if (printWarning_) {
0411           edm::LogWarning("L3Absolute not found")
0412               << "L2L3Residual and L3Absolute are not part of the jetCorrFactors\n"
0413               << "of module " << jetCorrs[0][jetRef].jecSet() << ". Jets will remain"
0414               << " uncorrected.";
0415           printWarning_ = false;
0416         }
0417       }
0418     }
0419 
0420     // get the MC flavour information for this jet
0421     if (getJetMCFlavour_ && useLegacyJetMCFlavour_) {
0422       ajet.setPartonFlavour((*jetFlavMatch)[edm::RefToBase<reco::Jet>(jetRef)].getFlavour());
0423     } else if (getJetMCFlavour_ && !useLegacyJetMCFlavour_) {
0424       if (addJetFlavourInfo_)
0425         ajet.setJetFlavourInfo((*jetFlavInfoMatch)[edm::RefToBase<reco::Jet>(jetRef)]);
0426       else {
0427         ajet.setPartonFlavour((*jetFlavInfoMatch)[edm::RefToBase<reco::Jet>(jetRef)].getPartonFlavour());
0428         ajet.setHadronFlavour((*jetFlavInfoMatch)[edm::RefToBase<reco::Jet>(jetRef)].getHadronFlavour());
0429       }
0430     }
0431     // store the match to the generated partons
0432     if (addGenPartonMatch_) {
0433       reco::GenParticleRef parton = (*partonMatch)[jetRef];
0434       if (parton.isNonnull() && parton.isAvailable()) {
0435         ajet.setGenParton(parton, embedGenPartonMatch_);
0436       }  // leave empty if no match found
0437     }
0438     // store the match to the GenJets
0439     if (addGenJetMatch_) {
0440       reco::GenJetRef genjet = (*genJetMatch)[jetRef];
0441       if (genjet.isNonnull() && genjet.isAvailable()) {
0442         genJetsOut->push_back(*genjet);
0443         // set the "forward" ref to the thinned collection
0444         edm::Ref<reco::GenJetCollection> genForwardRef(h_genJetsOut, genJetsOut->size() - 1);
0445         // set the "backward" ref to the original collection
0446         const edm::Ref<reco::GenJetCollection> &genBackRef(genjet);
0447         // make the FwdPtr
0448         edm::FwdRef<reco::GenJetCollection> genjetFwdRef(genForwardRef, genBackRef);
0449         ajet.setGenJetRef(genjetFwdRef);
0450       }  // leave empty if no match found
0451     }
0452 
0453     if (efficiencyLoader_.enabled()) {
0454       efficiencyLoader_.setEfficiencies(ajet, jetRef);
0455     }
0456 
0457     // IMPORTANT: DO THIS AFTER JES CORRECTIONS
0458     if (resolutionLoader_.enabled()) {
0459       resolutionLoader_.setResolutions(ajet);
0460     }
0461 
0462     // TO BE IMPLEMENTED FOR >=1_5_X: do the PartonJet matching
0463     if (addPartonJetMatch_) {
0464     }
0465 
0466     // add b-tag info if available & required
0467     if (addBTagInfo_) {
0468       if (addDiscriminators_) {
0469         for (size_t k = 0; k < jetDiscriminators.size(); ++k) {
0470           float value = (*jetDiscriminators[k])[jetRef];
0471           ajet.addBDiscriminatorPair(std::make_pair(discriminatorLabels_[k], value));
0472         }
0473       }
0474       if (addTagInfos_) {
0475         for (size_t k = 0; k < jetTagInfos.size(); ++k) {
0476           const edm::View<reco::BaseTagInfo> &taginfos = *jetTagInfos[k];
0477           // This is not associative, so we have to search the jet
0478           edm::Ptr<reco::BaseTagInfo> match;
0479           // Try first by 'same index'
0480           if ((idx < taginfos.size()) && (taginfos[idx].jet() == jetRef)) {
0481             match = taginfos.ptrAt(idx);
0482           } else {
0483             // otherwise fail back to a simple search
0484             for (edm::View<reco::BaseTagInfo>::const_iterator itTI = taginfos.begin(), edTI = taginfos.end();
0485                  itTI != edTI;
0486                  ++itTI) {
0487               if (itTI->jet() == jetRef) {
0488                 match = taginfos.ptrAt(itTI - taginfos.begin());
0489                 break;
0490               }
0491             }
0492           }
0493           if (match.isNonnull()) {
0494             tagInfosOut->push_back(match->clone());
0495             // set the "forward" ptr to the thinned collection
0496             edm::Ptr<reco::BaseTagInfo> tagInfoForwardPtr(
0497                 h_tagInfosOut.id(), &tagInfosOut->back(), tagInfosOut->size() - 1);
0498             // set the "backward" ptr to the original collection for association
0499             const edm::Ptr<reco::BaseTagInfo> &tagInfoBackPtr(match);
0500             // make FwdPtr
0501             TagInfoFwdPtrCollection::value_type tagInfoFwdPtr(tagInfoForwardPtr, tagInfoBackPtr);
0502             ajet.addTagInfo(tagInfoLabels_[k], tagInfoFwdPtr);
0503           }
0504         }
0505       }
0506     }
0507 
0508     if (addAssociatedTracks_)
0509       ajet.setAssociatedTracks((*hTrackAss)[jetRef]);
0510 
0511     if (addJetCharge_)
0512       ajet.setJetCharge((*hJetChargeAss)[jetRef]);
0513 
0514     // add jet ID for calo jets
0515     if (addJetID_ && ajet.isCaloJet()) {
0516       reco::JetID jetId = (*hJetIDMap)[jetRef];
0517       ajet.setJetID(jetId);
0518     }
0519     // add jet ID jpt jets
0520     else if (addJetID_ && ajet.isJPTJet()) {
0521       const reco::JPTJet *jptj = dynamic_cast<const reco::JPTJet *>(jetRef.get());
0522       reco::JetID jetId = (*hJetIDMap)[jptj->getCaloJetRef()];
0523       ajet.setJetID(jetId);
0524     }
0525     if (useUserData_) {
0526       userDataHelper_.add(ajet, iEvent, iSetup);
0527     }
0528     patJets->push_back(ajet);
0529   }
0530 
0531   // sort jets in pt
0532   std::sort(patJets->begin(), patJets->end(), pTComparator_);
0533 
0534   // put genEvt  in Event
0535   iEvent.put(std::move(patJets));
0536 
0537   iEvent.put(std::move(genJetsOut), "genJets");
0538   iEvent.put(std::move(caloTowersOut), "caloTowers");
0539   iEvent.put(std::move(pfCandidatesOut), "pfCandidates");
0540   iEvent.put(std::move(tagInfosOut), "tagInfos");
0541 }
0542 
0543 // ParameterSet description for module
0544 void PATJetProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0545   edm::ParameterSetDescription iDesc;
0546   iDesc.setComment("PAT jet producer module");
0547 
0548   // input source
0549   iDesc.add<edm::InputTag>("jetSource", edm::InputTag("no default"))->setComment("input collection");
0550 
0551   // embedding
0552   iDesc.addOptional<bool>("embedCaloTowers", false)
0553       ->setComment("embed external CaloTowers (not to be used on AOD input)");
0554   iDesc.add<bool>("embedPFCandidates", true)->setComment("embed external PFCandidates");
0555 
0556   // MC matching configurables
0557   iDesc.add<bool>("addGenPartonMatch", true)->setComment("add MC matching");
0558   iDesc.add<bool>("embedGenPartonMatch", false)->setComment("embed MC matched MC information");
0559   iDesc.add<edm::InputTag>("genPartonMatch", edm::InputTag())->setComment("input with MC match information");
0560 
0561   iDesc.add<bool>("addGenJetMatch", true)->setComment("add MC matching");
0562   iDesc.add<bool>("embedGenJetMatch", false)->setComment("embed MC matched MC information");
0563   iDesc.add<edm::InputTag>("genJetMatch", edm::InputTag())->setComment("input with MC match information");
0564 
0565   iDesc.add<bool>("addJetCharge", true);
0566   iDesc.add<edm::InputTag>("jetChargeSource", edm::InputTag("patJetCharge"));
0567 
0568   // jet id
0569   iDesc.add<bool>("addJetID", true)->setComment("Add jet ID information");
0570   iDesc.add<edm::InputTag>("jetIDMap", edm::InputTag())->setComment("jet id map");
0571 
0572   iDesc.add<bool>("addPartonJetMatch", false);
0573   iDesc.add<edm::InputTag>("partonJetSource", edm::InputTag("NOT IMPLEMENTED"));
0574 
0575   // track association
0576   iDesc.add<bool>("addAssociatedTracks", true);
0577   iDesc.add<edm::InputTag>("trackAssociationSource", edm::InputTag("ak4JTA"));
0578 
0579   // tag info
0580   iDesc.add<bool>("addTagInfos", true);
0581   std::vector<edm::InputTag> emptyVInputTags;
0582   iDesc.add<std::vector<edm::InputTag>>("tagInfoSources", emptyVInputTags);
0583 
0584   // jet energy corrections
0585   iDesc.add<bool>("addJetCorrFactors", true);
0586   iDesc.add<std::vector<edm::InputTag>>("jetCorrFactorsSource", emptyVInputTags);
0587 
0588   // btag discriminator tags
0589   iDesc.add<bool>("addBTagInfo", true);
0590   iDesc.add<bool>("addDiscriminators", true);
0591   iDesc.add<std::vector<edm::InputTag>>("discriminatorSources", emptyVInputTags);
0592 
0593   // jet flavour idetification configurables
0594   iDesc.add<bool>("getJetMCFlavour", true);
0595   iDesc.add<bool>("useLegacyJetMCFlavour", false);
0596   iDesc.add<bool>("addJetFlavourInfo", false);
0597   iDesc.add<edm::InputTag>("JetPartonMapSource", edm::InputTag("jetFlavourAssociationLegacy"));
0598   iDesc.add<edm::InputTag>("JetFlavourInfoSource", edm::InputTag("jetFlavourAssociation"));
0599 
0600   pat::helper::KinResolutionsLoader::fillDescription(iDesc);
0601 
0602   // Efficiency configurables
0603   edm::ParameterSetDescription efficienciesPSet;
0604   efficienciesPSet.setAllowAnything();  // TODO: the pat helper needs to implement a description.
0605   iDesc.add("efficiencies", efficienciesPSet);
0606   iDesc.add<bool>("addEfficiencies", false);
0607 
0608   // Check to see if the user wants to add user data
0609   edm::ParameterSetDescription userDataPSet;
0610   PATUserDataHelper<Jet>::fillDescription(userDataPSet);
0611   iDesc.addOptional("userData", userDataPSet);
0612 
0613   descriptions.add("PATJetProducer", iDesc);
0614 }
0615 
0616 #include "FWCore/Framework/interface/MakerMacros.h"
0617 DEFINE_FWK_MODULE(PATJetProducer);