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") {
29 TFile *inFile = TFile::Open(inFileName, "READ");
31 // create an AliAOD object
32 AliAODEvent *aod = new AliAODEvent();
33 aod->CreateStdContent();
36 TFile *outFile = TFile::Open(outFileName, "RECREATE");
40 TTree *aodTree = new TTree("aodTree", "AliAOD tree");
41 aodTree->Branch(aod->GetList());
44 TTree *t = (TTree*) inFile->Get("esdTree");
45 AliESDEvent *esd = new AliESDEvent();
48 Int_t nEvents = t->GetEntries();
50 // set arrays and pointers
58 // loop over events and fill them
59 for (Int_t iEvent = 0; iEvent < nEvents; ++iEvent) {
62 // Multiplicity information needed by the header (to be revised!)
63 Int_t nTracks = esd->GetNumberOfTracks();
65 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack)
66 if (esd->GetTrack(iTrack)->Charge()> 0) nPosTracks++;
69 AliAODHeader *header = aod->GetHeader();
72 header->SetRunNumber (esd->GetRunNumber() );
73 header->SetBunchCrossNumber(esd->GetBunchCrossNumber());
74 header->SetOrbitNumber (esd->GetOrbitNumber() );
75 header->SetPeriodNumber (esd->GetPeriodNumber() );
76 header->SetTriggerMask (esd->GetTriggerMask() );
77 header->SetTriggerCluster (esd->GetTriggerCluster() );
78 header->SetEventType (esd->GetEventType() );
79 header->SetMagneticField (esd->GetMagneticField() );
80 header->SetZDCN1Energy (esd->GetZDCN1Energy() );
81 header->SetZDCP1Energy (esd->GetZDCP1Energy() );
82 header->SetZDCN2Energy (esd->GetZDCN2Energy() );
83 header->SetZDCP2Energy (esd->GetZDCP2Energy() );
84 header->SetZDCEMEnergy (esd->GetZDCEMEnergy() );
85 header->SetRefMultiplicity (nTracks);
86 header->SetRefMultiplicityPos(nPosTracks);
87 header->SetRefMultiplicityNeg(nTracks - nPosTracks);
88 header->SetMuonMagFieldScale(-999.); // FIXME
89 header->SetCentrality(-999.); // FIXME
91 Int_t nV0s = esd->GetNumberOfV0s();
92 Int_t nCascades = esd->GetNumberOfCascades();
93 Int_t nKinks = esd->GetNumberOfKinks();
94 Int_t nVertices = nV0s + nCascades + nKinks;
96 aod->ResetStd(nTracks, nVertices);
97 AliAODTrack *aodTrack;
99 // Array to take into account the tracks already added to the AOD
100 Bool_t * usedTrack = NULL;
102 usedTrack = new Bool_t[nTracks];
103 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
105 // Array to take into account the V0s already added to the AOD
106 Bool_t * usedV0 = NULL;
108 usedV0 = new Bool_t[nV0s];
109 for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
111 // Array to take into account the kinks already added to the AOD
112 Bool_t * usedKink = NULL;
114 usedKink = new Bool_t[nKinks];
115 for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
118 // Access to the AOD container of vertices
119 TClonesArray &vertices = *(aod->GetVertices());
122 // Access to the AOD container of tracks
123 TClonesArray &tracks = *(aod->GetTracks());
126 // Add primary vertex. The primary tracks will be defined
127 // after the loops on the composite objects (V0, cascades, kinks)
128 const AliESDVertex *vtx = esd->GetPrimaryVertex();
130 vtx->GetXYZ(pos); // position
131 vtx->GetCovMatrix(covVtx); //covariance matrix
133 AliAODVertex * primary = new(vertices[jVertices++])
134 AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
136 // Create vertices starting from the most complex objects
139 for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
140 AliESDcascade *cascade = esd->GetCascade(nCascade);
142 cascade->GetXYZ(pos[0], pos[1], pos[2]);
143 cascade->GetPosCovXi(covVtx);
145 // Add the cascade vertex
146 AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
148 cascade->GetChi2Xi(), // = chi2/NDF since NDF = 2*2-3
151 AliAODVertex::kCascade);
153 primary->AddDaughter(vcascade);
155 // Add the V0 from the cascade. The ESD class have to be optimized...
156 // Now we have to search for the corresponding V0 in the list of V0s
157 // using the indeces of the positive and negative tracks
159 Int_t posFromV0 = cascade->GetPindex();
160 Int_t negFromV0 = cascade->GetNindex();
166 for (Int_t iV0=0; iV0<nV0s; ++iV0) {
168 v0 = esd->GetV0(iV0);
169 Int_t posV0 = v0->GetPindex();
170 Int_t negV0 = v0->GetNindex();
172 if (posV0==posFromV0 && negV0==negFromV0) {
178 AliAODVertex * vV0FromCascade = 0x0;
180 if (indV0>-1 && !usedV0[indV0] ) {
182 // the V0 exists in the array of V0s and is not used
184 usedV0[indV0] = kTRUE;
186 v0->GetXYZ(pos[0], pos[1], pos[2]);
187 v0->GetPosCov(covVtx);
189 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
191 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
197 // the V0 doesn't exist in the array of V0s or was used
198 cerr << "Error: event " << iEvent << " cascade " << nCascade
199 << " The V0 " << indV0
200 << " doesn't exist in the array of V0s or was used!" << endl;
202 cascade->GetXYZ(pos[0], pos[1], pos[2]);
203 cascade->GetPosCov(covVtx);
205 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
207 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
211 vcascade->AddDaughter(vV0FromCascade);
214 // Add the positive tracks from the V0
216 if (! usedTrack[posFromV0]) {
218 usedTrack[posFromV0] = kTRUE;
220 AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
221 esdTrack->GetPxPyPz(p);
222 esdTrack->GetXYZ(pos);
223 esdTrack->GetCovarianceXYZPxPyPz(covTr);
224 esdTrack->GetESDpid(pid);
226 vV0FromCascade->AddDaughter(aodTrack =
227 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
228 esdTrack->GetLabel(),
234 (Short_t)esdTrack->Charge(),
235 esdTrack->GetITSClusterMap(),
238 kTRUE, // check if this is right
239 kFALSE, // check if this is right
240 AliAODTrack::kSecondary)
242 aodTrack->ConvertAliPIDtoAODPID();
245 cerr << "Error: event " << iEvent << " cascade " << nCascade
246 << " track " << posFromV0 << " has already been used!" << endl;
249 // Add the negative tracks from the V0
251 if (!usedTrack[negFromV0]) {
253 usedTrack[negFromV0] = kTRUE;
255 AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
256 esdTrack->GetPxPyPz(p);
257 esdTrack->GetXYZ(pos);
258 esdTrack->GetCovarianceXYZPxPyPz(covTr);
259 esdTrack->GetESDpid(pid);
261 vV0FromCascade->AddDaughter(aodTrack =
262 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
263 esdTrack->GetLabel(),
269 (Short_t)esdTrack->Charge(),
270 esdTrack->GetITSClusterMap(),
273 kTRUE, // check if this is right
274 kFALSE, // check if this is right
275 AliAODTrack::kSecondary)
277 aodTrack->ConvertAliPIDtoAODPID();
280 cerr << "Error: event " << iEvent << " cascade " << nCascade
281 << " track " << negFromV0 << " has already been used!" << endl;
284 // Add the bachelor track from the cascade
286 Int_t bachelor = cascade->GetBindex();
288 if(!usedTrack[bachelor]) {
290 usedTrack[bachelor] = kTRUE;
292 AliESDtrack *esdTrack = esd->GetTrack(bachelor);
293 esdTrack->GetPxPyPz(p);
294 esdTrack->GetXYZ(pos);
295 esdTrack->GetCovarianceXYZPxPyPz(covTr);
296 esdTrack->GetESDpid(pid);
298 vcascade->AddDaughter(aodTrack =
299 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
300 esdTrack->GetLabel(),
306 (Short_t)esdTrack->Charge(),
307 esdTrack->GetITSClusterMap(),
310 kTRUE, // check if this is right
311 kFALSE, // check if this is right
312 AliAODTrack::kSecondary)
314 aodTrack->ConvertAliPIDtoAODPID();
317 cerr << "Error: event " << iEvent << " cascade " << nCascade
318 << " track " << bachelor << " has already been used!" << endl;
321 // Add the primary track of the cascade (if any)
323 } // end of the loop on cascades
327 for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
329 if (usedV0[nV0]) continue; // skip if aready added to the AOD
331 AliESDv0 *v0 = esd->GetV0(nV0);
333 v0->GetXYZ(pos[0], pos[1], pos[2]);
334 v0->GetPosCov(covVtx);
337 new(vertices[jVertices++]) AliAODVertex(pos,
339 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
343 primary->AddDaughter(vV0);
345 Int_t posFromV0 = v0->GetPindex();
346 Int_t negFromV0 = v0->GetNindex();
348 // Add the positive tracks from the V0
350 if (!usedTrack[posFromV0]) {
352 usedTrack[posFromV0] = kTRUE;
354 AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
355 esdTrack->GetPxPyPz(p);
356 esdTrack->GetXYZ(pos);
357 esdTrack->GetCovarianceXYZPxPyPz(covTr);
358 esdTrack->GetESDpid(pid);
360 vV0->AddDaughter(aodTrack =
361 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
362 esdTrack->GetLabel(),
368 (Short_t)esdTrack->Charge(),
369 esdTrack->GetITSClusterMap(),
372 kTRUE, // check if this is right
373 kFALSE, // check if this is right
374 AliAODTrack::kSecondary)
376 aodTrack->ConvertAliPIDtoAODPID();
379 cerr << "Error: event " << iEvent << " V0 " << nV0
380 << " track " << posFromV0 << " has already been used!" << endl;
383 // Add the negative tracks from the V0
385 if (!usedTrack[negFromV0]) {
387 usedTrack[negFromV0] = kTRUE;
389 AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
390 esdTrack->GetPxPyPz(p);
391 esdTrack->GetXYZ(pos);
392 esdTrack->GetCovarianceXYZPxPyPz(covTr);
393 esdTrack->GetESDpid(pid);
395 vV0->AddDaughter(aodTrack =
396 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
397 esdTrack->GetLabel(),
403 (Short_t)esdTrack->Charge(),
404 esdTrack->GetITSClusterMap(),
407 kTRUE, // check if this is right
408 kFALSE, // check if this is right
409 AliAODTrack::kSecondary)
411 aodTrack->ConvertAliPIDtoAODPID();
414 cerr << "Error: event " << iEvent << " V0 " << nV0
415 << " track " << negFromV0 << " has already been used!" << endl;
418 } // end of the loop on V0s
420 // Kinks: it is a big mess the access to the information in the kinks
421 // The loop is on the tracks in order to find the mother and daugther of each kink
424 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
427 AliESDtrack * esdTrack = esd->GetTrack(iTrack);
429 Int_t ikink = esdTrack->GetKinkIndex(0);
432 // Negative kink index: mother, positive: daughter
434 // Search for the second track of the kink
436 for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
438 AliESDtrack * esdTrack1 = esd->GetTrack(jTrack);
440 Int_t jkink = esdTrack1->GetKinkIndex(0);
442 if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
444 // The two tracks are from the same kink
446 if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
449 Int_t idaughter = -1;
451 if (ikink<0 && jkink>0) {
456 else if (ikink>0 && jkink<0) {
462 cerr << "Error: Wrong combination of kink indexes: "
463 << ikink << " " << jkink << endl;
467 // Add the mother track
469 AliAODTrack * mother = NULL;
471 if (!usedTrack[imother]) {
473 usedTrack[imother] = kTRUE;
475 AliESDtrack *esdTrack = esd->GetTrack(imother);
476 esdTrack->GetPxPyPz(p);
477 esdTrack->GetXYZ(pos);
478 esdTrack->GetCovarianceXYZPxPyPz(covTr);
479 esdTrack->GetESDpid(pid);
482 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
483 esdTrack->GetLabel(),
489 (Short_t)esdTrack->Charge(),
490 esdTrack->GetITSClusterMap(),
493 kTRUE, // check if this is right
494 kTRUE, // check if this is right
495 AliAODTrack::kPrimary);
496 primary->AddDaughter(mother);
497 mother->ConvertAliPIDtoAODPID();
500 cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
501 << " track " << imother << " has already been used!" << endl;
504 // Add the kink vertex
505 AliESDkink * kink = esd->GetKink(TMath::Abs(ikink)-1);
507 AliAODVertex * vkink =
508 new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
512 esdTrack->GetID(), // This is the track ID of the mother's track!
513 AliAODVertex::kKink);
514 // Add the daughter track
516 AliAODTrack * daughter = NULL;
518 if (!usedTrack[idaughter]) {
520 usedTrack[idaughter] = kTRUE;
522 AliESDtrack *esdTrack = esd->GetTrack(idaughter);
523 esdTrack->GetPxPyPz(p);
524 esdTrack->GetXYZ(pos);
525 esdTrack->GetCovarianceXYZPxPyPz(covTr);
526 esdTrack->GetESDpid(pid);
529 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
530 esdTrack->GetLabel(),
536 (Short_t)esdTrack->Charge(),
537 esdTrack->GetITSClusterMap(),
540 kTRUE, // check if this is right
541 kTRUE, // check if this is right
542 AliAODTrack::kPrimary);
543 vkink->AddDaughter(daughter);
544 daughter->ConvertAliPIDtoAODPID();
547 cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
548 << " track " << idaughter << " has already been used!" << endl;
560 // Tracks (primary and orphan)
562 for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
565 if (usedTrack[nTrack]) continue;
567 AliESDtrack *esdTrack = esd->GetTrack(nTrack);
568 esdTrack->GetPxPyPz(p);
569 esdTrack->GetXYZ(pos);
570 esdTrack->GetCovarianceXYZPxPyPz(covTr);
571 esdTrack->GetESDpid(pid);
573 Float_t impactXY, impactZ;
575 esdTrack->GetImpactParameters(impactXY,impactZ);
578 // track inside the beam pipe
580 primary->AddDaughter(aodTrack =
581 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
582 esdTrack->GetLabel(),
588 (Short_t)esdTrack->Charge(),
589 esdTrack->GetITSClusterMap(),
592 kTRUE, // check if this is right
593 kTRUE, // check if this is right
594 AliAODTrack::kPrimary)
596 aodTrack->ConvertAliPIDtoAODPID();
599 // outside the beam pipe: orphan track
601 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
602 esdTrack->GetLabel(),
608 (Short_t)esdTrack->Charge(),
609 esdTrack->GetITSClusterMap(),
612 kFALSE, // check if this is right
613 kFALSE, // check if this is right
614 AliAODTrack::kOrphan);
615 aodTrack->ConvertAliPIDtoAODPID();
617 } // end of loop on tracks
620 Int_t nMuTracks = esd->GetNumberOfMuonTracks();
621 for (Int_t nMuTrack = 0; nMuTrack < nMuTracks; ++nMuTrack) {
623 AliESDMuonTrack *esdMuTrack = esd->GetMuonTrack(nMuTrack);
624 p[0] = esdMuTrack->Px();
625 p[1] = esdMuTrack->Py();
626 p[2] = esdMuTrack->Pz();
627 pos[0] = primary->GetX();
628 pos[1] = primary->GetY();
629 pos[2] = primary->GetZ();
631 // has to be changed once the muon pid is provided by the ESD
632 for (Int_t i = 0; i < 10; pid[i++] = 0.); pid[AliAODTrack::kMuon]=1.;
634 primary->AddDaughter(aodTrack =
635 new(tracks[jTracks++]) AliAODTrack(0, // no ID provided
636 0, // no label provided
641 NULL, // no covariance matrix provided
642 esdMuTrack->Charge(),
643 0, // ITSClusterMap is set below
646 kFALSE, // muon tracks are not used to fit the primary vtx
647 kFALSE, // not used for vertex fit
648 AliAODTrack::kPrimary)
651 aodTrack->SetHitsPatternInTrigCh(esdMuTrack->GetHitsPatternInTrigCh());
652 Int_t track2Trigger = esdMuTrack->GetMatchTrigger();
653 aodTrack->SetMatchTrigger(track2Trigger);
655 aodTrack->SetChi2MatchTrigger(esdMuTrack->GetChi2MatchTrigger());
657 aodTrack->SetChi2MatchTrigger(0.);
660 // Access to the AOD container of clusters
661 TClonesArray &clusters = *(aod->GetClusters());
665 Int_t nClusters = esd->GetNumberOfCaloClusters();
667 for (Int_t iClust=0; iClust<nClusters; ++iClust) {
669 AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
671 Int_t id = cluster->GetID();
673 Float_t energy = cluster->E();
674 cluster->GetPosition(posF);
675 AliAODVertex *prodVertex = primary;
676 AliAODTrack *primTrack = NULL;
677 Char_t ttype=AliAODCluster::kUndef;
679 if (cluster->IsPHOS()) ttype=AliAODCluster::kPHOSNeutral;
680 else if (cluster->IsEMCAL()) {
682 if (cluster->GetClusterType() == AliESDCaloCluster::kPseudoCluster)
683 ttype = AliAODCluster::kEMCALPseudoCluster;
685 ttype = AliAODCluster::kEMCALClusterv1;
689 new(clusters[jClusters++]) AliAODCluster(id,
693 NULL, // no covariance matrix provided
694 NULL, // no pid for clusters provided
699 } // end of loop on calo clusters
702 const AliMultiplicity *mult = esd->GetMultiplicity();
704 if (mult->GetNumberOfTracklets()>0) {
705 aod->GetTracklets()->CreateContainer(mult->GetNumberOfTracklets());
707 for (Int_t n=0; n<mult->GetNumberOfTracklets(); n++) {
708 aod->GetTracklets()->SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n));
712 Printf("ERROR: AliMultiplicity could not be retrieved from ESD");
719 // fill the tree for this event
721 } // end of event loop
723 aodTree->GetUserInfo()->Add(aod);
728 // write the tree to the specified file
729 outFile = aodTree->GetCurrentFile();