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