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