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