#include <TTree.h>
#include <TFile.h>
+#include <TRef.h>
#include <TString.h>
#include <TList.h>
+#include <TROOT.h>
#include "AliLog.h"
#include "AliAODHandler.h"
fMCEventH(NULL),
fTreeA(NULL),
fFileA(NULL),
- fFileName("")
+ fFileName(""),
+ fExtensions(NULL)
{
// default constructor
}
fMCEventH(NULL),
fTreeA(NULL),
fFileA(NULL),
- fFileName("")
+ fFileName(""),
+ fExtensions(NULL)
{
}
//______________________________________________________________________________
AliAODHandler::~AliAODHandler()
{
+ // Destructor.
delete fAODEvent;
if(fFileA){
// is already handled in TerminateIO
delete fFileA;
}
delete fTreeA;
- // destructor
+ if (fExtensions) delete fExtensions;
}
//______________________________________________________________________________
// File opening according to execution mode
TString option(opt);
option.ToLower();
+ TDirectory *owd = gDirectory;
if (option.Contains("proof")) {
// proof
- if (option.Contains("special")) {
- // File for tree already opened on slave -> merging via files
- fFileA = gFile;
- CreateTree(1);
- } else {
- // Merging in memory
- CreateTree(0);
- }
+ // Merging via files. Need to access analysis manager via interpreter.
+ gROOT->ProcessLine(Form("AliAnalysisManager::GetAnalysisManager()->OpenProofFile(\"%s\", \"RECREATE\");", fFileName.Data()));
+ gROOT->ProcessLine(Form("AliAnalysisManager::GetAnalysisManager()->GetCommonOutputContainer()->SetFile((TFile*)0x%lx);", gFile));
+ fFileA = gFile;
} else {
// local and grid
- TDirectory *owd = gDirectory;
fFileA = new TFile(fFileName.Data(), "RECREATE");
- CreateTree(1);
- owd->cd();
}
+ CreateTree(1);
+ owd->cd();
+ if (fExtensions) {
+ TIter next(fExtensions);
+ AliAODExtension *ext;
+ while ((ext=(AliAODExtension*)next())) ext->Init(option);
+ }
return kTRUE;
}
-
+//______________________________________________________________________________
void AliAODHandler::StoreMCParticles(){
//
}
+//______________________________________________________________________________
Bool_t AliAODHandler::FinishEvent()
{
// Fill data structures
fAODEvent->MakeEntriesReferencable();
StoreMCParticles();
FillTree();
+ if (fExtensions) {
+ TIter next(fExtensions);
+ AliAODExtension *ext;
+ while ((ext=(AliAODExtension*)next())) {
+ ext->GetAOD()->MakeEntriesReferencable();
+ ext->GetTree()->Fill();
+ }
+ }
}
if (fIsStandard) fAODEvent->ResetStd();
//______________________________________________________________________________
Bool_t AliAODHandler::Terminate()
{
- // Terminate
- AddAODtoTreeUserInfo();
- return kTRUE;
+ // Terminate
+ AddAODtoTreeUserInfo();
+ if (fExtensions) {
+ TIter next(fExtensions);
+ AliAODExtension *ext;
+ while ((ext=(AliAODExtension*)next())) ext->GetTree()->GetUserInfo()->Add(ext->GetAOD());
+ }
+ return kTRUE;
}
//______________________________________________________________________________
Bool_t AliAODHandler::TerminateIO()
{
- // Terminate IO
- if (fFileA) {
- fFileA->Close();
- delete fFileA;
- }
- return kTRUE;
+ // Terminate IO
+ if (fFileA) {
+ fFileA->Close();
+ delete fFileA;
+ fFileA = 0;
+ }
+ if (fExtensions) {
+ TIter next(fExtensions);
+ AliAODExtension *ext;
+ while ((ext=(AliAODExtension*)next())) ext->TerminateIO();
+ }
+ return kTRUE;
}
//______________________________________________________________________________
// Creates the AOD Tree
fTreeA = new TTree("aodTree", "AliAOD tree");
fTreeA->Branch(fAODEvent->GetList());
+ TRef junk = (TObject*)fTreeA->BranchRef();
if (flag == 0) fTreeA->SetDirectory(0);
}
}
//______________________________________________________________________________
-void AliAODHandler::AddBranch(const char* cname, void* addobj)
+void AliAODHandler::AddBranch(const char* cname, void* addobj, const char* filename)
{
- // Add a new branch to the aod
+ // Add a new branch to the aod. Added optional filename parameter if the
+ // branch should be written to a separate file.
+ if (strlen(filename)) {
+ AliAODExtension *ext = AddExtension(filename);
+ ext->AddBranch(cname, addobj);
+ return;
+ }
TDirectory *owd = gDirectory;
if (fFileA) {
fFileA->cd();
owd->cd();
}
+//______________________________________________________________________________
+AliAODExtension *AliAODHandler::AddExtension(const char *filename, const char *title)
+{
+// Add an AOD extension with some branches in a different file.
+ TString fname(filename);
+ if (!fname.EndsWith(".root")) fname += ".root";
+ if (!fExtensions) {
+ fExtensions = new TObjArray();
+ fExtensions->SetOwner();
+ }
+ AliAODExtension *ext = (AliAODExtension*)fExtensions->FindObject(fname);
+ if (!ext) {
+ ext = new AliAODExtension(fname, title);
+ fExtensions->Add(ext);
+ }
+ return ext;
+}
+
//______________________________________________________________________________
void AliAODHandler::SetOutputFileName(const char* fname)
{
return fFileName.Data();
}
+//______________________________________________________________________________
void AliAODHandler::SetMCHeaderInfo(AliAODMCHeader *mcHeader,AliGenEventHeader *genHeader){
// Needed since different ProcessType and ImpactParamter are not
// in the base class...
// We don't encode process types for event cocktails yet
- // coul be done e.g. by adding offsets depnding on the generator
-
+ // could be done e.g. by adding offsets depnding on the generator
mcHeader->AddGeneratorName(genHeader->GetName());
-
-
-
if(!genHeader)return;
AliGenPythiaEventHeader *pythiaGenHeader = dynamic_cast<AliGenPythiaEventHeader*>(genHeader);
if (pythiaGenHeader) {
AliWarning(Form("MC Eventheader not known: %s",genHeader->GetName()));
}
+
+ClassImp(AliAODExtension)
+
+//-------------------------------------------------------------------------
+// Support class for AOD extensions. This is created by the user analysis
+// that requires a separate file for some AOD branches. The name of the
+// AliAODExtension object is the file name where the AOD branches will be
+// stored.
+//-------------------------------------------------------------------------
+
+//______________________________________________________________________________
+AliAODExtension::~AliAODExtension()
+{
+// Destructor.
+ delete fAODEvent;
+ if(fFileE){
+ // is already handled in TerminateIO
+ fFileE->Close();
+ delete fFileE;
+ }
+ delete fTreeE;
+}
+
+//______________________________________________________________________________
+void AliAODExtension::AddBranch(const char* cname, void* addobj)
+{
+ // Add a new branch to the aod
+ if (!fAODEvent) {
+ char type[20];
+ gROOT->ProcessLine(Form("TString s_tmp; AliAnalysisManager::GetAnalysisManager()->GetAnalysisTypeString(s_tmp); sprintf((char*)0x%lx, \"%%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);
+
+ const Int_t kSplitlevel = 99; // default value in TTree::Branch()
+ const Int_t kBufsize = 32000; // default value in TTree::Branch()
+
+ if (!fTreeE->FindBranch(obj->GetName())) {
+ // Do the same as if we book via
+ // TTree::Branch(TCollection*)
+
+ fTreeE->Bronch(obj->GetName(), cname, fAODEvent->GetList()->GetObjectRef(obj),
+ kBufsize, kSplitlevel - 1);
+ // fTreeA->Branch(obj->GetName(), cname, addobj);
+ }
+ owd->cd();
+}
+
+//______________________________________________________________________________
+Bool_t AliAODExtension::Init(Option_t *option)
+{
+// Initialize IO.
+ if(!fAODEvent) fAODEvent = new AliAODEvent();
+ TDirectory *owd = gDirectory;
+ TString opt(option);
+ opt.ToLower();
+ if (opt.Contains("proof")) {
+ // proof
+ // Merging via files. Need to access analysis manager via interpreter.
+ gROOT->ProcessLine(Form("AliAnalysisManager::GetAnalysisManager()->OpenProofFile(\"%s\", \"RECREATE\");", fName.Data()));
+ fFileE = gFile;
+ } else {
+ fFileE = new TFile(GetName(), "RECREATE");
+ }
+ fTreeE = new TTree("aodTree", "AliAOD tree");
+ fTreeE->Branch(fAODEvent->GetList());
+ TRef junk = (TObject*)fTreeE->BranchRef();
+ owd->cd();
+ return kTRUE;
+}
+
+//______________________________________________________________________________
+Bool_t AliAODExtension::TerminateIO()
+{
+ // Terminate IO
+ if (fFileE) {
+ fFileE->Write();
+ fFileE->Close();
+ delete fFileE;
+ fFileE = 0;
+ }
+ return kTRUE;
+}