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