Allow reconnection. Needed for efficient mixing.
[u/mrichter/AliRoot.git] / STEER / AliESDEvent.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 AliESDEvent class
20 //   This is the class to deal with during the physics analysis of data.
21 //   It also ensures the backward compatibility with the old ESD format.
22 /*
23    AliESDEvent *ev= new AliESDEvent();
24    ev->ReadFromTree(esdTree);
25    ...
26     for (Int_t i=0; i<nev; i++) {
27       esdTree->GetEntry(i);
28       if(ev->GetAliESDOld())ev->CopyFromOldESD();
29 */
30 //   The AliESDInputHandler does this automatically for you
31 //
32 // Origin: Christian Klein-Boesing, CERN, Christian.Klein-Boesing@cern.ch
33 //-----------------------------------------------------------------
34
35 #include "TList.h"
36 #include "TRefArray.h"
37 #include <TNamed.h>
38
39 #include "AliESDEvent.h"
40 #include "AliESDfriend.h"
41 #include "AliESDVZERO.h"
42 #include "AliESDFMD.h"
43 #include "AliESD.h"
44 #include "AliESDMuonTrack.h"
45 #include "AliESDPmdTrack.h"
46 #include "AliESDTrdTrack.h"
47 #include "AliESDVertex.h"
48 #include "AliESDcascade.h"
49 #include "AliESDPmdTrack.h"
50 #include "AliESDTrdTrack.h"
51 #include "AliESDVertex.h"
52 #include "AliESDcascade.h"
53 #include "AliESDkink.h"
54 #include "AliESDtrack.h"
55 #include "AliESDHLTtrack.h"
56 #include "AliESDCaloCluster.h"
57 #include "AliESDCaloCells.h"
58 #include "AliESDv0.h"
59 #include "AliESDFMD.h"
60 #include "AliESDVZERO.h"
61 #include "AliMultiplicity.h"
62 #include "AliRawDataErrorLog.h"
63 #include "AliLog.h"
64 #include "AliESDACORDE.h"
65 ClassImp(AliESDEvent)
66
67
68
69 // here we define the names, some classes are no TNamed, therefore the classnames 
70 // are the Names
71   const char* AliESDEvent::fgkESDListName[kESDListN] = {"AliESDRun",
72                                                        "AliESDHeader",
73                                                        "AliESDZDC",
74                                                        "AliESDFMD",
75                                                        "AliESDVZERO",
76                                                        "AliESDTZERO",
77                                                        "TPCVertex",
78                                                        "SPDVertex",
79                                                        "PrimaryVertex",
80                                                        "AliMultiplicity",
81                                                        "PHOSTrigger",
82                                                        "EMCALTrigger",
83                                                        "SPDPileupVertices",
84                                                        "TrkPileupVertices",
85                                                        "Tracks",
86                                                        "MuonTracks",
87                                                        "PmdTracks",
88                                                        "TrdTracks",
89                                                        "V0s",
90                                                        "Cascades",
91                                                        "Kinks",
92                                                        "CaloClusters",
93                                                       "EMCALCells",
94                                                       "PHOSCells",
95                                                        "AliRawDataErrorLogs",
96                                                        "AliESDACORDE"};
97
98 //______________________________________________________________________________
99 AliESDEvent::AliESDEvent():
100   AliVEvent(),
101   fESDObjects(new TList()),
102   fESDRun(0),
103   fHeader(0),
104   fESDZDC(0),
105   fESDFMD(0),
106   fESDVZERO(0),
107   fESDTZERO(0),
108   fTPCVertex(0),
109   fSPDVertex(0),
110   fPrimaryVertex(0),
111   fSPDMult(0),
112   fPHOSTrigger(0),
113   fEMCALTrigger(0),
114   fESDACORDE(0),
115   fSPDPileupVertices(0),
116   fTrkPileupVertices(0),
117   fTracks(0),
118   fMuonTracks(0),
119   fPmdTracks(0),
120   fTrdTracks(0),
121   fV0s(0),  
122   fCascades(0),
123   fKinks(0),
124   fCaloClusters(0),
125   fEMCALCells(0), fPHOSCells(0),
126   fErrorLogs(0),
127   fESDOld(0),
128   fESDFriendOld(0),
129   fConnected(kFALSE),
130   fUseOwnList(kFALSE),
131   fEMCALClusters(0), 
132   fFirstEMCALCluster(-1),
133   fPHOSClusters(0), 
134   fFirstPHOSCluster(-1)
135 {
136 }
137 //______________________________________________________________________________
138 AliESDEvent::AliESDEvent(const AliESDEvent& esd):
139   AliVEvent(esd),
140   fESDObjects(new TList()),
141   fESDRun(new AliESDRun(*esd.fESDRun)),
142   fHeader(new AliESDHeader(*esd.fHeader)),
143   fESDZDC(new AliESDZDC(*esd.fESDZDC)),
144   fESDFMD(new AliESDFMD(*esd.fESDFMD)),
145   fESDVZERO(new AliESDVZERO(*esd.fESDVZERO)),
146   fESDTZERO(new AliESDTZERO(*esd.fESDTZERO)),
147   fTPCVertex(new AliESDVertex(*esd.fTPCVertex)),
148   fSPDVertex(new AliESDVertex(*esd.fSPDVertex)),
149   fPrimaryVertex(new AliESDVertex(*esd.fPrimaryVertex)),
150   fSPDMult(new AliMultiplicity(*esd.fSPDMult)),
151   fPHOSTrigger(new AliESDCaloTrigger(*esd.fPHOSTrigger)),
152   fEMCALTrigger(new AliESDCaloTrigger(*esd.fEMCALTrigger)),
153   fESDACORDE(new AliESDACORDE(*esd.fESDACORDE)),
154   fSPDPileupVertices(new TClonesArray(*esd.fSPDPileupVertices)),
155   fTrkPileupVertices(new TClonesArray(*esd.fTrkPileupVertices)),
156   fTracks(new TClonesArray(*esd.fTracks)),
157   fMuonTracks(new TClonesArray(*esd.fMuonTracks)),
158   fPmdTracks(new TClonesArray(*esd.fPmdTracks)),
159   fTrdTracks(new TClonesArray(*esd.fTrdTracks)),
160   fV0s(new TClonesArray(*esd.fV0s)),  
161   fCascades(new TClonesArray(*esd.fCascades)),
162   fKinks(new TClonesArray(*esd.fKinks)),
163   fCaloClusters(new TClonesArray(*esd.fCaloClusters)),
164   fEMCALCells(new AliESDCaloCells(*esd.fEMCALCells)),
165   fPHOSCells(new AliESDCaloCells(*esd.fPHOSCells)),
166   fErrorLogs(new TClonesArray(*esd.fErrorLogs)),
167   fESDOld(new AliESD(*esd.fESDOld)),
168   fESDFriendOld(new AliESDfriend(*esd.fESDFriendOld)),
169   fConnected(esd.fConnected),
170   fUseOwnList(esd.fUseOwnList),
171   fEMCALClusters(esd.fEMCALClusters), 
172   fFirstEMCALCluster(esd.fFirstEMCALCluster),
173   fPHOSClusters(esd.fPHOSClusters), 
174   fFirstPHOSCluster(esd.fFirstPHOSCluster)
175
176 {
177   // CKB init in the constructor list and only add here ...
178   AddObject(fESDRun);
179   AddObject(fHeader);
180   AddObject(fESDZDC);
181   AddObject(fESDFMD);
182   AddObject(fESDVZERO);
183   AddObject(fESDTZERO);
184   AddObject(fTPCVertex);
185   AddObject(fSPDVertex);
186   AddObject(fPrimaryVertex);
187   AddObject(fSPDMult);
188   AddObject(fPHOSTrigger);
189   AddObject(fEMCALTrigger);
190   AddObject(fSPDPileupVertices);
191   AddObject(fTrkPileupVertices);
192   AddObject(fTracks);
193   AddObject(fMuonTracks);
194   AddObject(fPmdTracks);
195   AddObject(fTrdTracks);
196   AddObject(fV0s);
197   AddObject(fCascades);
198   AddObject(fKinks);
199   AddObject(fCaloClusters);
200   AddObject(fEMCALCells);
201   AddObject(fPHOSCells);
202   AddObject(fErrorLogs);
203   AddObject(fESDACORDE);
204
205   GetStdContent();
206
207 }
208
209 //______________________________________________________________________________
210 AliESDEvent & AliESDEvent::operator=(const AliESDEvent& source) {
211
212   // Assignment operator
213
214   if(&source == this) return *this;
215   AliVEvent::operator=(source);
216
217   // This assumes that the list is already created
218   // and that the virtual void Copy(Tobject&) function
219   // is correctly implemented in the derived class
220   // otherwise only TObject::Copy() will be used
221
222
223
224   if((fESDObjects->GetSize()==0)&&(source.fESDObjects->GetSize()>=kESDListN)){
225     // We cover the case that we do not yet have the 
226     // standard content but the source has it
227     CreateStdContent();
228   }
229
230   TIter next(source.GetList());
231   TObject *its = 0;
232   TString name;
233   while ((its = next())) {
234     name.Form("%s", its->GetName());
235     TObject *mine = fESDObjects->FindObject(name.Data());
236     if(!mine){
237       TClass* pClass=TClass::GetClass(its->ClassName());
238       if (!pClass) {
239         AliWarning(Form("Can not find class description for entry %s (%s)\n",
240                         its->ClassName(), name.Data()));
241         continue;
242       }
243
244       mine=(TObject*)pClass->New();
245       if(!mine){
246       // not in this: can be added to list
247         AliWarning(Form("%s:%d Could not find %s for copying \n",
248                         (char*)__FILE__,__LINE__,name.Data()));
249         continue;
250       }  
251       if(mine->InheritsFrom("TNamed")){
252         ((TNamed*)mine)->SetName(name);
253       }
254       else if(mine->InheritsFrom("TCollection")){
255         if(mine->InheritsFrom("TClonesArray"))
256           dynamic_cast<TClonesArray*>(mine)->SetClass(dynamic_cast<TClonesArray*>(its)->GetClass());
257         dynamic_cast<TCollection*>(mine)->SetName(name);
258       }
259       AliDebug(1, Form("adding object %s of type %s", mine->GetName(), mine->ClassName()));
260       AddObject(mine);
261     }  
262    
263     if(!its->InheritsFrom("TCollection")){
264       // simple objects
265       its->Copy(*mine);
266     }
267     else if(its->InheritsFrom("TClonesArray")){
268       // Create or expand the tclonesarray pointers
269       // so we can directly copy to the object
270       TClonesArray *its_tca = (TClonesArray*)its;
271       TClonesArray *mine_tca = (TClonesArray*)mine;
272
273       // this leaves the capacity of the TClonesArray the same
274       // except for a factor of 2 increase when size > capacity
275       // does not release any memory occupied by the tca
276       mine_tca->ExpandCreate(its_tca->GetEntriesFast());
277       for(int i = 0;i < its_tca->GetEntriesFast();++i){
278         // copy 
279         TObject *mine_tca_obj = mine_tca->At(i);
280         TObject *its_tca_obj = its_tca->At(i);
281         // no need to delete first
282         // pointers within the class should be handled by Copy()...
283         // Can there be Empty slots?
284         its_tca_obj->Copy(*mine_tca_obj);
285       }
286     }
287     else{
288       AliWarning(Form("%s:%d cannot copy TCollection \n",
289                       (char*)__FILE__,__LINE__));
290     }
291   }
292
293   fConnected = source.fConnected;
294   fUseOwnList = source.fUseOwnList;
295   fEMCALClusters = source.fEMCALClusters;
296   fFirstEMCALCluster = source.fFirstEMCALCluster;
297   fPHOSClusters = source.fPHOSClusters;
298   fFirstPHOSCluster = source.fFirstPHOSCluster;
299
300
301   return *this;
302
303 }
304
305
306 //______________________________________________________________________________
307 AliESDEvent::~AliESDEvent()
308 {
309   //
310   // Standard destructor
311   //
312
313   // everthing on the list gets deleted automatically
314
315   
316   if(fESDObjects&&!fConnected)
317     {
318       delete fESDObjects;
319       fESDObjects = 0;
320     }
321
322   
323 }
324
325 void AliESDEvent::Copy(TObject &obj) const {
326
327   // interface to TOBject::Copy
328   // Copies the content of this into obj!
329   // bascially obj = *this
330
331   if(this==&obj)return;
332   AliESDEvent *robj = dynamic_cast<AliESDEvent*>(&obj);
333   if(!robj)return; // not an AliESEvent
334   *robj = *this;
335   return;
336 }
337
338 //______________________________________________________________________________
339 void AliESDEvent::Reset()
340 {
341
342   // Handle the cases
343   // Std content + Non std content
344
345   // Reset the standard contents
346   ResetStdContent(); 
347
348   //  reset for the old data without AliESDEvent...
349   if(fESDOld)fESDOld->Reset();
350   if(fESDFriendOld){
351     fESDFriendOld->~AliESDfriend();
352     new (fESDFriendOld) AliESDfriend();
353   }
354   // 
355
356   if(fESDObjects->GetSize()>kESDListN){
357     // we have non std content
358     // this also covers esdfriends
359     for(int i = kESDListN;i < fESDObjects->GetSize();++i){
360       TObject *pObject = fESDObjects->At(i);
361       // TClonesArrays
362       if(pObject->InheritsFrom(TClonesArray::Class())){
363         ((TClonesArray*)pObject)->Delete();
364       }
365       else if(!pObject->InheritsFrom(TCollection::Class())){
366         ResetWithPlacementNew(pObject);
367       }
368       else{
369         AliWarning(Form("No reset for %s (%s)\n",
370                         pObject->ClassName()));
371       }
372     }
373   }
374
375 }
376
377 Bool_t AliESDEvent::ResetWithPlacementNew(TObject *pObject){
378   Long_t dtoronly = TObject::GetDtorOnly();
379   TClass *pClass = TClass::GetClass(pObject->ClassName()); 
380   TObject::SetDtorOnly(pObject);
381   delete pObject;
382   // Recreate with placement new
383   pClass->New(pObject);
384   // Restore the state.
385   TObject::SetDtorOnly((void*)dtoronly);
386   return kTRUE;
387 }
388
389 void AliESDEvent::ResetStdContent()
390 {
391   // Reset the standard contents
392   if(fESDRun) fESDRun->Reset();
393   if(fHeader) fHeader->Reset();
394   if(fESDZDC) fESDZDC->Reset();
395   if(fESDFMD) {
396     fESDFMD->Clear();
397   }
398   if(fESDVZERO){
399     // reset by callin d'to /c'tor keep the pointer
400     fESDVZERO->~AliESDVZERO();
401     new (fESDVZERO) AliESDVZERO();
402   }  
403   if(fESDACORDE){
404     fESDACORDE->~AliESDACORDE();
405     new (fESDACORDE) AliESDACORDE();    
406   } 
407   if(fESDTZERO) fESDTZERO->Reset(); 
408   // CKB no clear/reset implemented
409   if(fTPCVertex){
410     fTPCVertex->~AliESDVertex();
411     new (fTPCVertex) AliESDVertex();
412     fTPCVertex->SetName(fgkESDListName[kTPCVertex]);
413   }
414   if(fSPDVertex){
415     fSPDVertex->~AliESDVertex();
416     new (fSPDVertex) AliESDVertex();
417     fSPDVertex->SetName(fgkESDListName[kSPDVertex]);
418   }
419   if(fPrimaryVertex){
420     fPrimaryVertex->~AliESDVertex();
421     new (fPrimaryVertex) AliESDVertex();
422     fPrimaryVertex->SetName(fgkESDListName[kPrimaryVertex]);
423   }
424   if(fSPDMult){
425     fSPDMult->~AliMultiplicity();
426     new (fSPDMult) AliMultiplicity();
427   }
428   if(fPHOSTrigger)fPHOSTrigger->Reset(); 
429   if(fEMCALTrigger)fEMCALTrigger->Reset(); 
430   if(fSPDPileupVertices)fSPDPileupVertices->Delete();
431   if(fTrkPileupVertices)fTrkPileupVertices->Delete();
432   if(fTracks)fTracks->Delete();
433   if(fMuonTracks)fMuonTracks->Delete();
434   if(fPmdTracks)fPmdTracks->Delete();
435   if(fTrdTracks)fTrdTracks->Delete();
436   if(fV0s)fV0s->Delete();
437   if(fCascades)fCascades->Delete();
438   if(fKinks)fKinks->Delete();
439   if(fCaloClusters)fCaloClusters->Delete();
440   if(fPHOSCells)fPHOSCells->DeleteContainer();
441   if(fEMCALCells)fEMCALCells->DeleteContainer();
442   if(fErrorLogs) fErrorLogs->Delete();
443
444   // don't reset fconnected fConnected and the list
445
446   fEMCALClusters=0; 
447   fFirstEMCALCluster=-1; 
448   fPHOSClusters=0; 
449   fFirstPHOSCluster=-1; 
450 }
451
452
453 Int_t AliESDEvent::AddV0(const AliESDv0 *v) {
454   //
455   // Add V0
456   //
457   TClonesArray &fv = *fV0s;
458   Int_t idx=fV0s->GetEntriesFast();
459   new(fv[idx]) AliESDv0(*v);
460   return idx;
461 }  
462
463 //______________________________________________________________________________
464 void AliESDEvent::Print(Option_t *) const 
465 {
466   //
467   // Print header information of the event
468   //
469   printf("ESD run information\n");
470   printf("Event # in file %d Bunch crossing # %d Orbit # %d Period # %d Run # %d Trigger %lld Magnetic field %f \n",
471          GetEventNumberInFile(),
472          GetBunchCrossNumber(),
473          GetOrbitNumber(),
474          GetPeriodNumber(),
475          GetRunNumber(),
476          GetTriggerMask(),
477          GetMagneticField() );
478   printf("Vertex: (%.4f +- %.4f, %.4f +- %.4f, %.4f +- %.4f) cm\n",
479            fPrimaryVertex->GetXv(), fPrimaryVertex->GetXRes(),
480            fPrimaryVertex->GetYv(), fPrimaryVertex->GetYRes(),
481            fPrimaryVertex->GetZv(), fPrimaryVertex->GetZRes());
482     printf("Mean vertex in RUN: X=%.4f Y=%.4f cm\n",
483            GetDiamondX(),GetDiamondY());
484     printf("SPD Multiplicity. Number of tracklets %d \n",
485            fSPDMult->GetNumberOfTracklets());
486   printf("Number of pileup primary vertices reconstructed with SPD %d\n", 
487         GetNumberOfPileupVerticesSPD());
488   printf("Number of pileup primary vertices reconstructed using the tracks %d\n",
489         GetNumberOfPileupVerticesTracks());
490   printf("Number of tracks: \n");
491   printf("                 charged   %d\n", GetNumberOfTracks());
492   printf("                 muon      %d\n", GetNumberOfMuonTracks());
493   printf("                 pmd       %d\n", GetNumberOfPmdTracks());
494   printf("                 trd       %d\n", GetNumberOfTrdTracks());
495   printf("                 v0        %d\n", GetNumberOfV0s());
496   printf("                 cascades  %d\n", GetNumberOfCascades());
497   printf("                 kinks     %d\n", GetNumberOfKinks());
498   if(fPHOSCells)printf("                 PHOSCells %d\n", fPHOSCells->GetNumberOfCells());
499   else printf("                 PHOSCells not in the Event\n");
500   if(fEMCALCells)printf("                 EMCALCells %d\n", fEMCALCells->GetNumberOfCells());
501   else printf("                 EMCALCells not in the Event\n");
502   printf("                 CaloClusters %d\n", GetNumberOfCaloClusters());
503   printf("                 phos      %d\n", GetNumberOfPHOSClusters());
504   printf("                 emcal     %d\n", GetNumberOfEMCALClusters());
505   printf("                 FMD       %s\n", (fESDFMD ? "yes" : "no"));
506   printf("                 VZERO     %s\n", (fESDVZERO ? "yes" : "no"));
507
508   return;
509 }
510
511 void AliESDEvent::SetESDfriend(const AliESDfriend *ev) const {
512   //
513   // Attaches the complementary info to the ESD
514   //
515   if (!ev) return;
516
517   // to be sure that we set the tracks also
518   // in case of old esds 
519   // if(fESDOld)CopyFromOldESD();
520
521   Int_t ntrk=ev->GetNumberOfTracks();
522  
523   for (Int_t i=0; i<ntrk; i++) {
524     const AliESDfriendTrack *f=ev->GetTrack(i);
525     GetTrack(i)->SetFriendTrack(f);
526   }
527 }
528
529 Bool_t  AliESDEvent::RemoveKink(Int_t rm) const {
530   // ---------------------------------------------------------
531   // Remove a kink candidate and references to it from ESD,
532   // if this candidate does not come from a reconstructed decay
533   // Not yet implemented...
534   // ---------------------------------------------------------
535   Int_t last=GetNumberOfKinks()-1;
536   if ((rm<0)||(rm>last)) return kFALSE;
537
538   return kTRUE;
539 }
540
541 Bool_t  AliESDEvent::RemoveV0(Int_t rm) const {
542   // ---------------------------------------------------------
543   // Remove a V0 candidate and references to it from ESD,
544   // if this candidate does not come from a reconstructed decay
545   // ---------------------------------------------------------
546   Int_t last=GetNumberOfV0s()-1;
547   if ((rm<0)||(rm>last)) return kFALSE;
548
549   AliESDv0 *v0=GetV0(rm);
550   Int_t idxP=v0->GetPindex(), idxN=v0->GetNindex();
551
552   v0=GetV0(last);
553   Int_t lastIdxP=v0->GetPindex(), lastIdxN=v0->GetNindex();
554
555   Int_t used=0;
556
557   // Check if this V0 comes from a reconstructed decay
558   Int_t ncs=GetNumberOfCascades();
559   for (Int_t n=0; n<ncs; n++) {
560     AliESDcascade *cs=GetCascade(n);
561
562     Int_t csIdxP=cs->GetPindex();
563     Int_t csIdxN=cs->GetNindex();
564
565     if (idxP==csIdxP)
566        if (idxN==csIdxN) return kFALSE;
567
568     if (csIdxP==lastIdxP)
569        if (csIdxN==lastIdxN) used++;
570   }
571
572   //Replace the removed V0 with the last V0 
573   TClonesArray &a=*fV0s;
574   delete a.RemoveAt(rm);
575
576   if (rm==last) return kTRUE;
577
578   //v0 is pointing to the last V0 candidate... 
579   new (a[rm]) AliESDv0(*v0);
580   delete a.RemoveAt(last);
581
582   if (!used) return kTRUE;
583   
584
585   // Remap the indices of the daughters of reconstructed decays
586   for (Int_t n=0; n<ncs; n++) {
587     AliESDcascade *cs=GetCascade(n);
588
589
590     Int_t csIdxP=cs->GetPindex();
591     Int_t csIdxN=cs->GetNindex();
592
593     if (csIdxP==lastIdxP)
594       if (csIdxN==lastIdxN) {
595          cs->AliESDv0::SetIndex(1,idxP);
596          cs->AliESDv0::SetIndex(0,idxN);
597          used--;
598          if (!used) return kTRUE;
599       }
600   }
601
602   return kTRUE;
603 }
604
605 Bool_t  AliESDEvent::RemoveTrack(Int_t rm) const {
606   // ---------------------------------------------------------
607   // Remove a track and references to it from ESD,
608   // if this track does not come from a reconstructed decay
609   // ---------------------------------------------------------
610   Int_t last=GetNumberOfTracks()-1;
611   if ((rm<0)||(rm>last)) return kFALSE;
612
613   Int_t used=0;
614
615   // Check if this track comes from the reconstructed primary vertices
616   if (fTPCVertex && fTPCVertex->GetStatus()) {
617      UShort_t *primIdx=fTPCVertex->GetIndices();
618      Int_t n=fTPCVertex->GetNIndices();
619      while (n--) {
620        Int_t idx=Int_t(primIdx[n]);
621        if (rm==idx) return kFALSE;
622        if (idx==last) used++; 
623      }
624   }
625   if (fPrimaryVertex && fPrimaryVertex->GetStatus()) {
626      UShort_t *primIdx=fPrimaryVertex->GetIndices();
627      Int_t n=fPrimaryVertex->GetNIndices();
628      while (n--) {
629        Int_t idx=Int_t(primIdx[n]);
630        if (rm==idx) return kFALSE;
631        if (idx==last) used++; 
632      }
633   }
634   
635   // Check if this track comes from a reconstructed decay
636   Int_t nv0=GetNumberOfV0s();
637   for (Int_t n=0; n<nv0; n++) {
638     AliESDv0 *v0=GetV0(n);
639
640     Int_t idx=v0->GetNindex();
641     if (rm==idx) return kFALSE;
642     if (idx==last) used++;
643
644     idx=v0->GetPindex();
645     if (rm==idx) return kFALSE;
646     if (idx==last) used++;
647   }
648
649   Int_t ncs=GetNumberOfCascades();
650   for (Int_t n=0; n<ncs; n++) {
651     AliESDcascade *cs=GetCascade(n);
652
653     Int_t idx=cs->GetIndex();
654     if (rm==idx) return kFALSE;
655     if (idx==last) used++;
656
657     AliESDv0 *v0=cs;
658     idx=v0->GetNindex();
659     if (rm==idx) return kFALSE;
660     if (idx==last) used++;
661
662     idx=v0->GetPindex();
663     if (rm==idx) return kFALSE;
664     if (idx==last) used++;
665   }
666
667   Int_t nkn=GetNumberOfKinks();
668   for (Int_t n=0; n<nkn; n++) {
669     AliESDkink *kn=GetKink(n);
670
671     Int_t idx=kn->GetIndex(0);
672     if (rm==idx) return kFALSE;
673     if (idx==last) used++;
674
675     idx=kn->GetIndex(1);
676     if (rm==idx) return kFALSE;
677     if (idx==last) used++;
678   }
679
680   // Check if this track is associated with a CaloCluster
681   Int_t ncl=GetNumberOfCaloClusters();
682   for (Int_t n=0; n<ncl; n++) {
683     AliESDCaloCluster *cluster=GetCaloCluster(n);
684     TArrayI *arr=cluster->GetTracksMatched();
685     Int_t s=arr->GetSize();
686     while (s--) {
687       Int_t idx=arr->At(s);
688       if (rm==idx) return kFALSE;
689       if (idx==last) used++;     
690     }
691   }
692
693
694
695   //Replace the removed track with the last track 
696   TClonesArray &a=*fTracks;
697   delete a.RemoveAt(rm);
698
699   if (rm==last) return kTRUE;
700
701   AliESDtrack *t=GetTrack(last);
702   t->SetID(rm);
703   new (a[rm]) AliESDtrack(*t);
704   delete a.RemoveAt(last);
705
706
707   if (!used) return kTRUE;
708   
709
710   // Remap the indices of the tracks used for the primary vertex reconstruction
711   if (fTPCVertex && fTPCVertex->GetStatus()) {
712      UShort_t *primIdx=fTPCVertex->GetIndices();
713      Int_t n=fTPCVertex->GetNIndices();
714      while (n--) {
715        Int_t idx=Int_t(primIdx[n]);
716        if (idx==last) {
717           primIdx[n]=Short_t(rm); 
718           used--;
719           if (!used) return kTRUE;
720        }
721      }
722   }  
723   if (fPrimaryVertex && fPrimaryVertex->GetStatus()) {
724      UShort_t *primIdx=fPrimaryVertex->GetIndices();
725      Int_t n=fPrimaryVertex->GetNIndices();
726      while (n--) {
727        Int_t idx=Int_t(primIdx[n]);
728        if (idx==last) {
729           primIdx[n]=Short_t(rm); 
730           used--;
731           if (!used) return kTRUE;
732        }
733      }
734   }  
735
736   // Remap the indices of the daughters of reconstructed decays
737   for (Int_t n=0; n<nv0; n++) {
738     AliESDv0 *v0=GetV0(n);
739     if (v0->GetIndex(0)==last) {
740        v0->SetIndex(0,rm);
741        used--;
742        if (!used) return kTRUE;
743     }
744     if (v0->GetIndex(1)==last) {
745        v0->SetIndex(1,rm);
746        used--;
747        if (!used) return kTRUE;
748     }
749   }
750
751   for (Int_t n=0; n<ncs; n++) {
752     AliESDcascade *cs=GetCascade(n);
753     if (cs->GetIndex()==last) {
754        cs->SetIndex(rm);
755        used--;
756        if (!used) return kTRUE;
757     }
758     AliESDv0 *v0=cs;
759     if (v0->GetIndex(0)==last) {
760        v0->SetIndex(0,rm);
761        used--;
762        if (!used) return kTRUE;
763     }
764     if (v0->GetIndex(1)==last) {
765        v0->SetIndex(1,rm);
766        used--;
767        if (!used) return kTRUE;
768     }
769   }
770
771   for (Int_t n=0; n<nkn; n++) {
772     AliESDkink *kn=GetKink(n);
773     if (kn->GetIndex(0)==last) {
774        kn->SetIndex(rm,0);
775        used--;
776        if (!used) return kTRUE;
777     }
778     if (kn->GetIndex(1)==last) {
779        kn->SetIndex(rm,1);
780        used--;
781        if (!used) return kTRUE;
782     }
783   }
784
785   // Remap the indices of the tracks accosicated with CaloClusters
786   for (Int_t n=0; n<ncl; n++) {
787     AliESDCaloCluster *cluster=GetCaloCluster(n);
788     TArrayI *arr=cluster->GetTracksMatched();
789     Int_t s=arr->GetSize();
790     while (s--) {
791       Int_t idx=arr->At(s);
792       if (idx==last) {
793          arr->AddAt(rm,s);
794          used--; 
795          if (!used) return kTRUE;
796       }
797     }
798   }
799
800   return kTRUE;
801 }
802
803
804 Bool_t AliESDEvent::Clean(Float_t *cleanPars) {
805   //
806   // Remove the data which are not needed for the physics analysis.
807   //
808   // 1) Cleaning the V0 candidates
809   //    ---------------------------
810   //    If the cosine of the V0 pointing angle "csp" and 
811   //    the DCA between the daughter tracks "dca" does not satisfy 
812   //    the conditions 
813   //
814   //     csp > cleanPars[1] + dca/cleanPars[0]*(1.- cleanPars[1])
815   //
816   //    an attempt to remove this V0 candidate from ESD is made.
817   //
818   //    The V0 candidate gets removed if it does not belong to any 
819   //    recosntructed cascade decay
820   //
821   //    12.11.2007, optimal values: cleanPars[0]=0.5, cleanPars[1]=0.999
822   //
823   // 2) Cleaning the tracks
824   //    ----------------------
825   //    If track's transverse parameter is larger than cleanPars[2]
826   //                       OR
827   //    track's longitudinal parameter is larger than cleanPars[3]
828   //    an attempt to remove this track from ESD is made.
829   //
830   //    The track gets removed if it does not come 
831   //    from a reconstructed decay
832   //
833   Bool_t rc=kFALSE;
834
835   Float_t dcaMax=cleanPars[0];
836   Float_t cspMin=cleanPars[1];
837
838   Int_t nV0s=GetNumberOfV0s();
839   for (Int_t i=nV0s-1; i>=0; i--) {
840     AliESDv0 *v0=GetV0(i);
841
842     Float_t dca=v0->GetDcaV0Daughters();
843     Float_t csp=v0->GetV0CosineOfPointingAngle();
844     Float_t cspcut=cspMin + dca/dcaMax*(1.-cspMin);
845     if (csp > cspcut) continue;
846     if (RemoveV0(i)) rc=kTRUE;
847   }
848
849
850   Float_t dmax=cleanPars[2], zmax=cleanPars[3];
851
852   const AliESDVertex *vertex=GetPrimaryVertexSPD();
853   Bool_t vtxOK=vertex->GetStatus();
854   
855   Int_t nTracks=GetNumberOfTracks();
856   for (Int_t i=nTracks-1; i>=0; i--) {
857     AliESDtrack *track=GetTrack(i);
858     Float_t xy,z; track->GetImpactParameters(xy,z);
859     if ((TMath::Abs(xy) > dmax) || (vtxOK && (TMath::Abs(z) > zmax))) {
860       if (RemoveTrack(i)) rc=kTRUE;
861     }
862   }
863
864   return rc;
865 }
866
867 Char_t  AliESDEvent::AddPileupVertexSPD(const AliESDVertex *vtx) 
868 {
869     // Add a pileup primary vertex reconstructed with SPD
870     TClonesArray &ftr = *fSPDPileupVertices;
871     Char_t n=Char_t(ftr.GetEntriesFast());
872     AliESDVertex *vertex = new(ftr[n]) AliESDVertex(*vtx);
873     vertex->SetID(n);
874     return n;
875 }
876
877 Char_t  AliESDEvent::AddPileupVertexTracks(const AliESDVertex *vtx) 
878 {
879     // Add a pileup primary vertex reconstructed with SPD
880     TClonesArray &ftr = *fTrkPileupVertices;
881     Char_t n=Char_t(ftr.GetEntriesFast());
882     AliESDVertex *vertex = new(ftr[n]) AliESDVertex(*vtx);
883     vertex->SetID(n);
884     return n;
885 }
886
887 Int_t  AliESDEvent::AddTrack(const AliESDtrack *t) 
888 {
889     // Add track
890     TClonesArray &ftr = *fTracks;
891     AliESDtrack * track = new(ftr[fTracks->GetEntriesFast()])AliESDtrack(*t);
892     track->SetID(fTracks->GetEntriesFast()-1);
893     return  track->GetID();    
894 }
895
896  void AliESDEvent::AddMuonTrack(const AliESDMuonTrack *t) 
897 {
898     TClonesArray &fmu = *fMuonTracks;
899     new(fmu[fMuonTracks->GetEntriesFast()]) AliESDMuonTrack(*t);
900 }
901
902 void AliESDEvent::AddPmdTrack(const AliESDPmdTrack *t) 
903 {
904   TClonesArray &fpmd = *fPmdTracks;
905   new(fpmd[fPmdTracks->GetEntriesFast()]) AliESDPmdTrack(*t);
906 }
907
908 void AliESDEvent::AddTrdTrack(const AliESDTrdTrack *t) 
909 {
910   TClonesArray &ftrd = *fTrdTracks;
911   new(ftrd[fTrdTracks->GetEntriesFast()]) AliESDTrdTrack(*t);
912 }
913
914
915
916
917 Int_t AliESDEvent::AddKink(const AliESDkink *c) 
918 {
919     // Add kink
920     TClonesArray &fk = *fKinks;
921     AliESDkink * kink = new(fk[fKinks->GetEntriesFast()]) AliESDkink(*c);
922     kink->SetID(fKinks->GetEntriesFast()); // CKB different from the other imps..
923     return fKinks->GetEntriesFast()-1;
924 }
925
926
927 void AliESDEvent::AddCascade(const AliESDcascade *c) 
928 {
929   TClonesArray &fc = *fCascades;
930   new(fc[fCascades->GetEntriesFast()]) AliESDcascade(*c);
931 }
932
933
934 Int_t AliESDEvent::AddCaloCluster(const AliESDCaloCluster *c) 
935 {
936     // Add calocluster
937     TClonesArray &fc = *fCaloClusters;
938     AliESDCaloCluster *clus = new(fc[fCaloClusters->GetEntriesFast()]) AliESDCaloCluster(*c);
939     clus->SetID(fCaloClusters->GetEntriesFast()-1);
940     return fCaloClusters->GetEntriesFast()-1;
941   }
942
943
944 void  AliESDEvent::AddRawDataErrorLog(const AliRawDataErrorLog *log) const {
945   TClonesArray &errlogs = *fErrorLogs;
946   new(errlogs[errlogs.GetEntriesFast()])  AliRawDataErrorLog(*log);
947 }
948
949 void  AliESDEvent::SetPrimaryVertexTPC(const AliESDVertex *vertex) 
950 {
951   // Set the TPC vertex
952   // use already allocated space
953   if(fTPCVertex){
954     *fTPCVertex = *vertex;
955     fTPCVertex->SetName(fgkESDListName[kTPCVertex]);
956   }
957 }
958
959 void  AliESDEvent::SetPrimaryVertexSPD(const AliESDVertex *vertex) 
960 {
961   // Set the SPD vertex
962   // use already allocated space
963   if(fSPDVertex){
964     *fSPDVertex = *vertex;
965     fSPDVertex->SetName(fgkESDListName[kSPDVertex]);
966   }
967 }
968
969 void  AliESDEvent::SetPrimaryVertexTracks(const AliESDVertex *vertex) 
970 {
971   // Set the primary vertex reconstructed using he ESD tracks.
972   // use already allocated space
973   if(fPrimaryVertex){
974     *fPrimaryVertex = *vertex;
975     fPrimaryVertex->SetName(fgkESDListName[kPrimaryVertex]);
976   }
977 }
978
979 const AliESDVertex * AliESDEvent::GetPrimaryVertex() const 
980 {
981   //
982   // Get the "best" available reconstructed primary vertex.
983   //
984   if(fPrimaryVertex){
985     if (fPrimaryVertex->GetStatus()) return fPrimaryVertex;
986   }
987   if(fSPDVertex){
988     if (fSPDVertex->GetStatus()) return fSPDVertex;
989   }
990   if(fTPCVertex) return fTPCVertex;
991   
992   AliWarning("No primary vertex available. Returning the \"default\"...");
993   return fSPDVertex;
994 }
995
996 void AliESDEvent::SetMultiplicity(const AliMultiplicity *mul) 
997 {
998   // Set the SPD Multiplicity
999   if(fSPDMult){
1000     *fSPDMult = *mul;
1001   }
1002 }
1003
1004
1005 void AliESDEvent::SetFMDData(AliESDFMD * obj) 
1006
1007   // use already allocated space
1008   if(fESDFMD){
1009     *fESDFMD = *obj;
1010   }
1011 }
1012
1013 void AliESDEvent::SetVZEROData(AliESDVZERO * obj)
1014
1015   // use already allocated space
1016   if(fESDVZERO)
1017     *fESDVZERO = *obj;
1018 }
1019
1020 void AliESDEvent::SetACORDEData(AliESDACORDE * obj)
1021 {
1022   if(fESDACORDE)
1023     *fESDACORDE = *obj;
1024 }
1025
1026
1027 void AliESDEvent::GetESDfriend(AliESDfriend *ev) const 
1028 {
1029   //
1030   // Extracts the complementary info from the ESD
1031   //
1032   if (!ev) return;
1033
1034   Int_t ntrk=GetNumberOfTracks();
1035
1036   for (Int_t i=0; i<ntrk; i++) {
1037     AliESDtrack *t=GetTrack(i);
1038     const AliESDfriendTrack *f=t->GetFriendTrack();
1039     ev->AddTrack(f);
1040
1041     t->ReleaseESDfriendTrack();// Not to have two copies of "friendTrack"
1042
1043   }
1044
1045   AliESDfriend *fr = (AliESDfriend*)(const_cast<AliESDEvent*>(this)->FindListObject("AliESDfriend"));
1046   if (fr) ev->SetVZEROfriend(fr->GetVZEROfriend());
1047 }
1048
1049 void AliESDEvent::AddObject(TObject* obj) 
1050 {
1051   // Add an object to the list of object.
1052   // Please be aware that in order to increase performance you should
1053   // refrain from using TObjArrays (if possible). Use TClonesArrays, instead.
1054   fESDObjects->SetOwner(kTRUE);
1055   fESDObjects->AddLast(obj);
1056 }
1057
1058
1059 void AliESDEvent::GetStdContent() 
1060 {
1061   // set pointers for standard content
1062   // get by name much safer and not a big overhead since not called very often
1063  
1064   fESDRun = (AliESDRun*)fESDObjects->FindObject(fgkESDListName[kESDRun]);
1065   fHeader = (AliESDHeader*)fESDObjects->FindObject(fgkESDListName[kHeader]);
1066   fESDZDC = (AliESDZDC*)fESDObjects->FindObject(fgkESDListName[kESDZDC]);
1067   fESDFMD = (AliESDFMD*)fESDObjects->FindObject(fgkESDListName[kESDFMD]);
1068   fESDVZERO = (AliESDVZERO*)fESDObjects->FindObject(fgkESDListName[kESDVZERO]);
1069   fESDTZERO = (AliESDTZERO*)fESDObjects->FindObject(fgkESDListName[kESDTZERO]);
1070   fTPCVertex = (AliESDVertex*)fESDObjects->FindObject(fgkESDListName[kTPCVertex]);
1071   fSPDVertex = (AliESDVertex*)fESDObjects->FindObject(fgkESDListName[kSPDVertex]);
1072   fPrimaryVertex = (AliESDVertex*)fESDObjects->FindObject(fgkESDListName[kPrimaryVertex]);
1073   fSPDMult =       (AliMultiplicity*)fESDObjects->FindObject(fgkESDListName[kSPDMult]);
1074   fPHOSTrigger = (AliESDCaloTrigger*)fESDObjects->FindObject(fgkESDListName[kPHOSTrigger]);
1075   fEMCALTrigger = (AliESDCaloTrigger*)fESDObjects->FindObject(fgkESDListName[kEMCALTrigger]);
1076   fSPDPileupVertices = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kSPDPileupVertices]);
1077   fTrkPileupVertices = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTrkPileupVertices]);
1078   fTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTracks]);
1079   fMuonTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kMuonTracks]);
1080   fPmdTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kPmdTracks]);
1081   fTrdTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTrdTracks]);
1082   fV0s = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kV0s]);
1083   fCascades = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kCascades]);
1084   fKinks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kKinks]);
1085   fCaloClusters = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kCaloClusters]);
1086   fEMCALCells = (AliESDCaloCells*)fESDObjects->FindObject(fgkESDListName[kEMCALCells]);
1087   fPHOSCells = (AliESDCaloCells*)fESDObjects->FindObject(fgkESDListName[kPHOSCells]);
1088   fErrorLogs = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kErrorLogs]);
1089   fESDACORDE = (AliESDACORDE*)fESDObjects->FindObject(fgkESDListName[kESDACORDE]);
1090
1091 }
1092
1093 void AliESDEvent::SetStdNames(){
1094   // Set the names of the standard contents
1095   // 
1096   if(fESDObjects->GetEntries()>=kESDListN){
1097     for(int i = 0;i < fESDObjects->GetEntries() && i<kESDListN;i++){
1098       TObject *fObj = fESDObjects->At(i);
1099       if(fObj->InheritsFrom("TNamed")){
1100         ((TNamed*)fObj)->SetName(fgkESDListName[i]);
1101       }
1102       else if(fObj->InheritsFrom("TClonesArray")){
1103         ((TClonesArray*)fObj)->SetName(fgkESDListName[i]);
1104       }
1105     }
1106   }
1107   else{
1108      AliWarning("Std Entries missing");
1109   }
1110
1111
1112
1113 void AliESDEvent::CreateStdContent(Bool_t bUseThisList){
1114   fUseOwnList = bUseThisList;
1115   CreateStdContent();
1116 }
1117
1118 void AliESDEvent::CreateStdContent() 
1119 {
1120   // create the standard AOD content and set pointers
1121
1122   // create standard objects and add them to the TList of objects
1123   AddObject(new AliESDRun());
1124   AddObject(new AliESDHeader());
1125   AddObject(new AliESDZDC());
1126   AddObject(new AliESDFMD());
1127   AddObject(new AliESDVZERO());
1128   AddObject(new AliESDTZERO());
1129   AddObject(new AliESDVertex());
1130   AddObject(new AliESDVertex());
1131   AddObject(new AliESDVertex());
1132   AddObject(new AliMultiplicity());
1133   AddObject(new AliESDCaloTrigger());
1134   AddObject(new AliESDCaloTrigger());
1135   AddObject(new TClonesArray("AliESDVertex",0));
1136   AddObject(new TClonesArray("AliESDVertex",0));
1137   AddObject(new TClonesArray("AliESDtrack",0));
1138   AddObject(new TClonesArray("AliESDMuonTrack",0));
1139   AddObject(new TClonesArray("AliESDPmdTrack",0));
1140   AddObject(new TClonesArray("AliESDTrdTrack",0));
1141   AddObject(new TClonesArray("AliESDv0",0));
1142   AddObject(new TClonesArray("AliESDcascade",0));
1143   AddObject(new TClonesArray("AliESDkink",0));
1144   AddObject(new TClonesArray("AliESDCaloCluster",0));
1145   AddObject(new AliESDCaloCells());
1146   AddObject(new AliESDCaloCells());
1147   AddObject(new TClonesArray("AliRawDataErrorLog",0));
1148   AddObject(new AliESDACORDE()); 
1149
1150   // check the order of the indices against enum...
1151
1152   // set names
1153   SetStdNames();
1154   // read back pointers
1155   GetStdContent();
1156 }
1157
1158 TObject* AliESDEvent::FindListObject(const char *name){
1159 //
1160 // Find object with name "name" in the list of branches
1161 //
1162   if(fESDObjects){
1163     return fESDObjects->FindObject(name);
1164   }
1165   return 0;
1166
1167
1168 Int_t AliESDEvent::GetPHOSClusters(TRefArray *clusters) const
1169 {
1170   // fills the provided TRefArray with all found phos clusters
1171   
1172   clusters->Clear();
1173   
1174   AliESDCaloCluster *cl = 0;
1175   for (Int_t i = 0; i < GetNumberOfCaloClusters(); i++) {
1176     
1177     if ( (cl = GetCaloCluster(i)) ) {
1178       if (cl->IsPHOS()){
1179         clusters->Add(cl);
1180         AliDebug(1,Form("IsPHOS cluster %d Size: %d \n",i,clusters->GetEntriesFast()));
1181       }
1182     }
1183   }
1184   return clusters->GetEntriesFast();
1185 }
1186
1187 Int_t AliESDEvent::GetEMCALClusters(TRefArray *clusters) const
1188 {
1189   // fills the provided TRefArray with all found emcal clusters
1190
1191   clusters->Clear();
1192
1193   AliESDCaloCluster *cl = 0;
1194   for (Int_t i = 0; i < GetNumberOfCaloClusters(); i++) {
1195
1196     if ( (cl = GetCaloCluster(i)) ) {
1197       if (cl->IsEMCAL()){
1198         clusters->Add(cl);
1199         AliDebug(1,Form("IsEMCAL cluster %d Size: %d \n",i,clusters->GetEntriesFast()));
1200       }
1201     }
1202   }
1203   return clusters->GetEntriesFast();
1204 }
1205
1206 void AliESDEvent::WriteToTree(TTree* tree) const {
1207   // Book the branches as in TTree::Branch(TCollection*)
1208   // but add a "." at the end of top level branches which are
1209   // not a TClonesArray
1210
1211
1212   TString branchname;
1213   TIter next(fESDObjects);
1214   const Int_t kSplitlevel = 99; // default value in TTree::Branch()
1215   const Int_t kBufsize = 32000; // default value in TTree::Branch()
1216   TObject *obj = 0;
1217
1218   while ((obj = next())) {
1219     branchname.Form("%s", obj->GetName());
1220     if(branchname.CompareTo("AliESDfriend")==0)branchname = "ESDfriend.";
1221     if ((kSplitlevel > 1) &&  !obj->InheritsFrom(TClonesArray::Class())) {
1222       if(!branchname.EndsWith("."))branchname += ".";
1223     }
1224     if (!tree->FindBranch(branchname)) {
1225       tree->Bronch(branchname, obj->ClassName(), fESDObjects->GetObjectRef(obj),
1226                    kBufsize, kSplitlevel - 1);
1227     }
1228   }
1229 }
1230
1231
1232 void AliESDEvent::ReadFromTree(TTree *tree, Option_t* opt){
1233 //
1234 // Connect the ESDEvent to a tree
1235 //
1236   if(!tree){
1237     AliWarning("AliESDEvent::ReadFromTree() Zero Pointer to Tree \n");
1238     return;
1239   }
1240   // load the TTree
1241   if(!tree->GetTree())tree->LoadTree(0);
1242
1243   // if we find the "ESD" branch on the tree we do have the old structure
1244   if(tree->GetBranch("ESD")) {
1245     char ** address  = (char **)(tree->GetBranch("ESD")->GetAddress());
1246     // do we have the friend branch
1247     TBranch * esdFB = tree->GetBranch("ESDfriend.");
1248     char ** addressF = 0;
1249     if(esdFB)addressF = (char **)(esdFB->GetAddress());
1250     if (!address) {
1251       AliInfo("AliESDEvent::ReadFromTree() Reading old Tree");
1252       tree->SetBranchAddress("ESD",       &fESDOld);
1253       if(esdFB){
1254         tree->SetBranchAddress("ESDfriend.",&fESDFriendOld);
1255       }
1256     } else {
1257       AliInfo("AliESDEvent::ReadFromTree() Reading old Tree");
1258       AliInfo("Branch already connected. Using existing branch address.");
1259       fESDOld       = (AliESD*)       (*address);
1260       // addressF can still be 0, since branch needs to switched on
1261       if(addressF)fESDFriendOld = (AliESDfriend*) (*addressF);
1262     }
1263                                        
1264     //  have already connected the old ESD structure... ?
1265     // reuse also the pointer of the AlliESDEvent
1266     // otherwise create new ones
1267     TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("ESDObjectsConnectedToTree"));
1268   
1269     if(connectedList){
1270       // If connected use the connected list of objects
1271       if(fESDObjects!= connectedList){
1272         // protect when called twice 
1273         fESDObjects->Delete();
1274         fESDObjects = connectedList;
1275       }
1276       GetStdContent(); 
1277
1278       
1279       // The pointer to the friend changes when called twice via InitIO
1280       // since AliESDEvent is deleted
1281       TObject* oldf = FindListObject("AliESDfriend");
1282       TObject* newf = 0;
1283       if(addressF){
1284         newf = (TObject*)*addressF;
1285       }
1286       if(newf!=0&&oldf!=newf){
1287         // remove the old reference
1288         // Should we also delete it? Or is this handled in TTree I/O
1289         // since it is created by the first SetBranchAddress
1290         fESDObjects->Remove(oldf);
1291         // add the new one 
1292         fESDObjects->Add(newf);
1293       }
1294       
1295       fConnected = true;
1296       return;
1297     }
1298     // else...    
1299     CreateStdContent(); // create for copy
1300     // if we have the esdfriend add it, so we always can access it via the userinfo
1301     if(fESDFriendOld)AddObject(fESDFriendOld);
1302     // we are not owner of the list objects 
1303     // must not delete it
1304     fESDObjects->SetOwner(kFALSE);
1305     fESDObjects->SetName("ESDObjectsConnectedToTree");
1306     tree->GetUserInfo()->Add(fESDObjects);
1307     fConnected = true;
1308     return;
1309   }
1310   
1311
1312     delete fESDOld;
1313     fESDOld = 0;
1314   // Try to find AliESDEvent
1315   AliESDEvent *esdEvent = 0;
1316   esdEvent = (AliESDEvent*)tree->GetTree()->GetUserInfo()->FindObject("AliESDEvent");
1317   if(esdEvent){   
1318       // Check if already connected to tree
1319     TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("ESDObjectsConnectedToTree"));
1320
1321     
1322     if (connectedList && (strcmp(opt, "reconnect"))) {
1323       // If connected use the connected list if objects
1324       fESDObjects->Delete();
1325       fESDObjects = connectedList;
1326       GetStdContent(); 
1327       fConnected = true;
1328       return;
1329     }
1330
1331     // Connect to tree
1332     // prevent a memory leak when reading back the TList
1333     if (!(strcmp(opt, "reconnect"))) fESDObjects->Delete();
1334     
1335     if(!fUseOwnList){
1336       delete fESDObjects;
1337       fESDObjects = 0;
1338       // create a new TList from the UserInfo TList... 
1339       // copy constructor does not work...
1340       fESDObjects = (TList*)(esdEvent->GetList()->Clone());
1341       fESDObjects->SetOwner(kFALSE);
1342     }
1343     else if ( fESDObjects->GetEntries()==0){
1344       // at least create the std content if we want to read to our list
1345       CreateStdContent(); 
1346     }
1347
1348     // in principle
1349     // we only need new things in the list if we do no already have it..
1350     // TODO just add new entries
1351
1352     if(fESDObjects->GetEntries()<kESDListN){
1353       AliWarning(Form("AliESDEvent::ReadFromTree() TList contains less than the standard contents %d < %d \n",
1354                       fESDObjects->GetEntries(),kESDListN));
1355     }
1356     // set the branch addresses
1357     TIter next(fESDObjects);
1358     TNamed *el;
1359     while((el=(TNamed*)next())){
1360       TString bname(el->GetName());
1361       if(bname.CompareTo("AliESDfriend")==0)
1362         {
1363           // AliESDfriend does not have a name ...
1364           tree->SetBranchAddress("ESDfriend.",fESDObjects->GetObjectRef(el));
1365         }
1366       else{
1367         // check if branch exists under this Name
1368         TBranch *br = tree->GetBranch(bname.Data());
1369         if(br){
1370           tree->SetBranchAddress(bname.Data(),fESDObjects->GetObjectRef(el));
1371         }
1372         else{
1373           br = tree->GetBranch(Form("%s.",bname.Data()));
1374           if(br){
1375             tree->SetBranchAddress(Form("%s.",bname.Data()),fESDObjects->GetObjectRef(el));
1376           }
1377           else{
1378             AliWarning(Form("AliESDEvent::ReadFromTree() No Branch found with Name %s or %s.",bname.Data(),bname.Data()));
1379           }
1380
1381         }
1382       }
1383     }
1384     GetStdContent();
1385     // when reading back we are not owner of the list 
1386     // must not delete it
1387     fESDObjects->SetOwner(kFALSE);
1388     fESDObjects->SetName("ESDObjectsConnectedToTree");
1389     // we are not owner of the list objects 
1390     // must not delete it
1391     tree->GetUserInfo()->Add(fESDObjects);
1392     fConnected = true;
1393   }// no esdEvent
1394   else {
1395     // we can't get the list from the user data, create standard content
1396     // and set it by hand (no ESDfriend at the moment
1397     CreateStdContent();
1398     TIter next(fESDObjects);
1399     TNamed *el;
1400     while((el=(TNamed*)next())){
1401       TString bname(el->GetName());    
1402       TBranch *br = tree->GetBranch(bname.Data());
1403       if(br){
1404         tree->SetBranchAddress(bname.Data(),fESDObjects->GetObjectRef(el));
1405       }
1406       else{
1407         br = tree->GetBranch(Form("%s.",bname.Data()));
1408         if(br){
1409           tree->SetBranchAddress(Form("%s.",bname.Data()),fESDObjects->GetObjectRef(el));
1410         }
1411       }
1412     }
1413     GetStdContent();
1414     // when reading back we are not owner of the list 
1415     // must not delete it
1416     fESDObjects->SetOwner(kFALSE);
1417   }
1418 }
1419
1420
1421 void AliESDEvent::CopyFromOldESD()
1422 {
1423   // Method which copies over everthing from the old esd structure to the 
1424   // new  
1425   if(fESDOld){
1426     ResetStdContent();
1427      // Run
1428     SetRunNumber(fESDOld->GetRunNumber());
1429     SetPeriodNumber(fESDOld->GetPeriodNumber());
1430     SetMagneticField(fESDOld->GetMagneticField());
1431   
1432     // leave out diamond ...
1433     // SetDiamond(const AliESDVertex *vertex) { fESDRun->SetDiamond(vertex);}
1434
1435     // header
1436     SetTriggerMask(fESDOld->GetTriggerMask());
1437     SetOrbitNumber(fESDOld->GetOrbitNumber());
1438     SetTimeStamp(fESDOld->GetTimeStamp());
1439     SetEventType(fESDOld->GetEventType());
1440     SetEventNumberInFile(fESDOld->GetEventNumberInFile());
1441     SetBunchCrossNumber(fESDOld->GetBunchCrossNumber());
1442     SetTriggerCluster(fESDOld->GetTriggerCluster());
1443
1444     // ZDC
1445
1446     SetZDC(fESDOld->GetZDCN1Energy(),
1447            fESDOld->GetZDCP1Energy(),
1448            fESDOld->GetZDCEMEnergy(),
1449            0,
1450            fESDOld->GetZDCN2Energy(),
1451            fESDOld->GetZDCP2Energy(),
1452            fESDOld->GetZDCParticipants(),
1453            0);
1454
1455     // FMD
1456     
1457     if(fESDOld->GetFMDData())SetFMDData(fESDOld->GetFMDData());
1458
1459     // T0
1460
1461     SetT0zVertex(fESDOld->GetT0zVertex());
1462     SetT0(fESDOld->GetT0());
1463     //  leave amps out
1464
1465     // VZERO
1466     if (fESDOld->GetVZEROData()) SetVZEROData(fESDOld->GetVZEROData());
1467
1468     if(fESDOld->GetVertex())SetPrimaryVertexSPD(fESDOld->GetVertex());
1469
1470     if(fESDOld->GetPrimaryVertex())SetPrimaryVertexTracks(fESDOld->GetPrimaryVertex());
1471
1472     if(fESDOld->GetMultiplicity())SetMultiplicity(fESDOld->GetMultiplicity());
1473
1474     for(int i = 0;i<fESDOld->GetNumberOfTracks();i++){
1475       AddTrack(fESDOld->GetTrack(i));
1476     }
1477
1478     for(int i = 0;i<fESDOld->GetNumberOfMuonTracks();i++){
1479       AddMuonTrack(fESDOld->GetMuonTrack(i));
1480     }
1481
1482     for(int i = 0;i<fESDOld->GetNumberOfPmdTracks();i++){
1483       AddPmdTrack(fESDOld->GetPmdTrack(i));
1484     }
1485
1486     for(int i = 0;i<fESDOld->GetNumberOfTrdTracks();i++){
1487       AddTrdTrack(fESDOld->GetTrdTrack(i));
1488     }
1489
1490     for(int i = 0;i<fESDOld->GetNumberOfV0s();i++){
1491       AddV0(fESDOld->GetV0(i));
1492     }
1493
1494     for(int i = 0;i<fESDOld->GetNumberOfCascades();i++){
1495       AddCascade(fESDOld->GetCascade(i));
1496     }
1497
1498     for(int i = 0;i<fESDOld->GetNumberOfKinks();i++){
1499       AddKink(fESDOld->GetKink(i));
1500     }
1501
1502
1503     for(int i = 0;i<fESDOld->GetNumberOfCaloClusters();i++){
1504       AddCaloCluster(fESDOld->GetCaloCluster(i));
1505     }
1506
1507   }// if fesdold
1508 }
1509
1510
1511