fix calculation versus multiplicity
[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();");
f5e61abd 610 if (remote.BeginsWith("alien://")) {
611 gROOT->ProcessLine("TGrid::Connect(\"alien://pcapiserv01.cern.ch:10000\", gProofServ->GetUser());");
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//______________________________________________________________________________
61505f8b 1329Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree, Long64_t nentries, Long64_t firstentry)
c52c2132 1330{
aee5ee44 1331// Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1332// MIX. Process nentries starting from firstentry
bf574918 1333 Long64_t retv = 0;
57756ec5 1334 // Backup current directory and make sure gDirectory points to gROOT
1335 TDirectory *cdir = gDirectory;
1336 gROOT->cd();
c52c2132 1337 if (!fInitOK) {
1338 Error("StartAnalysis","Analysis manager was not initialized !");
57756ec5 1339 cdir->cd();
1f87e9fb 1340 return -1;
c52c2132 1341 }
cd463514 1342 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
8e1f0465 1343 fIsRemote = kFALSE;
c52c2132 1344 TString anaType = type;
1345 anaType.ToLower();
1346 fMode = kLocalAnalysis;
c57f56b7 1347 Bool_t runlocalinit = kTRUE;
90a4b3ee 1348 if (anaType.Contains("file")) {
1349 runlocalinit = kFALSE;
8e1f0465 1350 fIsRemote = kTRUE;
90a4b3ee 1351 }
4ab472d4 1352 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1353 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1354 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1355
c52c2132 1356 if (fMode == kGridAnalysis) {
8e1f0465 1357 fIsRemote = kTRUE;
f866cba5 1358 if (!anaType.Contains("terminate")) {
1359 if (!fGridHandler) {
1360 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1361 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
57756ec5 1362 cdir->cd();
f866cba5 1363 return -1;
1364 }
1365 // Write analysis manager in the analysis file
1366 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1367 // run local task configuration
1368 TIter nextTask(fTasks);
1369 AliAnalysisTask *task;
1370 while ((task=(AliAnalysisTask*)nextTask())) {
1371 task->LocalInit();
57756ec5 1372 gROOT->cd();
f866cba5 1373 }
1374 if (!fGridHandler->StartAnalysis(nentries, firstentry)) {
1375 Info("StartAnalysis", "Grid analysis was stopped and cannot be terminated");
57756ec5 1376 cdir->cd();
f866cba5 1377 return -1;
1378 }
c57f56b7 1379
f866cba5 1380 // Terminate grid analysis
57756ec5 1381 if (fSelector && fSelector->GetStatus() == -1) {cdir->cd(); return -1;}
1382 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) {cdir->cd(); return 0;}
f866cba5 1383 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1384 if (!fGridHandler->MergeOutputs()) {
1385 // Return if outputs could not be merged or if it alien handler
1386 // was configured for offline mode or local testing.
57756ec5 1387 cdir->cd();
f866cba5 1388 return 0;
1389 }
1390 }
1391 cout << "===== TERMINATING GRID ANALYSIS JOB: " << GetName() << endl;
c57f56b7 1392 ImportWrappers(NULL);
1393 Terminate();
57756ec5 1394 cdir->cd();
1f87e9fb 1395 return 0;
981f2614 1396 }
ab5d25d8 1397 TString line;
efd53803 1398 SetEventLoop(kFALSE);
8d7d3b59 1399 // Enable event loop mode if a tree was provided
aee5ee44 1400 if (tree || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
efd53803 1401
8c0ab8e8 1402 TChain *chain = 0;
1403 TString ttype = "TTree";
4ab472d4 1404 if (tree && tree->IsA() == TChain::Class()) {
8c0ab8e8 1405 chain = (TChain*)tree;
6b742510 1406 if (!chain || !chain->GetListOfFiles()->First()) {
1407 Error("StartAnalysis", "Cannot process null or empty chain...");
57756ec5 1408 cdir->cd();
1f87e9fb 1409 return -1;
6b742510 1410 }
8c0ab8e8 1411 ttype = "TChain";
1412 }
9b33830a 1413
096b5a2e 1414 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1415 if (getsysInfo) AliSysInfo::AddStamp("Start", 0);
aee5ee44 1416 // Initialize locally all tasks (happens for all modes)
9b33830a 1417 TIter next(fTasks);
1418 AliAnalysisTask *task;
c57f56b7 1419 if (runlocalinit) {
1420 while ((task=(AliAnalysisTask*)next())) {
1421 task->LocalInit();
57756ec5 1422 gROOT->cd();
c57f56b7 1423 }
096b5a2e 1424 if (getsysInfo) AliSysInfo::AddStamp("LocalInit_all", 0);
c57f56b7 1425 }
efd53803 1426
c52c2132 1427 switch (fMode) {
1428 case kLocalAnalysis:
1429 if (!tree) {
03a5cc9f 1430 TIter nextT(fTasks);
981f2614 1431 // Call CreateOutputObjects for all tasks
096b5a2e 1432 Int_t itask = 0;
979e448a 1433 Bool_t dirStatus = TH1::AddDirectoryStatus();
03a5cc9f 1434 while ((task=(AliAnalysisTask*)nextT())) {
979e448a 1435 TH1::AddDirectory(kFALSE);
c5a87c56 1436 task->CreateOutputObjects();
096b5a2e 1437 if (getsysInfo) AliSysInfo::AddStamp(Form("%s_CREATEOUTOBJ",task->ClassName()), 0, itask, 0);
57756ec5 1438 gROOT->cd();
096b5a2e 1439 itask++;
c5a87c56 1440 }
979e448a 1441 TH1::AddDirectory(dirStatus);
06a59280 1442 if (IsExternalLoop()) {
1443 Info("StartAnalysis", "Initialization done. Event loop is controlled externally.\
1444 \nSetData for top container, call ExecAnalysis in a loop and then Terminate manually");
1f87e9fb 1445 return 0;
57756ec5 1446 }
c52c2132 1447 ExecAnalysis();
981f2614 1448 Terminate();
1f87e9fb 1449 return 0;
c52c2132 1450 }
1451 // Run tree-based analysis via AliAnalysisSelector
c52c2132 1452 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
aee5ee44 1453 fSelector = new AliAnalysisSelector(this);
bf574918 1454 retv = tree->Process(fSelector, "", nentries, firstentry);
c52c2132 1455 break;
1456 case kProofAnalysis:
8e1f0465 1457 fIsRemote = kTRUE;
c52c2132 1458 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
61505f8b 1459 Error("StartAnalysis", "No PROOF!!! Exiting.");
57756ec5 1460 cdir->cd();
1f87e9fb 1461 return -1;
c52c2132 1462 }
ab5d25d8 1463 line = Form("gProof->AddInput((TObject*)0x%lx);", (ULong_t)this);
c52c2132 1464 gROOT->ProcessLine(line);
1465 if (chain) {
1466 chain->SetProof();
1467 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
bf574918 1468 retv = chain->Process("AliAnalysisSelector", "", nentries, firstentry);
c52c2132 1469 } else {
61505f8b 1470 Error("StartAnalysis", "No chain!!! Exiting.");
57756ec5 1471 cdir->cd();
1f87e9fb 1472 return -1;
c52c2132 1473 }
1474 break;
1475 case kGridAnalysis:
1476 Warning("StartAnalysis", "GRID analysis mode not implemented. Running local.");
aee5ee44 1477 break;
1478 case kMixingAnalysis:
1479 // Run event mixing analysis
1480 if (!fEventPool) {
1481 Error("StartAnalysis", "Cannot run event mixing without event pool");
57756ec5 1482 cdir->cd();
1f87e9fb 1483 return -1;
aee5ee44 1484 }
1485 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1486 fSelector = new AliAnalysisSelector(this);
aee5ee44 1487 while ((chain=fEventPool->GetNextChain())) {
d1e79f9e 1488 next.Reset();
aee5ee44 1489 // Call NotifyBinChange for all tasks
1490 while ((task=(AliAnalysisTask*)next()))
1491 if (!task->IsPostEventLoop()) task->NotifyBinChange();
bf574918 1492 retv = chain->Process(fSelector);
1493 if (retv < 0) {
1494 Error("StartAnalysis", "Mixing analysis failed");
57756ec5 1495 cdir->cd();
bf574918 1496 return retv;
1497 }
aee5ee44 1498 }
1499 PackOutput(fSelector->GetOutputList());
1500 Terminate();
1f87e9fb 1501 }
57756ec5 1502 cdir->cd();
bf574918 1503 return retv;
c52c2132 1504}
1505
1506//______________________________________________________________________________
1f87e9fb 1507Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
d86ed856 1508{
1509// Start analysis for this manager on a given dataset. Analysis task can be:
1510// LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1511 if (!fInitOK) {
1512 Error("StartAnalysis","Analysis manager was not initialized !");
1f87e9fb 1513 return -1;
d86ed856 1514 }
8e1f0465 1515 fIsRemote = kTRUE;
cd463514 1516 if (fDebug > 1) printf("StartAnalysis %s\n",GetName());
d86ed856 1517 TString anaType = type;
1518 anaType.ToLower();
1519 if (!anaType.Contains("proof")) {
d140f7fb 1520 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
1f87e9fb 1521 return -1;
d86ed856 1522 }
1523 fMode = kProofAnalysis;
ab5d25d8 1524 TString line;
d86ed856 1525 SetEventLoop(kTRUE);
1526 // Set the dataset flag
1527 TObject::SetBit(kUseDataSet);
1528 fTree = 0;
1529
1530 // Initialize locally all tasks
1531 TIter next(fTasks);
1532 AliAnalysisTask *task;
1533 while ((task=(AliAnalysisTask*)next())) {
1534 task->LocalInit();
1535 }
1536
1537 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
61505f8b 1538 Error("StartAnalysis", "No PROOF!!! Exiting.");
1f87e9fb 1539 return -1;
d86ed856 1540 }
ab5d25d8 1541 line = Form("gProof->AddInput((TObject*)0x%lx);", (ULong_t)this);
d86ed856 1542 gROOT->ProcessLine(line);
bc649bfe 1543// sprintf(line, "gProof->GetDataSet(\"%s\");", dataset);
1544// if (!gROOT->ProcessLine(line)) {
1545// Error("StartAnalysis", "Dataset %s not found", dataset);
1546// return -1;
1547// }
ab5d25d8 1548 line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"\", %lld, %lld);",
d86ed856 1549 dataset, nentries, firstentry);
1550 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
bf574918 1551 Long_t retv = (Long_t)gROOT->ProcessLine(line);
1552 return retv;
d86ed856 1553}
1554
1555//______________________________________________________________________________
84fcd93f 1556TFile *AliAnalysisManager::OpenFile(AliAnalysisDataContainer *cont, const char *option, Bool_t ignoreProof)
1557{
1558// Opens according the option the file specified by cont->GetFileName() and changes
1559// current directory to cont->GetFolderName(). If the file was already opened, it
1560// checks if the option UPDATE was preserved. File open via TProofOutputFile can
1561// be optionally ignored.
1562 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1563 TString filename = cont->GetFileName();
1564 TFile *f = NULL;
1565 if (filename.IsNull()) {
1566 ::Error("AliAnalysisManager::OpenFile", "No file name specified for container %s", cont->GetName());
1567 return NULL;
1568 }
1569 if (mgr->GetAnalysisType()==AliAnalysisManager::kProofAnalysis && cont->IsSpecialOutput()
1570 && !ignoreProof)
1571 f = mgr->OpenProofFile(cont,option);
1572 else {
1573 // Check first if the file is already opened
0f1b50f3 1574 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
84fcd93f 1575 if (f) {
1576 // Check if option "UPDATE" was preserved
1577 TString opt(option);
1578 opt.ToUpper();
1579 if ((opt=="UPDATE") && (opt!=f->GetOption()))
e85311b4 1580 ::Info("AliAnalysisManager::OpenFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
84fcd93f 1581 } else {
0f1b50f3 1582 f = TFile::Open(filename, option);
84fcd93f 1583 }
1584 }
1585 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1586 cont->SetFile(f);
1587 // Cd to file
1588 f->cd();
1589 // Check for a folder request
1590 TString dir = cont->GetFolderName();
1591 if (!dir.IsNull()) {
1592 if (!f->GetDirectory(dir)) f->mkdir(dir);
1593 f->cd(dir);
1594 }
1595 return f;
1596 }
1597 ::Fatal("AliAnalysisManager::OpenFile", "File %s could not be opened", filename.Data());
1598 cont->SetFile(NULL);
1599 return NULL;
1600}
1601
1602//______________________________________________________________________________
1603TFile *AliAnalysisManager::OpenProofFile(AliAnalysisDataContainer *cont, const char *option)
8d7d3b59 1604{
1605// Opens a special output file used in PROOF.
84fcd93f 1606 TString line;
1607 TString filename = cont->GetFileName();
23c9468b 1608 if (cont == fCommonOutput) {
1609 if (fOutputEventHandler) filename = fOutputEventHandler->GetOutputFileName();
61505f8b 1610 else Fatal("OpenProofFile","No output container. Exiting.");
23c9468b 1611 }
84fcd93f 1612 TFile *f = NULL;
1613 if (fMode!=kProofAnalysis || !fSelector) {
1614 Fatal("OpenProofFile","Cannot open PROOF file %s: no PROOF or selector",filename.Data());
1615 return NULL;
1616 }
1617 if (fSpecialOutputLocation.Length()) {
1618 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1619 if (f) {
1620 // Check if option "UPDATE" was preserved
1621 TString opt(option);
1622 opt.ToUpper();
23c9468b 1623 if ((opt=="UPDATE") && (opt!=f->GetOption()))
e85311b4 1624 ::Info("OpenProofFile", "File %s already opened in %s mode!", cont->GetFileName(), f->GetOption());
84fcd93f 1625 } else {
1626 f = new TFile(filename, option);
1627 }
1628 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1629 cont->SetFile(f);
1630 // Cd to file
1631 f->cd();
1632 // Check for a folder request
1633 TString dir = cont->GetFolderName();
1634 if (dir.Length()) {
1635 if (!f->GetDirectory(dir)) f->mkdir(dir);
1636 f->cd(dir);
1637 }
f5e61abd 1638 return f;
84fcd93f 1639 }
1640 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
1641 cont->SetFile(NULL);
1642 return NULL;
1643 }
1644 // Check if there is already a proof output file in the output list
1645 TObject *pof = fSelector->GetOutputList()->FindObject(filename);
1646 if (pof) {
1647 // Get the actual file
1648 line = Form("((TProofOutputFile*)0x%lx)->GetFileName();", (ULong_t)pof);
1649 filename = (const char*)gROOT->ProcessLine(line);
90a4b3ee 1650 if (fDebug>1) {
1651 printf("File: %s already booked via TProofOutputFile\n", filename.Data());
1652 }
84fcd93f 1653 f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
ab5d25d8 1654 if (!f) {
1655 Fatal("OpenProofFile", "Proof output file found but no file opened for %s", filename.Data());
1656 return NULL;
1657 }
84fcd93f 1658 // Check if option "UPDATE" was preserved
1659 TString opt(option);
1660 opt.ToUpper();
1661 if ((opt=="UPDATE") && (opt!=f->GetOption()))
1662 Fatal("OpenProofFile", "File %s already opened, but not in UPDATE mode!", cont->GetFileName());
1663 } else {
90a4b3ee 1664 if (cont->IsRegisterDataset()) {
61505f8b 1665 TString dsetName = filename;
1666 dsetName.ReplaceAll(".root", cont->GetTitle());
1667 dsetName.ReplaceAll(":","_");
1668 if (fDebug>1) printf("Booking dataset: %s\n", dsetName.Data());
1669 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\", \"DROV\", \"%s\");", filename.Data(), dsetName.Data());
90a4b3ee 1670 } else {
1671 if (fDebug>1) printf("Booking TProofOutputFile: %s to be merged\n", filename.Data());
1672 line = Form("TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename.Data());
1673 }
84fcd93f 1674 if (fDebug > 1) printf("=== %s\n", line.Data());
1675 gROOT->ProcessLine(line);
1676 line = Form("pf->OpenFile(\"%s\");", option);
1677 gROOT->ProcessLine(line);
1678 f = gFile;
1679 if (fDebug > 1) {
8d7d3b59 1680 gROOT->ProcessLine("pf->Print()");
84fcd93f 1681 printf(" == proof file name: %s", f->GetName());
1682 }
1683 // Add to proof output list
1684 line = Form("((TList*)0x%lx)->Add(pf);",(ULong_t)fSelector->GetOutputList());
90a4b3ee 1685 if (fDebug > 1) printf("=== %s\n", line.Data());
84fcd93f 1686 gROOT->ProcessLine(line);
1687 }
1688 if (f && !f->IsZombie() && !f->TestBit(TFile::kRecovered)) {
1689 cont->SetFile(f);
1690 // Cd to file
1691 f->cd();
1692 // Check for a folder request
1693 TString dir = cont->GetFolderName();
1694 if (!dir.IsNull()) {
1695 if (!f->GetDirectory(dir)) f->mkdir(dir);
1696 f->cd(dir);
1697 }
1698 return f;
1699 }
1700 Fatal("OpenProofFile", "File %s could not be opened", cont->GetFileName());
1701 cont->SetFile(NULL);
1702 return NULL;
8d7d3b59 1703}
1704
1705//______________________________________________________________________________
d3106602 1706void AliAnalysisManager::ExecAnalysis(Option_t *option)
1707{
1708// Execute analysis.
8c0ab8e8 1709 static Long64_t ncalls = 0;
cd463514 1710 static Long64_t nentries = 0;
1f04b637 1711 static TTree *lastTree = 0;
cd463514 1712 static TStopwatch *timer = new TStopwatch();
096b5a2e 1713 if (fDebug > 0) printf("MGR: Processing event #%lld\n", ncalls);
cd463514 1714 else {
1f04b637 1715 if (fTree && (fTree != lastTree)) {
1716 nentries += fTree->GetEntries();
1717 lastTree = fTree;
1718 }
cd463514 1719 if (!ncalls) timer->Start();
ff0d33e8 1720 if (!fIsRemote && TObject::TestBit(kUseProgressBar)) ProgressBar("Processing event", ncalls, nentries, timer, kFALSE);
cd463514 1721 }
57756ec5 1722 gROOT->cd();
cd463514 1723 TDirectory *cdir = gDirectory;
8c0ab8e8 1724 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
096b5a2e 1725 if (getsysInfo && ((ncalls%fNSysInfo)==0)) AliSysInfo::AddStamp("Exec_start", (Int_t)ncalls);
8c0ab8e8 1726 ncalls++;
327eaf46 1727 if (!fInitOK) {
57756ec5 1728 Error("ExecAnalysis", "Analysis manager was not initialized !");
1729 cdir->cd();
327eaf46 1730 return;
57756ec5 1731 }
d3106602 1732 AliAnalysisTask *task;
327eaf46 1733 // Check if the top tree is active.
1734 if (fTree) {
a8bc7397 1735 if (getsysInfo && ((ncalls%fNSysInfo)==0))
1736 AliSysInfo::AddStamp("Handlers_BeginEventGroup",(Int_t)ncalls, 1002, 0);
327eaf46 1737 TIter next(fTasks);
1738 // De-activate all tasks
1739 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
ce46ecc1 1740 AliAnalysisDataContainer *cont = fCommonInput;
1741 if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
327eaf46 1742 if (!cont) {
c52c2132 1743 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
57756ec5 1744 cdir->cd();
327eaf46 1745 return;
1746 }
1747 cont->SetData(fTree); // This will notify all consumers
57756ec5 1748 Long64_t entry = fTree->GetTree()->GetReadEntry();
6bb2b24f 1749//
c3701689 1750// Call BeginEvent() for optional input/output and MC services
ed97dc98 1751 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
1752 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
1753 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
57756ec5 1754 gROOT->cd();
096b5a2e 1755 if (getsysInfo && ((ncalls%fNSysInfo)==0))
1756 AliSysInfo::AddStamp("Handlers_BeginEvent",(Int_t)ncalls, 1000, 0);
6bb2b24f 1757//
1758// Execute the tasks
276941c8 1759// TIter next1(cont->GetConsumers());
1760 TIter next1(fTopTasks);
096b5a2e 1761 Int_t itask = 0;
327eaf46 1762 while ((task=(AliAnalysisTask*)next1())) {
c52c2132 1763 if (fDebug >1) {
1764 cout << " Executing task " << task->GetName() << endl;
096b5a2e 1765 }
327eaf46 1766 task->ExecuteTask(option);
57756ec5 1767 gROOT->cd();
096b5a2e 1768 if (getsysInfo && ((ncalls%fNSysInfo)==0))
1769 AliSysInfo::AddStamp(task->ClassName(),(Int_t)ncalls, itask, 1);
1770 itask++;
327eaf46 1771 }
6bb2b24f 1772//
1773// Call FinishEvent() for optional output and MC services
6073f8c9 1774 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
6bb2b24f 1775 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
1776 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
8c0ab8e8 1777 // Gather system information if requested
1778 if (getsysInfo && ((ncalls%fNSysInfo)==0))
a8bc7397 1779 AliSysInfo::AddStamp("Handlers_FinishEvent",(Int_t)ncalls, 1001, 1);
57756ec5 1780 cdir->cd();
327eaf46 1781 return;
1782 }
1783 // The event loop is not controlled by TSelector
6bb2b24f 1784//
c3701689 1785// Call BeginEvent() for optional input/output and MC services
ed97dc98 1786 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
1787 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
1788 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
57756ec5 1789 gROOT->cd();
096b5a2e 1790 if (getsysInfo && ((ncalls%fNSysInfo)==0))
1791 AliSysInfo::AddStamp("Handlers_BeginEvent",(Int_t)ncalls, 1000, 0);
327eaf46 1792 TIter next2(fTopTasks);
1793 while ((task=(AliAnalysisTask*)next2())) {
1794 task->SetActive(kTRUE);
c52c2132 1795 if (fDebug > 1) {
1796 cout << " Executing task " << task->GetName() << endl;
1797 }
d3106602 1798 task->ExecuteTask(option);
57756ec5 1799 gROOT->cd();
327eaf46 1800 }
6bb2b24f 1801//
1802// Call FinishEvent() for optional output and MC services
6073f8c9 1803 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
1804 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
6bb2b24f 1805 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
096b5a2e 1806 if (getsysInfo && ((ncalls%fNSysInfo)==0))
1807 AliSysInfo::AddStamp("Handlers_FinishEvent",(Int_t)ncalls, 1000, 1);
57756ec5 1808 cdir->cd();
d3106602 1809}
1810
1811//______________________________________________________________________________
61505f8b 1812void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
60a04972 1813{
1814// Set the input event handler and create a container for it.
1815 fInputEventHandler = handler;
d958c3ea 1816 fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
ff92d2b1 1817// Warning("SetInputEventHandler", " An automatic input container for the input chain was created.\nPlease use: mgr->GetCommonInputContainer() to access it.");
60a04972 1818}
1819
1820//______________________________________________________________________________
61505f8b 1821void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
60a04972 1822{
1823// Set the input event handler and create a container for it.
1824 fOutputEventHandler = handler;
d958c3ea 1825 fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
673f68ff 1826 fCommonOutput->SetSpecialOutput();
ff92d2b1 1827// Warning("SetOutputEventHandler", " An automatic output container for the output tree was created.\nPlease use: mgr->GetCommonOutputContainer() to access it.");
60a04972 1828}
c07b9ce2 1829
1830//______________________________________________________________________________
1831void AliAnalysisManager::RegisterExtraFile(const char *fname)
1832{
1833// This method is used externally to register output files which are not
1834// connected to any output container, so that the manager can properly register,
1835// retrieve or merge them when running in distributed mode. The file names are
1836// separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
5b9b4998 1837 if (fExtraFiles.Contains(fname)) return;
c07b9ce2 1838 if (fExtraFiles.Length()) fExtraFiles += " ";
1839 fExtraFiles += fname;
1840}
1841
1842//______________________________________________________________________________
61505f8b 1843Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
c07b9ce2 1844{
1845// Copy a file from the location specified ina the wrapper with the same name from the source list.
61505f8b 1846 char fullPath[512];
1847 char chUrl[512];
c07b9ce2 1848 TObject *pof = source->FindObject(filename);
1849 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
1850 Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
1851 return kFALSE;
1852 }
343691a5 1853 gROOT->ProcessLine(Form("sprintf((char*)0x%lx, \"%%s\", ((TProofOutputFile*)0x%lx)->GetOutputFileName();)", (ULong_t)fullPath, (ULong_t)pof));
1854 gROOT->ProcessLine(Form("sprintf((char*)0x%lx, \"%%s\", gProof->GetUrl();)", (ULong_t)chUrl));
61505f8b 1855 TString clientUrl(chUrl);
1856 TString fullPath_str(fullPath);
c07b9ce2 1857 if (clientUrl.Contains("localhost")){
61505f8b 1858 TObjArray* array = fullPath_str.Tokenize ( "//" );
c07b9ce2 1859 TObjString *strobj = ( TObjString *)array->At(1);
1860 TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
1861 TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
61505f8b 1862 fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
1863 fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
1864 if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
c07b9ce2 1865 delete arrayPort;
1866 delete array;
1867 }
1868 if (fDebug > 1)
61505f8b 1869 Info("GetFileFromWrapper","Copying file %s from PROOF scratch space", fullPath_str.Data());
1870 Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
c07b9ce2 1871 if (!gotit)
1872 Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
1873 return gotit;
1874}
d29168d6 1875
1876//______________________________________________________________________________
1877void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
1878{
1879// Fill analysis type in the provided string.
1880 switch (fMode) {
1881 case kLocalAnalysis:
1882 type = "local";
1883 return;
1884 case kProofAnalysis:
1885 type = "proof";
1886 return;
1887 case kGridAnalysis:
1888 type = "grid";
1889 return;
1890 case kMixingAnalysis:
1891 type = "mix";
1892 }
1893}
923e2ca5 1894
1895//______________________________________________________________________________
1896Bool_t AliAnalysisManager::ValidateOutputFiles() const
1897{
1898// Validate all output files.
1899 TIter next(fOutputs);
1900 AliAnalysisDataContainer *output;
1901 TDirectory *cdir = gDirectory;
84fcd93f 1902 TString openedFiles;
923e2ca5 1903 while ((output=(AliAnalysisDataContainer*)next())) {
90a4b3ee 1904 if (output->IsRegisterDataset()) continue;
923e2ca5 1905 TString filename = output->GetFileName();
1906 if (filename == "default") {
1907 if (!fOutputEventHandler) continue;
1908 filename = fOutputEventHandler->GetOutputFileName();
b3685485 1909 // Main AOD may not be there
1910 if (gSystem->AccessPathName(filename)) continue;
923e2ca5 1911 }
1912 // Check if the file is closed
84fcd93f 1913 if (openedFiles.Contains(filename)) continue;;
923e2ca5 1914 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
1915 if (file) {
1916 Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
f3c07fbd 1917 // Clear file list to release object ownership to user.
160e7161 1918// file->Clear();
923e2ca5 1919 file->Close();
1920 }
1921 file = TFile::Open(filename);
1922 if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
1923 Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
1924 cdir->cd();
1925 return kFALSE;
1926 }
1927 file->Close();
84fcd93f 1928 openedFiles += filename;
1929 openedFiles += " ";
923e2ca5 1930 }
1931 cdir->cd();
1932 return kTRUE;
1933}
cd11251e 1934
1935//______________________________________________________________________________
61505f8b 1936void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
cd11251e 1937{
1938// Implements a nice text mode progress bar.
1939 static Long64_t icount = 0;
1940 static TString oname;
1941 static TString nname;
1942 static Long64_t ocurrent = 0;
1943 static Long64_t osize = 0;
1944 static Int_t oseconds = 0;
1945 static TStopwatch *owatch = 0;
1946 static Bool_t oneoftwo = kFALSE;
1947 static Int_t nrefresh = 0;
1948 static Int_t nchecks = 0;
1949 const char symbol[4] = {'=','\\','|','/'};
1950 char progress[11] = " ";
1951 Int_t ichar = icount%4;
1952
1953 if (!refresh) {
1954 nrefresh = 0;
1955 if (!size) return;
1956 owatch = watch;
1957 oname = opname;
1958 ocurrent = TMath::Abs(current);
1959 osize = TMath::Abs(size);
1960 if (ocurrent > osize) ocurrent=osize;
1961 } else {
1962 nrefresh++;
1963 if (!osize) return;
1964 }
1965 icount++;
1966 Double_t time = 0.;
1967 Int_t hours = 0;
1968 Int_t minutes = 0;
1969 Int_t seconds = 0;
1970 if (owatch && !last) {
1971 owatch->Stop();
1972 time = owatch->RealTime();
1973 hours = (Int_t)(time/3600.);
1974 time -= 3600*hours;
1975 minutes = (Int_t)(time/60.);
1976 time -= 60*minutes;
1977 seconds = (Int_t)time;
1978 if (refresh) {
1979 if (oseconds==seconds) {
1980 owatch->Continue();
1981 return;
1982 }
1983 oneoftwo = !oneoftwo;
1984 }
1985 oseconds = seconds;
1986 }
1987 if (refresh && oneoftwo) {
1988 nname = oname;
1989 if (nchecks <= 0) nchecks = nrefresh+1;
1990 Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
1991 oname = Form(" == %d%% ==", pctdone);
1992 }
1993 Double_t percent = 100.0*ocurrent/osize;
1994 Int_t nchar = Int_t(percent/10);
1995 if (nchar>10) nchar=10;
1996 Int_t i;
1997 for (i=0; i<nchar; i++) progress[i] = '=';
1998 progress[nchar] = symbol[ichar];
1999 for (i=nchar+1; i<10; i++) progress[i] = ' ';
2000 progress[10] = '\0';
2001 oname += " ";
2002 oname.Remove(20);
2003 if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
2004 else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
2005 else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
2006 if (time>0.) fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d \r", percent, hours, minutes, seconds);
2007 else fprintf(stderr, "[%6.2f %%]\r", percent);
2008 if (refresh && oneoftwo) oname = nname;
2009 if (owatch) owatch->Continue();
2010 if (last) {
2011 icount = 0;
2012 owatch = 0;
2013 ocurrent = 0;
2014 osize = 0;
2015 oseconds = 0;
2016 oneoftwo = kFALSE;
2017 nrefresh = 0;
2018 fprintf(stderr, "\n");
2019 }
2020}
012e169c 2021
2022//______________________________________________________________________________
2023void AliAnalysisManager::DoLoadBranch(const char *name)
2024{
2025 // Get tree and load branch if needed.
2026
2027 if (!fTree)
2028 return;
2029
2030 TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
2031 if (!br) {
2032 br = fTree->GetBranch(name);
2033 if (!br) {
979e448a 2034 Error("DoLoadBranch", "Could not find branch %s",name);
012e169c 2035 return;
2036 }
2037 fTable.Add(br);
2038 }
2039 if (br->GetReadEntry()==GetCurrentEntry())
2040 return;
2041 br->GetEntry(GetCurrentEntry());
2042}