CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HPSPFRecoTauAlgorithm.cc
Go to the documentation of this file.
2 #include "Math/GenVector/VectorUtil.h"
4 using namespace reco;
5 
8 {
9 }
10 
13 {
14  configure(config);
15 }
16 
18 {
19  if(candidateMerger_ !=0 ) delete candidateMerger_;
20 }
21 
22 PFTau
24 {
25  PFTau pfTau;
26 
27  pfTaus_.clear();
28  //make the strips globally.
29  std::vector<std::vector<PFCandidatePtr>> strips = candidateMerger_->mergeCandidates(tagInfo->PFCands());
30 
31 
32  //Sort the hadrons globally and once!
33  std::vector<PFCandidatePtr> hadrons = tagInfo->PFChargedHadrCands();
34  if(hadrons.size()>1)
36 
37 
38  //OK For this Tau Tag Info we should create all the possible taus
39 
40  //One Prongs
41  if(doOneProngs_)
42  buildOneProng(tagInfo,hadrons);
43 
44  //One Prong Strips
46  buildOneProngStrip(tagInfo,strips,hadrons);
47 
48  //One Prong TwoStrips
50  buildOneProngTwoStrips(tagInfo,strips,hadrons);
51 
52  //Three Prong
53  if(doThreeProngs_)
54  buildThreeProngs(tagInfo,hadrons);
55 
56 
57  //Lets see if we created any taus
58  if(pfTaus_.size()>0) {
59 
61 
62  //Set the IP for the leading track
63  if(TransientTrackBuilder_!=0 &&pfTau.leadPFChargedHadrCand()->trackRef().isNonnull()) {
65  if(pfTau.pfTauTagInfoRef().isNonnull())
66  if(pfTau.pfTauTagInfoRef()->pfjetRef().isNonnull()) {
67  PFJetRef jet = pfTau.pfTauTagInfoRef()->pfjetRef();
68  GlobalVector jetDir(jet->px(),jet->py(),jet->pz());
69  if(IPTools::signedTransverseImpactParameter(leadTrack,jetDir,vertex).first)
70  pfTau.setleadPFChargedHadrCandsignedSipt(IPTools::signedTransverseImpactParameter(leadTrack,jetDir,vertex).second.significance());
71  }
72  }
73  }
74  else { //null PFTau
75  //Simone asked that in case there is no tau returned make a tau
76  //without refs and the LV of the jet
77  pfTau.setpfTauTagInfoRef(tagInfo);
78  pfTau.setP4(tagInfo->pfjetRef()->p4());
79  }
80 
81  return pfTau;
82 }
83 
84 
85 
86 //Create one prong tau
87 void
88 HPSPFRecoTauAlgorithm::buildOneProng(const reco::PFTauTagInfoRef& tagInfo,const std::vector<reco::PFCandidatePtr>& hadrons)
89 {
90  PFTauCollection taus;
91 
92  if(hadrons.size()>0)
93  for(unsigned int h=0;h<hadrons.size();++h) {
94  PFCandidatePtr hadron = hadrons[h];
95 
96  //In the one prong case the lead Track pt should be above the tau Threshold!
97  //since all the tau is just one track!
98  if(hadron->pt()>tauThreshold_)
99  if(hadron->pt()>leadPionThreshold_)
100  //The track should be within the matching cone
101  if(ROOT::Math::VectorUtil::DeltaR(hadron->p4(),tagInfo->pfjetRef()->p4())<matchingCone_) {
102  //OK Lets create a Particle Flow Tau!
103  PFTau tau = PFTau(hadron->charge(),hadron->p4(),hadron->vertex());
104 
105  //Associate the Tag Info to the tau
106  tau.setpfTauTagInfoRef(tagInfo);
107 
108  //Put the Hadron in the signal Constituents
109  std::vector<PFCandidatePtr> signal;
110  signal.push_back(hadron);
111 
112  //Set The signal candidates of the PF Tau
113  tau.setsignalPFChargedHadrCands(signal);
114  tau.setsignalPFCands(signal);
115  tau.setleadPFChargedHadrCand(hadron);
116  tau.setleadPFCand(hadron);
117 
118  //Fill isolation variables
120 
121  //Apply Muon rejection algorithms
122  applyMuonRejection(tau);
123  applyElectronRejection(tau,0.0);
124 
125  //Save this candidate
126  taus.push_back(tau);
127  }
128  }
129  if(taus.size()>0) {
130  pfTaus_.push_back(getBestTauCandidate(taus));
131  }
132 
133 }
134 
135 //Build one Prong + Strip
136 
137 void
138 HPSPFRecoTauAlgorithm::buildOneProngStrip(const reco::PFTauTagInfoRef& tagInfo,const std::vector<std::vector<PFCandidatePtr> >& strips,const std::vector<reco::PFCandidatePtr> & hadrons)
139 
140 {
141  //Create output Collection
142  PFTauCollection taus;
143 
144 
145 
146 
147  //make taus like this only if there is at least one hadron+ 1 strip
148  if(hadrons.size()>0&&strips.size()>0){
149  //Combinatorics between strips and clusters
150  for(std::vector<std::vector<PFCandidatePtr>>::const_iterator candVector=strips.begin();candVector!=strips.end();++candVector)
151  for(std::vector<PFCandidatePtr>::const_iterator hadron=hadrons.begin();hadron!=hadrons.end();++hadron) {
152 
153  //First Cross cleaning ! If you asked to clusterize the candidates
154  //with tracks too then you should not double count the track
155  std::vector<PFCandidatePtr> emConstituents = *candVector;
156  removeCandidateFromRefVector(*hadron,emConstituents);
157 
158  //Create a LorentzVector for the strip
159  math::XYZTLorentzVector strip = createMergedLorentzVector(emConstituents);
160 
161  //TEST: Apply Strip Constraint
162  applyMassConstraint(strip,0.1349);
163 
164  //create the Particle Flow Tau: Hadron plus Strip
165  PFTau tau((*hadron)->charge(),
166  (*hadron)->p4()+strip,
167  (*hadron)->vertex());
168 
169  //Check tau threshold, mass, Matching Cone window
170  if(tau.pt()>tauThreshold_&&strip.pt()>stripPtThreshold_)
171  if(tau.mass()>oneProngStripMassWindow_[0]&&tau.mass()<oneProngStripMassWindow_[1])//Apply mass window
172  if(ROOT::Math::VectorUtil::DeltaR(tau.p4(),tagInfo->pfjetRef()->p4())<matchingCone_) { //Apply matching cone
173  //Set The Tag Infor ref
174  tau.setpfTauTagInfoRef(tagInfo);
175 
176  //Create the signal vectors
177  std::vector<PFCandidatePtr> signal;
178  std::vector<PFCandidatePtr> signalH;
179  std::vector<PFCandidatePtr> signalG;
180 
181  //Store the hadron in the PFTau
182  signalH.push_back(*hadron);
183  signal.push_back(*hadron);
184 
185  //calculate the cone size : For the strip use it as one candidate !
186  double tauCone=0.0;
187  if(coneMetric_ =="angle")
188  tauCone=std::max(fabs(ROOT::Math::VectorUtil::Angle(tau.p4(),(*hadron)->p4())),
189  fabs(ROOT::Math::VectorUtil::Angle(tau.p4(),strip)));
190  else if(coneMetric_ == "DR")
191  tauCone=std::max(ROOT::Math::VectorUtil::DeltaR(tau.p4(),(*hadron)->p4()),
192  ROOT::Math::VectorUtil::DeltaR(tau.p4(),strip));
193 
194  if(emConstituents.size()>0)
195  for(std::vector<PFCandidatePtr>::const_iterator j=emConstituents.begin();j!=emConstituents.end();++j) {
196  signal.push_back(*j);
197  signalG.push_back(*j);
198  }
199 
200  //Set the PFTau
201  tau.setsignalPFChargedHadrCands(signalH);
202  tau.setsignalPFGammaCands(signalG);
203  tau.setsignalPFCands(signal);
204  tau.setleadPFChargedHadrCand(*hadron);
205  tau.setleadPFNeutralCand(emConstituents[0]);
206 
207  //Set the lead Candidate->Can be the hadron or the leading PFGamma(When we clear the Dataformat we will put the strip)
208  if((*hadron)->pt()>emConstituents[0]->pt())
209  tau.setleadPFCand(*hadron);
210  else
211  tau.setleadPFCand(emConstituents[0]);
212 
213  //Apply the signal cone size formula
214  if(isNarrowTau(tau,tauCone)) {
215  //calculate the isolation Deposits
217  //Set Muon Rejection
219  applyElectronRejection(tau,strip.energy());
220 
221  taus.push_back(tau);
222  }
223  }
224  }
225  }
226 
227  if(taus.size()>0) {
228  pfTaus_.push_back(getBestTauCandidate(taus));
229  }
230 
231 }
232 
233 void
234 HPSPFRecoTauAlgorithm::buildOneProngTwoStrips(const reco::PFTauTagInfoRef& tagInfo,const std::vector<std::vector<PFCandidatePtr> >& strips,const std::vector<reco::PFCandidatePtr>& hadrons)
235 {
236 
237 
238  PFTauCollection taus;
239 
240  //make taus like this only if there is at least one hadron+ 2 strips
241  if(hadrons.size()>0&&strips.size()>1){
242  //Combinatorics between strips and clusters
243  for(unsigned int Nstrip1=0;Nstrip1<strips.size()-1;++Nstrip1)
244  for(unsigned int Nstrip2=Nstrip1+1;Nstrip2<strips.size();++Nstrip2)
245  for(std::vector<PFCandidatePtr>::const_iterator hadron=hadrons.begin();hadron!=hadrons.end();++hadron) {
246 
247 
248 
249  //Create the strips and the vectors .Again cross clean the track if associated
250  std::vector<PFCandidatePtr> emConstituents1 = strips[Nstrip1];
251  std::vector<PFCandidatePtr> emConstituents2 = strips[Nstrip2];
252  removeCandidateFromRefVector(*hadron,emConstituents1);
253  removeCandidateFromRefVector(*hadron,emConstituents2);
254 
255 
256  //Create a LorentzVector for the strip
257  math::XYZTLorentzVector strip1 = createMergedLorentzVector(emConstituents1);
258  math::XYZTLorentzVector strip2 = createMergedLorentzVector(emConstituents2);
259 
260 
261 
262  //Apply Mass Constraints
263  applyMassConstraint(strip1,0.0);
264  applyMassConstraint(strip2,0.0);
265 
266 
267  PFTau tau((*hadron)->charge(),
268  (*hadron)->p4()+strip1+strip2,
269  (*hadron)->vertex());
270 
271 
272  if(tau.pt()>tauThreshold_&&strip1.pt()>stripPtThreshold_&&strip2.pt()>stripPtThreshold_)
273  if((strip1+strip2).M() >oneProngTwoStripsPi0MassWindow_[0] &&(strip1+strip2).M() <oneProngTwoStripsPi0MassWindow_[1] )//pi0 conmstraint for two strips
274  if(tau.mass()>oneProngTwoStripsMassWindow_[0]&&tau.mass()<oneProngTwoStripsMassWindow_[1] )//Apply mass window
275  if(ROOT::Math::VectorUtil::DeltaR(tau.p4(),tagInfo->pfjetRef()->p4())<matchingCone_) { //Apply matching cone
276  //create the PFTau
277  tau.setpfTauTagInfoRef(tagInfo);
278 
279 
280  //Create the signal vectors
281  std::vector<PFCandidatePtr> signal;
282  std::vector<PFCandidatePtr> signalH;
283  std::vector<PFCandidatePtr> signalG;
284 
285  //Store the hadron in the PFTau
286  signalH.push_back(*hadron);
287  signal.push_back(*hadron);
288 
289  //calculate the cone size from the reconstructed Objects
290  double tauCone=1000.0;
291  if(coneMetric_ =="angle") {
292  tauCone=std::max(std::max(fabs(ROOT::Math::VectorUtil::Angle(tau.p4(),(*hadron)->p4())),
293  fabs(ROOT::Math::VectorUtil::Angle(tau.p4(),strip1))),
294  fabs(ROOT::Math::VectorUtil::Angle(tau.p4(),strip2)));
295  }
296  else if(coneMetric_ =="DR") {
297  tauCone=std::max(std::max((ROOT::Math::VectorUtil::DeltaR(tau.p4(),(*hadron)->p4())),
298  (ROOT::Math::VectorUtil::DeltaR(tau.p4(),strip1))),
299  (ROOT::Math::VectorUtil::DeltaR(tau.p4(),strip2)));
300 
301  }
302 
303  for(std::vector<PFCandidatePtr>::const_iterator j=emConstituents1.begin();j!=emConstituents1.end();++j) {
304  signal.push_back(*j);
305  signalG.push_back(*j);
306  }
307 
308  for(std::vector<PFCandidatePtr>::const_iterator j=emConstituents2.begin();j!=emConstituents2.end();++j) {
309  signal.push_back(*j);
310  signalG.push_back(*j);
311  }
312 
313  //Set the PFTau
314  tau.setsignalPFChargedHadrCands(signalH);
315  tau.setsignalPFGammaCands(signalG);
316  tau.setsignalPFCands(signal);
317  tau.setleadPFChargedHadrCand(*hadron);
318 
319  //Set the lead Candidate->Can be the hadron or the leading PFGamma(When we clear the Dataformat we will put the strip)
320  if((*hadron)->pt()>emConstituents1[0]->pt())
321  tau.setleadPFCand(*hadron);
322  else
323  tau.setleadPFCand(emConstituents1[0]);
324 
325  //Apply the cone size formula
326  if(isNarrowTau(tau,tauCone)) {
327 
328  //calculate the isolation Deposits
330 
332 
333  //For two strips take the nearest strip to the track
334  if(ROOT::Math::VectorUtil::DeltaR(strip1,(*hadron)->p4())<
335  ROOT::Math::VectorUtil::DeltaR(strip2,(*hadron)->p4()))
336  applyElectronRejection(tau,strip1.energy());
337  else
338  applyElectronRejection(tau,strip2.energy());
339 
340  taus.push_back(tau);
341  }
342  }
343  }
344  }
345 
346  if(taus.size()>0) {
347  pfTaus_.push_back(getBestTauCandidate(taus));
348  }
349 }
350 
351 
352 
353 void
354 HPSPFRecoTauAlgorithm::buildThreeProngs(const reco::PFTauTagInfoRef& tagInfo,const std::vector<reco::PFCandidatePtr>& hadrons)
355 {
356  PFTauCollection taus;
357  //get Hadrons
358 
359 
360  //Require at least three hadrons
361  if(hadrons.size()>2)
362  for(unsigned int a=0;a<hadrons.size()-2;++a)
363  for(unsigned int b=a+1;b<hadrons.size()-1;++b)
364  for(unsigned int c=b+1;c<hadrons.size();++c) {
365 
366  PFCandidatePtr h1 = hadrons[a];
367  PFCandidatePtr h2 = hadrons[b];
368  PFCandidatePtr h3 = hadrons[c];
369 
370  //check charge Compatibility and lead track
371  int charge=h1->charge()+h2->charge()+h3->charge();
372  if(std::abs(charge)==1 && h1->pt()>leadPionThreshold_)
373  //check the track refs
374  if(h1->trackRef()!=h2->trackRef()&&h1->trackRef()!=h3->trackRef()&&h2->trackRef()!=h3->trackRef())
375  {
376 
377  //create the tau
378  PFTau tau = PFTau(charge,h1->p4()+h2->p4()+h3->p4(),h1->vertex());
379  tau.setpfTauTagInfoRef(tagInfo);
380 
381  if(tau.pt()>tauThreshold_)//Threshold
382  if(ROOT::Math::VectorUtil::DeltaR(tau.p4(),tagInfo->pfjetRef()->p4())<matchingCone_) {//Matching Cone
383 
384  std::vector<PFCandidatePtr> signal;
385  signal.push_back(h1);
386  signal.push_back(h2);
387  signal.push_back(h3);
388  //calculate the tau cone by getting the maximum distance
389  double tauCone = 10000.0;
390  if(coneMetric_=="DR")
391  {
392  tauCone = std::max(ROOT::Math::VectorUtil::DeltaR(tau.p4(),h1->p4()),
393  std::max(ROOT::Math::VectorUtil::DeltaR(tau.p4(),h2->p4()),
394  ROOT::Math::VectorUtil::DeltaR(tau.p4(),h3->p4())));
395  }
396  else if(coneMetric_=="angle")
397  {
398  tauCone =std::max(fabs(ROOT::Math::VectorUtil::Angle(tau.p4(),h1->p4())),
399  std::max(fabs(ROOT::Math::VectorUtil::Angle(tau.p4(),h2->p4())),
400  fabs(ROOT::Math::VectorUtil::Angle(tau.p4(),h3->p4()))));
401  }
402 
403  //Set The PFTau
404  tau.setsignalPFChargedHadrCands(signal);
405  tau.setsignalPFCands(signal);
406  tau.setleadPFChargedHadrCand(h1);
407  tau.setleadPFCand(h1);
408 
409  if(isNarrowTau(tau,tauCone)) {
410  //calculate the isolation Deposits
411  associateIsolationCandidates(tau,tauCone);
412  applyMuonRejection(tau);
413  applyElectronRejection(tau,0.0);
414  taus.push_back(tau);
415 
416  }
417  }
418  }
419  }
420 
421  if(taus.size()>0) {
422  PFTau bestTau = getBestTauCandidate(taus);
423  if(refitThreeProng(bestTau))
424  //Apply mass constraint
425  if ( bestTau.mass() > threeProngMassWindow_[0] && bestTau.mass() < threeProngMassWindow_[1] )//MassWindow
426  pfTaus_.push_back(bestTau);
427  }
428 
429 }
430 
431 
432 bool
434 {
435  double allowedConeSize=coneSizeFormula.Eval(tau.energy(),tau.et());
436  if (allowedConeSize<minSignalCone_) allowedConeSize=minSignalCone_;
437  if (allowedConeSize>maxSignalCone_) allowedConeSize=maxSignalCone_;
438 
439  if(cone<allowedConeSize)
440  return true;
441  else
442  return false;
443 }
444 
445 
446 void
448  double tauCone)
449 {
450 
451 
452  using namespace reco;
453 
454  //Information to get filled
455  double sumPT=0;
456  double sumET=0;
457 
458  if(tau.pfTauTagInfoRef().isNull()) return;
459 
460  std::vector<PFCandidatePtr> hadrons;
461  std::vector<PFCandidatePtr> gammas;
462  std::vector<PFCandidatePtr> neutral;
463 
464  //Remove candidates outside the cones
466  {
467  const std::vector<reco::PFCandidatePtr>& pfChargedHadrCands = tau.pfTauTagInfoRef()->PFChargedHadrCands();
468  double tauEta=tau.eta();
469  double tauPhi=tau.phi();
470  for ( std::vector<reco::PFCandidatePtr>::const_iterator pfChargedHadrCand = pfChargedHadrCands.begin();
471  pfChargedHadrCand != pfChargedHadrCands.end(); ++pfChargedHadrCand ) {
472  double dR = reco::deltaR(tauEta, tauPhi, (*pfChargedHadrCand)->eta(), (*pfChargedHadrCand)->phi());
473  if ( dR > tauCone && dR < chargeIsolationCone_ ) hadrons.push_back(*pfChargedHadrCand);
474  }
475 
476  const std::vector<reco::PFCandidatePtr>& pfGammaCands = tau.pfTauTagInfoRef()->PFGammaCands();
477  for ( std::vector<reco::PFCandidatePtr>::const_iterator pfGammaCand = pfGammaCands.begin();
478  pfGammaCand != pfGammaCands.end(); ++pfGammaCand ) {
479  double dR = reco::deltaR(tauEta, tauPhi, (*pfGammaCand)->eta(), (*pfGammaCand)->phi());
480  if ( dR > tauCone && dR < gammaIsolationCone_ ) gammas.push_back(*pfGammaCand);
481  }
482 
483  const std::vector<reco::PFCandidatePtr>& pfNeutralHadrCands = tau.pfTauTagInfoRef()->PFNeutrHadrCands();
484  for ( std::vector<reco::PFCandidatePtr>::const_iterator pfNeutralHadrCand = pfNeutralHadrCands.begin();
485  pfNeutralHadrCand != pfNeutralHadrCands.end(); ++pfNeutralHadrCand ) {
486  double dR = reco::deltaR(tauEta, tauPhi, (*pfNeutralHadrCand)->eta(), (*pfNeutralHadrCand)->phi());
487  if ( dR > tauCone && dR < neutrHadrIsolationCone_ ) hadrons.push_back(*pfNeutralHadrCand);
488  }
489  } else {
490  double tauEta=tau.eta();
491  double tauPhi=tau.phi();
492  const std::vector<reco::PFCandidatePtr>& pfChargedHadrCands = tau.pfTauTagInfoRef()->PFChargedHadrCands();
493  for ( std::vector<reco::PFCandidatePtr>::const_iterator pfChargedHadrCand = pfChargedHadrCands.begin();
494  pfChargedHadrCand != pfChargedHadrCands.end(); ++pfChargedHadrCand ) {
495  double dR = reco::deltaR(tauEta, tauPhi, (*pfChargedHadrCand)->eta(), (*pfChargedHadrCand)->phi());
496  if ( dR < chargeIsolationCone_ ) hadrons.push_back(*pfChargedHadrCand);
497  }
498 
499  const std::vector<reco::PFCandidatePtr>& pfGammaCands = tau.pfTauTagInfoRef()->PFGammaCands();
500  for ( std::vector<reco::PFCandidatePtr>::const_iterator pfGammaCand = pfGammaCands.begin();
501  pfGammaCand != pfGammaCands.end(); ++pfGammaCand ) {
502  double dR = reco::deltaR(tauEta, tauPhi, (*pfGammaCand)->eta(), (*pfGammaCand)->phi());
503  if ( dR < gammaIsolationCone_ ) gammas.push_back(*pfGammaCand);
504  }
505 
506  const std::vector<reco::PFCandidatePtr>& pfNeutralHadrCands = tau.pfTauTagInfoRef()->PFNeutrHadrCands();
507  for ( std::vector<reco::PFCandidatePtr>::const_iterator pfNeutralHadrCand = pfNeutralHadrCands.begin();
508  pfNeutralHadrCand != pfNeutralHadrCands.end(); ++pfNeutralHadrCand ) {
509  double dR = reco::deltaR(tauEta, tauPhi, (*pfNeutralHadrCand)->eta(), (*pfNeutralHadrCand)->phi());
510  if ( dR < neutrHadrIsolationCone_ ) hadrons.push_back(*pfNeutralHadrCand);
511  }
512  }
513 
514  //remove the signal Constituents from the collections
515  for(std::vector<PFCandidatePtr>::const_iterator i=tau.signalPFChargedHadrCands().begin();i!=tau.signalPFChargedHadrCands().end();++i)
516  {
518  }
519 
520  for(std::vector<PFCandidatePtr>::const_iterator i=tau.signalPFGammaCands().begin();i!=tau.signalPFGammaCands().end();++i)
521  {
523  removeCandidateFromRefVector(*i,hadrons);//special case where we included a hadron if the strip!
524  }
525 
526 
527  //calculate isolation deposits
528  for(unsigned int i=0;i<hadrons.size();++i)
529  {
530  sumPT+=hadrons[i]->pt();
531  }
532 
533  for(unsigned int i=0;i<gammas.size();++i)
534  {
535  sumET+=gammas[i]->pt();
536  }
537 
538 
541  tau.setisolationPFChargedHadrCands(hadrons);
542  tau.setisolationPFNeutrHadrCands(neutral);
543  tau.setisolationPFGammaCands(gammas);
544 
545  std::vector<PFCandidatePtr> isoAll = hadrons;
546  for(unsigned int i=0;i<gammas.size();++i)
547  isoAll.push_back(gammas[i]);
548 
549  for(unsigned int i=0;i<neutral.size();++i)
550  isoAll.push_back(neutral[i]);
551 
552  tau.setisolationPFCands(isoAll);
553 }
554 
555 void
557 {
558 
559  // Require that no signal track has segment matches
560 
561  //Also:
562  //The segment compatibility is the number of matched Muon Segments
563  //the old available does not exist in the muons anymore so i will fill the data format with that
564  bool decision=true;
565  float caloComp=0.0;
566  float segComp=0.0;
567 
568  if(tau.leadPFChargedHadrCand().isNonnull()) {
569  MuonRef mu =tau.leadPFChargedHadrCand()->muonRef();
570  if(mu.isNonnull()){
571  segComp=(float)(mu->matches().size());
572  if(mu->caloCompatibility()>caloComp)
573  caloComp = mu->caloCompatibility();
574 
575  if(segComp<1.0)
576  decision=false;
577 
578  tau.setCaloComp(caloComp);
579  tau.setSegComp(segComp);
580  tau.setMuonDecision(decision);
581  }
582 
583  }
584 }
585 
586 
587 void
589 {
590  //Here we apply the common electron rejection variables.
591  //The only not common is the E/P that is applied in the decay mode
592  //construction
593 
594 
595  if(tau.leadPFChargedHadrCand().isNonnull()) {
596  PFCandidatePtr leadCharged = tau.leadPFChargedHadrCand();
597  math::XYZVector caloDir(leadCharged->positionAtECALEntrance().x(),
598  leadCharged->positionAtECALEntrance().y(),
599  leadCharged->positionAtECALEntrance().z());
600 
601  tau.setmaximumHCALPFClusterEt(leadCharged->hcalEnergy()*sin(caloDir.theta()));
602 
603 
604 
605  if(leadCharged->trackRef().isNonnull()) {
606  TrackRef track = leadCharged->trackRef();
607  tau.setemFraction(leadCharged->ecalEnergy()/(leadCharged->ecalEnergy()+leadCharged->hcalEnergy()));
608  //For H/P trust particle Flow ! :Just take HCAL energy of the candidate
609  //end of story
610  tau.sethcalTotOverPLead(leadCharged->hcalEnergy()/track->p());
611  tau.sethcalMaxOverPLead(leadCharged->hcalEnergy()/track->p());
612  tau.sethcal3x3OverPLead(leadCharged->hcalEnergy()/track->p());
613  tau.setelectronPreIDTrack(track);
614  tau.setelectronPreIDOutput(leadCharged->mva_e_pi());
615  //Since PF uses brem recovery we will store the default ecal energy here
616  tau.setbremsRecoveryEOverPLead(leadCharged->ecalEnergy()/track->p());
617  tau.setecalStripSumEOverPLead((leadCharged->ecalEnergy()-stripEnergy)/track->p());
618  bool electronDecision;
619  if(std::abs(leadCharged->pdgId())==11)
620  electronDecision=true;
621  else
622  electronDecision=false;
623  tau.setelectronPreIDDecision(electronDecision);
624  }
625  }
626 }
627 
628 
629 
630 
631 void
633 {
634  emMerger_ = p.getParameter<std::string>("emMergingAlgorithm");
635  overlapCriterion_ = p.getParameter<std::string>("candOverlapCriterion");
636  doOneProngs_ = p.getParameter<bool>("doOneProng");
637  doOneProngStrips_ = p.getParameter<bool>("doOneProngStrip");
638  doOneProngTwoStrips_ = p.getParameter<bool>("doOneProngTwoStrips");
639  doThreeProngs_ = p.getParameter<bool>("doThreeProng");
640  tauThreshold_ = p.getParameter<double>("tauPtThreshold");
641  leadPionThreshold_ = p.getParameter<double>("leadPionThreshold");
642  stripPtThreshold_ = p.getParameter<double>("stripPtThreshold");
643  chargeIsolationCone_ = p.getParameter<double>("chargeHadrIsolationConeSize");
644  gammaIsolationCone_ = p.getParameter<double>("gammaIsolationConeSize");
645  neutrHadrIsolationCone_ = p.getParameter<double>("neutrHadrIsolationConeSize");
646  useIsolationAnnulus_ = p.getParameter<bool>("useIsolationAnnulus");
647  oneProngStripMassWindow_ = p.getParameter<std::vector<double> >("oneProngStripMassWindow");
648  oneProngTwoStripsMassWindow_ = p.getParameter<std::vector<double> >("oneProngTwoStripsMassWindow");
649  oneProngTwoStripsPi0MassWindow_= p.getParameter<std::vector<double> >("oneProngTwoStripsPi0MassWindow");
650  threeProngMassWindow_ = p.getParameter<std::vector<double> >("threeProngMassWindow");
651  matchingCone_ = p.getParameter<double>("matchingCone");
652  coneMetric_ = p.getParameter<std::string>("coneMetric");
653  coneSizeFormula_ = p.getParameter<std::string>("coneSizeFormula");
654  minSignalCone_ = p.getParameter<double>("minimumSignalCone");
655  maxSignalCone_ = p.getParameter<double>("maximumSignalCone");
656 
657 
658 
659  //Initialize The Merging Algorithm!
660  if(emMerger_ =="StripBased")
662  //Add the Pi0 Merger from Evan here
663 
664 
665  if(oneProngStripMassWindow_.size()!=2)
666  throw cms::Exception("") << "OneProngStripMassWindow must be a vector of size 2 [min,max] " << std::endl;
667  if(oneProngTwoStripsMassWindow_.size()!=2)
668  throw cms::Exception("") << "OneProngTwoStripsMassWindow must be a vector of size 2 [min,max] " << std::endl;
669  if(threeProngMassWindow_.size()!=2)
670  throw cms::Exception("") << "ThreeProngMassWindow must be a vector of size 2 [min,max] " << std::endl;
671  if(coneMetric_!= "angle" && coneMetric_ != "DR")
672  throw cms::Exception("") << "Cone Metric should be angle or DR " << std::endl;
673 
674  coneSizeFormula = TauTagTools::computeConeSizeTFormula(coneSizeFormula_,"Signal cone size Formula");
675 
676 
677 }
678 
679 
680 
682 HPSPFRecoTauAlgorithm::createMergedLorentzVector(const std::vector<reco::PFCandidatePtr>& cands)
683 {
685  for(unsigned int i=0;i<cands.size();++i) {
686  sum+=cands[i]->p4();
687  }
688  return sum;
689 }
690 
691 void
692 HPSPFRecoTauAlgorithm::removeCandidateFromRefVector(const reco::PFCandidatePtr& cand,std::vector<reco::PFCandidatePtr>& vec)
693 {
694  std::vector<PFCandidatePtr> newVec;
695 
696  std::vector<PFCandidatePtr>::iterator it;
697  it = std::find(vec.begin(),vec.end(),cand);
698  if(it!=vec.end())
699  vec.erase(it);
700 }
701 
702 void
704 {
705  double factor = sqrt(vec.energy()*vec.energy()-mass*mass)/vec.P();
706  vec.SetCoordinates(vec.px()*factor,vec.py()*factor,vec.pz()*factor,vec.energy());
707 }
708 
709 
710 
711 
712 bool
714 {
715  bool response=false;
716  //Get Hadrons
717  std::vector<reco::PFCandidatePtr> hadrons = tau.signalPFChargedHadrCands();
718  PFCandidatePtr h1 = hadrons[0];
719  PFCandidatePtr h2 = hadrons[1];
720  PFCandidatePtr h3 = hadrons[2];
721 
722  //Make transient tracks
723  std::vector<TransientTrack> transientTracks;
724  transientTracks.push_back(TransientTrackBuilder_->build(h1->trackRef()));
725  transientTracks.push_back(TransientTrackBuilder_->build(h2->trackRef()));
726  transientTracks.push_back(TransientTrackBuilder_->build(h3->trackRef()));
727 
728  //Apply the Vertex Fit
729  KalmanVertexFitter fitter(true);
730  TransientVertex myVertex = fitter.vertex(transientTracks);
731 
732  //Just require a valid vertex+ 3 refitted tracks
733  if(myVertex.isValid()&&
734  myVertex.hasRefittedTracks()&&
735  myVertex.refittedTracks().size()==3) {
736 
737  response=true;
738  math::XYZPoint vtx(myVertex.position().x(),myVertex.position().y(),myVertex.position().z());
739 
740  //Create a LV for each refitted track
741  const std::vector<reco::TransientTrack>& refittedTracks = myVertex.refittedTracks();
742  const reco::Track& track1 = refittedTracks.at(0).track();
743  math::XYZTLorentzVector p1(track1.px(), track1.py(), track1.pz(), sqrt(track1.momentum().mag2() + 0.139*0.139));
744  const reco::Track& track2 = refittedTracks.at(1).track();
745  math::XYZTLorentzVector p2(track2.px(), track2.py(), track2.pz(), sqrt(track2.momentum().mag2() + 0.139*0.139));
746  const reco::Track& track3 = refittedTracks.at(2).track();
747  math::XYZTLorentzVector p3(track3.px(), track3.py(), track3.pz(), sqrt(track3.momentum().mag2() + 0.139*0.139));
748 
749  //Update the tau p4
750  tau.setP4(p1+p2+p3);
751  //Update the vertex
752  tau.setVertex(vtx);
753  }
754  return response;
755 
756 }
757 
760 {
761  reco::PFTauCollection::iterator it;
762  if(overlapCriterion_ =="Isolation"){
764  it = std::min_element(taus.begin(),taus.end(),sorter);
765 
766  }
767  else if(overlapCriterion_ =="Pt"){
769  it = std::min_element(taus.begin(),taus.end(),sorter);
770  }
771 
772  return *it;
773 }
774 
virtual double energy() const GCC11_FINAL
energy
T getParameter(std::string const &) const
virtual double et() const GCC11_FINAL
transverse energy
int i
Definition: DBlmapReader.cc:9
void setMuonDecision(const bool &)
Definition: PFTau.cc:239
void setelectronPreIDOutput(const float &)
Definition: PFTau.cc:220
std::vector< PFTau > PFTauCollection
collection of PFTau objects
Definition: PFTauFwd.h:9
const Vector & momentum() const
track momentum vector
Definition: TrackBase.h:148
void setleadPFChargedHadrCand(const PFCandidatePtr &)
Definition: PFTau.cc:65
const PFCandidatePtr & leadPFChargedHadrCand() const
Definition: PFTau.cc:61
void setelectronPreIDDecision(const bool &)
Definition: PFTau.cc:221
virtual const LorentzVector & p4() const GCC11_FINAL
four-momentum Lorentz vector
math::XYZTLorentzVector createMergedLorentzVector(const std::vector< reco::PFCandidatePtr > &)
void setisolationPFCands(const std::vector< reco::PFCandidatePtr > &)
Definition: PFTau.cc:82
void buildOneProng(const reco::PFTauTagInfoRef &, const std::vector< reco::PFCandidatePtr > &)
const TransientTrackBuilder * TransientTrackBuilder_
void buildThreeProngs(const reco::PFTauTagInfoRef &, const std::vector< reco::PFCandidatePtr > &)
virtual CachingVertex< 5 > vertex(const std::vector< reco::TransientTrack > &tracks) const
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
std::pair< bool, Measurement1D > signedTransverseImpactParameter(const reco::TransientTrack &track, const GlobalVector &direction, const reco::Vertex &vertex)
Definition: IPTools.cc:50
const std::vector< reco::PFCandidatePtr > & signalPFGammaCands() const
Gamma candidates in signal region.
Definition: PFTau.cc:78
reco::PFTau buildPFTau(const reco::PFTauTagInfoRef &, const reco::Vertex &)
reco::TransientTrack build(const reco::Track *p) const
T y() const
Definition: PV3DBase.h:63
void buildOneProngStrip(const reco::PFTauTagInfoRef &, const std::vector< std::vector< reco::PFCandidatePtr >> &, const std::vector< reco::PFCandidatePtr > &)
bool hasRefittedTracks() const
std::vector< double > threeProngMassWindow_
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:131
void sethcal3x3OverPLead(const float &)
Definition: PFTau.cc:216
reco::PFTauCollection pfTaus_
void setisolationPFGammaCandsEtSum(const float &)
Definition: PFTau.cc:197
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
void setemFraction(const float &)
Definition: PFTau.cc:213
double charge(const std::vector< uint8_t > &Ampls)
void setisolationPFNeutrHadrCands(const std::vector< reco::PFCandidatePtr > &)
Definition: PFTau.cc:86
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:250
void setsignalPFChargedHadrCands(const std::vector< reco::PFCandidatePtr > &)
Definition: PFTau.cc:75
virtual float phi() const GCC11_FINAL
momentum azimuthal angle
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:152
reco::PFTau getBestTauCandidate(reco::PFTauCollection &)
bool isNull() const
Checks for null.
Definition: Ref.h:247
const T & max(const T &a, const T &b)
T sqrt(T t)
Definition: SSEVec.h:48
GlobalPoint position() const
T z() const
Definition: PV3DBase.h:64
void setleadPFCand(const PFCandidatePtr &)
Definition: PFTau.cc:67
void setCaloComp(const float &)
Definition: PFTau.cc:237
void applyElectronRejection(reco::PFTau &, double)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int j
Definition: DBlmapReader.cc:9
void setisolationPFChargedHadrCandsPtSum(const float &)
Definition: PFTau.cc:194
auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:30
void setleadPFChargedHadrCandsignedSipt(const float &)
Definition: PFTau.cc:70
void setsignalPFCands(const std::vector< reco::PFCandidatePtr > &)
Definition: PFTau.cc:73
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
virtual std::vector< std::vector< reco::PFCandidatePtr > > mergeCandidates(const std::vector< reco::PFCandidatePtr > &)=0
const int mu
Definition: Constants.h:22
double p2[4]
Definition: TauolaWrapper.h:90
TFormula computeConeSizeTFormula(const std::string &ConeSizeFormula, const char *errorMessage)
virtual void setVertex(const Point &vertex)
set vertex
void setbremsRecoveryEOverPLead(const float &)
Definition: PFTau.cc:218
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:135
virtual float eta() const GCC11_FINAL
momentum pseudorapidity
const PFTauTagInfoRef & pfTauTagInfoRef() const
Definition: PFTau.cc:55
virtual float mass() const GCC11_FINAL
mass
void sethcalMaxOverPLead(const float &)
Definition: PFTau.cc:215
std::vector< double > oneProngTwoStripsMassWindow_
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
void setisolationPFGammaCands(const std::vector< reco::PFCandidatePtr > &)
Definition: PFTau.cc:88
void setSegComp(const float &)
Definition: PFTau.cc:238
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
void setisolationPFChargedHadrCands(const std::vector< reco::PFCandidatePtr > &)
Definition: PFTau.cc:84
void buildOneProngTwoStrips(const reco::PFTauTagInfoRef &, const std::vector< std::vector< reco::PFCandidatePtr >> &, const std::vector< reco::PFCandidatePtr > &)
double b
Definition: hdecay.h:120
void sortRefVectorByPt(std::vector< reco::PFCandidatePtr > &)
Definition: TauTagTools.cc:242
std::vector< double > oneProngStripMassWindow_
double p1[4]
Definition: TauolaWrapper.h:89
virtual void setP4(const LorentzVector &p4) GCC11_FINAL
set 4-momentum
double a
Definition: hdecay.h:121
void setmaximumHCALPFClusterEt(const float &)
Definition: PFTau.cc:200
void removeCandidateFromRefVector(const reco::PFCandidatePtr &, std::vector< reco::PFCandidatePtr > &)
void applyMuonRejection(reco::PFTau &)
void setecalStripSumEOverPLead(const float &)
Definition: PFTau.cc:217
std::vector< double > oneProngTwoStripsPi0MassWindow_
std::vector< reco::TransientTrack > const & refittedTracks() const
void sethcalTotOverPLead(const float &)
Definition: PFTau.cc:214
void applyMassConstraint(math::XYZTLorentzVector &, double)
virtual float pt() const GCC11_FINAL
transverse momentum
void setelectronPreIDTrack(const reco::TrackRef &)
Definition: PFTau.cc:219
void configure(const edm::ParameterSet &)
T x() const
Definition: PV3DBase.h:62
bool refitThreeProng(reco::PFTau &)
PFCandidateMergerBase * candidateMerger_
bool isNarrowTau(const reco::PFTau &, double)
bool isValid() const
void associateIsolationCandidates(reco::PFTau &, double)
const std::vector< reco::PFCandidatePtr > & signalPFChargedHadrCands() const
Charged hadrons in signal region.
Definition: PFTau.cc:74
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:133
double p3[4]
Definition: TauolaWrapper.h:91
void setpfTauTagInfoRef(const PFTauTagInfoRef)
Definition: PFTau.cc:59