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 //*-- Authors: Andreas Morsch (CERN)
20 //* Aleksei Pavlinov (WSU)
29 #include <TBranchElement.h>
31 #include <TClonesArray.h>
38 #include <TParticle.h>
39 #include <TParticlePDG.h>
40 #include <TPaveText.h>
41 #include <TPythia6Calls.h>
48 #include "AliEMCALJetFinder.h"
49 #include "AliHeader.h"
51 #include "AliMagFCM.h"
53 #include "AliGenerator.h"
54 #include "AliRunLoader.h"
56 #include "AliEMCALLoader.h"
57 #include "AliEMCALDigit.h"
58 #include "AliEMCALDigitizer.h"
59 #include "AliEMCALFast.h"
60 #include "AliEMCALGeometry.h"
61 #include "AliEMCALHadronCorrection.h"
62 #include "AliEMCALHit.h"
63 #include "AliEMCALJetMicroDst.h"
65 // Interface to FORTRAN
70 ClassImp(AliEMCALJetFinder)
72 //____________________________________________________________________________
73 AliEMCALJetFinder::AliEMCALJetFinder()
75 // Default constructor
104 SetParametersForBgSubtraction();
107 AliEMCALJetFinder::AliEMCALJetFinder(const char* name, const char *title)
111 // Title is used in method GetFileNameForParameters();
113 fJets = new TClonesArray("AliEMCALJet",10000);
115 for (Int_t i = 0; i < 30000; i++)
137 fHadronCorrector = 0;
146 SetMomentumSmearing();
149 SetHadronCorrection();
153 SetParametersForBgSubtraction();
156 void AliEMCALJetFinder::SetParametersForBgSubtraction
157 (Int_t mode, Float_t minMove, Float_t maxMove, Float_t precBg)
159 // see file /home/pavlinov/cosmic/pythia/jetFinderParamData.inc
160 // at WSU Linux cluster - 11-feb-2002
161 // These parameters must be tuned more carefull !!!
168 //____________________________________________________________________________
169 AliEMCALJetFinder::~AliEMCALJetFinder()
181 delete fhLegoHadrCorr;
184 delete fhCellEMCALEt;
186 delete fhTrackPtBcut;
187 delete fhChPartMultInTpc;
195 delete[] fTrackListB;
203 # define jet_finder_ua1 jet_finder_ua1_
205 # define type_of_call
208 # define jet_finder_ua1 JET_FINDER_UA1
210 # define type_of_call _stdcall
213 extern "C" void type_of_call
214 jet_finder_ua1(Int_t& ncell, Int_t& ncell_tot,
215 Float_t etc[30000], Float_t etac[30000],
217 Float_t& min_move, Float_t& max_move, Int_t& mode,
218 Float_t& prec_bg, Int_t& ierror);
220 extern "C" void type_of_call hf1(Int_t& id, Float_t& x, Float_t& wgt);
223 void AliEMCALJetFinder::Init()
226 // Geometry and I/O initialization
230 // Get geometry parameters from EMCAL
234 //AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
235 AliEMCALGeometry* geom = AliEMCALGeometry::GetInstance();
237 // SetSamplingFraction(geom->GetSampling());
239 fNbinEta = geom->GetNZ();
240 fNbinPhi = geom->GetNPhi();
241 fPhiMin = geom->GetArm1PhiMin()*TMath::Pi()/180.;
242 fPhiMax = geom->GetArm1PhiMax()*TMath::Pi()/180.;
243 fEtaMin = geom->GetArm1EtaMin();
244 fEtaMax = geom->GetArm1EtaMax();
245 fDphi = (fPhiMax-fPhiMin)/fNbinPhi;
246 fDeta = (fEtaMax-fEtaMin)/fNbinEta;
247 fNtot = fNbinPhi*fNbinEta;
248 fWeightingMethod = kFALSE;
251 SetCellSize(fDeta, fDphi);
254 if (fOutFileName) fOutFile = new TFile(fOutFileName, "recreate");
259 void AliEMCALJetFinder::Find(Int_t ncell, Int_t ncelltot, Float_t etc[30000],
260 Float_t etac[30000], Float_t phic[30000],
261 Float_t minmove, Float_t maxmove, Int_t mode,
262 Float_t precbg, Int_t ierror)
264 // Wrapper for fortran coded jet finder
265 // Full argument list
266 jet_finder_ua1(ncell, ncelltot, etc, etac, phic,
267 minmove, maxmove, mode, precbg, ierror);
268 // Write result to output
269 if(fWrite) WriteJets();
273 void AliEMCALJetFinder::Find()
275 // Wrapper for fortran coded jet finder using member data for
278 Float_t minmove = fMinMove;
279 Float_t maxmove = fMaxMove;
281 Float_t precbg = fPrecBg;
283 ResetJets(); // 4-feb-2002 by PAI
285 jet_finder_ua1(fNcell, fNtot, fEtCell, fEtaCell, fPhiCell,
286 minmove, maxmove, mode, precbg, ierror);
288 // Write result to output
289 Int_t njet = Njets();
291 for (Int_t nj=0; nj<njet; nj++)
293 if (fWeightingMethod)
295 fJetT[nj] = new AliEMCALJet(WeightedJetEnergy( JetEtaW(nj),JetPhiW(nj) ),
301 fJetT[nj] = new AliEMCALJet(JetEnergy(nj),
305 fJetT[nj]->SetIsWeightedEnergy(fWeightingMethod);
306 fJetT[nj]->SetEMCALEnergy( EMCALConeEnergy(JetEtaW(nj),JetPhiW(nj)) );
307 fJetT[nj]->SetTrackEnergy(TrackConeEnergy( JetEtaW(nj),JetPhiW(nj) ));
311 FindTracksInJetCone();
312 if(fWrite) WriteJets();
317 Float_t AliEMCALJetFinder::EMCALConeEnergy(Float_t eta, Float_t phi)
319 // Calculate the energy in the cone
320 Float_t newenergy = 0.0;
321 Float_t bineta,binphi;
322 TAxis *x = fhLegoEMCAL->GetXaxis();
323 TAxis *y = fhLegoEMCAL->GetYaxis();
324 for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
326 for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
328 bineta = x->GetBinCenter(i);
329 binphi = y->GetBinCenter(j);
330 if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
332 newenergy += fhLegoEMCAL->GetBinContent(i,j);
339 Float_t AliEMCALJetFinder::TrackConeEnergy(Float_t eta, Float_t phi)
341 // Calculate the track energy in the cone
342 Float_t newenergy = 0.0;
343 Float_t bineta,binphi;
344 TAxis *x = fhLegoTracks->GetXaxis();
345 TAxis *y = fhLegoTracks->GetYaxis();
346 for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
348 for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
350 bineta = x->GetBinCenter(i);
351 binphi = y->GetBinCenter(j);
352 if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
354 newenergy += fhLegoTracks->GetBinContent(i,j);
362 Float_t AliEMCALJetFinder::WeightedJetEnergy(Float_t eta, Float_t phi)
364 // Calculate the weighted jet energy
366 Float_t newenergy = 0.0;
367 Float_t bineta,binphi;
368 TAxis *x = fhLegoEMCAL->GetXaxis();
369 TAxis *y = fhLegoEMCAL->GetYaxis();
372 for (Int_t i = 0 ; i < fNbinEta ; i++) // x coord
374 for (Int_t j = 0 ; j < fNbinPhi ; j++) // y coord
376 bineta = x->GetBinCenter(i);
377 binphi = y->GetBinCenter(j);
378 if ( (bineta-eta)*(bineta-eta) + (binphi-phi)*(binphi-phi) < fConeRadius*fConeRadius)
380 newenergy += (fEMCALWeight)* fhLegoEMCAL->GetBinContent(i,j) + (fTrackWeight)* fhLegoTracks->GetBinContent(i,j);
390 Int_t AliEMCALJetFinder::Njets() const
392 // Get number of reconstructed jets
393 return EMCALJETS.njet;
396 Float_t AliEMCALJetFinder::JetEnergy(Int_t i) const
398 // Get reconstructed jet energy
399 return EMCALJETS.etj[i];
402 Float_t AliEMCALJetFinder::JetPhiL(Int_t i) const
404 // Get reconstructed jet phi from leading particle
405 return EMCALJETS.phij[0][i];
408 Float_t AliEMCALJetFinder::JetPhiW(Int_t i) const
410 // Get reconstructed jet phi from weighting
411 return EMCALJETS.phij[1][i];
414 Float_t AliEMCALJetFinder::JetEtaL(Int_t i) const
416 // Get reconstructed jet eta from leading particles
417 return EMCALJETS.etaj[0][i];
421 Float_t AliEMCALJetFinder::JetEtaW(Int_t i) const
423 // Get reconstructed jet eta from weighting
424 return EMCALJETS.etaj[1][i];
427 void AliEMCALJetFinder::SetCellSize(Float_t eta, Float_t phi)
429 // Set grid cell size
430 EMCALCELLGEO.etaCellSize = eta;
431 EMCALCELLGEO.phiCellSize = phi;
434 void AliEMCALJetFinder::SetConeRadius(Float_t par)
436 // Set jet cone radius
437 EMCALJETPARAM.coneRad = par;
441 void AliEMCALJetFinder::SetEtSeed(Float_t par)
443 // Set et cut for seeds
444 EMCALJETPARAM.etSeed = par;
448 void AliEMCALJetFinder::SetMinJetEt(Float_t par)
450 // Set minimum jet et
451 EMCALJETPARAM.ejMin = par;
455 void AliEMCALJetFinder::SetMinCellEt(Float_t par)
457 // Set et cut per cell
458 EMCALJETPARAM.etMin = par;
462 void AliEMCALJetFinder::SetPtCut(Float_t par)
464 // Set pT cut on charged tracks
469 void AliEMCALJetFinder::Test()
472 // Test the finder call
474 const Int_t knmax = 30000;
476 Int_t ncelltot = 100;
488 Find(ncell, ncelltot, etc, etac, phic,
489 minmove, maxmove, mode, precbg, ierror);
497 void AliEMCALJetFinder::AddJet(const AliEMCALJet& jet)
502 TClonesArray &lrawcl = *fJets;
503 new(lrawcl[fNjets++]) AliEMCALJet(jet);
506 void AliEMCALJetFinder::ResetJets()
515 void AliEMCALJetFinder::WriteJets()
518 // Add all jets to the list
520 const Int_t kBufferSize = 4000;
521 const char* file = 0;
523 Int_t njet = Njets();
525 for (Int_t nj = 0; nj < njet; nj++)
532 AliRunLoader *rl = AliRunLoader::GetRunLoader();
533 AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(rl->GetDetectorLoader("EMCAL"));
537 // output written to input file
539 AliEMCAL* pEMCAL = (AliEMCAL* )gAlice->GetModule("EMCAL");
540 TTree* pK = rl->TreeK();
541 file = (pK->GetCurrentFile())->GetName();
542 TBranch * jetBranch ;
544 printf("Make Branch - TreeR address %p %p\n",(void*)gAlice->TreeR(), (void*)pEMCAL);
545 //if (fJets && gAlice->TreeR()) {
546 if (fJets && emcalLoader->TreeR()) {
547 // pEMCAL->MakeBranchInTree(gAlice->TreeR(),
548 jetBranch = emcalLoader->TreeR()->Branch("EMCALJets", &fJets, kBufferSize, 0) ;
549 //pEMCAL->MakeBranchInTree(gime->TreeR(),
555 //Int_t nev = gAlice->GetHeader()->GetEvent();
556 //gAlice->TreeR()->Fill();
559 //sprintf(hname,"TreeR%d", nev);
560 //gAlice->TreeR()->Write(hname);
561 //gAlice->TreeR()->Reset();
562 //gime->WriteRecPoints("OVERWRITE");
563 emcalLoader->WriteRecPoints("OVERWRITE");
567 // Output written to user specified output file
569 //TTree* pK = gAlice->TreeK();
570 TTree* pK = rl->TreeK();
571 fInFile = pK->GetCurrentFile();
575 sprintf(hname,"TreeR%d", fEvent);
576 TTree* treeJ = new TTree(hname, "EMCALJets");
577 treeJ->Branch("EMCALJets", &fJets, kBufferSize);
585 void AliEMCALJetFinder::BookLego()
588 // Book histo for discretization
592 // Don't add histos to the current directory
593 if(fDebug) printf("\n AliEMCALJetFinder::BookLego() \n");
595 // TH2::AddDirectory(0); // hists wil be put to the list from gROOT
596 // TH1::AddDirectory(0);
600 fLego = new TH2F("legoH","eta-phi",
601 fNbinEta, fEtaMin, fEtaMax,
602 fNbinPhi, fPhiMin, fPhiMax);
605 fLegoB = new TH2F("legoB","eta-phi for BG event",
606 fNbinEta, fEtaMin, fEtaMax,
607 fNbinPhi, fPhiMin, fPhiMax);
610 fhLegoTracks = new TH2F("hLegoTracks","eta-phi for Tracks",
611 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
613 fhLegoEMCAL = new TH2F("hLegoEMCAL","eta-phi for EMCAL",
614 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
615 // Hadron correction map
616 fhLegoHadrCorr = new TH2F("hLegoHadrCorr","eta-phi for Hadron. Correction",
617 fNbinEta, fEtaMin, fEtaMax, fNbinPhi, fPhiMin, fPhiMax);
618 // Hists. for tuning jet finder
619 fhEff = new TH2F("hEff","#epsilon vs momentum ", 100,0.,20., 50,0.5,1.);
623 for(Int_t i=1; i<=1000; i++) eTmp[i] = 0.1*i; // step 100 mev
624 for(Int_t i=1001; i<=1100; i++) eTmp[i] = eTmp[1000] + 1.0*(i-1000); // step 1GeV
626 fhCellEt = new TH1F("hCellEt","Cell E_{T} from fLego",
627 eTmp.GetSize()-1, eTmp.GetArray());
628 fhCellEMCALEt = new TH1F("hCellEMCALEt","Cell E_{T} for EMCAL itself",
629 eTmp.GetSize()-1, eTmp.GetArray());
630 fhTrackPt = new TH1F("hTrackPt","Ch.particles P_{T} ",
631 eTmp.GetSize()-1, eTmp.GetArray());
632 fhTrackPtBcut = new TH1F("hTrackPtBcut","Ch.particles P_{T} + magnetic field cut",
633 eTmp.GetSize()-1, eTmp.GetArray());
635 fhChPartMultInTpc = new TH1F("hChPartMultInTpc",
636 "Charge partilcle multiplicity in |%eta|<0.9", 2000, 0, 20000);
638 fhSinTheta = new TH1F("fhSinTheta","sin(theta)", fNbinEta, fEtaMin, fEtaMax);
639 TAxis *xax = fhSinTheta->GetXaxis();
640 for(Int_t i=1; i<=fNbinEta; i++) {
641 Double_t eta = xax->GetBinCenter(i);
642 fhSinTheta->Fill(eta, 1./TMath::CosH(eta)); // cosh(eta) = 1./sin(theta)
645 //! first canvas for drawing
646 fHistsList=AliEMCALJetMicroDst::MoveHistsToList("Hists from AliEMCALJetFinder", kFALSE);
649 void AliEMCALJetFinder::DumpLego()
652 // Dump lego histo into array
655 TAxis* xaxis = fLego->GetXaxis();
656 TAxis* yaxis = fLego->GetYaxis();
657 // fhCellEt->Clear();
659 for (Int_t i = 1; i <= fNbinEta; i++) {
660 for (Int_t j = 1; j <= fNbinPhi; j++) {
662 e = fLego->GetBinContent(i,j);
664 if (gRandom->Rndm() < 0.5) {
665 Float_t ebg = 0.28 * TMath::Abs(gRandom->Gaus(0.,1.));
669 if (e > 0.0) e -= fMinCellEt;
671 Float_t eta = xaxis->GetBinCenter(i);
672 Float_t phi = yaxis->GetBinCenter(j);
674 fEtaCell[fNcell] = eta;
675 fPhiCell[fNcell] = phi;
679 eH = fhLegoEMCAL->GetBinContent(i,j);
680 if(eH > 0.0) fhCellEMCALEt->Fill(eH);
688 void AliEMCALJetFinder::ResetMap()
691 // Reset eta-phi array
693 for (Int_t i=0; i<30000; i++)
702 void AliEMCALJetFinder::FillFromTracks(Int_t flag, Int_t ich)
706 const char* name = gAlice->Generator()->GetName();
707 enum {kPythia, kHijing, kHijingPara};
710 if (!strcmp(name, "Hijing")){
712 } else if (!strcmp(name, "Pythia")) {
714 } else if (!strcmp(name, "HIJINGpara") ||!strcmp(name, "HIGINGpara")) {
715 genType = kHijingPara;
718 printf("Fill tracks generated by %s %d\n", name, genType);
722 // Fill Cells with track information
725 printf("\n AliEMCALJetFinder::FillFromTracks(%i,%i) ",flag,ich);
730 if (!fLego) BookLego();
732 if (flag == 0) fLego->Reset();
734 // Access particle information
735 Int_t npart = (gAlice->GetHeader())->GetNprimary();
736 Int_t ntr = (gAlice->GetHeader())->GetNtrack();
737 printf(" : #primary particles %i # tracks %i : (before) Sum.Et %f\n",
738 npart, ntr, fLego->Integral());
743 // 1: selected for jet finding
746 if (fTrackList) delete[] fTrackList;
747 if (fPtT) delete[] fPtT;
748 if (fEtaT) delete[] fEtaT;
749 if (fPhiT) delete[] fPhiT;
750 if (fPdgT) delete[] fPdgT;
752 fTrackList = new Int_t [npart];
753 fPtT = new Float_t[npart];
754 fEtaT = new Float_t[npart];
755 fPhiT = new Float_t[npart];
756 fPdgT = new Int_t[npart];
760 Float_t chTmp=0.0; // charge of current particle
763 // this is for Pythia ??
764 for (Int_t part = 0; part < npart; part++) {
765 TParticle *mPart = gAlice->GetMCApp()->Particle(part);
766 Int_t mpart = mPart->GetPdgCode();
767 Int_t child1 = mPart->GetFirstDaughter();
768 Float_t pT = mPart->Pt();
769 Float_t p = mPart->P();
770 Float_t phi = mPart->Phi();
772 if(pT > 0.001) eta = mPart->Eta();
773 Float_t theta = mPart->Theta();
774 if (fDebug>=2 && mPart->GetStatusCode()==1) {
775 printf("ind %7i part %7i -> child1 %5i child2 %5i Status %5i\n",
776 part, mpart, child1, mPart->GetLastDaughter(), mPart->GetStatusCode());
779 if (fDebug >= 2 && genType == kPythia) {
780 if (part == 6 || part == 7)
782 printf("\n Simulated Jet (pt, eta, phi): %d %f %f %f\n",
783 part-5, pT, eta, phi);
787 fTrackList[part] = 0;
788 fPtT[part] = pT; // must be change after correction for resolution !!!
793 // final state particles only
795 if (genType == kPythia) {
796 if (mPart->GetStatusCode() != 1) continue;
797 } else if (genType == kHijing) {
798 if (child1 >= 0 && child1 < npart) continue;
802 TParticlePDG* pdgP = 0;
803 // charged or neutral
804 pdgP = mPart->GetPDG();
805 chTmp = pdgP->Charge() / 3.; // 13-feb-2001!!
812 if (mpart != kNeutron &&
813 mpart != kNeutronBar &&
814 mpart != kK0Long) continue;
817 } else if (ich == 2) {
818 if (mpart == kNeutron ||
819 mpart == kNeutronBar ||
820 mpart == kK0Long) continue;
823 if (TMath::Abs(eta)<=0.9) fNChTpc++;
825 if (child1 >= 0 && child1 < npart) continue;
827 if (eta > fEtaMax || eta < fEtaMin) continue;
828 if (phi > fPhiMax || phi < fPhiMin ) continue;
831 printf("\n=>nsel:%5d mpart %5d child1 %5d eta %6.2f phi %6.2f pT %6.2f ch %3.0f ",
832 part, mpart, child1, eta, phi, pT, chTmp);
835 // Momentum smearing goes here ...
839 if (fSmear && TMath::Abs(chTmp)) {
840 pw = AliEMCALFast::SmearMomentum(1,p);
841 // p changed - take into account when calculate pT,
844 if(fDebug >= 4) printf("\n Smearing : p %8.4f change to %8.4f ", p, pw);
848 // Tracking Efficiency and TPC acceptance goes here ...
850 if (fEffic && TMath::Abs(chTmp)) {
851 eff = 0.9; // AliEMCALFast::Efficiency(2,p);
852 if(fhEff) fhEff->Fill(p, eff);
853 if (AliEMCALFast::RandomReject(eff)) {
854 if(fDebug >= 5) printf(" reject due to unefficiency ");
859 // Correction of Hadronic Energy goes here ...
862 // phi propagation for hadronic correction
864 Bool_t curls = kFALSE; // hit two the EMCAL (no curl)
865 Float_t phiHC=0.0, dpH=0.0, dphi=0.0, eTdpH=0;
866 if(TMath::Abs(chTmp)) {
867 // hadr. correction only for charge particle
868 dphi = PropagatePhi(pT, chTmp, curls);
871 printf("\n Delta phi %f pT %f ", dphi, pT);
872 if (curls) printf("\n !! Track is curling");
874 if(!curls) fhTrackPtBcut->Fill(pT);
876 if (fHCorrection && !curls) {
877 if (!fHadronCorrector)
878 Fatal("AliEMCALJetFinder",
879 "Hadronic energy correction required but not defined !");
881 dpH = fHadronCorrector->GetEnergy(p, eta, 7);
882 eTdpH = dpH*TMath::Sin(theta);
884 if (fDebug >= 7) printf(" phi %f phiHC %f eTcorr %f\n",
885 phi, phiHC, -eTdpH); // correction is negative
887 xbin = fLego->GetXaxis()->FindBin(eta);
888 ybin = fLego->GetYaxis()->FindBin(phiHC);
889 cout <<"Hadron Correction affected bin - contents before correction : "<<fLego->GetBinContent(xbin,ybin)<<endl;
890 fLego->Fill(eta, phi, -fSamplingF*eTdpH );
891 cout <<"Hadron Correction affected bin - contents after correction : "<<fLego->GetBinContent(xbin,ybin)<<endl;
892 fhLegoHadrCorr->Fill(eta, phi, fSamplingF*eTdpH);
896 // More to do ? Just think about it !
898 if (phi > fPhiMax || phi < fPhiMin ) continue;
900 if(TMath::Abs(chTmp) ) { // charge particle
901 if (pT > fPtCut && !curls) {
902 if (fDebug >= 8) printf("Charge : fLego->Fill(%5.2f, %5.2f, %6.2f, %d)\n",
903 eta , phi, pT, fNtS);
904 fLego->Fill(eta, phi, pT);
905 fhLegoTracks->Fill(eta, phi, pT); // 20-feb for checking
906 fTrackList[part] = 1;
909 } else if(ich > 0 || fK0N) {
910 // case of n, nbar and K0L
911 if (fDebug >= 9) printf("Neutral : fLego->Fill(%5.2f, %5.2f, %6.2f, %d)\n",
912 eta , phi, pT, fNtS);
913 fLego->Fill(eta, phi, pT);
914 fTrackList[part] = 1;
919 for(Int_t i=0; i<fLego->GetSize(); i++) {
920 Float_t etc = (*fLego)[i];
921 if (etc > fMinCellEt) etsum += etc;
924 printf("FillFromTracks: Sum above threshold %f -> %f (%f)\n", fMinCellEt, etsum, fLego->Integral());
925 printf(" Track selected(fNtS) %i \n", fNtS);
930 void AliEMCALJetFinder::FillFromHits(Int_t flag)
933 // Fill Cells with hit information
937 printf("\n AliEMCALJetFinder::FillFromHits(%i)\n",flag);
941 if (!fLego) BookLego();
942 // Reset eta-phi maps if needed
943 if (flag == 0) { // default behavior
945 fhLegoTracks->Reset();
946 fhLegoEMCAL->Reset();
947 fhLegoHadrCorr->Reset();
949 // Initialize from background event if available
951 // Access hit information
952 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
953 AliLoader *emcalLoader = AliRunLoader::GetRunLoader()->GetDetectorLoader("EMCAL");
954 TTree *treeH = emcalLoader->TreeH();
955 Int_t ntracks = (Int_t) treeH->GetEntries();
960 // Double_t etH = 0.0;
962 for (Int_t track=0; track<ntracks;track++) {
964 nbytes += treeH->GetEvent(track);
968 for(AliEMCALHit* mHit=(AliEMCALHit*) pEMCAL->FirstHit(-1);
970 mHit=(AliEMCALHit*) pEMCAL->NextHit())
972 Float_t x = mHit->X(); // x-pos of hit
973 Float_t y = mHit->Y(); // y-pos
974 Float_t z = mHit->Z(); // z-pos
975 Float_t eloss = mHit->GetEnergy(); // deposited energy
977 Float_t r = TMath::Sqrt(x*x+y*y);
978 Float_t theta = TMath::ATan2(r,z);
979 Float_t eta = -TMath::Log(TMath::Tan(theta/2.));
980 Float_t phi = TMath::ATan2(y,x);
982 if (fDebug >= 21) printf("\n Hit %f %f %f %f %f %f %f %f", x, y, z, eloss, r, eta, phi, fSamplingF);
984 // etH = fSamplingF*eloss*TMath::Sin(theta);
985 fLego->Fill(eta, phi, eloss);
989 // Transition from deposit energy to eT (eT = de*SF*sin(theta))
991 for(Int_t i=1; i<=fLego->GetNbinsX(); i++){ // eta
992 Double_t sinTheta = fhSinTheta->GetBinContent(i), eT=0;
993 for(Int_t j=1; j<=fLego->GetNbinsY(); j++){ // phi
994 eT = fLego->GetBinContent(i,j)*fSamplingF*sinTheta;
995 fLego->SetBinContent(i,j,eT);
996 // copy content of fLego to fhLegoEMCAL (fLego and fhLegoEMCAL are identical)
997 fhLegoEMCAL->SetBinContent(i,j,eT);
998 if (eT > fMinCellEt) etsum += eT;
1002 // for(Int_t i=0; i<fLego->GetSize(); i++) {
1003 // (*fhLegoEMCAL)[i] = (*fLego)[i];
1004 // Float_t etc = (*fLego)[i];
1005 // if (etc > fMinCellEt) etsum += etc;
1008 printf("FillFromHits: Sum above threshold %f -> %f \n ", fMinCellEt, etsum);
1012 void AliEMCALJetFinder::FillFromDigits(Int_t flag)
1015 // Fill Cells with digit information
1020 if (!fLego) BookLego();
1021 if (flag == 0) fLego->Reset();
1028 TClonesArray* digs = new TClonesArray("AliEMCALDigit", 10000);
1029 TTree *treeD = gAlice->TreeD();
1030 TBranchElement* branchDg = (TBranchElement*)
1031 treeD->GetBranch("EMCAL");
1033 if (!branchDg) Fatal("AliEMCALJetFinder",
1034 "Reading digits requested but no digits in file !");
1036 branchDg->SetAddress(&digs);
1037 Int_t nent = (Int_t) branchDg->GetEntries();
1039 // Connect digitizer
1041 AliEMCALDigitizer* digr = new AliEMCALDigitizer();
1042 TBranchElement* branchDr = (TBranchElement*)
1043 treeD->GetBranch("AliEMCALDigitizer");
1044 branchDr->SetAddress(&digr);
1047 nbytes += branchDg->GetEntry(0);
1048 nbytes += branchDr->GetEntry(0);
1050 // Get digitizer parameters
1051 Float_t ecADCped = digr->GetECApedestal();
1052 Float_t ecADCcha = digr->GetECAchannel();
1054 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
1055 AliEMCALGeometry* geom =
1056 AliEMCALGeometry::GetInstance(pEMCAL->GetTitle(), "");
1059 Int_t ndig = digs->GetEntries();
1060 Info("FillFromDigits","Number of Digits: %d %d\n Parameters: EC: %f %f\n Geometry: %d %d",
1061 ndig, nent, ecADCped, ecADCcha, geom->GetNEta(), geom->GetNPhi());
1068 while ((sdg = (AliEMCALDigit*)(next())))
1070 Double_t pedestal = 0.;
1071 Double_t channel = 0.;
1072 if (geom->CheckAbsCellId(sdg->GetId())) { // May 31, 2006; IsInECA(Int_t) -> CheckAbsCellId
1073 pedestal = ecADCped;
1077 Fatal("FillFromDigits", "unexpected digit is number!") ;
1079 Float_t eta = sdg->GetEta();
1080 Float_t phi = sdg->GetPhi() * TMath::Pi()/180.;
1081 Float_t amp = (Float_t) (channel*(sdg->GetAmp())-pedestal);
1084 Info("FillFromDigits", "Digit: eta %8.3f phi %8.3f amp %8.3f %8d",
1085 eta, phi, amp, sdg->GetAmp());
1087 fLego->Fill(eta, phi, fSamplingF*amp);
1095 void AliEMCALJetFinder::FillFromHitFlaggedTracks(Int_t flag)
1098 // Fill Cells with hit information
1103 if (!fLego) BookLego();
1105 if (flag == 0) fLego->Reset();
1107 // Flag charged tracks passing through TPC which
1108 // are associated to EMCAL Hits
1109 BuildTrackFlagTable();
1112 // Access particle information
1113 TTree *treeK = gAlice->TreeK();
1114 Int_t ntracks = (Int_t) treeK->GetEntries();
1116 if (fPtT) delete[] fPtT;
1117 if (fEtaT) delete[] fEtaT;
1118 if (fPhiT) delete[] fPhiT;
1119 if (fPdgT) delete[] fPdgT;
1121 fPtT = new Float_t[ntracks];
1122 fEtaT = new Float_t[ntracks];
1123 fPhiT = new Float_t[ntracks];
1124 fPdgT = new Int_t[ntracks];
1129 for (Int_t track = 0; track < ntracks; track++) {
1130 TParticle *mPart = gAlice->GetMCApp()->Particle(track);
1131 Float_t pT = mPart->Pt();
1132 Float_t phi = mPart->Phi();
1133 Float_t eta = mPart->Eta();
1135 if(fTrackList[track]) {
1139 fPdgT[track] = mPart->GetPdgCode();
1141 if (track < 2) continue; //Colliding particles?
1142 if (pT == 0 || pT < fPtCut) continue;
1144 fLego->Fill(eta, phi, pT);
1150 void AliEMCALJetFinder::FillFromParticles()
1152 // 26-feb-2002 PAI - for checking all chain
1153 // Work on particles level; accept all particle (not neutrino )
1155 Double_t pX=0, pY=0, pZ=0, energy=0; // checking conservation law
1159 if (!fLego) BookLego();
1162 // Access particles information
1163 Int_t npart = (gAlice->GetHeader())->GetNprimary();
1164 if (fDebug >= 2 || npart<=0) {
1165 printf(" AliEMCALJetFinder::FillFromParticles : npart %i\n", npart);
1166 if(npart<=0) return;
1170 RearrangeParticlesMemory(npart);
1172 // Go through the particles
1173 Int_t mpart, child1, child2, geantPdg;
1174 Float_t pT, phi, eta, e=0, px=0, py=0, pz=0;
1176 for (Int_t part = 0; part < npart; part++) {
1178 fTrackList[part] = 0;
1180 mPart = gAlice->GetMCApp()->Particle(part);
1181 mpart = mPart->GetPdgCode();
1182 child1 = mPart->GetFirstDaughter();
1183 child2 = mPart->GetLastDaughter();
1191 e = mPart->Energy();
1193 // see pyedit in Pythia's text
1195 if (IsThisPartonsOrDiQuark(mpart)) continue;
1196 printf("%5i: %5i(%2i) px %5.1f py %5.1f pz %6.1f e %6.1f childs %5i,%5i \n",
1197 part, mpart, geantPdg, px, py, pz, e, child1, child2);
1199 // exclude partons (21 - gluon, 92 - string)
1202 // exclude neutrinous also ??
1203 if (fDebug >= 11 && pT>0.01)
1204 printf("\n part:%5d mpart %5d eta %9.2f phi %9.2f pT %9.2f ",
1205 part, mpart, eta, phi, pT);
1210 fPdgT[part] = mpart;
1214 if (child1 >= 0 && child1 < npart) continue;
1216 // printf("%4i -> %5i(%3i) px %6.1f py %6.1f pz %7.1f e %8.2f child1 %5i %s\n",
1217 // part, mpart, geantPdg, px, py, pz, e, child1, name.Data());
1224 if (TMath::Abs(eta) <= 0.9) fNChTpc++;
1226 if (eta > fEtaMax || eta < fEtaMin) continue;
1227 if (phi > fPhiMax || phi < fPhiMin ) continue;
1229 if(fK0N==0 ) { // exclude neutral hadrons
1230 if (mpart == kNeutron || mpart == kNeutronBar || mpart == kK0Long) continue;
1232 fTrackList[part] = 1;
1233 fLego->Fill(eta, phi, pT);
1236 printf("\n PX %8.2f PY %8.2f PZ %8.2f E %8.2f \n",
1237 pX, pY, pZ, energy);
1239 if(fhChPartMultInTpc) fhChPartMultInTpc->Fill(fNChTpc);
1242 void AliEMCALJetFinder::FillFromPartons()
1244 // function under construction - 13-feb-2002 PAI
1247 printf("\n AliEMCALJetFinder::FillFromPartons()\n");
1251 if (!fLego) BookLego();
1254 // Access particle information
1255 Int_t npart = (gAlice->GetHeader())->GetNprimary();
1256 if (fDebug >= 2 || npart<=0)
1257 printf("\n AliEMCALJetFinder::FillFromPartons : npart %i\n", npart);
1258 fNt = 0; // for FindTracksInJetCone
1261 // Go through the partons
1263 for (Int_t part = 8; part < npart; part++) {
1264 TParticle *mPart = gAlice->GetMCApp()->Particle(part);
1265 Int_t mpart = mPart->GetPdgCode();
1266 // Int_t child1 = MPart->GetFirstDaughter();
1267 Float_t pT = mPart->Pt();
1268 // Float_t p = MPart->P();
1269 Float_t phi = mPart->Phi();
1270 Float_t eta = mPart->Eta();
1271 // Float_t theta = MPart->Theta();
1272 statusCode = mPart->GetStatusCode();
1274 // accept partons (21 - gluon, 92 - string)
1275 if (!(TMath::Abs(mpart) <= 6 || mpart == 21 ||mpart == 92)) continue;
1276 if (fDebug > 1 && pT>0.01)
1277 printf("\n part:%5d mpart %5d status %5d eta %8.2f phi %8.2f pT %8.2f ",
1278 part, mpart, statusCode, eta, phi, pT);
1279 // if (fDebug >= 3) MPart->Print();
1280 // accept partons before fragmentation - p.57 in Pythia manual
1281 // if(statusCode != 1) continue;
1283 if (eta > fEtaMax || eta < fEtaMin) continue;
1284 if (phi > fPhiMax || phi < fPhiMin ) continue;
1286 // if (child1 >= 0 && child1 < npart) continue;
1289 fLego->Fill(eta, phi, pT);
1295 void AliEMCALJetFinder::BuildTrackFlagTable() {
1297 // Method to generate a lookup table for TreeK particles
1298 // which are linked to hits in the EMCAL
1300 // --Author: J.L. Klay
1302 // Access hit information
1303 AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
1305 TTree *treeK = gAlice->TreeK(); // Get the number of entries in the kine tree
1306 Int_t nKTrks = (Int_t) treeK->GetEntries(); // (Number of particles created somewhere)
1308 if(fTrackList) delete[] fTrackList; //Make sure we get rid of the old one
1309 fTrackList = new Int_t[nKTrks]; //before generating a new one
1311 for (Int_t i = 0; i < nKTrks; i++) { //Initialize members to 0
1315 AliLoader *emcalLoader = AliRunLoader::GetRunLoader()->GetDetectorLoader("EMCAL");
1316 //AliEMCALGetter * gime = AliEMCALGetter::Instance() ;
1317 // TTree *treeH = gAlice->TreeH();
1318 TTree *treeH = emcalLoader->TreeH();
1319 Int_t ntracks = (Int_t) treeH->GetEntries();
1325 for (Int_t track=0; track<ntracks;track++) {
1326 gAlice->ResetHits();
1327 nbytes += treeH->GetEvent(track);
1333 for(AliEMCALHit* mHit=(AliEMCALHit*) pEMCAL->FirstHit(-1);
1335 mHit=(AliEMCALHit*) pEMCAL->NextHit())
1337 Int_t iTrk = mHit->Track(); // track number
1338 Int_t idprim = mHit->GetPrimary(); // primary particle
1340 //Determine the origin point of this particle - it made a hit in the EMCAL
1341 TParticle *trkPart = gAlice->GetMCApp()->Particle(iTrk);
1342 TParticlePDG *trkPdg = trkPart->GetPDG();
1343 Int_t trkCode = trkPart->GetPdgCode();
1345 if (trkCode < 10000) { //Big Ions cause problems for
1346 trkChg = trkPdg->Charge(); //this function. Since they aren't
1347 } else { //likely to make it very far, set
1348 trkChg = 0.0; //their charge to 0 for the Flag test
1350 Float_t vxTrk = trkPart->Vx();
1351 Float_t vyTrk = trkPart->Vy();
1352 Float_t vrTrk = TMath::Sqrt(vxTrk*vxTrk+vyTrk*vyTrk);
1353 fTrackList[iTrk] = SetTrackFlag(vrTrk,trkCode,trkChg);
1355 //Loop through the ancestry of the EMCAL entrance particles
1356 Int_t ancestor = trkPart->GetFirstMother(); //Get track's Mother
1357 while (ancestor != -1) {
1358 TParticle *ancPart = gAlice->GetMCApp()->Particle(ancestor); //get particle info on ancestor
1359 TParticlePDG *ancPdg = ancPart->GetPDG();
1360 Int_t ancCode = ancPart->GetPdgCode();
1362 if (ancCode < 10000) {
1363 ancChg = ancPdg->Charge();
1367 Float_t vxAnc = ancPart->Vx();
1368 Float_t vyAnc = ancPart->Vy();
1369 Float_t vrAnc = TMath::Sqrt(vxAnc*vxAnc+vyAnc*vyAnc);
1370 fTrackList[ancestor] = SetTrackFlag(vrAnc,ancCode,ancChg);
1371 ancestor = ancPart->GetFirstMother(); //Get the next ancestor
1374 //Determine the origin point of the primary particle associated with the hit
1375 TParticle *primPart = gAlice->GetMCApp()->Particle(idprim);
1376 TParticlePDG *primPdg = primPart->GetPDG();
1377 Int_t primCode = primPart->GetPdgCode();
1379 if (primCode < 10000) {
1380 primChg = primPdg->Charge();
1384 Float_t vxPrim = primPart->Vx();
1385 Float_t vyPrim = primPart->Vy();
1386 Float_t vrPrim = TMath::Sqrt(vxPrim*vxPrim+vyPrim*vyPrim);
1387 fTrackList[idprim] = SetTrackFlag(vrPrim,primCode,primChg);
1393 Int_t AliEMCALJetFinder
1394 ::SetTrackFlag(Float_t radius, Int_t code, Double_t charge) {
1395 // Set the flag for the track
1400 if (charge == 0) neutral = 1;
1402 if (TMath::Abs(code) <= 6 ||
1404 code == 92) parton = 1;
1406 //It's not a parton, it's charged and it went through the TPC
1407 if (!parton && !neutral && radius <= 84.0) flag = 1;
1414 void AliEMCALJetFinder::SaveBackgroundEvent(const char *name)
1416 // Saves the eta-phi lego and the tracklist and name of file with BG events
1420 (*fLegoB) = (*fLegoB) + (*fLego);
1422 printf("\n AliEMCALJetFinder::SaveBackgroundEvent() (fLegoB) %f = %f(fLego) \n",
1423 fLegoB->Integral(), fLego->Integral());
1426 if (fPtB) delete[] fPtB;
1427 if (fEtaB) delete[] fEtaB;
1428 if (fPhiB) delete[] fPhiB;
1429 if (fPdgB) delete[] fPdgB;
1430 if (fTrackListB) delete[] fTrackListB;
1432 fPtB = new Float_t[fNtS];
1433 fEtaB = new Float_t[fNtS];
1434 fPhiB = new Float_t[fNtS];
1435 fPdgB = new Int_t [fNtS];
1436 fTrackListB = new Int_t [fNtS];
1440 for (Int_t i = 0; i < fNt; i++) {
1441 if (!fTrackList[i]) continue;
1442 fPtB [fNtB] = fPtT [i];
1443 fEtaB[fNtB] = fEtaT[i];
1444 fPhiB[fNtB] = fPhiT[i];
1445 fPdgB[fNtB] = fPdgT[i];
1446 fTrackListB[fNtB] = 1;
1450 printf(" fNtB %i => fNtS %i #particles %i \n", fNtB, fNtS, fNt);
1452 if(strlen(name) == 0) {
1453 TSeqCollection *li = gROOT->GetListOfFiles();
1455 for(Int_t i=0; i<li->GetSize(); i++) {
1456 nf = ((TFile*)li->At(i))->GetName();
1457 if(nf.Contains("backgorund")) break;
1463 printf("BG file name is \n %s\n", fBGFileName.Data());
1466 void AliEMCALJetFinder::InitFromBackground()
1470 if (fDebug) printf("\n AliEMCALJetFinder::InitFromBackground() ");
1474 (*fLego) = (*fLego) + (*fLegoB);
1476 printf("\n AliEMCALJetFinder::InitBackgroundEvent() (fLego) %f = %f(fLegoB) \n",
1477 fLego->Integral(), fLegoB->Integral());
1479 printf(" => fLego undefined \n");
1484 void AliEMCALJetFinder::FindTracksInJetCone()
1487 // Build list of tracks inside jet cone
1490 Int_t njet = Njets();
1491 for (Int_t nj = 0; nj < njet; nj++)
1493 Float_t etaj = JetEtaW(nj);
1494 Float_t phij = JetPhiW(nj);
1495 Int_t nT = 0; // number of associated tracks
1497 // Loop over particles in current event
1498 for (Int_t part = 0; part < fNt; part++) {
1499 if (!fTrackList[part]) continue;
1500 Float_t phi = fPhiT[part];
1501 Float_t eta = fEtaT[part];
1502 Float_t dr = TMath::Sqrt((etaj-eta)*(etaj-eta) +
1503 (phij-phi)*(phij-phi));
1504 if (dr < fConeRadius) {
1505 fTrackList[part] = nj+2;
1510 // Same for background event if available
1513 for (Int_t part = 0; part < fNtB; part++) {
1514 Float_t phi = fPhiB[part];
1515 Float_t eta = fEtaB[part];
1516 Float_t dr = TMath::Sqrt((etaj-eta)*(etaj-eta) +
1517 (phij-phi)*(phij-phi));
1518 fTrackListB[part] = 1;
1520 if (dr < fConeRadius) {
1521 fTrackListB[part] = nj+2;
1525 } // Background available ?
1527 Int_t nT0 = nT + nTB;
1528 printf("Total number of tracks %d\n", nT0);
1530 if (nT0 > 1000) nT0 = 1000;
1532 Float_t* ptT = new Float_t[nT0];
1533 Float_t* etaT = new Float_t[nT0];
1534 Float_t* phiT = new Float_t[nT0];
1535 Int_t* pdgT = new Int_t[nT0];
1540 for (Int_t part = 0; part < fNt; part++) {
1541 if (fTrackList[part] == nj+2) {
1543 for (j=iT-1; j>=0; j--) {
1544 if (fPtT[part] > ptT[j]) {
1549 for (j=iT-1; j>=index; j--) {
1550 ptT [j+1] = ptT [j];
1551 etaT[j+1] = etaT[j];
1552 phiT[j+1] = phiT[j];
1553 pdgT[j+1] = pdgT[j];
1555 ptT [index] = fPtT [part];
1556 etaT[index] = fEtaT[part];
1557 phiT[index] = fPhiT[part];
1558 pdgT[index] = fPdgT[part];
1560 } // particle associated
1561 if (iT > nT0) break;
1565 for (Int_t part = 0; part < fNtB; part++) {
1566 if (fTrackListB[part] == nj+2) {
1568 for (j=iT-1; j>=0; j--) {
1569 if (fPtB[part] > ptT[j]) {
1575 for (j=iT-1; j>=index; j--) {
1576 ptT [j+1] = ptT [j];
1577 etaT[j+1] = etaT[j];
1578 phiT[j+1] = phiT[j];
1579 pdgT[j+1] = pdgT[j];
1581 ptT [index] = fPtB [part];
1582 etaT[index] = fEtaB[part];
1583 phiT[index] = fPhiB[part];
1584 pdgT[index] = fPdgB[part];
1586 } // particle associated
1587 if (iT > nT0) break;
1589 } // Background available ?
1591 fJetT[nj]->SetTrackList(nT0, ptT, etaT, phiT, pdgT);
1600 Float_t AliEMCALJetFinder::PropagatePhi(Float_t pt, Float_t charge, Bool_t& curls)
1602 // Propagates phi angle to EMCAL radius
1604 static Float_t b = 0.0, rEMCAL = -1.0;
1606 b = gAlice->Field()->SolenoidField();
1607 // Get EMCAL radius in cm
1608 rEMCAL = AliEMCALGeometry::GetInstance()->GetIPDistance();
1616 Float_t rB = 3335.6 * pt / b; // [cm] (case of |charge|=1)
1618 // check if particle is curling below EMCAL
1619 if (2.*rB < rEMCAL) {
1624 // if not calculate delta phi
1625 Float_t phi = TMath::ACos(1.-rEMCAL*rEMCAL/(2.*rB*rB));
1626 dPhi = TMath::ATan2(1.-TMath::Cos(phi), TMath::Sin(phi));
1627 dPhi = -TMath::Sign(dPhi, charge);
1632 void hf1(Int_t& , Float_t& , Float_t& )
1634 // dummy for hbook calls
1638 void AliEMCALJetFinder::DrawLego(const char *opt)
1641 if(fLego) fLego->Draw(opt);
1644 void AliEMCALJetFinder::DrawLegoBackground(const char *opt)
1646 // Draw background lego
1647 if(fLegoB) fLegoB->Draw(opt);
1650 void AliEMCALJetFinder::DrawLegoEMCAL(const char *opt)
1653 if(fhLegoEMCAL) fhLegoEMCAL->Draw(opt);
1656 void AliEMCALJetFinder::DrawHistsForTuning(Int_t mode)
1659 static TPaveText *varLabel=0;
1661 fC1 = new TCanvas("C1","Hists. for tunning", 0,25,600,800);
1671 fhCellEMCALEt->Draw();
1676 fhTrackPtBcut->SetLineColor(2);
1677 fhTrackPtBcut->Draw("same");
1682 varLabel = new TPaveText(0.05,0.5,0.95,0.95,"NDC");
1683 varLabel->SetTextAlign(12);
1684 varLabel->SetFillColor(19); // see TAttFill
1685 TString tmp(GetTitle());
1686 varLabel->ReadFile(GetFileNameForParameters());
1690 if(mode) { // for saving picture to the file
1691 TString stmp(GetFileNameForParameters());
1692 stmp.ReplaceAll("_Par.txt",".ps");
1693 fC1->Print(stmp.Data());
1697 void AliEMCALJetFinder::PrintParameters(Int_t mode)
1699 // Print all parameters out
1702 if(mode==0) file = stdout; // output to terminal
1704 file = fopen(GetFileNameForParameters(),"w");
1705 if(file==0) file = stdout;
1707 fprintf(file,"==== Filling lego ==== \n");
1708 fprintf(file,"Sampling fraction %6.3f ", fSamplingF);
1709 fprintf(file,"Smearing %6i ", fSmear);
1710 fprintf(file,"Efficiency %6i\n", fEffic);
1711 fprintf(file,"Hadr.Correct. %6i ", fHCorrection);
1712 fprintf(file,"P_{T} Cut of ch.par. %6.2f\n", fPtCut);
1713 fprintf(file,"==== Jet finding ==== \n");
1714 fprintf(file,"Cone radius %6.2f ", fConeRadius);
1715 fprintf(file,"Seed E_{T} %6.1f\n", fEtSeed);
1716 fprintf(file,"Min E_{T} of cell %6.1f ", fMinCellEt);
1717 fprintf(file,"Min E_{T} of jet %6.1f\n", fMinJetEt);
1719 fprintf(file,"==== Bg subtraction ==== \n");
1720 fprintf(file,"BG subtraction %6i ", fMode);
1721 fprintf(file,"Min cone move %6.2f\n", fMinMove);
1722 fprintf(file,"Max cone move %6.2f ", fMaxMove);
1723 fprintf(file,"%% change for BG %6.4f\n", fPrecBg);
1725 fprintf(file,"==== No Bg subtraction ==== \n");
1727 printf("BG file name is %s \n", fBGFileName.Data());
1728 if(file != stdout) fclose(file);
1731 void AliEMCALJetFinder::DrawLegos()
1735 fC1 = new TCanvas("C1","Hists. for tunning", 0,25,600,800);
1739 gStyle->SetOptStat(111111);
1741 Int_t nent1, nent2, nent3, nent4;
1742 Double_t int1, int2, int3, int4;
1743 nent1 = (Int_t)fLego->GetEntries();
1744 int1 = fLego->Integral();
1746 if(int1) fLego->Draw("lego");
1748 nent2 = (Int_t)fhLegoTracks->GetEntries();
1749 int2 = fhLegoTracks->Integral();
1751 if(int2) fhLegoTracks->Draw("lego");
1753 nent3 = (Int_t)fhLegoEMCAL->GetEntries();
1754 int3 = fhLegoEMCAL->Integral();
1756 if(int3) fhLegoEMCAL->Draw("lego");
1758 nent4 = (Int_t)fhLegoHadrCorr->GetEntries();
1759 int4 = fhLegoHadrCorr->Integral();
1761 if(int4) fhLegoHadrCorr->Draw("lego");
1763 // just for checking
1764 printf(" Integrals \n");
1765 printf("lego %10.3f \ntrack %10.3f \nhits %10.3f \nHCorr %10.3f\n-- %10.3f(must be 0)\n",
1766 int1, int2, int3, int4, int1 - (int2 + int3 - int4));
1769 const Char_t* AliEMCALJetFinder::GetFileNameForParameters(const char* dir)
1771 // Get paramters from a file
1773 if(strlen(dir)) tmp = dir;
1779 void AliEMCALJetFinder::RearrangeParticlesMemory(Int_t npart)
1781 // See FillFromTracks() - npart must be positive
1782 if (fTrackList) delete[] fTrackList;
1783 if (fPtT) delete[] fPtT;
1784 if (fEtaT) delete[] fEtaT;
1785 if (fPhiT) delete[] fPhiT;
1786 if (fPdgT) delete[] fPdgT;
1789 fTrackList = new Int_t [npart];
1790 fPtT = new Float_t[npart];
1791 fEtaT = new Float_t[npart];
1792 fPhiT = new Float_t[npart];
1793 fPdgT = new Int_t[npart];
1795 printf("AliEMCALJetFinder::RearrangeParticlesMemory : npart = %d\n", npart);
1799 Bool_t AliEMCALJetFinder::IsThisPartonsOrDiQuark(Int_t pdg)
1801 // Return quark info
1802 Int_t absPdg = TMath::Abs(pdg);
1803 if(absPdg<=6) return kTRUE; // quarks
1804 if(pdg == 21) return kTRUE; // gluon
1805 if(pdg == 92) return kTRUE; // string
1807 // see p.51 of Pythia Manual
1808 // Not include diquarks with c and b quark - 4-mar-2002
1809 // ud_0,sd_0,su_0; dd_1,ud_1,uu_1; sd_1,su_1,ss_1
1810 static Int_t diquark[9]={2101,3101,3201, 1103,2103,2203, 3103,3203,3303};
1811 for(Int_t i=0; i<9; i++) if(absPdg == diquark[i]) return kTRUE; // diquarks
1816 void AliEMCALJetFinder::FindChargedJet()
1819 // Find jet from charged particle information only
1834 for (part = 0; part < fNt; part++) {
1835 if (!fTrackList[part]) continue;
1836 if (fPtT[part] > fEtSeed) nseed++;
1838 printf("\nThere are %d seeds (%d)\n", nseed, fNtS);
1839 Int_t* iSeeds = new Int_t[nseed];
1842 for (part = 0; part < fNt; part++) {
1843 if (!fTrackList[part]) continue;
1844 if (fPtT[part] > fEtSeed) iSeeds[nseed++] = part;
1855 // Find seed with highest pt
1857 Float_t ptmax = -1.;
1860 for (seed = 0; seed < nseed; seed++) {
1861 if ((pt = fPtT[iSeeds[seed]]) > ptmax && iSeeds[seed] != -1) {
1866 if (ptmax < 0.) break;
1867 jndex = iSeeds[index];
1869 // Remove from the list
1871 printf("\n Next Seed %d %f", jndex, ptmax);
1873 // Find tracks in cone around seed
1875 Float_t phiSeed = fPhiT[jndex];
1876 Float_t etaSeed = fEtaT[jndex];
1882 for (part = 0; part < fNt; part++) {
1883 if (!fTrackList[part]) continue;
1884 Float_t deta = fEtaT[part] - etaSeed;
1885 Float_t dphi = fPhiT[part] - phiSeed;
1886 Float_t dR = TMath::Sqrt(deta * deta + dphi * dphi);
1887 if (dR < fConeRadius) {
1889 Float_t theta = 2. * TMath::ATan(TMath::Exp(-fEtaT[part]));
1890 Float_t px = fPtT[part] * TMath::Cos(fPhiT[part]);
1891 Float_t py = fPtT[part] * TMath::Sin(fPhiT[part]);
1892 Float_t pz = fPtT[part] / TMath::Tan(theta);
1897 // if seed, remove it
1899 for (seed = 0; seed < nseed; seed++) {
1900 if (part == iSeeds[seed]) iSeeds[seed] = -1;
1906 // Estimate of jet direction
1907 Float_t phiJ = TMath::ATan2(pyJ, pxJ);
1908 Float_t thetaJ = TMath::ATan2(TMath::Sqrt(pxJ * pxJ + pyJ * pyJ), pzJ);
1909 Float_t etaJ = TMath::Log(TMath::Tan(thetaJ / 2.));
1910 // Float_t ptJ = TMath::Sqrt(pxJ * pxJ + pyJ * pyJ);
1913 // Sum up all energy
1915 Int_t iPhi0 = Int_t((phiJ - fPhiMin) / fDphi);
1916 Int_t iEta0 = Int_t((etaJ - fEtaMin) / fDeta);
1917 Int_t dIphi = Int_t(fConeRadius / fDphi);
1918 Int_t dIeta = Int_t(fConeRadius / fDeta);
1921 for (iPhi = iPhi0 -dIphi; iPhi < iPhi0 + dIphi; iPhi++) {
1922 for (iEta = iEta0 - dIeta; iEta < iEta0 + dIeta; iEta++) {
1923 if (iPhi < 0 || iEta < 0) continue;
1924 Float_t dPhi = fPhiMin + iPhi * fDphi;
1925 Float_t dEta = fEtaMin + iEta * fDeta;
1926 if (TMath::Sqrt(dPhi * dPhi + dEta * dEta) < fConeRadius) continue;
1927 sumE += fLego->GetBinContent(iEta, iPhi);
1933 fJetT[njets++] = new AliEMCALJet(sumE, phiJ, etaJ);
1934 FindTracksInJetCone();
1935 printf("\n Jet Energy %f %f %f %f %d\n", eT, sumE, fPtT[6], fPtT[7], njets);
1936 printf("\n Jet Phi %f %f %f \n", phiJ, fPhiT[6], fPhiT[7]);
1937 printf("\n Jet Eta %f %f %f \n", etaJ, fEtaT[6], fEtaT[7]);
1939 EMCALJETS.njet = njets;
1940 if (fWrite) WriteJets();
1943 // 16-jan-2003 - just for convenience
1944 void AliEMCALJetFinder::Browse(TBrowser* b)
1947 if(fHistsList) b->Add((TObject*)fHistsList);
1950 Bool_t AliEMCALJetFinder::IsFolder() const
1952 // Return folder status
1953 if(fHistsList) return kTRUE;
1957 const Char_t* AliEMCALJetFinder::GetNameOfVariant()
1959 // generate the literal string with info about jet finder
1961 sprintf(name, "jF_R%3.2fMinCell%4.1fPtCut%4.1fEtSeed%4.1fMinEt%4.1fBGSubtr%iSF%4.1f",
1962 fConeRadius,fMinCellEt,fPtCut,fEtSeed,fMinJetEt, fMode, fSamplingF);
1964 nt.ReplaceAll(" ","");
1965 if(fBGFileName.Length()) {
1966 Int_t i1 = fBGFileName.Index("kBackground");
1967 Int_t i2 = fBGFileName.Index("/0000") - 1;
1968 if(i1>=0 && i2>=0) {
1969 TString bg(fBGFileName(i1,i2-i1+1));
1973 printf("<I> Name of variant %s \n", nt.Data());