]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ANALYSIS/AliAnalysisManager.cxx
Modified file access mode
[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
c52c2132 30#include <TClass.h>
31#include <TFile.h>
32#include <TMethodCall.h>
33#include <TChain.h>
34#include <TSystem.h>
35#include <TROOT.h>
8c0ab8e8 36#include <TCanvas.h>
d3106602 37
8d7d3b59 38#include "AliAnalysisSelector.h"
d3106602 39#include "AliAnalysisTask.h"
40#include "AliAnalysisDataContainer.h"
41#include "AliAnalysisDataSlot.h"
d2f1d9ef 42#include "AliVEventHandler.h"
c2922515 43#include "AliVEventPool.h"
8c0ab8e8 44#include "AliSysInfo.h"
c52c2132 45#include "AliAnalysisManager.h"
d3106602 46
47ClassImp(AliAnalysisManager)
48
c52c2132 49AliAnalysisManager *AliAnalysisManager::fgAnalysisManager = NULL;
50
c52c2132 51//______________________________________________________________________________
52AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
53 :TNamed(name,title),
54 fTree(NULL),
8c0ab8e8 55 fInputEventHandler(NULL),
56 fOutputEventHandler(NULL),
57 fMCtruthEventHandler(NULL),
c2922515 58 fEventPool(NULL),
c52c2132 59 fCurrentEntry(-1),
8c0ab8e8 60 fNSysInfo(0),
c52c2132 61 fMode(kLocalAnalysis),
62 fInitOK(kFALSE),
63 fDebug(0),
26f071d8 64 fSpecialOutputLocation(""),
37a26056 65 fTasks(NULL),
66 fTopTasks(NULL),
c52c2132 67 fZombies(NULL),
68 fContainers(NULL),
69 fInputs(NULL),
8d7d3b59 70 fOutputs(NULL),
71 fSelector(NULL)
d3106602 72{
73// Default constructor.
c52c2132 74 fgAnalysisManager = this;
75 fTasks = new TObjArray();
76 fTopTasks = new TObjArray();
77 fZombies = new TObjArray();
78 fContainers = new TObjArray();
79 fInputs = new TObjArray();
37153431 80 fOutputs = new TObjArray();
b1310ef5 81 SetEventLoop(kTRUE);
d3106602 82}
83
84//______________________________________________________________________________
85AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
c52c2132 86 :TNamed(other),
327eaf46 87 fTree(NULL),
8c0ab8e8 88 fInputEventHandler(NULL),
89 fOutputEventHandler(NULL),
90 fMCtruthEventHandler(NULL),
c2922515 91 fEventPool(NULL),
c52c2132 92 fCurrentEntry(-1),
8c0ab8e8 93 fNSysInfo(0),
c52c2132 94 fMode(other.fMode),
95 fInitOK(other.fInitOK),
96 fDebug(other.fDebug),
26f071d8 97 fSpecialOutputLocation(""),
37a26056 98 fTasks(NULL),
99 fTopTasks(NULL),
c52c2132 100 fZombies(NULL),
101 fContainers(NULL),
102 fInputs(NULL),
8d7d3b59 103 fOutputs(NULL),
104 fSelector(NULL)
d3106602 105{
106// Copy constructor.
37a26056 107 fTasks = new TObjArray(*other.fTasks);
108 fTopTasks = new TObjArray(*other.fTopTasks);
109 fZombies = new TObjArray(*other.fZombies);
c52c2132 110 fContainers = new TObjArray(*other.fContainers);
111 fInputs = new TObjArray(*other.fInputs);
112 fOutputs = new TObjArray(*other.fOutputs);
113 fgAnalysisManager = this;
d3106602 114}
115
116//______________________________________________________________________________
117AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& other)
118{
119// Assignment
120 if (&other != this) {
c52c2132 121 TNamed::operator=(other);
54cff064 122 fInputEventHandler = other.fInputEventHandler;
6bb2b24f 123 fOutputEventHandler = other.fOutputEventHandler;
124 fMCtruthEventHandler = other.fMCtruthEventHandler;
c2922515 125 fEventPool = other.fEventPool;
c52c2132 126 fTree = NULL;
127 fCurrentEntry = -1;
8c0ab8e8 128 fNSysInfo = other.fNSysInfo;
c52c2132 129 fMode = other.fMode;
37a26056 130 fInitOK = other.fInitOK;
c52c2132 131 fDebug = other.fDebug;
37a26056 132 fTasks = new TObjArray(*other.fTasks);
133 fTopTasks = new TObjArray(*other.fTopTasks);
134 fZombies = new TObjArray(*other.fZombies);
c52c2132 135 fContainers = new TObjArray(*other.fContainers);
136 fInputs = new TObjArray(*other.fInputs);
137 fOutputs = new TObjArray(*other.fOutputs);
8d7d3b59 138 fSelector = NULL;
c52c2132 139 fgAnalysisManager = this;
d3106602 140 }
141 return *this;
142}
143
144//______________________________________________________________________________
145AliAnalysisManager::~AliAnalysisManager()
146{
147// Destructor.
d3106602 148 if (fTasks) {fTasks->Delete(); delete fTasks;}
149 if (fTopTasks) delete fTopTasks;
150 if (fZombies) delete fZombies;
c52c2132 151 if (fContainers) {fContainers->Delete(); delete fContainers;}
152 if (fInputs) delete fInputs;
153 if (fOutputs) delete fOutputs;
154 if (fgAnalysisManager==this) fgAnalysisManager = NULL;
d3106602 155}
c52c2132 156
d3106602 157//______________________________________________________________________________
327eaf46 158Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
159{
160// Read one entry of the tree or a whole branch.
8d7d3b59 161 if (fDebug > 0) printf("== AliAnalysisManager::GetEntry(%lld)\n", entry);
c52c2132 162 fCurrentEntry = entry;
327eaf46 163 return fTree ? fTree->GetTree()->GetEntry(entry, getall) : 0;
164}
165
166//______________________________________________________________________________
167void AliAnalysisManager::Init(TTree *tree)
d3106602 168{
169 // The Init() function is called when the selector needs to initialize
170 // a new tree or chain. Typically here the branch addresses of the tree
171 // will be set. It is normaly not necessary to make changes to the
172 // generated code, but the routine can be extended by the user if needed.
173 // Init() will be called many times when running with PROOF.
327eaf46 174 if (!tree) return;
8d7d3b59 175 if (fDebug > 0) {
176 printf("->AliAnalysisManager::Init(%s)\n", tree->GetName());
c52c2132 177 }
fdb458ec 178
f3d59a0d 179 // Call InitTree of EventHandler
36e82a52 180 if (fOutputEventHandler) {
181 if (fMode == kProofAnalysis) {
f3d59a0d 182 fOutputEventHandler->Init(0x0, "proof");
36e82a52 183 } else {
f3d59a0d 184 fOutputEventHandler->Init(0x0, "local");
36e82a52 185 }
186 }
187
fdb458ec 188 if (fInputEventHandler) {
36e82a52 189 if (fMode == kProofAnalysis) {
f3d59a0d 190 fInputEventHandler->Init(tree, "proof");
36e82a52 191 } else {
f3d59a0d 192 fInputEventHandler->Init(tree, "local");
36e82a52 193 }
e7ae3836 194 } else {
195 // If no input event handler we need to get the tree once
196 // for the chain
197 if(!tree->GetTree()) tree->LoadTree(0);
36e82a52 198 }
e7ae3836 199
36e82a52 200
201 if (fMCtruthEventHandler) {
202 if (fMode == kProofAnalysis) {
f3d59a0d 203 fMCtruthEventHandler->Init(0x0, "proof");
36e82a52 204 } else {
f3d59a0d 205 fMCtruthEventHandler->Init(0x0, "local");
36e82a52 206 }
fdb458ec 207 }
208
c52c2132 209 if (!fInitOK) InitAnalysis();
210 if (!fInitOK) return;
327eaf46 211 fTree = tree;
212 AliAnalysisDataContainer *top = (AliAnalysisDataContainer*)fInputs->At(0);
c52c2132 213 if (!top) {
8d7d3b59 214 Error("Init","No top input container !");
c52c2132 215 return;
37153431 216 }
327eaf46 217 top->SetData(tree);
8d7d3b59 218 if (fDebug > 0) {
981f2614 219 printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
220 }
d3106602 221}
222
d3106602 223//______________________________________________________________________________
327eaf46 224void AliAnalysisManager::SlaveBegin(TTree *tree)
d3106602 225{
226 // The SlaveBegin() function is called after the Begin() function.
227 // When running with PROOF SlaveBegin() is called on each slave server.
228 // The tree argument is deprecated (on PROOF 0 is passed).
8d7d3b59 229 if (fDebug > 0) printf("->AliAnalysisManager::SlaveBegin()\n");
aee5ee44 230 static Bool_t isCalled = kFALSE;
4ab472d4 231 TDirectory *curdir = gDirectory;
aee5ee44 232 // Call SlaveBegin only once in case of mixing
233 if (isCalled && fMode==kMixingAnalysis) return;
f3d59a0d 234 // Call Init of EventHandler
235 if (fOutputEventHandler) {
236 if (fMode == kProofAnalysis) {
4ab472d4 237 TIter nextout(fOutputs);
238 AliAnalysisDataContainer *c_aod;
239 while ((c_aod=(AliAnalysisDataContainer*)nextout())) if (!strcmp(c_aod->GetFileName(),"default")) break;
240 if (c_aod && c_aod->IsSpecialOutput()) {
241 // Merging via files
242 if (fDebug > 1) printf(" Initializing special output file %s...\n", fOutputEventHandler->GetOutputFileName());
243 OpenProofFile(fOutputEventHandler->GetOutputFileName(), "RECREATE");
244 c_aod->SetFile(gFile);
245 fOutputEventHandler->Init("proofspecial");
246 } else {
247 // Merging in memory
248 fOutputEventHandler->Init("proof");
249 }
f3d59a0d 250 } else {
251 fOutputEventHandler->Init("local");
252 }
253 }
254
255 if (fInputEventHandler) {
256 fInputEventHandler->SetInputTree(tree);
257 if (fMode == kProofAnalysis) {
258 fInputEventHandler->Init("proof");
259 } else {
260 fInputEventHandler->Init("local");
261 }
262 }
263
264 if (fMCtruthEventHandler) {
265 if (fMode == kProofAnalysis) {
266 fMCtruthEventHandler->Init("proof");
267 } else {
268 fMCtruthEventHandler->Init("local");
269 }
270 }
4ab472d4 271 if (curdir) curdir->cd();
272
c52c2132 273 TIter next(fTasks);
274 AliAnalysisTask *task;
275 // Call CreateOutputObjects for all tasks
c5a87c56 276 while ((task=(AliAnalysisTask*)next())) {
4ab472d4 277 curdir = gDirectory;
c52c2132 278 task->CreateOutputObjects();
c5a87c56 279 if (curdir) curdir->cd();
36e82a52 280 }
aee5ee44 281 isCalled = kTRUE;
36e82a52 282
8d7d3b59 283 if (fDebug > 0) printf("<-AliAnalysisManager::SlaveBegin()\n");
d3106602 284}
285
286//______________________________________________________________________________
327eaf46 287Bool_t AliAnalysisManager::Notify()
288{
289 // The Notify() function is called when a new file is opened. This
290 // can be either for a new TTree in a TChain or when when a new TTree
291 // is started when using PROOF. It is normaly not necessary to make changes
292 // to the generated code, but the routine can be extended by the
293 // user if needed. The return value is currently not used.
8d7d3b59 294 if (!fTree) {
295 Error("Notify","No current tree.");
296 return kFALSE;
297 }
298 TFile *curfile = fTree->GetCurrentFile();
299 if (!curfile) {
300 Error("Notify","No current file");
301 return kFALSE;
302 }
303
304 if (fDebug > 0) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
305 TIter next(fTasks);
306 AliAnalysisTask *task;
307 // Call Notify for all tasks
308 while ((task=(AliAnalysisTask*)next()))
309 task->Notify();
fdb458ec 310
8d7d3b59 311 // Call Notify of the event handlers
312 if (fInputEventHandler) {
313 fInputEventHandler->Notify(curfile->GetName());
314 }
6073f8c9 315
8d7d3b59 316 if (fOutputEventHandler) {
317 fOutputEventHandler->Notify(curfile->GetName());
318 }
890126ab 319
8d7d3b59 320 if (fMCtruthEventHandler) {
321 fMCtruthEventHandler->Notify(curfile->GetName());
322 }
323 if (fDebug > 0) printf("<-AliAnalysisManager::Notify()\n");
324 return kTRUE;
327eaf46 325}
326
327//______________________________________________________________________________
328Bool_t AliAnalysisManager::Process(Long64_t entry)
d3106602 329{
330 // The Process() function is called for each entry in the tree (or possibly
331 // keyed object in the case of PROOF) to be processed. The entry argument
332 // specifies which entry in the currently loaded tree is to be processed.
333 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
334 // to read either all or the required parts of the data. When processing
335 // keyed objects with PROOF, the object is already loaded and is available
336 // via the fObject pointer.
337 //
338 // This function should contain the "body" of the analysis. It can contain
339 // simple or elaborate selection criteria, run algorithms on the data
340 // of the event and typically fill histograms.
341
342 // WARNING when a selector is used with a TChain, you must use
343 // the pointer to the current TTree to call GetEntry(entry).
344 // The entry is always the local entry number in the current tree.
345 // Assuming that fChain is the pointer to the TChain being processed,
346 // use fChain->GetTree()->GetEntry(entry).
8d7d3b59 347 if (fDebug > 0) printf("->AliAnalysisManager::Process(%lld)\n", entry);
348
ed97dc98 349 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
350 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
351 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
6bb2b24f 352
327eaf46 353 GetEntry(entry);
354 ExecAnalysis();
8d7d3b59 355 if (fDebug > 0) printf("<-AliAnalysisManager::Process()\n");
327eaf46 356 return kTRUE;
d3106602 357}
358
359//______________________________________________________________________________
c52c2132 360void AliAnalysisManager::PackOutput(TList *target)
d3106602 361{
981f2614 362 // Pack all output data containers in the output list. Called at SlaveTerminate
363 // stage in PROOF case for each slave.
8d7d3b59 364 if (fDebug > 0) printf("->AliAnalysisManager::PackOutput()\n");
c52c2132 365 if (!target) {
366 Error("PackOutput", "No target. Aborting.");
367 return;
37153431 368 }
6073f8c9 369 if (fInputEventHandler) fInputEventHandler ->Terminate();
6bb2b24f 370 if (fOutputEventHandler) fOutputEventHandler ->Terminate();
371 if (fMCtruthEventHandler) fMCtruthEventHandler->Terminate();
8d7d3b59 372
373 // Call FinishTaskOutput() for each event loop task (not called for
374 // post-event loop tasks - use Terminate() fo those)
375 TIter nexttask(fTasks);
376 AliAnalysisTask *task;
377 while ((task=(AliAnalysisTask*)nexttask())) {
378 if (!task->IsPostEventLoop()) {
379 if (fDebug > 0) printf("->FinishTaskOutput: task %s\n", task->GetName());
380 task->FinishTaskOutput();
381 if (fDebug > 0) printf("<-FinishTaskOutput: task %s\n", task->GetName());
382 }
383 }
8c9485b2 384
c52c2132 385 if (fMode == kProofAnalysis) {
386 TIter next(fOutputs);
387 AliAnalysisDataContainer *output;
4ab472d4 388 Bool_t isManagedByHandler = kFALSE;
c52c2132 389 while ((output=(AliAnalysisDataContainer*)next())) {
8d7d3b59 390 // Do not consider outputs of post event loop tasks
2b83ca27 391 isManagedByHandler = kFALSE;
8d7d3b59 392 if (output->GetProducer()->IsPostEventLoop()) continue;
4ab472d4 393 const char *filename = output->GetFileName();
394 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
395 isManagedByHandler = kTRUE;
396 filename = fOutputEventHandler->GetOutputFileName();
397 }
8d7d3b59 398 // Check if data was posted to this container. If not, issue an error.
4ab472d4 399 if (!output->GetData() && !isManagedByHandler) {
8d7d3b59 400 Error("PackOutput", "No data for output container %s. Forgot to PostData ?\n", output->GetName());
401 continue;
402 }
403 if (!output->IsSpecialOutput()) {
404 // Normal outputs
4ab472d4 405 if (strlen(filename) && !isManagedByHandler) {
406 // File resident outputs
8d7d3b59 407 TFile *file = output->GetFile();
408 // Backup current folder
ca78991b 409 TDirectory *opwd = gDirectory;
8d7d3b59 410 // Create file if not existing and register to container.
ca78991b 411 if (file) file->cd();
8d7d3b59 412 else file = new TFile(filename, "RECREATE");
413 if (file->IsZombie()) {
414 Fatal("PackOutput", "Could not recreate file %s\n", filename);
415 return;
416 }
417 output->SetFile(file);
ca78991b 418 // Clear file list to release object ownership to user.
ca78991b 419 file->Clear();
8d7d3b59 420 // Save data to file, then close.
1be433fc 421 if (output->GetData()->InheritsFrom(TCollection::Class())) {
422 // If data is a collection, we set the name of the collection
423 // as the one of the container and we save as a single key.
424 TCollection *coll = (TCollection*)output->GetData();
425 coll->SetName(output->GetName());
426 coll->Write(output->GetName(), TObject::kSingleKey);
427 } else {
cbc8747a 428 if (output->GetData()->InheritsFrom(TTree::Class())) {
429 TTree *tree = (TTree*)output->GetData();
430 tree->SetDirectory(file);
431 tree->AutoSave();
432 } else {
433 output->GetData()->Write();
434 }
1be433fc 435 }
8d7d3b59 436 if (fDebug > 1) printf("PackOutput %s: memory merge, file resident output\n", output->GetName());
437 if (fDebug > 2) {
438 printf(" file %s listing content:\n", filename);
439 file->ls();
440 }
ca78991b 441 file->Close();
ca78991b 442 // Restore current directory
443 if (opwd) opwd->cd();
8d7d3b59 444 } else {
445 // Memory-resident outputs
4ab472d4 446 if (fDebug > 1) printf("PackOutput %s: memory merge memory resident output\n", filename);
447 }
448 AliAnalysisDataWrapper *wrap = 0;
449 if (isManagedByHandler) {
450 wrap = new AliAnalysisDataWrapper(fOutputEventHandler->GetTree());
451 wrap->SetName(output->GetName());
ca78991b 452 }
4ab472d4 453 else wrap =output->ExportData();
cbc8747a 454 // Output wrappers must NOT delete data after merging - the user owns them
455 wrap->SetDeleteData(kFALSE);
8167b1d0 456 target->Add(wrap);
4ab472d4 457 } else {
8d7d3b59 458 // Special outputs
d0864eb4 459 TDirectory *opwd = gDirectory;
8d7d3b59 460 TFile *file = output->GetFile();
802f90ef 461 if (fDebug > 1 && file) printf("PackOutput %s: file merge, special output\n", output->GetName());
4ab472d4 462 if (isManagedByHandler) {
463 // Terminate IO for files managed by the output handler
464 if (file) file->Write();
802f90ef 465 if (file && fDebug > 2) {
466 printf(" handled file %s listing content:\n", file->GetName());
467 file->ls();
468 }
4ab472d4 469 fOutputEventHandler->TerminateIO();
470 continue;
471 }
472
8d7d3b59 473 if (!file) {
474 AliAnalysisTask *producer = output->GetProducer();
475 Error("PackOutput",
476 "File %s for special container %s was NOT opened in %s::CreateOutputObjects !!!",
477 output->GetFileName(), output->GetName(), producer->ClassName());
478 continue;
479 }
ef788aee 480 file->cd();
8d7d3b59 481 // Release object ownership to users after writing data to file
1be433fc 482 if (output->GetData()->InheritsFrom(TCollection::Class())) {
483 // If data is a collection, we set the name of the collection
484 // as the one of the container and we save as a single key.
485 TCollection *coll = (TCollection*)output->GetData();
486 coll->SetName(output->GetName());
487 coll->Write(output->GetName(), TObject::kSingleKey);
488 } else {
cbc8747a 489 if (output->GetData()->InheritsFrom(TTree::Class())) {
490 TTree *tree = (TTree*)output->GetData();
491 tree->SetDirectory(file);
492 tree->AutoSave();
493 } else {
494 output->GetData()->Write();
495 }
1be433fc 496 }
8d7d3b59 497 file->Clear();
498 if (fDebug > 2) {
499 printf(" file %s listing content:\n", output->GetFileName());
500 file->ls();
501 }
13ef3bb0 502 file->Close();
8d7d3b59 503 // Restore current directory
d0864eb4 504 if (opwd) opwd->cd();
8d7d3b59 505 // Check if a special output location was provided or the output files have to be merged
13ef3bb0 506 if (strlen(fSpecialOutputLocation.Data())) {
507 TString remote = fSpecialOutputLocation;
508 remote += "/";
ef788aee 509 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
d0864eb4 510 remote += Form("%s_%d_", gSystem->HostName(), gid);
13ef3bb0 511 remote += output->GetFileName();
512 TFile::Cp(output->GetFileName(), remote.Data());
ca78991b 513 } else {
8d7d3b59 514 // No special location specified-> use TProofOutputFile as merging utility
515 // The file at this output slot must be opened in CreateOutputObjects
516 if (fDebug > 1) printf(" File %s to be merged...\n", output->GetFileName());
13ef3bb0 517 }
518 }
c52c2132 519 }
520 }
8d7d3b59 521 if (fDebug > 0) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
c52c2132 522}
523
524//______________________________________________________________________________
981f2614 525void AliAnalysisManager::ImportWrappers(TList *source)
c52c2132 526{
981f2614 527// Import data in output containers from wrappers coming in source.
8d7d3b59 528 if (fDebug > 0) printf("->AliAnalysisManager::ImportWrappers()\n");
327eaf46 529 TIter next(fOutputs);
981f2614 530 AliAnalysisDataContainer *cont;
531 AliAnalysisDataWrapper *wrap;
532 Int_t icont = 0;
c52c2132 533 while ((cont=(AliAnalysisDataContainer*)next())) {
0355fc48 534 wrap = 0;
8d7d3b59 535 if (cont->GetProducer()->IsPostEventLoop()) continue;
4ab472d4 536 const char *filename = cont->GetFileName();
537 Bool_t isManagedByHandler = kFALSE;
538 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
539 isManagedByHandler = kTRUE;
540 filename = fOutputEventHandler->GetOutputFileName();
541 }
8d7d3b59 542 if (cont->IsSpecialOutput()) {
4ab472d4 543 if (strlen(fSpecialOutputLocation.Data()) && !isManagedByHandler) continue;
8d7d3b59 544 // Copy merged file from PROOF scratch space
4ab472d4 545 char full_path[512];
546 TObject *pof = source->FindObject(filename);
547 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
548 Error("ImportWrappers", "TProofOutputFile object not found in output list for container %s", cont->GetName());
549 continue;
550 }
551 gROOT->ProcessLine(Form("sprintf((char*)0x%lx, \"%%s\", ((TProofOutputFile*)0x%lx)->GetOutputFileName();)", full_path, pof));
8d7d3b59 552 if (fDebug > 1)
4ab472d4 553 printf(" Copying file %s from PROOF scratch space\n", full_path);
554 Bool_t gotit = TFile::Cp(full_path, filename);
8d7d3b59 555 if (!gotit) {
556 Error("ImportWrappers", "Could not get file %s from proof scratch space", cont->GetFileName());
557 }
558 // Normally we should connect data from the copied file to the
559 // corresponding output container, but it is not obvious how to do this
560 // automatically if several objects in file...
4ab472d4 561 TFile *f = new TFile(filename, "READ");
802f90ef 562 TObject *obj = 0;
563 if (!isManagedByHandler) obj = f->Get(cont->GetName());
564 if (!obj && !isManagedByHandler) {
4ab472d4 565 Error("ImportWrappers", "Could not find object %s in file %s", cont->GetName(), filename);
0355fc48 566 continue;
567 }
568 wrap = new AliAnalysisDataWrapper(obj);
569 wrap->SetDeleteData(kFALSE);
8d7d3b59 570 }
0355fc48 571 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
8d7d3b59 572 if (!wrap) {
573 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
c52c2132 574 continue;
575 }
981f2614 576 icont++;
8d7d3b59 577 if (fDebug > 1) {
578 printf(" Importing data for container %s", cont->GetName());
4ab472d4 579 if (strlen(filename)) printf(" -> file %s\n", cont->GetFileName());
8d7d3b59 580 else printf("\n");
581 }
981f2614 582 cont->ImportData(wrap);
c52c2132 583 }
8d7d3b59 584 if (fDebug > 0) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
c52c2132 585}
586
587//______________________________________________________________________________
588void AliAnalysisManager::UnpackOutput(TList *source)
589{
ca78991b 590 // Called by AliAnalysisSelector::Terminate only on the client.
8d7d3b59 591 if (fDebug > 0) printf("->AliAnalysisManager::UnpackOutput()\n");
c52c2132 592 if (!source) {
981f2614 593 Error("UnpackOutput", "No target. Aborting.");
c52c2132 594 return;
595 }
8d7d3b59 596 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
c52c2132 597
981f2614 598 if (fMode == kProofAnalysis) ImportWrappers(source);
37153431 599
981f2614 600 TIter next(fOutputs);
c52c2132 601 AliAnalysisDataContainer *output;
602 while ((output=(AliAnalysisDataContainer*)next())) {
c52c2132 603 if (!output->GetData()) continue;
b1310ef5 604 // Check if there are client tasks that run post event loop
605 if (output->HasConsumers()) {
606 // Disable event loop semaphore
607 output->SetPostEventLoop(kTRUE);
608 TObjArray *list = output->GetConsumers();
609 Int_t ncons = list->GetEntriesFast();
610 for (Int_t i=0; i<ncons; i++) {
611 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
612 task->CheckNotify(kTRUE);
613 // If task is active, execute it
614 if (task->IsPostEventLoop() && task->IsActive()) {
8d7d3b59 615 if (fDebug > 0) printf("== Executing post event loop task %s\n", task->GetName());
b1310ef5 616 task->ExecuteTask();
617 }
618 }
619 }
c52c2132 620 }
8d7d3b59 621 if (fDebug > 0) printf("<-AliAnalysisManager::UnpackOutput()\n");
d3106602 622}
623
624//______________________________________________________________________________
625void AliAnalysisManager::Terminate()
626{
627 // The Terminate() function is the last function to be called during
628 // a query. It always runs on the client, it can be used to present
c52c2132 629 // the results graphically.
8d7d3b59 630 if (fDebug > 0) printf("->AliAnalysisManager::Terminate()\n");
327eaf46 631 AliAnalysisTask *task;
c52c2132 632 TIter next(fTasks);
327eaf46 633 // Call Terminate() for tasks
c52c2132 634 while ((task=(AliAnalysisTask*)next())) task->Terminate();
8c9485b2 635 //
8c0ab8e8 636 TIter next1(fOutputs);
637 AliAnalysisDataContainer *output;
638 while ((output=(AliAnalysisDataContainer*)next1())) {
1be433fc 639 // Special outputs have the files already closed and written.
640 if (output->IsSpecialOutput()) continue;
8c0ab8e8 641 const char *filename = output->GetFileName();
642 if (!(strcmp(filename, "default"))) {
643 if (fOutputEventHandler) filename = fOutputEventHandler->GetOutputFileName();
1be433fc 644 TFile *aodfile = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
645 if (aodfile) {
646 if (fDebug > 1) printf("Writing output handler file: %s\n", filename);
647 aodfile->Write();
648 continue;
649 }
8d7d3b59 650 }
651 if (!strlen(filename)) continue;
1be433fc 652 if (!output->GetData()) continue;
8d7d3b59 653 TFile *file = output->GetFile();
654 TDirectory *opwd = gDirectory;
8e6e6fe8 655 file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
656 if (!file) file = new TFile(filename, "RECREATE");
657 if (file->IsZombie()) continue;
658 output->SetFile(file);
659 file->cd();
8d7d3b59 660 if (fDebug > 1) printf(" writing output data %s to file %s\n", output->GetData()->GetName(), file->GetName());
1be433fc 661 if (output->GetData()->InheritsFrom(TCollection::Class())) {
662 // If data is a collection, we set the name of the collection
663 // as the one of the container and we save as a single key.
664 TCollection *coll = (TCollection*)output->GetData();
665 coll->SetName(output->GetName());
666 coll->Write(output->GetName(), TObject::kSingleKey);
667 } else {
cbc8747a 668 if (output->GetData()->InheritsFrom(TTree::Class())) {
669 TTree *tree = (TTree*)output->GetData();
670 tree->SetDirectory(file);
671 tree->AutoSave();
672 } else {
673 output->GetData()->Write();
674 }
1be433fc 675 }
8e6e6fe8 676 if (opwd) opwd->cd();
677 }
678 next1.Reset();
679 while ((output=(AliAnalysisDataContainer*)next1())) {
680 // Close all files at output
681 TDirectory *opwd = gDirectory;
682 if (output->GetFile()) output->GetFile()->Close();
8d7d3b59 683 if (opwd) opwd->cd();
8c0ab8e8 684 }
685
1be433fc 686 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
687 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
688 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
689
8c0ab8e8 690 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
691 if (getsysInfo) {
692 TDirectory *cdir = gDirectory;
693 TFile f("syswatch.root", "RECREATE");
694 if (!f.IsZombie()) {
695 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
696 tree->SetMarkerStyle(kCircle);
697 tree->SetMarkerColor(kBlue);
698 tree->SetMarkerSize(0.5);
699 if (!gROOT->IsBatch()) {
700 tree->SetAlias("event", "id0");
29cbcef8 701 tree->SetAlias("memUSED", "pI.fMemVirtual");
8c0ab8e8 702 tree->SetAlias("userCPU", "pI.fCpuUser");
703 TCanvas *c = new TCanvas("SysInfo","SysInfo",10,10,800,600);
704 c->Divide(2,1,0.01,0.01);
705 c->cd(1);
706 tree->Draw("memUSED:event","","", 1234567890, 0);
707 c->cd(2);
708 tree->Draw("userCPU:event","","", 1234567890, 0);
709 }
710 tree->Write();
711 f.Close();
712 delete tree;
713 }
714 if (cdir) cdir->cd();
715 }
8d7d3b59 716 if (fDebug > 0) printf("<-AliAnalysisManager::Terminate()\n");
d3106602 717}
718
719//______________________________________________________________________________
720void AliAnalysisManager::AddTask(AliAnalysisTask *task)
721{
722// Adds a user task to the global list of tasks.
8d7d3b59 723 if (fTasks->FindObject(task)) {
724 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
725 return;
726 }
d3106602 727 task->SetActive(kFALSE);
728 fTasks->Add(task);
729}
730
731//______________________________________________________________________________
732AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
733{
734// Retreive task by name.
735 if (!fTasks) return NULL;
736 return (AliAnalysisTask*)fTasks->FindObject(name);
737}
738
739//______________________________________________________________________________
740AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
c52c2132 741 TClass *datatype, EAliAnalysisContType type, const char *filename)
d3106602 742{
743// Create a data container of a certain type. Types can be:
c52c2132 744// kExchangeContainer = 0, used to exchange date between tasks
d3106602 745// kInputContainer = 1, used to store input data
746// kOutputContainer = 2, used for posting results
b1310ef5 747 if (fContainers->FindObject(name)) {
748 Error("CreateContainer","A container named %s already defined !\n",name);
749 return NULL;
750 }
d3106602 751 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
752 fContainers->Add(cont);
753 switch (type) {
754 case kInputContainer:
755 fInputs->Add(cont);
756 break;
757 case kOutputContainer:
758 fOutputs->Add(cont);
8c0ab8e8 759 if (filename && strlen(filename)) {
760 cont->SetFileName(filename);
761 cont->SetDataOwned(kFALSE); // data owned by the file
762 }
d3106602 763 break;
c52c2132 764 case kExchangeContainer:
d3106602 765 break;
766 }
767 return cont;
768}
769
770//______________________________________________________________________________
771Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
772 AliAnalysisDataContainer *cont)
773{
774// Connect input of an existing task to a data container.
775 if (!fTasks->FindObject(task)) {
776 AddTask(task);
8d7d3b59 777 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
d3106602 778 }
779 Bool_t connected = task->ConnectInput(islot, cont);
780 return connected;
781}
782
783//______________________________________________________________________________
784Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
785 AliAnalysisDataContainer *cont)
786{
787// Connect output of an existing task to a data container.
788 if (!fTasks->FindObject(task)) {
789 AddTask(task);
c52c2132 790 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
d3106602 791 }
792 Bool_t connected = task->ConnectOutput(islot, cont);
793 return connected;
794}
795
796//______________________________________________________________________________
797void AliAnalysisManager::CleanContainers()
798{
799// Clean data from all containers that have already finished all client tasks.
800 TIter next(fContainers);
801 AliAnalysisDataContainer *cont;
802 while ((cont=(AliAnalysisDataContainer *)next())) {
803 if (cont->IsOwnedData() &&
804 cont->IsDataReady() &&
805 cont->ClientsExecuted()) cont->DeleteData();
806 }
807}
808
809//______________________________________________________________________________
810Bool_t AliAnalysisManager::InitAnalysis()
811{
812// Initialization of analysis chain of tasks. Should be called after all tasks
813// and data containers are properly connected
814 // Check for input/output containers
815 fInitOK = kFALSE;
d3106602 816 // Check for top tasks (depending only on input data containers)
817 if (!fTasks->First()) {
c52c2132 818 Error("InitAnalysis", "Analysis has no tasks !");
d3106602 819 return kFALSE;
820 }
821 TIter next(fTasks);
822 AliAnalysisTask *task;
823 AliAnalysisDataContainer *cont;
824 Int_t ntop = 0;
825 Int_t nzombies = 0;
327eaf46 826 Bool_t iszombie = kFALSE;
827 Bool_t istop = kTRUE;
d3106602 828 Int_t i;
829 while ((task=(AliAnalysisTask*)next())) {
327eaf46 830 istop = kTRUE;
831 iszombie = kFALSE;
d3106602 832 Int_t ninputs = task->GetNinputs();
d3106602 833 for (i=0; i<ninputs; i++) {
834 cont = task->GetInputSlot(i)->GetContainer();
835 if (!cont) {
327eaf46 836 if (!iszombie) {
d3106602 837 task->SetZombie();
838 fZombies->Add(task);
839 nzombies++;
327eaf46 840 iszombie = kTRUE;
d3106602 841 }
c52c2132 842 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
843 i, task->GetName());
d3106602 844 }
327eaf46 845 if (iszombie) continue;
d3106602 846 // Check if cont is an input container
327eaf46 847 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
d3106602 848 // Connect to parent task
849 }
327eaf46 850 if (istop) {
d3106602 851 ntop++;
852 fTopTasks->Add(task);
853 }
854 }
855 if (!ntop) {
c52c2132 856 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
d3106602 857 return kFALSE;
858 }
859 // Check now if there are orphan tasks
860 for (i=0; i<ntop; i++) {
861 task = (AliAnalysisTask*)fTopTasks->At(i);
862 task->SetUsed();
863 }
864 Int_t norphans = 0;
865 next.Reset();
866 while ((task=(AliAnalysisTask*)next())) {
867 if (!task->IsUsed()) {
868 norphans++;
c52c2132 869 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
d3106602 870 }
871 }
872 // Check the task hierarchy (no parent task should depend on data provided
873 // by a daughter task)
874 for (i=0; i<ntop; i++) {
875 task = (AliAnalysisTask*)fTopTasks->At(i);
876 if (task->CheckCircularDeps()) {
c52c2132 877 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
d3106602 878 PrintStatus("dep");
879 return kFALSE;
880 }
881 }
b1310ef5 882 // Check that all containers feeding post-event loop tasks are in the outputs list
883 TIter nextcont(fContainers); // loop over all containers
884 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
885 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
886 if (cont->HasConsumers()) {
887 // Check if one of the consumers is post event loop
888 TIter nextconsumer(cont->GetConsumers());
889 while ((task=(AliAnalysisTask*)nextconsumer())) {
890 if (task->IsPostEventLoop()) {
891 fOutputs->Add(cont);
892 break;
893 }
894 }
895 }
896 }
897 }
8d7d3b59 898 // Check if all special output containers have a file name provided
899 TIter nextout(fOutputs);
900 while ((cont=(AliAnalysisDataContainer*)nextout())) {
901 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
902 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
903 return kFALSE;
904 }
905 }
327eaf46 906 fInitOK = kTRUE;
d3106602 907 return kTRUE;
908}
909
910//______________________________________________________________________________
911void AliAnalysisManager::PrintStatus(Option_t *option) const
912{
913// Print task hierarchy.
8c0ab8e8 914 if (!fInitOK) {
915 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
916 return;
917 }
918 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
919 if (getsysInfo)
920 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
d3106602 921 TIter next(fTopTasks);
922 AliAnalysisTask *task;
923 while ((task=(AliAnalysisTask*)next()))
924 task->PrintTask(option);
925}
926
927//______________________________________________________________________________
928void AliAnalysisManager::ResetAnalysis()
929{
930// Reset all execution flags and clean containers.
931 CleanContainers();
932}
933
c52c2132 934//______________________________________________________________________________
8c0ab8e8 935void AliAnalysisManager::StartAnalysis(const char *type, TTree *tree, Long64_t nentries, Long64_t firstentry)
c52c2132 936{
aee5ee44 937// Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
938// MIX. Process nentries starting from firstentry
c52c2132 939 if (!fInitOK) {
940 Error("StartAnalysis","Analysis manager was not initialized !");
941 return;
942 }
8d7d3b59 943 if (fDebug > 0) printf("StartAnalysis %s\n",GetName());
c52c2132 944 TString anaType = type;
945 anaType.ToLower();
946 fMode = kLocalAnalysis;
4ab472d4 947 if (anaType.Contains("proof")) fMode = kProofAnalysis;
948 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
949 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
950
c52c2132 951 if (fMode == kGridAnalysis) {
952 Warning("StartAnalysis", "GRID analysis mode not implemented. Running local.");
981f2614 953 fMode = kLocalAnalysis;
954 }
d86ed856 955 char line[256];
efd53803 956 SetEventLoop(kFALSE);
8d7d3b59 957 // Enable event loop mode if a tree was provided
aee5ee44 958 if (tree || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
efd53803 959
8c0ab8e8 960 TChain *chain = 0;
961 TString ttype = "TTree";
4ab472d4 962 if (tree && tree->IsA() == TChain::Class()) {
8c0ab8e8 963 chain = (TChain*)tree;
6b742510 964 if (!chain || !chain->GetListOfFiles()->First()) {
965 Error("StartAnalysis", "Cannot process null or empty chain...");
966 return;
967 }
8c0ab8e8 968 ttype = "TChain";
969 }
9b33830a 970
aee5ee44 971 // Initialize locally all tasks (happens for all modes)
9b33830a 972 TIter next(fTasks);
973 AliAnalysisTask *task;
efd53803 974 while ((task=(AliAnalysisTask*)next())) {
efd53803 975 task->LocalInit();
976 }
977
c52c2132 978 switch (fMode) {
979 case kLocalAnalysis:
980 if (!tree) {
03a5cc9f 981 TIter nextT(fTasks);
981f2614 982 // Call CreateOutputObjects for all tasks
03a5cc9f 983 while ((task=(AliAnalysisTask*)nextT())) {
c5a87c56 984 TDirectory *curdir = gDirectory;
985 task->CreateOutputObjects();
986 if (curdir) curdir->cd();
987 }
c52c2132 988 ExecAnalysis();
981f2614 989 Terminate();
c52c2132 990 return;
991 }
992 // Run tree-based analysis via AliAnalysisSelector
c52c2132 993 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
aee5ee44 994 fSelector = new AliAnalysisSelector(this);
995 tree->Process(fSelector, "", nentries, firstentry);
c52c2132 996 break;
997 case kProofAnalysis:
998 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
999 printf("StartAnalysis: no PROOF!!!\n");
1000 return;
1001 }
1002 sprintf(line, "gProof->AddInput((TObject*)0x%lx);", (ULong_t)this);
1003 gROOT->ProcessLine(line);
1004 if (chain) {
1005 chain->SetProof();
1006 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
8c0ab8e8 1007 chain->Process("AliAnalysisSelector", "", nentries, firstentry);
c52c2132 1008 } else {
1009 printf("StartAnalysis: no chain\n");
1010 return;
1011 }
1012 break;
1013 case kGridAnalysis:
1014 Warning("StartAnalysis", "GRID analysis mode not implemented. Running local.");
aee5ee44 1015 break;
1016 case kMixingAnalysis:
1017 // Run event mixing analysis
1018 if (!fEventPool) {
1019 Error("StartAnalysis", "Cannot run event mixing without event pool");
1020 return;
1021 }
1022 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1023 fSelector = new AliAnalysisSelector(this);
aee5ee44 1024 while ((chain=fEventPool->GetNextChain())) {
d1e79f9e 1025 next.Reset();
aee5ee44 1026 // Call NotifyBinChange for all tasks
1027 while ((task=(AliAnalysisTask*)next()))
1028 if (!task->IsPostEventLoop()) task->NotifyBinChange();
1029 chain->Process(fSelector);
1030 }
1031 PackOutput(fSelector->GetOutputList());
1032 Terminate();
c52c2132 1033 }
1034}
1035
d86ed856 1036//______________________________________________________________________________
1037void AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
1038{
1039// Start analysis for this manager on a given dataset. Analysis task can be:
1040// LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1041 if (!fInitOK) {
1042 Error("StartAnalysis","Analysis manager was not initialized !");
1043 return;
1044 }
8d7d3b59 1045 if (fDebug > 0) printf("StartAnalysis %s\n",GetName());
d86ed856 1046 TString anaType = type;
1047 anaType.ToLower();
1048 if (!anaType.Contains("proof")) {
d140f7fb 1049 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
d86ed856 1050 return;
1051 }
1052 fMode = kProofAnalysis;
1053 char line[256];
1054 SetEventLoop(kTRUE);
1055 // Set the dataset flag
1056 TObject::SetBit(kUseDataSet);
1057 fTree = 0;
1058
1059 // Initialize locally all tasks
1060 TIter next(fTasks);
1061 AliAnalysisTask *task;
1062 while ((task=(AliAnalysisTask*)next())) {
1063 task->LocalInit();
1064 }
1065
1066 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1067 printf("StartAnalysis: no PROOF!!!\n");
1068 return;
1069 }
1070 sprintf(line, "gProof->AddInput((TObject*)0x%lx);", (ULong_t)this);
1071 gROOT->ProcessLine(line);
1072 sprintf(line, "gProof->GetDataSet(\"%s\");", dataset);
1073 if (!gROOT->ProcessLine(line)) {
1074 Error("StartAnalysis", "Dataset %s not found", dataset);
1075 return;
1076 }
1077 sprintf(line, "gProof->Process(\"%s\", \"AliAnalysisSelector\", \"\", %lld, %lld);",
1078 dataset, nentries, firstentry);
1079 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
1080 gROOT->ProcessLine(line);
1081}
1082
d3106602 1083//______________________________________________________________________________
8d7d3b59 1084TFile *AliAnalysisManager::OpenProofFile(const char *filename, const char *option)
1085{
1086// Opens a special output file used in PROOF.
1087 char line[256];
1088 if (fMode!=kProofAnalysis || !fSelector) {
1089 Error("OpenProofFile","Cannot open PROOF file %s",filename);
1090 return NULL;
1091 }
1092 sprintf(line, "TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename);
1093 if (fDebug > 1) printf("=== %s\n", line);
1094 gROOT->ProcessLine(line);
1095 sprintf(line, "pf->OpenFile(\"%s\");", option);
1096 gROOT->ProcessLine(line);
1097 if (fDebug > 1) {
1098 gROOT->ProcessLine("pf->Print()");
1099 printf(" == proof file name: %s\n", gFile->GetName());
1100 }
1101 sprintf(line, "((TList*)0x%lx)->Add(pf);",(ULong_t)fSelector->GetOutputList());
1102 if (fDebug > 1) printf("=== %s\n", line);
1103 gROOT->ProcessLine(line);
1104 return gFile;
1105}
1106
1107//______________________________________________________________________________
d3106602 1108void AliAnalysisManager::ExecAnalysis(Option_t *option)
1109{
1110// Execute analysis.
8c0ab8e8 1111 static Long64_t ncalls = 0;
1112 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1113 if (getsysInfo && ncalls==0) AliSysInfo::AddStamp("Start", (Int_t)ncalls);
1114 ncalls++;
327eaf46 1115 if (!fInitOK) {
c52c2132 1116 Error("ExecAnalysis", "Analysis manager was not initialized !");
327eaf46 1117 return;
1118 }
d3106602 1119 AliAnalysisTask *task;
327eaf46 1120 // Check if the top tree is active.
1121 if (fTree) {
1122 TIter next(fTasks);
1123 // De-activate all tasks
1124 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
1125 AliAnalysisDataContainer *cont = (AliAnalysisDataContainer*)fInputs->At(0);
1126 if (!cont) {
c52c2132 1127 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
327eaf46 1128 return;
1129 }
1130 cont->SetData(fTree); // This will notify all consumers
ed97dc98 1131 Long64_t entry = fTree->GetTree()->GetReadEntry();
1132
6bb2b24f 1133//
c3701689 1134// Call BeginEvent() for optional input/output and MC services
ed97dc98 1135 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
1136 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
1137 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
6bb2b24f 1138//
1139// Execute the tasks
276941c8 1140// TIter next1(cont->GetConsumers());
1141 TIter next1(fTopTasks);
327eaf46 1142 while ((task=(AliAnalysisTask*)next1())) {
c52c2132 1143 if (fDebug >1) {
1144 cout << " Executing task " << task->GetName() << endl;
1145 }
6bb2b24f 1146
327eaf46 1147 task->ExecuteTask(option);
1148 }
6bb2b24f 1149//
1150// Call FinishEvent() for optional output and MC services
6073f8c9 1151 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
6bb2b24f 1152 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
1153 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
8c0ab8e8 1154 // Gather system information if requested
1155 if (getsysInfo && ((ncalls%fNSysInfo)==0))
1156 AliSysInfo::AddStamp(Form("Event#%lld",ncalls),(Int_t)ncalls);
327eaf46 1157 return;
1158 }
1159 // The event loop is not controlled by TSelector
6bb2b24f 1160//
c3701689 1161// Call BeginEvent() for optional input/output and MC services
ed97dc98 1162 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
1163 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
1164 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
327eaf46 1165 TIter next2(fTopTasks);
1166 while ((task=(AliAnalysisTask*)next2())) {
1167 task->SetActive(kTRUE);
c52c2132 1168 if (fDebug > 1) {
1169 cout << " Executing task " << task->GetName() << endl;
1170 }
d3106602 1171 task->ExecuteTask(option);
327eaf46 1172 }
6bb2b24f 1173//
1174// Call FinishEvent() for optional output and MC services
6073f8c9 1175 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
1176 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
6bb2b24f 1177 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
d3106602 1178}
1179
1180//______________________________________________________________________________
1181void AliAnalysisManager::FinishAnalysis()
1182{
1183// Finish analysis.
1184}