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 
28 
33 
34 #include "TMath.h"
35 #include "TGraph.h"
36 #include "TFormula.h"
37 #include "TFile.h"
38 
40 public:
42 
44  double discriminate(const pat::TauRef&) const override;
45  void beginEvent(const edm::Event& event, const edm::EventSetup& eventSetup) override;
46 
47  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
48 
49 private:
51 
54 
58  double cutValue_;
60  std::unique_ptr<StringObjectFunction<pat::Tau>> cutVariable_;
61  std::unique_ptr<const TGraph> cutFunction_;
63  int mode_;
64  };
65  typedef std::map<int, std::unique_ptr<DiscriminantCutEntry>> DiscriminantCutMap;
66  DiscriminantCutMap cuts_;
67 
69  std::unique_ptr<const TFormula> mvaOutput_normalization_;
70 
72 
79 
81 };
82 
83 namespace {
84  std::unique_ptr<TFile> openInputFile(const edm::FileInPath& inputFileName) {
85  if (inputFileName.location() == edm::FileInPath::Unknown) {
86  throw cms::Exception("PATTauDiscriminantCutMultiplexer::loadObjectFromFile")
87  << " Failed to find File = " << inputFileName << " !!\n";
88  }
89  return std::unique_ptr<TFile>{new TFile(inputFileName.fullPath().data())};
90  }
91 
92  template <typename T>
93  std::unique_ptr<const T> loadObjectFromFile(TFile& inputFile, const std::string& objectName) {
94  const T* object = dynamic_cast<T*>(inputFile.Get(objectName.data()));
95  if (!object)
96  throw cms::Exception("PATTauDiscriminantCutMultiplexer::loadObjectFromFile")
97  << " Failed to load Object = " << objectName.data() << " from file = " << inputFile.GetName() << " !!\n";
98  //Need to use TObject::Clone since the type T might be a base class
99  return std::unique_ptr<const T>{static_cast<T*>(object->Clone())};
100  }
101 
102  std::unique_ptr<const TGraph> loadTGraphFromDB(const edm::EventSetup& es,
103  const std::string& graphName,
104  const int& verbosity_ = 0) {
105  if (verbosity_) {
106  std::cout << "<loadTGraphFromDB>:" << std::endl;
107  std::cout << " graphName = " << graphName << std::endl;
108  }
110  es.get<PhysicsTGraphPayloadRcd>().get(graphName, graphPayload);
111  return std::unique_ptr<const TGraph>{new TGraph(*graphPayload.product())};
112  }
113 
114  std::unique_ptr<TFormula> loadTFormulaFromDB(const edm::EventSetup& es,
115  const std::string& formulaName,
116  const TString& newName,
117  const int& verbosity_ = 0) {
118  if (verbosity_) {
119  std::cout << "<loadTFormulaFromDB>:" << std::endl;
120  std::cout << " formulaName = " << formulaName << std::endl;
121  }
123  es.get<PhysicsTFormulaPayloadRcd>().get(formulaName, formulaPayload);
124 
125  if (formulaPayload->formulas().size() == 1 && formulaPayload->limits().size() == 1) {
126  return std::unique_ptr<TFormula>{new TFormula(newName, formulaPayload->formulas().at(0).data())};
127  } else {
128  throw cms::Exception("PATTauDiscriminantCutMultiplexer::loadTFormulaFromDB")
129  << "Failed to load TFormula = " << formulaName << " from Database !!\n";
130  }
131  return std::unique_ptr<TFormula>{};
132  }
133 } // namespace
134 
137  moduleLabel_(cfg.getParameter<std::string>("@module_label")),
140  toMultiplex_ = cfg.getParameter<edm::InputTag>("toMultiplex");
141  toMultiplex_token = consumes<pat::PATTauDiscriminator>(toMultiplex_);
142  key_ = cfg.getParameter<edm::InputTag>("key");
143  key_token = consumes<pat::PATTauDiscriminator>(key_);
144 
145  verbosity_ = cfg.getParameter<int>("verbosity");
146  loadMVAfromDB_ = cfg.getParameter<bool>("loadMVAfromDB");
147  if (!loadMVAfromDB_) {
148  inputFileName_ = cfg.getParameter<edm::FileInPath>("inputFileName");
149  }
150  if (verbosity_)
151  std::cout << moduleLabel_ << " loadMVA = " << loadMVAfromDB_ << std::endl;
153  "mvaOutput_normalization"); // default value is "" which should just overwrite existing value with same empty string
154 
155  // Setup our cut map
156  typedef std::vector<edm::ParameterSet> VPSet;
157  VPSet mapping = cfg.getParameter<VPSet>("mapping");
158  for (VPSet::const_iterator mappingEntry = mapping.begin(); mappingEntry != mapping.end(); ++mappingEntry) {
159  unsigned category = mappingEntry->getParameter<uint32_t>("category");
160  std::unique_ptr<DiscriminantCutEntry> cut{new DiscriminantCutEntry()};
161  if (mappingEntry->existsAs<double>("cut")) {
162  cut->cutValue_ = mappingEntry->getParameter<double>("cut");
164  } else if (mappingEntry->existsAs<std::string>("cut")) {
165  cut->cutName_ = mappingEntry->getParameter<std::string>("cut");
166  std::string cutVariable_string = mappingEntry->getParameter<std::string>("variable");
167  cut->cutVariable_.reset(new StringObjectFunction<pat::Tau>(cutVariable_string));
169  } else {
170  throw cms::Exception("PATTauDiscriminantCutMultiplexer") << " Undefined Configuration Parameter 'cut' !!\n";
171  }
173  }
174  verbosity_ = cfg.getParameter<int>("verbosity");
175  if (verbosity_)
176  std::cout << "constructed " << moduleLabel_ << std::endl;
177 }
178 
180 
182  if (verbosity_)
183  std::cout << " begin! " << moduleLabel_ << " " << isInitialized_ << std::endl;
184  if (!isInitialized_) {
185  //Only open the file once and we can close it when this routine is done
186  // since all objects gotten from the file will have been copied
187  std::unique_ptr<TFile> inputFile;
188  if (!mvaOutputNormalizationName_.empty()) {
189  if (!loadMVAfromDB_) {
190  inputFile = openInputFile(inputFileName_);
191  mvaOutput_normalization_ = loadObjectFromFile<TFormula>(*inputFile, mvaOutputNormalizationName_);
192  } else {
193  auto temp = loadTFormulaFromDB(
194  es, mvaOutputNormalizationName_, Form("%s_mvaOutput_normalization", moduleLabel_.data()), verbosity_);
196  }
197  }
198  for (DiscriminantCutMap::iterator cut = cuts_.begin(); cut != cuts_.end(); ++cut) {
199  if (cut->second->mode_ == DiscriminantCutEntry::kVariableCut) {
200  if (!loadMVAfromDB_) {
201  if (not inputFile) {
202  inputFile = openInputFile(inputFileName_);
203  }
204  if (verbosity_)
205  std::cout << "Loading from file" << inputFileName_ << std::endl;
206  cut->second->cutFunction_ = loadObjectFromFile<TGraph>(*inputFile, cut->second->cutName_);
207  } else {
208  if (verbosity_)
209  std::cout << "Loading from DB" << std::endl;
210  cut->second->cutFunction_ = loadTGraphFromDB(es, cut->second->cutName_, verbosity_);
211  }
212  }
213  }
214  isInitialized_ = true;
215  }
216 
219 }
220 
222  if (verbosity_) {
223  std::cout << "<PATTauDiscriminantCutMultiplexer::discriminate>:" << std::endl;
224  std::cout << " moduleLabel = " << moduleLabel_ << std::endl;
225  }
226 
227  double disc_result = (*toMultiplexHandle_)[tau];
228  if (verbosity_) {
229  std::cout << "disc_result = " << disc_result << std::endl;
230  }
232  disc_result = mvaOutput_normalization_->Eval(disc_result);
233  //if ( disc_result > 1. ) disc_result = 1.;
234  //if ( disc_result < 0. ) disc_result = 0.;
235  if (verbosity_) {
236  std::cout << "disc_result (normalized) = " << disc_result << std::endl;
237  }
238  }
239  double key_result = (*keyHandle_)[tau];
240  DiscriminantCutMap::const_iterator cutIter = cuts_.find(TMath::Nint(key_result));
241 
242  // Return null if it doesn't exist
243  if (cutIter == cuts_.end()) {
245  }
246  // See if the discriminator passes our cuts
247  bool passesCuts = false;
248  if (cutIter->second->mode_ == DiscriminantCutEntry::kFixedCut) {
249  passesCuts = (disc_result > cutIter->second->cutValue_);
250  if (verbosity_) {
251  std::cout << "cutValue (fixed) = " << cutIter->second->cutValue_ << " --> passesCuts = " << passesCuts
252  << std::endl;
253  }
254  } else if (cutIter->second->mode_ == DiscriminantCutEntry::kVariableCut) {
255  double cutVariable = (*cutIter->second->cutVariable_)(*tau);
256  double xMin, xMax, dummy;
257  cutIter->second->cutFunction_->GetPoint(0, xMin, dummy);
258  cutIter->second->cutFunction_->GetPoint(cutIter->second->cutFunction_->GetN() - 1, xMax, dummy);
259  const double epsilon = 1.e-3;
260  if (cutVariable < (xMin + epsilon))
261  cutVariable = xMin + epsilon;
262  else if (cutVariable > (xMax - epsilon))
263  cutVariable = xMax - epsilon;
264  double cutValue = cutIter->second->cutFunction_->Eval(cutVariable);
265  passesCuts = (disc_result > cutValue);
266  if (verbosity_) {
267  std::cout << "cutValue (@" << cutVariable << ") = " << cutValue << " --> passesCuts = " << passesCuts
268  << std::endl;
269  }
270  } else
271  assert(0);
272 
273  return passesCuts;
274 }
275 
277  // patTauDiscriminantCutMultiplexer
279  desc.add<edm::InputTag>("toMultiplex", edm::InputTag("fixme"));
280  desc.add<int>("verbosity", 0);
281  {
282  edm::ParameterSetDescription desc_mapping;
283  desc_mapping.add<unsigned int>("category");
284  desc_mapping.setAllowAnything(); //option cut can be double or (string plus additional option variable)
285 
286  std::vector<edm::ParameterSet> vpsd_mapping;
287  edm::ParameterSet psd1;
288  psd1.addParameter<unsigned int>("category", 0);
289  psd1.addParameter<double>("cut", 0.5);
290  vpsd_mapping.push_back(psd1);
291  edm::ParameterSet psd2;
292  psd2.addParameter<unsigned int>("category", 1);
293  psd2.addParameter<double>("cut", 0.2);
294  vpsd_mapping.push_back(psd2);
295  desc.addVPSet("mapping", desc_mapping, vpsd_mapping);
296  }
297  desc.add<edm::FileInPath>("inputFileName", edm::FileInPath("RecoTauTag/RecoTau/data/emptyMVAinputFile"));
298  desc.add<bool>("loadMVAfromDB", true);
299  fillProducerDescriptions(desc); // inherited from the base
300  desc.add<std::string>("mvaOutput_normalization", "");
301  desc.add<edm::InputTag>("key", edm::InputTag("fixme"));
302  descriptions.add("patTauDiscriminantCutMultiplexer", desc);
303 }
304 
T getParameter(std::string const &) const
ParameterDescriptionBase * addVPSet(U const &iLabel, ParameterSetDescription const &validator, std::vector< ParameterSet > const &defaults)
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:525
void setAllowAnything()
allow any parameter label/value pairs
PATTauDiscriminantCutMultiplexer(const edm::ParameterSet &pset)
std::map< int, std::unique_ptr< DiscriminantCutEntry > > DiscriminantCutMap
std::unique_ptr< StringObjectFunction< pat::Tau > > cutVariable_
const std::vector< std::pair< float, float > > & limits() const
edm::EDGetTokenT< pat::PATTauDiscriminator > key_token
string newName
Definition: mps_merge.py:86
const std::vector< std::string > & formulas() const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static void fillProducerDescriptions(edm::ParameterSetDescription &desc)
edm::EDGetTokenT< pat::PATTauDiscriminator > toMultiplex_token
void addParameter(std::string const &name, T const &value)
Definition: ParameterSet.h:124
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
LocationCode location() const
Where was the file found?
Definition: FileInPath.cc:161
ParameterDescriptionBase * add(U const &iLabel, T const &value)
edm::Handle< pat::PATTauDiscriminator > toMultiplexHandle_
edm::Handle< pat::PATTauDiscriminator > keyHandle_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
double discriminate(const pat::TauRef &) const override
T get() const
Definition: EventSetup.h:73
std::string fullPath() const
Definition: FileInPath.cc:163
long double T
T const * product() const
Definition: ESHandle.h:86
def move(src, dest)
Definition: eostools.py:511
Definition: event.py:1