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