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