]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliAODEvent.cxx
Dimuon branch in AODEvent
[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)
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 void AliAODEvent::ReadFromTree(TTree *tree, Option_t* opt /*= ""*/)
495 {
496   // Connects aod event to tree
497   
498   if(!tree){
499     Printf("%s %d AliAODEvent::ReadFromTree() Zero Pointer to Tree \n",(char*)__FILE__,__LINE__);
500     return;
501   }
502   // load the TTree
503   if(!tree->GetTree())tree->LoadTree(0);
504
505   // Try to find AliAODEvent
506   AliAODEvent *aodEvent = 0;
507   aodEvent = (AliAODEvent*)tree->GetTree()->GetUserInfo()->FindObject("AliAODEvent");
508   if(aodEvent){
509     // Check if already connected to tree
510     TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("AODObjectsConnectedToTree"));
511     if (connectedList && (strcmp(opt, "reconnect"))) {
512         // If connected use the connected list of objects
513         fAODObjects->Delete();
514         fAODObjects = connectedList;
515         GetStdContent(); 
516         fConnected = kTRUE;
517         return;
518     } 
519     // Connect to tree
520     // prevent a memory leak when reading back the TList
521     // if (!(strcmp(opt, "reconnect"))) fAODObjects->Delete();
522
523     // create a new TList from the UserInfo TList... 
524     // copy constructor does not work...
525     fAODObjects = (TList*)(aodEvent->GetList()->Clone());
526     fAODObjects->SetOwner(kTRUE);
527     if(fAODObjects->GetEntries()<kAODListN){
528       printf("%s %d AliAODEvent::ReadFromTree() TList contains less than the standard contents %d < %d \n",
529              (char*)__FILE__,__LINE__,fAODObjects->GetEntries(),kAODListN);
530     }
531     //
532     // Let's find out whether we have friends
533     TList* friendL = tree->GetTree()->GetListOfFriends();
534     if (friendL) 
535     {
536         TIter next(friendL);
537         TFriendElement* fe;
538         while ((fe = (TFriendElement*)next())){
539             aodEvent = (AliAODEvent*)(fe->GetTree()->GetUserInfo()->FindObject("AliAODEvent"));
540             if (!aodEvent) {
541                 printf("No UserInfo on tree \n");
542             } else {
543
544                 TList* objL = (TList*)(aodEvent->GetList()->Clone());
545                 printf("Get list of object from tree %d !!\n", objL->GetEntries());
546                 TIter nextobject(objL);
547                 TObject* obj =  0;
548                 while((obj = nextobject()))
549                 {
550                     printf("Adding object from friend %s !\n", obj->GetName());
551                     fAODObjects->Add(obj);
552                 } // object "branch" loop
553             } // has userinfo  
554         } // friend loop
555     } // has friends    
556             
557
558 // set the branch addresses
559     TIter next(fAODObjects);
560     TNamed *el;
561     while((el=(TNamed*)next())){
562       TString bname(el->GetName());
563       // check if branch exists under this Name
564       TBranch *br = tree->GetTree()->GetBranch(bname.Data());
565       if(br){
566         tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
567       } else {
568           br = tree->GetBranch(Form("%s.",bname.Data()));
569           if(br){
570               tree->SetBranchAddress(Form("%s.",bname.Data()),fAODObjects->GetObjectRef(el));
571           }
572           else{
573               printf("%s %d AliAODEvent::ReadFromTree() No Branch found with Name %s. \n",
574                      (char*)__FILE__,__LINE__,bname.Data());
575           }     
576       }
577     }
578     GetStdContent();
579     // when reading back we are not owner of the list 
580     // must not delete it
581     fAODObjects->SetOwner(kTRUE);
582     fAODObjects->SetName("AODObjectsConnectedToTree");
583     // we are not owner of the list objects 
584     // must not delete it
585     tree->GetUserInfo()->Add(fAODObjects);
586     fConnected = kTRUE;
587   }// no aodEvent
588   else {
589     // we can't get the list from the user data, create standard content
590     // and set it by hand
591     CreateStdContent();
592     TIter next(fAODObjects);
593     TNamed *el;
594     while((el=(TNamed*)next())){
595       TString bname(el->GetName());    
596       tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
597     }
598     GetStdContent();
599     // when reading back we are not owner of the list 
600     // must not delete it
601     fAODObjects->SetOwner(kTRUE);
602   }
603 }
604
605 //______________________________________________________________________________
606 void AliAODEvent::Print(Option_t *) const
607 {
608   // Print the names of the all branches
609   TIter next(fAODObjects);
610   TNamed *el;
611   Printf(">>>>>  AOD  Content <<<<<");    
612   while((el=(TNamed*)next())){
613     Printf(">> %s ",el->GetName());      
614   }
615   Printf(">>>>>                <<<<<");    
616   
617   return;
618 }
619
620 void AliAODEvent::AssignIDtoCollection(TCollection* col)
621 {
622     // Static method which assigns a ID to each object in a collection
623     // In this way the objects are marked as referenced and written with 
624     // an ID. This has the advantage that TRefs to this objects can be 
625     // written by a subsequent process.
626     TIter next(col);
627     TObject* obj;
628     while ((obj = next()))
629         TProcessID::AssignID(obj);
630 }