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