]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliESD.cxx
CreateAOD() member function added.
[u/mrichter/AliRoot.git] / STEER / AliESD.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 //-----------------------------------------------------------------
19 //           Implementation of the ESD class
20 //   This is the class to deal with during the phisical analysis of data
21 //   This class is generated directly by the reconstruction methods
22 //      Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
23 //-----------------------------------------------------------------
24
25 #include "AliESD.h"
26 #include "AliESDfriend.h"
27
28 #include "AliAODEvent.h"
29 #include "AliAODHeader.h"
30 #include "AliAODVertex.h"
31 #include "AliAODTrack.h"
32 #include "AliAODCluster.h"
33
34
35 ClassImp(AliESD)
36
37 //______________________________________________________________________________
38 AliESD::AliESD():
39   fEventNumberInFile(0),
40   fBunchCrossNumber(0),
41   fOrbitNumber(0),
42   fPeriodNumber(0),
43   fRunNumber(0),
44   fTimeStamp(0),
45   fEventType(0),
46   fTriggerMask(0),
47   fTriggerCluster(0),
48   fRecoVersion(0),
49   fMagneticField(0),
50   fZDCN1Energy(0),
51   fZDCP1Energy(0),
52   fZDCN2Energy(0),
53   fZDCP2Energy(0),
54   fZDCEMEnergy(0),
55   fZDCParticipants(0),
56   fT0zVertex(0),
57   fSPDVertex(),
58   fPrimaryVertex(),
59   fSPDMult(),
60   fT0timeStart(0),
61   fTracks("AliESDtrack",15000),
62   fHLTConfMapTracks("AliESDHLTtrack",25000),
63   fHLTHoughTracks("AliESDHLTtrack",15000),
64   fMuonTracks("AliESDMuonTrack",30),
65   fPmdTracks("AliESDPmdTrack",3000),
66   fTrdTracks("AliESDTrdTrack",300),
67   fV0s("AliESDv0",200),  
68   fCascades("AliESDcascade",20),
69   fKinks("AliESDkink",4000),
70   fCaloClusters("AliESDCaloCluster",10000),
71   fEMCALClusters(0), 
72   fFirstEMCALCluster(-1),
73   fEMCALTriggerPosition(0x0),
74   fEMCALTriggerAmplitudes(0x0),
75   fPHOSClusters(0), 
76   fFirstPHOSCluster(-1),
77   fPHOSTriggerPosition(0x0),
78   fPHOSTriggerAmplitudes(0x0),
79   fESDFMD(0x0),
80   fESDVZERO(0x0),
81   fErrorLogs("AliRawDataErrorLog",5)
82
83 {
84   for (Int_t i=0; i<24; i++) {
85     fT0time[i] = 0;
86     fT0amplitude[i] = 0;
87   }
88   for (Int_t i=0; i<2; i++) fDiamondXY[i]=0.;
89   for (Int_t i=0; i<3; i++) fDiamondCovXY[i]=0.;
90 }
91 //______________________________________________________________________________
92 AliESD::AliESD(const AliESD& esd):
93   TObject(esd),
94   fEventNumberInFile(esd.fEventNumberInFile),
95   fBunchCrossNumber(esd.fBunchCrossNumber),
96   fOrbitNumber(esd.fOrbitNumber),
97   fPeriodNumber(esd.fPeriodNumber),
98   fRunNumber(esd.fRunNumber),
99   fTimeStamp(esd.fTimeStamp),
100   fEventType(esd.fEventType),
101   fTriggerMask(esd.fTriggerMask),
102   fTriggerCluster(esd.fTriggerCluster),
103   fRecoVersion(esd.fRecoVersion),
104   fMagneticField(esd.fMagneticField),
105   fZDCN1Energy(esd.fZDCN1Energy),
106   fZDCP1Energy(esd.fZDCP1Energy),
107   fZDCN2Energy(esd.fZDCN2Energy),
108   fZDCP2Energy(esd.fZDCP2Energy),
109   fZDCEMEnergy(esd.fZDCEMEnergy),
110   fZDCParticipants(esd.fZDCParticipants),
111   fT0zVertex(esd.fT0zVertex),
112   fSPDVertex(esd.fSPDVertex),
113   fPrimaryVertex(esd.fPrimaryVertex),
114   fSPDMult(esd.fSPDMult),
115   fT0timeStart(esd.fT0timeStart),
116   fTracks(*((TClonesArray*)esd.fTracks.Clone())),
117   fHLTConfMapTracks(*((TClonesArray*)esd.fHLTConfMapTracks.Clone())),
118   fHLTHoughTracks(*((TClonesArray*)esd.fHLTHoughTracks.Clone())),
119   fMuonTracks(*((TClonesArray*)esd.fMuonTracks.Clone())),
120   fPmdTracks(*((TClonesArray*)esd.fPmdTracks.Clone())),
121   fTrdTracks(*((TClonesArray*)esd.fTrdTracks.Clone())),
122   fV0s(*((TClonesArray*)esd.fV0s.Clone())),  
123   fCascades(*((TClonesArray*)esd.fCascades.Clone())),
124   fKinks(*((TClonesArray*)esd.fKinks.Clone())),
125   fCaloClusters(*((TClonesArray*)esd.fCaloClusters.Clone())),
126   fEMCALClusters(esd.fEMCALClusters), 
127   fFirstEMCALCluster(esd.fFirstEMCALCluster),
128   fEMCALTriggerPosition(esd. fEMCALTriggerPosition),
129   fEMCALTriggerAmplitudes(esd.fEMCALTriggerAmplitudes),
130   fPHOSClusters(esd.fPHOSClusters), 
131   fFirstPHOSCluster(esd.fFirstPHOSCluster),
132   fPHOSTriggerPosition(esd.fPHOSTriggerPosition),
133   fPHOSTriggerAmplitudes(esd.fPHOSTriggerAmplitudes),
134   fESDFMD(esd.fESDFMD),
135   fESDVZERO(esd.fESDVZERO),
136   fErrorLogs(*((TClonesArray*)esd.fErrorLogs.Clone()))
137 {
138   for (Int_t i=0; i<24; i++) {
139     fT0time[i] = esd.fT0time[i];
140     fT0amplitude[i] = esd.fT0amplitude[i];
141   }
142   for (Int_t i=0; i<2; i++) fDiamondXY[i]=esd.fDiamondXY[i];
143   for (Int_t i=0; i<3; i++) fDiamondCovXY[i]=esd.fDiamondCovXY[i];
144 }
145
146 //______________________________________________________________________________
147 AliESD & AliESD::operator=(const AliESD& source) {
148
149   // Assignment operator
150
151   if(&source == this) return *this;
152
153   fEventNumberInFile = source.fEventNumberInFile;
154   fBunchCrossNumber = source.fBunchCrossNumber;
155   fOrbitNumber = source.fOrbitNumber;
156   fPeriodNumber = source.fPeriodNumber;
157   fRunNumber = source.fRunNumber;
158   fTimeStamp   = source.fTimeStamp;
159   fEventType   = source.fEventType;
160   fTriggerMask = source.fTriggerMask;
161   fTriggerCluster = source.fTriggerCluster;
162   fRecoVersion = source.fRecoVersion;
163   fMagneticField = source.fMagneticField;
164   fZDCN1Energy = source.fZDCN1Energy;
165   fZDCP1Energy = source.fZDCP1Energy;
166   fZDCN2Energy = source.fZDCN2Energy;
167   fZDCP2Energy = source.fZDCP2Energy;
168   fZDCEMEnergy = source.fZDCEMEnergy;
169   fZDCParticipants = source.fZDCParticipants;
170   fT0zVertex = source.fT0zVertex;
171   fSPDVertex = source.fSPDVertex;
172   fPrimaryVertex = source.fPrimaryVertex;
173   fSPDMult = source.fSPDMult;
174   fT0timeStart = source.fT0timeStart;
175   fTracks = *((TClonesArray*)source.fTracks.Clone());
176   fHLTConfMapTracks = *((TClonesArray*)source.fHLTConfMapTracks.Clone());
177   fHLTHoughTracks = *((TClonesArray*)source.fHLTHoughTracks.Clone());
178   fMuonTracks = *((TClonesArray*)source.fMuonTracks.Clone());
179   fPmdTracks = *((TClonesArray*)source.fPmdTracks.Clone());
180   fTrdTracks = *((TClonesArray*)source.fTrdTracks.Clone());
181   fV0s = *((TClonesArray*)source.fV0s.Clone());
182   fCascades = *((TClonesArray*)source.fCascades.Clone());
183   fKinks = *((TClonesArray*)source.fKinks.Clone());
184   fCaloClusters = *((TClonesArray*)source.fCaloClusters.Clone());
185   fEMCALClusters = source.fEMCALClusters;
186   fFirstEMCALCluster = source.fFirstEMCALCluster;
187   fPHOSClusters = source.fPHOSClusters;
188   fFirstPHOSCluster = source.fFirstPHOSCluster;
189   fESDFMD = source.fESDFMD;
190   fESDVZERO = source.fESDVZERO;
191   fEMCALTriggerPosition=source. fEMCALTriggerPosition;
192   fEMCALTriggerAmplitudes=source.fEMCALTriggerAmplitudes;
193   fPHOSTriggerPosition=source.fPHOSTriggerPosition;
194   fPHOSTriggerAmplitudes=source.fPHOSTriggerAmplitudes;
195   fErrorLogs = *((TClonesArray*)source.fErrorLogs.Clone());
196
197   for (Int_t i=0; i<24; i++) {
198     fT0time[i] = source.fT0time[i];
199     fT0amplitude[i] = source.fT0amplitude[i];
200   }
201   for (Int_t i=0; i<2; i++) fDiamondXY[i]=source.fDiamondXY[i];
202   for (Int_t i=0; i<3; i++) fDiamondCovXY[i]=source.fDiamondCovXY[i];
203
204   return *this;
205
206 }
207
208
209 //______________________________________________________________________________
210 AliESD::~AliESD()
211 {
212   //
213   // Standard destructor
214   //
215   fTracks.Delete();
216   fHLTConfMapTracks.Delete();
217   fHLTHoughTracks.Delete();
218   fMuonTracks.Delete();
219   fPmdTracks.Delete();
220   fTrdTracks.Delete();
221   fV0s.Delete();
222   fCascades.Delete();
223   fKinks.Delete();
224   fCaloClusters.Delete();
225   delete fESDFMD;
226   delete fESDVZERO;
227 //   fEMCALTriggerPosition->Delete();
228 //   fEMCALTriggerAmplitudes->Delete();
229 //   fPHOSTriggerPosition->Delete();
230 //   fPHOSTriggerAmplitudes->Delete();
231 //   delete fEMCALTriggerPosition;
232 //   delete fEMCALTriggerAmplitudes;
233 //   delete fPHOSTriggerPosition;
234 //   delete fPHOSTriggerAmplitudes;
235   fErrorLogs.Delete();
236
237 }
238
239 //______________________________________________________________________________
240 void AliESD::Reset()
241 {
242   fEventNumberInFile=0;
243   fBunchCrossNumber=0;
244   fOrbitNumber=0;
245   fPeriodNumber=0;
246   fRunNumber=0;
247   fTimeStamp = 0;
248   fEventType = 0;
249   fTriggerMask=0;
250   fTriggerCluster=0;
251   fRecoVersion=0;
252   fMagneticField=0;
253   fZDCN1Energy=0;
254   fZDCP1Energy=0;
255   fZDCN2Energy=0;
256   fZDCP2Energy=0;
257   fZDCEMEnergy=0;
258   fZDCParticipants=0;
259   fT0zVertex=0;
260   fT0timeStart = 0;
261   new (&fSPDVertex) AliESDVertex();
262   new (&fPrimaryVertex) AliESDVertex();
263   new (&fSPDMult) AliMultiplicity();
264   fTracks.Clear();
265   fHLTConfMapTracks.Clear();
266   fHLTHoughTracks.Clear();
267   fMuonTracks.Clear();
268   fPmdTracks.Clear();
269   fTrdTracks.Clear();
270   fV0s.Clear();
271   fCascades.Clear();
272   fCaloClusters.Clear();
273   fEMCALClusters=0; 
274   fFirstEMCALCluster=-1; 
275   fPHOSClusters=0; 
276   fFirstPHOSCluster=-1; 
277   if (fESDFMD) fESDFMD->Clear();
278 //   fEMCALTriggerPosition->Clear();
279 //   fEMCALTriggerAmplitudes->Clear();
280 //   fPHOSTriggerPosition->Clear();
281 //   fPHOSTriggerAmplitudes->Clear();
282   fErrorLogs.Clear();
283 }
284
285 Int_t AliESD::AddV0(const AliESDv0 *v) {
286   //
287   // Add V0
288   //
289     Int_t idx=fV0s.GetEntriesFast();
290     new(fV0s[idx]) AliESDv0(*v);
291     return idx;
292 }  
293
294 //______________________________________________________________________________
295 void AliESD::Print(Option_t *) const 
296 {
297   //
298   // Print header information of the event
299   //
300   printf("ESD run information\n");
301   printf("Event # in file %d Bunch crossing # %d Orbit # %d Period # %d Run # %d Trigger %lld Magnetic field %f \n",
302          GetEventNumberInFile(),
303          GetBunchCrossNumber(),
304          GetOrbitNumber(),
305          GetPeriodNumber(),
306          GetRunNumber(),
307          GetTriggerMask(),
308          GetMagneticField() );
309     printf("Vertex: (%.4f +- %.4f, %.4f +- %.4f, %.4f +- %.4f) cm\n",
310            fPrimaryVertex.GetXv(), fPrimaryVertex.GetXRes(),
311            fPrimaryVertex.GetYv(), fPrimaryVertex.GetYRes(),
312            fPrimaryVertex.GetZv(), fPrimaryVertex.GetZRes());
313     printf("Mean vertex in RUN: X=%.4f Y=%.4f cm\n",
314            GetDiamondX(),GetDiamondY());
315     printf("SPD Multiplicity. Number of tracklets %d \n",
316            fSPDMult.GetNumberOfTracklets());
317   printf("Event from reconstruction version %d \n",fRecoVersion);
318   printf("Number of tracks: \n");
319   printf("                 charged   %d\n", GetNumberOfTracks());
320   printf("                 hlt CF    %d\n", GetNumberOfHLTConfMapTracks());
321   printf("                 hlt HT    %d\n", GetNumberOfHLTHoughTracks());
322   printf("                 muon      %d\n", GetNumberOfMuonTracks());
323   printf("                 pmd       %d\n", GetNumberOfPmdTracks());
324   printf("                 trd       %d\n", GetNumberOfTrdTracks());
325   printf("                 v0        %d\n", GetNumberOfV0s());
326   printf("                 cascades  %d\n", GetNumberOfCascades());
327   printf("                 kinks     %d\n", GetNumberOfKinks());
328   printf("                 CaloClusters %d\n", GetNumberOfCaloClusters());
329   printf("                 phos      %d\n", GetNumberOfPHOSClusters());
330   printf("                 emcal     %d\n", GetNumberOfEMCALClusters());
331   printf("                 FMD       %s\n", (fESDFMD ? "yes" : "no"));
332   printf("                 VZERO     %s\n", (fESDVZERO ? "yes" : "no"));
333 }
334
335 void AliESD::SetESDfriend(const AliESDfriend *ev) {
336   //
337   // Attaches the complementary info to the ESD
338   //
339   if (!ev) return;
340
341   Int_t ntrk=ev->GetNumberOfTracks();
342
343   for (Int_t i=0; i<ntrk; i++) {
344     const AliESDfriendTrack *f=ev->GetTrack(i);
345     GetTrack(i)->SetFriendTrack(f);
346   }
347 }
348
349 void AliESD::GetESDfriend(AliESDfriend *ev) const {
350   //
351   // Extracts the complementary info from the ESD
352   //
353   if (!ev) return;
354
355   Int_t ntrk=GetNumberOfTracks();
356
357   for (Int_t i=0; i<ntrk; i++) {
358     const AliESDtrack *t=GetTrack(i);
359     const AliESDfriendTrack *f=t->GetFriendTrack();
360     ev->AddTrack(f);
361   }
362 }
363
364 AliAODEvent *AliESD::CreateAOD() const {
365   //
366   // Creates and returns the standard AOD from the ESD.
367   // Make sure to delete it outside of this function!
368   //
369   
370   // create an AliAOD object 
371   AliAODEvent *aod = new AliAODEvent();
372   aod->CreateStdContent();
373
374   // set arrays and pointers
375   Float_t posF[3];
376   Double_t pos[3];
377   Double_t p[3];
378   Double_t covVtx[6];
379   Double_t covTr[21];
380   Double_t pid[10];
381   
382   // Multiplicity information needed by the header (to be revised!)
383   Int_t nTracks   = GetNumberOfTracks();
384   Int_t nPosTracks = 0;
385   for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) 
386     if (GetTrack(iTrack)->GetSign()> 0) nPosTracks++;
387   
388   // create the header
389   aod->AddHeader(new AliAODHeader(GetRunNumber(),
390                                   GetBunchCrossNumber(),
391                                   GetOrbitNumber(),
392                                   GetPeriodNumber(),
393                                   nTracks,
394                                   nPosTracks,
395                                   nTracks-nPosTracks,
396                                   GetMagneticField(),
397                                   -999., // fill muon magnetic field
398                                   -999., // centrality; to be filled, still
399                                   GetZDCN1Energy(),
400                                   GetZDCP1Energy(),
401                                   GetZDCN2Energy(),
402                                   GetZDCP2Energy(),
403                                   GetZDCEMEnergy(),
404                                   GetTriggerMask(),
405                                   GetTriggerCluster(),
406                                   GetEventType()));
407   
408   Int_t nV0s      = GetNumberOfV0s();
409   Int_t nCascades = GetNumberOfCascades();
410   Int_t nKinks    = GetNumberOfKinks();
411   Int_t nVertices = nV0s + nCascades + nKinks;
412   
413   aod->ResetStd(nTracks, nVertices);
414   AliAODTrack *aodTrack;
415   
416   // Array to take into account the tracks already added to the AOD
417   Bool_t * usedTrack = NULL;
418   if (nTracks>0) {
419     usedTrack = new Bool_t[nTracks];
420     for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
421   }
422   // Array to take into account the V0s already added to the AOD
423   Bool_t * usedV0 = NULL;
424   if (nV0s>0) {
425     usedV0 = new Bool_t[nV0s];
426     for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
427   }
428   // Array to take into account the kinks already added to the AOD
429   Bool_t * usedKink = NULL;
430   if (nKinks>0) {
431     usedKink = new Bool_t[nKinks];
432     for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
433   }
434   
435   // Access to the AOD container of vertices
436   TClonesArray &vertices = *(aod->GetVertices());
437   Int_t jVertices=0;
438   
439   // Access to the AOD container of tracks
440   TClonesArray &tracks = *(aod->GetTracks());
441   Int_t jTracks=0; 
442   
443   // Add primary vertex. The primary tracks will be defined
444   // after the loops on the composite objects (V0, cascades, kinks)
445   const AliESDVertex *vtx = GetPrimaryVertex();
446   
447   vtx->GetXYZ(pos); // position
448   vtx->GetCovMatrix(covVtx); //covariance matrix
449   
450   AliAODVertex * primary = new(vertices[jVertices++])
451     AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, AliAODVertex::kPrimary);
452   
453   // Create vertices starting from the most complex objects
454   
455   // Cascades
456   for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
457     AliESDcascade *cascade = GetCascade(nCascade);
458     
459     cascade->GetXYZ(pos[0], pos[1], pos[2]);
460     cascade->GetPosCovXi(covVtx);
461     
462     // Add the cascade vertex
463     AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
464                                                                       covVtx,
465                                                                       cascade->GetChi2Xi(), // = chi2/NDF since NDF = 2*2-3
466                                                                       primary,
467                                                                       AliAODVertex::kCascade);
468     
469     primary->AddDaughter(vcascade);
470     
471     // Add the V0 from the cascade. The ESD class have to be optimized...
472     // Now we have to search for the corresponding Vo in the list of V0s
473     // using the indeces of the positive and negative tracks
474     
475     Int_t posFromV0 = cascade->GetPindex();
476     Int_t negFromV0 = cascade->GetNindex();
477     
478     AliESDv0 * v0 = 0x0;
479     Int_t indV0 = -1;
480     
481     for (Int_t iV0=0; iV0<nV0s; ++iV0) {
482       
483       v0 = GetV0(iV0);
484       Int_t posV0 = v0->GetPindex();
485       Int_t negV0 = v0->GetNindex();
486       
487       if (posV0==posFromV0 && negV0==negFromV0) {
488         indV0 = iV0;
489         break;
490       }
491     }
492     
493     AliAODVertex * vV0FromCascade = 0x0;
494     
495     if (indV0>-1 && !usedV0[indV0] ) {
496       
497       // the V0 exists in the array of V0s and is not used
498       
499       usedV0[indV0] = kTRUE;
500       
501       v0->GetXYZ(pos[0], pos[1], pos[2]);
502       v0->GetPosCov(covVtx);
503       
504       vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
505                                                                covVtx,
506                                                                v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
507                                                                vcascade,
508                                                                AliAODVertex::kV0);
509     } else {
510       
511       // the V0 doesn't exist in the array of V0s or was used
512       printf("Error: cascade %d. The V0 %d doesn't exist in the array of V0s or was used!\n", nCascade, indV0);
513       cascade->GetXYZ(pos[0], pos[1], pos[2]);
514       cascade->GetPosCov(covVtx);
515       
516       vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
517                                                                covVtx,
518                                                                v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
519                                                                vcascade,
520                                                                AliAODVertex::kV0);
521       vcascade->AddDaughter(vV0FromCascade);
522     }
523     
524     // Add the positive tracks from the V0
525     
526     if (! usedTrack[posFromV0]) {
527       
528       usedTrack[posFromV0] = kTRUE;
529       
530       AliESDtrack *esdTrack = GetTrack(posFromV0);
531       esdTrack->GetPxPyPz(p);
532       esdTrack->GetXYZ(pos);
533       esdTrack->GetCovarianceXYZPxPyPz(covTr);
534       esdTrack->GetESDpid(pid);
535       
536       vV0FromCascade->AddDaughter(
537            aodTrack = new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
538                                                          esdTrack->GetLabel(), 
539                                                          p, 
540                                                          kTRUE,
541                                                          pos,
542                                                          kFALSE,
543                                                          covTr, 
544                                                          (Short_t)esdTrack->GetSign(),
545                                                          esdTrack->GetITSClusterMap(), 
546                                                          pid,
547                                                          vV0FromCascade,
548                                                          kTRUE,  // check if this is right
549                                                          kFALSE, // check if this is right
550                                                          AliAODTrack::kSecondary)
551            );
552       aodTrack->ConvertAliPIDtoAODPID();
553     }
554     else {
555       printf("Error: cascade %d track %d has already been used!\n", nCascade, posFromV0);
556     }
557     
558     // Add the negative tracks from the V0
559     
560     if (!usedTrack[negFromV0]) {
561       
562       usedTrack[negFromV0] = kTRUE;
563       
564       AliESDtrack *esdTrack = GetTrack(negFromV0);
565       esdTrack->GetPxPyPz(p);
566       esdTrack->GetXYZ(pos);
567       esdTrack->GetCovarianceXYZPxPyPz(covTr);
568       esdTrack->GetESDpid(pid);
569       
570       vV0FromCascade->AddDaughter(
571            aodTrack = new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
572                                                          esdTrack->GetLabel(),
573                                                          p,
574                                                          kTRUE,
575                                                          pos,
576                                                          kFALSE,
577                                                          covTr, 
578                                                          (Short_t)esdTrack->GetSign(),
579                                                          esdTrack->GetITSClusterMap(), 
580                                                          pid,
581                                                          vV0FromCascade,
582                                                          kTRUE,  // check if this is right
583                                                          kFALSE, // check if this is right
584                                                          AliAODTrack::kSecondary)
585            );
586       aodTrack->ConvertAliPIDtoAODPID();
587     }
588     else {
589       printf("Error: cascade %d track %d has already been used!\n", nCascade,  negFromV0);
590     }
591     
592     // Add the bachelor track from the cascade
593     
594     Int_t bachelor = cascade->GetBindex();
595     
596     if(!usedTrack[bachelor]) {
597       
598       usedTrack[bachelor] = kTRUE;
599       
600       AliESDtrack *esdTrack = GetTrack(bachelor);
601       esdTrack->GetPxPyPz(p);
602       esdTrack->GetXYZ(pos);
603       esdTrack->GetCovarianceXYZPxPyPz(covTr);
604       esdTrack->GetESDpid(pid);
605       
606       vcascade->AddDaughter(
607        aodTrack = new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
608                                                      esdTrack->GetLabel(),
609                                                      p,
610                                                      kTRUE,
611                                                      pos,
612                                                      kFALSE,
613                                                      covTr, 
614                                                      (Short_t)esdTrack->GetSign(),
615                                                      esdTrack->GetITSClusterMap(), 
616                                                      pid,
617                                                      vcascade,
618                                                      kTRUE,  // check if this is right
619                                                      kFALSE, // check if this is right
620                                                      AliAODTrack::kSecondary)
621        );
622       aodTrack->ConvertAliPIDtoAODPID();
623     }
624     else {
625       printf("Error: cascade %d track %d has already been used!\n", nCascade, bachelor);
626     }
627     
628     // Add the primary track of the cascade (if any)
629     
630   } // end of the loop on cascades
631   
632     // V0s
633   
634   for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
635     
636     if (usedV0[nV0]) continue; // skip if aready added to the AOD
637     
638     AliESDv0 *v0 = GetV0(nV0);
639     
640     v0->GetXYZ(pos[0], pos[1], pos[2]);
641     v0->GetPosCov(covVtx);
642     
643     AliAODVertex * vV0 = 
644       new(vertices[jVertices++]) AliAODVertex(pos,
645                                               covVtx,
646                                               v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
647                                               primary,
648                                               AliAODVertex::kV0);
649     primary->AddDaughter(vV0);
650     
651     Int_t posFromV0 = v0->GetPindex();
652     Int_t negFromV0 = v0->GetNindex();
653     
654     // Add the positive tracks from the V0
655     
656     if (!usedTrack[posFromV0]) {
657       
658       usedTrack[posFromV0] = kTRUE;
659       
660       AliESDtrack *esdTrack = GetTrack(posFromV0);
661       esdTrack->GetPxPyPz(p);
662       esdTrack->GetXYZ(pos);
663       esdTrack->GetCovarianceXYZPxPyPz(covTr);
664       esdTrack->GetESDpid(pid);
665       
666       vV0->AddDaughter(
667         aodTrack = new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
668                                                       esdTrack->GetLabel(), 
669                                                       p, 
670                                                       kTRUE,
671                                                       pos,
672                                                       kFALSE,
673                                                       covTr, 
674                                                       (Short_t)esdTrack->GetSign(),
675                                                       esdTrack->GetITSClusterMap(), 
676                                                       pid,
677                                                       vV0,
678                                                       kTRUE,  // check if this is right
679                                                       kFALSE, // check if this is right
680                                                       AliAODTrack::kSecondary)
681         );
682       aodTrack->ConvertAliPIDtoAODPID();
683     }
684     else {
685       printf("Error: V0 %d track %d has already been used!\n", nV0, posFromV0);
686     }
687     
688     // Add the negative tracks from the V0
689     
690     if (!usedTrack[negFromV0]) {
691       
692       usedTrack[negFromV0] = kTRUE;
693       
694       AliESDtrack *esdTrack = GetTrack(negFromV0);
695       esdTrack->GetPxPyPz(p);
696       esdTrack->GetXYZ(pos);
697       esdTrack->GetCovarianceXYZPxPyPz(covTr);
698       esdTrack->GetESDpid(pid);
699       
700       vV0->AddDaughter(
701         aodTrack = new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
702                                                       esdTrack->GetLabel(),
703                                                       p,
704                                                       kTRUE,
705                                                       pos,
706                                                       kFALSE,
707                                                       covTr, 
708                                                       (Short_t)esdTrack->GetSign(),
709                                                       esdTrack->GetITSClusterMap(), 
710                                                       pid,
711                                                       vV0,
712                                                       kTRUE,  // check if this is right
713                                                       kFALSE, // check if this is right
714                                                       AliAODTrack::kSecondary)
715         );
716       aodTrack->ConvertAliPIDtoAODPID();
717     }
718     else {
719       printf("Error: V0 %d track %d has already been used!\n", nV0, negFromV0);
720     }
721     
722   } // end of the loop on V0s
723   
724   // Kinks: it is a big mess the access to the information in the kinks
725   // The loop is on the tracks in order to find the mother and daugther of each kink
726   
727   for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
728     
729     
730     AliESDtrack * esdTrack = GetTrack(iTrack);
731     
732     Int_t ikink = esdTrack->GetKinkIndex(0);
733     
734     if (ikink) {
735       // Negative kink index: mother, positive: daughter
736       
737       // Search for the second track of the kink
738       
739       for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
740         
741         AliESDtrack * esdTrack1 = GetTrack(jTrack);
742         
743         Int_t jkink = esdTrack1->GetKinkIndex(0);
744         
745         if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
746           
747           // The two tracks are from the same kink
748           
749           if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
750           
751           Int_t imother = -1;
752           Int_t idaughter = -1;
753           
754           if (ikink<0 && jkink>0) {
755             
756             imother = iTrack;
757             idaughter = jTrack;
758           }
759           else if (ikink>0 && jkink<0) {
760             
761             imother = jTrack;
762             idaughter = iTrack;
763           }
764           else {
765             printf("Error: Wrong combination of kink indexes: %d %d\n", ikink, jkink);
766             continue;
767           }
768           
769           // Add the mother track
770           
771           AliAODTrack * mother = NULL;
772           
773           if (!usedTrack[imother]) {
774             
775             usedTrack[imother] = kTRUE;
776             
777             AliESDtrack *esdTrack = GetTrack(imother);
778             esdTrack->GetPxPyPz(p);
779             esdTrack->GetXYZ(pos);
780             esdTrack->GetCovarianceXYZPxPyPz(covTr);
781             esdTrack->GetESDpid(pid);
782             
783             mother = 
784               new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
785                                                  esdTrack->GetLabel(),
786                                                  p,
787                                                  kTRUE,
788                                                  pos,
789                                                  kFALSE,
790                                                  covTr, 
791                                                  (Short_t)esdTrack->GetSign(),
792                                                  esdTrack->GetITSClusterMap(), 
793                                                  pid,
794                                                  primary,
795                                                  kTRUE, // check if this is right
796                                                  kTRUE, // check if this is right
797                                                  AliAODTrack::kPrimary);
798             primary->AddDaughter(mother);
799             mother->ConvertAliPIDtoAODPID();
800           }
801           else {
802             printf("Error: kink %d track %d has already been used!\n", TMath::Abs(ikink)-1, imother);
803           }
804           // Add the kink vertex
805           AliESDkink * kink = GetKink(TMath::Abs(ikink)-1);
806           
807           AliAODVertex * vkink = 
808             new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
809                                                     NULL,
810                                                     0.,
811                                                     mother,
812                                                     AliAODVertex::kKink);
813           // Add the daughter track
814           
815           AliAODTrack * daughter = NULL;
816           
817           if (!usedTrack[idaughter]) {
818             
819             usedTrack[idaughter] = kTRUE;
820             
821             AliESDtrack *esdTrack = GetTrack(idaughter);
822             esdTrack->GetPxPyPz(p);
823             esdTrack->GetXYZ(pos);
824             esdTrack->GetCovarianceXYZPxPyPz(covTr);
825             esdTrack->GetESDpid(pid);
826             
827             daughter = 
828               new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
829                                                  esdTrack->GetLabel(),
830                                                  p,
831                                                  kTRUE,
832                                                  pos,
833                                                  kFALSE,
834                                                  covTr, 
835                                                  (Short_t)esdTrack->GetSign(),
836                                                  esdTrack->GetITSClusterMap(), 
837                                                  pid,
838                                                  vkink,
839                                                  kTRUE, // check if this is right
840                                                  kTRUE, // check if this is right
841                                                  AliAODTrack::kPrimary);
842             vkink->AddDaughter(daughter);
843             daughter->ConvertAliPIDtoAODPID();
844           }
845           else {
846             printf("Error: kink %d track %d has already been used!\n", TMath::Abs(ikink)-1, idaughter);
847           }
848           
849         }
850   
851       }
852       
853     }      
854     
855   }
856   
857   // Tracks (primary and orphan)
858   
859   for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
860     
861     
862     if (usedTrack[nTrack]) continue;
863     
864     AliESDtrack *esdTrack = GetTrack(nTrack);
865     esdTrack->GetPxPyPz(p);
866     esdTrack->GetXYZ(pos);
867     esdTrack->GetCovarianceXYZPxPyPz(covTr);
868     esdTrack->GetESDpid(pid);
869     
870     Float_t impactXY, impactZ;
871     
872     esdTrack->GetImpactParameters(impactXY,impactZ);
873     
874     if (impactXY<3) {
875       // track inside the beam pipe
876       
877       primary->AddDaughter(
878         aodTrack = new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
879                                                       esdTrack->GetLabel(),
880                                                       p,
881                                                       kTRUE,
882                                                       pos,
883                                                       kFALSE,
884                                                       covTr, 
885                                                       (Short_t)esdTrack->GetSign(),
886                                                       esdTrack->GetITSClusterMap(), 
887                                                       pid,
888                                                       primary,
889                                                       kTRUE, // check if this is right
890                                                       kTRUE, // check if this is right
891                                                       AliAODTrack::kPrimary)
892         );
893       aodTrack->ConvertAliPIDtoAODPID();
894     }
895     else {
896       // outside the beam pipe: orphan track
897       aodTrack =
898         new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
899                                            esdTrack->GetLabel(),
900                                            p,
901                                            kTRUE,
902                                            pos,
903                                            kFALSE,
904                                            covTr, 
905                                            (Short_t)esdTrack->GetSign(),
906                                            esdTrack->GetITSClusterMap(), 
907                                            pid,
908                                            NULL,
909                                            kFALSE, // check if this is right
910                                            kFALSE, // check if this is right
911                                            AliAODTrack::kOrphan);
912       aodTrack->ConvertAliPIDtoAODPID();
913     }   
914   } // end of loop on tracks
915   
916   // muon tracks
917   Int_t nMuTracks = GetNumberOfMuonTracks();
918   for (Int_t nMuTrack = 0; nMuTrack < nMuTracks; ++nMuTrack) {
919     
920     AliESDMuonTrack *esdMuTrack = GetMuonTrack(nMuTrack);     
921     p[0] = esdMuTrack->Px(); 
922     p[1] = esdMuTrack->Py(); 
923     p[2] = esdMuTrack->Pz();
924     pos[0] = primary->GetX(); 
925     pos[1] = primary->GetY(); 
926     pos[2] = primary->GetZ();
927     
928     // has to be changed once the muon pid is provided by the ESD
929     for (Int_t i = 0; i < 10; pid[i++] = 0.); pid[AliAODTrack::kMuon]=1.;
930     
931     primary->AddDaughter(
932            new(tracks[jTracks++]) AliAODTrack(0, // no ID provided
933                                               0, // no label provided
934                                               p,
935                                               kTRUE,
936                                               pos,
937                                               kFALSE,
938                                               NULL, // no covariance matrix provided
939                                               (Short_t)-99, // no charge provided
940                                               0, // no ITSClusterMap
941                                               pid,
942                                               primary,
943                                               kTRUE,  // check if this is right
944                                               kTRUE,  // not used for vertex fit
945                                               AliAODTrack::kPrimary)
946            );
947   }
948   
949   // Access to the AOD container of clusters
950   TClonesArray &clusters = *(aod->GetClusters());
951   Int_t jClusters=0;
952   
953   // Calo Clusters
954   Int_t nClusters    = GetNumberOfCaloClusters();
955   
956   for (Int_t iClust=0; iClust<nClusters; ++iClust) {
957     
958     AliESDCaloCluster * cluster = GetCaloCluster(iClust);
959     
960     Int_t id = cluster->GetID();
961     Int_t label = -1;
962     Float_t energy = cluster->GetClusterEnergy();
963     cluster->GetGlobalPosition(posF);
964     AliAODVertex *prodVertex = primary;
965     AliAODTrack *primTrack = NULL;
966     Char_t ttype=AliAODCluster::kUndef;
967     
968     if (cluster->IsPHOS()) ttype=AliAODCluster::kPHOSNeutral;
969     else if (cluster->IsEMCAL()) {
970       
971       if (cluster->GetClusterType() == AliESDCaloCluster::kPseudoCluster)
972         ttype = AliAODCluster::kEMCALPseudoCluster;
973       else
974         ttype = AliAODCluster::kEMCALClusterv1;  
975     
976     }
977     
978     new(clusters[jClusters++]) AliAODCluster(id,
979                                              label,
980                                              energy,
981                                              pos,
982                                              NULL, // no covariance matrix provided
983                                              NULL, // no pid for clusters provided
984                                              prodVertex,
985                                              primTrack,
986                                              ttype);
987     
988   } // end of loop on calo clusters
989   
990   delete [] usedTrack;
991   delete [] usedV0;
992   delete [] usedKink;
993   
994   return aod;
995 }