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