2 /**************************************************************************
3 * AliTkConeJetFinder.cxx *
4 * Thorsten Kollegger <kollegge@ikf.physik.uni-frankfurt.de *
5 * Jet finder based on a cone algorithm with seeds and addition of *
6 * midpoints, for a description of the algorithm see hep-ex/0005012 *
7 *************************************************************************/
9 // all includes in AliTkConeJetFinder.h
10 #include "AliTkConeJetFinder.h"
12 ClassImp(AliTkConeJetFinder)
14 AliTkConeJetFinder::AliTkConeJetFinder() : TObject() {
15 setEtaGrid(-999,999,-999);
16 setPhiGrid(-999,999,-999);
20 AliTkConeJetFinder::~AliTkConeJetFinder() {
26 void AliTkConeJetFinder::setDefaultSettings() {
27 setEtaGrid(100,-5.,5.);
28 setPhiGrid((Int_t) (2*TMath::Pi()/0.1),
31 setJetConeRadius(0.7);
34 void AliTkConeJetFinder::Init() {
35 // create an array for the tower info
36 // and at this stage we know how many towers we have...
38 nTower = nEtaBins*nPhiBins;
39 towers = new AliTkTower[nTower];
41 cerr << "Couldn't allocate space for tower info!!!" << endl;
43 // let's create the towers;
44 Float_t etaBinSize = (nEtaMax-nEtaMin)/(Float_t)nEtaBins;
45 cout << "Init: etaBinSize=" << etaBinSize << endl;
46 Float_t phiBinSize = (nPhiMax-nPhiMin)/(Float_t)nPhiBins;
47 cout << "Init: phiBinSize=" << phiBinSize << endl;
49 Float_t eta = nEtaMin;
50 Float_t phi = nPhiMin;
51 for (Int_t uid = 0; uid < nTower; uid++) {
52 towers[uid].uid = uid;
53 towers[uid].etaMin = eta;
54 towers[uid].phiMin = phi;
55 towers[uid].etaMax = eta + etaBinSize;
56 towers[uid].phiMax = phi + phiBinSize;
65 // create an array for the seed list...
66 SeedTower = new Int_t[nTower];
68 // create the array to store the protojets
69 const Int_t expectedNumberOfProtoJets = 1000;
70 protojets = new TObjArray(expectedNumberOfProtoJets);
71 protojets->SetOwner(kTRUE);
73 // called once to initalize the finder...
74 // create the histogram which stores the Et information
75 hEtHist = new TH2D("Tower_EtHist","Tower_EtHist",
76 nEtaBins,nEtaMin,nEtaMax,
77 nPhiBins,nPhiMin,nPhiMax);
78 hEtHist->GetXaxis()->SetTitle("#eta");
79 hEtHist->GetYaxis()->SetTitle("#phi (rad)");
80 hEtHist->GetZaxis()->SetTitle("E_{t} in bins (GeV)");
82 // create histogram to hold Et cone centeres around tower center
83 hEtConeHist = new TH2D("Cone_EtHist","Cone_EtHist",
84 nEtaBins,nEtaMin,nEtaMax,
85 nPhiBins,nPhiMin,nPhiMax);
86 hEtConeHist->GetXaxis()->SetTitle("#eta");
87 hEtConeHist->GetYaxis()->SetTitle("#phi (rad)");
88 hEtConeHist->GetZaxis()->SetTitle("E_{t} in cones (GeV)");
90 // create histogram to show the stable protojets before merging
91 hStableProtoJetHist = new TH2D("StableProtoJetHist","StableProtoJetHist",
92 nEtaBins,nEtaMin,nEtaMax,
93 nPhiBins,nPhiMin,nPhiMax);
94 hStableProtoJetHist->GetXaxis()->SetTitle("#eta");
95 hStableProtoJetHist->GetYaxis()->SetTitle("#phi (rad)");
96 hStableProtoJetHist->GetZaxis()->SetTitle("E_{t} in stable cones (GeV)");
98 hTowerEt = new TH2D("tower_EtCheck","tower EtCheck",
99 nEtaBins,nEtaMin,nEtaMax,
100 nPhiBins,nPhiMin,nPhiMax);
101 hTowerEt->GetXaxis()->SetTitle("#eta");
102 hTowerEt->GetYaxis()->SetTitle("#phi (rad)");
103 hTowerEt->GetZaxis()->SetTitle("E_{t} in bins (GeV)");
107 void AliTkConeJetFinder::InitEvent() {
108 // called at each events
109 // clears the jet finder for the next event
111 // clear tower array - only Et
112 for (Int_t i = 0; i < nTower; i++) {
116 // clear protojet list
119 // clear control histograms
121 hEtConeHist->Reset();
123 hStableProtoJetHist->Reset();
127 void AliTkConeJetFinder::FillEtHistFromTParticles(TClonesArray *particles) {
128 // input TClonesArray with TParticles, e.g. from PYTHIA
129 // fills the Et grid from these particles
133 TParticle *particle = NULL;
136 // loop over all particles...
137 TIterator *iter = particles->MakeIterator();
138 while ((particle = (TParticle *) iter->Next()) != NULL) {
139 // check if particle is accepted
140 if (isTParticleAccepted(particle)) {
141 // calculate Et for a massless particle...
142 Et = TMath::Sqrt(particle->Pt()*particle->Pt());
143 // idea for Et check: Et = E *sin(theta);
144 Int_t tower = findTower(particle->Eta(),particle->Phi());
146 towers[tower].Et += Et;
148 // cerr << "Couldn't find tower!!! eta="
149 // << particle->Eta() << " phi=" << particle->Phi()
152 // and to the histogram for control reasons
153 AddEtHist(particle->Eta(),particle->Phi(),Et);
157 // at this point we have filled all towers...
158 // let's make sure tower info is right
159 for (Int_t i = 0; i < nTower; i++) {
160 Float_t etacenter = (towers[i].etaMin + towers[i].etaMax)/2.;
161 Float_t phicenter = (towers[i].phiMin + towers[i].phiMax)/2.;
162 hTowerEt->Fill(etacenter,phicenter,towers[i].Et);
167 Bool_t AliTkConeJetFinder::isTParticleAccepted(TParticle *particle) {
168 // check if particle is accepted
169 // makes sense to write this into a own class, but now I'm lazy
171 // check if particle is stable -> a detectable particle
172 if (particle->GetStatusCode() != 1) {
175 // and now just for fun
176 TParticlePDG *partPDG;
177 partPDG = particle->GetPDG();
178 // if (partPDG->Charge() == 0) {
179 // cout << partPDG->GetName() << endl;
183 // default case: accept
187 void AliTkConeJetFinder::AddEtHist(Float_t eta, Float_t phi, Double_t Et) {
188 // add particle/tower withEt at position eta,phi to the current Et grid...
191 // get the Et already stored in the bin eta,phi
192 oldEt = hEtHist->GetBinContent(hEtHist->GetXaxis()->FindFixBin(eta),
193 hEtHist->GetYaxis()->FindFixBin(phi));
196 // and set the bin to the sum of old+new Et.
197 hEtHist->SetBinContent(hEtHist->GetXaxis()->FindFixBin(eta),
198 hEtHist->GetYaxis()->FindFixBin(phi),
203 Int_t AliTkConeJetFinder::run() {
205 status = FindProtoJets();
206 cout << "Found " << protojets->GetEntries() << " stable protojets"
211 Int_t AliTkConeJetFinder::FindProtoJets() {
222 AliTkProtoJet protojet;
224 // let's take each tower as seed
225 // this means seedless search...
226 // introduce later step with seed+midpoints...
227 for (Int_t i=0; i < nTower; i++) {
228 // loop over all towers
229 etaTower = (towers[i].etaMax+towers[i].etaMin)/2.;
230 phiTower = (towers[i].phiMax+towers[i].phiMin)/2.;
235 // let's calculate a protojet with centered around tower center
236 if ((CalculateConeCentroid(&eta,&phi,&Et) > 0)) {
237 // ok, we found a valid centroid around tower pos
238 // let's fill the initial seed into the EtConeHist
239 hEtConeHist->Fill(etaTower,phiTower,Et);
240 // let's calculate the vector to the weighted cone center
241 etaDiff = (eta - etaTower)*(eta - etaTower);
242 phiDiff = calcPhiDiff(phi,phiTower);
244 // let's iterate the proto-jet while it's in the tower boundaries
246 // or the maximum number of iterations is reached
247 Bool_t isStable = kFALSE;
248 Bool_t isInTower = isProtoJetInTower(i,eta,phi);
249 //Bool_t isInTower = isProtoJetInTower(etaBin,phiBin,eta,phi);
250 Int_t nIterations = 0;
254 // make const variables private members and set in default...
255 const Int_t nMaxIterations = 100;
256 while ((nIterations < nMaxIterations) &&
261 CalculateConeCentroid(&eta,&phi,&Et);
262 etaDiff = (eta - etaOld)*(eta - etaOld);
263 phiDiff = calcPhiDiff(phi,phiOld)*calcPhiDiff(phi,phiOld);
264 // and check protojet again...
265 isStable = isProtoJetStable(etaDiff,phiDiff);
266 // we allow the jet to flow away...
268 // we force protojets to stay in tower
269 isInTower = isProtoJetInTower(i,eta,phi);
273 if ((isStable) || (nIterations == nMaxIterations)) {
274 // cout << "Found a stable protojet at eta=" << eta
275 // << " phi=" << phi << " with Et=" << Et << endl;
276 if (nIterations == nMaxIterations) {
277 cout << "To many iterations on protojet" << endl;
279 // create a new protojet object
280 AliTkProtoJet *protojet = new AliTkProtoJet();
285 // let's check if we allready found this protojet
286 TIter *iter = new TIter(protojets);
288 Bool_t wasFound = kFALSE;
289 while ((pj = (AliTkProtoJet *) iter->Next()) && !wasFound) {
290 wasFound = protojet->IsEqual(pj);
293 // and add it to the list of protojets...
295 protojets->Add(protojet);
296 //cout << protojet->Et << endl;
297 hStableProtoJetHist->Fill(eta,phi,Et);
307 Int_t AliTkConeJetFinder::FindJets() {
308 //let's look for the highest Et-Jet
315 Int_t AliTkConeJetFinder::CalculateConeCentroid(Float_t *eta, Float_t *phi,
318 //====================================================================
319 // WORKS STILL ON HISTOGRAM
320 // MUST WORK ON TOWERS
321 //====================================================================
324 // let's copy some stuff
325 Float_t etaCenter = *eta;
326 Float_t phiCenter = *phi;
329 cout << "CalculateConeCentroid: Initial Cone Center eta="
336 Float_t etaTower = 0;
337 Float_t phiTower = 0;
347 // lets calculate boundaries from jet cone
348 Float_t etaMin = etaCenter - jetRadius;
349 Float_t etaMax = etaCenter + jetRadius;
350 Float_t phiMin = phiCenter - jetRadius;
353 phiMin = 2*TMath::Pi() + phiMin;
355 Float_t phiMax = phiCenter + jetRadius;
356 if (phiMax > 2*TMath::Pi()) {
357 phiMax = phiMax - 2*TMath::Pi();
360 Int_t etaBinMin = hEtHist->GetXaxis()->FindFixBin(etaMin);
361 if (etaBinMin == 0) {
364 Int_t etaBinMax = hEtHist->GetXaxis()->FindFixBin(etaMax);
365 if (etaBinMax == hEtHist->GetXaxis()->GetNbins()+1) {
368 Int_t phiBinMin = hEtHist->GetYaxis()->FindFixBin(phiMin);
369 Int_t phiBinMax = hEtHist->GetYaxis()->FindFixBin(phiMax);
371 // let's loop over all bins/towers...
372 for (Int_t etaBin = etaBinMin; etaBin != etaBinMax+1; etaBin++) {
373 for (Int_t phiBin = phiBinMin; phiBin != phiBinMax+1; phiBin++) {
374 // roll over in phi...
375 if (phiBin == hEtHist->GetYaxis()->GetNbins()+1) {
379 // let's get the tower
380 etaTower = hEtHist->GetXaxis()->GetBinCenter(etaBin);
381 phiTower = hEtHist->GetYaxis()->GetBinCenter(phiBin);
382 EtTower = hEtHist->GetCellContent(etaBin,phiBin);
384 // let's check if the bin is in the cone
385 etaDiff = (etaTower - etaCenter)*(etaTower - etaCenter);
386 phiDiff = calcPhiDiff(phiTower,phiCenter)*
387 calcPhiDiff(phiTower,phiCenter);
388 if (TMath::Sqrt(etaDiff+phiDiff) < jetRadius) {
389 // tower is in cone - add it to the cone
392 etaJet += EtTower * etaTower;
393 phiJet += EtTower * phiTower;
399 // normalize eta and phi
406 cout << "CalculateConeCentroid: Final Cone Center eta="
415 // return the jet cone parameters
424 Float_t AliTkConeJetFinder::calcPhiDiff(Float_t phi1, Float_t phi2) {
425 Float_t phidiff1 = TMath::Sqrt((phi1-phi2)*(phi1-phi2));
426 Float_t phidiff2 = TMath::Sqrt((phi1-phi2-2*TMath::Pi())*
427 (phi1-phi2-2*TMath::Pi()));
428 Float_t phidiff3 = TMath::Sqrt((phi1-phi2+2*TMath::Pi())*
429 (phi1-phi2+2*TMath::Pi()));
430 // return the minmum;
431 Float_t phiret = phidiff1;
432 if (phiret > phidiff2) {
435 if (phiret > phidiff3) {
441 Bool_t AliTkConeJetFinder::isProtoJetStable(Float_t etaDiff, Float_t phiDiff) {
442 const Float_t epsilon = 0.00001;
443 if (TMath::Sqrt(etaDiff*phiDiff) < epsilon) {
449 Bool_t AliTkConeJetFinder::isProtoJetInTower(Int_t etaBin, Int_t phiBin,
450 Float_t eta, Float_t phi) {
451 Float_t etaBinMax = hEtHist->GetXaxis()->GetBinUpEdge(etaBin);
452 Float_t etaBinMin = hEtHist->GetXaxis()->GetBinLowEdge(etaBin);
453 Float_t phiBinMax = hEtHist->GetYaxis()->GetBinUpEdge(phiBin);
454 Float_t phiBinMin = hEtHist->GetYaxis()->GetBinLowEdge(phiBin);
455 if ((eta < etaBinMax) &&
465 Bool_t AliTkConeJetFinder::isProtoJetInTower(Int_t tower, Float_t eta,
467 if ((eta > towers[tower].etaMin) &&
468 (eta < towers[tower].etaMax) &&
469 (phi > towers[tower].phiMin) &&
470 (phi < towers[tower].phiMax)) {
476 Int_t AliTkConeJetFinder::findTower(Float_t eta, Float_t phi) {
477 Float_t etaBinSize = (nEtaMax - nEtaMin)/(Float_t)nEtaBins;
478 Float_t phiBinSize = (nPhiMax - nPhiMin)/(Float_t)nPhiBins;
480 if ((eta < nEtaMin) || (eta > nEtaMax)) {
483 if ((phi < nPhiMin) || (phi > nPhiMax)) {
487 Int_t etaBin = (Int_t) ((eta - nEtaMin)/etaBinSize);
488 Int_t phiBin = (Int_t) ((phi - nPhiMin)/phiBinSize);
490 Int_t bin = etaBin * nPhiBins + phiBin;
499 // lot of setters/getters... nothing special, no comments...
500 void AliTkConeJetFinder::setEtaNBins(Int_t nbins) {
504 Int_t AliTkConeJetFinder::getEtaNBins() {
508 void AliTkConeJetFinder::setEtaRange(Float_t min, Float_t max) {
513 Float_t AliTkConeJetFinder::getEtaRangeMin() {
517 Float_t AliTkConeJetFinder::getEtaRangeMax() {
521 void AliTkConeJetFinder::setEtaGrid(Int_t nbins, Float_t min, Float_t max) {
523 setEtaRange(min,max);
526 void AliTkConeJetFinder::setPhiNBins(Int_t nbins) {
530 Int_t AliTkConeJetFinder::getPhiNBins() {
534 void AliTkConeJetFinder::setPhiRange(Float_t min, Float_t max) {
539 Float_t AliTkConeJetFinder::getPhiRangeMin() {
543 Float_t AliTkConeJetFinder::getPhiRangeMax() {
547 void AliTkConeJetFinder::setPhiGrid(Int_t nbins, Float_t min, Float_t max) {
549 setPhiRange(min,max);
552 void AliTkConeJetFinder::setJetConeRadius(Float_t r) {
556 Float_t AliTkConeJetFinder::getJetConeRadius() {
560 TObjArray *AliTkConeJetFinder::getProtoJetList() {
564 //==========================================================================
567 //==========================================================================
568 ClassImp(AliTkProtoJet)
570 Bool_t AliTkProtoJet::IsEqual(AliTkProtoJet *other) {
571 const Float_t epsilon = 0.0000001;
573 Float_t etaDiff = (other->eta - eta)*(other->eta - eta);
574 Float_t phiDiff = (other->phi - phi)*(other->phi - phi);
575 Float_t EtDiff = (other->Et - Et)*(other->Et - Et);
577 Bool_t isEqual = kFALSE;
578 if ((etaDiff < epsilon) &&
579 (phiDiff < epsilon) &&
580 (EtDiff < epsilon)) {
586 bool SProtoJet::operator==(const SProtoJet &s1) {
587 Float_t epsilon = 0.0000001;
590 b = ((eta - s1.eta) < epsilon);
592 b = ((s1.eta - eta) < epsilon);
595 b = b && ((phi - s1.phi) < epsilon);
597 b = b && ((s1.phi - phi) < epsilon);
600 b = b && ((Et - s1.Et) < epsilon);
602 b = b && ((s1.Et - Et) < epsilon);