32 #include <sys/types.h>
37 #define FCF_VERSION "5.31"
42 #include <rtsSystems.h>
43 #include <fcfClass.hh>
45 static const char *fcf_cvs_revision =
"$Revision: 1.7 $" ;
47 #ifdef __ROOT__ // STAR Offline
49 #include "StDaqLib/TPC/trans_table.hh"
51 #define FCF_10BIT_ADC // ADC data is already in 10 bits!
52 #define LOG(x1,x2,x3,x4,x5,x6,x7)
70 #if __GNUC__ == 2 && __GNUC_MINOR__ < 8
85 u_short t1, t2, p1, p2 ;
87 #if defined(FCF_SIM_ON) || defined(FCF_ANNOTATE_CLUSTERS)
98 #if __GNUC__ == 2 && __GNUC_MINOR__ < 8
107 #if defined(__unix) || defined(__APPLE__)
110 #define FCF_MAX_RES_COU_FAST 8
112 #define preburst4(x) // meaningless for UNIX
122 static u_int *simout ;
127 #ifdef FCF_ANNOTATE_CLUSTERS
141 #include "mzGlobal.h"
142 #include "mzInlines.h"
143 #include "mzFastTimer.h"
146 #define FCF_MAX_RES_COU_FAST ((sizeof(fastMem->fcfStore)/sizeof(struct fcfResx))/2)
148 #define FCF_960_R8 asm ("r8")
149 #define FCF_960_R9 asm ("r9")
150 #define FCF_960_R10 asm ("r10")
151 #define FCF_960_R11 asm ("r11")
152 #define FCF_960_R13 asm ("r13")
159 extern __inline
volatile void mstore(
struct fcfResx *rr,
int av,
int ch, u_int mean, u_int flags)
163 rr->charge = rr->scharge = ch ;
178 int fcfClass::finder(u_char *adcin, u_short *cppin, u_int *outres)
184 chargeMinCorrect = chargeMin * FCF_GAIN_FACTOR ;
186 int new_res_ix, new_res_cou, old_res_cou ;
189 u_int *cl_found_pointer, *row_pointer ;
192 struct fcfResx **new_res, **old_res ;
195 row_pointer = outres++ ;
196 cl_found_pointer = outres++ ;
198 *cl_found_pointer = 0 ;
203 u_int *sim_found_ptr, *sim_row_ptr ;
209 if(simin && simout) {
210 sim_row_ptr = simout++ ;
211 sim_found_ptr = simout++ ;
219 sim_found_ptr = simout ;
220 sim_row_ptr = simout ;
224 memset(pixStruct,0,
sizeof(pixStruct)) ;
230 new_res_cou = old_res_cou = 0 ;
233 new_res = old_res = NULL ;
241 for(pad=padStart;pad<=padStop;pad++) {
250 start_flags = startFlags[pad] ;
266 #if defined(__unix) || defined(__APPLE__)
267 static u_int cppStore[32] ;
268 u_int *ptrs = cppStore ;
270 u_int *ptrs = fastMem->cppStore ;
272 register u_int *ptrs_r = ptrs ;
273 register u_int *cpp_r = (u_int *)((
char *)cppin + cppOff[pad]) ;
274 register u_int fe00 = 0xFE00FE00 ;
276 u_int *ptrs_end = ptrs_r + 31 ;
281 while(ptrs_r < ptrs_end) {
285 register unsigned int first FCF_960_R8 ;
286 register unsigned int second FCF_960_R9 ;
287 register unsigned int third FCF_960_R10 ;
288 register unsigned int fourth FCF_960_R11 ;
291 #if defined(__unix) || defined(__APPLE__)
293 second = *(cpp_r+1) ;
295 fourth = *(cpp_r+3) ;
298 if(first & fe00)
goto go_out ;
301 if(second & fe00)
goto go_out ;
304 if(third & fe00)
goto go_out ;
307 if(fourth & fe00)
goto go_out ;
316 u_int cou_ptrs = (ptrs_r - ptrs) ;
327 u_short *val = (u_short *)((
char *)adcin + adcOff[pad]) ;
329 u_char *val = (u_char *)((
char *)adcin + adcOff[pad]) ;
335 simval = (u_short *)((
char *)simin + adcOff[pad]) ;
342 if((next_pad != pad) && new_res_cou) {
348 if((*cl_found_pointer + new_res_cou) >= maxClusters) {
349 LOG(ERR,
"Too many clusters in pad %d - breaking!",pad,0,0,0,0) ;
350 return outres - row_pointer ;
356 wrote = saveRes(new_res, new_res_cou, outres) ;
358 *cl_found_pointer += wrote ;
362 *sim_found_ptr += wrote ;
371 if(new_res_ix == 1) {
386 old_res_cou = new_res_cou ;
393 u_short *ptrs_16 = (u_short *)ptrs ;
396 for(cl_counter=0;cl_counter<cou_ptrs;cl_counter++) {
397 register u_int start, stop ;
399 start = (u_int)*ptrs_16++ ;
400 stop = (u_int) *ptrs_16++ ;
410 if(start < timebinLo) start = timebinLo ;
411 if(stop > timebinHi) stop = timebinHi ;
412 if(stop < start) continue ;
424 register u_short *adc_p = val + start ;
425 register u_short *adc_end = val + stop + 1;
427 register u_char *adc_p = val + start ;
428 register u_char *adc_end = val + stop + 1;
436 sim_p = simval + start ;
445 register int flags = FCF_ONEPAD | start_flags ;
446 register int adc = *adc_p++ ;
449 register int min_adc = minAdcT ;
450 #ifndef FCF_10BIT_ADC
451 register u_short *adc8to10 FCF_960_R13 = a8to10 ;
458 register int last_falling = 0 ;
459 register int max_a = 0 ;
460 register int mean FCF_960_R11 = 0 ;
461 register u_int charge FCF_960_R9 = 0 ;
462 register int av FCF_960_R8 = 0 ;
464 register int last_a = 0 ;
467 int max_sim = sim_id ;
480 if(unlikely(last_falling)) {
481 if(unlikely(adc > (last_a + min_adc))) {
482 flags |= FCF_DOUBLE_T ;
488 if(unlikely(adc < (last_a - min_adc))) {
492 if(unlikely(adc >= max_a)) {
508 a = log8to10_table[adc];
518 #ifdef FCF_NEW_ADC_ROUNDOFF
519 av += start*a + (start+1)/2 ;
529 pixStruct[pad][start].adc = a ;
530 pixStruct[pad][start].cl_id = cl_id ;
531 pixStruct[pad][start].id_simtrk = sim_id ;
542 }
while(likely(adc_p <= adc_end)) ;
545 #ifdef FCF_NEW_ADC_ROUNDOFF
547 charge += ((start-stop)+1)/2 ;
553 av = GC * av + T0C * charge ;
559 #if defined(__unix) || defined(__APPLE__)
560 if(charge > 0x7FFFFFFF) {
561 LOG(ERR,
"Whoa charge 0x%08X, %d GC",charge,GC,0,0,0) ;
567 struct fcfResx *rn = new_res[new_res_cou++];
570 rn->pad = charge*pad ;
573 mstore(rn,av,charge,mean,flags) ;
587 rn->pix = start-stop ;
588 rn->adc_max = max_a ;
590 rn->cl_id = cl_id++ ;
595 }
while(likely(adc_p <= adc_end)) ;
618 for(i=0;likely(i<old_res_cou);i++) {
624 register int merged = 0 ;
626 register int old_mean = rr->mean ;
627 register int old_mean_m = old_mean - param1 ;
628 register int old_mean_p = old_mean + param1 ;
630 register int min_adc = minAdcPad ;
632 register u_int old_scharge = rr->scharge ;
633 register u_int old_flags = rr->flags ;
638 for(j=start;likely(j<new_res_cou);j++) {
639 register struct fcfResx *nresx ;
646 if(mean < old_mean_m) {
650 else if(mean <= old_mean_p) {
651 register u_int charge ;
653 charge = nresx->charge ;
656 if(old_flags & FCF_FALLING) {
658 if(charge > (old_scharge + min_adc)) {
659 register u_int sc_tmp, sc_p_tmp ;
663 sc_tmp = old_scharge / 2 ;
664 sc_p_tmp = sc_tmp * (pad-1) ;
666 nresx->flags |= FCF_DOUBLE_PAD ;
670 nresx->charge += sc_tmp ;
671 nresx->pad += sc_p_tmp ;
673 nresx->t += (mean * sc_tmp) ;
678 if(unlikely(sc_tmp > rr->charge)) {
679 LOG(WARN,
"oops - going negative 0x%08X - 0x%08X",rr->charge,sc_tmp,0,0,0) ;
683 rr->charge -= sc_tmp ;
684 rr->pad -= sc_p_tmp ;
687 rr->t -= old_mean * sc_tmp ;
689 rr->flags = old_flags | FCF_DOUBLE_PAD ;
692 nresx->p1 = pad - 1 ;
701 nresx->flags |= FCF_FALLING ;
705 if((
int)charge < ((
int)old_scharge - min_adc)) {
707 nresx->flags |= FCF_FALLING ;
714 nresx->flags |= old_flags ;
715 nresx->flags &= (~FCF_ONEPAD) ;
718 nresx->scharge = charge ;
719 nresx->charge += rr->charge ;
720 nresx->pad += rr->pad ;
727 if(rr->t1 < nresx->t1) nresx->t1 = rr->t1 ;
728 if(rr->t2 > nresx->t2) nresx->t2 = rr->t2 ;
732 nresx->pix += rr->pix ;
736 if(rr->adc_max > nresx->adc_max) {
737 nresx->adc_max = rr->adc_max ;
744 for(
int ii=0;ii<512;ii++) {
745 if(nresx->cl_id == pixStruct[pad][ii].cl_id) {
746 pixStruct[pad][ii].cl_id = rr->cl_id ;
749 nresx->cl_id = rr->cl_id ;
769 if((*cl_found_pointer + 1) >= maxClusters) {
770 LOG(ERR,
"Too many clusters in pad %d - breaking!",pad,0,0,0,0) ;
771 return outres - row_pointer ;
778 wrote = saveRes(&rr, 1, outres) ;
780 *cl_found_pointer += wrote ;
783 *sim_found_ptr += wrote ;
799 if((*cl_found_pointer + new_res_cou) >= maxClusters) {
801 LOG(ERR,
"Too many clusters in pad %d - breaking!",pad,0,0,0,0) ;
802 return outres - row_pointer ;
807 wrote = saveRes(new_res, new_res_cou, outres) ;
809 *cl_found_pointer += wrote ;
812 *sim_found_ptr += wrote ;
823 return (outres - row_pointer) ;
828 fcfClass::fcfClass(
int det, u_short *table)
832 #if defined(__unix) || defined(__APPLE__)
833 a8to10 = adc8to10_storage ;
835 a8to10 = fastMem->adc8to10 ;
845 int num_start=0, num_end=0, num_dot=0 ;
847 for(i=0;i<strlen(fcf_cvs_revision);i++) {
848 if(isdigit(fcf_cvs_revision[i])) {
853 for(i=num_start;i<strlen(fcf_cvs_revision);i++) {
854 if(fcf_cvs_revision[i]==0x20) {
858 if(fcf_cvs_revision[i]==
'.') {
863 strncpy(tmp,&(fcf_cvs_revision[num_start]),1) ;
864 cvs_revision = atoi(tmp) << 16 ;
865 strncpy(tmp,&(fcf_cvs_revision[num_dot+1]),num_end-num_dot) ;
866 cvs_revision |= atoi(tmp) ;
876 noADCconversion = 1 ;
879 noADCconversion = 0 ;
890 param1 = FCF_PARAM1 ;
891 minAdcT = FCF_MIN_ADC_T ;
892 minAdcPad = FCF_MIN_ADC_PAD ;
917 LOG(WARN,
"Cluster Finder can't work with DET Type %d",det,0,0,0,0) ;
923 minAdcPad *= FCF_GAIN_FACTOR ;
925 static struct fcfResx res_slow[2][512] ;
926 #if defined(__unix) || defined(__APPLE__)
927 static struct fcfResx res_fast_ux[2][FCF_MAX_RES_COU_FAST] ;
928 struct fcfResx *res_fast[2] = { res_fast_ux[0], res_fast_ux[1] } ;
931 #define RES_COU (sizeof(struct fcfResx)*2*FCF_MAX_RES_COU_FAST)
932 #define I960_MAX_RES (sizeof(fastMem->fcfStore))
934 if(RES_COU > I960_MAX_RES) {
935 LOG(CRIT,
"Error in MAX_RES_COU size %d > %d!!!",RES_COU,I960_MAX_RES,0,0,0) ;
939 struct fcfResx *res_fast[2] = {
940 (
struct fcfResx *) fastMem->fcfStore,
941 (
struct fcfResx *) &(fastMem->fcfStore[(
sizeof(
struct fcfResx)/4)*FCF_MAX_RES_COU_FAST]) } ;
951 for(j=0;j<FCF_MAX_RES_COU_FAST;j++) {
952 resx[i][j] = res_fast[i] + j ;
957 for(j=FCF_MAX_RES_COU_FAST;j<512;j++) {
958 resx[i][j] = &(res_slow[i][j]) ;
967 void fcfClass::set8to10(u_short *table)
973 a8to10[i] = *table++ ;
975 noADCconversion = 0 ;
978 noADCconversion = 1 ;
984 inline int fcfClass::saveRes(
struct fcfResx *res_p[],
int cou, u_int *output)
989 register u_int ch_min = chargeMinCorrect ;
990 register int do_cuts = doCuts ;
1011 if(fla & FCF_BROKEN_EDGE) {
1014 else if(fla & (FCF_ROW_EDGE | FCF_DEAD_EDGE | FCF_ONEPAD)) continue ;
1015 else if(cha <= ch_min) continue ;
1016 else if(rr->t1 == 0) continue ;
1017 else if((rr->t2-rr->t1) <= 3) continue ;
1021 if((cha == 0) || (cha > 0x7FFFFFFF)) {
1030 if(pad_c > 0x04000000) {
1034 pad_c = (pad_c + t_cha/2) / t_cha ;
1037 pad_c = ((pad_c + cha/2) / cha) << 6 ;
1044 pad_c = ((pad_c << 6) + (cha/2)) / cha ;
1047 if(time_c > 0x04000000) {
1051 time_c = (time_c + t_cha/2) / t_cha ;
1054 time_c = ((time_c + cha/2) / cha) << 6 ;
1059 time_c = ((time_c << 6) + (cha/2)) / cha ;
1068 if((pad_c > 0xFFFF) || (time_c > 0xFFFF)) {
1076 fla |= FCF_DOUBLE_T | FCF_DOUBLE_PAD ;
1080 fla &= (~FCF_FALLING) ;
1084 if((pad_c & 0xc000) || (time_c & 0x8000)) {
1085 LOG(ERR,
"Strange pad 0x%04X, time 0x%04X...",pad_c,time_c,0,0,0) ;
1090 u_int p = (pad_c >> 6) ;
1093 u_int p1 = p - rr->p1 ;
1094 u_int p2 = rr->p2 - p ;
1106 fl = (p1 << 8) | (p2 << 11) ;
1115 if(p1 > 15) p1 = 15 ;
1116 if(p2 > 15) p2 = 15 ;
1123 fl |= (p2 << 4) | p1 ;
1131 if(fla & FCF_ONEPAD) time_c |= 0x8000 ;
1132 if(fla & (FCF_DOUBLE_T | FCF_DOUBLE_PAD)) pad_c |= 0x8000 ;
1133 if(fla & FCF_DEAD_EDGE) pad_c |= 0x4000 ;
1135 if(fla & FCF_ROW_EDGE) fl |= 0x8000 ;
1136 if(fla & FCF_BROKEN_EDGE) fl |= 0x4000 ;
1143 *output++ = (time_c << 16) | pad_c ;
1144 *output++ = (cha << 16) | fl ;
1156 u_int sim_cha, all_cha ;
1158 sim_cha = all_cha = 0 ;
1160 for(i=1;i<=182;i++) {
1161 for(j=0;j<512;j++) {
1162 if(pixStruct[i][j].cl_id == rr->cl_id) {
1163 if(rr->id == pixStruct[i][j].id_simtrk) {
1164 sim_cha += pixStruct[i][j].adc ;
1166 all_cha += pixStruct[i][j].adc ;
1172 quality = (int)(100.0*(
double)sim_cha/(double)all_cha) ;
1181 s->id_simtrk = rr->id ;
1182 s->id_quality = quality ;
1184 s->cl_id = rr->cl_id ;
1190 #if defined(FCF_ANNOTATE_CLUSTERS) && !defined(__ROOT__)
1191 for(i=1;i<=182;i++) {
1192 for(j=0;j<512;j++) {
1193 if(pixStruct[i][j].adc) {
1194 fcfPixA[row-1][i-1][j] = pixStruct[i][j] ;
1201 #endif // FCF_SIM_ON!