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