#include "AliAnalysisTask.h"
#include "AliAnalysisDataContainer.h"
#include "AliAnalysisDataSlot.h"
+#include "AliVEventHandler.h"
#include "AliAnalysisManager.h"
ClassImp(AliAnalysisManager)
AliAnalysisManager::AliAnalysisManager()
:TNamed(),
fTree(NULL),
+ fInputEventHandler(NULL),
+ fOutputEventHandler(NULL),
+ fMCtruthEventHandler(NULL),
fCurrentEntry(-1),
fMode(kLocalAnalysis),
fInitOK(kFALSE),
+ fDebug(0),
fTasks(NULL),
fTopTasks(NULL),
fZombies(NULL),
{
// Dummy constructor.
fgAnalysisManager = this;
+ SetEventLoop(kTRUE);
}
//______________________________________________________________________________
AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
:TNamed(name,title),
fTree(NULL),
+ fInputEventHandler(NULL),
+ fOutputEventHandler(NULL),
+ fMCtruthEventHandler(NULL),
fCurrentEntry(-1),
fMode(kLocalAnalysis),
fInitOK(kFALSE),
fContainers = new TObjArray();
fInputs = new TObjArray();
fOutputs = new TObjArray();
+ SetEventLoop(kTRUE);
}
//______________________________________________________________________________
AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
:TNamed(other),
fTree(NULL),
+ fInputEventHandler(NULL),
+ fOutputEventHandler(NULL),
+ fMCtruthEventHandler(NULL),
fCurrentEntry(-1),
fMode(other.fMode),
fInitOK(other.fInitOK),
// Assignment
if (&other != this) {
TNamed::operator=(other);
+ fInputEventHandler = other.fInputEventHandler;
+ fOutputEventHandler = other.fOutputEventHandler;
+ fMCtruthEventHandler = other.fMCtruthEventHandler;
fTree = NULL;
fCurrentEntry = -1;
fMode = other.fMode;
if (fDebug > 1) {
printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
}
+
+ if (fInputEventHandler) {
+ fInputEventHandler->SetInputTree(tree);
+ fInputEventHandler->InitIO("");
+ }
+
if (!fInitOK) InitAnalysis();
if (!fInitOK) return;
fTree = tree;
if (fDebug > 1) {
cout << "->AliAnalysisManager::SlaveBegin()" << endl;
}
-
+ // Call InitIO of EventHandler
+ if (fOutputEventHandler) {
+ if (fMode == kProofAnalysis) {
+ fOutputEventHandler->InitIO("proof");
+ } else {
+ fOutputEventHandler->InitIO("local");
+ }
+ }
+ if (fInputEventHandler && fMode == kLocalAnalysis) {
+ fInputEventHandler->SetInputTree(tree);
+ fInputEventHandler->InitIO("");
+ }
+
+ //
TIter next(fTasks);
AliAnalysisTask *task;
// Call CreateOutputObjects for all tasks
task->CreateOutputObjects();
if (curdir) curdir->cd();
}
- if (fMode == kLocalAnalysis) Init(tree);
+ if (fMode == kLocalAnalysis)
+ Init(tree);
if (fDebug > 1) {
cout << "<-AliAnalysisManager::SlaveBegin()" << endl;
}
// is started when using PROOF. It is normaly not necessary to make changes
// to the generated code, but the routine can be extended by the
// user if needed. The return value is currently not used.
- if (fTree) {
- TFile *curfile = fTree->GetCurrentFile();
- if (curfile && fDebug>1) printf("AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
- TIter next(fTasks);
- AliAnalysisTask *task;
- // Call Notify for all tasks
- while ((task=(AliAnalysisTask*)next()))
- task->Notify();
- }
- return kTRUE;
+ if (fTree) {
+ TFile *curfile = fTree->GetCurrentFile();
+ if (curfile && fDebug>1) printf("AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
+ TIter next(fTasks);
+ AliAnalysisTask *task;
+ // Call Notify for all tasks
+ while ((task=(AliAnalysisTask*)next()))
+ task->Notify();
+
+ // Call Notify of the MC truth handler
+ if (fMCtruthEventHandler) {
+ fMCtruthEventHandler->Notify(curfile->GetName());
+ }
+
+ }
+ return kTRUE;
}
//______________________________________________________________________________
if (fDebug > 1) {
cout << "->AliAnalysisManager::Process()" << endl;
}
+ if (fInputEventHandler) fInputEventHandler ->BeginEvent();
+ if (fOutputEventHandler) fOutputEventHandler ->BeginEvent();
+ if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent();
+
GetEntry(entry);
ExecAnalysis();
if (fDebug > 1) {
return;
}
+ if (fOutputEventHandler) fOutputEventHandler ->Terminate();
+ if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
+
if (fMode == kProofAnalysis) {
TIter next(fOutputs);
AliAnalysisDataContainer *output;
AliAnalysisDataContainer *output;
while ((output=(AliAnalysisDataContainer*)next())) {
if (!output->GetData()) continue;
+ // Check if there are client tasks that run post event loop
+ if (output->HasConsumers()) {
+ // Disable event loop semaphore
+ output->SetPostEventLoop(kTRUE);
+ TObjArray *list = output->GetConsumers();
+ Int_t ncons = list->GetEntriesFast();
+ for (Int_t i=0; i<ncons; i++) {
+ AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
+ task->CheckNotify(kTRUE);
+ // If task is active, execute it
+ if (task->IsPostEventLoop() && task->IsActive()) {
+ if (fDebug > 1) {
+ cout << "== Executing post event loop task " << task->GetName() << endl;
+ }
+ task->ExecuteTask();
+ }
+ }
+ }
// Check if the output need to be written to a file.
const char *filename = output->GetFileName();
+ if (!(strcmp(filename, "default"))) {
+ if (fOutputEventHandler) filename = fOutputEventHandler->GetOutputFileName();
+ }
+
if (!filename || !strlen(filename)) continue;
TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
if (file) file->cd();
callEnv.SetParam((Long_t) file);
callEnv.Execute(output->GetData());
}
- output->GetData()->Write();
+ output->GetData()->Write();
}
if (fDebug > 1) {
cout << "<-AliAnalysisManager::UnpackOutput()" << endl;
if (fDebug > 1) {
cout << "<-AliAnalysisManager::Terminate()" << endl;
}
+ //
+ if (fOutputEventHandler) fOutputEventHandler->TerminateIO();
}
//______________________________________________________________________________
// kExchangeContainer = 0, used to exchange date between tasks
// kInputContainer = 1, used to store input data
// kOutputContainer = 2, used for posting results
+ if (fContainers->FindObject(name)) {
+ Error("CreateContainer","A container named %s already defined !\n",name);
+ return NULL;
+ }
AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
fContainers->Add(cont);
switch (type) {
fInputs->Add(cont);
break;
case kOutputContainer:
- if (fOutputs->FindObject(name)) printf("CreateContainer: warning: a container named %s existing !\n",name);
fOutputs->Add(cont);
if (filename && strlen(filename)) cont->SetFileName(filename);
break;
return kFALSE;
}
}
+ // Check that all containers feeding post-event loop tasks are in the outputs list
+ TIter nextcont(fContainers); // loop over all containers
+ while ((cont=(AliAnalysisDataContainer*)nextcont())) {
+ if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
+ if (cont->HasConsumers()) {
+ // Check if one of the consumers is post event loop
+ TIter nextconsumer(cont->GetConsumers());
+ while ((task=(AliAnalysisTask*)nextconsumer())) {
+ if (task->IsPostEventLoop()) {
+ fOutputs->Add(cont);
+ break;
+ }
+ }
+ }
+ }
+ }
fInitOK = kTRUE;
return kTRUE;
}
}
char line[128];
SetEventLoop(kFALSE);
- // Disable by default all branches and set event loop mode
+ // Disable all branches if requested and set event loop mode
if (tree) {
- tree->SetBranchStatus("*",0);
+ if (TestBit(kDisableBranches)) {
+ printf("Disabling all branches...\n");
+// tree->SetBranchStatus("*",0); // not yet working
+ }
SetEventLoop(kTRUE);
}
- AliAnalysisDataContainer *cont = 0;
- TIter nextc(fInputs);
- // Force top containers have the same event loop type as the analysis
- while ((cont=(AliAnalysisDataContainer*)nextc())) cont->SetEventByEvent(IsEventLoop());
- AliAnalysisDataContainer *cont_top = (AliAnalysisDataContainer*)fInputs->First();
TChain *chain = dynamic_cast<TChain*>(tree);
TIter next(fTasks);
AliAnalysisTask *task;
while ((task=(AliAnalysisTask*)next())) {
- for (Int_t islot=0; islot<task->GetNinputs(); islot++) {
- cont = task->GetInputSlot(islot)->GetContainer();
- if (cont==cont_top) break;
- cont = 0;
- }
- // All tasks feeding from the top containers must have the same event loop type
- if (cont) task->SetExecPerEvent(IsEventLoop());
- else task->SetExecPerEvent(task->IsExecPerEvent());
task->LocalInit();
}
return;
}
// Run tree-based analysis via AliAnalysisSelector
- gROOT->ProcessLine(".L $ALICE_ROOT/ANALYSIS/AliAnalysisSelector.cxx+");
+// gROOT->ProcessLine(".L $ALICE_ROOT/ANALYSIS/AliAnalysisSelector.cxx+");
cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
sprintf(line, "AliAnalysisSelector *selector = new AliAnalysisSelector((AliAnalysisManager*)0x%lx);",(ULong_t)this);
gROOT->ProcessLine(line);
if (chain) {
chain->SetProof();
cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
- chain->Process(gSystem->ExpandPathName("$ALICE_ROOT/ANALYSIS/AliAnalysisSelector.cxx+"));
+ chain->Process("AliAnalysisSelector");
} else {
printf("StartAnalysis: no chain\n");
return;
return;
}
cont->SetData(fTree); // This will notify all consumers
+//
+// Call BeginEvent() for optional input/output and MC services
+ if (fInputEventHandler) fInputEventHandler ->BeginEvent();
+ if (fOutputEventHandler) fOutputEventHandler ->BeginEvent();
+ if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent();
+//
+// Execute the tasks
TIter next1(cont->GetConsumers());
while ((task=(AliAnalysisTask*)next1())) {
-// task->SetActive(kTRUE);
if (fDebug >1) {
cout << " Executing task " << task->GetName() << endl;
}
+
task->ExecuteTask(option);
}
+//
+// Call FinishEvent() for optional output and MC services
+ if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
+ if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
+//
return;
}
// The event loop is not controlled by TSelector
+//
+// Call BeginEvent() for optional input/output and MC services
+ if (fInputEventHandler) fInputEventHandler ->BeginEvent();
+ if (fOutputEventHandler) fOutputEventHandler ->BeginEvent();
+ if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent();
TIter next2(fTopTasks);
while ((task=(AliAnalysisTask*)next2())) {
task->SetActive(kTRUE);
}
task->ExecuteTask(option);
}
+//
+// Call FinishEvent() for optional output and MC services
+ if (fOutputEventHandler) fOutputEventHandler->FinishEvent();
+ if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
}
//______________________________________________________________________________