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