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.5 2001/09/20 14:35:25 jchudoba
19 Temporary disable GetParticle and GetNParticles functions
21 Revision 1.4 2001/09/19 06:23:50 jchudoba
22 Move some tasks to AliStream and AliMergeCombi classes
24 Revision 1.3 2001/07/30 14:04:18 jchudoba
25 correct bug in the initialization
27 Revision 1.2 2001/07/28 10:44:32 hristov
28 Loop variable declared once; typos corrected
30 Revision 1.1 2001/07/27 12:59:00 jchudoba
31 Manager class for merging/digitization
35 ////////////////////////////////////////////////////////////////////////
37 // AliRunDigitizer.cxx
39 // Manager object for merging/digitization
41 // Instance of this class manages the digitization and/or merging of
42 // Sdigits into Digits.
44 // Only one instance of this class is created in the macro:
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.
50 // Then instances of specific detector digitizers are created:
51 // AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager)
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),
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.
65 // Single input file is permitted. Maximum MAXSTREAMSTOMERGE can be merged.
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.
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.
74 // Example with MUON digitizer:
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();
85 ////////////////////////////////////////////////////////////////////////
98 #include "AliRunDigitizer.h"
99 #include "AliDigitizer.h"
101 #include "AliHeader.h"
102 #include "TParticle.h"
103 #include "AliStream.h"
104 #include "AliMergeCombi.h"
106 ClassImp(AliRunDigitizer)
108 ////////////////////////////////////////////////////////////////////////
110 AliRunDigitizer::AliRunDigitizer() : TNamed("AliRunDigitizer","")
113 cerr<<"Don't use"<<endl;
121 ////////////////////////////////////////////////////////////////////////
122 AliRunDigitizer::AliRunDigitizer(Int_t nInputStreams, Int_t sperb) : TNamed("AliRunDigitizer","")
125 if (nInputStreams == 0) {
126 Error("AliRunDigitizer","Specify nr of input streams");
130 for (i=0;i<MAXDETECTORS;i++) fDigitizers[i]=0;
132 fNinputs = nInputStreams;
133 fOutputFileName = "digits.root";
134 fOutputDirName = "/tmp/";
135 fCombination.Set(MAXSTREAMSTOMERGE);
136 for (i=0;i<MAXSTREAMSTOMERGE;i++) {
137 fArrayTreeS[i]=fArrayTreeH[i]=fArrayTreeTPCS[i]=NULL;
140 fkMASKSTEP = 10000000;
142 for (i=1;i<MAXSTREAMSTOMERGE;i++) {
143 fkMASK[i] = fkMASK[i-1] + fkMASKSTEP;
145 fInputStreams = new TClonesArray("AliStream",nInputStreams);
146 TClonesArray &lInputStreams = *fInputStreams;
147 for (i=0;i<nInputStreams;i++) {
148 new(lInputStreams[i]) AliStream();
150 fInputFiles = new TClonesArray("TFile",1);
153 fNrOfEventsToWrite = 0;
154 fNrOfEventsWritten = 0;
155 fCopyTreesFromInput = -1;
156 fCombi = new AliMergeCombi(nInputStreams,sperb);
159 cerr<<"AliRunDigitizer::AliRunDigitizer() called"<<endl;
162 ////////////////////////////////////////////////////////////////////////
164 AliRunDigitizer::~AliRunDigitizer() {
172 delete fInputStreams;
182 ////////////////////////////////////////////////////////////////////////
183 void AliRunDigitizer::AddDigitizer(AliDigitizer *digitizer)
185 // add digitizer to the list of active digitizers
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;
192 fDigitizers[fNDigitizers++] = digitizer;
196 ////////////////////////////////////////////////////////////////////////
198 void AliRunDigitizer::SetInputStream(Int_t i, char *inputFile)
200 if (i > fInputStreams->GetLast()) {
201 Error("SetInputStream","Input stream number too high");
204 static_cast<AliStream*>(fInputStreams->At(i))->AddFile(inputFile);
207 ////////////////////////////////////////////////////////////////////////
208 void AliRunDigitizer::Digitize()
210 // get a new combination of inputs, connect input trees and loop
211 // over all digitizers
214 cerr<<"False from InitGlobal"<<endl;
217 // take gAlice from the first input file. It is needed to access
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;
224 Int_t eventsCreated = 0;
225 while (eventsCreated++ < fNrOfEventsToWrite) {
226 // if (GetDebug()>2) PrintCombination();
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();
238 ////////////////////////////////////////////////////////////////////////
239 Bool_t AliRunDigitizer::ConnectInputTrees()
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
248 Int_t eventNr[MAXSTREAMSTOMERGE], delta[MAXSTREAMSTOMERGE];
249 fCombi->Combination(eventNr, delta);
250 for (Int_t i=0;i<fNinputs;i++) {
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");
271 ////////////////////////////////////////////////////////////////////////
272 Bool_t AliRunDigitizer::InitGlobal()
274 // called once before Digitize() is called, initialize digitizers and output
276 if (!InitOutputGlobal()) return kFALSE;
277 for (Int_t i=0;i<fNDigitizers; i++) {
278 if (!fDigitizers[i]->Init()) return kFALSE;
283 ////////////////////////////////////////////////////////////////////////
284 Bool_t AliRunDigitizer::InitOutputGlobal()
286 // Creates the output file, called once by InitGlobal()
289 fn = fOutputDirName + '/' + fOutputFileName;
290 fOutput = new TFile(fn,"recreate");
292 cerr<<"file "<<fn.Data()<<" was opened"<<endl;
293 cerr<<"fOutput = "<<fOutput<<endl;
295 if (fOutput) return kTRUE;
296 Error("InitOutputGlobal","Could not create output file.");
301 ////////////////////////////////////////////////////////////////////////
302 void AliRunDigitizer::InitEvent()
304 // Creates TreeDxx in the output file, called from Digitize() once for
305 // each event. xx = fEvent
308 cerr<<"AliRunDigitizer::InitEvent: fEvent = "<<fEvent<<endl;
311 sprintf(hname,"TreeD%d",fEvent);
312 fTreeD = new TTree(hname,"Digits");
313 fTreeD->Write(); // Do I have to write it here???
316 ////////////////////////////////////////////////////////////////////////
317 void AliRunDigitizer::FinishEvent()
319 // called at the end of loop over digitizers
322 if (fCopyTreesFromInput > -1) {
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();
331 fNrOfEventsWritten++;
337 ////////////////////////////////////////////////////////////////////////
338 void AliRunDigitizer::FinishGlobal()
340 // called at the end of Exec
341 // save unique objects to the output file
345 if (fCopyTreesFromInput > -1) {
346 ((TFile*)fInputFiles->At(fCopyTreesFromInput))->Get("TE")
354 ////////////////////////////////////////////////////////////////////////
355 Int_t AliRunDigitizer::GetNParticles(Int_t event)
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
363 for (Int_t i = 0; i < fNinputs; i++) {
364 sumI = GetNParticles(GetInputEventNumber(event,i), i);
365 if (sumI < 0) return -1;
371 ////////////////////////////////////////////////////////////////////////
372 Int_t AliRunDigitizer::GetNParticles(Int_t event, Int_t input)
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
378 // Must be revised in the version with AliStream
383 TFile *file = ConnectInputFile(input);
385 Error("GetNParticles","Cannot open input file");
389 // find the header and get Nprimaries and Nsecondaries
390 TTree* tE = (TTree *)file->Get("TE") ;
392 Error("GetNParticles","input file does not contain TE");
397 tE->SetBranchAddress("Header", &header);
398 if (!tE->GetEntry(event)) {
399 Error("GetNParticles","event %d not found",event);
403 cerr<<"Nprimary: "<< header->GetNprimary()<<endl;
404 cerr<<"Nsecondary: "<<header->GetNsecondary()<<endl;
406 return header->GetNprimary() + header->GetNsecondary();
410 ////////////////////////////////////////////////////////////////////////
411 Int_t* AliRunDigitizer::GetInputEventNumbers(Int_t event)
413 // return pointer to an int array with input event numbers which were
414 // merged in the output event event
416 // simplified for now, implement later
417 Int_t * a = new Int_t[MAXSTREAMSTOMERGE];
418 for (Int_t i = 0; i < fNinputs; i++) {
423 ////////////////////////////////////////////////////////////////////////
424 Int_t AliRunDigitizer::GetInputEventNumber(Int_t event, Int_t input)
426 // return an event number of an eventInput from input file input
427 // which was merged to create output event event
429 // simplified for now, implement later
432 ////////////////////////////////////////////////////////////////////////
433 TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t event)
435 // return pointer to particle with index i (index with mask)
438 Int_t input = i/fkMASKSTEP;
439 return GetParticle(i,input,GetInputEventNumber(event,input));
442 ////////////////////////////////////////////////////////////////////////
443 TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t input, Int_t event)
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
448 // return 0 if it does not exist
450 // Must be revised in the version with AliStream
454 TFile *file = ConnectInputFile(input);
456 Error("GetParticle","Cannot open input file");
460 // find the header and get Nprimaries and Nsecondaries
461 TTree* tE = (TTree *)file->Get("TE") ;
463 Error("GetParticle","input file does not contain TE");
468 tE->SetBranchAddress("Header", &header);
469 if (!tE->GetEntry(event)) {
470 Error("GetParticle","event %d not found",event);
476 sprintf(treeName,"TreeK%d",event);
477 TTree* tK = static_cast<TTree*>(file->Get(treeName));
479 Error("GetParticle","input file does not contain TreeK%d",event);
482 TParticle *particleBuffer;
484 tK->SetBranchAddress("Particles", &particleBuffer);
487 // algorithmic way of getting entry index
488 // (primary particles are filled after secondaries)
490 if (i<header->GetNprimary())
491 entry = i+header->GetNsecondary();
493 entry = i-header->GetNprimary();
494 Int_t bytesRead = tK->GetEntry(entry);
495 // new ((*fParticles)[nentries]) TParticle(*fParticleBuffer);
497 return particleBuffer;
501 ////////////////////////////////////////////////////////////////////////