source: trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.cxx@ 1453

Last change on this file since 1453 was 1250, checked in by blanch, 23 years ago
It has been changed to take into account the larger trigger zone.
File size: 38.2 KB
Line 
1/////////////////////////////////////////////////////////////////
2//
3// MTrigger
4//
5//
6#include "MTrigger.hxx"
7
8#include "TROOT.h"
9#include "TFile.h"
10#include "TH1.h"
11#include "TObjArray.h"
12#include "MGTriggerSignal.hxx"
13
14
15MTrigger::MTrigger() {
16 // ============================================================
17 //
18 // default constructor
19 //
20 // The procedure is the following:
21 //
22 // 1. Allocation of some memory needed
23 // 2. some parameters of the trigger are set to default.
24 // 3. if a File MTrigger.card exists in the current directory,
25 // this parameters of the trigger may be changed
26 // 4. Then the all signals are set to zero
27
28 FILE *unit_mtrig ;
29 Int_t endflag = 1 ;
30 Int_t bthresholdpixel = FALSE;
31 char datac[256] ;
32 char dummy[50] ;
33 char input_thres[50];
34 Int_t i, ii ;
35
36 Float_t threshold ;
37
38 //
39 // allocate the memory for the 2dim arrays (a_sig, d_sig )
40 //
41
42 for( Int_t j=0; j<TRIGGER_PIXELS; j++ ) {
43
44 a_sig[j] = new Float_t[TRIGGER_TIME_SLICES] ;
45
46 d_sig[j] = new Float_t[TRIGGER_TIME_SLICES] ;
47 }
48
49 //
50 // set the values for the standard response pulse
51 //
52
53 fwhm_resp = RESPONSE_FWHM ;
54 ampl_resp = RESPONSE_AMPLITUDE ;
55
56 overlaping_time = TRIGGER_OVERLAPING;
57
58 threshold = CHANNEL_THRESHOLD ;
59
60
61 gate_leng = TRIGGER_GATE ;
62 trigger_multi = TRIGGER_MULTI ;
63 trigger_geometry = TRIGGER_GEOM ;
64
65 //
66 // check if the file MTrigger.card exists
67 //
68
69 if ( (unit_mtrig = fopen ("MTrigger.card", "r")) != 0 ) {
70 cout << "[MTrigger] use the values from MTrigger.card "<< endl ;
71
72 while ( endflag == 1 ) {
73 //
74 //
75 fgets (datac, 255, unit_mtrig) ;
76 // printf ("--> %s <--", datac ) ;
77
78 //
79 // now compare the line with controlcard words
80 //
81
82 if ( strncmp (datac, "channel_threshold", 17 ) == 0 ) {
83 sscanf (datac, "%s %f", dummy, &threshold ) ;
84 }
85 else if ( strncmp (datac, "gate_length", 11 ) == 0 ) {
86 sscanf (datac, "%s %f", dummy, &gate_leng ) ;
87 }
88 else if ( strncmp (datac, "response_fwhm", 13 ) == 0 ) {
89 sscanf (datac, "%s %f", dummy, &fwhm_resp ) ;
90 }
91 else if ( strncmp (datac, "response_ampl", 13 ) == 0 ) {
92 sscanf (datac, "%s %f", dummy, &ampl_resp ) ;
93 }
94 else if ( strncmp (datac, "overlaping", 10 ) == 0 ) {
95 sscanf (datac, "%s %f", dummy, &overlaping_time ) ;
96 }
97 else if ( strncmp (datac, "multiplicity", 12 ) == 0 ) {
98 sscanf (datac, "%s %f", dummy, &trigger_multi ) ;
99 }
100 else if ( strncmp (datac, "topology", 8 ) == 0 ) {
101 sscanf (datac, "%s %i", dummy, &trigger_geometry ) ;
102 }
103 else if ( strncmp (datac, "threshold_file", 14 ) == 0 ) {
104 sscanf (datac, "%s %s", dummy, input_thres ) ;
105 bthresholdpixel=TRUE;
106 }
107
108 if ( feof(unit_mtrig) != 0 ) {
109 endflag = 0 ;
110 }
111
112 }
113
114 fclose ( unit_mtrig ) ;
115 }
116 else {
117 cout << "[MTrigger] use the standard values for MTrigger "<< endl ;
118 }
119
120 cout << endl
121 << "[MTrigger] Setting up the MTrigger with this values "<< endl ;
122 if(bthresholdpixel){
123 cout<<endl
124 << "[MTrigger] ChannelThreshold from file: "<<input_thres
125 <<endl;
126 }
127 else{
128 cout << endl
129 << "[MTrigger] ChannelThreshold: " << threshold << " mV"
130 << endl ;
131 }
132 cout << "[MTrigger] Gate Length: " << gate_leng << " ns"
133 << endl ;
134 cout << "[MTrigger] Overlaping time: " << overlaping_time << " ns"
135 << endl ;
136 cout << "[MTrigger] Response FWHM: " << fwhm_resp << " ns"
137 << endl ;
138 cout << "[MTrigger] Response Amplitude: " << ampl_resp << " mV"
139 << endl ;
140 cout << "[MTrigger] Trigger Multiplicity: " << trigger_multi << " pixels"
141 << endl ;
142 cout << "[MTrigger] Trigger Topology: " << trigger_geometry
143 << endl ;
144
145 cout << endl ;
146
147
148 //
149 // we have introduced individual thresholds for all pixels
150 //
151 FILE *unit_thres;
152
153 if (bthresholdpixel == TRUE) {
154 if ((unit_thres=fopen(input_thres, "r"))==0){
155 cout<<"WARNING: not able to read ..."<<input_thres<<endl;
156 cout<<"Threshold will be set to "<<threshold<<" for all pixels"<<endl;
157 for (Int_t k=0; k<TRIGGER_PIXELS; k++ ) {
158 chan_thres[k] = threshold ;
159 }
160 }
161 else {
162 for (i=0;i<TRIGGER_PIXELS;i++){
163 fscanf(unit_thres, "%f",&chan_thres[i]);
164 }
165 fclose (unit_thres);
166 }
167 }
168 else {
169 for (Int_t k=0; k<TRIGGER_PIXELS; k++ ) {
170 chan_thres[k] = threshold ;
171 }
172 }
173
174
175 //
176 // set up the response shape
177 //
178
179 Float_t sigma ;
180 Float_t x, x0 ;
181
182 sigma = fwhm_resp / 2.35 ;
183 x0 = 3*sigma ;
184
185 for (i=0; i< RESPONSE_SLICES ; i++ ) {
186
187 x = i * (1./((Float_t)SLICES_PER_NSEC))
188 + (1./( 2 * (Float_t)SLICES_PER_NSEC )) ;
189
190 sing_resp[i] =
191 ampl_resp * expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ;
192
193 }
194
195 //
196 // look for the time between start of response function and the
197 // maximum value of the response function. This is needed by the
198 // member functions FillNSB() and FillStar()
199 //
200
201 Int_t imax = 0 ;
202 Float_t max = 0. ;
203 for (i=0; i< RESPONSE_SLICES ; i++ ) {
204 if ( sing_resp[i] > max ) {
205 imax = i ;
206 max = sing_resp[i] ;
207 }
208 }
209
210 peak_time = ( (Float_t) imax ) / ( (Float_t) SLICES_PER_NSEC ) ;
211
212
213 //
214 // the amplitude of one single photo electron is not a constant.
215 // There exists a measured distribution from Razmik. This distribution
216 // is used to simulate the noise of the amplitude.
217 // For this a histogramm (histPmt) is created and filled with the
218 // values.
219 //
220
221 histPmt = new TH1F ("histPmt","Noise of PMT", 40, 0., 40.) ;
222
223 Stat_t ValRazmik[41] = { 0., 2.14, 2.06, 2.05, 2.05, 2.06, 2.07, 2.08, 2.15,
224 2.27, 2.40, 2.48, 2.55, 2.50, 2.35, 2.20, 2.10,
225 1.90, 1.65, 1.40, 1.25, 1.00, 0.80, 0.65, 0.50,
226 0.35, 0.27, 0.20, 0.18, 0.16, 0.14, 0.12, 0.10,
227 0.08, 0.06, 0.04, 0.02, 0.01, 0.005,0.003, 0.001} ;
228
229 histMean = histPmt->GetMean() ;
230
231 for (i=0;i<41;i++){
232 histPmt->SetBinContent(i,ValRazmik[i]);
233 }
234
235 histMean = histPmt->GetMean() ;
236
237 //
238 // create the random generator for the Electronic Noise
239 //
240
241 GenElec = new TRandom() ;
242
243 //
244 // Read in the lookup table for NN trigger
245 //
246
247 FILE *unit ;
248 int id ;
249
250 i = 0 ;
251
252 if ( (unit = fopen("../include-MTrigger/TABLE_NEXT_NEIGHBOUR", "r" )) == 0 ) {
253 cout << "ERROR: not able to read ../include-MTrigger/TABLE_NEXT_NEIGHBOUR"
254 << endl ;
255 exit(123) ;
256 }
257 else {
258 while ( i < TRIGGER_PIXELS )
259 {
260 fscanf ( unit, " %d", &id ) ;
261
262 for ( Int_t k=0; k<6; k++ ) {
263 fscanf ( unit, "%d ", &NN[i][k] ) ;
264 }
265 i++ ;
266 }
267
268 fclose (unit) ;
269 }
270
271
272 //
273 // Read in the lookup table for trigger cells
274 //
275
276 i = 0 ;
277
278 if ( (unit = fopen("../include-MTrigger/TABLE_PIXELS_IN_CELLS", "r" )) == 0 ) {
279 cout << "ERROR: not able to read ../include-MTrigger/TABLE_PIXELS_IN_CELLS"
280 << endl ;
281 exit(123) ;
282 }
283 else {
284 while ( i < TRIGGER_PIXELS )
285 {
286 for ( Int_t k=0; k<TRIGGER_CELLS; k++ ) {
287 TC[k][i]=FALSE;
288 }
289 i++ ;
290 }
291 while ( feof(unit) == 0 ) {
292 for ( Int_t k=0; k<TRIGGER_CELLS; k++ ) {
293 fscanf ( unit, "%d ", &i ) ;
294 if ((i-1)<TRIGGER_PIXELS)
295 TC[k][i-1]=TRUE;
296 }
297 }
298 fclose (unit) ;
299 }
300
301
302 //
303 //
304 // set all the booleans used to FALSE, indicating that the pixel is not
305 // used in this event.
306 //
307
308 for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) {
309 used [i] = FALSE ;
310 dknt [i] = FALSE ;
311
312 nphotshow[i] = 0 ;
313 nphotnsb [i] = 0 ;
314 nphotstar[i] = 0 ;
315
316 baseline[i] = 0 ;
317 }
318
319 for ( ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) {
320 sum_d_sig[ii] = 0. ;
321 }
322
323 //
324 // set the information about the Different Level Triggers to zero
325 //
326
327 nZero = nFirst = nSecond = 0 ;
328
329 for (ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) {
330 SlicesZero[ii] = FALSE;
331 }
332
333 for ( i = 0 ; i < 5 ; i++) {
334 SlicesFirst[i] = -50 ;
335 SlicesSecond[i] = -50 ;
336 PixelsFirst[i] = -1;
337 PixelsSecond[i] = -1;
338 }
339 cout << " end of MTrigger::MTrigger()" << endl ;
340}
341
342MTrigger::MTrigger(float gate, float overt, float ampl, float fwhm) {
343 // ============================================================
344 //
345 // constructor
346 //
347 // The procedure is the following:
348 //
349 // 1. Allocation of some memory needed
350 // 2. some parameters of the trigger are set.
351 // 3. Then the all signals are set to zero
352
353 Int_t i, ii ;
354
355 Float_t threshold ;
356
357 //
358 // allocate the memory for the 2dim arrays (a_sig, d_sig )
359 //
360
361 for( Int_t j=0; j<TRIGGER_PIXELS; j++ ) {
362
363 a_sig[j] = new Float_t[TRIGGER_TIME_SLICES] ;
364
365 d_sig[j] = new Float_t[TRIGGER_TIME_SLICES] ;
366 }
367
368 //
369 // set the values for the standard response pulse
370 //
371
372 fwhm_resp = fwhm ;
373 ampl_resp = ampl ;
374
375 overlaping_time = overt;
376
377
378 threshold = CHANNEL_THRESHOLD ;
379
380
381 gate_leng = gate ;
382 trigger_multi = TRIGGER_MULTI ;
383 trigger_geometry = TRIGGER_GEOM ;
384
385 cout << endl
386 << "[MTrigger] Setting up the MTrigger with this values "<< endl ;
387 cout << "[MTrigger] Gate Length: " << gate_leng << " ns"
388 << endl ;
389 cout << "[MTrigger] Overlaping time: " << overlaping_time << " ns"
390 << endl ;
391 cout << "[MTrigger] Response FWHM: " << fwhm_resp << " ns"
392 << endl ;
393 cout << "[MTrigger] Response Amplitude: " << ampl_resp << " mV"
394 << endl ;
395 cout << endl ;
396
397
398 for (Int_t k=0; k<TRIGGER_PIXELS; k++ ) {
399 chan_thres[k] = threshold ;
400 }
401
402
403 //
404 // set up the response shape
405 //
406
407 Float_t sigma ;
408 Float_t x, x0 ;
409
410 sigma = fwhm_resp / 2.35 ;
411 x0 = 3*sigma ;
412
413 for (i=0; i< RESPONSE_SLICES ; i++ ) {
414
415 x = i * (1./((Float_t)SLICES_PER_NSEC))
416 + (1./( 2 * (Float_t)SLICES_PER_NSEC )) ;
417
418 sing_resp[i] =
419 ampl_resp * expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ;
420
421 }
422
423 //
424 // look for the time between start of response function and the
425 // maximum value of the response function. This is needed by the
426 // member functions FillNSB() and FillStar()
427 //
428
429 Int_t imax = 0 ;
430 Float_t max = 0. ;
431 for (i=0; i< RESPONSE_SLICES ; i++ ) {
432 if ( sing_resp[i] > max ) {
433 imax = i ;
434 max = sing_resp[i] ;
435 }
436 }
437
438 peak_time = ( (Float_t) imax ) / ( (Float_t) SLICES_PER_NSEC ) ;
439
440
441 //
442 // the amplitude of one single photo electron is not a constant.
443 // There exists a measured distribution from Razmik. This distribution
444 // is used to simulate the noise of the amplitude.
445 // For this a histogramm (histPmt) is created and filled with the
446 // values.
447 //
448
449 histPmt = new TH1F ("histPmt","Noise of PMT", 40, 0., 40.) ;
450
451 Stat_t ValRazmik[41] = { 0., 2.14, 2.06, 2.05, 2.05, 2.06, 2.07, 2.08, 2.15,
452 2.27, 2.40, 2.48, 2.55, 2.50, 2.35, 2.20, 2.10,
453 1.90, 1.65, 1.40, 1.25, 1.00, 0.80, 0.65, 0.50,
454 0.35, 0.27, 0.20, 0.18, 0.16, 0.14, 0.12, 0.10,
455 0.08, 0.06, 0.04, 0.02, 0.01, 0.005,0.003, 0.001} ;
456
457 histMean = histPmt->GetMean() ;
458
459 for (i=0;i<41;i++){
460 histPmt->SetBinContent(i,ValRazmik[i]);
461 }
462
463 histMean = histPmt->GetMean() ;
464
465 //
466 // create the random generator for the Electronic Noise
467 //
468
469 GenElec = new TRandom() ;
470
471 //
472 // Read in the lookup table for NN trigger
473 //
474
475 FILE *unit ;
476 int id ;
477
478 i = 0 ;
479
480 if ( (unit = fopen("../include-MTrigger/TABLE_NEXT_NEIGHBOUR", "r" )) == 0 ) {
481 cout << "ERROR: not able to read ../include-MTrigger/TABLE_NEXT_NEIGHBOUR"
482 << endl ;
483 exit(123) ;
484 }
485 else {
486 while ( i < TRIGGER_PIXELS )
487 {
488 fscanf ( unit, " %d", &id ) ;
489
490 for ( Int_t k=0; k<6; k++ ) {
491 fscanf ( unit, "%d ", &NN[i][k] ) ;
492 }
493 i++ ;
494 }
495
496 fclose (unit) ;
497 }
498
499
500 //
501 // Read in the lookup table for trigger cells
502 //
503
504 i = 0 ;
505
506 if ( (unit = fopen("../include-MTrigger/TABLE_PIXELS_IN_CELLS", "r" )) == 0 ) {
507 cout << "ERROR: not able to read ../include-MTrigger/TABLE_PIXELS_IN_CELLS"
508 << endl ;
509 exit(123) ;
510 }
511 else {
512 while ( i < TRIGGER_PIXELS )
513 {
514 for ( Int_t k=0; k<TRIGGER_CELLS; k++ ) {
515 TC[k][i]=FALSE;
516 }
517 i++ ;
518 }
519 while ( feof(unit) == 0 ) {
520 for ( Int_t k=0; k<TRIGGER_CELLS; k++ ) {
521 fscanf ( unit, "%d ", &i ) ;
522 if((i-1)<TRIGGER_PIXELS)
523 TC[k][i-1]=TRUE;
524 }
525 }
526 fclose (unit) ;
527 }
528
529
530 //
531 //
532 // set all the booleans used to FALSE, indicating that the pixel is not
533 // used in this event.
534 //
535
536 for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) {
537 used [i] = FALSE ;
538 dknt [i] = FALSE ;
539
540 nphotshow[i] = 0 ;
541 nphotnsb [i] = 0 ;
542 nphotstar[i] = 0 ;
543
544 baseline[i] = 0 ;
545 }
546
547 for ( ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) {
548 sum_d_sig[ii] = 0. ;
549 }
550
551 //
552 // set the information about the Different Level Triggers to zero
553 //
554
555 nZero = nFirst = nSecond = 0 ;
556
557 for (ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) {
558 SlicesZero[ii] = FALSE;
559 }
560
561 for ( i = 0 ; i < 5 ; i++) {
562 SlicesFirst[i] = -50 ;
563 SlicesSecond[i] = -50 ;
564 PixelsFirst[i] = -1;
565 PixelsSecond[i] = -1;
566 }
567 cout << " end of MTrigger::MTrigger()" << endl ;
568}
569
570MTrigger::~MTrigger() {
571 // ============================================================//
572 // destructor
573 //
574 int i;
575
576 delete histPmt ;
577
578 for(i=0;i<TRIGGER_PIXELS;i++){
579 //delete [] a_sig[i];
580 //delete [] d_sig[i];
581 }
582
583 delete GenElec;
584}
585
586
587void MTrigger::Reset() {
588 // ============================================================
589 //
590 // reset all values of the signals to zero
591 //
592 Int_t i, ii ;
593
594 for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) {
595 used [i] = FALSE ;
596 dknt [i] = FALSE ;
597
598 nphotshow[i] = 0 ;
599 nphotnsb [i] = 0 ;
600 nphotstar[i] = 0 ;
601 }
602
603 for ( ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) {
604 sum_d_sig[ii] = 0. ;
605 }
606}
607
608void MTrigger::ClearZero() {
609 //
610 // set the information about the Zero Level Trigger to zero
611 //
612
613 Int_t i;
614
615 nZero = 0 ;
616
617 for (i=0 ; i<TRIGGER_TIME_SLICES; i++ ) {
618 SlicesZero[i] = FALSE;
619 }
620
621}
622
623void MTrigger::ClearFirst() {
624 //
625 // set the information about the First Level Trigger to zero
626 //
627
628 Int_t i;
629
630 nFirst = 0 ;
631
632 for ( i = 0 ; i < 5 ; i++) {
633 SlicesFirst[i] = -50 ;
634 PixelsFirst[i] = -1;
635 }
636}
637
638Float_t MTrigger::FillShow(Int_t iPix, Float_t time) {
639 // ============================================================
640 //
641 // Fills the information of one single Phe electron that
642 // comes from the shower
643 //
644
645 //
646 // First check the time
647 //
648
649 if ( time < 0. || time > TOTAL_TRIGGER_TIME ) {
650 cout << " WARNING: time of phe out of time range: " << time << endl;
651 return 0. ;
652 }
653 else {
654 return ( Fill( iPix, time, CASE_SHOW ) ) ;
655 }
656}
657
658Float_t MTrigger::FillNSB(Int_t iPix, Float_t time) {
659 // ============================================================
660 //
661 // Fills the information of one single Phe electron that
662 // comes from the shower
663 //
664
665 //
666 // First check the time
667 //
668
669 if ( time < 0. || time > TOTAL_TRIGGER_TIME ) {
670 cout << " WARNING: time of phe out of time range: " << time << endl;
671 return 0. ;
672 }
673 else {
674 return ( Fill( iPix, time - peak_time, CASE_NSB ) ) ;
675 }
676}
677
678Float_t MTrigger::FillStar(Int_t iPix, Float_t time) {
679 // ============================================================
680 //
681 // Fills the information of one single Phe electron that
682 // comes from the shower
683 //
684
685 //
686 // First check the time
687 //
688
689 if ( time < 0. || time > TOTAL_TRIGGER_TIME ) {
690 cout << " WARNING: time of phe out of time range: " << time << endl;
691 return 0. ;
692 }
693 else {
694 return ( Fill( iPix, time - peak_time, CASE_STAR ) ) ;
695 }
696}
697
698Float_t MTrigger::Fill( Int_t iPix, Float_t time, Int_t fall ) {
699 // ============================================================
700 //
701 // Fills the information in the array for the analog signal
702 //
703
704 Float_t PmtAmp = 0 ; // Amplitude of the PMT signal (results from noise)
705
706 if ( iPix < 0 ) {
707 cout << " ERROR: in MTrigger::Fill() " << endl ;
708 cout << " ERROR: Pixel Id < 0 ---> Exit " << endl ;
709 exit (1) ;
710 }
711 else if ( iPix >= CAMERA_PIXELS ) {
712 cout << " ERROR: in MTrigger::Fill() " << endl ;
713 cout << " ERROR: Pixel Id > CAMERA_PIXELS ---> Exit " << endl ;
714 exit (1) ;
715 }
716 else if ( iPix >= TRIGGER_PIXELS ) {
717 //
718 // We have not to fill information in the trigger part,
719 // but we must create the height of the puls going into
720 // the FADC simulation
721 //
722 PmtAmp = (histPmt->GetRandom()/histMean) ;
723
724 //
725 // But we fill the information in the counters of phe's
726 //
727
728 if ( fall == CASE_SHOW )
729 nphotshow[iPix]++ ;
730 else if ( fall == CASE_NSB )
731 nphotshow[iPix]++ ;
732 else if ( fall == CASE_STAR )
733 nphotstar[iPix]++ ;
734
735
736 }
737 else {
738 //
739 // we have a trigger pixel and we fill it
740 //
741 Int_t i ;
742
743 //
744 // but at the beginning we must check if this pixel is
745 // hitted the first time
746 //
747
748 if ( used[iPix] == FALSE ) {
749 used [iPix] = TRUE ;
750 // baseline[iPix] = 0. ;
751
752 for (i=0; i < TRIGGER_TIME_SLICES; i++ ) {
753 a_sig[iPix][i] = 0. ;
754 d_sig[iPix][i] = 0. ;
755 }
756 }
757
758 //
759 // get the randomized amplitude
760 //
761 PmtAmp = (histPmt->GetRandom()/histMean) ;
762
763 //
764 // select the first slice to fill
765 //
766
767 Int_t ichan = (Int_t) ( time * ((Float_t) SLICES_PER_NSEC) ) ;
768
769 //
770 // look over the response signal and put it in the signal line
771 //
772
773 for ( i = 0 ; i<RESPONSE_SLICES; i++ ) {
774
775 if ( (ichan+i) >= 0 &&
776 (ichan+i) < TRIGGER_TIME_SLICES ) {
777 a_sig[iPix][ichan+i] += PmtAmp * sing_resp[i] ;
778 }
779 }
780
781 //
782 // we fill the information in the counters of phe's
783 //
784
785 if ( fall == CASE_SHOW )
786 nphotshow[iPix]++ ;
787 else if ( fall == CASE_NSB )
788 nphotshow[iPix]++ ;
789 else if ( fall == CASE_STAR )
790 nphotstar[iPix]++ ;
791
792 //
793 //
794 return PmtAmp ;
795 }
796 return PmtAmp ;
797}
798
799
800void MTrigger::AddNSB( Int_t iPix, Float_t resp[TRIGGER_TIME_SLICES]){
801 // ================================================================
802 //
803 // Sets the information in the array for the analog signal
804 // from a given array
805 //
806
807 if ( iPix < 0 ) {
808 cout << " ERROR: in MTrigger::SetNSB() " << endl ;
809 cout << " ERROR: Pixel Id < 0 ---> Exit " << endl ;
810 exit (1) ;
811 }
812 else if ( iPix >= CAMERA_PIXELS ) {
813 cout << " ERROR: in MTrigger::SetNSB() " << endl ;
814 cout << " ERROR: Pixel Id > CAMERA_PIXELS ---> Exit " << endl ;
815 exit (1) ;
816 }
817 else if ( iPix >= TRIGGER_PIXELS ) {
818 //
819 // We have not to fill information in the trigger part.
820 //
821 }
822 else {
823 //
824 // we have a trigger pixel and we fill it
825 //
826 Int_t i ;
827
828 //
829 // but at the beginning we must check if this pixel is
830 // hitted the first time
831 //
832
833 if ( used[iPix] == FALSE ) {
834 used [iPix] = TRUE ;
835
836 for (i=0; i < TRIGGER_TIME_SLICES; i++ ) {
837 a_sig[iPix][i] = 0. ;
838 d_sig[iPix][i] = 0. ;
839 }
840 }
841
842 //
843 // look over the response signal and put it in the signal line
844 //
845
846 for ( i = 0 ; i<TRIGGER_TIME_SLICES; i++ ) {
847
848 a_sig[iPix][i] += resp[i];
849 }
850
851 }
852}
853
854void MTrigger::ElecNoise(Float_t factor) {
855 // ============================================================
856 //
857 // adds the noise due to optronic and electronic
858 // to the signal
859 //
860 Float_t rausch ;
861
862 rausch = RESPONSE_AMPLITUDE * factor ;
863
864 for ( Int_t i=0 ; i < TRIGGER_PIXELS; i++ ) {
865 //
866 // but at the beginning we must check if this pixel is
867 // hitted the first time
868 //
869
870 if ( used[i] == FALSE ) {
871 used [i] = TRUE ;
872
873 for (Int_t ii=0; ii < TRIGGER_TIME_SLICES; ii++ ) {
874 a_sig[i][ii] = 0. ;
875 d_sig[i][ii] = 0. ;
876 }
877 }
878 //
879 // Then the noise is introduced for each time slice
880 //
881 for ( Int_t ii=1 ; ii<TRIGGER_TIME_SLICES; ii++ ) {
882
883 a_sig [i][ii] += GenElec->Gaus(0., rausch ) ;
884
885 }
886 }
887}
888
889void MTrigger::SetFwhm(Float_t fwhm){
890 //===========================================================
891 //
892 // It sets the fwhm for the single phe signal and
893 // updates the sing_resp for it
894
895 Float_t sigma ;
896 Float_t x, x0 ;
897 Int_t i;
898
899 fwhm_resp = fwhm;
900
901 sigma = fwhm_resp / 2.35 ;
902 x0 = 3*sigma ;
903
904 for (i=0; i< RESPONSE_SLICES ; i++ ) {
905
906 x = i * (1./((Float_t)SLICES_PER_NSEC))
907 + (1./( 2 * (Float_t)SLICES_PER_NSEC )) ;
908
909 sing_resp[i] =
910 ampl_resp * expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ;
911
912 }
913
914
915}
916
917void MTrigger::SetMultiplicity(Int_t multi){
918 //=============================================================
919 //
920 // It sets the private member trigger_multi
921
922 trigger_multi=multi;
923}
924
925void MTrigger::SetTopology(Int_t topo){
926 //=============================================================
927 //
928 // It sets the private member trigger_geometry
929
930 trigger_geometry=topo;
931}
932
933void MTrigger::SetThreshold(Float_t thres[]){
934 //=============================================================
935 //
936 // It sets the private member chan_thres[TRIGGER_PIXELS]
937
938 Int_t i;
939
940 for(i=0;i<TRIGGER_PIXELS;i++){
941 chan_thres[i]=thres[i];
942 }
943}
944
945
946void MTrigger::CheckThreshold(float *thres){
947 //=============================================================
948 //
949 // Set Right Discriminator threshold, taking into account trigger pixels
950
951 FILE *unit;
952
953 float thres_aux[CAMERA_PIXELS];
954 int id;
955
956 for (int i=0;i<CAMERA_PIXELS;i++)
957 thres_aux[i]=999999.99;
958
959 if((unit =fopen("../include-MTrigger/TABLE_PIXELS_IN_CELLS", "r" )) == 0 ){
960 cout << "ERROR: not able to read ../include-MTrigger/TABLE_PIXELS_IN_CELLS"
961 << endl ;
962 exit(123) ;
963 }
964 else {
965 while ( feof(unit) == 0 ) {
966 for ( Int_t k=0; k<TRIGGER_CELLS; k++ ) {
967 fscanf ( unit, "%d ", &id ) ;
968 if ((id-1)<TRIGGER_PIXELS)
969 thres_aux[id-1]=thres[id-1];
970 }
971 }
972 }
973 fclose (unit) ;
974
975 for (int i=0;i<CAMERA_PIXELS;i++)
976 thres[i]=thres_aux[i];
977
978}
979
980void MTrigger::ReadThreshold(char name[]){
981 //=============================================================
982 //
983 // It reads values for threshold of each pixel from file name
984
985 FILE *unit;
986 Int_t i=0;
987
988 if ((unit=fopen(name, "r"))==0){
989 cout<<"WARNING: not able to read ..."<<name<<endl;
990 }
991 else {
992 while (i<TRIGGER_PIXELS){
993 fscanf(unit, "%f",&chan_thres[i++]);
994 }
995 fclose (unit);
996 }
997
998}
999
1000void MTrigger::GetResponse(Float_t *resp) {
1001 // ============================================================
1002 //
1003 // puts the standard response function into the array resp
1004
1005 for ( Int_t i=0; i< RESPONSE_SLICES; i++ ) {
1006
1007 resp[i] = sing_resp[i] ;
1008 }
1009
1010}
1011
1012void MTrigger::GetMapDiskriminator(Byte_t *map){
1013 //=============================================================
1014 //
1015 // Gives a map of the fired pixels (Bool_t dknt [TRIGGER_PIXELS])
1016 // in an array of Byte_t (each byte has the information for 8 pixels)
1017 //
1018
1019 Int_t i,ii;
1020
1021 for(i=0;i<TRIGGER_PIXELS/8+1;i++){
1022 map[i]=0;
1023 }
1024
1025 for(i=0;i<TRIGGER_PIXELS;i++){
1026 ii=(Int_t)i/8;
1027 if (dknt[i]==TRUE){
1028 map[ii]=map[ii]+(Int_t)pow(2,i-ii*8);
1029 }
1030 }
1031}
1032
1033
1034void MTrigger::Diskriminate() {
1035 // ============================================================
1036 //
1037 // Diskriminates the analog signal
1038 //
1039 // one very important part is the calucaltion of the baseline
1040 // shift. Because of the AC coupling of the PMT, only the
1041 // fluctuations are interesting. If there are a lot of phe,
1042 // a so-called shift of the baseline occurs.
1043 //
1044
1045 Int_t iM = 0 ;
1046 Int_t i, ii ;
1047
1048
1049 Int_t jmax = (Int_t) (gate_leng * SLICES_PER_NSEC ) ;
1050
1051 //
1052 // first of all determine the integral of all signals to get
1053 // the baseline shift.
1054 //
1055
1056 for ( i=0 ; i < TRIGGER_PIXELS ; i++ ) {
1057 if ( used[i] == TRUE ) {
1058 baseline[i] = 0. ;
1059
1060 for ( ii = 0 ; ii < TRIGGER_TIME_SLICES ; ii++ ) {
1061 baseline[i] += a_sig[i][ii] ;
1062 }
1063
1064 baseline[i] = baseline[i] / ( (Float_t ) TRIGGER_TIME_SLICES) ;
1065
1066 //
1067 // now correct the baseline shift in the analog signal!!
1068 //
1069 for ( ii = 0 ; ii < TRIGGER_TIME_SLICES ; ii++ ) {
1070 a_sig[i][ii] = a_sig[i][ii] - baseline[i] ;
1071 }
1072 }
1073 }
1074
1075 //
1076 // now the diskrimination is coming
1077 //
1078 // take only that pixel which are used
1079 //
1080
1081 for ( i=0 ; i < TRIGGER_PIXELS; i++ ) {
1082 if ( used [i] == TRUE ) {
1083
1084 for ( ii=1 ; ii<TRIGGER_TIME_SLICES; ii++ ) {
1085 //
1086 // first check if the signal is crossing the CHANNEL_THRESHOLD
1087 // form low to big signals
1088 //
1089
1090 if ( a_sig[i][ii-1] < chan_thres[i] &&
1091 a_sig[i][ii] >= chan_thres[i] ) {
1092 {
1093 if ( dknt[i] == FALSE ) {
1094 dknt [i] = TRUE ;
1095 iM++ ;
1096 }
1097 // cout << " disk " << ii ;
1098 //
1099 // put the standard diskriminator signal in
1100 // the diskriminated signal
1101 //
1102 for ( Int_t j=0 ; j < jmax ; j++ ) {
1103
1104 if ( ii+j < TRIGGER_TIME_SLICES ) {
1105 d_sig [i][ii+j] = 1. ;
1106 }
1107 }
1108 ii = ii + jmax ;
1109 }
1110 }
1111 else d_sig[i][ii]=0.;
1112 }
1113 }
1114 }
1115}
1116
1117
1118void MTrigger::ShowSignal (MMcEvt *McEvt) {
1119 // ============================================================
1120 //
1121 // This method is used to book the histogramm to show the signal in
1122 // a special gui frame (class MGTriggerSignal). After the look onto the
1123 // signals for a better understanding of the things we will expect
1124 // the gui frame and all histogramms will be destroyed.
1125 //
1126
1127 //
1128 // first of all create a list of the histograms to show
1129 //
1130 // take only that one with a entry
1131
1132 TH1F *hist ;
1133 TH1F *dhist ;
1134 Char_t dumm[10];
1135 Char_t name[256];
1136
1137 TObjArray *AList ;
1138 AList = new TObjArray(10) ;
1139
1140 TObjArray *DList ;
1141 DList = new TObjArray(10) ;
1142
1143 // the list of analog signal histograms
1144 // at the beginning we initalise 10 elements
1145 // but this array expand automaticly if neccessay
1146
1147 Int_t ic = 0 ;
1148 for ( Int_t i=0 ; i < TRIGGER_PIXELS; i++ ) {
1149 if ( used [i] == TRUE ) {
1150
1151 sprintf (dumm, "A_%d", i ) ;
1152 sprintf (name, "analog %d", i ) ;
1153
1154 hist = new TH1F(dumm, name, TRIGGER_TIME_SLICES, 0., TOTAL_TRIGGER_TIME);
1155 //
1156 // fill the histogram
1157 //
1158
1159 for (Int_t ibin=1; ibin <=TRIGGER_TIME_SLICES; ibin++) {
1160 hist->SetBinContent (ibin, a_sig[i][ibin-1]) ;
1161 }
1162 hist->SetMaximum(8.);
1163 hist->SetMinimum(-8.);
1164 hist->SetStats(kFALSE);
1165
1166 AList->Add(hist) ;
1167
1168 sprintf (dumm, "D_%d", i ) ;
1169 sprintf (name, "digital %d", i ) ;
1170
1171 dhist = new TH1F(dumm, name, TRIGGER_TIME_SLICES, 0., TOTAL_TRIGGER_TIME);
1172 if ( dknt[i] == TRUE ) {
1173 //
1174 // fill the histogram of digital signal
1175 //
1176 for (Int_t ibin=1; ibin <=TRIGGER_TIME_SLICES; ibin++) {
1177 dhist->SetBinContent (ibin, d_sig[i][ibin-1]) ;
1178 dhist->SetStats(kFALSE);
1179 }
1180 }
1181 dhist->SetMaximum(1.5);
1182
1183 DList->Add(dhist);
1184
1185 ic++ ;
1186
1187 }
1188 }
1189
1190 //
1191 // create the Gui Tool
1192 //
1193 //
1194
1195 new MGTriggerSignal(McEvt,
1196 AList,
1197 DList,
1198 gClient->GetRoot(),
1199 gClient->GetRoot(),
1200 400, 400 ) ;
1201
1202 //
1203 // delete the List of histogramms
1204 //
1205
1206 AList->Delete() ;
1207 DList->Delete() ;
1208
1209 delete AList ;
1210 delete DList ;
1211}
1212
1213
1214Int_t MTrigger::ZeroLevel() {
1215 // ============================================================
1216 //
1217 // This is a level introduced just to speed up the program.
1218 // It makes sense to look for next neighbours only if there
1219 // are at least trigger_multi pixels with a diskriminator
1220 // signal.
1221 //
1222
1223 //
1224 // first count the pixels with a diskriminator signal
1225 //
1226 Int_t iMul = 0 ;
1227 for ( Int_t iP =0 ; iP < TRIGGER_PIXELS; iP++ ) {
1228 //
1229 //
1230 if ( dknt[iP] == TRUE ) {
1231 iMul++ ;
1232 }
1233 }
1234
1235 //
1236 // only if there are at least more pixels than requested
1237 // it make sense to look into details
1238 if ( iMul >= trigger_multi ) {
1239 //
1240 // fill the sum signal of all diskriminator signals
1241 //
1242 for ( Int_t iP =0 ; iP < TRIGGER_PIXELS; iP++ ) {
1243 //
1244 //
1245 if ( dknt[iP] == TRUE ) {
1246 //
1247 // sum it up
1248 //
1249 for (Int_t iS=0; iS< TRIGGER_TIME_SLICES; iS++ ) {
1250 //
1251 //
1252 sum_d_sig [iS] += d_sig[iP][iS] ;
1253 }
1254 }
1255 }
1256 //
1257 // run over the sum_d_sig and check each time slice
1258 //
1259 Int_t iReturn = 0 ;
1260
1261 for (Int_t iS=0; iS< TRIGGER_TIME_SLICES; iS++ ) {
1262
1263 if ( sum_d_sig[iS] >= trigger_multi ) {
1264 iReturn++ ;
1265 nZero++;
1266 SlicesZero[iS] = TRUE ;
1267
1268 }
1269 else SlicesZero[iS] = FALSE;
1270 }
1271
1272 return ( iReturn ) ;
1273 }
1274 else {
1275 return 0 ;
1276 }
1277}
1278
1279Int_t MTrigger::FirstLevel() {
1280 //=================================================
1281 //
1282 // This is a level trigger which can look for several
1283 // multiplicities (trigger_multi)
1284 // and topologies (trigger_geometry)
1285 //
1286
1287 Int_t iReturn = 0 ; // Return value for this function
1288
1289 // Definition of needed variables
1290 Bool_t Muster[TRIGGER_PIXELS] ;
1291 Bool_t Neighb[TRIGGER_PIXELS] ;
1292 Int_t iMulti = 0 ;
1293
1294 // We put several wrong topologies which we already know that they
1295 // are not possible. It can save time.
1296
1297 if (trigger_geometry==0 && trigger_multi>7) {
1298 cout <<"You are looking for a topology that needs more than six neighbours of the same pixel"<<endl;
1299 cout <<" Topology "<<trigger_geometry<<" Multiplicity "<<trigger_multi<<endl;;
1300 return (kFALSE);
1301 }
1302
1303 if (trigger_geometry==2 && trigger_multi<3) {
1304 cout<<"Closed pack geometry with multiplicity "<<trigger_multi<<" does not make sense, I'll check simple neihgbour condition"<<endl;
1305 trigger_geometry=1;
1306 }
1307 if (trigger_geometry>2) {
1308 cout << "This trigger topology is not implemented"<<endl;
1309 return (kFALSE);
1310 }
1311
1312 //
1313 // loop over all ZeroLevel Trigger
1314 //
1315 // it is only neccessary to look after a ZeroLevel Trigger for
1316 // a FirstLevel (NextNeighbour) trigger.
1317 //
1318
1319 if (nZero) {
1320
1321 //
1322 // Then run over all slices
1323 //
1324
1325 for ( Int_t iSli = 0;
1326 iSli < TRIGGER_TIME_SLICES; iSli++ ) {
1327
1328 // Check if this time slice has more fired pixels than trigger_multi
1329
1330 if (SlicesZero[iSli]){
1331 //
1332 // Loop over trigger cells. It is topology analisy,
1333 // therefore it is keep here after multiplicity and
1334 // threshold checks.
1335 //
1336
1337 for(Int_t iCell=0; iCell<TRIGGER_CELLS; iCell++){
1338 //
1339 // then look in all pixel of that cell if the
1340 // diskriminated signal is 1
1341 //
1342 for ( Int_t iPix = 0 ; iPix < TRIGGER_PIXELS; iPix++ ) {
1343 Muster[iPix] = kFALSE ;
1344 Neighb[iPix] = kFALSE ;
1345 // Select pixels which are used and it the current cell
1346 if ( used [iPix] == TRUE && TC[iCell][iPix]==TRUE) {
1347 //
1348 // now check the diskriminated signal
1349 //
1350 if ( d_sig [iPix][iSli] > 0. ) {
1351 Muster[iPix] = kTRUE ;
1352 }
1353 }
1354 } // end of loop over the pixels
1355
1356 //
1357 // Here we check which of the "muster" pixels will be fired for
1358 // the minimum required overlaping time
1359 //
1360
1361 OverlapingTime(Muster, &Muster[0],iSli);
1362
1363 //
1364 // here we have to look for the topologies
1365 //
1366
1367 switch(trigger_geometry){
1368 case 0:{
1369
1370 // It looks for a pixel above threshold which has
1371 // trigger_multi-1 neighbour pixels above threshold
1372
1373 Bool_t Dummy[TRIGGER_PIXELS] ;
1374
1375 // Loop over all pixels
1376 for (int j=0;j<TRIGGER_PIXELS;j++){
1377
1378 for (int k=0; k<TRIGGER_PIXELS; k++){
1379 Neighb[k]=kFALSE;
1380
1381 Dummy[k] = Muster[k] ;
1382 }
1383 if(Muster[j]){
1384 // If pixel is fired, it checks how many fired neighbours it has
1385 for (iMulti=1;iMulti<trigger_multi; iMulti++) {
1386 Neighb[j] = kTRUE ;
1387 Dummy[j] = kTRUE ;
1388 if (!PassNextNeighbour(Dummy, &Neighb[0])){
1389 break;
1390 }
1391 for (int k=0; k<TRIGGER_PIXELS; k++){
1392 if (Neighb[k]){
1393 Dummy[k]=kFALSE;
1394 Neighb[k]=kFALSE;
1395 }
1396 }
1397 }
1398 if (iMulti==trigger_multi ) {
1399 //
1400 // A NN-Trigger is detected at time Slice
1401 //
1402 PixelsFirst[nFirst] = j; // We save pixel that triggers
1403 SlicesFirst[nFirst++] = iSli ; // We save time when it triggers
1404 iReturn++ ;
1405 iSli+=(50*SLICES_PER_NSEC); // We skip the following 50 ns (dead time)
1406 iCell=TRIGGER_CELLS; // We skip the remaining trigger cells
1407 break ;
1408 }
1409 }
1410 }
1411 break;
1412 };
1413
1414 case 1:{
1415
1416 // It looks for trigger_multi neighbour pixels above the
1417 // threshold.
1418
1419 for (int j=0;j<TRIGGER_PIXELS;j++){
1420 if(Muster[j]){
1421 // It checks if you can find
1422 // trigger_multi fired neighbour pixels
1423 Neighb[j] = kTRUE ;
1424 for (iMulti=1;iMulti<trigger_multi; iMulti++) {
1425 if (!PassNextNeighbour(Muster, &Neighb[0]))
1426 break;
1427 }
1428 if (iMulti==trigger_multi ) {
1429 //
1430 // A NN-Trigger is detected at time Slice
1431 //
1432 PixelsFirst[nFirst] = j; // We save pixel that triggers
1433 SlicesFirst[nFirst++] = iSli ; // We save when it triggers
1434 iReturn++ ;
1435 iSli+=(50*SLICES_PER_NSEC); // We skip the following 50 ns (dead time)
1436 iCell=TRIGGER_CELLS; // We skip the remaining trigger cells
1437 break ;
1438 }
1439 else {
1440 // We put Neighb to kFALSE to check an other pixel
1441 for (int k=0; k<TRIGGER_PIXELS; k++){
1442 if (Neighb[k]){
1443 Neighb[k]=kFALSE;
1444 }
1445 }
1446 }
1447 }
1448 }
1449 break;
1450 };
1451 case 2:{
1452
1453 // It looks for trigger_multi closed pack neighbours
1454 // above threshold
1455 // Closed pack means that you can take out any pixel
1456 // and you will still get a trigger for trigger_multi -1
1457 // The algorithm is not perfect, there still somes cases
1458 // that are not really well treated
1459
1460 Int_t closed_pack = 1;
1461
1462 for (int j=0;j<TRIGGER_PIXELS;j++){
1463 if(Muster[j]){
1464 // It checks if there are trigger_multi
1465 // neighbours above threshold
1466
1467 Neighb[j] = kTRUE ;
1468 iMulti=1;
1469
1470 //while(PassNextNeighbour(Muster, &Neighb[0])) iMulti++;
1471 for (iMulti=1;iMulti<trigger_multi;iMulti++){
1472 if (!PassNextNeighbour(Muster, &Neighb[0]))
1473 break;
1474 }
1475
1476 if (iMulti==trigger_multi ) {
1477 //
1478 // A NN-Trigger is detected at time Slice
1479 //
1480
1481 // Check if there is closed pack topology
1482
1483 Bool_t Aux1[TRIGGER_PIXELS];
1484 Bool_t Aux2[TRIGGER_PIXELS];
1485 for (int jj=0;jj<TRIGGER_PIXELS;jj++)
1486 Aux2[jj]=kFALSE;
1487
1488 for (int i=0;i<TRIGGER_PIXELS;i++){
1489 if (Neighb[i]) {
1490 // Loop over pixels that achive neighbouring condition
1491
1492 for (int jj=0;jj<TRIGGER_PIXELS;jj++) {
1493
1494 Aux1[jj] = Neighb[jj] ; // huschel
1495 Aux2[jj]=kFALSE;
1496 }
1497
1498 // It checks if taking out any of the pixels we lose
1499 // neighbouring condition for trigger_multi -1
1500
1501 Aux1[i]=kFALSE;
1502 closed_pack=0;
1503 for (int jj=0;jj<TRIGGER_PIXELS;jj++) {
1504 if (Aux1[jj]==kTRUE){
1505 Aux2[jj]=kTRUE;
1506 for (iMulti=1;iMulti<(trigger_multi-1);iMulti++){
1507 if (!PassNextNeighbour(Aux1, &Aux2[0]))
1508 break;
1509 }
1510 if (iMulti==(trigger_multi-1)){
1511 // We found a NN trigger for trigger_multi -1
1512 // taking out pixel jj
1513 closed_pack=1;
1514 break;
1515 }
1516 Aux2[jj]=kFALSE;
1517 }
1518 }
1519 if (!closed_pack) break;
1520 // For some pixell we did not found NN condition
1521 // for trigger_multi -1
1522 }
1523 }
1524 if (closed_pack){
1525 PixelsFirst[nFirst] = j; // We save pixel that triggers
1526 SlicesFirst[nFirst++] = iSli ; // We save time when it triggers
1527 iReturn++ ;
1528 iSli+=(50*SLICES_PER_NSEC); // We skip the following 50 ns (dead time)
1529 iCell=TRIGGER_CELLS; // We skip the remaining trigger cells
1530 break ;
1531 }
1532 else {
1533 for (int k=0; k<TRIGGER_PIXELS; k++){
1534 if (Neighb[k]){
1535 Neighb[k]=kFALSE;
1536 }
1537 }
1538 }
1539 } // end if trigger multiplicity achived
1540 else{
1541 for (int k=0; k<TRIGGER_PIXELS; k++)
1542 Neighb[k]=kFALSE;
1543 }
1544 } // end if pixel fired
1545 } // end loop trigger pixels
1546 break;
1547 }; // end case 2:
1548 default:{
1549 cout << "This topology is not implemented yet"<<endl;
1550 break;
1551 }
1552 }
1553 } //end loop over trigger cells.
1554 }
1555 } // end of loop over the slices
1556 } // end of conditional for a trigger Zero
1557
1558 //
1559 // return the Number of FirstLevel Triggers
1560 //
1561 return iReturn ;
1562}
1563
1564
1565Bool_t MTrigger::PassNextNeighbour ( Bool_t m[], Bool_t *n) {
1566 //
1567 // This function is looking for a next neighbour of pixels in n[]
1568 // above triggers using a NNlookup table.
1569 // This table is builded by the default constructor
1570 //
1571
1572 //
1573 // loop over all trigger pixels
1574 //
1575
1576 Bool_t return_val = kFALSE;
1577
1578 for ( Int_t i=0; i<TRIGGER_PIXELS; i++) {
1579 //
1580 // check if this pixel has a diskrminator signal
1581 // (this is inside n[] )
1582 //
1583
1584 if ( n[i] && !return_val) {
1585
1586 //
1587 // look in the next neighbours from the lookuptable
1588 //
1589
1590 for ( Int_t kk=0; kk<6; kk++ ) {
1591 //
1592 // if the nextneighbour is outside the triggerarea do nothing
1593 //
1594 if (!return_val){
1595 if (NN[i][kk] >= TRIGGER_PIXELS ) {
1596
1597 }
1598 // the nextneighbour is not inside the TRIGGER_PIXELS
1599 else {
1600 //
1601 // look if the boolean of nn pixels is true
1602 //
1603
1604 if ( m[ NN[i][kk] ] && !n[NN[i][kk]] ) {
1605 n[NN[i][kk]]=kTRUE ;
1606 return_val =kTRUE;
1607 }
1608 }
1609 }
1610 else break;
1611 }
1612 }
1613 }
1614 return(return_val);
1615}
1616
1617Float_t MTrigger::GetFirstLevelTime( Int_t il ){
1618
1619 //=============================================================
1620 //
1621 // It gives the time for the il trigger at first level
1622
1623 return((Float_t) ((Float_t) SlicesFirst[il]/((Float_t) SLICES_PER_NSEC)));
1624}
1625
1626Int_t MTrigger::GetFirstLevelPixel( Int_t il ){
1627
1628 //=============================================================
1629 //
1630 // It gives the pixel that triggers for the il trigger at first level
1631 return(PixelsFirst[il]);
1632}
1633
1634void MTrigger::OverlapingTime ( Bool_t m[], Bool_t *n, Int_t ifSli){
1635
1636 //============================================================
1637 //
1638 // It returns in n the pixels of m that are fired during the
1639 // required overlaping time for trigger after ifSli
1640
1641 int i,j;
1642 int iNumSli;
1643
1644 // Translation from ns to slices
1645 iNumSli=(int) (overlaping_time*SLICES_PER_NSEC);
1646 if (iNumSli<1) iNumSli=1;
1647
1648 // Put pixels that fulfill the requirement in n
1649 for (i=0;i<TRIGGER_PIXELS;i++){
1650 if (m[i]==kTRUE){
1651 for(j=ifSli;j<ifSli+iNumSli;j++){
1652 if(!d_sig[i][j]){
1653 n[i]=kFALSE;
1654 break;
1655 }
1656 }
1657 }
1658 }
1659
1660}
1661
1662
1663
Note: See TracBrowser for help on using the repository browser.