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