]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/ESD/AliESDEvent.cxx
Modifications for 100 classes implemented in STEER
[u/mrichter/AliRoot.git] / STEER / ESD / 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: AliESDEvent.cxx 64008 2013-08-28 13:09:59Z hristov $ */
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 "AliESDMuonCluster.h"
48 #include "AliESDMuonPad.h"
49 #include "AliESDMuonGlobalTrack.h"       // AU
50 #include "AliESDPmdTrack.h"
51 #include "AliESDTrdTrack.h"
52 #include "AliESDVertex.h"
53 #include "AliESDcascade.h"
54 #include "AliESDPmdTrack.h"
55 #include "AliESDTrdTrigger.h"
56 #include "AliESDTrdTrack.h"
57 #include "AliESDTrdTracklet.h"
58 #include "AliESDVertex.h"
59 #include "AliVertexerTracks.h"
60 #include "AliESDcascade.h"
61 #include "AliESDkink.h"
62 #include "AliESDtrack.h"
63 #include "AliESDHLTtrack.h"
64 #include "AliESDCaloCluster.h"
65 #include "AliESDCaloCells.h"
66 #include "AliESDv0.h"
67 #include "AliESDFMD.h"
68 #include "AliESDVZERO.h"
69 #include "AliMultiplicity.h"
70 #include "AliRawDataErrorLog.h"
71 #include "AliLog.h"
72 #include "AliESDACORDE.h"
73 #include "AliESDAD.h"
74 #include "AliESDHLTDecision.h"
75 #include "AliCentrality.h"
76 #include "AliESDCosmicTrack.h"
77 #include "AliTriggerConfiguration.h"
78 #include "AliTriggerClass.h"
79 #include "AliTriggerCluster.h"
80 #include "AliEventplane.h"
81
82
83 ClassImp(AliESDEvent)
84
85
86
87 // here we define the names, some classes are no TNamed, therefore the classnames 
88 // are the Names
89   const char* AliESDEvent::fgkESDListName[kESDListN] = {"AliESDRun",
90                                                         "AliESDHeader",
91                                                         "AliESDZDC",
92                                                         "AliESDFMD",
93                                                         "AliESDVZERO",
94                                                         "AliESDTZERO",
95                                                         "TPCVertex",
96                                                         "SPDVertex",
97                                                         "PrimaryVertex",
98                                                         "AliMultiplicity",
99                                                         "PHOSTrigger",
100                                                         "EMCALTrigger",
101                                                         "SPDPileupVertices",
102                                                         "TrkPileupVertices",
103                                                         "Tracks",
104                                                         "MuonTracks",
105                                                         "MuonClusters",
106                                                         "MuonPads",
107                                                         "MuonGlobalTracks",      // AU
108                                                         "PmdTracks",
109                                                         "AliESDTrdTrigger",
110                                                         "TrdTracks",
111                                                         "TrdTracklets",
112                                                         "V0s",
113                                                         "Cascades",
114                                                         "Kinks",
115                                                         "CaloClusters",
116                                                         "EMCALCells",
117                                                         "PHOSCells",
118                                                         "AliRawDataErrorLogs",
119                                                         "AliESDACORDE",
120                                                         "AliESDAD",
121                                                         "AliTOFHeader",
122                                                         "CosmicTracks",
123                                                         "AliESDTOFCluster",
124                                                         "AliESDTOFHit",
125                                                         "AliESDTOFMatch"};
126
127
128 //______________________________________________________________________________
129 AliESDEvent::AliESDEvent():
130   AliVEvent(),
131   fESDObjects(new TList()),
132   fESDRun(0),
133   fHeader(0),
134   fESDZDC(0),
135   fESDFMD(0),
136   fESDVZERO(0),
137   fESDTZERO(0),
138   fTPCVertex(0),
139   fSPDVertex(0),
140   fPrimaryVertex(0),
141   fSPDMult(0),
142   fPHOSTrigger(0),
143   fEMCALTrigger(0),
144   fESDACORDE(0),
145   fESDAD(0),
146   fTrdTrigger(0),
147   fSPDPileupVertices(0),
148   fTrkPileupVertices(0),
149   fTracks(0),
150   fMuonTracks(0),
151   fMuonClusters(0),
152   fMuonPads(0),
153   fMuonGlobalTracks(0),    // AU
154   fPmdTracks(0),
155   fTrdTracks(0),
156   fTrdTracklets(0),
157   fV0s(0),  
158   fCascades(0),
159   fKinks(0),
160   fCaloClusters(0),
161   fEMCALCells(0), fPHOSCells(0),
162   fCosmicTracks(0),
163   fESDTOFClusters(0),
164   fESDTOFHits(0),
165   fESDTOFMatches(0),
166   fErrorLogs(0),
167   fOldMuonStructure(kFALSE),
168   fESDOld(0),
169   fESDFriendOld(0),
170   fConnected(kFALSE),
171   fUseOwnList(kFALSE),
172   fTracksConnected(kFALSE),
173   fTOFHeader(0),
174   fCentrality(0),
175   fEventplane(0),
176   fDetectorStatus(0xFFFFFFFF),
177   fDAQDetectorPattern(0xFFFF),
178   fDAQAttributes(0xFFFF)
179 {
180 }
181 //______________________________________________________________________________
182 AliESDEvent::AliESDEvent(const AliESDEvent& esd):
183   AliVEvent(esd),
184   fESDObjects(new TList()),
185   fESDRun(new AliESDRun(*esd.fESDRun)),
186   fHeader(new AliESDHeader(*esd.fHeader)),
187   fESDZDC(new AliESDZDC(*esd.fESDZDC)),
188   fESDFMD(new AliESDFMD(*esd.fESDFMD)),
189   fESDVZERO(new AliESDVZERO(*esd.fESDVZERO)),
190   fESDTZERO(new AliESDTZERO(*esd.fESDTZERO)),
191   fTPCVertex(new AliESDVertex(*esd.fTPCVertex)),
192   fSPDVertex(new AliESDVertex(*esd.fSPDVertex)),
193   fPrimaryVertex(new AliESDVertex(*esd.fPrimaryVertex)),
194   fSPDMult(new AliMultiplicity(*esd.fSPDMult)),
195   fPHOSTrigger(new AliESDCaloTrigger(*esd.fPHOSTrigger)),
196   fEMCALTrigger(new AliESDCaloTrigger(*esd.fEMCALTrigger)),
197   fESDACORDE(new AliESDACORDE(*esd.fESDACORDE)),
198   fESDAD(new AliESDAD(*esd.fESDAD)),
199   fTrdTrigger(new AliESDTrdTrigger(*esd.fTrdTrigger)),
200   fSPDPileupVertices(new TClonesArray(*esd.fSPDPileupVertices)),
201   fTrkPileupVertices(new TClonesArray(*esd.fTrkPileupVertices)),
202   fTracks(new TClonesArray(*esd.fTracks)),
203   fMuonTracks(new TClonesArray(*esd.fMuonTracks)),
204   fMuonClusters(new TClonesArray(*esd.fMuonClusters)),
205   fMuonPads(new TClonesArray(*esd.fMuonPads)),
206   fMuonGlobalTracks(new TClonesArray(*esd.fMuonGlobalTracks)),     // AU
207   fPmdTracks(new TClonesArray(*esd.fPmdTracks)),
208   fTrdTracks(new TClonesArray(*esd.fTrdTracks)),
209   fTrdTracklets(new TClonesArray(*esd.fTrdTracklets)),
210   fV0s(new TClonesArray(*esd.fV0s)),  
211   fCascades(new TClonesArray(*esd.fCascades)),
212   fKinks(new TClonesArray(*esd.fKinks)),
213   fCaloClusters(new TClonesArray(*esd.fCaloClusters)),
214   fEMCALCells(new AliESDCaloCells(*esd.fEMCALCells)),
215   fPHOSCells(new AliESDCaloCells(*esd.fPHOSCells)),
216   fCosmicTracks(new TClonesArray(*esd.fCosmicTracks)),
217   fESDTOFClusters(esd.fESDTOFClusters ? new TClonesArray(*esd.fESDTOFClusters) : 0),
218   fESDTOFHits(esd.fESDTOFHits ? new TClonesArray(*esd.fESDTOFHits) : 0),
219   fESDTOFMatches(esd.fESDTOFMatches ? new TClonesArray(*esd.fESDTOFMatches) : 0),
220   fErrorLogs(new TClonesArray(*esd.fErrorLogs)),
221   fOldMuonStructure(esd.fOldMuonStructure),
222   fESDOld(esd.fESDOld ? new AliESD(*esd.fESDOld) : 0),
223   fESDFriendOld(esd.fESDFriendOld ? new AliESDfriend(*esd.fESDFriendOld) : 0),
224   fConnected(esd.fConnected),
225   fUseOwnList(esd.fUseOwnList),
226   fTracksConnected(kFALSE),
227   fTOFHeader(new AliTOFHeader(*esd.fTOFHeader)),
228   fCentrality(new AliCentrality(*esd.fCentrality)),
229   fEventplane(new AliEventplane(*esd.fEventplane)),
230   fDetectorStatus(esd.fDetectorStatus),
231   fDAQDetectorPattern(esd.fDAQDetectorPattern),
232   fDAQAttributes(esd.fDAQAttributes)
233 {
234   printf("copying ESD event...\n");   // AU
235   // CKB init in the constructor list and only add here ...
236   AddObject(fESDRun);
237   AddObject(fHeader);
238   AddObject(fESDZDC);
239   AddObject(fESDFMD);
240   AddObject(fESDVZERO);
241   AddObject(fESDTZERO);
242   AddObject(fTPCVertex);
243   AddObject(fSPDVertex);
244   AddObject(fPrimaryVertex);
245   AddObject(fSPDMult);
246   AddObject(fPHOSTrigger);
247   AddObject(fEMCALTrigger);
248   AddObject(fTrdTrigger);
249   AddObject(fSPDPileupVertices);
250   AddObject(fTrkPileupVertices);
251   AddObject(fTracks);
252   AddObject(fMuonTracks);
253   AddObject(fMuonGlobalTracks);    // AU
254   AddObject(fPmdTracks);
255   AddObject(fTrdTracks);
256   AddObject(fTrdTracklets);
257   AddObject(fV0s);
258   AddObject(fCascades);
259   AddObject(fKinks);
260   AddObject(fCaloClusters);
261   AddObject(fEMCALCells);
262   AddObject(fPHOSCells);
263   AddObject(fCosmicTracks);
264   AddObject(fESDTOFClusters);
265   AddObject(fESDTOFHits);
266   AddObject(fESDTOFMatches);
267   AddObject(fErrorLogs);
268   AddObject(fESDACORDE);
269   AddObject(fESDAD);
270   AddObject(fTOFHeader);
271   AddObject(fMuonClusters);
272   AddObject(fMuonPads);
273   GetStdContent();
274   ConnectTracks();
275 }
276
277 //______________________________________________________________________________
278 AliESDEvent & AliESDEvent::operator=(const AliESDEvent& source) {
279
280   // Assignment operator
281   printf("operator = ESD\n");
282   if(&source == this) return *this;
283   AliVEvent::operator=(source);
284
285   // This assumes that the list is already created
286   // and that the virtual void Copy(Tobject&) function
287   // is correctly implemented in the derived class
288   // otherwise only TObject::Copy() will be used
289
290
291
292   if((fESDObjects->GetSize()==0)&&(source.fESDObjects->GetSize()>=kESDListN)){
293     // We cover the case that we do not yet have the 
294     // standard content but the source has it
295     CreateStdContent();
296   }
297
298   TIter next(source.GetList());
299   TObject *its = 0;
300   TString name;
301   while ((its = next())) {
302     name.Form("%s", its->GetName());
303     TObject *mine = fESDObjects->FindObject(name.Data());
304     if(!mine){
305       TClass* pClass=TClass::GetClass(its->ClassName());
306       if (!pClass) {
307         AliWarning(Form("Can not find class description for entry %s (%s)\n",
308                         its->ClassName(), name.Data()));
309         continue;
310       }
311
312       mine=(TObject*)pClass->New();
313       if(!mine){
314       // not in this: can be added to list
315         AliWarning(Form("%s:%d Could not find %s for copying \n",
316                         (char*)__FILE__,__LINE__,name.Data()));
317         continue;
318       }  
319       if(mine->InheritsFrom("TNamed")){
320         ((TNamed*)mine)->SetName(name);
321       }
322       else if(mine->InheritsFrom("TCollection")){
323         if(mine->InheritsFrom("TClonesArray")) {
324           TClonesArray* tcits = dynamic_cast<TClonesArray*>(its);
325           if (tcits)
326             dynamic_cast<TClonesArray*>(mine)->SetClass(tcits->GetClass());
327         }
328         dynamic_cast<TCollection*>(mine)->SetName(name);
329       }
330       AliDebug(1, Form("adding object %s of type %s", mine->GetName(), mine->ClassName()));
331       AddObject(mine);
332     }  
333    
334     if(!its->InheritsFrom("TCollection")){
335       // simple objects
336       its->Copy(*mine);
337     }
338     else if(its->InheritsFrom("TClonesArray")){
339       // Create or expand the tclonesarray pointers
340       // so we can directly copy to the object
341       TClonesArray *itstca = (TClonesArray*)its;
342       TClonesArray *minetca = (TClonesArray*)mine;
343
344       // this leaves the capacity of the TClonesArray the same
345       // except for a factor of 2 increase when size > capacity
346       // does not release any memory occupied by the tca
347       minetca->ExpandCreate(itstca->GetEntriesFast());
348       for(int i = 0;i < itstca->GetEntriesFast();++i){
349         // copy 
350         TObject *minetcaobj = minetca->At(i);
351         TObject *itstcaobj = itstca->At(i);
352         // no need to delete first
353         // pointers within the class should be handled by Copy()...
354         // Can there be Empty slots?
355         itstcaobj->Copy(*minetcaobj);
356       }
357     }
358     else{
359       AliWarning(Form("%s:%d cannot copy TCollection \n",
360                       (char*)__FILE__,__LINE__));
361     }
362   }
363
364   fOldMuonStructure = source.fOldMuonStructure;
365   
366   fCentrality = source.fCentrality;
367   fEventplane = source.fEventplane;
368
369   fConnected  = source.fConnected;
370   fUseOwnList = source.fUseOwnList;
371
372   fDetectorStatus = source.fDetectorStatus;
373   fDAQDetectorPattern = source.fDAQDetectorPattern;
374   fDAQAttributes = source.fDAQAttributes;
375
376   fTracksConnected = kFALSE;
377   ConnectTracks();
378   return *this;
379 }
380
381
382 //______________________________________________________________________________
383 AliESDEvent::~AliESDEvent()
384 {
385   //
386   // Standard destructor
387   //
388
389   // everthing on the list gets deleted automatically
390
391   
392   if(fESDObjects&&!fConnected)
393     {
394       delete fESDObjects;
395       fESDObjects = 0;
396     }
397   if (fCentrality) delete fCentrality;
398   if (fEventplane) delete fEventplane;
399   
400
401 }
402
403 void AliESDEvent::Copy(TObject &obj) const {
404
405   // interface to TOBject::Copy
406   // Copies the content of this into obj!
407   // bascially obj = *this
408
409   if(this==&obj)return;
410   AliESDEvent *robj = dynamic_cast<AliESDEvent*>(&obj);
411   if(!robj)return; // not an AliESEvent
412   *robj = *this;
413   return;
414 }
415
416 //______________________________________________________________________________
417 void AliESDEvent::Reset()
418 {
419
420   // Handle the cases
421   // Std content + Non std content
422
423   // Reset the standard contents
424   ResetStdContent(); 
425   fDetectorStatus = 0xFFFFFFFF;
426   fDAQDetectorPattern = 0xFFFF;
427   fDAQAttributes = 0xFFFF;
428   //  reset for the old data without AliESDEvent...
429   if(fESDOld)fESDOld->Reset();
430   if(fESDFriendOld){
431     fESDFriendOld->~AliESDfriend();
432     new (fESDFriendOld) AliESDfriend();
433   }
434   // 
435
436   if(fESDObjects->GetSize()>kESDListN){
437     // we have non std content
438     // this also covers esdfriends
439     for(int i = kESDListN;i < fESDObjects->GetSize();++i){
440       TObject *pObject = fESDObjects->At(i);
441       // TClonesArrays
442       if(pObject->InheritsFrom(TClonesArray::Class())){
443         ((TClonesArray*)pObject)->Delete();
444       }
445       else if(!pObject->InheritsFrom(TCollection::Class())){
446         TClass *pClass = TClass::GetClass(pObject->ClassName());
447         if (pClass && pClass->GetListOfMethods()->FindObject("Clear")) {
448           AliDebug(1, Form("Clear for object %s class %s", pObject->GetName(), pObject->ClassName()));
449           pObject->Clear();
450         }
451         else {
452           AliDebug(1, Form("ResetWithPlacementNew for object %s class %s", pObject->GetName(), pObject->ClassName()));
453           ResetWithPlacementNew(pObject);
454         }
455       }
456       else{
457         AliWarning(Form("No reset for %s \n",
458                         pObject->ClassName()));
459       }
460     }
461   }
462
463 }
464
465 //______________________________________________________________________________
466 Bool_t AliESDEvent::ResetWithPlacementNew(TObject *pObject){
467   //
468   // funtion to reset using the already allocated space
469   //
470   Long_t dtoronly = TObject::GetDtorOnly();
471   TClass *pClass = TClass::GetClass(pObject->ClassName()); 
472   TObject::SetDtorOnly(pObject);
473   delete pObject;
474   // Recreate with placement new
475   pClass->New(pObject);
476   // Restore the state.
477   TObject::SetDtorOnly((void*)dtoronly);
478   return kTRUE;
479 }
480
481 //______________________________________________________________________________
482 void AliESDEvent::ResetStdContent()
483 {
484   // Reset the standard contents
485   if(fESDRun) fESDRun->Reset();
486   if(fHeader) fHeader->Reset();
487   if(fCentrality) fCentrality->Reset();
488   if(fEventplane) fEventplane->Reset();
489   if(fESDZDC) fESDZDC->Reset();
490   if(fESDFMD) {
491     fESDFMD->Clear();
492   }
493   if(fESDVZERO){
494     // reset by callin d'to /c'tor keep the pointer
495     fESDVZERO->~AliESDVZERO();
496     new (fESDVZERO) AliESDVZERO();
497   }  
498   if(fESDACORDE){
499     fESDACORDE->~AliESDACORDE();
500     new (fESDACORDE) AliESDACORDE();    
501   } 
502
503   if(fESDAD){
504     fESDAD->~AliESDAD();
505     new (fESDAD) AliESDAD();    
506   } 
507
508
509   if(fESDTZERO) fESDTZERO->Reset(); 
510   // CKB no clear/reset implemented
511   if(fTPCVertex){
512     fTPCVertex->~AliESDVertex();
513     new (fTPCVertex) AliESDVertex();
514     fTPCVertex->SetName(fgkESDListName[kTPCVertex]);
515   }
516   if(fSPDVertex){
517     fSPDVertex->~AliESDVertex();
518     new (fSPDVertex) AliESDVertex();
519     fSPDVertex->SetName(fgkESDListName[kSPDVertex]);
520   }
521   if(fPrimaryVertex){
522     fPrimaryVertex->~AliESDVertex();
523     new (fPrimaryVertex) AliESDVertex();
524     fPrimaryVertex->SetName(fgkESDListName[kPrimaryVertex]);
525   }
526   if(fSPDMult){
527     fSPDMult->~AliMultiplicity();
528     new (fSPDMult) AliMultiplicity();
529   }
530   if(fTOFHeader){
531     fTOFHeader->~AliTOFHeader();
532     new (fTOFHeader) AliTOFHeader();
533     //fTOFHeader->SetName(fgkESDListName[kTOFHeader]);
534   }
535   if (fTrdTrigger) {
536     fTrdTrigger->~AliESDTrdTrigger();
537     new (fTrdTrigger) AliESDTrdTrigger();
538   }
539         
540   if(fPHOSTrigger)fPHOSTrigger->DeAllocate(); 
541   if(fEMCALTrigger)fEMCALTrigger->DeAllocate(); 
542   if(fSPDPileupVertices)fSPDPileupVertices->Delete();
543   if(fTrkPileupVertices)fTrkPileupVertices->Delete();
544   fTracksConnected = kFALSE;
545   if(fTracks)fTracks->Delete();
546   if(fMuonTracks)fMuonTracks->Clear("C");
547   if(fMuonClusters)fMuonClusters->Clear("C");
548   if(fMuonPads)fMuonPads->Clear("C");
549   if(fMuonGlobalTracks)fMuonGlobalTracks->Clear("C");     // AU
550   if(fPmdTracks)fPmdTracks->Delete();
551   if(fTrdTracks)fTrdTracks->Delete();
552   if(fTrdTracklets)fTrdTracklets->Delete();
553   if(fV0s)fV0s->Delete();
554   if(fCascades)fCascades->Delete();
555   if(fKinks)fKinks->Delete();
556   if(fCaloClusters)fCaloClusters->Delete();
557   if(fPHOSCells)fPHOSCells->DeleteContainer();
558   if(fEMCALCells)fEMCALCells->DeleteContainer();
559   if(fCosmicTracks)fCosmicTracks->Delete();
560   if(fESDTOFClusters)fESDTOFClusters->Clear();
561   if(fESDTOFHits)fESDTOFHits->Clear();
562   if(fESDTOFMatches)fESDTOFMatches->Clear();
563   if(fErrorLogs) fErrorLogs->Delete();
564
565   // don't reset fconnected fConnected and the list
566
567 }
568
569
570 //______________________________________________________________________________
571 Int_t AliESDEvent::AddV0(const AliESDv0 *v) {
572   //
573   // Add V0
574   //
575   TClonesArray &fv = *fV0s;
576   Int_t idx=fV0s->GetEntriesFast();
577   new(fv[idx]) AliESDv0(*v);
578   return idx;
579 }  
580
581 //______________________________________________________________________________
582 Bool_t AliESDEvent::IsDetectorInTriggerCluster(TString detector, AliTriggerConfiguration* trigConf) const {
583   // Check if a given detector was read-out in the analyzed event
584   const TObjArray& classesArray=trigConf->GetClasses();
585   ULong64_t trigMask=GetTriggerMask();
586   ULong64_t trigMaskNext50=GetTriggerMaskNext50();
587   Int_t nclasses = classesArray.GetEntriesFast();
588   for(Int_t iclass=0; iclass < nclasses; iclass++ ) {
589     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
590     ULong64_t classMask=trclass->GetMask();
591     ULong64_t classMaskNext50=trclass->GetMaskNext50();
592     if(trigMask & classMask){
593       TString detList=trclass->GetCluster()->GetDetectorsInCluster();
594       if(detList.Contains(detector.Data())){
595         return kTRUE;
596       }
597     }
598     if(trigMaskNext50 & classMaskNext50){
599       TString detList=trclass->GetCluster()->GetDetectorsInCluster();
600       if(detList.Contains(detector.Data())){
601         return kTRUE;
602       }
603     }
604   }
605   return kFALSE; 
606 }
607 //______________________________________________________________________________
608 void AliESDEvent::Print(Option_t *) const 
609 {
610   //
611   // Print header information of the event
612   //
613   printf("ESD run information\n");
614   printf("Event # in file %d Bunch crossing # %d Orbit # %d Period # %d Run # %d Trigger %lld %lld Magnetic field %f \n",
615          GetEventNumberInFile(),
616          GetBunchCrossNumber(),
617          GetOrbitNumber(),
618          GetPeriodNumber(),
619          GetRunNumber(),
620          GetTriggerMask(),
621          GetTriggerMaskNext50(),
622          GetMagneticField() );
623   if (fPrimaryVertex)
624     printf("Vertex: (%.4f +- %.4f, %.4f +- %.4f, %.4f +- %.4f) cm\n",
625            fPrimaryVertex->GetX(), fPrimaryVertex->GetXRes(),
626            fPrimaryVertex->GetY(), fPrimaryVertex->GetYRes(),
627            fPrimaryVertex->GetZ(), fPrimaryVertex->GetZRes());
628   printf("Mean vertex in RUN: X=%.4f Y=%.4f Z=%.4f cm\n",
629          GetDiamondX(),GetDiamondY(),GetDiamondZ());
630   if(fSPDMult)
631     printf("SPD Multiplicity. Number of tracklets %d \n",
632            fSPDMult->GetNumberOfTracklets());
633   printf("Number of pileup primary vertices reconstructed with SPD %d\n", 
634          GetNumberOfPileupVerticesSPD());
635   printf("Number of pileup primary vertices reconstructed using the tracks %d\n",
636          GetNumberOfPileupVerticesTracks());
637   printf("Number of tracks: \n");
638   printf("                 charged   %d\n", GetNumberOfTracks());
639   printf("                 muon      %d\n", GetNumberOfMuonTracks());
640   printf("                 glob muon %d\n", GetNumberOfMuonGlobalTracks());    // AU
641   printf("                 pmd       %d\n", GetNumberOfPmdTracks());
642   printf("                 trd       %d\n", GetNumberOfTrdTracks());
643   printf("                 trd trkl  %d\n", GetNumberOfTrdTracklets());
644   printf("                 v0        %d\n", GetNumberOfV0s());
645   printf("                 cascades  %d\n", GetNumberOfCascades());
646   printf("                 kinks     %d\n", GetNumberOfKinks());
647   if(fPHOSCells)printf("                 PHOSCells %d\n", fPHOSCells->GetNumberOfCells());
648   else printf("                 PHOSCells not in the Event\n");
649   if(fEMCALCells)printf("                 EMCALCells %d\n", fEMCALCells->GetNumberOfCells());
650   else printf("                 EMCALCells not in the Event\n");
651   printf("                 CaloClusters %d\n", GetNumberOfCaloClusters());
652   printf("                 FMD       %s\n", (fESDFMD ? "yes" : "no"));
653   printf("                 VZERO     %s\n", (fESDVZERO ? "yes" : "no"));
654   printf("                 muClusters %d\n", fMuonClusters ? fMuonClusters->GetEntriesFast() : 0);
655   printf("                 muPad     %d\n", fMuonPads ? fMuonPads->GetEntriesFast() : 0);
656   if (fCosmicTracks) printf("                 Cosmics   %d\n",  GetNumberOfCosmicTracks());
657         
658   TObject* pHLTDecision=GetHLTTriggerDecision();
659   printf("HLT trigger decision: %s\n", pHLTDecision?pHLTDecision->GetOption():"not available");
660   if (pHLTDecision) pHLTDecision->Print("compact");
661
662   return;
663 }
664
665 //______________________________________________________________________________
666 void AliESDEvent::SetESDfriend(const AliESDfriend *ev) const 
667 {
668 //
669 // Attaches the complementary info to the ESD
670 //
671   if (!ev) return;
672
673   // to be sure that we set the tracks also
674   // in case of old esds 
675   // if(fESDOld)CopyFromOldESD();
676
677   Int_t ntrk=ev->GetNumberOfTracks();
678  
679   for (Int_t i=0; i<ntrk; i++) {
680     const AliESDfriendTrack *f=ev->GetTrack(i);
681     if (!f) {AliFatal(Form("NULL pointer for ESD track %d",i));}
682     GetTrack(i)->SetFriendTrack(f);
683   }
684 }
685
686 //______________________________________________________________________________
687 Bool_t  AliESDEvent::RemoveKink(Int_t rm) const 
688 {
689 // ---------------------------------------------------------
690 // Remove a kink candidate and references to it from ESD,
691 // if this candidate does not come from a reconstructed decay
692 // Not yet implemented...
693 // ---------------------------------------------------------
694   Int_t last=GetNumberOfKinks()-1;
695   if ((rm<0)||(rm>last)) return kFALSE;
696
697   return kTRUE;
698 }
699
700 //______________________________________________________________________________
701 Bool_t  AliESDEvent::RemoveV0(Int_t rm) const 
702 {
703 // ---------------------------------------------------------
704 // Remove a V0 candidate and references to it from ESD,
705 // if this candidate does not come from a reconstructed decay
706 // ---------------------------------------------------------
707   Int_t last=GetNumberOfV0s()-1;
708   if ((rm<0)||(rm>last)) return kFALSE;
709
710   AliESDv0 *v0=GetV0(rm);
711   Int_t idxP=v0->GetPindex(), idxN=v0->GetNindex();
712
713   v0=GetV0(last);
714   Int_t lastIdxP=v0->GetPindex(), lastIdxN=v0->GetNindex();
715
716   Int_t used=0;
717
718   // Check if this V0 comes from a reconstructed decay
719   Int_t ncs=GetNumberOfCascades();
720   for (Int_t n=0; n<ncs; n++) {
721     AliESDcascade *cs=GetCascade(n);
722
723     Int_t csIdxP=cs->GetPindex();
724     Int_t csIdxN=cs->GetNindex();
725
726     if (idxP==csIdxP)
727        if (idxN==csIdxN) return kFALSE;
728
729     if (csIdxP==lastIdxP)
730        if (csIdxN==lastIdxN) used++;
731   }
732
733   //Replace the removed V0 with the last V0 
734   TClonesArray &a=*fV0s;
735   delete a.RemoveAt(rm);
736
737   if (rm==last) return kTRUE;
738
739   //v0 is pointing to the last V0 candidate... 
740   new (a[rm]) AliESDv0(*v0);
741   delete a.RemoveAt(last);
742
743   if (!used) return kTRUE;
744   
745
746   // Remap the indices of the daughters of reconstructed decays
747   for (Int_t n=0; n<ncs; n++) {
748     AliESDcascade *cs=GetCascade(n);
749
750
751     Int_t csIdxP=cs->GetPindex();
752     Int_t csIdxN=cs->GetNindex();
753
754     if (csIdxP==lastIdxP)
755       if (csIdxN==lastIdxN) {
756          cs->AliESDv0::SetIndex(1,idxP);
757          cs->AliESDv0::SetIndex(0,idxN);
758          used--;
759          if (!used) return kTRUE;
760       }
761   }
762
763   return kTRUE;
764 }
765
766 //______________________________________________________________________________
767 Bool_t  AliESDEvent::RemoveTrack(Int_t rm) const 
768 {
769 // ---------------------------------------------------------
770 // Remove a track and references to it from ESD,
771 // if this track does not come from a reconstructed decay
772 // ---------------------------------------------------------
773   Int_t last=GetNumberOfTracks()-1;
774   if ((rm<0)||(rm>last)) return kFALSE;
775
776   Int_t used=0;
777
778   // Check if this track comes from the reconstructed primary vertices
779   if (fTPCVertex && fTPCVertex->GetStatus()) {
780      UShort_t *primIdx=fTPCVertex->GetIndices();
781      Int_t n=fTPCVertex->GetNIndices();
782      while (n--) {
783        Int_t idx=Int_t(primIdx[n]);
784        if (rm==idx) return kFALSE;
785        if (idx==last) used++; 
786      }
787   }
788   if (fPrimaryVertex && fPrimaryVertex->GetStatus()) {
789      UShort_t *primIdx=fPrimaryVertex->GetIndices();
790      Int_t n=fPrimaryVertex->GetNIndices();
791      while (n--) {
792        Int_t idx=Int_t(primIdx[n]);
793        if (rm==idx) return kFALSE;
794        if (idx==last) used++; 
795      }
796   }
797   
798   // Check if this track comes from a reconstructed decay
799   Int_t nv0=GetNumberOfV0s();
800   for (Int_t n=0; n<nv0; n++) {
801     AliESDv0 *v0=GetV0(n);
802
803     Int_t idx=v0->GetNindex();
804     if (rm==idx) return kFALSE;
805     if (idx==last) used++;
806
807     idx=v0->GetPindex();
808     if (rm==idx) return kFALSE;
809     if (idx==last) used++;
810   }
811
812   Int_t ncs=GetNumberOfCascades();
813   for (Int_t n=0; n<ncs; n++) {
814     AliESDcascade *cs=GetCascade(n);
815
816     Int_t idx=cs->GetIndex();
817     if (rm==idx) return kFALSE;
818     if (idx==last) used++;
819
820     AliESDv0 *v0=cs;
821     idx=v0->GetNindex();
822     if (rm==idx) return kFALSE;
823     if (idx==last) used++;
824
825     idx=v0->GetPindex();
826     if (rm==idx) return kFALSE;
827     if (idx==last) used++;
828   }
829
830   Int_t nkn=GetNumberOfKinks();
831   for (Int_t n=0; n<nkn; n++) {
832     AliESDkink *kn=GetKink(n);
833
834     Int_t idx=kn->GetIndex(0);
835     if (rm==idx) return kFALSE;
836     if (idx==last) used++;
837
838     idx=kn->GetIndex(1);
839     if (rm==idx) return kFALSE;
840     if (idx==last) used++;
841   }
842
843   // Check if this track is associated with a CaloCluster
844   Int_t ncl=GetNumberOfCaloClusters();
845   for (Int_t n=0; n<ncl; n++) {
846     AliESDCaloCluster *cluster=GetCaloCluster(n);
847     TArrayI *arr=cluster->GetTracksMatched();
848     Int_t s=arr->GetSize();
849     while (s--) {
850       Int_t idx=arr->At(s);
851       if (rm==idx) return kFALSE;
852       if (idx==last) used++;     
853     }
854   }
855
856   // from here on we remove the track
857   //
858   //Replace the removed track with the last track 
859   TClonesArray &a=*fTracks;
860   AliESDtrack* trm = GetTrack(rm);
861   trm->SuppressTOFMatches(); // remove reference to this track from stored TOF clusters
862   delete a.RemoveAt(rm);
863   //
864   if (rm==last) return kTRUE;
865
866   AliESDtrack *t=GetTrack(last);
867   if (!t) {AliFatal(Form("NULL pointer for ESD track %d",last));}
868   t->SetID(rm);
869   new (a[rm]) AliESDtrack(*t);
870   delete a.RemoveAt(last);
871
872   if (!used) return kTRUE;
873   
874
875   // Remap the indices of the tracks used for the primary vertex reconstruction
876   if (fTPCVertex && fTPCVertex->GetStatus()) {
877      UShort_t *primIdx=fTPCVertex->GetIndices();
878      Int_t n=fTPCVertex->GetNIndices();
879      while (n--) {
880        Int_t idx=Int_t(primIdx[n]);
881        if (idx==last) {
882           primIdx[n]=Short_t(rm); 
883           used--;
884           if (!used) return kTRUE;
885        }
886      }
887   }  
888   if (fPrimaryVertex && fPrimaryVertex->GetStatus()) {
889      UShort_t *primIdx=fPrimaryVertex->GetIndices();
890      Int_t n=fPrimaryVertex->GetNIndices();
891      while (n--) {
892        Int_t idx=Int_t(primIdx[n]);
893        if (idx==last) {
894           primIdx[n]=Short_t(rm); 
895           used--;
896           if (!used) return kTRUE;
897        }
898      }
899   }  
900
901   // Remap the indices of the daughters of reconstructed decays
902   for (Int_t n=0; n<nv0; n++) {
903     AliESDv0 *v0=GetV0(n);
904     if (v0->GetIndex(0)==last) {
905        v0->SetIndex(0,rm);
906        used--;
907        if (!used) return kTRUE;
908     }
909     if (v0->GetIndex(1)==last) {
910        v0->SetIndex(1,rm);
911        used--;
912        if (!used) return kTRUE;
913     }
914   }
915
916   for (Int_t n=0; n<ncs; n++) {
917     AliESDcascade *cs=GetCascade(n);
918     if (cs->GetIndex()==last) {
919        cs->SetIndex(rm);
920        used--;
921        if (!used) return kTRUE;
922     }
923     AliESDv0 *v0=cs;
924     if (v0->GetIndex(0)==last) {
925        v0->SetIndex(0,rm);
926        used--;
927        if (!used) return kTRUE;
928     }
929     if (v0->GetIndex(1)==last) {
930        v0->SetIndex(1,rm);
931        used--;
932        if (!used) return kTRUE;
933     }
934   }
935
936   for (Int_t n=0; n<nkn; n++) {
937     AliESDkink *kn=GetKink(n);
938     if (kn->GetIndex(0)==last) {
939        kn->SetIndex(rm,0);
940        used--;
941        if (!used) return kTRUE;
942     }
943     if (kn->GetIndex(1)==last) {
944        kn->SetIndex(rm,1);
945        used--;
946        if (!used) return kTRUE;
947     }
948   }
949
950   // Remap the indices of the tracks accosicated with CaloClusters
951   for (Int_t n=0; n<ncl; n++) {
952     AliESDCaloCluster *cluster=GetCaloCluster(n);
953     TArrayI *arr=cluster->GetTracksMatched();
954     Int_t s=arr->GetSize();
955     while (s--) {
956       Int_t idx=arr->At(s);
957       if (idx==last) {
958          arr->AddAt(rm,s);
959          used--; 
960          if (!used) return kTRUE;
961       }
962     }
963   }
964
965   return kTRUE;
966 }
967
968 //______________________________________________________________________________
969 Bool_t AliESDEvent::Clean(Float_t *cleanPars) 
970 {
971   //
972   // Remove the data which are not needed for the physics analysis.
973   //
974   // 1) Cleaning the V0 candidates
975   //    ---------------------------
976   //    If the cosine of the V0 pointing angle "csp" and 
977   //    the DCA between the daughter tracks "dca" does not satisfy 
978   //    the conditions 
979   //
980   //     csp > cleanPars[1] + dca/cleanPars[0]*(1.- cleanPars[1])
981   //
982   //    an attempt to remove this V0 candidate from ESD is made.
983   //
984   //    The V0 candidate gets removed if it does not belong to any 
985   //    recosntructed cascade decay
986   //
987   //    12.11.2007, optimal values: cleanPars[0]=0.5, cleanPars[1]=0.999
988   //
989   // 2) Cleaning the tracks
990   //    ----------------------
991   //    If track's transverse parameter is larger than cleanPars[2]
992   //                       OR
993   //    track's longitudinal parameter is larger than cleanPars[3]
994   //    an attempt to remove this track from ESD is made.
995   //
996   //    The track gets removed if it does not come 
997   //    from a reconstructed decay
998   //
999   Bool_t rc=kFALSE;
1000
1001   Float_t dcaMax=cleanPars[0];
1002   Float_t cspMin=cleanPars[1];
1003
1004   Int_t nV0s=GetNumberOfV0s();
1005   for (Int_t i=nV0s-1; i>=0; i--) {
1006     AliESDv0 *v0=GetV0(i);
1007
1008     Float_t dca=v0->GetDcaV0Daughters();
1009     Float_t csp=v0->GetV0CosineOfPointingAngle();
1010     Float_t cspcut=cspMin + dca/dcaMax*(1.-cspMin);
1011     if (csp > cspcut) continue;
1012     if (RemoveV0(i)) rc=kTRUE;
1013   }
1014
1015
1016   Float_t dmax=cleanPars[2], zmax=cleanPars[3];
1017
1018   const AliESDVertex *vertex=GetPrimaryVertexSPD();
1019   Bool_t vtxOK=vertex->GetStatus();
1020   
1021   Int_t nTracks=GetNumberOfTracks();
1022   for (Int_t i=nTracks-1; i>=0; i--) {
1023     AliESDtrack *track=GetTrack(i);
1024     if (!track) {AliFatal(Form("NULL pointer for ESD track %d",i));}
1025     Float_t xy,z; track->GetImpactParameters(xy,z);
1026     if ((TMath::Abs(xy) > dmax) || (vtxOK && (TMath::Abs(z) > zmax))) {
1027       if (RemoveTrack(i)) rc=kTRUE;
1028     }
1029   }
1030
1031   return rc;
1032 }
1033
1034 //______________________________________________________________________________
1035 Char_t  AliESDEvent::AddPileupVertexSPD(const AliESDVertex *vtx) 
1036 {
1037     // Add a pileup primary vertex reconstructed with SPD
1038     TClonesArray &ftr = *fSPDPileupVertices;
1039     Char_t n=Char_t(ftr.GetEntriesFast());
1040     AliESDVertex *vertex = new(ftr[n]) AliESDVertex(*vtx);
1041     vertex->SetID(n);
1042     return n;
1043 }
1044
1045 //______________________________________________________________________________
1046 Char_t  AliESDEvent::AddPileupVertexTracks(const AliESDVertex *vtx) 
1047 {
1048     // Add a pileup primary vertex reconstructed with SPD
1049     TClonesArray &ftr = *fTrkPileupVertices;
1050     Char_t n=Char_t(ftr.GetEntriesFast());
1051     AliESDVertex *vertex = new(ftr[n]) AliESDVertex(*vtx);
1052     vertex->SetID(n);
1053     return n;
1054 }
1055
1056 //______________________________________________________________________________
1057 Int_t  AliESDEvent::AddTrack(const AliESDtrack *t) 
1058 {
1059     // Add track
1060     TClonesArray &ftr = *fTracks;
1061     AliESDtrack * track = new(ftr[fTracks->GetEntriesFast()])AliESDtrack(*t);
1062     track->SetID(fTracks->GetEntriesFast()-1);
1063     track->SetESDEvent(this);
1064     return  track->GetID();    
1065 }
1066
1067 //______________________________________________________________________________
1068 AliESDtrack*  AliESDEvent::NewTrack() 
1069 {
1070     // Add a new track
1071     TClonesArray &ftr = *fTracks;
1072     AliESDtrack * track = new(ftr[fTracks->GetEntriesFast()])AliESDtrack();
1073     track->SetID(fTracks->GetEntriesFast()-1);
1074     track->SetESDEvent(this);
1075     return  track;
1076 }
1077
1078 //______________________________________________________________________________
1079 Bool_t AliESDEvent::MoveMuonObjects() 
1080 {
1081   // move MUON clusters and pads to the new ESD structure in needed.
1082   // to ensure backward compatibility
1083   
1084   if (!fOldMuonStructure) return kTRUE;
1085   
1086   if (!fMuonTracks || !fMuonClusters || !fMuonPads) return kFALSE;
1087   
1088   Bool_t reset = kTRUE;
1089   Bool_t containTrackerData = kFALSE;
1090   for (Int_t i = 0; i < fMuonTracks->GetEntriesFast(); i++) {
1091     
1092     AliESDMuonTrack *track = (AliESDMuonTrack*) fMuonTracks->UncheckedAt(i);
1093     
1094     if (track->ContainTrackerData()) containTrackerData = kTRUE;
1095     else continue;
1096     
1097     if (!track->IsOldTrack()) continue;
1098     
1099     // remove objects connected to previous event if needed
1100     if (reset) {
1101       if (fMuonClusters->GetEntriesFast() > 0) fMuonClusters->Clear("C");
1102       if (fMuonPads->GetEntriesFast() > 0) fMuonPads->Clear("C");
1103       reset = kFALSE;
1104     }
1105     
1106     track->MoveClustersToESD(*this);
1107     
1108   }
1109   
1110   // remove objects connected to previous event if needed
1111   if (!containTrackerData) {
1112     if (fMuonClusters->GetEntriesFast() > 0) fMuonClusters->Clear("C");
1113     if (fMuonPads->GetEntriesFast() > 0) fMuonPads->Clear("C");
1114   }
1115   
1116   return kTRUE;
1117 }
1118
1119 //______________________________________________________________________________
1120 AliESDMuonTrack* AliESDEvent::GetMuonTrack(Int_t i)
1121 {
1122   // get the MUON track at the position i in the internal array of track
1123   if (!fMuonTracks) return 0x0;
1124   if (!MoveMuonObjects()) return 0x0;
1125   AliESDMuonTrack *track = (AliESDMuonTrack*) fMuonTracks->UncheckedAt(i);
1126   track->SetESDEvent(this);
1127   return track;
1128 }
1129
1130 //______________________________________________________________________________
1131 AliESDMuonGlobalTrack* AliESDEvent::GetMuonGlobalTrack(Int_t i)                      // AU
1132 {
1133   // get the MUON+MFT track at the position i in the internal array of track
1134   if (!fMuonGlobalTracks) return 0x0;
1135   AliESDMuonGlobalTrack *track = (AliESDMuonGlobalTrack*) fMuonGlobalTracks->UncheckedAt(i);
1136   track->SetESDEvent(this);
1137   return track;
1138 }
1139
1140 //______________________________________________________________________________
1141 void AliESDEvent::AddMuonTrack(const AliESDMuonTrack *t) 
1142 {
1143   // add a MUON track
1144   TClonesArray &fmu = *fMuonTracks;
1145   AliESDMuonTrack *track = new(fmu[fMuonTracks->GetEntriesFast()]) AliESDMuonTrack(*t);
1146   track->MoveClustersToESD(*this);
1147 }
1148
1149 //______________________________________________________________________________
1150 void AliESDEvent::AddMuonGlobalTrack(const AliESDMuonGlobalTrack *t)                             // AU
1151 {
1152   // add a MUON+MFT track
1153   TClonesArray &fmu = *fMuonGlobalTracks;
1154   new (fmu[fMuonGlobalTracks->GetEntriesFast()]) AliESDMuonGlobalTrack(*t);
1155 }
1156
1157 //______________________________________________________________________________
1158
1159 AliESDMuonTrack* AliESDEvent::NewMuonTrack() 
1160 {
1161   // create a new MUON track at the end of the internal array of track
1162   TClonesArray &fmu = *fMuonTracks;
1163   return new(fmu[fMuonTracks->GetEntriesFast()]) AliESDMuonTrack();
1164 }
1165
1166 //______________________________________________________________________________
1167 AliESDMuonGlobalTrack* AliESDEvent::NewMuonGlobalTrack()                                         // AU
1168 {
1169   // create a new MUON+MFT track at the end of the internal array of track
1170   TClonesArray &fmu = *fMuonGlobalTracks;
1171   return new(fmu[fMuonGlobalTracks->GetEntriesFast()]) AliESDMuonGlobalTrack();
1172 }
1173
1174 //______________________________________________________________________________
1175 Int_t AliESDEvent::GetNumberOfMuonClusters()
1176 {
1177   // get the number of MUON clusters
1178   if (!fMuonClusters) return 0;
1179   if (!MoveMuonObjects()) return 0;
1180   return fMuonClusters->GetEntriesFast();
1181 }
1182
1183 //______________________________________________________________________________
1184 AliESDMuonCluster* AliESDEvent::GetMuonCluster(Int_t i)
1185 {
1186   // get the MUON cluster at the position i in the internal array of cluster
1187   if (!fMuonClusters) return 0x0;
1188   if (!MoveMuonObjects()) return 0x0;
1189   return (AliESDMuonCluster*) fMuonClusters->UncheckedAt(i);
1190 }
1191
1192 //______________________________________________________________________________
1193 AliESDMuonCluster* AliESDEvent::FindMuonCluster(UInt_t clusterId)
1194 {
1195   // find the MUON cluster with this Id in the internal array of cluster
1196   if (!fMuonClusters) return 0x0;
1197   if (!MoveMuonObjects()) return 0x0;
1198   for (Int_t i = 0; i < fMuonClusters->GetEntriesFast(); i++) {
1199     AliESDMuonCluster *cluster = (AliESDMuonCluster*) fMuonClusters->UncheckedAt(i);
1200     if (cluster->GetUniqueID() == clusterId) return cluster;
1201   }
1202   return 0x0;
1203 }
1204
1205 //______________________________________________________________________________
1206 AliESDMuonCluster* AliESDEvent::NewMuonCluster() 
1207 {
1208   // create a new MUON cluster at the end of the internal array of cluster
1209   TClonesArray &fmu = *fMuonClusters;
1210   return new(fmu[fMuonClusters->GetEntriesFast()]) AliESDMuonCluster();
1211 }
1212
1213 //______________________________________________________________________________
1214 Int_t AliESDEvent::GetNumberOfMuonPads()
1215 {
1216   // get the number of MUON pads
1217   if (!fMuonPads) return 0;
1218   if (!MoveMuonObjects()) return 0;
1219   return fMuonPads->GetEntriesFast();
1220 }
1221
1222 //______________________________________________________________________________
1223 AliESDMuonPad* AliESDEvent::GetMuonPad(Int_t i)
1224 {
1225   // get the MUON pad at the position i in the internal array of pad
1226   if (!fMuonPads) return 0x0;
1227   if (!MoveMuonObjects()) return 0x0;
1228   return (AliESDMuonPad*) fMuonPads->UncheckedAt(i);
1229 }
1230
1231 //______________________________________________________________________________
1232 AliESDMuonPad* AliESDEvent::FindMuonPad(UInt_t padId)
1233 {
1234   // find the MUON pad with this Id in the internal array of pad
1235   if (!fMuonPads) return 0x0;
1236   if (!MoveMuonObjects()) return 0x0;
1237   for (Int_t i = 0; i < fMuonPads->GetEntriesFast(); i++) {
1238     AliESDMuonPad *pad = (AliESDMuonPad*) fMuonPads->UncheckedAt(i);
1239     if (pad->GetUniqueID() == padId) return pad;
1240   }
1241   return 0x0;
1242 }
1243
1244 //______________________________________________________________________________
1245 AliESDMuonPad* AliESDEvent::NewMuonPad() 
1246 {
1247   // create a new MUON pad at the end of the internal array of pad
1248   TClonesArray &fmu = *fMuonPads;
1249   return new(fmu[fMuonPads->GetEntriesFast()]) AliESDMuonPad();
1250 }
1251
1252 //______________________________________________________________________________
1253 void AliESDEvent::AddPmdTrack(const AliESDPmdTrack *t) 
1254 {
1255   TClonesArray &fpmd = *fPmdTracks;
1256   new(fpmd[fPmdTracks->GetEntriesFast()]) AliESDPmdTrack(*t);
1257 }
1258
1259 //______________________________________________________________________________
1260 void AliESDEvent::SetTrdTrigger(const AliESDTrdTrigger *t)
1261 {
1262   *fTrdTrigger = *t;
1263 }
1264
1265 //______________________________________________________________________________
1266 void AliESDEvent::AddTrdTrack(const AliESDTrdTrack *t) 
1267 {
1268   TClonesArray &ftrd = *fTrdTracks;
1269   new(ftrd[fTrdTracks->GetEntriesFast()]) AliESDTrdTrack(*t);
1270 }
1271
1272 //______________________________________________________________________________
1273 void AliESDEvent::AddTrdTracklet(const AliESDTrdTracklet *trkl)
1274 {
1275   new ((*fTrdTracklets)[fTrdTracklets->GetEntriesFast()]) AliESDTrdTracklet(*trkl);
1276 }
1277
1278 //______________________________________________________________________________
1279 void AliESDEvent::AddTrdTracklet(UInt_t trackletWord, Short_t hcid, Int_t label)
1280 {
1281   new ((*fTrdTracklets)[fTrdTracklets->GetEntriesFast()]) AliESDTrdTracklet(trackletWord, hcid, label);
1282 }
1283
1284 //______________________________________________________________________________
1285 Int_t AliESDEvent::AddKink(const AliESDkink *c) 
1286 {
1287   // Add kink
1288   TClonesArray &fk = *fKinks;
1289   AliESDkink * kink = new(fk[fKinks->GetEntriesFast()]) AliESDkink(*c);
1290   kink->SetID(fKinks->GetEntriesFast()); // CKB different from the other imps..
1291   return fKinks->GetEntriesFast()-1;
1292 }
1293
1294
1295 //______________________________________________________________________________
1296 void AliESDEvent::AddCascade(const AliESDcascade *c) 
1297 {
1298   TClonesArray &fc = *fCascades;
1299   new(fc[fCascades->GetEntriesFast()]) AliESDcascade(*c);
1300 }
1301
1302 //______________________________________________________________________________
1303 void AliESDEvent::AddCosmicTrack(const AliESDCosmicTrack *t) 
1304 {
1305   TClonesArray &ft = *fCosmicTracks;
1306   new(ft[fCosmicTracks->GetEntriesFast()]) AliESDCosmicTrack(*t);
1307
1308
1309
1310 //______________________________________________________________________________
1311 Int_t AliESDEvent::AddCaloCluster(const AliESDCaloCluster *c) 
1312 {
1313   // Add calocluster
1314   TClonesArray &fc = *fCaloClusters;
1315   AliESDCaloCluster *clus = new(fc[fCaloClusters->GetEntriesFast()]) AliESDCaloCluster(*c);
1316   clus->SetID(fCaloClusters->GetEntriesFast()-1);
1317   return fCaloClusters->GetEntriesFast()-1;
1318 }
1319
1320
1321 //______________________________________________________________________________
1322 void  AliESDEvent::AddRawDataErrorLog(const AliRawDataErrorLog *log) const {
1323   TClonesArray &errlogs = *fErrorLogs;
1324   new(errlogs[errlogs.GetEntriesFast()])  AliRawDataErrorLog(*log);
1325 }
1326
1327 //______________________________________________________________________________
1328 void AliESDEvent::SetZDCData(const AliESDZDC * obj)
1329
1330   // use already allocated space
1331   if(fESDZDC)
1332     *fESDZDC = *obj;
1333 }
1334
1335 //______________________________________________________________________________
1336 void  AliESDEvent::SetPrimaryVertexTPC(const AliESDVertex *vertex) 
1337 {
1338   // Set the TPC vertex
1339   // use already allocated space
1340   if(fTPCVertex){
1341     *fTPCVertex = *vertex;
1342     fTPCVertex->SetName(fgkESDListName[kTPCVertex]);
1343   }
1344 }
1345
1346 //______________________________________________________________________________
1347 void  AliESDEvent::SetPrimaryVertexSPD(const AliESDVertex *vertex) 
1348 {
1349   // Set the SPD vertex
1350   // use already allocated space
1351   if(fSPDVertex){
1352     *fSPDVertex = *vertex;
1353     fSPDVertex->SetName(fgkESDListName[kSPDVertex]);
1354   }
1355 }
1356
1357 //______________________________________________________________________________
1358 void  AliESDEvent::SetPrimaryVertexTracks(const AliESDVertex *vertex) 
1359 {
1360   // Set the primary vertex reconstructed using he ESD tracks.
1361   // use already allocated space
1362   if(fPrimaryVertex){
1363     *fPrimaryVertex = *vertex;
1364     fPrimaryVertex->SetName(fgkESDListName[kPrimaryVertex]);
1365   }
1366 }
1367
1368 //______________________________________________________________________________
1369 const AliESDVertex * AliESDEvent::GetPrimaryVertex() const 
1370 {
1371   //
1372   // Get the "best" available reconstructed primary vertex.
1373   //
1374   if(fPrimaryVertex){
1375     if (fPrimaryVertex->GetStatus()) return fPrimaryVertex;
1376   }
1377   if(fSPDVertex){
1378     if (fSPDVertex->GetStatus()) return fSPDVertex;
1379   }
1380   if(fTPCVertex) return fTPCVertex;
1381   
1382   AliWarning("No primary vertex available. Returning the \"default\"...");
1383   return fSPDVertex;
1384 }
1385
1386 //______________________________________________________________________________
1387 AliESDVertex * AliESDEvent::PrimaryVertexTracksUnconstrained() const 
1388 {
1389   //
1390   // Removes diamond constraint from fPrimaryVertex (reconstructed with tracks)
1391   // Returns a AliESDVertex which has to be deleted by the user
1392   //
1393   if(!fPrimaryVertex) {
1394     AliWarning("No primary vertex from tracks available.");
1395     return 0;
1396   }
1397   if(!fPrimaryVertex->GetStatus()) {
1398     AliWarning("No primary vertex from tracks available.");
1399     return 0;
1400   }
1401
1402   AliVertexerTracks vertexer(GetMagneticField());
1403   Float_t diamondxyz[3]={(Float_t)GetDiamondX(),(Float_t)GetDiamondY(),0.};
1404   Float_t diamondcovxy[3]; GetDiamondCovXY(diamondcovxy);
1405   Float_t diamondcov[6]={diamondcovxy[0],diamondcovxy[1],diamondcovxy[2],0.,0.,7.};
1406   AliESDVertex *vertex = 
1407     (AliESDVertex*)vertexer.RemoveConstraintFromVertex(fPrimaryVertex,diamondxyz,diamondcov);
1408
1409   return vertex;
1410 }
1411
1412 //______________________________________________________________________________
1413 void AliESDEvent::SetMultiplicity(const AliMultiplicity *mul) 
1414 {
1415   // Set the SPD Multiplicity
1416   if(fSPDMult){
1417     *fSPDMult = *mul;
1418   }
1419 }
1420
1421
1422 //______________________________________________________________________________
1423 void AliESDEvent::SetFMDData(AliESDFMD * obj) 
1424
1425   // use already allocated space
1426   if(fESDFMD){
1427     *fESDFMD = *obj;
1428   }
1429 }
1430
1431 //______________________________________________________________________________
1432 void AliESDEvent::SetVZEROData(const AliESDVZERO * obj)
1433
1434   // use already allocated space
1435   if(fESDVZERO)
1436     *fESDVZERO = *obj;
1437 }
1438
1439 //______________________________________________________________________________
1440 void AliESDEvent::SetTZEROData(const AliESDTZERO * obj)
1441
1442   // use already allocated space
1443   if(fESDTZERO)
1444     *fESDTZERO = *obj;
1445 }
1446
1447
1448 //______________________________________________________________________________
1449 void AliESDEvent::SetACORDEData(AliESDACORDE * obj)
1450 {
1451   if(fESDACORDE)
1452     *fESDACORDE = *obj;
1453 }
1454
1455 //______________________________________________________________________________
1456 void AliESDEvent::SetADData(AliESDAD * obj)
1457 {
1458   if(fESDAD)
1459     *fESDAD = *obj;
1460 }
1461
1462 //______________________________________________________________________________
1463 void AliESDEvent::GetESDfriend(AliESDfriend *ev) const 
1464 {
1465   //
1466   // Extracts the complementary info from the ESD
1467   //
1468   if (!ev) return;
1469
1470   Int_t ntrk=GetNumberOfTracks();
1471
1472   for (Int_t i=0; i<ntrk; i++) {
1473     AliESDtrack *t=GetTrack(i);
1474     if (!t) {AliFatal(Form("NULL pointer for ESD track %d",i));}
1475     const AliESDfriendTrack *f=t->GetFriendTrack();
1476     ev->AddTrack(f);
1477
1478     t->ReleaseESDfriendTrack();// Not to have two copies of "friendTrack"
1479
1480   }
1481
1482   AliESDfriend *fr = (AliESDfriend*)(const_cast<AliESDEvent*>(this)->FindListObject("AliESDfriend"));
1483   if (fr) ev->SetVZEROfriend(fr->GetVZEROfriend());
1484 }
1485
1486 //______________________________________________________________________________
1487 void AliESDEvent::AddObject(TObject* obj) 
1488 {
1489   // Add an object to the list of object.
1490   // Please be aware that in order to increase performance you should
1491   // refrain from using TObjArrays (if possible). Use TClonesArrays, instead.
1492   fESDObjects->SetOwner(kTRUE);
1493   fESDObjects->AddLast(obj);
1494 }
1495
1496 //______________________________________________________________________________
1497 void AliESDEvent::GetStdContent() 
1498 {
1499   // set pointers for standard content
1500   // get by name much safer and not a big overhead since not called very often
1501  
1502   fESDRun = (AliESDRun*)fESDObjects->FindObject(fgkESDListName[kESDRun]);
1503   fHeader = (AliESDHeader*)fESDObjects->FindObject(fgkESDListName[kHeader]);
1504   fESDZDC = (AliESDZDC*)fESDObjects->FindObject(fgkESDListName[kESDZDC]);
1505   fESDFMD = (AliESDFMD*)fESDObjects->FindObject(fgkESDListName[kESDFMD]);
1506   fESDVZERO = (AliESDVZERO*)fESDObjects->FindObject(fgkESDListName[kESDVZERO]);
1507   fESDTZERO = (AliESDTZERO*)fESDObjects->FindObject(fgkESDListName[kESDTZERO]);
1508   fTPCVertex = (AliESDVertex*)fESDObjects->FindObject(fgkESDListName[kTPCVertex]);
1509   fSPDVertex = (AliESDVertex*)fESDObjects->FindObject(fgkESDListName[kSPDVertex]);
1510   fPrimaryVertex = (AliESDVertex*)fESDObjects->FindObject(fgkESDListName[kPrimaryVertex]);
1511   fSPDMult =       (AliMultiplicity*)fESDObjects->FindObject(fgkESDListName[kSPDMult]);
1512   fPHOSTrigger = (AliESDCaloTrigger*)fESDObjects->FindObject(fgkESDListName[kPHOSTrigger]);
1513   fEMCALTrigger = (AliESDCaloTrigger*)fESDObjects->FindObject(fgkESDListName[kEMCALTrigger]);
1514   fSPDPileupVertices = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kSPDPileupVertices]);
1515   fTrkPileupVertices = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTrkPileupVertices]);
1516   fTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTracks]);
1517   fMuonTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kMuonTracks]);
1518   fMuonClusters = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kMuonClusters]);
1519   fMuonPads = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kMuonPads]);
1520   fMuonGlobalTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kMuonGlobalTracks]);         // AU
1521   fPmdTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kPmdTracks]);
1522   fTrdTrigger = (AliESDTrdTrigger*)fESDObjects->FindObject(fgkESDListName[kTrdTrigger]);
1523   fTrdTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTrdTracks]);
1524   fTrdTracklets = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTrdTracklets]);
1525   fV0s = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kV0s]);
1526   fCascades = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kCascades]);
1527   fKinks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kKinks]);
1528   fCaloClusters = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kCaloClusters]);
1529   fEMCALCells = (AliESDCaloCells*)fESDObjects->FindObject(fgkESDListName[kEMCALCells]);
1530   fPHOSCells = (AliESDCaloCells*)fESDObjects->FindObject(fgkESDListName[kPHOSCells]);
1531   fErrorLogs = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kErrorLogs]);
1532   fESDACORDE = (AliESDACORDE*)fESDObjects->FindObject(fgkESDListName[kESDACORDE]);
1533   fESDAD = (AliESDAD*)fESDObjects->FindObject(fgkESDListName[kESDAD]);
1534   fTOFHeader = (AliTOFHeader*)fESDObjects->FindObject(fgkESDListName[kTOFHeader]);
1535   fCosmicTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kCosmicTracks]);
1536   fESDTOFClusters = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTOFclusters]);
1537   fESDTOFHits = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTOFhit]);
1538   fESDTOFMatches = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTOFmatch]);
1539 }
1540
1541 //______________________________________________________________________________
1542 void AliESDEvent::SetStdNames(){
1543   // Set the names of the standard contents
1544   // 
1545   if(fESDObjects->GetEntries()>=kESDListN){
1546     for(int i = 0;i < fESDObjects->GetEntries() && i<kESDListN;i++){
1547       TObject *fObj = fESDObjects->At(i);
1548       if(fObj->InheritsFrom("TNamed")){
1549         ((TNamed*)fObj)->SetName(fgkESDListName[i]);
1550       }
1551       else if(fObj->InheritsFrom("TClonesArray")){
1552         ((TClonesArray*)fObj)->SetName(fgkESDListName[i]);
1553       }
1554     }
1555   }
1556   else{
1557      AliWarning("Std Entries missing");
1558   }
1559
1560
1561 //______________________________________________________________________________
1562 void AliESDEvent::CreateStdContent(Bool_t bUseThisList){
1563   fUseOwnList = bUseThisList;
1564   CreateStdContent();
1565 }
1566
1567 //______________________________________________________________________________
1568 void AliESDEvent::CreateStdContent() 
1569 {
1570   // create the standard AOD content and set pointers
1571
1572   // create standard objects and add them to the TList of objects
1573   AddObject(new AliESDRun());
1574   AddObject(new AliESDHeader());
1575   AddObject(new AliESDZDC());
1576   AddObject(new AliESDFMD());
1577   AddObject(new AliESDVZERO());
1578   AddObject(new AliESDTZERO());
1579   AddObject(new AliESDVertex());
1580   AddObject(new AliESDVertex());
1581   AddObject(new AliESDVertex());
1582   AddObject(new AliMultiplicity());
1583   AddObject(new AliESDCaloTrigger());
1584   AddObject(new AliESDCaloTrigger());
1585   AddObject(new TClonesArray("AliESDVertex",0));
1586   AddObject(new TClonesArray("AliESDVertex",0));
1587   AddObject(new TClonesArray("AliESDtrack",0));
1588   AddObject(new TClonesArray("AliESDMuonTrack",0));
1589   AddObject(new TClonesArray("AliESDMuonCluster",0));
1590   AddObject(new TClonesArray("AliESDMuonPad",0));
1591   AddObject(new TClonesArray("AliESDMuonGlobalTrack",0));   // AU
1592   AddObject(new TClonesArray("AliESDPmdTrack",0));
1593   AddObject(new AliESDTrdTrigger());
1594   AddObject(new TClonesArray("AliESDTrdTrack",0));
1595   AddObject(new TClonesArray("AliESDTrdTracklet",0));
1596   AddObject(new TClonesArray("AliESDv0",0));
1597   AddObject(new TClonesArray("AliESDcascade",0));
1598   AddObject(new TClonesArray("AliESDkink",0));
1599   AddObject(new TClonesArray("AliESDCaloCluster",0));
1600   AddObject(new AliESDCaloCells());
1601   AddObject(new AliESDCaloCells());
1602   AddObject(new TClonesArray("AliRawDataErrorLog",0));
1603   AddObject(new AliESDACORDE()); 
1604   AddObject(new AliESDAD()); 
1605   AddObject(new AliTOFHeader());
1606   AddObject(new TClonesArray("AliESDCosmicTrack",0));
1607   AddObject(new TClonesArray("AliESDTOFCluster",0));
1608   AddObject(new TClonesArray("AliESDTOFHit",0));
1609   AddObject(new TClonesArray("AliESDTOFMatch",0));
1610         
1611   // check the order of the indices against enum...
1612
1613   // set names
1614   SetStdNames();
1615   // read back pointers
1616   GetStdContent();
1617 }
1618
1619 //______________________________________________________________________________
1620 void AliESDEvent::CompleteStdContent() 
1621 {
1622   // Create missing standard objects and add them to the TList of objects
1623   //
1624   // Add cosmic tracks for cases where esd files were created 
1625   // before adding them to the std content
1626   if (!fESDObjects->FindObject(fgkESDListName[kCosmicTracks])) {
1627     TClonesArray* cosmics = new TClonesArray("AliESDCosmicTrack",0);
1628     fESDObjects->AddAt(cosmics, kCosmicTracks);
1629     fESDObjects->SetOwner(kTRUE);
1630   }
1631   // Add new MUON containers if missing (for backward compatibility)
1632   if (!fESDObjects->FindObject(fgkESDListName[kMuonClusters])) {
1633     TClonesArray* muonClusters = new TClonesArray("AliESDMuonCluster",0);
1634     muonClusters->SetName(fgkESDListName[kMuonClusters]);
1635     fESDObjects->AddAt(muonClusters, kMuonClusters);
1636     fESDObjects->SetOwner(kTRUE);
1637   }
1638   if (!fESDObjects->FindObject(fgkESDListName[kMuonPads])) {
1639     TClonesArray* muonPads = new TClonesArray("AliESDMuonPad",0);
1640     muonPads->SetName(fgkESDListName[kMuonPads]);
1641     fESDObjects->AddAt(muonPads, kMuonPads);
1642     fESDObjects->SetOwner(kTRUE);
1643   }
1644 }
1645
1646 //______________________________________________________________________________
1647 TObject* AliESDEvent::FindListObject(const char *name) const {
1648 //
1649 // Find object with name "name" in the list of branches
1650 //
1651   if(fESDObjects){
1652     return fESDObjects->FindObject(name);
1653   }
1654   return 0;
1655
1656
1657 //______________________________________________________________________________
1658 Int_t AliESDEvent::GetPHOSClusters(TRefArray *clusters) const
1659 {
1660   // fills the provided TRefArray with all found phos clusters
1661   
1662   clusters->Clear();
1663   
1664   AliESDCaloCluster *cl = 0;
1665   for (Int_t i = 0; i < GetNumberOfCaloClusters(); i++) {
1666     
1667     if ( (cl = GetCaloCluster(i)) ) {
1668       if (cl->IsPHOS()){
1669         clusters->Add(cl);
1670         AliDebug(1,Form("IsPHOS cluster %d Size: %d \n",i,clusters->GetEntriesFast()));
1671       }
1672     }
1673   }
1674   return clusters->GetEntriesFast();
1675 }
1676
1677 //______________________________________________________________________________
1678 Int_t AliESDEvent::GetEMCALClusters(TRefArray *clusters) const
1679 {
1680   // fills the provided TRefArray with all found emcal clusters
1681
1682   clusters->Clear();
1683
1684   AliESDCaloCluster *cl = 0;
1685   for (Int_t i = 0; i < GetNumberOfCaloClusters(); i++) {
1686
1687     if ( (cl = GetCaloCluster(i)) ) {
1688       if (cl->IsEMCAL()){
1689         clusters->Add(cl);
1690         AliDebug(1,Form("IsEMCAL cluster %d Size: %d \n",i,clusters->GetEntriesFast()));
1691       }
1692     }
1693   }
1694   return clusters->GetEntriesFast();
1695 }
1696
1697 //______________________________________________________________________________
1698 void AliESDEvent::WriteToTree(TTree* tree) const {
1699   // Book the branches as in TTree::Branch(TCollection*)
1700   // but add a "." at the end of top level branches which are
1701   // not a TClonesArray
1702
1703
1704   TString branchname;
1705   TIter next(fESDObjects);
1706   const Int_t kSplitlevel = 99; // default value in TTree::Branch()
1707   const Int_t kBufsize = 32000; // default value in TTree::Branch()
1708   TObject *obj = 0;
1709
1710   while ((obj = next())) {
1711     branchname.Form("%s", obj->GetName());
1712     if(branchname.CompareTo("AliESDfriend")==0)branchname = "ESDfriend.";
1713     if ((kSplitlevel > 1) &&  !obj->InheritsFrom(TClonesArray::Class())) {
1714       if(!branchname.EndsWith("."))branchname += ".";
1715     }
1716     if (!tree->FindBranch(branchname)) {
1717       // For the custom streamer to be called splitlevel
1718       // has to be negative, only needed for HLT
1719       Int_t splitLevel = (TString(obj->ClassName()) == "AliHLTGlobalTriggerDecision") ? -1 : kSplitlevel - 1;
1720       tree->Bronch(branchname, obj->ClassName(), fESDObjects->GetObjectRef(obj),kBufsize, splitLevel);
1721     }
1722   }
1723
1724   tree->Branch("fDetectorStatus",(void*)&fDetectorStatus,"fDetectorStatus/l");
1725   tree->Branch("fDAQDetectorPattern",(void*)&fDAQDetectorPattern,"fDAQDetectorPattern/i");
1726   tree->Branch("fDAQAttributes",(void*)&fDAQAttributes,"fDAQAttributes/i");
1727 }
1728
1729 //______________________________________________________________________________
1730 void AliESDEvent::ReadFromTree(TTree *tree, Option_t* opt){
1731 //
1732 // Connect the ESDEvent to a tree
1733 //
1734   if(!tree){
1735     AliWarning("AliESDEvent::ReadFromTree() Zero Pointer to Tree \n");
1736     return;
1737   }
1738   // load the TTree
1739   if(!tree->GetTree())tree->LoadTree(0);
1740
1741   // if we find the "ESD" branch on the tree we do have the old structure
1742   if(tree->GetBranch("ESD")) {
1743     fOldMuonStructure = kFALSE;
1744     char ** address  = (char **)(tree->GetBranch("ESD")->GetAddress());
1745     // do we have the friend branch
1746     TBranch * esdFB = tree->GetBranch("ESDfriend.");
1747     char ** addressF = 0;
1748     if(esdFB)addressF = (char **)(esdFB->GetAddress());
1749     if (!address) {
1750       AliInfo("AliESDEvent::ReadFromTree() Reading old Tree");
1751       tree->SetBranchAddress("ESD",       &fESDOld);
1752       if(esdFB){
1753         tree->SetBranchAddress("ESDfriend.",&fESDFriendOld);
1754       }
1755     } else {
1756       AliInfo("AliESDEvent::ReadFromTree() Reading old Tree");
1757       AliInfo("Branch already connected. Using existing branch address.");
1758       fESDOld       = (AliESD*)       (*address);
1759       // addressF can still be 0, since branch needs to switched on
1760       if(addressF)fESDFriendOld = (AliESDfriend*) (*addressF);
1761     }
1762                                        
1763     //  have already connected the old ESD structure... ?
1764     // reuse also the pointer of the AlliESDEvent
1765     // otherwise create new ones
1766     TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("ESDObjectsConnectedToTree"));
1767   
1768     if(connectedList){
1769       // If connected use the connected list of objects
1770       if(fESDObjects!= connectedList){
1771         // protect when called twice 
1772         fESDObjects->Delete();
1773         fESDObjects = connectedList;
1774       }
1775       GetStdContent(); 
1776
1777       
1778       // The pointer to the friend changes when called twice via InitIO
1779       // since AliESDEvent is deleted
1780       TObject* oldf = FindListObject("AliESDfriend");
1781       TObject* newf = 0;
1782       if(addressF){
1783         newf = (TObject*)*addressF;
1784       }
1785       if(newf!=0&&oldf!=newf){
1786         // remove the old reference
1787         // Should we also delete it? Or is this handled in TTree I/O
1788         // since it is created by the first SetBranchAddress
1789         fESDObjects->Remove(oldf);
1790         // add the new one 
1791         fESDObjects->Add(newf);
1792       }
1793       
1794       fConnected = true;
1795       return;
1796     }
1797     // else...    
1798     CreateStdContent(); // create for copy
1799     // if we have the esdfriend add it, so we always can access it via the userinfo
1800     if(fESDFriendOld)AddObject(fESDFriendOld);
1801     // we are not owner of the list objects 
1802     // must not delete it
1803     fESDObjects->SetOwner(kTRUE);
1804     fESDObjects->SetName("ESDObjectsConnectedToTree");
1805     tree->GetUserInfo()->Add(fESDObjects);
1806     fConnected = true;
1807     return;
1808   }
1809   
1810
1811     delete fESDOld;
1812     fESDOld = 0;
1813   // Try to find AliESDEvent
1814   AliESDEvent *esdEvent = 0;
1815   esdEvent = (AliESDEvent*)tree->GetTree()->GetUserInfo()->FindObject("AliESDEvent");
1816   if(esdEvent){   
1817       // Check if already connected to tree
1818     esdEvent->Reset();
1819     TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("ESDObjectsConnectedToTree"));
1820
1821     
1822     if (connectedList && (strcmp(opt, "reconnect"))) {
1823       // If connected use the connected list if objects
1824       fESDObjects->Delete();
1825       fESDObjects = connectedList;
1826       tree->SetBranchAddress("fDetectorStatus",&fDetectorStatus); //PH probably redundant
1827       tree->SetBranchAddress("fDAQDetectorPattern",&fDAQDetectorPattern);
1828       tree->SetBranchAddress("fDAQAttributes",&fDAQAttributes);
1829       GetStdContent(); 
1830       fOldMuonStructure = fESDObjects->TestBit(BIT(23));
1831       fConnected = true;
1832       return;
1833     }
1834
1835     // Connect to tree
1836     // prevent a memory leak when reading back the TList
1837     // if (!(strcmp(opt, "reconnect"))) fESDObjects->Delete();
1838     
1839     if(!fUseOwnList){
1840       // create a new TList from the UserInfo TList... 
1841       // copy constructor does not work...
1842       fESDObjects = (TList*)(esdEvent->GetList()->Clone());
1843       fESDObjects->SetOwner(kTRUE);
1844     }
1845     else if ( fESDObjects->GetEntries()==0){
1846       // at least create the std content if we want to read to our list
1847       CreateStdContent(); 
1848     }
1849
1850     // in principle
1851     // we only need new things in the list if we do no already have it..
1852     // TODO just add new entries
1853     CompleteStdContent();
1854
1855     if(fESDObjects->GetEntries()<kESDListN){
1856       AliWarning(Form("AliESDEvent::ReadFromTree() TList contains less than the standard contents %d < %d \n",
1857                       fESDObjects->GetEntries(),kESDListN));
1858     }
1859     // set the branch addresses
1860     fOldMuonStructure = kFALSE;
1861     TIter next(fESDObjects);
1862     TNamed *el;
1863     while((el=(TNamed*)next())){
1864       TString bname(el->GetName());
1865       if(bname.CompareTo("AliESDfriend")==0)
1866         {
1867           // AliESDfriend does not have a name ...
1868             TBranch *br = tree->GetBranch("ESDfriend.");
1869             if (br) tree->SetBranchAddress("ESDfriend.",fESDObjects->GetObjectRef(el));
1870         }
1871       else{
1872         // check if branch exists under this Name
1873         TBranch *br = tree->GetBranch(bname.Data());
1874         if(br){
1875           tree->SetBranchAddress(bname.Data(),fESDObjects->GetObjectRef(el));
1876         }
1877         else{
1878           br = tree->GetBranch(Form("%s.",bname.Data()));
1879           if(br){
1880             tree->SetBranchAddress(Form("%s.",bname.Data()),fESDObjects->GetObjectRef(el));
1881           }
1882           else{
1883             AliWarning(Form("AliESDEvent::ReadFromTree() No Branch found with Name %s or %s.",bname.Data(),bname.Data()));
1884             if (bname == fgkESDListName[kMuonClusters]) {
1885               fOldMuonStructure = kTRUE;
1886             }
1887           }
1888
1889         }
1890       }
1891     }
1892     tree->SetBranchAddress("fDetectorStatus",&fDetectorStatus);
1893     tree->SetBranchAddress("fDAQDetectorPattern",&fDAQDetectorPattern);
1894     tree->SetBranchAddress("fDAQAttributes",&fDAQAttributes);
1895
1896     GetStdContent();
1897     // when reading back we are not owner of the list 
1898     // must not delete it
1899     fESDObjects->SetOwner(kTRUE);
1900     fESDObjects->SetName("ESDObjectsConnectedToTree");
1901     fESDObjects->SetBit(BIT(23), fOldMuonStructure);
1902     // we are not owner of the list objects 
1903     // must not delete it
1904     tree->GetUserInfo()->Add(fESDObjects);
1905     tree->GetUserInfo()->SetOwner(kFALSE);
1906     fConnected = true;
1907   }// no esdEvent -->
1908   else {
1909     // we can't get the list from the user data, create standard content
1910     // and set it by hand (no ESDfriend at the moment
1911     CreateStdContent();
1912     fOldMuonStructure = kFALSE;
1913     TIter next(fESDObjects);
1914     TNamed *el;
1915     while((el=(TNamed*)next())){
1916       TString bname(el->GetName());    
1917       TBranch *br = tree->GetBranch(bname.Data());
1918       if(br){
1919         tree->SetBranchAddress(bname.Data(),fESDObjects->GetObjectRef(el));
1920       }
1921       else{
1922         br = tree->GetBranch(Form("%s.",bname.Data()));
1923         if(br){
1924           tree->SetBranchAddress(Form("%s.",bname.Data()),fESDObjects->GetObjectRef(el));
1925         }
1926         else if (bname == fgkESDListName[kMuonClusters]) {
1927           fOldMuonStructure = kTRUE;
1928         }
1929       }
1930     }
1931     tree->SetBranchAddress("fDetectorStatus",&fDetectorStatus);
1932     tree->SetBranchAddress("fDAQDetectorPattern",&fDAQDetectorPattern);
1933     tree->SetBranchAddress("fDAQAttributes",&fDAQAttributes);
1934
1935     GetStdContent();
1936     // when reading back we are not owner of the list 
1937     // must not delete it
1938     fESDObjects->SetOwner(kTRUE);
1939   }
1940 }
1941
1942 //______________________________________________________________________________
1943 void AliESDEvent::CopyFromOldESD()
1944 {
1945   // Method which copies over everthing from the old esd structure to the 
1946   // new  
1947   if(fESDOld){
1948     ResetStdContent();
1949      // Run
1950     SetRunNumber(fESDOld->GetRunNumber());
1951     SetPeriodNumber(fESDOld->GetPeriodNumber());
1952     SetMagneticField(fESDOld->GetMagneticField());
1953   
1954     // leave out diamond ...
1955     // SetDiamond(const AliESDVertex *vertex) { fESDRun->SetDiamond(vertex);}
1956
1957     // header
1958     SetTriggerMask(fESDOld->GetTriggerMask());
1959     SetOrbitNumber(fESDOld->GetOrbitNumber());
1960     SetTimeStamp(fESDOld->GetTimeStamp());
1961     SetEventType(fESDOld->GetEventType());
1962     SetEventNumberInFile(fESDOld->GetEventNumberInFile());
1963     SetBunchCrossNumber(fESDOld->GetBunchCrossNumber());
1964     SetTriggerCluster(fESDOld->GetTriggerCluster());
1965
1966     // ZDC
1967
1968     SetZDC(fESDOld->GetZDCN1Energy(),
1969            fESDOld->GetZDCP1Energy(),
1970            fESDOld->GetZDCEMEnergy(),
1971            0,
1972            fESDOld->GetZDCN2Energy(),
1973            fESDOld->GetZDCP2Energy(),
1974            fESDOld->GetZDCParticipants(),
1975            0,
1976            0,
1977            0,
1978            0,
1979            0,
1980            0);
1981
1982     // FMD
1983     
1984     if(fESDOld->GetFMDData())SetFMDData(fESDOld->GetFMDData());
1985
1986     // T0
1987
1988     SetT0zVertex(fESDOld->GetT0zVertex());
1989     SetT0(fESDOld->GetT0());
1990     //  leave amps out
1991
1992     // VZERO
1993     if (fESDOld->GetVZEROData()) SetVZEROData(fESDOld->GetVZEROData());
1994
1995     if(fESDOld->GetVertex())SetPrimaryVertexSPD(fESDOld->GetVertex());
1996
1997     if(fESDOld->GetPrimaryVertex())SetPrimaryVertexTracks(fESDOld->GetPrimaryVertex());
1998
1999     if(fESDOld->GetMultiplicity())SetMultiplicity(fESDOld->GetMultiplicity());
2000
2001     for(int i = 0;i<fESDOld->GetNumberOfTracks();i++){
2002       AddTrack(fESDOld->GetTrack(i));
2003     }
2004
2005     for(int i = 0;i<fESDOld->GetNumberOfMuonTracks();i++){
2006       AddMuonTrack(fESDOld->GetMuonTrack(i));
2007     }
2008
2009     for(int i = 0;i<fESDOld->GetNumberOfPmdTracks();i++){
2010       AddPmdTrack(fESDOld->GetPmdTrack(i));
2011     }
2012
2013     for(int i = 0;i<fESDOld->GetNumberOfTrdTracks();i++){
2014       AddTrdTrack(fESDOld->GetTrdTrack(i));
2015     }
2016
2017     for(int i = 0;i<fESDOld->GetNumberOfV0s();i++){
2018       AddV0(fESDOld->GetV0(i));
2019     }
2020
2021     for(int i = 0;i<fESDOld->GetNumberOfCascades();i++){
2022       AddCascade(fESDOld->GetCascade(i));
2023     }
2024
2025     for(int i = 0;i<fESDOld->GetNumberOfKinks();i++){
2026       AddKink(fESDOld->GetKink(i));
2027     }
2028
2029
2030     for(int i = 0;i<fESDOld->GetNumberOfCaloClusters();i++){
2031       AddCaloCluster(fESDOld->GetCaloCluster(i));
2032     }
2033           
2034   }// if fesdold
2035 }
2036
2037 //______________________________________________________________________________
2038 Bool_t AliESDEvent::IsEventSelected(const char *trigExpr) const
2039 {
2040   // Check if the event satisfies the trigger
2041   // selection expression trigExpr.
2042   // trigExpr can be any logical expression
2043   // of the trigger classes defined in AliESDRun
2044   // In case of wrong syntax return kTRUE.
2045   // Modified by rl for 100 classes - to be tested
2046
2047   TString expr(trigExpr);
2048   if (expr.IsNull()) return kTRUE;
2049
2050   ULong64_t mask = GetTriggerMask();
2051   for(Int_t itrig = 0; itrig < AliESDRun::kNTriggerClasses/2; itrig++) {
2052     if (mask & (1ull << itrig)) {
2053       expr.ReplaceAll(GetESDRun()->GetTriggerClass(itrig),"1");
2054     }
2055     else {
2056       expr.ReplaceAll(GetESDRun()->GetTriggerClass(itrig),"0");
2057     }
2058   }
2059   ULong64_t maskNext50 = GetTriggerMaskNext50();
2060   for(Int_t itrig = 0; itrig < AliESDRun::kNTriggerClasses/2; itrig++) {
2061     if (maskNext50 & (1ull << itrig)) {
2062       expr.ReplaceAll(GetESDRun()->GetTriggerClass(itrig+50),"1");
2063     }
2064     else {
2065       expr.ReplaceAll(GetESDRun()->GetTriggerClass(itrig+50),"0");
2066     }
2067   }
2068
2069   Int_t error;
2070   if ((gROOT->ProcessLineFast(expr.Data(),&error) == 0) &&
2071       (error == TInterpreter::kNoError)) {
2072     return kFALSE;
2073   }
2074
2075   return kTRUE;
2076
2077 }
2078
2079 //______________________________________________________________________________
2080 TObject*  AliESDEvent::GetHLTTriggerDecision() const
2081 {
2082   // get the HLT trigger decission object
2083
2084   // cast away const'nes because the FindListObject method
2085   // is not const
2086   AliESDEvent* pNonConst=const_cast<AliESDEvent*>(this);
2087   return pNonConst->FindListObject("HLTGlobalTrigger");
2088 }
2089
2090 TString   AliESDEvent::GetHLTTriggerDescription() const
2091 {
2092   // get the HLT trigger decission description
2093   TString description;
2094   TObject* pDecision=GetHLTTriggerDecision();
2095   if (pDecision) {
2096     description=pDecision->GetTitle();
2097   }
2098
2099   return description;
2100 }
2101
2102 //______________________________________________________________________________
2103 Bool_t    AliESDEvent::IsHLTTriggerFired(const char* name) const
2104 {
2105   // get the HLT trigger decission description
2106   TObject* pDecision=GetHLTTriggerDecision();
2107   if (!pDecision) return kFALSE;
2108
2109   Option_t* option=pDecision->GetOption();
2110   if (option==NULL || *option!='1') return kFALSE;
2111
2112   if (name) {
2113     TString description=GetHLTTriggerDescription();
2114     Int_t index=description.Index(name);
2115     if (index<0) return kFALSE;
2116     index+=strlen(name);
2117     if (index>=description.Length()) return kFALSE;
2118     if (description[index]!=0 && description[index]!=' ') return kFALSE;
2119   }
2120   return kTRUE;
2121 }
2122
2123 //______________________________________________________________________________
2124 Bool_t  AliESDEvent::IsPileupFromSPD(Int_t minContributors, 
2125                                      Double_t minZdist, 
2126                                      Double_t nSigmaZdist, 
2127                                      Double_t nSigmaDiamXY, 
2128                                      Double_t nSigmaDiamZ) const{
2129   //
2130   // This function checks if there was a pile up
2131   // reconstructed with SPD
2132   //
2133   Int_t nc1=fSPDVertex->GetNContributors();
2134   if(nc1<1) return kFALSE;
2135   Int_t nPileVert=GetNumberOfPileupVerticesSPD();
2136   if(nPileVert==0) return kFALSE;
2137   
2138   for(Int_t i=0; i<nPileVert;i++){
2139     const AliESDVertex* pv=GetPileupVertexSPD(i);
2140     Int_t nc2=pv->GetNContributors();
2141     if(nc2>=minContributors){
2142       Double_t z1=fSPDVertex->GetZ();
2143       Double_t z2=pv->GetZ();
2144       Double_t distZ=TMath::Abs(z2-z1);
2145       Double_t distZdiam=TMath::Abs(z2-GetDiamondZ());
2146       Double_t cutZdiam=nSigmaDiamZ*TMath::Sqrt(GetSigma2DiamondZ());
2147       if(GetSigma2DiamondZ()<0.0001)cutZdiam=99999.; //protection for missing z diamond information
2148       if(distZ>minZdist && distZdiam<cutZdiam){
2149         Double_t x2=pv->GetX();
2150         Double_t y2=pv->GetY();
2151         Double_t distXdiam=TMath::Abs(x2-GetDiamondX());
2152         Double_t distYdiam=TMath::Abs(y2-GetDiamondY());
2153         Double_t cov1[6],cov2[6];       
2154         fSPDVertex->GetCovarianceMatrix(cov1);
2155         pv->GetCovarianceMatrix(cov2);
2156         Double_t errxDist=TMath::Sqrt(cov2[0]+GetSigma2DiamondX());
2157         Double_t erryDist=TMath::Sqrt(cov2[2]+GetSigma2DiamondY());
2158         Double_t errzDist=TMath::Sqrt(cov1[5]+cov2[5]);
2159         Double_t cutXdiam=nSigmaDiamXY*errxDist;
2160         if(GetSigma2DiamondX()<0.0001)cutXdiam=99999.; //protection for missing diamond information
2161         Double_t cutYdiam=nSigmaDiamXY*erryDist;
2162         if(GetSigma2DiamondY()<0.0001)cutYdiam=99999.; //protection for missing diamond information
2163         if( (distXdiam<cutXdiam) && (distYdiam<cutYdiam) && (distZ>nSigmaZdist*errzDist) ){
2164           return kTRUE;
2165         }
2166       }
2167     }
2168   }
2169   return kFALSE;
2170 }
2171
2172 //______________________________________________________________________________
2173 void AliESDEvent::EstimateMultiplicity(Int_t &tracklets, Int_t &trITSTPC, Int_t &trITSSApure, Double_t eta, Bool_t useDCAFlag,Bool_t useV0Flag) const
2174 {
2175   //
2176   // calculates 3 estimators for the multiplicity in the -eta:eta range
2177   // tracklets   : using SPD tracklets only
2178   // trITSTPC    : using TPC/ITS + complementary ITS SA tracks + tracklets from clusters not used by tracks
2179   // trITSSApure : using ITS standalone tracks + tracklets from clusters not used by tracks
2180   // if useDCAFlag is true: account for the ESDtrack flag marking the tracks with large DCA
2181   // if useV0Flag  is true: account for the ESDtrack flag marking conversion and K0's V0s
2182
2183   AliWarning("This obsolete method will be eliminated soon. Use AliESDtrackCuts::GetReferenceMultiplicity");
2184
2185   tracklets = trITSSApure = trITSTPC = 0;
2186   int ntr = fSPDMult ? fSPDMult->GetNumberOfTracklets() : 0;
2187   //
2188   // count tracklets
2189   for (int itr=ntr;itr--;) { 
2190     if (TMath::Abs(fSPDMult->GetEta(itr))>eta) continue;
2191     tracklets++;
2192     if (fSPDMult->FreeClustersTracklet(itr,0)) trITSTPC++;    // not used in ITS/TPC or ITS_SA track
2193     if (fSPDMult->FreeClustersTracklet(itr,1)) trITSSApure++; // not used in ITS_SA_Pure track
2194   }
2195   //
2196   // count real tracks
2197   ntr = GetNumberOfTracks();
2198   for (int itr=ntr;itr--;) {
2199     AliESDtrack *t = GetTrack(itr);
2200     if (!t) {AliFatal(Form("NULL pointer for ESD track %d",itr));}
2201     if (TMath::Abs(t->Eta())>eta) continue;
2202     if (!t->IsOn(AliESDtrack::kITSin)) continue;
2203     if (useDCAFlag && t->IsOn(AliESDtrack::kMultSec))  continue;
2204     if (useV0Flag  && t->IsOn(AliESDtrack::kMultInV0)) continue;    
2205     if (t->IsOn(AliESDtrack::kITSpureSA)) trITSSApure++;
2206     else                                  trITSTPC++;
2207   }
2208   //
2209 }
2210
2211 //______________________________________________________________________________
2212 Bool_t AliESDEvent::IsPileupFromSPDInMultBins() const {
2213     Int_t nTracklets=GetMultiplicity()->GetNumberOfTracklets();
2214     if(nTracklets<20) return IsPileupFromSPD(3,0.8);
2215     else if(nTracklets<50) return IsPileupFromSPD(4,0.8);
2216     else return IsPileupFromSPD(5,0.8);
2217 }
2218
2219 //______________________________________________________________________________
2220 void  AliESDEvent::SetTOFHeader(const AliTOFHeader *header)
2221 {
2222   //
2223   // Set the TOF event_time
2224   //
2225
2226   if (fTOFHeader) {
2227     *fTOFHeader=*header;
2228     //fTOFHeader->SetName(fgkESDListName[kTOFHeader]);
2229   }
2230   else {
2231     // for analysis of reconstructed events
2232     // when this information is not avaliable
2233     fTOFHeader = new AliTOFHeader(*header);
2234     //AddObject(fTOFHeader);
2235   }
2236
2237 }
2238
2239 //______________________________________________________________________________
2240 AliCentrality* AliESDEvent::GetCentrality()
2241 {
2242     if (!fCentrality) fCentrality = new AliCentrality();
2243     return  fCentrality;
2244 }
2245
2246 //______________________________________________________________________________
2247 AliEventplane* AliESDEvent::GetEventplane()
2248 {
2249     if (!fEventplane) fEventplane = new AliEventplane();
2250     return  fEventplane;
2251 }
2252
2253 //______________________________________________________________________________
2254 Float_t AliESDEvent::GetVZEROEqMultiplicity(Int_t i) const
2255 {
2256   // Get VZERO Multiplicity for channel i
2257   // Themethod uses the equalization factors
2258   // stored in the ESD-run object in order to
2259   // get equal multiplicities within a VZERO rins (1/8 of VZERO)
2260   if (!fESDVZERO || !fESDRun) return -1;
2261
2262   Int_t ring = i/8;
2263   Float_t factorSum = 0;
2264   for(Int_t j = 8*ring; j < (8*ring+8); ++j) {
2265     factorSum += fESDRun->GetVZEROEqFactors(j);
2266   }
2267   Float_t factor = fESDRun->GetVZEROEqFactors(i)*8./factorSum;
2268
2269   return (fESDVZERO->GetMultiplicity(i)/factor);
2270 }
2271
2272 //______________________________________________________________________________
2273 void AliESDEvent::SetTOFcluster(Int_t ntofclusters,AliESDTOFCluster *cluster,Int_t *mapping)
2274 {
2275   // Reset TClonesArray of TOF clusters
2276   if (!fESDTOFClusters) {
2277     AliError("fESDTOFClusters is not initialized");
2278     return;
2279   }
2280   fESDTOFClusters->Clear();
2281   
2282   Int_t goodhit[20000];
2283   if(mapping){
2284     for(Int_t i=0;i < 20000;i++){
2285       goodhit[i] = 0;
2286     }
2287   }
2288
2289   for(Int_t i=0;i < ntofclusters;i++){
2290     
2291     if(cluster[i].GetNMatchableTracks() || !mapping){
2292       if(mapping)
2293         mapping[i] = fESDTOFClusters->GetEntriesFast();
2294       
2295       // update TClonesArray
2296       TClonesArray &ftr = *fESDTOFClusters;
2297       AliESDTOFCluster *clusterTBW = new(ftr[fESDTOFClusters->GetEntriesFast()])AliESDTOFCluster(cluster[i]);
2298
2299       if(mapping){
2300         // loop over hit in the cluster
2301         for(Int_t k=0;k < clusterTBW->GetNTOFhits();k++){
2302           Int_t ipos = clusterTBW->GetHitIndex(k);
2303           goodhit[ipos] = 1; // hit should be kept
2304         }
2305       }
2306     }
2307   }
2308
2309   if(mapping){
2310     AliInfo(Form("TOF cluster before of matching = %i , after = %i\n",ntofclusters,fESDTOFClusters->GetEntriesFast()));
2311     Int_t hitnewpos[20000]={0};
2312     Int_t nhitOriginal = fESDTOFHits->GetEntries();
2313     for(Int_t i=0;i < fESDTOFHits->GetEntries();i++){
2314       if(goodhit[i]){
2315         hitnewpos[i] = i;
2316       }
2317       else{ // remove hit and decrease the hit array
2318         TClonesArray &a=*fESDTOFHits;
2319         Int_t lastpos = fESDTOFHits->GetEntries()-1;
2320
2321         if(i == lastpos)
2322           delete a.RemoveAt(i);
2323         else{
2324           Int_t nhitBefore = fESDTOFHits->GetEntries();
2325           for(Int_t k=nhitBefore-1;k>i;k--){ // find the last good track
2326             if(!goodhit[k]){ // remove track
2327               delete a.RemoveAt(k);
2328               if(k-i==1) delete a.RemoveAt(i);
2329             }
2330             else{ // replace last one to the "i"
2331               AliESDTOFHit *last = (AliESDTOFHit *) fESDTOFHits->At(k);
2332               delete a.RemoveAt(i);
2333               new (a[i]) AliESDTOFHit(*last);
2334               delete a.RemoveAt(k);
2335               hitnewpos[k] = i;
2336               k = 0;
2337             }
2338           }
2339         }
2340       }
2341     }
2342
2343     // remap cluster to hits
2344     for(Int_t i=0;i < fESDTOFClusters->GetEntries();i++){
2345       AliESDTOFCluster *cl = (AliESDTOFCluster *) fESDTOFClusters->At(i);
2346       // loop over hit in the cluster
2347       for(Int_t k=0;k < cl->GetNTOFhits();k++){
2348         cl->SetHitIndex(k,hitnewpos[cl->GetHitIndex(k)]);
2349       }
2350     }
2351     AliInfo(Form("TOF hit before of matching = %i , after = %i\n",nhitOriginal,fESDTOFHits->GetEntriesFast()));
2352   } // end mapping
2353
2354 }
2355
2356 //______________________________________________________________________________
2357 void AliESDEvent::SetTOFcluster(Int_t ntofclusters,AliESDTOFCluster *cluster[],Int_t *mapping)
2358 {    
2359   // Reset TClonesArray of TOF clusters
2360   if(fESDTOFClusters)fESDTOFClusters->Delete();
2361    
2362   Int_t goodhit[20000];
2363   if(mapping){
2364     for(Int_t i=0;i < 20000;i++){
2365       goodhit[i] = 0;
2366     }
2367   }
2368       
2369   for(Int_t i=0;i < ntofclusters;i++){
2370
2371     if(cluster[i]->GetNMatchableTracks() || !mapping){
2372       if(mapping)
2373         mapping[i] = fESDTOFClusters->GetEntriesFast();
2374         
2375       // update TClonesArray
2376       TClonesArray &ftr = *fESDTOFClusters;
2377       AliESDTOFCluster *clusterTBW = new(ftr[fESDTOFClusters->GetEntriesFast()])AliESDTOFCluster(*(cluster[i]));
2378
2379       if(mapping){
2380         // loop over hit in the cluster
2381         for(Int_t k=0;k < clusterTBW->GetNTOFhits();k++){
2382           Int_t ipos = clusterTBW->GetHitIndex(k);
2383           goodhit[ipos] = 1; // hit should be kept
2384         }
2385       }
2386     }
2387   }
2388
2389   if(mapping){
2390     AliInfo(Form("TOF cluster before of matching = %i , after = %i\n",ntofclusters,fESDTOFClusters->GetEntriesFast()));
2391     Int_t hitnewpos[20000]={0};
2392     Int_t nhitOriginal = fESDTOFHits->GetEntries();
2393     for(Int_t i=0;i < fESDTOFHits->GetEntries();i++){
2394       if(goodhit[i]){
2395         hitnewpos[i] = i;
2396       }
2397       else{ // remove hit and decrease the hit array
2398         TClonesArray &a=*fESDTOFHits;
2399         Int_t lastpos = fESDTOFHits->GetEntries()-1;
2400
2401         if(i == lastpos)
2402           delete a.RemoveAt(i);
2403         else{
2404           Int_t nhitBefore = fESDTOFHits->GetEntries();
2405           for(Int_t k=nhitBefore-1;k>i;k--){ // find the last good track
2406             if(!goodhit[k]){ // remove track
2407               delete a.RemoveAt(k);
2408               if(k-i==1) delete a.RemoveAt(i);
2409             }
2410             else{ // replace last one to the "i"
2411               AliESDTOFHit *last = (AliESDTOFHit *) fESDTOFHits->At(k);
2412               delete a.RemoveAt(i);
2413               new (a[i]) AliESDTOFHit(*last);
2414               delete a.RemoveAt(k);
2415               hitnewpos[k] = i;
2416               k = 0;
2417             }
2418           }
2419         }
2420       }
2421     }
2422
2423     // remap cluster to hits
2424     for(Int_t i=0;i < fESDTOFClusters->GetEntries();i++){
2425       AliESDTOFCluster *cl = (AliESDTOFCluster *) fESDTOFClusters->At(i);
2426       // loop over hit in the cluster
2427       for(Int_t k=0;k < cl->GetNTOFhits();k++){
2428         cl->SetHitIndex(k,hitnewpos[cl->GetHitIndex(k)]);
2429       }
2430     }
2431     AliInfo(Form("TOF hit before of matching = %i , after = %i\n",nhitOriginal,fESDTOFHits->GetEntriesFast()));
2432   } // end mapping
2433
2434 }
2435
2436 //______________________________________________________________________________
2437 void AliESDEvent::ConnectTracks() {
2438 // Connect tracks to this event
2439   if (fTracksConnected || !fTracks || !fTracks->GetEntriesFast()) return;
2440   AliESDtrack *track;
2441   TIter next(fTracks);
2442   while ((track=(AliESDtrack*)next())) track->SetESDEvent(this);
2443   //
2444   // The same for TOF clusters
2445   if (fESDTOFClusters) {
2446     AliESDTOFCluster *clus;
2447     TIter nextTOF(fESDTOFClusters);
2448     while ((clus=(AliESDTOFCluster*)nextTOF())) clus->SetEvent((AliVEvent *) this);
2449   }
2450   fTracksConnected = kTRUE;
2451   //
2452 }