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

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