]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AOD/AliAODExtension.cxx
add new data members, move members to the correlation class to the base one, and...
[u/mrichter/AliRoot.git] / STEER / AOD / AliAODExtension.cxx
1 #include "AliAODExtension.h"
2
3 //-------------------------------------------------------------------------
4 //     Support class for AOD extensions. This is created by the user analysis
5 //     that requires a separate file for some AOD branches. The name of the 
6 //     AliAODExtension object is the file name where the AOD branches will be
7 //     stored.
8 //-------------------------------------------------------------------------
9
10 #include "AliAODBranchReplicator.h"
11 #include "AliAODEvent.h"
12 #include "AliCodeTimer.h"
13 #include "AliLog.h"
14 #include "Riostream.h"
15 #include "TDirectory.h"
16 #include "TFile.h"
17 #include "TList.h"
18 #include "TMap.h"
19 #include "TMap.h"
20 #include "TObjString.h"
21 #include "TROOT.h"
22 #include "TString.h"
23 #include "TTree.h"
24
25 using std::endl;
26 using std::cout;
27 ClassImp(AliAODExtension)
28
29 //______________________________________________________________________________
30 AliAODExtension::AliAODExtension() : TNamed(), 
31 fAODEvent(0), fTreeE(0), fFileE(0), fNtotal(0), fNpassed(0), 
32 fSelected(kFALSE), fTreeBuffSize(30000000), fMemCountAOD(0),
33 fRepFiMap(0x0), fRepFiList(0x0), fEnableReferences(kTRUE), fObjectList(0)
34 {
35   // default ctor
36 }
37
38 //______________________________________________________________________________
39 AliAODExtension::AliAODExtension(const char* name, const char* title, Bool_t isfilter)
40 :TNamed(name,title), 
41 fAODEvent(0), 
42 fTreeE(0), 
43 fFileE(0), 
44 fNtotal(0), 
45 fNpassed(0),
46 fSelected(kFALSE),
47 fTreeBuffSize(30000000),
48 fMemCountAOD(0),
49 fRepFiMap(0x0),
50 fRepFiList(0x0),
51 fEnableReferences(kTRUE),
52 fObjectList(0x0)
53 {
54   // Constructor.
55   if (isfilter) {
56     TObject::SetBit(kFilteredAOD);
57     printf("####### Added AOD filter %s\n", name);
58   } else printf("####### Added AOD extension %s\n", name);
59   KeepUnspecifiedBranches();
60 }   
61
62 //______________________________________________________________________________
63 AliAODExtension::~AliAODExtension()
64 {
65   // Destructor.
66   if(fFileE){
67     // is already handled in TerminateIO
68     fFileE->Close();
69     delete fFileE;
70     fTreeE = 0;
71     fAODEvent = 0;
72   }
73   if (fTreeE) delete fTreeE;
74   if (fRepFiMap) fRepFiMap->DeleteAll();
75   delete fRepFiMap; // the map is owner
76   delete fRepFiList; // the list is not
77   delete fObjectList; // not owner
78 }
79
80 //______________________________________________________________________________
81 void AliAODExtension::AddBranch(const char* cname, void* addobj)
82 {
83   // Add a new branch to the aod 
84   
85   if (!fAODEvent) {
86     char type[20];
87     gROOT->ProcessLine(Form("TString s_tmp; AliAnalysisManager::GetAnalysisManager()->GetAnalysisTypeString(s_tmp); sprintf((char*)%p, \"%%s\", s_tmp.Data());", type));
88     Init(type);
89   }
90   TDirectory *owd = gDirectory;
91   if (fFileE) {
92     fFileE->cd();
93   }
94   char** apointer = (char**) addobj;
95   TObject* obj = (TObject*) *apointer;
96   
97   fAODEvent->AddObject(obj);
98   
99   TString bname(obj->GetName());
100   
101   if (!fTreeE->FindBranch(bname.Data())) 
102   {
103     Bool_t acceptAdd(kTRUE);
104     
105     if ( TestBit(kDropUnspecifiedBranches) )
106     {
107       // check that this branch is in our list of specified ones...
108       // otherwise do not add it !
109       TIter next(fRepFiMap);
110       TObjString* p;
111       
112       acceptAdd=kFALSE;
113       
114       while ( ( p = static_cast<TObjString*>(next()) ) && !acceptAdd )
115       {
116         if ( p->String() == bname ) acceptAdd=kTRUE;
117       }
118     }
119     
120     if ( acceptAdd ) 
121     {
122       // Do the same as if we book via 
123       // TTree::Branch(TCollection*)
124       
125       fObjectList->Add(obj);
126
127       const Int_t kSplitlevel = 99; // default value in TTree::Branch()
128       const Int_t kBufsize = 32000; // default value in TTree::Branch()
129       
130       fTreeE->Bronch(bname.Data(), cname, 
131                      fAODEvent->GetList()->GetObjectRef(obj),
132                      kBufsize, kSplitlevel - 1);
133     }
134   }
135   owd->cd();
136 }
137
138 //______________________________________________________________________________
139 Bool_t AliAODExtension::FinishEvent()
140 {
141   // Fill current event.
142   fNtotal++;
143   if (!IsFilteredAOD()) {
144     fAODEvent->MakeEntriesReferencable();
145     FillTree();
146     return kTRUE;
147   }  
148   // Filtered AOD. Fill only if event is selected.
149   if (!fSelected) return kTRUE;
150   
151   TIter next(fRepFiList);
152   
153   AliAODBranchReplicator* repfi;
154   
155   while ( ( repfi = static_cast<AliAODBranchReplicator*>(next()) ) )
156   {
157     repfi->ReplicateAndFilter(*fAODEvent);
158   }
159   fNpassed++;
160   FillTree();
161   fSelected = kFALSE; // so that next event will not be selected unless demanded
162   return kTRUE;
163 }  
164
165 //______________________________________________________________________________
166 void AliAODExtension::FillTree() 
167 {
168   //
169   //   Fill AOD extension tree and check AutoFlush settings
170   //
171   
172   Long64_t nbf = fTreeE->Fill();
173   
174   // Check buffer size and set autoflush if fTreeBuffSize is reached
175   if (fTreeBuffSize>0 && fTreeE->GetAutoFlush()<0 && 
176       (fMemCountAOD += nbf)>fTreeBuffSize ) { // default limit is still not reached
177     nbf = fTreeE->GetZipBytes();
178     if (nbf>0) nbf = -nbf;
179     else       nbf = fTreeE->GetEntries();
180     fTreeE->SetAutoFlush(nbf);
181     AliInfo(Form("Calling fTreeE->SetAutoFlush(%lld) | W:%lld T:%lld Z:%lld", 
182                  nbf,fMemCountAOD,fTreeE->GetTotBytes(),fTreeE->GetZipBytes()));  
183     
184   }
185 }
186
187 //______________________________________________________________________________
188 Bool_t AliAODExtension::Init(Option_t *option)
189 {
190   // Initialize IO.
191   
192   AliCodeTimerAuto(GetName(),0);
193   
194   if(!fAODEvent) 
195   {
196     fAODEvent = new AliAODEvent();    
197   }
198   
199   TDirectory *owd = gDirectory;
200   TString opt(option);
201   opt.ToLower();
202   
203   if (opt.Contains("proof")) 
204   {
205     // proof
206     // Merging via files. Need to access analysis manager via interpreter.
207     gROOT->ProcessLine(Form("AliAnalysisDataContainer *c_common_out = AliAnalysisManager::GetAnalysisManager()->GetCommonOutputContainer();"));
208     gROOT->ProcessLine(Form("AliAnalysisManager::GetAnalysisManager()->OpenProofFile(c_common_out, \"RECREATE\", \"%s\");", fName.Data()));
209     fFileE = gFile;
210   } 
211   else 
212   {
213     fFileE = new TFile(GetName(), "RECREATE");
214   }  
215   fTreeE = new TTree("aodTree", "AliAOD tree");
216   
217   delete fObjectList;
218   fObjectList = new TList;
219   fObjectList->SetOwner(kFALSE); // be explicit we're not the owner...
220   TList* inputList = fAODEvent->GetList();
221   TIter next(inputList);
222   TObject* o;
223   
224   while ( ( o = next() ) )
225   {
226     // Loop on the objects that are within the main AOD, and see what to do with them :
227     // - transmit them to our AOD as they are
228     // - filter them (by means of an AliAODBranchReplicator)
229     // - drop them completely
230     
231     Bool_t mustKeep(kFALSE);
232     
233     TString test(o->ClassName());
234     test.ToUpper();
235     // check if there is a replicator for the header
236     Bool_t headerHasReplicator = fRepFiMap && (fRepFiMap->FindObject(o->GetName())!=0x0);
237     if (test.BeginsWith("ALIAODHEADER") && !headerHasReplicator)
238     {
239       // do not allow to drop header branch
240       mustKeep=kTRUE;
241     }
242     
243     if ( fRepFiMap && !mustKeep )
244     {
245       // we have some replicators, so let's see what the relevant one decides about this object
246       TObject* specified = fRepFiMap->FindObject(o->GetName()); // FindObject finds key=o->GetName() in the map
247       if (specified)
248       {
249         AliAODBranchReplicator* repfi = dynamic_cast<AliAODBranchReplicator*>(fRepFiMap->GetValue(o->GetName())); // GetValue gets the replicator corresponding to key=o->GetName()
250         if ( repfi ) 
251         {        
252           TList* replicatedList = repfi->GetList();
253           if (replicatedList)
254           {
255             AliAODEvent::AssignIDtoCollection(replicatedList);
256             TIter nextRep(replicatedList);
257             TObject* objRep;
258             while ( ( objRep = nextRep() ) )
259             {
260               if ( !fObjectList->FindObject(objRep) ) // insure we're not adding several times the same object
261               {                
262                 fObjectList->Add(objRep);                  
263               }
264             }
265           }
266           else
267           {
268             AliError(Form("replicatedList from %s is null !",repfi->GetName()));
269           }
270         }
271       }
272       else
273       {
274         if ( !TestBit(kDropUnspecifiedBranches) ) 
275         {
276           // object o will be transmitted to the output AOD, unchanged
277           fObjectList->Add(o);
278         }
279       }
280     } 
281     else
282     {
283       // no replicator, so decide based on the policy about dropping unspecified branches
284       if ( mustKeep || !TestBit(kDropUnspecifiedBranches) )
285       {
286         // object o will be transmitted to the output AOD, unchanged
287         fObjectList->Add(o);
288       }
289     }
290   }
291     
292   if (fEnableReferences) 
293   {
294     fTreeE->BranchRef();    
295   }
296     
297   fTreeE->Branch(fObjectList);
298   
299   owd->cd();
300   
301   return kTRUE;
302 }
303
304 //______________________________________________________________________________
305 void AliAODExtension::Print(Option_t* opt) const
306 {
307   // Print info about this extension
308   
309   cout << opt << Form("%s - %s - %s - aod %p",IsFilteredAOD() ? "FilteredAOD" : "Extension",
310                       GetName(),GetTitle(),GetAOD()) << endl;
311   if ( !fEnableReferences ) 
312   {
313     cout << opt << opt << "References are disabled ! Hope you know what you are doing !" << endl;
314   }
315   if ( TestBit(kDropUnspecifiedBranches) )
316   {
317     cout << opt << opt << "All branches not explicitely specified will be dropped" << endl;
318   }
319   
320   TIter next(fRepFiMap);
321   TObjString* s;
322   
323   while ( ( s = static_cast<TObjString*>(next()) ) )
324   {
325     AliAODBranchReplicator* br = static_cast<AliAODBranchReplicator*>(fRepFiMap->GetValue(s->String().Data()));
326     
327     cout << opt << opt << "Branch " << s->String();
328     if (br)
329     {
330       cout << " will be filtered by class " << br->ClassName();
331     }
332     else
333     {
334       cout << " will be transmitted as is";
335     }
336     cout << endl;
337   }
338 }
339
340 //______________________________________________________________________________
341 void AliAODExtension::SetEvent(AliAODEvent* event)
342 {
343   // Connects to an external event
344   if (!IsFilteredAOD()) {
345     Error("SetEvent", "Not allowed to set external event for non filtered AOD's");   
346     return;
347   }
348   fAODEvent = event;
349 }
350
351 //______________________________________________________________________________
352 void AliAODExtension::AddAODtoTreeUserInfo()
353 {
354   // Add aod event to tree user info
355   
356   if (!fTreeE) return;
357   
358   AliAODEvent* aodEvent(fAODEvent);
359   
360   if ( IsFilteredAOD() )
361   {
362     // cannot attach fAODEvent (which is shared with our AliAODHandler mother)
363     // so we create a custom (empty) AliAODEvent 
364     // Has also the advantage we can specify only the list of objects
365     // that are actually there in this filtered aod
366     //
367     aodEvent = new AliAODEvent;
368     TIter nextObj(fObjectList);
369     TObject* o;
370     while ( ( o = nextObj() ) ) 
371     {
372       aodEvent->AddObject(o);
373     }    
374   }
375
376   TList *l = aodEvent->GetList();
377   if (l) {
378     for(int i = 0;i < l->GetEntries(); ++i){
379       TObject *pObject = l->At(i);
380       if(pObject->InheritsFrom(TClonesArray::Class())){
381        ((TClonesArray*)pObject)->Delete();
382       } else if(!pObject->InheritsFrom(TCollection::Class())){
383        TClass *pClass = TClass::GetClass(pObject->ClassName());
384        if (pClass && pClass->GetListOfMethods()->FindObject("Clear")) {
385          AliDebug(1, Form("Clear for object %s class %s", pObject->GetName(), pObject->ClassName()));
386          pObject->Clear();
387        }
388       } else {
389          AliWarning(Form("No method to clear for object %s class %s", pObject->GetName(), pObject->ClassName()));
390       }
391     }
392   }
393   fTreeE->GetUserInfo()->Add(aodEvent);
394 }
395
396 //______________________________________________________________________________
397 Bool_t AliAODExtension::TerminateIO()
398 {
399   // Terminate IO
400   if (TObject::TestBit(kFilteredAOD))
401     printf("AOD Filter %s: events processed: %d   passed: %d\n", GetName(), fNtotal, fNpassed);
402   else
403     printf("AOD extension %s: events processed: %d\n", GetName(), fNtotal);
404   if (fFileE) 
405   {
406     fFileE->Write();
407     fFileE->Close();
408     delete fFileE;
409     fFileE = 0;
410     fTreeE = 0;
411     fAODEvent = 0;
412   }
413   return kTRUE;
414 }
415
416 //______________________________________________________________________________
417 void AliAODExtension::FilterBranch(const char* branchName, AliAODBranchReplicator* repfi)
418 {
419   // Specify a filter/replicator for a given branch
420   //
421   // If repfi=0x0, this will disable the branch (in the output) completely.
422   //
423   // repfi is adopted by this class, i.e. user should not delete it.
424   //
425   // WARNING : branch name must be exact.
426   //
427   // See also the documentation for AliAODBranchReplicator class.
428   //
429   
430   if (!fRepFiMap)
431   {
432     fRepFiMap = new TMap;
433     fRepFiMap->SetOwnerKeyValue(kTRUE,kTRUE);
434     fRepFiList = new TList;
435     fRepFiList->SetOwner(kFALSE);
436   }
437   
438   fRepFiMap->Add(new TObjString(branchName),repfi);
439   
440   if (repfi && !fRepFiList->FindObject(repfi))
441   {
442     // insure we get unique and non-null replicators in this list
443     fRepFiList->Add(repfi);
444   }
445 }
446