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