Coverity
[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     return *this;
237   }
238
239   fGasGain          = p.fGasGain;
240   fNoise            = p.fNoise;
241   fChipGain         = p.fChipGain;
242   fADCoutRange      = p.fADCoutRange;
243   fADCinRange       = p.fADCinRange;
244   fADCbaseline      = p.fADCbaseline;
245   fDiffusionOn      = p.fDiffusionOn;
246   fElAttachOn       = p.fElAttachOn;
247   fElAttachProp     = p.fElAttachProp;
248   fTRFOn            = p.fTRFOn;
249   fTRFsmp           = 0;
250   fTRFbin           = p.fTRFbin;
251   fTRFlo            = p.fTRFlo;
252   fTRFhi            = p.fTRFhi;
253   fTRFwid           = p.fTRFwid;
254   fCTOn             = p.fCTOn;
255   fCTsmp            = 0;
256   fPadCoupling      = p.fPadCoupling;
257   fTimeCoupling     = p.fTimeCoupling;
258   fTimeStructOn     = p.fTimeStructOn;
259   fPRFOn            = p.fPRFOn;
260   fNTimeBins        = p.fNTimeBins;
261   fNTBoverwriteOCDB = p.fNTBoverwriteOCDB;
262
263   Int_t iBin = 0;
264
265   if (fTRFsmp) {
266     delete[] fTRFsmp;
267   }
268   fTRFsmp = new Float_t[fTRFbin];
269   for (iBin = 0; iBin < fTRFbin; iBin++) {
270     fTRFsmp[iBin] = ((AliTRDSimParam &) p).fTRFsmp[iBin];
271   }                                                                             
272
273   if (fCTsmp) {
274     delete[] fCTsmp;
275   }
276   fCTsmp  = new Float_t[fTRFbin];
277   for (iBin = 0; iBin < fTRFbin; iBin++) {
278     fCTsmp[iBin]  = ((AliTRDSimParam &) p).fCTsmp[iBin];
279   }                                                                             
280
281   return *this;
282
283 }
284
285 //_____________________________________________________________________________
286 void AliTRDSimParam::Copy(TObject &p) const
287 {
288   //
289   // Copy function
290   //
291   
292   AliTRDSimParam *target = dynamic_cast<AliTRDSimParam *> (&p);
293   if (!target) {
294     return;
295   }
296
297   target->fGasGain            = fGasGain;
298   target->fNoise              = fNoise;
299   target->fChipGain           = fChipGain;  
300   target->fADCoutRange        = fADCoutRange;
301   target->fADCinRange         = fADCinRange;
302   target->fADCbaseline        = fADCbaseline; 
303   target->fDiffusionOn        = fDiffusionOn; 
304   target->fElAttachOn         = fElAttachOn;
305   target->fElAttachProp       = fElAttachProp;
306   target->fTRFOn              = fTRFOn;
307   target->fTRFbin             = fTRFbin;
308   target->fTRFlo              = fTRFlo;
309   target->fTRFhi              = fTRFhi;
310   target->fTRFwid             = fTRFwid;
311   target->fCTOn               = fCTOn;
312   target->fPadCoupling        = fPadCoupling;
313   target->fTimeCoupling       = fTimeCoupling;
314   target->fPRFOn              = fPRFOn;
315   target->fNTimeBins          = fNTimeBins;
316   target->fNTBoverwriteOCDB   = fNTBoverwriteOCDB;
317
318   if (target->fTRFsmp) {
319     delete[] target->fTRFsmp;
320   }
321   target->fTRFsmp = new Float_t[fTRFbin];
322   for (Int_t iBin = 0; iBin < fTRFbin; iBin++) {
323     target->fTRFsmp[iBin] = fTRFsmp[iBin];
324   }
325
326   if (target->fCTsmp) {
327     delete[] target->fCTsmp;
328   }
329   target->fCTsmp  = new Float_t[fTRFbin];
330   for (Int_t iBin = 0; iBin < fTRFbin; iBin++) {
331     target->fCTsmp[iBin]  = fCTsmp[iBin];
332   }
333   
334 }
335
336 //_____________________________________________________________________________
337 void AliTRDSimParam::ReInit()
338 {
339   //
340   // Reinitializes the parameter class after a change
341   //
342
343   if      (AliTRDCommonParam::Instance()->IsXenon()) {
344     // The range and the binwidth for the sampled TRF 
345     fTRFbin = 200;
346     // Start 0.2 mus before the signal
347     fTRFlo  = -0.4;
348     // End the maximum drift time after the signal 
349     fTRFhi  =  3.58;
350     // Standard gas gain
351     fGasGain = 4000.0;
352   }
353   else if (AliTRDCommonParam::Instance()->IsArgon()) {
354     // The range and the binwidth for the sampled TRF 
355     fTRFbin  =  50;
356     // Start 0.2 mus before the signal
357     fTRFlo   =  0.02;
358     // End the maximum drift time after the signal 
359     fTRFhi   =  1.98;
360     // Higher gas gain
361     fGasGain = 8000.0;
362   }
363   else {
364     AliFatal("Not a valid gas mixture!");
365     exit(1);
366   }
367   fTRFwid = (fTRFhi - fTRFlo) / ((Float_t) fTRFbin);
368
369   // Create the sampled TRF
370   SampleTRF();
371
372 }
373
374 //_____________________________________________________________________________
375 void AliTRDSimParam::SampleTRF()
376 {
377   //
378   // Samples the new time response function.
379   //
380
381   Int_t ipasa = 0;
382
383   // Xenon
384   // From Antons measurements with Fe55 source, adjusted by C. Lippmann.
385   // time bins are -0.4, -0.38, -0.36, ...., 3.54, 3.56, 3.58 microseconds
386   const Int_t kNpasa     = 200;  // kNpasa should be equal to fTRFbin!
387   Float_t xtalk[kNpasa];
388   Float_t signal[kNpasa]     = { 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000
389                                , 0.0002, 0.0007, 0.0026, 0.0089, 0.0253, 0.0612, 0.1319
390                                , 0.2416, 0.3913, 0.5609, 0.7295, 0.8662, 0.9581, 1.0000
391                                , 0.9990, 0.9611, 0.8995, 0.8269, 0.7495, 0.6714, 0.5987
392                                , 0.5334, 0.4756, 0.4249, 0.3811, 0.3433, 0.3110, 0.2837
393                                , 0.2607, 0.2409, 0.2243, 0.2099, 0.1974, 0.1868, 0.1776
394                                , 0.1695, 0.1627, 0.1566, 0.1509, 0.1457, 0.1407, 0.1362
395                                , 0.1317, 0.1274, 0.1233, 0.1196, 0.1162, 0.1131, 0.1102
396                                , 0.1075, 0.1051, 0.1026, 0.1004, 0.0979, 0.0956, 0.0934
397                                , 0.0912, 0.0892, 0.0875, 0.0858, 0.0843, 0.0829, 0.0815
398                                , 0.0799, 0.0786, 0.0772, 0.0757, 0.0741, 0.0729, 0.0718
399                                , 0.0706, 0.0692, 0.0680, 0.0669, 0.0655, 0.0643, 0.0630
400                                , 0.0618, 0.0607, 0.0596, 0.0587, 0.0576, 0.0568, 0.0558
401                                , 0.0550, 0.0541, 0.0531, 0.0522, 0.0513, 0.0505, 0.0497
402                                , 0.0490, 0.0484, 0.0474, 0.0465, 0.0457, 0.0449, 0.0441
403                                , 0.0433, 0.0425, 0.0417, 0.0410, 0.0402, 0.0395, 0.0388
404                                , 0.0381, 0.0374, 0.0368, 0.0361, 0.0354, 0.0348, 0.0342
405                                , 0.0336, 0.0330, 0.0324, 0.0318, 0.0312, 0.0306, 0.0301
406                                , 0.0296, 0.0290, 0.0285, 0.0280, 0.0275, 0.0270, 0.0265
407                                , 0.0260, 0.0256, 0.0251, 0.0246, 0.0242, 0.0238, 0.0233
408                                , 0.0229, 0.0225, 0.0221, 0.0217, 0.0213, 0.0209, 0.0206
409                                , 0.0202, 0.0198, 0.0195, 0.0191, 0.0188, 0.0184, 0.0181
410                                , 0.0178, 0.0175, 0.0171, 0.0168, 0.0165, 0.0162, 0.0159
411                                , 0.0157, 0.0154, 0.0151, 0.0148, 0.0146, 0.0143, 0.0140
412                                , 0.0138, 0.0135, 0.0133, 0.0131, 0.0128, 0.0126, 0.0124
413                                , 0.0121, 0.0119, 0.0120, 0.0115, 0.0113, 0.0111, 0.0109
414                                , 0.0107, 0.0105, 0.0103, 0.0101, 0.0100, 0.0098, 0.0096
415                                , 0.0094, 0.0092, 0.0091, 0.0089, 0.0088, 0.0086, 0.0084
416                                , 0.0083, 0.0081, 0.0080, 0.0078 };
417   signal[0] = 0.0;
418   signal[1] = 0.0;
419   signal[2] = 0.0;
420   // With undershoot, positive peak corresponds to ~3% of the main signal:
421   for (ipasa = 3; ipasa < kNpasa; ipasa++) {
422     xtalk[ipasa] = 0.2 * (signal[ipasa-2] - signal[ipasa-3]);
423   }
424   xtalk[0]  = 0.0;   
425   xtalk[1]  = 0.0;  
426   xtalk[2]  = 0.0;  
427
428   // Argon
429   // Ar measurement with Fe55 source by Anton
430   // time bins are 0.02, 0.06, 0.10, ...., 1.90, 1.94, 1.98 microseconds
431   const Int_t kNpasaAr = 50;
432   Float_t xtalkAr[kNpasaAr];
433   Float_t signalAr[kNpasaAr] = { -0.01,  0.01,  0.00,  0.00,  0.01
434                                , -0.01,  0.01,  2.15, 22.28, 55.53
435                                , 68.52, 58.21, 40.92, 27.12, 18.49
436                                , 13.42, 10.48,  8.67,  7.49,  6.55
437                                ,  5.71,  5.12,  4.63,  4.22,  3.81
438                                ,  3.48,  3.20,  2.94,  2.77,  2.63
439                                ,  2.50,  2.37,  2.23,  2.13,  2.03
440                                ,  1.91,  1.83,  1.75,  1.68,  1.63
441                                ,  1.56,  1.49,  1.50,  1.49,  1.29
442                                ,  1.19,  1.21,  1.21,  1.20,  1.10 };
443   // Normalization to maximum
444   for (ipasa = 0; ipasa < kNpasaAr; ipasa++) {
445     signalAr[ipasa] /= 68.52;
446   }
447   signalAr[0] = 0.0;
448   signalAr[1] = 0.0;
449   signalAr[2] = 0.0;
450   // With undershoot, positive peak corresponds to ~3% of the main signal:
451   for (ipasa = 3; ipasa < kNpasaAr; ipasa++) {
452     xtalkAr[ipasa] = 0.2 * (signalAr[ipasa-2] - signalAr[ipasa-3]);
453   }
454   xtalkAr[0]  = 0.0;   
455   xtalkAr[1]  = 0.0;  
456   xtalkAr[2]  = 0.0;  
457
458   if (fTRFsmp) {
459     delete [] fTRFsmp;
460   }
461   fTRFsmp = new Float_t[fTRFbin];
462
463   if (fCTsmp)  {
464     delete [] fCTsmp;
465   }
466   fCTsmp  = new Float_t[fTRFbin];
467
468   if      (AliTRDCommonParam::Instance()->IsXenon()) {
469     if (fTRFbin != kNpasa) {
470       AliError("Array mismatch (xenon)\n\n");
471     }
472   }
473   else if (AliTRDCommonParam::Instance()->IsArgon()) {
474     if (fTRFbin != kNpasaAr) {
475       AliError("Array mismatch (argon)\n\n");
476     }
477   }
478
479   for (Int_t iBin = 0; iBin < fTRFbin; iBin++) {
480     if      (AliTRDCommonParam::Instance()->IsXenon()) {
481       fTRFsmp[iBin] = signal[iBin];
482       fCTsmp[iBin]  = xtalk[iBin];
483     }
484     else if (AliTRDCommonParam::Instance()->IsArgon()) {
485       fTRFsmp[iBin] = signalAr[iBin];
486       fCTsmp[iBin]  = xtalkAr[iBin];
487     }
488   }
489
490 }
491
492 //_____________________________________________________________________________
493 Double_t AliTRDSimParam::TimeResponse(Double_t time) const
494 {
495   //
496   // Applies the preamp shaper time response
497   // (We assume a signal rise time of 0.2us = fTRFlo/2.
498   //
499
500   Double_t rt   = (time - .5*fTRFlo) / fTRFwid;
501   Int_t    iBin = (Int_t) rt; 
502   Double_t dt   = rt - iBin; 
503   if ((iBin >= 0) && (iBin+1 < fTRFbin)) {
504     return fTRFsmp[iBin] + (fTRFsmp[iBin+1] - fTRFsmp[iBin])*dt;
505   } 
506   else {
507     return 0.0;
508   }
509
510 }
511
512 //_____________________________________________________________________________
513 Double_t AliTRDSimParam::CrossTalk(Double_t time) const
514 {
515   //
516   // Applies the pad-pad capacitive cross talk
517   //
518
519   Double_t rt   = (time - fTRFlo) / fTRFwid;
520   Int_t    iBin = (Int_t) rt; 
521   Double_t dt   = rt - iBin; 
522   if ((iBin >= 0) && (iBin+1 < fTRFbin)) {
523     return fCTsmp[iBin] + (fCTsmp[iBin+1] - fCTsmp[iBin])*dt;
524   } 
525   else {
526     return 0.0;
527   }
528
529 }