Provide methods to make AOD objects "referencable" in a separate process, i.e.
[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::GetMuonTracks(TRefArray *muonTracks) const
337 {
338   // fills the provided TRefArray with all found muon tracks
339
340   muonTracks->Clear();
341
342   AliAODTrack *track = 0;
343   for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
344     if ((track = GetTrack(iTrack))->IsMuonTrack()) {
345       muonTracks->Add(track);
346     }
347   }
348   
349   return muonTracks->GetEntriesFast();
350 }
351
352
353 void AliAODEvent::ReadFromTree(TTree *tree)
354 {
355   // connects aod event to tree
356   
357   if(!tree){
358     Printf("%s %d AliAODEvent::ReadFromTree() Zero Pointer to Tree \n",(char*)__FILE__,__LINE__);
359     return;
360   }
361   // load the TTree
362   if(!tree->GetTree())tree->LoadTree(0);
363
364   // Try to find AliAODEvent
365   AliAODEvent *aodEvent = 0;
366   aodEvent = (AliAODEvent*)tree->GetTree()->GetUserInfo()->FindObject("AliAODEvent");
367   if(aodEvent){
368     // Check if already connected to tree
369     TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("AODObjectsConnectedToTree"));
370     if (connectedList) {
371       // If connected use the connected list if objects
372       fAODObjects->Delete();
373       fAODObjects = connectedList;
374       GetStdContent(); 
375       return;
376     }
377     // Connect to tree
378     // prevent a memory leak when reading back the TList
379     delete fAODObjects;
380     fAODObjects = 0;
381     // create a new TList from the UserInfo TList... 
382     // copy constructor does not work...
383     fAODObjects = (TList*)(aodEvent->GetList()->Clone());
384     fAODObjects->SetOwner(kFALSE);
385     if(fAODObjects->GetEntries()<kAODListN){
386       printf("%s %d AliAODEvent::ReadFromTree() TList contains less than the standard contents %d < %d \n",
387              (char*)__FILE__,__LINE__,fAODObjects->GetEntries(),kAODListN);
388     }
389     //
390     // Let's find out whether we have friends
391     TList* friendL = tree->GetListOfFriends();
392     if (friendL) 
393     {
394         TIter next(friendL);
395         TFriendElement* fe;
396         while ((fe = (TFriendElement*)next())){
397             aodEvent = (AliAODEvent*)(fe->GetTree()->GetUserInfo()->FindObject("AliAODEvent"));
398             if (!aodEvent) {
399                 printf("No UserInfo on tree \n");
400             } else {
401
402                 TList* objL = (TList*)(aodEvent->GetList()->Clone());
403                 printf("Get list of object from tree %d !!\n", objL->GetEntries());
404                 TIter nextobject(objL);
405                 TObject* obj =  0;
406                 while(obj = nextobject())
407                 {
408                     printf("Adding object from friend %s !\n", obj->GetName());
409                     fAODObjects->Add(obj);
410                 } // object "branch" loop
411             } // has userinfo  
412         } // friend loop
413     } // has friends    
414             
415
416 // set the branch addresses
417     TIter next(fAODObjects);
418     TNamed *el;
419     while((el=(TNamed*)next())){
420       TString bname(el->GetName());
421       // check if branch exists under this Name
422       TBranch *br = tree->GetBranch(bname.Data());
423       if(br){
424         tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
425       }
426       else{
427           br = tree->GetBranch(Form("%s.",bname.Data()));
428           if(br){
429               tree->SetBranchAddress(Form("%s.",bname.Data()),fAODObjects->GetObjectRef(el));
430           }
431           else{
432               printf("%s %d AliAODEvent::ReadFromTree() No Branch found with Name %s. \n",
433                      (char*)__FILE__,__LINE__,bname.Data());
434           }     
435       }
436     }
437     GetStdContent();
438     // when reading back we are not owner of the list 
439     // must not delete it
440     fAODObjects->SetOwner(kFALSE);
441     fAODObjects->SetName("AODObjectsConnectedToTree");
442     // we are not owner of the list objects 
443     // must not delete it
444     tree->GetUserInfo()->Add(fAODObjects);
445   }// no aodEvent
446   else {
447     // we can't get the list from the user data, create standard content
448     // and set it by hand
449     CreateStdContent();
450     TIter next(fAODObjects);
451     TNamed *el;
452     while((el=(TNamed*)next())){
453       TString bname(el->GetName());    
454       tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
455     }
456     GetStdContent();
457     // when reading back we are not owner of the list 
458     // must not delete it
459     fAODObjects->SetOwner(kFALSE);
460   }
461 }
462
463 //______________________________________________________________________________
464 void AliAODEvent::Print(Option_t *) const
465 {
466   // Something meaningful should be implemented here.
467   
468   return;
469 }
470
471 void AliAODEvent::AssignIDtoCollection(TCollection* col)
472 {
473     // Static method which assigns a ID to each object in a collection
474     // In this way the objects are marked as referenced and written with 
475     // an ID. This has the advantage that TRefs to this objects can be 
476     // written by a subsequent process.
477     TIter next(col);
478     TObject* obj;
479     while (obj = next())
480         TProcessID::AssignID(obj);
481 }