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