Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:27:50

0001 // -*- C++ -*-
0002 //
0003 // Package:    PFTauDecayModeCutMultiplexer
0004 // Class:      PFTauDecayModeCutMultiplexer
0005 //
0006 /*
0007 
0008  Description: Applies a different cut to a PFTauDiscriminator, depending on the 
0009               the reconstructed DecayMode (stored by RecoTauTag/RecoTau/PFTauDecayModeIndexProducer) 
0010               in PFTauDiscriminator form.
0011 
0012               Produces a PFTauDiscriminator output with a binary (0 or 1) output.
0013 
0014               Cuts are specified in the decay mode PSets, which map the cuts 
0015               to collections of decay mode indices.  These decay mode PSets are defined
0016               in the same manner as TaNC MVA computers (which also map to specific decay modes)
0017 
0018 
0019 */
0020 //
0021 // Original Author:  Evan K. Friis, UC Davis (friis@physics.ucdavis.edu)
0022 //         Created:  Thurs, April 16, 2009
0023 //
0024 //
0025 
0026 #include "RecoTauTag/RecoTau/interface/TauDiscriminationProducerBase.h"
0027 
0028 #include <FWCore/ParameterSet/interface/ConfigurationDescriptions.h>
0029 #include <FWCore/ParameterSet/interface/ParameterSetDescription.h>
0030 
0031 using namespace reco;
0032 
0033 class PFTauDecayModeCutMultiplexer : public PFTauDiscriminationProducerBase {
0034 public:
0035   explicit PFTauDecayModeCutMultiplexer(const edm::ParameterSet&);
0036   ~PFTauDecayModeCutMultiplexer() override {}
0037 
0038   struct ComputerAndCut {
0039     std::string computerName;
0040     double userCut;
0041   };
0042 
0043   typedef std::vector<ComputerAndCut> CutList;
0044   typedef std::map<int, CutList::iterator> DecayModeToCutMap;
0045 
0046   double discriminate(const PFTauRef& thePFTau) const override;
0047   void beginEvent(const edm::Event& event, const edm::EventSetup& eventSetup) override;
0048 
0049   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0050 
0051 private:
0052   // PFTau discriminator continaing the decaymode index of the tau collection
0053   edm::InputTag pfTauDecayModeIndexSrc_;
0054   edm::EDGetTokenT<PFTauDiscriminator> pfTauDecayModeIndex_token;
0055 
0056   // Discriminant to multiplex cut on
0057   edm::InputTag discriminantToMultiplex_;
0058   edm::EDGetTokenT<PFTauDiscriminator> discriminant_token;
0059 
0060   DecayModeToCutMap computerMap_;  //Maps decay mode to MVA implementation
0061   CutList computers_;
0062 
0063   edm::Handle<PFTauDiscriminator>
0064       pfTauDecayModeIndices;  // holds the decay mode indices for the taus in the current event
0065   edm::Handle<PFTauDiscriminator>
0066       targetDiscriminant;  // holds the discirminant values of the discriminant we will multiplex for the current event
0067 };
0068 
0069 PFTauDecayModeCutMultiplexer::PFTauDecayModeCutMultiplexer(const edm::ParameterSet& iConfig)
0070     : PFTauDiscriminationProducerBase(iConfig) {
0071   pfTauDecayModeIndexSrc_ = iConfig.getParameter<edm::InputTag>("PFTauDecayModeSrc");
0072   discriminantToMultiplex_ = iConfig.getParameter<edm::InputTag>("PFTauDiscriminantToMultiplex");
0073   pfTauDecayModeIndex_token = consumes<PFTauDiscriminator>(pfTauDecayModeIndexSrc_);
0074   discriminant_token = consumes<PFTauDiscriminator>(discriminantToMultiplex_);
0075   //get the computer/decay mode map
0076   std::vector<edm::ParameterSet> decayModeMap = iConfig.getParameter<std::vector<edm::ParameterSet> >("computers");
0077   computers_.reserve(decayModeMap.size());
0078 
0079   // for each decay mode MVA implementation (which may correspond to multiple decay modes, map the decay modes to the correct MVA computer
0080   for (std::vector<edm::ParameterSet>::const_iterator iComputer = decayModeMap.begin(); iComputer != decayModeMap.end();
0081        ++iComputer) {
0082     ComputerAndCut toInsert;
0083     toInsert.computerName = iComputer->getParameter<std::string>("computerName");
0084     toInsert.userCut = iComputer->getParameter<double>("cut");
0085     CutList::iterator computerJustAdded =
0086         computers_.insert(computers_.end(), toInsert);  //add this computer to the end of the list
0087 
0088     //populate the map
0089     std::vector<int> associatedDecayModes = iComputer->getParameter<std::vector<int> >("decayModeIndices");
0090     for (std::vector<int>::const_iterator iDecayMode = associatedDecayModes.begin();
0091          iDecayMode != associatedDecayModes.end();
0092          ++iDecayMode) {
0093       //map this integer specifying the decay mode to the MVA comptuer we just added to the list
0094       std::pair<DecayModeToCutMap::iterator, bool> insertResult =
0095           computerMap_.insert(std::make_pair(*iDecayMode, computerJustAdded));
0096 
0097       //make sure we aren't double mapping a decay mode
0098       if (insertResult.second == false) {  //indicates that the current key (decaymode) has already been entered!
0099         throw cms::Exception("PFTauDecayModeCutMultiplexer::ctor")
0100             << "A tau decay mode: " << *iDecayMode << " has been mapped to two different MVA implementations, "
0101             << insertResult.first->second->computerName << " and " << toInsert.computerName
0102             << ". Please check the appropriate cfi file." << std::endl;
0103       }
0104     }
0105   }
0106 }
0107 
0108 // ------------ get the relevant decay mode index handles at the beginning of each event ------------
0109 void PFTauDecayModeCutMultiplexer::beginEvent(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0110   iEvent.getByToken(pfTauDecayModeIndex_token, pfTauDecayModeIndices);
0111   iEvent.getByToken(discriminant_token, targetDiscriminant);
0112 }
0113 
0114 double PFTauDecayModeCutMultiplexer::discriminate(const PFTauRef& pfTau) const {
0115   // get decay mode for current tau
0116   int decayMode = lrint((*pfTauDecayModeIndices)[pfTau]);  //convert to int
0117 
0118   // get value we are trying to multiplex
0119   float valueToMultiplex = (*targetDiscriminant)[pfTau];
0120 
0121   // Get correct cut
0122   auto iterToComputer = computerMap_.find(decayMode);
0123   if (iterToComputer != computerMap_.end())  //if we don't have a MVA mapped to this decay mode, skip it, it fails.
0124   {
0125     // use the supplied cut to make a decision
0126     if (valueToMultiplex > iterToComputer->second->userCut)
0127       return 1.0;
0128     else
0129       return 0.0;
0130   }
0131 
0132   // no computer associated to this decay mode; it fails
0133   return 0.;
0134 }
0135 
0136 void PFTauDecayModeCutMultiplexer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0137   // pfTauDecayModeCutMultiplexer
0138   edm::ParameterSetDescription desc;
0139 
0140   desc.add<edm::InputTag>("PFTauDecayModeSrc");
0141   desc.add<edm::InputTag>("PFTauDiscriminantToMultiplex");
0142 
0143   edm::ParameterSetDescription vpsd_computers;
0144   vpsd_computers.add<std::string>("computerName");
0145   vpsd_computers.add<double>("cut");
0146   vpsd_computers.add<std::vector<int> >("decayModeIndices");
0147 
0148   //               name        description    defaults items
0149   //desc.addVPSet("computers", vpsd_builders, builders_vector);
0150   desc.addVPSet("computers", vpsd_computers);
0151 
0152   fillProducerDescriptions(desc);  // inherited from the base
0153 
0154   descriptions.add("pfTauDecayModeCutMultiplexer", desc);
0155 }
0156 
0157 DEFINE_FWK_MODULE(PFTauDecayModeCutMultiplexer);