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