ReadFromTree: option for reconnection of tree added.
[u/mrichter/AliRoot.git] / STEER / 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
30 #include "AliAODEvent.h"
31 #include "AliAODHeader.h"
32 #include "AliAODTrack.h"
33
34 ClassImp(AliAODEvent)
35
36 // definition of std AOD member names
37   const char* AliAODEvent::fAODListName[kAODListN] = {"header",
38                                                       "tracks",
39                                                       "vertices",
40                                                       "v0s",
41                                                       "tracklets",
42                                                       "jets",
43                                                       "emcalCells",
44                                                       "phosCells",
45                                                       "caloClusters",
46                                                       "fmdClusters",
47                                                       "pmdClusters"
48 };
49 //______________________________________________________________________________
50 AliAODEvent::AliAODEvent() :
51   AliVEvent(),
52   fAODObjects(new TList()),
53   fAODFolder(0),
54   fHeader(0),
55   fTracks(0),
56   fVertices(0),
57   fV0s(0),
58   fTracklets(0),
59   fJets(0),
60   fEmcalCells(0),
61   fPhosCells(0),
62   fCaloClusters(0),
63   fFmdClusters(0),
64   fPmdClusters(0)
65 {
66   // default constructor
67 }
68
69 //______________________________________________________________________________
70 AliAODEvent::AliAODEvent(const AliAODEvent& aod):
71   AliVEvent(aod),
72   fAODObjects(new TList()),
73   fAODFolder(new TFolder()),
74   fHeader(new AliAODHeader(*aod.fHeader)),
75   fTracks(new TClonesArray(*aod.fTracks)),
76   fVertices(new TClonesArray(*aod.fVertices)),
77   fV0s(new TClonesArray(*aod.fV0s)),
78   fTracklets(new AliAODTracklets(*aod.fTracklets)),
79   fJets(new TClonesArray(*aod.fJets)),
80   fEmcalCells(new AliAODCaloCells(*aod.fEmcalCells)),
81   fPhosCells(new AliAODCaloCells(*aod.fPhosCells)),
82   fCaloClusters(new TClonesArray(*aod.fCaloClusters)),
83   fFmdClusters(new TClonesArray(*aod.fFmdClusters)),
84   fPmdClusters(new TClonesArray(*aod.fPmdClusters))
85 {
86   // Copy constructor
87   AddObject(fHeader);
88   AddObject(fTracks);
89   AddObject(fVertices);
90   AddObject(fV0s);
91   AddObject(fTracklets);
92   AddObject(fJets);
93   AddObject(fEmcalCells);
94   AddObject(fPhosCells);
95   AddObject(fCaloClusters);
96   AddObject(fFmdClusters);
97   AddObject(fPmdClusters);
98
99   GetStdContent();
100 }
101
102 //______________________________________________________________________________
103 AliAODEvent & AliAODEvent::operator=(const AliAODEvent& aod) {
104
105     // Assignment operator
106
107     if(&aod == this) return *this;
108     AliVEvent::operator=(aod);
109
110     fAODObjects      = new TList();
111     fAODFolder       = new TFolder();
112     fHeader          = new AliAODHeader(*aod.fHeader);
113     fTracks          = new TClonesArray(*aod.fTracks);
114     fVertices        = new TClonesArray(*aod.fVertices);
115     fV0s             = new TClonesArray(*aod.fV0s);
116     fTracklets       = new AliAODTracklets(*aod.fTracklets);
117     fJets            = new TClonesArray(*aod.fJets);
118     fEmcalCells      = new AliAODCaloCells(*aod.fEmcalCells);
119     fPhosCells       = new AliAODCaloCells(*aod.fPhosCells);
120     fCaloClusters    = new TClonesArray(*aod.fCaloClusters);
121     fFmdClusters     = new TClonesArray(*aod.fFmdClusters);
122     fPmdClusters     = new TClonesArray(*aod.fPmdClusters);
123     
124     fAODObjects = new TList();
125     
126     AddObject(fHeader);
127     AddObject(fTracks);
128     AddObject(fVertices);
129     AddObject(fV0s);
130     AddObject(fTracklets);
131     AddObject(fJets);
132     AddObject(fEmcalCells);
133     AddObject(fPhosCells);
134     AddObject(fCaloClusters);
135     AddObject(fFmdClusters);
136     AddObject(fPmdClusters);
137     GetStdContent();
138     return *this;
139 }
140
141
142 //______________________________________________________________________________
143 AliAODEvent::~AliAODEvent() 
144 {
145 // destructor
146     delete fAODObjects;
147     delete fAODFolder;
148 }
149
150 //______________________________________________________________________________
151 void AliAODEvent::AddObject(TObject* obj) 
152 {
153   // Add an object to the list of objects.
154   // Please be aware that in order to increase performance you should
155   // refrain from using TObjArrays (if possible). Use TClonesArrays, instead.
156   
157   fAODObjects->AddLast(obj);
158 }
159
160 //______________________________________________________________________________
161 void AliAODEvent::RemoveObject(TObject* obj) 
162 {
163   // Removes an object from the list of objects.
164   
165   fAODObjects->Remove(obj);
166 }
167
168 //______________________________________________________________________________
169 TObject *AliAODEvent::FindListObject(const char *objName)
170 {
171   // Return the pointer to the object with the given name.
172
173   return fAODObjects->FindObject(objName);
174 }
175
176 //______________________________________________________________________________
177 void AliAODEvent::CreateStdContent() 
178 {
179   // create the standard AOD content and set pointers
180
181   // create standard objects and add them to the TList of objects
182   AddObject(new AliAODHeader());
183   AddObject(new TClonesArray("AliAODTrack", 0));
184   AddObject(new TClonesArray("AliAODVertex", 0));
185   AddObject(new TClonesArray("AliAODv0", 0));
186   AddObject(new AliAODTracklets());
187   AddObject(new TClonesArray("AliAODJet", 0));
188   AddObject(new AliAODCaloCells());
189   AddObject(new AliAODCaloCells());
190   AddObject(new TClonesArray("AliAODCaloCluster", 0));
191   AddObject(new TClonesArray("AliAODFmdCluster", 0));
192   AddObject(new TClonesArray("AliAODPmdCluster", 0));
193   // set names
194   SetStdNames();
195
196   // read back pointers
197   GetStdContent();
198   CreateStdFolders();
199   return;
200 }
201
202 void  AliAODEvent::MakeEntriesReferencable()
203 {
204     // Make all entries referencable in a subsequent process
205     //
206     TIter next(fAODObjects);
207     TObject* obj;
208     while ((obj = next()))
209     {
210         if(obj->InheritsFrom("TCollection"))
211             {
212                 AssignIDtoCollection((TCollection*)obj);
213             }
214     }
215 }
216
217 //______________________________________________________________________________
218 void AliAODEvent::SetStdNames()
219 {
220   // introduce the standard naming
221
222   if(fAODObjects->GetEntries()==kAODListN){
223     for(int i = 0;i < fAODObjects->GetEntries();i++){
224       TObject *fObj = fAODObjects->At(i);
225       if(fObj->InheritsFrom("TNamed")){
226         ((TNamed*)fObj)->SetName(fAODListName[i]);
227       }
228       else if(fObj->InheritsFrom("TClonesArray")){
229         ((TClonesArray*)fObj)->SetName(fAODListName[i]);
230       }
231     }
232   }
233   else{
234     printf("%s:%d SetStdNames() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__);
235   }
236
237
238 void AliAODEvent::CreateStdFolders()
239 {
240     // Create the standard folder structure
241     fAODFolder = gROOT->GetRootFolder()->AddFolder("AOD", "AOD");
242     if(fAODObjects->GetEntries()==kAODListN){
243         for(int i = 0;i < fAODObjects->GetEntries();i++){
244             TObject *fObj = fAODObjects->At(i);
245             if(fObj->InheritsFrom("TClonesArray")){
246                 fAODFolder->AddFolder(fAODListName[i], fAODListName[i], (TCollection*) fObj);
247             } else {
248                 fAODFolder->AddFolder(fAODListName[i], fAODListName[i], 0);
249             }
250         }
251     }
252     else{
253         printf("%s:%d CreateStdFolders() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__);
254     }
255
256
257 //______________________________________________________________________________
258 void AliAODEvent::GetStdContent()
259 {
260   // set pointers for standard content
261
262   fHeader        = (AliAODHeader*)fAODObjects->FindObject("header");
263   fTracks        = (TClonesArray*)fAODObjects->FindObject("tracks");
264   fVertices      = (TClonesArray*)fAODObjects->FindObject("vertices");
265   fV0s           = (TClonesArray*)fAODObjects->FindObject("v0s");
266   fTracklets     = (AliAODTracklets*)fAODObjects->FindObject("tracklets");
267   fJets          = (TClonesArray*)fAODObjects->FindObject("jets");
268   fEmcalCells    = (AliAODCaloCells*)fAODObjects->FindObject("emcalCells");
269   fPhosCells     = (AliAODCaloCells*)fAODObjects->FindObject("phosCells");
270   fCaloClusters  = (TClonesArray*)fAODObjects->FindObject("caloClusters");
271   fFmdClusters   = (TClonesArray*)fAODObjects->FindObject("fmdClusters");
272   fPmdClusters   = (TClonesArray*)fAODObjects->FindObject("pmdClusters");
273 }
274
275 //______________________________________________________________________________
276 void AliAODEvent::ResetStd(Int_t trkArrSize, 
277                            Int_t vtxArrSize, 
278                            Int_t v0ArrSize, 
279                            Int_t jetSize, 
280                            Int_t caloClusSize, 
281                            Int_t fmdClusSize, 
282                            Int_t pmdClusSize)
283 {
284   // deletes content of standard arrays and resets size 
285   fTracks->Delete();
286   if (trkArrSize > fTracks->GetSize()) 
287     fTracks->Expand(trkArrSize);
288
289   fVertices->Delete();
290   if (vtxArrSize > fVertices->GetSize()) 
291     fVertices->Expand(vtxArrSize);
292  
293   fV0s->Delete();
294   if (v0ArrSize > fV0s->GetSize()) 
295     fV0s->Expand(v0ArrSize);
296
297   fJets->Delete();
298   if (jetSize > fJets->GetSize()) 
299     fJets->Expand(jetSize);
300
301   fCaloClusters->Delete();
302   if (caloClusSize > fCaloClusters->GetSize()) 
303     fCaloClusters->Expand(caloClusSize);
304
305   fFmdClusters->Delete();
306   if (fmdClusSize > fFmdClusters->GetSize()) 
307     fFmdClusters->Expand(fmdClusSize);
308
309   fPmdClusters->Delete();
310   if (pmdClusSize > fPmdClusters->GetSize()) 
311     fPmdClusters->Expand(pmdClusSize);
312
313   // Reset the tracklets
314   fTracklets->DeleteContainer();
315   fPhosCells->DeleteContainer();  
316   fEmcalCells->DeleteContainer();
317
318 }
319
320 void AliAODEvent::ClearStd()
321 {
322   // clears the standard arrays
323   fTracks        ->Clear();
324   fVertices      ->Clear();
325   fV0s           ->Clear();
326   fTracklets     ->DeleteContainer();
327   fJets          ->Delete();
328   fEmcalCells    ->DeleteContainer();
329   fPhosCells     ->DeleteContainer();
330   fCaloClusters  ->Clear();
331   fFmdClusters   ->Clear();
332   fPmdClusters   ->Clear();
333 }
334
335 //_________________________________________________________________
336 Int_t AliAODEvent::GetPHOSClusters(TRefArray *clusters) const
337 {
338   // fills the provided TRefArray with all found phos clusters
339   
340   clusters->Clear();
341   
342   AliAODCaloCluster *cl = 0;
343   for (Int_t i = 0; i < GetNCaloClusters() ; i++) {
344     
345     if ( (cl = GetCaloCluster(i)) ) {
346       if (cl->IsPHOSCluster()){
347         clusters->Add(cl);
348         //AliDebug(1,Form("IsPHOS cluster %d Size: %d \n",i,clusters->GetEntriesFast()));
349       }
350     }
351   }
352   return clusters->GetEntriesFast();
353 }
354
355 //_________________________________________________________________
356 Int_t AliAODEvent::GetEMCALClusters(TRefArray *clusters) const
357 {
358   // fills the provided TRefArray with all found emcal clusters
359
360   clusters->Clear();
361
362   AliAODCaloCluster *cl = 0;
363   for (Int_t i = 0; i < GetNCaloClusters(); i++) {
364
365     if ( (cl = GetCaloCluster(i)) ) {
366       if (cl->IsEMCALCluster()){
367         clusters->Add(cl);
368         //AliDebug(1,Form("IsEMCAL cluster %d Size: %d \n",i,clusters->GetEntriesFast()));
369       }
370     }
371   }
372   return clusters->GetEntriesFast();
373 }
374
375
376 //______________________________________________________________________________
377 Int_t AliAODEvent::GetMuonTracks(TRefArray *muonTracks) const
378 {
379   // fills the provided TRefArray with all found muon tracks
380
381   muonTracks->Clear();
382
383   AliAODTrack *track = 0;
384   for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
385     if ((track = GetTrack(iTrack))->IsMuonTrack()) {
386       muonTracks->Add(track);
387     }
388   }
389   
390   return muonTracks->GetEntriesFast();
391 }
392
393
394 void AliAODEvent::ReadFromTree(TTree *tree, Option_t* opt /*= ""*/)
395 {
396   // Connects aod event to tree
397   
398   if(!tree){
399     Printf("%s %d AliAODEvent::ReadFromTree() Zero Pointer to Tree \n",(char*)__FILE__,__LINE__);
400     return;
401   }
402   // load the TTree
403   if(!tree->GetTree())tree->LoadTree(0);
404
405   // Try to find AliAODEvent
406   AliAODEvent *aodEvent = 0;
407   aodEvent = (AliAODEvent*)tree->GetTree()->GetUserInfo()->FindObject("AliAODEvent");
408   if(aodEvent){
409     // Check if already connected to tree
410     TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("AODObjectsConnectedToTree"));
411     if (connectedList && (strcmp(opt, "reconnect"))) {
412         // If connected use the connected list if objects
413         fAODObjects->Delete();
414         fAODObjects = connectedList;
415         GetStdContent(); 
416         return;
417     }
418     // Connect to tree
419     // prevent a memory leak when reading back the TList
420     delete fAODObjects;
421     fAODObjects = 0;
422     // create a new TList from the UserInfo TList... 
423     // copy constructor does not work...
424     fAODObjects = (TList*)(aodEvent->GetList()->Clone());
425     fAODObjects->SetOwner(kFALSE);
426     if(fAODObjects->GetEntries()<kAODListN){
427       printf("%s %d AliAODEvent::ReadFromTree() TList contains less than the standard contents %d < %d \n",
428              (char*)__FILE__,__LINE__,fAODObjects->GetEntries(),kAODListN);
429     }
430     //
431     // Let's find out whether we have friends
432     TList* friendL = tree->GetTree()->GetListOfFriends();
433     if (friendL) 
434     {
435         TIter next(friendL);
436         TFriendElement* fe;
437         while ((fe = (TFriendElement*)next())){
438             aodEvent = (AliAODEvent*)(fe->GetTree()->GetUserInfo()->FindObject("AliAODEvent"));
439             if (!aodEvent) {
440                 printf("No UserInfo on tree \n");
441             } else {
442
443                 TList* objL = (TList*)(aodEvent->GetList()->Clone());
444                 printf("Get list of object from tree %d !!\n", objL->GetEntries());
445                 TIter nextobject(objL);
446                 TObject* obj =  0;
447                 while((obj = nextobject()))
448                 {
449                     printf("Adding object from friend %s !\n", obj->GetName());
450                     fAODObjects->Add(obj);
451                 } // object "branch" loop
452             } // has userinfo  
453         } // friend loop
454     } // has friends    
455             
456
457 // set the branch addresses
458     TIter next(fAODObjects);
459     TNamed *el;
460     while((el=(TNamed*)next())){
461       TString bname(el->GetName());
462       // check if branch exists under this Name
463       TBranch *br = tree->GetTree()->GetBranch(bname.Data());
464       if(br){
465         tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
466       } else {
467           br = tree->GetBranch(Form("%s.",bname.Data()));
468           if(br){
469               tree->SetBranchAddress(Form("%s.",bname.Data()),fAODObjects->GetObjectRef(el));
470           }
471           else{
472               printf("%s %d AliAODEvent::ReadFromTree() No Branch found with Name %s. \n",
473                      (char*)__FILE__,__LINE__,bname.Data());
474           }     
475       }
476     }
477     GetStdContent();
478     // when reading back we are not owner of the list 
479     // must not delete it
480     fAODObjects->SetOwner(kFALSE);
481     fAODObjects->SetName("AODObjectsConnectedToTree");
482     // we are not owner of the list objects 
483     // must not delete it
484     tree->GetUserInfo()->Add(fAODObjects);
485   }// no aodEvent
486   else {
487     // we can't get the list from the user data, create standard content
488     // and set it by hand
489     CreateStdContent();
490     TIter next(fAODObjects);
491     TNamed *el;
492     while((el=(TNamed*)next())){
493       TString bname(el->GetName());    
494       tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
495     }
496     GetStdContent();
497     // when reading back we are not owner of the list 
498     // must not delete it
499     fAODObjects->SetOwner(kFALSE);
500   }
501 }
502
503 //______________________________________________________________________________
504 void AliAODEvent::Print(Option_t *) const
505 {
506   // Something meaningful should be implemented here.
507   
508   return;
509 }
510
511 void AliAODEvent::AssignIDtoCollection(TCollection* col)
512 {
513     // Static method which assigns a ID to each object in a collection
514     // In this way the objects are marked as referenced and written with 
515     // an ID. This has the advantage that TRefs to this objects can be 
516     // written by a subsequent process.
517     TIter next(col);
518     TObject* obj;
519     while ((obj = next()))
520         TProcessID::AssignID(obj);
521 }