dsilverm and gconesab: clean-up/simplification of AliEMCALRawUtils - mainly FitRaw...
[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;
84fcd93f 457 // File resident outputs
458 TFile *file = AliAnalysisManager::OpenFile(output, "RECREATE", kTRUE);
ca78991b 459 // Clear file list to release object ownership to user.
ca78991b 460 file->Clear();
8d7d3b59 461 // Save data to file, then close.
1be433fc 462 if (output->GetData()->InheritsFrom(TCollection::Class())) {
463 // If data is a collection, we set the name of the collection
464 // as the one of the container and we save as a single key.
465 TCollection *coll = (TCollection*)output->GetData();
466 coll->SetName(output->GetName());
467 coll->Write(output->GetName(), TObject::kSingleKey);
468 } else {
cbc8747a 469 if (output->GetData()->InheritsFrom(TTree::Class())) {
470 TTree *tree = (TTree*)output->GetData();
21d37b6f 471 // tree->SetDirectory(file);
cbc8747a 472 tree->AutoSave();
473 } else {
474 output->GetData()->Write();
475 }
1be433fc 476 }
84fcd93f 477 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
8d7d3b59 478 if (fDebug > 2) {
84fcd93f 479 printf(" file %s listing content:\n", filename);
8d7d3b59 480 file->ls();
481 }
ca78991b 482 file->Close();
84fcd93f 483 output->SetFile(NULL);
ca78991b 484 // Restore current directory
485 if (opwd) opwd->cd();
8d7d3b59 486 } else {
487 // Memory-resident outputs
84fcd93f 488 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
4ab472d4 489 }
490 AliAnalysisDataWrapper *wrap = 0;
491 if (isManagedByHandler) {
492 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
493 wrap->SetName(output->GetName());
ca78991b 494 }
4ab472d4 495 else wrap =output->ExportData();
cbc8747a 496 // Output wrappers must NOT delete data after merging - the user owns them
497 wrap->SetDeleteData(kFALSE);
8167b1d0 498 target->Add(wrap);
4ab472d4 499 } else {
f5e61abd 500 // Special outputs. The file must be opened and connected to the container.
d0864eb4 501 TDirectory *opwd = gDirectory;
8d7d3b59 502 TFile *file = output->GetFile();
f5e61abd 503 if (!file) {
504 AliAnalysisTask *producer = output->GetProducer();
84fcd93f 505 Fatal("PackOutput",
f5e61abd 506 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
507 output->GetFileName(), output->GetName(), producer->ClassName());
508 continue;
509 }
510 TString outFilename = file->GetName();
84fcd93f 511 if (fDebug > 1) printf("PackOutput %s: special output\n", output->GetName());
4ab472d4 512 if (isManagedByHandler) {
513 // Terminate IO for files managed by the output handler
514 if (file) file->Write();
802f90ef 515 if (file && fDebug > 2) {
84fcd93f 516 printf(" handled file %s listing content:\n", file->GetName());
802f90ef 517 file->ls();
518 }
4ab472d4 519 fOutputEventHandler->TerminateIO();
f5e61abd 520 } else {
521 file->cd();
522 // Release object ownership to users after writing data to file
523 if (output->GetData()->InheritsFrom(TCollection::Class())) {
524 // If data is a collection, we set the name of the collection
525 // as the one of the container and we save as a single key.
526 TCollection *coll = (TCollection*)output->GetData();
527 coll->SetName(output->GetName());
528 coll->Write(output->GetName(), TObject::kSingleKey);
cbc8747a 529 } else {
f5e61abd 530 if (output->GetData()->InheritsFrom(TTree::Class())) {
531 TTree *tree = (TTree*)output->GetData();
532 tree->SetDirectory(file);
533 tree->AutoSave();
534 } else {
535 output->GetData()->Write();
536 }
537 }
538 file->Clear();
539 if (fDebug > 2) {
84fcd93f 540 printf(" file %s listing content:\n", output->GetFileName());
f5e61abd 541 file->ls();
542 }
543 file->Close();
84fcd93f 544 output->SetFile(NULL);
ef73322e 545 }
8d7d3b59 546 // Restore current directory
d0864eb4 547 if (opwd) opwd->cd();
8d7d3b59 548 // Check if a special output location was provided or the output files have to be merged
13ef3bb0 549 if (strlen(fSpecialOutputLocation.Data())) {
550 TString remote = fSpecialOutputLocation;
551 remote += "/";
ef788aee 552 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
f5e61abd 553 if (remote.BeginsWith("alien://")) {
554 gROOT->ProcessLine("TGrid::Connect(\"alien://pcapiserv01.cern.ch:10000\", gProofServ->GetUser());");
555 remote += outFilename;
556 remote.ReplaceAll(".root", Form("_%d.root", gid));
557 } else {
558 remote += Form("%s_%d_", gSystem->HostName(), gid);
559 remote += outFilename;
560 }
561 if (fDebug > 1)
562 Info("PackOutput", "Output file for container %s to be copied \n at: %s. No merging.",
563 output->GetName(), remote.Data());
ef73322e 564 TFile::Cp ( outFilename.Data(), remote.Data() );
c9e39043 565 // Copy extra outputs
566 if (fExtraFiles.Length() && isManagedByHandler) {
567 TObjArray *arr = fExtraFiles.Tokenize(" ");
568 TObjString *os;
569 TIter nextfilename(arr);
570 while ((os=(TObjString*)nextfilename())) {
571 outFilename = os->GetString();
572 remote = fSpecialOutputLocation;
573 remote += "/";
574 if (remote.BeginsWith("alien://")) {
575 remote += outFilename;
576 remote.ReplaceAll(".root", Form("_%d.root", gid));
577 } else {
578 remote += Form("%s_%d_", gSystem->HostName(), gid);
579 remote += outFilename;
580 }
581 if (fDebug > 1)
582 Info("PackOutput", "Extra AOD file %s to be copied \n at: %s. No merging.",
583 outFilename.Data(), remote.Data());
584 TFile::Cp ( outFilename.Data(), remote.Data() );
585 }
586 delete arr;
587 }
ca78991b 588 } else {
8d7d3b59 589 // No special location specified-> use TProofOutputFile as merging utility
590 // The file at this output slot must be opened in CreateOutputObjects
84fcd93f 591 if (fDebug > 1) printf(" File for container %s to be merged via file merger...\n", output->GetName());
13ef3bb0 592 }
593 }
c52c2132 594 }
595 }
84fcd93f 596 if (fDebug > 0) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
c52c2132 597}
598
599//______________________________________________________________________________
981f2614 600void AliAnalysisManager::ImportWrappers(TList *source)
c52c2132 601{
981f2614 602// Import data in output containers from wrappers coming in source.
84fcd93f 603 if (fDebug > 0) printf("->AliAnalysisManager::ImportWrappers()\n");
327eaf46 604 TIter next(fOutputs);
981f2614 605 AliAnalysisDataContainer *cont;
606 AliAnalysisDataWrapper *wrap;
607 Int_t icont = 0;
c57f56b7 608 Bool_t inGrid = (fMode == kGridAnalysis)?kTRUE:kFALSE;
84fcd93f 609 TDirectory *cdir = gDirectory;
c52c2132 610 while ((cont=(AliAnalysisDataContainer*)next())) {
0355fc48 611 wrap = 0;
c57f56b7 612 if (cont->GetProducer()->IsPostEventLoop() && !inGrid) continue;
90a4b3ee 613 if (cont->IsRegisterDataset()) continue;
4ab472d4 614 const char *filename = cont->GetFileName();
615 Bool_t isManagedByHandler = kFALSE;
616 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
617 isManagedByHandler = kTRUE;
618 filename = fOutputEventHandler->GetOutputFileName();
619 }
c57f56b7 620 if (cont->IsSpecialOutput() || inGrid) {
f5e61abd 621 if (strlen(fSpecialOutputLocation.Data())) continue;
c57f56b7 622 // Copy merged file from PROOF scratch space.
623 // In case of grid the files are already in the current directory.
624 if (!inGrid) {
c07b9ce2 625 if (isManagedByHandler && fExtraFiles.Length()) {
626 // Copy extra registered dAOD files.
627 TObjArray *arr = fExtraFiles.Tokenize(" ");
628 TObjString *os;
629 TIter nextfilename(arr);
630 while ((os=(TObjString*)nextfilename())) GetFileFromWrapper(os->GetString(), source);
631 delete arr;
c57f56b7 632 }
c07b9ce2 633 if (!GetFileFromWrapper(filename, source)) continue;
c57f56b7 634 }
8d7d3b59 635 // Normally we should connect data from the copied file to the
636 // corresponding output container, but it is not obvious how to do this
637 // automatically if several objects in file...
84fcd93f 638 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
639 if (!f) f = TFile::Open(filename, "READ");
dd197a68 640 if (!f) {
641 Error("ImportWrappers", "Cannot open file %s in read-only mode", filename);
0355fc48 642 continue;
dd197a68 643 }
644 TObject *obj = 0;
84fcd93f 645 // Cd to the directory pointed by the container
646 TString folder = cont->GetFolderName();
647 if (!folder.IsNull()) f->cd(folder);
648 // Try to fetch first an object having the container name.
649 obj = gDirectory->Get(cont->GetName());
dd197a68 650 if (!obj) {
84fcd93f 651 Warning("ImportWrappers", "Could not import object for container %s in file %s:%s.\n Object will not be available in Terminate()",
652 cont->GetName(), filename, cont->GetFolderName());
dd197a68 653 continue;
654 }
0355fc48 655 wrap = new AliAnalysisDataWrapper(obj);
656 wrap->SetDeleteData(kFALSE);
8d7d3b59 657 }
0355fc48 658 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
8d7d3b59 659 if (!wrap) {
660 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
c52c2132 661 continue;
662 }
981f2614 663 icont++;
8d7d3b59 664 if (fDebug > 1) {
84fcd93f 665 printf(" Importing data for container %s\n", cont->GetName());
666 if (strlen(filename)) printf(" -> file %s\n", filename);
667 else printf("\n");
8d7d3b59 668 }
981f2614 669 cont->ImportData(wrap);
84fcd93f 670 }
671 if (cdir) cdir->cd();
672 if (fDebug > 0) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
c52c2132 673}
674
675//______________________________________________________________________________
676void AliAnalysisManager::UnpackOutput(TList *source)
677{
ca78991b 678 // Called by AliAnalysisSelector::Terminate only on the client.
84fcd93f 679 if (fDebug > 0) printf("->AliAnalysisManager::UnpackOutput()\n");
c52c2132 680 if (!source) {
981f2614 681 Error("UnpackOutput", "No target. Aborting.");
c52c2132 682 return;
683 }
84fcd93f 684 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
c52c2132 685
981f2614 686 if (fMode == kProofAnalysis) ImportWrappers(source);
37153431 687
981f2614 688 TIter next(fOutputs);
c52c2132 689 AliAnalysisDataContainer *output;
690 while ((output=(AliAnalysisDataContainer*)next())) {
c52c2132 691 if (!output->GetData()) continue;
b1310ef5 692 // Check if there are client tasks that run post event loop
693 if (output->HasConsumers()) {
694 // Disable event loop semaphore
695 output->SetPostEventLoop(kTRUE);
696 TObjArray *list = output->GetConsumers();
697 Int_t ncons = list->GetEntriesFast();
698 for (Int_t i=0; i<ncons; i++) {
699 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
700 task->CheckNotify(kTRUE);
701 // If task is active, execute it
702 if (task->IsPostEventLoop() && task->IsActive()) {
84fcd93f 703 if (fDebug > 0) printf("== Executing post event loop task %s\n", task->GetName());
b1310ef5 704 task->ExecuteTask();
705 }
706 }
707 }
c52c2132 708 }
84fcd93f 709 if (fDebug > 0) printf("<-AliAnalysisManager::UnpackOutput()\n");
d3106602 710}
711
712//______________________________________________________________________________
713void AliAnalysisManager::Terminate()
714{
715 // The Terminate() function is the last function to be called during
716 // a query. It always runs on the client, it can be used to present
c52c2132 717 // the results graphically.
84fcd93f 718 if (fDebug > 0) printf("->AliAnalysisManager::Terminate()\n");
327eaf46 719 AliAnalysisTask *task;
a0e2e8b1 720 AliAnalysisDataContainer *output;
c52c2132 721 TIter next(fTasks);
a0e2e8b1 722 TStopwatch timer;
327eaf46 723 // Call Terminate() for tasks
90a4b3ee 724 while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
a0e2e8b1 725 // Save all the canvases produced by the Terminate
726 TString pictname = Form("%s_%s", task->GetName(), task->ClassName());
a0e2e8b1 727 task->Terminate();
728 if (TObject::TestBit(kSaveCanvases)) {
226abfec 729 if (!gROOT->IsBatch()) {
730 Warning("Terminate", "Waiting 5 sec for %s::Terminate() to finish drawing", task->ClassName());
731 timer.Start();
732 while (timer.CpuTime()<5) {
733 timer.Continue();
734 gSystem->ProcessEvents();
735 }
736 }
737 Int_t iend = gROOT->GetListOfCanvases()->GetEntries();
738 if (iend==0) continue;
a0e2e8b1 739 TCanvas *canvas;
226abfec 740 for (Int_t ipict=0; ipict<iend; ipict++) {
741 canvas = (TCanvas*)gROOT->GetListOfCanvases()->At(ipict);
a0e2e8b1 742 if (!canvas) continue;
743 canvas->SaveAs(Form("%s_%02d.gif", pictname.Data(),ipict));
226abfec 744 }
745 gROOT->GetListOfCanvases()->Delete();
a0e2e8b1 746 }
747 }
8c9485b2 748 //
8c0ab8e8 749 TIter next1(fOutputs);
8c0ab8e8 750 while ((output=(AliAnalysisDataContainer*)next1())) {
c57f56b7 751 // Special outputs or grid files have the files already closed and written.
752 if (fMode == kGridAnalysis) continue;
90a4b3ee 753 if (fMode == kProofAnalysis) {
754 if (output->IsSpecialOutput() || output->IsRegisterDataset()) continue;
755 }
8c0ab8e8 756 const char *filename = output->GetFileName();
757 if (!(strcmp(filename, "default"))) {
758 if (fOutputEventHandler) filename = fOutputEventHandler->GetOutputFileName();
1be433fc 759 TFile *aodfile = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
760 if (aodfile) {
84fcd93f 761 if (fDebug > 1) printf("Writing output handler file: %s\n", filename);
1be433fc 762 aodfile->Write();
763 continue;
764 }
8d7d3b59 765 }
766 if (!strlen(filename)) continue;
1be433fc 767 if (!output->GetData()) continue;
8d7d3b59 768 TDirectory *opwd = gDirectory;
84fcd93f 769 TFile *file = output->GetFile();
770 if (!file) file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
8e6e6fe8 771 if (!file) file = new TFile(filename, "RECREATE");
84fcd93f 772 if (file->IsZombie()) {
773 Error("Terminate", "Cannot open output file %s", filename);
774 continue;
775 }
8e6e6fe8 776 output->SetFile(file);
777 file->cd();
84fcd93f 778 // Check for a folder request
779 TString dir = output->GetFolderName();
780 if (!dir.IsNull()) {
781 if (!file->GetDirectory(dir)) file->mkdir(dir);
782 file->cd(dir);
783 }
784 if (fDebug > 1) printf(" writing output data %s to file %s:%s\n", output->GetData()->GetName(), file->GetName(), output->GetFolderName());
1be433fc 785 if (output->GetData()->InheritsFrom(TCollection::Class())) {
786 // If data is a collection, we set the name of the collection
787 // as the one of the container and we save as a single key.
788 TCollection *coll = (TCollection*)output->GetData();
789 coll->SetName(output->GetName());
790 coll->Write(output->GetName(), TObject::kSingleKey);
791 } else {
cbc8747a 792 if (output->GetData()->InheritsFrom(TTree::Class())) {
793 TTree *tree = (TTree*)output->GetData();
794 tree->SetDirectory(file);
795 tree->AutoSave();
796 } else {
797 output->GetData()->Write();
798 }
1be433fc 799 }
8e6e6fe8 800 if (opwd) opwd->cd();
801 }
802 next1.Reset();
803 while ((output=(AliAnalysisDataContainer*)next1())) {
804 // Close all files at output
805 TDirectory *opwd = gDirectory;
f5e61abd 806 if (output->GetFile()) {
807 output->GetFile()->Close();
84fcd93f 808 output->SetFile(NULL);
f5e61abd 809 // Copy merged outputs in alien if requested
810 if (fSpecialOutputLocation.Length() &&
811 fSpecialOutputLocation.BeginsWith("alien://")) {
812 Info("Terminate", "Copy file %s to %s", output->GetFile()->GetName(),fSpecialOutputLocation.Data());
813 TFile::Cp(output->GetFile()->GetName(),
814 Form("%s/%s", fSpecialOutputLocation.Data(), output->GetFile()->GetName()));
815 }
816 }
8d7d3b59 817 if (opwd) opwd->cd();
8c0ab8e8 818 }
819
1be433fc 820 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
821 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
822 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
823
8c0ab8e8 824 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
825 if (getsysInfo) {
826 TDirectory *cdir = gDirectory;
827 TFile f("syswatch.root", "RECREATE");
828 if (!f.IsZombie()) {
829 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
830 tree->SetMarkerStyle(kCircle);
831 tree->SetMarkerColor(kBlue);
832 tree->SetMarkerSize(0.5);
833 if (!gROOT->IsBatch()) {
834 tree->SetAlias("event", "id0");
6da75e0b 835 tree->SetAlias("memUSED", "mi.fMemUsed");
836 new TCanvas("SysInfo","SysInfo",10,10,800,600);
8c0ab8e8 837 tree->Draw("memUSED:event","","", 1234567890, 0);
8c0ab8e8 838 }
839 tree->Write();
840 f.Close();
841 delete tree;
842 }
843 if (cdir) cdir->cd();
923e2ca5 844 }
845 // Validate the output files
846 if (ValidateOutputFiles()) {
847 ofstream out;
848 out.open("outputs_valid", ios::out);
849 out.close();
8c0ab8e8 850 }
84fcd93f 851 if (fDebug > 0) printf("<-AliAnalysisManager::Terminate()\n");
d3106602 852}
853
854//______________________________________________________________________________
855void AliAnalysisManager::AddTask(AliAnalysisTask *task)
856{
857// Adds a user task to the global list of tasks.
8d7d3b59 858 if (fTasks->FindObject(task)) {
859 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
860 return;
861 }
d3106602 862 task->SetActive(kFALSE);
863 fTasks->Add(task);
864}
865
866//______________________________________________________________________________
867AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
868{
869// Retreive task by name.
870 if (!fTasks) return NULL;
871 return (AliAnalysisTask*)fTasks->FindObject(name);
872}
873
874//______________________________________________________________________________
875AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
c52c2132 876 TClass *datatype, EAliAnalysisContType type, const char *filename)
d3106602 877{
878// Create a data container of a certain type. Types can be:
84fcd93f 879// kExchangeContainer = 0, used to exchange data between tasks
d3106602 880// kInputContainer = 1, used to store input data
84fcd93f 881// kOutputContainer = 2, used for writing result to a file
882// filename: composed by file#folder (e.g. results.root#INCLUSIVE) - will write
883// the output object to a folder inside the output file
b1310ef5 884 if (fContainers->FindObject(name)) {
923e2ca5 885 Error("CreateContainer","A container named %s already defined !",name);
b1310ef5 886 return NULL;
887 }
d3106602 888 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
889 fContainers->Add(cont);
890 switch (type) {
891 case kInputContainer:
892 fInputs->Add(cont);
893 break;
894 case kOutputContainer:
895 fOutputs->Add(cont);
8c0ab8e8 896 if (filename && strlen(filename)) {
897 cont->SetFileName(filename);
898 cont->SetDataOwned(kFALSE); // data owned by the file
899 }
d3106602 900 break;
c52c2132 901 case kExchangeContainer:
d3106602 902 break;
903 }
904 return cont;
905}
906
907//______________________________________________________________________________
908Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
909 AliAnalysisDataContainer *cont)
910{
911// Connect input of an existing task to a data container.
60a04972 912 if (!task) {
913 Error("ConnectInput", "Task pointer is NULL");
914 return kFALSE;
915 }
d3106602 916 if (!fTasks->FindObject(task)) {
917 AddTask(task);
8d7d3b59 918 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
d3106602 919 }
920 Bool_t connected = task->ConnectInput(islot, cont);
921 return connected;
922}
923
924//______________________________________________________________________________
925Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
926 AliAnalysisDataContainer *cont)
927{
928// Connect output of an existing task to a data container.
60a04972 929 if (!task) {
930 Error("ConnectOutput", "Task pointer is NULL");
931 return kFALSE;
932 }
d3106602 933 if (!fTasks->FindObject(task)) {
934 AddTask(task);
c52c2132 935 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
d3106602 936 }
937 Bool_t connected = task->ConnectOutput(islot, cont);
938 return connected;
939}
940
941//______________________________________________________________________________
942void AliAnalysisManager::CleanContainers()
943{
944// Clean data from all containers that have already finished all client tasks.
945 TIter next(fContainers);
946 AliAnalysisDataContainer *cont;
947 while ((cont=(AliAnalysisDataContainer *)next())) {
948 if (cont->IsOwnedData() &&
949 cont->IsDataReady() &&
950 cont->ClientsExecuted()) cont->DeleteData();
951 }
952}
953
954//______________________________________________________________________________
955Bool_t AliAnalysisManager::InitAnalysis()
956{
957// Initialization of analysis chain of tasks. Should be called after all tasks
958// and data containers are properly connected
923e2ca5 959 // Reset flag and remove valid_outputs file if exists
d3106602 960 fInitOK = kFALSE;
923e2ca5 961 if (!gSystem->AccessPathName("outputs_valid"))
962 gSystem->Unlink("outputs_valid");
d3106602 963 // Check for top tasks (depending only on input data containers)
964 if (!fTasks->First()) {
c52c2132 965 Error("InitAnalysis", "Analysis has no tasks !");
d3106602 966 return kFALSE;
967 }
968 TIter next(fTasks);
969 AliAnalysisTask *task;
970 AliAnalysisDataContainer *cont;
971 Int_t ntop = 0;
972 Int_t nzombies = 0;
327eaf46 973 Bool_t iszombie = kFALSE;
974 Bool_t istop = kTRUE;
d3106602 975 Int_t i;
976 while ((task=(AliAnalysisTask*)next())) {
327eaf46 977 istop = kTRUE;
978 iszombie = kFALSE;
d3106602 979 Int_t ninputs = task->GetNinputs();
d3106602 980 for (i=0; i<ninputs; i++) {
981 cont = task->GetInputSlot(i)->GetContainer();
982 if (!cont) {
327eaf46 983 if (!iszombie) {
d3106602 984 task->SetZombie();
985 fZombies->Add(task);
986 nzombies++;
327eaf46 987 iszombie = kTRUE;
d3106602 988 }
c52c2132 989 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
990 i, task->GetName());
d3106602 991 }
327eaf46 992 if (iszombie) continue;
d3106602 993 // Check if cont is an input container
327eaf46 994 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
d3106602 995 // Connect to parent task
996 }
327eaf46 997 if (istop) {
d3106602 998 ntop++;
999 fTopTasks->Add(task);
1000 }
1001 }
1002 if (!ntop) {
c52c2132 1003 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
d3106602 1004 return kFALSE;
1005 }
1006 // Check now if there are orphan tasks
1007 for (i=0; i<ntop; i++) {
1008 task = (AliAnalysisTask*)fTopTasks->At(i);
1009 task->SetUsed();
1010 }
1011 Int_t norphans = 0;
1012 next.Reset();
1013 while ((task=(AliAnalysisTask*)next())) {
1014 if (!task->IsUsed()) {
1015 norphans++;
c52c2132 1016 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
d3106602 1017 }
1018 }
1019 // Check the task hierarchy (no parent task should depend on data provided
1020 // by a daughter task)
1021 for (i=0; i<ntop; i++) {
1022 task = (AliAnalysisTask*)fTopTasks->At(i);
1023 if (task->CheckCircularDeps()) {
c52c2132 1024 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
d3106602 1025 PrintStatus("dep");
1026 return kFALSE;
1027 }
1028 }
b1310ef5 1029 // Check that all containers feeding post-event loop tasks are in the outputs list
1030 TIter nextcont(fContainers); // loop over all containers
1031 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
1032 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
1033 if (cont->HasConsumers()) {
1034 // Check if one of the consumers is post event loop
1035 TIter nextconsumer(cont->GetConsumers());
1036 while ((task=(AliAnalysisTask*)nextconsumer())) {
1037 if (task->IsPostEventLoop()) {
1038 fOutputs->Add(cont);
1039 break;
1040 }
1041 }
1042 }
1043 }
1044 }
8d7d3b59 1045 // Check if all special output containers have a file name provided
1046 TIter nextout(fOutputs);
1047 while ((cont=(AliAnalysisDataContainer*)nextout())) {
1048 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
1049 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
1050 return kFALSE;
1051 }
1052 }
327eaf46 1053 fInitOK = kTRUE;
d3106602 1054 return kTRUE;
1055}
1056
1057//______________________________________________________________________________
1058void AliAnalysisManager::PrintStatus(Option_t *option) const
1059{
1060// Print task hierarchy.
8c0ab8e8 1061 if (!fInitOK) {
1062 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
1063 return;
1064 }
1065 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1066 if (getsysInfo)
1067 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
d3106602 1068 TIter next(fTopTasks);
1069 AliAnalysisTask *task;
1070 while ((task=(AliAnalysisTask*)next()))
1071 task->PrintTask(option);
1072}
1073
1074//______________________________________________________________________________
1075void AliAnalysisManager::ResetAnalysis()
1076{
1077// Reset all execution flags and clean containers.
1078 CleanContainers();
1079}
1080
1081//______________________________________________________________________________
8c0ab8e8 1082void AliAnalysisManager::StartAnalysis(const char *type, TTree *tree, Long64_t nentries, Long64_t firstentry)
c52c2132 1083{
aee5ee44 1084// Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1085// MIX. Process nentries starting from firstentry
c52c2132 1086 if (!fInitOK) {
1087 Error("StartAnalysis","Analysis manager was not initialized !");
1088 return;
1089 }
84fcd93f 1090 if (fDebug > 0) printf("StartAnalysis %s\n",GetName());
c52c2132 1091 TString anaType = type;
1092 anaType.ToLower();
1093 fMode = kLocalAnalysis;
c57f56b7 1094 Bool_t runlocalinit = kTRUE;
90a4b3ee 1095 if (anaType.Contains("file")) {
1096 runlocalinit = kFALSE;
1097 SetSkipTerminate(kTRUE);
1098 }
4ab472d4 1099 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1100 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1101 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1102
c52c2132 1103 if (fMode == kGridAnalysis) {
c57f56b7 1104 if (!fGridHandler) {
1105 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1106 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1107 return;
1108 }
1109 // Write analysis manager in the analysis file
1110 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1111 // run local task configuration
1112 TIter nextTask(fTasks);
1113 AliAnalysisTask *task;
1114 while ((task=(AliAnalysisTask*)nextTask())) {
1115 task->LocalInit();
1116 }
5513444a 1117 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1118 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
1119 return;
1120 }
c57f56b7 1121
1122 // Terminate grid analysis
2d626244 1123 if (fSelector && fSelector->GetStatus() == -1) return;
c57f56b7 1124 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) return;
1125 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1126 if (!fGridHandler->MergeOutputs()) {
1127 // Return if outputs could not be merged or if it alien handler
1128 // was configured for offline mode or local testing.
1129 return;
1130 }
1131 ImportWrappers(NULL);
1132 Terminate();
1133 return;
981f2614 1134 }
d86ed856 1135 char line[256];
efd53803 1136 SetEventLoop(kFALSE);
8d7d3b59 1137 // Enable event loop mode if a tree was provided
aee5ee44 1138 if (tree || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
efd53803 1139
8c0ab8e8 1140 TChain *chain = 0;
1141 TString ttype = "TTree";
4ab472d4 1142 if (tree && tree->IsA() == TChain::Class()) {
8c0ab8e8 1143 chain = (TChain*)tree;
6b742510 1144 if (!chain || !chain->GetListOfFiles()->First()) {
1145 Error("StartAnalysis", "Cannot process null or empty chain...");
1146 return;
1147 }
8c0ab8e8 1148 ttype = "TChain";
1149 }
9b33830a 1150
aee5ee44 1151 // Initialize locally all tasks (happens for all modes)
9b33830a 1152 TIter next(fTasks);
1153 AliAnalysisTask *task;
c57f56b7 1154 if (runlocalinit) {
1155 while ((task=(AliAnalysisTask*)next())) {
1156 task->LocalInit();
1157 }
1158 }
efd53803 1159
c52c2132 1160 switch (fMode) {
1161 case kLocalAnalysis:
1162 if (!tree) {
03a5cc9f 1163 TIter nextT(fTasks);
981f2614 1164 // Call CreateOutputObjects for all tasks
03a5cc9f 1165 while ((task=(AliAnalysisTask*)nextT())) {
c5a87c56 1166 TDirectory *curdir = gDirectory;
1167 task->CreateOutputObjects();
1168 if (curdir) curdir->cd();
1169 }
06a59280 1170 if (IsExternalLoop()) {
1171 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1172 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1173 return;
1174 }
c52c2132 1175 ExecAnalysis();
981f2614 1176 Terminate();
c52c2132 1177 return;
1178 }
1179 // Run tree-based analysis via AliAnalysisSelector
c52c2132 1180 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
aee5ee44 1181 fSelector = new AliAnalysisSelector(this);
1182 tree->Process(fSelector, "", nentries, firstentry);
c52c2132 1183 break;
1184 case kProofAnalysis:
1185 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
923e2ca5 1186 Error("StartAnalysis", "No PROOF!!! Aborting.");
c52c2132 1187 return;
1188 }
1189 sprintf(line, "gProof->AddInput((TObject*)0x%lx);", (ULong_t)this);
1190 gROOT->ProcessLine(line);
1191 if (chain) {
1192 chain->SetProof();
1193 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
8c0ab8e8 1194 chain->Process("AliAnalysisSelector", "", nentries, firstentry);
c52c2132 1195 } else {
923e2ca5 1196 Error("StartAnalysis", "No chain!!! Aborting.");
c52c2132 1197 return;
1198 }
1199 break;
1200 case kGridAnalysis:
1201 Warning("StartAnalysis", "GRID analysis mode not implemented. Running local.");
aee5ee44 1202 break;
1203 case kMixingAnalysis:
1204 // Run event mixing analysis
1205 if (!fEventPool) {
1206 Error("StartAnalysis", "Cannot run event mixing without event pool");
1207 return;
1208 }
1209 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1210 fSelector = new AliAnalysisSelector(this);
aee5ee44 1211 while ((chain=fEventPool->GetNextChain())) {
d1e79f9e 1212 next.Reset();
aee5ee44 1213 // Call NotifyBinChange for all tasks
1214 while ((task=(AliAnalysisTask*)next()))
1215 if (!task->IsPostEventLoop()) task->NotifyBinChange();
1216 chain->Process(fSelector);
1217 }
1218 PackOutput(fSelector->GetOutputList());
1219 Terminate();
c52c2132 1220 }
1221}
1222
1223//______________________________________________________________________________
d86ed856 1224void AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
1225{
1226// Start analysis for this manager on a given dataset. Analysis task can be:
1227// LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1228 if (!fInitOK) {
1229 Error("StartAnalysis","Analysis manager was not initialized !");
1230 return;
1231 }
84fcd93f 1232 if (fDebug > 0) printf("StartAnalysis %s\n",GetName());
d86ed856 1233 TString anaType = type;
1234 anaType.ToLower();
1235 if (!anaType.Contains("proof")) {
d140f7fb 1236 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
d86ed856 1237 return;
1238 }
1239 fMode = kProofAnalysis;
1240 char line[256];
1241 SetEventLoop(kTRUE);
1242 // Set the dataset flag
1243 TObject::SetBit(kUseDataSet);
1244 fTree = 0;
1245
1246 // Initialize locally all tasks
1247 TIter next(fTasks);
1248 AliAnalysisTask *task;
1249 while ((task=(AliAnalysisTask*)next())) {
1250 task->LocalInit();
1251 }
1252
1253 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
923e2ca5 1254 Error("StartAnalysis", "No PROOF!!! Aborting.");
d86ed856 1255 return;
1256 }
1257 sprintf(line, "gProof->AddInput((TObject*)0x%lx);", (ULong_t)this);
1258 gROOT->ProcessLine(line);
1259 sprintf(line, "gProof->GetDataSet(\"%s\");", dataset);
1260 if (!gROOT->ProcessLine(line)) {
1261 Error("StartAnalysis", "Dataset %s not found", dataset);
1262 return;
1263 }
1264 sprintf(line, "gProof->Process(\"%s\", \"AliAnalysisSelector\", \"\", %lld, %lld);",
1265 dataset, nentries, firstentry);
1266 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
1267 gROOT->ProcessLine(line);
1268}
1269
1270//______________________________________________________________________________
84fcd93f 1271TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
1272{
1273// Opens according the option the file specified by cont->GetFileName() and changes
1274// current directory to cont->GetFolderName(). If the file was already opened, it
1275// checks if the option UPDATE was preserved. File open via TProofOutputFile can
1276// be optionally ignored.
1277 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1278 TString filename = cont->GetFileName();
1279 TFile *f = NULL;
1280 if (filename.IsNull()) {
1281 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
1282 return NULL;
1283 }
1284 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
1285 && !ignoreProof)
1286 f = mgr->OpenProofFile(cont,option);
1287 else {
1288 // Check first if the file is already opened
0f1b50f3 1289 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
84fcd93f 1290 if (f) {
1291 // Check if option "UPDATE" was preserved
1292 TString opt(option);
1293 opt.ToUpper();
1294 if ((opt=="UPDATE") && (opt!=f->GetOption()))
1295 ::Fatal("AliAnalysisManager::OpenFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
1296 } else {
0f1b50f3 1297 f = TFile::Open(filename, option);
84fcd93f 1298 }
1299 }
1300 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1301 cont->SetFile(f);
1302 // Cd to file
1303 f->cd();
1304 // Check for a folder request
1305 TString dir = cont->GetFolderName();
1306 if (!dir.IsNull()) {
1307 if (!f->GetDirectory(dir)) f->mkdir(dir);
1308 f->cd(dir);
1309 }
1310 return f;
1311 }
1312 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
1313 cont->SetFile(NULL);
1314 return NULL;
1315}
1316
1317//______________________________________________________________________________
1318TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option)
8d7d3b59 1319{
1320// Opens a special output file used in PROOF.
84fcd93f 1321 TString line;
1322 TString filename = cont->GetFileName();
23c9468b 1323 if (cont == fCommonOutput) {
1324 if (fOutputEventHandler) filename = fOutputEventHandler->GetOutputFileName();
1325 else Fatal("OpenProofFile","No output container. Aborting.");
1326 }
84fcd93f 1327 TFile *f = NULL;
1328 if (fMode!=kProofAnalysis || !fSelector) {
1329 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
1330 return NULL;
1331 }
1332 if (fSpecialOutputLocation.Length()) {
1333 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1334 if (f) {
1335 // Check if option "UPDATE" was preserved
1336 TString opt(option);
1337 opt.ToUpper();
23c9468b 1338 if ((opt=="UPDATE") && (opt!=f->GetOption()))
84fcd93f 1339 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
1340 } else {
1341 f = new TFile(filename, option);
1342 }
1343 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1344 cont->SetFile(f);
1345 // Cd to file
1346 f->cd();
1347 // Check for a folder request
1348 TString dir = cont->GetFolderName();
1349 if (dir.Length()) {
1350 if (!f->GetDirectory(dir)) f->mkdir(dir);
1351 f->cd(dir);
1352 }
f5e61abd 1353 return f;
84fcd93f 1354 }
1355 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
1356 cont->SetFile(NULL);
1357 return NULL;
1358 }
1359 // Check if there is already a proof output file in the output list
1360 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
1361 if (pof) {
1362 // Get the actual file
1363 line = Form("((TProofOutputFile*)0x%lx)->GetFileName();", (ULong_t)pof);
1364 filename = (const char*)gROOT->ProcessLine(line);
90a4b3ee 1365 if (fDebug>1) {
1366 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
1367 }
84fcd93f 1368 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1369 if (!f) Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
1370 // Check if option "UPDATE" was preserved
1371 TString opt(option);
1372 opt.ToUpper();
1373 if ((opt=="UPDATE") && (opt!=f->GetOption()))
1374 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
1375 } else {
90a4b3ee 1376 if (cont->IsRegisterDataset()) {
1377 TString dset_name = filename;
3df030bb 1378 dset_name.ReplaceAll(".root", cont->GetTitle());
90a4b3ee 1379 dset_name.ReplaceAll(":","_");
1380 if (fDebug>1) printf("Booking dataset: %s\n", dset_name.Data());
1381 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dset_name.Data());
1382 } else {
1383 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
1384 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
1385 }
84fcd93f 1386 if (fDebug > 1) printf("=== %s\n", line.Data());
1387 gROOT->ProcessLine(line);
1388 line = Form("pf->OpenFile(\"%s\");", option);
1389 gROOT->ProcessLine(line);
1390 f = gFile;
1391 if (fDebug > 1) {
8d7d3b59 1392 gROOT->ProcessLine("pf->Print()");
84fcd93f 1393 printf(" == proof file name: %s", f->GetName());
1394 }
1395 // Add to proof output list
1396 line = Form("((TList*)0x%lx)->Add(pf);",(ULong_t)fSelector->GetOutputList());
90a4b3ee 1397 if (fDebug > 1) printf("=== %s\n", line.Data());
84fcd93f 1398 gROOT->ProcessLine(line);
1399 }
1400 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1401 cont->SetFile(f);
1402 // Cd to file
1403 f->cd();
1404 // Check for a folder request
1405 TString dir = cont->GetFolderName();
1406 if (!dir.IsNull()) {
1407 if (!f->GetDirectory(dir)) f->mkdir(dir);
1408 f->cd(dir);
1409 }
1410 return f;
1411 }
1412 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
1413 cont->SetFile(NULL);
1414 return NULL;
8d7d3b59 1415}
1416
1417//______________________________________________________________________________
d3106602 1418void AliAnalysisManager::ExecAnalysis(Option_t *option)
1419{
1420// Execute analysis.
8c0ab8e8 1421 static Long64_t ncalls = 0;
1422 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1423 if (getsysInfo && ncalls==0) AliSysInfo::AddStamp("Start", (Int_t)ncalls);
1424 ncalls++;
327eaf46 1425 if (!fInitOK) {
c52c2132 1426 Error("ExecAnalysis", "Analysis manager was not initialized !");
327eaf46 1427 return;
1428 }
d3106602 1429 AliAnalysisTask *task;
327eaf46 1430 // Check if the top tree is active.
1431 if (fTree) {
1432 TIter next(fTasks);
1433 // De-activate all tasks
1434 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
ce46ecc1 1435 AliAnalysisDataContainer *cont = fCommonInput;
1436 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
327eaf46 1437 if (!cont) {
c52c2132 1438 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
327eaf46 1439 return;
1440 }
1441 cont->SetData(fTree); // This will notify all consumers
ed97dc98 1442 Long64_t entry = fTree->GetTree()->GetReadEntry();
1443
6bb2b24f 1444//
c3701689 1445// Call BeginEvent() for optional input/output and MC services
ed97dc98 1446 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
1447 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
1448 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
6bb2b24f 1449//
1450// Execute the tasks
276941c8 1451// TIter next1(cont->GetConsumers());
1452 TIter next1(fTopTasks);
327eaf46 1453 while ((task=(AliAnalysisTask*)next1())) {
c52c2132 1454 if (fDebug >1) {
1455 cout << " Executing task " << task->GetName() << endl;
1456 }
6bb2b24f 1457
327eaf46 1458 task->ExecuteTask(option);
1459 }
6bb2b24f 1460//
1461// Call FinishEvent() for optional output and MC services
6073f8c9 1462 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
6bb2b24f 1463 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
1464 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
8c0ab8e8 1465 // Gather system information if requested
1466 if (getsysInfo && ((ncalls%fNSysInfo)==0))
1467 AliSysInfo::AddStamp(Form("Event#%lld",ncalls),(Int_t)ncalls);
327eaf46 1468 return;
1469 }
1470 // The event loop is not controlled by TSelector
6bb2b24f 1471//
c3701689 1472// Call BeginEvent() for optional input/output and MC services
ed97dc98 1473 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
1474 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
1475 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
327eaf46 1476 TIter next2(fTopTasks);
1477 while ((task=(AliAnalysisTask*)next2())) {
1478 task->SetActive(kTRUE);
c52c2132 1479 if (fDebug > 1) {
1480 cout << " Executing task " << task->GetName() << endl;
1481 }
d3106602 1482 task->ExecuteTask(option);
327eaf46 1483 }
6bb2b24f 1484//
1485// Call FinishEvent() for optional output and MC services
6073f8c9 1486 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
1487 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
6bb2b24f 1488 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
d3106602 1489}
1490
1491//______________________________________________________________________________
1492void AliAnalysisManager::FinishAnalysis()
1493{
1494// Finish analysis.
1495}
60a04972 1496
1497//______________________________________________________________________________
1498void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* handler)
1499{
1500// Set the input event handler and create a container for it.
1501 fInputEventHandler = handler;
d958c3ea 1502 fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
ce46ecc1 1503 Warning("SetInputEventHandler", " An automatic input container for the input chain was created.\nPlease use: mgr->GetCommonInputContainer() to access it.");
60a04972 1504}
1505
1506//______________________________________________________________________________
1507void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* handler)
1508{
1509// Set the input event handler and create a container for it.
1510 fOutputEventHandler = handler;
d958c3ea 1511 fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
673f68ff 1512 fCommonOutput->SetSpecialOutput();
ca316909 1513 Warning("SetOutputEventHandler", " An automatic output container for the output tree was created.\nPlease use: mgr->GetCommonOutputContainer() to access it.");
60a04972 1514}
c07b9ce2 1515
1516//______________________________________________________________________________
1517void AliAnalysisManager::RegisterExtraFile(const char *fname)
1518{
1519// This method is used externally to register output files which are not
1520// connected to any output container, so that the manager can properly register,
1521// retrieve or merge them when running in distributed mode. The file names are
1522// separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
1523 if (fExtraFiles.Length()) fExtraFiles += " ";
1524 fExtraFiles += fname;
1525}
1526
1527//______________________________________________________________________________
1528Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, TList *source)
1529{
1530// Copy a file from the location specified ina the wrapper with the same name from the source list.
1531 char full_path[512];
1532 char ch_url[512];
1533 TObject *pof = source->FindObject(filename);
1534 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
1535 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
1536 return kFALSE;
1537 }
1538 gROOT->ProcessLine(Form("sprintf((char*)0x%lx, \"%%s\", ((TProofOutputFile*)0x%lx)->GetOutputFileName();)", full_path, pof));
1539 gROOT->ProcessLine(Form("sprintf((char*)0x%lx, \"%%s\", gProof->GetUrl();)", ch_url));
1540 TString clientUrl(ch_url);
1541 TString full_path_str(full_path);
1542 if (clientUrl.Contains("localhost")){
1543 TObjArray* array = full_path_str.Tokenize ( "//" );
1544 TObjString *strobj = ( TObjString *)array->At(1);
1545 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
1546 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
1547 full_path_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
1548 full_path_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
1549 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",full_path_str.Data(),filename);
1550 delete arrayPort;
1551 delete array;
1552 }
1553 if (fDebug > 1)
1554 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space", full_path_str.Data());
1555 Bool_t gotit = TFile::Cp(full_path_str.Data(), filename);
1556 if (!gotit)
1557 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
1558 return gotit;
1559}
d29168d6 1560
1561//______________________________________________________________________________
1562void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
1563{
1564// Fill analysis type in the provided string.
1565 switch (fMode) {
1566 case kLocalAnalysis:
1567 type = "local";
1568 return;
1569 case kProofAnalysis:
1570 type = "proof";
1571 return;
1572 case kGridAnalysis:
1573 type = "grid";
1574 return;
1575 case kMixingAnalysis:
1576 type = "mix";
1577 }
1578}
923e2ca5 1579
1580//______________________________________________________________________________
1581Bool_t AliAnalysisManager::ValidateOutputFiles() const
1582{
1583// Validate all output files.
1584 TIter next(fOutputs);
1585 AliAnalysisDataContainer *output;
1586 TDirectory *cdir = gDirectory;
84fcd93f 1587 TString openedFiles;
923e2ca5 1588 while ((output=(AliAnalysisDataContainer*)next())) {
90a4b3ee 1589 if (output->IsRegisterDataset()) continue;
923e2ca5 1590 TString filename = output->GetFileName();
1591 if (filename == "default") {
1592 if (!fOutputEventHandler) continue;
1593 filename = fOutputEventHandler->GetOutputFileName();
1594 }
1595 // Check if the file is closed
84fcd93f 1596 if (openedFiles.Contains(filename)) continue;;
923e2ca5 1597 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1598 if (file) {
1599 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
1600 file->Close();
1601 }
1602 file = TFile::Open(filename);
1603 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
1604 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
1605 cdir->cd();
1606 return kFALSE;
1607 }
1608 file->Close();
84fcd93f 1609 openedFiles += filename;
1610 openedFiles += " ";
923e2ca5 1611 }
1612 cdir->cd();
1613 return kTRUE;
1614}