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

Last change on this file since 2334 was 2290, checked in by blanch, 22 years ago
Low gain implemented Faster noise simulation Different signal for inner and outer pixels
File size: 15.5 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(Float_t ampl, Float_t fwhm, Float_t amplout, Float_t fwhmout) {
21 //
22 // Constructor overloaded II
23 //
24 // Input variables:
25 // 1. ampl(out) = integration of the single phe response (outer pixels)
26 // 2. fwhm(out) = width at half high of the single phe
27 // response(outer pixels)
28 //
29 // The procedure is the following:
30 // 1. some parameters of the trigger are set to default.
31 // this parameters of the trigger may be changed
32 // 3. Then the all signals are set to zero
33
34 fwhm_resp = fwhm;
35 ampl_resp = ampl;
36 fwhm_resp_outer = fwhmout;
37 ampl_resp_outer = amplout;
38
39 //
40 // set up the response shape
41 //
42 Int_t i ;
43
44 Float_t sigma ;
45 Float_t x, x0 ;
46
47 sigma = fwhm_resp / 2.35 ;
48 x0 = 3*sigma ;
49
50 Float_t dX, dX2 ;
51
52 dX = WIDTH_FADC_TIMESLICE / SUBBINS ;
53 dX2 = dX/2. ;
54
55 for (i=0; i< RESPONSE_SLICES_MFADC ; i++ ) {
56
57 x = i * dX + dX2 ;
58
59 //
60 // the value 1/(2*Pi*sigma^2) was introduced to normalize
61 // the area at the input value
62 //
63 sing_resp[i] = ampl_resp / sqrt(2*3.1415926*sigma*sigma)*
64 expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ;
65
66 }
67
68 sigma = fwhm_resp_outer / 2.35 ;
69 x0 = 3*sigma ;
70
71 dX = WIDTH_FADC_TIMESLICE / SUBBINS ;
72 dX2 = dX/2. ;
73
74 for (i=0; i< RESPONSE_SLICES_MFADC ; i++ ) {
75
76 x = i * dX + dX2 ;
77
78 //
79 // the value 1/(2*Pi*sigma^2) was introduced to normalize
80 // the area at the input value
81 //
82 sing_resp_outer[i] = ampl_resp_outer / sqrt(2*3.1415926*sigma*sigma)*
83 expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ;
84
85 }
86
87 //
88 // init the Random Generator for Electonic Noise
89 //
90
91 GenElec = new TRandom () ;
92
93 Reset();
94
95 //
96 // set all pedestals to 0
97 //
98
99 for ( i =0 ; i <CAMERA_PIXELS ; i++ ) {
100 pedestal[i] = 0.0 ;
101 }
102}
103
104void MFadc::Reset() {
105 //
106 // set all values of the signals to zero
107 // set tha values of FADC slices that would be read after trigger to zero
108 //
109 memset(used, 0, CAMERA_PIXELS*sizeof(Bool_t));
110 memset(output, 0, CAMERA_PIXELS*FADC_SLICES*sizeof(UChar_t));
111 memset(output_lowgain, 0, CAMERA_PIXELS*FADC_SLICES*sizeof(UChar_t));
112}
113void MFadc::Fill( Int_t iPix, Float_t time,
114 Float_t amplitude, Int_t isinner ) {
115
116 if(isinner)
117 Fill(iPix, time, amplitude);
118 else
119 FillOuter(iPix, time, amplitude);
120
121}
122void MFadc::Fill( Int_t iPix, Float_t time, Float_t amplitude ) {
123
124 //
125 // fills the information about one single Phe in the Trigger class
126 //
127 // parameter is the number of the pixel and the time-difference to the
128 // first particle
129 //
130 //
131
132 Int_t i, ichan, ichanfadc ;
133
134 //
135 // first we have to check if the pixel iPix is used or not until now
136 // if this is the first use, reset all signal for that pixels
137 //
138 if ( iPix > CAMERA_PIXELS ) {
139 cout << " WARNING: MFadc::Fill() : iPix greater than CAMERA_PIXELS"
140 << endl ;
141 exit(987) ;
142 }
143
144 if ( used[iPix] == FALSE ) {
145 used [iPix] = TRUE ;
146
147 for (i=0; i < (Int_t) SLICES_MFADC; i++ ) {
148 sig[iPix][i] = 0. ;
149 }
150 }
151
152 //
153 // then select the time slice to use (ican)
154 //
155
156
157 if ( time < 0. ) {
158 cout << " WARNING! Fadc::Fill " << time << " below ZERO!! Very strange!!"
159 << endl ;
160 }
161 else if ( time < TOTAL_TRIGGER_TIME ) {
162 //
163 // determine the slices number assuming the WIDTH_RESPONSE_MFADC
164 //
165 ichan = (Int_t) ( time / ((Float_t) WIDTH_RESPONSE_MFADC ));
166
167 //
168 // putting the response slices in the right sig slices.
169 // Be carefull, because both slices have different widths.
170 //
171
172 for ( i = 0 ; i<RESPONSE_SLICES; i++ ) {
173 ichanfadc = (Int_t) ((ichan+i)/SUBBINS) ;
174 if ( (ichanfadc) < (Int_t)SLICES_MFADC ) {
175 sig[iPix][ichanfadc] += (amplitude * sing_resp[i] ) ;
176 }
177 }
178 }
179 else {
180 cout << " WARNING! Fadc::Fill " << time << " out of TriggerTimeRange "
181 << TOTAL_TRIGGER_TIME << endl ;
182 }
183
184}
185
186void MFadc::FillOuter( Int_t iPix, Float_t time, Float_t amplitude ) {
187
188 //
189 // fills the information about one single Phe in the Trigger class
190 // for an outer pixel
191 //
192 // parameter is the number of the pixel and the time-difference to the
193 // first particle
194 //
195 //
196
197 Int_t i, ichan, ichanfadc ;
198
199 //
200 // first we have to check if the pixel iPix is used or not until now
201 // if this is the first use, reset all signal for that pixels
202 //
203 if ( iPix > CAMERA_PIXELS ) {
204 cout << " WARNING: MFadc::FillOuter() : iPix greater than CAMERA_PIXELS"
205 << endl ;
206 exit(987) ;
207 }
208
209 if ( used[iPix] == FALSE ) {
210 used [iPix] = TRUE ;
211
212 for (i=0; i < (Int_t) SLICES_MFADC; i++ ) {
213 sig[iPix][i] = 0. ;
214 }
215 }
216
217 //
218 // then select the time slice to use (ican)
219 //
220
221
222 if ( time < 0. ) {
223 cout << " WARNING! Fadc::FillOuter " << time << " below ZERO!! Very strange!!"
224 << endl ;
225 }
226 else if ( time < TOTAL_TRIGGER_TIME ) {
227 //
228 // determine the slices number assuming the WIDTH_RESPONSE_MFADC
229 //
230 ichan = (Int_t) ( time / ((Float_t) WIDTH_RESPONSE_MFADC ));
231
232 //
233 // putting the response slices in the right sig slices.
234 // Be carefull, because both slices have different widths.
235 //
236
237 for ( i = 0 ; i<RESPONSE_SLICES; i++ ) {
238 ichanfadc = (Int_t) ((ichan+i)/SUBBINS) ;
239 if ( (ichanfadc) < (Int_t)SLICES_MFADC ) {
240 sig[iPix][ichanfadc] += (amplitude * sing_resp_outer[i] ) ;
241 }
242 }
243 }
244 else {
245 cout << " WARNING! Fadc::FillOuter " << time << " out of TriggerTimeRange "
246 << TOTAL_TRIGGER_TIME << endl ;
247 }
248
249}
250
251void MFadc::Set( Int_t iPix, Float_t resp[(Int_t) SLICES_MFADC]) {
252
253 //
254 // Sets the information about fadc reponse from a given array
255 //
256 // parameter is the number of the pixel and the values to be set
257 //
258 //
259
260 Int_t i ;
261
262 //
263 // first we have to check if the pixel iPix is used or not until now
264 // if this is the first use, reset all signal for that pixels
265 //
266 if ( iPix > CAMERA_PIXELS ) {
267 cout << " WARNING: MFadc::Fill() : iPix greater than CAMERA_PIXELS"
268 << endl ;
269 exit(987) ;
270 }
271
272 if ( used[iPix] == FALSE ) {
273 used [iPix] = TRUE ;
274
275 for (i=0; i < (Int_t)SLICES_MFADC; i++ ) {
276 sig[iPix][i] = 0. ;
277 }
278 }
279 for ( i = 0 ; i<(Int_t)SLICES_MFADC; i++ ) {
280 sig[iPix][i] = resp[i] ;
281 }
282
283}
284
285void MFadc::AddSignal( Int_t iPix, Float_t resp[(Int_t) SLICES_MFADC]) {
286
287 //
288 // Adds signals to the fadc reponse from a given array
289 //
290 // parameter is the number of the pixel and the values to be added
291 //
292 //
293
294 Int_t i ;
295
296 //
297 // first we have to check if the pixel iPix is used or not until now
298 // if this is the first use, reset all signal for that pixels
299 //
300 if ( iPix > CAMERA_PIXELS ) {
301 cout << " WARNING: MFadc::Fill() : iPix greater than CAMERA_PIXELS"
302 << endl ;
303 exit(987) ;
304 }
305
306 if ( used[iPix] == FALSE ) {
307 used [iPix] = TRUE ;
308
309 for (i=0; i < (Int_t)SLICES_MFADC; i++ ) {
310 sig[iPix][i] = 0. ;
311 }
312 }
313 for ( i = 0 ; i<(Int_t)SLICES_MFADC; i++ ) {
314 sig[iPix][i] += resp[i] ;
315 }
316
317}
318
319void MFadc::SetPedestals( Int_t ped) {
320 // It sets pedestal for each pixel flat randomly dstributed between 0 and ped
321 // It uses the instance of TRandom GenElec.
322
323 Int_t i;
324
325 for(i=0;i<CAMERA_PIXELS;i++){
326 pedestal[i]= (Float_t)(ped* GenElec->Rndm());
327 }
328}
329
330void MFadc::SetPedestals( Float_t ped[CAMERA_PIXELS]) {
331 // It sets pedestal for each pixel from ped array
332
333 Int_t i;
334
335 for(i=0;i<CAMERA_PIXELS;i++){
336 pedestal[i]= ped[i];
337 }
338}
339
340
341void MFadc::Baseline(){
342 //
343 // It simulates the AC behaviour
344
345 int i,j;
346 Float_t baseline;
347
348 for(j=0;j<CAMERA_PIXELS;j++){
349 baseline=0.0;
350 for(i=0;i<(Int_t) SLICES_MFADC;i++){
351 baseline=+sig[j][i];
352 }
353 baseline=baseline/SLICES_MFADC;
354 for(i=0;i<(Int_t) SLICES_MFADC;i++){
355 sig[j][i]=-baseline;
356 }
357 }
358}
359
360void MFadc::Pedestals(){
361 //
362 // It shifts the FADC contents their pedestal values
363 // It shifts the values in the analog signal,
364 // therefore it has to be done before getting FADC output
365 //
366
367 Int_t i, j;
368
369 for(i=0;i<CAMERA_PIXELS;i++)
370 for(j=0;j<(Int_t)SLICES_MFADC;j++)
371 sig[i][j]+=pedestal[i];
372}
373
374void MFadc::Offset(Float_t offset, Int_t pixel){
375 //
376 // It puts an offset in the FADC signal
377 //
378
379 int i,j;
380 float fdum;
381 TRandom *GenOff = new TRandom () ;
382
383 if (offset<0) {
384 // It cannot be, so the program assumes that
385 // it should generate random values for the offset.
386
387 if (pixel<0) {
388 // It does not exist, so all pixels will have the same offset
389
390 for(i=0;i<CAMERA_PIXELS;i++){
391 if (used[i]){
392 fdum=(10*GenOff->Rndm());
393 for(j=0;j<(Int_t) SLICES_MFADC;j++)
394 sig[i][j]=+fdum;
395 }
396 }
397 } else {
398 // The program will put the specifies offset to the pixel "pixel".
399
400 if (used[pixel]){
401 fdum=(10*GenOff->Rndm());
402 for(j=0;j<(Int_t) SLICES_MFADC;j++)
403 sig[pixel][j]=+fdum;
404 }
405
406 }
407 }else {
408 // The "offset" will be the offset for the FADC
409
410 if (pixel<0) {
411 // It does not exist, so all pixels will have the same offset
412
413 for(i=0;i<CAMERA_PIXELS;i++){
414 if (used[i]){
415 for(j=0;j<(Int_t) SLICES_MFADC;j++)
416 sig[i][j]=+offset;
417 }
418 }
419 } else {
420 // The program will put the specifies offset to the pixel "pixel".
421
422 if (used[pixel]){
423 for(j=0;j<(Int_t) SLICES_MFADC;j++)
424 sig[pixel][j]=+offset;
425 }
426 }
427 }
428 delete GenOff;
429}
430
431void MFadc::SetElecNoise(Float_t value){
432
433 UInt_t i;
434
435 cout<<"MFadc::SetElecNoise ... generating database for electroni noise."
436 <<endl;
437
438 for (i=0;i<CAMERA_PIXELS*(Int_t) SLICES_MFADC*101;i++){
439 noise[i]=GenElec->Gaus(0., value );
440 }
441
442 cout<<"MFadc::SetElecNoise ... done"<<endl;
443
444}
445
446void MFadc::ElecNoise(Float_t value) {
447 // ============================================================
448 //
449 // adds the noise due to optronic and electronic
450 // to the signal
451 //
452 UInt_t startslice;
453
454 startslice=GenElec->Integer(CAMERA_PIXELS*(Int_t) SLICES_MFADC*100);
455
456 for ( Int_t i = 0 ; i < CAMERA_PIXELS; i++) {
457 //
458 // but at the beginning we must check if this pixel is
459 // hitted the first time
460 //
461 if ( used[i] == FALSE ) {
462 used [i] = TRUE ;
463
464 memcpy( (Float_t*)&sig[0][0],
465 (Float_t*)&noise[startslice+i*(Int_t) SLICES_MFADC],
466 (Int_t) SLICES_MFADC*sizeof(Float_t));
467
468 }
469 //
470 // Then the noise is introduced for each time slice
471 //
472 else
473 for ( Int_t is=0 ; is< (Int_t)SLICES_MFADC ; is++ ) {
474
475 sig[i][is] += noise[startslice+i*(Int_t) SLICES_MFADC+is] ;
476
477 }
478
479 }
480}
481
482
483
484void MFadc::Scan() {
485
486
487 for ( Int_t ip=0; ip<CAMERA_PIXELS; ip++ ) {
488
489 if ( used[ip] == kTRUE ) {
490
491 printf ("Pid %3d", ip ) ;
492
493 for ( Int_t is=0 ; is < (Int_t)SLICES_MFADC; is++ ) {
494
495 if ( sig[ip][is] > 0. ) {
496 printf (" %4.1f/", sig[ip][is] ) ;
497 }
498 else {
499 printf ("----/" ) ;
500 }
501 }
502
503 printf ("\n");
504
505 }
506 }
507
508}
509
510void MFadc::Scan(Float_t time) {
511
512 //
513 // first of all we subtract from the time a offset (8 ns)
514 //
515
516 Float_t t ;
517
518 (0 > time - TIME_BEFORE_TRIGGER)? t=0: t=(time-TIME_BEFORE_TRIGGER) ; // to show also the start of the pulse before the trigger time
519
520 if ( t < 0. ) {
521 cout << " WARNING!! FROM MFADC::SCAN(t) " << endl ;
522 exit (776) ;
523 }
524
525 //
526 // calculate the first slice to write out
527 //
528
529 Int_t iFirstSlice ;
530
531 iFirstSlice = (Int_t) ( t / WIDTH_FADC_TIMESLICE ) ;
532
533 for ( Int_t ip=0; ip<CAMERA_PIXELS; ip++ ) {
534
535 if ( used[ip] == kTRUE ) {
536
537 printf ("Pid %3d", ip ) ;
538
539 for ( Int_t is=iFirstSlice ; is < (iFirstSlice+15); is++ ) {
540 printf (" %5.2f /", sig[ip][is] ) ;
541 }
542
543 printf ("\n");
544
545 }
546 }
547}
548
549void MFadc::GetResponse( Float_t *resp ) {
550 // ============================================================
551 //
552 // puts the standard response function into the array resp
553
554 for ( Int_t i=0; i< RESPONSE_SLICES; i++ ) {
555
556 resp[i] = sing_resp[i] ;
557 }
558}
559
560void MFadc::GetPedestals( Float_t *offset) {
561 // ============================================================
562 //
563 // puts the pedestal values into the array offset
564
565 for ( Int_t i=0; i< CAMERA_PIXELS; i++ ) {
566
567 offset[i] = pedestal[i] ;
568 }
569}
570
571void MFadc::TriggeredFadc(Float_t time) {
572
573 //
574 // first of all we subtract from the time a offset (8 ns)
575 //
576
577 Float_t t ;
578
579 (0>time-TIME_BEFORE_TRIGGER)? t=0: t=(time-TIME_BEFORE_TRIGGER) ; // to show also the start of the pulse before the trigger time
580
581 if ( t < 0. ) {
582 cout << " WARNING!! FROM MFADC::SCAN(t) " << endl ;
583 exit (776) ;
584 }
585
586 //
587 // calculate the first slice to write out
588 //
589
590 Int_t iFirstSlice ;
591 Int_t i;
592
593 iFirstSlice = (Int_t) ( t / WIDTH_FADC_TIMESLICE ) ;
594
595 for ( Int_t ip=0; ip<CAMERA_PIXELS; ip++ ) {
596
597 if ( used[ip] == kTRUE ) {
598 i=0;
599 for ( Int_t is=iFirstSlice ; is < (iFirstSlice+FADC_SLICES) ; is++ ) {
600 if (is< (Int_t)SLICES_MFADC && sig[ip][is]>0.0)
601 {
602 output[ip][i++]=(sig[ip][is] > 255. ? 255 :(UChar_t) (sig[ip][is]+0.5));
603 output_lowgain[ip][i++]=
604 (Int_t)(pedestal[ip]+(sig[ip][is]-pedestal[ip])/HIGH2LOWGAIN) > 255. ? 255 :
605 (UChar_t)(pedestal[ip]+(sig[ip][is]-pedestal[ip])/HIGH2LOWGAIN);
606
607 }
608 else
609 {
610 output[ip][i]= 0;
611 output_lowgain[ip][i++]= 0;
612 }
613 }
614
615 }
616 }
617}
618
619void MFadc::ShowSignal (MMcEvt *McEvt, Float_t trigTime) {
620 // ============================================================
621 //
622 // This method is used to book the histogram to show the signal in
623 // a special gui frame (class MGTriggerSignal). After the look onto the
624 // signals for a better understanding of the things we will expect
625 // the gui frame and all histogramms will be destroyed.
626 //
627
628 //
629 // first of all create a list of the histograms to show
630 //
631 // take only that one with a entry
632
633 TH1F *hist ;
634 Char_t dumm[10];
635 Char_t name[256];
636
637 TObjArray *AList ;
638 AList = new TObjArray(10) ;
639
640 // the list of analog signal histograms
641 // at the beginning we initalise 10 elements
642 // but this array expand automaticly if neccessay
643
644 Int_t ic = 0 ;
645 for ( Int_t i=0 ; i < CAMERA_PIXELS; i++ ) {
646 if ( used [i] == TRUE ) {
647
648 sprintf (dumm, "FADC_%d", i ) ;
649 sprintf (name, "fadc signal %d", i ) ;
650
651 hist = new TH1F(dumm, name, SLICES_MFADC, 0., TOTAL_TRIGGER_TIME);
652 //
653 // fill the histogram
654 //
655
656 for (Int_t ibin=1; ibin <=(Int_t)SLICES_MFADC; ibin++) {
657 hist->SetBinContent (ibin, sig[i][ibin-1]) ;
658 }
659
660 // hist->SetMaximum( 5.);
661 // hist->SetMinimum(-10.);
662 hist->SetStats(kFALSE);
663
664 // hist->SetAxisRange(0., 80. ) ;
665
666 AList->Add(hist) ;
667
668 ic++ ;
669 }
670 }
671
672 //
673 // create the Gui Tool
674 //
675 //
676
677 new MGFadcSignal(McEvt,
678 AList,
679 trigTime,
680 gClient->GetRoot(),
681 gClient->GetRoot(),
682 400, 400 ) ;
683
684 //
685 // delete the List of histogramms
686 //
687 AList->Delete() ;
688
689 delete AList ;
690}
691
692UChar_t MFadc::GetFadcSignal(Int_t pixel, Int_t slice){
693
694 // It returns the analog signal for a given pixel and a given FADC
695 // time slice which would be read.
696
697 return (output[pixel][slice]);
698}
699
700
701UChar_t MFadc::GetFadcLowGainSignal(Int_t pixel, Int_t slice){
702
703 // It returns the analog signal for a given pixel and a given FADC
704 // time slice which would be read.
705
706 return (output_lowgain[pixel][slice]);
707}
708
709
710
Note: See TracBrowser for help on using the repository browser.