Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:24:37

0001 // -*- C++ -*-
0002 //
0003 // Package:    JetTagProducer
0004 // Class:      JetTagProducer
0005 //
0006 /**\class JetTagProducer JetTagProducer.cc RecoBTag/JetTagProducer/src/JetTagProducer.cc
0007 
0008  Description: Uses a JetTagComputer to produce JetTags from TagInfos
0009 
0010  Implementation:
0011      <Notes on implementation>
0012 */
0013 //
0014 // Original Author:  Andrea Rizzi
0015 //         Created:  Thu Apr  6 09:56:23 CEST 2006
0016 //
0017 //
0018 
0019 // system include files
0020 #include <memory>
0021 #include <string>
0022 #include <vector>
0023 #include <map>
0024 
0025 // user include files
0026 #include "FWCore/Framework/interface/Frameworkfwd.h"
0027 #include "FWCore/Framework/interface/Event.h"
0028 #include "FWCore/Framework/interface/EventSetup.h"
0029 #include "FWCore/Framework/interface/ESHandle.h"
0030 #include "FWCore/Framework/interface/makeRefToBaseProdFrom.h"
0031 #include "FWCore/Framework/interface/global/EDProducer.h"
0032 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0033 #include "FWCore/Utilities/interface/InputTag.h"
0034 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0035 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0036 #include "FWCore/Utilities/interface/Exception.h"
0037 #include "FWCore/Utilities/interface/EDMException.h"
0038 
0039 #include "RecoBTau/JetTagComputer/interface/JetTagComputer.h"
0040 #include "RecoBTau/JetTagComputer/interface/JetTagComputerRecord.h"
0041 #include "DataFormats/Common/interface/View.h"
0042 #include "DataFormats/BTauReco/interface/BaseTagInfo.h"
0043 #include "DataFormats/Common/interface/RefToBase.h"
0044 #include "DataFormats/TrackReco/interface/Track.h"
0045 #include "DataFormats/BTauReco/interface/JetTag.h"
0046 
0047 #include <string>
0048 #include <vector>
0049 #include <map>
0050 
0051 using namespace std;
0052 using namespace reco;
0053 using namespace edm;
0054 
0055 class JetTagProducer : public edm::global::EDProducer<> {
0056 public:
0057   explicit JetTagProducer(const edm::ParameterSet &);
0058   static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
0059 
0060 private:
0061   void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override;
0062 
0063   std::vector<edm::EDGetTokenT<edm::View<reco::BaseTagInfo> > > token_tagInfos_;
0064   const edm::ESGetToken<JetTagComputer, JetTagComputerRecord> token_computer_;
0065   const edm::EDPutTokenT<JetTagCollection> token_put_;
0066   mutable std::atomic<unsigned long long> recordCacheID_{0};
0067   unsigned int nTagInfos_;
0068 };
0069 
0070 //
0071 // constructors and destructor
0072 //
0073 JetTagProducer::JetTagProducer(const ParameterSet &iConfig)
0074     : token_computer_(esConsumes(edm::ESInputTag("", iConfig.getParameter<string>("jetTagComputer")))),
0075       token_put_(produces()) {
0076   const std::vector<edm::InputTag> tagInfos = iConfig.getParameter<vector<InputTag> >("tagInfos");
0077   nTagInfos_ = tagInfos.size();
0078   token_tagInfos_.reserve(nTagInfos_);
0079   std::transform(tagInfos.begin(), tagInfos.end(), std::back_inserter(token_tagInfos_), [this](auto const &tagInfo) {
0080     return consumes<View<BaseTagInfo> >(tagInfo);
0081   });
0082 }
0083 
0084 //
0085 // member functions
0086 //
0087 
0088 // map helper - for some reason RefToBase lacks operator < (...)
0089 namespace {
0090   struct JetRefCompare {
0091     inline bool operator()(const RefToBase<Jet> &j1, const RefToBase<Jet> &j2) const {
0092       return j1.id() < j2.id() || (j1.id() == j2.id() && j1.key() < j2.key());
0093     }
0094   };
0095 }  // namespace
0096 
0097 // ------------ method called to produce the data  ------------
0098 void JetTagProducer::produce(StreamID, Event &iEvent, const EventSetup &iSetup) const {
0099   auto const &computer = iSetup.getData(token_computer_);
0100 
0101   auto oldID = recordCacheID_.load();
0102   auto newID = iSetup.get<JetTagComputerRecord>().cacheIdentifier();
0103   if (oldID != newID) {
0104     unsigned int nLabels = computer.getInputLabels().size();
0105     if (nLabels == 0)
0106       ++nLabels;
0107     if (nTagInfos_ != nLabels) {
0108       vector<string> inputLabels(computer.getInputLabels());
0109       // backward compatible case, use default tagInfo
0110       if (inputLabels.empty())
0111         inputLabels.push_back("tagInfo");
0112       std::string message(
0113           "VInputTag size mismatch - the following taginfo "
0114           "labels are needed:\n");
0115       for (vector<string>::const_iterator iter = inputLabels.begin(); iter != inputLabels.end(); ++iter)
0116         message += "\"" + *iter + "\"\n";
0117       throw edm::Exception(errors::Configuration) << message;
0118     }
0119     //only if we didn't encounter a problem should we update the cache
0120     // that way other threads will see the same problem
0121     recordCacheID_.compare_exchange_strong(oldID, newID);
0122   }
0123 
0124   // now comes the tricky part:
0125   // we need to collect all requested TagInfos belonging to the same jet
0126 
0127   typedef vector<const BaseTagInfo *> TagInfoPtrs;
0128   typedef RefToBase<Jet> JetRef;
0129   typedef map<JetRef, TagInfoPtrs, JetRefCompare> JetToTagInfoMap;
0130 
0131   JetToTagInfoMap jetToTagInfos;
0132 
0133   // retrieve all requested TagInfos
0134   Handle<View<BaseTagInfo> > tagInfoHandle;
0135   for (unsigned int i = 0; i < nTagInfos_; i++) {
0136     auto tagHandle = iEvent.getHandle(token_tagInfos_[i]);
0137     // take first tagInfo
0138     if (not tagInfoHandle.isValid()) {
0139       tagInfoHandle = tagHandle;
0140     }
0141 
0142     for (auto const &tagInfo : *tagHandle) {
0143       TagInfoPtrs &tagInfos = jetToTagInfos[tagInfo.jet()];
0144       if (tagInfos.empty())
0145         tagInfos.resize(nTagInfos_);
0146 
0147       tagInfos[i] = &tagInfo;
0148     }
0149   }
0150 
0151   std::unique_ptr<JetTagCollection> jetTagCollection;
0152   if (!tagInfoHandle.product()->empty()) {
0153     RefToBase<Jet> jj = tagInfoHandle->begin()->jet();
0154     jetTagCollection = std::make_unique<JetTagCollection>(edm::makeRefToBaseProdFrom(jj, iEvent));
0155   } else
0156     jetTagCollection = std::make_unique<JetTagCollection>();
0157 
0158   // now loop over the map and compute all JetTags
0159   for (JetToTagInfoMap::const_iterator iter = jetToTagInfos.begin(); iter != jetToTagInfos.end(); iter++) {
0160     const TagInfoPtrs &tagInfoPtrs = iter->second;
0161 
0162     JetTagComputer::TagInfoHelper helper(tagInfoPtrs);
0163     float discriminator = computer(helper);
0164 
0165     (*jetTagCollection)[iter->first] = discriminator;
0166   }
0167 
0168   iEvent.put(token_put_, std::move(jetTagCollection));
0169 }
0170 
0171 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
0172 void JetTagProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0173   edm::ParameterSetDescription desc;
0174   desc.add<std::string>("jetTagComputer", "combinedMVAComputer");
0175   {
0176     std::vector<edm::InputTag> tagInfos;
0177     tagInfos.push_back(edm::InputTag("impactParameterTagInfos"));
0178     tagInfos.push_back(edm::InputTag("inclusiveSecondaryVertexFinderTagInfos"));
0179     tagInfos.push_back(edm::InputTag("softPFMuonsTagInfos"));
0180     tagInfos.push_back(edm::InputTag("softPFElectronsTagInfos"));
0181     desc.add<std::vector<edm::InputTag> >("tagInfos", tagInfos);
0182   }
0183   descriptions.addDefault(desc);
0184 }
0185 
0186 // define it as plugin
0187 #include "FWCore/Framework/interface/MakerMacros.h"
0188 DEFINE_FWK_MODULE(JetTagProducer);