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 Int_t AliAnalysisManager::fPBUpdateFreq = 1;
68 //______________________________________________________________________________
69 AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
72 fInputEventHandler(0),
73 fOutputEventHandler(0),
74 fMCtruthEventHandler(0),
78 fMode(kLocalAnalysis),
84 fSpecialOutputLocation(""),
93 fFileDescriptors(new TObjArray()),
94 fCurrentDescriptor(0),
101 fAutoBranchHandling(kTRUE),
102 fAsyncReading(kTRUE), // default prefetching on
107 fCacheSize(100000000), // default 100 MB
109 fRequestedBranches(),
119 // Default constructor.
120 fgAnalysisManager = this;
121 fgCommonFileName = "AnalysisResults.root";
122 if (TClass::IsCallingNew() != TClass::kDummyNew) {
123 fTasks = new TObjArray();
124 fTopTasks = new TObjArray();
125 fZombies = new TObjArray();
126 fContainers = new TObjArray();
127 fInputs = new TObjArray();
128 fOutputs = new TObjArray();
129 fParamCont = new TObjArray();
130 fGlobals = new TMap();
132 fIOTimer = new TStopwatch();
133 fCPUTimer = new TStopwatch();
134 fInitTimer = new TStopwatch();
138 //______________________________________________________________________________
139 AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
142 fInputEventHandler(NULL),
143 fOutputEventHandler(NULL),
144 fMCtruthEventHandler(NULL),
149 fInitOK(other.fInitOK),
150 fMustClean(other.fMustClean),
151 fIsRemote(other.fIsRemote),
152 fLocked(other.fLocked),
153 fDebug(other.fDebug),
154 fSpecialOutputLocation(""),
163 fFileDescriptors(new TObjArray()),
164 fCurrentDescriptor(0),
169 fExtraFiles(other.fExtraFiles),
170 fFileInfoLog(other.fFileInfoLog),
171 fAutoBranchHandling(other.fAutoBranchHandling),
172 fAsyncReading(other.fAsyncReading),
175 fNcalls(other.fNcalls),
176 fMaxEntries(other.fMaxEntries),
177 fCacheSize(other.fCacheSize),
178 fStatisticsMsg(other.fStatisticsMsg),
179 fRequestedBranches(other.fRequestedBranches),
180 fStatistics(other.fStatistics),
181 fGlobals(other.fGlobals),
182 fIOTimer(new TStopwatch()),
183 fCPUTimer(new TStopwatch()),
184 fInitTimer(new TStopwatch()),
190 fTasks = new TObjArray(*other.fTasks);
191 fTopTasks = new TObjArray(*other.fTopTasks);
192 fZombies = new TObjArray(*other.fZombies);
193 fContainers = new TObjArray(*other.fContainers);
194 fInputs = new TObjArray(*other.fInputs);
195 fOutputs = new TObjArray(*other.fOutputs);
196 fParamCont = new TObjArray(*other.fParamCont);
197 fgCommonFileName = "AnalysisResults.root";
198 fgAnalysisManager = this;
201 //______________________________________________________________________________
202 AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& other)
205 if (&other != this) {
206 TNamed::operator=(other);
207 fInputEventHandler = other.fInputEventHandler;
208 fOutputEventHandler = other.fOutputEventHandler;
209 fMCtruthEventHandler = other.fMCtruthEventHandler;
210 fEventPool = other.fEventPool;
213 fNSysInfo = other.fNSysInfo;
215 fInitOK = other.fInitOK;
216 fIsRemote = other.fIsRemote;
217 fLocked = other.fLocked;
218 fDebug = other.fDebug;
219 fTasks = new TObjArray(*other.fTasks);
220 fTopTasks = new TObjArray(*other.fTopTasks);
221 fZombies = new TObjArray(*other.fZombies);
222 fContainers = new TObjArray(*other.fContainers);
223 fInputs = new TObjArray(*other.fInputs);
224 fOutputs = new TObjArray(*other.fOutputs);
225 fParamCont = new TObjArray(*other.fParamCont);
226 fDebugOptions = NULL;
227 fFileDescriptors = new TObjArray();
228 fCurrentDescriptor = 0;
230 fCommonOutput = NULL;
233 fExtraFiles = other.fExtraFiles;
234 fFileInfoLog = other.fFileInfoLog;
235 fgCommonFileName = "AnalysisResults.root";
236 fgAnalysisManager = this;
237 fAutoBranchHandling = other.fAutoBranchHandling;
238 fAsyncReading = other.fAsyncReading;
239 fTable.Clear("nodelete");
240 fRunFromPath = other.fRunFromPath;
241 fNcalls = other. fNcalls;
242 fMaxEntries = other.fMaxEntries;
243 fCacheSize = other.fCacheSize;
244 fStatisticsMsg = other.fStatisticsMsg;
245 fRequestedBranches = other.fRequestedBranches;
246 fStatistics = other.fStatistics;
247 fGlobals = new TMap();
248 fIOTimer = new TStopwatch();
249 fCPUTimer = new TStopwatch();
250 fInitTimer = new TStopwatch();
258 //______________________________________________________________________________
259 AliAnalysisManager::~AliAnalysisManager()
262 if (fTasks) {fTasks->Delete(); delete fTasks;}
263 if (fTopTasks) delete fTopTasks;
264 if (fZombies) delete fZombies;
265 if (fContainers) {fContainers->Delete(); delete fContainers;}
266 if (fInputs) delete fInputs;
267 if (fOutputs) delete fOutputs;
268 if (fParamCont) delete fParamCont;
269 if (fDebugOptions) delete fDebugOptions;
270 if (fGridHandler) delete fGridHandler;
271 if (fInputEventHandler) delete fInputEventHandler;
272 if (fOutputEventHandler) delete fOutputEventHandler;
273 if (fMCtruthEventHandler) delete fMCtruthEventHandler;
274 if (fEventPool) delete fEventPool;
275 if (fgAnalysisManager==this) fgAnalysisManager = NULL;
276 if (fGlobals) {fGlobals->DeleteAll(); delete fGlobals;}
277 if (fFileDescriptors) {fFileDescriptors->Delete(); delete fFileDescriptors;}
283 //______________________________________________________________________________
284 void AliAnalysisManager::CreateReadCache()
286 // Create cache for reading according fCacheSize and fAsyncReading.
287 if (!fTree || !fTree->GetCurrentFile()) {
288 Error("CreateReadCache","Current tree or tree file not yet defined");
292 if (fDebug) Info("CreateReadCache","=== Read caching disabled ===");
295 // gEnv->SetValue("TFile.AsyncPrefetching",(Int_t)fAsyncReading);
296 // if (fAsyncReading) gEnv->SetValue("Cache.Directory",Form("file://%s/cache", gSystem->WorkingDirectory()));
297 if (fAsyncReading) gEnv->SetValue("TFile.AsyncReading",1);
298 fTree->SetCacheSize(fCacheSize);
299 TTreeCache::SetLearnEntries(1); //<<< we can take the decision after 1 entry
300 fTree->AddBranchToCache("*",kTRUE); //<<< add all branches to the cache
302 Info("CreateReadCache","Read cache enabled %lld bytes with async reading=%d",fCacheSize, (Int_t)fAsyncReading);
307 //______________________________________________________________________________
308 Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
310 // Read one entry of the tree or a whole branch.
311 fCurrentEntry = entry;
312 if (!fAutoBranchHandling)
314 if (!fTree) return -1;
315 fIOTimer->Start(kTRUE);
316 Long64_t readbytes = fTree->GetTree()->GetEntry(entry, getall);
318 fIOTime += fIOTimer->RealTime();
319 return (Int_t)readbytes;
322 //______________________________________________________________________________
323 Int_t AliAnalysisManager::GetRunFromAlienPath(const char *path)
325 // Attempt to extract run number from input data path. Works only for paths to
326 // alice data in alien.
327 // sim: /alice/sim/<production>/run_no/...
328 // data: /alice/data/year/period/000run_no/... (ESD or AOD)
329 TString type = "unknown";
331 if (s.Contains("/alice/data")) type = "real";
332 else if (s.Contains("/alice/sim")) type = "simulated";
335 ind1 = s.Index("/00");
337 ind2 = s.Index("/",ind1+1);
338 if (ind2-ind1>8) srun = s(ind1+1, ind2-ind1-1);
341 ind1 = s.Index("/LHC");
343 ind1 = s.Index("/",ind1+1);
345 ind2 = s.Index("/",ind1+1);
346 if (ind2>0) srun = s(ind1+1, ind2-ind1-1);
350 Int_t run = srun.Atoi();
351 if (run>0) printf("=== GetRunFromAlienPath: run %d of %s data ===\n", run, type.Data());
355 //______________________________________________________________________________
356 Bool_t AliAnalysisManager::Init(TTree *tree)
358 // The Init() function is called when the selector needs to initialize
359 // a new tree or chain. Typically here the branch addresses of the tree
360 // will be set. It is normaly not necessary to make changes to the
361 // generated code, but the routine can be extended by the user if needed.
362 // Init() will be called many times when running with PROOF.
363 Bool_t init = kFALSE;
364 if (!tree) return kFALSE; // Should not happen - protected in selector caller
366 printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
368 // Call InitTree of EventHandler
369 if (fOutputEventHandler) {
370 if (fMode == kProofAnalysis) {
371 init = fOutputEventHandler->Init(0x0, "proof");
373 init = fOutputEventHandler->Init(0x0, "local");
376 Error("Init", "Output event handler failed to initialize");
381 if (fInputEventHandler) {
382 if (fMode == kProofAnalysis) {
383 init = fInputEventHandler->Init(tree, "proof");
385 init = fInputEventHandler->Init(tree, "local");
388 Error("Init", "Input event handler failed to initialize tree");
392 // If no input event handler we need to get the tree once
394 if(!tree->GetTree()) {
395 Long64_t readEntry = tree->LoadTree(0);
396 if (readEntry == -2) {
397 Error("Init", "Input tree has no entry. Exiting");
403 if (fMCtruthEventHandler) {
404 if (fMode == kProofAnalysis) {
405 init = fMCtruthEventHandler->Init(0x0, "proof");
407 init = fMCtruthEventHandler->Init(0x0, "local");
410 Error("Init", "MC event handler failed to initialize");
415 if (!fInitOK) InitAnalysis();
416 if (!fInitOK) return kFALSE;
418 if (fMode != kProofAnalysis) CreateReadCache();
420 AliAnalysisDataContainer *top = fCommonInput;
421 if (!top) top = (AliAnalysisDataContainer*)fInputs->At(0);
423 Error("Init","No top input container !");
427 CheckBranches(kFALSE);
429 printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
434 //______________________________________________________________________________
435 void AliAnalysisManager::SlaveBegin(TTree *tree)
437 // The SlaveBegin() function is called after the Begin() function.
438 // When running with PROOF SlaveBegin() is called on each slave server.
439 // The tree argument is deprecated (on PROOF 0 is passed).
440 if (fDebug > 1) printf("->AliAnalysisManager::SlaveBegin()\n");
441 // Init timer should be already started
442 // Apply debug options
445 fMCtruthEventHandler &&
446 (fMode != kProofAnalysis)) fMCtruthEventHandler->SetCacheSize(fCacheSize);
447 if (!CheckTasks()) Fatal("SlaveBegin", "Not all needed libraries were loaded");
448 static Bool_t isCalled = kFALSE;
449 Bool_t init = kFALSE;
450 Bool_t initOK = kTRUE;
452 TDirectory *curdir = gDirectory;
453 // Call SlaveBegin only once in case of mixing
454 if (isCalled && fMode==kMixingAnalysis) return;
456 // Call Init of EventHandler
457 if (fOutputEventHandler) {
458 if (fMode == kProofAnalysis) {
459 // Merging AOD's in PROOF via TProofOutputFile
460 if (fDebug > 1) printf(" Initializing AOD output file %s...\n", fOutputEventHandler->GetOutputFileName());
461 init = fOutputEventHandler->Init("proof");
462 if (!init) msg = "Failed to initialize output handler on worker";
464 init = fOutputEventHandler->Init("local");
465 if (!init) msg = "Failed to initialize output handler";
468 if (!fSelector) Error("SlaveBegin", "Selector not set");
469 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
472 if (fInputEventHandler) {
473 fInputEventHandler->SetInputTree(tree);
474 if (fMode == kProofAnalysis) {
475 init = fInputEventHandler->Init("proof");
476 if (!init) msg = "Failed to initialize input handler on worker";
478 init = fInputEventHandler->Init("local");
479 if (!init) msg = "Failed to initialize input handler";
482 if (!fSelector) Error("SlaveBegin", "Selector not set");
483 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
486 if (fMCtruthEventHandler) {
487 if (fMode == kProofAnalysis) {
488 init = fMCtruthEventHandler->Init("proof");
489 if (!init) msg = "Failed to initialize MC handler on worker";
491 init = fMCtruthEventHandler->Init("local");
492 if (!init) msg = "Failed to initialize MC handler";
495 if (!fSelector) Error("SlaveBegin", "Selector not set");
496 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
498 if (curdir) curdir->cd();
502 AliAnalysisTask *task;
503 // Call CreateOutputObjects for all tasks
504 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
505 Bool_t dirStatus = TH1::AddDirectoryStatus();
507 while ((task=(AliAnalysisTask*)next())) {
509 // Start with memory as current dir and make sure by default histograms do not get attached to files.
510 TH1::AddDirectory(kFALSE);
511 task->CreateOutputObjects();
512 if (!task->CheckPostData()) {
513 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
514 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
515 ####### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ##########", task->GetName(), task->ClassName());
517 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
520 TH1::AddDirectory(dirStatus);
521 if (curdir) curdir->cd();
523 fInitTime += fInitTimer->RealTime();
524 fInitTimer->Continue();
525 printf("Initialization time: %g [sec]\n", fInitTime);
526 if (fDebug > 1) printf("<-AliAnalysisManager::SlaveBegin()\n");
529 //______________________________________________________________________________
530 Bool_t AliAnalysisManager::Notify()
532 // The Notify() function is called when a new file is opened. This
533 // can be either for a new TTree in a TChain or when when a new TTree
534 // is started when using PROOF. It is normaly not necessary to make changes
535 // to the generated code, but the routine can be extended by the
536 // user if needed. The return value is currently not used.
537 fIOTimer->Start(kTRUE);
538 if (!fTree) return kFALSE;
539 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) return kFALSE;
541 fTable.Clear("nodelete"); // clearing the hash table may not be needed -> C.L.
542 if (fMode == kProofAnalysis) fIsRemote = kTRUE;
544 TFile *curfile = fTree->GetCurrentFile();
546 Error("Notify","No current file");
549 if (IsCollectThroughput()) {
550 if (fCurrentDescriptor) fCurrentDescriptor->Done();
551 fCurrentDescriptor = new AliAnalysisFileDescriptor(curfile);
552 fFileDescriptors->Add(fCurrentDescriptor);
555 if (fDebug > 1) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
556 Int_t run = AliAnalysisManager::GetRunFromAlienPath(curfile->GetName());
557 if (run && (run != fRunFromPath)) {
559 if (fDebug > 1) printf(" ### run found from path: %d\n", run);
562 AliAnalysisTask *task;
564 // Call Notify of the event handlers
565 if (fInputEventHandler) {
566 fInputEventHandler->Notify(curfile->GetName());
569 if (fOutputEventHandler) {
570 fOutputEventHandler->Notify(curfile->GetName());
573 if (fMCtruthEventHandler) {
574 fMCtruthEventHandler->Notify(curfile->GetName());
577 // Call Notify for all tasks
578 while ((task=(AliAnalysisTask*)next()))
581 if (fDebug > 1) printf("<-AliAnalysisManager::Notify()\n");
583 fIOTime += fIOTimer->RealTime();
587 //______________________________________________________________________________
588 Bool_t AliAnalysisManager::Process(Long64_t)
590 // The Process() function is called for each entry in the tree (or possibly
591 // keyed object in the case of PROOF) to be processed. The entry argument
592 // specifies which entry in the currently loaded tree is to be processed.
593 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
594 // to read either all or the required parts of the data. When processing
595 // keyed objects with PROOF, the object is already loaded and is available
596 // via the fObject pointer.
598 // This function should contain the "body" of the analysis. It can contain
599 // simple or elaborate selection criteria, run algorithms on the data
600 // of the event and typically fill histograms.
602 // WARNING when a selector is used with a TChain, you must use
603 // the pointer to the current TTree to call GetEntry(entry).
604 // The entry is always the local entry number in the current tree.
605 // Assuming that fChain is the pointer to the TChain being processed,
606 // use fChain->GetTree()->GetEntry(entry).
608 // This method is obsolete. ExecAnalysis is called instead.
612 //______________________________________________________________________________
613 void AliAnalysisManager::PackOutput(TList *target)
615 // Pack all output data containers in the output list. Called at SlaveTerminate
616 // stage in PROOF case for each slave.
617 if (fDebug > 1) printf("->AliAnalysisManager::PackOutput()\n");
618 fIOTimer->Start(kTRUE);
620 if (IsCollectThroughput()) {
621 if (fCurrentDescriptor) fCurrentDescriptor->Done();
622 fFileDescriptors->Print();
623 if (fFileInfoLog.IsNull()) fFileInfoLog = "fileinfo.log";
624 out.open(fFileInfoLog, std::ios::app);
625 if (out.bad()) Error("SavePrimitive", "Bad file name: %s", fFileInfoLog.Data());
627 TIter nextflog(fFileDescriptors);
629 while ((log=nextflog())) log->SavePrimitive(out,"");
633 Error("PackOutput", "No target. Exiting.");
636 TDirectory *cdir = gDirectory;
638 if (fInputEventHandler) fInputEventHandler ->Terminate();
639 if (fOutputEventHandler) fOutputEventHandler ->Terminate();
640 if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
643 // Call FinishTaskOutput() for each event loop task (not called for
644 // post-event loop tasks - use Terminate() fo those)
645 TIter nexttask(fTasks);
646 AliAnalysisTask *task;
647 while ((task=(AliAnalysisTask*)nexttask())) {
648 if (!task->IsPostEventLoop()) {
649 if (fDebug > 1) printf("->FinishTaskOutput: task %s\n", task->GetName());
650 task->FinishTaskOutput();
652 if (fDebug > 1) printf("<-FinishTaskOutput: task %s\n", task->GetName());
655 // Write statistics message on the workers.
656 if (fStatistics) WriteStatisticsMsg(fNcalls);
658 if (fMode == kProofAnalysis) {
659 TIter next(fOutputs);
660 AliAnalysisDataContainer *output;
661 Bool_t isManagedByHandler = kFALSE;
664 while ((output=(AliAnalysisDataContainer*)next())) {
665 // Do not consider outputs of post event loop tasks
666 isManagedByHandler = kFALSE;
667 if (output->GetProducer() && output->GetProducer()->IsPostEventLoop()) continue;
668 const char *filename = output->GetFileName();
669 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
670 isManagedByHandler = kTRUE;
671 printf("#### Handler output. Extra: %s\n", fExtraFiles.Data());
672 filename = fOutputEventHandler->GetOutputFileName();
674 // Check if data was posted to this container. If not, issue an error.
675 if (!output->GetData() && !isManagedByHandler) {
676 Error("PackOutput", "No data for output container %s. Forgot to PostData ?", output->GetName());
679 if (!output->IsSpecialOutput()) {
681 if (strlen(filename) && !isManagedByHandler) {
682 // Backup current folder
683 TDirectory *opwd = gDirectory;
684 // File resident outputs.
685 // Check first if the file exists.
686 TString openoption = "RECREATE";
687 Bool_t firsttime = kTRUE;
688 if (filestmp.FindObject(output->GetFileName())) {
691 filestmp.Add(new TNamed(output->GetFileName(),""));
693 if (!gSystem->AccessPathName(output->GetFileName()) && !firsttime) openoption = "UPDATE";
694 // TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
695 // Save data to file, then close.
696 if (output->GetData()->InheritsFrom(TCollection::Class())) {
697 // If data is a collection, we set the name of the collection
698 // as the one of the container and we save as a single key.
699 TCollection *coll = (TCollection*)output->GetData();
700 coll->SetName(output->GetName());
701 // coll->Write(output->GetName(), TObject::kSingleKey);
703 if (output->GetData()->InheritsFrom(TTree::Class())) {
704 TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
705 // Save data to file, then close.
706 TTree *tree = (TTree*)output->GetData();
707 // Check if tree is in memory
708 if (tree->GetDirectory()==gROOT) tree->SetDirectory(gDirectory);
712 // output->GetData()->Write();
715 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
717 // printf(" file %s listing content:\n", filename);
720 // Clear file list to release object ownership to user.
723 output->SetFile(NULL);
724 // Restore current directory
725 if (opwd) opwd->cd();
727 // Memory-resident outputs
728 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
730 AliAnalysisDataWrapper *wrap = 0;
731 if (isManagedByHandler) {
732 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
733 wrap->SetName(output->GetName());
735 else wrap =output->ExportData();
736 // Output wrappers must NOT delete data after merging - the user owns them
737 wrap->SetDeleteData(kFALSE);
740 // Special outputs. The file must be opened and connected to the container.
741 TDirectory *opwd = gDirectory;
742 TFile *file = output->GetFile();
744 AliAnalysisTask *producer = output->GetProducer();
746 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
747 output->GetFileName(), output->GetName(), producer->ClassName());
750 TString outFilename = file->GetName();
751 if (fDebug > 1) printf("PackOutput %s: special output\n", output->GetName());
752 if (isManagedByHandler) {
753 // Terminate IO for files managed by the output handler
754 // file->Write() moved to AOD handler (A.G. 11.01.10)
755 // if (file) file->Write();
756 if (file && fDebug > 2) {
757 printf(" handled file %s listing content:\n", file->GetName());
760 fOutputEventHandler->TerminateIO();
763 // Release object ownership to users after writing data to file
764 if (output->GetData()->InheritsFrom(TCollection::Class())) {
765 // If data is a collection, we set the name of the collection
766 // as the one of the container and we save as a single key.
767 TCollection *coll = (TCollection*)output->GetData();
768 coll->SetName(output->GetName());
769 coll->Write(output->GetName(), TObject::kSingleKey);
771 if (output->GetData()->InheritsFrom(TTree::Class())) {
772 TTree *tree = (TTree*)output->GetData();
773 tree->SetDirectory(file);
776 output->GetData()->Write();
780 printf(" file %s listing content:\n", output->GetFileName());
783 // Clear file list to release object ownership to user.
786 output->SetFile(NULL);
788 // Restore current directory
789 if (opwd) opwd->cd();
790 // Check if a special output location was provided or the output files have to be merged
791 if (strlen(fSpecialOutputLocation.Data())) {
792 TString remote = fSpecialOutputLocation;
794 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
795 if (remote.BeginsWith("alien:")) {
796 gROOT->ProcessLine("TGrid::Connect(\"alien:\", gProofServ->GetUser());");
797 remote += outFilename;
798 remote.ReplaceAll(".root", Form("_%d.root", gid));
800 remote += Form("%s_%d_", gSystem->HostName(), gid);
801 remote += outFilename;
804 Info("PackOutput", "Output file for container %s to be copied \n at: %s. No merging.",
805 output->GetName(), remote.Data());
806 TFile::Cp ( outFilename.Data(), remote.Data() );
807 // Copy extra outputs
808 if (fExtraFiles.Length() && isManagedByHandler) {
809 TObjArray *arr = fExtraFiles.Tokenize(" ");
811 TIter nextfilename(arr);
812 while ((os=(TObjString*)nextfilename())) {
813 outFilename = os->GetString();
814 remote = fSpecialOutputLocation;
816 if (remote.BeginsWith("alien://")) {
817 remote += outFilename;
818 remote.ReplaceAll(".root", Form("_%d.root", gid));
820 remote += Form("%s_%d_", gSystem->HostName(), gid);
821 remote += outFilename;
824 Info("PackOutput", "Extra AOD file %s to be copied \n at: %s. No merging.",
825 outFilename.Data(), remote.Data());
826 TFile::Cp ( outFilename.Data(), remote.Data() );
831 // No special location specified-> use TProofOutputFile as merging utility
832 // The file at this output slot must be opened in CreateOutputObjects
833 if (fDebug > 1) printf(" File for container %s to be merged via file merger...\n", output->GetName());
838 fIOTime += fIOTimer->RealTime();
839 if ((fDebug || IsCollectThroughput())) {
841 fInitTime = fInitTimer->RealTime()-fIOTime-fCPUTime;
842 printf("=Analysis %s= init time: %g[sec]\
843 \n I/O & data mng.: %g [sec]\
844 \n task execution: %g [sec]\
845 \n total time: CPU=%g [sec] REAL=%g[sec]\n",
846 GetName(), fInitTime, fIOTime, fCPUTime, fInitTimer->CpuTime(), fInitTimer->RealTime());
847 if (IsCollectThroughput()) {
848 out << "#summary#########################################################" << endl;
849 out << "train_name " << GetName() << endl;
850 out << "root_time " << fInitTimer->RealTime() << endl;
851 out << "root_cpu " << fInitTimer->CpuTime() << endl;
852 out << "init_time " << fInitTime << endl;
853 out << "io_mng_time " << fIOTime << endl;
854 out << "exec_time " << fCPUTime << endl;
855 TString aliensite = gSystem->Getenv("ALIEN_SITE");
856 out << "alien_site " << aliensite << endl;
858 TString hostname = gSystem->Getenv("ALIEN_HOSTNAME");
859 if (hostname.IsNull()) {
861 gSystem->Exec(Form("hostname -f >> %s", fFileInfoLog.Data()));
863 out << hostname << endl;
868 if (cdir) cdir->cd();
869 if (fDebug > 1) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
872 //______________________________________________________________________________
873 void AliAnalysisManager::ImportWrappers(TList *source)
875 // Import data in output containers from wrappers coming in source.
876 if (fDebug > 1) printf("->AliAnalysisManager::ImportWrappers()\n");
877 fIOTimer->Start(kTRUE);
878 TIter next(fOutputs);
879 AliAnalysisDataContainer *cont;
880 AliAnalysisDataWrapper *wrap;
882 Bool_t inGrid = (fMode == kGridAnalysis)?kTRUE:kFALSE;
883 TDirectory *cdir = gDirectory;
884 while ((cont=(AliAnalysisDataContainer*)next())) {
886 if (cont->GetProducer() && cont->GetProducer()->IsPostEventLoop() && !inGrid) continue;
887 if (cont->IsRegisterDataset()) continue;
888 const char *filename = cont->GetFileName();
889 Bool_t isManagedByHandler = kFALSE;
890 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
891 isManagedByHandler = kTRUE;
892 filename = fOutputEventHandler->GetOutputFileName();
894 if (cont->IsSpecialOutput() || inGrid) {
895 if (strlen(fSpecialOutputLocation.Data())) continue;
896 // Copy merged file from PROOF scratch space.
897 // In case of grid the files are already in the current directory.
899 if (isManagedByHandler && fExtraFiles.Length()) {
900 // Copy extra registered dAOD files.
901 TObjArray *arr = fExtraFiles.Tokenize(" ");
903 TIter nextfilename(arr);
904 while ((os=(TObjString*)nextfilename())) GetFileFromWrapper(os->GetString(), source);
907 if (!GetFileFromWrapper(filename, source)) continue;
909 // Normally we should connect data from the copied file to the
910 // corresponding output container, but it is not obvious how to do this
911 // automatically if several objects in file...
912 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
913 if (!f) f = TFile::Open(filename, "READ");
915 Error("ImportWrappers", "Cannot open file %s in read-only mode", filename);
920 // Cd to the directory pointed by the container
921 TString folder = cont->GetFolderName();
922 if (!folder.IsNull()) f->cd(folder);
923 // Try to fetch first an object having the container name.
924 obj = gDirectory->Get(cont->GetName());
926 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",
927 cont->GetType()->GetName(), cont->GetName(), filename, cont->GetFolderName(), cont->GetName());
930 wrap = new AliAnalysisDataWrapper(obj);
931 wrap->SetDeleteData(kFALSE);
933 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
935 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
940 printf(" Importing data for container %s\n", cont->GetName());
941 if (strlen(filename)) printf(" -> file %s\n", filename);
944 cont->ImportData(wrap);
946 if (cdir) cdir->cd();
948 fIOTime += fIOTimer->RealTime();
949 if (fDebug > 1) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
952 //______________________________________________________________________________
953 void AliAnalysisManager::UnpackOutput(TList *source)
955 // Called by AliAnalysisSelector::Terminate only on the client.
956 fIOTimer->Start(kTRUE);
957 if (fDebug > 1) printf("->AliAnalysisManager::UnpackOutput()\n");
959 Error("UnpackOutput", "No target. Exiting.");
962 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
964 if (fMode == kProofAnalysis) ImportWrappers(source);
966 TIter next(fOutputs);
967 AliAnalysisDataContainer *output;
968 while ((output=(AliAnalysisDataContainer*)next())) {
969 if (!output->GetData()) continue;
970 // Check if there are client tasks that run post event loop
971 if (output->HasConsumers()) {
972 // Disable event loop semaphore
973 output->SetPostEventLoop(kTRUE);
974 TObjArray *list = output->GetConsumers();
975 Int_t ncons = list->GetEntriesFast();
976 for (Int_t i=0; i<ncons; i++) {
977 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
978 task->CheckNotify(kTRUE);
979 // If task is active, execute it
980 if (task->IsPostEventLoop() && task->IsActive()) {
981 if (fDebug > 1) printf("== Executing post event loop task %s\n", task->GetName());
988 fIOTime += fIOTimer->RealTime();
989 if (fDebug > 1) printf("<-AliAnalysisManager::UnpackOutput()\n");
992 //______________________________________________________________________________
993 void AliAnalysisManager::Terminate()
995 // The Terminate() function is the last function to be called during
996 // a query. It always runs on the client, it can be used to present
997 // the results graphically.
998 if (fDebug > 1) printf("->AliAnalysisManager::Terminate()\n");
999 fInitTimer->Start(kTRUE);
1000 TDirectory *cdir = gDirectory;
1002 AliAnalysisTask *task;
1003 AliAnalysisDataContainer *output;
1006 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1007 // Call Terminate() for tasks
1009 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
1010 // Save all the canvases produced by the Terminate
1011 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
1015 AliSysInfo::AddStamp(Form("%s_TERMINATE",task->ClassName()),0, itask, 2);
1017 if (TObject::TestBit(kSaveCanvases)) {
1018 if (!gROOT->IsBatch()) {
1019 if (fDebug>1) printf("Waiting 5 sec for %s::Terminate() to finish drawing ...\n", task->ClassName());
1021 while (timer.RealTime()<5) {
1023 gSystem->ProcessEvents();
1026 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
1027 if (iend==0) continue;
1029 for (Int_t ipict=0; ipict<iend; ipict++) {
1030 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
1031 if (!canvas) continue;
1032 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
1034 gROOT->GetListOfCanvases()->Delete();
1038 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
1039 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
1040 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
1042 TObjArray *allOutputs = new TObjArray();
1044 for (icont=0; icont<fOutputs->GetEntriesFast(); icont++) allOutputs->Add(fOutputs->At(icont));
1045 if (!IsSkipTerminate())
1046 for (icont=0; icont<fParamCont->GetEntriesFast(); icont++) allOutputs->Add(fParamCont->At(icont));
1047 TIter next1(allOutputs);
1048 TString handlerFile = "";
1049 TString extraOutputs = "";
1050 if (fOutputEventHandler) {
1051 handlerFile = fOutputEventHandler->GetOutputFileName();
1052 extraOutputs = fOutputEventHandler->GetExtraOutputs();
1056 while ((output=(AliAnalysisDataContainer*)next1())) {
1057 // Special outputs or grid files have the files already closed and written.
1059 if (fMode == kGridAnalysis && icont<=fOutputs->GetEntriesFast()) continue;
1060 if (fMode == kProofAnalysis) {
1061 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
1063 const char *filename = output->GetFileName();
1064 TString openoption = "RECREATE";
1065 if (!(strcmp(filename, "default"))) continue;
1066 if (!strlen(filename)) continue;
1067 if (!output->GetData()) continue;
1068 TDirectory *opwd = gDirectory;
1069 TFile *file = output->GetFile();
1070 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1072 //if (handlerFile == filename && !gSystem->AccessPathName(filename)) openoption = "UPDATE";
1073 Bool_t firsttime = kTRUE;
1074 if (filestmp.FindObject(filename) || extraOutputs.Contains(filename)) {
1077 filestmp.Add(new TNamed(filename,""));
1079 if (!gSystem->AccessPathName(filename) && !firsttime) openoption = "UPDATE";
1080 if (fDebug>1) printf("Opening file: %s option=%s\n",filename, openoption.Data());
1081 file = new TFile(filename, openoption);
1083 if (fDebug>1) printf("File <%s> already opened with option: <%s> \n", filename, file->GetOption());
1084 openoption = file->GetOption();
1085 if (openoption == "READ") {
1086 if (fDebug>1) printf("...reopening in UPDATE mode\n");
1087 file->ReOpen("UPDATE");
1090 if (file->IsZombie()) {
1091 Error("Terminate", "Cannot open output file %s", filename);
1094 output->SetFile(file);
1096 // Check for a folder request
1097 TString dir = output->GetFolderName();
1098 if (!dir.IsNull()) {
1099 if (!file->GetDirectory(dir)) file->mkdir(dir);
1102 if (fDebug > 1) printf("...writing container %s to file %s:%s\n", output->GetName(), file->GetName(), output->GetFolderName());
1103 if (output->GetData()->InheritsFrom(TCollection::Class())) {
1104 // If data is a collection, we set the name of the collection
1105 // as the one of the container and we save as a single key.
1106 TCollection *coll = (TCollection*)output->GetData();
1107 coll->SetName(output->GetName());
1108 coll->Write(output->GetName(), TObject::kSingleKey);
1110 if (output->GetData()->InheritsFrom(TTree::Class())) {
1111 TTree *tree = (TTree*)output->GetData();
1112 tree->SetDirectory(gDirectory);
1115 output->GetData()->Write();
1118 if (opwd) opwd->cd();
1122 TString copiedFiles;
1123 while ((output=(AliAnalysisDataContainer*)next1())) {
1124 // Close all files at output
1125 TDirectory *opwd = gDirectory;
1126 if (output->GetFile()) {
1127 // Clear file list to release object ownership to user.
1128 // output->GetFile()->Clear();
1129 output->GetFile()->Close();
1130 // Copy merged outputs in alien if requested
1131 if (fSpecialOutputLocation.BeginsWith("alien://")) {
1132 if (copiedFiles.Contains(output->GetFile()->GetName())) {
1133 if (opwd) opwd->cd();
1134 output->SetFile(NULL);
1137 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
1138 gROOT->ProcessLine("if (!gGrid) TGrid::Connect(\"alien:\");");
1139 TFile::Cp(output->GetFile()->GetName(),
1140 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
1141 copiedFiles += output->GetFile()->GetName();
1143 output->SetFile(NULL);
1145 if (opwd) opwd->cd();
1148 //Write statistics information on the client
1149 if (fStatistics) WriteStatisticsMsg(fNcalls);
1151 TDirectory *crtdir = gDirectory;
1152 TFile f("syswatch.root", "RECREATE");
1155 if (!f.IsZombie()) {
1156 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
1157 tree->SetName("syswatch");
1158 tree->SetMarkerStyle(kCircle);
1159 tree->SetMarkerColor(kBlue);
1160 tree->SetMarkerSize(0.5);
1161 if (!gROOT->IsBatch()) {
1162 tree->SetAlias("event", "id0");
1163 tree->SetAlias("task", "id1");
1164 tree->SetAlias("stage", "id2");
1165 // Already defined aliases
1166 // tree->SetAlias("deltaT","stampSec-stampOldSec");
1167 // tree->SetAlias("T","stampSec-first");
1168 // tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)");
1169 // tree->SetAlias("VM","pI.fMemVirtual");
1170 TCanvas *canvas = new TCanvas("SysInfo","SysInfo",10,10,1200,800);
1171 Int_t npads = 1 /*COO plot for all tasks*/ +
1172 fTopTasks->GetEntries() /*Exec plot per task*/ +
1173 1 /*Terminate plot for all tasks*/ +
1176 Int_t iopt = (Int_t)TMath::Sqrt((Double_t)npads);
1177 if (npads<iopt*(iopt+1))
1178 canvas->Divide(iopt, iopt+1, 0.01, 0.01);
1180 canvas->Divide(iopt+1, iopt+1, 0.01, 0.01);
1182 // draw the plot of deltaVM for Exec for each task
1183 for (itask=0; itask<fTopTasks->GetEntriesFast(); itask++) {
1184 task = (AliAnalysisTask*)fTopTasks->At(itask);
1186 cut = Form("task==%d && stage==1", itask);
1187 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1188 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1190 hist->SetTitle(Form("%s: Exec dVM[MB]/event", task->GetName()));
1191 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1194 // Draw the plot of deltaVM for CreateOutputObjects for all tasks
1196 tree->SetMarkerStyle(kFullTriangleUp);
1197 tree->SetMarkerColor(kRed);
1198 tree->SetMarkerSize(0.8);
1199 cut = "task>=0 && task<1000 && stage==0";
1200 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1201 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1203 hist->SetTitle("Memory in CreateOutputObjects()");
1204 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1205 hist->GetXaxis()->SetTitle("task");
1207 // draw the plot of deltaVM for Terminate for all tasks
1209 tree->SetMarkerStyle(kOpenSquare);
1210 tree->SetMarkerColor(kMagenta);
1211 cut = "task>=0 && task<1000 && stage==2";
1212 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1213 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1215 hist->SetTitle("Memory in Terminate()");
1216 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1217 hist->GetXaxis()->SetTitle("task");
1221 tree->SetMarkerStyle(kFullCircle);
1222 tree->SetMarkerColor(kGreen);
1223 cut = Form("task==%d && stage==1",fTopTasks->GetEntriesFast()-1);
1224 tree->Draw("VM:event",cut,"", 1234567890, 0);
1225 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1227 hist->SetTitle("Virtual memory");
1228 hist->GetYaxis()->SetTitle("VM [MB]");
1232 tree->SetMarkerStyle(kCircle);
1233 tree->SetMarkerColor(kBlue);
1234 tree->SetMarkerSize(0.5);
1239 if (crtdir) crtdir->cd();
1241 // Validate the output files
1242 if (ValidateOutputFiles() && fIsRemote && fMode!=kProofAnalysis) {
1244 out.open("outputs_valid", ios::out);
1247 if (cdir) cdir->cd();
1249 if (fDebug || IsCollectThroughput()) {
1250 printf("=Analysis %s= Terminate time: %g[sec]\n", GetName(), fInitTimer->RealTime());
1252 if (fDebug > 1) printf("<-AliAnalysisManager::Terminate()\n");
1254 //______________________________________________________________________________
1255 void AliAnalysisManager::ProfileTask(Int_t itop, const char *option) const
1257 // Profiles the task having the itop index in the list of top (first level) tasks.
1258 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->At(itop);
1260 Error("ProfileTask", "There are only %d top tasks in the manager", fTopTasks->GetEntries());
1263 ProfileTask(task->GetName(), option);
1266 //______________________________________________________________________________
1267 void AliAnalysisManager::ProfileTask(const char *name, const char */*option*/) const
1269 // Profile a managed task after the execution of the analysis in case NSysInfo
1271 if (gSystem->AccessPathName("syswatch.root")) {
1272 Error("ProfileTask", "No file syswatch.root found in the current directory");
1275 if (gROOT->IsBatch()) return;
1276 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->FindObject(name);
1278 Error("ProfileTask", "No top task named %s known by the manager.", name);
1281 Int_t itop = fTopTasks->IndexOf(task);
1282 Int_t itask = fTasks->IndexOf(task);
1283 // Create canvas with 2 pads: first draw COO + Terminate, second Exec
1284 TDirectory *cdir = gDirectory;
1285 TFile f("syswatch.root");
1286 TTree *tree = (TTree*)f.Get("syswatch");
1288 Error("ProfileTask", "No tree named <syswatch> found in file syswatch.root");
1291 if (fDebug > 1) printf("=== Profiling task %s (class %s)\n", name, task->ClassName());
1292 TCanvas *canvas = new TCanvas(Form("profile_%d",itop),Form("Profile of task %s (class %s)",name,task->ClassName()),10,10,800,600);
1293 canvas->Divide(2, 2, 0.01, 0.01);
1297 // VM profile for COO and Terminate methods
1299 cut = Form("task==%d && (stage==0 || stage==2)",itask);
1300 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1301 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1303 hist->SetTitle("Alocated VM[MB] for COO and Terminate");
1304 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1305 hist->GetXaxis()->SetTitle("method");
1307 // CPU profile per event
1309 cut = Form("task==%d && stage==1",itop);
1310 tree->Draw("deltaT:event",cut,"", 1234567890, 0);
1311 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1313 hist->SetTitle("Execution time per event");
1314 hist->GetYaxis()->SetTitle("CPU/event [s]");
1316 // VM profile for Exec
1318 cut = Form("task==%d && stage==1",itop);
1319 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1320 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1322 hist->SetTitle("Alocated VM[MB] per event");
1323 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1328 if (cdir) cdir->cd();
1331 //______________________________________________________________________________
1332 void AliAnalysisManager::AddTask(AliAnalysisTask *task)
1334 // Adds a user task to the global list of tasks.
1336 Error("AddTask", "Cannot add task %s since InitAnalysis was already called", task->GetName());
1340 if (fTasks->FindObject(task)) {
1341 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
1344 task->SetActive(kFALSE);
1348 //______________________________________________________________________________
1349 AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
1351 // Retreive task by name.
1352 if (!fTasks) return NULL;
1353 return (AliAnalysisTask*)fTasks->FindObject(name);
1356 //______________________________________________________________________________
1357 AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
1358 TClass *datatype, EAliAnalysisContType type, const char *filename)
1360 // Create a data container of a certain type. Types can be:
1361 // kExchangeContainer = 0, used to exchange data between tasks
1362 // kInputContainer = 1, used to store input data
1363 // kOutputContainer = 2, used for writing result to a file
1364 // filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
1365 // the output object to a folder inside the output file
1366 if (fContainers->FindObject(name)) {
1367 Error("CreateContainer","A container named %s already defined !",name);
1370 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
1371 fContainers->Add(cont);
1373 case kInputContainer:
1376 case kOutputContainer:
1377 fOutputs->Add(cont);
1378 if (filename && strlen(filename)) {
1379 cont->SetFileName(filename);
1380 cont->SetDataOwned(kFALSE); // data owned by the file
1383 case kParamContainer:
1384 fParamCont->Add(cont);
1385 if (filename && strlen(filename)) {
1386 cont->SetFileName(filename);
1387 cont->SetDataOwned(kFALSE); // data owned by the file
1390 case kExchangeContainer:
1396 //______________________________________________________________________________
1397 Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
1398 AliAnalysisDataContainer *cont)
1400 // Connect input of an existing task to a data container.
1402 Error("ConnectInput", "Task pointer is NULL");
1405 if (!fTasks->FindObject(task)) {
1407 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
1409 Bool_t connected = task->ConnectInput(islot, cont);
1413 //______________________________________________________________________________
1414 Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
1415 AliAnalysisDataContainer *cont)
1417 // Connect output of an existing task to a data container.
1419 Error("ConnectOutput", "Task pointer is NULL");
1422 if (!fTasks->FindObject(task)) {
1424 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
1426 Bool_t connected = task->ConnectOutput(islot, cont);
1430 //______________________________________________________________________________
1431 void AliAnalysisManager::CleanContainers()
1433 // Clean data from all containers that have already finished all client tasks.
1434 TIter next(fContainers);
1435 AliAnalysisDataContainer *cont;
1436 while ((cont=(AliAnalysisDataContainer *)next())) {
1437 if (cont->IsOwnedData() &&
1438 cont->IsDataReady() &&
1439 cont->ClientsExecuted()) cont->DeleteData();
1443 //______________________________________________________________________________
1444 Bool_t AliAnalysisManager::InitAnalysis()
1446 // Initialization of analysis chain of tasks. Should be called after all tasks
1447 // and data containers are properly connected
1448 // Reset flag and remove valid_outputs file if exists
1449 if (fInitOK) return kTRUE;
1450 if (!gSystem->AccessPathName("outputs_valid"))
1451 gSystem->Unlink("outputs_valid");
1452 // Check for top tasks (depending only on input data containers)
1453 if (!fTasks->First()) {
1454 Error("InitAnalysis", "Analysis has no tasks !");
1458 AliAnalysisTask *task;
1459 AliAnalysisDataContainer *cont;
1462 Bool_t iszombie = kFALSE;
1463 Bool_t istop = kTRUE;
1465 while ((task=(AliAnalysisTask*)next())) {
1468 Int_t ninputs = task->GetNinputs();
1469 for (i=0; i<ninputs; i++) {
1470 cont = task->GetInputSlot(i)->GetContainer();
1474 fZombies->Add(task);
1478 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
1479 i, task->GetName());
1481 if (iszombie) continue;
1482 // Check if cont is an input container
1483 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
1484 // Connect to parent task
1488 fTopTasks->Add(task);
1492 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
1495 // Check now if there are orphan tasks
1496 for (i=0; i<ntop; i++) {
1497 task = (AliAnalysisTask*)fTopTasks->At(i);
1502 while ((task=(AliAnalysisTask*)next())) {
1503 if (!task->IsUsed()) {
1505 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
1508 // Check the task hierarchy (no parent task should depend on data provided
1509 // by a daughter task)
1510 for (i=0; i<ntop; i++) {
1511 task = (AliAnalysisTask*)fTopTasks->At(i);
1512 if (task->CheckCircularDeps()) {
1513 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
1518 // Check that all containers feeding post-event loop tasks are in the outputs list
1519 TIter nextcont(fContainers); // loop over all containers
1520 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1521 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1522 if (cont->HasConsumers()) {
1523 // Check if one of the consumers is post event loop
1524 TIter nextconsumer(cont->GetConsumers());
1525 while ((task=(AliAnalysisTask*)nextconsumer())) {
1526 if (task->IsPostEventLoop()) {
1527 fOutputs->Add(cont);
1534 // Check if all special output containers have a file name provided
1535 TIter nextout(fOutputs);
1536 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1537 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1538 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1542 // Initialize requested branch list if needed
1543 if (!fAutoBranchHandling) {
1545 while ((task=(AliAnalysisTask*)next())) {
1546 if (!task->HasBranches()) {
1547 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\"",
1548 task->GetName(), task->ClassName());
1551 if (!fInputEventHandler || !strlen(fInputEventHandler->GetDataType())) {
1552 Error("InitAnalysis", "Manual branch loading requested but no input handler defined or handler does not define data type.");
1555 TString taskbranches;
1556 task->GetBranches(fInputEventHandler->GetDataType(), taskbranches);
1557 if (taskbranches.IsNull()) {
1558 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches of type %s:",
1559 task->GetName(), task->ClassName(), fInputEventHandler->GetDataType());
1562 AddBranches(taskbranches);
1569 //______________________________________________________________________________
1570 void AliAnalysisManager::AddBranches(const char *branches)
1572 // Add branches to the existing fRequestedBranches.
1573 TString br(branches);
1574 TObjArray *arr = br.Tokenize(",");
1577 while ((obj=next())) {
1578 if (!fRequestedBranches.Contains(obj->GetName())) {
1579 if (!fRequestedBranches.IsNull()) fRequestedBranches += ",";
1580 fRequestedBranches += obj->GetName();
1586 //______________________________________________________________________________
1587 void AliAnalysisManager::CheckBranches(Bool_t load)
1589 // The method checks the input branches to be loaded during the analysis.
1590 if (fAutoBranchHandling || fRequestedBranches.IsNull() || !fTree) return;
1591 TObjArray *arr = fRequestedBranches.Tokenize(",");
1594 while ((obj=next())) {
1595 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(obj->GetName()));
1597 br = fTree->GetBranch(obj->GetName());
1599 Error("CheckBranches", "Could not find branch %s",obj->GetName());
1604 if (load && br->GetReadEntry()!=GetCurrentEntry()) {
1605 br->GetEntry(GetCurrentEntry());
1611 //______________________________________________________________________________
1612 Bool_t AliAnalysisManager::CheckTasks() const
1614 // Check consistency of tasks.
1615 Int_t ntasks = fTasks->GetEntries();
1617 Error("CheckTasks", "No tasks connected to the manager. This may be due to forgetting to compile the task or to load their library.");
1620 // Get the pointer to AliAnalysisTaskSE::Class()
1621 TClass *badptr = (TClass*)gROOT->ProcessLine("AliAnalysisTaskSE::Class()");
1622 // Loop all tasks to check if their corresponding library was loaded
1625 while ((obj=next())) {
1626 if (obj->IsA() == badptr) {
1627 Error("CheckTasks", "##################\n \
1628 Class for task %s NOT loaded. You probably forgot to load the library for this task (or compile it dynamically).\n###########################\n",obj->GetName());
1635 //______________________________________________________________________________
1636 void AliAnalysisManager::PrintStatus(Option_t *option) const
1638 // Print task hierarchy.
1640 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1643 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1645 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
1646 TIter next(fTopTasks);
1647 AliAnalysisTask *task;
1648 while ((task=(AliAnalysisTask*)next()))
1649 task->PrintTask(option);
1651 if (!fAutoBranchHandling && !fRequestedBranches.IsNull())
1652 printf("Requested input branches:\n%s\n", fRequestedBranches.Data());
1654 TString sopt(option);
1657 if (sopt.Contains("ALL"))
1659 if ( fOutputEventHandler )
1661 cout << TString('_',78) << endl;
1662 cout << "OutputEventHandler:" << endl;
1663 fOutputEventHandler->Print(" ");
1668 //______________________________________________________________________________
1669 void AliAnalysisManager::ResetAnalysis()
1671 // Reset all execution flags and clean containers.
1675 //______________________________________________________________________________
1676 void AliAnalysisManager::RunLocalInit()
1678 // Run LocalInit method for all tasks.
1679 TDirectory *cdir = gDirectory;
1680 if (IsTrainInitialized()) return;
1681 TIter nextTask(fTasks);
1682 AliAnalysisTask *task;
1683 while ((task=(AliAnalysisTask*)nextTask())) {
1687 if (cdir) cdir->cd();
1688 TObject::SetBit(kTasksInitialized, kTRUE);
1691 //______________________________________________________________________________
1692 Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
1694 // Start analysis having a grid handler.
1695 if (!fGridHandler) {
1696 Error("StartAnalysis", "Cannot start analysis providing just the analysis type without a grid handler.");
1697 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1701 return StartAnalysis(type, tree, nentries, firstentry);
1704 //______________________________________________________________________________
1705 Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
1707 // Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1708 // MIX. Process nentries starting from firstentry
1710 // Backup current directory and make sure gDirectory points to gROOT
1711 TDirectory *cdir = gDirectory;
1714 Error("StartAnalysis","Analysis manager was not initialized !");
1715 if (cdir) cdir->cd();
1718 if (!CheckTasks()) Fatal("StartAnalysis", "Not all needed libraries were loaded");
1720 printf("StartAnalysis %s\n",GetName());
1721 AliLog::SetGlobalLogLevel(AliLog::kInfo);
1723 fMaxEntries = nentries;
1725 TString anaType = type;
1727 fMode = kLocalAnalysis;
1728 if (anaType.Contains("file")) fIsRemote = kTRUE;
1729 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1730 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1731 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1733 if (fMode == kGridAnalysis) {
1735 if (!anaType.Contains("terminate")) {
1736 if (!fGridHandler) {
1737 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1738 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1739 if (cdir) cdir->cd();
1742 // Write analysis manager in the analysis file
1743 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1744 // run local task configuration
1746 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1747 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1748 if (cdir) cdir->cd();
1752 // Terminate grid analysis
1753 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1754 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1755 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1756 if (!fGridHandler->MergeOutputs()) {
1757 // Return if outputs could not be merged or if it alien handler
1758 // was configured for offline mode or local testing.
1759 if (cdir) cdir->cd();
1763 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1764 if (cdir) cdir->cd();
1765 ImportWrappers(NULL);
1767 if (cdir) cdir->cd();
1771 SetEventLoop(kFALSE);
1772 // Enable event loop mode if a tree was provided
1773 if (tree || fGridHandler || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
1776 TString ttype = "TTree";
1777 if (tree && tree->IsA() == TChain::Class()) {
1778 chain = (TChain*)tree;
1779 if (!chain || !chain->GetListOfFiles()->First()) {
1780 Error("StartAnalysis", "Cannot process null or empty chain...");
1781 if (cdir) cdir->cd();
1787 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1788 if (getsysInfo) AliSysInfo::AddStamp("Start", 0);
1789 // Initialize locally all tasks (happens for all modes)
1791 AliAnalysisTask *task;
1795 case kLocalAnalysis:
1796 if (!tree && !fGridHandler) {
1797 TIter nextT(fTasks);
1798 // Call CreateOutputObjects for all tasks
1800 Bool_t dirStatus = TH1::AddDirectoryStatus();
1801 while ((task=(AliAnalysisTask*)nextT())) {
1802 TH1::AddDirectory(kFALSE);
1803 task->CreateOutputObjects();
1804 if (!task->CheckPostData()) {
1805 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
1806 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
1807 ########### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ###########", task->GetName(), task->ClassName());
1809 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
1813 TH1::AddDirectory(dirStatus);
1814 if (IsExternalLoop()) {
1815 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1816 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1823 fSelector = new AliAnalysisSelector(this);
1824 // Check if a plugin handler is used
1826 // Get the chain from the plugin
1827 TString dataType = "esdTree";
1828 if (fInputEventHandler) {
1829 dataType = fInputEventHandler->GetDataType();
1833 chain = fGridHandler->GetChainForTestMode(dataType);
1835 Error("StartAnalysis", "No chain for test mode. Aborting.");
1838 cout << "===== RUNNING LOCAL ANALYSIS" << GetName() << " ON CHAIN " << chain->GetName() << endl;
1839 retv = chain->Process(fSelector, "", nentries, firstentry);
1842 // Run tree-based analysis via AliAnalysisSelector
1843 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
1844 retv = tree->Process(fSelector, "", nentries, firstentry);
1846 case kProofAnalysis:
1848 // Check if the plugin is used
1850 return StartAnalysis(type, fGridHandler->GetProofDataSet(), nentries, firstentry);
1852 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1853 Error("StartAnalysis", "No PROOF!!! Exiting.");
1854 if (cdir) cdir->cd();
1857 line = Form("gProof->AddInput((TObject*)%p);", this);
1858 gROOT->ProcessLine(line);
1861 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
1862 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
1864 Error("StartAnalysis", "No chain!!! Exiting.");
1865 if (cdir) cdir->cd();
1871 if (!anaType.Contains("terminate")) {
1872 if (!fGridHandler) {
1873 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1874 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1875 if (cdir) cdir->cd();
1878 // Write analysis manager in the analysis file
1879 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1880 // Start the analysis via the handler
1881 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1882 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1883 if (cdir) cdir->cd();
1887 // Terminate grid analysis
1888 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1889 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1890 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1891 if (!fGridHandler->MergeOutputs()) {
1892 // Return if outputs could not be merged or if it alien handler
1893 // was configured for offline mode or local testing.
1894 if (cdir) cdir->cd();
1898 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1899 ImportWrappers(NULL);
1901 if (cdir) cdir->cd();
1903 case kMixingAnalysis:
1904 // Run event mixing analysis
1906 Error("StartAnalysis", "Cannot run event mixing without event pool");
1907 if (cdir) cdir->cd();
1910 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1911 fSelector = new AliAnalysisSelector(this);
1912 while ((chain=fEventPool->GetNextChain())) {
1914 // Call NotifyBinChange for all tasks
1915 while ((task=(AliAnalysisTask*)next()))
1916 if (!task->IsPostEventLoop()) task->NotifyBinChange();
1917 retv = chain->Process(fSelector);
1919 Error("StartAnalysis", "Mixing analysis failed");
1920 if (cdir) cdir->cd();
1924 PackOutput(fSelector->GetOutputList());
1927 if (cdir) cdir->cd();
1931 //______________________________________________________________________________
1932 Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
1934 // Start analysis for this manager on a given dataset. Analysis task can be:
1935 // LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1937 Error("StartAnalysis","Analysis manager was not initialized !");
1941 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
1942 TString anaType = type;
1944 if (!anaType.Contains("proof")) {
1945 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
1948 fMode = kProofAnalysis;
1950 SetEventLoop(kTRUE);
1951 // Set the dataset flag
1952 TObject::SetBit(kUseDataSet);
1955 // Start proof analysis using the grid handler
1956 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1957 Error("StartAnalysis", "The grid plugin could not start PROOF analysis");
1960 // Check if the plugin is in test mode
1961 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kTest) {
1962 dataset = "test_collection";
1964 dataset = fGridHandler->GetProofDataSet();
1968 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1969 Error("StartAnalysis", "No PROOF!!! Exiting.");
1973 // Initialize locally all tasks
1976 line = Form("gProof->AddInput((TObject*)%p);", this);
1977 gROOT->ProcessLine(line);
1979 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"\", %lld, %lld);",
1980 dataset, nentries, firstentry);
1981 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
1982 retv = (Long_t)gROOT->ProcessLine(line);
1986 //______________________________________________________________________________
1987 TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
1989 // Opens according the option the file specified by cont->GetFileName() and changes
1990 // current directory to cont->GetFolderName(). If the file was already opened, it
1991 // checks if the option UPDATE was preserved. File open via TProofOutputFile can
1992 // be optionally ignored.
1993 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1994 TString filename = cont->GetFileName();
1996 if (filename.IsNull()) {
1997 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
2000 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
2002 f = mgr->OpenProofFile(cont,option);
2004 // Check first if the file is already opened
2005 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2007 // Check if option "UPDATE" was preserved
2008 TString opt(option);
2010 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2011 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2013 f = TFile::Open(filename, option);
2016 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2020 // Check for a folder request
2021 TString dir = cont->GetFolderName();
2022 if (!dir.IsNull()) {
2023 if (!f->GetDirectory(dir)) f->mkdir(dir);
2028 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
2029 cont->SetFile(NULL);
2033 //______________________________________________________________________________
2034 TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option, const char *extaod)
2036 // Opens a special output file used in PROOF.
2038 TString filename = cont->GetFileName();
2039 if (cont == fCommonOutput) {
2040 if (fOutputEventHandler) {
2041 if (strlen(extaod)) filename = extaod;
2042 filename = fOutputEventHandler->GetOutputFileName();
2044 else Fatal("OpenProofFile","No output container. Exiting.");
2047 if (fMode!=kProofAnalysis || !fSelector) {
2048 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
2051 if (fSpecialOutputLocation.Length()) {
2052 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2054 // Check if option "UPDATE" was preserved
2055 TString opt(option);
2057 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2058 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2060 f = new TFile(filename, option);
2062 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2066 // Check for a folder request
2067 TString dir = cont->GetFolderName();
2069 if (!f->GetDirectory(dir)) f->mkdir(dir);
2074 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2075 cont->SetFile(NULL);
2078 // Check if there is already a proof output file in the output list
2079 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
2081 // Get the actual file
2082 line = Form("((TProofOutputFile*)%p)->GetFileName();", pof);
2083 filename = (const char*)gROOT->ProcessLine(line);
2085 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
2087 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2089 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
2092 // Check if option "UPDATE" was preserved
2093 TString opt(option);
2095 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2096 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
2098 if (cont->IsRegisterDataset()) {
2099 TString dsetName = filename;
2100 dsetName.ReplaceAll(".root", cont->GetTitle());
2101 dsetName.ReplaceAll(":","_");
2102 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
2103 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
2105 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
2106 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
2108 if (fDebug > 1) printf("=== %s\n", line.Data());
2109 gROOT->ProcessLine(line);
2110 line = Form("pf->OpenFile(\"%s\");", option);
2111 gROOT->ProcessLine(line);
2114 gROOT->ProcessLine("pf->Print()");
2115 printf(" == proof file name: %s", f->GetName());
2117 // Add to proof output list
2118 line = Form("((TList*)%p)->Add(pf);",fSelector->GetOutputList());
2119 if (fDebug > 1) printf("=== %s\n", line.Data());
2120 gROOT->ProcessLine(line);
2122 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2126 // Check for a folder request
2127 TString dir = cont->GetFolderName();
2128 if (!dir.IsNull()) {
2129 if (!f->GetDirectory(dir)) f->mkdir(dir);
2134 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2135 cont->SetFile(NULL);
2139 //______________________________________________________________________________
2140 void AliAnalysisManager::ExecAnalysis(Option_t *option)
2142 // Execute analysis.
2143 static Long64_t nentries = 0;
2144 static TTree *lastTree = 0;
2145 static TStopwatch *timer = new TStopwatch();
2146 // Only the first call to Process will trigger a true Notify. Other Notify
2147 // coming before is ignored.
2148 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) {
2149 TObject::SetBit(AliAnalysisManager::kTrueNotify);
2152 if (fDebug > 0) printf("MGR: Processing event #%d\n", fNcalls);
2154 if (fTree && (fTree != lastTree)) {
2155 nentries += fTree->GetEntries();
2158 if (!fNcalls) timer->Start();
2159 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", fNcalls, TMath::Min(fMaxEntries,nentries), timer, kFALSE);
2161 fIOTimer->Start(kTRUE);
2163 TDirectory *cdir = gDirectory;
2164 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
2165 if (getsysInfo && ((fNcalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)fNcalls);
2167 Error("ExecAnalysis", "Analysis manager was not initialized !");
2168 if (cdir) cdir->cd();
2172 AliAnalysisTask *task;
2173 // Check if the top tree is active.
2175 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2176 AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
2178 // De-activate all tasks
2179 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
2180 AliAnalysisDataContainer *cont = fCommonInput;
2181 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
2183 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
2184 if (cdir) cdir->cd();
2187 cont->SetData(fTree); // This will notify all consumers
2188 Long64_t entry = fTree->GetTree()->GetReadEntry();
2190 // Call BeginEvent() for optional input/output and MC services
2191 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
2192 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
2193 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
2195 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2196 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2198 // Execute the tasks
2199 // TIter next1(cont->GetConsumers());
2201 fIOTime += fIOTimer->RealTime();
2202 fCPUTimer->Start(kTRUE);
2203 TIter next1(fTopTasks);
2205 while ((task=(AliAnalysisTask*)next1())) {
2207 cout << " Executing task " << task->GetName() << endl;
2209 task->ExecuteTask(option);
2211 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2212 AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
2216 fCPUTime += fCPUTimer->RealTime();
2217 fIOTimer->Start(kTRUE);
2219 // Call FinishEvent() for optional output and MC services
2220 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2221 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2222 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2223 // Gather system information if requested
2224 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2225 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1001, 1);
2226 if (cdir) cdir->cd();
2228 fIOTime += fIOTimer->RealTime();
2231 // The event loop is not controlled by TSelector
2233 // Call BeginEvent() for optional input/output and MC services
2234 fIOTimer->Start(kTRUE);
2235 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
2236 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
2237 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
2239 fIOTime += fIOTimer->RealTime();
2241 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2242 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2243 fCPUTimer->Start(kTRUE);
2244 TIter next2(fTopTasks);
2245 while ((task=(AliAnalysisTask*)next2())) {
2246 task->SetActive(kTRUE);
2248 cout << " Executing task " << task->GetName() << endl;
2250 task->ExecuteTask(option);
2254 fCPUTime += fCPUTimer->RealTime();
2256 // Call FinishEvent() for optional output and MC services
2257 fIOTimer->Start(kTRUE);
2258 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2259 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2260 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2261 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2262 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
2263 if (cdir) cdir->cd();
2265 fIOTime += fIOTimer->RealTime();
2268 //______________________________________________________________________________
2269 Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
2271 // Check if the stdout is connected to a pipe (C.Holm)
2272 Bool_t ispipe = kFALSE;
2273 out.seekp(0, std::ios_base::cur);
2276 if (errno == ESPIPE) ispipe = kTRUE;
2281 //______________________________________________________________________________
2282 void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
2284 // Set the input event handler and create a container for it.
2286 fInputEventHandler = handler;
2287 if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
2290 //______________________________________________________________________________
2291 void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
2293 // Set the input event handler and create a container for it.
2295 fOutputEventHandler = handler;
2296 if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
2297 fCommonOutput->SetSpecialOutput();
2300 //______________________________________________________________________________
2301 void AliAnalysisManager::SetDebugLevel(UInt_t level)
2303 // Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
2304 if (TObject::TestBit(kUseProgressBar)) {
2305 Info("SetDebugLevel","Ignored. Disable the progress bar first.");
2311 //______________________________________________________________________________
2312 void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
2314 // Enable a text mode progress bar. Resets debug level to 0.
2315 Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
2316 TObject::SetBit(kUseProgressBar,flag);
2317 fPBUpdateFreq = freq;
2321 //______________________________________________________________________________
2322 void AliAnalysisManager::RegisterExtraFile(const char *fname)
2324 // This method is used externally to register output files which are not
2325 // connected to any output container, so that the manager can properly register,
2326 // retrieve or merge them when running in distributed mode. The file names are
2327 // separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
2328 if (fExtraFiles.Contains(fname)) return;
2329 if (fExtraFiles.Length()) fExtraFiles += " ";
2330 fExtraFiles += fname;
2333 //______________________________________________________________________________
2334 Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
2336 // Copy a file from the location specified ina the wrapper with the same name from the source list.
2340 TObject *pof = source->FindObject(filename);
2341 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
2342 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
2345 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
2346 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
2347 TString clientUrl(chUrl);
2348 TString fullPath_str(fullPath);
2349 if (clientUrl.Contains("localhost")){
2350 TObjArray* array = fullPath_str.Tokenize ( "//" );
2351 TObjString *strobj = ( TObjString *)array->At(1);
2352 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
2353 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
2354 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
2355 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
2356 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
2360 else if (clientUrl.Contains("__lite__")) {
2361 // Special case for ProofLite environement - get file info and copy.
2362 gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
2363 fullPath_str = Form("%s/%s", tmp, fullPath);
2366 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
2367 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
2369 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
2373 //______________________________________________________________________________
2374 void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
2376 // Fill analysis type in the provided string.
2378 case kLocalAnalysis:
2381 case kProofAnalysis:
2387 case kMixingAnalysis:
2392 //______________________________________________________________________________
2393 Bool_t AliAnalysisManager::ValidateOutputFiles() const
2395 // Validate all output files.
2396 TIter next(fOutputs);
2397 AliAnalysisDataContainer *output;
2398 TDirectory *cdir = gDirectory;
2399 TString openedFiles;
2400 while ((output=(AliAnalysisDataContainer*)next())) {
2401 if (output->IsRegisterDataset()) continue;
2402 TString filename = output->GetFileName();
2403 if (filename == "default") {
2404 if (!fOutputEventHandler) continue;
2405 filename = fOutputEventHandler->GetOutputFileName();
2406 // Main AOD may not be there
2407 if (gSystem->AccessPathName(filename)) continue;
2409 // Check if the file is closed
2410 if (openedFiles.Contains(filename)) continue;;
2411 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2413 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
2414 // Clear file list to release object ownership to user.
2418 file = TFile::Open(filename);
2419 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
2420 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
2421 if (cdir) cdir->cd();
2425 openedFiles += filename;
2428 if (cdir) cdir->cd();
2432 //______________________________________________________________________________
2433 void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
2435 // Implements a nice text mode progress bar.
2436 static Long64_t icount = 0;
2437 static TString oname;
2438 static TString nname;
2439 static Long64_t ocurrent = 0;
2440 static Long64_t osize = 0;
2441 static Int_t oseconds = 0;
2442 static TStopwatch *owatch = 0;
2443 static Bool_t oneoftwo = kFALSE;
2444 static Int_t nrefresh = 0;
2445 static Int_t nchecks = 0;
2446 static char lastChar = 0;
2447 const char symbol[4] = {'-','\\','|','/'};
2449 if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
2455 ocurrent = TMath::Abs(current);
2456 osize = TMath::Abs(size);
2457 if (ocurrent > osize) ocurrent=osize;
2462 if ((current % fPBUpdateFreq) != 0) return;
2464 char progress[11] = " ";
2465 Int_t ichar = icount%4;
2470 if (owatch && !last) {
2472 time = owatch->RealTime();
2473 seconds = int(time) % 60;
2474 minutes = (int(time) / 60) % 60;
2475 hours = (int(time) / 60 / 60);
2477 if (oseconds==seconds) {
2481 oneoftwo = !oneoftwo;
2485 if (refresh && oneoftwo) {
2487 if (nchecks <= 0) nchecks = nrefresh+1;
2488 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
2489 oname = Form(" == %d%% ==", pctdone);
2491 Double_t percent = 100.0*ocurrent/osize;
2492 Int_t nchar = Int_t(percent/10);
2493 if (nchar>10) nchar=10;
2495 for (i=0; i<nchar; i++) progress[i] = '=';
2496 progress[nchar] = symbol[ichar];
2497 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2498 progress[10] = '\0';
2501 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2502 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2503 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
2505 Int_t full = Int_t(ocurrent > 0 ?
2506 time * (float(osize)/ocurrent) + .5 :
2508 Int_t remain = Int_t(full - time);
2509 Int_t rsec = remain % 60;
2510 Int_t rmin = (remain / 60) % 60;
2511 Int_t rhour = (remain / 60 / 60);
2512 fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
2513 percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
2515 else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
2516 if (refresh && oneoftwo) oname = nname;
2517 if (owatch) owatch->Continue();
2526 fprintf(stderr, "\n");
2530 //______________________________________________________________________________
2531 void AliAnalysisManager::DoLoadBranch(const char *name)
2533 // Get tree and load branch if needed.
2534 static Long64_t crtEntry = -100;
2536 if (fAutoBranchHandling || !fTree)
2539 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2541 br = fTree->GetBranch(name);
2543 Error("DoLoadBranch", "Could not find branch %s",name);
2548 if (br->GetReadEntry()==fCurrentEntry) return;
2549 Long64_t readbytes = br->GetEntry(GetCurrentEntry());
2551 Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
2552 if (crtEntry != fCurrentEntry) {
2553 CountEvent(1,0,1,0);
2554 crtEntry = fCurrentEntry;
2557 if (crtEntry != fCurrentEntry) {
2558 CountEvent(1,1,0,0);
2559 crtEntry = fCurrentEntry;
2564 //______________________________________________________________________________
2565 void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
2567 // Add the statistics task to the manager.
2569 Info("AddStatisticsTask", "Already added");
2572 TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
2573 gROOT->ProcessLine(line);
2576 //______________________________________________________________________________
2577 void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
2579 // Bookkeep current event;
2580 if (!fStatistics) return;
2581 fStatistics->AddInput(ninput);
2582 fStatistics->AddProcessed(nprocessed);
2583 fStatistics->AddFailed(nfailed);
2584 fStatistics->AddAccepted(naccepted);
2587 //______________________________________________________________________________
2588 void AliAnalysisManager::AddStatisticsMsg(const char *line)
2590 // Add a line in the statistics message. If available, the statistics message is written
2591 // at the end of the SlaveTerminate phase on workers AND at the end of Terminate
2593 if (!strlen(line)) return;
2594 if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
2595 fStatisticsMsg += line;
2598 //______________________________________________________________________________
2599 void AliAnalysisManager::WriteStatisticsMsg(Int_t)
2601 // If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
2602 static Bool_t done = kFALSE;
2605 if (!fStatistics) return;
2607 AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
2608 AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
2609 AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
2610 AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
2611 out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
2612 fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
2613 fStatistics->GetNaccepted()), ios::out);
2614 out << fStatisticsMsg << endl;
2618 //______________________________________________________________________________
2619 const char* AliAnalysisManager::GetOADBPath()
2621 // returns the path of the OADB
2622 // this static function just depends on environment variables
2624 static TString oadbPath;
2626 if (gSystem->Getenv("OADB_PATH"))
2627 oadbPath = gSystem->Getenv("OADB_PATH");
2628 else if (gSystem->Getenv("ALICE_ROOT"))
2629 oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
2631 ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
2636 //______________________________________________________________________________
2637 void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
2639 // Define a custom string variable mapped to a global unique name. The variable
2640 // can be then retrieved by a given analysis macro via GetGlobalStr(key).
2641 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2643 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2646 Bool_t valid = kFALSE;
2647 TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
2649 ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
2652 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
2655 //______________________________________________________________________________
2656 const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
2658 // Static method to retrieve a global variable defined via SetGlobalStr.
2660 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2662 TObject *value = mgr->GetGlobals()->GetValue(key);
2663 if (!value) return 0;
2665 return value->GetName();
2668 //______________________________________________________________________________
2669 void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
2671 // Define a custom integer variable mapped to a global unique name. The variable
2672 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2673 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2675 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2678 Bool_t valid = kFALSE;
2679 Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
2681 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
2684 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
2687 //______________________________________________________________________________
2688 Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
2690 // Static method to retrieve a global variable defined via SetGlobalInt.
2692 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2694 TObject *value = mgr->GetGlobals()->GetValue(key);
2695 if (!value) return 0;
2697 TString s = value->GetName();
2701 //______________________________________________________________________________
2702 void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
2704 // Define a custom double precision variable mapped to a global unique name. The variable
2705 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2706 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2708 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2711 Bool_t valid = kFALSE;
2712 Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
2714 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
2717 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));
2720 //______________________________________________________________________________
2721 Double_t AliAnalysisManager::GetGlobalDbl(const char *key, Bool_t &valid)
2723 // Static method to retrieve a global variable defined via SetGlobalDbl.
2725 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2727 TObject *value = mgr->GetGlobals()->GetValue(key);
2728 if (!value) return 0;
2730 TString s = value->GetName();
2734 //______________________________________________________________________________
2735 void AliAnalysisManager::AddClassDebug(const char *className, Int_t debugLevel)
2737 // Sets Class debug level
2739 if (!fDebugOptions) {
2740 fDebugOptions = new TObjArray();
2741 fDebugOptions->SetOwner(kTRUE);
2744 // substracting DebugOffset, beacuse of AliLog::SetClassDebugLevel()
2745 debugLevel -= AliLog::kDebug-1;
2747 TNamed *debugOpt = (TNamed*)fDebugOptions->FindObject(className);
2749 AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel+AliLog::kDebug-1,className).Data());
2750 fDebugOptions->Add(new TNamed(className,TString::Format("%d",debugLevel).Data()));
2752 TString oldDebugStr = debugOpt->GetTitle();
2753 Int_t oldDebug = oldDebugStr.Atoi();
2754 if (debugLevel > oldDebug) {
2755 AliWarning(TString::Format("Overwriting debug level to %d class %s, because it is higher then previously set (%d).",debugLevel+AliLog::kDebug-1,className,oldDebug+AliLog::kDebug-1).Data());
2756 debugOpt->SetTitle(TString::Format("%d",debugLevel).Data());
2758 AliWarning(TString::Format("Ignoring debug level to %d class %s, because it is smaller then previously set (%d).",debugLevel+AliLog::kDebug-1,className,oldDebug+AliLog::kDebug-1).Data());
2763 //______________________________________________________________________________
2764 void AliAnalysisManager::ApplyDebugOptions()
2766 // Apply debug options
2768 if (!fDebugOptions) return;
2770 TIter next(fDebugOptions);
2773 while ((debug=dynamic_cast<TNamed*>(next()))) {
2774 debugLevel = debug->GetTitle();
2775 AliInfo(TString::Format("ApplyDebugOptions : Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()+AliLog::kDebug-1).Data());
2776 AliLog::SetClassDebugLevel(debug->GetName(), debugLevel.Atoi());
2780 //______________________________________________________________________________
2781 void AliAnalysisManager::Lock()
2783 // Security lock. This is to detect NORMAL user errors and not really to
2784 // protect against intentional hacks.
2785 if (fLocked) return;
2787 if (fInputEventHandler) fInputEventHandler->Lock();
2788 if (fOutputEventHandler) fOutputEventHandler->Lock();
2789 if (fMCtruthEventHandler) fMCtruthEventHandler->Lock();
2790 Info("Lock","====== ANALYSIS MANAGER LOCKED ======");
2793 //______________________________________________________________________________
2794 void AliAnalysisManager::UnLock()
2796 // Verbose unlocking. Hackers will be punished ;-) ...
2797 if (!fLocked) return;
2799 if (fInputEventHandler) fInputEventHandler->UnLock();
2800 if (fOutputEventHandler) fOutputEventHandler->UnLock();
2801 if (fMCtruthEventHandler) fMCtruthEventHandler->UnLock();
2802 Info("UnLock", "====== ANALYSIS MANAGER UNLOCKED ======");
2805 //______________________________________________________________________________
2806 void AliAnalysisManager::Changed()
2808 // All critical setters pass through the Changed method that throws an exception
2809 // in case the lock was set.
2810 if (fLocked) Fatal("Changed","Critical setter called in locked mode");