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(""),
90 fAutoBranchHandling(kTRUE),
100 // Default constructor.
101 fgAnalysisManager = this;
102 fgCommonFileName = "AnalysisResults.root";
103 if (TClass::IsCallingNew() != TClass::kDummyNew) {
104 fTasks = new TObjArray();
105 fTopTasks = new TObjArray();
106 fZombies = new TObjArray();
107 fContainers = new TObjArray();
108 fInputs = new TObjArray();
109 fOutputs = new TObjArray();
110 fParamCont = new TObjArray();
111 fGlobals = new TMap();
116 //______________________________________________________________________________
117 AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
120 fInputEventHandler(NULL),
121 fOutputEventHandler(NULL),
122 fMCtruthEventHandler(NULL),
127 fInitOK(other.fInitOK),
128 fMustClean(other.fMustClean),
129 fIsRemote(other.fIsRemote),
130 fDebug(other.fDebug),
131 fSpecialOutputLocation(""),
144 fAutoBranchHandling(other.fAutoBranchHandling),
147 fNcalls(other.fNcalls),
148 fMaxEntries(other.fMaxEntries),
149 fStatisticsMsg(other.fStatisticsMsg),
150 fRequestedBranches(other.fRequestedBranches),
151 fStatistics(other.fStatistics),
152 fGlobals(other.fGlobals)
155 fTasks = new TObjArray(*other.fTasks);
156 fTopTasks = new TObjArray(*other.fTopTasks);
157 fZombies = new TObjArray(*other.fZombies);
158 fContainers = new TObjArray(*other.fContainers);
159 fInputs = new TObjArray(*other.fInputs);
160 fOutputs = new TObjArray(*other.fOutputs);
161 fParamCont = new TObjArray(*other.fParamCont);
162 fgCommonFileName = "AnalysisResults.root";
163 fgAnalysisManager = this;
166 //______________________________________________________________________________
167 AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& other)
170 if (&other != this) {
171 TNamed::operator=(other);
172 fInputEventHandler = other.fInputEventHandler;
173 fOutputEventHandler = other.fOutputEventHandler;
174 fMCtruthEventHandler = other.fMCtruthEventHandler;
175 fEventPool = other.fEventPool;
178 fNSysInfo = other.fNSysInfo;
180 fInitOK = other.fInitOK;
181 fIsRemote = other.fIsRemote;
182 fDebug = other.fDebug;
183 fTasks = new TObjArray(*other.fTasks);
184 fTopTasks = new TObjArray(*other.fTopTasks);
185 fZombies = new TObjArray(*other.fZombies);
186 fContainers = new TObjArray(*other.fContainers);
187 fInputs = new TObjArray(*other.fInputs);
188 fOutputs = new TObjArray(*other.fOutputs);
189 fParamCont = new TObjArray(*other.fParamCont);
191 fCommonOutput = NULL;
194 fExtraFiles = other.fExtraFiles;
195 fgCommonFileName = "AnalysisResults.root";
196 fgAnalysisManager = this;
197 fAutoBranchHandling = other.fAutoBranchHandling;
198 fTable.Clear("nodelete");
199 fRunFromPath = other.fRunFromPath;
200 fNcalls = other. fNcalls;
201 fMaxEntries = other.fMaxEntries;
202 fStatisticsMsg = other.fStatisticsMsg;
203 fRequestedBranches = other.fRequestedBranches;
204 fStatistics = other.fStatistics;
205 fGlobals = new TMap();
210 //______________________________________________________________________________
211 AliAnalysisManager::~AliAnalysisManager()
214 if (fTasks) {fTasks->Delete(); delete fTasks;}
215 if (fTopTasks) delete fTopTasks;
216 if (fZombies) delete fZombies;
217 if (fContainers) {fContainers->Delete(); delete fContainers;}
218 if (fInputs) delete fInputs;
219 if (fOutputs) delete fOutputs;
220 if (fParamCont) delete fParamCont;
221 if (fGridHandler) delete fGridHandler;
222 if (fInputEventHandler) delete fInputEventHandler;
223 if (fOutputEventHandler) delete fOutputEventHandler;
224 if (fMCtruthEventHandler) delete fMCtruthEventHandler;
225 if (fEventPool) delete fEventPool;
226 if (fgAnalysisManager==this) fgAnalysisManager = NULL;
227 if (fGlobals) {fGlobals->DeleteAll(); delete fGlobals;}
230 //______________________________________________________________________________
231 Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
233 // Read one entry of the tree or a whole branch.
234 fCurrentEntry = entry;
235 if (!fAutoBranchHandling)
237 return fTree ? fTree->GetTree()->GetEntry(entry, getall) : -1;
240 //______________________________________________________________________________
241 Int_t AliAnalysisManager::GetRunFromAlienPath(const char *path)
243 // Attempt to extract run number from input data path. Works only for paths to
244 // alice data in alien.
245 // sim: /alice/sim/<production>/run_no/...
246 // data: /alice/data/year/period/000run_no/... (ESD or AOD)
247 TString type = "unknown";
249 if (s.Contains("/alice/data")) type = "real";
250 else if (s.Contains("/alice/sim")) type = "simulated";
253 ind1 = s.Index("/00");
255 ind2 = s.Index("/",ind1+1);
256 if (ind2-ind1>8) srun = s(ind1+1, ind2-ind1-1);
259 ind1 = s.Index("/LHC");
261 ind1 = s.Index("/",ind1+1);
263 ind2 = s.Index("/",ind1+1);
264 if (ind2>0) srun = s(ind1+1, ind2-ind1-1);
268 Int_t run = srun.Atoi();
269 if (run>0) printf("=== GetRunFromAlienPath: run %d of %s data ===\n", run, type.Data());
273 //______________________________________________________________________________
274 Bool_t AliAnalysisManager::Init(TTree *tree)
276 // The Init() function is called when the selector needs to initialize
277 // a new tree or chain. Typically here the branch addresses of the tree
278 // will be set. It is normaly not necessary to make changes to the
279 // generated code, but the routine can be extended by the user if needed.
280 // Init() will be called many times when running with PROOF.
281 Bool_t init = kFALSE;
282 if (!tree) return kFALSE; // Should not happen - protected in selector caller
284 printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
286 // Call InitTree of EventHandler
287 if (fOutputEventHandler) {
288 if (fMode == kProofAnalysis) {
289 init = fOutputEventHandler->Init(0x0, "proof");
291 init = fOutputEventHandler->Init(0x0, "local");
294 Error("Init", "Output event handler failed to initialize");
299 if (fInputEventHandler) {
300 if (fMode == kProofAnalysis) {
301 init = fInputEventHandler->Init(tree, "proof");
303 init = fInputEventHandler->Init(tree, "local");
306 Error("Init", "Input event handler failed to initialize tree");
310 // If no input event handler we need to get the tree once
312 if(!tree->GetTree()) {
313 Long64_t readEntry = tree->LoadTree(0);
314 if (readEntry == -2) {
315 Error("Init", "Input tree has no entry. Exiting");
321 if (fMCtruthEventHandler) {
322 if (fMode == kProofAnalysis) {
323 init = fMCtruthEventHandler->Init(0x0, "proof");
325 init = fMCtruthEventHandler->Init(0x0, "local");
328 Error("Init", "MC event handler failed to initialize");
333 if (!fInitOK) InitAnalysis();
334 if (!fInitOK) return kFALSE;
337 AliAnalysisDataContainer *top = fCommonInput;
338 if (!top) top = (AliAnalysisDataContainer*)fInputs->At(0);
340 Error("Init","No top input container !");
344 CheckBranches(kFALSE);
346 printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
351 //______________________________________________________________________________
352 void AliAnalysisManager::SlaveBegin(TTree *tree)
354 // The SlaveBegin() function is called after the Begin() function.
355 // When running with PROOF SlaveBegin() is called on each slave server.
356 // The tree argument is deprecated (on PROOF 0 is passed).
357 if (fDebug > 1) printf("->AliAnalysisManager::SlaveBegin()\n");
358 if (!CheckTasks()) Fatal("SlaveBegin", "Not all needed libraries were loaded");
359 static Bool_t isCalled = kFALSE;
360 Bool_t init = kFALSE;
361 Bool_t initOK = kTRUE;
363 TDirectory *curdir = gDirectory;
364 // Call SlaveBegin only once in case of mixing
365 if (isCalled && fMode==kMixingAnalysis) return;
367 // Call Init of EventHandler
368 if (fOutputEventHandler) {
369 if (fMode == kProofAnalysis) {
370 // Merging AOD's in PROOF via TProofOutputFile
371 if (fDebug > 1) printf(" Initializing AOD output file %s...\n", fOutputEventHandler->GetOutputFileName());
372 init = fOutputEventHandler->Init("proof");
373 if (!init) msg = "Failed to initialize output handler on worker";
375 init = fOutputEventHandler->Init("local");
376 if (!init) msg = "Failed to initialize output handler";
379 if (!fSelector) Error("SlaveBegin", "Selector not set");
380 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
383 if (fInputEventHandler) {
384 fInputEventHandler->SetInputTree(tree);
385 if (fMode == kProofAnalysis) {
386 init = fInputEventHandler->Init("proof");
387 if (!init) msg = "Failed to initialize input handler on worker";
389 init = fInputEventHandler->Init("local");
390 if (!init) msg = "Failed to initialize input handler";
393 if (!fSelector) Error("SlaveBegin", "Selector not set");
394 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
397 if (fMCtruthEventHandler) {
398 if (fMode == kProofAnalysis) {
399 init = fMCtruthEventHandler->Init("proof");
400 if (!init) msg = "Failed to initialize MC handler on worker";
402 init = fMCtruthEventHandler->Init("local");
403 if (!init) msg = "Failed to initialize MC handler";
406 if (!fSelector) Error("SlaveBegin", "Selector not set");
407 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
409 if (curdir) curdir->cd();
413 AliAnalysisTask *task;
414 // Call CreateOutputObjects for all tasks
415 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
416 Bool_t dirStatus = TH1::AddDirectoryStatus();
418 while ((task=(AliAnalysisTask*)next())) {
420 // Start with memory as current dir and make sure by default histograms do not get attached to files.
421 TH1::AddDirectory(kFALSE);
422 task->CreateOutputObjects();
423 if (!task->CheckPostData()) {
424 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
425 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
426 ####### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ##########", task->GetName(), task->ClassName());
428 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
431 TH1::AddDirectory(dirStatus);
432 if (curdir) curdir->cd();
433 if (fDebug > 1) printf("<-AliAnalysisManager::SlaveBegin()\n");
436 //______________________________________________________________________________
437 Bool_t AliAnalysisManager::Notify()
439 // The Notify() function is called when a new file is opened. This
440 // can be either for a new TTree in a TChain or when when a new TTree
441 // is started when using PROOF. It is normaly not necessary to make changes
442 // to the generated code, but the routine can be extended by the
443 // user if needed. The return value is currently not used.
444 if (!fTree) return kFALSE;
445 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) return kFALSE;
447 fTable.Clear("nodelete"); // clearing the hash table may not be needed -> C.L.
448 if (fMode == kProofAnalysis) fIsRemote = kTRUE;
450 TFile *curfile = fTree->GetCurrentFile();
452 Error("Notify","No current file");
456 if (fDebug > 1) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
457 Int_t run = AliAnalysisManager::GetRunFromAlienPath(curfile->GetName());
458 if (run && (run != fRunFromPath)) {
460 if (fDebug > 1) printf(" ### run found from path: %d\n", run);
463 AliAnalysisTask *task;
465 // Call Notify of the event handlers
466 if (fInputEventHandler) {
467 fInputEventHandler->Notify(curfile->GetName());
470 if (fOutputEventHandler) {
471 fOutputEventHandler->Notify(curfile->GetName());
474 if (fMCtruthEventHandler) {
475 fMCtruthEventHandler->Notify(curfile->GetName());
478 // Call Notify for all tasks
479 while ((task=(AliAnalysisTask*)next()))
482 if (fDebug > 1) printf("<-AliAnalysisManager::Notify()\n");
486 //______________________________________________________________________________
487 Bool_t AliAnalysisManager::Process(Long64_t)
489 // The Process() function is called for each entry in the tree (or possibly
490 // keyed object in the case of PROOF) to be processed. The entry argument
491 // specifies which entry in the currently loaded tree is to be processed.
492 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
493 // to read either all or the required parts of the data. When processing
494 // keyed objects with PROOF, the object is already loaded and is available
495 // via the fObject pointer.
497 // This function should contain the "body" of the analysis. It can contain
498 // simple or elaborate selection criteria, run algorithms on the data
499 // of the event and typically fill histograms.
501 // WARNING when a selector is used with a TChain, you must use
502 // the pointer to the current TTree to call GetEntry(entry).
503 // The entry is always the local entry number in the current tree.
504 // Assuming that fChain is the pointer to the TChain being processed,
505 // use fChain->GetTree()->GetEntry(entry).
507 // This method is obsolete. ExecAnalysis is called instead.
511 //______________________________________________________________________________
512 void AliAnalysisManager::PackOutput(TList *target)
514 // Pack all output data containers in the output list. Called at SlaveTerminate
515 // stage in PROOF case for each slave.
516 if (fDebug > 1) printf("->AliAnalysisManager::PackOutput()\n");
518 Error("PackOutput", "No target. Exiting.");
521 TDirectory *cdir = gDirectory;
523 if (fInputEventHandler) fInputEventHandler ->Terminate();
524 if (fOutputEventHandler) fOutputEventHandler ->Terminate();
525 if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
528 // Call FinishTaskOutput() for each event loop task (not called for
529 // post-event loop tasks - use Terminate() fo those)
530 TIter nexttask(fTasks);
531 AliAnalysisTask *task;
532 while ((task=(AliAnalysisTask*)nexttask())) {
533 if (!task->IsPostEventLoop()) {
534 if (fDebug > 1) printf("->FinishTaskOutput: task %s\n", task->GetName());
535 task->FinishTaskOutput();
537 if (fDebug > 1) printf("<-FinishTaskOutput: task %s\n", task->GetName());
540 // Write statistics message on the workers.
541 if (fStatistics) WriteStatisticsMsg(fNcalls);
543 if (fMode == kProofAnalysis) {
544 TIter next(fOutputs);
545 AliAnalysisDataContainer *output;
546 Bool_t isManagedByHandler = kFALSE;
549 while ((output=(AliAnalysisDataContainer*)next())) {
550 // Do not consider outputs of post event loop tasks
551 isManagedByHandler = kFALSE;
552 if (output->GetProducer() && output->GetProducer()->IsPostEventLoop()) continue;
553 const char *filename = output->GetFileName();
554 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
555 isManagedByHandler = kTRUE;
556 printf("#### Handler output. Extra: %s\n", fExtraFiles.Data());
557 filename = fOutputEventHandler->GetOutputFileName();
559 // Check if data was posted to this container. If not, issue an error.
560 if (!output->GetData() && !isManagedByHandler) {
561 Error("PackOutput", "No data for output container %s. Forgot to PostData ?", output->GetName());
564 if (!output->IsSpecialOutput()) {
566 if (strlen(filename) && !isManagedByHandler) {
567 // Backup current folder
568 TDirectory *opwd = gDirectory;
569 // File resident outputs.
570 // Check first if the file exists.
571 TString openoption = "RECREATE";
572 Bool_t firsttime = kTRUE;
573 if (filestmp.FindObject(output->GetFileName())) {
576 filestmp.Add(new TNamed(output->GetFileName(),""));
578 if (!gSystem->AccessPathName(output->GetFileName()) && !firsttime) openoption = "UPDATE";
579 // TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
580 // Save data to file, then close.
581 if (output->GetData()->InheritsFrom(TCollection::Class())) {
582 // If data is a collection, we set the name of the collection
583 // as the one of the container and we save as a single key.
584 TCollection *coll = (TCollection*)output->GetData();
585 coll->SetName(output->GetName());
586 // coll->Write(output->GetName(), TObject::kSingleKey);
588 if (output->GetData()->InheritsFrom(TTree::Class())) {
589 TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
590 // Save data to file, then close.
591 TTree *tree = (TTree*)output->GetData();
592 // Check if tree is in memory
593 if (tree->GetDirectory()==gROOT) tree->SetDirectory(gDirectory);
597 // output->GetData()->Write();
600 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
602 // printf(" file %s listing content:\n", filename);
605 // Clear file list to release object ownership to user.
608 output->SetFile(NULL);
609 // Restore current directory
610 if (opwd) opwd->cd();
612 // Memory-resident outputs
613 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
615 AliAnalysisDataWrapper *wrap = 0;
616 if (isManagedByHandler) {
617 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
618 wrap->SetName(output->GetName());
620 else wrap =output->ExportData();
621 // Output wrappers must NOT delete data after merging - the user owns them
622 wrap->SetDeleteData(kFALSE);
625 // Special outputs. The file must be opened and connected to the container.
626 TDirectory *opwd = gDirectory;
627 TFile *file = output->GetFile();
629 AliAnalysisTask *producer = output->GetProducer();
631 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
632 output->GetFileName(), output->GetName(), producer->ClassName());
635 TString outFilename = file->GetName();
636 if (fDebug > 1) printf("PackOutput %s: special output\n", output->GetName());
637 if (isManagedByHandler) {
638 // Terminate IO for files managed by the output handler
639 // file->Write() moved to AOD handler (A.G. 11.01.10)
640 // if (file) file->Write();
641 if (file && fDebug > 2) {
642 printf(" handled file %s listing content:\n", file->GetName());
645 fOutputEventHandler->TerminateIO();
648 // Release object ownership to users after writing data to file
649 if (output->GetData()->InheritsFrom(TCollection::Class())) {
650 // If data is a collection, we set the name of the collection
651 // as the one of the container and we save as a single key.
652 TCollection *coll = (TCollection*)output->GetData();
653 coll->SetName(output->GetName());
654 coll->Write(output->GetName(), TObject::kSingleKey);
656 if (output->GetData()->InheritsFrom(TTree::Class())) {
657 TTree *tree = (TTree*)output->GetData();
658 tree->SetDirectory(file);
661 output->GetData()->Write();
665 printf(" file %s listing content:\n", output->GetFileName());
668 // Clear file list to release object ownership to user.
671 output->SetFile(NULL);
673 // Restore current directory
674 if (opwd) opwd->cd();
675 // Check if a special output location was provided or the output files have to be merged
676 if (strlen(fSpecialOutputLocation.Data())) {
677 TString remote = fSpecialOutputLocation;
679 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
680 if (remote.BeginsWith("alien:")) {
681 gROOT->ProcessLine("TGrid::Connect(\"alien:\", gProofServ->GetUser());");
682 remote += outFilename;
683 remote.ReplaceAll(".root", Form("_%d.root", gid));
685 remote += Form("%s_%d_", gSystem->HostName(), gid);
686 remote += outFilename;
689 Info("PackOutput", "Output file for container %s to be copied \n at: %s. No merging.",
690 output->GetName(), remote.Data());
691 TFile::Cp ( outFilename.Data(), remote.Data() );
692 // Copy extra outputs
693 if (fExtraFiles.Length() && isManagedByHandler) {
694 TObjArray *arr = fExtraFiles.Tokenize(" ");
696 TIter nextfilename(arr);
697 while ((os=(TObjString*)nextfilename())) {
698 outFilename = os->GetString();
699 remote = fSpecialOutputLocation;
701 if (remote.BeginsWith("alien://")) {
702 remote += outFilename;
703 remote.ReplaceAll(".root", Form("_%d.root", gid));
705 remote += Form("%s_%d_", gSystem->HostName(), gid);
706 remote += outFilename;
709 Info("PackOutput", "Extra AOD file %s to be copied \n at: %s. No merging.",
710 outFilename.Data(), remote.Data());
711 TFile::Cp ( outFilename.Data(), remote.Data() );
716 // No special location specified-> use TProofOutputFile as merging utility
717 // The file at this output slot must be opened in CreateOutputObjects
718 if (fDebug > 1) printf(" File for container %s to be merged via file merger...\n", output->GetName());
724 if (fDebug > 1) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
727 //______________________________________________________________________________
728 void AliAnalysisManager::ImportWrappers(TList *source)
730 // Import data in output containers from wrappers coming in source.
731 if (fDebug > 1) printf("->AliAnalysisManager::ImportWrappers()\n");
732 TIter next(fOutputs);
733 AliAnalysisDataContainer *cont;
734 AliAnalysisDataWrapper *wrap;
736 Bool_t inGrid = (fMode == kGridAnalysis)?kTRUE:kFALSE;
737 TDirectory *cdir = gDirectory;
738 while ((cont=(AliAnalysisDataContainer*)next())) {
740 if (cont->GetProducer() && cont->GetProducer()->IsPostEventLoop() && !inGrid) continue;
741 if (cont->IsRegisterDataset()) continue;
742 const char *filename = cont->GetFileName();
743 Bool_t isManagedByHandler = kFALSE;
744 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
745 isManagedByHandler = kTRUE;
746 filename = fOutputEventHandler->GetOutputFileName();
748 if (cont->IsSpecialOutput() || inGrid) {
749 if (strlen(fSpecialOutputLocation.Data())) continue;
750 // Copy merged file from PROOF scratch space.
751 // In case of grid the files are already in the current directory.
753 if (isManagedByHandler && fExtraFiles.Length()) {
754 // Copy extra registered dAOD files.
755 TObjArray *arr = fExtraFiles.Tokenize(" ");
757 TIter nextfilename(arr);
758 while ((os=(TObjString*)nextfilename())) GetFileFromWrapper(os->GetString(), source);
761 if (!GetFileFromWrapper(filename, source)) continue;
763 // Normally we should connect data from the copied file to the
764 // corresponding output container, but it is not obvious how to do this
765 // automatically if several objects in file...
766 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
767 if (!f) f = TFile::Open(filename, "READ");
769 Error("ImportWrappers", "Cannot open file %s in read-only mode", filename);
774 // Cd to the directory pointed by the container
775 TString folder = cont->GetFolderName();
776 if (!folder.IsNull()) f->cd(folder);
777 // Try to fetch first an object having the container name.
778 obj = gDirectory->Get(cont->GetName());
780 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",
781 cont->GetType()->GetName(), cont->GetName(), filename, cont->GetFolderName(), cont->GetName());
784 wrap = new AliAnalysisDataWrapper(obj);
785 wrap->SetDeleteData(kFALSE);
787 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
789 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
794 printf(" Importing data for container %s\n", cont->GetName());
795 if (strlen(filename)) printf(" -> file %s\n", filename);
798 cont->ImportData(wrap);
800 if (cdir) cdir->cd();
801 if (fDebug > 1) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
804 //______________________________________________________________________________
805 void AliAnalysisManager::UnpackOutput(TList *source)
807 // Called by AliAnalysisSelector::Terminate only on the client.
808 if (fDebug > 1) printf("->AliAnalysisManager::UnpackOutput()\n");
810 Error("UnpackOutput", "No target. Exiting.");
813 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
815 if (fMode == kProofAnalysis) ImportWrappers(source);
817 TIter next(fOutputs);
818 AliAnalysisDataContainer *output;
819 while ((output=(AliAnalysisDataContainer*)next())) {
820 if (!output->GetData()) continue;
821 // Check if there are client tasks that run post event loop
822 if (output->HasConsumers()) {
823 // Disable event loop semaphore
824 output->SetPostEventLoop(kTRUE);
825 TObjArray *list = output->GetConsumers();
826 Int_t ncons = list->GetEntriesFast();
827 for (Int_t i=0; i<ncons; i++) {
828 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
829 task->CheckNotify(kTRUE);
830 // If task is active, execute it
831 if (task->IsPostEventLoop() && task->IsActive()) {
832 if (fDebug > 1) printf("== Executing post event loop task %s\n", task->GetName());
838 if (fDebug > 1) printf("<-AliAnalysisManager::UnpackOutput()\n");
841 //______________________________________________________________________________
842 void AliAnalysisManager::Terminate()
844 // The Terminate() function is the last function to be called during
845 // a query. It always runs on the client, it can be used to present
846 // the results graphically.
847 if (fDebug > 1) printf("->AliAnalysisManager::Terminate()\n");
848 TDirectory *cdir = gDirectory;
850 AliAnalysisTask *task;
851 AliAnalysisDataContainer *output;
854 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
855 // Call Terminate() for tasks
857 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
858 // Save all the canvases produced by the Terminate
859 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
863 AliSysInfo::AddStamp(Form("%s_TERMINATE",task->ClassName()),0, itask, 2);
865 if (TObject::TestBit(kSaveCanvases)) {
866 if (!gROOT->IsBatch()) {
867 if (fDebug>1) printf("Waiting 5 sec for %s::Terminate() to finish drawing ...\n", task->ClassName());
869 while (timer.CpuTime()<5) {
871 gSystem->ProcessEvents();
874 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
875 if (iend==0) continue;
877 for (Int_t ipict=0; ipict<iend; ipict++) {
878 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
879 if (!canvas) continue;
880 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
882 gROOT->GetListOfCanvases()->Delete();
886 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
887 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
888 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
890 TObjArray *allOutputs = new TObjArray();
892 for (icont=0; icont<fOutputs->GetEntriesFast(); icont++) allOutputs->Add(fOutputs->At(icont));
893 if (!IsSkipTerminate())
894 for (icont=0; icont<fParamCont->GetEntriesFast(); icont++) allOutputs->Add(fParamCont->At(icont));
895 TIter next1(allOutputs);
896 TString handlerFile = "";
897 TString extraOutputs = "";
898 if (fOutputEventHandler) {
899 handlerFile = fOutputEventHandler->GetOutputFileName();
900 extraOutputs = fOutputEventHandler->GetExtraOutputs();
904 while ((output=(AliAnalysisDataContainer*)next1())) {
905 // Special outputs or grid files have the files already closed and written.
907 if (fMode == kGridAnalysis && icont<=fOutputs->GetEntriesFast()) continue;
908 if (fMode == kProofAnalysis) {
909 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
911 const char *filename = output->GetFileName();
912 TString openoption = "RECREATE";
913 if (!(strcmp(filename, "default"))) continue;
914 if (!strlen(filename)) continue;
915 if (!output->GetData()) continue;
916 TDirectory *opwd = gDirectory;
917 TFile *file = output->GetFile();
918 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
920 //if (handlerFile == filename && !gSystem->AccessPathName(filename)) openoption = "UPDATE";
921 Bool_t firsttime = kTRUE;
922 if (filestmp.FindObject(filename) || extraOutputs.Contains(filename)) {
925 filestmp.Add(new TNamed(filename,""));
927 if (!gSystem->AccessPathName(filename) && !firsttime) openoption = "UPDATE";
928 if (fDebug>1) printf("Opening file: %s option=%s\n",filename, openoption.Data());
929 file = new TFile(filename, openoption);
931 if (fDebug>1) printf("File <%s> already opened with option: <%s> \n", filename, file->GetOption());
932 openoption = file->GetOption();
933 if (openoption == "READ") {
934 if (fDebug>1) printf("...reopening in UPDATE mode\n");
935 file->ReOpen("UPDATE");
938 if (file->IsZombie()) {
939 Error("Terminate", "Cannot open output file %s", filename);
942 output->SetFile(file);
944 // Check for a folder request
945 TString dir = output->GetFolderName();
947 if (!file->GetDirectory(dir)) file->mkdir(dir);
950 if (fDebug > 1) printf("...writing container %s to file %s:%s\n", output->GetName(), file->GetName(), output->GetFolderName());
951 if (output->GetData()->InheritsFrom(TCollection::Class())) {
952 // If data is a collection, we set the name of the collection
953 // as the one of the container and we save as a single key.
954 TCollection *coll = (TCollection*)output->GetData();
955 coll->SetName(output->GetName());
956 coll->Write(output->GetName(), TObject::kSingleKey);
958 if (output->GetData()->InheritsFrom(TTree::Class())) {
959 TTree *tree = (TTree*)output->GetData();
960 tree->SetDirectory(gDirectory);
963 output->GetData()->Write();
966 if (opwd) opwd->cd();
971 while ((output=(AliAnalysisDataContainer*)next1())) {
972 // Close all files at output
973 TDirectory *opwd = gDirectory;
974 if (output->GetFile()) {
975 // Clear file list to release object ownership to user.
976 // output->GetFile()->Clear();
977 output->GetFile()->Close();
978 // Copy merged outputs in alien if requested
979 if (fSpecialOutputLocation.BeginsWith("alien://")) {
980 if (copiedFiles.Contains(output->GetFile()->GetName())) {
981 if (opwd) opwd->cd();
982 output->SetFile(NULL);
985 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
986 gROOT->ProcessLine("if (!gGrid) TGrid::Connect(\"alien:\");");
987 TFile::Cp(output->GetFile()->GetName(),
988 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
989 copiedFiles += output->GetFile()->GetName();
991 output->SetFile(NULL);
993 if (opwd) opwd->cd();
996 //Write statistics information on the client
997 if (fStatistics) WriteStatisticsMsg(fNcalls);
999 TDirectory *crtdir = gDirectory;
1000 TFile f("syswatch.root", "RECREATE");
1003 if (!f.IsZombie()) {
1004 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
1005 tree->SetName("syswatch");
1006 tree->SetMarkerStyle(kCircle);
1007 tree->SetMarkerColor(kBlue);
1008 tree->SetMarkerSize(0.5);
1009 if (!gROOT->IsBatch()) {
1010 tree->SetAlias("event", "id0");
1011 tree->SetAlias("task", "id1");
1012 tree->SetAlias("stage", "id2");
1013 // Already defined aliases
1014 // tree->SetAlias("deltaT","stampSec-stampOldSec");
1015 // tree->SetAlias("T","stampSec-first");
1016 // tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)");
1017 // tree->SetAlias("VM","pI.fMemVirtual");
1018 TCanvas *canvas = new TCanvas("SysInfo","SysInfo",10,10,1200,800);
1019 Int_t npads = 1 /*COO plot for all tasks*/ +
1020 fTopTasks->GetEntries() /*Exec plot per task*/ +
1021 1 /*Terminate plot for all tasks*/ +
1024 Int_t iopt = (Int_t)TMath::Sqrt((Double_t)npads);
1025 if (npads<iopt*(iopt+1))
1026 canvas->Divide(iopt, iopt+1, 0.01, 0.01);
1028 canvas->Divide(iopt+1, iopt+1, 0.01, 0.01);
1030 // draw the plot of deltaVM for Exec for each task
1031 for (itask=0; itask<fTopTasks->GetEntriesFast(); itask++) {
1032 task = (AliAnalysisTask*)fTopTasks->At(itask);
1034 cut = Form("task==%d && stage==1", itask);
1035 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1036 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1038 hist->SetTitle(Form("%s: Exec dVM[MB]/event", task->GetName()));
1039 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1042 // Draw the plot of deltaVM for CreateOutputObjects for all tasks
1044 tree->SetMarkerStyle(kFullTriangleUp);
1045 tree->SetMarkerColor(kRed);
1046 tree->SetMarkerSize(0.8);
1047 cut = "task>=0 && task<1000 && stage==0";
1048 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1049 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1051 hist->SetTitle("Memory in CreateOutputObjects()");
1052 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1053 hist->GetXaxis()->SetTitle("task");
1055 // draw the plot of deltaVM for Terminate for all tasks
1057 tree->SetMarkerStyle(kOpenSquare);
1058 tree->SetMarkerColor(kMagenta);
1059 cut = "task>=0 && task<1000 && stage==2";
1060 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1061 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1063 hist->SetTitle("Memory in Terminate()");
1064 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1065 hist->GetXaxis()->SetTitle("task");
1069 tree->SetMarkerStyle(kFullCircle);
1070 tree->SetMarkerColor(kGreen);
1071 cut = Form("task==%d && stage==1",fTopTasks->GetEntriesFast()-1);
1072 tree->Draw("VM:event",cut,"", 1234567890, 0);
1073 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1075 hist->SetTitle("Virtual memory");
1076 hist->GetYaxis()->SetTitle("VM [MB]");
1080 tree->SetMarkerStyle(kCircle);
1081 tree->SetMarkerColor(kBlue);
1082 tree->SetMarkerSize(0.5);
1087 if (crtdir) crtdir->cd();
1089 // Validate the output files
1090 if (ValidateOutputFiles() && fIsRemote && fMode!=kProofAnalysis) {
1092 out.open("outputs_valid", ios::out);
1096 if (fDebug > 1) printf("<-AliAnalysisManager::Terminate()\n");
1098 //______________________________________________________________________________
1099 void AliAnalysisManager::ProfileTask(Int_t itop, const char *option) const
1101 // Profiles the task having the itop index in the list of top (first level) tasks.
1102 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->At(itop);
1104 Error("ProfileTask", "There are only %d top tasks in the manager", fTopTasks->GetEntries());
1107 ProfileTask(task->GetName(), option);
1110 //______________________________________________________________________________
1111 void AliAnalysisManager::ProfileTask(const char *name, const char */*option*/) const
1113 // Profile a managed task after the execution of the analysis in case NSysInfo
1115 if (gSystem->AccessPathName("syswatch.root")) {
1116 Error("ProfileTask", "No file syswatch.root found in the current directory");
1119 if (gROOT->IsBatch()) return;
1120 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->FindObject(name);
1122 Error("ProfileTask", "No top task named %s known by the manager.", name);
1125 Int_t itop = fTopTasks->IndexOf(task);
1126 Int_t itask = fTasks->IndexOf(task);
1127 // Create canvas with 2 pads: first draw COO + Terminate, second Exec
1128 TDirectory *cdir = gDirectory;
1129 TFile f("syswatch.root");
1130 TTree *tree = (TTree*)f.Get("syswatch");
1132 Error("ProfileTask", "No tree named <syswatch> found in file syswatch.root");
1135 if (fDebug > 1) printf("=== Profiling task %s (class %s)\n", name, task->ClassName());
1136 TCanvas *canvas = new TCanvas(Form("profile_%d",itop),Form("Profile of task %s (class %s)",name,task->ClassName()),10,10,800,600);
1137 canvas->Divide(2, 2, 0.01, 0.01);
1141 // VM profile for COO and Terminate methods
1143 cut = Form("task==%d && (stage==0 || stage==2)",itask);
1144 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1145 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1147 hist->SetTitle("Alocated VM[MB] for COO and Terminate");
1148 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1149 hist->GetXaxis()->SetTitle("method");
1151 // CPU profile per event
1153 cut = Form("task==%d && stage==1",itop);
1154 tree->Draw("deltaT:event",cut,"", 1234567890, 0);
1155 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1157 hist->SetTitle("Execution time per event");
1158 hist->GetYaxis()->SetTitle("CPU/event [s]");
1160 // VM profile for Exec
1162 cut = Form("task==%d && stage==1",itop);
1163 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1164 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1166 hist->SetTitle("Alocated VM[MB] per event");
1167 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1172 if (cdir) cdir->cd();
1175 //______________________________________________________________________________
1176 void AliAnalysisManager::AddTask(AliAnalysisTask *task)
1178 // Adds a user task to the global list of tasks.
1180 Error("AddTask", "Cannot add task %s since InitAnalysis was already called", task->GetName());
1184 if (fTasks->FindObject(task)) {
1185 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
1188 task->SetActive(kFALSE);
1192 //______________________________________________________________________________
1193 AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
1195 // Retreive task by name.
1196 if (!fTasks) return NULL;
1197 return (AliAnalysisTask*)fTasks->FindObject(name);
1200 //______________________________________________________________________________
1201 AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
1202 TClass *datatype, EAliAnalysisContType type, const char *filename)
1204 // Create a data container of a certain type. Types can be:
1205 // kExchangeContainer = 0, used to exchange data between tasks
1206 // kInputContainer = 1, used to store input data
1207 // kOutputContainer = 2, used for writing result to a file
1208 // filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
1209 // the output object to a folder inside the output file
1210 if (fContainers->FindObject(name)) {
1211 Error("CreateContainer","A container named %s already defined !",name);
1214 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
1215 fContainers->Add(cont);
1217 case kInputContainer:
1220 case kOutputContainer:
1221 fOutputs->Add(cont);
1222 if (filename && strlen(filename)) {
1223 cont->SetFileName(filename);
1224 cont->SetDataOwned(kFALSE); // data owned by the file
1227 case kParamContainer:
1228 fParamCont->Add(cont);
1229 if (filename && strlen(filename)) {
1230 cont->SetFileName(filename);
1231 cont->SetDataOwned(kFALSE); // data owned by the file
1234 case kExchangeContainer:
1240 //______________________________________________________________________________
1241 Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
1242 AliAnalysisDataContainer *cont)
1244 // Connect input of an existing task to a data container.
1246 Error("ConnectInput", "Task pointer is NULL");
1249 if (!fTasks->FindObject(task)) {
1251 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
1253 Bool_t connected = task->ConnectInput(islot, cont);
1257 //______________________________________________________________________________
1258 Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
1259 AliAnalysisDataContainer *cont)
1261 // Connect output of an existing task to a data container.
1263 Error("ConnectOutput", "Task pointer is NULL");
1266 if (!fTasks->FindObject(task)) {
1268 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
1270 Bool_t connected = task->ConnectOutput(islot, cont);
1274 //______________________________________________________________________________
1275 void AliAnalysisManager::CleanContainers()
1277 // Clean data from all containers that have already finished all client tasks.
1278 TIter next(fContainers);
1279 AliAnalysisDataContainer *cont;
1280 while ((cont=(AliAnalysisDataContainer *)next())) {
1281 if (cont->IsOwnedData() &&
1282 cont->IsDataReady() &&
1283 cont->ClientsExecuted()) cont->DeleteData();
1287 //______________________________________________________________________________
1288 Bool_t AliAnalysisManager::InitAnalysis()
1290 // Initialization of analysis chain of tasks. Should be called after all tasks
1291 // and data containers are properly connected
1292 // Reset flag and remove valid_outputs file if exists
1293 if (fInitOK) return kTRUE;
1294 if (!gSystem->AccessPathName("outputs_valid"))
1295 gSystem->Unlink("outputs_valid");
1296 // Check for top tasks (depending only on input data containers)
1297 if (!fTasks->First()) {
1298 Error("InitAnalysis", "Analysis has no tasks !");
1302 AliAnalysisTask *task;
1303 AliAnalysisDataContainer *cont;
1306 Bool_t iszombie = kFALSE;
1307 Bool_t istop = kTRUE;
1309 while ((task=(AliAnalysisTask*)next())) {
1312 Int_t ninputs = task->GetNinputs();
1313 for (i=0; i<ninputs; i++) {
1314 cont = task->GetInputSlot(i)->GetContainer();
1318 fZombies->Add(task);
1322 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
1323 i, task->GetName());
1325 if (iszombie) continue;
1326 // Check if cont is an input container
1327 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
1328 // Connect to parent task
1332 fTopTasks->Add(task);
1336 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
1339 // Check now if there are orphan tasks
1340 for (i=0; i<ntop; i++) {
1341 task = (AliAnalysisTask*)fTopTasks->At(i);
1346 while ((task=(AliAnalysisTask*)next())) {
1347 if (!task->IsUsed()) {
1349 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
1352 // Check the task hierarchy (no parent task should depend on data provided
1353 // by a daughter task)
1354 for (i=0; i<ntop; i++) {
1355 task = (AliAnalysisTask*)fTopTasks->At(i);
1356 if (task->CheckCircularDeps()) {
1357 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
1362 // Check that all containers feeding post-event loop tasks are in the outputs list
1363 TIter nextcont(fContainers); // loop over all containers
1364 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1365 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1366 if (cont->HasConsumers()) {
1367 // Check if one of the consumers is post event loop
1368 TIter nextconsumer(cont->GetConsumers());
1369 while ((task=(AliAnalysisTask*)nextconsumer())) {
1370 if (task->IsPostEventLoop()) {
1371 fOutputs->Add(cont);
1378 // Check if all special output containers have a file name provided
1379 TIter nextout(fOutputs);
1380 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1381 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1382 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1386 // Initialize requested branch list if needed
1387 if (!fAutoBranchHandling) {
1389 while ((task=(AliAnalysisTask*)next())) {
1390 if (!task->HasBranches()) {
1391 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\"",
1392 task->GetName(), task->ClassName());
1395 if (!fInputEventHandler || !strlen(fInputEventHandler->GetDataType())) {
1396 Error("InitAnalysis", "Manual branch loading requested but no input handler defined or handler does not define data type.");
1399 TString taskbranches;
1400 task->GetBranches(fInputEventHandler->GetDataType(), taskbranches);
1401 if (taskbranches.IsNull()) {
1402 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches of type %s:",
1403 task->GetName(), task->ClassName(), fInputEventHandler->GetDataType());
1406 AddBranches(taskbranches);
1413 //______________________________________________________________________________
1414 void AliAnalysisManager::AddBranches(const char *branches)
1416 // Add branches to the existing fRequestedBranches.
1417 TString br(branches);
1418 TObjArray *arr = br.Tokenize(",");
1421 while ((obj=next())) {
1422 if (!fRequestedBranches.Contains(obj->GetName())) {
1423 if (!fRequestedBranches.IsNull()) fRequestedBranches += ",";
1424 fRequestedBranches += obj->GetName();
1430 //______________________________________________________________________________
1431 void AliAnalysisManager::CheckBranches(Bool_t load)
1433 // The method checks the input branches to be loaded during the analysis.
1434 if (fAutoBranchHandling || fRequestedBranches.IsNull() || !fTree) return;
1435 TObjArray *arr = fRequestedBranches.Tokenize(",");
1438 while ((obj=next())) {
1439 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(obj->GetName()));
1441 br = fTree->GetBranch(obj->GetName());
1443 Error("CheckBranches", "Could not find branch %s",obj->GetName());
1448 if (load && br->GetReadEntry()!=GetCurrentEntry()) br->GetEntry(GetCurrentEntry());
1453 //______________________________________________________________________________
1454 Bool_t AliAnalysisManager::CheckTasks() const
1456 // Check consistency of tasks.
1457 Int_t ntasks = fTasks->GetEntries();
1459 Error("CheckTasks", "No tasks connected to the manager. This may be due to forgetting to compile the task or to load their library.");
1462 // Get the pointer to AliAnalysisTaskSE::Class()
1463 TClass *badptr = (TClass*)gROOT->ProcessLine("AliAnalysisTaskSE::Class()");
1464 // Loop all tasks to check if their corresponding library was loaded
1467 while ((obj=next())) {
1468 if (obj->IsA() == badptr) {
1469 Error("CheckTasks", "##################\n \
1470 Class for task %s NOT loaded. You probably forgot to load the library for this task (or compile it dynamically).\n###########################\n",obj->GetName());
1477 //______________________________________________________________________________
1478 void AliAnalysisManager::PrintStatus(Option_t *option) const
1480 // Print task hierarchy.
1482 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1485 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1487 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
1488 TIter next(fTopTasks);
1489 AliAnalysisTask *task;
1490 while ((task=(AliAnalysisTask*)next()))
1491 task->PrintTask(option);
1493 if (!fAutoBranchHandling && !fRequestedBranches.IsNull())
1494 printf("Requested input branches:\n%s\n", fRequestedBranches.Data());
1496 TString sopt(option);
1499 if (sopt.Contains("ALL"))
1501 if ( fOutputEventHandler )
1503 cout << TString('_',78) << endl;
1504 cout << "OutputEventHandler:" << endl;
1505 fOutputEventHandler->Print(" ");
1510 //______________________________________________________________________________
1511 void AliAnalysisManager::ResetAnalysis()
1513 // Reset all execution flags and clean containers.
1517 //______________________________________________________________________________
1518 void AliAnalysisManager::RunLocalInit()
1520 // Run LocalInit method for all tasks.
1521 TDirectory *cdir = gDirectory;
1522 if (IsTrainInitialized()) return;
1523 TIter nextTask(fTasks);
1524 AliAnalysisTask *task;
1525 while ((task=(AliAnalysisTask*)nextTask())) {
1530 TObject::SetBit(kTasksInitialized, kTRUE);
1533 //______________________________________________________________________________
1534 Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
1536 // Start analysis having a grid handler.
1537 if (!fGridHandler) {
1538 Error("StartAnalysis", "Cannot start analysis providing just the analysis type without a grid handler.");
1539 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1543 return StartAnalysis(type, tree, nentries, firstentry);
1546 //______________________________________________________________________________
1547 Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
1549 // Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1550 // MIX. Process nentries starting from firstentry
1552 // Backup current directory and make sure gDirectory points to gROOT
1553 TDirectory *cdir = gDirectory;
1556 Error("StartAnalysis","Analysis manager was not initialized !");
1560 if (!CheckTasks()) Fatal("StartAnalysis", "Not all needed libraries were loaded");
1562 printf("StartAnalysis %s\n",GetName());
1563 AliLog::SetGlobalLogLevel(AliLog::kInfo);
1565 fMaxEntries = nentries;
1567 TString anaType = type;
1569 fMode = kLocalAnalysis;
1570 if (anaType.Contains("file")) fIsRemote = kTRUE;
1571 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1572 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1573 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1575 if (fMode == kGridAnalysis) {
1577 if (!anaType.Contains("terminate")) {
1578 if (!fGridHandler) {
1579 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1580 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1584 // Write analysis manager in the analysis file
1585 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1586 // run local task configuration
1588 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1589 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1594 // Terminate grid analysis
1595 if (fSelector && fSelector->GetStatus() == -1) {cdir->cd(); return -1;}
1596 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {cdir->cd(); return 0;}
1597 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1598 if (!fGridHandler->MergeOutputs()) {
1599 // Return if outputs could not be merged or if it alien handler
1600 // was configured for offline mode or local testing.
1605 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1606 ImportWrappers(NULL);
1612 SetEventLoop(kFALSE);
1613 // Enable event loop mode if a tree was provided
1614 if (tree || fGridHandler || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
1617 TString ttype = "TTree";
1618 if (tree && tree->IsA() == TChain::Class()) {
1619 chain = (TChain*)tree;
1620 if (!chain || !chain->GetListOfFiles()->First()) {
1621 Error("StartAnalysis", "Cannot process null or empty chain...");
1628 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1629 if (getsysInfo) AliSysInfo::AddStamp("Start", 0);
1630 // Initialize locally all tasks (happens for all modes)
1632 AliAnalysisTask *task;
1636 case kLocalAnalysis:
1637 if (!tree && !fGridHandler) {
1638 TIter nextT(fTasks);
1639 // Call CreateOutputObjects for all tasks
1641 Bool_t dirStatus = TH1::AddDirectoryStatus();
1642 while ((task=(AliAnalysisTask*)nextT())) {
1643 TH1::AddDirectory(kFALSE);
1644 task->CreateOutputObjects();
1645 if (!task->CheckPostData()) {
1646 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
1647 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
1648 ########### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ###########", task->GetName(), task->ClassName());
1650 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
1654 TH1::AddDirectory(dirStatus);
1655 if (IsExternalLoop()) {
1656 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1657 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1664 fSelector = new AliAnalysisSelector(this);
1665 // Check if a plugin handler is used
1667 // Get the chain from the plugin
1668 TString dataType = "esdTree";
1669 if (fInputEventHandler) {
1670 dataType = fInputEventHandler->GetDataType();
1674 chain = fGridHandler->GetChainForTestMode(dataType);
1676 Error("StartAnalysis", "No chain for test mode. Aborting.");
1679 cout << "===== RUNNING LOCAL ANALYSIS" << GetName() << " ON CHAIN " << chain->GetName() << endl;
1680 retv = chain->Process(fSelector, "", nentries, firstentry);
1683 // Run tree-based analysis via AliAnalysisSelector
1684 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
1685 retv = tree->Process(fSelector, "", nentries, firstentry);
1687 case kProofAnalysis:
1689 // Check if the plugin is used
1691 return StartAnalysis(type, fGridHandler->GetProofDataSet(), nentries, firstentry);
1693 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1694 Error("StartAnalysis", "No PROOF!!! Exiting.");
1698 line = Form("gProof->AddInput((TObject*)%p);", this);
1699 gROOT->ProcessLine(line);
1702 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
1703 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
1705 Error("StartAnalysis", "No chain!!! Exiting.");
1712 if (!anaType.Contains("terminate")) {
1713 if (!fGridHandler) {
1714 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1715 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1719 // Write analysis manager in the analysis file
1720 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1721 // Start the analysis via the handler
1722 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1723 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1728 // Terminate grid analysis
1729 if (fSelector && fSelector->GetStatus() == -1) {cdir->cd(); return -1;}
1730 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {cdir->cd(); return 0;}
1731 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1732 if (!fGridHandler->MergeOutputs()) {
1733 // Return if outputs could not be merged or if it alien handler
1734 // was configured for offline mode or local testing.
1739 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1740 ImportWrappers(NULL);
1744 case kMixingAnalysis:
1745 // Run event mixing analysis
1747 Error("StartAnalysis", "Cannot run event mixing without event pool");
1751 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1752 fSelector = new AliAnalysisSelector(this);
1753 while ((chain=fEventPool->GetNextChain())) {
1755 // Call NotifyBinChange for all tasks
1756 while ((task=(AliAnalysisTask*)next()))
1757 if (!task->IsPostEventLoop()) task->NotifyBinChange();
1758 retv = chain->Process(fSelector);
1760 Error("StartAnalysis", "Mixing analysis failed");
1765 PackOutput(fSelector->GetOutputList());
1772 //______________________________________________________________________________
1773 Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
1775 // Start analysis for this manager on a given dataset. Analysis task can be:
1776 // LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1778 Error("StartAnalysis","Analysis manager was not initialized !");
1782 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
1783 TString anaType = type;
1785 if (!anaType.Contains("proof")) {
1786 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
1789 fMode = kProofAnalysis;
1791 SetEventLoop(kTRUE);
1792 // Set the dataset flag
1793 TObject::SetBit(kUseDataSet);
1796 // Start proof analysis using the grid handler
1797 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1798 Error("StartAnalysis", "The grid plugin could not start PROOF analysis");
1801 // Check if the plugin is in test mode
1802 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kTest) {
1803 dataset = "test_collection";
1805 dataset = fGridHandler->GetProofDataSet();
1809 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1810 Error("StartAnalysis", "No PROOF!!! Exiting.");
1814 // Initialize locally all tasks
1817 line = Form("gProof->AddInput((TObject*)%p);", this);
1818 gROOT->ProcessLine(line);
1820 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"\", %lld, %lld);",
1821 dataset, nentries, firstentry);
1822 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
1823 retv = (Long_t)gROOT->ProcessLine(line);
1827 //______________________________________________________________________________
1828 TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
1830 // Opens according the option the file specified by cont->GetFileName() and changes
1831 // current directory to cont->GetFolderName(). If the file was already opened, it
1832 // checks if the option UPDATE was preserved. File open via TProofOutputFile can
1833 // be optionally ignored.
1834 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1835 TString filename = cont->GetFileName();
1837 if (filename.IsNull()) {
1838 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
1841 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
1843 f = mgr->OpenProofFile(cont,option);
1845 // Check first if the file is already opened
1846 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1848 // Check if option "UPDATE" was preserved
1849 TString opt(option);
1851 if ((opt=="UPDATE") && (opt!=f->GetOption()))
1852 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
1854 f = TFile::Open(filename, option);
1857 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1861 // Check for a folder request
1862 TString dir = cont->GetFolderName();
1863 if (!dir.IsNull()) {
1864 if (!f->GetDirectory(dir)) f->mkdir(dir);
1869 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
1870 cont->SetFile(NULL);
1874 //______________________________________________________________________________
1875 TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option, const char *extaod)
1877 // Opens a special output file used in PROOF.
1879 TString filename = cont->GetFileName();
1880 if (cont == fCommonOutput) {
1881 if (fOutputEventHandler) {
1882 if (strlen(extaod)) filename = extaod;
1883 filename = fOutputEventHandler->GetOutputFileName();
1885 else Fatal("OpenProofFile","No output container. Exiting.");
1888 if (fMode!=kProofAnalysis || !fSelector) {
1889 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
1892 if (fSpecialOutputLocation.Length()) {
1893 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1895 // Check if option "UPDATE" was preserved
1896 TString opt(option);
1898 if ((opt=="UPDATE") && (opt!=f->GetOption()))
1899 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
1901 f = new TFile(filename, option);
1903 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1907 // Check for a folder request
1908 TString dir = cont->GetFolderName();
1910 if (!f->GetDirectory(dir)) f->mkdir(dir);
1915 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
1916 cont->SetFile(NULL);
1919 // Check if there is already a proof output file in the output list
1920 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
1922 // Get the actual file
1923 line = Form("((TProofOutputFile*)%p)->GetFileName();", pof);
1924 filename = (const char*)gROOT->ProcessLine(line);
1926 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
1928 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1930 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
1933 // Check if option "UPDATE" was preserved
1934 TString opt(option);
1936 if ((opt=="UPDATE") && (opt!=f->GetOption()))
1937 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
1939 if (cont->IsRegisterDataset()) {
1940 TString dsetName = filename;
1941 dsetName.ReplaceAll(".root", cont->GetTitle());
1942 dsetName.ReplaceAll(":","_");
1943 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
1944 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
1946 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
1947 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
1949 if (fDebug > 1) printf("=== %s\n", line.Data());
1950 gROOT->ProcessLine(line);
1951 line = Form("pf->OpenFile(\"%s\");", option);
1952 gROOT->ProcessLine(line);
1955 gROOT->ProcessLine("pf->Print()");
1956 printf(" == proof file name: %s", f->GetName());
1958 // Add to proof output list
1959 line = Form("((TList*)%p)->Add(pf);",fSelector->GetOutputList());
1960 if (fDebug > 1) printf("=== %s\n", line.Data());
1961 gROOT->ProcessLine(line);
1963 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1967 // Check for a folder request
1968 TString dir = cont->GetFolderName();
1969 if (!dir.IsNull()) {
1970 if (!f->GetDirectory(dir)) f->mkdir(dir);
1975 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
1976 cont->SetFile(NULL);
1980 //______________________________________________________________________________
1981 void AliAnalysisManager::ExecAnalysis(Option_t *option)
1983 // Execute analysis.
1984 static Long64_t nentries = 0;
1985 static TTree *lastTree = 0;
1986 static TStopwatch *timer = new TStopwatch();
1987 // Only the first call to Process will trigger a true Notify. Other Notify
1988 // coming before is ignored.
1989 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) {
1990 TObject::SetBit(AliAnalysisManager::kTrueNotify);
1993 if (fDebug > 0) printf("MGR: Processing event #%d\n", fNcalls);
1995 if (fTree && (fTree != lastTree)) {
1996 nentries += fTree->GetEntries();
1999 if (!fNcalls) timer->Start();
2000 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", fNcalls, TMath::Min(fMaxEntries,nentries), timer, kFALSE);
2003 TDirectory *cdir = gDirectory;
2004 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
2005 if (getsysInfo && ((fNcalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)fNcalls);
2007 Error("ExecAnalysis", "Analysis manager was not initialized !");
2012 AliAnalysisTask *task;
2013 // Check if the top tree is active.
2015 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2016 AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
2018 // De-activate all tasks
2019 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
2020 AliAnalysisDataContainer *cont = fCommonInput;
2021 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
2023 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
2027 cont->SetData(fTree); // This will notify all consumers
2028 Long64_t entry = fTree->GetTree()->GetReadEntry();
2030 // Call BeginEvent() for optional input/output and MC services
2031 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
2032 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
2033 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
2035 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2036 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2038 // Execute the tasks
2039 // TIter next1(cont->GetConsumers());
2040 TIter next1(fTopTasks);
2042 while ((task=(AliAnalysisTask*)next1())) {
2044 cout << " Executing task " << task->GetName() << endl;
2046 task->ExecuteTask(option);
2048 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2049 AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
2053 // Call FinishEvent() for optional output and MC services
2054 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2055 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2056 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2057 // Gather system information if requested
2058 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2059 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1001, 1);
2063 // The event loop is not controlled by TSelector
2065 // Call BeginEvent() for optional input/output and MC services
2066 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
2067 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
2068 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
2070 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2071 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2072 TIter next2(fTopTasks);
2073 while ((task=(AliAnalysisTask*)next2())) {
2074 task->SetActive(kTRUE);
2076 cout << " Executing task " << task->GetName() << endl;
2078 task->ExecuteTask(option);
2082 // Call FinishEvent() for optional output and MC services
2083 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2084 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2085 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2086 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2087 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
2091 //______________________________________________________________________________
2092 Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
2094 // Check if the stdout is connected to a pipe (C.Holm)
2095 Bool_t ispipe = kFALSE;
2096 out.seekp(0, std::ios_base::cur);
2099 if (errno == ESPIPE) ispipe = kTRUE;
2104 //______________________________________________________________________________
2105 void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
2107 // Set the input event handler and create a container for it.
2108 fInputEventHandler = handler;
2109 if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
2112 //______________________________________________________________________________
2113 void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
2115 // Set the input event handler and create a container for it.
2116 fOutputEventHandler = handler;
2117 if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
2118 fCommonOutput->SetSpecialOutput();
2121 //______________________________________________________________________________
2122 void AliAnalysisManager::SetDebugLevel(UInt_t level)
2124 // Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
2125 if (TObject::TestBit(kUseProgressBar)) {
2126 Info("SetDebugLevel","Ignored. Disable the progress bar first.");
2132 //______________________________________________________________________________
2133 void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
2135 // Enable a text mode progress bar. Resets debug level to 0.
2136 Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
2137 TObject::SetBit(kUseProgressBar,flag);
2138 fPBUpdateFreq = freq;
2142 //______________________________________________________________________________
2143 void AliAnalysisManager::RegisterExtraFile(const char *fname)
2145 // This method is used externally to register output files which are not
2146 // connected to any output container, so that the manager can properly register,
2147 // retrieve or merge them when running in distributed mode. The file names are
2148 // separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
2149 if (fExtraFiles.Contains(fname)) return;
2150 if (fExtraFiles.Length()) fExtraFiles += " ";
2151 fExtraFiles += fname;
2154 //______________________________________________________________________________
2155 Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
2157 // Copy a file from the location specified ina the wrapper with the same name from the source list.
2161 TObject *pof = source->FindObject(filename);
2162 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
2163 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
2166 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
2167 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
2168 TString clientUrl(chUrl);
2169 TString fullPath_str(fullPath);
2170 if (clientUrl.Contains("localhost")){
2171 TObjArray* array = fullPath_str.Tokenize ( "//" );
2172 TObjString *strobj = ( TObjString *)array->At(1);
2173 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
2174 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
2175 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
2176 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
2177 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
2181 else if (clientUrl.Contains("__lite__")) {
2182 // Special case for ProofLite environement - get file info and copy.
2183 gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
2184 fullPath_str = Form("%s/%s", tmp, fullPath);
2187 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
2188 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
2190 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
2194 //______________________________________________________________________________
2195 void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
2197 // Fill analysis type in the provided string.
2199 case kLocalAnalysis:
2202 case kProofAnalysis:
2208 case kMixingAnalysis:
2213 //______________________________________________________________________________
2214 Bool_t AliAnalysisManager::ValidateOutputFiles() const
2216 // Validate all output files.
2217 TIter next(fOutputs);
2218 AliAnalysisDataContainer *output;
2219 TDirectory *cdir = gDirectory;
2220 TString openedFiles;
2221 while ((output=(AliAnalysisDataContainer*)next())) {
2222 if (output->IsRegisterDataset()) continue;
2223 TString filename = output->GetFileName();
2224 if (filename == "default") {
2225 if (!fOutputEventHandler) continue;
2226 filename = fOutputEventHandler->GetOutputFileName();
2227 // Main AOD may not be there
2228 if (gSystem->AccessPathName(filename)) continue;
2230 // Check if the file is closed
2231 if (openedFiles.Contains(filename)) continue;;
2232 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2234 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
2235 // Clear file list to release object ownership to user.
2239 file = TFile::Open(filename);
2240 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
2241 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
2246 openedFiles += filename;
2253 //______________________________________________________________________________
2254 void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
2256 // Implements a nice text mode progress bar.
2257 static Long64_t icount = 0;
2258 static TString oname;
2259 static TString nname;
2260 static Long64_t ocurrent = 0;
2261 static Long64_t osize = 0;
2262 static Int_t oseconds = 0;
2263 static TStopwatch *owatch = 0;
2264 static Bool_t oneoftwo = kFALSE;
2265 static Int_t nrefresh = 0;
2266 static Int_t nchecks = 0;
2267 static char lastChar = 0;
2268 const char symbol[4] = {'-','\\','|','/'};
2270 if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
2276 ocurrent = TMath::Abs(current);
2277 osize = TMath::Abs(size);
2278 if (ocurrent > osize) ocurrent=osize;
2283 if ((current % fPBUpdateFreq) != 0) return;
2285 char progress[11] = " ";
2286 Int_t ichar = icount%4;
2291 if (owatch && !last) {
2293 time = owatch->RealTime();
2294 seconds = int(time) % 60;
2295 minutes = (int(time) / 60) % 60;
2296 hours = (int(time) / 60 / 60);
2298 if (oseconds==seconds) {
2302 oneoftwo = !oneoftwo;
2306 if (refresh && oneoftwo) {
2308 if (nchecks <= 0) nchecks = nrefresh+1;
2309 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
2310 oname = Form(" == %d%% ==", pctdone);
2312 Double_t percent = 100.0*ocurrent/osize;
2313 Int_t nchar = Int_t(percent/10);
2314 if (nchar>10) nchar=10;
2316 for (i=0; i<nchar; i++) progress[i] = '=';
2317 progress[nchar] = symbol[ichar];
2318 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2319 progress[10] = '\0';
2322 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2323 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2324 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
2326 Int_t full = Int_t(ocurrent > 0 ?
2327 time * (float(osize)/ocurrent) + .5 :
2329 Int_t remain = Int_t(full - time);
2330 Int_t rsec = remain % 60;
2331 Int_t rmin = (remain / 60) % 60;
2332 Int_t rhour = (remain / 60 / 60);
2333 fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
2334 percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
2336 else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
2337 if (refresh && oneoftwo) oname = nname;
2338 if (owatch) owatch->Continue();
2347 fprintf(stderr, "\n");
2351 //______________________________________________________________________________
2352 void AliAnalysisManager::DoLoadBranch(const char *name)
2354 // Get tree and load branch if needed.
2355 static Long64_t crtEntry = -100;
2357 if (fAutoBranchHandling || !fTree)
2360 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2362 br = fTree->GetBranch(name);
2364 Error("DoLoadBranch", "Could not find branch %s",name);
2369 if (br->GetReadEntry()==fCurrentEntry) return;
2370 Int_t ret = br->GetEntry(GetCurrentEntry());
2372 Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
2373 if (crtEntry != fCurrentEntry) {
2374 CountEvent(1,0,1,0);
2375 crtEntry = fCurrentEntry;
2378 if (crtEntry != fCurrentEntry) {
2379 CountEvent(1,1,0,0);
2380 crtEntry = fCurrentEntry;
2385 //______________________________________________________________________________
2386 void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
2388 // Add the statistics task to the manager.
2390 Info("AddStatisticsTask", "Already added");
2393 TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
2394 gROOT->ProcessLine(line);
2397 //______________________________________________________________________________
2398 void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
2400 // Bookkeep current event;
2401 if (!fStatistics) return;
2402 fStatistics->AddInput(ninput);
2403 fStatistics->AddProcessed(nprocessed);
2404 fStatistics->AddFailed(nfailed);
2405 fStatistics->AddAccepted(naccepted);
2408 //______________________________________________________________________________
2409 void AliAnalysisManager::AddStatisticsMsg(const char *line)
2411 // Add a line in the statistics message. If available, the statistics message is written
2412 // at the end of the SlaveTerminate phase on workers AND at the end of Terminate
2414 if (!strlen(line)) return;
2415 if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
2416 fStatisticsMsg += line;
2419 //______________________________________________________________________________
2420 void AliAnalysisManager::WriteStatisticsMsg(Int_t)
2422 // If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
2423 static Bool_t done = kFALSE;
2426 if (!fStatistics) return;
2428 AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
2429 AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
2430 AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
2431 AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
2432 out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
2433 fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
2434 fStatistics->GetNaccepted()), ios::out);
2435 out << fStatisticsMsg << endl;
2439 //______________________________________________________________________________
2440 const char* AliAnalysisManager::GetOADBPath()
2442 // returns the path of the OADB
2443 // this static function just depends on environment variables
2445 static TString oadbPath;
2447 if (gSystem->Getenv("OADB_PATH"))
2448 oadbPath = gSystem->Getenv("OADB_PATH");
2449 else if (gSystem->Getenv("ALICE_ROOT"))
2450 oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
2452 ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
2457 //______________________________________________________________________________
2458 void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
2460 // Define a custom string variable mapped to a global unique name. The variable
2461 // can be then retrieved by a given analysis macro via GetGlobalStr(key).
2462 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2464 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2467 Bool_t valid = kFALSE;
2468 TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
2470 ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
2473 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
2476 //______________________________________________________________________________
2477 const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
2479 // Static method to retrieve a global variable defined via SetGlobalStr.
2481 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2483 TObject *value = mgr->GetGlobals()->GetValue(key);
2484 if (!value) return 0;
2486 return value->GetName();
2489 //______________________________________________________________________________
2490 void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
2492 // Define a custom integer variable mapped to a global unique name. The variable
2493 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2494 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2496 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2499 Bool_t valid = kFALSE;
2500 Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
2502 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
2505 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
2508 //______________________________________________________________________________
2509 Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
2511 // Static method to retrieve a global variable defined via SetGlobalInt.
2513 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2515 TObject *value = mgr->GetGlobals()->GetValue(key);
2516 if (!value) return 0;
2518 TString s = value->GetName();
2522 //______________________________________________________________________________
2523 void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
2525 // Define a custom double precision variable mapped to a global unique name. The variable
2526 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2527 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2529 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2532 Bool_t valid = kFALSE;
2533 Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
2535 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
2538 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));
2541 //______________________________________________________________________________
2542 Double_t AliAnalysisManager::GetGlobalDbl(const char *key, Bool_t &valid)
2544 // Static method to retrieve a global variable defined via SetGlobalDbl.
2546 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2548 TObject *value = mgr->GetGlobals()->GetValue(key);
2549 if (!value) return 0;
2551 TString s = value->GetName();