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>
38 #include <TMethodCall.h>
43 #include <TStopwatch.h>
46 #include "AliAnalysisSelector.h"
47 #include "AliAnalysisGrid.h"
48 #include "AliAnalysisTask.h"
49 #include "AliAnalysisDataContainer.h"
50 #include "AliAnalysisDataSlot.h"
51 #include "AliVEventHandler.h"
52 #include "AliVEventPool.h"
53 #include "AliSysInfo.h"
54 #include "AliAnalysisStatistics.h"
60 ClassImp(AliAnalysisManager)
62 AliAnalysisManager *AliAnalysisManager::fgAnalysisManager = NULL;
63 TString AliAnalysisManager::fgCommonFileName = "";
64 Int_t AliAnalysisManager::fPBUpdateFreq = 1;
66 //______________________________________________________________________________
67 AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
70 fInputEventHandler(0),
71 fOutputEventHandler(0),
72 fMCtruthEventHandler(0),
76 fMode(kLocalAnalysis),
82 fSpecialOutputLocation(""),
91 fFileDescriptors(new TObjArray()),
92 fCurrentDescriptor(0),
99 fAutoBranchHandling(kTRUE),
105 fRequestedBranches(),
115 // Default constructor.
116 fgAnalysisManager = this;
117 fgCommonFileName = "AnalysisResults.root";
118 if (TClass::IsCallingNew() != TClass::kDummyNew) {
119 fTasks = new TObjArray();
120 fTopTasks = new TObjArray();
121 fZombies = new TObjArray();
122 fContainers = new TObjArray();
123 fInputs = new TObjArray();
124 fOutputs = new TObjArray();
125 fParamCont = new TObjArray();
126 fGlobals = new TMap();
128 fIOTimer = new TStopwatch();
129 fCPUTimer = new TStopwatch();
130 fInitTimer = new TStopwatch();
134 //______________________________________________________________________________
135 AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
138 fInputEventHandler(NULL),
139 fOutputEventHandler(NULL),
140 fMCtruthEventHandler(NULL),
145 fInitOK(other.fInitOK),
146 fMustClean(other.fMustClean),
147 fIsRemote(other.fIsRemote),
148 fLocked(other.fLocked),
149 fDebug(other.fDebug),
150 fSpecialOutputLocation(""),
159 fFileDescriptors(new TObjArray()),
160 fCurrentDescriptor(0),
165 fExtraFiles(other.fExtraFiles),
166 fFileInfoLog(other.fFileInfoLog),
167 fAutoBranchHandling(other.fAutoBranchHandling),
170 fNcalls(other.fNcalls),
171 fMaxEntries(other.fMaxEntries),
172 fStatisticsMsg(other.fStatisticsMsg),
173 fRequestedBranches(other.fRequestedBranches),
174 fStatistics(other.fStatistics),
175 fGlobals(other.fGlobals),
176 fIOTimer(new TStopwatch()),
177 fCPUTimer(new TStopwatch()),
178 fInitTimer(new TStopwatch()),
184 fTasks = new TObjArray(*other.fTasks);
185 fTopTasks = new TObjArray(*other.fTopTasks);
186 fZombies = new TObjArray(*other.fZombies);
187 fContainers = new TObjArray(*other.fContainers);
188 fInputs = new TObjArray(*other.fInputs);
189 fOutputs = new TObjArray(*other.fOutputs);
190 fParamCont = new TObjArray(*other.fParamCont);
191 fgCommonFileName = "AnalysisResults.root";
192 fgAnalysisManager = this;
195 //______________________________________________________________________________
196 AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& other)
199 if (&other != this) {
200 TNamed::operator=(other);
201 fInputEventHandler = other.fInputEventHandler;
202 fOutputEventHandler = other.fOutputEventHandler;
203 fMCtruthEventHandler = other.fMCtruthEventHandler;
204 fEventPool = other.fEventPool;
207 fNSysInfo = other.fNSysInfo;
209 fInitOK = other.fInitOK;
210 fIsRemote = other.fIsRemote;
211 fLocked = other.fLocked;
212 fDebug = other.fDebug;
213 fTasks = new TObjArray(*other.fTasks);
214 fTopTasks = new TObjArray(*other.fTopTasks);
215 fZombies = new TObjArray(*other.fZombies);
216 fContainers = new TObjArray(*other.fContainers);
217 fInputs = new TObjArray(*other.fInputs);
218 fOutputs = new TObjArray(*other.fOutputs);
219 fParamCont = new TObjArray(*other.fParamCont);
220 fDebugOptions = NULL;
221 fFileDescriptors = new TObjArray();
222 fCurrentDescriptor = 0;
224 fCommonOutput = NULL;
227 fExtraFiles = other.fExtraFiles;
228 fFileInfoLog = other.fFileInfoLog;
229 fgCommonFileName = "AnalysisResults.root";
230 fgAnalysisManager = this;
231 fAutoBranchHandling = other.fAutoBranchHandling;
232 fTable.Clear("nodelete");
233 fRunFromPath = other.fRunFromPath;
234 fNcalls = other. fNcalls;
235 fMaxEntries = other.fMaxEntries;
236 fStatisticsMsg = other.fStatisticsMsg;
237 fRequestedBranches = other.fRequestedBranches;
238 fStatistics = other.fStatistics;
239 fGlobals = new TMap();
240 fIOTimer = new TStopwatch();
241 fCPUTimer = new TStopwatch();
242 fInitTimer = new TStopwatch();
250 //______________________________________________________________________________
251 AliAnalysisManager::~AliAnalysisManager()
254 if (fTasks) {fTasks->Delete(); delete fTasks;}
255 if (fTopTasks) delete fTopTasks;
256 if (fZombies) delete fZombies;
257 if (fContainers) {fContainers->Delete(); delete fContainers;}
258 if (fInputs) delete fInputs;
259 if (fOutputs) delete fOutputs;
260 if (fParamCont) delete fParamCont;
261 if (fDebugOptions) delete fDebugOptions;
262 if (fGridHandler) delete fGridHandler;
263 if (fInputEventHandler) delete fInputEventHandler;
264 if (fOutputEventHandler) delete fOutputEventHandler;
265 if (fMCtruthEventHandler) delete fMCtruthEventHandler;
266 if (fEventPool) delete fEventPool;
267 if (fgAnalysisManager==this) fgAnalysisManager = NULL;
268 if (fGlobals) {fGlobals->DeleteAll(); delete fGlobals;}
269 if (fFileDescriptors) {fFileDescriptors->Delete(); delete fFileDescriptors;}
275 //______________________________________________________________________________
276 Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
278 // Read one entry of the tree or a whole branch.
279 fCurrentEntry = entry;
280 if (!fAutoBranchHandling)
282 if (!fTree) return -1;
283 fIOTimer->Start(kTRUE);
284 Long64_t readbytes = fTree->GetTree()->GetEntry(entry, getall);
286 fIOTime += fIOTimer->RealTime();
287 return (Int_t)readbytes;
290 //______________________________________________________________________________
291 Int_t AliAnalysisManager::GetRunFromAlienPath(const char *path)
293 // Attempt to extract run number from input data path. Works only for paths to
294 // alice data in alien.
295 // sim: /alice/sim/<production>/run_no/...
296 // data: /alice/data/year/period/000run_no/... (ESD or AOD)
297 TString type = "unknown";
299 if (s.Contains("/alice/data")) type = "real";
300 else if (s.Contains("/alice/sim")) type = "simulated";
303 ind1 = s.Index("/00");
305 ind2 = s.Index("/",ind1+1);
306 if (ind2-ind1>8) srun = s(ind1+1, ind2-ind1-1);
309 ind1 = s.Index("/LHC");
311 ind1 = s.Index("/",ind1+1);
313 ind2 = s.Index("/",ind1+1);
314 if (ind2>0) srun = s(ind1+1, ind2-ind1-1);
318 Int_t run = srun.Atoi();
319 if (run>0) printf("=== GetRunFromAlienPath: run %d of %s data ===\n", run, type.Data());
323 //______________________________________________________________________________
324 Bool_t AliAnalysisManager::Init(TTree *tree)
326 // The Init() function is called when the selector needs to initialize
327 // a new tree or chain. Typically here the branch addresses of the tree
328 // will be set. It is normaly not necessary to make changes to the
329 // generated code, but the routine can be extended by the user if needed.
330 // Init() will be called many times when running with PROOF.
331 Bool_t init = kFALSE;
332 if (!tree) return kFALSE; // Should not happen - protected in selector caller
334 printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
336 // Call InitTree of EventHandler
337 if (fOutputEventHandler) {
338 if (fMode == kProofAnalysis) {
339 init = fOutputEventHandler->Init(0x0, "proof");
341 init = fOutputEventHandler->Init(0x0, "local");
344 Error("Init", "Output event handler failed to initialize");
349 if (fInputEventHandler) {
350 if (fMode == kProofAnalysis) {
351 init = fInputEventHandler->Init(tree, "proof");
353 init = fInputEventHandler->Init(tree, "local");
356 Error("Init", "Input event handler failed to initialize tree");
360 // If no input event handler we need to get the tree once
362 if(!tree->GetTree()) {
363 Long64_t readEntry = tree->LoadTree(0);
364 if (readEntry == -2) {
365 Error("Init", "Input tree has no entry. Exiting");
371 if (fMCtruthEventHandler) {
372 if (fMode == kProofAnalysis) {
373 init = fMCtruthEventHandler->Init(0x0, "proof");
375 init = fMCtruthEventHandler->Init(0x0, "local");
378 Error("Init", "MC event handler failed to initialize");
383 if (!fInitOK) InitAnalysis();
384 if (!fInitOK) return kFALSE;
387 AliAnalysisDataContainer *top = fCommonInput;
388 if (!top) top = (AliAnalysisDataContainer*)fInputs->At(0);
390 Error("Init","No top input container !");
394 CheckBranches(kFALSE);
396 printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
401 //______________________________________________________________________________
402 void AliAnalysisManager::SlaveBegin(TTree *tree)
404 // The SlaveBegin() function is called after the Begin() function.
405 // When running with PROOF SlaveBegin() is called on each slave server.
406 // The tree argument is deprecated (on PROOF 0 is passed).
407 if (fDebug > 1) printf("->AliAnalysisManager::SlaveBegin()\n");
408 // Init timer should be already started
409 // Apply debug options
412 if (!CheckTasks()) Fatal("SlaveBegin", "Not all needed libraries were loaded");
413 static Bool_t isCalled = kFALSE;
414 Bool_t init = kFALSE;
415 Bool_t initOK = kTRUE;
417 TDirectory *curdir = gDirectory;
418 // Call SlaveBegin only once in case of mixing
419 if (isCalled && fMode==kMixingAnalysis) return;
421 // Call Init of EventHandler
422 if (fOutputEventHandler) {
423 if (fMode == kProofAnalysis) {
424 // Merging AOD's in PROOF via TProofOutputFile
425 if (fDebug > 1) printf(" Initializing AOD output file %s...\n", fOutputEventHandler->GetOutputFileName());
426 init = fOutputEventHandler->Init("proof");
427 if (!init) msg = "Failed to initialize output handler on worker";
429 init = fOutputEventHandler->Init("local");
430 if (!init) msg = "Failed to initialize output handler";
433 if (!fSelector) Error("SlaveBegin", "Selector not set");
434 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
437 if (fInputEventHandler) {
438 fInputEventHandler->SetInputTree(tree);
439 if (fMode == kProofAnalysis) {
440 init = fInputEventHandler->Init("proof");
441 if (!init) msg = "Failed to initialize input handler on worker";
443 init = fInputEventHandler->Init("local");
444 if (!init) msg = "Failed to initialize input handler";
447 if (!fSelector) Error("SlaveBegin", "Selector not set");
448 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
451 if (fMCtruthEventHandler) {
452 if (fMode == kProofAnalysis) {
453 init = fMCtruthEventHandler->Init("proof");
454 if (!init) msg = "Failed to initialize MC handler on worker";
456 init = fMCtruthEventHandler->Init("local");
457 if (!init) msg = "Failed to initialize MC handler";
460 if (!fSelector) Error("SlaveBegin", "Selector not set");
461 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
463 if (curdir) curdir->cd();
467 AliAnalysisTask *task;
468 // Call CreateOutputObjects for all tasks
469 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
470 Bool_t dirStatus = TH1::AddDirectoryStatus();
472 while ((task=(AliAnalysisTask*)next())) {
474 // Start with memory as current dir and make sure by default histograms do not get attached to files.
475 TH1::AddDirectory(kFALSE);
476 task->CreateOutputObjects();
477 if (!task->CheckPostData()) {
478 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
479 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
480 ####### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ##########", task->GetName(), task->ClassName());
482 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
485 TH1::AddDirectory(dirStatus);
486 if (curdir) curdir->cd();
488 fInitTime += fInitTimer->RealTime();
489 fInitTimer->Continue();
490 printf("Initialization time: %g [sec]\n", fInitTime);
491 if (fDebug > 1) printf("<-AliAnalysisManager::SlaveBegin()\n");
494 //______________________________________________________________________________
495 Bool_t AliAnalysisManager::Notify()
497 // The Notify() function is called when a new file is opened. This
498 // can be either for a new TTree in a TChain or when when a new TTree
499 // is started when using PROOF. It is normaly not necessary to make changes
500 // to the generated code, but the routine can be extended by the
501 // user if needed. The return value is currently not used.
502 fIOTimer->Start(kTRUE);
503 if (!fTree) return kFALSE;
504 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) return kFALSE;
506 fTable.Clear("nodelete"); // clearing the hash table may not be needed -> C.L.
507 if (fMode == kProofAnalysis) fIsRemote = kTRUE;
509 TFile *curfile = fTree->GetCurrentFile();
511 Error("Notify","No current file");
514 if (IsCollectThroughput()) {
515 if (fCurrentDescriptor) fCurrentDescriptor->Done();
516 fCurrentDescriptor = new AliAnalysisFileDescriptor(curfile);
517 fFileDescriptors->Add(fCurrentDescriptor);
520 if (fDebug > 1) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
521 Int_t run = AliAnalysisManager::GetRunFromAlienPath(curfile->GetName());
522 if (run && (run != fRunFromPath)) {
524 if (fDebug > 1) printf(" ### run found from path: %d\n", run);
527 AliAnalysisTask *task;
529 // Call Notify of the event handlers
530 if (fInputEventHandler) {
531 fInputEventHandler->Notify(curfile->GetName());
534 if (fOutputEventHandler) {
535 fOutputEventHandler->Notify(curfile->GetName());
538 if (fMCtruthEventHandler) {
539 fMCtruthEventHandler->Notify(curfile->GetName());
542 // Call Notify for all tasks
543 while ((task=(AliAnalysisTask*)next()))
546 if (fDebug > 1) printf("<-AliAnalysisManager::Notify()\n");
548 fIOTime += fIOTimer->RealTime();
552 //______________________________________________________________________________
553 Bool_t AliAnalysisManager::Process(Long64_t)
555 // The Process() function is called for each entry in the tree (or possibly
556 // keyed object in the case of PROOF) to be processed. The entry argument
557 // specifies which entry in the currently loaded tree is to be processed.
558 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
559 // to read either all or the required parts of the data. When processing
560 // keyed objects with PROOF, the object is already loaded and is available
561 // via the fObject pointer.
563 // This function should contain the "body" of the analysis. It can contain
564 // simple or elaborate selection criteria, run algorithms on the data
565 // of the event and typically fill histograms.
567 // WARNING when a selector is used with a TChain, you must use
568 // the pointer to the current TTree to call GetEntry(entry).
569 // The entry is always the local entry number in the current tree.
570 // Assuming that fChain is the pointer to the TChain being processed,
571 // use fChain->GetTree()->GetEntry(entry).
573 // This method is obsolete. ExecAnalysis is called instead.
577 //______________________________________________________________________________
578 void AliAnalysisManager::PackOutput(TList *target)
580 // Pack all output data containers in the output list. Called at SlaveTerminate
581 // stage in PROOF case for each slave.
582 if (fDebug > 1) printf("->AliAnalysisManager::PackOutput()\n");
583 fIOTimer->Start(kTRUE);
585 if (IsCollectThroughput()) {
586 if (fCurrentDescriptor) fCurrentDescriptor->Done();
587 fFileDescriptors->Print();
588 if (fFileInfoLog.IsNull()) fFileInfoLog = "fileinfo.log";
589 out.open(fFileInfoLog, std::ios::app);
590 if (out.bad()) Error("SavePrimitive", "Bad file name: %s", fFileInfoLog.Data());
592 TIter nextflog(fFileDescriptors);
594 while ((log=nextflog())) log->SavePrimitive(out,"");
598 Error("PackOutput", "No target. Exiting.");
601 TDirectory *cdir = gDirectory;
603 if (fInputEventHandler) fInputEventHandler ->Terminate();
604 if (fOutputEventHandler) fOutputEventHandler ->Terminate();
605 if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
608 // Call FinishTaskOutput() for each event loop task (not called for
609 // post-event loop tasks - use Terminate() fo those)
610 TIter nexttask(fTasks);
611 AliAnalysisTask *task;
612 while ((task=(AliAnalysisTask*)nexttask())) {
613 if (!task->IsPostEventLoop()) {
614 if (fDebug > 1) printf("->FinishTaskOutput: task %s\n", task->GetName());
615 task->FinishTaskOutput();
617 if (fDebug > 1) printf("<-FinishTaskOutput: task %s\n", task->GetName());
620 // Write statistics message on the workers.
621 if (fStatistics) WriteStatisticsMsg(fNcalls);
623 if (fMode == kProofAnalysis) {
624 TIter next(fOutputs);
625 AliAnalysisDataContainer *output;
626 Bool_t isManagedByHandler = kFALSE;
629 while ((output=(AliAnalysisDataContainer*)next())) {
630 // Do not consider outputs of post event loop tasks
631 isManagedByHandler = kFALSE;
632 if (output->GetProducer() && output->GetProducer()->IsPostEventLoop()) continue;
633 const char *filename = output->GetFileName();
634 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
635 isManagedByHandler = kTRUE;
636 printf("#### Handler output. Extra: %s\n", fExtraFiles.Data());
637 filename = fOutputEventHandler->GetOutputFileName();
639 // Check if data was posted to this container. If not, issue an error.
640 if (!output->GetData() && !isManagedByHandler) {
641 Error("PackOutput", "No data for output container %s. Forgot to PostData ?", output->GetName());
644 if (!output->IsSpecialOutput()) {
646 if (strlen(filename) && !isManagedByHandler) {
647 // Backup current folder
648 TDirectory *opwd = gDirectory;
649 // File resident outputs.
650 // Check first if the file exists.
651 TString openoption = "RECREATE";
652 Bool_t firsttime = kTRUE;
653 if (filestmp.FindObject(output->GetFileName())) {
656 filestmp.Add(new TNamed(output->GetFileName(),""));
658 if (!gSystem->AccessPathName(output->GetFileName()) && !firsttime) openoption = "UPDATE";
659 // TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
660 // Save data to file, then close.
661 if (output->GetData()->InheritsFrom(TCollection::Class())) {
662 // If data is a collection, we set the name of the collection
663 // as the one of the container and we save as a single key.
664 TCollection *coll = (TCollection*)output->GetData();
665 coll->SetName(output->GetName());
666 // coll->Write(output->GetName(), TObject::kSingleKey);
668 if (output->GetData()->InheritsFrom(TTree::Class())) {
669 TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
670 // Save data to file, then close.
671 TTree *tree = (TTree*)output->GetData();
672 // Check if tree is in memory
673 if (tree->GetDirectory()==gROOT) tree->SetDirectory(gDirectory);
677 // output->GetData()->Write();
680 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
682 // printf(" file %s listing content:\n", filename);
685 // Clear file list to release object ownership to user.
688 output->SetFile(NULL);
689 // Restore current directory
690 if (opwd) opwd->cd();
692 // Memory-resident outputs
693 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
695 AliAnalysisDataWrapper *wrap = 0;
696 if (isManagedByHandler) {
697 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
698 wrap->SetName(output->GetName());
700 else wrap =output->ExportData();
701 // Output wrappers must NOT delete data after merging - the user owns them
702 wrap->SetDeleteData(kFALSE);
705 // Special outputs. The file must be opened and connected to the container.
706 TDirectory *opwd = gDirectory;
707 TFile *file = output->GetFile();
709 AliAnalysisTask *producer = output->GetProducer();
711 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
712 output->GetFileName(), output->GetName(), producer->ClassName());
715 TString outFilename = file->GetName();
716 if (fDebug > 1) printf("PackOutput %s: special output\n", output->GetName());
717 if (isManagedByHandler) {
718 // Terminate IO for files managed by the output handler
719 // file->Write() moved to AOD handler (A.G. 11.01.10)
720 // if (file) file->Write();
721 if (file && fDebug > 2) {
722 printf(" handled file %s listing content:\n", file->GetName());
725 fOutputEventHandler->TerminateIO();
728 // Release object ownership to users after writing data to file
729 if (output->GetData()->InheritsFrom(TCollection::Class())) {
730 // If data is a collection, we set the name of the collection
731 // as the one of the container and we save as a single key.
732 TCollection *coll = (TCollection*)output->GetData();
733 coll->SetName(output->GetName());
734 coll->Write(output->GetName(), TObject::kSingleKey);
736 if (output->GetData()->InheritsFrom(TTree::Class())) {
737 TTree *tree = (TTree*)output->GetData();
738 tree->SetDirectory(file);
741 output->GetData()->Write();
745 printf(" file %s listing content:\n", output->GetFileName());
748 // Clear file list to release object ownership to user.
751 output->SetFile(NULL);
753 // Restore current directory
754 if (opwd) opwd->cd();
755 // Check if a special output location was provided or the output files have to be merged
756 if (strlen(fSpecialOutputLocation.Data())) {
757 TString remote = fSpecialOutputLocation;
759 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
760 if (remote.BeginsWith("alien:")) {
761 gROOT->ProcessLine("TGrid::Connect(\"alien:\", gProofServ->GetUser());");
762 remote += outFilename;
763 remote.ReplaceAll(".root", Form("_%d.root", gid));
765 remote += Form("%s_%d_", gSystem->HostName(), gid);
766 remote += outFilename;
769 Info("PackOutput", "Output file for container %s to be copied \n at: %s. No merging.",
770 output->GetName(), remote.Data());
771 TFile::Cp ( outFilename.Data(), remote.Data() );
772 // Copy extra outputs
773 if (fExtraFiles.Length() && isManagedByHandler) {
774 TObjArray *arr = fExtraFiles.Tokenize(" ");
776 TIter nextfilename(arr);
777 while ((os=(TObjString*)nextfilename())) {
778 outFilename = os->GetString();
779 remote = fSpecialOutputLocation;
781 if (remote.BeginsWith("alien://")) {
782 remote += outFilename;
783 remote.ReplaceAll(".root", Form("_%d.root", gid));
785 remote += Form("%s_%d_", gSystem->HostName(), gid);
786 remote += outFilename;
789 Info("PackOutput", "Extra AOD file %s to be copied \n at: %s. No merging.",
790 outFilename.Data(), remote.Data());
791 TFile::Cp ( outFilename.Data(), remote.Data() );
796 // No special location specified-> use TProofOutputFile as merging utility
797 // The file at this output slot must be opened in CreateOutputObjects
798 if (fDebug > 1) printf(" File for container %s to be merged via file merger...\n", output->GetName());
803 fIOTime += fIOTimer->RealTime();
804 if ((fDebug || IsCollectThroughput())) {
806 fInitTime = fInitTimer->RealTime()-fIOTime-fCPUTime;
807 printf("=Analysis %s= init time: %g[sec]\
808 \n I/O & data mng.: %g [sec]\
809 \n task execution: %g [sec]\
810 \n total time: CPU=%g [sec] REAL=%g[sec]\n",
811 GetName(), fInitTime, fIOTime, fCPUTime, fInitTimer->CpuTime(), fInitTimer->RealTime());
812 if (IsCollectThroughput()) {
813 out << "#summary#########################################################" << endl;
814 out << "train_name " << GetName() << endl;
815 out << "root_time " << fInitTimer->RealTime() << endl;
816 out << "root_cpu " << fInitTimer->CpuTime() << endl;
817 out << "init_time " << fInitTime << endl;
818 out << "io_mng_time " << fIOTime << endl;
819 out << "exec_time " << fCPUTime << endl;
820 TString aliensite = gSystem->Getenv("ALIEN_SITE");
821 out << "alien_site " << aliensite << endl;
823 TString hostname = gSystem->Getenv("ALIEN_HOSTNAME");
824 if (hostname.IsNull()) {
826 gSystem->Exec(Form("hostname -f >> %s", fFileInfoLog.Data()));
828 out << hostname << endl;
833 if (cdir) cdir->cd();
834 if (fDebug > 1) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
837 //______________________________________________________________________________
838 void AliAnalysisManager::ImportWrappers(TList *source)
840 // Import data in output containers from wrappers coming in source.
841 if (fDebug > 1) printf("->AliAnalysisManager::ImportWrappers()\n");
842 fIOTimer->Start(kTRUE);
843 TIter next(fOutputs);
844 AliAnalysisDataContainer *cont;
845 AliAnalysisDataWrapper *wrap;
847 Bool_t inGrid = (fMode == kGridAnalysis)?kTRUE:kFALSE;
848 TDirectory *cdir = gDirectory;
849 while ((cont=(AliAnalysisDataContainer*)next())) {
851 if (cont->GetProducer() && cont->GetProducer()->IsPostEventLoop() && !inGrid) continue;
852 if (cont->IsRegisterDataset()) continue;
853 const char *filename = cont->GetFileName();
854 Bool_t isManagedByHandler = kFALSE;
855 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
856 isManagedByHandler = kTRUE;
857 filename = fOutputEventHandler->GetOutputFileName();
859 if (cont->IsSpecialOutput() || inGrid) {
860 if (strlen(fSpecialOutputLocation.Data())) continue;
861 // Copy merged file from PROOF scratch space.
862 // In case of grid the files are already in the current directory.
864 if (isManagedByHandler && fExtraFiles.Length()) {
865 // Copy extra registered dAOD files.
866 TObjArray *arr = fExtraFiles.Tokenize(" ");
868 TIter nextfilename(arr);
869 while ((os=(TObjString*)nextfilename())) GetFileFromWrapper(os->GetString(), source);
872 if (!GetFileFromWrapper(filename, source)) continue;
874 // Normally we should connect data from the copied file to the
875 // corresponding output container, but it is not obvious how to do this
876 // automatically if several objects in file...
877 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
878 if (!f) f = TFile::Open(filename, "READ");
880 Error("ImportWrappers", "Cannot open file %s in read-only mode", filename);
885 // Cd to the directory pointed by the container
886 TString folder = cont->GetFolderName();
887 if (!folder.IsNull()) f->cd(folder);
888 // Try to fetch first an object having the container name.
889 obj = gDirectory->Get(cont->GetName());
891 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",
892 cont->GetType()->GetName(), cont->GetName(), filename, cont->GetFolderName(), cont->GetName());
895 wrap = new AliAnalysisDataWrapper(obj);
896 wrap->SetDeleteData(kFALSE);
898 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
900 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
905 printf(" Importing data for container %s\n", cont->GetName());
906 if (strlen(filename)) printf(" -> file %s\n", filename);
909 cont->ImportData(wrap);
911 if (cdir) cdir->cd();
913 fIOTime += fIOTimer->RealTime();
914 if (fDebug > 1) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
917 //______________________________________________________________________________
918 void AliAnalysisManager::UnpackOutput(TList *source)
920 // Called by AliAnalysisSelector::Terminate only on the client.
921 fIOTimer->Start(kTRUE);
922 if (fDebug > 1) printf("->AliAnalysisManager::UnpackOutput()\n");
924 Error("UnpackOutput", "No target. Exiting.");
927 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
929 if (fMode == kProofAnalysis) ImportWrappers(source);
931 TIter next(fOutputs);
932 AliAnalysisDataContainer *output;
933 while ((output=(AliAnalysisDataContainer*)next())) {
934 if (!output->GetData()) continue;
935 // Check if there are client tasks that run post event loop
936 if (output->HasConsumers()) {
937 // Disable event loop semaphore
938 output->SetPostEventLoop(kTRUE);
939 TObjArray *list = output->GetConsumers();
940 Int_t ncons = list->GetEntriesFast();
941 for (Int_t i=0; i<ncons; i++) {
942 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
943 task->CheckNotify(kTRUE);
944 // If task is active, execute it
945 if (task->IsPostEventLoop() && task->IsActive()) {
946 if (fDebug > 1) printf("== Executing post event loop task %s\n", task->GetName());
953 fIOTime += fIOTimer->RealTime();
954 if (fDebug > 1) printf("<-AliAnalysisManager::UnpackOutput()\n");
957 //______________________________________________________________________________
958 void AliAnalysisManager::Terminate()
960 // The Terminate() function is the last function to be called during
961 // a query. It always runs on the client, it can be used to present
962 // the results graphically.
963 if (fDebug > 1) printf("->AliAnalysisManager::Terminate()\n");
964 fInitTimer->Start(kTRUE);
965 TDirectory *cdir = gDirectory;
967 AliAnalysisTask *task;
968 AliAnalysisDataContainer *output;
971 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
972 // Call Terminate() for tasks
974 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
975 // Save all the canvases produced by the Terminate
976 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
980 AliSysInfo::AddStamp(Form("%s_TERMINATE",task->ClassName()),0, itask, 2);
982 if (TObject::TestBit(kSaveCanvases)) {
983 if (!gROOT->IsBatch()) {
984 if (fDebug>1) printf("Waiting 5 sec for %s::Terminate() to finish drawing ...\n", task->ClassName());
986 while (timer.RealTime()<5) {
988 gSystem->ProcessEvents();
991 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
992 if (iend==0) continue;
994 for (Int_t ipict=0; ipict<iend; ipict++) {
995 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
996 if (!canvas) continue;
997 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
999 gROOT->GetListOfCanvases()->Delete();
1003 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
1004 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
1005 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
1007 TObjArray *allOutputs = new TObjArray();
1009 for (icont=0; icont<fOutputs->GetEntriesFast(); icont++) allOutputs->Add(fOutputs->At(icont));
1010 if (!IsSkipTerminate())
1011 for (icont=0; icont<fParamCont->GetEntriesFast(); icont++) allOutputs->Add(fParamCont->At(icont));
1012 TIter next1(allOutputs);
1013 TString handlerFile = "";
1014 TString extraOutputs = "";
1015 if (fOutputEventHandler) {
1016 handlerFile = fOutputEventHandler->GetOutputFileName();
1017 extraOutputs = fOutputEventHandler->GetExtraOutputs();
1021 while ((output=(AliAnalysisDataContainer*)next1())) {
1022 // Special outputs or grid files have the files already closed and written.
1024 if (fMode == kGridAnalysis && icont<=fOutputs->GetEntriesFast()) continue;
1025 if (fMode == kProofAnalysis) {
1026 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
1028 const char *filename = output->GetFileName();
1029 TString openoption = "RECREATE";
1030 if (!(strcmp(filename, "default"))) continue;
1031 if (!strlen(filename)) continue;
1032 if (!output->GetData()) continue;
1033 TDirectory *opwd = gDirectory;
1034 TFile *file = output->GetFile();
1035 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1037 //if (handlerFile == filename && !gSystem->AccessPathName(filename)) openoption = "UPDATE";
1038 Bool_t firsttime = kTRUE;
1039 if (filestmp.FindObject(filename) || extraOutputs.Contains(filename)) {
1042 filestmp.Add(new TNamed(filename,""));
1044 if (!gSystem->AccessPathName(filename) && !firsttime) openoption = "UPDATE";
1045 if (fDebug>1) printf("Opening file: %s option=%s\n",filename, openoption.Data());
1046 file = new TFile(filename, openoption);
1048 if (fDebug>1) printf("File <%s> already opened with option: <%s> \n", filename, file->GetOption());
1049 openoption = file->GetOption();
1050 if (openoption == "READ") {
1051 if (fDebug>1) printf("...reopening in UPDATE mode\n");
1052 file->ReOpen("UPDATE");
1055 if (file->IsZombie()) {
1056 Error("Terminate", "Cannot open output file %s", filename);
1059 output->SetFile(file);
1061 // Check for a folder request
1062 TString dir = output->GetFolderName();
1063 if (!dir.IsNull()) {
1064 if (!file->GetDirectory(dir)) file->mkdir(dir);
1067 if (fDebug > 1) printf("...writing container %s to file %s:%s\n", output->GetName(), file->GetName(), output->GetFolderName());
1068 if (output->GetData()->InheritsFrom(TCollection::Class())) {
1069 // If data is a collection, we set the name of the collection
1070 // as the one of the container and we save as a single key.
1071 TCollection *coll = (TCollection*)output->GetData();
1072 coll->SetName(output->GetName());
1073 coll->Write(output->GetName(), TObject::kSingleKey);
1075 if (output->GetData()->InheritsFrom(TTree::Class())) {
1076 TTree *tree = (TTree*)output->GetData();
1077 tree->SetDirectory(gDirectory);
1080 output->GetData()->Write();
1083 if (opwd) opwd->cd();
1087 TString copiedFiles;
1088 while ((output=(AliAnalysisDataContainer*)next1())) {
1089 // Close all files at output
1090 TDirectory *opwd = gDirectory;
1091 if (output->GetFile()) {
1092 // Clear file list to release object ownership to user.
1093 // output->GetFile()->Clear();
1094 output->GetFile()->Close();
1095 // Copy merged outputs in alien if requested
1096 if (fSpecialOutputLocation.BeginsWith("alien://")) {
1097 if (copiedFiles.Contains(output->GetFile()->GetName())) {
1098 if (opwd) opwd->cd();
1099 output->SetFile(NULL);
1102 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
1103 gROOT->ProcessLine("if (!gGrid) TGrid::Connect(\"alien:\");");
1104 TFile::Cp(output->GetFile()->GetName(),
1105 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
1106 copiedFiles += output->GetFile()->GetName();
1108 output->SetFile(NULL);
1110 if (opwd) opwd->cd();
1113 //Write statistics information on the client
1114 if (fStatistics) WriteStatisticsMsg(fNcalls);
1116 TDirectory *crtdir = gDirectory;
1117 TFile f("syswatch.root", "RECREATE");
1120 if (!f.IsZombie()) {
1121 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
1122 tree->SetName("syswatch");
1123 tree->SetMarkerStyle(kCircle);
1124 tree->SetMarkerColor(kBlue);
1125 tree->SetMarkerSize(0.5);
1126 if (!gROOT->IsBatch()) {
1127 tree->SetAlias("event", "id0");
1128 tree->SetAlias("task", "id1");
1129 tree->SetAlias("stage", "id2");
1130 // Already defined aliases
1131 // tree->SetAlias("deltaT","stampSec-stampOldSec");
1132 // tree->SetAlias("T","stampSec-first");
1133 // tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)");
1134 // tree->SetAlias("VM","pI.fMemVirtual");
1135 TCanvas *canvas = new TCanvas("SysInfo","SysInfo",10,10,1200,800);
1136 Int_t npads = 1 /*COO plot for all tasks*/ +
1137 fTopTasks->GetEntries() /*Exec plot per task*/ +
1138 1 /*Terminate plot for all tasks*/ +
1141 Int_t iopt = (Int_t)TMath::Sqrt((Double_t)npads);
1142 if (npads<iopt*(iopt+1))
1143 canvas->Divide(iopt, iopt+1, 0.01, 0.01);
1145 canvas->Divide(iopt+1, iopt+1, 0.01, 0.01);
1147 // draw the plot of deltaVM for Exec for each task
1148 for (itask=0; itask<fTopTasks->GetEntriesFast(); itask++) {
1149 task = (AliAnalysisTask*)fTopTasks->At(itask);
1151 cut = Form("task==%d && stage==1", itask);
1152 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1153 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1155 hist->SetTitle(Form("%s: Exec dVM[MB]/event", task->GetName()));
1156 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1159 // Draw the plot of deltaVM for CreateOutputObjects for all tasks
1161 tree->SetMarkerStyle(kFullTriangleUp);
1162 tree->SetMarkerColor(kRed);
1163 tree->SetMarkerSize(0.8);
1164 cut = "task>=0 && task<1000 && stage==0";
1165 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1166 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1168 hist->SetTitle("Memory in CreateOutputObjects()");
1169 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1170 hist->GetXaxis()->SetTitle("task");
1172 // draw the plot of deltaVM for Terminate for all tasks
1174 tree->SetMarkerStyle(kOpenSquare);
1175 tree->SetMarkerColor(kMagenta);
1176 cut = "task>=0 && task<1000 && stage==2";
1177 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1178 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1180 hist->SetTitle("Memory in Terminate()");
1181 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1182 hist->GetXaxis()->SetTitle("task");
1186 tree->SetMarkerStyle(kFullCircle);
1187 tree->SetMarkerColor(kGreen);
1188 cut = Form("task==%d && stage==1",fTopTasks->GetEntriesFast()-1);
1189 tree->Draw("VM:event",cut,"", 1234567890, 0);
1190 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1192 hist->SetTitle("Virtual memory");
1193 hist->GetYaxis()->SetTitle("VM [MB]");
1197 tree->SetMarkerStyle(kCircle);
1198 tree->SetMarkerColor(kBlue);
1199 tree->SetMarkerSize(0.5);
1204 if (crtdir) crtdir->cd();
1206 // Validate the output files
1207 if (ValidateOutputFiles() && fIsRemote && fMode!=kProofAnalysis) {
1209 out.open("outputs_valid", ios::out);
1212 if (cdir) cdir->cd();
1214 if (fDebug || IsCollectThroughput()) {
1215 printf("=Analysis %s= Terminate time: %g[sec]\n", GetName(), fInitTimer->RealTime());
1217 if (fDebug > 1) printf("<-AliAnalysisManager::Terminate()\n");
1219 //______________________________________________________________________________
1220 void AliAnalysisManager::ProfileTask(Int_t itop, const char *option) const
1222 // Profiles the task having the itop index in the list of top (first level) tasks.
1223 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->At(itop);
1225 Error("ProfileTask", "There are only %d top tasks in the manager", fTopTasks->GetEntries());
1228 ProfileTask(task->GetName(), option);
1231 //______________________________________________________________________________
1232 void AliAnalysisManager::ProfileTask(const char *name, const char */*option*/) const
1234 // Profile a managed task after the execution of the analysis in case NSysInfo
1236 if (gSystem->AccessPathName("syswatch.root")) {
1237 Error("ProfileTask", "No file syswatch.root found in the current directory");
1240 if (gROOT->IsBatch()) return;
1241 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->FindObject(name);
1243 Error("ProfileTask", "No top task named %s known by the manager.", name);
1246 Int_t itop = fTopTasks->IndexOf(task);
1247 Int_t itask = fTasks->IndexOf(task);
1248 // Create canvas with 2 pads: first draw COO + Terminate, second Exec
1249 TDirectory *cdir = gDirectory;
1250 TFile f("syswatch.root");
1251 TTree *tree = (TTree*)f.Get("syswatch");
1253 Error("ProfileTask", "No tree named <syswatch> found in file syswatch.root");
1256 if (fDebug > 1) printf("=== Profiling task %s (class %s)\n", name, task->ClassName());
1257 TCanvas *canvas = new TCanvas(Form("profile_%d",itop),Form("Profile of task %s (class %s)",name,task->ClassName()),10,10,800,600);
1258 canvas->Divide(2, 2, 0.01, 0.01);
1262 // VM profile for COO and Terminate methods
1264 cut = Form("task==%d && (stage==0 || stage==2)",itask);
1265 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1266 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1268 hist->SetTitle("Alocated VM[MB] for COO and Terminate");
1269 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1270 hist->GetXaxis()->SetTitle("method");
1272 // CPU profile per event
1274 cut = Form("task==%d && stage==1",itop);
1275 tree->Draw("deltaT:event",cut,"", 1234567890, 0);
1276 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1278 hist->SetTitle("Execution time per event");
1279 hist->GetYaxis()->SetTitle("CPU/event [s]");
1281 // VM profile for Exec
1283 cut = Form("task==%d && stage==1",itop);
1284 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1285 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1287 hist->SetTitle("Alocated VM[MB] per event");
1288 hist->GetYaxis()->SetTitle("deltaVM [MB]");
1293 if (cdir) cdir->cd();
1296 //______________________________________________________________________________
1297 void AliAnalysisManager::AddTask(AliAnalysisTask *task)
1299 // Adds a user task to the global list of tasks.
1301 Error("AddTask", "Cannot add task %s since InitAnalysis was already called", task->GetName());
1305 if (fTasks->FindObject(task)) {
1306 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
1309 task->SetActive(kFALSE);
1313 //______________________________________________________________________________
1314 AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
1316 // Retreive task by name.
1317 if (!fTasks) return NULL;
1318 return (AliAnalysisTask*)fTasks->FindObject(name);
1321 //______________________________________________________________________________
1322 AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
1323 TClass *datatype, EAliAnalysisContType type, const char *filename)
1325 // Create a data container of a certain type. Types can be:
1326 // kExchangeContainer = 0, used to exchange data between tasks
1327 // kInputContainer = 1, used to store input data
1328 // kOutputContainer = 2, used for writing result to a file
1329 // filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
1330 // the output object to a folder inside the output file
1331 if (fContainers->FindObject(name)) {
1332 Error("CreateContainer","A container named %s already defined !",name);
1335 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
1336 fContainers->Add(cont);
1338 case kInputContainer:
1341 case kOutputContainer:
1342 fOutputs->Add(cont);
1343 if (filename && strlen(filename)) {
1344 cont->SetFileName(filename);
1345 cont->SetDataOwned(kFALSE); // data owned by the file
1348 case kParamContainer:
1349 fParamCont->Add(cont);
1350 if (filename && strlen(filename)) {
1351 cont->SetFileName(filename);
1352 cont->SetDataOwned(kFALSE); // data owned by the file
1355 case kExchangeContainer:
1361 //______________________________________________________________________________
1362 Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
1363 AliAnalysisDataContainer *cont)
1365 // Connect input of an existing task to a data container.
1367 Error("ConnectInput", "Task pointer is NULL");
1370 if (!fTasks->FindObject(task)) {
1372 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
1374 Bool_t connected = task->ConnectInput(islot, cont);
1378 //______________________________________________________________________________
1379 Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
1380 AliAnalysisDataContainer *cont)
1382 // Connect output of an existing task to a data container.
1384 Error("ConnectOutput", "Task pointer is NULL");
1387 if (!fTasks->FindObject(task)) {
1389 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
1391 Bool_t connected = task->ConnectOutput(islot, cont);
1395 //______________________________________________________________________________
1396 void AliAnalysisManager::CleanContainers()
1398 // Clean data from all containers that have already finished all client tasks.
1399 TIter next(fContainers);
1400 AliAnalysisDataContainer *cont;
1401 while ((cont=(AliAnalysisDataContainer *)next())) {
1402 if (cont->IsOwnedData() &&
1403 cont->IsDataReady() &&
1404 cont->ClientsExecuted()) cont->DeleteData();
1408 //______________________________________________________________________________
1409 Bool_t AliAnalysisManager::InitAnalysis()
1411 // Initialization of analysis chain of tasks. Should be called after all tasks
1412 // and data containers are properly connected
1413 // Reset flag and remove valid_outputs file if exists
1414 if (fInitOK) return kTRUE;
1415 if (!gSystem->AccessPathName("outputs_valid"))
1416 gSystem->Unlink("outputs_valid");
1417 // Check for top tasks (depending only on input data containers)
1418 if (!fTasks->First()) {
1419 Error("InitAnalysis", "Analysis has no tasks !");
1423 AliAnalysisTask *task;
1424 AliAnalysisDataContainer *cont;
1427 Bool_t iszombie = kFALSE;
1428 Bool_t istop = kTRUE;
1430 while ((task=(AliAnalysisTask*)next())) {
1433 Int_t ninputs = task->GetNinputs();
1434 for (i=0; i<ninputs; i++) {
1435 cont = task->GetInputSlot(i)->GetContainer();
1439 fZombies->Add(task);
1443 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
1444 i, task->GetName());
1446 if (iszombie) continue;
1447 // Check if cont is an input container
1448 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
1449 // Connect to parent task
1453 fTopTasks->Add(task);
1457 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
1460 // Check now if there are orphan tasks
1461 for (i=0; i<ntop; i++) {
1462 task = (AliAnalysisTask*)fTopTasks->At(i);
1467 while ((task=(AliAnalysisTask*)next())) {
1468 if (!task->IsUsed()) {
1470 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
1473 // Check the task hierarchy (no parent task should depend on data provided
1474 // by a daughter task)
1475 for (i=0; i<ntop; i++) {
1476 task = (AliAnalysisTask*)fTopTasks->At(i);
1477 if (task->CheckCircularDeps()) {
1478 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
1483 // Check that all containers feeding post-event loop tasks are in the outputs list
1484 TIter nextcont(fContainers); // loop over all containers
1485 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1486 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1487 if (cont->HasConsumers()) {
1488 // Check if one of the consumers is post event loop
1489 TIter nextconsumer(cont->GetConsumers());
1490 while ((task=(AliAnalysisTask*)nextconsumer())) {
1491 if (task->IsPostEventLoop()) {
1492 fOutputs->Add(cont);
1499 // Check if all special output containers have a file name provided
1500 TIter nextout(fOutputs);
1501 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1502 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1503 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1507 // Initialize requested branch list if needed
1508 if (!fAutoBranchHandling) {
1510 while ((task=(AliAnalysisTask*)next())) {
1511 if (!task->HasBranches()) {
1512 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\"",
1513 task->GetName(), task->ClassName());
1516 if (!fInputEventHandler || !strlen(fInputEventHandler->GetDataType())) {
1517 Error("InitAnalysis", "Manual branch loading requested but no input handler defined or handler does not define data type.");
1520 TString taskbranches;
1521 task->GetBranches(fInputEventHandler->GetDataType(), taskbranches);
1522 if (taskbranches.IsNull()) {
1523 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches of type %s:",
1524 task->GetName(), task->ClassName(), fInputEventHandler->GetDataType());
1527 AddBranches(taskbranches);
1534 //______________________________________________________________________________
1535 void AliAnalysisManager::AddBranches(const char *branches)
1537 // Add branches to the existing fRequestedBranches.
1538 TString br(branches);
1539 TObjArray *arr = br.Tokenize(",");
1542 while ((obj=next())) {
1543 if (!fRequestedBranches.Contains(obj->GetName())) {
1544 if (!fRequestedBranches.IsNull()) fRequestedBranches += ",";
1545 fRequestedBranches += obj->GetName();
1551 //______________________________________________________________________________
1552 void AliAnalysisManager::CheckBranches(Bool_t load)
1554 // The method checks the input branches to be loaded during the analysis.
1555 if (fAutoBranchHandling || fRequestedBranches.IsNull() || !fTree) return;
1556 TObjArray *arr = fRequestedBranches.Tokenize(",");
1559 while ((obj=next())) {
1560 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(obj->GetName()));
1562 br = fTree->GetBranch(obj->GetName());
1564 Error("CheckBranches", "Could not find branch %s",obj->GetName());
1569 if (load && br->GetReadEntry()!=GetCurrentEntry()) {
1570 br->GetEntry(GetCurrentEntry());
1576 //______________________________________________________________________________
1577 Bool_t AliAnalysisManager::CheckTasks() const
1579 // Check consistency of tasks.
1580 Int_t ntasks = fTasks->GetEntries();
1582 Error("CheckTasks", "No tasks connected to the manager. This may be due to forgetting to compile the task or to load their library.");
1585 // Get the pointer to AliAnalysisTaskSE::Class()
1586 TClass *badptr = (TClass*)gROOT->ProcessLine("AliAnalysisTaskSE::Class()");
1587 // Loop all tasks to check if their corresponding library was loaded
1590 while ((obj=next())) {
1591 if (obj->IsA() == badptr) {
1592 Error("CheckTasks", "##################\n \
1593 Class for task %s NOT loaded. You probably forgot to load the library for this task (or compile it dynamically).\n###########################\n",obj->GetName());
1600 //______________________________________________________________________________
1601 void AliAnalysisManager::PrintStatus(Option_t *option) const
1603 // Print task hierarchy.
1605 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1608 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1610 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
1611 TIter next(fTopTasks);
1612 AliAnalysisTask *task;
1613 while ((task=(AliAnalysisTask*)next()))
1614 task->PrintTask(option);
1616 if (!fAutoBranchHandling && !fRequestedBranches.IsNull())
1617 printf("Requested input branches:\n%s\n", fRequestedBranches.Data());
1619 TString sopt(option);
1622 if (sopt.Contains("ALL"))
1624 if ( fOutputEventHandler )
1626 cout << TString('_',78) << endl;
1627 cout << "OutputEventHandler:" << endl;
1628 fOutputEventHandler->Print(" ");
1633 //______________________________________________________________________________
1634 void AliAnalysisManager::ResetAnalysis()
1636 // Reset all execution flags and clean containers.
1640 //______________________________________________________________________________
1641 void AliAnalysisManager::RunLocalInit()
1643 // Run LocalInit method for all tasks.
1644 TDirectory *cdir = gDirectory;
1645 if (IsTrainInitialized()) return;
1646 TIter nextTask(fTasks);
1647 AliAnalysisTask *task;
1648 while ((task=(AliAnalysisTask*)nextTask())) {
1652 if (cdir) cdir->cd();
1653 TObject::SetBit(kTasksInitialized, kTRUE);
1656 //______________________________________________________________________________
1657 Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
1659 // Start analysis having a grid handler.
1660 if (!fGridHandler) {
1661 Error("StartAnalysis", "Cannot start analysis providing just the analysis type without a grid handler.");
1662 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1666 return StartAnalysis(type, tree, nentries, firstentry);
1669 //______________________________________________________________________________
1670 Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
1672 // Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1673 // MIX. Process nentries starting from firstentry
1675 // Backup current directory and make sure gDirectory points to gROOT
1676 TDirectory *cdir = gDirectory;
1679 Error("StartAnalysis","Analysis manager was not initialized !");
1680 if (cdir) cdir->cd();
1683 if (!CheckTasks()) Fatal("StartAnalysis", "Not all needed libraries were loaded");
1685 printf("StartAnalysis %s\n",GetName());
1686 AliLog::SetGlobalLogLevel(AliLog::kInfo);
1688 fMaxEntries = nentries;
1690 TString anaType = type;
1692 fMode = kLocalAnalysis;
1693 if (anaType.Contains("file")) fIsRemote = kTRUE;
1694 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1695 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1696 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1698 if (fMode == kGridAnalysis) {
1700 if (!anaType.Contains("terminate")) {
1701 if (!fGridHandler) {
1702 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1703 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1704 if (cdir) cdir->cd();
1707 // Write analysis manager in the analysis file
1708 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1709 // run local task configuration
1711 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1712 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1713 if (cdir) cdir->cd();
1717 // Terminate grid analysis
1718 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1719 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1720 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1721 if (!fGridHandler->MergeOutputs()) {
1722 // Return if outputs could not be merged or if it alien handler
1723 // was configured for offline mode or local testing.
1724 if (cdir) cdir->cd();
1728 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1729 if (cdir) cdir->cd();
1730 ImportWrappers(NULL);
1732 if (cdir) cdir->cd();
1736 SetEventLoop(kFALSE);
1737 // Enable event loop mode if a tree was provided
1738 if (tree || fGridHandler || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
1741 TString ttype = "TTree";
1742 if (tree && tree->IsA() == TChain::Class()) {
1743 chain = (TChain*)tree;
1744 if (!chain || !chain->GetListOfFiles()->First()) {
1745 Error("StartAnalysis", "Cannot process null or empty chain...");
1746 if (cdir) cdir->cd();
1752 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1753 if (getsysInfo) AliSysInfo::AddStamp("Start", 0);
1754 // Initialize locally all tasks (happens for all modes)
1756 AliAnalysisTask *task;
1760 case kLocalAnalysis:
1761 if (!tree && !fGridHandler) {
1762 TIter nextT(fTasks);
1763 // Call CreateOutputObjects for all tasks
1765 Bool_t dirStatus = TH1::AddDirectoryStatus();
1766 while ((task=(AliAnalysisTask*)nextT())) {
1767 TH1::AddDirectory(kFALSE);
1768 task->CreateOutputObjects();
1769 if (!task->CheckPostData()) {
1770 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
1771 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
1772 ########### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ###########", task->GetName(), task->ClassName());
1774 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
1778 TH1::AddDirectory(dirStatus);
1779 if (IsExternalLoop()) {
1780 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1781 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1788 fSelector = new AliAnalysisSelector(this);
1789 // Check if a plugin handler is used
1791 // Get the chain from the plugin
1792 TString dataType = "esdTree";
1793 if (fInputEventHandler) {
1794 dataType = fInputEventHandler->GetDataType();
1798 chain = fGridHandler->GetChainForTestMode(dataType);
1800 Error("StartAnalysis", "No chain for test mode. Aborting.");
1803 cout << "===== RUNNING LOCAL ANALYSIS" << GetName() << " ON CHAIN " << chain->GetName() << endl;
1804 retv = chain->Process(fSelector, "", nentries, firstentry);
1807 // Run tree-based analysis via AliAnalysisSelector
1808 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
1809 retv = tree->Process(fSelector, "", nentries, firstentry);
1811 case kProofAnalysis:
1813 // Check if the plugin is used
1815 return StartAnalysis(type, fGridHandler->GetProofDataSet(), nentries, firstentry);
1817 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1818 Error("StartAnalysis", "No PROOF!!! Exiting.");
1819 if (cdir) cdir->cd();
1822 line = Form("gProof->AddInput((TObject*)%p);", this);
1823 gROOT->ProcessLine(line);
1826 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
1827 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
1829 Error("StartAnalysis", "No chain!!! Exiting.");
1830 if (cdir) cdir->cd();
1836 if (!anaType.Contains("terminate")) {
1837 if (!fGridHandler) {
1838 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1839 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1840 if (cdir) cdir->cd();
1843 // Write analysis manager in the analysis file
1844 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1845 // Start the analysis via the handler
1846 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1847 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1848 if (cdir) cdir->cd();
1852 // Terminate grid analysis
1853 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1854 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
1855 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1856 if (!fGridHandler->MergeOutputs()) {
1857 // Return if outputs could not be merged or if it alien handler
1858 // was configured for offline mode or local testing.
1859 if (cdir) cdir->cd();
1863 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1864 ImportWrappers(NULL);
1866 if (cdir) cdir->cd();
1868 case kMixingAnalysis:
1869 // Run event mixing analysis
1871 Error("StartAnalysis", "Cannot run event mixing without event pool");
1872 if (cdir) cdir->cd();
1875 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1876 fSelector = new AliAnalysisSelector(this);
1877 while ((chain=fEventPool->GetNextChain())) {
1879 // Call NotifyBinChange for all tasks
1880 while ((task=(AliAnalysisTask*)next()))
1881 if (!task->IsPostEventLoop()) task->NotifyBinChange();
1882 retv = chain->Process(fSelector);
1884 Error("StartAnalysis", "Mixing analysis failed");
1885 if (cdir) cdir->cd();
1889 PackOutput(fSelector->GetOutputList());
1892 if (cdir) cdir->cd();
1896 //______________________________________________________________________________
1897 Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
1899 // Start analysis for this manager on a given dataset. Analysis task can be:
1900 // LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1902 Error("StartAnalysis","Analysis manager was not initialized !");
1906 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
1907 TString anaType = type;
1909 if (!anaType.Contains("proof")) {
1910 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
1913 fMode = kProofAnalysis;
1915 SetEventLoop(kTRUE);
1916 // Set the dataset flag
1917 TObject::SetBit(kUseDataSet);
1920 // Start proof analysis using the grid handler
1921 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1922 Error("StartAnalysis", "The grid plugin could not start PROOF analysis");
1925 // Check if the plugin is in test mode
1926 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kTest) {
1927 dataset = "test_collection";
1929 dataset = fGridHandler->GetProofDataSet();
1933 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1934 Error("StartAnalysis", "No PROOF!!! Exiting.");
1938 // Initialize locally all tasks
1941 line = Form("gProof->AddInput((TObject*)%p);", this);
1942 gROOT->ProcessLine(line);
1944 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"\", %lld, %lld);",
1945 dataset, nentries, firstentry);
1946 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
1947 retv = (Long_t)gROOT->ProcessLine(line);
1951 //______________________________________________________________________________
1952 TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
1954 // Opens according the option the file specified by cont->GetFileName() and changes
1955 // current directory to cont->GetFolderName(). If the file was already opened, it
1956 // checks if the option UPDATE was preserved. File open via TProofOutputFile can
1957 // be optionally ignored.
1958 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1959 TString filename = cont->GetFileName();
1961 if (filename.IsNull()) {
1962 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
1965 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
1967 f = mgr->OpenProofFile(cont,option);
1969 // Check first if the file is already opened
1970 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1972 // Check if option "UPDATE" was preserved
1973 TString opt(option);
1975 if ((opt=="UPDATE") && (opt!=f->GetOption()))
1976 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
1978 f = TFile::Open(filename, option);
1981 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1985 // Check for a folder request
1986 TString dir = cont->GetFolderName();
1987 if (!dir.IsNull()) {
1988 if (!f->GetDirectory(dir)) f->mkdir(dir);
1993 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
1994 cont->SetFile(NULL);
1998 //______________________________________________________________________________
1999 TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option, const char *extaod)
2001 // Opens a special output file used in PROOF.
2003 TString filename = cont->GetFileName();
2004 if (cont == fCommonOutput) {
2005 if (fOutputEventHandler) {
2006 if (strlen(extaod)) filename = extaod;
2007 filename = fOutputEventHandler->GetOutputFileName();
2009 else Fatal("OpenProofFile","No output container. Exiting.");
2012 if (fMode!=kProofAnalysis || !fSelector) {
2013 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
2016 if (fSpecialOutputLocation.Length()) {
2017 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2019 // Check if option "UPDATE" was preserved
2020 TString opt(option);
2022 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2023 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
2025 f = new TFile(filename, option);
2027 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2031 // Check for a folder request
2032 TString dir = cont->GetFolderName();
2034 if (!f->GetDirectory(dir)) f->mkdir(dir);
2039 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2040 cont->SetFile(NULL);
2043 // Check if there is already a proof output file in the output list
2044 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
2046 // Get the actual file
2047 line = Form("((TProofOutputFile*)%p)->GetFileName();", pof);
2048 filename = (const char*)gROOT->ProcessLine(line);
2050 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
2052 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2054 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
2057 // Check if option "UPDATE" was preserved
2058 TString opt(option);
2060 if ((opt=="UPDATE") && (opt!=f->GetOption()))
2061 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
2063 if (cont->IsRegisterDataset()) {
2064 TString dsetName = filename;
2065 dsetName.ReplaceAll(".root", cont->GetTitle());
2066 dsetName.ReplaceAll(":","_");
2067 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
2068 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
2070 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
2071 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
2073 if (fDebug > 1) printf("=== %s\n", line.Data());
2074 gROOT->ProcessLine(line);
2075 line = Form("pf->OpenFile(\"%s\");", option);
2076 gROOT->ProcessLine(line);
2079 gROOT->ProcessLine("pf->Print()");
2080 printf(" == proof file name: %s", f->GetName());
2082 // Add to proof output list
2083 line = Form("((TList*)%p)->Add(pf);",fSelector->GetOutputList());
2084 if (fDebug > 1) printf("=== %s\n", line.Data());
2085 gROOT->ProcessLine(line);
2087 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2091 // Check for a folder request
2092 TString dir = cont->GetFolderName();
2093 if (!dir.IsNull()) {
2094 if (!f->GetDirectory(dir)) f->mkdir(dir);
2099 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2100 cont->SetFile(NULL);
2104 //______________________________________________________________________________
2105 void AliAnalysisManager::ExecAnalysis(Option_t *option)
2107 // Execute analysis.
2108 static Long64_t nentries = 0;
2109 static TTree *lastTree = 0;
2110 static TStopwatch *timer = new TStopwatch();
2111 // Only the first call to Process will trigger a true Notify. Other Notify
2112 // coming before is ignored.
2113 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) {
2114 TObject::SetBit(AliAnalysisManager::kTrueNotify);
2117 if (fDebug > 0) printf("MGR: Processing event #%d\n", fNcalls);
2119 if (fTree && (fTree != lastTree)) {
2120 nentries += fTree->GetEntries();
2123 if (!fNcalls) timer->Start();
2124 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", fNcalls, TMath::Min(fMaxEntries,nentries), timer, kFALSE);
2126 fIOTimer->Start(kTRUE);
2128 TDirectory *cdir = gDirectory;
2129 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
2130 if (getsysInfo && ((fNcalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)fNcalls);
2132 Error("ExecAnalysis", "Analysis manager was not initialized !");
2133 if (cdir) cdir->cd();
2137 AliAnalysisTask *task;
2138 // Check if the top tree is active.
2140 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2141 AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
2143 // De-activate all tasks
2144 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
2145 AliAnalysisDataContainer *cont = fCommonInput;
2146 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
2148 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
2149 if (cdir) cdir->cd();
2152 cont->SetData(fTree); // This will notify all consumers
2153 Long64_t entry = fTree->GetTree()->GetReadEntry();
2155 // Call BeginEvent() for optional input/output and MC services
2156 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
2157 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
2158 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
2160 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2161 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2163 // Execute the tasks
2164 // TIter next1(cont->GetConsumers());
2166 fIOTime += fIOTimer->RealTime();
2167 fCPUTimer->Start(kTRUE);
2168 TIter next1(fTopTasks);
2170 while ((task=(AliAnalysisTask*)next1())) {
2172 cout << " Executing task " << task->GetName() << endl;
2174 task->ExecuteTask(option);
2176 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2177 AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
2181 fCPUTime += fCPUTimer->RealTime();
2182 fIOTimer->Start(kTRUE);
2184 // Call FinishEvent() for optional output and MC services
2185 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2186 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2187 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2188 // Gather system information if requested
2189 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2190 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1001, 1);
2191 if (cdir) cdir->cd();
2193 fIOTime += fIOTimer->RealTime();
2196 // The event loop is not controlled by TSelector
2198 // Call BeginEvent() for optional input/output and MC services
2199 fIOTimer->Start(kTRUE);
2200 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
2201 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
2202 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
2204 fIOTime += fIOTimer->RealTime();
2206 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2207 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
2208 fCPUTimer->Start(kTRUE);
2209 TIter next2(fTopTasks);
2210 while ((task=(AliAnalysisTask*)next2())) {
2211 task->SetActive(kTRUE);
2213 cout << " Executing task " << task->GetName() << endl;
2215 task->ExecuteTask(option);
2219 fCPUTime += fCPUTimer->RealTime();
2221 // Call FinishEvent() for optional output and MC services
2222 fIOTimer->Start(kTRUE);
2223 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2224 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2225 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
2226 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2227 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
2228 if (cdir) cdir->cd();
2230 fIOTime += fIOTimer->RealTime();
2233 //______________________________________________________________________________
2234 Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
2236 // Check if the stdout is connected to a pipe (C.Holm)
2237 Bool_t ispipe = kFALSE;
2238 out.seekp(0, std::ios_base::cur);
2241 if (errno == ESPIPE) ispipe = kTRUE;
2246 //______________________________________________________________________________
2247 void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
2249 // Set the input event handler and create a container for it.
2251 fInputEventHandler = handler;
2252 if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
2255 //______________________________________________________________________________
2256 void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
2258 // Set the input event handler and create a container for it.
2260 fOutputEventHandler = handler;
2261 if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
2262 fCommonOutput->SetSpecialOutput();
2265 //______________________________________________________________________________
2266 void AliAnalysisManager::SetDebugLevel(UInt_t level)
2268 // Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
2269 if (TObject::TestBit(kUseProgressBar)) {
2270 Info("SetDebugLevel","Ignored. Disable the progress bar first.");
2276 //______________________________________________________________________________
2277 void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
2279 // Enable a text mode progress bar. Resets debug level to 0.
2280 Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
2281 TObject::SetBit(kUseProgressBar,flag);
2282 fPBUpdateFreq = freq;
2286 //______________________________________________________________________________
2287 void AliAnalysisManager::RegisterExtraFile(const char *fname)
2289 // This method is used externally to register output files which are not
2290 // connected to any output container, so that the manager can properly register,
2291 // retrieve or merge them when running in distributed mode. The file names are
2292 // separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
2293 if (fExtraFiles.Contains(fname)) return;
2294 if (fExtraFiles.Length()) fExtraFiles += " ";
2295 fExtraFiles += fname;
2298 //______________________________________________________________________________
2299 Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
2301 // Copy a file from the location specified ina the wrapper with the same name from the source list.
2305 TObject *pof = source->FindObject(filename);
2306 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
2307 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
2310 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
2311 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
2312 TString clientUrl(chUrl);
2313 TString fullPath_str(fullPath);
2314 if (clientUrl.Contains("localhost")){
2315 TObjArray* array = fullPath_str.Tokenize ( "//" );
2316 TObjString *strobj = ( TObjString *)array->At(1);
2317 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
2318 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
2319 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
2320 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
2321 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
2325 else if (clientUrl.Contains("__lite__")) {
2326 // Special case for ProofLite environement - get file info and copy.
2327 gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
2328 fullPath_str = Form("%s/%s", tmp, fullPath);
2331 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
2332 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
2334 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
2338 //______________________________________________________________________________
2339 void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
2341 // Fill analysis type in the provided string.
2343 case kLocalAnalysis:
2346 case kProofAnalysis:
2352 case kMixingAnalysis:
2357 //______________________________________________________________________________
2358 Bool_t AliAnalysisManager::ValidateOutputFiles() const
2360 // Validate all output files.
2361 TIter next(fOutputs);
2362 AliAnalysisDataContainer *output;
2363 TDirectory *cdir = gDirectory;
2364 TString openedFiles;
2365 while ((output=(AliAnalysisDataContainer*)next())) {
2366 if (output->IsRegisterDataset()) continue;
2367 TString filename = output->GetFileName();
2368 if (filename == "default") {
2369 if (!fOutputEventHandler) continue;
2370 filename = fOutputEventHandler->GetOutputFileName();
2371 // Main AOD may not be there
2372 if (gSystem->AccessPathName(filename)) continue;
2374 // Check if the file is closed
2375 if (openedFiles.Contains(filename)) continue;;
2376 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2378 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
2379 // Clear file list to release object ownership to user.
2383 file = TFile::Open(filename);
2384 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
2385 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
2386 if (cdir) cdir->cd();
2390 openedFiles += filename;
2393 if (cdir) cdir->cd();
2397 //______________________________________________________________________________
2398 void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
2400 // Implements a nice text mode progress bar.
2401 static Long64_t icount = 0;
2402 static TString oname;
2403 static TString nname;
2404 static Long64_t ocurrent = 0;
2405 static Long64_t osize = 0;
2406 static Int_t oseconds = 0;
2407 static TStopwatch *owatch = 0;
2408 static Bool_t oneoftwo = kFALSE;
2409 static Int_t nrefresh = 0;
2410 static Int_t nchecks = 0;
2411 static char lastChar = 0;
2412 const char symbol[4] = {'-','\\','|','/'};
2414 if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
2420 ocurrent = TMath::Abs(current);
2421 osize = TMath::Abs(size);
2422 if (ocurrent > osize) ocurrent=osize;
2427 if ((current % fPBUpdateFreq) != 0) return;
2429 char progress[11] = " ";
2430 Int_t ichar = icount%4;
2435 if (owatch && !last) {
2437 time = owatch->RealTime();
2438 seconds = int(time) % 60;
2439 minutes = (int(time) / 60) % 60;
2440 hours = (int(time) / 60 / 60);
2442 if (oseconds==seconds) {
2446 oneoftwo = !oneoftwo;
2450 if (refresh && oneoftwo) {
2452 if (nchecks <= 0) nchecks = nrefresh+1;
2453 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
2454 oname = Form(" == %d%% ==", pctdone);
2456 Double_t percent = 100.0*ocurrent/osize;
2457 Int_t nchar = Int_t(percent/10);
2458 if (nchar>10) nchar=10;
2460 for (i=0; i<nchar; i++) progress[i] = '=';
2461 progress[nchar] = symbol[ichar];
2462 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2463 progress[10] = '\0';
2466 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2467 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2468 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
2470 Int_t full = Int_t(ocurrent > 0 ?
2471 time * (float(osize)/ocurrent) + .5 :
2473 Int_t remain = Int_t(full - time);
2474 Int_t rsec = remain % 60;
2475 Int_t rmin = (remain / 60) % 60;
2476 Int_t rhour = (remain / 60 / 60);
2477 fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
2478 percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
2480 else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
2481 if (refresh && oneoftwo) oname = nname;
2482 if (owatch) owatch->Continue();
2491 fprintf(stderr, "\n");
2495 //______________________________________________________________________________
2496 void AliAnalysisManager::DoLoadBranch(const char *name)
2498 // Get tree and load branch if needed.
2499 static Long64_t crtEntry = -100;
2501 if (fAutoBranchHandling || !fTree)
2504 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2506 br = fTree->GetBranch(name);
2508 Error("DoLoadBranch", "Could not find branch %s",name);
2513 if (br->GetReadEntry()==fCurrentEntry) return;
2514 Long64_t readbytes = br->GetEntry(GetCurrentEntry());
2516 Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
2517 if (crtEntry != fCurrentEntry) {
2518 CountEvent(1,0,1,0);
2519 crtEntry = fCurrentEntry;
2522 if (crtEntry != fCurrentEntry) {
2523 CountEvent(1,1,0,0);
2524 crtEntry = fCurrentEntry;
2529 //______________________________________________________________________________
2530 void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
2532 // Add the statistics task to the manager.
2534 Info("AddStatisticsTask", "Already added");
2537 TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
2538 gROOT->ProcessLine(line);
2541 //______________________________________________________________________________
2542 void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
2544 // Bookkeep current event;
2545 if (!fStatistics) return;
2546 fStatistics->AddInput(ninput);
2547 fStatistics->AddProcessed(nprocessed);
2548 fStatistics->AddFailed(nfailed);
2549 fStatistics->AddAccepted(naccepted);
2552 //______________________________________________________________________________
2553 void AliAnalysisManager::AddStatisticsMsg(const char *line)
2555 // Add a line in the statistics message. If available, the statistics message is written
2556 // at the end of the SlaveTerminate phase on workers AND at the end of Terminate
2558 if (!strlen(line)) return;
2559 if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
2560 fStatisticsMsg += line;
2563 //______________________________________________________________________________
2564 void AliAnalysisManager::WriteStatisticsMsg(Int_t)
2566 // If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
2567 static Bool_t done = kFALSE;
2570 if (!fStatistics) return;
2572 AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
2573 AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
2574 AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
2575 AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
2576 out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
2577 fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
2578 fStatistics->GetNaccepted()), ios::out);
2579 out << fStatisticsMsg << endl;
2583 //______________________________________________________________________________
2584 const char* AliAnalysisManager::GetOADBPath()
2586 // returns the path of the OADB
2587 // this static function just depends on environment variables
2589 static TString oadbPath;
2591 if (gSystem->Getenv("OADB_PATH"))
2592 oadbPath = gSystem->Getenv("OADB_PATH");
2593 else if (gSystem->Getenv("ALICE_ROOT"))
2594 oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
2596 ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
2601 //______________________________________________________________________________
2602 void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
2604 // Define a custom string variable mapped to a global unique name. The variable
2605 // can be then retrieved by a given analysis macro via GetGlobalStr(key).
2606 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2608 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2611 Bool_t valid = kFALSE;
2612 TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
2614 ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
2617 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
2620 //______________________________________________________________________________
2621 const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
2623 // Static method to retrieve a global variable defined via SetGlobalStr.
2625 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2627 TObject *value = mgr->GetGlobals()->GetValue(key);
2628 if (!value) return 0;
2630 return value->GetName();
2633 //______________________________________________________________________________
2634 void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
2636 // Define a custom integer variable mapped to a global unique name. The variable
2637 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2638 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2640 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2643 Bool_t valid = kFALSE;
2644 Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
2646 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
2649 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
2652 //______________________________________________________________________________
2653 Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
2655 // Static method to retrieve a global variable defined via SetGlobalInt.
2657 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2659 TObject *value = mgr->GetGlobals()->GetValue(key);
2660 if (!value) return 0;
2662 TString s = value->GetName();
2666 //______________________________________________________________________________
2667 void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
2669 // Define a custom double precision variable mapped to a global unique name. The variable
2670 // can be then retrieved by a given analysis macro via GetGlobalInt(key).
2671 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2673 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2676 Bool_t valid = kFALSE;
2677 Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
2679 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
2682 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));
2685 //______________________________________________________________________________
2686 Double_t AliAnalysisManager::GetGlobalDbl(const char *key, Bool_t &valid)
2688 // Static method to retrieve a global variable defined via SetGlobalDbl.
2690 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2692 TObject *value = mgr->GetGlobals()->GetValue(key);
2693 if (!value) return 0;
2695 TString s = value->GetName();
2699 //______________________________________________________________________________
2700 void AliAnalysisManager::AddClassDebug(const char *className, Int_t debugLevel)
2702 // Sets Class debug level
2704 if (!fDebugOptions) {
2705 fDebugOptions = new TObjArray();
2706 fDebugOptions->SetOwner(kTRUE);
2709 // substracting DebugOffset, beacuse of AliLog::SetClassDebugLevel()
2710 debugLevel -= AliLog::kDebug-1;
2712 TNamed *debugOpt = (TNamed*)fDebugOptions->FindObject(className);
2714 AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel+AliLog::kDebug-1,className).Data());
2715 fDebugOptions->Add(new TNamed(className,TString::Format("%d",debugLevel).Data()));
2717 TString oldDebugStr = debugOpt->GetTitle();
2718 Int_t oldDebug = oldDebugStr.Atoi();
2719 if (debugLevel > oldDebug) {
2720 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());
2721 debugOpt->SetTitle(TString::Format("%d",debugLevel).Data());
2723 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());
2728 //______________________________________________________________________________
2729 void AliAnalysisManager::ApplyDebugOptions()
2731 // Apply debug options
2733 if (!fDebugOptions) return;
2735 TIter next(fDebugOptions);
2738 while ((debug=dynamic_cast<TNamed*>(next()))) {
2739 debugLevel = debug->GetTitle();
2740 AliInfo(TString::Format("ApplyDebugOptions : Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()+AliLog::kDebug-1).Data());
2741 AliLog::SetClassDebugLevel(debug->GetName(), debugLevel.Atoi());
2745 //______________________________________________________________________________
2746 void AliAnalysisManager::Lock()
2748 // Security lock. This is to detect NORMAL user errors and not really to
2749 // protect against intentional hacks.
2750 if (fLocked) return;
2752 if (fInputEventHandler) fInputEventHandler->Lock();
2753 if (fOutputEventHandler) fOutputEventHandler->Lock();
2754 if (fMCtruthEventHandler) fMCtruthEventHandler->Lock();
2755 Info("Lock","====== ANALYSIS MANAGER LOCKED ======");
2758 //______________________________________________________________________________
2759 void AliAnalysisManager::UnLock()
2761 // Verbose unlocking. Hackers will be punished ;-) ...
2762 if (!fLocked) return;
2764 if (fInputEventHandler) fInputEventHandler->UnLock();
2765 if (fOutputEventHandler) fOutputEventHandler->UnLock();
2766 if (fMCtruthEventHandler) fMCtruthEventHandler->UnLock();
2767 Info("UnLock", "====== ANALYSIS MANAGER UNLOCKED ======");
2770 //______________________________________________________________________________
2771 void AliAnalysisManager::Changed()
2773 // All critical setters pass through the Changed method that throws an exception
2774 // in case the lock was set.
2775 if (fLocked) Fatal("Changed","Critical setter called in locked mode");