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

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