Corrections for randomized event.
[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>
dd197a68 33#include <TKey.h>
c52c2132 34#include <TMethodCall.h>
35#include <TChain.h>
36#include <TSystem.h>
37#include <TROOT.h>
8c0ab8e8 38#include <TCanvas.h>
a0e2e8b1 39#include <TStopwatch.h>
d3106602 40
8d7d3b59 41#include "AliAnalysisSelector.h"
c57f56b7 42#include "AliAnalysisGrid.h"
d3106602 43#include "AliAnalysisTask.h"
44#include "AliAnalysisDataContainer.h"
45#include "AliAnalysisDataSlot.h"
d2f1d9ef 46#include "AliVEventHandler.h"
c2922515 47#include "AliVEventPool.h"
8c0ab8e8 48#include "AliSysInfo.h"
c52c2132 49#include "AliAnalysisManager.h"
d3106602 50
51ClassImp(AliAnalysisManager)
52
c52c2132 53AliAnalysisManager *AliAnalysisManager::fgAnalysisManager = NULL;
84fcd93f 54TString AliAnalysisManager::fgCommonFileName = "";
c52c2132 55
d3106602 56//______________________________________________________________________________
c52c2132 57AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
58 :TNamed(name,title),
59 fTree(NULL),
8c0ab8e8 60 fInputEventHandler(NULL),
61 fOutputEventHandler(NULL),
62 fMCtruthEventHandler(NULL),
c57f56b7 63 fEventPool(NULL),
c52c2132 64 fCurrentEntry(-1),
8c0ab8e8 65 fNSysInfo(0),
c52c2132 66 fMode(kLocalAnalysis),
67 fInitOK(kFALSE),
68 fDebug(0),
26f071d8 69 fSpecialOutputLocation(""),
37a26056 70 fTasks(NULL),
71 fTopTasks(NULL),
c52c2132 72 fZombies(NULL),
73 fContainers(NULL),
74 fInputs(NULL),
8d7d3b59 75 fOutputs(NULL),
60a04972 76 fCommonInput(NULL),
77 fCommonOutput(NULL),
c57f56b7 78 fSelector(NULL),
c07b9ce2 79 fGridHandler(NULL),
80 fExtraFiles("")
d3106602 81{
82// Default constructor.
c52c2132 83 fgAnalysisManager = this;
84fcd93f 84 fgCommonFileName = "AnalysisResults.root";
c52c2132 85 fTasks = new TObjArray();
86 fTopTasks = new TObjArray();
87 fZombies = new TObjArray();
88 fContainers = new TObjArray();
89 fInputs = new TObjArray();
37153431 90 fOutputs = new TObjArray();
b1310ef5 91 SetEventLoop(kTRUE);
48f1c230 92 TObject::SetObjectStat(kFALSE);
d3106602 93}
94
95//______________________________________________________________________________
96AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
c52c2132 97 :TNamed(other),
327eaf46 98 fTree(NULL),
8c0ab8e8 99 fInputEventHandler(NULL),
100 fOutputEventHandler(NULL),
101 fMCtruthEventHandler(NULL),
84fcd93f 102 fEventPool(NULL),
c52c2132 103 fCurrentEntry(-1),
8c0ab8e8 104 fNSysInfo(0),
c52c2132 105 fMode(other.fMode),
106 fInitOK(other.fInitOK),
107 fDebug(other.fDebug),
26f071d8 108 fSpecialOutputLocation(""),
37a26056 109 fTasks(NULL),
110 fTopTasks(NULL),
c52c2132 111 fZombies(NULL),
112 fContainers(NULL),
113 fInputs(NULL),
8d7d3b59 114 fOutputs(NULL),
60a04972 115 fCommonInput(NULL),
116 fCommonOutput(NULL),
c57f56b7 117 fSelector(NULL),
c07b9ce2 118 fGridHandler(NULL),
119 fExtraFiles()
d3106602 120{
121// Copy constructor.
37a26056 122 fTasks = new TObjArray(*other.fTasks);
123 fTopTasks = new TObjArray(*other.fTopTasks);
124 fZombies = new TObjArray(*other.fZombies);
c52c2132 125 fContainers = new TObjArray(*other.fContainers);
126 fInputs = new TObjArray(*other.fInputs);
127 fOutputs = new TObjArray(*other.fOutputs);
84fcd93f 128 fgCommonFileName = "AnalysisResults.root";
c52c2132 129 fgAnalysisManager = this;
48f1c230 130 TObject::SetObjectStat(kFALSE);
d3106602 131}
132
133//______________________________________________________________________________
134AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& other)
135{
136// Assignment
137 if (&other != this) {
c52c2132 138 TNamed::operator=(other);
54cff064 139 fInputEventHandler = other.fInputEventHandler;
6bb2b24f 140 fOutputEventHandler = other.fOutputEventHandler;
141 fMCtruthEventHandler = other.fMCtruthEventHandler;
c2922515 142 fEventPool = other.fEventPool;
c52c2132 143 fTree = NULL;
144 fCurrentEntry = -1;
8c0ab8e8 145 fNSysInfo = other.fNSysInfo;
c52c2132 146 fMode = other.fMode;
37a26056 147 fInitOK = other.fInitOK;
c52c2132 148 fDebug = other.fDebug;
37a26056 149 fTasks = new TObjArray(*other.fTasks);
150 fTopTasks = new TObjArray(*other.fTopTasks);
151 fZombies = new TObjArray(*other.fZombies);
c52c2132 152 fContainers = new TObjArray(*other.fContainers);
153 fInputs = new TObjArray(*other.fInputs);
154 fOutputs = new TObjArray(*other.fOutputs);
60a04972 155 fCommonInput = NULL;
156 fCommonOutput = NULL;
8d7d3b59 157 fSelector = NULL;
c57f56b7 158 fGridHandler = NULL;
c07b9ce2 159 fExtraFiles = other.fExtraFiles;
84fcd93f 160 fgCommonFileName = "AnalysisResults.root";
c52c2132 161 fgAnalysisManager = this;
d3106602 162 }
163 return *this;
164}
165
166//______________________________________________________________________________
167AliAnalysisManager::~AliAnalysisManager()
168{
169// Destructor.
d3106602 170 if (fTasks) {fTasks->Delete(); delete fTasks;}
171 if (fTopTasks) delete fTopTasks;
172 if (fZombies) delete fZombies;
c52c2132 173 if (fContainers) {fContainers->Delete(); delete fContainers;}
174 if (fInputs) delete fInputs;
175 if (fOutputs) delete fOutputs;
c57f56b7 176 if (fGridHandler) delete fGridHandler;
c52c2132 177 if (fgAnalysisManager==this) fgAnalysisManager = NULL;
48f1c230 178 TObject::SetObjectStat(kTRUE);
d3106602 179}
c52c2132 180
d3106602 181//______________________________________________________________________________
327eaf46 182Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
183{
184// Read one entry of the tree or a whole branch.
84fcd93f 185 if (fDebug > 0) printf("== AliAnalysisManager::GetEntry(%lld)\n", entry);
c52c2132 186 fCurrentEntry = entry;
327eaf46 187 return fTree ? fTree->GetTree()->GetEntry(entry, getall) : 0;
188}
189
190//______________________________________________________________________________
2d626244 191Bool_t AliAnalysisManager::Init(TTree *tree)
d3106602 192{
193 // The Init() function is called when the selector needs to initialize
194 // a new tree or chain. Typically here the branch addresses of the tree
195 // will be set. It is normaly not necessary to make changes to the
196 // generated code, but the routine can be extended by the user if needed.
197 // Init() will be called many times when running with PROOF.
2d626244 198 Bool_t init = kFALSE;
199 if (!tree) return kFALSE; // Should not happen - protected in selector caller
8d7d3b59 200 if (fDebug > 0) {
84fcd93f 201 printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
c52c2132 202 }
f3d59a0d 203 // Call InitTree of EventHandler
36e82a52 204 if (fOutputEventHandler) {
205 if (fMode == kProofAnalysis) {
2d626244 206 init = fOutputEventHandler->Init(0x0, "proof");
36e82a52 207 } else {
2d626244 208 init = fOutputEventHandler->Init(0x0, "local");
36e82a52 209 }
2d626244 210 if (!init) {
211 Error("Init", "Output event handler failed to initialize");
212 return kFALSE;
213 }
36e82a52 214 }
2d626244 215
fdb458ec 216 if (fInputEventHandler) {
36e82a52 217 if (fMode == kProofAnalysis) {
2d626244 218 init = fInputEventHandler->Init(tree, "proof");
36e82a52 219 } else {
2d626244 220 init = fInputEventHandler->Init(tree, "local");
36e82a52 221 }
2d626244 222 if (!init) {
223 Error("Init", "Input event handler failed to initialize tree");
224 return kFALSE;
225 }
e7ae3836 226 } else {
227 // If no input event handler we need to get the tree once
228 // for the chain
2d626244 229 if(!tree->GetTree()) {
230 Long64_t readEntry = tree->LoadTree(0);
231 if (readEntry == -2) {
232 Error("Init", "Input tree has no entry. Aborting");
233 return kFALSE;
234 }
235 }
36e82a52 236 }
237
238 if (fMCtruthEventHandler) {
239 if (fMode == kProofAnalysis) {
2d626244 240 init = fMCtruthEventHandler->Init(0x0, "proof");
36e82a52 241 } else {
2d626244 242 init = fMCtruthEventHandler->Init(0x0, "local");
36e82a52 243 }
2d626244 244 if (!init) {
245 Error("Init", "MC event handler failed to initialize");
246 return kFALSE;
247 }
fdb458ec 248 }
249
c52c2132 250 if (!fInitOK) InitAnalysis();
2d626244 251 if (!fInitOK) return kFALSE;
327eaf46 252 fTree = tree;
ce46ecc1 253 AliAnalysisDataContainer *top = fCommonInput;
254 if (!top) top = (AliAnalysisDataContainer*)fInputs->At(0);
c52c2132 255 if (!top) {
8d7d3b59 256 Error("Init","No top input container !");
2d626244 257 return kFALSE;
37153431 258 }
327eaf46 259 top->SetData(tree);
8d7d3b59 260 if (fDebug > 0) {
84fcd93f 261 printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
981f2614 262 }
2d626244 263 return kTRUE;
d3106602 264}
265
266//______________________________________________________________________________
327eaf46 267void AliAnalysisManager::SlaveBegin(TTree *tree)
d3106602 268{
269 // The SlaveBegin() function is called after the Begin() function.
270 // When running with PROOF SlaveBegin() is called on each slave server.
271 // The tree argument is deprecated (on PROOF 0 is passed).
84fcd93f 272 if (fDebug > 0) printf("->AliAnalysisManager::SlaveBegin()\n");
aee5ee44 273 static Bool_t isCalled = kFALSE;
2d626244 274 Bool_t init = kFALSE;
275 Bool_t initOK = kTRUE;
276 TString msg;
4ab472d4 277 TDirectory *curdir = gDirectory;
aee5ee44 278 // Call SlaveBegin only once in case of mixing
279 if (isCalled && fMode==kMixingAnalysis) return;
f3d59a0d 280 // Call Init of EventHandler
281 if (fOutputEventHandler) {
282 if (fMode == kProofAnalysis) {
673f68ff 283 // Merging AOD's in PROOF via TProofOutputFile
84fcd93f 284 if (fDebug > 1) printf(" Initializing AOD output file %s...\n", fOutputEventHandler->GetOutputFileName());
673f68ff 285 init = fOutputEventHandler->Init("proof");
286 if (!init) msg = "Failed to initialize output handler on worker";
f3d59a0d 287 } else {
2d626244 288 init = fOutputEventHandler->Init("local");
673f68ff 289 if (!init) msg = "Failed to initialize output handler";
f3d59a0d 290 }
2d626244 291 initOK &= init;
292 if (!fSelector) Error("SlaveBegin", "Selector not set");
293 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
f3d59a0d 294 }
295
296 if (fInputEventHandler) {
297 fInputEventHandler->SetInputTree(tree);
298 if (fMode == kProofAnalysis) {
2d626244 299 init = fInputEventHandler->Init("proof");
300 if (!init) msg = "Failed to initialize input handler on worker";
f3d59a0d 301 } else {
2d626244 302 init = fInputEventHandler->Init("local");
303 if (!init) msg = "Failed to initialize input handler";
f3d59a0d 304 }
2d626244 305 initOK &= init;
306 if (!fSelector) Error("SlaveBegin", "Selector not set");
307 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
f3d59a0d 308 }
309
310 if (fMCtruthEventHandler) {
311 if (fMode == kProofAnalysis) {
2d626244 312 init = fMCtruthEventHandler->Init("proof");
313 if (!init) msg = "Failed to initialize MC handler on worker";
f3d59a0d 314 } else {
2d626244 315 init = fMCtruthEventHandler->Init("local");
316 if (!init) msg = "Failed to initialize MC handler";
f3d59a0d 317 }
2d626244 318 initOK &= init;
319 if (!fSelector) Error("SlaveBegin", "Selector not set");
320 else if (!init) {fSelector->Abort(msg); fSelector->SetStatus(-1);}
f3d59a0d 321 }
4ab472d4 322 if (curdir) curdir->cd();
2d626244 323 isCalled = kTRUE;
324 if (!initOK) return;
c52c2132 325 TIter next(fTasks);
326 AliAnalysisTask *task;
327 // Call CreateOutputObjects for all tasks
c5a87c56 328 while ((task=(AliAnalysisTask*)next())) {
4ab472d4 329 curdir = gDirectory;
c52c2132 330 task->CreateOutputObjects();
c5a87c56 331 if (curdir) curdir->cd();
36e82a52 332 }
84fcd93f 333 if (fDebug > 0) printf("<-AliAnalysisManager::SlaveBegin()\n");
d3106602 334}
335
336//______________________________________________________________________________
327eaf46 337Bool_t AliAnalysisManager::Notify()
338{
339 // The Notify() function is called when a new file is opened. This
340 // can be either for a new TTree in a TChain or when when a new TTree
341 // is started when using PROOF. It is normaly not necessary to make changes
342 // to the generated code, but the routine can be extended by the
343 // user if needed. The return value is currently not used.
2d626244 344 if (!fTree) return kFALSE;
345
8d7d3b59 346 TFile *curfile = fTree->GetCurrentFile();
347 if (!curfile) {
348 Error("Notify","No current file");
349 return kFALSE;
350 }
351
84fcd93f 352 if (fDebug > 0) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
8d7d3b59 353 TIter next(fTasks);
354 AliAnalysisTask *task;
355 // Call Notify for all tasks
356 while ((task=(AliAnalysisTask*)next()))
357 task->Notify();
fdb458ec 358
8d7d3b59 359 // Call Notify of the event handlers
360 if (fInputEventHandler) {
361 fInputEventHandler->Notify(curfile->GetName());
362 }
6073f8c9 363
8d7d3b59 364 if (fOutputEventHandler) {
365 fOutputEventHandler->Notify(curfile->GetName());
366 }
890126ab 367
8d7d3b59 368 if (fMCtruthEventHandler) {
369 fMCtruthEventHandler->Notify(curfile->GetName());
370 }
84fcd93f 371 if (fDebug > 0) printf("<-AliAnalysisManager::Notify()\n");
8d7d3b59 372 return kTRUE;
327eaf46 373}
374
375//______________________________________________________________________________
376Bool_t AliAnalysisManager::Process(Long64_t entry)
d3106602 377{
378 // The Process() function is called for each entry in the tree (or possibly
379 // keyed object in the case of PROOF) to be processed. The entry argument
380 // specifies which entry in the currently loaded tree is to be processed.
381 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
382 // to read either all or the required parts of the data. When processing
383 // keyed objects with PROOF, the object is already loaded and is available
384 // via the fObject pointer.
385 //
386 // This function should contain the "body" of the analysis. It can contain
387 // simple or elaborate selection criteria, run algorithms on the data
388 // of the event and typically fill histograms.
389
390 // WARNING when a selector is used with a TChain, you must use
391 // the pointer to the current TTree to call GetEntry(entry).
392 // The entry is always the local entry number in the current tree.
393 // Assuming that fChain is the pointer to the TChain being processed,
394 // use fChain->GetTree()->GetEntry(entry).
84fcd93f 395 if (fDebug > 0) printf("->AliAnalysisManager::Process(%lld)\n", entry);
8d7d3b59 396
ed97dc98 397 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
398 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
399 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
6bb2b24f 400
327eaf46 401 GetEntry(entry);
402 ExecAnalysis();
84fcd93f 403 if (fDebug > 0) printf("<-AliAnalysisManager::Process()\n");
327eaf46 404 return kTRUE;
d3106602 405}
406
407//______________________________________________________________________________
c52c2132 408void AliAnalysisManager::PackOutput(TList *target)
d3106602 409{
981f2614 410 // Pack all output data containers in the output list. Called at SlaveTerminate
411 // stage in PROOF case for each slave.
84fcd93f 412 if (fDebug > 0) printf("->AliAnalysisManager::PackOutput()\n");
c52c2132 413 if (!target) {
414 Error("PackOutput", "No target. Aborting.");
415 return;
37153431 416 }
6073f8c9 417 if (fInputEventHandler) fInputEventHandler ->Terminate();
6bb2b24f 418 if (fOutputEventHandler) fOutputEventHandler ->Terminate();
419 if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
8d7d3b59 420
421 // Call FinishTaskOutput() for each event loop task (not called for
422 // post-event loop tasks - use Terminate() fo those)
423 TIter nexttask(fTasks);
424 AliAnalysisTask *task;
425 while ((task=(AliAnalysisTask*)nexttask())) {
426 if (!task->IsPostEventLoop()) {
84fcd93f 427 if (fDebug > 0) printf("->FinishTaskOutput: task %s\n", task->GetName());
8d7d3b59 428 task->FinishTaskOutput();
84fcd93f 429 if (fDebug > 0) printf("<-FinishTaskOutput: task %s\n", task->GetName());
8d7d3b59 430 }
431 }
8c9485b2 432
c52c2132 433 if (fMode == kProofAnalysis) {
434 TIter next(fOutputs);
435 AliAnalysisDataContainer *output;
4ab472d4 436 Bool_t isManagedByHandler = kFALSE;
c52c2132 437 while ((output=(AliAnalysisDataContainer*)next())) {
8d7d3b59 438 // Do not consider outputs of post event loop tasks
2b83ca27 439 isManagedByHandler = kFALSE;
8d7d3b59 440 if (output->GetProducer()->IsPostEventLoop()) continue;
4ab472d4 441 const char *filename = output->GetFileName();
442 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
443 isManagedByHandler = kTRUE;
84fcd93f 444 printf("#### Handler output. Extra: %s\n", fExtraFiles.Data());
4ab472d4 445 filename = fOutputEventHandler->GetOutputFileName();
446 }
8d7d3b59 447 // Check if data was posted to this container. If not, issue an error.
4ab472d4 448 if (!output->GetData() && !isManagedByHandler) {
923e2ca5 449 Error("PackOutput", "No data for output container %s. Forgot to PostData ?", output->GetName());
8d7d3b59 450 continue;
451 }
452 if (!output->IsSpecialOutput()) {
453 // Normal outputs
4ab472d4 454 if (strlen(filename) && !isManagedByHandler) {
8d7d3b59 455 // Backup current folder
ca78991b 456 TDirectory *opwd = gDirectory;
f2087b52 457 // File resident outputs.
458 // Check first if the file exists.
459 TString open_option = "RECREATE";
460 if (!gSystem->AccessPathName(output->GetFileName())) open_option = "UPDATE";
461 TFile *file = AliAnalysisManager::OpenFile(output, open_option, kTRUE);
ca78991b 462 // Clear file list to release object ownership to user.
ca78991b 463 file->Clear();
8d7d3b59 464 // Save data to file, then close.
1be433fc 465 if (output->GetData()->InheritsFrom(TCollection::Class())) {
466 // If data is a collection, we set the name of the collection
467 // as the one of the container and we save as a single key.
468 TCollection *coll = (TCollection*)output->GetData();
469 coll->SetName(output->GetName());
470 coll->Write(output->GetName(), TObject::kSingleKey);
471 } else {
cbc8747a 472 if (output->GetData()->InheritsFrom(TTree::Class())) {
473 TTree *tree = (TTree*)output->GetData();
21d37b6f 474 // tree->SetDirectory(file);
cbc8747a 475 tree->AutoSave();
476 } else {
477 output->GetData()->Write();
478 }
1be433fc 479 }
84fcd93f 480 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
8d7d3b59 481 if (fDebug > 2) {
84fcd93f 482 printf(" file %s listing content:\n", filename);
8d7d3b59 483 file->ls();
484 }
ca78991b 485 file->Close();
84fcd93f 486 output->SetFile(NULL);
ca78991b 487 // Restore current directory
488 if (opwd) opwd->cd();
8d7d3b59 489 } else {
490 // Memory-resident outputs
84fcd93f 491 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
4ab472d4 492 }
493 AliAnalysisDataWrapper *wrap = 0;
494 if (isManagedByHandler) {
495 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
496 wrap->SetName(output->GetName());
ca78991b 497 }
4ab472d4 498 else wrap =output->ExportData();
cbc8747a 499 // Output wrappers must NOT delete data after merging - the user owns them
500 wrap->SetDeleteData(kFALSE);
8167b1d0 501 target->Add(wrap);
4ab472d4 502 } else {
f5e61abd 503 // Special outputs. The file must be opened and connected to the container.
d0864eb4 504 TDirectory *opwd = gDirectory;
8d7d3b59 505 TFile *file = output->GetFile();
f5e61abd 506 if (!file) {
507 AliAnalysisTask *producer = output->GetProducer();
84fcd93f 508 Fatal("PackOutput",
f5e61abd 509 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
510 output->GetFileName(), output->GetName(), producer->ClassName());
511 continue;
512 }
513 TString outFilename = file->GetName();
84fcd93f 514 if (fDebug > 1) printf("PackOutput %s: special output\n", output->GetName());
4ab472d4 515 if (isManagedByHandler) {
516 // Terminate IO for files managed by the output handler
aa399a26 517 // file->Write() moved to AOD handler (A.G. 11.01.10)
518// if (file) file->Write();
802f90ef 519 if (file && fDebug > 2) {
84fcd93f 520 printf(" handled file %s listing content:\n", file->GetName());
802f90ef 521 file->ls();
522 }
4ab472d4 523 fOutputEventHandler->TerminateIO();
f5e61abd 524 } else {
525 file->cd();
526 // Release object ownership to users after writing data to file
527 if (output->GetData()->InheritsFrom(TCollection::Class())) {
528 // If data is a collection, we set the name of the collection
529 // as the one of the container and we save as a single key.
530 TCollection *coll = (TCollection*)output->GetData();
531 coll->SetName(output->GetName());
532 coll->Write(output->GetName(), TObject::kSingleKey);
cbc8747a 533 } else {
f5e61abd 534 if (output->GetData()->InheritsFrom(TTree::Class())) {
535 TTree *tree = (TTree*)output->GetData();
536 tree->SetDirectory(file);
537 tree->AutoSave();
538 } else {
539 output->GetData()->Write();
540 }
541 }
542 file->Clear();
543 if (fDebug > 2) {
84fcd93f 544 printf(" file %s listing content:\n", output->GetFileName());
f5e61abd 545 file->ls();
546 }
547 file->Close();
84fcd93f 548 output->SetFile(NULL);
ef73322e 549 }
8d7d3b59 550 // Restore current directory
d0864eb4 551 if (opwd) opwd->cd();
8d7d3b59 552 // Check if a special output location was provided or the output files have to be merged
13ef3bb0 553 if (strlen(fSpecialOutputLocation.Data())) {
554 TString remote = fSpecialOutputLocation;
555 remote += "/";
ef788aee 556 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
f5e61abd 557 if (remote.BeginsWith("alien://")) {
558 gROOT->ProcessLine("TGrid::Connect(\"alien://pcapiserv01.cern.ch:10000\", gProofServ->GetUser());");
559 remote += outFilename;
560 remote.ReplaceAll(".root", Form("_%d.root", gid));
561 } else {
562 remote += Form("%s_%d_", gSystem->HostName(), gid);
563 remote += outFilename;
564 }
565 if (fDebug > 1)
566 Info("PackOutput", "Output file for container %s to be copied \n at: %s. No merging.",
567 output->GetName(), remote.Data());
ef73322e 568 TFile::Cp ( outFilename.Data(), remote.Data() );
c9e39043 569 // Copy extra outputs
570 if (fExtraFiles.Length() && isManagedByHandler) {
571 TObjArray *arr = fExtraFiles.Tokenize(" ");
572 TObjString *os;
573 TIter nextfilename(arr);
574 while ((os=(TObjString*)nextfilename())) {
575 outFilename = os->GetString();
576 remote = fSpecialOutputLocation;
577 remote += "/";
578 if (remote.BeginsWith("alien://")) {
579 remote += outFilename;
580 remote.ReplaceAll(".root", Form("_%d.root", gid));
581 } else {
582 remote += Form("%s_%d_", gSystem->HostName(), gid);
583 remote += outFilename;
584 }
585 if (fDebug > 1)
586 Info("PackOutput", "Extra AOD file %s to be copied \n at: %s. No merging.",
587 outFilename.Data(), remote.Data());
588 TFile::Cp ( outFilename.Data(), remote.Data() );
589 }
590 delete arr;
591 }
ca78991b 592 } else {
8d7d3b59 593 // No special location specified-> use TProofOutputFile as merging utility
594 // The file at this output slot must be opened in CreateOutputObjects
84fcd93f 595 if (fDebug > 1) printf(" File for container %s to be merged via file merger...\n", output->GetName());
13ef3bb0 596 }
597 }
c52c2132 598 }
599 }
84fcd93f 600 if (fDebug > 0) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
c52c2132 601}
602
603//______________________________________________________________________________
981f2614 604void AliAnalysisManager::ImportWrappers(TList *source)
c52c2132 605{
981f2614 606// Import data in output containers from wrappers coming in source.
84fcd93f 607 if (fDebug > 0) printf("->AliAnalysisManager::ImportWrappers()\n");
327eaf46 608 TIter next(fOutputs);
981f2614 609 AliAnalysisDataContainer *cont;
610 AliAnalysisDataWrapper *wrap;
611 Int_t icont = 0;
c57f56b7 612 Bool_t inGrid = (fMode == kGridAnalysis)?kTRUE:kFALSE;
84fcd93f 613 TDirectory *cdir = gDirectory;
c52c2132 614 while ((cont=(AliAnalysisDataContainer*)next())) {
0355fc48 615 wrap = 0;
c57f56b7 616 if (cont->GetProducer()->IsPostEventLoop() && !inGrid) continue;
90a4b3ee 617 if (cont->IsRegisterDataset()) continue;
4ab472d4 618 const char *filename = cont->GetFileName();
619 Bool_t isManagedByHandler = kFALSE;
620 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
621 isManagedByHandler = kTRUE;
622 filename = fOutputEventHandler->GetOutputFileName();
623 }
c57f56b7 624 if (cont->IsSpecialOutput() || inGrid) {
f5e61abd 625 if (strlen(fSpecialOutputLocation.Data())) continue;
c57f56b7 626 // Copy merged file from PROOF scratch space.
627 // In case of grid the files are already in the current directory.
628 if (!inGrid) {
c07b9ce2 629 if (isManagedByHandler && fExtraFiles.Length()) {
630 // Copy extra registered dAOD files.
631 TObjArray *arr = fExtraFiles.Tokenize(" ");
632 TObjString *os;
633 TIter nextfilename(arr);
634 while ((os=(TObjString*)nextfilename())) GetFileFromWrapper(os->GetString(), source);
635 delete arr;
c57f56b7 636 }
c07b9ce2 637 if (!GetFileFromWrapper(filename, source)) continue;
c57f56b7 638 }
8d7d3b59 639 // Normally we should connect data from the copied file to the
640 // corresponding output container, but it is not obvious how to do this
641 // automatically if several objects in file...
84fcd93f 642 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
643 if (!f) f = TFile::Open(filename, "READ");
dd197a68 644 if (!f) {
645 Error("ImportWrappers", "Cannot open file %s in read-only mode", filename);
0355fc48 646 continue;
dd197a68 647 }
648 TObject *obj = 0;
84fcd93f 649 // Cd to the directory pointed by the container
650 TString folder = cont->GetFolderName();
651 if (!folder.IsNull()) f->cd(folder);
652 // Try to fetch first an object having the container name.
653 obj = gDirectory->Get(cont->GetName());
dd197a68 654 if (!obj) {
84fcd93f 655 Warning("ImportWrappers", "Could not import object for container %s in file %s:%s.\n Object will not be available in Terminate()",
656 cont->GetName(), filename, cont->GetFolderName());
dd197a68 657 continue;
658 }
0355fc48 659 wrap = new AliAnalysisDataWrapper(obj);
660 wrap->SetDeleteData(kFALSE);
8d7d3b59 661 }
0355fc48 662 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
8d7d3b59 663 if (!wrap) {
664 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
c52c2132 665 continue;
666 }
981f2614 667 icont++;
8d7d3b59 668 if (fDebug > 1) {
84fcd93f 669 printf(" Importing data for container %s\n", cont->GetName());
670 if (strlen(filename)) printf(" -> file %s\n", filename);
671 else printf("\n");
8d7d3b59 672 }
981f2614 673 cont->ImportData(wrap);
84fcd93f 674 }
675 if (cdir) cdir->cd();
676 if (fDebug > 0) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
c52c2132 677}
678
679//______________________________________________________________________________
680void AliAnalysisManager::UnpackOutput(TList *source)
681{
ca78991b 682 // Called by AliAnalysisSelector::Terminate only on the client.
84fcd93f 683 if (fDebug > 0) printf("->AliAnalysisManager::UnpackOutput()\n");
c52c2132 684 if (!source) {
981f2614 685 Error("UnpackOutput", "No target. Aborting.");
c52c2132 686 return;
687 }
84fcd93f 688 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
c52c2132 689
981f2614 690 if (fMode == kProofAnalysis) ImportWrappers(source);
37153431 691
981f2614 692 TIter next(fOutputs);
c52c2132 693 AliAnalysisDataContainer *output;
694 while ((output=(AliAnalysisDataContainer*)next())) {
c52c2132 695 if (!output->GetData()) continue;
b1310ef5 696 // Check if there are client tasks that run post event loop
697 if (output->HasConsumers()) {
698 // Disable event loop semaphore
699 output->SetPostEventLoop(kTRUE);
700 TObjArray *list = output->GetConsumers();
701 Int_t ncons = list->GetEntriesFast();
702 for (Int_t i=0; i<ncons; i++) {
703 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
704 task->CheckNotify(kTRUE);
705 // If task is active, execute it
706 if (task->IsPostEventLoop() && task->IsActive()) {
84fcd93f 707 if (fDebug > 0) printf("== Executing post event loop task %s\n", task->GetName());
b1310ef5 708 task->ExecuteTask();
709 }
710 }
711 }
c52c2132 712 }
84fcd93f 713 if (fDebug > 0) printf("<-AliAnalysisManager::UnpackOutput()\n");
d3106602 714}
715
716//______________________________________________________________________________
717void AliAnalysisManager::Terminate()
718{
719 // The Terminate() function is the last function to be called during
720 // a query. It always runs on the client, it can be used to present
c52c2132 721 // the results graphically.
84fcd93f 722 if (fDebug > 0) printf("->AliAnalysisManager::Terminate()\n");
327eaf46 723 AliAnalysisTask *task;
a0e2e8b1 724 AliAnalysisDataContainer *output;
c52c2132 725 TIter next(fTasks);
a0e2e8b1 726 TStopwatch timer;
327eaf46 727 // Call Terminate() for tasks
90a4b3ee 728 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
a0e2e8b1 729 // Save all the canvases produced by the Terminate
730 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
a0e2e8b1 731 task->Terminate();
732 if (TObject::TestBit(kSaveCanvases)) {
226abfec 733 if (!gROOT->IsBatch()) {
734 Warning("Terminate", "Waiting 5 sec for %s::Terminate() to finish drawing", task->ClassName());
735 timer.Start();
736 while (timer.CpuTime()<5) {
737 timer.Continue();
738 gSystem->ProcessEvents();
739 }
740 }
741 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
742 if (iend==0) continue;
a0e2e8b1 743 TCanvas *canvas;
226abfec 744 for (Int_t ipict=0; ipict<iend; ipict++) {
745 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
a0e2e8b1 746 if (!canvas) continue;
747 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
226abfec 748 }
749 gROOT->GetListOfCanvases()->Delete();
a0e2e8b1 750 }
751 }
8c9485b2 752 //
aa399a26 753 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
754 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
755 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
8c0ab8e8 756 TIter next1(fOutputs);
f2087b52 757 TString handlerFile = "";
758 if (fOutputEventHandler) {
759 handlerFile = fOutputEventHandler->GetOutputFileName();
760 }
8c0ab8e8 761 while ((output=(AliAnalysisDataContainer*)next1())) {
c57f56b7 762 // Special outputs or grid files have the files already closed and written.
763 if (fMode == kGridAnalysis) continue;
90a4b3ee 764 if (fMode == kProofAnalysis) {
765 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
766 }
8c0ab8e8 767 const char *filename = output->GetFileName();
f2087b52 768 TString open_option = "RECREATE";
aa399a26 769 if (!(strcmp(filename, "default"))) continue;
8d7d3b59 770 if (!strlen(filename)) continue;
1be433fc 771 if (!output->GetData()) continue;
8d7d3b59 772 TDirectory *opwd = gDirectory;
84fcd93f 773 TFile *file = output->GetFile();
774 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
f2087b52 775 if (!file) {
776 if (handlerFile == filename && !gSystem->AccessPathName(filename)) open_option = "UPDATE";
777 file = new TFile(filename, open_option);
778 }
84fcd93f 779 if (file->IsZombie()) {
780 Error("Terminate", "Cannot open output file %s", filename);
781 continue;
782 }
8e6e6fe8 783 output->SetFile(file);
784 file->cd();
84fcd93f 785 // Check for a folder request
786 TString dir = output->GetFolderName();
787 if (!dir.IsNull()) {
788 if (!file->GetDirectory(dir)) file->mkdir(dir);
789 file->cd(dir);
790 }
791 if (fDebug > 1) printf(" writing output data %s to file %s:%s\n", output->GetData()->GetName(), file->GetName(), output->GetFolderName());
1be433fc 792 if (output->GetData()->InheritsFrom(TCollection::Class())) {
793 // If data is a collection, we set the name of the collection
794 // as the one of the container and we save as a single key.
795 TCollection *coll = (TCollection*)output->GetData();
796 coll->SetName(output->GetName());
797 coll->Write(output->GetName(), TObject::kSingleKey);
798 } else {
cbc8747a 799 if (output->GetData()->InheritsFrom(TTree::Class())) {
800 TTree *tree = (TTree*)output->GetData();
801 tree->SetDirectory(file);
802 tree->AutoSave();
803 } else {
804 output->GetData()->Write();
805 }
1be433fc 806 }
8e6e6fe8 807 if (opwd) opwd->cd();
808 }
809 next1.Reset();
810 while ((output=(AliAnalysisDataContainer*)next1())) {
811 // Close all files at output
812 TDirectory *opwd = gDirectory;
f5e61abd 813 if (output->GetFile()) {
814 output->GetFile()->Close();
84fcd93f 815 output->SetFile(NULL);
f5e61abd 816 // Copy merged outputs in alien if requested
817 if (fSpecialOutputLocation.Length() &&
818 fSpecialOutputLocation.BeginsWith("alien://")) {
819 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
820 TFile::Cp(output->GetFile()->GetName(),
821 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
822 }
823 }
8d7d3b59 824 if (opwd) opwd->cd();
8c0ab8e8 825 }
826
827 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
828 if (getsysInfo) {
829 TDirectory *cdir = gDirectory;
830 TFile f("syswatch.root", "RECREATE");
831 if (!f.IsZombie()) {
832 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
833 tree->SetMarkerStyle(kCircle);
834 tree->SetMarkerColor(kBlue);
835 tree->SetMarkerSize(0.5);
836 if (!gROOT->IsBatch()) {
837 tree->SetAlias("event", "id0");
6da75e0b 838 tree->SetAlias("memUSED", "mi.fMemUsed");
839 new TCanvas("SysInfo","SysInfo",10,10,800,600);
8c0ab8e8 840 tree->Draw("memUSED:event","","", 1234567890, 0);
8c0ab8e8 841 }
842 tree->Write();
843 f.Close();
844 delete tree;
845 }
846 if (cdir) cdir->cd();
923e2ca5 847 }
848 // Validate the output files
849 if (ValidateOutputFiles()) {
850 ofstream out;
851 out.open("outputs_valid", ios::out);
852 out.close();
8c0ab8e8 853 }
84fcd93f 854 if (fDebug > 0) printf("<-AliAnalysisManager::Terminate()\n");
d3106602 855}
856
857//______________________________________________________________________________
858void AliAnalysisManager::AddTask(AliAnalysisTask *task)
859{
860// Adds a user task to the global list of tasks.
8d7d3b59 861 if (fTasks->FindObject(task)) {
862 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
863 return;
864 }
d3106602 865 task->SetActive(kFALSE);
866 fTasks->Add(task);
867}
868
869//______________________________________________________________________________
870AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
871{
872// Retreive task by name.
873 if (!fTasks) return NULL;
874 return (AliAnalysisTask*)fTasks->FindObject(name);
875}
876
877//______________________________________________________________________________
878AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
c52c2132 879 TClass *datatype, EAliAnalysisContType type, const char *filename)
d3106602 880{
881// Create a data container of a certain type. Types can be:
84fcd93f 882// kExchangeContainer = 0, used to exchange data between tasks
d3106602 883// kInputContainer = 1, used to store input data
84fcd93f 884// kOutputContainer = 2, used for writing result to a file
885// filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
886// the output object to a folder inside the output file
b1310ef5 887 if (fContainers->FindObject(name)) {
923e2ca5 888 Error("CreateContainer","A container named %s already defined !",name);
b1310ef5 889 return NULL;
890 }
d3106602 891 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
892 fContainers->Add(cont);
893 switch (type) {
894 case kInputContainer:
895 fInputs->Add(cont);
896 break;
897 case kOutputContainer:
898 fOutputs->Add(cont);
8c0ab8e8 899 if (filename && strlen(filename)) {
900 cont->SetFileName(filename);
901 cont->SetDataOwned(kFALSE); // data owned by the file
902 }
d3106602 903 break;
c52c2132 904 case kExchangeContainer:
d3106602 905 break;
906 }
907 return cont;
908}
909
910//______________________________________________________________________________
911Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
912 AliAnalysisDataContainer *cont)
913{
914// Connect input of an existing task to a data container.
60a04972 915 if (!task) {
916 Error("ConnectInput", "Task pointer is NULL");
917 return kFALSE;
918 }
d3106602 919 if (!fTasks->FindObject(task)) {
920 AddTask(task);
8d7d3b59 921 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
d3106602 922 }
923 Bool_t connected = task->ConnectInput(islot, cont);
924 return connected;
925}
926
927//______________________________________________________________________________
928Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
929 AliAnalysisDataContainer *cont)
930{
931// Connect output of an existing task to a data container.
60a04972 932 if (!task) {
933 Error("ConnectOutput", "Task pointer is NULL");
934 return kFALSE;
935 }
d3106602 936 if (!fTasks->FindObject(task)) {
937 AddTask(task);
c52c2132 938 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
d3106602 939 }
940 Bool_t connected = task->ConnectOutput(islot, cont);
941 return connected;
942}
943
944//______________________________________________________________________________
945void AliAnalysisManager::CleanContainers()
946{
947// Clean data from all containers that have already finished all client tasks.
948 TIter next(fContainers);
949 AliAnalysisDataContainer *cont;
950 while ((cont=(AliAnalysisDataContainer *)next())) {
951 if (cont->IsOwnedData() &&
952 cont->IsDataReady() &&
953 cont->ClientsExecuted()) cont->DeleteData();
954 }
955}
956
957//______________________________________________________________________________
958Bool_t AliAnalysisManager::InitAnalysis()
959{
960// Initialization of analysis chain of tasks. Should be called after all tasks
961// and data containers are properly connected
923e2ca5 962 // Reset flag and remove valid_outputs file if exists
d3106602 963 fInitOK = kFALSE;
923e2ca5 964 if (!gSystem->AccessPathName("outputs_valid"))
965 gSystem->Unlink("outputs_valid");
d3106602 966 // Check for top tasks (depending only on input data containers)
967 if (!fTasks->First()) {
c52c2132 968 Error("InitAnalysis", "Analysis has no tasks !");
d3106602 969 return kFALSE;
970 }
971 TIter next(fTasks);
972 AliAnalysisTask *task;
973 AliAnalysisDataContainer *cont;
974 Int_t ntop = 0;
975 Int_t nzombies = 0;
327eaf46 976 Bool_t iszombie = kFALSE;
977 Bool_t istop = kTRUE;
d3106602 978 Int_t i;
979 while ((task=(AliAnalysisTask*)next())) {
327eaf46 980 istop = kTRUE;
981 iszombie = kFALSE;
d3106602 982 Int_t ninputs = task->GetNinputs();
d3106602 983 for (i=0; i<ninputs; i++) {
984 cont = task->GetInputSlot(i)->GetContainer();
985 if (!cont) {
327eaf46 986 if (!iszombie) {
d3106602 987 task->SetZombie();
988 fZombies->Add(task);
989 nzombies++;
327eaf46 990 iszombie = kTRUE;
d3106602 991 }
c52c2132 992 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
993 i, task->GetName());
d3106602 994 }
327eaf46 995 if (iszombie) continue;
d3106602 996 // Check if cont is an input container
327eaf46 997 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
d3106602 998 // Connect to parent task
999 }
327eaf46 1000 if (istop) {
d3106602 1001 ntop++;
1002 fTopTasks->Add(task);
1003 }
1004 }
1005 if (!ntop) {
c52c2132 1006 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
d3106602 1007 return kFALSE;
1008 }
1009 // Check now if there are orphan tasks
1010 for (i=0; i<ntop; i++) {
1011 task = (AliAnalysisTask*)fTopTasks->At(i);
1012 task->SetUsed();
1013 }
1014 Int_t norphans = 0;
1015 next.Reset();
1016 while ((task=(AliAnalysisTask*)next())) {
1017 if (!task->IsUsed()) {
1018 norphans++;
c52c2132 1019 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
d3106602 1020 }
1021 }
1022 // Check the task hierarchy (no parent task should depend on data provided
1023 // by a daughter task)
1024 for (i=0; i<ntop; i++) {
1025 task = (AliAnalysisTask*)fTopTasks->At(i);
1026 if (task->CheckCircularDeps()) {
c52c2132 1027 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
d3106602 1028 PrintStatus("dep");
1029 return kFALSE;
1030 }
1031 }
b1310ef5 1032 // Check that all containers feeding post-event loop tasks are in the outputs list
1033 TIter nextcont(fContainers); // loop over all containers
1034 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1035 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1036 if (cont->HasConsumers()) {
1037 // Check if one of the consumers is post event loop
1038 TIter nextconsumer(cont->GetConsumers());
1039 while ((task=(AliAnalysisTask*)nextconsumer())) {
1040 if (task->IsPostEventLoop()) {
1041 fOutputs->Add(cont);
1042 break;
1043 }
1044 }
1045 }
1046 }
1047 }
8d7d3b59 1048 // Check if all special output containers have a file name provided
1049 TIter nextout(fOutputs);
1050 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1051 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1052 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1053 return kFALSE;
1054 }
1055 }
327eaf46 1056 fInitOK = kTRUE;
d3106602 1057 return kTRUE;
1058}
1059
1060//______________________________________________________________________________
1061void AliAnalysisManager::PrintStatus(Option_t *option) const
1062{
1063// Print task hierarchy.
8c0ab8e8 1064 if (!fInitOK) {
1065 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1066 return;
1067 }
1068 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1069 if (getsysInfo)
1070 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
d3106602 1071 TIter next(fTopTasks);
1072 AliAnalysisTask *task;
1073 while ((task=(AliAnalysisTask*)next()))
1074 task->PrintTask(option);
1075}
1076
1077//______________________________________________________________________________
1078void AliAnalysisManager::ResetAnalysis()
1079{
1080// Reset all execution flags and clean containers.
1081 CleanContainers();
1082}
1083
1084//______________________________________________________________________________
8c0ab8e8 1085void AliAnalysisManager::StartAnalysis(const char *type, TTree *tree, Long64_t nentries, Long64_t firstentry)
c52c2132 1086{
aee5ee44 1087// Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1088// MIX. Process nentries starting from firstentry
c52c2132 1089 if (!fInitOK) {
1090 Error("StartAnalysis","Analysis manager was not initialized !");
1091 return;
1092 }
84fcd93f 1093 if (fDebug > 0) printf("StartAnalysis %s\n",GetName());
c52c2132 1094 TString anaType = type;
1095 anaType.ToLower();
1096 fMode = kLocalAnalysis;
c57f56b7 1097 Bool_t runlocalinit = kTRUE;
90a4b3ee 1098 if (anaType.Contains("file")) {
1099 runlocalinit = kFALSE;
90a4b3ee 1100 }
4ab472d4 1101 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1102 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1103 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1104
c52c2132 1105 if (fMode == kGridAnalysis) {
c57f56b7 1106 if (!fGridHandler) {
1107 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1108 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1109 return;
1110 }
1111 // Write analysis manager in the analysis file
1112 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1113 // run local task configuration
1114 TIter nextTask(fTasks);
1115 AliAnalysisTask *task;
1116 while ((task=(AliAnalysisTask*)nextTask())) {
1117 task->LocalInit();
1118 }
5513444a 1119 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1120 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1121 return;
1122 }
c57f56b7 1123
1124 // Terminate grid analysis
2d626244 1125 if (fSelector && fSelector->GetStatus() == -1) return;
c57f56b7 1126 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) return;
1127 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1128 if (!fGridHandler->MergeOutputs()) {
1129 // Return if outputs could not be merged or if it alien handler
1130 // was configured for offline mode or local testing.
1131 return;
1132 }
1133 ImportWrappers(NULL);
1134 Terminate();
1135 return;
981f2614 1136 }
d86ed856 1137 char line[256];
efd53803 1138 SetEventLoop(kFALSE);
8d7d3b59 1139 // Enable event loop mode if a tree was provided
aee5ee44 1140 if (tree || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
efd53803 1141
8c0ab8e8 1142 TChain *chain = 0;
1143 TString ttype = "TTree";
4ab472d4 1144 if (tree && tree->IsA() == TChain::Class()) {
8c0ab8e8 1145 chain = (TChain*)tree;
6b742510 1146 if (!chain || !chain->GetListOfFiles()->First()) {
1147 Error("StartAnalysis", "Cannot process null or empty chain...");
1148 return;
1149 }
8c0ab8e8 1150 ttype = "TChain";
1151 }
9b33830a 1152
aee5ee44 1153 // Initialize locally all tasks (happens for all modes)
9b33830a 1154 TIter next(fTasks);
1155 AliAnalysisTask *task;
c57f56b7 1156 if (runlocalinit) {
1157 while ((task=(AliAnalysisTask*)next())) {
1158 task->LocalInit();
1159 }
1160 }
efd53803 1161
c52c2132 1162 switch (fMode) {
1163 case kLocalAnalysis:
1164 if (!tree) {
03a5cc9f 1165 TIter nextT(fTasks);
981f2614 1166 // Call CreateOutputObjects for all tasks
03a5cc9f 1167 while ((task=(AliAnalysisTask*)nextT())) {
c5a87c56 1168 TDirectory *curdir = gDirectory;
1169 task->CreateOutputObjects();
1170 if (curdir) curdir->cd();
1171 }
06a59280 1172 if (IsExternalLoop()) {
1173 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1174 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1175 return;
1176 }
c52c2132 1177 ExecAnalysis();
981f2614 1178 Terminate();
c52c2132 1179 return;
1180 }
1181 // Run tree-based analysis via AliAnalysisSelector
c52c2132 1182 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
aee5ee44 1183 fSelector = new AliAnalysisSelector(this);
1184 tree->Process(fSelector, "", nentries, firstentry);
c52c2132 1185 break;
1186 case kProofAnalysis:
1187 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
923e2ca5 1188 Error("StartAnalysis", "No PROOF!!! Aborting.");
c52c2132 1189 return;
1190 }
1191 sprintf(line, "gProof->AddInput((TObject*)0x%lx);", (ULong_t)this);
1192 gROOT->ProcessLine(line);
1193 if (chain) {
1194 chain->SetProof();
1195 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
8c0ab8e8 1196 chain->Process("AliAnalysisSelector", "", nentries, firstentry);
c52c2132 1197 } else {
923e2ca5 1198 Error("StartAnalysis", "No chain!!! Aborting.");
c52c2132 1199 return;
1200 }
1201 break;
1202 case kGridAnalysis:
1203 Warning("StartAnalysis", "GRID analysis mode not implemented. Running local.");
aee5ee44 1204 break;
1205 case kMixingAnalysis:
1206 // Run event mixing analysis
1207 if (!fEventPool) {
1208 Error("StartAnalysis", "Cannot run event mixing without event pool");
1209 return;
1210 }
1211 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1212 fSelector = new AliAnalysisSelector(this);
aee5ee44 1213 while ((chain=fEventPool->GetNextChain())) {
d1e79f9e 1214 next.Reset();
aee5ee44 1215 // Call NotifyBinChange for all tasks
1216 while ((task=(AliAnalysisTask*)next()))
1217 if (!task->IsPostEventLoop()) task->NotifyBinChange();
1218 chain->Process(fSelector);
1219 }
1220 PackOutput(fSelector->GetOutputList());
1221 Terminate();
c52c2132 1222 }
1223}
1224
1225//______________________________________________________________________________
d86ed856 1226void AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
1227{
1228// Start analysis for this manager on a given dataset. Analysis task can be:
1229// LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1230 if (!fInitOK) {
1231 Error("StartAnalysis","Analysis manager was not initialized !");
1232 return;
1233 }
84fcd93f 1234 if (fDebug > 0) printf("StartAnalysis %s\n",GetName());
d86ed856 1235 TString anaType = type;
1236 anaType.ToLower();
1237 if (!anaType.Contains("proof")) {
d140f7fb 1238 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
d86ed856 1239 return;
1240 }
1241 fMode = kProofAnalysis;
1242 char line[256];
1243 SetEventLoop(kTRUE);
1244 // Set the dataset flag
1245 TObject::SetBit(kUseDataSet);
1246 fTree = 0;
1247
1248 // Initialize locally all tasks
1249 TIter next(fTasks);
1250 AliAnalysisTask *task;
1251 while ((task=(AliAnalysisTask*)next())) {
1252 task->LocalInit();
1253 }
1254
1255 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
923e2ca5 1256 Error("StartAnalysis", "No PROOF!!! Aborting.");
d86ed856 1257 return;
1258 }
1259 sprintf(line, "gProof->AddInput((TObject*)0x%lx);", (ULong_t)this);
1260 gROOT->ProcessLine(line);
1261 sprintf(line, "gProof->GetDataSet(\"%s\");", dataset);
1262 if (!gROOT->ProcessLine(line)) {
1263 Error("StartAnalysis", "Dataset %s not found", dataset);
1264 return;
1265 }
1266 sprintf(line, "gProof->Process(\"%s\", \"AliAnalysisSelector\", \"\", %lld, %lld);",
1267 dataset, nentries, firstentry);
1268 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
1269 gROOT->ProcessLine(line);
1270}
1271
1272//______________________________________________________________________________
84fcd93f 1273TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
1274{
1275// Opens according the option the file specified by cont->GetFileName() and changes
1276// current directory to cont->GetFolderName(). If the file was already opened, it
1277// checks if the option UPDATE was preserved. File open via TProofOutputFile can
1278// be optionally ignored.
1279 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1280 TString filename = cont->GetFileName();
1281 TFile *f = NULL;
1282 if (filename.IsNull()) {
1283 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
1284 return NULL;
1285 }
1286 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
1287 && !ignoreProof)
1288 f = mgr->OpenProofFile(cont,option);
1289 else {
1290 // Check first if the file is already opened
0f1b50f3 1291 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
84fcd93f 1292 if (f) {
1293 // Check if option "UPDATE" was preserved
1294 TString opt(option);
1295 opt.ToUpper();
1296 if ((opt=="UPDATE") && (opt!=f->GetOption()))
1297 ::Fatal("AliAnalysisManager::OpenFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
1298 } else {
0f1b50f3 1299 f = TFile::Open(filename, option);
84fcd93f 1300 }
1301 }
1302 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1303 cont->SetFile(f);
1304 // Cd to file
1305 f->cd();
1306 // Check for a folder request
1307 TString dir = cont->GetFolderName();
1308 if (!dir.IsNull()) {
1309 if (!f->GetDirectory(dir)) f->mkdir(dir);
1310 f->cd(dir);
1311 }
1312 return f;
1313 }
1314 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
1315 cont->SetFile(NULL);
1316 return NULL;
1317}
1318
1319//______________________________________________________________________________
1320TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option)
8d7d3b59 1321{
1322// Opens a special output file used in PROOF.
84fcd93f 1323 TString line;
1324 TString filename = cont->GetFileName();
23c9468b 1325 if (cont == fCommonOutput) {
1326 if (fOutputEventHandler) filename = fOutputEventHandler->GetOutputFileName();
1327 else Fatal("OpenProofFile","No output container. Aborting.");
1328 }
84fcd93f 1329 TFile *f = NULL;
1330 if (fMode!=kProofAnalysis || !fSelector) {
1331 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
1332 return NULL;
1333 }
1334 if (fSpecialOutputLocation.Length()) {
1335 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1336 if (f) {
1337 // Check if option "UPDATE" was preserved
1338 TString opt(option);
1339 opt.ToUpper();
23c9468b 1340 if ((opt=="UPDATE") && (opt!=f->GetOption()))
84fcd93f 1341 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
1342 } else {
1343 f = new TFile(filename, option);
1344 }
1345 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1346 cont->SetFile(f);
1347 // Cd to file
1348 f->cd();
1349 // Check for a folder request
1350 TString dir = cont->GetFolderName();
1351 if (dir.Length()) {
1352 if (!f->GetDirectory(dir)) f->mkdir(dir);
1353 f->cd(dir);
1354 }
f5e61abd 1355 return f;
84fcd93f 1356 }
1357 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
1358 cont->SetFile(NULL);
1359 return NULL;
1360 }
1361 // Check if there is already a proof output file in the output list
1362 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
1363 if (pof) {
1364 // Get the actual file
1365 line = Form("((TProofOutputFile*)0x%lx)->GetFileName();", (ULong_t)pof);
1366 filename = (const char*)gROOT->ProcessLine(line);
90a4b3ee 1367 if (fDebug>1) {
1368 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
1369 }
84fcd93f 1370 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1371 if (!f) Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
1372 // Check if option "UPDATE" was preserved
1373 TString opt(option);
1374 opt.ToUpper();
1375 if ((opt=="UPDATE") && (opt!=f->GetOption()))
1376 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
1377 } else {
90a4b3ee 1378 if (cont->IsRegisterDataset()) {
1379 TString dset_name = filename;
3df030bb 1380 dset_name.ReplaceAll(".root", cont->GetTitle());
90a4b3ee 1381 dset_name.ReplaceAll(":","_");
1382 if (fDebug>1) printf("Booking dataset: %s\n", dset_name.Data());
1383 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dset_name.Data());
1384 } else {
1385 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
1386 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
1387 }
84fcd93f 1388 if (fDebug > 1) printf("=== %s\n", line.Data());
1389 gROOT->ProcessLine(line);
1390 line = Form("pf->OpenFile(\"%s\");", option);
1391 gROOT->ProcessLine(line);
1392 f = gFile;
1393 if (fDebug > 1) {
8d7d3b59 1394 gROOT->ProcessLine("pf->Print()");
84fcd93f 1395 printf(" == proof file name: %s", f->GetName());
1396 }
1397 // Add to proof output list
1398 line = Form("((TList*)0x%lx)->Add(pf);",(ULong_t)fSelector->GetOutputList());
90a4b3ee 1399 if (fDebug > 1) printf("=== %s\n", line.Data());
84fcd93f 1400 gROOT->ProcessLine(line);
1401 }
1402 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1403 cont->SetFile(f);
1404 // Cd to file
1405 f->cd();
1406 // Check for a folder request
1407 TString dir = cont->GetFolderName();
1408 if (!dir.IsNull()) {
1409 if (!f->GetDirectory(dir)) f->mkdir(dir);
1410 f->cd(dir);
1411 }
1412 return f;
1413 }
1414 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
1415 cont->SetFile(NULL);
1416 return NULL;
8d7d3b59 1417}
1418
1419//______________________________________________________________________________
d3106602 1420void AliAnalysisManager::ExecAnalysis(Option_t *option)
1421{
1422// Execute analysis.
8c0ab8e8 1423 static Long64_t ncalls = 0;
1424 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1425 if (getsysInfo && ncalls==0) AliSysInfo::AddStamp("Start", (Int_t)ncalls);
1426 ncalls++;
327eaf46 1427 if (!fInitOK) {
c52c2132 1428 Error("ExecAnalysis", "Analysis manager was not initialized !");
327eaf46 1429 return;
1430 }
d3106602 1431 AliAnalysisTask *task;
327eaf46 1432 // Check if the top tree is active.
1433 if (fTree) {
1434 TIter next(fTasks);
1435 // De-activate all tasks
1436 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
ce46ecc1 1437 AliAnalysisDataContainer *cont = fCommonInput;
1438 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
327eaf46 1439 if (!cont) {
c52c2132 1440 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
327eaf46 1441 return;
1442 }
1443 cont->SetData(fTree); // This will notify all consumers
ed97dc98 1444 Long64_t entry = fTree->GetTree()->GetReadEntry();
1445
6bb2b24f 1446//
c3701689 1447// Call BeginEvent() for optional input/output and MC services
ed97dc98 1448 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
1449 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
1450 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
6bb2b24f 1451//
1452// Execute the tasks
276941c8 1453// TIter next1(cont->GetConsumers());
1454 TIter next1(fTopTasks);
327eaf46 1455 while ((task=(AliAnalysisTask*)next1())) {
c52c2132 1456 if (fDebug >1) {
1457 cout << " Executing task " << task->GetName() << endl;
1458 }
6bb2b24f 1459
327eaf46 1460 task->ExecuteTask(option);
1461 }
6bb2b24f 1462//
1463// Call FinishEvent() for optional output and MC services
6073f8c9 1464 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
6bb2b24f 1465 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
1466 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
8c0ab8e8 1467 // Gather system information if requested
1468 if (getsysInfo && ((ncalls%fNSysInfo)==0))
1469 AliSysInfo::AddStamp(Form("Event#%lld",ncalls),(Int_t)ncalls);
327eaf46 1470 return;
1471 }
1472 // The event loop is not controlled by TSelector
6bb2b24f 1473//
c3701689 1474// Call BeginEvent() for optional input/output and MC services
ed97dc98 1475 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
1476 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
1477 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
327eaf46 1478 TIter next2(fTopTasks);
1479 while ((task=(AliAnalysisTask*)next2())) {
1480 task->SetActive(kTRUE);
c52c2132 1481 if (fDebug > 1) {
1482 cout << " Executing task " << task->GetName() << endl;
1483 }
d3106602 1484 task->ExecuteTask(option);
327eaf46 1485 }
6bb2b24f 1486//
1487// Call FinishEvent() for optional output and MC services
6073f8c9 1488 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
1489 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
6bb2b24f 1490 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
d3106602 1491}
1492
1493//______________________________________________________________________________
1494void AliAnalysisManager::FinishAnalysis()
1495{
1496// Finish analysis.
1497}
60a04972 1498
1499//______________________________________________________________________________
1500void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* handler)
1501{
1502// Set the input event handler and create a container for it.
1503 fInputEventHandler = handler;
d958c3ea 1504 fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
ce46ecc1 1505 Warning("SetInputEventHandler", " An automatic input container for the input chain was created.\nPlease use: mgr->GetCommonInputContainer() to access it.");
60a04972 1506}
1507
1508//______________________________________________________________________________
1509void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* handler)
1510{
1511// Set the input event handler and create a container for it.
1512 fOutputEventHandler = handler;
d958c3ea 1513 fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
673f68ff 1514 fCommonOutput->SetSpecialOutput();
ca316909 1515 Warning("SetOutputEventHandler", " An automatic output container for the output tree was created.\nPlease use: mgr->GetCommonOutputContainer() to access it.");
60a04972 1516}
c07b9ce2 1517
1518//______________________________________________________________________________
1519void AliAnalysisManager::RegisterExtraFile(const char *fname)
1520{
1521// This method is used externally to register output files which are not
1522// connected to any output container, so that the manager can properly register,
1523// retrieve or merge them when running in distributed mode. The file names are
1524// separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
1525 if (fExtraFiles.Length()) fExtraFiles += " ";
1526 fExtraFiles += fname;
1527}
1528
1529//______________________________________________________________________________
1530Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, TList *source)
1531{
1532// Copy a file from the location specified ina the wrapper with the same name from the source list.
1533 char full_path[512];
1534 char ch_url[512];
1535 TObject *pof = source->FindObject(filename);
1536 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
1537 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
1538 return kFALSE;
1539 }
1540 gROOT->ProcessLine(Form("sprintf((char*)0x%lx, \"%%s\", ((TProofOutputFile*)0x%lx)->GetOutputFileName();)", full_path, pof));
1541 gROOT->ProcessLine(Form("sprintf((char*)0x%lx, \"%%s\", gProof->GetUrl();)", ch_url));
1542 TString clientUrl(ch_url);
1543 TString full_path_str(full_path);
1544 if (clientUrl.Contains("localhost")){
1545 TObjArray* array = full_path_str.Tokenize ( "//" );
1546 TObjString *strobj = ( TObjString *)array->At(1);
1547 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
1548 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
1549 full_path_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
1550 full_path_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
1551 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",full_path_str.Data(),filename);
1552 delete arrayPort;
1553 delete array;
1554 }
1555 if (fDebug > 1)
1556 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space", full_path_str.Data());
1557 Bool_t gotit = TFile::Cp(full_path_str.Data(), filename);
1558 if (!gotit)
1559 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
1560 return gotit;
1561}
d29168d6 1562
1563//______________________________________________________________________________
1564void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
1565{
1566// Fill analysis type in the provided string.
1567 switch (fMode) {
1568 case kLocalAnalysis:
1569 type = "local";
1570 return;
1571 case kProofAnalysis:
1572 type = "proof";
1573 return;
1574 case kGridAnalysis:
1575 type = "grid";
1576 return;
1577 case kMixingAnalysis:
1578 type = "mix";
1579 }
1580}
923e2ca5 1581
1582//______________________________________________________________________________
1583Bool_t AliAnalysisManager::ValidateOutputFiles() const
1584{
1585// Validate all output files.
1586 TIter next(fOutputs);
1587 AliAnalysisDataContainer *output;
1588 TDirectory *cdir = gDirectory;
84fcd93f 1589 TString openedFiles;
923e2ca5 1590 while ((output=(AliAnalysisDataContainer*)next())) {
90a4b3ee 1591 if (output->IsRegisterDataset()) continue;
923e2ca5 1592 TString filename = output->GetFileName();
1593 if (filename == "default") {
1594 if (!fOutputEventHandler) continue;
1595 filename = fOutputEventHandler->GetOutputFileName();
b3685485 1596 // Main AOD may not be there
1597 if (gSystem->AccessPathName(filename)) continue;
923e2ca5 1598 }
1599 // Check if the file is closed
84fcd93f 1600 if (openedFiles.Contains(filename)) continue;;
923e2ca5 1601 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1602 if (file) {
1603 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
1604 file->Close();
1605 }
1606 file = TFile::Open(filename);
1607 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
1608 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
1609 cdir->cd();
1610 return kFALSE;
1611 }
1612 file->Close();
84fcd93f 1613 openedFiles += filename;
1614 openedFiles += " ";
923e2ca5 1615 }
1616 cdir->cd();
1617 return kTRUE;
1618}
cd11251e 1619
1620//______________________________________________________________________________
1621void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch *watch, Bool_t last, Bool_t refresh)
1622{
1623// Implements a nice text mode progress bar.
1624 static Long64_t icount = 0;
1625 static TString oname;
1626 static TString nname;
1627 static Long64_t ocurrent = 0;
1628 static Long64_t osize = 0;
1629 static Int_t oseconds = 0;
1630 static TStopwatch *owatch = 0;
1631 static Bool_t oneoftwo = kFALSE;
1632 static Int_t nrefresh = 0;
1633 static Int_t nchecks = 0;
1634 const char symbol[4] = {'=','\\','|','/'};
1635 char progress[11] = " ";
1636 Int_t ichar = icount%4;
1637
1638 if (!refresh) {
1639 nrefresh = 0;
1640 if (!size) return;
1641 owatch = watch;
1642 oname = opname;
1643 ocurrent = TMath::Abs(current);
1644 osize = TMath::Abs(size);
1645 if (ocurrent > osize) ocurrent=osize;
1646 } else {
1647 nrefresh++;
1648 if (!osize) return;
1649 }
1650 icount++;
1651 Double_t time = 0.;
1652 Int_t hours = 0;
1653 Int_t minutes = 0;
1654 Int_t seconds = 0;
1655 if (owatch && !last) {
1656 owatch->Stop();
1657 time = owatch->RealTime();
1658 hours = (Int_t)(time/3600.);
1659 time -= 3600*hours;
1660 minutes = (Int_t)(time/60.);
1661 time -= 60*minutes;
1662 seconds = (Int_t)time;
1663 if (refresh) {
1664 if (oseconds==seconds) {
1665 owatch->Continue();
1666 return;
1667 }
1668 oneoftwo = !oneoftwo;
1669 }
1670 oseconds = seconds;
1671 }
1672 if (refresh && oneoftwo) {
1673 nname = oname;
1674 if (nchecks <= 0) nchecks = nrefresh+1;
1675 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
1676 oname = Form(" == %d%% ==", pctdone);
1677 }
1678 Double_t percent = 100.0*ocurrent/osize;
1679 Int_t nchar = Int_t(percent/10);
1680 if (nchar>10) nchar=10;
1681 Int_t i;
1682 for (i=0; i<nchar; i++) progress[i] = '=';
1683 progress[nchar] = symbol[ichar];
1684 for (i=nchar+1; i<10; i++) progress[i] = ' ';
1685 progress[10] = '\0';
1686 oname += " ";
1687 oname.Remove(20);
1688 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
1689 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
1690 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
1691 if (time>0.) fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d \r", percent, hours, minutes, seconds);
1692 else fprintf(stderr, "[%6.2f %%]\r", percent);
1693 if (refresh && oneoftwo) oname = nname;
1694 if (owatch) owatch->Continue();
1695 if (last) {
1696 icount = 0;
1697 owatch = 0;
1698 ocurrent = 0;
1699 osize = 0;
1700 oseconds = 0;
1701 oneoftwo = kFALSE;
1702 nrefresh = 0;
1703 fprintf(stderr, "\n");
1704 }
1705}