]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG4/AliGammaMCDataReader.cxx
Protection against cluster labels larger than kinematics entries
[u/mrichter/AliRoot.git] / PWG4 / AliGammaMCDataReader.cxx
CommitLineData
bdcfac30 1
2/**************************************************************************
3 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * *
5 * Author: The ALICE Off-line Project. *
6 * Contributors are mentioned in the code where appropriate. *
7 * *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16/* $Id$ */
17
18/* History of cvs commits:
19 *
20 * $Log$
b398a6cb 21 * Revision 1.4 2007/10/29 13:48:42 gustavo
22 * Corrected coding violations
23 *
4b707925 24 * Revision 1.2 2007/08/17 12:40:04 schutz
25 * New analysis classes by Gustavo Conesa
26 *
bdcfac30 27 * Revision 1.1.2.1 2007/07/26 10:32:09 schutz
28 * new analysis classes in the the new analysis framework
29 *
30 *
31 */
32
33//_________________________________________________________________________
34// Class for reading data (Kinematics and ESDs) in order to do prompt gamma correlations
35// Class created from old AliPHOSGammaJet
36// (see AliRoot versions previous Release 4-09)
37//
38//*-- Author: Gustavo Conesa (LNF-INFN)
39//////////////////////////////////////////////////////////////////////////////
40
41
42// --- ROOT system ---
3bb2c538 43#include <TFormula.h>
bdcfac30 44#include <TParticle.h>
3bb2c538 45
bdcfac30 46//---- ANALYSIS system ----
47#include "AliGammaMCDataReader.h"
bdcfac30 48#include "AliESDEvent.h"
49#include "AliESDVertex.h"
50#include "AliESDCaloCluster.h"
51#include "AliStack.h"
3bb2c538 52#include "AliLog.h"
bdcfac30 53
54ClassImp(AliGammaMCDataReader)
55
56//____________________________________________________________________________
57 AliGammaMCDataReader::AliGammaMCDataReader() :
4b707925 58 AliGammaReader()
bdcfac30 59{
60 //Default Ctor
61
62 //Initialize parameters
63 fDataType=kMCData;
bdcfac30 64
65}
66
67//____________________________________________________________________________
68AliGammaMCDataReader::AliGammaMCDataReader(const AliGammaMCDataReader & g) :
4b707925 69 AliGammaReader(g)
bdcfac30 70{
71 // cpy ctor
72}
73
74//_________________________________________________________________________
75AliGammaMCDataReader & AliGammaMCDataReader::operator = (const AliGammaMCDataReader & source)
76{
77 // assignment operator
78
79 if(&source == this) return *this;
80
4b707925 81
bdcfac30 82 return *this;
83
84}
85
86//____________________________________________________________________________
87void AliGammaMCDataReader::CreateParticleList(TObject * data, TObject * kine,
88 TClonesArray * plCTS,
89 TClonesArray * plEMCAL,
4b707925 90 TClonesArray * plPHOS,
91 TClonesArray * plPrimCTS,
92 TClonesArray * plPrimEMCAL,
93 TClonesArray * plPrimPHOS){
bdcfac30 94
95 //Create a list of particles from the ESD. These particles have been measured
3bb2c538 96 //by the Central Tracking system (TPC+ITS+...), PHOS and EMCAL
97 //Also create particle list with mothers.
bdcfac30 98
99 AliESDEvent* esd = (AliESDEvent*) data;
100 AliStack* stack = (AliStack*) kine;
101
102 Int_t npar = 0 ;
4b707925 103 Double_t *pid = new Double_t[AliPID::kSPECIESN];
bdcfac30 104 AliDebug(3,"Fill particle lists");
105
106 //Get vertex for momentum calculation
107 Double_t v[3] ; //vertex ;
108 esd->GetVertex()->GetXYZ(v) ;
109
3bb2c538 110 //########### CALORIMETERS ##############
111 Int_t nCaloCluster = esd->GetNumberOfCaloClusters() ;
bdcfac30 112 Int_t indexPH = plPHOS->GetEntries() ;
3bb2c538 113 Int_t indexEM = plEMCAL->GetEntries() ;
bdcfac30 114
3bb2c538 115 for (npar = 0; npar < nCaloCluster; npar++) {//////////////CaloCluster loop
116 AliESDCaloCluster * clus = esd->GetCaloCluster(npar) ; // retrieve cluster from esd
117 Int_t type = clus->GetClusterType();
118
119 //########### PHOS ##############
120 if(fSwitchOnPHOS && type == AliESDCaloCluster::kPHOSCluster){
121 AliDebug(4,Form("PHOS clusters: E %f, match %d", clus->E(),clus->GetTrackMatched()));
122
123 if(clus->GetTrackMatched()==-1){
124 TLorentzVector momentum ;
125 clus->GetMomentum(momentum, v);
126 Double_t phi = momentum.Phi();
127 if(phi<0) phi+=TMath::TwoPi() ;
128 if(momentum.Pt() > fNeutralPtCut && TMath::Abs(momentum.Eta()) < fPHOSEtaCut &&
129 phi > fPhiPHOSCut[0] && phi < fPhiPHOSCut[1] ) {
4b707925 130
3bb2c538 131 pid=clus->GetPid();
132 Int_t pdg = 22;
4b707925 133
3bb2c538 134 if(IsPHOSPIDOn()){
135 AliDebug(5,Form("E %1.2f; PID: ph %0.2f, pi0 %0.2f, el %0.2f, conv el %0.2f,pi %0.2f, k %0.2f, p %0.2f, k0 %0.2f, n %0.2f, mu %0.2f ",
136 momentum.E(),pid[AliPID::kPhoton],pid[AliPID::kPi0],pid[AliPID::kElectron],pid[AliPID::kEleCon],pid[AliPID::kPion],
137 pid[AliPID::kKaon],pid[AliPID::kProton], pid[AliPID::kKaon0],pid[AliPID::kNeutron], pid[AliPID::kMuon]));
138
139 Float_t wPhoton = fPHOSPhotonWeight;
140 Float_t wPi0 = fPHOSPi0Weight;
141
142 if(fPHOSWeightFormula){
143 wPhoton = fPHOSPhotonWeightFormula->Eval(momentum.E()) ;
144 wPi0 = fPHOSPi0WeightFormula->Eval(momentum.E());
145 }
146
147 if(pid[AliPID::kPhoton] > wPhoton)
148 pdg = kPhoton ;
149 else if(pid[AliPID::kPi0] > wPi0)
150 pdg = kPi0 ;
151 else if(pid[AliPID::kElectron] > fPHOSElectronWeight)
152 pdg = kElectron ;
153 else if(pid[AliPID::kEleCon] > fPHOSElectronWeight)
154 pdg = kEleCon ;
155 else if(pid[AliPID::kPion]+pid[AliPID::kKaon]+pid[AliPID::kProton] > fPHOSChargeWeight)
156 pdg = kChargedHadron ;
157 else if(pid[AliPID::kKaon0]+pid[AliPID::kNeutron] > fPHOSNeutralWeight)
158 pdg = kNeutralHadron ;
159
160 else if(pid[AliPID::kElectron]+pid[AliPID::kEleCon]+pid[AliPID::kPion]+pid[AliPID::kKaon]+pid[AliPID::kProton] >
161 pid[AliPID::kPhoton] + pid[AliPID::kPi0]+pid[AliPID::kKaon0]+pid[AliPID::kNeutron])
162 pdg = kChargedUnknown ;
163 else
164 pdg = kNeutralUnknown ;
165 //neutral cluster, unidentifed.
4b707925 166 }
167
3bb2c538 168 if(pdg != kElectron && pdg != kEleCon && pdg !=kChargedHadron && pdg !=kChargedUnknown ){//keep only neutral particles in the array
b398a6cb 169
170 TParticle * particle = new TParticle(pdg, 1, -1, -1, -1, -1, momentum.Px(), momentum.Py(), momentum.Pz(), momentum.E(), v[0], v[1], v[2], 0);
171 new((*plPHOS)[indexPH]) TParticle(*particle) ;
172 AliDebug(4,Form("PHOS added: pdg %d, pt %f, phi %f, eta %f", pdg, particle->Pt(),particle->Phi(),particle->Eta()));
173
3bb2c538 174 //###############
175 //Check kinematics
176 //###############
b398a6cb 177 TParticle * pmother = new TParticle();
3bb2c538 178 Int_t label = clus->GetLabel();
b398a6cb 179 if(label < stack->GetNprimary())
180 pmother = GetMotherParticle(label,stack, "PHOS",momentum);
181 else
182 AliInfo(Form("PHOS: Bad label %d, too large, NPrimaries %d",label,stack->GetNprimary()));
3bb2c538 183 new((*plPrimPHOS)[indexPH]) TParticle(*pmother) ;
3bb2c538 184
b398a6cb 185 indexPH++;
3bb2c538 186 }
187 else AliDebug(4,Form("PHOS charged cluster NOT added: pdg %d, pt %f, phi %f, eta %f\n",
188 pdg, momentum.Pt(),momentum.Phi(),momentum.Eta()));
4b707925 189
3bb2c538 190 }//pt, eta, phi cut
191 else AliDebug(4,"Particle not added");
192 }//track-match?
193 }//PHOS cluster
4b707925 194
3bb2c538 195 //################ EMCAL ##############
196 else if(fSwitchOnEMCAL && type == AliESDCaloCluster::kEMCALClusterv1){
197 AliDebug(4,Form("EMCAL clusters: E %f, match %d", clus->E(),clus->GetTrackMatched()));
198
199 if(clus->GetTrackMatched()==-1 ){
200 TLorentzVector momentum ;
201 clus->GetMomentum(momentum, v);
202 Double_t phi = momentum.Phi();
203 if(phi<0) phi+=TMath::TwoPi() ;
204 if(momentum.Pt() > fNeutralPtCut && TMath::Abs(momentum.Eta()) < fEMCALEtaCut &&
205 phi > fPhiEMCALCut[0] && phi < fPhiEMCALCut[1] ) {
4b707925 206
3bb2c538 207 pid=clus->GetPid();
208 Int_t pdg = 22;
4b707925 209
3bb2c538 210 if(IsEMCALPIDOn()){
211 AliDebug(5,Form("E %1.2f; PID: ph %0.2f, pi0 %0.2f, el %0.2f, conv el %0.2f,pi %0.2f, k %0.2f, p %0.2f, k0 %0.2f, n %0.2f, mu %0.2f ",
212 momentum.E(),pid[AliPID::kPhoton],pid[AliPID::kPi0],pid[AliPID::kElectron],pid[AliPID::kEleCon],pid[AliPID::kPion],
213 pid[AliPID::kKaon],pid[AliPID::kProton], pid[AliPID::kKaon0],pid[AliPID::kNeutron], pid[AliPID::kMuon]));
214
215 if(pid[AliPID::kPhoton] > fEMCALPhotonWeight)
216 pdg = kPhoton ;
217 else if(pid[AliPID::kPi0] > fEMCALPi0Weight)
218 pdg = kPi0 ;
219 else if(pid[AliPID::kElectron] > fEMCALElectronWeight)
220 pdg = kElectron ;
221 else if(pid[AliPID::kEleCon] > fEMCALElectronWeight)
222 pdg = kEleCon ;
223 else if(pid[AliPID::kPion]+pid[AliPID::kKaon]+pid[AliPID::kProton] > fEMCALChargeWeight)
224 pdg = kChargedHadron ;
225 else if(pid[AliPID::kKaon0]+pid[AliPID::kNeutron] > fEMCALNeutralWeight)
226 pdg = kNeutralHadron ;
227 else if(pid[AliPID::kElectron]+pid[AliPID::kEleCon]+pid[AliPID::kPion]+pid[AliPID::kKaon]+pid[AliPID::kProton] >
228 pid[AliPID::kPhoton] + pid[AliPID::kPi0]+pid[AliPID::kKaon0]+pid[AliPID::kNeutron])
229 pdg = kChargedUnknown ;
230 else
231 pdg = kNeutralUnknown ;
232 }
233
234 if(pdg != kElectron && pdg != kEleCon && pdg !=kChargedHadron && pdg !=kChargedUnknown){//keep only neutral particles in the array
b398a6cb 235
236 TParticle * particle = new TParticle(pdg, 1, -1, -1, -1, -1, momentum.Px(), momentum.Py(), momentum.Pz(), momentum.E(), v[0], v[1], v[2], 0);
237 new((*plEMCAL)[indexEM]) TParticle(*particle) ;
238 AliDebug(4,Form("EMCAL cluster added: pdg %f, pt %f, phi %f, eta %f", pdg, particle->Pt(),particle->Phi(),particle->Eta()));
3bb2c538 239
240 //###############
241 //Check kinematics
242 //###############
b398a6cb 243 TParticle * pmother = new TParticle();
3bb2c538 244 Int_t label = clus->GetLabel();
b398a6cb 245 if(label < stack->GetNprimary())
246 pmother = GetMotherParticle(label,stack, "EMCAL",momentum);
247 else
248 AliInfo(Form("EMCAL: Bad label %d, too large, NPrimaries %d",label,stack->GetNprimary()));
3bb2c538 249 new((*plPrimEMCAL)[indexEM]) TParticle(*pmother) ;
b398a6cb 250
3bb2c538 251 indexEM++;
252 }
253 else AliDebug(4,Form("EMCAL charged cluster NOT added: pdg %d, pt %f, phi %f, eta %f",
254 pdg, momentum.Pt(),momentum.Phi(),momentum.Eta()));
255
256 }//pt, phi, eta cut
257 else AliDebug(4,"Particle not added");
258 }//track-matched
259 }//EMCAL cluster
4b707925 260
bdcfac30 261 }//cluster loop
262
3bb2c538 263
264
bdcfac30 265 //########### CTS (TPC+ITS) #####################
3bb2c538 266 Int_t nTracks = esd->GetNumberOfTracks() ;
bdcfac30 267 Int_t indexCh = plCTS->GetEntries() ;
4b707925 268
3bb2c538 269 if(fSwitchOnCTS){
270 AliDebug(3,Form("Number of tracks %d",nTracks));
bdcfac30 271
3bb2c538 272 for (npar = 0; npar < nTracks; npar++) {////////////// track loop
273 AliESDtrack * track = esd->GetTrack(npar) ; // retrieve track from esd
bdcfac30 274
3bb2c538 275 //We want tracks fitted in the detectors:
276 ULong_t status=AliESDtrack::kTPCrefit;
277 status|=AliESDtrack::kITSrefit;
278
279 //We want tracks whose PID bit is set:
280 // ULong_t status =AliESDtrack::kITSpid;
281 // status|=AliESDtrack::kTPCpid;
bdcfac30 282
3bb2c538 283 if ( (track->GetStatus() & status) == status) {//Check if the bits we want are set
284 // Do something with the tracks which were successfully
285 // re-fitted
286 Double_t en = 0; //track ->GetTPCsignal() ;
287 Double_t mom[3];
288 track->GetPxPyPz(mom) ;
289 Double_t px = mom[0];
290 Double_t py = mom[1];
291 Double_t pz = mom[2]; //Check with TPC people if this is correct.
292 Int_t pdg = 11; //Give any charged PDG code, in this case electron.
293 //I just want to tag the particle as charged
4b707925 294
4b707925 295 //Check kinematics
3bb2c538 296 Int_t label = TMath::Abs(track->GetLabel());
297 TParticle * pmother = new TParticle();
298 pmother = stack->Particle(label);
4b707925 299
300 TParticle * particle = new TParticle(pdg, 1, -1, -1, -1, -1,
3bb2c538 301 px, py, pz, en, v[0], v[1], v[2], 0);
4b707925 302
3bb2c538 303 if(particle->Pt() > fChargedPtCut && TMath::Abs(particle->Eta())<fCTSEtaCut){
304 new((*plCTS)[indexCh]) TParticle(*particle) ;
305 new((*plPrimCTS)[indexCh]) TParticle(*pmother) ;
306 indexCh++;
307
308 }//kinematic selection
309 }//select track from refit
310 }//track loop
311 }//CTS
bdcfac30 312
3bb2c538 313 AliDebug(3,Form("Particle lists filled, tracks %d , clusters: EMCAL %d, PHOS %d", indexCh,indexEM,indexPH));
314
315}
4b707925 316
317TParticle * AliGammaMCDataReader:: GetMotherParticle(Int_t label, AliStack *stack, TString calo, TLorentzVector momentum)
bdcfac30 318{
4b707925 319 //Gets the primary particle and do some checks:
320 //Check if primary is inside calorimeter and look the mother outsie
321 //Check if mother is a decay photon, in which case check if decay was overlapped
322
323 Float_t minangle = 0;
324 Float_t ipdist = 0;
325 TParticle * pmother = new TParticle();
bdcfac30 326
4b707925 327 if(calo == "PHOS"){
328 ipdist= fPHOSIPDistance;
329 minangle = fPHOSMinAngle;
330 }
331 else if (calo == "EMCAL"){
332 ipdist = fEMCALIPDistance;
333 minangle = fEMCALMinAngle;
334 }
bdcfac30 335
bdcfac30 336
4b707925 337 if(label>=0){
338 pmother = stack->Particle(label);
339 Int_t mostatus = pmother->GetStatusCode();
340 Int_t mopdg = TMath::Abs(pmother->GetPdgCode());
341
342 //Check if mother is a conversion inside the calorimeter
343 //In such case, return the mother before the calorimeter.
344 //First approximation.
345 Float_t vy = TMath::Abs(pmother->Vy()) ;
bdcfac30 346
4b707925 347 if( mostatus == 0 && vy >= ipdist){
bdcfac30 348
4b707925 349 //cout<<"Calo: "<<calo<<" vy "<<vy<<" E clus "<<momentum.E()<<" Emother "<<pmother->Energy()<<" "
350 // <<pmother->GetName()<<endl;
351
352 while( vy >= ipdist){//inside calorimeter
353 AliDebug(4,Form("Conversion inside calorimeter, mother vertex %0.2f, IP distance %0.2f", vy, ipdist));
354 pmother = stack->Particle(pmother->GetMother(0));
355 vy = TMath::Abs(pmother->Vy()) ;
356 //cout<<" label "<<label<<" Mother: "<<pmother->GetName()<<" E "<<pmother->Energy()<<" Status "<<pmother->GetStatusCode()<<" and vertex "<<vy<<endl;
357 mostatus = pmother->GetStatusCode();
358 mopdg = TMath::Abs(pmother->GetPdgCode());
359 }//while vertex is inside calorimeter
360 //cout<<"Calo: "<<calo<<" final vy "<<vy<<" E clus "<<momentum.E()<<" Emother "<<pmother->Energy()<<" "
361 // <<pmother->GetName()<<endl;
362 }//check status and vertex
363
364 AliDebug(4,Form("%s, ESD E %2.2f, PID %d, mother: E %2.2f, label %d, status %d, vertex %3.2f, mother 2 %d, grandmother %d \n",
365 calo.Data(),momentum.E(),pmother->Energy(), label, pmother->GetPdgCode(),
366 pmother->GetStatusCode(), vy, pmother->GetMother(0), stack->GetPrimary(label)));
367
368 //Check Decay photons
369 if(mopdg == 22){
370
371 //his mother was a pi0?
372 TParticle * pmotherpi0 = stack->Particle(pmother->GetMother(0));
373 if( pmotherpi0->GetPdgCode() == 111){
374
375 AliDebug(4,Form(" %s: E cluster %2.2f, E gamma %2.2f, Mother Pi0, E %0.2f, status %d, daughters %d\n",
376 calo.Data(), momentum.E(),pmother->Energy(),pmotherpi0->Energy(),
377 pmotherpi0->GetStatusCode(), pmotherpi0->GetNDaughters()));
378
379 if(pmotherpi0->GetNDaughters() == 1) mostatus = 2 ; //signal that this photon can only be decay, not overlapped.
380 else if(pmotherpi0->GetNDaughters() == 2){
381
382 TParticle * pd1 = stack->Particle(pmotherpi0->GetDaughter(0));
383 TParticle * pd2 = stack->Particle(pmotherpi0->GetDaughter(1));
384 //if(pmotherpi0->Energy()> 10 ){
385// cout<<"Two "<<calo<<" daugthers, pi0 label "<<pmother->GetMother(0)<<" E :"<<pmotherpi0->Energy()<<endl;
386// cout<<" 1) label "<<pmotherpi0->GetDaughter(0)<<" pdg "<<pd1->GetPdgCode()<<" E "<<pd1->Energy()
387// <<" phi "<<pd1->Phi()*TMath::RadToDeg()<<" eta "<<pd1->Eta()
388// <<" mother label "<<pd1->GetMother(0)<<" n daug "<<pd1->GetNDaughters() <<endl;
389// cout<<" 2) label "<<pmotherpi0->GetDaughter(1)<<" pdg "<<pd2->GetPdgCode()<<" E "<<pd2->Energy()
390// <<" phi "<<pd2->Phi()*TMath::RadToDeg()<<" eta "<<pd2->Eta()<<" mother label "
391// <<pd2->GetMother(0)<<" n daug "<<pd2->GetNDaughters() <<endl;
392 //}
393 if(pd1->GetPdgCode() == 22 && pd2->GetPdgCode() == 22){
394 TLorentzVector lv1 , lv2 ;
395 pd1->Momentum(lv1);
396 pd2->Momentum(lv2);
397 Double_t angle = lv1.Angle(lv2.Vect());
398// if(pmotherpi0->Energy()> 10 )
399// cout<<"angle*ipdist "<<angle*ipdist<<" mindist "<< minangle <<endl;
400 if (angle < minangle){
401 //There is overlapping, pass the pi0 as mother
402
403 AliDebug(4,Form(">>>> %s cluster with E %2.2f is a overlapped pi0, E %2.2f, angle %2.4f < anglemin %2.4f\n",
404 calo.Data(), momentum.E(), pmotherpi0->Energy(), angle, minangle));
405
406 pmother = pmotherpi0 ;
407
408 }
409 else mostatus = 2 ; // gamma decay not overlapped
410 }// daughters are photons
411 else mostatus = 2; // daughters are e-gamma or e-e, no overlapped, or charged cluster
412 }//2 daughters
413 else AliDebug(4,Form("pi0 has %d daughters",pmotherpi0->GetNDaughters()));
414 }//pi0 decay photon?
415 }//photon
416
417 pmother->SetStatusCode(mostatus); // if status = 2, decay photon.
418
419 }//label >=0
420 else AliInfo(Form("Negative Kinematic label of PHOS cluster: %d",label));
421
422 return pmother ;
bdcfac30 423
424}