2 //--------------------------------------------------------------------------
3 // AliTkChargedJetFinder.cxx
4 // implementation of a simple jet finder for charged particles
5 // based on CDF PRD 65, 092002 (2002)
6 // T. Kollegger <kollegge@ikf.physik.uni-frankfurt.de> 10/12/2002
7 //--------------------------------------------------------------------------
10 //-----------------------------------------------------------------------
14 //-----------------------------------------------------------------------
21 #include <TClonesArray.h>
22 #include <TParticle.h>
23 //--------------------------------------------------------------------------
24 #include "AliTkEtaPhiVector.h"
26 #include "TkChargedJet.h"
28 #include "AliTkConeJet.h"
29 #include "AliTkConeJetEvent.h"
30 #include "AliTkTowerV2.h"
32 //--------------------------------------------------------------------------
34 #include <AliJetParticle.h>
35 #include <AliJetEvent.h>
36 #include <AliJetEventParticles.h>
38 //-------------------------------------------------------------------------
39 #include "AliTkChargedJetFinder.h"
41 //------------------------------------------------------------------------
42 // implementation of the jet helper class
43 //------------------------------------------------------------------------
52 AliTkEtaPhiVector jet::getCentroid() const
54 return AliTkEtaPhiVector(fEta,fPhi);
57 void jet::addParticle(TParticle *particle)
59 // add a particle to the jet
60 fParticles.push_back(particle);
70 Double_t jet::getPt() const
75 // returns the pt of the jet
78 // loop over all particles which are assigned to the jet...
79 // and sum the pt of them
80 for(list<TParticle *>::const_iterator i = particles.begin();
81 i != particles.end(); ++i) {
82 TParticle *particle = *i;
90 Int_t jet::getNParticles() const
95 TParticle *jet::getParticle(Int_t i) const
97 if ((i < 0) || ((UInt_t)i > fParticles.size()-1)) {
98 cerr << "jet:: out of range" << i << endl;
101 list<TParticle *>::const_iterator iter = fParticles.begin();
102 for(Int_t pos = 0; pos < i+1; pos++) {
108 TClonesArray *jet::getParticles() const
110 TClonesArray *parts = new TClonesArray("TParticle",this->getNParticles());
112 for(list<TParticle *>::const_iterator iter = fParticles.begin();
113 iter != fParticles.end(); ++iter, i++) {
114 TParticle *particle = *iter;
115 if (particle == NULL) {
116 cerr << "jet: What's wrong? NULL pointer in particles" << endl;
119 new ((*parts)[i]) TParticle(*particle);
124 Double_t jet::getDiff(TParticle *particle) const
126 // calculate the difference between jet center and particle in eta-phi space
127 return sqrt(getDiffSq(particle));
130 Double_t jet::getDiffSq(TParticle *particle) const
132 // calculate the square of the difference between jet center
133 // and particle in eta-phi space
134 AliTkEtaPhiVector jetCenter = getCentroid();
135 AliTkEtaPhiVector particlePos(particle->Eta(),particle->Phi());
136 return jetCenter.diffSq(particlePos);
139 ostream& operator<< (ostream& s,jet& j)
141 return s << "jet: position " << j.getCentroid()
142 << " #particles=" << j.getNParticles()
143 << " pT=" << j.getPt();
147 //------------------------------------------------------------------------
148 // implementation of the jet finder class
149 //------------------------------------------------------------------------
151 ClassImp(AliTkChargedJetFinder)
153 AliTkChargedJetFinder::AliTkChargedJetFinder() : TObject()
181 #ifdef ALICEINTERFACE
188 AliTkChargedJetFinder::~AliTkChargedJetFinder()
190 if(fEvoutevent) delete fEvoutevent;
191 if(fEvoutfile) delete fEvoutfile;
192 if(fEvout_name) delete[] fEvout_name;
193 #ifdef ALICEINTERFACE
194 if(fAliParticles) delete fAliParticles;
197 if(fHistos) delete fHistos;
198 if(fHistoutFile) delete fHistoutFile;
199 if(fOutput_name) delete[] fOutput_name;
203 void AliTkChargedJetFinder::defaultSettings()
205 // default settings for a first study...
208 // lower bound of eta range
210 // high bound of eta range
218 setEvOutFilename("$JF_DATADIR/charged_jets.evout.root");
221 setHistFilename("$JF_DATADIR/charged_jets.hist.root");
225 void AliTkChargedJetFinder::init()
228 // initalization of the jet finder
229 fHistos = new TObjArray(10);
230 TH1F *hist = new TH1F("ncharged","charged tracks",31,-0.5,30.5);
231 hist->GetXaxis()->SetTitle("n_{charged} tracks");
232 hist->GetYaxis()->SetTitle("entries");
234 hist = new TH1F("jet_pt","jet p_{T}",100,0,100);
235 hist->GetXaxis()->SetTitle("p_{T} (GeV/c)");
236 hist->GetYaxis()->SetTitle("entries");
239 // declare all histograms
241 if(fOutput) cout << "Writing summary output to " << getHistFilename() << endl;
242 fHistoutfile = new TFile(getHistFilename(),"RECREATE");
248 if(fOutput) cout << "Writing event output to " << getEvOutFilename() << endl;
249 fEvoutfile = new TFile(getEvOutFilename(),"RECREATE");
250 fMyTJet = new TkChargedJet();
251 fEvouttree = new TTree("jets","");
252 fEvouttree->Branch("jet","TkChargedJet",&(this->fMyTJet));
257 fEvoutevent = new AliTkConeJetEvent();
259 if (getEvOutFilename()) {
260 if(fOutput) cout << "Writing finder output to " << getEvOutFilename() << endl;
261 fEvoutfile = new TFile(getEvOutFilename(),"RECREATE");
262 fEvouttree = new TTree("jets","TKConeJetFinderV2 jets");
263 fEvouttree->Branch("ConeFinder","AliTkConeJetEvent",&(this->fEvoutevent),32000,0);
268 void AliTkChargedJetFinder::initEvent(TClonesArray *newParticles,Int_t type)
270 // initalizes the jet finder for a new event
273 fEvoutevent->Clear();
274 fEvoutevent->setRadius(fR);
275 fEvoutevent->setEtCut(fPtSeed);
276 fEvoutevent->setPtCut(fPtCut);
277 fEvoutevent->setDesc(*new TString("AliTkChargedJetFinder"));
281 // delete old particle list and old jets
282 fParticles.erase(fParticles.begin(),fParticles.end());
283 fJets.erase(fJets.begin(),fJets.end());
286 TIterator *iter = newParticles->MakeIterator();
288 list<TParticle *>::const_iterator siter;
291 // create new particle list
294 // TParticles in TClonesArray
295 while ((particle = (TParticle *) iter->Next()) != NULL) {
296 if (isTParticleAccepted(particle)) {
297 addParticle(particle);
300 if(fOutput) cout << "found particles for jets: " << fParticles.size() << endl;
303 cerr << "AliTkChargedJetFinder: don't know how to fill Et hist from TClonesArray with type " << type << endl;
308 for (siter=particles.begin(); siter != particles.end(); ++siter) {
309 cout << "particle eta=" << (*siter)->Eta()
310 << " phi=" << (*siter)->Phi()
311 << " pT=" << (*siter)->Pt()
312 << " pointer=" << (*siter)
318 #ifdef ALICEINTERFACE
319 void AliTkChargedJetFinder::initEvent(const AliJetEventParticles *p,TString desc)
322 fEvoutevent->Clear();
323 fEvoutevent->setRadius(fR);
324 fEvoutevent->setEtCut(fPtSeed);
325 fEvoutevent->setPtCut(fPtCut);
326 fEvoutevent->setDesc(desc);
327 //fEvoutevent->setJetParticles(p);
330 // delete old particle list and old jets
331 fParticles.erase(fParticles.begin(),fParticles.end());
332 fJets.erase(fJets.begin(),fJets.end());
334 const TClonesArray *particles=p->GetParticles();
335 if(fAliParticles) fAliParticles->Clear();
336 else fAliParticles=new TClonesArray("TParticle",0);
337 fAliParticles->Expand(particles->GetEntriesFast());
339 // loop over all particles...
341 AliJetParticle *aliparticle = NULL;
342 TIterator *iter = particles->MakeIterator();
343 while ((aliparticle = (AliJetParticle *) iter->Next()) != NULL) {
344 Float_t pt=aliparticle->Pt();
345 if(pt<fPtCut) continue;
346 // particle is accepted through reader in JETAN
347 TParticle *particle = new((*fAliParticles)[i]) TParticle(0,0,0,0,0,0,aliparticle->Px(),aliparticle->Py(),
348 aliparticle->Pz(),aliparticle->Energy(),0,0,0,0);
349 //mark particle (-123 for Pythia)
350 particle->SetWeight(aliparticle->GetType());
351 //particle is accepted through reader
352 addParticle(particle);
359 void AliTkChargedJetFinder::run()
361 // loop over particles as long as there are
362 // some which are not assigned to a jet
363 if (fParticles.empty()) {
367 list<TParticle *>::iterator iter;
368 while (!fParticles.empty()) {
369 // get particle with highest pT...
370 iter = fParticles.begin();
371 if((*iter)->Pt()<fPtSeed) {
372 fParticles.erase(iter);
375 // create a new jet...
377 // and add the particle with highest pT...
378 myJet.addParticle(*iter);
379 // delete it from the list of unassigned particles...
380 fParticles.erase(iter);
381 // loop over all particles to see if they are within the new jet...
382 for(iter = fParticles.begin(); iter != fParticles.end(); ++iter) {
383 if (myJet.getDiffSq(*iter) < fRSq) {
384 // add this particle to the jet...
385 myJet.addParticle(*iter);
386 // remove this particle from the list of unassigned ones...
387 fParticles.erase(iter);
388 // and start again from the beginnig of the list
389 // -- the pT-weigthed center of the jet might have changed,
390 // so one might add now a particle which was before rejected
391 iter = fParticles.begin();
395 // we have our final jet - add it to the jet list...
396 fJets.push_back(myJet);
400 void AliTkChargedJetFinder::finishEvent()
406 list<jet>::iterator highjet = findHighestJet();
407 if (highjet == NULL) {
408 cerr << "AliTkChargedJetFinder:: no jet found - no output! " << endl;
412 cout << "high jet ncharged=" << (*highjet).getNParticles()
413 << " pt=" << (*highjet).getPt() << endl;
414 cout << *highjet << endl;
418 // write out event histograms
419 if ((*highjet).getPt() > 30) {
420 ((TH1F *)fHistos->At(0))->Fill((*highjet).getNParticles());
422 ((TH1F *)fHistos->At(1))->Fill((*highjet).getPt());
425 TkChargedJet *jet = new TkChargedJet(*highjet);
426 if ((fEvoutfile) && (fEvoutfile->IsOpen())) {
431 fMyTJet = new TkChargedJet();
436 #else /******************************************************/
438 AliTkConeJet *conejet = new AliTkConeJet();
439 AliTkTowerV2 *myTower = new AliTkTowerV2();
440 list<jet>::iterator iter;
441 for (iter = fJets.begin();
442 iter != fJets.end(); ++iter) {
444 Float_t jetet=(*iter).getPt();
445 if(jetet<fMinJetPt) continue;
447 conejet->setEta((*iter).Eta());
448 conejet->setPhi((*iter).Phi());
449 conejet->setEt(jetet);
452 myTower->setEta((*iter).Eta());
453 myTower->setPhi((*iter).Phi());
454 myTower->setEt(jetet);
455 myTower->setParticleList((*iter).getParticles());
456 conejet->addTower(myTower);
457 conejet->calculateValues();
458 fEvoutevent->addJet(conejet);
460 fEvoutevent->sortJets();
461 fEvoutevent->Print("");
470 void AliTkChargedJetFinder::finish()
473 // write out histograms
474 if ((fHistoutfile) && (fHistoutfile->IsOpen())) {
476 ((TH1F *)fHistos->At(0))->Write();
477 ((TH1F *)fHistos->At(1))->Write();
478 fHistoutfile->Write();
479 fHistoutfile->Close();
482 if ((fEvoutfile) && (fEvoutfile->IsOpen())) {
486 ((TH1F *)fHistos->At(0))->Write();
493 void AliTkChargedJetFinder::setEvOutFilename(const Char_t *filename)
496 fEvout_name = new Char_t[4096];
498 strcpy(fEvout_name,filename);
502 void AliTkChargedJetFinder::setHistFilename(const Char_t *filename)
505 fOutput_name = new Char_t[4096];
507 strcpy(fOutput_name,filename);
511 bool AliTkChargedJetFinder::isTParticleAccepted(TParticle *particle)
515 // check if particle is stable
516 if (particle->GetStatusCode() != 1) return false;
519 TParticlePDG *partPDG;
520 partPDG = particle->GetPDG();
521 if (partPDG->Charge() == 0) {
526 if ((particle->Eta() < fEtaMin) || (particle->Eta() > fEtaMax)) {
533 void AliTkChargedJetFinder::addParticle(TParticle *particle)
535 // add particle at right position
536 // first point to speed up program, use a sorted tree for example...
538 // if first particle, store at beginning
539 if (fParticles.empty()) {
540 fParticles.push_front(particle);
544 // search insert position
545 list<TParticle *>::iterator iter;
546 for (iter = fParticles.begin(); iter != fParticles.end(); ++iter) {
547 if ((*iter)->Pt() < particle->Pt()) {
548 fParticles.insert(iter,particle);
554 list<jet>::iterator AliTkChargedJetFinder::findHighestJet()
556 list<jet>::iterator iter;
557 list<jet>::iterator high;
560 return fJets.begin();
563 high = fJets.begin();
564 for (iter = fJets.begin(); iter != fJets.end(); ++iter) {
565 //cout << *iter << endl;
566 if ((*iter).getPt() > (*high).getPt()) {
573 void AliTkChargedJetFinder::checkJets()
575 list<jet>::iterator i;
576 list<jet>::iterator j;
577 for (i = fJets.begin(); i != fJets.end(); ++i) {
578 for (j = i, ++j; j != fJets.end(); ++j) {
579 AliTkEtaPhiVector v1 = (*i).getCentroid();
580 AliTkEtaPhiVector v2 = (*j).getCentroid();
581 Double_t diff = v1.diff(v2);
583 cerr << "AliTkChargedJetFinder: Something is wrong - jets to close..." << endl;
584 cerr << v1 << " pt=" << (*i).getPt() << " -- "
585 << v2 << " pt=" << (*j).getPt() << endl;