Changes for #89817: Commit calorimeter AOD
[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
35 ClassImp(AliAODEvent)
36
37 // definition of std AOD member names
38   const char* AliAODEvent::fAODListName[kAODListN] = {"header",
39                                                       "tracks",
40                                                       "vertices",
41                                                       "v0s",
42                                                       "cascades",
43                                                       "tracklets",
44                                                       "jets",
45                                                       "emcalCells",
46                                                       "phosCells",
47                                                                         "caloClusters",
48                                                                         "emcalTrigger",
49                                                                         "phosTrigger",
50                                                       "fmdClusters",
51                                                       "pmdClusters",
52                                                       "dimuons",
53                                                       "AliAODTZERO",
54                                                       "AliAODVZERO",
55                                                       "AliAODZDC"
56 #ifdef MFT_UPGRADE        
57                                                       ,"AliAODMFT"
58 #endif                                                
59                                                       
60 };
61 //______________________________________________________________________________
62 AliAODEvent::AliAODEvent() :
63   AliVEvent(),
64   fAODObjects(0),
65   fAODFolder(0),
66   fConnected(kFALSE),
67   fHeader(0),
68   fTracks(0),
69   fVertices(0),
70   fV0s(0),
71   fCascades(0),
72   fTracklets(0),
73   fJets(0),
74   fEmcalCells(0),
75   fPhosCells(0),
76   fCaloClusters(0),
77   fEMCALTrigger(0),
78   fPHOSTrigger(0),
79   fFmdClusters(0),
80   fPmdClusters(0),
81   fDimuons(0),
82   fAODTZERO(0),
83   fAODVZERO(0),
84   fAODZDC(0)
85 #ifdef MFT_UPGRADE
86   ,fAODMFT(0)
87 #endif
88 {
89   // default constructor
90 }
91
92 //______________________________________________________________________________
93 AliAODEvent::AliAODEvent(const AliAODEvent& aod):
94   AliVEvent(aod),
95   fAODObjects(new TList()),
96   fAODFolder(0),
97   fConnected(kFALSE),
98   fHeader(new AliAODHeader(*aod.fHeader)),
99   fTracks(new TClonesArray(*aod.fTracks)),
100   fVertices(new TClonesArray(*aod.fVertices)),
101   fV0s(new TClonesArray(*aod.fV0s)),
102   fCascades(new TClonesArray(*aod.fCascades)),
103   fTracklets(new AliAODTracklets(*aod.fTracklets)),
104   fJets(new TClonesArray(*aod.fJets)),
105   fEmcalCells(new AliAODCaloCells(*aod.fEmcalCells)),
106   fPhosCells(new AliAODCaloCells(*aod.fPhosCells)),
107   fCaloClusters(new TClonesArray(*aod.fCaloClusters)),
108   fEMCALTrigger(new AliAODCaloTrigger(*aod.fEMCALTrigger)),
109   fPHOSTrigger(new AliAODCaloTrigger(*aod.fPHOSTrigger)),
110   fFmdClusters(new TClonesArray(*aod.fFmdClusters)),
111   fPmdClusters(new TClonesArray(*aod.fPmdClusters)),
112   fDimuons(new TClonesArray(*aod.fDimuons)),
113   fAODTZERO(new AliAODTZERO(*aod.fAODTZERO)),
114   fAODVZERO(new AliAODVZERO(*aod.fAODVZERO)),
115   fAODZDC(new AliAODZDC(*aod.fAODZDC))
116 #ifdef MFT_UPGRADE
117   ,fAODMFT(new AliAODMFT(*aod.fAODMFT))
118 #endif
119 {
120   // Copy constructor
121   AddObject(fHeader);
122   AddObject(fTracks);
123   AddObject(fVertices);
124   AddObject(fV0s);
125   AddObject(fCascades);
126   AddObject(fTracklets);
127   AddObject(fJets);
128   AddObject(fEmcalCells);
129   AddObject(fPhosCells);
130   AddObject(fCaloClusters);
131   AddObject(fEMCALTrigger);
132   AddObject(fPHOSTrigger);
133   AddObject(fFmdClusters);
134   AddObject(fPmdClusters);
135   AddObject(fDimuons);
136   AddObject(fAODTZERO);
137   AddObject(fAODVZERO);
138   AddObject(fAODZDC);
139 #ifdef MFT_UPGRADE      
140   AddObject(fAODVZERO);
141 #endif
142   fConnected = aod.fConnected;
143   GetStdContent();
144   CreateStdFolders();
145 }
146
147 //______________________________________________________________________________
148 AliAODEvent & AliAODEvent::operator=(const AliAODEvent& aod) {
149
150     // Assignment operator
151
152   if(&aod == this) return *this;
153   AliVEvent::operator=(aod);
154
155   // This assumes that the list is already created
156   // and that the virtual void Copy(Tobject&) function
157   // is correctly implemented in the derived class
158   // otherwise only TObject::Copy() will be used
159
160   if((fAODObjects->GetSize()==0)&&(aod.fAODObjects->GetSize()>=kAODListN)){
161     // We cover the case that we do not yet have the 
162     // standard content but the source has it
163     CreateStdContent();
164   }
165   
166   // Here we have the standard content without user additions, but the content is 
167   // not matching the aod source.
168   
169   // Iterate the list of source objects
170   TIter next(aod.GetList());
171   TObject *its = 0;
172   TString name;
173   while ((its = next())) {
174     name = its->GetName();
175     // Check if we have this object type in out list
176     TObject *mine = fAODObjects->FindObject(name);    
177     if(!mine) {
178       // We have to create the same type of object.
179       TClass* pClass=TClass::GetClass(its->ClassName());     
180       if (!pClass) {
181         AliWarning(Form("Can not find class description for entry %s (%s)\n",
182                    its->ClassName(), name.Data()));
183         continue;
184       }
185       mine=(TObject*)pClass->New();
186       if(!mine){
187         // not in this: can be added to list
188         AliWarning(Form("%s:%d Could not find %s for copying \n",
189                    (char*)__FILE__,__LINE__,name.Data()));
190         continue;
191       }  
192       if(mine->InheritsFrom("TNamed"))  {
193         ((TNamed*)mine)->SetName(name);
194       } else if(mine->InheritsFrom("TCollection")){
195         if(mine->InheritsFrom("TClonesArray")) {
196           TClonesArray *itscl = dynamic_cast<TClonesArray*>(its);
197           if (!itscl) {
198             AliWarning(Form("Class description for entry %s (%s) not TClonesArray\n",
199                    its->ClassName(), name.Data()));
200             continue;
201           
202           }
203                dynamic_cast<TClonesArray*>(mine)->SetClass(itscl->GetClass(), itscl->GetSize());
204         }
205         dynamic_cast<TCollection*>(mine)->SetName(name);
206       }
207       AliDebug(1, Form("adding object %s of type %s", mine->GetName(), mine->ClassName()));
208       AddObject(mine);
209     }
210     // Now we have an object of the same type and name, but different content.        
211     if(!its->InheritsFrom("TCollection")){
212       // simple objects (do they have a Copy method that calls operator= ?)
213       its->Copy(*mine);
214     } else if (its->InheritsFrom("TClonesArray")) {
215       // Create or expand the tclonesarray pointers
216       // so we can directly copy to the object
217       TClonesArray *its_tca = (TClonesArray*)its;
218       TClonesArray *mine_tca = (TClonesArray*)mine;
219       // this leaves the capacity of the TClonesArray the same
220       // except for a factor of 2 increase when size > capacity
221       // does not release any memory occupied by the tca
222       Int_t its_entries = its_tca->GetEntriesFast();
223       mine_tca->ExpandCreate(its_entries);
224       for(int i=0; i<its_entries; i++){
225         // copy 
226         TObject *mine_tca_obj = mine_tca->At(i);
227         TObject *its_tca_obj = its_tca->At(i);
228         // no need to delete first
229         // pointers within the class should be handled by Copy()...
230         // Can there be Empty slots?
231         its_tca_obj->Copy(*mine_tca_obj);
232       }
233     } else {
234       AliWarning(Form("%s:%d cannot copy TCollection \n",
235                       (char*)__FILE__,__LINE__));
236     }
237   }  
238   fConnected = aod.fConnected;
239   return *this;
240 }
241
242
243 //______________________________________________________________________________
244 AliAODEvent::~AliAODEvent() 
245 {
246 // destructor
247     if(!fConnected) {
248        fAODObjects->Delete("slow");
249        delete fAODObjects;
250     }   
251     delete fAODFolder;
252 }
253
254 //______________________________________________________________________________
255 void AliAODEvent::AddObject(TObject* obj) 
256 {
257   // Add an object to the list of objects.
258   // Please be aware that in order to increase performance you should
259   // refrain from using TObjArrays (if possible). Use TClonesArrays, instead.
260   
261   if ( !fAODObjects->FindObject(obj) ) 
262   {
263     fAODObjects->AddLast(obj);
264   }
265 }
266
267 //______________________________________________________________________________
268 void AliAODEvent::RemoveObject(TObject* obj) 
269 {
270   // Removes an object from the list of objects.
271   
272   fAODObjects->Remove(obj);
273 }
274
275 //______________________________________________________________________________
276 TObject *AliAODEvent::FindListObject(const char *objName) const
277 {
278   // Return the pointer to the object with the given name.
279
280   return fAODObjects->FindObject(objName);
281 }
282
283 //______________________________________________________________________________
284 void AliAODEvent::CreateStdContent() 
285 {
286   // create the standard AOD content and set pointers
287
288   // create standard objects and add them to the TList of objects
289   AddObject(new AliAODHeader());
290   AddObject(new TClonesArray("AliAODTrack", 0));
291   AddObject(new TClonesArray("AliAODVertex", 0));
292   AddObject(new TClonesArray("AliAODv0", 0));
293   AddObject(new TClonesArray("AliAODcascade", 0));
294   AddObject(new AliAODTracklets());
295   AddObject(new TClonesArray("AliAODJet", 0));
296   AddObject(new AliAODCaloCells());
297   AddObject(new AliAODCaloCells());
298   AddObject(new TClonesArray("AliAODCaloCluster", 0));
299   AddObject(new AliAODCaloTrigger()); // EMCAL 
300   AddObject(new AliAODCaloTrigger()); // PHOS
301   AddObject(new TClonesArray("AliAODFmdCluster", 0));
302   AddObject(new TClonesArray("AliAODPmdCluster", 0));
303   AddObject(new TClonesArray("AliAODDimuon", 0));
304   AddObject(new AliAODTZERO());
305   AddObject(new AliAODVZERO());
306   AddObject(new AliAODZDC());
307 #ifdef MFT_UPGRADE
308   AddObject(new AliAODMFT());
309 #endif
310   // set names
311   SetStdNames();
312
313   // read back pointers
314   GetStdContent();
315   CreateStdFolders();
316   return;
317 }
318
319 void  AliAODEvent::MakeEntriesReferencable()
320 {
321     // Make all entries referencable in a subsequent process
322     //
323     TIter next(fAODObjects);
324     TObject* obj;
325     while ((obj = next()))
326     {
327         if(obj->InheritsFrom("TCollection"))
328             {
329                 AssignIDtoCollection((TCollection*)obj);
330             }
331     }
332 }
333
334 //______________________________________________________________________________
335 void AliAODEvent::SetStdNames()
336 {
337   // introduce the standard naming
338
339   if(fAODObjects->GetEntries()==kAODListN){
340     for(int i = 0;i < fAODObjects->GetEntries();i++){
341       TObject *fObj = fAODObjects->At(i);
342       if(fObj->InheritsFrom("TNamed")){
343         ((TNamed*)fObj)->SetName(fAODListName[i]);
344       }
345       else if(fObj->InheritsFrom("TClonesArray")){
346         ((TClonesArray*)fObj)->SetName(fAODListName[i]);
347       }
348     }
349   }
350   else{
351     printf("%s:%d SetStdNames() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__);
352   }
353
354
355 void AliAODEvent::CreateStdFolders()
356 {
357     // Create the standard folder structure
358   if(fAODFolder)delete fAODFolder;
359     fAODFolder = gROOT->GetRootFolder()->AddFolder("AOD", "AOD");
360     if(fAODObjects->GetEntries()==kAODListN){
361         for(int i = 0;i < fAODObjects->GetEntries();i++){
362             TObject *fObj = fAODObjects->At(i);
363             if(fObj->InheritsFrom("TClonesArray")){
364                 fAODFolder->AddFolder(fAODListName[i], fAODListName[i], (TCollection*) fObj);
365             } else {
366                 fAODFolder->AddFolder(fAODListName[i], fAODListName[i], 0);
367             }
368         }
369     }
370     else{
371         printf("%s:%d CreateStdFolders() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__);
372     }
373
374
375 //______________________________________________________________________________
376 void AliAODEvent::GetStdContent()
377 {
378   // set pointers for standard content
379
380   fHeader        = (AliAODHeader*)fAODObjects->FindObject("header");
381   fTracks        = (TClonesArray*)fAODObjects->FindObject("tracks");
382   fVertices      = (TClonesArray*)fAODObjects->FindObject("vertices");
383   fV0s           = (TClonesArray*)fAODObjects->FindObject("v0s");
384   fCascades      = (TClonesArray*)fAODObjects->FindObject("cascades");
385   fTracklets     = (AliAODTracklets*)fAODObjects->FindObject("tracklets");
386   fJets          = (TClonesArray*)fAODObjects->FindObject("jets");
387   fEmcalCells    = (AliAODCaloCells*)fAODObjects->FindObject("emcalCells");
388   fPhosCells     = (AliAODCaloCells*)fAODObjects->FindObject("phosCells");
389   fCaloClusters  = (TClonesArray*)fAODObjects->FindObject("caloClusters");
390         fEMCALTrigger  = (AliAODCaloTrigger*)fAODObjects->FindObject("emcalTrigger");
391         fPHOSTrigger   = (AliAODCaloTrigger*)fAODObjects->FindObject("phosTrigger");
392   fFmdClusters   = (TClonesArray*)fAODObjects->FindObject("fmdClusters");
393   fPmdClusters   = (TClonesArray*)fAODObjects->FindObject("pmdClusters");
394   fDimuons       = (TClonesArray*)fAODObjects->FindObject("dimuons");
395   fAODTZERO      = (AliAODTZERO*)fAODObjects->FindObject("AliAODTZERO");
396   fAODVZERO      = (AliAODVZERO*)fAODObjects->FindObject("AliAODVZERO");
397   fAODZDC        = (AliAODZDC*)fAODObjects->FindObject("AliAODZDC");
398 #ifdef MFT_UPGRADE
399   fAODMFT        = (AliAODMFT*)fAODObjects->FindObject("AliAODMFT");
400 #endif
401 }
402
403 //______________________________________________________________________________
404 void AliAODEvent::ResetStd(Int_t trkArrSize, 
405                            Int_t vtxArrSize, 
406                            Int_t v0ArrSize,
407                            Int_t cascadeArrSize,
408                            Int_t jetSize, 
409                            Int_t caloClusSize, 
410                            Int_t fmdClusSize, 
411                            Int_t pmdClusSize,
412                            Int_t dimuonArrSize
413                            )
414 {
415   // deletes content of standard arrays and resets size 
416   
417   if (fTracks) {
418     fTracks->Delete();
419     if (trkArrSize > fTracks->GetSize()) 
420       fTracks->Expand(trkArrSize);
421   }
422   if (fVertices) {
423     fVertices->Delete();
424     if (vtxArrSize > fVertices->GetSize()) 
425       fVertices->Expand(vtxArrSize);
426   }
427   if (fV0s) {
428     fV0s->Delete();
429     if (v0ArrSize > fV0s->GetSize()) 
430       fV0s->Expand(v0ArrSize);
431   }
432   if (fCascades) {
433     fCascades->Delete();
434     if (cascadeArrSize > fCascades->GetSize()) 
435       fCascades->Expand(cascadeArrSize);
436   }
437   if (fJets) {
438     fJets->Delete();
439     if (jetSize > fJets->GetSize())
440       fJets->Expand(jetSize);
441   }
442   if (fCaloClusters) {
443     fCaloClusters->Delete();
444     if (caloClusSize > fCaloClusters->GetSize()) 
445       fCaloClusters->Expand(caloClusSize);
446   }
447   if (fFmdClusters) {
448     fFmdClusters->Delete();
449     if (fmdClusSize > fFmdClusters->GetSize()) 
450       fFmdClusters->Expand(fmdClusSize);
451   }
452   if (fPmdClusters) {
453     fPmdClusters->Delete();
454     if (pmdClusSize > fPmdClusters->GetSize()) 
455       fPmdClusters->Expand(pmdClusSize);
456   }
457   if (fDimuons) {
458     fDimuons->Delete();
459     if (dimuonArrSize > fDimuons->GetSize()) 
460       fDimuons->Expand(dimuonArrSize);
461   }
462   if (fTracklets)
463     fTracklets->DeleteContainer();
464   if (fPhosCells)
465     fPhosCells->DeleteContainer();  
466   if (fEmcalCells)
467     fEmcalCells->DeleteContainer();
468   
469   if (fEMCALTrigger)
470         fEMCALTrigger->DeAllocate();
471   if (fPHOSTrigger)
472         fPHOSTrigger->DeAllocate();
473 }
474
475 void AliAODEvent::ClearStd()
476 {
477   // clears the standard arrays
478   if (fHeader)
479     fHeader        ->Clear();
480   if (fTracks)
481     fTracks        ->Delete();
482   if (fVertices)
483     fVertices      ->Delete();
484   if (fV0s)
485     fV0s           ->Delete();
486   if (fCascades)
487     fCascades      ->Delete();
488   if (fTracklets)
489     fTracklets     ->DeleteContainer();
490   if (fJets)
491     fJets          ->Delete();
492   if (fEmcalCells)
493     fEmcalCells    ->DeleteContainer();
494   if (fPhosCells)
495     fPhosCells     ->DeleteContainer();
496   if (fCaloClusters)
497     fCaloClusters  ->Delete();
498   if (fFmdClusters)
499     fFmdClusters   ->Clear();
500   if (fPmdClusters)
501     fPmdClusters   ->Clear();
502   if (fDimuons)
503     fDimuons       ->Clear();
504         
505   if (fEMCALTrigger)
506         fEMCALTrigger->DeAllocate();
507   if (fPHOSTrigger)
508         fPHOSTrigger->DeAllocate();
509 }
510
511 //_________________________________________________________________
512 Int_t AliAODEvent::GetPHOSClusters(TRefArray *clusters) const
513 {
514   // fills the provided TRefArray with all found phos clusters
515   
516   clusters->Clear();
517   
518   AliAODCaloCluster *cl = 0;
519   Bool_t first = kTRUE;
520   for (Int_t i = 0; i < GetNumberOfCaloClusters() ; i++) {
521     if ( (cl = GetCaloCluster(i)) ) {
522       if (cl->IsPHOS()){
523         if(first) {
524           new (clusters) TRefArray(TProcessID::GetProcessWithUID(cl)); 
525           first=kFALSE;
526         }
527         clusters->Add(cl);
528         //printf("IsPHOS cluster %d, E %2.3f Size: %d \n",i,cl->E(),clusters->GetEntriesFast());
529       }
530     }
531   }
532   return clusters->GetEntriesFast();
533 }
534
535 //_________________________________________________________________
536 Int_t AliAODEvent::GetEMCALClusters(TRefArray *clusters) const
537 {
538   // fills the provided TRefArray with all found emcal clusters
539
540   clusters->Clear();
541   AliAODCaloCluster *cl = 0;
542   Bool_t first = kTRUE;
543   for (Int_t i = 0; i < GetNumberOfCaloClusters(); i++) {
544     if ( (cl = GetCaloCluster(i)) ) {
545       if (cl->IsEMCAL()){
546         if(first) {
547           new (clusters) TRefArray(TProcessID::GetProcessWithUID(cl)); 
548           first=kFALSE;
549         }
550         clusters->Add(cl);
551         //printf("IsEMCal cluster %d, E %2.3f Size: %d \n",i,cl->E(),clusters->GetEntriesFast());
552       }
553     }
554   }
555   return clusters->GetEntriesFast();
556 }
557
558
559 //______________________________________________________________________________
560 Int_t AliAODEvent::GetMuonTracks(TRefArray *muonTracks) const
561 {
562   // fills the provided TRefArray with all found muon tracks
563
564   muonTracks->Clear();
565
566   AliAODTrack *track = 0;
567   for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
568     track = GetTrack(iTrack);
569     if (track->IsMuonTrack()) {
570       muonTracks->Add(track);
571     }
572   }
573   
574   return muonTracks->GetEntriesFast();
575 }
576
577
578 //______________________________________________________________________________
579 Int_t AliAODEvent::GetNumberOfMuonTracks() const
580 {
581   // get number of muon tracks
582   Int_t nMuonTracks=0;
583   for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
584     if ((GetTrack(iTrack))->IsMuonTrack()) {
585        nMuonTracks++;
586     }
587   }
588   
589   return nMuonTracks;
590 }
591
592 //______________________________________________________________________________
593 void AliAODEvent::ReadFromTree(TTree *tree, Option_t* opt /*= ""*/)
594 {
595     // Connects aod event to tree
596   
597   if(!tree){
598     AliWarning("Zero Pointer to Tree \n");
599     return;
600   }
601     // load the TTree
602   if(!tree->GetTree())tree->LoadTree(0);
603   
604     // Try to find AliAODEvent
605   AliAODEvent *aodEvent = 0;
606   aodEvent = (AliAODEvent*)tree->GetTree()->GetUserInfo()->FindObject("AliAODEvent");
607   if(aodEvent){
608     // This event is connected to the tree by definition, just say so
609     aodEvent->SetConnected();
610       // Check if already connected to tree
611     TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("AODObjectsConnectedToTree"));
612     if (connectedList && (strcmp(opt, "reconnect"))) {
613         // If connected use the connected list of objects
614         delete fAODObjects;
615         fAODObjects = connectedList;
616         GetStdContent(); 
617         fConnected = kTRUE;
618         return;
619     } 
620       // Connect to tree
621       // prevent a memory leak when reading back the TList
622 //      if (!(strcmp(opt, "reconnect"))) fAODObjects->Delete();
623     
624       // create a new TList from the UserInfo TList... 
625       // copy constructor does not work...
626     //    fAODObjects = (TList*)(aodEvent->GetList()->Clone());
627     fAODObjects = (TList*)aodEvent->GetList();
628     fAODObjects->SetOwner(kTRUE);
629     if(fAODObjects->GetEntries()<kAODListN)
630     {
631       AliWarning(Form("AliAODEvent::ReadFromTree() TList contains less than the standard contents %d < %d"
632                       " That might be fine though (at least for filtered AODs)",fAODObjects->GetEntries(),kAODListN));
633     }
634       //
635       // Let's find out whether we have friends
636     TList* friendL = tree->GetTree()->GetListOfFriends();
637     if (friendL) 
638     {
639       TIter next(friendL);
640       TFriendElement* fe;
641       while ((fe = (TFriendElement*)next())){
642         aodEvent = (AliAODEvent*)(fe->GetTree()->GetUserInfo()->FindObject("AliAODEvent"));
643         if (!aodEvent) {
644           printf("No UserInfo on tree \n");
645         } else {
646           
647           //          TList* objL = (TList*)(aodEvent->GetList()->Clone());
648           TList* objL = (TList*)aodEvent->GetList();
649           printf("Get list of object from tree %d !!\n", objL->GetEntries());
650           TIter nextobject(objL);
651           TObject* obj =  0;
652           while((obj = nextobject()))
653           {
654             printf("Adding object from friend %s !\n", obj->GetName());
655             fAODObjects->Add(obj);
656           } // object "branch" loop
657         } // has userinfo  
658       } // friend loop
659     } // has friends    
660       // set the branch addresses
661     TIter next(fAODObjects);
662     TNamed *el;
663     while((el=(TNamed*)next())){
664       TString bname(el->GetName());
665         // check if branch exists under this Name
666       TBranch *br = tree->GetTree()->GetBranch(bname.Data());
667       if(br){
668         tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
669       } else {
670         br = tree->GetBranch(Form("%s.",bname.Data()));
671         if(br){
672           tree->SetBranchAddress(Form("%s.",bname.Data()),fAODObjects->GetObjectRef(el));
673         }
674         else{
675           printf("%s %d AliAODEvent::ReadFromTree() No Branch found with Name %s. \n",
676                  (char*)__FILE__,__LINE__,bname.Data());
677         }       
678       }
679     }
680     GetStdContent();
681       // when reading back we are not owner of the list 
682       // must not delete it
683     fAODObjects->SetOwner(kTRUE);
684     fAODObjects->SetName("AODObjectsConnectedToTree");
685       // we are not owner of the list objects 
686       // must not delete it
687     tree->GetUserInfo()->Add(fAODObjects);
688     fConnected = kTRUE;
689   }// no aodEvent
690   else {
691       // we can't get the list from the user data, create standard content
692       // and set it by hand
693     CreateStdContent();
694     TIter next(fAODObjects);
695     TNamed *el;
696     while((el=(TNamed*)next())){
697       TString bname(el->GetName());    
698       tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
699     }
700     GetStdContent();
701       // when reading back we are not owner of the list 
702       // must not delete it
703     fAODObjects->SetOwner(kTRUE);
704   }
705 }
706   //______________________________________________________________________________
707 Int_t  AliAODEvent::GetNumberOfPileupVerticesSPD() const{
708   // count number of SPD pileup vertices
709   Int_t nVertices=GetNumberOfVertices();
710   Int_t nPileupVertices=0;
711   for(Int_t iVert=0; iVert<nVertices; iVert++){
712     AliAODVertex *v=GetVertex(iVert);
713     if(v->GetType()==AliAODVertex::kPileupSPD) nPileupVertices++;
714   }
715   return nPileupVertices;
716 }
717 //______________________________________________________________________________
718 Int_t  AliAODEvent::GetNumberOfPileupVerticesTracks() const{
719   // count number of track pileup vertices
720   Int_t nVertices=GetNumberOfVertices();
721   Int_t nPileupVertices=0;
722   for(Int_t iVert=0; iVert<nVertices; iVert++){
723     AliAODVertex *v=GetVertex(iVert);
724     if(v->GetType()==AliAODVertex::kPileupTracks) nPileupVertices++;
725   }
726   return nPileupVertices;
727 }
728 //______________________________________________________________________________
729 AliAODVertex* AliAODEvent::GetPrimaryVertexSPD() const{
730   // Get SPD primary vertex
731   Int_t nVertices=GetNumberOfVertices();
732   for(Int_t iVert=0; iVert<nVertices; iVert++){
733     AliAODVertex *v=GetVertex(iVert);
734     if(v->GetType()==AliAODVertex::kMainSPD) return v;
735   }
736   return 0;
737 }
738 //______________________________________________________________________________
739 AliAODVertex* AliAODEvent::GetPileupVertexSPD(Int_t iV) const{
740   // Get pile-up vertex iV
741   Int_t nVertices=GetNumberOfVertices();
742   Int_t counter=0;
743   for(Int_t iVert=0; iVert<nVertices; iVert++){
744     AliAODVertex *v=GetVertex(iVert);
745     if(v->GetType()==AliAODVertex::kPileupSPD){
746       if(counter==iV) return v;
747       ++counter;
748     }
749   }
750   return 0;
751 }
752 //______________________________________________________________________________
753 AliAODVertex* AliAODEvent::GetPileupVertexTracks(Int_t iV) const{
754   // Get pile-up vertex iV
755   Int_t nVertices=GetNumberOfVertices();
756   Int_t counter=0;
757   for(Int_t iVert=0; iVert<nVertices; iVert++){
758     AliAODVertex *v=GetVertex(iVert);
759     if(v->GetType()==AliAODVertex::kPileupTracks){
760       if(counter==iV) return v;
761       ++counter;
762     }
763   }
764   return 0;
765 }
766 //______________________________________________________________________________
767 Bool_t  AliAODEvent::IsPileupFromSPD(Int_t minContributors, 
768                                      Double_t minZdist, 
769                                      Double_t nSigmaZdist, 
770                                      Double_t nSigmaDiamXY, 
771                                      Double_t nSigmaDiamZ) const{
772   //
773   // This function checks if there was a pile up
774   // reconstructed with SPD
775   //
776   AliAODVertex *mainV=GetPrimaryVertexSPD();
777   if(!mainV) return kFALSE;
778   Int_t nc1=mainV->GetNContributors();
779   if(nc1<1) return kFALSE;
780   Int_t nPileVert=GetNumberOfPileupVerticesSPD();
781   if(nPileVert==0) return kFALSE;
782   Int_t nVertices=GetNumberOfVertices();
783   
784   for(Int_t iVert=0; iVert<nVertices; iVert++){
785     AliAODVertex *pv=GetVertex(iVert);
786     if(pv->GetType()!=AliAODVertex::kPileupSPD) continue;
787     Int_t nc2=pv->GetNContributors();
788     if(nc2>=minContributors){
789       Double_t z1=mainV->GetZ();
790       Double_t z2=pv->GetZ();
791       Double_t distZ=TMath::Abs(z2-z1);
792       Double_t distZdiam=TMath::Abs(z2-GetDiamondZ());
793       Double_t cutZdiam=nSigmaDiamZ*TMath::Sqrt(GetSigma2DiamondZ());
794       if(GetSigma2DiamondZ()<0.0001)cutZdiam=99999.; //protection for missing z diamond information
795       if(distZ>minZdist && distZdiam<cutZdiam){
796         Double_t x2=pv->GetX();
797         Double_t y2=pv->GetY();
798         Double_t distXdiam=TMath::Abs(x2-GetDiamondX());
799         Double_t distYdiam=TMath::Abs(y2-GetDiamondY());
800         Double_t cov1[6],cov2[6];       
801         mainV->GetCovarianceMatrix(cov1);
802         pv->GetCovarianceMatrix(cov2);
803         Double_t errxDist=TMath::Sqrt(cov2[0]+GetSigma2DiamondX());
804         Double_t erryDist=TMath::Sqrt(cov2[2]+GetSigma2DiamondY());
805         Double_t errzDist=TMath::Sqrt(cov1[5]+cov2[5]);
806         Double_t cutXdiam=nSigmaDiamXY*errxDist;
807         if(GetSigma2DiamondX()<0.0001)cutXdiam=99999.; //protection for missing diamond information
808         Double_t cutYdiam=nSigmaDiamXY*erryDist;
809         if(GetSigma2DiamondY()<0.0001)cutYdiam=99999.; //protection for missing diamond information
810         if( (distXdiam<cutXdiam) && (distYdiam<cutYdiam) && (distZ>nSigmaZdist*errzDist) ){
811           return kTRUE;
812         }
813       }
814     }
815   }
816   return kFALSE;
817 }
818
819 //______________________________________________________________________________
820 void AliAODEvent::Print(Option_t *) const
821 {
822   // Print the names of the all branches
823   TIter next(fAODObjects);
824   TNamed *el;
825   Printf(">>>>>  AOD  Content <<<<<");    
826   while((el=(TNamed*)next())){
827     Printf(">> %s ",el->GetName());      
828   }
829   Printf(">>>>>                <<<<<");    
830   
831   return;
832 }
833
834 void AliAODEvent::AssignIDtoCollection(const TCollection* col)
835 {
836     // Static method which assigns a ID to each object in a collection
837     // In this way the objects are marked as referenced and written with 
838     // an ID. This has the advantage that TRefs to this objects can be 
839     // written by a subsequent process.
840     TIter next(col);
841     TObject* obj;
842     while ((obj = next()))
843         TProcessID::AssignID(obj);
844 }
845
846 Bool_t AliAODEvent::IsPileupFromSPDInMultBins() const {
847     Int_t nTracklets=GetTracklets()->GetNumberOfTracklets();
848     if(nTracklets<20) return IsPileupFromSPD(3,0.8);
849     else if(nTracklets<50) return IsPileupFromSPD(4,0.8);
850     else return IsPileupFromSPD(5,0.8);
851 }
852
853 Float_t AliAODEvent::GetVZEROEqMultiplicity(Int_t i) const
854 {
855   // Get VZERO Multiplicity for channel i
856   // Themethod uses the equalization factors
857   // stored in the ESD-run object in order to
858   // get equal multiplicities within a VZERO rins (1/8 of VZERO)
859   if (!fAODVZERO || !fHeader) return -1;
860
861   Int_t ring = i/8;
862   Float_t factorSum = 0;
863   for(Int_t j = 8*ring; j < (8*ring+8); ++j) {
864     factorSum += fHeader->GetVZEROEqFactors(j);
865   }
866   Float_t factor = fHeader->GetVZEROEqFactors(i)*8./factorSum;
867
868   return (fAODVZERO->GetMultiplicity(i)/factor);
869 }