Interface for setting up custom monitoring lib policy (Requested by Jens).
[u/mrichter/AliRoot.git] / STEER / STEER / AliRunDigitizer.cxx
CommitLineData
9ce40367 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
acd84897 16/* $Id$ */
9ce40367 17
88cb7938 18//_______________________________________________________________________
9ce40367 19//
20// AliRunDigitizer.cxx
21//
22// Manager object for merging/digitization
23//
24// Instance of this class manages the digitization and/or merging of
25// Sdigits into Digits.
26//
27// Only one instance of this class is created in the macro:
a90ecf3c 28// AliRunDigitizer * manager =
29// new AliRunDigitizer(nInputStreams,SPERB);
30// where nInputStreams is number of input streams and SPERB is
31// signals per background variable, which determines how combinations
32// of signal and background events are generated.
9ce40367 33// Then instances of specific detector digitizers are created:
34// AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager)
a90ecf3c 35// and the I/O configured (you have to specify input files
36// and an output file). The manager connects appropriate trees from
37// the input files according a combination returned by AliMergeCombi
9ae76683 38// class. It creates TreeD in the output and runs once per
a90ecf3c 39// event Digitize method of all existing AliDetDigitizers
40// (without any option). AliDetDigitizers ask manager
41// for a TTree with input (manager->GetInputTreeS(Int_t i),
9ce40367 42// merge all inputs, digitize it, and save it in the TreeD
43// obtained by manager->GetTreeD(). Output events are stored with
44// numbers from 0, this default can be changed by
45// manager->SetFirstOutputEventNr(Int_t) method. The particle numbers
46// in the output are shifted by MASK, which is taken from manager.
47//
8d5e6345 48// The default output is to the signal file (stream 0). This can be
49// changed with the SetOutputFile(TString fn) method.
50//
af7ba10c 51// Single input file is permitted. Maximum MAXSTREAMSTOMERGE can be merged.
9ce40367 52// Input from the memory (on-the-fly merging) is not yet
53// supported, as well as access to the input data by invoking methods
54// on the output data.
55//
a90ecf3c 56// Access to the some data is via gAlice for now (supposing the
57// same geometry in all input files), gAlice is taken from the first
58// input file on the first stream.
9ce40367 59//
314558d7 60// Example with MUON digitizer, no merging, just digitization
61//
62// AliRunDigitizer * manager = new AliRunDigitizer(1,1);
63// manager->SetInputStream(0,"galice.root");
64// AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager);
65// manager->Exec("");
66//
67// Example with MUON digitizer, merge all events from
68// galice.root (signal) file with events from bgr.root
69// (background) file. Number of merged events is
70// min(number of events in galice.root, number of events in bgr.root)
71//
72// AliRunDigitizer * manager = new AliRunDigitizer(2,1);
73// manager->SetInputStream(0,"galice.root");
74// manager->SetInputStream(1,"bgr.root");
75// AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager);
76// manager->Exec("");
77//
78// Example with MUON digitizer, save digits in a new file digits.root,
79// process only 1 event
9ce40367 80//
a90ecf3c 81// AliRunDigitizer * manager = new AliRunDigitizer(2,1);
314558d7 82// manager->SetInputStream(0,"galice.root");
83// manager->SetInputStream(1,"bgr.root");
a90ecf3c 84// manager->SetOutputFile("digits.root");
85// AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager);
86// manager->SetNrOfEventsToWrite(1);
8d5e6345 87// manager->Exec("");
9ce40367 88//
88cb7938 89//_______________________________________________________________________
9ce40367 90
91// system includes
92
9ce40367 93// ROOT includes
94
1bb2a43c 95class TList;
c93255fe 96#include <Riostream.h>
97#include <TTree.h>
9ce40367 98
99// AliROOT includes
100
594d8990 101#include "AliLog.h"
9ce40367 102#include "AliDigitizer.h"
1bb2a43c 103#include "AliHeader.h"
88cb7938 104#include "AliLoader.h"
1bb2a43c 105#include "AliMergeCombi.h"
e2afb3b6 106#include "AliRun.h"
107#include "AliRunDigitizer.h"
1bb2a43c 108#include "AliRunLoader.h"
9ce40367 109
110ClassImp(AliRunDigitizer)
111
88cb7938 112const TString AliRunDigitizer::fgkDefOutFolderName("Output");
113const TString AliRunDigitizer::fgkBaseInFolderName("Input");
114
115
e2afb3b6 116//_______________________________________________________________________
5d0ec6e3 117AliRunDigitizer::AliRunDigitizer(): TTask("AliRunDigitizer","The manager for Merging"),
88cb7938 118 fkMASKSTEP(0),
119 fOutputFileName(0),
120 fOutputDirName(0),
121 fEvent(0),
122 fNrOfEventsToWrite(0),
123 fNrOfEventsWritten(0),
124 fCopyTreesFromInput(0),
125 fNinputs(0),
126 fNinputsGiven(0),
127 fInputStreams(0x0),
128 fOutRunLoader(0x0),
129 fOutputInitialized(kFALSE),
130 fCombi(0),
131 fCombination(0),
594d8990 132 fCombinationFileName(0)
314558d7 133{
1bb2a43c 134 //
135 // root requires default ctor, where no new objects can be created
136 // do not use this ctor, it is supplied only for root needs
246e4424 137 for (Int_t i=0; i<MAXSTREAMSTOMERGE; ++i) fkMASK[i]=0;
e2afb3b6 138}
314558d7 139
e2afb3b6 140//_______________________________________________________________________
88cb7938 141AliRunDigitizer::AliRunDigitizer(Int_t nInputStreams, Int_t sperb):
142 TTask("AliRunDigitizer","The manager for Merging"),
143 fkMASKSTEP(10000000),
144 fOutputFileName(""),
145 fOutputDirName("."),
146 fEvent(0),
147 fNrOfEventsToWrite(-1),
148 fNrOfEventsWritten(0),
149 fCopyTreesFromInput(-1),
150 fNinputs(nInputStreams),
151 fNinputsGiven(0),
152 fInputStreams(new TClonesArray("AliStream",nInputStreams)),
153 fOutRunLoader(0x0),
154 fOutputInitialized(kFALSE),
155 fCombi(new AliMergeCombi(nInputStreams,sperb)),
af7ba10c 156 fCombination(MAXSTREAMSTOMERGE),
594d8990 157 fCombinationFileName(0)
88cb7938 158
159{
1bb2a43c 160 //
161 // ctor which should be used to create
162 // a manager for merging/digitization
163 //
88cb7938 164 if (nInputStreams == 0)
165 {//kidding
594d8990 166 AliFatal("Specify nr of input streams");
88cb7938 167 return;
168 }
169 Int_t i;
170
171 fkMASK[0] = 0;
172
af7ba10c 173 for (i=1;i<MAXSTREAMSTOMERGE;i++)
88cb7938 174 {
175 fkMASK[i] = fkMASK[i-1] + fkMASKSTEP;
176 }
177
178 TClonesArray &lInputStreams = *fInputStreams;
88cb7938 179
5f0ac153 180 new(lInputStreams[0]) AliStream(fgkBaseInFolderName+(Long_t)0,"UPDATE");
181 for (i=1;i<nInputStreams;i++) {
182 new(lInputStreams[i]) AliStream(fgkBaseInFolderName+(Long_t)i,"READ");
88cb7938 183 }
184}
185//_______________________________________________________________________
186
6c4904c2 187void AliRunDigitizer::Copy(TObject&) const
a90ecf3c 188{
1bb2a43c 189 //
190 // Non implemented copy function
191 //
594d8990 192 AliFatal("Not installed");
e2afb3b6 193}
194
e2afb3b6 195//_______________________________________________________________________
e2afb3b6 196
1bb2a43c 197AliRunDigitizer::~AliRunDigitizer()
198{
199 //
200 // dtor
201 //
88cb7938 202 delete fInputStreams;
203 delete fCombi;
204 delete fOutRunLoader;
9ce40367 205}
e2afb3b6 206//_______________________________________________________________________
9ce40367 207void AliRunDigitizer::AddDigitizer(AliDigitizer *digitizer)
208{
1bb2a43c 209 //
210 // add digitizer to the list of active digitizers
211 //
8d5e6345 212 this->Add(digitizer);
9ce40367 213}
e2afb3b6 214//_______________________________________________________________________
88cb7938 215void AliRunDigitizer::SetInputStream(Int_t i, const char *inputFile, TString foldername)
9ce40367 216{
88cb7938 217//
218// Sets the name of the input file
219//
a90ecf3c 220 if (i > fInputStreams->GetLast()) {
594d8990 221 AliError("Input stream number too high");
a90ecf3c 222 return;
9ce40367 223 }
88cb7938 224 AliStream * stream = static_cast<AliStream*>(fInputStreams->At(i)) ;
225 if ( !foldername.IsNull() ) {
226 if ( i > 0 )
227 foldername += i ; // foldername should stay unchanged for the default output
228 stream->SetFolderName(foldername) ;
229 }
230 stream->AddFile(inputFile);
9ce40367 231}
232
e2afb3b6 233//_______________________________________________________________________
8d5e6345 234void AliRunDigitizer::Digitize(Option_t* option)
9ce40367 235{
88cb7938 236// get a new combination of inputs, loads events to folders
9ce40367 237
9ce40367 238// take gAlice from the first input file. It is needed to access
239// geometry data
f042097d 240// If gAlice is already in memory, use it
88cb7938 241
d7888e54 242 if (!static_cast<AliStream*>(fInputStreams->At(0))->ImportgAlice())
88cb7938 243 {
594d8990 244 AliError("Error occured while getting gAlice from Input 0");
d7888e54 245 return;
88cb7938 246 }
247
248 if (!InitGlobal()) //calls Init() for all (sub)digitizers
249 {
594d8990 250 AliError("InitGlobal returned error");
88cb7938 251 return;
252 }
253
a90ecf3c 254 Int_t eventsCreated = 0;
8d5e6345 255// loop until there is anything on the input in case fNrOfEventsToWrite < 0
88cb7938 256 while ((eventsCreated++ < fNrOfEventsToWrite) || (fNrOfEventsToWrite < 0))
257 {
258 if (!ConnectInputTrees()) break;
259 InitEvent();//this must be after call of Connect Input tress.
260 if (fOutRunLoader)
261 {
262 fOutRunLoader->SetEventNumber(eventsCreated-1);
263 }
8de97894 264 static_cast<AliStream*>(fInputStreams->At(0))->ImportgAlice(); // use gAlice of the first input stream
88cb7938 265 ExecuteTasks(option);// loop over all registered digitizers and let them do the work
266 FinishEvent();
267 CleanTasks();
268 }
9ce40367 269 FinishGlobal();
270}
271
e2afb3b6 272//_______________________________________________________________________
a90ecf3c 273Bool_t AliRunDigitizer::ConnectInputTrees()
9ce40367 274{
1bb2a43c 275 //
276 // loads events
277 //
af7ba10c 278 Int_t eventNr[MAXSTREAMSTOMERGE], delta[MAXSTREAMSTOMERGE];
a90ecf3c 279 fCombi->Combination(eventNr, delta);
88cb7938 280 for (Int_t i=0;i<fNinputs;i++)
281 {
282 if (delta[i] == 1)
283 {
284 AliStream *iStream = static_cast<AliStream*>(fInputStreams->At(i));//gets the "i" defined in combination
285 if (!iStream->NextEventInStream()) return kFALSE; //sets serial number
286 }
287 else if (delta[i] != 0)
288 {
594d8990 289 AliError("Only delta 0 or 1 is implemented");
a90ecf3c 290 return kFALSE;
88cb7938 291 }
292 }
293
a90ecf3c 294 return kTRUE;
9ce40367 295}
296
e2afb3b6 297//_______________________________________________________________________
9ce40367 298Bool_t AliRunDigitizer::InitGlobal()
299{
1bb2a43c 300 //
301 // Method called once before Digitize() is called
302 // initialize digitizers and output
303 //
88cb7938 304 fOutputInitialized = kFALSE;
305 TList* subTasks = this->GetListOfTasks();
8d5e6345 306 if (subTasks) {
1c0b669a 307 TIter next(subTasks);
308 while (AliDigitizer * dig = (AliDigitizer *) next())
88cb7938 309 dig->Init();
310 }
9ce40367 311 return kTRUE;
312}
313
e2afb3b6 314//_______________________________________________________________________
88cb7938 315
8d5e6345 316void AliRunDigitizer::SetOutputFile(TString fn)
8d5e6345 317{
1bb2a43c 318 //
319 // The output will be to separate file,
320 // not to the signal file here should be protection
321 //to avoid setting the same file as any input
322 //
594d8990 323 AliInfo(Form("Setting Output File Name %s ",fn.Data()));
8d5e6345 324 fOutputFileName = fn;
1bb2a43c 325 // InitOutputGlobal();
8d5e6345 326}
327
e2afb3b6 328//_______________________________________________________________________
9ce40367 329Bool_t AliRunDigitizer::InitOutputGlobal()
330{
1bb2a43c 331 //
332 // Creates the output file, called by InitEvent()
333 // Needs to be called after all inputs are opened
334 //
88cb7938 335 if (fOutputInitialized) return kTRUE;
336
337 if ( !fOutputFileName.IsNull())
338 {
339 fOutRunLoader = AliRunLoader::Open(fOutputFileName,fgkDefOutFolderName,"recreate");
340
341 if (fOutRunLoader == 0x0)
342 {
594d8990 343 AliError("Can not open output");
88cb7938 344 return kFALSE;
345 }
346 Info("InitOutputGlobal", " 1 %s = ", GetInputFolderName(0).Data()) ;
347 AliRunLoader* inrl = AliRunLoader::GetRunLoader(GetInputFolderName(0));
348 if (inrl == 0x0)
349 {
594d8990 350 AliError("Can not get Run Loader Input 0. Maybe yet not initialized?");
88cb7938 351 return kFALSE;
352 }
73bbf779 353 AliDebug(2, Form(" 2 %p = ", inrl)) ;
88cb7938 354
355 //Copy all detector loaders from input 0 to output
356 const TObjArray* inloaders = inrl->GetArrayOfLoaders();
357 TIter next(inloaders);
358 AliLoader *loader;
359 while((loader = (AliLoader*)next()))
360 {
361 AliLoader* cloneloader = (AliLoader*)loader->Clone();
362 cloneloader->Register(fOutRunLoader->GetEventFolder());//creates folders for this loader in Output Folder Structure
363 GetOutRunLoader()->AddLoader(cloneloader);//adds a loader for output
364 }
365
366 fOutRunLoader->MakeTree("E");
367
594d8990 368 AliDebug(3,Form("file %s was opened.",fOutputFileName.Data()));
88cb7938 369 }
370 fOutputInitialized = kTRUE;
371 return kTRUE;
9ce40367 372}
e2afb3b6 373//_______________________________________________________________________
88cb7938 374
a90ecf3c 375void AliRunDigitizer::InitEvent()
9ce40367 376{
1bb2a43c 377 //
378 // redirects output properly
379 //
594d8990 380 AliDebug(3,Form("fEvent = %d",fEvent));
381 AliDebug(3,Form("fOutputFileName \"%s\"",fOutputFileName.Data()));
88cb7938 382 if (fOutputInitialized == kFALSE) InitOutputGlobal();
383
1bb2a43c 384 // if fOutputFileName was not given, write output to signal directory
9ce40367 385}
e2afb3b6 386//_______________________________________________________________________
88cb7938 387
a90ecf3c 388void AliRunDigitizer::FinishEvent()
9ce40367 389{
1bb2a43c 390 //
391 // called at the end of loop over digitizers
392 //
88cb7938 393
394 if (GetOutRunLoader() == 0x0)
395 {
594d8990 396 AliError("fOutRunLoader is null");
88cb7938 397 return;
398 }
399
9ce40367 400 fEvent++;
401 fNrOfEventsWritten++;
88cb7938 402
403 if (fOutRunLoader)
404 {
405 AliRunLoader* inrl = AliRunLoader::GetRunLoader(GetInputFolderName(0));
406 AliHeader* outheader = fOutRunLoader->GetHeader();
407 AliHeader* inheader = inrl->GetHeader();
408 if (inheader == 0x0)
409 {
410 inrl->LoadHeader();
411 inheader = inrl->GetHeader();
594d8990 412 if (inheader == 0x0) AliFatal("Can not get header from input 0");
88cb7938 413 }
414
415 outheader->SetNprimary(inheader->GetNprimary());
416 outheader->SetNtrack(inheader->GetNtrack());
417 outheader->SetEvent(inheader->GetEvent());
418 outheader->SetEventNrInRun(inheader->GetEventNrInRun());
419 outheader->SetNvertex(inheader->GetNvertex());
420 fOutRunLoader->TreeE()->Fill();
421 }
422
423 if (fCopyTreesFromInput > -1)
424 {
425 //this is sensless since no information would be coherent in case of merging
426 //
594d8990 427 AliWarning("Copy trees from input: Copy or link files manually");
88cb7938 428 return;
429 }
9ce40367 430}
e2afb3b6 431//_______________________________________________________________________
88cb7938 432
9ce40367 433void AliRunDigitizer::FinishGlobal()
434{
1bb2a43c 435 //
436 // called at the end of Exec
437 // save unique objects to the output file
438 //
88cb7938 439 if (GetOutRunLoader() == 0x0)
440 {
594d8990 441 AliError("Can not get RunLoader from Output Stream folder");
88cb7938 442 return;
443 }
e456dfc6 444 GetOutRunLoader()->CdGAFile();
445 this->Write(NULL, TObject::kOverwrite);
88cb7938 446 if (fOutRunLoader)
447 {
448 fOutRunLoader->WriteHeader("OVERWRITE");
449 fOutRunLoader->WriteRunLoader("OVERWRITE");
450 TFolder* outfolder = fOutRunLoader->GetEventFolder();
451 if (outfolder == 0x0)
452 {
594d8990 453 AliError("Can not get Event Folder");
88cb7938 454 return;
455 }
456
457 AliRunLoader* inRN = AliRunLoader::GetRunLoader(GetInputFolderName(0));
458 outfolder->Add(inRN->GetAliRun());
459 fOutRunLoader->WriteAliRun("OVERWRITE");
460 }
461
462 if (fCopyTreesFromInput > -1)
463 {
464 //copy files manually
465 }
9ce40367 466}
e2afb3b6 467//_______________________________________________________________________
88cb7938 468
9ae76683 469Int_t AliRunDigitizer::GetNParticles(Int_t event) const
9ce40367 470{
471// return number of particles in all input files for a given
472// event (as numbered in the output file)
473// return -1 if some file cannot be accessed
474
475 Int_t sum = 0;
476 Int_t sumI;
477 for (Int_t i = 0; i < fNinputs; i++) {
478 sumI = GetNParticles(GetInputEventNumber(event,i), i);
479 if (sumI < 0) return -1;
480 sum += sumI;
481 }
482 return sum;
483}
e2afb3b6 484//_______________________________________________________________________
88cb7938 485
d1898505 486Int_t AliRunDigitizer::GetNParticles(Int_t /*event*/, Int_t /*input*/) const
9ce40367 487{
488// return number of particles in input file input for a given
489// event (as numbered in this input file)
490// return -1 if some error
491
bd7a3098 492// Must be revised in the version with AliStream
493
494 return -1;
495
9ce40367 496}
497
e2afb3b6 498//_______________________________________________________________________
9ae76683 499Int_t* AliRunDigitizer::GetInputEventNumbers(Int_t event) const
9ce40367 500{
501// return pointer to an int array with input event numbers which were
502// merged in the output event event
503
504// simplified for now, implement later
af7ba10c 505 Int_t * a = new Int_t[MAXSTREAMSTOMERGE];
9ce40367 506 for (Int_t i = 0; i < fNinputs; i++) {
507 a[i] = event;
508 }
509 return a;
510}
e2afb3b6 511//_______________________________________________________________________
d1898505 512Int_t AliRunDigitizer::GetInputEventNumber(Int_t event, Int_t /*input*/) const
9ce40367 513{
514// return an event number of an eventInput from input file input
515// which was merged to create output event event
516
517// simplified for now, implement later
518 return event;
519}
e2afb3b6 520//_______________________________________________________________________
9ae76683 521TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t event) const
9ce40367 522{
523// return pointer to particle with index i (index with mask)
524
525// decode the MASK
526 Int_t input = i/fkMASKSTEP;
527 return GetParticle(i,input,GetInputEventNumber(event,input));
528}
529
e2afb3b6 530//_______________________________________________________________________
d1898505 531TParticle* AliRunDigitizer::GetParticle(Int_t /*i*/, Int_t /*input*/, Int_t /*event*/) const
9ce40367 532{
533// return pointer to particle with index i in the input file input
534// (index without mask)
535// event is the event number in the file input
8d5e6345 536// return 0 i fit does not exist
bd7a3098 537
538// Must be revised in the version with AliStream
9ce40367 539
bd7a3098 540 return 0;
9ce40367 541}
8d5e6345 542
e2afb3b6 543//_______________________________________________________________________
8d5e6345 544void AliRunDigitizer::ExecuteTask(Option_t* option)
545{
1bb2a43c 546 //
547 // overwrite ExecuteTask to do Digitize only
548 //
8d5e6345 549 if (!IsActive()) return;
550 Digitize(option);
551 fHasExecuted = kTRUE;
552 return;
553}
e2afb3b6 554
555//_______________________________________________________________________
88cb7938 556const TString& AliRunDigitizer::GetInputFolderName(Int_t i) const
557{
1bb2a43c 558 //
559 // Get the input Folder Name
560 //
88cb7938 561 AliStream* stream = dynamic_cast<AliStream*>(fInputStreams->At(i));
562 if (stream == 0x0)
594d8990 563 AliFatal(Form("Can not get the input stream. Index = %d. Exiting",i));
88cb7938 564 return stream->GetFolderName();
565}
566//_______________________________________________________________________
567
568const char* AliRunDigitizer::GetOutputFolderName()
569{
1bb2a43c 570 //
571 // Get output folder name
572 //
88cb7938 573 return GetOutRunLoader()->GetEventFolder()->GetName();
574}
575//_______________________________________________________________________
576
577AliRunLoader* AliRunDigitizer::GetOutRunLoader()
578{
1bb2a43c 579 //
580 // Returns Run Loader
581 //
88cb7938 582 if (fOutRunLoader) return fOutRunLoader;
583
584 if ( fOutputFileName.IsNull() )
585 {//guard that sombody calls it without settting file name
594d8990 586 AliDebug(1,"Output file name is empty. Using Input 0 for output");
88cb7938 587 return AliRunLoader::GetRunLoader(GetInputFolderName(0));
588 }
589// InitOutputGlobal();
590 return fOutRunLoader;
591}
592//_______________________________________________________________________
593
fea8896f 594TString AliRunDigitizer::GetInputFileName(Int_t input, Int_t order) const
2e3dd5e5 595{
596// returns file name of the order-th file in the input stream input
597// returns empty string if such file does not exist
598// first input stream is 0
599// first file in the input stream is 0
600 TString fileName("");
601 if (input >= fNinputs) return fileName;
602 AliStream * stream = static_cast<AliStream*>(fInputStreams->At(input));
603 if (order > stream->GetNInputFiles()) return fileName;
604 fileName = stream->GetFileName(order);
605 return fileName;
606}