00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <stdio.h>
00031 #include <string.h>
00032 #include <sys/types.h>
00033 #include <stdlib.h>
00034 #include <stdarg.h>
00035
00036
00037 #define FCF_VERSION "5.31"
00038
00039
00040
00041 #include <rts.h>
00042 #include <rtsSystems.h>
00043 #include <fcfClass.hh>
00044
00045 static char *fcf_CVS_revision = "$Revision: 1.19 $" ;
00046
00047 #ifdef __ROOT__ // STAR Offline
00048
00049 #include "StDaqLib/TPC/trans_table.hh"
00050
00051 #define FCF_10BIT_ADC // ADC data is already in 10 bits!
00052 #define LOG(x1,x2,x3,x4,x5,x6,x7)
00053
00054
00055
00056 #else
00057
00058 #include <rtsLog.h>
00059
00060 #endif
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #if __GNUC__ == 2 && __GNUC_MINOR__ < 8
00071 #pragma align 1
00072 #pragma pack 1
00073 #endif
00074 namespace OLDEVP {
00075
00076 struct fcfResx {
00077 int t ;
00078 u_int charge ;
00079 u_int scharge ;
00080
00081 u_short flags ;
00082 short mean ;
00083
00084 u_int pad ;
00085
00086 u_short t1, t2, p1, p2 ;
00087
00088 #if defined(FCF_SIM_ON) || defined(FCF_ANNOTATE_CLUSTERS)
00089
00090 u_int pix ;
00091 u_int adc_max ;
00092
00093 short id ;
00094 u_short cl_id ;
00095 #endif
00096
00097 } ;
00098 }
00099
00100 #if __GNUC__ == 2 && __GNUC_MINOR__ < 8
00101 #pragma pack 0
00102 #pragma align 0
00103 #endif
00104
00105
00106
00107
00108
00109 #ifdef __unix
00110
00111
00112 #define FCF_MAX_RES_COU_FAST 8
00113
00114 #define preburst4(x) // meaningless for UNIX
00115
00116 #define FCF_960_R8
00117 #define FCF_960_R9
00118 #define FCF_960_R10
00119 #define FCF_960_R11
00120 #define FCF_960_R13
00121
00122
00123 #ifdef FCF_SIM_ON
00124 static u_int *simout ;
00125 static fcfPixAnnotate pixStruct[183][512];
00126 #endif
00127
00128
00129 #ifdef FCF_ANNOTATE_CLUSTERS
00130
00131
00132 #ifndef __ROOT__
00133 struct fcfPixAnnotate fcfPixA[45][182][512] ;
00134 #endif
00135
00136 #endif
00137
00138
00139
00140 #else // I960
00141
00142
00143 #include "mzGlobal.h"
00144 #include "mzInlines.h"
00145 #include "mzFastTimer.h"
00146
00147
00148 #define FCF_MAX_RES_COU_FAST ((sizeof(fastMem->fcfStore)/sizeof(struct fcfResx))/2)
00149
00150 #define FCF_960_R8 asm ("r8")
00151 #define FCF_960_R9 asm ("r9")
00152 #define FCF_960_R10 asm ("r10")
00153 #define FCF_960_R11 asm ("r11")
00154 #define FCF_960_R13 asm ("r13")
00155
00156
00157
00158 #endif // UNIX
00159
00160
00161 extern __inline volatile void mstore(struct fcfResx *rr, int av, int ch, u_int mean, u_int flags)
00162 {
00163
00164 rr->t = av ;
00165 rr->charge = rr->scharge = ch ;
00166
00167 rr->flags = flags ;
00168 rr->mean = mean ;
00169
00170 return ;
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180 int fcfClass::finder(u_char *adcin, u_short *cppin, u_int *outres)
00181 {
00182 int i, j, pad ;
00183 int next_pad ;
00184 u_int start_flags ;
00185
00186 chargeMinCorrect = chargeMin * FCF_GAIN_FACTOR ;
00187
00188 int new_res_ix, new_res_cou, old_res_cou ;
00189
00190
00191 u_int *cl_found_pointer, *row_pointer ;
00192
00193
00194 struct fcfResx **new_res, **old_res ;
00195
00196
00197 row_pointer = outres++ ;
00198 cl_found_pointer = outres++ ;
00199
00200 *cl_found_pointer = 0 ;
00201 *row_pointer = row ;
00202
00203
00204 #ifdef FCF_SIM_ON
00205 u_int *sim_found_ptr, *sim_row_ptr ;
00206 short *simin ;
00207
00208 simin = simIn ;
00209 simout = simOut ;
00210
00211 if(simin && simout) {
00212 sim_row_ptr = simout++ ;
00213 sim_found_ptr = simout++ ;
00214
00215 *sim_found_ptr = 0 ;
00216 *sim_row_ptr = row ;
00217 }
00218 else {
00219 simout = 0 ;
00220
00221 sim_found_ptr = simout ;
00222 sim_row_ptr = simout ;
00223 }
00224
00225 u_short cl_id = 1 ;
00226 memset(pixStruct,0,sizeof(pixStruct)) ;
00227
00228 #endif
00229
00230
00231 new_res_ix = 0 ;
00232 new_res_cou = old_res_cou = 0 ;
00233
00234
00235 new_res = old_res = NULL ;
00236 next_pad = 0 ;
00237
00238
00239
00240
00241
00242
00243 for(pad=padStart;pad<=padStop;pad++) {
00244 u_int GC ;
00245 int T0C ;
00246
00247
00248 GC = gainCorr[pad] ;
00249 T0C = t0Corr[pad] ;
00250
00251 if(startFlags) {
00252 start_flags = startFlags[pad] ;
00253 }
00254 else {
00255 start_flags = 0 ;
00256 }
00257
00258 if(GC == 0) {
00259
00260 continue ;
00261 }
00262
00263
00264
00265
00266
00267
00268 #ifdef __unix
00269 static u_int cppStore[32] ;
00270 u_int *ptrs = cppStore ;
00271 #else
00272 u_int *ptrs = fastMem->cppStore ;
00273 #endif
00274 register u_int *ptrs_r = ptrs ;
00275 register u_int *cpp_r = (u_int *)((char*)cppin + cppOff[pad]) ;
00276 register u_int fe00 = 0xFE00FE00 ;
00277
00278 u_int *ptrs_end = ptrs_r + 31 ;
00279
00280
00281
00282
00283 while(ptrs_r < ptrs_end) {
00284
00285
00286
00287 register unsigned int first FCF_960_R8 ;
00288 register unsigned int second FCF_960_R9 ;
00289 register unsigned int third FCF_960_R10 ;
00290 register unsigned int fourth FCF_960_R11 ;
00291
00292 preburst4(cpp_r) ;
00293 #ifdef __unix
00294 first = *cpp_r ;
00295 second = *(cpp_r+1) ;
00296 third = *(cpp_r+2) ;
00297 fourth = *(cpp_r+3) ;
00298
00299 #endif
00300 if(first & fe00) goto go_out ;
00301 *ptrs_r++ = first ;
00302
00303 if(second & fe00) goto go_out ;
00304 *ptrs_r++ = second ;
00305
00306 if(third & fe00) goto go_out ;
00307 *ptrs_r++ = third ;
00308
00309 if(fourth & fe00) goto go_out ;
00310 *ptrs_r++ = fourth ;
00311
00312 cpp_r += 4 ;
00313 }
00314
00315
00316 go_out : ;
00317
00318 u_int cou_ptrs = (ptrs_r - ptrs) ;
00319
00320
00321
00322 if(cou_ptrs == 0) {
00323 continue ;
00324 }
00325
00326
00327
00328 #ifdef FCF_10BIT_ADC
00329 u_short *val = (u_short *)((char*)adcin + adcOff[pad]) ;
00330 #else
00331 u_char *val = (u_char *)((u_int)adcin + adcOff[pad]) ;
00332 #endif
00333
00334 #ifdef FCF_SIM_ON
00335 u_short *simval ;
00336 if(simout) {
00337 simval = (u_short *)((char*)simin + adcOff[pad]) ;
00338 }
00339 else {
00340 simval = 0 ;
00341 }
00342 #endif
00343
00344 if((next_pad != pad) && new_res_cou) {
00345
00346
00347 int wrote ;
00348
00349
00350 if((*cl_found_pointer + new_res_cou) >= maxClusters) {
00351 LOG(ERR,"Too many clusters in pad %d - breaking!",pad,0,0,0,0) ;
00352 return outres - row_pointer ;
00353 }
00354
00355
00356
00357
00358 wrote = saveRes(new_res, new_res_cou, outres) ;
00359 outres += wrote*2 ;
00360 *cl_found_pointer += wrote ;
00361
00362 #ifdef FCF_SIM_ON
00363 if(simout) {
00364 *sim_found_ptr += wrote ;
00365 }
00366 #endif
00367
00368 new_res_cou = 0 ;
00369 }
00370
00371
00372
00373 if(new_res_ix == 1) {
00374 new_res_ix = 0 ;
00375
00376 old_res = resx[1] ;
00377 new_res = resx[0] ;
00378
00379 }
00380 else {
00381 new_res_ix = 1 ;
00382
00383 old_res = resx[0] ;
00384 new_res = resx[1] ;
00385
00386 }
00387
00388 old_res_cou = new_res_cou ;
00389 new_res_cou = 0 ;
00390
00391
00392
00393
00394
00395 u_short *ptrs_16 = (u_short *)ptrs ;
00396 u_int cl_counter ;
00397
00398 for(cl_counter=0;cl_counter<cou_ptrs;cl_counter++) {
00399 register u_int start, stop ;
00400
00401 start = (u_int)*ptrs_16++ ;
00402 stop = (u_int) *ptrs_16++ ;
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 if(start < timebinLo) start = timebinLo ;
00413 if(stop > timebinHi) stop = timebinHi ;
00414 if(stop < start) continue ;
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 #ifdef FCF_10BIT_ADC
00426 register u_short *adc_p = val + start ;
00427 register u_short *adc_end = val + stop + 1;
00428 #else
00429 register u_char *adc_p = val + start ;
00430 register u_char *adc_end = val + stop + 1;
00431 #endif
00432
00433 #ifdef FCF_SIM_ON
00434 u_short *sim_p ;
00435 u_short sim_id ;
00436
00437 if(simout) {
00438 sim_p = simval + start ;
00439 sim_id = *sim_p++ ;
00440 }
00441 else {
00442 sim_p = 0 ;
00443 sim_id = 0 ;
00444 }
00445 #endif
00446
00447 register int flags = FCF_ONEPAD | start_flags ;
00448 register int adc = *adc_p++ ;
00449
00450
00451 register int min_adc = minAdcT ;
00452 #ifndef FCF_10BIT_ADC
00453 register u_short *adc8to10 FCF_960_R13 = a8to10 ;
00454 #endif
00455
00456
00457
00458
00459 do {
00460 register int last_falling = 0 ;
00461 register int max_a = 0 ;
00462 register int mean FCF_960_R11 = 0 ;
00463 register u_int charge FCF_960_R9 = 0 ;
00464 register int av FCF_960_R8 = 0 ;
00465
00466 register int last_a = 0 ;
00467
00468 #ifdef FCF_SIM_ON
00469 int max_sim = sim_id ;
00470 #endif
00471
00472
00473 stop = start ;
00474
00475
00476
00477 do {
00478
00479 register int a ;
00480
00481
00482 if(unlikely(last_falling)) {
00483 if(unlikely(adc > (last_a + min_adc))) {
00484 flags |= FCF_DOUBLE_T ;
00485
00486 break ;
00487 }
00488 }
00489 else {
00490 if(unlikely(adc < (last_a - min_adc))) {
00491 last_falling = 1 ;
00492 }
00493 else {
00494 if(unlikely(adc >= max_a)) {
00495 max_a = adc ;
00496 #ifdef FCF_SIM_ON
00497 max_sim = sim_id ;
00498 #endif
00499 mean = start ;
00500
00501 }
00502
00503 }
00504 }
00505
00506 #ifdef FCF_10BIT_ADC
00507
00508
00509
00510 a = log8to10_table[adc];
00511
00512
00513
00514
00515 #else
00516 a = adc8to10[adc] ;
00517 #endif
00518 last_a = adc ;
00519
00520 #ifdef FCF_NEW_ADC_ROUNDOFF
00521 av += start*a + (start+1)/2 ;
00522 #else
00523 av += start * a ;
00524 #endif
00525 charge += a ;
00526
00527
00528
00529 adc = *adc_p++ ;
00530 #ifdef FCF_SIM_ON
00531 pixStruct[pad][start].adc = a ;
00532 pixStruct[pad][start].cl_id = cl_id ;
00533 pixStruct[pad][start].id_simtrk = sim_id ;
00534
00535 if(simout) {
00536 sim_id = *sim_p++ ;
00537 }
00538 #endif
00539
00540
00541
00542 start++ ;
00543
00544 } while(likely(adc_p <= adc_end)) ;
00545
00546
00547 #ifdef FCF_NEW_ADC_ROUNDOFF
00548
00549 charge += ((start-stop)+1)/2 ;
00550
00551 #endif
00552
00553
00554
00555 av = GC * av + T0C * charge ;
00556
00557
00558 charge *= GC ;
00559
00560
00561 #ifdef __unix
00562 if(charge > 0x7FFFFFFF) {
00563 LOG(ERR,"Whoa charge 0x%08X, %d GC",charge,GC,0,0,0) ;
00564 }
00565 #endif
00566
00567
00568
00569 struct fcfResx *rn = new_res[new_res_cou++];
00570
00571
00572 rn->pad = charge*pad ;
00573
00574
00575 mstore(rn,av,charge,mean,flags) ;
00576
00577
00578 rn->p1 = pad ;
00579 rn->p2 = pad ;
00580 rn->t1 = stop ;
00581 rn->t2 = start-1 ;
00582
00583
00584
00585
00586 #ifdef FCF_SIM_ON
00587 rn->pix = start-stop ;
00588 rn->adc_max = max_a ;
00589 rn->id = max_sim ;
00590 rn->cl_id = cl_id++ ;
00591 #endif
00592
00593
00594
00595 } while(likely(adc_p <= adc_end)) ;
00596
00597
00598
00599
00600 }
00601
00602
00603
00604
00605
00606 if(new_res_cou) {
00607 next_pad = pad + 1 ;
00608 }
00609
00610
00611
00612
00613
00614
00615
00616 int new_start = 0 ;
00617
00618 for(i=0;likely(i<old_res_cou);i++) {
00619 register struct fcfResx *rr ;
00620 register int start ;
00621
00622 rr = old_res[i] ;
00623
00624 register int merged = 0 ;
00625
00626 register int old_mean = rr->mean ;
00627 register int old_mean_m = old_mean - param1 ;
00628 register int old_mean_p = old_mean + param1 ;
00629
00630 register int min_adc = minAdcPad ;
00631
00632 register u_int old_scharge = rr->scharge ;
00633 register u_int old_flags = rr->flags ;
00634
00635 start = new_start ;
00636
00637
00638 for(j=start;likely(j<new_res_cou);j++) {
00639 register struct fcfResx *nresx ;
00640 register int mean ;
00641
00642 nresx = new_res[j] ;
00643
00644 mean = nresx->mean ;
00645
00646 if(mean < old_mean_m) {
00647 new_start = j + 1 ;
00648 continue ;
00649 }
00650 else if(mean <= old_mean_p) {
00651 register u_int charge ;
00652
00653 charge = nresx->charge ;
00654
00655
00656 if(old_flags & FCF_FALLING) {
00657
00658 if(charge > (old_scharge + min_adc)) {
00659 register u_int sc_tmp, sc_p_tmp ;
00660
00661
00662
00663 sc_tmp = old_scharge / 2 ;
00664 sc_p_tmp = sc_tmp * (pad-1) ;
00665
00666 nresx->flags |= FCF_DOUBLE_PAD ;
00667
00668
00669
00670 nresx->charge += sc_tmp ;
00671 nresx->pad += sc_p_tmp ;
00672
00673 nresx->t += (mean * sc_tmp) ;
00674
00675
00676
00677
00678 if(unlikely(sc_tmp > rr->charge)) {
00679 LOG(WARN,"oops - going negative 0x%08X - 0x%08X",rr->charge,sc_tmp,0,0,0) ;
00680 }
00681
00682
00683 rr->charge -= sc_tmp ;
00684 rr->pad -= sc_p_tmp ;
00685
00686
00687 rr->t -= old_mean * sc_tmp ;
00688
00689 rr->flags = old_flags | FCF_DOUBLE_PAD ;
00690
00691
00692 nresx->p1 = pad - 1 ;
00693 rr->p2 = pad ;
00694
00695 new_start = j+1 ;
00696
00697 break ;
00698
00699 }
00700
00701 nresx->flags |= FCF_FALLING ;
00702 }
00703 else {
00704
00705 if((int)charge < ((int)old_scharge - min_adc)) {
00706
00707 nresx->flags |= FCF_FALLING ;
00708 }
00709 }
00710
00711
00712 merged = 1 ;
00713
00714 nresx->flags |= old_flags ;
00715 nresx->flags &= (~FCF_ONEPAD) ;
00716
00717
00718 nresx->scharge = charge ;
00719 nresx->charge += rr->charge ;
00720 nresx->pad += rr->pad ;
00721 nresx->t += rr->t ;
00722
00723
00724
00725
00726 nresx->p1 = rr->p1 ;
00727 if(rr->t1 < nresx->t1) nresx->t1 = rr->t1 ;
00728 if(rr->t2 > nresx->t2) nresx->t2 = rr->t2 ;
00729
00730
00731 #ifdef FCF_SIM_ON
00732 nresx->pix += rr->pix ;
00733
00734
00735 if(rr->adc_max > nresx->adc_max) {
00736 nresx->adc_max = rr->adc_max ;
00737
00738 nresx->id = rr->id ;
00739 }
00740
00741
00742
00743 for(int ii=0;ii<512;ii++) {
00744 if(nresx->cl_id == pixStruct[pad][ii].cl_id) {
00745 pixStruct[pad][ii].cl_id = rr->cl_id ;
00746 }
00747 }
00748 nresx->cl_id = rr->cl_id ;
00749
00750 #endif
00751 new_start = j + 1 ;
00752
00753 break ;
00754 }
00755 else {
00756 new_start = j ;
00757
00758 break ;
00759 }
00760
00761 }
00762
00763
00764 if(!merged) {
00765 int wrote ;
00766
00767
00768 if((*cl_found_pointer + 1) >= maxClusters) {
00769 LOG(ERR,"Too many clusters in pad %d - breaking!",pad,0,0,0,0) ;
00770 return outres - row_pointer ;
00771 }
00772
00773
00774
00775
00776
00777 wrote = saveRes(&rr, 1, outres) ;
00778 outres += wrote*2 ;
00779 *cl_found_pointer += wrote ;
00780 #ifdef FCF_SIM_ON
00781 if(simout) {
00782 *sim_found_ptr += wrote ;
00783 }
00784 #endif
00785 }
00786
00787 }
00788
00789
00790
00791 }
00792
00793
00794 if(new_res_cou) {
00795 int wrote ;
00796
00797
00798 if((*cl_found_pointer + new_res_cou) >= maxClusters) {
00799
00800 LOG(ERR,"Too many clusters in pad %d - breaking!",pad,0,0,0,0) ;
00801 return outres - row_pointer ;
00802 }
00803
00804
00805
00806 wrote = saveRes(new_res, new_res_cou, outres) ;
00807 outres += wrote*2 ;
00808 *cl_found_pointer += wrote ;
00809 #ifdef FCF_SIM_ON
00810 if(simout) {
00811 *sim_found_ptr += wrote ;
00812 }
00813 #endif
00814 }
00815
00816
00817
00818
00819
00820
00821
00822 return (outres - row_pointer) ;
00823
00824 }
00825
00826
00827 fcfClass::fcfClass(int det, u_short *table)
00828 {
00829 detector = det ;
00830
00831 #ifdef __unix
00832 a8to10 = adc8to10_storage ;
00833 #else // I960
00834 a8to10 = fastMem->adc8to10 ;
00835 #endif
00836
00837
00838 simIn = 0 ;
00839 simOut = 0 ;
00840
00841 if(table == NULL) {
00842 noADCconversion = 1 ;
00843 }
00844 else {
00845 noADCconversion = 0 ;
00846 }
00847
00848
00849 svtPedestal = 0 ;
00850
00851
00852 deconTime = 1 ;
00853 deconPad = 1 ;
00854 doCuts = 1 ;
00855
00856 param1 = FCF_PARAM1 ;
00857 minAdcT = FCF_MIN_ADC_T ;
00858 minAdcPad = FCF_MIN_ADC_PAD ;
00859
00860 switch(det) {
00861 case TPC_ID :
00862 maxCPP = 31 ;
00863 maxTimebin = 511 ;
00864 timebinLo = 0 ;
00865 timebinHi = 400 ;
00866 chargeMin = 40 ;
00867 break ;
00868 case FTP_ID :
00869 maxCPP = 31 ;
00870 maxTimebin = 511 ;
00871 timebinLo = 0 ;
00872 timebinHi = 255 ;
00873 chargeMin = 40 ;
00874 break ;
00875 case SVT_ID :
00876 maxCPP = 8 ;
00877 maxTimebin = 127 ;
00878 timebinLo = 0 ;
00879 timebinHi = 127 ;
00880 chargeMin = 20 ;
00881 break ;
00882 default :
00883 LOG(WARN,"Cluster Finder can't work with DET Type %d",det,0,0,0,0) ;
00884 return ;
00885 }
00886
00887
00888
00889 minAdcPad *= FCF_GAIN_FACTOR ;
00890
00891 static struct fcfResx res_slow[2][512] ;
00892 #ifdef __unix
00893 static struct fcfResx res_fast_ux[2][FCF_MAX_RES_COU_FAST] ;
00894 struct fcfResx *res_fast[2] = { res_fast_ux[0], res_fast_ux[1] } ;
00895 #else
00896
00897 #define RES_COU (sizeof(struct fcfResx)*2*FCF_MAX_RES_COU_FAST)
00898 #define I960_MAX_RES (sizeof(fastMem->fcfStore))
00899
00900 if(RES_COU > I960_MAX_RES) {
00901 LOG(CRIT,"Error in MAX_RES_COU size %d > %d!!!",RES_COU,I960_MAX_RES,0,0,0) ;
00902 }
00903
00904
00905 struct fcfResx *res_fast[2] = {
00906 (struct fcfResx *) fastMem->fcfStore,
00907 (struct fcfResx *) &(fastMem->fcfStore[(sizeof(struct fcfResx)/4)*FCF_MAX_RES_COU_FAST]) } ;
00908
00909
00910
00911
00912 #endif
00913
00914
00915 u_int i, j ;
00916 for(i=0;i<2;i++) {
00917 for(j=0;j<FCF_MAX_RES_COU_FAST;j++) {
00918 resx[i][j] = res_fast[i] + j ;
00919
00920 }
00921 }
00922 for(i=0;i<2;i++) {
00923 for(j=FCF_MAX_RES_COU_FAST;j<512;j++) {
00924 resx[i][j] = &(res_slow[i][j]) ;
00925 }
00926 }
00927
00928 return ;
00929 }
00930
00931
00932
00933 void fcfClass::set8to10(u_short *table)
00934 {
00935 int i ;
00936
00937 if(table) {
00938 for(i=0;i<256;i++) {
00939 a8to10[i] = *table++ ;
00940 }
00941 noADCconversion = 0 ;
00942 }
00943 else {
00944 noADCconversion = 1 ;
00945 }
00946 return ;
00947 }
00948
00949
00950 inline int fcfClass::saveRes(struct fcfResx *res_p[], int cou, u_int *output)
00951 {
00952
00953 int i ;
00954 int saved = 0 ;
00955 register u_int ch_min = chargeMinCorrect ;
00956 register int do_cuts = doCuts ;
00957 u_int fla, cha ;
00958 u_int pad_c ;
00959 u_int time_c ;
00960 u_int t_cha ;
00961
00962 for(i=0;i<cou;i++) {
00963 struct fcfResx *rr ;
00964
00965 rr = res_p[i] ;
00966
00967
00968 fla = rr->flags ;
00969 cha = rr->charge ;
00970
00971
00972
00973
00974
00975
00976 if(do_cuts) {
00977 if(fla & FCF_BROKEN_EDGE) {
00978 ;
00979 }
00980 else if(fla & (FCF_ROW_EDGE | FCF_DEAD_EDGE | FCF_ONEPAD)) continue ;
00981 else if(cha <= ch_min) continue ;
00982 else if(rr->t1 == 0) continue ;
00983 else if((rr->t2-rr->t1) <= 3) continue ;
00984 }
00985
00986
00987 if((cha == 0) || (cha > 0x7FFFFFFF)) {
00988
00989 continue ;
00990 }
00991
00992
00993 pad_c = rr->pad ;
00994 time_c = rr->t ;
00995
00996 if(pad_c > 0x04000000) {
00997 t_cha = cha >> 6 ;
00998
00999 if(t_cha) {
01000 pad_c = (pad_c + t_cha/2) / t_cha ;
01001 }
01002 else {
01003 pad_c = ((pad_c + cha/2) / cha) << 6 ;
01004 }
01005
01006
01007 }
01008 else {
01009
01010 pad_c = ((pad_c << 6) + (cha/2)) / cha ;
01011 }
01012
01013 if(time_c > 0x04000000) {
01014 t_cha = cha >> 6 ;
01015
01016 if(t_cha) {
01017 time_c = (time_c + t_cha/2) / t_cha ;
01018 }
01019 else {
01020 time_c = ((time_c + cha/2) / cha) << 6 ;
01021 }
01022 }
01023 else {
01024
01025 time_c = ((time_c << 6) + (cha/2)) / cha ;
01026 }
01027
01028
01029
01030 cha = (cha+32)/64 ;
01031
01032
01033
01034 if((pad_c > 0xFFFF) || (time_c > 0xFFFF)) {
01035
01036 continue ;
01037 }
01038
01039 if(cha > 0xFFFF) {
01040
01041 cha = 0xFFFF ;
01042 fla |= FCF_DOUBLE_T | FCF_DOUBLE_PAD ;
01043 }
01044
01045
01046
01047
01048
01049
01050 if((pad_c & 0xc000) || (time_c & 0x8000)) {
01051 LOG(ERR,"Strange pad 0x%04X, time 0x%04X...",pad_c,time_c,0,0,0) ;
01052 continue ;
01053 }
01054
01055
01056 u_int p = (pad_c >> 6) ;
01057 u_int fl ;
01058
01059 u_int p1 = p - rr->p1 ;
01060 u_int p2 = rr->p2 - p ;
01061
01062 if(p1 > 7) p1 = 7 ;
01063 if(p2 > 7) p2 = 7 ;
01064
01065
01066
01067
01068
01069
01070
01071
01072 fl = (p1 << 8) | (p2 << 11) ;
01073
01074
01075 p = (time_c >> 6) ;
01076
01077
01078 p1 = p - rr->t1 ;
01079 p2 = rr->t2 - p ;
01080
01081 if(p1 > 15) p1 = 15 ;
01082 if(p2 > 15) p2 = 15 ;
01083
01084
01085
01086
01087
01088
01089 fl |= (p2 << 4) | p1 ;
01090
01091
01092
01093
01094
01095
01096
01097 if(fla & FCF_ONEPAD) time_c |= 0x8000 ;
01098 if(fla & (FCF_DOUBLE_T | FCF_DOUBLE_PAD)) pad_c |= 0x8000 ;
01099 if(fla & FCF_DEAD_EDGE) pad_c |= 0x4000 ;
01100
01101 if(fla & FCF_ROW_EDGE) fl |= 0x8000 ;
01102 if(fla & FCF_BROKEN_EDGE) fl |= 0x4000 ;
01103
01104
01105
01106
01107
01108
01109 *output++ = (time_c << 16) | pad_c ;
01110 *output++ = (cha << 16) | fl ;
01111
01112 #ifdef FCF_SIM_ON
01113
01114 {
01115 int i, j ;
01116
01117 int quality = 1 ;
01118
01119 if(simout) {
01120
01121 u_int sim_cha, all_cha ;
01122
01123 sim_cha = all_cha = 0 ;
01124
01125 for(i=1;i<=182;i++) {
01126 for(j=0;j<512;j++) {
01127 if(pixStruct[i][j].cl_id == rr->cl_id) {
01128 if(rr->id == pixStruct[i][j].id_simtrk) {
01129 sim_cha += pixStruct[i][j].adc ;
01130 }
01131 all_cha += pixStruct[i][j].adc ;
01132 }
01133 }
01134 }
01135
01136 if(all_cha) {
01137 quality = (int)(100.0*(double)sim_cha/(double)all_cha) ;
01138 }
01139 else {
01140 quality = 0 ;
01141 }
01142
01143
01144 struct FcfSimOutput *s = (struct FcfSimOutput *) simout ;
01145
01146 s->id_simtrk = rr->id ;
01147 s->id_quality = quality ;
01148
01149 s->cl_id = rr->cl_id ;
01150
01151 simout += sizeof(struct FcfSimOutput)/4 ;
01152
01153 }
01154
01155 #if defined(FCF_ANNOTATE_CLUSTERS) && !defined(__ROOT__)
01156 for(i=1;i<=182;i++) {
01157 for(j=0;j<512;j++) {
01158 if(pixStruct[i][j].adc) {
01159 fcfPixA[row-1][i-1][j] = pixStruct[i][j] ;
01160 }
01161 }
01162 }
01163 #endif
01164 }
01165
01166 #endif // FCF_SIM_ON!
01167
01168
01169
01170
01171
01172
01173
01174 saved++ ;
01175
01176
01177 }
01178
01179
01180 return saved ;
01181 }
01182