test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PATTauDiscriminationByMVAIsolationRun2.cc
Go to the documentation of this file.
1 
2 /*
3  * \class PATTauDiscriminationByMVAIsolationRun2
4  *
5  * MVA based discriminator against jet -> tau fakes
6  *
7  * Adopted from RecoTauTag/RecoTau/plugins/PFRecoTauDiscriminationByMVAIsolationRun2.cc
8  * to enable computation of MVA isolation on MiniAOD
9  *
10  * \author Alexander Nehrkorn, RWTH Aachen
11  */
12 
13 // todo 1: remove leadingTrackChi2 as input variable from:
14 // - here
15 // - TauPFEssential
16 // - PFRecoTauDiscriminationByMVAIsolationRun2
17 // - Training of BDT
18 // todo 2: do we need/want to add PATTauIDEmbedder?
19 
21 
27 
29 
35 
39 
40 #include <TMath.h>
41 #include <TFile.h>
42 
43 #include <iostream>
44 
45 using namespace pat;
46 
47 namespace
48 {
49  const GBRForest* loadMVAfromFile(const edm::FileInPath& inputFileName, const std::string& mvaName, std::vector<TFile*>& inputFilesToDelete)
50  {
51  if ( inputFileName.location() == edm::FileInPath::Unknown ) throw cms::Exception("PATTauDiscriminationByIsolationMVARun2::loadMVA")
52  << " Failed to find File = " << inputFileName << " !!\n";
53  TFile* inputFile = new TFile(inputFileName.fullPath().data());
54 
55  //const GBRForest* mva = dynamic_cast<GBRForest*>(inputFile->Get(mvaName.data())); // CV: dynamic_cast<GBRForest*> fails for some reason ?!
56  const GBRForest* mva = (GBRForest*)inputFile->Get(mvaName.data());
57  if ( !mva )
58  throw cms::Exception("PATTauDiscriminationByIsolationMVARun2::loadMVA")
59  << " Failed to load MVA = " << mvaName.data() << " from file = " << inputFileName.fullPath().data() << " !!\n";
60 
61  inputFilesToDelete.push_back(inputFile);
62 
63  return mva;
64  }
65 
66  const GBRForest* loadMVAfromDB(const edm::EventSetup& es, const std::string& mvaName)
67  {
69  es.get<GBRWrapperRcd>().get(mvaName, mva);
70  return mva.product();
71  }
72 }
73 
75 {
76  public:
79  moduleLabel_(cfg.getParameter<std::string>("@module_label")),
80  mvaReader_(0),
81  mvaInput_(0),
82  category_output_()
83  {
84  mvaName_ = cfg.getParameter<std::string>("mvaName");
85  loadMVAfromDB_ = cfg.exists("loadMVAfromDB") ? cfg.getParameter<bool>("loadMVAfromDB") : false;
86  if ( !loadMVAfromDB_ ) {
87  if(cfg.exists("inputFileName")){
88  inputFileName_ = cfg.getParameter<edm::FileInPath>("inputFileName");
89  }else throw cms::Exception("MVA input not defined") << "Requested to load tau MVA input from ROOT file but no file provided in cfg file";
90  }
91  std::string mvaOpt_string = cfg.getParameter<std::string>("mvaOpt");
92  if ( mvaOpt_string == "oldDMwoLT" ) mvaOpt_ = kOldDMwoLT;
93  else if ( mvaOpt_string == "oldDMwLT" ) mvaOpt_ = kOldDMwLT;
94  else if ( mvaOpt_string == "newDMwoLT" ) mvaOpt_ = kNewDMwoLT;
95  else if ( mvaOpt_string == "newDMwLT" ) mvaOpt_ = kNewDMwLT;
96  else if ( mvaOpt_string == "DBoldDMwLT" ) mvaOpt_ = kDBoldDMwLT;
97  else if ( mvaOpt_string == "DBnewDMwLT" ) mvaOpt_ = kDBnewDMwLT;
98  else if ( mvaOpt_string == "PWoldDMwLT" ) mvaOpt_ = kPWoldDMwLT;
99  else if ( mvaOpt_string == "PWnewDMwLT" ) mvaOpt_ = kPWnewDMwLT;
100  else throw cms::Exception("PATTauDiscriminationByMVAIsolationRun2")
101  << " Invalid Configuration Parameter 'mvaOpt' = " << mvaOpt_string << " !!\n";
102 
103  if ( mvaOpt_ == kOldDMwoLT || mvaOpt_ == kNewDMwoLT ) mvaInput_ = new float[6];
104  else if ( mvaOpt_ == kOldDMwLT || mvaOpt_ == kNewDMwLT ) mvaInput_ = new float[12];
105  else if ( mvaOpt_ == kDBoldDMwLT || mvaOpt_ == kDBnewDMwLT ||
106  mvaOpt_ == kPWoldDMwLT || mvaOpt_ == kPWnewDMwLT) mvaInput_ = new float[23];
107  else assert(0);
108 
109  chargedIsoPtSums_ = cfg.getParameter<std::string>("srcChargedIsoPtSum");
110  neutralIsoPtSums_ = cfg.getParameter<std::string>("srcNeutralIsoPtSum");
111  puCorrPtSums_ = cfg.getParameter<std::string>("srcPUcorrPtSum");
112  photonPtSumOutsideSignalCone_ = cfg.getParameter<std::string>("srcPhotonPtSumOutsideSignalCone");
113  footprintCorrection_ = cfg.getParameter<std::string>("srcFootprintCorrection");
114 
115  verbosity_ = ( cfg.exists("verbosity") ) ?
116  cfg.getParameter<int>("verbosity") : 0;
117 
118  produces<pat::PATTauDiscriminator>("category");
119  }
120 
121  void beginEvent(const edm::Event&, const edm::EventSetup&);
122 
123  double discriminate(const TauRef&) const;
124 
125  void endEvent(edm::Event&);
126 
128  {
129  if(!loadMVAfromDB_) delete mvaReader_;
130  delete[] mvaInput_;
131  for ( std::vector<TFile*>::iterator it = inputFilesToDelete_.begin();
132  it != inputFilesToDelete_.end(); ++it ) {
133  delete (*it);
134  }
135  }
136 
137  private:
138 
140 
145  enum { kOldDMwoLT, kOldDMwLT, kNewDMwoLT, kNewDMwLT, kDBoldDMwLT, kDBnewDMwLT, kPWoldDMwLT, kPWnewDMwLT };
146  int mvaOpt_;
147  float* mvaInput_;
148 
154 
156  std::unique_ptr<pat::PATTauDiscriminator> category_output_;
157  std::vector<TFile*> inputFilesToDelete_;
159 
161 };
162 
164 {
165  if( !mvaReader_ ) {
166  if ( loadMVAfromDB_ ) {
167  mvaReader_ = loadMVAfromDB(es, mvaName_);
168  } else {
169  mvaReader_ = loadMVAfromFile(inputFileName_, mvaName_, inputFilesToDelete_);
170  }
171  }
172 
173  evt.getByToken(Tau_token, taus_);
174  category_output_.reset(new pat::PATTauDiscriminator(TauRefProd(taus_)));
175 }
176 
178 {
179  // CV: define dummy category index in order to use RecoTauDiscriminantCutMultiplexer module to appy WP cuts
180  double category = 0.;
181  category_output_->setValue(tauIndex_, category);
182 
183  // CV: computation of MVA value requires presence of leading charged hadron
184  if ( tau->leadChargedHadrCand().isNull() ) return 0.;
185 
186  int tauDecayMode = tau->decayMode();
187 
188  if ( ((mvaOpt_ == kOldDMwoLT || mvaOpt_ == kOldDMwLT || mvaOpt_ == kDBoldDMwLT || mvaOpt_ == kPWoldDMwLT) && (tauDecayMode == 0 || tauDecayMode == 1 || tauDecayMode == 2 || tauDecayMode == 10)) ||
189  ((mvaOpt_ == kNewDMwoLT || mvaOpt_ == kNewDMwLT || mvaOpt_ == kDBnewDMwLT || mvaOpt_ == kPWnewDMwLT) && (tauDecayMode == 0 || tauDecayMode == 1 || tauDecayMode == 2 || tauDecayMode == 5 || tauDecayMode == 6 || tauDecayMode == 10)) ) {
190 
191  float chargedIsoPtSum = tau->tauID(chargedIsoPtSums_);
192  float neutralIsoPtSum = tau->tauID(neutralIsoPtSums_);
193  float puCorrPtSum = tau->tauID(puCorrPtSums_);
194  float photonPtSumOutsideSignalCone = tau->tauID(photonPtSumOutsideSignalCone_);
195  float footprintCorrection = tau->tauID(footprintCorrection_);
196 
197  float decayDistX = tau->flightLength().x();
198  float decayDistY = tau->flightLength().y();
199  float decayDistZ = tau->flightLength().z();
200  float decayDistMag = std::sqrt(decayDistX*decayDistX + decayDistY*decayDistY + decayDistZ*decayDistZ);
201 
202  // --- The following 5 variables differ slightly between AOD & MiniAOD
203  // because they are recomputed using packedCandidates saved in the tau
204  float nPhoton = (float)clusterVariables_.tau_n_photons_total(*tau);
205  float ptWeightedDetaStrip = clusterVariables_.tau_pt_weighted_deta_strip(*tau, tauDecayMode);
206  float ptWeightedDphiStrip = clusterVariables_.tau_pt_weighted_dphi_strip(*tau, tauDecayMode);
207  float ptWeightedDrSignal = clusterVariables_.tau_pt_weighted_dr_signal(*tau, tauDecayMode);
208  float ptWeightedDrIsolation = clusterVariables_.tau_pt_weighted_dr_iso(*tau, tauDecayMode);
209  // ---
210  float leadingTrackChi2 = tau->leadingTrackNormChi2();
211  float eRatio = clusterVariables_.tau_Eratio(*tau);
212 
213  if ( mvaOpt_ == kOldDMwoLT || mvaOpt_ == kNewDMwoLT ) {
214  mvaInput_[0] = std::log(std::max((float)1., (float)tau->pt()));
215  mvaInput_[1] = std::fabs((float)tau->eta());
216  mvaInput_[2] = std::log(std::max((float)1.e-2, chargedIsoPtSum));
217  mvaInput_[3] = std::log(std::max((float)1.e-2, neutralIsoPtSum - (float)0.125*puCorrPtSum));
218  mvaInput_[4] = std::log(std::max((float)1.e-2, puCorrPtSum));
219  mvaInput_[5] = tauDecayMode;
220  } else if ( mvaOpt_ == kOldDMwLT || mvaOpt_ == kNewDMwLT ) {
221  mvaInput_[0] = std::log(std::max((float)1., (float)tau->pt()));
222  mvaInput_[1] = std::fabs((float)tau->eta());
223  mvaInput_[2] = std::log(std::max((float)1.e-2, chargedIsoPtSum));
224  mvaInput_[3] = std::log(std::max((float)1.e-2, neutralIsoPtSum - (float)0.125*puCorrPtSum));
225  mvaInput_[4] = std::log(std::max((float)1.e-2, puCorrPtSum));
226  mvaInput_[5] = tauDecayMode;
227  mvaInput_[6] = TMath::Sign((float)+1., tau->dxy());
228  mvaInput_[7] = std::sqrt(std::min((float)1., std::fabs(tau->dxy())));
229  mvaInput_[8] = std::min((float)10., std::fabs(tau->dxy_Sig()));
230  mvaInput_[9] = ( tau->hasSecondaryVertex() ) ? 1. : 0.;
231  mvaInput_[10] = std::sqrt(decayDistMag);
232  mvaInput_[11] = std::min((float)10., tau->flightLengthSig());
233  } else if ( mvaOpt_ == kDBoldDMwLT || mvaOpt_ == kDBnewDMwLT ) {
234  mvaInput_[0] = std::log(std::max((float)1., (float)tau->pt()));
235  mvaInput_[1] = std::fabs(tau->eta());
236  mvaInput_[2] = std::log(std::max((float)1.e-2, chargedIsoPtSum));
237  mvaInput_[3] = std::log(std::max((float)1.e-2, neutralIsoPtSum));
238  mvaInput_[4] = std::log(std::max((float)1.e-2, puCorrPtSum));
239  mvaInput_[5] = std::log(std::max((float)1.e-2, photonPtSumOutsideSignalCone));
240  mvaInput_[6] = tauDecayMode;
241  mvaInput_[7] = std::min((float)30., nPhoton);
242  mvaInput_[8] = std::min((float)0.5, ptWeightedDetaStrip);
243  mvaInput_[9] = std::min((float)0.5, ptWeightedDphiStrip);
244  mvaInput_[10] = std::min((float)0.5, ptWeightedDrSignal);
245  mvaInput_[11] = std::min((float)0.5, ptWeightedDrIsolation);
246  mvaInput_[12] = std::min((float)100., leadingTrackChi2);
247  mvaInput_[13] = std::min((float)1., eRatio);
248  mvaInput_[14] = TMath::Sign((float)+1., tau->dxy());
249  mvaInput_[15] = std::sqrt(std::min((float)1., std::fabs(tau->dxy())));
250  mvaInput_[16] = std::min((float)10., std::fabs(tau->dxy_Sig()));
251  mvaInput_[17] = TMath::Sign((float)+1., tau->ip3d());
252  mvaInput_[18] = std::sqrt(std::min((float)1., std::fabs(tau->ip3d())));
253  mvaInput_[19] = std::min((float)10., std::fabs(tau->ip3d_Sig()));
254  mvaInput_[20] = ( tau->hasSecondaryVertex() ) ? 1. : 0.;
255  mvaInput_[21] = std::sqrt(decayDistMag);
256  mvaInput_[22] = std::min((float)10., tau->flightLengthSig());
257  } else if ( mvaOpt_ == kPWoldDMwLT || mvaOpt_ == kPWnewDMwLT ) {
258  mvaInput_[0] = std::log(std::max((float)1., (float)tau->pt()));
259  mvaInput_[1] = std::fabs(tau->eta());
260  mvaInput_[2] = std::log(std::max((float)1.e-2, chargedIsoPtSum));
261  mvaInput_[3] = std::log(std::max((float)1.e-2, neutralIsoPtSum));
262  mvaInput_[4] = std::log(std::max((float)1.e-2, footprintCorrection));
263  mvaInput_[5] = std::log(std::max((float)1.e-2, photonPtSumOutsideSignalCone));
264  mvaInput_[6] = tauDecayMode;
265  mvaInput_[7] = std::min((float)30., nPhoton);
266  mvaInput_[8] = std::min((float)0.5, ptWeightedDetaStrip);
267  mvaInput_[9] = std::min((float)0.5, ptWeightedDphiStrip);
268  mvaInput_[10] = std::min((float)0.5, ptWeightedDrSignal);
269  mvaInput_[11] = std::min((float)0.5, ptWeightedDrIsolation);
270  mvaInput_[12] = std::min((float)100., leadingTrackChi2);
271  mvaInput_[13] = std::min((float)1., eRatio);
272  mvaInput_[14] = TMath::Sign((float)+1., tau->dxy());
273  mvaInput_[15] = std::sqrt(std::fabs(std::min((float)1., std::fabs(tau->dxy()))));
274  mvaInput_[16] = std::min((float)10., std::fabs(tau->dxy_Sig()));
275  mvaInput_[17] = TMath::Sign((float)+1., tau->ip3d());
276  mvaInput_[18] = std::sqrt(std::fabs(std::min((float)1., std::fabs(tau->ip3d()))));
277  mvaInput_[19] = std::min((float)10., std::fabs(tau->ip3d_Sig()));
278  mvaInput_[20] = ( tau->hasSecondaryVertex() ) ? 1. : 0.;
279  mvaInput_[21] = std::sqrt(decayDistMag);
280  mvaInput_[22] = std::min((float)10., tau->flightLengthSig());
281  }
282 
283  double mvaValue = mvaReader_->GetClassifier(mvaInput_);
284  if ( verbosity_ ) {
285  edm::LogPrint("PATTauDiscByMVAIsolRun2") << "<PATTauDiscriminationByMVAIsolationRun2::discriminate>:";
286  edm::LogPrint("PATTauDiscByMVAIsolRun2") << " tau: Pt = " << tau->pt() << ", eta = " << tau->eta();
287  edm::LogPrint("PATTauDiscByMVAIsolRun2") << " isolation: charged = " << chargedIsoPtSum << ", neutral = " << neutralIsoPtSum << ", PUcorr = " << puCorrPtSum;
288  edm::LogPrint("PATTauDiscByMVAIsolRun2") << " decay mode = " << tauDecayMode;
289  edm::LogPrint("PATTauDiscByMVAIsolRun2") << " impact parameter: distance = " << tau->dxy() << ", significance = " << tau->dxy_Sig();
290  edm::LogPrint("PATTauDiscByMVAIsolRun2") << " has decay vertex = " << tau->hasSecondaryVertex() << ":"
291  << " distance = " << decayDistMag << ", significance = " << tau->flightLengthSig();
292  edm::LogPrint("PATTauDiscByMVAIsolRun2") << "--> mvaValue = " << mvaValue;
293  }
294  return mvaValue;
295  } else {
296  return -1.;
297  }
298 }
299 
301 {
302  // add all category indices to event
303  evt.put(std::move(category_output_), "category");
304 }
305 
T getParameter(std::string const &) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:122
edm::RefProd< TauCollection > TauRefProd
Definition: Tau.h:39
tuple cfg
Definition: looper.py:293
T Sign(T A, T B)
Definition: MathUtil.h:54
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:457
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
assert(m_qm.get())
bool exists(std::string const &parameterName) const
checks if a parameter exists
void beginEvent(const edm::Event &, const edm::EventSetup &)
T sqrt(T t)
Definition: SSEVec.h:18
def move
Definition: eostools.py:510
T min(T a, T b)
Definition: MathUtil.h:58
bool isNull() const
Checks for null.
Definition: Ref.h:249
LocationCode location() const
Where was the file found?
Definition: FileInPath.cc:178
std::unique_ptr< pat::PATTauDiscriminator > category_output_
const T & get() const
Definition: EventSetup.h:56
T const * product() const
Definition: ESHandle.h:86
std::string fullPath() const
Definition: FileInPath.cc:184
moduleLabel_(iConfig.getParameter< string >("@module_label"))
tuple loadMVAfromDB
Definition: mvaPFMET_cff.py:84