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