1 #include "AliAODExtension.h"
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
8 //-------------------------------------------------------------------------
10 #include "AliAODBranchReplicator.h"
11 #include "AliAODEvent.h"
12 #include "AliCodeTimer.h"
14 #include "Riostream.h"
15 #include "TDirectory.h"
20 #include "TObjString.h"
27 ClassImp(AliAODExtension)
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)
38 //______________________________________________________________________________
39 AliAODExtension::AliAODExtension(const char* name, const char* title, Bool_t isfilter)
47 fTreeBuffSize(30000000),
51 fEnableReferences(kTRUE),
56 TObject::SetBit(kFilteredAOD);
57 printf("####### Added AOD filter %s\n", name);
58 } else printf("####### Added AOD extension %s\n", name);
59 KeepUnspecifiedBranches();
62 //______________________________________________________________________________
63 AliAODExtension::~AliAODExtension()
67 // is already handled in TerminateIO
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
80 //______________________________________________________________________________
81 void AliAODExtension::AddBranch(const char* cname, void* addobj)
83 // Add a new branch to the aod
87 gROOT->ProcessLine(Form("TString s_tmp; AliAnalysisManager::GetAnalysisManager()->GetAnalysisTypeString(s_tmp); sprintf((char*)%p, \"%%s\", s_tmp.Data());", type));
90 TDirectory *owd = gDirectory;
94 char** apointer = (char**) addobj;
95 TObject* obj = (TObject*) *apointer;
97 fAODEvent->AddObject(obj);
99 TString bname(obj->GetName());
101 if (!fTreeE->FindBranch(bname.Data()))
103 Bool_t acceptAdd(kTRUE);
105 if ( TestBit(kDropUnspecifiedBranches) )
107 // check that this branch is in our list of specified ones...
108 // otherwise do not add it !
109 TIter next(fRepFiMap);
114 while ( ( p = static_cast<TObjString*>(next()) ) && !acceptAdd )
116 if ( p->String() == bname ) acceptAdd=kTRUE;
122 // Do the same as if we book via
123 // TTree::Branch(TCollection*)
125 fObjectList->Add(obj);
127 const Int_t kSplitlevel = 99; // default value in TTree::Branch()
128 const Int_t kBufsize = 32000; // default value in TTree::Branch()
130 fTreeE->Bronch(bname.Data(), cname,
131 fAODEvent->GetList()->GetObjectRef(obj),
132 kBufsize, kSplitlevel - 1);
138 //______________________________________________________________________________
139 Bool_t AliAODExtension::FinishEvent()
141 // Fill current event.
143 if (!IsFilteredAOD()) {
144 fAODEvent->MakeEntriesReferencable();
148 // Filtered AOD. Fill only if event is selected.
149 if (!fSelected) return kTRUE;
151 TIter next(fRepFiList);
153 AliAODBranchReplicator* repfi;
155 while ( ( repfi = static_cast<AliAODBranchReplicator*>(next()) ) )
157 repfi->ReplicateAndFilter(*fAODEvent);
161 fSelected = kFALSE; // so that next event will not be selected unless demanded
165 //______________________________________________________________________________
166 void AliAODExtension::FillTree()
169 // Fill AOD extension tree and check AutoFlush settings
172 Long64_t nbf = fTreeE->Fill();
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()));
187 //______________________________________________________________________________
188 Bool_t AliAODExtension::Init(Option_t *option)
192 AliCodeTimerAuto(GetName(),0);
196 fAODEvent = new AliAODEvent();
199 TDirectory *owd = gDirectory;
203 if (opt.Contains("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()));
213 fFileE = new TFile(GetName(), "RECREATE");
215 fTreeE = new TTree("aodTree", "AliAOD tree");
218 fObjectList = new TList;
219 fObjectList->SetOwner(kFALSE); // be explicit we're not the owner...
220 TList* inputList = fAODEvent->GetList();
221 TIter next(inputList);
224 while ( ( o = next() ) )
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
231 Bool_t mustKeep(kFALSE);
233 TString test(o->ClassName());
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)
239 // do not allow to drop header branch
243 if ( fRepFiMap && !mustKeep )
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
249 AliAODBranchReplicator* repfi = dynamic_cast<AliAODBranchReplicator*>(fRepFiMap->GetValue(o->GetName())); // GetValue gets the replicator corresponding to key=o->GetName()
252 TList* replicatedList = repfi->GetList();
255 AliAODEvent::AssignIDtoCollection(replicatedList);
256 TIter nextRep(replicatedList);
258 while ( ( objRep = nextRep() ) )
260 if ( !fObjectList->FindObject(objRep) ) // insure we're not adding several times the same object
262 fObjectList->Add(objRep);
268 AliError(Form("replicatedList from %s is null !",repfi->GetName()));
274 if ( !TestBit(kDropUnspecifiedBranches) )
276 // object o will be transmitted to the output AOD, unchanged
283 // no replicator, so decide based on the policy about dropping unspecified branches
284 if ( mustKeep || !TestBit(kDropUnspecifiedBranches) )
286 // object o will be transmitted to the output AOD, unchanged
292 if (fEnableReferences)
297 fTreeE->Branch(fObjectList);
304 //______________________________________________________________________________
305 void AliAODExtension::Print(Option_t* opt) const
307 // Print info about this extension
309 cout << opt << Form("%s - %s - %s - aod %p",IsFilteredAOD() ? "FilteredAOD" : "Extension",
310 GetName(),GetTitle(),GetAOD()) << endl;
311 if ( !fEnableReferences )
313 cout << opt << opt << "References are disabled ! Hope you know what you are doing !" << endl;
315 if ( TestBit(kDropUnspecifiedBranches) )
317 cout << opt << opt << "All branches not explicitely specified will be dropped" << endl;
320 TIter next(fRepFiMap);
323 while ( ( s = static_cast<TObjString*>(next()) ) )
325 AliAODBranchReplicator* br = static_cast<AliAODBranchReplicator*>(fRepFiMap->GetValue(s->String().Data()));
327 cout << opt << opt << "Branch " << s->String();
330 cout << " will be filtered by class " << br->ClassName();
334 cout << " will be transmitted as is";
340 //______________________________________________________________________________
341 void AliAODExtension::SetEvent(AliAODEvent* event)
343 // Connects to an external event
344 if (!IsFilteredAOD()) {
345 Error("SetEvent", "Not allowed to set external event for non filtered AOD's");
351 //______________________________________________________________________________
352 void AliAODExtension::AddAODtoTreeUserInfo()
354 // Add aod event to tree user info
358 AliAODEvent* aodEvent(fAODEvent);
360 if ( IsFilteredAOD() )
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
367 aodEvent = new AliAODEvent;
368 TIter nextObj(fObjectList);
370 while ( ( o = nextObj() ) )
372 aodEvent->AddObject(o);
376 TList *l = aodEvent->GetList();
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()));
389 AliWarning(Form("No method to clear for object %s class %s", pObject->GetName(), pObject->ClassName()));
393 fTreeE->GetUserInfo()->Add(aodEvent);
396 //______________________________________________________________________________
397 Bool_t AliAODExtension::TerminateIO()
400 if (TObject::TestBit(kFilteredAOD))
401 printf("AOD Filter %s: events processed: %d passed: %d\n", GetName(), fNtotal, fNpassed);
403 printf("AOD extension %s: events processed: %d\n", GetName(), fNtotal);
416 //______________________________________________________________________________
417 void AliAODExtension::FilterBranch(const char* branchName, AliAODBranchReplicator* repfi)
419 // Specify a filter/replicator for a given branch
421 // If repfi=0x0, this will disable the branch (in the output) completely.
423 // repfi is adopted by this class, i.e. user should not delete it.
425 // WARNING : branch name must be exact.
427 // See also the documentation for AliAODBranchReplicator class.
432 fRepFiMap = new TMap;
433 fRepFiMap->SetOwnerKeyValue(kTRUE,kTRUE);
434 fRepFiList = new TList;
435 fRepFiList->SetOwner(kFALSE);
438 fRepFiMap->Add(new TObjString(branchName),repfi);
440 if (repfi && !fRepFiList->FindObject(repfi))
442 // insure we get unique and non-null replicators in this list
443 fRepFiList->Add(repfi);