X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=ANALYSIS%2FAliAnalysisManager.cxx;h=8f3be8618a877776040788e7774c85f1cb663c11;hb=b7980dfe7f95c317715bf8f6af9129780af1b1e0;hp=f75df58170cae73364ac944b11618457c437b878;hpb=8167b1d0ec353baa71757da26e2fa1304b984175;p=u%2Fmrichter%2FAliRoot.git diff --git a/ANALYSIS/AliAnalysisManager.cxx b/ANALYSIS/AliAnalysisManager.cxx index f75df58170c..8f3be8618a8 100644 --- a/ANALYSIS/AliAnalysisManager.cxx +++ b/ANALYSIS/AliAnalysisManager.cxx @@ -33,11 +33,13 @@ #include #include #include +#include #include "AliAnalysisTask.h" #include "AliAnalysisDataContainer.h" #include "AliAnalysisDataSlot.h" #include "AliVEventHandler.h" +#include "AliSysInfo.h" #include "AliAnalysisManager.h" ClassImp(AliAnalysisManager) @@ -48,13 +50,15 @@ AliAnalysisManager *AliAnalysisManager::fgAnalysisManager = NULL; AliAnalysisManager::AliAnalysisManager(const char *name, const char *title) :TNamed(name,title), fTree(NULL), - fInputEventHandler(NULL), - fOutputEventHandler(NULL), - fMCtruthEventHandler(NULL), + fInputEventHandler(NULL), + fOutputEventHandler(NULL), + fMCtruthEventHandler(NULL), fCurrentEntry(-1), + fNSysInfo(0), fMode(kLocalAnalysis), fInitOK(kFALSE), fDebug(0), + fSpecialOutputLocation(""), fTasks(NULL), fTopTasks(NULL), fZombies(NULL), @@ -77,13 +81,15 @@ AliAnalysisManager::AliAnalysisManager(const char *name, const char *title) AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other) :TNamed(other), fTree(NULL), - fInputEventHandler(NULL), - fOutputEventHandler(NULL), - fMCtruthEventHandler(NULL), + fInputEventHandler(NULL), + fOutputEventHandler(NULL), + fMCtruthEventHandler(NULL), fCurrentEntry(-1), + fNSysInfo(0), fMode(other.fMode), fInitOK(other.fInitOK), fDebug(other.fDebug), + fSpecialOutputLocation(""), fTasks(NULL), fTopTasks(NULL), fZombies(NULL), @@ -112,6 +118,7 @@ AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& othe fMCtruthEventHandler = other.fMCtruthEventHandler; fTree = NULL; fCurrentEntry = -1; + fNSysInfo = other.fNSysInfo; fMode = other.fMode; fInitOK = other.fInitOK; fDebug = other.fDebug; @@ -160,12 +167,37 @@ void AliAnalysisManager::Init(TTree *tree) // Init() will be called many times when running with PROOF. if (!tree) return; if (fDebug > 1) { - printf("->AliAnalysisManager::Init(%s)\n", tree->GetName()); + printf("->AliAnalysisManager::InitTree(%s)\n", tree->GetName()); + } + + // Call InitTree of EventHandler + if (fOutputEventHandler) { + if (fMode == kProofAnalysis) { + fOutputEventHandler->Init(0x0, "proof"); + } else { + fOutputEventHandler->Init(0x0, "local"); + } } if (fInputEventHandler) { - fInputEventHandler->SetInputTree(tree); - fInputEventHandler->InitIO("proof"); + if (fMode == kProofAnalysis) { + fInputEventHandler->Init(tree, "proof"); + } else { + fInputEventHandler->Init(tree, "local"); + } + } else { + // If no input event handler we need to get the tree once + // for the chain + if(!tree->GetTree()) tree->LoadTree(0); + } + + + if (fMCtruthEventHandler) { + if (fMode == kProofAnalysis) { + fMCtruthEventHandler->Init(0x0, "proof"); + } else { + fMCtruthEventHandler->Init(0x0, "local"); + } } if (!fInitOK) InitAnalysis(); @@ -182,18 +214,6 @@ void AliAnalysisManager::Init(TTree *tree) } } -//______________________________________________________________________________ -void AliAnalysisManager::Begin(TTree *tree) -{ - // The Begin() function is called at the start of the query. - // When running with PROOF Begin() is only called on the client. - // The tree argument is deprecated (on PROOF 0 is passed). - if (fDebug > 1) { - cout << "AliAnalysisManager::Begin()" << endl; - } - Init(tree); -} - //______________________________________________________________________________ void AliAnalysisManager::SlaveBegin(TTree *tree) { @@ -203,33 +223,33 @@ void AliAnalysisManager::SlaveBegin(TTree *tree) if (fDebug > 1) { cout << "->AliAnalysisManager::SlaveBegin()" << endl; } - // Call InitIO of EventHandler + + // Call Init of EventHandler if (fOutputEventHandler) { - if (fMode == kProofAnalysis) { - fOutputEventHandler->InitIO("proof"); - } else { - fOutputEventHandler->InitIO("local"); - } + if (fMode == kProofAnalysis) { + fOutputEventHandler->Init("proof"); + } else { + fOutputEventHandler->Init("local"); + } } + if (fInputEventHandler) { - if (fMode == kProofAnalysis) { - fInputEventHandler->SetInputTree(tree); - fInputEventHandler->InitIO("proof"); - } else { - fInputEventHandler->SetInputTree(tree); - fInputEventHandler->InitIO("local"); - } + fInputEventHandler->SetInputTree(tree); + if (fMode == kProofAnalysis) { + fInputEventHandler->Init("proof"); + } else { + fInputEventHandler->Init("local"); + } } if (fMCtruthEventHandler) { - if (fMode == kProofAnalysis) { - fMCtruthEventHandler->InitIO("proof"); - } else { - fMCtruthEventHandler->InitIO("local"); - } + if (fMode == kProofAnalysis) { + fMCtruthEventHandler->Init("proof"); + } else { + fMCtruthEventHandler->Init("local"); + } } - - // + TIter next(fTasks); AliAnalysisTask *task; // Call CreateOutputObjects for all tasks @@ -237,9 +257,8 @@ void AliAnalysisManager::SlaveBegin(TTree *tree) TDirectory *curdir = gDirectory; task->CreateOutputObjects(); if (curdir) curdir->cd(); - } - if (fMode == kLocalAnalysis) - Init(tree); + } + if (fDebug > 1) { cout << "<-AliAnalysisManager::SlaveBegin()" << endl; } @@ -300,11 +319,11 @@ Bool_t AliAnalysisManager::Process(Long64_t entry) // Assuming that fChain is the pointer to the TChain being processed, // use fChain->GetTree()->GetEntry(entry). if (fDebug > 1) { - cout << "->AliAnalysisManager::Process()" << endl; + cout << "->AliAnalysisManager::Process(" << entry << ")" << endl; } - if (fInputEventHandler) fInputEventHandler ->BeginEvent(); - if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(); - if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(); + if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry); + if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry); + if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry); GetEntry(entry); ExecAnalysis(); @@ -334,15 +353,70 @@ void AliAnalysisManager::PackOutput(TList *target) TIter next(fOutputs); AliAnalysisDataContainer *output; while ((output=(AliAnalysisDataContainer*)next())) { - if (output->GetData()) { + if (output->GetData() && !output->IsSpecialOutput()) { if (output->GetProducer()->IsPostEventLoop()) continue; + + const char *filename = output->GetFileName(); + if (!(strcmp(filename, "default"))) { + if (fOutputEventHandler) filename = fOutputEventHandler->GetOutputFileName(); + } + if (strlen(filename)) { + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename); + TDirectory *opwd = gDirectory; + if (file) file->cd(); + else file = new TFile(filename, "RECREATE"); + if (file->IsZombie()) continue; + // Clear file list to release object ownership to user. + // Save data to file, then close. + file->Clear(); + output->GetData()->Write(); + file->Close(); + // Set null directory to histograms and trees. + TMethodCall callEnv; + if (output->GetData()->IsA()) + callEnv.InitWithPrototype(output->GetData()->IsA(), "SetDirectory", "TDirectory*"); + if (callEnv.IsValid()) { + callEnv.SetParam(Long_t(0)); + callEnv.Execute(output->GetData()); + } + // Restore current directory + if (opwd) opwd->cd(); + } AliAnalysisDataWrapper *wrap = output->ExportData(); // Output wrappers must delete data after merging (AG 13/11/07) wrap->SetDeleteData(kTRUE); if (fDebug > 1) printf(" Packing container %s...\n", output->GetName()); target->Add(wrap); } + // Special outputs files are closed and copied on the remote location + if (output->IsSpecialOutput() && strlen(output->GetFileName())) { + TDirectory *opwd = gDirectory; + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(output->GetFileName()); + if (!file) continue; + file->cd(); + if (output->GetData()) output->GetData()->Write(); + file->Close(); + if (opwd) opwd->cd(); + if (strlen(fSpecialOutputLocation.Data())) { + TString remote = fSpecialOutputLocation; + remote += "/"; + Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();"); + remote += Form("%s_%d_", gSystem->HostName(), gid); + remote += output->GetFileName(); + TFile::Cp(output->GetFileName(), remote.Data()); + } else { + // No special location specified-> use TProofFile as merging utility + char line[256]; + sprintf(line, "((TList*)0x%lx)->Add(new TProofFile(\"%s\"));", + (ULong_t)target, output->GetFileName()); + gROOT->ProcessLine(line); + } + } } + // Cleanup tasks on each slave + TIter nexttask(fTasks); + AliAnalysisTask *task; + while ((task=(AliAnalysisTask*)nexttask())) task->Cleanup(); } if (fDebug > 1) { printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize()); @@ -361,7 +435,8 @@ void AliAnalysisManager::ImportWrappers(TList *source) AliAnalysisDataWrapper *wrap; Int_t icont = 0; while ((cont=(AliAnalysisDataContainer*)next())) { - if (cont->GetProducer()->IsPostEventLoop()) continue; + if (cont->GetProducer()->IsPostEventLoop() || + cont->IsSpecialOutput()) continue; wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName()); if (!wrap && fDebug>1) { printf("(WW) ImportWrappers: container %s not found in analysis output !\n", cont->GetName()); @@ -380,8 +455,7 @@ void AliAnalysisManager::ImportWrappers(TList *source) //______________________________________________________________________________ void AliAnalysisManager::UnpackOutput(TList *source) { - // Called by AliAnalysisSelector::Terminate. Output containers should - // be in source in the same order as in fOutputs. + // Called by AliAnalysisSelector::Terminate only on the client. if (fDebug > 1) { cout << "->AliAnalysisManager::UnpackOutput()" << endl; } @@ -425,6 +499,7 @@ void AliAnalysisManager::UnpackOutput(TList *source) if (!filename || !strlen(filename)) continue; TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename); + TDirectory *opwd = gDirectory; if (file) file->cd(); else file = new TFile(filename, "RECREATE"); if (file->IsZombie()) continue; @@ -437,6 +512,7 @@ void AliAnalysisManager::UnpackOutput(TList *source) callEnv.Execute(output->GetData()); } output->GetData()->Write(); + if (opwd) opwd->cd(); } if (fDebug > 1) { cout << "<-AliAnalysisManager::UnpackOutput()" << endl; @@ -463,6 +539,47 @@ void AliAnalysisManager::Terminate() if (fInputEventHandler) fInputEventHandler ->TerminateIO(); if (fOutputEventHandler) fOutputEventHandler ->TerminateIO(); if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO(); + TIter next1(fOutputs); + AliAnalysisDataContainer *output; + while ((output=(AliAnalysisDataContainer*)next1())) { + // Close all files at output + 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->IsZombie()) continue; + file->Close(); + } + + Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE; + if (getsysInfo) { + TDirectory *cdir = gDirectory; + TFile f("syswatch.root", "RECREATE"); + if (!f.IsZombie()) { + TTree *tree = AliSysInfo::MakeTree("syswatch.log"); + tree->SetMarkerStyle(kCircle); + tree->SetMarkerColor(kBlue); + tree->SetMarkerSize(0.5); + if (!gROOT->IsBatch()) { + tree->SetAlias("event", "id0"); + tree->SetAlias("memUSED", "mi.fMemUsed"); + tree->SetAlias("userCPU", "pI.fCpuUser"); + TCanvas *c = new TCanvas("SysInfo","SysInfo",10,10,800,600); + c->Divide(2,1,0.01,0.01); + c->cd(1); + tree->Draw("memUSED:event","","", 1234567890, 0); + c->cd(2); + tree->Draw("userCPU:event","","", 1234567890, 0); + } + tree->Write(); + f.Close(); + delete tree; + } + if (cdir) cdir->cd(); + } } //______________________________________________________________________________ @@ -501,7 +618,10 @@ AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name, break; case kOutputContainer: fOutputs->Add(cont); - if (filename && strlen(filename)) cont->SetFileName(filename); + if (filename && strlen(filename)) { + cont->SetFileName(filename); + cont->SetDataOwned(kFALSE); // data owned by the file + } break; case kExchangeContainer: break; @@ -645,6 +765,13 @@ Bool_t AliAnalysisManager::InitAnalysis() void AliAnalysisManager::PrintStatus(Option_t *option) const { // Print task hierarchy. + if (!fInitOK) { + Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName()); + return; + } + Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE; + if (getsysInfo) + Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo); TIter next(fTopTasks); AliAnalysisTask *task; while ((task=(AliAnalysisTask*)next())) @@ -659,9 +786,10 @@ void AliAnalysisManager::ResetAnalysis() } //______________________________________________________________________________ -void AliAnalysisManager::StartAnalysis(const char *type, TTree *tree) +void AliAnalysisManager::StartAnalysis(const char *type, TTree *tree, Long64_t nentries, Long64_t firstentry) { // Start analysis for this manager. Analysis task can be: LOCAL, PROOF or GRID. +// Process nentries starting from firstentry if (!fInitOK) { Error("StartAnalysis","Analysis manager was not initialized !"); return; @@ -680,7 +808,7 @@ void AliAnalysisManager::StartAnalysis(const char *type, TTree *tree) Warning("StartAnalysis", "GRID analysis mode not implemented. Running local."); fMode = kLocalAnalysis; } - char line[128]; + char line[256]; SetEventLoop(kFALSE); // Disable all branches if requested and set event loop mode if (tree) { @@ -691,7 +819,16 @@ void AliAnalysisManager::StartAnalysis(const char *type, TTree *tree) SetEventLoop(kTRUE); } - TChain *chain = dynamic_cast(tree); + TChain *chain = 0; + TString ttype = "TTree"; + if (tree->IsA() == TChain::Class()) { + chain = (TChain*)tree; + if (!chain || !chain->GetListOfFiles()->First()) { + Error("StartAnalysis", "Cannot process null or empty chain..."); + return; + } + ttype = "TChain"; + } // Initialize locally all tasks TIter next(fTasks); @@ -716,11 +853,10 @@ void AliAnalysisManager::StartAnalysis(const char *type, TTree *tree) return; } // Run tree-based analysis via AliAnalysisSelector -// 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); - sprintf(line, "((TTree*)0x%lx)->Process(selector);",(ULong_t)tree); + sprintf(line, "((%s*)0x%lx)->Process(selector, \"\",%lld, %lld);",ttype.Data(),(ULong_t)tree, nentries, firstentry); gROOT->ProcessLine(line); break; case kProofAnalysis: @@ -733,7 +869,7 @@ void AliAnalysisManager::StartAnalysis(const char *type, TTree *tree) if (chain) { chain->SetProof(); cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl; - chain->Process("AliAnalysisSelector"); + chain->Process("AliAnalysisSelector", "", nentries, firstentry); } else { printf("StartAnalysis: no chain\n"); return; @@ -744,10 +880,63 @@ void AliAnalysisManager::StartAnalysis(const char *type, TTree *tree) } } +//______________________________________________________________________________ +void AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry) +{ +// Start analysis for this manager on a given dataset. Analysis task can be: +// LOCAL, PROOF or GRID. Process nentries starting from firstentry. + if (!fInitOK) { + Error("StartAnalysis","Analysis manager was not initialized !"); + return; + } + if (fDebug>1) { + cout << "StartAnalysis: " << GetName() << endl; + } + TString anaType = type; + anaType.ToLower(); + if (!anaType.Contains("proof")) { + Error("Cannot process datasets in %s mode. Try PROOF.", type); + return; + } + fMode = kProofAnalysis; + char line[256]; + SetEventLoop(kTRUE); + // Set the dataset flag + TObject::SetBit(kUseDataSet); + fTree = 0; + + // Initialize locally all tasks + TIter next(fTasks); + AliAnalysisTask *task; + while ((task=(AliAnalysisTask*)next())) { + task->LocalInit(); + } + + if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) { + printf("StartAnalysis: no PROOF!!!\n"); + return; + } + sprintf(line, "gProof->AddInput((TObject*)0x%lx);", (ULong_t)this); + gROOT->ProcessLine(line); + sprintf(line, "gProof->GetDataSet(\"%s\");", dataset); + if (!gROOT->ProcessLine(line)) { + Error("StartAnalysis", "Dataset %s not found", dataset); + return; + } + sprintf(line, "gProof->Process(\"%s\", \"AliAnalysisSelector\", \"\", %lld, %lld);", + dataset, nentries, firstentry); + cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl; + gROOT->ProcessLine(line); +} + //______________________________________________________________________________ void AliAnalysisManager::ExecAnalysis(Option_t *option) { // Execute analysis. + static Long64_t ncalls = 0; + Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE; + if (getsysInfo && ncalls==0) AliSysInfo::AddStamp("Start", (Int_t)ncalls); + ncalls++; if (!fInitOK) { Error("ExecAnalysis", "Analysis manager was not initialized !"); return; @@ -764,14 +953,17 @@ void AliAnalysisManager::ExecAnalysis(Option_t *option) return; } cont->SetData(fTree); // This will notify all consumers + Long64_t entry = fTree->GetTree()->GetReadEntry(); + // // Call BeginEvent() for optional input/output and MC services - if (fInputEventHandler) fInputEventHandler ->BeginEvent(); - if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(); - if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(); + if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry); + if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry); + if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry); // // Execute the tasks - TIter next1(cont->GetConsumers()); +// TIter next1(cont->GetConsumers()); + TIter next1(fTopTasks); while ((task=(AliAnalysisTask*)next1())) { if (fDebug >1) { cout << " Executing task " << task->GetName() << endl; @@ -784,15 +976,17 @@ void AliAnalysisManager::ExecAnalysis(Option_t *option) if (fInputEventHandler) fInputEventHandler ->FinishEvent(); if (fOutputEventHandler) fOutputEventHandler ->FinishEvent(); if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent(); -// + // Gather system information if requested + if (getsysInfo && ((ncalls%fNSysInfo)==0)) + AliSysInfo::AddStamp(Form("Event#%lld",ncalls),(Int_t)ncalls); 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(); + if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1); + if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1); + if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1); TIter next2(fTopTasks); while ((task=(AliAnalysisTask*)next2())) { task->SetActive(kTRUE);