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