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