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