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

Last change on this file since 384 was 375, checked in by harald, 25 years ago
I found in the implementation of Oscar a smaller bug concerning the procedure of copying two arrays.
File size: 25.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
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 char datac[256] ;
31 char dummy[50] ;
32
33 Float_t threshold ;
34
35 //
36 // allocate the memory for the 2dim arrays (a_sig, d_sig )
37 //
38
39 for( Int_t j=0; j<TRIGGER_PIXELS; j++ ) {
40
41 a_sig[j] = new Float_t[TRIGGER_TIME_SLICES] ;
42
43 d_sig[j] = new Float_t[TRIGGER_TIME_SLICES] ;
44 }
45
46 //
47 // set the values for the standard response pulse
48 //
49
50 fwhm_resp = RESPONSE_FWHM ;
51 ampl_resp = RESPONSE_AMPLITUDE ;
52
53 threshold = CHANNEL_THRESHOLD ;
54
55
56 gate_leng = TRIGGER_GATE ;
57 trigger_multi = TRIGGER_MULTI ;
58 trigger_geometry = TRIGGER_GEOM ;
59
60 //
61 // check if the file MTrigger.card exists
62 //
63
64 if ( (unit_mtrig = fopen ("MTrigger.card", "r")) != 0 ) {
65 cout << "[MTrigger] use the values from MTrigger.card "<< endl ;
66
67 while ( endflag == 1 ) {
68 //
69 //
70 fgets (datac, 255, unit_mtrig) ;
71 // printf ("--> %s <--", datac ) ;
72
73 //
74 // now compare the line with controlcard words
75 //
76
77 if ( strncmp (datac, "channel_threshold", 17 ) == 0 ) {
78 sscanf (datac, "%s %f", dummy, &threshold ) ;
79 }
80 else if ( strncmp (datac, "gate_length", 11 ) == 0 ) {
81 sscanf (datac, "%s %f", dummy, &gate_leng ) ;
82 }
83 else if ( strncmp (datac, "response_fwhm", 13 ) == 0 ) {
84 sscanf (datac, "%s %f", dummy, &fwhm_resp ) ;
85 }
86 else if ( strncmp (datac, "response_ampl", 13 ) == 0 ) {
87 sscanf (datac, "%s %f", dummy, &ampl_resp ) ;
88 }
89 else if ( strncmp (datac, "multiplicity", 12 ) == 0 ) {
90 sscanf (datac, "%s %f", dummy, &trigger_multi ) ;
91 }
92 else if ( strncmp (datac, "topology", 8 ) == 0 ) {
93 sscanf (datac, "%s %i", dummy, &trigger_geometry ) ;
94 }
95
96 if ( feof(unit_mtrig) != 0 ) {
97 endflag = 0 ;
98 }
99
100 }
101
102 fclose ( unit_mtrig ) ;
103 }
104 else {
105 cout << "[MTrigger] use the standard values for MTrigger "<< endl ;
106 }
107
108 cout << endl
109 << "[MTrigger] Setting up the MTrigger with this values "<< endl ;
110 cout << endl
111 << "[MTrigger] ChannelThreshold: " << threshold << " mV"
112 << endl ;
113
114 cout << "[MTrigger] Gate Length: " << gate_leng << " ns"
115 << endl ;
116 cout << "[MTrigger] Response FWHM: " << fwhm_resp << " ns"
117 << endl ;
118 cout << "[MTrigger] Response Amplitude: " << ampl_resp << " mV"
119 << endl ;
120 cout << "[MTrigger] Trigger Multiplicity: " << trigger_multi << " pixels"
121 << endl ;
122 cout << "[MTrigger] Trigger Topology: " << trigger_geometry
123 << endl ;
124
125 cout << endl ;
126
127
128 //
129 // we have introduced individual thresholds for all pixels
130 //
131 for (Int_t k=0; k<TRIGGER_PIXELS; k++ ) {
132 chan_thres[k] = threshold ;
133 }
134
135 //
136 // set up the response shape
137 //
138 Int_t i, ii ;
139
140 Float_t sigma ;
141 Float_t x, x0 ;
142
143 sigma = fwhm_resp / 2.35 ;
144 x0 = 3*sigma ;
145
146 for (i=0; i< RESPONSE_SLICES ; i++ ) {
147
148 x = i * (1./((Float_t)SLICES_PER_NSEC))
149 + (1./( 2 * (Float_t)SLICES_PER_NSEC )) ;
150
151 sing_resp[i] =
152 ampl_resp * expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ;
153
154 // cout << i << " "
155 // << x << " "
156 // << sing_resp[i]
157 // << endl ;
158
159
160 }
161
162 //
163 // look for the time between start of response function and the
164 // maximum value of the response function. This is needed by the
165 // member functions FillNSB() and FillStar()
166 //
167
168 Int_t imax = 0 ;
169 Float_t max = 0. ;
170 for (i=0; i< RESPONSE_SLICES ; i++ ) {
171 if ( sing_resp[i] > max ) {
172 imax = i ;
173 max = sing_resp[i] ;
174 }
175 }
176
177 peak_time = ( (Float_t) imax ) / ( (Float_t) SLICES_PER_NSEC ) ;
178
179
180 //
181 // the amplitude of one single photo electron is not a constant.
182 // There exists a measured distribution from Razmik. This distribution
183 // is used to simulate the noise of the amplitude.
184 // For this a histogramm (histPmt) is created and filled with the
185 // values.
186 //
187
188 histPmt = new TH1F ("histPmt","Noise of PMT", 40, 0., 40.) ;
189
190 Stat_t ValRazmik[41] = { 0., 2.14, 2.06, 2.05, 2.05, 2.06, 2.07, 2.08, 2.15,
191 2.27, 2.40, 2.48, 2.55, 2.50, 2.35, 2.20, 2.10,
192 1.90, 1.65, 1.40, 1.25, 1.00, 0.80, 0.65, 0.50,
193 0.35, 0.27, 0.20, 0.18, 0.16, 0.14, 0.12, 0.10,
194 0.08, 0.06, 0.04, 0.02, 0.01, 0.005,0.003, 0.001} ;
195
196 histMean = histPmt->GetMean() ;
197
198 histPmt->SetContent( ValRazmik) ;
199
200 histMean = histPmt->GetMean() ;
201
202 //
203 // create the random generator for the Electronic Noise
204 //
205
206 GenElec = new TRandom() ;
207
208 //
209 // Read in the lookup table for NN trigger
210 //
211
212 FILE *unit ;
213 int id ;
214
215 i = 0 ;
216
217 if ( (unit = fopen("../include-MTrigger/TABLE_NEXT_NEIGHBOUR", "r" )) == 0 ) {
218 cout << "ERROR: not able to read ../include-MTrigger/TABLE_NEXT_NEIGHBOUR"
219 << endl ;
220 exit(123) ;
221 }
222 else {
223 while ( i < TRIGGER_PIXELS )
224 {
225 fscanf ( unit, " %d", &id ) ;
226
227 for ( Int_t k=0; k<6; k++ ) {
228 fscanf ( unit, "%d ", &NN[i][k] ) ;
229 }
230 i++ ;
231 }
232
233 fclose (unit) ;
234 }
235
236
237 //
238 //
239 // set all the booleans used to FALSE, indicating that the pixel is not
240 // used in this event.
241 //
242
243 for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) {
244 used [i] = FALSE ;
245 dknt [i] = FALSE ;
246
247 nphotshow[i] = 0 ;
248 nphotnsb [i] = 0 ;
249 nphotstar[i] = 0 ;
250
251 baseline[i] = 0 ;
252 }
253
254 for ( ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) {
255 sum_d_sig[ii] = 0. ;
256 }
257
258 //
259 // set the information about the Different Level Triggers to zero
260 //
261
262 nZero = nFirst = nSecond = 0 ;
263
264 for (ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) {
265 SlicesZero[ii] = FALSE;
266 }
267
268 for ( i = 0 ; i < 5 ; i++) {
269 SlicesFirst[i] = 0 ;
270 SlicesSecond[i] = 0 ;
271 }
272 cout << " end of MTrigger::MTrigger()" << endl ;
273}
274
275MTrigger::~MTrigger() {
276 // ============================================================//
277 // destructor
278 //
279 int i;
280 // delete histPmt ;
281 for(i=0;i<TRIGGER_PIXELS;i++){
282 delete [] a_sig[i];
283 delete [] d_sig[i];
284 }
285 delete GenElec;
286}
287
288
289void MTrigger::Reset() {
290 // ============================================================
291 //
292 // reset all values of the signals to zero
293 //
294 Int_t i, ii ;
295
296 for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) {
297 used [i] = FALSE ;
298 dknt [i] = FALSE ;
299
300 nphotshow[i] = 0 ;
301 nphotnsb [i] = 0 ;
302 nphotstar[i] = 0 ;
303 }
304
305 for ( ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) {
306 sum_d_sig[ii] = 0. ;
307 }
308
309 //
310 // set the information about the Different Level Triggers to zero
311 //
312
313 nZero = nFirst = nSecond = 0 ;
314
315 for ( i = 0 ; i < 5 ; i++) {
316 SlicesZero[i] = 0 ;
317 SlicesFirst[i] = 0 ;
318 SlicesSecond[i] = 0 ;
319 }
320
321}
322
323Float_t MTrigger::FillShow(Int_t iPix, Float_t time) {
324 // ============================================================
325 //
326 // Fills the information of one single Phe electron that
327 // comes from the shower
328 //
329
330 //
331 // First check the time
332 //
333
334 if ( time < 0. || time > TOTAL_TRIGGER_TIME ) {
335 cout << " WARNING: time of phe out of time range: " << time << endl;
336 return 0. ;
337 }
338 else {
339 return ( Fill( iPix, time, CASE_SHOW ) ) ;
340 }
341}
342
343Float_t MTrigger::FillNSB(Int_t iPix, Float_t time) {
344 // ============================================================
345 //
346 // Fills the information of one single Phe electron that
347 // comes from the shower
348 //
349
350 //
351 // First check the time
352 //
353
354 if ( time < 0. || time > TOTAL_TRIGGER_TIME ) {
355 cout << " WARNING: time of phe out of time range: " << time << endl;
356 return 0. ;
357 }
358 else {
359 return ( Fill( iPix, time - peak_time, CASE_NSB ) ) ;
360 }
361}
362
363Float_t MTrigger::FillStar(Int_t iPix, Float_t time) {
364 // ============================================================
365 //
366 // Fills the information of one single Phe electron that
367 // comes from the shower
368 //
369
370 //
371 // First check the time
372 //
373
374 if ( time < 0. || time > TOTAL_TRIGGER_TIME ) {
375 cout << " WARNING: time of phe out of time range: " << time << endl;
376 return 0. ;
377 }
378 else {
379 return ( Fill( iPix, time - peak_time, CASE_STAR ) ) ;
380 }
381}
382
383Float_t MTrigger::Fill( Int_t iPix, Float_t time, Int_t fall ) {
384 // ============================================================
385 //
386 // Fills the information in the array for the analog signal
387 //
388
389 Float_t PmtAmp = 0 ; // Amplitude of the PMT signal (results from noise)
390
391 if ( iPix < 0 ) {
392 cout << " ERROR: in MTrigger::Fill() " << endl ;
393 cout << " ERROR: Pixel Id < 0 ---> Exit " << endl ;
394 exit (1) ;
395 }
396 else if ( iPix >= CAMERA_PIXELS ) {
397 cout << " ERROR: in MTrigger::Fill() " << endl ;
398 cout << " ERROR: Pixel Id > CAMERA_PIXELS ---> Exit " << endl ;
399 exit (1) ;
400 }
401 else if ( iPix >= TRIGGER_PIXELS ) {
402 //
403 // We have not to fill information in the trigger part,
404 // but we must create the height of the puls going into
405 // the FADC simulation
406 //
407 PmtAmp = (histPmt->GetRandom()/histMean) ;
408
409 //
410 // But we fill the information in the counters of phe's
411 //
412
413 if ( fall == CASE_SHOW )
414 nphotshow[iPix]++ ;
415 else if ( fall == CASE_NSB )
416 nphotshow[iPix]++ ;
417 else if ( fall == CASE_STAR )
418 nphotstar[iPix]++ ;
419
420
421 }
422 else {
423 //
424 // we have a trigger pixel and we fill it
425 //
426 Int_t i ;
427
428 //
429 // but at the beginning we must check if this pixel is
430 // hitted the first time
431 //
432
433 if ( used[iPix] == FALSE ) {
434 used [iPix] = TRUE ;
435 // baseline[iPix] = 0. ;
436
437 for (i=0; i < TRIGGER_TIME_SLICES; i++ ) {
438 a_sig[iPix][i] = 0. ;
439 d_sig[iPix][i] = 0. ;
440 }
441 }
442
443 //
444 // get the randomized amplitude
445 //
446 PmtAmp = (histPmt->GetRandom()/histMean) ;
447
448 //
449 // select the first slice to fill
450 //
451
452 Int_t ichan = (Int_t) ( time * ((Float_t) SLICES_PER_NSEC) ) ;
453
454 //
455 // look over the response signal and put it in the signal line
456 //
457
458 for ( i = 0 ; i<RESPONSE_SLICES; i++ ) {
459
460 if ( (ichan+i) >= 0 &&
461 (ichan+i) < TRIGGER_TIME_SLICES ) {
462 a_sig[iPix][ichan+i] += PmtAmp * sing_resp[i] ;
463 }
464 }
465
466 //
467 // we fill the information in the counters of phe's
468 //
469
470 if ( fall == CASE_SHOW )
471 nphotshow[iPix]++ ;
472 else if ( fall == CASE_NSB )
473 nphotshow[iPix]++ ;
474 else if ( fall == CASE_STAR )
475 nphotstar[iPix]++ ;
476
477 //
478 //
479 return PmtAmp ;
480 }
481 return PmtAmp ;
482}
483
484
485
486void MTrigger::ElecNoise() {
487 // ============================================================
488 //
489 // adds the noise due to optronic and electronic
490 // to the signal
491 //
492 Float_t rausch ;
493
494 rausch = RESPONSE_AMPLITUDE * 0.3 ;
495
496 for ( Int_t i=0 ; i < TRIGGER_PIXELS; i++ ) {
497 if ( used [i] == TRUE ) {
498 //cout << "Pixel " << i << " used" ;
499
500 for ( Int_t ii=1 ; ii<TRIGGER_TIME_SLICES; ii++ ) {
501
502 a_sig [i][ii] += GenElec->Gaus(0., rausch ) ;
503
504 }
505 }
506 }
507}
508
509void MTrigger::Diskriminate() {
510 // ============================================================
511 //
512 // Diskriminates the analog signal
513 //
514 // one very important part is the calucaltion of the baseline
515 // shift. Because of the AC coupling of the PMT, only the
516 // fluctuations are interesting. If there are a lot of phe,
517 // a so-called shift of the baseline occurs.
518 //
519
520 Int_t iM = 0 ;
521 Int_t i, ii ;
522
523
524 Int_t jmax = (Int_t) (gate_leng * SLICES_PER_NSEC ) ;
525
526 //
527 // first of all determine the integral of all signals to get
528 // the baseline shift.
529 //
530
531 for ( i=0 ; i < TRIGGER_PIXELS ; i++ ) {
532 if ( used[i] == TRUE ) {
533 baseline[i] = 0. ;
534
535 for ( ii = 0 ; ii < TRIGGER_TIME_SLICES ; ii++ ) {
536 baseline[i] += a_sig[i][ii] ;
537 }
538
539 baseline[i] = baseline[i] / ( (Float_t ) TRIGGER_TIME_SLICES) ;
540
541 // cout << "Pixel " << i << " baseline " << baseline[i] <<endl ;
542
543 //
544 // now correct the baseline shift in the analog signal!!
545 //
546 for ( ii = 0 ; ii < TRIGGER_TIME_SLICES ; ii++ ) {
547 a_sig[i][ii] = a_sig[i][ii] - baseline[i] ;
548 }
549 }
550 }
551
552 //
553 // now the diskrimination is coming
554 //
555 // take only that pixel which are used
556 //
557
558 for ( i=0 ; i < TRIGGER_PIXELS; i++ ) {
559 if ( used [i] == TRUE ) {
560
561 for ( ii=1 ; ii<TRIGGER_TIME_SLICES; ii++ ) {
562 //
563 // first check if the signal is crossing the CHANNEL_THRESHOLD
564 // form low to big signals
565 //
566
567 if ( a_sig[i][ii-1] < chan_thres[i] &&
568 a_sig[i][ii] >= chan_thres[i] ) {
569 {
570 if ( dknt[i] == FALSE ) {
571 dknt [i] = TRUE ;
572 iM++ ;
573 }
574 // cout << " disk " << ii ;
575 //
576 // put the standard diskriminator signal in
577 // the diskriminated signal
578 //
579 for ( Int_t j=0 ; j < jmax ; j++ ) {
580
581 if ( ii+j < TRIGGER_TIME_SLICES ) {
582 d_sig [i][ii+j] = 1. ;
583 }
584 }
585 ii = ii + jmax ;
586 }
587 }
588 else d_sig[i][ii]=0.;
589 }
590 }
591 }
592}
593
594
595void MTrigger::ShowSignal (MMcEvt *McEvt) {
596 // ============================================================
597 //
598 // This method is used to book the histogramm to show the signal in
599 // a special gui frame (class MGTriggerSignal). After the look onto the
600 // signals for a better understanding of the things we will expect
601 // the gui frame and all histogramms will be destroyed.
602 //
603
604 //
605 // first of all create a list of the histograms to show
606 //
607 // take only that one with a entry
608
609 TH1F *hist ;
610 TH1F *dhist ;
611 Char_t dumm[10];
612 Char_t name[256];
613
614 TObjArray *AList ;
615 AList = new TObjArray(10) ;
616
617 TObjArray *DList ;
618 DList = new TObjArray(10) ;
619
620 // the list of analog signal histograms
621 // at the beginning we initalise 10 elements
622 // but this array expand automaticly if neccessay
623
624 Int_t ic = 0 ;
625 for ( Int_t i=0 ; i < TRIGGER_PIXELS; i++ ) {
626 if ( used [i] == TRUE ) {
627
628 sprintf (dumm, "A_%d", i ) ;
629 sprintf (name, "analog %d", i ) ;
630
631 hist = new TH1F(dumm, name, TRIGGER_TIME_SLICES, 0., TOTAL_TRIGGER_TIME);
632 //
633 // fill the histogram
634 //
635
636 for (Int_t ibin=1; ibin <=TRIGGER_TIME_SLICES; ibin++) {
637 hist->SetBinContent (ibin, a_sig[i][ibin-1]) ;
638 }
639 hist->SetMaximum(8.);
640 hist->SetMinimum(-8.);
641 hist->SetStats(kFALSE);
642
643 AList->Add(hist) ;
644
645 sprintf (dumm, "D_%d", i ) ;
646 sprintf (name, "digital %d", i ) ;
647
648 dhist = new TH1F(dumm, name, TRIGGER_TIME_SLICES, 0., TOTAL_TRIGGER_TIME);
649 if ( dknt[i] == TRUE ) {
650 //
651 // fill the histogram of digital signal
652 //
653 for (Int_t ibin=1; ibin <=TRIGGER_TIME_SLICES; ibin++) {
654 dhist->SetBinContent (ibin, d_sig[i][ibin-1]) ;
655 dhist->SetStats(kFALSE);
656 }
657 }
658 dhist->SetMaximum(1.5);
659
660 DList->Add(dhist);
661
662 ic++ ;
663
664 }
665 }
666
667 //
668 // create the Gui Tool
669 //
670 //
671
672 new MGTriggerSignal(McEvt,
673 AList,
674 DList,
675 gClient->GetRoot(),
676 gClient->GetRoot(),
677 400, 400 ) ;
678
679 //
680 // delete the List of histogramms
681 //
682
683 AList->Delete() ;
684 DList->Delete() ;
685
686 delete AList ;
687 delete DList ;
688}
689
690
691Int_t MTrigger::ZeroLevel() {
692 // ============================================================
693 //
694 // This is a level introduced just to speed up the program.
695 // It makes sense to look for next neighbours only if there
696 // are at least trigger_multi pixels with a diskriminator
697 // signal.
698 //
699
700 //
701 // first count the pixels with a diskriminator signal
702 //
703 Int_t iMul = 0 ;
704 for ( Int_t iP =0 ; iP < TRIGGER_PIXELS; iP++ ) {
705 //
706 //
707 if ( dknt[iP] == TRUE ) {
708 iMul++ ;
709 }
710 }
711
712 //
713 // only if there are at least more pixels than requested
714 // it make sense to look into details
715 if ( iMul >= trigger_multi ) {
716 //
717 // fill the sum signal of all diskriminator signals
718 //
719 for ( Int_t iP =0 ; iP < TRIGGER_PIXELS; iP++ ) {
720 //
721 //
722 if ( dknt[iP] == TRUE ) {
723 //
724 // sum it up
725 //
726 for (Int_t iS=0; iS< TRIGGER_TIME_SLICES; iS++ ) {
727 //
728 //
729 sum_d_sig [iS] += d_sig[iP][iS] ;
730 }
731 }
732 }
733 //
734 // run over the sum_d_sig and check each time slice
735 //
736 Int_t iReturn = 0 ;
737
738 for (Int_t iS=0; iS< TRIGGER_TIME_SLICES; iS++ ) {
739
740 if ( sum_d_sig[iS] >= trigger_multi ) {
741 iReturn++ ;
742 nZero++;
743 SlicesZero[iS] = TRUE ;
744
745 }
746 else SlicesZero[iS] = FALSE;
747 }
748
749 return ( iReturn ) ;
750 }
751 else {
752 return 0 ;
753 }
754}
755
756Int_t MTrigger::FirstLevel() {
757 //=================================================
758 //
759 // This is a level trigger which can look for several
760 // multiplicities (trigger_multi)
761 // and topologies (trigger_geometry)
762 //
763
764 Int_t iReturn = 0 ; // Return value for this function
765
766 if ( nZero > 1 ) {
767 cout << " INFORMATION: more than one Zero Level TRIGGER " << endl ;
768 }
769
770 // Definition of needed variables
771 Bool_t Muster[TRIGGER_PIXELS] ;
772 Bool_t Neighb[TRIGGER_PIXELS] ;
773 Int_t iMulti = 0 ;
774
775 // We put several wrong topologies which we already know that they
776 // are not possible. It can save time.
777
778 if (trigger_geometry==0 && trigger_multi>7) {
779 cout <<"You are lookiny for a topology that needs more than six neighbours of the same pixel"<<endl;
780 cout <<" Topology "<<trigger_geometry<<" Multiplicity "<<trigger_multi<<endl;;
781 return (kFALSE);
782 }
783
784 if (trigger_geometry==2 && trigger_multi<3) {
785 cout<<"Closed pack geometry with multiplicity "<<trigger_multi<<" does not make sense"<<endl;
786 return (kFALSE);
787 }
788 if (trigger_geometry>2) {
789 cout << "This trigger topology is not implemented"<<endl;
790 return (kFALSE);
791 }
792
793 //
794 // loop over all ZeroLevel Trigger
795 //
796 // it is only neccessary to look after a ZeroLevel Trigger for
797 // a FirstLevel (NextNeighbour) trigger.
798 //
799
800 if (nZero) {
801
802 //
803 // Then run over all slices
804 //
805
806 for ( Int_t iSli = 0;
807 iSli < TRIGGER_TIME_SLICES; iSli++ ) {
808
809 // Check if this time slice has more fired pixels than trigger_multi
810
811 if (SlicesZero[iSli]){
812 //
813 // then look in all pixel if the diskriminated signal is 1
814 //
815
816 for ( Int_t iPix = 0 ; iPix < TRIGGER_PIXELS; iPix++ ) {
817 Muster[iPix] = kFALSE ;
818 Neighb[iPix] = kFALSE ;
819 if ( used [iPix] == TRUE ) {
820 //
821 // now check the diskriminated signal
822 //
823 if ( d_sig [iPix][iSli] > 0. ) {
824
825 Muster[iPix] = kTRUE ;
826 }
827 }
828 } // end of loop over the pixels
829
830 //
831 // here we have to look for the topologies
832 //
833
834 switch(trigger_geometry){
835 case 0:{
836
837 // It looks for a pixel above threshold which has
838 // trigger_multi-1 neighbour pixels above threshold
839
840 Bool_t Dummy[TRIGGER_PIXELS] ;
841
842 // Loop over all pixels
843 for (int j=0;j<TRIGGER_PIXELS;j++){
844
845 //
846 // I commented out this line here
847 // Dummy=Muster;
848
849 for (int k=0; k<TRIGGER_PIXELS; k++){
850 Neighb[k]=kFALSE;
851
852 Dummy[k] = Muster[k] ;
853 }
854 if(Muster[j]){
855 // If pixel is fired, it checks how many fired neighbours it has
856 for (iMulti=1;iMulti<trigger_multi; iMulti++) {
857 Neighb[j] = kTRUE ;
858 Dummy[j] = kTRUE ;
859 if (!PassNextNeighbour(Dummy, &Neighb[0])){
860 break;
861 }
862 for (int k=0; k<TRIGGER_PIXELS; k++){
863 if (Neighb[k]){
864 Dummy[k]=kFALSE;
865 Neighb[k]=kFALSE;
866 }
867 }
868 }
869 if (iMulti==trigger_multi ) {
870 //
871 // A NN-Trigger is detected at time Slice
872 //
873 SlicesFirst[nFirst++] = iSli ; // We save time when it triggers
874 iReturn++ ;
875 iSli+=(50*SLICES_PER_NSEC); // We skip the following 50 ns (dead time)
876 break ;
877 }
878 }
879 }
880 break;
881 };
882
883 case 1:{
884
885 // It looks for trigger_multi neighbour pixels above the
886 // threshold.
887
888 for (int j=0;j<TRIGGER_PIXELS;j++){
889 if(Muster[j]){
890 // It checks if you can find
891 // trigger_multi fired neighbour pixels
892 Neighb[j] = kTRUE ;
893 for (iMulti=1;iMulti<trigger_multi; iMulti++) {
894 if (!PassNextNeighbour(Muster, &Neighb[0]))
895 break;
896 }
897 if (iMulti==trigger_multi ) {
898 //
899 // A NN-Trigger is detected at time Slice
900 //
901 SlicesFirst[nFirst++] = iSli ; // We save when it triggers
902 iReturn++ ;
903 iSli+=(50*SLICES_PER_NSEC); // We skip the following 50 ns (dead time)
904 break ;
905 }
906 else {
907 // We put Neighb to kFALSE to check an other pixel
908 for (int k=0; k<TRIGGER_PIXELS; k++){
909 if (Neighb[k]){
910 Neighb[k]=kFALSE;
911 }
912 }
913 }
914 }
915 }
916 break;
917 };
918 case 2:{
919
920 // It looks for trigger_multi closed pack neighbours
921 // above threshold
922 // Closed pack means that you can take out any pixel
923 // and you will still get a trigger for trigger_multi -1
924
925 Int_t closed_pack = 1;
926
927 for (int j=0;j<TRIGGER_PIXELS;j++){
928 if(Muster[j]){
929 // It checks if there are trigger_multi
930 // neighbours above threshold
931 Neighb[j] = kTRUE ;
932 for (iMulti=1;iMulti<trigger_multi; iMulti++){
933 if (!PassNextNeighbour(Muster, &Neighb[0]))
934 break;
935 }
936 if (iMulti==trigger_multi ) {
937 //
938 // A NN-Trigger is detected at time Slice
939 //
940
941 // Check if there is closed pack topology
942 Bool_t Aux1[TRIGGER_PIXELS];
943 Bool_t Aux2[TRIGGER_PIXELS];
944 for (int jj=0;jj<TRIGGER_PIXELS;jj++)
945 Aux2[jj]=kFALSE;
946
947 for (int i=0;i<TRIGGER_PIXELS;i++){
948 if (Neighb[i]) {
949 // Loop over pixels that achive neighbouring condition
950
951 // huschel
952 // here also some corrections were neccessary
953 //
954 //Aux1=Neighb;
955
956 for (int jj=0;jj<TRIGGER_PIXELS;jj++) {
957 Aux1[jj] = Neighb[jj] ; // huschel
958
959 Aux2[jj]=kFALSE;
960 }
961
962 Aux1[i]=kFALSE;
963 Aux2[j]=kTRUE;
964 // It checks if taking any of the pixels we lose
965 // neighbouring condition for trigger -1
966 for (iMulti=1;iMulti<(trigger_multi-1);iMulti++){
967 if (!PassNextNeighbour(Aux1, &Aux2[0]))
968 break;
969 }
970 if (iMulti<(trigger_multi-1)){
971 closed_pack=0;
972 break;
973 }
974
975 }
976 }
977 if (closed_pack){
978 SlicesFirst[nFirst++] = iSli ; // We save time when it triggers
979 iReturn++ ;
980 iSli+=(50*SLICES_PER_NSEC); // We skip the following 50 ns (dead time)
981 break ;
982 }
983 else {
984 for (int k=0; k<TRIGGER_PIXELS; k++){
985 if (Neighb[k]){
986 Neighb[k]=kFALSE;
987 }
988 }
989 }
990 }
991 else
992 for (int k=0; k<TRIGGER_PIXELS; k++)
993 Neighb[k]=kFALSE;
994 }
995 }
996 break;
997 };
998 default:{
999 cout << "This topology is not implemented yet"<<endl;
1000 break;
1001 }
1002 }
1003 }
1004 } // end of loop over the slices
1005 } // end of conditional for a trigger Zero
1006
1007 //
1008 // return the Number of FirstLevel Triggers
1009 //
1010 return iReturn ;
1011}
1012
1013
1014Bool_t MTrigger::PassNextNeighbour ( Bool_t m[], Bool_t *n) {
1015 //
1016 // This function is looking for a next neighbour of pixels in n[]
1017 // above triggers using a NNlookup table.
1018 // This table is builded by the default constructor
1019 //
1020
1021 //
1022 // loop over all trigger pixels
1023 //
1024
1025 Bool_t return_val = kFALSE;
1026
1027 for ( Int_t i=0; i<TRIGGER_PIXELS; i++) {
1028 //
1029 // check if this pixel has a diskrminator signal
1030 // (this is inside n[] )
1031 //
1032
1033 if ( n[i] && !return_val) {
1034
1035 //
1036 // look in the next neighbours from the lookuptable
1037 //
1038
1039 for ( Int_t kk=0; kk<6; kk++ ) {
1040 //
1041 // if the nextneighbour is outside the triggerarea do nothing
1042 //
1043 if (!return_val){
1044 if (NN[i][kk] >= TRIGGER_PIXELS ) {
1045
1046 }
1047 // the nextneighbour is not inside the TRIGGER_PIXELS
1048 else {
1049 //
1050 // look if the boolean of nn pixels is true
1051 //
1052
1053 if ( m[ NN[i][kk] ] && !n[NN[i][kk]] ) {
1054 n[NN[i][kk]]=kTRUE ;
1055 return_val =kTRUE;
1056 }
1057 }
1058 }
1059 else break;
1060 }
1061 }
1062 }
1063 return(return_val);
1064}
Note: See TracBrowser for help on using the repository browser.