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