All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
IsolatedLeptonFinderProcessor.cc
Go to the documentation of this file.
2 
3 #include <iostream>
4 #include <sstream>
5 #include <fstream>
6 #include <utility>
7 #include <cmath>
8 
9 #include <EVENT/LCCollection.h>
10 #include <EVENT/MCParticle.h>
11 #include <IMPL/LCCollectionVec.h>
12 
13 // ----- include for verbosity dependend logging ---------
14 #include <marlin/VerbosityLevels.h>
15 
16 #include <TMath.h>
17 #include <TVector3.h>
18 #include <TLorentzVector.h>
19 
20 using namespace lcio ;
21 using namespace marlin ;
22 
24 
26  : Processor("IsolatedLeptonFinderProcessor") {
27 
28  // Processor description
29  _description = "Isolated Lepton Finder Processor" ;
30 
31  // register steering parameters: name, description, class-variable, default value
32  registerInputCollection( LCIO::RECONSTRUCTEDPARTICLE,
33  "InputCollection" ,
34  "Input collection of ReconstructedParticles",
36  std::string("PandoraPFOs"));
37 
38  registerOutputCollection( LCIO::RECONSTRUCTEDPARTICLE,
39  "OutputCollectionWithoutIsolatedLepton",
40  "Copy of input collection but without the isolated leptons",
42  std::string("PandoraPFOsWithoutIsoLep") );
43 
44  registerOutputCollection( LCIO::RECONSTRUCTEDPARTICLE,
45  "OutputCollectionIsolatedLeptons",
46  "Output collection of isolated leptons",
48  std::string("Isolep") );
49 
50  registerProcessorParameter( "CosConeAngle",
51  "Cosine of the half-angle of the cone used in isolation criteria",
53  float(0.98));
54 
55  registerProcessorParameter( "UsePID",
56  "Use primitive particle ID based on calorimeter energy deposits",
57  _usePID,
58  bool(true));
59 
60  registerProcessorParameter( "ElectronMinEnergyDepositByMomentum",
61  "Electron ID: Minimum energy deposit divided by momentum",
63  float(0.7));
64 
65  registerProcessorParameter( "ElectronMaxEnergyDepositByMomentum",
66  "Electron ID: Maximum energy deposit divided by momentum",
68  float(1.4));
69 
70  registerProcessorParameter( "ElectronMinEcalToHcalFraction",
71  "Electron ID: Minimum Ecal deposit divided by sum of Ecal and Hcal deposits",
73  float(0.9));
74 
75  registerProcessorParameter( "ElectronMaxEcalToHcalFraction",
76  "Electron ID: Maximum Ecal deposit divided by sum of Ecal and Hcal deposits",
78  float(1.0));
79 
80  registerProcessorParameter( "MuonMinEnergyDepositByMomentum",
81  "Muon ID: Minimum energy deposit divided by momentum",
83  float(0.0));
84 
85  registerProcessorParameter( "MuonMaxEnergyDepositByMomentum",
86  "Muon ID: Maximum energy deposit divided by momentum",
88  float(0.3));
89 
90  registerProcessorParameter( "MuonMinEcalToHcalFraction",
91  "Muon ID: Minimum Ecal deposit divided by sum of Ecal and Hcal deposits",
93  float(0.0));
94 
95  registerProcessorParameter( "MuonMaxEcalToHcalFraction",
96  "Muon ID: Maximum Ecal deposit divided by sum of Ecal and Hcal deposits",
98  float(0.4));
99 
100  registerProcessorParameter( "UseImpactParameter",
101  "Use impact parameter cuts for consistency with primary/secondary track",
103  bool(true));
104 
105  registerProcessorParameter( "ImpactParameterMinD0",
106  "Minimum d0 impact parameter",
107  _minD0,
108  float(0.0));
109 
110  registerProcessorParameter( "ImpactParameterMaxD0",
111  "Maximum d0 impact parameter",
112  _maxD0,
113  float(1e20));
114 
115  registerProcessorParameter( "ImpactParameterMinZ0",
116  "Minimum z0 impact parameter",
117  _minZ0,
118  float(0.0));
119 
120  registerProcessorParameter( "ImpactParameterMaxZ0",
121  "Maximum z0 impact parameter",
122  _maxZ0,
123  float(1e20));
124 
125  registerProcessorParameter( "ImpactParameterMin3D",
126  "Minimum impact parameter in 3D",
127  _minR0,
128  float(0.0));
129 
130  registerProcessorParameter( "ImpactParameterMax3D",
131  "Maximum impact parameter in 3D",
132  _maxR0,
133  float(0.01));
134 
135  registerProcessorParameter( "UseImpactParameterSignificance",
136  "Use impact parameter significance cuts for consistency with primary/secondary track",
138  bool(false));
139 
140  registerProcessorParameter( "ImpactParameterMinD0Significance",
141  "Minimum d0 impact parameter significance",
142  _minD0Sig,
143  float(0.0));
144 
145  registerProcessorParameter( "ImpactParameterMaxD0Significance",
146  "Maximum d0 impact parameter significance",
147  _maxD0Sig,
148  float(1e20));
149 
150  registerProcessorParameter( "ImpactParameterMinZ0Significance",
151  "Minimum z0 impact parameter significance",
152  _minZ0Sig,
153  float(0.0));
154 
155  registerProcessorParameter( "ImpactParameterMaxZ0Significance",
156  "Maximum z0 impact parameter significance",
157  _maxZ0Sig,
158  float(1e20));
159 
160  registerProcessorParameter( "ImpactParameterMin3DSignificance",
161  "Minimum impact parameter significance in 3D",
162  _minR0Sig,
163  float(0.0));
164 
165  registerProcessorParameter( "ImpactParameterMax3DSignificance",
166  "Maximum impact parameter significance in 3D",
167  _maxR0Sig,
168  float(1e20));
169 
170  registerProcessorParameter( "UseRectangularIsolation",
171  "Use rectangular cuts on track and cone energy",
173  bool(true));
174 
175  registerProcessorParameter( "IsolationMinimumTrackEnergy",
176  "Minimum track energy for isolation requirement",
178  float(15));
179 
180  registerProcessorParameter( "IsolationMaximumTrackEnergy",
181  "Maximum track energy for isolation requirement",
183  float(1e20));
184 
185  registerProcessorParameter( "IsolationMinimumConeEnergy",
186  "Minimum cone energy for isolation requirement",
188  float(0));
189 
190  registerProcessorParameter( "IsolationMaximumConeEnergy",
191  "Maximum cone energy for isolation requirement",
193  float(1e20));
194 
195  registerProcessorParameter( "UsePolynomialIsolation",
196  "Use polynomial cuts on track and cone energy",
198  bool(true));
199 
200  registerProcessorParameter( "IsolationPolynomialCutA",
201  "Polynomial cut (A) on track energy and cone energy: Econe^2 < A*Etrk^2+B*Etrk+C",
203  float(0));
204 
205  registerProcessorParameter( "IsolationPolynomialCutB",
206  "Polynomial cut (B) on track energy and cone energy: Econe^2 < A*Etrk^2+B*Etrk+C",
208  float(20));
209 
210  registerProcessorParameter( "IsolationPolynomialCutC",
211  "Polynomial cut (C) on track energy and cone energy: Econe^2 < A*Etrk^2+B*Etrk+C",
213  float(-300));
214 
215  registerProcessorParameter( "UseJetIsolation",
216  "Use jet-based isolation",
218  bool(false));
219 
220  registerInputCollection( LCIO::RECONSTRUCTEDPARTICLE,
221  "JetCollection" ,
222  "Input collection of jets for isolation",
224  std::string("JetsForIsolation"));
225 
226  registerProcessorParameter( "JetIsolationVetoMinimumXt",
227  "Minimum Xt in jet-based isolation",
229  float(0.));
230 
231  registerProcessorParameter( "JetIsolationVetoMaximumXt",
232  "Maximum Xt in jet-based isolation",
234  float(0.25));
235 
236  registerProcessorParameter( "JetIsolationVetoMinimumZ",
237  "Mininum Z in jet-based isolation",
239  float(0.));
240 
241  registerProcessorParameter( "JetIsolationVetoMaximumZ",
242  "Maximum Z in jet-based isolation",
244  float(0.6));
245 
246  registerProcessorParameter( "UseDressedLeptons",
247  "Dress leptons with close-by particles",
249  bool(false));
250 
251  registerProcessorParameter( "MergeCloseElectrons",
252  "Merge close-by electrons into higher energy lepton",
254  bool(false));
255 
256  registerProcessorParameter( "DressPhotonConeAngle",
257  "Half-angle (in degrees) of the cone used for lepton dressing with photons",
259  float(1));
260 
261  registerProcessorParameter( "MergeLeptonConeAngle",
262  "Half-angle (in degrees) of the cone used for lepton merging",
264  float(2));
265 
266  registerProcessorParameter( "UsePandoraIDs",
267  "Use Pandora particle IDs for algorithm",
269  bool(false));
270  }
271 
272 
274  streamlog_out(DEBUG) << " init called " << std::endl ;
275  printParameters() ;
276 }
277 
279 
280  streamlog_out(DEBUG) <<std::endl;
281  streamlog_out(DEBUG) << "processing event: " << evt->getEventNumber() << " in run: " << evt->getRunNumber() << std::endl ;
282 
283  _rpJetMap.clear();
284  _workingList.clear();
285 
286  _pfoCol = evt->getCollection( _inputPFOsCollection ) ;
287 
288  // Output PFOs isolated leptons
289  auto outIsoLepCol = std::unique_ptr<LCCollectionVec>(new LCCollectionVec( LCIO::RECONSTRUCTEDPARTICLE ) );
290  // Output PFOs removed isolated leptons
291  auto outPFOsRemovedIsoLepCol = std::unique_ptr<LCCollectionVec>(new LCCollectionVec( LCIO::RECONSTRUCTEDPARTICLE ) );
292 
293  // Prepare jet/recoparticle map for jet-based isolation
294  if (_useJetIsolation) {
295  LCCollection *colJet = evt->getCollection(_jetCollectionName);
296  int njet = colJet->getNumberOfElements();
297  for (int i=0; i<njet; ++i) {
298  ReconstructedParticle* jet = static_cast<ReconstructedParticle*>( colJet->getElementAt(i) );
299  for (ReconstructedParticleVec::const_iterator iter = jet->getParticles().begin();
300  iter != jet->getParticles().end(); ++iter) {
301  _rpJetMap.insert( std::make_pair( *iter, jet ) );
302  }
303  }
304  }
305 
306  // Determine lepton pfos
307  std::vector<int> goodLeptonIndices;
308  int npfo = _pfoCol->getNumberOfElements();
309  for (int i = 0; i < npfo; i++ ) {
310  ReconstructedParticle* pfo = static_cast<ReconstructedParticle*>( _pfoCol->getElementAt(i) );
311  _workingList.push_back( pfo );
312 
313  if ( !IsGoodLepton( pfo )) {
314  continue;
315  }
316 
317  // remember lepton indices for later
318  if (_useDressedLeptons){
319  if (IsLepton( pfo )) goodLeptonIndices.push_back(i);
320  }else{
321  goodLeptonIndices.push_back(i);
322  }
323  }
324 
325  // order by energy
326  std::sort(goodLeptonIndices.begin(), goodLeptonIndices.end(), [this](const int i, const int j) {return isMoreEnergetic(i, j);});
327 
328  // process and save leptons
329  for (unsigned int i = 0; i < goodLeptonIndices.size(); ++i)
330  {
331  ReconstructedParticle* pfo_tmp = static_cast<ReconstructedParticle*>( _pfoCol->getElementAt(goodLeptonIndices.at(i) ));
332  ReconstructedParticleImpl* pfo = CopyReconstructedParticle( pfo_tmp );
333 
334  if (_useDressedLeptons){
335  // don't reprocess merged leptons
336  if (std::find(_workingList.begin(), _workingList.end(), pfo_tmp) == _workingList.end()) {
337  continue;
338  }
339 
340  double energy_before = pfo->getEnergy();
341  int n_working_list_before = _workingList.size();
342 
343  dressLepton(pfo, goodLeptonIndices.at(i));
344 
345  streamlog_out(DEBUG) << "dress lepton " << i << " with " << n_working_list_before - _workingList.size() << " particles: energy " << energy_before << " -> " << pfo->getEnergy() << std::endl ;
346  // printf("dressedMomentum: %.2f -> %.2f, %.2f -> %.2f ,%.2f -> %.2f ,%.2f -> %.2f\n", pfo_tmp->getMomentum()[0], pfo->getMomentum()[0], pfo_tmp->getMomentum()[1], pfo->getMomentum()[1], pfo_tmp->getMomentum()[2], pfo->getMomentum()[2], pfo->getEnergy(), pfo_tmp->getEnergy());
347  }
348 
349  if ( IsIsolatedLepton( pfo ) ){
350  outIsoLepCol->addElement( pfo );
351  }else{
352  outPFOsRemovedIsoLepCol->addElement( pfo );
353  }
354  }
355 
356  // filling remaining non-lepton PFOs
357  for (unsigned int i = 0; i < _workingList.size(); i++ ) {
358  // don't add leptons again
359  if (std::find(goodLeptonIndices.begin(), goodLeptonIndices.end(), i) != goodLeptonIndices.end()){
360  continue;
361  }
362  ReconstructedParticle* pfo_tmp = static_cast<ReconstructedParticle*>( _workingList.at(i) );
363  ReconstructedParticleImpl* pfo = CopyReconstructedParticle( pfo_tmp );
364  outPFOsRemovedIsoLepCol->addElement( pfo );
365  }
366 
367  // Add PFOs to new collections
368  evt->addCollection( outPFOsRemovedIsoLepCol.release(), _outputPFOsRemovedIsoLepCollection.c_str() );
369  evt->addCollection( outIsoLepCol.release(), _outputIsoLepCollection.c_str() );
370 }
371 void IsolatedLeptonFinderProcessor::dressLepton( ReconstructedParticleImpl* pfo, int PFO_idx ) {
372  TVector3 P_lep( pfo->getMomentum() );
373  int npfo = _pfoCol->getNumberOfElements();
374  std::vector<int> _dressedPFOs {};
375  for ( int i = 0; i < npfo; i++ ) {
376  ReconstructedParticle* pfo_dress = static_cast<ReconstructedParticle*>( _pfoCol->getElementAt(i) );
377 
378  // only add photons and electrons
379  bool isPhoton = IsPhoton(pfo_dress);
380  bool isElectron = !isPhoton && IsElectron(pfo_dress); // avoid electrons identified as photons to enter as both
381  if (!isPhoton && !isElectron) continue;
382 
383  if (!_mergeCloseElectrons && isElectron) continue;
384 
385  // don't add itself to itself
386  if ( i == PFO_idx ) continue;
387 
388  TVector3 Pdress( pfo_dress->getMomentum() );
389  float theta = TMath::ACos(P_lep.Dot( Pdress )/(P_lep.Mag()*Pdress.Mag())) * 360 / (2 * TMath::Pi());
390 
391  if ( (isPhoton && theta <= _dressPhotonConeAngle) ||
392  (isElectron && theta <= _mergeLeptonConeAngle) ){
393  if (std::find(_dressedPFOs.begin(), _dressedPFOs.end(), i) != _dressedPFOs.end()){
394  if (isPhoton) {streamlog_out(DEBUG) << "WARNING: photon "<<i<<" with theta "<<theta <<" and type "<<pfo->getType()<<" already close to another lepton!"<<std::endl;}
395  else if (isElectron) {streamlog_out(DEBUG) << "WARNING: lepton "<<i<<" with theta "<<theta <<" and type "<<pfo->getType()<<" already close to another lepton!"<<std::endl;}
396  // printf(" -- this lep: %.2f, %.2f ,%.2f ,%.2f\n", pfo->getMomentum()[0], pfo->getMomentum()[1], pfo->getMomentum()[2], pfo->getEnergy());
397  continue;
398  }
399  if (isPhoton) {streamlog_out(DEBUG) << "MESSAGE: dressing photon "<<i<<" with theta "<<theta <<" and type "<<pfo->getType()<<std::endl;}
400  else if (isElectron) {streamlog_out(DEBUG) << "MESSAGE: merging lepton "<<i<<" with theta "<<theta <<" and type "<<pfo->getType()<<std::endl;}
401  _dressedPFOs.push_back(i);
402  _workingList.erase(std::remove(_workingList.begin(), _workingList.end(), pfo_dress), _workingList.end());
403  double dressedMomentum[3] = {pfo->getMomentum()[0] + pfo_dress->getMomentum()[0],
404  pfo->getMomentum()[1] + pfo_dress->getMomentum()[1],
405  pfo->getMomentum()[2] + pfo_dress->getMomentum()[2]};
406  double dressedE = pfo->getEnergy() + pfo_dress->getEnergy();
407  pfo->setMomentum(dressedMomentum);
408  pfo->setEnergy(dressedE);
409  }
410  }
411 }
413 }
414 ReconstructedParticleImpl* IsolatedLeptonFinderProcessor::CopyReconstructedParticle ( ReconstructedParticle* pfo_orig ) {
415  // copy this in an ugly fashion to be modifiable - a versatile copy constructor would be much better!
416  ReconstructedParticleImpl* pfo = new ReconstructedParticleImpl();
417  pfo->setMomentum(pfo_orig->getMomentum());
418  pfo->setEnergy(pfo_orig->getEnergy());
419  pfo->setType(pfo_orig->getType());
420  pfo->setCovMatrix(pfo_orig->getCovMatrix());
421  pfo->setMass(pfo_orig->getMass());
422  pfo->setCharge(pfo_orig->getCharge());
423  pfo->setParticleIDUsed(pfo_orig->getParticleIDUsed());
424  pfo->setGoodnessOfPID(pfo_orig->getGoodnessOfPID());
425  pfo->setStartVertex(pfo_orig->getStartVertex());
426  for(unsigned int i=0;i<pfo->getTracks().size();i++){
427  pfo->addTrack(pfo_orig->getTracks()[i]);
428  }
429  for(unsigned int i=0;i<pfo->getClusters().size();i++){
430  pfo->addCluster(pfo_orig->getClusters()[i]);
431  }
432  return pfo;
433 }
434 bool IsolatedLeptonFinderProcessor::IsCharged( ReconstructedParticle* pfo ) {
435  if ( pfo->getCharge() == 0 ) return false;
436  return true;
437 }
438 
439 bool IsolatedLeptonFinderProcessor::IsPhoton( ReconstructedParticle* pfo ) {
440  if ( pfo->getType() == 22 ) return true;
441  return false;
442 }
443 bool IsolatedLeptonFinderProcessor::IsElectron( ReconstructedParticle* pfo ) {
444 
445  if (_usePandoraIDs) return (abs(pfo->getType()) == 11);
446 
447  float CalE[2];
448  getCalEnergy( pfo , CalE );
449  double ecale = CalE[0];
450  double hcale = CalE[1];
451  double p = TVector3( pfo->getMomentum() ).Mag();
452  double calByP = p>0 ? (ecale + hcale)/p : 0;
453  double calSum = ecale+hcale;
454  double ecalFrac = calSum>0 ? ecale / calSum : 0;
455 
458  && ecalFrac >= _electronMinEcalToHcalFraction
459  && ecalFrac <= _electronMaxEcalToHcalFraction )
460  return true;
461 
462  return false;
463 }
464 bool IsolatedLeptonFinderProcessor::IsMuon( ReconstructedParticle* pfo ) {
465 
466  if (_usePandoraIDs) return (abs(pfo->getType()) == 13);
467 
468  float CalE[2];
469  getCalEnergy( pfo , CalE );
470  double ecale = CalE[0];
471  double hcale = CalE[1];
472  double p = TVector3( pfo->getMomentum() ).Mag();
473  double calByP = p>0 ? (ecale + hcale)/p : 0;
474  double calSum = ecale+hcale;
475  double ecalFrac = calSum>0 ? ecale / calSum : 0;
476 
477  if ( calByP >= _muonMinEnergyDepositByMomentum
479  && ecalFrac >= _muonMinEcalToHcalFraction
480  && ecalFrac <= _muonMaxEcalToHcalFraction )
481  return true;
482 
483  return false;
484 }
485 bool IsolatedLeptonFinderProcessor::IsLepton( ReconstructedParticle* pfo ) {
486 
487  if (IsElectron(pfo) || IsMuon(pfo))
488  return true;
489  return false;
490 }
491 
492 bool IsolatedLeptonFinderProcessor::IsGoodLepton( ReconstructedParticle* pfo ) {
493 
494  if ( !IsCharged(pfo) )
495  return false;
496 
497  if ( _usePID && !IsLepton(pfo) )
498  return false;
499 
501  return false ;
502 
504  return false ;
505 
506  return true;
507 }
508 
509 bool IsolatedLeptonFinderProcessor::IsIsolatedLepton( ReconstructedParticle* pfo ) {
510 
512  return false;
513 
515  return false;
516 
517  if ( _useJetIsolation && !IsIsolatedJet(pfo) )
518  return false;
519 
520  return true;
521 }
522 
523 bool IsolatedLeptonFinderProcessor::IsIsolatedRectangular( ReconstructedParticle* pfo ) {
524  float E = pfo->getEnergy() ;
525  float coneE = getConeEnergy( pfo );
526 
527  if (E < _isoMinTrackEnergy) return false;
528  if (E > _isoMaxTrackEnergy) return false;
529  if (coneE < _isoMinConeEnergy) return false;
530  if (coneE > _isoMaxConeEnergy) return false;
531 
532  return true;
533 }
534 
535 bool IsolatedLeptonFinderProcessor::IsIsolatedPolynomial( ReconstructedParticle* pfo ) {
536  float E = pfo->getEnergy() ;
537  float coneE = getConeEnergy( pfo );
538 
539  if ( coneE*coneE <= _isoPolynomialA*E*E + _isoPolynomialB*E + _isoPolynomialC )
540  return true ;
541  return false;
542 }
543 
544 bool IsolatedLeptonFinderProcessor::IsIsolatedJet( ReconstructedParticle* pfo ) {
545  // jet-based isolated lepton (LAL algorithm)
546 
547  if ( _rpJetMap.find( pfo ) == _rpJetMap.end() ) {
548  // this is often the case when jet finding fails e.g. due to too few particles in event
549  return false;
550  }
551 
552  ReconstructedParticle* jet = _rpJetMap[pfo];
553  TVector3 vec1( pfo->getMomentum() );
554  TVector3 jetmom( jet->getMomentum() );
555  TLorentzVector jetmom4( jet->getMomentum(), jet->getEnergy() );
556 
557  float jetxt = vec1.Pt( jetmom )/jetmom4.M();
558  float jetz = pfo->getEnergy()/jet->getEnergy();
559 
560  if (jetxt >= _jetIsoVetoMinXt && jetxt < _jetIsoVetoMaxXt
561  && jetz >= _jetIsoVetoMinZ && jetz < _jetIsoVetoMaxZ) {
562  //printf("xt=%f z=%f (not pass)\n",jetxt,jetz);
563  return false;
564  }
565 
566  //printf("xt=%f z=%f (PASS)\n",jetxt,jetz);
567  return true;
568 }
569 
571  const EVENT::TrackVec & trkvec = pfo->getTracks();
572 
573  if (trkvec.size()==0) return false;
574 
575  // TODO: more sophisticated pfo/track matching
576  float d0 = fabs(trkvec[0]->getD0());
577  float z0 = fabs(trkvec[0]->getZ0());
578  float r0 = sqrt( d0*d0 + z0*z0 );
579 
580  if ( d0 < _minD0 ) return false;
581  if ( d0 > _maxD0 ) return false;
582  if ( z0 < _minZ0 ) return false;
583  if ( z0 > _maxZ0 ) return false;
584  if ( r0 < _minR0 ) return false;
585  if ( r0 > _maxR0 ) return false;
586 
587  return true;
588 }
589 
591  const EVENT::TrackVec & trkvec = pfo->getTracks();
592 
593  if (trkvec.size()==0) return false;
594 
595  // TODO: more sophisticated pfo/track matching
596  float d0 = fabs(trkvec[0]->getD0());
597  float z0 = fabs(trkvec[0]->getZ0());
598  float d0err = sqrt(trkvec[0]->getCovMatrix()[0]);
599  float z0err = sqrt(trkvec[0]->getCovMatrix()[9]);
600 
601  float d0sig = d0err != 0 ? d0/d0err : 0;
602  float z0sig = z0err != 0 ? z0/z0err : 0;
603  float r0sig = sqrt( d0sig*d0sig + z0sig*z0sig );
604 
605  if ( d0sig < _minD0Sig ) return false;
606  if ( d0sig > _maxD0Sig ) return false;
607  if ( z0sig < _minZ0Sig ) return false;
608  if ( z0sig > _maxZ0Sig ) return false;
609  if ( r0sig < _minR0Sig ) return false;
610  if ( r0sig > _maxR0Sig ) return false;
611 
612  return true;
613 }
614 
615 float IsolatedLeptonFinderProcessor::getConeEnergy( ReconstructedParticle* pfo ) {
616  float coneE = 0;
617 
618  TVector3 P( pfo->getMomentum() );
619  int npfo = _workingList.size();
620  for ( int i = 0; i < npfo; i++ ) {
621  ReconstructedParticle* pfo_i = static_cast<ReconstructedParticle*>( _workingList.at(i) );
622 
623  // don't add itself to the cone energy
624  if ( pfo == pfo_i ) continue;
625 
626  TVector3 P_i( pfo_i->getMomentum() );
627  float cosTheta = P.Dot( P_i )/(P.Mag()*P_i.Mag());
628  if ( cosTheta >= _cosConeAngle )
629  coneE += pfo_i->getEnergy();
630  }
631 
632  return coneE;
633 }
634 
635 void IsolatedLeptonFinderProcessor::getCalEnergy( ReconstructedParticle* pfo , float* cale) {
636  float ecal = 0;
637  float hcal = 0;
638  std::vector<lcio::Cluster*> clusters = pfo->getClusters();
639  for ( std::vector<lcio::Cluster*>::const_iterator iCluster=clusters.begin();
640  iCluster!=clusters.end();
641  ++iCluster) {
642  ecal += (*iCluster)->getSubdetectorEnergies()[0];
643  hcal += (*iCluster)->getSubdetectorEnergies()[1];
644  }
645  cale[0] = ecal;
646  cale[1] = hcal;
647 }
648 
649 
std::string _outputIsoLepCollection
Output collection of isolated leptons.
bool _useImpactParameterSignificance
If set to true, uses impact parameter significance cuts.
bool IsIsolatedRectangular(ReconstructedParticle *pfo)
Returns true if isolated, as defined by the cone energy.
bool _usePandoraIDs
If set to true, uses Pandora particle IDs.
void dressLepton(ReconstructedParticleImpl *pfo, int PFO_idx)
Adds photons around lepton to four vector.
void getCalEnergy(ReconstructedParticle *pfo, float *cale)
[0]:Ecal energy, [1]:Hcal energy
std::vector< ReconstructedParticle * > _workingList
bool IsLepton(ReconstructedParticle *pfo)
Returns true if it passes muon or electron ID cuts.
bool PassesImpactParameterCuts(ReconstructedParticle *pfo)
Returns true if it passes impact parameter cuts.
bool IsGoodLepton(ReconstructedParticle *pfo)
Returns true if pfo is a lepton.
ReconstructedParticleImpl * CopyReconstructedParticle(ReconstructedParticle *pfo)
Replace missing copy constructor by hand.
bool PassesImpactParameterSignificanceCuts(ReconstructedParticle *pfo)
Returns true if it passes impact parameter significance cuts.
bool IsIsolatedPolynomial(ReconstructedParticle *pfo)
bool IsIsolatedLepton(ReconstructedParticle *pfo)
Returns true if pfo is an isolated lepton.
std::map< ReconstructedParticle *, ReconstructedParticle * > _rpJetMap
IsolatedLeptonFinderProcessor aIsolatedLeptonFinderProcessor
bool _usePolynomialIsolation
If set to true, uses polynomial cuts for isolation.
bool _usePID
If set to true, uses PID cuts.
bool IsCharged(ReconstructedParticle *pfo)
Returns true if charged.
bool _useImpactParameter
If set to true, uses impact parameter cuts.
bool IsPhoton(ReconstructedParticle *pfo)
Returns true if it passes photon ID cuts.
float getConeEnergy(ReconstructedParticle *pfo)
Calculates the cone energy.
bool IsElectron(ReconstructedParticle *pfo)
Returns true if it passes electron ID cuts.
bool _useJetIsolation
If set to true, uses jet-based isolation (LAL algorithm)
bool IsMuon(ReconstructedParticle *pfo)
Returns true if it passes muon ID cuts.
std::vector< LCCollection * > LCCollectionVec
Definition: SiStripClus.h:55
std::string _outputPFOsRemovedIsoLepCollection
Output collection (all input with isolated leptons removed)
bool _useRectangularIsolation
If set to true, uses rectangular cuts for isolation.
bool _useDressedLeptons
If set to true, uses lepton dressing.
Marlin processor for finding isolated leptons.
bool isMoreEnergetic(int i, int j)
Helper function to order PFOS by energy.
std::string _inputPFOsCollection
Input collection.
bool IsIsolatedJet(ReconstructedParticle *pfo)