]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AOD/AliAODEvent.cxx
Fixing leak
[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(new TList()),
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 }