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>
36 #include <TTreeCache.h>
40 #include <TMethodCall.h>
45 #include <TStopwatch.h>
48 #include "AliAnalysisSelector.h"
49 #include "AliAnalysisGrid.h"
50 #include "AliAnalysisTask.h"
51 #include "AliAnalysisDataContainer.h"
52 #include "AliAnalysisDataSlot.h"
53 #include "AliVEventHandler.h"
54 #include "AliVEventPool.h"
55 #include "AliSysInfo.h"
56 #include "AliAnalysisStatistics.h"
62 ClassImp(AliAnalysisManager)
64 AliAnalysisManager *AliAnalysisManager::fgAnalysisManager = NULL;
65 TString AliAnalysisManager::fgCommonFileName = "";
66 TString AliAnalysisManager::fgMacroNames = "";
67 Int_t AliAnalysisManager::fPBUpdateFreq = 1;
69 //______________________________________________________________________________
70 AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
73 fInputEventHandler(0),
74 fOutputEventHandler(0),
75 fMCtruthEventHandler(0),
79 fMode(kLocalAnalysis),
85 fSpecialOutputLocation(""),
94 fFileDescriptors(new TObjArray()),
95 fCurrentDescriptor(0),
102 fAutoBranchHandling(kTRUE),
103 fAsyncReading(kTRUE), // default prefetching on
108 fCacheSize(100000000), // default 100 MB
110 fRequestedBranches(),
120 // Default constructor.
121 fgAnalysisManager = this;
122 fgCommonFileName = "AnalysisResults.root";
123 if (TClass::IsCallingNew() != TClass::kDummyNew) {
124 fTasks = new TObjArray();
125 fTopTasks = new TObjArray();
126 fZombies = new TObjArray();
127 fContainers = new TObjArray();
128 fInputs = new TObjArray();
129 fOutputs = new TObjArray();
130 fParamCont = new TObjArray();
131 fGlobals = new TMap();
133 fIOTimer = new TStopwatch();
134 fCPUTimer = new TStopwatch();
135 fInitTimer = new TStopwatch();
139 //______________________________________________________________________________
140 AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
143 fInputEventHandler(NULL),
144 fOutputEventHandler(NULL),
145 fMCtruthEventHandler(NULL),
150 fInitOK(other.fInitOK),
151 fMustClean(other.fMustClean),
152 fIsRemote(other.fIsRemote),
153 fLocked(other.fLocked),
154 fDebug(other.fDebug),
155 fSpecialOutputLocation(""),
164 fFileDescriptors(new TObjArray()),
165 fCurrentDescriptor(0),
170 fExtraFiles(other.fExtraFiles),
171 fFileInfoLog(other.fFileInfoLog),
172 fAutoBranchHandling(other.fAutoBranchHandling),
173 fAsyncReading(other.fAsyncReading),
176 fNcalls(other.fNcalls),
177 fMaxEntries(other.fMaxEntries),
178 fCacheSize(other.fCacheSize),
179 fStatisticsMsg(other.fStatisticsMsg),
180 fRequestedBranches(other.fRequestedBranches),
181 fStatistics(other.fStatistics),
182 fGlobals(other.fGlobals),
183 fIOTimer(new TStopwatch()),
184 fCPUTimer(new TStopwatch()),
185 fInitTimer(new TStopwatch()),
191 fTasks = new TObjArray(*other.fTasks);
192 fTopTasks = new TObjArray(*other.fTopTasks);
193 fZombies = new TObjArray(*other.fZombies);
194 fContainers = new TObjArray(*other.fContainers);
195 fInputs = new TObjArray(*other.fInputs);
196 fOutputs = new TObjArray(*other.fOutputs);
197 fParamCont = new TObjArray(*other.fParamCont);
198 fgCommonFileName = "AnalysisResults.root";
199 fgAnalysisManager = this;
202 //______________________________________________________________________________
203 AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& other)
206 if (&other != this) {
207 TNamed::operator=(other);
208 fInputEventHandler = other.fInputEventHandler;
209 fOutputEventHandler = other.fOutputEventHandler;
210 fMCtruthEventHandler = other.fMCtruthEventHandler;
211 fEventPool = other.fEventPool;
214 fNSysInfo = other.fNSysInfo;
216 fInitOK = other.fInitOK;
217 fIsRemote = other.fIsRemote;
218 fLocked = other.fLocked;
219 fDebug = other.fDebug;
220 fTasks = new TObjArray(*other.fTasks);
221 fTopTasks = new TObjArray(*other.fTopTasks);
222 fZombies = new TObjArray(*other.fZombies);
223 fContainers = new TObjArray(*other.fContainers);
224 fInputs = new TObjArray(*other.fInputs);
225 fOutputs = new TObjArray(*other.fOutputs);
226 fParamCont = new TObjArray(*other.fParamCont);
227 fDebugOptions = NULL;
228 fFileDescriptors = new TObjArray();
229 fCurrentDescriptor = 0;
231 fCommonOutput = NULL;
234 fExtraFiles = other.fExtraFiles;
235 fFileInfoLog = other.fFileInfoLog;
236 fgCommonFileName = "AnalysisResults.root";
237 fgAnalysisManager = this;
238 fAutoBranchHandling = other.fAutoBranchHandling;
239 fAsyncReading = other.fAsyncReading;
240 fTable.Clear("nodelete");
241 fRunFromPath = other.fRunFromPath;
242 fNcalls = other. fNcalls;
243 fMaxEntries = other.fMaxEntries;
244 fCacheSize = other.fCacheSize;
245 fStatisticsMsg = other.fStatisticsMsg;
246 fRequestedBranches = other.fRequestedBranches;
247 fStatistics = other.fStatistics;
248 fGlobals = new TMap();
249 fIOTimer = new TStopwatch();
250 fCPUTimer = new TStopwatch();
251 fInitTimer = new TStopwatch();
259 //______________________________________________________________________________
260 AliAnalysisManager::~AliAnalysisManager()
263 if (fTasks) {fTasks->Delete(); delete fTasks;}
264 if (fTopTasks) delete fTopTasks;
265 if (fZombies) delete fZombies;
266 if (fContainers) {fContainers->Delete(); delete fContainers;}
267 if (fInputs) delete fInputs;
268 if (fOutputs) delete fOutputs;
269 if (fParamCont) delete fParamCont;
270 if (fDebugOptions) delete fDebugOptions;
271 if (fGridHandler) delete fGridHandler;
272 if (fInputEventHandler) delete fInputEventHandler;
273 if (fOutputEventHandler) delete fOutputEventHandler;
274 if (fMCtruthEventHandler) delete fMCtruthEventHandler;
275 if (fEventPool) delete fEventPool;
276 if (fgAnalysisManager==this) fgAnalysisManager = NULL;
277 if (fGlobals) {fGlobals->DeleteAll(); delete fGlobals;}
278 if (fFileDescriptors) {fFileDescriptors->Delete(); delete fFileDescriptors;}
284 //______________________________________________________________________________
285 void AliAnalysisManager::CreateReadCache()
287 // Create cache for reading according fCacheSize and fAsyncReading.
288 if (!fTree || !fTree->GetCurrentFile()) {
289 Error("CreateReadCache","Current tree or tree file not yet defined");
293 if (fDebug) Info("CreateReadCache","=== Read caching disabled ===");
296 // gEnv->SetValue("TFile.AsyncPrefetching",(Int_t)fAsyncReading);
297 // if (fAsyncReading) gEnv->SetValue("Cache.Directory",Form("file://%s/cache", gSystem->WorkingDirectory()));
298 // if (fAsyncReading) gEnv->SetValue("TFile.AsyncReading",1);
299 fTree->SetCacheSize(fCacheSize);
300 TTreeCache::SetLearnEntries(1); //<<< we can take the decision after 1 entry
301 fTree->AddBranchToCache("*",kTRUE); //<<< add all branches to the cache
303 Info("CreateReadCache","Read cache enabled %lld bytes with async reading=%d",fCacheSize, (Int_t)fAsyncReading);
308 //______________________________________________________________________________
309 Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
311 // Read one entry of the tree or a whole branch.
312 fCurrentEntry = entry;
313 if (!fAutoBranchHandling)
315 if (!fTree || !fTree->GetTree()) return -1;
316 fIOTimer->Start(kTRUE);
317 Long64_t readbytes = fTree->GetTree()->GetEntry(entry, getall);
319 fIOTime += fIOTimer->RealTime();
320 return (Int_t)readbytes;
323 //______________________________________________________________________________
324 Int_t AliAnalysisManager::GetRunFromAlienPath(const char *path)
326 // Attempt to extract run number from input data path. Works only for paths to
327 // alice data in alien.
328 // sim: /alice/sim/<production>/run_no/...
329 // data: /alice/data/year/period/000run_no/... (ESD or AOD)
330 TString type = "unknown";
332 if (s.Contains("/alice/data")) type = "real";
333 else if (s.Contains("/alice/sim")) type = "simulated";
336 ind1 = s.Index("/00");
338 ind2 = s.Index("/",ind1+1);
339 if (ind2-ind1>8) srun = s(ind1+1, ind2-ind1-1);
342 ind1 = s.Index("/LHC");
344 ind1 = s.Index("/",ind1+1);
346 ind2 = s.Index("/",ind1+1);
347 if (ind2>0) srun = s(ind1+1, ind2-ind1-1);
351 Int_t run = srun.Atoi();
352 if (run>0) printf("=== GetRunFromAlienPath: run %d of %s data ===\n", run, type.Data());
356 //______________________________________________________________________________
357 Bool_t AliAnalysisManager::Init(TTree *tree)
359 // The Init() function is called when the selector needs to initialize
360 // a new tree or chain. Typically here the branch addresses of the tree
361 // will be set. It is normaly not necessary to make changes to the
362 // generated code, but the routine can be extended by the user if needed.
363 // Init() will be called many times when running with PROOF.
364 Bool_t init = kFALSE;
365 if (!tree) return kFALSE; // Should not happen - protected in selector caller
367 printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
369 // Call InitTree of EventHandler
370 if (fOutputEventHandler) {
371 if (fMode == kProofAnalysis) {
372 init = fOutputEventHandler->Init(0x0, "proof");
374 init = fOutputEventHandler->Init(0x0, "local");
377 Error("Init", "Output event handler failed to initialize");
382 if (fInputEventHandler) {
383 if (fMode == kProofAnalysis) {
384 init = fInputEventHandler->Init(tree, "proof");
386 init = fInputEventHandler->Init(tree, "local");
389 Error("Init", "Input event handler failed to initialize tree");
393 // If no input event handler we need to get the tree once
395 if(!tree->GetTree()) {
396 Long64_t readEntry = tree->LoadTree(0);
397 if (readEntry == -2) {
398 Error("Init", "Input tree has no entry. Exiting");
404 if (fMCtruthEventHandler) {
405 if (fMode == kProofAnalysis) {
406 init = fMCtruthEventHandler->Init(0x0, "proof");
408 init = fMCtruthEventHandler->Init(0x0, "local");
411 Error("Init", "MC event handler failed to initialize");
416 if (!fInitOK) InitAnalysis();
417 if (!fInitOK) return kFALSE;
419 if (fMode != kProofAnalysis) CreateReadCache();
421 AliAnalysisDataContainer *top = fCommonInput;
422 if (!top) top = (AliAnalysisDataContainer*)fInputs->At(0);
424 Error("Init","No top input container !");
428 CheckBranches(kFALSE);
430 printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
435 //______________________________________________________________________________
436 void AliAnalysisManager::SlaveBegin(TTree *tree)
438 // The SlaveBegin() function is called after the Begin() function.
439 // When running with PROOF SlaveBegin() is called on each slave server.
440 // The tree argument is deprecated (on PROOF 0 is passed).
441 if (fDebug > 1) printf("->AliAnalysisManager::SlaveBegin()\n");
442 // Init timer should be already started
443 // Apply debug options
446 fMCtruthEventHandler &&
447 (fMode != kProofAnalysis)) fMCtruthEventHandler->SetCacheSize(fCacheSize);
448 if (!CheckTasks()) Fatal("SlaveBegin", "Not all needed libraries were loaded");
449 static Bool_t isCalled = kFALSE;
450 Bool_t init = kFALSE;
451 Bool_t initOK = kTRUE;
453 TDirectory *curdir = gDirectory;
454 // Call SlaveBegin only once in case of mixing
455 if (isCalled && fMode==kMixingAnalysis) return;
457 // Call Init of EventHandler
458 if (fOutputEventHandler) {
459 if (fMode == kProofAnalysis) {
460 // Merging AOD's in PROOF via TProofOutputFile
461 if (fDebug > 1) printf(" Initializing AOD output file %s...\n", fOutputEventHandler->GetOutputFileName());
462 init = fOutputEventHandler->Init("proof");
463 if (!init) msg = "Failed to initialize output handler on worker";
465 init = fOutputEventHandler->Init("local");
466 if (!init) msg = "Failed to initialize output handler";
469 if (!fSelector) Error("SlaveBegin", "Selector not set");
470 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
473 if (fInputEventHandler) {
474 fInputEventHandler->SetInputTree(tree);
475 if (fMode == kProofAnalysis) {
476 init = fInputEventHandler->Init("proof");
477 if (!init) msg = "Failed to initialize input handler on worker";
479 init = fInputEventHandler->Init("local");
480 if (!init) msg = "Failed to initialize input handler";
483 if (!fSelector) Error("SlaveBegin", "Selector not set");
484 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
487 if (fMCtruthEventHandler) {
488 if (fMode == kProofAnalysis) {
489 init = fMCtruthEventHandler->Init("proof");
490 if (!init) msg = "Failed to initialize MC handler on worker";
492 init = fMCtruthEventHandler->Init("local");
493 if (!init) msg = "Failed to initialize MC handler";
496 if (!fSelector) Error("SlaveBegin", "Selector not set");
497 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
499 if (curdir) curdir->cd();
503 AliAnalysisTask *task;
504 // Call CreateOutputObjects for all tasks
505 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
506 Bool_t dirStatus = TH1::AddDirectoryStatus();
508 while ((task=(AliAnalysisTask*)next())) {
510 // Start with memory as current dir and make sure by default histograms do not get attached to files.
511 TH1::AddDirectory(kFALSE);
512 task->CreateOutputObjects();
513 if (!task->CheckPostData()) {
514 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
515 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
516 ####### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ##########", task->GetName(), task->ClassName());
518 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
521 TH1::AddDirectory(dirStatus);
522 if (curdir) curdir->cd();
524 fInitTime += fInitTimer->RealTime();
525 fInitTimer->Continue();
526 printf("Initialization time: %g [sec]\n", fInitTime);
527 if (fDebug > 1) printf("<-AliAnalysisManager::SlaveBegin()\n");
530 //______________________________________________________________________________
531 Bool_t AliAnalysisManager::Notify()
533 // The Notify() function is called when a new file is opened. This
534 // can be either for a new TTree in a TChain or when when a new TTree
535 // is started when using PROOF. It is normaly not necessary to make changes
536 // to the generated code, but the routine can be extended by the
537 // user if needed. The return value is currently not used.
538 fIOTimer->Start(kTRUE);
539 if (!fTree) return kFALSE;
540 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) return kFALSE;
542 fTable.Clear("nodelete"); // clearing the hash table may not be needed -> C.L.
543 if (fMode == kProofAnalysis) fIsRemote = kTRUE;
545 TFile *curfile = fTree->GetCurrentFile();
547 Error("Notify","No current file");
550 if (IsCollectThroughput()) {
551 if (fCurrentDescriptor) fCurrentDescriptor->Done();
552 fCurrentDescriptor = new AliAnalysisFileDescriptor(curfile);
553 fFileDescriptors->Add(fCurrentDescriptor);
556 if (fDebug > 1) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
557 Int_t run = AliAnalysisManager::GetRunFromAlienPath(curfile->GetName());
558 if (run && (run != fRunFromPath)) {
560 if (fDebug > 1) printf(" ### run found from path: %d\n", run);
563 AliAnalysisTask *task;
565 // Call Notify of the event handlers
566 if (fInputEventHandler) {
567 fInputEventHandler->Notify(curfile->GetName());
570 if (fOutputEventHandler) {
571 fOutputEventHandler->Notify(curfile->GetName());
574 if (fMCtruthEventHandler) {
575 fMCtruthEventHandler->Notify(curfile->GetName());
578 // Call Notify for all tasks
579 while ((task=(AliAnalysisTask*)next()))
582 if (fDebug > 1) printf("<-AliAnalysisManager::Notify()\n");
584 fIOTime += fIOTimer->RealTime();
588 //______________________________________________________________________________
589 Bool_t AliAnalysisManager::Process(Long64_t)
591 // The Process() function is called for each entry in the tree (or possibly
592 // keyed object in the case of PROOF) to be processed. The entry argument
593 // specifies which entry in the currently loaded tree is to be processed.
594 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
595 // to read either all or the required parts of the data. When processing
596 // keyed objects with PROOF, the object is already loaded and is available
597 // via the fObject pointer.
599 // This function should contain the "body" of the analysis. It can contain
600 // simple or elaborate selection criteria, run algorithms on the data
601 // of the event and typically fill histograms.
603 // WARNING when a selector is used with a TChain, you must use
604 // the pointer to the current TTree to call GetEntry(entry).
605 // The entry is always the local entry number in the current tree.
606 // Assuming that fChain is the pointer to the TChain being processed,
607 // use fChain->GetTree()->GetEntry(entry).
609 // This method is obsolete. ExecAnalysis is called instead.
613 //______________________________________________________________________________
614 void AliAnalysisManager::PackOutput(TList *target)
616 // Pack all output data containers in the output list. Called at SlaveTerminate
617 // stage in PROOF case for each slave.
618 if (fDebug > 1) printf("->AliAnalysisManager::PackOutput()\n");
619 fIOTimer->Start(kTRUE);
621 if (IsCollectThroughput()) {
622 if (fCurrentDescriptor) fCurrentDescriptor->Done();
623 fFileDescriptors->Print();
624 if (fFileInfoLog.IsNull()) fFileInfoLog = "fileinfo.log";
625 out.open(fFileInfoLog, std::ios::app);
626 if (out.bad()) Error("SavePrimitive", "Bad file name: %s", fFileInfoLog.Data());
628 TIter nextflog(fFileDescriptors);
630 while ((log=nextflog())) log->SavePrimitive(out,"");
634 Error("PackOutput", "No target. Exiting.");
637 TDirectory *cdir = gDirectory;
639 if (fInputEventHandler) fInputEventHandler ->Terminate();
640 if (fOutputEventHandler) fOutputEventHandler ->Terminate();
641 if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
644 // Call FinishTaskOutput() for each event loop task (not called for
645 // post-event loop tasks - use Terminate() fo those)
646 TIter nexttask(fTasks);
647 AliAnalysisTask *task;
648 while ((task=(AliAnalysisTask*)nexttask())) {
649 if (!task->IsPostEventLoop()) {
650 if (fDebug > 1) printf("->FinishTaskOutput: task %s\n", task->GetName());
651 task->FinishTaskOutput();
653 if (fDebug > 1) printf("<-FinishTaskOutput: task %s\n", task->GetName());
656 // Write statistics message on the workers.
657 if (fStatistics) WriteStatisticsMsg(fNcalls);
659 if (fMode == kProofAnalysis) {
660 TIter next(fOutputs);
661 AliAnalysisDataContainer *output;
662 Bool_t isManagedByHandler = kFALSE;
665 while ((output=(AliAnalysisDataContainer*)next())) {
666 // Do not consider outputs of post event loop tasks
667 isManagedByHandler = kFALSE;
668 if (output->GetProducer() && output->GetProducer()->IsPostEventLoop()) continue;
669 const char *filename = output->GetFileName();
670 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
671 isManagedByHandler = kTRUE;
672 printf("#### Handler output. Extra: %s\n", fExtraFiles.Data());
673 filename = fOutputEventHandler->GetOutputFileName();
675 // Check if data was posted to this container. If not, issue an error.
676 if (!output->GetData() && !isManagedByHandler) {
677 Error("PackOutput", "No data for output container %s. Forgot to PostData ?", output->GetName());
680 if (!output->IsSpecialOutput()) {
682 if (strlen(filename) && !isManagedByHandler) {
683 // Backup current folder
684 TDirectory *opwd = gDirectory;
685 // File resident outputs.
686 // Check first if the file exists.
687 TString openoption = "RECREATE";
688 Bool_t firsttime = kTRUE;
689 if (filestmp.FindObject(output->GetFileName())) {
692 filestmp.Add(new TNamed(output->GetFileName(),""));
694 if (!gSystem->AccessPathName(output->GetFileName()) && !firsttime) openoption = "UPDATE";
695 // TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
696 // Save data to file, then close.
697 if (output->GetData()->InheritsFrom(TCollection::Class())) {
698 // If data is a collection, we set the name of the collection
699 // as the one of the container and we save as a single key.
700 TCollection *coll = (TCollection*)output->GetData();
701 coll->SetName(output->GetName());
702 // coll->Write(output->GetName(), TObject::kSingleKey);
704 if (output->GetData()->InheritsFrom(TTree::Class())) {
705 TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
706 // Save data to file, then close.
707 TTree *tree = (TTree*)output->GetData();
708 // Check if tree is in memory
709 if (tree->GetDirectory()==gROOT) tree->SetDirectory(gDirectory);
713 // output->GetData()->Write();
716 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
718 // printf(" file %s listing content:\n", filename);
721 // Clear file list to release object ownership to user.
724 output->SetFile(NULL);
725 // Restore current directory
726 if (opwd) opwd->cd();
728 // Memory-resident outputs
729 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
731 AliAnalysisDataWrapper *wrap = 0;
732 if (isManagedByHandler) {
733 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
734 wrap->SetName(output->GetName());
736 else wrap =output->ExportData();
737 // Output wrappers must NOT delete data after merging - the user owns them
738 wrap->SetDeleteData(kFALSE);
741 // Special outputs. The file must be opened and connected to the container.
742 TDirectory *opwd = gDirectory;
743 TFile *file = output->GetFile();
745 AliAnalysisTask *producer = output->GetProducer();
747 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
748 output->GetFileName(), output->GetName(), producer->ClassName());
751 TString outFilename = file->GetName();
752 if (fDebug > 1) printf("PackOutput %s: special output\n", output->GetName());
753 if (isManagedByHandler) {
754 // Terminate IO for files managed by the output handler
755 // file->Write() moved to AOD handler (A.G. 11.01.10)
756 // if (file) file->Write();
757 if (file && fDebug > 2) {
758 printf(" handled file %s listing content:\n", file->GetName());
761 fOutputEventHandler->TerminateIO();
764 // Release object ownership to users after writing data to file
765 if (output->GetData()->InheritsFrom(TCollection::Class())) {
766 // If data is a collection, we set the name of the collection
767 // as the one of the container and we save as a single key.
768 TCollection *coll = (TCollection*)output->GetData();
769 coll->SetName(output->GetName());
770 coll->Write(output->GetName(), TObject::kSingleKey);
772 if (output->GetData()->InheritsFrom(TTree::Class())) {
773 TTree *tree = (TTree*)output->GetData();
774 tree->SetDirectory(file);
777 output->GetData()->Write();
781 printf(" file %s listing content:\n", output->GetFileName());
784 // Clear file list to release object ownership to user.
787 output->SetFile(NULL);
789 // Restore current directory
790 if (opwd) opwd->cd();
791 // Check if a special output location was provided or the output files have to be merged
792 if (strlen(fSpecialOutputLocation.Data())) {
793 TString remote = fSpecialOutputLocation;
795 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
796 if (remote.BeginsWith("alien:")) {
797 gROOT->ProcessLine("TGrid::Connect(\"alien:\", gProofServ->GetUser());");
798 remote += outFilename;
799 remote.ReplaceAll(".root", Form("_%d.root", gid));
801 remote += Form("%s_%d_", gSystem->HostName(), gid);
802 remote += outFilename;
805 Info("PackOutput", "Output file for container %s to be copied \n at: %s. No merging.",
806 output->GetName(), remote.Data());
807 TFile::Cp ( outFilename.Data(), remote.Data() );
808 // Copy extra outputs
809 if (fExtraFiles.Length() && isManagedByHandler) {
810 TObjArray *arr = fExtraFiles.Tokenize(" ");
812 TIter nextfilename(arr);
813 while ((os=(TObjString*)nextfilename())) {
814 outFilename = os->GetString();
815 remote = fSpecialOutputLocation;
817 if (remote.BeginsWith("alien://")) {
818 remote += outFilename;
819 remote.ReplaceAll(".root", Form("_%d.root", gid));
821 remote += Form("%s_%d_", gSystem->HostName(), gid);
822 remote += outFilename;
825 Info("PackOutput", "Extra AOD file %s to be copied \n at: %s. No merging.",
826 outFilename.Data(), remote.Data());
827 TFile::Cp ( outFilename.Data(), remote.Data() );
832 // No special location specified-> use TProofOutputFile as merging utility
833 // The file at this output slot must be opened in CreateOutputObjects
834 if (fDebug > 1) printf(" File for container %s to be merged via file merger...\n", output->GetName());
839 fIOTime += fIOTimer->RealTime();
840 if ((fDebug || IsCollectThroughput())) {
842 fInitTime = fInitTimer->RealTime()-fIOTime-fCPUTime;
843 printf("=Analysis %s= init time: %g[sec]\
844 \n I/O & data mng.: %g [sec]\
845 \n task execution: %g [sec]\
846 \n total time: CPU=%g [sec] REAL=%g[sec]\n",
847 GetName(), fInitTime, fIOTime, fCPUTime, fInitTimer->CpuTime(), fInitTimer->RealTime());
848 if (IsCollectThroughput()) {
849 out << "#summary#########################################################" << endl;
850 out << "train_name " << GetName() << endl;
851 out << "root_time " << fInitTimer->RealTime() << endl;
852 out << "root_cpu " << fInitTimer->CpuTime() << endl;
853 out << "init_time " << fInitTime << endl;
854 out << "io_mng_time " << fIOTime << endl;
855 out << "exec_time " << fCPUTime << endl;
856 TString aliensite = gSystem->Getenv("ALIEN_SITE");
857 out << "alien_site " << aliensite << endl;
859 TString hostname = gSystem->Getenv("ALIEN_HOSTNAME");
860 if (hostname.IsNull()) {
862 gSystem->Exec(Form("hostname -f >> %s", fFileInfoLog.Data()));
864 out << hostname << endl;
869 if (cdir) cdir->cd();
870 if (fDebug > 1) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
873 //______________________________________________________________________________
874 void AliAnalysisManager::ImportWrappers(TList *source)
876 // Import data in output containers from wrappers coming in source.
877 if (fDebug > 1) printf("->AliAnalysisManager::ImportWrappers()\n");
878 fIOTimer->Start(kTRUE);
879 TIter next(fOutputs);
880 AliAnalysisDataContainer *cont;
881 AliAnalysisDataWrapper *wrap;
883 Bool_t inGrid = (fMode == kGridAnalysis)?kTRUE:kFALSE;
884 TDirectory *cdir = gDirectory;
885 while ((cont=(AliAnalysisDataContainer*)next())) {
887 if (cont->GetProducer() && cont->GetProducer()->IsPostEventLoop() && !inGrid) continue;
888 if (cont->IsRegisterDataset()) continue;
889 const char *filename = cont->GetFileName();
890 Bool_t isManagedByHandler = kFALSE;
891 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
892 isManagedByHandler = kTRUE;
893 filename = fOutputEventHandler->GetOutputFileName();
895 if (cont->IsSpecialOutput() || inGrid) {
896 if (strlen(fSpecialOutputLocation.Data())) continue;
897 // Copy merged file from PROOF scratch space.
898 // In case of grid the files are already in the current directory.
900 if (isManagedByHandler && fExtraFiles.Length()) {
901 // Copy extra registered dAOD files.
902 TObjArray *arr = fExtraFiles.Tokenize(" ");
904 TIter nextfilename(arr);
905 while ((os=(TObjString*)nextfilename())) GetFileFromWrapper(os->GetString(), source);
908 if (!GetFileFromWrapper(filename, source)) continue;
910 // Normally we should connect data from the copied file to the
911 // corresponding output container, but it is not obvious how to do this
912 // automatically if several objects in file...
913 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
914 if (!f) f = TFile::Open(filename, "READ");
916 Error("ImportWrappers", "Cannot open file %s in read-only mode", filename);
921 // Cd to the directory pointed by the container
922 TString folder = cont->GetFolderName();
923 if (!folder.IsNull()) f->cd(folder);
924 // Try to fetch first an object having the container name.
925 obj = gDirectory->Get(cont->GetName());
927 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",
928 cont->GetType()->GetName(), cont->GetName(), filename, cont->GetFolderName(), cont->GetName());
931 wrap = new AliAnalysisDataWrapper(obj);
932 wrap->SetDeleteData(kFALSE);
934 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
936 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
941 printf(" Importing data for container %s\n", cont->GetName());
942 if (strlen(filename)) printf(" -> file %s\n", filename);
945 cont->ImportData(wrap);
947 if (cdir) cdir->cd();
949 fIOTime += fIOTimer->RealTime();
950 if (fDebug > 1) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
953 //______________________________________________________________________________
954 void AliAnalysisManager::UnpackOutput(TList *source)
956 // Called by AliAnalysisSelector::Terminate only on the client.
957 fIOTimer->Start(kTRUE);
958 if (fDebug > 1) printf("->AliAnalysisManager::UnpackOutput()\n");
960 Error("UnpackOutput", "No target. Exiting.");
963 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
965 if (fMode == kProofAnalysis) ImportWrappers(source);
967 TIter next(fOutputs);
968 AliAnalysisDataContainer *output;
969 while ((output=(AliAnalysisDataContainer*)next())) {
970 if (!output->GetData()) continue;
971 // Check if there are client tasks that run post event loop
972 if (output->HasConsumers()) {
973 // Disable event loop semaphore
974 output->SetPostEventLoop(kTRUE);
975 TObjArray *list = output->GetConsumers();
976 Int_t ncons = list->GetEntriesFast();
977 for (Int_t i=0; i<ncons; i++) {
978 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
979 task->CheckNotify(kTRUE);
980 // If task is active, execute it
981 if (task->IsPostEventLoop() && task->IsActive()) {
982 if (fDebug > 1) printf("== Executing post event loop task %s\n", task->GetName());
983 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
987 if (fStatistics) fStatistics->StopTimer();
991 fIOTime += fIOTimer->RealTime();
992 if (fDebug > 1) printf("<-AliAnalysisManager::UnpackOutput()\n");
995 //______________________________________________________________________________
996 void AliAnalysisManager::Terminate()
998 // The Terminate() function is the last function to be called during
999 // a query. It always runs on the client, it can be used to present
1000 // the results graphically.
1001 if (fDebug > 1) printf("->AliAnalysisManager::Terminate()\n");
1002 fInitTimer->Start(kTRUE);
1003 TDirectory *cdir = gDirectory;
1005 AliAnalysisTask *task;
1006 AliAnalysisDataContainer *output;
1009 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1010 // Call Terminate() for tasks
1012 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
1013 // Save all the canvases produced by the Terminate
1014 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
1018 AliSysInfo::AddStamp(Form("%s_TERMINATE",task->ClassName()),0, itask, 2);
1020 if (TObject::TestBit(kSaveCanvases)) {
1021 if (!gROOT->IsBatch()) {
1022 if (fDebug>1) printf("Waiting 5 sec for %s::Terminate() to finish drawing ...\n", task->ClassName());
1024 while (timer.RealTime()<5) {
1026 gSystem->ProcessEvents();
1029 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
1030 if (iend==0) continue;
1032 for (Int_t ipict=0; ipict<iend; ipict++) {
1033 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
1034 if (!canvas) continue;
1035 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
1037 gROOT->GetListOfCanvases()->Delete();
1041 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
1042 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
1043 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
1045 TObjArray *allOutputs = new TObjArray();
1047 for (icont=0; icont<fOutputs->GetEntriesFast(); icont++) allOutputs->Add(fOutputs->At(icont));
1048 if (!IsSkipTerminate())
1049 for (icont=0; icont<fParamCont->GetEntriesFast(); icont++) allOutputs->Add(fParamCont->At(icont));
1050 TIter next1(allOutputs);
1051 TString handlerFile = "";
1052 TString extraOutputs = "";
1053 if (fOutputEventHandler) {
1054 handlerFile = fOutputEventHandler->GetOutputFileName();
1055 extraOutputs = fOutputEventHandler->GetExtraOutputs();
1059 while ((output=(AliAnalysisDataContainer*)next1())) {
1060 // Special outputs or grid files have the files already closed and written.
1062 if (fMode == kGridAnalysis && icont<=fOutputs->GetEntriesFast()) continue;
1063 if (fMode == kProofAnalysis) {
1064 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
1066 const char *filename = output->GetFileName();
1067 TString openoption = "RECREATE";
1068 if (!(strcmp(filename, "default"))) continue;
1069 if (!strlen(filename)) continue;
1070 if (!output->GetData()) continue;
1071 TDirectory *opwd = gDirectory;
1072 TFile *file = output->GetFile();
1073 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1075 //if (handlerFile == filename && !gSystem->AccessPathName(filename)) openoption = "UPDATE";
1076 Bool_t firsttime = kTRUE;
1077 if (filestmp.FindObject(filename) || extraOutputs.Contains(filename)) {
1080 filestmp.Add(new TNamed(filename,""));
1082 if (!gSystem->AccessPathName(filename) && !firsttime) openoption = "UPDATE";
1083 if (fDebug>1) printf("Opening file: %s option=%s\n",filename, openoption.Data());
1084 file = new TFile(filename, openoption);
1086 if (fDebug>1) printf("File <%s> already opened with option: <%s> \n", filename, file->GetOption());
1087 openoption = file->GetOption();
1088 if (openoption == "READ") {
1089 if (fDebug>1) printf("...reopening in UPDATE mode\n");
1090 file->ReOpen("UPDATE");
1093 if (file->IsZombie()) {
1094 Error("Terminate", "Cannot open output file %s", filename);
1097 output->SetFile(file);
1099 // Check for a folder request
1100 TString dir = output->GetFolderName();
1101 if (!dir.IsNull()) {
1102 if (!file->GetDirectory(dir)) file->mkdir(dir);
1105 if (fDebug > 1) printf("...writing container %s to file %s:%s\n", output->GetName(), file->GetName(), output->GetFolderName());
1106 if (output->GetData()->InheritsFrom(TCollection::Class())) {
1107 // If data is a collection, we set the name of the collection
1108 // as the one of the container and we save as a single key.
1109 TCollection *coll = (TCollection*)output->GetData();
1110 coll->SetName(output->GetName());
1111 coll->Write(output->GetName(), TObject::kSingleKey);
1113 if (output->GetData()->InheritsFrom(TTree::Class())) {
1114 TTree *tree = (TTree*)output->GetData();
1115 tree->SetDirectory(gDirectory);
1118 output->GetData()->Write();
1121 if (opwd) opwd->cd();
1125 TString copiedFiles;
1126 while ((output=(AliAnalysisDataContainer*)next1())) {
1127 // Close all files at output
1128 TDirectory *opwd = gDirectory;
1129 if (output->GetFile()) {
1130 // Clear file list to release object ownership to user.
1131 // output->GetFile()->Clear();
1132 output->GetFile()->Close();
1133 // Copy merged outputs in alien if requested
1134 if (fSpecialOutputLocation.BeginsWith("alien://")) {
1135 if (copiedFiles.Contains(output->GetFile()->GetName())) {
1136 if (opwd) opwd->cd();
1137 output->SetFile(NULL);
1140 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
1141 gROOT->ProcessLine("if (!gGrid) TGrid::Connect(\"alien:\");");
1142 TFile::Cp(output->GetFile()->GetName(),
1143 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
1144 copiedFiles += output->GetFile()->GetName();
1146 output->SetFile(NULL);
1148 if (opwd) opwd->cd();
1151 //Write statistics information on the client
1152 if (fStatistics) WriteStatisticsMsg(fNcalls);
1154 TDirectory *crtdir = gDirectory;
1155 TFile f("syswatch.root", "RECREATE");
1158 if (!f.IsZombie()) {
1159 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
1160 tree->SetName("syswatch");
1161 tree->SetMarkerStyle(kCircle);
1162 tree->SetMarkerColor(kBlue);
1163 tree->SetMarkerSize(0.5);
1164 if (!gROOT->IsBatch()) {
1165 tree->SetAlias("event", "id0");
1166 tree->SetAlias("task", "id1");
1167 tree->SetAlias("stage", "id2");
1168 // Already defined aliases
1169 // tree->SetAlias("deltaT","stampSec-stampOldSec");
1170 // tree->SetAlias("T","stampSec-first");
1171 // tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)");
1172 // tree->SetAlias("VM","pI.fMemVirtual");
1173 TCanvas *canvas = new TCanvas("SysInfo","SysInfo",10,10,1200,800);
1174 Int_t npads = 1 /*COO plot for all tasks*/ +
1175 fTopTasks->GetEntries() /*Exec plot per task*/ +
1176 1 /*Terminate plot for all tasks*/ +
1179 Int_t iopt = (Int_t)TMath::Sqrt((Double_t)npads);
1180 if (npads<iopt*(iopt+1))
1181 canvas->Divide(iopt, iopt+1, 0.01, 0.01);
1183 canvas->Divide(iopt+1, iopt+1, 0.01, 0.01);
1185 // draw the plot of deltaVM for Exec for each task
1186 for (itask=0; itask<fTopTasks->GetEntriesFast(); itask++) {
1187 task = (AliAnalysisTask*)fTopTasks->At(itask);
1189 cut = Form("task==%d && stage==1", itask);
1190 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1191 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1193 hist->SetTitle(Form("%s: Exec dVM[MB]/event", task->GetName()));
1194 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1197 // Draw the plot of deltaVM for CreateOutputObjects for all tasks
1199 tree->SetMarkerStyle(kFullTriangleUp);
1200 tree->SetMarkerColor(kRed);
1201 tree->SetMarkerSize(0.8);
1202 cut = "task>=0 && task<1000 && stage==0";
1203 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1204 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1206 hist->SetTitle("Memory in CreateOutputObjects()");
1207 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1208 hist->GetXaxis()->SetTitle("task");
1210 // draw the plot of deltaVM for Terminate for all tasks
1212 tree->SetMarkerStyle(kOpenSquare);
1213 tree->SetMarkerColor(kMagenta);
1214 cut = "task>=0 && task<1000 && stage==2";
1215 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1216 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1218 hist->SetTitle("Memory in Terminate()");
1219 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1220 hist->GetXaxis()->SetTitle("task");
1224 tree->SetMarkerStyle(kFullCircle);
1225 tree->SetMarkerColor(kGreen);
1226 cut = Form("task==%d && stage==1",fTopTasks->GetEntriesFast()-1);
1227 tree->Draw("VM:event",cut,"", 1234567890, 0);
1228 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1230 hist->SetTitle("Virtual memory");
1231 hist->GetYaxis()->SetTitle("VM [MB]");
1235 tree->SetMarkerStyle(kCircle);
1236 tree->SetMarkerColor(kBlue);
1237 tree->SetMarkerSize(0.5);
1242 if (crtdir) crtdir->cd();
1244 // Validate the output files
1245 if (ValidateOutputFiles() && fIsRemote && fMode!=kProofAnalysis) {
1247 out.open("outputs_valid", ios::out);
1250 if (cdir) cdir->cd();
1252 if (fDebug || IsCollectThroughput()) {
1253 printf("=Analysis %s= Terminate time: %g[sec]\n", GetName(), fInitTimer->RealTime());
1255 if (fDebug > 1) printf("<-AliAnalysisManager::Terminate()\n");
1257 //______________________________________________________________________________
1258 void AliAnalysisManager::ProfileTask(Int_t itop, const char *option) const
1260 // Profiles the task having the itop index in the list of top (first level) tasks.
1261 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->At(itop);
1263 Error("ProfileTask", "There are only %d top tasks in the manager", fTopTasks->GetEntries());
1266 ProfileTask(task->GetName(), option);
1269 //______________________________________________________________________________
1270 void AliAnalysisManager::ProfileTask(const char *name, const char */*option*/) const
1272 // Profile a managed task after the execution of the analysis in case NSysInfo
1274 if (gSystem->AccessPathName("syswatch.root")) {
1275 Error("ProfileTask", "No file syswatch.root found in the current directory");
1278 if (gROOT->IsBatch()) return;
1279 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->FindObject(name);
1281 Error("ProfileTask", "No top task named %s known by the manager.", name);
1284 Int_t itop = fTopTasks->IndexOf(task);
1285 Int_t itask = fTasks->IndexOf(task);
1286 // Create canvas with 2 pads: first draw COO + Terminate, second Exec
1287 TDirectory *cdir = gDirectory;
1288 TFile f("syswatch.root");
1289 TTree *tree = (TTree*)f.Get("syswatch");
1291 Error("ProfileTask", "No tree named <syswatch> found in file syswatch.root");
1294 if (fDebug > 1) printf("=== Profiling task %s (class %s)\n", name, task->ClassName());
1295 TCanvas *canvas = new TCanvas(Form("profile_%d",itop),Form("Profile of task %s (class %s)",name,task->ClassName()),10,10,800,600);
1296 canvas->Divide(2, 2, 0.01, 0.01);
1300 // VM profile for COO and Terminate methods
1302 cut = Form("task==%d && (stage==0 || stage==2)",itask);
1303 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1304 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1306 hist->SetTitle("Alocated VM[MB] for COO and Terminate");
1307 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1308 hist->GetXaxis()->SetTitle("method");
1310 // CPU profile per event
1312 cut = Form("task==%d && stage==1",itop);
1313 tree->Draw("deltaT:event",cut,"", 1234567890, 0);
1314 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1316 hist->SetTitle("Execution time per event");
1317 hist->GetYaxis()->SetTitle("CPU/event [s]");
1319 // VM profile for Exec
1321 cut = Form("task==%d && stage==1",itop);
1322 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1323 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1325 hist->SetTitle("Alocated VM[MB] per event");
1326 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1331 if (cdir) cdir->cd();
1334 //______________________________________________________________________________
1335 void AliAnalysisManager::AddTask(AliAnalysisTask *task)
1337 // Adds a user task to the global list of tasks.
1339 Error("AddTask", "Cannot add task %s since InitAnalysis was already called", task->GetName());
1343 if (fTasks->FindObject(task)) {
1344 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
1347 task->SetActive(kFALSE);
1351 //______________________________________________________________________________
1352 AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
1354 // Retreive task by name.
1355 if (!fTasks) return NULL;
1356 return (AliAnalysisTask*)fTasks->FindObject(name);
1359 //______________________________________________________________________________
1360 Int_t AliAnalysisManager::GetTaskIndex(const AliAnalysisTask *task) const
1362 // Returns task inded in the manager's list, -1 if not registered.
1363 if (!fTasks) return -1;
1364 return fTasks->IndexOf(task);
1367 //______________________________________________________________________________
1368 AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
1369 TClass *datatype, EAliAnalysisContType type, const char *filename)
1371 // Create a data container of a certain type. Types can be:
1372 // kExchangeContainer = 0, used to exchange data between tasks
1373 // kInputContainer = 1, used to store input data
1374 // kOutputContainer = 2, used for writing result to a file
1375 // filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
1376 // the output object to a folder inside the output file
1377 if (fContainers->FindObject(name)) {
1378 Error("CreateContainer","A container named %s already defined !",name);
1381 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
1382 fContainers->Add(cont);
1384 case kInputContainer:
1387 case kOutputContainer:
1388 fOutputs->Add(cont);
1389 if (filename && strlen(filename)) {
1390 cont->SetFileName(filename);
1391 cont->SetDataOwned(kFALSE); // data owned by the file
1394 case kParamContainer:
1395 fParamCont->Add(cont);
1396 if (filename && strlen(filename)) {
1397 cont->SetFileName(filename);
1398 cont->SetDataOwned(kFALSE); // data owned by the file
1401 case kExchangeContainer:
1407 //______________________________________________________________________________
1408 Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
1409 AliAnalysisDataContainer *cont)
1411 // Connect input of an existing task to a data container.
1413 Error("ConnectInput", "Task pointer is NULL");
1416 if (!fTasks->FindObject(task)) {
1418 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
1420 Bool_t connected = task->ConnectInput(islot, cont);
1424 //______________________________________________________________________________
1425 Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
1426 AliAnalysisDataContainer *cont)
1428 // Connect output of an existing task to a data container.
1430 Error("ConnectOutput", "Task pointer is NULL");
1433 if (!fTasks->FindObject(task)) {
1435 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
1437 Bool_t connected = task->ConnectOutput(islot, cont);
1441 //______________________________________________________________________________
1442 void AliAnalysisManager::CleanContainers()
1444 // Clean data from all containers that have already finished all client tasks.
1445 TIter next(fContainers);
1446 AliAnalysisDataContainer *cont;
1447 while ((cont=(AliAnalysisDataContainer *)next())) {
1448 if (cont->IsOwnedData() &&
1449 cont->IsDataReady() &&
1450 cont->ClientsExecuted()) cont->DeleteData();
1454 //______________________________________________________________________________
1455 Bool_t AliAnalysisManager::InitAnalysis()
1457 // Initialization of analysis chain of tasks. Should be called after all tasks
1458 // and data containers are properly connected
1459 // Reset flag and remove valid_outputs file if exists
1460 if (fInitOK) return kTRUE;
1461 if (!gSystem->AccessPathName("outputs_valid"))
1462 gSystem->Unlink("outputs_valid");
1463 // Check for top tasks (depending only on input data containers)
1464 if (!fTasks->First()) {
1465 Error("InitAnalysis", "Analysis has no tasks !");
1469 AliAnalysisTask *task;
1470 AliAnalysisDataContainer *cont;
1473 Bool_t iszombie = kFALSE;
1474 Bool_t istop = kTRUE;
1476 while ((task=(AliAnalysisTask*)next())) {
1479 Int_t ninputs = task->GetNinputs();
1480 for (i=0; i<ninputs; i++) {
1481 cont = task->GetInputSlot(i)->GetContainer();
1485 fZombies->Add(task);
1489 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
1490 i, task->GetName());
1492 if (iszombie) continue;
1493 // Check if cont is an input container
1494 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
1495 // Connect to parent task
1499 fTopTasks->Add(task);
1503 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
1506 // Check now if there are orphan tasks
1507 for (i=0; i<ntop; i++) {
1508 task = (AliAnalysisTask*)fTopTasks->At(i);
1513 while ((task=(AliAnalysisTask*)next())) {
1514 if (!task->IsUsed()) {
1516 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
1519 // Check the task hierarchy (no parent task should depend on data provided
1520 // by a daughter task)
1521 for (i=0; i<ntop; i++) {
1522 task = (AliAnalysisTask*)fTopTasks->At(i);
1523 if (task->CheckCircularDeps()) {
1524 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
1529 // Check that all containers feeding post-event loop tasks are in the outputs list
1530 TIter nextcont(fContainers); // loop over all containers
1531 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1532 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1533 if (cont->HasConsumers()) {
1534 // Check if one of the consumers is post event loop
1535 TIter nextconsumer(cont->GetConsumers());
1536 while ((task=(AliAnalysisTask*)nextconsumer())) {
1537 if (task->IsPostEventLoop()) {
1538 fOutputs->Add(cont);
1545 // Check if all special output containers have a file name provided
1546 TIter nextout(fOutputs);
1547 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1548 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1549 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1553 // Initialize requested branch list if needed
1554 if (!fAutoBranchHandling) {
1556 while ((task=(AliAnalysisTask*)next())) {
1557 if (!task->HasBranches()) {
1558 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\"",
1559 task->GetName(), task->ClassName());
1562 if (!fInputEventHandler || !strlen(fInputEventHandler->GetDataType())) {
1563 Error("InitAnalysis", "Manual branch loading requested but no input handler defined or handler does not define data type.");
1566 TString taskbranches;
1567 task->GetBranches(fInputEventHandler->GetDataType(), taskbranches);
1568 if (taskbranches.IsNull()) {
1569 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches of type %s:",
1570 task->GetName(), task->ClassName(), fInputEventHandler->GetDataType());
1573 AddBranches(taskbranches);
1580 //______________________________________________________________________________
1581 void AliAnalysisManager::AddBranches(const char *branches)
1583 // Add branches to the existing fRequestedBranches.
1584 TString br(branches);
1585 TObjArray *arr = br.Tokenize(",");
1588 while ((obj=next())) {
1589 if (!fRequestedBranches.Contains(obj->GetName())) {
1590 if (!fRequestedBranches.IsNull()) fRequestedBranches += ",";
1591 fRequestedBranches += obj->GetName();
1597 //______________________________________________________________________________
1598 void AliAnalysisManager::CheckBranches(Bool_t load)
1600 // The method checks the input branches to be loaded during the analysis.
1601 if (fAutoBranchHandling || fRequestedBranches.IsNull() || !fTree) return;
1602 TObjArray *arr = fRequestedBranches.Tokenize(",");
1605 while ((obj=next())) {
1606 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(obj->GetName()));
1608 br = fTree->GetBranch(obj->GetName());
1610 Error("CheckBranches", "Could not find branch %s",obj->GetName());
1615 if (load && br->GetReadEntry()!=GetCurrentEntry()) {
1616 br->GetEntry(GetCurrentEntry());
1622 //______________________________________________________________________________
1623 Bool_t AliAnalysisManager::CheckTasks() const
1625 // Check consistency of tasks.
1626 Int_t ntasks = fTasks->GetEntries();
1628 Error("CheckTasks", "No tasks connected to the manager. This may be due to forgetting to compile the task or to load their library.");
1631 // Get the pointer to AliAnalysisTaskSE::Class()
1632 TClass *badptr = (TClass*)gROOT->ProcessLine("AliAnalysisTaskSE::Class()");
1633 // Loop all tasks to check if their corresponding library was loaded
1636 while ((obj=next())) {
1637 if (obj->IsA() == badptr) {
1638 Error("CheckTasks", "##################\n \
1639 Class for task %s NOT loaded. You probably forgot to load the library for this task (or compile it dynamically).\n###########################\n",obj->GetName());
1646 //______________________________________________________________________________
1647 void AliAnalysisManager::PrintStatus(Option_t *option) const
1649 // Print task hierarchy.
1651 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1654 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1656 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
1657 TIter next(fTopTasks);
1658 AliAnalysisTask *task;
1659 while ((task=(AliAnalysisTask*)next()))
1660 task->PrintTask(option);
1662 if (!fAutoBranchHandling && !fRequestedBranches.IsNull())
1663 printf("Requested input branches:\n%s\n", fRequestedBranches.Data());
1665 TString sopt(option);
1668 if (sopt.Contains("ALL"))
1670 if ( fOutputEventHandler )
1672 cout << TString('_',78) << endl;
1673 cout << "OutputEventHandler:" << endl;
1674 fOutputEventHandler->Print(" ");
1679 //______________________________________________________________________________
1680 void AliAnalysisManager::ResetAnalysis()
1682 // Reset all execution flags and clean containers.
1686 //______________________________________________________________________________
1687 void AliAnalysisManager::RunLocalInit()
1689 // Run LocalInit method for all tasks.
1690 TDirectory *cdir = gDirectory;
1691 if (IsTrainInitialized()) return;
1692 TIter nextTask(fTasks);
1693 AliAnalysisTask *task;
1694 while ((task=(AliAnalysisTask*)nextTask())) {
1698 if (cdir) cdir->cd();
1699 TObject::SetBit(kTasksInitialized, kTRUE);
1702 //______________________________________________________________________________
1703 void AliAnalysisManager::InputFileFromTree(TTree * const tree, TString &fname)
1705 // Retrieves name of the file from tree
1708 TFile *file = tree->GetCurrentFile();
1711 TChain *chain = dynamic_cast<TChain*>(tree);
1712 if (!chain || !chain->GetNtrees()) return;
1713 basename = gSystem->BaseName(chain->GetListOfFiles()->First()->GetTitle());
1715 basename = gSystem->BaseName(file->GetName());
1717 Int_t index = basename.Index("#");
1718 fname = basename(index+1, basename.Length());
1721 //______________________________________________________________________________
1722 Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
1724 // Start analysis having a grid handler.
1725 if (!fGridHandler) {
1726 Error("StartAnalysis", "Cannot start analysis providing just the analysis type without a grid handler.");
1727 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1731 return StartAnalysis(type, tree, nentries, firstentry);
1734 //______________________________________________________________________________
1735 Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
1737 // Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1738 // MIX. Process nentries starting from firstentry
1740 // Backup current directory and make sure gDirectory points to gROOT
1741 TDirectory *cdir = gDirectory;
1744 Error("StartAnalysis","Analysis manager was not initialized !");
1745 if (cdir) cdir->cd();
1748 if (!CheckTasks()) Fatal("StartAnalysis", "Not all needed libraries were loaded");
1750 printf("StartAnalysis %s\n",GetName());
1751 AliLog::SetGlobalLogLevel(AliLog::kInfo);
1753 fMaxEntries = nentries;
1755 TString anaType = type;
1757 fMode = kLocalAnalysis;
1758 if (anaType.Contains("file")) fIsRemote = kTRUE;
1759 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1760 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1761 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1762 if (fInputEventHandler) {
1764 InputFileFromTree(tree, fname);
1765 if (fname.Length()) fInputEventHandler->SetInputFileName(fname);
1768 if (fMode == kGridAnalysis) {
1770 if (!anaType.Contains("terminate")) {
1771 if (!fGridHandler) {
1772 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1773 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1774 if (cdir) cdir->cd();
1777 // Write analysis manager in the analysis file
1778 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1779 // run local task configuration
1781 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1782 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1783 if (cdir) cdir->cd();
1787 // Terminate grid analysis
1788 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1789 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1790 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1791 if (!fGridHandler->MergeOutputs()) {
1792 // Return if outputs could not be merged or if it alien handler
1793 // was configured for offline mode or local testing.
1794 if (cdir) cdir->cd();
1798 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1799 if (cdir) cdir->cd();
1800 ImportWrappers(NULL);
1802 if (cdir) cdir->cd();
1806 SetEventLoop(kFALSE);
1807 // Enable event loop mode if a tree was provided
1808 if (tree || fGridHandler || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
1811 TString ttype = "TTree";
1812 if (tree && tree->IsA() == TChain::Class()) {
1813 chain = (TChain*)tree;
1814 if (!chain || !chain->GetListOfFiles()->First()) {
1815 Error("StartAnalysis", "Cannot process null or empty chain...");
1816 if (cdir) cdir->cd();
1822 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1823 if (getsysInfo) AliSysInfo::AddStamp("Start", 0);
1824 // Initialize locally all tasks (happens for all modes)
1826 AliAnalysisTask *task;
1830 case kLocalAnalysis:
1831 if (!tree && !fGridHandler) {
1832 TIter nextT(fTasks);
1833 // Call CreateOutputObjects for all tasks
1835 Bool_t dirStatus = TH1::AddDirectoryStatus();
1836 while ((task=(AliAnalysisTask*)nextT())) {
1837 TH1::AddDirectory(kFALSE);
1838 task->CreateOutputObjects();
1839 if (!task->CheckPostData()) {
1840 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
1841 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
1842 ########### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ###########", task->GetName(), task->ClassName());
1844 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
1848 TH1::AddDirectory(dirStatus);
1849 if (IsExternalLoop()) {
1850 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1851 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1858 fSelector = new AliAnalysisSelector(this);
1859 // Check if a plugin handler is used
1861 // Get the chain from the plugin
1862 TString dataType = "esdTree";
1863 if (fInputEventHandler) {
1864 dataType = fInputEventHandler->GetDataType();
1868 chain = fGridHandler->GetChainForTestMode(dataType);
1870 Error("StartAnalysis", "No chain for test mode. Aborting.");
1873 cout << "===== RUNNING LOCAL ANALYSIS" << GetName() << " ON CHAIN " << chain->GetName() << endl;
1874 retv = chain->Process(fSelector, "", nentries, firstentry);
1877 // Run tree-based analysis via AliAnalysisSelector
1878 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
1879 retv = tree->Process(fSelector, "", nentries, firstentry);
1881 case kProofAnalysis:
1883 // Check if the plugin is used
1885 return StartAnalysis(type, fGridHandler->GetProofDataSet(), nentries, firstentry);
1887 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1888 Error("StartAnalysis", "No PROOF!!! Exiting.");
1889 if (cdir) cdir->cd();
1892 line = Form("gProof->AddInput((TObject*)%p);", this);
1893 gROOT->ProcessLine(line);
1896 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
1897 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
1899 Error("StartAnalysis", "No chain!!! Exiting.");
1900 if (cdir) cdir->cd();
1906 if (!anaType.Contains("terminate")) {
1907 if (!fGridHandler) {
1908 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1909 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1910 if (cdir) cdir->cd();
1913 // Write analysis manager in the analysis file
1914 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1915 // Start the analysis via the handler
1916 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1917 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1918 if (cdir) cdir->cd();
1922 // Terminate grid analysis
1923 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1924 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1925 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1926 if (!fGridHandler->MergeOutputs()) {
1927 // Return if outputs could not be merged or if it alien handler
1928 // was configured for offline mode or local testing.
1929 if (cdir) cdir->cd();
1933 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1934 ImportWrappers(NULL);
1936 if (cdir) cdir->cd();
1938 case kMixingAnalysis:
1939 // Run event mixing analysis
1941 Error("StartAnalysis", "Cannot run event mixing without event pool");
1942 if (cdir) cdir->cd();
1945 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1946 fSelector = new AliAnalysisSelector(this);
1947 while ((chain=fEventPool->GetNextChain())) {
1949 // Call NotifyBinChange for all tasks
1950 while ((task=(AliAnalysisTask*)next()))
1951 if (!task->IsPostEventLoop()) task->NotifyBinChange();
1952 retv = chain->Process(fSelector);
1954 Error("StartAnalysis", "Mixing analysis failed");
1955 if (cdir) cdir->cd();
1959 PackOutput(fSelector->GetOutputList());
1962 if (cdir) cdir->cd();
1966 //______________________________________________________________________________
1967 Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
1969 // Start analysis for this manager on a given dataset. Analysis task can be:
1970 // LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1972 Error("StartAnalysis","Analysis manager was not initialized !");
1976 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
1977 TString anaType = type;
1979 if (!anaType.Contains("proof")) {
1980 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
1983 fMode = kProofAnalysis;
1985 TString proofProcessOpt;
1986 SetEventLoop(kTRUE);
1987 // Set the dataset flag
1988 TObject::SetBit(kUseDataSet);
1991 // Start proof analysis using the grid handler
1992 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1993 Error("StartAnalysis", "The grid plugin could not start PROOF analysis");
1996 // Check if the plugin is in test mode
1997 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kTest) {
1998 dataset = "test_collection";
2000 dataset = fGridHandler->GetProofDataSet();
2003 proofProcessOpt = fGridHandler->GetProofProcessOpt();
2006 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
2007 Error("StartAnalysis", "No PROOF!!! Exiting.");
2011 // Initialize locally all tasks
2014 line = Form("gProof->AddInput((TObject*)%p);", this);
2015 gROOT->ProcessLine(line);
2017 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"%s\", %lld, %lld);",
2018 dataset,proofProcessOpt.Data(), nentries, firstentry);
2019 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
2020 retv = (Long_t)gROOT->ProcessLine(line);
2024 //______________________________________________________________________________
2025 TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
2027 // Opens according the option the file specified by cont->GetFileName() and changes
2028 // current directory to cont->GetFolderName(). If the file was already opened, it
2029 // checks if the option UPDATE was preserved. File open via TProofOutputFile can
2030 // be optionally ignored.
2031 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2032 TString filename = cont->GetFileName();
2034 if (filename.IsNull()) {
2035 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
2038 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
2040 f = mgr->OpenProofFile(cont,option);
2042 // Check first if the file is already opened
2043 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2045 // Check if option "UPDATE" was preserved
2046 TString opt(option);
2048 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2049 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2051 f = TFile::Open(filename, option);
2054 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2058 // Check for a folder request
2059 TString dir = cont->GetFolderName();
2060 if (!dir.IsNull()) {
2061 if (!f->GetDirectory(dir)) f->mkdir(dir);
2066 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
2067 cont->SetFile(NULL);
2071 //______________________________________________________________________________
2072 TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option, const char *extaod)
2074 // Opens a special output file used in PROOF.
2076 TString filename = cont->GetFileName();
2077 if (cont == fCommonOutput) {
2078 if (fOutputEventHandler) {
2079 if (strlen(extaod)) filename = extaod;
2080 filename = fOutputEventHandler->GetOutputFileName();
2082 else Fatal("OpenProofFile","No output container. Exiting.");
2085 if (fMode!=kProofAnalysis || !fSelector) {
2086 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
2089 if (fSpecialOutputLocation.Length()) {
2090 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2092 // Check if option "UPDATE" was preserved
2093 TString opt(option);
2095 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2096 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2098 f = new TFile(filename, option);
2100 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2104 // Check for a folder request
2105 TString dir = cont->GetFolderName();
2107 if (!f->GetDirectory(dir)) f->mkdir(dir);
2112 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2113 cont->SetFile(NULL);
2116 // Check if there is already a proof output file in the output list
2117 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
2119 // Get the actual file
2120 line = Form("((TProofOutputFile*)%p)->GetFileName();", pof);
2121 filename = (const char*)gROOT->ProcessLine(line);
2123 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
2125 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2127 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
2130 // Check if option "UPDATE" was preserved
2131 TString opt(option);
2133 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2134 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
2136 if (cont->IsRegisterDataset()) {
2137 TString dsetName = filename;
2138 dsetName.ReplaceAll(".root", cont->GetTitle());
2139 dsetName.ReplaceAll(":","_");
2140 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
2141 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
2143 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
2144 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
2146 if (fDebug > 1) printf("=== %s\n", line.Data());
2147 gROOT->ProcessLine(line);
2148 line = Form("pf->OpenFile(\"%s\");", option);
2149 gROOT->ProcessLine(line);
2152 gROOT->ProcessLine("pf->Print()");
2153 printf(" == proof file name: %s", f->GetName());
2155 // Add to proof output list
2156 line = Form("((TList*)%p)->Add(pf);",fSelector->GetOutputList());
2157 if (fDebug > 1) printf("=== %s\n", line.Data());
2158 gROOT->ProcessLine(line);
2160 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2164 // Check for a folder request
2165 TString dir = cont->GetFolderName();
2166 if (!dir.IsNull()) {
2167 if (!f->GetDirectory(dir)) f->mkdir(dir);
2172 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2173 cont->SetFile(NULL);
2177 //______________________________________________________________________________
2178 void AliAnalysisManager::ExecAnalysis(Option_t *option)
2180 // Execute analysis.
2181 static Long64_t nentries = 0;
2182 static TTree *lastTree = 0;
2183 static TStopwatch *timer = new TStopwatch();
2184 // Only the first call to Process will trigger a true Notify. Other Notify
2185 // coming before is ignored.
2186 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) {
2187 TObject::SetBit(AliAnalysisManager::kTrueNotify);
2190 if (fDebug > 0) printf("MGR: Processing event #%d\n", fNcalls);
2192 if (fTree && (fTree != lastTree)) {
2193 nentries += fTree->GetEntries();
2196 if (!fNcalls) timer->Start();
2197 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", fNcalls, TMath::Min(fMaxEntries,nentries), timer, kFALSE);
2199 fIOTimer->Start(kTRUE);
2201 TDirectory *cdir = gDirectory;
2202 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
2203 if (getsysInfo && ((fNcalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)fNcalls);
2205 Error("ExecAnalysis", "Analysis manager was not initialized !");
2206 if (cdir) cdir->cd();
2210 AliAnalysisTask *task;
2211 // Check if the top tree is active.
2213 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2214 AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
2216 // De-activate all tasks
2217 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
2218 AliAnalysisDataContainer *cont = fCommonInput;
2219 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
2221 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
2222 if (cdir) cdir->cd();
2225 cont->SetData(fTree); // This will notify all consumers
2226 Long64_t entry = fTree->GetTree()->GetReadEntry();
2228 // Call BeginEvent() for optional input/output and MC services
2229 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
2230 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
2231 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
2233 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2234 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2236 // Execute the tasks
2237 // TIter next1(cont->GetConsumers());
2239 fIOTime += fIOTimer->RealTime();
2240 fCPUTimer->Start(kTRUE);
2241 TIter next1(fTopTasks);
2243 while ((task=(AliAnalysisTask*)next1())) {
2245 cout << " Executing task " << task->GetName() << endl;
2247 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
2248 task->ExecuteTask(option);
2249 if (fStatistics) fStatistics->StopTimer();
2251 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2252 AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
2256 fCPUTime += fCPUTimer->RealTime();
2257 fIOTimer->Start(kTRUE);
2259 // Call FinishEvent() for optional output and MC services
2260 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2261 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2262 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2263 // Gather system information if requested
2264 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2265 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1001, 1);
2266 if (cdir) cdir->cd();
2268 fIOTime += fIOTimer->RealTime();
2271 // The event loop is not controlled by TSelector
2273 // Call BeginEvent() for optional input/output and MC services
2274 fIOTimer->Start(kTRUE);
2275 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
2276 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
2277 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
2279 fIOTime += fIOTimer->RealTime();
2281 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2282 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2283 fCPUTimer->Start(kTRUE);
2284 TIter next2(fTopTasks);
2285 while ((task=(AliAnalysisTask*)next2())) {
2286 task->SetActive(kTRUE);
2288 cout << " Executing task " << task->GetName() << endl;
2290 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
2291 task->ExecuteTask(option);
2292 if (fStatistics) fStatistics->StopTimer();
2296 fCPUTime += fCPUTimer->RealTime();
2298 // Call FinishEvent() for optional output and MC services
2299 fIOTimer->Start(kTRUE);
2300 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2301 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2302 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2303 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2304 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
2305 if (cdir) cdir->cd();
2307 fIOTime += fIOTimer->RealTime();
2310 //______________________________________________________________________________
2311 Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
2313 // Check if the stdout is connected to a pipe (C.Holm)
2314 Bool_t ispipe = kFALSE;
2315 out.seekp(0, std::ios_base::cur);
2318 if (errno == ESPIPE) ispipe = kTRUE;
2323 //______________________________________________________________________________
2324 void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
2326 // Set the input event handler and create a container for it.
2328 fInputEventHandler = handler;
2329 if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
2332 //______________________________________________________________________________
2333 void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
2335 // Set the input event handler and create a container for it.
2337 fOutputEventHandler = handler;
2338 if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
2339 fCommonOutput->SetSpecialOutput();
2342 //______________________________________________________________________________
2343 void AliAnalysisManager::SetDebugLevel(UInt_t level)
2345 // Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
2346 if (TObject::TestBit(kUseProgressBar)) {
2347 Info("SetDebugLevel","Ignored. Disable the progress bar first.");
2353 //______________________________________________________________________________
2354 void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
2356 // Enable a text mode progress bar. Resets debug level to 0.
2357 Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
2358 TObject::SetBit(kUseProgressBar,flag);
2359 fPBUpdateFreq = freq;
2363 //______________________________________________________________________________
2364 void AliAnalysisManager::RegisterExtraFile(const char *fname)
2366 // This method is used externally to register output files which are not
2367 // connected to any output container, so that the manager can properly register,
2368 // retrieve or merge them when running in distributed mode. The file names are
2369 // separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
2370 if (fExtraFiles.Contains(fname)) return;
2371 if (fExtraFiles.Length()) fExtraFiles += " ";
2372 fExtraFiles += fname;
2375 //______________________________________________________________________________
2376 Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
2378 // Copy a file from the location specified ina the wrapper with the same name from the source list.
2382 TObject *pof = source->FindObject(filename);
2383 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
2384 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
2387 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
2388 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
2389 TString clientUrl(chUrl);
2390 TString fullPath_str(fullPath);
2391 if (clientUrl.Contains("localhost")){
2392 TObjArray* array = fullPath_str.Tokenize ( "//" );
2393 TObjString *strobj = ( TObjString *)array->At(1);
2394 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
2395 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
2396 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
2397 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
2398 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
2402 else if (clientUrl.Contains("__lite__")) {
2403 // Special case for ProofLite environement - get file info and copy.
2404 gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
2405 fullPath_str = Form("%s/%s", tmp, fullPath);
2408 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
2409 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
2411 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
2415 //______________________________________________________________________________
2416 void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
2418 // Fill analysis type in the provided string.
2420 case kLocalAnalysis:
2423 case kProofAnalysis:
2429 case kMixingAnalysis:
2434 //______________________________________________________________________________
2435 Bool_t AliAnalysisManager::ValidateOutputFiles() const
2437 // Validate all output files.
2438 TIter next(fOutputs);
2439 AliAnalysisDataContainer *output;
2440 TDirectory *cdir = gDirectory;
2441 TString openedFiles;
2442 while ((output=(AliAnalysisDataContainer*)next())) {
2443 if (output->IsRegisterDataset()) continue;
2444 TString filename = output->GetFileName();
2445 if (filename == "default") {
2446 if (!fOutputEventHandler) continue;
2447 filename = fOutputEventHandler->GetOutputFileName();
2448 // Main AOD may not be there
2449 if (gSystem->AccessPathName(filename)) continue;
2451 // Check if the file is closed
2452 if (openedFiles.Contains(filename)) continue;;
2453 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2455 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
2456 // Clear file list to release object ownership to user.
2460 file = TFile::Open(filename);
2461 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
2462 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
2463 if (cdir) cdir->cd();
2467 openedFiles += filename;
2470 if (cdir) cdir->cd();
2474 //______________________________________________________________________________
2475 void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
2477 // Implements a nice text mode progress bar.
2478 static Long64_t icount = 0;
2479 static TString oname;
2480 static TString nname;
2481 static Long64_t ocurrent = 0;
2482 static Long64_t osize = 0;
2483 static Int_t oseconds = 0;
2484 static TStopwatch *owatch = 0;
2485 static Bool_t oneoftwo = kFALSE;
2486 static Int_t nrefresh = 0;
2487 static Int_t nchecks = 0;
2488 static char lastChar = 0;
2489 const char symbol[4] = {'-','\\','|','/'};
2491 if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
2497 ocurrent = TMath::Abs(current);
2498 osize = TMath::Abs(size);
2499 if (ocurrent > osize) ocurrent=osize;
2504 if ((current % fPBUpdateFreq) != 0) return;
2506 char progress[11] = " ";
2507 Int_t ichar = icount%4;
2512 if (owatch && !last) {
2514 time = owatch->RealTime();
2515 seconds = int(time) % 60;
2516 minutes = (int(time) / 60) % 60;
2517 hours = (int(time) / 60 / 60);
2519 if (oseconds==seconds) {
2523 oneoftwo = !oneoftwo;
2527 if (refresh && oneoftwo) {
2529 if (nchecks <= 0) nchecks = nrefresh+1;
2530 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
2531 oname = Form(" == %d%% ==", pctdone);
2533 Double_t percent = 100.0*ocurrent/osize;
2534 Int_t nchar = Int_t(percent/10);
2535 if (nchar>10) nchar=10;
2537 for (i=0; i<nchar; i++) progress[i] = '=';
2538 progress[nchar] = symbol[ichar];
2539 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2540 progress[10] = '\0';
2543 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2544 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2545 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
2547 Int_t full = Int_t(ocurrent > 0 ?
2548 time * (float(osize)/ocurrent) + .5 :
2550 Int_t remain = Int_t(full - time);
2551 Int_t rsec = remain % 60;
2552 Int_t rmin = (remain / 60) % 60;
2553 Int_t rhour = (remain / 60 / 60);
2554 fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
2555 percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
2557 else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
2558 if (refresh && oneoftwo) oname = nname;
2559 if (owatch) owatch->Continue();
2568 fprintf(stderr, "\n");
2572 //______________________________________________________________________________
2573 void AliAnalysisManager::DoLoadBranch(const char *name)
2575 // Get tree and load branch if needed.
2576 static Long64_t crtEntry = -100;
2578 if (fAutoBranchHandling || !fTree)
2581 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2583 br = fTree->GetBranch(name);
2585 Error("DoLoadBranch", "Could not find branch %s",name);
2590 if (br->GetReadEntry()==fCurrentEntry) return;
2591 Long64_t readbytes = br->GetEntry(GetCurrentEntry());
2593 Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
2594 if (crtEntry != fCurrentEntry) {
2595 CountEvent(1,0,1,0);
2596 crtEntry = fCurrentEntry;
2599 if (crtEntry != fCurrentEntry) {
2600 CountEvent(1,1,0,0);
2601 crtEntry = fCurrentEntry;
2606 //______________________________________________________________________________
2607 void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
2609 // Add the statistics task to the manager.
2611 Info("AddStatisticsTask", "Already added");
2614 TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
2615 gROOT->ProcessLine(line);
2618 //______________________________________________________________________________
2619 void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
2621 // Bookkeep current event;
2622 if (!fStatistics) return;
2623 fStatistics->AddInput(ninput);
2624 fStatistics->AddProcessed(nprocessed);
2625 fStatistics->AddFailed(nfailed);
2626 fStatistics->AddAccepted(naccepted);
2629 //______________________________________________________________________________
2630 void AliAnalysisManager::AddStatisticsMsg(const char *line)
2632 // Add a line in the statistics message. If available, the statistics message is written
2633 // at the end of the SlaveTerminate phase on workers AND at the end of Terminate
2635 if (!strlen(line)) return;
2636 if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
2637 fStatisticsMsg += line;
2640 //______________________________________________________________________________
2641 void AliAnalysisManager::WriteStatisticsMsg(Int_t)
2643 // If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
2644 static Bool_t done = kFALSE;
2647 if (!fStatistics) return;
2649 AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
2650 AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
2651 AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
2652 AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
2653 out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
2654 fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
2655 fStatistics->GetNaccepted()), ios::out);
2656 out << fStatisticsMsg << endl;
2660 //______________________________________________________________________________
2661 const char* AliAnalysisManager::GetOADBPath()
2663 // returns the path of the OADB
2664 // this static function just depends on environment variables
2666 static TString oadbPath;
2668 if (gSystem->Getenv("OADB_PATH"))
2669 oadbPath = gSystem->Getenv("OADB_PATH");
2670 else if (gSystem->Getenv("ALICE_ROOT"))
2671 oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
2673 ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
2678 //______________________________________________________________________________
2679 void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
2681 // Define a custom string variable mapped to a global unique name. The variable
2682 // can be then retrieved by a given analysis macro via GetGlobalStr(key).
2683 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2685 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2688 Bool_t valid = kFALSE;
2689 TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
2691 ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
2694 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
2697 //______________________________________________________________________________
2698 const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
2700 // Static method to retrieve a global variable defined via SetGlobalStr.
2702 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2704 TObject *value = mgr->GetGlobals()->GetValue(key);
2705 if (!value) return 0;
2707 return value->GetName();
2710 //______________________________________________________________________________
2711 void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
2713 // Define a custom integer variable mapped to a global unique name. The variable
2714 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2715 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2717 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2720 Bool_t valid = kFALSE;
2721 Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
2723 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
2726 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
2729 //______________________________________________________________________________
2730 Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
2732 // Static method to retrieve a global variable defined via SetGlobalInt.
2734 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2736 TObject *value = mgr->GetGlobals()->GetValue(key);
2737 if (!value) return 0;
2739 TString s = value->GetName();
2743 //______________________________________________________________________________
2744 void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
2746 // Define a custom double precision variable mapped to a global unique name. The variable
2747 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2748 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2750 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2753 Bool_t valid = kFALSE;
2754 Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
2756 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
2759 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));
2762 //______________________________________________________________________________
2763 Double_t AliAnalysisManager::GetGlobalDbl(const char *key, Bool_t &valid)
2765 // Static method to retrieve a global variable defined via SetGlobalDbl.
2767 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2769 TObject *value = mgr->GetGlobals()->GetValue(key);
2770 if (!value) return 0;
2772 TString s = value->GetName();
2776 //______________________________________________________________________________
2777 void AliAnalysisManager::AddClassDebug(const char *className, Int_t debugLevel)
2779 // Sets Class debug level
2781 if (!fDebugOptions) {
2782 fDebugOptions = new TObjArray();
2783 fDebugOptions->SetOwner(kTRUE);
2786 TNamed *debugOpt = (TNamed*)fDebugOptions->FindObject(className);
2788 AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel,className).Data());
2789 fDebugOptions->Add(new TNamed(className,TString::Format("%d",debugLevel).Data()));
2791 TString oldDebugStr = debugOpt->GetTitle();
2792 Int_t oldDebug = oldDebugStr.Atoi();
2793 if (debugLevel > oldDebug) {
2794 AliWarning(TString::Format("Overwriting debug level to %d class %s, because it is higher then previously set (%d).",debugLevel,className,oldDebug).Data());
2795 debugOpt->SetTitle(TString::Format("%d",debugLevel).Data());
2797 AliWarning(TString::Format("Ignoring debug level to %d class %s, because it is smaller then previously set (%d).",debugLevel,className,oldDebug).Data());
2802 //______________________________________________________________________________
2803 void AliAnalysisManager::ApplyDebugOptions()
2805 // Apply debug options
2807 if (!fDebugOptions) return;
2809 TIter next(fDebugOptions);
2812 while ((debug=dynamic_cast<TNamed*>(next()))) {
2813 debugLevel = debug->GetTitle();
2814 AliInfo(TString::Format("Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()).Data());
2815 AliLog::SetClassDebugLevel(debug->GetName(), debugLevel.Atoi());
2819 //______________________________________________________________________________
2820 Bool_t AliAnalysisManager::IsMacroLoaded(const char filename)
2822 // Check if a macro was loaded.
2823 return fgMacroNames.Contains(filename);
2826 //______________________________________________________________________________
2827 Int_t AliAnalysisManager::LoadMacro(const char *filename, Int_t *error, Bool_t check)
2829 // Redirection of gROOT->LoadMacro which makes sure the same macro is not loaded
2831 TString macroName = gSystem->BaseName(filename);
2832 // Strip appended +, ++, +g, +O
2833 Int_t index = macroName.Index("+");
2834 if (index>0) macroName.Remove(index);
2835 if (fgMacroNames.Contains(macroName)) {
2836 // Macro with the same name loaded already in this root session, do
2841 Int_t ret = gROOT->LoadMacro(filename,error,check);
2842 // In case of error return the error code
2843 if (ret) return ret;
2844 // Append the macro name to the loaded macros list
2845 fgMacroNames += macroName;
2846 fgMacroNames += " ";
2850 //______________________________________________________________________________
2851 void AliAnalysisManager::Lock()
2853 // Security lock. This is to detect NORMAL user errors and not really to
2854 // protect against intentional hacks.
2855 if (fLocked) return;
2857 if (fInputEventHandler) fInputEventHandler->Lock();
2858 if (fOutputEventHandler) fOutputEventHandler->Lock();
2859 if (fMCtruthEventHandler) fMCtruthEventHandler->Lock();
2860 Info("Lock","====== ANALYSIS MANAGER LOCKED ======");
2863 //______________________________________________________________________________
2864 void AliAnalysisManager::UnLock()
2866 // Verbose unlocking. Hackers will be punished ;-) ...
2867 if (!fLocked) return;
2869 if (fInputEventHandler) fInputEventHandler->UnLock();
2870 if (fOutputEventHandler) fOutputEventHandler->UnLock();
2871 if (fMCtruthEventHandler) fMCtruthEventHandler->UnLock();
2872 Info("UnLock", "====== ANALYSIS MANAGER UNLOCKED ======");
2875 //______________________________________________________________________________
2876 void AliAnalysisManager::Changed()
2878 // All critical setters pass through the Changed method that throws an exception
2879 // in case the lock was set.
2880 if (fLocked) Fatal("Changed","Critical setter called in locked mode");