]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ANALYSIS/AliAnalysisManager.cxx
fix: minor logical inconsistancy in AliAnalysisTaskPi0Flow constructor.
[u/mrichter/AliRoot.git] / ANALYSIS / AliAnalysisManager.cxx
CommitLineData
d3106602 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/* $Id$ */
17// Author: Andrei Gheata, 31/05/2006
18
19//==============================================================================
c7597be6 20// AliAnalysisManager - Manager analysis class. Allows creation of several
37153431 21// analysis tasks and data containers storing their input/output. Allows
d3106602 22// connecting/chaining tasks via shared data containers. Serializes the current
23// event for all tasks depending only on initial input data.
24//==============================================================================
25//
26//==============================================================================
27
f5cbe261 28#include "AliAnalysisManager.h"
11026a80 29
8ddad121 30#include <cerrno>
f5cbe261 31#include <Riostream.h>
84fcd93f 32#include <TError.h>
77dad4a9 33#include <TMap.h>
c52c2132 34#include <TClass.h>
35#include <TFile.h>
096b5a2e 36#include <TMath.h>
37#include <TH1.h>
c52c2132 38#include <TMethodCall.h>
39#include <TChain.h>
40#include <TSystem.h>
41#include <TROOT.h>
8c0ab8e8 42#include <TCanvas.h>
a0e2e8b1 43#include <TStopwatch.h>
d3106602 44
20b7268e 45#include "AliLog.h"
8d7d3b59 46#include "AliAnalysisSelector.h"
c57f56b7 47#include "AliAnalysisGrid.h"
d3106602 48#include "AliAnalysisTask.h"
49#include "AliAnalysisDataContainer.h"
50#include "AliAnalysisDataSlot.h"
d2f1d9ef 51#include "AliVEventHandler.h"
c2922515 52#include "AliVEventPool.h"
8c0ab8e8 53#include "AliSysInfo.h"
f5cbe261 54#include "AliAnalysisStatistics.h"
d3106602 55
c82bb898 56using std::ofstream;
57using std::ios;
58using std::cout;
59using std::endl;
d3106602 60ClassImp(AliAnalysisManager)
61
c52c2132 62AliAnalysisManager *AliAnalysisManager::fgAnalysisManager = NULL;
84fcd93f 63TString AliAnalysisManager::fgCommonFileName = "";
f03a8355 64Int_t AliAnalysisManager::fPBUpdateFreq = 1;
c52c2132 65
c52c2132 66//______________________________________________________________________________
67AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
68 :TNamed(name,title),
9162405c 69 fTree(0),
70 fInputEventHandler(0),
71 fOutputEventHandler(0),
72 fMCtruthEventHandler(0),
73 fEventPool(0),
c52c2132 74 fCurrentEntry(-1),
8c0ab8e8 75 fNSysInfo(0),
c52c2132 76 fMode(kLocalAnalysis),
77 fInitOK(kFALSE),
270bc710 78 fMustClean(kFALSE),
8e1f0465 79 fIsRemote(kFALSE),
c52c2132 80 fDebug(0),
26f071d8 81 fSpecialOutputLocation(""),
9162405c 82 fTasks(0),
83 fTopTasks(0),
84 fZombies(0),
85 fContainers(0),
86 fInputs(0),
87 fOutputs(0),
88 fParamCont(0),
89 fDebugOptions(0),
90 fFileDescriptors(new TObjArray()),
91 fCurrentDescriptor(0),
92 fCommonInput(0),
93 fCommonOutput(0),
94 fSelector(0),
95 fGridHandler(0),
96 fExtraFiles(),
97 fFileInfoLog(),
012e169c 98 fAutoBranchHandling(kTRUE),
242accb2 99 fTable(),
e9247450 100 fRunFromPath(0),
101 fNcalls(0),
f03a8355 102 fMaxEntries(0),
7acc5b9d 103 fStatisticsMsg(),
f5cbe261 104 fRequestedBranches(),
77dad4a9 105 fStatistics(0),
106 fGlobals(0)
d3106602 107{
108// Default constructor.
c52c2132 109 fgAnalysisManager = this;
84fcd93f 110 fgCommonFileName = "AnalysisResults.root";
77dad4a9 111 if (TClass::IsCallingNew() != TClass::kDummyNew) {
112 fTasks = new TObjArray();
113 fTopTasks = new TObjArray();
114 fZombies = new TObjArray();
115 fContainers = new TObjArray();
116 fInputs = new TObjArray();
117 fOutputs = new TObjArray();
118 fParamCont = new TObjArray();
119 fGlobals = new TMap();
120 }
b1310ef5 121 SetEventLoop(kTRUE);
d3106602 122}
123
124//______________________________________________________________________________
125AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
c52c2132 126 :TNamed(other),
327eaf46 127 fTree(NULL),
8c0ab8e8 128 fInputEventHandler(NULL),
129 fOutputEventHandler(NULL),
130 fMCtruthEventHandler(NULL),
84fcd93f 131 fEventPool(NULL),
c52c2132 132 fCurrentEntry(-1),
8c0ab8e8 133 fNSysInfo(0),
c52c2132 134 fMode(other.fMode),
135 fInitOK(other.fInitOK),
270bc710 136 fMustClean(other.fMustClean),
8e1f0465 137 fIsRemote(other.fIsRemote),
c52c2132 138 fDebug(other.fDebug),
26f071d8 139 fSpecialOutputLocation(""),
37a26056 140 fTasks(NULL),
141 fTopTasks(NULL),
c52c2132 142 fZombies(NULL),
143 fContainers(NULL),
144 fInputs(NULL),
8d7d3b59 145 fOutputs(NULL),
6cd44ee0 146 fParamCont(NULL),
6f3e07d8 147 fDebugOptions(NULL),
9162405c 148 fFileDescriptors(new TObjArray()),
149 fCurrentDescriptor(0),
60a04972 150 fCommonInput(NULL),
151 fCommonOutput(NULL),
c57f56b7 152 fSelector(NULL),
c07b9ce2 153 fGridHandler(NULL),
9162405c 154 fExtraFiles(other.fExtraFiles),
155 fFileInfoLog(other.fFileInfoLog),
012e169c 156 fAutoBranchHandling(other.fAutoBranchHandling),
242accb2 157 fTable(),
e9247450 158 fRunFromPath(0),
159 fNcalls(other.fNcalls),
f03a8355 160 fMaxEntries(other.fMaxEntries),
7acc5b9d 161 fStatisticsMsg(other.fStatisticsMsg),
f5cbe261 162 fRequestedBranches(other.fRequestedBranches),
77dad4a9 163 fStatistics(other.fStatistics),
164 fGlobals(other.fGlobals)
d3106602 165{
166// Copy constructor.
37a26056 167 fTasks = new TObjArray(*other.fTasks);
168 fTopTasks = new TObjArray(*other.fTopTasks);
169 fZombies = new TObjArray(*other.fZombies);
c52c2132 170 fContainers = new TObjArray(*other.fContainers);
171 fInputs = new TObjArray(*other.fInputs);
172 fOutputs = new TObjArray(*other.fOutputs);
6cd44ee0 173 fParamCont = new TObjArray(*other.fParamCont);
84fcd93f 174 fgCommonFileName = "AnalysisResults.root";
c52c2132 175 fgAnalysisManager = this;
d3106602 176}
177
178//______________________________________________________________________________
179AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& other)
180{
181// Assignment
182 if (&other != this) {
c52c2132 183 TNamed::operator=(other);
54cff064 184 fInputEventHandler = other.fInputEventHandler;
6bb2b24f 185 fOutputEventHandler = other.fOutputEventHandler;
186 fMCtruthEventHandler = other.fMCtruthEventHandler;
c2922515 187 fEventPool = other.fEventPool;
c52c2132 188 fTree = NULL;
189 fCurrentEntry = -1;
8c0ab8e8 190 fNSysInfo = other.fNSysInfo;
c52c2132 191 fMode = other.fMode;
37a26056 192 fInitOK = other.fInitOK;
8e1f0465 193 fIsRemote = other.fIsRemote;
c52c2132 194 fDebug = other.fDebug;
37a26056 195 fTasks = new TObjArray(*other.fTasks);
196 fTopTasks = new TObjArray(*other.fTopTasks);
197 fZombies = new TObjArray(*other.fZombies);
c52c2132 198 fContainers = new TObjArray(*other.fContainers);
199 fInputs = new TObjArray(*other.fInputs);
200 fOutputs = new TObjArray(*other.fOutputs);
6cd44ee0 201 fParamCont = new TObjArray(*other.fParamCont);
6f3e07d8 202 fDebugOptions = NULL;
9162405c 203 fFileDescriptors = new TObjArray();
204 fCurrentDescriptor = 0;
60a04972 205 fCommonInput = NULL;
206 fCommonOutput = NULL;
8d7d3b59 207 fSelector = NULL;
c57f56b7 208 fGridHandler = NULL;
c07b9ce2 209 fExtraFiles = other.fExtraFiles;
9162405c 210 fFileInfoLog = other.fFileInfoLog;
84fcd93f 211 fgCommonFileName = "AnalysisResults.root";
c52c2132 212 fgAnalysisManager = this;
012e169c 213 fAutoBranchHandling = other.fAutoBranchHandling;
242accb2 214 fTable.Clear("nodelete");
215 fRunFromPath = other.fRunFromPath;
e9247450 216 fNcalls = other. fNcalls;
f03a8355 217 fMaxEntries = other.fMaxEntries;
e9247450 218 fStatisticsMsg = other.fStatisticsMsg;
7acc5b9d 219 fRequestedBranches = other.fRequestedBranches;
f5cbe261 220 fStatistics = other.fStatistics;
77dad4a9 221 fGlobals = new TMap();
d3106602 222 }
223 return *this;
224}
225
226//______________________________________________________________________________
227AliAnalysisManager::~AliAnalysisManager()
228{
229// Destructor.
d3106602 230 if (fTasks) {fTasks->Delete(); delete fTasks;}
231 if (fTopTasks) delete fTopTasks;
232 if (fZombies) delete fZombies;
c52c2132 233 if (fContainers) {fContainers->Delete(); delete fContainers;}
234 if (fInputs) delete fInputs;
235 if (fOutputs) delete fOutputs;
6cd44ee0 236 if (fParamCont) delete fParamCont;
6f3e07d8 237 if (fDebugOptions) delete fDebugOptions;
c57f56b7 238 if (fGridHandler) delete fGridHandler;
f3c07fbd 239 if (fInputEventHandler) delete fInputEventHandler;
240 if (fOutputEventHandler) delete fOutputEventHandler;
241 if (fMCtruthEventHandler) delete fMCtruthEventHandler;
242 if (fEventPool) delete fEventPool;
c52c2132 243 if (fgAnalysisManager==this) fgAnalysisManager = NULL;
77dad4a9 244 if (fGlobals) {fGlobals->DeleteAll(); delete fGlobals;}
9162405c 245 if (fFileDescriptors) {fFileDescriptors->Delete(); delete fFileDescriptors;}
d3106602 246}
c52c2132 247
d3106602 248//______________________________________________________________________________
327eaf46 249Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
250{
251// Read one entry of the tree or a whole branch.
c52c2132 252 fCurrentEntry = entry;
012e169c 253 if (!fAutoBranchHandling)
f5cbe261 254 return 123456789;
9162405c 255 if (!fTree) return -1;
256 Long64_t readbytes = fTree->GetTree()->GetEntry(entry, getall);
257 return (Int_t)readbytes;
327eaf46 258}
242accb2 259
260//______________________________________________________________________________
261Int_t AliAnalysisManager::GetRunFromAlienPath(const char *path)
262{
263// Attempt to extract run number from input data path. Works only for paths to
264// alice data in alien.
265// sim: /alice/sim/<production>/run_no/...
266// data: /alice/data/year/period/000run_no/... (ESD or AOD)
ff5309f8 267 TString type = "unknown";
242accb2 268 TString s(path);
ff5309f8 269 if (s.Contains("/alice/data")) type = "real";
270 else if (s.Contains("/alice/sim")) type = "simulated";
242accb2 271 TString srun;
ff5309f8 272 Int_t ind1, ind2;
273 ind1 = s.Index("/00");
274 if (ind1>0) {
275 ind2 = s.Index("/",ind1+1);
8c1f7958 276 if (ind2-ind1>8) srun = s(ind1+1, ind2-ind1-1);
ff5309f8 277 }
278 if (srun.IsNull()) {
279 ind1 = s.Index("/LHC");
280 if (ind1>0) {
281 ind1 = s.Index("/",ind1+1);
282 if (ind1>0) {
283 ind2 = s.Index("/",ind1+1);
284 if (ind2>0) srun = s(ind1+1, ind2-ind1-1);
285 }
242accb2 286 }
ff5309f8 287 }
288 Int_t run = srun.Atoi();
289 if (run>0) printf("=== GetRunFromAlienPath: run %d of %s data ===\n", run, type.Data());
242accb2 290 return run;
291}
292
327eaf46 293//______________________________________________________________________________
2d626244 294Bool_t AliAnalysisManager::Init(TTree *tree)
d3106602 295{
296 // The Init() function is called when the selector needs to initialize
297 // a new tree or chain. Typically here the branch addresses of the tree
298 // will be set. It is normaly not necessary to make changes to the
299 // generated code, but the routine can be extended by the user if needed.
300 // Init() will be called many times when running with PROOF.
2d626244 301 Bool_t init = kFALSE;
302 if (!tree) return kFALSE; // Should not happen - protected in selector caller
cd463514 303 if (fDebug > 1) {
84fcd93f 304 printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
c52c2132 305 }
f3d59a0d 306 // Call InitTree of EventHandler
36e82a52 307 if (fOutputEventHandler) {
308 if (fMode == kProofAnalysis) {
2d626244 309 init = fOutputEventHandler->Init(0x0, "proof");
36e82a52 310 } else {
2d626244 311 init = fOutputEventHandler->Init(0x0, "local");
36e82a52 312 }
2d626244 313 if (!init) {
314 Error("Init", "Output event handler failed to initialize");
315 return kFALSE;
316 }
36e82a52 317 }
2d626244 318
fdb458ec 319 if (fInputEventHandler) {
36e82a52 320 if (fMode == kProofAnalysis) {
2d626244 321 init = fInputEventHandler->Init(tree, "proof");
36e82a52 322 } else {
2d626244 323 init = fInputEventHandler->Init(tree, "local");
36e82a52 324 }
2d626244 325 if (!init) {
326 Error("Init", "Input event handler failed to initialize tree");
327 return kFALSE;
328 }
e7ae3836 329 } else {
330 // If no input event handler we need to get the tree once
331 // for the chain
2d626244 332 if(!tree->GetTree()) {
333 Long64_t readEntry = tree->LoadTree(0);
334 if (readEntry == -2) {
61505f8b 335 Error("Init", "Input tree has no entry. Exiting");
2d626244 336 return kFALSE;
337 }
338 }
36e82a52 339 }
340
341 if (fMCtruthEventHandler) {
342 if (fMode == kProofAnalysis) {
2d626244 343 init = fMCtruthEventHandler->Init(0x0, "proof");
36e82a52 344 } else {
2d626244 345 init = fMCtruthEventHandler->Init(0x0, "local");
36e82a52 346 }
2d626244 347 if (!init) {
348 Error("Init", "MC event handler failed to initialize");
349 return kFALSE;
350 }
fdb458ec 351 }
352
c52c2132 353 if (!fInitOK) InitAnalysis();
2d626244 354 if (!fInitOK) return kFALSE;
327eaf46 355 fTree = tree;
012e169c 356 fTable.Rehash(100);
ce46ecc1 357 AliAnalysisDataContainer *top = fCommonInput;
358 if (!top) top = (AliAnalysisDataContainer*)fInputs->At(0);
c52c2132 359 if (!top) {
8d7d3b59 360 Error("Init","No top input container !");
2d626244 361 return kFALSE;
37153431 362 }
327eaf46 363 top->SetData(tree);
7acc5b9d 364 CheckBranches(kFALSE);
cd463514 365 if (fDebug > 1) {
84fcd93f 366 printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
981f2614 367 }
2d626244 368 return kTRUE;
d3106602 369}
370
d3106602 371//______________________________________________________________________________
327eaf46 372void AliAnalysisManager::SlaveBegin(TTree *tree)
d3106602 373{
374 // The SlaveBegin() function is called after the Begin() function.
375 // When running with PROOF SlaveBegin() is called on each slave server.
376 // The tree argument is deprecated (on PROOF 0 is passed).
cd463514 377 if (fDebug > 1) printf("->AliAnalysisManager::SlaveBegin()\n");
6f3e07d8 378
379 // Apply debug options
380 ApplyDebugOptions();
381
4747b4a7 382 if (!CheckTasks()) Fatal("SlaveBegin", "Not all needed libraries were loaded");
aee5ee44 383 static Bool_t isCalled = kFALSE;
2d626244 384 Bool_t init = kFALSE;
385 Bool_t initOK = kTRUE;
386 TString msg;
4ab472d4 387 TDirectory *curdir = gDirectory;
aee5ee44 388 // Call SlaveBegin only once in case of mixing
389 if (isCalled && fMode==kMixingAnalysis) return;
979e448a 390 gROOT->cd();
f3d59a0d 391 // Call Init of EventHandler
392 if (fOutputEventHandler) {
393 if (fMode == kProofAnalysis) {
673f68ff 394 // Merging AOD's in PROOF via TProofOutputFile
84fcd93f 395 if (fDebug > 1) printf(" Initializing AOD output file %s...\n", fOutputEventHandler->GetOutputFileName());
673f68ff 396 init = fOutputEventHandler->Init("proof");
397 if (!init) msg = "Failed to initialize output handler on worker";
f3d59a0d 398 } else {
2d626244 399 init = fOutputEventHandler->Init("local");
673f68ff 400 if (!init) msg = "Failed to initialize output handler";
f3d59a0d 401 }
2d626244 402 initOK &= init;
403 if (!fSelector) Error("SlaveBegin", "Selector not set");
404 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
f3d59a0d 405 }
979e448a 406 gROOT->cd();
f3d59a0d 407 if (fInputEventHandler) {
408 fInputEventHandler->SetInputTree(tree);
409 if (fMode == kProofAnalysis) {
2d626244 410 init = fInputEventHandler->Init("proof");
411 if (!init) msg = "Failed to initialize input handler on worker";
f3d59a0d 412 } else {
2d626244 413 init = fInputEventHandler->Init("local");
414 if (!init) msg = "Failed to initialize input handler";
f3d59a0d 415 }
2d626244 416 initOK &= init;
417 if (!fSelector) Error("SlaveBegin", "Selector not set");
418 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
f3d59a0d 419 }
979e448a 420 gROOT->cd();
f3d59a0d 421 if (fMCtruthEventHandler) {
422 if (fMode == kProofAnalysis) {
2d626244 423 init = fMCtruthEventHandler->Init("proof");
424 if (!init) msg = "Failed to initialize MC handler on worker";
f3d59a0d 425 } else {
2d626244 426 init = fMCtruthEventHandler->Init("local");
427 if (!init) msg = "Failed to initialize MC handler";
f3d59a0d 428 }
2d626244 429 initOK &= init;
430 if (!fSelector) Error("SlaveBegin", "Selector not set");
431 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
f3d59a0d 432 }
4ab472d4 433 if (curdir) curdir->cd();
2d626244 434 isCalled = kTRUE;
435 if (!initOK) return;
c52c2132 436 TIter next(fTasks);
437 AliAnalysisTask *task;
438 // Call CreateOutputObjects for all tasks
096b5a2e 439 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
979e448a 440 Bool_t dirStatus = TH1::AddDirectoryStatus();
096b5a2e 441 Int_t itask = 0;
c5a87c56 442 while ((task=(AliAnalysisTask*)next())) {
979e448a 443 gROOT->cd();
444 // Start with memory as current dir and make sure by default histograms do not get attached to files.
445 TH1::AddDirectory(kFALSE);
c52c2132 446 task->CreateOutputObjects();
4747b4a7 447 if (!task->CheckPostData()) {
448 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
449 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
450 ####### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ##########", task->GetName(), task->ClassName());
451 }
096b5a2e 452 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
453 itask++;
36e82a52 454 }
979e448a 455 TH1::AddDirectory(dirStatus);
456 if (curdir) curdir->cd();
cd463514 457 if (fDebug > 1) printf("<-AliAnalysisManager::SlaveBegin()\n");
d3106602 458}
459
460//______________________________________________________________________________
327eaf46 461Bool_t AliAnalysisManager::Notify()
462{
463 // The Notify() function is called when a new file is opened. This
464 // can be either for a new TTree in a TChain or when when a new TTree
465 // is started when using PROOF. It is normaly not necessary to make changes
466 // to the generated code, but the routine can be extended by the
467 // user if needed. The return value is currently not used.
2d626244 468 if (!fTree) return kFALSE;
20b7268e 469 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) return kFALSE;
012e169c 470
471 fTable.Clear("nodelete"); // clearing the hash table may not be needed -> C.L.
8e1f0465 472 if (fMode == kProofAnalysis) fIsRemote = kTRUE;
2d626244 473
8d7d3b59 474 TFile *curfile = fTree->GetCurrentFile();
475 if (!curfile) {
476 Error("Notify","No current file");
477 return kFALSE;
478 }
9162405c 479 if (IsCollectThroughput()) {
480 if (fCurrentDescriptor) fCurrentDescriptor->Done();
481 fCurrentDescriptor = new AliAnalysisFileDescriptor(curfile);
482 fFileDescriptors->Add(fCurrentDescriptor);
483 }
8d7d3b59 484
cd463514 485 if (fDebug > 1) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
242accb2 486 Int_t run = AliAnalysisManager::GetRunFromAlienPath(curfile->GetName());
20b7268e 487 if (run && (run != fRunFromPath)) {
488 fRunFromPath = run;
489 if (fDebug > 1) printf(" ### run found from path: %d\n", run);
490 }
8d7d3b59 491 TIter next(fTasks);
492 AliAnalysisTask *task;
fdb458ec 493
8d7d3b59 494 // Call Notify of the event handlers
495 if (fInputEventHandler) {
496 fInputEventHandler->Notify(curfile->GetName());
497 }
6073f8c9 498
8d7d3b59 499 if (fOutputEventHandler) {
500 fOutputEventHandler->Notify(curfile->GetName());
501 }
890126ab 502
8d7d3b59 503 if (fMCtruthEventHandler) {
504 fMCtruthEventHandler->Notify(curfile->GetName());
505 }
012e169c 506
242accb2 507 // Call Notify for all tasks
508 while ((task=(AliAnalysisTask*)next()))
509 task->Notify();
510
cd463514 511 if (fDebug > 1) printf("<-AliAnalysisManager::Notify()\n");
8d7d3b59 512 return kTRUE;
327eaf46 513}
514
515//______________________________________________________________________________
20b7268e 516Bool_t AliAnalysisManager::Process(Long64_t)
d3106602 517{
518 // The Process() function is called for each entry in the tree (or possibly
519 // keyed object in the case of PROOF) to be processed. The entry argument
520 // specifies which entry in the currently loaded tree is to be processed.
521 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
522 // to read either all or the required parts of the data. When processing
523 // keyed objects with PROOF, the object is already loaded and is available
524 // via the fObject pointer.
525 //
526 // This function should contain the "body" of the analysis. It can contain
527 // simple or elaborate selection criteria, run algorithms on the data
528 // of the event and typically fill histograms.
529
530 // WARNING when a selector is used with a TChain, you must use
531 // the pointer to the current TTree to call GetEntry(entry).
532 // The entry is always the local entry number in the current tree.
533 // Assuming that fChain is the pointer to the TChain being processed,
534 // use fChain->GetTree()->GetEntry(entry).
0d6a82a5 535
20b7268e 536 // This method is obsolete. ExecAnalysis is called instead.
327eaf46 537 return kTRUE;
d3106602 538}
539
540//______________________________________________________________________________
c52c2132 541void AliAnalysisManager::PackOutput(TList *target)
d3106602 542{
981f2614 543 // Pack all output data containers in the output list. Called at SlaveTerminate
544 // stage in PROOF case for each slave.
cd463514 545 if (fDebug > 1) printf("->AliAnalysisManager::PackOutput()\n");
9162405c 546 if (IsCollectThroughput()) {
547 if (fCurrentDescriptor) fCurrentDescriptor->Done();
548 fFileDescriptors->Print();
549 if (fFileInfoLog.IsNull()) fFileInfoLog = "fileinfo.log";
550 std::ofstream out;
551 out.open(fFileInfoLog, std::ios::out);
552 if (out.bad()) Error("SavePrimitive", "Bad file name: %s", fFileInfoLog.Data());
553 else {
554 TIter nextflog(fFileDescriptors);
555 TObject *log;
556 while ((log=nextflog())) log->SavePrimitive(out,"");
557 }
558 }
c52c2132 559 if (!target) {
61505f8b 560 Error("PackOutput", "No target. Exiting.");
c52c2132 561 return;
37153431 562 }
57756ec5 563 TDirectory *cdir = gDirectory;
564 gROOT->cd();
6073f8c9 565 if (fInputEventHandler) fInputEventHandler ->Terminate();
6bb2b24f 566 if (fOutputEventHandler) fOutputEventHandler ->Terminate();
567 if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
57756ec5 568 gROOT->cd();
8d7d3b59 569
570 // Call FinishTaskOutput() for each event loop task (not called for
571 // post-event loop tasks - use Terminate() fo those)
572 TIter nexttask(fTasks);
573 AliAnalysisTask *task;
574 while ((task=(AliAnalysisTask*)nexttask())) {
575 if (!task->IsPostEventLoop()) {
cd463514 576 if (fDebug > 1) printf("->FinishTaskOutput: task %s\n", task->GetName());
8d7d3b59 577 task->FinishTaskOutput();
57756ec5 578 gROOT->cd();
cd463514 579 if (fDebug > 1) printf("<-FinishTaskOutput: task %s\n", task->GetName());
8d7d3b59 580 }
e9247450 581 }
582 // Write statistics message on the workers.
e296c79c 583 if (fStatistics) WriteStatisticsMsg(fNcalls);
8c9485b2 584
c52c2132 585 if (fMode == kProofAnalysis) {
586 TIter next(fOutputs);
587 AliAnalysisDataContainer *output;
4ab472d4 588 Bool_t isManagedByHandler = kFALSE;
ab5d25d8 589 TList filestmp;
590 filestmp.SetOwner();
c52c2132 591 while ((output=(AliAnalysisDataContainer*)next())) {
8d7d3b59 592 // Do not consider outputs of post event loop tasks
2b83ca27 593 isManagedByHandler = kFALSE;
1c5dff85 594 if (output->GetProducer() && output->GetProducer()->IsPostEventLoop()) continue;
4ab472d4 595 const char *filename = output->GetFileName();
596 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
597 isManagedByHandler = kTRUE;
84fcd93f 598 printf("#### Handler output. Extra: %s\n", fExtraFiles.Data());
4ab472d4 599 filename = fOutputEventHandler->GetOutputFileName();
600 }
8d7d3b59 601 // Check if data was posted to this container. If not, issue an error.
4ab472d4 602 if (!output->GetData() && !isManagedByHandler) {
923e2ca5 603 Error("PackOutput", "No data for output container %s. Forgot to PostData ?", output->GetName());
8d7d3b59 604 continue;
605 }
606 if (!output->IsSpecialOutput()) {
607 // Normal outputs
4ab472d4 608 if (strlen(filename) && !isManagedByHandler) {
8d7d3b59 609 // Backup current folder
ca78991b 610 TDirectory *opwd = gDirectory;
f2087b52 611 // File resident outputs.
612 // Check first if the file exists.
61505f8b 613 TString openoption = "RECREATE";
ab5d25d8 614 Bool_t firsttime = kTRUE;
615 if (filestmp.FindObject(output->GetFileName())) {
616 firsttime = kFALSE;
617 } else {
618 filestmp.Add(new TNamed(output->GetFileName(),""));
619 }
620 if (!gSystem->AccessPathName(output->GetFileName()) && !firsttime) openoption = "UPDATE";
621// TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
8d7d3b59 622 // Save data to file, then close.
1be433fc 623 if (output->GetData()->InheritsFrom(TCollection::Class())) {
624 // If data is a collection, we set the name of the collection
625 // as the one of the container and we save as a single key.
626 TCollection *coll = (TCollection*)output->GetData();
627 coll->SetName(output->GetName());
ab5d25d8 628// coll->Write(output->GetName(), TObject::kSingleKey);
1be433fc 629 } else {
cbc8747a 630 if (output->GetData()->InheritsFrom(TTree::Class())) {
ab5d25d8 631 TFile *file = AliAnalysisManager::OpenFile(output, openoption, kTRUE);
632 // Save data to file, then close.
cbc8747a 633 TTree *tree = (TTree*)output->GetData();
57756ec5 634 // Check if tree is in memory
635 if (tree->GetDirectory()==gROOT) tree->SetDirectory(gDirectory);
cbc8747a 636 tree->AutoSave();
ab5d25d8 637 file->Close();
cbc8747a 638 } else {
ab5d25d8 639// output->GetData()->Write();
cbc8747a 640 }
1be433fc 641 }
84fcd93f 642 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
ab5d25d8 643// if (fDebug > 2) {
644// printf(" file %s listing content:\n", filename);
645// file->ls();
646// }
f3c07fbd 647 // Clear file list to release object ownership to user.
160e7161 648// file->Clear();
ab5d25d8 649// file->Close();
84fcd93f 650 output->SetFile(NULL);
ca78991b 651 // Restore current directory
652 if (opwd) opwd->cd();
8d7d3b59 653 } else {
654 // Memory-resident outputs
84fcd93f 655 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
4ab472d4 656 }
657 AliAnalysisDataWrapper *wrap = 0;
658 if (isManagedByHandler) {
659 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
660 wrap->SetName(output->GetName());
ca78991b 661 }
4ab472d4 662 else wrap =output->ExportData();
cbc8747a 663 // Output wrappers must NOT delete data after merging - the user owns them
664 wrap->SetDeleteData(kFALSE);
8167b1d0 665 target->Add(wrap);
4ab472d4 666 } else {
f5e61abd 667 // Special outputs. The file must be opened and connected to the container.
d0864eb4 668 TDirectory *opwd = gDirectory;
8d7d3b59 669 TFile *file = output->GetFile();
f5e61abd 670 if (!file) {
671 AliAnalysisTask *producer = output->GetProducer();
84fcd93f 672 Fatal("PackOutput",
f5e61abd 673 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
674 output->GetFileName(), output->GetName(), producer->ClassName());
675 continue;
676 }
677 TString outFilename = file->GetName();
84fcd93f 678 if (fDebug > 1) printf("PackOutput %s: special output\n", output->GetName());
4ab472d4 679 if (isManagedByHandler) {
680 // Terminate IO for files managed by the output handler
aa399a26 681 // file->Write() moved to AOD handler (A.G. 11.01.10)
682// if (file) file->Write();
802f90ef 683 if (file && fDebug > 2) {
84fcd93f 684 printf(" handled file %s listing content:\n", file->GetName());
802f90ef 685 file->ls();
686 }
4ab472d4 687 fOutputEventHandler->TerminateIO();
f5e61abd 688 } else {
689 file->cd();
690 // Release object ownership to users after writing data to file
691 if (output->GetData()->InheritsFrom(TCollection::Class())) {
692 // If data is a collection, we set the name of the collection
693 // as the one of the container and we save as a single key.
694 TCollection *coll = (TCollection*)output->GetData();
695 coll->SetName(output->GetName());
696 coll->Write(output->GetName(), TObject::kSingleKey);
cbc8747a 697 } else {
f5e61abd 698 if (output->GetData()->InheritsFrom(TTree::Class())) {
699 TTree *tree = (TTree*)output->GetData();
700 tree->SetDirectory(file);
701 tree->AutoSave();
702 } else {
703 output->GetData()->Write();
704 }
705 }
f5e61abd 706 if (fDebug > 2) {
84fcd93f 707 printf(" file %s listing content:\n", output->GetFileName());
f5e61abd 708 file->ls();
709 }
f3c07fbd 710 // Clear file list to release object ownership to user.
160e7161 711// file->Clear();
f5e61abd 712 file->Close();
84fcd93f 713 output->SetFile(NULL);
ef73322e 714 }
8d7d3b59 715 // Restore current directory
d0864eb4 716 if (opwd) opwd->cd();
8d7d3b59 717 // Check if a special output location was provided or the output files have to be merged
13ef3bb0 718 if (strlen(fSpecialOutputLocation.Data())) {
719 TString remote = fSpecialOutputLocation;
720 remote += "/";
ef788aee 721 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
3bdcb562 722 if (remote.BeginsWith("alien:")) {
723 gROOT->ProcessLine("TGrid::Connect(\"alien:\", gProofServ->GetUser());");
f5e61abd 724 remote += outFilename;
725 remote.ReplaceAll(".root", Form("_%d.root", gid));
726 } else {
727 remote += Form("%s_%d_", gSystem->HostName(), gid);
728 remote += outFilename;
729 }
730 if (fDebug > 1)
731 Info("PackOutput", "Output file for container %s to be copied \n at: %s. No merging.",
732 output->GetName(), remote.Data());
ef73322e 733 TFile::Cp ( outFilename.Data(), remote.Data() );
c9e39043 734 // Copy extra outputs
735 if (fExtraFiles.Length() && isManagedByHandler) {
736 TObjArray *arr = fExtraFiles.Tokenize(" ");
737 TObjString *os;
738 TIter nextfilename(arr);
739 while ((os=(TObjString*)nextfilename())) {
740 outFilename = os->GetString();
741 remote = fSpecialOutputLocation;
742 remote += "/";
743 if (remote.BeginsWith("alien://")) {
744 remote += outFilename;
745 remote.ReplaceAll(".root", Form("_%d.root", gid));
746 } else {
747 remote += Form("%s_%d_", gSystem->HostName(), gid);
748 remote += outFilename;
749 }
750 if (fDebug > 1)
751 Info("PackOutput", "Extra AOD file %s to be copied \n at: %s. No merging.",
752 outFilename.Data(), remote.Data());
753 TFile::Cp ( outFilename.Data(), remote.Data() );
754 }
755 delete arr;
756 }
ca78991b 757 } else {
8d7d3b59 758 // No special location specified-> use TProofOutputFile as merging utility
759 // The file at this output slot must be opened in CreateOutputObjects
84fcd93f 760 if (fDebug > 1) printf(" File for container %s to be merged via file merger...\n", output->GetName());
13ef3bb0 761 }
762 }
c52c2132 763 }
764 }
2f0e656b 765 if (cdir) cdir->cd();
cd463514 766 if (fDebug > 1) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
c52c2132 767}
768
769//______________________________________________________________________________
981f2614 770void AliAnalysisManager::ImportWrappers(TList *source)
c52c2132 771{
981f2614 772// Import data in output containers from wrappers coming in source.
cd463514 773 if (fDebug > 1) printf("->AliAnalysisManager::ImportWrappers()\n");
327eaf46 774 TIter next(fOutputs);
981f2614 775 AliAnalysisDataContainer *cont;
776 AliAnalysisDataWrapper *wrap;
777 Int_t icont = 0;
c57f56b7 778 Bool_t inGrid = (fMode == kGridAnalysis)?kTRUE:kFALSE;
84fcd93f 779 TDirectory *cdir = gDirectory;
c52c2132 780 while ((cont=(AliAnalysisDataContainer*)next())) {
0355fc48 781 wrap = 0;
f3c07fbd 782 if (cont->GetProducer() && cont->GetProducer()->IsPostEventLoop() && !inGrid) continue;
90a4b3ee 783 if (cont->IsRegisterDataset()) continue;
4ab472d4 784 const char *filename = cont->GetFileName();
785 Bool_t isManagedByHandler = kFALSE;
786 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
787 isManagedByHandler = kTRUE;
788 filename = fOutputEventHandler->GetOutputFileName();
789 }
c57f56b7 790 if (cont->IsSpecialOutput() || inGrid) {
f5e61abd 791 if (strlen(fSpecialOutputLocation.Data())) continue;
c57f56b7 792 // Copy merged file from PROOF scratch space.
793 // In case of grid the files are already in the current directory.
794 if (!inGrid) {
c07b9ce2 795 if (isManagedByHandler && fExtraFiles.Length()) {
796 // Copy extra registered dAOD files.
797 TObjArray *arr = fExtraFiles.Tokenize(" ");
798 TObjString *os;
799 TIter nextfilename(arr);
800 while ((os=(TObjString*)nextfilename())) GetFileFromWrapper(os->GetString(), source);
801 delete arr;
c57f56b7 802 }
c07b9ce2 803 if (!GetFileFromWrapper(filename, source)) continue;
c57f56b7 804 }
8d7d3b59 805 // Normally we should connect data from the copied file to the
806 // corresponding output container, but it is not obvious how to do this
807 // automatically if several objects in file...
84fcd93f 808 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
809 if (!f) f = TFile::Open(filename, "READ");
dd197a68 810 if (!f) {
811 Error("ImportWrappers", "Cannot open file %s in read-only mode", filename);
0355fc48 812 continue;
dd197a68 813 }
dd151ce7 814 f->cd();
dd197a68 815 TObject *obj = 0;
84fcd93f 816 // Cd to the directory pointed by the container
817 TString folder = cont->GetFolderName();
818 if (!folder.IsNull()) f->cd(folder);
819 // Try to fetch first an object having the container name.
820 obj = gDirectory->Get(cont->GetName());
dd197a68 821 if (!obj) {
c7597be6 822 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",
823 cont->GetType()->GetName(), cont->GetName(), filename, cont->GetFolderName(), cont->GetName());
dd197a68 824 continue;
825 }
0355fc48 826 wrap = new AliAnalysisDataWrapper(obj);
827 wrap->SetDeleteData(kFALSE);
8d7d3b59 828 }
0355fc48 829 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
8d7d3b59 830 if (!wrap) {
831 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
c52c2132 832 continue;
833 }
981f2614 834 icont++;
8d7d3b59 835 if (fDebug > 1) {
84fcd93f 836 printf(" Importing data for container %s\n", cont->GetName());
837 if (strlen(filename)) printf(" -> file %s\n", filename);
838 else printf("\n");
8d7d3b59 839 }
981f2614 840 cont->ImportData(wrap);
84fcd93f 841 }
842 if (cdir) cdir->cd();
cd463514 843 if (fDebug > 1) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
c52c2132 844}
845
846//______________________________________________________________________________
847void AliAnalysisManager::UnpackOutput(TList *source)
848{
ca78991b 849 // Called by AliAnalysisSelector::Terminate only on the client.
cd463514 850 if (fDebug > 1) printf("->AliAnalysisManager::UnpackOutput()\n");
c52c2132 851 if (!source) {
61505f8b 852 Error("UnpackOutput", "No target. Exiting.");
c52c2132 853 return;
854 }
84fcd93f 855 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
c52c2132 856
981f2614 857 if (fMode == kProofAnalysis) ImportWrappers(source);
37153431 858
981f2614 859 TIter next(fOutputs);
c52c2132 860 AliAnalysisDataContainer *output;
861 while ((output=(AliAnalysisDataContainer*)next())) {
c52c2132 862 if (!output->GetData()) continue;
b1310ef5 863 // Check if there are client tasks that run post event loop
864 if (output->HasConsumers()) {
865 // Disable event loop semaphore
866 output->SetPostEventLoop(kTRUE);
867 TObjArray *list = output->GetConsumers();
868 Int_t ncons = list->GetEntriesFast();
869 for (Int_t i=0; i<ncons; i++) {
870 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
871 task->CheckNotify(kTRUE);
872 // If task is active, execute it
873 if (task->IsPostEventLoop() && task->IsActive()) {
cd463514 874 if (fDebug > 1) printf("== Executing post event loop task %s\n", task->GetName());
b1310ef5 875 task->ExecuteTask();
876 }
877 }
878 }
c52c2132 879 }
cd463514 880 if (fDebug > 1) printf("<-AliAnalysisManager::UnpackOutput()\n");
d3106602 881}
882
883//______________________________________________________________________________
884void AliAnalysisManager::Terminate()
885{
886 // The Terminate() function is the last function to be called during
887 // a query. It always runs on the client, it can be used to present
c52c2132 888 // the results graphically.
cd463514 889 if (fDebug > 1) printf("->AliAnalysisManager::Terminate()\n");
57756ec5 890 TDirectory *cdir = gDirectory;
891 gROOT->cd();
327eaf46 892 AliAnalysisTask *task;
a0e2e8b1 893 AliAnalysisDataContainer *output;
c52c2132 894 TIter next(fTasks);
a0e2e8b1 895 TStopwatch timer;
096b5a2e 896 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
327eaf46 897 // Call Terminate() for tasks
096b5a2e 898 Int_t itask = 0;
90a4b3ee 899 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
a0e2e8b1 900 // Save all the canvases produced by the Terminate
901 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
a0e2e8b1 902 task->Terminate();
57756ec5 903 gROOT->cd();
096b5a2e 904 if (getsysInfo)
905 AliSysInfo::AddStamp(Form("%s_TERMINATE",task->ClassName()),0, itask, 2);
906 itask++;
a0e2e8b1 907 if (TObject::TestBit(kSaveCanvases)) {
226abfec 908 if (!gROOT->IsBatch()) {
8e1f0465 909 if (fDebug>1) printf("Waiting 5 sec for %s::Terminate() to finish drawing ...\n", task->ClassName());
226abfec 910 timer.Start();
911 while (timer.CpuTime()<5) {
912 timer.Continue();
913 gSystem->ProcessEvents();
914 }
915 }
916 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
917 if (iend==0) continue;
a0e2e8b1 918 TCanvas *canvas;
226abfec 919 for (Int_t ipict=0; ipict<iend; ipict++) {
920 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
a0e2e8b1 921 if (!canvas) continue;
922 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
226abfec 923 }
924 gROOT->GetListOfCanvases()->Delete();
a0e2e8b1 925 }
926 }
8c9485b2 927 //
aa399a26 928 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
929 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
930 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
57756ec5 931 gROOT->cd();
6cd44ee0 932 TObjArray *allOutputs = new TObjArray();
933 Int_t icont;
934 for (icont=0; icont<fOutputs->GetEntriesFast(); icont++) allOutputs->Add(fOutputs->At(icont));
935 if (!IsSkipTerminate())
936 for (icont=0; icont<fParamCont->GetEntriesFast(); icont++) allOutputs->Add(fParamCont->At(icont));
937 TIter next1(allOutputs);
f2087b52 938 TString handlerFile = "";
90d50a8c 939 TString extraOutputs = "";
f2087b52 940 if (fOutputEventHandler) {
941 handlerFile = fOutputEventHandler->GetOutputFileName();
90d50a8c 942 extraOutputs = fOutputEventHandler->GetExtraOutputs();
f2087b52 943 }
e16a394c 944 icont = 0;
ab5d25d8 945 TList filestmp;
8c0ab8e8 946 while ((output=(AliAnalysisDataContainer*)next1())) {
c57f56b7 947 // Special outputs or grid files have the files already closed and written.
e16a394c 948 icont++;
949 if (fMode == kGridAnalysis && icont<=fOutputs->GetEntriesFast()) continue;
90a4b3ee 950 if (fMode == kProofAnalysis) {
951 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
952 }
8c0ab8e8 953 const char *filename = output->GetFileName();
61505f8b 954 TString openoption = "RECREATE";
aa399a26 955 if (!(strcmp(filename, "default"))) continue;
8d7d3b59 956 if (!strlen(filename)) continue;
1be433fc 957 if (!output->GetData()) continue;
8d7d3b59 958 TDirectory *opwd = gDirectory;
84fcd93f 959 TFile *file = output->GetFile();
960 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
f2087b52 961 if (!file) {
61505f8b 962 //if (handlerFile == filename && !gSystem->AccessPathName(filename)) openoption = "UPDATE";
ab5d25d8 963 Bool_t firsttime = kTRUE;
90d50a8c 964 if (filestmp.FindObject(filename) || extraOutputs.Contains(filename)) {
ab5d25d8 965 firsttime = kFALSE;
966 } else {
967 filestmp.Add(new TNamed(filename,""));
968 }
969 if (!gSystem->AccessPathName(filename) && !firsttime) openoption = "UPDATE";
cd463514 970 if (fDebug>1) printf("Opening file: %s option=%s\n",filename, openoption.Data());
61505f8b 971 file = new TFile(filename, openoption);
6cd44ee0 972 } else {
cd463514 973 if (fDebug>1) printf("File <%s> already opened with option: <%s> \n", filename, file->GetOption());
ff07ec61 974 openoption = file->GetOption();
975 if (openoption == "READ") {
cd463514 976 if (fDebug>1) printf("...reopening in UPDATE mode\n");
ff07ec61 977 file->ReOpen("UPDATE");
978 }
6cd44ee0 979 }
84fcd93f 980 if (file->IsZombie()) {
981 Error("Terminate", "Cannot open output file %s", filename);
982 continue;
983 }
8e6e6fe8 984 output->SetFile(file);
985 file->cd();
84fcd93f 986 // Check for a folder request
987 TString dir = output->GetFolderName();
988 if (!dir.IsNull()) {
989 if (!file->GetDirectory(dir)) file->mkdir(dir);
990 file->cd(dir);
991 }
cd463514 992 if (fDebug > 1) printf("...writing container %s to file %s:%s\n", output->GetName(), file->GetName(), output->GetFolderName());
1be433fc 993 if (output->GetData()->InheritsFrom(TCollection::Class())) {
994 // If data is a collection, we set the name of the collection
995 // as the one of the container and we save as a single key.
996 TCollection *coll = (TCollection*)output->GetData();
997 coll->SetName(output->GetName());
998 coll->Write(output->GetName(), TObject::kSingleKey);
999 } else {
cbc8747a 1000 if (output->GetData()->InheritsFrom(TTree::Class())) {
1001 TTree *tree = (TTree*)output->GetData();
7a151c06 1002 tree->SetDirectory(gDirectory);
cbc8747a 1003 tree->AutoSave();
1004 } else {
1005 output->GetData()->Write();
1006 }
1be433fc 1007 }
8e6e6fe8 1008 if (opwd) opwd->cd();
57756ec5 1009 }
1010 gROOT->cd();
8e6e6fe8 1011 next1.Reset();
9f2d937f 1012 TString copiedFiles;
8e6e6fe8 1013 while ((output=(AliAnalysisDataContainer*)next1())) {
1014 // Close all files at output
1015 TDirectory *opwd = gDirectory;
f5e61abd 1016 if (output->GetFile()) {
f3c07fbd 1017 // Clear file list to release object ownership to user.
160e7161 1018// output->GetFile()->Clear();
f5e61abd 1019 output->GetFile()->Close();
1020 // Copy merged outputs in alien if requested
9f2d937f 1021 if (fSpecialOutputLocation.BeginsWith("alien://")) {
1022 if (copiedFiles.Contains(output->GetFile()->GetName())) {
1023 if (opwd) opwd->cd();
1024 output->SetFile(NULL);
1025 continue;
1026 }
f5e61abd 1027 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
77dad4a9 1028 gROOT->ProcessLine("if (!gGrid) TGrid::Connect(\"alien:\");");
f5e61abd 1029 TFile::Cp(output->GetFile()->GetName(),
1030 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
9f2d937f 1031 copiedFiles += output->GetFile()->GetName();
f5e61abd 1032 }
77dad4a9 1033 output->SetFile(NULL);
f5e61abd 1034 }
8d7d3b59 1035 if (opwd) opwd->cd();
8c0ab8e8 1036 }
6cd44ee0 1037 delete allOutputs;
e9247450 1038 //Write statistics information on the client
e296c79c 1039 if (fStatistics) WriteStatisticsMsg(fNcalls);
8c0ab8e8 1040 if (getsysInfo) {
b6db1d18 1041 TDirectory *crtdir = gDirectory;
8c0ab8e8 1042 TFile f("syswatch.root", "RECREATE");
096b5a2e 1043 TH1 *hist;
1044 TString cut;
8c0ab8e8 1045 if (!f.IsZombie()) {
1046 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
096b5a2e 1047 tree->SetName("syswatch");
8c0ab8e8 1048 tree->SetMarkerStyle(kCircle);
1049 tree->SetMarkerColor(kBlue);
1050 tree->SetMarkerSize(0.5);
1051 if (!gROOT->IsBatch()) {
1052 tree->SetAlias("event", "id0");
096b5a2e 1053 tree->SetAlias("task", "id1");
1054 tree->SetAlias("stage", "id2");
1055 // Already defined aliases
1056 // tree->SetAlias("deltaT","stampSec-stampOldSec");
1057 // tree->SetAlias("T","stampSec-first");
1058 // tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)");
1059 // tree->SetAlias("VM","pI.fMemVirtual");
1060 TCanvas *canvas = new TCanvas("SysInfo","SysInfo",10,10,1200,800);
1061 Int_t npads = 1 /*COO plot for all tasks*/ +
1062 fTopTasks->GetEntries() /*Exec plot per task*/ +
1063 1 /*Terminate plot for all tasks*/ +
1064 1; /*vm plot*/
1065
1066 Int_t iopt = (Int_t)TMath::Sqrt((Double_t)npads);
1067 if (npads<iopt*(iopt+1))
1068 canvas->Divide(iopt, iopt+1, 0.01, 0.01);
1069 else
1070 canvas->Divide(iopt+1, iopt+1, 0.01, 0.01);
1071 Int_t ipad = 1;
1072 // draw the plot of deltaVM for Exec for each task
779e9992 1073 for (itask=0; itask<fTopTasks->GetEntriesFast(); itask++) {
096b5a2e 1074 task = (AliAnalysisTask*)fTopTasks->At(itask);
1075 canvas->cd(ipad++);
1076 cut = Form("task==%d && stage==1", itask);
1077 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1078 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1079 if (hist) {
084c84df 1080 hist->SetTitle(Form("%s: Exec dVM[MB]/event", task->GetName()));
b3e07543 1081 hist->GetYaxis()->SetTitle("deltaVM [MB]");
096b5a2e 1082 }
1083 }
1084 // Draw the plot of deltaVM for CreateOutputObjects for all tasks
1085 canvas->cd(ipad++);
1086 tree->SetMarkerStyle(kFullTriangleUp);
1087 tree->SetMarkerColor(kRed);
1088 tree->SetMarkerSize(0.8);
1089 cut = "task>=0 && task<1000 && stage==0";
1090 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1091 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1092 if (hist) {
1093 hist->SetTitle("Memory in CreateOutputObjects()");
b3e07543 1094 hist->GetYaxis()->SetTitle("deltaVM [MB]");
096b5a2e 1095 hist->GetXaxis()->SetTitle("task");
1096 }
1097 // draw the plot of deltaVM for Terminate for all tasks
1098 canvas->cd(ipad++);
1099 tree->SetMarkerStyle(kOpenSquare);
1100 tree->SetMarkerColor(kMagenta);
1101 cut = "task>=0 && task<1000 && stage==2";
1102 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1103 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1104 if (hist) {
1105 hist->SetTitle("Memory in Terminate()");
b3e07543 1106 hist->GetYaxis()->SetTitle("deltaVM [MB]");
096b5a2e 1107 hist->GetXaxis()->SetTitle("task");
1108 }
1109 // Full VM profile
1110 canvas->cd(ipad++);
1111 tree->SetMarkerStyle(kFullCircle);
1112 tree->SetMarkerColor(kGreen);
1113 cut = Form("task==%d && stage==1",fTopTasks->GetEntriesFast()-1);
1114 tree->Draw("VM:event",cut,"", 1234567890, 0);
1115 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1116 if (hist) {
1117 hist->SetTitle("Virtual memory");
b3e07543 1118 hist->GetYaxis()->SetTitle("VM [MB]");
096b5a2e 1119 }
1120 canvas->Modified();
8c0ab8e8 1121 }
096b5a2e 1122 tree->SetMarkerStyle(kCircle);
1123 tree->SetMarkerColor(kBlue);
1124 tree->SetMarkerSize(0.5);
8c0ab8e8 1125 tree->Write();
1126 f.Close();
1127 delete tree;
1128 }
b6db1d18 1129 if (crtdir) crtdir->cd();
923e2ca5 1130 }
1131 // Validate the output files
f62a0e4c 1132 if (ValidateOutputFiles() && fIsRemote && fMode!=kProofAnalysis) {
923e2ca5 1133 ofstream out;
1134 out.open("outputs_valid", ios::out);
1135 out.close();
57756ec5 1136 }
2f0e656b 1137 if (cdir) cdir->cd();
cd463514 1138 if (fDebug > 1) printf("<-AliAnalysisManager::Terminate()\n");
d3106602 1139}
096b5a2e 1140//______________________________________________________________________________
1141void AliAnalysisManager::ProfileTask(Int_t itop, const char *option) const
1142{
1143// Profiles the task having the itop index in the list of top (first level) tasks.
1144 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->At(itop);
1145 if (!task) {
1146 Error("ProfileTask", "There are only %d top tasks in the manager", fTopTasks->GetEntries());
1147 return;
1148 }
1149 ProfileTask(task->GetName(), option);
1150}
1151
1152//______________________________________________________________________________
1153void AliAnalysisManager::ProfileTask(const char *name, const char */*option*/) const
1154{
1155// Profile a managed task after the execution of the analysis in case NSysInfo
1156// was used.
1157 if (gSystem->AccessPathName("syswatch.root")) {
1158 Error("ProfileTask", "No file syswatch.root found in the current directory");
1159 return;
1160 }
1161 if (gROOT->IsBatch()) return;
1162 AliAnalysisTask *task = (AliAnalysisTask*)fTopTasks->FindObject(name);
1163 if (!task) {
1164 Error("ProfileTask", "No top task named %s known by the manager.", name);
1165 return;
1166 }
1167 Int_t itop = fTopTasks->IndexOf(task);
1168 Int_t itask = fTasks->IndexOf(task);
1169 // Create canvas with 2 pads: first draw COO + Terminate, second Exec
1170 TDirectory *cdir = gDirectory;
1171 TFile f("syswatch.root");
1172 TTree *tree = (TTree*)f.Get("syswatch");
1173 if (!tree) {
1174 Error("ProfileTask", "No tree named <syswatch> found in file syswatch.root");
1175 return;
1176 }
cd463514 1177 if (fDebug > 1) printf("=== Profiling task %s (class %s)\n", name, task->ClassName());
096b5a2e 1178 TCanvas *canvas = new TCanvas(Form("profile_%d",itop),Form("Profile of task %s (class %s)",name,task->ClassName()),10,10,800,600);
1179 canvas->Divide(2, 2, 0.01, 0.01);
1180 Int_t ipad = 1;
1181 TString cut;
1182 TH1 *hist;
1183 // VM profile for COO and Terminate methods
1184 canvas->cd(ipad++);
1185 cut = Form("task==%d && (stage==0 || stage==2)",itask);
1186 tree->Draw("deltaVM:sname",cut,"", 1234567890, 0);
1187 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1188 if (hist) {
084c84df 1189 hist->SetTitle("Alocated VM[MB] for COO and Terminate");
1190 hist->GetYaxis()->SetTitle("deltaVM [MB]");
096b5a2e 1191 hist->GetXaxis()->SetTitle("method");
1192 }
1193 // CPU profile per event
1194 canvas->cd(ipad++);
1195 cut = Form("task==%d && stage==1",itop);
1196 tree->Draw("deltaT:event",cut,"", 1234567890, 0);
1197 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1198 if (hist) {
1199 hist->SetTitle("Execution time per event");
1200 hist->GetYaxis()->SetTitle("CPU/event [s]");
1201 }
1202 // VM profile for Exec
1203 canvas->cd(ipad++);
1204 cut = Form("task==%d && stage==1",itop);
1205 tree->Draw("deltaVM:event",cut,"", 1234567890, 0);
1206 hist = (TH1*)gPad->GetListOfPrimitives()->FindObject("htemp");
1207 if (hist) {
084c84df 1208 hist->SetTitle("Alocated VM[MB] per event");
1209 hist->GetYaxis()->SetTitle("deltaVM [MB]");
096b5a2e 1210 }
1211 canvas->Modified();
1212 delete tree;
1213 f.Close();
1214 if (cdir) cdir->cd();
1215}
d3106602 1216
1217//______________________________________________________________________________
1218void AliAnalysisManager::AddTask(AliAnalysisTask *task)
1219{
1220// Adds a user task to the global list of tasks.
21ca8e59 1221 if (fInitOK) {
1222 Error("AddTask", "Cannot add task %s since InitAnalysis was already called", task->GetName());
1223 return;
1224 }
1225
8d7d3b59 1226 if (fTasks->FindObject(task)) {
1227 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
1228 return;
1229 }
d3106602 1230 task->SetActive(kFALSE);
1231 fTasks->Add(task);
1232}
1233
1234//______________________________________________________________________________
1235AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
1236{
1237// Retreive task by name.
1238 if (!fTasks) return NULL;
1239 return (AliAnalysisTask*)fTasks->FindObject(name);
1240}
1241
1242//______________________________________________________________________________
1243AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
c52c2132 1244 TClass *datatype, EAliAnalysisContType type, const char *filename)
d3106602 1245{
1246// Create a data container of a certain type. Types can be:
84fcd93f 1247// kExchangeContainer = 0, used to exchange data between tasks
d3106602 1248// kInputContainer = 1, used to store input data
84fcd93f 1249// kOutputContainer = 2, used for writing result to a file
1250// filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
1251// the output object to a folder inside the output file
b1310ef5 1252 if (fContainers->FindObject(name)) {
923e2ca5 1253 Error("CreateContainer","A container named %s already defined !",name);
b1310ef5 1254 return NULL;
1255 }
d3106602 1256 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
1257 fContainers->Add(cont);
1258 switch (type) {
1259 case kInputContainer:
1260 fInputs->Add(cont);
1261 break;
1262 case kOutputContainer:
1263 fOutputs->Add(cont);
8c0ab8e8 1264 if (filename && strlen(filename)) {
1265 cont->SetFileName(filename);
6cd44ee0 1266 cont->SetDataOwned(kFALSE); // data owned by the file
1267 }
1268 break;
1269 case kParamContainer:
1270 fParamCont->Add(cont);
1271 if (filename && strlen(filename)) {
1272 cont->SetFileName(filename);
8c0ab8e8 1273 cont->SetDataOwned(kFALSE); // data owned by the file
1274 }
d3106602 1275 break;
c52c2132 1276 case kExchangeContainer:
d3106602 1277 break;
1278 }
1279 return cont;
1280}
1281
1282//______________________________________________________________________________
1283Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
1284 AliAnalysisDataContainer *cont)
1285{
1286// Connect input of an existing task to a data container.
60a04972 1287 if (!task) {
1288 Error("ConnectInput", "Task pointer is NULL");
1289 return kFALSE;
1290 }
d3106602 1291 if (!fTasks->FindObject(task)) {
1292 AddTask(task);
8d7d3b59 1293 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
d3106602 1294 }
1295 Bool_t connected = task->ConnectInput(islot, cont);
1296 return connected;
1297}
1298
1299//______________________________________________________________________________
1300Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
1301 AliAnalysisDataContainer *cont)
1302{
1303// Connect output of an existing task to a data container.
60a04972 1304 if (!task) {
1305 Error("ConnectOutput", "Task pointer is NULL");
1306 return kFALSE;
1307 }
d3106602 1308 if (!fTasks->FindObject(task)) {
1309 AddTask(task);
c52c2132 1310 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
d3106602 1311 }
1312 Bool_t connected = task->ConnectOutput(islot, cont);
1313 return connected;
1314}
1315
1316//______________________________________________________________________________
1317void AliAnalysisManager::CleanContainers()
1318{
1319// Clean data from all containers that have already finished all client tasks.
1320 TIter next(fContainers);
1321 AliAnalysisDataContainer *cont;
1322 while ((cont=(AliAnalysisDataContainer *)next())) {
1323 if (cont->IsOwnedData() &&
1324 cont->IsDataReady() &&
1325 cont->ClientsExecuted()) cont->DeleteData();
1326 }
1327}
1328
1329//______________________________________________________________________________
1330Bool_t AliAnalysisManager::InitAnalysis()
1331{
1332// Initialization of analysis chain of tasks. Should be called after all tasks
1333// and data containers are properly connected
923e2ca5 1334 // Reset flag and remove valid_outputs file if exists
21ca8e59 1335 if (fInitOK) return kTRUE;
923e2ca5 1336 if (!gSystem->AccessPathName("outputs_valid"))
1337 gSystem->Unlink("outputs_valid");
d3106602 1338 // Check for top tasks (depending only on input data containers)
1339 if (!fTasks->First()) {
c52c2132 1340 Error("InitAnalysis", "Analysis has no tasks !");
d3106602 1341 return kFALSE;
1342 }
1343 TIter next(fTasks);
1344 AliAnalysisTask *task;
1345 AliAnalysisDataContainer *cont;
1346 Int_t ntop = 0;
1347 Int_t nzombies = 0;
327eaf46 1348 Bool_t iszombie = kFALSE;
1349 Bool_t istop = kTRUE;
d3106602 1350 Int_t i;
1351 while ((task=(AliAnalysisTask*)next())) {
327eaf46 1352 istop = kTRUE;
1353 iszombie = kFALSE;
d3106602 1354 Int_t ninputs = task->GetNinputs();
d3106602 1355 for (i=0; i<ninputs; i++) {
1356 cont = task->GetInputSlot(i)->GetContainer();
1357 if (!cont) {
327eaf46 1358 if (!iszombie) {
d3106602 1359 task->SetZombie();
1360 fZombies->Add(task);
1361 nzombies++;
327eaf46 1362 iszombie = kTRUE;
d3106602 1363 }
c52c2132 1364 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
1365 i, task->GetName());
d3106602 1366 }
327eaf46 1367 if (iszombie) continue;
d3106602 1368 // Check if cont is an input container
327eaf46 1369 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
d3106602 1370 // Connect to parent task
1371 }
327eaf46 1372 if (istop) {
d3106602 1373 ntop++;
1374 fTopTasks->Add(task);
1375 }
1376 }
1377 if (!ntop) {
c52c2132 1378 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
d3106602 1379 return kFALSE;
1380 }
1381 // Check now if there are orphan tasks
1382 for (i=0; i<ntop; i++) {
1383 task = (AliAnalysisTask*)fTopTasks->At(i);
1384 task->SetUsed();
1385 }
1386 Int_t norphans = 0;
1387 next.Reset();
1388 while ((task=(AliAnalysisTask*)next())) {
1389 if (!task->IsUsed()) {
1390 norphans++;
c52c2132 1391 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
d3106602 1392 }
1393 }
1394 // Check the task hierarchy (no parent task should depend on data provided
1395 // by a daughter task)
1396 for (i=0; i<ntop; i++) {
1397 task = (AliAnalysisTask*)fTopTasks->At(i);
1398 if (task->CheckCircularDeps()) {
c52c2132 1399 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
d3106602 1400 PrintStatus("dep");
1401 return kFALSE;
1402 }
1403 }
b1310ef5 1404 // Check that all containers feeding post-event loop tasks are in the outputs list
1405 TIter nextcont(fContainers); // loop over all containers
1406 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1407 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1408 if (cont->HasConsumers()) {
1409 // Check if one of the consumers is post event loop
1410 TIter nextconsumer(cont->GetConsumers());
1411 while ((task=(AliAnalysisTask*)nextconsumer())) {
1412 if (task->IsPostEventLoop()) {
1413 fOutputs->Add(cont);
1414 break;
1415 }
1416 }
1417 }
1418 }
1419 }
8d7d3b59 1420 // Check if all special output containers have a file name provided
1421 TIter nextout(fOutputs);
1422 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1423 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1424 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1425 return kFALSE;
1426 }
7acc5b9d 1427 }
1428 // Initialize requested branch list if needed
1429 if (!fAutoBranchHandling) {
1430 next.Reset();
1431 while ((task=(AliAnalysisTask*)next())) {
1432 if (!task->HasBranches()) {
1433 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\"",
1434 task->GetName(), task->ClassName());
1435 return kFALSE;
1436 }
1437 if (!fInputEventHandler || !strlen(fInputEventHandler->GetDataType())) {
1438 Error("InitAnalysis", "Manual branch loading requested but no input handler defined or handler does not define data type.");
1439 return kFALSE;
1440 }
1441 TString taskbranches;
1442 task->GetBranches(fInputEventHandler->GetDataType(), taskbranches);
1443 if (taskbranches.IsNull()) {
1444 Error("InitAnalysis", "Manual branch loading requested but task %s of type %s does not define branches of type %s:",
1445 task->GetName(), task->ClassName(), fInputEventHandler->GetDataType());
1446 return kFALSE;
1447 }
1448 AddBranches(taskbranches);
1449 }
1450 }
327eaf46 1451 fInitOK = kTRUE;
d3106602 1452 return kTRUE;
1453}
1454
7acc5b9d 1455//______________________________________________________________________________
1456void AliAnalysisManager::AddBranches(const char *branches)
1457{
1458// Add branches to the existing fRequestedBranches.
1459 TString br(branches);
1460 TObjArray *arr = br.Tokenize(",");
1461 TIter next(arr);
1462 TObject *obj;
1463 while ((obj=next())) {
1464 if (!fRequestedBranches.Contains(obj->GetName())) {
1465 if (!fRequestedBranches.IsNull()) fRequestedBranches += ",";
1466 fRequestedBranches += obj->GetName();
1467 }
1468 }
dcc1f876 1469 delete arr;
7acc5b9d 1470}
1471
1472//______________________________________________________________________________
1473void AliAnalysisManager::CheckBranches(Bool_t load)
1474{
1475// The method checks the input branches to be loaded during the analysis.
1476 if (fAutoBranchHandling || fRequestedBranches.IsNull() || !fTree) return;
1477 TObjArray *arr = fRequestedBranches.Tokenize(",");
1478 TIter next(arr);
1479 TObject *obj;
1480 while ((obj=next())) {
1481 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(obj->GetName()));
1482 if (!br) {
1483 br = fTree->GetBranch(obj->GetName());
1484 if (!br) {
1485 Error("CheckBranches", "Could not find branch %s",obj->GetName());
1486 continue;
1487 }
1488 }
1489 fTable.Add(br);
9162405c 1490 if (load && br->GetReadEntry()!=GetCurrentEntry()) {
1491 br->GetEntry(GetCurrentEntry());
1492 }
7acc5b9d 1493 }
dcc1f876 1494 delete arr;
7acc5b9d 1495}
1496
4747b4a7 1497//______________________________________________________________________________
1498Bool_t AliAnalysisManager::CheckTasks() const
1499{
1500// Check consistency of tasks.
25c87093 1501 Int_t ntasks = fTasks->GetEntries();
1502 if (!ntasks) {
1503 Error("CheckTasks", "No tasks connected to the manager. This may be due to forgetting to compile the task or to load their library.");
1504 return kFALSE;
1505 }
4747b4a7 1506 // Get the pointer to AliAnalysisTaskSE::Class()
1507 TClass *badptr = (TClass*)gROOT->ProcessLine("AliAnalysisTaskSE::Class()");
1508 // Loop all tasks to check if their corresponding library was loaded
1509 TIter next(fTasks);
1510 TObject *obj;
1511 while ((obj=next())) {
1512 if (obj->IsA() == badptr) {
1513 Error("CheckTasks", "##################\n \
1514 Class for task %s NOT loaded. You probably forgot to load the library for this task (or compile it dynamically).\n###########################\n",obj->GetName());
1515 return kFALSE;
1516 }
1517 }
1518 return kTRUE;
1519}
1520
d3106602 1521//______________________________________________________________________________
1522void AliAnalysisManager::PrintStatus(Option_t *option) const
1523{
1524// Print task hierarchy.
8c0ab8e8 1525 if (!fInitOK) {
1526 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1527 return;
1528 }
1529 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1530 if (getsysInfo)
1531 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
d3106602 1532 TIter next(fTopTasks);
1533 AliAnalysisTask *task;
1534 while ((task=(AliAnalysisTask*)next()))
1535 task->PrintTask(option);
dcc1f876 1536
7acc5b9d 1537 if (!fAutoBranchHandling && !fRequestedBranches.IsNull())
1538 printf("Requested input branches:\n%s\n", fRequestedBranches.Data());
dcc1f876 1539
1540 TString sopt(option);
1541 sopt.ToUpper();
1542
1543 if (sopt.Contains("ALL"))
1544 {
1545 if ( fOutputEventHandler )
1546 {
1547 cout << TString('_',78) << endl;
1548 cout << "OutputEventHandler:" << endl;
1549 fOutputEventHandler->Print(" ");
1550 }
1551 }
d3106602 1552}
1553
1554//______________________________________________________________________________
1555void AliAnalysisManager::ResetAnalysis()
1556{
1557// Reset all execution flags and clean containers.
1558 CleanContainers();
1559}
1560
d512d8e2 1561//______________________________________________________________________________
1562void AliAnalysisManager::RunLocalInit()
1563{
1564// Run LocalInit method for all tasks.
1565 TDirectory *cdir = gDirectory;
1566 if (IsTrainInitialized()) return;
1567 TIter nextTask(fTasks);
1568 AliAnalysisTask *task;
1569 while ((task=(AliAnalysisTask*)nextTask())) {
1570 gROOT->cd();
1571 task->LocalInit();
1572 }
2f0e656b 1573 if (cdir) cdir->cd();
d512d8e2 1574 TObject::SetBit(kTasksInitialized, kTRUE);
1575}
1576
27734f0e 1577//______________________________________________________________________________
1578Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
1579{
1580// Start analysis having a grid handler.
1581 if (!fGridHandler) {
1582 Error("StartAnalysis", "Cannot start analysis providing just the analysis type without a grid handler.");
1583 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1584 return -1;
1585 }
1586 TTree *tree = NULL;
1587 return StartAnalysis(type, tree, nentries, firstentry);
1588}
1589
c52c2132 1590//______________________________________________________________________________
61505f8b 1591Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
c52c2132 1592{
aee5ee44 1593// Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1594// MIX. Process nentries starting from firstentry
bf574918 1595 Long64_t retv = 0;
57756ec5 1596 // Backup current directory and make sure gDirectory points to gROOT
1597 TDirectory *cdir = gDirectory;
1598 gROOT->cd();
c52c2132 1599 if (!fInitOK) {
1600 Error("StartAnalysis","Analysis manager was not initialized !");
2f0e656b 1601 if (cdir) cdir->cd();
1f87e9fb 1602 return -1;
c52c2132 1603 }
4747b4a7 1604 if (!CheckTasks()) Fatal("StartAnalysis", "Not all needed libraries were loaded");
20b7268e 1605 if (fDebug > 1) {
1606 printf("StartAnalysis %s\n",GetName());
1607 AliLog::SetGlobalLogLevel(AliLog::kInfo);
1608 }
f03a8355 1609 fMaxEntries = nentries;
8e1f0465 1610 fIsRemote = kFALSE;
c52c2132 1611 TString anaType = type;
1612 anaType.ToLower();
1613 fMode = kLocalAnalysis;
d512d8e2 1614 if (anaType.Contains("file")) fIsRemote = kTRUE;
4ab472d4 1615 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1616 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1617 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1618
c52c2132 1619 if (fMode == kGridAnalysis) {
8e1f0465 1620 fIsRemote = kTRUE;
f866cba5 1621 if (!anaType.Contains("terminate")) {
1622 if (!fGridHandler) {
1623 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1624 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
2f0e656b 1625 if (cdir) cdir->cd();
f866cba5 1626 return -1;
1627 }
1628 // Write analysis manager in the analysis file
1629 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1630 // run local task configuration
d512d8e2 1631 RunLocalInit();
f866cba5 1632 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1633 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
2f0e656b 1634 if (cdir) cdir->cd();
f866cba5 1635 return -1;
1636 }
c57f56b7 1637
f866cba5 1638 // Terminate grid analysis
2f0e656b 1639 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1640 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
f866cba5 1641 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1642 if (!fGridHandler->MergeOutputs()) {
1643 // Return if outputs could not be merged or if it alien handler
1644 // was configured for offline mode or local testing.
2f0e656b 1645 if (cdir) cdir->cd();
f866cba5 1646 return 0;
1647 }
1648 }
1649 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
0309b722 1650 if (cdir) cdir->cd();
c57f56b7 1651 ImportWrappers(NULL);
1652 Terminate();
2f0e656b 1653 if (cdir) cdir->cd();
1f87e9fb 1654 return 0;
981f2614 1655 }
ab5d25d8 1656 TString line;
efd53803 1657 SetEventLoop(kFALSE);
8d7d3b59 1658 // Enable event loop mode if a tree was provided
27734f0e 1659 if (tree || fGridHandler || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
efd53803 1660
8c0ab8e8 1661 TChain *chain = 0;
1662 TString ttype = "TTree";
4ab472d4 1663 if (tree && tree->IsA() == TChain::Class()) {
8c0ab8e8 1664 chain = (TChain*)tree;
6b742510 1665 if (!chain || !chain->GetListOfFiles()->First()) {
1666 Error("StartAnalysis", "Cannot process null or empty chain...");
2f0e656b 1667 if (cdir) cdir->cd();
1f87e9fb 1668 return -1;
6b742510 1669 }
8c0ab8e8 1670 ttype = "TChain";
1671 }
9b33830a 1672
096b5a2e 1673 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1674 if (getsysInfo) AliSysInfo::AddStamp("Start", 0);
aee5ee44 1675 // Initialize locally all tasks (happens for all modes)
9b33830a 1676 TIter next(fTasks);
1677 AliAnalysisTask *task;
d512d8e2 1678 RunLocalInit();
efd53803 1679
c52c2132 1680 switch (fMode) {
1681 case kLocalAnalysis:
27734f0e 1682 if (!tree && !fGridHandler) {
03a5cc9f 1683 TIter nextT(fTasks);
981f2614 1684 // Call CreateOutputObjects for all tasks
096b5a2e 1685 Int_t itask = 0;
979e448a 1686 Bool_t dirStatus = TH1::AddDirectoryStatus();
03a5cc9f 1687 while ((task=(AliAnalysisTask*)nextT())) {
979e448a 1688 TH1::AddDirectory(kFALSE);
c5a87c56 1689 task->CreateOutputObjects();
4747b4a7 1690 if (!task->CheckPostData()) {
1691 Error("SlaveBegin","####### IMPORTANT! ####### \n\n\n\
1692 Task %s (%s) did not call PostData() for all its outputs in (User)CreateOutputObjects()\n\n\
1693 ########### FIX YOUR CODE, THIS WILL PRODUCE A FATAL ERROR IN FUTURE! ###########", task->GetName(), task->ClassName());
1694 }
096b5a2e 1695 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
57756ec5 1696 gROOT->cd();
096b5a2e 1697 itask++;
c5a87c56 1698 }
979e448a 1699 TH1::AddDirectory(dirStatus);
06a59280 1700 if (IsExternalLoop()) {
1701 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1702 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1f87e9fb 1703 return 0;
57756ec5 1704 }
c52c2132 1705 ExecAnalysis();
981f2614 1706 Terminate();
1f87e9fb 1707 return 0;
c52c2132 1708 }
27734f0e 1709 fSelector = new AliAnalysisSelector(this);
1710 // Check if a plugin handler is used
1711 if (fGridHandler) {
1712 // Get the chain from the plugin
1713 TString dataType = "esdTree";
1714 if (fInputEventHandler) {
1715 dataType = fInputEventHandler->GetDataType();
1716 dataType.ToLower();
1717 dataType += "Tree";
1718 }
1719 chain = fGridHandler->GetChainForTestMode(dataType);
1720 if (!chain) {
1721 Error("StartAnalysis", "No chain for test mode. Aborting.");
1722 return -1;
1723 }
1724 cout << "===== RUNNING LOCAL ANALYSIS" << GetName() << " ON CHAIN " << chain->GetName() << endl;
1725 retv = chain->Process(fSelector, "", nentries, firstentry);
1726 break;
1727 }
c52c2132 1728 // Run tree-based analysis via AliAnalysisSelector
c52c2132 1729 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
bf574918 1730 retv = tree->Process(fSelector, "", nentries, firstentry);
c52c2132 1731 break;
1732 case kProofAnalysis:
8e1f0465 1733 fIsRemote = kTRUE;
3bdcb562 1734 // Check if the plugin is used
1735 if (fGridHandler) {
1736 return StartAnalysis(type, fGridHandler->GetProofDataSet(), nentries, firstentry);
1737 }
c52c2132 1738 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
61505f8b 1739 Error("StartAnalysis", "No PROOF!!! Exiting.");
2f0e656b 1740 if (cdir) cdir->cd();
1f87e9fb 1741 return -1;
c52c2132 1742 }
ea091b97 1743 line = Form("gProof->AddInput((TObject*)%p);", this);
c52c2132 1744 gROOT->ProcessLine(line);
1745 if (chain) {
1746 chain->SetProof();
1747 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
bf574918 1748 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
c52c2132 1749 } else {
61505f8b 1750 Error("StartAnalysis", "No chain!!! Exiting.");
2f0e656b 1751 if (cdir) cdir->cd();
1f87e9fb 1752 return -1;
c52c2132 1753 }
1754 break;
1755 case kGridAnalysis:
27734f0e 1756 fIsRemote = kTRUE;
1757 if (!anaType.Contains("terminate")) {
1758 if (!fGridHandler) {
1759 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1760 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
2f0e656b 1761 if (cdir) cdir->cd();
27734f0e 1762 return -1;
1763 }
1764 // Write analysis manager in the analysis file
1765 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1766 // Start the analysis via the handler
1767 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1768 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
2f0e656b 1769 if (cdir) cdir->cd();
27734f0e 1770 return -1;
1771 }
1772
1773 // Terminate grid analysis
2f0e656b 1774 if (fSelector && fSelector->GetStatus() == -1) {if (cdir) cdir->cd(); return -1;}
1775 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {if (cdir) cdir->cd(); return 0;}
27734f0e 1776 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1777 if (!fGridHandler->MergeOutputs()) {
1778 // Return if outputs could not be merged or if it alien handler
1779 // was configured for offline mode or local testing.
2f0e656b 1780 if (cdir) cdir->cd();
27734f0e 1781 return 0;
1782 }
1783 }
1784 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
1785 ImportWrappers(NULL);
1786 Terminate();
2f0e656b 1787 if (cdir) cdir->cd();
27734f0e 1788 return 0;
aee5ee44 1789 case kMixingAnalysis:
1790 // Run event mixing analysis
1791 if (!fEventPool) {
1792 Error("StartAnalysis", "Cannot run event mixing without event pool");
2f0e656b 1793 if (cdir) cdir->cd();
1f87e9fb 1794 return -1;
aee5ee44 1795 }
1796 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1797 fSelector = new AliAnalysisSelector(this);
aee5ee44 1798 while ((chain=fEventPool->GetNextChain())) {
d1e79f9e 1799 next.Reset();
aee5ee44 1800 // Call NotifyBinChange for all tasks
1801 while ((task=(AliAnalysisTask*)next()))
1802 if (!task->IsPostEventLoop()) task->NotifyBinChange();
bf574918 1803 retv = chain->Process(fSelector);
1804 if (retv < 0) {
1805 Error("StartAnalysis", "Mixing analysis failed");
2f0e656b 1806 if (cdir) cdir->cd();
bf574918 1807 return retv;
1808 }
aee5ee44 1809 }
1810 PackOutput(fSelector->GetOutputList());
1811 Terminate();
1f87e9fb 1812 }
2f0e656b 1813 if (cdir) cdir->cd();
bf574918 1814 return retv;
c52c2132 1815}
1816
d86ed856 1817//______________________________________________________________________________
1f87e9fb 1818Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
d86ed856 1819{
1820// Start analysis for this manager on a given dataset. Analysis task can be:
1821// LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1822 if (!fInitOK) {
1823 Error("StartAnalysis","Analysis manager was not initialized !");
1f87e9fb 1824 return -1;
d86ed856 1825 }
8e1f0465 1826 fIsRemote = kTRUE;
cd463514 1827 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
d86ed856 1828 TString anaType = type;
1829 anaType.ToLower();
1830 if (!anaType.Contains("proof")) {
d140f7fb 1831 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
1f87e9fb 1832 return -1;
d86ed856 1833 }
1834 fMode = kProofAnalysis;
ab5d25d8 1835 TString line;
d86ed856 1836 SetEventLoop(kTRUE);
1837 // Set the dataset flag
1838 TObject::SetBit(kUseDataSet);
1839 fTree = 0;
3bdcb562 1840 if (fGridHandler) {
1841 // Start proof analysis using the grid handler
1842 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1843 Error("StartAnalysis", "The grid plugin could not start PROOF analysis");
1844 return -1;
1845 }
1846 // Check if the plugin is in test mode
1847 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kTest) {
830acc4c 1848 dataset = "test_collection";
3bdcb562 1849 } else {
1850 dataset = fGridHandler->GetProofDataSet();
1851 }
1852 }
1853
1854 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1855 Error("StartAnalysis", "No PROOF!!! Exiting.");
1856 return -1;
1857 }
d86ed856 1858
1859 // Initialize locally all tasks
d512d8e2 1860 RunLocalInit();
1861
ea091b97 1862 line = Form("gProof->AddInput((TObject*)%p);", this);
d86ed856 1863 gROOT->ProcessLine(line);
3bdcb562 1864 Long_t retv;
ea091b97 1865 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"\", %lld, %lld);",
1866 dataset, nentries, firstentry);
1867 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
1868 retv = (Long_t)gROOT->ProcessLine(line);
bf574918 1869 return retv;
d86ed856 1870}
1871
d3106602 1872//______________________________________________________________________________
84fcd93f 1873TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
1874{
1875// Opens according the option the file specified by cont->GetFileName() and changes
1876// current directory to cont->GetFolderName(). If the file was already opened, it
1877// checks if the option UPDATE was preserved. File open via TProofOutputFile can
1878// be optionally ignored.
1879 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1880 TString filename = cont->GetFileName();
1881 TFile *f = NULL;
1882 if (filename.IsNull()) {
1883 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
1884 return NULL;
1885 }
1886 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
1887 && !ignoreProof)
1888 f = mgr->OpenProofFile(cont,option);
1889 else {
1890 // Check first if the file is already opened
0f1b50f3 1891 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
84fcd93f 1892 if (f) {
1893 // Check if option "UPDATE" was preserved
1894 TString opt(option);
1895 opt.ToUpper();
1896 if ((opt=="UPDATE") && (opt!=f->GetOption()))
e85311b4 1897 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
84fcd93f 1898 } else {
0f1b50f3 1899 f = TFile::Open(filename, option);
84fcd93f 1900 }
1901 }
1902 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1903 cont->SetFile(f);
1904 // Cd to file
1905 f->cd();
1906 // Check for a folder request
1907 TString dir = cont->GetFolderName();
1908 if (!dir.IsNull()) {
1909 if (!f->GetDirectory(dir)) f->mkdir(dir);
1910 f->cd(dir);
1911 }
1912 return f;
1913 }
1914 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
1915 cont->SetFile(NULL);
1916 return NULL;
1917}
1918
1919//______________________________________________________________________________
039e671e 1920TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option, const char *extaod)
8d7d3b59 1921{
1922// Opens a special output file used in PROOF.
84fcd93f 1923 TString line;
1924 TString filename = cont->GetFileName();
23c9468b 1925 if (cont == fCommonOutput) {
039e671e 1926 if (fOutputEventHandler) {
1927 if (strlen(extaod)) filename = extaod;
1928 filename = fOutputEventHandler->GetOutputFileName();
1929 }
61505f8b 1930 else Fatal("OpenProofFile","No output container. Exiting.");
23c9468b 1931 }
84fcd93f 1932 TFile *f = NULL;
1933 if (fMode!=kProofAnalysis || !fSelector) {
1934 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
1935 return NULL;
1936 }
1937 if (fSpecialOutputLocation.Length()) {
1938 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1939 if (f) {
1940 // Check if option "UPDATE" was preserved
1941 TString opt(option);
1942 opt.ToUpper();
23c9468b 1943 if ((opt=="UPDATE") && (opt!=f->GetOption()))
e85311b4 1944 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
84fcd93f 1945 } else {
1946 f = new TFile(filename, option);
1947 }
1948 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1949 cont->SetFile(f);
1950 // Cd to file
1951 f->cd();
1952 // Check for a folder request
1953 TString dir = cont->GetFolderName();
1954 if (dir.Length()) {
1955 if (!f->GetDirectory(dir)) f->mkdir(dir);
1956 f->cd(dir);
1957 }
f5e61abd 1958 return f;
84fcd93f 1959 }
1960 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
1961 cont->SetFile(NULL);
1962 return NULL;
1963 }
1964 // Check if there is already a proof output file in the output list
1965 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
1966 if (pof) {
1967 // Get the actual file
b3e07543 1968 line = Form("((TProofOutputFile*)%p)->GetFileName();", pof);
84fcd93f 1969 filename = (const char*)gROOT->ProcessLine(line);
90a4b3ee 1970 if (fDebug>1) {
1971 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
1972 }
84fcd93f 1973 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
ab5d25d8 1974 if (!f) {
1975 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
1976 return NULL;
1977 }
84fcd93f 1978 // Check if option "UPDATE" was preserved
1979 TString opt(option);
1980 opt.ToUpper();
1981 if ((opt=="UPDATE") && (opt!=f->GetOption()))
1982 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
1983 } else {
90a4b3ee 1984 if (cont->IsRegisterDataset()) {
61505f8b 1985 TString dsetName = filename;
1986 dsetName.ReplaceAll(".root", cont->GetTitle());
1987 dsetName.ReplaceAll(":","_");
1988 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
1989 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
90a4b3ee 1990 } else {
1991 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
1992 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
1993 }
84fcd93f 1994 if (fDebug > 1) printf("=== %s\n", line.Data());
1995 gROOT->ProcessLine(line);
1996 line = Form("pf->OpenFile(\"%s\");", option);
1997 gROOT->ProcessLine(line);
1998 f = gFile;
1999 if (fDebug > 1) {
8d7d3b59 2000 gROOT->ProcessLine("pf->Print()");
84fcd93f 2001 printf(" == proof file name: %s", f->GetName());
2002 }
2003 // Add to proof output list
b3e07543 2004 line = Form("((TList*)%p)->Add(pf);",fSelector->GetOutputList());
90a4b3ee 2005 if (fDebug > 1) printf("=== %s\n", line.Data());
84fcd93f 2006 gROOT->ProcessLine(line);
2007 }
2008 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
2009 cont->SetFile(f);
2010 // Cd to file
2011 f->cd();
2012 // Check for a folder request
2013 TString dir = cont->GetFolderName();
2014 if (!dir.IsNull()) {
2015 if (!f->GetDirectory(dir)) f->mkdir(dir);
2016 f->cd(dir);
2017 }
2018 return f;
2019 }
2020 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
2021 cont->SetFile(NULL);
2022 return NULL;
8d7d3b59 2023}
2024
2025//______________________________________________________________________________
d3106602 2026void AliAnalysisManager::ExecAnalysis(Option_t *option)
2027{
2028// Execute analysis.
cd463514 2029 static Long64_t nentries = 0;
1f04b637 2030 static TTree *lastTree = 0;
cd463514 2031 static TStopwatch *timer = new TStopwatch();
20b7268e 2032 // Only the first call to Process will trigger a true Notify. Other Notify
2033 // coming before is ignored.
2034 if (!TObject::TestBit(AliAnalysisManager::kTrueNotify)) {
2035 TObject::SetBit(AliAnalysisManager::kTrueNotify);
2036 Notify();
2037 }
e9247450 2038 if (fDebug > 0) printf("MGR: Processing event #%d\n", fNcalls);
cd463514 2039 else {
1f04b637 2040 if (fTree && (fTree != lastTree)) {
2041 nentries += fTree->GetEntries();
2042 lastTree = fTree;
2043 }
e9247450 2044 if (!fNcalls) timer->Start();
f03a8355 2045 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", fNcalls, TMath::Min(fMaxEntries,nentries), timer, kFALSE);
cd463514 2046 }
57756ec5 2047 gROOT->cd();
cd463514 2048 TDirectory *cdir = gDirectory;
8c0ab8e8 2049 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
e9247450 2050 if (getsysInfo && ((fNcalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)fNcalls);
327eaf46 2051 if (!fInitOK) {
57756ec5 2052 Error("ExecAnalysis", "Analysis manager was not initialized !");
2f0e656b 2053 if (cdir) cdir->cd();
327eaf46 2054 return;
57756ec5 2055 }
e9247450 2056 fNcalls++;
d3106602 2057 AliAnalysisTask *task;
327eaf46 2058 // Check if the top tree is active.
2059 if (fTree) {
e9247450 2060 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2061 AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
327eaf46 2062 TIter next(fTasks);
2063 // De-activate all tasks
2064 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
ce46ecc1 2065 AliAnalysisDataContainer *cont = fCommonInput;
2066 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
327eaf46 2067 if (!cont) {
c52c2132 2068 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
2f0e656b 2069 if (cdir) cdir->cd();
327eaf46 2070 return;
2071 }
2072 cont->SetData(fTree); // This will notify all consumers
57756ec5 2073 Long64_t entry = fTree->GetTree()->GetReadEntry();
6bb2b24f 2074//
c3701689 2075// Call BeginEvent() for optional input/output and MC services
ed97dc98 2076 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
2077 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
2078 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
57756ec5 2079 gROOT->cd();
e9247450 2080 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2081 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
6bb2b24f 2082//
2083// Execute the tasks
276941c8 2084// TIter next1(cont->GetConsumers());
2085 TIter next1(fTopTasks);
096b5a2e 2086 Int_t itask = 0;
327eaf46 2087 while ((task=(AliAnalysisTask*)next1())) {
c52c2132 2088 if (fDebug >1) {
2089 cout << " Executing task " << task->GetName() << endl;
096b5a2e 2090 }
327eaf46 2091 task->ExecuteTask(option);
57756ec5 2092 gROOT->cd();
e9247450 2093 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2094 AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
096b5a2e 2095 itask++;
327eaf46 2096 }
6bb2b24f 2097//
2098// Call FinishEvent() for optional output and MC services
6073f8c9 2099 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
6bb2b24f 2100 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
2101 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
8c0ab8e8 2102 // Gather system information if requested
e9247450 2103 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2104 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1001, 1);
2f0e656b 2105 if (cdir) cdir->cd();
327eaf46 2106 return;
2107 }
2108 // The event loop is not controlled by TSelector
6bb2b24f 2109//
c3701689 2110// Call BeginEvent() for optional input/output and MC services
ed97dc98 2111 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
2112 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
2113 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
57756ec5 2114 gROOT->cd();
e9247450 2115 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2116 AliSysInfo::AddStamp("Handlers_BeginEvent",fNcalls, 1000, 0);
327eaf46 2117 TIter next2(fTopTasks);
2118 while ((task=(AliAnalysisTask*)next2())) {
2119 task->SetActive(kTRUE);
c52c2132 2120 if (fDebug > 1) {
2121 cout << " Executing task " << task->GetName() << endl;
2122 }
d3106602 2123 task->ExecuteTask(option);
57756ec5 2124 gROOT->cd();
327eaf46 2125 }
6bb2b24f 2126//
2127// Call FinishEvent() for optional output and MC services
6073f8c9 2128 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
2129 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
6bb2b24f 2130 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
e9247450 2131 if (getsysInfo && ((fNcalls%fNSysInfo)==0))
2132 AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
2f0e656b 2133 if (cdir) cdir->cd();
d3106602 2134}
2135
8ddad121 2136//______________________________________________________________________________
2137Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
2138{
2139// Check if the stdout is connected to a pipe (C.Holm)
2140 Bool_t ispipe = kFALSE;
2141 out.seekp(0, std::ios_base::cur);
2142 if (out.fail()) {
2143 out.clear();
2144 if (errno == ESPIPE) ispipe = kTRUE;
2145 }
2146 return ispipe;
2147}
2148
d3106602 2149//______________________________________________________________________________
61505f8b 2150void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
60a04972 2151{
2152// Set the input event handler and create a container for it.
2153 fInputEventHandler = handler;
523aab8b 2154 if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
60a04972 2155}
2156
2157//______________________________________________________________________________
61505f8b 2158void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
60a04972 2159{
2160// Set the input event handler and create a container for it.
2161 fOutputEventHandler = handler;
523aab8b 2162 if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
673f68ff 2163 fCommonOutput->SetSpecialOutput();
60a04972 2164}
c07b9ce2 2165
f03a8355 2166//______________________________________________________________________________
2167void AliAnalysisManager::SetDebugLevel(UInt_t level)
2168{
2169// Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
2170 if (TObject::TestBit(kUseProgressBar)) {
2171 Info("SetDebugLevel","Ignored. Disable the progress bar first.");
2172 return;
2173 }
2174 fDebug = level;
2175}
2176
2177//______________________________________________________________________________
2178void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
2179{
2180// Enable a text mode progress bar. Resets debug level to 0.
2181 Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
2182 TObject::SetBit(kUseProgressBar,flag);
2183 fPBUpdateFreq = freq;
2184 fDebug = 0;
2185}
2186
c07b9ce2 2187//______________________________________________________________________________
2188void AliAnalysisManager::RegisterExtraFile(const char *fname)
2189{
2190// This method is used externally to register output files which are not
2191// connected to any output container, so that the manager can properly register,
2192// retrieve or merge them when running in distributed mode. The file names are
2193// separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
5b9b4998 2194 if (fExtraFiles.Contains(fname)) return;
c07b9ce2 2195 if (fExtraFiles.Length()) fExtraFiles += " ";
2196 fExtraFiles += fname;
2197}
2198
2199//______________________________________________________________________________
61505f8b 2200Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
c07b9ce2 2201{
2202// Copy a file from the location specified ina the wrapper with the same name from the source list.
61505f8b 2203 char fullPath[512];
2204 char chUrl[512];
b3e07543 2205 char tmp[1024];
c07b9ce2 2206 TObject *pof = source->FindObject(filename);
2207 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
2208 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
2209 return kFALSE;
2210 }
b3e07543 2211 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
2212 gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
61505f8b 2213 TString clientUrl(chUrl);
2214 TString fullPath_str(fullPath);
c07b9ce2 2215 if (clientUrl.Contains("localhost")){
61505f8b 2216 TObjArray* array = fullPath_str.Tokenize ( "//" );
c07b9ce2 2217 TObjString *strobj = ( TObjString *)array->At(1);
2218 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
2219 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
61505f8b 2220 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
2221 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
2222 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
c07b9ce2 2223 delete arrayPort;
2224 delete array;
2225 }
b3e07543 2226 else if (clientUrl.Contains("__lite__")) {
2227 // Special case for ProofLite environement - get file info and copy.
2228 gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
2229 fullPath_str = Form("%s/%s", tmp, fullPath);
2230 }
c07b9ce2 2231 if (fDebug > 1)
b3e07543 2232 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
61505f8b 2233 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
c07b9ce2 2234 if (!gotit)
2235 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
2236 return gotit;
2237}
d29168d6 2238
2239//______________________________________________________________________________
2240void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
2241{
2242// Fill analysis type in the provided string.
2243 switch (fMode) {
2244 case kLocalAnalysis:
2245 type = "local";
2246 return;
2247 case kProofAnalysis:
2248 type = "proof";
2249 return;
2250 case kGridAnalysis:
2251 type = "grid";
2252 return;
2253 case kMixingAnalysis:
2254 type = "mix";
2255 }
2256}
923e2ca5 2257
2258//______________________________________________________________________________
2259Bool_t AliAnalysisManager::ValidateOutputFiles() const
2260{
2261// Validate all output files.
2262 TIter next(fOutputs);
2263 AliAnalysisDataContainer *output;
2264 TDirectory *cdir = gDirectory;
84fcd93f 2265 TString openedFiles;
923e2ca5 2266 while ((output=(AliAnalysisDataContainer*)next())) {
90a4b3ee 2267 if (output->IsRegisterDataset()) continue;
923e2ca5 2268 TString filename = output->GetFileName();
2269 if (filename == "default") {
2270 if (!fOutputEventHandler) continue;
2271 filename = fOutputEventHandler->GetOutputFileName();
b3685485 2272 // Main AOD may not be there
2273 if (gSystem->AccessPathName(filename)) continue;
923e2ca5 2274 }
2275 // Check if the file is closed
84fcd93f 2276 if (openedFiles.Contains(filename)) continue;;
923e2ca5 2277 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
2278 if (file) {
2279 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
f3c07fbd 2280 // Clear file list to release object ownership to user.
160e7161 2281// file->Clear();
923e2ca5 2282 file->Close();
2283 }
2284 file = TFile::Open(filename);
2285 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
2286 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
2f0e656b 2287 if (cdir) cdir->cd();
923e2ca5 2288 return kFALSE;
2289 }
2290 file->Close();
84fcd93f 2291 openedFiles += filename;
2292 openedFiles += " ";
923e2ca5 2293 }
2f0e656b 2294 if (cdir) cdir->cd();
923e2ca5 2295 return kTRUE;
2296}
cd11251e 2297
2298//______________________________________________________________________________
61505f8b 2299void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
cd11251e 2300{
2301// Implements a nice text mode progress bar.
2302 static Long64_t icount = 0;
2303 static TString oname;
2304 static TString nname;
2305 static Long64_t ocurrent = 0;
2306 static Long64_t osize = 0;
2307 static Int_t oseconds = 0;
2308 static TStopwatch *owatch = 0;
2309 static Bool_t oneoftwo = kFALSE;
2310 static Int_t nrefresh = 0;
2311 static Int_t nchecks = 0;
8ddad121 2312 static char lastChar = 0;
f03a8355 2313 const char symbol[4] = {'-','\\','|','/'};
cd11251e 2314
8ddad121 2315 if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
cd11251e 2316 if (!refresh) {
2317 nrefresh = 0;
2318 if (!size) return;
2319 owatch = watch;
2320 oname = opname;
2321 ocurrent = TMath::Abs(current);
2322 osize = TMath::Abs(size);
2323 if (ocurrent > osize) ocurrent=osize;
2324 } else {
2325 nrefresh++;
2326 if (!osize) return;
2327 }
f03a8355 2328 if ((current % fPBUpdateFreq) != 0) return;
cd11251e 2329 icount++;
f03a8355 2330 char progress[11] = " ";
2331 Int_t ichar = icount%4;
cd11251e 2332 Double_t time = 0.;
2333 Int_t hours = 0;
2334 Int_t minutes = 0;
2335 Int_t seconds = 0;
2336 if (owatch && !last) {
2337 owatch->Stop();
2338 time = owatch->RealTime();
f03a8355 2339 seconds = int(time) % 60;
2340 minutes = (int(time) / 60) % 60;
2341 hours = (int(time) / 60 / 60);
cd11251e 2342 if (refresh) {
2343 if (oseconds==seconds) {
2344 owatch->Continue();
2345 return;
2346 }
2347 oneoftwo = !oneoftwo;
2348 }
2349 oseconds = seconds;
2350 }
2351 if (refresh && oneoftwo) {
2352 nname = oname;
2353 if (nchecks <= 0) nchecks = nrefresh+1;
2354 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
2355 oname = Form(" == %d%% ==", pctdone);
2356 }
2357 Double_t percent = 100.0*ocurrent/osize;
2358 Int_t nchar = Int_t(percent/10);
2359 if (nchar>10) nchar=10;
2360 Int_t i;
2361 for (i=0; i<nchar; i++) progress[i] = '=';
2362 progress[nchar] = symbol[ichar];
2363 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2364 progress[10] = '\0';
2365 oname += " ";
2366 oname.Remove(20);
2367 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2368 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2369 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
f03a8355 2370 if (time>0.) {
2371 Int_t full = Int_t(ocurrent > 0 ?
2372 time * (float(osize)/ocurrent) + .5 :
2373 99*3600+59*60+59);
499b6d5d 2374 Int_t remain = Int_t(full - time);
f03a8355 2375 Int_t rsec = remain % 60;
2376 Int_t rmin = (remain / 60) % 60;
2377 Int_t rhour = (remain / 60 / 60);
8ddad121 2378 fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
2379 percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
f03a8355 2380 }
8ddad121 2381 else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
cd11251e 2382 if (refresh && oneoftwo) oname = nname;
2383 if (owatch) owatch->Continue();
2384 if (last) {
2385 icount = 0;
2386 owatch = 0;
2387 ocurrent = 0;
2388 osize = 0;
2389 oseconds = 0;
2390 oneoftwo = kFALSE;
2391 nrefresh = 0;
2392 fprintf(stderr, "\n");
2393 }
2394}
012e169c 2395
2396//______________________________________________________________________________
2397void AliAnalysisManager::DoLoadBranch(const char *name)
2398{
2399 // Get tree and load branch if needed.
c5734a4b 2400 static Long64_t crtEntry = -100;
012e169c 2401
7acc5b9d 2402 if (fAutoBranchHandling || !fTree)
012e169c 2403 return;
2404
2405 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2406 if (!br) {
2407 br = fTree->GetBranch(name);
2408 if (!br) {
979e448a 2409 Error("DoLoadBranch", "Could not find branch %s",name);
012e169c 2410 return;
2411 }
2412 fTable.Add(br);
2413 }
c5734a4b 2414 if (br->GetReadEntry()==fCurrentEntry) return;
9162405c 2415 Long64_t readbytes = br->GetEntry(GetCurrentEntry());
2416 if (readbytes<0) {
f5cbe261 2417 Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
c5734a4b 2418 if (crtEntry != fCurrentEntry) {
2419 CountEvent(1,0,1,0);
2420 crtEntry = fCurrentEntry;
2421 }
2422 } else {
2423 if (crtEntry != fCurrentEntry) {
2424 CountEvent(1,1,0,0);
2425 crtEntry = fCurrentEntry;
2426 }
f5cbe261 2427 }
012e169c 2428}
e9247450 2429
f5cbe261 2430//______________________________________________________________________________
c3732d79 2431void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
f5cbe261 2432{
2433// Add the statistics task to the manager.
2434 if (fStatistics) {
2435 Info("AddStatisticsTask", "Already added");
2436 return;
c3732d79 2437 }
2438 TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
2439 gROOT->ProcessLine(line);
f5cbe261 2440}
2441
2442//______________________________________________________________________________
2443void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
2444{
2445// Bookkeep current event;
2446 if (!fStatistics) return;
2447 fStatistics->AddInput(ninput);
2448 fStatistics->AddProcessed(nprocessed);
2449 fStatistics->AddFailed(nfailed);
2450 fStatistics->AddAccepted(naccepted);
2451}
2452
e9247450 2453//______________________________________________________________________________
2454void AliAnalysisManager::AddStatisticsMsg(const char *line)
2455{
2456// Add a line in the statistics message. If available, the statistics message is written
2457// at the end of the SlaveTerminate phase on workers AND at the end of Terminate
2458// on the client.
2459 if (!strlen(line)) return;
2460 if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
2461 fStatisticsMsg += line;
2462}
2463
2464//______________________________________________________________________________
a99b2241 2465void AliAnalysisManager::WriteStatisticsMsg(Int_t)
e9247450 2466{
23a74fb4 2467// If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
c3732d79 2468 static Bool_t done = kFALSE;
2469 if (done) return;
2470 done = kTRUE;
e296c79c 2471 if (!fStatistics) return;
e9247450 2472 ofstream out;
e296c79c 2473 AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
2474 AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
2475 AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
2476 AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
2477 out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
2478 fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
2479 fStatistics->GetNaccepted()), ios::out);
2480 out << fStatisticsMsg << endl;
e9247450 2481 out.close();
2482}
37196805 2483
2484//______________________________________________________________________________
2485const char* AliAnalysisManager::GetOADBPath()
2486{
2487// returns the path of the OADB
2488// this static function just depends on environment variables
2489
2490 static TString oadbPath;
2491
2492 if (gSystem->Getenv("OADB_PATH"))
2493 oadbPath = gSystem->Getenv("OADB_PATH");
2494 else if (gSystem->Getenv("ALICE_ROOT"))
2495 oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
2496 else
0a9cc013 2497 ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
37196805 2498
2499 return oadbPath;
2500}
77dad4a9 2501
2502//______________________________________________________________________________
2503void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
2504{
2505// Define a custom string variable mapped to a global unique name. The variable
2506// can be then retrieved by a given analysis macro via GetGlobalStr(key).
2507 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2508 if (!mgr) {
2509 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2510 return;
2511 }
2512 Bool_t valid = kFALSE;
2513 TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
2514 if (valid) {
2515 ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
2516 return;
2517 }
2518 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
2519}
2520
2521//______________________________________________________________________________
2522const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
2523{
2524// Static method to retrieve a global variable defined via SetGlobalStr.
2525 valid = kFALSE;
2526 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2527 if (!mgr) return 0;
2528 TObject *value = mgr->GetGlobals()->GetValue(key);
2529 if (!value) return 0;
2530 valid = kTRUE;
2531 return value->GetName();
2532}
2533
2534//______________________________________________________________________________
2535void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
2536{
2537// Define a custom integer variable mapped to a global unique name. The variable
2538// can be then retrieved by a given analysis macro via GetGlobalInt(key).
2539 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2540 if (!mgr) {
2541 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2542 return;
2543 }
2544 Bool_t valid = kFALSE;
2545 Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
2546 if (valid) {
2547 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
2548 return;
2549 }
2550 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
2551}
2552
2553//______________________________________________________________________________
2554Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
2555{
2556// Static method to retrieve a global variable defined via SetGlobalInt.
2557 valid = kFALSE;
2558 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2559 if (!mgr) return 0;
2560 TObject *value = mgr->GetGlobals()->GetValue(key);
2561 if (!value) return 0;
2562 valid = kTRUE;
2563 TString s = value->GetName();
2564 return s.Atoi();
2565}
2566
2567//______________________________________________________________________________
2568void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
2569{
2570// Define a custom double precision variable mapped to a global unique name. The variable
2571// can be then retrieved by a given analysis macro via GetGlobalInt(key).
2572 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2573 if (!mgr) {
2574 ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
2575 return;
2576 }
2577 Bool_t valid = kFALSE;
2578 Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
2579 if (valid) {
2580 ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
2581 return;
2582 }
2583 mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));
2584}
2585
2586//______________________________________________________________________________
2587Double_t AliAnalysisManager::GetGlobalDbl(const char *key, Bool_t &valid)
2588{
2589// Static method to retrieve a global variable defined via SetGlobalDbl.
2590 valid = kFALSE;
2591 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2592 if (!mgr) return 0;
2593 TObject *value = mgr->GetGlobals()->GetValue(key);
2594 if (!value) return 0;
2595 valid = kTRUE;
2596 TString s = value->GetName();
2597 return s.Atof();
2598}
6f3e07d8 2599
2600//______________________________________________________________________________
2601void AliAnalysisManager::AddClassDebug(const char *className, Int_t debugLevel)
2602{
2603// Sets Class debug level
2604
2605 if (!fDebugOptions) {
2606 fDebugOptions = new TObjArray();
2607 fDebugOptions->SetOwner(kTRUE);
2608 }
2609
2610 // substracting DebugOffset, beacuse of AliLog::SetClassDebugLevel()
2611 debugLevel -= AliLog::kDebug-1;
2612
2613 TNamed *debugOpt = (TNamed*)fDebugOptions->FindObject(className);
2614 if (!debugOpt) {
2615 AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel+AliLog::kDebug-1,className).Data());
2616 fDebugOptions->Add(new TNamed(className,TString::Format("%d",debugLevel).Data()));
2617 } else {
2618 TString oldDebugStr = debugOpt->GetTitle();
2619 Int_t oldDebug = oldDebugStr.Atoi();
2620 if (debugLevel > oldDebug) {
2621 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());
2622 debugOpt->SetTitle(TString::Format("%d",debugLevel).Data());
2623 } else {
2624 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());
2625 }
2626 }
2627}
2628
2629//______________________________________________________________________________
2630void AliAnalysisManager::ApplyDebugOptions()
2631{
2632// Apply debug options
2633
2634 if (!fDebugOptions) return;
2635
2636 TIter next(fDebugOptions);
2637 TNamed *debug;
2638 TString debugLevel;
2639 while ((debug=dynamic_cast<TNamed*>(next()))) {
2640 debugLevel = debug->GetTitle();
2641 AliInfo(TString::Format("ApplyDebugOptions : Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()+AliLog::kDebug-1).Data());
2642 AliLog::SetClassDebugLevel(debug->GetName(), debugLevel.Atoi());
2643 }
2644}
2645