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