]> git.uio.no Git - u/mrichter/AliRoot.git/blame - JETAN/jetan2004/AliTkConeJetFinderV2.cxx
Replaced by JETANLinkDef.h
[u/mrichter/AliRoot.git] / JETAN / jetan2004 / AliTkConeJetFinderV2.cxx
CommitLineData
b9a6a391 1// $Id$
2
3#include <Riostream.h>
4#include <vector>
5#include <list>
6#include <map>
7
8#include <TROOT.h>
9#include <TClonesArray.h>
10#include <TParticle.h>
11#include <TH2.h>
12#include <TCanvas.h>
13#include <TFile.h>
14#include <TTree.h>
15#include <TString.h>
16
17#include "AliTkConeJet.h"
18#include "AliTkTowerV2.h"
19#include "AliTkConeJetEvent.h"
20#include "AliTkConeJetFinderV2.h"
21
22#ifdef ALICEINTERFACE
23#include <AliJetParticle.h>
24#include <AliJetEvent.h>
25#include <AliJetEventParticles.h>
26#endif
27
28//numerical precision
29#define __epsilon__ 1e-6
30
31//==== Implementation of tower =====
32tower::tower() : fEta_min(-999),fEta_max(-999),fEta_center(-999),
33 fPhi_min(-999),fPhi_max(-999),fPhi_center(-999),
34 fEt(0), fParticles(0)
35{
36}
37
38tower::tower(const tower& t)
39{
40 fEta_min = t.getEtaMin();
41 fEta_max = t.getEtaMax();
42 fEta_center = t.getEta();
43 fPhi_min = t.getPhiMin();
44 fPhi_max = t.getPhiMax();
45 fPhi_center = t.getPhi();
46 fEt = t.getEt();
47}
48
49tower::tower(Float_t phimin, Float_t phimax, Float_t etamin, Float_t etamax)
50{
51 fEta_min = etamin;
52 fEta_max = etamax;
53 fEta_center = (etamax+etamin)/2.;
54 fPhi_min = phimin;
55 fPhi_max = phimax;
56 fPhi_center = (phimax+phimin)/2.;
57 fEt = 0;
58}
59
60tower::~tower()
61{
62 clearParticles();
63}
64
83a9e4e6 65tower& tower::operator+=(const Float_t E)
b9a6a391 66{
67 fEt += E;
68 return *this;
69}
70
83a9e4e6 71tower& tower::operator+=(const TParticle *part)
b9a6a391 72{
73 fEt += part->Pt(); // Et for a massless particle...
74 addParticle(part);
75 return *this;
76}
77
78ostream& operator<<(ostream& s,const tower& t)
79{
80 return s << "tower info: etamin=" << t.getEtaMin()
81 << " etamax=" << t.getEtaMax()
82 << " phimin=" << t.getPhiMin()
83 << " phimax=" << t.getPhiMax()
84 << " Et=" << t.getEt();
85}
86
83a9e4e6 87list<const TParticle*> *tower::getParticles()
b9a6a391 88{
89 list<const TParticle*> *newList = new list<const TParticle*>;
90 list<const TParticle*> &myList = *newList;
91 copy(fParticles.begin(),fParticles.end(),back_inserter(myList));
92 return newList;
93}
94
95//==== Implementation of protojet =====
96protojet:: protojet() : fCentroid(-999,-999),
97 fEtWeightedCentroid(-999,-999),
98 fEt(-999),fUpdate(kFALSE),fTowers(0)
99{
100}
101
102protojet::protojet(const protojet& p) :
103 fCentroid(-999,-999),
104 fEtWeightedCentroid(-999,-999),
105 fEt(-999),fUpdate(kFALSE),fTowers(0)
106{
107 setCentroidPosition(p.getCentroidPosition());
108}
109
110protojet::protojet(const protojet *p) :
111 fCentroid(-999,-999),
112 fEtWeightedCentroid(-999,-999),
113 fEt(-999),fUpdate(kFALSE),fTowers(0)
114{
115 setCentroidPosition(p->getCentroidPosition());
116}
117
118bool protojet::operator==(const protojet &p1)
119{
120 AliTkEtaPhiVector otherCenter = p1.getCentroidPosition();
121 if (fCentroid.diffSq(otherCenter) > __epsilon__)
122 return false;
123
124 if ((getEt() - p1.getEt())*(getEt() - p1.getEt()) > __epsilon__)
125 return false;
126
127 return true;
128}
129
130void protojet::update()
131{
132 Float_t Et = 0;
133 Float_t phi = 0;
134 Float_t eta = 0;
135
136 for (list<tower*>::const_iterator iter = fTowers.begin();
137 iter != fTowers.end(); ++iter) {
138 Et += (*iter)->getEt();
139 phi += (*iter)->getEt() * (*iter)->getPhi();
140 eta += (*iter)->getEt() * (*iter)->getEta();
141 }
142 if (Et != 0) {
143 phi /= Et;
144 eta /= Et;
145 }
146 fEtWeightedCentroid.setVector(eta,phi);
147 fEt=Et;
148 fUpdate=kFALSE;
149}
150
83a9e4e6 151list<tower*> protojet::getTowerList() const
b9a6a391 152{
153 list<tower*> newList;
154 copy(fTowers.begin(),fTowers.end(),back_inserter(newList));
155 return newList;
156}
157
83a9e4e6 158list<tower*> protojet::getSharedTowerList(const protojet *other) const
b9a6a391 159{
160 list<tower*> newList;
161 for (list<tower*>::const_iterator i = fTowers.begin();
162 i != fTowers.end(); ++i) {
163 if (other->hasTower((*i))) {
164 newList.push_back((*i));
165 }
166 }
167 return newList;
168}
169
83a9e4e6 170bool protojet::hasTower(tower *pTower) const
b9a6a391 171{
172 bool bHasTower = false;
173 for (list<tower*>::const_iterator iter = fTowers.begin();
174 iter != fTowers.end(); ++iter) {
175 if (pTower == (*iter)) {
176 bHasTower = true;
177 break;
178 }
179 }
180 return bHasTower;
181}
182
83a9e4e6 183bool protojet::shareTowers(const protojet *other) const
b9a6a391 184{
185 bool bShareTowers = false;
186 for (list<tower*>::const_iterator iter = fTowers.begin();
187 iter != fTowers.end(); ++iter) {
188 if (other->hasTower(*iter)) {
189 bShareTowers = true;
190 break;
191 }
192 }
193 return bShareTowers;
194}
195
83a9e4e6 196Float_t protojet::diffToCenter(tower *pTower) const
b9a6a391 197{
198 AliTkEtaPhiVector v(pTower->getEta(),pTower->getPhi());
199 AliTkEtaPhiVector center = getCentroidPosition();
200
201 return v.diff(center);
202}
203
204ostream& operator<<(ostream& s,const protojet& p)
205{
206 return s << "Protojet info: eta=" << p.Eta()
207 << " phi=" << p.Phi() << " Et=" << p.getEt();
208}
209
210
211//================== implementation of AliTkConeJetFinderV2 ==============
212ClassImp(AliTkConeJetFinderV2)
213
214AliTkConeJetFinderV2::AliTkConeJetFinderV2()
215 : TObject(),
216 fOutput(0),fNTowers(0),fEtaBins(0),fEtaMin(0),
217 fEtaMax(0),fEtaWidth(0),fPhiBins(0),fPhiMin(0),fPhiMax(0),
218 fPhiWidth(0),fEtCut(0),fEtMinJet(0),fPtCut(0),fRadius(0),fTowers(0),
219 fSeedPointsNew(),fProtojets(),fJets(0),
220 fEvoutfile(0),fEvout_name(0),fEvoutevent(0),fEvouttree(0)
221#ifdef ALICEINTERFACE
222 ,fAliParticles(0)
223#endif
224
225#ifdef DOHISTOS
226 ,fHistos(),fEventHistos(),fHistFile(0)
227#endif
228{
229 defaultSettings();
230}
231
232
233AliTkConeJetFinderV2::~AliTkConeJetFinderV2()
234{
235 if(fEvoutevent) delete fEvoutevent;
236 if(fEvoutfile) delete fEvoutfile;
237 if(fEvout_name) delete[] fEvout_name;
238#ifdef ALICEINTERFACE
239 if(fAliParticles) delete fAliParticles;
240#endif
241
242#ifdef DOHISTOS
243 if(fHistFile) delete fHistFile;
244#endif
245}
246
247void AliTkConeJetFinderV2::defaultSettings()
248{
249 fOutput = kFALSE;
250 fRadius = 0.7;
251 // some more or less usefull default settings
252 // only possibilty to control the jet finder without setters/getters
253 fPhiBins = (Int_t) (2 * TMath::Pi() / 0.1);
254 fPhiMin = 0;
255 fPhiMax = 2 * TMath::Pi();
256 fEtaBins = 20;
257 fEtaMin = -1;
258 fEtaMax = 1;
259 fEtCut = 0;
260 fPtCut = 0;
261 fEtMinJet = 0;
262 fNTowers = fPhiBins*fEtaBins;
263}
264
265void AliTkConeJetFinderV2::setSettings(Int_t phibins,Int_t etabins)
266{
267 fPhiBins = phibins;
268 fPhiMin = 0;
269 fPhiMax = 2 * TMath::Pi();
270 fEtaBins = etabins;
271 fEtaMin = -1;
272 fEtaMax = 1;
273 fNTowers = fPhiBins*fEtaBins;
274}
275
276void AliTkConeJetFinderV2::init()
277{
278 createTowers();
279
280 fEvoutevent = new AliTkConeJetEvent();
281 fEvoutfile = 0;
282 fEvouttree = 0;
283
284#ifdef DOHISTOS
285 createHistos();
286 createEventHistos();
287#endif
288
289 if (getEvOutFilename()) {
290 if(fOutput)cout << "Writing finder output to " << getEvOutFilename() << endl;
291 fEvoutfile = new TFile(getEvOutFilename(),"RECREATE");
292 fEvouttree = new TTree("jets","TKConeJetFinderV2 jets");
293 fEvouttree->Branch("ConeFinder","AliTkConeJetEvent",&(this->fEvoutevent),32000,0);
294 }
295}
296
297#ifdef ALICEINTERFACE
298void AliTkConeJetFinderV2::initEvent(const AliJetEventParticles *p,TString desc)
299{
300 if(fEvoutevent){
301 fEvoutevent->Clear();
302 fEvoutevent->setDesc(desc);
303 //fEvoutevent->setJetParticles(p);
304 fEvoutevent->setJetParticles(0);
305 }
306 const TClonesArray *parts=p->GetParticles();
307 initEvent_(parts,2);
308}
309#endif
310
311void AliTkConeJetFinderV2::initEvent(const TClonesArray *particles,Int_t type,TString desc)
312{
313 if(fEvoutevent){
314 fEvoutevent->Clear();
315 fEvoutevent->setDesc(desc);
316 }
317 initEvent_(particles,type);
318}
319
320void AliTkConeJetFinderV2::initEvent(const TClonesArray *particles,Int_t type)
321{
322#ifdef DOHISTOS
323 // clear event histograms for new event
324 clearEventHistos();
325#endif
326
327 if(fEvoutevent){
328 fEvoutevent->Clear();
329 }
330
331 initEvent_(particles,type);
332}
333
334
335void AliTkConeJetFinderV2::initEvent_(const TClonesArray *particles,Int_t type)
336{
337 fEvoutevent->setRadius(fRadius);
338 fEvoutevent->setEtCut(fEtCut);
339 fEvoutevent->setPtCut(fPtCut);
340
341 // reset all towers
342 for (vector<tower>::iterator i = fTowers->begin(); i != fTowers->end();++i) {
343 (*i).clear();
344 }
345 // reset seed points
346 fSeedPointsNew.erase(fSeedPointsNew.begin(),fSeedPointsNew.end());
347 // reset protojet list
348 for (list<protojet*>::iterator i = fProtojets.begin();i != fProtojets.end(); ++i) {
349 protojet *p = (*i);
350 if (p) {
351 delete p;
352 }
353 }
354 fProtojets.erase(fProtojets.begin(),fProtojets.end());
355
356 // reset jet list
357 for (list<protojet*>::iterator i = fJets.begin();
358 i != fJets.end(); ++i) {
359 protojet *p = (*i);
360 if (p) {
361 delete p;
362 }
363 }
364 fJets.erase(fJets.begin(),fJets.end());
365
366 // fill Et towers from particles
367 switch (type) {
368 case 1:
369 fillTowersFromTParticles(particles);
370 break;
371#ifdef ALICEINTERFACE
372 case 2:
373 fillTowersFromAliParticles(particles);
374 break;
375#endif
376 default:
377 cerr << "AliTkConeJetFinderV2: don't know how to fill Et hist from TClonesArray with type " << type << endl;
378 }
379 createSeedPoints();
380
381#ifdef DOHISTOS
382 fillTowerHist();
383#endif
384}
385
386Bool_t AliTkConeJetFinderV2::isJetEnergy(Float_t min, Float_t max)
387{ // Checks if there was an jet with Et between min and max
388 Float_t men=maxJetEnergy();
389
390 if((men>min)&&(men<max)) return kTRUE;
391 return kFALSE;
392}
393
394Float_t AliTkConeJetFinderV2::maxJetEnergy()
395{
396 Float_t men=-1;
397 for (list<protojet*>::const_iterator iter = fJets.begin();
398 iter != fJets.end(); ++iter) {
399
400 Float_t et=(*iter)->getEt();
401 if(men<et) men=et;
402 }
403 return men;
404}
405
406void AliTkConeJetFinderV2::run()
407{
408 findProtojets();
409 findJets();
410}
411
412void AliTkConeJetFinderV2::finishEvent()
413{
414 if (fEvoutevent){
415 AliTkConeJet *jet = new AliTkConeJet();
416 AliTkTowerV2 *myTower = new AliTkTowerV2();
417 for (list<protojet*>::const_iterator iter = fJets.begin();
418 iter != fJets.end(); ++iter) {
419
420 Float_t jetet=(*iter)->getEt();
421 if(jetet<fEtMinJet) continue;
422 jet->Clear();
423 jet->setEta((*iter)->Eta());
424 jet->setPhi((*iter)->Phi());
425 jet->setEt(jetet);
426
427 list<tower*> jettowers = (*iter)->getTowerList();
428 for (list<tower*>::const_iterator twiter = jettowers.begin();
429 twiter != jettowers.end(); ++twiter) {
430 myTower->Clear();
431 myTower->setEta((*twiter)->getEta());
432 myTower->setPhi((*twiter)->getPhi());
433 myTower->setEt((*twiter)->getEt());
434 list<const TParticle*> &twparts = *((*twiter)->getParticles());
435 for (list<const TParticle*>::const_iterator partiter = twparts.begin();
436 partiter != twparts.end(); ++partiter) {
437 myTower->addParticle(*partiter);
438 }
439 delete &twparts;
440 jet->addTower(myTower);
441 }
442 jet->calculateValues();
443 fEvoutevent->addJet(jet);
444 }
445 fEvoutevent->sortJets();
446
447 if (fEvouttree)
448 fEvouttree->Fill();
449 delete jet;
450 delete myTower;
451 }
452#ifdef DOHISTOS
453 writeEventHistos();
454#endif
455}
456
457void AliTkConeJetFinderV2::finish()
458{
459 if ((fEvoutfile) && (fEvoutfile->IsOpen())) {
460 fEvoutfile->cd();
461 fEvouttree->Write();
462 fEvoutfile->Close();
463 }
464
465#ifdef DOHISTOS
466 writeHistos();
467 fHistFile->Close();
468#endif
469}
470
471void AliTkConeJetFinderV2::createTowers()
472{
473 if(fOutput) cout << "Creating " << fNTowers << " tower" << endl;
474 if (fPhiMax > fPhiMin) {
475 fPhiWidth = (fPhiMax-fPhiMin)/(Float_t)fPhiBins;
476 } else {
477 fPhiWidth = (fPhiMin-fPhiMax)/(Float_t)fPhiBins;
478 }
479 if (fEtaMax > fEtaMin) {
480 fEtaWidth = (fEtaMax-fEtaMin)/(Float_t)fEtaBins;
481 } else {
482 fEtaWidth = (fEtaMin-fEtaMax)/(Float_t)fEtaBins;
483 }
484 if(fOutput) cout << "Delta(eta)=" << fEtaWidth << " Delta(phi)=" << fPhiWidth << endl;
485
486 // let's create the container
487 fTowers = new vector<tower>(fNTowers);
488
489 // set tower boundaries...
490 Float_t eta = fEtaMin;
491 Float_t phi = fPhiMin;
492 for (Int_t e = 0; e < fEtaBins; e++) {
493 for (Int_t p = 0; p < fPhiBins; p++) {
494 Int_t tower = e*fPhiBins + p;
495 (*fTowers)[tower].setPhiMin(phi);
496 (*fTowers)[tower].setPhiMax(phi + fPhiWidth);
497 (*fTowers)[tower].setPhi(phi + fPhiWidth/2.);
498 (*fTowers)[tower].setEtaMin(eta);
499 (*fTowers)[tower].setEtaMax(eta + fEtaWidth);
500 (*fTowers)[tower].setEta(eta + fEtaWidth/2.);
501
502 phi += fPhiWidth;
503 }
504 eta += fEtaWidth;
505 phi = fPhiMin;
506 }
507}
508
509void AliTkConeJetFinderV2::fillTowersFromTParticles(const TClonesArray *particles)
510{
511 // input TClonesArray with TParticles, e.g. from PYTHIA
512 // fills the Et grid from these particles
513 if (!particles) {
514 return;
515 }
516
517 // loop over all particles...
518 TParticle *particle = NULL;
519 TIterator *iter = particles->MakeIterator();
520 while ((particle = (TParticle *) iter->Next()) != NULL) {
521 // check if particle is accepted
522 if (1) { //isTParticleAccepted(particle)) {
523 Float_t pt=particle->Pt();
524 if(pt<fPtCut) continue;
525 Int_t tower = findTower(particle->Phi(),particle->Eta());
526 if (tower >= 0) {
527 (*fTowers)[tower] += particle;
528#ifdef DOHISTOS
529 // calculate Et for a massless particle...
530 // idea for Et check: Et = E *sin(theta);
531 Float_t Et = TMath::Sqrt(pt*pt);
532 // just as check - fill particle Et in histogram
533 ((TH2F *)fEventHistos.At(1))->Fill(particle->Eta(),particle->Phi(),Et);
534#endif
535 }
536 }
537 }
538 delete iter;
539}
540
541#ifdef ALICEINTERFACE
542void AliTkConeJetFinderV2::fillTowersFromAliParticles(const TClonesArray *particles)
543{
544 // input TClonesArray with AliParticles
545 // fills the Et grid from these particles
546 if (!particles) {
547 return;
548 }
549
550 if(fAliParticles) fAliParticles->Clear();
551 else fAliParticles=new TClonesArray("TParticle",0);
552 fAliParticles->Expand(particles->GetEntriesFast());
553
554 // loop over all particles...
555 AliJetParticle *aliparticle = NULL;
556 TIterator *iter = particles->MakeIterator();
557
558 Int_t i=0;
559 //Float_t meanet=0,totet=0;
560 while ((aliparticle = (AliJetParticle *) iter->Next()) != NULL) {
561 Float_t pt=aliparticle->Pt();
562 if(pt<fPtCut) continue;
563 // particle is accepted through reader in JETAN
564 TParticle *particle = new((*fAliParticles)[i]) TParticle(0,0,0,0,0,0,aliparticle->Px(),aliparticle->Py(),
565 aliparticle->Pz(),aliparticle->Energy(),0,0,0,0);
566 //mark particle (-123 for Pythia)
567 particle->SetWeight(aliparticle->GetType());
568 Int_t tower = findTower(particle->Phi(),particle->Eta());
569 if (tower >= 0) {
570 (*fTowers)[tower] += particle;
571 //meanet+=pt;totet+=pt;
572#ifdef DOHISTOS
573 // calculate Et for a massless particle...
574 // idea for Et check: Et = E *sin(theta);
575 Float_t Et = TMath::Sqrt(particle->Pt()*particle->Pt());
576 // just as check - fill particle Et in histogram
577 ((TH2F *)fEventHistos.At(1))->Fill(particle->Eta(),particle->Phi(),Et);
578#endif
579 }
580 i++;
581 }
582 delete iter;
583 //cout << "Mean particle " << meanet/i << " " << totet << endl;
584}
585
586#endif
587
83a9e4e6 588Int_t AliTkConeJetFinderV2::findTower(Float_t phi,Float_t eta)
b9a6a391 589{
590 if ((phi < fPhiMin) || (phi > fPhiMax) ||
591 (eta < fEtaMin) || (eta > fEtaMax)) {
592 return -1;
593 }
594 Int_t phibins = (Int_t) ((phi - fPhiMin) / fPhiWidth);
595 Int_t etabins = (Int_t) ((eta - fEtaMin) / fEtaWidth);
596 return (etabins * fPhiBins + phibins);
597}
598
599void AliTkConeJetFinderV2::createSeedPoints()
600{
601 // function should decide if it makes sense
602 // to use fEtCut for seed towers
603 // + midpoints or simply tower list
604 // uses only tower list so far...
605
606#if 0
607 Float_t met=0.;Float_t set=0.;
608 Int_t counter=0;
609 for(vector<tower>::iterator iter = fTowers->begin();
610 iter != fTowers->end(); ++iter) {
611 met+=iter->getEt();
612 set+=iter->getEt()*iter->getEt();
613 counter++;
614 }
615 if(counter>1){
616 met/=counter;
617 set=set/counter-met*met;
618 if(set>0) set=TMath::Sqrt(set)/(counter-1);
619 else set=0;
620 if(fOutput) cout << "Tower Mean Et: " << met << "+-" << set << " " << counter << endl;
621 }
622 Float_t meanEt=met-set; //store mean tower et
623
624 for(vector<tower>::iterator pos = fTowers->begin();
625 pos != fTowers->end(); ++pos) {
626 if(pos->getEt()<meanEt){
627 pos->clear();
628 }
629 }
630#endif
631
632 for(vector<tower>::iterator iter = fTowers->begin();
633 iter != fTowers->end(); ++iter) {
634 if(iter->getEt()>fEtCut){
635 AliTkEtaPhiVector seedPoint((*iter).getEta(),(*iter).getPhi());
636 fSeedPointsNew.push_back(seedPoint);
637 }
638 }
639 if(fOutput) cout << "created " << fSeedPointsNew.size() << " seed points" << endl;
640}
641
642void AliTkConeJetFinderV2::findProtojets()
643{
644 const Float_t radiusSq = fRadius*fRadius;
645 const Int_t maxIterations = 100;
646 const Bool_t geoCut = kTRUE;
647 const Float_t geoCutRadiusSq = 2*(fPhiWidth*fPhiWidth + fEtaWidth*fEtaWidth);
648
649 // loop over all seedpoints
650 for(list<AliTkEtaPhiVector>::iterator iter = fSeedPointsNew.begin();
651 iter != fSeedPointsNew.end(); ++iter) {
652 // create a new protojet at seedpoint position
653 protojet *pj = new protojet();
654 pj->setCentroidPosition(*iter);
655 // loop over all towers and add all within "radius" to the protojet...
656 for (vector<tower>::iterator tower = fTowers->begin();
657 tower != fTowers->end(); ++tower) {
658 if(tower->getEt()<=0) continue;
659 AliTkEtaPhiVector TwCenter((*tower).getEta(),(*tower).getPhi());
660 AliTkEtaPhiVector protojetCenter(pj->getCentroidPosition());
661 if (TwCenter.diffSq(protojetCenter) < radiusSq) {
662 pj->addTower(&(*tower));
663 }
664 }
665 //update mean values
666 pj->update();
667 // have added all towers within "radius" to protojet...
668 // iterate seedpoint until stable
669 // lets get the pT-weigthed center of the protojet...
670 AliTkEtaPhiVector centerGeo = pj->getCentroidPosition();
671 AliTkEtaPhiVector centerEt = pj->getEtWeightedPosition();
672 Int_t iteration = 0;
673 Bool_t wasGeoCut = kFALSE;
674 while ((centerGeo.diffSq(centerEt) > __epsilon__) &&
675 (iteration < maxIterations)) {
676 iteration++;
677 pj->eraseTowers();
678 pj->setCentroidPosition(centerEt);
679 centerGeo = pj->getCentroidPosition();
680
681 // if geoCut == kTRUE, break if it leaves original bin...
682 if ((geoCut == kTRUE) &&
683 ((*iter).diffSq(centerGeo) > geoCutRadiusSq)) {
684 wasGeoCut = kTRUE;
685 break;
686 }
687 // loop over all towers and add all within "radius" to the protojet...
688 for (vector<tower>::iterator tower = fTowers->begin();
689 tower != fTowers->end(); ++tower) {
690 if(tower->getEt()<=0) continue;
691 AliTkEtaPhiVector TwCenter((*tower).getEta(),(*tower).getPhi());
692 if (TwCenter.diffSq(centerEt) < radiusSq) {
693 pj->addTower(&(*tower));
694 }
695 }
696 // have added all towers within "radius" to protojet...
697 centerEt = pj->getEtWeightedPosition();
698 }
699
700 // we have a stable protojet (or run out of iterations...)
701#if 0
702 if((fOutput) &&(iteration==maxIterations))
703 cout << " FindProtojets warning: max iterations of "
704 << maxIterations << " reached !!!" << endl;
705#endif
706 // let's add it to the protojet list...
707 if (!wasGeoCut) {
708 addProtojet(pj);
709 } else {
710 delete pj;
711 }
712 }
713 //if(fOutput) cout << "found " << fProtojets.size() << "proto jets" << endl;
714}
715
716void AliTkConeJetFinderV2::addProtojet(protojet *pj)
717{
718 if (!pj) {
719 return;
720 }
721 for(list<protojet*>::const_iterator iter = fProtojets.begin();
722 iter != fProtojets.end(); ++iter) {
723 if ((*pj) == (*(*iter))) {
724 delete pj;
725 return;
726 }
727 }
728 fProtojets.push_back(pj);
729}
730
731void AliTkConeJetFinderV2::dumpProtojets(Float_t etmin)
732{
733 for(list<protojet*>::const_iterator iter = fProtojets.begin();
734 iter != fProtojets.end(); ++iter) {
735 if ((*iter)->getEt() > etmin) {
736 cout << (*(*iter)) << endl;
737 }
738 }
739}
740
741void AliTkConeJetFinderV2::findJets()
742{
743 // loop over all protojets until list is empty
744 while(!fProtojets.empty()) {
745 // find the protojet with maximum Et
746 // should be easy to have a sorted list...
83a9e4e6 747 list<protojet*>::iterator maxEtProtojet = fProtojets.begin();
b9a6a391 748 Float_t maxEt = 0;
749 for (list<protojet*>::iterator iter = fProtojets.begin();
750 iter != fProtojets.end(); ++iter) {
751 if ((*iter)->getEt() > maxEt) {
752 maxEt = (*iter)->getEt();
753 maxEtProtojet = iter;
754 }
755 }
756 // we've found the protojet with the highest Et - remove it from the list
757 protojet *jet1 = *maxEtProtojet;
758 fProtojets.erase(maxEtProtojet);
759 // loop again over all protojets to find sharing jet with highest Et
83a9e4e6 760 list<protojet*>::iterator maxEtNeighbor = fProtojets.begin();
b9a6a391 761 maxEt = 0;
762 for (list<protojet*>::iterator iter = fProtojets.begin();
763 iter != fProtojets.end(); ++iter) {
764 if (((*iter)->getEt() > maxEt) &&
765 (jet1->shareTowers(*iter))) {
766 maxEt = (*iter)->getEt();
767 maxEtNeighbor = iter;
768 }
769 }
83a9e4e6 770 if (maxEt>0) {
b9a6a391 771 // jet's share towers
772 // merging splitting step...
773 protojet *jet2 = (*maxEtNeighbor);
774 fProtojets.erase(maxEtNeighbor);
775 splitMergeJets(jet1,jet2);
776 } else {
777 // protojet 1 doesn't share towers with other protojets, make it a jet...
778 addJet(jet1);
779 }
780 }
781 if(fOutput){
782 cout << "found " << fJets.size() << " jets" << endl;
783 dumpJets();
784 }
785}
786
787void AliTkConeJetFinderV2::splitMergeJets(protojet *jet1,protojet *jet2)
788{
789 const Float_t EtRatioCut = 0.5;
790
791 // let's calcualte the shared energy...
792 Float_t fEtShared = 0.0;
793 list<tower*> sharedTowers = jet1->getSharedTowerList(jet2);
794 for (list<tower*>::const_iterator iter = sharedTowers.begin();
795 iter != sharedTowers.end(); ++iter) {
796 fEtShared += (*iter)->getEt();
797 }
798 Float_t fEtJet2 = jet2->getEt();
799 // calculate the ratio of the shared energy and decided if split or merge
800 Float_t fEtRatio = EtRatioCut + 1.;
801 if(fEtJet2) fEtRatio = fEtShared / fEtJet2;
802 if (fEtRatio > EtRatioCut) {
803 mergeJets(jet1,jet2);
804 } else {
805 splitJets(jet1,jet2);
806 }
807}
808
809void AliTkConeJetFinderV2::mergeJets(protojet *jet1,protojet *jet2) {
810 // merge protojets...
811 list<tower*> jet2Towers = jet2->getTowerList();
812 for (list<tower*>::const_iterator iter = jet2Towers.begin();
813 iter != jet2Towers.end(); ++iter) {
814 // add towers from protojet2 to protojet1...
815 // don't add shared towers...
816 if (!jet1->hasTower((*iter))) {
817 jet1->addTower((*iter));
818 }
819 }
820 addProtojet(jet1);
821 delete jet2;
822}
823
824void AliTkConeJetFinderV2::splitJets(protojet *jet1,protojet *jet2)
825{
826 // split protojets...
827 list<tower*> sharedTowers = jet1->getSharedTowerList(jet2);
828 for (list<tower*>::const_iterator iter = sharedTowers.begin();
829 iter != sharedTowers.end(); ++iter) {
830 // search nearest jet
831 if (jet1->diffToCenter(*iter) < jet2->diffToCenter(*iter)) {
832 // tower closer to jet1
833 jet2->eraseTower(*iter);
834 } else {
835 // tower closer to jet2
836 jet1->eraseTower(*iter);
837 }
838 }
839 if (jet1->shareTowers(jet2)) {
840 cerr << "!!! SplitJets: Something is wrong !!!" << endl;
841 addProtojet(jet1);
842 delete jet2;
843 return;
844 }
845 addProtojet(jet1);
846 addProtojet(jet2);
847}
848
849void AliTkConeJetFinderV2::dumpJets()
850{
851 cout << "----- found jets > " << fEtMinJet << " GeV -----" << endl;
852 for (list<protojet*>::const_iterator iter = fJets.begin();
853 iter != fJets.end(); ++iter) {
854 if((*iter)->getEt()>fEtMinJet) cout << (*(*iter)) << endl;
855 }
856}
857
858#ifdef DOHISTOS
859void AliTkConeJetFinderV2::createHistos()
860{
861}
862#endif
863
864#ifdef DOHISTOS
865void AliTkConeJetFinderV2::createEventHistos()
866{
867 fHistFile = new TFile("$JF_DATADIR/ConeFinderV2.root","RECREATE");
868 TH2F *h = new TH2F("Etbins","Etbins",
869 fEtaBins,fEtaMin,fEtaMax,
870 fPhiBins,fPhiMin,fPhiMax);
871 h->GetXaxis()->SetTitle("#eta");
872 h->GetYaxis()->SetTitle("#phi");
873 h->GetZaxis()->SetTitle("E_{t} (GeV)");
874 fEventHistos.Add(h);
875
876 h = new TH2F("Etbin_check","Etbin_check",
877 fEtaBins,fEtaMin,fEtaMax,
878 fPhiBins,fPhiMin,fPhiMax);
879 h->GetXaxis()->SetTitle("#eta");
880 h->GetYaxis()->SetTitle("#phi");
881 h->GetZaxis()->SetTitle("E_{t} (GeV)");
882 fEventHistos.Add(h);
883
884 h = new TH2F("seedpoints","seedpoints",
885 fEtaBins,fEtaMin,fEtaMax,
886 fPhiBins,fPhiMin,fPhiMax);
887 h->GetXaxis()->SetTitle("#eta");
888 h->GetYaxis()->SetTitle("#phi");
889 fEventHistos.Add(h);
890}
891#endif
892#ifdef DOHISTOS
893void AliTkConeJetFinderV2::clearEventHistos()
894{
895 ((TH2F *)fEventHistos.At(0))->Reset();
896 ((TH2F *)fEventHistos.At(1))->Reset();
897 ((TH2F *)fEventHistos.At(2))->Reset();
898}
899#endif
900
901#ifdef DOHISTOS
902void AliTkConeJetFinderV2::writeEventHistos()
903{
904 fHistFile->cd();
905 ((TH2F *)fEventHistos.At(0))->Write();
906 ((TH2F *)fEventHistos.At(1))->Write();
907 ((TH2F *)fEventHistos.At(2))->Write();
908}
909#endif
910
911#ifdef DOHISTOS
912void AliTkConeJetFinderV2::writeHistos()
913{
914}
915#endif
916
917#ifdef DOHISTOS
918void AliTkConeJetFinderV2::fillTowerHist()
919{
920 for (vector<tower>::iterator i=(*fTowers).begin(); i!=(*fTowers).end(); ++i) {
921 tower t = *i;
922 Float_t eta = (t.getEtaMax() + t.getEtaMin()) / 2.;
923 Float_t phi = (t.getPhiMax() + t.getPhiMin()) / 2.;
924 ((TH2F *)fEventHistos.At(0))->Fill(eta,phi,t.getEt());
925 }
926}
927#endif
928
929void AliTkConeJetFinderV2::setEvOutFilename(const Char_t *filename)
930{
931 if (!fEvout_name) {
932 fEvout_name = new Char_t[4096];
933 }
934
935 strcpy(fEvout_name,filename);
936}
937