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 void AliAnalysisManager::InputFileFromTree(TTree * const tree, TString &fname)
1695 // Retrieves name of the file from tree
1698 TFile *file = tree->GetCurrentFile();
1701 TChain *chain = dynamic_cast<TChain*>(tree);
1702 if (!chain || !chain->GetNtrees()) return;
1703 basename = gSystem->BaseName(chain->GetListOfFiles()->First()->GetTitle());
1705 basename = gSystem->BaseName(file->GetName());
1707 Int_t index = basename.Index("#");
1708 fname = basename(index+1, basename.Length());
1711 //______________________________________________________________________________
1712 Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
1714 // Start analysis having a grid handler.
1715 if (!fGridHandler) {
1716 Error("StartAnalysis", "Cannot start analysis providing just the analysis type without a grid handler.");
1717 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1721 return StartAnalysis(type, tree, nentries, firstentry);
1724 //______________________________________________________________________________
1725 Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
1727 // Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1728 // MIX. Process nentries starting from firstentry
1730 // Backup current directory and make sure gDirectory points to gROOT
1731 TDirectory *cdir = gDirectory;
1734 Error("StartAnalysis","Analysis manager was not initialized !");
1735 if (cdir) cdir->cd();
1738 if (!CheckTasks()) Fatal("StartAnalysis", "Not all needed libraries were loaded");
1740 printf("StartAnalysis %s\n",GetName());
1741 AliLog::SetGlobalLogLevel(AliLog::kInfo);
1743 fMaxEntries = nentries;
1745 TString anaType = type;
1747 fMode = kLocalAnalysis;
1748 if (anaType.Contains("file")) fIsRemote = kTRUE;
1749 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1750 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1751 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1752 if (fInputEventHandler) {
1754 InputFileFromTree(tree, fname);
1755 if (fname.Length()) fInputEventHandler->SetInputFileName(fname);
1758 if (fMode == kGridAnalysis) {
1760 if (!anaType.Contains("terminate")) {
1761 if (!fGridHandler) {
1762 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1763 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1764 if (cdir) cdir->cd();
1767 // Write analysis manager in the analysis file
1768 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1769 // run local task configuration
1771 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1772 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1773 if (cdir) cdir->cd();
1777 // Terminate grid analysis
1778 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1779 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1780 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1781 if (!fGridHandler->MergeOutputs()) {
1782 // Return if outputs could not be merged or if it alien handler
1783 // was configured for offline mode or local testing.
1784 if (cdir) cdir->cd();
1788 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1789 if (cdir) cdir->cd();
1790 ImportWrappers(NULL);
1792 if (cdir) cdir->cd();
1796 SetEventLoop(kFALSE);
1797 // Enable event loop mode if a tree was provided
1798 if (tree || fGridHandler || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
1801 TString ttype = "TTree";
1802 if (tree && tree->IsA() == TChain::Class()) {
1803 chain = (TChain*)tree;
1804 if (!chain || !chain->GetListOfFiles()->First()) {
1805 Error("StartAnalysis", "Cannot process null or empty chain...");
1806 if (cdir) cdir->cd();
1812 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1813 if (getsysInfo) AliSysInfo::AddStamp("Start", 0);
1814 // Initialize locally all tasks (happens for all modes)
1816 AliAnalysisTask *task;
1820 case kLocalAnalysis:
1821 if (!tree && !fGridHandler) {
1822 TIter nextT(fTasks);
1823 // Call CreateOutputObjects for all tasks
1825 Bool_t dirStatus = TH1::AddDirectoryStatus();
1826 while ((task=(AliAnalysisTask*)nextT())) {
1827 TH1::AddDirectory(kFALSE);
1828 task->CreateOutputObjects();
1829 if (!task->CheckPostData()) {
1830 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
1831 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
1832 ########### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ###########", task->GetName(), task->ClassName());
1834 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
1838 TH1::AddDirectory(dirStatus);
1839 if (IsExternalLoop()) {
1840 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1841 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1848 fSelector = new AliAnalysisSelector(this);
1849 // Check if a plugin handler is used
1851 // Get the chain from the plugin
1852 TString dataType = "esdTree";
1853 if (fInputEventHandler) {
1854 dataType = fInputEventHandler->GetDataType();
1858 chain = fGridHandler->GetChainForTestMode(dataType);
1860 Error("StartAnalysis", "No chain for test mode. Aborting.");
1863 cout << "===== RUNNING LOCAL ANALYSIS" << GetName() << " ON CHAIN " << chain->GetName() << endl;
1864 retv = chain->Process(fSelector, "", nentries, firstentry);
1867 // Run tree-based analysis via AliAnalysisSelector
1868 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
1869 retv = tree->Process(fSelector, "", nentries, firstentry);
1871 case kProofAnalysis:
1873 // Check if the plugin is used
1875 return StartAnalysis(type, fGridHandler->GetProofDataSet(), nentries, firstentry);
1877 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1878 Error("StartAnalysis", "No PROOF!!! Exiting.");
1879 if (cdir) cdir->cd();
1882 line = Form("gProof->AddInput((TObject*)%p);", this);
1883 gROOT->ProcessLine(line);
1886 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
1887 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
1889 Error("StartAnalysis", "No chain!!! Exiting.");
1890 if (cdir) cdir->cd();
1896 if (!anaType.Contains("terminate")) {
1897 if (!fGridHandler) {
1898 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1899 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1900 if (cdir) cdir->cd();
1903 // Write analysis manager in the analysis file
1904 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1905 // Start the analysis via the handler
1906 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1907 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1908 if (cdir) cdir->cd();
1912 // Terminate grid analysis
1913 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1914 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1915 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1916 if (!fGridHandler->MergeOutputs()) {
1917 // Return if outputs could not be merged or if it alien handler
1918 // was configured for offline mode or local testing.
1919 if (cdir) cdir->cd();
1923 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1924 ImportWrappers(NULL);
1926 if (cdir) cdir->cd();
1928 case kMixingAnalysis:
1929 // Run event mixing analysis
1931 Error("StartAnalysis", "Cannot run event mixing without event pool");
1932 if (cdir) cdir->cd();
1935 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1936 fSelector = new AliAnalysisSelector(this);
1937 while ((chain=fEventPool->GetNextChain())) {
1939 // Call NotifyBinChange for all tasks
1940 while ((task=(AliAnalysisTask*)next()))
1941 if (!task->IsPostEventLoop()) task->NotifyBinChange();
1942 retv = chain->Process(fSelector);
1944 Error("StartAnalysis", "Mixing analysis failed");
1945 if (cdir) cdir->cd();
1949 PackOutput(fSelector->GetOutputList());
1952 if (cdir) cdir->cd();
1956 //______________________________________________________________________________
1957 Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
1959 // Start analysis for this manager on a given dataset. Analysis task can be:
1960 // LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1962 Error("StartAnalysis","Analysis manager was not initialized !");
1966 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
1967 TString anaType = type;
1969 if (!anaType.Contains("proof")) {
1970 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
1973 fMode = kProofAnalysis;
1975 TString proofProcessOpt;
1976 SetEventLoop(kTRUE);
1977 // Set the dataset flag
1978 TObject::SetBit(kUseDataSet);
1981 // Start proof analysis using the grid handler
1982 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1983 Error("StartAnalysis", "The grid plugin could not start PROOF analysis");
1986 // Check if the plugin is in test mode
1987 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kTest) {
1988 dataset = "test_collection";
1990 dataset = fGridHandler->GetProofDataSet();
1993 proofProcessOpt = fGridHandler->GetProofProcessOpt();
1996 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1997 Error("StartAnalysis", "No PROOF!!! Exiting.");
2001 // Initialize locally all tasks
2004 line = Form("gProof->AddInput((TObject*)%p);", this);
2005 gROOT->ProcessLine(line);
2007 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"%s\", %lld, %lld);",
2008 dataset,proofProcessOpt.Data(), nentries, firstentry);
2009 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
2010 retv = (Long_t)gROOT->ProcessLine(line);
2014 //______________________________________________________________________________
2015 TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
2017 // Opens according the option the file specified by cont->GetFileName() and changes
2018 // current directory to cont->GetFolderName(). If the file was already opened, it
2019 // checks if the option UPDATE was preserved. File open via TProofOutputFile can
2020 // be optionally ignored.
2021 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2022 TString filename = cont->GetFileName();
2024 if (filename.IsNull()) {
2025 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
2028 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
2030 f = mgr->OpenProofFile(cont,option);
2032 // Check first if the file is already opened
2033 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2035 // Check if option "UPDATE" was preserved
2036 TString opt(option);
2038 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2039 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2041 f = TFile::Open(filename, option);
2044 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2048 // Check for a folder request
2049 TString dir = cont->GetFolderName();
2050 if (!dir.IsNull()) {
2051 if (!f->GetDirectory(dir)) f->mkdir(dir);
2056 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
2057 cont->SetFile(NULL);
2061 //______________________________________________________________________________
2062 TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option, const char *extaod)
2064 // Opens a special output file used in PROOF.
2066 TString filename = cont->GetFileName();
2067 if (cont == fCommonOutput) {
2068 if (fOutputEventHandler) {
2069 if (strlen(extaod)) filename = extaod;
2070 filename = fOutputEventHandler->GetOutputFileName();
2072 else Fatal("OpenProofFile","No output container. Exiting.");
2075 if (fMode!=kProofAnalysis || !fSelector) {
2076 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
2079 if (fSpecialOutputLocation.Length()) {
2080 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2082 // Check if option "UPDATE" was preserved
2083 TString opt(option);
2085 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2086 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2088 f = new TFile(filename, option);
2090 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2094 // Check for a folder request
2095 TString dir = cont->GetFolderName();
2097 if (!f->GetDirectory(dir)) f->mkdir(dir);
2102 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2103 cont->SetFile(NULL);
2106 // Check if there is already a proof output file in the output list
2107 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
2109 // Get the actual file
2110 line = Form("((TProofOutputFile*)%p)->GetFileName();", pof);
2111 filename = (const char*)gROOT->ProcessLine(line);
2113 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
2115 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2117 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
2120 // Check if option "UPDATE" was preserved
2121 TString opt(option);
2123 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2124 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
2126 if (cont->IsRegisterDataset()) {
2127 TString dsetName = filename;
2128 dsetName.ReplaceAll(".root", cont->GetTitle());
2129 dsetName.ReplaceAll(":","_");
2130 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
2131 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
2133 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
2134 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
2136 if (fDebug > 1) printf("=== %s\n", line.Data());
2137 gROOT->ProcessLine(line);
2138 line = Form("pf->OpenFile(\"%s\");", option);
2139 gROOT->ProcessLine(line);
2142 gROOT->ProcessLine("pf->Print()");
2143 printf(" == proof file name: %s", f->GetName());
2145 // Add to proof output list
2146 line = Form("((TList*)%p)->Add(pf);",fSelector->GetOutputList());
2147 if (fDebug > 1) printf("=== %s\n", line.Data());
2148 gROOT->ProcessLine(line);
2150 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2154 // Check for a folder request
2155 TString dir = cont->GetFolderName();
2156 if (!dir.IsNull()) {
2157 if (!f->GetDirectory(dir)) f->mkdir(dir);
2162 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2163 cont->SetFile(NULL);
2167 //______________________________________________________________________________
2168 void AliAnalysisManager::ExecAnalysis(Option_t *option)
2170 // Execute analysis.
2171 static Long64_t nentries = 0;
2172 static TTree *lastTree = 0;
2173 static TStopwatch *timer = new TStopwatch();
2174 // Only the first call to Process will trigger a true Notify. Other Notify
2175 // coming before is ignored.
2176 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) {
2177 TObject::SetBit(AliAnalysisManager::kTrueNotify);
2180 if (fDebug > 0) printf("MGR: Processing event #%d\n", fNcalls);
2182 if (fTree && (fTree != lastTree)) {
2183 nentries += fTree->GetEntries();
2186 if (!fNcalls) timer->Start();
2187 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", fNcalls, TMath::Min(fMaxEntries,nentries), timer, kFALSE);
2189 fIOTimer->Start(kTRUE);
2191 TDirectory *cdir = gDirectory;
2192 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
2193 if (getsysInfo && ((fNcalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)fNcalls);
2195 Error("ExecAnalysis", "Analysis manager was not initialized !");
2196 if (cdir) cdir->cd();
2200 AliAnalysisTask *task;
2201 // Check if the top tree is active.
2203 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2204 AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
2206 // De-activate all tasks
2207 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
2208 AliAnalysisDataContainer *cont = fCommonInput;
2209 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
2211 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
2212 if (cdir) cdir->cd();
2215 cont->SetData(fTree); // This will notify all consumers
2216 Long64_t entry = fTree->GetTree()->GetReadEntry();
2218 // Call BeginEvent() for optional input/output and MC services
2219 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
2220 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
2221 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
2223 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2224 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2226 // Execute the tasks
2227 // TIter next1(cont->GetConsumers());
2229 fIOTime += fIOTimer->RealTime();
2230 fCPUTimer->Start(kTRUE);
2231 TIter next1(fTopTasks);
2233 while ((task=(AliAnalysisTask*)next1())) {
2235 cout << " Executing task " << task->GetName() << endl;
2237 task->ExecuteTask(option);
2239 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2240 AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
2244 fCPUTime += fCPUTimer->RealTime();
2245 fIOTimer->Start(kTRUE);
2247 // Call FinishEvent() for optional output and MC services
2248 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2249 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2250 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2251 // Gather system information if requested
2252 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2253 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1001, 1);
2254 if (cdir) cdir->cd();
2256 fIOTime += fIOTimer->RealTime();
2259 // The event loop is not controlled by TSelector
2261 // Call BeginEvent() for optional input/output and MC services
2262 fIOTimer->Start(kTRUE);
2263 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
2264 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
2265 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
2267 fIOTime += fIOTimer->RealTime();
2269 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2270 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2271 fCPUTimer->Start(kTRUE);
2272 TIter next2(fTopTasks);
2273 while ((task=(AliAnalysisTask*)next2())) {
2274 task->SetActive(kTRUE);
2276 cout << " Executing task " << task->GetName() << endl;
2278 task->ExecuteTask(option);
2282 fCPUTime += fCPUTimer->RealTime();
2284 // Call FinishEvent() for optional output and MC services
2285 fIOTimer->Start(kTRUE);
2286 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2287 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2288 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2289 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2290 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
2291 if (cdir) cdir->cd();
2293 fIOTime += fIOTimer->RealTime();
2296 //______________________________________________________________________________
2297 Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
2299 // Check if the stdout is connected to a pipe (C.Holm)
2300 Bool_t ispipe = kFALSE;
2301 out.seekp(0, std::ios_base::cur);
2304 if (errno == ESPIPE) ispipe = kTRUE;
2309 //______________________________________________________________________________
2310 void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
2312 // Set the input event handler and create a container for it.
2314 fInputEventHandler = handler;
2315 if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
2318 //______________________________________________________________________________
2319 void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
2321 // Set the input event handler and create a container for it.
2323 fOutputEventHandler = handler;
2324 if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
2325 fCommonOutput->SetSpecialOutput();
2328 //______________________________________________________________________________
2329 void AliAnalysisManager::SetDebugLevel(UInt_t level)
2331 // Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
2332 if (TObject::TestBit(kUseProgressBar)) {
2333 Info("SetDebugLevel","Ignored. Disable the progress bar first.");
2339 //______________________________________________________________________________
2340 void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
2342 // Enable a text mode progress bar. Resets debug level to 0.
2343 Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
2344 TObject::SetBit(kUseProgressBar,flag);
2345 fPBUpdateFreq = freq;
2349 //______________________________________________________________________________
2350 void AliAnalysisManager::RegisterExtraFile(const char *fname)
2352 // This method is used externally to register output files which are not
2353 // connected to any output container, so that the manager can properly register,
2354 // retrieve or merge them when running in distributed mode. The file names are
2355 // separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
2356 if (fExtraFiles.Contains(fname)) return;
2357 if (fExtraFiles.Length()) fExtraFiles += " ";
2358 fExtraFiles += fname;
2361 //______________________________________________________________________________
2362 Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
2364 // Copy a file from the location specified ina the wrapper with the same name from the source list.
2368 TObject *pof = source->FindObject(filename);
2369 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
2370 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
2373 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
2374 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
2375 TString clientUrl(chUrl);
2376 TString fullPath_str(fullPath);
2377 if (clientUrl.Contains("localhost")){
2378 TObjArray* array = fullPath_str.Tokenize ( "//" );
2379 TObjString *strobj = ( TObjString *)array->At(1);
2380 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
2381 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
2382 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
2383 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
2384 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
2388 else if (clientUrl.Contains("__lite__")) {
2389 // Special case for ProofLite environement - get file info and copy.
2390 gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
2391 fullPath_str = Form("%s/%s", tmp, fullPath);
2394 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
2395 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
2397 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
2401 //______________________________________________________________________________
2402 void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
2404 // Fill analysis type in the provided string.
2406 case kLocalAnalysis:
2409 case kProofAnalysis:
2415 case kMixingAnalysis:
2420 //______________________________________________________________________________
2421 Bool_t AliAnalysisManager::ValidateOutputFiles() const
2423 // Validate all output files.
2424 TIter next(fOutputs);
2425 AliAnalysisDataContainer *output;
2426 TDirectory *cdir = gDirectory;
2427 TString openedFiles;
2428 while ((output=(AliAnalysisDataContainer*)next())) {
2429 if (output->IsRegisterDataset()) continue;
2430 TString filename = output->GetFileName();
2431 if (filename == "default") {
2432 if (!fOutputEventHandler) continue;
2433 filename = fOutputEventHandler->GetOutputFileName();
2434 // Main AOD may not be there
2435 if (gSystem->AccessPathName(filename)) continue;
2437 // Check if the file is closed
2438 if (openedFiles.Contains(filename)) continue;;
2439 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2441 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
2442 // Clear file list to release object ownership to user.
2446 file = TFile::Open(filename);
2447 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
2448 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
2449 if (cdir) cdir->cd();
2453 openedFiles += filename;
2456 if (cdir) cdir->cd();
2460 //______________________________________________________________________________
2461 void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
2463 // Implements a nice text mode progress bar.
2464 static Long64_t icount = 0;
2465 static TString oname;
2466 static TString nname;
2467 static Long64_t ocurrent = 0;
2468 static Long64_t osize = 0;
2469 static Int_t oseconds = 0;
2470 static TStopwatch *owatch = 0;
2471 static Bool_t oneoftwo = kFALSE;
2472 static Int_t nrefresh = 0;
2473 static Int_t nchecks = 0;
2474 static char lastChar = 0;
2475 const char symbol[4] = {'-','\\','|','/'};
2477 if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
2483 ocurrent = TMath::Abs(current);
2484 osize = TMath::Abs(size);
2485 if (ocurrent > osize) ocurrent=osize;
2490 if ((current % fPBUpdateFreq) != 0) return;
2492 char progress[11] = " ";
2493 Int_t ichar = icount%4;
2498 if (owatch && !last) {
2500 time = owatch->RealTime();
2501 seconds = int(time) % 60;
2502 minutes = (int(time) / 60) % 60;
2503 hours = (int(time) / 60 / 60);
2505 if (oseconds==seconds) {
2509 oneoftwo = !oneoftwo;
2513 if (refresh && oneoftwo) {
2515 if (nchecks <= 0) nchecks = nrefresh+1;
2516 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
2517 oname = Form(" == %d%% ==", pctdone);
2519 Double_t percent = 100.0*ocurrent/osize;
2520 Int_t nchar = Int_t(percent/10);
2521 if (nchar>10) nchar=10;
2523 for (i=0; i<nchar; i++) progress[i] = '=';
2524 progress[nchar] = symbol[ichar];
2525 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2526 progress[10] = '\0';
2529 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2530 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2531 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
2533 Int_t full = Int_t(ocurrent > 0 ?
2534 time * (float(osize)/ocurrent) + .5 :
2536 Int_t remain = Int_t(full - time);
2537 Int_t rsec = remain % 60;
2538 Int_t rmin = (remain / 60) % 60;
2539 Int_t rhour = (remain / 60 / 60);
2540 fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
2541 percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
2543 else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
2544 if (refresh && oneoftwo) oname = nname;
2545 if (owatch) owatch->Continue();
2554 fprintf(stderr, "\n");
2558 //______________________________________________________________________________
2559 void AliAnalysisManager::DoLoadBranch(const char *name)
2561 // Get tree and load branch if needed.
2562 static Long64_t crtEntry = -100;
2564 if (fAutoBranchHandling || !fTree)
2567 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2569 br = fTree->GetBranch(name);
2571 Error("DoLoadBranch", "Could not find branch %s",name);
2576 if (br->GetReadEntry()==fCurrentEntry) return;
2577 Long64_t readbytes = br->GetEntry(GetCurrentEntry());
2579 Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
2580 if (crtEntry != fCurrentEntry) {
2581 CountEvent(1,0,1,0);
2582 crtEntry = fCurrentEntry;
2585 if (crtEntry != fCurrentEntry) {
2586 CountEvent(1,1,0,0);
2587 crtEntry = fCurrentEntry;
2592 //______________________________________________________________________________
2593 void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
2595 // Add the statistics task to the manager.
2597 Info("AddStatisticsTask", "Already added");
2600 TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
2601 gROOT->ProcessLine(line);
2604 //______________________________________________________________________________
2605 void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
2607 // Bookkeep current event;
2608 if (!fStatistics) return;
2609 fStatistics->AddInput(ninput);
2610 fStatistics->AddProcessed(nprocessed);
2611 fStatistics->AddFailed(nfailed);
2612 fStatistics->AddAccepted(naccepted);
2615 //______________________________________________________________________________
2616 void AliAnalysisManager::AddStatisticsMsg(const char *line)
2618 // Add a line in the statistics message. If available, the statistics message is written
2619 // at the end of the SlaveTerminate phase on workers AND at the end of Terminate
2621 if (!strlen(line)) return;
2622 if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
2623 fStatisticsMsg += line;
2626 //______________________________________________________________________________
2627 void AliAnalysisManager::WriteStatisticsMsg(Int_t)
2629 // If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
2630 static Bool_t done = kFALSE;
2633 if (!fStatistics) return;
2635 AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
2636 AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
2637 AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
2638 AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
2639 out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
2640 fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
2641 fStatistics->GetNaccepted()), ios::out);
2642 out << fStatisticsMsg << endl;
2646 //______________________________________________________________________________
2647 const char* AliAnalysisManager::GetOADBPath()
2649 // returns the path of the OADB
2650 // this static function just depends on environment variables
2652 static TString oadbPath;
2654 if (gSystem->Getenv("OADB_PATH"))
2655 oadbPath = gSystem->Getenv("OADB_PATH");
2656 else if (gSystem->Getenv("ALICE_ROOT"))
2657 oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
2659 ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
2664 //______________________________________________________________________________
2665 void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
2667 // Define a custom string variable mapped to a global unique name. The variable
2668 // can be then retrieved by a given analysis macro via GetGlobalStr(key).
2669 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2671 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2674 Bool_t valid = kFALSE;
2675 TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
2677 ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
2680 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
2683 //______________________________________________________________________________
2684 const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
2686 // Static method to retrieve a global variable defined via SetGlobalStr.
2688 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2690 TObject *value = mgr->GetGlobals()->GetValue(key);
2691 if (!value) return 0;
2693 return value->GetName();
2696 //______________________________________________________________________________
2697 void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
2699 // Define a custom integer variable mapped to a global unique name. The variable
2700 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2701 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2703 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2706 Bool_t valid = kFALSE;
2707 Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
2709 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
2712 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
2715 //______________________________________________________________________________
2716 Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
2718 // Static method to retrieve a global variable defined via SetGlobalInt.
2720 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2722 TObject *value = mgr->GetGlobals()->GetValue(key);
2723 if (!value) return 0;
2725 TString s = value->GetName();
2729 //______________________________________________________________________________
2730 void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
2732 // Define a custom double precision variable mapped to a global unique name. The variable
2733 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2734 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2736 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2739 Bool_t valid = kFALSE;
2740 Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
2742 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
2745 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));
2748 //______________________________________________________________________________
2749 Double_t AliAnalysisManager::GetGlobalDbl(const char *key, Bool_t &valid)
2751 // Static method to retrieve a global variable defined via SetGlobalDbl.
2753 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2755 TObject *value = mgr->GetGlobals()->GetValue(key);
2756 if (!value) return 0;
2758 TString s = value->GetName();
2762 //______________________________________________________________________________
2763 void AliAnalysisManager::AddClassDebug(const char *className, Int_t debugLevel)
2765 // Sets Class debug level
2767 if (!fDebugOptions) {
2768 fDebugOptions = new TObjArray();
2769 fDebugOptions->SetOwner(kTRUE);
2772 TNamed *debugOpt = (TNamed*)fDebugOptions->FindObject(className);
2774 AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel,className).Data());
2775 fDebugOptions->Add(new TNamed(className,TString::Format("%d",debugLevel).Data()));
2777 TString oldDebugStr = debugOpt->GetTitle();
2778 Int_t oldDebug = oldDebugStr.Atoi();
2779 if (debugLevel > oldDebug) {
2780 AliWarning(TString::Format("Overwriting debug level to %d class %s, because it is higher then previously set (%d).",debugLevel,className,oldDebug).Data());
2781 debugOpt->SetTitle(TString::Format("%d",debugLevel).Data());
2783 AliWarning(TString::Format("Ignoring debug level to %d class %s, because it is smaller then previously set (%d).",debugLevel,className,oldDebug).Data());
2788 //______________________________________________________________________________
2789 void AliAnalysisManager::ApplyDebugOptions()
2791 // Apply debug options
2793 if (!fDebugOptions) return;
2795 TIter next(fDebugOptions);
2798 while ((debug=dynamic_cast<TNamed*>(next()))) {
2799 debugLevel = debug->GetTitle();
2800 AliInfo(TString::Format("Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()).Data());
2801 AliLog::SetClassDebugLevel(debug->GetName(), debugLevel.Atoi());
2805 //______________________________________________________________________________
2806 Bool_t AliAnalysisManager::IsMacroLoaded(const char filename)
2808 // Check if a macro was loaded.
2809 return fgMacroNames.Contains(filename);
2812 //______________________________________________________________________________
2813 Int_t AliAnalysisManager::LoadMacro(const char *filename, Int_t *error, Bool_t check)
2815 // Redirection of gROOT->LoadMacro which makes sure the same macro is not loaded
2817 TString macroName = gSystem->BaseName(filename);
2818 // Strip appended +, ++, +g, +O
2819 Int_t index = macroName.Index("+");
2820 if (index>0) macroName.Remove(index);
2821 if (fgMacroNames.Contains(macroName)) {
2822 // Macro with the same name loaded already in this root session, do
2827 Int_t ret = gROOT->LoadMacro(filename,error,check);
2828 // In case of error return the error code
2829 if (ret) return ret;
2830 // Append the macro name to the loaded macros list
2831 fgMacroNames += macroName;
2832 fgMacroNames += " ";
2836 //______________________________________________________________________________
2837 void AliAnalysisManager::Lock()
2839 // Security lock. This is to detect NORMAL user errors and not really to
2840 // protect against intentional hacks.
2841 if (fLocked) return;
2843 if (fInputEventHandler) fInputEventHandler->Lock();
2844 if (fOutputEventHandler) fOutputEventHandler->Lock();
2845 if (fMCtruthEventHandler) fMCtruthEventHandler->Lock();
2846 Info("Lock","====== ANALYSIS MANAGER LOCKED ======");
2849 //______________________________________________________________________________
2850 void AliAnalysisManager::UnLock()
2852 // Verbose unlocking. Hackers will be punished ;-) ...
2853 if (!fLocked) return;
2855 if (fInputEventHandler) fInputEventHandler->UnLock();
2856 if (fOutputEventHandler) fOutputEventHandler->UnLock();
2857 if (fMCtruthEventHandler) fMCtruthEventHandler->UnLock();
2858 Info("UnLock", "====== ANALYSIS MANAGER UNLOCKED ======");
2861 //______________________________________________________________________________
2862 void AliAnalysisManager::Changed()
2864 // All critical setters pass through the Changed method that throws an exception
2865 // in case the lock was set.
2866 if (fLocked) Fatal("Changed","Critical setter called in locked mode");