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