1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 // Author: Andrei Gheata, 31/05/2006
19 //==============================================================================
20 // AliAnalysisManager - Manager analysis class. Allows creation of several
21 // analysis tasks and data containers storing their input/output. Allows
22 // connecting/chaining tasks via shared data containers. Serializes the current
23 // event for all tasks depending only on initial input data.
24 //==============================================================================
26 //==============================================================================
28 #include "AliAnalysisManager.h"
31 #include <Riostream.h>
36 #include <TTreeCache.h>
40 #include <TMethodCall.h>
45 #include <TStopwatch.h>
48 #include "AliAnalysisSelector.h"
49 #include "AliAnalysisGrid.h"
50 #include "AliAnalysisTask.h"
51 #include "AliAnalysisDataContainer.h"
52 #include "AliAnalysisDataSlot.h"
53 #include "AliVEventHandler.h"
54 #include "AliVEventPool.h"
55 #include "AliSysInfo.h"
56 #include "AliAnalysisStatistics.h"
62 ClassImp(AliAnalysisManager)
64 AliAnalysisManager *AliAnalysisManager::fgAnalysisManager = NULL;
65 TString AliAnalysisManager::fgCommonFileName = "";
66 TString AliAnalysisManager::fgMacroNames = "";
67 Int_t AliAnalysisManager::fPBUpdateFreq = 1;
69 //______________________________________________________________________________
70 AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
73 fInputEventHandler(0),
74 fOutputEventHandler(0),
75 fMCtruthEventHandler(0),
79 fMode(kLocalAnalysis),
86 fSpecialOutputLocation(""),
96 fFileDescriptors(new TObjArray()),
97 fCurrentDescriptor(0),
104 fAutoBranchHandling(kTRUE),
105 fAsyncReading(kFALSE), // default prefetching on
110 fCacheSize(100000000), // default 100 MB
112 fRequestedBranches(),
122 // Default constructor.
123 fgAnalysisManager = this;
124 fgCommonFileName = "AnalysisResults.root";
125 if (TClass::IsCallingNew() != TClass::kDummyNew) {
126 fTasks = new TObjArray();
127 fTopTasks = new TObjArray();
128 fZombies = new TObjArray();
129 fContainers = new TObjArray();
130 fInputs = new TObjArray();
131 fOutputs = new TObjArray();
132 fParamCont = new TObjArray();
133 fExchangeCont = new TObjArray();
134 fGlobals = new TMap();
136 fIOTimer = new TStopwatch();
137 fCPUTimer = new TStopwatch();
138 fInitTimer = new TStopwatch();
142 //______________________________________________________________________________
143 AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
146 fInputEventHandler(NULL),
147 fOutputEventHandler(NULL),
148 fMCtruthEventHandler(NULL),
153 fInitOK(other.fInitOK),
154 fMustClean(other.fMustClean),
155 fIsRemote(other.fIsRemote),
156 fLocked(other.fLocked),
157 fMCLoop(other.fMCLoop),
158 fDebug(other.fDebug),
159 fSpecialOutputLocation(""),
169 fFileDescriptors(new TObjArray()),
170 fCurrentDescriptor(0),
175 fExtraFiles(other.fExtraFiles),
176 fFileInfoLog(other.fFileInfoLog),
177 fAutoBranchHandling(other.fAutoBranchHandling),
178 fAsyncReading(other.fAsyncReading),
181 fNcalls(other.fNcalls),
182 fMaxEntries(other.fMaxEntries),
183 fCacheSize(other.fCacheSize),
184 fStatisticsMsg(other.fStatisticsMsg),
185 fRequestedBranches(other.fRequestedBranches),
186 fStatistics(other.fStatistics),
187 fGlobals(other.fGlobals),
188 fIOTimer(new TStopwatch()),
189 fCPUTimer(new TStopwatch()),
190 fInitTimer(new TStopwatch()),
196 fTasks = new TObjArray(*other.fTasks);
197 fTopTasks = new TObjArray(*other.fTopTasks);
198 fZombies = new TObjArray(*other.fZombies);
199 fContainers = new TObjArray(*other.fContainers);
200 fInputs = new TObjArray(*other.fInputs);
201 fOutputs = new TObjArray(*other.fOutputs);
202 fParamCont = new TObjArray(*other.fParamCont);
203 fExchangeCont = new TObjArray(*other.fExchangeCont);
204 fgCommonFileName = "AnalysisResults.root";
205 fgAnalysisManager = this;
208 //______________________________________________________________________________
209 AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& other)
212 if (&other != this) {
213 TNamed::operator=(other);
214 fInputEventHandler = other.fInputEventHandler;
215 fOutputEventHandler = other.fOutputEventHandler;
216 fMCtruthEventHandler = other.fMCtruthEventHandler;
217 fEventPool = other.fEventPool;
220 fNSysInfo = other.fNSysInfo;
222 fInitOK = other.fInitOK;
223 fIsRemote = other.fIsRemote;
224 fLocked = other.fLocked;
225 fMCLoop = other.fMCLoop;
226 fDebug = other.fDebug;
227 fTasks = new TObjArray(*other.fTasks);
228 fTopTasks = new TObjArray(*other.fTopTasks);
229 fZombies = new TObjArray(*other.fZombies);
230 fContainers = new TObjArray(*other.fContainers);
231 fInputs = new TObjArray(*other.fInputs);
232 fOutputs = new TObjArray(*other.fOutputs);
233 fParamCont = new TObjArray(*other.fParamCont);
234 fExchangeCont = new TObjArray(*other.fExchangeCont);
235 fDebugOptions = NULL;
236 fFileDescriptors = new TObjArray();
237 fCurrentDescriptor = 0;
239 fCommonOutput = NULL;
242 fExtraFiles = other.fExtraFiles;
243 fFileInfoLog = other.fFileInfoLog;
244 fgCommonFileName = "AnalysisResults.root";
245 fgAnalysisManager = this;
246 fAutoBranchHandling = other.fAutoBranchHandling;
247 fAsyncReading = other.fAsyncReading;
248 fTable.Clear("nodelete");
249 fRunFromPath = other.fRunFromPath;
250 fNcalls = other. fNcalls;
251 fMaxEntries = other.fMaxEntries;
252 fCacheSize = other.fCacheSize;
253 fStatisticsMsg = other.fStatisticsMsg;
254 fRequestedBranches = other.fRequestedBranches;
255 fStatistics = other.fStatistics;
256 fGlobals = new TMap();
257 fIOTimer = new TStopwatch();
258 fCPUTimer = new TStopwatch();
259 fInitTimer = new TStopwatch();
267 //______________________________________________________________________________
268 AliAnalysisManager::~AliAnalysisManager()
271 if (fTasks) {fTasks->Delete(); delete fTasks;}
274 if (fContainers) {fContainers->Delete(); delete fContainers;}
278 delete fExchangeCont;
279 delete fDebugOptions;
281 delete fInputEventHandler;
282 delete fOutputEventHandler;
283 delete fMCtruthEventHandler;
285 if (fgAnalysisManager==this) fgAnalysisManager = NULL;
286 if (fGlobals) {fGlobals->DeleteAll(); delete fGlobals;}
287 if (fFileDescriptors) {fFileDescriptors->Delete(); delete fFileDescriptors;}
293 //______________________________________________________________________________
294 void AliAnalysisManager::CreateReadCache()
296 // Create cache for reading according fCacheSize and fAsyncReading.
297 if (!fTree || !fTree->GetCurrentFile()) {
298 Error("CreateReadCache","Current tree or tree file not yet defined");
302 if (fDebug) Info("CreateReadCache","=== Read caching disabled ===");
305 gEnv->SetValue("TFile.AsyncPrefetching",(Int_t)fAsyncReading);
306 // if (fAsyncReading) gEnv->SetValue("Cache.Directory",Form("file://%s/cache", gSystem->WorkingDirectory()));
307 // if (fAsyncReading) gEnv->SetValue("TFile.AsyncReading",1);
308 fTree->SetCacheSize(fCacheSize);
309 TTreeCache::SetLearnEntries(1); //<<< we can take the decision after 1 entry
310 if (!fAutoBranchHandling && !fRequestedBranches.IsNull()) {
311 TObjArray *arr = fRequestedBranches.Tokenize(",");
315 fTree->AddBranchToCache(obj->GetName(),kTRUE); //<<< add requested branches to cache
318 fTree->AddBranchToCache("*", kTRUE); //<<< add all branches to cache
321 Info("CreateReadCache","Read cache enabled %lld bytes with async reading=%d",fCacheSize, (Int_t)fAsyncReading);
326 //______________________________________________________________________________
327 Bool_t AliAnalysisManager::EventLoop(Long64_t nevents)
329 // Initialize an event loop where the data producer is the input handler
330 // The handler must implement MakeTree creating the tree of events (likely
331 // memory resident) and generate the current event in the method BeginEvent.
332 // If the tree is memory resident, the handler should never call TTree::Fill
334 cout << "===== RUNNING IN EVENT LOOP MODE: " << GetName() << endl;
335 if (!fInputEventHandler) {
336 Error("EventLoop", "No input handler: exiting");
339 TTree *tree = new TTree("DummyTree", "Dummy tree for AliAnalysisManager::EventLoop");
340 SetExternalLoop(kTRUE);
341 if (!Init(tree)) return kFALSE;
343 for (Long64_t iev=0; iev<nevents; iev++)
346 PackOutput(&dummyList);
352 //______________________________________________________________________________
353 Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
355 // Read one entry of the tree or a whole branch.
356 fCurrentEntry = entry;
357 if (!fAutoBranchHandling)
359 if (!fTree || !fTree->GetTree()) return -1;
360 fIOTimer->Start(kTRUE);
361 Long64_t readbytes = fTree->GetTree()->GetEntry(entry, getall);
363 fIOTime += fIOTimer->RealTime();
364 return (Int_t)readbytes;
367 //______________________________________________________________________________
368 Int_t AliAnalysisManager::GetRunFromAlienPath(const char *path)
370 // Attempt to extract run number from input data path. Works only for paths to
371 // alice data in alien.
372 // sim: /alice/sim/<production>/run_no/...
373 // data: /alice/data/year/period/000run_no/... (ESD or AOD)
374 TString type = "unknown";
376 if (s.Contains("/alice/data")) type = "real";
377 else if (s.Contains("/alice/sim")) type = "simulated";
380 ind1 = s.Index("/00");
382 ind2 = s.Index("/",ind1+1);
383 if (ind2-ind1>8) srun = s(ind1+1, ind2-ind1-1);
386 ind1 = s.Index("/LHC");
388 ind1 = s.Index("/",ind1+1);
390 ind2 = s.Index("/",ind1+1);
391 if (ind2>0) srun = s(ind1+1, ind2-ind1-1);
395 Int_t run = srun.Atoi();
396 if (run>0) printf("=== GetRunFromAlienPath: run %d of %s data ===\n", run, type.Data());
400 //______________________________________________________________________________
401 Bool_t AliAnalysisManager::Init(TTree *tree)
403 // The Init() function is called when the selector needs to initialize
404 // a new tree or chain. Typically here the branch addresses of the tree
405 // will be set. It is normaly not necessary to make changes to the
406 // generated code, but the routine can be extended by the user if needed.
407 // Init() will be called many times when running with PROOF.
408 Bool_t init = kFALSE;
409 if (!tree) return kFALSE; // Should not happen - protected in selector caller
411 printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
413 // Call InitTree of EventHandler
414 if (fOutputEventHandler) {
415 if (fMode == kProofAnalysis) {
416 init = fOutputEventHandler->Init(0x0, "proof");
418 init = fOutputEventHandler->Init(0x0, "local");
421 Error("Init", "Output event handler failed to initialize");
426 if (fInputEventHandler) {
427 if (fMode == kProofAnalysis) {
428 init = fInputEventHandler->Init(tree, "proof");
430 init = fInputEventHandler->Init(tree, "local");
433 Error("Init", "Input event handler failed to initialize tree");
437 // If no input event handler we need to get the tree once
439 if(!tree->GetTree()) {
440 Long64_t readEntry = tree->LoadTree(0);
441 if (readEntry == -2) {
442 Error("Init", "Input tree has no entry. Exiting");
448 if (fMCtruthEventHandler) {
449 if (fMode == kProofAnalysis) {
450 init = fMCtruthEventHandler->Init(0x0, "proof");
452 init = fMCtruthEventHandler->Init(0x0, "local");
455 Error("Init", "MC event handler failed to initialize");
460 if (!fInitOK) InitAnalysis();
461 if (!fInitOK) return kFALSE;
463 if (fMode != kProofAnalysis) CreateReadCache();
465 // cholm - here we should re-add to the table or branches
468 AliAnalysisDataContainer *top = fCommonInput;
469 if (!top) top = (AliAnalysisDataContainer*)fInputs->At(0);
471 Error("Init","No top input container !");
475 CheckBranches(kFALSE);
478 printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
483 //______________________________________________________________________________
484 void AliAnalysisManager::SlaveBegin(TTree *tree)
486 // The SlaveBegin() function is called after the Begin() function.
487 // When running with PROOF SlaveBegin() is called on each slave server.
488 // The tree argument is deprecated (on PROOF 0 is passed).
489 if (fDebug > 1) printf("->AliAnalysisManager::SlaveBegin()\n");
490 // Init timer should be already started
491 // Apply debug options
494 fMCtruthEventHandler &&
495 (fMode != kProofAnalysis)) fMCtruthEventHandler->SetCacheSize(fCacheSize);
496 if (!CheckTasks()) Fatal("SlaveBegin", "Not all needed libraries were loaded");
497 static Bool_t isCalled = kFALSE;
498 Bool_t init = kFALSE;
499 Bool_t initOK = kTRUE;
501 TDirectory *curdir = gDirectory;
502 // Call SlaveBegin only once in case of mixing
503 if (isCalled && fMode==kMixingAnalysis) return;
505 // Call Init of EventHandler
506 if (fOutputEventHandler) {
507 if (fMode == kProofAnalysis) {
508 // Merging AOD's in PROOF via TProofOutputFile
509 if (fDebug > 1) printf(" Initializing AOD output file %s...\n", fOutputEventHandler->GetOutputFileName());
510 init = fOutputEventHandler->Init("proof");
511 if (!init) msg = "Failed to initialize output handler on worker";
513 init = fOutputEventHandler->Init("local");
514 if (!init) msg = "Failed to initialize output handler";
517 if (!fSelector) Error("SlaveBegin", "Selector not set");
518 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
521 if (fInputEventHandler) {
522 fInputEventHandler->SetInputTree(tree);
523 if (fMode == kProofAnalysis) {
524 init = fInputEventHandler->Init("proof");
525 if (!init) msg = "Failed to initialize input handler on worker";
527 init = fInputEventHandler->Init("local");
528 if (!init) msg = "Failed to initialize input handler";
531 if (!fSelector) Error("SlaveBegin", "Selector not set");
532 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
535 if (fMCtruthEventHandler) {
536 if (fMode == kProofAnalysis) {
537 init = fMCtruthEventHandler->Init("proof");
538 if (!init) msg = "Failed to initialize MC handler on worker";
540 init = fMCtruthEventHandler->Init("local");
541 if (!init) msg = "Failed to initialize MC handler";
544 if (!fSelector) Error("SlaveBegin", "Selector not set");
545 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
547 if (curdir) curdir->cd();
551 AliAnalysisTask *task;
552 // Call CreateOutputObjects for all tasks
553 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
554 if (getsysInfo) AliSysInfo::SetVerbose(kTRUE);
555 Bool_t dirStatus = TH1::AddDirectoryStatus();
557 while ((task=(AliAnalysisTask*)next())) {
559 // Start with memory as current dir and make sure by default histograms do not get attached to files.
560 TH1::AddDirectory(kFALSE);
561 task->CreateOutputObjects();
562 if (!task->CheckPostData()) {
563 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
564 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
565 ####### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ##########", task->GetName(), task->ClassName());
567 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
570 TH1::AddDirectory(dirStatus);
571 if (curdir) curdir->cd();
573 fInitTime += fInitTimer->RealTime();
574 fInitTimer->Continue();
575 printf("Initialization time: %g [sec]\n", fInitTime);
576 if (fDebug > 1) printf("<-AliAnalysisManager::SlaveBegin()\n");
579 //______________________________________________________________________________
580 Bool_t AliAnalysisManager::Notify()
582 // The Notify() function is called when a new file is opened. This
583 // can be either for a new TTree in a TChain or when when a new TTree
584 // is started when using PROOF. It is normaly not necessary to make changes
585 // to the generated code, but the routine can be extended by the
586 // user if needed. The return value is currently not used.
587 fIOTimer->Start(kTRUE);
588 if (!fTree) return kFALSE;
589 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) return kFALSE;
591 fTable.Clear("nodelete"); // clearing the hash table may not be needed -> C.L.
592 if (fMode == kProofAnalysis) fIsRemote = kTRUE;
594 TFile *curfile = fTree->GetCurrentFile();
596 Error("Notify","No current file");
599 if (IsCollectThroughput()) {
600 if (fCurrentDescriptor) fCurrentDescriptor->Done();
601 fCurrentDescriptor = new AliAnalysisFileDescriptor(curfile);
602 fFileDescriptors->Add(fCurrentDescriptor);
605 if (fDebug > 1) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
606 Int_t run = AliAnalysisManager::GetRunFromAlienPath(curfile->GetName());
607 if (run && (run != fRunFromPath)) {
609 if (fDebug > 1) printf(" ### run found from path: %d\n", run);
612 AliAnalysisTask *task;
614 // Call Notify of the event handlers
615 if (fInputEventHandler) {
616 fInputEventHandler->Notify(curfile->GetName());
619 if (fOutputEventHandler) {
620 fOutputEventHandler->Notify(curfile->GetName());
623 if (fMCtruthEventHandler) {
624 fMCtruthEventHandler->Notify(curfile->GetName());
627 // Call Notify for all tasks
628 while ((task=(AliAnalysisTask*)next()))
631 if (fDebug > 1) printf("<-AliAnalysisManager::Notify()\n");
633 fIOTime += fIOTimer->RealTime();
637 //______________________________________________________________________________
638 Bool_t AliAnalysisManager::Process(Long64_t)
640 // The Process() function is called for each entry in the tree (or possibly
641 // keyed object in the case of PROOF) to be processed. The entry argument
642 // specifies which entry in the currently loaded tree is to be processed.
643 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
644 // to read either all or the required parts of the data. When processing
645 // keyed objects with PROOF, the object is already loaded and is available
646 // via the fObject pointer.
648 // This function should contain the "body" of the analysis. It can contain
649 // simple or elaborate selection criteria, run algorithms on the data
650 // of the event and typically fill histograms.
652 // WARNING when a selector is used with a TChain, you must use
653 // the pointer to the current TTree to call GetEntry(entry).
654 // The entry is always the local entry number in the current tree.
655 // Assuming that fChain is the pointer to the TChain being processed,
656 // use fChain->GetTree()->GetEntry(entry).
658 // This method is obsolete. ExecAnalysis is called instead.
662 //______________________________________________________________________________
663 void AliAnalysisManager::PackOutput(TList *target)
665 // Pack all output data containers in the output list. Called at SlaveTerminate
666 // stage in PROOF case for each slave.
667 if (fDebug > 1) printf("->AliAnalysisManager::PackOutput()\n");
668 fIOTimer->Start(kTRUE);
670 if (IsCollectThroughput()) {
671 if (fCurrentDescriptor) fCurrentDescriptor->Done();
672 fFileDescriptors->Print();
673 if (fFileInfoLog.IsNull()) fFileInfoLog = "fileinfo.log";
674 out.open(fFileInfoLog, std::ios::app);
675 if (out.bad()) Error("SavePrimitive", "Bad file name: %s", fFileInfoLog.Data());
677 TIter nextflog(fFileDescriptors);
679 while ((log=nextflog())) log->SavePrimitive(out,"");
683 Error("PackOutput", "No target. Exiting.");
686 TDirectory *cdir = gDirectory;
688 if (fInputEventHandler) fInputEventHandler ->Terminate();
689 if (fOutputEventHandler) fOutputEventHandler ->Terminate();
690 if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
693 // Call FinishTaskOutput() for each event loop task (not called for
694 // post-event loop tasks - use Terminate() fo those)
695 TIter nexttask(fTasks);
696 AliAnalysisTask *task;
697 while ((task=(AliAnalysisTask*)nexttask())) {
698 if (!task->IsPostEventLoop()) {
699 if (fDebug > 1) printf("->FinishTaskOutput: task %s\n", task->GetName());
700 task->FinishTaskOutput();
702 if (fDebug > 1) printf("<-FinishTaskOutput: task %s\n", task->GetName());
705 // Write statistics message on the workers.
706 if (fStatistics) WriteStatisticsMsg(fNcalls);
708 if (fMode == kProofAnalysis) {
709 TIter next(fOutputs);
710 AliAnalysisDataContainer *output;
711 Bool_t isManagedByHandler = kFALSE;
714 while ((output=(AliAnalysisDataContainer*)next())) {
715 // Do not consider outputs of post event loop tasks
716 isManagedByHandler = kFALSE;
717 if (output->GetProducer() && output->GetProducer()->IsPostEventLoop()) continue;
718 const char *filename = output->GetFileName();
719 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
720 isManagedByHandler = kTRUE;
721 printf("#### Handler output. Extra: %s\n", fExtraFiles.Data());
722 filename = fOutputEventHandler->GetOutputFileName();
724 // Check if data was posted to this container. If not, issue an error.
725 if (!output->GetData() && !isManagedByHandler) {
726 Error("PackOutput", "No data for output container %s. Forgot to PostData ?", output->GetName());
729 if (!output->IsSpecialOutput()) {
731 if (strlen(filename) && !isManagedByHandler) {
732 // Backup current folder
733 TDirectory *opwd = gDirectory;
734 // File resident outputs.
735 // Check first if the file exists.
736 TString openoption = "RECREATE";
737 Bool_t firsttime = kTRUE;
738 if (filestmp.FindObject(output->GetFileName())) {
741 filestmp.Add(new TNamed(output->GetFileName(),""));
743 if (!gSystem->AccessPathName(output->GetFileName()) && !firsttime) openoption = "UPDATE";
744 // TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
745 // Save data to file, then close.
746 if (output->GetData()->InheritsFrom(TCollection::Class())) {
747 // If data is a collection, we set the name of the collection
748 // as the one of the container and we save as a single key.
749 TCollection *coll = (TCollection*)output->GetData();
750 coll->SetName(output->GetName());
751 // coll->Write(output->GetName(), TObject::kSingleKey);
753 if (output->GetData()->InheritsFrom(TTree::Class())) {
754 TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
755 // Save data to file, then close.
756 TTree *tree = (TTree*)output->GetData();
757 // Check if tree is in memory
758 if (tree->GetDirectory()==gROOT) tree->SetDirectory(gDirectory);
762 // output->GetData()->Write();
765 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
767 // printf(" file %s listing content:\n", filename);
770 // Clear file list to release object ownership to user.
773 output->SetFile(NULL);
774 // Restore current directory
775 if (opwd) opwd->cd();
777 // Memory-resident outputs
778 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
780 AliAnalysisDataWrapper *wrap = 0;
781 if (isManagedByHandler) {
782 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
783 wrap->SetName(output->GetName());
785 else wrap =output->ExportData();
786 // Output wrappers must NOT delete data after merging - the user owns them
787 wrap->SetDeleteData(kFALSE);
790 // Special outputs. The file must be opened and connected to the container.
791 TDirectory *opwd = gDirectory;
792 TFile *file = output->GetFile();
794 AliAnalysisTask *producer = output->GetProducer();
796 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
797 output->GetFileName(), output->GetName(), producer->ClassName());
800 TString outFilename = file->GetName();
801 if (fDebug > 1) printf("PackOutput %s: special output\n", output->GetName());
802 if (isManagedByHandler) {
803 // Terminate IO for files managed by the output handler
804 // file->Write() moved to AOD handler (A.G. 11.01.10)
805 // if (file) file->Write();
806 if (file && fDebug > 2) {
807 printf(" handled file %s listing content:\n", file->GetName());
810 fOutputEventHandler->TerminateIO();
813 // Release object ownership to users after writing data to file
814 if (output->GetData()->InheritsFrom(TCollection::Class())) {
815 // If data is a collection, we set the name of the collection
816 // as the one of the container and we save as a single key.
817 TCollection *coll = (TCollection*)output->GetData();
818 coll->SetName(output->GetName());
819 coll->Write(output->GetName(), TObject::kSingleKey);
821 if (output->GetData()->InheritsFrom(TTree::Class())) {
822 TTree *tree = (TTree*)output->GetData();
823 tree->SetDirectory(file);
826 output->GetData()->Write();
830 printf(" file %s listing content:\n", output->GetFileName());
833 // Clear file list to release object ownership to user.
836 output->SetFile(NULL);
838 // Restore current directory
839 if (opwd) opwd->cd();
840 // Check if a special output location was provided or the output files have to be merged
841 if (strlen(fSpecialOutputLocation.Data())) {
842 TString remote = fSpecialOutputLocation;
844 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
845 if (remote.BeginsWith("alien:")) {
846 gROOT->ProcessLine("TGrid::Connect(\"alien:\", gProofServ->GetUser());");
847 remote += outFilename;
848 remote.ReplaceAll(".root", Form("_%d.root", gid));
850 remote += Form("%s_%d_", gSystem->HostName(), gid);
851 remote += outFilename;
854 Info("PackOutput", "Output file for container %s to be copied \n at: %s. No merging.",
855 output->GetName(), remote.Data());
856 TFile::Cp ( outFilename.Data(), remote.Data() );
857 // Copy extra outputs
858 if (fExtraFiles.Length() && isManagedByHandler) {
859 TObjArray *arr = fExtraFiles.Tokenize(" ");
861 TIter nextfilename(arr);
862 while ((os=(TObjString*)nextfilename())) {
863 outFilename = os->GetString();
864 remote = fSpecialOutputLocation;
866 if (remote.BeginsWith("alien://")) {
867 remote += outFilename;
868 remote.ReplaceAll(".root", Form("_%d.root", gid));
870 remote += Form("%s_%d_", gSystem->HostName(), gid);
871 remote += outFilename;
874 Info("PackOutput", "Extra AOD file %s to be copied \n at: %s. No merging.",
875 outFilename.Data(), remote.Data());
876 TFile::Cp ( outFilename.Data(), remote.Data() );
881 // No special location specified-> use TProofOutputFile as merging utility
882 // The file at this output slot must be opened in CreateOutputObjects
883 if (fDebug > 1) printf(" File for container %s to be merged via file merger...\n", output->GetName());
888 fIOTime += fIOTimer->RealTime();
889 if ((fDebug || IsCollectThroughput())) {
891 fInitTime = fInitTimer->RealTime()-fIOTime-fCPUTime;
892 printf("=Analysis %s= init time: %g[sec]\
893 \n I/O & data mng.: %g [sec]\
894 \n task execution: %g [sec]\
895 \n total time: CPU=%g [sec] REAL=%g[sec]\n",
896 GetName(), fInitTime, fIOTime, fCPUTime, fInitTimer->CpuTime(), fInitTimer->RealTime());
897 if (IsCollectThroughput()) {
898 out << "#summary#########################################################" << endl;
899 out << "train_name " << GetName() << endl;
900 out << "root_time " << fInitTimer->RealTime() << endl;
901 out << "root_cpu " << fInitTimer->CpuTime() << endl;
902 out << "init_time " << fInitTime << endl;
903 out << "io_mng_time " << fIOTime << endl;
904 out << "exec_time " << fCPUTime << endl;
905 TString aliensite = gSystem->Getenv("ALIEN_SITE");
906 out << "alien_site " << aliensite << endl;
908 TString hostname = gSystem->Getenv("ALIEN_HOSTNAME");
909 if (hostname.IsNull()) {
911 gSystem->Exec(Form("hostname -f >> %s", fFileInfoLog.Data()));
913 out << hostname << endl;
918 if (cdir) cdir->cd();
919 if (fDebug > 1) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
922 //______________________________________________________________________________
923 void AliAnalysisManager::ImportWrappers(TList *source)
925 // Import data in output containers from wrappers coming in source.
926 if (fDebug > 1) printf("->AliAnalysisManager::ImportWrappers()\n");
927 fIOTimer->Start(kTRUE);
928 TIter next(fOutputs);
929 AliAnalysisDataContainer *cont;
930 AliAnalysisDataWrapper *wrap;
932 Bool_t inGrid = (fMode == kGridAnalysis)?kTRUE:kFALSE;
933 TDirectory *cdir = gDirectory;
934 while ((cont=(AliAnalysisDataContainer*)next())) {
936 if (cont->GetProducer() && cont->GetProducer()->IsPostEventLoop() && !inGrid) continue;
937 if (cont->IsRegisterDataset()) continue;
938 const char *filename = cont->GetFileName();
939 Bool_t isManagedByHandler = kFALSE;
940 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
941 isManagedByHandler = kTRUE;
942 filename = fOutputEventHandler->GetOutputFileName();
944 if (cont->IsSpecialOutput() || inGrid) {
945 if (strlen(fSpecialOutputLocation.Data())) continue;
946 // Copy merged file from PROOF scratch space.
947 // In case of grid the files are already in the current directory.
949 if (isManagedByHandler && fExtraFiles.Length()) {
950 // Copy extra registered dAOD files.
951 TObjArray *arr = fExtraFiles.Tokenize(" ");
953 TIter nextfilename(arr);
954 while ((os=(TObjString*)nextfilename())) GetFileFromWrapper(os->GetString(), source);
957 if (!GetFileFromWrapper(filename, source)) continue;
959 // Normally we should connect data from the copied file to the
960 // corresponding output container, but it is not obvious how to do this
961 // automatically if several objects in file...
962 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
963 if (!f) f = TFile::Open(filename, "READ");
965 Error("ImportWrappers", "Cannot open file %s in read-only mode", filename);
970 // Cd to the directory pointed by the container
971 TString folder = cont->GetFolderName();
972 if (!folder.IsNull()) f->cd(folder);
973 // Try to fetch first an object having the container name.
974 obj = gDirectory->Get(cont->GetName());
976 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",
977 cont->GetType()->GetName(), cont->GetName(), filename, cont->GetFolderName(), cont->GetName());
980 wrap = new AliAnalysisDataWrapper(obj);
981 wrap->SetDeleteData(kFALSE);
983 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
985 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
990 printf(" Importing data for container %s\n", cont->GetName());
991 if (strlen(filename)) printf(" -> file %s\n", filename);
994 cont->ImportData(wrap);
996 if (cdir) cdir->cd();
998 fIOTime += fIOTimer->RealTime();
999 if (fDebug > 1) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
1002 //______________________________________________________________________________
1003 void AliAnalysisManager::UnpackOutput(TList *source)
1005 // Called by AliAnalysisSelector::Terminate only on the client.
1006 fIOTimer->Start(kTRUE);
1007 if (fDebug > 1) printf("->AliAnalysisManager::UnpackOutput()\n");
1009 Error("UnpackOutput", "No target. Exiting.");
1012 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
1014 if (fMode == kProofAnalysis) ImportWrappers(source);
1016 TIter next(fOutputs);
1017 AliAnalysisDataContainer *output;
1018 while ((output=(AliAnalysisDataContainer*)next())) {
1019 if (!output->GetData()) continue;
1020 // Check if there are client tasks that run post event loop
1021 if (output->HasConsumers()) {
1022 // Disable event loop semaphore
1023 output->SetPostEventLoop(kTRUE);
1024 TObjArray *list = output->GetConsumers();
1025 Int_t ncons = list->GetEntriesFast();
1026 for (Int_t i=0; i<ncons; i++) {
1027 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
1028 task->CheckNotify(kTRUE);
1029 // If task is active, execute it
1030 if (task->IsPostEventLoop() && task->IsActive()) {
1031 if (fDebug > 1) printf("== Executing post event loop task %s\n", task->GetName());
1032 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
1033 task->ExecuteTask();
1036 if (fStatistics) fStatistics->StopTimer();
1040 fIOTime += fIOTimer->RealTime();
1041 if (fDebug > 1) printf("<-AliAnalysisManager::UnpackOutput()\n");
1044 //______________________________________________________________________________
1045 void AliAnalysisManager::Terminate()
1047 // The Terminate() function is the last function to be called during
1048 // a query. It always runs on the client, it can be used to present
1049 // the results graphically.
1050 if (fDebug > 1) printf("->AliAnalysisManager::Terminate()\n");
1051 fInitTimer->Start(kTRUE);
1052 TDirectory *cdir = gDirectory;
1054 AliAnalysisTask *task;
1055 AliAnalysisDataContainer *output;
1058 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1059 if (getsysInfo) AliSysInfo::SetVerbose(kTRUE);
1060 // Call Terminate() for tasks
1062 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
1063 // Save all the canvases produced by the Terminate
1064 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
1068 AliSysInfo::AddStamp(Form("%s_TERMINATE",task->ClassName()),0, itask, 2);
1070 if (TObject::TestBit(kSaveCanvases)) {
1071 if (!gROOT->IsBatch()) {
1072 if (fDebug>1) printf("Waiting 5 sec for %s::Terminate() to finish drawing ...\n", task->ClassName());
1074 while (timer.RealTime()<5) {
1076 gSystem->ProcessEvents();
1079 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
1080 if (iend==0) continue;
1082 for (Int_t ipict=0; ipict<iend; ipict++) {
1083 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
1084 if (!canvas) continue;
1085 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
1087 gROOT->GetListOfCanvases()->Delete();
1091 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
1092 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
1093 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
1095 TObjArray *allOutputs = new TObjArray();
1097 for (icont=0; icont<fOutputs->GetEntriesFast(); icont++) allOutputs->Add(fOutputs->At(icont));
1098 if (!IsSkipTerminate())
1099 for (icont=0; icont<fParamCont->GetEntriesFast(); icont++) allOutputs->Add(fParamCont->At(icont));
1100 TIter next1(allOutputs);
1101 TString handlerFile = "";
1102 TString extraOutputs = "";
1103 if (fOutputEventHandler) {
1104 handlerFile = fOutputEventHandler->GetOutputFileName();
1105 extraOutputs = fOutputEventHandler->GetExtraOutputs();
1109 while ((output=(AliAnalysisDataContainer*)next1())) {
1110 // Special outputs or grid files have the files already closed and written.
1112 if (fMode == kGridAnalysis && icont<=fOutputs->GetEntriesFast()) continue;
1113 if (fMode == kProofAnalysis) {
1114 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
1116 const char *filename = output->GetFileName();
1117 TString openoption = "RECREATE";
1118 if (!(strcmp(filename, "default"))) continue;
1119 if (!strlen(filename)) continue;
1120 if (!output->GetData()) continue;
1121 TDirectory *opwd = gDirectory;
1122 TFile *file = output->GetFile();
1123 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1125 //if (handlerFile == filename && !gSystem->AccessPathName(filename)) openoption = "UPDATE";
1126 Bool_t firsttime = kTRUE;
1127 if (filestmp.FindObject(filename) || extraOutputs.Contains(filename)) {
1130 filestmp.Add(new TNamed(filename,""));
1132 if (!gSystem->AccessPathName(filename) && !firsttime) openoption = "UPDATE";
1133 if (fDebug>1) printf("Opening file: %s option=%s\n",filename, openoption.Data());
1134 file = new TFile(filename, openoption);
1136 if (fDebug>1) printf("File <%s> already opened with option: <%s> \n", filename, file->GetOption());
1137 openoption = file->GetOption();
1138 if (openoption == "READ") {
1139 if (fDebug>1) printf("...reopening in UPDATE mode\n");
1140 file->ReOpen("UPDATE");
1143 if (file->IsZombie()) {
1144 Error("Terminate", "Cannot open output file %s", filename);
1147 output->SetFile(file);
1149 // Check for a folder request
1150 TString dir = output->GetFolderName();
1151 if (!dir.IsNull()) {
1152 if (!file->GetDirectory(dir)) file->mkdir(dir);
1155 if (fDebug > 1) printf("...writing container %s to file %s:%s\n", output->GetName(), file->GetName(), output->GetFolderName());
1156 if (output->GetData()->InheritsFrom(TCollection::Class())) {
1157 // If data is a collection, we set the name of the collection
1158 // as the one of the container and we save as a single key.
1159 TCollection *coll = (TCollection*)output->GetData();
1160 coll->SetName(output->GetName());
1161 coll->Write(output->GetName(), TObject::kSingleKey);
1163 if (output->GetData()->InheritsFrom(TTree::Class())) {
1164 TTree *tree = (TTree*)output->GetData();
1165 tree->SetDirectory(gDirectory);
1168 output->GetData()->Write();
1171 if (opwd) opwd->cd();
1175 TString copiedFiles;
1176 while ((output=(AliAnalysisDataContainer*)next1())) {
1177 // Close all files at output
1178 TDirectory *opwd = gDirectory;
1179 if (output->GetFile()) {
1180 // Clear file list to release object ownership to user.
1181 // output->GetFile()->Clear();
1182 output->GetFile()->Close();
1183 // Copy merged outputs in alien if requested
1184 if (fSpecialOutputLocation.BeginsWith("alien://")) {
1185 if (copiedFiles.Contains(output->GetFile()->GetName())) {
1186 if (opwd) opwd->cd();
1187 output->SetFile(NULL);
1190 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
1191 gROOT->ProcessLine("if (!gGrid) TGrid::Connect(\"alien:\");");
1192 TFile::Cp(output->GetFile()->GetName(),
1193 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
1194 copiedFiles += output->GetFile()->GetName();
1196 output->SetFile(NULL);
1198 if (opwd) opwd->cd();
1201 //Write statistics information on the client
1202 if (fStatistics) WriteStatisticsMsg(fNcalls);
1204 TDirectory *crtdir = gDirectory;
1205 TFile f("syswatch.root", "RECREATE");
1208 if (!f.IsZombie()) {
1209 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
1210 tree->SetName("syswatch");
1211 tree->SetMarkerStyle(kCircle);
1212 tree->SetMarkerColor(kBlue);
1213 tree->SetMarkerSize(0.5);
1214 if (!gROOT->IsBatch()) {
1215 tree->SetAlias("event", "id0");
1216 tree->SetAlias("task", "id1");
1217 tree->SetAlias("stage", "id2");
1218 // Already defined aliases
1219 // tree->SetAlias("deltaT","stampSec-stampOldSec");
1220 // tree->SetAlias("T","stampSec-first");
1221 // tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)");
1222 // tree->SetAlias("VM","pI.fMemVirtual");
1223 TCanvas *canvas = new TCanvas("SysInfo","SysInfo",10,10,1200,800);
1224 Int_t npads = 1 /*COO plot for all tasks*/ +
1225 fTopTasks->GetEntries() /*Exec plot per task*/ +
1226 1 /*Terminate plot for all tasks*/ +
1229 Int_t iopt = (Int_t)TMath::Sqrt((Double_t)npads);
1230 if (npads<iopt*(iopt+1))
1231 canvas->Divide(iopt, iopt+1, 0.01, 0.01);
1233 canvas->Divide(iopt+1, iopt+1, 0.01, 0.01);
1235 // draw the plot of deltaVM for Exec for each task
1236 for (itask=0; itask<fTopTasks->GetEntriesFast(); itask++) {
1237 task = (AliAnalysisTask*)fTopTasks->At(itask);
1239 cut = Form("task==%d && stage==1", itask);
1240 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1241 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1243 hist->SetTitle(Form("%s: Exec dVM[MB]/event", task->GetName()));
1244 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1247 // Draw the plot of deltaVM for CreateOutputObjects for all tasks
1249 tree->SetMarkerStyle(kFullTriangleUp);
1250 tree->SetMarkerColor(kRed);
1251 tree->SetMarkerSize(0.8);
1252 cut = "task>=0 && task<1000 && stage==0";
1253 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1254 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1256 hist->SetTitle("Memory in CreateOutputObjects()");
1257 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1258 hist->GetXaxis()->SetTitle("task");
1260 // draw the plot of deltaVM for Terminate for all tasks
1262 tree->SetMarkerStyle(kOpenSquare);
1263 tree->SetMarkerColor(kMagenta);
1264 cut = "task>=0 && task<1000 && stage==2";
1265 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1266 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1268 hist->SetTitle("Memory in Terminate()");
1269 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1270 hist->GetXaxis()->SetTitle("task");
1274 tree->SetMarkerStyle(kFullCircle);
1275 tree->SetMarkerColor(kGreen);
1276 cut = Form("task==%d && stage==1",fTopTasks->GetEntriesFast()-1);
1277 tree->Draw("VM:event",cut,"", 1234567890, 0);
1278 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1280 hist->SetTitle("Virtual memory");
1281 hist->GetYaxis()->SetTitle("VM [MB]");
1285 tree->SetMarkerStyle(kCircle);
1286 tree->SetMarkerColor(kBlue);
1287 tree->SetMarkerSize(0.5);
1292 if (crtdir) crtdir->cd();
1294 // Validate the output files
1295 if (ValidateOutputFiles() && fIsRemote && fMode!=kProofAnalysis) {
1297 out.open("outputs_valid", ios::out);
1300 if (cdir) cdir->cd();
1302 if (fDebug || IsCollectThroughput()) {
1303 printf("=Analysis %s= Terminate time: %g[sec]\n", GetName(), fInitTimer->RealTime());
1305 if (fDebug > 1) printf("<-AliAnalysisManager::Terminate()\n");
1307 //______________________________________________________________________________
1308 void AliAnalysisManager::ProfileTask(Int_t itop, const char *option) const
1310 // Profiles the task having the itop index in the list of top (first level) tasks.
1311 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->At(itop);
1313 Error("ProfileTask", "There are only %d top tasks in the manager", fTopTasks->GetEntries());
1316 ProfileTask(task->GetName(), option);
1319 //______________________________________________________________________________
1320 void AliAnalysisManager::ProfileTask(const char *name, const char */*option*/) const
1322 // Profile a managed task after the execution of the analysis in case NSysInfo
1324 if (gSystem->AccessPathName("syswatch.root")) {
1325 Error("ProfileTask", "No file syswatch.root found in the current directory");
1328 if (gROOT->IsBatch()) return;
1329 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->FindObject(name);
1331 Error("ProfileTask", "No top task named %s known by the manager.", name);
1334 Int_t itop = fTopTasks->IndexOf(task);
1335 Int_t itask = fTasks->IndexOf(task);
1336 // Create canvas with 2 pads: first draw COO + Terminate, second Exec
1337 TDirectory *cdir = gDirectory;
1338 TFile f("syswatch.root");
1339 TTree *tree = (TTree*)f.Get("syswatch");
1341 Error("ProfileTask", "No tree named <syswatch> found in file syswatch.root");
1344 if (fDebug > 1) printf("=== Profiling task %s (class %s)\n", name, task->ClassName());
1345 TCanvas *canvas = new TCanvas(Form("profile_%d",itop),Form("Profile of task %s (class %s)",name,task->ClassName()),10,10,800,600);
1346 canvas->Divide(2, 2, 0.01, 0.01);
1350 // VM profile for COO and Terminate methods
1352 cut = Form("task==%d && (stage==0 || stage==2)",itask);
1353 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1354 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1356 hist->SetTitle("Alocated VM[MB] for COO and Terminate");
1357 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1358 hist->GetXaxis()->SetTitle("method");
1360 // CPU profile per event
1362 cut = Form("task==%d && stage==1",itop);
1363 tree->Draw("deltaT:event",cut,"", 1234567890, 0);
1364 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1366 hist->SetTitle("Execution time per event");
1367 hist->GetYaxis()->SetTitle("CPU/event [s]");
1369 // VM profile for Exec
1371 cut = Form("task==%d && stage==1",itop);
1372 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1373 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1375 hist->SetTitle("Alocated VM[MB] per event");
1376 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1381 if (cdir) cdir->cd();
1384 //______________________________________________________________________________
1385 void AliAnalysisManager::AddTask(AliAnalysisTask *task)
1387 // Adds a user task to the global list of tasks.
1389 Error("AddTask", "Cannot add task %s since InitAnalysis was already called", task->GetName());
1393 if (fTasks->FindObject(task)) {
1394 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
1397 task->SetActive(kFALSE);
1401 //______________________________________________________________________________
1402 AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
1404 // Retreive task by name.
1405 if (!fTasks) return NULL;
1406 return (AliAnalysisTask*)fTasks->FindObject(name);
1409 //______________________________________________________________________________
1410 Int_t AliAnalysisManager::GetTaskIndex(const AliAnalysisTask *task) const
1412 // Returns task inded in the manager's list, -1 if not registered.
1413 if (!fTasks) return -1;
1414 return fTasks->IndexOf(task);
1417 //______________________________________________________________________________
1418 AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
1419 TClass *datatype, EAliAnalysisContType type, const char *filename)
1421 // Create a data container of a certain type. Types can be:
1422 // kExchangeContainer = 0, used to exchange data between tasks
1423 // kInputContainer = 1, used to store input data
1424 // kOutputContainer = 2, used for writing result to a file
1425 // filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
1426 // the output object to a folder inside the output file
1427 if (fContainers->FindObject(name)) {
1428 Error("CreateContainer","A container named %s already defined !",name);
1431 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
1432 fContainers->Add(cont);
1434 case kInputContainer:
1437 case kOutputContainer:
1438 fOutputs->Add(cont);
1439 if (filename && strlen(filename)) {
1440 cont->SetFileName(filename);
1441 cont->SetDataOwned(kFALSE); // data owned by the file
1444 case kParamContainer:
1445 fParamCont->Add(cont);
1446 if (filename && strlen(filename)) {
1447 cont->SetFileName(filename);
1448 cont->SetDataOwned(kFALSE); // data owned by the file
1451 case kExchangeContainer:
1452 cont->SetExchange(kTRUE);
1453 fExchangeCont->Add(cont);
1454 cont->SetDataOwned(kFALSE); // data owned by the publisher
1460 //______________________________________________________________________________
1461 Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
1462 AliAnalysisDataContainer *cont)
1464 // Connect input of an existing task to a data container.
1466 Error("ConnectInput", "Task pointer is NULL");
1469 if (!fTasks->FindObject(task)) {
1471 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
1473 Bool_t connected = task->ConnectInput(islot, cont);
1477 //______________________________________________________________________________
1478 Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
1479 AliAnalysisDataContainer *cont)
1481 // Connect output of an existing task to a data container.
1483 Error("ConnectOutput", "Task pointer is NULL");
1486 if (!fTasks->FindObject(task)) {
1488 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
1490 Bool_t connected = task->ConnectOutput(islot, cont);
1494 //______________________________________________________________________________
1495 void AliAnalysisManager::CleanContainers()
1497 // Clean data from all containers that have already finished all client tasks.
1498 TIter next(fContainers);
1499 AliAnalysisDataContainer *cont;
1500 while ((cont=(AliAnalysisDataContainer *)next())) {
1501 if (cont->IsOwnedData() &&
1502 cont->IsDataReady() &&
1503 cont->ClientsExecuted()) cont->DeleteData();
1507 //______________________________________________________________________________
1508 Bool_t AliAnalysisManager::InitAnalysis()
1510 // Initialization of analysis chain of tasks. Should be called after all tasks
1511 // and data containers are properly connected
1512 // Reset flag and remove valid_outputs file if exists
1513 if (fInitOK) return kTRUE;
1514 if (!gSystem->AccessPathName("outputs_valid"))
1515 gSystem->Unlink("outputs_valid");
1516 // Check for top tasks (depending only on input data containers)
1517 if (!fTasks->First()) {
1518 Error("InitAnalysis", "Analysis has no tasks !");
1522 AliAnalysisTask *task;
1523 AliAnalysisDataContainer *cont;
1526 Bool_t iszombie = kFALSE;
1527 Bool_t istop = kTRUE;
1529 while ((task=(AliAnalysisTask*)next())) {
1532 Int_t ninputs = task->GetNinputs();
1533 for (i=0; i<ninputs; i++) {
1534 cont = task->GetInputSlot(i)->GetContainer();
1538 fZombies->Add(task);
1542 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
1543 i, task->GetName());
1545 if (iszombie) continue;
1546 // Check if cont is an input container
1547 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
1548 // Connect to parent task
1552 fTopTasks->Add(task);
1556 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
1559 // Check now if there are orphan tasks
1560 for (i=0; i<ntop; i++) {
1561 task = (AliAnalysisTask*)fTopTasks->At(i);
1566 while ((task=(AliAnalysisTask*)next())) {
1567 if (!task->IsUsed()) {
1569 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
1572 // Check the task hierarchy (no parent task should depend on data provided
1573 // by a daughter task)
1574 for (i=0; i<ntop; i++) {
1575 task = (AliAnalysisTask*)fTopTasks->At(i);
1576 if (task->CheckCircularDeps()) {
1577 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
1582 // Check that all containers feeding post-event loop tasks are in the outputs list
1583 TIter nextcont(fContainers); // loop over all containers
1584 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1585 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1586 if (cont->HasConsumers()) {
1587 // Check if one of the consumers is post event loop
1588 TIter nextconsumer(cont->GetConsumers());
1589 while ((task=(AliAnalysisTask*)nextconsumer())) {
1590 if (task->IsPostEventLoop()) {
1591 fOutputs->Add(cont);
1598 // Check if all special output containers have a file name provided
1599 TIter nextout(fOutputs);
1600 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1601 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1602 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1606 // Initialize requested branch list if needed
1607 if (!fAutoBranchHandling) {
1609 while ((task=(AliAnalysisTask*)next())) {
1610 if (!task->HasBranches()) {
1611 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches.\nUse: fBranchNames = \"ESD:br1,br2,...,brN AOD:bra1,bra2,...,braM\"",
1612 task->GetName(), task->ClassName());
1615 if (!fInputEventHandler || !strlen(fInputEventHandler->GetDataType())) {
1616 Error("InitAnalysis", "Manual branch loading requested but no input handler defined or handler does not define data type.");
1619 TString taskbranches;
1620 task->GetBranches(fInputEventHandler->GetDataType(), taskbranches);
1621 if (taskbranches.IsNull()) {
1622 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches of type %s:",
1623 task->GetName(), task->ClassName(), fInputEventHandler->GetDataType());
1626 AddBranches(taskbranches);
1633 //______________________________________________________________________________
1634 void AliAnalysisManager::AddBranches(const char *branches)
1636 // Add branches to the existing fRequestedBranches.
1637 TString br(branches);
1638 TObjArray *arr = br.Tokenize(",");
1641 while ((obj=next())) {
1642 if (!fRequestedBranches.Contains(obj->GetName())) {
1643 if (!fRequestedBranches.IsNull()) fRequestedBranches += ",";
1644 fRequestedBranches += obj->GetName();
1650 //______________________________________________________________________________
1651 void AliAnalysisManager::CheckBranches(Bool_t load)
1653 // The method checks the input branches to be loaded during the analysis.
1654 if (fAutoBranchHandling || fRequestedBranches.IsNull() || !fTree) return;
1655 TObjArray *arr = fRequestedBranches.Tokenize(",");
1658 while ((obj=next())) {
1659 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(obj->GetName()));
1661 br = fTree->GetBranch(obj->GetName());
1663 Error("CheckBranches", "Could not find branch %s",obj->GetName());
1668 if (load && br->GetReadEntry()!=GetCurrentEntry()) {
1669 br->GetEntry(GetCurrentEntry());
1675 //______________________________________________________________________________
1676 Bool_t AliAnalysisManager::CheckTasks() const
1678 // Check consistency of tasks.
1679 Int_t ntasks = fTasks->GetEntries();
1681 Error("CheckTasks", "No tasks connected to the manager. This may be due to forgetting to compile the task or to load their library.");
1684 // Get the pointer to AliAnalysisTaskSE::Class()
1685 TClass *badptr = (TClass*)gROOT->ProcessLine("AliAnalysisTaskSE::Class()");
1686 // Loop all tasks to check if their corresponding library was loaded
1689 while ((obj=next())) {
1690 if (obj->IsA() == badptr) {
1691 Error("CheckTasks", "##################\n \
1692 Class for task %s NOT loaded. You probably forgot to load the library for this task (or compile it dynamically).\n###########################\n",obj->GetName());
1699 //______________________________________________________________________________
1700 void AliAnalysisManager::PrintStatus(Option_t *option) const
1702 // Print task hierarchy.
1704 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1707 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1709 AliSysInfo::SetVerbose(kTRUE);
1710 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
1712 AliAnalysisDataContainer *cont = fCommonInput;
1713 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
1714 printf("=== TOP CONTAINER:\n");
1715 cont->PrintContainer(option,0);
1716 // Reset "touched" flag
1717 TIter next(fContainers);
1718 while ((cont = (AliAnalysisDataContainer*)next())) cont->SetTouched(kFALSE);
1719 TIter nextt(fTasks);
1720 AliAnalysisTask *task;
1721 while ((task=(AliAnalysisTask*)nextt()))
1722 task->SetActive(kFALSE);
1724 if (!fAutoBranchHandling && !fRequestedBranches.IsNull())
1725 printf("Requested input branches:\n%s\n", fRequestedBranches.Data());
1727 TString sopt(option);
1730 if (sopt.Contains("ALL"))
1732 if ( fOutputEventHandler )
1734 cout << TString('_',78) << endl;
1735 cout << "OutputEventHandler:" << endl;
1736 fOutputEventHandler->Print(" ");
1741 //______________________________________________________________________________
1742 void AliAnalysisManager::ResetAnalysis()
1744 // Reset all execution flags and clean containers.
1745 TIter nextTask(fTasks);
1746 AliAnalysisTask *task;
1747 while ((task=(AliAnalysisTask*)nextTask())) {
1751 // CleanContainers();
1754 //______________________________________________________________________________
1755 void AliAnalysisManager::RunLocalInit()
1757 // Run LocalInit method for all tasks.
1758 TDirectory *cdir = gDirectory;
1759 if (IsTrainInitialized()) return;
1760 TIter nextTask(fTasks);
1761 AliAnalysisTask *task;
1762 while ((task=(AliAnalysisTask*)nextTask())) {
1766 if (cdir) cdir->cd();
1767 TObject::SetBit(kTasksInitialized, kTRUE);
1770 //______________________________________________________________________________
1771 void AliAnalysisManager::InputFileFromTree(TTree * const tree, TString &fname)
1773 // Retrieves name of the file from tree
1776 TFile *file = tree->GetCurrentFile();
1779 TChain *chain = dynamic_cast<TChain*>(tree);
1780 if (!chain || !chain->GetNtrees()) return;
1781 basename = gSystem->BaseName(chain->GetListOfFiles()->First()->GetTitle());
1783 basename = gSystem->BaseName(file->GetName());
1785 Int_t index = basename.Index("#");
1786 fname = basename(index+1, basename.Length());
1789 //______________________________________________________________________________
1790 Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
1792 // Start analysis having a grid handler.
1793 if (!fGridHandler) {
1794 Error("StartAnalysis", "Cannot start analysis providing just the analysis type without a grid handler.");
1795 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1799 return StartAnalysis(type, tree, nentries, firstentry);
1802 //______________________________________________________________________________
1803 Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
1805 // Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1806 // MIX. Process nentries starting from firstentry
1808 // Backup current directory and make sure gDirectory points to gROOT
1809 TDirectory *cdir = gDirectory;
1812 Error("StartAnalysis","Analysis manager was not initialized !");
1813 if (cdir) cdir->cd();
1816 if (!CheckTasks()) Fatal("StartAnalysis", "Not all needed libraries were loaded");
1818 printf("StartAnalysis %s\n",GetName());
1819 AliLog::SetGlobalLogLevel(AliLog::kInfo);
1821 fMaxEntries = nentries;
1823 TString anaType = type;
1825 fMode = kLocalAnalysis;
1826 if (anaType.Contains("file")) fIsRemote = kTRUE;
1827 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1828 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1829 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1830 if (fInputEventHandler) {
1832 InputFileFromTree(tree, fname);
1833 if (fname.Length()) fInputEventHandler->SetInputFileName(fname);
1836 if (fMode == kGridAnalysis) {
1838 if (!anaType.Contains("terminate")) {
1839 if (!fGridHandler) {
1840 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1841 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1842 if (cdir) cdir->cd();
1845 // Write analysis manager in the analysis file
1846 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1847 // run local task configuration
1849 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1850 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1851 if (cdir) cdir->cd();
1855 // Terminate grid analysis
1856 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1857 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1858 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1859 if (!fGridHandler->MergeOutputs()) {
1860 // Return if outputs could not be merged or if it alien handler
1861 // was configured for offline mode or local testing.
1862 if (cdir) cdir->cd();
1866 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1867 if (cdir) cdir->cd();
1868 ImportWrappers(NULL);
1870 if (cdir) cdir->cd();
1874 SetEventLoop(kFALSE);
1875 // Enable event loop mode if a tree was provided
1876 if (tree || fGridHandler || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
1879 TString ttype = "TTree";
1880 if (tree && tree->IsA() == TChain::Class()) {
1881 chain = (TChain*)tree;
1882 if (!chain || !chain->GetListOfFiles()->First()) {
1883 Error("StartAnalysis", "Cannot process null or empty chain...");
1884 if (cdir) cdir->cd();
1890 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1892 AliSysInfo::SetVerbose(kTRUE);
1893 AliSysInfo::AddStamp("Start", 0);
1895 // Initialize locally all tasks (happens for all modes)
1897 AliAnalysisTask *task;
1901 case kLocalAnalysis:
1902 if (!tree && !fGridHandler) {
1903 TIter nextT(fTasks);
1904 // Call CreateOutputObjects for all tasks
1906 Bool_t dirStatus = TH1::AddDirectoryStatus();
1907 while ((task=(AliAnalysisTask*)nextT())) {
1908 TH1::AddDirectory(kFALSE);
1909 task->CreateOutputObjects();
1910 if (!task->CheckPostData()) {
1911 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
1912 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
1913 ########### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ###########", task->GetName(), task->ClassName());
1915 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
1919 TH1::AddDirectory(dirStatus);
1920 if (IsExternalLoop()) {
1921 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1922 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1929 fSelector = new AliAnalysisSelector(this);
1930 // Check if a plugin handler is used
1932 // Get the chain from the plugin
1933 TString dataType = "esdTree";
1934 if (fInputEventHandler) {
1935 dataType = fInputEventHandler->GetDataType();
1939 chain = fGridHandler->GetChainForTestMode(dataType);
1941 Error("StartAnalysis", "No chain for test mode. Aborting.");
1944 cout << "===== RUNNING LOCAL ANALYSIS" << GetName() << " ON CHAIN " << chain->GetName() << endl;
1945 retv = chain->Process(fSelector, "", nentries, firstentry);
1948 // Run tree-based analysis via AliAnalysisSelector
1949 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
1950 retv = tree->Process(fSelector, "", nentries, firstentry);
1952 case kProofAnalysis:
1954 // Check if the plugin is used
1956 return StartAnalysis(type, fGridHandler->GetProofDataSet(), nentries, firstentry);
1958 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1959 Error("StartAnalysis", "No PROOF!!! Exiting.");
1960 if (cdir) cdir->cd();
1963 line = Form("gProof->AddInput((TObject*)%p);", this);
1964 gROOT->ProcessLine(line);
1967 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
1968 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
1970 Error("StartAnalysis", "No chain!!! Exiting.");
1971 if (cdir) cdir->cd();
1977 if (!anaType.Contains("terminate")) {
1978 if (!fGridHandler) {
1979 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1980 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1981 if (cdir) cdir->cd();
1984 // Write analysis manager in the analysis file
1985 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1986 // Start the analysis via the handler
1987 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1988 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1989 if (cdir) cdir->cd();
1993 // Terminate grid analysis
1994 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1995 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1996 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1997 if (!fGridHandler->MergeOutputs()) {
1998 // Return if outputs could not be merged or if it alien handler
1999 // was configured for offline mode or local testing.
2000 if (cdir) cdir->cd();
2004 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
2005 ImportWrappers(NULL);
2007 if (cdir) cdir->cd();
2009 case kMixingAnalysis:
2010 // Run event mixing analysis
2012 Error("StartAnalysis", "Cannot run event mixing without event pool");
2013 if (cdir) cdir->cd();
2016 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
2017 fSelector = new AliAnalysisSelector(this);
2018 while ((chain=fEventPool->GetNextChain())) {
2020 // Call NotifyBinChange for all tasks
2021 while ((task=(AliAnalysisTask*)next()))
2022 if (!task->IsPostEventLoop()) task->NotifyBinChange();
2023 retv = chain->Process(fSelector);
2025 Error("StartAnalysis", "Mixing analysis failed");
2026 if (cdir) cdir->cd();
2030 PackOutput(fSelector->GetOutputList());
2033 if (cdir) cdir->cd();
2037 //______________________________________________________________________________
2038 Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
2040 // Start analysis for this manager on a given dataset. Analysis task can be:
2041 // LOCAL, PROOF or GRID. Process nentries starting from firstentry.
2043 Error("StartAnalysis","Analysis manager was not initialized !");
2047 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
2048 TString anaType = type;
2050 if (!anaType.Contains("proof")) {
2051 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
2054 fMode = kProofAnalysis;
2056 TString proofProcessOpt;
2057 SetEventLoop(kTRUE);
2058 // Set the dataset flag
2059 TObject::SetBit(kUseDataSet);
2062 // Start proof analysis using the grid handler
2063 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
2064 Error("StartAnalysis", "The grid plugin could not start PROOF analysis");
2067 // Check if the plugin is in test mode
2068 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kTest) {
2069 dataset = "test_collection";
2071 dataset = fGridHandler->GetProofDataSet();
2074 proofProcessOpt = fGridHandler->GetProofProcessOpt();
2077 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
2078 Error("StartAnalysis", "No PROOF!!! Exiting.");
2082 // Initialize locally all tasks
2085 line = Form("gProof->AddInput((TObject*)%p);", this);
2086 gROOT->ProcessLine(line);
2088 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"%s\", %lld, %lld);",
2089 dataset,proofProcessOpt.Data(), nentries, firstentry);
2090 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
2091 retv = (Long_t)gROOT->ProcessLine(line);
2095 //______________________________________________________________________________
2096 TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
2098 // Opens according the option the file specified by cont->GetFileName() and changes
2099 // current directory to cont->GetFolderName(). If the file was already opened, it
2100 // checks if the option UPDATE was preserved. File open via TProofOutputFile can
2101 // be optionally ignored.
2102 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2103 TString filename = cont->GetFileName();
2105 if (filename.IsNull()) {
2106 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
2109 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
2111 f = mgr->OpenProofFile(cont,option);
2113 // Check first if the file is already opened
2114 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2116 // Check if option "UPDATE" was preserved
2117 TString opt(option);
2119 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2120 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2122 f = TFile::Open(filename, option);
2125 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2129 // Check for a folder request
2130 TString dir = cont->GetFolderName();
2131 if (!dir.IsNull()) {
2132 if (!f->GetDirectory(dir)) f->mkdir(dir);
2137 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
2138 cont->SetFile(NULL);
2142 //______________________________________________________________________________
2143 TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option, const char *extaod)
2145 // Opens a special output file used in PROOF.
2147 TString filename = cont->GetFileName();
2148 if (cont == fCommonOutput) {
2149 if (fOutputEventHandler) {
2150 if (strlen(extaod)) filename = extaod;
2151 filename = fOutputEventHandler->GetOutputFileName();
2153 else Fatal("OpenProofFile","No output container. Exiting.");
2156 if (fMode!=kProofAnalysis || !fSelector) {
2157 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
2160 if (fSpecialOutputLocation.Length()) {
2161 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2163 // Check if option "UPDATE" was preserved
2164 TString opt(option);
2166 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2167 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2169 f = new TFile(filename, option);
2171 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2175 // Check for a folder request
2176 TString dir = cont->GetFolderName();
2178 if (!f->GetDirectory(dir)) f->mkdir(dir);
2183 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2184 cont->SetFile(NULL);
2187 // Check if there is already a proof output file in the output list
2188 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
2190 // Get the actual file
2191 line = Form("((TProofOutputFile*)%p)->GetFileName();", pof);
2192 filename = (const char*)gROOT->ProcessLine(line);
2194 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
2196 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2198 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
2201 // Check if option "UPDATE" was preserved
2202 TString opt(option);
2204 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2205 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
2207 if (cont->IsRegisterDataset()) {
2208 TString dsetName = filename;
2209 dsetName.ReplaceAll(".root", cont->GetTitle());
2210 dsetName.ReplaceAll(":","_");
2211 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
2212 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
2214 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
2215 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
2217 if (fDebug > 1) printf("=== %s\n", line.Data());
2218 gROOT->ProcessLine(line);
2219 line = Form("pf->OpenFile(\"%s\");", option);
2220 gROOT->ProcessLine(line);
2223 gROOT->ProcessLine("pf->Print()");
2224 printf(" == proof file name: %s", f->GetName());
2226 // Add to proof output list
2227 line = Form("((TList*)%p)->Add(pf);",fSelector->GetOutputList());
2228 if (fDebug > 1) printf("=== %s\n", line.Data());
2229 gROOT->ProcessLine(line);
2231 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2235 // Check for a folder request
2236 TString dir = cont->GetFolderName();
2237 if (!dir.IsNull()) {
2238 if (!f->GetDirectory(dir)) f->mkdir(dir);
2243 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2244 cont->SetFile(NULL);
2248 //______________________________________________________________________________
2249 void AliAnalysisManager::ExecAnalysis(Option_t *option)
2251 // Execute analysis.
2252 static Long64_t nentries = 0;
2253 static TTree *lastTree = 0;
2254 static TStopwatch *timer = new TStopwatch();
2255 // Only the first call to Process will trigger a true Notify. Other Notify
2256 // coming before is ignored.
2257 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) {
2258 TObject::SetBit(AliAnalysisManager::kTrueNotify);
2261 if (fDebug > 0) printf("MGR: Processing event #%d\n", fNcalls);
2263 if (fTree && (fTree != lastTree)) {
2264 nentries += fTree->GetEntries();
2267 if (!fNcalls) timer->Start();
2268 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", fNcalls, TMath::Min(fMaxEntries,nentries), timer, kFALSE);
2270 fIOTimer->Start(kTRUE);
2272 TDirectory *cdir = gDirectory;
2273 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
2274 if (getsysInfo && ((fNcalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)fNcalls);
2276 Error("ExecAnalysis", "Analysis manager was not initialized !");
2277 if (cdir) cdir->cd();
2281 AliAnalysisTask *task;
2282 // Reset the analysis
2284 // Check if the top tree is active.
2286 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2287 AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
2289 // De-activate all tasks (not needed anymore after ResetAnalysis
2290 // while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
2291 AliAnalysisDataContainer *cont = fCommonInput;
2292 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
2294 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
2295 if (cdir) cdir->cd();
2298 cont->SetData(fTree); // This set activity for all tasks reading only from the top container
2299 Long64_t entry = fTree->GetTree()->GetReadEntry();
2301 // Call BeginEvent() for optional input/output and MC services
2302 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
2303 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
2304 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
2306 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2307 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2309 // Execute the tasks
2310 // TIter next1(cont->GetConsumers());
2312 fIOTime += fIOTimer->RealTime();
2313 fCPUTimer->Start(kTRUE);
2314 TIter next1(fTopTasks);
2316 while ((task=(AliAnalysisTask*)next1())) {
2317 task->SetActive(kTRUE);
2319 cout << " Executing task " << task->GetName() << endl;
2321 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
2322 task->ExecuteTask(option);
2323 if (fStatistics) fStatistics->StopTimer();
2325 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2326 AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
2330 fCPUTime += fCPUTimer->RealTime();
2331 fIOTimer->Start(kTRUE);
2333 // Call FinishEvent() for optional output and MC services
2334 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2335 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2336 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2337 // Gather system information if requested
2338 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2339 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1001, 1);
2340 if (cdir) cdir->cd();
2342 fIOTime += fIOTimer->RealTime();
2345 // The event loop is not controlled by TSelector
2347 // Call BeginEvent() for optional input/output and MC services
2348 fIOTimer->Start(kTRUE);
2349 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
2350 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
2351 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
2353 fIOTime += fIOTimer->RealTime();
2355 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2356 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2357 fCPUTimer->Start(kTRUE);
2358 TIter next2(fTopTasks);
2359 while ((task=(AliAnalysisTask*)next2())) {
2360 task->SetActive(kTRUE);
2362 cout << " Executing task " << task->GetName() << endl;
2364 if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
2365 task->ExecuteTask(option);
2366 if (fStatistics) fStatistics->StopTimer();
2370 fCPUTime += fCPUTimer->RealTime();
2372 // Call FinishEvent() for optional output and MC services
2373 fIOTimer->Start(kTRUE);
2374 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2375 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2376 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2377 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2378 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
2379 if (cdir) cdir->cd();
2381 fIOTime += fIOTimer->RealTime();
2384 //______________________________________________________________________________
2385 Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
2387 // Check if the stdout is connected to a pipe (C.Holm)
2388 Bool_t ispipe = kFALSE;
2389 out.seekp(0, std::ios_base::cur);
2392 if (errno == ESPIPE) ispipe = kTRUE;
2397 //______________________________________________________________________________
2398 void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
2400 // Set the input event handler and create a container for it.
2402 fInputEventHandler = handler;
2403 if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
2406 //______________________________________________________________________________
2407 void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
2409 // Set the input event handler and create a container for it.
2411 fOutputEventHandler = handler;
2412 if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
2413 fCommonOutput->SetSpecialOutput();
2416 //______________________________________________________________________________
2417 void AliAnalysisManager::SetDebugLevel(UInt_t level)
2419 // Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
2420 if (TObject::TestBit(kUseProgressBar)) {
2421 Info("SetDebugLevel","Ignored. Disable the progress bar first.");
2427 //______________________________________________________________________________
2428 void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
2430 // Enable a text mode progress bar. Resets debug level to 0.
2431 Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
2432 TObject::SetBit(kUseProgressBar,flag);
2433 fPBUpdateFreq = freq;
2437 //______________________________________________________________________________
2438 void AliAnalysisManager::RegisterExtraFile(const char *fname)
2440 // This method is used externally to register output files which are not
2441 // connected to any output container, so that the manager can properly register,
2442 // retrieve or merge them when running in distributed mode. The file names are
2443 // separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
2444 if (fExtraFiles.Contains(fname)) return;
2445 if (fExtraFiles.Length()) fExtraFiles += " ";
2446 fExtraFiles += fname;
2449 //______________________________________________________________________________
2450 Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
2452 // Copy a file from the location specified ina the wrapper with the same name from the source list.
2456 TObject *pof = source->FindObject(filename);
2457 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
2458 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
2461 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
2462 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
2463 TString clientUrl(chUrl);
2464 TString fullPath_str(fullPath);
2465 if (clientUrl.Contains("localhost")){
2466 TObjArray* array = fullPath_str.Tokenize ( "//" );
2467 TObjString *strobj = ( TObjString *)array->At(1);
2468 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
2469 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
2470 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
2471 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
2472 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
2476 else if (clientUrl.Contains("__lite__")) {
2477 // Special case for ProofLite environement - get file info and copy.
2478 gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
2479 fullPath_str = Form("%s/%s", tmp, fullPath);
2482 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
2483 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
2485 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
2489 //______________________________________________________________________________
2490 void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
2492 // Fill analysis type in the provided string.
2494 case kLocalAnalysis:
2497 case kProofAnalysis:
2503 case kMixingAnalysis:
2508 //______________________________________________________________________________
2509 Bool_t AliAnalysisManager::ValidateOutputFiles() const
2511 // Validate all output files.
2512 TIter next(fOutputs);
2513 AliAnalysisDataContainer *output;
2514 TDirectory *cdir = gDirectory;
2515 TString openedFiles;
2516 while ((output=(AliAnalysisDataContainer*)next())) {
2517 if (output->IsRegisterDataset()) continue;
2518 TString filename = output->GetFileName();
2519 if (filename == "default") {
2520 if (!fOutputEventHandler) continue;
2521 filename = fOutputEventHandler->GetOutputFileName();
2522 // Main AOD may not be there
2523 if (gSystem->AccessPathName(filename)) continue;
2525 // Check if the file is closed
2526 if (openedFiles.Contains(filename)) continue;;
2527 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2529 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
2530 // Clear file list to release object ownership to user.
2534 file = TFile::Open(filename);
2535 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
2536 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
2537 if (cdir) cdir->cd();
2541 openedFiles += filename;
2544 if (cdir) cdir->cd();
2548 //______________________________________________________________________________
2549 void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
2551 // Implements a nice text mode progress bar.
2552 static Long64_t icount = 0;
2553 static TString oname;
2554 static TString nname;
2555 static Long64_t ocurrent = 0;
2556 static Long64_t osize = 0;
2557 static Int_t oseconds = 0;
2558 static TStopwatch *owatch = 0;
2559 static Bool_t oneoftwo = kFALSE;
2560 static Int_t nrefresh = 0;
2561 static Int_t nchecks = 0;
2562 static char lastChar = 0;
2563 const char symbol[4] = {'-','\\','|','/'};
2565 if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
2571 ocurrent = TMath::Abs(current);
2572 osize = TMath::Abs(size);
2573 if (ocurrent > osize) ocurrent=osize;
2578 if ((current % fPBUpdateFreq) != 0) return;
2580 char progress[11] = " ";
2581 Int_t ichar = icount%4;
2586 if (owatch && !last) {
2588 time = owatch->RealTime();
2589 seconds = int(time) % 60;
2590 minutes = (int(time) / 60) % 60;
2591 hours = (int(time) / 60 / 60);
2593 if (oseconds==seconds) {
2597 oneoftwo = !oneoftwo;
2601 if (refresh && oneoftwo) {
2603 if (nchecks <= 0) nchecks = nrefresh+1;
2604 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
2605 oname = Form(" == %d%% ==", pctdone);
2607 Double_t percent = 100.0*ocurrent/osize;
2608 Int_t nchar = Int_t(percent/10);
2609 if (nchar>10) nchar=10;
2611 for (i=0; i<nchar; i++) progress[i] = '=';
2612 progress[nchar] = symbol[ichar];
2613 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2614 progress[10] = '\0';
2617 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2618 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2619 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
2621 Int_t full = Int_t(ocurrent > 0 ?
2622 time * (float(osize)/ocurrent) + .5 :
2624 Int_t remain = Int_t(full - time);
2625 Int_t rsec = remain % 60;
2626 Int_t rmin = (remain / 60) % 60;
2627 Int_t rhour = (remain / 60 / 60);
2628 fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
2629 percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
2631 else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
2632 if (refresh && oneoftwo) oname = nname;
2633 if (owatch) owatch->Continue();
2642 fprintf(stderr, "\n");
2646 //______________________________________________________________________________
2647 void AliAnalysisManager::DoLoadBranch(const char *name)
2649 // Get tree and load branch if needed.
2650 static Long64_t crtEntry = -100;
2652 if (fAutoBranchHandling || !fTree)
2655 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2657 br = fTree->GetBranch(name);
2659 Error("DoLoadBranch", "Could not find branch %s",name);
2664 if (br->GetReadEntry()==fCurrentEntry) return;
2665 Long64_t readbytes = br->GetEntry(GetCurrentEntry());
2667 Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
2668 if (crtEntry != fCurrentEntry) {
2669 CountEvent(1,0,1,0);
2670 crtEntry = fCurrentEntry;
2673 if (crtEntry != fCurrentEntry) {
2674 CountEvent(1,1,0,0);
2675 crtEntry = fCurrentEntry;
2680 //______________________________________________________________________________
2681 void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
2683 // Add the statistics task to the manager.
2685 Info("AddStatisticsTask", "Already added");
2688 TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
2689 gROOT->ProcessLine(line);
2692 //______________________________________________________________________________
2693 void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
2695 // Bookkeep current event;
2696 if (!fStatistics) return;
2697 fStatistics->AddInput(ninput);
2698 fStatistics->AddProcessed(nprocessed);
2699 fStatistics->AddFailed(nfailed);
2700 fStatistics->AddAccepted(naccepted);
2703 //______________________________________________________________________________
2704 void AliAnalysisManager::AddStatisticsMsg(const char *line)
2706 // Add a line in the statistics message. If available, the statistics message is written
2707 // at the end of the SlaveTerminate phase on workers AND at the end of Terminate
2709 if (!strlen(line)) return;
2710 if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
2711 fStatisticsMsg += line;
2714 //______________________________________________________________________________
2715 void AliAnalysisManager::WriteStatisticsMsg(Int_t)
2717 // If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
2718 static Bool_t done = kFALSE;
2721 if (!fStatistics) return;
2723 AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
2724 AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
2725 AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
2726 AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
2727 out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
2728 fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
2729 fStatistics->GetNaccepted()), ios::out);
2730 out << fStatisticsMsg << endl;
2734 //______________________________________________________________________________
2735 const char* AliAnalysisManager::GetOADBPath()
2737 // returns the path of the OADB
2738 // this static function just depends on environment variables
2740 static TString oadbPath;
2742 if (gSystem->Getenv("OADB_PATH"))
2743 oadbPath = gSystem->Getenv("OADB_PATH");
2744 else if (gSystem->Getenv("ALICE_ROOT"))
2745 oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
2747 ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
2752 //______________________________________________________________________________
2753 void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
2755 // Define a custom string variable mapped to a global unique name. The variable
2756 // can be then retrieved by a given analysis macro via GetGlobalStr(key).
2757 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2759 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2762 Bool_t valid = kFALSE;
2763 TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
2765 ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
2768 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
2771 //______________________________________________________________________________
2772 const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
2774 // Static method to retrieve a global variable defined via SetGlobalStr.
2776 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2778 TObject *value = mgr->GetGlobals()->GetValue(key);
2779 if (!value) return 0;
2781 return value->GetName();
2784 //______________________________________________________________________________
2785 void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
2787 // Define a custom integer variable mapped to a global unique name. The variable
2788 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2789 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2791 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2794 Bool_t valid = kFALSE;
2795 Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
2797 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
2800 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
2803 //______________________________________________________________________________
2804 Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
2806 // Static method to retrieve a global variable defined via SetGlobalInt.
2808 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2810 TObject *value = mgr->GetGlobals()->GetValue(key);
2811 if (!value) return 0;
2813 TString s = value->GetName();
2817 //______________________________________________________________________________
2818 void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
2820 // Define a custom double precision variable mapped to a global unique name. The variable
2821 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2822 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2824 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2827 Bool_t valid = kFALSE;
2828 Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
2830 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
2833 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));
2836 //______________________________________________________________________________
2837 Double_t AliAnalysisManager::GetGlobalDbl(const char *key, Bool_t &valid)
2839 // Static method to retrieve a global variable defined via SetGlobalDbl.
2841 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2843 TObject *value = mgr->GetGlobals()->GetValue(key);
2844 if (!value) return 0;
2846 TString s = value->GetName();
2850 //______________________________________________________________________________
2851 void AliAnalysisManager::AddClassDebug(const char *className, Int_t debugLevel)
2853 // Sets Class debug level
2855 if (!fDebugOptions) {
2856 fDebugOptions = new TObjArray();
2857 fDebugOptions->SetOwner(kTRUE);
2860 TNamed *debugOpt = (TNamed*)fDebugOptions->FindObject(className);
2862 AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel,className).Data());
2863 fDebugOptions->Add(new TNamed(className,TString::Format("%d",debugLevel).Data()));
2865 TString oldDebugStr = debugOpt->GetTitle();
2866 Int_t oldDebug = oldDebugStr.Atoi();
2867 if (debugLevel > oldDebug) {
2868 AliWarning(TString::Format("Overwriting debug level to %d class %s, because it is higher then previously set (%d).",debugLevel,className,oldDebug).Data());
2869 debugOpt->SetTitle(TString::Format("%d",debugLevel).Data());
2871 AliWarning(TString::Format("Ignoring debug level to %d class %s, because it is smaller then previously set (%d).",debugLevel,className,oldDebug).Data());
2876 //______________________________________________________________________________
2877 void AliAnalysisManager::ApplyDebugOptions()
2879 // Apply debug options
2881 if (!fDebugOptions) return;
2883 TIter next(fDebugOptions);
2886 while ((debug=dynamic_cast<TNamed*>(next()))) {
2887 debugLevel = debug->GetTitle();
2888 AliInfo(TString::Format("Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()).Data());
2889 AliLog::SetClassDebugLevel(debug->GetName(), debugLevel.Atoi());
2893 //______________________________________________________________________________
2894 Bool_t AliAnalysisManager::IsMacroLoaded(const char * filename)
2896 // Check if a macro was loaded.
2897 return fgMacroNames.Contains(filename);
2900 //______________________________________________________________________________
2901 Int_t AliAnalysisManager::LoadMacro(const char *filename, Int_t *error, Bool_t check)
2903 // Redirection of gROOT->LoadMacro which makes sure the same macro is not loaded
2905 TString macroName = gSystem->BaseName(filename);
2906 // Strip appended +, ++, +g, +O
2907 Int_t index = macroName.Index("+");
2908 if (index>0) macroName.Remove(index);
2909 if (fgMacroNames.Contains(macroName)) {
2910 // Macro with the same name loaded already in this root session, do
2915 Int_t ret = gROOT->LoadMacro(filename,error,check);
2916 // In case of error return the error code
2917 if (ret) return ret;
2918 // Append the macro name to the loaded macros list
2919 fgMacroNames += macroName;
2920 fgMacroNames += " ";
2924 //______________________________________________________________________________
2925 void AliAnalysisManager::Lock()
2927 // Security lock. This is to detect NORMAL user errors and not really to
2928 // protect against intentional hacks.
2929 if (fLocked) return;
2931 if (fInputEventHandler) fInputEventHandler->Lock();
2932 if (fOutputEventHandler) fOutputEventHandler->Lock();
2933 if (fMCtruthEventHandler) fMCtruthEventHandler->Lock();
2934 Info("Lock","====== ANALYSIS MANAGER LOCKED ======");
2937 //______________________________________________________________________________
2938 void AliAnalysisManager::UnLock()
2940 // Verbose unlocking. Hackers will be punished ;-) ...
2941 if (!fLocked) return;
2943 if (fInputEventHandler) fInputEventHandler->UnLock();
2944 if (fOutputEventHandler) fOutputEventHandler->UnLock();
2945 if (fMCtruthEventHandler) fMCtruthEventHandler->UnLock();
2946 Info("UnLock", "====== ANALYSIS MANAGER UNLOCKED ======");
2949 //______________________________________________________________________________
2950 void AliAnalysisManager::Changed()
2952 // All critical setters pass through the Changed method that throws an exception
2953 // in case the lock was set.
2954 if (fLocked) Fatal("Changed","Critical setter called in locked mode");