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