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