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 //_________________________________________________________________________
18 // Class to collect two-photon invariant mass distributions for
19 // extractin raw pi0 yield.
21 //-- Author: Dmitri Peressounko (RRC "KI")
22 //_________________________________________________________________________
25 // --- ROOT system ---
26 #include "TClonesArray.h"
27 #include "TRefArray.h"
30 //---- AliRoot system ----
31 #include "AliAnaPi0.h"
33 #include "AliCaloPhoton.h"
34 #include "AliESDEvent.h"
35 #include "AliAODEvent.h"
36 #include "AliESDVertex.h"
37 #include "AliAODVertex.h"
38 #include "AliESDCaloCluster.h"
39 #include "AliAODCaloCluster.h"
43 //____________________________________________________________________________
44 AliAnaPi0::AliAnaPi0() : AliAnalysisTaskSE(),
45 fNCentrBin(1),fNZvertBin(1),fNrpBin(1),fNPID(2),fNmaxMixEv(10),
46 fCurCentrBin(0),fCurZvertBin(0),fCurRPBin(0),fPtMin(0.),fZvtxCut(40.),
47 fEventsList(0x0),fCurrentEvent(0x0),fOutputList(0x0),fhEtalon(0x0),
48 fhRe1(0x0),fhMi1(0x0),fhRe2(0x0),fhMi2(0x0),fhRe3(0x0),fhMi3(0x0),fhEvents(0x0)
53 //____________________________________________________________________________
54 AliAnaPi0::AliAnaPi0(const char *name): AliAnalysisTaskSE(name),
55 fNCentrBin(1),fNZvertBin(1),fNrpBin(1),fNPID(9),fNmaxMixEv(10),
56 fCurCentrBin(0),fCurZvertBin(0),fCurRPBin(0),fPtMin(0.),fZvtxCut(40.),
57 fEventsList(0x0),fCurrentEvent(0x0),fOutputList(0x0),fhEtalon(0x0),
58 fhRe1(0x0),fhMi1(0x0),fhRe2(0x0),fhMi2(0x0),fhRe3(0x0),fhMi3(0x0),fhEvents(0x0)
61 DefineOutput(1,TList::Class());
64 //____________________________________________________________________________
65 AliAnaPi0::AliAnaPi0(const AliAnaPi0 & ex) : AliAnalysisTaskSE(ex)
70 //_________________________________________________________________________
71 AliAnaPi0 & AliAnaPi0::operator = (const AliAnaPi0 & ex)
73 // assignment operator
75 if(this == &ex)return *this;
76 ((AliAnalysisTaskSE *)this)->operator=(ex);
81 //____________________________________________________________________________
82 AliAnaPi0::~AliAnaPi0() {
83 // Remove event containers
85 for(Int_t ic=0; ic<fNCentrBin; ic++){
86 for(Int_t iz=0; iz<fNZvertBin; iz++){
87 for(Int_t irp=0; irp<fNrpBin; irp++){
88 fEventsList[ic*fNZvertBin*fNrpBin+iz*fNrpBin+irp]->Delete() ;
89 delete fEventsList[ic*fNZvertBin*fNrpBin+iz*fNrpBin+irp] ;
100 if(fhRe1) delete[] fhRe1 ; //Do not delete histograms!
101 if(fhRe2) delete[] fhRe2 ; //Do not delete histograms!
102 if(fhRe3) delete[] fhRe3 ; //Do not delete histograms!
103 if(fhMi1) delete[] fhMi1 ; //Do not delete histograms!
104 if(fhMi2) delete[] fhMi2 ; //Do not delete histograms!
105 if(fhMi3) delete[] fhMi3 ; //Do not delete histograms!
108 //________________________________________________________________________
109 void AliAnaPi0::UserCreateOutputObjects()
111 // Create histograms to be saved in output file and
112 // store them in fOutputContainer
114 AliDebug(1,"Init inv. mass histograms");
117 fOutputList = new TList() ;
118 fOutputList->SetName(GetName()) ;
120 fhRe1=new TH3D*[fNCentrBin*fNPID] ;
121 fhRe2=new TH3D*[fNCentrBin*fNPID] ;
122 fhRe3=new TH3D*[fNCentrBin*fNPID] ;
123 fhMi1=new TH3D*[fNCentrBin*fNPID] ;
124 fhMi2=new TH3D*[fNCentrBin*fNPID] ;
125 fhMi3=new TH3D*[fNCentrBin*fNPID] ;
129 for(Int_t ic=0; ic<fNCentrBin; ic++){
130 for(Int_t ipid=0; ipid<fNPID; ipid++){
131 //Distance to bad module 1
132 sprintf(key,"hRe_cen%d_pid%d_dist1",ic,ipid) ;
133 sprintf(title,"Real m_{#gamma#gamma} distr. for centrality=%d and PID=%d",ic,ipid) ;
134 fhRe1[ic*fNPID+ipid]=(TH3D*)fhEtalon->Clone(key) ;
135 fhRe1[ic*fNPID+ipid]->SetName(key) ;
136 fhRe1[ic*fNPID+ipid]->SetTitle(title) ;
137 fOutputList->Add(fhRe1[ic*fNPID+ipid]) ;
139 sprintf(key,"hMi_cen%d_pid%d_dist1",ic,ipid) ;
140 sprintf(title,"Mixed m_{#gamma#gamma} distr. for centrality=%d and PID=%d",ic,ipid) ;
141 fhMi1[ic*fNPID+ipid]=(TH3D*)fhEtalon->Clone(key) ;
142 fhMi1[ic*fNPID+ipid]->SetName(key) ;
143 fhMi1[ic*fNPID+ipid]->SetTitle(title) ;
144 fOutputList->Add(fhMi1[ic*fNPID+ipid]) ;
146 //Distance to bad module 2
147 sprintf(key,"hRe_cen%d_pid%d_dist2",ic,ipid) ;
148 sprintf(title,"Real m_{#gamma#gamma} distr. for centrality=%d and PID=%d",ic,ipid) ;
149 fhRe2[ic*fNPID+ipid]=(TH3D*)fhEtalon->Clone(key) ;
150 fhRe2[ic*fNPID+ipid]->SetName(key) ;
151 fhRe2[ic*fNPID+ipid]->SetTitle(title) ;
152 fOutputList->Add(fhRe2[ic*fNPID+ipid]) ;
154 sprintf(key,"hMi_cen%d_pid%d_dist2",ic,ipid) ;
155 sprintf(title,"Mixed m_{#gamma#gamma} distr. for centrality=%d and PID=%d",ic,ipid) ;
156 fhMi2[ic*fNPID+ipid]=(TH3D*)fhEtalon->Clone(key) ;
157 fhMi2[ic*fNPID+ipid]->SetName(key) ;
158 fhMi2[ic*fNPID+ipid]->SetTitle(title) ;
159 fOutputList->Add(fhMi2[ic*fNPID+ipid]) ;
161 //Distance to bad module 3
162 sprintf(key,"hRe_cen%d_pid%d_dist3",ic,ipid) ;
163 sprintf(title,"Real m_{#gamma#gamma} distr. for centrality=%d and PID=%d",ic,ipid) ;
164 fhRe3[ic*fNPID+ipid]=(TH3D*)fhEtalon->Clone(key) ;
165 fhRe3[ic*fNPID+ipid]->SetName(key) ;
166 fhRe3[ic*fNPID+ipid]->SetTitle(title) ;
167 fOutputList->Add(fhRe3[ic*fNPID+ipid]) ;
169 sprintf(key,"hMi_cen%d_pid%d_dist3",ic,ipid) ;
170 sprintf(title,"Mixed m_{#gamma#gamma} distr. for centrality=%d and PID=%d",ic,ipid) ;
171 fhMi3[ic*fNPID+ipid]=(TH3D*)fhEtalon->Clone(key) ;
172 fhMi3[ic*fNPID+ipid]->SetName(key) ;
173 fhMi3[ic*fNPID+ipid]->SetTitle(title) ;
174 fOutputList->Add(fhMi3[ic*fNPID+ipid]) ;
178 fhEvents=new TH3D("hEvents","Number of events",fNCentrBin,0.,1.*fNCentrBin,
179 fNZvertBin,0.,1.*fNZvertBin,fNrpBin,0.,1.*fNrpBin) ;
180 fOutputList->Add(fhEvents) ;
182 //Save parameters used for analysis
183 fOutputList->Add(this);
186 //__________________________________________________
187 void AliAnaPi0::InitParameters()
189 //Initialize the parameters of the analysis.
192 //__________________________________________________
193 void AliAnaPi0::Init()
195 //Make here all memory allocations
196 //create etalon histo for all later histograms
197 if(!fhEtalon){ // p_T alpha d m_gg
198 fhEtalon = new TH3D("hEtalon","Histo with binning parameters",20,0.,10.,10,0.,1.,200,0.,1.) ;
199 fhEtalon->SetXTitle("P_{T} (GeV)") ;
200 fhEtalon->SetYTitle("#alpha") ;
201 fhEtalon->SetZTitle("m_{#gamma#gamma} (GeV)") ;
204 //create event containers
205 fEventsList = new TList*[fNCentrBin*fNZvertBin*fNrpBin] ;
206 for(Int_t ic=0; ic<fNCentrBin; ic++){
207 for(Int_t iz=0; iz<fNZvertBin; iz++){
208 for(Int_t irp=0; irp<fNrpBin; irp++){
209 fEventsList[ic*fNZvertBin*fNrpBin+iz*fNrpBin+irp] = new TList() ;
214 //__________________________________________________________________
215 void AliAnaPi0::Print(const Option_t * /*opt*/) const
217 //Print some relevant parameters set for the analysis
218 printf("Class AliAnaPi0 for gamma-gamma inv.mass construction \n") ;
219 printf("Number of bins in Centrality: %d \n",fNCentrBin) ;
220 printf("Number of bins in Z vert. pos: %d \n",fNZvertBin) ;
221 printf("Number of bins in Reac. Plain: %d \n",fNrpBin) ;
222 printf("Depth of event buffer: %d \n",fNmaxMixEv) ;
223 printf("Number of different PID used: %d \n",fNPID) ;
225 printf("Z vertex position: -%f < z < %f \n",fZvtxCut,fZvtxCut) ;
226 printf("Minimal P_t: %f \n", fPtMin) ;
227 printf("------------------------------------------------------\n") ;
230 //__________________________________________________________________
231 void AliAnaPi0::UserExec(Option_t *)
233 //Process one event and extract photons
234 //impose cuts on bad modules and bad runs
235 //fill internal storage for subsequent histo filling
237 AliVEvent* event = InputEvent();
239 //Apply some cuts on event: vertex position and centrality range
240 Int_t iRun=event->GetRunNumber() ;
244 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(event) ;
245 AliAODEvent* aod = dynamic_cast<AliAODEvent*>(event) ;
247 if(!FillFromESD(esd))
248 return ; //Event can not be used (vertex, centrality,... cuts not fulfilled)
251 if(!FillFromAOD(aod))
252 return ; //Event can not be used (vertex, centrality,... cuts not fulfilled)
255 printf("Input neither ESD nor AOD, do nothing \n") ;
260 fhEvents->Fill(fCurCentrBin+0.5,fCurZvertBin+0.5,fCurRPBin+0.5) ;
262 if(fCurrentEvent->GetEntriesFast()>0){
263 //Reduce size for storing
264 fCurrentEvent->Expand(fCurrentEvent->GetEntriesFast()) ;
268 PostData(1, fOutputList);
271 //__________________________________________________________________
272 Bool_t AliAnaPi0::FillFromESD(AliESDEvent * esd){
273 //Fill photon list from ESD applying
274 //some cut should be applyed:
275 const Float_t kMinDist=2. ; //Minimal distance to bad channel to accept cluster
276 const Float_t kMinDist2=4.; //Cuts on Minimal distance
277 const Float_t kMinDist3=5.; //used for acceptance-efficiency study
278 const Float_t kDispCut=1.5; //Cut on dispersion, used in PID evaluation
279 const Float_t kTOFCut=5.e-9;//Cut on TOF, used in PID evaluation
280 const Float_t kPhotPID=0.6; //Baesian PID for photon
282 //Impose cut on vertex and calculate Zvertex bin
283 const AliESDVertex *esdV = esd->GetVertex() ;
285 if(fVert[2]<-fZvtxCut || fVert[2]> fZvtxCut)
287 fCurZvertBin=(Int_t)(0.5*fNZvertBin*(fVert[2]+fZvtxCut)/fZvtxCut) ;
289 //Get Centrality and calculate centrality bin
290 //Does not exist in ESD yet???????
293 //Get Reaction Plain position and calculate RP bin
294 //does not exist in ESD yet????
297 //************************ PHOS *************************************
298 TRefArray * caloClustersArr = new TRefArray();
299 esd->GetPHOSClusters(caloClustersArr);
301 const Int_t kNumberOfPhosClusters = caloClustersArr->GetEntries() ;
302 //if fCurrentEvent!=0 it was not filled in previous event, still empty and can be used
304 fCurrentEvent = new TClonesArray("AliCaloPhoton",kNumberOfPhosClusters) ;
307 // loop over the PHOS Cluster
308 for(Int_t i = 0 ; i < kNumberOfPhosClusters ; i++) {
309 AliESDCaloCluster * calo = (AliESDCaloCluster *) caloClustersArr->At(i) ;
315 Double_t distBad=calo->GetDistanceToBadChannel() ; //Distance to bad in cm
316 if(distBad<0.)distBad=9999. ; //workout strange convension dist = -1. ;
317 if(distBad<kMinDist) //In bad channel (cristall size 2.2x2.2 cm)
320 new((*fCurrentEvent)[inList])AliCaloPhoton() ;
321 AliCaloPhoton * ph = static_cast<AliCaloPhoton*>(fCurrentEvent->At(inList)) ;
325 calo->GetMomentum(*ph,fVert);
328 Double_t disp=calo->GetClusterDisp() ;
329 // Double_t m20=calo->GetM20() ;
330 // Double_t m02=calo->GetM02() ;
331 ph->SetDispBit(disp<kDispCut) ;
334 Double_t tof=calo->GetTOF() ;
335 ph->SetTOFBit(TMath::Abs(tof)<kTOFCut) ;
338 // Double_t cpvR=calo->GetEmcCpvDistance() ;
339 Int_t itr=calo->GetNTracksMatched(); //number of track matched
340 ph->SetCPVBit(itr>0) ; //Temporary cut, should we evaluate distance?
343 Double_t *pid=calo->GetPid();
344 ph->SetPCAPID(pid[AliPID::kPhoton]>kPhotPID) ;
346 //Set Distance to Bad channel
347 if(distBad>kMinDist3)
348 ph->SetDistToBad(2) ;
349 else if(distBad>kMinDist2)
350 ph->SetDistToBad(1) ;
352 ph->SetDistToBad(0) ;
357 //__________________________________________________________________
358 Bool_t AliAnaPi0::FillFromAOD(AliAODEvent * aod){
359 //Fill photon list from AOD applying
361 const Float_t kMinDist=2. ; //Minimal distance to bad channel to accept cluster
362 const Float_t kMinDist2=4.; //Cuts on Minimal distance
363 const Float_t kMinDist3=5.; //used for acceptance-efficiency study
364 const Float_t kDispCut=1.5; //Cut on dispersion, used in PID evaluation
365 const Float_t kTOFCut=5.e-9;//Cut on TOF, used in PID evaluation
366 const Float_t kPhotPID=0.6 ; //Baesian PID for photon
368 //Impose cut on vertex and calculate Zvertex bin
369 const AliAODVertex *aodV = aod->GetPrimaryVertex() ;
370 fVert[0]=aodV->GetX();
371 fVert[1]=aodV->GetY();
372 fVert[2]=aodV->GetZ();
373 if(fVert[2]<-fZvtxCut || fVert[2]> fZvtxCut)
375 fCurZvertBin=(Int_t)(0.5*fNZvertBin*(fVert[2]+fZvtxCut)/fZvtxCut) ;
377 //Get Centrality and calculate centrality bin
378 //Does not exist in ESD yet???????
381 //Get Reaction Plain position and calculate RP bin
382 //does not exist in ESD yet????
385 //************************ PHOS *************************************
386 const Int_t kNumberOfPhosClusters = aod->GetNCaloClusters() ;
388 fCurrentEvent = new TClonesArray("AliCaloPhoton",kNumberOfPhosClusters) ;
391 // loop over the PHOS Cluster
392 for(Int_t i = 0 ; i < kNumberOfPhosClusters ; i++) {
393 AliAODCaloCluster * calo = aod->GetCaloCluster(i);
399 Double_t distBad=calo->GetDistToBadChannel() ;
400 if(distBad<kMinDist) //In bad channel
403 new((*fCurrentEvent)[inList])AliCaloPhoton() ;
404 AliCaloPhoton * ph = static_cast<AliCaloPhoton*>(fCurrentEvent->At(inList)) ;
408 calo->GetMomentum(*ph,fVert);
411 Double_t disp=calo->GetDispersion() ;
412 // Double_t m20=calo->GetM20() ;
413 // Double_t m02=calo->GetM02() ;
414 ph->SetDispBit(disp<kDispCut) ;
417 Double_t tof=calo->GetTOF() ;
418 ph->SetTOFBit(TMath::Abs(tof)<kTOFCut) ;
421 // Double_t cpvR=calo->GetEmcCpvDistance() ;
422 Int_t itr=calo->GetNTracksMatched(); //number of track matched
423 ph->SetCPVBit(itr>0) ; //Temporary cut !!!!
428 ph->SetPCAPID(pid[AliAODCluster::kPhoton]>kPhotPID) ;
431 if(distBad>kMinDist3)
432 ph->SetDistToBad(2) ;
433 else if(distBad>kMinDist2)
434 ph->SetDistToBad(1) ;
436 ph->SetDistToBad(0) ;
442 //__________________________________________________________________
443 void AliAnaPi0::FillHistograms()
445 //Fill Real and Mixed invariant mass histograms
446 //then add current event to the buffer and
447 //remove redundant events from buffer if necessary
449 //Fill histograms only if list of particles for current event was created
453 //Fill Real distribution
454 Int_t nPhot = fCurrentEvent->GetEntriesFast() ;
455 for(Int_t i1=0; i1<nPhot-1; i1++){
456 AliCaloPhoton * p1 = static_cast<AliCaloPhoton*>(fCurrentEvent->At(i1)) ;
457 for(Int_t i2=i1+1; i2<nPhot; i2++){
458 AliCaloPhoton * p2 = static_cast<AliCaloPhoton*>(fCurrentEvent->At(i2)) ;
459 Double_t m =(*p1 + *p2).M() ;
460 Double_t pt=(*p1 + *p2).Pt();
461 Double_t a = TMath::Abs(p1->Energy()-p2->Energy())/(p1->Energy()+p2->Energy()) ;
462 for(Int_t ipid=0; ipid<fNPID; ipid++){
463 if(p1->IsPIDOK(ipid)&&p2->IsPIDOK(ipid)){
464 fhRe1[fCurCentrBin*fNPID+ipid]->Fill(pt,a,m) ;
465 if(p1->DistToBad()>0 && p2->DistToBad()>0){
466 fhRe2[fCurCentrBin*fNPID+ipid]->Fill(pt,a,m) ;
467 if(p1->DistToBad()>1 && p2->DistToBad()>1){
468 fhRe3[fCurCentrBin*fNPID+ipid]->Fill(pt,a,m) ;
477 TList * evMixList=fEventsList[fCurCentrBin*fNZvertBin*fNrpBin+fCurZvertBin*fNrpBin+fCurRPBin] ;
478 Int_t nMixed = evMixList->GetSize() ;
479 for(Int_t ii=0; ii<nMixed; ii++){
480 TClonesArray* ev2=dynamic_cast<TClonesArray*>(evMixList->At(ii));
481 Int_t nPhot2=ev2->GetEntriesFast() ;
482 for(Int_t i1=0; i1<nPhot; i1++){
483 AliCaloPhoton * p1 = static_cast<AliCaloPhoton*>(fCurrentEvent->At(i1)) ;
484 for(Int_t i2=0; i2<nPhot2; i2++){
485 AliCaloPhoton * p2 = static_cast<AliCaloPhoton*>(ev2->At(i2)) ;
486 Double_t m =(*p1 + *p2).M() ;
487 Double_t pt=(*p1 + *p2).Pt();
488 Double_t a = TMath::Abs(p1->Energy()-p2->Energy())/(p1->Energy()+p2->Energy()) ;
489 for(Int_t ipid=0; ipid<fNPID; ipid++){
490 if(p1->IsPIDOK(ipid)&&p2->IsPIDOK(ipid)){
491 fhMi1[fCurCentrBin*fNPID+ipid]->Fill(pt,a,m) ;
492 if(p1->DistToBad()>0 && p2->DistToBad()>0){
493 fhMi2[fCurCentrBin*fNPID+ipid]->Fill(pt,a,m) ;
494 if(p1->DistToBad()>1 && p2->DistToBad()>1){
495 fhMi3[fCurCentrBin*fNPID+ipid]->Fill(pt,a,m) ;
504 //Add current event to buffer and Remove redandant events
505 if(fCurrentEvent->GetEntriesFast()>0){
506 evMixList->AddFirst(fCurrentEvent) ;
507 fCurrentEvent=0 ; //Now list of particles belongs to buffer and it will be deleted with buffer
508 if(evMixList->GetSize()>=fNmaxMixEv){
509 TClonesArray * tmp = dynamic_cast<TClonesArray*>(evMixList->Last()) ;
510 evMixList->RemoveLast() ;
515 delete fCurrentEvent ;
519 //______________________________________________________________________________
520 void AliAnaPi0::Terminate(Option_t *)