1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 // Author: Andrei Gheata, 31/05/2006
19 //==============================================================================
20 // AliAnalysisManager - Manager analysis class. Allows creation of several
21 // analysis tasks and data containers storing their input/output. Allows
22 // connecting/chaining tasks via shared data containers. Serializes the current
23 // event for all tasks depending only on initial input data.
24 //==============================================================================
26 //==============================================================================
28 #include "AliAnalysisManager.h"
31 #include <Riostream.h>
38 #include <TMethodCall.h>
43 #include <TStopwatch.h>
46 #include "AliAnalysisSelector.h"
47 #include "AliAnalysisGrid.h"
48 #include "AliAnalysisTask.h"
49 #include "AliAnalysisDataContainer.h"
50 #include "AliAnalysisDataSlot.h"
51 #include "AliVEventHandler.h"
52 #include "AliVEventPool.h"
53 #include "AliSysInfo.h"
54 #include "AliAnalysisStatistics.h"
56 ClassImp(AliAnalysisManager)
58 AliAnalysisManager *AliAnalysisManager::fgAnalysisManager = NULL;
59 TString AliAnalysisManager::fgCommonFileName = "";
60 Int_t AliAnalysisManager::fPBUpdateFreq = 1;
62 //______________________________________________________________________________
63 AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
66 fInputEventHandler(NULL),
67 fOutputEventHandler(NULL),
68 fMCtruthEventHandler(NULL),
72 fMode(kLocalAnalysis),
77 fSpecialOutputLocation(""),
91 fAutoBranchHandling(kTRUE),
101 // Default constructor.
102 fgAnalysisManager = this;
103 fgCommonFileName = "AnalysisResults.root";
104 if (TClass::IsCallingNew() != TClass::kDummyNew) {
105 fTasks = new TObjArray();
106 fTopTasks = new TObjArray();
107 fZombies = new TObjArray();
108 fContainers = new TObjArray();
109 fInputs = new TObjArray();
110 fOutputs = new TObjArray();
111 fParamCont = new TObjArray();
112 fGlobals = new TMap();
117 //______________________________________________________________________________
118 AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
121 fInputEventHandler(NULL),
122 fOutputEventHandler(NULL),
123 fMCtruthEventHandler(NULL),
128 fInitOK(other.fInitOK),
129 fMustClean(other.fMustClean),
130 fIsRemote(other.fIsRemote),
131 fDebug(other.fDebug),
132 fSpecialOutputLocation(""),
146 fAutoBranchHandling(other.fAutoBranchHandling),
149 fNcalls(other.fNcalls),
150 fMaxEntries(other.fMaxEntries),
151 fStatisticsMsg(other.fStatisticsMsg),
152 fRequestedBranches(other.fRequestedBranches),
153 fStatistics(other.fStatistics),
154 fGlobals(other.fGlobals)
157 fTasks = new TObjArray(*other.fTasks);
158 fTopTasks = new TObjArray(*other.fTopTasks);
159 fZombies = new TObjArray(*other.fZombies);
160 fContainers = new TObjArray(*other.fContainers);
161 fInputs = new TObjArray(*other.fInputs);
162 fOutputs = new TObjArray(*other.fOutputs);
163 fParamCont = new TObjArray(*other.fParamCont);
164 fgCommonFileName = "AnalysisResults.root";
165 fgAnalysisManager = this;
168 //______________________________________________________________________________
169 AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& other)
172 if (&other != this) {
173 TNamed::operator=(other);
174 fInputEventHandler = other.fInputEventHandler;
175 fOutputEventHandler = other.fOutputEventHandler;
176 fMCtruthEventHandler = other.fMCtruthEventHandler;
177 fEventPool = other.fEventPool;
180 fNSysInfo = other.fNSysInfo;
182 fInitOK = other.fInitOK;
183 fIsRemote = other.fIsRemote;
184 fDebug = other.fDebug;
185 fTasks = new TObjArray(*other.fTasks);
186 fTopTasks = new TObjArray(*other.fTopTasks);
187 fZombies = new TObjArray(*other.fZombies);
188 fContainers = new TObjArray(*other.fContainers);
189 fInputs = new TObjArray(*other.fInputs);
190 fOutputs = new TObjArray(*other.fOutputs);
191 fParamCont = new TObjArray(*other.fParamCont);
192 fDebugOptions = NULL;
194 fCommonOutput = NULL;
197 fExtraFiles = other.fExtraFiles;
198 fgCommonFileName = "AnalysisResults.root";
199 fgAnalysisManager = this;
200 fAutoBranchHandling = other.fAutoBranchHandling;
201 fTable.Clear("nodelete");
202 fRunFromPath = other.fRunFromPath;
203 fNcalls = other. fNcalls;
204 fMaxEntries = other.fMaxEntries;
205 fStatisticsMsg = other.fStatisticsMsg;
206 fRequestedBranches = other.fRequestedBranches;
207 fStatistics = other.fStatistics;
208 fGlobals = new TMap();
213 //______________________________________________________________________________
214 AliAnalysisManager::~AliAnalysisManager()
217 if (fTasks) {fTasks->Delete(); delete fTasks;}
218 if (fTopTasks) delete fTopTasks;
219 if (fZombies) delete fZombies;
220 if (fContainers) {fContainers->Delete(); delete fContainers;}
221 if (fInputs) delete fInputs;
222 if (fOutputs) delete fOutputs;
223 if (fParamCont) delete fParamCont;
224 if (fDebugOptions) delete fDebugOptions;
225 if (fGridHandler) delete fGridHandler;
226 if (fInputEventHandler) delete fInputEventHandler;
227 if (fOutputEventHandler) delete fOutputEventHandler;
228 if (fMCtruthEventHandler) delete fMCtruthEventHandler;
229 if (fEventPool) delete fEventPool;
230 if (fgAnalysisManager==this) fgAnalysisManager = NULL;
231 if (fGlobals) {fGlobals->DeleteAll(); delete fGlobals;}
234 //______________________________________________________________________________
235 Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
237 // Read one entry of the tree or a whole branch.
238 fCurrentEntry = entry;
239 if (!fAutoBranchHandling)
241 return fTree ? fTree->GetTree()->GetEntry(entry, getall) : -1;
244 //______________________________________________________________________________
245 Int_t AliAnalysisManager::GetRunFromAlienPath(const char *path)
247 // Attempt to extract run number from input data path. Works only for paths to
248 // alice data in alien.
249 // sim: /alice/sim/<production>/run_no/...
250 // data: /alice/data/year/period/000run_no/... (ESD or AOD)
251 TString type = "unknown";
253 if (s.Contains("/alice/data")) type = "real";
254 else if (s.Contains("/alice/sim")) type = "simulated";
257 ind1 = s.Index("/00");
259 ind2 = s.Index("/",ind1+1);
260 if (ind2-ind1>8) srun = s(ind1+1, ind2-ind1-1);
263 ind1 = s.Index("/LHC");
265 ind1 = s.Index("/",ind1+1);
267 ind2 = s.Index("/",ind1+1);
268 if (ind2>0) srun = s(ind1+1, ind2-ind1-1);
272 Int_t run = srun.Atoi();
273 if (run>0) printf("=== GetRunFromAlienPath: run %d of %s data ===\n", run, type.Data());
277 //______________________________________________________________________________
278 Bool_t AliAnalysisManager::Init(TTree *tree)
280 // The Init() function is called when the selector needs to initialize
281 // a new tree or chain. Typically here the branch addresses of the tree
282 // will be set. It is normaly not necessary to make changes to the
283 // generated code, but the routine can be extended by the user if needed.
284 // Init() will be called many times when running with PROOF.
285 Bool_t init = kFALSE;
286 if (!tree) return kFALSE; // Should not happen - protected in selector caller
288 printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
290 // Call InitTree of EventHandler
291 if (fOutputEventHandler) {
292 if (fMode == kProofAnalysis) {
293 init = fOutputEventHandler->Init(0x0, "proof");
295 init = fOutputEventHandler->Init(0x0, "local");
298 Error("Init", "Output event handler failed to initialize");
303 if (fInputEventHandler) {
304 if (fMode == kProofAnalysis) {
305 init = fInputEventHandler->Init(tree, "proof");
307 init = fInputEventHandler->Init(tree, "local");
310 Error("Init", "Input event handler failed to initialize tree");
314 // If no input event handler we need to get the tree once
316 if(!tree->GetTree()) {
317 Long64_t readEntry = tree->LoadTree(0);
318 if (readEntry == -2) {
319 Error("Init", "Input tree has no entry. Exiting");
325 if (fMCtruthEventHandler) {
326 if (fMode == kProofAnalysis) {
327 init = fMCtruthEventHandler->Init(0x0, "proof");
329 init = fMCtruthEventHandler->Init(0x0, "local");
332 Error("Init", "MC event handler failed to initialize");
337 if (!fInitOK) InitAnalysis();
338 if (!fInitOK) return kFALSE;
341 AliAnalysisDataContainer *top = fCommonInput;
342 if (!top) top = (AliAnalysisDataContainer*)fInputs->At(0);
344 Error("Init","No top input container !");
348 CheckBranches(kFALSE);
350 printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
355 //______________________________________________________________________________
356 void AliAnalysisManager::SlaveBegin(TTree *tree)
358 // The SlaveBegin() function is called after the Begin() function.
359 // When running with PROOF SlaveBegin() is called on each slave server.
360 // The tree argument is deprecated (on PROOF 0 is passed).
361 if (fDebug > 1) printf("->AliAnalysisManager::SlaveBegin()\n");
363 // Apply debug options
366 if (!CheckTasks()) Fatal("SlaveBegin", "Not all needed libraries were loaded");
367 static Bool_t isCalled = kFALSE;
368 Bool_t init = kFALSE;
369 Bool_t initOK = kTRUE;
371 TDirectory *curdir = gDirectory;
372 // Call SlaveBegin only once in case of mixing
373 if (isCalled && fMode==kMixingAnalysis) return;
375 // Call Init of EventHandler
376 if (fOutputEventHandler) {
377 if (fMode == kProofAnalysis) {
378 // Merging AOD's in PROOF via TProofOutputFile
379 if (fDebug > 1) printf(" Initializing AOD output file %s...\n", fOutputEventHandler->GetOutputFileName());
380 init = fOutputEventHandler->Init("proof");
381 if (!init) msg = "Failed to initialize output handler on worker";
383 init = fOutputEventHandler->Init("local");
384 if (!init) msg = "Failed to initialize output handler";
387 if (!fSelector) Error("SlaveBegin", "Selector not set");
388 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
391 if (fInputEventHandler) {
392 fInputEventHandler->SetInputTree(tree);
393 if (fMode == kProofAnalysis) {
394 init = fInputEventHandler->Init("proof");
395 if (!init) msg = "Failed to initialize input handler on worker";
397 init = fInputEventHandler->Init("local");
398 if (!init) msg = "Failed to initialize input handler";
401 if (!fSelector) Error("SlaveBegin", "Selector not set");
402 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
405 if (fMCtruthEventHandler) {
406 if (fMode == kProofAnalysis) {
407 init = fMCtruthEventHandler->Init("proof");
408 if (!init) msg = "Failed to initialize MC handler on worker";
410 init = fMCtruthEventHandler->Init("local");
411 if (!init) msg = "Failed to initialize MC handler";
414 if (!fSelector) Error("SlaveBegin", "Selector not set");
415 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
417 if (curdir) curdir->cd();
421 AliAnalysisTask *task;
422 // Call CreateOutputObjects for all tasks
423 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
424 Bool_t dirStatus = TH1::AddDirectoryStatus();
426 while ((task=(AliAnalysisTask*)next())) {
428 // Start with memory as current dir and make sure by default histograms do not get attached to files.
429 TH1::AddDirectory(kFALSE);
430 task->CreateOutputObjects();
431 if (!task->CheckPostData()) {
432 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
433 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
434 ####### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ##########", task->GetName(), task->ClassName());
436 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
439 TH1::AddDirectory(dirStatus);
440 if (curdir) curdir->cd();
441 if (fDebug > 1) printf("<-AliAnalysisManager::SlaveBegin()\n");
444 //______________________________________________________________________________
445 Bool_t AliAnalysisManager::Notify()
447 // The Notify() function is called when a new file is opened. This
448 // can be either for a new TTree in a TChain or when when a new TTree
449 // is started when using PROOF. It is normaly not necessary to make changes
450 // to the generated code, but the routine can be extended by the
451 // user if needed. The return value is currently not used.
452 if (!fTree) return kFALSE;
453 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) return kFALSE;
455 fTable.Clear("nodelete"); // clearing the hash table may not be needed -> C.L.
456 if (fMode == kProofAnalysis) fIsRemote = kTRUE;
458 TFile *curfile = fTree->GetCurrentFile();
460 Error("Notify","No current file");
464 if (fDebug > 1) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
465 Int_t run = AliAnalysisManager::GetRunFromAlienPath(curfile->GetName());
466 if (run && (run != fRunFromPath)) {
468 if (fDebug > 1) printf(" ### run found from path: %d\n", run);
471 AliAnalysisTask *task;
473 // Call Notify of the event handlers
474 if (fInputEventHandler) {
475 fInputEventHandler->Notify(curfile->GetName());
478 if (fOutputEventHandler) {
479 fOutputEventHandler->Notify(curfile->GetName());
482 if (fMCtruthEventHandler) {
483 fMCtruthEventHandler->Notify(curfile->GetName());
486 // Call Notify for all tasks
487 while ((task=(AliAnalysisTask*)next()))
490 if (fDebug > 1) printf("<-AliAnalysisManager::Notify()\n");
494 //______________________________________________________________________________
495 Bool_t AliAnalysisManager::Process(Long64_t)
497 // The Process() function is called for each entry in the tree (or possibly
498 // keyed object in the case of PROOF) to be processed. The entry argument
499 // specifies which entry in the currently loaded tree is to be processed.
500 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
501 // to read either all or the required parts of the data. When processing
502 // keyed objects with PROOF, the object is already loaded and is available
503 // via the fObject pointer.
505 // This function should contain the "body" of the analysis. It can contain
506 // simple or elaborate selection criteria, run algorithms on the data
507 // of the event and typically fill histograms.
509 // WARNING when a selector is used with a TChain, you must use
510 // the pointer to the current TTree to call GetEntry(entry).
511 // The entry is always the local entry number in the current tree.
512 // Assuming that fChain is the pointer to the TChain being processed,
513 // use fChain->GetTree()->GetEntry(entry).
515 // This method is obsolete. ExecAnalysis is called instead.
519 //______________________________________________________________________________
520 void AliAnalysisManager::PackOutput(TList *target)
522 // Pack all output data containers in the output list. Called at SlaveTerminate
523 // stage in PROOF case for each slave.
524 if (fDebug > 1) printf("->AliAnalysisManager::PackOutput()\n");
526 Error("PackOutput", "No target. Exiting.");
529 TDirectory *cdir = gDirectory;
531 if (fInputEventHandler) fInputEventHandler ->Terminate();
532 if (fOutputEventHandler) fOutputEventHandler ->Terminate();
533 if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
536 // Call FinishTaskOutput() for each event loop task (not called for
537 // post-event loop tasks - use Terminate() fo those)
538 TIter nexttask(fTasks);
539 AliAnalysisTask *task;
540 while ((task=(AliAnalysisTask*)nexttask())) {
541 if (!task->IsPostEventLoop()) {
542 if (fDebug > 1) printf("->FinishTaskOutput: task %s\n", task->GetName());
543 task->FinishTaskOutput();
545 if (fDebug > 1) printf("<-FinishTaskOutput: task %s\n", task->GetName());
548 // Write statistics message on the workers.
549 if (fStatistics) WriteStatisticsMsg(fNcalls);
551 if (fMode == kProofAnalysis) {
552 TIter next(fOutputs);
553 AliAnalysisDataContainer *output;
554 Bool_t isManagedByHandler = kFALSE;
557 while ((output=(AliAnalysisDataContainer*)next())) {
558 // Do not consider outputs of post event loop tasks
559 isManagedByHandler = kFALSE;
560 if (output->GetProducer() && output->GetProducer()->IsPostEventLoop()) continue;
561 const char *filename = output->GetFileName();
562 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
563 isManagedByHandler = kTRUE;
564 printf("#### Handler output. Extra: %s\n", fExtraFiles.Data());
565 filename = fOutputEventHandler->GetOutputFileName();
567 // Check if data was posted to this container. If not, issue an error.
568 if (!output->GetData() && !isManagedByHandler) {
569 Error("PackOutput", "No data for output container %s. Forgot to PostData ?", output->GetName());
572 if (!output->IsSpecialOutput()) {
574 if (strlen(filename) && !isManagedByHandler) {
575 // Backup current folder
576 TDirectory *opwd = gDirectory;
577 // File resident outputs.
578 // Check first if the file exists.
579 TString openoption = "RECREATE";
580 Bool_t firsttime = kTRUE;
581 if (filestmp.FindObject(output->GetFileName())) {
584 filestmp.Add(new TNamed(output->GetFileName(),""));
586 if (!gSystem->AccessPathName(output->GetFileName()) && !firsttime) openoption = "UPDATE";
587 // TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
588 // Save data to file, then close.
589 if (output->GetData()->InheritsFrom(TCollection::Class())) {
590 // If data is a collection, we set the name of the collection
591 // as the one of the container and we save as a single key.
592 TCollection *coll = (TCollection*)output->GetData();
593 coll->SetName(output->GetName());
594 // coll->Write(output->GetName(), TObject::kSingleKey);
596 if (output->GetData()->InheritsFrom(TTree::Class())) {
597 TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
598 // Save data to file, then close.
599 TTree *tree = (TTree*)output->GetData();
600 // Check if tree is in memory
601 if (tree->GetDirectory()==gROOT) tree->SetDirectory(gDirectory);
605 // output->GetData()->Write();
608 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
610 // printf(" file %s listing content:\n", filename);
613 // Clear file list to release object ownership to user.
616 output->SetFile(NULL);
617 // Restore current directory
618 if (opwd) opwd->cd();
620 // Memory-resident outputs
621 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
623 AliAnalysisDataWrapper *wrap = 0;
624 if (isManagedByHandler) {
625 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
626 wrap->SetName(output->GetName());
628 else wrap =output->ExportData();
629 // Output wrappers must NOT delete data after merging - the user owns them
630 wrap->SetDeleteData(kFALSE);
633 // Special outputs. The file must be opened and connected to the container.
634 TDirectory *opwd = gDirectory;
635 TFile *file = output->GetFile();
637 AliAnalysisTask *producer = output->GetProducer();
639 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
640 output->GetFileName(), output->GetName(), producer->ClassName());
643 TString outFilename = file->GetName();
644 if (fDebug > 1) printf("PackOutput %s: special output\n", output->GetName());
645 if (isManagedByHandler) {
646 // Terminate IO for files managed by the output handler
647 // file->Write() moved to AOD handler (A.G. 11.01.10)
648 // if (file) file->Write();
649 if (file && fDebug > 2) {
650 printf(" handled file %s listing content:\n", file->GetName());
653 fOutputEventHandler->TerminateIO();
656 // Release object ownership to users after writing data to file
657 if (output->GetData()->InheritsFrom(TCollection::Class())) {
658 // If data is a collection, we set the name of the collection
659 // as the one of the container and we save as a single key.
660 TCollection *coll = (TCollection*)output->GetData();
661 coll->SetName(output->GetName());
662 coll->Write(output->GetName(), TObject::kSingleKey);
664 if (output->GetData()->InheritsFrom(TTree::Class())) {
665 TTree *tree = (TTree*)output->GetData();
666 tree->SetDirectory(file);
669 output->GetData()->Write();
673 printf(" file %s listing content:\n", output->GetFileName());
676 // Clear file list to release object ownership to user.
679 output->SetFile(NULL);
681 // Restore current directory
682 if (opwd) opwd->cd();
683 // Check if a special output location was provided or the output files have to be merged
684 if (strlen(fSpecialOutputLocation.Data())) {
685 TString remote = fSpecialOutputLocation;
687 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
688 if (remote.BeginsWith("alien:")) {
689 gROOT->ProcessLine("TGrid::Connect(\"alien:\", gProofServ->GetUser());");
690 remote += outFilename;
691 remote.ReplaceAll(".root", Form("_%d.root", gid));
693 remote += Form("%s_%d_", gSystem->HostName(), gid);
694 remote += outFilename;
697 Info("PackOutput", "Output file for container %s to be copied \n at: %s. No merging.",
698 output->GetName(), remote.Data());
699 TFile::Cp ( outFilename.Data(), remote.Data() );
700 // Copy extra outputs
701 if (fExtraFiles.Length() && isManagedByHandler) {
702 TObjArray *arr = fExtraFiles.Tokenize(" ");
704 TIter nextfilename(arr);
705 while ((os=(TObjString*)nextfilename())) {
706 outFilename = os->GetString();
707 remote = fSpecialOutputLocation;
709 if (remote.BeginsWith("alien://")) {
710 remote += outFilename;
711 remote.ReplaceAll(".root", Form("_%d.root", gid));
713 remote += Form("%s_%d_", gSystem->HostName(), gid);
714 remote += outFilename;
717 Info("PackOutput", "Extra AOD file %s to be copied \n at: %s. No merging.",
718 outFilename.Data(), remote.Data());
719 TFile::Cp ( outFilename.Data(), remote.Data() );
724 // No special location specified-> use TProofOutputFile as merging utility
725 // The file at this output slot must be opened in CreateOutputObjects
726 if (fDebug > 1) printf(" File for container %s to be merged via file merger...\n", output->GetName());
731 if (cdir) cdir->cd();
732 if (fDebug > 1) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
735 //______________________________________________________________________________
736 void AliAnalysisManager::ImportWrappers(TList *source)
738 // Import data in output containers from wrappers coming in source.
739 if (fDebug > 1) printf("->AliAnalysisManager::ImportWrappers()\n");
740 TIter next(fOutputs);
741 AliAnalysisDataContainer *cont;
742 AliAnalysisDataWrapper *wrap;
744 Bool_t inGrid = (fMode == kGridAnalysis)?kTRUE:kFALSE;
745 TDirectory *cdir = gDirectory;
746 while ((cont=(AliAnalysisDataContainer*)next())) {
748 if (cont->GetProducer() && cont->GetProducer()->IsPostEventLoop() && !inGrid) continue;
749 if (cont->IsRegisterDataset()) continue;
750 const char *filename = cont->GetFileName();
751 Bool_t isManagedByHandler = kFALSE;
752 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
753 isManagedByHandler = kTRUE;
754 filename = fOutputEventHandler->GetOutputFileName();
756 if (cont->IsSpecialOutput() || inGrid) {
757 if (strlen(fSpecialOutputLocation.Data())) continue;
758 // Copy merged file from PROOF scratch space.
759 // In case of grid the files are already in the current directory.
761 if (isManagedByHandler && fExtraFiles.Length()) {
762 // Copy extra registered dAOD files.
763 TObjArray *arr = fExtraFiles.Tokenize(" ");
765 TIter nextfilename(arr);
766 while ((os=(TObjString*)nextfilename())) GetFileFromWrapper(os->GetString(), source);
769 if (!GetFileFromWrapper(filename, source)) continue;
771 // Normally we should connect data from the copied file to the
772 // corresponding output container, but it is not obvious how to do this
773 // automatically if several objects in file...
774 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
775 if (!f) f = TFile::Open(filename, "READ");
777 Error("ImportWrappers", "Cannot open file %s in read-only mode", filename);
782 // Cd to the directory pointed by the container
783 TString folder = cont->GetFolderName();
784 if (!folder.IsNull()) f->cd(folder);
785 // Try to fetch first an object having the container name.
786 obj = gDirectory->Get(cont->GetName());
788 Warning("ImportWrappers", "Could not import object of type:%s for container %s in file %s:%s.\n Object will not be available in Terminate(). Try if possible to name the output object as the container (%s) or to embed it in a TList",
789 cont->GetType()->GetName(), cont->GetName(), filename, cont->GetFolderName(), cont->GetName());
792 wrap = new AliAnalysisDataWrapper(obj);
793 wrap->SetDeleteData(kFALSE);
795 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
797 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
802 printf(" Importing data for container %s\n", cont->GetName());
803 if (strlen(filename)) printf(" -> file %s\n", filename);
806 cont->ImportData(wrap);
808 if (cdir) cdir->cd();
809 if (fDebug > 1) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
812 //______________________________________________________________________________
813 void AliAnalysisManager::UnpackOutput(TList *source)
815 // Called by AliAnalysisSelector::Terminate only on the client.
816 if (fDebug > 1) printf("->AliAnalysisManager::UnpackOutput()\n");
818 Error("UnpackOutput", "No target. Exiting.");
821 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
823 if (fMode == kProofAnalysis) ImportWrappers(source);
825 TIter next(fOutputs);
826 AliAnalysisDataContainer *output;
827 while ((output=(AliAnalysisDataContainer*)next())) {
828 if (!output->GetData()) continue;
829 // Check if there are client tasks that run post event loop
830 if (output->HasConsumers()) {
831 // Disable event loop semaphore
832 output->SetPostEventLoop(kTRUE);
833 TObjArray *list = output->GetConsumers();
834 Int_t ncons = list->GetEntriesFast();
835 for (Int_t i=0; i<ncons; i++) {
836 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
837 task->CheckNotify(kTRUE);
838 // If task is active, execute it
839 if (task->IsPostEventLoop() && task->IsActive()) {
840 if (fDebug > 1) printf("== Executing post event loop task %s\n", task->GetName());
846 if (fDebug > 1) printf("<-AliAnalysisManager::UnpackOutput()\n");
849 //______________________________________________________________________________
850 void AliAnalysisManager::Terminate()
852 // The Terminate() function is the last function to be called during
853 // a query. It always runs on the client, it can be used to present
854 // the results graphically.
855 if (fDebug > 1) printf("->AliAnalysisManager::Terminate()\n");
856 TDirectory *cdir = gDirectory;
858 AliAnalysisTask *task;
859 AliAnalysisDataContainer *output;
862 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
863 // Call Terminate() for tasks
865 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
866 // Save all the canvases produced by the Terminate
867 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
871 AliSysInfo::AddStamp(Form("%s_TERMINATE",task->ClassName()),0, itask, 2);
873 if (TObject::TestBit(kSaveCanvases)) {
874 if (!gROOT->IsBatch()) {
875 if (fDebug>1) printf("Waiting 5 sec for %s::Terminate() to finish drawing ...\n", task->ClassName());
877 while (timer.CpuTime()<5) {
879 gSystem->ProcessEvents();
882 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
883 if (iend==0) continue;
885 for (Int_t ipict=0; ipict<iend; ipict++) {
886 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
887 if (!canvas) continue;
888 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
890 gROOT->GetListOfCanvases()->Delete();
894 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
895 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
896 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
898 TObjArray *allOutputs = new TObjArray();
900 for (icont=0; icont<fOutputs->GetEntriesFast(); icont++) allOutputs->Add(fOutputs->At(icont));
901 if (!IsSkipTerminate())
902 for (icont=0; icont<fParamCont->GetEntriesFast(); icont++) allOutputs->Add(fParamCont->At(icont));
903 TIter next1(allOutputs);
904 TString handlerFile = "";
905 TString extraOutputs = "";
906 if (fOutputEventHandler) {
907 handlerFile = fOutputEventHandler->GetOutputFileName();
908 extraOutputs = fOutputEventHandler->GetExtraOutputs();
912 while ((output=(AliAnalysisDataContainer*)next1())) {
913 // Special outputs or grid files have the files already closed and written.
915 if (fMode == kGridAnalysis && icont<=fOutputs->GetEntriesFast()) continue;
916 if (fMode == kProofAnalysis) {
917 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
919 const char *filename = output->GetFileName();
920 TString openoption = "RECREATE";
921 if (!(strcmp(filename, "default"))) continue;
922 if (!strlen(filename)) continue;
923 if (!output->GetData()) continue;
924 TDirectory *opwd = gDirectory;
925 TFile *file = output->GetFile();
926 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
928 //if (handlerFile == filename && !gSystem->AccessPathName(filename)) openoption = "UPDATE";
929 Bool_t firsttime = kTRUE;
930 if (filestmp.FindObject(filename) || extraOutputs.Contains(filename)) {
933 filestmp.Add(new TNamed(filename,""));
935 if (!gSystem->AccessPathName(filename) && !firsttime) openoption = "UPDATE";
936 if (fDebug>1) printf("Opening file: %s option=%s\n",filename, openoption.Data());
937 file = new TFile(filename, openoption);
939 if (fDebug>1) printf("File <%s> already opened with option: <%s> \n", filename, file->GetOption());
940 openoption = file->GetOption();
941 if (openoption == "READ") {
942 if (fDebug>1) printf("...reopening in UPDATE mode\n");
943 file->ReOpen("UPDATE");
946 if (file->IsZombie()) {
947 Error("Terminate", "Cannot open output file %s", filename);
950 output->SetFile(file);
952 // Check for a folder request
953 TString dir = output->GetFolderName();
955 if (!file->GetDirectory(dir)) file->mkdir(dir);
958 if (fDebug > 1) printf("...writing container %s to file %s:%s\n", output->GetName(), file->GetName(), output->GetFolderName());
959 if (output->GetData()->InheritsFrom(TCollection::Class())) {
960 // If data is a collection, we set the name of the collection
961 // as the one of the container and we save as a single key.
962 TCollection *coll = (TCollection*)output->GetData();
963 coll->SetName(output->GetName());
964 coll->Write(output->GetName(), TObject::kSingleKey);
966 if (output->GetData()->InheritsFrom(TTree::Class())) {
967 TTree *tree = (TTree*)output->GetData();
968 tree->SetDirectory(gDirectory);
971 output->GetData()->Write();
974 if (opwd) opwd->cd();
979 while ((output=(AliAnalysisDataContainer*)next1())) {
980 // Close all files at output
981 TDirectory *opwd = gDirectory;
982 if (output->GetFile()) {
983 // Clear file list to release object ownership to user.
984 // output->GetFile()->Clear();
985 output->GetFile()->Close();
986 // Copy merged outputs in alien if requested
987 if (fSpecialOutputLocation.BeginsWith("alien://")) {
988 if (copiedFiles.Contains(output->GetFile()->GetName())) {
989 if (opwd) opwd->cd();
990 output->SetFile(NULL);
993 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
994 gROOT->ProcessLine("if (!gGrid) TGrid::Connect(\"alien:\");");
995 TFile::Cp(output->GetFile()->GetName(),
996 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
997 copiedFiles += output->GetFile()->GetName();
999 output->SetFile(NULL);
1001 if (opwd) opwd->cd();
1004 //Write statistics information on the client
1005 if (fStatistics) WriteStatisticsMsg(fNcalls);
1007 TDirectory *crtdir = gDirectory;
1008 TFile f("syswatch.root", "RECREATE");
1011 if (!f.IsZombie()) {
1012 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
1013 tree->SetName("syswatch");
1014 tree->SetMarkerStyle(kCircle);
1015 tree->SetMarkerColor(kBlue);
1016 tree->SetMarkerSize(0.5);
1017 if (!gROOT->IsBatch()) {
1018 tree->SetAlias("event", "id0");
1019 tree->SetAlias("task", "id1");
1020 tree->SetAlias("stage", "id2");
1021 // Already defined aliases
1022 // tree->SetAlias("deltaT","stampSec-stampOldSec");
1023 // tree->SetAlias("T","stampSec-first");
1024 // tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)");
1025 // tree->SetAlias("VM","pI.fMemVirtual");
1026 TCanvas *canvas = new TCanvas("SysInfo","SysInfo",10,10,1200,800);
1027 Int_t npads = 1 /*COO plot for all tasks*/ +
1028 fTopTasks->GetEntries() /*Exec plot per task*/ +
1029 1 /*Terminate plot for all tasks*/ +
1032 Int_t iopt = (Int_t)TMath::Sqrt((Double_t)npads);
1033 if (npads<iopt*(iopt+1))
1034 canvas->Divide(iopt, iopt+1, 0.01, 0.01);
1036 canvas->Divide(iopt+1, iopt+1, 0.01, 0.01);
1038 // draw the plot of deltaVM for Exec for each task
1039 for (itask=0; itask<fTopTasks->GetEntriesFast(); itask++) {
1040 task = (AliAnalysisTask*)fTopTasks->At(itask);
1042 cut = Form("task==%d && stage==1", itask);
1043 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1044 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1046 hist->SetTitle(Form("%s: Exec dVM[MB]/event", task->GetName()));
1047 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1050 // Draw the plot of deltaVM for CreateOutputObjects for all tasks
1052 tree->SetMarkerStyle(kFullTriangleUp);
1053 tree->SetMarkerColor(kRed);
1054 tree->SetMarkerSize(0.8);
1055 cut = "task>=0 && task<1000 && stage==0";
1056 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1057 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1059 hist->SetTitle("Memory in CreateOutputObjects()");
1060 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1061 hist->GetXaxis()->SetTitle("task");
1063 // draw the plot of deltaVM for Terminate for all tasks
1065 tree->SetMarkerStyle(kOpenSquare);
1066 tree->SetMarkerColor(kMagenta);
1067 cut = "task>=0 && task<1000 && stage==2";
1068 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1069 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1071 hist->SetTitle("Memory in Terminate()");
1072 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1073 hist->GetXaxis()->SetTitle("task");
1077 tree->SetMarkerStyle(kFullCircle);
1078 tree->SetMarkerColor(kGreen);
1079 cut = Form("task==%d && stage==1",fTopTasks->GetEntriesFast()-1);
1080 tree->Draw("VM:event",cut,"", 1234567890, 0);
1081 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1083 hist->SetTitle("Virtual memory");
1084 hist->GetYaxis()->SetTitle("VM [MB]");
1088 tree->SetMarkerStyle(kCircle);
1089 tree->SetMarkerColor(kBlue);
1090 tree->SetMarkerSize(0.5);
1095 if (crtdir) crtdir->cd();
1097 // Validate the output files
1098 if (ValidateOutputFiles() && fIsRemote && fMode!=kProofAnalysis) {
1100 out.open("outputs_valid", ios::out);
1103 if (cdir) cdir->cd();
1104 if (fDebug > 1) printf("<-AliAnalysisManager::Terminate()\n");
1106 //______________________________________________________________________________
1107 void AliAnalysisManager::ProfileTask(Int_t itop, const char *option) const
1109 // Profiles the task having the itop index in the list of top (first level) tasks.
1110 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->At(itop);
1112 Error("ProfileTask", "There are only %d top tasks in the manager", fTopTasks->GetEntries());
1115 ProfileTask(task->GetName(), option);
1118 //______________________________________________________________________________
1119 void AliAnalysisManager::ProfileTask(const char *name, const char */*option*/) const
1121 // Profile a managed task after the execution of the analysis in case NSysInfo
1123 if (gSystem->AccessPathName("syswatch.root")) {
1124 Error("ProfileTask", "No file syswatch.root found in the current directory");
1127 if (gROOT->IsBatch()) return;
1128 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->FindObject(name);
1130 Error("ProfileTask", "No top task named %s known by the manager.", name);
1133 Int_t itop = fTopTasks->IndexOf(task);
1134 Int_t itask = fTasks->IndexOf(task);
1135 // Create canvas with 2 pads: first draw COO + Terminate, second Exec
1136 TDirectory *cdir = gDirectory;
1137 TFile f("syswatch.root");
1138 TTree *tree = (TTree*)f.Get("syswatch");
1140 Error("ProfileTask", "No tree named <syswatch> found in file syswatch.root");
1143 if (fDebug > 1) printf("=== Profiling task %s (class %s)\n", name, task->ClassName());
1144 TCanvas *canvas = new TCanvas(Form("profile_%d",itop),Form("Profile of task %s (class %s)",name,task->ClassName()),10,10,800,600);
1145 canvas->Divide(2, 2, 0.01, 0.01);
1149 // VM profile for COO and Terminate methods
1151 cut = Form("task==%d && (stage==0 || stage==2)",itask);
1152 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1153 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1155 hist->SetTitle("Alocated VM[MB] for COO and Terminate");
1156 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1157 hist->GetXaxis()->SetTitle("method");
1159 // CPU profile per event
1161 cut = Form("task==%d && stage==1",itop);
1162 tree->Draw("deltaT:event",cut,"", 1234567890, 0);
1163 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1165 hist->SetTitle("Execution time per event");
1166 hist->GetYaxis()->SetTitle("CPU/event [s]");
1168 // VM profile for Exec
1170 cut = Form("task==%d && stage==1",itop);
1171 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1172 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1174 hist->SetTitle("Alocated VM[MB] per event");
1175 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1180 if (cdir) cdir->cd();
1183 //______________________________________________________________________________
1184 void AliAnalysisManager::AddTask(AliAnalysisTask *task)
1186 // Adds a user task to the global list of tasks.
1188 Error("AddTask", "Cannot add task %s since InitAnalysis was already called", task->GetName());
1192 if (fTasks->FindObject(task)) {
1193 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
1196 task->SetActive(kFALSE);
1200 //______________________________________________________________________________
1201 AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
1203 // Retreive task by name.
1204 if (!fTasks) return NULL;
1205 return (AliAnalysisTask*)fTasks->FindObject(name);
1208 //______________________________________________________________________________
1209 AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
1210 TClass *datatype, EAliAnalysisContType type, const char *filename)
1212 // Create a data container of a certain type. Types can be:
1213 // kExchangeContainer = 0, used to exchange data between tasks
1214 // kInputContainer = 1, used to store input data
1215 // kOutputContainer = 2, used for writing result to a file
1216 // filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
1217 // the output object to a folder inside the output file
1218 if (fContainers->FindObject(name)) {
1219 Error("CreateContainer","A container named %s already defined !",name);
1222 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
1223 fContainers->Add(cont);
1225 case kInputContainer:
1228 case kOutputContainer:
1229 fOutputs->Add(cont);
1230 if (filename && strlen(filename)) {
1231 cont->SetFileName(filename);
1232 cont->SetDataOwned(kFALSE); // data owned by the file
1235 case kParamContainer:
1236 fParamCont->Add(cont);
1237 if (filename && strlen(filename)) {
1238 cont->SetFileName(filename);
1239 cont->SetDataOwned(kFALSE); // data owned by the file
1242 case kExchangeContainer:
1248 //______________________________________________________________________________
1249 Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
1250 AliAnalysisDataContainer *cont)
1252 // Connect input of an existing task to a data container.
1254 Error("ConnectInput", "Task pointer is NULL");
1257 if (!fTasks->FindObject(task)) {
1259 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
1261 Bool_t connected = task->ConnectInput(islot, cont);
1265 //______________________________________________________________________________
1266 Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
1267 AliAnalysisDataContainer *cont)
1269 // Connect output of an existing task to a data container.
1271 Error("ConnectOutput", "Task pointer is NULL");
1274 if (!fTasks->FindObject(task)) {
1276 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
1278 Bool_t connected = task->ConnectOutput(islot, cont);
1282 //______________________________________________________________________________
1283 void AliAnalysisManager::CleanContainers()
1285 // Clean data from all containers that have already finished all client tasks.
1286 TIter next(fContainers);
1287 AliAnalysisDataContainer *cont;
1288 while ((cont=(AliAnalysisDataContainer *)next())) {
1289 if (cont->IsOwnedData() &&
1290 cont->IsDataReady() &&
1291 cont->ClientsExecuted()) cont->DeleteData();
1295 //______________________________________________________________________________
1296 Bool_t AliAnalysisManager::InitAnalysis()
1298 // Initialization of analysis chain of tasks. Should be called after all tasks
1299 // and data containers are properly connected
1300 // Reset flag and remove valid_outputs file if exists
1301 if (fInitOK) return kTRUE;
1302 if (!gSystem->AccessPathName("outputs_valid"))
1303 gSystem->Unlink("outputs_valid");
1304 // Check for top tasks (depending only on input data containers)
1305 if (!fTasks->First()) {
1306 Error("InitAnalysis", "Analysis has no tasks !");
1310 AliAnalysisTask *task;
1311 AliAnalysisDataContainer *cont;
1314 Bool_t iszombie = kFALSE;
1315 Bool_t istop = kTRUE;
1317 while ((task=(AliAnalysisTask*)next())) {
1320 Int_t ninputs = task->GetNinputs();
1321 for (i=0; i<ninputs; i++) {
1322 cont = task->GetInputSlot(i)->GetContainer();
1326 fZombies->Add(task);
1330 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
1331 i, task->GetName());
1333 if (iszombie) continue;
1334 // Check if cont is an input container
1335 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
1336 // Connect to parent task
1340 fTopTasks->Add(task);
1344 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
1347 // Check now if there are orphan tasks
1348 for (i=0; i<ntop; i++) {
1349 task = (AliAnalysisTask*)fTopTasks->At(i);
1354 while ((task=(AliAnalysisTask*)next())) {
1355 if (!task->IsUsed()) {
1357 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
1360 // Check the task hierarchy (no parent task should depend on data provided
1361 // by a daughter task)
1362 for (i=0; i<ntop; i++) {
1363 task = (AliAnalysisTask*)fTopTasks->At(i);
1364 if (task->CheckCircularDeps()) {
1365 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
1370 // Check that all containers feeding post-event loop tasks are in the outputs list
1371 TIter nextcont(fContainers); // loop over all containers
1372 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1373 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1374 if (cont->HasConsumers()) {
1375 // Check if one of the consumers is post event loop
1376 TIter nextconsumer(cont->GetConsumers());
1377 while ((task=(AliAnalysisTask*)nextconsumer())) {
1378 if (task->IsPostEventLoop()) {
1379 fOutputs->Add(cont);
1386 // Check if all special output containers have a file name provided
1387 TIter nextout(fOutputs);
1388 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1389 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1390 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1394 // Initialize requested branch list if needed
1395 if (!fAutoBranchHandling) {
1397 while ((task=(AliAnalysisTask*)next())) {
1398 if (!task->HasBranches()) {
1399 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches.\nUse: fBranchNames = \"ESD:br1,br2,...,brN AOD:bra1,bra2,...,braM\"",
1400 task->GetName(), task->ClassName());
1403 if (!fInputEventHandler || !strlen(fInputEventHandler->GetDataType())) {
1404 Error("InitAnalysis", "Manual branch loading requested but no input handler defined or handler does not define data type.");
1407 TString taskbranches;
1408 task->GetBranches(fInputEventHandler->GetDataType(), taskbranches);
1409 if (taskbranches.IsNull()) {
1410 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches of type %s:",
1411 task->GetName(), task->ClassName(), fInputEventHandler->GetDataType());
1414 AddBranches(taskbranches);
1421 //______________________________________________________________________________
1422 void AliAnalysisManager::AddBranches(const char *branches)
1424 // Add branches to the existing fRequestedBranches.
1425 TString br(branches);
1426 TObjArray *arr = br.Tokenize(",");
1429 while ((obj=next())) {
1430 if (!fRequestedBranches.Contains(obj->GetName())) {
1431 if (!fRequestedBranches.IsNull()) fRequestedBranches += ",";
1432 fRequestedBranches += obj->GetName();
1438 //______________________________________________________________________________
1439 void AliAnalysisManager::CheckBranches(Bool_t load)
1441 // The method checks the input branches to be loaded during the analysis.
1442 if (fAutoBranchHandling || fRequestedBranches.IsNull() || !fTree) return;
1443 TObjArray *arr = fRequestedBranches.Tokenize(",");
1446 while ((obj=next())) {
1447 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(obj->GetName()));
1449 br = fTree->GetBranch(obj->GetName());
1451 Error("CheckBranches", "Could not find branch %s",obj->GetName());
1456 if (load && br->GetReadEntry()!=GetCurrentEntry()) br->GetEntry(GetCurrentEntry());
1461 //______________________________________________________________________________
1462 Bool_t AliAnalysisManager::CheckTasks() const
1464 // Check consistency of tasks.
1465 Int_t ntasks = fTasks->GetEntries();
1467 Error("CheckTasks", "No tasks connected to the manager. This may be due to forgetting to compile the task or to load their library.");
1470 // Get the pointer to AliAnalysisTaskSE::Class()
1471 TClass *badptr = (TClass*)gROOT->ProcessLine("AliAnalysisTaskSE::Class()");
1472 // Loop all tasks to check if their corresponding library was loaded
1475 while ((obj=next())) {
1476 if (obj->IsA() == badptr) {
1477 Error("CheckTasks", "##################\n \
1478 Class for task %s NOT loaded. You probably forgot to load the library for this task (or compile it dynamically).\n###########################\n",obj->GetName());
1485 //______________________________________________________________________________
1486 void AliAnalysisManager::PrintStatus(Option_t *option) const
1488 // Print task hierarchy.
1490 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1493 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1495 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
1496 TIter next(fTopTasks);
1497 AliAnalysisTask *task;
1498 while ((task=(AliAnalysisTask*)next()))
1499 task->PrintTask(option);
1501 if (!fAutoBranchHandling && !fRequestedBranches.IsNull())
1502 printf("Requested input branches:\n%s\n", fRequestedBranches.Data());
1504 TString sopt(option);
1507 if (sopt.Contains("ALL"))
1509 if ( fOutputEventHandler )
1511 cout << TString('_',78) << endl;
1512 cout << "OutputEventHandler:" << endl;
1513 fOutputEventHandler->Print(" ");
1518 //______________________________________________________________________________
1519 void AliAnalysisManager::ResetAnalysis()
1521 // Reset all execution flags and clean containers.
1525 //______________________________________________________________________________
1526 void AliAnalysisManager::RunLocalInit()
1528 // Run LocalInit method for all tasks.
1529 TDirectory *cdir = gDirectory;
1530 if (IsTrainInitialized()) return;
1531 TIter nextTask(fTasks);
1532 AliAnalysisTask *task;
1533 while ((task=(AliAnalysisTask*)nextTask())) {
1537 if (cdir) cdir->cd();
1538 TObject::SetBit(kTasksInitialized, kTRUE);
1541 //______________________________________________________________________________
1542 Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
1544 // Start analysis having a grid handler.
1545 if (!fGridHandler) {
1546 Error("StartAnalysis", "Cannot start analysis providing just the analysis type without a grid handler.");
1547 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1551 return StartAnalysis(type, tree, nentries, firstentry);
1554 //______________________________________________________________________________
1555 Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
1557 // Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1558 // MIX. Process nentries starting from firstentry
1560 // Backup current directory and make sure gDirectory points to gROOT
1561 TDirectory *cdir = gDirectory;
1564 Error("StartAnalysis","Analysis manager was not initialized !");
1565 if (cdir) cdir->cd();
1568 if (!CheckTasks()) Fatal("StartAnalysis", "Not all needed libraries were loaded");
1570 printf("StartAnalysis %s\n",GetName());
1571 AliLog::SetGlobalLogLevel(AliLog::kInfo);
1573 fMaxEntries = nentries;
1575 TString anaType = type;
1577 fMode = kLocalAnalysis;
1578 if (anaType.Contains("file")) fIsRemote = kTRUE;
1579 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1580 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1581 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1583 if (fMode == kGridAnalysis) {
1585 if (!anaType.Contains("terminate")) {
1586 if (!fGridHandler) {
1587 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1588 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1589 if (cdir) cdir->cd();
1592 // Write analysis manager in the analysis file
1593 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1594 // run local task configuration
1596 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1597 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1598 if (cdir) cdir->cd();
1602 // Terminate grid analysis
1603 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1604 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1605 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1606 if (!fGridHandler->MergeOutputs()) {
1607 // Return if outputs could not be merged or if it alien handler
1608 // was configured for offline mode or local testing.
1609 if (cdir) cdir->cd();
1613 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1614 if (cdir) cdir->cd();
1615 ImportWrappers(NULL);
1617 if (cdir) cdir->cd();
1621 SetEventLoop(kFALSE);
1622 // Enable event loop mode if a tree was provided
1623 if (tree || fGridHandler || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
1626 TString ttype = "TTree";
1627 if (tree && tree->IsA() == TChain::Class()) {
1628 chain = (TChain*)tree;
1629 if (!chain || !chain->GetListOfFiles()->First()) {
1630 Error("StartAnalysis", "Cannot process null or empty chain...");
1631 if (cdir) cdir->cd();
1637 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1638 if (getsysInfo) AliSysInfo::AddStamp("Start", 0);
1639 // Initialize locally all tasks (happens for all modes)
1641 AliAnalysisTask *task;
1645 case kLocalAnalysis:
1646 if (!tree && !fGridHandler) {
1647 TIter nextT(fTasks);
1648 // Call CreateOutputObjects for all tasks
1650 Bool_t dirStatus = TH1::AddDirectoryStatus();
1651 while ((task=(AliAnalysisTask*)nextT())) {
1652 TH1::AddDirectory(kFALSE);
1653 task->CreateOutputObjects();
1654 if (!task->CheckPostData()) {
1655 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
1656 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
1657 ########### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ###########", task->GetName(), task->ClassName());
1659 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
1663 TH1::AddDirectory(dirStatus);
1664 if (IsExternalLoop()) {
1665 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1666 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1673 fSelector = new AliAnalysisSelector(this);
1674 // Check if a plugin handler is used
1676 // Get the chain from the plugin
1677 TString dataType = "esdTree";
1678 if (fInputEventHandler) {
1679 dataType = fInputEventHandler->GetDataType();
1683 chain = fGridHandler->GetChainForTestMode(dataType);
1685 Error("StartAnalysis", "No chain for test mode. Aborting.");
1688 cout << "===== RUNNING LOCAL ANALYSIS" << GetName() << " ON CHAIN " << chain->GetName() << endl;
1689 retv = chain->Process(fSelector, "", nentries, firstentry);
1692 // Run tree-based analysis via AliAnalysisSelector
1693 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
1694 retv = tree->Process(fSelector, "", nentries, firstentry);
1696 case kProofAnalysis:
1698 // Check if the plugin is used
1700 return StartAnalysis(type, fGridHandler->GetProofDataSet(), nentries, firstentry);
1702 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1703 Error("StartAnalysis", "No PROOF!!! Exiting.");
1704 if (cdir) cdir->cd();
1707 line = Form("gProof->AddInput((TObject*)%p);", this);
1708 gROOT->ProcessLine(line);
1711 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
1712 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
1714 Error("StartAnalysis", "No chain!!! Exiting.");
1715 if (cdir) cdir->cd();
1721 if (!anaType.Contains("terminate")) {
1722 if (!fGridHandler) {
1723 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1724 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1725 if (cdir) cdir->cd();
1728 // Write analysis manager in the analysis file
1729 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1730 // Start the analysis via the handler
1731 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1732 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1733 if (cdir) cdir->cd();
1737 // Terminate grid analysis
1738 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1739 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1740 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1741 if (!fGridHandler->MergeOutputs()) {
1742 // Return if outputs could not be merged or if it alien handler
1743 // was configured for offline mode or local testing.
1744 if (cdir) cdir->cd();
1748 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1749 ImportWrappers(NULL);
1751 if (cdir) cdir->cd();
1753 case kMixingAnalysis:
1754 // Run event mixing analysis
1756 Error("StartAnalysis", "Cannot run event mixing without event pool");
1757 if (cdir) cdir->cd();
1760 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1761 fSelector = new AliAnalysisSelector(this);
1762 while ((chain=fEventPool->GetNextChain())) {
1764 // Call NotifyBinChange for all tasks
1765 while ((task=(AliAnalysisTask*)next()))
1766 if (!task->IsPostEventLoop()) task->NotifyBinChange();
1767 retv = chain->Process(fSelector);
1769 Error("StartAnalysis", "Mixing analysis failed");
1770 if (cdir) cdir->cd();
1774 PackOutput(fSelector->GetOutputList());
1777 if (cdir) cdir->cd();
1781 //______________________________________________________________________________
1782 Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
1784 // Start analysis for this manager on a given dataset. Analysis task can be:
1785 // LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1787 Error("StartAnalysis","Analysis manager was not initialized !");
1791 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
1792 TString anaType = type;
1794 if (!anaType.Contains("proof")) {
1795 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
1798 fMode = kProofAnalysis;
1800 SetEventLoop(kTRUE);
1801 // Set the dataset flag
1802 TObject::SetBit(kUseDataSet);
1805 // Start proof analysis using the grid handler
1806 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1807 Error("StartAnalysis", "The grid plugin could not start PROOF analysis");
1810 // Check if the plugin is in test mode
1811 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kTest) {
1812 dataset = "test_collection";
1814 dataset = fGridHandler->GetProofDataSet();
1818 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1819 Error("StartAnalysis", "No PROOF!!! Exiting.");
1823 // Initialize locally all tasks
1826 line = Form("gProof->AddInput((TObject*)%p);", this);
1827 gROOT->ProcessLine(line);
1829 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"\", %lld, %lld);",
1830 dataset, nentries, firstentry);
1831 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
1832 retv = (Long_t)gROOT->ProcessLine(line);
1836 //______________________________________________________________________________
1837 TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
1839 // Opens according the option the file specified by cont->GetFileName() and changes
1840 // current directory to cont->GetFolderName(). If the file was already opened, it
1841 // checks if the option UPDATE was preserved. File open via TProofOutputFile can
1842 // be optionally ignored.
1843 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1844 TString filename = cont->GetFileName();
1846 if (filename.IsNull()) {
1847 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
1850 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
1852 f = mgr->OpenProofFile(cont,option);
1854 // Check first if the file is already opened
1855 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1857 // Check if option "UPDATE" was preserved
1858 TString opt(option);
1860 if ((opt=="UPDATE") && (opt!=f->GetOption()))
1861 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
1863 f = TFile::Open(filename, option);
1866 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1870 // Check for a folder request
1871 TString dir = cont->GetFolderName();
1872 if (!dir.IsNull()) {
1873 if (!f->GetDirectory(dir)) f->mkdir(dir);
1878 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
1879 cont->SetFile(NULL);
1883 //______________________________________________________________________________
1884 TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option, const char *extaod)
1886 // Opens a special output file used in PROOF.
1888 TString filename = cont->GetFileName();
1889 if (cont == fCommonOutput) {
1890 if (fOutputEventHandler) {
1891 if (strlen(extaod)) filename = extaod;
1892 filename = fOutputEventHandler->GetOutputFileName();
1894 else Fatal("OpenProofFile","No output container. Exiting.");
1897 if (fMode!=kProofAnalysis || !fSelector) {
1898 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
1901 if (fSpecialOutputLocation.Length()) {
1902 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1904 // Check if option "UPDATE" was preserved
1905 TString opt(option);
1907 if ((opt=="UPDATE") && (opt!=f->GetOption()))
1908 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
1910 f = new TFile(filename, option);
1912 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1916 // Check for a folder request
1917 TString dir = cont->GetFolderName();
1919 if (!f->GetDirectory(dir)) f->mkdir(dir);
1924 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
1925 cont->SetFile(NULL);
1928 // Check if there is already a proof output file in the output list
1929 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
1931 // Get the actual file
1932 line = Form("((TProofOutputFile*)%p)->GetFileName();", pof);
1933 filename = (const char*)gROOT->ProcessLine(line);
1935 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
1937 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1939 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
1942 // Check if option "UPDATE" was preserved
1943 TString opt(option);
1945 if ((opt=="UPDATE") && (opt!=f->GetOption()))
1946 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
1948 if (cont->IsRegisterDataset()) {
1949 TString dsetName = filename;
1950 dsetName.ReplaceAll(".root", cont->GetTitle());
1951 dsetName.ReplaceAll(":","_");
1952 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
1953 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
1955 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
1956 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
1958 if (fDebug > 1) printf("=== %s\n", line.Data());
1959 gROOT->ProcessLine(line);
1960 line = Form("pf->OpenFile(\"%s\");", option);
1961 gROOT->ProcessLine(line);
1964 gROOT->ProcessLine("pf->Print()");
1965 printf(" == proof file name: %s", f->GetName());
1967 // Add to proof output list
1968 line = Form("((TList*)%p)->Add(pf);",fSelector->GetOutputList());
1969 if (fDebug > 1) printf("=== %s\n", line.Data());
1970 gROOT->ProcessLine(line);
1972 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1976 // Check for a folder request
1977 TString dir = cont->GetFolderName();
1978 if (!dir.IsNull()) {
1979 if (!f->GetDirectory(dir)) f->mkdir(dir);
1984 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
1985 cont->SetFile(NULL);
1989 //______________________________________________________________________________
1990 void AliAnalysisManager::ExecAnalysis(Option_t *option)
1992 // Execute analysis.
1993 static Long64_t nentries = 0;
1994 static TTree *lastTree = 0;
1995 static TStopwatch *timer = new TStopwatch();
1996 // Only the first call to Process will trigger a true Notify. Other Notify
1997 // coming before is ignored.
1998 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) {
1999 TObject::SetBit(AliAnalysisManager::kTrueNotify);
2002 if (fDebug > 0) printf("MGR: Processing event #%d\n", fNcalls);
2004 if (fTree && (fTree != lastTree)) {
2005 nentries += fTree->GetEntries();
2008 if (!fNcalls) timer->Start();
2009 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", fNcalls, TMath::Min(fMaxEntries,nentries), timer, kFALSE);
2012 TDirectory *cdir = gDirectory;
2013 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
2014 if (getsysInfo && ((fNcalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)fNcalls);
2016 Error("ExecAnalysis", "Analysis manager was not initialized !");
2017 if (cdir) cdir->cd();
2021 AliAnalysisTask *task;
2022 // Check if the top tree is active.
2024 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2025 AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
2027 // De-activate all tasks
2028 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
2029 AliAnalysisDataContainer *cont = fCommonInput;
2030 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
2032 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
2033 if (cdir) cdir->cd();
2036 cont->SetData(fTree); // This will notify all consumers
2037 Long64_t entry = fTree->GetTree()->GetReadEntry();
2039 // Call BeginEvent() for optional input/output and MC services
2040 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
2041 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
2042 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
2044 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2045 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2047 // Execute the tasks
2048 // TIter next1(cont->GetConsumers());
2049 TIter next1(fTopTasks);
2051 while ((task=(AliAnalysisTask*)next1())) {
2053 cout << " Executing task " << task->GetName() << endl;
2055 task->ExecuteTask(option);
2057 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2058 AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
2062 // Call FinishEvent() for optional output and MC services
2063 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2064 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2065 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2066 // Gather system information if requested
2067 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2068 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1001, 1);
2069 if (cdir) cdir->cd();
2072 // The event loop is not controlled by TSelector
2074 // Call BeginEvent() for optional input/output and MC services
2075 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
2076 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
2077 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
2079 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2080 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2081 TIter next2(fTopTasks);
2082 while ((task=(AliAnalysisTask*)next2())) {
2083 task->SetActive(kTRUE);
2085 cout << " Executing task " << task->GetName() << endl;
2087 task->ExecuteTask(option);
2091 // Call FinishEvent() for optional output and MC services
2092 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2093 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2094 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2095 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2096 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
2097 if (cdir) cdir->cd();
2100 //______________________________________________________________________________
2101 Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
2103 // Check if the stdout is connected to a pipe (C.Holm)
2104 Bool_t ispipe = kFALSE;
2105 out.seekp(0, std::ios_base::cur);
2108 if (errno == ESPIPE) ispipe = kTRUE;
2113 //______________________________________________________________________________
2114 void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
2116 // Set the input event handler and create a container for it.
2117 fInputEventHandler = handler;
2118 if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
2121 //______________________________________________________________________________
2122 void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
2124 // Set the input event handler and create a container for it.
2125 fOutputEventHandler = handler;
2126 if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
2127 fCommonOutput->SetSpecialOutput();
2130 //______________________________________________________________________________
2131 void AliAnalysisManager::SetDebugLevel(UInt_t level)
2133 // Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
2134 if (TObject::TestBit(kUseProgressBar)) {
2135 Info("SetDebugLevel","Ignored. Disable the progress bar first.");
2141 //______________________________________________________________________________
2142 void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
2144 // Enable a text mode progress bar. Resets debug level to 0.
2145 Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
2146 TObject::SetBit(kUseProgressBar,flag);
2147 fPBUpdateFreq = freq;
2151 //______________________________________________________________________________
2152 void AliAnalysisManager::RegisterExtraFile(const char *fname)
2154 // This method is used externally to register output files which are not
2155 // connected to any output container, so that the manager can properly register,
2156 // retrieve or merge them when running in distributed mode. The file names are
2157 // separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
2158 if (fExtraFiles.Contains(fname)) return;
2159 if (fExtraFiles.Length()) fExtraFiles += " ";
2160 fExtraFiles += fname;
2163 //______________________________________________________________________________
2164 Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
2166 // Copy a file from the location specified ina the wrapper with the same name from the source list.
2170 TObject *pof = source->FindObject(filename);
2171 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
2172 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
2175 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
2176 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
2177 TString clientUrl(chUrl);
2178 TString fullPath_str(fullPath);
2179 if (clientUrl.Contains("localhost")){
2180 TObjArray* array = fullPath_str.Tokenize ( "//" );
2181 TObjString *strobj = ( TObjString *)array->At(1);
2182 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
2183 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
2184 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
2185 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
2186 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
2190 else if (clientUrl.Contains("__lite__")) {
2191 // Special case for ProofLite environement - get file info and copy.
2192 gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
2193 fullPath_str = Form("%s/%s", tmp, fullPath);
2196 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
2197 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
2199 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
2203 //______________________________________________________________________________
2204 void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
2206 // Fill analysis type in the provided string.
2208 case kLocalAnalysis:
2211 case kProofAnalysis:
2217 case kMixingAnalysis:
2222 //______________________________________________________________________________
2223 Bool_t AliAnalysisManager::ValidateOutputFiles() const
2225 // Validate all output files.
2226 TIter next(fOutputs);
2227 AliAnalysisDataContainer *output;
2228 TDirectory *cdir = gDirectory;
2229 TString openedFiles;
2230 while ((output=(AliAnalysisDataContainer*)next())) {
2231 if (output->IsRegisterDataset()) continue;
2232 TString filename = output->GetFileName();
2233 if (filename == "default") {
2234 if (!fOutputEventHandler) continue;
2235 filename = fOutputEventHandler->GetOutputFileName();
2236 // Main AOD may not be there
2237 if (gSystem->AccessPathName(filename)) continue;
2239 // Check if the file is closed
2240 if (openedFiles.Contains(filename)) continue;;
2241 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2243 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
2244 // Clear file list to release object ownership to user.
2248 file = TFile::Open(filename);
2249 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
2250 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
2251 if (cdir) cdir->cd();
2255 openedFiles += filename;
2258 if (cdir) cdir->cd();
2262 //______________________________________________________________________________
2263 void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
2265 // Implements a nice text mode progress bar.
2266 static Long64_t icount = 0;
2267 static TString oname;
2268 static TString nname;
2269 static Long64_t ocurrent = 0;
2270 static Long64_t osize = 0;
2271 static Int_t oseconds = 0;
2272 static TStopwatch *owatch = 0;
2273 static Bool_t oneoftwo = kFALSE;
2274 static Int_t nrefresh = 0;
2275 static Int_t nchecks = 0;
2276 static char lastChar = 0;
2277 const char symbol[4] = {'-','\\','|','/'};
2279 if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
2285 ocurrent = TMath::Abs(current);
2286 osize = TMath::Abs(size);
2287 if (ocurrent > osize) ocurrent=osize;
2292 if ((current % fPBUpdateFreq) != 0) return;
2294 char progress[11] = " ";
2295 Int_t ichar = icount%4;
2300 if (owatch && !last) {
2302 time = owatch->RealTime();
2303 seconds = int(time) % 60;
2304 minutes = (int(time) / 60) % 60;
2305 hours = (int(time) / 60 / 60);
2307 if (oseconds==seconds) {
2311 oneoftwo = !oneoftwo;
2315 if (refresh && oneoftwo) {
2317 if (nchecks <= 0) nchecks = nrefresh+1;
2318 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
2319 oname = Form(" == %d%% ==", pctdone);
2321 Double_t percent = 100.0*ocurrent/osize;
2322 Int_t nchar = Int_t(percent/10);
2323 if (nchar>10) nchar=10;
2325 for (i=0; i<nchar; i++) progress[i] = '=';
2326 progress[nchar] = symbol[ichar];
2327 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2328 progress[10] = '\0';
2331 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2332 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2333 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
2335 Int_t full = Int_t(ocurrent > 0 ?
2336 time * (float(osize)/ocurrent) + .5 :
2338 Int_t remain = Int_t(full - time);
2339 Int_t rsec = remain % 60;
2340 Int_t rmin = (remain / 60) % 60;
2341 Int_t rhour = (remain / 60 / 60);
2342 fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
2343 percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
2345 else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
2346 if (refresh && oneoftwo) oname = nname;
2347 if (owatch) owatch->Continue();
2356 fprintf(stderr, "\n");
2360 //______________________________________________________________________________
2361 void AliAnalysisManager::DoLoadBranch(const char *name)
2363 // Get tree and load branch if needed.
2364 static Long64_t crtEntry = -100;
2366 if (fAutoBranchHandling || !fTree)
2369 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2371 br = fTree->GetBranch(name);
2373 Error("DoLoadBranch", "Could not find branch %s",name);
2378 if (br->GetReadEntry()==fCurrentEntry) return;
2379 Int_t ret = br->GetEntry(GetCurrentEntry());
2381 Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
2382 if (crtEntry != fCurrentEntry) {
2383 CountEvent(1,0,1,0);
2384 crtEntry = fCurrentEntry;
2387 if (crtEntry != fCurrentEntry) {
2388 CountEvent(1,1,0,0);
2389 crtEntry = fCurrentEntry;
2394 //______________________________________________________________________________
2395 void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
2397 // Add the statistics task to the manager.
2399 Info("AddStatisticsTask", "Already added");
2402 TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
2403 gROOT->ProcessLine(line);
2406 //______________________________________________________________________________
2407 void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
2409 // Bookkeep current event;
2410 if (!fStatistics) return;
2411 fStatistics->AddInput(ninput);
2412 fStatistics->AddProcessed(nprocessed);
2413 fStatistics->AddFailed(nfailed);
2414 fStatistics->AddAccepted(naccepted);
2417 //______________________________________________________________________________
2418 void AliAnalysisManager::AddStatisticsMsg(const char *line)
2420 // Add a line in the statistics message. If available, the statistics message is written
2421 // at the end of the SlaveTerminate phase on workers AND at the end of Terminate
2423 if (!strlen(line)) return;
2424 if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
2425 fStatisticsMsg += line;
2428 //______________________________________________________________________________
2429 void AliAnalysisManager::WriteStatisticsMsg(Int_t)
2431 // If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
2432 static Bool_t done = kFALSE;
2435 if (!fStatistics) return;
2437 AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
2438 AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
2439 AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
2440 AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
2441 out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
2442 fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
2443 fStatistics->GetNaccepted()), ios::out);
2444 out << fStatisticsMsg << endl;
2448 //______________________________________________________________________________
2449 const char* AliAnalysisManager::GetOADBPath()
2451 // returns the path of the OADB
2452 // this static function just depends on environment variables
2454 static TString oadbPath;
2456 if (gSystem->Getenv("OADB_PATH"))
2457 oadbPath = gSystem->Getenv("OADB_PATH");
2458 else if (gSystem->Getenv("ALICE_ROOT"))
2459 oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
2461 ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
2466 //______________________________________________________________________________
2467 void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
2469 // Define a custom string variable mapped to a global unique name. The variable
2470 // can be then retrieved by a given analysis macro via GetGlobalStr(key).
2471 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2473 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2476 Bool_t valid = kFALSE;
2477 TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
2479 ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
2482 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
2485 //______________________________________________________________________________
2486 const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
2488 // Static method to retrieve a global variable defined via SetGlobalStr.
2490 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2492 TObject *value = mgr->GetGlobals()->GetValue(key);
2493 if (!value) return 0;
2495 return value->GetName();
2498 //______________________________________________________________________________
2499 void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
2501 // Define a custom integer variable mapped to a global unique name. The variable
2502 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2503 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2505 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2508 Bool_t valid = kFALSE;
2509 Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
2511 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
2514 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
2517 //______________________________________________________________________________
2518 Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
2520 // Static method to retrieve a global variable defined via SetGlobalInt.
2522 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2524 TObject *value = mgr->GetGlobals()->GetValue(key);
2525 if (!value) return 0;
2527 TString s = value->GetName();
2531 //______________________________________________________________________________
2532 void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
2534 // Define a custom double precision variable mapped to a global unique name. The variable
2535 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2536 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2538 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2541 Bool_t valid = kFALSE;
2542 Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
2544 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
2547 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));
2550 //______________________________________________________________________________
2551 Double_t AliAnalysisManager::GetGlobalDbl(const char *key, Bool_t &valid)
2553 // Static method to retrieve a global variable defined via SetGlobalDbl.
2555 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2557 TObject *value = mgr->GetGlobals()->GetValue(key);
2558 if (!value) return 0;
2560 TString s = value->GetName();
2564 //______________________________________________________________________________
2565 void AliAnalysisManager::AddClassDebug(const char *className, Int_t debugLevel)
2567 // Sets Class debug level
2569 if (!fDebugOptions) {
2570 fDebugOptions = new TObjArray();
2571 fDebugOptions->SetOwner(kTRUE);
2574 // substracting DebugOffset, beacuse of AliLog::SetClassDebugLevel()
2575 debugLevel -= AliLog::kDebug-1;
2577 TNamed *debugOpt = (TNamed*)fDebugOptions->FindObject(className);
2579 AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel+AliLog::kDebug-1,className).Data());
2580 fDebugOptions->Add(new TNamed(className,TString::Format("%d",debugLevel).Data()));
2582 TString oldDebugStr = debugOpt->GetTitle();
2583 Int_t oldDebug = oldDebugStr.Atoi();
2584 if (debugLevel > oldDebug) {
2585 AliWarning(TString::Format("Overwriting debug level to %d class %s, because it is higher then previously set (%d).",debugLevel+AliLog::kDebug-1,className,oldDebug+AliLog::kDebug-1).Data());
2586 debugOpt->SetTitle(TString::Format("%d",debugLevel).Data());
2588 AliWarning(TString::Format("Ignoring debug level to %d class %s, because it is smaller then previously set (%d).",debugLevel+AliLog::kDebug-1,className,oldDebug+AliLog::kDebug-1).Data());
2593 //______________________________________________________________________________
2594 void AliAnalysisManager::ApplyDebugOptions()
2596 // Apply debug options
2598 if (!fDebugOptions) return;
2600 TIter next(fDebugOptions);
2603 while ((debug=dynamic_cast<TNamed*>(next()))) {
2604 debugLevel = debug->GetTitle();
2605 AliInfo(TString::Format("ApplyDebugOptions : Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()+AliLog::kDebug-1).Data());
2606 AliLog::SetClassDebugLevel(debug->GetName(), debugLevel.Atoi());