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