1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 // Author: Andrei Gheata, 31/05/2006
19 //==============================================================================
20 // AliAnalysisManager - Manager analysis class. Allows creation of several
21 // analysis tasks and data containers storing their input/output. Allows
22 // connecting/chaining tasks via shared data containers. Serializes the current
23 // event for all tasks depending only on initial input data.
24 //==============================================================================
26 //==============================================================================
28 #include "AliAnalysisManager.h"
31 #include <Riostream.h>
36 #include <TTreeCache.h>
40 #include <TMethodCall.h>
45 #include <TStopwatch.h>
48 #include "AliAnalysisSelector.h"
49 #include "AliAnalysisGrid.h"
50 #include "AliAnalysisTask.h"
51 #include "AliAnalysisDataContainer.h"
52 #include "AliAnalysisDataSlot.h"
53 #include "AliVEventHandler.h"
54 #include "AliVEventPool.h"
55 #include "AliSysInfo.h"
56 #include "AliAnalysisStatistics.h"
62 ClassImp(AliAnalysisManager)
64 AliAnalysisManager *AliAnalysisManager::fgAnalysisManager = NULL;
65 TString AliAnalysisManager::fgCommonFileName = "";
66 TString AliAnalysisManager::fgMacroNames = "";
67 Int_t AliAnalysisManager::fPBUpdateFreq = 1;
69 //______________________________________________________________________________
70 AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
73 fInputEventHandler(0),
74 fOutputEventHandler(0),
75 fMCtruthEventHandler(0),
79 fMode(kLocalAnalysis),
86 fSpecialOutputLocation(""),
96 fFileDescriptors(new TObjArray()),
97 fCurrentDescriptor(0),
104 fAutoBranchHandling(kTRUE),
105 fAsyncReading(kFALSE), // default prefetching on
110 fCacheSize(100000000), // default 100 MB
112 fRequestedBranches(),
122 // Default constructor.
123 fgAnalysisManager = this;
124 fgCommonFileName = "AnalysisResults.root";
125 if (TClass::IsCallingNew() != TClass::kDummyNew) {
126 fTasks = new TObjArray();
127 fTopTasks = new TObjArray();
128 fZombies = new TObjArray();
129 fContainers = new TObjArray();
130 fInputs = new TObjArray();
131 fOutputs = new TObjArray();
132 fParamCont = new TObjArray();
133 fExchangeCont = new TObjArray();
134 fGlobals = new TMap();
136 fIOTimer = new TStopwatch();
137 fCPUTimer = new TStopwatch();
138 fInitTimer = new TStopwatch();
142 //______________________________________________________________________________
143 AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
146 fInputEventHandler(NULL),
147 fOutputEventHandler(NULL),
148 fMCtruthEventHandler(NULL),
153 fInitOK(other.fInitOK),
154 fMustClean(other.fMustClean),
155 fIsRemote(other.fIsRemote),
156 fLocked(other.fLocked),
157 fMCLoop(other.fMCLoop),
158 fDebug(other.fDebug),
159 fSpecialOutputLocation(""),
169 fFileDescriptors(new TObjArray()),
170 fCurrentDescriptor(0),
175 fExtraFiles(other.fExtraFiles),
176 fFileInfoLog(other.fFileInfoLog),
177 fAutoBranchHandling(other.fAutoBranchHandling),
178 fAsyncReading(other.fAsyncReading),
181 fNcalls(other.fNcalls),
182 fMaxEntries(other.fMaxEntries),
183 fCacheSize(other.fCacheSize),
184 fStatisticsMsg(other.fStatisticsMsg),
185 fRequestedBranches(other.fRequestedBranches),
186 fStatistics(other.fStatistics),
187 fGlobals(other.fGlobals),
188 fIOTimer(new TStopwatch()),
189 fCPUTimer(new TStopwatch()),
190 fInitTimer(new TStopwatch()),
196 fTasks = new TObjArray(*other.fTasks);
197 fTopTasks = new TObjArray(*other.fTopTasks);
198 fZombies = new TObjArray(*other.fZombies);
199 fContainers = new TObjArray(*other.fContainers);
200 fInputs = new TObjArray(*other.fInputs);
201 fOutputs = new TObjArray(*other.fOutputs);
202 fParamCont = new TObjArray(*other.fParamCont);
203 fExchangeCont = new TObjArray(*other.fExchangeCont);
204 fgCommonFileName = "AnalysisResults.root";
205 fgAnalysisManager = this;
208 //______________________________________________________________________________
209 AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& other)
212 if (&other != this) {
213 TNamed::operator=(other);
214 fInputEventHandler = other.fInputEventHandler;
215 fOutputEventHandler = other.fOutputEventHandler;
216 fMCtruthEventHandler = other.fMCtruthEventHandler;
217 fEventPool = other.fEventPool;
220 fNSysInfo = other.fNSysInfo;
222 fInitOK = other.fInitOK;
223 fIsRemote = other.fIsRemote;
224 fLocked = other.fLocked;
225 fMCLoop = other.fMCLoop;
226 fDebug = other.fDebug;
227 fTasks = new TObjArray(*other.fTasks);
228 fTopTasks = new TObjArray(*other.fTopTasks);
229 fZombies = new TObjArray(*other.fZombies);
230 fContainers = new TObjArray(*other.fContainers);
231 fInputs = new TObjArray(*other.fInputs);
232 fOutputs = new TObjArray(*other.fOutputs);
233 fParamCont = new TObjArray(*other.fParamCont);
234 fExchangeCont = new TObjArray(*other.fExchangeCont);
235 fDebugOptions = NULL;
236 fFileDescriptors = new TObjArray();
237 fCurrentDescriptor = 0;
239 fCommonOutput = NULL;
242 fExtraFiles = other.fExtraFiles;
243 fFileInfoLog = other.fFileInfoLog;
244 fgCommonFileName = "AnalysisResults.root";
245 fgAnalysisManager = this;
246 fAutoBranchHandling = other.fAutoBranchHandling;
247 fAsyncReading = other.fAsyncReading;
248 fTable.Clear("nodelete");
249 fRunFromPath = other.fRunFromPath;
250 fNcalls = other. fNcalls;
251 fMaxEntries = other.fMaxEntries;
252 fCacheSize = other.fCacheSize;
253 fStatisticsMsg = other.fStatisticsMsg;
254 fRequestedBranches = other.fRequestedBranches;
255 fStatistics = other.fStatistics;
256 fGlobals = new TMap();
257 fIOTimer = new TStopwatch();
258 fCPUTimer = new TStopwatch();
259 fInitTimer = new TStopwatch();
267 //______________________________________________________________________________
268 AliAnalysisManager::~AliAnalysisManager()
271 if (fTasks) {fTasks->Delete(); delete fTasks;}
274 if (fContainers) {fContainers->Delete(); delete fContainers;}
278 delete fExchangeCont;
279 delete fDebugOptions;
281 delete fInputEventHandler;
282 delete fOutputEventHandler;
283 delete fMCtruthEventHandler;
285 if (fgAnalysisManager==this) fgAnalysisManager = NULL;
286 if (fGlobals) {fGlobals->DeleteAll(); delete fGlobals;}
287 if (fFileDescriptors) {fFileDescriptors->Delete(); delete fFileDescriptors;}
293 //______________________________________________________________________________
294 void AliAnalysisManager::CreateReadCache()
296 // Create cache for reading according fCacheSize and fAsyncReading.
297 if (!fTree || !fTree->GetCurrentFile()) {
298 Error("CreateReadCache","Current tree or tree file not yet defined");
302 if (fDebug) Info("CreateReadCache","=== Read caching disabled ===");
305 gEnv->SetValue("TFile.AsyncPrefetching",(Int_t)fAsyncReading);
306 if (fAsyncReading) gEnv->SetValue("Cache.Directory",Form("file://%s/cache", gSystem->WorkingDirectory()));
307 if (fAsyncReading) gEnv->SetValue("TFile.AsyncReading",1);
308 fTree->SetCacheSize(fCacheSize);
309 TTreeCache::SetLearnEntries(1); //<<< we can take the decision after 1 entry
310 if (!fAutoBranchHandling && !fRequestedBranches.IsNull()) {
311 TObjArray *arr = fRequestedBranches.Tokenize(",");
315 fTree->AddBranchToCache(obj->GetName(),kTRUE); //<<< add requested branches to cache
318 fTree->AddBranchToCache("*", kTRUE); //<<< add all branches to cache
321 Info("CreateReadCache","Read cache enabled %lld bytes with async reading=%d",fCacheSize, (Int_t)fAsyncReading);
326 //______________________________________________________________________________
327 Bool_t AliAnalysisManager::EventLoop(Long64_t nevents)
329 // Initialize an event loop where the data producer is the input handler
330 // The handler must implement MakeTree creating the tree of events (likely
331 // memory resident) and generate the current event in the method BeginEvent.
332 // If the tree is memory resident, the handler should never call TTree::Fill
334 cout << "===== RUNNING IN EVENT LOOP MODE: " << GetName() << endl;
335 if (!fInputEventHandler) {
336 Error("EventLoop", "No input handler: exiting");
339 TTree *tree = new TTree("DummyTree", "Dummy tree for AliAnalysisManager::EventLoop");
340 SetExternalLoop(kTRUE);
341 if (!Init(tree)) return kFALSE;
343 for (Long64_t iev=0; iev<nevents; iev++)
346 PackOutput(&dummyList);
352 //______________________________________________________________________________
353 Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
355 // Read one entry of the tree or a whole branch.
356 fCurrentEntry = entry;
357 if (!fAutoBranchHandling)
359 if (!fTree || !fTree->GetTree()) return -1;
360 fIOTimer->Start(kTRUE);
361 Long64_t readbytes = fTree->GetTree()->GetEntry(entry, getall);
363 fIOTime += fIOTimer->RealTime();
364 return (Int_t)readbytes;
367 //______________________________________________________________________________
368 Int_t AliAnalysisManager::GetRunFromAlienPath(const char *path)
370 // Attempt to extract run number from input data path. Works only for paths to
371 // alice data in alien.
372 // sim: /alice/sim/<production>/run_no/...
373 // data: /alice/data/year/period/000run_no/... (ESD or AOD)
374 TString type = "unknown";
376 if (s.Contains("/alice/data")) type = "real";
377 else if (s.Contains("/alice/sim")) type = "simulated";
380 ind1 = s.Index("/00");
382 ind2 = s.Index("/",ind1+1);
383 if (ind2-ind1>8) srun = s(ind1+1, ind2-ind1-1);
386 ind1 = s.Index("/LHC");
388 ind1 = s.Index("/",ind1+1);
390 ind2 = s.Index("/",ind1+1);
391 if (ind2>0) srun = s(ind1+1, ind2-ind1-1);
395 Int_t run = srun.Atoi();
396 if (run>0) printf("=== GetRunFromAlienPath: run %d of %s data ===\n", run, type.Data());
400 //______________________________________________________________________________
401 Bool_t AliAnalysisManager::Init(TTree *tree)
403 // The Init() function is called when the selector needs to initialize
404 // a new tree or chain. Typically here the branch addresses of the tree
405 // will be set. It is normaly not necessary to make changes to the
406 // generated code, but the routine can be extended by the user if needed.
407 // Init() will be called many times when running with PROOF.
408 Bool_t init = kFALSE;
409 if (!tree) return kFALSE; // Should not happen - protected in selector caller
411 printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
413 // Call InitTree of EventHandler
414 if (fOutputEventHandler) {
415 if (fMode == kProofAnalysis) {
416 init = fOutputEventHandler->Init(0x0, "proof");
418 init = fOutputEventHandler->Init(0x0, "local");
421 Error("Init", "Output event handler failed to initialize");
426 if (fInputEventHandler) {
427 if (fMode == kProofAnalysis) {
428 init = fInputEventHandler->Init(tree, "proof");
430 init = fInputEventHandler->Init(tree, "local");
433 Error("Init", "Input event handler failed to initialize tree");
437 // If no input event handler we need to get the tree once
439 if(!tree->GetTree()) {
440 Long64_t readEntry = tree->LoadTree(0);
441 if (readEntry == -2) {
442 Error("Init", "Input tree has no entry. Exiting");
448 if (fMCtruthEventHandler) {
449 if (fMode == kProofAnalysis) {
450 init = fMCtruthEventHandler->Init(0x0, "proof");
452 init = fMCtruthEventHandler->Init(0x0, "local");
455 Error("Init", "MC event handler failed to initialize");
460 if (!fInitOK) InitAnalysis();
461 if (!fInitOK) return kFALSE;
463 if (fMode != kProofAnalysis) CreateReadCache();
465 // cholm - here we should re-add to the table or branches
468 AliAnalysisDataContainer *top = fCommonInput;
469 if (!top) top = (AliAnalysisDataContainer*)fInputs->At(0);
471 Error("Init","No top input container !");
475 CheckBranches(kFALSE);
478 printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
483 //______________________________________________________________________________
484 void AliAnalysisManager::SlaveBegin(TTree *tree)
486 // The SlaveBegin() function is called after the Begin() function.
487 // When running with PROOF SlaveBegin() is called on each slave server.
488 // The tree argument is deprecated (on PROOF 0 is passed).
489 if (fDebug > 1) printf("->AliAnalysisManager::SlaveBegin()\n");
490 // Init timer should be already started
491 // Apply debug options
494 fMCtruthEventHandler &&
495 (fMode != kProofAnalysis)) fMCtruthEventHandler->SetCacheSize(fCacheSize);
496 if (!CheckTasks()) Fatal("SlaveBegin", "Not all needed libraries were loaded");
497 static Bool_t isCalled = kFALSE;
498 Bool_t init = kFALSE;
499 Bool_t initOK = kTRUE;
501 TDirectory *curdir = gDirectory;
502 // Call SlaveBegin only once in case of mixing
503 if (isCalled && fMode==kMixingAnalysis) return;
505 // Call Init of EventHandler
506 if (fOutputEventHandler) {
507 if (fMode == kProofAnalysis) {
508 // Merging AOD's in PROOF via TProofOutputFile
509 if (fDebug > 1) printf(" Initializing AOD output file %s...\n", fOutputEventHandler->GetOutputFileName());
510 init = fOutputEventHandler->Init("proof");
511 if (!init) msg = "Failed to initialize output handler on worker";
513 init = fOutputEventHandler->Init("local");
514 if (!init) msg = "Failed to initialize output handler";
517 if (!fSelector) Error("SlaveBegin", "Selector not set");
518 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
521 if (fInputEventHandler) {
522 fInputEventHandler->SetInputTree(tree);
523 if (fMode == kProofAnalysis) {
524 init = fInputEventHandler->Init("proof");
525 if (!init) msg = "Failed to initialize input handler on worker";
527 init = fInputEventHandler->Init("local");
528 if (!init) msg = "Failed to initialize input handler";
531 if (!fSelector) Error("SlaveBegin", "Selector not set");
532 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
535 if (fMCtruthEventHandler) {
536 if (fMode == kProofAnalysis) {
537 init = fMCtruthEventHandler->Init("proof");
538 if (!init) msg = "Failed to initialize MC handler on worker";
540 init = fMCtruthEventHandler->Init("local");
541 if (!init) msg = "Failed to initialize MC handler";
544 if (!fSelector) Error("SlaveBegin", "Selector not set");
545 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
547 if (curdir) curdir->cd();
551 AliAnalysisTask *task;
552 // Call CreateOutputObjects for all tasks
553 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
554 Bool_t dirStatus = TH1::AddDirectoryStatus();
556 while ((task=(AliAnalysisTask*)next())) {
558 // Start with memory as current dir and make sure by default histograms do not get attached to files.
559 TH1::AddDirectory(kFALSE);
560 task->CreateOutputObjects();
561 if (!task->CheckPostData()) {
562 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
563 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
564 ####### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ##########", task->GetName(), task->ClassName());
566 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
569 TH1::AddDirectory(dirStatus);
570 if (curdir) curdir->cd();
572 fInitTime += fInitTimer->RealTime();
573 fInitTimer->Continue();
574 printf("Initialization time: %g [sec]\n", fInitTime);
575 if (fDebug > 1) printf("<-AliAnalysisManager::SlaveBegin()\n");
578 //______________________________________________________________________________
579 Bool_t AliAnalysisManager::Notify()
581 // The Notify() function is called when a new file is opened. This
582 // can be either for a new TTree in a TChain or when when a new TTree
583 // is started when using PROOF. It is normaly not necessary to make changes
584 // to the generated code, but the routine can be extended by the
585 // user if needed. The return value is currently not used.
586 fIOTimer->Start(kTRUE);
587 if (!fTree) return kFALSE;
588 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) return kFALSE;
590 fTable.Clear("nodelete"); // clearing the hash table may not be needed -> C.L.
591 if (fMode == kProofAnalysis) fIsRemote = kTRUE;
593 TFile *curfile = fTree->GetCurrentFile();
595 Error("Notify","No current file");
598 if (IsCollectThroughput()) {
599 if (fCurrentDescriptor) fCurrentDescriptor->Done();
600 fCurrentDescriptor = new AliAnalysisFileDescriptor(curfile);
601 fFileDescriptors->Add(fCurrentDescriptor);
604 if (fDebug > 1) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
605 Int_t run = AliAnalysisManager::GetRunFromAlienPath(curfile->GetName());
606 if (run && (run != fRunFromPath)) {
608 if (fDebug > 1) printf(" ### run found from path: %d\n", run);
611 AliAnalysisTask *task;
613 // Call Notify of the event handlers
614 if (fInputEventHandler) {
615 fInputEventHandler->Notify(curfile->GetName());
618 if (fOutputEventHandler) {
619 fOutputEventHandler->Notify(curfile->GetName());
622 if (fMCtruthEventHandler) {
623 fMCtruthEventHandler->Notify(curfile->GetName());
626 // Call Notify for all tasks
627 while ((task=(AliAnalysisTask*)next()))
630 if (fDebug > 1) printf("<-AliAnalysisManager::Notify()\n");
632 fIOTime += fIOTimer->RealTime();
636 //______________________________________________________________________________
637 Bool_t AliAnalysisManager::Process(Long64_t)
639 // The Process() function is called for each entry in the tree (or possibly
640 // keyed object in the case of PROOF) to be processed. The entry argument
641 // specifies which entry in the currently loaded tree is to be processed.
642 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
643 // to read either all or the required parts of the data. When processing
644 // keyed objects with PROOF, the object is already loaded and is available
645 // via the fObject pointer.
647 // This function should contain the "body" of the analysis. It can contain
648 // simple or elaborate selection criteria, run algorithms on the data
649 // of the event and typically fill histograms.
651 // WARNING when a selector is used with a TChain, you must use
652 // the pointer to the current TTree to call GetEntry(entry).
653 // The entry is always the local entry number in the current tree.
654 // Assuming that fChain is the pointer to the TChain being processed,
655 // use fChain->GetTree()->GetEntry(entry).
657 // This method is obsolete. ExecAnalysis is called instead.
661 //______________________________________________________________________________
662 void AliAnalysisManager::PackOutput(TList *target)
664 // Pack all output data containers in the output list. Called at SlaveTerminate
665 // stage in PROOF case for each slave.
666 if (fDebug > 1) printf("->AliAnalysisManager::PackOutput()\n");
667 fIOTimer->Start(kTRUE);
669 if (IsCollectThroughput()) {
670 if (fCurrentDescriptor) fCurrentDescriptor->Done();
671 fFileDescriptors->Print();
672 if (fFileInfoLog.IsNull()) fFileInfoLog = "fileinfo.log";
673 out.open(fFileInfoLog, std::ios::app);
674 if (out.bad()) Error("SavePrimitive", "Bad file name: %s", fFileInfoLog.Data());
676 TIter nextflog(fFileDescriptors);
678 while ((log=nextflog())) log->SavePrimitive(out,"");
682 Error("PackOutput", "No target. Exiting.");
685 TDirectory *cdir = gDirectory;
687 if (fInputEventHandler) fInputEventHandler ->Terminate();
688 if (fOutputEventHandler) fOutputEventHandler ->Terminate();
689 if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
692 // Call FinishTaskOutput() for each event loop task (not called for
693 // post-event loop tasks - use Terminate() fo those)
694 TIter nexttask(fTasks);
695 AliAnalysisTask *task;
696 while ((task=(AliAnalysisTask*)nexttask())) {
697 if (!task->IsPostEventLoop()) {
698 if (fDebug > 1) printf("->FinishTaskOutput: task %s\n", task->GetName());
699 task->FinishTaskOutput();
701 if (fDebug > 1) printf("<-FinishTaskOutput: task %s\n", task->GetName());
704 // Write statistics message on the workers.
705 if (fStatistics) WriteStatisticsMsg(fNcalls);
707 if (fMode == kProofAnalysis) {
708 TIter next(fOutputs);
709 AliAnalysisDataContainer *output;
710 Bool_t isManagedByHandler = kFALSE;
713 while ((output=(AliAnalysisDataContainer*)next())) {
714 // Do not consider outputs of post event loop tasks
715 isManagedByHandler = kFALSE;
716 if (output->GetProducer() && output->GetProducer()->IsPostEventLoop()) continue;
717 const char *filename = output->GetFileName();
718 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
719 isManagedByHandler = kTRUE;
720 printf("#### Handler output. Extra: %s\n", fExtraFiles.Data());
721 filename = fOutputEventHandler->GetOutputFileName();
723 // Check if data was posted to this container. If not, issue an error.
724 if (!output->GetData() && !isManagedByHandler) {
725 Error("PackOutput", "No data for output container %s. Forgot to PostData ?", output->GetName());
728 if (!output->IsSpecialOutput()) {
730 if (strlen(filename) && !isManagedByHandler) {
731 // Backup current folder
732 TDirectory *opwd = gDirectory;
733 // File resident outputs.
734 // Check first if the file exists.
735 TString openoption = "RECREATE";
736 Bool_t firsttime = kTRUE;
737 if (filestmp.FindObject(output->GetFileName())) {
740 filestmp.Add(new TNamed(output->GetFileName(),""));
742 if (!gSystem->AccessPathName(output->GetFileName()) && !firsttime) openoption = "UPDATE";
743 // TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
744 // Save data to file, then close.
745 if (output->GetData()->InheritsFrom(TCollection::Class())) {
746 // If data is a collection, we set the name of the collection
747 // as the one of the container and we save as a single key.
748 TCollection *coll = (TCollection*)output->GetData();
749 coll->SetName(output->GetName());
750 // coll->Write(output->GetName(), TObject::kSingleKey);
752 if (output->GetData()->InheritsFrom(TTree::Class())) {
753 TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
754 // Save data to file, then close.
755 TTree *tree = (TTree*)output->GetData();
756 // Check if tree is in memory
757 if (tree->GetDirectory()==gROOT) tree->SetDirectory(gDirectory);
761 // output->GetData()->Write();
764 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
766 // printf(" file %s listing content:\n", filename);
769 // Clear file list to release object ownership to user.
772 output->SetFile(NULL);
773 // Restore current directory
774 if (opwd) opwd->cd();
776 // Memory-resident outputs
777 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
779 AliAnalysisDataWrapper *wrap = 0;
780 if (isManagedByHandler) {
781 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
782 wrap->SetName(output->GetName());
784 else wrap =output->ExportData();
785 // Output wrappers must NOT delete data after merging - the user owns them
786 wrap->SetDeleteData(kFALSE);
789 // Special outputs. The file must be opened and connected to the container.
790 TDirectory *opwd = gDirectory;
791 TFile *file = output->GetFile();
793 AliAnalysisTask *producer = output->GetProducer();
795 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
796 output->GetFileName(), output->GetName(), producer->ClassName());
799 TString outFilename = file->GetName();
800 if (fDebug > 1) printf("PackOutput %s: special output\n", output->GetName());
801 if (isManagedByHandler) {
802 // Terminate IO for files managed by the output handler
803 // file->Write() moved to AOD handler (A.G. 11.01.10)
804 // if (file) file->Write();
805 if (file && fDebug > 2) {
806 printf(" handled file %s listing content:\n", file->GetName());
809 fOutputEventHandler->TerminateIO();
812 // Release object ownership to users after writing data to file
813 if (output->GetData()->InheritsFrom(TCollection::Class())) {
814 // If data is a collection, we set the name of the collection
815 // as the one of the container and we save as a single key.
816 TCollection *coll = (TCollection*)output->GetData();
817 coll->SetName(output->GetName());
818 coll->Write(output->GetName(), TObject::kSingleKey);
820 if (output->GetData()->InheritsFrom(TTree::Class())) {
821 TTree *tree = (TTree*)output->GetData();
822 tree->SetDirectory(file);
825 output->GetData()->Write();
829 printf(" file %s listing content:\n", output->GetFileName());
832 // Clear file list to release object ownership to user.
835 output->SetFile(NULL);
837 // Restore current directory
838 if (opwd) opwd->cd();
839 // Check if a special output location was provided or the output files have to be merged
840 if (strlen(fSpecialOutputLocation.Data())) {
841 TString remote = fSpecialOutputLocation;
843 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
844 if (remote.BeginsWith("alien:")) {
845 gROOT->ProcessLine("TGrid::Connect(\"alien:\", gProofServ->GetUser());");
846 remote += outFilename;
847 remote.ReplaceAll(".root", Form("_%d.root", gid));
849 remote += Form("%s_%d_", gSystem->HostName(), gid);
850 remote += outFilename;
853 Info("PackOutput", "Output file for container %s to be copied \n at: %s. No merging.",
854 output->GetName(), remote.Data());
855 TFile::Cp ( outFilename.Data(), remote.Data() );
856 // Copy extra outputs
857 if (fExtraFiles.Length() && isManagedByHandler) {
858 TObjArray *arr = fExtraFiles.Tokenize(" ");
860 TIter nextfilename(arr);
861 while ((os=(TObjString*)nextfilename())) {
862 outFilename = os->GetString();
863 remote = fSpecialOutputLocation;
865 if (remote.BeginsWith("alien://")) {
866 remote += outFilename;
867 remote.ReplaceAll(".root", Form("_%d.root", gid));
869 remote += Form("%s_%d_", gSystem->HostName(), gid);
870 remote += outFilename;
873 Info("PackOutput", "Extra AOD file %s to be copied \n at: %s. No merging.",
874 outFilename.Data(), remote.Data());
875 TFile::Cp ( outFilename.Data(), remote.Data() );
880 // No special location specified-> use TProofOutputFile as merging utility
881 // The file at this output slot must be opened in CreateOutputObjects
882 if (fDebug > 1) printf(" File for container %s to be merged via file merger...\n", output->GetName());
887 fIOTime += fIOTimer->RealTime();
888 if ((fDebug || IsCollectThroughput())) {
890 fInitTime = fInitTimer->RealTime()-fIOTime-fCPUTime;
891 printf("=Analysis %s= init time: %g[sec]\
892 \n I/O & data mng.: %g [sec]\
893 \n task execution: %g [sec]\
894 \n total time: CPU=%g [sec] REAL=%g[sec]\n",
895 GetName(), fInitTime, fIOTime, fCPUTime, fInitTimer->CpuTime(), fInitTimer->RealTime());
896 if (IsCollectThroughput()) {
897 out << "#summary#########################################################" << endl;
898 out << "train_name " << GetName() << endl;
899 out << "root_time " << fInitTimer->RealTime() << endl;
900 out << "root_cpu " << fInitTimer->CpuTime() << endl;
901 out << "init_time " << fInitTime << endl;
902 out << "io_mng_time " << fIOTime << endl;
903 out << "exec_time " << fCPUTime << endl;
904 TString aliensite = gSystem->Getenv("ALIEN_SITE");
905 out << "alien_site " << aliensite << endl;
907 TString hostname = gSystem->Getenv("ALIEN_HOSTNAME");
908 if (hostname.IsNull()) {
910 gSystem->Exec(Form("hostname -f >> %s", fFileInfoLog.Data()));
912 out << hostname << endl;
917 if (cdir) cdir->cd();
918 if (fDebug > 1) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
921 //______________________________________________________________________________
922 void AliAnalysisManager::ImportWrappers(TList *source)
924 // Import data in output containers from wrappers coming in source.
925 if (fDebug > 1) printf("->AliAnalysisManager::ImportWrappers()\n");
926 fIOTimer->Start(kTRUE);
927 TIter next(fOutputs);
928 AliAnalysisDataContainer *cont;
929 AliAnalysisDataWrapper *wrap;
931 Bool_t inGrid = (fMode == kGridAnalysis)?kTRUE:kFALSE;
932 TDirectory *cdir = gDirectory;
933 while ((cont=(AliAnalysisDataContainer*)next())) {
935 if (cont->GetProducer() && cont->GetProducer()->IsPostEventLoop() && !inGrid) continue;
936 if (cont->IsRegisterDataset()) continue;
937 const char *filename = cont->GetFileName();
938 Bool_t isManagedByHandler = kFALSE;
939 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
940 isManagedByHandler = kTRUE;
941 filename = fOutputEventHandler->GetOutputFileName();
943 if (cont->IsSpecialOutput() || inGrid) {
944 if (strlen(fSpecialOutputLocation.Data())) continue;
945 // Copy merged file from PROOF scratch space.
946 // In case of grid the files are already in the current directory.
948 if (isManagedByHandler && fExtraFiles.Length()) {
949 // Copy extra registered dAOD files.
950 TObjArray *arr = fExtraFiles.Tokenize(" ");
952 TIter nextfilename(arr);
953 while ((os=(TObjString*)nextfilename())) GetFileFromWrapper(os->GetString(), source);
956 if (!GetFileFromWrapper(filename, source)) continue;
958 // Normally we should connect data from the copied file to the
959 // corresponding output container, but it is not obvious how to do this
960 // automatically if several objects in file...
961 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
962 if (!f) f = TFile::Open(filename, "READ");
964 Error("ImportWrappers", "Cannot open file %s in read-only mode", filename);
969 // Cd to the directory pointed by the container
970 TString folder = cont->GetFolderName();
971 if (!folder.IsNull()) f->cd(folder);
972 // Try to fetch first an object having the container name.
973 obj = gDirectory->Get(cont->GetName());
975 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",
976 cont->GetType()->GetName(), cont->GetName(), filename, cont->GetFolderName(), cont->GetName());
979 wrap = new AliAnalysisDataWrapper(obj);
980 wrap->SetDeleteData(kFALSE);
982 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
984 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
989 printf(" Importing data for container %s\n", cont->GetName());
990 if (strlen(filename)) printf(" -> file %s\n", filename);
993 cont->ImportData(wrap);
995 if (cdir) cdir->cd();
997 fIOTime += fIOTimer->RealTime();
998 if (fDebug > 1) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
1001 //______________________________________________________________________________
1002 void AliAnalysisManager::UnpackOutput(TList *source)
1004 // Called by AliAnalysisSelector::Terminate only on the client.
1005 fIOTimer->Start(kTRUE);
1006 if (fDebug > 1) printf("->AliAnalysisManager::UnpackOutput()\n");
1008 Error("UnpackOutput", "No target. Exiting.");
1011 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
1013 if (fMode == kProofAnalysis) ImportWrappers(source);
1015 TIter next(fOutputs);
1016 AliAnalysisDataContainer *output;
1017 while ((output=(AliAnalysisDataContainer*)next())) {
1018 if (!output->GetData()) continue;
1019 // Check if there are client tasks that run post event loop
1020 if (output->HasConsumers()) {
1021 // Disable event loop semaphore
1022 output->SetPostEventLoop(kTRUE);
1023 TObjArray *list = output->GetConsumers();
1024 Int_t ncons = list->GetEntriesFast();
1025 for (Int_t i=0; i<ncons; i++) {
1026 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
1027 task->CheckNotify(kTRUE);
1028 // If task is active, execute it
1029 if (task->IsPostEventLoop() && task->IsActive()) {
1030 if (fDebug > 1) printf("== Executing post event loop task %s\n", task->GetName());
1031 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
1032 task->ExecuteTask();
1035 if (fStatistics) fStatistics->StopTimer();
1039 fIOTime += fIOTimer->RealTime();
1040 if (fDebug > 1) printf("<-AliAnalysisManager::UnpackOutput()\n");
1043 //______________________________________________________________________________
1044 void AliAnalysisManager::Terminate()
1046 // The Terminate() function is the last function to be called during
1047 // a query. It always runs on the client, it can be used to present
1048 // the results graphically.
1049 if (fDebug > 1) printf("->AliAnalysisManager::Terminate()\n");
1050 fInitTimer->Start(kTRUE);
1051 TDirectory *cdir = gDirectory;
1053 AliAnalysisTask *task;
1054 AliAnalysisDataContainer *output;
1057 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1058 // Call Terminate() for tasks
1060 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
1061 // Save all the canvases produced by the Terminate
1062 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
1066 AliSysInfo::AddStamp(Form("%s_TERMINATE",task->ClassName()),0, itask, 2);
1068 if (TObject::TestBit(kSaveCanvases)) {
1069 if (!gROOT->IsBatch()) {
1070 if (fDebug>1) printf("Waiting 5 sec for %s::Terminate() to finish drawing ...\n", task->ClassName());
1072 while (timer.RealTime()<5) {
1074 gSystem->ProcessEvents();
1077 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
1078 if (iend==0) continue;
1080 for (Int_t ipict=0; ipict<iend; ipict++) {
1081 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
1082 if (!canvas) continue;
1083 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
1085 gROOT->GetListOfCanvases()->Delete();
1089 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
1090 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
1091 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
1093 TObjArray *allOutputs = new TObjArray();
1095 for (icont=0; icont<fOutputs->GetEntriesFast(); icont++) allOutputs->Add(fOutputs->At(icont));
1096 if (!IsSkipTerminate())
1097 for (icont=0; icont<fParamCont->GetEntriesFast(); icont++) allOutputs->Add(fParamCont->At(icont));
1098 TIter next1(allOutputs);
1099 TString handlerFile = "";
1100 TString extraOutputs = "";
1101 if (fOutputEventHandler) {
1102 handlerFile = fOutputEventHandler->GetOutputFileName();
1103 extraOutputs = fOutputEventHandler->GetExtraOutputs();
1107 while ((output=(AliAnalysisDataContainer*)next1())) {
1108 // Special outputs or grid files have the files already closed and written.
1110 if (fMode == kGridAnalysis && icont<=fOutputs->GetEntriesFast()) continue;
1111 if (fMode == kProofAnalysis) {
1112 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
1114 const char *filename = output->GetFileName();
1115 TString openoption = "RECREATE";
1116 if (!(strcmp(filename, "default"))) continue;
1117 if (!strlen(filename)) continue;
1118 if (!output->GetData()) continue;
1119 TDirectory *opwd = gDirectory;
1120 TFile *file = output->GetFile();
1121 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1123 //if (handlerFile == filename && !gSystem->AccessPathName(filename)) openoption = "UPDATE";
1124 Bool_t firsttime = kTRUE;
1125 if (filestmp.FindObject(filename) || extraOutputs.Contains(filename)) {
1128 filestmp.Add(new TNamed(filename,""));
1130 if (!gSystem->AccessPathName(filename) && !firsttime) openoption = "UPDATE";
1131 if (fDebug>1) printf("Opening file: %s option=%s\n",filename, openoption.Data());
1132 file = new TFile(filename, openoption);
1134 if (fDebug>1) printf("File <%s> already opened with option: <%s> \n", filename, file->GetOption());
1135 openoption = file->GetOption();
1136 if (openoption == "READ") {
1137 if (fDebug>1) printf("...reopening in UPDATE mode\n");
1138 file->ReOpen("UPDATE");
1141 if (file->IsZombie()) {
1142 Error("Terminate", "Cannot open output file %s", filename);
1145 output->SetFile(file);
1147 // Check for a folder request
1148 TString dir = output->GetFolderName();
1149 if (!dir.IsNull()) {
1150 if (!file->GetDirectory(dir)) file->mkdir(dir);
1153 if (fDebug > 1) printf("...writing container %s to file %s:%s\n", output->GetName(), file->GetName(), output->GetFolderName());
1154 if (output->GetData()->InheritsFrom(TCollection::Class())) {
1155 // If data is a collection, we set the name of the collection
1156 // as the one of the container and we save as a single key.
1157 TCollection *coll = (TCollection*)output->GetData();
1158 coll->SetName(output->GetName());
1159 coll->Write(output->GetName(), TObject::kSingleKey);
1161 if (output->GetData()->InheritsFrom(TTree::Class())) {
1162 TTree *tree = (TTree*)output->GetData();
1163 tree->SetDirectory(gDirectory);
1166 output->GetData()->Write();
1169 if (opwd) opwd->cd();
1173 TString copiedFiles;
1174 while ((output=(AliAnalysisDataContainer*)next1())) {
1175 // Close all files at output
1176 TDirectory *opwd = gDirectory;
1177 if (output->GetFile()) {
1178 // Clear file list to release object ownership to user.
1179 // output->GetFile()->Clear();
1180 output->GetFile()->Close();
1181 // Copy merged outputs in alien if requested
1182 if (fSpecialOutputLocation.BeginsWith("alien://")) {
1183 if (copiedFiles.Contains(output->GetFile()->GetName())) {
1184 if (opwd) opwd->cd();
1185 output->SetFile(NULL);
1188 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
1189 gROOT->ProcessLine("if (!gGrid) TGrid::Connect(\"alien:\");");
1190 TFile::Cp(output->GetFile()->GetName(),
1191 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
1192 copiedFiles += output->GetFile()->GetName();
1194 output->SetFile(NULL);
1196 if (opwd) opwd->cd();
1199 //Write statistics information on the client
1200 if (fStatistics) WriteStatisticsMsg(fNcalls);
1202 TDirectory *crtdir = gDirectory;
1203 TFile f("syswatch.root", "RECREATE");
1206 if (!f.IsZombie()) {
1207 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
1208 tree->SetName("syswatch");
1209 tree->SetMarkerStyle(kCircle);
1210 tree->SetMarkerColor(kBlue);
1211 tree->SetMarkerSize(0.5);
1212 if (!gROOT->IsBatch()) {
1213 tree->SetAlias("event", "id0");
1214 tree->SetAlias("task", "id1");
1215 tree->SetAlias("stage", "id2");
1216 // Already defined aliases
1217 // tree->SetAlias("deltaT","stampSec-stampOldSec");
1218 // tree->SetAlias("T","stampSec-first");
1219 // tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)");
1220 // tree->SetAlias("VM","pI.fMemVirtual");
1221 TCanvas *canvas = new TCanvas("SysInfo","SysInfo",10,10,1200,800);
1222 Int_t npads = 1 /*COO plot for all tasks*/ +
1223 fTopTasks->GetEntries() /*Exec plot per task*/ +
1224 1 /*Terminate plot for all tasks*/ +
1227 Int_t iopt = (Int_t)TMath::Sqrt((Double_t)npads);
1228 if (npads<iopt*(iopt+1))
1229 canvas->Divide(iopt, iopt+1, 0.01, 0.01);
1231 canvas->Divide(iopt+1, iopt+1, 0.01, 0.01);
1233 // draw the plot of deltaVM for Exec for each task
1234 for (itask=0; itask<fTopTasks->GetEntriesFast(); itask++) {
1235 task = (AliAnalysisTask*)fTopTasks->At(itask);
1237 cut = Form("task==%d && stage==1", itask);
1238 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1239 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1241 hist->SetTitle(Form("%s: Exec dVM[MB]/event", task->GetName()));
1242 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1245 // Draw the plot of deltaVM for CreateOutputObjects for all tasks
1247 tree->SetMarkerStyle(kFullTriangleUp);
1248 tree->SetMarkerColor(kRed);
1249 tree->SetMarkerSize(0.8);
1250 cut = "task>=0 && task<1000 && stage==0";
1251 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1252 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1254 hist->SetTitle("Memory in CreateOutputObjects()");
1255 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1256 hist->GetXaxis()->SetTitle("task");
1258 // draw the plot of deltaVM for Terminate for all tasks
1260 tree->SetMarkerStyle(kOpenSquare);
1261 tree->SetMarkerColor(kMagenta);
1262 cut = "task>=0 && task<1000 && stage==2";
1263 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1264 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1266 hist->SetTitle("Memory in Terminate()");
1267 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1268 hist->GetXaxis()->SetTitle("task");
1272 tree->SetMarkerStyle(kFullCircle);
1273 tree->SetMarkerColor(kGreen);
1274 cut = Form("task==%d && stage==1",fTopTasks->GetEntriesFast()-1);
1275 tree->Draw("VM:event",cut,"", 1234567890, 0);
1276 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1278 hist->SetTitle("Virtual memory");
1279 hist->GetYaxis()->SetTitle("VM [MB]");
1283 tree->SetMarkerStyle(kCircle);
1284 tree->SetMarkerColor(kBlue);
1285 tree->SetMarkerSize(0.5);
1290 if (crtdir) crtdir->cd();
1292 // Validate the output files
1293 if (ValidateOutputFiles() && fIsRemote && fMode!=kProofAnalysis) {
1295 out.open("outputs_valid", ios::out);
1298 if (cdir) cdir->cd();
1300 if (fDebug || IsCollectThroughput()) {
1301 printf("=Analysis %s= Terminate time: %g[sec]\n", GetName(), fInitTimer->RealTime());
1303 if (fDebug > 1) printf("<-AliAnalysisManager::Terminate()\n");
1305 //______________________________________________________________________________
1306 void AliAnalysisManager::ProfileTask(Int_t itop, const char *option) const
1308 // Profiles the task having the itop index in the list of top (first level) tasks.
1309 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->At(itop);
1311 Error("ProfileTask", "There are only %d top tasks in the manager", fTopTasks->GetEntries());
1314 ProfileTask(task->GetName(), option);
1317 //______________________________________________________________________________
1318 void AliAnalysisManager::ProfileTask(const char *name, const char */*option*/) const
1320 // Profile a managed task after the execution of the analysis in case NSysInfo
1322 if (gSystem->AccessPathName("syswatch.root")) {
1323 Error("ProfileTask", "No file syswatch.root found in the current directory");
1326 if (gROOT->IsBatch()) return;
1327 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->FindObject(name);
1329 Error("ProfileTask", "No top task named %s known by the manager.", name);
1332 Int_t itop = fTopTasks->IndexOf(task);
1333 Int_t itask = fTasks->IndexOf(task);
1334 // Create canvas with 2 pads: first draw COO + Terminate, second Exec
1335 TDirectory *cdir = gDirectory;
1336 TFile f("syswatch.root");
1337 TTree *tree = (TTree*)f.Get("syswatch");
1339 Error("ProfileTask", "No tree named <syswatch> found in file syswatch.root");
1342 if (fDebug > 1) printf("=== Profiling task %s (class %s)\n", name, task->ClassName());
1343 TCanvas *canvas = new TCanvas(Form("profile_%d",itop),Form("Profile of task %s (class %s)",name,task->ClassName()),10,10,800,600);
1344 canvas->Divide(2, 2, 0.01, 0.01);
1348 // VM profile for COO and Terminate methods
1350 cut = Form("task==%d && (stage==0 || stage==2)",itask);
1351 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1352 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1354 hist->SetTitle("Alocated VM[MB] for COO and Terminate");
1355 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1356 hist->GetXaxis()->SetTitle("method");
1358 // CPU profile per event
1360 cut = Form("task==%d && stage==1",itop);
1361 tree->Draw("deltaT:event",cut,"", 1234567890, 0);
1362 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1364 hist->SetTitle("Execution time per event");
1365 hist->GetYaxis()->SetTitle("CPU/event [s]");
1367 // VM profile for Exec
1369 cut = Form("task==%d && stage==1",itop);
1370 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1371 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1373 hist->SetTitle("Alocated VM[MB] per event");
1374 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1379 if (cdir) cdir->cd();
1382 //______________________________________________________________________________
1383 void AliAnalysisManager::AddTask(AliAnalysisTask *task)
1385 // Adds a user task to the global list of tasks.
1387 Error("AddTask", "Cannot add task %s since InitAnalysis was already called", task->GetName());
1391 if (fTasks->FindObject(task)) {
1392 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
1395 task->SetActive(kFALSE);
1399 //______________________________________________________________________________
1400 AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
1402 // Retreive task by name.
1403 if (!fTasks) return NULL;
1404 return (AliAnalysisTask*)fTasks->FindObject(name);
1407 //______________________________________________________________________________
1408 Int_t AliAnalysisManager::GetTaskIndex(const AliAnalysisTask *task) const
1410 // Returns task inded in the manager's list, -1 if not registered.
1411 if (!fTasks) return -1;
1412 return fTasks->IndexOf(task);
1415 //______________________________________________________________________________
1416 AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
1417 TClass *datatype, EAliAnalysisContType type, const char *filename)
1419 // Create a data container of a certain type. Types can be:
1420 // kExchangeContainer = 0, used to exchange data between tasks
1421 // kInputContainer = 1, used to store input data
1422 // kOutputContainer = 2, used for writing result to a file
1423 // filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
1424 // the output object to a folder inside the output file
1425 if (fContainers->FindObject(name)) {
1426 Error("CreateContainer","A container named %s already defined !",name);
1429 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
1430 fContainers->Add(cont);
1432 case kInputContainer:
1435 case kOutputContainer:
1436 fOutputs->Add(cont);
1437 if (filename && strlen(filename)) {
1438 cont->SetFileName(filename);
1439 cont->SetDataOwned(kFALSE); // data owned by the file
1442 case kParamContainer:
1443 fParamCont->Add(cont);
1444 if (filename && strlen(filename)) {
1445 cont->SetFileName(filename);
1446 cont->SetDataOwned(kFALSE); // data owned by the file
1449 case kExchangeContainer:
1450 cont->SetExchange(kTRUE);
1451 fExchangeCont->Add(cont);
1452 cont->SetDataOwned(kFALSE); // data owned by the publisher
1458 //______________________________________________________________________________
1459 Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
1460 AliAnalysisDataContainer *cont)
1462 // Connect input of an existing task to a data container.
1464 Error("ConnectInput", "Task pointer is NULL");
1467 if (!fTasks->FindObject(task)) {
1469 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
1471 Bool_t connected = task->ConnectInput(islot, cont);
1475 //______________________________________________________________________________
1476 Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
1477 AliAnalysisDataContainer *cont)
1479 // Connect output of an existing task to a data container.
1481 Error("ConnectOutput", "Task pointer is NULL");
1484 if (!fTasks->FindObject(task)) {
1486 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
1488 Bool_t connected = task->ConnectOutput(islot, cont);
1492 //______________________________________________________________________________
1493 void AliAnalysisManager::CleanContainers()
1495 // Clean data from all containers that have already finished all client tasks.
1496 TIter next(fContainers);
1497 AliAnalysisDataContainer *cont;
1498 while ((cont=(AliAnalysisDataContainer *)next())) {
1499 if (cont->IsOwnedData() &&
1500 cont->IsDataReady() &&
1501 cont->ClientsExecuted()) cont->DeleteData();
1505 //______________________________________________________________________________
1506 Bool_t AliAnalysisManager::InitAnalysis()
1508 // Initialization of analysis chain of tasks. Should be called after all tasks
1509 // and data containers are properly connected
1510 // Reset flag and remove valid_outputs file if exists
1511 if (fInitOK) return kTRUE;
1512 if (!gSystem->AccessPathName("outputs_valid"))
1513 gSystem->Unlink("outputs_valid");
1514 // Check for top tasks (depending only on input data containers)
1515 if (!fTasks->First()) {
1516 Error("InitAnalysis", "Analysis has no tasks !");
1520 AliAnalysisTask *task;
1521 AliAnalysisDataContainer *cont;
1524 Bool_t iszombie = kFALSE;
1525 Bool_t istop = kTRUE;
1527 while ((task=(AliAnalysisTask*)next())) {
1530 Int_t ninputs = task->GetNinputs();
1531 for (i=0; i<ninputs; i++) {
1532 cont = task->GetInputSlot(i)->GetContainer();
1536 fZombies->Add(task);
1540 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
1541 i, task->GetName());
1543 if (iszombie) continue;
1544 // Check if cont is an input container
1545 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
1546 // Connect to parent task
1550 fTopTasks->Add(task);
1554 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
1557 // Check now if there are orphan tasks
1558 for (i=0; i<ntop; i++) {
1559 task = (AliAnalysisTask*)fTopTasks->At(i);
1564 while ((task=(AliAnalysisTask*)next())) {
1565 if (!task->IsUsed()) {
1567 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
1570 // Check the task hierarchy (no parent task should depend on data provided
1571 // by a daughter task)
1572 for (i=0; i<ntop; i++) {
1573 task = (AliAnalysisTask*)fTopTasks->At(i);
1574 if (task->CheckCircularDeps()) {
1575 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
1580 // Check that all containers feeding post-event loop tasks are in the outputs list
1581 TIter nextcont(fContainers); // loop over all containers
1582 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1583 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1584 if (cont->HasConsumers()) {
1585 // Check if one of the consumers is post event loop
1586 TIter nextconsumer(cont->GetConsumers());
1587 while ((task=(AliAnalysisTask*)nextconsumer())) {
1588 if (task->IsPostEventLoop()) {
1589 fOutputs->Add(cont);
1596 // Check if all special output containers have a file name provided
1597 TIter nextout(fOutputs);
1598 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1599 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1600 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1604 // Initialize requested branch list if needed
1605 if (!fAutoBranchHandling) {
1607 while ((task=(AliAnalysisTask*)next())) {
1608 if (!task->HasBranches()) {
1609 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\"",
1610 task->GetName(), task->ClassName());
1613 if (!fInputEventHandler || !strlen(fInputEventHandler->GetDataType())) {
1614 Error("InitAnalysis", "Manual branch loading requested but no input handler defined or handler does not define data type.");
1617 TString taskbranches;
1618 task->GetBranches(fInputEventHandler->GetDataType(), taskbranches);
1619 if (taskbranches.IsNull()) {
1620 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches of type %s:",
1621 task->GetName(), task->ClassName(), fInputEventHandler->GetDataType());
1624 AddBranches(taskbranches);
1631 //______________________________________________________________________________
1632 void AliAnalysisManager::AddBranches(const char *branches)
1634 // Add branches to the existing fRequestedBranches.
1635 TString br(branches);
1636 TObjArray *arr = br.Tokenize(",");
1639 while ((obj=next())) {
1640 if (!fRequestedBranches.Contains(obj->GetName())) {
1641 if (!fRequestedBranches.IsNull()) fRequestedBranches += ",";
1642 fRequestedBranches += obj->GetName();
1648 //______________________________________________________________________________
1649 void AliAnalysisManager::CheckBranches(Bool_t load)
1651 // The method checks the input branches to be loaded during the analysis.
1652 if (fAutoBranchHandling || fRequestedBranches.IsNull() || !fTree) return;
1653 TObjArray *arr = fRequestedBranches.Tokenize(",");
1656 while ((obj=next())) {
1657 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(obj->GetName()));
1659 br = fTree->GetBranch(obj->GetName());
1661 Error("CheckBranches", "Could not find branch %s",obj->GetName());
1666 if (load && br->GetReadEntry()!=GetCurrentEntry()) {
1667 br->GetEntry(GetCurrentEntry());
1673 //______________________________________________________________________________
1674 Bool_t AliAnalysisManager::CheckTasks() const
1676 // Check consistency of tasks.
1677 Int_t ntasks = fTasks->GetEntries();
1679 Error("CheckTasks", "No tasks connected to the manager. This may be due to forgetting to compile the task or to load their library.");
1682 // Get the pointer to AliAnalysisTaskSE::Class()
1683 TClass *badptr = (TClass*)gROOT->ProcessLine("AliAnalysisTaskSE::Class()");
1684 // Loop all tasks to check if their corresponding library was loaded
1687 while ((obj=next())) {
1688 if (obj->IsA() == badptr) {
1689 Error("CheckTasks", "##################\n \
1690 Class for task %s NOT loaded. You probably forgot to load the library for this task (or compile it dynamically).\n###########################\n",obj->GetName());
1697 //______________________________________________________________________________
1698 void AliAnalysisManager::PrintStatus(Option_t *option) const
1700 // Print task hierarchy.
1702 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1705 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1707 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
1708 AliAnalysisDataContainer *cont = fCommonInput;
1709 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
1710 printf("=== TOP CONTAINER:\n");
1711 cont->PrintContainer(option,0);
1712 // Reset "touched" flag
1713 TIter next(fContainers);
1714 while ((cont = (AliAnalysisDataContainer*)next())) cont->SetTouched(kFALSE);
1715 TIter nextt(fTasks);
1716 AliAnalysisTask *task;
1717 while ((task=(AliAnalysisTask*)nextt()))
1718 task->SetActive(kFALSE);
1720 if (!fAutoBranchHandling && !fRequestedBranches.IsNull())
1721 printf("Requested input branches:\n%s\n", fRequestedBranches.Data());
1723 TString sopt(option);
1726 if (sopt.Contains("ALL"))
1728 if ( fOutputEventHandler )
1730 cout << TString('_',78) << endl;
1731 cout << "OutputEventHandler:" << endl;
1732 fOutputEventHandler->Print(" ");
1737 //______________________________________________________________________________
1738 void AliAnalysisManager::ResetAnalysis()
1740 // Reset all execution flags and clean containers.
1741 TIter nextTask(fTasks);
1742 AliAnalysisTask *task;
1743 while ((task=(AliAnalysisTask*)nextTask())) {
1747 // CleanContainers();
1750 //______________________________________________________________________________
1751 void AliAnalysisManager::RunLocalInit()
1753 // Run LocalInit method for all tasks.
1754 TDirectory *cdir = gDirectory;
1755 if (IsTrainInitialized()) return;
1756 TIter nextTask(fTasks);
1757 AliAnalysisTask *task;
1758 while ((task=(AliAnalysisTask*)nextTask())) {
1762 if (cdir) cdir->cd();
1763 TObject::SetBit(kTasksInitialized, kTRUE);
1766 //______________________________________________________________________________
1767 void AliAnalysisManager::InputFileFromTree(TTree * const tree, TString &fname)
1769 // Retrieves name of the file from tree
1772 TFile *file = tree->GetCurrentFile();
1775 TChain *chain = dynamic_cast<TChain*>(tree);
1776 if (!chain || !chain->GetNtrees()) return;
1777 basename = gSystem->BaseName(chain->GetListOfFiles()->First()->GetTitle());
1779 basename = gSystem->BaseName(file->GetName());
1781 Int_t index = basename.Index("#");
1782 fname = basename(index+1, basename.Length());
1785 //______________________________________________________________________________
1786 Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
1788 // Start analysis having a grid handler.
1789 if (!fGridHandler) {
1790 Error("StartAnalysis", "Cannot start analysis providing just the analysis type without a grid handler.");
1791 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1795 return StartAnalysis(type, tree, nentries, firstentry);
1798 //______________________________________________________________________________
1799 Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
1801 // Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1802 // MIX. Process nentries starting from firstentry
1804 // Backup current directory and make sure gDirectory points to gROOT
1805 TDirectory *cdir = gDirectory;
1808 Error("StartAnalysis","Analysis manager was not initialized !");
1809 if (cdir) cdir->cd();
1812 if (!CheckTasks()) Fatal("StartAnalysis", "Not all needed libraries were loaded");
1814 printf("StartAnalysis %s\n",GetName());
1815 AliLog::SetGlobalLogLevel(AliLog::kInfo);
1817 fMaxEntries = nentries;
1819 TString anaType = type;
1821 fMode = kLocalAnalysis;
1822 if (anaType.Contains("file")) fIsRemote = kTRUE;
1823 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1824 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1825 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1826 if (fInputEventHandler) {
1828 InputFileFromTree(tree, fname);
1829 if (fname.Length()) fInputEventHandler->SetInputFileName(fname);
1832 if (fMode == kGridAnalysis) {
1834 if (!anaType.Contains("terminate")) {
1835 if (!fGridHandler) {
1836 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1837 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1838 if (cdir) cdir->cd();
1841 // Write analysis manager in the analysis file
1842 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1843 // run local task configuration
1845 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1846 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1847 if (cdir) cdir->cd();
1851 // Terminate grid analysis
1852 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1853 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1854 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1855 if (!fGridHandler->MergeOutputs()) {
1856 // Return if outputs could not be merged or if it alien handler
1857 // was configured for offline mode or local testing.
1858 if (cdir) cdir->cd();
1862 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1863 if (cdir) cdir->cd();
1864 ImportWrappers(NULL);
1866 if (cdir) cdir->cd();
1870 SetEventLoop(kFALSE);
1871 // Enable event loop mode if a tree was provided
1872 if (tree || fGridHandler || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
1875 TString ttype = "TTree";
1876 if (tree && tree->IsA() == TChain::Class()) {
1877 chain = (TChain*)tree;
1878 if (!chain || !chain->GetListOfFiles()->First()) {
1879 Error("StartAnalysis", "Cannot process null or empty chain...");
1880 if (cdir) cdir->cd();
1886 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1887 if (getsysInfo) AliSysInfo::AddStamp("Start", 0);
1888 // Initialize locally all tasks (happens for all modes)
1890 AliAnalysisTask *task;
1894 case kLocalAnalysis:
1895 if (!tree && !fGridHandler) {
1896 TIter nextT(fTasks);
1897 // Call CreateOutputObjects for all tasks
1899 Bool_t dirStatus = TH1::AddDirectoryStatus();
1900 while ((task=(AliAnalysisTask*)nextT())) {
1901 TH1::AddDirectory(kFALSE);
1902 task->CreateOutputObjects();
1903 if (!task->CheckPostData()) {
1904 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
1905 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
1906 ########### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ###########", task->GetName(), task->ClassName());
1908 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
1912 TH1::AddDirectory(dirStatus);
1913 if (IsExternalLoop()) {
1914 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1915 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1922 fSelector = new AliAnalysisSelector(this);
1923 // Check if a plugin handler is used
1925 // Get the chain from the plugin
1926 TString dataType = "esdTree";
1927 if (fInputEventHandler) {
1928 dataType = fInputEventHandler->GetDataType();
1932 chain = fGridHandler->GetChainForTestMode(dataType);
1934 Error("StartAnalysis", "No chain for test mode. Aborting.");
1937 cout << "===== RUNNING LOCAL ANALYSIS" << GetName() << " ON CHAIN " << chain->GetName() << endl;
1938 retv = chain->Process(fSelector, "", nentries, firstentry);
1941 // Run tree-based analysis via AliAnalysisSelector
1942 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
1943 retv = tree->Process(fSelector, "", nentries, firstentry);
1945 case kProofAnalysis:
1947 // Check if the plugin is used
1949 return StartAnalysis(type, fGridHandler->GetProofDataSet(), nentries, firstentry);
1951 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1952 Error("StartAnalysis", "No PROOF!!! Exiting.");
1953 if (cdir) cdir->cd();
1956 line = Form("gProof->AddInput((TObject*)%p);", this);
1957 gROOT->ProcessLine(line);
1960 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
1961 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
1963 Error("StartAnalysis", "No chain!!! Exiting.");
1964 if (cdir) cdir->cd();
1970 if (!anaType.Contains("terminate")) {
1971 if (!fGridHandler) {
1972 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1973 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1974 if (cdir) cdir->cd();
1977 // Write analysis manager in the analysis file
1978 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1979 // Start the analysis via the handler
1980 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1981 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1982 if (cdir) cdir->cd();
1986 // Terminate grid analysis
1987 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1988 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1989 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1990 if (!fGridHandler->MergeOutputs()) {
1991 // Return if outputs could not be merged or if it alien handler
1992 // was configured for offline mode or local testing.
1993 if (cdir) cdir->cd();
1997 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1998 ImportWrappers(NULL);
2000 if (cdir) cdir->cd();
2002 case kMixingAnalysis:
2003 // Run event mixing analysis
2005 Error("StartAnalysis", "Cannot run event mixing without event pool");
2006 if (cdir) cdir->cd();
2009 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
2010 fSelector = new AliAnalysisSelector(this);
2011 while ((chain=fEventPool->GetNextChain())) {
2013 // Call NotifyBinChange for all tasks
2014 while ((task=(AliAnalysisTask*)next()))
2015 if (!task->IsPostEventLoop()) task->NotifyBinChange();
2016 retv = chain->Process(fSelector);
2018 Error("StartAnalysis", "Mixing analysis failed");
2019 if (cdir) cdir->cd();
2023 PackOutput(fSelector->GetOutputList());
2026 if (cdir) cdir->cd();
2030 //______________________________________________________________________________
2031 Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
2033 // Start analysis for this manager on a given dataset. Analysis task can be:
2034 // LOCAL, PROOF or GRID. Process nentries starting from firstentry.
2036 Error("StartAnalysis","Analysis manager was not initialized !");
2040 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
2041 TString anaType = type;
2043 if (!anaType.Contains("proof")) {
2044 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
2047 fMode = kProofAnalysis;
2049 TString proofProcessOpt;
2050 SetEventLoop(kTRUE);
2051 // Set the dataset flag
2052 TObject::SetBit(kUseDataSet);
2055 // Start proof analysis using the grid handler
2056 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
2057 Error("StartAnalysis", "The grid plugin could not start PROOF analysis");
2060 // Check if the plugin is in test mode
2061 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kTest) {
2062 dataset = "test_collection";
2064 dataset = fGridHandler->GetProofDataSet();
2067 proofProcessOpt = fGridHandler->GetProofProcessOpt();
2070 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
2071 Error("StartAnalysis", "No PROOF!!! Exiting.");
2075 // Initialize locally all tasks
2078 line = Form("gProof->AddInput((TObject*)%p);", this);
2079 gROOT->ProcessLine(line);
2081 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"%s\", %lld, %lld);",
2082 dataset,proofProcessOpt.Data(), nentries, firstentry);
2083 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
2084 retv = (Long_t)gROOT->ProcessLine(line);
2088 //______________________________________________________________________________
2089 TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
2091 // Opens according the option the file specified by cont->GetFileName() and changes
2092 // current directory to cont->GetFolderName(). If the file was already opened, it
2093 // checks if the option UPDATE was preserved. File open via TProofOutputFile can
2094 // be optionally ignored.
2095 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2096 TString filename = cont->GetFileName();
2098 if (filename.IsNull()) {
2099 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
2102 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
2104 f = mgr->OpenProofFile(cont,option);
2106 // Check first if the file is already opened
2107 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2109 // Check if option "UPDATE" was preserved
2110 TString opt(option);
2112 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2113 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2115 f = TFile::Open(filename, option);
2118 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2122 // Check for a folder request
2123 TString dir = cont->GetFolderName();
2124 if (!dir.IsNull()) {
2125 if (!f->GetDirectory(dir)) f->mkdir(dir);
2130 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
2131 cont->SetFile(NULL);
2135 //______________________________________________________________________________
2136 TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option, const char *extaod)
2138 // Opens a special output file used in PROOF.
2140 TString filename = cont->GetFileName();
2141 if (cont == fCommonOutput) {
2142 if (fOutputEventHandler) {
2143 if (strlen(extaod)) filename = extaod;
2144 filename = fOutputEventHandler->GetOutputFileName();
2146 else Fatal("OpenProofFile","No output container. Exiting.");
2149 if (fMode!=kProofAnalysis || !fSelector) {
2150 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
2153 if (fSpecialOutputLocation.Length()) {
2154 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2156 // Check if option "UPDATE" was preserved
2157 TString opt(option);
2159 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2160 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2162 f = new TFile(filename, option);
2164 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2168 // Check for a folder request
2169 TString dir = cont->GetFolderName();
2171 if (!f->GetDirectory(dir)) f->mkdir(dir);
2176 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2177 cont->SetFile(NULL);
2180 // Check if there is already a proof output file in the output list
2181 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
2183 // Get the actual file
2184 line = Form("((TProofOutputFile*)%p)->GetFileName();", pof);
2185 filename = (const char*)gROOT->ProcessLine(line);
2187 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
2189 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2191 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
2194 // Check if option "UPDATE" was preserved
2195 TString opt(option);
2197 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2198 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
2200 if (cont->IsRegisterDataset()) {
2201 TString dsetName = filename;
2202 dsetName.ReplaceAll(".root", cont->GetTitle());
2203 dsetName.ReplaceAll(":","_");
2204 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
2205 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
2207 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
2208 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
2210 if (fDebug > 1) printf("=== %s\n", line.Data());
2211 gROOT->ProcessLine(line);
2212 line = Form("pf->OpenFile(\"%s\");", option);
2213 gROOT->ProcessLine(line);
2216 gROOT->ProcessLine("pf->Print()");
2217 printf(" == proof file name: %s", f->GetName());
2219 // Add to proof output list
2220 line = Form("((TList*)%p)->Add(pf);",fSelector->GetOutputList());
2221 if (fDebug > 1) printf("=== %s\n", line.Data());
2222 gROOT->ProcessLine(line);
2224 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2228 // Check for a folder request
2229 TString dir = cont->GetFolderName();
2230 if (!dir.IsNull()) {
2231 if (!f->GetDirectory(dir)) f->mkdir(dir);
2236 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2237 cont->SetFile(NULL);
2241 //______________________________________________________________________________
2242 void AliAnalysisManager::ExecAnalysis(Option_t *option)
2244 // Execute analysis.
2245 static Long64_t nentries = 0;
2246 static TTree *lastTree = 0;
2247 static TStopwatch *timer = new TStopwatch();
2248 // Only the first call to Process will trigger a true Notify. Other Notify
2249 // coming before is ignored.
2250 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) {
2251 TObject::SetBit(AliAnalysisManager::kTrueNotify);
2254 if (fDebug > 0) printf("MGR: Processing event #%d\n", fNcalls);
2256 if (fTree && (fTree != lastTree)) {
2257 nentries += fTree->GetEntries();
2260 if (!fNcalls) timer->Start();
2261 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", fNcalls, TMath::Min(fMaxEntries,nentries), timer, kFALSE);
2263 fIOTimer->Start(kTRUE);
2265 TDirectory *cdir = gDirectory;
2266 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
2267 if (getsysInfo && ((fNcalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)fNcalls);
2269 Error("ExecAnalysis", "Analysis manager was not initialized !");
2270 if (cdir) cdir->cd();
2274 AliAnalysisTask *task;
2275 // Reset the analysis
2277 // Check if the top tree is active.
2279 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2280 AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
2282 // De-activate all tasks (not needed anymore after ResetAnalysis
2283 // while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
2284 AliAnalysisDataContainer *cont = fCommonInput;
2285 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
2287 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
2288 if (cdir) cdir->cd();
2291 cont->SetData(fTree); // This set activity for all tasks reading only from the top container
2292 Long64_t entry = fTree->GetTree()->GetReadEntry();
2294 // Call BeginEvent() for optional input/output and MC services
2295 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
2296 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
2297 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
2299 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2300 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2302 // Execute the tasks
2303 // TIter next1(cont->GetConsumers());
2305 fIOTime += fIOTimer->RealTime();
2306 fCPUTimer->Start(kTRUE);
2307 TIter next1(fTopTasks);
2309 while ((task=(AliAnalysisTask*)next1())) {
2310 task->SetActive(kTRUE);
2312 cout << " Executing task " << task->GetName() << endl;
2314 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
2315 task->ExecuteTask(option);
2316 if (fStatistics) fStatistics->StopTimer();
2318 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2319 AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
2323 fCPUTime += fCPUTimer->RealTime();
2324 fIOTimer->Start(kTRUE);
2326 // Call FinishEvent() for optional output and MC services
2327 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2328 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2329 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2330 // Gather system information if requested
2331 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2332 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1001, 1);
2333 if (cdir) cdir->cd();
2335 fIOTime += fIOTimer->RealTime();
2338 // The event loop is not controlled by TSelector
2340 // Call BeginEvent() for optional input/output and MC services
2341 fIOTimer->Start(kTRUE);
2342 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
2343 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
2344 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
2346 fIOTime += fIOTimer->RealTime();
2348 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2349 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2350 fCPUTimer->Start(kTRUE);
2351 TIter next2(fTopTasks);
2352 while ((task=(AliAnalysisTask*)next2())) {
2353 task->SetActive(kTRUE);
2355 cout << " Executing task " << task->GetName() << endl;
2357 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
2358 task->ExecuteTask(option);
2359 if (fStatistics) fStatistics->StopTimer();
2363 fCPUTime += fCPUTimer->RealTime();
2365 // Call FinishEvent() for optional output and MC services
2366 fIOTimer->Start(kTRUE);
2367 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2368 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2369 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2370 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2371 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
2372 if (cdir) cdir->cd();
2374 fIOTime += fIOTimer->RealTime();
2377 //______________________________________________________________________________
2378 Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
2380 // Check if the stdout is connected to a pipe (C.Holm)
2381 Bool_t ispipe = kFALSE;
2382 out.seekp(0, std::ios_base::cur);
2385 if (errno == ESPIPE) ispipe = kTRUE;
2390 //______________________________________________________________________________
2391 void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
2393 // Set the input event handler and create a container for it.
2395 fInputEventHandler = handler;
2396 if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
2399 //______________________________________________________________________________
2400 void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
2402 // Set the input event handler and create a container for it.
2404 fOutputEventHandler = handler;
2405 if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
2406 fCommonOutput->SetSpecialOutput();
2409 //______________________________________________________________________________
2410 void AliAnalysisManager::SetDebugLevel(UInt_t level)
2412 // Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
2413 if (TObject::TestBit(kUseProgressBar)) {
2414 Info("SetDebugLevel","Ignored. Disable the progress bar first.");
2420 //______________________________________________________________________________
2421 void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
2423 // Enable a text mode progress bar. Resets debug level to 0.
2424 Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
2425 TObject::SetBit(kUseProgressBar,flag);
2426 fPBUpdateFreq = freq;
2430 //______________________________________________________________________________
2431 void AliAnalysisManager::RegisterExtraFile(const char *fname)
2433 // This method is used externally to register output files which are not
2434 // connected to any output container, so that the manager can properly register,
2435 // retrieve or merge them when running in distributed mode. The file names are
2436 // separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
2437 if (fExtraFiles.Contains(fname)) return;
2438 if (fExtraFiles.Length()) fExtraFiles += " ";
2439 fExtraFiles += fname;
2442 //______________________________________________________________________________
2443 Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
2445 // Copy a file from the location specified ina the wrapper with the same name from the source list.
2449 TObject *pof = source->FindObject(filename);
2450 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
2451 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
2454 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
2455 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
2456 TString clientUrl(chUrl);
2457 TString fullPath_str(fullPath);
2458 if (clientUrl.Contains("localhost")){
2459 TObjArray* array = fullPath_str.Tokenize ( "//" );
2460 TObjString *strobj = ( TObjString *)array->At(1);
2461 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
2462 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
2463 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
2464 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
2465 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
2469 else if (clientUrl.Contains("__lite__")) {
2470 // Special case for ProofLite environement - get file info and copy.
2471 gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
2472 fullPath_str = Form("%s/%s", tmp, fullPath);
2475 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
2476 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
2478 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
2482 //______________________________________________________________________________
2483 void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
2485 // Fill analysis type in the provided string.
2487 case kLocalAnalysis:
2490 case kProofAnalysis:
2496 case kMixingAnalysis:
2501 //______________________________________________________________________________
2502 Bool_t AliAnalysisManager::ValidateOutputFiles() const
2504 // Validate all output files.
2505 TIter next(fOutputs);
2506 AliAnalysisDataContainer *output;
2507 TDirectory *cdir = gDirectory;
2508 TString openedFiles;
2509 while ((output=(AliAnalysisDataContainer*)next())) {
2510 if (output->IsRegisterDataset()) continue;
2511 TString filename = output->GetFileName();
2512 if (filename == "default") {
2513 if (!fOutputEventHandler) continue;
2514 filename = fOutputEventHandler->GetOutputFileName();
2515 // Main AOD may not be there
2516 if (gSystem->AccessPathName(filename)) continue;
2518 // Check if the file is closed
2519 if (openedFiles.Contains(filename)) continue;;
2520 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2522 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
2523 // Clear file list to release object ownership to user.
2527 file = TFile::Open(filename);
2528 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
2529 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
2530 if (cdir) cdir->cd();
2534 openedFiles += filename;
2537 if (cdir) cdir->cd();
2541 //______________________________________________________________________________
2542 void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
2544 // Implements a nice text mode progress bar.
2545 static Long64_t icount = 0;
2546 static TString oname;
2547 static TString nname;
2548 static Long64_t ocurrent = 0;
2549 static Long64_t osize = 0;
2550 static Int_t oseconds = 0;
2551 static TStopwatch *owatch = 0;
2552 static Bool_t oneoftwo = kFALSE;
2553 static Int_t nrefresh = 0;
2554 static Int_t nchecks = 0;
2555 static char lastChar = 0;
2556 const char symbol[4] = {'-','\\','|','/'};
2558 if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
2564 ocurrent = TMath::Abs(current);
2565 osize = TMath::Abs(size);
2566 if (ocurrent > osize) ocurrent=osize;
2571 if ((current % fPBUpdateFreq) != 0) return;
2573 char progress[11] = " ";
2574 Int_t ichar = icount%4;
2579 if (owatch && !last) {
2581 time = owatch->RealTime();
2582 seconds = int(time) % 60;
2583 minutes = (int(time) / 60) % 60;
2584 hours = (int(time) / 60 / 60);
2586 if (oseconds==seconds) {
2590 oneoftwo = !oneoftwo;
2594 if (refresh && oneoftwo) {
2596 if (nchecks <= 0) nchecks = nrefresh+1;
2597 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
2598 oname = Form(" == %d%% ==", pctdone);
2600 Double_t percent = 100.0*ocurrent/osize;
2601 Int_t nchar = Int_t(percent/10);
2602 if (nchar>10) nchar=10;
2604 for (i=0; i<nchar; i++) progress[i] = '=';
2605 progress[nchar] = symbol[ichar];
2606 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2607 progress[10] = '\0';
2610 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2611 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2612 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
2614 Int_t full = Int_t(ocurrent > 0 ?
2615 time * (float(osize)/ocurrent) + .5 :
2617 Int_t remain = Int_t(full - time);
2618 Int_t rsec = remain % 60;
2619 Int_t rmin = (remain / 60) % 60;
2620 Int_t rhour = (remain / 60 / 60);
2621 fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
2622 percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
2624 else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
2625 if (refresh && oneoftwo) oname = nname;
2626 if (owatch) owatch->Continue();
2635 fprintf(stderr, "\n");
2639 //______________________________________________________________________________
2640 void AliAnalysisManager::DoLoadBranch(const char *name)
2642 // Get tree and load branch if needed.
2643 static Long64_t crtEntry = -100;
2645 if (fAutoBranchHandling || !fTree)
2648 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2650 br = fTree->GetBranch(name);
2652 Error("DoLoadBranch", "Could not find branch %s",name);
2657 if (br->GetReadEntry()==fCurrentEntry) return;
2658 Long64_t readbytes = br->GetEntry(GetCurrentEntry());
2660 Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
2661 if (crtEntry != fCurrentEntry) {
2662 CountEvent(1,0,1,0);
2663 crtEntry = fCurrentEntry;
2666 if (crtEntry != fCurrentEntry) {
2667 CountEvent(1,1,0,0);
2668 crtEntry = fCurrentEntry;
2673 //______________________________________________________________________________
2674 void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
2676 // Add the statistics task to the manager.
2678 Info("AddStatisticsTask", "Already added");
2681 TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
2682 gROOT->ProcessLine(line);
2685 //______________________________________________________________________________
2686 void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
2688 // Bookkeep current event;
2689 if (!fStatistics) return;
2690 fStatistics->AddInput(ninput);
2691 fStatistics->AddProcessed(nprocessed);
2692 fStatistics->AddFailed(nfailed);
2693 fStatistics->AddAccepted(naccepted);
2696 //______________________________________________________________________________
2697 void AliAnalysisManager::AddStatisticsMsg(const char *line)
2699 // Add a line in the statistics message. If available, the statistics message is written
2700 // at the end of the SlaveTerminate phase on workers AND at the end of Terminate
2702 if (!strlen(line)) return;
2703 if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
2704 fStatisticsMsg += line;
2707 //______________________________________________________________________________
2708 void AliAnalysisManager::WriteStatisticsMsg(Int_t)
2710 // If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
2711 static Bool_t done = kFALSE;
2714 if (!fStatistics) return;
2716 AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
2717 AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
2718 AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
2719 AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
2720 out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
2721 fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
2722 fStatistics->GetNaccepted()), ios::out);
2723 out << fStatisticsMsg << endl;
2727 //______________________________________________________________________________
2728 const char* AliAnalysisManager::GetOADBPath()
2730 // returns the path of the OADB
2731 // this static function just depends on environment variables
2733 static TString oadbPath;
2735 if (gSystem->Getenv("OADB_PATH"))
2736 oadbPath = gSystem->Getenv("OADB_PATH");
2737 else if (gSystem->Getenv("ALICE_ROOT"))
2738 oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
2740 ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
2745 //______________________________________________________________________________
2746 void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
2748 // Define a custom string variable mapped to a global unique name. The variable
2749 // can be then retrieved by a given analysis macro via GetGlobalStr(key).
2750 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2752 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2755 Bool_t valid = kFALSE;
2756 TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
2758 ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
2761 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
2764 //______________________________________________________________________________
2765 const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
2767 // Static method to retrieve a global variable defined via SetGlobalStr.
2769 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2771 TObject *value = mgr->GetGlobals()->GetValue(key);
2772 if (!value) return 0;
2774 return value->GetName();
2777 //______________________________________________________________________________
2778 void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
2780 // Define a custom integer variable mapped to a global unique name. The variable
2781 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2782 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2784 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2787 Bool_t valid = kFALSE;
2788 Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
2790 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
2793 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
2796 //______________________________________________________________________________
2797 Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
2799 // Static method to retrieve a global variable defined via SetGlobalInt.
2801 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2803 TObject *value = mgr->GetGlobals()->GetValue(key);
2804 if (!value) return 0;
2806 TString s = value->GetName();
2810 //______________________________________________________________________________
2811 void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
2813 // Define a custom double precision variable mapped to a global unique name. The variable
2814 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2815 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2817 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2820 Bool_t valid = kFALSE;
2821 Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
2823 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
2826 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));
2829 //______________________________________________________________________________
2830 Double_t AliAnalysisManager::GetGlobalDbl(const char *key, Bool_t &valid)
2832 // Static method to retrieve a global variable defined via SetGlobalDbl.
2834 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2836 TObject *value = mgr->GetGlobals()->GetValue(key);
2837 if (!value) return 0;
2839 TString s = value->GetName();
2843 //______________________________________________________________________________
2844 void AliAnalysisManager::AddClassDebug(const char *className, Int_t debugLevel)
2846 // Sets Class debug level
2848 if (!fDebugOptions) {
2849 fDebugOptions = new TObjArray();
2850 fDebugOptions->SetOwner(kTRUE);
2853 TNamed *debugOpt = (TNamed*)fDebugOptions->FindObject(className);
2855 AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel,className).Data());
2856 fDebugOptions->Add(new TNamed(className,TString::Format("%d",debugLevel).Data()));
2858 TString oldDebugStr = debugOpt->GetTitle();
2859 Int_t oldDebug = oldDebugStr.Atoi();
2860 if (debugLevel > oldDebug) {
2861 AliWarning(TString::Format("Overwriting debug level to %d class %s, because it is higher then previously set (%d).",debugLevel,className,oldDebug).Data());
2862 debugOpt->SetTitle(TString::Format("%d",debugLevel).Data());
2864 AliWarning(TString::Format("Ignoring debug level to %d class %s, because it is smaller then previously set (%d).",debugLevel,className,oldDebug).Data());
2869 //______________________________________________________________________________
2870 void AliAnalysisManager::ApplyDebugOptions()
2872 // Apply debug options
2874 if (!fDebugOptions) return;
2876 TIter next(fDebugOptions);
2879 while ((debug=dynamic_cast<TNamed*>(next()))) {
2880 debugLevel = debug->GetTitle();
2881 AliInfo(TString::Format("Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()).Data());
2882 AliLog::SetClassDebugLevel(debug->GetName(), debugLevel.Atoi());
2886 //______________________________________________________________________________
2887 Bool_t AliAnalysisManager::IsMacroLoaded(const char * filename)
2889 // Check if a macro was loaded.
2890 return fgMacroNames.Contains(filename);
2893 //______________________________________________________________________________
2894 Int_t AliAnalysisManager::LoadMacro(const char *filename, Int_t *error, Bool_t check)
2896 // Redirection of gROOT->LoadMacro which makes sure the same macro is not loaded
2898 TString macroName = gSystem->BaseName(filename);
2899 // Strip appended +, ++, +g, +O
2900 Int_t index = macroName.Index("+");
2901 if (index>0) macroName.Remove(index);
2902 if (fgMacroNames.Contains(macroName)) {
2903 // Macro with the same name loaded already in this root session, do
2908 Int_t ret = gROOT->LoadMacro(filename,error,check);
2909 // In case of error return the error code
2910 if (ret) return ret;
2911 // Append the macro name to the loaded macros list
2912 fgMacroNames += macroName;
2913 fgMacroNames += " ";
2917 //______________________________________________________________________________
2918 void AliAnalysisManager::Lock()
2920 // Security lock. This is to detect NORMAL user errors and not really to
2921 // protect against intentional hacks.
2922 if (fLocked) return;
2924 if (fInputEventHandler) fInputEventHandler->Lock();
2925 if (fOutputEventHandler) fOutputEventHandler->Lock();
2926 if (fMCtruthEventHandler) fMCtruthEventHandler->Lock();
2927 Info("Lock","====== ANALYSIS MANAGER LOCKED ======");
2930 //______________________________________________________________________________
2931 void AliAnalysisManager::UnLock()
2933 // Verbose unlocking. Hackers will be punished ;-) ...
2934 if (!fLocked) return;
2936 if (fInputEventHandler) fInputEventHandler->UnLock();
2937 if (fOutputEventHandler) fOutputEventHandler->UnLock();
2938 if (fMCtruthEventHandler) fMCtruthEventHandler->UnLock();
2939 Info("UnLock", "====== ANALYSIS MANAGER UNLOCKED ======");
2942 //______________________________________________________________________________
2943 void AliAnalysisManager::Changed()
2945 // All critical setters pass through the Changed method that throws an exception
2946 // in case the lock was set.
2947 if (fLocked) Fatal("Changed","Critical setter called in locked mode");