]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ANALYSIS/AliAnalysisManager.cxx
Added code to put N_primary and N_total into all SDigits.
[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");
29cbcef8 775 tree->SetAlias("memUSED", "pI.fMemVirtual");
8c0ab8e8 776 tree->SetAlias("userCPU", "pI.fCpuUser");
777 TCanvas *c = new TCanvas("SysInfo","SysInfo",10,10,800,600);
778 c->Divide(2,1,0.01,0.01);
779 c->cd(1);
780 tree->Draw("memUSED:event","","", 1234567890, 0);
781 c->cd(2);
782 tree->Draw("userCPU:event","","", 1234567890, 0);
783 }
784 tree->Write();
785 f.Close();
786 delete tree;
787 }
788 if (cdir) cdir->cd();
789 }
8d7d3b59 790 if (fDebug > 0) printf("<-AliAnalysisManager::Terminate()\n");
d3106602 791}
792
793//______________________________________________________________________________
794void AliAnalysisManager::AddTask(AliAnalysisTask *task)
795{
796// Adds a user task to the global list of tasks.
8d7d3b59 797 if (fTasks->FindObject(task)) {
798 Warning("AddTask", "Task %s: the same object already added to the analysis manager. Not adding.", task->GetName());
799 return;
800 }
d3106602 801 task->SetActive(kFALSE);
802 fTasks->Add(task);
803}
804
805//______________________________________________________________________________
806AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
807{
808// Retreive task by name.
809 if (!fTasks) return NULL;
810 return (AliAnalysisTask*)fTasks->FindObject(name);
811}
812
813//______________________________________________________________________________
814AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
c52c2132 815 TClass *datatype, EAliAnalysisContType type, const char *filename)
d3106602 816{
817// Create a data container of a certain type. Types can be:
c52c2132 818// kExchangeContainer = 0, used to exchange date between tasks
d3106602 819// kInputContainer = 1, used to store input data
820// kOutputContainer = 2, used for posting results
b1310ef5 821 if (fContainers->FindObject(name)) {
822 Error("CreateContainer","A container named %s already defined !\n",name);
823 return NULL;
824 }
d3106602 825 AliAnalysisDataContainer *cont = new AliAnalysisDataContainer(name, datatype);
826 fContainers->Add(cont);
827 switch (type) {
828 case kInputContainer:
829 fInputs->Add(cont);
830 break;
831 case kOutputContainer:
832 fOutputs->Add(cont);
8c0ab8e8 833 if (filename && strlen(filename)) {
834 cont->SetFileName(filename);
835 cont->SetDataOwned(kFALSE); // data owned by the file
836 }
d3106602 837 break;
c52c2132 838 case kExchangeContainer:
d3106602 839 break;
840 }
841 return cont;
842}
843
844//______________________________________________________________________________
845Bool_t AliAnalysisManager::ConnectInput(AliAnalysisTask *task, Int_t islot,
846 AliAnalysisDataContainer *cont)
847{
848// Connect input of an existing task to a data container.
849 if (!fTasks->FindObject(task)) {
850 AddTask(task);
8d7d3b59 851 Info("ConnectInput", "Task %s was not registered. Now owned by analysis manager", task->GetName());
d3106602 852 }
853 Bool_t connected = task->ConnectInput(islot, cont);
854 return connected;
855}
856
857//______________________________________________________________________________
858Bool_t AliAnalysisManager::ConnectOutput(AliAnalysisTask *task, Int_t islot,
859 AliAnalysisDataContainer *cont)
860{
861// Connect output of an existing task to a data container.
862 if (!fTasks->FindObject(task)) {
863 AddTask(task);
c52c2132 864 Warning("ConnectOutput", "Task %s not registered. Now owned by analysis manager", task->GetName());
d3106602 865 }
866 Bool_t connected = task->ConnectOutput(islot, cont);
867 return connected;
868}
869
870//______________________________________________________________________________
871void AliAnalysisManager::CleanContainers()
872{
873// Clean data from all containers that have already finished all client tasks.
874 TIter next(fContainers);
875 AliAnalysisDataContainer *cont;
876 while ((cont=(AliAnalysisDataContainer *)next())) {
877 if (cont->IsOwnedData() &&
878 cont->IsDataReady() &&
879 cont->ClientsExecuted()) cont->DeleteData();
880 }
881}
882
883//______________________________________________________________________________
884Bool_t AliAnalysisManager::InitAnalysis()
885{
886// Initialization of analysis chain of tasks. Should be called after all tasks
887// and data containers are properly connected
888 // Check for input/output containers
889 fInitOK = kFALSE;
d3106602 890 // Check for top tasks (depending only on input data containers)
891 if (!fTasks->First()) {
c52c2132 892 Error("InitAnalysis", "Analysis has no tasks !");
d3106602 893 return kFALSE;
894 }
895 TIter next(fTasks);
896 AliAnalysisTask *task;
897 AliAnalysisDataContainer *cont;
898 Int_t ntop = 0;
899 Int_t nzombies = 0;
327eaf46 900 Bool_t iszombie = kFALSE;
901 Bool_t istop = kTRUE;
d3106602 902 Int_t i;
903 while ((task=(AliAnalysisTask*)next())) {
327eaf46 904 istop = kTRUE;
905 iszombie = kFALSE;
d3106602 906 Int_t ninputs = task->GetNinputs();
d3106602 907 for (i=0; i<ninputs; i++) {
908 cont = task->GetInputSlot(i)->GetContainer();
909 if (!cont) {
327eaf46 910 if (!iszombie) {
d3106602 911 task->SetZombie();
912 fZombies->Add(task);
913 nzombies++;
327eaf46 914 iszombie = kTRUE;
d3106602 915 }
c52c2132 916 Error("InitAnalysis", "Input slot %d of task %s has no container connected ! Declared zombie...",
917 i, task->GetName());
d3106602 918 }
327eaf46 919 if (iszombie) continue;
d3106602 920 // Check if cont is an input container
327eaf46 921 if (istop && !fInputs->FindObject(cont)) istop=kFALSE;
d3106602 922 // Connect to parent task
923 }
327eaf46 924 if (istop) {
d3106602 925 ntop++;
926 fTopTasks->Add(task);
927 }
928 }
929 if (!ntop) {
c52c2132 930 Error("InitAnalysis", "No top task defined. At least one task should be connected only to input containers");
d3106602 931 return kFALSE;
932 }
933 // Check now if there are orphan tasks
934 for (i=0; i<ntop; i++) {
935 task = (AliAnalysisTask*)fTopTasks->At(i);
936 task->SetUsed();
937 }
938 Int_t norphans = 0;
939 next.Reset();
940 while ((task=(AliAnalysisTask*)next())) {
941 if (!task->IsUsed()) {
942 norphans++;
c52c2132 943 Warning("InitAnalysis", "Task %s is orphan", task->GetName());
d3106602 944 }
945 }
946 // Check the task hierarchy (no parent task should depend on data provided
947 // by a daughter task)
948 for (i=0; i<ntop; i++) {
949 task = (AliAnalysisTask*)fTopTasks->At(i);
950 if (task->CheckCircularDeps()) {
c52c2132 951 Error("InitAnalysis", "Found illegal circular dependencies between following tasks:");
d3106602 952 PrintStatus("dep");
953 return kFALSE;
954 }
955 }
b1310ef5 956 // Check that all containers feeding post-event loop tasks are in the outputs list
957 TIter nextcont(fContainers); // loop over all containers
958 while ((cont=(AliAnalysisDataContainer*)nextcont())) {
959 if (!cont->IsPostEventLoop() && !fOutputs->FindObject(cont)) {
960 if (cont->HasConsumers()) {
961 // Check if one of the consumers is post event loop
962 TIter nextconsumer(cont->GetConsumers());
963 while ((task=(AliAnalysisTask*)nextconsumer())) {
964 if (task->IsPostEventLoop()) {
965 fOutputs->Add(cont);
966 break;
967 }
968 }
969 }
970 }
971 }
8d7d3b59 972 // Check if all special output containers have a file name provided
973 TIter nextout(fOutputs);
974 while ((cont=(AliAnalysisDataContainer*)nextout())) {
975 if (cont->IsSpecialOutput() && !strlen(cont->GetFileName())) {
976 Error("InitAnalysis", "Wrong container %s : a file name MUST be provided for special outputs", cont->GetName());
977 return kFALSE;
978 }
979 }
327eaf46 980 fInitOK = kTRUE;
d3106602 981 return kTRUE;
982}
983
984//______________________________________________________________________________
985void AliAnalysisManager::PrintStatus(Option_t *option) const
986{
987// Print task hierarchy.
8c0ab8e8 988 if (!fInitOK) {
989 Info("PrintStatus", "Analysis manager %s not initialized : call InitAnalysis() first", GetName());
990 return;
991 }
992 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
993 if (getsysInfo)
994 Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
d3106602 995 TIter next(fTopTasks);
996 AliAnalysisTask *task;
997 while ((task=(AliAnalysisTask*)next()))
998 task->PrintTask(option);
999}
1000
1001//______________________________________________________________________________
1002void AliAnalysisManager::ResetAnalysis()
1003{
1004// Reset all execution flags and clean containers.
1005 CleanContainers();
1006}
1007
c52c2132 1008//______________________________________________________________________________
8c0ab8e8 1009void AliAnalysisManager::StartAnalysis(const char *type, TTree *tree, Long64_t nentries, Long64_t firstentry)
c52c2132 1010{
aee5ee44 1011// Start analysis for this manager. Analysis task can be: LOCAL, PROOF, GRID or
1012// MIX. Process nentries starting from firstentry
c52c2132 1013 if (!fInitOK) {
1014 Error("StartAnalysis","Analysis manager was not initialized !");
1015 return;
1016 }
8d7d3b59 1017 if (fDebug > 0) printf("StartAnalysis %s\n",GetName());
c52c2132 1018 TString anaType = type;
1019 anaType.ToLower();
1020 fMode = kLocalAnalysis;
c57f56b7 1021 Bool_t runlocalinit = kTRUE;
1022 if (anaType.Contains("file")) runlocalinit = kFALSE;
4ab472d4 1023 if (anaType.Contains("proof")) fMode = kProofAnalysis;
1024 else if (anaType.Contains("grid")) fMode = kGridAnalysis;
1025 else if (anaType.Contains("mix")) fMode = kMixingAnalysis;
1026
c52c2132 1027 if (fMode == kGridAnalysis) {
c57f56b7 1028 if (!fGridHandler) {
1029 Error("StartAnalysis", "Cannot start grid analysis without a grid handler.");
1030 Info("===", "Add an AliAnalysisAlien object as plugin for this manager and configure it.");
1031 return;
1032 }
1033 // Write analysis manager in the analysis file
1034 cout << "===== RUNNING GRID ANALYSIS: " << GetName() << endl;
1035 // run local task configuration
1036 TIter nextTask(fTasks);
1037 AliAnalysisTask *task;
1038 while ((task=(AliAnalysisTask*)nextTask())) {
1039 task->LocalInit();
1040 }
1041 fGridHandler->StartAnalysis(nentries, firstentry);
1042
1043 // Terminate grid analysis
2d626244 1044 if (fSelector && fSelector->GetStatus() == -1) return;
c57f56b7 1045 if (fGridHandler->GetRunMode() == AliAnalysisGrid::kOffline) return;
1046 cout << "===== MERGING OUTPUTS REGISTERED BY YOUR ANALYSIS JOB: " << GetName() << endl;
1047 if (!fGridHandler->MergeOutputs()) {
1048 // Return if outputs could not be merged or if it alien handler
1049 // was configured for offline mode or local testing.
1050 return;
1051 }
1052 ImportWrappers(NULL);
1053 Terminate();
1054 return;
981f2614 1055 }
d86ed856 1056 char line[256];
efd53803 1057 SetEventLoop(kFALSE);
8d7d3b59 1058 // Enable event loop mode if a tree was provided
aee5ee44 1059 if (tree || fMode==kMixingAnalysis) SetEventLoop(kTRUE);
efd53803 1060
8c0ab8e8 1061 TChain *chain = 0;
1062 TString ttype = "TTree";
4ab472d4 1063 if (tree && tree->IsA() == TChain::Class()) {
8c0ab8e8 1064 chain = (TChain*)tree;
6b742510 1065 if (!chain || !chain->GetListOfFiles()->First()) {
1066 Error("StartAnalysis", "Cannot process null or empty chain...");
1067 return;
1068 }
8c0ab8e8 1069 ttype = "TChain";
1070 }
9b33830a 1071
aee5ee44 1072 // Initialize locally all tasks (happens for all modes)
9b33830a 1073 TIter next(fTasks);
1074 AliAnalysisTask *task;
c57f56b7 1075 if (runlocalinit) {
1076 while ((task=(AliAnalysisTask*)next())) {
1077 task->LocalInit();
1078 }
1079 }
efd53803 1080
c52c2132 1081 switch (fMode) {
1082 case kLocalAnalysis:
1083 if (!tree) {
03a5cc9f 1084 TIter nextT(fTasks);
981f2614 1085 // Call CreateOutputObjects for all tasks
03a5cc9f 1086 while ((task=(AliAnalysisTask*)nextT())) {
c5a87c56 1087 TDirectory *curdir = gDirectory;
1088 task->CreateOutputObjects();
1089 if (curdir) curdir->cd();
1090 }
c52c2132 1091 ExecAnalysis();
981f2614 1092 Terminate();
c52c2132 1093 return;
1094 }
1095 // Run tree-based analysis via AliAnalysisSelector
c52c2132 1096 cout << "===== RUNNING LOCAL ANALYSIS " << GetName() << " ON TREE " << tree->GetName() << endl;
aee5ee44 1097 fSelector = new AliAnalysisSelector(this);
1098 tree->Process(fSelector, "", nentries, firstentry);
c52c2132 1099 break;
1100 case kProofAnalysis:
1101 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1102 printf("StartAnalysis: no PROOF!!!\n");
1103 return;
1104 }
1105 sprintf(line, "gProof->AddInput((TObject*)0x%lx);", (ULong_t)this);
1106 gROOT->ProcessLine(line);
1107 if (chain) {
1108 chain->SetProof();
1109 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON CHAIN " << chain->GetName() << endl;
8c0ab8e8 1110 chain->Process("AliAnalysisSelector", "", nentries, firstentry);
c52c2132 1111 } else {
1112 printf("StartAnalysis: no chain\n");
1113 return;
1114 }
1115 break;
1116 case kGridAnalysis:
1117 Warning("StartAnalysis", "GRID analysis mode not implemented. Running local.");
aee5ee44 1118 break;
1119 case kMixingAnalysis:
1120 // Run event mixing analysis
1121 if (!fEventPool) {
1122 Error("StartAnalysis", "Cannot run event mixing without event pool");
1123 return;
1124 }
1125 cout << "===== RUNNING EVENT MIXING ANALYSIS " << GetName() << endl;
1126 fSelector = new AliAnalysisSelector(this);
aee5ee44 1127 while ((chain=fEventPool->GetNextChain())) {
d1e79f9e 1128 next.Reset();
aee5ee44 1129 // Call NotifyBinChange for all tasks
1130 while ((task=(AliAnalysisTask*)next()))
1131 if (!task->IsPostEventLoop()) task->NotifyBinChange();
1132 chain->Process(fSelector);
1133 }
1134 PackOutput(fSelector->GetOutputList());
1135 Terminate();
c52c2132 1136 }
1137}
1138
d86ed856 1139//______________________________________________________________________________
1140void AliAnalysisManager::StartAnalysis(const char *type, const char *dataset, Long64_t nentries, Long64_t firstentry)
1141{
1142// Start analysis for this manager on a given dataset. Analysis task can be:
1143// LOCAL, PROOF or GRID. Process nentries starting from firstentry.
1144 if (!fInitOK) {
1145 Error("StartAnalysis","Analysis manager was not initialized !");
1146 return;
1147 }
8d7d3b59 1148 if (fDebug > 0) printf("StartAnalysis %s\n",GetName());
d86ed856 1149 TString anaType = type;
1150 anaType.ToLower();
1151 if (!anaType.Contains("proof")) {
d140f7fb 1152 Error("StartAnalysis", "Cannot process datasets in %s mode. Try PROOF.", type);
d86ed856 1153 return;
1154 }
1155 fMode = kProofAnalysis;
1156 char line[256];
1157 SetEventLoop(kTRUE);
1158 // Set the dataset flag
1159 TObject::SetBit(kUseDataSet);
1160 fTree = 0;
1161
1162 // Initialize locally all tasks
1163 TIter next(fTasks);
1164 AliAnalysisTask *task;
1165 while ((task=(AliAnalysisTask*)next())) {
1166 task->LocalInit();
1167 }
1168
1169 if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
1170 printf("StartAnalysis: no PROOF!!!\n");
1171 return;
1172 }
1173 sprintf(line, "gProof->AddInput((TObject*)0x%lx);", (ULong_t)this);
1174 gROOT->ProcessLine(line);
1175 sprintf(line, "gProof->GetDataSet(\"%s\");", dataset);
1176 if (!gROOT->ProcessLine(line)) {
1177 Error("StartAnalysis", "Dataset %s not found", dataset);
1178 return;
1179 }
1180 sprintf(line, "gProof->Process(\"%s\", \"AliAnalysisSelector\", \"\", %lld, %lld);",
1181 dataset, nentries, firstentry);
1182 cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
1183 gROOT->ProcessLine(line);
1184}
1185
d3106602 1186//______________________________________________________________________________
8d7d3b59 1187TFile *AliAnalysisManager::OpenProofFile(const char *filename, const char *option)
1188{
1189// Opens a special output file used in PROOF.
1190 char line[256];
1191 if (fMode!=kProofAnalysis || !fSelector) {
1192 Error("OpenProofFile","Cannot open PROOF file %s",filename);
1193 return NULL;
1194 }
1195 sprintf(line, "TProofOutputFile *pf = new TProofOutputFile(\"%s\");", filename);
1196 if (fDebug > 1) printf("=== %s\n", line);
1197 gROOT->ProcessLine(line);
1198 sprintf(line, "pf->OpenFile(\"%s\");", option);
1199 gROOT->ProcessLine(line);
1200 if (fDebug > 1) {
1201 gROOT->ProcessLine("pf->Print()");
1202 printf(" == proof file name: %s\n", gFile->GetName());
1203 }
1204 sprintf(line, "((TList*)0x%lx)->Add(pf);",(ULong_t)fSelector->GetOutputList());
1205 if (fDebug > 1) printf("=== %s\n", line);
1206 gROOT->ProcessLine(line);
1207 return gFile;
1208}
1209
1210//______________________________________________________________________________
d3106602 1211void AliAnalysisManager::ExecAnalysis(Option_t *option)
1212{
1213// Execute analysis.
8c0ab8e8 1214 static Long64_t ncalls = 0;
1215 Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
1216 if (getsysInfo && ncalls==0) AliSysInfo::AddStamp("Start", (Int_t)ncalls);
1217 ncalls++;
327eaf46 1218 if (!fInitOK) {
c52c2132 1219 Error("ExecAnalysis", "Analysis manager was not initialized !");
327eaf46 1220 return;
1221 }
d3106602 1222 AliAnalysisTask *task;
327eaf46 1223 // Check if the top tree is active.
1224 if (fTree) {
1225 TIter next(fTasks);
1226 // De-activate all tasks
1227 while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
1228 AliAnalysisDataContainer *cont = (AliAnalysisDataContainer*)fInputs->At(0);
1229 if (!cont) {
c52c2132 1230 Error("ExecAnalysis","Cannot execute analysis in TSelector mode without at least one top container");
327eaf46 1231 return;
1232 }
1233 cont->SetData(fTree); // This will notify all consumers
ed97dc98 1234 Long64_t entry = fTree->GetTree()->GetReadEntry();
1235
6bb2b24f 1236//
c3701689 1237// Call BeginEvent() for optional input/output and MC services
ed97dc98 1238 if (fInputEventHandler) fInputEventHandler ->BeginEvent(entry);
1239 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(entry);
1240 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(entry);
6bb2b24f 1241//
1242// Execute the tasks
276941c8 1243// TIter next1(cont->GetConsumers());
1244 TIter next1(fTopTasks);
327eaf46 1245 while ((task=(AliAnalysisTask*)next1())) {
c52c2132 1246 if (fDebug >1) {
1247 cout << " Executing task " << task->GetName() << endl;
1248 }
6bb2b24f 1249
327eaf46 1250 task->ExecuteTask(option);
1251 }
6bb2b24f 1252//
1253// Call FinishEvent() for optional output and MC services
6073f8c9 1254 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
6bb2b24f 1255 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
1256 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
8c0ab8e8 1257 // Gather system information if requested
1258 if (getsysInfo && ((ncalls%fNSysInfo)==0))
1259 AliSysInfo::AddStamp(Form("Event#%lld",ncalls),(Int_t)ncalls);
327eaf46 1260 return;
1261 }
1262 // The event loop is not controlled by TSelector
6bb2b24f 1263//
c3701689 1264// Call BeginEvent() for optional input/output and MC services
ed97dc98 1265 if (fInputEventHandler) fInputEventHandler ->BeginEvent(-1);
1266 if (fOutputEventHandler) fOutputEventHandler ->BeginEvent(-1);
1267 if (fMCtruthEventHandler) fMCtruthEventHandler->BeginEvent(-1);
327eaf46 1268 TIter next2(fTopTasks);
1269 while ((task=(AliAnalysisTask*)next2())) {
1270 task->SetActive(kTRUE);
c52c2132 1271 if (fDebug > 1) {
1272 cout << " Executing task " << task->GetName() << endl;
1273 }
d3106602 1274 task->ExecuteTask(option);
327eaf46 1275 }
6bb2b24f 1276//
1277// Call FinishEvent() for optional output and MC services
6073f8c9 1278 if (fInputEventHandler) fInputEventHandler ->FinishEvent();
1279 if (fOutputEventHandler) fOutputEventHandler ->FinishEvent();
6bb2b24f 1280 if (fMCtruthEventHandler) fMCtruthEventHandler->FinishEvent();
d3106602 1281}
1282
1283//______________________________________________________________________________
1284void AliAnalysisManager::FinishAnalysis()
1285{
1286// Finish analysis.
1287}