Make full use of newly introduced functionality:
[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 #include <TArrayS.h>
8 #include <TArrayD.h>
9
10 #include "AliAODEvent.h"
11 #include "AliAODHeader.h"
12 #include "AliAODVertex.h"
13 #include "AliAODTrack.h"
14 #include "AliAODCaloCluster.h"
15 #include "AliAODPmdCluster.h"
16 #include "AliAODTracklets.h"
17
18 #include "AliESDEvent.h"
19 #include "AliESDtrack.h"
20 #include "AliESDMuonTrack.h"
21 #include "AliESDVertex.h"
22 #include "AliESDv0.h"
23 #include "AliESDkink.h"
24 #include "AliESDcascade.h"
25 #include "AliESDCaloCluster.h"
26 #include "AliESDPmdTrack.h"
27 #include "AliMultiplicity.h"
28
29 #endif
30
31 void CreateAODfromESD(const char *inFileName = "AliESDs.root",
32                       const char *outFileName = "AliAOD.root") {
33
34   // open input file
35   TFile *inFile = TFile::Open(inFileName, "READ");
36
37   // create an AliAOD object 
38   AliAODEvent *aod = new AliAODEvent();
39   aod->CreateStdContent();
40
41   // open output file
42   TFile *outFile = TFile::Open(outFileName, "RECREATE");
43   outFile->cd();
44
45   // create the tree
46   TTree *aodTree = new TTree("aodTree", "AliAOD tree");
47   aodTree->Branch(aod->GetList());
48
49   // connect to ESD
50   TTree *t = (TTree*) inFile->Get("esdTree");
51   AliESDEvent *esd = new AliESDEvent();
52   esd->ReadFromTree(t);
53
54   Int_t nEvents = t->GetEntries();
55
56   // set arrays and pointers
57   Float_t posF[3];
58   Double_t pos[3];
59   Double_t p[3];
60   Double_t p_pos[3];
61   Double_t p_neg[3];
62   Double_t covVtx[6];
63   Double_t covTr[21];
64   Double_t pid[10];
65
66   // loop over events and fill them
67   for (Int_t iEvent = 0; iEvent < nEvents; ++iEvent) {
68     //cout << "event: " << iEvent << endl;
69     t->GetEntry(iEvent);
70
71     // Multiplicity information needed by the header (to be revised!)
72     Int_t nTracks   = esd->GetNumberOfTracks();
73     Int_t nPosTracks = 0;
74     for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) 
75       if (esd->GetTrack(iTrack)->Charge()> 0) nPosTracks++;
76
77     // Access the header
78     AliAODHeader *header = aod->GetHeader();
79
80     // fill the header
81     header->SetRunNumber       (esd->GetRunNumber()       );
82     header->SetBunchCrossNumber(esd->GetBunchCrossNumber());
83     header->SetOrbitNumber     (esd->GetOrbitNumber()     );
84     header->SetPeriodNumber    (esd->GetPeriodNumber()    );
85     header->SetTriggerMask     (esd->GetTriggerMask()     ); 
86     header->SetTriggerCluster  (esd->GetTriggerCluster()  );
87     header->SetEventType       (esd->GetEventType()       );
88     header->SetMagneticField   (esd->GetMagneticField()   );
89     header->SetZDCN1Energy     (esd->GetZDCN1Energy()     );
90     header->SetZDCP1Energy     (esd->GetZDCP1Energy()     );
91     header->SetZDCN2Energy     (esd->GetZDCN2Energy()     );
92     header->SetZDCP2Energy     (esd->GetZDCP2Energy()     );
93     header->SetZDCEMEnergy     (esd->GetZDCEMEnergy()     );
94     header->SetRefMultiplicity   (nTracks);
95     header->SetRefMultiplicityPos(nPosTracks);
96     header->SetRefMultiplicityNeg(nTracks - nPosTracks);
97     header->SetMuonMagFieldScale(-999.); // FIXME
98     header->SetCentrality(-999.);        // FIXME
99
100     Int_t nV0s      = esd->GetNumberOfV0s();
101     Int_t nCascades = esd->GetNumberOfCascades();
102     Int_t nKinks    = esd->GetNumberOfKinks();
103     Int_t nVertices = nV0s + nCascades + nKinks + 1 /* = prim. vtx*/;
104     Int_t nJets     = 0;
105     Int_t nCaloClus = esd->GetNumberOfCaloClusters();
106     Int_t nFmdClus  = 0;
107     Int_t nPmdClus  = esd->GetNumberOfPmdTracks();
108    
109     aod->ResetStd(nTracks, nVertices, nV0s+nCascades, nJets, nCaloClus, nFmdClus, nPmdClus);
110     
111     // Array to take into account the tracks already added to the AOD
112     Bool_t * usedTrack = NULL;
113     if (nTracks>0) {
114       usedTrack = new Bool_t[nTracks];
115       for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
116     }
117     // Array to take into account the V0s already added to the AOD
118     Bool_t * usedV0 = NULL;
119     if (nV0s>0) {
120       usedV0 = new Bool_t[nV0s];
121       for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
122     }
123     // Array to take into account the kinks already added to the AOD
124     Bool_t * usedKink = NULL;
125     if (nKinks>0) {
126       usedKink = new Bool_t[nKinks];
127       for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
128     }
129     
130     // Access to the AOD container of vertices
131     TClonesArray &vertices = *(aod->GetVertices());
132     Int_t jVertices=0;
133
134     // Access to the AOD container of tracks
135     TClonesArray &tracks = *(aod->GetTracks());
136     Int_t jTracks=0; 
137    
138     // Access to the AOD container of V0s
139     TClonesArray &V0s = *(aod->GetV0s());
140     Int_t jV0s=0;
141     
142     // Add primary vertex. The primary tracks will be defined
143     // after the loops on the composite objects (V0, cascades, kinks)
144     const AliESDVertex *vtx = esd->GetPrimaryVertex();
145       
146     vtx->GetXYZ(pos); // position
147     vtx->GetCovMatrix(covVtx); //covariance matrix
148
149     AliAODVertex * primary = new(vertices[jVertices++])
150       AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
151          
152
153     AliAODTrack *aodTrack = 0x0;
154     
155     // Create vertices starting from the most complex objects
156
157     // Cascades
158     for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
159       AliESDcascade *cascade = esd->GetCascade(nCascade);
160       
161       cascade->GetXYZ(pos[0], pos[1], pos[2]);
162       cascade->GetPosCovXi(covVtx);
163      
164       // Add the cascade vertex
165       AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
166                                                                         covVtx,
167                                                                         cascade->GetChi2Xi(), // = chi2/NDF since NDF = 2*2-3
168                                                                         primary,
169                                                                         nCascade,
170                                                                         AliAODVertex::kCascade);
171
172       primary->AddDaughter(vcascade); // the cascade 'particle' (represented by a vertex) is added as a daughter to the primary vertex
173
174       // Add the V0 from the cascade. The ESD class have to be optimized...
175       // Now we have to search for the corresponding V0 in the list of V0s
176       // using the indeces of the positive and negative tracks
177
178       Int_t posFromV0 = cascade->GetPindex();
179       Int_t negFromV0 = cascade->GetNindex();
180
181
182       AliESDv0 * v0 = 0x0;
183       Int_t indV0 = -1;
184
185       for (Int_t iV0=0; iV0<nV0s; ++iV0) {
186
187         v0 = esd->GetV0(iV0);
188         Int_t posV0 = v0->GetPindex();
189         Int_t negV0 = v0->GetNindex();
190
191         if (posV0==posFromV0 && negV0==negFromV0) {
192           indV0 = iV0;
193           break;
194         }
195       }
196
197       AliAODVertex * vV0FromCascade = 0x0;
198
199       if (indV0>-1 && !usedV0[indV0]) {
200         
201         // the V0 exists in the array of V0s and is not used
202
203         usedV0[indV0] = kTRUE;
204         
205         v0->GetXYZ(pos[0], pos[1], pos[2]);
206         v0->GetPosCov(covVtx);
207         
208         vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
209                                                                  covVtx,
210                                                                  v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
211                                                                  vcascade,
212                                                                  indV0,
213                                                                  AliAODVertex::kV0);
214       } else {
215
216         // the V0 doesn't exist in the array of V0s or was used
217         cerr << "Error: event " << iEvent << " cascade " << nCascade
218              << " The V0 " << indV0 
219              << " doesn't exist in the array of V0s or was used!" << endl;
220
221         cascade->GetXYZ(pos[0], pos[1], pos[2]);
222         cascade->GetPosCov(covVtx);
223       
224         vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
225                                                                  covVtx,
226                                                                  v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
227                                                                  vcascade,
228                                                                  indV0,
229                                                                  AliAODVertex::kV0);
230         vcascade->AddDaughter(vV0FromCascade);
231
232       }
233
234       // Add the positive tracks from the V0
235
236       if (! usedTrack[posFromV0]) {
237
238         usedTrack[posFromV0] = kTRUE;
239
240         AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
241         esdTrack->GetPxPyPz(p_pos);
242         esdTrack->GetXYZ(pos);
243         esdTrack->GetCovarianceXYZPxPyPz(covTr);
244         esdTrack->GetESDpid(pid);
245         
246         vV0FromCascade->AddDaughter(aodTrack =
247                                     new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
248                                            esdTrack->GetLabel(), 
249                                            p_pos, 
250                                            kTRUE,
251                                            pos,
252                                            kFALSE,
253                                            covTr, 
254                                            (Short_t)esdTrack->Charge(),
255                                            esdTrack->GetITSClusterMap(), 
256                                            pid,
257                                            vV0FromCascade,
258                                            kTRUE,  // check if this is right
259                                            kFALSE, // check if this is right
260                                            AliAODTrack::kSecondary)
261                 );
262         aodTrack->ConvertAliPIDtoAODPID();
263       }
264       else {
265         cerr << "Error: event " << iEvent << " cascade " << nCascade
266              << " track " << posFromV0 << " has already been used!" << endl;
267       }
268
269       // Add the negative tracks from the V0
270
271       if (!usedTrack[negFromV0]) {
272         
273         usedTrack[negFromV0] = kTRUE;
274         
275         AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
276         esdTrack->GetPxPyPz(p_neg);
277         esdTrack->GetXYZ(pos);
278         esdTrack->GetCovarianceXYZPxPyPz(covTr);
279         esdTrack->GetESDpid(pid);
280         
281         vV0FromCascade->AddDaughter(aodTrack =
282                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
283                                            esdTrack->GetLabel(),
284                                            p_neg,
285                                            kTRUE,
286                                            pos,
287                                            kFALSE,
288                                            covTr, 
289                                            (Short_t)esdTrack->Charge(),
290                                            esdTrack->GetITSClusterMap(), 
291                                            pid,
292                                            vV0FromCascade,
293                                            kTRUE,  // check if this is right
294                                            kFALSE, // check if this is right
295                                            AliAODTrack::kSecondary)
296                 );
297         aodTrack->ConvertAliPIDtoAODPID();
298       }
299       else {
300         cerr << "Error: event " << iEvent << " cascade " << nCascade
301              << " track " << negFromV0 << " has already been used!" << endl;
302       }
303
304       // add it to the V0 array as well
305       Double_t d0[2] = { -999., -99.};
306       // counting is probably wrong
307       new(V0s[jV0s++]) AliAODv0(vV0FromCascade, -999., -99., p_pos, p_neg, d0); // to be refined
308
309       // Add the bachelor track from the cascade
310
311       Int_t bachelor = cascade->GetBindex();
312       
313       if(!usedTrack[bachelor]) {
314       
315         usedTrack[bachelor] = kTRUE;
316         
317         AliESDtrack *esdTrack = esd->GetTrack(bachelor);
318         esdTrack->GetPxPyPz(p);
319         esdTrack->GetXYZ(pos);
320         esdTrack->GetCovarianceXYZPxPyPz(covTr);
321         esdTrack->GetESDpid(pid);
322
323         vcascade->AddDaughter(aodTrack =
324                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
325                                            esdTrack->GetLabel(),
326                                            p,
327                                            kTRUE,
328                                            pos,
329                                            kFALSE,
330                                            covTr, 
331                                            (Short_t)esdTrack->Charge(),
332                                            esdTrack->GetITSClusterMap(), 
333                                            pid,
334                                            vcascade,
335                                            kTRUE,  // check if this is right
336                                            kFALSE, // check if this is right
337                                            AliAODTrack::kSecondary)
338                 );
339         aodTrack->ConvertAliPIDtoAODPID();
340      }
341       else {
342         cerr << "Error: event " << iEvent << " cascade " << nCascade
343              << " track " << bachelor << " has already been used!" << endl;
344       }
345       
346       // Add the primary track of the cascade (if any)
347       
348     } // end of the loop on cascades
349  
350     // V0s
351         
352     for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
353
354       if (usedV0[nV0]) continue; // skip if aready added to the AOD
355
356       AliESDv0 *v0 = esd->GetV0(nV0); 
357      
358       v0->GetXYZ(pos[0], pos[1], pos[2]);
359       v0->GetPosCov(covVtx);
360
361       AliAODVertex * vV0 = 
362         new(vertices[jVertices++]) AliAODVertex(pos,
363                                                 covVtx,
364                                                 v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
365                                                 primary,
366                                                 nV0,
367                                                 AliAODVertex::kV0);
368       primary->AddDaughter(vV0);
369
370       Int_t posFromV0 = v0->GetPindex();
371       Int_t negFromV0 = v0->GetNindex();
372       
373       // Add the positive tracks from the V0
374
375       if (!usedTrack[posFromV0]) {
376         
377         usedTrack[posFromV0] = kTRUE;
378
379         AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
380         esdTrack->GetPxPyPz(p_pos);
381         esdTrack->GetXYZ(pos);
382         esdTrack->GetCovarianceXYZPxPyPz(covTr);
383         esdTrack->GetESDpid(pid);
384         
385         vV0->AddDaughter(aodTrack =
386                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
387                                            esdTrack->GetLabel(), 
388                                            p_pos, 
389                                            kTRUE,
390                                            pos,
391                                            kFALSE,
392                                            covTr, 
393                                            (Short_t)esdTrack->Charge(),
394                                            esdTrack->GetITSClusterMap(), 
395                                            pid,
396                                            vV0,
397                                            kTRUE,  // check if this is right
398                                            kFALSE, // check if this is right
399                                            AliAODTrack::kSecondary)
400                 );
401         aodTrack->ConvertAliPIDtoAODPID();
402       }
403       else {
404         cerr << "Error: event " << iEvent << " V0 " << nV0
405              << " track " << posFromV0 << " has already been used!" << endl;
406       }
407
408       // Add the negative tracks from the V0
409
410       if (!usedTrack[negFromV0]) {
411
412         usedTrack[negFromV0] = kTRUE;
413
414         AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
415         esdTrack->GetPxPyPz(p_neg);
416         esdTrack->GetXYZ(pos);
417         esdTrack->GetCovarianceXYZPxPyPz(covTr);
418         esdTrack->GetESDpid(pid);
419
420         vV0->AddDaughter(aodTrack =
421                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
422                                            esdTrack->GetLabel(),
423                                            p_neg,
424                                            kTRUE,
425                                            pos,
426                                            kFALSE,
427                                            covTr, 
428                                            (Short_t)esdTrack->Charge(),
429                                            esdTrack->GetITSClusterMap(), 
430                                            pid,
431                                            vV0,
432                                            kTRUE,  // check if this is right
433                                            kFALSE, // check if this is right
434                                            AliAODTrack::kSecondary)
435                 );
436         aodTrack->ConvertAliPIDtoAODPID();
437       }
438       else {
439         cerr << "Error: event " << iEvent << " V0 " << nV0
440              << " track " << negFromV0 << " has already been used!" << endl;
441       }
442
443       // add it to the V0 array as well
444       Double_t d0[2] = { 999., 99.};
445       new(V0s[jV0s++]) AliAODv0(vV0, 999., 99., p_pos, p_neg, d0); // to be refined
446     } // end of the loop on V0s
447     
448     // Kinks: it is a big mess the access to the information in the kinks
449     // The loop is on the tracks in order to find the mother and daugther of each kink
450
451
452     for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
453
454
455       AliESDtrack * esdTrack = esd->GetTrack(iTrack);
456
457       Int_t ikink = esdTrack->GetKinkIndex(0);
458
459       if (ikink) {
460         // Negative kink index: mother, positive: daughter
461
462         // Search for the second track of the kink
463
464         for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
465
466           AliESDtrack * esdTrack1 = esd->GetTrack(jTrack);
467
468           Int_t jkink = esdTrack1->GetKinkIndex(0);
469
470           if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
471
472             // The two tracks are from the same kink
473           
474             if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
475
476             Int_t imother = -1;
477             Int_t idaughter = -1;
478
479             if (ikink<0 && jkink>0) {
480
481               imother = iTrack;
482               idaughter = jTrack;
483             }
484             else if (ikink>0 && jkink<0) {
485
486               imother = jTrack;
487               idaughter = iTrack;
488             }
489             else {
490               cerr << "Error: Wrong combination of kink indexes: "
491               << ikink << " " << jkink << endl;
492               continue;
493             }
494
495             // Add the mother track
496
497             AliAODTrack * mother = NULL;
498
499             if (!usedTrack[imother]) {
500         
501               usedTrack[imother] = kTRUE;
502         
503               AliESDtrack *esdTrack = esd->GetTrack(imother);
504               esdTrack->GetPxPyPz(p);
505               esdTrack->GetXYZ(pos);
506               esdTrack->GetCovarianceXYZPxPyPz(covTr);
507               esdTrack->GetESDpid(pid);
508
509               mother = 
510                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
511                                            esdTrack->GetLabel(),
512                                            p,
513                                            kTRUE,
514                                            pos,
515                                            kFALSE,
516                                            covTr, 
517                                            (Short_t)esdTrack->Charge(),
518                                            esdTrack->GetITSClusterMap(), 
519                                            pid,
520                                            primary,
521                                            kTRUE, // check if this is right
522                                            kTRUE, // check if this is right
523                                            AliAODTrack::kPrimary);
524               primary->AddDaughter(mother);
525               mother->ConvertAliPIDtoAODPID();
526             }
527             else {
528               cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
529               << " track " << imother << " has already been used!" << endl;
530             }
531
532             // Add the kink vertex
533             AliESDkink * kink = esd->GetKink(TMath::Abs(ikink)-1);
534
535             AliAODVertex * vkink = 
536             new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
537                                                     NULL,
538                                                     0.,
539                                                     mother,
540                                                     esdTrack->GetID(), // This is the track ID of the mother's track!
541                                                     AliAODVertex::kKink);
542             // Add the daughter track
543
544             AliAODTrack * daughter = NULL;
545
546             if (!usedTrack[idaughter]) {
547         
548               usedTrack[idaughter] = kTRUE;
549         
550               AliESDtrack *esdTrack = esd->GetTrack(idaughter);
551               esdTrack->GetPxPyPz(p);
552               esdTrack->GetXYZ(pos);
553               esdTrack->GetCovarianceXYZPxPyPz(covTr);
554               esdTrack->GetESDpid(pid);
555
556               daughter = 
557                 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
558                                            esdTrack->GetLabel(),
559                                            p,
560                                            kTRUE,
561                                            pos,
562                                            kFALSE,
563                                            covTr, 
564                                            (Short_t)esdTrack->Charge(),
565                                            esdTrack->GetITSClusterMap(), 
566                                            pid,
567                                            vkink,
568                                            kTRUE, // check if this is right
569                                            kTRUE, // check if this is right
570                                            AliAODTrack::kPrimary);
571               vkink->AddDaughter(daughter);
572               daughter->ConvertAliPIDtoAODPID();
573             }
574             else {
575               cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
576               << " track " << idaughter << " has already been used!" << endl;
577             }
578           }
579         }
580       }
581     }
582
583     // Tracks (primary and orphan)
584     for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {        
585
586       if (usedTrack[nTrack]) continue;
587
588       AliESDtrack *esdTrack = esd->GetTrack(nTrack);
589       esdTrack->GetPxPyPz(p);
590       esdTrack->GetXYZ(pos);
591       esdTrack->GetCovarianceXYZPxPyPz(covTr);
592       esdTrack->GetESDpid(pid);
593
594       Float_t impactXY, impactZ;
595
596       esdTrack->GetImpactParameters(impactXY,impactZ);
597
598       if (impactXY<3.) {
599         // track inside the beam pipe
600       
601         primary->AddDaughter(aodTrack =
602             new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
603                                          esdTrack->GetLabel(),
604                                          p,
605                                          kTRUE,
606                                          pos,
607                                          kFALSE,
608                                          covTr, 
609                                          (Short_t)esdTrack->Charge(),
610                                          esdTrack->GetITSClusterMap(), 
611                                          pid,
612                                          primary,
613                                          kTRUE, // check if this is right
614                                          kTRUE, // check if this is right
615                                          AliAODTrack::kPrimary)
616             );
617         aodTrack->ConvertAliPIDtoAODPID();
618       }
619       else {
620         // outside the beam pipe: orphan track
621         // Don't write them anymore!
622         continue;
623       } 
624     } // end of loop on tracks
625     
626     // muon tracks
627     Int_t nMuTracks = esd->GetNumberOfMuonTracks();
628     for (Int_t nMuTrack = 0; nMuTrack < nMuTracks; ++nMuTrack) {
629       
630       AliESDMuonTrack *esdMuTrack = esd->GetMuonTrack(nMuTrack);     
631       p[0] = esdMuTrack->Px(); 
632       p[1] = esdMuTrack->Py(); 
633       p[2] = esdMuTrack->Pz();
634       pos[0] = primary->GetX(); 
635       pos[1] = primary->GetY(); 
636       pos[2] = primary->GetZ();
637       
638       // has to be changed once the muon pid is provided by the ESD
639       for (Int_t i = 0; i < 10; pid[i++] = 0.); pid[AliAODTrack::kMuon]=1.;
640       
641       primary->AddDaughter(aodTrack =
642           new(tracks[jTracks++]) AliAODTrack(0, // no ID provided
643                                              0, // no label provided
644                                              p,
645                                              kTRUE,
646                                              pos,
647                                              kFALSE,
648                                              NULL, // no covariance matrix provided
649                                              esdMuTrack->Charge(),
650                                              0, // ITSClusterMap is set below
651                                              pid,
652                                              primary,
653                                              kFALSE,  // muon tracks are not used to fit the primary vtx
654                                              kFALSE,  // not used for vertex fit
655                                              AliAODTrack::kPrimary)
656           );
657
658       aodTrack->SetHitsPatternInTrigCh(esdMuTrack->GetHitsPatternInTrigCh());
659       Int_t track2Trigger = esdMuTrack->GetMatchTrigger();
660       aodTrack->SetMatchTrigger(track2Trigger);
661       if (track2Trigger) 
662         aodTrack->SetChi2MatchTrigger(esdMuTrack->GetChi2MatchTrigger());
663       else 
664         aodTrack->SetChi2MatchTrigger(0.);
665     }
666    
667     // Access to the AOD container of PMD clusters
668     TClonesArray &pmdClusters = *(aod->GetPmdClusters());
669     Int_t jPmdClusters=0;
670   
671     for (Int_t iPmd = 0; iPmd < nPmdClus; ++iPmd) {
672       // file pmd clusters, to be revised!
673       AliESDPmdTrack *pmdTrack = esd->GetPmdTrack(iPmd);
674       Int_t nLabel = 0;
675       Int_t *label = 0x0;
676       Double_t pos[3] = { pmdTrack->GetClusterX(), pmdTrack->GetClusterY(), pmdTrack->GetClusterZ() };
677       Double_t pid[9] = { 0., 0., 0., 0., 0., 0., 0., 0., 0. }; // to be revised!
678       // type not set!
679       // assoc cluster not set
680       new(pmdClusters[jPmdClusters++]) AliAODPmdCluster(iPmd, nLabel, label, pmdTrack->GetClusterADC(), pos, pid);
681     }
682
683     // Access to the AOD container of clusters
684     TClonesArray &caloClusters = *(aod->GetCaloClusters());
685     Int_t jClusters=0;
686
687     // Calo Clusters
688     TArrayS EMCCellNumber(15000);
689     TArrayD EMCCellAmplitude(15000);
690     Int_t nEMCCells = 0;
691     const Float_t fEMCAmpScale = 1./500;
692  
693     for (Int_t iClust=0; iClust<nCaloClus; ++iClust) {
694
695       AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
696
697       Int_t id = cluster->GetID();
698       Int_t nLabel = 0;
699       Int_t *label = 0x0;
700       Float_t energy = cluster->E();
701       cluster->GetPosition(posF);
702       Char_t ttype=AliAODCluster::kUndef;
703
704       if (cluster->GetClusterType() == AliESDCaloCluster::kPHOSCluster) {
705         ttype=AliAODCluster::kPHOSNeutral;
706       } 
707       else if (cluster->GetClusterType() == AliESDCaloCluster::kEMCALClusterv1) {
708         ttype = AliAODCluster::kEMCALClusterv1;
709       }
710       else if (cluster->GetClusterType() == AliESDCaloCluster::kEMCALPseudoCluster) {
711         // Collect raw tower info
712         for (Int_t iDig = 0; iDig < cluster->GetNumberOfDigits(); iDig++) {
713           EMCCellNumber[nEMCCells] = cluster->GetDigitIndex()->At(iDig);
714           EMCCellAmplitude[nEMCCells] = fEMCAmpScale*cluster->GetDigitAmplitude()->At(iDig);
715           nEMCCells++;
716         }
717         // don't write cluster data (it's just a pseudo cluster, holding the tower information)
718         continue; 
719       }
720       
721       AliAODCaloCluster *caloCluster = new(caloClusters[jClusters++]) AliAODCaloCluster(id,
722                                                                                         nLabel,
723                                                                                         label,
724                                                                                         energy,
725                                                                                         pos,
726                                                                                         NULL,
727                                                                                         ttype);
728       
729       caloCluster->SetCaloCluster(); // to be refined!
730
731     } // end of loop on calo clusters
732
733     // fill EMC cell info
734     AliAODCaloCells &EMCCells = *(aod->GetCaloCells());
735     EMCCells.CreateContainer(nEMCCells);
736     EMCCells.SetType(AliAODCaloCells::kEMCAL);
737     for (Int_t iCell = 0; iCell < nEMCCells; iCell++) {      
738       EMCCells.SetCell(iCell,EMCCellNumber[iCell],EMCCellAmplitude[iCell]);
739     }
740     EMCCells.Sort();
741
742     // tracklets    
743     AliAODTracklets &SPDTracklets = *(aod->GetTracklets());
744     const AliMultiplicity *mult = esd->GetMultiplicity();
745     if (mult) {
746       if (mult->GetNumberOfTracklets()>0) {
747         SPDTracklets.CreateContainer(mult->GetNumberOfTracklets());
748
749         for (Int_t n=0; n<mult->GetNumberOfTracklets(); n++) {
750           SPDTracklets.SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n));
751         }
752       }
753     } else {
754       Printf("ERROR: AliMultiplicity could not be retrieved from ESD");
755     }
756
757     delete [] usedTrack;
758     delete [] usedV0;
759     delete [] usedKink;
760
761     // fill the tree for this event
762     aodTree->Fill();
763   } // end of event loop
764
765   aodTree->GetUserInfo()->Add(aod);
766
767   // close ESD file
768   inFile->Close();
769
770   // write the tree to the specified file
771   outFile = aodTree->GetCurrentFile();
772   outFile->cd();
773   aodTree->Write();
774   outFile->Close();
775 }