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 #include <ctype.h>
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.4 $" ;
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
00075 struct fcfResx {
00076 int t ;
00077 u_int charge ;
00078 u_int scharge ;
00079
00080 u_short flags ;
00081 short mean ;
00082
00083 u_int pad ;
00084
00085 u_short t1, t2, p1, p2 ;
00086
00087 #if defined(FCF_SIM_ON) || defined(FCF_ANNOTATE_CLUSTERS)
00088
00089 u_int pix ;
00090 u_int adc_max ;
00091
00092 short id ;
00093 u_short cl_id ;
00094 #endif
00095
00096 } ;
00097
00098 #if __GNUC__ == 2 && __GNUC_MINOR__ < 8
00099 #pragma pack 0
00100 #pragma align 0
00101 #endif
00102
00103
00104
00105
00106
00107 #ifdef __unix
00108
00109
00110 #define FCF_MAX_RES_COU_FAST 8
00111
00112 #define preburst4(x) // meaningless for UNIX
00113
00114 #define FCF_960_R8
00115 #define FCF_960_R9
00116 #define FCF_960_R10
00117 #define FCF_960_R11
00118 #define FCF_960_R13
00119
00120
00121 #ifdef FCF_SIM_ON
00122 static u_int *simout ;
00123 static fcfPixAnnotate pixStruct[183][512];
00124 #endif
00125
00126
00127 #ifdef FCF_ANNOTATE_CLUSTERS
00128
00129
00130 #ifndef __ROOT__
00131 struct fcfPixAnnotate fcfPixA[45][182][512] ;
00132 #endif
00133
00134 #endif
00135
00136
00137
00138 #else // I960
00139
00140
00141 #include "mzGlobal.h"
00142 #include "mzInlines.h"
00143 #include "mzFastTimer.h"
00144
00145
00146 #define FCF_MAX_RES_COU_FAST ((sizeof(fastMem->fcfStore)/sizeof(struct fcfResx))/2)
00147
00148 #define FCF_960_R8 asm ("r8")
00149 #define FCF_960_R9 asm ("r9")
00150 #define FCF_960_R10 asm ("r10")
00151 #define FCF_960_R11 asm ("r11")
00152 #define FCF_960_R13 asm ("r13")
00153
00154
00155
00156 #endif // UNIX
00157
00158
00159 extern __inline volatile void mstore(struct fcfResx *rr, int av, int ch, u_int mean, u_int flags)
00160 {
00161
00162 rr->t = av ;
00163 rr->charge = rr->scharge = ch ;
00164
00165 rr->flags = flags ;
00166 rr->mean = mean ;
00167
00168 return ;
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178 int fcfClass::finder(u_char *adcin, u_short *cppin, u_int *outres)
00179 {
00180 int i, j, pad ;
00181 int next_pad ;
00182 u_int start_flags ;
00183
00184 chargeMinCorrect = chargeMin * FCF_GAIN_FACTOR ;
00185
00186 int new_res_ix, new_res_cou, old_res_cou ;
00187
00188
00189 u_int *cl_found_pointer, *row_pointer ;
00190
00191
00192 struct fcfResx **new_res, **old_res ;
00193
00194
00195 row_pointer = outres++ ;
00196 cl_found_pointer = outres++ ;
00197
00198 *cl_found_pointer = 0 ;
00199 *row_pointer = row ;
00200
00201
00202 #ifdef FCF_SIM_ON
00203 u_int *sim_found_ptr, *sim_row_ptr ;
00204 short *simin ;
00205
00206 simin = simIn ;
00207 simout = simOut ;
00208
00209 if(simin && simout) {
00210 sim_row_ptr = simout++ ;
00211 sim_found_ptr = simout++ ;
00212
00213 *sim_found_ptr = 0 ;
00214 *sim_row_ptr = row ;
00215 }
00216 else {
00217 simout = 0 ;
00218
00219 sim_found_ptr = simout ;
00220 sim_row_ptr = simout ;
00221 }
00222
00223 u_short cl_id = 1 ;
00224 memset(pixStruct,0,sizeof(pixStruct)) ;
00225
00226 #endif
00227
00228
00229 new_res_ix = 0 ;
00230 new_res_cou = old_res_cou = 0 ;
00231
00232
00233 new_res = old_res = NULL ;
00234 next_pad = 0 ;
00235
00236
00237
00238
00239
00240
00241 for(pad=padStart;pad<=padStop;pad++) {
00242 u_int GC ;
00243 int T0C ;
00244
00245
00246 GC = gainCorr[pad] ;
00247 T0C = t0Corr[pad] ;
00248
00249 if(startFlags) {
00250 start_flags = startFlags[pad] ;
00251 }
00252 else {
00253 start_flags = 0 ;
00254 }
00255
00256 if(GC == 0) {
00257
00258 continue ;
00259 }
00260
00261
00262
00263
00264
00265
00266 #ifdef __unix
00267 static u_int cppStore[32] ;
00268 u_int *ptrs = cppStore ;
00269 #else
00270 u_int *ptrs = fastMem->cppStore ;
00271 #endif
00272 register u_int *ptrs_r = ptrs ;
00273 register u_int *cpp_r = (u_int *)((char *)cppin + cppOff[pad]) ;
00274 register u_int fe00 = 0xFE00FE00 ;
00275
00276 u_int *ptrs_end = ptrs_r + 31 ;
00277
00278
00279
00280
00281 while(ptrs_r < ptrs_end) {
00282
00283
00284
00285 register unsigned int first FCF_960_R8 ;
00286 register unsigned int second FCF_960_R9 ;
00287 register unsigned int third FCF_960_R10 ;
00288 register unsigned int fourth FCF_960_R11 ;
00289
00290 preburst4(cpp_r) ;
00291 #ifdef __unix
00292 first = *cpp_r ;
00293 second = *(cpp_r+1) ;
00294 third = *(cpp_r+2) ;
00295 fourth = *(cpp_r+3) ;
00296
00297 #endif
00298 if(first & fe00) goto go_out ;
00299 *ptrs_r++ = first ;
00300
00301 if(second & fe00) goto go_out ;
00302 *ptrs_r++ = second ;
00303
00304 if(third & fe00) goto go_out ;
00305 *ptrs_r++ = third ;
00306
00307 if(fourth & fe00) goto go_out ;
00308 *ptrs_r++ = fourth ;
00309
00310 cpp_r += 4 ;
00311 }
00312
00313
00314 go_out : ;
00315
00316 u_int cou_ptrs = (ptrs_r - ptrs) ;
00317
00318
00319
00320 if(cou_ptrs == 0) {
00321 continue ;
00322 }
00323
00324
00325
00326 #ifdef FCF_10BIT_ADC
00327 u_short *val = (u_short *)((char *)adcin + adcOff[pad]) ;
00328 #else
00329 u_char *val = (u_char *)((char *)adcin + adcOff[pad]) ;
00330 #endif
00331
00332 #ifdef FCF_SIM_ON
00333 u_short *simval ;
00334 if(simout) {
00335 simval = (u_short *)((char *)simin + adcOff[pad]) ;
00336 }
00337 else {
00338 simval = 0 ;
00339 }
00340 #endif
00341
00342 if((next_pad != pad) && new_res_cou) {
00343
00344
00345 int wrote ;
00346
00347
00348 if((*cl_found_pointer + new_res_cou) >= maxClusters) {
00349 LOG(ERR,"Too many clusters in pad %d - breaking!",pad,0,0,0,0) ;
00350 return outres - row_pointer ;
00351 }
00352
00353
00354
00355
00356 wrote = saveRes(new_res, new_res_cou, outres) ;
00357 outres += wrote*2 ;
00358 *cl_found_pointer += wrote ;
00359
00360 #ifdef FCF_SIM_ON
00361 if(simout) {
00362 *sim_found_ptr += wrote ;
00363 }
00364 #endif
00365
00366 new_res_cou = 0 ;
00367 }
00368
00369
00370
00371 if(new_res_ix == 1) {
00372 new_res_ix = 0 ;
00373
00374 old_res = resx[1] ;
00375 new_res = resx[0] ;
00376
00377 }
00378 else {
00379 new_res_ix = 1 ;
00380
00381 old_res = resx[0] ;
00382 new_res = resx[1] ;
00383
00384 }
00385
00386 old_res_cou = new_res_cou ;
00387 new_res_cou = 0 ;
00388
00389
00390
00391
00392
00393 u_short *ptrs_16 = (u_short *)ptrs ;
00394 u_int cl_counter ;
00395
00396 for(cl_counter=0;cl_counter<cou_ptrs;cl_counter++) {
00397 register u_int start, stop ;
00398
00399 start = (u_int)*ptrs_16++ ;
00400 stop = (u_int) *ptrs_16++ ;
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 if(start < timebinLo) start = timebinLo ;
00411 if(stop > timebinHi) stop = timebinHi ;
00412 if(stop < start) continue ;
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 #ifdef FCF_10BIT_ADC
00424 register u_short *adc_p = val + start ;
00425 register u_short *adc_end = val + stop + 1;
00426 #else
00427 register u_char *adc_p = val + start ;
00428 register u_char *adc_end = val + stop + 1;
00429 #endif
00430
00431 #ifdef FCF_SIM_ON
00432 u_short *sim_p ;
00433 u_short sim_id ;
00434
00435 if(simout) {
00436 sim_p = simval + start ;
00437 sim_id = *sim_p++ ;
00438 }
00439 else {
00440 sim_p = 0 ;
00441 sim_id = 0 ;
00442 }
00443 #endif
00444
00445 register int flags = FCF_ONEPAD | start_flags ;
00446 register int adc = *adc_p++ ;
00447
00448
00449 register int min_adc = minAdcT ;
00450 #ifndef FCF_10BIT_ADC
00451 register u_short *adc8to10 FCF_960_R13 = a8to10 ;
00452 #endif
00453
00454
00455
00456
00457 do {
00458 register int last_falling = 0 ;
00459 register int max_a = 0 ;
00460 register int mean FCF_960_R11 = 0 ;
00461 register u_int charge FCF_960_R9 = 0 ;
00462 register int av FCF_960_R8 = 0 ;
00463
00464 register int last_a = 0 ;
00465
00466 #ifdef FCF_SIM_ON
00467 int max_sim = sim_id ;
00468 #endif
00469
00470
00471 stop = start ;
00472
00473
00474
00475 do {
00476
00477 register int a ;
00478
00479
00480 if(unlikely(last_falling)) {
00481 if(unlikely(adc > (last_a + min_adc))) {
00482 flags |= FCF_DOUBLE_T ;
00483
00484 break ;
00485 }
00486 }
00487 else {
00488 if(unlikely(adc < (last_a - min_adc))) {
00489 last_falling = 1 ;
00490 }
00491 else {
00492 if(unlikely(adc >= max_a)) {
00493 max_a = adc ;
00494 #ifdef FCF_SIM_ON
00495 max_sim = sim_id ;
00496 #endif
00497 mean = start ;
00498
00499 }
00500
00501 }
00502 }
00503
00504 #ifdef FCF_10BIT_ADC
00505
00506
00507
00508 a = log8to10_table[adc];
00509
00510
00511
00512
00513 #else
00514 a = adc8to10[adc] ;
00515 #endif
00516 last_a = adc ;
00517
00518 #ifdef FCF_NEW_ADC_ROUNDOFF
00519 av += start*a + (start+1)/2 ;
00520 #else
00521 av += start * a ;
00522 #endif
00523 charge += a ;
00524
00525
00526
00527 adc = *adc_p++ ;
00528 #ifdef FCF_SIM_ON
00529 pixStruct[pad][start].adc = a ;
00530 pixStruct[pad][start].cl_id = cl_id ;
00531 pixStruct[pad][start].id_simtrk = sim_id ;
00532
00533 if(simout) {
00534 sim_id = *sim_p++ ;
00535 }
00536 #endif
00537
00538
00539
00540 start++ ;
00541
00542 } while(likely(adc_p <= adc_end)) ;
00543
00544
00545 #ifdef FCF_NEW_ADC_ROUNDOFF
00546
00547 charge += ((start-stop)+1)/2 ;
00548
00549 #endif
00550
00551
00552
00553 av = GC * av + T0C * charge ;
00554
00555
00556 charge *= GC ;
00557
00558
00559 #ifdef __unix
00560 if(charge > 0x7FFFFFFF) {
00561 LOG(ERR,"Whoa charge 0x%08X, %d GC",charge,GC,0,0,0) ;
00562 }
00563 #endif
00564
00565
00566
00567 struct fcfResx *rn = new_res[new_res_cou++];
00568
00569
00570 rn->pad = charge*pad ;
00571
00572
00573 mstore(rn,av,charge,mean,flags) ;
00574
00575
00576 rn->p1 = pad ;
00577 rn->p2 = pad ;
00578 rn->t1 = stop ;
00579 rn->t2 = start-1 ;
00580
00581
00582
00583
00584 #ifdef FCF_SIM_ON
00585
00586
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
00736 if(rr->adc_max > nresx->adc_max) {
00737 nresx->adc_max = rr->adc_max ;
00738
00739 nresx->id = rr->id ;
00740 }
00741
00742
00743
00744 for(int ii=0;ii<512;ii++) {
00745 if(nresx->cl_id == pixStruct[pad][ii].cl_id) {
00746 pixStruct[pad][ii].cl_id = rr->cl_id ;
00747 }
00748 }
00749 nresx->cl_id = rr->cl_id ;
00750
00751 #endif
00752 new_start = j + 1 ;
00753
00754 break ;
00755 }
00756 else {
00757 new_start = j ;
00758
00759 break ;
00760 }
00761
00762 }
00763
00764
00765 if(!merged) {
00766 int wrote ;
00767
00768
00769 if((*cl_found_pointer + 1) >= maxClusters) {
00770 LOG(ERR,"Too many clusters in pad %d - breaking!",pad,0,0,0,0) ;
00771 return outres - row_pointer ;
00772 }
00773
00774
00775
00776
00777
00778 wrote = saveRes(&rr, 1, outres) ;
00779 outres += wrote*2 ;
00780 *cl_found_pointer += wrote ;
00781 #ifdef FCF_SIM_ON
00782 if(simout) {
00783 *sim_found_ptr += wrote ;
00784 }
00785 #endif
00786 }
00787
00788 }
00789
00790
00791
00792 }
00793
00794
00795 if(new_res_cou) {
00796 int wrote ;
00797
00798
00799 if((*cl_found_pointer + new_res_cou) >= maxClusters) {
00800
00801 LOG(ERR,"Too many clusters in pad %d - breaking!",pad,0,0,0,0) ;
00802 return outres - row_pointer ;
00803 }
00804
00805
00806
00807 wrote = saveRes(new_res, new_res_cou, outres) ;
00808 outres += wrote*2 ;
00809 *cl_found_pointer += wrote ;
00810 #ifdef FCF_SIM_ON
00811 if(simout) {
00812 *sim_found_ptr += wrote ;
00813 }
00814 #endif
00815 }
00816
00817
00818
00819
00820
00821
00822
00823 return (outres - row_pointer) ;
00824
00825 }
00826
00827
00828 fcfClass::fcfClass(int det, u_short *table)
00829 {
00830 detector = det ;
00831
00832 #ifdef __unix
00833 a8to10 = adc8to10_storage ;
00834 #else // I960
00835 a8to10 = fastMem->adc8to10 ;
00836 #endif
00837
00838
00839
00840 cvs_revision = 0 ;
00841
00842 {
00843 size_t i ;
00844 char tmp[10] ;
00845 int num_start, num_end, num_dot ;
00846
00847 for(i=0;i<strlen(fcf_cvs_revision);i++) {
00848 if(isdigit(fcf_cvs_revision[i])) {
00849 num_start = i ;
00850 break ;
00851 }
00852 }
00853 for(i=num_start;i<strlen(fcf_cvs_revision);i++) {
00854 if(fcf_cvs_revision[i]==0x20) {
00855 num_end = i-1 ;
00856 break ;
00857 }
00858 if(fcf_cvs_revision[i]=='.') {
00859 num_dot = i ;
00860 }
00861 }
00862
00863 strncpy(tmp,&(fcf_cvs_revision[num_start]),1) ;
00864 cvs_revision = atoi(tmp) << 16 ;
00865 strncpy(tmp,&(fcf_cvs_revision[num_dot+1]),num_end-num_dot) ;
00866 cvs_revision |= atoi(tmp) ;
00867
00868
00869
00870 }
00871
00872 simIn = 0 ;
00873 simOut = 0 ;
00874
00875 if(table == NULL) {
00876 noADCconversion = 1 ;
00877 }
00878 else {
00879 noADCconversion = 0 ;
00880 }
00881
00882
00883 svtPedestal = 0 ;
00884
00885
00886 deconTime = 1 ;
00887 deconPad = 1 ;
00888 doCuts = 1 ;
00889
00890 param1 = FCF_PARAM1 ;
00891 minAdcT = FCF_MIN_ADC_T ;
00892 minAdcPad = FCF_MIN_ADC_PAD ;
00893
00894 switch(det) {
00895 case TPC_ID :
00896 maxCPP = 31 ;
00897 maxTimebin = 511 ;
00898 timebinLo = 0 ;
00899 timebinHi = 400 ;
00900 chargeMin = 40 ;
00901 break ;
00902 case FTP_ID :
00903 maxCPP = 31 ;
00904 maxTimebin = 511 ;
00905 timebinLo = 0 ;
00906 timebinHi = 255 ;
00907 chargeMin = 40 ;
00908 break ;
00909 case SVT_ID :
00910 maxCPP = 8 ;
00911 maxTimebin = 127 ;
00912 timebinLo = 0 ;
00913 timebinHi = 127 ;
00914 chargeMin = 20 ;
00915 break ;
00916 default :
00917 LOG(WARN,"Cluster Finder can't work with DET Type %d",det,0,0,0,0) ;
00918 return ;
00919 }
00920
00921
00922
00923 minAdcPad *= FCF_GAIN_FACTOR ;
00924
00925 static struct fcfResx res_slow[2][512] ;
00926 #ifdef __unix
00927 static struct fcfResx res_fast_ux[2][FCF_MAX_RES_COU_FAST] ;
00928 struct fcfResx *res_fast[2] = { res_fast_ux[0], res_fast_ux[1] } ;
00929 #else
00930
00931 #define RES_COU (sizeof(struct fcfResx)*2*FCF_MAX_RES_COU_FAST)
00932 #define I960_MAX_RES (sizeof(fastMem->fcfStore))
00933
00934 if(RES_COU > I960_MAX_RES) {
00935 LOG(CRIT,"Error in MAX_RES_COU size %d > %d!!!",RES_COU,I960_MAX_RES,0,0,0) ;
00936 }
00937
00938
00939 struct fcfResx *res_fast[2] = {
00940 (struct fcfResx *) fastMem->fcfStore,
00941 (struct fcfResx *) &(fastMem->fcfStore[(sizeof(struct fcfResx)/4)*FCF_MAX_RES_COU_FAST]) } ;
00942
00943
00944
00945
00946 #endif
00947
00948
00949 u_int i, j ;
00950 for(i=0;i<2;i++) {
00951 for(j=0;j<FCF_MAX_RES_COU_FAST;j++) {
00952 resx[i][j] = res_fast[i] + j ;
00953
00954 }
00955 }
00956 for(i=0;i<2;i++) {
00957 for(j=FCF_MAX_RES_COU_FAST;j<512;j++) {
00958 resx[i][j] = &(res_slow[i][j]) ;
00959 }
00960 }
00961
00962 return ;
00963 }
00964
00965
00966
00967 void fcfClass::set8to10(u_short *table)
00968 {
00969 int i ;
00970
00971 if(table) {
00972 for(i=0;i<256;i++) {
00973 a8to10[i] = *table++ ;
00974 }
00975 noADCconversion = 0 ;
00976 }
00977 else {
00978 noADCconversion = 1 ;
00979 }
00980 return ;
00981 }
00982
00983
00984 inline int fcfClass::saveRes(struct fcfResx *res_p[], int cou, u_int *output)
00985 {
00986
00987 int i ;
00988 int saved = 0 ;
00989 register u_int ch_min = chargeMinCorrect ;
00990 register int do_cuts = doCuts ;
00991 u_int fla, cha ;
00992 u_int pad_c ;
00993 u_int time_c ;
00994 u_int t_cha ;
00995
00996 for(i=0;i<cou;i++) {
00997 struct fcfResx *rr ;
00998
00999 rr = res_p[i] ;
01000
01001
01002 fla = rr->flags ;
01003 cha = rr->charge ;
01004
01005
01006
01007
01008
01009
01010 if(do_cuts) {
01011 if(fla & FCF_BROKEN_EDGE) {
01012 ;
01013 }
01014 else if(fla & (FCF_ROW_EDGE | FCF_DEAD_EDGE | FCF_ONEPAD)) continue ;
01015 else if(cha <= ch_min) continue ;
01016 else if(rr->t1 == 0) continue ;
01017 else if((rr->t2-rr->t1) <= 3) continue ;
01018 }
01019
01020
01021 if((cha == 0) || (cha > 0x7FFFFFFF)) {
01022
01023 continue ;
01024 }
01025
01026
01027 pad_c = rr->pad ;
01028 time_c = rr->t ;
01029
01030 if(pad_c > 0x04000000) {
01031 t_cha = cha >> 6 ;
01032
01033 if(t_cha) {
01034 pad_c = (pad_c + t_cha/2) / t_cha ;
01035 }
01036 else {
01037 pad_c = ((pad_c + cha/2) / cha) << 6 ;
01038 }
01039
01040
01041 }
01042 else {
01043
01044 pad_c = ((pad_c << 6) + (cha/2)) / cha ;
01045 }
01046
01047 if(time_c > 0x04000000) {
01048 t_cha = cha >> 6 ;
01049
01050 if(t_cha) {
01051 time_c = (time_c + t_cha/2) / t_cha ;
01052 }
01053 else {
01054 time_c = ((time_c + cha/2) / cha) << 6 ;
01055 }
01056 }
01057 else {
01058
01059 time_c = ((time_c << 6) + (cha/2)) / cha ;
01060 }
01061
01062
01063
01064 cha = (cha+32)/64 ;
01065
01066
01067
01068 if((pad_c > 0xFFFF) || (time_c > 0xFFFF)) {
01069
01070 continue ;
01071 }
01072
01073 if(cha > 0xFFFF) {
01074
01075 cha = 0xFFFF ;
01076 fla |= FCF_DOUBLE_T | FCF_DOUBLE_PAD ;
01077 }
01078
01079
01080 fla &= (~FCF_FALLING) ;
01081
01082
01083
01084 if((pad_c & 0xc000) || (time_c & 0x8000)) {
01085 LOG(ERR,"Strange pad 0x%04X, time 0x%04X...",pad_c,time_c,0,0,0) ;
01086 continue ;
01087 }
01088
01089
01090 u_int p = (pad_c >> 6) ;
01091 u_int fl ;
01092
01093 u_int p1 = p - rr->p1 ;
01094 u_int p2 = rr->p2 - p ;
01095
01096 if(p1 > 7) p1 = 7 ;
01097 if(p2 > 7) p2 = 7 ;
01098
01099
01100
01101
01102
01103
01104
01105
01106 fl = (p1 << 8) | (p2 << 11) ;
01107
01108
01109 p = (time_c >> 6) ;
01110
01111
01112 p1 = p - rr->t1 ;
01113 p2 = rr->t2 - p ;
01114
01115 if(p1 > 15) p1 = 15 ;
01116 if(p2 > 15) p2 = 15 ;
01117
01118
01119
01120
01121
01122
01123 fl |= (p2 << 4) | p1 ;
01124
01125
01126
01127
01128
01129
01130
01131 if(fla & FCF_ONEPAD) time_c |= 0x8000 ;
01132 if(fla & (FCF_DOUBLE_T | FCF_DOUBLE_PAD)) pad_c |= 0x8000 ;
01133 if(fla & FCF_DEAD_EDGE) pad_c |= 0x4000 ;
01134
01135 if(fla & FCF_ROW_EDGE) fl |= 0x8000 ;
01136 if(fla & FCF_BROKEN_EDGE) fl |= 0x4000 ;
01137
01138
01139
01140
01141
01142
01143 *output++ = (time_c << 16) | pad_c ;
01144 *output++ = (cha << 16) | fl ;
01145
01146 #ifdef FCF_SIM_ON
01147
01148
01149 {
01150 int i, j ;
01151
01152 int quality = 1 ;
01153
01154 if(simout) {
01155
01156 u_int sim_cha, all_cha ;
01157
01158 sim_cha = all_cha = 0 ;
01159
01160 for(i=1;i<=182;i++) {
01161 for(j=0;j<512;j++) {
01162 if(pixStruct[i][j].cl_id == rr->cl_id) {
01163 if(rr->id == pixStruct[i][j].id_simtrk) {
01164 sim_cha += pixStruct[i][j].adc ;
01165 }
01166 all_cha += pixStruct[i][j].adc ;
01167 }
01168 }
01169 }
01170
01171 if(all_cha) {
01172 quality = (int)(100.0*(double)sim_cha/(double)all_cha) ;
01173 }
01174 else {
01175 quality = 0 ;
01176 }
01177
01178
01179 struct FcfSimOutput *s = (struct FcfSimOutput *) simout ;
01180
01181 s->id_simtrk = rr->id ;
01182 s->id_quality = quality ;
01183
01184 s->cl_id = rr->cl_id ;
01185
01186 simout += sizeof(struct FcfSimOutput)/4 ;
01187
01188 }
01189
01190 #if defined(FCF_ANNOTATE_CLUSTERS) && !defined(__ROOT__)
01191 for(i=1;i<=182;i++) {
01192 for(j=0;j<512;j++) {
01193 if(pixStruct[i][j].adc) {
01194 fcfPixA[row-1][i-1][j] = pixStruct[i][j] ;
01195 }
01196 }
01197 }
01198 #endif
01199 }
01200
01201 #endif // FCF_SIM_ON!
01202
01203
01204
01205
01206
01207
01208
01209 saved++ ;
01210
01211
01212 }
01213
01214
01215 return saved ;
01216 }
01217