#include "AliAODExtension.h"
#include "AliAODBranchReplicator.h"
#include "AliAODEvent.h"
#include "AliCodeTimer.h"
#include "AliLog.h"
#include "Riostream.h"
#include "TDirectory.h"
#include "TFile.h"
#include "TList.h"
#include "TMap.h"
#include "TMap.h"
#include "TObjString.h"
#include "TROOT.h"
#include "TString.h"
#include "TTree.h"
using std::endl;
using std::cout;
ClassImp(AliAODExtension)
AliAODExtension::AliAODExtension() : TNamed(),
fAODEvent(0), fTreeE(0), fFileE(0), fNtotal(0), fNpassed(0),
fSelected(kFALSE), fTreeBuffSize(30000000), fMemCountAOD(0),
fRepFiMap(0x0), fRepFiList(0x0), fEnableReferences(kTRUE), fObjectList(0)
{
}
AliAODExtension::AliAODExtension(const char* name, const char* title, Bool_t isfilter)
:TNamed(name,title),
fAODEvent(0),
fTreeE(0),
fFileE(0),
fNtotal(0),
fNpassed(0),
fSelected(kFALSE),
fTreeBuffSize(30000000),
fMemCountAOD(0),
fRepFiMap(0x0),
fRepFiList(0x0),
fEnableReferences(kTRUE),
fObjectList(0x0)
{
if (isfilter) {
TObject::SetBit(kFilteredAOD);
printf("####### Added AOD filter %s\n", name);
} else printf("####### Added AOD extension %s\n", name);
KeepUnspecifiedBranches();
}
AliAODExtension::~AliAODExtension()
{
if(fFileE){
fFileE->Close();
delete fFileE;
fTreeE = 0;
fAODEvent = 0;
}
if (fTreeE) delete fTreeE;
if (fRepFiMap) fRepFiMap->DeleteAll();
delete fRepFiMap;
delete fRepFiList;
delete fObjectList;
}
void AliAODExtension::AddBranch(const char* cname, void* addobj)
{
if (!fAODEvent) {
char type[20];
gROOT->ProcessLine(Form("TString s_tmp; AliAnalysisManager::GetAnalysisManager()->GetAnalysisTypeString(s_tmp); sprintf((char*)%p, \"%%s\", s_tmp.Data());", type));
Init(type);
}
TDirectory *owd = gDirectory;
if (fFileE) {
fFileE->cd();
}
char** apointer = (char**) addobj;
TObject* obj = (TObject*) *apointer;
fAODEvent->AddObject(obj);
TString bname(obj->GetName());
if (!fTreeE->FindBranch(bname.Data()))
{
Bool_t acceptAdd(kTRUE);
if ( TestBit(kDropUnspecifiedBranches) )
{
TIter next(fRepFiMap);
TObjString* p;
acceptAdd=kFALSE;
while ( ( p = static_cast<TObjString*>(next()) ) && !acceptAdd )
{
if ( p->String() == bname ) acceptAdd=kTRUE;
}
}
if ( acceptAdd )
{
fObjectList->Add(obj);
const Int_t kSplitlevel = 99;
const Int_t kBufsize = 32000;
fTreeE->Bronch(bname.Data(), cname,
fAODEvent->GetList()->GetObjectRef(obj),
kBufsize, kSplitlevel - 1);
}
}
owd->cd();
}
Bool_t AliAODExtension::FinishEvent()
{
fNtotal++;
if (!IsFilteredAOD()) {
fAODEvent->MakeEntriesReferencable();
FillTree();
return kTRUE;
}
if (!fSelected) return kTRUE;
TIter next(fRepFiList);
AliAODBranchReplicator* repfi;
while ( ( repfi = static_cast<AliAODBranchReplicator*>(next()) ) )
{
repfi->ReplicateAndFilter(*fAODEvent);
}
fNpassed++;
FillTree();
fSelected = kFALSE;
return kTRUE;
}
void AliAODExtension::FillTree()
{
Long64_t nbf = fTreeE->Fill();
if (fTreeBuffSize>0 && fTreeE->GetAutoFlush()<0 &&
(fMemCountAOD += nbf)>fTreeBuffSize ) {
nbf = fTreeE->GetZipBytes();
if (nbf>0) nbf = -nbf;
else nbf = fTreeE->GetEntries();
fTreeE->SetAutoFlush(nbf);
AliInfo(Form("Calling fTreeE->SetAutoFlush(%lld) | W:%lld T:%lld Z:%lld",
nbf,fMemCountAOD,fTreeE->GetTotBytes(),fTreeE->GetZipBytes()));
}
}
Bool_t AliAODExtension::Init(Option_t *option)
{
AliCodeTimerAuto(GetName(),0);
if(!fAODEvent)
{
fAODEvent = new AliAODEvent();
}
TDirectory *owd = gDirectory;
TString opt(option);
opt.ToLower();
if (opt.Contains("proof"))
{
gROOT->ProcessLine(Form("AliAnalysisDataContainer *c_common_out = AliAnalysisManager::GetAnalysisManager()->GetCommonOutputContainer();"));
gROOT->ProcessLine(Form("AliAnalysisManager::GetAnalysisManager()->OpenProofFile(c_common_out, \"RECREATE\", \"%s\");", fName.Data()));
fFileE = gFile;
}
else
{
fFileE = new TFile(GetName(), "RECREATE");
}
fTreeE = new TTree("aodTree", "AliAOD tree");
delete fObjectList;
fObjectList = new TList;
fObjectList->SetOwner(kFALSE);
TList* inputList = fAODEvent->GetList();
TIter next(inputList);
TObject* o;
while ( ( o = next() ) )
{
Bool_t mustKeep(kFALSE);
TString test(o->ClassName());
test.ToUpper();
Bool_t headerHasReplicator = fRepFiMap && (fRepFiMap->FindObject(o->GetName())!=0x0);
if (test.BeginsWith("ALIAODHEADER") && !headerHasReplicator)
{
mustKeep=kTRUE;
}
if ( fRepFiMap && !mustKeep )
{
TObject* specified = fRepFiMap->FindObject(o->GetName());
if (specified)
{
AliAODBranchReplicator* repfi = dynamic_cast<AliAODBranchReplicator*>(fRepFiMap->GetValue(o->GetName()));
if ( repfi )
{
TList* replicatedList = repfi->GetList();
if (replicatedList)
{
AliAODEvent::AssignIDtoCollection(replicatedList);
TIter nextRep(replicatedList);
TObject* objRep;
while ( ( objRep = nextRep() ) )
{
if ( !fObjectList->FindObject(objRep) )
{
fObjectList->Add(objRep);
}
}
}
else
{
AliError(Form("replicatedList from %s is null !",repfi->GetName()));
}
}
}
else
{
if ( !TestBit(kDropUnspecifiedBranches) )
{
fObjectList->Add(o);
}
}
}
else
{
if ( mustKeep || !TestBit(kDropUnspecifiedBranches) )
{
fObjectList->Add(o);
}
}
}
if (fEnableReferences)
{
fTreeE->BranchRef();
}
fTreeE->Branch(fObjectList);
owd->cd();
return kTRUE;
}
void AliAODExtension::Print(Option_t* opt) const
{
cout << opt << Form("%s - %s - %s - aod %p",IsFilteredAOD() ? "FilteredAOD" : "Extension",
GetName(),GetTitle(),GetAOD()) << endl;
if ( !fEnableReferences )
{
cout << opt << opt << "References are disabled ! Hope you know what you are doing !" << endl;
}
if ( TestBit(kDropUnspecifiedBranches) )
{
cout << opt << opt << "All branches not explicitely specified will be dropped" << endl;
}
TIter next(fRepFiMap);
TObjString* s;
while ( ( s = static_cast<TObjString*>(next()) ) )
{
AliAODBranchReplicator* br = static_cast<AliAODBranchReplicator*>(fRepFiMap->GetValue(s->String().Data()));
cout << opt << opt << "Branch " << s->String();
if (br)
{
cout << " will be filtered by class " << br->ClassName();
}
else
{
cout << " will be transmitted as is";
}
cout << endl;
}
}
void AliAODExtension::SetEvent(AliAODEvent* event)
{
if (!IsFilteredAOD()) {
Error("SetEvent", "Not allowed to set external event for non filtered AOD's");
return;
}
fAODEvent = event;
}
void AliAODExtension::AddAODtoTreeUserInfo()
{
if (!fTreeE) return;
AliAODEvent* aodEvent(fAODEvent);
if ( IsFilteredAOD() )
{
aodEvent = new AliAODEvent;
TIter nextObj(fObjectList);
TObject* o;
while ( ( o = nextObj() ) )
{
aodEvent->AddObject(o);
}
}
TList *l = aodEvent->GetList();
if (l) {
for(int i = 0;i < l->GetEntries(); ++i){
TObject *pObject = l->At(i);
if(pObject->InheritsFrom(TClonesArray::Class())){
((TClonesArray*)pObject)->Delete();
} else if(!pObject->InheritsFrom(TCollection::Class())){
TClass *pClass = TClass::GetClass(pObject->ClassName());
if (pClass && pClass->GetListOfMethods()->FindObject("Clear")) {
AliDebug(1, Form("Clear for object %s class %s", pObject->GetName(), pObject->ClassName()));
pObject->Clear();
}
} else {
AliWarning(Form("No method to clear for object %s class %s", pObject->GetName(), pObject->ClassName()));
}
}
}
fTreeE->GetUserInfo()->Add(aodEvent);
}
Bool_t AliAODExtension::TerminateIO()
{
if (TObject::TestBit(kFilteredAOD))
printf("AOD Filter %s: events processed: %d passed: %d\n", GetName(), fNtotal, fNpassed);
else
printf("AOD extension %s: events processed: %d\n", GetName(), fNtotal);
if (fFileE)
{
fFileE->Write();
fFileE->Close();
delete fFileE;
fFileE = 0;
fTreeE = 0;
fAODEvent = 0;
}
return kTRUE;
}
void AliAODExtension::FilterBranch(const char* branchName, AliAODBranchReplicator* repfi)
{
if (!fRepFiMap)
{
fRepFiMap = new TMap;
fRepFiMap->SetOwnerKeyValue(kTRUE,kTRUE);
fRepFiList = new TList;
fRepFiList->SetOwner(kFALSE);
}
fRepFiMap->Add(new TObjString(branchName),repfi);
if (repfi && !fRepFiList->FindObject(repfi))
{
fRepFiList->Add(repfi);
}
}