]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDSimParam.cxx
Go back to 24 time bins for the time being
[u/mrichter/AliRoot.git] / TRD / AliTRDSimParam.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 /* $Id$ */
17
18 ////////////////////////////////////////////////////////////////////////////
19 //                                                                        //
20 // Class containing constant simulation parameters                        //
21 //                                                                        //
22 // Request an instance with AliTRDSimParam::Instance()                    //
23 // Then request the needed values                                         //
24 //                                                                        //
25 ////////////////////////////////////////////////////////////////////////////
26
27 #include <TMath.h>
28
29 #include "AliRun.h"
30
31 #include "AliTRDSimParam.h"
32 #include "AliTRDCommonParam.h"
33
34 ClassImp(AliTRDSimParam)
35
36 AliTRDSimParam *AliTRDSimParam::fgInstance   = 0;
37 Bool_t          AliTRDSimParam::fgTerminated = kFALSE;
38
39 //_ singleton implementation __________________________________________________
40 AliTRDSimParam* AliTRDSimParam::Instance()
41 {
42   //
43   // Singleton implementation
44   // Returns an instance of this class, it is created if neccessary
45   // 
46   
47   if (fgTerminated != kFALSE) {
48     return 0;
49   }
50
51   if (fgInstance == 0) {
52     fgInstance = new AliTRDSimParam();
53   }  
54
55   return fgInstance;
56
57 }
58
59 //_ singleton implementation __________________________________________________
60 void AliTRDSimParam::Terminate()
61 {
62   //
63   // Singleton implementation
64   // Deletes the instance of this class and sets the terminated flag,
65   // instances cannot be requested anymore
66   // This function can be called several times.
67   //
68   
69   fgTerminated = kTRUE;
70   
71   if (fgInstance != 0) {
72     delete fgInstance;
73     fgInstance = 0;
74   }
75
76 }
77
78 //_____________________________________________________________________________
79 AliTRDSimParam::AliTRDSimParam()
80   :TObject()
81   ,fGasGain(0.0)
82   ,fNoise(0.0)
83   ,fChipGain(0.0)
84   ,fADCoutRange(0.0)
85   ,fADCinRange(0.0)
86   ,fADCbaseline(0)
87   ,fDiffusionOn(kFALSE)
88   ,fElAttachOn(kFALSE)
89   ,fElAttachProp(0.0)
90   ,fTRFOn(kFALSE)
91   ,fTRFsmp(0)
92   ,fTRFbin(0)
93   ,fTRFlo(0.0)
94   ,fTRFhi(0.0)
95   ,fTRFwid(0.0)
96   ,fCTOn(kFALSE)
97   ,fCTsmp(0)
98   ,fPadCoupling(0.0)
99   ,fTimeCoupling(0.0)
100   ,fTimeStructOn(kFALSE)
101   ,fPRFOn(kFALSE)
102   ,fNTimeBins(0)
103 {
104   //
105   // Default constructor
106   //
107   
108   Init();
109
110 }
111
112 //_____________________________________________________________________________
113 void AliTRDSimParam::Init()
114 {
115   // 
116   // Default initializiation
117   //
118   
119   // The default parameter for the digitization
120   fGasGain           = 4000.0;
121   fChipGain          =   12.4;
122   fNoise             = 1250.0;
123   fADCoutRange       = 1023.0;          // 10-bit ADC
124   fADCinRange        = 2000.0;          // 2V input range
125   fADCbaseline       =   10;
126
127   // Diffusion on
128   fDiffusionOn       = kTRUE;
129   
130   // Propability for electron attachment
131   fElAttachOn        = kFALSE;
132   fElAttachProp      = 0.0;
133
134   // The time response function
135   fTRFOn             = kTRUE;
136
137   // The cross talk
138   fCTOn              = kTRUE;
139
140   // The pad coupling factor
141   // Use 0.46, instead of the theroetical value 0.3, since it reproduces better 
142   // the test beam data, even tough it is not understood why.
143   fPadCoupling       = 0.46;
144
145   // The time coupling factor (same number as for the TPC)
146   fTimeCoupling      = 0.4;
147
148   // Use drift time maps
149   fTimeStructOn      = kTRUE;
150   
151   // The pad response function
152   fPRFOn             = kTRUE;
153
154   // The number of time bins
155   //fNTimeBins         = 30;
156   fNTimeBins         = 24;
157
158   ReInit();
159
160 }
161
162 //_____________________________________________________________________________
163 AliTRDSimParam::~AliTRDSimParam() 
164 {
165   //
166   // Destructor
167   //
168   
169   if (fTRFsmp) {
170     delete [] fTRFsmp;
171     fTRFsmp = 0;
172   }
173
174   if (fCTsmp) {
175     delete [] fCTsmp;
176     fCTsmp  = 0;
177   }
178
179 }
180
181 //_____________________________________________________________________________
182 AliTRDSimParam::AliTRDSimParam(const AliTRDSimParam &p)
183   :TObject(p)
184   ,fGasGain(p.fGasGain)
185   ,fNoise(p.fNoise)
186   ,fChipGain(p.fChipGain)
187   ,fADCoutRange(p.fADCoutRange)
188   ,fADCinRange(p.fADCinRange)
189   ,fADCbaseline(p.fADCbaseline)
190   ,fDiffusionOn(p.fDiffusionOn)
191   ,fElAttachOn(p.fElAttachOn)
192   ,fElAttachProp(p.fElAttachProp)
193   ,fTRFOn(p.fTRFOn)
194   ,fTRFsmp(0)
195   ,fTRFbin(p.fTRFbin)
196   ,fTRFlo(p.fTRFlo)
197   ,fTRFhi(p.fTRFhi)
198   ,fTRFwid(p.fTRFwid)
199   ,fCTOn(p.fCTOn)
200   ,fCTsmp(0)
201   ,fPadCoupling(p.fPadCoupling)
202   ,fTimeCoupling(p.fTimeCoupling)
203   ,fTimeStructOn(p.fTimeStructOn)
204   ,fPRFOn(p.fPRFOn)
205   ,fNTimeBins(p.fNTimeBins)
206 {
207   //
208   // Copy constructor
209   //
210
211   Int_t iBin = 0;
212
213   if (((AliTRDSimParam &) p).fTRFsmp) {
214     delete [] ((AliTRDSimParam &) p).fTRFsmp;
215   }
216   ((AliTRDSimParam &) p).fTRFsmp = new Float_t[fTRFbin];
217   for (iBin = 0; iBin < fTRFbin; iBin++) {
218     ((AliTRDSimParam &) p).fTRFsmp[iBin] = fTRFsmp[iBin];
219   }                                                                             
220
221   if (((AliTRDSimParam &) p).fCTsmp) {
222     delete [] ((AliTRDSimParam &) p).fCTsmp;
223   }
224   ((AliTRDSimParam &) p).fCTsmp  = new Float_t[fTRFbin];
225   for (iBin = 0; iBin < fTRFbin; iBin++) {
226     ((AliTRDSimParam &) p).fCTsmp[iBin] = fCTsmp[iBin];
227   }                                                                             
228
229 }
230
231 //_____________________________________________________________________________
232 AliTRDSimParam &AliTRDSimParam::operator=(const AliTRDSimParam &p)
233 {
234   //
235   // Assignment operator
236   //
237
238   if (this != &p) {
239     ((AliTRDSimParam &) p).Copy(*this);
240   }
241
242   return *this;
243
244 }
245
246 //_____________________________________________________________________________
247 void AliTRDSimParam::Copy(TObject &p) const
248 {
249   //
250   // Copy function
251   //
252   
253   AliTRDSimParam *target = dynamic_cast<AliTRDSimParam *> (&p);
254   if (!target) {
255     return;
256   }
257
258   target->fGasGain            = fGasGain;
259   target->fNoise              = fNoise;
260   target->fChipGain           = fChipGain;  
261   target->fADCoutRange        = fADCoutRange;
262   target->fADCinRange         = fADCinRange;
263   target->fADCbaseline        = fADCbaseline; 
264   target->fDiffusionOn        = fDiffusionOn; 
265   target->fElAttachOn         = fElAttachOn;
266   target->fElAttachProp       = fElAttachProp;
267   target->fTRFOn              = fTRFOn;
268   target->fTRFbin             = fTRFbin;
269   target->fTRFlo              = fTRFlo;
270   target->fTRFhi              = fTRFhi;
271   target->fTRFwid             = fTRFwid;
272   target->fCTOn               = fCTOn;
273   target->fPadCoupling        = fPadCoupling;
274   target->fTimeCoupling       = fTimeCoupling;
275   target->fPRFOn              = fPRFOn;
276   target->fNTimeBins          = fNTimeBins;
277
278   if (target->fTRFsmp) {
279     delete[] target->fTRFsmp;
280   }
281   target->fTRFsmp = new Float_t[fTRFbin];
282   for (Int_t iBin = 0; iBin < fTRFbin; iBin++) {
283     target->fTRFsmp[iBin] = fTRFsmp[iBin];
284   }
285
286   if (target->fCTsmp) {
287     delete[] target->fCTsmp;
288   }
289   target->fCTsmp  = new Float_t[fTRFbin];
290   for (Int_t iBin = 0; iBin < fTRFbin; iBin++) {
291     target->fCTsmp[iBin]  = fCTsmp[iBin];
292   }
293   
294 }
295
296 //_____________________________________________________________________________
297 void AliTRDSimParam::ReInit()
298 {
299   //
300   // Reinitializes the parameter class after a change
301   //
302
303   if      (AliTRDCommonParam::Instance()->IsXenon()) {
304     // The range and the binwidth for the sampled TRF 
305     fTRFbin = 200;
306     // Start 0.2 mus before the signal
307     fTRFlo  = -0.4;
308     // End the maximum drift time after the signal 
309     fTRFhi  =  3.58;
310     // Standard gas gain
311     fGasGain = 4000.0;
312   }
313   else if (AliTRDCommonParam::Instance()->IsArgon()) {
314     // The range and the binwidth for the sampled TRF 
315     fTRFbin  =  50;
316     // Start 0.2 mus before the signal
317     fTRFlo   =  0.02;
318     // End the maximum drift time after the signal 
319     fTRFhi   =  1.98;
320     // Higher gas gain
321     fGasGain = 8000.0;
322   }
323   else {
324     AliFatal("Not a valid gas mixture!");
325     exit(1);
326   }
327   fTRFwid = (fTRFhi - fTRFlo) / ((Float_t) fTRFbin);
328
329   // Create the sampled TRF
330   SampleTRF();
331
332 }
333
334 //_____________________________________________________________________________
335 void AliTRDSimParam::SampleTRF()
336 {
337   //
338   // Samples the new time response function.
339   //
340
341   Int_t ipasa = 0;
342
343   // Xenon
344   // From Antons measurements with Fe55 source, adjusted by C. Lippmann.
345   // time bins are -0.4, -0.38, -0.36, ...., 3.54, 3.56, 3.58 microseconds
346   const Int_t kNpasa     = 200;  // kNpasa should be equal to fTRFbin!
347   Float_t xtalk[kNpasa];
348   Float_t signal[kNpasa]     = { 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000
349                                , 0.0002, 0.0007, 0.0026, 0.0089, 0.0253, 0.0612, 0.1319
350                                , 0.2416, 0.3913, 0.5609, 0.7295, 0.8662, 0.9581, 1.0000
351                                , 0.9990, 0.9611, 0.8995, 0.8269, 0.7495, 0.6714, 0.5987
352                                , 0.5334, 0.4756, 0.4249, 0.3811, 0.3433, 0.3110, 0.2837
353                                , 0.2607, 0.2409, 0.2243, 0.2099, 0.1974, 0.1868, 0.1776
354                                , 0.1695, 0.1627, 0.1566, 0.1509, 0.1457, 0.1407, 0.1362
355                                , 0.1317, 0.1274, 0.1233, 0.1196, 0.1162, 0.1131, 0.1102
356                                , 0.1075, 0.1051, 0.1026, 0.1004, 0.0979, 0.0956, 0.0934
357                                , 0.0912, 0.0892, 0.0875, 0.0858, 0.0843, 0.0829, 0.0815
358                                , 0.0799, 0.0786, 0.0772, 0.0757, 0.0741, 0.0729, 0.0718
359                                , 0.0706, 0.0692, 0.0680, 0.0669, 0.0655, 0.0643, 0.0630
360                                , 0.0618, 0.0607, 0.0596, 0.0587, 0.0576, 0.0568, 0.0558
361                                , 0.0550, 0.0541, 0.0531, 0.0522, 0.0513, 0.0505, 0.0497
362                                , 0.0490, 0.0484, 0.0474, 0.0465, 0.0457, 0.0449, 0.0441
363                                , 0.0433, 0.0425, 0.0417, 0.0410, 0.0402, 0.0395, 0.0388
364                                , 0.0381, 0.0374, 0.0368, 0.0361, 0.0354, 0.0348, 0.0342
365                                , 0.0336, 0.0330, 0.0324, 0.0318, 0.0312, 0.0306, 0.0301
366                                , 0.0296, 0.0290, 0.0285, 0.0280, 0.0275, 0.0270, 0.0265
367                                , 0.0260, 0.0256, 0.0251, 0.0246, 0.0242, 0.0238, 0.0233
368                                , 0.0229, 0.0225, 0.0221, 0.0217, 0.0213, 0.0209, 0.0206
369                                , 0.0202, 0.0198, 0.0195, 0.0191, 0.0188, 0.0184, 0.0181
370                                , 0.0178, 0.0175, 0.0171, 0.0168, 0.0165, 0.0162, 0.0159
371                                , 0.0157, 0.0154, 0.0151, 0.0148, 0.0146, 0.0143, 0.0140
372                                , 0.0138, 0.0135, 0.0133, 0.0131, 0.0128, 0.0126, 0.0124
373                                , 0.0121, 0.0119, 0.0120, 0.0115, 0.0113, 0.0111, 0.0109
374                                , 0.0107, 0.0105, 0.0103, 0.0101, 0.0100, 0.0098, 0.0096
375                                , 0.0094, 0.0092, 0.0091, 0.0089, 0.0088, 0.0086, 0.0084
376                                , 0.0083, 0.0081, 0.0080, 0.0078 };
377   signal[0] = 0.0;
378   signal[1] = 0.0;
379   signal[2] = 0.0;
380   // With undershoot, positive peak corresponds to ~3% of the main signal:
381   for (ipasa = 3; ipasa < kNpasa; ipasa++) {
382     xtalk[ipasa] = 0.2 * (signal[ipasa-2] - signal[ipasa-3]);
383   }
384   xtalk[0]  = 0.0;   
385   xtalk[1]  = 0.0;  
386   xtalk[2]  = 0.0;  
387
388   // Argon
389   // Ar measurement with Fe55 source by Anton
390   // time bins are 0.02, 0.06, 0.10, ...., 1.90, 1.94, 1.98 microseconds
391   const Int_t kNpasaAr = 50;
392   Float_t xtalkAr[kNpasaAr];
393   Float_t signalAr[kNpasaAr] = { -0.01,  0.01,  0.00,  0.00,  0.01
394                                , -0.01,  0.01,  2.15, 22.28, 55.53
395                                , 68.52, 58.21, 40.92, 27.12, 18.49
396                                , 13.42, 10.48,  8.67,  7.49,  6.55
397                                ,  5.71,  5.12,  4.63,  4.22,  3.81
398                                ,  3.48,  3.20,  2.94,  2.77,  2.63
399                                ,  2.50,  2.37,  2.23,  2.13,  2.03
400                                ,  1.91,  1.83,  1.75,  1.68,  1.63
401                                ,  1.56,  1.49,  1.50,  1.49,  1.29
402                                ,  1.19,  1.21,  1.21,  1.20,  1.10 };
403   // Normalization to maximum
404   for (ipasa = 0; ipasa < kNpasaAr; ipasa++) {
405     signalAr[ipasa] /= 68.52;
406   }
407   signalAr[0] = 0.0;
408   signalAr[1] = 0.0;
409   signalAr[2] = 0.0;
410   // With undershoot, positive peak corresponds to ~3% of the main signal:
411   for (ipasa = 3; ipasa < kNpasaAr; ipasa++) {
412     xtalkAr[ipasa] = 0.2 * (signalAr[ipasa-2] - signalAr[ipasa-3]);
413   }
414   xtalkAr[0]  = 0.0;   
415   xtalkAr[1]  = 0.0;  
416   xtalkAr[2]  = 0.0;  
417
418   if (fTRFsmp) {
419     delete [] fTRFsmp;
420   }
421   fTRFsmp = new Float_t[fTRFbin];
422
423   if (fCTsmp)  {
424     delete [] fCTsmp;
425   }
426   fCTsmp  = new Float_t[fTRFbin];
427
428   if      (AliTRDCommonParam::Instance()->IsXenon()) {
429     if (fTRFbin != kNpasa) {
430       AliError("Array mismatch (xenon)\n\n");
431     }
432   }
433   else if (AliTRDCommonParam::Instance()->IsArgon()) {
434     if (fTRFbin != kNpasaAr) {
435       AliError("Array mismatch (argon)\n\n");
436     }
437   }
438
439   for (Int_t iBin = 0; iBin < fTRFbin; iBin++) {
440     if      (AliTRDCommonParam::Instance()->IsXenon()) {
441       fTRFsmp[iBin] = signal[iBin];
442       fCTsmp[iBin]  = xtalk[iBin];
443     }
444     else if (AliTRDCommonParam::Instance()->IsArgon()) {
445       fTRFsmp[iBin] = signalAr[iBin];
446       fCTsmp[iBin]  = xtalkAr[iBin];
447     }
448   }
449
450 }
451
452 //_____________________________________________________________________________
453 Double_t AliTRDSimParam::TimeResponse(Double_t time) const
454 {
455   //
456   // Applies the preamp shaper time response
457   // (We assume a signal rise time of 0.2us = fTRFlo/2.
458   //
459
460   Double_t rt   = (time - .5*fTRFlo) / fTRFwid;
461   Int_t    iBin = (Int_t) rt; 
462   Double_t dt   = rt - iBin; 
463   if ((iBin >= 0) && (iBin+1 < fTRFbin)) {
464     return fTRFsmp[iBin] + (fTRFsmp[iBin+1] - fTRFsmp[iBin])*dt;
465   } 
466   else {
467     return 0.0;
468   }
469
470 }
471
472 //_____________________________________________________________________________
473 Double_t AliTRDSimParam::CrossTalk(Double_t time) const
474 {
475   //
476   // Applies the pad-pad capacitive cross talk
477   //
478
479   Double_t rt   = (time - fTRFlo) / fTRFwid;
480   Int_t    iBin = (Int_t) rt; 
481   Double_t dt   = rt - iBin; 
482   if ((iBin >= 0) && (iBin+1 < fTRFbin)) {
483     return fCTsmp[iBin] + (fCTsmp[iBin+1] - fCTsmp[iBin])*dt;
484   } 
485   else {
486     return 0.0;
487   }
488
489 }