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