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