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