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