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