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());
989 fIOTime += fIOTimer->RealTime();
990 if (fDebug > 1) printf("<-AliAnalysisManager::UnpackOutput()\n");
993 //______________________________________________________________________________
994 void AliAnalysisManager::Terminate()
996 // The Terminate() function is the last function to be called during
997 // a query. It always runs on the client, it can be used to present
998 // the results graphically.
999 if (fDebug > 1) printf("->AliAnalysisManager::Terminate()\n");
1000 fInitTimer->Start(kTRUE);
1001 TDirectory *cdir = gDirectory;
1003 AliAnalysisTask *task;
1004 AliAnalysisDataContainer *output;
1007 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1008 // Call Terminate() for tasks
1010 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
1011 // Save all the canvases produced by the Terminate
1012 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
1016 AliSysInfo::AddStamp(Form("%s_TERMINATE",task->ClassName()),0, itask, 2);
1018 if (TObject::TestBit(kSaveCanvases)) {
1019 if (!gROOT->IsBatch()) {
1020 if (fDebug>1) printf("Waiting 5 sec for %s::Terminate() to finish drawing ...\n", task->ClassName());
1022 while (timer.RealTime()<5) {
1024 gSystem->ProcessEvents();
1027 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
1028 if (iend==0) continue;
1030 for (Int_t ipict=0; ipict<iend; ipict++) {
1031 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
1032 if (!canvas) continue;
1033 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
1035 gROOT->GetListOfCanvases()->Delete();
1039 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
1040 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
1041 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
1043 TObjArray *allOutputs = new TObjArray();
1045 for (icont=0; icont<fOutputs->GetEntriesFast(); icont++) allOutputs->Add(fOutputs->At(icont));
1046 if (!IsSkipTerminate())
1047 for (icont=0; icont<fParamCont->GetEntriesFast(); icont++) allOutputs->Add(fParamCont->At(icont));
1048 TIter next1(allOutputs);
1049 TString handlerFile = "";
1050 TString extraOutputs = "";
1051 if (fOutputEventHandler) {
1052 handlerFile = fOutputEventHandler->GetOutputFileName();
1053 extraOutputs = fOutputEventHandler->GetExtraOutputs();
1057 while ((output=(AliAnalysisDataContainer*)next1())) {
1058 // Special outputs or grid files have the files already closed and written.
1060 if (fMode == kGridAnalysis && icont<=fOutputs->GetEntriesFast()) continue;
1061 if (fMode == kProofAnalysis) {
1062 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
1064 const char *filename = output->GetFileName();
1065 TString openoption = "RECREATE";
1066 if (!(strcmp(filename, "default"))) continue;
1067 if (!strlen(filename)) continue;
1068 if (!output->GetData()) continue;
1069 TDirectory *opwd = gDirectory;
1070 TFile *file = output->GetFile();
1071 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1073 //if (handlerFile == filename && !gSystem->AccessPathName(filename)) openoption = "UPDATE";
1074 Bool_t firsttime = kTRUE;
1075 if (filestmp.FindObject(filename) || extraOutputs.Contains(filename)) {
1078 filestmp.Add(new TNamed(filename,""));
1080 if (!gSystem->AccessPathName(filename) && !firsttime) openoption = "UPDATE";
1081 if (fDebug>1) printf("Opening file: %s option=%s\n",filename, openoption.Data());
1082 file = new TFile(filename, openoption);
1084 if (fDebug>1) printf("File <%s> already opened with option: <%s> \n", filename, file->GetOption());
1085 openoption = file->GetOption();
1086 if (openoption == "READ") {
1087 if (fDebug>1) printf("...reopening in UPDATE mode\n");
1088 file->ReOpen("UPDATE");
1091 if (file->IsZombie()) {
1092 Error("Terminate", "Cannot open output file %s", filename);
1095 output->SetFile(file);
1097 // Check for a folder request
1098 TString dir = output->GetFolderName();
1099 if (!dir.IsNull()) {
1100 if (!file->GetDirectory(dir)) file->mkdir(dir);
1103 if (fDebug > 1) printf("...writing container %s to file %s:%s\n", output->GetName(), file->GetName(), output->GetFolderName());
1104 if (output->GetData()->InheritsFrom(TCollection::Class())) {
1105 // If data is a collection, we set the name of the collection
1106 // as the one of the container and we save as a single key.
1107 TCollection *coll = (TCollection*)output->GetData();
1108 coll->SetName(output->GetName());
1109 coll->Write(output->GetName(), TObject::kSingleKey);
1111 if (output->GetData()->InheritsFrom(TTree::Class())) {
1112 TTree *tree = (TTree*)output->GetData();
1113 tree->SetDirectory(gDirectory);
1116 output->GetData()->Write();
1119 if (opwd) opwd->cd();
1123 TString copiedFiles;
1124 while ((output=(AliAnalysisDataContainer*)next1())) {
1125 // Close all files at output
1126 TDirectory *opwd = gDirectory;
1127 if (output->GetFile()) {
1128 // Clear file list to release object ownership to user.
1129 // output->GetFile()->Clear();
1130 output->GetFile()->Close();
1131 // Copy merged outputs in alien if requested
1132 if (fSpecialOutputLocation.BeginsWith("alien://")) {
1133 if (copiedFiles.Contains(output->GetFile()->GetName())) {
1134 if (opwd) opwd->cd();
1135 output->SetFile(NULL);
1138 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
1139 gROOT->ProcessLine("if (!gGrid) TGrid::Connect(\"alien:\");");
1140 TFile::Cp(output->GetFile()->GetName(),
1141 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
1142 copiedFiles += output->GetFile()->GetName();
1144 output->SetFile(NULL);
1146 if (opwd) opwd->cd();
1149 //Write statistics information on the client
1150 if (fStatistics) WriteStatisticsMsg(fNcalls);
1152 TDirectory *crtdir = gDirectory;
1153 TFile f("syswatch.root", "RECREATE");
1156 if (!f.IsZombie()) {
1157 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
1158 tree->SetName("syswatch");
1159 tree->SetMarkerStyle(kCircle);
1160 tree->SetMarkerColor(kBlue);
1161 tree->SetMarkerSize(0.5);
1162 if (!gROOT->IsBatch()) {
1163 tree->SetAlias("event", "id0");
1164 tree->SetAlias("task", "id1");
1165 tree->SetAlias("stage", "id2");
1166 // Already defined aliases
1167 // tree->SetAlias("deltaT","stampSec-stampOldSec");
1168 // tree->SetAlias("T","stampSec-first");
1169 // tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)");
1170 // tree->SetAlias("VM","pI.fMemVirtual");
1171 TCanvas *canvas = new TCanvas("SysInfo","SysInfo",10,10,1200,800);
1172 Int_t npads = 1 /*COO plot for all tasks*/ +
1173 fTopTasks->GetEntries() /*Exec plot per task*/ +
1174 1 /*Terminate plot for all tasks*/ +
1177 Int_t iopt = (Int_t)TMath::Sqrt((Double_t)npads);
1178 if (npads<iopt*(iopt+1))
1179 canvas->Divide(iopt, iopt+1, 0.01, 0.01);
1181 canvas->Divide(iopt+1, iopt+1, 0.01, 0.01);
1183 // draw the plot of deltaVM for Exec for each task
1184 for (itask=0; itask<fTopTasks->GetEntriesFast(); itask++) {
1185 task = (AliAnalysisTask*)fTopTasks->At(itask);
1187 cut = Form("task==%d && stage==1", itask);
1188 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1189 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1191 hist->SetTitle(Form("%s: Exec dVM[MB]/event", task->GetName()));
1192 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1195 // Draw the plot of deltaVM for CreateOutputObjects for all tasks
1197 tree->SetMarkerStyle(kFullTriangleUp);
1198 tree->SetMarkerColor(kRed);
1199 tree->SetMarkerSize(0.8);
1200 cut = "task>=0 && task<1000 && stage==0";
1201 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1202 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1204 hist->SetTitle("Memory in CreateOutputObjects()");
1205 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1206 hist->GetXaxis()->SetTitle("task");
1208 // draw the plot of deltaVM for Terminate for all tasks
1210 tree->SetMarkerStyle(kOpenSquare);
1211 tree->SetMarkerColor(kMagenta);
1212 cut = "task>=0 && task<1000 && stage==2";
1213 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1214 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1216 hist->SetTitle("Memory in Terminate()");
1217 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1218 hist->GetXaxis()->SetTitle("task");
1222 tree->SetMarkerStyle(kFullCircle);
1223 tree->SetMarkerColor(kGreen);
1224 cut = Form("task==%d && stage==1",fTopTasks->GetEntriesFast()-1);
1225 tree->Draw("VM:event",cut,"", 1234567890, 0);
1226 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1228 hist->SetTitle("Virtual memory");
1229 hist->GetYaxis()->SetTitle("VM [MB]");
1233 tree->SetMarkerStyle(kCircle);
1234 tree->SetMarkerColor(kBlue);
1235 tree->SetMarkerSize(0.5);
1240 if (crtdir) crtdir->cd();
1242 // Validate the output files
1243 if (ValidateOutputFiles() && fIsRemote && fMode!=kProofAnalysis) {
1245 out.open("outputs_valid", ios::out);
1248 if (cdir) cdir->cd();
1250 if (fDebug || IsCollectThroughput()) {
1251 printf("=Analysis %s= Terminate time: %g[sec]\n", GetName(), fInitTimer->RealTime());
1253 if (fDebug > 1) printf("<-AliAnalysisManager::Terminate()\n");
1255 //______________________________________________________________________________
1256 void AliAnalysisManager::ProfileTask(Int_t itop, const char *option) const
1258 // Profiles the task having the itop index in the list of top (first level) tasks.
1259 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->At(itop);
1261 Error("ProfileTask", "There are only %d top tasks in the manager", fTopTasks->GetEntries());
1264 ProfileTask(task->GetName(), option);
1267 //______________________________________________________________________________
1268 void AliAnalysisManager::ProfileTask(const char *name, const char */*option*/) const
1270 // Profile a managed task after the execution of the analysis in case NSysInfo
1272 if (gSystem->AccessPathName("syswatch.root")) {
1273 Error("ProfileTask", "No file syswatch.root found in the current directory");
1276 if (gROOT->IsBatch()) return;
1277 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->FindObject(name);
1279 Error("ProfileTask", "No top task named %s known by the manager.", name);
1282 Int_t itop = fTopTasks->IndexOf(task);
1283 Int_t itask = fTasks->IndexOf(task);
1284 // Create canvas with 2 pads: first draw COO + Terminate, second Exec
1285 TDirectory *cdir = gDirectory;
1286 TFile f("syswatch.root");
1287 TTree *tree = (TTree*)f.Get("syswatch");
1289 Error("ProfileTask", "No tree named <syswatch> found in file syswatch.root");
1292 if (fDebug > 1) printf("=== Profiling task %s (class %s)\n", name, task->ClassName());
1293 TCanvas *canvas = new TCanvas(Form("profile_%d",itop),Form("Profile of task %s (class %s)",name,task->ClassName()),10,10,800,600);
1294 canvas->Divide(2, 2, 0.01, 0.01);
1298 // VM profile for COO and Terminate methods
1300 cut = Form("task==%d && (stage==0 || stage==2)",itask);
1301 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1302 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1304 hist->SetTitle("Alocated VM[MB] for COO and Terminate");
1305 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1306 hist->GetXaxis()->SetTitle("method");
1308 // CPU profile per event
1310 cut = Form("task==%d && stage==1",itop);
1311 tree->Draw("deltaT:event",cut,"", 1234567890, 0);
1312 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1314 hist->SetTitle("Execution time per event");
1315 hist->GetYaxis()->SetTitle("CPU/event [s]");
1317 // VM profile for Exec
1319 cut = Form("task==%d && stage==1",itop);
1320 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1321 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1323 hist->SetTitle("Alocated VM[MB] per event");
1324 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1329 if (cdir) cdir->cd();
1332 //______________________________________________________________________________
1333 void AliAnalysisManager::AddTask(AliAnalysisTask *task)
1335 // Adds a user task to the global list of tasks.
1337 Error("AddTask", "Cannot add task %s since InitAnalysis was already called", task->GetName());
1341 if (fTasks->FindObject(task)) {
1342 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
1345 task->SetActive(kFALSE);
1349 //______________________________________________________________________________
1350 AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
1352 // Retreive task by name.
1353 if (!fTasks) return NULL;
1354 return (AliAnalysisTask*)fTasks->FindObject(name);
1357 //______________________________________________________________________________
1358 AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
1359 TClass *datatype, EAliAnalysisContType type, const char *filename)
1361 // Create a data container of a certain type. Types can be:
1362 // kExchangeContainer = 0, used to exchange data between tasks
1363 // kInputContainer = 1, used to store input data
1364 // kOutputContainer = 2, used for writing result to a file
1365 // filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
1366 // the output object to a folder inside the output file
1367 if (fContainers->FindObject(name)) {
1368 Error("CreateContainer","A container named %s already defined !",name);
1371 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
1372 fContainers->Add(cont);
1374 case kInputContainer:
1377 case kOutputContainer:
1378 fOutputs->Add(cont);
1379 if (filename && strlen(filename)) {
1380 cont->SetFileName(filename);
1381 cont->SetDataOwned(kFALSE); // data owned by the file
1384 case kParamContainer:
1385 fParamCont->Add(cont);
1386 if (filename && strlen(filename)) {
1387 cont->SetFileName(filename);
1388 cont->SetDataOwned(kFALSE); // data owned by the file
1391 case kExchangeContainer:
1397 //______________________________________________________________________________
1398 Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
1399 AliAnalysisDataContainer *cont)
1401 // Connect input of an existing task to a data container.
1403 Error("ConnectInput", "Task pointer is NULL");
1406 if (!fTasks->FindObject(task)) {
1408 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
1410 Bool_t connected = task->ConnectInput(islot, cont);
1414 //______________________________________________________________________________
1415 Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
1416 AliAnalysisDataContainer *cont)
1418 // Connect output of an existing task to a data container.
1420 Error("ConnectOutput", "Task pointer is NULL");
1423 if (!fTasks->FindObject(task)) {
1425 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
1427 Bool_t connected = task->ConnectOutput(islot, cont);
1431 //______________________________________________________________________________
1432 void AliAnalysisManager::CleanContainers()
1434 // Clean data from all containers that have already finished all client tasks.
1435 TIter next(fContainers);
1436 AliAnalysisDataContainer *cont;
1437 while ((cont=(AliAnalysisDataContainer *)next())) {
1438 if (cont->IsOwnedData() &&
1439 cont->IsDataReady() &&
1440 cont->ClientsExecuted()) cont->DeleteData();
1444 //______________________________________________________________________________
1445 Bool_t AliAnalysisManager::InitAnalysis()
1447 // Initialization of analysis chain of tasks. Should be called after all tasks
1448 // and data containers are properly connected
1449 // Reset flag and remove valid_outputs file if exists
1450 if (fInitOK) return kTRUE;
1451 if (!gSystem->AccessPathName("outputs_valid"))
1452 gSystem->Unlink("outputs_valid");
1453 // Check for top tasks (depending only on input data containers)
1454 if (!fTasks->First()) {
1455 Error("InitAnalysis", "Analysis has no tasks !");
1459 AliAnalysisTask *task;
1460 AliAnalysisDataContainer *cont;
1463 Bool_t iszombie = kFALSE;
1464 Bool_t istop = kTRUE;
1466 while ((task=(AliAnalysisTask*)next())) {
1469 Int_t ninputs = task->GetNinputs();
1470 for (i=0; i<ninputs; i++) {
1471 cont = task->GetInputSlot(i)->GetContainer();
1475 fZombies->Add(task);
1479 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
1480 i, task->GetName());
1482 if (iszombie) continue;
1483 // Check if cont is an input container
1484 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
1485 // Connect to parent task
1489 fTopTasks->Add(task);
1493 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
1496 // Check now if there are orphan tasks
1497 for (i=0; i<ntop; i++) {
1498 task = (AliAnalysisTask*)fTopTasks->At(i);
1503 while ((task=(AliAnalysisTask*)next())) {
1504 if (!task->IsUsed()) {
1506 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
1509 // Check the task hierarchy (no parent task should depend on data provided
1510 // by a daughter task)
1511 for (i=0; i<ntop; i++) {
1512 task = (AliAnalysisTask*)fTopTasks->At(i);
1513 if (task->CheckCircularDeps()) {
1514 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
1519 // Check that all containers feeding post-event loop tasks are in the outputs list
1520 TIter nextcont(fContainers); // loop over all containers
1521 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1522 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1523 if (cont->HasConsumers()) {
1524 // Check if one of the consumers is post event loop
1525 TIter nextconsumer(cont->GetConsumers());
1526 while ((task=(AliAnalysisTask*)nextconsumer())) {
1527 if (task->IsPostEventLoop()) {
1528 fOutputs->Add(cont);
1535 // Check if all special output containers have a file name provided
1536 TIter nextout(fOutputs);
1537 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1538 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1539 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1543 // Initialize requested branch list if needed
1544 if (!fAutoBranchHandling) {
1546 while ((task=(AliAnalysisTask*)next())) {
1547 if (!task->HasBranches()) {
1548 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\"",
1549 task->GetName(), task->ClassName());
1552 if (!fInputEventHandler || !strlen(fInputEventHandler->GetDataType())) {
1553 Error("InitAnalysis", "Manual branch loading requested but no input handler defined or handler does not define data type.");
1556 TString taskbranches;
1557 task->GetBranches(fInputEventHandler->GetDataType(), taskbranches);
1558 if (taskbranches.IsNull()) {
1559 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches of type %s:",
1560 task->GetName(), task->ClassName(), fInputEventHandler->GetDataType());
1563 AddBranches(taskbranches);
1570 //______________________________________________________________________________
1571 void AliAnalysisManager::AddBranches(const char *branches)
1573 // Add branches to the existing fRequestedBranches.
1574 TString br(branches);
1575 TObjArray *arr = br.Tokenize(",");
1578 while ((obj=next())) {
1579 if (!fRequestedBranches.Contains(obj->GetName())) {
1580 if (!fRequestedBranches.IsNull()) fRequestedBranches += ",";
1581 fRequestedBranches += obj->GetName();
1587 //______________________________________________________________________________
1588 void AliAnalysisManager::CheckBranches(Bool_t load)
1590 // The method checks the input branches to be loaded during the analysis.
1591 if (fAutoBranchHandling || fRequestedBranches.IsNull() || !fTree) return;
1592 TObjArray *arr = fRequestedBranches.Tokenize(",");
1595 while ((obj=next())) {
1596 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(obj->GetName()));
1598 br = fTree->GetBranch(obj->GetName());
1600 Error("CheckBranches", "Could not find branch %s",obj->GetName());
1605 if (load && br->GetReadEntry()!=GetCurrentEntry()) {
1606 br->GetEntry(GetCurrentEntry());
1612 //______________________________________________________________________________
1613 Bool_t AliAnalysisManager::CheckTasks() const
1615 // Check consistency of tasks.
1616 Int_t ntasks = fTasks->GetEntries();
1618 Error("CheckTasks", "No tasks connected to the manager. This may be due to forgetting to compile the task or to load their library.");
1621 // Get the pointer to AliAnalysisTaskSE::Class()
1622 TClass *badptr = (TClass*)gROOT->ProcessLine("AliAnalysisTaskSE::Class()");
1623 // Loop all tasks to check if their corresponding library was loaded
1626 while ((obj=next())) {
1627 if (obj->IsA() == badptr) {
1628 Error("CheckTasks", "##################\n \
1629 Class for task %s NOT loaded. You probably forgot to load the library for this task (or compile it dynamically).\n###########################\n",obj->GetName());
1636 //______________________________________________________________________________
1637 void AliAnalysisManager::PrintStatus(Option_t *option) const
1639 // Print task hierarchy.
1641 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1644 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1646 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
1647 TIter next(fTopTasks);
1648 AliAnalysisTask *task;
1649 while ((task=(AliAnalysisTask*)next()))
1650 task->PrintTask(option);
1652 if (!fAutoBranchHandling && !fRequestedBranches.IsNull())
1653 printf("Requested input branches:\n%s\n", fRequestedBranches.Data());
1655 TString sopt(option);
1658 if (sopt.Contains("ALL"))
1660 if ( fOutputEventHandler )
1662 cout << TString('_',78) << endl;
1663 cout << "OutputEventHandler:" << endl;
1664 fOutputEventHandler->Print(" ");
1669 //______________________________________________________________________________
1670 void AliAnalysisManager::ResetAnalysis()
1672 // Reset all execution flags and clean containers.
1676 //______________________________________________________________________________
1677 void AliAnalysisManager::RunLocalInit()
1679 // Run LocalInit method for all tasks.
1680 TDirectory *cdir = gDirectory;
1681 if (IsTrainInitialized()) return;
1682 TIter nextTask(fTasks);
1683 AliAnalysisTask *task;
1684 while ((task=(AliAnalysisTask*)nextTask())) {
1688 if (cdir) cdir->cd();
1689 TObject::SetBit(kTasksInitialized, kTRUE);
1692 //______________________________________________________________________________
1693 Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
1695 // Start analysis having a grid handler.
1696 if (!fGridHandler) {
1697 Error("StartAnalysis", "Cannot start analysis providing just the analysis type without a grid handler.");
1698 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1702 return StartAnalysis(type, tree, nentries, firstentry);
1705 //______________________________________________________________________________
1706 Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
1708 // Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1709 // MIX. Process nentries starting from firstentry
1711 // Backup current directory and make sure gDirectory points to gROOT
1712 TDirectory *cdir = gDirectory;
1715 Error("StartAnalysis","Analysis manager was not initialized !");
1716 if (cdir) cdir->cd();
1719 if (!CheckTasks()) Fatal("StartAnalysis", "Not all needed libraries were loaded");
1721 printf("StartAnalysis %s\n",GetName());
1722 AliLog::SetGlobalLogLevel(AliLog::kInfo);
1724 fMaxEntries = nentries;
1726 TString anaType = type;
1728 fMode = kLocalAnalysis;
1729 if (anaType.Contains("file")) fIsRemote = kTRUE;
1730 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1731 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1732 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1734 if (fMode == kGridAnalysis) {
1736 if (!anaType.Contains("terminate")) {
1737 if (!fGridHandler) {
1738 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1739 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1740 if (cdir) cdir->cd();
1743 // Write analysis manager in the analysis file
1744 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1745 // run local task configuration
1747 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1748 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1749 if (cdir) cdir->cd();
1753 // Terminate grid analysis
1754 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1755 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1756 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1757 if (!fGridHandler->MergeOutputs()) {
1758 // Return if outputs could not be merged or if it alien handler
1759 // was configured for offline mode or local testing.
1760 if (cdir) cdir->cd();
1764 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1765 if (cdir) cdir->cd();
1766 ImportWrappers(NULL);
1768 if (cdir) cdir->cd();
1772 SetEventLoop(kFALSE);
1773 // Enable event loop mode if a tree was provided
1774 if (tree || fGridHandler || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
1777 TString ttype = "TTree";
1778 if (tree && tree->IsA() == TChain::Class()) {
1779 chain = (TChain*)tree;
1780 if (!chain || !chain->GetListOfFiles()->First()) {
1781 Error("StartAnalysis", "Cannot process null or empty chain...");
1782 if (cdir) cdir->cd();
1788 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1789 if (getsysInfo) AliSysInfo::AddStamp("Start", 0);
1790 // Initialize locally all tasks (happens for all modes)
1792 AliAnalysisTask *task;
1796 case kLocalAnalysis:
1797 if (!tree && !fGridHandler) {
1798 TIter nextT(fTasks);
1799 // Call CreateOutputObjects for all tasks
1801 Bool_t dirStatus = TH1::AddDirectoryStatus();
1802 while ((task=(AliAnalysisTask*)nextT())) {
1803 TH1::AddDirectory(kFALSE);
1804 task->CreateOutputObjects();
1805 if (!task->CheckPostData()) {
1806 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
1807 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
1808 ########### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ###########", task->GetName(), task->ClassName());
1810 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
1814 TH1::AddDirectory(dirStatus);
1815 if (IsExternalLoop()) {
1816 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1817 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1824 fSelector = new AliAnalysisSelector(this);
1825 // Check if a plugin handler is used
1827 // Get the chain from the plugin
1828 TString dataType = "esdTree";
1829 if (fInputEventHandler) {
1830 dataType = fInputEventHandler->GetDataType();
1834 chain = fGridHandler->GetChainForTestMode(dataType);
1836 Error("StartAnalysis", "No chain for test mode. Aborting.");
1839 cout << "===== RUNNING LOCAL ANALYSIS" << GetName() << " ON CHAIN " << chain->GetName() << endl;
1840 retv = chain->Process(fSelector, "", nentries, firstentry);
1843 // Run tree-based analysis via AliAnalysisSelector
1844 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
1845 retv = tree->Process(fSelector, "", nentries, firstentry);
1847 case kProofAnalysis:
1849 // Check if the plugin is used
1851 return StartAnalysis(type, fGridHandler->GetProofDataSet(), nentries, firstentry);
1853 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1854 Error("StartAnalysis", "No PROOF!!! Exiting.");
1855 if (cdir) cdir->cd();
1858 line = Form("gProof->AddInput((TObject*)%p);", this);
1859 gROOT->ProcessLine(line);
1862 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
1863 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
1865 Error("StartAnalysis", "No chain!!! Exiting.");
1866 if (cdir) cdir->cd();
1872 if (!anaType.Contains("terminate")) {
1873 if (!fGridHandler) {
1874 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1875 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1876 if (cdir) cdir->cd();
1879 // Write analysis manager in the analysis file
1880 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1881 // Start the analysis via the handler
1882 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1883 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1884 if (cdir) cdir->cd();
1888 // Terminate grid analysis
1889 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1890 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1891 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1892 if (!fGridHandler->MergeOutputs()) {
1893 // Return if outputs could not be merged or if it alien handler
1894 // was configured for offline mode or local testing.
1895 if (cdir) cdir->cd();
1899 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1900 ImportWrappers(NULL);
1902 if (cdir) cdir->cd();
1904 case kMixingAnalysis:
1905 // Run event mixing analysis
1907 Error("StartAnalysis", "Cannot run event mixing without event pool");
1908 if (cdir) cdir->cd();
1911 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1912 fSelector = new AliAnalysisSelector(this);
1913 while ((chain=fEventPool->GetNextChain())) {
1915 // Call NotifyBinChange for all tasks
1916 while ((task=(AliAnalysisTask*)next()))
1917 if (!task->IsPostEventLoop()) task->NotifyBinChange();
1918 retv = chain->Process(fSelector);
1920 Error("StartAnalysis", "Mixing analysis failed");
1921 if (cdir) cdir->cd();
1925 PackOutput(fSelector->GetOutputList());
1928 if (cdir) cdir->cd();
1932 //______________________________________________________________________________
1933 Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
1935 // Start analysis for this manager on a given dataset. Analysis task can be:
1936 // LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1938 Error("StartAnalysis","Analysis manager was not initialized !");
1942 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
1943 TString anaType = type;
1945 if (!anaType.Contains("proof")) {
1946 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
1949 fMode = kProofAnalysis;
1951 TString proofProcessOpt;
1952 SetEventLoop(kTRUE);
1953 // Set the dataset flag
1954 TObject::SetBit(kUseDataSet);
1957 // Start proof analysis using the grid handler
1958 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1959 Error("StartAnalysis", "The grid plugin could not start PROOF analysis");
1962 // Check if the plugin is in test mode
1963 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kTest) {
1964 dataset = "test_collection";
1966 dataset = fGridHandler->GetProofDataSet();
1969 proofProcessOpt = fGridHandler->GetProofProcessOpt();
1972 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1973 Error("StartAnalysis", "No PROOF!!! Exiting.");
1977 // Initialize locally all tasks
1980 line = Form("gProof->AddInput((TObject*)%p);", this);
1981 gROOT->ProcessLine(line);
1983 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"%s\", %lld, %lld);",
1984 dataset,proofProcessOpt.Data(), nentries, firstentry);
1985 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
1986 retv = (Long_t)gROOT->ProcessLine(line);
1990 //______________________________________________________________________________
1991 TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
1993 // Opens according the option the file specified by cont->GetFileName() and changes
1994 // current directory to cont->GetFolderName(). If the file was already opened, it
1995 // checks if the option UPDATE was preserved. File open via TProofOutputFile can
1996 // be optionally ignored.
1997 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1998 TString filename = cont->GetFileName();
2000 if (filename.IsNull()) {
2001 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
2004 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
2006 f = mgr->OpenProofFile(cont,option);
2008 // Check first if the file is already opened
2009 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2011 // Check if option "UPDATE" was preserved
2012 TString opt(option);
2014 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2015 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2017 f = TFile::Open(filename, option);
2020 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2024 // Check for a folder request
2025 TString dir = cont->GetFolderName();
2026 if (!dir.IsNull()) {
2027 if (!f->GetDirectory(dir)) f->mkdir(dir);
2032 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
2033 cont->SetFile(NULL);
2037 //______________________________________________________________________________
2038 TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option, const char *extaod)
2040 // Opens a special output file used in PROOF.
2042 TString filename = cont->GetFileName();
2043 if (cont == fCommonOutput) {
2044 if (fOutputEventHandler) {
2045 if (strlen(extaod)) filename = extaod;
2046 filename = fOutputEventHandler->GetOutputFileName();
2048 else Fatal("OpenProofFile","No output container. Exiting.");
2051 if (fMode!=kProofAnalysis || !fSelector) {
2052 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
2055 if (fSpecialOutputLocation.Length()) {
2056 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2058 // Check if option "UPDATE" was preserved
2059 TString opt(option);
2061 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2062 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2064 f = new TFile(filename, option);
2066 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2070 // Check for a folder request
2071 TString dir = cont->GetFolderName();
2073 if (!f->GetDirectory(dir)) f->mkdir(dir);
2078 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2079 cont->SetFile(NULL);
2082 // Check if there is already a proof output file in the output list
2083 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
2085 // Get the actual file
2086 line = Form("((TProofOutputFile*)%p)->GetFileName();", pof);
2087 filename = (const char*)gROOT->ProcessLine(line);
2089 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
2091 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2093 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
2096 // Check if option "UPDATE" was preserved
2097 TString opt(option);
2099 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2100 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
2102 if (cont->IsRegisterDataset()) {
2103 TString dsetName = filename;
2104 dsetName.ReplaceAll(".root", cont->GetTitle());
2105 dsetName.ReplaceAll(":","_");
2106 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
2107 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
2109 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
2110 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
2112 if (fDebug > 1) printf("=== %s\n", line.Data());
2113 gROOT->ProcessLine(line);
2114 line = Form("pf->OpenFile(\"%s\");", option);
2115 gROOT->ProcessLine(line);
2118 gROOT->ProcessLine("pf->Print()");
2119 printf(" == proof file name: %s", f->GetName());
2121 // Add to proof output list
2122 line = Form("((TList*)%p)->Add(pf);",fSelector->GetOutputList());
2123 if (fDebug > 1) printf("=== %s\n", line.Data());
2124 gROOT->ProcessLine(line);
2126 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2130 // Check for a folder request
2131 TString dir = cont->GetFolderName();
2132 if (!dir.IsNull()) {
2133 if (!f->GetDirectory(dir)) f->mkdir(dir);
2138 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2139 cont->SetFile(NULL);
2143 //______________________________________________________________________________
2144 void AliAnalysisManager::ExecAnalysis(Option_t *option)
2146 // Execute analysis.
2147 static Long64_t nentries = 0;
2148 static TTree *lastTree = 0;
2149 static TStopwatch *timer = new TStopwatch();
2150 // Only the first call to Process will trigger a true Notify. Other Notify
2151 // coming before is ignored.
2152 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) {
2153 TObject::SetBit(AliAnalysisManager::kTrueNotify);
2156 if (fDebug > 0) printf("MGR: Processing event #%d\n", fNcalls);
2158 if (fTree && (fTree != lastTree)) {
2159 nentries += fTree->GetEntries();
2162 if (!fNcalls) timer->Start();
2163 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", fNcalls, TMath::Min(fMaxEntries,nentries), timer, kFALSE);
2165 fIOTimer->Start(kTRUE);
2167 TDirectory *cdir = gDirectory;
2168 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
2169 if (getsysInfo && ((fNcalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)fNcalls);
2171 Error("ExecAnalysis", "Analysis manager was not initialized !");
2172 if (cdir) cdir->cd();
2176 AliAnalysisTask *task;
2177 // Check if the top tree is active.
2179 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2180 AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
2182 // De-activate all tasks
2183 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
2184 AliAnalysisDataContainer *cont = fCommonInput;
2185 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
2187 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
2188 if (cdir) cdir->cd();
2191 cont->SetData(fTree); // This will notify all consumers
2192 Long64_t entry = fTree->GetTree()->GetReadEntry();
2194 // Call BeginEvent() for optional input/output and MC services
2195 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
2196 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
2197 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
2199 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2200 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2202 // Execute the tasks
2203 // TIter next1(cont->GetConsumers());
2205 fIOTime += fIOTimer->RealTime();
2206 fCPUTimer->Start(kTRUE);
2207 TIter next1(fTopTasks);
2209 while ((task=(AliAnalysisTask*)next1())) {
2211 cout << " Executing task " << task->GetName() << endl;
2213 task->ExecuteTask(option);
2215 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2216 AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
2220 fCPUTime += fCPUTimer->RealTime();
2221 fIOTimer->Start(kTRUE);
2223 // Call FinishEvent() for optional output and MC services
2224 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2225 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2226 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2227 // Gather system information if requested
2228 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2229 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1001, 1);
2230 if (cdir) cdir->cd();
2232 fIOTime += fIOTimer->RealTime();
2235 // The event loop is not controlled by TSelector
2237 // Call BeginEvent() for optional input/output and MC services
2238 fIOTimer->Start(kTRUE);
2239 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
2240 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
2241 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
2243 fIOTime += fIOTimer->RealTime();
2245 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2246 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2247 fCPUTimer->Start(kTRUE);
2248 TIter next2(fTopTasks);
2249 while ((task=(AliAnalysisTask*)next2())) {
2250 task->SetActive(kTRUE);
2252 cout << " Executing task " << task->GetName() << endl;
2254 task->ExecuteTask(option);
2258 fCPUTime += fCPUTimer->RealTime();
2260 // Call FinishEvent() for optional output and MC services
2261 fIOTimer->Start(kTRUE);
2262 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2263 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2264 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2265 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2266 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
2267 if (cdir) cdir->cd();
2269 fIOTime += fIOTimer->RealTime();
2272 //______________________________________________________________________________
2273 Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
2275 // Check if the stdout is connected to a pipe (C.Holm)
2276 Bool_t ispipe = kFALSE;
2277 out.seekp(0, std::ios_base::cur);
2280 if (errno == ESPIPE) ispipe = kTRUE;
2285 //______________________________________________________________________________
2286 void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
2288 // Set the input event handler and create a container for it.
2290 fInputEventHandler = handler;
2291 if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
2294 //______________________________________________________________________________
2295 void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
2297 // Set the input event handler and create a container for it.
2299 fOutputEventHandler = handler;
2300 if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
2301 fCommonOutput->SetSpecialOutput();
2304 //______________________________________________________________________________
2305 void AliAnalysisManager::SetDebugLevel(UInt_t level)
2307 // Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
2308 if (TObject::TestBit(kUseProgressBar)) {
2309 Info("SetDebugLevel","Ignored. Disable the progress bar first.");
2315 //______________________________________________________________________________
2316 void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
2318 // Enable a text mode progress bar. Resets debug level to 0.
2319 Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
2320 TObject::SetBit(kUseProgressBar,flag);
2321 fPBUpdateFreq = freq;
2325 //______________________________________________________________________________
2326 void AliAnalysisManager::RegisterExtraFile(const char *fname)
2328 // This method is used externally to register output files which are not
2329 // connected to any output container, so that the manager can properly register,
2330 // retrieve or merge them when running in distributed mode. The file names are
2331 // separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
2332 if (fExtraFiles.Contains(fname)) return;
2333 if (fExtraFiles.Length()) fExtraFiles += " ";
2334 fExtraFiles += fname;
2337 //______________________________________________________________________________
2338 Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
2340 // Copy a file from the location specified ina the wrapper with the same name from the source list.
2344 TObject *pof = source->FindObject(filename);
2345 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
2346 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
2349 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
2350 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
2351 TString clientUrl(chUrl);
2352 TString fullPath_str(fullPath);
2353 if (clientUrl.Contains("localhost")){
2354 TObjArray* array = fullPath_str.Tokenize ( "//" );
2355 TObjString *strobj = ( TObjString *)array->At(1);
2356 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
2357 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
2358 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
2359 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
2360 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
2364 else if (clientUrl.Contains("__lite__")) {
2365 // Special case for ProofLite environement - get file info and copy.
2366 gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
2367 fullPath_str = Form("%s/%s", tmp, fullPath);
2370 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
2371 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
2373 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
2377 //______________________________________________________________________________
2378 void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
2380 // Fill analysis type in the provided string.
2382 case kLocalAnalysis:
2385 case kProofAnalysis:
2391 case kMixingAnalysis:
2396 //______________________________________________________________________________
2397 Bool_t AliAnalysisManager::ValidateOutputFiles() const
2399 // Validate all output files.
2400 TIter next(fOutputs);
2401 AliAnalysisDataContainer *output;
2402 TDirectory *cdir = gDirectory;
2403 TString openedFiles;
2404 while ((output=(AliAnalysisDataContainer*)next())) {
2405 if (output->IsRegisterDataset()) continue;
2406 TString filename = output->GetFileName();
2407 if (filename == "default") {
2408 if (!fOutputEventHandler) continue;
2409 filename = fOutputEventHandler->GetOutputFileName();
2410 // Main AOD may not be there
2411 if (gSystem->AccessPathName(filename)) continue;
2413 // Check if the file is closed
2414 if (openedFiles.Contains(filename)) continue;;
2415 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2417 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
2418 // Clear file list to release object ownership to user.
2422 file = TFile::Open(filename);
2423 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
2424 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
2425 if (cdir) cdir->cd();
2429 openedFiles += filename;
2432 if (cdir) cdir->cd();
2436 //______________________________________________________________________________
2437 void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
2439 // Implements a nice text mode progress bar.
2440 static Long64_t icount = 0;
2441 static TString oname;
2442 static TString nname;
2443 static Long64_t ocurrent = 0;
2444 static Long64_t osize = 0;
2445 static Int_t oseconds = 0;
2446 static TStopwatch *owatch = 0;
2447 static Bool_t oneoftwo = kFALSE;
2448 static Int_t nrefresh = 0;
2449 static Int_t nchecks = 0;
2450 static char lastChar = 0;
2451 const char symbol[4] = {'-','\\','|','/'};
2453 if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
2459 ocurrent = TMath::Abs(current);
2460 osize = TMath::Abs(size);
2461 if (ocurrent > osize) ocurrent=osize;
2466 if ((current % fPBUpdateFreq) != 0) return;
2468 char progress[11] = " ";
2469 Int_t ichar = icount%4;
2474 if (owatch && !last) {
2476 time = owatch->RealTime();
2477 seconds = int(time) % 60;
2478 minutes = (int(time) / 60) % 60;
2479 hours = (int(time) / 60 / 60);
2481 if (oseconds==seconds) {
2485 oneoftwo = !oneoftwo;
2489 if (refresh && oneoftwo) {
2491 if (nchecks <= 0) nchecks = nrefresh+1;
2492 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
2493 oname = Form(" == %d%% ==", pctdone);
2495 Double_t percent = 100.0*ocurrent/osize;
2496 Int_t nchar = Int_t(percent/10);
2497 if (nchar>10) nchar=10;
2499 for (i=0; i<nchar; i++) progress[i] = '=';
2500 progress[nchar] = symbol[ichar];
2501 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2502 progress[10] = '\0';
2505 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2506 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2507 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
2509 Int_t full = Int_t(ocurrent > 0 ?
2510 time * (float(osize)/ocurrent) + .5 :
2512 Int_t remain = Int_t(full - time);
2513 Int_t rsec = remain % 60;
2514 Int_t rmin = (remain / 60) % 60;
2515 Int_t rhour = (remain / 60 / 60);
2516 fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
2517 percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
2519 else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
2520 if (refresh && oneoftwo) oname = nname;
2521 if (owatch) owatch->Continue();
2530 fprintf(stderr, "\n");
2534 //______________________________________________________________________________
2535 void AliAnalysisManager::DoLoadBranch(const char *name)
2537 // Get tree and load branch if needed.
2538 static Long64_t crtEntry = -100;
2540 if (fAutoBranchHandling || !fTree)
2543 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2545 br = fTree->GetBranch(name);
2547 Error("DoLoadBranch", "Could not find branch %s",name);
2552 if (br->GetReadEntry()==fCurrentEntry) return;
2553 Long64_t readbytes = br->GetEntry(GetCurrentEntry());
2555 Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
2556 if (crtEntry != fCurrentEntry) {
2557 CountEvent(1,0,1,0);
2558 crtEntry = fCurrentEntry;
2561 if (crtEntry != fCurrentEntry) {
2562 CountEvent(1,1,0,0);
2563 crtEntry = fCurrentEntry;
2568 //______________________________________________________________________________
2569 void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
2571 // Add the statistics task to the manager.
2573 Info("AddStatisticsTask", "Already added");
2576 TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
2577 gROOT->ProcessLine(line);
2580 //______________________________________________________________________________
2581 void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
2583 // Bookkeep current event;
2584 if (!fStatistics) return;
2585 fStatistics->AddInput(ninput);
2586 fStatistics->AddProcessed(nprocessed);
2587 fStatistics->AddFailed(nfailed);
2588 fStatistics->AddAccepted(naccepted);
2591 //______________________________________________________________________________
2592 void AliAnalysisManager::AddStatisticsMsg(const char *line)
2594 // Add a line in the statistics message. If available, the statistics message is written
2595 // at the end of the SlaveTerminate phase on workers AND at the end of Terminate
2597 if (!strlen(line)) return;
2598 if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
2599 fStatisticsMsg += line;
2602 //______________________________________________________________________________
2603 void AliAnalysisManager::WriteStatisticsMsg(Int_t)
2605 // If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
2606 static Bool_t done = kFALSE;
2609 if (!fStatistics) return;
2611 AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
2612 AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
2613 AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
2614 AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
2615 out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
2616 fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
2617 fStatistics->GetNaccepted()), ios::out);
2618 out << fStatisticsMsg << endl;
2622 //______________________________________________________________________________
2623 const char* AliAnalysisManager::GetOADBPath()
2625 // returns the path of the OADB
2626 // this static function just depends on environment variables
2628 static TString oadbPath;
2630 if (gSystem->Getenv("OADB_PATH"))
2631 oadbPath = gSystem->Getenv("OADB_PATH");
2632 else if (gSystem->Getenv("ALICE_ROOT"))
2633 oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
2635 ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
2640 //______________________________________________________________________________
2641 void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
2643 // Define a custom string variable mapped to a global unique name. The variable
2644 // can be then retrieved by a given analysis macro via GetGlobalStr(key).
2645 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2647 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2650 Bool_t valid = kFALSE;
2651 TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
2653 ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
2656 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
2659 //______________________________________________________________________________
2660 const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
2662 // Static method to retrieve a global variable defined via SetGlobalStr.
2664 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2666 TObject *value = mgr->GetGlobals()->GetValue(key);
2667 if (!value) return 0;
2669 return value->GetName();
2672 //______________________________________________________________________________
2673 void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
2675 // Define a custom integer variable mapped to a global unique name. The variable
2676 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2677 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2679 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2682 Bool_t valid = kFALSE;
2683 Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
2685 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
2688 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
2691 //______________________________________________________________________________
2692 Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
2694 // Static method to retrieve a global variable defined via SetGlobalInt.
2696 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2698 TObject *value = mgr->GetGlobals()->GetValue(key);
2699 if (!value) return 0;
2701 TString s = value->GetName();
2705 //______________________________________________________________________________
2706 void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
2708 // Define a custom double precision variable mapped to a global unique name. The variable
2709 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2710 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2712 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2715 Bool_t valid = kFALSE;
2716 Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
2718 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
2721 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));
2724 //______________________________________________________________________________
2725 Double_t AliAnalysisManager::GetGlobalDbl(const char *key, Bool_t &valid)
2727 // Static method to retrieve a global variable defined via SetGlobalDbl.
2729 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2731 TObject *value = mgr->GetGlobals()->GetValue(key);
2732 if (!value) return 0;
2734 TString s = value->GetName();
2738 //______________________________________________________________________________
2739 void AliAnalysisManager::AddClassDebug(const char *className, Int_t debugLevel)
2741 // Sets Class debug level
2743 if (!fDebugOptions) {
2744 fDebugOptions = new TObjArray();
2745 fDebugOptions->SetOwner(kTRUE);
2748 TNamed *debugOpt = (TNamed*)fDebugOptions->FindObject(className);
2750 AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel,className).Data());
2751 fDebugOptions->Add(new TNamed(className,TString::Format("%d",debugLevel).Data()));
2753 TString oldDebugStr = debugOpt->GetTitle();
2754 Int_t oldDebug = oldDebugStr.Atoi();
2755 if (debugLevel > oldDebug) {
2756 AliWarning(TString::Format("Overwriting debug level to %d class %s, because it is higher then previously set (%d).",debugLevel,className,oldDebug).Data());
2757 debugOpt->SetTitle(TString::Format("%d",debugLevel).Data());
2759 AliWarning(TString::Format("Ignoring debug level to %d class %s, because it is smaller then previously set (%d).",debugLevel,className,oldDebug).Data());
2764 //______________________________________________________________________________
2765 void AliAnalysisManager::ApplyDebugOptions()
2767 // Apply debug options
2769 if (!fDebugOptions) return;
2771 TIter next(fDebugOptions);
2774 while ((debug=dynamic_cast<TNamed*>(next()))) {
2775 debugLevel = debug->GetTitle();
2776 AliInfo(TString::Format("Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()).Data());
2777 AliLog::SetClassDebugLevel(debug->GetName(), debugLevel.Atoi());
2781 //______________________________________________________________________________
2782 Bool_t AliAnalysisManager::IsMacroLoaded(const char filename)
2784 // Check if a macro was loaded.
2785 return fgMacroNames.Contains(filename);
2788 //______________________________________________________________________________
2789 Int_t AliAnalysisManager::LoadMacro(const char *filename, Int_t *error, Bool_t check)
2791 // Redirection of gROOT->LoadMacro which makes sure the same macro is not loaded
2793 TString macroName = gSystem->BaseName(filename);
2794 // Strip appended +, ++, +g, +O
2795 Int_t index = macroName.Index("+");
2796 if (index>0) macroName.Remove(index);
2797 if (fgMacroNames.Contains(macroName)) {
2798 // Macro with the same name loaded already in this root session, do
2803 Int_t ret = gROOT->LoadMacro(filename,error,check);
2804 // In case of error return the error code
2805 if (ret) return ret;
2806 // Append the macro name to the loaded macros list
2807 fgMacroNames += macroName;
2808 fgMacroNames += " ";
2812 //______________________________________________________________________________
2813 void AliAnalysisManager::Lock()
2815 // Security lock. This is to detect NORMAL user errors and not really to
2816 // protect against intentional hacks.
2817 if (fLocked) return;
2819 if (fInputEventHandler) fInputEventHandler->Lock();
2820 if (fOutputEventHandler) fOutputEventHandler->Lock();
2821 if (fMCtruthEventHandler) fMCtruthEventHandler->Lock();
2822 Info("Lock","====== ANALYSIS MANAGER LOCKED ======");
2825 //______________________________________________________________________________
2826 void AliAnalysisManager::UnLock()
2828 // Verbose unlocking. Hackers will be punished ;-) ...
2829 if (!fLocked) return;
2831 if (fInputEventHandler) fInputEventHandler->UnLock();
2832 if (fOutputEventHandler) fOutputEventHandler->UnLock();
2833 if (fMCtruthEventHandler) fMCtruthEventHandler->UnLock();
2834 Info("UnLock", "====== ANALYSIS MANAGER UNLOCKED ======");
2837 //______________________________________________________________________________
2838 void AliAnalysisManager::Changed()
2840 // All critical setters pass through the Changed method that throws an exception
2841 // in case the lock was set.
2842 if (fLocked) Fatal("Changed","Critical setter called in locked mode");