1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 // Author: Andrei Gheata, 31/05/2006
19 //==============================================================================
20 // AliAnalysisManager - Manager analysis class. Allows creation of several
21 // analysis tasks and data containers storing their input/output. Allows
22 // connecting/chaining tasks via shared data containers. Serializes the current
23 // event for all tasks depending only on initial input data.
24 //==============================================================================
26 //==============================================================================
28 #include "AliAnalysisManager.h"
31 #include <Riostream.h>
36 #include <TTreeCache.h>
40 #include <TMethodCall.h>
45 #include <TStopwatch.h>
48 #include "AliAnalysisSelector.h"
49 #include "AliAnalysisGrid.h"
50 #include "AliAnalysisTask.h"
51 #include "AliAnalysisDataContainer.h"
52 #include "AliAnalysisDataSlot.h"
53 #include "AliVEventHandler.h"
54 #include "AliVEventPool.h"
55 #include "AliSysInfo.h"
56 #include "AliAnalysisStatistics.h"
57 #include "AliVEvent.h"
58 #include "AliHLTTestInputHandler.h"
64 ClassImp(AliAnalysisManager)
66 AliAnalysisManager *AliAnalysisManager::fgAnalysisManager = NULL;
67 TString AliAnalysisManager::fgCommonFileName = "";
68 TString AliAnalysisManager::fgMacroNames = "";
69 Int_t AliAnalysisManager::fPBUpdateFreq = 1;
71 //______________________________________________________________________________
72 AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
75 fInputEventHandler(0),
76 fOutputEventHandler(0),
77 fMCtruthEventHandler(0),
81 fMode(kLocalAnalysis),
88 fSpecialOutputLocation(""),
98 fFileDescriptors(new TObjArray()),
99 fCurrentDescriptor(0),
106 fAutoBranchHandling(kTRUE),
107 fAsyncReading(kFALSE), // default prefetching on
112 fCacheSize(100000000), // default 100 MB
114 fRequestedBranches(),
124 // Default constructor.
125 fgAnalysisManager = this;
126 fgCommonFileName = "AnalysisResults.root";
127 if (TClass::IsCallingNew() != TClass::kDummyNew) {
128 fTasks = new TObjArray();
129 fTopTasks = new TObjArray();
130 fZombies = new TObjArray();
131 fContainers = new TObjArray();
132 fInputs = new TObjArray();
133 fOutputs = new TObjArray();
134 fParamCont = new TObjArray();
135 fExchangeCont = new TObjArray();
136 fGlobals = new TMap();
138 fIOTimer = new TStopwatch();
139 fCPUTimer = new TStopwatch();
140 fInitTimer = new TStopwatch();
144 //______________________________________________________________________________
145 AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
148 fInputEventHandler(NULL),
149 fOutputEventHandler(NULL),
150 fMCtruthEventHandler(NULL),
155 fInitOK(other.fInitOK),
156 fMustClean(other.fMustClean),
157 fIsRemote(other.fIsRemote),
158 fLocked(other.fLocked),
159 fMCLoop(other.fMCLoop),
160 fDebug(other.fDebug),
161 fSpecialOutputLocation(""),
171 fFileDescriptors(new TObjArray()),
172 fCurrentDescriptor(0),
177 fExtraFiles(other.fExtraFiles),
178 fFileInfoLog(other.fFileInfoLog),
179 fAutoBranchHandling(other.fAutoBranchHandling),
180 fAsyncReading(other.fAsyncReading),
183 fNcalls(other.fNcalls),
184 fMaxEntries(other.fMaxEntries),
185 fCacheSize(other.fCacheSize),
186 fStatisticsMsg(other.fStatisticsMsg),
187 fRequestedBranches(other.fRequestedBranches),
188 fStatistics(other.fStatistics),
189 fGlobals(other.fGlobals),
190 fIOTimer(new TStopwatch()),
191 fCPUTimer(new TStopwatch()),
192 fInitTimer(new TStopwatch()),
198 fTasks = new TObjArray(*other.fTasks);
199 fTopTasks = new TObjArray(*other.fTopTasks);
200 fZombies = new TObjArray(*other.fZombies);
201 fContainers = new TObjArray(*other.fContainers);
202 fInputs = new TObjArray(*other.fInputs);
203 fOutputs = new TObjArray(*other.fOutputs);
204 fParamCont = new TObjArray(*other.fParamCont);
205 fExchangeCont = new TObjArray(*other.fExchangeCont);
206 fgCommonFileName = "AnalysisResults.root";
207 fgAnalysisManager = this;
210 //______________________________________________________________________________
211 AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& other)
214 if (&other != this) {
215 TNamed::operator=(other);
216 fInputEventHandler = other.fInputEventHandler;
217 fOutputEventHandler = other.fOutputEventHandler;
218 fMCtruthEventHandler = other.fMCtruthEventHandler;
219 fEventPool = other.fEventPool;
222 fNSysInfo = other.fNSysInfo;
224 fInitOK = other.fInitOK;
225 fIsRemote = other.fIsRemote;
226 fLocked = other.fLocked;
227 fMCLoop = other.fMCLoop;
228 fDebug = other.fDebug;
229 fTasks = new TObjArray(*other.fTasks);
230 fTopTasks = new TObjArray(*other.fTopTasks);
231 fZombies = new TObjArray(*other.fZombies);
232 fContainers = new TObjArray(*other.fContainers);
233 fInputs = new TObjArray(*other.fInputs);
234 fOutputs = new TObjArray(*other.fOutputs);
235 fParamCont = new TObjArray(*other.fParamCont);
236 fExchangeCont = new TObjArray(*other.fExchangeCont);
237 fDebugOptions = NULL;
238 fFileDescriptors = new TObjArray();
239 fCurrentDescriptor = 0;
241 fCommonOutput = NULL;
244 fExtraFiles = other.fExtraFiles;
245 fFileInfoLog = other.fFileInfoLog;
246 fgCommonFileName = "AnalysisResults.root";
247 fgAnalysisManager = this;
248 fAutoBranchHandling = other.fAutoBranchHandling;
249 fAsyncReading = other.fAsyncReading;
250 fTable.Clear("nodelete");
251 fRunFromPath = other.fRunFromPath;
252 fNcalls = other. fNcalls;
253 fMaxEntries = other.fMaxEntries;
254 fCacheSize = other.fCacheSize;
255 fStatisticsMsg = other.fStatisticsMsg;
256 fRequestedBranches = other.fRequestedBranches;
257 fStatistics = other.fStatistics;
258 fGlobals = new TMap();
259 fIOTimer = new TStopwatch();
260 fCPUTimer = new TStopwatch();
261 fInitTimer = new TStopwatch();
269 //______________________________________________________________________________
270 AliAnalysisManager::~AliAnalysisManager()
273 if (fTasks) {fTasks->Delete(); delete fTasks;}
276 if (fContainers) {fContainers->Delete(); delete fContainers;}
280 delete fExchangeCont;
281 delete fDebugOptions;
283 delete fInputEventHandler;
284 delete fOutputEventHandler;
285 delete fMCtruthEventHandler;
287 if (fgAnalysisManager==this) fgAnalysisManager = NULL;
288 if (fGlobals) {fGlobals->DeleteAll(); delete fGlobals;}
289 if (fFileDescriptors) {fFileDescriptors->Delete(); delete fFileDescriptors;}
295 //______________________________________________________________________________
296 void AliAnalysisManager::CreateReadCache()
298 // Create cache for reading according fCacheSize and fAsyncReading.
299 if (!fTree || !fTree->GetCurrentFile()) {
300 Error("CreateReadCache","Current tree or tree file not yet defined");
304 if (fDebug) Info("CreateReadCache","=== Read caching disabled ===");
307 gEnv->SetValue("TFile.AsyncPrefetching",(Int_t)fAsyncReading);
308 // if (fAsyncReading) gEnv->SetValue("Cache.Directory",Form("file://%s/cache", gSystem->WorkingDirectory()));
309 // if (fAsyncReading) gEnv->SetValue("TFile.AsyncReading",1);
310 fTree->SetCacheSize(fCacheSize);
311 TTreeCache::SetLearnEntries(1); //<<< we can take the decision after 1 entry
312 if (!fAutoBranchHandling && !fRequestedBranches.IsNull()) {
313 TObjArray *arr = fRequestedBranches.Tokenize(",");
317 fTree->AddBranchToCache(obj->GetName(),kTRUE); //<<< add requested branches to cache
320 fTree->AddBranchToCache("*", kTRUE); //<<< add all branches to cache
323 Info("CreateReadCache","Read cache enabled %lld bytes with async reading=%d",fCacheSize, (Int_t)fAsyncReading);
328 //______________________________________________________________________________
329 Bool_t AliAnalysisManager::EventLoop(Long64_t nevents)
331 // Initialize an event loop where the data producer is the input handler
332 // The handler must implement MakeTree creating the tree of events (likely
333 // memory resident) and generate the current event in the method BeginEvent.
334 // If the tree is memory resident, the handler should never call TTree::Fill
336 cout << "===== RUNNING IN EVENT LOOP MODE: " << GetName() << endl;
337 if (!fInputEventHandler) {
338 Error("EventLoop", "No input handler: exiting");
341 TTree *tree = new TTree("DummyTree", "Dummy tree for AliAnalysisManager::EventLoop");
342 SetExternalLoop(kTRUE);
343 if (!Init(tree)) return kFALSE;
345 for (Long64_t iev=0; iev<nevents; iev++)
348 PackOutput(&dummyList);
354 //______________________________________________________________________________
355 Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
357 // Read one entry of the tree or a whole branch.
358 fCurrentEntry = entry;
359 if (!fAutoBranchHandling)
361 if (!fTree || !fTree->GetTree()) return -1;
362 fIOTimer->Start(kTRUE);
363 Long64_t readbytes = fTree->GetTree()->GetEntry(entry, getall);
365 fIOTime += fIOTimer->RealTime();
366 return (Int_t)readbytes;
369 //______________________________________________________________________________
370 Int_t AliAnalysisManager::GetRunFromAlienPath(const char *path)
372 // Attempt to extract run number from input data path. Works only for paths to
373 // alice data in alien.
374 // sim: /alice/sim/<production>/run_no/...
375 // data: /alice/data/year/period/000run_no/... (ESD or AOD)
376 TString type = "unknown";
378 if (s.Contains("/alice/data")) type = "real";
379 else if (s.Contains("/alice/sim")) type = "simulated";
382 ind1 = s.Index("/00");
384 ind2 = s.Index("/",ind1+1);
385 if (ind2-ind1>8) srun = s(ind1+1, ind2-ind1-1);
388 ind1 = s.Index("/LHC");
390 ind1 = s.Index("/",ind1+1);
392 ind2 = s.Index("/",ind1+1);
393 if (ind2>0) srun = s(ind1+1, ind2-ind1-1);
397 Int_t run = srun.Atoi();
398 if (run>0) printf("=== GetRunFromAlienPath: run %d of %s data ===\n", run, type.Data());
402 //______________________________________________________________________________
403 Bool_t AliAnalysisManager::Init(TTree *tree)
405 // The Init() function is called when the selector needs to initialize
406 // a new tree or chain. Typically here the branch addresses of the tree
407 // will be set. It is normaly not necessary to make changes to the
408 // generated code, but the routine can be extended by the user if needed.
409 // Init() will be called many times when running with PROOF.
410 Bool_t init = kFALSE;
411 if (!tree) return kFALSE; // Should not happen - protected in selector caller
413 printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
415 // Call InitTree of EventHandler
416 if (fOutputEventHandler) {
417 if (fMode == kProofAnalysis) {
418 init = fOutputEventHandler->Init(0x0, "proof");
420 init = fOutputEventHandler->Init(0x0, "local");
423 Error("Init", "Output event handler failed to initialize");
428 if (fInputEventHandler) {
429 if (fMode == kProofAnalysis) {
430 init = fInputEventHandler->Init(tree, "proof");
432 init = fInputEventHandler->Init(tree, "local");
435 Error("Init", "Input event handler failed to initialize tree");
439 // If no input event handler we need to get the tree once
441 if(!tree->GetTree()) {
442 Long64_t readEntry = tree->LoadTree(0);
443 if (readEntry == -2) {
444 Error("Init", "Input tree has no entry. Exiting");
450 if (fMCtruthEventHandler) {
451 if (fMode == kProofAnalysis) {
452 init = fMCtruthEventHandler->Init(0x0, "proof");
454 init = fMCtruthEventHandler->Init(0x0, "local");
457 Error("Init", "MC event handler failed to initialize");
462 if (!fInitOK) InitAnalysis();
463 if (!fInitOK) return kFALSE;
465 if (fMode != kProofAnalysis) CreateReadCache();
467 // cholm - here we should re-add to the table or branches
470 AliAnalysisDataContainer *top = fCommonInput;
471 if (!top) top = (AliAnalysisDataContainer*)fInputs->At(0);
473 Error("Init","No top input container !");
477 CheckBranches(kFALSE);
480 printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
485 //______________________________________________________________________________
486 void AliAnalysisManager::SlaveBegin(TTree *tree)
488 // The SlaveBegin() function is called after the Begin() function.
489 // When running with PROOF SlaveBegin() is called on each slave server.
490 // The tree argument is deprecated (on PROOF 0 is passed).
491 if (fDebug > 1) printf("->AliAnalysisManager::SlaveBegin()\n");
492 // Init timer should be already started
493 // Apply debug options
496 fMCtruthEventHandler &&
497 (fMode != kProofAnalysis)) fMCtruthEventHandler->SetCacheSize(fCacheSize);
498 if (!CheckTasks()) Fatal("SlaveBegin", "Not all needed libraries were loaded");
499 static Bool_t isCalled = kFALSE;
500 Bool_t init = kFALSE;
501 Bool_t initOK = kTRUE;
503 TDirectory *curdir = gDirectory;
504 // Call SlaveBegin only once in case of mixing
505 if (isCalled && fMode==kMixingAnalysis) return;
507 // Call Init of EventHandler
508 if (fOutputEventHandler) {
509 if (fMode == kProofAnalysis) {
510 // Merging AOD's in PROOF via TProofOutputFile
511 if (fDebug > 1) printf(" Initializing AOD output file %s...\n", fOutputEventHandler->GetOutputFileName());
512 init = fOutputEventHandler->Init("proof");
513 if (!init) msg = "Failed to initialize output handler on worker";
515 init = fOutputEventHandler->Init("local");
516 if (!init) msg = "Failed to initialize output handler";
519 if (!fSelector) Error("SlaveBegin", "Selector not set");
520 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
523 if (fInputEventHandler) {
524 fInputEventHandler->SetInputTree(tree);
525 if (fMode == kProofAnalysis) {
526 init = fInputEventHandler->Init("proof");
527 if (!init) msg = "Failed to initialize input handler on worker";
529 init = fInputEventHandler->Init("local");
530 if (!init) msg = "Failed to initialize input handler";
533 if (!fSelector) Error("SlaveBegin", "Selector not set");
534 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
537 if (fMCtruthEventHandler) {
538 if (fMode == kProofAnalysis) {
539 init = fMCtruthEventHandler->Init("proof");
540 if (!init) msg = "Failed to initialize MC handler on worker";
542 init = fMCtruthEventHandler->Init("local");
543 if (!init) msg = "Failed to initialize MC handler";
546 if (!fSelector) Error("SlaveBegin", "Selector not set");
547 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
549 if (curdir) curdir->cd();
553 AliAnalysisTask *task;
554 // Call CreateOutputObjects for all tasks
555 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
556 if (getsysInfo) AliSysInfo::SetVerbose(kTRUE);
557 Bool_t dirStatus = TH1::AddDirectoryStatus();
559 while ((task=(AliAnalysisTask*)next())) {
561 // Start with memory as current dir and make sure by default histograms do not get attached to files.
562 TH1::AddDirectory(kFALSE);
563 task->CreateOutputObjects();
564 if (!task->CheckPostData()) {
565 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
566 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
567 ####### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ##########", task->GetName(), task->ClassName());
569 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
572 TH1::AddDirectory(dirStatus);
573 if (curdir) curdir->cd();
575 fInitTime += fInitTimer->RealTime();
576 fInitTimer->Continue();
577 printf("Initialization time: %g [sec]\n", fInitTime);
578 if (fDebug > 1) printf("<-AliAnalysisManager::SlaveBegin()\n");
581 //______________________________________________________________________________
582 Bool_t AliAnalysisManager::Notify()
584 // The Notify() function is called when a new file is opened. This
585 // can be either for a new TTree in a TChain or when when a new TTree
586 // is started when using PROOF. It is normaly not necessary to make changes
587 // to the generated code, but the routine can be extended by the
588 // user if needed. The return value is currently not used.
589 fIOTimer->Start(kTRUE);
590 if (!fTree) return kFALSE;
591 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) return kFALSE;
593 fTable.Clear("nodelete"); // clearing the hash table may not be needed -> C.L.
594 if (fMode == kProofAnalysis) fIsRemote = kTRUE;
596 TFile *curfile = fTree->GetCurrentFile();
598 Error("Notify","No current file");
601 if (IsCollectThroughput()) {
602 if (fCurrentDescriptor) fCurrentDescriptor->Done();
603 fCurrentDescriptor = new AliAnalysisFileDescriptor(curfile);
604 fFileDescriptors->Add(fCurrentDescriptor);
607 if (fDebug > 1) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
608 Int_t run = AliAnalysisManager::GetRunFromAlienPath(curfile->GetName());
609 if (run && (run != fRunFromPath)) {
611 if (fDebug > 1) printf(" ### run found from path: %d\n", run);
614 AliAnalysisTask *task;
616 // Call Notify of the event handlers
617 if (fInputEventHandler) {
618 fInputEventHandler->Notify(curfile->GetName());
621 if (fOutputEventHandler) {
622 fOutputEventHandler->Notify(curfile->GetName());
625 if (fMCtruthEventHandler) {
626 fMCtruthEventHandler->Notify(curfile->GetName());
629 // Call Notify for all tasks
630 while ((task=(AliAnalysisTask*)next()))
633 if (fDebug > 1) printf("<-AliAnalysisManager::Notify()\n");
635 fIOTime += fIOTimer->RealTime();
639 //______________________________________________________________________________
640 Bool_t AliAnalysisManager::Process(Long64_t)
642 // The Process() function is called for each entry in the tree (or possibly
643 // keyed object in the case of PROOF) to be processed. The entry argument
644 // specifies which entry in the currently loaded tree is to be processed.
645 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
646 // to read either all or the required parts of the data. When processing
647 // keyed objects with PROOF, the object is already loaded and is available
648 // via the fObject pointer.
650 // This function should contain the "body" of the analysis. It can contain
651 // simple or elaborate selection criteria, run algorithms on the data
652 // of the event and typically fill histograms.
654 // WARNING when a selector is used with a TChain, you must use
655 // the pointer to the current TTree to call GetEntry(entry).
656 // The entry is always the local entry number in the current tree.
657 // Assuming that fChain is the pointer to the TChain being processed,
658 // use fChain->GetTree()->GetEntry(entry).
660 // This method is obsolete. ExecAnalysis is called instead.
664 //______________________________________________________________________________
665 void AliAnalysisManager::PackOutput(TList *target)
667 // Pack all output data containers in the output list. Called at SlaveTerminate
668 // stage in PROOF case for each slave.
669 if (fDebug > 1) printf("->AliAnalysisManager::PackOutput()\n");
670 fIOTimer->Start(kTRUE);
672 if (IsCollectThroughput()) {
673 if (fCurrentDescriptor) fCurrentDescriptor->Done();
674 fFileDescriptors->Print();
675 if (fFileInfoLog.IsNull()) fFileInfoLog = "fileinfo.log";
676 out.open(fFileInfoLog, std::ios::app);
677 if (out.bad()) Error("SavePrimitive", "Bad file name: %s", fFileInfoLog.Data());
679 TIter nextflog(fFileDescriptors);
681 while ((log=nextflog())) log->SavePrimitive(out,"");
685 Error("PackOutput", "No target. Exiting.");
688 TDirectory *cdir = gDirectory;
690 if (fInputEventHandler) fInputEventHandler ->Terminate();
691 if (fOutputEventHandler) fOutputEventHandler ->Terminate();
692 if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
695 // Call FinishTaskOutput() for each event loop task (not called for
696 // post-event loop tasks - use Terminate() fo those)
697 TIter nexttask(fTasks);
698 AliAnalysisTask *task;
699 while ((task=(AliAnalysisTask*)nexttask())) {
700 if (!task->IsPostEventLoop()) {
701 if (fDebug > 1) printf("->FinishTaskOutput: task %s\n", task->GetName());
702 task->FinishTaskOutput();
704 if (fDebug > 1) printf("<-FinishTaskOutput: task %s\n", task->GetName());
707 // Write statistics message on the workers.
708 if (fStatistics) WriteStatisticsMsg(fNcalls);
710 if (fMode == kProofAnalysis) {
711 TIter next(fOutputs);
712 AliAnalysisDataContainer *output;
713 Bool_t isManagedByHandler = kFALSE;
716 while ((output=(AliAnalysisDataContainer*)next())) {
717 // Do not consider outputs of post event loop tasks
718 isManagedByHandler = kFALSE;
719 if (output->GetProducer() && output->GetProducer()->IsPostEventLoop()) continue;
720 const char *filename = output->GetFileName();
721 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
722 isManagedByHandler = kTRUE;
723 printf("#### Handler output. Extra: %s\n", fExtraFiles.Data());
724 filename = fOutputEventHandler->GetOutputFileName();
726 // Check if data was posted to this container. If not, issue an error.
727 if (!output->GetData() && !isManagedByHandler) {
728 Error("PackOutput", "No data for output container %s. Forgot to PostData ?", output->GetName());
731 if (!output->IsSpecialOutput()) {
733 if (strlen(filename) && !isManagedByHandler) {
734 // Backup current folder
735 TDirectory *opwd = gDirectory;
736 // File resident outputs.
737 // Check first if the file exists.
738 TString openoption = "RECREATE";
739 Bool_t firsttime = kTRUE;
740 if (filestmp.FindObject(output->GetFileName())) {
743 filestmp.Add(new TNamed(output->GetFileName(),""));
745 if (!gSystem->AccessPathName(output->GetFileName()) && !firsttime) openoption = "UPDATE";
746 // TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
747 // Save data to file, then close.
748 if (output->GetData()->InheritsFrom(TCollection::Class())) {
749 // If data is a collection, we set the name of the collection
750 // as the one of the container and we save as a single key.
751 TCollection *coll = (TCollection*)output->GetData();
752 coll->SetName(output->GetName());
753 // coll->Write(output->GetName(), TObject::kSingleKey);
755 if (output->GetData()->InheritsFrom(TTree::Class())) {
756 TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
757 // Save data to file, then close.
758 TTree *tree = (TTree*)output->GetData();
759 // Check if tree is in memory
760 if (tree->GetDirectory()==gROOT) tree->SetDirectory(gDirectory);
764 // output->GetData()->Write();
767 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
769 // printf(" file %s listing content:\n", filename);
772 // Clear file list to release object ownership to user.
775 output->SetFile(NULL);
776 // Restore current directory
777 if (opwd) opwd->cd();
779 // Memory-resident outputs
780 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
782 AliAnalysisDataWrapper *wrap = 0;
783 if (isManagedByHandler) {
784 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
785 wrap->SetName(output->GetName());
787 else wrap =output->ExportData();
788 // Output wrappers must NOT delete data after merging - the user owns them
789 wrap->SetDeleteData(kFALSE);
792 // Special outputs. The file must be opened and connected to the container.
793 TDirectory *opwd = gDirectory;
794 TFile *file = output->GetFile();
796 AliAnalysisTask *producer = output->GetProducer();
798 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
799 output->GetFileName(), output->GetName(), producer->ClassName());
802 TString outFilename = file->GetName();
803 if (fDebug > 1) printf("PackOutput %s: special output\n", output->GetName());
804 if (isManagedByHandler) {
805 // Terminate IO for files managed by the output handler
806 // file->Write() moved to AOD handler (A.G. 11.01.10)
807 // if (file) file->Write();
808 if (file && fDebug > 2) {
809 printf(" handled file %s listing content:\n", file->GetName());
812 fOutputEventHandler->TerminateIO();
815 // Release object ownership to users after writing data to file
816 if (output->GetData()->InheritsFrom(TCollection::Class())) {
817 // If data is a collection, we set the name of the collection
818 // as the one of the container and we save as a single key.
819 TCollection *coll = (TCollection*)output->GetData();
820 coll->SetName(output->GetName());
821 coll->Write(output->GetName(), TObject::kSingleKey);
823 if (output->GetData()->InheritsFrom(TTree::Class())) {
824 TTree *tree = (TTree*)output->GetData();
825 tree->SetDirectory(file);
828 output->GetData()->Write();
832 printf(" file %s listing content:\n", output->GetFileName());
835 // Clear file list to release object ownership to user.
838 output->SetFile(NULL);
840 // Restore current directory
841 if (opwd) opwd->cd();
842 // Check if a special output location was provided or the output files have to be merged
843 if (strlen(fSpecialOutputLocation.Data())) {
844 TString remote = fSpecialOutputLocation;
846 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
847 if (remote.BeginsWith("alien:")) {
848 gROOT->ProcessLine("TGrid::Connect(\"alien:\", gProofServ->GetUser());");
849 remote += outFilename;
850 remote.ReplaceAll(".root", Form("_%d.root", gid));
852 remote += Form("%s_%d_", gSystem->HostName(), gid);
853 remote += outFilename;
856 Info("PackOutput", "Output file for container %s to be copied \n at: %s. No merging.",
857 output->GetName(), remote.Data());
858 TFile::Cp ( outFilename.Data(), remote.Data() );
859 // Copy extra outputs
860 if (fExtraFiles.Length() && isManagedByHandler) {
861 TObjArray *arr = fExtraFiles.Tokenize(" ");
863 TIter nextfilename(arr);
864 while ((os=(TObjString*)nextfilename())) {
865 outFilename = os->GetString();
866 remote = fSpecialOutputLocation;
868 if (remote.BeginsWith("alien://")) {
869 remote += outFilename;
870 remote.ReplaceAll(".root", Form("_%d.root", gid));
872 remote += Form("%s_%d_", gSystem->HostName(), gid);
873 remote += outFilename;
876 Info("PackOutput", "Extra AOD file %s to be copied \n at: %s. No merging.",
877 outFilename.Data(), remote.Data());
878 TFile::Cp ( outFilename.Data(), remote.Data() );
883 // No special location specified-> use TProofOutputFile as merging utility
884 // The file at this output slot must be opened in CreateOutputObjects
885 if (fDebug > 1) printf(" File for container %s to be merged via file merger...\n", output->GetName());
890 fIOTime += fIOTimer->RealTime();
891 if ((fDebug || IsCollectThroughput())) {
893 fInitTime = fInitTimer->RealTime()-fIOTime-fCPUTime;
894 printf("=Analysis %s= init time: %g[sec]\
895 \n I/O & data mng.: %g [sec]\
896 \n task execution: %g [sec]\
897 \n total time: CPU=%g [sec] REAL=%g[sec]\n",
898 GetName(), fInitTime, fIOTime, fCPUTime, fInitTimer->CpuTime(), fInitTimer->RealTime());
899 if (IsCollectThroughput()) {
900 out << "#summary#########################################################" << endl;
901 out << "train_name " << GetName() << endl;
902 out << "root_time " << fInitTimer->RealTime() << endl;
903 out << "root_cpu " << fInitTimer->CpuTime() << endl;
904 out << "init_time " << fInitTime << endl;
905 out << "io_mng_time " << fIOTime << endl;
906 out << "exec_time " << fCPUTime << endl;
907 TString aliensite = gSystem->Getenv("ALIEN_SITE");
908 out << "alien_site " << aliensite << endl;
910 TString hostname = gSystem->Getenv("ALIEN_HOSTNAME");
911 if (hostname.IsNull()) {
913 gSystem->Exec(Form("hostname -f >> %s", fFileInfoLog.Data()));
915 out << hostname << endl;
920 if (cdir) cdir->cd();
921 if (fDebug > 1) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
924 //______________________________________________________________________________
925 void AliAnalysisManager::ImportWrappers(TList *source)
927 // Import data in output containers from wrappers coming in source.
928 if (fDebug > 1) printf("->AliAnalysisManager::ImportWrappers()\n");
929 fIOTimer->Start(kTRUE);
930 TIter next(fOutputs);
931 AliAnalysisDataContainer *cont;
932 AliAnalysisDataWrapper *wrap;
934 Bool_t inGrid = (fMode == kGridAnalysis)?kTRUE:kFALSE;
935 TDirectory *cdir = gDirectory;
936 while ((cont=(AliAnalysisDataContainer*)next())) {
938 if (cont->GetProducer() && cont->GetProducer()->IsPostEventLoop() && !inGrid) continue;
939 if (cont->IsRegisterDataset()) continue;
940 const char *filename = cont->GetFileName();
941 Bool_t isManagedByHandler = kFALSE;
942 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
943 isManagedByHandler = kTRUE;
944 filename = fOutputEventHandler->GetOutputFileName();
946 if (cont->IsSpecialOutput() || inGrid) {
947 if (strlen(fSpecialOutputLocation.Data())) continue;
948 // Copy merged file from PROOF scratch space.
949 // In case of grid the files are already in the current directory.
951 if (isManagedByHandler && fExtraFiles.Length()) {
952 // Copy extra registered dAOD files.
953 TObjArray *arr = fExtraFiles.Tokenize(" ");
955 TIter nextfilename(arr);
956 while ((os=(TObjString*)nextfilename())) GetFileFromWrapper(os->GetString(), source);
959 if (!GetFileFromWrapper(filename, source)) continue;
961 // Normally we should connect data from the copied file to the
962 // corresponding output container, but it is not obvious how to do this
963 // automatically if several objects in file...
964 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
965 if (!f) f = TFile::Open(filename, "READ");
967 Error("ImportWrappers", "Cannot open file %s in read-only mode", filename);
972 // Cd to the directory pointed by the container
973 TString folder = cont->GetFolderName();
974 if (!folder.IsNull()) f->cd(folder);
975 // Try to fetch first an object having the container name.
976 obj = gDirectory->Get(cont->GetName());
978 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",
979 cont->GetType()->GetName(), cont->GetName(), filename, cont->GetFolderName(), cont->GetName());
982 wrap = new AliAnalysisDataWrapper(obj);
983 wrap->SetDeleteData(kFALSE);
985 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
987 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
992 printf(" Importing data for container %s\n", cont->GetName());
993 if (strlen(filename)) printf(" -> file %s\n", filename);
996 cont->ImportData(wrap);
998 if (cdir) cdir->cd();
1000 fIOTime += fIOTimer->RealTime();
1001 if (fDebug > 1) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
1004 //______________________________________________________________________________
1005 void AliAnalysisManager::UnpackOutput(TList *source)
1007 // Called by AliAnalysisSelector::Terminate only on the client.
1008 fIOTimer->Start(kTRUE);
1009 if (fDebug > 1) printf("->AliAnalysisManager::UnpackOutput()\n");
1011 Error("UnpackOutput", "No target. Exiting.");
1014 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
1016 if (fMode == kProofAnalysis) ImportWrappers(source);
1018 TIter next(fOutputs);
1019 AliAnalysisDataContainer *output;
1020 while ((output=(AliAnalysisDataContainer*)next())) {
1021 if (!output->GetData()) continue;
1022 // Check if there are client tasks that run post event loop
1023 if (output->HasConsumers()) {
1024 // Disable event loop semaphore
1025 output->SetPostEventLoop(kTRUE);
1026 TObjArray *list = output->GetConsumers();
1027 Int_t ncons = list->GetEntriesFast();
1028 for (Int_t i=0; i<ncons; i++) {
1029 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
1030 task->CheckNotify(kTRUE);
1031 // If task is active, execute it
1032 if (task->IsPostEventLoop() && task->IsActive()) {
1033 if (fDebug > 1) printf("== Executing post event loop task %s\n", task->GetName());
1034 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
1035 task->ExecuteTask();
1038 if (fStatistics) fStatistics->StopTimer();
1042 fIOTime += fIOTimer->RealTime();
1043 if (fDebug > 1) printf("<-AliAnalysisManager::UnpackOutput()\n");
1046 //______________________________________________________________________________
1047 void AliAnalysisManager::Terminate()
1049 // The Terminate() function is the last function to be called during
1050 // a query. It always runs on the client, it can be used to present
1051 // the results graphically.
1052 if (fDebug > 1) printf("->AliAnalysisManager::Terminate()\n");
1053 fInitTimer->Start(kTRUE);
1054 TDirectory *cdir = gDirectory;
1056 AliAnalysisTask *task;
1057 AliAnalysisDataContainer *output;
1060 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1061 if (getsysInfo) AliSysInfo::SetVerbose(kTRUE);
1062 // Call Terminate() for tasks
1064 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
1065 // Save all the canvases produced by the Terminate
1066 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
1070 AliSysInfo::AddStamp(Form("%s_TERMINATE",task->ClassName()),0, itask, 2);
1072 if (TObject::TestBit(kSaveCanvases)) {
1073 if (!gROOT->IsBatch()) {
1074 if (fDebug>1) printf("Waiting 5 sec for %s::Terminate() to finish drawing ...\n", task->ClassName());
1076 while (timer.RealTime()<5) {
1078 gSystem->ProcessEvents();
1081 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
1082 if (iend==0) continue;
1084 for (Int_t ipict=0; ipict<iend; ipict++) {
1085 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
1086 if (!canvas) continue;
1087 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
1089 gROOT->GetListOfCanvases()->Delete();
1093 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
1094 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
1095 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
1097 TObjArray *allOutputs = new TObjArray();
1099 for (icont=0; icont<fOutputs->GetEntriesFast(); icont++) allOutputs->Add(fOutputs->At(icont));
1100 if (!IsSkipTerminate())
1101 for (icont=0; icont<fParamCont->GetEntriesFast(); icont++) allOutputs->Add(fParamCont->At(icont));
1102 TIter next1(allOutputs);
1103 TString handlerFile = "";
1104 TString extraOutputs = "";
1105 if (fOutputEventHandler) {
1106 handlerFile = fOutputEventHandler->GetOutputFileName();
1107 extraOutputs = fOutputEventHandler->GetExtraOutputs();
1111 while ((output=(AliAnalysisDataContainer*)next1())) {
1112 // Special outputs or grid files have the files already closed and written.
1114 if (fMode == kGridAnalysis && icont<=fOutputs->GetEntriesFast()) continue;
1115 if (fMode == kProofAnalysis) {
1116 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
1118 const char *filename = output->GetFileName();
1119 TString openoption = "RECREATE";
1120 if (!(strcmp(filename, "default"))) continue;
1121 if (!strlen(filename)) continue;
1122 if (!output->GetData()) continue;
1123 TDirectory *opwd = gDirectory;
1124 TFile *file = output->GetFile();
1125 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1127 //if (handlerFile == filename && !gSystem->AccessPathName(filename)) openoption = "UPDATE";
1128 Bool_t firsttime = kTRUE;
1129 if (filestmp.FindObject(filename) || extraOutputs.Contains(filename)) {
1132 filestmp.Add(new TNamed(filename,""));
1134 if (!gSystem->AccessPathName(filename) && !firsttime) openoption = "UPDATE";
1135 if (fDebug>1) printf("Opening file: %s option=%s\n",filename, openoption.Data());
1136 file = new TFile(filename, openoption);
1138 if (fDebug>1) printf("File <%s> already opened with option: <%s> \n", filename, file->GetOption());
1139 openoption = file->GetOption();
1140 if (openoption == "READ") {
1141 if (fDebug>1) printf("...reopening in UPDATE mode\n");
1142 file->ReOpen("UPDATE");
1145 if (file->IsZombie()) {
1146 Error("Terminate", "Cannot open output file %s", filename);
1149 output->SetFile(file);
1151 // Check for a folder request
1152 TString dir = output->GetFolderName();
1153 if (!dir.IsNull()) {
1154 if (!file->GetDirectory(dir)) file->mkdir(dir);
1157 if (fDebug > 1) printf("...writing container %s to file %s:%s\n", output->GetName(), file->GetName(), output->GetFolderName());
1158 if (output->GetData()->InheritsFrom(TCollection::Class())) {
1159 // If data is a collection, we set the name of the collection
1160 // as the one of the container and we save as a single key.
1161 TCollection *coll = (TCollection*)output->GetData();
1162 coll->SetName(output->GetName());
1163 coll->Write(output->GetName(), TObject::kSingleKey);
1165 if (output->GetData()->InheritsFrom(TTree::Class())) {
1166 TTree *tree = (TTree*)output->GetData();
1167 tree->SetDirectory(gDirectory);
1170 output->GetData()->Write();
1173 if (opwd) opwd->cd();
1177 TString copiedFiles;
1178 while ((output=(AliAnalysisDataContainer*)next1())) {
1179 // Close all files at output
1180 TDirectory *opwd = gDirectory;
1181 if (output->GetFile()) {
1182 // Clear file list to release object ownership to user.
1183 // output->GetFile()->Clear();
1184 output->GetFile()->Close();
1185 // Copy merged outputs in alien if requested
1186 if (fSpecialOutputLocation.BeginsWith("alien://")) {
1187 if (copiedFiles.Contains(output->GetFile()->GetName())) {
1188 if (opwd) opwd->cd();
1189 output->SetFile(NULL);
1192 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
1193 gROOT->ProcessLine("if (!gGrid) TGrid::Connect(\"alien:\");");
1194 TFile::Cp(output->GetFile()->GetName(),
1195 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
1196 copiedFiles += output->GetFile()->GetName();
1198 output->SetFile(NULL);
1200 if (opwd) opwd->cd();
1203 //Write statistics information on the client
1204 if (fStatistics) WriteStatisticsMsg(fNcalls);
1206 TDirectory *crtdir = gDirectory;
1207 TFile f("syswatch.root", "RECREATE");
1210 if (!f.IsZombie()) {
1211 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
1212 tree->SetName("syswatch");
1213 tree->SetMarkerStyle(kCircle);
1214 tree->SetMarkerColor(kBlue);
1215 tree->SetMarkerSize(0.5);
1216 if (!gROOT->IsBatch()) {
1217 tree->SetAlias("event", "id0");
1218 tree->SetAlias("task", "id1");
1219 tree->SetAlias("stage", "id2");
1220 // Already defined aliases
1221 // tree->SetAlias("deltaT","stampSec-stampOldSec");
1222 // tree->SetAlias("T","stampSec-first");
1223 // tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)");
1224 // tree->SetAlias("VM","pI.fMemVirtual");
1225 TCanvas *canvas = new TCanvas("SysInfo","SysInfo",10,10,1200,800);
1226 Int_t npads = 1 /*COO plot for all tasks*/ +
1227 fTopTasks->GetEntries() /*Exec plot per task*/ +
1228 1 /*Terminate plot for all tasks*/ +
1231 Int_t iopt = (Int_t)TMath::Sqrt((Double_t)npads);
1232 if (npads<iopt*(iopt+1))
1233 canvas->Divide(iopt, iopt+1, 0.01, 0.01);
1235 canvas->Divide(iopt+1, iopt+1, 0.01, 0.01);
1237 // draw the plot of deltaVM for Exec for each task
1238 for (itask=0; itask<fTopTasks->GetEntriesFast(); itask++) {
1239 task = (AliAnalysisTask*)fTopTasks->At(itask);
1241 cut = Form("task==%d && stage==1", itask);
1242 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1243 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1245 hist->SetTitle(Form("%s: Exec dVM[MB]/event", task->GetName()));
1246 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1249 // Draw the plot of deltaVM for CreateOutputObjects for all tasks
1251 tree->SetMarkerStyle(kFullTriangleUp);
1252 tree->SetMarkerColor(kRed);
1253 tree->SetMarkerSize(0.8);
1254 cut = "task>=0 && task<1000 && stage==0";
1255 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1256 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1258 hist->SetTitle("Memory in CreateOutputObjects()");
1259 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1260 hist->GetXaxis()->SetTitle("task");
1262 // draw the plot of deltaVM for Terminate for all tasks
1264 tree->SetMarkerStyle(kOpenSquare);
1265 tree->SetMarkerColor(kMagenta);
1266 cut = "task>=0 && task<1000 && stage==2";
1267 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1268 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1270 hist->SetTitle("Memory in Terminate()");
1271 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1272 hist->GetXaxis()->SetTitle("task");
1276 tree->SetMarkerStyle(kFullCircle);
1277 tree->SetMarkerColor(kGreen);
1278 cut = Form("task==%d && stage==1",fTopTasks->GetEntriesFast()-1);
1279 tree->Draw("VM:event",cut,"", 1234567890, 0);
1280 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1282 hist->SetTitle("Virtual memory");
1283 hist->GetYaxis()->SetTitle("VM [MB]");
1287 tree->SetMarkerStyle(kCircle);
1288 tree->SetMarkerColor(kBlue);
1289 tree->SetMarkerSize(0.5);
1294 if (crtdir) crtdir->cd();
1296 // Validate the output files
1297 if (ValidateOutputFiles() && fIsRemote && fMode!=kProofAnalysis) {
1299 out.open("outputs_valid", ios::out);
1302 if (cdir) cdir->cd();
1304 if (fDebug || IsCollectThroughput()) {
1305 printf("=Analysis %s= Terminate time: %g[sec]\n", GetName(), fInitTimer->RealTime());
1307 if (fDebug > 1) printf("<-AliAnalysisManager::Terminate()\n");
1309 //______________________________________________________________________________
1310 void AliAnalysisManager::ProfileTask(Int_t itop, const char *option) const
1312 // Profiles the task having the itop index in the list of top (first level) tasks.
1313 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->At(itop);
1315 Error("ProfileTask", "There are only %d top tasks in the manager", fTopTasks->GetEntries());
1318 ProfileTask(task->GetName(), option);
1321 //______________________________________________________________________________
1322 void AliAnalysisManager::ProfileTask(const char *name, const char */*option*/) const
1324 // Profile a managed task after the execution of the analysis in case NSysInfo
1326 if (gSystem->AccessPathName("syswatch.root")) {
1327 Error("ProfileTask", "No file syswatch.root found in the current directory");
1330 if (gROOT->IsBatch()) return;
1331 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->FindObject(name);
1333 Error("ProfileTask", "No top task named %s known by the manager.", name);
1336 Int_t itop = fTopTasks->IndexOf(task);
1337 Int_t itask = fTasks->IndexOf(task);
1338 // Create canvas with 2 pads: first draw COO + Terminate, second Exec
1339 TDirectory *cdir = gDirectory;
1340 TFile f("syswatch.root");
1341 TTree *tree = (TTree*)f.Get("syswatch");
1343 Error("ProfileTask", "No tree named <syswatch> found in file syswatch.root");
1346 if (fDebug > 1) printf("=== Profiling task %s (class %s)\n", name, task->ClassName());
1347 TCanvas *canvas = new TCanvas(Form("profile_%d",itop),Form("Profile of task %s (class %s)",name,task->ClassName()),10,10,800,600);
1348 canvas->Divide(2, 2, 0.01, 0.01);
1352 // VM profile for COO and Terminate methods
1354 cut = Form("task==%d && (stage==0 || stage==2)",itask);
1355 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1356 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1358 hist->SetTitle("Alocated VM[MB] for COO and Terminate");
1359 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1360 hist->GetXaxis()->SetTitle("method");
1362 // CPU profile per event
1364 cut = Form("task==%d && stage==1",itop);
1365 tree->Draw("deltaT:event",cut,"", 1234567890, 0);
1366 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1368 hist->SetTitle("Execution time per event");
1369 hist->GetYaxis()->SetTitle("CPU/event [s]");
1371 // VM profile for Exec
1373 cut = Form("task==%d && stage==1",itop);
1374 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1375 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1377 hist->SetTitle("Alocated VM[MB] per event");
1378 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1383 if (cdir) cdir->cd();
1386 //______________________________________________________________________________
1387 void AliAnalysisManager::AddTask(AliAnalysisTask *task)
1389 // Adds a user task to the global list of tasks.
1391 Error("AddTask", "Cannot add task %s since InitAnalysis was already called", task->GetName());
1395 if (fTasks->FindObject(task)) {
1396 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
1399 task->SetActive(kFALSE);
1403 //______________________________________________________________________________
1404 AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
1406 // Retreive task by name.
1407 if (!fTasks) return NULL;
1408 return (AliAnalysisTask*)fTasks->FindObject(name);
1411 //______________________________________________________________________________
1412 Int_t AliAnalysisManager::GetTaskIndex(const AliAnalysisTask *task) const
1414 // Returns task inded in the manager's list, -1 if not registered.
1415 if (!fTasks) return -1;
1416 return fTasks->IndexOf(task);
1419 //______________________________________________________________________________
1420 AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
1421 TClass *datatype, EAliAnalysisContType type, const char *filename)
1423 // Create a data container of a certain type. Types can be:
1424 // kExchangeContainer = 0, used to exchange data between tasks
1425 // kInputContainer = 1, used to store input data
1426 // kOutputContainer = 2, used for writing result to a file
1427 // filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
1428 // the output object to a folder inside the output file
1429 if (fContainers->FindObject(name)) {
1430 Error("CreateContainer","A container named %s already defined !",name);
1433 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
1434 fContainers->Add(cont);
1436 case kInputContainer:
1439 case kOutputContainer:
1440 fOutputs->Add(cont);
1441 if (filename && strlen(filename)) {
1442 cont->SetFileName(filename);
1443 cont->SetDataOwned(kFALSE); // data owned by the file
1446 case kParamContainer:
1447 fParamCont->Add(cont);
1448 if (filename && strlen(filename)) {
1449 cont->SetFileName(filename);
1450 cont->SetDataOwned(kFALSE); // data owned by the file
1453 case kExchangeContainer:
1454 cont->SetExchange(kTRUE);
1455 fExchangeCont->Add(cont);
1456 cont->SetDataOwned(kFALSE); // data owned by the publisher
1462 //______________________________________________________________________________
1463 Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
1464 AliAnalysisDataContainer *cont)
1466 // Connect input of an existing task to a data container.
1468 Error("ConnectInput", "Task pointer is NULL");
1471 if (!fTasks->FindObject(task)) {
1473 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
1475 Bool_t connected = task->ConnectInput(islot, cont);
1479 //______________________________________________________________________________
1480 Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
1481 AliAnalysisDataContainer *cont)
1483 // Connect output of an existing task to a data container.
1485 Error("ConnectOutput", "Task pointer is NULL");
1488 if (!fTasks->FindObject(task)) {
1490 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
1492 Bool_t connected = task->ConnectOutput(islot, cont);
1496 //______________________________________________________________________________
1497 void AliAnalysisManager::CleanContainers()
1499 // Clean data from all containers that have already finished all client tasks.
1500 TIter next(fContainers);
1501 AliAnalysisDataContainer *cont;
1502 while ((cont=(AliAnalysisDataContainer *)next())) {
1503 if (cont->IsOwnedData() &&
1504 cont->IsDataReady() &&
1505 cont->ClientsExecuted()) cont->DeleteData();
1509 //______________________________________________________________________________
1510 Bool_t AliAnalysisManager::InitAnalysis()
1512 // Initialization of analysis chain of tasks. Should be called after all tasks
1513 // and data containers are properly connected
1514 // Reset flag and remove valid_outputs file if exists
1515 if (fInitOK) return kTRUE;
1516 if (!gSystem->AccessPathName("outputs_valid"))
1517 gSystem->Unlink("outputs_valid");
1518 // Check for top tasks (depending only on input data containers)
1519 if (!fTasks->First()) {
1520 Error("InitAnalysis", "Analysis has no tasks !");
1524 AliAnalysisTask *task;
1525 AliAnalysisDataContainer *cont;
1528 Bool_t iszombie = kFALSE;
1529 Bool_t istop = kTRUE;
1531 while ((task=(AliAnalysisTask*)next())) {
1534 Int_t ninputs = task->GetNinputs();
1535 for (i=0; i<ninputs; i++) {
1536 cont = task->GetInputSlot(i)->GetContainer();
1540 fZombies->Add(task);
1544 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
1545 i, task->GetName());
1547 if (iszombie) continue;
1548 // Check if cont is an input container
1549 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
1550 // Connect to parent task
1554 fTopTasks->Add(task);
1558 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
1561 // Check now if there are orphan tasks
1562 for (i=0; i<ntop; i++) {
1563 task = (AliAnalysisTask*)fTopTasks->At(i);
1568 while ((task=(AliAnalysisTask*)next())) {
1569 if (!task->IsUsed()) {
1571 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
1574 // Check the task hierarchy (no parent task should depend on data provided
1575 // by a daughter task)
1576 for (i=0; i<ntop; i++) {
1577 task = (AliAnalysisTask*)fTopTasks->At(i);
1578 if (task->CheckCircularDeps()) {
1579 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
1584 // Check that all containers feeding post-event loop tasks are in the outputs list
1585 TIter nextcont(fContainers); // loop over all containers
1586 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1587 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1588 if (cont->HasConsumers()) {
1589 // Check if one of the consumers is post event loop
1590 TIter nextconsumer(cont->GetConsumers());
1591 while ((task=(AliAnalysisTask*)nextconsumer())) {
1592 if (task->IsPostEventLoop()) {
1593 fOutputs->Add(cont);
1600 // Check if all special output containers have a file name provided
1601 TIter nextout(fOutputs);
1602 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1603 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1604 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1608 // Initialize requested branch list if needed
1609 if (!fAutoBranchHandling) {
1611 while ((task=(AliAnalysisTask*)next())) {
1612 if (!task->HasBranches()) {
1613 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\"",
1614 task->GetName(), task->ClassName());
1617 if (!fInputEventHandler || !strlen(fInputEventHandler->GetDataType())) {
1618 Error("InitAnalysis", "Manual branch loading requested but no input handler defined or handler does not define data type.");
1621 TString taskbranches;
1622 task->GetBranches(fInputEventHandler->GetDataType(), taskbranches);
1623 if (taskbranches.IsNull()) {
1624 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches of type %s:",
1625 task->GetName(), task->ClassName(), fInputEventHandler->GetDataType());
1628 AddBranches(taskbranches);
1635 //______________________________________________________________________________
1636 void AliAnalysisManager::AddBranches(const char *branches)
1638 // Add branches to the existing fRequestedBranches.
1639 TString br(branches);
1640 TObjArray *arr = br.Tokenize(",");
1643 while ((obj=next())) {
1644 if (!fRequestedBranches.Contains(obj->GetName())) {
1645 if (!fRequestedBranches.IsNull()) fRequestedBranches += ",";
1646 fRequestedBranches += obj->GetName();
1652 //______________________________________________________________________________
1653 void AliAnalysisManager::CheckBranches(Bool_t load)
1655 // The method checks the input branches to be loaded during the analysis.
1656 if (fAutoBranchHandling || fRequestedBranches.IsNull() || !fTree) return;
1657 TObjArray *arr = fRequestedBranches.Tokenize(",");
1660 while ((obj=next())) {
1661 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(obj->GetName()));
1663 br = fTree->GetBranch(obj->GetName());
1665 Error("CheckBranches", "Could not find branch %s",obj->GetName());
1670 if (load && br->GetReadEntry()!=GetCurrentEntry()) {
1671 br->GetEntry(GetCurrentEntry());
1677 //______________________________________________________________________________
1678 Bool_t AliAnalysisManager::CheckTasks() const
1680 // Check consistency of tasks.
1681 Int_t ntasks = fTasks->GetEntries();
1683 Error("CheckTasks", "No tasks connected to the manager. This may be due to forgetting to compile the task or to load their library.");
1686 // Get the pointer to AliAnalysisTaskSE::Class()
1687 TClass *badptr = (TClass*)gROOT->ProcessLine("AliAnalysisTaskSE::Class()");
1688 // Loop all tasks to check if their corresponding library was loaded
1691 while ((obj=next())) {
1692 if (obj->IsA() == badptr) {
1693 Error("CheckTasks", "##################\n \
1694 Class for task %s NOT loaded. You probably forgot to load the library for this task (or compile it dynamically).\n###########################\n",obj->GetName());
1701 //______________________________________________________________________________
1702 void AliAnalysisManager::PrintStatus(Option_t *option) const
1704 // Print task hierarchy.
1706 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1709 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1711 AliSysInfo::SetVerbose(kTRUE);
1712 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
1714 AliAnalysisDataContainer *cont = fCommonInput;
1715 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
1716 printf("=== TOP CONTAINER:\n");
1717 cont->PrintContainer(option,0);
1718 // Reset "touched" flag
1719 TIter next(fContainers);
1720 while ((cont = (AliAnalysisDataContainer*)next())) cont->SetTouched(kFALSE);
1721 TIter nextt(fTasks);
1722 AliAnalysisTask *task;
1723 while ((task=(AliAnalysisTask*)nextt()))
1724 task->SetActive(kFALSE);
1726 if (!fAutoBranchHandling && !fRequestedBranches.IsNull())
1727 printf("Requested input branches:\n%s\n", fRequestedBranches.Data());
1729 TString sopt(option);
1732 if (sopt.Contains("ALL"))
1734 if ( fOutputEventHandler )
1736 cout << TString('_',78) << endl;
1737 cout << "OutputEventHandler:" << endl;
1738 fOutputEventHandler->Print(" ");
1743 //______________________________________________________________________________
1744 void AliAnalysisManager::ResetAnalysis()
1746 // Reset all execution flags and clean containers.
1747 TIter nextTask(fTasks);
1748 AliAnalysisTask *task;
1749 while ((task=(AliAnalysisTask*)nextTask())) {
1753 // CleanContainers();
1756 //______________________________________________________________________________
1757 void AliAnalysisManager::RunLocalInit()
1759 // Run LocalInit method for all tasks.
1760 TDirectory *cdir = gDirectory;
1761 if (IsTrainInitialized()) return;
1762 TIter nextTask(fTasks);
1763 AliAnalysisTask *task;
1764 while ((task=(AliAnalysisTask*)nextTask())) {
1768 if (cdir) cdir->cd();
1769 TObject::SetBit(kTasksInitialized, kTRUE);
1772 //______________________________________________________________________________
1773 void AliAnalysisManager::InputFileFromTree(TTree * const tree, TString &fname)
1775 // Retrieves name of the file from tree
1778 TFile *file = tree->GetCurrentFile();
1781 TChain *chain = dynamic_cast<TChain*>(tree);
1782 if (!chain || !chain->GetNtrees()) return;
1783 basename = gSystem->BaseName(chain->GetListOfFiles()->First()->GetTitle());
1785 basename = gSystem->BaseName(file->GetName());
1787 Int_t index = basename.Index("#");
1788 fname = basename(index+1, basename.Length());
1791 //______________________________________________________________________________
1792 Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
1794 // Start analysis having a grid handler.
1795 if (!fGridHandler) {
1796 Error("StartAnalysis", "Cannot start analysis providing just the analysis type without a grid handler.");
1797 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1801 return StartAnalysis(type, tree, nentries, firstentry);
1804 //______________________________________________________________________________
1805 Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
1807 // Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1808 // MIX. Process nentries starting from firstentry
1810 // Backup current directory and make sure gDirectory points to gROOT
1811 TDirectory *cdir = gDirectory;
1814 Error("StartAnalysis","Analysis manager was not initialized !");
1815 if (cdir) cdir->cd();
1818 if (!CheckTasks()) Fatal("StartAnalysis", "Not all needed libraries were loaded");
1820 printf("StartAnalysis %s\n",GetName());
1821 AliLog::SetGlobalLogLevel(AliLog::kInfo);
1823 fMaxEntries = nentries;
1825 TString anaType = type;
1827 fMode = kLocalAnalysis;
1828 if (anaType.Contains("file")) fIsRemote = kTRUE;
1829 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1830 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1831 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1832 if (fInputEventHandler) {
1834 InputFileFromTree(tree, fname);
1835 if (fname.Length()) fInputEventHandler->SetInputFileName(fname);
1838 if (fMode == kGridAnalysis) {
1840 if (!anaType.Contains("terminate")) {
1841 if (!fGridHandler) {
1842 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1843 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1844 if (cdir) cdir->cd();
1847 // Write analysis manager in the analysis file
1848 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1849 // run local task configuration
1851 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1852 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1853 if (cdir) cdir->cd();
1857 // Terminate grid analysis
1858 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1859 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1860 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1861 if (!fGridHandler->MergeOutputs()) {
1862 // Return if outputs could not be merged or if it alien handler
1863 // was configured for offline mode or local testing.
1864 if (cdir) cdir->cd();
1868 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1869 if (cdir) cdir->cd();
1870 ImportWrappers(NULL);
1872 if (cdir) cdir->cd();
1876 SetEventLoop(kFALSE);
1877 // Enable event loop mode if a tree was provided
1878 if (tree || fGridHandler || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
1881 TString ttype = "TTree";
1882 if (tree && tree->IsA() == TChain::Class()) {
1883 chain = (TChain*)tree;
1884 if (!chain || !chain->GetListOfFiles()->First()) {
1885 Error("StartAnalysis", "Cannot process null or empty chain...");
1886 if (cdir) cdir->cd();
1892 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1894 AliSysInfo::SetVerbose(kTRUE);
1895 AliSysInfo::AddStamp("Start", 0);
1897 // Initialize locally all tasks (happens for all modes)
1899 AliAnalysisTask *task;
1903 case kLocalAnalysis:
1904 if (!tree && !fGridHandler) {
1905 TIter nextT(fTasks);
1906 // Call CreateOutputObjects for all tasks
1908 Bool_t dirStatus = TH1::AddDirectoryStatus();
1909 while ((task=(AliAnalysisTask*)nextT())) {
1910 TH1::AddDirectory(kFALSE);
1911 task->CreateOutputObjects();
1912 if (!task->CheckPostData()) {
1913 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
1914 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
1915 ########### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ###########", task->GetName(), task->ClassName());
1917 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
1921 TH1::AddDirectory(dirStatus);
1922 if (IsExternalLoop()) {
1923 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1924 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1931 fSelector = new AliAnalysisSelector(this);
1932 // Check if a plugin handler is used
1934 // Get the chain from the plugin
1935 TString dataType = "esdTree";
1936 if (fInputEventHandler) {
1937 dataType = fInputEventHandler->GetDataType();
1941 chain = fGridHandler->GetChainForTestMode(dataType);
1943 Error("StartAnalysis", "No chain for test mode. Aborting.");
1946 cout << "===== RUNNING LOCAL ANALYSIS" << GetName() << " ON CHAIN " << chain->GetName() << endl;
1947 retv = chain->Process(fSelector, "", nentries, firstentry);
1950 // Run tree-based analysis via AliAnalysisSelector
1951 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
1952 retv = tree->Process(fSelector, "", nentries, firstentry);
1954 case kProofAnalysis:
1956 // Check if the plugin is used
1958 return StartAnalysis(type, fGridHandler->GetProofDataSet(), nentries, firstentry);
1960 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1961 Error("StartAnalysis", "No PROOF!!! Exiting.");
1962 if (cdir) cdir->cd();
1965 line = Form("gProof->AddInput((TObject*)%p);", this);
1966 gROOT->ProcessLine(line);
1969 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
1970 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
1972 Error("StartAnalysis", "No chain!!! Exiting.");
1973 if (cdir) cdir->cd();
1979 if (!anaType.Contains("terminate")) {
1980 if (!fGridHandler) {
1981 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1982 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1983 if (cdir) cdir->cd();
1986 // Write analysis manager in the analysis file
1987 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1988 // Start the analysis via the handler
1989 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1990 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1991 if (cdir) cdir->cd();
1995 // Terminate grid analysis
1996 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1997 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1998 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1999 if (!fGridHandler->MergeOutputs()) {
2000 // Return if outputs could not be merged or if it alien handler
2001 // was configured for offline mode or local testing.
2002 if (cdir) cdir->cd();
2006 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
2007 ImportWrappers(NULL);
2009 if (cdir) cdir->cd();
2011 case kMixingAnalysis:
2012 // Run event mixing analysis
2014 Error("StartAnalysis", "Cannot run event mixing without event pool");
2015 if (cdir) cdir->cd();
2018 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
2019 fSelector = new AliAnalysisSelector(this);
2020 while ((chain=fEventPool->GetNextChain())) {
2022 // Call NotifyBinChange for all tasks
2023 while ((task=(AliAnalysisTask*)next()))
2024 if (!task->IsPostEventLoop()) task->NotifyBinChange();
2025 retv = chain->Process(fSelector);
2027 Error("StartAnalysis", "Mixing analysis failed");
2028 if (cdir) cdir->cd();
2032 PackOutput(fSelector->GetOutputList());
2035 if (cdir) cdir->cd();
2039 //______________________________________________________________________________
2040 Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
2042 // Start analysis for this manager on a given dataset. Analysis task can be:
2043 // LOCAL, PROOF or GRID. Process nentries starting from firstentry.
2045 Error("StartAnalysis","Analysis manager was not initialized !");
2049 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
2050 TString anaType = type;
2052 if (!anaType.Contains("proof")) {
2053 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
2056 fMode = kProofAnalysis;
2058 TString proofProcessOpt;
2059 SetEventLoop(kTRUE);
2060 // Set the dataset flag
2061 TObject::SetBit(kUseDataSet);
2064 // Start proof analysis using the grid handler
2065 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
2066 Error("StartAnalysis", "The grid plugin could not start PROOF analysis");
2069 // Check if the plugin is in test mode
2070 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kTest) {
2071 dataset = "test_collection";
2073 dataset = fGridHandler->GetProofDataSet();
2076 proofProcessOpt = fGridHandler->GetProofProcessOpt();
2079 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
2080 Error("StartAnalysis", "No PROOF!!! Exiting.");
2084 // Initialize locally all tasks
2087 line = Form("gProof->AddInput((TObject*)%p);", this);
2088 gROOT->ProcessLine(line);
2090 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"%s\", %lld, %lld);",
2091 dataset,proofProcessOpt.Data(), nentries, firstentry);
2092 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
2093 retv = (Long_t)gROOT->ProcessLine(line);
2097 //______________________________________________________________________________
2098 TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
2100 // Opens according the option the file specified by cont->GetFileName() and changes
2101 // current directory to cont->GetFolderName(). If the file was already opened, it
2102 // checks if the option UPDATE was preserved. File open via TProofOutputFile can
2103 // be optionally ignored.
2104 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2105 TString filename = cont->GetFileName();
2107 if (filename.IsNull()) {
2108 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
2111 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
2113 f = mgr->OpenProofFile(cont,option);
2115 // Check first if the file is already opened
2116 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2118 // Check if option "UPDATE" was preserved
2119 TString opt(option);
2121 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2122 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2124 f = TFile::Open(filename, option);
2127 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2131 // Check for a folder request
2132 TString dir = cont->GetFolderName();
2133 if (!dir.IsNull()) {
2134 if (!f->GetDirectory(dir)) f->mkdir(dir);
2139 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
2140 cont->SetFile(NULL);
2144 //______________________________________________________________________________
2145 TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option, const char *extaod)
2147 // Opens a special output file used in PROOF.
2149 TString filename = cont->GetFileName();
2150 if (cont == fCommonOutput) {
2151 if (fOutputEventHandler) {
2152 if (strlen(extaod)) filename = extaod;
2153 filename = fOutputEventHandler->GetOutputFileName();
2155 else Fatal("OpenProofFile","No output container. Exiting.");
2158 if (fMode!=kProofAnalysis || !fSelector) {
2159 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
2162 if (fSpecialOutputLocation.Length()) {
2163 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2165 // Check if option "UPDATE" was preserved
2166 TString opt(option);
2168 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2169 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2171 f = new TFile(filename, option);
2173 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2177 // Check for a folder request
2178 TString dir = cont->GetFolderName();
2180 if (!f->GetDirectory(dir)) f->mkdir(dir);
2185 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2186 cont->SetFile(NULL);
2189 // Check if there is already a proof output file in the output list
2190 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
2192 // Get the actual file
2193 line = Form("((TProofOutputFile*)%p)->GetFileName();", pof);
2194 filename = (const char*)gROOT->ProcessLine(line);
2196 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
2198 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2200 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
2203 // Check if option "UPDATE" was preserved
2204 TString opt(option);
2206 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2207 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
2209 if (cont->IsRegisterDataset()) {
2210 TString dsetName = filename;
2211 dsetName.ReplaceAll(".root", cont->GetTitle());
2212 dsetName.ReplaceAll(":","_");
2213 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
2214 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
2216 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
2217 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
2219 if (fDebug > 1) printf("=== %s\n", line.Data());
2220 gROOT->ProcessLine(line);
2221 line = Form("pf->OpenFile(\"%s\");", option);
2222 gROOT->ProcessLine(line);
2225 gROOT->ProcessLine("pf->Print()");
2226 printf(" == proof file name: %s", f->GetName());
2228 // Add to proof output list
2229 line = Form("((TList*)%p)->Add(pf);",fSelector->GetOutputList());
2230 if (fDebug > 1) printf("=== %s\n", line.Data());
2231 gROOT->ProcessLine(line);
2233 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2237 // Check for a folder request
2238 TString dir = cont->GetFolderName();
2239 if (!dir.IsNull()) {
2240 if (!f->GetDirectory(dir)) f->mkdir(dir);
2245 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2246 cont->SetFile(NULL);
2250 //______________________________________________________________________________
2251 void AliAnalysisManager::ExecAnalysis(Option_t *option)
2253 // Execute analysis.
2254 static Long64_t nentries = 0;
2255 static TTree *lastTree = 0;
2256 static TStopwatch *timer = new TStopwatch();
2257 // Only the first call to Process will trigger a true Notify. Other Notify
2258 // coming before is ignored.
2259 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) {
2260 TObject::SetBit(AliAnalysisManager::kTrueNotify);
2263 if (fDebug > 0) printf("MGR: Processing event #%d\n", fNcalls);
2265 if (fTree && (fTree != lastTree)) {
2266 nentries += fTree->GetEntries();
2269 if (!fNcalls) timer->Start();
2270 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", fNcalls, TMath::Min(fMaxEntries,nentries), timer, kFALSE);
2272 fIOTimer->Start(kTRUE);
2274 TDirectory *cdir = gDirectory;
2275 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
2276 if (getsysInfo && ((fNcalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)fNcalls);
2278 Error("ExecAnalysis", "Analysis manager was not initialized !");
2279 if (cdir) cdir->cd();
2283 AliAnalysisTask *task;
2284 // Reset the analysis
2286 // Check if the top tree is active.
2288 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2289 AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
2291 // De-activate all tasks (not needed anymore after ResetAnalysis
2292 // while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
2293 AliAnalysisDataContainer *cont = fCommonInput;
2294 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
2296 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
2297 if (cdir) cdir->cd();
2300 cont->SetData(fTree); // This set activity for all tasks reading only from the top container
2301 Long64_t entry = fTree->GetTree()->GetReadEntry();
2303 // Call BeginEvent() for optional input/output and MC services
2304 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
2305 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
2306 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
2308 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2309 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2311 // Execute the tasks
2312 // TIter next1(cont->GetConsumers());
2314 fIOTime += fIOTimer->RealTime();
2315 fCPUTimer->Start(kTRUE);
2316 TIter next1(fTopTasks);
2318 while ((task=(AliAnalysisTask*)next1())) {
2319 task->SetActive(kTRUE);
2321 cout << " Executing task " << task->GetName() << endl;
2323 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
2324 task->ExecuteTask(option);
2325 if (fStatistics) fStatistics->StopTimer();
2327 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2328 AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
2332 fCPUTime += fCPUTimer->RealTime();
2333 fIOTimer->Start(kTRUE);
2335 // Call FinishEvent() for optional output and MC services
2336 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2337 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2338 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2339 // Gather system information if requested
2340 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2341 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1001, 1);
2342 if (cdir) cdir->cd();
2344 fIOTime += fIOTimer->RealTime();
2347 // The event loop is not controlled by TSelector
2349 // Call BeginEvent() for optional input/output and MC services
2350 fIOTimer->Start(kTRUE);
2351 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
2352 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
2353 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
2355 fIOTime += fIOTimer->RealTime();
2357 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2358 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2359 fCPUTimer->Start(kTRUE);
2360 TIter next2(fTopTasks);
2361 while ((task=(AliAnalysisTask*)next2())) {
2362 task->SetActive(kTRUE);
2364 cout << " Executing task " << task->GetName() << endl;
2366 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
2367 task->ExecuteTask(option);
2368 if (fStatistics) fStatistics->StopTimer();
2372 fCPUTime += fCPUTimer->RealTime();
2374 // Call FinishEvent() for optional output and MC services
2375 fIOTimer->Start(kTRUE);
2376 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2377 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2378 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2379 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2380 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
2381 if (cdir) cdir->cd();
2383 fIOTime += fIOTimer->RealTime();
2386 //______________________________________________________________________________
2387 Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
2389 // Check if the stdout is connected to a pipe (C.Holm)
2390 Bool_t ispipe = kFALSE;
2391 out.seekp(0, std::ios_base::cur);
2394 if (errno == ESPIPE) ispipe = kTRUE;
2399 //______________________________________________________________________________
2400 void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
2402 // Set the input event handler and create a container for it.
2404 fInputEventHandler = handler;
2405 if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
2408 //______________________________________________________________________________
2409 void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
2411 // Set the input event handler and create a container for it.
2413 fOutputEventHandler = handler;
2414 if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
2415 fCommonOutput->SetSpecialOutput();
2418 //______________________________________________________________________________
2419 void AliAnalysisManager::SetDebugLevel(UInt_t level)
2421 // Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
2422 if (TObject::TestBit(kUseProgressBar)) {
2423 Info("SetDebugLevel","Ignored. Disable the progress bar first.");
2429 //______________________________________________________________________________
2430 void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
2432 // Enable a text mode progress bar. Resets debug level to 0.
2433 Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
2434 TObject::SetBit(kUseProgressBar,flag);
2435 fPBUpdateFreq = freq;
2439 //______________________________________________________________________________
2440 void AliAnalysisManager::RegisterExtraFile(const char *fname)
2442 // This method is used externally to register output files which are not
2443 // connected to any output container, so that the manager can properly register,
2444 // retrieve or merge them when running in distributed mode. The file names are
2445 // separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
2446 if (fExtraFiles.Contains(fname)) return;
2447 if (fExtraFiles.Length()) fExtraFiles += " ";
2448 fExtraFiles += fname;
2451 //______________________________________________________________________________
2452 Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
2454 // Copy a file from the location specified ina the wrapper with the same name from the source list.
2458 TObject *pof = source->FindObject(filename);
2459 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
2460 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
2463 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
2464 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
2465 TString clientUrl(chUrl);
2466 TString fullPath_str(fullPath);
2467 if (clientUrl.Contains("localhost")){
2468 TObjArray* array = fullPath_str.Tokenize ( "//" );
2469 TObjString *strobj = ( TObjString *)array->At(1);
2470 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
2471 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
2472 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
2473 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
2474 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
2478 else if (clientUrl.Contains("__lite__")) {
2479 // Special case for ProofLite environement - get file info and copy.
2480 gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
2481 fullPath_str = Form("%s/%s", tmp, fullPath);
2484 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
2485 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
2487 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
2491 //______________________________________________________________________________
2492 void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
2494 // Fill analysis type in the provided string.
2496 case kLocalAnalysis:
2499 case kProofAnalysis:
2505 case kMixingAnalysis:
2510 //______________________________________________________________________________
2511 Bool_t AliAnalysisManager::ValidateOutputFiles() const
2513 // Validate all output files.
2514 TIter next(fOutputs);
2515 AliAnalysisDataContainer *output;
2516 TDirectory *cdir = gDirectory;
2517 TString openedFiles;
2518 while ((output=(AliAnalysisDataContainer*)next())) {
2519 if (output->IsRegisterDataset()) continue;
2520 TString filename = output->GetFileName();
2521 if (filename == "default") {
2522 if (!fOutputEventHandler) continue;
2523 filename = fOutputEventHandler->GetOutputFileName();
2524 // Main AOD may not be there
2525 if (gSystem->AccessPathName(filename)) continue;
2527 // Check if the file is closed
2528 if (openedFiles.Contains(filename)) continue;;
2529 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2531 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
2532 // Clear file list to release object ownership to user.
2536 file = TFile::Open(filename);
2537 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
2538 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
2539 if (cdir) cdir->cd();
2543 openedFiles += filename;
2546 if (cdir) cdir->cd();
2550 //______________________________________________________________________________
2551 void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
2553 // Implements a nice text mode progress bar.
2554 static Long64_t icount = 0;
2555 static TString oname;
2556 static TString nname;
2557 static Long64_t ocurrent = 0;
2558 static Long64_t osize = 0;
2559 static Int_t oseconds = 0;
2560 static TStopwatch *owatch = 0;
2561 static Bool_t oneoftwo = kFALSE;
2562 static Int_t nrefresh = 0;
2563 static Int_t nchecks = 0;
2564 static char lastChar = 0;
2565 const char symbol[4] = {'-','\\','|','/'};
2567 if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
2573 ocurrent = TMath::Abs(current);
2574 osize = TMath::Abs(size);
2575 if (ocurrent > osize) ocurrent=osize;
2580 if ((current % fPBUpdateFreq) != 0) return;
2582 char progress[11] = " ";
2583 Int_t ichar = icount%4;
2588 if (owatch && !last) {
2590 time = owatch->RealTime();
2591 seconds = int(time) % 60;
2592 minutes = (int(time) / 60) % 60;
2593 hours = (int(time) / 60 / 60);
2595 if (oseconds==seconds) {
2599 oneoftwo = !oneoftwo;
2603 if (refresh && oneoftwo) {
2605 if (nchecks <= 0) nchecks = nrefresh+1;
2606 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
2607 oname = Form(" == %d%% ==", pctdone);
2609 Double_t percent = 100.0*ocurrent/osize;
2610 Int_t nchar = Int_t(percent/10);
2611 if (nchar>10) nchar=10;
2613 for (i=0; i<nchar; i++) progress[i] = '=';
2614 progress[nchar] = symbol[ichar];
2615 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2616 progress[10] = '\0';
2619 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2620 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2621 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
2623 Int_t full = Int_t(ocurrent > 0 ?
2624 time * (float(osize)/ocurrent) + .5 :
2626 Int_t remain = Int_t(full - time);
2627 Int_t rsec = remain % 60;
2628 Int_t rmin = (remain / 60) % 60;
2629 Int_t rhour = (remain / 60 / 60);
2630 fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
2631 percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
2633 else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
2634 if (refresh && oneoftwo) oname = nname;
2635 if (owatch) owatch->Continue();
2644 fprintf(stderr, "\n");
2648 //______________________________________________________________________________
2649 void AliAnalysisManager::DoLoadBranch(const char *name)
2651 // Get tree and load branch if needed.
2652 static Long64_t crtEntry = -100;
2654 if (fAutoBranchHandling || !fTree)
2657 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2659 br = fTree->GetBranch(name);
2661 Error("DoLoadBranch", "Could not find branch %s",name);
2666 if (br->GetReadEntry()==fCurrentEntry) return;
2667 Long64_t readbytes = br->GetEntry(GetCurrentEntry());
2669 Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
2670 if (crtEntry != fCurrentEntry) {
2671 CountEvent(1,0,1,0);
2672 crtEntry = fCurrentEntry;
2675 if (crtEntry != fCurrentEntry) {
2676 CountEvent(1,1,0,0);
2677 crtEntry = fCurrentEntry;
2682 //______________________________________________________________________________
2683 void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
2685 // Add the statistics task to the manager.
2687 Info("AddStatisticsTask", "Already added");
2690 TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
2691 gROOT->ProcessLine(line);
2694 //______________________________________________________________________________
2695 void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
2697 // Bookkeep current event;
2698 if (!fStatistics) return;
2699 fStatistics->AddInput(ninput);
2700 fStatistics->AddProcessed(nprocessed);
2701 fStatistics->AddFailed(nfailed);
2702 fStatistics->AddAccepted(naccepted);
2705 //______________________________________________________________________________
2706 void AliAnalysisManager::AddStatisticsMsg(const char *line)
2708 // Add a line in the statistics message. If available, the statistics message is written
2709 // at the end of the SlaveTerminate phase on workers AND at the end of Terminate
2711 if (!strlen(line)) return;
2712 if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
2713 fStatisticsMsg += line;
2716 //______________________________________________________________________________
2717 void AliAnalysisManager::WriteStatisticsMsg(Int_t)
2719 // If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
2720 static Bool_t done = kFALSE;
2723 if (!fStatistics) return;
2725 AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
2726 AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
2727 AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
2728 AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
2729 out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
2730 fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
2731 fStatistics->GetNaccepted()), ios::out);
2732 out << fStatisticsMsg << endl;
2736 //______________________________________________________________________________
2737 const char* AliAnalysisManager::GetOADBPath()
2739 // returns the path of the OADB
2740 // this static function just depends on environment variables
2742 static TString oadbPath;
2744 if (gSystem->Getenv("OADB_PATH"))
2745 oadbPath = gSystem->Getenv("OADB_PATH");
2746 else if (gSystem->Getenv("ALICE_ROOT"))
2747 oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
2749 ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
2754 //______________________________________________________________________________
2755 void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
2757 // Define a custom string variable mapped to a global unique name. The variable
2758 // can be then retrieved by a given analysis macro via GetGlobalStr(key).
2759 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2761 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2764 Bool_t valid = kFALSE;
2765 TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
2767 ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
2770 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
2773 //______________________________________________________________________________
2774 const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
2776 // Static method to retrieve a global variable defined via SetGlobalStr.
2778 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2780 TObject *value = mgr->GetGlobals()->GetValue(key);
2781 if (!value) return 0;
2783 return value->GetName();
2786 //______________________________________________________________________________
2787 void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
2789 // Define a custom integer variable mapped to a global unique name. The variable
2790 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2791 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2793 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2796 Bool_t valid = kFALSE;
2797 Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
2799 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
2802 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
2805 //______________________________________________________________________________
2806 Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
2808 // Static method to retrieve a global variable defined via SetGlobalInt.
2810 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2812 TObject *value = mgr->GetGlobals()->GetValue(key);
2813 if (!value) return 0;
2815 TString s = value->GetName();
2819 //______________________________________________________________________________
2820 void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
2822 // Define a custom double precision variable mapped to a global unique name. The variable
2823 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2824 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2826 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2829 Bool_t valid = kFALSE;
2830 Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
2832 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
2835 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));
2838 //______________________________________________________________________________
2839 Double_t AliAnalysisManager::GetGlobalDbl(const char *key, Bool_t &valid)
2841 // Static method to retrieve a global variable defined via SetGlobalDbl.
2843 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2845 TObject *value = mgr->GetGlobals()->GetValue(key);
2846 if (!value) return 0;
2848 TString s = value->GetName();
2852 //______________________________________________________________________________
2853 void AliAnalysisManager::AddClassDebug(const char *className, Int_t debugLevel)
2855 // Sets Class debug level
2857 if (!fDebugOptions) {
2858 fDebugOptions = new TObjArray();
2859 fDebugOptions->SetOwner(kTRUE);
2862 TNamed *debugOpt = (TNamed*)fDebugOptions->FindObject(className);
2864 AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel,className).Data());
2865 fDebugOptions->Add(new TNamed(className,TString::Format("%d",debugLevel).Data()));
2867 TString oldDebugStr = debugOpt->GetTitle();
2868 Int_t oldDebug = oldDebugStr.Atoi();
2869 if (debugLevel > oldDebug) {
2870 AliWarning(TString::Format("Overwriting debug level to %d class %s, because it is higher then previously set (%d).",debugLevel,className,oldDebug).Data());
2871 debugOpt->SetTitle(TString::Format("%d",debugLevel).Data());
2873 AliWarning(TString::Format("Ignoring debug level to %d class %s, because it is smaller then previously set (%d).",debugLevel,className,oldDebug).Data());
2878 //______________________________________________________________________________
2879 void AliAnalysisManager::ApplyDebugOptions()
2881 // Apply debug options
2883 if (!fDebugOptions) return;
2885 TIter next(fDebugOptions);
2888 while ((debug=dynamic_cast<TNamed*>(next()))) {
2889 debugLevel = debug->GetTitle();
2890 AliInfo(TString::Format("Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()).Data());
2891 AliLog::SetClassDebugLevel(debug->GetName(), debugLevel.Atoi());
2895 //______________________________________________________________________________
2896 Bool_t AliAnalysisManager::IsMacroLoaded(const char * filename)
2898 // Check if a macro was loaded.
2899 return fgMacroNames.Contains(filename);
2902 //______________________________________________________________________________
2903 Int_t AliAnalysisManager::LoadMacro(const char *filename, Int_t *error, Bool_t check)
2905 // Redirection of gROOT->LoadMacro which makes sure the same macro is not loaded
2907 TString macroName = gSystem->BaseName(filename);
2908 // Strip appended +, ++, +g, +O
2909 Int_t index = macroName.Index("+");
2910 if (index>0) macroName.Remove(index);
2911 if (fgMacroNames.Contains(macroName)) {
2912 // Macro with the same name loaded already in this root session, do
2917 Int_t ret = gROOT->LoadMacro(filename,error,check);
2918 // In case of error return the error code
2919 if (ret) return ret;
2920 // Append the macro name to the loaded macros list
2921 fgMacroNames += macroName;
2922 fgMacroNames += " ";
2926 //______________________________________________________________________________
2927 void AliAnalysisManager::Lock()
2929 // Security lock. This is to detect NORMAL user errors and not really to
2930 // protect against intentional hacks.
2931 if (fLocked) return;
2933 if (fInputEventHandler) fInputEventHandler->Lock();
2934 if (fOutputEventHandler) fOutputEventHandler->Lock();
2935 if (fMCtruthEventHandler) fMCtruthEventHandler->Lock();
2936 Info("Lock","====== ANALYSIS MANAGER LOCKED ======");
2939 //______________________________________________________________________________
2940 void AliAnalysisManager::UnLock()
2942 // Verbose unlocking. Hackers will be punished ;-) ...
2943 if (!fLocked) return;
2945 if (fInputEventHandler) fInputEventHandler->UnLock();
2946 if (fOutputEventHandler) fOutputEventHandler->UnLock();
2947 if (fMCtruthEventHandler) fMCtruthEventHandler->UnLock();
2948 Info("UnLock", "====== ANALYSIS MANAGER UNLOCKED ======");
2951 //______________________________________________________________________________
2952 void AliAnalysisManager::Changed()
2954 // All critical setters pass through the Changed method that throws an exception
2955 // in case the lock was set.
2956 if (fLocked) Fatal("Changed","Critical setter called in locked mode");
2959 //______________________________________________________________________________
2960 void AliAnalysisManager::InitInputData(AliVEvent* esdEvent, AliVfriendEvent* esdFriend)
2963 // Method to propagte to all the connected tasks the HLT event.
2964 // This method expects that the input hanlder is of type HLT, should
2965 // not be used otherwise
2967 if (fInputEventHandler) {
2968 TString classInputHandler = fInputEventHandler->ClassName();
2969 if (classInputHandler.Contains("HLT")){
2970 TObjArray* arrTasks = GetTasks();
2971 fInputEventHandler->InitTaskInputData(esdEvent, esdFriend, arrTasks);
2974 Fatal("PropagateHLTEvent", "Input Handler not of type HLT, we cannot use this method!");
2978 Fatal("PropagateHLTEvent", "Input Handler not found, we cannot use this method!");