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.37 2003/01/23 11:50:04 morsch
19 - option for adding energy of all particles (ich == 2)
20 - provisions for principle component analysis
23 Revision 1.36 2003/01/15 19:05:44 morsch
24 Updated selection in ReadFromTracks()
26 Revision 1.35 2003/01/15 04:59:38 morsch
27 - TPC eff. from AliEMCALFast
28 - Correction in PropagatePhi()
30 Revision 1.34 2003/01/14 10:50:18 alibrary
31 Cleanup of STEER coding conventions
33 Revision 1.33 2003/01/10 10:48:19 morsch
34 SetSamplingFraction() removed from constructor.
36 Revision 1.32 2003/01/10 10:26:40 morsch
37 Sampling fraction initialized from geometry class.
39 Revision 1.31 2003/01/08 17:13:41 schutz
40 added the HCAL section
42 Revision 1.30 2002/12/09 16:26:28 morsch
43 - Nummber of particles per jet increased to 1000
46 Revision 1.29 2002/11/21 17:01:40 alibrary
47 Removing AliMCProcess and AliMC
49 Revision 1.28 2002/11/20 14:13:16 morsch
50 - FindChargedJets() added.
51 - Destructor corrected.
52 - Geometry cuts taken from AliEMCALGeometry.
54 Revision 1.27 2002/11/15 17:39:10 morsch
55 GetPythiaParticleName removed.
57 Revision 1.26 2002/10/14 14:55:35 hristov
58 Merging the VirtualMC branch to the main development branch (HEAD)
60 Revision 1.20.4.3 2002/10/10 15:07:49 hristov
61 Updating VirtualMC to v3-09-02
63 Revision 1.25 2002/09/13 10:24:57 morsch
66 Revision 1.24 2002/09/13 10:21:13 morsch
69 Revision 1.23 2002/06/27 09:24:26 morsch
70 Uncomment the TH1::AddDirectory statement.
72 Revision 1.22 2002/05/22 13:48:43 morsch
73 Pdg code added to track list.
75 Revision 1.21 2002/04/27 07:43:08 morsch
76 Calculation of fDphi corrected (Renan Cabrera)
78 Revision 1.20 2002/03/12 01:06:23 pavlinov
79 Testin output from generator
81 Revision 1.19 2002/02/27 00:46:33 pavlinov
82 Added method FillFromParticles()
84 Revision 1.18 2002/02/21 08:48:59 morsch
85 Correction in FillFromHitFlaggedTrack. (Jennifer Klay)
87 Revision 1.17 2002/02/14 08:52:53 morsch
88 Major updates by Aleksei Pavlinov:
89 FillFromPartons, FillFromTracks, jetfinder configuration.
91 Revision 1.16 2002/02/08 11:43:05 morsch
92 SetOutputFileName(..) allows to specify an output file to which the
93 reconstructed jets are written. If not set output goes to input file.
94 Attention call Init() before processing.
96 Revision 1.15 2002/02/02 08:37:18 morsch
97 Formula for rB corrected.
99 Revision 1.14 2002/02/01 08:55:30 morsch
100 Fill map with Et and pT.
102 Revision 1.13 2002/01/31 09:37:36 morsch
103 Geometry parameters in constructor and call of SetCellSize()
105 Revision 1.12 2002/01/23 13:40:23 morsch
106 Fastidious debug print statement removed.
108 Revision 1.11 2002/01/22 17:25:47 morsch
109 Some corrections for event mixing and bg event handling.
111 Revision 1.10 2002/01/22 10:31:44 morsch
112 Some correction for bg mixing.
114 Revision 1.9 2002/01/21 16:28:42 morsch
115 Correct sign of dphi.
117 Revision 1.8 2002/01/21 16:05:31 morsch
118 - different phi-bin for hadron correction
119 - provisions for background mixing.
121 Revision 1.7 2002/01/21 15:47:18 morsch
122 Bending radius correctly in cm.
124 Revision 1.6 2002/01/21 12:53:50 morsch
127 Revision 1.5 2002/01/21 12:47:47 morsch
128 Possibility to include K0long and neutrons.
130 Revision 1.4 2002/01/21 11:03:21 morsch
131 Phi propagation introduced in FillFromTracks.
133 Revision 1.3 2002/01/18 05:07:56 morsch
134 - hadronic correction
136 - track selection upon EMCAL information
140 //*-- Authors: Andreas Morsch (CERN)
142 //* Aleksei Pavlinov (WSU)
148 #include <TBranchElement.h>
150 #include <TClonesArray.h>
155 #include <TPDGCode.h>
157 #include <TParticle.h>
158 #include <TParticlePDG.h>
159 #include <TPaveText.h>
160 #include <TPythia6Calls.h>
166 #include "AliEMCAL.h"
167 #include "AliEMCALDigit.h"
168 #include "AliEMCALDigitizer.h"
169 #include "AliEMCALFast.h"
170 #include "AliEMCALGeometry.h"
171 #include "AliEMCALHadronCorrection.h"
172 #include "AliEMCALHit.h"
173 #include "AliEMCALJetFinder.h"
174 #include "AliEMCALJetMicroDst.h"
175 #include "AliHeader.h"
177 #include "AliMagFCM.h"
179 #include "AliGenerator.h"
180 // Interface to FORTRAN
184 ClassImp(AliEMCALJetFinder)
186 //____________________________________________________________________________
187 AliEMCALJetFinder::AliEMCALJetFinder()
189 // Default constructor
208 fHadronCorrector = 0;
218 SetParametersForBgSubtraction();
221 AliEMCALJetFinder::AliEMCALJetFinder(const char* name, const char *title)
225 // Title is used in method GetFileNameForParameters();
227 fJets = new TClonesArray("AliEMCALJet",10000);
229 for (Int_t i = 0; i < 30000; i++)
251 fHadronCorrector = 0;
260 SetMomentumSmearing();
263 SetHadronCorrection();
267 SetParametersForBgSubtraction();
270 void AliEMCALJetFinder::SetParametersForBgSubtraction
271 (Int_t mode, Float_t minMove, Float_t maxMove, Float_t precBg)
273 // see file /home/pavlinov/cosmic/pythia/jetFinderParamData.inc
274 // at WSU Linux cluster - 11-feb-2002
275 // These parameters must be tuned more carefull !!!
282 //____________________________________________________________________________
283 AliEMCALJetFinder::~AliEMCALJetFinder()
295 delete fhLegoHadrCorr;
298 delete fhCellEMCALEt;
300 delete fhTrackPtBcut;
301 delete fhChPartMultInTpc;
309 delete[] fTrackListB;
317 # define jet_finder_ua1 jet_finder_ua1_
319 # define type_of_call
322 # define jet_finder_ua1 JET_FINDER_UA1
324 # define type_of_call _stdcall
327 extern "C" void type_of_call
328 jet_finder_ua1(Int_t& ncell, Int_t& ncell_tot,
329 Float_t etc[30000], Float_t etac[30000],
331 Float_t& min_move, Float_t& max_move, Int_t& mode,
332 Float_t& prec_bg, Int_t& ierror);
334 extern "C" void type_of_call hf1(Int_t& id, Float_t& x, Float_t& wgt);
337 void AliEMCALJetFinder::Init()
340 // Geometry and I/O initialization
344 // Get geometry parameters from EMCAL
348 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
349 AliEMCALGeometry* geom =
350 AliEMCALGeometry::GetInstance(pEMCAL->GetTitle(), "");
352 // SetSamplingFraction(geom->GetSampling());
354 fNbinEta = geom->GetNZ();
355 fNbinPhi = geom->GetNPhi();
356 fPhiMin = geom->GetArm1PhiMin()*TMath::Pi()/180.;
357 fPhiMax = geom->GetArm1PhiMax()*TMath::Pi()/180.;
358 fEtaMin = geom->GetArm1EtaMin();
359 fEtaMax = geom->GetArm1EtaMax();
360 fDphi = (fPhiMax-fPhiMin)/fNbinPhi;
361 fDeta = (fEtaMax-fEtaMin)/fNbinEta;
362 fNtot = fNbinPhi*fNbinEta;
363 fWeightingMethod = kFALSE;
366 SetCellSize(fDeta, fDphi);
369 if (fOutFileName) fOutFile = new TFile(fOutFileName, "recreate");
374 void AliEMCALJetFinder::Find(Int_t ncell, Int_t ncell_tot, Float_t etc[30000],
375 Float_t etac[30000], Float_t phic[30000],
376 Float_t min_move, Float_t max_move, Int_t mode,
377 Float_t prec_bg, Int_t ierror)
379 // Wrapper for fortran coded jet finder
380 // Full argument list
381 jet_finder_ua1(ncell, ncell_tot, etc, etac, phic,
382 min_move, max_move, mode, prec_bg, ierror);
383 // Write result to output
384 if(fWrite) WriteJets();
388 void AliEMCALJetFinder::Find()
390 // Wrapper for fortran coded jet finder using member data for
393 Float_t min_move = fMinMove;
394 Float_t max_move = fMaxMove;
396 Float_t prec_bg = fPrecBg;
398 ResetJets(); // 4-feb-2002 by PAI
400 jet_finder_ua1(fNcell, fNtot, fEtCell, fEtaCell, fPhiCell,
401 min_move, max_move, mode, prec_bg, ierror);
403 // Write result to output
404 Int_t njet = Njets();
406 for (Int_t nj=0; nj<njet; nj++)
408 if (fWeightingMethod)
410 fJetT[nj] = new AliEMCALJet(WeightedJetEnergy( JetEtaW(nj),JetPhiW(nj) ),
416 fJetT[nj] = new AliEMCALJet(JetEnergy(nj),
420 fJetT[nj]->SetIsWeightedEnergy(fWeightingMethod);
421 fJetT[nj]->SetEMCALEnergy( EMCALConeEnergy(JetEtaW(nj),JetPhiW(nj)) );
422 fJetT[nj]->SetTrackEnergy(TrackConeEnergy( JetEtaW(nj),JetPhiW(nj) ));
423 fJetT[nj]->SetHCEnergy(HCConeEnergy( JetEtaW(nj),JetPhiW(nj) ));
427 FindTracksInJetCone();
428 if(fWrite) WriteJets();
433 Float_t AliEMCALJetFinder::EMCALConeEnergy(Float_t eta, Float_t phi)
435 Float_t newenergy = 0.0;
436 Float_t bineta,binphi;
437 TAxis *x = fhLegoEMCAL->GetXaxis();
438 TAxis *y = fhLegoEMCAL->GetYaxis();
439 for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
441 for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
443 bineta = x->GetBinCenter(i);
444 binphi = y->GetBinCenter(j);
445 if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
447 newenergy += fhLegoEMCAL->GetBinContent(i,j);
454 Float_t AliEMCALJetFinder::TrackConeEnergy(Float_t eta, Float_t phi)
456 Float_t newenergy = 0.0;
457 Float_t bineta,binphi;
458 TAxis *x = fhLegoTracks->GetXaxis();
459 TAxis *y = fhLegoTracks->GetYaxis();
460 for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
462 for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
464 bineta = x->GetBinCenter(i);
465 binphi = y->GetBinCenter(j);
466 if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
468 newenergy += fhLegoTracks->GetBinContent(i,j);
475 Float_t AliEMCALJetFinder::HCConeEnergy(Float_t eta, Float_t phi)
477 //Float_t newenergy = 0.0;
478 //Float_t bineta,binphi;
479 //TAxis *x = fhLegoTracks->GetXaxis();
480 //TAxis *y = fhLegoTracks->GetYaxis();
481 //for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
483 // for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
485 // bineta = x->GetBinCenter(i);
486 // binphi = y->GetBinCenter(j);
487 // if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
489 // newenergy += fhLegoTracks->GetBinContent(i,j);
501 Float_t AliEMCALJetFinder::WeightedJetEnergy(Float_t eta, Float_t phi)
505 Float_t newenergy = 0.0;
506 Float_t bineta,binphi;
507 TAxis *x = fhLegoEMCAL->GetXaxis();
508 TAxis *y = fhLegoEMCAL->GetYaxis();
511 for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
513 for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
515 bineta = x->GetBinCenter(i);
516 binphi = y->GetBinCenter(j);
517 if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
519 newenergy += (fEMCALWeight)* fhLegoEMCAL->GetBinContent(i,j) + (fTrackWeight)* fhLegoTracks->GetBinContent(i,j);
529 Int_t AliEMCALJetFinder::Njets()
531 // Get number of reconstructed jets
532 return EMCALJETS.njet;
535 Float_t AliEMCALJetFinder::JetEnergy(Int_t i)
537 // Get reconstructed jet energy
538 return EMCALJETS.etj[i];
541 Float_t AliEMCALJetFinder::JetPhiL(Int_t i)
543 // Get reconstructed jet phi from leading particle
544 return EMCALJETS.phij[0][i];
547 Float_t AliEMCALJetFinder::JetPhiW(Int_t i)
549 // Get reconstructed jet phi from weighting
550 return EMCALJETS.phij[1][i];
553 Float_t AliEMCALJetFinder::JetEtaL(Int_t i)
555 // Get reconstructed jet eta from leading particles
556 return EMCALJETS.etaj[0][i];
560 Float_t AliEMCALJetFinder::JetEtaW(Int_t i)
562 // Get reconstructed jet eta from weighting
563 return EMCALJETS.etaj[1][i];
566 void AliEMCALJetFinder::SetCellSize(Float_t eta, Float_t phi)
568 // Set grid cell size
569 EMCALCELLGEO.etaCellSize = eta;
570 EMCALCELLGEO.phiCellSize = phi;
573 void AliEMCALJetFinder::SetConeRadius(Float_t par)
575 // Set jet cone radius
576 EMCALJETPARAM.coneRad = par;
580 void AliEMCALJetFinder::SetEtSeed(Float_t par)
582 // Set et cut for seeds
583 EMCALJETPARAM.etSeed = par;
587 void AliEMCALJetFinder::SetMinJetEt(Float_t par)
589 // Set minimum jet et
590 EMCALJETPARAM.ejMin = par;
594 void AliEMCALJetFinder::SetMinCellEt(Float_t par)
596 // Set et cut per cell
597 EMCALJETPARAM.etMin = par;
601 void AliEMCALJetFinder::SetPtCut(Float_t par)
603 // Set pT cut on charged tracks
608 void AliEMCALJetFinder::Test()
611 // Test the finder call
613 const Int_t nmax = 30000;
615 Int_t ncell_tot = 100;
620 Float_t min_move = 0;
621 Float_t max_move = 0;
627 Find(ncell, ncell_tot, etc, etac, phic,
628 min_move, max_move, mode, prec_bg, ierror);
636 void AliEMCALJetFinder::AddJet(const AliEMCALJet& jet)
641 TClonesArray &lrawcl = *fJets;
642 new(lrawcl[fNjets++]) AliEMCALJet(jet);
645 void AliEMCALJetFinder::ResetJets()
654 void AliEMCALJetFinder::WriteJets()
657 // Add all jets to the list
659 const Int_t kBufferSize = 4000;
660 const char* file = 0;
662 Int_t njet = Njets();
664 for (Int_t nj = 0; nj < njet; nj++)
673 // output written to input file
675 AliEMCAL* pEMCAL = (AliEMCAL* )gAlice->GetModule("EMCAL");
676 TTree* pK = gAlice->TreeK();
677 file = (pK->GetCurrentFile())->GetName();
679 printf("Make Branch - TreeR address %p %p\n",gAlice->TreeR(), pEMCAL);
680 if (fJets && gAlice->TreeR()) {
681 pEMCAL->MakeBranchInTree(gAlice->TreeR(),
687 Int_t nev = gAlice->GetHeader()->GetEvent();
688 gAlice->TreeR()->Fill();
690 sprintf(hname,"TreeR%d", nev);
691 gAlice->TreeR()->Write(hname);
692 gAlice->TreeR()->Reset();
695 // Output written to user specified output file
697 TTree* pK = gAlice->TreeK();
698 fInFile = pK->GetCurrentFile();
702 sprintf(hname,"TreeR%d", fEvent);
703 TTree* treeJ = new TTree(hname, "EMCALJets");
704 treeJ->Branch("EMCALJets", &fJets, kBufferSize);
712 void AliEMCALJetFinder::BookLego()
715 // Book histo for discretisation
719 // Don't add histos to the current directory
720 if(fDebug) printf("\n AliEMCALJetFinder::BookLego() \n");
722 TH2::AddDirectory(0);
723 TH1::AddDirectory(0);
727 fLego = new TH2F("legoH","eta-phi",
728 fNbinEta, fEtaMin, fEtaMax,
729 fNbinPhi, fPhiMin, fPhiMax);
732 fLegoB = new TH2F("legoB","eta-phi for BG event",
733 fNbinEta, fEtaMin, fEtaMax,
734 fNbinPhi, fPhiMin, fPhiMax);
737 fhLegoTracks = new TH2F("hLegoTracks","eta-phi for Tracks",
738 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
740 fhLegoEMCAL = new TH2F("hLegoEMCAL","eta-phi for EMCAL",
741 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
742 // Hadron correction map
743 fhLegoHadrCorr = new TH2F("hLegoHadrCorr","eta-phi for Hadron. Correction",
744 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
745 // Hists. for tuning jet finder
746 fhEff = new TH2F("hEff","#epsilon vs momentum ", 100,0.,20., 50,0.5,1.);
750 for(Int_t i=1; i<=1000; i++) eTmp[i] = 0.1*i; // step 100 mev
751 for(Int_t i=1001; i<=1100; i++) eTmp[i] = eTmp[1000] + 1.0*(i-1000); // step 1GeV
753 fhCellEt = new TH1F("hCellEt","Cell E_{T} from fLego",
754 eTmp.GetSize()-1, eTmp.GetArray());
755 fhCellEMCALEt = new TH1F("hCellEMCALEt","Cell E_{T} for EMCAL itself",
756 eTmp.GetSize()-1, eTmp.GetArray());
757 fhTrackPt = new TH1F("hTrackPt","Ch.particles P_{T} ",
758 eTmp.GetSize()-1, eTmp.GetArray());
759 fhTrackPtBcut = new TH1F("hTrackPtBcut","Ch.particles P_{T} + magnetic field cut",
760 eTmp.GetSize()-1, eTmp.GetArray());
762 fhChPartMultInTpc = new TH1F("hChPartMultInTpc",
763 "Charge partilcle multiplicity in |%eta|<0.9", 2000, 0, 20000);
765 //! first canvas for drawing
766 fHistsList=AliEMCALJetMicroDst::MoveHistsToList("Hists from AliEMCALJetFinder", kTRUE);
769 void AliEMCALJetFinder::DumpLego()
772 // Dump lego histo into array
775 TAxis* Xaxis = fLego->GetXaxis();
776 TAxis* Yaxis = fLego->GetYaxis();
777 // fhCellEt->Clear();
779 for (Int_t i = 1; i <= fNbinEta; i++) {
780 for (Int_t j = 1; j <= fNbinPhi; j++) {
782 e = fLego->GetBinContent(i,j);
784 if (gRandom->Rndm() < 0.5) {
785 Float_t ebg = 0.28 * TMath::Abs(gRandom->Gaus(0.,1.));
789 if (e > 0.0) e -= fMinCellEt;
791 Float_t eta = Xaxis->GetBinCenter(i);
792 Float_t phi = Yaxis->GetBinCenter(j);
794 fEtaCell[fNcell] = eta;
795 fPhiCell[fNcell] = phi;
799 eH = fhLegoEMCAL->GetBinContent(i,j);
800 if(eH > 0.0) fhCellEMCALEt->Fill(eH);
808 void AliEMCALJetFinder::ResetMap()
811 // Reset eta-phi array
813 for (Int_t i=0; i<30000; i++)
822 void AliEMCALJetFinder::FillFromTracks(Int_t flag, Int_t ich)
826 const char* name = gAlice->Generator()->GetName();
827 enum {kPythia, kHijing, kHijingPara};
830 if (!strcmp(name, "Hijing")){
832 } else if (!strcmp(name, "Pythia")) {
834 } else if (!strcmp(name, "HIJINGpara") ||!strcmp(name, "HIGINGpara")) {
835 genType = kHijingPara;
838 printf("Fill tracks generated by %s %d\n", name, genType);
842 // Fill Cells with track information
845 printf("\n AliEMCALJetFinder::FillFromTracks(%i,%i) ",flag,ich);
850 if (!fLego) BookLego();
852 if (flag == 0) fLego->Reset();
854 // Access particle information
855 Int_t npart = (gAlice->GetHeader())->GetNprimary();
856 Int_t ntr = (gAlice->GetHeader())->GetNtrack();
857 printf(" : #primary particles %i # tracks %i \n", npart, ntr);
862 // 1: selected for jet finding
865 if (fTrackList) delete[] fTrackList;
866 if (fPtT) delete[] fPtT;
867 if (fEtaT) delete[] fEtaT;
868 if (fPhiT) delete[] fPhiT;
869 if (fPdgT) delete[] fPdgT;
871 fTrackList = new Int_t [npart];
872 fPtT = new Float_t[npart];
873 fEtaT = new Float_t[npart];
874 fPhiT = new Float_t[npart];
875 fPdgT = new Int_t[npart];
879 Float_t chTmp=0.0; // charge of current particle
882 // this is for Pythia ??
883 for (Int_t part = 0; part < npart; part++) {
884 TParticle *MPart = gAlice->Particle(part);
885 Int_t mpart = MPart->GetPdgCode();
886 Int_t child1 = MPart->GetFirstDaughter();
887 Float_t pT = MPart->Pt();
888 Float_t p = MPart->P();
889 Float_t phi = MPart->Phi();
891 if(pT > 0.001) eta = MPart->Eta();
892 Float_t theta = MPart->Theta();
894 printf("ind %7i part %7i -> child1 %5i child2 %5i Status %5i\n",
895 part, mpart, child1, MPart->GetLastDaughter(), MPart->GetStatusCode());
898 if (fDebug >= 2 && genType == kPythia) {
899 if (part == 6 || part == 7)
901 printf("\n Simulated Jet (pt, eta, phi): %d %f %f %f\n",
902 part-5, pT, eta, phi);
906 fTrackList[part] = 0;
907 fPtT[part] = pT; // must be change after correction for resolution !!!
912 // final state particles only
914 if (genType == kPythia) {
915 if (MPart->GetStatusCode() != 1) continue;
916 } else if (genType == kHijing) {
917 if (child1 >= 0 && child1 < npart) continue;
921 TParticlePDG* pdgP = 0;
922 // charged or neutral
923 pdgP = MPart->GetPDG();
924 chTmp = pdgP->Charge() / 3.; // 13-feb-2001!!
931 if (mpart != kNeutron &&
932 mpart != kNeutronBar &&
933 mpart != kK0Long) continue;
936 } else if (ich == 2) {
937 if (mpart == kNeutron ||
938 mpart == kNeutronBar ||
939 mpart == kK0Long) continue;
942 if (TMath::Abs(eta)<=0.9) fNChTpc++;
944 if (child1 >= 0 && child1 < npart) continue;
946 if (eta > fEtaMax || eta < fEtaMin) continue;
947 if (phi > fPhiMax || phi < fPhiMin ) continue;
950 printf("\n=>nsel:%5d mpart %5d child1 %5d eta %6.2f phi %6.2f pT %6.2f ch %3.0f ",
951 part, mpart, child1, eta, phi, pT, chTmp);
954 // Momentum smearing goes here ...
958 if (fSmear && TMath::Abs(chTmp)) {
959 pw = AliEMCALFast::SmearMomentum(1,p);
960 // p changed - take into account when calculate pT,
963 if(fDebug >= 4) printf("\n Smearing : p %8.4f change to %8.4f ", p, pw);
967 // Tracking Efficiency and TPC acceptance goes here ...
969 if (fEffic && TMath::Abs(chTmp)) {
970 eff = 0.9; // AliEMCALFast::Efficiency(2,p);
971 if(fhEff) fhEff->Fill(p, eff);
972 if (AliEMCALFast::RandomReject(eff)) {
973 if(fDebug >= 5) printf(" reject due to unefficiency ");
978 // Correction of Hadronic Energy goes here ...
981 // phi propagation for hadronic correction
983 Bool_t curls = kFALSE; // hit two the EMCAL (no curl)
984 Float_t phiHC=0.0, dpH=0.0, dphi=0.0, eTdpH=0;
985 if(TMath::Abs(chTmp)) {
986 // hadr. correction only for charge particle
987 dphi = PropagatePhi(pT, chTmp, curls);
990 printf("\n Delta phi %f pT %f ", dphi, pT);
991 if (curls) printf("\n !! Track is curling");
993 if(!curls) fhTrackPtBcut->Fill(pT);
995 if (fHCorrection && !curls) {
996 if (!fHadronCorrector)
997 Fatal("AliEMCALJetFinder",
998 "Hadronic energy correction required but not defined !");
1000 dpH = fHadronCorrector->GetEnergy(p, eta, 7);
1001 eTdpH = dpH*TMath::Sin(theta);
1003 if (fDebug >= 7) printf(" phi %f phiHC %f eTcorr %f\n",
1004 phi, phiHC, -eTdpH); // correction is negative
1006 xbin = fLego->GetXaxis()->FindBin(eta);
1007 ybin = fLego->GetYaxis()->FindBin(phiHC);
1008 cout <<"Hadron Correction affected bin - contents before correction : "<<fLego->GetBinContent(xbin,ybin)<<endl;
1009 fLego->Fill(eta, phi, -fSamplingF*eTdpH );
1010 cout <<"Hadron Correction affected bin - contents after correction : "<<fLego->GetBinContent(xbin,ybin)<<endl;
1011 fhLegoHadrCorr->Fill(eta, phi, fSamplingF*eTdpH);
1015 // More to do ? Just think about it !
1017 if (phi > fPhiMax || phi < fPhiMin ) continue;
1019 if(TMath::Abs(chTmp) ) { // charge particle
1020 if (pT > fPtCut && !curls) {
1021 if (fDebug >= 8) printf("Charge : fLego->Fill(%5.2f, %5.2f, %6.2f, %d)\n",
1022 eta , phi, pT, fNtS);
1023 fLego->Fill(eta, phi, pT);
1024 fhLegoTracks->Fill(eta, phi, pT); // 20-feb for checking
1025 fTrackList[part] = 1;
1028 } else if(ich > 0 || fK0N) {
1029 // case of n, nbar and K0L
1030 if (fDebug >= 9) printf("Neutral : fLego->Fill(%5.2f, %5.2f, %6.2f, %d)\n",
1031 eta , phi, pT, fNtS);
1032 fLego->Fill(eta, phi, pT);
1033 fTrackList[part] = 1;
1038 for(Int_t i=0; i<fLego->GetSize(); i++) {
1039 Float_t etc = (*fLego)[i];
1040 if (etc > fMinCellEt) etsum += etc;
1043 printf("\nFillFromTracks: Sum above threshold %f %f \n \n", fMinCellEt, etsum);
1048 void AliEMCALJetFinder::FillFromHits(Int_t flag)
1051 // Fill Cells with hit information
1055 printf("\n AliEMCALJetFinder::FillFromHits(%i)\n",flag);
1059 if (!fLego) BookLego();
1060 // Reset eta-phi maps if needed
1061 if (flag == 0) { // default behavior
1063 fhLegoTracks->Reset();
1064 fhLegoEMCAL->Reset();
1065 fhLegoHadrCorr->Reset();
1067 // Initialize from background event if available
1069 // Access hit information
1070 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
1071 TTree *treeH = gAlice->TreeH();
1072 Int_t ntracks = (Int_t) treeH->GetEntries();
1079 for (Int_t track=0; track<ntracks;track++) {
1080 gAlice->ResetHits();
1081 nbytes += treeH->GetEvent(track);
1085 for(AliEMCALHit* mHit=(AliEMCALHit*) pEMCAL->FirstHit(-1);
1087 mHit=(AliEMCALHit*) pEMCAL->NextHit())
1089 Float_t x = mHit->X(); // x-pos of hit
1090 Float_t y = mHit->Y(); // y-pos
1091 Float_t z = mHit->Z(); // z-pos
1092 Float_t eloss = mHit->GetEnergy(); // deposited energy
1094 Float_t r = TMath::Sqrt(x*x+y*y);
1095 Float_t theta = TMath::ATan2(r,z);
1096 Float_t eta = -TMath::Log(TMath::Tan(theta/2.));
1097 Float_t phi = TMath::ATan2(y,x);
1099 if (fDebug >= 11) printf("\n Hit %f %f %f %f %f %f %f %f", x, y, z, eloss, r, eta, phi, fSamplingF);
1100 // printf("\n Hit %f %f %f %f", x, y, z, eloss);
1102 etH = fSamplingF*eloss*TMath::Sin(theta);
1103 fLego->Fill(eta, phi, etH);
1104 // fhLegoEMCAL->Fill(eta, phi, etH);
1107 // copy content of fLego to fhLegoEMCAL (fLego and fhLegoEMCAL are identical)
1110 for(Int_t i=0; i<fLego->GetSize(); i++) {
1111 (*fhLegoEMCAL)[i] = (*fLego)[i];
1112 Float_t etc = (*fLego)[i];
1113 if (etc > fMinCellEt) etsum += etc;
1116 printf("\nFillFromHits: Sum above threshold %f %f \n \n", fMinCellEt, etsum);
1122 void AliEMCALJetFinder::FillFromDigits(Int_t flag)
1125 // Fill Cells with digit information
1130 if (!fLego) BookLego();
1131 if (flag == 0) fLego->Reset();
1138 TClonesArray* digs = new TClonesArray("AliEMCALDigit", 10000);
1139 TTree *treeD = gAlice->TreeD();
1140 TBranchElement* branchDg = (TBranchElement*)
1141 treeD->GetBranch("EMCAL");
1143 if (!branchDg) Fatal("AliEMCALJetFinder",
1144 "Reading digits requested but no digits in file !");
1146 branchDg->SetAddress(&digs);
1147 Int_t nent = (Int_t) branchDg->GetEntries();
1149 // Connect digitizer
1151 AliEMCALDigitizer* digr = new AliEMCALDigitizer();
1152 TBranchElement* branchDr = (TBranchElement*)
1153 treeD->GetBranch("AliEMCALDigitizer");
1154 branchDr->SetAddress(&digr);
1157 nbytes += branchDg->GetEntry(0);
1158 nbytes += branchDr->GetEntry(0);
1160 // Get digitizer parameters
1161 Float_t preADCped = digr->GetPREpedestal();
1162 Float_t preADCcha = digr->GetPREchannel();
1163 Float_t ecADCped = digr->GetECpedestal();
1164 Float_t ecADCcha = digr->GetECchannel();
1165 Float_t hcADCped = digr->GetHCpedestal();
1166 Float_t hcADCcha = digr->GetHCchannel();
1168 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
1169 AliEMCALGeometry* geom =
1170 AliEMCALGeometry::GetInstance(pEMCAL->GetTitle(), "");
1173 Int_t ndig = digs->GetEntries();
1174 Info("FillFromDigits","Number of Digits: %d %d\n Parameters: PRE : %f %f EC: %f %f HC: %f %f\n Geometry: %d %d",
1175 ndig, nent, preADCped, preADCcha, ecADCped, ecADCcha, hcADCped, hcADCcha, geom->GetNEta(), geom->GetNPhi());
1182 while ((sdg = (AliEMCALDigit*)(next())))
1184 Double_t pedestal = 0.;
1185 Double_t channel = 0.;
1186 if (geom->IsInPRE(sdg->GetId())) {
1187 pedestal = preADCped;
1188 channel = preADCcha;
1190 else if (geom->IsInECAL(sdg->GetId())) {
1191 pedestal = ecADCped;
1194 else if (geom->IsInHCAL(sdg->GetId())) {
1195 pedestal = hcADCped;
1199 Fatal("FillFromDigits", "unexpected digit is number!") ;
1201 Float_t eta = sdg->GetEta();
1202 Float_t phi = sdg->GetPhi() * TMath::Pi()/180.;
1203 Float_t amp = (Float_t) (channel*(sdg->GetAmp())-pedestal);
1206 Info("FillFromDigits", "Digit: eta %8.3f phi %8.3f amp %8.3f %8d",
1207 eta, phi, amp, sdg->GetAmp());
1209 fLego->Fill(eta, phi, fSamplingF*amp);
1217 void AliEMCALJetFinder::FillFromHitFlaggedTracks(Int_t flag)
1220 // Fill Cells with hit information
1225 if (!fLego) BookLego();
1227 if (flag == 0) fLego->Reset();
1229 // Flag charged tracks passing through TPC which
1230 // are associated to EMCAL Hits
1231 BuildTrackFlagTable();
1234 // Access particle information
1235 TTree *treeK = gAlice->TreeK();
1236 Int_t ntracks = (Int_t) treeK->GetEntries();
1238 if (fPtT) delete[] fPtT;
1239 if (fEtaT) delete[] fEtaT;
1240 if (fPhiT) delete[] fPhiT;
1241 if (fPdgT) delete[] fPdgT;
1243 fPtT = new Float_t[ntracks];
1244 fEtaT = new Float_t[ntracks];
1245 fPhiT = new Float_t[ntracks];
1246 fPdgT = new Int_t[ntracks];
1251 for (Int_t track = 0; track < ntracks; track++) {
1252 TParticle *MPart = gAlice->Particle(track);
1253 Float_t pT = MPart->Pt();
1254 Float_t phi = MPart->Phi();
1255 Float_t eta = MPart->Eta();
1257 if(fTrackList[track]) {
1261 fPdgT[track] = MPart->GetPdgCode();
1263 if (track < 2) continue; //Colliding particles?
1264 if (pT == 0 || pT < fPtCut) continue;
1266 fLego->Fill(eta, phi, pT);
1272 void AliEMCALJetFinder::FillFromParticles()
1274 // 26-feb-2002 PAI - for checking all chain
1275 // Work on particles level; accept all particle (not neutrino )
1277 Double_t PX=0, PY=0, PZ=0, E=0; // checking conservation law
1281 if (!fLego) BookLego();
1284 // Access particles information
1285 Int_t npart = (gAlice->GetHeader())->GetNprimary();
1286 if (fDebug >= 2 || npart<=0) {
1287 printf(" AliEMCALJetFinder::FillFromParticles : npart %i\n", npart);
1288 if(npart<=0) return;
1292 RearrangeParticlesMemory(npart);
1294 // Go through the particles
1295 Int_t mpart, child1, child2, geantPdg;
1296 Float_t pT, phi, eta, e=0, px=0, py=0, pz=0;
1298 for (Int_t part = 0; part < npart; part++) {
1300 fTrackList[part] = 0;
1302 MPart = gAlice->Particle(part);
1303 mpart = MPart->GetPdgCode();
1304 child1 = MPart->GetFirstDaughter();
1305 child2 = MPart->GetLastDaughter();
1313 e = MPart->Energy();
1315 // see pyedit in Pythia's text
1317 if (IsThisPartonsOrDiQuark(mpart)) continue;
1318 printf("%5i: %5i(%2i) px %5.1f py %5.1f pz %6.1f e %6.1f childs %5i,%5i \n",
1319 part, mpart, geantPdg, px, py, pz, e, child1, child2);
1321 // exclude partons (21 - gluon, 92 - string)
1324 // exclude neutrinous also ??
1325 if (fDebug >= 11 && pT>0.01)
1326 printf("\n part:%5d mpart %5d eta %9.2f phi %9.2f pT %9.2f ",
1327 part, mpart, eta, phi, pT);
1332 fPdgT[part] = mpart;
1336 if (child1 >= 0 && child1 < npart) continue;
1338 // printf("%4i -> %5i(%3i) px %6.1f py %6.1f pz %7.1f e %8.2f child1 %5i %s\n",
1339 // part, mpart, geantPdg, px, py, pz, e, child1, name.Data());
1346 if (TMath::Abs(eta) <= 0.9) fNChTpc++;
1348 if (eta > fEtaMax || eta < fEtaMin) continue;
1349 if (phi > fPhiMax || phi < fPhiMin ) continue;
1351 if(fK0N==0 ) { // exclude neutral hadrons
1352 if (mpart == kNeutron || mpart == kNeutronBar || mpart == kK0Long) continue;
1354 fTrackList[part] = 1;
1355 fLego->Fill(eta, phi, pT);
1358 printf("\n PX %8.2f PY %8.2f PZ %8.2f E %8.2f \n",
1361 if(fhChPartMultInTpc) fhChPartMultInTpc->Fill(fNChTpc);
1364 void AliEMCALJetFinder::FillFromPartons()
1366 // function under construction - 13-feb-2002 PAI
1369 printf("\n AliEMCALJetFinder::FillFromPartons()\n");
1373 if (!fLego) BookLego();
1376 // Access particle information
1377 Int_t npart = (gAlice->GetHeader())->GetNprimary();
1378 if (fDebug >= 2 || npart<=0)
1379 printf("\n AliEMCALJetFinder::FillFromPartons : npart %i\n", npart);
1380 fNt = 0; // for FindTracksInJetCone
1383 // Go through the partons
1385 for (Int_t part = 8; part < npart; part++) {
1386 TParticle *MPart = gAlice->Particle(part);
1387 Int_t mpart = MPart->GetPdgCode();
1388 // Int_t child1 = MPart->GetFirstDaughter();
1389 Float_t pT = MPart->Pt();
1390 // Float_t p = MPart->P();
1391 Float_t phi = MPart->Phi();
1392 Float_t eta = MPart->Eta();
1393 // Float_t theta = MPart->Theta();
1394 statusCode = MPart->GetStatusCode();
1396 // accept partons (21 - gluon, 92 - string)
1397 if (!(TMath::Abs(mpart) <= 6 || mpart == 21 ||mpart == 92)) continue;
1398 if (fDebug > 1 && pT>0.01)
1399 printf("\n part:%5d mpart %5d status %5d eta %8.2f phi %8.2f pT %8.2f ",
1400 part, mpart, statusCode, eta, phi, pT);
1401 // if (fDebug >= 3) MPart->Print();
1402 // accept partons before fragmentation - p.57 in Pythia manual
1403 // if(statusCode != 1) continue;
1405 if (eta > fEtaMax || eta < fEtaMin) continue;
1406 if (phi > fPhiMax || phi < fPhiMin ) continue;
1408 // if (child1 >= 0 && child1 < npart) continue;
1411 fLego->Fill(eta, phi, pT);
1417 void AliEMCALJetFinder::BuildTrackFlagTable() {
1419 // Method to generate a lookup table for TreeK particles
1420 // which are linked to hits in the EMCAL
1422 // --Author: J.L. Klay
1424 // Access hit information
1425 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
1427 TTree *TK = gAlice->TreeK(); // Get the number of entries in the kine tree
1428 Int_t nKTrks = (Int_t) TK->GetEntries(); // (Number of particles created somewhere)
1430 if(fTrackList) delete[] fTrackList; //Make sure we get rid of the old one
1431 fTrackList = new Int_t[nKTrks]; //before generating a new one
1433 for (Int_t i = 0; i < nKTrks; i++) { //Initialize members to 0
1437 TTree *treeH = gAlice->TreeH();
1438 Int_t ntracks = (Int_t) treeH->GetEntries();
1444 for (Int_t track=0; track<ntracks;track++) {
1445 gAlice->ResetHits();
1446 nbytes += treeH->GetEvent(track);
1452 for(AliEMCALHit* mHit=(AliEMCALHit*) pEMCAL->FirstHit(-1);
1454 mHit=(AliEMCALHit*) pEMCAL->NextHit())
1456 Int_t iTrk = mHit->Track(); // track number
1457 Int_t idprim = mHit->GetPrimary(); // primary particle
1459 //Determine the origin point of this particle - it made a hit in the EMCAL
1460 TParticle *trkPart = gAlice->Particle(iTrk);
1461 TParticlePDG *trkPdg = trkPart->GetPDG();
1462 Int_t trkCode = trkPart->GetPdgCode();
1464 if (trkCode < 10000) { //Big Ions cause problems for
1465 trkChg = trkPdg->Charge(); //this function. Since they aren't
1466 } else { //likely to make it very far, set
1467 trkChg = 0.0; //their charge to 0 for the Flag test
1469 Float_t vxTrk = trkPart->Vx();
1470 Float_t vyTrk = trkPart->Vy();
1471 Float_t vrTrk = TMath::Sqrt(vxTrk*vxTrk+vyTrk*vyTrk);
1472 fTrackList[iTrk] = SetTrackFlag(vrTrk,trkCode,trkChg);
1474 //Loop through the ancestry of the EMCAL entrance particles
1475 Int_t ancestor = trkPart->GetFirstMother(); //Get track's Mother
1476 while (ancestor != -1) {
1477 TParticle *ancPart = gAlice->Particle(ancestor); //get particle info on ancestor
1478 TParticlePDG *ancPdg = ancPart->GetPDG();
1479 Int_t ancCode = ancPart->GetPdgCode();
1481 if (ancCode < 10000) {
1482 ancChg = ancPdg->Charge();
1486 Float_t vxAnc = ancPart->Vx();
1487 Float_t vyAnc = ancPart->Vy();
1488 Float_t vrAnc = TMath::Sqrt(vxAnc*vxAnc+vyAnc*vyAnc);
1489 fTrackList[ancestor] = SetTrackFlag(vrAnc,ancCode,ancChg);
1490 ancestor = ancPart->GetFirstMother(); //Get the next ancestor
1493 //Determine the origin point of the primary particle associated with the hit
1494 TParticle *primPart = gAlice->Particle(idprim);
1495 TParticlePDG *primPdg = primPart->GetPDG();
1496 Int_t primCode = primPart->GetPdgCode();
1498 if (primCode < 10000) {
1499 primChg = primPdg->Charge();
1503 Float_t vxPrim = primPart->Vx();
1504 Float_t vyPrim = primPart->Vy();
1505 Float_t vrPrim = TMath::Sqrt(vxPrim*vxPrim+vyPrim*vyPrim);
1506 fTrackList[idprim] = SetTrackFlag(vrPrim,primCode,primChg);
1512 Int_t AliEMCALJetFinder
1513 ::SetTrackFlag(Float_t radius, Int_t code, Double_t charge) {
1519 if (charge == 0) neutral = 1;
1521 if (TMath::Abs(code) <= 6 ||
1523 code == 92) parton = 1;
1525 //It's not a parton, it's charged and it went through the TPC
1526 if (!parton && !neutral && radius <= 84.0) flag = 1;
1533 void AliEMCALJetFinder::SaveBackgroundEvent()
1535 // Saves the eta-phi lego and the tracklist
1539 (*fLegoB) = (*fLegoB) + (*fLego);
1541 printf("\n AliEMCALJetFinder::SaveBackgroundEvent() (fLegoB) %f = %f(fLego) \n",
1542 fLegoB->Integral(), fLego->Integral());
1545 if (fPtB) delete[] fPtB;
1546 if (fEtaB) delete[] fEtaB;
1547 if (fPhiB) delete[] fPhiB;
1548 if (fPdgB) delete[] fPdgB;
1549 if (fTrackListB) delete[] fTrackListB;
1551 fPtB = new Float_t[fNtS];
1552 fEtaB = new Float_t[fNtS];
1553 fPhiB = new Float_t[fNtS];
1554 fPdgB = new Int_t [fNtS];
1555 fTrackListB = new Int_t [fNtS];
1559 for (Int_t i = 0; i < fNt; i++) {
1560 if (!fTrackList[i]) continue;
1561 fPtB [fNtB] = fPtT [i];
1562 fEtaB[fNtB] = fEtaT[i];
1563 fPhiB[fNtB] = fPhiT[i];
1564 fPdgB[fNtB] = fPdgT[i];
1565 fTrackListB[fNtB] = 1;
1569 printf(" fNtB %i => fNtS %i #particles %i \n", fNtB, fNtS, fNt);
1572 void AliEMCALJetFinder::InitFromBackground()
1576 if (fDebug) printf("\n AliEMCALJetFinder::InitFromBackground() ");
1580 (*fLego) = (*fLego) + (*fLegoB);
1582 printf("\n AliEMCALJetFinder::SaveBackgroundEvent() (fLego) %f = %f(fLegoB) \n",
1583 fLego->Integral(), fLegoB->Integral());
1585 printf(" => fLego undefined \n");
1590 void AliEMCALJetFinder::FindTracksInJetCone()
1593 // Build list of tracks inside jet cone
1596 Int_t njet = Njets();
1597 for (Int_t nj = 0; nj < njet; nj++)
1599 Float_t etaj = JetEtaW(nj);
1600 Float_t phij = JetPhiW(nj);
1601 Int_t nT = 0; // number of associated tracks
1603 // Loop over particles in current event
1604 for (Int_t part = 0; part < fNt; part++) {
1605 if (!fTrackList[part]) continue;
1606 Float_t phi = fPhiT[part];
1607 Float_t eta = fEtaT[part];
1608 Float_t dr = TMath::Sqrt((etaj-eta)*(etaj-eta) +
1609 (phij-phi)*(phij-phi));
1610 if (dr < fConeRadius) {
1611 fTrackList[part] = nj+2;
1616 // Same for background event if available
1619 for (Int_t part = 0; part < fNtB; part++) {
1620 Float_t phi = fPhiB[part];
1621 Float_t eta = fEtaB[part];
1622 Float_t dr = TMath::Sqrt((etaj-eta)*(etaj-eta) +
1623 (phij-phi)*(phij-phi));
1624 fTrackListB[part] = 1;
1626 if (dr < fConeRadius) {
1627 fTrackListB[part] = nj+2;
1631 } // Background available ?
1633 Int_t nT0 = nT + nTB;
1634 printf("Total number of tracks %d\n", nT0);
1636 if (nT0 > 1000) nT0 = 1000;
1638 Float_t* ptT = new Float_t[nT0];
1639 Float_t* etaT = new Float_t[nT0];
1640 Float_t* phiT = new Float_t[nT0];
1641 Int_t* pdgT = new Int_t[nT0];
1646 for (Int_t part = 0; part < fNt; part++) {
1647 if (fTrackList[part] == nj+2) {
1649 for (j=iT-1; j>=0; j--) {
1650 if (fPtT[part] > ptT[j]) {
1655 for (j=iT-1; j>=index; j--) {
1656 ptT [j+1] = ptT [j];
1657 etaT[j+1] = etaT[j];
1658 phiT[j+1] = phiT[j];
1659 pdgT[j+1] = pdgT[j];
1661 ptT [index] = fPtT [part];
1662 etaT[index] = fEtaT[part];
1663 phiT[index] = fPhiT[part];
1664 pdgT[index] = fPdgT[part];
1666 } // particle associated
1667 if (iT > nT0) break;
1671 for (Int_t part = 0; part < fNtB; part++) {
1672 if (fTrackListB[part] == nj+2) {
1674 for (j=iT-1; j>=0; j--) {
1675 if (fPtB[part] > ptT[j]) {
1681 for (j=iT-1; j>=index; j--) {
1682 ptT [j+1] = ptT [j];
1683 etaT[j+1] = etaT[j];
1684 phiT[j+1] = phiT[j];
1685 pdgT[j+1] = pdgT[j];
1687 ptT [index] = fPtB [part];
1688 etaT[index] = fEtaB[part];
1689 phiT[index] = fPhiB[part];
1690 pdgT[index] = fPdgB[part];
1692 } // particle associated
1693 if (iT > nT0) break;
1695 } // Background available ?
1697 fJetT[nj]->SetTrackList(nT0, ptT, etaT, phiT, pdgT);
1706 Float_t AliEMCALJetFinder::PropagatePhi(Float_t pt, Float_t charge, Bool_t& curls)
1708 // Propagates phi angle to EMCAL radius
1710 static Float_t b = 0.0, rEMCAL = -1.0;
1712 b = gAlice->Field()->SolenoidField();
1713 // Get EMCAL radius in cm
1714 rEMCAL = AliEMCALGeometry::GetInstance()->GetIPDistance();
1722 Float_t rB = 3335.6 * pt / b; // [cm] (case of |charge|=1)
1724 // check if particle is curling below EMCAL
1725 if (2.*rB < rEMCAL) {
1730 // if not calculate delta phi
1731 Float_t phi = TMath::ACos(1.-rEMCAL*rEMCAL/(2.*rB*rB));
1732 dPhi = TMath::ATan2(1.-TMath::Cos(phi), TMath::Sin(phi));
1733 dPhi = -TMath::Sign(dPhi, charge);
1738 void hf1(Int_t& id, Float_t& x, Float_t& wgt)
1740 // dummy for hbook calls
1744 void AliEMCALJetFinder::DrawLego(Char_t *opt)
1747 void AliEMCALJetFinder::DrawLegoEMCAL(Char_t *opt)
1748 {fhLegoEMCAL->Draw(opt);}
1750 void AliEMCALJetFinder::DrawHistsForTuning(Int_t mode)
1752 static TPaveText *varLabel=0;
1754 fC1 = new TCanvas("C1","Hists. for tunning", 0,25,600,800);
1764 fhCellEMCALEt->Draw();
1769 fhTrackPtBcut->SetLineColor(2);
1770 fhTrackPtBcut->Draw("same");
1775 varLabel = new TPaveText(0.05,0.5,0.95,0.95,"NDC");
1776 varLabel->SetTextAlign(12);
1777 varLabel->SetFillColor(19); // see TAttFill
1778 TString tmp(GetTitle());
1779 varLabel->ReadFile(GetFileNameForParameters());
1783 if(mode) { // for saving picture to the file
1784 TString stmp(GetFileNameForParameters());
1785 stmp.ReplaceAll("_Par.txt",".ps");
1786 fC1->Print(stmp.Data());
1790 void AliEMCALJetFinder::PrintParameters(Int_t mode)
1793 if(mode==0) file = stdout; // output to terminal
1795 file = fopen(GetFileNameForParameters(),"w");
1796 if(file==0) file = stdout;
1798 fprintf(file,"==== Filling lego ==== \n");
1799 fprintf(file,"Smearing %6i ", fSmear);
1800 fprintf(file,"Efficiency %6i\n", fEffic);
1801 fprintf(file,"Hadr.Correct. %6i ", fHCorrection);
1802 fprintf(file,"P_{T} Cut of ch.par. %6.2f\n", fPtCut);
1803 fprintf(file,"==== Jet finding ==== \n");
1804 fprintf(file,"Cone radius %6.2f ", fConeRadius);
1805 fprintf(file,"Seed E_{T} %6.1f\n", fEtSeed);
1806 fprintf(file,"Min E_{T} of cell %6.1f ", fMinCellEt);
1807 fprintf(file,"Min E_{T} of jet %6.1f\n", fMinJetEt);
1809 fprintf(file,"==== Bg subtraction ==== \n");
1810 fprintf(file,"BG subtraction %6i ", fMode);
1811 fprintf(file,"Min cone move %6.2f\n", fMinMove);
1812 fprintf(file,"Max cone move %6.2f ", fMaxMove);
1813 fprintf(file,"%% change for BG %6.4f\n", fPrecBg);
1815 fprintf(file,"==== No Bg subtraction ==== \n");
1816 if(file != stdout) fclose(file);
1819 void AliEMCALJetFinder::DrawLegos()
1822 fC1 = new TCanvas("C1","Hists. for tunning", 0,25,600,800);
1826 gStyle->SetOptStat(111111);
1828 Int_t nent1, nent2, nent3, nent4;
1829 Double_t int1, int2, int3, int4;
1830 nent1 = (Int_t)fLego->GetEntries();
1831 int1 = fLego->Integral();
1833 if(int1) fLego->Draw("lego");
1835 nent2 = (Int_t)fhLegoTracks->GetEntries();
1836 int2 = fhLegoTracks->Integral();
1838 if(int2) fhLegoTracks->Draw("lego");
1840 nent3 = (Int_t)fhLegoEMCAL->GetEntries();
1841 int3 = fhLegoEMCAL->Integral();
1843 if(int3) fhLegoEMCAL->Draw("lego");
1845 nent4 = (Int_t)fhLegoHadrCorr->GetEntries();
1846 int4 = fhLegoHadrCorr->Integral();
1848 if(int4) fhLegoHadrCorr->Draw("lego");
1850 // just for checking
1851 printf(" Integrals \n");
1852 printf("lego %10.3f \ntrack %10.3f \nhits %10.3f \nHCorr %10.3f\n-- %10.3f(must be 0)\n",
1853 int1, int2, int3, int4, int1 - (int2 + int3 - int4));
1856 const Char_t* AliEMCALJetFinder::GetFileNameForParameters(Char_t* dir)
1859 if(strlen(dir)) tmp = dir;
1865 void AliEMCALJetFinder::RearrangeParticlesMemory(Int_t npart)
1866 { // See FillFromTracks() - npart must be positive
1867 if (fTrackList) delete[] fTrackList;
1868 if (fPtT) delete[] fPtT;
1869 if (fEtaT) delete[] fEtaT;
1870 if (fPhiT) delete[] fPhiT;
1871 if (fPdgT) delete[] fPdgT;
1874 fTrackList = new Int_t [npart];
1875 fPtT = new Float_t[npart];
1876 fEtaT = new Float_t[npart];
1877 fPhiT = new Float_t[npart];
1878 fPdgT = new Int_t[npart];
1880 printf("AliEMCALJetFinder::RearrangeParticlesMemory : npart = %d\n", npart);
1884 Bool_t AliEMCALJetFinder::IsThisPartonsOrDiQuark(Int_t pdg)
1886 Int_t absPdg = TMath::Abs(pdg);
1887 if(absPdg<=6) return kTRUE; // quarks
1888 if(pdg == 21) return kTRUE; // gluon
1889 if(pdg == 92) return kTRUE; // string
1891 // see p.51 of Pythia Manual
1892 // Not include diquarks with c and b quark - 4-mar-2002
1893 // ud_0,sd_0,su_0; dd_1,ud_1,uu_1; sd_1,su_1,ss_1
1894 static Int_t diquark[9]={2101,3101,3201, 1103,2103,2203, 3103,3203,3303};
1895 for(Int_t i=0; i<9; i++) if(absPdg == diquark[i]) return kTRUE; // diquarks
1900 void AliEMCALJetFinder::FindChargedJet()
1903 // Find jet from charged particle information only
1918 for (part = 0; part < fNt; part++) {
1919 if (!fTrackList[part]) continue;
1920 if (fPtT[part] > fEtSeed) nseed++;
1922 printf("\nThere are %d seeds (%d)\n", nseed, fNtS);
1923 Int_t* iSeeds = new Int_t[nseed];
1926 for (part = 0; part < fNt; part++) {
1927 if (!fTrackList[part]) continue;
1928 if (fPtT[part] > fEtSeed) iSeeds[nseed++] = part;
1939 // Find seed with highest pt
1941 Float_t ptmax = -1.;
1944 for (seed = 0; seed < nseed; seed++) {
1945 if ((pt = fPtT[iSeeds[seed]]) > ptmax && iSeeds[seed] != -1) {
1950 if (ptmax < 0.) break;
1951 jndex = iSeeds[index];
1953 // Remove from the list
1955 printf("\n Next Seed %d %f", jndex, ptmax);
1957 // Find tracks in cone around seed
1959 Float_t phiSeed = fPhiT[jndex];
1960 Float_t etaSeed = fEtaT[jndex];
1966 for (part = 0; part < fNt; part++) {
1967 if (!fTrackList[part]) continue;
1968 Float_t deta = fEtaT[part] - etaSeed;
1969 Float_t dphi = fPhiT[part] - phiSeed;
1970 Float_t dR = TMath::Sqrt(deta * deta + dphi * dphi);
1971 if (dR < fConeRadius) {
1973 Float_t theta = 2. * TMath::ATan(TMath::Exp(-fEtaT[part]));
1974 Float_t px = fPtT[part] * TMath::Cos(fPhiT[part]);
1975 Float_t py = fPtT[part] * TMath::Sin(fPhiT[part]);
1976 Float_t pz = fPtT[part] / TMath::Tan(theta);
1981 // if seed, remove it
1983 for (seed = 0; seed < nseed; seed++) {
1984 if (part == iSeeds[seed]) iSeeds[seed] = -1;
1990 // Estimate of jet direction
1991 Float_t phiJ = TMath::ATan2(pyJ, pxJ);
1992 Float_t thetaJ = TMath::ATan2(TMath::Sqrt(pxJ * pxJ + pyJ * pyJ), pzJ);
1993 Float_t etaJ = TMath::Log(TMath::Tan(thetaJ / 2.));
1994 // Float_t ptJ = TMath::Sqrt(pxJ * pxJ + pyJ * pyJ);
1997 // Sum up all energy
1999 Int_t iPhi0 = Int_t((phiJ - fPhiMin) / fDphi);
2000 Int_t iEta0 = Int_t((etaJ - fEtaMin) / fDeta);
2001 Int_t dIphi = Int_t(fConeRadius / fDphi);
2002 Int_t dIeta = Int_t(fConeRadius / fDeta);
2005 for (iPhi = iPhi0 -dIphi; iPhi < iPhi0 + dIphi; iPhi++) {
2006 for (iEta = iEta0 - dIeta; iEta < iEta0 + dIeta; iEta++) {
2007 if (iPhi < 0 || iEta < 0) continue;
2008 Float_t dPhi = fPhiMin + iPhi * fDphi;
2009 Float_t dEta = fEtaMin + iEta * fDeta;
2010 if (TMath::Sqrt(dPhi * dPhi + dEta * dEta) < fConeRadius) continue;
2011 sumE += fLego->GetBinContent(iEta, iPhi);
2017 fJetT[njets++] = new AliEMCALJet(sumE, phiJ, etaJ);
2018 FindTracksInJetCone();
2019 printf("\n Jet Energy %f %f %f %f %d\n", eT, sumE, fPtT[6], fPtT[7], njets);
2020 printf("\n Jet Phi %f %f %f \n", phiJ, fPhiT[6], fPhiT[7]);
2021 printf("\n Jet Eta %f %f %f \n", etaJ, fEtaT[6], fEtaT[7]);
2023 EMCALJETS.njet = njets;
2024 if (fWrite) WriteJets();