X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=ANALYSIS%2FAliAnalysisManager.cxx;h=8f3be8618a877776040788e7774c85f1cb663c11;hb=b7980dfe7f95c317715bf8f6af9129780af1b1e0;hp=c96618341812e6aa4fecea7955aea92107b6207d;hpb=f3d59a0dca608c8600081e2577dabc5c6c1cd4cf;p=u%2Fmrichter%2FAliRoot.git diff --git a/ANALYSIS/AliAnalysisManager.cxx b/ANALYSIS/AliAnalysisManager.cxx index c9661834181..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; @@ -178,7 +185,12 @@ void AliAnalysisManager::Init(TTree *tree) } 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) { @@ -341,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()); @@ -368,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()); @@ -387,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; } @@ -432,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; @@ -444,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; @@ -470,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(); + } } //______________________________________________________________________________ @@ -508,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; @@ -652,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())) @@ -666,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; @@ -687,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) { @@ -698,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); @@ -723,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: @@ -740,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; @@ -751,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; @@ -780,7 +962,8 @@ void AliAnalysisManager::ExecAnalysis(Option_t *option) 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; @@ -793,7 +976,9 @@ 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