00001 // -*- C++ -*- 00002 // 00003 // Package: PFTauDecayModeCutMultiplexer 00004 // Class: PFTauDecayModeCutMultiplexer 00005 // 00006 /* 00007 00008 Description: Applies a different cut to a PFTauDiscriminator, depending on the 00009 the reconstructed DecayMode (stored by RecoTauTag/RecoTau/PFTauDecayModeIndexProducer) 00010 in PFTauDiscriminator form. 00011 00012 Produces a PFTauDiscriminator output with a binary (0 or 1) output. 00013 00014 Cuts are specified in the decay mode PSets, which map the cuts 00015 to collections of decay mode indices. These decay mode PSets are defined 00016 in the same manner as TaNC MVA computers (which also map to specific decay modes) 00017 00018 00019 */ 00020 // 00021 // Original Author: Evan K. Friis, UC Davis (friis@physics.ucdavis.edu) 00022 // Created: Thurs, April 16, 2009 00023 // $Id: PFTauDecayModeCutMultiplexer.cc,v 1.3 2010/10/19 21:29:13 wmtan Exp $ 00024 // 00025 // 00026 00027 #include "RecoTauTag/RecoTau/interface/TauDiscriminationProducerBase.h" 00028 00029 using namespace reco; 00030 00031 class PFTauDecayModeCutMultiplexer : public PFTauDiscriminationProducerBase { 00032 public: 00033 explicit PFTauDecayModeCutMultiplexer(const edm::ParameterSet&); 00034 ~PFTauDecayModeCutMultiplexer(){} 00035 00036 struct ComputerAndCut { 00037 std::string computerName; 00038 double userCut; 00039 }; 00040 00041 typedef std::vector<ComputerAndCut> CutList; 00042 typedef std::map<int, CutList::iterator> DecayModeToCutMap; 00043 00044 double discriminate(const PFTauRef& thePFTau); 00045 void beginEvent(const edm::Event& event, const edm::EventSetup& eventSetup); 00046 00047 private: 00048 // PFTau discriminator continaing the decaymode index of the tau collection 00049 edm::InputTag pfTauDecayModeIndexSrc_; 00050 00051 // Discriminant to multiplex cut on 00052 edm::InputTag discriminantToMultiplex_; 00053 00054 DecayModeToCutMap computerMap_; //Maps decay mode to MVA implementation 00055 CutList computers_; 00056 00057 edm::Handle<PFTauDiscriminator> pfTauDecayModeIndices; // holds the decay mode indices for the taus in the current event 00058 edm::Handle<PFTauDiscriminator> targetDiscriminant; // holds the discirminant values of the discriminant we will multiplex for the current event 00059 }; 00060 00061 PFTauDecayModeCutMultiplexer::PFTauDecayModeCutMultiplexer(const edm::ParameterSet& iConfig):PFTauDiscriminationProducerBase(iConfig) 00062 { 00063 pfTauDecayModeIndexSrc_ = iConfig.getParameter<edm::InputTag>("PFTauDecayModeSrc"); 00064 discriminantToMultiplex_ = iConfig.getParameter<edm::InputTag>("PFTauDiscriminantToMultiplex"); 00065 00066 //get the computer/decay mode map 00067 std::vector<edm::ParameterSet> decayModeMap = iConfig.getParameter<std::vector<edm::ParameterSet> >("computers"); 00068 computers_.reserve(decayModeMap.size()); 00069 00070 // for each decay mode MVA implementation (which may correspond to multiple decay modes, map the decay modes to the correct MVA computer 00071 for(std::vector<edm::ParameterSet>::const_iterator iComputer = decayModeMap.begin(); 00072 iComputer != decayModeMap.end(); 00073 ++iComputer) 00074 { 00075 ComputerAndCut toInsert; 00076 toInsert.computerName = iComputer->getParameter<std::string>("computerName"); 00077 toInsert.userCut = iComputer->getParameter<double>("cut"); 00078 CutList::iterator computerJustAdded = computers_.insert(computers_.end(), toInsert); //add this computer to the end of the list 00079 00080 //populate the map 00081 std::vector<int> associatedDecayModes = iComputer->getParameter<std::vector<int> >("decayModeIndices"); 00082 for(std::vector<int>::const_iterator iDecayMode = associatedDecayModes.begin(); 00083 iDecayMode != associatedDecayModes.end(); 00084 ++iDecayMode) 00085 { 00086 //map this integer specifying the decay mode to the MVA comptuer we just added to the list 00087 std::pair<DecayModeToCutMap::iterator, bool> insertResult = computerMap_.insert(std::make_pair(*iDecayMode, computerJustAdded)); 00088 00089 //make sure we aren't double mapping a decay mode 00090 if(insertResult.second == false) { //indicates that the current key (decaymode) has already been entered! 00091 throw cms::Exception("PFTauDecayModeCutMultiplexer::ctor") << "A tau decay mode: " << *iDecayMode << " has been mapped to two different MVA implementations, " 00092 << insertResult.first->second->computerName << " and " << toInsert.computerName 00093 << ". Please check the appropriate cfi file." << std::endl; 00094 } 00095 } 00096 } 00097 } 00098 00099 // ------------ get the relevant decay mode index handles at the beginning of each event ------------ 00100 void 00101 PFTauDecayModeCutMultiplexer::beginEvent(const edm::Event& iEvent, const edm::EventSetup& iSetup) 00102 { 00103 00104 iEvent.getByLabel(pfTauDecayModeIndexSrc_, pfTauDecayModeIndices); 00105 iEvent.getByLabel(discriminantToMultiplex_, targetDiscriminant); 00106 } 00107 00108 double PFTauDecayModeCutMultiplexer::discriminate(const PFTauRef& pfTau) 00109 { 00110 // get decay mode for current tau 00111 int decayMode = lrint( (*pfTauDecayModeIndices)[pfTau] ); //convert to int 00112 00113 // get value we are trying to multiplex 00114 float valueToMultiplex = (*targetDiscriminant)[pfTau]; 00115 00116 // Get correct cut 00117 DecayModeToCutMap::iterator iterToComputer = computerMap_.find(decayMode); 00118 if(iterToComputer != computerMap_.end()) //if we don't have a MVA mapped to this decay mode, skip it, it fails. 00119 { 00120 // use the supplied cut to make a decision 00121 if (valueToMultiplex > iterToComputer->second->userCut) 00122 return 1.0; 00123 else 00124 return 0.0; 00125 } 00126 00127 // no computer associated to this decay mode; it fails 00128 return 0.; 00129 } 00130 00131 DEFINE_FWK_MODULE(PFTauDecayModeCutMultiplexer);