1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 Revision 1.3 2001/07/30 14:04:18 jchudoba
19 correct bug in the initialization
21 Revision 1.2 2001/07/28 10:44:32 hristov
22 Loop variable declared once; typos corrected
24 Revision 1.1 2001/07/27 12:59:00 jchudoba
25 Manager class for merging/digitization
29 ////////////////////////////////////////////////////////////////////////
31 // AliRunDigitizer.cxx
33 // Manager object for merging/digitization
35 // Instance of this class manages the digitization and/or merging of
36 // Sdigits into Digits.
38 // Only one instance of this class is created in the macro:
39 // AliRunDigitizer * manager =
40 // new AliRunDigitizer(nInputStreams,SPERB);
41 // where nInputStreams is number of input streams and SPERB is
42 // signals per background variable, which determines how combinations
43 // of signal and background events are generated.
44 // Then instances of specific detector digitizers are created:
45 // AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager)
46 // and the I/O configured (you have to specify input files
47 // and an output file). The manager connects appropriate trees from
48 // the input files according a combination returned by AliMergeCombi
49 // classcreates. It creates TreeD in the output and runs once per
50 // event Digitize method of all existing AliDetDigitizers
51 // (without any option). AliDetDigitizers ask manager
52 // for a TTree with input (manager->GetInputTreeS(Int_t i),
53 // merge all inputs, digitize it, and save it in the TreeD
54 // obtained by manager->GetTreeD(). Output events are stored with
55 // numbers from 0, this default can be changed by
56 // manager->SetFirstOutputEventNr(Int_t) method. The particle numbers
57 // in the output are shifted by MASK, which is taken from manager.
59 // Single input file is permitted. Maximum MAXSTREAMSTOMERGE can be merged.
60 // Input from the memory (on-the-fly merging) is not yet
61 // supported, as well as access to the input data by invoking methods
62 // on the output data.
64 // Access to the some data is via gAlice for now (supposing the
65 // same geometry in all input files), gAlice is taken from the first
66 // input file on the first stream.
68 // Example with MUON digitizer:
70 // AliRunDigitizer * manager = new AliRunDigitizer(2,1);
71 // manager->SetInputStream(0,"1track_10events_phi45_60.root");
72 // manager->SetInputStream(1,"1track_10events_phi120_135.root");
73 // manager->SetOutputDir("/tmp");
74 // manager->SetOutputFile("digits.root");
75 // AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager);
76 // manager->SetNrOfEventsToWrite(1);
77 // manager->Digitize();
79 ////////////////////////////////////////////////////////////////////////
92 #include "AliRunDigitizer.h"
93 #include "AliDigitizer.h"
95 #include "AliHeader.h"
96 #include "TParticle.h"
97 #include "AliStream.h"
98 #include "AliMergeCombi.h"
100 ClassImp(AliRunDigitizer)
102 ////////////////////////////////////////////////////////////////////////
104 AliRunDigitizer::AliRunDigitizer() : TNamed("AliRunDigitizer","")
107 cerr<<"Don't use"<<endl;
115 ////////////////////////////////////////////////////////////////////////
116 AliRunDigitizer::AliRunDigitizer(Int_t nInputStreams, Int_t sperb) : TNamed("AliRunDigitizer","")
119 if (nInputStreams == 0) {
120 Error("AliRunDigitizer","Specify nr of input streams");
124 for (i=0;i<MAXDETECTORS;i++) fDigitizers[i]=0;
126 fNinputs = nInputStreams;
127 fOutputFileName = "digits.root";
128 fOutputDirName = "/tmp/";
129 fCombination.Set(MAXSTREAMSTOMERGE);
130 for (i=0;i<MAXSTREAMSTOMERGE;i++) {
131 fArrayTreeS[i]=fArrayTreeH[i]=fArrayTreeTPCS[i]=NULL;
134 fkMASKSTEP = 10000000;
136 for (i=1;i<MAXSTREAMSTOMERGE;i++) {
137 fkMASK[i] = fkMASK[i-1] + fkMASKSTEP;
139 fInputStreams = new TClonesArray("AliStream",nInputStreams);
140 TClonesArray &lInputStreams = *fInputStreams;
141 for (i=0;i<nInputStreams;i++) {
142 new(lInputStreams[i]) AliStream();
144 fInputFiles = new TClonesArray("TFile",1);
147 fNrOfEventsToWrite = 0;
148 fNrOfEventsWritten = 0;
149 fCopyTreesFromInput = -1;
150 fCombi = new AliMergeCombi(nInputStreams,sperb);
153 cerr<<"AliRunDigitizer::AliRunDigitizer() called"<<endl;
156 ////////////////////////////////////////////////////////////////////////
158 AliRunDigitizer::~AliRunDigitizer() {
166 delete fInputStreams;
176 ////////////////////////////////////////////////////////////////////////
177 void AliRunDigitizer::AddDigitizer(AliDigitizer *digitizer)
179 // add digitizer to the list of active digitizers
181 if (fNDigitizers >= MAXDETECTORS) {
182 cerr<<"Too many detectors to digitize. Increase value of MAXDETECTORS"
183 <<" constant in AliRunDigitizer.h and recompile or decrease the"
184 <<" the number of detectors"<<endl;
186 fDigitizers[fNDigitizers++] = digitizer;
190 ////////////////////////////////////////////////////////////////////////
192 void AliRunDigitizer::SetInputStream(Int_t i, char *inputFile)
194 if (i > fInputStreams->GetLast()) {
195 Error("SetInputStream","Input stream number too high");
198 static_cast<AliStream*>(fInputStreams->At(i))->AddFile(inputFile);
201 ////////////////////////////////////////////////////////////////////////
202 void AliRunDigitizer::Digitize()
204 // get a new combination of inputs, connect input trees and loop
205 // over all digitizers
208 cerr<<"False from InitGlobal"<<endl;
211 // take gAlice from the first input file. It is needed to access
213 if (!static_cast<AliStream*>(fInputStreams->At(0))->ImportgAlice()) {
214 cerr<<"gAlice object not found in the first file of "
215 <<"the 1st stream"<<endl;
218 Int_t eventsCreated = 0;
219 while (eventsCreated++ < fNrOfEventsToWrite) {
220 // if (GetDebug()>2) PrintCombination();
223 // loop over all registered digitizers and let them do the work
224 for (Int_t i=0;i<fNDigitizers; i++) {
225 fDigitizers[i]->Digitize();
232 ////////////////////////////////////////////////////////////////////////
233 Bool_t AliRunDigitizer::ConnectInputTrees()
235 // fill arrays fArrayTreeS, fArrayTreeH and fArrayTreeTPCS with
236 // pointers to the correct events according fCombination values
237 // null pointers can be in the output, AliDigitizer has to check it
242 Int_t eventNr[MAXSTREAMSTOMERGE], delta[MAXSTREAMSTOMERGE];
243 fCombi->Combination(eventNr, delta);
244 for (Int_t i=0;i<fNinputs;i++) {
246 AliStream *iStream = static_cast<AliStream*>(fInputStreams->At(i));
247 if (!iStream->NextEventInStream(serialNr)) return kFALSE;
248 sprintf(treeName,"TreeS%d",serialNr);
249 tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
250 fArrayTreeS[i] = tree;
251 sprintf(treeName,"TreeH%d",serialNr);
252 tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
253 fArrayTreeH[i] = tree;
254 sprintf(treeName,"TreeS_75x40_100x60_%d",serialNr);
255 tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
256 fArrayTreeTPCS[i] = tree;
257 } else if (delta[i] != 0) {
258 Error("ConnectInputTrees","Only delta 0 or 1 is implemented");
265 ////////////////////////////////////////////////////////////////////////
266 Bool_t AliRunDigitizer::InitGlobal()
268 // called once before Digitize() is called, initialize digitizers and output
270 if (!InitOutputGlobal()) return kFALSE;
271 for (Int_t i=0;i<fNDigitizers; i++) {
272 if (!fDigitizers[i]->Init()) return kFALSE;
277 ////////////////////////////////////////////////////////////////////////
278 Bool_t AliRunDigitizer::InitOutputGlobal()
280 // Creates the output file, called once by InitGlobal()
283 fn = fOutputDirName + '/' + fOutputFileName;
284 fOutput = new TFile(fn,"recreate");
286 cerr<<"file "<<fn.Data()<<" was opened"<<endl;
287 cerr<<"fOutput = "<<fOutput<<endl;
289 if (fOutput) return kTRUE;
290 Error("InitOutputGlobal","Could not create output file.");
295 ////////////////////////////////////////////////////////////////////////
296 void AliRunDigitizer::InitEvent()
298 // Creates TreeDxx in the output file, called from Digitize() once for
299 // each event. xx = fEvent
302 cerr<<"AliRunDigitizer::InitEvent: fEvent = "<<fEvent<<endl;
305 sprintf(hname,"TreeD%d",fEvent);
306 fTreeD = new TTree(hname,"Digits");
307 fTreeD->Write(); // Do I have to write it here???
310 ////////////////////////////////////////////////////////////////////////
311 void AliRunDigitizer::FinishEvent()
313 // called at the end of loop over digitizers
316 if (fCopyTreesFromInput > -1) {
318 Int_t i = fCopyTreesFromInput;
319 sprintf(treeName,"TreeK%d",fCombination[i]);
320 ((TFile*)fInputFiles->At(i))->Get(treeName)->Clone()->Write();
321 sprintf(treeName,"TreeH%d",fCombination[i]);
322 ((TFile*)fInputFiles->At(i))->Get(treeName)->Clone()->Write();
325 fNrOfEventsWritten++;
331 ////////////////////////////////////////////////////////////////////////
332 void AliRunDigitizer::FinishGlobal()
334 // called at the end of Exec
335 // save unique objects to the output file
339 if (fCopyTreesFromInput > -1) {
340 ((TFile*)fInputFiles->At(fCopyTreesFromInput))->Get("TE")
348 ////////////////////////////////////////////////////////////////////////
349 Int_t AliRunDigitizer::GetNParticles(Int_t event)
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
357 for (Int_t i = 0; i < fNinputs; i++) {
358 sumI = GetNParticles(GetInputEventNumber(event,i), i);
359 if (sumI < 0) return -1;
365 ////////////////////////////////////////////////////////////////////////
366 Int_t AliRunDigitizer::GetNParticles(Int_t event, Int_t input)
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
372 TFile *file = ConnectInputFile(input);
374 Error("GetNParticles","Cannot open input file");
378 // find the header and get Nprimaries and Nsecondaries
379 TTree* tE = (TTree *)file->Get("TE") ;
381 Error("GetNParticles","input file does not contain TE");
386 tE->SetBranchAddress("Header", &header);
387 if (!tE->GetEntry(event)) {
388 Error("GetNParticles","event %d not found",event);
392 cerr<<"Nprimary: "<< header->GetNprimary()<<endl;
393 cerr<<"Nsecondary: "<<header->GetNsecondary()<<endl;
395 return header->GetNprimary() + header->GetNsecondary();
398 ////////////////////////////////////////////////////////////////////////
399 Int_t* AliRunDigitizer::GetInputEventNumbers(Int_t event)
401 // return pointer to an int array with input event numbers which were
402 // merged in the output event event
404 // simplified for now, implement later
405 Int_t a[MAXSTREAMSTOMERGE];
406 for (Int_t i = 0; i < fNinputs; i++) {
411 ////////////////////////////////////////////////////////////////////////
412 Int_t AliRunDigitizer::GetInputEventNumber(Int_t event, Int_t input)
414 // return an event number of an eventInput from input file input
415 // which was merged to create output event event
417 // simplified for now, implement later
420 ////////////////////////////////////////////////////////////////////////
421 TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t event)
423 // return pointer to particle with index i (index with mask)
426 Int_t input = i/fkMASKSTEP;
427 return GetParticle(i,input,GetInputEventNumber(event,input));
430 ////////////////////////////////////////////////////////////////////////
431 TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t input, Int_t event)
433 // return pointer to particle with index i in the input file input
434 // (index without mask)
435 // event is the event number in the file input
436 // return 0 i fit does not exist
438 TFile *file = ConnectInputFile(input);
440 Error("GetParticle","Cannot open input file");
444 // find the header and get Nprimaries and Nsecondaries
445 TTree* tE = (TTree *)file->Get("TE") ;
447 Error("GetParticle","input file does not contain TE");
452 tE->SetBranchAddress("Header", &header);
453 if (!tE->GetEntry(event)) {
454 Error("GetParticle","event %d not found",event);
460 sprintf(treeName,"TreeK%d",event);
461 TTree* tK = static_cast<TTree*>(file->Get(treeName));
463 Error("GetParticle","input file does not contain TreeK%d",event);
466 TParticle *particleBuffer;
468 tK->SetBranchAddress("Particles", &particleBuffer);
471 // algorithmic way of getting entry index
472 // (primary particles are filled after secondaries)
474 if (i<header->GetNprimary())
475 entry = i+header->GetNsecondary();
477 entry = i-header->GetNprimary();
478 Int_t bytesRead = tK->GetEntry(entry);
479 // new ((*fParticles)[nentries]) TParticle(*fParticleBuffer);
481 return particleBuffer;
484 ////////////////////////////////////////////////////////////////////////