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