1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 Revision 1.27 2002/11/15 17:39:10 morsch
19 GetPythiaParticleName removed.
21 Revision 1.26 2002/10/14 14:55:35 hristov
22 Merging the VirtualMC branch to the main development branch (HEAD)
24 Revision 1.20.4.3 2002/10/10 15:07:49 hristov
25 Updating VirtualMC to v3-09-02
27 Revision 1.25 2002/09/13 10:24:57 morsch
30 Revision 1.24 2002/09/13 10:21:13 morsch
33 Revision 1.23 2002/06/27 09:24:26 morsch
34 Uncomment the TH1::AddDirectory statement.
36 Revision 1.22 2002/05/22 13:48:43 morsch
37 Pdg code added to track list.
39 Revision 1.21 2002/04/27 07:43:08 morsch
40 Calculation of fDphi corrected (Renan Cabrera)
42 Revision 1.20 2002/03/12 01:06:23 pavlinov
43 Testin output from generator
45 Revision 1.19 2002/02/27 00:46:33 pavlinov
46 Added method FillFromParticles()
48 Revision 1.18 2002/02/21 08:48:59 morsch
49 Correction in FillFromHitFlaggedTrack. (Jennifer Klay)
51 Revision 1.17 2002/02/14 08:52:53 morsch
52 Major updates by Aleksei Pavlinov:
53 FillFromPartons, FillFromTracks, jetfinder configuration.
55 Revision 1.16 2002/02/08 11:43:05 morsch
56 SetOutputFileName(..) allows to specify an output file to which the
57 reconstructed jets are written. If not set output goes to input file.
58 Attention call Init() before processing.
60 Revision 1.15 2002/02/02 08:37:18 morsch
61 Formula for rB corrected.
63 Revision 1.14 2002/02/01 08:55:30 morsch
64 Fill map with Et and pT.
66 Revision 1.13 2002/01/31 09:37:36 morsch
67 Geometry parameters in constructor and call of SetCellSize()
69 Revision 1.12 2002/01/23 13:40:23 morsch
70 Fastidious debug print statement removed.
72 Revision 1.11 2002/01/22 17:25:47 morsch
73 Some corrections for event mixing and bg event handling.
75 Revision 1.10 2002/01/22 10:31:44 morsch
76 Some correction for bg mixing.
78 Revision 1.9 2002/01/21 16:28:42 morsch
81 Revision 1.8 2002/01/21 16:05:31 morsch
82 - different phi-bin for hadron correction
83 - provisions for background mixing.
85 Revision 1.7 2002/01/21 15:47:18 morsch
86 Bending radius correctly in cm.
88 Revision 1.6 2002/01/21 12:53:50 morsch
91 Revision 1.5 2002/01/21 12:47:47 morsch
92 Possibility to include K0long and neutrons.
94 Revision 1.4 2002/01/21 11:03:21 morsch
95 Phi propagation introduced in FillFromTracks.
97 Revision 1.3 2002/01/18 05:07:56 morsch
100 - track selection upon EMCAL information
104 //*-- Authors: Andreas Morsch (CERN)
106 //* Aleksei Pavlinov (WSU)
111 #include <TClonesArray.h>
113 #include <TBranchElement.h>
121 #include <TPaveText.h>
124 #include <TParticle.h>
125 #include <TParticlePDG.h>
126 #include <TPythia6Calls.h>
129 #include "AliEMCALJetFinder.h"
130 #include "AliEMCALFast.h"
131 #include "AliEMCALGeometry.h"
132 #include "AliEMCALHit.h"
133 #include "AliEMCALDigit.h"
134 #include "AliEMCALDigitizer.h"
135 #include "AliEMCALHadronCorrection.h"
136 #include "AliEMCALJetMicroDst.h"
139 #include "AliMagFCM.h"
140 #include "AliEMCAL.h"
141 #include "AliHeader.h"
145 // Interface to FORTRAN
149 ClassImp(AliEMCALJetFinder)
151 //____________________________________________________________________________
152 AliEMCALJetFinder::AliEMCALJetFinder()
154 // Default constructor
173 fHadronCorrector = 0;
181 SetParametersForBgSubtraction();
184 AliEMCALJetFinder::AliEMCALJetFinder(const char* name, const char *title)
188 // Title is used in method GetFileNameForParameters();
190 fJets = new TClonesArray("AliEMCALJet",10000);
192 for (Int_t i = 0; i < 30000; i++)
214 fHadronCorrector = 0;
223 SetMomentumSmearing();
226 SetHadronCorrection();
227 SetSamplingFraction();
230 SetParametersForBgSubtraction();
233 void AliEMCALJetFinder::SetParametersForBgSubtraction
234 (Int_t mode, Float_t minMove, Float_t maxMove, Float_t precBg)
236 // see file /home/pavlinov/cosmic/pythia/jetFinderParamData.inc
237 // at WSU Linux cluster - 11-feb-2002
238 // These parameters must be tuned more carefull !!!
245 //____________________________________________________________________________
246 AliEMCALJetFinder::~AliEMCALJetFinder()
258 delete fhLegoHadrCorr;
261 delete fhCellEMCALEt;
263 delete fhTrackPtBcut;
264 delete fhChPartMultInTpc;
272 delete[] fTrackListB;
280 # define jet_finder_ua1 jet_finder_ua1_
282 # define type_of_call
285 # define jet_finder_ua1 JET_FINDER_UA1
287 # define type_of_call _stdcall
290 extern "C" void type_of_call
291 jet_finder_ua1(Int_t& ncell, Int_t& ncell_tot,
292 Float_t etc[30000], Float_t etac[30000],
294 Float_t& min_move, Float_t& max_move, Int_t& mode,
295 Float_t& prec_bg, Int_t& ierror);
297 extern "C" void type_of_call hf1(Int_t& id, Float_t& x, Float_t& wgt);
300 void AliEMCALJetFinder::Init()
303 // Geometry and I/O initialization
307 // Get geometry parameters from EMCAL
311 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
312 AliEMCALGeometry* geom =
313 AliEMCALGeometry::GetInstance(pEMCAL->GetTitle(), "");
314 fNbinEta = geom->GetNZ();
315 fNbinPhi = geom->GetNPhi();
316 fPhiMin = geom->GetArm1PhiMin()*TMath::Pi()/180.;
317 fPhiMax = geom->GetArm1PhiMax()*TMath::Pi()/180.;
318 fEtaMin = geom->GetArm1EtaMin();
319 fEtaMax = geom->GetArm1EtaMax();
320 fDphi = (fPhiMax-fPhiMin)/fNbinPhi;
321 fDeta = (fEtaMax-fEtaMin)/fNbinEta;
322 fNtot = fNbinPhi*fNbinEta;
324 SetCellSize(fDeta, fDphi);
327 if (fOutFileName) fOutFile = new TFile(fOutFileName, "recreate");
330 void AliEMCALJetFinder::Find(Int_t ncell, Int_t ncell_tot, Float_t etc[30000],
331 Float_t etac[30000], Float_t phic[30000],
332 Float_t min_move, Float_t max_move, Int_t mode,
333 Float_t prec_bg, Int_t ierror)
335 // Wrapper for fortran coded jet finder
336 // Full argument list
337 jet_finder_ua1(ncell, ncell_tot, etc, etac, phic,
338 min_move, max_move, mode, prec_bg, ierror);
339 // Write result to output
340 if(fWrite) WriteJets();
344 void AliEMCALJetFinder::Find()
346 // Wrapper for fortran coded jet finder using member data for
349 Float_t min_move = fMinMove;
350 Float_t max_move = fMaxMove;
352 Float_t prec_bg = fPrecBg;
355 ResetJets(); // 4-feb-2002 by PAI
357 jet_finder_ua1(fNcell, fNtot, fEtCell, fEtaCell, fPhiCell,
358 min_move, max_move, mode, prec_bg, ierror);
360 // Write result to output
361 Int_t njet = Njets();
363 for (Int_t nj=0; nj<njet; nj++)
366 fJetT[nj] = new AliEMCALJet(JetEnergy(nj),
371 FindTracksInJetCone();
372 if(fWrite) WriteJets();
376 Int_t AliEMCALJetFinder::Njets()
378 // Get number of reconstructed jets
379 return EMCALJETS.njet;
382 Float_t AliEMCALJetFinder::JetEnergy(Int_t i)
384 // Get reconstructed jet energy
385 return EMCALJETS.etj[i];
388 Float_t AliEMCALJetFinder::JetPhiL(Int_t i)
390 // Get reconstructed jet phi from leading particle
391 return EMCALJETS.phij[0][i];
394 Float_t AliEMCALJetFinder::JetPhiW(Int_t i)
396 // Get reconstructed jet phi from weighting
397 return EMCALJETS.phij[1][i];
400 Float_t AliEMCALJetFinder::JetEtaL(Int_t i)
402 // Get reconstructed jet eta from leading particles
403 return EMCALJETS.etaj[0][i];
407 Float_t AliEMCALJetFinder::JetEtaW(Int_t i)
409 // Get reconstructed jet eta from weighting
410 return EMCALJETS.etaj[1][i];
413 void AliEMCALJetFinder::SetCellSize(Float_t eta, Float_t phi)
415 // Set grid cell size
416 EMCALCELLGEO.etaCellSize = eta;
417 EMCALCELLGEO.phiCellSize = phi;
420 void AliEMCALJetFinder::SetConeRadius(Float_t par)
422 // Set jet cone radius
423 EMCALJETPARAM.coneRad = par;
427 void AliEMCALJetFinder::SetEtSeed(Float_t par)
429 // Set et cut for seeds
430 EMCALJETPARAM.etSeed = par;
434 void AliEMCALJetFinder::SetMinJetEt(Float_t par)
436 // Set minimum jet et
437 EMCALJETPARAM.ejMin = par;
441 void AliEMCALJetFinder::SetMinCellEt(Float_t par)
443 // Set et cut per cell
444 EMCALJETPARAM.etMin = par;
448 void AliEMCALJetFinder::SetPtCut(Float_t par)
450 // Set pT cut on charged tracks
455 void AliEMCALJetFinder::Test()
458 // Test the finder call
460 const Int_t nmax = 30000;
462 Int_t ncell_tot = 100;
467 Float_t min_move = 0;
468 Float_t max_move = 0;
474 Find(ncell, ncell_tot, etc, etac, phic,
475 min_move, max_move, mode, prec_bg, ierror);
483 void AliEMCALJetFinder::AddJet(const AliEMCALJet& jet)
488 TClonesArray &lrawcl = *fJets;
489 new(lrawcl[fNjets++]) AliEMCALJet(jet);
492 void AliEMCALJetFinder::ResetJets()
501 void AliEMCALJetFinder::WriteJets()
504 // Add all jets to the list
506 const Int_t kBufferSize = 4000;
507 const char* file = 0;
509 Int_t njet = Njets();
511 for (Int_t nj = 0; nj < njet; nj++)
520 // output written to input file
522 AliEMCAL* pEMCAL = (AliEMCAL* )gAlice->GetModule("EMCAL");
523 TTree* pK = gAlice->TreeK();
524 file = (pK->GetCurrentFile())->GetName();
526 printf("Make Branch - TreeR address %p %p\n",gAlice->TreeR(), pEMCAL);
527 if (fJets && gAlice->TreeR()) {
528 pEMCAL->MakeBranchInTree(gAlice->TreeR(),
534 Int_t nev = gAlice->GetHeader()->GetEvent();
535 gAlice->TreeR()->Fill();
537 sprintf(hname,"TreeR%d", nev);
538 gAlice->TreeR()->Write(hname);
539 gAlice->TreeR()->Reset();
542 // Output written to user specified output file
544 TTree* pK = gAlice->TreeK();
545 fInFile = pK->GetCurrentFile();
549 sprintf(hname,"TreeR%d", fEvent);
550 TTree* treeJ = new TTree(hname, "EMCALJets");
551 treeJ->Branch("EMCALJets", &fJets, kBufferSize);
559 void AliEMCALJetFinder::BookLego()
562 // Book histo for discretisation
566 // Don't add histos to the current directory
567 if(fDebug) printf("\n AliEMCALJetFinder::BookLego() \n");
569 TH2::AddDirectory(0);
570 TH1::AddDirectory(0);
574 fLego = new TH2F("legoH","eta-phi",
575 fNbinEta, fEtaMin, fEtaMax,
576 fNbinPhi, fPhiMin, fPhiMax);
579 fLegoB = new TH2F("legoB","eta-phi for BG event",
580 fNbinEta, fEtaMin, fEtaMax,
581 fNbinPhi, fPhiMin, fPhiMax);
584 fhLegoTracks = new TH2F("hLegoTracks","eta-phi for Tracks",
585 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
587 fhLegoEMCAL = new TH2F("hLegoEMCAL","eta-phi for EMCAL",
588 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
589 // Hadron correction map
590 fhLegoHadrCorr = new TH2F("hLegoHadrCorr","eta-phi for Hadron. Correction",
591 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
592 // Hists. for tuning jet finder
593 fhEff = new TH2F("hEff","#epsilon vs momentum ", 100,0.,20., 50,0.5,1.);
597 for(Int_t i=1; i<=1000; i++) eTmp[i] = 0.1*i; // step 100 mev
598 for(Int_t i=1001; i<=1100; i++) eTmp[i] = eTmp[1000] + 1.0*(i-1000); // step 1GeV
600 fhCellEt = new TH1F("hCellEt","Cell E_{T} from fLego",
601 eTmp.GetSize()-1, eTmp.GetArray());
602 fhCellEMCALEt = new TH1F("hCellEMCALEt","Cell E_{T} for EMCAL itself",
603 eTmp.GetSize()-1, eTmp.GetArray());
604 fhTrackPt = new TH1F("hTrackPt","Ch.particles P_{T} ",
605 eTmp.GetSize()-1, eTmp.GetArray());
606 fhTrackPtBcut = new TH1F("hTrackPtBcut","Ch.particles P_{T} + magnetic field cut",
607 eTmp.GetSize()-1, eTmp.GetArray());
609 fhChPartMultInTpc = new TH1F("hChPartMultInTpc",
610 "Charge partilcle multiplicity in |%eta|<0.9", 2000, 0, 20000);
612 //! first canvas for drawing
613 fHistsList=AliEMCALJetMicroDst::MoveHistsToList("Hists from AliEMCALJetFinder", kTRUE);
616 void AliEMCALJetFinder::DumpLego()
619 // Dump lego histo into array
622 TAxis* Xaxis = fLego->GetXaxis();
623 TAxis* Yaxis = fLego->GetYaxis();
624 // fhCellEt->Clear();
626 for (Int_t i = 1; i <= fNbinEta; i++) {
627 for (Int_t j = 1; j <= fNbinPhi; j++) {
628 e = fLego->GetBinContent(i,j);
630 Float_t eta = Xaxis->GetBinCenter(i);
631 Float_t phi = Yaxis->GetBinCenter(j);
633 fEtaCell[fNcell] = eta;
634 fPhiCell[fNcell] = phi;
639 eH = fhLegoEMCAL->GetBinContent(i,j);
640 if(eH > 0.0) fhCellEMCALEt->Fill(eH);
647 void AliEMCALJetFinder::ResetMap()
650 // Reset eta-phi array
652 for (Int_t i=0; i<30000; i++)
661 void AliEMCALJetFinder::FillFromTracks(Int_t flag, Int_t ich)
664 // Fill Cells with track information
667 printf("\n AliEMCALJetFinder::FillFromTracks(%i,%i) ",flag,ich);
672 if (!fLego) BookLego();
674 if (flag == 0) fLego->Reset();
676 // Access particle information
677 Int_t npart = (gAlice->GetHeader())->GetNprimary();
678 Int_t ntr = (gAlice->GetHeader())->GetNtrack();
679 printf(" : #primary particles %i # tracks %i \n", npart, ntr);
684 // 1: selected for jet finding
687 if (fTrackList) delete[] fTrackList;
688 if (fPtT) delete[] fPtT;
689 if (fEtaT) delete[] fEtaT;
690 if (fPhiT) delete[] fPhiT;
691 if (fPdgT) delete[] fPdgT;
693 fTrackList = new Int_t [npart];
694 fPtT = new Float_t[npart];
695 fEtaT = new Float_t[npart];
696 fPhiT = new Float_t[npart];
697 fPdgT = new Int_t[npart];
701 Float_t chTmp=0.0; // charge of current particle
704 // this is for Pythia ??
705 for (Int_t part = 0; part < npart; part++) {
706 TParticle *MPart = gAlice->Particle(part);
707 Int_t mpart = MPart->GetPdgCode();
708 Int_t child1 = MPart->GetFirstDaughter();
709 Float_t pT = MPart->Pt();
710 Float_t p = MPart->P();
711 Float_t phi = MPart->Phi();
713 if(pT > 0.001) eta = MPart->Eta();
714 Float_t theta = MPart->Theta();
716 printf("ind %7i part %7i -> child1 %5i child2 %5i Status %5i\n",
717 part, mpart, child1, MPart->GetLastDaughter(), MPart->GetStatusCode());
721 if (part == 6 || part == 7)
723 printf("\n Simulated Jet (pt, eta, phi): %d %f %f %f\n",
724 part-5, pT, eta, phi);
729 // printf("\n Simulated Jet (pt, eta, phi): %d %d %f %f %f",
730 // part, mpart, pT, eta, phi);
733 fTrackList[part] = 0;
734 fPtT[part] = pT; // must be change after correction for resolution !!!
740 if (part < 2) continue;
742 // move to fLego->Fill because hadron correction must apply
743 // if particle hit to EMCAL - 11-feb-2002
744 // if (pT == 0 || pT < fPtCut) continue;
745 TParticlePDG* pdgP = 0;
746 // charged or neutral
747 pdgP = MPart->GetPDG();
748 chTmp = pdgP->Charge() / 3.; // 13-feb-2001!!
755 if (mpart != kNeutron &&
756 mpart != kNeutronBar &&
757 mpart != kK0Long) continue;
763 if (TMath::Abs(mpart) <= 6 ||
765 mpart == 92) continue;
767 if (TMath::Abs(eta)<=0.9) fNChTpc++;
769 if (child1 >= 0 && child1 < npart) continue;
771 if (eta > fEtaMax || eta < fEtaMin) continue;
772 if (phi > fPhiMax || phi < fPhiMin ) continue;
775 printf("\n=>nsel:%5d mpart %5d child1 %5d eta %6.2f phi %6.2f pT %6.2f ch %3.0f ",
776 part, mpart, child1, eta, phi, pT, chTmp);
779 // Momentum smearing goes here ...
783 if (fSmear && TMath::Abs(chTmp)) {
784 pw = AliEMCALFast::SmearMomentum(1,p);
785 // p changed - take into account when calculate pT,
788 if(fDebug >= 4) printf("\n Smearing : p %8.4f change to %8.4f ", p, pw);
792 // Tracking Efficiency and TPC acceptance goes here ...
794 if (fEffic && TMath::Abs(chTmp)) {
795 // eff = AliEMCALFast::Efficiency(1,p);
796 eff = 0.95; // for testing 25-feb-2002
797 if(fhEff) fhEff->Fill(p, eff);
798 if (AliEMCALFast::RandomReject(eff)) {
799 if(fDebug >= 5) printf(" reject due to unefficiency ");
804 // Correction of Hadronic Energy goes here ...
807 // phi propagation for hadronic correction
809 Bool_t curls = kFALSE; // hit two the EMCAL (no curl)
810 Float_t phiHC=0.0, dpH=0.0, dphi=0.0, eTdpH=0;
811 if(TMath::Abs(chTmp)) {
812 // hadr. correction only for charge particle
813 dphi = PropagatePhi(pT, chTmp, curls);
816 printf("\n Delta phi %f pT %f ", dphi, pT);
817 if (curls) printf("\n !! Track is curling");
819 if(!curls) fhTrackPtBcut->Fill(pT);
821 if (fHCorrection && !curls) {
822 if (!fHadronCorrector)
823 Fatal("AliEMCALJetFinder",
824 "Hadronic energy correction required but not defined !");
826 dpH = fHadronCorrector->GetEnergy(p, eta, 7);
827 eTdpH = dpH*TMath::Sin(theta);
829 if (fDebug >= 7) printf(" phi %f phiHC %f eTcorr %f\n",
830 phi, phiHC, -eTdpH); // correction is negative
831 fLego->Fill(eta, phiHC, -eTdpH);
832 fhLegoHadrCorr->Fill(eta, phiHC, eTdpH);
836 // More to do ? Just think about it !
838 if (phi > fPhiMax || phi < fPhiMin ) continue;
840 if(TMath::Abs(chTmp) ) { // charge particle
841 if (pT > fPtCut && !curls) {
842 if (fDebug >= 8) printf("Charge : fLego->Fill(%5.2f, %5.2f, %6.2f, %d)\n",
843 eta , phi, pT, fNtS);
844 fLego->Fill(eta, phi, pT);
845 fhLegoTracks->Fill(eta, phi, pT); // 20-feb for checking
846 fTrackList[part] = 1;
849 } else if(ich==0 && fK0N) {
850 // case of n, nbar and K0L
851 if (fDebug >= 9) printf("Neutral : fLego->Fill(%5.2f, %5.2f, %6.2f, %d)\n",
852 eta , phi, pT, fNtS);
853 fLego->Fill(eta, phi, pT);
854 fTrackList[part] = 1;
862 void AliEMCALJetFinder::FillFromHits(Int_t flag)
865 // Fill Cells with hit information
869 printf("\n AliEMCALJetFinder::FillFromHits(%i)\n",flag);
873 if (!fLego) BookLego();
874 // Reset eta-phi maps if needed
875 if (flag == 0) { // default behavior
877 fhLegoTracks->Reset();
878 fhLegoEMCAL->Reset();
879 fhLegoHadrCorr->Reset();
881 // Initialize from background event if available
883 // Access hit information
884 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
885 TTree *treeH = gAlice->TreeH();
886 Int_t ntracks = (Int_t) treeH->GetEntries();
893 for (Int_t track=0; track<ntracks;track++) {
895 nbytes += treeH->GetEvent(track);
899 for(AliEMCALHit* mHit=(AliEMCALHit*) pEMCAL->FirstHit(-1);
901 mHit=(AliEMCALHit*) pEMCAL->NextHit())
903 Float_t x = mHit->X(); // x-pos of hit
904 Float_t y = mHit->Y(); // y-pos
905 Float_t z = mHit->Z(); // z-pos
906 Float_t eloss = mHit->GetEnergy(); // deposited energy
908 Float_t r = TMath::Sqrt(x*x+y*y);
909 Float_t theta = TMath::ATan2(r,z);
910 Float_t eta = -TMath::Log(TMath::Tan(theta/2.));
911 Float_t phi = TMath::ATan2(y,x);
913 if (fDebug >= 11) printf("\n Hit %f %f %f %f", x, y, z, eloss);
914 // printf("\n Hit %f %f %f %f", x, y, z, eloss);
916 etH = fSamplingF*eloss*TMath::Sin(theta);
917 fLego->Fill(eta, phi, etH);
918 // fhLegoEMCAL->Fill(eta, phi, etH);
921 // copy content of fLego to fhLegoEMCAL (fLego and fhLegoEMCAL are identical)
922 for(Int_t i=0; i<fLego->GetSize(); i++) (*fhLegoEMCAL)[i] = (*fLego)[i];
926 void AliEMCALJetFinder::FillFromDigits(Int_t flag)
929 // Fill Cells with digit information
934 if (!fLego) BookLego();
935 if (flag == 0) fLego->Reset();
942 TClonesArray* digs = new TClonesArray("AliEMCALDigit", 10000);
943 TTree *treeD = gAlice->TreeD();
944 TBranchElement* branchDg = (TBranchElement*)
945 treeD->GetBranch("EMCAL");
947 if (!branchDg) Fatal("AliEMCALJetFinder",
948 "Reading digits requested but no digits in file !");
950 branchDg->SetAddress(&digs);
951 Int_t nent = (Int_t) branchDg->GetEntries();
955 AliEMCALDigitizer* digr = new AliEMCALDigitizer();
956 TBranchElement* branchDr = (TBranchElement*)
957 treeD->GetBranch("AliEMCALDigitizer");
958 branchDr->SetAddress(&digr);
961 nbytes += branchDg->GetEntry(0);
962 nbytes += branchDr->GetEntry(0);
964 // Get digitizer parameters
965 Float_t towerADCped = digr->GetTowerpedestal();
966 Float_t towerADCcha = digr->GetTowerchannel();
967 Float_t preshoADCped = digr->GetPreShopedestal();
968 Float_t preshoADCcha = digr->GetPreShochannel();
970 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
971 AliEMCALGeometry* geom =
972 AliEMCALGeometry::GetInstance(pEMCAL->GetTitle(), "");
975 Int_t ndig = digs->GetEntries();
976 printf("\n Number of Digits: %d %d\n", ndig, nent);
977 printf("\n Parameters: %f %f %f %f\n",
978 towerADCped, towerADCcha, preshoADCped, preshoADCcha );
979 printf("\n Geometry: %d %d\n", geom->GetNEta(), geom->GetNPhi());
986 while ((sdg = (AliEMCALDigit*)(next())))
990 if (sdg->GetId() > (geom->GetNZ() * geom->GetNPhi()))
992 pedestal = preshoADCped;
993 channel = preshoADCcha;
995 pedestal = towerADCped;
996 channel = towerADCcha;
999 Float_t eta = sdg->GetEta();
1000 Float_t phi = sdg->GetPhi() * TMath::Pi()/180.;
1001 Float_t amp = (Float_t) (channel*(sdg->GetAmp())-pedestal);
1003 if (fDebug > 1) printf("\n Digit: eta %8.3f phi %8.3f amp %8.3f %8d",
1004 eta, phi, amp, sdg->GetAmp());
1006 fLego->Fill(eta, phi, fSamplingF*amp);
1014 void AliEMCALJetFinder::FillFromHitFlaggedTracks(Int_t flag)
1017 // Fill Cells with hit information
1022 if (!fLego) BookLego();
1024 if (flag == 0) fLego->Reset();
1026 // Flag charged tracks passing through TPC which
1027 // are associated to EMCAL Hits
1028 BuildTrackFlagTable();
1031 // Access particle information
1032 TTree *treeK = gAlice->TreeK();
1033 Int_t ntracks = (Int_t) treeK->GetEntries();
1035 if (fPtT) delete[] fPtT;
1036 if (fEtaT) delete[] fEtaT;
1037 if (fPhiT) delete[] fPhiT;
1038 if (fPdgT) delete[] fPdgT;
1040 fPtT = new Float_t[ntracks];
1041 fEtaT = new Float_t[ntracks];
1042 fPhiT = new Float_t[ntracks];
1043 fPdgT = new Int_t[ntracks];
1048 for (Int_t track = 0; track < ntracks; track++) {
1049 TParticle *MPart = gAlice->Particle(track);
1050 Float_t pT = MPart->Pt();
1051 Float_t phi = MPart->Phi();
1052 Float_t eta = MPart->Eta();
1054 if(fTrackList[track]) {
1058 fPdgT[track] = MPart->GetPdgCode();
1060 if (track < 2) continue; //Colliding particles?
1061 if (pT == 0 || pT < fPtCut) continue;
1063 fLego->Fill(eta, phi, pT);
1069 void AliEMCALJetFinder::FillFromParticles()
1071 // 26-feb-2002 PAI - for checking all chain
1072 // Work on particles level; accept all particle (not neutrino )
1074 Double_t PX=0, PY=0, PZ=0, E=0; // checking conservation law
1078 if (!fLego) BookLego();
1081 // Access particles information
1082 Int_t npart = (gAlice->GetHeader())->GetNprimary();
1083 if (fDebug >= 2 || npart<=0) {
1084 printf(" AliEMCALJetFinder::FillFromParticles : npart %i\n", npart);
1085 if(npart<=0) return;
1089 RearrangeParticlesMemory(npart);
1091 // Go through the particles
1092 Int_t mpart, child1, child2, geantPdg;
1093 Float_t pT, phi, eta, e=0, px=0, py=0, pz=0;
1095 for (Int_t part = 0; part < npart; part++) {
1097 fTrackList[part] = 0;
1099 MPart = gAlice->Particle(part);
1100 mpart = MPart->GetPdgCode();
1101 child1 = MPart->GetFirstDaughter();
1102 child2 = MPart->GetLastDaughter();
1110 e = MPart->Energy();
1112 // see pyedit in Pythia's text
1114 if (IsThisPartonsOrDiQuark(mpart)) continue;
1115 printf("%5i: %5i(%2i) px %5.1f py %5.1f pz %6.1f e %6.1f childs %5i,%5i \n",
1116 part, mpart, geantPdg, px, py, pz, e, child1, child2);
1118 // exclude partons (21 - gluon, 92 - string)
1121 // exclude neutrinous also ??
1122 if (fDebug >= 11 && pT>0.01)
1123 printf("\n part:%5d mpart %5d eta %9.2f phi %9.2f pT %9.2f ",
1124 part, mpart, eta, phi, pT);
1129 fPdgT[part] = mpart;
1133 if (child1 >= 0 && child1 < npart) continue;
1135 // printf("%4i -> %5i(%3i) px %6.1f py %6.1f pz %7.1f e %8.2f child1 %5i %s\n",
1136 // part, mpart, geantPdg, px, py, pz, e, child1, name.Data());
1143 if (TMath::Abs(eta) <= 0.9) fNChTpc++;
1145 if (eta > fEtaMax || eta < fEtaMin) continue;
1146 if (phi > fPhiMax || phi < fPhiMin ) continue;
1148 if(fK0N==0 ) { // exclude neutral hadrons
1149 if (mpart == kNeutron || mpart == kNeutronBar || mpart == kK0Long) continue;
1151 fTrackList[part] = 1;
1152 fLego->Fill(eta, phi, pT);
1155 printf("\n PX %8.2f PY %8.2f PZ %8.2f E %8.2f \n",
1158 if(fhChPartMultInTpc) fhChPartMultInTpc->Fill(fNChTpc);
1161 void AliEMCALJetFinder::FillFromPartons()
1163 // function under construction - 13-feb-2002 PAI
1166 printf("\n AliEMCALJetFinder::FillFromPartons()\n");
1170 if (!fLego) BookLego();
1173 // Access particle information
1174 Int_t npart = (gAlice->GetHeader())->GetNprimary();
1175 if (fDebug >= 2 || npart<=0)
1176 printf("\n AliEMCALJetFinder::FillFromPartons : npart %i\n", npart);
1177 fNt = 0; // for FindTracksInJetCone
1180 // Go through the partons
1182 for (Int_t part = 8; part < npart; part++) {
1183 TParticle *MPart = gAlice->Particle(part);
1184 Int_t mpart = MPart->GetPdgCode();
1185 // Int_t child1 = MPart->GetFirstDaughter();
1186 Float_t pT = MPart->Pt();
1187 // Float_t p = MPart->P();
1188 Float_t phi = MPart->Phi();
1189 Float_t eta = MPart->Eta();
1190 // Float_t theta = MPart->Theta();
1191 statusCode = MPart->GetStatusCode();
1193 // accept partons (21 - gluon, 92 - string)
1194 if (!(TMath::Abs(mpart) <= 6 || mpart == 21 ||mpart == 92)) continue;
1195 if (fDebug > 1 && pT>0.01)
1196 printf("\n part:%5d mpart %5d status %5d eta %8.2f phi %8.2f pT %8.2f ",
1197 part, mpart, statusCode, eta, phi, pT);
1198 // if (fDebug >= 3) MPart->Print();
1199 // accept partons before fragmentation - p.57 in Pythia manual
1200 // if(statusCode != 1) continue;
1202 if (eta > fEtaMax || eta < fEtaMin) continue;
1203 if (phi > fPhiMax || phi < fPhiMin ) continue;
1205 // if (child1 >= 0 && child1 < npart) continue;
1208 fLego->Fill(eta, phi, pT);
1214 void AliEMCALJetFinder::BuildTrackFlagTable() {
1216 // Method to generate a lookup table for TreeK particles
1217 // which are linked to hits in the EMCAL
1219 // --Author: J.L. Klay
1221 // Access hit information
1222 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
1224 TTree *TK = gAlice->TreeK(); // Get the number of entries in the kine tree
1225 Int_t nKTrks = (Int_t) TK->GetEntries(); // (Number of particles created somewhere)
1227 if(fTrackList) delete[] fTrackList; //Make sure we get rid of the old one
1228 fTrackList = new Int_t[nKTrks]; //before generating a new one
1230 for (Int_t i = 0; i < nKTrks; i++) { //Initialize members to 0
1234 TTree *treeH = gAlice->TreeH();
1235 Int_t ntracks = (Int_t) treeH->GetEntries();
1241 for (Int_t track=0; track<ntracks;track++) {
1242 gAlice->ResetHits();
1243 nbytes += treeH->GetEvent(track);
1249 for(AliEMCALHit* mHit=(AliEMCALHit*) pEMCAL->FirstHit(-1);
1251 mHit=(AliEMCALHit*) pEMCAL->NextHit())
1253 Int_t iTrk = mHit->Track(); // track number
1254 Int_t idprim = mHit->GetPrimary(); // primary particle
1256 //Determine the origin point of this particle - it made a hit in the EMCAL
1257 TParticle *trkPart = gAlice->Particle(iTrk);
1258 TParticlePDG *trkPdg = trkPart->GetPDG();
1259 Int_t trkCode = trkPart->GetPdgCode();
1261 if (trkCode < 10000) { //Big Ions cause problems for
1262 trkChg = trkPdg->Charge(); //this function. Since they aren't
1263 } else { //likely to make it very far, set
1264 trkChg = 0.0; //their charge to 0 for the Flag test
1266 Float_t vxTrk = trkPart->Vx();
1267 Float_t vyTrk = trkPart->Vy();
1268 Float_t vrTrk = TMath::Sqrt(vxTrk*vxTrk+vyTrk*vyTrk);
1269 fTrackList[iTrk] = SetTrackFlag(vrTrk,trkCode,trkChg);
1271 //Loop through the ancestry of the EMCAL entrance particles
1272 Int_t ancestor = trkPart->GetFirstMother(); //Get track's Mother
1273 while (ancestor != -1) {
1274 TParticle *ancPart = gAlice->Particle(ancestor); //get particle info on ancestor
1275 TParticlePDG *ancPdg = ancPart->GetPDG();
1276 Int_t ancCode = ancPart->GetPdgCode();
1278 if (ancCode < 10000) {
1279 ancChg = ancPdg->Charge();
1283 Float_t vxAnc = ancPart->Vx();
1284 Float_t vyAnc = ancPart->Vy();
1285 Float_t vrAnc = TMath::Sqrt(vxAnc*vxAnc+vyAnc*vyAnc);
1286 fTrackList[ancestor] = SetTrackFlag(vrAnc,ancCode,ancChg);
1287 ancestor = ancPart->GetFirstMother(); //Get the next ancestor
1290 //Determine the origin point of the primary particle associated with the hit
1291 TParticle *primPart = gAlice->Particle(idprim);
1292 TParticlePDG *primPdg = primPart->GetPDG();
1293 Int_t primCode = primPart->GetPdgCode();
1295 if (primCode < 10000) {
1296 primChg = primPdg->Charge();
1300 Float_t vxPrim = primPart->Vx();
1301 Float_t vyPrim = primPart->Vy();
1302 Float_t vrPrim = TMath::Sqrt(vxPrim*vxPrim+vyPrim*vyPrim);
1303 fTrackList[idprim] = SetTrackFlag(vrPrim,primCode,primChg);
1309 Int_t AliEMCALJetFinder
1310 ::SetTrackFlag(Float_t radius, Int_t code, Double_t charge) {
1316 if (charge == 0) neutral = 1;
1318 if (TMath::Abs(code) <= 6 ||
1320 code == 92) parton = 1;
1322 //It's not a parton, it's charged and it went through the TPC
1323 if (!parton && !neutral && radius <= 84.0) flag = 1;
1330 void AliEMCALJetFinder::SaveBackgroundEvent()
1332 // Saves the eta-phi lego and the tracklist
1336 (*fLegoB) = (*fLegoB) + (*fLego);
1338 printf("\n AliEMCALJetFinder::SaveBackgroundEvent() (fLegoB) %f = %f(fLego) \n",
1339 fLegoB->Integral(), fLego->Integral());
1342 if (fPtB) delete[] fPtB;
1343 if (fEtaB) delete[] fEtaB;
1344 if (fPhiB) delete[] fPhiB;
1345 if (fPdgB) delete[] fPdgB;
1346 if (fTrackListB) delete[] fTrackListB;
1348 fPtB = new Float_t[fNtS];
1349 fEtaB = new Float_t[fNtS];
1350 fPhiB = new Float_t[fNtS];
1351 fPdgB = new Int_t [fNtS];
1352 fTrackListB = new Int_t [fNtS];
1356 for (Int_t i = 0; i < fNt; i++) {
1357 if (!fTrackList[i]) continue;
1358 fPtB [fNtB] = fPtT [i];
1359 fEtaB[fNtB] = fEtaT[i];
1360 fPhiB[fNtB] = fPhiT[i];
1361 fPdgB[fNtB] = fPdgT[i];
1362 fTrackListB[fNtB] = 1;
1366 printf(" fNtB %i => fNtS %i #particles %i \n", fNtB, fNtS, fNt);
1369 void AliEMCALJetFinder::InitFromBackground()
1373 if (fDebug) printf("\n AliEMCALJetFinder::InitFromBackground() ");
1377 (*fLego) = (*fLego) + (*fLegoB);
1379 printf("\n AliEMCALJetFinder::SaveBackgroundEvent() (fLego) %f = %f(fLegoB) \n",
1380 fLego->Integral(), fLegoB->Integral());
1382 printf(" => fLego undefined \n");
1387 void AliEMCALJetFinder::FindTracksInJetCone()
1390 // Build list of tracks inside jet cone
1393 Int_t njet = Njets();
1394 for (Int_t nj = 0; nj < njet; nj++)
1396 Float_t etaj = JetEtaW(nj);
1397 Float_t phij = JetPhiW(nj);
1398 Int_t nT = 0; // number of associated tracks
1400 // Loop over particles in current event
1401 for (Int_t part = 0; part < fNt; part++) {
1402 if (!fTrackList[part]) continue;
1403 Float_t phi = fPhiT[part];
1404 Float_t eta = fEtaT[part];
1405 Float_t dr = TMath::Sqrt((etaj-eta)*(etaj-eta) +
1406 (phij-phi)*(phij-phi));
1407 if (dr < fConeRadius) {
1408 fTrackList[part] = nj+2;
1413 // Same for background event if available
1416 for (Int_t part = 0; part < fNtB; part++) {
1417 Float_t phi = fPhiB[part];
1418 Float_t eta = fEtaB[part];
1419 Float_t dr = TMath::Sqrt((etaj-eta)*(etaj-eta) +
1420 (phij-phi)*(phij-phi));
1421 fTrackListB[part] = 1;
1423 if (dr < fConeRadius) {
1424 fTrackListB[part] = nj+2;
1428 } // Background available ?
1430 Int_t nT0 = nT + nTB;
1431 printf("Total number of tracks %d\n", nT0);
1433 if (nT0 > 50) nT0 = 50;
1435 Float_t* ptT = new Float_t[nT0];
1436 Float_t* etaT = new Float_t[nT0];
1437 Float_t* phiT = new Float_t[nT0];
1438 Int_t* pdgT = new Int_t[nT0];
1443 for (Int_t part = 0; part < fNt; part++) {
1444 if (fTrackList[part] == nj+2) {
1446 for (j=iT-1; j>=0; j--) {
1447 if (fPtT[part] > ptT[j]) {
1452 for (j=iT-1; j>=index; j--) {
1453 ptT [j+1] = ptT [j];
1454 etaT[j+1] = etaT[j];
1455 phiT[j+1] = phiT[j];
1456 pdgT[j+1] = pdgT[j];
1458 ptT [index] = fPtT [part];
1459 etaT[index] = fEtaT[part];
1460 phiT[index] = fPhiT[part];
1461 pdgT[index] = fPdgT[part];
1463 } // particle associated
1464 if (iT > nT0) break;
1468 for (Int_t part = 0; part < fNtB; part++) {
1469 if (fTrackListB[part] == nj+2) {
1471 for (j=iT-1; j>=0; j--) {
1472 if (fPtB[part] > ptT[j]) {
1478 for (j=iT-1; j>=index; j--) {
1479 ptT [j+1] = ptT [j];
1480 etaT[j+1] = etaT[j];
1481 phiT[j+1] = phiT[j];
1482 pdgT[j+1] = pdgT[j];
1484 ptT [index] = fPtB [part];
1485 etaT[index] = fEtaB[part];
1486 phiT[index] = fPhiB[part];
1487 pdgT[index] = fPdgB[part];
1489 } // particle associated
1490 if (iT > nT0) break;
1492 } // Background available ?
1494 fJetT[nj]->SetTrackList(nT0, ptT, etaT, phiT, pdgT);
1503 Float_t AliEMCALJetFinder::PropagatePhi(Float_t pt, Float_t charge, Bool_t& curls)
1505 // Propagates phi angle to EMCAL radius
1507 static Float_t b = 0.0, rEMCAL = -1.0;
1510 b = gAlice->Field()->SolenoidField();
1511 // Get EMCAL radius in cm
1512 rEMCAL = AliEMCALGeometry::GetInstance()->GetIPDistance();
1513 printf("\nMagnetic field %f rEMCAL %f ", b, rEMCAL);
1522 Float_t rB = 3335.6 * pt / b; // [cm] (case of |charge|=1)
1524 // check if particle is curling below EMCAL
1525 if (2.*rB < rEMCAL) {
1530 // if not calculate delta phi
1531 Float_t phi = TMath::ACos(1.-rEMCAL*rEMCAL/(2.*rB*rB));
1532 dPhi = TMath::ATan2(1.-TMath::Cos(phi), TMath::Sin(phi));
1533 dPhi = -TMath::Sign(dPhi, charge);
1538 void hf1(Int_t& id, Float_t& x, Float_t& wgt)
1540 // dummy for hbook calls
1544 void AliEMCALJetFinder::DrawLego(Char_t *opt)
1547 void AliEMCALJetFinder::DrawLegoEMCAL(Char_t *opt)
1548 {fhLegoEMCAL->Draw(opt);}
1550 void AliEMCALJetFinder::DrawHistsForTuning(Int_t mode)
1552 static TPaveText *varLabel=0;
1554 fC1 = new TCanvas("C1","Hists. for tunning", 0,25,600,800);
1564 fhCellEMCALEt->Draw();
1569 fhTrackPtBcut->SetLineColor(2);
1570 fhTrackPtBcut->Draw("same");
1575 varLabel = new TPaveText(0.05,0.5,0.95,0.95,"NDC");
1576 varLabel->SetTextAlign(12);
1577 varLabel->SetFillColor(19); // see TAttFill
1578 TString tmp(GetTitle());
1579 varLabel->ReadFile(GetFileNameForParameters());
1583 if(mode) { // for saving picture to the file
1584 TString stmp(GetFileNameForParameters());
1585 stmp.ReplaceAll("_Par.txt",".ps");
1586 fC1->Print(stmp.Data());
1590 void AliEMCALJetFinder::PrintParameters(Int_t mode)
1593 if(mode==0) file = stdout; // output to terminal
1595 file = fopen(GetFileNameForParameters(),"w");
1596 if(file==0) file = stdout;
1598 fprintf(file,"==== Filling lego ==== \n");
1599 fprintf(file,"Smearing %6i ", fSmear);
1600 fprintf(file,"Efficiency %6i\n", fEffic);
1601 fprintf(file,"Hadr.Correct. %6i ", fHCorrection);
1602 fprintf(file,"P_{T} Cut of ch.par. %6.2f\n", fPtCut);
1603 fprintf(file,"==== Jet finding ==== \n");
1604 fprintf(file,"Cone radius %6.2f ", fConeRadius);
1605 fprintf(file,"Seed E_{T} %6.1f\n", fEtSeed);
1606 fprintf(file,"Min E_{T} of cell %6.1f ", fMinCellEt);
1607 fprintf(file,"Min E_{T} of jet %6.1f\n", fMinJetEt);
1609 fprintf(file,"==== Bg subtraction ==== \n");
1610 fprintf(file,"BG subtraction %6i ", fMode);
1611 fprintf(file,"Min cone move %6.2f\n", fMinMove);
1612 fprintf(file,"Max cone move %6.2f ", fMaxMove);
1613 fprintf(file,"%% change for BG %6.4f\n", fPrecBg);
1615 fprintf(file,"==== No Bg subtraction ==== \n");
1616 if(file != stdout) fclose(file);
1619 void AliEMCALJetFinder::DrawLegos()
1622 fC1 = new TCanvas("C1","Hists. for tunning", 0,25,600,800);
1626 gStyle->SetOptStat(111111);
1628 Int_t nent1, nent2, nent3, nent4;
1629 Double_t int1, int2, int3, int4;
1630 nent1 = (Int_t)fLego->GetEntries();
1631 int1 = fLego->Integral();
1633 if(int1) fLego->Draw("lego");
1635 nent2 = (Int_t)fhLegoTracks->GetEntries();
1636 int2 = fhLegoTracks->Integral();
1638 if(int2) fhLegoTracks->Draw("lego");
1640 nent3 = (Int_t)fhLegoEMCAL->GetEntries();
1641 int3 = fhLegoEMCAL->Integral();
1643 if(int3) fhLegoEMCAL->Draw("lego");
1645 nent4 = (Int_t)fhLegoHadrCorr->GetEntries();
1646 int4 = fhLegoHadrCorr->Integral();
1648 if(int4) fhLegoHadrCorr->Draw("lego");
1650 // just for checking
1651 printf(" Integrals \n");
1652 printf("lego %10.3f \ntrack %10.3f \nhits %10.3f \nHCorr %10.3f\n-- %10.3f(must be 0)\n",
1653 int1, int2, int3, int4, int1 - (int2 + int3 - int4));
1656 const Char_t* AliEMCALJetFinder::GetFileNameForParameters(Char_t* dir)
1659 if(strlen(dir)) tmp = dir;
1665 void AliEMCALJetFinder::RearrangeParticlesMemory(Int_t npart)
1666 { // See FillFromTracks() - npart must be positive
1667 if (fTrackList) delete[] fTrackList;
1668 if (fPtT) delete[] fPtT;
1669 if (fEtaT) delete[] fEtaT;
1670 if (fPhiT) delete[] fPhiT;
1671 if (fPdgT) delete[] fPdgT;
1674 fTrackList = new Int_t [npart];
1675 fPtT = new Float_t[npart];
1676 fEtaT = new Float_t[npart];
1677 fPhiT = new Float_t[npart];
1678 fPdgT = new Int_t[npart];
1680 printf("AliEMCALJetFinder::RearrangeParticlesMemory : npart = %d\n", npart);
1684 Bool_t AliEMCALJetFinder::IsThisPartonsOrDiQuark(Int_t pdg)
1686 Int_t absPdg = TMath::Abs(pdg);
1687 if(absPdg<=6) return kTRUE; // quarks
1688 if(pdg == 21) return kTRUE; // gluon
1689 if(pdg == 92) return kTRUE; // string
1691 // see p.51 of Pythia Manual
1692 // Not include diquarks with c and b quark - 4-mar-2002
1693 // ud_0,sd_0,su_0; dd_1,ud_1,uu_1; sd_1,su_1,ss_1
1694 static Int_t diquark[9]={2101,3101,3201, 1103,2103,2203, 3103,3203,3303};
1695 for(Int_t i=0; i<9; i++) if(absPdg == diquark[i]) return kTRUE; // diquarks
1700 void AliEMCALJetFinder::FindChargedJet()
1703 // Find jet from charged particle information only
1718 for (part = 0; part < fNt; part++) {
1719 if (!fTrackList[part]) continue;
1720 if (fPtT[part] > fEtSeed) nseed++;
1722 printf("\nThere are %d seeds (%d)\n", nseed, fNtS);
1723 Int_t* iSeeds = new Int_t[nseed];
1726 for (part = 0; part < fNt; part++) {
1727 if (!fTrackList[part]) continue;
1728 if (fPtT[part] > fEtSeed) iSeeds[nseed++] = part;
1739 // Find seed with highest pt
1741 Float_t ptmax = -1.;
1744 for (seed = 0; seed < nseed; seed++) {
1745 if ((pt = fPtT[iSeeds[seed]]) > ptmax && iSeeds[seed] != -1) {
1750 if (ptmax < 0.) break;
1751 jndex = iSeeds[index];
1753 // Remove from the list
1755 printf("\n Next Seed %d %f", jndex, ptmax);
1757 // Find tracks in cone around seed
1759 Float_t phiSeed = fPhiT[jndex];
1760 Float_t etaSeed = fEtaT[jndex];
1766 for (part = 0; part < fNt; part++) {
1767 if (!fTrackList[part]) continue;
1768 Float_t deta = fEtaT[part] - etaSeed;
1769 Float_t dphi = fPhiT[part] - phiSeed;
1770 Float_t dR = TMath::Sqrt(deta * deta + dphi * dphi);
1771 if (dR < fConeRadius) {
1773 Float_t theta = 2. * TMath::ATan(TMath::Exp(-fEtaT[part]));
1774 Float_t px = fPtT[part] * TMath::Cos(fPhiT[part]);
1775 Float_t py = fPtT[part] * TMath::Sin(fPhiT[part]);
1776 Float_t pz = fPtT[part] / TMath::Tan(theta);
1781 // if seed, remove it
1783 for (seed = 0; seed < nseed; seed++) {
1784 if (part == iSeeds[seed]) iSeeds[seed] = -1;
1790 // Estimate of jet direction
1791 Float_t phiJ = TMath::ATan2(pyJ, pxJ);
1792 Float_t thetaJ = TMath::ATan2(TMath::Sqrt(pxJ * pxJ + pyJ * pyJ), pzJ);
1793 Float_t etaJ = TMath::Log(TMath::Tan(thetaJ / 2.));
1794 Float_t ptJ = TMath::Sqrt(pxJ * pxJ + pyJ * pyJ);
1797 // Sum up all energy
1799 Int_t iPhi0 = Int_t((phiJ - fPhiMin) / fDphi);
1800 Int_t iEta0 = Int_t((etaJ - fEtaMin) / fDeta);
1801 Int_t dIphi = Int_t(fConeRadius / fDphi);
1802 Int_t dIeta = Int_t(fConeRadius / fDeta);
1805 for (iPhi = iPhi0 -dIphi; iPhi < iPhi0 + dIphi; iPhi++) {
1806 for (iEta = iEta0 - dIeta; iEta < iEta0 + dIeta; iEta++) {
1807 if (iPhi < 0 || iEta < 0) continue;
1808 Float_t dPhi = fPhiMin + iPhi * fDphi;
1809 Float_t dEta = fEtaMin + iEta * fDeta;
1810 if (TMath::Sqrt(dPhi * dPhi + dEta * dEta) < fConeRadius) continue;
1811 sumE += fLego->GetBinContent(iEta, iPhi);
1817 fJetT[njets++] = new AliEMCALJet(sumE, phiJ, etaJ);
1818 FindTracksInJetCone();
1819 printf("\n Jet Energy %f %f %f %f %d\n", eT, sumE, fPtT[6], fPtT[7], njets);
1820 printf("\n Jet Phi %f %f %f \n", phiJ, fPhiT[6], fPhiT[7]);
1821 printf("\n Jet Eta %f %f %f \n", etaJ, fEtaT[6], fEtaT[7]);
1823 EMCALJETS.njet = njets;
1824 if (fWrite) WriteJets();