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

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