CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFRecoTauDiscriminationAgainstElectronMVA6.cc
Go to the documentation of this file.
1 /* class PFRecoTauDiscriminationAgainstElectronMVA6
2  * created : Nov 2 2015,
3  * revised : ,
4  * Authorss : Fabio Colombo (KIT)
5  */
6 
9 
12 
20 
21 #include <iostream>
22 #include <sstream>
23 #include <fstream>
24 
25 using namespace reco;
26 
28 {
29  public:
32  mva_(0),
33  category_output_(0)
34  {
35  mva_ = new AntiElectronIDMVA6(cfg);
36 
37  srcGsfElectrons_ = cfg.getParameter<edm::InputTag>("srcGsfElectrons");
38  GsfElectrons_token = consumes<reco::GsfElectronCollection>(srcGsfElectrons_);
39 
40  verbosity_ = ( cfg.exists("verbosity") ) ?
41  cfg.getParameter<int>("verbosity") : 0;
42 
43  // add category index
44  produces<PFTauDiscriminator>("category");
45  }
46 
47  void beginEvent(const edm::Event&, const edm::EventSetup&);
48 
49  double discriminate(const PFTauRef&) const;
50 
51  void endEvent(edm::Event&);
52 
54  {
55  delete mva_;
56  }
57 
58 private:
59  bool isInEcalCrack(double) const;
60 
62 
64  float* mvaInput_;
65 
70 
71  std::auto_ptr<PFTauDiscriminator> category_output_;
72 
74 };
75 
77 {
78  mva_->beginEvent(evt, es);
79 
80  evt.getByToken(Tau_token, taus_);
81  category_output_.reset(new PFTauDiscriminator(TauRefProd(taus_)));
82 
83  evt.getByToken(GsfElectrons_token, gsfElectrons_);
84 }
85 
87 {
88  double mvaValue = 1.;
89  double category = -1.;
90  bool isGsfElectronMatched = false;
91 
92  float deltaRDummy = 9.9;
93 
94  const float ECALBarrelEndcapEtaBorder = 1.479;
95  float tauEtaAtEcalEntrance = -99.;
96  float sumEtaTimesEnergy = 0.;
97  float sumEnergy = 0.;
98  const std::vector<reco::PFCandidatePtr>& signalPFCands = thePFTauRef->signalPFCands();
99  for ( std::vector<reco::PFCandidatePtr>::const_iterator pfCandidate = signalPFCands.begin();
100  pfCandidate != signalPFCands.end(); ++pfCandidate ) {
101  sumEtaTimesEnergy += ((*pfCandidate)->positionAtECALEntrance().eta()*(*pfCandidate)->energy());
102  sumEnergy += (*pfCandidate)->energy();
103  }
104  if ( sumEnergy > 0. ) {
105  tauEtaAtEcalEntrance = sumEtaTimesEnergy/sumEnergy;
106  }
107 
108  float leadChargedPFCandEtaAtEcalEntrance = -99.;
109  float leadChargedPFCandPt = -99.;
110  for ( std::vector<reco::PFCandidatePtr>::const_iterator pfCandidate = signalPFCands.begin();
111  pfCandidate != signalPFCands.end(); ++pfCandidate ) {
112  const reco::Track* track = 0;
113  if ( (*pfCandidate)->trackRef().isNonnull() ) track = (*pfCandidate)->trackRef().get();
114  else if ( (*pfCandidate)->muonRef().isNonnull() && (*pfCandidate)->muonRef()->innerTrack().isNonnull() ) track = (*pfCandidate)->muonRef()->innerTrack().get();
115  else if ( (*pfCandidate)->muonRef().isNonnull() && (*pfCandidate)->muonRef()->globalTrack().isNonnull() ) track = (*pfCandidate)->muonRef()->globalTrack().get();
116  else if ( (*pfCandidate)->muonRef().isNonnull() && (*pfCandidate)->muonRef()->outerTrack().isNonnull() ) track = (*pfCandidate)->muonRef()->outerTrack().get();
117  else if ( (*pfCandidate)->gsfTrackRef().isNonnull() ) track = (*pfCandidate)->gsfTrackRef().get();
118  if ( track ) {
119  if ( track->pt() > leadChargedPFCandPt ) {
120  leadChargedPFCandEtaAtEcalEntrance = (*pfCandidate)->positionAtECALEntrance().eta();
121  leadChargedPFCandPt = track->pt();
122  }
123  }
124  }
125 
126  if( (*thePFTauRef).leadPFChargedHadrCand().isNonnull()) {
127 
128  int numSignalPFGammaCandsInSigCone = 0;
129  const std::vector<reco::PFCandidatePtr>& signalPFGammaCands = thePFTauRef->signalPFGammaCands();
130 
131  for ( std::vector<reco::PFCandidatePtr>::const_iterator pfGamma = signalPFGammaCands.begin();
132  pfGamma != signalPFGammaCands.end(); ++pfGamma ) {
133 
134  double dR = deltaR((*pfGamma)->p4(), thePFTauRef->leadPFChargedHadrCand()->p4());
135  double signalrad = std::max(0.05, std::min(0.10, 3.0/std::max(1.0, thePFTauRef->pt())));
136 
137  // pfGammas inside the tau signal cone
138  if (dR < signalrad) {
139  numSignalPFGammaCandsInSigCone += 1;
140  }
141  }
142 
143  // loop over the electrons
144  for ( reco::GsfElectronCollection::const_iterator theGsfElectron = gsfElectrons_->begin();
145  theGsfElectron != gsfElectrons_->end(); ++theGsfElectron ) {
146  if ( theGsfElectron->pt() > 10. ) { // CV: only take electrons above some minimal energy/Pt into account...
147  double deltaREleTau = deltaR(theGsfElectron->p4(), thePFTauRef->p4());
148  deltaRDummy = deltaREleTau;
149  if ( deltaREleTau < 0.3 ) {
150  double mva_match = mva_->MVAValue(*thePFTauRef, *theGsfElectron);
151  bool hasGsfTrack = thePFTauRef->leadPFChargedHadrCand()->gsfTrackRef().isNonnull();
152  if ( !hasGsfTrack )
153  hasGsfTrack = theGsfElectron->gsfTrack().isNonnull();
154 
156  if ( isInEcalCrack(tauEtaAtEcalEntrance) || isInEcalCrack(leadChargedPFCandEtaAtEcalEntrance) ) {
157  // add category index
158  category_output_->setValue(tauIndex_, category);
159  // return MVA output value
160  return -99;
161  }
163 
164  if ( std::abs(tauEtaAtEcalEntrance) < ECALBarrelEndcapEtaBorder ) { // Barrel
165  if ( numSignalPFGammaCandsInSigCone == 0 && hasGsfTrack ) {
166  category = 5.;
167  }
168  else if ( numSignalPFGammaCandsInSigCone >= 1 && hasGsfTrack ) {
169  category = 7.;
170  }
171  } else { // Endcap
172  if ( numSignalPFGammaCandsInSigCone == 0 && hasGsfTrack ) {
173  category = 13.;
174  }
175  else if ( numSignalPFGammaCandsInSigCone >= 1 && hasGsfTrack ) {
176  category = 15.;
177  }
178  }
179 
180  mvaValue = std::min(mvaValue, mva_match);
181  isGsfElectronMatched = true;
182  } // deltaR < 0.3
183  } // electron pt > 10
184  } // end of loop over electrons
185 
186  if ( !isGsfElectronMatched ) {
187  mvaValue = mva_->MVAValue(*thePFTauRef);
188  bool hasGsfTrack = thePFTauRef->leadPFChargedHadrCand()->gsfTrackRef().isNonnull();
189 
191  if ( isInEcalCrack(tauEtaAtEcalEntrance) || isInEcalCrack(leadChargedPFCandEtaAtEcalEntrance) ) {
192  // add category index
193  category_output_->setValue(tauIndex_, category);
194  // return MVA output value
195  return -99;
196  }
198 
199  if ( std::abs(tauEtaAtEcalEntrance) < ECALBarrelEndcapEtaBorder ) { // Barrel
200  if ( numSignalPFGammaCandsInSigCone == 0 && !hasGsfTrack ) {
201  category = 0.;
202  }
203  else if ( numSignalPFGammaCandsInSigCone >= 1 && !hasGsfTrack ) {
204  category = 2.;
205  }
206  } else { // Endcap
207  if ( numSignalPFGammaCandsInSigCone == 0 && !hasGsfTrack ) {
208  category = 8.;
209  }
210  else if ( numSignalPFGammaCandsInSigCone >= 1 && !hasGsfTrack ) {
211  category = 10.;
212  }
213  }
214  }
215  }
216 
217  if ( verbosity_ ) {
218  edm::LogPrint("PFTauAgainstEleMVA6") << "<PFRecoTauDiscriminationAgainstElectronMVA6::discriminate>:" ;
219  edm::LogPrint("PFTauAgainstEleMVA6") << " tau: Pt = " << thePFTauRef->pt() << ", eta = " << thePFTauRef->eta() << ", phi = " << thePFTauRef->phi();
220  edm::LogPrint("PFTauAgainstEleMVA6") << " deltaREleTau = " << deltaRDummy << ", isGsfElectronMatched = " << isGsfElectronMatched;
221  edm::LogPrint("PFTauAgainstEleMVA6") << " #Prongs = " << thePFTauRef->signalPFChargedHadrCands().size();
222  edm::LogPrint("PFTauAgainstEleMVA6") << " MVA = " << mvaValue << ", category = " << category;
223  }
224 
225  // add category index
226  category_output_->setValue(tauIndex_, category);
227  // return MVA output value
228  return mvaValue;
229 }
230 
232 {
233  // add all category indices to event
234  evt.put(category_output_, "category");
235 }
236 
237 bool
239 {
240  double absEta = fabs(eta);
241  return (absEta > 1.460 && absEta < 1.558);
242 }
243 
T getParameter(std::string const &) const
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:252
tuple cfg
Definition: looper.py:293
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:462
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
bool exists(std::string const &parameterName) const
checks if a parameter exists
edm::EDGetTokenT< reco::GsfElectronCollection > GsfElectrons_token
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:646
void beginEvent(const edm::Event &, const edm::EventSetup &)
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:121
double pt() const
track transverse momentum
Definition: TrackBase.h:616
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:28
T min(T a, T b)
Definition: MathUtil.h:58