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