9 #include <marlin/AIDAProcessor.h>
10 #include <AIDA/IHistogramFactory.h>
11 #include <AIDA/ICloud1D.h>
15 #include <EVENT/LCCollection.h>
16 #include <IMPL/LCCollectionVec.h>
17 #include <EVENT/LCRelation.h>
18 #include <IMPL/LCRelationImpl.h>
19 #include <EVENT/ReconstructedParticle.h>
20 #include <IMPL/ReconstructedParticleImpl.h>
21 #include "UTIL/LCRelationNavigator.h"
22 #include <EVENT/Vertex.h>
24 #include <marlin/Global.h>
26 #include "HelixClass.h"
27 #include "SimpleLine.h"
29 #include "marlin/VerbosityLevels.h"
36 using namespace lcio ;
37 using namespace marlin ;
43 bool MyEnergySort( ReconstructedParticle *p1, ReconstructedParticle *p2)
45 return fabs(p1->getEnergy()) > fabs(p2->getEnergy());
51 _description =
"TauFinder writes tau candidates as ReconstructedParticles into collection. It runs on a collection of ReconstructedParticels, if you want to run on MCParticles you have to convert them before hand (use e.g. PrepareRECParticles processor)" ;
59 registerInputCollection( LCIO::RECONSTRUCTEDPARTICLE,
63 std::string(
"PandoraPFANewPFOs"));
65 registerOutputCollection( LCIO::RECONSTRUCTEDPARTICLE,
67 "Collection of Tau Candidates",
69 std::string(
"TauRec_PFO"));
71 registerOutputCollection( LCIO::RECONSTRUCTEDPARTICLE,
72 "TauRecRestCollection",
73 "Collection of Particles in Rest Group not in Tau Candidates",
75 std::string(
"TauRecRest_PFO"));
77 registerOutputCollection( LCIO::LCRELATION,
78 "TauRecLinkCollectionName" ,
79 "Name of the Tau link to ReconstructedParticle collection" ,
81 std::string(
"TauRecLink_PFO") ) ;
83 registerProcessorParameter(
"FileName_Signal",
84 "Name of the Signal output file " ,
86 std::string(
"Signal.root") ) ;
88 registerProcessorParameter(
"pt_cut" ,
89 "Cut on pt to suppress background" ,
92 registerProcessorParameter(
"cosT_cut" ,
93 "Cut on cosT to suppress background" ,
97 registerProcessorParameter(
"searchConeAngle" ,
98 "Opening angle of the search cone for tau jet in rad" ,
102 registerProcessorParameter(
"isolationConeAngle" ,
103 "Outer isolation cone around search cone of tau jet in rad (relativ to cone angle)" ,
107 registerProcessorParameter(
"isolationEnergy" ,
108 "Energy allowed within isolation cone region" ,
112 registerProcessorParameter(
"ptseed" ,
113 "Minimum tranverse momentum of tau seed" ,
117 registerProcessorParameter(
"invariant_mass" ,
118 "Upper limit on invariant mass of tau candidate" ,
126 streamlog_out(DEBUG) <<
" init called " << std::endl ;
133 failtuple=
new TNtuple(
"failtuple",
"failtuple",
"minv:Qtr:isoE:mergeTries:minv_neg");
156 LCCollection *colRECO;
159 colRECO = evt->getCollection(
_incol ) ;
160 }
catch (Exception&
e) {
166 relationcol->parameters().setValue(std::string(
"FromType"),LCIO::RECONSTRUCTEDPARTICLE);
167 relationcol->parameters().setValue(std::string(
"ToType"),LCIO::RECONSTRUCTEDPARTICLE);
169 _nEvt = evt->getEventNumber();
173 restcol->setSubset(1);
175 std::vector<ReconstructedParticle*> Avector;
176 std::vector<ReconstructedParticle*> Qvector;
177 std::vector<ReconstructedParticle*> Nvector;
182 int nRCP = colRECO->getNumberOfElements();
184 for (
int i = 0; i < nRCP; i++)
186 ReconstructedParticle *particle =
static_cast<ReconstructedParticle*
>( colRECO->getElementAt( i ) );
187 double pt=sqrt(particle->getMomentum()[0]*particle->getMomentum()[0]
188 +particle->getMomentum()[1]*particle->getMomentum()[1]);
189 double Cos_T = fabs(particle->getMomentum()[2]) / sqrt(pow(particle->getMomentum()[0],2)+pow(particle->getMomentum()[1],2) + pow(particle->getMomentum()[2],2));
192 Avector.push_back(particle);
193 if(particle->getCharge()==1 || particle->getCharge()==-1)
194 Qvector.push_back(particle);
196 Nvector.push_back(particle);
202 std::sort(Qvector.begin(), Qvector.end(),
MyEnergySort);
203 std::sort(Nvector.begin(), Nvector.end(),
MyEnergySort);
206 std::vector<std::vector<ReconstructedParticle*> > tauvec;
207 bool finding_done=
false;
208 while(Qvector.size() && !finding_done)
209 finding_done=
FindTau(Qvector,Nvector,tauvec);
212 std::vector<std::vector<ReconstructedParticle*> >::iterator iterT=tauvec.begin();
213 std::vector<ReconstructedParticleImpl* > tauRecvec;
215 std::vector<int> QTvec;
216 std::vector<int> NTvec;
217 for(
unsigned int p=0;p<tauvec.size();p++)
219 ReconstructedParticleImpl *taurec=
new ReconstructedParticleImpl();
222 double mom[3]={0,0,0};
225 std::vector<ReconstructedParticle*> tau=tauvec[p];
227 for(
unsigned int tp=0;tp<tau.size();tp++)
230 E+=tau[tp]->getEnergy();
231 charge+=tau[tp]->getCharge();
232 mom[0]+=tau[tp]->getMomentum()[0];
233 mom[1]+=tau[tp]->getMomentum()[1];
234 mom[2]+=tau[tp]->getMomentum()[2];
235 if(tau[tp]->getCharge())
239 taurec->addParticle(tau[tp]);
242 double pt_tau=sqrt(mom[0]*mom[0]+mom[1]*mom[1]);
243 double psquare=pt_tau*pt_tau+mom[2]*mom[2];
247 mass_inv=E-sqrt(psquare);
249 mass_inv=sqrt(E*E-psquare);
252 if(mass_inv>
_minv || mass_inv<-0.001 || chargedtracks>4 || chargedtracks==0)
258 if(chargedtracks>4 || chargedtracks==0)
262 for(
unsigned int tp=0;tp<tau.size();tp++)
263 restcol->addElement(tau[tp]);
265 iterT=tauvec.erase(iterT);
270 double phi=180./TMath::Pi()*atan(mom[1]/mom[0]);
271 double theta=180./TMath::Pi()*atan(pt_tau/fabs(mom[2]));
272 streamlog_out(DEBUG) <<
"Tau candidate failed: minv="<<mass_inv<<
" pt="<<pt_tau<<
" "<<E<<
" Q trks:"<<chargedtracks<<
" N trks:"<<neutraltracks<<
" "<<phi<<
" "<<theta<<endl;
280 for(
unsigned int tp=0;tp<tau.size();tp++) {
281 LCRelationImpl *rel =
new LCRelationImpl(taurec,tau[tp]);
282 relationcol->addElement( rel );
289 taurec->setEnergy(E);
290 taurec->setCharge(charge);
291 taurec->setMomentum(mom);
292 taurec->setType(pdg);
295 double phi=180./TMath::Pi()*atan(mom[1]/mom[0]);
296 double theta=180./TMath::Pi()*atan(pt_tau/fabs(mom[2]));
297 streamlog_out(DEBUG)<<
"Tau candidate "<<p<<
": "<<E<<
" Q trks:"<<chargedtracks<<
" N trks:"<<neutraltracks<<
" "<<phi<<
" "<<theta<<endl;
299 QTvec.push_back(chargedtracks);
300 NTvec.push_back(neutraltracks);
301 tauRecvec.push_back(taurec);
304 LCRelationNavigator *relationNavigator =
new LCRelationNavigator( relationcol );
306 if(tauRecvec.size()>1)
308 std::vector<ReconstructedParticleImpl*>::iterator iterC=tauRecvec.begin();
309 std::vector<ReconstructedParticleImpl*>::iterator iterF=tauRecvec.begin();
311 for (
unsigned int t=0; t<tauRecvec.size() ; t++ )
313 ReconstructedParticleImpl *tau=
static_cast<ReconstructedParticleImpl*
>(tauRecvec[t]);
314 const double *mom=tau->getMomentum();
315 double pt_tau=sqrt(mom[0]*mom[0]+mom[1]*mom[1]);
316 double phi=180./TMath::Pi()*atan(mom[1]/mom[0]);
317 double theta=180./TMath::Pi()*atan(pt_tau/fabs(mom[2]));
318 double angle=10000000;
320 for (
unsigned int t2=t+1; t2<tauRecvec.size() ; t2++ )
322 iterC=tauRecvec.begin()+t2;
323 ReconstructedParticleImpl *taun=
static_cast<ReconstructedParticleImpl*
>(tauRecvec[t2]);
325 const double *momn=taun->getMomentum();
326 angle=acos((mom[0]*momn[0]+mom[1]*momn[1]+mom[2]*momn[2])/
327 (sqrt(mom[0]*mom[0]+mom[1]*mom[1]+mom[2]*mom[2])*
328 sqrt(momn[0]*momn[0]+momn[1]*momn[1]+momn[2]*momn[2])));
333 double E=tau->getEnergy();
334 double En=E+taun->getEnergy();
336 double newp[3]={mom[0]+momn[0],mom[1]+momn[1],mom[2]+momn[2]};
337 tau->setMomentum(newp);
338 tau->setCharge(tau->getCharge()+taun->getCharge());
342 streamlog_out(DEBUG)<<
" Tau Merging: "<<endl;
343 streamlog_out(DEBUG)<<t<<
" "<<E<<
" "<<phi<<
" "<<theta<<endl;
344 streamlog_out(DEBUG)<<t2<<
" "<<taun->getEnergy()<<
" "<<angle<<
" -> "<<En<<
" "<<QTvec[t]+QTvec[t2]<<endl;
348 double ptn=sqrt(newp[0]*newp[0]+newp[1]*newp[1]);
349 double psquaren=ptn*ptn+newp[2]*newp[2];
352 mass_inv=En*En-psquaren;
354 mass_inv= sqrt(En*En-psquaren);
356 if(mass_inv>
_minv || mass_inv<-0.001 || QTvec[t+erasecount]+QTvec[t2+erasecount]>4)
362 if(QTvec[t+erasecount]+QTvec[t2+erasecount]>4)
366 for(
unsigned int tp=0;tp<(*iterC)->getParticles().size();tp++)
367 restcol->addElement((*iterC)->getParticles()[tp]);
368 for(
unsigned int tp=0;tp<(*iterF)->getParticles().size();tp++)
369 restcol->addElement((*iterF)->getParticles()[tp]);
372 tauRecvec.erase(iterC);
376 iterF=tauRecvec.erase(iterF);
378 if(iterF!=tauRecvec.end())
381 mom=tau->getMomentum();
382 pt_tau=sqrt(mom[0]*mom[0]+mom[1]*mom[1]);
383 phi=180./TMath::Pi()*atan(mom[1]/mom[0]);
384 theta=180./TMath::Pi()*atan(pt_tau/fabs(mom[2]));
391 std::vector< ReconstructedParticle * > mergetaus=taun->getParticles();
392 for(
unsigned int p=0;p<mergetaus.size();p++)
393 tau->addParticle(mergetaus[p]);
394 EVENT::LCObjectVec relobjFROM = relationNavigator->getRelatedToObjects(taun);
395 for(
unsigned int o=0;o<relobjFROM.size();o++)
397 ReconstructedParticle *rec=
static_cast<ReconstructedParticle*
>(relobjFROM[o]);
398 LCRelationImpl *rel =
new LCRelationImpl(tau,rec);
399 relationcol->addElement( rel );
402 tauRecvec.erase(iterC);
411 delete relationNavigator;
413 std::vector<ReconstructedParticleImpl*>::iterator iter=tauRecvec.begin();
415 for (
unsigned int t=0; t<tauRecvec.size() ; t++ )
417 ReconstructedParticleImpl *tau=
static_cast<ReconstructedParticleImpl*
>(tauRecvec[t]);
420 const double *pvec_tau=tau->getMomentum();
422 if(QTvec[t+erasecount]+NTvec[t+erasecount]>10 || QTvec[t+erasecount]>4)
426 streamlog_out(DEBUG) <<
"Tau "<<tau->getEnergy()
427 <<
": too many particles: "<<QTvec[t+erasecount]<<
" "<<NTvec[t+erasecount]<<endl;
429 for(
unsigned int tp=0;tp<(*iter)->getParticles().size();tp++)
430 restcol->addElement((*iter)->getParticles()[tp]);
432 iter=tauRecvec.erase(iter);
438 for (
unsigned int s=0;
s<Avector.size() ;
s++ )
440 ReconstructedParticle *track=
static_cast<ReconstructedParticle*
>(Avector[
s]);
441 const double *pvec=track->getMomentum();
442 double angle=acos((pvec[0]*pvec_tau[0]+pvec[1]*pvec_tau[1]+pvec[2]*pvec_tau[2])/
443 (sqrt(pvec[0]*pvec[0]+pvec[1]*pvec[1]+pvec[2]*pvec[2])*
444 sqrt(pvec_tau[0]*pvec_tau[0]+pvec_tau[1]*pvec_tau[1]+pvec_tau[2]*pvec_tau[2])));
448 E_iso+=track->getEnergy();
456 streamlog_out(DEBUG) <<
"Tau "<<tau->getEnergy()
457 <<
": Isolation Energy: "<<E_iso<<
" in "<<nparticles<<
" particles"<<endl;
459 for(
unsigned int tp=0;tp<(*iter)->getParticles().size();tp++)
460 restcol->addElement((*iter)->getParticles()[tp]);
462 iter=tauRecvec.erase(iter);
468 reccol->addElement(tau);
469 streamlog_out(DEBUG) <<
"Tau "<<tau->getEnergy()<<
" "<<QTvec[t+erasecount]<<
" "<<NTvec[t+erasecount]<<endl;
475 for(
unsigned int tp=0;tp<Qvector.size();tp++)
476 restcol->addElement(Qvector[tp]);
477 for(
unsigned int tp=0;tp<Nvector.size();tp++)
478 restcol->addElement(Nvector[tp]);
480 evt->addCollection(reccol,
_outcol);
488 bool TauFinder::FindTau(std::vector<ReconstructedParticle*> &Qvec,std::vector<ReconstructedParticle*> &Nvec,
489 std::vector<std::vector<ReconstructedParticle*> > &tauvec)
491 std::vector<ReconstructedParticle*> tau;
495 streamlog_out(DEBUG) <<
"No charged particle in event!"<<endl;
500 ReconstructedParticle *tauseed=NULL;
501 std::vector<ReconstructedParticle*>::iterator iterS=Qvec.begin();
502 for (
unsigned int s=0;
s<Qvec.size() ;
s++ )
504 tauseed=
static_cast<ReconstructedParticle*
>(Qvec[
s]);
506 for (
int icomp=0; icomp<3; ++icomp)
507 mom[icomp]=(
float)tauseed->getMomentum()[icomp];
509 double pt=sqrt(mom[0]*mom[0]+mom[1]*mom[1]);
522 streamlog_out(DEBUG) <<
"no further tau seed!"<<endl;
526 double Etau=tauseed->getEnergy();
528 tau.push_back(tauseed);
532 const double *pvec=tauseed->getMomentum();
533 double pt=sqrt(pvec[0]*pvec[0]+pvec[1]*pvec[1]);
534 double p=sqrt(pt*pt+pvec[2]*pvec[2]);
535 double phi=180./TMath::Pi()*atan(pvec[1]/pvec[0]);
536 double theta=180./TMath::Pi()*atan(pt/fabs(pvec[2]));
539 streamlog_out(DEBUG) <<
"seeding: "<<tauseed->getType()<<
"\t"<<tauseed->getEnergy()<<
"\t"<<p<<
"\t"<<theta<<
"\t"<<phi<<endl;
543 double pvec_tau[3]={0,0,0};
544 pvec_tau[0]=tauseed->getMomentum()[0];
545 pvec_tau[1]=tauseed->getMomentum()[1];
546 pvec_tau[2]=tauseed->getMomentum()[2];
549 std::vector<ReconstructedParticle*>::iterator iterQ=Qvec.begin();
550 for (
unsigned int s=0;
s<Qvec.size() ;
s++ )
552 ReconstructedParticle *track=
static_cast<ReconstructedParticle*
>(Qvec[
s]);
554 const double *pvec=track->getMomentum();
555 double angle=acos((pvec[0]*pvec_tau[0]+pvec[1]*pvec_tau[1]+pvec[2]*pvec_tau[2])/
556 (sqrt(pvec[0]*pvec[0]+pvec[1]*pvec[1]+pvec[2]*pvec[2])*
557 sqrt(pvec_tau[0]*pvec_tau[0]+pvec_tau[1]*pvec_tau[1]+pvec_tau[2]*pvec_tau[2])));
558 double pt=sqrt(pvec[0]*pvec[0]+pvec[1]*pvec[1]);
559 double p=sqrt(pt*pt+pvec[2]*pvec[2]);
560 double phi=180./TMath::Pi()*atan(pvec[1]/pvec[0]);
561 double theta=180./TMath::Pi()*atan(pt/fabs(pvec[2]));
567 tau.push_back(Qvec[
s]);
569 streamlog_out(DEBUG) <<
"Adding Q: "<<track->getType()<<
"\t"<<track->getEnergy()<<
"\t"<<p<<
"\t"<<theta<<
"\t"<<phi<<std::endl;
570 Etau+=Qvec[
s]->getEnergy();
572 for(
int i=0;i<3;i++){
573 pvec_tau[i]=pvec_tau[i]+track->getMomentum()[i];
582 std::vector<ReconstructedParticle*>::iterator iterN=Nvec.begin();
583 for (
unsigned int s=0;
s<Nvec.size() ;
s++ )
585 ReconstructedParticle *track=Nvec[
s];
587 double *pvec=(
double*)track->getMomentum();
588 double angle=acos((pvec[0]*pvec_tau[0]+pvec[1]*pvec_tau[1]+pvec[2]*pvec_tau[2])/
589 (sqrt(pvec[0]*pvec[0]+pvec[1]*pvec[1]+pvec[2]*pvec[2])*
590 sqrt(pvec_tau[0]*pvec_tau[0]+pvec_tau[1]*pvec_tau[1]+pvec_tau[2]*pvec_tau[2])));
591 double pt=sqrt(pvec[0]*pvec[0]+pvec[1]*pvec[1]);
592 double p=sqrt(pt*pt+pvec[2]*pvec[2]);
593 double phi=180./TMath::Pi()*atan(pvec[1]/pvec[0]);
594 double theta=180./TMath::Pi()*atan(pt/fabs(pvec[2]));
600 tau.push_back(Nvec[
s]);
602 streamlog_out(DEBUG) <<
"Adding N: "<<track->getType()
603 <<
"\t"<<track->getEnergy()
606 <<
"\t"<<phi<<std::endl;
608 Etau+=Nvec[
s]->getEnergy();
610 for(
int i=0;i<3;i++){
611 pvec_tau[i]=pvec_tau[i]+track->getMomentum()[i];
619 tauvec.push_back(tau);
631 streamlog_out( MESSAGE ) <<
"TauFinder::end() " << name()
632 <<
" processed " <<
_nEvt <<
" events in " <<
_nRun <<
" runs "
634 streamlog_out( MESSAGE ) <<
"Reasons for Failure: " <<std::endl;
635 streamlog_out( MESSAGE ) <<
"High invariant mass: " <<
_fail_minv<< std::endl;
636 streamlog_out( MESSAGE ) <<
"Negative invariant mass: " <<
_fail_minv_neg<< std::endl;
637 streamlog_out( MESSAGE ) <<
"No or to many tracks: " <<
_fail_Qtr<< std::endl;
638 streamlog_out( MESSAGE ) <<
"No isolation : " <<
_fail_isoE<< std::endl;
639 streamlog_out( MESSAGE ) <<
"Tried to merge : " <<
_mergeTries<< std::endl;
virtual void init()
Called at the begin of the job before anything is read.
virtual void processRunHeader(LCRunHeader *run)
Called for every run.
TauFinder processor for marlin.
virtual void processEvent(LCEvent *evt)
Called for every event - the working horse.
virtual void check(LCEvent *evt)
bool MyEnergySort(ReconstructedParticle *p1, ReconstructedParticle *p2)
std::vector< LCCollection * > LCCollectionVec
std::string _colNameTauRecLink
std::string _OutputFile_Signal
virtual void end()
Called after data processing for clean up.
bool FindTau(std::vector< ReconstructedParticle * > &Qvec, std::vector< ReconstructedParticle * > &Nvec, std::vector< std::vector< ReconstructedParticle * > > &tauvec)