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