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