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:
24 //_________________________________________________________________________
25 // Class for reading data (Kinematics) in order to do prompt gamma
26 // or other particle identification and correlations
28 //*-- Author: Gustavo Conesa (LNF-INFN)
29 //////////////////////////////////////////////////////////////////////////////
32 // --- ROOT system ---
34 #include <TParticle.h>
38 #include <TClonesArray.h>
40 //---- ANALYSIS system ----
41 #include "AliCaloTrackMCReader.h"
42 #include "Riostream.h"
44 #include "AliGenEventHeader.h"
46 #include "AliAODCaloCluster.h"
47 #include "AliAODTrack.h"
49 ClassImp(AliCaloTrackMCReader)
51 //____________________________________________________________________________
52 AliCaloTrackMCReader::AliCaloTrackMCReader() :
53 AliCaloTrackReader(), fDecayPi0(0),
54 fNeutralParticlesArray(0x0), fChargedParticlesArray(0x0),
55 fStatusArray(0x0), fKeepAllStatus(0), fClonesArrayType(0)
59 //Initialize parameters
65 //____________________________________________________________________________
66 AliCaloTrackMCReader::AliCaloTrackMCReader(const AliCaloTrackMCReader & g) :
67 AliCaloTrackReader(g), fDecayPi0(g.fDecayPi0),
68 fNeutralParticlesArray(g.fNeutralParticlesArray?new TArrayI(*g.fNeutralParticlesArray):0x0),
69 fChargedParticlesArray(g.fChargedParticlesArray?new TArrayI(*g.fChargedParticlesArray):0x0),
70 fStatusArray(g.fStatusArray?new TArrayI(*g.fStatusArray):0x0),
71 fKeepAllStatus(g.fKeepAllStatus), fClonesArrayType(g.fClonesArrayType)
76 //_________________________________________________________________________
77 AliCaloTrackMCReader & AliCaloTrackMCReader::operator = (const AliCaloTrackMCReader & source)
79 // assignment operator
81 if(&source == this) return *this;
83 fDecayPi0 = source.fDecayPi0;
85 delete fChargedParticlesArray;
86 fChargedParticlesArray = source.fChargedParticlesArray?new TArrayI(*source.fChargedParticlesArray):0x0;
88 delete fNeutralParticlesArray;
89 fNeutralParticlesArray = source.fNeutralParticlesArray?new TArrayI(*source.fNeutralParticlesArray):0x0;
92 fStatusArray = source.fStatusArray?new TArrayI(*source.fStatusArray):0x0;
94 fKeepAllStatus = source.fKeepAllStatus ;
95 fClonesArrayType = source.fClonesArrayType ;
101 //_________________________________
102 AliCaloTrackMCReader::~AliCaloTrackMCReader() {
105 if(fChargedParticlesArray) delete fChargedParticlesArray ;
106 if(fNeutralParticlesArray) delete fNeutralParticlesArray ;
107 if(fStatusArray) delete fStatusArray ;
111 //____________________________________________________________________________
112 void AliCaloTrackMCReader::GetVertex(Double_t v[3]) {
113 //Return vertex position
116 GetGenEventHeader()->PrimaryVertex(pv);
124 //_______________________________________________________________
125 void AliCaloTrackMCReader::InitParameters()
128 //Initialize the parameters of the analysis.
132 fChargedParticlesArray = new TArrayI(1);
133 fChargedParticlesArray->SetAt(11,0);
134 //Int_t pdgarray[]={12,14,16};// skip neutrinos
135 //fNeutralParticlesArray = new TArrayI(3, pdgarray);
136 fNeutralParticlesArray = new TArrayI(3);
137 fNeutralParticlesArray->SetAt(12,0); fNeutralParticlesArray->SetAt(14,1); fNeutralParticlesArray->SetAt(16,2);
138 fStatusArray = new TArrayI(1);
139 fStatusArray->SetAt(1,0);
141 fKeepAllStatus = kFALSE;
142 fClonesArrayType = kAliAOD ;
146 //____________________________________________________________________________
147 void AliCaloTrackMCReader::FillCalorimeters(const Int_t iParticle, TParticle* particle, TLorentzVector momentum,
148 Int_t &indexPHOS, Int_t &indexEMCAL){
149 //Fill AODCaloClusters or TParticles lists of PHOS or EMCAL
152 if(fFillPHOS && fFidutialCut->IsInFidutialCut(momentum,"PHOS") && momentum.Pt() > fPHOSPtMin){
154 if(fClonesArrayType == kTParticle) new((*fAODPHOS)[indexPHOS++]) TParticle(*particle) ;
157 Char_t ttype= AliAODCluster::kPHOSNeutral;
158 Int_t labels[] = {iParticle};
159 Float_t x[] = {momentum.X(), momentum.Y(), momentum.Z()};
160 AliAODCaloCluster *calo = new((*fAODPHOS)[indexPHOS++])
161 AliAODCaloCluster(iParticle,1,labels,momentum.E(), x, NULL, ttype, 0);
162 SetCaloClusterPID(particle->GetPdgCode(),calo) ;
166 else if(fFillEMCAL && fFidutialCut->IsInFidutialCut(momentum,"EMCAL") && momentum.Pt() > fEMCALPtMin){
167 //cout<<"Reader : E "<<momentum.E()<<" ; Phi"<<momentum.Phi()<< " ; Eta "<<momentum.Eta()<<endl;
168 if(fClonesArrayType == kTParticle) new((*fAODEMCAL)[indexEMCAL++]) TParticle(*particle) ;
170 Char_t ttype= AliAODCluster::kEMCALClusterv1;
171 Int_t labels[] = {iParticle};
172 Float_t x[] = {momentum.X(), momentum.Y(), momentum.Z()};
173 AliAODCaloCluster *calo = new((*fAODEMCAL)[indexEMCAL++])
174 AliAODCaloCluster(iParticle,1,labels,momentum.E(), x, NULL, ttype, 0);
175 SetCaloClusterPID(particle->GetPdgCode(),calo) ;
180 //____________________________________________________________________________
181 void AliCaloTrackMCReader::FillInputEvent()
183 //Create list of particles from EMCAL, PHOS and CTS.
185 if(fClonesArrayType == kTParticle){
186 fAODCTS = new TClonesArray("TParticle",0);
187 fAODEMCAL = new TClonesArray("TParticle",0);
188 fAODPHOS = new TClonesArray("TParticle",0);
190 else if(fClonesArrayType == kAliAOD){
191 fAODCTS = new TClonesArray("AliAODTrack",0);
192 fAODPHOS = new TClonesArray("AliAODCaloCluster",0);
193 fAODEMCAL = new TClonesArray("AliAODCaloCluster",0);
195 else {AliFatal("Wrong clones type");}
199 Int_t indexEMCAL = 0 ;
200 Int_t indexPHOS = 0 ;
202 Int_t iParticle = 0 ;
203 Double_t charge = 0.;
205 for (iParticle=0 ; iParticle < GetStack()->GetNprimary() ; iParticle++) {
206 TParticle * particle = GetStack()->Particle(iParticle);
207 TLorentzVector momentum;
210 Int_t pdg = particle->GetPdgCode();
212 //Keep particles with a given status
213 if(KeepParticleWithStatus(particle->GetStatusCode()) && (particle->Pt() > 0) ){
215 charge = TDatabasePDG::Instance()->GetParticle(pdg)->Charge();
216 particle->Momentum(momentum);
217 //---------- Charged particles ----------------------
218 if((charge != 0) && (momentum.Pt() > fCTSPtMin) && (fFidutialCut->IsInFidutialCut(momentum,"CTS"))){
220 //Particles in CTS acceptance
221 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",
222 momentum.E(),momentum.Pt(),momentum.Phi()*TMath::RadToDeg(),momentum.Eta());
224 if(fClonesArrayType == kTParticle) new((*fAODCTS)[indexCh++]) TParticle(*particle) ;
226 x[0] = particle->Vx(); x[1] = particle->Vy(); x[2] = particle->Vz();
227 p[0] = particle->Px(); p[1] = particle->Py(); p[2] = particle->Pz();
228 AliAODTrack *aodTrack = new((*fAODCTS)[indexCh++])
229 AliAODTrack(0, iParticle, p, kTRUE, x, kFALSE,NULL, 0, 0,
232 kFALSE, // No fit performed
233 kFALSE, // No fit performed
234 AliAODTrack::kPrimary,
236 SetTrackChargeAndPID(pdg, aodTrack);
239 //Keep some charged particles in calorimeters lists
240 if((fFillPHOS || fFillEMCAL) && KeepChargedParticles(pdg)) FillCalorimeters(iParticle, particle, momentum, indexPHOS, indexEMCAL);
244 //-------------Neutral particles ----------------------
245 else if(charge == 0 && (fFillPHOS || fFillEMCAL)){
246 //Skip neutrinos or other neutral particles
247 if(SkipNeutralParticles(pdg) || particle->IsPrimary()) continue ; // protection added (MG)
249 //Fill particle/calocluster arrays
250 if(!fDecayPi0) FillCalorimeters(iParticle, particle, momentum, indexPHOS, indexEMCAL);
252 //Sometimes pi0 are stable for the generator, if needed decay it by hand
254 if(momentum.Pt() > fPHOSPtMin || momentum.Pt() > fEMCALPtMin){
255 TLorentzVector lvGamma1, lvGamma2 ;
256 //Double_t angle = 0;
259 MakePi0Decay(momentum,lvGamma1,lvGamma2);//,angle);
261 //Check if Pi0 is in the acceptance of the calorimeters, if aperture angle is small, keep it
262 TParticle * pPhoton1 = new TParticle(22,1,iParticle,0,0,0,lvGamma1.Px(),lvGamma1.Py(),
263 lvGamma1.Pz(),lvGamma1.E(),0,0,0,0);
264 TParticle * pPhoton2 = new TParticle(22,1,iParticle,0,0,0,lvGamma2.Px(),lvGamma2.Py(),
265 lvGamma2.Pz(),lvGamma2.E(),0,0,0,0);
266 //Fill particle/calocluster arrays
267 FillCalorimeters(iParticle,pPhoton1,lvGamma1, indexPHOS, indexEMCAL);
268 FillCalorimeters(iParticle,pPhoton2,lvGamma2, indexPHOS, indexEMCAL);
271 else FillCalorimeters(iParticle,particle, momentum, indexPHOS, indexEMCAL); //Add the rest
274 } //particle with correct status
279 //________________________________________________________________
280 Bool_t AliCaloTrackMCReader::KeepParticleWithStatus(Int_t status) const {
281 //Check if status is equal to one of the list
282 //These particles will be used in analysis.
284 for(Int_t i= 0; i < fStatusArray->GetSize(); i++)
285 if(status == fStatusArray->At(i)) return kTRUE ;
294 //________________________________________________________________
295 Bool_t AliCaloTrackMCReader::KeepChargedParticles(Int_t pdg) const {
296 //Check if pdg is equal to one of the charged particles list
297 //These particles will be added to the calorimeters lists.
299 for(Int_t i= 0; i < fChargedParticlesArray->GetSize(); i++)
300 if(TMath::Abs(pdg) == fChargedParticlesArray->At(i)) return kTRUE ;
306 //________________________________________________________________
307 void AliCaloTrackMCReader::Print(const Option_t * opt) const
309 //Print some relevant parameters set for the analysis
313 Info("**** Print **** ", "%s %s", GetName(), GetTitle() ) ;
315 printf("Decay Pi0? : %d\n", fDecayPi0) ;
316 printf("TClonesArray type : %d\n", fClonesArrayType) ;
317 printf("Keep all status? : %d\n", fKeepAllStatus) ;
319 if(!fKeepAllStatus) printf("Keep particles with status : ");
320 for(Int_t i= 0; i < fStatusArray->GetSize(); i++)
321 printf(" %d ; ", fStatusArray->At(i));
324 printf("Skip neutral particles in calo : ");
325 for(Int_t i= 0; i < fNeutralParticlesArray->GetSize(); i++)
326 printf(" %d ; ", fNeutralParticlesArray->At(i));
329 printf("Keep charged particles in calo : ");
330 for(Int_t i= 0; i < fChargedParticlesArray->GetSize(); i++)
331 printf(" %d ; ", fChargedParticlesArray->At(i));
336 //____________________________________________________________________________
337 void AliCaloTrackMCReader::MakePi0Decay(TLorentzVector &p0, TLorentzVector &p1,
338 TLorentzVector &p2){//, Double_t &angle) {
339 // Perform isotropic decay pi0 -> 2 photons
340 // p0 is pi0 4-momentum (inut)
341 // p1 and p2 are photon 4-momenta (output)
342 // cout<<"Boost vector"<<endl;
343 Double_t mPi0 = TDatabasePDG::Instance()->GetParticle(111)->Mass();
344 TVector3 b = p0.BoostVector();
345 //cout<<"Parameters"<<endl;
346 //Double_t mPi0 = p0.M();
347 Double_t phi = TMath::TwoPi() * gRandom->Rndm();
348 Double_t cosThe = 2 * gRandom->Rndm() - 1;
349 Double_t cosPhi = TMath::Cos(phi);
350 Double_t sinPhi = TMath::Sin(phi);
351 Double_t sinThe = TMath::Sqrt(1-cosThe*cosThe);
352 Double_t ePi0 = mPi0/2.;
353 //cout<<"ePi0 "<<ePi0<<endl;
354 //cout<<"Components"<<endl;
355 p1.SetPx(+ePi0*cosPhi*sinThe);
356 p1.SetPy(+ePi0*sinPhi*sinThe);
357 p1.SetPz(+ePi0*cosThe);
359 //cout<<"p1: "<<p1.Px()<<" "<<p1.Py()<<" "<<p1.Pz()<<" "<<p1.E()<<endl;
360 //cout<<"p1 Mass: "<<p1.Px()*p1.Px()+p1.Py()*p1.Py()+p1.Pz()*p1.Pz()-p1.E()*p1.E()<<endl;
361 p2.SetPx(-ePi0*cosPhi*sinThe);
362 p2.SetPy(-ePi0*sinPhi*sinThe);
363 p2.SetPz(-ePi0*cosThe);
365 //cout<<"p2: "<<p2.Px()<<" "<<p2.Py()<<" "<<p2.Pz()<<" "<<p2.E()<<endl;
366 //cout<<"p2 Mass: "<<p2.Px()*p2.Px()+p2.Py()*p2.Py()+p2.Pz()*p2.Pz()-p2.E()*p2.E()<<endl;
367 //cout<<"Boost "<<b.X()<<" "<<b.Y()<<" "<<b.Z()<<endl;
369 //cout<<"p1: "<<p1.Px()<<" "<<p1.Py()<<" "<<p1.Pz()<<" "<<p1.E()<<endl;
371 //cout<<"p2: "<<p2.Px()<<" "<<p2.Py()<<" "<<p2.Pz()<<" "<<p2.E()<<endl;
372 //cout<<"angle"<<endl;
373 //angle = p1.Angle(p2.Vect());
377 //____________________________________________________________________________
378 void AliCaloTrackMCReader::SetInputEvent(TObject* /*esd*/, TObject* /*aod*/, TObject* mc) {
379 // Connect the data pointer
380 SetMC((AliMCEvent*) mc);
384 //________________________________________________________________
385 Bool_t AliCaloTrackMCReader::SkipNeutralParticles(Int_t pdg) const {
386 //Check if pdg is equal to one of the neutral particles list
387 //These particles will be skipped from analysis.
389 for(Int_t i= 0; i < fNeutralParticlesArray->GetSize(); i++)
390 if(TMath::Abs(pdg) == fNeutralParticlesArray->At(i)) return kTRUE ;
397 //____________________________________________________________________
398 void AliCaloTrackMCReader::SetTrackChargeAndPID(const Int_t pdgCode, AliAODTrack *track) {
400 Float_t PID[10] = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0.};
406 PID[AliAODTrack::kUnknown] = 1.;
411 track->SetCharge(-1);
412 PID[AliAODTrack::kElectron] = 1.;
417 track->SetCharge(+1);
418 PID[AliAODTrack::kElectron] = 1.;
423 track->SetCharge(-1);
424 PID[AliAODTrack::kMuon] = 1.;
429 track->SetCharge(+1);
430 PID[AliAODTrack::kMuon] = 1.;
436 PID[AliAODTrack::kUnknown] = 1.;
441 track->SetCharge(+1);
442 PID[AliAODTrack::kPion] = 1.;
447 track->SetCharge(-1);
448 PID[AliAODTrack::kPion] = 1.;
454 PID[AliAODTrack::kUnknown] = 1.;
459 track->SetCharge(+1);
460 PID[AliAODTrack::kKaon] = 1.;
465 track->SetCharge(-1);
466 PID[AliAODTrack::kKaon] = 1.;
472 PID[AliAODTrack::kUnknown] = 1.;
477 track->SetCharge(+1);
478 PID[AliAODTrack::kProton] = 1.;
482 case -2212: // anti-p
483 track->SetCharge(-1);
484 PID[AliAODTrack::kProton] = 1.;
490 PID[AliAODTrack::kUnknown] = 1.;
496 PID[AliAODTrack::kUnknown] = 1.;
500 case -311: // anti-K0
502 PID[AliAODTrack::kUnknown] = 1.;
508 PID[AliAODTrack::kUnknown] = 1.;
514 PID[AliAODTrack::kUnknown] = 1.;
519 track->SetCharge(+1);
520 PID[AliAODTrack::kUnknown] = 1.;
525 track->SetCharge(-1);
526 PID[AliAODTrack::kUnknown] = 1.;
531 track->SetCharge(-1);
532 PID[AliAODTrack::kUnknown] = 1.;
538 PID[AliAODTrack::kUnknown] = 1.;
543 track->SetCharge(-1);
544 PID[AliAODTrack::kUnknown] = 1.;
549 track->SetCharge(-1);
550 PID[AliAODTrack::kUnknown] = 1.;
556 PID[AliAODTrack::kUnknown] = 1.;
560 case -3122: // anti-Lambda
562 PID[AliAODTrack::kUnknown] = 1.;
566 case -3222: // anti-Sigma-
567 track->SetCharge(-1);
568 PID[AliAODTrack::kUnknown] = 1.;
572 case -3212: // anti-Sigma0
574 PID[AliAODTrack::kUnknown] = 1.;
578 case -3112: // anti-Sigma+
579 track->SetCharge(+1);
580 PID[AliAODTrack::kUnknown] = 1.;
584 case -3322: // anti-Xi0
586 PID[AliAODTrack::kUnknown] = 1.;
590 case -3312: // anti-Xi+
591 track->SetCharge(+1);
594 case -3334: // anti-Omega+
595 track->SetCharge(+1);
596 PID[AliAODTrack::kUnknown] = 1.;
601 track->SetCharge(+1);
602 PID[AliAODTrack::kUnknown] = 1.;
607 track->SetCharge(-1);
608 PID[AliAODTrack::kUnknown] = 1.;
614 PID[AliAODTrack::kUnknown] = 1.;
618 case -421: // anti-D0
620 PID[AliAODTrack::kUnknown] = 1.;
625 track->SetCharge(-99);
626 PID[AliAODTrack::kUnknown] = 1.;
633 //____________________________________________________________________
634 void AliCaloTrackMCReader::SetCaloClusterPID(const Int_t pdgCode, AliAODCaloCluster *calo) {
636 Float_t PID[9] = {0., 0., 0., 0., 0., 0., 0., 0., 0.};
641 PID[AliAODCaloCluster::kPhoton] = 1.;
646 PID[AliAODCaloCluster::kElectron] = 1.;
651 PID[AliAODCaloCluster::kElectron] = 1.;
656 PID[AliAODCaloCluster::kCharged] = 1.;
661 PID[AliAODCaloCluster::kCharged] = 1.;
666 PID[AliAODCaloCluster::kPi0] = 1.;
671 PID[AliAODCaloCluster::kCharged] = 1.;
676 PID[AliAODCaloCluster::kCharged] = 1.;
681 PID[AliAODCaloCluster::kKaon0] = 1.;
682 PID[AliAODCaloCluster::kNeutral] = 1;
687 PID[AliAODCaloCluster::kCharged] = 1.;
692 PID[AliAODCaloCluster::kCharged] = 1.;
697 PID[AliAODCaloCluster::kNeutron] = 1.;
698 PID[AliAODCaloCluster::kNeutral] = 1.;
703 PID[AliAODCaloCluster::kCharged] = 1.;
707 case -2212: // anti-p
708 PID[AliAODCaloCluster::kCharged] = 1.;
713 PID[AliAODCaloCluster::kKaon0] = 1.;
714 PID[AliAODCaloCluster::kNeutral] = 1.;
719 PID[AliAODCaloCluster::kKaon0] = 1.;
720 PID[AliAODCaloCluster::kNeutral] = 1.;
724 case -311: // anti-K0
725 PID[AliAODCaloCluster::kKaon0] = 1.;
726 PID[AliAODCaloCluster::kNeutral] = 1.;
731 PID[AliAODCaloCluster::kNeutral] = 1.;
736 PID[AliAODCaloCluster::kUnknown] = 1.;
741 PID[AliAODCaloCluster::kUnknown] = 1.;
746 PID[AliAODCaloCluster::kUnknown] = 1.;
751 PID[AliAODCaloCluster::kUnknown] = 1.;
756 PID[AliAODCaloCluster::kUnknown] = 1.;
761 PID[AliAODCaloCluster::kUnknown] = 1.;
766 PID[AliAODCaloCluster::kUnknown] = 1.;
771 PID[AliAODCaloCluster::kNeutron] = 1.;
772 PID[AliAODCaloCluster::kNeutral] = 1.;
776 case -3122: // anti-Lambda
777 PID[AliAODCaloCluster::kUnknown] = 1.;
781 case -3222: // anti-Sigma-
782 PID[AliAODCaloCluster::kUnknown] = 1.;
786 case -3212: // anti-Sigma0
787 PID[AliAODCaloCluster::kUnknown] = 1.;
791 case -3112: // anti-Sigma+
792 PID[AliAODCaloCluster::kUnknown] = 1.;
796 case -3322: // anti-Xi0
797 PID[AliAODCaloCluster::kUnknown] = 1.;
801 case -3312: // anti-Xi+
802 PID[AliAODCaloCluster::kUnknown] = 1.;
806 case -3334: // anti-Omega+
807 PID[AliAODCaloCluster::kUnknown] = 1.;
812 PID[AliAODCaloCluster::kUnknown] = 1.;
817 PID[AliAODCaloCluster::kUnknown] = 1.;
822 PID[AliAODCaloCluster::kUnknown] = 1.;
826 case -421: // anti-D0
827 PID[AliAODCaloCluster::kUnknown] = 1.;
832 PID[AliAODCaloCluster::kUnknown] = 1.;