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 for reading data (Kinematics) in order to do prompt gamma
19 // or other particle identification and correlations
21 //*-- Author: Gustavo Conesa (LNF-INFN)
22 //////////////////////////////////////////////////////////////////////////////
25 // --- ROOT system ---
27 #include <TParticle.h>
31 #include <TClonesArray.h>
33 //---- ANALYSIS system ----
34 #include "AliCaloTrackMCReader.h"
35 #include "Riostream.h"
37 #include "AliGenEventHeader.h"
39 #include "AliAODCaloCluster.h"
40 #include "AliAODTrack.h"
42 ClassImp(AliCaloTrackMCReader)
44 //____________________________________________________________________________
45 AliCaloTrackMCReader::AliCaloTrackMCReader() :
46 AliCaloTrackReader(), fDecayPi0(0),
47 fNeutralParticlesArray(0x0), fChargedParticlesArray(0x0),
48 fStatusArray(0x0), fKeepAllStatus(0), fClonesArrayType(0)
52 //Initialize parameters
58 //____________________________________________________________________________
59 AliCaloTrackMCReader::AliCaloTrackMCReader(const AliCaloTrackMCReader & g) :
60 AliCaloTrackReader(g), fDecayPi0(g.fDecayPi0),
61 fNeutralParticlesArray(g.fNeutralParticlesArray?new TArrayI(*g.fNeutralParticlesArray):0x0),
62 fChargedParticlesArray(g.fChargedParticlesArray?new TArrayI(*g.fChargedParticlesArray):0x0),
63 fStatusArray(g.fStatusArray?new TArrayI(*g.fStatusArray):0x0),
64 fKeepAllStatus(g.fKeepAllStatus), fClonesArrayType(g.fClonesArrayType)
69 //_________________________________________________________________________
70 AliCaloTrackMCReader & AliCaloTrackMCReader::operator = (const AliCaloTrackMCReader & source)
72 // assignment operator
74 if(&source == this) return *this;
76 fDecayPi0 = source.fDecayPi0;
78 delete fChargedParticlesArray;
79 fChargedParticlesArray = source.fChargedParticlesArray?new TArrayI(*source.fChargedParticlesArray):0x0;
81 delete fNeutralParticlesArray;
82 fNeutralParticlesArray = source.fNeutralParticlesArray?new TArrayI(*source.fNeutralParticlesArray):0x0;
85 fStatusArray = source.fStatusArray?new TArrayI(*source.fStatusArray):0x0;
87 fKeepAllStatus = source.fKeepAllStatus ;
88 fClonesArrayType = source.fClonesArrayType ;
94 //_________________________________
95 AliCaloTrackMCReader::~AliCaloTrackMCReader() {
98 if(fChargedParticlesArray) delete fChargedParticlesArray ;
99 if(fNeutralParticlesArray) delete fNeutralParticlesArray ;
100 if(fStatusArray) delete fStatusArray ;
104 //____________________________________________________________________________
105 void AliCaloTrackMCReader::GetVertex(Double_t v[3]) {
106 //Return vertex position
109 GetGenEventHeader()->PrimaryVertex(pv);
117 //_______________________________________________________________
118 void AliCaloTrackMCReader::InitParameters()
121 //Initialize the parameters of the analysis.
125 fChargedParticlesArray = new TArrayI(1);
126 fChargedParticlesArray->SetAt(11,0);
127 //Int_t pdgarray[]={12,14,16};// skip neutrinos
128 //fNeutralParticlesArray = new TArrayI(3, pdgarray);
129 fNeutralParticlesArray = new TArrayI(3);
130 fNeutralParticlesArray->SetAt(12,0); fNeutralParticlesArray->SetAt(14,1); fNeutralParticlesArray->SetAt(16,2);
131 fStatusArray = new TArrayI(1);
132 fStatusArray->SetAt(1,0);
134 fKeepAllStatus = kTRUE;
135 fClonesArrayType = kAliAOD ;
139 //____________________________________________________________________________
140 void AliCaloTrackMCReader::FillCalorimeters(const Int_t iParticle, TParticle* particle, TLorentzVector momentum,
141 Int_t &indexPHOS, Int_t &indexEMCAL){
142 //Fill AODCaloClusters or TParticles lists of PHOS or EMCAL
145 if(fFillPHOS && fFidutialCut->IsInFidutialCut(momentum,"PHOS") && momentum.Pt() > fPHOSPtMin){
147 if(fClonesArrayType == kTParticle) new((*fAODPHOS)[indexPHOS++]) TParticle(*particle) ;
150 Char_t ttype= AliAODCluster::kPHOSNeutral;
151 Int_t labels[] = {iParticle};
152 Float_t x[] = {momentum.X(), momentum.Y(), momentum.Z()};
153 AliAODCaloCluster *calo = new((*fAODPHOS)[indexPHOS++])
154 AliAODCaloCluster(iParticle,1,labels,momentum.E(), x, NULL, ttype, 0);
155 SetCaloClusterPID(particle->GetPdgCode(),calo) ;
159 else if(fFillEMCAL && fFidutialCut->IsInFidutialCut(momentum,"EMCAL") && momentum.Pt() > fEMCALPtMin){
160 //cout<<"Reader : E "<<momentum.E()<<" ; Phi"<<momentum.Phi()<< " ; Eta "<<momentum.Eta()<<endl;
161 if(fClonesArrayType == kTParticle) new((*fAODEMCAL)[indexEMCAL++]) TParticle(*particle) ;
163 Char_t ttype= AliAODCluster::kEMCALClusterv1;
164 Int_t labels[] = {iParticle};
165 Float_t x[] = {momentum.X(), momentum.Y(), momentum.Z()};
166 AliAODCaloCluster *calo = new((*fAODEMCAL)[indexEMCAL++])
167 AliAODCaloCluster(iParticle,1,labels,momentum.E(), x, NULL, ttype, 0);
168 SetCaloClusterPID(particle->GetPdgCode(),calo) ;
173 //____________________________________________________________________________
174 void AliCaloTrackMCReader::FillInputEvent()
176 //Create list of particles from EMCAL, PHOS and CTS.
178 if(fClonesArrayType == kTParticle){
179 fAODCTS = new TClonesArray("TParticle",0);
180 fAODEMCAL = new TClonesArray("TParticle",0);
181 fAODPHOS = new TClonesArray("TParticle",0);
183 else if(fClonesArrayType == kAliAOD){
184 fAODCTS = new TClonesArray("AliAODTrack",0);
185 fAODPHOS = new TClonesArray("AliAODCaloCluster",0);
186 fAODEMCAL = new TClonesArray("AliAODCaloCluster",0);
188 else {AliFatal("Wrong clones type");}
192 Int_t indexEMCAL = 0 ;
193 Int_t indexPHOS = 0 ;
195 Int_t iParticle = 0 ;
196 Double_t charge = 0.;
198 for (iParticle=0 ; iParticle < GetStack()->GetNprimary() ; iParticle++) {
199 TParticle * particle = GetStack()->Particle(iParticle);
200 TLorentzVector momentum;
203 Int_t pdg = particle->GetPdgCode();
205 //Keep particles with a given status
206 if(KeepParticleWithStatus(particle->GetStatusCode()) && (particle->Pt() > 0) ){
208 charge = TDatabasePDG::Instance()->GetParticle(pdg)->Charge();
209 particle->Momentum(momentum);
210 //---------- Charged particles ----------------------
211 if((charge != 0) && (momentum.Pt() > fCTSPtMin) && (fFidutialCut->IsInFidutialCut(momentum,"CTS"))){
213 //Particles in CTS acceptance
214 if(fDebug > 3 && momentum.Pt() > 0.2)printf("Fill MC CTS :: Selected tracks E %3.2f, pt %3.2f, phi %3.2f, eta %3.2f\n",
215 momentum.E(),momentum.Pt(),momentum.Phi()*TMath::RadToDeg(),momentum.Eta());
217 if(fClonesArrayType == kTParticle) new((*fAODCTS)[indexCh++]) TParticle(*particle) ;
219 x[0] = particle->Vx(); x[1] = particle->Vy(); x[2] = particle->Vz();
220 p[0] = particle->Px(); p[1] = particle->Py(); p[2] = particle->Pz();
221 AliAODTrack *aodTrack = new((*fAODCTS)[indexCh++])
222 AliAODTrack(0, iParticle, p, kTRUE, x, kFALSE,NULL, 0, 0,
225 kFALSE, // No fit performed
226 kFALSE, // No fit performed
227 AliAODTrack::kPrimary,
229 SetTrackChargeAndPID(pdg, aodTrack);
232 //Keep some charged particles in calorimeters lists
233 if((fFillPHOS || fFillEMCAL) && KeepChargedParticles(pdg)) FillCalorimeters(iParticle, particle, momentum, indexPHOS, indexEMCAL);
237 //-------------Neutral particles ----------------------
238 else if(charge == 0 && (fFillPHOS || fFillEMCAL)){
239 //Skip neutrinos or other neutral particles
240 if(SkipNeutralParticles(pdg) || particle->IsPrimary()) continue ; // protection added (MG)
242 //Fill particle/calocluster arrays
243 if(!fDecayPi0) FillCalorimeters(iParticle, particle, momentum, indexPHOS, indexEMCAL);
245 //Sometimes pi0 are stable for the generator, if needed decay it by hand
247 if(momentum.Pt() > fPHOSPtMin || momentum.Pt() > fEMCALPtMin){
248 TLorentzVector lvGamma1, lvGamma2 ;
249 //Double_t angle = 0;
252 MakePi0Decay(momentum,lvGamma1,lvGamma2);//,angle);
254 //Check if Pi0 is in the acceptance of the calorimeters, if aperture angle is small, keep it
255 TParticle * pPhoton1 = new TParticle(22,1,iParticle,0,0,0,lvGamma1.Px(),lvGamma1.Py(),
256 lvGamma1.Pz(),lvGamma1.E(),0,0,0,0);
257 TParticle * pPhoton2 = new TParticle(22,1,iParticle,0,0,0,lvGamma2.Px(),lvGamma2.Py(),
258 lvGamma2.Pz(),lvGamma2.E(),0,0,0,0);
259 //Fill particle/calocluster arrays
260 FillCalorimeters(iParticle,pPhoton1,lvGamma1, indexPHOS, indexEMCAL);
261 FillCalorimeters(iParticle,pPhoton2,lvGamma2, indexPHOS, indexEMCAL);
264 else FillCalorimeters(iParticle,particle, momentum, indexPHOS, indexEMCAL); //Add the rest
267 } //particle with correct status
272 //________________________________________________________________
273 Bool_t AliCaloTrackMCReader::KeepParticleWithStatus(Int_t status) const {
274 //Check if status is equal to one of the list
275 //These particles will be used in analysis.
277 for(Int_t i= 0; i < fStatusArray->GetSize(); i++)
278 if(status == fStatusArray->At(i)) return kTRUE ;
287 //________________________________________________________________
288 Bool_t AliCaloTrackMCReader::KeepChargedParticles(Int_t pdg) const {
289 //Check if pdg is equal to one of the charged particles list
290 //These particles will be added to the calorimeters lists.
292 for(Int_t i= 0; i < fChargedParticlesArray->GetSize(); i++)
293 if(TMath::Abs(pdg) == fChargedParticlesArray->At(i)) return kTRUE ;
299 //________________________________________________________________
300 void AliCaloTrackMCReader::Print(const Option_t * opt) const
302 //Print some relevant parameters set for the analysis
306 Info("**** Print **** ", "%s %s", GetName(), GetTitle() ) ;
308 printf("Decay Pi0? : %d\n", fDecayPi0) ;
309 printf("TClonesArray type : %d\n", fClonesArrayType) ;
310 printf("Keep all status? : %d\n", fKeepAllStatus) ;
312 if(!fKeepAllStatus) printf("Keep particles with status : ");
313 for(Int_t i= 0; i < fStatusArray->GetSize(); i++)
314 printf(" %d ; ", fStatusArray->At(i));
317 printf("Skip neutral particles in calo : ");
318 for(Int_t i= 0; i < fNeutralParticlesArray->GetSize(); i++)
319 printf(" %d ; ", fNeutralParticlesArray->At(i));
322 printf("Keep charged particles in calo : ");
323 for(Int_t i= 0; i < fChargedParticlesArray->GetSize(); i++)
324 printf(" %d ; ", fChargedParticlesArray->At(i));
329 //____________________________________________________________________________
330 void AliCaloTrackMCReader::MakePi0Decay(TLorentzVector &p0, TLorentzVector &p1,
331 TLorentzVector &p2){//, Double_t &angle) {
332 // Perform isotropic decay pi0 -> 2 photons
333 // p0 is pi0 4-momentum (inut)
334 // p1 and p2 are photon 4-momenta (output)
335 // cout<<"Boost vector"<<endl;
336 Double_t mPi0 = TDatabasePDG::Instance()->GetParticle(111)->Mass();
337 TVector3 b = p0.BoostVector();
338 //cout<<"Parameters"<<endl;
339 //Double_t mPi0 = p0.M();
340 Double_t phi = TMath::TwoPi() * gRandom->Rndm();
341 Double_t cosThe = 2 * gRandom->Rndm() - 1;
342 Double_t cosPhi = TMath::Cos(phi);
343 Double_t sinPhi = TMath::Sin(phi);
344 Double_t sinThe = TMath::Sqrt(1-cosThe*cosThe);
345 Double_t ePi0 = mPi0/2.;
346 //cout<<"ePi0 "<<ePi0<<endl;
347 //cout<<"Components"<<endl;
348 p1.SetPx(+ePi0*cosPhi*sinThe);
349 p1.SetPy(+ePi0*sinPhi*sinThe);
350 p1.SetPz(+ePi0*cosThe);
352 //cout<<"p1: "<<p1.Px()<<" "<<p1.Py()<<" "<<p1.Pz()<<" "<<p1.E()<<endl;
353 //cout<<"p1 Mass: "<<p1.Px()*p1.Px()+p1.Py()*p1.Py()+p1.Pz()*p1.Pz()-p1.E()*p1.E()<<endl;
354 p2.SetPx(-ePi0*cosPhi*sinThe);
355 p2.SetPy(-ePi0*sinPhi*sinThe);
356 p2.SetPz(-ePi0*cosThe);
358 //cout<<"p2: "<<p2.Px()<<" "<<p2.Py()<<" "<<p2.Pz()<<" "<<p2.E()<<endl;
359 //cout<<"p2 Mass: "<<p2.Px()*p2.Px()+p2.Py()*p2.Py()+p2.Pz()*p2.Pz()-p2.E()*p2.E()<<endl;
360 //cout<<"Boost "<<b.X()<<" "<<b.Y()<<" "<<b.Z()<<endl;
362 //cout<<"p1: "<<p1.Px()<<" "<<p1.Py()<<" "<<p1.Pz()<<" "<<p1.E()<<endl;
364 //cout<<"p2: "<<p2.Px()<<" "<<p2.Py()<<" "<<p2.Pz()<<" "<<p2.E()<<endl;
365 //cout<<"angle"<<endl;
366 //angle = p1.Angle(p2.Vect());
370 //____________________________________________________________________________
371 void AliCaloTrackMCReader::SetInputEvent(TObject* /*esd*/, TObject* /*aod*/, TObject* mc) {
372 // Connect the data pointer
373 SetMC((AliMCEvent*) mc);
377 //________________________________________________________________
378 Bool_t AliCaloTrackMCReader::SkipNeutralParticles(Int_t pdg) const {
379 //Check if pdg is equal to one of the neutral particles list
380 //These particles will be skipped from analysis.
382 for(Int_t i= 0; i < fNeutralParticlesArray->GetSize(); i++)
383 if(TMath::Abs(pdg) == fNeutralParticlesArray->At(i)) return kTRUE ;
390 //____________________________________________________________________
391 void AliCaloTrackMCReader::SetTrackChargeAndPID(const Int_t pdgCode, AliAODTrack *track) {
393 Float_t PID[10] = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0.};
399 PID[AliAODTrack::kUnknown] = 1.;
404 track->SetCharge(-1);
405 PID[AliAODTrack::kElectron] = 1.;
410 track->SetCharge(+1);
411 PID[AliAODTrack::kElectron] = 1.;
416 track->SetCharge(-1);
417 PID[AliAODTrack::kMuon] = 1.;
422 track->SetCharge(+1);
423 PID[AliAODTrack::kMuon] = 1.;
429 PID[AliAODTrack::kUnknown] = 1.;
434 track->SetCharge(+1);
435 PID[AliAODTrack::kPion] = 1.;
440 track->SetCharge(-1);
441 PID[AliAODTrack::kPion] = 1.;
447 PID[AliAODTrack::kUnknown] = 1.;
452 track->SetCharge(+1);
453 PID[AliAODTrack::kKaon] = 1.;
458 track->SetCharge(-1);
459 PID[AliAODTrack::kKaon] = 1.;
465 PID[AliAODTrack::kUnknown] = 1.;
470 track->SetCharge(+1);
471 PID[AliAODTrack::kProton] = 1.;
475 case -2212: // anti-p
476 track->SetCharge(-1);
477 PID[AliAODTrack::kProton] = 1.;
483 PID[AliAODTrack::kUnknown] = 1.;
489 PID[AliAODTrack::kUnknown] = 1.;
493 case -311: // anti-K0
495 PID[AliAODTrack::kUnknown] = 1.;
501 PID[AliAODTrack::kUnknown] = 1.;
507 PID[AliAODTrack::kUnknown] = 1.;
512 track->SetCharge(+1);
513 PID[AliAODTrack::kUnknown] = 1.;
518 track->SetCharge(-1);
519 PID[AliAODTrack::kUnknown] = 1.;
524 track->SetCharge(-1);
525 PID[AliAODTrack::kUnknown] = 1.;
531 PID[AliAODTrack::kUnknown] = 1.;
536 track->SetCharge(-1);
537 PID[AliAODTrack::kUnknown] = 1.;
542 track->SetCharge(-1);
543 PID[AliAODTrack::kUnknown] = 1.;
549 PID[AliAODTrack::kUnknown] = 1.;
553 case -3122: // anti-Lambda
555 PID[AliAODTrack::kUnknown] = 1.;
559 case -3222: // anti-Sigma-
560 track->SetCharge(-1);
561 PID[AliAODTrack::kUnknown] = 1.;
565 case -3212: // anti-Sigma0
567 PID[AliAODTrack::kUnknown] = 1.;
571 case -3112: // anti-Sigma+
572 track->SetCharge(+1);
573 PID[AliAODTrack::kUnknown] = 1.;
577 case -3322: // anti-Xi0
579 PID[AliAODTrack::kUnknown] = 1.;
583 case -3312: // anti-Xi+
584 track->SetCharge(+1);
587 case -3334: // anti-Omega+
588 track->SetCharge(+1);
589 PID[AliAODTrack::kUnknown] = 1.;
594 track->SetCharge(+1);
595 PID[AliAODTrack::kUnknown] = 1.;
600 track->SetCharge(-1);
601 PID[AliAODTrack::kUnknown] = 1.;
607 PID[AliAODTrack::kUnknown] = 1.;
611 case -421: // anti-D0
613 PID[AliAODTrack::kUnknown] = 1.;
618 track->SetCharge(-99);
619 PID[AliAODTrack::kUnknown] = 1.;
626 //____________________________________________________________________
627 void AliCaloTrackMCReader::SetCaloClusterPID(const Int_t pdgCode, AliAODCaloCluster *calo) {
629 Float_t PID[9] = {0., 0., 0., 0., 0., 0., 0., 0., 0.};
634 PID[AliAODCaloCluster::kPhoton] = 1.;
639 PID[AliAODCaloCluster::kElectron] = 1.;
644 PID[AliAODCaloCluster::kElectron] = 1.;
649 PID[AliAODCaloCluster::kCharged] = 1.;
654 PID[AliAODCaloCluster::kCharged] = 1.;
659 PID[AliAODCaloCluster::kPi0] = 1.;
664 PID[AliAODCaloCluster::kCharged] = 1.;
669 PID[AliAODCaloCluster::kCharged] = 1.;
674 PID[AliAODCaloCluster::kKaon0] = 1.;
675 PID[AliAODCaloCluster::kNeutral] = 1;
680 PID[AliAODCaloCluster::kCharged] = 1.;
685 PID[AliAODCaloCluster::kCharged] = 1.;
690 PID[AliAODCaloCluster::kNeutron] = 1.;
691 PID[AliAODCaloCluster::kNeutral] = 1.;
696 PID[AliAODCaloCluster::kCharged] = 1.;
700 case -2212: // anti-p
701 PID[AliAODCaloCluster::kCharged] = 1.;
706 PID[AliAODCaloCluster::kKaon0] = 1.;
707 PID[AliAODCaloCluster::kNeutral] = 1.;
712 PID[AliAODCaloCluster::kKaon0] = 1.;
713 PID[AliAODCaloCluster::kNeutral] = 1.;
717 case -311: // anti-K0
718 PID[AliAODCaloCluster::kKaon0] = 1.;
719 PID[AliAODCaloCluster::kNeutral] = 1.;
724 PID[AliAODCaloCluster::kNeutral] = 1.;
729 PID[AliAODCaloCluster::kUnknown] = 1.;
734 PID[AliAODCaloCluster::kUnknown] = 1.;
739 PID[AliAODCaloCluster::kUnknown] = 1.;
744 PID[AliAODCaloCluster::kUnknown] = 1.;
749 PID[AliAODCaloCluster::kUnknown] = 1.;
754 PID[AliAODCaloCluster::kUnknown] = 1.;
759 PID[AliAODCaloCluster::kUnknown] = 1.;
764 PID[AliAODCaloCluster::kNeutron] = 1.;
765 PID[AliAODCaloCluster::kNeutral] = 1.;
769 case -3122: // anti-Lambda
770 PID[AliAODCaloCluster::kUnknown] = 1.;
774 case -3222: // anti-Sigma-
775 PID[AliAODCaloCluster::kUnknown] = 1.;
779 case -3212: // anti-Sigma0
780 PID[AliAODCaloCluster::kUnknown] = 1.;
784 case -3112: // anti-Sigma+
785 PID[AliAODCaloCluster::kUnknown] = 1.;
789 case -3322: // anti-Xi0
790 PID[AliAODCaloCluster::kUnknown] = 1.;
794 case -3312: // anti-Xi+
795 PID[AliAODCaloCluster::kUnknown] = 1.;
799 case -3334: // anti-Omega+
800 PID[AliAODCaloCluster::kUnknown] = 1.;
805 PID[AliAODCaloCluster::kUnknown] = 1.;
810 PID[AliAODCaloCluster::kUnknown] = 1.;
815 PID[AliAODCaloCluster::kUnknown] = 1.;
819 case -421: // anti-D0
820 PID[AliAODCaloCluster::kUnknown] = 1.;
825 PID[AliAODCaloCluster::kUnknown] = 1.;