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.19.2.5 2003/07/08 16:43:48 schutz
19 NewIO and remove AliEMCALReconstructionner
21 Revision 1.19.2.4 2003/07/07 14:13:31 schutz
25 Revision 1.40 2003/01/30 17:29:02 hristov
26 No default arguments in the implementation file
28 Revision 1.39 2003/01/29 00:34:51 pavlinov
29 fixed bug in FillFromHits
31 Revision 1.38 2003/01/28 16:08:11 morsch
32 Particle loading according to generator type.
34 Revision 1.37 2003/01/23 11:50:04 morsch
35 - option for adding energy of all particles (ich == 2)
36 - provisions for principle component analysis
39 Revision 1.36 2003/01/15 19:05:44 morsch
40 Updated selection in ReadFromTracks()
42 Revision 1.35 2003/01/15 04:59:38 morsch
43 - TPC eff. from AliEMCALFast
44 - Correction in PropagatePhi()
46 Revision 1.34 2003/01/14 10:50:18 alibrary
47 Cleanup of STEER coding conventions
49 Revision 1.33 2003/01/10 10:48:19 morsch
50 SetSamplingFraction() removed from constructor.
52 Revision 1.32 2003/01/10 10:26:40 morsch
53 Sampling fraction initialized from geometry class.
55 Revision 1.31 2003/01/08 17:13:41 schutz
56 added the HCAL section
58 Revision 1.30 2002/12/09 16:26:28 morsch
59 - Nummber of particles per jet increased to 1000
62 Revision 1.29 2002/11/21 17:01:40 alibrary
63 Removing AliMCProcess and AliMC
65 Revision 1.28 2002/11/20 14:13:16 morsch
66 - FindChargedJets() added.
67 - Destructor corrected.
68 - Geometry cuts taken from AliEMCALGeometry.
70 Revision 1.27 2002/11/15 17:39:10 morsch
71 GetPythiaParticleName removed.
73 Revision 1.26 2002/10/14 14:55:35 hristov
74 Merging the VirtualMC branch to the main development branch (HEAD)
76 Revision 1.20.4.3 2002/10/10 15:07:49 hristov
77 Updating VirtualMC to v3-09-02
79 Revision 1.25 2002/09/13 10:24:57 morsch
82 Revision 1.24 2002/09/13 10:21:13 morsch
85 Revision 1.23 2002/06/27 09:24:26 morsch
86 Uncomment the TH1::AddDirectory statement.
88 Revision 1.22 2002/05/22 13:48:43 morsch
89 Pdg code added to track list.
91 Revision 1.21 2002/04/27 07:43:08 morsch
92 Calculation of fDphi corrected (Renan Cabrera)
94 Revision 1.20 2002/03/12 01:06:23 pavlinov
95 Testin output from generator
97 Revision 1.19 2002/02/27 00:46:33 pavlinov
98 Added method FillFromParticles()
100 Revision 1.18 2002/02/21 08:48:59 morsch
101 Correction in FillFromHitFlaggedTrack. (Jennifer Klay)
103 Revision 1.17 2002/02/14 08:52:53 morsch
104 Major updates by Aleksei Pavlinov:
105 FillFromPartons, FillFromTracks, jetfinder configuration.
107 Revision 1.16 2002/02/08 11:43:05 morsch
108 SetOutputFileName(..) allows to specify an output file to which the
109 reconstructed jets are written. If not set output goes to input file.
110 Attention call Init() before processing.
112 Revision 1.15 2002/02/02 08:37:18 morsch
113 Formula for rB corrected.
115 Revision 1.14 2002/02/01 08:55:30 morsch
116 Fill map with Et and pT.
118 Revision 1.13 2002/01/31 09:37:36 morsch
119 Geometry parameters in constructor and call of SetCellSize()
121 Revision 1.12 2002/01/23 13:40:23 morsch
122 Fastidious debug print statement removed.
124 Revision 1.11 2002/01/22 17:25:47 morsch
125 Some corrections for event mixing and bg event handling.
127 Revision 1.10 2002/01/22 10:31:44 morsch
128 Some correction for bg mixing.
130 Revision 1.9 2002/01/21 16:28:42 morsch
131 Correct sign of dphi.
133 Revision 1.8 2002/01/21 16:05:31 morsch
134 - different phi-bin for hadron correction
135 - provisions for background mixing.
137 Revision 1.7 2002/01/21 15:47:18 morsch
138 Bending radius correctly in cm.
140 Revision 1.6 2002/01/21 12:53:50 morsch
143 Revision 1.5 2002/01/21 12:47:47 morsch
144 Possibility to include K0long and neutrons.
146 Revision 1.4 2002/01/21 11:03:21 morsch
147 Phi propagation introduced in FillFromTracks.
149 Revision 1.3 2002/01/18 05:07:56 morsch
150 - hadronic correction
152 - track selection upon EMCAL information
156 //*-- Authors: Andreas Morsch (CERN)
158 //* Aleksei Pavlinov (WSU)
164 #include <TBranchElement.h>
166 #include <TClonesArray.h>
171 #include <TPDGCode.h>
173 #include <TParticle.h>
174 #include <TParticlePDG.h>
175 #include <TPaveText.h>
176 #include <TPythia6Calls.h>
180 #include <TBrowser.h>
183 #include "AliEMCAL.h"
184 #include "AliEMCALDigit.h"
185 #include "AliEMCALDigitizer.h"
186 #include "AliEMCALFast.h"
187 #include "AliEMCALGeometry.h"
188 #include "AliEMCALHadronCorrection.h"
189 #include "AliEMCALHit.h"
190 #include "AliEMCALJetFinder.h"
191 #include "AliEMCALJetMicroDst.h"
192 #include "AliHeader.h"
194 #include "AliMagFCM.h"
196 #include "AliGenerator.h"
197 #include "AliEMCALGetter.h"
198 // Interface to FORTRAN
202 ClassImp(AliEMCALJetFinder)
204 //____________________________________________________________________________
205 AliEMCALJetFinder::AliEMCALJetFinder()
207 // Default constructor
226 fHadronCorrector = 0;
236 SetParametersForBgSubtraction();
239 AliEMCALJetFinder::AliEMCALJetFinder(const char* name, const char *title)
243 // Title is used in method GetFileNameForParameters();
245 fJets = new TClonesArray("AliEMCALJet",10000);
247 for (Int_t i = 0; i < 30000; i++)
269 fHadronCorrector = 0;
278 SetMomentumSmearing();
281 SetHadronCorrection();
285 SetParametersForBgSubtraction();
288 void AliEMCALJetFinder::SetParametersForBgSubtraction
289 (Int_t mode, Float_t minMove, Float_t maxMove, Float_t precBg)
291 // see file /home/pavlinov/cosmic/pythia/jetFinderParamData.inc
292 // at WSU Linux cluster - 11-feb-2002
293 // These parameters must be tuned more carefull !!!
300 //____________________________________________________________________________
301 AliEMCALJetFinder::~AliEMCALJetFinder()
313 delete fhLegoHadrCorr;
316 delete fhCellEMCALEt;
318 delete fhTrackPtBcut;
319 delete fhChPartMultInTpc;
327 delete[] fTrackListB;
335 # define jet_finder_ua1 jet_finder_ua1_
337 # define type_of_call
340 # define jet_finder_ua1 JET_FINDER_UA1
342 # define type_of_call _stdcall
345 extern "C" void type_of_call
346 jet_finder_ua1(Int_t& ncell, Int_t& ncell_tot,
347 Float_t etc[30000], Float_t etac[30000],
349 Float_t& min_move, Float_t& max_move, Int_t& mode,
350 Float_t& prec_bg, Int_t& ierror);
352 extern "C" void type_of_call hf1(Int_t& id, Float_t& x, Float_t& wgt);
355 void AliEMCALJetFinder::Init()
358 // Geometry and I/O initialization
362 // Get geometry parameters from EMCAL
366 //AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
367 // AliEMCALGeometry* geom =
368 // AliEMCALGeometry::GetInstance(pEMCAL->GetTitle(), "");
369 AliEMCALGetter * gime = AliEMCALGetter::Instance() ;
370 AliEMCALGeometry* geom = gime->EMCALGeometry() ;
372 // SetSamplingFraction(geom->GetSampling());
374 fNbinEta = geom->GetNZ();
375 fNbinPhi = geom->GetNPhi();
376 fPhiMin = geom->GetArm1PhiMin()*TMath::Pi()/180.;
377 fPhiMax = geom->GetArm1PhiMax()*TMath::Pi()/180.;
378 fEtaMin = geom->GetArm1EtaMin();
379 fEtaMax = geom->GetArm1EtaMax();
380 fDphi = (fPhiMax-fPhiMin)/fNbinPhi;
381 fDeta = (fEtaMax-fEtaMin)/fNbinEta;
382 fNtot = fNbinPhi*fNbinEta;
383 fWeightingMethod = kFALSE;
386 SetCellSize(fDeta, fDphi);
389 if (fOutFileName) fOutFile = new TFile(fOutFileName, "recreate");
394 void AliEMCALJetFinder::Find(Int_t ncell, Int_t ncell_tot, Float_t etc[30000],
395 Float_t etac[30000], Float_t phic[30000],
396 Float_t min_move, Float_t max_move, Int_t mode,
397 Float_t prec_bg, Int_t ierror)
399 // Wrapper for fortran coded jet finder
400 // Full argument list
401 jet_finder_ua1(ncell, ncell_tot, etc, etac, phic,
402 min_move, max_move, mode, prec_bg, ierror);
403 // Write result to output
404 if(fWrite) WriteJets();
408 void AliEMCALJetFinder::Find()
410 // Wrapper for fortran coded jet finder using member data for
413 Float_t min_move = fMinMove;
414 Float_t max_move = fMaxMove;
416 Float_t prec_bg = fPrecBg;
418 ResetJets(); // 4-feb-2002 by PAI
420 jet_finder_ua1(fNcell, fNtot, fEtCell, fEtaCell, fPhiCell,
421 min_move, max_move, mode, prec_bg, ierror);
423 // Write result to output
424 Int_t njet = Njets();
426 for (Int_t nj=0; nj<njet; nj++)
428 if (fWeightingMethod)
430 fJetT[nj] = new AliEMCALJet(WeightedJetEnergy( JetEtaW(nj),JetPhiW(nj) ),
436 fJetT[nj] = new AliEMCALJet(JetEnergy(nj),
440 fJetT[nj]->SetIsWeightedEnergy(fWeightingMethod);
441 fJetT[nj]->SetEMCALEnergy( EMCALConeEnergy(JetEtaW(nj),JetPhiW(nj)) );
442 fJetT[nj]->SetTrackEnergy(TrackConeEnergy( JetEtaW(nj),JetPhiW(nj) ));
443 fJetT[nj]->SetHCEnergy(HCConeEnergy( JetEtaW(nj),JetPhiW(nj) ));
447 FindTracksInJetCone();
448 if(fWrite) WriteJets();
453 Float_t AliEMCALJetFinder::EMCALConeEnergy(Float_t eta, Float_t phi)
455 Float_t newenergy = 0.0;
456 Float_t bineta,binphi;
457 TAxis *x = fhLegoEMCAL->GetXaxis();
458 TAxis *y = fhLegoEMCAL->GetYaxis();
459 for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
461 for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
463 bineta = x->GetBinCenter(i);
464 binphi = y->GetBinCenter(j);
465 if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
467 newenergy += fhLegoEMCAL->GetBinContent(i,j);
474 Float_t AliEMCALJetFinder::TrackConeEnergy(Float_t eta, Float_t phi)
476 Float_t newenergy = 0.0;
477 Float_t bineta,binphi;
478 TAxis *x = fhLegoTracks->GetXaxis();
479 TAxis *y = fhLegoTracks->GetYaxis();
480 for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
482 for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
484 bineta = x->GetBinCenter(i);
485 binphi = y->GetBinCenter(j);
486 if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
488 newenergy += fhLegoTracks->GetBinContent(i,j);
495 Float_t AliEMCALJetFinder::HCConeEnergy(Float_t eta, Float_t phi)
497 //Float_t newenergy = 0.0;
498 //Float_t bineta,binphi;
499 //TAxis *x = fhLegoTracks->GetXaxis();
500 //TAxis *y = fhLegoTracks->GetYaxis();
501 //for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
503 // for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
505 // bineta = x->GetBinCenter(i);
506 // binphi = y->GetBinCenter(j);
507 // if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
509 // newenergy += fhLegoTracks->GetBinContent(i,j);
521 Float_t AliEMCALJetFinder::WeightedJetEnergy(Float_t eta, Float_t phi)
525 Float_t newenergy = 0.0;
526 Float_t bineta,binphi;
527 TAxis *x = fhLegoEMCAL->GetXaxis();
528 TAxis *y = fhLegoEMCAL->GetYaxis();
531 for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
533 for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
535 bineta = x->GetBinCenter(i);
536 binphi = y->GetBinCenter(j);
537 if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
539 newenergy += (fEMCALWeight)* fhLegoEMCAL->GetBinContent(i,j) + (fTrackWeight)* fhLegoTracks->GetBinContent(i,j);
549 Int_t AliEMCALJetFinder::Njets()
551 // Get number of reconstructed jets
552 return EMCALJETS.njet;
555 Float_t AliEMCALJetFinder::JetEnergy(Int_t i)
557 // Get reconstructed jet energy
558 return EMCALJETS.etj[i];
561 Float_t AliEMCALJetFinder::JetPhiL(Int_t i)
563 // Get reconstructed jet phi from leading particle
564 return EMCALJETS.phij[0][i];
567 Float_t AliEMCALJetFinder::JetPhiW(Int_t i)
569 // Get reconstructed jet phi from weighting
570 return EMCALJETS.phij[1][i];
573 Float_t AliEMCALJetFinder::JetEtaL(Int_t i)
575 // Get reconstructed jet eta from leading particles
576 return EMCALJETS.etaj[0][i];
580 Float_t AliEMCALJetFinder::JetEtaW(Int_t i)
582 // Get reconstructed jet eta from weighting
583 return EMCALJETS.etaj[1][i];
586 void AliEMCALJetFinder::SetCellSize(Float_t eta, Float_t phi)
588 // Set grid cell size
589 EMCALCELLGEO.etaCellSize = eta;
590 EMCALCELLGEO.phiCellSize = phi;
593 void AliEMCALJetFinder::SetConeRadius(Float_t par)
595 // Set jet cone radius
596 EMCALJETPARAM.coneRad = par;
600 void AliEMCALJetFinder::SetEtSeed(Float_t par)
602 // Set et cut for seeds
603 EMCALJETPARAM.etSeed = par;
607 void AliEMCALJetFinder::SetMinJetEt(Float_t par)
609 // Set minimum jet et
610 EMCALJETPARAM.ejMin = par;
614 void AliEMCALJetFinder::SetMinCellEt(Float_t par)
616 // Set et cut per cell
617 EMCALJETPARAM.etMin = par;
621 void AliEMCALJetFinder::SetPtCut(Float_t par)
623 // Set pT cut on charged tracks
628 void AliEMCALJetFinder::Test()
631 // Test the finder call
633 const Int_t nmax = 30000;
635 Int_t ncell_tot = 100;
640 Float_t min_move = 0;
641 Float_t max_move = 0;
647 Find(ncell, ncell_tot, etc, etac, phic,
648 min_move, max_move, mode, prec_bg, ierror);
656 void AliEMCALJetFinder::AddJet(const AliEMCALJet& jet)
661 TClonesArray &lrawcl = *fJets;
662 new(lrawcl[fNjets++]) AliEMCALJet(jet);
665 void AliEMCALJetFinder::ResetJets()
674 void AliEMCALJetFinder::WriteJets()
677 // Add all jets to the list
679 const Int_t kBufferSize = 4000;
680 const char* file = 0;
682 Int_t njet = Njets();
684 for (Int_t nj = 0; nj < njet; nj++)
691 AliEMCALGetter * gime = AliEMCALGetter::Instance() ;
694 // output written to input file
696 AliEMCAL* pEMCAL = (AliEMCAL* )gAlice->GetModule("EMCAL");
697 TTree* pK = gAlice->TreeK();
698 file = (pK->GetCurrentFile())->GetName();
699 TBranch * jetBranch ;
701 printf("Make Branch - TreeR address %p %p\n",gAlice->TreeR(), pEMCAL);
702 //if (fJets && gAlice->TreeR()) {
703 if (fJets && gime->TreeR()) {
704 // pEMCAL->MakeBranchInTree(gAlice->TreeR(),
705 jetBranch = gime->TreeR()->Branch("EMCALJets", &fJets, kBufferSize, 0) ;
706 //pEMCAL->MakeBranchInTree(gime->TreeR(),
712 //Int_t nev = gAlice->GetHeader()->GetEvent();
713 //gAlice->TreeR()->Fill();
716 //sprintf(hname,"TreeR%d", nev);
717 //gAlice->TreeR()->Write(hname);
718 //gAlice->TreeR()->Reset();
719 gime->WriteRecPoints("OVERWRITE");
723 // Output written to user specified output file
725 //TTree* pK = gAlice->TreeK();
726 TTree* pK = gAlice->TreeK();
727 fInFile = pK->GetCurrentFile();
731 sprintf(hname,"TreeR%d", fEvent);
732 TTree* treeJ = new TTree(hname, "EMCALJets");
733 treeJ->Branch("EMCALJets", &fJets, kBufferSize);
741 void AliEMCALJetFinder::BookLego()
744 // Book histo for discretization
748 // Don't add histos to the current directory
749 if(fDebug) printf("\n AliEMCALJetFinder::BookLego() \n");
751 // TH2::AddDirectory(0); // hists wil be put to the list from gROOT
752 // TH1::AddDirectory(0);
756 fLego = new TH2F("legoH","eta-phi",
757 fNbinEta, fEtaMin, fEtaMax,
758 fNbinPhi, fPhiMin, fPhiMax);
761 fLegoB = new TH2F("legoB","eta-phi for BG event",
762 fNbinEta, fEtaMin, fEtaMax,
763 fNbinPhi, fPhiMin, fPhiMax);
766 fhLegoTracks = new TH2F("hLegoTracks","eta-phi for Tracks",
767 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
769 fhLegoEMCAL = new TH2F("hLegoEMCAL","eta-phi for EMCAL",
770 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
771 // Hadron correction map
772 fhLegoHadrCorr = new TH2F("hLegoHadrCorr","eta-phi for Hadron. Correction",
773 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
774 // Hists. for tuning jet finder
775 fhEff = new TH2F("hEff","#epsilon vs momentum ", 100,0.,20., 50,0.5,1.);
779 for(Int_t i=1; i<=1000; i++) eTmp[i] = 0.1*i; // step 100 mev
780 for(Int_t i=1001; i<=1100; i++) eTmp[i] = eTmp[1000] + 1.0*(i-1000); // step 1GeV
782 fhCellEt = new TH1F("hCellEt","Cell E_{T} from fLego",
783 eTmp.GetSize()-1, eTmp.GetArray());
784 fhCellEMCALEt = new TH1F("hCellEMCALEt","Cell E_{T} for EMCAL itself",
785 eTmp.GetSize()-1, eTmp.GetArray());
786 fhTrackPt = new TH1F("hTrackPt","Ch.particles P_{T} ",
787 eTmp.GetSize()-1, eTmp.GetArray());
788 fhTrackPtBcut = new TH1F("hTrackPtBcut","Ch.particles P_{T} + magnetic field cut",
789 eTmp.GetSize()-1, eTmp.GetArray());
791 fhChPartMultInTpc = new TH1F("hChPartMultInTpc",
792 "Charge partilcle multiplicity in |%eta|<0.9", 2000, 0, 20000);
794 fhSinTheta = new TH1F("fhSinTheta","sin(theta)", fNbinEta, fEtaMin, fEtaMax);
795 TAxis *xax = fhSinTheta->GetXaxis();
796 for(Int_t i=1; i<=fNbinEta; i++) {
797 Double_t eta = xax->GetBinCenter(i);
798 fhSinTheta->Fill(eta, 1./TMath::CosH(eta)); // cosh(eta) = 1./sin(theta)
801 //! first canvas for drawing
802 fHistsList=AliEMCALJetMicroDst::MoveHistsToList("Hists from AliEMCALJetFinder", kFALSE);
805 void AliEMCALJetFinder::DumpLego()
808 // Dump lego histo into array
811 TAxis* Xaxis = fLego->GetXaxis();
812 TAxis* Yaxis = fLego->GetYaxis();
813 // fhCellEt->Clear();
815 for (Int_t i = 1; i <= fNbinEta; i++) {
816 for (Int_t j = 1; j <= fNbinPhi; j++) {
818 e = fLego->GetBinContent(i,j);
820 if (gRandom->Rndm() < 0.5) {
821 Float_t ebg = 0.28 * TMath::Abs(gRandom->Gaus(0.,1.));
825 if (e > 0.0) e -= fMinCellEt;
827 Float_t eta = Xaxis->GetBinCenter(i);
828 Float_t phi = Yaxis->GetBinCenter(j);
830 fEtaCell[fNcell] = eta;
831 fPhiCell[fNcell] = phi;
835 eH = fhLegoEMCAL->GetBinContent(i,j);
836 if(eH > 0.0) fhCellEMCALEt->Fill(eH);
844 void AliEMCALJetFinder::ResetMap()
847 // Reset eta-phi array
849 for (Int_t i=0; i<30000; i++)
858 void AliEMCALJetFinder::FillFromTracks(Int_t flag, Int_t ich)
862 const char* name = gAlice->Generator()->GetName();
863 enum {kPythia, kHijing, kHijingPara};
866 if (!strcmp(name, "Hijing")){
868 } else if (!strcmp(name, "Pythia")) {
870 } else if (!strcmp(name, "HIJINGpara") ||!strcmp(name, "HIGINGpara")) {
871 genType = kHijingPara;
874 printf("Fill tracks generated by %s %d\n", name, genType);
878 // Fill Cells with track information
881 printf("\n AliEMCALJetFinder::FillFromTracks(%i,%i) ",flag,ich);
886 if (!fLego) BookLego();
888 if (flag == 0) fLego->Reset();
890 // Access particle information
891 Int_t npart = (gAlice->GetHeader())->GetNprimary();
892 Int_t ntr = (gAlice->GetHeader())->GetNtrack();
893 printf(" : #primary particles %i # tracks %i : (before) Sum.Et %f\n",
894 npart, ntr, fLego->Integral());
899 // 1: selected for jet finding
902 if (fTrackList) delete[] fTrackList;
903 if (fPtT) delete[] fPtT;
904 if (fEtaT) delete[] fEtaT;
905 if (fPhiT) delete[] fPhiT;
906 if (fPdgT) delete[] fPdgT;
908 fTrackList = new Int_t [npart];
909 fPtT = new Float_t[npart];
910 fEtaT = new Float_t[npart];
911 fPhiT = new Float_t[npart];
912 fPdgT = new Int_t[npart];
916 Float_t chTmp=0.0; // charge of current particle
919 // this is for Pythia ??
920 for (Int_t part = 0; part < npart; part++) {
921 TParticle *MPart = gAlice->Particle(part);
922 Int_t mpart = MPart->GetPdgCode();
923 Int_t child1 = MPart->GetFirstDaughter();
924 Float_t pT = MPart->Pt();
925 Float_t p = MPart->P();
926 Float_t phi = MPart->Phi();
928 if(pT > 0.001) eta = MPart->Eta();
929 Float_t theta = MPart->Theta();
930 if (fDebug>=2 && MPart->GetStatusCode()==1) {
931 printf("ind %7i part %7i -> child1 %5i child2 %5i Status %5i\n",
932 part, mpart, child1, MPart->GetLastDaughter(), MPart->GetStatusCode());
935 if (fDebug >= 2 && genType == kPythia) {
936 if (part == 6 || part == 7)
938 printf("\n Simulated Jet (pt, eta, phi): %d %f %f %f\n",
939 part-5, pT, eta, phi);
943 fTrackList[part] = 0;
944 fPtT[part] = pT; // must be change after correction for resolution !!!
949 // final state particles only
951 if (genType == kPythia) {
952 if (MPart->GetStatusCode() != 1) continue;
953 } else if (genType == kHijing) {
954 if (child1 >= 0 && child1 < npart) continue;
958 TParticlePDG* pdgP = 0;
959 // charged or neutral
960 pdgP = MPart->GetPDG();
961 chTmp = pdgP->Charge() / 3.; // 13-feb-2001!!
968 if (mpart != kNeutron &&
969 mpart != kNeutronBar &&
970 mpart != kK0Long) continue;
973 } else if (ich == 2) {
974 if (mpart == kNeutron ||
975 mpart == kNeutronBar ||
976 mpart == kK0Long) continue;
979 if (TMath::Abs(eta)<=0.9) fNChTpc++;
981 if (child1 >= 0 && child1 < npart) continue;
983 if (eta > fEtaMax || eta < fEtaMin) continue;
984 if (phi > fPhiMax || phi < fPhiMin ) continue;
987 printf("\n=>nsel:%5d mpart %5d child1 %5d eta %6.2f phi %6.2f pT %6.2f ch %3.0f ",
988 part, mpart, child1, eta, phi, pT, chTmp);
991 // Momentum smearing goes here ...
995 if (fSmear && TMath::Abs(chTmp)) {
996 pw = AliEMCALFast::SmearMomentum(1,p);
997 // p changed - take into account when calculate pT,
1000 if(fDebug >= 4) printf("\n Smearing : p %8.4f change to %8.4f ", p, pw);
1004 // Tracking Efficiency and TPC acceptance goes here ...
1006 if (fEffic && TMath::Abs(chTmp)) {
1007 eff = 0.9; // AliEMCALFast::Efficiency(2,p);
1008 if(fhEff) fhEff->Fill(p, eff);
1009 if (AliEMCALFast::RandomReject(eff)) {
1010 if(fDebug >= 5) printf(" reject due to unefficiency ");
1015 // Correction of Hadronic Energy goes here ...
1018 // phi propagation for hadronic correction
1020 Bool_t curls = kFALSE; // hit two the EMCAL (no curl)
1021 Float_t phiHC=0.0, dpH=0.0, dphi=0.0, eTdpH=0;
1022 if(TMath::Abs(chTmp)) {
1023 // hadr. correction only for charge particle
1024 dphi = PropagatePhi(pT, chTmp, curls);
1027 printf("\n Delta phi %f pT %f ", dphi, pT);
1028 if (curls) printf("\n !! Track is curling");
1030 if(!curls) fhTrackPtBcut->Fill(pT);
1032 if (fHCorrection && !curls) {
1033 if (!fHadronCorrector)
1034 Fatal("AliEMCALJetFinder",
1035 "Hadronic energy correction required but not defined !");
1037 dpH = fHadronCorrector->GetEnergy(p, eta, 7);
1038 eTdpH = dpH*TMath::Sin(theta);
1040 if (fDebug >= 7) printf(" phi %f phiHC %f eTcorr %f\n",
1041 phi, phiHC, -eTdpH); // correction is negative
1043 xbin = fLego->GetXaxis()->FindBin(eta);
1044 ybin = fLego->GetYaxis()->FindBin(phiHC);
1045 cout <<"Hadron Correction affected bin - contents before correction : "<<fLego->GetBinContent(xbin,ybin)<<endl;
1046 fLego->Fill(eta, phi, -fSamplingF*eTdpH );
1047 cout <<"Hadron Correction affected bin - contents after correction : "<<fLego->GetBinContent(xbin,ybin)<<endl;
1048 fhLegoHadrCorr->Fill(eta, phi, fSamplingF*eTdpH);
1052 // More to do ? Just think about it !
1054 if (phi > fPhiMax || phi < fPhiMin ) continue;
1056 if(TMath::Abs(chTmp) ) { // charge particle
1057 if (pT > fPtCut && !curls) {
1058 if (fDebug >= 8) printf("Charge : fLego->Fill(%5.2f, %5.2f, %6.2f, %d)\n",
1059 eta , phi, pT, fNtS);
1060 fLego->Fill(eta, phi, pT);
1061 fhLegoTracks->Fill(eta, phi, pT); // 20-feb for checking
1062 fTrackList[part] = 1;
1065 } else if(ich > 0 || fK0N) {
1066 // case of n, nbar and K0L
1067 if (fDebug >= 9) printf("Neutral : fLego->Fill(%5.2f, %5.2f, %6.2f, %d)\n",
1068 eta , phi, pT, fNtS);
1069 fLego->Fill(eta, phi, pT);
1070 fTrackList[part] = 1;
1075 for(Int_t i=0; i<fLego->GetSize(); i++) {
1076 Float_t etc = (*fLego)[i];
1077 if (etc > fMinCellEt) etsum += etc;
1080 printf("FillFromTracks: Sum above threshold %f -> %f (%f)\n", fMinCellEt, etsum, fLego->Integral());
1081 printf(" Track selected(fNtS) %i \n", fNtS);
1086 void AliEMCALJetFinder::FillFromHits(Int_t flag)
1089 // Fill Cells with hit information
1093 printf("\n AliEMCALJetFinder::FillFromHits(%i)\n",flag);
1097 if (!fLego) BookLego();
1098 // Reset eta-phi maps if needed
1099 if (flag == 0) { // default behavior
1101 fhLegoTracks->Reset();
1102 fhLegoEMCAL->Reset();
1103 fhLegoHadrCorr->Reset();
1105 // Initialize from background event if available
1107 // Access hit information
1108 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
1109 AliEMCALGetter * gime = AliEMCALGetter::Instance() ;
1110 TTree *treeH = gime->TreeH();
1111 Int_t ntracks = (Int_t) treeH->GetEntries();
1116 // Double_t etH = 0.0;
1118 for (Int_t track=0; track<ntracks;track++) {
1119 gAlice->ResetHits();
1120 nbytes += treeH->GetEvent(track);
1124 for(AliEMCALHit* mHit=(AliEMCALHit*) pEMCAL->FirstHit(-1);
1126 mHit=(AliEMCALHit*) pEMCAL->NextHit())
1128 Float_t x = mHit->X(); // x-pos of hit
1129 Float_t y = mHit->Y(); // y-pos
1130 Float_t z = mHit->Z(); // z-pos
1131 Float_t eloss = mHit->GetEnergy(); // deposited energy
1133 Float_t r = TMath::Sqrt(x*x+y*y);
1134 Float_t theta = TMath::ATan2(r,z);
1135 Float_t eta = -TMath::Log(TMath::Tan(theta/2.));
1136 Float_t phi = TMath::ATan2(y,x);
1138 if (fDebug >= 21) printf("\n Hit %f %f %f %f %f %f %f %f", x, y, z, eloss, r, eta, phi, fSamplingF);
1140 // etH = fSamplingF*eloss*TMath::Sin(theta);
1141 fLego->Fill(eta, phi, eloss);
1145 // Transition from deposit energy to eT (eT = de*SF*sin(theta))
1147 for(Int_t i=1; i<=fLego->GetNbinsX(); i++){ // eta
1148 Double_t sinTheta = fhSinTheta->GetBinContent(i), eT=0;
1149 for(Int_t j=1; j<=fLego->GetNbinsY(); j++){ // phi
1150 eT = fLego->GetBinContent(i,j)*fSamplingF*sinTheta;
1151 fLego->SetBinContent(i,j,eT);
1152 // copy content of fLego to fhLegoEMCAL (fLego and fhLegoEMCAL are identical)
1153 fhLegoEMCAL->SetBinContent(i,j,eT);
1154 if (eT > fMinCellEt) etsum += eT;
1158 // for(Int_t i=0; i<fLego->GetSize(); i++) {
1159 // (*fhLegoEMCAL)[i] = (*fLego)[i];
1160 // Float_t etc = (*fLego)[i];
1161 // if (etc > fMinCellEt) etsum += etc;
1164 printf("FillFromHits: Sum above threshold %f -> %f \n ", fMinCellEt, etsum);
1168 void AliEMCALJetFinder::FillFromDigits(Int_t flag)
1171 // Fill Cells with digit information
1176 if (!fLego) BookLego();
1177 if (flag == 0) fLego->Reset();
1184 TClonesArray* digs = new TClonesArray("AliEMCALDigit", 10000);
1185 TTree *treeD = gAlice->TreeD();
1186 TBranchElement* branchDg = (TBranchElement*)
1187 treeD->GetBranch("EMCAL");
1189 if (!branchDg) Fatal("AliEMCALJetFinder",
1190 "Reading digits requested but no digits in file !");
1192 branchDg->SetAddress(&digs);
1193 Int_t nent = (Int_t) branchDg->GetEntries();
1195 // Connect digitizer
1197 AliEMCALDigitizer* digr = new AliEMCALDigitizer();
1198 TBranchElement* branchDr = (TBranchElement*)
1199 treeD->GetBranch("AliEMCALDigitizer");
1200 branchDr->SetAddress(&digr);
1203 nbytes += branchDg->GetEntry(0);
1204 nbytes += branchDr->GetEntry(0);
1206 // Get digitizer parameters
1207 Float_t preADCped = digr->GetPREpedestal();
1208 Float_t preADCcha = digr->GetPREchannel();
1209 Float_t ecADCped = digr->GetECApedestal();
1210 Float_t ecADCcha = digr->GetECAchannel();
1211 Float_t hcADCped = digr->GetHCApedestal();
1212 Float_t hcADCcha = digr->GetHCAchannel();
1214 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
1215 AliEMCALGeometry* geom =
1216 AliEMCALGeometry::GetInstance(pEMCAL->GetTitle(), "");
1219 Int_t ndig = digs->GetEntries();
1220 Info("FillFromDigits","Number of Digits: %d %d\n Parameters: PRE : %f %f EC: %f %f HC: %f %f\n Geometry: %d %d",
1221 ndig, nent, preADCped, preADCcha, ecADCped, ecADCcha, hcADCped, hcADCcha, geom->GetNEta(), geom->GetNPhi());
1228 while ((sdg = (AliEMCALDigit*)(next())))
1230 Double_t pedestal = 0.;
1231 Double_t channel = 0.;
1232 if (geom->IsInPRE(sdg->GetId())) {
1233 pedestal = preADCped;
1234 channel = preADCcha;
1236 else if (geom->IsInECA(sdg->GetId())) {
1237 pedestal = ecADCped;
1240 else if (geom->IsInHCA(sdg->GetId())) {
1241 pedestal = hcADCped;
1245 Fatal("FillFromDigits", "unexpected digit is number!") ;
1247 Float_t eta = sdg->GetEta();
1248 Float_t phi = sdg->GetPhi() * TMath::Pi()/180.;
1249 Float_t amp = (Float_t) (channel*(sdg->GetAmp())-pedestal);
1252 Info("FillFromDigits", "Digit: eta %8.3f phi %8.3f amp %8.3f %8d",
1253 eta, phi, amp, sdg->GetAmp());
1255 fLego->Fill(eta, phi, fSamplingF*amp);
1263 void AliEMCALJetFinder::FillFromHitFlaggedTracks(Int_t flag)
1266 // Fill Cells with hit information
1271 if (!fLego) BookLego();
1273 if (flag == 0) fLego->Reset();
1275 // Flag charged tracks passing through TPC which
1276 // are associated to EMCAL Hits
1277 BuildTrackFlagTable();
1280 // Access particle information
1281 TTree *treeK = gAlice->TreeK();
1282 Int_t ntracks = (Int_t) treeK->GetEntries();
1284 if (fPtT) delete[] fPtT;
1285 if (fEtaT) delete[] fEtaT;
1286 if (fPhiT) delete[] fPhiT;
1287 if (fPdgT) delete[] fPdgT;
1289 fPtT = new Float_t[ntracks];
1290 fEtaT = new Float_t[ntracks];
1291 fPhiT = new Float_t[ntracks];
1292 fPdgT = new Int_t[ntracks];
1297 for (Int_t track = 0; track < ntracks; track++) {
1298 TParticle *MPart = gAlice->Particle(track);
1299 Float_t pT = MPart->Pt();
1300 Float_t phi = MPart->Phi();
1301 Float_t eta = MPart->Eta();
1303 if(fTrackList[track]) {
1307 fPdgT[track] = MPart->GetPdgCode();
1309 if (track < 2) continue; //Colliding particles?
1310 if (pT == 0 || pT < fPtCut) continue;
1312 fLego->Fill(eta, phi, pT);
1318 void AliEMCALJetFinder::FillFromParticles()
1320 // 26-feb-2002 PAI - for checking all chain
1321 // Work on particles level; accept all particle (not neutrino )
1323 Double_t PX=0, PY=0, PZ=0, E=0; // checking conservation law
1327 if (!fLego) BookLego();
1330 // Access particles information
1331 Int_t npart = (gAlice->GetHeader())->GetNprimary();
1332 if (fDebug >= 2 || npart<=0) {
1333 printf(" AliEMCALJetFinder::FillFromParticles : npart %i\n", npart);
1334 if(npart<=0) return;
1338 RearrangeParticlesMemory(npart);
1340 // Go through the particles
1341 Int_t mpart, child1, child2, geantPdg;
1342 Float_t pT, phi, eta, e=0, px=0, py=0, pz=0;
1344 for (Int_t part = 0; part < npart; part++) {
1346 fTrackList[part] = 0;
1348 MPart = gAlice->Particle(part);
1349 mpart = MPart->GetPdgCode();
1350 child1 = MPart->GetFirstDaughter();
1351 child2 = MPart->GetLastDaughter();
1359 e = MPart->Energy();
1361 // see pyedit in Pythia's text
1363 if (IsThisPartonsOrDiQuark(mpart)) continue;
1364 printf("%5i: %5i(%2i) px %5.1f py %5.1f pz %6.1f e %6.1f childs %5i,%5i \n",
1365 part, mpart, geantPdg, px, py, pz, e, child1, child2);
1367 // exclude partons (21 - gluon, 92 - string)
1370 // exclude neutrinous also ??
1371 if (fDebug >= 11 && pT>0.01)
1372 printf("\n part:%5d mpart %5d eta %9.2f phi %9.2f pT %9.2f ",
1373 part, mpart, eta, phi, pT);
1378 fPdgT[part] = mpart;
1382 if (child1 >= 0 && child1 < npart) continue;
1384 // printf("%4i -> %5i(%3i) px %6.1f py %6.1f pz %7.1f e %8.2f child1 %5i %s\n",
1385 // part, mpart, geantPdg, px, py, pz, e, child1, name.Data());
1392 if (TMath::Abs(eta) <= 0.9) fNChTpc++;
1394 if (eta > fEtaMax || eta < fEtaMin) continue;
1395 if (phi > fPhiMax || phi < fPhiMin ) continue;
1397 if(fK0N==0 ) { // exclude neutral hadrons
1398 if (mpart == kNeutron || mpart == kNeutronBar || mpart == kK0Long) continue;
1400 fTrackList[part] = 1;
1401 fLego->Fill(eta, phi, pT);
1404 printf("\n PX %8.2f PY %8.2f PZ %8.2f E %8.2f \n",
1407 if(fhChPartMultInTpc) fhChPartMultInTpc->Fill(fNChTpc);
1410 void AliEMCALJetFinder::FillFromPartons()
1412 // function under construction - 13-feb-2002 PAI
1415 printf("\n AliEMCALJetFinder::FillFromPartons()\n");
1419 if (!fLego) BookLego();
1422 // Access particle information
1423 Int_t npart = (gAlice->GetHeader())->GetNprimary();
1424 if (fDebug >= 2 || npart<=0)
1425 printf("\n AliEMCALJetFinder::FillFromPartons : npart %i\n", npart);
1426 fNt = 0; // for FindTracksInJetCone
1429 // Go through the partons
1431 for (Int_t part = 8; part < npart; part++) {
1432 TParticle *MPart = gAlice->Particle(part);
1433 Int_t mpart = MPart->GetPdgCode();
1434 // Int_t child1 = MPart->GetFirstDaughter();
1435 Float_t pT = MPart->Pt();
1436 // Float_t p = MPart->P();
1437 Float_t phi = MPart->Phi();
1438 Float_t eta = MPart->Eta();
1439 // Float_t theta = MPart->Theta();
1440 statusCode = MPart->GetStatusCode();
1442 // accept partons (21 - gluon, 92 - string)
1443 if (!(TMath::Abs(mpart) <= 6 || mpart == 21 ||mpart == 92)) continue;
1444 if (fDebug > 1 && pT>0.01)
1445 printf("\n part:%5d mpart %5d status %5d eta %8.2f phi %8.2f pT %8.2f ",
1446 part, mpart, statusCode, eta, phi, pT);
1447 // if (fDebug >= 3) MPart->Print();
1448 // accept partons before fragmentation - p.57 in Pythia manual
1449 // if(statusCode != 1) continue;
1451 if (eta > fEtaMax || eta < fEtaMin) continue;
1452 if (phi > fPhiMax || phi < fPhiMin ) continue;
1454 // if (child1 >= 0 && child1 < npart) continue;
1457 fLego->Fill(eta, phi, pT);
1463 void AliEMCALJetFinder::BuildTrackFlagTable() {
1465 // Method to generate a lookup table for TreeK particles
1466 // which are linked to hits in the EMCAL
1468 // --Author: J.L. Klay
1470 // Access hit information
1471 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
1473 TTree *TK = gAlice->TreeK(); // Get the number of entries in the kine tree
1474 Int_t nKTrks = (Int_t) TK->GetEntries(); // (Number of particles created somewhere)
1476 if(fTrackList) delete[] fTrackList; //Make sure we get rid of the old one
1477 fTrackList = new Int_t[nKTrks]; //before generating a new one
1479 for (Int_t i = 0; i < nKTrks; i++) { //Initialize members to 0
1483 AliEMCALGetter * gime = AliEMCALGetter::Instance() ;
1484 // TTree *treeH = gAlice->TreeH();
1485 TTree *treeH = gime->TreeH();
1486 Int_t ntracks = (Int_t) treeH->GetEntries();
1492 for (Int_t track=0; track<ntracks;track++) {
1493 gAlice->ResetHits();
1494 nbytes += treeH->GetEvent(track);
1500 for(AliEMCALHit* mHit=(AliEMCALHit*) pEMCAL->FirstHit(-1);
1502 mHit=(AliEMCALHit*) pEMCAL->NextHit())
1504 Int_t iTrk = mHit->Track(); // track number
1505 Int_t idprim = mHit->GetPrimary(); // primary particle
1507 //Determine the origin point of this particle - it made a hit in the EMCAL
1508 TParticle *trkPart = gAlice->Particle(iTrk);
1509 TParticlePDG *trkPdg = trkPart->GetPDG();
1510 Int_t trkCode = trkPart->GetPdgCode();
1512 if (trkCode < 10000) { //Big Ions cause problems for
1513 trkChg = trkPdg->Charge(); //this function. Since they aren't
1514 } else { //likely to make it very far, set
1515 trkChg = 0.0; //their charge to 0 for the Flag test
1517 Float_t vxTrk = trkPart->Vx();
1518 Float_t vyTrk = trkPart->Vy();
1519 Float_t vrTrk = TMath::Sqrt(vxTrk*vxTrk+vyTrk*vyTrk);
1520 fTrackList[iTrk] = SetTrackFlag(vrTrk,trkCode,trkChg);
1522 //Loop through the ancestry of the EMCAL entrance particles
1523 Int_t ancestor = trkPart->GetFirstMother(); //Get track's Mother
1524 while (ancestor != -1) {
1525 TParticle *ancPart = gAlice->Particle(ancestor); //get particle info on ancestor
1526 TParticlePDG *ancPdg = ancPart->GetPDG();
1527 Int_t ancCode = ancPart->GetPdgCode();
1529 if (ancCode < 10000) {
1530 ancChg = ancPdg->Charge();
1534 Float_t vxAnc = ancPart->Vx();
1535 Float_t vyAnc = ancPart->Vy();
1536 Float_t vrAnc = TMath::Sqrt(vxAnc*vxAnc+vyAnc*vyAnc);
1537 fTrackList[ancestor] = SetTrackFlag(vrAnc,ancCode,ancChg);
1538 ancestor = ancPart->GetFirstMother(); //Get the next ancestor
1541 //Determine the origin point of the primary particle associated with the hit
1542 TParticle *primPart = gAlice->Particle(idprim);
1543 TParticlePDG *primPdg = primPart->GetPDG();
1544 Int_t primCode = primPart->GetPdgCode();
1546 if (primCode < 10000) {
1547 primChg = primPdg->Charge();
1551 Float_t vxPrim = primPart->Vx();
1552 Float_t vyPrim = primPart->Vy();
1553 Float_t vrPrim = TMath::Sqrt(vxPrim*vxPrim+vyPrim*vyPrim);
1554 fTrackList[idprim] = SetTrackFlag(vrPrim,primCode,primChg);
1560 Int_t AliEMCALJetFinder
1561 ::SetTrackFlag(Float_t radius, Int_t code, Double_t charge) {
1567 if (charge == 0) neutral = 1;
1569 if (TMath::Abs(code) <= 6 ||
1571 code == 92) parton = 1;
1573 //It's not a parton, it's charged and it went through the TPC
1574 if (!parton && !neutral && radius <= 84.0) flag = 1;
1581 void AliEMCALJetFinder::SaveBackgroundEvent(Char_t *name)
1583 // Saves the eta-phi lego and the tracklist and name of file with BG events
1587 (*fLegoB) = (*fLegoB) + (*fLego);
1589 printf("\n AliEMCALJetFinder::SaveBackgroundEvent() (fLegoB) %f = %f(fLego) \n",
1590 fLegoB->Integral(), fLego->Integral());
1593 if (fPtB) delete[] fPtB;
1594 if (fEtaB) delete[] fEtaB;
1595 if (fPhiB) delete[] fPhiB;
1596 if (fPdgB) delete[] fPdgB;
1597 if (fTrackListB) delete[] fTrackListB;
1599 fPtB = new Float_t[fNtS];
1600 fEtaB = new Float_t[fNtS];
1601 fPhiB = new Float_t[fNtS];
1602 fPdgB = new Int_t [fNtS];
1603 fTrackListB = new Int_t [fNtS];
1607 for (Int_t i = 0; i < fNt; i++) {
1608 if (!fTrackList[i]) continue;
1609 fPtB [fNtB] = fPtT [i];
1610 fEtaB[fNtB] = fEtaT[i];
1611 fPhiB[fNtB] = fPhiT[i];
1612 fPdgB[fNtB] = fPdgT[i];
1613 fTrackListB[fNtB] = 1;
1617 printf(" fNtB %i => fNtS %i #particles %i \n", fNtB, fNtS, fNt);
1619 if(strlen(name) == 0) {
1620 TSeqCollection *li = gROOT->GetListOfFiles();
1622 for(Int_t i=0; i<li->GetSize(); i++) {
1623 nf = ((TFile*)li->At(i))->GetName();
1624 if(nf.Contains("backgorund")) break;
1630 printf("BG file name is \n %s\n", fBGFileName.Data());
1633 void AliEMCALJetFinder::InitFromBackground()
1637 if (fDebug) printf("\n AliEMCALJetFinder::InitFromBackground() ");
1641 (*fLego) = (*fLego) + (*fLegoB);
1643 printf("\n AliEMCALJetFinder::InitBackgroundEvent() (fLego) %f = %f(fLegoB) \n",
1644 fLego->Integral(), fLegoB->Integral());
1646 printf(" => fLego undefined \n");
1651 void AliEMCALJetFinder::FindTracksInJetCone()
1654 // Build list of tracks inside jet cone
1657 Int_t njet = Njets();
1658 for (Int_t nj = 0; nj < njet; nj++)
1660 Float_t etaj = JetEtaW(nj);
1661 Float_t phij = JetPhiW(nj);
1662 Int_t nT = 0; // number of associated tracks
1664 // Loop over particles in current event
1665 for (Int_t part = 0; part < fNt; part++) {
1666 if (!fTrackList[part]) continue;
1667 Float_t phi = fPhiT[part];
1668 Float_t eta = fEtaT[part];
1669 Float_t dr = TMath::Sqrt((etaj-eta)*(etaj-eta) +
1670 (phij-phi)*(phij-phi));
1671 if (dr < fConeRadius) {
1672 fTrackList[part] = nj+2;
1677 // Same for background event if available
1680 for (Int_t part = 0; part < fNtB; part++) {
1681 Float_t phi = fPhiB[part];
1682 Float_t eta = fEtaB[part];
1683 Float_t dr = TMath::Sqrt((etaj-eta)*(etaj-eta) +
1684 (phij-phi)*(phij-phi));
1685 fTrackListB[part] = 1;
1687 if (dr < fConeRadius) {
1688 fTrackListB[part] = nj+2;
1692 } // Background available ?
1694 Int_t nT0 = nT + nTB;
1695 printf("Total number of tracks %d\n", nT0);
1697 if (nT0 > 1000) nT0 = 1000;
1699 Float_t* ptT = new Float_t[nT0];
1700 Float_t* etaT = new Float_t[nT0];
1701 Float_t* phiT = new Float_t[nT0];
1702 Int_t* pdgT = new Int_t[nT0];
1707 for (Int_t part = 0; part < fNt; part++) {
1708 if (fTrackList[part] == nj+2) {
1710 for (j=iT-1; j>=0; j--) {
1711 if (fPtT[part] > ptT[j]) {
1716 for (j=iT-1; j>=index; j--) {
1717 ptT [j+1] = ptT [j];
1718 etaT[j+1] = etaT[j];
1719 phiT[j+1] = phiT[j];
1720 pdgT[j+1] = pdgT[j];
1722 ptT [index] = fPtT [part];
1723 etaT[index] = fEtaT[part];
1724 phiT[index] = fPhiT[part];
1725 pdgT[index] = fPdgT[part];
1727 } // particle associated
1728 if (iT > nT0) break;
1732 for (Int_t part = 0; part < fNtB; part++) {
1733 if (fTrackListB[part] == nj+2) {
1735 for (j=iT-1; j>=0; j--) {
1736 if (fPtB[part] > ptT[j]) {
1742 for (j=iT-1; j>=index; j--) {
1743 ptT [j+1] = ptT [j];
1744 etaT[j+1] = etaT[j];
1745 phiT[j+1] = phiT[j];
1746 pdgT[j+1] = pdgT[j];
1748 ptT [index] = fPtB [part];
1749 etaT[index] = fEtaB[part];
1750 phiT[index] = fPhiB[part];
1751 pdgT[index] = fPdgB[part];
1753 } // particle associated
1754 if (iT > nT0) break;
1756 } // Background available ?
1758 fJetT[nj]->SetTrackList(nT0, ptT, etaT, phiT, pdgT);
1767 Float_t AliEMCALJetFinder::PropagatePhi(Float_t pt, Float_t charge, Bool_t& curls)
1769 // Propagates phi angle to EMCAL radius
1771 static Float_t b = 0.0, rEMCAL = -1.0;
1773 b = gAlice->Field()->SolenoidField();
1774 // Get EMCAL radius in cm
1775 rEMCAL = AliEMCALGeometry::GetInstance()->GetIPDistance();
1783 Float_t rB = 3335.6 * pt / b; // [cm] (case of |charge|=1)
1785 // check if particle is curling below EMCAL
1786 if (2.*rB < rEMCAL) {
1791 // if not calculate delta phi
1792 Float_t phi = TMath::ACos(1.-rEMCAL*rEMCAL/(2.*rB*rB));
1793 dPhi = TMath::ATan2(1.-TMath::Cos(phi), TMath::Sin(phi));
1794 dPhi = -TMath::Sign(dPhi, charge);
1799 void hf1(Int_t& id, Float_t& x, Float_t& wgt)
1801 // dummy for hbook calls
1805 void AliEMCALJetFinder::DrawLego(Char_t *opt)
1806 {if(fLego) fLego->Draw(opt);}
1808 void AliEMCALJetFinder::DrawLegoBackground(Char_t *opt)
1809 {if(fLegoB) fLegoB->Draw(opt);}
1811 void AliEMCALJetFinder::DrawLegoEMCAL(Char_t *opt)
1812 {if(fhLegoEMCAL) fhLegoEMCAL->Draw(opt);}
1814 void AliEMCALJetFinder::DrawHistsForTuning(Int_t mode)
1816 static TPaveText *varLabel=0;
1818 fC1 = new TCanvas("C1","Hists. for tunning", 0,25,600,800);
1828 fhCellEMCALEt->Draw();
1833 fhTrackPtBcut->SetLineColor(2);
1834 fhTrackPtBcut->Draw("same");
1839 varLabel = new TPaveText(0.05,0.5,0.95,0.95,"NDC");
1840 varLabel->SetTextAlign(12);
1841 varLabel->SetFillColor(19); // see TAttFill
1842 TString tmp(GetTitle());
1843 varLabel->ReadFile(GetFileNameForParameters());
1847 if(mode) { // for saving picture to the file
1848 TString stmp(GetFileNameForParameters());
1849 stmp.ReplaceAll("_Par.txt",".ps");
1850 fC1->Print(stmp.Data());
1854 void AliEMCALJetFinder::PrintParameters(Int_t mode)
1857 if(mode==0) file = stdout; // output to terminal
1859 file = fopen(GetFileNameForParameters(),"w");
1860 if(file==0) file = stdout;
1862 fprintf(file,"==== Filling lego ==== \n");
1863 fprintf(file,"Sampling fraction %6.3f ", fSamplingF);
1864 fprintf(file,"Smearing %6i ", fSmear);
1865 fprintf(file,"Efficiency %6i\n", fEffic);
1866 fprintf(file,"Hadr.Correct. %6i ", fHCorrection);
1867 fprintf(file,"P_{T} Cut of ch.par. %6.2f\n", fPtCut);
1868 fprintf(file,"==== Jet finding ==== \n");
1869 fprintf(file,"Cone radius %6.2f ", fConeRadius);
1870 fprintf(file,"Seed E_{T} %6.1f\n", fEtSeed);
1871 fprintf(file,"Min E_{T} of cell %6.1f ", fMinCellEt);
1872 fprintf(file,"Min E_{T} of jet %6.1f\n", fMinJetEt);
1874 fprintf(file,"==== Bg subtraction ==== \n");
1875 fprintf(file,"BG subtraction %6i ", fMode);
1876 fprintf(file,"Min cone move %6.2f\n", fMinMove);
1877 fprintf(file,"Max cone move %6.2f ", fMaxMove);
1878 fprintf(file,"%% change for BG %6.4f\n", fPrecBg);
1880 fprintf(file,"==== No Bg subtraction ==== \n");
1882 printf("BG file name is %s \n", fBGFileName.Data());
1883 if(file != stdout) fclose(file);
1886 void AliEMCALJetFinder::DrawLegos()
1889 fC1 = new TCanvas("C1","Hists. for tunning", 0,25,600,800);
1893 gStyle->SetOptStat(111111);
1895 Int_t nent1, nent2, nent3, nent4;
1896 Double_t int1, int2, int3, int4;
1897 nent1 = (Int_t)fLego->GetEntries();
1898 int1 = fLego->Integral();
1900 if(int1) fLego->Draw("lego");
1902 nent2 = (Int_t)fhLegoTracks->GetEntries();
1903 int2 = fhLegoTracks->Integral();
1905 if(int2) fhLegoTracks->Draw("lego");
1907 nent3 = (Int_t)fhLegoEMCAL->GetEntries();
1908 int3 = fhLegoEMCAL->Integral();
1910 if(int3) fhLegoEMCAL->Draw("lego");
1912 nent4 = (Int_t)fhLegoHadrCorr->GetEntries();
1913 int4 = fhLegoHadrCorr->Integral();
1915 if(int4) fhLegoHadrCorr->Draw("lego");
1917 // just for checking
1918 printf(" Integrals \n");
1919 printf("lego %10.3f \ntrack %10.3f \nhits %10.3f \nHCorr %10.3f\n-- %10.3f(must be 0)\n",
1920 int1, int2, int3, int4, int1 - (int2 + int3 - int4));
1923 const Char_t* AliEMCALJetFinder::GetFileNameForParameters(Char_t* dir)
1926 if(strlen(dir)) tmp = dir;
1932 void AliEMCALJetFinder::RearrangeParticlesMemory(Int_t npart)
1933 { // See FillFromTracks() - npart must be positive
1934 if (fTrackList) delete[] fTrackList;
1935 if (fPtT) delete[] fPtT;
1936 if (fEtaT) delete[] fEtaT;
1937 if (fPhiT) delete[] fPhiT;
1938 if (fPdgT) delete[] fPdgT;
1941 fTrackList = new Int_t [npart];
1942 fPtT = new Float_t[npart];
1943 fEtaT = new Float_t[npart];
1944 fPhiT = new Float_t[npart];
1945 fPdgT = new Int_t[npart];
1947 printf("AliEMCALJetFinder::RearrangeParticlesMemory : npart = %d\n", npart);
1951 Bool_t AliEMCALJetFinder::IsThisPartonsOrDiQuark(Int_t pdg)
1953 Int_t absPdg = TMath::Abs(pdg);
1954 if(absPdg<=6) return kTRUE; // quarks
1955 if(pdg == 21) return kTRUE; // gluon
1956 if(pdg == 92) return kTRUE; // string
1958 // see p.51 of Pythia Manual
1959 // Not include diquarks with c and b quark - 4-mar-2002
1960 // ud_0,sd_0,su_0; dd_1,ud_1,uu_1; sd_1,su_1,ss_1
1961 static Int_t diquark[9]={2101,3101,3201, 1103,2103,2203, 3103,3203,3303};
1962 for(Int_t i=0; i<9; i++) if(absPdg == diquark[i]) return kTRUE; // diquarks
1967 void AliEMCALJetFinder::FindChargedJet()
1970 // Find jet from charged particle information only
1985 for (part = 0; part < fNt; part++) {
1986 if (!fTrackList[part]) continue;
1987 if (fPtT[part] > fEtSeed) nseed++;
1989 printf("\nThere are %d seeds (%d)\n", nseed, fNtS);
1990 Int_t* iSeeds = new Int_t[nseed];
1993 for (part = 0; part < fNt; part++) {
1994 if (!fTrackList[part]) continue;
1995 if (fPtT[part] > fEtSeed) iSeeds[nseed++] = part;
2006 // Find seed with highest pt
2008 Float_t ptmax = -1.;
2011 for (seed = 0; seed < nseed; seed++) {
2012 if ((pt = fPtT[iSeeds[seed]]) > ptmax && iSeeds[seed] != -1) {
2017 if (ptmax < 0.) break;
2018 jndex = iSeeds[index];
2020 // Remove from the list
2022 printf("\n Next Seed %d %f", jndex, ptmax);
2024 // Find tracks in cone around seed
2026 Float_t phiSeed = fPhiT[jndex];
2027 Float_t etaSeed = fEtaT[jndex];
2033 for (part = 0; part < fNt; part++) {
2034 if (!fTrackList[part]) continue;
2035 Float_t deta = fEtaT[part] - etaSeed;
2036 Float_t dphi = fPhiT[part] - phiSeed;
2037 Float_t dR = TMath::Sqrt(deta * deta + dphi * dphi);
2038 if (dR < fConeRadius) {
2040 Float_t theta = 2. * TMath::ATan(TMath::Exp(-fEtaT[part]));
2041 Float_t px = fPtT[part] * TMath::Cos(fPhiT[part]);
2042 Float_t py = fPtT[part] * TMath::Sin(fPhiT[part]);
2043 Float_t pz = fPtT[part] / TMath::Tan(theta);
2048 // if seed, remove it
2050 for (seed = 0; seed < nseed; seed++) {
2051 if (part == iSeeds[seed]) iSeeds[seed] = -1;
2057 // Estimate of jet direction
2058 Float_t phiJ = TMath::ATan2(pyJ, pxJ);
2059 Float_t thetaJ = TMath::ATan2(TMath::Sqrt(pxJ * pxJ + pyJ * pyJ), pzJ);
2060 Float_t etaJ = TMath::Log(TMath::Tan(thetaJ / 2.));
2061 // Float_t ptJ = TMath::Sqrt(pxJ * pxJ + pyJ * pyJ);
2064 // Sum up all energy
2066 Int_t iPhi0 = Int_t((phiJ - fPhiMin) / fDphi);
2067 Int_t iEta0 = Int_t((etaJ - fEtaMin) / fDeta);
2068 Int_t dIphi = Int_t(fConeRadius / fDphi);
2069 Int_t dIeta = Int_t(fConeRadius / fDeta);
2072 for (iPhi = iPhi0 -dIphi; iPhi < iPhi0 + dIphi; iPhi++) {
2073 for (iEta = iEta0 - dIeta; iEta < iEta0 + dIeta; iEta++) {
2074 if (iPhi < 0 || iEta < 0) continue;
2075 Float_t dPhi = fPhiMin + iPhi * fDphi;
2076 Float_t dEta = fEtaMin + iEta * fDeta;
2077 if (TMath::Sqrt(dPhi * dPhi + dEta * dEta) < fConeRadius) continue;
2078 sumE += fLego->GetBinContent(iEta, iPhi);
2084 fJetT[njets++] = new AliEMCALJet(sumE, phiJ, etaJ);
2085 FindTracksInJetCone();
2086 printf("\n Jet Energy %f %f %f %f %d\n", eT, sumE, fPtT[6], fPtT[7], njets);
2087 printf("\n Jet Phi %f %f %f \n", phiJ, fPhiT[6], fPhiT[7]);
2088 printf("\n Jet Eta %f %f %f \n", etaJ, fEtaT[6], fEtaT[7]);
2090 EMCALJETS.njet = njets;
2091 if (fWrite) WriteJets();
2094 // 16-jan-2003 - just for convenience
2095 void AliEMCALJetFinder::Browse(TBrowser* b)
2097 if(fHistsList) b->Add((TObject*)fHistsList);
2100 Bool_t AliEMCALJetFinder::IsFolder() const
2102 if(fHistsList) return kTRUE;
2106 const Char_t* AliEMCALJetFinder::GetNameOfVariant()
2107 {// generate the literal string with info about jet finder
2109 sprintf(name, "jF_R%3.2fMinCell%4.1fPtCut%4.1fEtSeed%4.1fMinEt%4.1fBGSubtr%iSF%4.1f",
2110 fConeRadius,fMinCellEt,fPtCut,fEtSeed,fMinJetEt, fMode, fSamplingF);
2112 nt.ReplaceAll(" ","");
2113 if(fBGFileName.Length()) {
2114 Int_t i1 = fBGFileName.Index("kBackground");
2115 Int_t i2 = fBGFileName.Index("/0000") - 1;
2116 if(i1>=0 && i2>=0) {
2117 TString bg(fBGFileName(i1,i2-i1+1));
2121 printf("<I> Name of variant %s \n", nt.Data());