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"
13 #include "AliAODTracklets.h"
15 #include "AliESDEvent.h"
16 #include "AliESDtrack.h"
17 #include "AliESDMuonTrack.h"
18 #include "AliESDVertex.h"
20 #include "AliESDcascade.h"
21 #include "AliESDCaloCluster.h"
25 void CreateAODfromESD(const char *inFileName = "AliESDs.root",
26 const char *outFileName = "AliAOD.root") {
28 // create an AliAOD object
29 AliAODEvent *aod = new AliAODEvent();
30 aod->CreateStdContent();
33 TFile *outFile = TFile::Open(outFileName, "RECREATE");
36 TTree *aodTree = new TTree("aodTree", "AliAOD tree");
37 aodTree->Branch(aod->GetList());
40 TFile *inFile = TFile::Open(inFileName, "READ");
41 TTree *t = (TTree*) inFile->Get("esdTree");
42 AliESDEvent *esd = new AliESDEvent();
45 Int_t nEvents = t->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)->Charge()> 0) nPosTracks++;
65 // Access to the header
66 AliAODHeader *header = aod->GetHeader();
69 *header = AliAODHeader(esd->GetRunNumber(),
70 esd->GetBunchCrossNumber(),
71 esd->GetOrbitNumber(),
72 esd->GetPeriodNumber(),
76 esd->GetMagneticField(),
77 -999., // fill muon magnetic field
78 -999., // centrality; to be filled, still
79 esd->GetZDCN1Energy(),
80 esd->GetZDCP1Energy(),
81 esd->GetZDCN2Energy(),
82 esd->GetZDCP2Energy(),
83 esd->GetZDCEMEnergy(),
84 esd->GetTriggerMask(),
85 esd->GetTriggerCluster(),
88 Int_t nV0s = esd->GetNumberOfV0s();
89 Int_t nCascades = esd->GetNumberOfCascades();
90 Int_t nKinks = esd->GetNumberOfKinks();
91 Int_t nVertices = nV0s + nCascades + nKinks;
93 aod->ResetStd(nTracks, nVertices);
94 AliAODTrack *aodTrack;
96 // Array to take into account the tracks already added to the AOD
97 Bool_t * usedTrack = NULL;
99 usedTrack = new Bool_t[nTracks];
100 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
102 // Array to take into account the V0s already added to the AOD
103 Bool_t * usedV0 = NULL;
105 usedV0 = new Bool_t[nV0s];
106 for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
108 // Array to take into account the kinks already added to the AOD
109 Bool_t * usedKink = NULL;
111 usedKink = new Bool_t[nKinks];
112 for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
115 // Access to the AOD container of vertices
116 TClonesArray &vertices = *(aod->GetVertices());
119 // Access to the AOD container of tracks
120 TClonesArray &tracks = *(aod->GetTracks());
123 // Add primary vertex. The primary tracks will be defined
124 // after the loops on the composite objects (V0, cascades, kinks)
125 const AliESDVertex *vtx = esd->GetPrimaryVertex();
127 vtx->GetXYZ(pos); // position
128 vtx->GetCovMatrix(covVtx); //covariance matrix
130 AliAODVertex * primary = new(vertices[jVertices++])
131 AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
133 // Create vertices starting from the most complex objects
136 for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
137 AliESDcascade *cascade = esd->GetCascade(nCascade);
139 cascade->GetXYZ(pos[0], pos[1], pos[2]);
140 cascade->GetPosCovXi(covVtx);
142 // Add the cascade vertex
143 AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
145 cascade->GetChi2Xi(), // = chi2/NDF since NDF = 2*2-3
148 AliAODVertex::kCascade);
150 primary->AddDaughter(vcascade);
152 // Add the V0 from the cascade. The ESD class have to be optimized...
153 // Now we have to search for the corresponding V0 in the list of V0s
154 // using the indeces of the positive and negative tracks
156 Int_t posFromV0 = cascade->GetPindex();
157 Int_t negFromV0 = cascade->GetNindex();
163 for (Int_t iV0=0; iV0<nV0s; ++iV0) {
165 v0 = esd->GetV0(iV0);
166 Int_t posV0 = v0->GetPindex();
167 Int_t negV0 = v0->GetNindex();
169 if (posV0==posFromV0 && negV0==negFromV0) {
175 AliAODVertex * vV0FromCascade = 0x0;
177 if (indV0>-1 && !usedV0[indV0] ) {
179 // the V0 exists in the array of V0s and is not used
181 usedV0[indV0] = kTRUE;
183 v0->GetXYZ(pos[0], pos[1], pos[2]);
184 v0->GetPosCov(covVtx);
186 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
188 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
194 // the V0 doesn't exist in the array of V0s or was used
195 cerr << "Error: event " << iEvent << " cascade " << nCascade
196 << " The V0 " << indV0
197 << " doesn't exist in the array of V0s or was used!" << endl;
199 cascade->GetXYZ(pos[0], pos[1], pos[2]);
200 cascade->GetPosCov(covVtx);
202 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
204 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
208 vcascade->AddDaughter(vV0FromCascade);
211 // Add the positive tracks from the V0
213 if (! usedTrack[posFromV0]) {
215 usedTrack[posFromV0] = kTRUE;
217 AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
218 esdTrack->GetPxPyPz(p);
219 esdTrack->GetXYZ(pos);
220 esdTrack->GetCovarianceXYZPxPyPz(covTr);
221 esdTrack->GetESDpid(pid);
223 vV0FromCascade->AddDaughter(aodTrack =
224 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
225 esdTrack->GetLabel(),
231 (Short_t)esdTrack->Charge(),
232 esdTrack->GetITSClusterMap(),
235 kTRUE, // check if this is right
236 kFALSE, // check if this is right
237 AliAODTrack::kSecondary)
239 aodTrack->ConvertAliPIDtoAODPID();
242 cerr << "Error: event " << iEvent << " cascade " << nCascade
243 << " track " << posFromV0 << " has already been used!" << endl;
246 // Add the negative tracks from the V0
248 if (!usedTrack[negFromV0]) {
250 usedTrack[negFromV0] = kTRUE;
252 AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
253 esdTrack->GetPxPyPz(p);
254 esdTrack->GetXYZ(pos);
255 esdTrack->GetCovarianceXYZPxPyPz(covTr);
256 esdTrack->GetESDpid(pid);
258 vV0FromCascade->AddDaughter(aodTrack =
259 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
260 esdTrack->GetLabel(),
266 (Short_t)esdTrack->Charge(),
267 esdTrack->GetITSClusterMap(),
270 kTRUE, // check if this is right
271 kFALSE, // check if this is right
272 AliAODTrack::kSecondary)
274 aodTrack->ConvertAliPIDtoAODPID();
277 cerr << "Error: event " << iEvent << " cascade " << nCascade
278 << " track " << negFromV0 << " has already been used!" << endl;
281 // Add the bachelor track from the cascade
283 Int_t bachelor = cascade->GetBindex();
285 if(!usedTrack[bachelor]) {
287 usedTrack[bachelor] = kTRUE;
289 AliESDtrack *esdTrack = esd->GetTrack(bachelor);
290 esdTrack->GetPxPyPz(p);
291 esdTrack->GetXYZ(pos);
292 esdTrack->GetCovarianceXYZPxPyPz(covTr);
293 esdTrack->GetESDpid(pid);
295 vcascade->AddDaughter(aodTrack =
296 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
297 esdTrack->GetLabel(),
303 (Short_t)esdTrack->Charge(),
304 esdTrack->GetITSClusterMap(),
307 kTRUE, // check if this is right
308 kFALSE, // check if this is right
309 AliAODTrack::kSecondary)
311 aodTrack->ConvertAliPIDtoAODPID();
314 cerr << "Error: event " << iEvent << " cascade " << nCascade
315 << " track " << bachelor << " has already been used!" << endl;
318 // Add the primary track of the cascade (if any)
320 } // end of the loop on cascades
324 for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
326 if (usedV0[nV0]) continue; // skip if aready added to the AOD
328 AliESDv0 *v0 = esd->GetV0(nV0);
330 v0->GetXYZ(pos[0], pos[1], pos[2]);
331 v0->GetPosCov(covVtx);
334 new(vertices[jVertices++]) AliAODVertex(pos,
336 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
340 primary->AddDaughter(vV0);
342 Int_t posFromV0 = v0->GetPindex();
343 Int_t negFromV0 = v0->GetNindex();
345 // Add the positive tracks from the V0
347 if (!usedTrack[posFromV0]) {
349 usedTrack[posFromV0] = kTRUE;
351 AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
352 esdTrack->GetPxPyPz(p);
353 esdTrack->GetXYZ(pos);
354 esdTrack->GetCovarianceXYZPxPyPz(covTr);
355 esdTrack->GetESDpid(pid);
357 vV0->AddDaughter(aodTrack =
358 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
359 esdTrack->GetLabel(),
365 (Short_t)esdTrack->Charge(),
366 esdTrack->GetITSClusterMap(),
369 kTRUE, // check if this is right
370 kFALSE, // check if this is right
371 AliAODTrack::kSecondary)
373 aodTrack->ConvertAliPIDtoAODPID();
376 cerr << "Error: event " << iEvent << " V0 " << nV0
377 << " track " << posFromV0 << " has already been used!" << endl;
380 // Add the negative tracks from the V0
382 if (!usedTrack[negFromV0]) {
384 usedTrack[negFromV0] = kTRUE;
386 AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
387 esdTrack->GetPxPyPz(p);
388 esdTrack->GetXYZ(pos);
389 esdTrack->GetCovarianceXYZPxPyPz(covTr);
390 esdTrack->GetESDpid(pid);
392 vV0->AddDaughter(aodTrack =
393 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
394 esdTrack->GetLabel(),
400 (Short_t)esdTrack->Charge(),
401 esdTrack->GetITSClusterMap(),
404 kTRUE, // check if this is right
405 kFALSE, // check if this is right
406 AliAODTrack::kSecondary)
408 aodTrack->ConvertAliPIDtoAODPID();
411 cerr << "Error: event " << iEvent << " V0 " << nV0
412 << " track " << negFromV0 << " has already been used!" << endl;
415 } // end of the loop on V0s
417 // Kinks: it is a big mess the access to the information in the kinks
418 // The loop is on the tracks in order to find the mother and daugther of each kink
421 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
424 AliESDtrack * esdTrack = esd->GetTrack(iTrack);
426 Int_t ikink = esdTrack->GetKinkIndex(0);
429 // Negative kink index: mother, positive: daughter
431 // Search for the second track of the kink
433 for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
435 AliESDtrack * esdTrack1 = esd->GetTrack(jTrack);
437 Int_t jkink = esdTrack1->GetKinkIndex(0);
439 if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
441 // The two tracks are from the same kink
443 if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
446 Int_t idaughter = -1;
448 if (ikink<0 && jkink>0) {
453 else if (ikink>0 && jkink<0) {
459 cerr << "Error: Wrong combination of kink indexes: "
460 << ikink << " " << jkink << endl;
464 // Add the mother track
466 AliAODTrack * mother = NULL;
468 if (!usedTrack[imother]) {
470 usedTrack[imother] = kTRUE;
472 AliESDtrack *esdTrack = esd->GetTrack(imother);
473 esdTrack->GetPxPyPz(p);
474 esdTrack->GetXYZ(pos);
475 esdTrack->GetCovarianceXYZPxPyPz(covTr);
476 esdTrack->GetESDpid(pid);
479 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
480 esdTrack->GetLabel(),
486 (Short_t)esdTrack->Charge(),
487 esdTrack->GetITSClusterMap(),
490 kTRUE, // check if this is right
491 kTRUE, // check if this is right
492 AliAODTrack::kPrimary);
493 primary->AddDaughter(mother);
494 mother->ConvertAliPIDtoAODPID();
497 cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
498 << " track " << imother << " has already been used!" << endl;
501 // Add the kink vertex
502 AliESDkink * kink = esd->GetKink(TMath::Abs(ikink)-1);
504 AliAODVertex * vkink =
505 new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
509 esdTrack->GetID(), // This is the track ID of the mother's track!
510 AliAODVertex::kKink);
511 // Add the daughter track
513 AliAODTrack * daughter = NULL;
515 if (!usedTrack[idaughter]) {
517 usedTrack[idaughter] = kTRUE;
519 AliESDtrack *esdTrack = esd->GetTrack(idaughter);
520 esdTrack->GetPxPyPz(p);
521 esdTrack->GetXYZ(pos);
522 esdTrack->GetCovarianceXYZPxPyPz(covTr);
523 esdTrack->GetESDpid(pid);
526 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
527 esdTrack->GetLabel(),
533 (Short_t)esdTrack->Charge(),
534 esdTrack->GetITSClusterMap(),
537 kTRUE, // check if this is right
538 kTRUE, // check if this is right
539 AliAODTrack::kPrimary);
540 vkink->AddDaughter(daughter);
541 daughter->ConvertAliPIDtoAODPID();
544 cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
545 << " track " << idaughter << " has already been used!" << endl;
557 // Tracks (primary and orphan)
559 for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
562 if (usedTrack[nTrack]) continue;
564 AliESDtrack *esdTrack = esd->GetTrack(nTrack);
565 esdTrack->GetPxPyPz(p);
566 esdTrack->GetXYZ(pos);
567 esdTrack->GetCovarianceXYZPxPyPz(covTr);
568 esdTrack->GetESDpid(pid);
570 Float_t impactXY, impactZ;
572 esdTrack->GetImpactParameters(impactXY,impactZ);
575 // track inside the beam pipe
577 primary->AddDaughter(aodTrack =
578 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
579 esdTrack->GetLabel(),
585 (Short_t)esdTrack->Charge(),
586 esdTrack->GetITSClusterMap(),
589 kTRUE, // check if this is right
590 kTRUE, // check if this is right
591 AliAODTrack::kPrimary)
593 aodTrack->ConvertAliPIDtoAODPID();
596 // outside the beam pipe: orphan track
598 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
599 esdTrack->GetLabel(),
605 (Short_t)esdTrack->Charge(),
606 esdTrack->GetITSClusterMap(),
609 kFALSE, // check if this is right
610 kFALSE, // check if this is right
611 AliAODTrack::kOrphan);
612 aodTrack->ConvertAliPIDtoAODPID();
614 } // end of loop on tracks
617 Int_t nMuTracks = esd->GetNumberOfMuonTracks();
618 for (Int_t nMuTrack = 0; nMuTrack < nMuTracks; ++nMuTrack) {
620 AliESDMuonTrack *esdMuTrack = esd->GetMuonTrack(nMuTrack);
621 p[0] = esdMuTrack->Px();
622 p[1] = esdMuTrack->Py();
623 p[2] = esdMuTrack->Pz();
624 pos[0] = primary->GetX();
625 pos[1] = primary->GetY();
626 pos[2] = primary->GetZ();
628 // has to be changed once the muon pid is provided by the ESD
629 for (Int_t i = 0; i < 10; pid[i++] = 0.); pid[AliAODTrack::kMuon]=1.;
631 primary->AddDaughter( aodTrack =
632 new(tracks[jTracks++]) AliAODTrack(0, // no ID provided
633 0, // no label provided
638 NULL, // no covariance matrix provided
639 esdMuTrack->Charge(),
640 0, // ITSClusterMap is set below
643 kFALSE, // muon tracks are not used to fit the primary vtx
644 kFALSE, // not used for vertex fit
645 AliAODTrack::kPrimary)
647 aodTrack->SetHitsPatternInTrigCh(esdMuTrack->GetHitsPatternInTrigCh());
648 Int_t track2Trigger = esdMuTrack->GetMatchTrigger();
649 aodTrack->SetMatchTrigger(track2Trigger);
651 aodTrack->SetChi2MatchTrigger(esdMuTrack->GetChi2MatchTrigger());
653 aodTrack->SetChi2MatchTrigger(0.);
656 // Access to the AOD container of clusters
657 TClonesArray &clusters = *(aod->GetClusters());
661 Int_t nClusters = esd->GetNumberOfCaloClusters();
663 for (Int_t iClust=0; iClust<nClusters; ++iClust) {
665 AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
667 Int_t id = cluster->GetID();
669 Float_t energy = cluster->E();
670 cluster->GetPosition(posF);
671 AliAODVertex *prodVertex = primary;
672 AliAODTrack *primTrack = NULL;
673 Char_t ttype=AliAODCluster::kUndef;
675 if (cluster->IsPHOS()) ttype=AliAODCluster::kPHOSNeutral;
676 else if (cluster->IsEMCAL()) {
678 if (cluster->GetClusterType() == AliESDCaloCluster::kPseudoCluster)
679 ttype = AliAODCluster::kEMCALPseudoCluster;
681 ttype = AliAODCluster::kEMCALClusterv1;
685 new(clusters[jClusters++]) AliAODCluster(id,
689 NULL, // no covariance matrix provided
690 NULL, // no pid for clusters provided
695 } // end of loop on calo clusters
698 const AliMultiplicity *mult = esd->GetMultiplicity();
700 if (mult->GetNumberOfTracklets()>0) {
701 aod->GetTracklets()->CreateContainer(mult->GetNumberOfTracklets());
703 for (Int_t n=0; n<mult->GetNumberOfTracklets(); n++) {
704 aod->GetTracklets()->SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n));
708 Printf("ERROR: AliMultiplicity could not be retrieved from ESD");
715 // fill the tree for this event
717 } // end of event loop
719 aodTree->GetUserInfo()->Add(aod);
724 // write the tree to the specified file
725 outFile = aodTree->GetCurrentFile();