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"
57 #include "AliVEvent.h"
58 #include "AliHLTTestInputHandler.h"
64 ClassImp(AliAnalysisManager)
66 AliAnalysisManager *AliAnalysisManager::fgAnalysisManager = NULL;
67 TString AliAnalysisManager::fgCommonFileName = "";
68 TString AliAnalysisManager::fgMacroNames = "";
69 Int_t AliAnalysisManager::fPBUpdateFreq = 1;
71 //______________________________________________________________________________
72 AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
75 fInputEventHandler(0),
76 fOutputEventHandler(0),
77 fMCtruthEventHandler(0),
81 fMode(kLocalAnalysis),
88 fSpecialOutputLocation(""),
98 fFileDescriptors(new TObjArray()),
99 fCurrentDescriptor(0),
106 fAutoBranchHandling(kTRUE),
107 fAsyncReading(kFALSE), // default prefetching on
112 fCacheSize(100000000), // default 100 MB
114 fRequestedBranches(),
124 // Default constructor.
125 fgAnalysisManager = this;
126 fgCommonFileName = "AnalysisResults.root";
127 if (TClass::IsCallingNew() != TClass::kDummyNew) {
128 fTasks = new TObjArray();
129 fTopTasks = new TObjArray();
130 fZombies = new TObjArray();
131 fContainers = new TObjArray();
132 fInputs = new TObjArray();
133 fOutputs = new TObjArray();
134 fParamCont = new TObjArray();
135 fExchangeCont = new TObjArray();
136 fGlobals = new TMap();
138 fIOTimer = new TStopwatch();
139 fCPUTimer = new TStopwatch();
140 fInitTimer = new TStopwatch();
144 //______________________________________________________________________________
145 AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
148 fInputEventHandler(NULL),
149 fOutputEventHandler(NULL),
150 fMCtruthEventHandler(NULL),
155 fInitOK(other.fInitOK),
156 fMustClean(other.fMustClean),
157 fIsRemote(other.fIsRemote),
158 fLocked(other.fLocked),
159 fMCLoop(other.fMCLoop),
160 fDebug(other.fDebug),
161 fSpecialOutputLocation(""),
171 fFileDescriptors(new TObjArray()),
172 fCurrentDescriptor(0),
177 fExtraFiles(other.fExtraFiles),
178 fFileInfoLog(other.fFileInfoLog),
179 fAutoBranchHandling(other.fAutoBranchHandling),
180 fAsyncReading(other.fAsyncReading),
183 fNcalls(other.fNcalls),
184 fMaxEntries(other.fMaxEntries),
185 fCacheSize(other.fCacheSize),
186 fStatisticsMsg(other.fStatisticsMsg),
187 fRequestedBranches(other.fRequestedBranches),
188 fStatistics(other.fStatistics),
189 fGlobals(other.fGlobals),
190 fIOTimer(new TStopwatch()),
191 fCPUTimer(new TStopwatch()),
192 fInitTimer(new TStopwatch()),
198 fTasks = new TObjArray(*other.fTasks);
199 fTopTasks = new TObjArray(*other.fTopTasks);
200 fZombies = new TObjArray(*other.fZombies);
201 fContainers = new TObjArray(*other.fContainers);
202 fInputs = new TObjArray(*other.fInputs);
203 fOutputs = new TObjArray(*other.fOutputs);
204 fParamCont = new TObjArray(*other.fParamCont);
205 fExchangeCont = new TObjArray(*other.fExchangeCont);
206 fgCommonFileName = "AnalysisResults.root";
207 fgAnalysisManager = this;
210 //______________________________________________________________________________
211 AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& other)
214 if (&other != this) {
215 TNamed::operator=(other);
216 fInputEventHandler = other.fInputEventHandler;
217 fOutputEventHandler = other.fOutputEventHandler;
218 fMCtruthEventHandler = other.fMCtruthEventHandler;
219 fEventPool = other.fEventPool;
222 fNSysInfo = other.fNSysInfo;
224 fInitOK = other.fInitOK;
225 fIsRemote = other.fIsRemote;
226 fLocked = other.fLocked;
227 fMCLoop = other.fMCLoop;
228 fDebug = other.fDebug;
229 fTasks = new TObjArray(*other.fTasks);
230 fTopTasks = new TObjArray(*other.fTopTasks);
231 fZombies = new TObjArray(*other.fZombies);
232 fContainers = new TObjArray(*other.fContainers);
233 fInputs = new TObjArray(*other.fInputs);
234 fOutputs = new TObjArray(*other.fOutputs);
235 fParamCont = new TObjArray(*other.fParamCont);
236 fExchangeCont = new TObjArray(*other.fExchangeCont);
237 fDebugOptions = NULL;
238 fFileDescriptors = new TObjArray();
239 fCurrentDescriptor = 0;
241 fCommonOutput = NULL;
244 fExtraFiles = other.fExtraFiles;
245 fFileInfoLog = other.fFileInfoLog;
246 fgCommonFileName = "AnalysisResults.root";
247 fgAnalysisManager = this;
248 fAutoBranchHandling = other.fAutoBranchHandling;
249 fAsyncReading = other.fAsyncReading;
250 fTable.Clear("nodelete");
251 fRunFromPath = other.fRunFromPath;
252 fNcalls = other. fNcalls;
253 fMaxEntries = other.fMaxEntries;
254 fCacheSize = other.fCacheSize;
255 fStatisticsMsg = other.fStatisticsMsg;
256 fRequestedBranches = other.fRequestedBranches;
257 fStatistics = other.fStatistics;
258 fGlobals = new TMap();
259 fIOTimer = new TStopwatch();
260 fCPUTimer = new TStopwatch();
261 fInitTimer = new TStopwatch();
269 //______________________________________________________________________________
270 AliAnalysisManager::~AliAnalysisManager()
273 if (fTasks) {fTasks->Delete(); delete fTasks;}
276 if (fContainers) {fContainers->Delete(); delete fContainers;}
280 delete fExchangeCont;
281 delete fDebugOptions;
283 delete fInputEventHandler;
284 delete fOutputEventHandler;
285 delete fMCtruthEventHandler;
287 if (fgAnalysisManager==this) fgAnalysisManager = NULL;
288 if (fGlobals) {fGlobals->DeleteAll(); delete fGlobals;}
289 if (fFileDescriptors) {fFileDescriptors->Delete(); delete fFileDescriptors;}
295 //______________________________________________________________________________
296 void AliAnalysisManager::CreateReadCache()
298 // Create cache for reading according fCacheSize and fAsyncReading.
299 if (!fTree || !fTree->GetCurrentFile()) {
300 Error("CreateReadCache","Current tree or tree file not yet defined");
304 if (fDebug) Info("CreateReadCache","=== Read caching disabled ===");
307 gEnv->SetValue("TFile.AsyncPrefetching",(Int_t)fAsyncReading);
308 if (fAsyncReading) gEnv->SetValue("Cache.Directory",Form("file://%s/cache", gSystem->WorkingDirectory()));
309 if (fAsyncReading) gEnv->SetValue("TFile.AsyncReading",1);
310 fTree->SetCacheSize(fCacheSize);
311 TTreeCache::SetLearnEntries(1); //<<< we can take the decision after 1 entry
312 if (!fAutoBranchHandling && !fRequestedBranches.IsNull()) {
313 TObjArray *arr = fRequestedBranches.Tokenize(",");
317 fTree->AddBranchToCache(obj->GetName(),kTRUE); //<<< add requested branches to cache
320 fTree->AddBranchToCache("*", kTRUE); //<<< add all branches to cache
323 Info("CreateReadCache","Read cache enabled %lld bytes with async reading=%d",fCacheSize, (Int_t)fAsyncReading);
328 //______________________________________________________________________________
329 Bool_t AliAnalysisManager::EventLoop(Long64_t nevents)
331 // Initialize an event loop where the data producer is the input handler
332 // The handler must implement MakeTree creating the tree of events (likely
333 // memory resident) and generate the current event in the method BeginEvent.
334 // If the tree is memory resident, the handler should never call TTree::Fill
336 cout << "===== RUNNING IN EVENT LOOP MODE: " << GetName() << endl;
337 if (!fInputEventHandler) {
338 Error("EventLoop", "No input handler: exiting");
341 TTree *tree = new TTree("DummyTree", "Dummy tree for AliAnalysisManager::EventLoop");
342 SetExternalLoop(kTRUE);
343 if (!Init(tree)) return kFALSE;
345 for (Long64_t iev=0; iev<nevents; iev++)
348 PackOutput(&dummyList);
354 //______________________________________________________________________________
355 Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
357 // Read one entry of the tree or a whole branch.
358 fCurrentEntry = entry;
359 if (!fAutoBranchHandling)
361 if (!fTree || !fTree->GetTree()) return -1;
362 fIOTimer->Start(kTRUE);
363 Long64_t readbytes = fTree->GetTree()->GetEntry(entry, getall);
365 fIOTime += fIOTimer->RealTime();
366 return (Int_t)readbytes;
369 //______________________________________________________________________________
370 Int_t AliAnalysisManager::GetRunFromAlienPath(const char *path)
372 // Attempt to extract run number from input data path. Works only for paths to
373 // alice data in alien.
374 // sim: /alice/sim/<production>/run_no/...
375 // data: /alice/data/year/period/000run_no/... (ESD or AOD)
376 TString type = "unknown";
378 if (s.Contains("/alice/data")) type = "real";
379 else if (s.Contains("/alice/sim")) type = "simulated";
382 ind1 = s.Index("/00");
384 ind2 = s.Index("/",ind1+1);
385 if (ind2-ind1>8) srun = s(ind1+1, ind2-ind1-1);
388 ind1 = s.Index("/LHC");
390 ind1 = s.Index("/",ind1+1);
392 ind2 = s.Index("/",ind1+1);
393 if (ind2>0) srun = s(ind1+1, ind2-ind1-1);
397 Int_t run = srun.Atoi();
398 if (run>0) printf("=== GetRunFromAlienPath: run %d of %s data ===\n", run, type.Data());
402 //______________________________________________________________________________
403 Bool_t AliAnalysisManager::Init(TTree *tree)
405 // The Init() function is called when the selector needs to initialize
406 // a new tree or chain. Typically here the branch addresses of the tree
407 // will be set. It is normaly not necessary to make changes to the
408 // generated code, but the routine can be extended by the user if needed.
409 // Init() will be called many times when running with PROOF.
410 Bool_t init = kFALSE;
411 if (!tree) return kFALSE; // Should not happen - protected in selector caller
413 printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
415 // Call InitTree of EventHandler
416 if (fOutputEventHandler) {
417 if (fMode == kProofAnalysis) {
418 init = fOutputEventHandler->Init(0x0, "proof");
420 init = fOutputEventHandler->Init(0x0, "local");
423 Error("Init", "Output event handler failed to initialize");
428 if (fInputEventHandler) {
429 if (fMode == kProofAnalysis) {
430 init = fInputEventHandler->Init(tree, "proof");
432 init = fInputEventHandler->Init(tree, "local");
435 Error("Init", "Input event handler failed to initialize tree");
439 // If no input event handler we need to get the tree once
441 if(!tree->GetTree()) {
442 Long64_t readEntry = tree->LoadTree(0);
443 if (readEntry == -2) {
444 Error("Init", "Input tree has no entry. Exiting");
450 if (fMCtruthEventHandler) {
451 if (fMode == kProofAnalysis) {
452 init = fMCtruthEventHandler->Init(0x0, "proof");
454 init = fMCtruthEventHandler->Init(0x0, "local");
457 Error("Init", "MC event handler failed to initialize");
462 if (!fInitOK) InitAnalysis();
463 if (!fInitOK) return kFALSE;
465 if (fMode != kProofAnalysis) CreateReadCache();
467 // cholm - here we should re-add to the table or branches
470 AliAnalysisDataContainer *top = fCommonInput;
471 if (!top) top = (AliAnalysisDataContainer*)fInputs->At(0);
473 Error("Init","No top input container !");
477 CheckBranches(kFALSE);
480 printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
485 //______________________________________________________________________________
486 void AliAnalysisManager::SlaveBegin(TTree *tree)
488 // The SlaveBegin() function is called after the Begin() function.
489 // When running with PROOF SlaveBegin() is called on each slave server.
490 // The tree argument is deprecated (on PROOF 0 is passed).
491 if (fDebug > 1) printf("->AliAnalysisManager::SlaveBegin()\n");
492 // Init timer should be already started
493 // Apply debug options
496 fMCtruthEventHandler &&
497 (fMode != kProofAnalysis)) fMCtruthEventHandler->SetCacheSize(fCacheSize);
498 if (!CheckTasks()) Fatal("SlaveBegin", "Not all needed libraries were loaded");
499 static Bool_t isCalled = kFALSE;
500 Bool_t init = kFALSE;
501 Bool_t initOK = kTRUE;
503 TDirectory *curdir = gDirectory;
504 // Call SlaveBegin only once in case of mixing
505 if (isCalled && fMode==kMixingAnalysis) return;
507 // Call Init of EventHandler
508 if (fOutputEventHandler) {
509 if (fMode == kProofAnalysis) {
510 // Merging AOD's in PROOF via TProofOutputFile
511 if (fDebug > 1) printf(" Initializing AOD output file %s...\n", fOutputEventHandler->GetOutputFileName());
512 init = fOutputEventHandler->Init("proof");
513 if (!init) msg = "Failed to initialize output handler on worker";
515 init = fOutputEventHandler->Init("local");
516 if (!init) msg = "Failed to initialize output handler";
519 if (!fSelector) Error("SlaveBegin", "Selector not set");
520 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
523 if (fInputEventHandler) {
524 fInputEventHandler->SetInputTree(tree);
525 if (fMode == kProofAnalysis) {
526 init = fInputEventHandler->Init("proof");
527 if (!init) msg = "Failed to initialize input handler on worker";
529 init = fInputEventHandler->Init("local");
530 if (!init) msg = "Failed to initialize input handler";
533 if (!fSelector) Error("SlaveBegin", "Selector not set");
534 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
537 if (fMCtruthEventHandler) {
538 if (fMode == kProofAnalysis) {
539 init = fMCtruthEventHandler->Init("proof");
540 if (!init) msg = "Failed to initialize MC handler on worker";
542 init = fMCtruthEventHandler->Init("local");
543 if (!init) msg = "Failed to initialize MC handler";
546 if (!fSelector) Error("SlaveBegin", "Selector not set");
547 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
549 if (curdir) curdir->cd();
553 AliAnalysisTask *task;
554 // Call CreateOutputObjects for all tasks
555 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
556 Bool_t dirStatus = TH1::AddDirectoryStatus();
558 while ((task=(AliAnalysisTask*)next())) {
560 // Start with memory as current dir and make sure by default histograms do not get attached to files.
561 TH1::AddDirectory(kFALSE);
562 task->CreateOutputObjects();
563 if (!task->CheckPostData()) {
564 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
565 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
566 ####### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ##########", task->GetName(), task->ClassName());
568 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
571 TH1::AddDirectory(dirStatus);
572 if (curdir) curdir->cd();
574 fInitTime += fInitTimer->RealTime();
575 fInitTimer->Continue();
576 printf("Initialization time: %g [sec]\n", fInitTime);
577 if (fDebug > 1) printf("<-AliAnalysisManager::SlaveBegin()\n");
580 //______________________________________________________________________________
581 Bool_t AliAnalysisManager::Notify()
583 // The Notify() function is called when a new file is opened. This
584 // can be either for a new TTree in a TChain or when when a new TTree
585 // is started when using PROOF. It is normaly not necessary to make changes
586 // to the generated code, but the routine can be extended by the
587 // user if needed. The return value is currently not used.
588 fIOTimer->Start(kTRUE);
589 if (!fTree) return kFALSE;
590 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) return kFALSE;
592 fTable.Clear("nodelete"); // clearing the hash table may not be needed -> C.L.
593 if (fMode == kProofAnalysis) fIsRemote = kTRUE;
595 TFile *curfile = fTree->GetCurrentFile();
597 Error("Notify","No current file");
600 if (IsCollectThroughput()) {
601 if (fCurrentDescriptor) fCurrentDescriptor->Done();
602 fCurrentDescriptor = new AliAnalysisFileDescriptor(curfile);
603 fFileDescriptors->Add(fCurrentDescriptor);
606 if (fDebug > 1) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
607 Int_t run = AliAnalysisManager::GetRunFromAlienPath(curfile->GetName());
608 if (run && (run != fRunFromPath)) {
610 if (fDebug > 1) printf(" ### run found from path: %d\n", run);
613 AliAnalysisTask *task;
615 // Call Notify of the event handlers
616 if (fInputEventHandler) {
617 fInputEventHandler->Notify(curfile->GetName());
620 if (fOutputEventHandler) {
621 fOutputEventHandler->Notify(curfile->GetName());
624 if (fMCtruthEventHandler) {
625 fMCtruthEventHandler->Notify(curfile->GetName());
628 // Call Notify for all tasks
629 while ((task=(AliAnalysisTask*)next()))
632 if (fDebug > 1) printf("<-AliAnalysisManager::Notify()\n");
634 fIOTime += fIOTimer->RealTime();
638 //______________________________________________________________________________
639 Bool_t AliAnalysisManager::Process(Long64_t)
641 // The Process() function is called for each entry in the tree (or possibly
642 // keyed object in the case of PROOF) to be processed. The entry argument
643 // specifies which entry in the currently loaded tree is to be processed.
644 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
645 // to read either all or the required parts of the data. When processing
646 // keyed objects with PROOF, the object is already loaded and is available
647 // via the fObject pointer.
649 // This function should contain the "body" of the analysis. It can contain
650 // simple or elaborate selection criteria, run algorithms on the data
651 // of the event and typically fill histograms.
653 // WARNING when a selector is used with a TChain, you must use
654 // the pointer to the current TTree to call GetEntry(entry).
655 // The entry is always the local entry number in the current tree.
656 // Assuming that fChain is the pointer to the TChain being processed,
657 // use fChain->GetTree()->GetEntry(entry).
659 // This method is obsolete. ExecAnalysis is called instead.
663 //______________________________________________________________________________
664 void AliAnalysisManager::PackOutput(TList *target)
666 // Pack all output data containers in the output list. Called at SlaveTerminate
667 // stage in PROOF case for each slave.
668 if (fDebug > 1) printf("->AliAnalysisManager::PackOutput()\n");
669 fIOTimer->Start(kTRUE);
671 if (IsCollectThroughput()) {
672 if (fCurrentDescriptor) fCurrentDescriptor->Done();
673 fFileDescriptors->Print();
674 if (fFileInfoLog.IsNull()) fFileInfoLog = "fileinfo.log";
675 out.open(fFileInfoLog, std::ios::app);
676 if (out.bad()) Error("SavePrimitive", "Bad file name: %s", fFileInfoLog.Data());
678 TIter nextflog(fFileDescriptors);
680 while ((log=nextflog())) log->SavePrimitive(out,"");
684 Error("PackOutput", "No target. Exiting.");
687 TDirectory *cdir = gDirectory;
689 if (fInputEventHandler) fInputEventHandler ->Terminate();
690 if (fOutputEventHandler) fOutputEventHandler ->Terminate();
691 if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
694 // Call FinishTaskOutput() for each event loop task (not called for
695 // post-event loop tasks - use Terminate() fo those)
696 TIter nexttask(fTasks);
697 AliAnalysisTask *task;
698 while ((task=(AliAnalysisTask*)nexttask())) {
699 if (!task->IsPostEventLoop()) {
700 if (fDebug > 1) printf("->FinishTaskOutput: task %s\n", task->GetName());
701 task->FinishTaskOutput();
703 if (fDebug > 1) printf("<-FinishTaskOutput: task %s\n", task->GetName());
706 // Write statistics message on the workers.
707 if (fStatistics) WriteStatisticsMsg(fNcalls);
709 if (fMode == kProofAnalysis) {
710 TIter next(fOutputs);
711 AliAnalysisDataContainer *output;
712 Bool_t isManagedByHandler = kFALSE;
715 while ((output=(AliAnalysisDataContainer*)next())) {
716 // Do not consider outputs of post event loop tasks
717 isManagedByHandler = kFALSE;
718 if (output->GetProducer() && output->GetProducer()->IsPostEventLoop()) continue;
719 const char *filename = output->GetFileName();
720 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
721 isManagedByHandler = kTRUE;
722 printf("#### Handler output. Extra: %s\n", fExtraFiles.Data());
723 filename = fOutputEventHandler->GetOutputFileName();
725 // Check if data was posted to this container. If not, issue an error.
726 if (!output->GetData() && !isManagedByHandler) {
727 Error("PackOutput", "No data for output container %s. Forgot to PostData ?", output->GetName());
730 if (!output->IsSpecialOutput()) {
732 if (strlen(filename) && !isManagedByHandler) {
733 // Backup current folder
734 TDirectory *opwd = gDirectory;
735 // File resident outputs.
736 // Check first if the file exists.
737 TString openoption = "RECREATE";
738 Bool_t firsttime = kTRUE;
739 if (filestmp.FindObject(output->GetFileName())) {
742 filestmp.Add(new TNamed(output->GetFileName(),""));
744 if (!gSystem->AccessPathName(output->GetFileName()) && !firsttime) openoption = "UPDATE";
745 // TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
746 // Save data to file, then close.
747 if (output->GetData()->InheritsFrom(TCollection::Class())) {
748 // If data is a collection, we set the name of the collection
749 // as the one of the container and we save as a single key.
750 TCollection *coll = (TCollection*)output->GetData();
751 coll->SetName(output->GetName());
752 // coll->Write(output->GetName(), TObject::kSingleKey);
754 if (output->GetData()->InheritsFrom(TTree::Class())) {
755 TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
756 // Save data to file, then close.
757 TTree *tree = (TTree*)output->GetData();
758 // Check if tree is in memory
759 if (tree->GetDirectory()==gROOT) tree->SetDirectory(gDirectory);
763 // output->GetData()->Write();
766 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
768 // printf(" file %s listing content:\n", filename);
771 // Clear file list to release object ownership to user.
774 output->SetFile(NULL);
775 // Restore current directory
776 if (opwd) opwd->cd();
778 // Memory-resident outputs
779 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
781 AliAnalysisDataWrapper *wrap = 0;
782 if (isManagedByHandler) {
783 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
784 wrap->SetName(output->GetName());
786 else wrap =output->ExportData();
787 // Output wrappers must NOT delete data after merging - the user owns them
788 wrap->SetDeleteData(kFALSE);
791 // Special outputs. The file must be opened and connected to the container.
792 TDirectory *opwd = gDirectory;
793 TFile *file = output->GetFile();
795 AliAnalysisTask *producer = output->GetProducer();
797 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
798 output->GetFileName(), output->GetName(), producer->ClassName());
801 TString outFilename = file->GetName();
802 if (fDebug > 1) printf("PackOutput %s: special output\n", output->GetName());
803 if (isManagedByHandler) {
804 // Terminate IO for files managed by the output handler
805 // file->Write() moved to AOD handler (A.G. 11.01.10)
806 // if (file) file->Write();
807 if (file && fDebug > 2) {
808 printf(" handled file %s listing content:\n", file->GetName());
811 fOutputEventHandler->TerminateIO();
814 // Release object ownership to users after writing data to file
815 if (output->GetData()->InheritsFrom(TCollection::Class())) {
816 // If data is a collection, we set the name of the collection
817 // as the one of the container and we save as a single key.
818 TCollection *coll = (TCollection*)output->GetData();
819 coll->SetName(output->GetName());
820 coll->Write(output->GetName(), TObject::kSingleKey);
822 if (output->GetData()->InheritsFrom(TTree::Class())) {
823 TTree *tree = (TTree*)output->GetData();
824 tree->SetDirectory(file);
827 output->GetData()->Write();
831 printf(" file %s listing content:\n", output->GetFileName());
834 // Clear file list to release object ownership to user.
837 output->SetFile(NULL);
839 // Restore current directory
840 if (opwd) opwd->cd();
841 // Check if a special output location was provided or the output files have to be merged
842 if (strlen(fSpecialOutputLocation.Data())) {
843 TString remote = fSpecialOutputLocation;
845 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
846 if (remote.BeginsWith("alien:")) {
847 gROOT->ProcessLine("TGrid::Connect(\"alien:\", gProofServ->GetUser());");
848 remote += outFilename;
849 remote.ReplaceAll(".root", Form("_%d.root", gid));
851 remote += Form("%s_%d_", gSystem->HostName(), gid);
852 remote += outFilename;
855 Info("PackOutput", "Output file for container %s to be copied \n at: %s. No merging.",
856 output->GetName(), remote.Data());
857 TFile::Cp ( outFilename.Data(), remote.Data() );
858 // Copy extra outputs
859 if (fExtraFiles.Length() && isManagedByHandler) {
860 TObjArray *arr = fExtraFiles.Tokenize(" ");
862 TIter nextfilename(arr);
863 while ((os=(TObjString*)nextfilename())) {
864 outFilename = os->GetString();
865 remote = fSpecialOutputLocation;
867 if (remote.BeginsWith("alien://")) {
868 remote += outFilename;
869 remote.ReplaceAll(".root", Form("_%d.root", gid));
871 remote += Form("%s_%d_", gSystem->HostName(), gid);
872 remote += outFilename;
875 Info("PackOutput", "Extra AOD file %s to be copied \n at: %s. No merging.",
876 outFilename.Data(), remote.Data());
877 TFile::Cp ( outFilename.Data(), remote.Data() );
882 // No special location specified-> use TProofOutputFile as merging utility
883 // The file at this output slot must be opened in CreateOutputObjects
884 if (fDebug > 1) printf(" File for container %s to be merged via file merger...\n", output->GetName());
889 fIOTime += fIOTimer->RealTime();
890 if ((fDebug || IsCollectThroughput())) {
892 fInitTime = fInitTimer->RealTime()-fIOTime-fCPUTime;
893 printf("=Analysis %s= init time: %g[sec]\
894 \n I/O & data mng.: %g [sec]\
895 \n task execution: %g [sec]\
896 \n total time: CPU=%g [sec] REAL=%g[sec]\n",
897 GetName(), fInitTime, fIOTime, fCPUTime, fInitTimer->CpuTime(), fInitTimer->RealTime());
898 if (IsCollectThroughput()) {
899 out << "#summary#########################################################" << endl;
900 out << "train_name " << GetName() << endl;
901 out << "root_time " << fInitTimer->RealTime() << endl;
902 out << "root_cpu " << fInitTimer->CpuTime() << endl;
903 out << "init_time " << fInitTime << endl;
904 out << "io_mng_time " << fIOTime << endl;
905 out << "exec_time " << fCPUTime << endl;
906 TString aliensite = gSystem->Getenv("ALIEN_SITE");
907 out << "alien_site " << aliensite << endl;
909 TString hostname = gSystem->Getenv("ALIEN_HOSTNAME");
910 if (hostname.IsNull()) {
912 gSystem->Exec(Form("hostname -f >> %s", fFileInfoLog.Data()));
914 out << hostname << endl;
919 if (cdir) cdir->cd();
920 if (fDebug > 1) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
923 //______________________________________________________________________________
924 void AliAnalysisManager::ImportWrappers(TList *source)
926 // Import data in output containers from wrappers coming in source.
927 if (fDebug > 1) printf("->AliAnalysisManager::ImportWrappers()\n");
928 fIOTimer->Start(kTRUE);
929 TIter next(fOutputs);
930 AliAnalysisDataContainer *cont;
931 AliAnalysisDataWrapper *wrap;
933 Bool_t inGrid = (fMode == kGridAnalysis)?kTRUE:kFALSE;
934 TDirectory *cdir = gDirectory;
935 while ((cont=(AliAnalysisDataContainer*)next())) {
937 if (cont->GetProducer() && cont->GetProducer()->IsPostEventLoop() && !inGrid) continue;
938 if (cont->IsRegisterDataset()) continue;
939 const char *filename = cont->GetFileName();
940 Bool_t isManagedByHandler = kFALSE;
941 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
942 isManagedByHandler = kTRUE;
943 filename = fOutputEventHandler->GetOutputFileName();
945 if (cont->IsSpecialOutput() || inGrid) {
946 if (strlen(fSpecialOutputLocation.Data())) continue;
947 // Copy merged file from PROOF scratch space.
948 // In case of grid the files are already in the current directory.
950 if (isManagedByHandler && fExtraFiles.Length()) {
951 // Copy extra registered dAOD files.
952 TObjArray *arr = fExtraFiles.Tokenize(" ");
954 TIter nextfilename(arr);
955 while ((os=(TObjString*)nextfilename())) GetFileFromWrapper(os->GetString(), source);
958 if (!GetFileFromWrapper(filename, source)) continue;
960 // Normally we should connect data from the copied file to the
961 // corresponding output container, but it is not obvious how to do this
962 // automatically if several objects in file...
963 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
964 if (!f) f = TFile::Open(filename, "READ");
966 Error("ImportWrappers", "Cannot open file %s in read-only mode", filename);
971 // Cd to the directory pointed by the container
972 TString folder = cont->GetFolderName();
973 if (!folder.IsNull()) f->cd(folder);
974 // Try to fetch first an object having the container name.
975 obj = gDirectory->Get(cont->GetName());
977 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",
978 cont->GetType()->GetName(), cont->GetName(), filename, cont->GetFolderName(), cont->GetName());
981 wrap = new AliAnalysisDataWrapper(obj);
982 wrap->SetDeleteData(kFALSE);
984 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
986 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
991 printf(" Importing data for container %s\n", cont->GetName());
992 if (strlen(filename)) printf(" -> file %s\n", filename);
995 cont->ImportData(wrap);
997 if (cdir) cdir->cd();
999 fIOTime += fIOTimer->RealTime();
1000 if (fDebug > 1) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
1003 //______________________________________________________________________________
1004 void AliAnalysisManager::UnpackOutput(TList *source)
1006 // Called by AliAnalysisSelector::Terminate only on the client.
1007 fIOTimer->Start(kTRUE);
1008 if (fDebug > 1) printf("->AliAnalysisManager::UnpackOutput()\n");
1010 Error("UnpackOutput", "No target. Exiting.");
1013 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
1015 if (fMode == kProofAnalysis) ImportWrappers(source);
1017 TIter next(fOutputs);
1018 AliAnalysisDataContainer *output;
1019 while ((output=(AliAnalysisDataContainer*)next())) {
1020 if (!output->GetData()) continue;
1021 // Check if there are client tasks that run post event loop
1022 if (output->HasConsumers()) {
1023 // Disable event loop semaphore
1024 output->SetPostEventLoop(kTRUE);
1025 TObjArray *list = output->GetConsumers();
1026 Int_t ncons = list->GetEntriesFast();
1027 for (Int_t i=0; i<ncons; i++) {
1028 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
1029 task->CheckNotify(kTRUE);
1030 // If task is active, execute it
1031 if (task->IsPostEventLoop() && task->IsActive()) {
1032 if (fDebug > 1) printf("== Executing post event loop task %s\n", task->GetName());
1033 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
1034 task->ExecuteTask();
1037 if (fStatistics) fStatistics->StopTimer();
1041 fIOTime += fIOTimer->RealTime();
1042 if (fDebug > 1) printf("<-AliAnalysisManager::UnpackOutput()\n");
1045 //______________________________________________________________________________
1046 void AliAnalysisManager::Terminate()
1048 // The Terminate() function is the last function to be called during
1049 // a query. It always runs on the client, it can be used to present
1050 // the results graphically.
1051 if (fDebug > 1) printf("->AliAnalysisManager::Terminate()\n");
1052 fInitTimer->Start(kTRUE);
1053 TDirectory *cdir = gDirectory;
1055 AliAnalysisTask *task;
1056 AliAnalysisDataContainer *output;
1059 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1060 // Call Terminate() for tasks
1062 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
1063 // Save all the canvases produced by the Terminate
1064 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
1068 AliSysInfo::AddStamp(Form("%s_TERMINATE",task->ClassName()),0, itask, 2);
1070 if (TObject::TestBit(kSaveCanvases)) {
1071 if (!gROOT->IsBatch()) {
1072 if (fDebug>1) printf("Waiting 5 sec for %s::Terminate() to finish drawing ...\n", task->ClassName());
1074 while (timer.RealTime()<5) {
1076 gSystem->ProcessEvents();
1079 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
1080 if (iend==0) continue;
1082 for (Int_t ipict=0; ipict<iend; ipict++) {
1083 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
1084 if (!canvas) continue;
1085 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
1087 gROOT->GetListOfCanvases()->Delete();
1091 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
1092 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
1093 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
1095 TObjArray *allOutputs = new TObjArray();
1097 for (icont=0; icont<fOutputs->GetEntriesFast(); icont++) allOutputs->Add(fOutputs->At(icont));
1098 if (!IsSkipTerminate())
1099 for (icont=0; icont<fParamCont->GetEntriesFast(); icont++) allOutputs->Add(fParamCont->At(icont));
1100 TIter next1(allOutputs);
1101 TString handlerFile = "";
1102 TString extraOutputs = "";
1103 if (fOutputEventHandler) {
1104 handlerFile = fOutputEventHandler->GetOutputFileName();
1105 extraOutputs = fOutputEventHandler->GetExtraOutputs();
1109 while ((output=(AliAnalysisDataContainer*)next1())) {
1110 // Special outputs or grid files have the files already closed and written.
1112 if (fMode == kGridAnalysis && icont<=fOutputs->GetEntriesFast()) continue;
1113 if (fMode == kProofAnalysis) {
1114 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
1116 const char *filename = output->GetFileName();
1117 TString openoption = "RECREATE";
1118 if (!(strcmp(filename, "default"))) continue;
1119 if (!strlen(filename)) continue;
1120 if (!output->GetData()) continue;
1121 TDirectory *opwd = gDirectory;
1122 TFile *file = output->GetFile();
1123 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1125 //if (handlerFile == filename && !gSystem->AccessPathName(filename)) openoption = "UPDATE";
1126 Bool_t firsttime = kTRUE;
1127 if (filestmp.FindObject(filename) || extraOutputs.Contains(filename)) {
1130 filestmp.Add(new TNamed(filename,""));
1132 if (!gSystem->AccessPathName(filename) && !firsttime) openoption = "UPDATE";
1133 if (fDebug>1) printf("Opening file: %s option=%s\n",filename, openoption.Data());
1134 file = new TFile(filename, openoption);
1136 if (fDebug>1) printf("File <%s> already opened with option: <%s> \n", filename, file->GetOption());
1137 openoption = file->GetOption();
1138 if (openoption == "READ") {
1139 if (fDebug>1) printf("...reopening in UPDATE mode\n");
1140 file->ReOpen("UPDATE");
1143 if (file->IsZombie()) {
1144 Error("Terminate", "Cannot open output file %s", filename);
1147 output->SetFile(file);
1149 // Check for a folder request
1150 TString dir = output->GetFolderName();
1151 if (!dir.IsNull()) {
1152 if (!file->GetDirectory(dir)) file->mkdir(dir);
1155 if (fDebug > 1) printf("...writing container %s to file %s:%s\n", output->GetName(), file->GetName(), output->GetFolderName());
1156 if (output->GetData()->InheritsFrom(TCollection::Class())) {
1157 // If data is a collection, we set the name of the collection
1158 // as the one of the container and we save as a single key.
1159 TCollection *coll = (TCollection*)output->GetData();
1160 coll->SetName(output->GetName());
1161 coll->Write(output->GetName(), TObject::kSingleKey);
1163 if (output->GetData()->InheritsFrom(TTree::Class())) {
1164 TTree *tree = (TTree*)output->GetData();
1165 tree->SetDirectory(gDirectory);
1168 output->GetData()->Write();
1171 if (opwd) opwd->cd();
1175 TString copiedFiles;
1176 while ((output=(AliAnalysisDataContainer*)next1())) {
1177 // Close all files at output
1178 TDirectory *opwd = gDirectory;
1179 if (output->GetFile()) {
1180 // Clear file list to release object ownership to user.
1181 // output->GetFile()->Clear();
1182 output->GetFile()->Close();
1183 // Copy merged outputs in alien if requested
1184 if (fSpecialOutputLocation.BeginsWith("alien://")) {
1185 if (copiedFiles.Contains(output->GetFile()->GetName())) {
1186 if (opwd) opwd->cd();
1187 output->SetFile(NULL);
1190 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
1191 gROOT->ProcessLine("if (!gGrid) TGrid::Connect(\"alien:\");");
1192 TFile::Cp(output->GetFile()->GetName(),
1193 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
1194 copiedFiles += output->GetFile()->GetName();
1196 output->SetFile(NULL);
1198 if (opwd) opwd->cd();
1201 //Write statistics information on the client
1202 if (fStatistics) WriteStatisticsMsg(fNcalls);
1204 TDirectory *crtdir = gDirectory;
1205 TFile f("syswatch.root", "RECREATE");
1208 if (!f.IsZombie()) {
1209 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
1210 tree->SetName("syswatch");
1211 tree->SetMarkerStyle(kCircle);
1212 tree->SetMarkerColor(kBlue);
1213 tree->SetMarkerSize(0.5);
1214 if (!gROOT->IsBatch()) {
1215 tree->SetAlias("event", "id0");
1216 tree->SetAlias("task", "id1");
1217 tree->SetAlias("stage", "id2");
1218 // Already defined aliases
1219 // tree->SetAlias("deltaT","stampSec-stampOldSec");
1220 // tree->SetAlias("T","stampSec-first");
1221 // tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)");
1222 // tree->SetAlias("VM","pI.fMemVirtual");
1223 TCanvas *canvas = new TCanvas("SysInfo","SysInfo",10,10,1200,800);
1224 Int_t npads = 1 /*COO plot for all tasks*/ +
1225 fTopTasks->GetEntries() /*Exec plot per task*/ +
1226 1 /*Terminate plot for all tasks*/ +
1229 Int_t iopt = (Int_t)TMath::Sqrt((Double_t)npads);
1230 if (npads<iopt*(iopt+1))
1231 canvas->Divide(iopt, iopt+1, 0.01, 0.01);
1233 canvas->Divide(iopt+1, iopt+1, 0.01, 0.01);
1235 // draw the plot of deltaVM for Exec for each task
1236 for (itask=0; itask<fTopTasks->GetEntriesFast(); itask++) {
1237 task = (AliAnalysisTask*)fTopTasks->At(itask);
1239 cut = Form("task==%d && stage==1", itask);
1240 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1241 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1243 hist->SetTitle(Form("%s: Exec dVM[MB]/event", task->GetName()));
1244 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1247 // Draw the plot of deltaVM for CreateOutputObjects for all tasks
1249 tree->SetMarkerStyle(kFullTriangleUp);
1250 tree->SetMarkerColor(kRed);
1251 tree->SetMarkerSize(0.8);
1252 cut = "task>=0 && task<1000 && stage==0";
1253 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1254 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1256 hist->SetTitle("Memory in CreateOutputObjects()");
1257 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1258 hist->GetXaxis()->SetTitle("task");
1260 // draw the plot of deltaVM for Terminate for all tasks
1262 tree->SetMarkerStyle(kOpenSquare);
1263 tree->SetMarkerColor(kMagenta);
1264 cut = "task>=0 && task<1000 && stage==2";
1265 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1266 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1268 hist->SetTitle("Memory in Terminate()");
1269 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1270 hist->GetXaxis()->SetTitle("task");
1274 tree->SetMarkerStyle(kFullCircle);
1275 tree->SetMarkerColor(kGreen);
1276 cut = Form("task==%d && stage==1",fTopTasks->GetEntriesFast()-1);
1277 tree->Draw("VM:event",cut,"", 1234567890, 0);
1278 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1280 hist->SetTitle("Virtual memory");
1281 hist->GetYaxis()->SetTitle("VM [MB]");
1285 tree->SetMarkerStyle(kCircle);
1286 tree->SetMarkerColor(kBlue);
1287 tree->SetMarkerSize(0.5);
1292 if (crtdir) crtdir->cd();
1294 // Validate the output files
1295 if (ValidateOutputFiles() && fIsRemote && fMode!=kProofAnalysis) {
1297 out.open("outputs_valid", ios::out);
1300 if (cdir) cdir->cd();
1302 if (fDebug || IsCollectThroughput()) {
1303 printf("=Analysis %s= Terminate time: %g[sec]\n", GetName(), fInitTimer->RealTime());
1305 if (fDebug > 1) printf("<-AliAnalysisManager::Terminate()\n");
1307 //______________________________________________________________________________
1308 void AliAnalysisManager::ProfileTask(Int_t itop, const char *option) const
1310 // Profiles the task having the itop index in the list of top (first level) tasks.
1311 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->At(itop);
1313 Error("ProfileTask", "There are only %d top tasks in the manager", fTopTasks->GetEntries());
1316 ProfileTask(task->GetName(), option);
1319 //______________________________________________________________________________
1320 void AliAnalysisManager::ProfileTask(const char *name, const char */*option*/) const
1322 // Profile a managed task after the execution of the analysis in case NSysInfo
1324 if (gSystem->AccessPathName("syswatch.root")) {
1325 Error("ProfileTask", "No file syswatch.root found in the current directory");
1328 if (gROOT->IsBatch()) return;
1329 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->FindObject(name);
1331 Error("ProfileTask", "No top task named %s known by the manager.", name);
1334 Int_t itop = fTopTasks->IndexOf(task);
1335 Int_t itask = fTasks->IndexOf(task);
1336 // Create canvas with 2 pads: first draw COO + Terminate, second Exec
1337 TDirectory *cdir = gDirectory;
1338 TFile f("syswatch.root");
1339 TTree *tree = (TTree*)f.Get("syswatch");
1341 Error("ProfileTask", "No tree named <syswatch> found in file syswatch.root");
1344 if (fDebug > 1) printf("=== Profiling task %s (class %s)\n", name, task->ClassName());
1345 TCanvas *canvas = new TCanvas(Form("profile_%d",itop),Form("Profile of task %s (class %s)",name,task->ClassName()),10,10,800,600);
1346 canvas->Divide(2, 2, 0.01, 0.01);
1350 // VM profile for COO and Terminate methods
1352 cut = Form("task==%d && (stage==0 || stage==2)",itask);
1353 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1354 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1356 hist->SetTitle("Alocated VM[MB] for COO and Terminate");
1357 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1358 hist->GetXaxis()->SetTitle("method");
1360 // CPU profile per event
1362 cut = Form("task==%d && stage==1",itop);
1363 tree->Draw("deltaT:event",cut,"", 1234567890, 0);
1364 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1366 hist->SetTitle("Execution time per event");
1367 hist->GetYaxis()->SetTitle("CPU/event [s]");
1369 // VM profile for Exec
1371 cut = Form("task==%d && stage==1",itop);
1372 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1373 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1375 hist->SetTitle("Alocated VM[MB] per event");
1376 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1381 if (cdir) cdir->cd();
1384 //______________________________________________________________________________
1385 void AliAnalysisManager::AddTask(AliAnalysisTask *task)
1387 // Adds a user task to the global list of tasks.
1389 Error("AddTask", "Cannot add task %s since InitAnalysis was already called", task->GetName());
1393 if (fTasks->FindObject(task)) {
1394 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
1397 task->SetActive(kFALSE);
1401 //______________________________________________________________________________
1402 AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
1404 // Retreive task by name.
1405 if (!fTasks) return NULL;
1406 return (AliAnalysisTask*)fTasks->FindObject(name);
1409 //______________________________________________________________________________
1410 Int_t AliAnalysisManager::GetTaskIndex(const AliAnalysisTask *task) const
1412 // Returns task inded in the manager's list, -1 if not registered.
1413 if (!fTasks) return -1;
1414 return fTasks->IndexOf(task);
1417 //______________________________________________________________________________
1418 AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
1419 TClass *datatype, EAliAnalysisContType type, const char *filename)
1421 // Create a data container of a certain type. Types can be:
1422 // kExchangeContainer = 0, used to exchange data between tasks
1423 // kInputContainer = 1, used to store input data
1424 // kOutputContainer = 2, used for writing result to a file
1425 // filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
1426 // the output object to a folder inside the output file
1427 if (fContainers->FindObject(name)) {
1428 Error("CreateContainer","A container named %s already defined !",name);
1431 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
1432 fContainers->Add(cont);
1434 case kInputContainer:
1437 case kOutputContainer:
1438 fOutputs->Add(cont);
1439 if (filename && strlen(filename)) {
1440 cont->SetFileName(filename);
1441 cont->SetDataOwned(kFALSE); // data owned by the file
1444 case kParamContainer:
1445 fParamCont->Add(cont);
1446 if (filename && strlen(filename)) {
1447 cont->SetFileName(filename);
1448 cont->SetDataOwned(kFALSE); // data owned by the file
1451 case kExchangeContainer:
1452 cont->SetExchange(kTRUE);
1453 fExchangeCont->Add(cont);
1454 cont->SetDataOwned(kFALSE); // data owned by the publisher
1460 //______________________________________________________________________________
1461 Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
1462 AliAnalysisDataContainer *cont)
1464 // Connect input of an existing task to a data container.
1466 Error("ConnectInput", "Task pointer is NULL");
1469 if (!fTasks->FindObject(task)) {
1471 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
1473 Bool_t connected = task->ConnectInput(islot, cont);
1477 //______________________________________________________________________________
1478 Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
1479 AliAnalysisDataContainer *cont)
1481 // Connect output of an existing task to a data container.
1483 Error("ConnectOutput", "Task pointer is NULL");
1486 if (!fTasks->FindObject(task)) {
1488 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
1490 Bool_t connected = task->ConnectOutput(islot, cont);
1494 //______________________________________________________________________________
1495 void AliAnalysisManager::CleanContainers()
1497 // Clean data from all containers that have already finished all client tasks.
1498 TIter next(fContainers);
1499 AliAnalysisDataContainer *cont;
1500 while ((cont=(AliAnalysisDataContainer *)next())) {
1501 if (cont->IsOwnedData() &&
1502 cont->IsDataReady() &&
1503 cont->ClientsExecuted()) cont->DeleteData();
1507 //______________________________________________________________________________
1508 Bool_t AliAnalysisManager::InitAnalysis()
1510 // Initialization of analysis chain of tasks. Should be called after all tasks
1511 // and data containers are properly connected
1512 // Reset flag and remove valid_outputs file if exists
1513 if (fInitOK) return kTRUE;
1514 if (!gSystem->AccessPathName("outputs_valid"))
1515 gSystem->Unlink("outputs_valid");
1516 // Check for top tasks (depending only on input data containers)
1517 if (!fTasks->First()) {
1518 Error("InitAnalysis", "Analysis has no tasks !");
1522 AliAnalysisTask *task;
1523 AliAnalysisDataContainer *cont;
1526 Bool_t iszombie = kFALSE;
1527 Bool_t istop = kTRUE;
1529 while ((task=(AliAnalysisTask*)next())) {
1532 Int_t ninputs = task->GetNinputs();
1533 for (i=0; i<ninputs; i++) {
1534 cont = task->GetInputSlot(i)->GetContainer();
1538 fZombies->Add(task);
1542 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
1543 i, task->GetName());
1545 if (iszombie) continue;
1546 // Check if cont is an input container
1547 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
1548 // Connect to parent task
1552 fTopTasks->Add(task);
1556 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
1559 // Check now if there are orphan tasks
1560 for (i=0; i<ntop; i++) {
1561 task = (AliAnalysisTask*)fTopTasks->At(i);
1566 while ((task=(AliAnalysisTask*)next())) {
1567 if (!task->IsUsed()) {
1569 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
1572 // Check the task hierarchy (no parent task should depend on data provided
1573 // by a daughter task)
1574 for (i=0; i<ntop; i++) {
1575 task = (AliAnalysisTask*)fTopTasks->At(i);
1576 if (task->CheckCircularDeps()) {
1577 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
1582 // Check that all containers feeding post-event loop tasks are in the outputs list
1583 TIter nextcont(fContainers); // loop over all containers
1584 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1585 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1586 if (cont->HasConsumers()) {
1587 // Check if one of the consumers is post event loop
1588 TIter nextconsumer(cont->GetConsumers());
1589 while ((task=(AliAnalysisTask*)nextconsumer())) {
1590 if (task->IsPostEventLoop()) {
1591 fOutputs->Add(cont);
1598 // Check if all special output containers have a file name provided
1599 TIter nextout(fOutputs);
1600 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1601 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1602 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1606 // Initialize requested branch list if needed
1607 if (!fAutoBranchHandling) {
1609 while ((task=(AliAnalysisTask*)next())) {
1610 if (!task->HasBranches()) {
1611 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\"",
1612 task->GetName(), task->ClassName());
1615 if (!fInputEventHandler || !strlen(fInputEventHandler->GetDataType())) {
1616 Error("InitAnalysis", "Manual branch loading requested but no input handler defined or handler does not define data type.");
1619 TString taskbranches;
1620 task->GetBranches(fInputEventHandler->GetDataType(), taskbranches);
1621 if (taskbranches.IsNull()) {
1622 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches of type %s:",
1623 task->GetName(), task->ClassName(), fInputEventHandler->GetDataType());
1626 AddBranches(taskbranches);
1633 //______________________________________________________________________________
1634 void AliAnalysisManager::AddBranches(const char *branches)
1636 // Add branches to the existing fRequestedBranches.
1637 TString br(branches);
1638 TObjArray *arr = br.Tokenize(",");
1641 while ((obj=next())) {
1642 if (!fRequestedBranches.Contains(obj->GetName())) {
1643 if (!fRequestedBranches.IsNull()) fRequestedBranches += ",";
1644 fRequestedBranches += obj->GetName();
1650 //______________________________________________________________________________
1651 void AliAnalysisManager::CheckBranches(Bool_t load)
1653 // The method checks the input branches to be loaded during the analysis.
1654 if (fAutoBranchHandling || fRequestedBranches.IsNull() || !fTree) return;
1655 TObjArray *arr = fRequestedBranches.Tokenize(",");
1658 while ((obj=next())) {
1659 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(obj->GetName()));
1661 br = fTree->GetBranch(obj->GetName());
1663 Error("CheckBranches", "Could not find branch %s",obj->GetName());
1668 if (load && br->GetReadEntry()!=GetCurrentEntry()) {
1669 br->GetEntry(GetCurrentEntry());
1675 //______________________________________________________________________________
1676 Bool_t AliAnalysisManager::CheckTasks() const
1678 // Check consistency of tasks.
1679 Int_t ntasks = fTasks->GetEntries();
1681 Error("CheckTasks", "No tasks connected to the manager. This may be due to forgetting to compile the task or to load their library.");
1684 // Get the pointer to AliAnalysisTaskSE::Class()
1685 TClass *badptr = (TClass*)gROOT->ProcessLine("AliAnalysisTaskSE::Class()");
1686 // Loop all tasks to check if their corresponding library was loaded
1689 while ((obj=next())) {
1690 if (obj->IsA() == badptr) {
1691 Error("CheckTasks", "##################\n \
1692 Class for task %s NOT loaded. You probably forgot to load the library for this task (or compile it dynamically).\n###########################\n",obj->GetName());
1699 //______________________________________________________________________________
1700 void AliAnalysisManager::PrintStatus(Option_t *option) const
1702 // Print task hierarchy.
1704 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1707 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1709 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
1710 AliAnalysisDataContainer *cont = fCommonInput;
1711 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
1712 printf("=== TOP CONTAINER:\n");
1713 cont->PrintContainer(option,0);
1714 // Reset "touched" flag
1715 TIter next(fContainers);
1716 while ((cont = (AliAnalysisDataContainer*)next())) cont->SetTouched(kFALSE);
1717 TIter nextt(fTasks);
1718 AliAnalysisTask *task;
1719 while ((task=(AliAnalysisTask*)nextt()))
1720 task->SetActive(kFALSE);
1722 if (!fAutoBranchHandling && !fRequestedBranches.IsNull())
1723 printf("Requested input branches:\n%s\n", fRequestedBranches.Data());
1725 TString sopt(option);
1728 if (sopt.Contains("ALL"))
1730 if ( fOutputEventHandler )
1732 cout << TString('_',78) << endl;
1733 cout << "OutputEventHandler:" << endl;
1734 fOutputEventHandler->Print(" ");
1739 //______________________________________________________________________________
1740 void AliAnalysisManager::ResetAnalysis()
1742 // Reset all execution flags and clean containers.
1743 TIter nextTask(fTasks);
1744 AliAnalysisTask *task;
1745 while ((task=(AliAnalysisTask*)nextTask())) {
1749 // CleanContainers();
1752 //______________________________________________________________________________
1753 void AliAnalysisManager::RunLocalInit()
1755 // Run LocalInit method for all tasks.
1756 TDirectory *cdir = gDirectory;
1757 if (IsTrainInitialized()) return;
1758 TIter nextTask(fTasks);
1759 AliAnalysisTask *task;
1760 while ((task=(AliAnalysisTask*)nextTask())) {
1764 if (cdir) cdir->cd();
1765 TObject::SetBit(kTasksInitialized, kTRUE);
1768 //______________________________________________________________________________
1769 void AliAnalysisManager::InputFileFromTree(TTree * const tree, TString &fname)
1771 // Retrieves name of the file from tree
1774 TFile *file = tree->GetCurrentFile();
1777 TChain *chain = dynamic_cast<TChain*>(tree);
1778 if (!chain || !chain->GetNtrees()) return;
1779 basename = gSystem->BaseName(chain->GetListOfFiles()->First()->GetTitle());
1781 basename = gSystem->BaseName(file->GetName());
1783 Int_t index = basename.Index("#");
1784 fname = basename(index+1, basename.Length());
1787 //______________________________________________________________________________
1788 Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
1790 // Start analysis having a grid handler.
1791 if (!fGridHandler) {
1792 Error("StartAnalysis", "Cannot start analysis providing just the analysis type without a grid handler.");
1793 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1797 return StartAnalysis(type, tree, nentries, firstentry);
1800 //______________________________________________________________________________
1801 Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
1803 // Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1804 // MIX. Process nentries starting from firstentry
1806 // Backup current directory and make sure gDirectory points to gROOT
1807 TDirectory *cdir = gDirectory;
1810 Error("StartAnalysis","Analysis manager was not initialized !");
1811 if (cdir) cdir->cd();
1814 if (!CheckTasks()) Fatal("StartAnalysis", "Not all needed libraries were loaded");
1816 printf("StartAnalysis %s\n",GetName());
1817 AliLog::SetGlobalLogLevel(AliLog::kInfo);
1819 fMaxEntries = nentries;
1821 TString anaType = type;
1823 fMode = kLocalAnalysis;
1824 if (anaType.Contains("file")) fIsRemote = kTRUE;
1825 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1826 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1827 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1828 if (fInputEventHandler) {
1830 InputFileFromTree(tree, fname);
1831 if (fname.Length()) fInputEventHandler->SetInputFileName(fname);
1834 if (fMode == kGridAnalysis) {
1836 if (!anaType.Contains("terminate")) {
1837 if (!fGridHandler) {
1838 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1839 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1840 if (cdir) cdir->cd();
1843 // Write analysis manager in the analysis file
1844 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1845 // run local task configuration
1847 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1848 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1849 if (cdir) cdir->cd();
1853 // Terminate grid analysis
1854 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1855 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1856 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1857 if (!fGridHandler->MergeOutputs()) {
1858 // Return if outputs could not be merged or if it alien handler
1859 // was configured for offline mode or local testing.
1860 if (cdir) cdir->cd();
1864 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1865 if (cdir) cdir->cd();
1866 ImportWrappers(NULL);
1868 if (cdir) cdir->cd();
1872 SetEventLoop(kFALSE);
1873 // Enable event loop mode if a tree was provided
1874 if (tree || fGridHandler || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
1877 TString ttype = "TTree";
1878 if (tree && tree->IsA() == TChain::Class()) {
1879 chain = (TChain*)tree;
1880 if (!chain || !chain->GetListOfFiles()->First()) {
1881 Error("StartAnalysis", "Cannot process null or empty chain...");
1882 if (cdir) cdir->cd();
1888 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1889 if (getsysInfo) AliSysInfo::AddStamp("Start", 0);
1890 // Initialize locally all tasks (happens for all modes)
1892 AliAnalysisTask *task;
1896 case kLocalAnalysis:
1897 if (!tree && !fGridHandler) {
1898 TIter nextT(fTasks);
1899 // Call CreateOutputObjects for all tasks
1901 Bool_t dirStatus = TH1::AddDirectoryStatus();
1902 while ((task=(AliAnalysisTask*)nextT())) {
1903 TH1::AddDirectory(kFALSE);
1904 task->CreateOutputObjects();
1905 if (!task->CheckPostData()) {
1906 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
1907 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
1908 ########### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ###########", task->GetName(), task->ClassName());
1910 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
1914 TH1::AddDirectory(dirStatus);
1915 if (IsExternalLoop()) {
1916 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1917 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1924 fSelector = new AliAnalysisSelector(this);
1925 // Check if a plugin handler is used
1927 // Get the chain from the plugin
1928 TString dataType = "esdTree";
1929 if (fInputEventHandler) {
1930 dataType = fInputEventHandler->GetDataType();
1934 chain = fGridHandler->GetChainForTestMode(dataType);
1936 Error("StartAnalysis", "No chain for test mode. Aborting.");
1939 cout << "===== RUNNING LOCAL ANALYSIS" << GetName() << " ON CHAIN " << chain->GetName() << endl;
1940 retv = chain->Process(fSelector, "", nentries, firstentry);
1943 // Run tree-based analysis via AliAnalysisSelector
1944 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
1945 retv = tree->Process(fSelector, "", nentries, firstentry);
1947 case kProofAnalysis:
1949 // Check if the plugin is used
1951 return StartAnalysis(type, fGridHandler->GetProofDataSet(), nentries, firstentry);
1953 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1954 Error("StartAnalysis", "No PROOF!!! Exiting.");
1955 if (cdir) cdir->cd();
1958 line = Form("gProof->AddInput((TObject*)%p);", this);
1959 gROOT->ProcessLine(line);
1962 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
1963 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
1965 Error("StartAnalysis", "No chain!!! Exiting.");
1966 if (cdir) cdir->cd();
1972 if (!anaType.Contains("terminate")) {
1973 if (!fGridHandler) {
1974 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1975 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1976 if (cdir) cdir->cd();
1979 // Write analysis manager in the analysis file
1980 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1981 // Start the analysis via the handler
1982 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1983 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1984 if (cdir) cdir->cd();
1988 // Terminate grid analysis
1989 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1990 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1991 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1992 if (!fGridHandler->MergeOutputs()) {
1993 // Return if outputs could not be merged or if it alien handler
1994 // was configured for offline mode or local testing.
1995 if (cdir) cdir->cd();
1999 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
2000 ImportWrappers(NULL);
2002 if (cdir) cdir->cd();
2004 case kMixingAnalysis:
2005 // Run event mixing analysis
2007 Error("StartAnalysis", "Cannot run event mixing without event pool");
2008 if (cdir) cdir->cd();
2011 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
2012 fSelector = new AliAnalysisSelector(this);
2013 while ((chain=fEventPool->GetNextChain())) {
2015 // Call NotifyBinChange for all tasks
2016 while ((task=(AliAnalysisTask*)next()))
2017 if (!task->IsPostEventLoop()) task->NotifyBinChange();
2018 retv = chain->Process(fSelector);
2020 Error("StartAnalysis", "Mixing analysis failed");
2021 if (cdir) cdir->cd();
2025 PackOutput(fSelector->GetOutputList());
2028 if (cdir) cdir->cd();
2032 //______________________________________________________________________________
2033 Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
2035 // Start analysis for this manager on a given dataset. Analysis task can be:
2036 // LOCAL, PROOF or GRID. Process nentries starting from firstentry.
2038 Error("StartAnalysis","Analysis manager was not initialized !");
2042 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
2043 TString anaType = type;
2045 if (!anaType.Contains("proof")) {
2046 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
2049 fMode = kProofAnalysis;
2051 TString proofProcessOpt;
2052 SetEventLoop(kTRUE);
2053 // Set the dataset flag
2054 TObject::SetBit(kUseDataSet);
2057 // Start proof analysis using the grid handler
2058 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
2059 Error("StartAnalysis", "The grid plugin could not start PROOF analysis");
2062 // Check if the plugin is in test mode
2063 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kTest) {
2064 dataset = "test_collection";
2066 dataset = fGridHandler->GetProofDataSet();
2069 proofProcessOpt = fGridHandler->GetProofProcessOpt();
2072 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
2073 Error("StartAnalysis", "No PROOF!!! Exiting.");
2077 // Initialize locally all tasks
2080 line = Form("gProof->AddInput((TObject*)%p);", this);
2081 gROOT->ProcessLine(line);
2083 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"%s\", %lld, %lld);",
2084 dataset,proofProcessOpt.Data(), nentries, firstentry);
2085 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
2086 retv = (Long_t)gROOT->ProcessLine(line);
2090 //______________________________________________________________________________
2091 TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
2093 // Opens according the option the file specified by cont->GetFileName() and changes
2094 // current directory to cont->GetFolderName(). If the file was already opened, it
2095 // checks if the option UPDATE was preserved. File open via TProofOutputFile can
2096 // be optionally ignored.
2097 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2098 TString filename = cont->GetFileName();
2100 if (filename.IsNull()) {
2101 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
2104 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
2106 f = mgr->OpenProofFile(cont,option);
2108 // Check first if the file is already opened
2109 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2111 // Check if option "UPDATE" was preserved
2112 TString opt(option);
2114 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2115 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2117 f = TFile::Open(filename, option);
2120 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2124 // Check for a folder request
2125 TString dir = cont->GetFolderName();
2126 if (!dir.IsNull()) {
2127 if (!f->GetDirectory(dir)) f->mkdir(dir);
2132 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
2133 cont->SetFile(NULL);
2137 //______________________________________________________________________________
2138 TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option, const char *extaod)
2140 // Opens a special output file used in PROOF.
2142 TString filename = cont->GetFileName();
2143 if (cont == fCommonOutput) {
2144 if (fOutputEventHandler) {
2145 if (strlen(extaod)) filename = extaod;
2146 filename = fOutputEventHandler->GetOutputFileName();
2148 else Fatal("OpenProofFile","No output container. Exiting.");
2151 if (fMode!=kProofAnalysis || !fSelector) {
2152 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
2155 if (fSpecialOutputLocation.Length()) {
2156 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2158 // Check if option "UPDATE" was preserved
2159 TString opt(option);
2161 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2162 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2164 f = new TFile(filename, option);
2166 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2170 // Check for a folder request
2171 TString dir = cont->GetFolderName();
2173 if (!f->GetDirectory(dir)) f->mkdir(dir);
2178 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2179 cont->SetFile(NULL);
2182 // Check if there is already a proof output file in the output list
2183 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
2185 // Get the actual file
2186 line = Form("((TProofOutputFile*)%p)->GetFileName();", pof);
2187 filename = (const char*)gROOT->ProcessLine(line);
2189 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
2191 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2193 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
2196 // Check if option "UPDATE" was preserved
2197 TString opt(option);
2199 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2200 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
2202 if (cont->IsRegisterDataset()) {
2203 TString dsetName = filename;
2204 dsetName.ReplaceAll(".root", cont->GetTitle());
2205 dsetName.ReplaceAll(":","_");
2206 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
2207 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
2209 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
2210 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
2212 if (fDebug > 1) printf("=== %s\n", line.Data());
2213 gROOT->ProcessLine(line);
2214 line = Form("pf->OpenFile(\"%s\");", option);
2215 gROOT->ProcessLine(line);
2218 gROOT->ProcessLine("pf->Print()");
2219 printf(" == proof file name: %s", f->GetName());
2221 // Add to proof output list
2222 line = Form("((TList*)%p)->Add(pf);",fSelector->GetOutputList());
2223 if (fDebug > 1) printf("=== %s\n", line.Data());
2224 gROOT->ProcessLine(line);
2226 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2230 // Check for a folder request
2231 TString dir = cont->GetFolderName();
2232 if (!dir.IsNull()) {
2233 if (!f->GetDirectory(dir)) f->mkdir(dir);
2238 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2239 cont->SetFile(NULL);
2243 //______________________________________________________________________________
2244 void AliAnalysisManager::ExecAnalysis(Option_t *option)
2246 // Execute analysis.
2247 static Long64_t nentries = 0;
2248 static TTree *lastTree = 0;
2249 static TStopwatch *timer = new TStopwatch();
2250 // Only the first call to Process will trigger a true Notify. Other Notify
2251 // coming before is ignored.
2252 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) {
2253 TObject::SetBit(AliAnalysisManager::kTrueNotify);
2256 if (fDebug > 0) printf("MGR: Processing event #%d\n", fNcalls);
2258 if (fTree && (fTree != lastTree)) {
2259 nentries += fTree->GetEntries();
2262 if (!fNcalls) timer->Start();
2263 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", fNcalls, TMath::Min(fMaxEntries,nentries), timer, kFALSE);
2265 fIOTimer->Start(kTRUE);
2267 TDirectory *cdir = gDirectory;
2268 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
2269 if (getsysInfo && ((fNcalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)fNcalls);
2271 Error("ExecAnalysis", "Analysis manager was not initialized !");
2272 if (cdir) cdir->cd();
2276 AliAnalysisTask *task;
2277 // Reset the analysis
2279 // Check if the top tree is active.
2281 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2282 AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
2284 // De-activate all tasks (not needed anymore after ResetAnalysis
2285 // while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
2286 AliAnalysisDataContainer *cont = fCommonInput;
2287 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
2289 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
2290 if (cdir) cdir->cd();
2293 cont->SetData(fTree); // This set activity for all tasks reading only from the top container
2294 Long64_t entry = fTree->GetTree()->GetReadEntry();
2296 // Call BeginEvent() for optional input/output and MC services
2297 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
2298 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
2299 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
2301 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2302 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2304 // Execute the tasks
2305 // TIter next1(cont->GetConsumers());
2307 fIOTime += fIOTimer->RealTime();
2308 fCPUTimer->Start(kTRUE);
2309 TIter next1(fTopTasks);
2311 while ((task=(AliAnalysisTask*)next1())) {
2312 task->SetActive(kTRUE);
2314 cout << " Executing task " << task->GetName() << endl;
2316 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
2317 task->ExecuteTask(option);
2318 if (fStatistics) fStatistics->StopTimer();
2320 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2321 AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
2325 fCPUTime += fCPUTimer->RealTime();
2326 fIOTimer->Start(kTRUE);
2328 // Call FinishEvent() for optional output and MC services
2329 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2330 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2331 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2332 // Gather system information if requested
2333 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2334 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1001, 1);
2335 if (cdir) cdir->cd();
2337 fIOTime += fIOTimer->RealTime();
2340 // The event loop is not controlled by TSelector
2342 // Call BeginEvent() for optional input/output and MC services
2343 fIOTimer->Start(kTRUE);
2344 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
2345 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
2346 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
2348 fIOTime += fIOTimer->RealTime();
2350 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2351 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2352 fCPUTimer->Start(kTRUE);
2353 TIter next2(fTopTasks);
2354 while ((task=(AliAnalysisTask*)next2())) {
2355 task->SetActive(kTRUE);
2357 cout << " Executing task " << task->GetName() << endl;
2359 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
2360 task->ExecuteTask(option);
2361 if (fStatistics) fStatistics->StopTimer();
2365 fCPUTime += fCPUTimer->RealTime();
2367 // Call FinishEvent() for optional output and MC services
2368 fIOTimer->Start(kTRUE);
2369 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2370 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2371 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2372 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2373 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
2374 if (cdir) cdir->cd();
2376 fIOTime += fIOTimer->RealTime();
2379 //______________________________________________________________________________
2380 Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
2382 // Check if the stdout is connected to a pipe (C.Holm)
2383 Bool_t ispipe = kFALSE;
2384 out.seekp(0, std::ios_base::cur);
2387 if (errno == ESPIPE) ispipe = kTRUE;
2392 //______________________________________________________________________________
2393 void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
2395 // Set the input event handler and create a container for it.
2397 fInputEventHandler = handler;
2398 if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
2401 //______________________________________________________________________________
2402 void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
2404 // Set the input event handler and create a container for it.
2406 fOutputEventHandler = handler;
2407 if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
2408 fCommonOutput->SetSpecialOutput();
2411 //______________________________________________________________________________
2412 void AliAnalysisManager::SetDebugLevel(UInt_t level)
2414 // Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
2415 if (TObject::TestBit(kUseProgressBar)) {
2416 Info("SetDebugLevel","Ignored. Disable the progress bar first.");
2422 //______________________________________________________________________________
2423 void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
2425 // Enable a text mode progress bar. Resets debug level to 0.
2426 Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
2427 TObject::SetBit(kUseProgressBar,flag);
2428 fPBUpdateFreq = freq;
2432 //______________________________________________________________________________
2433 void AliAnalysisManager::RegisterExtraFile(const char *fname)
2435 // This method is used externally to register output files which are not
2436 // connected to any output container, so that the manager can properly register,
2437 // retrieve or merge them when running in distributed mode. The file names are
2438 // separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
2439 if (fExtraFiles.Contains(fname)) return;
2440 if (fExtraFiles.Length()) fExtraFiles += " ";
2441 fExtraFiles += fname;
2444 //______________________________________________________________________________
2445 Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
2447 // Copy a file from the location specified ina the wrapper with the same name from the source list.
2451 TObject *pof = source->FindObject(filename);
2452 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
2453 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
2456 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
2457 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
2458 TString clientUrl(chUrl);
2459 TString fullPath_str(fullPath);
2460 if (clientUrl.Contains("localhost")){
2461 TObjArray* array = fullPath_str.Tokenize ( "//" );
2462 TObjString *strobj = ( TObjString *)array->At(1);
2463 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
2464 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
2465 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
2466 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
2467 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
2471 else if (clientUrl.Contains("__lite__")) {
2472 // Special case for ProofLite environement - get file info and copy.
2473 gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
2474 fullPath_str = Form("%s/%s", tmp, fullPath);
2477 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
2478 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
2480 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
2484 //______________________________________________________________________________
2485 void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
2487 // Fill analysis type in the provided string.
2489 case kLocalAnalysis:
2492 case kProofAnalysis:
2498 case kMixingAnalysis:
2503 //______________________________________________________________________________
2504 Bool_t AliAnalysisManager::ValidateOutputFiles() const
2506 // Validate all output files.
2507 TIter next(fOutputs);
2508 AliAnalysisDataContainer *output;
2509 TDirectory *cdir = gDirectory;
2510 TString openedFiles;
2511 while ((output=(AliAnalysisDataContainer*)next())) {
2512 if (output->IsRegisterDataset()) continue;
2513 TString filename = output->GetFileName();
2514 if (filename == "default") {
2515 if (!fOutputEventHandler) continue;
2516 filename = fOutputEventHandler->GetOutputFileName();
2517 // Main AOD may not be there
2518 if (gSystem->AccessPathName(filename)) continue;
2520 // Check if the file is closed
2521 if (openedFiles.Contains(filename)) continue;;
2522 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2524 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
2525 // Clear file list to release object ownership to user.
2529 file = TFile::Open(filename);
2530 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
2531 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
2532 if (cdir) cdir->cd();
2536 openedFiles += filename;
2539 if (cdir) cdir->cd();
2543 //______________________________________________________________________________
2544 void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
2546 // Implements a nice text mode progress bar.
2547 static Long64_t icount = 0;
2548 static TString oname;
2549 static TString nname;
2550 static Long64_t ocurrent = 0;
2551 static Long64_t osize = 0;
2552 static Int_t oseconds = 0;
2553 static TStopwatch *owatch = 0;
2554 static Bool_t oneoftwo = kFALSE;
2555 static Int_t nrefresh = 0;
2556 static Int_t nchecks = 0;
2557 static char lastChar = 0;
2558 const char symbol[4] = {'-','\\','|','/'};
2560 if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
2566 ocurrent = TMath::Abs(current);
2567 osize = TMath::Abs(size);
2568 if (ocurrent > osize) ocurrent=osize;
2573 if ((current % fPBUpdateFreq) != 0) return;
2575 char progress[11] = " ";
2576 Int_t ichar = icount%4;
2581 if (owatch && !last) {
2583 time = owatch->RealTime();
2584 seconds = int(time) % 60;
2585 minutes = (int(time) / 60) % 60;
2586 hours = (int(time) / 60 / 60);
2588 if (oseconds==seconds) {
2592 oneoftwo = !oneoftwo;
2596 if (refresh && oneoftwo) {
2598 if (nchecks <= 0) nchecks = nrefresh+1;
2599 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
2600 oname = Form(" == %d%% ==", pctdone);
2602 Double_t percent = 100.0*ocurrent/osize;
2603 Int_t nchar = Int_t(percent/10);
2604 if (nchar>10) nchar=10;
2606 for (i=0; i<nchar; i++) progress[i] = '=';
2607 progress[nchar] = symbol[ichar];
2608 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2609 progress[10] = '\0';
2612 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2613 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2614 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
2616 Int_t full = Int_t(ocurrent > 0 ?
2617 time * (float(osize)/ocurrent) + .5 :
2619 Int_t remain = Int_t(full - time);
2620 Int_t rsec = remain % 60;
2621 Int_t rmin = (remain / 60) % 60;
2622 Int_t rhour = (remain / 60 / 60);
2623 fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
2624 percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
2626 else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
2627 if (refresh && oneoftwo) oname = nname;
2628 if (owatch) owatch->Continue();
2637 fprintf(stderr, "\n");
2641 //______________________________________________________________________________
2642 void AliAnalysisManager::DoLoadBranch(const char *name)
2644 // Get tree and load branch if needed.
2645 static Long64_t crtEntry = -100;
2647 if (fAutoBranchHandling || !fTree)
2650 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2652 br = fTree->GetBranch(name);
2654 Error("DoLoadBranch", "Could not find branch %s",name);
2659 if (br->GetReadEntry()==fCurrentEntry) return;
2660 Long64_t readbytes = br->GetEntry(GetCurrentEntry());
2662 Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
2663 if (crtEntry != fCurrentEntry) {
2664 CountEvent(1,0,1,0);
2665 crtEntry = fCurrentEntry;
2668 if (crtEntry != fCurrentEntry) {
2669 CountEvent(1,1,0,0);
2670 crtEntry = fCurrentEntry;
2675 //______________________________________________________________________________
2676 void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
2678 // Add the statistics task to the manager.
2680 Info("AddStatisticsTask", "Already added");
2683 TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
2684 gROOT->ProcessLine(line);
2687 //______________________________________________________________________________
2688 void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
2690 // Bookkeep current event;
2691 if (!fStatistics) return;
2692 fStatistics->AddInput(ninput);
2693 fStatistics->AddProcessed(nprocessed);
2694 fStatistics->AddFailed(nfailed);
2695 fStatistics->AddAccepted(naccepted);
2698 //______________________________________________________________________________
2699 void AliAnalysisManager::AddStatisticsMsg(const char *line)
2701 // Add a line in the statistics message. If available, the statistics message is written
2702 // at the end of the SlaveTerminate phase on workers AND at the end of Terminate
2704 if (!strlen(line)) return;
2705 if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
2706 fStatisticsMsg += line;
2709 //______________________________________________________________________________
2710 void AliAnalysisManager::WriteStatisticsMsg(Int_t)
2712 // If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
2713 static Bool_t done = kFALSE;
2716 if (!fStatistics) return;
2718 AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
2719 AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
2720 AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
2721 AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
2722 out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
2723 fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
2724 fStatistics->GetNaccepted()), ios::out);
2725 out << fStatisticsMsg << endl;
2729 //______________________________________________________________________________
2730 const char* AliAnalysisManager::GetOADBPath()
2732 // returns the path of the OADB
2733 // this static function just depends on environment variables
2735 static TString oadbPath;
2737 if (gSystem->Getenv("OADB_PATH"))
2738 oadbPath = gSystem->Getenv("OADB_PATH");
2739 else if (gSystem->Getenv("ALICE_ROOT"))
2740 oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
2742 ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
2747 //______________________________________________________________________________
2748 void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
2750 // Define a custom string variable mapped to a global unique name. The variable
2751 // can be then retrieved by a given analysis macro via GetGlobalStr(key).
2752 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2754 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2757 Bool_t valid = kFALSE;
2758 TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
2760 ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
2763 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
2766 //______________________________________________________________________________
2767 const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
2769 // Static method to retrieve a global variable defined via SetGlobalStr.
2771 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2773 TObject *value = mgr->GetGlobals()->GetValue(key);
2774 if (!value) return 0;
2776 return value->GetName();
2779 //______________________________________________________________________________
2780 void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
2782 // Define a custom integer variable mapped to a global unique name. The variable
2783 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2784 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2786 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2789 Bool_t valid = kFALSE;
2790 Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
2792 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
2795 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
2798 //______________________________________________________________________________
2799 Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
2801 // Static method to retrieve a global variable defined via SetGlobalInt.
2803 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2805 TObject *value = mgr->GetGlobals()->GetValue(key);
2806 if (!value) return 0;
2808 TString s = value->GetName();
2812 //______________________________________________________________________________
2813 void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
2815 // Define a custom double precision variable mapped to a global unique name. The variable
2816 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2817 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2819 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2822 Bool_t valid = kFALSE;
2823 Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
2825 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
2828 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));
2831 //______________________________________________________________________________
2832 Double_t AliAnalysisManager::GetGlobalDbl(const char *key, Bool_t &valid)
2834 // Static method to retrieve a global variable defined via SetGlobalDbl.
2836 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2838 TObject *value = mgr->GetGlobals()->GetValue(key);
2839 if (!value) return 0;
2841 TString s = value->GetName();
2845 //______________________________________________________________________________
2846 void AliAnalysisManager::AddClassDebug(const char *className, Int_t debugLevel)
2848 // Sets Class debug level
2850 if (!fDebugOptions) {
2851 fDebugOptions = new TObjArray();
2852 fDebugOptions->SetOwner(kTRUE);
2855 TNamed *debugOpt = (TNamed*)fDebugOptions->FindObject(className);
2857 AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel,className).Data());
2858 fDebugOptions->Add(new TNamed(className,TString::Format("%d",debugLevel).Data()));
2860 TString oldDebugStr = debugOpt->GetTitle();
2861 Int_t oldDebug = oldDebugStr.Atoi();
2862 if (debugLevel > oldDebug) {
2863 AliWarning(TString::Format("Overwriting debug level to %d class %s, because it is higher then previously set (%d).",debugLevel,className,oldDebug).Data());
2864 debugOpt->SetTitle(TString::Format("%d",debugLevel).Data());
2866 AliWarning(TString::Format("Ignoring debug level to %d class %s, because it is smaller then previously set (%d).",debugLevel,className,oldDebug).Data());
2871 //______________________________________________________________________________
2872 void AliAnalysisManager::ApplyDebugOptions()
2874 // Apply debug options
2876 if (!fDebugOptions) return;
2878 TIter next(fDebugOptions);
2881 while ((debug=dynamic_cast<TNamed*>(next()))) {
2882 debugLevel = debug->GetTitle();
2883 AliInfo(TString::Format("Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()).Data());
2884 AliLog::SetClassDebugLevel(debug->GetName(), debugLevel.Atoi());
2888 //______________________________________________________________________________
2889 Bool_t AliAnalysisManager::IsMacroLoaded(const char * filename)
2891 // Check if a macro was loaded.
2892 return fgMacroNames.Contains(filename);
2895 //______________________________________________________________________________
2896 Int_t AliAnalysisManager::LoadMacro(const char *filename, Int_t *error, Bool_t check)
2898 // Redirection of gROOT->LoadMacro which makes sure the same macro is not loaded
2900 TString macroName = gSystem->BaseName(filename);
2901 // Strip appended +, ++, +g, +O
2902 Int_t index = macroName.Index("+");
2903 if (index>0) macroName.Remove(index);
2904 if (fgMacroNames.Contains(macroName)) {
2905 // Macro with the same name loaded already in this root session, do
2910 Int_t ret = gROOT->LoadMacro(filename,error,check);
2911 // In case of error return the error code
2912 if (ret) return ret;
2913 // Append the macro name to the loaded macros list
2914 fgMacroNames += macroName;
2915 fgMacroNames += " ";
2919 //______________________________________________________________________________
2920 void AliAnalysisManager::Lock()
2922 // Security lock. This is to detect NORMAL user errors and not really to
2923 // protect against intentional hacks.
2924 if (fLocked) return;
2926 if (fInputEventHandler) fInputEventHandler->Lock();
2927 if (fOutputEventHandler) fOutputEventHandler->Lock();
2928 if (fMCtruthEventHandler) fMCtruthEventHandler->Lock();
2929 Info("Lock","====== ANALYSIS MANAGER LOCKED ======");
2932 //______________________________________________________________________________
2933 void AliAnalysisManager::UnLock()
2935 // Verbose unlocking. Hackers will be punished ;-) ...
2936 if (!fLocked) return;
2938 if (fInputEventHandler) fInputEventHandler->UnLock();
2939 if (fOutputEventHandler) fOutputEventHandler->UnLock();
2940 if (fMCtruthEventHandler) fMCtruthEventHandler->UnLock();
2941 Info("UnLock", "====== ANALYSIS MANAGER UNLOCKED ======");
2944 //______________________________________________________________________________
2945 void AliAnalysisManager::Changed()
2947 // All critical setters pass through the Changed method that throws an exception
2948 // in case the lock was set.
2949 if (fLocked) Fatal("Changed","Critical setter called in locked mode");
2952 //______________________________________________________________________________
2953 void AliAnalysisManager::InitInpuData(AliVEvent* esdEvent)
2956 // Method to propagte to all the connected tasks the HLT event.
2957 // This method expects that the input hanlder is of type HLT, should
2958 // not be used otherwise
2960 if (fInputEventHandler) {
2961 TString classInputHandler = fInputEventHandler->ClassName();
2962 if (classInputHandler.Contains("HLT")){
2963 TObjArray* arrTasks = GetTasks();
2964 fInputEventHandler->InitTaskInputData(esdEvent, arrTasks);
2967 Fatal("PropagateHLTEvent", "Input Handler not of type HLT, we cannot use this method!");
2971 Fatal("PropagateHLTEvent", "Input Handler not found, we cannot use this method!");