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