]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliAODEvent.cxx
Fix for report #64208 Missing OCDB (GRP/Calib/MeanVertex) object in GRP
[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 #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                                                       
52 };
53 //______________________________________________________________________________
54 AliAODEvent::AliAODEvent() :
55   AliVEvent(),
56   fAODObjects(new TList()),
57   fAODFolder(0),
58   fConnected(kFALSE),
59   fHeader(0),
60   fTracks(0),
61   fVertices(0),
62   fV0s(0),
63   fCascades(0),
64   fTracklets(0),
65   fJets(0),
66   fEmcalCells(0),
67   fPhosCells(0),
68   fCaloClusters(0),
69   fFmdClusters(0),
70   fPmdClusters(0),
71   fDimuons(0)
72 {
73   // default constructor
74 }
75
76 //______________________________________________________________________________
77 AliAODEvent::AliAODEvent(const AliAODEvent& aod):
78   AliVEvent(aod),
79   fAODObjects(new TList()),
80   fAODFolder(new TFolder()),
81   fConnected(kFALSE),
82   fHeader(new AliAODHeader(*aod.fHeader)),
83   fTracks(new TClonesArray(*aod.fTracks)),
84   fVertices(new TClonesArray(*aod.fVertices)),
85   fV0s(new TClonesArray(*aod.fV0s)),
86   fCascades(new TClonesArray(*aod.fCascades)),
87   fTracklets(new AliAODTracklets(*aod.fTracklets)),
88   fJets(new TClonesArray(*aod.fJets)),
89   fEmcalCells(new AliAODCaloCells(*aod.fEmcalCells)),
90   fPhosCells(new AliAODCaloCells(*aod.fPhosCells)),
91   fCaloClusters(new TClonesArray(*aod.fCaloClusters)),
92   fFmdClusters(new TClonesArray(*aod.fFmdClusters)),
93   fPmdClusters(new TClonesArray(*aod.fPmdClusters)),
94   fDimuons(new TClonesArray(*aod.fDimuons))
95 {
96   // Copy constructor
97   AddObject(fHeader);
98   AddObject(fTracks);
99   AddObject(fVertices);
100   AddObject(fV0s);
101   AddObject(fCascades);
102   AddObject(fTracklets);
103   AddObject(fJets);
104   AddObject(fEmcalCells);
105   AddObject(fPhosCells);
106   AddObject(fCaloClusters);
107   AddObject(fFmdClusters);
108   AddObject(fPmdClusters);
109   AddObject(fDimuons);
110   fConnected = aod.fConnected;
111   GetStdContent();
112   CreateStdFolders();
113 }
114
115 //______________________________________________________________________________
116 AliAODEvent & AliAODEvent::operator=(const AliAODEvent& aod) {
117
118     // Assignment operator
119
120   if(&aod == this) return *this;
121   AliVEvent::operator=(aod);
122
123   // This assumes that the list is already created
124   // and that the virtual void Copy(Tobject&) function
125   // is correctly implemented in the derived class
126   // otherwise only TObject::Copy() will be used
127
128   if((fAODObjects->GetSize()==0)&&(aod.fAODObjects->GetSize()>=kAODListN)){
129     // We cover the case that we do not yet have the 
130     // standard content but the source has it
131     CreateStdContent();
132   }
133   
134   // Here we have the standard content without user additions, but the content is 
135   // not matching the aod source.
136   
137   // Iterate the list of source objects
138   TIter next(aod.GetList());
139   TObject *its = 0;
140   TString name;
141   while ((its = next())) {
142     name = its->GetName();
143     // Check if we have this object type in out list
144     TObject *mine = fAODObjects->FindObject(name);    
145     if(!mine) {
146       // We have to create the same type of object.
147       TClass* pClass=TClass::GetClass(its->ClassName());     
148       if (!pClass) {
149         AliWarning(Form("Can not find class description for entry %s (%s)\n",
150                    its->ClassName(), name.Data()));
151         continue;
152       }
153       mine=(TObject*)pClass->New();
154       if(!mine){
155         // not in this: can be added to list
156         AliWarning(Form("%s:%d Could not find %s for copying \n",
157                    (char*)__FILE__,__LINE__,name.Data()));
158         continue;
159       }  
160       if(mine->InheritsFrom("TNamed"))  {
161         ((TNamed*)mine)->SetName(name);
162       } else if(mine->InheritsFrom("TCollection")){
163         if(mine->InheritsFrom("TClonesArray")) {
164           TClonesArray *itscl = dynamic_cast<TClonesArray*>(its);
165           if (!itscl) {
166             AliWarning(Form("Class description for entry %s (%s) not TClonesArray\n",
167                    its->ClassName(), name.Data()));
168             continue;
169           
170           }
171                dynamic_cast<TClonesArray*>(mine)->SetClass(itscl->GetClass(), itscl->GetSize());
172         }
173         dynamic_cast<TCollection*>(mine)->SetName(name);
174       }
175       AliDebug(1, Form("adding object %s of type %s", mine->GetName(), mine->ClassName()));
176       AddObject(mine);
177     }
178     // Now we have an object of the same type and name, but different content.        
179     if(!its->InheritsFrom("TCollection")){
180       // simple objects (do they have a Copy method that calls operator= ?)
181       its->Copy(*mine);
182     } else if (its->InheritsFrom("TClonesArray")) {
183       // Create or expand the tclonesarray pointers
184       // so we can directly copy to the object
185       TClonesArray *its_tca = (TClonesArray*)its;
186       TClonesArray *mine_tca = (TClonesArray*)mine;
187       // this leaves the capacity of the TClonesArray the same
188       // except for a factor of 2 increase when size > capacity
189       // does not release any memory occupied by the tca
190       Int_t its_entries = its_tca->GetEntriesFast();
191       mine_tca->ExpandCreate(its_entries);
192       for(int i=0; i<its_entries; i++){
193         // copy 
194         TObject *mine_tca_obj = mine_tca->At(i);
195         TObject *its_tca_obj = its_tca->At(i);
196         // no need to delete first
197         // pointers within the class should be handled by Copy()...
198         // Can there be Empty slots?
199         its_tca_obj->Copy(*mine_tca_obj);
200       }
201     } else {
202       AliWarning(Form("%s:%d cannot copy TCollection \n",
203                       (char*)__FILE__,__LINE__));
204     }
205   }  
206   fConnected = aod.fConnected;
207   return *this;
208 }
209
210
211 //______________________________________________________________________________
212 AliAODEvent::~AliAODEvent() 
213 {
214 // destructor
215     if(fAODObjects&&!fConnected)
216     {
217         delete fAODObjects;
218         fAODObjects = 0;
219     }
220
221     delete fAODFolder;
222 }
223
224 //______________________________________________________________________________
225 void AliAODEvent::AddObject(TObject* obj) 
226 {
227   // Add an object to the list of objects.
228   // Please be aware that in order to increase performance you should
229   // refrain from using TObjArrays (if possible). Use TClonesArrays, instead.
230   
231   fAODObjects->AddLast(obj);
232 }
233
234 //______________________________________________________________________________
235 void AliAODEvent::RemoveObject(TObject* obj) 
236 {
237   // Removes an object from the list of objects.
238   
239   fAODObjects->Remove(obj);
240 }
241
242 //______________________________________________________________________________
243 TObject *AliAODEvent::FindListObject(const char *objName) const
244 {
245   // Return the pointer to the object with the given name.
246
247   return fAODObjects->FindObject(objName);
248 }
249
250 //______________________________________________________________________________
251 void AliAODEvent::CreateStdContent() 
252 {
253   // create the standard AOD content and set pointers
254
255   // create standard objects and add them to the TList of objects
256   AddObject(new AliAODHeader());
257   AddObject(new TClonesArray("AliAODTrack", 0));
258   AddObject(new TClonesArray("AliAODVertex", 0));
259   AddObject(new TClonesArray("AliAODv0", 0));
260   AddObject(new TClonesArray("AliAODcascade", 0));
261   AddObject(new AliAODTracklets());
262   AddObject(new TClonesArray("AliAODJet", 0));
263   AddObject(new AliAODCaloCells());
264   AddObject(new AliAODCaloCells());
265   AddObject(new TClonesArray("AliAODCaloCluster", 0));
266   AddObject(new TClonesArray("AliAODFmdCluster", 0));
267   AddObject(new TClonesArray("AliAODPmdCluster", 0));
268   AddObject(new TClonesArray("AliAODDimuon", 0));
269   // set names
270   SetStdNames();
271
272   // read back pointers
273   GetStdContent();
274   CreateStdFolders();
275   return;
276 }
277
278 void  AliAODEvent::MakeEntriesReferencable()
279 {
280     // Make all entries referencable in a subsequent process
281     //
282     TIter next(fAODObjects);
283     TObject* obj;
284     while ((obj = next()))
285     {
286         if(obj->InheritsFrom("TCollection"))
287             {
288                 AssignIDtoCollection((TCollection*)obj);
289             }
290     }
291 }
292
293 //______________________________________________________________________________
294 void AliAODEvent::SetStdNames()
295 {
296   // introduce the standard naming
297
298   if(fAODObjects->GetEntries()==kAODListN){
299     for(int i = 0;i < fAODObjects->GetEntries();i++){
300       TObject *fObj = fAODObjects->At(i);
301       if(fObj->InheritsFrom("TNamed")){
302         ((TNamed*)fObj)->SetName(fAODListName[i]);
303       }
304       else if(fObj->InheritsFrom("TClonesArray")){
305         ((TClonesArray*)fObj)->SetName(fAODListName[i]);
306       }
307     }
308   }
309   else{
310     printf("%s:%d SetStdNames() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__);
311   }
312
313
314 void AliAODEvent::CreateStdFolders()
315 {
316     // Create the standard folder structure
317     fAODFolder = gROOT->GetRootFolder()->AddFolder("AOD", "AOD");
318     if(fAODObjects->GetEntries()==kAODListN){
319         for(int i = 0;i < fAODObjects->GetEntries();i++){
320             TObject *fObj = fAODObjects->At(i);
321             if(fObj->InheritsFrom("TClonesArray")){
322                 fAODFolder->AddFolder(fAODListName[i], fAODListName[i], (TCollection*) fObj);
323             } else {
324                 fAODFolder->AddFolder(fAODListName[i], fAODListName[i], 0);
325             }
326         }
327     }
328     else{
329         printf("%s:%d CreateStdFolders() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__);
330     }
331
332
333 //______________________________________________________________________________
334 void AliAODEvent::GetStdContent()
335 {
336   // set pointers for standard content
337
338   fHeader        = (AliAODHeader*)fAODObjects->FindObject("header");
339   fTracks        = (TClonesArray*)fAODObjects->FindObject("tracks");
340   fVertices      = (TClonesArray*)fAODObjects->FindObject("vertices");
341   fV0s           = (TClonesArray*)fAODObjects->FindObject("v0s");
342   fCascades      = (TClonesArray*)fAODObjects->FindObject("cascades");
343   fTracklets     = (AliAODTracklets*)fAODObjects->FindObject("tracklets");
344   fJets          = (TClonesArray*)fAODObjects->FindObject("jets");
345   fEmcalCells    = (AliAODCaloCells*)fAODObjects->FindObject("emcalCells");
346   fPhosCells     = (AliAODCaloCells*)fAODObjects->FindObject("phosCells");
347   fCaloClusters  = (TClonesArray*)fAODObjects->FindObject("caloClusters");
348   fFmdClusters   = (TClonesArray*)fAODObjects->FindObject("fmdClusters");
349   fPmdClusters   = (TClonesArray*)fAODObjects->FindObject("pmdClusters");
350   fDimuons       = (TClonesArray*)fAODObjects->FindObject("dimuons");
351 }
352
353 //______________________________________________________________________________
354 void AliAODEvent::ResetStd(Int_t trkArrSize, 
355                            Int_t vtxArrSize, 
356                            Int_t v0ArrSize,
357                            Int_t cascadeArrSize,
358                            Int_t jetSize, 
359                            Int_t caloClusSize, 
360                            Int_t fmdClusSize, 
361                            Int_t pmdClusSize,
362                            Int_t dimuonArrSize
363                            )
364 {
365   // deletes content of standard arrays and resets size 
366   
367   fTracks->Delete();
368   if (trkArrSize > fTracks->GetSize()) 
369     fTracks->Expand(trkArrSize);
370
371   fVertices->Delete();
372   if (vtxArrSize > fVertices->GetSize()) 
373     fVertices->Expand(vtxArrSize);
374          
375   fV0s->Delete();
376   if (v0ArrSize > fV0s->GetSize()) 
377     fV0s->Expand(v0ArrSize);
378   
379   fCascades->Delete();
380   if (cascadeArrSize > fCascades->GetSize()) 
381     fCascades->Expand(cascadeArrSize);
382   
383   fJets->Delete();
384   if (jetSize > fJets->GetSize())
385     fJets->Expand(jetSize);
386
387   fCaloClusters->Delete();
388   if (caloClusSize > fCaloClusters->GetSize()) 
389     fCaloClusters->Expand(caloClusSize);
390
391   fFmdClusters->Delete();
392   if (fmdClusSize > fFmdClusters->GetSize()) 
393     fFmdClusters->Expand(fmdClusSize);
394
395   fPmdClusters->Delete();
396   if (pmdClusSize > fPmdClusters->GetSize()) 
397     fPmdClusters->Expand(pmdClusSize);
398     
399   fDimuons->Delete();
400   if (dimuonArrSize > fDimuons->GetSize()) 
401     fDimuons->Expand(dimuonArrSize);
402
403   // Reset the tracklets
404   fTracklets->DeleteContainer();
405   fPhosCells->DeleteContainer();  
406   fEmcalCells->DeleteContainer();
407
408 }
409
410 void AliAODEvent::ClearStd()
411 {
412   // clears the standard arrays
413   fHeader        ->RemoveQTheta();
414   fTracks        ->Delete();
415   fVertices      ->Delete();
416   fV0s           ->Delete();
417   fCascades      ->Delete();
418   fTracklets     ->DeleteContainer();
419   fJets          ->Delete();
420   fEmcalCells    ->DeleteContainer();
421   fPhosCells     ->DeleteContainer();
422   fCaloClusters  ->Delete();
423   fFmdClusters   ->Clear();
424   fPmdClusters   ->Clear();
425   fDimuons       ->Clear();
426 }
427
428 //_________________________________________________________________
429 Int_t AliAODEvent::GetPHOSClusters(TRefArray *clusters) const
430 {
431   // fills the provided TRefArray with all found phos clusters
432   
433   clusters->Clear();
434   
435   AliAODCaloCluster *cl = 0;
436   Bool_t first = kTRUE;
437   for (Int_t i = 0; i < GetNCaloClusters() ; i++) {
438     if ( (cl = GetCaloCluster(i)) ) {
439       if (cl->IsPHOSCluster()){
440         if(first) {
441           new (clusters) TRefArray(TProcessID::GetProcessWithUID(cl)); 
442           first=kFALSE;
443         }
444         clusters->Add(cl);
445         //printf("IsPHOS cluster %d, E %2.3f Size: %d \n",i,cl->E(),clusters->GetEntriesFast());
446       }
447     }
448   }
449   return clusters->GetEntriesFast();
450 }
451
452 //_________________________________________________________________
453 Int_t AliAODEvent::GetEMCALClusters(TRefArray *clusters) const
454 {
455   // fills the provided TRefArray with all found emcal clusters
456
457   clusters->Clear();
458   AliAODCaloCluster *cl = 0;
459   Bool_t first = kTRUE;
460   for (Int_t i = 0; i < GetNCaloClusters(); i++) {
461     if ( (cl = GetCaloCluster(i)) ) {
462       if (cl->IsEMCALCluster()){
463         if(first) {
464           new (clusters) TRefArray(TProcessID::GetProcessWithUID(cl)); 
465           first=kFALSE;
466         }
467         clusters->Add(cl);
468         //printf("IsEMCal cluster %d, E %2.3f Size: %d \n",i,cl->E(),clusters->GetEntriesFast());
469       }
470     }
471   }
472   return clusters->GetEntriesFast();
473 }
474
475
476 //______________________________________________________________________________
477 Int_t AliAODEvent::GetMuonTracks(TRefArray *muonTracks) const
478 {
479   // fills the provided TRefArray with all found muon tracks
480
481   muonTracks->Clear();
482
483   AliAODTrack *track = 0;
484   for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
485     if ((track = GetTrack(iTrack))->IsMuonTrack()) {
486       muonTracks->Add(track);
487     }
488   }
489   
490   return muonTracks->GetEntriesFast();
491 }
492
493
494 //______________________________________________________________________________
495 Int_t AliAODEvent::GetNumberOfMuonTracks() const
496 {
497   // get number of muon tracks
498   Int_t nMuonTracks=0;
499   AliAODTrack *track = 0;
500   for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
501     if ((track = GetTrack(iTrack))->IsMuonTrack()) {
502        nMuonTracks++;
503     }
504   }
505   
506   return nMuonTracks;
507 }
508
509 void AliAODEvent::ReadFromTree(TTree *tree, Option_t* opt /*= ""*/)
510 {
511   // Connects aod event to tree
512   
513   if(!tree){
514     Printf("%s %d AliAODEvent::ReadFromTree() Zero Pointer to Tree \n",(char*)__FILE__,__LINE__);
515     return;
516   }
517   // load the TTree
518   if(!tree->GetTree())tree->LoadTree(0);
519
520   // Try to find AliAODEvent
521   AliAODEvent *aodEvent = 0;
522   aodEvent = (AliAODEvent*)tree->GetTree()->GetUserInfo()->FindObject("AliAODEvent");
523   if(aodEvent){
524     // Check if already connected to tree
525     TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("AODObjectsConnectedToTree"));
526     if (connectedList && (strcmp(opt, "reconnect"))) {
527         // If connected use the connected list of objects
528         fAODObjects->Delete();
529         fAODObjects = connectedList;
530         GetStdContent(); 
531         fConnected = kTRUE;
532         return;
533     } 
534     // Connect to tree
535     // prevent a memory leak when reading back the TList
536     // if (!(strcmp(opt, "reconnect"))) fAODObjects->Delete();
537
538     // create a new TList from the UserInfo TList... 
539     // copy constructor does not work...
540     fAODObjects = (TList*)(aodEvent->GetList()->Clone());
541     fAODObjects->SetOwner(kTRUE);
542     if(fAODObjects->GetEntries()<kAODListN){
543       printf("%s %d AliAODEvent::ReadFromTree() TList contains less than the standard contents %d < %d \n",
544              (char*)__FILE__,__LINE__,fAODObjects->GetEntries(),kAODListN);
545     }
546     //
547     // Let's find out whether we have friends
548     TList* friendL = tree->GetTree()->GetListOfFriends();
549     if (friendL) 
550     {
551         TIter next(friendL);
552         TFriendElement* fe;
553         while ((fe = (TFriendElement*)next())){
554             aodEvent = (AliAODEvent*)(fe->GetTree()->GetUserInfo()->FindObject("AliAODEvent"));
555             if (!aodEvent) {
556                 printf("No UserInfo on tree \n");
557             } else {
558
559                 TList* objL = (TList*)(aodEvent->GetList()->Clone());
560                 printf("Get list of object from tree %d !!\n", objL->GetEntries());
561                 TIter nextobject(objL);
562                 TObject* obj =  0;
563                 while((obj = nextobject()))
564                 {
565                     printf("Adding object from friend %s !\n", obj->GetName());
566                     fAODObjects->Add(obj);
567                 } // object "branch" loop
568             } // has userinfo  
569         } // friend loop
570     } // has friends    
571             
572
573 // set the branch addresses
574     TIter next(fAODObjects);
575     TNamed *el;
576     while((el=(TNamed*)next())){
577       TString bname(el->GetName());
578       // check if branch exists under this Name
579       TBranch *br = tree->GetTree()->GetBranch(bname.Data());
580       if(br){
581         tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
582       } else {
583           br = tree->GetBranch(Form("%s.",bname.Data()));
584           if(br){
585               tree->SetBranchAddress(Form("%s.",bname.Data()),fAODObjects->GetObjectRef(el));
586           }
587           else{
588               printf("%s %d AliAODEvent::ReadFromTree() No Branch found with Name %s. \n",
589                      (char*)__FILE__,__LINE__,bname.Data());
590           }     
591       }
592     }
593     GetStdContent();
594     // when reading back we are not owner of the list 
595     // must not delete it
596     fAODObjects->SetOwner(kTRUE);
597     fAODObjects->SetName("AODObjectsConnectedToTree");
598     // we are not owner of the list objects 
599     // must not delete it
600     tree->GetUserInfo()->Add(fAODObjects);
601     fConnected = kTRUE;
602   }// no aodEvent
603   else {
604     // we can't get the list from the user data, create standard content
605     // and set it by hand
606     CreateStdContent();
607     TIter next(fAODObjects);
608     TNamed *el;
609     while((el=(TNamed*)next())){
610       TString bname(el->GetName());    
611       tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
612     }
613     GetStdContent();
614     // when reading back we are not owner of the list 
615     // must not delete it
616     fAODObjects->SetOwner(kTRUE);
617   }
618 }
619
620 //______________________________________________________________________________
621 void AliAODEvent::Print(Option_t *) const
622 {
623   // Print the names of the all branches
624   TIter next(fAODObjects);
625   TNamed *el;
626   Printf(">>>>>  AOD  Content <<<<<");    
627   while((el=(TNamed*)next())){
628     Printf(">> %s ",el->GetName());      
629   }
630   Printf(">>>>>                <<<<<");    
631   
632   return;
633 }
634
635 void AliAODEvent::AssignIDtoCollection(TCollection* col)
636 {
637     // Static method which assigns a ID to each object in a collection
638     // In this way the objects are marked as referenced and written with 
639     // an ID. This has the advantage that TRefs to this objects can be 
640     // written by a subsequent process.
641     TIter next(col);
642     TObject* obj;
643     while ((obj = next()))
644         TProcessID::AssignID(obj);
645 }