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