Vertex ID added. It corresponds to the array index of the appropriate ESD container.
[u/mrichter/AliRoot.git] / STEER / CreateAODfromESD.C
1 #if !defined(__CINT__) || defined(__MAKECINT__)
2
3 #include <Riostream.h>
4 #include <TFile.h>
5 #include <TTree.h>
6 #include <TMath.h>
7
8 #include "AliAODEvent.h"
9 #include "AliAODHeader.h"
10 #include "AliAODVertex.h"
11 #include "AliAODTrack.h"
12 #include "AliAODCluster.h"
13 #include "AliAODTracklets.h"
14
15 #include "AliESDEvent.h"
16 #include "AliESDtrack.h"
17 #include "AliESDMuonTrack.h"
18 #include "AliESDVertex.h"
19 #include "AliESDv0.h"
20 #include "AliESDcascade.h"
21 #include "AliESDCaloCluster.h"
22
23 #endif
24
25 void CreateAODfromESD(const char *inFileName = "AliESDs.root",
26                       const char *outFileName = "AliAOD.root") {
27
28   // create an AliAOD object 
29   AliAODEvent *aod = new AliAODEvent();
30   aod->CreateStdContent();
31
32   // open the file
33   TFile *outFile = TFile::Open(outFileName, "RECREATE");
34
35   // create the tree
36   TTree *aodTree = new TTree("aodTree", "AliAOD tree");
37   aodTree->Branch(aod->GetList());
38
39   // connect to ESD
40   TFile *inFile = TFile::Open(inFileName, "READ");
41   TTree *t = (TTree*) inFile->Get("esdTree");
42   AliESDEvent *esd = new AliESDEvent();
43   esd->ReadFromTree(t);
44
45   Int_t nEvents = t->GetEntries();
46
47   // set arrays and pointers
48   Float_t posF[3];
49   Double_t pos[3];
50   Double_t p[3];
51   Double_t covVtx[6];
52   Double_t covTr[21];
53   Double_t pid[10];
54
55   // loop over events and fill them
56   for (Int_t iEvent = 0; iEvent < nEvents; ++iEvent) {
57     t->GetEntry(iEvent);
58
59     // Multiplicity information needed by the header (to be revised!)
60     Int_t nTracks   = esd->GetNumberOfTracks();
61     Int_t nPosTracks = 0;
62     for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) 
63       if (esd->GetTrack(iTrack)->Charge()> 0) nPosTracks++;
64     
65     // Access to the header
66     AliAODHeader *header = aod->GetHeader();
67
68     // fill the header
69     *header = AliAODHeader(esd->GetRunNumber(),
70                            esd->GetBunchCrossNumber(),
71                            esd->GetOrbitNumber(),
72                            esd->GetPeriodNumber(),
73                            nTracks,
74                            nPosTracks,
75                            nTracks-nPosTracks,
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(),
86                            esd->GetEventType());
87   
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;
92     
93     aod->ResetStd(nTracks, nVertices);
94     AliAODTrack *aodTrack;
95     
96     // Array to take into account the tracks already added to the AOD
97     Bool_t * usedTrack = NULL;
98     if (nTracks>0) {
99       usedTrack = new Bool_t[nTracks];
100       for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
101     }
102     // Array to take into account the V0s already added to the AOD
103     Bool_t * usedV0 = NULL;
104     if (nV0s>0) {
105       usedV0 = new Bool_t[nV0s];
106       for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
107     }
108     // Array to take into account the kinks already added to the AOD
109     Bool_t * usedKink = NULL;
110     if (nKinks>0) {
111       usedKink = new Bool_t[nKinks];
112       for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
113     }
114
115     // Access to the AOD container of vertices
116     TClonesArray &vertices = *(aod->GetVertices());
117     Int_t jVertices=0;
118
119     // Access to the AOD container of tracks
120     TClonesArray &tracks = *(aod->GetTracks());
121     Int_t jTracks=0; 
122   
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();
126       
127     vtx->GetXYZ(pos); // position
128     vtx->GetCovMatrix(covVtx); //covariance matrix
129
130     AliAODVertex * primary = new(vertices[jVertices++])
131       AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
132          
133     // Create vertices starting from the most complex objects
134       
135     // Cascades
136     for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
137       AliESDcascade *cascade = esd->GetCascade(nCascade);
138       
139       cascade->GetXYZ(pos[0], pos[1], pos[2]);
140       cascade->GetPosCovXi(covVtx);
141      
142       // Add the cascade vertex
143       AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
144                                                                         covVtx,
145                                                                         cascade->GetChi2Xi(), // = chi2/NDF since NDF = 2*2-3
146                                                                         primary,
147                                                                         nCascade,
148                                                                         AliAODVertex::kCascade);
149
150       primary->AddDaughter(vcascade);
151
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
155
156       Int_t posFromV0 = cascade->GetPindex();
157       Int_t negFromV0 = cascade->GetNindex();
158
159
160       AliESDv0 * v0 = 0x0;
161       Int_t indV0 = -1;
162
163       for (Int_t iV0=0; iV0<nV0s; ++iV0) {
164
165         v0 = esd->GetV0(iV0);
166         Int_t posV0 = v0->GetPindex();
167         Int_t negV0 = v0->GetNindex();
168
169         if (posV0==posFromV0 && negV0==negFromV0) {
170           indV0 = iV0;
171           break;
172         }
173       }
174
175       AliAODVertex * vV0FromCascade = 0x0;
176
177       if (indV0>-1 && !usedV0[indV0] ) {
178         
179         // the V0 exists in the array of V0s and is not used
180
181         usedV0[indV0] = kTRUE;
182         
183         v0->GetXYZ(pos[0], pos[1], pos[2]);
184         v0->GetPosCov(covVtx);
185         
186         vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
187                                                                  covVtx,
188                                                                  v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
189                                                                  vcascade,
190                                                                  indV0,
191                                                                  AliAODVertex::kV0);
192       } else {
193
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;
198
199         cascade->GetXYZ(pos[0], pos[1], pos[2]);
200         cascade->GetPosCov(covVtx);
201       
202         vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
203                                                                  covVtx,
204                                                                  v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
205                                                                  vcascade,
206                                                                  indV0,
207                                                                  AliAODVertex::kV0);
208         vcascade->AddDaughter(vV0FromCascade);
209       }
210
211       // Add the positive tracks from the V0
212
213       if (! usedTrack[posFromV0]) {
214
215         usedTrack[posFromV0] = kTRUE;
216
217         AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
218         esdTrack->GetPxPyPz(p);
219         esdTrack->GetXYZ(pos);
220         esdTrack->GetCovarianceXYZPxPyPz(covTr);
221         esdTrack->GetESDpid(pid);
222         
223         vV0FromCascade->AddDaughter(aodTrack =
224                                     new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
225                                            esdTrack->GetLabel(), 
226                                            p, 
227                                            kTRUE,
228                                            pos,
229                                            kFALSE,
230                                            covTr, 
231                                            (Short_t)esdTrack->Charge(),
232                                            esdTrack->GetITSClusterMap(), 
233                                            pid,
234                                            vV0FromCascade,
235                                            kTRUE,  // check if this is right
236                                            kFALSE, // check if this is right
237                                            AliAODTrack::kSecondary)
238                 );
239         aodTrack->ConvertAliPIDtoAODPID();
240       }
241       else {
242         cerr << "Error: event " << iEvent << " cascade " << nCascade
243              << " track " << posFromV0 << " has already been used!" << endl;
244       }
245
246       // Add the negative tracks from the V0
247
248       if (!usedTrack[negFromV0]) {
249         
250         usedTrack[negFromV0] = kTRUE;
251         
252         AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
253         esdTrack->GetPxPyPz(p);
254         esdTrack->GetXYZ(pos);
255         esdTrack->GetCovarianceXYZPxPyPz(covTr);
256         esdTrack->GetESDpid(pid);
257         
258         vV0FromCascade->AddDaughter(aodTrack =
259                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
260                                            esdTrack->GetLabel(),
261                                            p,
262                                            kTRUE,
263                                            pos,
264                                            kFALSE,
265                                            covTr, 
266                                            (Short_t)esdTrack->Charge(),
267                                            esdTrack->GetITSClusterMap(), 
268                                            pid,
269                                            vV0FromCascade,
270                                            kTRUE,  // check if this is right
271                                            kFALSE, // check if this is right
272                                            AliAODTrack::kSecondary)
273                 );
274         aodTrack->ConvertAliPIDtoAODPID();
275       }
276       else {
277         cerr << "Error: event " << iEvent << " cascade " << nCascade
278              << " track " << negFromV0 << " has already been used!" << endl;
279       }
280
281       // Add the bachelor track from the cascade
282
283       Int_t bachelor = cascade->GetBindex();
284       
285       if(!usedTrack[bachelor]) {
286       
287         usedTrack[bachelor] = kTRUE;
288         
289         AliESDtrack *esdTrack = esd->GetTrack(bachelor);
290         esdTrack->GetPxPyPz(p);
291         esdTrack->GetXYZ(pos);
292         esdTrack->GetCovarianceXYZPxPyPz(covTr);
293         esdTrack->GetESDpid(pid);
294
295         vcascade->AddDaughter(aodTrack =
296                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
297                                            esdTrack->GetLabel(),
298                                            p,
299                                            kTRUE,
300                                            pos,
301                                            kFALSE,
302                                            covTr, 
303                                            (Short_t)esdTrack->Charge(),
304                                            esdTrack->GetITSClusterMap(), 
305                                            pid,
306                                            vcascade,
307                                            kTRUE,  // check if this is right
308                                            kFALSE, // check if this is right
309                                            AliAODTrack::kSecondary)
310                 );
311         aodTrack->ConvertAliPIDtoAODPID();
312      }
313       else {
314         cerr << "Error: event " << iEvent << " cascade " << nCascade
315              << " track " << bachelor << " has already been used!" << endl;
316       }
317
318       // Add the primary track of the cascade (if any)
319
320     } // end of the loop on cascades
321     
322     // V0s
323         
324     for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
325
326       if (usedV0[nV0]) continue; // skip if aready added to the AOD
327
328       AliESDv0 *v0 = esd->GetV0(nV0);
329       
330       v0->GetXYZ(pos[0], pos[1], pos[2]);
331       v0->GetPosCov(covVtx);
332
333       AliAODVertex * vV0 = 
334         new(vertices[jVertices++]) AliAODVertex(pos,
335                                                 covVtx,
336                                                 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
337                                                 primary,
338                                                 nV0,
339                                                 AliAODVertex::kV0);
340       primary->AddDaughter(vV0);
341
342       Int_t posFromV0 = v0->GetPindex();
343       Int_t negFromV0 = v0->GetNindex();
344       
345       // Add the positive tracks from the V0
346
347       if (!usedTrack[posFromV0]) {
348         
349         usedTrack[posFromV0] = kTRUE;
350
351         AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
352         esdTrack->GetPxPyPz(p);
353         esdTrack->GetXYZ(pos);
354         esdTrack->GetCovarianceXYZPxPyPz(covTr);
355         esdTrack->GetESDpid(pid);
356         
357         vV0->AddDaughter(aodTrack =
358                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
359                                            esdTrack->GetLabel(), 
360                                            p, 
361                                            kTRUE,
362                                            pos,
363                                            kFALSE,
364                                            covTr, 
365                                            (Short_t)esdTrack->Charge(),
366                                            esdTrack->GetITSClusterMap(), 
367                                            pid,
368                                            vV0,
369                                            kTRUE,  // check if this is right
370                                            kFALSE, // check if this is right
371                                            AliAODTrack::kSecondary)
372                 );
373         aodTrack->ConvertAliPIDtoAODPID();
374       }
375       else {
376         cerr << "Error: event " << iEvent << " V0 " << nV0
377              << " track " << posFromV0 << " has already been used!" << endl;
378       }
379
380       // Add the negative tracks from the V0
381
382       if (!usedTrack[negFromV0]) {
383
384         usedTrack[negFromV0] = kTRUE;
385
386         AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
387         esdTrack->GetPxPyPz(p);
388         esdTrack->GetXYZ(pos);
389         esdTrack->GetCovarianceXYZPxPyPz(covTr);
390         esdTrack->GetESDpid(pid);
391
392         vV0->AddDaughter(aodTrack =
393                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
394                                            esdTrack->GetLabel(),
395                                            p,
396                                            kTRUE,
397                                            pos,
398                                            kFALSE,
399                                            covTr, 
400                                            (Short_t)esdTrack->Charge(),
401                                            esdTrack->GetITSClusterMap(), 
402                                            pid,
403                                            vV0,
404                                            kTRUE,  // check if this is right
405                                            kFALSE, // check if this is right
406                                            AliAODTrack::kSecondary)
407                 );
408         aodTrack->ConvertAliPIDtoAODPID();
409       }
410       else {
411         cerr << "Error: event " << iEvent << " V0 " << nV0
412              << " track " << negFromV0 << " has already been used!" << endl;
413       }
414
415     } // end of the loop on V0s
416     
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
419
420
421     for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
422
423
424       AliESDtrack * esdTrack = esd->GetTrack(iTrack);
425
426       Int_t ikink = esdTrack->GetKinkIndex(0);
427
428       if (ikink) {
429         // Negative kink index: mother, positive: daughter
430
431         // Search for the second track of the kink
432
433         for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
434
435           AliESDtrack * esdTrack1 = esd->GetTrack(jTrack);
436
437           Int_t jkink = esdTrack1->GetKinkIndex(0);
438
439           if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
440
441             // The two tracks are from the same kink
442           
443             if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
444
445             Int_t imother = -1;
446             Int_t idaughter = -1;
447
448             if (ikink<0 && jkink>0) {
449
450               imother = iTrack;
451               idaughter = jTrack;
452             }
453             else if (ikink>0 && jkink<0) {
454
455               imother = jTrack;
456               idaughter = iTrack;
457             }
458             else {
459               cerr << "Error: Wrong combination of kink indexes: "
460               << ikink << " " << jkink << endl;
461               continue;
462             }
463
464             // Add the mother track
465
466             AliAODTrack * mother = NULL;
467
468             if (!usedTrack[imother]) {
469         
470               usedTrack[imother] = kTRUE;
471         
472               AliESDtrack *esdTrack = esd->GetTrack(imother);
473               esdTrack->GetPxPyPz(p);
474               esdTrack->GetXYZ(pos);
475               esdTrack->GetCovarianceXYZPxPyPz(covTr);
476               esdTrack->GetESDpid(pid);
477
478               mother = 
479                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
480                                            esdTrack->GetLabel(),
481                                            p,
482                                            kTRUE,
483                                            pos,
484                                            kFALSE,
485                                            covTr, 
486                                            (Short_t)esdTrack->Charge(),
487                                            esdTrack->GetITSClusterMap(), 
488                                            pid,
489                                            primary,
490                                            kTRUE, // check if this is right
491                                            kTRUE, // check if this is right
492                                            AliAODTrack::kPrimary);
493               primary->AddDaughter(mother);
494               mother->ConvertAliPIDtoAODPID();
495             }
496             else {
497               cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
498               << " track " << imother << " has already been used!" << endl;
499             }
500
501             // Add the kink vertex
502             AliESDkink * kink = esd->GetKink(TMath::Abs(ikink)-1);
503
504             AliAODVertex * vkink = 
505             new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
506                                                     NULL,
507                                                     0.,
508                                                     mother,
509                                                     esdTrack->GetID(), // This is the track ID of the mother's track!
510                                                     AliAODVertex::kKink);
511             // Add the daughter track
512
513             AliAODTrack * daughter = NULL;
514
515             if (!usedTrack[idaughter]) {
516         
517               usedTrack[idaughter] = kTRUE;
518         
519               AliESDtrack *esdTrack = esd->GetTrack(idaughter);
520               esdTrack->GetPxPyPz(p);
521               esdTrack->GetXYZ(pos);
522               esdTrack->GetCovarianceXYZPxPyPz(covTr);
523               esdTrack->GetESDpid(pid);
524
525               daughter = 
526                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
527                                            esdTrack->GetLabel(),
528                                            p,
529                                            kTRUE,
530                                            pos,
531                                            kFALSE,
532                                            covTr, 
533                                            (Short_t)esdTrack->Charge(),
534                                            esdTrack->GetITSClusterMap(), 
535                                            pid,
536                                            vkink,
537                                            kTRUE, // check if this is right
538                                            kTRUE, // check if this is right
539                                            AliAODTrack::kPrimary);
540               vkink->AddDaughter(daughter);
541               daughter->ConvertAliPIDtoAODPID();
542             }
543             else {
544               cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
545               << " track " << idaughter << " has already been used!" << endl;
546             }
547
548
549           }
550         }
551
552       }      
553
554     }
555
556     
557     // Tracks (primary and orphan)
558       
559     for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
560         
561
562       if (usedTrack[nTrack]) continue;
563
564       AliESDtrack *esdTrack = esd->GetTrack(nTrack);
565       esdTrack->GetPxPyPz(p);
566       esdTrack->GetXYZ(pos);
567       esdTrack->GetCovarianceXYZPxPyPz(covTr);
568       esdTrack->GetESDpid(pid);
569
570       Float_t impactXY, impactZ;
571
572       esdTrack->GetImpactParameters(impactXY,impactZ);
573
574       if (impactXY<3) {
575         // track inside the beam pipe
576       
577         primary->AddDaughter(aodTrack =
578             new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
579                                          esdTrack->GetLabel(),
580                                          p,
581                                          kTRUE,
582                                          pos,
583                                          kFALSE,
584                                          covTr, 
585                                          (Short_t)esdTrack->Charge(),
586                                          esdTrack->GetITSClusterMap(), 
587                                          pid,
588                                          primary,
589                                          kTRUE, // check if this is right
590                                          kTRUE, // check if this is right
591                                          AliAODTrack::kPrimary)
592             );
593         aodTrack->ConvertAliPIDtoAODPID();
594       }
595       else {
596         // outside the beam pipe: orphan track
597             aodTrack =
598             new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
599                                          esdTrack->GetLabel(),
600                                          p,
601                                          kTRUE,
602                                          pos,
603                                          kFALSE,
604                                          covTr, 
605                                          (Short_t)esdTrack->Charge(),
606                                          esdTrack->GetITSClusterMap(), 
607                                          pid,
608                                          NULL,
609                                          kFALSE, // check if this is right
610                                          kFALSE, // check if this is right
611                                          AliAODTrack::kOrphan);
612             aodTrack->ConvertAliPIDtoAODPID();
613       } 
614     } // end of loop on tracks
615
616     // muon tracks
617     Int_t nMuTracks = esd->GetNumberOfMuonTracks();
618     for (Int_t nMuTrack = 0; nMuTrack < nMuTracks; ++nMuTrack) {
619       
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();
627       
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.;
630       
631       primary->AddDaughter( aodTrack =
632           new(tracks[jTracks++]) AliAODTrack(0, // no ID provided
633                                              0, // no label provided
634                                              p,
635                                              kTRUE,
636                                              pos,
637                                              kFALSE,
638                                              NULL, // no covariance matrix provided
639                                              esdMuTrack->Charge(),
640                                              0, // ITSClusterMap is set below
641                                              pid,
642                                              primary,
643                                              kFALSE,  // muon tracks are not used to fit the primary vtx
644                                              kFALSE,  // not used for vertex fit
645                                              AliAODTrack::kPrimary)
646           );
647         aodTrack->SetHitsPatternInTrigCh(esdMuTrack->GetHitsPatternInTrigCh());
648         Int_t track2Trigger = esdMuTrack->GetMatchTrigger();
649         aodTrack->SetMatchTrigger(track2Trigger);
650         if (track2Trigger) 
651           aodTrack->SetChi2MatchTrigger(esdMuTrack->GetChi2MatchTrigger());
652         else 
653           aodTrack->SetChi2MatchTrigger(0.);
654     }
655     
656     // Access to the AOD container of clusters
657     TClonesArray &clusters = *(aod->GetClusters());
658     Int_t jClusters=0;
659
660     // Calo Clusters
661     Int_t nClusters    = esd->GetNumberOfCaloClusters();
662
663     for (Int_t iClust=0; iClust<nClusters; ++iClust) {
664
665       AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
666
667       Int_t id = cluster->GetID();
668       Int_t label = -1;
669       Float_t energy = cluster->E();
670       cluster->GetPosition(posF);
671       AliAODVertex *prodVertex = primary;
672       AliAODTrack *primTrack = NULL;
673       Char_t ttype=AliAODCluster::kUndef;
674
675       if (cluster->IsPHOS()) ttype=AliAODCluster::kPHOSNeutral;
676       else if (cluster->IsEMCAL()) {
677
678         if (cluster->GetClusterType() == AliESDCaloCluster::kPseudoCluster)
679           ttype = AliAODCluster::kEMCALPseudoCluster;
680         else
681           ttype = AliAODCluster::kEMCALClusterv1;
682
683       }
684       
685       new(clusters[jClusters++]) AliAODCluster(id,
686                                                label,
687                                                energy,
688                                                pos,
689                                                NULL, // no covariance matrix provided
690                                                NULL, // no pid for clusters provided
691                                                prodVertex,
692                                                primTrack,
693                                                ttype);
694
695     } // end of loop on calo clusters
696
697     // tracklets
698     const AliMultiplicity *mult = esd->GetMultiplicity();
699     if (mult) {
700       if (mult->GetNumberOfTracklets()>0) {
701         aod->GetTracklets()->CreateContainer(mult->GetNumberOfTracklets());
702
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));
705         }
706       }
707     } else {
708       Printf("ERROR: AliMultiplicity could not be retrieved from ESD");
709     }
710
711     delete [] usedTrack;
712     delete [] usedV0;
713     delete [] usedKink;
714
715     // fill the tree for this event
716     aodTree->Fill();
717   } // end of event loop
718   
719   aodTree->GetUserInfo()->Add(aod);
720
721   // close ESD file
722   inFile->Close();
723   
724   // write the tree to the specified file
725   outFile = aodTree->GetCurrentFile();
726   outFile->cd();
727   aodTree->Write();
728   outFile->Close();
729
730 }