CMS 3D CMS Logo

PFRecoTauDiscriminationByMVAIsolation2.cc
Go to the documentation of this file.
1 
11 
17 
19 
22 
29 
33 
34 #include <TMath.h>
35 #include <TFile.h>
36 
37 #include <iostream>
38 
39 using namespace reco;
40 
41 namespace
42 {
43  const GBRForest* loadMVAfromFile(const edm::FileInPath& inputFileName, const std::string& mvaName, std::vector<TFile*>& inputFilesToDelete)
44  {
45  if ( inputFileName.location() == edm::FileInPath::Unknown ) throw cms::Exception("PFRecoTauDiscriminationByIsolationMVA2::loadMVA")
46  << " Failed to find File = " << inputFileName << " !!\n";
47  TFile* inputFile = new TFile(inputFileName.fullPath().data());
48 
49  //const GBRForest* mva = dynamic_cast<GBRForest*>(inputFile->Get(mvaName.data())); // CV: dynamic_cast<GBRForest*> fails for some reason ?!
50  const GBRForest* mva = (GBRForest*)inputFile->Get(mvaName.data());
51  if ( !mva )
52  throw cms::Exception("PFRecoTauDiscriminationByIsolationMVA2::loadMVA")
53  << " Failed to load MVA = " << mvaName.data() << " from file = " << inputFileName.fullPath().data() << " !!\n";
54 
55  inputFilesToDelete.push_back(inputFile);
56 
57  return mva;
58  }
59 
60  const GBRForest* loadMVAfromDB(const edm::EventSetup& es, const std::string& mvaName)
61  {
63  es.get<GBRWrapperRcd>().get(mvaName, mva);
64  return mva.product();
65  }
66 }
67 
69 {
70  public:
73  moduleLabel_(cfg.getParameter<std::string>("@module_label")),
74  mvaReader_(nullptr),
75  mvaInput_(nullptr),
76  category_output_()
77  {
78  mvaName_ = cfg.getParameter<std::string>("mvaName");
79  loadMVAfromDB_ = cfg.getParameter<bool>("loadMVAfromDB");
80  if ( !loadMVAfromDB_ ) {
81  inputFileName_ = cfg.getParameter<edm::FileInPath>("inputFileName");
82  }
83  std::string mvaOpt_string = cfg.getParameter<std::string>("mvaOpt");
84  if ( mvaOpt_string == "oldDMwoLT" ) mvaOpt_ = kOldDMwoLT;
85  else if ( mvaOpt_string == "oldDMwLT" ) mvaOpt_ = kOldDMwLT;
86  else if ( mvaOpt_string == "newDMwoLT" ) mvaOpt_ = kNewDMwoLT;
87  else if ( mvaOpt_string == "newDMwLT" ) mvaOpt_ = kNewDMwLT;
88  else throw cms::Exception("PFRecoTauDiscriminationByIsolationMVA2")
89  << " Invalid Configuration Parameter 'mvaOpt' = " << mvaOpt_string << " !!\n";
90 
91  if ( mvaOpt_ == kOldDMwoLT || mvaOpt_ == kNewDMwoLT ) mvaInput_ = new float[6];
92  else if ( mvaOpt_ == kOldDMwLT || mvaOpt_ == kNewDMwLT ) mvaInput_ = new float[12];
93  else assert(0);
94 
95  TauTransverseImpactParameters_token = consumes<PFTauTIPAssociationByRef>(cfg.getParameter<edm::InputTag>("srcTauTransverseImpactParameters"));
96 
97  ChargedIsoPtSum_token = consumes<reco::PFTauDiscriminator>(cfg.getParameter<edm::InputTag>("srcChargedIsoPtSum"));
98  NeutralIsoPtSum_token = consumes<reco::PFTauDiscriminator>(cfg.getParameter<edm::InputTag>("srcNeutralIsoPtSum"));
99  PUcorrPtSum_token = consumes<reco::PFTauDiscriminator>(cfg.getParameter<edm::InputTag>("srcPUcorrPtSum"));
100 
101  verbosity_ = cfg.getParameter<int>("verbosity");
102 
103  produces<PFTauDiscriminator>("category");
104  }
105 
106  void beginEvent(const edm::Event&, const edm::EventSetup&) override;
107 
108  double discriminate(const PFTauRef&) const override;
109 
110  void endEvent(edm::Event&) override;
111 
113  {
114  if(!loadMVAfromDB_) delete mvaReader_;
115  delete[] mvaInput_;
116  for ( std::vector<TFile*>::iterator it = inputFilesToDelete_.begin();
117  it != inputFilesToDelete_.end(); ++it ) {
118  delete (*it);
119  }
120  }
121 
122  static void fillDescriptions(edm::ConfigurationDescriptions & descriptions);
123  private:
124 
126 
132  int mvaOpt_;
133  float* mvaInput_;
134 
138 
145 
147  std::unique_ptr<PFTauDiscriminator> category_output_;
148 
149  std::vector<TFile*> inputFilesToDelete_;
150 
152 };
153 
155 {
156  if ( !mvaReader_ ) {
157  if ( loadMVAfromDB_ ) {
158  mvaReader_ = loadMVAfromDB(es, mvaName_);
159  } else {
160  mvaReader_ = loadMVAfromFile(inputFileName_, mvaName_, inputFilesToDelete_);
161  }
162  }
163 
164  evt.getByToken(TauTransverseImpactParameters_token, tauLifetimeInfos);
165 
166  evt.getByToken(ChargedIsoPtSum_token, chargedIsoPtSums_);
167  evt.getByToken(NeutralIsoPtSum_token, neutralIsoPtSums_);
168  evt.getByToken(PUcorrPtSum_token, puCorrPtSums_);
169 
170  evt.getByToken(Tau_token, taus_);
171  category_output_.reset(new PFTauDiscriminator(TauRefProd(taus_)));
172 }
173 
175 {
176  // CV: define dummy category index in order to use RecoTauDiscriminantCutMultiplexer module to appy WP cuts
177  double category = 0.;
178  category_output_->setValue(tauIndex_, category);
179 
180  // CV: computation of MVA value requires presence of leading charged hadron
181  if ( tau->leadChargedHadrCand().isNull() ) return 0.;
182 
183  int tauDecayMode = tau->decayMode();
184 
185  if ( ((mvaOpt_ == kOldDMwoLT || mvaOpt_ == kOldDMwLT) && (tauDecayMode == 0 || tauDecayMode == 1 || tauDecayMode == 2 || tauDecayMode == 10)) ||
186  ((mvaOpt_ == kNewDMwoLT || mvaOpt_ == kNewDMwLT) && (tauDecayMode == 0 || tauDecayMode == 1 || tauDecayMode == 2 || tauDecayMode == 5 || tauDecayMode == 6 || tauDecayMode == 10)) ) {
187 
188  double chargedIsoPtSum = (*chargedIsoPtSums_)[tau];
189  double neutralIsoPtSum = (*neutralIsoPtSums_)[tau];
190  double puCorrPtSum = (*puCorrPtSums_)[tau];
191 
192  const reco::PFTauTransverseImpactParameter& tauLifetimeInfo = *(*tauLifetimeInfos)[tau];
193 
194  double decayDistX = tauLifetimeInfo.flightLength().x();
195  double decayDistY = tauLifetimeInfo.flightLength().y();
196  double decayDistZ = tauLifetimeInfo.flightLength().z();
197  double decayDistMag = TMath::Sqrt(decayDistX*decayDistX + decayDistY*decayDistY + decayDistZ*decayDistZ);
198 
199  if ( mvaOpt_ == kOldDMwoLT || mvaOpt_ == kNewDMwoLT ) {
200  mvaInput_[0] = TMath::Log(TMath::Max(1., Double_t(tau->pt())));
201  mvaInput_[1] = TMath::Abs(tau->eta());
202  mvaInput_[2] = TMath::Log(TMath::Max(1.e-2, chargedIsoPtSum));
203  mvaInput_[3] = TMath::Log(TMath::Max(1.e-2, neutralIsoPtSum - 0.125*puCorrPtSum));
204  mvaInput_[4] = TMath::Log(TMath::Max(1.e-2, puCorrPtSum));
205  mvaInput_[5] = tauDecayMode;
206  } else if ( mvaOpt_ == kOldDMwLT || mvaOpt_ == kNewDMwLT ) {
207  mvaInput_[0] = TMath::Log(TMath::Max(1., Double_t(tau->pt())));
208  mvaInput_[1] = TMath::Abs(tau->eta());
209  mvaInput_[2] = TMath::Log(TMath::Max(1.e-2, chargedIsoPtSum));
210  mvaInput_[3] = TMath::Log(TMath::Max(1.e-2, neutralIsoPtSum - 0.125*puCorrPtSum));
211  mvaInput_[4] = TMath::Log(TMath::Max(1.e-2, puCorrPtSum));
212  mvaInput_[5] = tauDecayMode;
213  mvaInput_[6] = TMath::Sign(+1., tauLifetimeInfo.dxy());
214  mvaInput_[7] = TMath::Sqrt(TMath::Abs(TMath::Min(1., tauLifetimeInfo.dxy())));
215  mvaInput_[8] = TMath::Min(10., TMath::Abs(tauLifetimeInfo.dxy_Sig()));
216  mvaInput_[9] = ( tauLifetimeInfo.hasSecondaryVertex() ) ? 1. : 0.;
217  mvaInput_[10] = TMath::Sqrt(decayDistMag);
218  mvaInput_[11] = TMath::Min(10., tauLifetimeInfo.flightLengthSig());
219  }
220 
221  double mvaValue = mvaReader_->GetClassifier(mvaInput_);
222  if ( verbosity_ ) {
223  edm::LogPrint("PFTauDiscByMVAIsol2") << "<PFRecoTauDiscriminationByIsolationMVA2::discriminate>:";
224  edm::LogPrint("PFTauDiscByMVAIsol2") << " tau: Pt = " << tau->pt() << ", eta = " << tau->eta();
225  edm::LogPrint("PFTauDiscByMVAIsol2") << " isolation: charged = " << chargedIsoPtSum << ", neutral = " << neutralIsoPtSum << ", PUcorr = " << puCorrPtSum;
226  edm::LogPrint("PFTauDiscByMVAIsol2") << " decay mode = " << tauDecayMode;
227  edm::LogPrint("PFTauDiscByMVAIsol2") << " impact parameter: distance = " << tauLifetimeInfo.dxy() << ", significance = " << tauLifetimeInfo.dxy_Sig();
228  edm::LogPrint("PFTauDiscByMVAIsol2") << " has decay vertex = " << tauLifetimeInfo.hasSecondaryVertex() << ":"
229  << " distance = " << decayDistMag << ", significance = " << tauLifetimeInfo.flightLengthSig();
230  edm::LogPrint("PFTauDiscByMVAIsol2") << "--> mvaValue = " << mvaValue;
231  }
232  return mvaValue;
233  } else {
234  return -1.;
235  }
236 }
237 
239 {
240  // add all category indices to event
241  evt.put(std::move(category_output_), "category");
242 }
243 
244 void
246  // pfRecoTauDiscriminationByIsolationMVA2
248 
249  desc.add<std::string>("mvaName");
250  desc.add<bool>("loadMVAfromDB");
251  desc.addOptional<edm::FileInPath>("inputFileName");
252  desc.add<std::string>("mvaOpt");
253 
254  desc.add<edm::InputTag>("srcTauTransverseImpactParameters");
255  desc.add<edm::InputTag>("srcChargedIsoPtSum");
256  desc.add<edm::InputTag>("srcNeutralIsoPtSum");
257  desc.add<edm::InputTag>("srcPUcorrPtSum");
258  desc.add<int>("verbosity", 0);
259 
260  fillProducerDescriptions(desc); // inherited from the base
261 
262  descriptions.add("pfRecoTauDiscriminationByIsolationMVA2", desc);
263 }
264 
T getParameter(std::string const &) const
void beginEvent(const edm::Event &, const edm::EventSetup &) override
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
edm::RefProd< TauCollection > TauRefProd
Definition: Tau.h:40
T Sign(T A, T B)
Definition: MathUtil.h:54
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
edm::AssociationVector< reco::PFTauRefProd, std::vector< reco::PFTauTransverseImpactParameterRef > > PFTauTIPAssociationByRef
edm::Handle< reco::PFTauDiscriminator > chargedIsoPtSums_
#define nullptr
edm::Handle< PFTauTIPAssociationByRef > tauLifetimeInfos
T Min(T a, T b)
Definition: MathUtil.h:39
edm::EDGetTokenT< reco::PFTauDiscriminator > ChargedIsoPtSum_token
edm::EDGetTokenT< reco::PFTauDiscriminator > NeutralIsoPtSum_token
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
T Abs(T a)
Definition: MathUtil.h:49
edm::EDGetTokenT< PFTauTIPAssociationByRef > TauTransverseImpactParameters_token
LocationCode location() const
Where was the file found?
Definition: FileInPath.cc:161
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool isNull() const
Checks for null.
Definition: Ref.h:248
T Max(T a, T b)
Definition: MathUtil.h:44
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
edm::Handle< reco::PFTauDiscriminator > neutralIsoPtSums_
fixed size matrix
T get() const
Definition: EventSetup.h:71
std::string fullPath() const
Definition: FileInPath.cc:163
T const * product() const
Definition: ESHandle.h:86
edm::EDGetTokenT< reco::PFTauDiscriminator > PUcorrPtSum_token
def move(src, dest)
Definition: eostools.py:511