CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFRecoTauDiscriminationAgainstElectronMVA5GBR.cc
Go to the documentation of this file.
1 /* class PFRecoTauDiscriminationAgainstElectronMVA5
2  * created : Aug 13 2013,
3  * revised : ,
4  * Authorss : Ivo Naranjo (LLR Ecole-Polytechnique)
5  */
6 
9 
12 
20 
21 #include <TMath.h>
22 
23 #include <iostream>
24 #include <sstream>
25 #include <fstream>
26 
27 using namespace reco;
28 
30 public:
33  mva_(0),
34  category_output_(0)
35  {
36  method_ = iConfig.getParameter<std::string>("method");
37  gbrFile_ = iConfig.getParameter<edm::FileInPath>("gbrFile");
38  if ( gbrFile_.location() == edm::FileInPath::Unknown)
39  throw cms::Exception("PFRecoTauDiscriminationAgainstElectronMVA5GBR")
40  << " Failed to find File = " << gbrFile_ << " !!\n";
41 
42  returnMVA_ = iConfig.getParameter<bool>("returnMVA");
43  minMVANoEleMatchWOgWOgsfBL_ = iConfig.getParameter<double>("minMVANoEleMatchWOgWOgsfBL");
44  minMVANoEleMatchWOgWgsfBL_ = iConfig.getParameter<double>("minMVANoEleMatchWOgWgsfBL");
45  minMVANoEleMatchWgWOgsfBL_ = iConfig.getParameter<double>("minMVANoEleMatchWgWOgsfBL");
46  minMVANoEleMatchWgWgsfBL_ = iConfig.getParameter<double>("minMVANoEleMatchWgWgsfBL");
47  minMVAWOgWOgsfBL_ = iConfig.getParameter<double>("minMVAWOgWOgsfBL");
48  minMVAWOgWgsfBL_ = iConfig.getParameter<double>("minMVAWOgWgsfBL");
49  minMVAWgWOgsfBL_ = iConfig.getParameter<double>("minMVAWgWOgsfBL");
50  minMVAWgWgsfBL_ = iConfig.getParameter<double>("minMVAWgWgsfBL");
51  minMVANoEleMatchWOgWOgsfEC_ = iConfig.getParameter<double>("minMVANoEleMatchWOgWOgsfEC");
52  minMVANoEleMatchWOgWgsfEC_ = iConfig.getParameter<double>("minMVANoEleMatchWOgWgsfEC");
53  minMVANoEleMatchWgWOgsfEC_ = iConfig.getParameter<double>("minMVANoEleMatchWgWOgsfEC");
54  minMVANoEleMatchWgWgsfEC_ = iConfig.getParameter<double>("minMVANoEleMatchWgWgsfEC");
55  minMVAWOgWOgsfEC_ = iConfig.getParameter<double>("minMVAWOgWOgsfEC");
56  minMVAWOgWgsfEC_ = iConfig.getParameter<double>("minMVAWOgWgsfEC");
57  minMVAWgWOgsfEC_ = iConfig.getParameter<double>("minMVAWgWOgsfEC");
58  minMVAWgWgsfEC_ = iConfig.getParameter<double>("minMVAWgWgsfEC");
59 
60  srcGsfElectrons_ = iConfig.getParameter<edm::InputTag>("srcGsfElectrons");
61  GsfElectrons_token = consumes<reco::GsfElectronCollection>(srcGsfElectrons_);
62 
63  mva_ = new AntiElectronIDMVA5GBR();
64  mva_->Initialize_from_file(method_, gbrFile_.fullPath().data());
65 
66  verbosity_ = ( iConfig.exists("verbosity") ) ?
67  iConfig.getParameter<int>("verbosity") : 0;
68 
69  // add category index
70  if ( returnMVA_ ) {
71  produces<PFTauDiscriminator>("category");
72  }
73  }
74 
75  void beginEvent(const edm::Event&, const edm::EventSetup&);
76 
77  double discriminate(const PFTauRef&);
78 
79  void endEvent(edm::Event&);
80 
82  {
83  delete mva_;
84  }
85 
86 private:
87  bool isInEcalCrack(double) const;
88 
92  bool returnMVA_ ;
113  std::auto_ptr<PFTauDiscriminator> category_output_;
114  size_t tauIndex_;
115 
117 };
118 
120 {
121  if ( returnMVA_ ) {
122  evt.getByToken(Tau_token, taus_);
123  category_output_.reset(new PFTauDiscriminator(TauRefProd(taus_)));
124  tauIndex_ = 0;
125  }
126  evt.getByToken(GsfElectrons_token, gsfElectrons_);
127 }
128 
130 {
131  double mva = 1.;
132  double workingPoint = 1.;
133  double category = -1.;
134  bool isGsfElectronMatched = false;
135 
136  float deltaRDummy = 9.9;
137  float mvaCutDummy = 999;
138 
139  float tauEtaAtEcalEntrance = -99.;
140  float sumEtaTimesEnergy = 0.;
141  float sumEnergy = 0.;
142  const std::vector<reco::PFCandidatePtr>& signalPFCands = thePFTauRef->signalPFCands();
143  for ( std::vector<reco::PFCandidatePtr>::const_iterator pfCandidate = signalPFCands.begin();
144  pfCandidate != signalPFCands.end(); ++pfCandidate ) {
145  sumEtaTimesEnergy += ((*pfCandidate)->positionAtECALEntrance().eta()*(*pfCandidate)->energy());
146  sumEnergy += (*pfCandidate)->energy();
147  }
148  if ( sumEnergy > 0. ) {
149  tauEtaAtEcalEntrance = sumEtaTimesEnergy/sumEnergy;
150  }
151 
152  float leadChargedPFCandEtaAtEcalEntrance = -99.;
153  float leadChargedPFCandPt = -99.;
154  for ( std::vector<reco::PFCandidatePtr>::const_iterator pfCandidate = signalPFCands.begin();
155  pfCandidate != signalPFCands.end(); ++pfCandidate ) {
156  const reco::Track* track = 0;
157  if ( (*pfCandidate)->trackRef().isNonnull() ) track = (*pfCandidate)->trackRef().get();
158  else if ( (*pfCandidate)->muonRef().isNonnull() && (*pfCandidate)->muonRef()->innerTrack().isNonnull() ) track = (*pfCandidate)->muonRef()->innerTrack().get();
159  else if ( (*pfCandidate)->muonRef().isNonnull() && (*pfCandidate)->muonRef()->globalTrack().isNonnull() ) track = (*pfCandidate)->muonRef()->globalTrack().get();
160  else if ( (*pfCandidate)->muonRef().isNonnull() && (*pfCandidate)->muonRef()->outerTrack().isNonnull() ) track = (*pfCandidate)->muonRef()->outerTrack().get();
161  else if ( (*pfCandidate)->gsfTrackRef().isNonnull() ) track = (*pfCandidate)->gsfTrackRef().get();
162  if ( track ) {
163  if ( track->pt() > leadChargedPFCandPt ) {
164  leadChargedPFCandEtaAtEcalEntrance = (*pfCandidate)->positionAtECALEntrance().eta();
165  leadChargedPFCandPt = track->pt();
166  }
167  }
168  }
169 
170  if( (*thePFTauRef).leadPFChargedHadrCand().isNonnull()) {
171  for ( reco::GsfElectronCollection::const_iterator theGsfElectron = gsfElectrons_->begin();
172  theGsfElectron != gsfElectrons_->end(); ++theGsfElectron ) {
173  if ( theGsfElectron->pt() > 10. ) { // CV: only take electrons above some minimal energy/Pt into account...
174  double deltaREleTau = deltaR(theGsfElectron->p4(), thePFTauRef->p4());
175  deltaRDummy = deltaREleTau;
176  if ( deltaREleTau < 0.3 ) {
177  double mva_match = mva_->MVAValue(*thePFTauRef, *theGsfElectron);
178  double workingPoint_match = 0.;
179  size_t numSignalPFGammaCands = thePFTauRef->signalPFGammaCands().size();
180  bool hasGsfTrack = thePFTauRef->leadPFChargedHadrCand()->gsfTrackRef().isNonnull();
181 
183  if ( isInEcalCrack(tauEtaAtEcalEntrance) || isInEcalCrack(leadChargedPFCandEtaAtEcalEntrance) ) {
184  if ( returnMVA_ ) {
185  // add category index
186  category_output_->setValue(tauIndex_, category);
187  ++tauIndex_;
188  // return MVA output value
189  return -99;
190  } else {
191  //return Workingpoint 0
192  return 0;
193  }
194  }
196 
197  double mvaCut = 999.;
198  if ( TMath::Abs(tauEtaAtEcalEntrance) < 1.479 ) { // Barrel
199  if ( numSignalPFGammaCands == 0 && !hasGsfTrack ) {
200  category = 4.;
201  mvaCut = minMVAWOgWOgsfBL_;
202  } else if ( numSignalPFGammaCands == 0 && hasGsfTrack ) {
203  category = 5.;
204  mvaCut = minMVAWOgWgsfBL_;
205  } else if ( numSignalPFGammaCands >= 1 && !hasGsfTrack ) {
206  category = 6.;
207  mvaCut = minMVAWgWOgsfBL_;
208  } else if ( numSignalPFGammaCands >= 1 && hasGsfTrack ) {
209  category = 7.;
210  mvaCut = minMVAWgWgsfBL_;
211  }
212  } else { // Endcap
213  if ( numSignalPFGammaCands == 0 && !hasGsfTrack ) {
214  category = 12.;
215  mvaCut = minMVAWOgWOgsfEC_;
216  } else if ( numSignalPFGammaCands == 0 && hasGsfTrack ) {
217  category = 13.;
218  mvaCut = minMVAWOgWgsfEC_;
219  } else if ( numSignalPFGammaCands >= 1 && !hasGsfTrack ) {
220  category = 14.;
221  mvaCut = minMVAWgWOgsfEC_;
222  } else if ( numSignalPFGammaCands >= 1 && hasGsfTrack ) {
223  category = 15.;
224  mvaCut = minMVAWgWgsfEC_;
225  }
226  }
227  workingPoint_match = (mva_match > mvaCut);
228  mvaCutDummy = mvaCut;
229 
230  mva = TMath::Min(mva, mva_match);
231  workingPoint = TMath::Min(workingPoint, workingPoint_match);
232  isGsfElectronMatched = true;
233  } // deltaR < 0.3
234  } // electron pt > 10
235  } // end of loop over electrons
236 
237  if ( !isGsfElectronMatched ) {
238  mva = mva_->MVAValue(*thePFTauRef);
239  size_t numSignalPFGammaCands = thePFTauRef->signalPFGammaCands().size();
240  bool hasGsfTrack = thePFTauRef->leadPFChargedHadrCand()->gsfTrackRef().isNonnull();
241 
243  if ( isInEcalCrack(tauEtaAtEcalEntrance) || isInEcalCrack(leadChargedPFCandEtaAtEcalEntrance) ) {
244  if ( returnMVA_ ) {
245  // add category index
246  category_output_->setValue(tauIndex_, category);
247  ++tauIndex_;
248  // return MVA output value
249  return -99;
250  } else {
251  //return Workingpoint 0
252  return 0;
253  }
254  }
256 
257  double mvaCut = 999.;
258  if ( TMath::Abs(tauEtaAtEcalEntrance) < 1.479 ) { // Barrel
259  if ( numSignalPFGammaCands == 0 && !hasGsfTrack ) {
260  category = 0.;
261  mvaCut = minMVANoEleMatchWOgWOgsfBL_;
262  } else if ( numSignalPFGammaCands == 0 && hasGsfTrack ) {
263  category = 1.;
264  mvaCut = minMVANoEleMatchWOgWgsfBL_;
265  } else if ( numSignalPFGammaCands >= 1 && !hasGsfTrack ) {
266  category = 2.;
267  mvaCut = minMVANoEleMatchWgWOgsfBL_;
268  } else if ( numSignalPFGammaCands >= 1 && hasGsfTrack ) {
269  category = 3.;
270  mvaCut = minMVANoEleMatchWgWgsfBL_;
271  }
272  } else { // Endcap
273  if ( numSignalPFGammaCands == 0 && !hasGsfTrack ) {
274  category = 8.;
275  mvaCut = minMVANoEleMatchWOgWOgsfEC_;
276  } else if ( numSignalPFGammaCands == 0 && hasGsfTrack ) {
277  category = 9.;
278  mvaCut = minMVANoEleMatchWOgWgsfEC_;
279  } else if ( numSignalPFGammaCands >= 1 && !hasGsfTrack ) {
280  category = 10.;
281  mvaCut = minMVANoEleMatchWgWOgsfEC_;
282  } else if ( numSignalPFGammaCands >= 1 && hasGsfTrack ) {
283  category = 11.;
284  mvaCut = minMVANoEleMatchWgWgsfEC_;
285  }
286  }
287  workingPoint = (mva > mvaCut);
288  mvaCutDummy = mvaCut;
289  }
290  }
291 
292  if ( verbosity_ ) {
293  edm::LogPrint("PFTauAgainstEleMVA5") <<" Taus : "<<TauProducer_;
294  edm::LogPrint("PFTauAgainstEleMVA5") << "<PFRecoTauDiscriminationAgainstElectronMVA5::discriminate>:" ;
295  edm::LogPrint("PFTauAgainstEleMVA5") << " tau: Pt = " << thePFTauRef->pt() << ", eta = " << thePFTauRef->eta() << ", phi = " << thePFTauRef->phi() ;
296  edm::LogPrint("PFTauAgainstEleMVA5") << " mva = " << mva << ", mvaCut = " << mvaCutDummy << ", isGsfElectronMatched = " << isGsfElectronMatched ;
297  edm::LogPrint("PFTauAgainstEleMVA5") << " category = " << category << ": workingPoint = " << workingPoint ;
298  edm::LogPrint("PFTauAgainstEleMVA5") << " deltaREleTau = " << deltaRDummy ;
299  edm::LogPrint("PFTauAgainstEleMVA5") << " charged hadron in tau: "<<(*thePFTauRef).leadPFChargedHadrCand().isNonnull() ;
300  edm::LogPrint("PFTauAgainstEleMVA5") << " Prongs in tau: " << thePFTauRef->signalPFChargedHadrCands().size() ;
301  edm::LogPrint("PFTauAgainstEleMVA5") << " MVA GBR:" << mva ;
302  }
303 
304  if ( returnMVA_ ) {
305  // add category index
306  category_output_->setValue(tauIndex_, category);
307  ++tauIndex_;
308  // return MVA output value
309  return mva;
310  } else {
311  return workingPoint;
312  }
313 }
314 
316 {
317  // add all category indices to event
318  if ( returnMVA_ ) {
319  evt.put(category_output_, "category");
320  }
321 }
322 
323 bool
325 {
326  double absEta = fabs(eta);
327  return (absEta > 1.460 && absEta < 1.558);
328 }
329 
T getParameter(std::string const &) const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:434
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
bool exists(std::string const &parameterName) const
checks if a parameter exists
double deltaR(const T1 &t1, const T2 &t2)
Definition: deltaR.h:48
T Min(T a, T b)
Definition: MathUtil.h:39
T eta() const
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:250
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:139
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:116
double pt() const
track transverse momentum
Definition: TrackBase.h:129
T Abs(T a)
Definition: MathUtil.h:49
edm::EDGetTokenT< reco::GsfElectronCollection > GsfElectrons_token