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

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