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 ///////////////////////////////////////////////////////////////////////////
20 Origin: marian.ivanov@cern.ch
21 Container classes with MC infomation
25 #if !defined(__CINT__) || defined(__MAKECINT__)
36 #include "TStopwatch.h"
37 #include "TParticle.h"
40 #include "TGeometry.h"
41 #include "TPolyLine3D.h"
46 #include "AliSimDigits.h"
47 #include "AliTPCParam.h"
49 #include "AliTPCLoader.h"
50 #include "AliDetector.h"
51 #include "AliTrackReference.h"
52 #include "AliTPCParamSR.h"
53 #include "AliTracker.h"
56 #include "AliTrackPointArray.h"
59 #include "AliGenInfo.h"
63 ClassImp(AliTPCdigitRow);
65 ClassImp(AliGenV0Info)
66 ClassImp(AliGenKinkInfo)
70 ////////////////////////////////////////////////////////////////////////
71 AliMCInfo::AliMCInfo():
84 fRowsWithDigitsInn(0),
89 fNTPCRef(0), // tpc references counter
90 fNITSRef(0), // ITS references counter
91 fNTRDRef(0), // TRD references counter
92 fNTOFRef(0), // TOF references counter
98 fTPCReferences = new TClonesArray("AliTrackReference",10);
99 fITSReferences = new TClonesArray("AliTrackReference",10);
100 fTRDReferences = new TClonesArray("AliTrackReference",10);
101 fTOFReferences = new TClonesArray("AliTrackReference",10);
102 fTRdecay.SetTrack(-1);
106 AliMCInfo::AliMCInfo(const AliMCInfo& info):
108 fTrackRef(info.fTrackRef),
109 fTrackRefOut(info.fTrackRefOut),
110 fTRdecay(info.GetTRdecay()),
111 fPrimPart(info.fPrimPart),
112 fParticle(info.fParticle),
113 fMass(info.GetMass()),
114 fCharge(info.fCharge),
116 fEventNr(info.fEventNr),
117 fMCtracks(info.fMCtracks),
119 fTPCdecay(info.fTPCdecay),
120 fRowsWithDigitsInn(info.fRowsWithDigitsInn),
121 fRowsWithDigits(info.fRowsWithDigits),
122 fRowsTrackLength(info.fRowsTrackLength),
124 fTPCRow(info.fTPCRow),
125 fNTPCRef(info.fNTPCRef), // tpc references counter
126 fNITSRef(info.fNITSRef), // ITS references counter
127 fNTRDRef(info.fNTRDRef), // TRD references counter
128 fNTOFRef(info.fNTOFRef), // TOF references counter
134 fTPCReferences = (TClonesArray*)info.fTPCReferences->Clone();
135 fITSReferences = (TClonesArray*)info.fITSReferences->Clone();
136 fTRDReferences = (TClonesArray*)info.fTRDReferences->Clone();
137 fTOFReferences = (TClonesArray*)info.fTOFReferences->Clone();
141 AliMCInfo::~AliMCInfo()
143 if (fTPCReferences) {
144 delete fTPCReferences;
147 delete fITSReferences;
150 delete fTRDReferences;
153 delete fTOFReferences;
160 void AliMCInfo::Update()
165 if (!fTPCReferences) {
171 fNTPCRef = fTPCReferences->GetEntriesFast();
172 fNITSRef = fITSReferences->GetEntriesFast();
173 fNTRDRef = fTRDReferences->GetEntriesFast();
174 fNTOFRef = fTOFReferences->GetEntriesFast();
176 for (Int_t iref =0;iref<fTPCReferences->GetEntriesFast();iref++){
177 AliTrackReference * ref = (AliTrackReference *) fTPCReferences->At(iref);
178 //Float_t r = (ref->X()*ref->X()+ref->Y()*ref->Y());
179 Float_t newdirection = ref->X()*ref->Px()+ref->Y()*ref->Py(); //inside or outside
180 if (iref==0) direction = newdirection;
181 if ( newdirection*direction<0){
183 direction = newdirection;
191 if (fTRdecay.GetTrack()>0){
192 fDecayCoord[0] = fTRdecay.X();
193 fDecayCoord[1] = fTRdecay.Y();
194 fDecayCoord[2] = fTRdecay.Z();
195 if ( (fTRdecay.R()<250)&&(fTRdecay.R()>85) && (TMath::Abs(fTRdecay.Z())<250) ){
206 //digits information update
207 fRowsWithDigits = fTPCRow.RowsOn();
208 fRowsWithDigitsInn = fTPCRow.RowsOn(63); // 63 = number of inner rows
209 fRowsTrackLength = fTPCRow.Last() - fTPCRow.First();
212 // calculate primary ionization per cm
213 if (fParticle.GetPDG()){
214 fMass = fParticle.GetMass();
215 fCharge = fParticle.GetPDG()->Charge();
216 if (fTPCReferences->GetEntriesFast()>0){
217 fTrackRef = *((AliTrackReference*)fTPCReferences->At(0));
220 Float_t p = TMath::Sqrt(fTrackRef.Px()*fTrackRef.Px()+
221 fTrackRef.Py()*fTrackRef.Py()+
222 fTrackRef.Pz()*fTrackRef.Pz());
224 Float_t betagama = p /fMass;
225 fPrim = TPCBetheBloch(betagama);
234 /////////////////////////////////////////////////////////////////////////////////
235 AliGenV0Info::AliGenV0Info():
236 fMCd(), //info about daughter particle -
237 fMCm(), //info about mother particle - first particle for V0
238 fMotherP(), //particle info about mother particle
239 fMCDist1(0), //info about closest distance according closest MC - linear DCA
240 fMCDist2(0), //info about closest distance parabolic DCA
241 fMCRr(0), // rec position of the vertex
242 fMCR(0), //exact r position of the vertex
243 fInvMass(0), //reconstructed invariant mass -
244 fPointAngleFi(0), //point angle fi
245 fPointAngleTh(0), //point angle theta
246 fPointAngle(0) //point angle full
248 for (Int_t i=0;i<3; i++){
257 for (Int_t i=0; i<2;i++){
263 void AliGenV0Info::Update(Float_t vertex[3])
266 // Update information - calculates derived variables
269 fMCPd[0] = fMCd.GetParticle().Px();
270 fMCPd[1] = fMCd.GetParticle().Py();
271 fMCPd[2] = fMCd.GetParticle().Pz();
272 fMCPd[3] = fMCd.GetParticle().P();
274 fMCX[0] = fMCd.GetParticle().Vx();
275 fMCX[1] = fMCd.GetParticle().Vy();
276 fMCX[2] = fMCd.GetParticle().Vz();
277 fMCR = TMath::Sqrt( fMCX[0]*fMCX[0]+fMCX[1]*fMCX[1]);
279 fPdg[0] = fMCd.GetParticle().GetPdgCode();
280 fPdg[1] = fMCm.GetParticle().GetPdgCode();
282 fLab[0] = fMCd.GetParticle().GetUniqueID();
283 fLab[1] = fMCm.GetParticle().GetUniqueID();
287 Double_t x1[3],p1[3];
288 TParticle& pdaughter = fMCd.GetParticle();
289 x1[0] = pdaughter.Vx();
290 x1[1] = pdaughter.Vy();
291 x1[2] = pdaughter.Vz();
292 p1[0] = pdaughter.Px();
293 p1[1] = pdaughter.Py();
294 p1[2] = pdaughter.Pz();
295 Double_t sign = (pdaughter.GetPDG()->Charge()>0)? -1:1;
296 AliHelix dhelix1(x1,p1,sign);
299 Double_t x2[3],p2[3];
301 TParticle& pmother = fMCm.GetParticle();
302 x2[0] = pmother.Vx();
303 x2[1] = pmother.Vy();
304 x2[2] = pmother.Vz();
305 p2[0] = pmother.Px();
306 p2[1] = pmother.Py();
307 p2[2] = pmother.Pz();
310 sign = (pmother.GetPDG()->Charge()>0) ? -1:1;
311 AliHelix mhelix(x2,p2,sign);
316 //find intersection linear
318 Double_t distance1, distance2;
319 Double_t phase[2][2],radius[2];
320 Int_t points = dhelix1.GetRPHIintersections(mhelix, phase, radius);
321 Double_t delta1=10000,delta2=10000;
323 dhelix1.LinearDCA(mhelix,phase[0][0],phase[0][1],radius[0],delta1);
324 dhelix1.LinearDCA(mhelix,phase[0][0],phase[0][1],radius[0],delta1);
325 dhelix1.LinearDCA(mhelix,phase[0][0],phase[0][1],radius[0],delta1);
332 dhelix1.LinearDCA(mhelix,phase[1][0],phase[1][1],radius[1],delta2);
333 dhelix1.LinearDCA(mhelix,phase[1][0],phase[1][1],radius[1],delta2);
334 dhelix1.LinearDCA(mhelix,phase[1][0],phase[1][1],radius[1],delta2);
336 distance1 = TMath::Min(delta1,delta2);
338 //find intersection parabolic
340 points = dhelix1.GetRPHIintersections(mhelix, phase, radius);
341 delta1=10000,delta2=10000;
344 dhelix1.ParabolicDCA(mhelix,phase[0][0],phase[0][1],radius[0],delta1);
347 dhelix1.ParabolicDCA(mhelix,phase[1][0],phase[1][1],radius[1],delta2);
350 distance2 = TMath::Min(delta1,delta2);
354 dhelix1.Evaluate(phase[0][0],fMCXr);
355 dhelix1.GetMomentum(phase[0][0],fMCPdr);
356 mhelix.GetMomentum(phase[0][1],fMCPm);
357 dhelix1.GetAngle(phase[0][0],mhelix,phase[0][1],fMCAngle);
358 fMCRr = TMath::Sqrt(radius[0]);
361 dhelix1.Evaluate(phase[1][0],fMCXr);
362 dhelix1.GetMomentum(phase[1][0],fMCPdr);
363 mhelix.GetMomentum(phase[1][1],fMCPm);
364 dhelix1.GetAngle(phase[1][0],mhelix,phase[1][1],fMCAngle);
365 fMCRr = TMath::Sqrt(radius[1]);
369 fMCDist1 = TMath::Sqrt(distance1);
370 fMCDist2 = TMath::Sqrt(distance2);
374 Float_t v[3] = {fMCXr[0]-vertex[0],fMCXr[1]-vertex[1],fMCXr[2]-vertex[2]};
375 //Float_t v[3] = {fMCXr[0],fMCXr[1],fMCXr[2]};
376 Float_t p[3] = {fMCPdr[0]+fMCPm[0], fMCPdr[1]+fMCPm[1],fMCPdr[2]+fMCPm[2]};
377 Float_t vnorm2 = v[0]*v[0]+v[1]*v[1];
378 Float_t vnorm3 = TMath::Sqrt(v[2]*v[2]+vnorm2);
379 vnorm2 = TMath::Sqrt(vnorm2);
380 Float_t pnorm2 = p[0]*p[0]+p[1]*p[1];
381 Float_t pnorm3 = TMath::Sqrt(p[2]*p[2]+pnorm2);
382 pnorm2 = TMath::Sqrt(pnorm2);
384 fPointAngleFi = (v[0]*p[0]+v[1]*p[1])/(vnorm2*pnorm2);
385 fPointAngleTh = (v[2]*p[2]+vnorm2*pnorm2)/(vnorm3*pnorm3);
386 fPointAngle = (v[0]*p[0]+v[1]*p[1]+v[2]*p[2])/(vnorm3*pnorm3);
387 Double_t mass1 = fMCd.GetMass();
388 Double_t mass2 = fMCm.GetMass();
391 Double_t e1 = TMath::Sqrt(mass1*mass1+
395 Double_t e2 = TMath::Sqrt(mass2*mass2+
401 (fMCPm[0]+fMCPd[0])*(fMCPm[0]+fMCPd[0])+
402 (fMCPm[1]+fMCPd[1])*(fMCPm[1]+fMCPd[1])+
403 (fMCPm[2]+fMCPd[2])*(fMCPm[2]+fMCPd[2]);
405 // fInvMass = TMath::Sqrt((e1+e2)*(e1+e2)-fInvMass);
406 fInvMass = (e1+e2)*(e1+e2)-fInvMass;
407 if (fInvMass>0) fInvMass = TMath::Sqrt(fInvMass);
412 /////////////////////////////////////////////////////////////////////////////////
414 AliGenKinkInfo::AliGenKinkInfo():
415 fMCd(), //info about daughter particle - second particle for V0
416 fMCm(), //info about mother particle - first particle for V0
417 fMCDist1(0), //info about closest distance according closest MC - linear DCA
418 fMCDist2(0), //info about closest distance parabolic DCA
419 fMCRr(0), // rec position of the vertex
420 fMCR(0) //exact r position of the vertex
423 // default constructor
425 for (Int_t i=0;i<3;i++){
432 for (Int_t i=0; i<2; i++) {
438 void AliGenKinkInfo::Update()
441 // Update information
442 // some redundancy - faster acces to the values in analysis code
444 fMCPd[0] = fMCd.GetParticle().Px();
445 fMCPd[1] = fMCd.GetParticle().Py();
446 fMCPd[2] = fMCd.GetParticle().Pz();
447 fMCPd[3] = fMCd.GetParticle().P();
449 fMCX[0] = fMCd.GetParticle().Vx();
450 fMCX[1] = fMCd.GetParticle().Vy();
451 fMCX[2] = fMCd.GetParticle().Vz();
452 fMCR = TMath::Sqrt( fMCX[0]*fMCX[0]+fMCX[1]*fMCX[1]);
454 fPdg[0] = fMCd.GetParticle().GetPdgCode();
455 fPdg[1] = fMCm.GetParticle().GetPdgCode();
457 fLab[0] = fMCd.GetParticle().GetUniqueID();
458 fLab[1] = fMCm.GetParticle().GetUniqueID();
462 Double_t x1[3],p1[3];
463 TParticle& pdaughter = fMCd.GetParticle();
464 x1[0] = pdaughter.Vx();
465 x1[1] = pdaughter.Vy();
466 x1[2] = pdaughter.Vz();
467 p1[0] = pdaughter.Px();
468 p1[1] = pdaughter.Py();
469 p1[2] = pdaughter.Pz();
470 Double_t sign = (pdaughter.GetPDG()->Charge()>0)? -1:1;
471 AliHelix dhelix1(x1,p1,sign);
474 Double_t x2[3],p2[3];
476 TParticle& pmother = fMCm.GetParticle();
477 x2[0] = pmother.Vx();
478 x2[1] = pmother.Vy();
479 x2[2] = pmother.Vz();
480 p2[0] = pmother.Px();
481 p2[1] = pmother.Py();
482 p2[2] = pmother.Pz();
484 const AliTrackReference & pdecay = fMCm.GetTRdecay();
492 sign = (pmother.GetPDG()->Charge()>0) ? -1:1;
493 AliHelix mhelix(x2,p2,sign);
498 //find intersection linear
500 Double_t distance1, distance2;
501 Double_t phase[2][2],radius[2];
502 Int_t points = dhelix1.GetRPHIintersections(mhelix, phase, radius);
503 Double_t delta1=10000,delta2=10000;
505 dhelix1.LinearDCA(mhelix,phase[0][0],phase[0][1],radius[0],delta1);
506 dhelix1.LinearDCA(mhelix,phase[0][0],phase[0][1],radius[0],delta1);
507 dhelix1.LinearDCA(mhelix,phase[0][0],phase[0][1],radius[0],delta1);
510 dhelix1.LinearDCA(mhelix,phase[1][0],phase[1][1],radius[1],delta2);
511 dhelix1.LinearDCA(mhelix,phase[1][0],phase[1][1],radius[1],delta2);
512 dhelix1.LinearDCA(mhelix,phase[1][0],phase[1][1],radius[1],delta2);
514 distance1 = TMath::Min(delta1,delta2);
516 //find intersection parabolic
518 points = dhelix1.GetRPHIintersections(mhelix, phase, radius);
519 delta1=10000,delta2=10000;
522 dhelix1.ParabolicDCA(mhelix,phase[0][0],phase[0][1],radius[0],delta1);
525 dhelix1.ParabolicDCA(mhelix,phase[1][0],phase[1][1],radius[1],delta2);
528 distance2 = TMath::Min(delta1,delta2);
532 dhelix1.Evaluate(phase[0][0],fMCXr);
533 dhelix1.GetMomentum(phase[0][0],fMCPdr);
534 mhelix.GetMomentum(phase[0][1],fMCPm);
535 dhelix1.GetAngle(phase[0][0],mhelix,phase[0][1],fMCAngle);
536 fMCRr = TMath::Sqrt(radius[0]);
539 dhelix1.Evaluate(phase[1][0],fMCXr);
540 dhelix1.GetMomentum(phase[1][0],fMCPdr);
541 mhelix.GetMomentum(phase[1][1],fMCPm);
542 dhelix1.GetAngle(phase[1][0],mhelix,phase[1][1],fMCAngle);
543 fMCRr = TMath::Sqrt(radius[1]);
547 fMCDist1 = TMath::Sqrt(distance1);
548 fMCDist2 = TMath::Sqrt(distance2);
553 Float_t AliGenKinkInfo::GetQt(){
556 Float_t momentumd = TMath::Sqrt(fMCPd[0]*fMCPd[0]+fMCPd[1]*fMCPd[1]+fMCPd[2]*fMCPd[2]);
557 return TMath::Sin(fMCAngle[2])*momentumd;
563 ////////////////////////////////////////////////////////////////////////
564 AliTPCdigitRow::AliTPCdigitRow()
568 ////////////////////////////////////////////////////////////////////////
569 AliTPCdigitRow & AliTPCdigitRow::operator=(const AliTPCdigitRow &digOld)
571 for (Int_t i = 0; i<kgRowBytes; i++) fDig[i] = digOld.fDig[i];
574 ////////////////////////////////////////////////////////////////////////
575 void AliTPCdigitRow::SetRow(Int_t row)
577 if (row >= 8*kgRowBytes) {
578 cerr<<"AliTPCdigitRow::SetRow: index "<<row<<" out of bounds."<<endl;
586 ////////////////////////////////////////////////////////////////////////
587 Bool_t AliTPCdigitRow::TestRow(Int_t row) const
590 // return kTRUE if row is on
594 return TESTBIT(fDig[iC],iB);
596 ////////////////////////////////////////////////////////////////////////
597 Int_t AliTPCdigitRow::RowsOn(Int_t upto) const
600 // returns number of rows with a digit
601 // count only rows less equal row number upto
604 for (Int_t i = 0; i<kgRowBytes; i++) {
605 for (Int_t j = 0; j < 8; j++) {
606 if (i*8+j > upto) return total;
607 if (TESTBIT(fDig[i],j)) total++;
612 ////////////////////////////////////////////////////////////////////////
613 void AliTPCdigitRow::Reset()
616 // resets all rows to zero
618 for (Int_t i = 0; i<kgRowBytes; i++) {
622 ////////////////////////////////////////////////////////////////////////
623 Int_t AliTPCdigitRow::Last() const
626 // returns the last row number with a digit
627 // returns -1 if now digits
629 for (Int_t i = kgRowBytes-1; i>=0; i--) {
630 for (Int_t j = 7; j >= 0; j--) {
631 if TESTBIT(fDig[i],j) return i*8+j;
636 ////////////////////////////////////////////////////////////////////////
637 Int_t AliTPCdigitRow::First() const
640 // returns the first row number with a digit
641 // returns -1 if now digits
643 for (Int_t i = 0; i<kgRowBytes; i++) {
644 for (Int_t j = 0; j < 8; j++) {
645 if (TESTBIT(fDig[i],j)) return i*8+j;
652 //_____________________________________________________________________________
653 Float_t AliMCInfo::TPCBetheBloch(Float_t bg)
656 // Bethe-Bloch energy loss formula
658 const Double_t kp1=0.76176e-1;
659 const Double_t kp2=10.632;
660 const Double_t kp3=0.13279e-4;
661 const Double_t kp4=1.8631;
662 const Double_t kp5=1.9479;
664 Double_t dbg = (Double_t) bg;
666 Double_t beta = dbg/TMath::Sqrt(1.+dbg*dbg);
668 Double_t aa = TMath::Power(beta,kp4);
669 Double_t bb = TMath::Power(1./dbg,kp5);
671 bb=TMath::Log(kp3+bb);
673 return ((Float_t)((kp2-aa-bb)*kp1/aa));