]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AOD/AliAODEvent.cxx
Fixed leak in AliAODEvent::ResetStd
[u/mrichter/AliRoot.git] / STEER / AOD / AliAODEvent.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 //-------------------------------------------------------------------------
19 //     AOD base class
20 //     Author: Markus Oldenburg, CERN
21 //-------------------------------------------------------------------------
22
23 #include <TROOT.h>
24 #include <TTree.h>
25 #include <TFolder.h>
26 #include <TFriendElement.h>
27 #include <TProcessID.h>
28 #include <TCollection.h>
29 #include "Riostream.h"
30 #include "AliAODEvent.h"
31 #include "AliAODHeader.h"
32 #include "AliAODTrack.h"
33 #include "AliAODDimuon.h"
34 #include "AliAODTrdTrack.h"
35
36 ClassImp(AliAODEvent)
37
38 // definition of std AOD member names
39   const char* AliAODEvent::fAODListName[kAODListN] = {"header",
40                                                       "tracks",
41                                                       "vertices",
42                                                       "v0s",
43                                                       "cascades",
44                                                       "tracklets",
45                                                       "jets",
46                                                       "emcalCells",
47                                                       "phosCells",
48                                                                         "caloClusters",
49                                                                         "emcalTrigger",
50                                                                         "phosTrigger",
51                                                       "fmdClusters",
52                                                       "pmdClusters",
53                                                       "hmpidRings",
54                                                       "dimuons",
55                                                       "AliAODTZERO",
56                                                       "AliAODVZERO",
57                                                       "AliAODZDC",
58                                                       "AliTOFHeader",
59                                                       "trdTracks"
60                                                                               
61 };
62 //______________________________________________________________________________
63 AliAODEvent::AliAODEvent() :
64   AliVEvent(),
65   fAODObjects(0),
66   fAODFolder(0),
67   fConnected(kFALSE),
68   fTracksConnected(kFALSE),
69   fHeader(0),
70   fTracks(0),
71   fVertices(0),
72   fV0s(0),
73   fCascades(0),
74   fTracklets(0),
75   fJets(0),
76   fEmcalCells(0),
77   fPhosCells(0),
78   fCaloClusters(0),
79   fEMCALTrigger(0),
80   fPHOSTrigger(0),
81   fFmdClusters(0),
82   fPmdClusters(0),
83   fHMPIDrings(0),
84   fDimuons(0),
85   fAODTZERO(0),
86   fAODVZERO(0),
87   fAODZDC(0),
88   fTOFHeader(0),
89   fTrdTracks(0)
90 {
91   // default constructor
92   if (TClass::IsCallingNew() != TClass::kDummyNew) fAODObjects = new TList();
93 }
94
95 //______________________________________________________________________________
96 AliAODEvent::AliAODEvent(const AliAODEvent& aod):
97   AliVEvent(aod),
98   fAODObjects(new TList()),
99   fAODFolder(0),
100   fConnected(kFALSE),
101   fTracksConnected(kFALSE),
102   fHeader(new AliAODHeader(*aod.fHeader)),
103   fTracks(new TClonesArray(*aod.fTracks)),
104   fVertices(new TClonesArray(*aod.fVertices)),
105   fV0s(new TClonesArray(*aod.fV0s)),
106   fCascades(new TClonesArray(*aod.fCascades)),
107   fTracklets(new AliAODTracklets(*aod.fTracklets)),
108   fJets(new TClonesArray(*aod.fJets)),
109   fEmcalCells(new AliAODCaloCells(*aod.fEmcalCells)),
110   fPhosCells(new AliAODCaloCells(*aod.fPhosCells)),
111   fCaloClusters(new TClonesArray(*aod.fCaloClusters)),
112   fEMCALTrigger(new AliAODCaloTrigger(*aod.fEMCALTrigger)),
113   fPHOSTrigger(new AliAODCaloTrigger(*aod.fPHOSTrigger)),
114   fFmdClusters(new TClonesArray(*aod.fFmdClusters)),
115   fPmdClusters(new TClonesArray(*aod.fPmdClusters)),
116   fHMPIDrings(new TClonesArray(*aod.fHMPIDrings)),
117   fDimuons(new TClonesArray(*aod.fDimuons)),
118   fAODTZERO(new AliAODTZERO(*aod.fAODTZERO)),
119   fAODVZERO(new AliAODVZERO(*aod.fAODVZERO)),
120   fAODZDC(new AliAODZDC(*aod.fAODZDC)),
121   fTOFHeader(new AliTOFHeader(*aod.fTOFHeader)),
122   fTrdTracks(new TClonesArray(*aod.fTrdTracks))
123 {
124   // Copy constructor
125   AddObject(fHeader);
126   AddObject(fTracks);
127   AddObject(fVertices);
128   AddObject(fV0s);
129   AddObject(fCascades);
130   AddObject(fTracklets);
131   AddObject(fJets);
132   AddObject(fEmcalCells);
133   AddObject(fPhosCells);
134   AddObject(fCaloClusters);
135   AddObject(fEMCALTrigger);
136   AddObject(fPHOSTrigger);
137   AddObject(fFmdClusters);
138   AddObject(fPmdClusters);
139   AddObject(fHMPIDrings);
140   AddObject(fDimuons);
141   AddObject(fAODTZERO);
142   AddObject(fAODVZERO);
143   AddObject(fAODZDC);
144   AddObject(fTOFHeader);
145   AddObject(fTrdTracks);
146   fConnected = aod.fConnected;
147   ConnectTracks();
148   GetStdContent();
149   CreateStdFolders();
150 }
151
152 //______________________________________________________________________________
153 AliAODEvent & AliAODEvent::operator=(const AliAODEvent& aod) {
154
155     // Assignment operator
156
157   if(&aod == this) return *this;
158   AliVEvent::operator=(aod);
159
160   // This assumes that the list is already created
161   // and that the virtual void Copy(Tobject&) function
162   // is correctly implemented in the derived class
163   // otherwise only TObject::Copy() will be used
164
165   if((fAODObjects->GetSize()==0)&&(aod.fAODObjects->GetSize()>=kAODListN)){
166     // We cover the case that we do not yet have the 
167     // standard content but the source has it
168     CreateStdContent();
169   }
170   
171   // Here we have the standard content without user additions, but the content is 
172   // not matching the aod source.
173   
174   // Iterate the list of source objects
175   TIter next(aod.GetList());
176   TObject *its = 0;
177   TString name;
178   while ((its = next())) {
179     name = its->GetName();
180     // Check if we have this object type in out list
181     TObject *mine = fAODObjects->FindObject(name);    
182     if(!mine) {
183       // We have to create the same type of object.
184       TClass* pClass=TClass::GetClass(its->ClassName());     
185       if (!pClass) {
186         AliWarning(Form("Can not find class description for entry %s (%s)\n",
187                    its->ClassName(), name.Data()));
188         continue;
189       }
190       mine=(TObject*)pClass->New();
191       if(!mine){
192         // not in this: can be added to list
193         AliWarning(Form("%s:%d Could not find %s for copying \n",
194                    (char*)__FILE__,__LINE__,name.Data()));
195         continue;
196       }  
197       if(mine->InheritsFrom("TNamed"))  {
198         ((TNamed*)mine)->SetName(name);
199       } else if(mine->InheritsFrom("TCollection")){
200         if(mine->InheritsFrom("TClonesArray")) {
201           TClonesArray *itscl = dynamic_cast<TClonesArray*>(its);
202           if (!itscl) {
203             AliWarning(Form("Class description for entry %s (%s) not TClonesArray\n",
204                    its->ClassName(), name.Data()));
205             continue;
206           
207           }
208                dynamic_cast<TClonesArray*>(mine)->SetClass(itscl->GetClass(), itscl->GetSize());
209         }
210         dynamic_cast<TCollection*>(mine)->SetName(name);
211       }
212       AliDebug(1, Form("adding object %s of type %s", mine->GetName(), mine->ClassName()));
213       AddObject(mine);
214     }
215     // Now we have an object of the same type and name, but different content.        
216     if(!its->InheritsFrom("TCollection")){
217       // simple objects (do they have a Copy method that calls operator= ?)
218       its->Copy(*mine);
219     } else if (its->InheritsFrom("TClonesArray")) {
220       // Create or expand the tclonesarray pointers
221       // so we can directly copy to the object
222       TClonesArray *its_tca = (TClonesArray*)its;
223       TClonesArray *mine_tca = (TClonesArray*)mine;
224       // this leaves the capacity of the TClonesArray the same
225       // except for a factor of 2 increase when size > capacity
226       // does not release any memory occupied by the tca
227       Int_t its_entries = its_tca->GetEntriesFast();
228       mine_tca->ExpandCreate(its_entries);
229       for(int i=0; i<its_entries; i++){
230         // copy 
231         TObject *mine_tca_obj = mine_tca->At(i);
232         TObject *its_tca_obj = its_tca->At(i);
233         // no need to delete first
234         // pointers within the class should be handled by Copy()...
235         // Can there be Empty slots?
236         its_tca_obj->Copy(*mine_tca_obj);
237       }
238     } else {
239       AliWarning(Form("%s:%d cannot copy TCollection \n",
240                       (char*)__FILE__,__LINE__));
241     }
242   }  
243   fConnected = aod.fConnected;
244   fTracksConnected = kFALSE;
245   ConnectTracks();
246   return *this;
247 }
248
249
250 //______________________________________________________________________________
251 AliAODEvent::~AliAODEvent() 
252 {
253 // destructor
254     delete fAODFolder;
255     fAODFolder = 0;
256     if(!fConnected) {
257 //       fAODObjects->Delete("slow");
258        delete fAODObjects;
259     }   
260 }
261
262 //______________________________________________________________________________
263 void AliAODEvent::AddObject(TObject* obj) 
264 {
265   // Add an object to the list of objects.
266   // Please be aware that in order to increase performance you should
267   // refrain from using TObjArrays (if possible). Use TClonesArrays, instead.
268   
269 //  if ( !fAODObjects ) {
270 //     fAODObjects = new TList();
271 //     fAODObjects->SetOwner();
272 //  }
273   if ( !fAODObjects->FindObject(obj) ) 
274   {
275     fAODObjects->AddLast(obj);
276   }
277 }
278
279 //______________________________________________________________________________
280 Int_t AliAODEvent::AddTrack(const AliAODTrack* trk)
281 {
282 // Add new AOD track. Make sure to set the event if needed.
283   AliAODTrack *track =  new((*fTracks)[fTracks->GetEntriesFast()]) AliAODTrack(*trk);
284   track->SetAODEvent(this);
285   return fTracks->GetEntriesFast()-1;
286 }  
287
288 //______________________________________________________________________________
289 void AliAODEvent::RemoveObject(TObject* obj) 
290 {
291   // Removes an object from the list of objects.
292   
293   fAODObjects->Remove(obj);
294 }
295
296 //______________________________________________________________________________
297 TObject *AliAODEvent::FindListObject(const char *objName) const
298 {
299   // Return the pointer to the object with the given name.
300
301   return fAODObjects->FindObject(objName);
302 }
303
304 //______________________________________________________________________________
305 void AliAODEvent::CreateStdContent() 
306 {
307   // create the standard AOD content and set pointers
308
309   // create standard objects and add them to the TList of objects
310   AddObject(new AliAODHeader());
311   AddObject(new TClonesArray("AliAODTrack", 0));
312   AddObject(new TClonesArray("AliAODVertex", 0));
313   AddObject(new TClonesArray("AliAODv0", 0));
314   AddObject(new TClonesArray("AliAODcascade", 0));
315   AddObject(new AliAODTracklets());
316   AddObject(new TClonesArray("AliAODJet", 0));
317   AddObject(new AliAODCaloCells());
318   AddObject(new AliAODCaloCells());
319   AddObject(new TClonesArray("AliAODCaloCluster", 0));
320   AddObject(new AliAODCaloTrigger()); // EMCAL 
321   AddObject(new AliAODCaloTrigger()); // PHOS
322   AddObject(new TClonesArray("AliAODFmdCluster", 0));
323   AddObject(new TClonesArray("AliAODPmdCluster", 0));
324   AddObject(new TClonesArray("AliAODHMPIDrings", 0));
325   AddObject(new TClonesArray("AliAODDimuon", 0));
326   AddObject(new AliAODTZERO());
327   AddObject(new AliAODVZERO());
328   AddObject(new AliAODZDC());
329   AddObject(new AliTOFHeader());
330   AddObject(new TClonesArray("AliAODTrdTrack", 0));
331   // set names
332   SetStdNames();
333
334   // read back pointers
335   GetStdContent();
336   CreateStdFolders();
337   return;
338 }
339
340 void  AliAODEvent::MakeEntriesReferencable()
341 {
342     // Make all entries referencable in a subsequent process
343     //
344     TIter next(fAODObjects);
345     TObject* obj;
346     while ((obj = next()))
347     {
348         if(obj->InheritsFrom("TCollection"))
349             {
350                 AssignIDtoCollection((TCollection*)obj);
351             }
352     }
353 }
354
355 //______________________________________________________________________________
356 void AliAODEvent::SetStdNames()
357 {
358   // introduce the standard naming
359
360   if(fAODObjects->GetEntries()==kAODListN){
361     for(int i = 0;i < fAODObjects->GetEntries();i++){
362       TObject *fObj = fAODObjects->At(i);
363       if(fObj->InheritsFrom("TNamed")){
364         ((TNamed*)fObj)->SetName(fAODListName[i]);
365       }
366       else if(fObj->InheritsFrom("TClonesArray")){
367         ((TClonesArray*)fObj)->SetName(fAODListName[i]);
368       }
369     }
370   }
371   else{
372     printf("%s:%d SetStdNames() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__);
373   }
374
375
376 //______________________________________________________________________________
377 void AliAODEvent::CreateStdFolders()
378 {
379     // Create the standard folder structure
380   if(fAODFolder)delete fAODFolder;
381     fAODFolder = gROOT->GetRootFolder()->AddFolder("AOD", "AOD");
382     if(fAODObjects->GetEntries()==kAODListN){
383         for(int i = 0;i < fAODObjects->GetEntries();i++){
384             TObject *fObj = fAODObjects->At(i);
385             if(fObj->InheritsFrom("TClonesArray")){
386                 fAODFolder->AddFolder(fAODListName[i], fAODListName[i], (TCollection*) fObj);
387             } else {
388                 fAODFolder->AddFolder(fAODListName[i], fAODListName[i], 0);
389             }
390         }
391     }
392     else{
393         printf("%s:%d CreateStdFolders() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__);
394     }
395
396
397 //______________________________________________________________________________
398 void AliAODEvent::GetStdContent()
399 {
400   // set pointers for standard content
401
402   fHeader        = (AliAODHeader*)fAODObjects->FindObject("header");
403   fTracks        = (TClonesArray*)fAODObjects->FindObject("tracks");
404   fVertices      = (TClonesArray*)fAODObjects->FindObject("vertices");
405   fV0s           = (TClonesArray*)fAODObjects->FindObject("v0s");
406   fCascades      = (TClonesArray*)fAODObjects->FindObject("cascades");
407   fTracklets     = (AliAODTracklets*)fAODObjects->FindObject("tracklets");
408   fJets          = (TClonesArray*)fAODObjects->FindObject("jets");
409   fEmcalCells    = (AliAODCaloCells*)fAODObjects->FindObject("emcalCells");
410   fPhosCells     = (AliAODCaloCells*)fAODObjects->FindObject("phosCells");
411   fCaloClusters  = (TClonesArray*)fAODObjects->FindObject("caloClusters");
412   fEMCALTrigger  = (AliAODCaloTrigger*)fAODObjects->FindObject("emcalTrigger");
413   fPHOSTrigger   = (AliAODCaloTrigger*)fAODObjects->FindObject("phosTrigger");
414   fFmdClusters   = (TClonesArray*)fAODObjects->FindObject("fmdClusters");
415   fPmdClusters   = (TClonesArray*)fAODObjects->FindObject("pmdClusters");
416   fHMPIDrings    = (TClonesArray*)fAODObjects->FindObject("hmpidRings");  
417   fDimuons       = (TClonesArray*)fAODObjects->FindObject("dimuons");
418   fAODTZERO      = (AliAODTZERO*)fAODObjects->FindObject("AliAODTZERO");
419   fAODVZERO      = (AliAODVZERO*)fAODObjects->FindObject("AliAODVZERO");
420   fAODZDC        = (AliAODZDC*)fAODObjects->FindObject("AliAODZDC");
421   fTOFHeader     = (AliTOFHeader*)fAODObjects->FindObject("AliTOFHeader");
422   fTrdTracks     = (TClonesArray*)fAODObjects->FindObject("trdTracks");
423 }
424
425 //______________________________________________________________________________
426 void AliAODEvent::ResetStd(Int_t trkArrSize, 
427             Int_t vtxArrSize, 
428             Int_t v0ArrSize,
429             Int_t cascadeArrSize,
430             Int_t jetSize, 
431             Int_t caloClusSize, 
432             Int_t fmdClusSize, 
433             Int_t pmdClusSize,
434             Int_t hmpidRingsSize,
435             Int_t dimuonArrSize,
436             Int_t nTrdTracks
437                            )
438 {
439   // deletes content of standard arrays and resets size 
440   fTracksConnected = kFALSE;
441   if (fTracks) {
442     fTracks->Delete();
443     if (trkArrSize > fTracks->GetSize()) 
444       fTracks->Expand(trkArrSize);
445   }
446   if (fVertices) {
447     fVertices->Delete();
448     if (vtxArrSize > fVertices->GetSize()) 
449       fVertices->Expand(vtxArrSize);
450   }
451   if (fV0s) {
452     fV0s->Delete();
453     if (v0ArrSize > fV0s->GetSize()) 
454       fV0s->Expand(v0ArrSize);
455   }
456   if (fCascades) {
457     fCascades->Delete();
458     if (cascadeArrSize > fCascades->GetSize()) 
459       fCascades->Expand(cascadeArrSize);
460   }
461   if (fJets) {
462     fJets->Delete();
463     if (jetSize > fJets->GetSize())
464       fJets->Expand(jetSize);
465   }
466   if (fCaloClusters) {
467     fCaloClusters->Delete();
468     if (caloClusSize > fCaloClusters->GetSize()) 
469       fCaloClusters->Expand(caloClusSize);
470   }
471   if (fFmdClusters) {
472     fFmdClusters->Delete();
473     if (fmdClusSize > fFmdClusters->GetSize()) 
474       fFmdClusters->Expand(fmdClusSize);
475   }
476   if (fPmdClusters) {
477     fPmdClusters->Delete();
478     if (pmdClusSize > fPmdClusters->GetSize()) 
479       fPmdClusters->Expand(pmdClusSize);
480   }
481   if (fHMPIDrings) {
482      fHMPIDrings->Delete();
483     if (hmpidRingsSize > fHMPIDrings->GetSize()) 
484       fHMPIDrings->Expand(hmpidRingsSize);
485   }
486   if (fDimuons) {
487     fDimuons->Delete();
488     if (dimuonArrSize > fDimuons->GetSize()) 
489       fDimuons->Expand(dimuonArrSize);
490   }
491   if (fTrdTracks) {
492     // no pointers in there, so cheaper Clear suffices
493 //    fTrdTracks->Clear("C");
494     // Not quite: AliAODTrdTrack has a clones array of tracklets inside
495     fTrdTracks->Delete();
496     if (nTrdTracks > fTrdTracks->GetSize())
497       fTrdTracks->Expand(nTrdTracks);
498   }
499
500   if (fTracklets)
501     fTracklets->DeleteContainer();
502   if (fPhosCells)
503     fPhosCells->DeleteContainer();  
504   if (fEmcalCells)
505     fEmcalCells->DeleteContainer();
506   
507   if (fEMCALTrigger)
508         fEMCALTrigger->DeAllocate();
509   if (fPHOSTrigger)
510         fPHOSTrigger->DeAllocate();
511
512 }
513
514 //______________________________________________________________________________
515 void AliAODEvent::ClearStd()
516 {
517   // clears the standard arrays
518   if (fHeader){
519     // FIXME: this if-else patch was introduced by Michele Floris on 17/03/14 to test nano AOD. To be removed.
520     if(fHeader->InheritsFrom("AliAODHeader")){
521       fHeader        ->Clear();
522     }
523     else {
524       AliVHeader * head = 0;
525       head = dynamic_cast<AliVHeader*>((TObject*)fHeader);
526       if(head) head->Clear();
527     }
528   }
529   fTracksConnected = kFALSE;
530   if (fTracks)
531     fTracks        ->Delete();
532   if (fVertices)
533     fVertices      ->Delete();
534   if (fV0s)
535     fV0s           ->Delete();
536   if (fCascades)
537     fCascades      ->Delete();
538   if (fTracklets)
539     fTracklets     ->DeleteContainer();
540   if (fJets)
541     fJets          ->Delete();
542   if (fEmcalCells)
543     fEmcalCells    ->DeleteContainer();
544   if (fPhosCells)
545     fPhosCells     ->DeleteContainer();
546   if (fCaloClusters)
547     fCaloClusters  ->Delete();
548   if (fFmdClusters)
549     fFmdClusters   ->Clear();
550   if (fPmdClusters)
551     fPmdClusters   ->Clear();  
552   if (fHMPIDrings) 
553      fHMPIDrings   ->Clear();    
554   if (fDimuons)
555     fDimuons       ->Clear();
556   if (fTrdTracks)
557     fTrdTracks     ->Clear();
558         
559   if (fEMCALTrigger)
560         fEMCALTrigger->DeAllocate();
561   if (fPHOSTrigger)
562         fPHOSTrigger->DeAllocate();
563 }
564
565 //_________________________________________________________________
566 Int_t AliAODEvent::GetPHOSClusters(TRefArray *clusters) const
567 {
568   // fills the provided TRefArray with all found phos clusters
569   
570   clusters->Clear();
571   
572   AliAODCaloCluster *cl = 0;
573   Bool_t first = kTRUE;
574   for (Int_t i = 0; i < GetNumberOfCaloClusters() ; i++) {
575     if ( (cl = GetCaloCluster(i)) ) {
576       if (cl->IsPHOS()){
577         if(first) {
578           new (clusters) TRefArray(TProcessID::GetProcessWithUID(cl)); 
579           first=kFALSE;
580         }
581         clusters->Add(cl);
582         //printf("IsPHOS cluster %d, E %2.3f Size: %d \n",i,cl->E(),clusters->GetEntriesFast());
583       }
584     }
585   }
586   return clusters->GetEntriesFast();
587 }
588
589 //_________________________________________________________________
590 Int_t AliAODEvent::GetEMCALClusters(TRefArray *clusters) const
591 {
592   // fills the provided TRefArray with all found emcal clusters
593
594   clusters->Clear();
595   AliAODCaloCluster *cl = 0;
596   Bool_t first = kTRUE;
597   for (Int_t i = 0; i < GetNumberOfCaloClusters(); i++) {
598     if ( (cl = GetCaloCluster(i)) ) {
599       if (cl->IsEMCAL()){
600         if(first) {
601           new (clusters) TRefArray(TProcessID::GetProcessWithUID(cl)); 
602           first=kFALSE;
603         }
604         clusters->Add(cl);
605         //printf("IsEMCal cluster %d, E %2.3f Size: %d \n",i,cl->E(),clusters->GetEntriesFast());
606       }
607     }
608   }
609   return clusters->GetEntriesFast();
610 }
611
612
613 //______________________________________________________________________________
614 Int_t AliAODEvent::GetMuonTracks(TRefArray *muonTracks) const
615 {
616   // fills the provided TRefArray with all found muon tracks
617
618   muonTracks->Clear();
619
620   AliAODTrack *track = 0;
621   for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
622     track = GetTrack(iTrack);
623     if (track->IsMuonTrack()) {
624       muonTracks->Add(track);
625     }
626   }
627   
628   return muonTracks->GetEntriesFast();
629 }
630
631
632 //______________________________________________________________________________
633 Int_t AliAODEvent::GetNumberOfMuonTracks() const
634 {
635   // get number of muon tracks
636   Int_t nMuonTracks=0;
637   for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
638     if ((GetTrack(iTrack))->IsMuonTrack()) {
639        nMuonTracks++;
640     }
641   }
642   
643   return nMuonTracks;
644 }
645
646 //______________________________________________________________________________
647 Int_t AliAODEvent::GetMuonGlobalTracks(TRefArray *muonGlobalTracks) const           // AU
648 {
649   // fills the provided TRefArray with all found muon global tracks
650
651   muonGlobalTracks->Clear();
652
653   AliAODTrack *track = 0;
654   for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
655     track = GetTrack(iTrack);
656     if (track->IsMuonGlobalTrack()) {
657       muonGlobalTracks->Add(track);
658     }
659   }
660   
661   return muonGlobalTracks->GetEntriesFast();
662 }
663
664
665 //______________________________________________________________________________
666 Int_t AliAODEvent::GetNumberOfMuonGlobalTracks() const                                    // AU
667 {
668   // get number of muon global tracks
669   Int_t nMuonGlobalTracks=0;
670   for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
671     if ((GetTrack(iTrack))->IsMuonGlobalTrack()) {
672        nMuonGlobalTracks++;
673     }
674   }
675   
676   return nMuonGlobalTracks;
677 }
678
679 //______________________________________________________________________________
680 void AliAODEvent::ReadFromTree(TTree *tree, Option_t* opt /*= ""*/)
681 {
682     // Connects aod event to tree
683   
684   if(!tree){
685     AliWarning("Zero Pointer to Tree \n");
686     return;
687   }
688     // load the TTree
689   if(!tree->GetTree())tree->LoadTree(0);
690   
691     // Try to find AliAODEvent
692   AliAODEvent *aodEvent = 0;
693   aodEvent = (AliAODEvent*)tree->GetTree()->GetUserInfo()->FindObject("AliAODEvent");
694   if(aodEvent){
695     // This event is connected to the tree by definition, just say so
696     aodEvent->SetConnected();
697       // Check if already connected to tree
698     TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("AODObjectsConnectedToTree"));
699     if (connectedList && (!strcmp(opt, "reconnect"))) {
700         // If connected use the connected list of objects
701         if (fAODObjects != connectedList) {
702            delete fAODObjects;
703            fAODObjects = connectedList;
704         }   
705         GetStdContent(); 
706         fConnected = kTRUE;
707         return;
708     } 
709       // Connect to tree
710       // prevent a memory leak when reading back the TList
711 //      if (!(strcmp(opt, "reconnect"))) fAODObjects->Delete();
712     
713       // create a new TList from the UserInfo TList... 
714       // copy constructor does not work...
715     //    fAODObjects = (TList*)(aodEvent->GetList()->Clone());
716     fAODObjects = (TList*)aodEvent->GetList();
717     fAODObjects->SetOwner(kTRUE);
718     if(fAODObjects->GetEntries()<kAODListN)
719     {
720       AliWarning(Form("AliAODEvent::ReadFromTree() TList contains less than the standard contents %d < %d"
721                       " That might be fine though (at least for filtered AODs)",fAODObjects->GetEntries(),kAODListN));
722     }
723       //
724       // Let's find out whether we have friends
725     TList* friendL = tree->GetTree()->GetListOfFriends();
726     if (friendL) 
727     {
728       TIter next(friendL);
729       TFriendElement* fe;
730       while ((fe = (TFriendElement*)next())){
731         aodEvent = (AliAODEvent*)(fe->GetTree()->GetUserInfo()->FindObject("AliAODEvent"));
732         if (!aodEvent) {
733           printf("No UserInfo on tree \n");
734         } else {
735           
736           //          TList* objL = (TList*)(aodEvent->GetList()->Clone());
737           TList* objL = (TList*)aodEvent->GetList();
738           printf("Get list of object from tree %d !!\n", objL->GetEntries());
739           TIter nextobject(objL);
740           TObject* obj =  0;
741           while((obj = nextobject()))
742           {
743             printf("Adding object from friend %s !\n", obj->GetName());
744             fAODObjects->Add(obj);
745           } // object "branch" loop
746         } // has userinfo  
747       } // friend loop
748     } // has friends    
749       // set the branch addresses
750     TIter next(fAODObjects);
751     TNamed *el;
752     while((el=(TNamed*)next())){
753       TString bname(el->GetName());
754         // check if branch exists under this Name
755       TBranch *br = tree->GetTree()->GetBranch(bname.Data());
756       if(br){
757         tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
758       } else {
759         br = tree->GetBranch(Form("%s.",bname.Data()));
760         if(br){
761           tree->SetBranchAddress(Form("%s.",bname.Data()),fAODObjects->GetObjectRef(el));
762         }
763         else{
764           printf("%s %d AliAODEvent::ReadFromTree() No Branch found with Name %s. \n",
765                  (char*)__FILE__,__LINE__,bname.Data());
766         }       
767       }
768     }
769     GetStdContent();
770       // when reading back we are not owner of the list 
771       // must not delete it
772     fAODObjects->SetOwner(kTRUE);
773     fAODObjects->SetName("AODObjectsConnectedToTree");
774       // we are not owner of the list objects 
775       // must not delete it
776     tree->GetUserInfo()->Add(fAODObjects);
777     fConnected = kTRUE;
778   }// no aodEvent
779   else {
780       // we can't get the list from the user data, create standard content
781       // and set it by hand
782     CreateStdContent();
783     TIter next(fAODObjects);
784     TNamed *el;
785     while((el=(TNamed*)next())){
786       TString bname(el->GetName());    
787       tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
788     }
789     GetStdContent();
790       // when reading back we are not owner of the list 
791       // must not delete it
792     fAODObjects->SetOwner(kTRUE);
793   }
794 }
795   //______________________________________________________________________________
796 Int_t  AliAODEvent::GetNumberOfPileupVerticesSPD() const{
797   // count number of SPD pileup vertices
798   Int_t nVertices=GetNumberOfVertices();
799   Int_t nPileupVertices=0;
800   for(Int_t iVert=0; iVert<nVertices; iVert++){
801     AliAODVertex *v=GetVertex(iVert);
802     if(v->GetType()==AliAODVertex::kPileupSPD) nPileupVertices++;
803   }
804   return nPileupVertices;
805 }
806 //______________________________________________________________________________
807 Int_t  AliAODEvent::GetNumberOfPileupVerticesTracks() const{
808   // count number of track pileup vertices
809   Int_t nVertices=GetNumberOfVertices();
810   Int_t nPileupVertices=0;
811   for(Int_t iVert=0; iVert<nVertices; iVert++){
812     AliAODVertex *v=GetVertex(iVert);
813     if(v->GetType()==AliAODVertex::kPileupTracks) nPileupVertices++;
814   }
815   return nPileupVertices;
816 }
817 //______________________________________________________________________________
818 AliAODVertex* AliAODEvent::GetPrimaryVertexSPD() const{
819   // Get SPD primary vertex
820   Int_t nVertices=GetNumberOfVertices();
821   for(Int_t iVert=0; iVert<nVertices; iVert++){
822     AliAODVertex *v=GetVertex(iVert);
823     if(v->GetType()==AliAODVertex::kMainSPD) return v;
824   }
825   return 0;
826 }
827 //______________________________________________________________________________
828 AliAODVertex* AliAODEvent::GetPileupVertexSPD(Int_t iV) const{
829   // Get pile-up vertex iV
830   Int_t nVertices=GetNumberOfVertices();
831   Int_t counter=0;
832   for(Int_t iVert=0; iVert<nVertices; iVert++){
833     AliAODVertex *v=GetVertex(iVert);
834     if(v->GetType()==AliAODVertex::kPileupSPD){
835       if(counter==iV) return v;
836       ++counter;
837     }
838   }
839   return 0;
840 }
841 //______________________________________________________________________________
842 AliAODVertex* AliAODEvent::GetPileupVertexTracks(Int_t iV) const{
843   // Get pile-up vertex iV
844   Int_t nVertices=GetNumberOfVertices();
845   Int_t counter=0;
846   for(Int_t iVert=0; iVert<nVertices; iVert++){
847     AliAODVertex *v=GetVertex(iVert);
848     if(v->GetType()==AliAODVertex::kPileupTracks){
849       if(counter==iV) return v;
850       ++counter;
851     }
852   }
853   return 0;
854 }
855 //______________________________________________________________________________
856 Bool_t  AliAODEvent::IsPileupFromSPD(Int_t minContributors, 
857                                      Double_t minZdist, 
858                                      Double_t nSigmaZdist, 
859                                      Double_t nSigmaDiamXY, 
860                                      Double_t nSigmaDiamZ) const{
861   //
862   // This function checks if there was a pile up
863   // reconstructed with SPD
864   //
865   AliAODVertex *mainV=GetPrimaryVertexSPD();
866   if(!mainV) return kFALSE;
867   Int_t nc1=mainV->GetNContributors();
868   if(nc1<1) return kFALSE;
869   Int_t nPileVert=GetNumberOfPileupVerticesSPD();
870   if(nPileVert==0) return kFALSE;
871   Int_t nVertices=GetNumberOfVertices();
872   
873   for(Int_t iVert=0; iVert<nVertices; iVert++){
874     AliAODVertex *pv=GetVertex(iVert);
875     if(pv->GetType()!=AliAODVertex::kPileupSPD) continue;
876     Int_t nc2=pv->GetNContributors();
877     if(nc2>=minContributors){
878       Double_t z1=mainV->GetZ();
879       Double_t z2=pv->GetZ();
880       Double_t distZ=TMath::Abs(z2-z1);
881       Double_t distZdiam=TMath::Abs(z2-GetDiamondZ());
882       Double_t cutZdiam=nSigmaDiamZ*TMath::Sqrt(GetSigma2DiamondZ());
883       if(GetSigma2DiamondZ()<0.0001)cutZdiam=99999.; //protection for missing z diamond information
884       if(distZ>minZdist && distZdiam<cutZdiam){
885         Double_t x2=pv->GetX();
886         Double_t y2=pv->GetY();
887         Double_t distXdiam=TMath::Abs(x2-GetDiamondX());
888         Double_t distYdiam=TMath::Abs(y2-GetDiamondY());
889         Double_t cov1[6],cov2[6];       
890         mainV->GetCovarianceMatrix(cov1);
891         pv->GetCovarianceMatrix(cov2);
892         Double_t errxDist=TMath::Sqrt(cov2[0]+GetSigma2DiamondX());
893         Double_t erryDist=TMath::Sqrt(cov2[2]+GetSigma2DiamondY());
894         Double_t errzDist=TMath::Sqrt(cov1[5]+cov2[5]);
895         Double_t cutXdiam=nSigmaDiamXY*errxDist;
896         if(GetSigma2DiamondX()<0.0001)cutXdiam=99999.; //protection for missing diamond information
897         Double_t cutYdiam=nSigmaDiamXY*erryDist;
898         if(GetSigma2DiamondY()<0.0001)cutYdiam=99999.; //protection for missing diamond information
899         if( (distXdiam<cutXdiam) && (distYdiam<cutYdiam) && (distZ>nSigmaZdist*errzDist) ){
900           return kTRUE;
901         }
902       }
903     }
904   }
905   return kFALSE;
906 }
907
908 //______________________________________________________________________________
909 void AliAODEvent::Print(Option_t *) const
910 {
911   // Print the names of the all branches
912   TIter next(fAODObjects);
913   TNamed *el;
914   Printf(">>>>>  AOD  Content <<<<<");    
915   while((el=(TNamed*)next())){
916     Printf(">> %s ",el->GetName());      
917   }
918   Printf(">>>>>                <<<<<");    
919   
920   return;
921 }
922
923 //______________________________________________________________________________
924 void AliAODEvent::AssignIDtoCollection(const TCollection* col)
925 {
926     // Static method which assigns a ID to each object in a collection
927     // In this way the objects are marked as referenced and written with 
928     // an ID. This has the advantage that TRefs to this objects can be 
929     // written by a subsequent process.
930     TIter next(col);
931     TObject* obj;
932     while ((obj = next()))
933         TProcessID::AssignID(obj);
934 }
935
936 //______________________________________________________________________________
937 Bool_t AliAODEvent::IsPileupFromSPDInMultBins() const {
938     Int_t nTracklets=GetTracklets()->GetNumberOfTracklets();
939     if(nTracklets<20) return IsPileupFromSPD(3,0.8);
940     else if(nTracklets<50) return IsPileupFromSPD(4,0.8);
941     else return IsPileupFromSPD(5,0.8);
942 }
943
944 //______________________________________________________________________________
945 void AliAODEvent::Reset()
946 {
947   // Handle the cases
948   // Std content + Non std content
949
950   ClearStd();
951   if(fAODObjects->GetSize()>kAODListN){
952     // we have non std content
953     // this also covers aodfriends
954     for(int i = kAODListN;i < fAODObjects->GetSize();++i){
955       TObject *pObject = fAODObjects->At(i);
956       // TClonesArrays
957       if(pObject->InheritsFrom(TClonesArray::Class())){
958        ((TClonesArray*)pObject)->Delete();
959       }
960       else if(!pObject->InheritsFrom(TCollection::Class())){
961        TClass *pClass = TClass::GetClass(pObject->ClassName());
962        if (pClass && pClass->GetListOfMethods()->FindObject("Clear")) {
963          AliDebug(1, Form("Clear for object %s class %s", pObject->GetName(), pObject->ClassName()));
964          pObject->Clear();
965        }
966        else {
967          AliDebug(1, Form("ResetWithPlacementNew for object %s class %s", pObject->GetName(), pObject->ClassName()));
968           Long_t dtoronly = TObject::GetDtorOnly();
969           TObject::SetDtorOnly(pObject);
970           delete pObject;
971           pClass->New(pObject);
972           TObject::SetDtorOnly((void*)dtoronly);
973        }
974       }
975       else{
976        AliWarning(Form("No reset for %s \n",
977                        pObject->ClassName()));
978       }
979     }
980   }
981 }
982
983 Float_t AliAODEvent::GetVZEROEqMultiplicity(Int_t i) const
984 {
985   // Get VZERO Multiplicity for channel i
986   // Themethod uses the equalization factors
987   // stored in the ESD-run object in order to
988   // get equal multiplicities within a VZERO rins (1/8 of VZERO)
989   if (!fAODVZERO || !fHeader) return -1;
990
991   Int_t ring = i/8;
992   Float_t factorSum = 0;
993   for(Int_t j = 8*ring; j < (8*ring+8); ++j) {
994     factorSum += fHeader->GetVZEROEqFactors(j);
995   }
996   Float_t factor = fHeader->GetVZEROEqFactors(i)*8./factorSum;
997
998   return (fAODVZERO->GetMultiplicity(i)/factor);
999 }
1000
1001 //------------------------------------------------------------
1002 void  AliAODEvent::SetTOFHeader(const AliTOFHeader *header)
1003 {
1004   //
1005   // Set the TOF event_time
1006   //
1007
1008   if (fTOFHeader) {
1009     *fTOFHeader=*header;
1010     //fTOFHeader->SetName(fgkESDListName[kTOFHeader]);
1011   }
1012   else {
1013     // for analysis of reconstructed events
1014     // when this information is not avaliable
1015     fTOFHeader = new AliTOFHeader(*header);
1016     //AddObject(fTOFHeader);
1017   }
1018
1019 }
1020 //------------------------------------------------------------
1021 AliAODHMPIDrings *AliAODEvent::GetHMPIDringForTrackID(Int_t trackID) const
1022 {
1023   //
1024   // Returns the HMPID object if any for a given track ID
1025   //
1026   if(GetHMPIDrings())
1027   {
1028     for(Int_t ien = 0 ; ien < GetNHMPIDrings(); ien++)
1029     {
1030       if( GetHMPIDring(ien)->GetHmpTrkID() == trackID ) return GetHMPIDring(ien);      
1031     }//rings loop  
1032   }
1033   return 0;
1034 }
1035 //------------------------------------------------------------
1036 Int_t AliAODEvent::GetNHMPIDrings() const   
1037
1038   //
1039   // If there is a list of HMPID rings in the given AOD event, return their number
1040   //
1041   if ( fHMPIDrings) return fHMPIDrings->GetEntriesFast(); 
1042   else return -1;
1043
1044 //------------------------------------------------------------
1045 AliAODHMPIDrings *AliAODEvent::GetHMPIDring(Int_t nRings) const
1046
1047   //
1048   // If there is a list of HMPID rings in the given AOD event, return corresponding ring
1049   //
1050   if(fHMPIDrings) {
1051     if(   (AliAODHMPIDrings*)fHMPIDrings->UncheckedAt(nRings) ) {
1052       return (AliAODHMPIDrings*)fHMPIDrings->UncheckedAt(nRings);
1053     }
1054     else return 0x0;
1055   }
1056   else return 0x0;  
1057 }
1058 //------------------------------------------------------------
1059 AliAODTrdTrack& AliAODEvent::AddTrdTrack(const AliVTrdTrack *track) {
1060   return *(new ((*fTrdTracks)[fTrdTracks->GetEntriesFast()]) AliAODTrdTrack(*track));
1061 }
1062
1063 //______________________________________________________________________________
1064 void AliAODEvent::ConnectTracks() {
1065 // Connect tracks to this event
1066   if (fTracksConnected || !fTracks || !fTracks->GetEntriesFast()) return;
1067   if(!GetTrack(0)->InheritsFrom("AliAODTrack")) { // FIXME: consider using a dynamic_cast instead of InheritsFrom
1068     AliWarning("Not an AliAODTrack, this is not a standard AOD"); 
1069     return;
1070   }
1071   AliAODTrack *track;
1072   TIter next(fTracks);
1073   while ((track=(AliAODTrack*)next())) track->SetAODEvent(this);
1074   fTracksConnected = kTRUE;
1075 }
1076