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

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