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