minor
[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
d3106602 51//______________________________________________________________________________
c52c2132 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
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();
ef73322e 501 }
502 TString outFilename = file->GetName();
13ef3bb0 503 file->Close();
8d7d3b59 504 // Restore current directory
d0864eb4 505 if (opwd) opwd->cd();
8d7d3b59 506 // Check if a special output location was provided or the output files have to be merged
13ef3bb0 507 if (strlen(fSpecialOutputLocation.Data())) {
508 TString remote = fSpecialOutputLocation;
509 remote += "/";
ef788aee 510 Int_t gid = gROOT->ProcessLine("gProofServ->GetGroupId();");
d0864eb4 511 remote += Form("%s_%d_", gSystem->HostName(), gid);
13ef3bb0 512 remote += output->GetFileName();
ef73322e 513 TFile::Cp ( outFilename.Data(), remote.Data() );
ca78991b 514 } else {
8d7d3b59 515 // No special location specified-> use TProofOutputFile as merging utility
516 // The file at this output slot must be opened in CreateOutputObjects
517 if (fDebug > 1) printf(" File %s to be merged...\n", output->GetFileName());
13ef3bb0 518 }
519 }
c52c2132 520 }
521 }
8d7d3b59 522 if (fDebug > 0) printf("<-AliAnalysisManager::PackOutput: output list contains %d containers\n", target->GetSize());
c52c2132 523}
524
525//______________________________________________________________________________
981f2614 526void AliAnalysisManager::ImportWrappers(TList *source)
c52c2132 527{
981f2614 528// Import data in output containers from wrappers coming in source.
8d7d3b59 529 if (fDebug > 0) printf("->AliAnalysisManager::ImportWrappers()\n");
327eaf46 530 TIter next(fOutputs);
981f2614 531 AliAnalysisDataContainer *cont;
532 AliAnalysisDataWrapper *wrap;
533 Int_t icont = 0;
c52c2132 534 while ((cont=(AliAnalysisDataContainer*)next())) {
0355fc48 535 wrap = 0;
8d7d3b59 536 if (cont->GetProducer()->IsPostEventLoop()) continue;
4ab472d4 537 const char *filename = cont->GetFileName();
538 Bool_t isManagedByHandler = kFALSE;
539 if (!(strcmp(filename, "default")) && fOutputEventHandler) {
540 isManagedByHandler = kTRUE;
541 filename = fOutputEventHandler->GetOutputFileName();
542 }
8d7d3b59 543 if (cont->IsSpecialOutput()) {
4ab472d4 544 if (strlen(fSpecialOutputLocation.Data()) && !isManagedByHandler) continue;
8d7d3b59 545 // Copy merged file from PROOF scratch space
4ab472d4 546 char full_path[512];
547 TObject *pof = source->FindObject(filename);
548 if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
549 Error("ImportWrappers", "TProofOutputFile object not found in output list for container %s", cont->GetName());
550 continue;
551 }
552 gROOT->ProcessLine(Form("sprintf((char*)0x%lx, \"%%s\", ((TProofOutputFile*)0x%lx)->GetOutputFileName();)", full_path, pof));
8d7d3b59 553 if (fDebug > 1)
4ab472d4 554 printf(" Copying file %s from PROOF scratch space\n", full_path);
555 Bool_t gotit = TFile::Cp(full_path, filename);
8d7d3b59 556 if (!gotit) {
557 Error("ImportWrappers", "Could not get file %s from proof scratch space", cont->GetFileName());
558 }
559 // Normally we should connect data from the copied file to the
560 // corresponding output container, but it is not obvious how to do this
561 // automatically if several objects in file...
4ab472d4 562 TFile *f = new TFile(filename, "READ");
802f90ef 563 TObject *obj = 0;
564 if (!isManagedByHandler) obj = f->Get(cont->GetName());
565 if (!obj && !isManagedByHandler) {
4ab472d4 566 Error("ImportWrappers", "Could not find object %s in file %s", cont->GetName(), filename);
0355fc48 567 continue;
568 }
569 wrap = new AliAnalysisDataWrapper(obj);
570 wrap->SetDeleteData(kFALSE);
8d7d3b59 571 }
0355fc48 572 if (!wrap) wrap = (AliAnalysisDataWrapper*)source->FindObject(cont->GetName());
8d7d3b59 573 if (!wrap) {
574 Error("ImportWrappers","Container %s not found in analysis output !", cont->GetName());
c52c2132 575 continue;
576 }
981f2614 577 icont++;
8d7d3b59 578 if (fDebug > 1) {
579 printf(" Importing data for container %s", cont->GetName());
4ab472d4 580 if (strlen(filename)) printf(" -> file %s\n", cont->GetFileName());
8d7d3b59 581 else printf("\n");
582 }
981f2614 583 cont->ImportData(wrap);
c52c2132 584 }
8d7d3b59 585 if (fDebug > 0) printf("<-AliAnalysisManager::ImportWrappers(): %d containers imported\n", icont);
c52c2132 586}
587
588//______________________________________________________________________________
589void AliAnalysisManager::UnpackOutput(TList *source)
590{
ca78991b 591 // Called by AliAnalysisSelector::Terminate only on the client.
8d7d3b59 592 if (fDebug > 0) printf("->AliAnalysisManager::UnpackOutput()\n");
c52c2132 593 if (!source) {
981f2614 594 Error("UnpackOutput", "No target. Aborting.");
c52c2132 595 return;
596 }
8d7d3b59 597 if (fDebug > 1) printf(" Source list contains %d containers\n", source->GetSize());
c52c2132 598
981f2614 599 if (fMode == kProofAnalysis) ImportWrappers(source);
37153431 600
981f2614 601 TIter next(fOutputs);
c52c2132 602 AliAnalysisDataContainer *output;
603 while ((output=(AliAnalysisDataContainer*)next())) {
c52c2132 604 if (!output->GetData()) continue;
b1310ef5 605 // Check if there are client tasks that run post event loop
606 if (output->HasConsumers()) {
607 // Disable event loop semaphore
608 output->SetPostEventLoop(kTRUE);
609 TObjArray *list = output->GetConsumers();
610 Int_t ncons = list->GetEntriesFast();
611 for (Int_t i=0; i<ncons; i++) {
612 AliAnalysisTask *task = (AliAnalysisTask*)list->At(i);
613 task->CheckNotify(kTRUE);
614 // If task is active, execute it
615 if (task->IsPostEventLoop() && task->IsActive()) {
8d7d3b59 616 if (fDebug > 0) printf("== Executing post event loop task %s\n", task->GetName());
b1310ef5 617 task->ExecuteTask();
618 }
619 }
620 }
c52c2132 621 }
8d7d3b59 622 if (fDebug > 0) printf("<-AliAnalysisManager::UnpackOutput()\n");
d3106602 623}
624
625//______________________________________________________________________________
626void AliAnalysisManager::Terminate()
627{
628 // The Terminate() function is the last function to be called during
629 // a query. It always runs on the client, it can be used to present
c52c2132 630 // the results graphically.
8d7d3b59 631 if (fDebug > 0) printf("->AliAnalysisManager::Terminate()\n");
327eaf46 632 AliAnalysisTask *task;
c52c2132 633 TIter next(fTasks);
327eaf46 634 // Call Terminate() for tasks
c52c2132 635 while ((task=(AliAnalysisTask*)next())) task->Terminate();
8c9485b2 636 //
8c0ab8e8 637 TIter next1(fOutputs);
638 AliAnalysisDataContainer *output;
639 while ((output=(AliAnalysisDataContainer*)next1())) {
1be433fc 640 // Special outputs have the files already closed and written.
3259c7bd 641 if (output->IsSpecialOutput()&&(fMode == kProofAnalysis)) continue;
8c0ab8e8 642 const char *filename = output->GetFileName();
643 if (!(strcmp(filename, "default"))) {
644 if (fOutputEventHandler) filename = fOutputEventHandler->GetOutputFileName();
1be433fc 645 TFile *aodfile = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
646 if (aodfile) {
647 if (fDebug > 1) printf("Writing output handler file: %s\n", filename);
648 aodfile->Write();
649 continue;
650 }
8d7d3b59 651 }
652 if (!strlen(filename)) continue;
1be433fc 653 if (!output->GetData()) continue;
8d7d3b59 654 TFile *file = output->GetFile();
655 TDirectory *opwd = gDirectory;
8e6e6fe8 656 file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
657 if (!file) file = new TFile(filename, "RECREATE");
658 if (file->IsZombie()) continue;
659 output->SetFile(file);
660 file->cd();
8d7d3b59 661 if (fDebug > 1) printf(" writing output data %s to file %s\n", output->GetData()->GetName(), file->GetName());
1be433fc 662 if (output->GetData()->InheritsFrom(TCollection::Class())) {
663 // If data is a collection, we set the name of the collection
664 // as the one of the container and we save as a single key.
665 TCollection *coll = (TCollection*)output->GetData();
666 coll->SetName(output->GetName());
667 coll->Write(output->GetName(), TObject::kSingleKey);
668 } else {
cbc8747a 669 if (output->GetData()->InheritsFrom(TTree::Class())) {
670 TTree *tree = (TTree*)output->GetData();
671 tree->SetDirectory(file);
672 tree->AutoSave();
673 } else {
674 output->GetData()->Write();
675 }
1be433fc 676 }
8e6e6fe8 677 if (opwd) opwd->cd();
678 }
679 next1.Reset();
680 while ((output=(AliAnalysisDataContainer*)next1())) {
681 // Close all files at output
682 TDirectory *opwd = gDirectory;
683 if (output->GetFile()) output->GetFile()->Close();
8d7d3b59 684 if (opwd) opwd->cd();
8c0ab8e8 685 }
686
1be433fc 687 if (fInputEventHandler) fInputEventHandler ->TerminateIO();
688 if (fOutputEventHandler) fOutputEventHandler ->TerminateIO();
689 if (fMCtruthEventHandler) fMCtruthEventHandler->TerminateIO();
690
8c0ab8e8 691 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
692 if (getsysInfo) {
693 TDirectory *cdir = gDirectory;
694 TFile f("syswatch.root", "RECREATE");
695 if (!f.IsZombie()) {
696 TTree *tree = AliSysInfo::MakeTree("syswatch.log");
697 tree->SetMarkerStyle(kCircle);
698 tree->SetMarkerColor(kBlue);
699 tree->SetMarkerSize(0.5);
700 if (!gROOT->IsBatch()) {
701 tree->SetAlias("event", "id0");
29cbcef8 702 tree->SetAlias("memUSED", "pI.fMemVirtual");
8c0ab8e8 703 tree->SetAlias("userCPU", "pI.fCpuUser");
704 TCanvas *c = new TCanvas("SysInfo","SysInfo",10,10,800,600);
705 c->Divide(2,1,0.01,0.01);
706 c->cd(1);
707 tree->Draw("memUSED:event","","", 1234567890, 0);
708 c->cd(2);
709 tree->Draw("userCPU:event","","", 1234567890, 0);
710 }
711 tree->Write();
712 f.Close();
713 delete tree;
714 }
715 if (cdir) cdir->cd();
716 }
8d7d3b59 717 if (fDebug > 0) printf("<-AliAnalysisManager::Terminate()\n");
d3106602 718}
719
720//______________________________________________________________________________
721void AliAnalysisManager::AddTask(AliAnalysisTask *task)
722{
723// Adds a user task to the global list of tasks.
8d7d3b59 724 if (fTasks->FindObject(task)) {
725 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
726 return;
727 }
d3106602 728 task->SetActive(kFALSE);
729 fTasks->Add(task);
730}
731
732//______________________________________________________________________________
733AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
734{
735// Retreive task by name.
736 if (!fTasks) return NULL;
737 return (AliAnalysisTask*)fTasks->FindObject(name);
738}
739
740//______________________________________________________________________________
741AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
c52c2132 742 TClass *datatype, EAliAnalysisContType type, const char *filename)
d3106602 743{
744// Create a data container of a certain type. Types can be:
c52c2132 745// kExchangeContainer = 0, used to exchange date between tasks
d3106602 746// kInputContainer = 1, used to store input data
747// kOutputContainer = 2, used for posting results
b1310ef5 748 if (fContainers->FindObject(name)) {
749 Error("CreateContainer","A container named %s already defined !\n",name);
750 return NULL;
751 }
d3106602 752 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
753 fContainers->Add(cont);
754 switch (type) {
755 case kInputContainer:
756 fInputs->Add(cont);
757 break;
758 case kOutputContainer:
759 fOutputs->Add(cont);
8c0ab8e8 760 if (filename && strlen(filename)) {
761 cont->SetFileName(filename);
762 cont->SetDataOwned(kFALSE); // data owned by the file
763 }
d3106602 764 break;
c52c2132 765 case kExchangeContainer:
d3106602 766 break;
767 }
768 return cont;
769}
770
771//______________________________________________________________________________
772Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
773 AliAnalysisDataContainer *cont)
774{
775// Connect input of an existing task to a data container.
776 if (!fTasks->FindObject(task)) {
777 AddTask(task);
8d7d3b59 778 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
d3106602 779 }
780 Bool_t connected = task->ConnectInput(islot, cont);
781 return connected;
782}
783
784//______________________________________________________________________________
785Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
786 AliAnalysisDataContainer *cont)
787{
788// Connect output of an existing task to a data container.
789 if (!fTasks->FindObject(task)) {
790 AddTask(task);
c52c2132 791 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
d3106602 792 }
793 Bool_t connected = task->ConnectOutput(islot, cont);
794 return connected;
795}
796
797//______________________________________________________________________________
798void AliAnalysisManager::CleanContainers()
799{
800// Clean data from all containers that have already finished all client tasks.
801 TIter next(fContainers);
802 AliAnalysisDataContainer *cont;
803 while ((cont=(AliAnalysisDataContainer *)next())) {
804 if (cont->IsOwnedData() &&
805 cont->IsDataReady() &&
806 cont->ClientsExecuted()) cont->DeleteData();
807 }
808}
809
810//______________________________________________________________________________
811Bool_t AliAnalysisManager::InitAnalysis()
812{
813// Initialization of analysis chain of tasks. Should be called after all tasks
814// and data containers are properly connected
815 // Check for input/output containers
816 fInitOK = kFALSE;
d3106602 817 // Check for top tasks (depending only on input data containers)
818 if (!fTasks->First()) {
c52c2132 819 Error("InitAnalysis", "Analysis has no tasks !");
d3106602 820 return kFALSE;
821 }
822 TIter next(fTasks);
823 AliAnalysisTask *task;
824 AliAnalysisDataContainer *cont;
825 Int_t ntop = 0;
826 Int_t nzombies = 0;
327eaf46 827 Bool_t iszombie = kFALSE;
828 Bool_t istop = kTRUE;
d3106602 829 Int_t i;
830 while ((task=(AliAnalysisTask*)next())) {
327eaf46 831 istop = kTRUE;
832 iszombie = kFALSE;
d3106602 833 Int_t ninputs = task->GetNinputs();
d3106602 834 for (i=0; i<ninputs; i++) {
835 cont = task->GetInputSlot(i)->GetContainer();
836 if (!cont) {
327eaf46 837 if (!iszombie) {
d3106602 838 task->SetZombie();
839 fZombies->Add(task);
840 nzombies++;
327eaf46 841 iszombie = kTRUE;
d3106602 842 }
c52c2132 843 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
844 i, task->GetName());
d3106602 845 }
327eaf46 846 if (iszombie) continue;
d3106602 847 // Check if cont is an input container
327eaf46 848 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
d3106602 849 // Connect to parent task
850 }
327eaf46 851 if (istop) {
d3106602 852 ntop++;
853 fTopTasks->Add(task);
854 }
855 }
856 if (!ntop) {
c52c2132 857 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
d3106602 858 return kFALSE;
859 }
860 // Check now if there are orphan tasks
861 for (i=0; i<ntop; i++) {
862 task = (AliAnalysisTask*)fTopTasks->At(i);
863 task->SetUsed();
864 }
865 Int_t norphans = 0;
866 next.Reset();
867 while ((task=(AliAnalysisTask*)next())) {
868 if (!task->IsUsed()) {
869 norphans++;
c52c2132 870 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
d3106602 871 }
872 }
873 // Check the task hierarchy (no parent task should depend on data provided
874 // by a daughter task)
875 for (i=0; i<ntop; i++) {
876 task = (AliAnalysisTask*)fTopTasks->At(i);
877 if (task->CheckCircularDeps()) {
c52c2132 878 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
d3106602 879 PrintStatus("dep");
880 return kFALSE;
881 }
882 }
b1310ef5 883 // Check that all containers feeding post-event loop tasks are in the outputs list
884 TIter nextcont(fContainers); // loop over all containers
885 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
886 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
887 if (cont->HasConsumers()) {
888 // Check if one of the consumers is post event loop
889 TIter nextconsumer(cont->GetConsumers());
890 while ((task=(AliAnalysisTask*)nextconsumer())) {
891 if (task->IsPostEventLoop()) {
892 fOutputs->Add(cont);
893 break;
894 }
895 }
896 }
897 }
898 }
8d7d3b59 899 // Check if all special output containers have a file name provided
900 TIter nextout(fOutputs);
901 while ((cont=(AliAnalysisDataContainer*)nextout())) {
902 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
903 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
904 return kFALSE;
905 }
906 }
327eaf46 907 fInitOK = kTRUE;
d3106602 908 return kTRUE;
909}
910
911//______________________________________________________________________________
912void AliAnalysisManager::PrintStatus(Option_t *option) const
913{
914// Print task hierarchy.
8c0ab8e8 915 if (!fInitOK) {
916 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
917 return;
918 }
919 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
920 if (getsysInfo)
921 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
d3106602 922 TIter next(fTopTasks);
923 AliAnalysisTask *task;
924 while ((task=(AliAnalysisTask*)next()))
925 task->PrintTask(option);
926}
927
928//______________________________________________________________________________
929void AliAnalysisManager::ResetAnalysis()
930{
931// Reset all execution flags and clean containers.
932 CleanContainers();
933}
934
935//______________________________________________________________________________
8c0ab8e8 936void AliAnalysisManager::StartAnalysis(const char *type, TTree *tree, Long64_t nentries, Long64_t firstentry)
c52c2132 937{
aee5ee44 938// Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
939// MIX. Process nentries starting from firstentry
c52c2132 940 if (!fInitOK) {
941 Error("StartAnalysis","Analysis manager was not initialized !");
942 return;
943 }
8d7d3b59 944 if (fDebug > 0) printf("StartAnalysis %s\n",GetName());
c52c2132 945 TString anaType = type;
946 anaType.ToLower();
947 fMode = kLocalAnalysis;
4ab472d4 948 if (anaType.Contains("proof")) fMode = kProofAnalysis;
949 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
950 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
951
c52c2132 952 if (fMode == kGridAnalysis) {
953 Warning("StartAnalysis", "GRID analysis mode not implemented. Running local.");
981f2614 954 fMode = kLocalAnalysis;
955 }
d86ed856 956 char line[256];
efd53803 957 SetEventLoop(kFALSE);
8d7d3b59 958 // Enable event loop mode if a tree was provided
aee5ee44 959 if (tree || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
efd53803 960
8c0ab8e8 961 TChain *chain = 0;
962 TString ttype = "TTree";
4ab472d4 963 if (tree && tree->IsA() == TChain::Class()) {
8c0ab8e8 964 chain = (TChain*)tree;
6b742510 965 if (!chain || !chain->GetListOfFiles()->First()) {
966 Error("StartAnalysis", "Cannot process null or empty chain...");
967 return;
968 }
8c0ab8e8 969 ttype = "TChain";
970 }
9b33830a 971
aee5ee44 972 // Initialize locally all tasks (happens for all modes)
9b33830a 973 TIter next(fTasks);
974 AliAnalysisTask *task;
efd53803 975 while ((task=(AliAnalysisTask*)next())) {
efd53803 976 task->LocalInit();
977 }
978
c52c2132 979 switch (fMode) {
980 case kLocalAnalysis:
981 if (!tree) {
03a5cc9f 982 TIter nextT(fTasks);
981f2614 983 // Call CreateOutputObjects for all tasks
03a5cc9f 984 while ((task=(AliAnalysisTask*)nextT())) {
c5a87c56 985 TDirectory *curdir = gDirectory;
986 task->CreateOutputObjects();
987 if (curdir) curdir->cd();
988 }
c52c2132 989 ExecAnalysis();
981f2614 990 Terminate();
c52c2132 991 return;
992 }
993 // Run tree-based analysis via AliAnalysisSelector
c52c2132 994 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
aee5ee44 995 fSelector = new AliAnalysisSelector(this);
996 tree->Process(fSelector, "", nentries, firstentry);
c52c2132 997 break;
998 case kProofAnalysis:
999 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1000 printf("StartAnalysis: no PROOF!!!\n");
1001 return;
1002 }
1003 sprintf(line, "gProof->AddInput((TObject*)0x%lx);", (ULong_t)this);
1004 gROOT->ProcessLine(line);
1005 if (chain) {
1006 chain->SetProof();
1007 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
8c0ab8e8 1008 chain->Process("AliAnalysisSelector", "", nentries, firstentry);
c52c2132 1009 } else {
1010 printf("StartAnalysis: no chain\n");
1011 return;
1012 }
1013 break;
1014 case kGridAnalysis:
1015 Warning("StartAnalysis", "GRID analysis mode not implemented. Running local.");
aee5ee44 1016 break;
1017 case kMixingAnalysis:
1018 // Run event mixing analysis
1019 if (!fEventPool) {
1020 Error("StartAnalysis", "Cannot run event mixing without event pool");
1021 return;
1022 }
1023 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1024 fSelector = new AliAnalysisSelector(this);
aee5ee44 1025 while ((chain=fEventPool->GetNextChain())) {
d1e79f9e 1026 next.Reset();
aee5ee44 1027 // Call NotifyBinChange for all tasks
1028 while ((task=(AliAnalysisTask*)next()))
1029 if (!task->IsPostEventLoop()) task->NotifyBinChange();
1030 chain->Process(fSelector);
1031 }
1032 PackOutput(fSelector->GetOutputList());
1033 Terminate();
c52c2132 1034 }
1035}
1036
1037//______________________________________________________________________________
d86ed856 1038void AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
1039{
1040// Start analysis for this manager on a given dataset. Analysis task can be:
1041// LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1042 if (!fInitOK) {
1043 Error("StartAnalysis","Analysis manager was not initialized !");
1044 return;
1045 }
8d7d3b59 1046 if (fDebug > 0) printf("StartAnalysis %s\n",GetName());
d86ed856 1047 TString anaType = type;
1048 anaType.ToLower();
1049 if (!anaType.Contains("proof")) {
d140f7fb 1050 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
d86ed856 1051 return;
1052 }
1053 fMode = kProofAnalysis;
1054 char line[256];
1055 SetEventLoop(kTRUE);
1056 // Set the dataset flag
1057 TObject::SetBit(kUseDataSet);
1058 fTree = 0;
1059
1060 // Initialize locally all tasks
1061 TIter next(fTasks);
1062 AliAnalysisTask *task;
1063 while ((task=(AliAnalysisTask*)next())) {
1064 task->LocalInit();
1065 }
1066
1067 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1068 printf("StartAnalysis: no PROOF!!!\n");
1069 return;
1070 }
1071 sprintf(line, "gProof->AddInput((TObject*)0x%lx);", (ULong_t)this);
1072 gROOT->ProcessLine(line);
1073 sprintf(line, "gProof->GetDataSet(\"%s\");", dataset);
1074 if (!gROOT->ProcessLine(line)) {
1075 Error("StartAnalysis", "Dataset %s not found", dataset);
1076 return;
1077 }
1078 sprintf(line, "gProof->Process(\"%s\", \"AliAnalysisSelector\", \"\", %lld, %lld);",
1079 dataset, nentries, firstentry);
1080 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
1081 gROOT->ProcessLine(line);
1082}
1083
1084//______________________________________________________________________________
8d7d3b59 1085TFile *AliAnalysisManager::OpenProofFile(const char *filename, const char *option)
1086{
1087// Opens a special output file used in PROOF.
1088 char line[256];
1089 if (fMode!=kProofAnalysis || !fSelector) {
1090 Error("OpenProofFile","Cannot open PROOF file %s",filename);
1091 return NULL;
1092 }
1093 sprintf(line, "TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename);
1094 if (fDebug > 1) printf("=== %s\n", line);
1095 gROOT->ProcessLine(line);
1096 sprintf(line, "pf->OpenFile(\"%s\");", option);
1097 gROOT->ProcessLine(line);
1098 if (fDebug > 1) {
1099 gROOT->ProcessLine("pf->Print()");
1100 printf(" == proof file name: %s\n", gFile->GetName());
1101 }
1102 sprintf(line, "((TList*)0x%lx)->Add(pf);",(ULong_t)fSelector->GetOutputList());
1103 if (fDebug > 1) printf("=== %s\n", line);
1104 gROOT->ProcessLine(line);
1105 return gFile;
1106}
1107
1108//______________________________________________________________________________
d3106602 1109void AliAnalysisManager::ExecAnalysis(Option_t *option)
1110{
1111// Execute analysis.
8c0ab8e8 1112 static Long64_t ncalls = 0;
1113 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1114 if (getsysInfo && ncalls==0) AliSysInfo::AddStamp("Start", (Int_t)ncalls);
1115 ncalls++;
327eaf46 1116 if (!fInitOK) {
c52c2132 1117 Error("ExecAnalysis", "Analysis manager was not initialized !");
327eaf46 1118 return;
1119 }
d3106602 1120 AliAnalysisTask *task;
327eaf46 1121 // Check if the top tree is active.
1122 if (fTree) {
1123 TIter next(fTasks);
1124 // De-activate all tasks
1125 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
1126 AliAnalysisDataContainer *cont = (AliAnalysisDataContainer*)fInputs->At(0);
1127 if (!cont) {
c52c2132 1128 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
327eaf46 1129 return;
1130 }
1131 cont->SetData(fTree); // This will notify all consumers
ed97dc98 1132 Long64_t entry = fTree->GetTree()->GetReadEntry();
1133
6bb2b24f 1134//
c3701689 1135// Call BeginEvent() for optional input/output and MC services
ed97dc98 1136 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
1137 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
1138 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
6bb2b24f 1139//
1140// Execute the tasks
276941c8 1141// TIter next1(cont->GetConsumers());
1142 TIter next1(fTopTasks);
327eaf46 1143 while ((task=(AliAnalysisTask*)next1())) {
c52c2132 1144 if (fDebug >1) {
1145 cout << " Executing task " << task->GetName() << endl;
1146 }
6bb2b24f 1147
327eaf46 1148 task->ExecuteTask(option);
1149 }
6bb2b24f 1150//
1151// Call FinishEvent() for optional output and MC services
6073f8c9 1152 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
6bb2b24f 1153 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
1154 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
8c0ab8e8 1155 // Gather system information if requested
1156 if (getsysInfo && ((ncalls%fNSysInfo)==0))
1157 AliSysInfo::AddStamp(Form("Event#%lld",ncalls),(Int_t)ncalls);
327eaf46 1158 return;
1159 }
1160 // The event loop is not controlled by TSelector
6bb2b24f 1161//
c3701689 1162// Call BeginEvent() for optional input/output and MC services
ed97dc98 1163 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
1164 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
1165 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
327eaf46 1166 TIter next2(fTopTasks);
1167 while ((task=(AliAnalysisTask*)next2())) {
1168 task->SetActive(kTRUE);
c52c2132 1169 if (fDebug > 1) {
1170 cout << " Executing task " << task->GetName() << endl;
1171 }
d3106602 1172 task->ExecuteTask(option);
327eaf46 1173 }
6bb2b24f 1174//
1175// Call FinishEvent() for optional output and MC services
6073f8c9 1176 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
1177 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
6bb2b24f 1178 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
d3106602 1179}
1180
1181//______________________________________________________________________________
1182void AliAnalysisManager::FinishAnalysis()
1183{
1184// Finish analysis.
1185}