source: trunk/MagicSoft/Simulation/Detector/include-MFadc/MFadc.cxx@ 5094

Last change on this file since 5094 was 5079, checked in by moralejo, 21 years ago
*** empty log message ***
File size: 25.8 KB
Line 
1////////////////////////////////////////////////////////////////
2//
3// MFadc
4//
5//
6#include "MFadc.hxx"
7
8#include "MMcEvt.hxx"
9
10#include "TROOT.h"
11#include <TApplication.h>
12#include <TVirtualX.h>
13#include <TGClient.h>
14
15#include "TH1.h"
16#include "TObjArray.h"
17
18#include "MGFadcSignal.hxx"
19
20MFadc::MFadc(Int_t pix, Int_t shape, Float_t integral, Float_t fwhm, Int_t shapeout, Float_t integralout, Float_t fwhmout, Float_t trigger_delay) {
21 //
22 // Constructor overloaded II
23 //
24 // Input variables:
25 // 1. integral(out) = integration of the single phe response for inner
26 // (outer) pixels.
27 // 2. fwhm(out) = width at half high of the single phe response for
28 // inner (outer) pixels.
29 //
30 // trigger_delay: shift of signals towards later times in FADC, in order
31 // to center the signals in a good range. It acts as a sort of delay of
32 // the signals (before being sent to the FADC) with respect to the trigger.
33 //
34 // The procedure is the following:
35 // 1. some parameters of the trigger are set to default.
36 // this parameters of the trigger may be changed
37 // 3. Then the all signals are set to zero
38
39 numpix=pix;
40
41 fwhm_resp = fwhm;
42 integ_resp = integral;
43 fwhm_resp_outer = fwhmout;
44 integ_resp_outer = integralout;
45 shape_resp=shape;
46 shape_resp_outer=shapeout;
47
48 cout<< "[MFadc] Setting up the MFadc with this values "<< endl ;
49 cout<< "[MFadc] - Inner pixels : "<< endl ;
50 switch(shape_resp){
51 case 0:
52 cout<< "[MFadc] Pulse shape : Gaussian ("<<shape_resp<<")"<< endl ;
53 cout<< "[MFadc] Response Area : "<<integ_resp<<" adc counts"<< endl ;
54 cout<< "[MFadc] Response FWHM : "<<fwhm_resp<<" ns"<< endl ;
55 break;
56 case 1:
57 cout<< "[MFadc] Pulse shape : From Pulpo ("<<shape_resp<<")"<< endl ;
58 cout<< "[MFadc] Response Area : "<<integ_resp<<" adc counts"<< endl ;
59 break;
60 default:
61 cout<< "[MFadc] Pulse shape unknown"<<endl;
62 }
63 cout<< "[MFadc] - Outer pixels : "<< endl ;
64 switch(shape_resp_outer){
65 case 0:
66 cout<< "[MFadc] Pulse shape : Gaussian ("<<shape_resp_outer<<")"<<endl;
67 cout<< "[MFadc] Response Area : "<<integ_resp_outer<<" adc counts"<<endl;
68 cout<< "[MFadc] Response FWHM : "<<fwhm_resp_outer<<" ns"<< endl ;
69 break;
70 case 1:
71 cout<< "[MFadc] Pulse shape : From Pulpo ("<<shape_resp_outer<<")"<<endl;
72 cout<< "[MFadc] Response Area : "<<integ_resp_outer<<" adc counts"<< endl ;
73 break;
74 default:
75 cout<< "[MFadc] Pulse shape unknown ("<<shape_resp_outer<<")"<<endl;
76 }
77
78
79 //
80 // set up the response shape
81 //
82 Int_t i ;
83
84 Float_t sigma ;
85 Float_t x, x0 ;
86 Float_t dX, dX2 ;
87
88 Float_t response_sum_inner, response_sum_outer;
89 response_sum_inner = 0.;
90 response_sum_outer = 0.;
91
92 dX = WIDTH_FADC_TIMESLICE / SUBBINS ; // Units: ns
93 dX2 = dX/2. ;
94
95 switch(shape_resp){
96
97 case 0:
98 sigma = fwhm_resp / 2.35 ;
99 x0 = 3*sigma;
100 fadc_time_offset = trigger_delay-x0; // ns
101
102 for (i=0; i< RESPONSE_SLICES_MFADC ; i++ ) {
103
104 x = i * dX + dX2 ;
105
106 sing_resp[i] = expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ;
107
108 response_sum_inner += sing_resp[i];
109 }
110
111 break;
112 case 1:
113 float p1,p2,p3,p4,p5,p6,p7;
114 float d;
115 float zed_slices;
116 // Parameters values extracted from fitting a real FADC response
117 // gaussian electronic pulse passed through the whole chain from
118 // transmitter boards to FADC.
119 p1 = 2.066;
120 p2 = 1.568;
121 p3 = 3; // This sets the peak of the pulse at x ~ 3 ADC slices
122 // It is just a safe value so that the pulse is well contained.
123 p4 = 0.00282;
124 p5 = 0.04093;
125 p6 = 0.2411;
126 p7 = -0.009442;
127 // Define the time before trigger to read FADC signal when it
128 // has to be written
129 fadc_time_offset = trigger_delay-p3*WIDTH_FADC_TIMESLICE; // ns
130
131 for (i=0; i< RESPONSE_SLICES_MFADC ; i++ ) {
132 x = i * dX + dX2;
133
134 // x has to be converted from ns to units FADC slices:
135 zed_slices=x/WIDTH_FADC_TIMESLICE-p3;
136 d=(zed_slices>0)?0.5:-0.5;
137
138 sing_resp[i] = (p1*exp(-p2*(exp(-p2*zed_slices)+zed_slices))+p4+
139 p5*exp(-p2*(exp(-p2*zed_slices)+p6*zed_slices))+p7*d);
140
141 response_sum_inner += sing_resp[i];
142 }
143
144 break;
145 default:
146 cout<<"[MFadc] MFadc::MFadc : Shape of FADC pulse for inner pixel unknown."
147 <<endl;
148 cout<<"[MFadc] MFadc::MFadc : Exiting Camera ..."
149 <<endl;
150 exit(1);
151 }
152
153 // Response for outer pixels
154
155 switch(shape_resp_outer){
156
157 case 0:
158 sigma = fwhm_resp_outer / 2.35 ;
159 x0 = 3*sigma ;
160 fadc_time_offset = trigger_delay-x0; // ns
161
162 for (i=0; i< RESPONSE_SLICES_MFADC ; i++ ) {
163
164 x = i * dX + dX2 ;
165
166 //
167 // the value 1/sqrt(2*Pi*sigma^2) was introduced to normalize
168 // the area at the input value After this, the integral
169 // of the response will be integ_resp.
170 //
171 sing_resp_outer[i] = expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ;
172 response_sum_outer += sing_resp_outer[i];
173 }
174 break;
175 case 1:
176 float p1,p2,p3,p4,p5,p6,p7;
177 float d;
178 float zed_slices;
179 // Parameters values extracted from fitting a real FADC response
180 // gaussian electronic pulse passed through the whole chain from
181 // transmitter boards to FADC.
182 p1 = 2.066;
183 p2 = 1.568;
184 p3 = 3; // This sets the peak of the pulse at x ~ 3 ADC slices
185 // It is just a safe value so that the pulse is well contained.
186 p4 = 0.00282;
187 p5 = 0.04093;
188 p6 = 0.2411;
189 p7 = -0.009442;
190 // Define the time before trigger to read FADC signal when it
191 // has to be written
192 fadc_time_offset = trigger_delay-p3*WIDTH_FADC_TIMESLICE; // ns
193
194 for (i=0; i< RESPONSE_SLICES_MFADC ; i++ ) {
195 x = i * dX + dX2;
196
197 zed_slices=x/WIDTH_FADC_TIMESLICE-p3;
198 d=(zed_slices>0)?0.5:-0.5;
199
200 sing_resp_outer[i] = (p1*exp(-p2*(exp(-p2*zed_slices)+zed_slices))+p4+
201 p5*exp(-p2*(exp(-p2*zed_slices)+p6*zed_slices))+p7*d);
202 response_sum_outer += sing_resp_outer[i];
203 }
204 break;
205 default:
206 cout<<"[MFadc] MFadc::MFadc : Shape of FADC pulse for inner pixel unknown."
207 <<endl;
208 cout<<"[MFadc] MFadc::MFadc : Exiting Camera ..."
209 <<endl;
210 exit(1);
211 }
212
213 //
214 // Normalize responses to values set trhough input card: (= set gain of electronic chain)
215 // Take into account that only 1 of every SUBBINS bins of sing_resp[] will be "sampled" by
216 // the FADC, so we have to correct for this to get the right "FADC integral" (=integ_resp)
217 // per photoelectron:
218 //
219
220 for (i=0; i< RESPONSE_SLICES_MFADC ; i++ ) {
221 sing_resp[i] *= integ_resp / response_sum_inner * SUBBINS;
222 sing_resp_outer[i] *= integ_resp_outer / response_sum_outer * SUBBINS;
223 }
224
225 //
226 // init the Random Generator for Electonic Noise
227 //
228
229 GenElec = new TRandom () ;
230
231 Reset();
232
233 //
234 // set all pedestals to 0
235 //
236
237 for ( i =0 ; i <CAMERA_PIXELS ; i++ ) {
238 pedestal[i] = 0.0 ;
239 }
240
241 cout<<" end of MFadc::MFadc()"<<endl;
242}
243
244void MFadc::Reset() {
245 //
246 // set all values of the signals to zero
247 // set the values of FADC slices that would be read after trigger to zero
248 //
249 memset(used, 0, CAMERA_PIXELS*sizeof(Bool_t));
250 memset(output, 0, CAMERA_PIXELS*FADC_SLICES*sizeof(Float_t));
251 memset(output_lowgain, 0, CAMERA_PIXELS*FADC_SLICES*sizeof(Float_t));
252 //
253 // Added 15 01 2004, AM:
254 //
255 memset(sig, 0, (Int_t)(CAMERA_PIXELS*SLICES_MFADC*sizeof(Float_t)));
256}
257void MFadc::Fill( Int_t iPix, Float_t time,
258 Float_t amplitude, Int_t isinner ) {
259
260 // AM, Jan 2004 : added delay to shift the signal peak to the desired
261 // range in the FADC window (indicated through the trigger_delay command
262 // in the camera input card.
263
264 time += fadc_time_offset;
265
266 if(isinner)
267 Fill(iPix, time, amplitude);
268 else
269 FillOuter(iPix, time, amplitude);
270
271}
272void MFadc::Fill( Int_t iPix, Float_t time, Float_t amplitude ) {
273
274 //
275 // fills the information about one single Phe in the Trigger class
276 //
277 // parameter is the number of the pixel and the time-difference to the
278 // first particle
279 //
280 //
281
282 Int_t i, ichan, ichanfadc ;
283
284 //
285 // first we have to check if the pixel iPix is used or not until now
286 // if this is the first use, reset all signal for that pixels
287 //
288 if ( iPix > numpix ) {
289 cout << " WARNING: MFadc::Fill() : iPix greater than Pixels in Camera = "
290 << numpix
291 << endl ;
292 exit(987) ;
293 }
294
295 if ( used[iPix] == FALSE ) {
296 used [iPix] = TRUE ;
297
298 for (i=0; i < (Int_t) SLICES_MFADC; i++ ) {
299 sig[iPix][i] = 0. ;
300 }
301 }
302
303 //
304 // then select the time slice to use (ican)
305 //
306
307 if ( time < TOTAL_TRIGGER_TIME+fadc_time_offset ) {
308 //
309 // determine the slices number assuming the WIDTH_RESPONSE_MFADC
310 // ichan marks the start of the pulse, in number of bins of width
311 // WIDTH_RESPONSE_MFADC (2/3 of a ns), measured from the start of the
312 // FADC.
313 //
314
315 ichan = (Int_t) ( time / ((Float_t) WIDTH_RESPONSE_MFADC ));
316
317 //
318 // putting the response slices in the right sig slices.
319 // Be carefull, because both slices have different widths.
320 //
321
322 //
323 // AM, Jan 2004: Replaced former FADC simulation (integration of signal)
324 // with a more realistic one (measuring signal height at discrete points).
325 //
326
327 // We take the pulse height in the middle of FADC slices, we start in the
328 // first such point after the time "time" (=ichan in response bins). Each
329 // FADC slice corresponds to SUBBINS response bins (SUBBINS=5 by default).
330
331 Int_t first_i = Int_t(SUBBINS/2) - ichan%(Int_t)SUBBINS;
332 first_i = first_i < 0 ? (Int_t)SUBBINS+first_i : first_i;
333
334
335 for ( i = first_i ; i < (Int_t)RESPONSE_SLICES; i += (Int_t)SUBBINS) {
336 ichanfadc = (Int_t) ((ichan+i)/SUBBINS) ;
337 if ( ichanfadc < 0 )
338 continue;
339
340 //
341 // SLICES_MFADC is by default 48. sig[][] is not the true FADC, which
342 // is filled from sig[][] in MFadc::TriggeredFadc()
343 //
344 if ( (ichanfadc) < (Int_t)SLICES_MFADC ) {
345 sig[iPix][ichanfadc] += (amplitude * sing_resp[i] ) ;
346 }
347 }
348
349 }
350 else {
351 cout << " WARNING! Fadc::Fill " << time << " out of TriggerTimeRange "
352 << TOTAL_TRIGGER_TIME+fadc_time_offset << endl ;
353 }
354
355}
356
357void MFadc::FillOuter( Int_t iPix, Float_t time, Float_t amplitude ) {
358
359 //
360 // fills the information about one single Phe in the Trigger class
361 // for an outer pixel
362 //
363 // parameter is the number of the pixel and the time-difference to the
364 // first particle
365 //
366 //
367
368 Int_t i, ichan, ichanfadc ;
369
370 //
371 // first we have to check if the pixel iPix is used or not until now
372 // if this is the first use, reset all signal for that pixels
373 //
374 if ( iPix > numpix ) {
375 cout << " WARNING: MFadc::FillOuter() : iPix greater than CAMERA_PIXELS"
376 << endl ;
377 exit(987) ;
378 }
379
380 if ( used[iPix] == FALSE ) {
381 used [iPix] = TRUE ;
382
383 for (i=0; i < (Int_t) SLICES_MFADC; i++ ) {
384 sig[iPix][i] = 0. ;
385 }
386 }
387
388 //
389 // then select the time slice to use (ican)
390 //
391
392
393 if ( time < TOTAL_TRIGGER_TIME+fadc_time_offset ) {
394 //
395 // determine the slices number assuming the WIDTH_RESPONSE_MFADC
396 //
397 ichan = (Int_t) ( time / ((Float_t) WIDTH_RESPONSE_MFADC ));
398
399 //
400 // putting the response slices in the right sig slices.
401 // Be carefull, because both slices have different widths.
402 //
403
404 //
405 // AM, Jan 2004: Replaced former FADC simulation (integration of signal)
406 // with a more realistic one (measuring signal height at discrete points).
407 //
408
409 // We take the pulse height in the middle of FADC slices, we start in the
410 // first such point after the time "time" (=ichan in response bins). Each
411 // FADC slice corresponds to SUBBINS response bins (SUBBINS=5 by default).
412
413 Int_t first_i = Int_t(SUBBINS/2) - ichan%(Int_t)SUBBINS;
414 first_i = first_i < 0 ? (Int_t)SUBBINS+first_i : first_i;
415
416 for ( i = first_i ; i < (Int_t)RESPONSE_SLICES; i += (Int_t)SUBBINS) {
417 ichanfadc = (Int_t) ((ichan+i)/SUBBINS) ;
418
419 if ( ichanfadc < 0 )
420 continue;
421
422 if ( (ichanfadc) < (Int_t)SLICES_MFADC ) {
423 sig[iPix][ichanfadc] += (amplitude * sing_resp_outer[i] ) ;
424 }
425 }
426
427 }
428 else {
429 cout << " WARNING! Fadc::FillOuter " << time << " out of TriggerTimeRange "
430 << TOTAL_TRIGGER_TIME+fadc_time_offset << endl ;
431 }
432
433}
434
435void MFadc::Set( Int_t iPix, Float_t resp[(Int_t) SLICES_MFADC]) {
436
437 //
438 // Sets the information about fadc reponse from a given array
439 //
440 // parameter is the number of the pixel and the values to be set
441 //
442 //
443
444 Int_t i ;
445
446 //
447 // first we have to check if the pixel iPix is used or not until now
448 // if this is the first use, reset all signal for that pixels
449 //
450 if ( iPix > numpix ) {
451 cout << " WARNING: MFadc::Fill() : iPix greater than CAMERA_PIXELS"
452 << endl ;
453 exit(987) ;
454 }
455
456 if ( used[iPix] == FALSE ) {
457 used [iPix] = TRUE ;
458
459 for (i=0; i < (Int_t)SLICES_MFADC; i++ ) {
460 sig[iPix][i] = 0. ;
461 }
462 }
463 for ( i = 0 ; i<(Int_t)SLICES_MFADC; i++ ) {
464 sig[iPix][i] = resp[i] ;
465 }
466
467}
468
469void MFadc::AddSignal( Int_t iPix, Float_t resp[(Int_t) SLICES_MFADC]) {
470
471 //
472 // Adds signals to the fadc reponse from a given array
473 //
474 // parameters are the number of the pixel and the values to be added
475 //
476 //
477
478 Int_t i ;
479
480 //
481 // first we have to check if the pixel iPix is used or not until now
482 // if this is the first use, reset all signal for that pixels
483 //
484 if ( iPix > numpix ) {
485 cout << " WARNING: MFadc::Fill() : iPix greater than CAMERA_PIXELS"
486 << endl ;
487 exit(987) ;
488 }
489
490 if ( used[iPix] == FALSE ) {
491 used [iPix] = TRUE ;
492
493 for (i=0; i < (Int_t)SLICES_MFADC; i++ ) {
494 sig[iPix][i] = 0. ;
495 }
496 }
497 for ( i = 0 ; i<(Int_t)SLICES_MFADC; i++ ) {
498 sig[iPix][i] += resp[i] ;
499 }
500
501}
502
503void MFadc::SetPedestals( Int_t ped) {
504 // It sets pedestal for each pixel flat randomly dstributed between 0 and ped
505 // It uses the instance of TRandom GenElec.
506
507 Int_t i;
508
509 for(i=0;i<numpix;i++){
510 pedestal[i]= (Float_t)(ped* GenElec->Rndm());
511 }
512}
513
514void MFadc::SetPedestals( Float_t *ped) {
515 // It sets pedestal for each pixel from ped array
516
517 Int_t i;
518
519 for(i=0;i<numpix;i++){
520 pedestal[i]= ped[i];
521 }
522}
523
524
525void MFadc::Baseline(){
526 //
527 // It simulates the AC behaviour
528
529 int i,j;
530 Float_t baseline;
531
532 for(j=0;j<numpix;j++){
533 baseline=0.0;
534 for(i=0;i<(Int_t) SLICES_MFADC;i++){
535 baseline+=sig[j][i];
536 }
537 baseline=baseline/SLICES_MFADC;
538 for(i=0;i<(Int_t) SLICES_MFADC;i++){
539 sig[j][i]=-baseline;
540 }
541 }
542}
543
544void MFadc::Pedestals(){
545 //
546 // It shifts the FADC contents their pedestal values
547 // It shifts the values in the analog signal,
548 // therefore it has to be done before getting FADC output
549 //
550
551 Int_t i, j;
552
553 for(i=0;i<numpix;i++)
554 for(j=0;j<(Int_t)SLICES_MFADC;j++)
555 sig[i][j]+=pedestal[i];
556 //
557 // AM 15 01 2003: Formerly the above operation was performed only
558 // for pixels in which used[] was true. But to run camera with no noise
559 // and get the right baseline on the pixels with no C-photons, we have
560 // to do it for all pixels.
561 //
562
563
564}
565
566void MFadc::Offset(Float_t offset, Int_t pixel){
567 //
568 // It puts an offset in the FADC signal
569 //
570
571 int i,j;
572 float fdum;
573 TRandom *GenOff = new TRandom () ;
574
575 if (offset<0) {
576 // It cannot be, so the program assumes that
577 // it should generate random values for the offset.
578
579 if (pixel<0) {
580 // It does not exist, so all pixels will have the same offset
581
582 for(i=0;i<numpix;i++){
583 if (used[i]){
584 fdum=(10*GenOff->Rndm());
585 for(j=0;j<(Int_t) SLICES_MFADC;j++)
586 sig[i][j]+=fdum;
587 }
588 }
589 } else {
590 // The program will put the specifies offset to the pixel "pixel".
591
592 if (used[pixel]){
593 fdum=(10*GenOff->Rndm());
594 for(j=0;j<(Int_t) SLICES_MFADC;j++)
595 sig[pixel][j]+=fdum;
596 }
597
598 }
599 }else {
600 // The "offset" will be the offset for the FADC
601
602 if (pixel<0) {
603 // It does not exist, so all pixels will have the same offset
604
605 for(i=0;i<numpix;i++){
606 if (used[i]){
607 for(j=0;j<(Int_t) SLICES_MFADC;j++)
608 sig[i][j]+=offset;
609 }
610 }
611 } else {
612 // The program will put the specifies offset to the pixel "pixel".
613
614 if (used[pixel]){
615 for(j=0;j<(Int_t) SLICES_MFADC;j++)
616 sig[pixel][j]+=offset;
617 }
618 }
619 }
620 delete GenOff;
621}
622
623void MFadc::SetElecNoise(Float_t value1, Float_t value2, UInt_t n_in_pix){
624
625 UInt_t i;
626
627 fInnerPixelsNum = n_in_pix;
628
629 cout<<"MFadc::SetElecNoise ... generating database for electronic noise."
630 <<endl;
631
632 for (i=0;i<(UInt_t (SLICES_MFADC))*1001;i++){
633 noise[i]=GenElec->Gaus(0., value1 );
634 noise_outer[i]=GenElec->Gaus(0., value2 );
635 }
636
637 cout<<"MFadc::SetElecNoise ... done"<<endl;
638
639}
640
641void MFadc::ElecNoise() {
642 // ============================================================
643 //
644 // adds the noise due to optronics and electronics
645 // to the signal. This is noise which comes before the FADC,
646 // so it will be later scaled down in the low gain branch.
647 //
648 UInt_t startslice;
649
650 for ( Int_t i = 0 ; i < numpix; i++) {
651 //
652 // but at the beginning we must check if this pixel is
653 // hitted the first time
654 //
655
656 startslice=GenElec->Integer(((Int_t)SLICES_MFADC)*1000);
657
658 if ( used[i] == FALSE )
659 {
660 used [i] = TRUE ;
661 if (i < fInnerPixelsNum)
662 memcpy( (Float_t*)&sig[i][0],
663 (Float_t*)&noise[startslice],
664 ((Int_t) SLICES_MFADC)*sizeof(Float_t));
665 else
666 memcpy( (Float_t*)&sig[i][0],
667 (Float_t*)&noise_outer[startslice],
668 ((Int_t) SLICES_MFADC)*sizeof(Float_t));
669 }
670
671 //
672 // If pixel already in use, the noise is added each time slice
673 //
674 else
675 {
676 if (i < fInnerPixelsNum)
677 for ( Int_t is=0 ; is< (Int_t)SLICES_MFADC ; is++ )
678 sig[i][is] += noise[startslice+is];
679 else
680 for ( Int_t is=0 ; is< (Int_t)SLICES_MFADC ; is++ )
681 sig[i][is] += noise_outer[startslice+is];
682 }
683 }
684}
685
686void MFadc::SetDigitalNoise(Float_t value){
687
688 UInt_t i;
689 Float_t xrdm;
690
691 cout<<"MFadc::SetDigitalNoise ... generating database for electronic noise."
692 <<endl;
693
694 for (i=0;i<UInt_t(SLICES_MFADC*1001);i++){
695 xrdm=GenElec->Gaus(0., value);
696 digital_noise[i]=(xrdm>0?Int_t(xrdm+0.5):Int_t(xrdm-0.5));
697 }
698
699 cout<<"MFadc::SetDigitalNoise ... done"<<endl;
700
701}
702
703void MFadc::DigitalNoise() {
704 // ============================================================
705 //
706 // adds the noise due to FADC electronics to the signal. This
707 // noise affects equally the high and low gain branches, that is,
708 // it is not scaled down in the low gain branch.
709 //
710 UInt_t startslice;
711
712 for ( Int_t i = 0 ; i < numpix; i++)
713 {
714 if ( used[i] == FALSE )
715 continue;
716
717 startslice=GenElec->Integer((Int_t) SLICES_MFADC*999);
718 //
719 // Then the noise is introduced for each time slice
720 //
721 for ( Int_t is=0 ; is< FADC_SLICES; is++ )
722 {
723 output[i][is] += digital_noise[startslice+is];
724 output_lowgain[i][is] += digital_noise[startslice+FADC_SLICES+is];
725 }
726 }
727}
728
729void MFadc::Scan() {
730
731
732 for ( Int_t ip=0; ip<numpix; ip++ ) {
733
734 if ( used[ip] == kTRUE ) {
735
736 printf ("Pid %3d", ip ) ;
737
738 for ( Int_t is=0 ; is < (Int_t)SLICES_MFADC; is++ ) {
739
740 if ( sig[ip][is] > 0. ) {
741 printf (" %4.1f/", sig[ip][is] ) ;
742 }
743 else {
744 printf ("----/" ) ;
745 }
746 }
747
748 printf ("\n");
749
750 }
751 }
752
753}
754
755void MFadc::Scan(Float_t time) {
756
757 //
758 // first of all we subtract from the time a offset (8 ns)
759 //
760
761 Float_t t ;
762
763 (0 > time - TIME_BEFORE_TRIGGER)? t=fadc_time_offset: t=(time-TIME_BEFORE_TRIGGER+fadc_time_offset) ; // to show also the start of the pulse before the trigger time
764
765 if ( t < 0. ) {
766 cout << " WARNING!! FROM MFADC::SCAN(t) " << endl ;
767 exit (776) ;
768 }
769
770 //
771 // calculate the first slice to write out
772 //
773
774 Int_t iFirstSlice ;
775
776 iFirstSlice = (Int_t) ( t / WIDTH_FADC_TIMESLICE ) ;
777
778 for ( Int_t ip=0; ip<numpix; ip++ ) {
779
780 if ( used[ip] == kTRUE ) {
781
782 printf ("Pid %3d", ip ) ;
783
784 for ( Int_t is=iFirstSlice ; is < (iFirstSlice+15); is++ ) {
785 printf (" %5.2f /", sig[ip][is] ) ;
786 }
787
788 printf ("\n");
789
790 }
791 }
792}
793
794void MFadc::GetResponse( Float_t *resp ) {
795 // ============================================================
796 //
797 // puts the standard response function into the array resp
798
799 for ( Int_t i=0; i< RESPONSE_SLICES; i++ ) {
800
801 resp[i] = sing_resp[i] ;
802 }
803}
804
805void MFadc::GetPedestals( Float_t *offset) {
806 // ============================================================
807 //
808 // puts the pedestal values into the array offset
809
810 for ( Int_t i=0; i< numpix; i++ ) {
811
812 offset[i] = pedestal[i] ;
813 }
814}
815
816//===========================================================================
817//
818// Next function generates one pure noise event for pixel "pix", then adds
819// up the readouts of a number n_slices of its FADC slices, this being the
820// return value.
821//
822Float_t MFadc::AddNoiseInSlices( Int_t pix, Int_t ishigh, Int_t n_slices) {
823
824 Float_t sum=0;
825 Float_t fvalue = 0.;
826 UChar_t value=0;
827
828 Float_t factor;
829 UInt_t startslice;
830
831 //
832 // If we deal with low gain, we have to scale the values in sig[][] by
833 // the gain ratio (high2low_gain), since "sig" contains here the noise
834 // produce before the receiver boards (for instance NSB noise)
835 //
836 factor=(ishigh?1.0:high2low_gain);
837
838 //
839 // Get at random a point in the FADC presimulated digital noise:
840 //
841 startslice=GenElec->Integer((Int_t) SLICES_MFADC*999);
842
843 for ( Int_t is=0; is < n_slices ; is++ )
844 {
845 fvalue = pedestal[pix]+(sig[pix][is]-pedestal[pix])/factor;
846 fvalue += digital_noise[startslice+is];
847
848 fvalue = fvalue < 0? fvalue-0.5 : fvalue+0.5;
849
850 value = fvalue < 0.? (UChar_t) 0 :
851 (fvalue > 255.? 255 : (UChar_t) fvalue);
852
853
854 // Add up slices:
855 sum += value - pedestal[pix];
856 }
857
858 return sum;
859}
860
861//=======================================================================
862
863void MFadc::TriggeredFadc(Float_t time) {
864
865 //
866 // calculate the first slice to write out, according to trigger time:
867 //
868
869 Int_t iFirstSlice ;
870 Int_t i;
871
872 //
873 // We had 0.5 for the correct rounding:
874 //
875 iFirstSlice = (Int_t) ( 0.5 + time / WIDTH_FADC_TIMESLICE ) ;
876
877
878 for ( Int_t ip=0; ip<numpix; ip++ )
879 {
880
881 if ( used[ip] == kFALSE)
882 // Pixels with no C-photons, in the case that camera is being run with
883 // no noise (nor NSB neither electronic). We then set the mean pedestal as
884 // signal, since when analyzing the camera output file, MARS will subtract
885 // it anyway!
886 {
887 for ( Int_t i=0 ; i < FADC_SLICES ; i++ )
888 {
889 output[ip][i]= pedestal[ip];
890 output_lowgain[ip][i]= pedestal[ip];
891 }
892 continue;
893 }
894
895 i=0;
896 for ( Int_t is=iFirstSlice ; is < (iFirstSlice+FADC_SLICES) ; is++ )
897 {
898 if (is < (Int_t)SLICES_MFADC)
899 {
900 output[ip][i] = sig[ip][is];
901
902 // Low gain is scaled down by the factor high2low_gain:
903 output_lowgain[ip][i]= pedestal[ip] + (sig[ip][is]-pedestal[ip])/high2low_gain;
904 }
905 else // We are beyond the simulated signal history in sig[][]! Put just mean pedestal!
906 {
907 output[ip][i] = pedestal[ip];
908 output_lowgain[ip][i]= pedestal[ip];
909 }
910 i++;
911 }
912 }
913}
914
915
916void MFadc::ShowSignal (MMcEvt *McEvt, Float_t trigTime) {
917 // ============================================================
918 //
919 // This method is used to book the histogram to show the signal in
920 // a special gui frame (class MGTriggerSignal). After the look onto the
921 // signals for a better understanding of the things we will expect
922 // the gui frame and all histogramms will be destroyed.
923 //
924
925 //
926 // first of all create a list of the histograms to show
927 //
928 // take only that one with a entry
929
930 TH1F *hist ;
931 Char_t dumm[10];
932 Char_t name[256];
933
934 TObjArray *AList ;
935 AList = new TObjArray(10) ;
936
937 // the list of analog signal histograms
938 // at the beginning we initalise 10 elements
939 // but this array expand automatically if neccessay
940
941 Int_t ic = 0 ;
942 for ( Int_t i=0 ; i < numpix; i++ ) {
943 if ( used [i] == TRUE ) {
944
945 sprintf (dumm, "FADC_%d", i ) ;
946 sprintf (name, "fadc signal %d", i ) ;
947
948 hist = new TH1F(dumm, name, (Int_t)SLICES_MFADC, fadc_time_offset, TOTAL_TRIGGER_TIME+fadc_time_offset);
949 //
950 // fill the histogram
951 //
952
953 for (Int_t ibin=1; ibin <=(Int_t)SLICES_MFADC; ibin++) {
954 hist->SetBinContent (ibin, sig[i][ibin-1]) ;
955 }
956
957 // hist->SetMaximum( 5.);
958 // hist->SetMinimum(-10.);
959 hist->SetStats(kFALSE);
960
961 // hist->SetAxisRange(0., 80. ) ;
962
963 AList->Add(hist) ;
964
965 ic++ ;
966 }
967 }
968
969 //
970 // create the Gui Tool
971 //
972 //
973
974 new MGFadcSignal(McEvt,
975 AList,
976 trigTime,
977 gClient->GetRoot(),
978 gClient->GetRoot(),
979 400, 400 ) ;
980
981 //
982 // delete the List of histogramms
983 //
984 AList->Delete() ;
985
986 delete AList ;
987}
988
989UChar_t MFadc::GetFadcSignal(Int_t pixel, Int_t slice){
990
991 // It returns the analog signal for a given pixel and a given FADC
992 // time slice which would be read.
993
994 // Since May 1 2004, we do the rounding and the truncation to the range
995 // 0-255 counts here. (A. Moralejo)
996
997 Float_t out = output[pixel][slice] > 0. ?
998 output[pixel][slice]+0.5 : output[pixel][slice]-0.5;
999 // (add or subtract 0.5 for correct rounding)
1000
1001 return (out < 0.? (UChar_t) 0 :
1002 (out > 255.? (UChar_t) 255 :
1003 (UChar_t) out));
1004}
1005
1006
1007UChar_t MFadc::GetFadcLowGainSignal(Int_t pixel, Int_t slice){
1008
1009 // It returns the analog signal for a given pixel and a given FADC
1010 // time slice which would be read. Same comment as above.
1011
1012 Float_t outlow = output_lowgain[pixel][slice] > 0. ?
1013 output_lowgain[pixel][slice]+0.5 :
1014 output_lowgain[pixel][slice]-0.5;
1015 // (add or subtract 0.5 for correct rounding)
1016
1017 return (outlow < 0.? (UChar_t) 0 :
1018 (outlow > 255.? (UChar_t) 255 :
1019 (UChar_t) outlow));
1020}
1021
1022
1023
Note: See TracBrowser for help on using the repository browser.