]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliRunDigitizer.cxx
Factory method corrected, the array is now created using operator new
[u/mrichter/AliRoot.git] / STEER / AliRunDigitizer.cxx
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$
18 Revision 1.5  2001/09/20 14:35:25  jchudoba
19 Temporary disable GetParticle and GetNParticles functions
20
21 Revision 1.4  2001/09/19 06:23:50  jchudoba
22 Move some tasks to AliStream and AliMergeCombi classes
23
24 Revision 1.3  2001/07/30 14:04:18  jchudoba
25 correct bug in the initialization
26
27 Revision 1.2  2001/07/28 10:44:32  hristov
28 Loop variable declared once; typos corrected
29
30 Revision 1.1  2001/07/27 12:59:00  jchudoba
31 Manager class for merging/digitization
32
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:
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.
64 //
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.
69 //
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.
73 //
74 // Example with MUON digitizer:
75 //
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();
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"
103 #include "AliStream.h"
104 #include "AliMergeCombi.h"
105
106 ClassImp(AliRunDigitizer)
107
108 ////////////////////////////////////////////////////////////////////////
109
110 AliRunDigitizer::AliRunDigitizer() : TNamed("AliRunDigitizer","")
111 {
112 // default ctor
113   cerr<<"Don't use"<<endl;
114   fCombi = 0;
115   fInputFiles = 0;
116   fNDigitizers = 0;
117   fNinputs = 0;
118   fInputStreams = 0;
119 }
120
121 ////////////////////////////////////////////////////////////////////////
122 AliRunDigitizer::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   }
129   Int_t i;
130   for (i=0;i<MAXDETECTORS;i++) fDigitizers[i]=0;
131   fNDigitizers = 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;
138     fCombination[i]=-1;
139   }
140   fkMASKSTEP = 10000000;
141   fkMASK[0] = 0;
142   for (i=1;i<MAXSTREAMSTOMERGE;i++) {
143     fkMASK[i] = fkMASK[i-1] + fkMASKSTEP;
144   }
145   fInputStreams = new TClonesArray("AliStream",nInputStreams);
146   TClonesArray &lInputStreams = *fInputStreams;
147   for (i=0;i<nInputStreams;i++) {
148     new(lInputStreams[i]) AliStream();
149   }
150   fInputFiles = new TClonesArray("TFile",1);
151   fOutput = 0;
152   fEvent = 0;
153   fNrOfEventsToWrite = 0;
154   fNrOfEventsWritten = 0;
155   fCopyTreesFromInput = -1;
156   fCombi = new AliMergeCombi(nInputStreams,sperb);
157   fDebug = 3;
158   if (GetDebug()>2) 
159     cerr<<"AliRunDigitizer::AliRunDigitizer() called"<<endl;
160 }
161
162 ////////////////////////////////////////////////////////////////////////
163
164 AliRunDigitizer::~AliRunDigitizer() {
165 // dtor
166
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
180 }
181
182 ////////////////////////////////////////////////////////////////////////
183 void 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
198 void AliRunDigitizer::SetInputStream(Int_t i, char *inputFile)
199 {
200   if (i > fInputStreams->GetLast()) {
201     Error("SetInputStream","Input stream number too high");
202     return;
203   }
204   static_cast<AliStream*>(fInputStreams->At(i))->AddFile(inputFile);
205 }
206
207 ////////////////////////////////////////////////////////////////////////
208 void 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
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();
227     ConnectInputTrees();
228     InitEvent();
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     }
233     FinishEvent();
234   }
235   FinishGlobal();
236 }
237
238 ////////////////////////////////////////////////////////////////////////
239 Bool_t AliRunDigitizer::ConnectInputTrees()
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
245   TTree *tree;
246   char treeName[20];
247   Int_t serialNr;
248   Int_t eventNr[MAXSTREAMSTOMERGE], delta[MAXSTREAMSTOMERGE];
249   fCombi->Combination(eventNr, delta);
250   for (Int_t i=0;i<fNinputs;i++) {
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;
269 }
270
271 ////////////////////////////////////////////////////////////////////////
272 Bool_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 ////////////////////////////////////////////////////////////////////////
284 Bool_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 ////////////////////////////////////////////////////////////////////////
302 void AliRunDigitizer::InitEvent()
303 {
304 // Creates TreeDxx in the output file, called from Digitize() once for 
305 //  each event. xx = fEvent
306
307   if (GetDebug()>2) 
308     cerr<<"AliRunDigitizer::InitEvent: fEvent = "<<fEvent<<endl;
309   fOutput->cd();
310   char hname[30];
311   sprintf(hname,"TreeD%d",fEvent);
312   fTreeD = new TTree(hname,"Digits");
313   fTreeD->Write();   // Do I have to write it here???
314 }
315
316 ////////////////////////////////////////////////////////////////////////
317 void AliRunDigitizer::FinishEvent()
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 ////////////////////////////////////////////////////////////////////////
338 void 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 ////////////////////////////////////////////////////////////////////////
355 Int_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 ////////////////////////////////////////////////////////////////////////
372 Int_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
378 // Must be revised in the version with AliStream
379
380   return -1;
381
382 /*
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();
407 */
408 }
409
410 ////////////////////////////////////////////////////////////////////////
411 Int_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
417   Int_t * a = new Int_t[MAXSTREAMSTOMERGE];
418   for (Int_t i = 0; i < fNinputs; i++) {
419     a[i] = event;
420   }
421   return a;
422 }
423 ////////////////////////////////////////////////////////////////////////
424 Int_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 }
432 ////////////////////////////////////////////////////////////////////////
433 TParticle* 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 ////////////////////////////////////////////////////////////////////////
443 TParticle* 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
448 // return 0 if it does not exist
449
450 // Must be revised in the version with AliStream
451
452   return 0;
453 /*
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();
494   Int_t bytesRead = tK->GetEntry(entry);
495 //  new ((*fParticles)[nentries]) TParticle(*fParticleBuffer);
496   if (bytesRead)
497     return particleBuffer;
498   return  0;
499 */
500 }
501 ////////////////////////////////////////////////////////////////////////
502