CMS 3D CMS Logo

RecoTauDiscriminantCutMultiplexer.cc
Go to the documentation of this file.
1 /*
2  * RecoTauDiscriminantCutMultiplexer
3  *
4  * Author: Evan K. Friis, UW
5  *
6  * Takes two PFTauDiscriminators.
7  *
8  * The "key" discriminantor is rounded to the nearest integer.
9  *
10  * A set of cuts for different keys on the "toMultiplex" discriminantor is
11  * provided in the config file.
12  *
13  * Both the key and toMultiplex discriminators should map to the same PFTau
14  * collection.
15  *
16  */
17 #include <boost/foreach.hpp>
23 
28 
29 #include "TMath.h"
30 #include "TGraph.h"
31 #include "TFormula.h"
32 #include "TFile.h"
33 
35 {
36  public:
38 
40  double discriminate(const reco::PFTauRef&) const override;
41  void beginEvent(const edm::Event& event, const edm::EventSetup& eventSetup) override;
42 
43  private:
45 
48 
50  {
52  : cutVariable_(),
53  cutFunction_(),
55  {}
57  {
58  }
59  double cutValue_;
61  std::unique_ptr<StringObjectFunction<reco::PFTau>> cutVariable_;
62  std::unique_ptr<const TGraph> cutFunction_;
64  int mode_;
65  };
66  typedef std::map<int, std::unique_ptr<DiscriminantCutEntry>> DiscriminantCutMap;
67  DiscriminantCutMap cuts_;
68 
70  std::unique_ptr<const TFormula> mvaOutput_normalization_;
71 
73 
80 
82 };
83 
84 namespace
85 {
86  std::unique_ptr<TFile> openInputFile(const edm::FileInPath& inputFileName) {
87  if ( inputFileName.location() == edm::FileInPath::Unknown){ throw cms::Exception("RecoTauDiscriminantCutMultiplexer::loadObjectFromFile")
88  << " Failed to find File = " << inputFileName << " !!\n";
89  }
90  return std::unique_ptr<TFile>{ new TFile(inputFileName.fullPath().data()) };
91  }
92 
93  template <typename T>
94  std::unique_ptr<const T> loadObjectFromFile(TFile& inputFile, const std::string& objectName)
95  {
96  const T* object = dynamic_cast<T*>(inputFile.Get(objectName.data()));
97  if ( !object )
98  throw cms::Exception("RecoTauDiscriminantCutMultiplexer::loadObjectFromFile")
99  << " Failed to load Object = " << objectName.data() << " from file = " << inputFile.GetName() << " !!\n";
100  //Need to use TObject::Clone since the type T might be a base class
101  std::unique_ptr<const T> copy{ static_cast<T*>(object->Clone()) };
102 
103  return std::move(copy);
104  }
105 
106  std::unique_ptr<const TGraph> loadTGraphFromDB(const edm::EventSetup& es, const std::string& graphName, const int& verbosity_ = 0)
107  {
108  if(verbosity_){
109  std::cout << "<loadTGraphFromDB>:" << std::endl;
110  std::cout << " graphName = " << graphName << std::endl;
111  }
113  es.get<PhysicsTGraphPayloadRcd>().get(graphName, graphPayload);
114  return std::unique_ptr<const TGraph>{ new TGraph(*graphPayload.product()) };
115  }
116 
117  std::unique_ptr<TFormula> loadTFormulaFromDB(const edm::EventSetup& es, const std::string& formulaName, const TString& newName, const int& verbosity_ = 0)
118  {
119  if(verbosity_){
120  std::cout << "<loadTFormulaFromDB>:" << std::endl;
121  std::cout << " formulaName = " << formulaName << std::endl;
122  }
124  es.get<PhysicsTFormulaPayloadRcd>().get(formulaName, formulaPayload);
125 
126  if ( formulaPayload->formulas().size() == 1 && formulaPayload->limits().size() == 1 ) {
127  return std::unique_ptr<TFormula> {new TFormula(newName, formulaPayload->formulas().at(0).data()) };
128  } else {
129  throw cms::Exception("RecoTauDiscriminantCutMultiplexer::loadTFormulaFromDB")
130  << "Failed to load TFormula = " << formulaName << " from Database !!\n";
131  }
132  return std::unique_ptr<TFormula>{};
133  }
134 }
135 
138  moduleLabel_(cfg.getParameter<std::string>("@module_label")),
141 {
142 
143  toMultiplex_ = cfg.getParameter<edm::InputTag>("toMultiplex");
144  toMultiplex_token = consumes<reco::PFTauDiscriminator>(toMultiplex_);
145  key_ = cfg.getParameter<edm::InputTag>("key");
146  key_token = consumes<reco::PFTauDiscriminator>(key_);
147 
148  verbosity_ = ( cfg.exists("verbosity") ) ?
149  cfg.getParameter<int>("verbosity") : 0;
150 
151 
152  loadMVAfromDB_ = cfg.exists("loadMVAfromDB") ? cfg.getParameter<bool>("loadMVAfromDB") : false;
153  if ( !loadMVAfromDB_ ) {
154  if(cfg.exists("inputFileName")){
155  inputFileName_ = cfg.getParameter<edm::FileInPath>("inputFileName");
156  }else throw cms::Exception("MVA input not defined") << "Requested to load tau MVA input from ROOT file but no file provided in cfg file";
157  }
158  if(verbosity_) std::cout << moduleLabel_ << " loadMVA = " << loadMVAfromDB_ << std::endl;
159  if ( cfg.exists("mvaOutput_normalization") ) {
160  mvaOutputNormalizationName_ = cfg.getParameter<std::string>("mvaOutput_normalization");
161  }
162 
163  // Setup our cut map
164  typedef std::vector<edm::ParameterSet> VPSet;
165  VPSet mapping = cfg.getParameter<VPSet>("mapping");
166  for ( VPSet::const_iterator mappingEntry = mapping.begin();
167  mappingEntry != mapping.end(); ++mappingEntry ) {
168  unsigned category = mappingEntry->getParameter<uint32_t>("category");
169  std::unique_ptr<DiscriminantCutEntry> cut{new DiscriminantCutEntry()};
170  if ( mappingEntry->existsAs<double>("cut") ) {
171  cut->cutValue_ = mappingEntry->getParameter<double>("cut");
173  } else if ( mappingEntry->existsAs<std::string>("cut") ) {
174  cut->cutName_ = mappingEntry->getParameter<std::string>("cut");
175  std::string cutVariable_string = mappingEntry->getParameter<std::string>("variable");
176  cut->cutVariable_.reset( new StringObjectFunction<reco::PFTau>(cutVariable_string.data()) );
178  } else {
179  throw cms::Exception("RecoTauDiscriminantCutMultiplexer")
180  << " Undefined Configuration Parameter 'cut' !!\n";
181  }
183  }
184 
185  verbosity_ = ( cfg.exists("verbosity") ) ?
186  cfg.getParameter<int>("verbosity") : 0;
187  if(verbosity_) std::cout << "constructed " << moduleLabel_ << std::endl;
188 }
189 
191 {
192 }
193 
195 {
196  if(verbosity_) std::cout << " begin! " << moduleLabel_ << " " << isInitialized_ << std::endl;
197  if ( !isInitialized_ ) {
198  //Only open the file once and we can close it when this routine is done
199  // since all objects gotten from the file will have been copied
200  std::unique_ptr<TFile> inputFile;
201  if ( mvaOutputNormalizationName_ != "" ) {
202  if ( !loadMVAfromDB_ ) {
203  inputFile = openInputFile(inputFileName_);
204  mvaOutput_normalization_ = loadObjectFromFile<TFormula>(*inputFile, mvaOutputNormalizationName_);
205  } else {
206  auto temp = loadTFormulaFromDB(es, mvaOutputNormalizationName_, Form("%s_mvaOutput_normalization", moduleLabel_.data()), verbosity_);
207  mvaOutput_normalization_.reset(temp.release());
208  }
209  }
210  for ( DiscriminantCutMap::iterator cut = cuts_.begin();
211  cut != cuts_.end(); ++cut ) {
212  if ( cut->second->mode_ == DiscriminantCutEntry::kVariableCut ) {
213  if ( !loadMVAfromDB_ ) {
214  if(not inputFile) {
215  inputFile = openInputFile(inputFileName_);
216  }
217  if(verbosity_) std::cout << "Loading from file" << inputFileName_ << std::endl;
218  cut->second->cutFunction_ = loadObjectFromFile<TGraph>(*inputFile, cut->second->cutName_);
219  } else {
220  if(verbosity_) std::cout << "Loading from DB" << std::endl;
221  cut->second->cutFunction_ = loadTGraphFromDB(es, cut->second->cutName_, verbosity_);
222  }
223  }
224  }
225  isInitialized_ = true;
226  }
227 
230 }
231 
232 double
234 {
235  if ( verbosity_ ) {
236  std::cout << "<RecoTauDiscriminantCutMultiplexer::discriminate>:" << std::endl;
237  std::cout << " moduleLabel = " << moduleLabel_ << std::endl;
238  }
239 
240  double disc_result = (*toMultiplexHandle_)[tau];
241  if ( verbosity_ ) {
242  std::cout << "disc_result = " << disc_result << std::endl;
243  }
244  if ( mvaOutput_normalization_ ) {
245  disc_result = mvaOutput_normalization_->Eval(disc_result);
246  //if ( disc_result > 1. ) disc_result = 1.;
247  //if ( disc_result < 0. ) disc_result = 0.;
248  if ( verbosity_ ) {
249  std::cout << "disc_result (normalized) = " << disc_result << std::endl;
250  }
251  }
252  double key_result = (*keyHandle_)[tau];
253  DiscriminantCutMap::const_iterator cutIter = cuts_.find(TMath::Nint(key_result));
254 
255 
256  // Return null if it doesn't exist
257  if ( cutIter == cuts_.end() ) {
259  }
260  // See if the discriminator passes our cuts
261  bool passesCuts = false;
262  if ( cutIter->second->mode_ == DiscriminantCutEntry::kFixedCut ) {
263  passesCuts = (disc_result > cutIter->second->cutValue_);
264  if ( verbosity_ ) {
265  std::cout << "cutValue (fixed) = " << cutIter->second->cutValue_ << " --> passesCuts = " << passesCuts << std::endl;
266  }
267  } else if ( cutIter->second->mode_ == DiscriminantCutEntry::kVariableCut ) {
268  double cutVariable = (*cutIter->second->cutVariable_)(*tau);
269  double xMin, xMax, dummy;
270  cutIter->second->cutFunction_->GetPoint(0, xMin, dummy);
271  cutIter->second->cutFunction_->GetPoint(cutIter->second->cutFunction_->GetN() - 1, xMax, dummy);
272  const double epsilon = 1.e-3;
273  if ( cutVariable < (xMin + epsilon) ) cutVariable = xMin + epsilon;
274  else if ( cutVariable > (xMax - epsilon) ) cutVariable = xMax - epsilon;
275  double cutValue = cutIter->second->cutFunction_->Eval(cutVariable);
276  passesCuts = (disc_result > cutValue);
277  if ( verbosity_ ) {
278  std::cout << "cutValue (@" << cutVariable << ") = " << cutValue << " --> passesCuts = " << passesCuts << std::endl;
279  }
280  } else assert(0);
281 
282  return passesCuts;
283 }
284 
T getParameter(std::string const &) const
std::unique_ptr< const TFormula > mvaOutput_normalization_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:460
edm::Handle< reco::PFTauDiscriminator > keyHandle_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
void beginEvent(const edm::Event &event, const edm::EventSetup &eventSetup) override
bool exists(std::string const &parameterName) const
checks if a parameter exists
edm::Handle< reco::PFTauDiscriminator > toMultiplexHandle_
string newName
Definition: mps_merge.py:84
std::unique_ptr< StringObjectFunction< reco::PFTau > > cutVariable_
const std::vector< std::string > & formulas() const
edm::EDGetTokenT< reco::PFTauDiscriminator > toMultiplex_token
double discriminate(const reco::PFTauRef &) const override
edm::EDGetTokenT< reco::PFTauDiscriminator > key_token
LocationCode location() const
Where was the file found?
Definition: FileInPath.cc:178
const T & get() const
Definition: EventSetup.h:56
RecoTauDiscriminantCutMultiplexer(const edm::ParameterSet &pset)
std::string fullPath() const
Definition: FileInPath.cc:184
const std::vector< std::pair< float, float > > & limits() const
std::map< int, std::unique_ptr< DiscriminantCutEntry > > DiscriminantCutMap
long double T
T const * product() const
Definition: ESHandle.h:86
def move(src, dest)
Definition: eostools.py:510
Definition: event.py:1