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 "AliESDMuonTrack.h"
17 #include "AliESDVertex.h"
19 #include "AliESDcascade.h"
20 #include "AliESDCaloCluster.h"
24 void CreateAODfromESD(const char *inFileName = "AliESDs.root",
25 const char *outFileName = "AliAOD.root") {
27 // create an AliAOD object
28 AliAODEvent *aod = new AliAODEvent();
29 aod->CreateStdContent();
32 TFile *outFile = TFile::Open(outFileName, "RECREATE");
35 TTree *aodTree = new TTree("AOD", "AliAOD tree");
36 aodTree->Branch(aod->GetList());
39 TFile *inFile = TFile::Open(inFileName, "READ");
40 TTree *t = (TTree*) inFile->Get("esdTree");
41 TBranch *b = t->GetBranch("ESD");
45 Int_t nEvents = b->GetEntries();
47 // set arrays and pointers
55 // loop over events and fill them
56 for (Int_t iEvent = 0; iEvent < nEvents; ++iEvent) {
59 // Multiplicity information needed by the header (to be revised!)
60 Int_t nTracks = esd->GetNumberOfTracks();
62 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack)
63 if (esd->GetTrack(iTrack)->GetSign()> 0) nPosTracks++;
66 aod->AddHeader(new AliAODHeader(esd->GetRunNumber(),
67 esd->GetBunchCrossNumber(),
68 esd->GetOrbitNumber(),
69 esd->GetPeriodNumber(),
73 esd->GetMagneticField(),
74 -999., // fill muon magnetic field
75 -999., // centrality; to be filled, still
76 esd->GetZDCN1Energy(),
77 esd->GetZDCP1Energy(),
78 esd->GetZDCN2Energy(),
79 esd->GetZDCP2Energy(),
80 esd->GetZDCEMEnergy(),
81 esd->GetTriggerMask(),
82 esd->GetTriggerCluster(),
83 esd->GetEventType()));
85 Int_t nV0s = esd->GetNumberOfV0s();
86 Int_t nCascades = esd->GetNumberOfCascades();
87 Int_t nKinks = esd->GetNumberOfKinks();
88 Int_t nVertices = nV0s + nCascades + nKinks;
90 aod->ResetStd(nTracks, nVertices);
91 AliAODTrack *aodTrack;
94 // Array to take into account the tracks already added to the AOD
95 Bool_t * usedTrack = NULL;
97 usedTrack = new Bool_t[nTracks];
98 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
100 // Array to take into account the V0s already added to the AOD
101 Bool_t * usedV0 = NULL;
103 usedV0 = new Bool_t[nV0s];
104 for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
106 // Array to take into account the kinks already added to the AOD
107 Bool_t * usedKink = NULL;
109 usedKink = new Bool_t[nKinks];
110 for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
113 // Access to the AOD container of vertices
114 TClonesArray &vertices = *(aod->GetVertices());
117 // Access to the AOD container of tracks
118 TClonesArray &tracks = *(aod->GetTracks());
121 // Add primary vertex. The primary tracks will be defined
122 // after the loops on the composite objects (V0, cascades, kinks)
123 const AliESDVertex *vtx = esd->GetPrimaryVertex();
125 vtx->GetXYZ(pos); // position
126 vtx->GetCovMatrix(covVtx); //covariance matrix
128 AliAODVertex * primary = new(vertices[jVertices++])
129 AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, AliAODVertex::kPrimary);
131 // Create vertices starting from the most complex objects
134 for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
135 AliESDcascade *cascade = esd->GetCascade(nCascade);
137 cascade->GetXYZ(pos[0], pos[1], pos[2]);
138 cascade->GetPosCovXi(covVtx);
140 // Add the cascade vertex
141 AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
143 cascade->GetChi2Xi(), // = chi2/NDF since NDF = 2*2-3
145 AliAODVertex::kCascade);
147 primary->AddDaughter(vcascade);
149 // Add the V0 from the cascade. The ESD class have to be optimized...
150 // Now we have to search for the corresponding Vo in the list of V0s
151 // using the indeces of the positive and negative tracks
153 Int_t posFromV0 = cascade->GetPindex();
154 Int_t negFromV0 = cascade->GetNindex();
160 for (Int_t iV0=0; iV0<nV0s; ++iV0) {
162 v0 = esd->GetV0(iV0);
163 Int_t posV0 = v0->GetPindex();
164 Int_t negV0 = v0->GetNindex();
166 if (posV0==posFromV0 && negV0==negFromV0) {
172 AliAODVertex * vV0FromCascade = 0x0;
174 if (indV0>-1 && !usedV0[indV0] ) {
176 // the V0 exists in the array of V0s and is not used
178 usedV0[indV0] = kTRUE;
180 v0->GetXYZ(pos[0], pos[1], pos[2]);
181 v0->GetPosCov(covVtx);
183 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
185 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
190 // the V0 doesn't exist in the array of V0s or was used
191 cerr << "Error: event " << iEvent << " cascade " << nCascade
192 << " The V0 " << indV0
193 << " doesn't exist in the array of V0s or was used!" << endl;
195 cascade->GetXYZ(pos[0], pos[1], pos[2]);
196 cascade->GetPosCov(covVtx);
198 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
200 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
203 vcascade->AddDaughter(vV0FromCascade);
206 // Add the positive tracks from the V0
208 if (! usedTrack[posFromV0]) {
210 usedTrack[posFromV0] = kTRUE;
212 AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
213 esdTrack->GetPxPyPz(p);
214 esdTrack->GetXYZ(pos);
215 esdTrack->GetCovarianceXYZPxPyPz(covTr);
216 esdTrack->GetESDpid(pid);
218 vV0FromCascade->AddDaughter(aodTrack =
219 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
220 esdTrack->GetLabel(),
226 (Short_t)esdTrack->GetSign(),
227 esdTrack->GetITSClusterMap(),
230 kTRUE, // check if this is right
231 kFALSE, // check if this is right
232 AliAODTrack::kSecondary)
234 aodTrack->ConvertAliPIDtoAODPID();
237 cerr << "Error: event " << iEvent << " cascade " << nCascade
238 << " track " << posFromV0 << " has already been used!" << endl;
241 // Add the negative tracks from the V0
243 if (!usedTrack[negFromV0]) {
245 usedTrack[negFromV0] = kTRUE;
247 AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
248 esdTrack->GetPxPyPz(p);
249 esdTrack->GetXYZ(pos);
250 esdTrack->GetCovarianceXYZPxPyPz(covTr);
251 esdTrack->GetESDpid(pid);
253 vV0FromCascade->AddDaughter(aodTrack =
254 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
255 esdTrack->GetLabel(),
261 (Short_t)esdTrack->GetSign(),
262 esdTrack->GetITSClusterMap(),
265 kTRUE, // check if this is right
266 kFALSE, // check if this is right
267 AliAODTrack::kSecondary)
269 aodTrack->ConvertAliPIDtoAODPID();
272 cerr << "Error: event " << iEvent << " cascade " << nCascade
273 << " track " << negFromV0 << " has already been used!" << endl;
276 // Add the bachelor track from the cascade
278 Int_t bachelor = cascade->GetBindex();
280 if(!usedTrack[bachelor]) {
282 usedTrack[bachelor] = kTRUE;
284 AliESDtrack *esdTrack = esd->GetTrack(bachelor);
285 esdTrack->GetPxPyPz(p);
286 esdTrack->GetXYZ(pos);
287 esdTrack->GetCovarianceXYZPxPyPz(covTr);
288 esdTrack->GetESDpid(pid);
290 vcascade->AddDaughter(aodTrack =
291 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
292 esdTrack->GetLabel(),
298 (Short_t)esdTrack->GetSign(),
299 esdTrack->GetITSClusterMap(),
302 kTRUE, // check if this is right
303 kFALSE, // check if this is right
304 AliAODTrack::kSecondary)
306 aodTrack->ConvertAliPIDtoAODPID();
309 cerr << "Error: event " << iEvent << " cascade " << nCascade
310 << " track " << bachelor << " has already been used!" << endl;
313 // Add the primary track of the cascade (if any)
315 } // end of the loop on cascades
319 for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
321 if (usedV0[nV0]) continue; // skip if aready added to the AOD
323 AliESDv0 *v0 = esd->GetV0(nV0);
325 v0->GetXYZ(pos[0], pos[1], pos[2]);
326 v0->GetPosCov(covVtx);
329 new(vertices[jVertices++]) AliAODVertex(pos,
331 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
334 primary->AddDaughter(vV0);
336 Int_t posFromV0 = v0->GetPindex();
337 Int_t negFromV0 = v0->GetNindex();
339 // Add the positive tracks from the V0
341 if (!usedTrack[posFromV0]) {
343 usedTrack[posFromV0] = kTRUE;
345 AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
346 esdTrack->GetPxPyPz(p);
347 esdTrack->GetXYZ(pos);
348 esdTrack->GetCovarianceXYZPxPyPz(covTr);
349 esdTrack->GetESDpid(pid);
351 vV0->AddDaughter(aodTrack =
352 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
353 esdTrack->GetLabel(),
359 (Short_t)esdTrack->GetSign(),
360 esdTrack->GetITSClusterMap(),
363 kTRUE, // check if this is right
364 kFALSE, // check if this is right
365 AliAODTrack::kSecondary)
367 aodTrack->ConvertAliPIDtoAODPID();
370 cerr << "Error: event " << iEvent << " V0 " << nV0
371 << " track " << posFromV0 << " has already been used!" << endl;
374 // Add the negative tracks from the V0
376 if (!usedTrack[negFromV0]) {
378 usedTrack[negFromV0] = kTRUE;
380 AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
381 esdTrack->GetPxPyPz(p);
382 esdTrack->GetXYZ(pos);
383 esdTrack->GetCovarianceXYZPxPyPz(covTr);
384 esdTrack->GetESDpid(pid);
386 vV0->AddDaughter(aodTrack =
387 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
388 esdTrack->GetLabel(),
394 (Short_t)esdTrack->GetSign(),
395 esdTrack->GetITSClusterMap(),
398 kTRUE, // check if this is right
399 kFALSE, // check if this is right
400 AliAODTrack::kSecondary)
402 aodTrack->ConvertAliPIDtoAODPID();
405 cerr << "Error: event " << iEvent << " V0 " << nV0
406 << " track " << negFromV0 << " has already been used!" << endl;
409 } // end of the loop on V0s
411 // Kinks: it is a big mess the access to the information in the kinks
412 // The loop is on the tracks in order to find the mother and daugther of each kink
415 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
418 AliESDtrack * esdTrack = esd->GetTrack(iTrack);
420 Int_t ikink = esdTrack->GetKinkIndex(0);
423 // Negative kink index: mother, positive: daughter
425 // Search for the second track of the kink
427 for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
429 AliESDtrack * esdTrack1 = esd->GetTrack(jTrack);
431 Int_t jkink = esdTrack1->GetKinkIndex(0);
433 if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
435 // The two tracks are from the same kink
437 if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
440 Int_t idaughter = -1;
442 if (ikink<0 && jkink>0) {
447 else if (ikink>0 && jkink<0) {
453 cerr << "Error: Wrong combination of kink indexes: "
454 << ikink << " " << jkink << endl;
458 // Add the mother track
460 AliAODTrack * mother = NULL;
462 if (!usedTrack[imother]) {
464 usedTrack[imother] = kTRUE;
466 AliESDtrack *esdTrack = esd->GetTrack(imother);
467 esdTrack->GetPxPyPz(p);
468 esdTrack->GetXYZ(pos);
469 esdTrack->GetCovarianceXYZPxPyPz(covTr);
470 esdTrack->GetESDpid(pid);
473 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
474 esdTrack->GetLabel(),
480 (Short_t)esdTrack->GetSign(),
481 esdTrack->GetITSClusterMap(),
484 kTRUE, // check if this is right
485 kTRUE, // check if this is right
486 AliAODTrack::kPrimary);
487 primary->AddDaughter(mother);
488 mother->ConvertAliPIDtoAODPID();
491 cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
492 << " track " << imother << " has already been used!" << endl;
495 // Add the kink vertex
496 AliESDkink * kink = esd->GetKink(TMath::Abs(ikink)-1);
498 AliAODVertex * vkink =
499 new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
503 AliAODVertex::kKink);
504 // Add the daughter track
506 AliAODTrack * daughter = NULL;
508 if (!usedTrack[idaughter]) {
510 usedTrack[idaughter] = kTRUE;
512 AliESDtrack *esdTrack = esd->GetTrack(idaughter);
513 esdTrack->GetPxPyPz(p);
514 esdTrack->GetXYZ(pos);
515 esdTrack->GetCovarianceXYZPxPyPz(covTr);
516 esdTrack->GetESDpid(pid);
519 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
520 esdTrack->GetLabel(),
526 (Short_t)esdTrack->GetSign(),
527 esdTrack->GetITSClusterMap(),
530 kTRUE, // check if this is right
531 kTRUE, // check if this is right
532 AliAODTrack::kPrimary);
533 vkink->AddDaughter(daughter);
534 daughter->ConvertAliPIDtoAODPID();
537 cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
538 << " track " << idaughter << " has already been used!" << endl;
550 // Tracks (primary and orphan)
552 for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
555 if (usedTrack[nTrack]) continue;
557 AliESDtrack *esdTrack = esd->GetTrack(nTrack);
558 esdTrack->GetPxPyPz(p);
559 esdTrack->GetXYZ(pos);
560 esdTrack->GetCovarianceXYZPxPyPz(covTr);
561 esdTrack->GetESDpid(pid);
563 Float_t impactXY, impactZ;
565 esdTrack->GetImpactParameters(impactXY,impactZ);
568 // track inside the beam pipe
570 primary->AddDaughter(aodTrack =
571 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
572 esdTrack->GetLabel(),
578 (Short_t)esdTrack->GetSign(),
579 esdTrack->GetITSClusterMap(),
582 kTRUE, // check if this is right
583 kTRUE, // check if this is right
584 AliAODTrack::kPrimary)
586 aodTrack->ConvertAliPIDtoAODPID();
589 // outside the beam pipe: orphan track
591 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
592 esdTrack->GetLabel(),
598 (Short_t)esdTrack->GetSign(),
599 esdTrack->GetITSClusterMap(),
602 kFALSE, // check if this is right
603 kFALSE, // check if this is right
604 AliAODTrack::kOrphan);
605 aodTrack->ConvertAliPIDtoAODPID();
607 } // end of loop on tracks
610 Int_t nMuTracks = esd->GetNumberOfMuonTracks();
611 for (Int_t nMuTrack = 0; nMuTrack < nMuTracks; ++nMuTrack) {
613 AliESDMuonTrack *esdMuTrack = esd->GetMuonTrack(nMuTrack);
614 p[0] = esdMuTrack->Px();
615 p[1] = esdMuTrack->Py();
616 p[2] = esdMuTrack->Pz();
617 pos[0] = primary->GetX();
618 pos[1] = primary->GetY();
619 pos[2] = primary->GetZ();
621 // has to be changed once the muon pid is provided by the ESD
622 for (Int_t i = 0; i < 10; pid[i++] = 0.); pid[AliAODTrack::kMuon]=1.;
624 primary->AddDaughter(
625 new(tracks[jTracks++]) AliAODTrack(0, // no ID provided
626 0, // no label provided
631 NULL, // no covariance matrix provided
632 (Short_t)-99, // no charge provided
633 0, // no ITSClusterMap
636 kTRUE, // check if this is right
637 kTRUE, // not used for vertex fit
638 AliAODTrack::kPrimary)
642 // Access to the AOD container of clusters
643 TClonesArray &clusters = *(aod->GetClusters());
647 Int_t nClusters = esd->GetNumberOfCaloClusters();
649 for (Int_t iClust=0; iClust<nClusters; ++iClust) {
651 AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
653 Int_t id = cluster->GetID();
655 Float_t energy = cluster->GetClusterEnergy();
656 cluster->GetGlobalPosition(posF);
657 AliAODVertex *prodVertex = primary;
658 AliAODTrack *primTrack = NULL;
659 Char_t ttype=AliAODCluster::kUndef;
661 if (cluster->IsPHOS()) ttype=AliAODCluster::kPHOSNeutral;
662 else if (cluster->IsEMCAL()) {
664 if (cluster->GetClusterType() == AliESDCaloCluster::kPseudoCluster)
665 ttype = AliAODCluster::kEMCALPseudoCluster;
667 ttype = AliAODCluster::kEMCALClusterv1;
671 new(clusters[jClusters++]) AliAODCluster(id,
675 NULL, // no covariance matrix provided
676 NULL, // no pid for clusters provided
681 } // end of loop on calo clusters
687 // fill the tree for this event
689 } // end of event loop
691 aodTree->GetUserInfo()->Add(aod);
696 // write the tree to the specified file
697 outFile = aodTree->GetCurrentFile();