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 AliESD *esd = new AliESD();
44 Int_t nEvents = t->GetEntries();
46 // set arrays and pointers
54 // loop over events and fill them
55 for (Int_t iEvent = 0; iEvent < nEvents; ++iEvent) {
58 // Multiplicity information needed by the header (to be revised!)
59 Int_t nTracks = esd->GetNumberOfTracks();
61 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack)
62 if (esd->GetTrack(iTrack)->GetSign()> 0) nPosTracks++;
64 // Access to the header
65 AliAODHeader *header = aod->GetHeader();
68 *header = AliAODHeader(esd->GetRunNumber(),
69 esd->GetBunchCrossNumber(),
70 esd->GetOrbitNumber(),
71 esd->GetPeriodNumber(),
75 esd->GetMagneticField(),
76 -999., // fill muon magnetic field
77 -999., // centrality; to be filled, still
78 esd->GetZDCN1Energy(),
79 esd->GetZDCP1Energy(),
80 esd->GetZDCN2Energy(),
81 esd->GetZDCP2Energy(),
82 esd->GetZDCEMEnergy(),
83 esd->GetTriggerMask(),
84 esd->GetTriggerCluster(),
87 Int_t nV0s = esd->GetNumberOfV0s();
88 Int_t nCascades = esd->GetNumberOfCascades();
89 Int_t nKinks = esd->GetNumberOfKinks();
90 Int_t nVertices = nV0s + nCascades + nKinks;
92 aod->ResetStd(nTracks, nVertices);
93 AliAODTrack *aodTrack;
95 // Array to take into account the tracks already added to the AOD
96 Bool_t * usedTrack = NULL;
98 usedTrack = new Bool_t[nTracks];
99 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
101 // Array to take into account the V0s already added to the AOD
102 Bool_t * usedV0 = NULL;
104 usedV0 = new Bool_t[nV0s];
105 for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
107 // Array to take into account the kinks already added to the AOD
108 Bool_t * usedKink = NULL;
110 usedKink = new Bool_t[nKinks];
111 for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
114 // Access to the AOD container of vertices
115 TClonesArray &vertices = *(aod->GetVertices());
118 // Access to the AOD container of tracks
119 TClonesArray &tracks = *(aod->GetTracks());
122 // Add primary vertex. The primary tracks will be defined
123 // after the loops on the composite objects (V0, cascades, kinks)
124 const AliESDVertex *vtx = esd->GetPrimaryVertex();
126 vtx->GetXYZ(pos); // position
127 vtx->GetCovMatrix(covVtx); //covariance matrix
129 AliAODVertex * primary = new(vertices[jVertices++])
130 AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, AliAODVertex::kPrimary);
132 // Create vertices starting from the most complex objects
135 for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
136 AliESDcascade *cascade = esd->GetCascade(nCascade);
138 cascade->GetXYZ(pos[0], pos[1], pos[2]);
139 cascade->GetPosCovXi(covVtx);
141 // Add the cascade vertex
142 AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
144 cascade->GetChi2Xi(), // = chi2/NDF since NDF = 2*2-3
146 AliAODVertex::kCascade);
148 primary->AddDaughter(vcascade);
150 // Add the V0 from the cascade. The ESD class have to be optimized...
151 // Now we have to search for the corresponding Vo in the list of V0s
152 // using the indeces of the positive and negative tracks
154 Int_t posFromV0 = cascade->GetPindex();
155 Int_t negFromV0 = cascade->GetNindex();
161 for (Int_t iV0=0; iV0<nV0s; ++iV0) {
163 v0 = esd->GetV0(iV0);
164 Int_t posV0 = v0->GetPindex();
165 Int_t negV0 = v0->GetNindex();
167 if (posV0==posFromV0 && negV0==negFromV0) {
173 AliAODVertex * vV0FromCascade = 0x0;
175 if (indV0>-1 && !usedV0[indV0] ) {
177 // the V0 exists in the array of V0s and is not used
179 usedV0[indV0] = kTRUE;
181 v0->GetXYZ(pos[0], pos[1], pos[2]);
182 v0->GetPosCov(covVtx);
184 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
186 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
191 // the V0 doesn't exist in the array of V0s or was used
192 cerr << "Error: event " << iEvent << " cascade " << nCascade
193 << " The V0 " << indV0
194 << " doesn't exist in the array of V0s or was used!" << endl;
196 cascade->GetXYZ(pos[0], pos[1], pos[2]);
197 cascade->GetPosCov(covVtx);
199 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
201 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
204 vcascade->AddDaughter(vV0FromCascade);
207 // Add the positive tracks from the V0
209 if (! usedTrack[posFromV0]) {
211 usedTrack[posFromV0] = kTRUE;
213 AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
214 esdTrack->GetPxPyPz(p);
215 esdTrack->GetXYZ(pos);
216 esdTrack->GetCovarianceXYZPxPyPz(covTr);
217 esdTrack->GetESDpid(pid);
219 vV0FromCascade->AddDaughter(aodTrack =
220 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
221 esdTrack->GetLabel(),
227 (Short_t)esdTrack->GetSign(),
228 esdTrack->GetITSClusterMap(),
231 kTRUE, // check if this is right
232 kFALSE, // check if this is right
233 AliAODTrack::kSecondary)
235 aodTrack->ConvertAliPIDtoAODPID();
238 cerr << "Error: event " << iEvent << " cascade " << nCascade
239 << " track " << posFromV0 << " has already been used!" << endl;
242 // Add the negative tracks from the V0
244 if (!usedTrack[negFromV0]) {
246 usedTrack[negFromV0] = kTRUE;
248 AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
249 esdTrack->GetPxPyPz(p);
250 esdTrack->GetXYZ(pos);
251 esdTrack->GetCovarianceXYZPxPyPz(covTr);
252 esdTrack->GetESDpid(pid);
254 vV0FromCascade->AddDaughter(aodTrack =
255 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
256 esdTrack->GetLabel(),
262 (Short_t)esdTrack->GetSign(),
263 esdTrack->GetITSClusterMap(),
266 kTRUE, // check if this is right
267 kFALSE, // check if this is right
268 AliAODTrack::kSecondary)
270 aodTrack->ConvertAliPIDtoAODPID();
273 cerr << "Error: event " << iEvent << " cascade " << nCascade
274 << " track " << negFromV0 << " has already been used!" << endl;
277 // Add the bachelor track from the cascade
279 Int_t bachelor = cascade->GetBindex();
281 if(!usedTrack[bachelor]) {
283 usedTrack[bachelor] = kTRUE;
285 AliESDtrack *esdTrack = esd->GetTrack(bachelor);
286 esdTrack->GetPxPyPz(p);
287 esdTrack->GetXYZ(pos);
288 esdTrack->GetCovarianceXYZPxPyPz(covTr);
289 esdTrack->GetESDpid(pid);
291 vcascade->AddDaughter(aodTrack =
292 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
293 esdTrack->GetLabel(),
299 (Short_t)esdTrack->GetSign(),
300 esdTrack->GetITSClusterMap(),
303 kTRUE, // check if this is right
304 kFALSE, // check if this is right
305 AliAODTrack::kSecondary)
307 aodTrack->ConvertAliPIDtoAODPID();
310 cerr << "Error: event " << iEvent << " cascade " << nCascade
311 << " track " << bachelor << " has already been used!" << endl;
314 // Add the primary track of the cascade (if any)
316 } // end of the loop on cascades
320 for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
322 if (usedV0[nV0]) continue; // skip if aready added to the AOD
324 AliESDv0 *v0 = esd->GetV0(nV0);
326 v0->GetXYZ(pos[0], pos[1], pos[2]);
327 v0->GetPosCov(covVtx);
330 new(vertices[jVertices++]) AliAODVertex(pos,
332 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
335 primary->AddDaughter(vV0);
337 Int_t posFromV0 = v0->GetPindex();
338 Int_t negFromV0 = v0->GetNindex();
340 // Add the positive tracks from the V0
342 if (!usedTrack[posFromV0]) {
344 usedTrack[posFromV0] = kTRUE;
346 AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
347 esdTrack->GetPxPyPz(p);
348 esdTrack->GetXYZ(pos);
349 esdTrack->GetCovarianceXYZPxPyPz(covTr);
350 esdTrack->GetESDpid(pid);
352 vV0->AddDaughter(aodTrack =
353 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
354 esdTrack->GetLabel(),
360 (Short_t)esdTrack->GetSign(),
361 esdTrack->GetITSClusterMap(),
364 kTRUE, // check if this is right
365 kFALSE, // check if this is right
366 AliAODTrack::kSecondary)
368 aodTrack->ConvertAliPIDtoAODPID();
371 cerr << "Error: event " << iEvent << " V0 " << nV0
372 << " track " << posFromV0 << " has already been used!" << endl;
375 // Add the negative tracks from the V0
377 if (!usedTrack[negFromV0]) {
379 usedTrack[negFromV0] = kTRUE;
381 AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
382 esdTrack->GetPxPyPz(p);
383 esdTrack->GetXYZ(pos);
384 esdTrack->GetCovarianceXYZPxPyPz(covTr);
385 esdTrack->GetESDpid(pid);
387 vV0->AddDaughter(aodTrack =
388 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
389 esdTrack->GetLabel(),
395 (Short_t)esdTrack->GetSign(),
396 esdTrack->GetITSClusterMap(),
399 kTRUE, // check if this is right
400 kFALSE, // check if this is right
401 AliAODTrack::kSecondary)
403 aodTrack->ConvertAliPIDtoAODPID();
406 cerr << "Error: event " << iEvent << " V0 " << nV0
407 << " track " << negFromV0 << " has already been used!" << endl;
410 } // end of the loop on V0s
412 // Kinks: it is a big mess the access to the information in the kinks
413 // The loop is on the tracks in order to find the mother and daugther of each kink
416 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
419 AliESDtrack * esdTrack = esd->GetTrack(iTrack);
421 Int_t ikink = esdTrack->GetKinkIndex(0);
424 // Negative kink index: mother, positive: daughter
426 // Search for the second track of the kink
428 for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
430 AliESDtrack * esdTrack1 = esd->GetTrack(jTrack);
432 Int_t jkink = esdTrack1->GetKinkIndex(0);
434 if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
436 // The two tracks are from the same kink
438 if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
441 Int_t idaughter = -1;
443 if (ikink<0 && jkink>0) {
448 else if (ikink>0 && jkink<0) {
454 cerr << "Error: Wrong combination of kink indexes: "
455 << ikink << " " << jkink << endl;
459 // Add the mother track
461 AliAODTrack * mother = NULL;
463 if (!usedTrack[imother]) {
465 usedTrack[imother] = kTRUE;
467 AliESDtrack *esdTrack = esd->GetTrack(imother);
468 esdTrack->GetPxPyPz(p);
469 esdTrack->GetXYZ(pos);
470 esdTrack->GetCovarianceXYZPxPyPz(covTr);
471 esdTrack->GetESDpid(pid);
474 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
475 esdTrack->GetLabel(),
481 (Short_t)esdTrack->GetSign(),
482 esdTrack->GetITSClusterMap(),
485 kTRUE, // check if this is right
486 kTRUE, // check if this is right
487 AliAODTrack::kPrimary);
488 primary->AddDaughter(mother);
489 mother->ConvertAliPIDtoAODPID();
492 cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
493 << " track " << imother << " has already been used!" << endl;
496 // Add the kink vertex
497 AliESDkink * kink = esd->GetKink(TMath::Abs(ikink)-1);
499 AliAODVertex * vkink =
500 new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
504 AliAODVertex::kKink);
505 // Add the daughter track
507 AliAODTrack * daughter = NULL;
509 if (!usedTrack[idaughter]) {
511 usedTrack[idaughter] = kTRUE;
513 AliESDtrack *esdTrack = esd->GetTrack(idaughter);
514 esdTrack->GetPxPyPz(p);
515 esdTrack->GetXYZ(pos);
516 esdTrack->GetCovarianceXYZPxPyPz(covTr);
517 esdTrack->GetESDpid(pid);
520 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
521 esdTrack->GetLabel(),
527 (Short_t)esdTrack->GetSign(),
528 esdTrack->GetITSClusterMap(),
531 kTRUE, // check if this is right
532 kTRUE, // check if this is right
533 AliAODTrack::kPrimary);
534 vkink->AddDaughter(daughter);
535 daughter->ConvertAliPIDtoAODPID();
538 cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
539 << " track " << idaughter << " has already been used!" << endl;
551 // Tracks (primary and orphan)
553 for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
556 if (usedTrack[nTrack]) continue;
558 AliESDtrack *esdTrack = esd->GetTrack(nTrack);
559 esdTrack->GetPxPyPz(p);
560 esdTrack->GetXYZ(pos);
561 esdTrack->GetCovarianceXYZPxPyPz(covTr);
562 esdTrack->GetESDpid(pid);
564 Float_t impactXY, impactZ;
566 esdTrack->GetImpactParameters(impactXY,impactZ);
569 // track inside the beam pipe
571 primary->AddDaughter(aodTrack =
572 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
573 esdTrack->GetLabel(),
579 (Short_t)esdTrack->GetSign(),
580 esdTrack->GetITSClusterMap(),
583 kTRUE, // check if this is right
584 kTRUE, // check if this is right
585 AliAODTrack::kPrimary)
587 aodTrack->ConvertAliPIDtoAODPID();
590 // outside the beam pipe: orphan track
592 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
593 esdTrack->GetLabel(),
599 (Short_t)esdTrack->GetSign(),
600 esdTrack->GetITSClusterMap(),
603 kFALSE, // check if this is right
604 kFALSE, // check if this is right
605 AliAODTrack::kOrphan);
606 aodTrack->ConvertAliPIDtoAODPID();
608 } // end of loop on tracks
611 Int_t nMuTracks = esd->GetNumberOfMuonTracks();
612 for (Int_t nMuTrack = 0; nMuTrack < nMuTracks; ++nMuTrack) {
614 AliESDMuonTrack *esdMuTrack = esd->GetMuonTrack(nMuTrack);
615 p[0] = esdMuTrack->Px();
616 p[1] = esdMuTrack->Py();
617 p[2] = esdMuTrack->Pz();
618 pos[0] = primary->GetX();
619 pos[1] = primary->GetY();
620 pos[2] = primary->GetZ();
622 // has to be changed once the muon pid is provided by the ESD
623 for (Int_t i = 0; i < 10; pid[i++] = 0.); pid[AliAODTrack::kMuon]=1.;
625 primary->AddDaughter(
626 new(tracks[jTracks++]) AliAODTrack(0, // no ID provided
627 0, // no label provided
632 NULL, // no covariance matrix provided
633 (Short_t)-99, // no charge provided
634 0, // no ITSClusterMap
637 kTRUE, // check if this is right
638 kTRUE, // not used for vertex fit
639 AliAODTrack::kPrimary)
643 // Access to the AOD container of clusters
644 TClonesArray &clusters = *(aod->GetClusters());
648 Int_t nClusters = esd->GetNumberOfCaloClusters();
650 for (Int_t iClust=0; iClust<nClusters; ++iClust) {
652 AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
654 Int_t id = cluster->GetID();
656 Float_t energy = cluster->E();
657 cluster->GetPosition(posF);
658 AliAODVertex *prodVertex = primary;
659 AliAODTrack *primTrack = NULL;
660 Char_t ttype=AliAODCluster::kUndef;
662 if (cluster->IsPHOS()) ttype=AliAODCluster::kPHOSNeutral;
663 else if (cluster->IsEMCAL()) {
665 if (cluster->GetClusterType() == AliESDCaloCluster::kPseudoCluster)
666 ttype = AliAODCluster::kEMCALPseudoCluster;
668 ttype = AliAODCluster::kEMCALClusterv1;
672 new(clusters[jClusters++]) AliAODCluster(id,
676 NULL, // no covariance matrix provided
677 NULL, // no pid for clusters provided
682 } // end of loop on calo clusters
688 // fill the tree for this event
690 } // end of event loop
692 aodTree->GetUserInfo()->Add(aod);
697 // write the tree to the specified file
698 outFile = aodTree->GetCurrentFile();