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