Implement non default combination
[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
16/*
17$Log$
4e815361 18Revision 1.5 2001/09/20 14:35:25 jchudoba
19Temporary disable GetParticle and GetNParticles functions
20
bd7a3098 21Revision 1.4 2001/09/19 06:23:50 jchudoba
22Move some tasks to AliStream and AliMergeCombi classes
23
a90ecf3c 24Revision 1.3 2001/07/30 14:04:18 jchudoba
25correct bug in the initialization
26
af20391f 27Revision 1.2 2001/07/28 10:44:32 hristov
28Loop variable declared once; typos corrected
29
aee2ebe9 30Revision 1.1 2001/07/27 12:59:00 jchudoba
31Manager class for merging/digitization
32
9ce40367 33*/
34
35////////////////////////////////////////////////////////////////////////
36//
37// AliRunDigitizer.cxx
38//
39// Manager object for merging/digitization
40//
41// Instance of this class manages the digitization and/or merging of
42// Sdigits into Digits.
43//
44// Only one instance of this class is created in the macro:
a90ecf3c 45// AliRunDigitizer * manager =
46// new AliRunDigitizer(nInputStreams,SPERB);
47// where nInputStreams is number of input streams and SPERB is
48// signals per background variable, which determines how combinations
49// of signal and background events are generated.
9ce40367 50// Then instances of specific detector digitizers are created:
51// AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager)
a90ecf3c 52// and the I/O configured (you have to specify input files
53// and an output file). The manager connects appropriate trees from
54// the input files according a combination returned by AliMergeCombi
55// classcreates. It creates TreeD in the output and runs once per
56// event Digitize method of all existing AliDetDigitizers
57// (without any option). AliDetDigitizers ask manager
58// for a TTree with input (manager->GetInputTreeS(Int_t i),
9ce40367 59// merge all inputs, digitize it, and save it in the TreeD
60// obtained by manager->GetTreeD(). Output events are stored with
61// numbers from 0, this default can be changed by
62// manager->SetFirstOutputEventNr(Int_t) method. The particle numbers
63// in the output are shifted by MASK, which is taken from manager.
64//
a90ecf3c 65// Single input file is permitted. Maximum MAXSTREAMSTOMERGE can be merged.
9ce40367 66// Input from the memory (on-the-fly merging) is not yet
67// supported, as well as access to the input data by invoking methods
68// on the output data.
69//
a90ecf3c 70// Access to the some data is via gAlice for now (supposing the
71// same geometry in all input files), gAlice is taken from the first
72// input file on the first stream.
9ce40367 73//
74// Example with MUON digitizer:
75//
a90ecf3c 76// AliRunDigitizer * manager = new AliRunDigitizer(2,1);
77// manager->SetInputStream(0,"1track_10events_phi45_60.root");
78// manager->SetInputStream(1,"1track_10events_phi120_135.root");
79// manager->SetOutputDir("/tmp");
80// manager->SetOutputFile("digits.root");
81// AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager);
82// manager->SetNrOfEventsToWrite(1);
83// manager->Digitize();
9ce40367 84//
85////////////////////////////////////////////////////////////////////////
86
87// system includes
88
89#include <iostream.h>
90
91// ROOT includes
92
93#include "TFile.h"
94#include "TTree.h"
95
96// AliROOT includes
97
98#include "AliRunDigitizer.h"
99#include "AliDigitizer.h"
100#include "AliRun.h"
101#include "AliHeader.h"
102#include "TParticle.h"
a90ecf3c 103#include "AliStream.h"
104#include "AliMergeCombi.h"
9ce40367 105
106ClassImp(AliRunDigitizer)
107
108////////////////////////////////////////////////////////////////////////
109
a90ecf3c 110AliRunDigitizer::AliRunDigitizer() : TNamed("AliRunDigitizer","")
9ce40367 111{
112// default ctor
a90ecf3c 113 cerr<<"Don't use"<<endl;
114 fCombi = 0;
115 fInputFiles = 0;
116 fNDigitizers = 0;
117 fNinputs = 0;
118 fInputStreams = 0;
119}
9ce40367 120
a90ecf3c 121////////////////////////////////////////////////////////////////////////
122AliRunDigitizer::AliRunDigitizer(Int_t nInputStreams, Int_t sperb) : TNamed("AliRunDigitizer","")
123{
124// default ctor
125 if (nInputStreams == 0) {
126 Error("AliRunDigitizer","Specify nr of input streams");
127 return;
128 }
aee2ebe9 129 Int_t i;
aee2ebe9 130 for (i=0;i<MAXDETECTORS;i++) fDigitizers[i]=0;
9ce40367 131 fNDigitizers = 0;
a90ecf3c 132 fNinputs = nInputStreams;
9ce40367 133 fOutputFileName = "digits.root";
134 fOutputDirName = "/tmp/";
a90ecf3c 135 fCombination.Set(MAXSTREAMSTOMERGE);
136 for (i=0;i<MAXSTREAMSTOMERGE;i++) {
9ce40367 137 fArrayTreeS[i]=fArrayTreeH[i]=fArrayTreeTPCS[i]=NULL;
138 fCombination[i]=-1;
139 }
140 fkMASKSTEP = 10000000;
141 fkMASK[0] = 0;
a90ecf3c 142 for (i=1;i<MAXSTREAMSTOMERGE;i++) {
9ce40367 143 fkMASK[i] = fkMASK[i-1] + fkMASKSTEP;
144 }
a90ecf3c 145 fInputStreams = new TClonesArray("AliStream",nInputStreams);
146 TClonesArray &lInputStreams = *fInputStreams;
147 for (i=0;i<nInputStreams;i++) {
148 new(lInputStreams[i]) AliStream();
149 }
9ce40367 150 fInputFiles = new TClonesArray("TFile",1);
9ce40367 151 fOutput = 0;
152 fEvent = 0;
153 fNrOfEventsToWrite = 0;
154 fNrOfEventsWritten = 0;
155 fCopyTreesFromInput = -1;
a90ecf3c 156 fCombi = new AliMergeCombi(nInputStreams,sperb);
9ce40367 157 fDebug = 3;
158 if (GetDebug()>2)
159 cerr<<"AliRunDigitizer::AliRunDigitizer() called"<<endl;
160}
161
162////////////////////////////////////////////////////////////////////////
163
164AliRunDigitizer::~AliRunDigitizer() {
165// dtor
166
a90ecf3c 167 if (fInputFiles) {
168 delete fInputFiles;
169 fInputFiles = 0;
170 }
171 if (fInputStreams) {
172 delete fInputStreams;
173 fInputStreams = 0;
174 }
175 if (fCombi) {
176 delete fCombi;
177 fCombi = 0;
178 }
179
9ce40367 180}
181
182////////////////////////////////////////////////////////////////////////
183void AliRunDigitizer::AddDigitizer(AliDigitizer *digitizer)
184{
185// add digitizer to the list of active digitizers
186
187 if (fNDigitizers >= MAXDETECTORS) {
188 cerr<<"Too many detectors to digitize. Increase value of MAXDETECTORS"
189 <<" constant in AliRunDigitizer.h and recompile or decrease the"
190 <<" the number of detectors"<<endl;
191 } else {
192 fDigitizers[fNDigitizers++] = digitizer;
193 }
194}
195
196////////////////////////////////////////////////////////////////////////
197
a90ecf3c 198void AliRunDigitizer::SetInputStream(Int_t i, char *inputFile)
9ce40367 199{
a90ecf3c 200 if (i > fInputStreams->GetLast()) {
201 Error("SetInputStream","Input stream number too high");
202 return;
9ce40367 203 }
a90ecf3c 204 static_cast<AliStream*>(fInputStreams->At(i))->AddFile(inputFile);
9ce40367 205}
206
207////////////////////////////////////////////////////////////////////////
208void AliRunDigitizer::Digitize()
209{
210// get a new combination of inputs, connect input trees and loop
211// over all digitizers
212
213 if (!InitGlobal()) {
214 cerr<<"False from InitGlobal"<<endl;
215 return;
216 }
217// take gAlice from the first input file. It is needed to access
218// geometry data
a90ecf3c 219 if (!static_cast<AliStream*>(fInputStreams->At(0))->ImportgAlice()) {
220 cerr<<"gAlice object not found in the first file of "
221 <<"the 1st stream"<<endl;
222 return;
223 }
224 Int_t eventsCreated = 0;
225 while (eventsCreated++ < fNrOfEventsToWrite) {
226// if (GetDebug()>2) PrintCombination();
9ce40367 227 ConnectInputTrees();
a90ecf3c 228 InitEvent();
9ce40367 229// loop over all registered digitizers and let them do the work
230 for (Int_t i=0;i<fNDigitizers; i++) {
231 fDigitizers[i]->Digitize();
232 }
a90ecf3c 233 FinishEvent();
9ce40367 234 }
235 FinishGlobal();
236}
237
238////////////////////////////////////////////////////////////////////////
a90ecf3c 239Bool_t AliRunDigitizer::ConnectInputTrees()
9ce40367 240{
241// fill arrays fArrayTreeS, fArrayTreeH and fArrayTreeTPCS with
242// pointers to the correct events according fCombination values
243// null pointers can be in the output, AliDigitizer has to check it
244
9ce40367 245 TTree *tree;
246 char treeName[20];
a90ecf3c 247 Int_t serialNr;
248 Int_t eventNr[MAXSTREAMSTOMERGE], delta[MAXSTREAMSTOMERGE];
249 fCombi->Combination(eventNr, delta);
9ce40367 250 for (Int_t i=0;i<fNinputs;i++) {
a90ecf3c 251 if (delta[i] == 1) {
252 AliStream *iStream = static_cast<AliStream*>(fInputStreams->At(i));
253 if (!iStream->NextEventInStream(serialNr)) return kFALSE;
254 sprintf(treeName,"TreeS%d",serialNr);
255 tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
256 fArrayTreeS[i] = tree;
257 sprintf(treeName,"TreeH%d",serialNr);
258 tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
259 fArrayTreeH[i] = tree;
260 sprintf(treeName,"TreeS_75x40_100x60_%d",serialNr);
261 tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
262 fArrayTreeTPCS[i] = tree;
263 } else if (delta[i] != 0) {
264 Error("ConnectInputTrees","Only delta 0 or 1 is implemented");
265 return kFALSE;
266 }
267 }
268 return kTRUE;
9ce40367 269}
270
271////////////////////////////////////////////////////////////////////////
272Bool_t AliRunDigitizer::InitGlobal()
273{
274// called once before Digitize() is called, initialize digitizers and output
275
276 if (!InitOutputGlobal()) return kFALSE;
277 for (Int_t i=0;i<fNDigitizers; i++) {
278 if (!fDigitizers[i]->Init()) return kFALSE;
279 }
280 return kTRUE;
281}
282
283////////////////////////////////////////////////////////////////////////
284Bool_t AliRunDigitizer::InitOutputGlobal()
285{
286// Creates the output file, called once by InitGlobal()
287
288 TString fn;
289 fn = fOutputDirName + '/' + fOutputFileName;
290 fOutput = new TFile(fn,"recreate");
291 if (GetDebug()>2) {
292 cerr<<"file "<<fn.Data()<<" was opened"<<endl;
293 cerr<<"fOutput = "<<fOutput<<endl;
294 }
295 if (fOutput) return kTRUE;
296 Error("InitOutputGlobal","Could not create output file.");
297 return kFALSE;
298}
299
300
301////////////////////////////////////////////////////////////////////////
a90ecf3c 302void AliRunDigitizer::InitEvent()
9ce40367 303{
304// Creates TreeDxx in the output file, called from Digitize() once for
305// each event. xx = fEvent
306
307 if (GetDebug()>2)
a90ecf3c 308 cerr<<"AliRunDigitizer::InitEvent: fEvent = "<<fEvent<<endl;
9ce40367 309 fOutput->cd();
310 char hname[30];
311 sprintf(hname,"TreeD%d",fEvent);
312 fTreeD = new TTree(hname,"Digits");
a90ecf3c 313 fTreeD->Write(); // Do I have to write it here???
9ce40367 314}
315
316////////////////////////////////////////////////////////////////////////
a90ecf3c 317void AliRunDigitizer::FinishEvent()
9ce40367 318{
319// called at the end of loop over digitizers
320
321 fOutput->cd();
322 if (fCopyTreesFromInput > -1) {
323 char treeName[20];
324 Int_t i = fCopyTreesFromInput;
325 sprintf(treeName,"TreeK%d",fCombination[i]);
326 ((TFile*)fInputFiles->At(i))->Get(treeName)->Clone()->Write();
327 sprintf(treeName,"TreeH%d",fCombination[i]);
328 ((TFile*)fInputFiles->At(i))->Get(treeName)->Clone()->Write();
329 }
330 fEvent++;
331 fNrOfEventsWritten++;
332 if (fTreeD) {
333 delete fTreeD;
334 fTreeD = 0;
335 }
336}
337////////////////////////////////////////////////////////////////////////
338void AliRunDigitizer::FinishGlobal()
339{
340// called at the end of Exec
341// save unique objects to the output file
342
343 fOutput->cd();
344 this->Write();
345 if (fCopyTreesFromInput > -1) {
346 ((TFile*)fInputFiles->At(fCopyTreesFromInput))->Get("TE")
347 ->Clone()->Write();
348 gAlice->Write();
349 }
350 fOutput->Close();
351}
352
353
354////////////////////////////////////////////////////////////////////////
355Int_t AliRunDigitizer::GetNParticles(Int_t event)
356{
357// return number of particles in all input files for a given
358// event (as numbered in the output file)
359// return -1 if some file cannot be accessed
360
361 Int_t sum = 0;
362 Int_t sumI;
363 for (Int_t i = 0; i < fNinputs; i++) {
364 sumI = GetNParticles(GetInputEventNumber(event,i), i);
365 if (sumI < 0) return -1;
366 sum += sumI;
367 }
368 return sum;
369}
370
371////////////////////////////////////////////////////////////////////////
372Int_t AliRunDigitizer::GetNParticles(Int_t event, Int_t input)
373{
374// return number of particles in input file input for a given
375// event (as numbered in this input file)
376// return -1 if some error
377
bd7a3098 378// Must be revised in the version with AliStream
379
380 return -1;
381
382/*
9ce40367 383 TFile *file = ConnectInputFile(input);
384 if (!file) {
385 Error("GetNParticles","Cannot open input file");
386 return -1;
387 }
388
389// find the header and get Nprimaries and Nsecondaries
390 TTree* tE = (TTree *)file->Get("TE") ;
391 if (!tE) {
392 Error("GetNParticles","input file does not contain TE");
393 return -1;
394 }
395 AliHeader* header;
396 header = 0;
397 tE->SetBranchAddress("Header", &header);
398 if (!tE->GetEntry(event)) {
399 Error("GetNParticles","event %d not found",event);
400 return -1;
401 }
402 if (GetDebug()>2) {
403 cerr<<"Nprimary: "<< header->GetNprimary()<<endl;
404 cerr<<"Nsecondary: "<<header->GetNsecondary()<<endl;
405 }
406 return header->GetNprimary() + header->GetNsecondary();
bd7a3098 407*/
9ce40367 408}
409
410////////////////////////////////////////////////////////////////////////
411Int_t* AliRunDigitizer::GetInputEventNumbers(Int_t event)
412{
413// return pointer to an int array with input event numbers which were
414// merged in the output event event
415
416// simplified for now, implement later
4e815361 417 Int_t * a = new Int_t[MAXSTREAMSTOMERGE];
9ce40367 418 for (Int_t i = 0; i < fNinputs; i++) {
419 a[i] = event;
420 }
421 return a;
422}
423////////////////////////////////////////////////////////////////////////
424Int_t AliRunDigitizer::GetInputEventNumber(Int_t event, Int_t input)
425{
426// return an event number of an eventInput from input file input
427// which was merged to create output event event
428
429// simplified for now, implement later
430 return event;
431}
9ce40367 432////////////////////////////////////////////////////////////////////////
433TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t event)
434{
435// return pointer to particle with index i (index with mask)
436
437// decode the MASK
438 Int_t input = i/fkMASKSTEP;
439 return GetParticle(i,input,GetInputEventNumber(event,input));
440}
441
442////////////////////////////////////////////////////////////////////////
443TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t input, Int_t event)
444{
445// return pointer to particle with index i in the input file input
446// (index without mask)
447// event is the event number in the file input
bd7a3098 448// return 0 if it does not exist
449
450// Must be revised in the version with AliStream
9ce40367 451
bd7a3098 452 return 0;
453/*
9ce40367 454 TFile *file = ConnectInputFile(input);
455 if (!file) {
456 Error("GetParticle","Cannot open input file");
457 return 0;
458 }
459
460// find the header and get Nprimaries and Nsecondaries
461 TTree* tE = (TTree *)file->Get("TE") ;
462 if (!tE) {
463 Error("GetParticle","input file does not contain TE");
464 return 0;
465 }
466 AliHeader* header;
467 header = 0;
468 tE->SetBranchAddress("Header", &header);
469 if (!tE->GetEntry(event)) {
470 Error("GetParticle","event %d not found",event);
471 return 0;
472 }
473
474// connect TreeK
475 char treeName[30];
476 sprintf(treeName,"TreeK%d",event);
477 TTree* tK = static_cast<TTree*>(file->Get(treeName));
478 if (!tK) {
479 Error("GetParticle","input file does not contain TreeK%d",event);
480 return 0;
481 }
482 TParticle *particleBuffer;
483 particleBuffer = 0;
484 tK->SetBranchAddress("Particles", &particleBuffer);
485
486
487// algorithmic way of getting entry index
488// (primary particles are filled after secondaries)
489 Int_t entry;
490 if (i<header->GetNprimary())
491 entry = i+header->GetNsecondary();
492 else
493 entry = i-header->GetNprimary();
9ce40367 494 Int_t bytesRead = tK->GetEntry(entry);
495// new ((*fParticles)[nentries]) TParticle(*fParticleBuffer);
496 if (bytesRead)
497 return particleBuffer;
498 return 0;
bd7a3098 499*/
9ce40367 500}
501////////////////////////////////////////////////////////////////////////
502