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