CMS 3D CMS Logo

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