1 #if !defined(__CINT__) || defined(__MAKECINT__)
8 #include "AliAODEvent.h"
9 #include "AliAODHeader.h"
10 #include "AliAODVertex.h"
11 #include "AliAODTrack.h"
12 #include "AliAODCluster.h"
15 #include "AliESDtrack.h"
16 #include "AliESDVertex.h"
18 #include "AliESDcascade.h"
19 #include "AliESDCaloCluster.h"
23 void CreateAODfromESD(const char *inFileName = "AliESDs.root",
24 const char *outFileName = "AliAOD.root") {
26 // create an AliAOD object
27 AliAODEvent *aod = new AliAODEvent();
28 aod->CreateStdContent();
31 TFile *outFile = TFile::Open(outFileName, "RECREATE");
34 TTree *aodTree = new TTree("AOD", "AliAOD tree");
35 aodTree->Branch(aod->GetList());
38 TFile *inFile = TFile::Open(inFileName, "READ");
39 TTree *t = (TTree*) inFile->Get("esdTree");
40 TBranch *b = t->GetBranch("ESD");
44 Int_t nEvents = b->GetEntries();
46 // loop over events and fill them
47 for (Int_t iEvent = 0; iEvent < nEvents; ++iEvent) {
50 // Multiplicity information needed by the header (to be revised!)
51 Int_t nTracks = esd->GetNumberOfTracks();
53 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack)
54 if (esd->GetTrack(iTrack)->GetSign()> 0) nPosTracks++;
57 aod->AddHeader(new AliAODHeader(esd->GetRunNumber(),
58 esd->GetBunchCrossNumber(),
59 esd->GetOrbitNumber(),
63 esd->GetMagneticField(),
64 -999., // fill muon magnetic field
65 -999., // centrality; to be filled, still
66 esd->GetZDCN1Energy(),
67 esd->GetZDCP1Energy(),
68 esd->GetZDCN2Energy(),
69 esd->GetZDCP2Energy(),
70 esd->GetZDCEMEnergy(),
71 esd->GetTriggerMask(),
72 esd->GetTriggerCluster(),
73 esd->GetEventType()));
75 Int_t nV0s = esd->GetNumberOfV0s();
76 Int_t nCascades = esd->GetNumberOfCascades();
77 Int_t nKinks = esd->GetNumberOfKinks();
78 Int_t nVertices = nV0s + nCascades + nKinks;
80 aod->ResetStd(nTracks, nVertices);
83 // Array to take into account the tracks already added to the AOD
84 Bool_t * usedTrack = NULL;
86 usedTrack = new Bool_t[nTracks];
87 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
89 // Array to take into account the V0s already added to the AOD
90 Bool_t * usedV0 = NULL;
92 usedV0 = new Bool_t[nV0s];
93 for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
95 // Array to take into account the kinks already added to the AOD
96 Bool_t * usedKink = NULL;
98 usedKink = new Bool_t[nKinks];
99 for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
102 // Access to the AOD container of vertices
103 TClonesArray &vertices = *(aod->GetVertices());
106 // Access to the AOD container of tracks
107 TClonesArray &tracks = *(aod->GetTracks());
110 // Add primary vertex. The primary tracks will be defined
111 // after the loops on the composite objects (V0, cascades, kinks)
112 const AliESDVertex *vtx = esd->GetPrimaryVertex();
115 vtx->GetXYZ(pos); // position
116 Double_t covVtx[6]; // We have to give changing names to the variables (like cov?, x?, and p?) because CINT doesn't recognize blocks correctly.
117 vtx->GetCovMatrix(covVtx); //covariance matrix
119 AliAODVertex * primary = new(vertices[jVertices++])
120 AliAODVertex(pos, covVtx, vtx->GetChi2(), NULL, AliAODVertex::kPrimary);
122 // Create vertices starting from the most complex objects
125 for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
126 AliESDcascade *cascade = esd->GetCascade(nCascade);
129 cascade->GetXYZ(posXi[0], posXi[1], posXi[2]);
131 cascade->GetPosCovXi(covXi);
133 // Add the cascade vertex
134 AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(posXi,
136 cascade->GetChi2Xi(),
138 AliAODVertex::kCascade);
140 primary->AddDaughter(vcascade);
142 // Add the V0 from the cascade. The ESD class have to be optimized...
143 // Now we have to search for the corresponding Vo in the list of V0s
144 // using the indeces of the positive and negative tracks
146 Int_t posFromV0 = cascade->GetPindex();
147 Int_t negFromV0 = cascade->GetNindex();
153 for (Int_t iV0=0; iV0<nV0s; ++iV0) {
155 v0 = esd->GetV0(iV0);
156 Int_t posV0 = v0->GetPindex();
157 Int_t negV0 = v0->GetNindex();
159 if (posV0==posFromV0 && negV0==negFromV0) {
165 AliAODVertex * vV0FromCascade = 0x0;
167 if (indV0>-1 && !usedV0[indV0] ) {
169 // the V0 exists in the array of V0s and is not used
171 usedV0[indV0] = kTRUE;
174 v0->GetXYZ(posV0[0], posV0[1], posV0[2]);
176 v0->GetPosCov(covV0_1);
178 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(posV0,
185 // the V0 doesn't exist in the array of V0s or was used
186 cerr << "Error: event " << iEvent << " cascade " << nCascade
187 << " The V0 " << indV0
188 << " doesn't exist in the array of V0s or was used!" << endl;
191 cascade->GetXYZ(posV0_2[0], posV0_2[1], posV0_2[2]);
193 cascade->GetPosCov(covV0_2);
195 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(posV0_2,
200 vcascade->AddDaughter(vV0FromCascade);
203 // Add the positive tracks from the V0
205 if (! usedTrack[posFromV0]) {
207 usedTrack[posFromV0] = kTRUE;
209 AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
212 esdTrack->GetPxPyPz(p1);
215 esdTrack->GetXYZ(x1);
217 Double_t covV0PosTr[21];
218 esdTrack->GetCovarianceXYZPxPyPz(covV0PosTr);
221 esdTrack->GetESDpid(pid1);
223 vV0FromCascade->AddDaughter(
224 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
225 esdTrack->GetLabel(),
231 (Short_t)esdTrack->GetSign(),
232 esdTrack->GetITSClusterMap(),
235 kFALSE, // check if this is right
236 AliAODTrack::kSecondary)
240 cerr << "Error: event " << iEvent << " cascade " << nCascade
241 << " track " << posFromV0 << " has already been used!" << endl;
244 // Add the negative tracks from the V0
246 if (!usedTrack[negFromV0]) {
248 usedTrack[negFromV0] = kTRUE;
250 AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
253 esdTrack->GetPxPyPz(p2);
256 esdTrack->GetXYZ(x2);
258 Double_t covV0NegTr[21];
259 esdTrack->GetCovarianceXYZPxPyPz(covV0NegTr);
262 esdTrack->GetESDpid(pid2);
264 vV0FromCascade->AddDaughter(
265 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
266 esdTrack->GetLabel(),
272 (Short_t)esdTrack->GetSign(),
273 esdTrack->GetITSClusterMap(),
276 kFALSE, // check if this is right
277 AliAODTrack::kSecondary)
281 cerr << "Error: event " << iEvent << " cascade " << nCascade
282 << " track " << negFromV0 << " has already been used!" << endl;
285 // Add the bachelor track from the cascade
287 Int_t bachelor = cascade->GetBindex();
289 if(!usedTrack[bachelor]) {
291 usedTrack[bachelor] = kTRUE;
293 AliESDtrack *esdTrack = esd->GetTrack(bachelor);
296 esdTrack->GetPxPyPz(p3);
299 esdTrack->GetXYZ(x3);
301 Double_t covXiTr[21];
302 esdTrack->GetCovarianceXYZPxPyPz(covXiTr);
305 esdTrack->GetESDpid(pid3);
307 vcascade->AddDaughter(
308 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
309 esdTrack->GetLabel(),
315 (Short_t)esdTrack->GetSign(),
316 esdTrack->GetITSClusterMap(),
319 kFALSE, // check if this is right
320 AliAODTrack::kSecondary)
324 cerr << "Error: event " << iEvent << " cascade " << nCascade
325 << " track " << bachelor << " has already been used!" << endl;
328 // Add the primary track of the cascade (if any)
330 } // end of the loop on cascades
334 for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
336 if (usedV0[nV0]) continue; // skip if aready added to the AOD
338 AliESDv0 *v0 = esd->GetV0(nV0);
341 v0->GetXYZ(posV0_3[0], posV0_3[1], posV0_3[2]);
343 v0->GetPosCov(covV0_3);
346 new(vertices[jVertices++]) AliAODVertex(posV0_3,
351 primary->AddDaughter(vV0);
353 Int_t posFromV0 = v0->GetPindex();
354 Int_t negFromV0 = v0->GetNindex();
356 // Add the positive tracks from the V0
358 if (!usedTrack[posFromV0]) {
360 usedTrack[posFromV0] = kTRUE;
362 AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
365 esdTrack->GetPxPyPz(p4);
368 esdTrack->GetXYZ(x4);
370 Double_t covV0PosTr_2[21];
371 esdTrack->GetCovarianceXYZPxPyPz(covV0PosTr_2);
374 esdTrack->GetESDpid(pid4);
377 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
378 esdTrack->GetLabel(),
384 (Short_t)esdTrack->GetSign(),
385 esdTrack->GetITSClusterMap(),
388 kFALSE, // check if this is right
389 AliAODTrack::kSecondary)
393 cerr << "Error: event " << iEvent << " V0 " << nV0
394 << " track " << posFromV0 << " has already been used!" << endl;
397 // Add the negative tracks from the V0
399 if (!usedTrack[negFromV0]) {
401 usedTrack[negFromV0] = kTRUE;
403 AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
406 esdTrack->GetPxPyPz(p5);
409 esdTrack->GetXYZ(x5);
411 Double_t covV0NegTr_2[21];
412 esdTrack->GetCovarianceXYZPxPyPz(covV0NegTr_2);
415 esdTrack->GetESDpid(pid5);
418 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
419 esdTrack->GetLabel(),
425 (Short_t)esdTrack->GetSign(),
426 esdTrack->GetITSClusterMap(),
429 kFALSE, // check if this is right
430 AliAODTrack::kSecondary)
434 cerr << "Error: event " << iEvent << " V0 " << nV0
435 << " track " << negFromV0 << " has already been used!" << endl;
438 } // end of the loop on V0s
440 // Kinks: it is a big mess the access to the information in the kinks
441 // The loop is on the tracks in order to find the mother and daugther of each kink
444 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
447 AliESDtrack * track = esd->GetTrack(iTrack);
450 Int_t ikink = track->GetKinkIndex(0);
453 // Negative kink index: mother, positive: daughter
455 // Search for the second track of the kink
457 for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
459 AliESDtrack * track1 = esd->GetTrack(jTrack);
461 Int_t jkink = track1->GetKinkIndex(0);
463 if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
465 // The two tracks are from the same kink
467 if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
470 Int_t idaughter = -1;
472 if (ikink<0 && jkink>0) {
477 else if (ikink>0 && jkink<0) {
483 cerr << "Error: Wrong combination of kink indexes: "
484 << ikink << " " << jkink << endl;
488 // Add the mother track
490 AliAODTrack * mother = NULL;
492 if (!usedTrack[imother]) {
494 usedTrack[imother] = kTRUE;
496 AliESDtrack *esdTrack = esd->GetTrack(imother);
499 esdTrack->GetPxPyPz(p6);
502 esdTrack->GetXYZ(x6);
504 Double_t covKinkMother[21];
505 esdTrack->GetCovarianceXYZPxPyPz(covKinkMother);
508 esdTrack->GetESDpid(pid6);
511 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
512 esdTrack->GetLabel(),
518 (Short_t)esdTrack->GetSign(),
519 esdTrack->GetITSClusterMap(),
522 kTRUE, // check if this is right
523 AliAODTrack::kPrimary);
524 primary->AddDaughter(mother);
527 cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
528 << " track " << imother << " has already been used!" << endl;
531 // Add the kink vertex
532 AliESDkink * kink = esd->GetKink(TMath::Abs(ikink)-1);
534 AliAODVertex * vkink =
535 new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
539 AliAODVertex::kKink);
540 // Add the daughter track
542 AliAODTrack * daughter = NULL;
544 if (!usedTrack[idaughter]) {
546 usedTrack[idaughter] = kTRUE;
548 AliESDtrack *esdTrack = esd->GetTrack(idaughter);
551 esdTrack->GetPxPyPz(p7);
554 esdTrack->GetXYZ(x7);
556 Double_t covKinkDaughter[21];
557 esdTrack->GetCovarianceXYZPxPyPz(covKinkDaughter);
560 esdTrack->GetESDpid(pid7);
563 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
564 esdTrack->GetLabel(),
570 (Short_t)esdTrack->GetSign(),
571 esdTrack->GetITSClusterMap(),
574 kTRUE, // check if this is right
575 AliAODTrack::kPrimary);
576 vkink->AddDaughter(daughter);
579 cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
580 << " track " << idaughter << " has already been used!" << endl;
592 // Tracks (primary and orphan)
594 for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
597 if (usedTrack[nTrack]) continue;
599 AliESDtrack *esdTrack = esd->GetTrack(nTrack);
602 esdTrack->GetPxPyPz(p8);
605 esdTrack->GetXYZ(x8);
608 esdTrack->GetCovarianceXYZPxPyPz(covTr);
611 esdTrack->GetESDpid(pid8);
613 Float_t impactXY, impactZ;
615 esdTrack->GetImpactParameters(impactXY,impactZ);
618 // track inside the beam pipe
620 primary->AddDaughter(
621 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
622 esdTrack->GetLabel(),
628 (Short_t)esdTrack->GetSign(),
629 esdTrack->GetITSClusterMap(),
632 kTRUE, // check if this is right
633 AliAODTrack::kPrimary)
637 // outside the beam pipe: orphan track
638 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
639 esdTrack->GetLabel(),
645 (Short_t)esdTrack->GetSign(),
646 esdTrack->GetITSClusterMap(),
649 kFALSE, // check if this is right
650 AliAODTrack::kOrphan);
652 } // end of loop on tracks
655 // Access to the AOD container of clusters
656 TClonesArray &clusters = *(aod->GetClusters());
660 Int_t nClusters = esd->GetNumberOfCaloClusters();
662 for (Int_t iClust=0; iClust<nClusters; ++iClust) {
664 AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
666 Int_t id = cluster->GetID();
668 Float_t energy = cluster->GetClusterEnergy();
670 cluster->GetGlobalPosition(x9);
671 Float_t * covMatrix = NULL;
672 Float_t * pid9 = NULL;
673 AliAODVertex *prodVertex = primary;
674 AliAODTrack *primTrack = NULL;
675 Char_t ttype=AliAODCluster::kUndef;
677 if (cluster->IsPHOS()) ttype=AliAODCluster::kPHOSNeutral;
678 else if (cluster->IsEMCAL()) {
680 if (cluster->GetClusterType() == AliESDCaloCluster::kPseudoCluster)
681 ttype = AliAODCluster::kEMCALPseudoCluster;
683 ttype = AliAODCluster::kEMCALClusterv1;
687 new(clusters[jClusters++]) AliAODCluster(id,
697 } // end of loop on calo clusters
704 // fill the tree for this event
706 } // end of event loop
708 aodTree->GetUserInfo()->Add(aod);
713 // write the tree to the specified file
714 outFile = aodTree->GetCurrentFile();