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.36 2003/01/15 19:05:44 morsch
19 Updated selection in ReadFromTracks()
21 Revision 1.35 2003/01/15 04:59:38 morsch
22 - TPC eff. from AliEMCALFast
23 - Correction in PropagatePhi()
25 Revision 1.34 2003/01/14 10:50:18 alibrary
26 Cleanup of STEER coding conventions
28 Revision 1.33 2003/01/10 10:48:19 morsch
29 SetSamplingFraction() removed from constructor.
31 Revision 1.32 2003/01/10 10:26:40 morsch
32 Sampling fraction initialized from geometry class.
34 Revision 1.31 2003/01/08 17:13:41 schutz
35 added the HCAL section
37 Revision 1.30 2002/12/09 16:26:28 morsch
38 - Nummber of particles per jet increased to 1000
41 Revision 1.29 2002/11/21 17:01:40 alibrary
42 Removing AliMCProcess and AliMC
44 Revision 1.28 2002/11/20 14:13:16 morsch
45 - FindChargedJets() added.
46 - Destructor corrected.
47 - Geometry cuts taken from AliEMCALGeometry.
49 Revision 1.27 2002/11/15 17:39:10 morsch
50 GetPythiaParticleName removed.
52 Revision 1.26 2002/10/14 14:55:35 hristov
53 Merging the VirtualMC branch to the main development branch (HEAD)
55 Revision 1.20.4.3 2002/10/10 15:07:49 hristov
56 Updating VirtualMC to v3-09-02
58 Revision 1.25 2002/09/13 10:24:57 morsch
61 Revision 1.24 2002/09/13 10:21:13 morsch
64 Revision 1.23 2002/06/27 09:24:26 morsch
65 Uncomment the TH1::AddDirectory statement.
67 Revision 1.22 2002/05/22 13:48:43 morsch
68 Pdg code added to track list.
70 Revision 1.21 2002/04/27 07:43:08 morsch
71 Calculation of fDphi corrected (Renan Cabrera)
73 Revision 1.20 2002/03/12 01:06:23 pavlinov
74 Testin output from generator
76 Revision 1.19 2002/02/27 00:46:33 pavlinov
77 Added method FillFromParticles()
79 Revision 1.18 2002/02/21 08:48:59 morsch
80 Correction in FillFromHitFlaggedTrack. (Jennifer Klay)
82 Revision 1.17 2002/02/14 08:52:53 morsch
83 Major updates by Aleksei Pavlinov:
84 FillFromPartons, FillFromTracks, jetfinder configuration.
86 Revision 1.16 2002/02/08 11:43:05 morsch
87 SetOutputFileName(..) allows to specify an output file to which the
88 reconstructed jets are written. If not set output goes to input file.
89 Attention call Init() before processing.
91 Revision 1.15 2002/02/02 08:37:18 morsch
92 Formula for rB corrected.
94 Revision 1.14 2002/02/01 08:55:30 morsch
95 Fill map with Et and pT.
97 Revision 1.13 2002/01/31 09:37:36 morsch
98 Geometry parameters in constructor and call of SetCellSize()
100 Revision 1.12 2002/01/23 13:40:23 morsch
101 Fastidious debug print statement removed.
103 Revision 1.11 2002/01/22 17:25:47 morsch
104 Some corrections for event mixing and bg event handling.
106 Revision 1.10 2002/01/22 10:31:44 morsch
107 Some correction for bg mixing.
109 Revision 1.9 2002/01/21 16:28:42 morsch
110 Correct sign of dphi.
112 Revision 1.8 2002/01/21 16:05:31 morsch
113 - different phi-bin for hadron correction
114 - provisions for background mixing.
116 Revision 1.7 2002/01/21 15:47:18 morsch
117 Bending radius correctly in cm.
119 Revision 1.6 2002/01/21 12:53:50 morsch
122 Revision 1.5 2002/01/21 12:47:47 morsch
123 Possibility to include K0long and neutrons.
125 Revision 1.4 2002/01/21 11:03:21 morsch
126 Phi propagation introduced in FillFromTracks.
128 Revision 1.3 2002/01/18 05:07:56 morsch
129 - hadronic correction
131 - track selection upon EMCAL information
135 //*-- Authors: Andreas Morsch (CERN)
137 //* Aleksei Pavlinov (WSU)
143 #include <TBranchElement.h>
145 #include <TClonesArray.h>
150 #include <TPDGCode.h>
152 #include <TParticle.h>
153 #include <TParticlePDG.h>
154 #include <TPaveText.h>
155 #include <TPythia6Calls.h>
161 #include "AliEMCAL.h"
162 #include "AliEMCALDigit.h"
163 #include "AliEMCALDigitizer.h"
164 #include "AliEMCALFast.h"
165 #include "AliEMCALGeometry.h"
166 #include "AliEMCALHadronCorrection.h"
167 #include "AliEMCALHit.h"
168 #include "AliEMCALJetFinder.h"
169 #include "AliEMCALJetMicroDst.h"
170 #include "AliHeader.h"
172 #include "AliMagFCM.h"
175 // Interface to FORTRAN
179 ClassImp(AliEMCALJetFinder)
181 //____________________________________________________________________________
182 AliEMCALJetFinder::AliEMCALJetFinder()
184 // Default constructor
203 fHadronCorrector = 0;
211 SetParametersForBgSubtraction();
214 AliEMCALJetFinder::AliEMCALJetFinder(const char* name, const char *title)
218 // Title is used in method GetFileNameForParameters();
220 fJets = new TClonesArray("AliEMCALJet",10000);
222 for (Int_t i = 0; i < 30000; i++)
244 fHadronCorrector = 0;
253 SetMomentumSmearing();
256 SetHadronCorrection();
259 SetParametersForBgSubtraction();
262 void AliEMCALJetFinder::SetParametersForBgSubtraction
263 (Int_t mode, Float_t minMove, Float_t maxMove, Float_t precBg)
265 // see file /home/pavlinov/cosmic/pythia/jetFinderParamData.inc
266 // at WSU Linux cluster - 11-feb-2002
267 // These parameters must be tuned more carefull !!!
274 //____________________________________________________________________________
275 AliEMCALJetFinder::~AliEMCALJetFinder()
287 delete fhLegoHadrCorr;
290 delete fhCellEMCALEt;
292 delete fhTrackPtBcut;
293 delete fhChPartMultInTpc;
301 delete[] fTrackListB;
309 # define jet_finder_ua1 jet_finder_ua1_
311 # define type_of_call
314 # define jet_finder_ua1 JET_FINDER_UA1
316 # define type_of_call _stdcall
319 extern "C" void type_of_call
320 jet_finder_ua1(Int_t& ncell, Int_t& ncell_tot,
321 Float_t etc[30000], Float_t etac[30000],
323 Float_t& min_move, Float_t& max_move, Int_t& mode,
324 Float_t& prec_bg, Int_t& ierror);
326 extern "C" void type_of_call hf1(Int_t& id, Float_t& x, Float_t& wgt);
329 void AliEMCALJetFinder::Init()
332 // Geometry and I/O initialization
336 // Get geometry parameters from EMCAL
340 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
341 AliEMCALGeometry* geom =
342 AliEMCALGeometry::GetInstance(pEMCAL->GetTitle(), "");
344 // SetSamplingFraction(geom->GetSampling());
346 fNbinEta = geom->GetNZ();
347 fNbinPhi = geom->GetNPhi();
348 fPhiMin = geom->GetArm1PhiMin()*TMath::Pi()/180.;
349 fPhiMax = geom->GetArm1PhiMax()*TMath::Pi()/180.;
350 fEtaMin = geom->GetArm1EtaMin();
351 fEtaMax = geom->GetArm1EtaMax();
352 fDphi = (fPhiMax-fPhiMin)/fNbinPhi;
353 fDeta = (fEtaMax-fEtaMin)/fNbinEta;
354 fNtot = fNbinPhi*fNbinEta;
355 fWeightingMethod = kFALSE;
358 SetCellSize(fDeta, fDphi);
361 if (fOutFileName) fOutFile = new TFile(fOutFileName, "recreate");
364 void AliEMCALJetFinder::Find(Int_t ncell, Int_t ncell_tot, Float_t etc[30000],
365 Float_t etac[30000], Float_t phic[30000],
366 Float_t min_move, Float_t max_move, Int_t mode,
367 Float_t prec_bg, Int_t ierror)
369 // Wrapper for fortran coded jet finder
370 // Full argument list
371 jet_finder_ua1(ncell, ncell_tot, etc, etac, phic,
372 min_move, max_move, mode, prec_bg, ierror);
373 // Write result to output
374 if(fWrite) WriteJets();
378 void AliEMCALJetFinder::Find()
380 // Wrapper for fortran coded jet finder using member data for
383 Float_t min_move = fMinMove;
384 Float_t max_move = fMaxMove;
386 Float_t prec_bg = fPrecBg;
388 ResetJets(); // 4-feb-2002 by PAI
390 jet_finder_ua1(fNcell, fNtot, fEtCell, fEtaCell, fPhiCell,
391 min_move, max_move, mode, prec_bg, ierror);
393 // Write result to output
394 Int_t njet = Njets();
396 for (Int_t nj=0; nj<njet; nj++)
398 if (fWeightingMethod)
400 fJetT[nj] = new AliEMCALJet(WeightedJetEnergy( JetEtaW(nj),JetPhiW(nj) ),
406 fJetT[nj] = new AliEMCALJet(JetEnergy(nj),
410 fJetT[nj]->SetIsWeightedEnergy(fWeightingMethod);
411 fJetT[nj]->SetEMCALEnergy( EMCALConeEnergy(JetEtaW(nj),JetPhiW(nj)) );
412 fJetT[nj]->SetTrackEnergy(TrackConeEnergy( JetEtaW(nj),JetPhiW(nj) ));
413 fJetT[nj]->SetHCEnergy(HCConeEnergy( JetEtaW(nj),JetPhiW(nj) ));
417 FindTracksInJetCone();
418 if(fWrite) WriteJets();
423 Float_t AliEMCALJetFinder::EMCALConeEnergy(Float_t eta, Float_t phi)
425 Float_t newenergy = 0.0;
426 Float_t bineta,binphi;
427 TAxis *x = fhLegoEMCAL->GetXaxis();
428 TAxis *y = fhLegoEMCAL->GetYaxis();
429 for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
431 for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
433 bineta = x->GetBinCenter(i);
434 binphi = y->GetBinCenter(j);
435 if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
437 newenergy += fhLegoEMCAL->GetBinContent(i,j);
444 Float_t AliEMCALJetFinder::TrackConeEnergy(Float_t eta, Float_t phi)
446 Float_t newenergy = 0.0;
447 Float_t bineta,binphi;
448 TAxis *x = fhLegoTracks->GetXaxis();
449 TAxis *y = fhLegoTracks->GetYaxis();
450 for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
452 for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
454 bineta = x->GetBinCenter(i);
455 binphi = y->GetBinCenter(j);
456 if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
458 newenergy += fhLegoTracks->GetBinContent(i,j);
465 Float_t AliEMCALJetFinder::HCConeEnergy(Float_t eta, Float_t phi)
467 //Float_t newenergy = 0.0;
468 //Float_t bineta,binphi;
469 //TAxis *x = fhLegoTracks->GetXaxis();
470 //TAxis *y = fhLegoTracks->GetYaxis();
471 //for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
473 // for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
475 // bineta = x->GetBinCenter(i);
476 // binphi = y->GetBinCenter(j);
477 // if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
479 // newenergy += fhLegoTracks->GetBinContent(i,j);
491 Float_t AliEMCALJetFinder::WeightedJetEnergy(Float_t eta, Float_t phi)
495 Float_t newenergy = 0.0;
496 Float_t bineta,binphi;
497 TAxis *x = fhLegoEMCAL->GetXaxis();
498 TAxis *y = fhLegoEMCAL->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 += (fEMCALWeight)* fhLegoEMCAL->GetBinContent(i,j) + (fTrackWeight)* fhLegoTracks->GetBinContent(i,j);
519 Int_t AliEMCALJetFinder::Njets()
521 // Get number of reconstructed jets
522 return EMCALJETS.njet;
525 Float_t AliEMCALJetFinder::JetEnergy(Int_t i)
527 // Get reconstructed jet energy
528 return EMCALJETS.etj[i];
531 Float_t AliEMCALJetFinder::JetPhiL(Int_t i)
533 // Get reconstructed jet phi from leading particle
534 return EMCALJETS.phij[0][i];
537 Float_t AliEMCALJetFinder::JetPhiW(Int_t i)
539 // Get reconstructed jet phi from weighting
540 return EMCALJETS.phij[1][i];
543 Float_t AliEMCALJetFinder::JetEtaL(Int_t i)
545 // Get reconstructed jet eta from leading particles
546 return EMCALJETS.etaj[0][i];
550 Float_t AliEMCALJetFinder::JetEtaW(Int_t i)
552 // Get reconstructed jet eta from weighting
553 return EMCALJETS.etaj[1][i];
556 void AliEMCALJetFinder::SetCellSize(Float_t eta, Float_t phi)
558 // Set grid cell size
559 EMCALCELLGEO.etaCellSize = eta;
560 EMCALCELLGEO.phiCellSize = phi;
563 void AliEMCALJetFinder::SetConeRadius(Float_t par)
565 // Set jet cone radius
566 EMCALJETPARAM.coneRad = par;
570 void AliEMCALJetFinder::SetEtSeed(Float_t par)
572 // Set et cut for seeds
573 EMCALJETPARAM.etSeed = par;
577 void AliEMCALJetFinder::SetMinJetEt(Float_t par)
579 // Set minimum jet et
580 EMCALJETPARAM.ejMin = par;
584 void AliEMCALJetFinder::SetMinCellEt(Float_t par)
586 // Set et cut per cell
587 EMCALJETPARAM.etMin = par;
591 void AliEMCALJetFinder::SetPtCut(Float_t par)
593 // Set pT cut on charged tracks
598 void AliEMCALJetFinder::Test()
601 // Test the finder call
603 const Int_t nmax = 30000;
605 Int_t ncell_tot = 100;
610 Float_t min_move = 0;
611 Float_t max_move = 0;
617 Find(ncell, ncell_tot, etc, etac, phic,
618 min_move, max_move, mode, prec_bg, ierror);
626 void AliEMCALJetFinder::AddJet(const AliEMCALJet& jet)
631 TClonesArray &lrawcl = *fJets;
632 new(lrawcl[fNjets++]) AliEMCALJet(jet);
635 void AliEMCALJetFinder::ResetJets()
644 void AliEMCALJetFinder::WriteJets()
647 // Add all jets to the list
649 const Int_t kBufferSize = 4000;
650 const char* file = 0;
652 Int_t njet = Njets();
654 for (Int_t nj = 0; nj < njet; nj++)
663 // output written to input file
665 AliEMCAL* pEMCAL = (AliEMCAL* )gAlice->GetModule("EMCAL");
666 TTree* pK = gAlice->TreeK();
667 file = (pK->GetCurrentFile())->GetName();
669 printf("Make Branch - TreeR address %p %p\n",gAlice->TreeR(), pEMCAL);
670 if (fJets && gAlice->TreeR()) {
671 pEMCAL->MakeBranchInTree(gAlice->TreeR(),
677 Int_t nev = gAlice->GetHeader()->GetEvent();
678 gAlice->TreeR()->Fill();
680 sprintf(hname,"TreeR%d", nev);
681 gAlice->TreeR()->Write(hname);
682 gAlice->TreeR()->Reset();
685 // Output written to user specified output file
687 TTree* pK = gAlice->TreeK();
688 fInFile = pK->GetCurrentFile();
692 sprintf(hname,"TreeR%d", fEvent);
693 TTree* treeJ = new TTree(hname, "EMCALJets");
694 treeJ->Branch("EMCALJets", &fJets, kBufferSize);
702 void AliEMCALJetFinder::BookLego()
705 // Book histo for discretisation
709 // Don't add histos to the current directory
710 if(fDebug) printf("\n AliEMCALJetFinder::BookLego() \n");
712 TH2::AddDirectory(0);
713 TH1::AddDirectory(0);
717 fLego = new TH2F("legoH","eta-phi",
718 fNbinEta, fEtaMin, fEtaMax,
719 fNbinPhi, fPhiMin, fPhiMax);
722 fLegoB = new TH2F("legoB","eta-phi for BG event",
723 fNbinEta, fEtaMin, fEtaMax,
724 fNbinPhi, fPhiMin, fPhiMax);
727 fhLegoTracks = new TH2F("hLegoTracks","eta-phi for Tracks",
728 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
730 fhLegoEMCAL = new TH2F("hLegoEMCAL","eta-phi for EMCAL",
731 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
732 // Hadron correction map
733 fhLegoHadrCorr = new TH2F("hLegoHadrCorr","eta-phi for Hadron. Correction",
734 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
735 // Hists. for tuning jet finder
736 fhEff = new TH2F("hEff","#epsilon vs momentum ", 100,0.,20., 50,0.5,1.);
740 for(Int_t i=1; i<=1000; i++) eTmp[i] = 0.1*i; // step 100 mev
741 for(Int_t i=1001; i<=1100; i++) eTmp[i] = eTmp[1000] + 1.0*(i-1000); // step 1GeV
743 fhCellEt = new TH1F("hCellEt","Cell E_{T} from fLego",
744 eTmp.GetSize()-1, eTmp.GetArray());
745 fhCellEMCALEt = new TH1F("hCellEMCALEt","Cell E_{T} for EMCAL itself",
746 eTmp.GetSize()-1, eTmp.GetArray());
747 fhTrackPt = new TH1F("hTrackPt","Ch.particles P_{T} ",
748 eTmp.GetSize()-1, eTmp.GetArray());
749 fhTrackPtBcut = new TH1F("hTrackPtBcut","Ch.particles P_{T} + magnetic field cut",
750 eTmp.GetSize()-1, eTmp.GetArray());
752 fhChPartMultInTpc = new TH1F("hChPartMultInTpc",
753 "Charge partilcle multiplicity in |%eta|<0.9", 2000, 0, 20000);
755 //! first canvas for drawing
756 fHistsList=AliEMCALJetMicroDst::MoveHistsToList("Hists from AliEMCALJetFinder", kTRUE);
759 void AliEMCALJetFinder::DumpLego()
762 // Dump lego histo into array
765 TAxis* Xaxis = fLego->GetXaxis();
766 TAxis* Yaxis = fLego->GetYaxis();
767 // fhCellEt->Clear();
769 for (Int_t i = 1; i <= fNbinEta; i++) {
770 for (Int_t j = 1; j <= fNbinPhi; j++) {
771 e = fLego->GetBinContent(i,j);
773 Float_t eta = Xaxis->GetBinCenter(i);
774 Float_t phi = Yaxis->GetBinCenter(j);
776 fEtaCell[fNcell] = eta;
777 fPhiCell[fNcell] = phi;
782 eH = fhLegoEMCAL->GetBinContent(i,j);
783 if(eH > 0.0) fhCellEMCALEt->Fill(eH);
791 void AliEMCALJetFinder::ResetMap()
794 // Reset eta-phi array
796 for (Int_t i=0; i<30000; i++)
805 void AliEMCALJetFinder::FillFromTracks(Int_t flag, Int_t ich)
808 // Fill Cells with track information
811 printf("\n AliEMCALJetFinder::FillFromTracks(%i,%i) ",flag,ich);
816 if (!fLego) BookLego();
818 if (flag == 0) fLego->Reset();
820 // Access particle information
821 Int_t npart = (gAlice->GetHeader())->GetNprimary();
822 Int_t ntr = (gAlice->GetHeader())->GetNtrack();
823 printf(" : #primary particles %i # tracks %i \n", npart, ntr);
828 // 1: selected for jet finding
831 if (fTrackList) delete[] fTrackList;
832 if (fPtT) delete[] fPtT;
833 if (fEtaT) delete[] fEtaT;
834 if (fPhiT) delete[] fPhiT;
835 if (fPdgT) delete[] fPdgT;
837 fTrackList = new Int_t [npart];
838 fPtT = new Float_t[npart];
839 fEtaT = new Float_t[npart];
840 fPhiT = new Float_t[npart];
841 fPdgT = new Int_t[npart];
845 Float_t chTmp=0.0; // charge of current particle
848 // this is for Pythia ??
849 for (Int_t part = 0; part < npart; part++) {
850 TParticle *MPart = gAlice->Particle(part);
851 Int_t mpart = MPart->GetPdgCode();
852 Int_t child1 = MPart->GetFirstDaughter();
853 Float_t pT = MPart->Pt();
854 Float_t p = MPart->P();
855 Float_t phi = MPart->Phi();
857 if(pT > 0.001) eta = MPart->Eta();
858 Float_t theta = MPart->Theta();
860 printf("ind %7i part %7i -> child1 %5i child2 %5i Status %5i\n",
861 part, mpart, child1, MPart->GetLastDaughter(), MPart->GetStatusCode());
865 if (part == 6 || part == 7)
867 printf("\n Simulated Jet (pt, eta, phi): %d %f %f %f\n",
868 part-5, pT, eta, phi);
872 fTrackList[part] = 0;
873 fPtT[part] = pT; // must be change after correction for resolution !!!
878 // if (part < 2) continue;
879 if (MPart->GetStatusCode() != 1) continue;
881 TParticlePDG* pdgP = 0;
882 // charged or neutral
883 pdgP = MPart->GetPDG();
884 chTmp = pdgP->Charge() / 3.; // 13-feb-2001!!
891 if (mpart != kNeutron &&
892 mpart != kNeutronBar &&
893 mpart != kK0Long) continue;
896 } else if (ich == 2) {
897 if (mpart == kNeutron ||
898 mpart == kNeutronBar ||
899 mpart == kK0Long) continue;
902 if (TMath::Abs(eta)<=0.9) fNChTpc++;
904 if (child1 >= 0 && child1 < npart) continue;
906 if (eta > fEtaMax || eta < fEtaMin) continue;
907 if (phi > fPhiMax || phi < fPhiMin ) continue;
910 printf("\n=>nsel:%5d mpart %5d child1 %5d eta %6.2f phi %6.2f pT %6.2f ch %3.0f ",
911 part, mpart, child1, eta, phi, pT, chTmp);
914 // Momentum smearing goes here ...
918 if (fSmear && TMath::Abs(chTmp)) {
919 pw = AliEMCALFast::SmearMomentum(1,p);
920 // p changed - take into account when calculate pT,
923 if(fDebug >= 4) printf("\n Smearing : p %8.4f change to %8.4f ", p, pw);
927 // Tracking Efficiency and TPC acceptance goes here ...
929 if (fEffic && TMath::Abs(chTmp)) {
930 eff = 0.9; // AliEMCALFast::Efficiency(2,p);
931 if(fhEff) fhEff->Fill(p, eff);
932 if (AliEMCALFast::RandomReject(eff)) {
933 if(fDebug >= 5) printf(" reject due to unefficiency ");
938 // Correction of Hadronic Energy goes here ...
941 // phi propagation for hadronic correction
943 Bool_t curls = kFALSE; // hit two the EMCAL (no curl)
944 Float_t phiHC=0.0, dpH=0.0, dphi=0.0, eTdpH=0;
945 if(TMath::Abs(chTmp)) {
946 // hadr. correction only for charge particle
947 dphi = PropagatePhi(pT, chTmp, curls);
950 printf("\n Delta phi %f pT %f ", dphi, pT);
951 if (curls) printf("\n !! Track is curling");
953 if(!curls) fhTrackPtBcut->Fill(pT);
955 if (fHCorrection && !curls) {
956 if (!fHadronCorrector)
957 Fatal("AliEMCALJetFinder",
958 "Hadronic energy correction required but not defined !");
960 dpH = fHadronCorrector->GetEnergy(p, eta, 7);
961 eTdpH = dpH*TMath::Sin(theta);
963 if (fDebug >= 7) printf(" phi %f phiHC %f eTcorr %f\n",
964 phi, phiHC, -eTdpH); // correction is negative
966 xbin = fLego->GetXaxis()->FindBin(eta);
967 ybin = fLego->GetYaxis()->FindBin(phiHC);
968 cout <<"Hadron Correction affected bin - contents before correction : "<<fLego->GetBinContent(xbin,ybin)<<endl;
969 fLego->Fill(eta, phi, -fSamplingF*eTdpH );
970 cout <<"Hadron Correction affected bin - contents after correction : "<<fLego->GetBinContent(xbin,ybin)<<endl;
971 fhLegoHadrCorr->Fill(eta, phi, fSamplingF*eTdpH);
975 // More to do ? Just think about it !
977 if (phi > fPhiMax || phi < fPhiMin ) continue;
979 if(TMath::Abs(chTmp) ) { // charge particle
980 if (pT > fPtCut && !curls) {
981 if (fDebug >= 8) printf("Charge : fLego->Fill(%5.2f, %5.2f, %6.2f, %d)\n",
982 eta , phi, pT, fNtS);
983 fLego->Fill(eta, phi, pT);
984 fhLegoTracks->Fill(eta, phi, pT); // 20-feb for checking
985 fTrackList[part] = 1;
988 } else if(ich > 0 || fK0N) {
989 // case of n, nbar and K0L
990 if (fDebug >= 9) printf("Neutral : fLego->Fill(%5.2f, %5.2f, %6.2f, %d)\n",
991 eta , phi, pT, fNtS);
992 fLego->Fill(eta, phi, pT);
993 fTrackList[part] = 1;
998 for(Int_t i=0; i<fLego->GetSize(); i++) {
999 Float_t etc = (*fLego)[i];
1000 if (etc > fMinCellEt) etsum += etc;
1003 printf("\nFillFromTracks: Sum above threshold %f %f \n \n", fMinCellEt, etsum);
1008 void AliEMCALJetFinder::FillFromHits(Int_t flag)
1011 // Fill Cells with hit information
1015 printf("\n AliEMCALJetFinder::FillFromHits(%i)\n",flag);
1019 if (!fLego) BookLego();
1020 // Reset eta-phi maps if needed
1021 if (flag == 0) { // default behavior
1023 fhLegoTracks->Reset();
1024 fhLegoEMCAL->Reset();
1025 fhLegoHadrCorr->Reset();
1027 // Initialize from background event if available
1029 // Access hit information
1030 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
1031 TTree *treeH = gAlice->TreeH();
1032 Int_t ntracks = (Int_t) treeH->GetEntries();
1039 for (Int_t track=0; track<ntracks;track++) {
1040 gAlice->ResetHits();
1041 nbytes += treeH->GetEvent(track);
1045 for(AliEMCALHit* mHit=(AliEMCALHit*) pEMCAL->FirstHit(-1);
1047 mHit=(AliEMCALHit*) pEMCAL->NextHit())
1049 Float_t x = mHit->X(); // x-pos of hit
1050 Float_t y = mHit->Y(); // y-pos
1051 Float_t z = mHit->Z(); // z-pos
1052 Float_t eloss = mHit->GetEnergy(); // deposited energy
1054 Float_t r = TMath::Sqrt(x*x+y*y);
1055 Float_t theta = TMath::ATan2(r,z);
1056 Float_t eta = -TMath::Log(TMath::Tan(theta/2.));
1057 Float_t phi = TMath::ATan2(y,x);
1059 if (fDebug >= 11) printf("\n Hit %f %f %f %f %f %f %f %f", x, y, z, eloss, r, eta, phi, fSamplingF);
1060 // printf("\n Hit %f %f %f %f", x, y, z, eloss);
1062 etH = fSamplingF*eloss*TMath::Sin(theta);
1063 fLego->Fill(eta, phi, etH);
1064 // fhLegoEMCAL->Fill(eta, phi, etH);
1067 // copy content of fLego to fhLegoEMCAL (fLego and fhLegoEMCAL are identical)
1070 for(Int_t i=0; i<fLego->GetSize(); i++) {
1071 (*fhLegoEMCAL)[i] = (*fLego)[i];
1072 Float_t etc = (*fLego)[i];
1073 if (etc > fMinCellEt) etsum += etc;
1076 printf("\nFillFromHits: Sum above threshold %f %f \n \n", fMinCellEt, etsum);
1082 void AliEMCALJetFinder::FillFromDigits(Int_t flag)
1085 // Fill Cells with digit information
1090 if (!fLego) BookLego();
1091 if (flag == 0) fLego->Reset();
1098 TClonesArray* digs = new TClonesArray("AliEMCALDigit", 10000);
1099 TTree *treeD = gAlice->TreeD();
1100 TBranchElement* branchDg = (TBranchElement*)
1101 treeD->GetBranch("EMCAL");
1103 if (!branchDg) Fatal("AliEMCALJetFinder",
1104 "Reading digits requested but no digits in file !");
1106 branchDg->SetAddress(&digs);
1107 Int_t nent = (Int_t) branchDg->GetEntries();
1109 // Connect digitizer
1111 AliEMCALDigitizer* digr = new AliEMCALDigitizer();
1112 TBranchElement* branchDr = (TBranchElement*)
1113 treeD->GetBranch("AliEMCALDigitizer");
1114 branchDr->SetAddress(&digr);
1117 nbytes += branchDg->GetEntry(0);
1118 nbytes += branchDr->GetEntry(0);
1120 // Get digitizer parameters
1121 Float_t preADCped = digr->GetPREpedestal();
1122 Float_t preADCcha = digr->GetPREchannel();
1123 Float_t ecADCped = digr->GetECpedestal();
1124 Float_t ecADCcha = digr->GetECchannel();
1125 Float_t hcADCped = digr->GetHCpedestal();
1126 Float_t hcADCcha = digr->GetHCchannel();
1128 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
1129 AliEMCALGeometry* geom =
1130 AliEMCALGeometry::GetInstance(pEMCAL->GetTitle(), "");
1133 Int_t ndig = digs->GetEntries();
1134 Info("FillFromDigits","Number of Digits: %d %d\n Parameters: PRE : %f %f EC: %f %f HC: %f %f\n Geometry: %d %d",
1135 ndig, nent, preADCped, preADCcha, ecADCped, ecADCcha, hcADCped, hcADCcha, geom->GetNEta(), geom->GetNPhi());
1142 while ((sdg = (AliEMCALDigit*)(next())))
1144 Double_t pedestal = 0.;
1145 Double_t channel = 0.;
1146 if (geom->IsInPRE(sdg->GetId())) {
1147 pedestal = preADCped;
1148 channel = preADCcha;
1150 else if (geom->IsInECAL(sdg->GetId())) {
1151 pedestal = ecADCped;
1154 else if (geom->IsInHCAL(sdg->GetId())) {
1155 pedestal = hcADCped;
1159 Fatal("FillFromDigits", "unexpected digit is number!") ;
1161 Float_t eta = sdg->GetEta();
1162 Float_t phi = sdg->GetPhi() * TMath::Pi()/180.;
1163 Float_t amp = (Float_t) (channel*(sdg->GetAmp())-pedestal);
1166 Info("FillFromDigits", "Digit: eta %8.3f phi %8.3f amp %8.3f %8d",
1167 eta, phi, amp, sdg->GetAmp());
1169 fLego->Fill(eta, phi, fSamplingF*amp);
1177 void AliEMCALJetFinder::FillFromHitFlaggedTracks(Int_t flag)
1180 // Fill Cells with hit information
1185 if (!fLego) BookLego();
1187 if (flag == 0) fLego->Reset();
1189 // Flag charged tracks passing through TPC which
1190 // are associated to EMCAL Hits
1191 BuildTrackFlagTable();
1194 // Access particle information
1195 TTree *treeK = gAlice->TreeK();
1196 Int_t ntracks = (Int_t) treeK->GetEntries();
1198 if (fPtT) delete[] fPtT;
1199 if (fEtaT) delete[] fEtaT;
1200 if (fPhiT) delete[] fPhiT;
1201 if (fPdgT) delete[] fPdgT;
1203 fPtT = new Float_t[ntracks];
1204 fEtaT = new Float_t[ntracks];
1205 fPhiT = new Float_t[ntracks];
1206 fPdgT = new Int_t[ntracks];
1211 for (Int_t track = 0; track < ntracks; track++) {
1212 TParticle *MPart = gAlice->Particle(track);
1213 Float_t pT = MPart->Pt();
1214 Float_t phi = MPart->Phi();
1215 Float_t eta = MPart->Eta();
1217 if(fTrackList[track]) {
1221 fPdgT[track] = MPart->GetPdgCode();
1223 if (track < 2) continue; //Colliding particles?
1224 if (pT == 0 || pT < fPtCut) continue;
1226 fLego->Fill(eta, phi, pT);
1232 void AliEMCALJetFinder::FillFromParticles()
1234 // 26-feb-2002 PAI - for checking all chain
1235 // Work on particles level; accept all particle (not neutrino )
1237 Double_t PX=0, PY=0, PZ=0, E=0; // checking conservation law
1241 if (!fLego) BookLego();
1244 // Access particles information
1245 Int_t npart = (gAlice->GetHeader())->GetNprimary();
1246 if (fDebug >= 2 || npart<=0) {
1247 printf(" AliEMCALJetFinder::FillFromParticles : npart %i\n", npart);
1248 if(npart<=0) return;
1252 RearrangeParticlesMemory(npart);
1254 // Go through the particles
1255 Int_t mpart, child1, child2, geantPdg;
1256 Float_t pT, phi, eta, e=0, px=0, py=0, pz=0;
1258 for (Int_t part = 0; part < npart; part++) {
1260 fTrackList[part] = 0;
1262 MPart = gAlice->Particle(part);
1263 mpart = MPart->GetPdgCode();
1264 child1 = MPart->GetFirstDaughter();
1265 child2 = MPart->GetLastDaughter();
1273 e = MPart->Energy();
1275 // see pyedit in Pythia's text
1277 if (IsThisPartonsOrDiQuark(mpart)) continue;
1278 printf("%5i: %5i(%2i) px %5.1f py %5.1f pz %6.1f e %6.1f childs %5i,%5i \n",
1279 part, mpart, geantPdg, px, py, pz, e, child1, child2);
1281 // exclude partons (21 - gluon, 92 - string)
1284 // exclude neutrinous also ??
1285 if (fDebug >= 11 && pT>0.01)
1286 printf("\n part:%5d mpart %5d eta %9.2f phi %9.2f pT %9.2f ",
1287 part, mpart, eta, phi, pT);
1292 fPdgT[part] = mpart;
1296 if (child1 >= 0 && child1 < npart) continue;
1298 // printf("%4i -> %5i(%3i) px %6.1f py %6.1f pz %7.1f e %8.2f child1 %5i %s\n",
1299 // part, mpart, geantPdg, px, py, pz, e, child1, name.Data());
1306 if (TMath::Abs(eta) <= 0.9) fNChTpc++;
1308 if (eta > fEtaMax || eta < fEtaMin) continue;
1309 if (phi > fPhiMax || phi < fPhiMin ) continue;
1311 if(fK0N==0 ) { // exclude neutral hadrons
1312 if (mpart == kNeutron || mpart == kNeutronBar || mpart == kK0Long) continue;
1314 fTrackList[part] = 1;
1315 fLego->Fill(eta, phi, pT);
1318 printf("\n PX %8.2f PY %8.2f PZ %8.2f E %8.2f \n",
1321 if(fhChPartMultInTpc) fhChPartMultInTpc->Fill(fNChTpc);
1324 void AliEMCALJetFinder::FillFromPartons()
1326 // function under construction - 13-feb-2002 PAI
1329 printf("\n AliEMCALJetFinder::FillFromPartons()\n");
1333 if (!fLego) BookLego();
1336 // Access particle information
1337 Int_t npart = (gAlice->GetHeader())->GetNprimary();
1338 if (fDebug >= 2 || npart<=0)
1339 printf("\n AliEMCALJetFinder::FillFromPartons : npart %i\n", npart);
1340 fNt = 0; // for FindTracksInJetCone
1343 // Go through the partons
1345 for (Int_t part = 8; part < npart; part++) {
1346 TParticle *MPart = gAlice->Particle(part);
1347 Int_t mpart = MPart->GetPdgCode();
1348 // Int_t child1 = MPart->GetFirstDaughter();
1349 Float_t pT = MPart->Pt();
1350 // Float_t p = MPart->P();
1351 Float_t phi = MPart->Phi();
1352 Float_t eta = MPart->Eta();
1353 // Float_t theta = MPart->Theta();
1354 statusCode = MPart->GetStatusCode();
1356 // accept partons (21 - gluon, 92 - string)
1357 if (!(TMath::Abs(mpart) <= 6 || mpart == 21 ||mpart == 92)) continue;
1358 if (fDebug > 1 && pT>0.01)
1359 printf("\n part:%5d mpart %5d status %5d eta %8.2f phi %8.2f pT %8.2f ",
1360 part, mpart, statusCode, eta, phi, pT);
1361 // if (fDebug >= 3) MPart->Print();
1362 // accept partons before fragmentation - p.57 in Pythia manual
1363 // if(statusCode != 1) continue;
1365 if (eta > fEtaMax || eta < fEtaMin) continue;
1366 if (phi > fPhiMax || phi < fPhiMin ) continue;
1368 // if (child1 >= 0 && child1 < npart) continue;
1371 fLego->Fill(eta, phi, pT);
1377 void AliEMCALJetFinder::BuildTrackFlagTable() {
1379 // Method to generate a lookup table for TreeK particles
1380 // which are linked to hits in the EMCAL
1382 // --Author: J.L. Klay
1384 // Access hit information
1385 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
1387 TTree *TK = gAlice->TreeK(); // Get the number of entries in the kine tree
1388 Int_t nKTrks = (Int_t) TK->GetEntries(); // (Number of particles created somewhere)
1390 if(fTrackList) delete[] fTrackList; //Make sure we get rid of the old one
1391 fTrackList = new Int_t[nKTrks]; //before generating a new one
1393 for (Int_t i = 0; i < nKTrks; i++) { //Initialize members to 0
1397 TTree *treeH = gAlice->TreeH();
1398 Int_t ntracks = (Int_t) treeH->GetEntries();
1404 for (Int_t track=0; track<ntracks;track++) {
1405 gAlice->ResetHits();
1406 nbytes += treeH->GetEvent(track);
1412 for(AliEMCALHit* mHit=(AliEMCALHit*) pEMCAL->FirstHit(-1);
1414 mHit=(AliEMCALHit*) pEMCAL->NextHit())
1416 Int_t iTrk = mHit->Track(); // track number
1417 Int_t idprim = mHit->GetPrimary(); // primary particle
1419 //Determine the origin point of this particle - it made a hit in the EMCAL
1420 TParticle *trkPart = gAlice->Particle(iTrk);
1421 TParticlePDG *trkPdg = trkPart->GetPDG();
1422 Int_t trkCode = trkPart->GetPdgCode();
1424 if (trkCode < 10000) { //Big Ions cause problems for
1425 trkChg = trkPdg->Charge(); //this function. Since they aren't
1426 } else { //likely to make it very far, set
1427 trkChg = 0.0; //their charge to 0 for the Flag test
1429 Float_t vxTrk = trkPart->Vx();
1430 Float_t vyTrk = trkPart->Vy();
1431 Float_t vrTrk = TMath::Sqrt(vxTrk*vxTrk+vyTrk*vyTrk);
1432 fTrackList[iTrk] = SetTrackFlag(vrTrk,trkCode,trkChg);
1434 //Loop through the ancestry of the EMCAL entrance particles
1435 Int_t ancestor = trkPart->GetFirstMother(); //Get track's Mother
1436 while (ancestor != -1) {
1437 TParticle *ancPart = gAlice->Particle(ancestor); //get particle info on ancestor
1438 TParticlePDG *ancPdg = ancPart->GetPDG();
1439 Int_t ancCode = ancPart->GetPdgCode();
1441 if (ancCode < 10000) {
1442 ancChg = ancPdg->Charge();
1446 Float_t vxAnc = ancPart->Vx();
1447 Float_t vyAnc = ancPart->Vy();
1448 Float_t vrAnc = TMath::Sqrt(vxAnc*vxAnc+vyAnc*vyAnc);
1449 fTrackList[ancestor] = SetTrackFlag(vrAnc,ancCode,ancChg);
1450 ancestor = ancPart->GetFirstMother(); //Get the next ancestor
1453 //Determine the origin point of the primary particle associated with the hit
1454 TParticle *primPart = gAlice->Particle(idprim);
1455 TParticlePDG *primPdg = primPart->GetPDG();
1456 Int_t primCode = primPart->GetPdgCode();
1458 if (primCode < 10000) {
1459 primChg = primPdg->Charge();
1463 Float_t vxPrim = primPart->Vx();
1464 Float_t vyPrim = primPart->Vy();
1465 Float_t vrPrim = TMath::Sqrt(vxPrim*vxPrim+vyPrim*vyPrim);
1466 fTrackList[idprim] = SetTrackFlag(vrPrim,primCode,primChg);
1472 Int_t AliEMCALJetFinder
1473 ::SetTrackFlag(Float_t radius, Int_t code, Double_t charge) {
1479 if (charge == 0) neutral = 1;
1481 if (TMath::Abs(code) <= 6 ||
1483 code == 92) parton = 1;
1485 //It's not a parton, it's charged and it went through the TPC
1486 if (!parton && !neutral && radius <= 84.0) flag = 1;
1493 void AliEMCALJetFinder::SaveBackgroundEvent()
1495 // Saves the eta-phi lego and the tracklist
1499 (*fLegoB) = (*fLegoB) + (*fLego);
1501 printf("\n AliEMCALJetFinder::SaveBackgroundEvent() (fLegoB) %f = %f(fLego) \n",
1502 fLegoB->Integral(), fLego->Integral());
1505 if (fPtB) delete[] fPtB;
1506 if (fEtaB) delete[] fEtaB;
1507 if (fPhiB) delete[] fPhiB;
1508 if (fPdgB) delete[] fPdgB;
1509 if (fTrackListB) delete[] fTrackListB;
1511 fPtB = new Float_t[fNtS];
1512 fEtaB = new Float_t[fNtS];
1513 fPhiB = new Float_t[fNtS];
1514 fPdgB = new Int_t [fNtS];
1515 fTrackListB = new Int_t [fNtS];
1519 for (Int_t i = 0; i < fNt; i++) {
1520 if (!fTrackList[i]) continue;
1521 fPtB [fNtB] = fPtT [i];
1522 fEtaB[fNtB] = fEtaT[i];
1523 fPhiB[fNtB] = fPhiT[i];
1524 fPdgB[fNtB] = fPdgT[i];
1525 fTrackListB[fNtB] = 1;
1529 printf(" fNtB %i => fNtS %i #particles %i \n", fNtB, fNtS, fNt);
1532 void AliEMCALJetFinder::InitFromBackground()
1536 if (fDebug) printf("\n AliEMCALJetFinder::InitFromBackground() ");
1540 (*fLego) = (*fLego) + (*fLegoB);
1542 printf("\n AliEMCALJetFinder::SaveBackgroundEvent() (fLego) %f = %f(fLegoB) \n",
1543 fLego->Integral(), fLegoB->Integral());
1545 printf(" => fLego undefined \n");
1550 void AliEMCALJetFinder::FindTracksInJetCone()
1553 // Build list of tracks inside jet cone
1556 Int_t njet = Njets();
1557 for (Int_t nj = 0; nj < njet; nj++)
1559 Float_t etaj = JetEtaW(nj);
1560 Float_t phij = JetPhiW(nj);
1561 Int_t nT = 0; // number of associated tracks
1563 // Loop over particles in current event
1564 for (Int_t part = 0; part < fNt; part++) {
1565 if (!fTrackList[part]) continue;
1566 Float_t phi = fPhiT[part];
1567 Float_t eta = fEtaT[part];
1568 Float_t dr = TMath::Sqrt((etaj-eta)*(etaj-eta) +
1569 (phij-phi)*(phij-phi));
1570 if (dr < fConeRadius) {
1571 fTrackList[part] = nj+2;
1576 // Same for background event if available
1579 for (Int_t part = 0; part < fNtB; part++) {
1580 Float_t phi = fPhiB[part];
1581 Float_t eta = fEtaB[part];
1582 Float_t dr = TMath::Sqrt((etaj-eta)*(etaj-eta) +
1583 (phij-phi)*(phij-phi));
1584 fTrackListB[part] = 1;
1586 if (dr < fConeRadius) {
1587 fTrackListB[part] = nj+2;
1591 } // Background available ?
1593 Int_t nT0 = nT + nTB;
1594 printf("Total number of tracks %d\n", nT0);
1596 if (nT0 > 1000) nT0 = 1000;
1598 Float_t* ptT = new Float_t[nT0];
1599 Float_t* etaT = new Float_t[nT0];
1600 Float_t* phiT = new Float_t[nT0];
1601 Int_t* pdgT = new Int_t[nT0];
1606 for (Int_t part = 0; part < fNt; part++) {
1607 if (fTrackList[part] == nj+2) {
1609 for (j=iT-1; j>=0; j--) {
1610 if (fPtT[part] > ptT[j]) {
1615 for (j=iT-1; j>=index; j--) {
1616 ptT [j+1] = ptT [j];
1617 etaT[j+1] = etaT[j];
1618 phiT[j+1] = phiT[j];
1619 pdgT[j+1] = pdgT[j];
1621 ptT [index] = fPtT [part];
1622 etaT[index] = fEtaT[part];
1623 phiT[index] = fPhiT[part];
1624 pdgT[index] = fPdgT[part];
1626 } // particle associated
1627 if (iT > nT0) break;
1631 for (Int_t part = 0; part < fNtB; part++) {
1632 if (fTrackListB[part] == nj+2) {
1634 for (j=iT-1; j>=0; j--) {
1635 if (fPtB[part] > ptT[j]) {
1641 for (j=iT-1; j>=index; j--) {
1642 ptT [j+1] = ptT [j];
1643 etaT[j+1] = etaT[j];
1644 phiT[j+1] = phiT[j];
1645 pdgT[j+1] = pdgT[j];
1647 ptT [index] = fPtB [part];
1648 etaT[index] = fEtaB[part];
1649 phiT[index] = fPhiB[part];
1650 pdgT[index] = fPdgB[part];
1652 } // particle associated
1653 if (iT > nT0) break;
1655 } // Background available ?
1657 fJetT[nj]->SetTrackList(nT0, ptT, etaT, phiT, pdgT);
1666 Float_t AliEMCALJetFinder::PropagatePhi(Float_t pt, Float_t charge, Bool_t& curls)
1668 // Propagates phi angle to EMCAL radius
1670 static Float_t b = 0.0, rEMCAL = -1.0;
1672 b = gAlice->Field()->SolenoidField();
1673 // Get EMCAL radius in cm
1674 rEMCAL = AliEMCALGeometry::GetInstance()->GetIPDistance();
1682 Float_t rB = 3335.6 * pt / b; // [cm] (case of |charge|=1)
1684 // check if particle is curling below EMCAL
1685 if (2.*rB < rEMCAL) {
1690 // if not calculate delta phi
1691 Float_t phi = TMath::ACos(1.-rEMCAL*rEMCAL/(2.*rB*rB));
1692 dPhi = TMath::ATan2(1.-TMath::Cos(phi), TMath::Sin(phi));
1693 dPhi = -TMath::Sign(dPhi, charge);
1698 void hf1(Int_t& id, Float_t& x, Float_t& wgt)
1700 // dummy for hbook calls
1704 void AliEMCALJetFinder::DrawLego(Char_t *opt)
1707 void AliEMCALJetFinder::DrawLegoEMCAL(Char_t *opt)
1708 {fhLegoEMCAL->Draw(opt);}
1710 void AliEMCALJetFinder::DrawHistsForTuning(Int_t mode)
1712 static TPaveText *varLabel=0;
1714 fC1 = new TCanvas("C1","Hists. for tunning", 0,25,600,800);
1724 fhCellEMCALEt->Draw();
1729 fhTrackPtBcut->SetLineColor(2);
1730 fhTrackPtBcut->Draw("same");
1735 varLabel = new TPaveText(0.05,0.5,0.95,0.95,"NDC");
1736 varLabel->SetTextAlign(12);
1737 varLabel->SetFillColor(19); // see TAttFill
1738 TString tmp(GetTitle());
1739 varLabel->ReadFile(GetFileNameForParameters());
1743 if(mode) { // for saving picture to the file
1744 TString stmp(GetFileNameForParameters());
1745 stmp.ReplaceAll("_Par.txt",".ps");
1746 fC1->Print(stmp.Data());
1750 void AliEMCALJetFinder::PrintParameters(Int_t mode)
1753 if(mode==0) file = stdout; // output to terminal
1755 file = fopen(GetFileNameForParameters(),"w");
1756 if(file==0) file = stdout;
1758 fprintf(file,"==== Filling lego ==== \n");
1759 fprintf(file,"Smearing %6i ", fSmear);
1760 fprintf(file,"Efficiency %6i\n", fEffic);
1761 fprintf(file,"Hadr.Correct. %6i ", fHCorrection);
1762 fprintf(file,"P_{T} Cut of ch.par. %6.2f\n", fPtCut);
1763 fprintf(file,"==== Jet finding ==== \n");
1764 fprintf(file,"Cone radius %6.2f ", fConeRadius);
1765 fprintf(file,"Seed E_{T} %6.1f\n", fEtSeed);
1766 fprintf(file,"Min E_{T} of cell %6.1f ", fMinCellEt);
1767 fprintf(file,"Min E_{T} of jet %6.1f\n", fMinJetEt);
1769 fprintf(file,"==== Bg subtraction ==== \n");
1770 fprintf(file,"BG subtraction %6i ", fMode);
1771 fprintf(file,"Min cone move %6.2f\n", fMinMove);
1772 fprintf(file,"Max cone move %6.2f ", fMaxMove);
1773 fprintf(file,"%% change for BG %6.4f\n", fPrecBg);
1775 fprintf(file,"==== No Bg subtraction ==== \n");
1776 if(file != stdout) fclose(file);
1779 void AliEMCALJetFinder::DrawLegos()
1782 fC1 = new TCanvas("C1","Hists. for tunning", 0,25,600,800);
1786 gStyle->SetOptStat(111111);
1788 Int_t nent1, nent2, nent3, nent4;
1789 Double_t int1, int2, int3, int4;
1790 nent1 = (Int_t)fLego->GetEntries();
1791 int1 = fLego->Integral();
1793 if(int1) fLego->Draw("lego");
1795 nent2 = (Int_t)fhLegoTracks->GetEntries();
1796 int2 = fhLegoTracks->Integral();
1798 if(int2) fhLegoTracks->Draw("lego");
1800 nent3 = (Int_t)fhLegoEMCAL->GetEntries();
1801 int3 = fhLegoEMCAL->Integral();
1803 if(int3) fhLegoEMCAL->Draw("lego");
1805 nent4 = (Int_t)fhLegoHadrCorr->GetEntries();
1806 int4 = fhLegoHadrCorr->Integral();
1808 if(int4) fhLegoHadrCorr->Draw("lego");
1810 // just for checking
1811 printf(" Integrals \n");
1812 printf("lego %10.3f \ntrack %10.3f \nhits %10.3f \nHCorr %10.3f\n-- %10.3f(must be 0)\n",
1813 int1, int2, int3, int4, int1 - (int2 + int3 - int4));
1816 const Char_t* AliEMCALJetFinder::GetFileNameForParameters(Char_t* dir)
1819 if(strlen(dir)) tmp = dir;
1825 void AliEMCALJetFinder::RearrangeParticlesMemory(Int_t npart)
1826 { // See FillFromTracks() - npart must be positive
1827 if (fTrackList) delete[] fTrackList;
1828 if (fPtT) delete[] fPtT;
1829 if (fEtaT) delete[] fEtaT;
1830 if (fPhiT) delete[] fPhiT;
1831 if (fPdgT) delete[] fPdgT;
1834 fTrackList = new Int_t [npart];
1835 fPtT = new Float_t[npart];
1836 fEtaT = new Float_t[npart];
1837 fPhiT = new Float_t[npart];
1838 fPdgT = new Int_t[npart];
1840 printf("AliEMCALJetFinder::RearrangeParticlesMemory : npart = %d\n", npart);
1844 Bool_t AliEMCALJetFinder::IsThisPartonsOrDiQuark(Int_t pdg)
1846 Int_t absPdg = TMath::Abs(pdg);
1847 if(absPdg<=6) return kTRUE; // quarks
1848 if(pdg == 21) return kTRUE; // gluon
1849 if(pdg == 92) return kTRUE; // string
1851 // see p.51 of Pythia Manual
1852 // Not include diquarks with c and b quark - 4-mar-2002
1853 // ud_0,sd_0,su_0; dd_1,ud_1,uu_1; sd_1,su_1,ss_1
1854 static Int_t diquark[9]={2101,3101,3201, 1103,2103,2203, 3103,3203,3303};
1855 for(Int_t i=0; i<9; i++) if(absPdg == diquark[i]) return kTRUE; // diquarks
1860 void AliEMCALJetFinder::FindChargedJet()
1863 // Find jet from charged particle information only
1878 for (part = 0; part < fNt; part++) {
1879 if (!fTrackList[part]) continue;
1880 if (fPtT[part] > fEtSeed) nseed++;
1882 printf("\nThere are %d seeds (%d)\n", nseed, fNtS);
1883 Int_t* iSeeds = new Int_t[nseed];
1886 for (part = 0; part < fNt; part++) {
1887 if (!fTrackList[part]) continue;
1888 if (fPtT[part] > fEtSeed) iSeeds[nseed++] = part;
1899 // Find seed with highest pt
1901 Float_t ptmax = -1.;
1904 for (seed = 0; seed < nseed; seed++) {
1905 if ((pt = fPtT[iSeeds[seed]]) > ptmax && iSeeds[seed] != -1) {
1910 if (ptmax < 0.) break;
1911 jndex = iSeeds[index];
1913 // Remove from the list
1915 printf("\n Next Seed %d %f", jndex, ptmax);
1917 // Find tracks in cone around seed
1919 Float_t phiSeed = fPhiT[jndex];
1920 Float_t etaSeed = fEtaT[jndex];
1926 for (part = 0; part < fNt; part++) {
1927 if (!fTrackList[part]) continue;
1928 Float_t deta = fEtaT[part] - etaSeed;
1929 Float_t dphi = fPhiT[part] - phiSeed;
1930 Float_t dR = TMath::Sqrt(deta * deta + dphi * dphi);
1931 if (dR < fConeRadius) {
1933 Float_t theta = 2. * TMath::ATan(TMath::Exp(-fEtaT[part]));
1934 Float_t px = fPtT[part] * TMath::Cos(fPhiT[part]);
1935 Float_t py = fPtT[part] * TMath::Sin(fPhiT[part]);
1936 Float_t pz = fPtT[part] / TMath::Tan(theta);
1941 // if seed, remove it
1943 for (seed = 0; seed < nseed; seed++) {
1944 if (part == iSeeds[seed]) iSeeds[seed] = -1;
1950 // Estimate of jet direction
1951 Float_t phiJ = TMath::ATan2(pyJ, pxJ);
1952 Float_t thetaJ = TMath::ATan2(TMath::Sqrt(pxJ * pxJ + pyJ * pyJ), pzJ);
1953 Float_t etaJ = TMath::Log(TMath::Tan(thetaJ / 2.));
1954 // Float_t ptJ = TMath::Sqrt(pxJ * pxJ + pyJ * pyJ);
1957 // Sum up all energy
1959 Int_t iPhi0 = Int_t((phiJ - fPhiMin) / fDphi);
1960 Int_t iEta0 = Int_t((etaJ - fEtaMin) / fDeta);
1961 Int_t dIphi = Int_t(fConeRadius / fDphi);
1962 Int_t dIeta = Int_t(fConeRadius / fDeta);
1965 for (iPhi = iPhi0 -dIphi; iPhi < iPhi0 + dIphi; iPhi++) {
1966 for (iEta = iEta0 - dIeta; iEta < iEta0 + dIeta; iEta++) {
1967 if (iPhi < 0 || iEta < 0) continue;
1968 Float_t dPhi = fPhiMin + iPhi * fDphi;
1969 Float_t dEta = fEtaMin + iEta * fDeta;
1970 if (TMath::Sqrt(dPhi * dPhi + dEta * dEta) < fConeRadius) continue;
1971 sumE += fLego->GetBinContent(iEta, iPhi);
1977 fJetT[njets++] = new AliEMCALJet(sumE, phiJ, etaJ);
1978 FindTracksInJetCone();
1979 printf("\n Jet Energy %f %f %f %f %d\n", eT, sumE, fPtT[6], fPtT[7], njets);
1980 printf("\n Jet Phi %f %f %f \n", phiJ, fPhiT[6], fPhiT[7]);
1981 printf("\n Jet Eta %f %f %f \n", etaJ, fEtaT[6], fEtaT[7]);
1983 EMCALJETS.njet = njets;
1984 if (fWrite) WriteJets();