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 **************************************************************************/
17 /* History of cvs commits:
20 * Revision 1.1 2007/01/23 17:17:29 schutz
26 //_________________________________________________________________________
27 // Class for the analysis of gamma correlations (gamma-jet,
28 // gamma-hadron and isolation cut.
29 // This class contains 3 main methods: one to fill lists of particles (ESDs) comming
30 // from the CTS (ITS+TPC) and the calorimeters; the other one tags a candidate
31 // cluster as isolated; the last one search in the
32 // corresponing calorimeter for the highest energy cluster, identified it as
35 // Class created from old AliPHOSGammaJet
36 // (see AliRoot versions previous Release 4-09)
38 //*-- Author: Gustavo Conesa (LNF-INFN)
39 //////////////////////////////////////////////////////////////////////////////
42 // --- ROOT system ---
45 #include <TParticle.h>
48 #include "AliAnaGammaDirect.h"
50 #include "AliESDtrack.h"
51 #include "AliESDCaloCluster.h"
52 #include "Riostream.h"
55 ClassImp(AliAnaGammaDirect)
57 //____________________________________________________________________________
58 AliAnaGammaDirect::AliAnaGammaDirect(const char *name) :
59 AliAnalysisTask(name,""), fChain(0), fESD(0),
60 fOutputContainer(new TObjArray(100)),
61 fPrintInfo(0), fMinGammaPt(0.),
62 fCalorimeter(""), fEMCALPID(0),fPHOSPID(0),
63 fConeSize(0.),fPtThreshold(0.),fPtSumThreshold(0),
67 TList * list = gDirectory->GetListOfKeys() ;
71 for (index = 0 ; index < list->GetSize()-1 ; index++) {
72 //-1 to avoid GammaJet Task
73 h = dynamic_cast<TH2F*>(gDirectory->Get(list->At(index)->GetName())) ;
74 fOutputContainer->Add(h) ;
77 // Input slot #0 works with an Ntuple
78 DefineInput(0, TChain::Class());
79 // Output slot #0 writes into a TH1 container
80 DefineOutput(0, TObjArray::Class()) ;
85 //____________________________________________________________________________
86 AliAnaGammaDirect::AliAnaGammaDirect(const AliAnaGammaDirect & g) :
87 AliAnalysisTask(g), fChain(g.fChain), fESD(g.fESD),
88 fOutputContainer(g. fOutputContainer), fPrintInfo(g.fPrintInfo),
89 fMinGammaPt(g.fMinGammaPt), fCalorimeter(g.fCalorimeter),
90 fEMCALPID(g.fEMCALPID),fPHOSPID(g.fPHOSPID),
91 fConeSize(g.fConeSize),
92 fPtThreshold(g.fPtThreshold),
93 fPtSumThreshold(g.fPtSumThreshold),
94 fMakeICMethod(g.fMakeICMethod)
97 SetName (g.GetName()) ;
98 SetTitle(g.GetTitle()) ;
101 //____________________________________________________________________________
102 AliAnaGammaDirect::~AliAnaGammaDirect()
104 // Remove all pointers
105 fOutputContainer->Clear() ;
106 delete fOutputContainer ;
113 //______________________________________________________________________________
114 void AliAnaGammaDirect::ConnectInputData(const Option_t*)
116 // Initialisation of branch container and histograms
118 AliInfo(Form("*** Initialization of %s", GetName())) ;
121 fChain = dynamic_cast<TChain *>(GetInputData(0)) ;
123 AliError(Form("Input 0 for %s not found\n", GetName()));
127 // One should first check if the branch address was taken by some other task
128 char ** address = (char **)GetBranchAddress(0, "ESD");
130 fESD = (AliESD*)(*address);
133 SetBranchAddress(0, "ESD", &fESD);
138 //________________________________________________________________________
139 void AliAnaGammaDirect::CreateOutputObjects()
142 // Init parameteres and create histograms to be saved in output file and
143 // stores them in fOutputContainer
146 fOutputContainer = new TObjArray(3) ;
148 //Histograms of highest gamma identified in Event
149 fhNGamma = new TH1F("NGamma","Number of #gamma over PHOS",240,0,120);
150 fhNGamma->SetYTitle("N");
151 fhNGamma->SetXTitle("p_{T #gamma}(GeV/c)");
152 fOutputContainer->Add(fhNGamma) ;
154 fhPhiGamma = new TH2F
155 ("PhiGamma","#phi_{#gamma}",200,0,120,200,0,7);
156 fhPhiGamma->SetYTitle("#phi");
157 fhPhiGamma->SetXTitle("p_{T #gamma} (GeV/c)");
158 fOutputContainer->Add(fhPhiGamma) ;
160 fhEtaGamma = new TH2F
161 ("EtaGamma","#phi_{#gamma}",200,0,120,200,-0.8,0.8);
162 fhEtaGamma->SetYTitle("#eta");
163 fhEtaGamma->SetXTitle("p_{T #gamma} (GeV/c)");
164 fOutputContainer->Add(fhEtaGamma) ;
168 //____________________________________________________________________________
169 void AliAnaGammaDirect::CreateParticleList(TClonesArray * pl,
170 TClonesArray * plCTS,
171 TClonesArray * plEMCAL,
172 TClonesArray * plPHOS){
174 //Create a list of particles from the ESD. These particles have been measured
175 //by the Central Tracking system (TPC+ITS), PHOS and EMCAL
177 Int_t index = pl->GetEntries() ;
179 Float_t *pid = new Float_t[AliPID::kSPECIESN];
180 AliDebug(3,"Fill particle lists");
182 AliInfo(Form("fCalorimeter %s",fCalorimeter.Data()));
184 Double_t v[3] ; //vertex ;
185 fESD->GetVertex()->GetXYZ(v) ;
187 //########### PHOS ##############
188 if(fCalorimeter == "PHOS"){
190 Int_t begphos = fESD->GetFirstPHOSCluster();
191 Int_t endphos = fESD->GetFirstPHOSCluster() +
192 fESD->GetNumberOfPHOSClusters() ;
193 Int_t indexNePHOS = plPHOS->GetEntries() ;
194 AliDebug(3,Form("First PHOS particle %d, last particle %d", begphos,endphos));
196 if(fCalorimeter == "PHOS"){
197 for (npar = begphos; npar < endphos; npar++) {//////////////PHOS track loop
198 AliESDCaloCluster * clus = fESD->GetCaloCluster(npar) ; // retrieve track from esd
200 //Create a TParticle to fill the particle list
202 Float_t en = clus->GetClusterEnergy() ;
203 Float_t *p = new Float_t();
204 clus->GetGlobalPosition(p) ;
205 TVector3 pos(p[0],p[1],p[2]) ;
206 Double_t phi = pos.Phi();
207 Double_t theta= pos.Theta();
208 Double_t px = en*TMath::Cos(phi)*TMath::Sin(theta);;
209 Double_t py = en*TMath::Sin(phi)*TMath::Sin(theta);
210 Double_t pz = en*TMath::Cos(theta);
212 TParticle * particle = new TParticle() ;
213 particle->SetMomentum(px,py,pz,en) ;
214 AliDebug(4,Form("PHOS clusters: pt %f, phi %f, eta %f", particle->Pt(),particle->Phi(),particle->Eta()));
216 //Select only photons
219 //cout<<"pid "<<pid[AliPID::kPhoton]<<endl ;
221 new((*plPHOS)[indexNePHOS++]) TParticle(*particle) ;
222 else if( pid[AliPID::kPhoton] > 0.75)
223 new((*plPHOS)[indexNePHOS++]) TParticle(*particle) ;
228 //########### CTS (TPC+ITS) #####################
230 Int_t endtpc = fESD->GetNumberOfTracks() ;
231 Int_t indexCh = plCTS->GetEntries() ;
232 AliDebug(3,Form("First CTS particle %d, last particle %d", begtpc,endtpc));
234 for (npar = begtpc; npar < endtpc; npar++) {////////////// track loop
235 AliESDtrack * track = fESD->GetTrack(npar) ; // retrieve track from esd
236 //We want tracks fitted in the detectors:
237 ULong_t status=AliESDtrack::kTPCrefit;
238 status|=AliESDtrack::kITSrefit;
240 //We want tracks whose PID bit is set:
241 // ULong_t status =AliESDtrack::kITSpid;
242 // status|=AliESDtrack::kTPCpid;
244 if ( (track->GetStatus() & status) == status) {//Check if the bits we want are set
245 // Do something with the tracks which were successfully
247 Double_t en = 0; //track ->GetTPCsignal() ;
249 track->GetPxPyPz(mom) ;
250 Double_t px = mom[0];
251 Double_t py = mom[1];
252 Double_t pz = mom[2]; //Check with TPC people if this is correct.
253 Int_t pdg = 11; //Give any charged PDG code, in this case electron.
254 //I just want to tag the particle as charged
255 TParticle * particle = new TParticle(pdg, 1, -1, -1, -1, -1,
256 px, py, pz, en, v[0], v[1], v[2], 0);
258 //TParticle * particle = new TParticle() ;
259 //particle->SetMomentum(px,py,pz,en) ;
261 new((*plCTS)[indexCh++]) TParticle(*particle) ;
262 new((*pl)[index++]) TParticle(*particle) ;
266 //################ EMCAL ##############
268 Int_t begem = fESD->GetFirstEMCALCluster();
269 Int_t endem = fESD->GetFirstEMCALCluster() +
270 fESD->GetNumberOfEMCALClusters() ;
271 Int_t indexNe = plEMCAL->GetEntries() ;
273 AliDebug(3,Form("First EMCAL particle %d, last particle %d",begem,endem));
275 for (npar = begem; npar < endem; npar++) {//////////////EMCAL track loop
276 AliESDCaloCluster * clus = fESD->GetCaloCluster(npar) ; // retrieve track from esd
277 Int_t clustertype= clus->GetClusterType();
278 if(clustertype == AliESDCaloCluster::kClusterv1){
279 Float_t en = clus->GetClusterEnergy() ;
280 Float_t *p = new Float_t();
281 clus->GetGlobalPosition(p) ;
282 TVector3 pos(p[0],p[1],p[2]) ;
283 Double_t phi = pos.Phi();
284 Double_t theta= pos.Theta();
285 Double_t px = en*TMath::Cos(phi)*TMath::Sin(theta);;
286 Double_t py = en*TMath::Sin(phi)*TMath::Sin(theta);
287 Double_t pz = en*TMath::Cos(theta);
290 if(fCalorimeter == "EMCAL")
292 TParticle * particle = new TParticle() ;
293 particle->SetMomentum(px,py,pz,en) ;
294 AliDebug(4,Form("EMCAL clusters: pt %f, phi %f, eta %f", particle->Pt(),particle->Phi(),particle->Eta()));
295 if(!fEMCALPID) //Only identified particles
296 new((*plEMCAL)[indexNe++]) TParticle(*particle) ;
297 else if(pid[AliPID::kPhoton] > 0.75)
298 new((*plEMCAL)[indexNe++]) TParticle(*particle) ;
305 if( pid[AliPID::kPhoton] > 0.75) //This has to be fixen.
307 else if( pid[AliPID::kPi0] > 0.75)
311 pdg = 22; //No PID, assume all photons
313 TParticle * particle = new TParticle(pdg, 1, -1, -1, -1, -1,
314 px, py, pz, en, v[0], v[1], v[2], 0);
315 AliDebug(4,Form("EMCAL clusters: pt %f, phi %f, eta %f", particle->Pt(),particle->Phi(),particle->Eta()));
317 new((*plEMCAL)[indexNe++]) TParticle(*particle) ;
318 new((*pl)[index++]) TParticle(*particle) ;
323 AliDebug(3,"Particle lists filled");
329 //____________________________________________________________________________
330 void AliAnaGammaDirect::Exec(Option_t *)
333 // Processing of one event
336 Long64_t entry = fChain->GetReadEntry() ;
339 AliError("fESD is not connected to the input!") ;
344 AliInfo(Form("%s ----> Processing event # %lld", (dynamic_cast<TChain *>(fChain))->GetFile()->GetName(), entry)) ;
346 //CreateTLists with arrays of TParticles. Filled with particles only relevant for the analysis.
348 TClonesArray * particleList = new TClonesArray("TParticle",1000); // All particles refitted in CTS and detected in EMCAL (jet)
349 TClonesArray * plCTS = new TClonesArray("TParticle",1000); // All particles refitted in Central Tracking System (ITS+TPC)
350 TClonesArray * plNe = new TClonesArray("TParticle",1000); // All particles measured in Jet Calorimeter (EMCAL)
351 TClonesArray * plPHOS = new TClonesArray("TParticle",1000); // All particles measured in PHOS as Gamma calorimeter
352 TClonesArray * plEMCAL = new TClonesArray("TParticle",1000); // All particles measured in EMCAL as Gamma calorimeter
354 TParticle *pGamma = new TParticle(); //It will contain the kinematics of the found prompt gamma
356 //Fill lists with photons, neutral particles and charged particles
357 //look for the highest energy photon in the event inside fCalorimeter
359 AliDebug(2, "Fill particle lists, get prompt gamma");
361 //Fill particle lists
362 CreateParticleList(particleList, plCTS,plEMCAL,plPHOS);
364 if(fCalorimeter == "PHOS")
366 if(fCalorimeter == "EMCAL")
370 Bool_t iIsInPHOSorEMCAL = kFALSE ; //To check if Gamma was in any calorimeter
371 //Search highest energy prompt gamma in calorimeter
372 GetPromptGamma(plNe, plCTS, pGamma, iIsInPHOSorEMCAL) ;
374 AliDebug(1, Form("Is Gamma in %s? %d",fCalorimeter.Data(),iIsInPHOSorEMCAL));
376 //If there is any photon candidate in fCalorimeter
377 if(iIsInPHOSorEMCAL){
379 AliInfo(Form("Prompt Gamma: pt %f, phi %f, eta %f", pGamma->Pt(),pGamma->Phi(),pGamma->Eta())) ;
383 AliDebug(2, "End of analysis, delete pointers");
385 particleList->Delete() ;
392 PostData(0, fOutputContainer);
398 delete particleList ;
405 //____________________________________________________________________________
406 void AliAnaGammaDirect::GetPromptGamma(TClonesArray * pl, TClonesArray * plCTS, TParticle *pGamma, Bool_t &Is) const
408 //Search for the prompt photon in Calorimeter with pt > fMinGammaPt
412 for(Int_t ipr = 0;ipr < pl->GetEntries() ; ipr ++ ){
413 TParticle * particle = dynamic_cast<TParticle *>(pl->At(ipr)) ;
415 if((particle->Pt() > fMinGammaPt) && (particle->Pt() > pt)){
418 pGamma->SetMomentum(particle->Px(),particle->Py(),particle->Pz(),particle->Energy());
419 AliDebug(4,Form("Cluster in calo: pt %f, phi %f, eta %f", pGamma->Pt(),pGamma->Phi(),pGamma->Eta())) ;
425 if(fMakeICMethod && Is)
427 Float_t coneptsum = 0 ;
428 Bool_t icPtThres = kFALSE;
429 Bool_t icPtSum = kFALSE;
430 MakeIsolationCut(plCTS,pl, pGamma, index,
431 icPtThres, icPtSum,coneptsum);
432 if(fMakeICMethod == 1) //Pt thres method
434 if(fMakeICMethod == 2) //Pt cone sum method
439 AliDebug(3,Form("Cluster with p_{T} larger than %f found in calorimeter ", fMinGammaPt)) ;
440 AliDebug(3,Form("Gamma: pt %f, phi %f, eta %f", pGamma->Pt(),pGamma->Phi(),pGamma->Eta())) ;
441 //Fill prompt gamma histograms
442 fhNGamma ->Fill(pGamma->Pt());
443 fhPhiGamma->Fill( pGamma->Pt(),pGamma->Phi());
444 fhEtaGamma->Fill(pGamma->Pt(),pGamma->Eta());
447 AliDebug(1,Form("NO Cluster with pT larger than %f found in calorimeter ", fMinGammaPt)) ;
450 //____________________________________________________________________________
451 void AliAnaGammaDirect::InitParameters()
454 //Initialize the parameters of the analysis.
459 //Fill particle lists when PID is ok
465 fPtSumThreshold = 1.;
467 fMakeICMethod = 1; // 0 don't isolate, 1 pt thresh method, 2 cone pt sum method
470 //__________________________________________________________________
471 void AliAnaGammaDirect::MakeIsolationCut(TClonesArray * plCTS,
473 TParticle * pCandidate,
475 Bool_t &icmpt, Bool_t &icms,
476 Float_t &coneptsum) const
478 //Search in cone around a candidate particle if it is isolated
479 Float_t phiC = pCandidate->Phi() ;
480 Float_t etaC = pCandidate->Eta() ;
482 Float_t eta = -100. ;
483 Float_t phi = -100. ;
486 TParticle * particle = new TParticle();
492 //Check charged particles in cone.
493 for(Int_t ipr = 0;ipr < plCTS->GetEntries() ; ipr ++ ){
494 particle = dynamic_cast<TParticle *>(plCTS->At(ipr)) ;
496 eta = particle->Eta();
497 phi = particle->Phi() ;
499 //Check if there is any particle inside cone with pt larger than fPtThreshold
500 rad = TMath::Sqrt(TMath::Power((eta-etaC),2) +
501 TMath::Power((phi-phiC),2));
503 AliDebug(3,Form("charged in cone pt %f, phi %f, eta %f, R %f ",pt,phi,eta,rad));
505 if(pt > fPtThreshold ) n++;
507 }// charged particle loop
509 //Check neutral particles in cone.
510 for(Int_t ipr = 0;ipr < plNe->GetEntries() ; ipr ++ ){
511 if(ipr != index){//Do not count the candidate
512 particle = dynamic_cast<TParticle *>(plNe->At(ipr)) ;
514 eta = particle->Eta();
515 phi = particle->Phi() ;
517 //Check if there is any particle inside cone with pt larger than fPtThreshold
518 rad = TMath::Sqrt(TMath::Power((eta-etaC),2) +
519 TMath::Power((phi-phiC),2));
521 AliDebug(3,Form("charged in cone pt %f, phi %f, eta %f, R %f ",pt,phi,eta,rad));
523 if(pt > fPtThreshold ) n++;
526 }// neutral particle loop
530 if(coneptsum < fPtSumThreshold)
535 void AliAnaGammaDirect::Print(const Option_t * opt) const
538 //Print some relevant parameters set for the analysis
542 Info("Print", "%s %s", GetName(), GetTitle() ) ;
543 printf("IC method = %d\n", fMakeICMethod) ;
544 printf("Cone Size = %f\n", fConeSize) ;
545 printf("pT threshold = %f\n", fPtThreshold) ;
546 printf("pT sum threshold = %f\n", fPtSumThreshold) ;
547 printf("Min Gamma pT = %f\n", fMinGammaPt) ;
548 printf("Calorimeter = %s\n", fCalorimeter.Data()) ;
551 void AliAnaGammaDirect::Terminate(Option_t *)
553 // The Terminate() function is the last function to be called during
554 // a query. It always runs on the client, it can be used to present
555 // the results graphically or save the results to file.