1 ////////////////////////////////////////////////////////////////////////////////
3 // AliFemtoEventReaderESDChainKine - the reader class for the Alice ESD and //
4 // the model Kinematics information tailored for the Task framework and the //
5 // Reads in AliESDfriend to create shared hit/quality information //
6 // Authors: Adam Kisiel kisiel@mps.ohio-state.edu //
8 ////////////////////////////////////////////////////////////////////////////////
9 #include "AliFemtoEventReaderESDChainKine.h"
14 #include "AliESDEvent.h"
15 #include "AliESDtrack.h"
16 #include "AliESDVertex.h"
18 #include "AliFmPhysicalHelixD.h"
19 #include "AliFmThreeVectorF.h"
21 #include "SystemOfUnits.h"
23 #include "AliFemtoEvent.h"
25 #include "TParticle.h"
26 #include "AliFemtoModelHiddenInfo.h"
27 #include "AliFemtoModelGlobalHiddenInfo.h"
28 #include "AliGenHijingEventHeader.h"
29 #include "AliGenCocktailEventHeader.h"
31 #include "AliVertexerTracks.h"
33 ClassImp(AliFemtoEventReaderESDChainKine)
35 #if !(ST_NO_NAMESPACES)
36 using namespace units;
40 //____________________________
41 AliFemtoEventReaderESDChainKine::AliFemtoEventReaderESDChainKine():
51 fRotateToEventPlane(0)
53 //constructor with 0 parameters , look at default settings
57 AliFemtoEventReaderESDChainKine::AliFemtoEventReaderESDChainKine(const AliFemtoEventReaderESDChainKine& aReader):
58 AliFemtoEventReader(aReader),
68 fRotateToEventPlane(0)
71 fConstrained = aReader.fConstrained;
72 fUseTPCOnly = aReader.fUseTPCOnly;
73 fNumberofEvent = aReader.fNumberofEvent;
74 fCurEvent = aReader.fCurEvent;
75 fCurFile = aReader.fCurFile;
76 fEvent = new AliESDEvent();
77 fStack = aReader.fStack;
78 fRotateToEventPlane = aReader.fRotateToEventPlane;
81 AliFemtoEventReaderESDChainKine::~AliFemtoEventReaderESDChainKine()
88 AliFemtoEventReaderESDChainKine& AliFemtoEventReaderESDChainKine::operator=(const AliFemtoEventReaderESDChainKine& aReader)
90 // Assignment operator
94 fConstrained = aReader.fConstrained;
95 fUseTPCOnly = aReader.fUseTPCOnly;
96 fNumberofEvent = aReader.fNumberofEvent;
97 fCurEvent = aReader.fCurEvent;
98 fCurFile = aReader.fCurFile;
99 if (fEvent) delete fEvent;
100 fEvent = new AliESDEvent();
101 fStack = aReader.fStack;
102 fGenHeader = aReader.fGenHeader;
103 fRotateToEventPlane = aReader.fRotateToEventPlane;
108 AliFemtoString AliFemtoEventReaderESDChainKine::Report()
110 AliFemtoString temp = "\n This is the AliFemtoEventReaderESDChainKine\n";
115 void AliFemtoEventReaderESDChainKine::SetConstrained(const bool constrained)
117 // Select whether to read constrained or not constrained momentum
118 fConstrained=constrained;
121 bool AliFemtoEventReaderESDChainKine::GetConstrained() const
123 // Check whether we read constrained or not constrained momentum
127 AliFemtoEvent* AliFemtoEventReaderESDChainKine::ReturnHbtEvent()
129 // Get the event, read all the relevant information
130 // and fill the AliFemtoEvent class
131 // Returns a valid AliFemtoEvent
132 AliFemtoEvent *hbtEvent = 0;
133 string tFriendFileName;
135 // Get the friend information
136 cout << "AliFemtoEventReaderESDChainKine::Starting to read event: "<<fCurEvent<<endl;
137 // fEvent->SetESDfriend(fEventFriend);
139 hbtEvent = new AliFemtoEvent;
140 //setting basic things
141 // hbtEvent->SetEventNumber(fEvent->GetEventNumber());
142 hbtEvent->SetRunNumber(fEvent->GetRunNumber());
143 //hbtEvent->SetNumberOfTracks(fEvent->GetNumberOfTracks());
144 hbtEvent->SetMagneticField(fEvent->GetMagneticField()*kilogauss);//to check if here is ok
145 hbtEvent->SetZDCN1Energy(fEvent->GetZDCN1Energy());
146 hbtEvent->SetZDCP1Energy(fEvent->GetZDCP1Energy());
147 hbtEvent->SetZDCN2Energy(fEvent->GetZDCN2Energy());
148 hbtEvent->SetZDCP2Energy(fEvent->GetZDCP2Energy());
149 hbtEvent->SetZDCEMEnergy(fEvent->GetZDCEMEnergy());
150 hbtEvent->SetZDCParticipants(fEvent->GetZDCParticipants());
151 hbtEvent->SetTriggerMask(fEvent->GetTriggerMask());
152 hbtEvent->SetTriggerCluster(fEvent->GetTriggerCluster());
158 fEvent->GetPrimaryVertexTPC()->GetXYZ(fV1);
159 fEvent->GetPrimaryVertexTPC()->GetCovMatrix(fVCov);
160 if (!fEvent->GetPrimaryVertexTPC()->GetStatus())
164 if (fEvent->GetPrimaryVertex()) {
165 fEvent->GetPrimaryVertex()->GetXYZ(fV1);
166 fEvent->GetPrimaryVertex()->GetCovMatrix(fVCov);
168 if (!fEvent->GetPrimaryVertex()->GetStatus()) {
169 // Get the vertex from SPD
170 fEvent->GetPrimaryVertexSPD()->GetXYZ(fV1);
171 fEvent->GetPrimaryVertexSPD()->GetCovMatrix(fVCov);
174 if (!fEvent->GetPrimaryVertexSPD()->GetStatus())
177 fEvent->GetPrimaryVertexSPD()->GetXYZ(fV1);
178 fEvent->GetPrimaryVertexSPD()->GetCovMatrix(fVCov);
183 if (fEvent->GetPrimaryVertexSPD()) {
184 fEvent->GetPrimaryVertexSPD()->GetXYZ(fV1);
185 fEvent->GetPrimaryVertexSPD()->GetCovMatrix(fVCov);
188 if ((!fEvent->GetPrimaryVertex()) && (!fEvent->GetPrimaryVertexSPD()))
190 cout << "No vertex found !!!" << endl;
198 AliFmThreeVectorF vertex(fV1[0],fV1[1],fV1[2]);
200 hbtEvent->SetPrimVertPos(vertex);
201 hbtEvent->SetPrimVertCov(fVCov);
203 Double_t tReactionPlane = 0;
205 AliGenHijingEventHeader *hdh = dynamic_cast<AliGenHijingEventHeader *> (fGenHeader);
207 AliGenCocktailEventHeader *cdh = dynamic_cast<AliGenCocktailEventHeader *> (fGenHeader);
209 TList *tGenHeaders = cdh->GetHeaders();
210 for (int ihead = 0; ihead<tGenHeaders->GetEntries(); ihead++) {
211 hdh = dynamic_cast<AliGenHijingEventHeader *> (fGenHeader);
219 tReactionPlane = hdh->ReactionPlaneAngle();
220 cout << "Got reaction plane " << tReactionPlane << endl;
223 hbtEvent->SetReactionPlaneAngle(tReactionPlane);
225 //starting to reading tracks
226 int nofTracks=0; //number of reconstructed tracks in event
227 nofTracks=fEvent->GetNumberOfTracks();
228 int realnofTracks=0;//number of track which we use ina analysis
231 motherids = new Int_t[fStack->GetNtrack()];
232 for (int ip=0; ip<fStack->GetNtrack(); ip++) motherids[ip] = 0;
234 // Read in mother ids
235 TParticle *motherpart;
236 for (int ip=0; ip<fStack->GetNtrack(); ip++) {
237 motherpart = fStack->Particle(ip);
238 if (motherpart->GetDaughter(0) > 0)
239 motherids[motherpart->GetDaughter(0)] = ip;
240 if (motherpart->GetDaughter(1) > 0)
241 motherids[motherpart->GetDaughter(1)] = ip;
243 // if (motherpart->GetPdgCode() == 211) {
244 // cout << "Mother " << ip << " has daughters "
245 // << motherpart->GetDaughter(0) << " "
246 // << motherpart->GetDaughter(1) << " "
247 // << motherpart->Vx() << " "
248 // << motherpart->Vy() << " "
249 // << motherpart->Vz() << " "
255 for (int i=0;i<nofTracks;i++)
257 // cout << "Reading track " << i << endl;
258 bool tGoodMomentum=true; //flaga to chcek if we can read momentum of this track
260 AliFemtoTrack* trackCopy = new AliFemtoTrack();
261 const AliESDtrack *esdtrack=fEvent->GetTrack(i);//getting next track
262 // const AliESDfriendTrack *tESDfriendTrack = esdtrack->GetFriendTrack();
264 trackCopy->SetCharge((short)esdtrack->GetSign());
266 //in aliroot we have AliPID
267 //0-electron 1-muon 2-pion 3-kaon 4-proton 5-photon 6-pi0 7-neutron 8-kaon0 9-eleCon
268 //we use only 5 first
270 esdtrack->GetESDpid(esdpid);
271 trackCopy->SetPidProbElectron(esdpid[0]);
272 trackCopy->SetPidProbMuon(esdpid[1]);
273 trackCopy->SetPidProbPion(esdpid[2]);
274 trackCopy->SetPidProbKaon(esdpid[3]);
275 trackCopy->SetPidProbProton(esdpid[4]);
283 if (!esdtrack->GetTPCInnerParam()) {
284 cout << "No TPC inner param !" << endl;
289 AliExternalTrackParam *param = new AliExternalTrackParam(*esdtrack->GetTPCInnerParam());
291 param->PropagateToDCA(fEvent->GetPrimaryVertexTPC(), (fEvent->GetMagneticField()), 10000, impact, covimpact);
292 param->GetPxPyPz(pxyz);//reading noconstarined momentum
294 if (fRotateToEventPlane) {
295 double tPhi = TMath::ATan2(pxyz[1], pxyz[0]);
296 double tRad = TMath::Hypot(pxyz[0], pxyz[1]);
298 pxyz[0] = tRad*TMath::Cos(tPhi - tReactionPlane);
299 pxyz[1] = tRad*TMath::Sin(tPhi - tReactionPlane);
302 AliFemtoThreeVector v(pxyz[0],pxyz[1],pxyz[2]);
303 if (v.mag() < 0.0001) {
304 // cout << "Found 0 momentum ???? " << pxyz[0] << " " << pxyz[1] << " " << pxyz[2] << endl;
309 trackCopy->SetP(v);//setting momentum
310 trackCopy->SetPt(sqrt(pxyz[0]*pxyz[0]+pxyz[1]*pxyz[1]));
312 const AliFmThreeVectorD kP(pxyz[0],pxyz[1],pxyz[2]);
313 const AliFmThreeVectorD kOrigin(fV1[0],fV1[1],fV1[2]);
314 //setting helix I do not if it is ok
315 AliFmPhysicalHelixD helix(kP,kOrigin,(double)(fEvent->GetMagneticField())*kilogauss,(double)(trackCopy->Charge()));
316 trackCopy->SetHelix(helix);
318 //some stuff which could be useful
319 trackCopy->SetImpactD(impact[0]);
320 trackCopy->SetImpactZ(impact[1]);
321 trackCopy->SetCdd(covimpact[0]);
322 trackCopy->SetCdz(covimpact[1]);
323 trackCopy->SetCzz(covimpact[2]);
324 trackCopy->SetSigmaToVertex(GetSigmaToVertex(impact, covimpact));
329 if (fConstrained==true)
330 tGoodMomentum=esdtrack->GetConstrainedPxPyPz(pxyz); //reading constrained momentum
332 tGoodMomentum=esdtrack->GetPxPyPz(pxyz);//reading noconstarined momentum
335 if (fRotateToEventPlane) {
336 double tPhi = TMath::ATan2(pxyz[1], pxyz[0]);
337 double tRad = TMath::Hypot(pxyz[0], pxyz[1]);
339 pxyz[0] = tRad*TMath::Cos(tPhi - tReactionPlane);
340 pxyz[1] = tRad*TMath::Sin(tPhi - tReactionPlane);
343 AliFemtoThreeVector v(pxyz[0],pxyz[1],pxyz[2]);
344 if (v.mag() < 0.0001) {
345 // cout << "Found 0 momentum ???? " << pxyz[0] << " " << pxyz[1] << " " << pxyz[2] << endl;
350 trackCopy->SetP(v);//setting momentum
351 trackCopy->SetPt(sqrt(pxyz[0]*pxyz[0]+pxyz[1]*pxyz[1]));
352 const AliFmThreeVectorD kP(pxyz[0],pxyz[1],pxyz[2]);
353 const AliFmThreeVectorD kOrigin(fV1[0],fV1[1],fV1[2]);
354 //setting helix I do not if it is ok
355 AliFmPhysicalHelixD helix(kP,kOrigin,(double)(fEvent->GetMagneticField())*kilogauss,(double)(trackCopy->Charge()));
356 trackCopy->SetHelix(helix);
358 //some stuff which could be useful
361 esdtrack->GetImpactParameters(imp,cim);
365 covimpact[0] = cim[0];
366 covimpact[1] = cim[1];
367 covimpact[2] = cim[2];
369 trackCopy->SetImpactD(impact[0]);
370 trackCopy->SetImpactZ(impact[1]);
371 trackCopy->SetCdd(covimpact[0]);
372 trackCopy->SetCdz(covimpact[1]);
373 trackCopy->SetCzz(covimpact[2]);
374 trackCopy->SetSigmaToVertex(GetSigmaToVertex(impact,covimpact));
377 trackCopy->SetTrackId(esdtrack->GetID());
378 trackCopy->SetFlags(esdtrack->GetStatus());
379 trackCopy->SetLabel(esdtrack->GetLabel());
381 trackCopy->SetITSchi2(esdtrack->GetITSchi2());
382 trackCopy->SetITSncls(esdtrack->GetNcls(0));
383 trackCopy->SetTPCchi2(esdtrack->GetTPCchi2());
384 trackCopy->SetTPCncls(esdtrack->GetTPCNcls());
385 trackCopy->SetTPCnclsF(esdtrack->GetTPCNclsF());
386 trackCopy->SetTPCsignalN((short)esdtrack->GetTPCsignalN()); //due to bug in aliesdtrack class
387 trackCopy->SetTPCsignalS(esdtrack->GetTPCsignalSigma());
390 trackCopy->SetTPCClusterMap(esdtrack->GetTPCClusterMap());
391 trackCopy->SetTPCSharedMap(esdtrack->GetTPCSharedMap());
394 esdtrack->GetInnerXYZ(xtpc);
396 trackCopy->SetNominalTPCEntrancePoint(xtpc);
398 esdtrack->GetOuterXYZ(xtpc);
400 trackCopy->SetNominalTPCExitPoint(xtpc);
403 for (int ik=0; ik<3; ik++) {
404 indexes[ik] = esdtrack->GetKinkIndex(ik);
406 trackCopy->SetKinkIndexes(indexes);
408 // Fill the hidden information with the simulated data
409 if (TMath::Abs(esdtrack->GetLabel()) < fStack->GetNtrack()) {
410 TParticle *tPart = fStack->Particle(TMath::Abs(esdtrack->GetLabel()));
412 // Check the mother information
414 // Using the new way of storing the freeze-out information
415 // Final state particle is stored twice on the stack
416 // one copy (mother) is stored with original freeze-out information
417 // and is not tracked
418 // the other one (daughter) is stored with primary vertex position
421 // Freeze-out coordinates
422 double fpx=0.0, fpy=0.0, fpz=0.0, fpt=0.0;
423 fpx = tPart->Vx() - fV1[0];
424 fpy = tPart->Vy() - fV1[1];
425 fpz = tPart->Vz() - fV1[2];
428 AliFemtoModelGlobalHiddenInfo *tInfo = new AliFemtoModelGlobalHiddenInfo();
429 tInfo->SetGlobalEmissionPoint(fpx, fpy, fpz);
436 // cout << "Looking for mother ids " << endl;
437 if (motherids[TMath::Abs(esdtrack->GetLabel())]>0) {
438 // cout << "Got mother id" << endl;
439 TParticle *mother = fStack->Particle(motherids[TMath::Abs(esdtrack->GetLabel())]);
440 // Check if this is the same particle stored twice on the stack
441 if ((mother->GetPdgCode() == tPart->GetPdgCode() || (mother->Px() == tPart->Px()))) {
442 // It is the same particle
443 // Read in the original freeze-out information
444 // and convert it from to [fm]
447 fpx = mother->Vx()*1e13*0.197327;
448 fpy = mother->Vy()*1e13*0.197327;
449 fpz = mother->Vz()*1e13*0.197327;
450 fpt = mother->T() *1e13*0.197327;
454 // fpx = mother->Vx()*1e13;
455 // fpy = mother->Vy()*1e13;
456 // fpz = mother->Vz()*1e13;
457 // fpt = mother->T() *1e13*3e10;
462 if (fRotateToEventPlane) {
463 double tPhi = TMath::ATan2(fpy, fpx);
464 double tRad = TMath::Hypot(fpx, fpy);
466 fpx = tRad*TMath::Cos(tPhi - tReactionPlane);
467 fpy = tRad*TMath::Sin(tPhi - tReactionPlane);
470 tInfo->SetPDGPid(tPart->GetPdgCode());
472 if (fRotateToEventPlane) {
473 double tPhi = TMath::ATan2(tPart->Py(), tPart->Px());
474 double tRad = TMath::Hypot(tPart->Px(), tPart->Py());
476 tInfo->SetTrueMomentum(tRad*TMath::Cos(tPhi - tReactionPlane),
477 tRad*TMath::Sin(tPhi - tReactionPlane),
481 tInfo->SetTrueMomentum(tPart->Px(), tPart->Py(), tPart->Pz());
482 Double_t mass2 = (tPart->Energy() *tPart->Energy() -
483 tPart->Px()*tPart->Px() -
484 tPart->Py()*tPart->Py() -
485 tPart->Pz()*tPart->Pz());
487 tInfo->SetMass(TMath::Sqrt(mass2));
491 tInfo->SetEmissionPoint(fpx, fpy, fpz, fpt);
492 trackCopy->SetHiddenInfo(tInfo);
495 AliFemtoModelGlobalHiddenInfo *tInfo = new AliFemtoModelGlobalHiddenInfo();
497 double fpx=0.0, fpy=0.0, fpz=0.0, fpt=0.0;
502 tInfo->SetEmissionPoint(fpx, fpy, fpz, fpt);
504 tInfo->SetTrueMomentum(pxyz[0],pxyz[1],pxyz[2]);
506 trackCopy->SetHiddenInfo(tInfo);
508 // cout << "Got freeze-out " << fpx << " " << fpy << " " << fpz << " " << fpt << " " << mass2 << " " << tPart->GetPdgCode() << endl;
510 //decision if we want this track
511 //if we using diffrent labels we want that this label was use for first time
512 //if we use hidden info we want to have match between sim data and ESD
513 if (tGoodMomentum==true)
515 hbtEvent->TrackCollection()->push_back(trackCopy);//adding track to analysis
516 realnofTracks++;//real number of tracks
528 hbtEvent->SetNumberOfTracks(realnofTracks);//setting number of track which we read in event
530 // cout<<"end of reading nt "<<nofTracks<<" real number "<<realnofTracks<<endl;
533 //___________________
534 void AliFemtoEventReaderESDChainKine::SetESDSource(AliESDEvent *aESD)
536 // The chain loads the ESD for us
537 // You must provide the address where it can be found
540 //___________________
541 void AliFemtoEventReaderESDChainKine::SetStackSource(AliStack *aStack)
543 // The chain loads the stack for us
544 // You must provide the address where it can be found
547 //___________________
548 void AliFemtoEventReaderESDChainKine::SetGenEventHeader(AliGenEventHeader *aGenHeader)
550 // The chain loads the generator event header for us
551 // You must provide the address where it can be found
552 fGenHeader = aGenHeader;
556 void AliFemtoEventReaderESDChainKine::SetUseTPCOnly(const bool usetpconly)
558 fUseTPCOnly=usetpconly;
560 void AliFemtoEventReaderESDChainKine::SetRotateToEventPlane(short dorotate)
562 fRotateToEventPlane=dorotate;
565 bool AliFemtoEventReaderESDChainKine::GetUseTPCOnly() const
569 Float_t AliFemtoEventReaderESDChainKine::GetSigmaToVertex(double *impact, double *covar)
571 // Calculates the number of sigma to the vertex.
583 bRes[0] = TMath::Sqrt(bCov[0]);
584 bRes[1] = TMath::Sqrt(bCov[2]);
586 // -----------------------------------
587 // How to get to a n-sigma cut?
589 // The accumulated statistics from 0 to d is
591 // -> Erf(d/Sqrt(2)) for a 1-dim gauss (d = n_sigma)
592 // -> 1 - Exp(-d**2) for a 2-dim gauss (d*d = dx*dx + dy*dy != n_sigma)
594 // It means that for a 2-dim gauss: n_sigma(d) = Sqrt(2)*ErfInv(1 - Exp((-x**2)/2)
595 // Can this be expressed in a different way?
597 if (bRes[0] == 0 || bRes[1] ==0)
600 Float_t d = TMath::Sqrt(TMath::Power(b[0]/bRes[0],2) + TMath::Power(b[1]/bRes[1],2));
602 // stupid rounding problem screws up everything:
603 // if d is too big, TMath::Exp(...) gets 0, and TMath::ErfInverse(1) that should be infinite, gets 0 :(
604 if (TMath::Exp(-d * d / 2) < 1e-10)
607 d = TMath::ErfInverse(1 - TMath::Exp(-d * d / 2)) * TMath::Sqrt(2);