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),
86 fSpecialOutputLocation(""),
95 fFileDescriptors(new TObjArray()),
96 fCurrentDescriptor(0),
103 fAutoBranchHandling(kTRUE),
104 fAsyncReading(kFALSE), // default prefetching on
109 fCacheSize(100000000), // default 100 MB
111 fRequestedBranches(),
121 // Default constructor.
122 fgAnalysisManager = this;
123 fgCommonFileName = "AnalysisResults.root";
124 if (TClass::IsCallingNew() != TClass::kDummyNew) {
125 fTasks = new TObjArray();
126 fTopTasks = new TObjArray();
127 fZombies = new TObjArray();
128 fContainers = new TObjArray();
129 fInputs = new TObjArray();
130 fOutputs = new TObjArray();
131 fParamCont = new TObjArray();
132 fGlobals = new TMap();
134 fIOTimer = new TStopwatch();
135 fCPUTimer = new TStopwatch();
136 fInitTimer = new TStopwatch();
140 //______________________________________________________________________________
141 AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
144 fInputEventHandler(NULL),
145 fOutputEventHandler(NULL),
146 fMCtruthEventHandler(NULL),
151 fInitOK(other.fInitOK),
152 fMustClean(other.fMustClean),
153 fIsRemote(other.fIsRemote),
154 fLocked(other.fLocked),
155 fMCLoop(other.fMCLoop),
156 fDebug(other.fDebug),
157 fSpecialOutputLocation(""),
166 fFileDescriptors(new TObjArray()),
167 fCurrentDescriptor(0),
172 fExtraFiles(other.fExtraFiles),
173 fFileInfoLog(other.fFileInfoLog),
174 fAutoBranchHandling(other.fAutoBranchHandling),
175 fAsyncReading(other.fAsyncReading),
178 fNcalls(other.fNcalls),
179 fMaxEntries(other.fMaxEntries),
180 fCacheSize(other.fCacheSize),
181 fStatisticsMsg(other.fStatisticsMsg),
182 fRequestedBranches(other.fRequestedBranches),
183 fStatistics(other.fStatistics),
184 fGlobals(other.fGlobals),
185 fIOTimer(new TStopwatch()),
186 fCPUTimer(new TStopwatch()),
187 fInitTimer(new TStopwatch()),
193 fTasks = new TObjArray(*other.fTasks);
194 fTopTasks = new TObjArray(*other.fTopTasks);
195 fZombies = new TObjArray(*other.fZombies);
196 fContainers = new TObjArray(*other.fContainers);
197 fInputs = new TObjArray(*other.fInputs);
198 fOutputs = new TObjArray(*other.fOutputs);
199 fParamCont = new TObjArray(*other.fParamCont);
200 fgCommonFileName = "AnalysisResults.root";
201 fgAnalysisManager = this;
204 //______________________________________________________________________________
205 AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& other)
208 if (&other != this) {
209 TNamed::operator=(other);
210 fInputEventHandler = other.fInputEventHandler;
211 fOutputEventHandler = other.fOutputEventHandler;
212 fMCtruthEventHandler = other.fMCtruthEventHandler;
213 fEventPool = other.fEventPool;
216 fNSysInfo = other.fNSysInfo;
218 fInitOK = other.fInitOK;
219 fIsRemote = other.fIsRemote;
220 fLocked = other.fLocked;
221 fMCLoop = other.fMCLoop;
222 fDebug = other.fDebug;
223 fTasks = new TObjArray(*other.fTasks);
224 fTopTasks = new TObjArray(*other.fTopTasks);
225 fZombies = new TObjArray(*other.fZombies);
226 fContainers = new TObjArray(*other.fContainers);
227 fInputs = new TObjArray(*other.fInputs);
228 fOutputs = new TObjArray(*other.fOutputs);
229 fParamCont = new TObjArray(*other.fParamCont);
230 fDebugOptions = NULL;
231 fFileDescriptors = new TObjArray();
232 fCurrentDescriptor = 0;
234 fCommonOutput = NULL;
237 fExtraFiles = other.fExtraFiles;
238 fFileInfoLog = other.fFileInfoLog;
239 fgCommonFileName = "AnalysisResults.root";
240 fgAnalysisManager = this;
241 fAutoBranchHandling = other.fAutoBranchHandling;
242 fAsyncReading = other.fAsyncReading;
243 fTable.Clear("nodelete");
244 fRunFromPath = other.fRunFromPath;
245 fNcalls = other. fNcalls;
246 fMaxEntries = other.fMaxEntries;
247 fCacheSize = other.fCacheSize;
248 fStatisticsMsg = other.fStatisticsMsg;
249 fRequestedBranches = other.fRequestedBranches;
250 fStatistics = other.fStatistics;
251 fGlobals = new TMap();
252 fIOTimer = new TStopwatch();
253 fCPUTimer = new TStopwatch();
254 fInitTimer = new TStopwatch();
262 //______________________________________________________________________________
263 AliAnalysisManager::~AliAnalysisManager()
266 if (fTasks) {fTasks->Delete(); delete fTasks;}
267 if (fTopTasks) delete fTopTasks;
268 if (fZombies) delete fZombies;
269 if (fContainers) {fContainers->Delete(); delete fContainers;}
270 if (fInputs) delete fInputs;
271 if (fOutputs) delete fOutputs;
272 if (fParamCont) delete fParamCont;
273 if (fDebugOptions) delete fDebugOptions;
274 if (fGridHandler) delete fGridHandler;
275 if (fInputEventHandler) delete fInputEventHandler;
276 if (fOutputEventHandler) delete fOutputEventHandler;
277 if (fMCtruthEventHandler) delete fMCtruthEventHandler;
278 if (fEventPool) delete fEventPool;
279 if (fgAnalysisManager==this) fgAnalysisManager = NULL;
280 if (fGlobals) {fGlobals->DeleteAll(); delete fGlobals;}
281 if (fFileDescriptors) {fFileDescriptors->Delete(); delete fFileDescriptors;}
287 //______________________________________________________________________________
288 void AliAnalysisManager::CreateReadCache()
290 // Create cache for reading according fCacheSize and fAsyncReading.
291 if (!fTree || !fTree->GetCurrentFile()) {
292 Error("CreateReadCache","Current tree or tree file not yet defined");
296 if (fDebug) Info("CreateReadCache","=== Read caching disabled ===");
299 gEnv->SetValue("TFile.AsyncPrefetching",(Int_t)fAsyncReading);
300 if (fAsyncReading) gEnv->SetValue("Cache.Directory",Form("file://%s/cache", gSystem->WorkingDirectory()));
301 if (fAsyncReading) gEnv->SetValue("TFile.AsyncReading",1);
302 fTree->SetCacheSize(fCacheSize);
303 TTreeCache::SetLearnEntries(1); //<<< we can take the decision after 1 entry
304 fTree->AddBranchToCache("*",kTRUE); //<<< add all branches to the cache
306 Info("CreateReadCache","Read cache enabled %lld bytes with async reading=%d",fCacheSize, (Int_t)fAsyncReading);
311 //______________________________________________________________________________
312 Bool_t AliAnalysisManager::EventLoop(Long64_t nevents)
314 // Initialize an event loop where the data producer is the input handler
315 // The handler must implement MakeTree creating the tree of events (likely
316 // memory resident) and generate the current event in the method BeginEvent.
317 // If the tree is memory resident, the handler should never call TTree::Fill
319 cout << "===== RUNNING IN EVENT LOOP MODE: " << GetName() << endl;
320 if (!fInputEventHandler) {
321 Error("EventLoop", "No input handler: exiting");
324 TTree *tree = new TTree("DummyTree", "Dummy tree for AliAnalysisManager::EventLoop");
325 SetExternalLoop(kTRUE);
326 if (!Init(tree)) return kFALSE;
328 for (Long64_t iev=0; iev<nevents; iev++)
331 PackOutput(&dummyList);
337 //______________________________________________________________________________
338 Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
340 // Read one entry of the tree or a whole branch.
341 fCurrentEntry = entry;
342 if (!fAutoBranchHandling)
344 if (!fTree || !fTree->GetTree()) return -1;
345 fIOTimer->Start(kTRUE);
346 Long64_t readbytes = fTree->GetTree()->GetEntry(entry, getall);
348 fIOTime += fIOTimer->RealTime();
349 return (Int_t)readbytes;
352 //______________________________________________________________________________
353 Int_t AliAnalysisManager::GetRunFromAlienPath(const char *path)
355 // Attempt to extract run number from input data path. Works only for paths to
356 // alice data in alien.
357 // sim: /alice/sim/<production>/run_no/...
358 // data: /alice/data/year/period/000run_no/... (ESD or AOD)
359 TString type = "unknown";
361 if (s.Contains("/alice/data")) type = "real";
362 else if (s.Contains("/alice/sim")) type = "simulated";
365 ind1 = s.Index("/00");
367 ind2 = s.Index("/",ind1+1);
368 if (ind2-ind1>8) srun = s(ind1+1, ind2-ind1-1);
371 ind1 = s.Index("/LHC");
373 ind1 = s.Index("/",ind1+1);
375 ind2 = s.Index("/",ind1+1);
376 if (ind2>0) srun = s(ind1+1, ind2-ind1-1);
380 Int_t run = srun.Atoi();
381 if (run>0) printf("=== GetRunFromAlienPath: run %d of %s data ===\n", run, type.Data());
385 //______________________________________________________________________________
386 Bool_t AliAnalysisManager::Init(TTree *tree)
388 // The Init() function is called when the selector needs to initialize
389 // a new tree or chain. Typically here the branch addresses of the tree
390 // will be set. It is normaly not necessary to make changes to the
391 // generated code, but the routine can be extended by the user if needed.
392 // Init() will be called many times when running with PROOF.
393 Bool_t init = kFALSE;
394 if (!tree) return kFALSE; // Should not happen - protected in selector caller
396 printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
398 // Call InitTree of EventHandler
399 if (fOutputEventHandler) {
400 if (fMode == kProofAnalysis) {
401 init = fOutputEventHandler->Init(0x0, "proof");
403 init = fOutputEventHandler->Init(0x0, "local");
406 Error("Init", "Output event handler failed to initialize");
411 if (fInputEventHandler) {
412 if (fMode == kProofAnalysis) {
413 init = fInputEventHandler->Init(tree, "proof");
415 init = fInputEventHandler->Init(tree, "local");
418 Error("Init", "Input event handler failed to initialize tree");
422 // If no input event handler we need to get the tree once
424 if(!tree->GetTree()) {
425 Long64_t readEntry = tree->LoadTree(0);
426 if (readEntry == -2) {
427 Error("Init", "Input tree has no entry. Exiting");
433 if (fMCtruthEventHandler) {
434 if (fMode == kProofAnalysis) {
435 init = fMCtruthEventHandler->Init(0x0, "proof");
437 init = fMCtruthEventHandler->Init(0x0, "local");
440 Error("Init", "MC event handler failed to initialize");
445 if (!fInitOK) InitAnalysis();
446 if (!fInitOK) return kFALSE;
448 if (fMode != kProofAnalysis) CreateReadCache();
450 // cholm - here we should re-add to the table or branches
453 AliAnalysisDataContainer *top = fCommonInput;
454 if (!top) top = (AliAnalysisDataContainer*)fInputs->At(0);
456 Error("Init","No top input container !");
460 CheckBranches(kFALSE);
463 printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
468 //______________________________________________________________________________
469 void AliAnalysisManager::SlaveBegin(TTree *tree)
471 // The SlaveBegin() function is called after the Begin() function.
472 // When running with PROOF SlaveBegin() is called on each slave server.
473 // The tree argument is deprecated (on PROOF 0 is passed).
474 if (fDebug > 1) printf("->AliAnalysisManager::SlaveBegin()\n");
475 // Init timer should be already started
476 // Apply debug options
479 fMCtruthEventHandler &&
480 (fMode != kProofAnalysis)) fMCtruthEventHandler->SetCacheSize(fCacheSize);
481 if (!CheckTasks()) Fatal("SlaveBegin", "Not all needed libraries were loaded");
482 static Bool_t isCalled = kFALSE;
483 Bool_t init = kFALSE;
484 Bool_t initOK = kTRUE;
486 TDirectory *curdir = gDirectory;
487 // Call SlaveBegin only once in case of mixing
488 if (isCalled && fMode==kMixingAnalysis) return;
490 // Call Init of EventHandler
491 if (fOutputEventHandler) {
492 if (fMode == kProofAnalysis) {
493 // Merging AOD's in PROOF via TProofOutputFile
494 if (fDebug > 1) printf(" Initializing AOD output file %s...\n", fOutputEventHandler->GetOutputFileName());
495 init = fOutputEventHandler->Init("proof");
496 if (!init) msg = "Failed to initialize output handler on worker";
498 init = fOutputEventHandler->Init("local");
499 if (!init) msg = "Failed to initialize output handler";
502 if (!fSelector) Error("SlaveBegin", "Selector not set");
503 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
506 if (fInputEventHandler) {
507 fInputEventHandler->SetInputTree(tree);
508 if (fMode == kProofAnalysis) {
509 init = fInputEventHandler->Init("proof");
510 if (!init) msg = "Failed to initialize input handler on worker";
512 init = fInputEventHandler->Init("local");
513 if (!init) msg = "Failed to initialize input handler";
516 if (!fSelector) Error("SlaveBegin", "Selector not set");
517 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
520 if (fMCtruthEventHandler) {
521 if (fMode == kProofAnalysis) {
522 init = fMCtruthEventHandler->Init("proof");
523 if (!init) msg = "Failed to initialize MC handler on worker";
525 init = fMCtruthEventHandler->Init("local");
526 if (!init) msg = "Failed to initialize MC handler";
529 if (!fSelector) Error("SlaveBegin", "Selector not set");
530 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
532 if (curdir) curdir->cd();
536 AliAnalysisTask *task;
537 // Call CreateOutputObjects for all tasks
538 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
539 Bool_t dirStatus = TH1::AddDirectoryStatus();
541 while ((task=(AliAnalysisTask*)next())) {
543 // Start with memory as current dir and make sure by default histograms do not get attached to files.
544 TH1::AddDirectory(kFALSE);
545 task->CreateOutputObjects();
546 if (!task->CheckPostData()) {
547 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
548 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
549 ####### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ##########", task->GetName(), task->ClassName());
551 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
554 TH1::AddDirectory(dirStatus);
555 if (curdir) curdir->cd();
557 fInitTime += fInitTimer->RealTime();
558 fInitTimer->Continue();
559 printf("Initialization time: %g [sec]\n", fInitTime);
560 if (fDebug > 1) printf("<-AliAnalysisManager::SlaveBegin()\n");
563 //______________________________________________________________________________
564 Bool_t AliAnalysisManager::Notify()
566 // The Notify() function is called when a new file is opened. This
567 // can be either for a new TTree in a TChain or when when a new TTree
568 // is started when using PROOF. It is normaly not necessary to make changes
569 // to the generated code, but the routine can be extended by the
570 // user if needed. The return value is currently not used.
571 fIOTimer->Start(kTRUE);
572 if (!fTree) return kFALSE;
573 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) return kFALSE;
575 fTable.Clear("nodelete"); // clearing the hash table may not be needed -> C.L.
576 if (fMode == kProofAnalysis) fIsRemote = kTRUE;
578 TFile *curfile = fTree->GetCurrentFile();
580 Error("Notify","No current file");
583 if (IsCollectThroughput()) {
584 if (fCurrentDescriptor) fCurrentDescriptor->Done();
585 fCurrentDescriptor = new AliAnalysisFileDescriptor(curfile);
586 fFileDescriptors->Add(fCurrentDescriptor);
589 if (fDebug > 1) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
590 Int_t run = AliAnalysisManager::GetRunFromAlienPath(curfile->GetName());
591 if (run && (run != fRunFromPath)) {
593 if (fDebug > 1) printf(" ### run found from path: %d\n", run);
596 AliAnalysisTask *task;
598 // Call Notify of the event handlers
599 if (fInputEventHandler) {
600 fInputEventHandler->Notify(curfile->GetName());
603 if (fOutputEventHandler) {
604 fOutputEventHandler->Notify(curfile->GetName());
607 if (fMCtruthEventHandler) {
608 fMCtruthEventHandler->Notify(curfile->GetName());
611 // Call Notify for all tasks
612 while ((task=(AliAnalysisTask*)next()))
615 if (fDebug > 1) printf("<-AliAnalysisManager::Notify()\n");
617 fIOTime += fIOTimer->RealTime();
621 //______________________________________________________________________________
622 Bool_t AliAnalysisManager::Process(Long64_t)
624 // The Process() function is called for each entry in the tree (or possibly
625 // keyed object in the case of PROOF) to be processed. The entry argument
626 // specifies which entry in the currently loaded tree is to be processed.
627 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
628 // to read either all or the required parts of the data. When processing
629 // keyed objects with PROOF, the object is already loaded and is available
630 // via the fObject pointer.
632 // This function should contain the "body" of the analysis. It can contain
633 // simple or elaborate selection criteria, run algorithms on the data
634 // of the event and typically fill histograms.
636 // WARNING when a selector is used with a TChain, you must use
637 // the pointer to the current TTree to call GetEntry(entry).
638 // The entry is always the local entry number in the current tree.
639 // Assuming that fChain is the pointer to the TChain being processed,
640 // use fChain->GetTree()->GetEntry(entry).
642 // This method is obsolete. ExecAnalysis is called instead.
646 //______________________________________________________________________________
647 void AliAnalysisManager::PackOutput(TList *target)
649 // Pack all output data containers in the output list. Called at SlaveTerminate
650 // stage in PROOF case for each slave.
651 if (fDebug > 1) printf("->AliAnalysisManager::PackOutput()\n");
652 fIOTimer->Start(kTRUE);
654 if (IsCollectThroughput()) {
655 if (fCurrentDescriptor) fCurrentDescriptor->Done();
656 fFileDescriptors->Print();
657 if (fFileInfoLog.IsNull()) fFileInfoLog = "fileinfo.log";
658 out.open(fFileInfoLog, std::ios::app);
659 if (out.bad()) Error("SavePrimitive", "Bad file name: %s", fFileInfoLog.Data());
661 TIter nextflog(fFileDescriptors);
663 while ((log=nextflog())) log->SavePrimitive(out,"");
667 Error("PackOutput", "No target. Exiting.");
670 TDirectory *cdir = gDirectory;
672 if (fInputEventHandler) fInputEventHandler ->Terminate();
673 if (fOutputEventHandler) fOutputEventHandler ->Terminate();
674 if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
677 // Call FinishTaskOutput() for each event loop task (not called for
678 // post-event loop tasks - use Terminate() fo those)
679 TIter nexttask(fTasks);
680 AliAnalysisTask *task;
681 while ((task=(AliAnalysisTask*)nexttask())) {
682 if (!task->IsPostEventLoop()) {
683 if (fDebug > 1) printf("->FinishTaskOutput: task %s\n", task->GetName());
684 task->FinishTaskOutput();
686 if (fDebug > 1) printf("<-FinishTaskOutput: task %s\n", task->GetName());
689 // Write statistics message on the workers.
690 if (fStatistics) WriteStatisticsMsg(fNcalls);
692 if (fMode == kProofAnalysis) {
693 TIter next(fOutputs);
694 AliAnalysisDataContainer *output;
695 Bool_t isManagedByHandler = kFALSE;
698 while ((output=(AliAnalysisDataContainer*)next())) {
699 // Do not consider outputs of post event loop tasks
700 isManagedByHandler = kFALSE;
701 if (output->GetProducer() && output->GetProducer()->IsPostEventLoop()) continue;
702 const char *filename = output->GetFileName();
703 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
704 isManagedByHandler = kTRUE;
705 printf("#### Handler output. Extra: %s\n", fExtraFiles.Data());
706 filename = fOutputEventHandler->GetOutputFileName();
708 // Check if data was posted to this container. If not, issue an error.
709 if (!output->GetData() && !isManagedByHandler) {
710 Error("PackOutput", "No data for output container %s. Forgot to PostData ?", output->GetName());
713 if (!output->IsSpecialOutput()) {
715 if (strlen(filename) && !isManagedByHandler) {
716 // Backup current folder
717 TDirectory *opwd = gDirectory;
718 // File resident outputs.
719 // Check first if the file exists.
720 TString openoption = "RECREATE";
721 Bool_t firsttime = kTRUE;
722 if (filestmp.FindObject(output->GetFileName())) {
725 filestmp.Add(new TNamed(output->GetFileName(),""));
727 if (!gSystem->AccessPathName(output->GetFileName()) && !firsttime) openoption = "UPDATE";
728 // TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
729 // Save data to file, then close.
730 if (output->GetData()->InheritsFrom(TCollection::Class())) {
731 // If data is a collection, we set the name of the collection
732 // as the one of the container and we save as a single key.
733 TCollection *coll = (TCollection*)output->GetData();
734 coll->SetName(output->GetName());
735 // coll->Write(output->GetName(), TObject::kSingleKey);
737 if (output->GetData()->InheritsFrom(TTree::Class())) {
738 TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
739 // Save data to file, then close.
740 TTree *tree = (TTree*)output->GetData();
741 // Check if tree is in memory
742 if (tree->GetDirectory()==gROOT) tree->SetDirectory(gDirectory);
746 // output->GetData()->Write();
749 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
751 // printf(" file %s listing content:\n", filename);
754 // Clear file list to release object ownership to user.
757 output->SetFile(NULL);
758 // Restore current directory
759 if (opwd) opwd->cd();
761 // Memory-resident outputs
762 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
764 AliAnalysisDataWrapper *wrap = 0;
765 if (isManagedByHandler) {
766 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
767 wrap->SetName(output->GetName());
769 else wrap =output->ExportData();
770 // Output wrappers must NOT delete data after merging - the user owns them
771 wrap->SetDeleteData(kFALSE);
774 // Special outputs. The file must be opened and connected to the container.
775 TDirectory *opwd = gDirectory;
776 TFile *file = output->GetFile();
778 AliAnalysisTask *producer = output->GetProducer();
780 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
781 output->GetFileName(), output->GetName(), producer->ClassName());
784 TString outFilename = file->GetName();
785 if (fDebug > 1) printf("PackOutput %s: special output\n", output->GetName());
786 if (isManagedByHandler) {
787 // Terminate IO for files managed by the output handler
788 // file->Write() moved to AOD handler (A.G. 11.01.10)
789 // if (file) file->Write();
790 if (file && fDebug > 2) {
791 printf(" handled file %s listing content:\n", file->GetName());
794 fOutputEventHandler->TerminateIO();
797 // Release object ownership to users after writing data to file
798 if (output->GetData()->InheritsFrom(TCollection::Class())) {
799 // If data is a collection, we set the name of the collection
800 // as the one of the container and we save as a single key.
801 TCollection *coll = (TCollection*)output->GetData();
802 coll->SetName(output->GetName());
803 coll->Write(output->GetName(), TObject::kSingleKey);
805 if (output->GetData()->InheritsFrom(TTree::Class())) {
806 TTree *tree = (TTree*)output->GetData();
807 tree->SetDirectory(file);
810 output->GetData()->Write();
814 printf(" file %s listing content:\n", output->GetFileName());
817 // Clear file list to release object ownership to user.
820 output->SetFile(NULL);
822 // Restore current directory
823 if (opwd) opwd->cd();
824 // Check if a special output location was provided or the output files have to be merged
825 if (strlen(fSpecialOutputLocation.Data())) {
826 TString remote = fSpecialOutputLocation;
828 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
829 if (remote.BeginsWith("alien:")) {
830 gROOT->ProcessLine("TGrid::Connect(\"alien:\", gProofServ->GetUser());");
831 remote += outFilename;
832 remote.ReplaceAll(".root", Form("_%d.root", gid));
834 remote += Form("%s_%d_", gSystem->HostName(), gid);
835 remote += outFilename;
838 Info("PackOutput", "Output file for container %s to be copied \n at: %s. No merging.",
839 output->GetName(), remote.Data());
840 TFile::Cp ( outFilename.Data(), remote.Data() );
841 // Copy extra outputs
842 if (fExtraFiles.Length() && isManagedByHandler) {
843 TObjArray *arr = fExtraFiles.Tokenize(" ");
845 TIter nextfilename(arr);
846 while ((os=(TObjString*)nextfilename())) {
847 outFilename = os->GetString();
848 remote = fSpecialOutputLocation;
850 if (remote.BeginsWith("alien://")) {
851 remote += outFilename;
852 remote.ReplaceAll(".root", Form("_%d.root", gid));
854 remote += Form("%s_%d_", gSystem->HostName(), gid);
855 remote += outFilename;
858 Info("PackOutput", "Extra AOD file %s to be copied \n at: %s. No merging.",
859 outFilename.Data(), remote.Data());
860 TFile::Cp ( outFilename.Data(), remote.Data() );
865 // No special location specified-> use TProofOutputFile as merging utility
866 // The file at this output slot must be opened in CreateOutputObjects
867 if (fDebug > 1) printf(" File for container %s to be merged via file merger...\n", output->GetName());
872 fIOTime += fIOTimer->RealTime();
873 if ((fDebug || IsCollectThroughput())) {
875 fInitTime = fInitTimer->RealTime()-fIOTime-fCPUTime;
876 printf("=Analysis %s= init time: %g[sec]\
877 \n I/O & data mng.: %g [sec]\
878 \n task execution: %g [sec]\
879 \n total time: CPU=%g [sec] REAL=%g[sec]\n",
880 GetName(), fInitTime, fIOTime, fCPUTime, fInitTimer->CpuTime(), fInitTimer->RealTime());
881 if (IsCollectThroughput()) {
882 out << "#summary#########################################################" << endl;
883 out << "train_name " << GetName() << endl;
884 out << "root_time " << fInitTimer->RealTime() << endl;
885 out << "root_cpu " << fInitTimer->CpuTime() << endl;
886 out << "init_time " << fInitTime << endl;
887 out << "io_mng_time " << fIOTime << endl;
888 out << "exec_time " << fCPUTime << endl;
889 TString aliensite = gSystem->Getenv("ALIEN_SITE");
890 out << "alien_site " << aliensite << endl;
892 TString hostname = gSystem->Getenv("ALIEN_HOSTNAME");
893 if (hostname.IsNull()) {
895 gSystem->Exec(Form("hostname -f >> %s", fFileInfoLog.Data()));
897 out << hostname << endl;
902 if (cdir) cdir->cd();
903 if (fDebug > 1) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
906 //______________________________________________________________________________
907 void AliAnalysisManager::ImportWrappers(TList *source)
909 // Import data in output containers from wrappers coming in source.
910 if (fDebug > 1) printf("->AliAnalysisManager::ImportWrappers()\n");
911 fIOTimer->Start(kTRUE);
912 TIter next(fOutputs);
913 AliAnalysisDataContainer *cont;
914 AliAnalysisDataWrapper *wrap;
916 Bool_t inGrid = (fMode == kGridAnalysis)?kTRUE:kFALSE;
917 TDirectory *cdir = gDirectory;
918 while ((cont=(AliAnalysisDataContainer*)next())) {
920 if (cont->GetProducer() && cont->GetProducer()->IsPostEventLoop() && !inGrid) continue;
921 if (cont->IsRegisterDataset()) continue;
922 const char *filename = cont->GetFileName();
923 Bool_t isManagedByHandler = kFALSE;
924 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
925 isManagedByHandler = kTRUE;
926 filename = fOutputEventHandler->GetOutputFileName();
928 if (cont->IsSpecialOutput() || inGrid) {
929 if (strlen(fSpecialOutputLocation.Data())) continue;
930 // Copy merged file from PROOF scratch space.
931 // In case of grid the files are already in the current directory.
933 if (isManagedByHandler && fExtraFiles.Length()) {
934 // Copy extra registered dAOD files.
935 TObjArray *arr = fExtraFiles.Tokenize(" ");
937 TIter nextfilename(arr);
938 while ((os=(TObjString*)nextfilename())) GetFileFromWrapper(os->GetString(), source);
941 if (!GetFileFromWrapper(filename, source)) continue;
943 // Normally we should connect data from the copied file to the
944 // corresponding output container, but it is not obvious how to do this
945 // automatically if several objects in file...
946 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
947 if (!f) f = TFile::Open(filename, "READ");
949 Error("ImportWrappers", "Cannot open file %s in read-only mode", filename);
954 // Cd to the directory pointed by the container
955 TString folder = cont->GetFolderName();
956 if (!folder.IsNull()) f->cd(folder);
957 // Try to fetch first an object having the container name.
958 obj = gDirectory->Get(cont->GetName());
960 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",
961 cont->GetType()->GetName(), cont->GetName(), filename, cont->GetFolderName(), cont->GetName());
964 wrap = new AliAnalysisDataWrapper(obj);
965 wrap->SetDeleteData(kFALSE);
967 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
969 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
974 printf(" Importing data for container %s\n", cont->GetName());
975 if (strlen(filename)) printf(" -> file %s\n", filename);
978 cont->ImportData(wrap);
980 if (cdir) cdir->cd();
982 fIOTime += fIOTimer->RealTime();
983 if (fDebug > 1) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
986 //______________________________________________________________________________
987 void AliAnalysisManager::UnpackOutput(TList *source)
989 // Called by AliAnalysisSelector::Terminate only on the client.
990 fIOTimer->Start(kTRUE);
991 if (fDebug > 1) printf("->AliAnalysisManager::UnpackOutput()\n");
993 Error("UnpackOutput", "No target. Exiting.");
996 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
998 if (fMode == kProofAnalysis) ImportWrappers(source);
1000 TIter next(fOutputs);
1001 AliAnalysisDataContainer *output;
1002 while ((output=(AliAnalysisDataContainer*)next())) {
1003 if (!output->GetData()) continue;
1004 // Check if there are client tasks that run post event loop
1005 if (output->HasConsumers()) {
1006 // Disable event loop semaphore
1007 output->SetPostEventLoop(kTRUE);
1008 TObjArray *list = output->GetConsumers();
1009 Int_t ncons = list->GetEntriesFast();
1010 for (Int_t i=0; i<ncons; i++) {
1011 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
1012 task->CheckNotify(kTRUE);
1013 // If task is active, execute it
1014 if (task->IsPostEventLoop() && task->IsActive()) {
1015 if (fDebug > 1) printf("== Executing post event loop task %s\n", task->GetName());
1016 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
1017 task->ExecuteTask();
1020 if (fStatistics) fStatistics->StopTimer();
1024 fIOTime += fIOTimer->RealTime();
1025 if (fDebug > 1) printf("<-AliAnalysisManager::UnpackOutput()\n");
1028 //______________________________________________________________________________
1029 void AliAnalysisManager::Terminate()
1031 // The Terminate() function is the last function to be called during
1032 // a query. It always runs on the client, it can be used to present
1033 // the results graphically.
1034 if (fDebug > 1) printf("->AliAnalysisManager::Terminate()\n");
1035 fInitTimer->Start(kTRUE);
1036 TDirectory *cdir = gDirectory;
1038 AliAnalysisTask *task;
1039 AliAnalysisDataContainer *output;
1042 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1043 // Call Terminate() for tasks
1045 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
1046 // Save all the canvases produced by the Terminate
1047 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
1051 AliSysInfo::AddStamp(Form("%s_TERMINATE",task->ClassName()),0, itask, 2);
1053 if (TObject::TestBit(kSaveCanvases)) {
1054 if (!gROOT->IsBatch()) {
1055 if (fDebug>1) printf("Waiting 5 sec for %s::Terminate() to finish drawing ...\n", task->ClassName());
1057 while (timer.RealTime()<5) {
1059 gSystem->ProcessEvents();
1062 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
1063 if (iend==0) continue;
1065 for (Int_t ipict=0; ipict<iend; ipict++) {
1066 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
1067 if (!canvas) continue;
1068 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
1070 gROOT->GetListOfCanvases()->Delete();
1074 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
1075 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
1076 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
1078 TObjArray *allOutputs = new TObjArray();
1080 for (icont=0; icont<fOutputs->GetEntriesFast(); icont++) allOutputs->Add(fOutputs->At(icont));
1081 if (!IsSkipTerminate())
1082 for (icont=0; icont<fParamCont->GetEntriesFast(); icont++) allOutputs->Add(fParamCont->At(icont));
1083 TIter next1(allOutputs);
1084 TString handlerFile = "";
1085 TString extraOutputs = "";
1086 if (fOutputEventHandler) {
1087 handlerFile = fOutputEventHandler->GetOutputFileName();
1088 extraOutputs = fOutputEventHandler->GetExtraOutputs();
1092 while ((output=(AliAnalysisDataContainer*)next1())) {
1093 // Special outputs or grid files have the files already closed and written.
1095 if (fMode == kGridAnalysis && icont<=fOutputs->GetEntriesFast()) continue;
1096 if (fMode == kProofAnalysis) {
1097 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
1099 const char *filename = output->GetFileName();
1100 TString openoption = "RECREATE";
1101 if (!(strcmp(filename, "default"))) continue;
1102 if (!strlen(filename)) continue;
1103 if (!output->GetData()) continue;
1104 TDirectory *opwd = gDirectory;
1105 TFile *file = output->GetFile();
1106 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1108 //if (handlerFile == filename && !gSystem->AccessPathName(filename)) openoption = "UPDATE";
1109 Bool_t firsttime = kTRUE;
1110 if (filestmp.FindObject(filename) || extraOutputs.Contains(filename)) {
1113 filestmp.Add(new TNamed(filename,""));
1115 if (!gSystem->AccessPathName(filename) && !firsttime) openoption = "UPDATE";
1116 if (fDebug>1) printf("Opening file: %s option=%s\n",filename, openoption.Data());
1117 file = new TFile(filename, openoption);
1119 if (fDebug>1) printf("File <%s> already opened with option: <%s> \n", filename, file->GetOption());
1120 openoption = file->GetOption();
1121 if (openoption == "READ") {
1122 if (fDebug>1) printf("...reopening in UPDATE mode\n");
1123 file->ReOpen("UPDATE");
1126 if (file->IsZombie()) {
1127 Error("Terminate", "Cannot open output file %s", filename);
1130 output->SetFile(file);
1132 // Check for a folder request
1133 TString dir = output->GetFolderName();
1134 if (!dir.IsNull()) {
1135 if (!file->GetDirectory(dir)) file->mkdir(dir);
1138 if (fDebug > 1) printf("...writing container %s to file %s:%s\n", output->GetName(), file->GetName(), output->GetFolderName());
1139 if (output->GetData()->InheritsFrom(TCollection::Class())) {
1140 // If data is a collection, we set the name of the collection
1141 // as the one of the container and we save as a single key.
1142 TCollection *coll = (TCollection*)output->GetData();
1143 coll->SetName(output->GetName());
1144 coll->Write(output->GetName(), TObject::kSingleKey);
1146 if (output->GetData()->InheritsFrom(TTree::Class())) {
1147 TTree *tree = (TTree*)output->GetData();
1148 tree->SetDirectory(gDirectory);
1151 output->GetData()->Write();
1154 if (opwd) opwd->cd();
1158 TString copiedFiles;
1159 while ((output=(AliAnalysisDataContainer*)next1())) {
1160 // Close all files at output
1161 TDirectory *opwd = gDirectory;
1162 if (output->GetFile()) {
1163 // Clear file list to release object ownership to user.
1164 // output->GetFile()->Clear();
1165 output->GetFile()->Close();
1166 // Copy merged outputs in alien if requested
1167 if (fSpecialOutputLocation.BeginsWith("alien://")) {
1168 if (copiedFiles.Contains(output->GetFile()->GetName())) {
1169 if (opwd) opwd->cd();
1170 output->SetFile(NULL);
1173 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
1174 gROOT->ProcessLine("if (!gGrid) TGrid::Connect(\"alien:\");");
1175 TFile::Cp(output->GetFile()->GetName(),
1176 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
1177 copiedFiles += output->GetFile()->GetName();
1179 output->SetFile(NULL);
1181 if (opwd) opwd->cd();
1184 //Write statistics information on the client
1185 if (fStatistics) WriteStatisticsMsg(fNcalls);
1187 TDirectory *crtdir = gDirectory;
1188 TFile f("syswatch.root", "RECREATE");
1191 if (!f.IsZombie()) {
1192 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
1193 tree->SetName("syswatch");
1194 tree->SetMarkerStyle(kCircle);
1195 tree->SetMarkerColor(kBlue);
1196 tree->SetMarkerSize(0.5);
1197 if (!gROOT->IsBatch()) {
1198 tree->SetAlias("event", "id0");
1199 tree->SetAlias("task", "id1");
1200 tree->SetAlias("stage", "id2");
1201 // Already defined aliases
1202 // tree->SetAlias("deltaT","stampSec-stampOldSec");
1203 // tree->SetAlias("T","stampSec-first");
1204 // tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)");
1205 // tree->SetAlias("VM","pI.fMemVirtual");
1206 TCanvas *canvas = new TCanvas("SysInfo","SysInfo",10,10,1200,800);
1207 Int_t npads = 1 /*COO plot for all tasks*/ +
1208 fTopTasks->GetEntries() /*Exec plot per task*/ +
1209 1 /*Terminate plot for all tasks*/ +
1212 Int_t iopt = (Int_t)TMath::Sqrt((Double_t)npads);
1213 if (npads<iopt*(iopt+1))
1214 canvas->Divide(iopt, iopt+1, 0.01, 0.01);
1216 canvas->Divide(iopt+1, iopt+1, 0.01, 0.01);
1218 // draw the plot of deltaVM for Exec for each task
1219 for (itask=0; itask<fTopTasks->GetEntriesFast(); itask++) {
1220 task = (AliAnalysisTask*)fTopTasks->At(itask);
1222 cut = Form("task==%d && stage==1", itask);
1223 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1224 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1226 hist->SetTitle(Form("%s: Exec dVM[MB]/event", task->GetName()));
1227 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1230 // Draw the plot of deltaVM for CreateOutputObjects for all tasks
1232 tree->SetMarkerStyle(kFullTriangleUp);
1233 tree->SetMarkerColor(kRed);
1234 tree->SetMarkerSize(0.8);
1235 cut = "task>=0 && task<1000 && stage==0";
1236 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1237 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1239 hist->SetTitle("Memory in CreateOutputObjects()");
1240 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1241 hist->GetXaxis()->SetTitle("task");
1243 // draw the plot of deltaVM for Terminate for all tasks
1245 tree->SetMarkerStyle(kOpenSquare);
1246 tree->SetMarkerColor(kMagenta);
1247 cut = "task>=0 && task<1000 && stage==2";
1248 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1249 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1251 hist->SetTitle("Memory in Terminate()");
1252 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1253 hist->GetXaxis()->SetTitle("task");
1257 tree->SetMarkerStyle(kFullCircle);
1258 tree->SetMarkerColor(kGreen);
1259 cut = Form("task==%d && stage==1",fTopTasks->GetEntriesFast()-1);
1260 tree->Draw("VM:event",cut,"", 1234567890, 0);
1261 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1263 hist->SetTitle("Virtual memory");
1264 hist->GetYaxis()->SetTitle("VM [MB]");
1268 tree->SetMarkerStyle(kCircle);
1269 tree->SetMarkerColor(kBlue);
1270 tree->SetMarkerSize(0.5);
1275 if (crtdir) crtdir->cd();
1277 // Validate the output files
1278 if (ValidateOutputFiles() && fIsRemote && fMode!=kProofAnalysis) {
1280 out.open("outputs_valid", ios::out);
1283 if (cdir) cdir->cd();
1285 if (fDebug || IsCollectThroughput()) {
1286 printf("=Analysis %s= Terminate time: %g[sec]\n", GetName(), fInitTimer->RealTime());
1288 if (fDebug > 1) printf("<-AliAnalysisManager::Terminate()\n");
1290 //______________________________________________________________________________
1291 void AliAnalysisManager::ProfileTask(Int_t itop, const char *option) const
1293 // Profiles the task having the itop index in the list of top (first level) tasks.
1294 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->At(itop);
1296 Error("ProfileTask", "There are only %d top tasks in the manager", fTopTasks->GetEntries());
1299 ProfileTask(task->GetName(), option);
1302 //______________________________________________________________________________
1303 void AliAnalysisManager::ProfileTask(const char *name, const char */*option*/) const
1305 // Profile a managed task after the execution of the analysis in case NSysInfo
1307 if (gSystem->AccessPathName("syswatch.root")) {
1308 Error("ProfileTask", "No file syswatch.root found in the current directory");
1311 if (gROOT->IsBatch()) return;
1312 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->FindObject(name);
1314 Error("ProfileTask", "No top task named %s known by the manager.", name);
1317 Int_t itop = fTopTasks->IndexOf(task);
1318 Int_t itask = fTasks->IndexOf(task);
1319 // Create canvas with 2 pads: first draw COO + Terminate, second Exec
1320 TDirectory *cdir = gDirectory;
1321 TFile f("syswatch.root");
1322 TTree *tree = (TTree*)f.Get("syswatch");
1324 Error("ProfileTask", "No tree named <syswatch> found in file syswatch.root");
1327 if (fDebug > 1) printf("=== Profiling task %s (class %s)\n", name, task->ClassName());
1328 TCanvas *canvas = new TCanvas(Form("profile_%d",itop),Form("Profile of task %s (class %s)",name,task->ClassName()),10,10,800,600);
1329 canvas->Divide(2, 2, 0.01, 0.01);
1333 // VM profile for COO and Terminate methods
1335 cut = Form("task==%d && (stage==0 || stage==2)",itask);
1336 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1337 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1339 hist->SetTitle("Alocated VM[MB] for COO and Terminate");
1340 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1341 hist->GetXaxis()->SetTitle("method");
1343 // CPU profile per event
1345 cut = Form("task==%d && stage==1",itop);
1346 tree->Draw("deltaT:event",cut,"", 1234567890, 0);
1347 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1349 hist->SetTitle("Execution time per event");
1350 hist->GetYaxis()->SetTitle("CPU/event [s]");
1352 // VM profile for Exec
1354 cut = Form("task==%d && stage==1",itop);
1355 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1356 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1358 hist->SetTitle("Alocated VM[MB] per event");
1359 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1364 if (cdir) cdir->cd();
1367 //______________________________________________________________________________
1368 void AliAnalysisManager::AddTask(AliAnalysisTask *task)
1370 // Adds a user task to the global list of tasks.
1372 Error("AddTask", "Cannot add task %s since InitAnalysis was already called", task->GetName());
1376 if (fTasks->FindObject(task)) {
1377 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
1380 task->SetActive(kFALSE);
1384 //______________________________________________________________________________
1385 AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
1387 // Retreive task by name.
1388 if (!fTasks) return NULL;
1389 return (AliAnalysisTask*)fTasks->FindObject(name);
1392 //______________________________________________________________________________
1393 Int_t AliAnalysisManager::GetTaskIndex(const AliAnalysisTask *task) const
1395 // Returns task inded in the manager's list, -1 if not registered.
1396 if (!fTasks) return -1;
1397 return fTasks->IndexOf(task);
1400 //______________________________________________________________________________
1401 AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
1402 TClass *datatype, EAliAnalysisContType type, const char *filename)
1404 // Create a data container of a certain type. Types can be:
1405 // kExchangeContainer = 0, used to exchange data between tasks
1406 // kInputContainer = 1, used to store input data
1407 // kOutputContainer = 2, used for writing result to a file
1408 // filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
1409 // the output object to a folder inside the output file
1410 if (fContainers->FindObject(name)) {
1411 Error("CreateContainer","A container named %s already defined !",name);
1414 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
1415 fContainers->Add(cont);
1417 case kInputContainer:
1420 case kOutputContainer:
1421 fOutputs->Add(cont);
1422 if (filename && strlen(filename)) {
1423 cont->SetFileName(filename);
1424 cont->SetDataOwned(kFALSE); // data owned by the file
1427 case kParamContainer:
1428 fParamCont->Add(cont);
1429 if (filename && strlen(filename)) {
1430 cont->SetFileName(filename);
1431 cont->SetDataOwned(kFALSE); // data owned by the file
1434 case kExchangeContainer:
1440 //______________________________________________________________________________
1441 Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
1442 AliAnalysisDataContainer *cont)
1444 // Connect input of an existing task to a data container.
1446 Error("ConnectInput", "Task pointer is NULL");
1449 if (!fTasks->FindObject(task)) {
1451 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
1453 Bool_t connected = task->ConnectInput(islot, cont);
1457 //______________________________________________________________________________
1458 Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
1459 AliAnalysisDataContainer *cont)
1461 // Connect output of an existing task to a data container.
1463 Error("ConnectOutput", "Task pointer is NULL");
1466 if (!fTasks->FindObject(task)) {
1468 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
1470 Bool_t connected = task->ConnectOutput(islot, cont);
1474 //______________________________________________________________________________
1475 void AliAnalysisManager::CleanContainers()
1477 // Clean data from all containers that have already finished all client tasks.
1478 TIter next(fContainers);
1479 AliAnalysisDataContainer *cont;
1480 while ((cont=(AliAnalysisDataContainer *)next())) {
1481 if (cont->IsOwnedData() &&
1482 cont->IsDataReady() &&
1483 cont->ClientsExecuted()) cont->DeleteData();
1487 //______________________________________________________________________________
1488 Bool_t AliAnalysisManager::InitAnalysis()
1490 // Initialization of analysis chain of tasks. Should be called after all tasks
1491 // and data containers are properly connected
1492 // Reset flag and remove valid_outputs file if exists
1493 if (fInitOK) return kTRUE;
1494 if (!gSystem->AccessPathName("outputs_valid"))
1495 gSystem->Unlink("outputs_valid");
1496 // Check for top tasks (depending only on input data containers)
1497 if (!fTasks->First()) {
1498 Error("InitAnalysis", "Analysis has no tasks !");
1502 AliAnalysisTask *task;
1503 AliAnalysisDataContainer *cont;
1506 Bool_t iszombie = kFALSE;
1507 Bool_t istop = kTRUE;
1509 while ((task=(AliAnalysisTask*)next())) {
1512 Int_t ninputs = task->GetNinputs();
1513 for (i=0; i<ninputs; i++) {
1514 cont = task->GetInputSlot(i)->GetContainer();
1518 fZombies->Add(task);
1522 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
1523 i, task->GetName());
1525 if (iszombie) continue;
1526 // Check if cont is an input container
1527 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
1528 // Connect to parent task
1532 fTopTasks->Add(task);
1536 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
1539 // Check now if there are orphan tasks
1540 for (i=0; i<ntop; i++) {
1541 task = (AliAnalysisTask*)fTopTasks->At(i);
1546 while ((task=(AliAnalysisTask*)next())) {
1547 if (!task->IsUsed()) {
1549 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
1552 // Check the task hierarchy (no parent task should depend on data provided
1553 // by a daughter task)
1554 for (i=0; i<ntop; i++) {
1555 task = (AliAnalysisTask*)fTopTasks->At(i);
1556 if (task->CheckCircularDeps()) {
1557 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
1562 // Check that all containers feeding post-event loop tasks are in the outputs list
1563 TIter nextcont(fContainers); // loop over all containers
1564 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1565 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1566 if (cont->HasConsumers()) {
1567 // Check if one of the consumers is post event loop
1568 TIter nextconsumer(cont->GetConsumers());
1569 while ((task=(AliAnalysisTask*)nextconsumer())) {
1570 if (task->IsPostEventLoop()) {
1571 fOutputs->Add(cont);
1578 // Check if all special output containers have a file name provided
1579 TIter nextout(fOutputs);
1580 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1581 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1582 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1586 // Initialize requested branch list if needed
1587 if (!fAutoBranchHandling) {
1589 while ((task=(AliAnalysisTask*)next())) {
1590 if (!task->HasBranches()) {
1591 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\"",
1592 task->GetName(), task->ClassName());
1595 if (!fInputEventHandler || !strlen(fInputEventHandler->GetDataType())) {
1596 Error("InitAnalysis", "Manual branch loading requested but no input handler defined or handler does not define data type.");
1599 TString taskbranches;
1600 task->GetBranches(fInputEventHandler->GetDataType(), taskbranches);
1601 if (taskbranches.IsNull()) {
1602 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches of type %s:",
1603 task->GetName(), task->ClassName(), fInputEventHandler->GetDataType());
1606 AddBranches(taskbranches);
1613 //______________________________________________________________________________
1614 void AliAnalysisManager::AddBranches(const char *branches)
1616 // Add branches to the existing fRequestedBranches.
1617 TString br(branches);
1618 TObjArray *arr = br.Tokenize(",");
1621 while ((obj=next())) {
1622 if (!fRequestedBranches.Contains(obj->GetName())) {
1623 if (!fRequestedBranches.IsNull()) fRequestedBranches += ",";
1624 fRequestedBranches += obj->GetName();
1630 //______________________________________________________________________________
1631 void AliAnalysisManager::CheckBranches(Bool_t load)
1633 // The method checks the input branches to be loaded during the analysis.
1634 if (fAutoBranchHandling || fRequestedBranches.IsNull() || !fTree) return;
1635 TObjArray *arr = fRequestedBranches.Tokenize(",");
1638 while ((obj=next())) {
1639 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(obj->GetName()));
1641 br = fTree->GetBranch(obj->GetName());
1643 Error("CheckBranches", "Could not find branch %s",obj->GetName());
1648 if (load && br->GetReadEntry()!=GetCurrentEntry()) {
1649 br->GetEntry(GetCurrentEntry());
1655 //______________________________________________________________________________
1656 Bool_t AliAnalysisManager::CheckTasks() const
1658 // Check consistency of tasks.
1659 Int_t ntasks = fTasks->GetEntries();
1661 Error("CheckTasks", "No tasks connected to the manager. This may be due to forgetting to compile the task or to load their library.");
1664 // Get the pointer to AliAnalysisTaskSE::Class()
1665 TClass *badptr = (TClass*)gROOT->ProcessLine("AliAnalysisTaskSE::Class()");
1666 // Loop all tasks to check if their corresponding library was loaded
1669 while ((obj=next())) {
1670 if (obj->IsA() == badptr) {
1671 Error("CheckTasks", "##################\n \
1672 Class for task %s NOT loaded. You probably forgot to load the library for this task (or compile it dynamically).\n###########################\n",obj->GetName());
1679 //______________________________________________________________________________
1680 void AliAnalysisManager::PrintStatus(Option_t *option) const
1682 // Print task hierarchy.
1684 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1687 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1689 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
1690 TIter next(fTopTasks);
1691 AliAnalysisTask *task;
1692 while ((task=(AliAnalysisTask*)next()))
1693 task->PrintTask(option);
1695 if (!fAutoBranchHandling && !fRequestedBranches.IsNull())
1696 printf("Requested input branches:\n%s\n", fRequestedBranches.Data());
1698 TString sopt(option);
1701 if (sopt.Contains("ALL"))
1703 if ( fOutputEventHandler )
1705 cout << TString('_',78) << endl;
1706 cout << "OutputEventHandler:" << endl;
1707 fOutputEventHandler->Print(" ");
1712 //______________________________________________________________________________
1713 void AliAnalysisManager::ResetAnalysis()
1715 // Reset all execution flags and clean containers.
1719 //______________________________________________________________________________
1720 void AliAnalysisManager::RunLocalInit()
1722 // Run LocalInit method for all tasks.
1723 TDirectory *cdir = gDirectory;
1724 if (IsTrainInitialized()) return;
1725 TIter nextTask(fTasks);
1726 AliAnalysisTask *task;
1727 while ((task=(AliAnalysisTask*)nextTask())) {
1731 if (cdir) cdir->cd();
1732 TObject::SetBit(kTasksInitialized, kTRUE);
1735 //______________________________________________________________________________
1736 void AliAnalysisManager::InputFileFromTree(TTree * const tree, TString &fname)
1738 // Retrieves name of the file from tree
1741 TFile *file = tree->GetCurrentFile();
1744 TChain *chain = dynamic_cast<TChain*>(tree);
1745 if (!chain || !chain->GetNtrees()) return;
1746 basename = gSystem->BaseName(chain->GetListOfFiles()->First()->GetTitle());
1748 basename = gSystem->BaseName(file->GetName());
1750 Int_t index = basename.Index("#");
1751 fname = basename(index+1, basename.Length());
1754 //______________________________________________________________________________
1755 Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
1757 // Start analysis having a grid handler.
1758 if (!fGridHandler) {
1759 Error("StartAnalysis", "Cannot start analysis providing just the analysis type without a grid handler.");
1760 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1764 return StartAnalysis(type, tree, nentries, firstentry);
1767 //______________________________________________________________________________
1768 Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
1770 // Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1771 // MIX. Process nentries starting from firstentry
1773 // Backup current directory and make sure gDirectory points to gROOT
1774 TDirectory *cdir = gDirectory;
1777 Error("StartAnalysis","Analysis manager was not initialized !");
1778 if (cdir) cdir->cd();
1781 if (!CheckTasks()) Fatal("StartAnalysis", "Not all needed libraries were loaded");
1783 printf("StartAnalysis %s\n",GetName());
1784 AliLog::SetGlobalLogLevel(AliLog::kInfo);
1786 fMaxEntries = nentries;
1788 TString anaType = type;
1790 fMode = kLocalAnalysis;
1791 if (anaType.Contains("file")) fIsRemote = kTRUE;
1792 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1793 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1794 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1795 if (fInputEventHandler) {
1797 InputFileFromTree(tree, fname);
1798 if (fname.Length()) fInputEventHandler->SetInputFileName(fname);
1801 if (fMode == kGridAnalysis) {
1803 if (!anaType.Contains("terminate")) {
1804 if (!fGridHandler) {
1805 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1806 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1807 if (cdir) cdir->cd();
1810 // Write analysis manager in the analysis file
1811 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1812 // run local task configuration
1814 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1815 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1816 if (cdir) cdir->cd();
1820 // Terminate grid analysis
1821 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1822 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1823 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1824 if (!fGridHandler->MergeOutputs()) {
1825 // Return if outputs could not be merged or if it alien handler
1826 // was configured for offline mode or local testing.
1827 if (cdir) cdir->cd();
1831 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1832 if (cdir) cdir->cd();
1833 ImportWrappers(NULL);
1835 if (cdir) cdir->cd();
1839 SetEventLoop(kFALSE);
1840 // Enable event loop mode if a tree was provided
1841 if (tree || fGridHandler || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
1844 TString ttype = "TTree";
1845 if (tree && tree->IsA() == TChain::Class()) {
1846 chain = (TChain*)tree;
1847 if (!chain || !chain->GetListOfFiles()->First()) {
1848 Error("StartAnalysis", "Cannot process null or empty chain...");
1849 if (cdir) cdir->cd();
1855 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1856 if (getsysInfo) AliSysInfo::AddStamp("Start", 0);
1857 // Initialize locally all tasks (happens for all modes)
1859 AliAnalysisTask *task;
1863 case kLocalAnalysis:
1864 if (!tree && !fGridHandler) {
1865 TIter nextT(fTasks);
1866 // Call CreateOutputObjects for all tasks
1868 Bool_t dirStatus = TH1::AddDirectoryStatus();
1869 while ((task=(AliAnalysisTask*)nextT())) {
1870 TH1::AddDirectory(kFALSE);
1871 task->CreateOutputObjects();
1872 if (!task->CheckPostData()) {
1873 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
1874 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
1875 ########### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ###########", task->GetName(), task->ClassName());
1877 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
1881 TH1::AddDirectory(dirStatus);
1882 if (IsExternalLoop()) {
1883 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1884 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1891 fSelector = new AliAnalysisSelector(this);
1892 // Check if a plugin handler is used
1894 // Get the chain from the plugin
1895 TString dataType = "esdTree";
1896 if (fInputEventHandler) {
1897 dataType = fInputEventHandler->GetDataType();
1901 chain = fGridHandler->GetChainForTestMode(dataType);
1903 Error("StartAnalysis", "No chain for test mode. Aborting.");
1906 cout << "===== RUNNING LOCAL ANALYSIS" << GetName() << " ON CHAIN " << chain->GetName() << endl;
1907 retv = chain->Process(fSelector, "", nentries, firstentry);
1910 // Run tree-based analysis via AliAnalysisSelector
1911 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
1912 retv = tree->Process(fSelector, "", nentries, firstentry);
1914 case kProofAnalysis:
1916 // Check if the plugin is used
1918 return StartAnalysis(type, fGridHandler->GetProofDataSet(), nentries, firstentry);
1920 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1921 Error("StartAnalysis", "No PROOF!!! Exiting.");
1922 if (cdir) cdir->cd();
1925 line = Form("gProof->AddInput((TObject*)%p);", this);
1926 gROOT->ProcessLine(line);
1929 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
1930 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
1932 Error("StartAnalysis", "No chain!!! Exiting.");
1933 if (cdir) cdir->cd();
1939 if (!anaType.Contains("terminate")) {
1940 if (!fGridHandler) {
1941 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1942 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1943 if (cdir) cdir->cd();
1946 // Write analysis manager in the analysis file
1947 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1948 // Start the analysis via the handler
1949 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1950 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1951 if (cdir) cdir->cd();
1955 // Terminate grid analysis
1956 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1957 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1958 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1959 if (!fGridHandler->MergeOutputs()) {
1960 // Return if outputs could not be merged or if it alien handler
1961 // was configured for offline mode or local testing.
1962 if (cdir) cdir->cd();
1966 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1967 ImportWrappers(NULL);
1969 if (cdir) cdir->cd();
1971 case kMixingAnalysis:
1972 // Run event mixing analysis
1974 Error("StartAnalysis", "Cannot run event mixing without event pool");
1975 if (cdir) cdir->cd();
1978 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1979 fSelector = new AliAnalysisSelector(this);
1980 while ((chain=fEventPool->GetNextChain())) {
1982 // Call NotifyBinChange for all tasks
1983 while ((task=(AliAnalysisTask*)next()))
1984 if (!task->IsPostEventLoop()) task->NotifyBinChange();
1985 retv = chain->Process(fSelector);
1987 Error("StartAnalysis", "Mixing analysis failed");
1988 if (cdir) cdir->cd();
1992 PackOutput(fSelector->GetOutputList());
1995 if (cdir) cdir->cd();
1999 //______________________________________________________________________________
2000 Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
2002 // Start analysis for this manager on a given dataset. Analysis task can be:
2003 // LOCAL, PROOF or GRID. Process nentries starting from firstentry.
2005 Error("StartAnalysis","Analysis manager was not initialized !");
2009 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
2010 TString anaType = type;
2012 if (!anaType.Contains("proof")) {
2013 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
2016 fMode = kProofAnalysis;
2018 TString proofProcessOpt;
2019 SetEventLoop(kTRUE);
2020 // Set the dataset flag
2021 TObject::SetBit(kUseDataSet);
2024 // Start proof analysis using the grid handler
2025 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
2026 Error("StartAnalysis", "The grid plugin could not start PROOF analysis");
2029 // Check if the plugin is in test mode
2030 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kTest) {
2031 dataset = "test_collection";
2033 dataset = fGridHandler->GetProofDataSet();
2036 proofProcessOpt = fGridHandler->GetProofProcessOpt();
2039 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
2040 Error("StartAnalysis", "No PROOF!!! Exiting.");
2044 // Initialize locally all tasks
2047 line = Form("gProof->AddInput((TObject*)%p);", this);
2048 gROOT->ProcessLine(line);
2050 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"%s\", %lld, %lld);",
2051 dataset,proofProcessOpt.Data(), nentries, firstentry);
2052 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
2053 retv = (Long_t)gROOT->ProcessLine(line);
2057 //______________________________________________________________________________
2058 TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
2060 // Opens according the option the file specified by cont->GetFileName() and changes
2061 // current directory to cont->GetFolderName(). If the file was already opened, it
2062 // checks if the option UPDATE was preserved. File open via TProofOutputFile can
2063 // be optionally ignored.
2064 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2065 TString filename = cont->GetFileName();
2067 if (filename.IsNull()) {
2068 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
2071 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
2073 f = mgr->OpenProofFile(cont,option);
2075 // Check first if the file is already opened
2076 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2078 // Check if option "UPDATE" was preserved
2079 TString opt(option);
2081 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2082 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2084 f = TFile::Open(filename, option);
2087 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2091 // Check for a folder request
2092 TString dir = cont->GetFolderName();
2093 if (!dir.IsNull()) {
2094 if (!f->GetDirectory(dir)) f->mkdir(dir);
2099 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
2100 cont->SetFile(NULL);
2104 //______________________________________________________________________________
2105 TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option, const char *extaod)
2107 // Opens a special output file used in PROOF.
2109 TString filename = cont->GetFileName();
2110 if (cont == fCommonOutput) {
2111 if (fOutputEventHandler) {
2112 if (strlen(extaod)) filename = extaod;
2113 filename = fOutputEventHandler->GetOutputFileName();
2115 else Fatal("OpenProofFile","No output container. Exiting.");
2118 if (fMode!=kProofAnalysis || !fSelector) {
2119 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
2122 if (fSpecialOutputLocation.Length()) {
2123 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2125 // Check if option "UPDATE" was preserved
2126 TString opt(option);
2128 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2129 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2131 f = new TFile(filename, option);
2133 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2137 // Check for a folder request
2138 TString dir = cont->GetFolderName();
2140 if (!f->GetDirectory(dir)) f->mkdir(dir);
2145 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2146 cont->SetFile(NULL);
2149 // Check if there is already a proof output file in the output list
2150 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
2152 // Get the actual file
2153 line = Form("((TProofOutputFile*)%p)->GetFileName();", pof);
2154 filename = (const char*)gROOT->ProcessLine(line);
2156 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
2158 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2160 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
2163 // Check if option "UPDATE" was preserved
2164 TString opt(option);
2166 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2167 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
2169 if (cont->IsRegisterDataset()) {
2170 TString dsetName = filename;
2171 dsetName.ReplaceAll(".root", cont->GetTitle());
2172 dsetName.ReplaceAll(":","_");
2173 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
2174 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
2176 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
2177 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
2179 if (fDebug > 1) printf("=== %s\n", line.Data());
2180 gROOT->ProcessLine(line);
2181 line = Form("pf->OpenFile(\"%s\");", option);
2182 gROOT->ProcessLine(line);
2185 gROOT->ProcessLine("pf->Print()");
2186 printf(" == proof file name: %s", f->GetName());
2188 // Add to proof output list
2189 line = Form("((TList*)%p)->Add(pf);",fSelector->GetOutputList());
2190 if (fDebug > 1) printf("=== %s\n", line.Data());
2191 gROOT->ProcessLine(line);
2193 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2197 // Check for a folder request
2198 TString dir = cont->GetFolderName();
2199 if (!dir.IsNull()) {
2200 if (!f->GetDirectory(dir)) f->mkdir(dir);
2205 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2206 cont->SetFile(NULL);
2210 //______________________________________________________________________________
2211 void AliAnalysisManager::ExecAnalysis(Option_t *option)
2213 // Execute analysis.
2214 static Long64_t nentries = 0;
2215 static TTree *lastTree = 0;
2216 static TStopwatch *timer = new TStopwatch();
2217 // Only the first call to Process will trigger a true Notify. Other Notify
2218 // coming before is ignored.
2219 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) {
2220 TObject::SetBit(AliAnalysisManager::kTrueNotify);
2223 if (fDebug > 0) printf("MGR: Processing event #%d\n", fNcalls);
2225 if (fTree && (fTree != lastTree)) {
2226 nentries += fTree->GetEntries();
2229 if (!fNcalls) timer->Start();
2230 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", fNcalls, TMath::Min(fMaxEntries,nentries), timer, kFALSE);
2232 fIOTimer->Start(kTRUE);
2234 TDirectory *cdir = gDirectory;
2235 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
2236 if (getsysInfo && ((fNcalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)fNcalls);
2238 Error("ExecAnalysis", "Analysis manager was not initialized !");
2239 if (cdir) cdir->cd();
2243 AliAnalysisTask *task;
2244 // Check if the top tree is active.
2246 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2247 AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
2249 // De-activate all tasks
2250 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
2251 AliAnalysisDataContainer *cont = fCommonInput;
2252 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
2254 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
2255 if (cdir) cdir->cd();
2258 cont->SetData(fTree); // This will notify all consumers
2259 Long64_t entry = fTree->GetTree()->GetReadEntry();
2261 // Call BeginEvent() for optional input/output and MC services
2262 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
2263 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
2264 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
2266 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2267 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2269 // Execute the tasks
2270 // TIter next1(cont->GetConsumers());
2272 fIOTime += fIOTimer->RealTime();
2273 fCPUTimer->Start(kTRUE);
2274 TIter next1(fTopTasks);
2276 while ((task=(AliAnalysisTask*)next1())) {
2278 cout << " Executing task " << task->GetName() << endl;
2280 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
2281 task->ExecuteTask(option);
2282 if (fStatistics) fStatistics->StopTimer();
2284 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2285 AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
2289 fCPUTime += fCPUTimer->RealTime();
2290 fIOTimer->Start(kTRUE);
2292 // Call FinishEvent() for optional output and MC services
2293 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2294 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2295 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2296 // Gather system information if requested
2297 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2298 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1001, 1);
2299 if (cdir) cdir->cd();
2301 fIOTime += fIOTimer->RealTime();
2304 // The event loop is not controlled by TSelector
2306 // Call BeginEvent() for optional input/output and MC services
2307 fIOTimer->Start(kTRUE);
2308 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
2309 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
2310 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
2312 fIOTime += fIOTimer->RealTime();
2314 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2315 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2316 fCPUTimer->Start(kTRUE);
2317 TIter next2(fTopTasks);
2318 while ((task=(AliAnalysisTask*)next2())) {
2319 task->SetActive(kTRUE);
2321 cout << " Executing task " << task->GetName() << endl;
2323 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
2324 task->ExecuteTask(option);
2325 if (fStatistics) fStatistics->StopTimer();
2329 fCPUTime += fCPUTimer->RealTime();
2331 // Call FinishEvent() for optional output and MC services
2332 fIOTimer->Start(kTRUE);
2333 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2334 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2335 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2336 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2337 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
2338 if (cdir) cdir->cd();
2340 fIOTime += fIOTimer->RealTime();
2343 //______________________________________________________________________________
2344 Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
2346 // Check if the stdout is connected to a pipe (C.Holm)
2347 Bool_t ispipe = kFALSE;
2348 out.seekp(0, std::ios_base::cur);
2351 if (errno == ESPIPE) ispipe = kTRUE;
2356 //______________________________________________________________________________
2357 void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
2359 // Set the input event handler and create a container for it.
2361 fInputEventHandler = handler;
2362 if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
2365 //______________________________________________________________________________
2366 void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
2368 // Set the input event handler and create a container for it.
2370 fOutputEventHandler = handler;
2371 if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
2372 fCommonOutput->SetSpecialOutput();
2375 //______________________________________________________________________________
2376 void AliAnalysisManager::SetDebugLevel(UInt_t level)
2378 // Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
2379 if (TObject::TestBit(kUseProgressBar)) {
2380 Info("SetDebugLevel","Ignored. Disable the progress bar first.");
2386 //______________________________________________________________________________
2387 void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
2389 // Enable a text mode progress bar. Resets debug level to 0.
2390 Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
2391 TObject::SetBit(kUseProgressBar,flag);
2392 fPBUpdateFreq = freq;
2396 //______________________________________________________________________________
2397 void AliAnalysisManager::RegisterExtraFile(const char *fname)
2399 // This method is used externally to register output files which are not
2400 // connected to any output container, so that the manager can properly register,
2401 // retrieve or merge them when running in distributed mode. The file names are
2402 // separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
2403 if (fExtraFiles.Contains(fname)) return;
2404 if (fExtraFiles.Length()) fExtraFiles += " ";
2405 fExtraFiles += fname;
2408 //______________________________________________________________________________
2409 Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
2411 // Copy a file from the location specified ina the wrapper with the same name from the source list.
2415 TObject *pof = source->FindObject(filename);
2416 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
2417 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
2420 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
2421 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
2422 TString clientUrl(chUrl);
2423 TString fullPath_str(fullPath);
2424 if (clientUrl.Contains("localhost")){
2425 TObjArray* array = fullPath_str.Tokenize ( "//" );
2426 TObjString *strobj = ( TObjString *)array->At(1);
2427 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
2428 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
2429 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
2430 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
2431 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
2435 else if (clientUrl.Contains("__lite__")) {
2436 // Special case for ProofLite environement - get file info and copy.
2437 gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
2438 fullPath_str = Form("%s/%s", tmp, fullPath);
2441 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
2442 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
2444 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
2448 //______________________________________________________________________________
2449 void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
2451 // Fill analysis type in the provided string.
2453 case kLocalAnalysis:
2456 case kProofAnalysis:
2462 case kMixingAnalysis:
2467 //______________________________________________________________________________
2468 Bool_t AliAnalysisManager::ValidateOutputFiles() const
2470 // Validate all output files.
2471 TIter next(fOutputs);
2472 AliAnalysisDataContainer *output;
2473 TDirectory *cdir = gDirectory;
2474 TString openedFiles;
2475 while ((output=(AliAnalysisDataContainer*)next())) {
2476 if (output->IsRegisterDataset()) continue;
2477 TString filename = output->GetFileName();
2478 if (filename == "default") {
2479 if (!fOutputEventHandler) continue;
2480 filename = fOutputEventHandler->GetOutputFileName();
2481 // Main AOD may not be there
2482 if (gSystem->AccessPathName(filename)) continue;
2484 // Check if the file is closed
2485 if (openedFiles.Contains(filename)) continue;;
2486 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2488 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
2489 // Clear file list to release object ownership to user.
2493 file = TFile::Open(filename);
2494 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
2495 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
2496 if (cdir) cdir->cd();
2500 openedFiles += filename;
2503 if (cdir) cdir->cd();
2507 //______________________________________________________________________________
2508 void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
2510 // Implements a nice text mode progress bar.
2511 static Long64_t icount = 0;
2512 static TString oname;
2513 static TString nname;
2514 static Long64_t ocurrent = 0;
2515 static Long64_t osize = 0;
2516 static Int_t oseconds = 0;
2517 static TStopwatch *owatch = 0;
2518 static Bool_t oneoftwo = kFALSE;
2519 static Int_t nrefresh = 0;
2520 static Int_t nchecks = 0;
2521 static char lastChar = 0;
2522 const char symbol[4] = {'-','\\','|','/'};
2524 if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
2530 ocurrent = TMath::Abs(current);
2531 osize = TMath::Abs(size);
2532 if (ocurrent > osize) ocurrent=osize;
2537 if ((current % fPBUpdateFreq) != 0) return;
2539 char progress[11] = " ";
2540 Int_t ichar = icount%4;
2545 if (owatch && !last) {
2547 time = owatch->RealTime();
2548 seconds = int(time) % 60;
2549 minutes = (int(time) / 60) % 60;
2550 hours = (int(time) / 60 / 60);
2552 if (oseconds==seconds) {
2556 oneoftwo = !oneoftwo;
2560 if (refresh && oneoftwo) {
2562 if (nchecks <= 0) nchecks = nrefresh+1;
2563 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
2564 oname = Form(" == %d%% ==", pctdone);
2566 Double_t percent = 100.0*ocurrent/osize;
2567 Int_t nchar = Int_t(percent/10);
2568 if (nchar>10) nchar=10;
2570 for (i=0; i<nchar; i++) progress[i] = '=';
2571 progress[nchar] = symbol[ichar];
2572 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2573 progress[10] = '\0';
2576 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2577 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2578 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
2580 Int_t full = Int_t(ocurrent > 0 ?
2581 time * (float(osize)/ocurrent) + .5 :
2583 Int_t remain = Int_t(full - time);
2584 Int_t rsec = remain % 60;
2585 Int_t rmin = (remain / 60) % 60;
2586 Int_t rhour = (remain / 60 / 60);
2587 fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
2588 percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
2590 else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
2591 if (refresh && oneoftwo) oname = nname;
2592 if (owatch) owatch->Continue();
2601 fprintf(stderr, "\n");
2605 //______________________________________________________________________________
2606 void AliAnalysisManager::DoLoadBranch(const char *name)
2608 // Get tree and load branch if needed.
2609 static Long64_t crtEntry = -100;
2611 if (fAutoBranchHandling || !fTree)
2614 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2616 br = fTree->GetBranch(name);
2618 Error("DoLoadBranch", "Could not find branch %s",name);
2623 if (br->GetReadEntry()==fCurrentEntry) return;
2624 Long64_t readbytes = br->GetEntry(GetCurrentEntry());
2626 Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
2627 if (crtEntry != fCurrentEntry) {
2628 CountEvent(1,0,1,0);
2629 crtEntry = fCurrentEntry;
2632 if (crtEntry != fCurrentEntry) {
2633 CountEvent(1,1,0,0);
2634 crtEntry = fCurrentEntry;
2639 //______________________________________________________________________________
2640 void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
2642 // Add the statistics task to the manager.
2644 Info("AddStatisticsTask", "Already added");
2647 TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
2648 gROOT->ProcessLine(line);
2651 //______________________________________________________________________________
2652 void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
2654 // Bookkeep current event;
2655 if (!fStatistics) return;
2656 fStatistics->AddInput(ninput);
2657 fStatistics->AddProcessed(nprocessed);
2658 fStatistics->AddFailed(nfailed);
2659 fStatistics->AddAccepted(naccepted);
2662 //______________________________________________________________________________
2663 void AliAnalysisManager::AddStatisticsMsg(const char *line)
2665 // Add a line in the statistics message. If available, the statistics message is written
2666 // at the end of the SlaveTerminate phase on workers AND at the end of Terminate
2668 if (!strlen(line)) return;
2669 if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
2670 fStatisticsMsg += line;
2673 //______________________________________________________________________________
2674 void AliAnalysisManager::WriteStatisticsMsg(Int_t)
2676 // If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
2677 static Bool_t done = kFALSE;
2680 if (!fStatistics) return;
2682 AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
2683 AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
2684 AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
2685 AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
2686 out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
2687 fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
2688 fStatistics->GetNaccepted()), ios::out);
2689 out << fStatisticsMsg << endl;
2693 //______________________________________________________________________________
2694 const char* AliAnalysisManager::GetOADBPath()
2696 // returns the path of the OADB
2697 // this static function just depends on environment variables
2699 static TString oadbPath;
2701 if (gSystem->Getenv("OADB_PATH"))
2702 oadbPath = gSystem->Getenv("OADB_PATH");
2703 else if (gSystem->Getenv("ALICE_ROOT"))
2704 oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
2706 ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
2711 //______________________________________________________________________________
2712 void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
2714 // Define a custom string variable mapped to a global unique name. The variable
2715 // can be then retrieved by a given analysis macro via GetGlobalStr(key).
2716 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2718 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2721 Bool_t valid = kFALSE;
2722 TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
2724 ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
2727 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
2730 //______________________________________________________________________________
2731 const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
2733 // Static method to retrieve a global variable defined via SetGlobalStr.
2735 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2737 TObject *value = mgr->GetGlobals()->GetValue(key);
2738 if (!value) return 0;
2740 return value->GetName();
2743 //______________________________________________________________________________
2744 void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
2746 // Define a custom integer variable mapped to a global unique name. The variable
2747 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2748 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2750 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2753 Bool_t valid = kFALSE;
2754 Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
2756 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
2759 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
2762 //______________________________________________________________________________
2763 Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
2765 // Static method to retrieve a global variable defined via SetGlobalInt.
2767 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2769 TObject *value = mgr->GetGlobals()->GetValue(key);
2770 if (!value) return 0;
2772 TString s = value->GetName();
2776 //______________________________________________________________________________
2777 void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
2779 // Define a custom double precision variable mapped to a global unique name. The variable
2780 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2781 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2783 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2786 Bool_t valid = kFALSE;
2787 Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
2789 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
2792 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));
2795 //______________________________________________________________________________
2796 Double_t AliAnalysisManager::GetGlobalDbl(const char *key, Bool_t &valid)
2798 // Static method to retrieve a global variable defined via SetGlobalDbl.
2800 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2802 TObject *value = mgr->GetGlobals()->GetValue(key);
2803 if (!value) return 0;
2805 TString s = value->GetName();
2809 //______________________________________________________________________________
2810 void AliAnalysisManager::AddClassDebug(const char *className, Int_t debugLevel)
2812 // Sets Class debug level
2814 if (!fDebugOptions) {
2815 fDebugOptions = new TObjArray();
2816 fDebugOptions->SetOwner(kTRUE);
2819 TNamed *debugOpt = (TNamed*)fDebugOptions->FindObject(className);
2821 AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel,className).Data());
2822 fDebugOptions->Add(new TNamed(className,TString::Format("%d",debugLevel).Data()));
2824 TString oldDebugStr = debugOpt->GetTitle();
2825 Int_t oldDebug = oldDebugStr.Atoi();
2826 if (debugLevel > oldDebug) {
2827 AliWarning(TString::Format("Overwriting debug level to %d class %s, because it is higher then previously set (%d).",debugLevel,className,oldDebug).Data());
2828 debugOpt->SetTitle(TString::Format("%d",debugLevel).Data());
2830 AliWarning(TString::Format("Ignoring debug level to %d class %s, because it is smaller then previously set (%d).",debugLevel,className,oldDebug).Data());
2835 //______________________________________________________________________________
2836 void AliAnalysisManager::ApplyDebugOptions()
2838 // Apply debug options
2840 if (!fDebugOptions) return;
2842 TIter next(fDebugOptions);
2845 while ((debug=dynamic_cast<TNamed*>(next()))) {
2846 debugLevel = debug->GetTitle();
2847 AliInfo(TString::Format("Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()).Data());
2848 AliLog::SetClassDebugLevel(debug->GetName(), debugLevel.Atoi());
2852 //______________________________________________________________________________
2853 Bool_t AliAnalysisManager::IsMacroLoaded(const char * filename)
2855 // Check if a macro was loaded.
2856 return fgMacroNames.Contains(filename);
2859 //______________________________________________________________________________
2860 Int_t AliAnalysisManager::LoadMacro(const char *filename, Int_t *error, Bool_t check)
2862 // Redirection of gROOT->LoadMacro which makes sure the same macro is not loaded
2864 TString macroName = gSystem->BaseName(filename);
2865 // Strip appended +, ++, +g, +O
2866 Int_t index = macroName.Index("+");
2867 if (index>0) macroName.Remove(index);
2868 if (fgMacroNames.Contains(macroName)) {
2869 // Macro with the same name loaded already in this root session, do
2874 Int_t ret = gROOT->LoadMacro(filename,error,check);
2875 // In case of error return the error code
2876 if (ret) return ret;
2877 // Append the macro name to the loaded macros list
2878 fgMacroNames += macroName;
2879 fgMacroNames += " ";
2883 //______________________________________________________________________________
2884 void AliAnalysisManager::Lock()
2886 // Security lock. This is to detect NORMAL user errors and not really to
2887 // protect against intentional hacks.
2888 if (fLocked) return;
2890 if (fInputEventHandler) fInputEventHandler->Lock();
2891 if (fOutputEventHandler) fOutputEventHandler->Lock();
2892 if (fMCtruthEventHandler) fMCtruthEventHandler->Lock();
2893 Info("Lock","====== ANALYSIS MANAGER LOCKED ======");
2896 //______________________________________________________________________________
2897 void AliAnalysisManager::UnLock()
2899 // Verbose unlocking. Hackers will be punished ;-) ...
2900 if (!fLocked) return;
2902 if (fInputEventHandler) fInputEventHandler->UnLock();
2903 if (fOutputEventHandler) fOutputEventHandler->UnLock();
2904 if (fMCtruthEventHandler) fMCtruthEventHandler->UnLock();
2905 Info("UnLock", "====== ANALYSIS MANAGER UNLOCKED ======");
2908 //______________________________________________________________________________
2909 void AliAnalysisManager::Changed()
2911 // All critical setters pass through the Changed method that throws an exception
2912 // in case the lock was set.
2913 if (fLocked) Fatal("Changed","Critical setter called in locked mode");