]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/ESD/AliESDEvent.cxx
5f72ac612ac4e9237ee44cfc5c54650d38166d39
[u/mrichter/AliRoot.git] / STEER / ESD / 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: AliESDEvent.cxx 64008 2013-08-28 13:09:59Z hristov $ */
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 #include <TROOT.h>
39 #include <TInterpreter.h>
40
41 #include "AliESDEvent.h"
42 #include "AliESDfriend.h"
43 #include "AliESDVZERO.h"
44 #include "AliESDFMD.h"
45 #include "AliESD.h"
46 #include "AliESDMuonTrack.h"
47 #include "AliESDMuonCluster.h"
48 #include "AliESDMuonPad.h"
49 #include "AliESDPmdTrack.h"
50 #include "AliESDTrdTrack.h"
51 #include "AliESDVertex.h"
52 #include "AliESDcascade.h"
53 #include "AliESDPmdTrack.h"
54 #include "AliESDTrdTrigger.h"
55 #include "AliESDTrdTrack.h"
56 #include "AliESDTrdTracklet.h"
57 #include "AliESDVertex.h"
58 #include "AliVertexerTracks.h"
59 #include "AliESDcascade.h"
60 #include "AliESDkink.h"
61 #include "AliESDtrack.h"
62 #include "AliESDHLTtrack.h"
63 #include "AliESDCaloCluster.h"
64 #include "AliESDCaloCells.h"
65 #include "AliESDv0.h"
66 #include "AliESDFMD.h"
67 #include "AliESDVZERO.h"
68 #include "AliMultiplicity.h"
69 #include "AliRawDataErrorLog.h"
70 #include "AliLog.h"
71 #include "AliESDACORDE.h"
72 #include "AliESDAD.h"
73 #include "AliESDHLTDecision.h"
74 #include "AliCentrality.h"
75 #include "AliESDCosmicTrack.h"
76 #include "AliTriggerConfiguration.h"
77 #include "AliTriggerClass.h"
78 #include "AliTriggerCluster.h"
79 #include "AliEventplane.h"
80
81
82 ClassImp(AliESDEvent)
83
84
85
86 // here we define the names, some classes are no TNamed, therefore the classnames 
87 // are the Names
88   const char* AliESDEvent::fgkESDListName[kESDListN] = {"AliESDRun",
89                                                         "AliESDHeader",
90                                                         "AliESDZDC",
91                                                         "AliESDFMD",
92                                                         "AliESDVZERO",
93                                                         "AliESDTZERO",
94                                                         "TPCVertex",
95                                                         "SPDVertex",
96                                                         "PrimaryVertex",
97                                                         "AliMultiplicity",
98                                                         "PHOSTrigger",
99                                                         "EMCALTrigger",
100                                                         "SPDPileupVertices",
101                                                         "TrkPileupVertices",
102                                                         "Tracks",
103                                                         "MuonTracks",
104                                                         "MuonClusters",
105                                                         "MuonPads",
106                                                         "PmdTracks",
107                                                         "AliESDTrdTrigger",
108                                                         "TrdTracks",
109                                                         "TrdTracklets",
110                                                         "V0s",
111                                                         "Cascades",
112                                                         "Kinks",
113                                                         "CaloClusters",
114                                                         "EMCALCells",
115                                                         "PHOSCells",
116                                                         "AliRawDataErrorLogs",
117                                                         "AliESDACORDE",
118                                                         "AliESDAD",
119                                                         "AliTOFHeader",
120                                                         "CosmicTracks"};
121
122 //______________________________________________________________________________
123 AliESDEvent::AliESDEvent():
124   AliVEvent(),
125   fESDObjects(new TList()),
126   fESDRun(0),
127   fHeader(0),
128   fESDZDC(0),
129   fESDFMD(0),
130   fESDVZERO(0),
131   fESDTZERO(0),
132   fTPCVertex(0),
133   fSPDVertex(0),
134   fPrimaryVertex(0),
135   fSPDMult(0),
136   fPHOSTrigger(0),
137   fEMCALTrigger(0),
138   fESDACORDE(0),
139   fESDAD(0),
140   fTrdTrigger(0),
141   fSPDPileupVertices(0),
142   fTrkPileupVertices(0),
143   fTracks(0),
144   fMuonTracks(0),
145   fMuonClusters(0),
146   fMuonPads(0),
147   fPmdTracks(0),
148   fTrdTracks(0),
149   fTrdTracklets(0),
150   fV0s(0),  
151   fCascades(0),
152   fKinks(0),
153   fCaloClusters(0),
154   fEMCALCells(0), fPHOSCells(0),
155   fCosmicTracks(0),
156   fErrorLogs(0),
157   fOldMuonStructure(kFALSE),
158   fESDOld(0),
159   fESDFriendOld(0),
160   fConnected(kFALSE),
161   fUseOwnList(kFALSE),
162   fTOFHeader(0),
163   fCentrality(0),
164   fEventplane(0),
165   fDetectorStatus(0xFFFFFFFF),
166   fDAQDetectorPattern(0xFFFF),
167   fDAQAttributes(0xFFFF),
168   fNTOFclusters(0),
169   fTOFcluster(0)
170 {
171 }
172 //______________________________________________________________________________
173 AliESDEvent::AliESDEvent(const AliESDEvent& esd):
174   AliVEvent(esd),
175   fESDObjects(new TList()),
176   fESDRun(new AliESDRun(*esd.fESDRun)),
177   fHeader(new AliESDHeader(*esd.fHeader)),
178   fESDZDC(new AliESDZDC(*esd.fESDZDC)),
179   fESDFMD(new AliESDFMD(*esd.fESDFMD)),
180   fESDVZERO(new AliESDVZERO(*esd.fESDVZERO)),
181   fESDTZERO(new AliESDTZERO(*esd.fESDTZERO)),
182   fTPCVertex(new AliESDVertex(*esd.fTPCVertex)),
183   fSPDVertex(new AliESDVertex(*esd.fSPDVertex)),
184   fPrimaryVertex(new AliESDVertex(*esd.fPrimaryVertex)),
185   fSPDMult(new AliMultiplicity(*esd.fSPDMult)),
186   fPHOSTrigger(new AliESDCaloTrigger(*esd.fPHOSTrigger)),
187   fEMCALTrigger(new AliESDCaloTrigger(*esd.fEMCALTrigger)),
188   fESDACORDE(new AliESDACORDE(*esd.fESDACORDE)),
189   fESDAD(new AliESDAD(*esd.fESDAD)),
190   fTrdTrigger(new AliESDTrdTrigger(*esd.fTrdTrigger)),
191   fSPDPileupVertices(new TClonesArray(*esd.fSPDPileupVertices)),
192   fTrkPileupVertices(new TClonesArray(*esd.fTrkPileupVertices)),
193   fTracks(new TClonesArray(*esd.fTracks)),
194   fMuonTracks(new TClonesArray(*esd.fMuonTracks)),
195   fMuonClusters(new TClonesArray(*esd.fMuonClusters)),
196   fMuonPads(new TClonesArray(*esd.fMuonPads)),
197   fPmdTracks(new TClonesArray(*esd.fPmdTracks)),
198   fTrdTracks(new TClonesArray(*esd.fTrdTracks)),
199   fTrdTracklets(new TClonesArray(*esd.fTrdTracklets)),
200   fV0s(new TClonesArray(*esd.fV0s)),  
201   fCascades(new TClonesArray(*esd.fCascades)),
202   fKinks(new TClonesArray(*esd.fKinks)),
203   fCaloClusters(new TClonesArray(*esd.fCaloClusters)),
204   fEMCALCells(new AliESDCaloCells(*esd.fEMCALCells)),
205   fPHOSCells(new AliESDCaloCells(*esd.fPHOSCells)),
206   fCosmicTracks(new TClonesArray(*esd.fCosmicTracks)),
207   fErrorLogs(new TClonesArray(*esd.fErrorLogs)),
208   fOldMuonStructure(esd.fOldMuonStructure),
209   fESDOld(esd.fESDOld ? new AliESD(*esd.fESDOld) : 0),
210   fESDFriendOld(esd.fESDFriendOld ? new AliESDfriend(*esd.fESDFriendOld) : 0),
211   fConnected(esd.fConnected),
212   fUseOwnList(esd.fUseOwnList),
213   fTOFHeader(new AliTOFHeader(*esd.fTOFHeader)),
214   fCentrality(new AliCentrality(*esd.fCentrality)),
215   fEventplane(new AliEventplane(*esd.fEventplane)),
216   fDetectorStatus(esd.fDetectorStatus),
217   fDAQDetectorPattern(esd.fDAQDetectorPattern),
218   fDAQAttributes(esd.fDAQAttributes),
219   fNTOFclusters(esd.fNTOFclusters),
220   //  fTOFcluster(esd.fTOFcluster)
221   fTOFcluster(new TObjArray(*(esd.fTOFcluster)))
222 {
223   printf("copying ESD event...\n");   // AU
224   // CKB init in the constructor list and only add here ...
225   AddObject(fESDRun);
226   AddObject(fHeader);
227   AddObject(fESDZDC);
228   AddObject(fESDFMD);
229   AddObject(fESDVZERO);
230   AddObject(fESDTZERO);
231   AddObject(fTPCVertex);
232   AddObject(fSPDVertex);
233   AddObject(fPrimaryVertex);
234   AddObject(fSPDMult);
235   AddObject(fPHOSTrigger);
236   AddObject(fEMCALTrigger);
237   AddObject(fTrdTrigger);
238   AddObject(fSPDPileupVertices);
239   AddObject(fTrkPileupVertices);
240   AddObject(fTracks);
241   AddObject(fMuonTracks);
242   AddObject(fPmdTracks);
243   AddObject(fTrdTracks);
244   AddObject(fTrdTracklets);
245   AddObject(fV0s);
246   AddObject(fCascades);
247   AddObject(fKinks);
248   AddObject(fCaloClusters);
249   AddObject(fEMCALCells);
250   AddObject(fPHOSCells);
251   AddObject(fCosmicTracks);
252   AddObject(fErrorLogs);
253   AddObject(fESDACORDE);
254   AddObject(fESDAD);
255   AddObject(fTOFHeader);
256   AddObject(fMuonClusters);
257   AddObject(fMuonPads);
258   GetStdContent();
259 }
260
261 //______________________________________________________________________________
262 AliESDEvent & AliESDEvent::operator=(const AliESDEvent& source) {
263
264   // Assignment operator
265   printf("operator = ESD\n");
266   if(&source == this) return *this;
267   AliVEvent::operator=(source);
268
269   // This assumes that the list is already created
270   // and that the virtual void Copy(Tobject&) function
271   // is correctly implemented in the derived class
272   // otherwise only TObject::Copy() will be used
273
274
275
276   if((fESDObjects->GetSize()==0)&&(source.fESDObjects->GetSize()>=kESDListN)){
277     // We cover the case that we do not yet have the 
278     // standard content but the source has it
279     CreateStdContent();
280   }
281
282   TIter next(source.GetList());
283   TObject *its = 0;
284   TString name;
285   while ((its = next())) {
286     name.Form("%s", its->GetName());
287     TObject *mine = fESDObjects->FindObject(name.Data());
288     if(!mine){
289       TClass* pClass=TClass::GetClass(its->ClassName());
290       if (!pClass) {
291         AliWarning(Form("Can not find class description for entry %s (%s)\n",
292                         its->ClassName(), name.Data()));
293         continue;
294       }
295
296       mine=(TObject*)pClass->New();
297       if(!mine){
298       // not in this: can be added to list
299         AliWarning(Form("%s:%d Could not find %s for copying \n",
300                         (char*)__FILE__,__LINE__,name.Data()));
301         continue;
302       }  
303       if(mine->InheritsFrom("TNamed")){
304         ((TNamed*)mine)->SetName(name);
305       }
306       else if(mine->InheritsFrom("TCollection")){
307         if(mine->InheritsFrom("TClonesArray")) {
308           TClonesArray* tcits = dynamic_cast<TClonesArray*>(its);
309           if (tcits)
310             dynamic_cast<TClonesArray*>(mine)->SetClass(tcits->GetClass());
311         }
312         dynamic_cast<TCollection*>(mine)->SetName(name);
313       }
314       AliDebug(1, Form("adding object %s of type %s", mine->GetName(), mine->ClassName()));
315       AddObject(mine);
316     }  
317    
318     if(!its->InheritsFrom("TCollection")){
319       // simple objects
320       its->Copy(*mine);
321     }
322     else if(its->InheritsFrom("TClonesArray")){
323       // Create or expand the tclonesarray pointers
324       // so we can directly copy to the object
325       TClonesArray *itstca = (TClonesArray*)its;
326       TClonesArray *minetca = (TClonesArray*)mine;
327
328       // this leaves the capacity of the TClonesArray the same
329       // except for a factor of 2 increase when size > capacity
330       // does not release any memory occupied by the tca
331       minetca->ExpandCreate(itstca->GetEntriesFast());
332       for(int i = 0;i < itstca->GetEntriesFast();++i){
333         // copy 
334         TObject *minetcaobj = minetca->At(i);
335         TObject *itstcaobj = itstca->At(i);
336         // no need to delete first
337         // pointers within the class should be handled by Copy()...
338         // Can there be Empty slots?
339         itstcaobj->Copy(*minetcaobj);
340       }
341     }
342     else{
343       AliWarning(Form("%s:%d cannot copy TCollection \n",
344                       (char*)__FILE__,__LINE__));
345     }
346   }
347
348   fOldMuonStructure = source.fOldMuonStructure;
349   
350   fCentrality = source.fCentrality;
351   fEventplane = source.fEventplane;
352
353   fConnected  = source.fConnected;
354   fUseOwnList = source.fUseOwnList;
355   
356   fDetectorStatus = source.fDetectorStatus;
357   fDAQDetectorPattern = source.fDAQDetectorPattern;
358   fDAQAttributes = source.fDAQAttributes;
359   fNTOFclusters = source.fNTOFclusters;
360
361   *fTOFcluster = *source.fTOFcluster;
362   //  fTOFcluster = new TObjArray(*(source.fTOFcluster));
363
364   return *this;
365 }
366
367
368 //______________________________________________________________________________
369 AliESDEvent::~AliESDEvent()
370 {
371   //
372   // Standard destructor
373   //
374
375   // everthing on the list gets deleted automatically
376
377   
378   if(fESDObjects&&!fConnected)
379     {
380       delete fESDObjects;
381       fESDObjects = 0;
382     }
383   if (fCentrality) delete fCentrality;
384   if (fEventplane) delete fEventplane;
385   
386
387   if(fTOFcluster){
388     fTOFcluster->Clear();
389     delete fTOFcluster;
390   }
391 }
392
393 void AliESDEvent::Copy(TObject &obj) const {
394
395   // interface to TOBject::Copy
396   // Copies the content of this into obj!
397   // bascially obj = *this
398
399   if(this==&obj)return;
400   AliESDEvent *robj = dynamic_cast<AliESDEvent*>(&obj);
401   if(!robj)return; // not an AliESEvent
402   *robj = *this;
403   return;
404 }
405
406 //______________________________________________________________________________
407 void AliESDEvent::Reset()
408 {
409
410   // Handle the cases
411   // Std content + Non std content
412
413   // Reset the standard contents
414   ResetStdContent(); 
415   fDetectorStatus = 0xFFFFFFFF;
416   fDAQDetectorPattern = 0xFFFF;
417   fDAQAttributes = 0xFFFF;
418   //  reset for the old data without AliESDEvent...
419   if(fESDOld)fESDOld->Reset();
420   if(fESDFriendOld){
421     fESDFriendOld->~AliESDfriend();
422     new (fESDFriendOld) AliESDfriend();
423   }
424   // 
425
426   if(fESDObjects->GetSize()>kESDListN){
427     // we have non std content
428     // this also covers esdfriends
429     for(int i = kESDListN;i < fESDObjects->GetSize();++i){
430       TObject *pObject = fESDObjects->At(i);
431       // TClonesArrays
432       if(pObject->InheritsFrom(TClonesArray::Class())){
433         ((TClonesArray*)pObject)->Delete();
434       }
435       else if(!pObject->InheritsFrom(TCollection::Class())){
436         TClass *pClass = TClass::GetClass(pObject->ClassName());
437         if (pClass && pClass->GetListOfMethods()->FindObject("Clear")) {
438           AliDebug(1, Form("Clear for object %s class %s", pObject->GetName(), pObject->ClassName()));
439           pObject->Clear();
440         }
441         else {
442           AliDebug(1, Form("ResetWithPlacementNew for object %s class %s", pObject->GetName(), pObject->ClassName()));
443           ResetWithPlacementNew(pObject);
444         }
445       }
446       else{
447         AliWarning(Form("No reset for %s \n",
448                         pObject->ClassName()));
449       }
450     }
451   }
452
453 }
454
455 Bool_t AliESDEvent::ResetWithPlacementNew(TObject *pObject){
456   //
457   // funtion to reset using the already allocated space
458   //
459   Long_t dtoronly = TObject::GetDtorOnly();
460   TClass *pClass = TClass::GetClass(pObject->ClassName()); 
461   TObject::SetDtorOnly(pObject);
462   delete pObject;
463   // Recreate with placement new
464   pClass->New(pObject);
465   // Restore the state.
466   TObject::SetDtorOnly((void*)dtoronly);
467   return kTRUE;
468 }
469
470 void AliESDEvent::ResetStdContent()
471 {
472   // Reset the standard contents
473   if(fESDRun) fESDRun->Reset();
474   if(fHeader) fHeader->Reset();
475   if(fCentrality) fCentrality->Reset();
476   if(fEventplane) fEventplane->Reset();
477   if(fESDZDC) fESDZDC->Reset();
478   if(fESDFMD) {
479     fESDFMD->Clear();
480   }
481   if(fESDVZERO){
482     // reset by callin d'to /c'tor keep the pointer
483     fESDVZERO->~AliESDVZERO();
484     new (fESDVZERO) AliESDVZERO();
485   }  
486   if(fESDACORDE){
487     fESDACORDE->~AliESDACORDE();
488     new (fESDACORDE) AliESDACORDE();    
489   } 
490
491   if(fESDAD){
492     fESDAD->~AliESDAD();
493     new (fESDAD) AliESDAD();    
494   } 
495
496
497   if(fESDTZERO) fESDTZERO->Reset(); 
498   // CKB no clear/reset implemented
499   if(fTPCVertex){
500     fTPCVertex->~AliESDVertex();
501     new (fTPCVertex) AliESDVertex();
502     fTPCVertex->SetName(fgkESDListName[kTPCVertex]);
503   }
504   if(fSPDVertex){
505     fSPDVertex->~AliESDVertex();
506     new (fSPDVertex) AliESDVertex();
507     fSPDVertex->SetName(fgkESDListName[kSPDVertex]);
508   }
509   if(fPrimaryVertex){
510     fPrimaryVertex->~AliESDVertex();
511     new (fPrimaryVertex) AliESDVertex();
512     fPrimaryVertex->SetName(fgkESDListName[kPrimaryVertex]);
513   }
514   if(fSPDMult){
515     fSPDMult->~AliMultiplicity();
516     new (fSPDMult) AliMultiplicity();
517   }
518   if(fTOFHeader){
519     fTOFHeader->~AliTOFHeader();
520     new (fTOFHeader) AliTOFHeader();
521     //fTOFHeader->SetName(fgkESDListName[kTOFHeader]);
522   }
523   if (fTrdTrigger) {
524     fTrdTrigger->~AliESDTrdTrigger();
525     new (fTrdTrigger) AliESDTrdTrigger();
526   }
527         
528   if(fPHOSTrigger)fPHOSTrigger->DeAllocate(); 
529   if(fEMCALTrigger)fEMCALTrigger->DeAllocate(); 
530   if(fSPDPileupVertices)fSPDPileupVertices->Delete();
531   if(fTrkPileupVertices)fTrkPileupVertices->Delete();
532   if(fTracks)fTracks->Delete();
533   if(fMuonTracks)fMuonTracks->Clear("C");
534   if(fMuonClusters)fMuonClusters->Clear("C");
535   if(fMuonPads)fMuonPads->Clear("C");
536   if(fPmdTracks)fPmdTracks->Delete();
537   if(fTrdTracks)fTrdTracks->Delete();
538   if(fTrdTracklets)fTrdTracklets->Delete();
539   if(fV0s)fV0s->Delete();
540   if(fCascades)fCascades->Delete();
541   if(fKinks)fKinks->Delete();
542   if(fCaloClusters)fCaloClusters->Delete();
543   if(fPHOSCells)fPHOSCells->DeleteContainer();
544   if(fEMCALCells)fEMCALCells->DeleteContainer();
545   if(fCosmicTracks)fCosmicTracks->Delete();
546   if(fErrorLogs) fErrorLogs->Delete();
547
548   // don't reset fconnected fConnected and the list
549
550 }
551
552
553 Int_t AliESDEvent::AddV0(const AliESDv0 *v) {
554   //
555   // Add V0
556   //
557   TClonesArray &fv = *fV0s;
558   Int_t idx=fV0s->GetEntriesFast();
559   new(fv[idx]) AliESDv0(*v);
560   return idx;
561 }  
562
563 //______________________________________________________________________________
564 Bool_t AliESDEvent::IsDetectorInTriggerCluster(TString detector, AliTriggerConfiguration* trigConf) const {
565   // Check if a given detector was read-out in the analyzed event
566   const TObjArray& classesArray=trigConf->GetClasses();
567   ULong64_t trigMask=GetTriggerMask();
568   Int_t nclasses = classesArray.GetEntriesFast();
569   for(Int_t iclass=0; iclass < nclasses; iclass++ ) {
570     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
571     Int_t classMask=trclass->GetMask();
572     if(trigMask & classMask){
573       TString detList=trclass->GetCluster()->GetDetectorsInCluster();
574       if(detList.Contains(detector.Data())){
575         return kTRUE;
576       }
577     }
578   }
579   return kFALSE; 
580 }
581 //______________________________________________________________________________
582 void AliESDEvent::Print(Option_t *) const 
583 {
584   //
585   // Print header information of the event
586   //
587   printf("ESD run information\n");
588   printf("Event # in file %d Bunch crossing # %d Orbit # %d Period # %d Run # %d Trigger %lld Magnetic field %f \n",
589          GetEventNumberInFile(),
590          GetBunchCrossNumber(),
591          GetOrbitNumber(),
592          GetPeriodNumber(),
593          GetRunNumber(),
594          GetTriggerMask(),
595          GetMagneticField() );
596   if (fPrimaryVertex)
597     printf("Vertex: (%.4f +- %.4f, %.4f +- %.4f, %.4f +- %.4f) cm\n",
598            fPrimaryVertex->GetXv(), fPrimaryVertex->GetXRes(),
599            fPrimaryVertex->GetYv(), fPrimaryVertex->GetYRes(),
600            fPrimaryVertex->GetZv(), fPrimaryVertex->GetZRes());
601   printf("Mean vertex in RUN: X=%.4f Y=%.4f Z=%.4f cm\n",
602          GetDiamondX(),GetDiamondY(),GetDiamondZ());
603   if(fSPDMult)
604     printf("SPD Multiplicity. Number of tracklets %d \n",
605            fSPDMult->GetNumberOfTracklets());
606   printf("Number of pileup primary vertices reconstructed with SPD %d\n", 
607          GetNumberOfPileupVerticesSPD());
608   printf("Number of pileup primary vertices reconstructed using the tracks %d\n",
609          GetNumberOfPileupVerticesTracks());
610   printf("Number of tracks: \n");
611   printf("                 charged   %d\n", GetNumberOfTracks());
612   printf("                 muon      %d\n", GetNumberOfMuonTracks());
613   printf("                 pmd       %d\n", GetNumberOfPmdTracks());
614   printf("                 trd       %d\n", GetNumberOfTrdTracks());
615   printf("                 trd trkl  %d\n", GetNumberOfTrdTracklets());
616   printf("                 v0        %d\n", GetNumberOfV0s());
617   printf("                 cascades  %d\n", GetNumberOfCascades());
618   printf("                 kinks     %d\n", GetNumberOfKinks());
619   if(fPHOSCells)printf("                 PHOSCells %d\n", fPHOSCells->GetNumberOfCells());
620   else printf("                 PHOSCells not in the Event\n");
621   if(fEMCALCells)printf("                 EMCALCells %d\n", fEMCALCells->GetNumberOfCells());
622   else printf("                 EMCALCells not in the Event\n");
623   printf("                 CaloClusters %d\n", GetNumberOfCaloClusters());
624   printf("                 FMD       %s\n", (fESDFMD ? "yes" : "no"));
625   printf("                 VZERO     %s\n", (fESDVZERO ? "yes" : "no"));
626   printf("                 muClusters %d\n", fMuonClusters ? fMuonClusters->GetEntriesFast() : 0);
627   printf("                 muPad     %d\n", fMuonPads ? fMuonPads->GetEntriesFast() : 0);
628   if (fCosmicTracks) printf("                 Cosmics   %d\n",  GetNumberOfCosmicTracks());
629         
630   TObject* pHLTDecision=GetHLTTriggerDecision();
631   printf("HLT trigger decision: %s\n", pHLTDecision?pHLTDecision->GetOption():"not available");
632   if (pHLTDecision) pHLTDecision->Print("compact");
633
634   return;
635 }
636
637 void AliESDEvent::SetESDfriend(const AliESDfriend *ev) const {
638   //
639   // Attaches the complementary info to the ESD
640   //
641   if (!ev) return;
642
643   // to be sure that we set the tracks also
644   // in case of old esds 
645   // if(fESDOld)CopyFromOldESD();
646
647   Int_t ntrk=ev->GetNumberOfTracks();
648  
649   for (Int_t i=0; i<ntrk; i++) {
650     const AliESDfriendTrack *f=ev->GetTrack(i);
651     if (!f) {AliFatal(Form("NULL pointer for ESD track %d",i));}
652     GetTrack(i)->SetFriendTrack(f);
653   }
654 }
655
656 Bool_t  AliESDEvent::RemoveKink(Int_t rm) const {
657   // ---------------------------------------------------------
658   // Remove a kink candidate and references to it from ESD,
659   // if this candidate does not come from a reconstructed decay
660   // Not yet implemented...
661   // ---------------------------------------------------------
662   Int_t last=GetNumberOfKinks()-1;
663   if ((rm<0)||(rm>last)) return kFALSE;
664
665   return kTRUE;
666 }
667
668 Bool_t  AliESDEvent::RemoveV0(Int_t rm) const {
669   // ---------------------------------------------------------
670   // Remove a V0 candidate and references to it from ESD,
671   // if this candidate does not come from a reconstructed decay
672   // ---------------------------------------------------------
673   Int_t last=GetNumberOfV0s()-1;
674   if ((rm<0)||(rm>last)) return kFALSE;
675
676   AliESDv0 *v0=GetV0(rm);
677   Int_t idxP=v0->GetPindex(), idxN=v0->GetNindex();
678
679   v0=GetV0(last);
680   Int_t lastIdxP=v0->GetPindex(), lastIdxN=v0->GetNindex();
681
682   Int_t used=0;
683
684   // Check if this V0 comes from a reconstructed decay
685   Int_t ncs=GetNumberOfCascades();
686   for (Int_t n=0; n<ncs; n++) {
687     AliESDcascade *cs=GetCascade(n);
688
689     Int_t csIdxP=cs->GetPindex();
690     Int_t csIdxN=cs->GetNindex();
691
692     if (idxP==csIdxP)
693        if (idxN==csIdxN) return kFALSE;
694
695     if (csIdxP==lastIdxP)
696        if (csIdxN==lastIdxN) used++;
697   }
698
699   //Replace the removed V0 with the last V0 
700   TClonesArray &a=*fV0s;
701   delete a.RemoveAt(rm);
702
703   if (rm==last) return kTRUE;
704
705   //v0 is pointing to the last V0 candidate... 
706   new (a[rm]) AliESDv0(*v0);
707   delete a.RemoveAt(last);
708
709   if (!used) return kTRUE;
710   
711
712   // Remap the indices of the daughters of reconstructed decays
713   for (Int_t n=0; n<ncs; n++) {
714     AliESDcascade *cs=GetCascade(n);
715
716
717     Int_t csIdxP=cs->GetPindex();
718     Int_t csIdxN=cs->GetNindex();
719
720     if (csIdxP==lastIdxP)
721       if (csIdxN==lastIdxN) {
722          cs->AliESDv0::SetIndex(1,idxP);
723          cs->AliESDv0::SetIndex(0,idxN);
724          used--;
725          if (!used) return kTRUE;
726       }
727   }
728
729   return kTRUE;
730 }
731
732 Bool_t  AliESDEvent::RemoveTrack(Int_t rm) const {
733   // ---------------------------------------------------------
734   // Remove a track and references to it from ESD,
735   // if this track does not come from a reconstructed decay
736   // ---------------------------------------------------------
737   Int_t last=GetNumberOfTracks()-1;
738   if ((rm<0)||(rm>last)) return kFALSE;
739
740   Int_t used=0;
741
742   // Check if this track comes from the reconstructed primary vertices
743   if (fTPCVertex && fTPCVertex->GetStatus()) {
744      UShort_t *primIdx=fTPCVertex->GetIndices();
745      Int_t n=fTPCVertex->GetNIndices();
746      while (n--) {
747        Int_t idx=Int_t(primIdx[n]);
748        if (rm==idx) return kFALSE;
749        if (idx==last) used++; 
750      }
751   }
752   if (fPrimaryVertex && fPrimaryVertex->GetStatus()) {
753      UShort_t *primIdx=fPrimaryVertex->GetIndices();
754      Int_t n=fPrimaryVertex->GetNIndices();
755      while (n--) {
756        Int_t idx=Int_t(primIdx[n]);
757        if (rm==idx) return kFALSE;
758        if (idx==last) used++; 
759      }
760   }
761   
762   // Check if this track comes from a reconstructed decay
763   Int_t nv0=GetNumberOfV0s();
764   for (Int_t n=0; n<nv0; n++) {
765     AliESDv0 *v0=GetV0(n);
766
767     Int_t idx=v0->GetNindex();
768     if (rm==idx) return kFALSE;
769     if (idx==last) used++;
770
771     idx=v0->GetPindex();
772     if (rm==idx) return kFALSE;
773     if (idx==last) used++;
774   }
775
776   Int_t ncs=GetNumberOfCascades();
777   for (Int_t n=0; n<ncs; n++) {
778     AliESDcascade *cs=GetCascade(n);
779
780     Int_t idx=cs->GetIndex();
781     if (rm==idx) return kFALSE;
782     if (idx==last) used++;
783
784     AliESDv0 *v0=cs;
785     idx=v0->GetNindex();
786     if (rm==idx) return kFALSE;
787     if (idx==last) used++;
788
789     idx=v0->GetPindex();
790     if (rm==idx) return kFALSE;
791     if (idx==last) used++;
792   }
793
794   Int_t nkn=GetNumberOfKinks();
795   for (Int_t n=0; n<nkn; n++) {
796     AliESDkink *kn=GetKink(n);
797
798     Int_t idx=kn->GetIndex(0);
799     if (rm==idx) return kFALSE;
800     if (idx==last) used++;
801
802     idx=kn->GetIndex(1);
803     if (rm==idx) return kFALSE;
804     if (idx==last) used++;
805   }
806
807   // Check if this track is associated with a CaloCluster
808   Int_t ncl=GetNumberOfCaloClusters();
809   for (Int_t n=0; n<ncl; n++) {
810     AliESDCaloCluster *cluster=GetCaloCluster(n);
811     TArrayI *arr=cluster->GetTracksMatched();
812     Int_t s=arr->GetSize();
813     while (s--) {
814       Int_t idx=arr->At(s);
815       if (rm==idx) return kFALSE;
816       if (idx==last) used++;     
817     }
818   }
819
820
821
822   //Replace the removed track with the last track 
823   TClonesArray &a=*fTracks;
824   delete a.RemoveAt(rm);
825
826   if (rm==last) return kTRUE;
827
828   AliESDtrack *t=GetTrack(last);
829   if (!t) {AliFatal(Form("NULL pointer for ESD track %d",last));}
830   t->SetID(rm);
831   new (a[rm]) AliESDtrack(*t);
832   delete a.RemoveAt(last);
833
834
835   if (!used) return kTRUE;
836   
837
838   // Remap the indices of the tracks used for the primary vertex reconstruction
839   if (fTPCVertex && fTPCVertex->GetStatus()) {
840      UShort_t *primIdx=fTPCVertex->GetIndices();
841      Int_t n=fTPCVertex->GetNIndices();
842      while (n--) {
843        Int_t idx=Int_t(primIdx[n]);
844        if (idx==last) {
845           primIdx[n]=Short_t(rm); 
846           used--;
847           if (!used) return kTRUE;
848        }
849      }
850   }  
851   if (fPrimaryVertex && fPrimaryVertex->GetStatus()) {
852      UShort_t *primIdx=fPrimaryVertex->GetIndices();
853      Int_t n=fPrimaryVertex->GetNIndices();
854      while (n--) {
855        Int_t idx=Int_t(primIdx[n]);
856        if (idx==last) {
857           primIdx[n]=Short_t(rm); 
858           used--;
859           if (!used) return kTRUE;
860        }
861      }
862   }  
863
864   // Remap the indices of the daughters of reconstructed decays
865   for (Int_t n=0; n<nv0; n++) {
866     AliESDv0 *v0=GetV0(n);
867     if (v0->GetIndex(0)==last) {
868        v0->SetIndex(0,rm);
869        used--;
870        if (!used) return kTRUE;
871     }
872     if (v0->GetIndex(1)==last) {
873        v0->SetIndex(1,rm);
874        used--;
875        if (!used) return kTRUE;
876     }
877   }
878
879   for (Int_t n=0; n<ncs; n++) {
880     AliESDcascade *cs=GetCascade(n);
881     if (cs->GetIndex()==last) {
882        cs->SetIndex(rm);
883        used--;
884        if (!used) return kTRUE;
885     }
886     AliESDv0 *v0=cs;
887     if (v0->GetIndex(0)==last) {
888        v0->SetIndex(0,rm);
889        used--;
890        if (!used) return kTRUE;
891     }
892     if (v0->GetIndex(1)==last) {
893        v0->SetIndex(1,rm);
894        used--;
895        if (!used) return kTRUE;
896     }
897   }
898
899   for (Int_t n=0; n<nkn; n++) {
900     AliESDkink *kn=GetKink(n);
901     if (kn->GetIndex(0)==last) {
902        kn->SetIndex(rm,0);
903        used--;
904        if (!used) return kTRUE;
905     }
906     if (kn->GetIndex(1)==last) {
907        kn->SetIndex(rm,1);
908        used--;
909        if (!used) return kTRUE;
910     }
911   }
912
913   // Remap the indices of the tracks accosicated with CaloClusters
914   for (Int_t n=0; n<ncl; n++) {
915     AliESDCaloCluster *cluster=GetCaloCluster(n);
916     TArrayI *arr=cluster->GetTracksMatched();
917     Int_t s=arr->GetSize();
918     while (s--) {
919       Int_t idx=arr->At(s);
920       if (idx==last) {
921          arr->AddAt(rm,s);
922          used--; 
923          if (!used) return kTRUE;
924       }
925     }
926   }
927
928   return kTRUE;
929 }
930
931
932 Bool_t AliESDEvent::Clean(Float_t *cleanPars) {
933   //
934   // Remove the data which are not needed for the physics analysis.
935   //
936   // 1) Cleaning the V0 candidates
937   //    ---------------------------
938   //    If the cosine of the V0 pointing angle "csp" and 
939   //    the DCA between the daughter tracks "dca" does not satisfy 
940   //    the conditions 
941   //
942   //     csp > cleanPars[1] + dca/cleanPars[0]*(1.- cleanPars[1])
943   //
944   //    an attempt to remove this V0 candidate from ESD is made.
945   //
946   //    The V0 candidate gets removed if it does not belong to any 
947   //    recosntructed cascade decay
948   //
949   //    12.11.2007, optimal values: cleanPars[0]=0.5, cleanPars[1]=0.999
950   //
951   // 2) Cleaning the tracks
952   //    ----------------------
953   //    If track's transverse parameter is larger than cleanPars[2]
954   //                       OR
955   //    track's longitudinal parameter is larger than cleanPars[3]
956   //    an attempt to remove this track from ESD is made.
957   //
958   //    The track gets removed if it does not come 
959   //    from a reconstructed decay
960   //
961   Bool_t rc=kFALSE;
962
963   Float_t dcaMax=cleanPars[0];
964   Float_t cspMin=cleanPars[1];
965
966   Int_t nV0s=GetNumberOfV0s();
967   for (Int_t i=nV0s-1; i>=0; i--) {
968     AliESDv0 *v0=GetV0(i);
969
970     Float_t dca=v0->GetDcaV0Daughters();
971     Float_t csp=v0->GetV0CosineOfPointingAngle();
972     Float_t cspcut=cspMin + dca/dcaMax*(1.-cspMin);
973     if (csp > cspcut) continue;
974     if (RemoveV0(i)) rc=kTRUE;
975   }
976
977
978   Float_t dmax=cleanPars[2], zmax=cleanPars[3];
979
980   const AliESDVertex *vertex=GetPrimaryVertexSPD();
981   Bool_t vtxOK=vertex->GetStatus();
982   
983   Int_t nTracks=GetNumberOfTracks();
984   for (Int_t i=nTracks-1; i>=0; i--) {
985     AliESDtrack *track=GetTrack(i);
986     if (!track) {AliFatal(Form("NULL pointer for ESD track %d",i));}
987     Float_t xy,z; track->GetImpactParameters(xy,z);
988     if ((TMath::Abs(xy) > dmax) || (vtxOK && (TMath::Abs(z) > zmax))) {
989       if (RemoveTrack(i)) rc=kTRUE;
990     }
991   }
992
993   return rc;
994 }
995
996 Char_t  AliESDEvent::AddPileupVertexSPD(const AliESDVertex *vtx) 
997 {
998     // Add a pileup primary vertex reconstructed with SPD
999     TClonesArray &ftr = *fSPDPileupVertices;
1000     Char_t n=Char_t(ftr.GetEntriesFast());
1001     AliESDVertex *vertex = new(ftr[n]) AliESDVertex(*vtx);
1002     vertex->SetID(n);
1003     return n;
1004 }
1005
1006 Char_t  AliESDEvent::AddPileupVertexTracks(const AliESDVertex *vtx) 
1007 {
1008     // Add a pileup primary vertex reconstructed with SPD
1009     TClonesArray &ftr = *fTrkPileupVertices;
1010     Char_t n=Char_t(ftr.GetEntriesFast());
1011     AliESDVertex *vertex = new(ftr[n]) AliESDVertex(*vtx);
1012     vertex->SetID(n);
1013     return n;
1014 }
1015
1016 Int_t  AliESDEvent::AddTrack(const AliESDtrack *t) 
1017 {
1018     // Add track
1019     TClonesArray &ftr = *fTracks;
1020     AliESDtrack * track = new(ftr[fTracks->GetEntriesFast()])AliESDtrack(*t);
1021     track->SetID(fTracks->GetEntriesFast()-1);
1022     return  track->GetID();    
1023 }
1024
1025 AliESDtrack*  AliESDEvent::NewTrack() 
1026 {
1027     // Add a new track
1028     TClonesArray &ftr = *fTracks;
1029     AliESDtrack * track = new(ftr[fTracks->GetEntriesFast()])AliESDtrack();
1030     track->SetID(fTracks->GetEntriesFast()-1);
1031     return  track;
1032 }
1033
1034 //______________________________________________________________________________
1035 Bool_t AliESDEvent::MoveMuonObjects() 
1036 {
1037   // move MUON clusters and pads to the new ESD structure in needed.
1038   // to ensure backward compatibility
1039   
1040   if (!fOldMuonStructure) return kTRUE;
1041   
1042   if (!fMuonTracks || !fMuonClusters || !fMuonPads) return kFALSE;
1043   
1044   Bool_t reset = kTRUE;
1045   Bool_t containTrackerData = kFALSE;
1046   for (Int_t i = 0; i < fMuonTracks->GetEntriesFast(); i++) {
1047     
1048     AliESDMuonTrack *track = (AliESDMuonTrack*) fMuonTracks->UncheckedAt(i);
1049     
1050     if (track->ContainTrackerData()) containTrackerData = kTRUE;
1051     else continue;
1052     
1053     if (!track->IsOldTrack()) continue;
1054     
1055     // remove objects connected to previous event if needed
1056     if (reset) {
1057       if (fMuonClusters->GetEntriesFast() > 0) fMuonClusters->Clear("C");
1058       if (fMuonPads->GetEntriesFast() > 0) fMuonPads->Clear("C");
1059       reset = kFALSE;
1060     }
1061     
1062     track->MoveClustersToESD(*this);
1063     
1064   }
1065   
1066   // remove objects connected to previous event if needed
1067   if (!containTrackerData) {
1068     if (fMuonClusters->GetEntriesFast() > 0) fMuonClusters->Clear("C");
1069     if (fMuonPads->GetEntriesFast() > 0) fMuonPads->Clear("C");
1070   }
1071   
1072   return kTRUE;
1073 }
1074
1075 //______________________________________________________________________________
1076 AliESDMuonTrack* AliESDEvent::GetMuonTrack(Int_t i)
1077 {
1078   // get the MUON track at the position i in the internal array of track
1079   if (!fMuonTracks) return 0x0;
1080   if (!MoveMuonObjects()) return 0x0;
1081   AliESDMuonTrack *track = (AliESDMuonTrack*) fMuonTracks->UncheckedAt(i);
1082   track->SetESDEvent(this);
1083   return track;
1084 }
1085
1086 //______________________________________________________________________________
1087 void AliESDEvent::AddMuonTrack(const AliESDMuonTrack *t) 
1088 {
1089   // add a MUON track
1090   TClonesArray &fmu = *fMuonTracks;
1091   AliESDMuonTrack *track = new(fmu[fMuonTracks->GetEntriesFast()]) AliESDMuonTrack(*t);
1092   track->MoveClustersToESD(*this);
1093 }
1094
1095 //______________________________________________________________________________
1096 AliESDMuonTrack* AliESDEvent::NewMuonTrack() 
1097 {
1098   // create a new MUON track at the end of the internal array of track
1099   TClonesArray &fmu = *fMuonTracks;
1100   return new(fmu[fMuonTracks->GetEntriesFast()]) AliESDMuonTrack();
1101 }
1102
1103 //______________________________________________________________________________
1104 Int_t AliESDEvent::GetNumberOfMuonClusters()
1105 {
1106   // get the number of MUON clusters
1107   if (!fMuonClusters) return 0;
1108   if (!MoveMuonObjects()) return 0;
1109   return fMuonClusters->GetEntriesFast();
1110 }
1111
1112 //______________________________________________________________________________
1113 AliESDMuonCluster* AliESDEvent::GetMuonCluster(Int_t i)
1114 {
1115   // get the MUON cluster at the position i in the internal array of cluster
1116   if (!fMuonClusters) return 0x0;
1117   if (!MoveMuonObjects()) return 0x0;
1118   return (AliESDMuonCluster*) fMuonClusters->UncheckedAt(i);
1119 }
1120
1121 //______________________________________________________________________________
1122 AliESDMuonCluster* AliESDEvent::FindMuonCluster(UInt_t clusterId)
1123 {
1124   // find the MUON cluster with this Id in the internal array of cluster
1125   if (!fMuonClusters) return 0x0;
1126   if (!MoveMuonObjects()) return 0x0;
1127   for (Int_t i = 0; i < fMuonClusters->GetEntriesFast(); i++) {
1128     AliESDMuonCluster *cluster = (AliESDMuonCluster*) fMuonClusters->UncheckedAt(i);
1129     if (cluster->GetUniqueID() == clusterId) return cluster;
1130   }
1131   return 0x0;
1132 }
1133
1134 //______________________________________________________________________________
1135 AliESDMuonCluster* AliESDEvent::NewMuonCluster() 
1136 {
1137   // create a new MUON cluster at the end of the internal array of cluster
1138   TClonesArray &fmu = *fMuonClusters;
1139   return new(fmu[fMuonClusters->GetEntriesFast()]) AliESDMuonCluster();
1140 }
1141
1142 //______________________________________________________________________________
1143 Int_t AliESDEvent::GetNumberOfMuonPads()
1144 {
1145   // get the number of MUON pads
1146   if (!fMuonPads) return 0;
1147   if (!MoveMuonObjects()) return 0;
1148   return fMuonPads->GetEntriesFast();
1149 }
1150
1151 //______________________________________________________________________________
1152 AliESDMuonPad* AliESDEvent::GetMuonPad(Int_t i)
1153 {
1154   // get the MUON pad at the position i in the internal array of pad
1155   if (!fMuonPads) return 0x0;
1156   if (!MoveMuonObjects()) return 0x0;
1157   return (AliESDMuonPad*) fMuonPads->UncheckedAt(i);
1158 }
1159
1160 //______________________________________________________________________________
1161 AliESDMuonPad* AliESDEvent::FindMuonPad(UInt_t padId)
1162 {
1163   // find the MUON pad with this Id in the internal array of pad
1164   if (!fMuonPads) return 0x0;
1165   if (!MoveMuonObjects()) return 0x0;
1166   for (Int_t i = 0; i < fMuonPads->GetEntriesFast(); i++) {
1167     AliESDMuonPad *pad = (AliESDMuonPad*) fMuonPads->UncheckedAt(i);
1168     if (pad->GetUniqueID() == padId) return pad;
1169   }
1170   return 0x0;
1171 }
1172
1173 //______________________________________________________________________________
1174 AliESDMuonPad* AliESDEvent::NewMuonPad() 
1175 {
1176   // create a new MUON pad at the end of the internal array of pad
1177   TClonesArray &fmu = *fMuonPads;
1178   return new(fmu[fMuonPads->GetEntriesFast()]) AliESDMuonPad();
1179 }
1180
1181 void AliESDEvent::AddPmdTrack(const AliESDPmdTrack *t) 
1182 {
1183   TClonesArray &fpmd = *fPmdTracks;
1184   new(fpmd[fPmdTracks->GetEntriesFast()]) AliESDPmdTrack(*t);
1185 }
1186
1187 void AliESDEvent::SetTrdTrigger(const AliESDTrdTrigger *t)
1188 {
1189   *fTrdTrigger = *t;
1190 }
1191
1192 void AliESDEvent::AddTrdTrack(const AliESDTrdTrack *t) 
1193 {
1194   TClonesArray &ftrd = *fTrdTracks;
1195   new(ftrd[fTrdTracks->GetEntriesFast()]) AliESDTrdTrack(*t);
1196 }
1197
1198 void AliESDEvent::AddTrdTracklet(const AliESDTrdTracklet *trkl)
1199 {
1200   new ((*fTrdTracklets)[fTrdTracklets->GetEntriesFast()]) AliESDTrdTracklet(*trkl);
1201 }
1202
1203 void AliESDEvent::AddTrdTracklet(UInt_t trackletWord, Short_t hcid, Int_t label)
1204 {
1205   new ((*fTrdTracklets)[fTrdTracklets->GetEntriesFast()]) AliESDTrdTracklet(trackletWord, hcid, label);
1206 }
1207
1208 Int_t AliESDEvent::AddKink(const AliESDkink *c) 
1209 {
1210     // Add kink
1211     TClonesArray &fk = *fKinks;
1212     AliESDkink * kink = new(fk[fKinks->GetEntriesFast()]) AliESDkink(*c);
1213     kink->SetID(fKinks->GetEntriesFast()); // CKB different from the other imps..
1214     return fKinks->GetEntriesFast()-1;
1215 }
1216
1217
1218 void AliESDEvent::AddCascade(const AliESDcascade *c) 
1219 {
1220   TClonesArray &fc = *fCascades;
1221   new(fc[fCascades->GetEntriesFast()]) AliESDcascade(*c);
1222 }
1223
1224 void AliESDEvent::AddCosmicTrack(const AliESDCosmicTrack *t) 
1225 {
1226   TClonesArray &ft = *fCosmicTracks;
1227   new(ft[fCosmicTracks->GetEntriesFast()]) AliESDCosmicTrack(*t);
1228
1229
1230
1231 Int_t AliESDEvent::AddCaloCluster(const AliESDCaloCluster *c) 
1232 {
1233     // Add calocluster
1234     TClonesArray &fc = *fCaloClusters;
1235     AliESDCaloCluster *clus = new(fc[fCaloClusters->GetEntriesFast()]) AliESDCaloCluster(*c);
1236     clus->SetID(fCaloClusters->GetEntriesFast()-1);
1237     return fCaloClusters->GetEntriesFast()-1;
1238   }
1239
1240
1241 void  AliESDEvent::AddRawDataErrorLog(const AliRawDataErrorLog *log) const {
1242   TClonesArray &errlogs = *fErrorLogs;
1243   new(errlogs[errlogs.GetEntriesFast()])  AliRawDataErrorLog(*log);
1244 }
1245
1246 void AliESDEvent::SetZDCData(const AliESDZDC * obj)
1247
1248   // use already allocated space
1249   if(fESDZDC)
1250     *fESDZDC = *obj;
1251 }
1252
1253 void  AliESDEvent::SetPrimaryVertexTPC(const AliESDVertex *vertex) 
1254 {
1255   // Set the TPC vertex
1256   // use already allocated space
1257   if(fTPCVertex){
1258     *fTPCVertex = *vertex;
1259     fTPCVertex->SetName(fgkESDListName[kTPCVertex]);
1260   }
1261 }
1262
1263 void  AliESDEvent::SetPrimaryVertexSPD(const AliESDVertex *vertex) 
1264 {
1265   // Set the SPD vertex
1266   // use already allocated space
1267   if(fSPDVertex){
1268     *fSPDVertex = *vertex;
1269     fSPDVertex->SetName(fgkESDListName[kSPDVertex]);
1270   }
1271 }
1272
1273 void  AliESDEvent::SetPrimaryVertexTracks(const AliESDVertex *vertex) 
1274 {
1275   // Set the primary vertex reconstructed using he ESD tracks.
1276   // use already allocated space
1277   if(fPrimaryVertex){
1278     *fPrimaryVertex = *vertex;
1279     fPrimaryVertex->SetName(fgkESDListName[kPrimaryVertex]);
1280   }
1281 }
1282
1283 const AliESDVertex * AliESDEvent::GetPrimaryVertex() const 
1284 {
1285   //
1286   // Get the "best" available reconstructed primary vertex.
1287   //
1288   if(fPrimaryVertex){
1289     if (fPrimaryVertex->GetStatus()) return fPrimaryVertex;
1290   }
1291   if(fSPDVertex){
1292     if (fSPDVertex->GetStatus()) return fSPDVertex;
1293   }
1294   if(fTPCVertex) return fTPCVertex;
1295   
1296   AliWarning("No primary vertex available. Returning the \"default\"...");
1297   return fSPDVertex;
1298 }
1299
1300 AliESDVertex * AliESDEvent::PrimaryVertexTracksUnconstrained() const 
1301 {
1302   //
1303   // Removes diamond constraint from fPrimaryVertex (reconstructed with tracks)
1304   // Returns a AliESDVertex which has to be deleted by the user
1305   //
1306   if(!fPrimaryVertex) {
1307     AliWarning("No primary vertex from tracks available.");
1308     return 0;
1309   }
1310   if(!fPrimaryVertex->GetStatus()) {
1311     AliWarning("No primary vertex from tracks available.");
1312     return 0;
1313   }
1314
1315   AliVertexerTracks vertexer(GetMagneticField());
1316   Float_t diamondxyz[3]={(Float_t)GetDiamondX(),(Float_t)GetDiamondY(),0.};
1317   Float_t diamondcovxy[3]; GetDiamondCovXY(diamondcovxy);
1318   Float_t diamondcov[6]={diamondcovxy[0],diamondcovxy[1],diamondcovxy[2],0.,0.,7.};
1319   AliESDVertex *vertex = 
1320     (AliESDVertex*)vertexer.RemoveConstraintFromVertex(fPrimaryVertex,diamondxyz,diamondcov);
1321
1322   return vertex;
1323 }
1324
1325 void AliESDEvent::SetMultiplicity(const AliMultiplicity *mul) 
1326 {
1327   // Set the SPD Multiplicity
1328   if(fSPDMult){
1329     *fSPDMult = *mul;
1330   }
1331 }
1332
1333
1334 void AliESDEvent::SetFMDData(AliESDFMD * obj) 
1335
1336   // use already allocated space
1337   if(fESDFMD){
1338     *fESDFMD = *obj;
1339   }
1340 }
1341
1342 void AliESDEvent::SetVZEROData(const AliESDVZERO * obj)
1343
1344   // use already allocated space
1345   if(fESDVZERO)
1346     *fESDVZERO = *obj;
1347 }
1348
1349 void AliESDEvent::SetTZEROData(const AliESDTZERO * obj)
1350
1351   // use already allocated space
1352   if(fESDTZERO)
1353     *fESDTZERO = *obj;
1354 }
1355
1356
1357 void AliESDEvent::SetACORDEData(AliESDACORDE * obj)
1358 {
1359   if(fESDACORDE)
1360     *fESDACORDE = *obj;
1361 }
1362
1363 void AliESDEvent::SetADData(AliESDAD * obj)
1364 {
1365   if(fESDAD)
1366     *fESDAD = *obj;
1367 }
1368
1369
1370
1371 void AliESDEvent::GetESDfriend(AliESDfriend *ev) const 
1372 {
1373   //
1374   // Extracts the complementary info from the ESD
1375   //
1376   if (!ev) return;
1377
1378   Int_t ntrk=GetNumberOfTracks();
1379
1380   for (Int_t i=0; i<ntrk; i++) {
1381     AliESDtrack *t=GetTrack(i);
1382     if (!t) {AliFatal(Form("NULL pointer for ESD track %d",i));}
1383     const AliESDfriendTrack *f=t->GetFriendTrack();
1384     ev->AddTrack(f);
1385
1386     t->ReleaseESDfriendTrack();// Not to have two copies of "friendTrack"
1387
1388   }
1389
1390   AliESDfriend *fr = (AliESDfriend*)(const_cast<AliESDEvent*>(this)->FindListObject("AliESDfriend"));
1391   if (fr) ev->SetVZEROfriend(fr->GetVZEROfriend());
1392 }
1393
1394 void AliESDEvent::AddObject(TObject* obj) 
1395 {
1396   // Add an object to the list of object.
1397   // Please be aware that in order to increase performance you should
1398   // refrain from using TObjArrays (if possible). Use TClonesArrays, instead.
1399   fESDObjects->SetOwner(kTRUE);
1400   fESDObjects->AddLast(obj);
1401 }
1402
1403
1404 void AliESDEvent::GetStdContent() 
1405 {
1406   // set pointers for standard content
1407   // get by name much safer and not a big overhead since not called very often
1408  
1409   fESDRun = (AliESDRun*)fESDObjects->FindObject(fgkESDListName[kESDRun]);
1410   fHeader = (AliESDHeader*)fESDObjects->FindObject(fgkESDListName[kHeader]);
1411   fESDZDC = (AliESDZDC*)fESDObjects->FindObject(fgkESDListName[kESDZDC]);
1412   fESDFMD = (AliESDFMD*)fESDObjects->FindObject(fgkESDListName[kESDFMD]);
1413   fESDVZERO = (AliESDVZERO*)fESDObjects->FindObject(fgkESDListName[kESDVZERO]);
1414   fESDTZERO = (AliESDTZERO*)fESDObjects->FindObject(fgkESDListName[kESDTZERO]);
1415   fTPCVertex = (AliESDVertex*)fESDObjects->FindObject(fgkESDListName[kTPCVertex]);
1416   fSPDVertex = (AliESDVertex*)fESDObjects->FindObject(fgkESDListName[kSPDVertex]);
1417   fPrimaryVertex = (AliESDVertex*)fESDObjects->FindObject(fgkESDListName[kPrimaryVertex]);
1418   fSPDMult =       (AliMultiplicity*)fESDObjects->FindObject(fgkESDListName[kSPDMult]);
1419   fPHOSTrigger = (AliESDCaloTrigger*)fESDObjects->FindObject(fgkESDListName[kPHOSTrigger]);
1420   fEMCALTrigger = (AliESDCaloTrigger*)fESDObjects->FindObject(fgkESDListName[kEMCALTrigger]);
1421   fSPDPileupVertices = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kSPDPileupVertices]);
1422   fTrkPileupVertices = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTrkPileupVertices]);
1423   fTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTracks]);
1424   fMuonTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kMuonTracks]);
1425   fMuonClusters = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kMuonClusters]);
1426   fMuonPads = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kMuonPads]);
1427   fPmdTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kPmdTracks]);
1428   fTrdTrigger = (AliESDTrdTrigger*)fESDObjects->FindObject(fgkESDListName[kTrdTrigger]);
1429   fTrdTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTrdTracks]);
1430   fTrdTracklets = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTrdTracklets]);
1431   fV0s = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kV0s]);
1432   fCascades = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kCascades]);
1433   fKinks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kKinks]);
1434   fCaloClusters = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kCaloClusters]);
1435   fEMCALCells = (AliESDCaloCells*)fESDObjects->FindObject(fgkESDListName[kEMCALCells]);
1436   fPHOSCells = (AliESDCaloCells*)fESDObjects->FindObject(fgkESDListName[kPHOSCells]);
1437   fErrorLogs = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kErrorLogs]);
1438   fESDACORDE = (AliESDACORDE*)fESDObjects->FindObject(fgkESDListName[kESDACORDE]);
1439   fESDAD = (AliESDAD*)fESDObjects->FindObject(fgkESDListName[kESDAD]);
1440   fTOFHeader = (AliTOFHeader*)fESDObjects->FindObject(fgkESDListName[kTOFHeader]);
1441   fCosmicTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kCosmicTracks]);
1442   fTOFcluster = new TObjArray(1);
1443 }
1444
1445 void AliESDEvent::SetStdNames(){
1446   // Set the names of the standard contents
1447   // 
1448   if(fESDObjects->GetEntries()>=kESDListN){
1449     for(int i = 0;i < fESDObjects->GetEntries() && i<kESDListN;i++){
1450       TObject *fObj = fESDObjects->At(i);
1451       if(fObj->InheritsFrom("TNamed")){
1452         ((TNamed*)fObj)->SetName(fgkESDListName[i]);
1453       }
1454       else if(fObj->InheritsFrom("TClonesArray")){
1455         ((TClonesArray*)fObj)->SetName(fgkESDListName[i]);
1456       }
1457     }
1458   }
1459   else{
1460      AliWarning("Std Entries missing");
1461   }
1462
1463
1464
1465 void AliESDEvent::CreateStdContent(Bool_t bUseThisList){
1466   fUseOwnList = bUseThisList;
1467   CreateStdContent();
1468 }
1469
1470 void AliESDEvent::CreateStdContent() 
1471 {
1472   // create the standard AOD content and set pointers
1473
1474   // create standard objects and add them to the TList of objects
1475   AddObject(new AliESDRun());
1476   AddObject(new AliESDHeader());
1477   AddObject(new AliESDZDC());
1478   AddObject(new AliESDFMD());
1479   AddObject(new AliESDVZERO());
1480   AddObject(new AliESDTZERO());
1481   AddObject(new AliESDVertex());
1482   AddObject(new AliESDVertex());
1483   AddObject(new AliESDVertex());
1484   AddObject(new AliMultiplicity());
1485   AddObject(new AliESDCaloTrigger());
1486   AddObject(new AliESDCaloTrigger());
1487   AddObject(new TClonesArray("AliESDVertex",0));
1488   AddObject(new TClonesArray("AliESDVertex",0));
1489   AddObject(new TClonesArray("AliESDtrack",0));
1490   AddObject(new TClonesArray("AliESDMuonTrack",0));
1491   AddObject(new TClonesArray("AliESDMuonCluster",0));
1492   AddObject(new TClonesArray("AliESDMuonPad",0));
1493   AddObject(new TClonesArray("AliESDPmdTrack",0));
1494   AddObject(new AliESDTrdTrigger());
1495   AddObject(new TClonesArray("AliESDTrdTrack",0));
1496   AddObject(new TClonesArray("AliESDTrdTracklet",0));
1497   AddObject(new TClonesArray("AliESDv0",0));
1498   AddObject(new TClonesArray("AliESDcascade",0));
1499   AddObject(new TClonesArray("AliESDkink",0));
1500   AddObject(new TClonesArray("AliESDCaloCluster",0));
1501   AddObject(new AliESDCaloCells());
1502   AddObject(new AliESDCaloCells());
1503   AddObject(new TClonesArray("AliRawDataErrorLog",0));
1504   AddObject(new AliESDACORDE()); 
1505   AddObject(new AliESDAD()); 
1506   AddObject(new AliTOFHeader());
1507   AddObject(new TClonesArray("AliESDCosmicTrack",0));
1508         
1509   // check the order of the indices against enum...
1510
1511   // set names
1512   SetStdNames();
1513   // read back pointers
1514   GetStdContent();
1515 }
1516
1517 void AliESDEvent::CompleteStdContent() 
1518 {
1519   // Create missing standard objects and add them to the TList of objects
1520   //
1521   // Add cosmic tracks for cases where esd files were created 
1522   // before adding them to the std content
1523   if (!fESDObjects->FindObject(fgkESDListName[kCosmicTracks])) {
1524     TClonesArray* cosmics = new TClonesArray("AliESDCosmicTrack",0);
1525     fESDObjects->AddAt(cosmics, kCosmicTracks);
1526     fESDObjects->SetOwner(kTRUE);
1527   }
1528   // Add new MUON containers if missing (for backward compatibility)
1529   if (!fESDObjects->FindObject(fgkESDListName[kMuonClusters])) {
1530     TClonesArray* muonClusters = new TClonesArray("AliESDMuonCluster",0);
1531     muonClusters->SetName(fgkESDListName[kMuonClusters]);
1532     fESDObjects->AddAt(muonClusters, kMuonClusters);
1533     fESDObjects->SetOwner(kTRUE);
1534   }
1535   if (!fESDObjects->FindObject(fgkESDListName[kMuonPads])) {
1536     TClonesArray* muonPads = new TClonesArray("AliESDMuonPad",0);
1537     muonPads->SetName(fgkESDListName[kMuonPads]);
1538     fESDObjects->AddAt(muonPads, kMuonPads);
1539     fESDObjects->SetOwner(kTRUE);
1540   }
1541 }
1542
1543 TObject* AliESDEvent::FindListObject(const char *name) const {
1544 //
1545 // Find object with name "name" in the list of branches
1546 //
1547   if(fESDObjects){
1548     return fESDObjects->FindObject(name);
1549   }
1550   return 0;
1551
1552
1553 Int_t AliESDEvent::GetPHOSClusters(TRefArray *clusters) const
1554 {
1555   // fills the provided TRefArray with all found phos clusters
1556   
1557   clusters->Clear();
1558   
1559   AliESDCaloCluster *cl = 0;
1560   for (Int_t i = 0; i < GetNumberOfCaloClusters(); i++) {
1561     
1562     if ( (cl = GetCaloCluster(i)) ) {
1563       if (cl->IsPHOS()){
1564         clusters->Add(cl);
1565         AliDebug(1,Form("IsPHOS cluster %d Size: %d \n",i,clusters->GetEntriesFast()));
1566       }
1567     }
1568   }
1569   return clusters->GetEntriesFast();
1570 }
1571
1572 Int_t AliESDEvent::GetEMCALClusters(TRefArray *clusters) const
1573 {
1574   // fills the provided TRefArray with all found emcal clusters
1575
1576   clusters->Clear();
1577
1578   AliESDCaloCluster *cl = 0;
1579   for (Int_t i = 0; i < GetNumberOfCaloClusters(); i++) {
1580
1581     if ( (cl = GetCaloCluster(i)) ) {
1582       if (cl->IsEMCAL()){
1583         clusters->Add(cl);
1584         AliDebug(1,Form("IsEMCAL cluster %d Size: %d \n",i,clusters->GetEntriesFast()));
1585       }
1586     }
1587   }
1588   return clusters->GetEntriesFast();
1589 }
1590
1591 void AliESDEvent::WriteToTree(TTree* tree) const {
1592   // Book the branches as in TTree::Branch(TCollection*)
1593   // but add a "." at the end of top level branches which are
1594   // not a TClonesArray
1595
1596
1597   TString branchname;
1598   TIter next(fESDObjects);
1599   const Int_t kSplitlevel = 99; // default value in TTree::Branch()
1600   const Int_t kBufsize = 32000; // default value in TTree::Branch()
1601   TObject *obj = 0;
1602
1603   while ((obj = next())) {
1604     branchname.Form("%s", obj->GetName());
1605     if(branchname.CompareTo("AliESDfriend")==0)branchname = "ESDfriend.";
1606     if ((kSplitlevel > 1) &&  !obj->InheritsFrom(TClonesArray::Class())) {
1607       if(!branchname.EndsWith("."))branchname += ".";
1608     }
1609     if (!tree->FindBranch(branchname)) {
1610       // For the custom streamer to be called splitlevel
1611       // has to be negative, only needed for HLT
1612       Int_t splitLevel = (TString(obj->ClassName()) == "AliHLTGlobalTriggerDecision") ? -1 : kSplitlevel - 1;
1613       tree->Bronch(branchname, obj->ClassName(), fESDObjects->GetObjectRef(obj),kBufsize, splitLevel);
1614     }
1615   }
1616
1617   tree->Branch("fDetectorStatus",(void*)&fDetectorStatus,"fDetectorStatus/l");
1618   tree->Branch("fDAQDetectorPattern",(void*)&fDAQDetectorPattern,"fDAQDetectorPattern/i");
1619   tree->Branch("fDAQAttributes",(void*)&fDAQAttributes,"fDAQAttributes/i");
1620   tree->Branch("fNTOFclusters",(void *) &fNTOFclusters,"fNTOFclusters/i");
1621   tree->Branch("fTOFcluster","TObjArray",(void *) &fTOFcluster);
1622 }
1623
1624
1625 void AliESDEvent::ReadFromTree(TTree *tree, Option_t* opt){
1626 //
1627 // Connect the ESDEvent to a tree
1628 //
1629   if(!tree){
1630     AliWarning("AliESDEvent::ReadFromTree() Zero Pointer to Tree \n");
1631     return;
1632   }
1633   // load the TTree
1634   if(!tree->GetTree())tree->LoadTree(0);
1635
1636   // if we find the "ESD" branch on the tree we do have the old structure
1637   if(tree->GetBranch("ESD")) {
1638     fOldMuonStructure = kFALSE;
1639     char ** address  = (char **)(tree->GetBranch("ESD")->GetAddress());
1640     // do we have the friend branch
1641     TBranch * esdFB = tree->GetBranch("ESDfriend.");
1642     char ** addressF = 0;
1643     if(esdFB)addressF = (char **)(esdFB->GetAddress());
1644     if (!address) {
1645       AliInfo("AliESDEvent::ReadFromTree() Reading old Tree");
1646       tree->SetBranchAddress("ESD",       &fESDOld);
1647       if(esdFB){
1648         tree->SetBranchAddress("ESDfriend.",&fESDFriendOld);
1649       }
1650     } else {
1651       AliInfo("AliESDEvent::ReadFromTree() Reading old Tree");
1652       AliInfo("Branch already connected. Using existing branch address.");
1653       fESDOld       = (AliESD*)       (*address);
1654       // addressF can still be 0, since branch needs to switched on
1655       if(addressF)fESDFriendOld = (AliESDfriend*) (*addressF);
1656     }
1657                                        
1658     //  have already connected the old ESD structure... ?
1659     // reuse also the pointer of the AlliESDEvent
1660     // otherwise create new ones
1661     TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("ESDObjectsConnectedToTree"));
1662   
1663     if(connectedList){
1664       // If connected use the connected list of objects
1665       if(fESDObjects!= connectedList){
1666         // protect when called twice 
1667         fESDObjects->Delete();
1668         fESDObjects = connectedList;
1669       }
1670       GetStdContent(); 
1671
1672       
1673       // The pointer to the friend changes when called twice via InitIO
1674       // since AliESDEvent is deleted
1675       TObject* oldf = FindListObject("AliESDfriend");
1676       TObject* newf = 0;
1677       if(addressF){
1678         newf = (TObject*)*addressF;
1679       }
1680       if(newf!=0&&oldf!=newf){
1681         // remove the old reference
1682         // Should we also delete it? Or is this handled in TTree I/O
1683         // since it is created by the first SetBranchAddress
1684         fESDObjects->Remove(oldf);
1685         // add the new one 
1686         fESDObjects->Add(newf);
1687       }
1688       
1689       fConnected = true;
1690       return;
1691     }
1692     // else...    
1693     CreateStdContent(); // create for copy
1694     // if we have the esdfriend add it, so we always can access it via the userinfo
1695     if(fESDFriendOld)AddObject(fESDFriendOld);
1696     // we are not owner of the list objects 
1697     // must not delete it
1698     fESDObjects->SetOwner(kTRUE);
1699     fESDObjects->SetName("ESDObjectsConnectedToTree");
1700     tree->GetUserInfo()->Add(fESDObjects);
1701     fConnected = true;
1702     return;
1703   }
1704   
1705
1706     delete fESDOld;
1707     fESDOld = 0;
1708   // Try to find AliESDEvent
1709   AliESDEvent *esdEvent = 0;
1710   esdEvent = (AliESDEvent*)tree->GetTree()->GetUserInfo()->FindObject("AliESDEvent");
1711   if(esdEvent){   
1712       // Check if already connected to tree
1713     esdEvent->Reset();
1714     TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("ESDObjectsConnectedToTree"));
1715
1716     
1717     if (connectedList && (strcmp(opt, "reconnect"))) {
1718       // If connected use the connected list if objects
1719       fESDObjects->Delete();
1720       fESDObjects = connectedList;
1721       tree->SetBranchAddress("fDetectorStatus",&fDetectorStatus); //PH probably redundant
1722       tree->SetBranchAddress("fDAQDetectorPattern",&fDAQDetectorPattern);
1723       tree->SetBranchAddress("fDAQAttributes",&fDAQAttributes);
1724       if(tree->GetBranch("fNTOFclusters")) tree->SetBranchAddress("fNTOFclusters",(UInt_t *) &fNTOFclusters);
1725       if(tree->GetBranch("fTOFcluster")) tree->SetBranchAddress("fTOFcluster",&fTOFcluster);
1726       GetStdContent(); 
1727       fOldMuonStructure = fESDObjects->TestBit(BIT(23));
1728       fConnected = true;
1729       return;
1730     }
1731
1732     // Connect to tree
1733     // prevent a memory leak when reading back the TList
1734     // if (!(strcmp(opt, "reconnect"))) fESDObjects->Delete();
1735     
1736     if(!fUseOwnList){
1737       // create a new TList from the UserInfo TList... 
1738       // copy constructor does not work...
1739       fESDObjects = (TList*)(esdEvent->GetList()->Clone());
1740       fESDObjects->SetOwner(kTRUE);
1741     }
1742     else if ( fESDObjects->GetEntries()==0){
1743       // at least create the std content if we want to read to our list
1744       CreateStdContent(); 
1745     }
1746
1747     // in principle
1748     // we only need new things in the list if we do no already have it..
1749     // TODO just add new entries
1750     CompleteStdContent();
1751
1752     if(fESDObjects->GetEntries()<kESDListN){
1753       AliWarning(Form("AliESDEvent::ReadFromTree() TList contains less than the standard contents %d < %d \n",
1754                       fESDObjects->GetEntries(),kESDListN));
1755     }
1756     // set the branch addresses
1757     fOldMuonStructure = kFALSE;
1758     TIter next(fESDObjects);
1759     TNamed *el;
1760     while((el=(TNamed*)next())){
1761       TString bname(el->GetName());
1762       if(bname.CompareTo("AliESDfriend")==0)
1763         {
1764           // AliESDfriend does not have a name ...
1765             TBranch *br = tree->GetBranch("ESDfriend.");
1766             if (br) tree->SetBranchAddress("ESDfriend.",fESDObjects->GetObjectRef(el));
1767         }
1768       else{
1769         // check if branch exists under this Name
1770         TBranch *br = tree->GetBranch(bname.Data());
1771         if(br){
1772           tree->SetBranchAddress(bname.Data(),fESDObjects->GetObjectRef(el));
1773         }
1774         else{
1775           br = tree->GetBranch(Form("%s.",bname.Data()));
1776           if(br){
1777             tree->SetBranchAddress(Form("%s.",bname.Data()),fESDObjects->GetObjectRef(el));
1778           }
1779           else{
1780             AliWarning(Form("AliESDEvent::ReadFromTree() No Branch found with Name %s or %s.",bname.Data(),bname.Data()));
1781             if (bname == fgkESDListName[kMuonClusters]) {
1782               fOldMuonStructure = kTRUE;
1783             }
1784           }
1785
1786         }
1787       }
1788     }
1789     tree->SetBranchAddress("fDetectorStatus",&fDetectorStatus);
1790     tree->SetBranchAddress("fDAQDetectorPattern",&fDAQDetectorPattern);
1791     tree->SetBranchAddress("fDAQAttributes",&fDAQAttributes);
1792     if(tree->GetBranch("fNTOFclusters")) tree->SetBranchAddress("fNTOFclusters",(UInt_t *) &fNTOFclusters);
1793     if(tree->GetBranch("fTOFcluster")) tree->SetBranchAddress("fTOFcluster",&fTOFcluster);
1794
1795     GetStdContent();
1796     // when reading back we are not owner of the list 
1797     // must not delete it
1798     fESDObjects->SetOwner(kTRUE);
1799     fESDObjects->SetName("ESDObjectsConnectedToTree");
1800     fESDObjects->SetBit(BIT(23), fOldMuonStructure);
1801     // we are not owner of the list objects 
1802     // must not delete it
1803     tree->GetUserInfo()->Add(fESDObjects);
1804     tree->GetUserInfo()->SetOwner(kFALSE);
1805     fConnected = true;
1806   }// no esdEvent -->
1807   else {
1808     // we can't get the list from the user data, create standard content
1809     // and set it by hand (no ESDfriend at the moment
1810     CreateStdContent();
1811     fOldMuonStructure = kFALSE;
1812     TIter next(fESDObjects);
1813     TNamed *el;
1814     while((el=(TNamed*)next())){
1815       TString bname(el->GetName());    
1816       TBranch *br = tree->GetBranch(bname.Data());
1817       if(br){
1818         tree->SetBranchAddress(bname.Data(),fESDObjects->GetObjectRef(el));
1819       }
1820       else{
1821         br = tree->GetBranch(Form("%s.",bname.Data()));
1822         if(br){
1823           tree->SetBranchAddress(Form("%s.",bname.Data()),fESDObjects->GetObjectRef(el));
1824         }
1825         else if (bname == fgkESDListName[kMuonClusters]) {
1826           fOldMuonStructure = kTRUE;
1827         }
1828       }
1829     }
1830     tree->SetBranchAddress("fDetectorStatus",&fDetectorStatus);
1831     tree->SetBranchAddress("fDAQDetectorPattern",&fDAQDetectorPattern);
1832     tree->SetBranchAddress("fDAQAttributes",&fDAQAttributes);
1833     if(tree->GetBranch("fNTOFclusters")) tree->SetBranchAddress("fNTOFclusters",(UInt_t *) &fNTOFclusters);
1834     if(tree->GetBranch("fTOFcluster")) tree->SetBranchAddress("fTOFcluster",&fTOFcluster);
1835
1836     GetStdContent();
1837     // when reading back we are not owner of the list 
1838     // must not delete it
1839     fESDObjects->SetOwner(kTRUE);
1840   }
1841 }
1842
1843
1844 void AliESDEvent::CopyFromOldESD()
1845 {
1846   // Method which copies over everthing from the old esd structure to the 
1847   // new  
1848   if(fESDOld){
1849     ResetStdContent();
1850      // Run
1851     SetRunNumber(fESDOld->GetRunNumber());
1852     SetPeriodNumber(fESDOld->GetPeriodNumber());
1853     SetMagneticField(fESDOld->GetMagneticField());
1854   
1855     // leave out diamond ...
1856     // SetDiamond(const AliESDVertex *vertex) { fESDRun->SetDiamond(vertex);}
1857
1858     // header
1859     SetTriggerMask(fESDOld->GetTriggerMask());
1860     SetOrbitNumber(fESDOld->GetOrbitNumber());
1861     SetTimeStamp(fESDOld->GetTimeStamp());
1862     SetEventType(fESDOld->GetEventType());
1863     SetEventNumberInFile(fESDOld->GetEventNumberInFile());
1864     SetBunchCrossNumber(fESDOld->GetBunchCrossNumber());
1865     SetTriggerCluster(fESDOld->GetTriggerCluster());
1866
1867     // ZDC
1868
1869     SetZDC(fESDOld->GetZDCN1Energy(),
1870            fESDOld->GetZDCP1Energy(),
1871            fESDOld->GetZDCEMEnergy(),
1872            0,
1873            fESDOld->GetZDCN2Energy(),
1874            fESDOld->GetZDCP2Energy(),
1875            fESDOld->GetZDCParticipants(),
1876            0,
1877            0,
1878            0,
1879            0,
1880            0,
1881            0);
1882
1883     // FMD
1884     
1885     if(fESDOld->GetFMDData())SetFMDData(fESDOld->GetFMDData());
1886
1887     // T0
1888
1889     SetT0zVertex(fESDOld->GetT0zVertex());
1890     SetT0(fESDOld->GetT0());
1891     //  leave amps out
1892
1893     // VZERO
1894     if (fESDOld->GetVZEROData()) SetVZEROData(fESDOld->GetVZEROData());
1895
1896     if(fESDOld->GetVertex())SetPrimaryVertexSPD(fESDOld->GetVertex());
1897
1898     if(fESDOld->GetPrimaryVertex())SetPrimaryVertexTracks(fESDOld->GetPrimaryVertex());
1899
1900     if(fESDOld->GetMultiplicity())SetMultiplicity(fESDOld->GetMultiplicity());
1901
1902     for(int i = 0;i<fESDOld->GetNumberOfTracks();i++){
1903       AddTrack(fESDOld->GetTrack(i));
1904     }
1905
1906     for(int i = 0;i<fESDOld->GetNumberOfMuonTracks();i++){
1907       AddMuonTrack(fESDOld->GetMuonTrack(i));
1908     }
1909
1910     for(int i = 0;i<fESDOld->GetNumberOfPmdTracks();i++){
1911       AddPmdTrack(fESDOld->GetPmdTrack(i));
1912     }
1913
1914     for(int i = 0;i<fESDOld->GetNumberOfTrdTracks();i++){
1915       AddTrdTrack(fESDOld->GetTrdTrack(i));
1916     }
1917
1918     for(int i = 0;i<fESDOld->GetNumberOfV0s();i++){
1919       AddV0(fESDOld->GetV0(i));
1920     }
1921
1922     for(int i = 0;i<fESDOld->GetNumberOfCascades();i++){
1923       AddCascade(fESDOld->GetCascade(i));
1924     }
1925
1926     for(int i = 0;i<fESDOld->GetNumberOfKinks();i++){
1927       AddKink(fESDOld->GetKink(i));
1928     }
1929
1930
1931     for(int i = 0;i<fESDOld->GetNumberOfCaloClusters();i++){
1932       AddCaloCluster(fESDOld->GetCaloCluster(i));
1933     }
1934           
1935   }// if fesdold
1936 }
1937
1938 Bool_t AliESDEvent::IsEventSelected(const char *trigExpr) const
1939 {
1940   // Check if the event satisfies the trigger
1941   // selection expression trigExpr.
1942   // trigExpr can be any logical expression
1943   // of the trigger classes defined in AliESDRun
1944   // In case of wrong syntax return kTRUE.
1945
1946   TString expr(trigExpr);
1947   if (expr.IsNull()) return kTRUE;
1948
1949   ULong64_t mask = GetTriggerMask();
1950   for(Int_t itrig = 0; itrig < AliESDRun::kNTriggerClasses; itrig++) {
1951     if (mask & (1ull << itrig)) {
1952       expr.ReplaceAll(GetESDRun()->GetTriggerClass(itrig),"1");
1953     }
1954     else {
1955       expr.ReplaceAll(GetESDRun()->GetTriggerClass(itrig),"0");
1956     }
1957   }
1958
1959   Int_t error;
1960   if ((gROOT->ProcessLineFast(expr.Data(),&error) == 0) &&
1961       (error == TInterpreter::kNoError)) {
1962     return kFALSE;
1963   }
1964
1965   return kTRUE;
1966
1967 }
1968
1969 TObject*  AliESDEvent::GetHLTTriggerDecision() const
1970 {
1971   // get the HLT trigger decission object
1972
1973   // cast away const'nes because the FindListObject method
1974   // is not const
1975   AliESDEvent* pNonConst=const_cast<AliESDEvent*>(this);
1976   return pNonConst->FindListObject("HLTGlobalTrigger");
1977 }
1978
1979 TString   AliESDEvent::GetHLTTriggerDescription() const
1980 {
1981   // get the HLT trigger decission description
1982   TString description;
1983   TObject* pDecision=GetHLTTriggerDecision();
1984   if (pDecision) {
1985     description=pDecision->GetTitle();
1986   }
1987
1988   return description;
1989 }
1990
1991 Bool_t    AliESDEvent::IsHLTTriggerFired(const char* name) const
1992 {
1993   // get the HLT trigger decission description
1994   TObject* pDecision=GetHLTTriggerDecision();
1995   if (!pDecision) return kFALSE;
1996
1997   Option_t* option=pDecision->GetOption();
1998   if (option==NULL || *option!='1') return kFALSE;
1999
2000   if (name) {
2001     TString description=GetHLTTriggerDescription();
2002     Int_t index=description.Index(name);
2003     if (index<0) return kFALSE;
2004     index+=strlen(name);
2005     if (index>=description.Length()) return kFALSE;
2006     if (description[index]!=0 && description[index]!=' ') return kFALSE;
2007   }
2008   return kTRUE;
2009 }
2010
2011 //______________________________________________________________________________
2012 Bool_t  AliESDEvent::IsPileupFromSPD(Int_t minContributors, 
2013                                      Double_t minZdist, 
2014                                      Double_t nSigmaZdist, 
2015                                      Double_t nSigmaDiamXY, 
2016                                      Double_t nSigmaDiamZ) const{
2017   //
2018   // This function checks if there was a pile up
2019   // reconstructed with SPD
2020   //
2021   Int_t nc1=fSPDVertex->GetNContributors();
2022   if(nc1<1) return kFALSE;
2023   Int_t nPileVert=GetNumberOfPileupVerticesSPD();
2024   if(nPileVert==0) return kFALSE;
2025   
2026   for(Int_t i=0; i<nPileVert;i++){
2027     const AliESDVertex* pv=GetPileupVertexSPD(i);
2028     Int_t nc2=pv->GetNContributors();
2029     if(nc2>=minContributors){
2030       Double_t z1=fSPDVertex->GetZ();
2031       Double_t z2=pv->GetZ();
2032       Double_t distZ=TMath::Abs(z2-z1);
2033       Double_t distZdiam=TMath::Abs(z2-GetDiamondZ());
2034       Double_t cutZdiam=nSigmaDiamZ*TMath::Sqrt(GetSigma2DiamondZ());
2035       if(GetSigma2DiamondZ()<0.0001)cutZdiam=99999.; //protection for missing z diamond information
2036       if(distZ>minZdist && distZdiam<cutZdiam){
2037         Double_t x2=pv->GetX();
2038         Double_t y2=pv->GetY();
2039         Double_t distXdiam=TMath::Abs(x2-GetDiamondX());
2040         Double_t distYdiam=TMath::Abs(y2-GetDiamondY());
2041         Double_t cov1[6],cov2[6];       
2042         fSPDVertex->GetCovarianceMatrix(cov1);
2043         pv->GetCovarianceMatrix(cov2);
2044         Double_t errxDist=TMath::Sqrt(cov2[0]+GetSigma2DiamondX());
2045         Double_t erryDist=TMath::Sqrt(cov2[2]+GetSigma2DiamondY());
2046         Double_t errzDist=TMath::Sqrt(cov1[5]+cov2[5]);
2047         Double_t cutXdiam=nSigmaDiamXY*errxDist;
2048         if(GetSigma2DiamondX()<0.0001)cutXdiam=99999.; //protection for missing diamond information
2049         Double_t cutYdiam=nSigmaDiamXY*erryDist;
2050         if(GetSigma2DiamondY()<0.0001)cutYdiam=99999.; //protection for missing diamond information
2051         if( (distXdiam<cutXdiam) && (distYdiam<cutYdiam) && (distZ>nSigmaZdist*errzDist) ){
2052           return kTRUE;
2053         }
2054       }
2055     }
2056   }
2057   return kFALSE;
2058 }
2059
2060 //______________________________________________________________________________
2061 void AliESDEvent::EstimateMultiplicity(Int_t &tracklets, Int_t &trITSTPC, Int_t &trITSSApure, Double_t eta, Bool_t useDCAFlag,Bool_t useV0Flag) const
2062 {
2063   //
2064   // calculates 3 estimators for the multiplicity in the -eta:eta range
2065   // tracklets   : using SPD tracklets only
2066   // trITSTPC    : using TPC/ITS + complementary ITS SA tracks + tracklets from clusters not used by tracks
2067   // trITSSApure : using ITS standalone tracks + tracklets from clusters not used by tracks
2068   // if useDCAFlag is true: account for the ESDtrack flag marking the tracks with large DCA
2069   // if useV0Flag  is true: account for the ESDtrack flag marking conversion and K0's V0s
2070
2071   AliWarning("This obsolete method will be eliminated soon. Use AliESDtrackCuts::GetReferenceMultiplicity");
2072
2073   tracklets = trITSSApure = trITSTPC = 0;
2074   int ntr = fSPDMult ? fSPDMult->GetNumberOfTracklets() : 0;
2075   //
2076   // count tracklets
2077   for (int itr=ntr;itr--;) { 
2078     if (TMath::Abs(fSPDMult->GetEta(itr))>eta) continue;
2079     tracklets++;
2080     if (fSPDMult->FreeClustersTracklet(itr,0)) trITSTPC++;    // not used in ITS/TPC or ITS_SA track
2081     if (fSPDMult->FreeClustersTracklet(itr,1)) trITSSApure++; // not used in ITS_SA_Pure track
2082   }
2083   //
2084   // count real tracks
2085   ntr = GetNumberOfTracks();
2086   for (int itr=ntr;itr--;) {
2087     AliESDtrack *t = GetTrack(itr);
2088     if (!t) {AliFatal(Form("NULL pointer for ESD track %d",itr));}
2089     if (TMath::Abs(t->Eta())>eta) continue;
2090     if (!t->IsOn(AliESDtrack::kITSin)) continue;
2091     if (useDCAFlag && t->IsOn(AliESDtrack::kMultSec))  continue;
2092     if (useV0Flag  && t->IsOn(AliESDtrack::kMultInV0)) continue;    
2093     if (t->IsOn(AliESDtrack::kITSpureSA)) trITSSApure++;
2094     else                                  trITSTPC++;
2095   }
2096   //
2097 }
2098
2099 Bool_t AliESDEvent::IsPileupFromSPDInMultBins() const {
2100     Int_t nTracklets=GetMultiplicity()->GetNumberOfTracklets();
2101     if(nTracklets<20) return IsPileupFromSPD(3,0.8);
2102     else if(nTracklets<50) return IsPileupFromSPD(4,0.8);
2103     else return IsPileupFromSPD(5,0.8);
2104 }
2105
2106 void  AliESDEvent::SetTOFHeader(const AliTOFHeader *header)
2107 {
2108   //
2109   // Set the TOF event_time
2110   //
2111
2112   if (fTOFHeader) {
2113     *fTOFHeader=*header;
2114     //fTOFHeader->SetName(fgkESDListName[kTOFHeader]);
2115   }
2116   else {
2117     // for analysis of reconstructed events
2118     // when this information is not avaliable
2119     fTOFHeader = new AliTOFHeader(*header);
2120     //AddObject(fTOFHeader);
2121   }
2122
2123 }
2124
2125 AliCentrality* AliESDEvent::GetCentrality()
2126 {
2127     if (!fCentrality) fCentrality = new AliCentrality();
2128     return  fCentrality;
2129 }
2130
2131 AliEventplane* AliESDEvent::GetEventplane()
2132 {
2133     if (!fEventplane) fEventplane = new AliEventplane();
2134     return  fEventplane;
2135 }
2136
2137 Float_t AliESDEvent::GetVZEROEqMultiplicity(Int_t i) const
2138 {
2139   // Get VZERO Multiplicity for channel i
2140   // Themethod uses the equalization factors
2141   // stored in the ESD-run object in order to
2142   // get equal multiplicities within a VZERO rins (1/8 of VZERO)
2143   if (!fESDVZERO || !fESDRun) return -1;
2144
2145   Int_t ring = i/8;
2146   Float_t factorSum = 0;
2147   for(Int_t j = 8*ring; j < (8*ring+8); ++j) {
2148     factorSum += fESDRun->GetVZEROEqFactors(j);
2149   }
2150   Float_t factor = fESDRun->GetVZEROEqFactors(i)*8./factorSum;
2151
2152   return (fESDVZERO->GetMultiplicity(i)/factor);
2153 }
2154
2155 void AliESDEvent::SetTOFcluster(Int_t ntofclusters,AliESDTOFcluster *cluster,Int_t *mapping){
2156   fNTOFclusters = 0;
2157
2158   fTOFcluster->Clear();
2159   fTOFcluster->Expand(1);      
2160       
2161   for(Int_t i=0;i < ntofclusters;i++){
2162
2163     if(cluster[i].GetNMatchableTracks() || !mapping){
2164       fTOFcluster->Expand(fNTOFclusters+1);      
2165       fTOFcluster->AddAt(&cluster[i],fNTOFclusters);
2166       if(mapping)
2167         mapping[i] = fNTOFclusters;
2168       fNTOFclusters++;
2169     }
2170   }
2171   if(mapping)
2172     printf("TOF cluster before of matching = %i , after = %i\n",ntofclusters,fNTOFclusters);
2173    
2174
2175 }
2176 void AliESDEvent::SetTOFcluster(Int_t ntofclusters,AliESDTOFcluster *cluster[],Int_t *mapping){
2177   fNTOFclusters = 0;
2178
2179   fTOFcluster->Clear();
2180   fTOFcluster->Expand(1);      
2181       
2182   for(Int_t i=0;i < ntofclusters;i++){
2183
2184     if(cluster[i]->GetNMatchableTracks() || !mapping){
2185       fTOFcluster->Expand(fNTOFclusters+1);      
2186       fTOFcluster->AddAt(cluster[i],fNTOFclusters);
2187       if(mapping)
2188         mapping[i] = fNTOFclusters;
2189       fNTOFclusters++;
2190     }
2191   }
2192   if(mapping)
2193     printf("TOF cluster before of matching = %i , after = %i\n",ntofclusters,fNTOFclusters);
2194    
2195
2196 }