00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdio.h>
00012 #include <string.h>
00013 #include <stdlib.h>
00014
00015 #include <rtsLog.h>
00016 #include <I386/i386Lib.h>
00017
00018 #include <TPC/rowlen.h>
00019
00020 #include "tpxGain.h"
00021 #include "tpxFCF.h"
00022
00023 #include <DAQ_READER/daq_dta_structs.h>
00024
00025 #define likely(x) __builtin_expect((x),1)
00026 #define unlikely(x) __builtin_expect((x),0)
00027
00028 char *tpxFCF::fcf_flags(u_char flags)
00029 {
00030 static char c_flags[32] ;
00031
00032 c_flags[0] = 0 ;
00033
00034 if(flags & FCF_IN_DOUBLE) strcat(c_flags,"?") ;
00035
00036 if(flags & FCF_DEAD_EDGE) strcat(c_flags,"D") ;
00037 if(flags & FCF_BROKEN_EDGE) strcat(c_flags,"B") ;
00038 if(flags & FCF_ROW_EDGE) strcat(c_flags,"E") ;
00039
00040 if(flags & FCF_BIG_CHARGE) strcat(c_flags,"c") ;
00041 if(flags & FCF_DOUBLE_T) strcat(c_flags,"!") ;
00042 if(flags & FCF_MERGED) strcat(c_flags,"m") ;
00043 if(flags & FCF_ONEPAD) strcat(c_flags,"1") ;
00044
00045 if(c_flags[0] == 0) strcpy(c_flags,"0") ;
00046
00047 return c_flags ;
00048 }
00049
00050
00051 int tpxFCF::afterburner(int cou, daq_cld *store[])
00052 {
00053 int merged ;
00054
00055 if(likely(cou == 0)) return 0 ;
00056
00057
00058
00059 merged = 0 ;
00060
00061 for(int i=0;i<cou;i++) {
00062 daq_cld *l = store[i] ;
00063 int merge_ix = -1 ;
00064
00065
00066
00067 if(l->charge == 0) continue ;
00068 if(l->flags & FCF_BROKEN_EDGE) ;
00069 else continue ;
00070
00071 int type = 0 ;
00072
00073 for(int j=0;j<cou;j++) {
00074 int ok = 0 ;
00075
00076
00077 if(j<=i) continue ;
00078
00079 daq_cld *r = store[j] ;
00080
00081 if(r->charge == 0) continue ;
00082 if(r->flags & FCF_BROKEN_EDGE) ;
00083 else continue ;
00084
00085 if(r->p1==13) {
00086 if(l->p2 != 12) continue ;
00087 type = 1 ;
00088 }
00089 else if(r->p2==12) {
00090 if(l->p1 != 13) continue ;
00091 type = 2 ;
00092 }
00093 else if(r->p1==131) {
00094 if(l->p2 != 130) continue ;
00095 type = 3 ;
00096 }
00097 else if(r->p2==130) {
00098 if(l->p1 != 131) continue ;
00099 type = 4 ;
00100 }
00101 else {
00102 continue ;
00103 type = 5 ;
00104 }
00105
00106 if((r->t1 >= l->t1) && (r->t1 <= l->t2)) ok = 1 ;
00107 if((r->t2 >= l->t1) && (r->t2 <= l->t2)) ok = 1 ;
00108
00109 if(ok==0) continue ;
00110
00111 merge_ix = j ;
00112 break ;
00113
00114
00115
00116 }
00117
00118 if(merge_ix < 0) {
00119
00120 }
00121 else {
00122
00123 merged++ ;
00124
00125
00126 daq_cld *r = store[merge_ix] ;
00127 double charge = l->charge + r->charge ;
00128
00129
00130
00131
00132
00133
00134
00135
00136 l->tb = (l->tb * l->charge + r->tb * r->charge) / charge ;
00137 l->pad = (l->pad * l->charge + r->pad * r->charge) / charge ;
00138
00139 if(r->t1 < l->t1) l->t1 = r->t1 ;
00140 if(r->t2 > l->t2) l->t2 = r->t2 ;
00141
00142 if(r->p1 < l->p1) l->p1 = r->p1 ;
00143 if(r->p2 > l->p2) l->p2 = r->p2 ;
00144
00145 l->flags |= r->flags ;
00146 l->flags &= ~FCF_ONEPAD ;
00147
00148
00149 if(charge > (double)0x7FFF) {
00150
00151 int ch = (int) (charge+1) ;
00152
00153 ch /= 1024 ;
00154
00155 l->charge = (u_short) ch * 1024 ;
00156 l->flags |= FCF_BIG_CHARGE ;
00157 }
00158 else {
00159 l->charge = (u_short) charge ;
00160 }
00161
00162 l->flags &= ~FCF_BROKEN_EDGE ;
00163
00164
00165 r->flags |= FCF_DEAD_EDGE ;
00166 r->charge = 0 ;
00167 }
00168
00169
00170
00171 }
00172
00173
00174 for(int i=0;i<cou;i++) {
00175 daq_cld *l = store[i] ;
00176
00177
00178
00179 if(l->flags & (FCF_ONEPAD | FCF_DEAD_EDGE | FCF_ROW_EDGE)) {
00180 l->flags |= FCF_DEAD_EDGE ;
00181 l->charge = 0 ;
00182 }
00183 else {
00184 l->flags &= ~FCF_BROKEN_EDGE ;
00185 }
00186
00187 }
00188
00189 return merged ;
00190 }
00191
00192 int tpxFCF::fcf_decode(u_int *p_buff, daq_cld *dc, u_short version)
00193 {
00194 double p, t ;
00195 int p1,p2,t1,t2,cha,fla ;
00196 u_int p_tmp, t_tmp ;
00197
00198
00199 p_tmp = *p_buff & 0xFFFF ;
00200
00201
00202 t_tmp = *p_buff >> 16 ;
00203
00204
00205 if(version==FCF_V_FY08) {
00206 p = (double)(p_tmp & 0x3FFF) / 32.0 ;
00207 t = (double)(t_tmp & 0x7FFF) / 32.0 ;
00208 }
00209 else {
00210 p = (double)(p_tmp & 0x3FFF) / 64.0 ;
00211 t = (double)(t_tmp & 0x7FFF) / 64.0 ;
00212 }
00213
00214 fla = 0 ;
00215 if(p_tmp & 0x8000) fla |= FCF_MERGED ;
00216 if(p_tmp & 0x4000) fla |= FCF_DEAD_EDGE ;
00217 if(t_tmp & 0x8000) fla |= FCF_ONEPAD ;
00218
00219
00220 p_buff++ ;
00221 cha = *p_buff >> 16 ;
00222
00223 if(cha >= 0x8000) {
00224
00225
00226 fla |= FCF_BIG_CHARGE ;
00227 cha = (cha & 0x7FFF) * 1024 ;
00228
00229
00230
00231
00232
00233 if(cha > 0xFFFF) cha = 0xFFFF ;
00234
00235 }
00236
00237 p_tmp = *p_buff & 0xFFFF ;
00238
00239 if(p_tmp & 0x8000) fla |= FCF_ROW_EDGE ;
00240 if(p_tmp & 0x4000) fla |= FCF_BROKEN_EDGE ;
00241
00242 t1 = p_tmp & 0xF ;
00243 t2 = (p_tmp >> 4) & 0xF ;
00244
00245
00246 p1 = (p_tmp >> 8) & 0x7 ;
00247 p2 = (p_tmp >> 11) & 0x7 ;
00248
00249
00250 t1 = (int)t - t1 ;
00251 t2 = (int)t + t2 ;
00252
00253
00254 p1 = (int)p - p1 ;
00255 p2 = (int)p + p2 ;
00256
00257 dc->t1 = t1 ;
00258 dc->t2 = t2 ;
00259 dc->p1 = p1 ;
00260 dc->p2 = p2 ;
00261 dc->charge = cha ;
00262 dc->flags = fla ;
00263 dc->pad = p ;
00264 dc->tb = t ;
00265
00266
00267 return 2 ;
00268
00269 }
00270
00271 int tpxFCF::fcf_decode(u_int *p_buff, daq_sim_cld *sdc, u_short version)
00272 {
00273 int skip = fcf_decode(p_buff,&(sdc->cld), version) ;
00274
00275 sdc->track_id = 0 ;
00276 sdc->quality = 0 ;
00277
00278
00279 p_buff += skip ;
00280
00281
00282 sdc->quality = (*p_buff) >> 16 ;
00283 sdc->track_id = (*p_buff) & 0xFFFF ;
00284
00285
00286
00287
00288
00289 skip++ ;
00290
00291
00292 return skip ;
00293 }
00294
00295
00296 tpxFCF::tpxFCF()
00297 {
00298 rbs = 0 ;
00299 sector = 0 ;
00300 gains = 0 ;
00301 cl_marker = 0 ;
00302
00303 run_compatibility = 9 ;
00304 do_cuts = 2 ;
00305 ch_min = 10 ;
00306
00307 row_count = 45 ;
00308 tpx_rowlen = tpc_rowlen ;
00309 tpx_padplane = 0 ;
00310
00311 memset(row_ix,0xFF,sizeof(row_ix)) ;
00312 storage = 0 ;
00313
00314
00315 read_version = 0 ;
00316 do_version = FCF_V_FY09 ;
00317
00318 return ;
00319 }
00320
00321
00322 tpxFCF::~tpxFCF()
00323 {
00324 if(storage) {
00325 free(storage) ;
00326 storage = 0 ;
00327 }
00328
00329 return ;
00330 }
00331
00332
00333
00334
00335 void tpxFCF::config(u_int mask, int mode, int rows, unsigned char *rowlen)
00336 {
00337 rbs = mask ;
00338 modes = mode ;
00339
00340 int r ;
00341 int row, pad ;
00342 int a, ch ;
00343
00344 memset(row_ix,0,sizeof(row_ix)) ;
00345
00346 if((rowlen==0) || (rows<=0)) {
00347 tpx_rowlen = tpc_rowlen ;
00348 row_count = 45 ;
00349 tpx_padplane = 0 ;
00350 }
00351 else {
00352 tpx_rowlen = rowlen ;
00353 row_count = rows ;
00354 tpx_padplane = 1 ;
00355 }
00356
00357
00358 LOG(NOTE,"calling config: mask 0x%X, mode %d, rows %3d",mask,mode,row_count) ;
00359
00360
00361
00362
00363 if(tpx_padplane) {
00364 for(row=1;row<=row_count;row++) row_ix[row] = 1 ;
00365 }
00366 else {
00367
00368 for(r=0;r<6;r++) {
00369 if(rbs & (1<<r)) {
00370 for(a=0;a<256;a++) {
00371 for(ch=0;ch<16;ch++) {
00372 tpx_from_altro(r,a,ch,row,pad) ;
00373
00374 if(row > 250) continue ;
00375 if(row == 0) continue ;
00376 row_ix[row] = 1 ;
00377 }
00378 }
00379 }
00380 }
00381 }
00382
00383
00384 int tot_count = 0 ;
00385 for(row=0;row<=row_count;row++) {
00386 if(row_ix[row]) {
00387 tot_count += tpx_rowlen[row] ;
00388 }
00389 }
00390
00391 LOG(NOTE,"fcfconfig: RDO mask 0x%03X: allocated %d pads (%d bytes)",rbs,tot_count,tot_count * sizeof(struct stage1)) ;
00392
00393
00394 if(storage) {
00395 LOG(WARN,"Whoa! Storage already allocated!") ;
00396 free(storage) ;
00397 }
00398
00399 storage = (struct stage1 *) valloc(tot_count * sizeof(struct stage1)) ;
00400
00401 LOG(NOTE,"FCF for mask 0x%02X: alloced %d bytes for %d tot_count X %d; cleared gains",mask,
00402 tot_count * sizeof(struct stage1),
00403 tot_count,
00404 sizeof(struct stage1)) ;
00405
00406
00407 memset(storage,0,tot_count * sizeof(struct stage1)) ;
00408
00409
00410
00411
00412 tot_count = 0 ;
00413 for(row=0;row<=row_count;row++) {
00414 if(row_ix[row] == 0) {
00415 row_ix[row] = -1 ;
00416 continue ;
00417 }
00418
00419 row_ix[row] = tot_count ;
00420
00421 tot_count += tpx_rowlen[row] ;
00422 }
00423
00424
00425
00426
00427 if(tpx_padplane) {
00428 for(row=1;row<=row_count;row++) {
00429 for(pad=1;pad<=tpx_rowlen[row];pad++) {
00430 get_stage1(row,pad)->f = 0x8000 | FCF_ONEPAD ;
00431 get_stage1(row,pad)->g = 1.0 ;
00432 get_stage1(row,pad)->t0 = 0.0 ;
00433 }
00434 }
00435 }
00436 else {
00437
00438 for(r=0;r<6;r++) {
00439 if(rbs & (1<<r)) {
00440 for(a=0;a<256;a++) {
00441 for(ch=0;ch<16;ch++) {
00442 tpx_from_altro(r,a,ch,row,pad) ;
00443
00444 if(row > 250) continue ;
00445 if(row == 0) continue ;
00446
00447 get_stage1(row, pad)->f = 0x8000 | FCF_ONEPAD ;
00448 get_stage1(row, pad)->g = 1.0 ;
00449 get_stage1(row, pad)->t0 = 0.0 ;
00450
00451 }
00452 }
00453 }
00454 }
00455 }
00456
00457 return ;
00458 }
00459
00460
00461
00462
00463 void tpxFCF::apply_gains(int sec, tpxGain *gain)
00464 {
00465 sector = sec ;
00466 gains = gain ;
00467
00468 int row, pad ;
00469
00470 if(tpx_padplane) gains = 0 ;
00471
00472 if(gains == 0) {
00473 LOG(WARN,"Sector %2d, gains NULL",sector) ;
00474 }
00475 else {
00476 LOG(NOTE,"Applying gains to sector %d [%p ?]",sector,gains) ;
00477 }
00478
00479
00480 for(row=1;row<=row_count;row++) {
00481 if(row_ix[row] < 0) continue ;
00482
00483 for(pad=1;pad <= tpx_rowlen[row]; pad++) {
00484
00485 get_stage1(row, pad)->f &= 0xFF00 ;
00486 }
00487 }
00488
00489
00490
00491 for(row=1;row<=row_count;row++) {
00492 if(row_ix[row] < 0) continue ;
00493
00494 for(pad=1;pad<=tpx_rowlen[row];pad++) {
00495 stage1 *s = get_stage1(row, pad) ;
00496
00497 if(gains) {
00498 s->g = gains->get_gains(sector,row,pad)->g ;
00499 s->t0 = gains->get_gains(sector,row,pad)->t0 ;
00500 }
00501 else {
00502 s->g = 1.0 ;
00503 s->t0 = 0.0 ;
00504 }
00505
00506 u_int fl = 0 ;
00507
00508 if(!(s->f & 0x8000)) {
00509
00510 fl |= FCF_BROKEN_EDGE ;
00511 }
00512
00513 if(s->g == 0.0) {
00514 fl |= FCF_DEAD_EDGE ;
00515 }
00516
00517
00518
00519 if(fl) {
00520 if(pad>1) {
00521 get_stage1(row,pad-1)->f |= fl ;
00522 }
00523 if(pad < tpx_rowlen[row]) {
00524 get_stage1(row,pad+1)->f |= fl ;
00525 }
00526
00527 }
00528
00529
00530 if((pad==1) || (pad==tpx_rowlen[row])) {
00531 fl |= FCF_ROW_EDGE ;
00532 }
00533
00534 s->f |= fl | FCF_ONEPAD ;
00535
00536 LOG(DBG,"FCF gains: row %2d, pad %3d: gain %f, flags 0x%04X",row,pad,s->g,s->f) ;
00537
00538 }
00539
00540
00541 }
00542
00543
00544 return ;
00545 }
00546
00547 void tpxFCF::start_evt()
00548 {
00549 cl_marker = 10000 ;
00550
00551 for(int r=1;r<=row_count;r++) {
00552 if(row_ix[r] < 0) continue ;
00553
00554 for(int p=1;p<=tpx_rowlen[r];p++) {
00555 struct stage1 *o ;
00556 o = get_stage1(r, p) ;
00557 if(unlikely(o==0)) {
00558 LOG(ERR,"No row pad %d:%d???",r,p) ;
00559 }
00560 else {
00561 o->count = 0 ;
00562 }
00563 }
00564 }
00565
00566
00567 return ;
00568 }
00569
00570
00571
00572 int tpxFCF::do_pad(tpx_altro_struct *a, daq_sim_adc_tb *sim_adc)
00573 {
00574 struct stage1 *s ;
00575
00576 if(unlikely(a->row > 250)) return 0 ;
00577 if(unlikely(a->row == 0)) return 0 ;
00578 if(unlikely(a->pad > tpx_rowlen[a->row])) return 0 ;
00579
00580
00581 s = get_stage1(a->row, a->pad) ;
00582
00583 if(unlikely(s==0)) {
00584 LOG(ERR,"Whoa -- no row:pad %d:%d???",a->row,a->pad) ;
00585 return 0 ;
00586 }
00587
00588
00589 s->count = 0 ;
00590
00591 if(unlikely(a->count<=1)) return 0 ;
00592
00593
00594
00595
00596
00597
00598
00599 if(unlikely(a->count >= 400)) {
00600
00601 return 0 ;
00602 }
00603
00604
00605
00606 if(unlikely(s->g <= 0.001)) return 0 ;
00607
00608 u_int t_ave, charge ;
00609 u_int tb_start ;
00610 u_int last_falling, last_adc ;
00611 u_int flags ;
00612 u_int tb_prev ;
00613 int new_cluster ;
00614
00615 struct tpxFCF_cl *cl, *cl_max ;
00616
00617
00618 cl = s->cl ;
00619 cl_max = &(s->cl[FCF_MAX_CL]) ;
00620
00621
00622 u_int max_adc = 0 ;
00623
00624 last_falling = last_adc = 0 ;
00625 t_ave = charge = 0 ;
00626
00627 tb_prev = tb_start = a->tb[0] ;
00628 flags = s->f & 0xFF ;
00629 new_cluster = 0 ;
00630
00631
00632
00633 for(int i=0;likely( i < a->count );i++) {
00634 u_int adc, tb ;
00635
00636
00637 adc = a->adc[i] ;
00638 tb = a->tb[i] ;
00639
00640
00641
00642 if(unlikely( adc <= 1 )) {
00643 continue ;
00644 }
00645
00646 if(unlikely( tb < (tb_prev - 1) )) {
00647 new_cluster |= FCF_ONEPAD ;
00648 }
00649
00650 if(unlikely( last_falling )) {
00651 if(unlikely( last_falling > FCF_MIN_WIDTH )) {
00652 if(unlikely( adc > (last_adc + FCF_ADC_NOISE) )) {
00653 flags |= FCF_DOUBLE_T ;
00654 new_cluster |= FCF_DOUBLE_T ;
00655
00656 }
00657 }
00658 else {
00659 last_falling++ ;
00660 }
00661
00662 }
00663 else {
00664 if(unlikely( (adc + FCF_ADC_NOISE) < last_adc )) {
00665 last_falling = 1 ;
00666 }
00667 }
00668
00669
00670 if(unlikely( new_cluster )) {
00671 if(likely(max_adc >= FCF_ADC_MIN)) {
00672 cl->t_ave = t_ave ;
00673 cl->charge = charge ;
00674
00675 cl->t1 = tb_prev;
00676 cl->t2 = tb_start ;
00677
00678 cl->flags = flags ;
00679
00680
00681 cl++ ;
00682
00683
00684 if(unlikely( cl >= cl_max )) goto pad_done ;
00685 }
00686
00687
00688 if(unlikely( new_cluster & FCF_DOUBLE_T )) ;
00689 else flags = s->f & 0xFF ;
00690
00691 t_ave = charge = 0 ;
00692 tb_start = tb ;
00693 last_falling = 0 ;
00694 max_adc = 0 ;
00695
00696 new_cluster = 0 ;
00697 }
00698
00699
00700 if(unlikely( adc > max_adc )) {
00701 max_adc = adc ;
00702 }
00703
00704 last_adc = adc ;
00705 tb_prev = tb ;
00706
00707 t_ave += adc * tb ;
00708 charge += adc ;
00709
00710
00711 }
00712
00713
00714 if(likely(max_adc >= FCF_ADC_MIN)) {
00715 cl->t1 = tb_prev ;
00716 cl->t2 = tb_start ;
00717
00718 cl->flags = flags ;
00719
00720 cl->charge = charge ;
00721 cl->t_ave = t_ave ;
00722
00723 cl++ ;
00724 }
00725
00726
00727 pad_done: ;
00728
00729
00730 s->count = cl - s->cl ;
00731
00732
00733 if(unlikely( s->count == 0 )) {
00734
00735 }
00736 else {
00737 if(unlikely( s->count >= FCF_MAX_CL )) {
00738 LOG(NOTE,"Row %d:%d, %d clusters [max!]",a->row,a->pad,s->count) ;
00739 }
00740 else {
00741
00742 }
00743 }
00744
00745 #ifdef FCF_DEBUG
00746
00747 cl = s->cl ;
00748 for(int j=0;j<s->count;j++) {
00749 LOG(DBG,"C: %d:%d\t %3d %3d, ch %5d, fl 0x%X",a->row,a->pad,cl->t1,cl->t2,cl->charge,cl->flags) ;
00750 cl++ ;
00751 }
00752
00753 #endif
00754
00755 if(unlikely(sim_adc && modes)) {
00756 cl = s->cl ;
00757
00758 for(int j=0;j<s->count;j++) {
00759
00760 int t_lo = cl->t1 ;
00761 int t_hi = cl->t2 ;
00762 int adc_min = 0 ;
00763
00764 cl->track_id = 0 ;
00765 cl->quality = 0 ;
00766
00767 u_int adc_sum = 0 ;
00768 u_int t_sum = 0 ;
00769
00770
00771 int i_min = 0xFFFFFF ;
00772 cl->sim = 0 ;
00773 cl->sim_length = 0 ;
00774 for(int i=0;i<a->count;i++) {
00775 if((a->tb[i] >= t_lo) && (a->tb[i]<=t_hi)) {
00776 if(i < i_min) i_min = i ;
00777 cl->sim_length++ ;
00778
00779
00780 if(sim_adc[i].track_id == 0xFFFF) {
00781 modes |= 2 ;
00782 sim_adc[i].track_id = cl_marker ;
00783 }
00784 }
00785 }
00786 cl->sim = sim_adc + i_min ;
00787
00788
00789
00790 for(int i=0;i<a->count;i++) {
00791 if((a->tb[i] >= t_lo) && (a->tb[i]<=t_hi)) {
00792 adc_sum += a->adc[i] ;
00793
00794 if(a->adc[i] >= adc_min) {
00795 adc_min = a->adc[i] ;
00796 cl->track_id = sim_adc[i].track_id ;
00797 }
00798 }
00799 }
00800
00801
00802 for(int i=0;i<a->count;i++) {
00803 if((a->tb[i] >= t_lo) && (a->tb[i]<=t_hi)) {
00804
00805 if(cl->track_id == sim_adc[i].track_id) {
00806 t_sum += a->adc[i] ;
00807 }
00808 }
00809 }
00810
00811 if(adc_sum) {
00812 cl->quality = (t_sum * 100) / adc_sum ;
00813
00814 }
00815 else {
00816 cl->quality = 0 ;
00817 }
00818
00819
00820
00821
00822 cl_marker++ ;
00823 cl++ ;
00824
00825 }
00826
00827 }
00828
00829
00830 return s->count ;
00831 }
00832
00833
00834 int tpxFCF::stage2(u_int *outbuff, int max_bytes)
00835 {
00836 int r, p, c ;
00837 struct stage1 *old1, *cur1 ;
00838 tpxFCF_cl *old, *cur, *old_end, *cur_end ;
00839
00840 loc_buff = outbuff ;
00841
00842
00843 for(r=0;r<=row_count;r++) {
00844 if(row_ix[r] < 0) {
00845 continue ;
00846 }
00847
00848
00849 cur_row = r ;
00850 if(cur_row == 0) {
00851 LOG(WARN,"Can;t be -- row 0; row_ix %d",row_ix[r]) ;
00852 }
00853
00854 int bytes_so_far = (loc_buff - outbuff)*4 ;
00855 if(bytes_so_far > (max_bytes-1024)) {
00856 LOG(WARN,"row %d: approaching limit: is %d, max %d",cur_row,bytes_so_far,max_bytes) ;
00857 }
00858
00859
00860 u_int *row_cache = loc_buff++ ;
00861 u_int *clust_count_cache = loc_buff++ ;
00862
00863
00864 cur_row_clusters = 0 ;
00865
00866
00867
00868
00869 for(p=1;p<tpx_rowlen[r];p++) {
00870
00871 old1 = get_stage1(r,p) ;
00872 old = old1->cl ;
00873
00874 cur1 = get_stage1(r,p+1) ;
00875 cur = cur1->cl ;
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 cur_end = cur + cur1->count ;
00886 old_end = old + old1->count ;
00887
00888
00889 while(old<old_end) {
00890 int merge ;
00891
00892 merge = 0 ;
00893
00894
00895
00896 while(likely(cur<cur_end)) {
00897
00898
00899
00900
00901
00902 if(cur->flags & FCF_ONEPAD) ;
00903 else {
00904 LOG(WARN,"Can;t be without ONEPAD %d:%d 0x%X?! %d..%d",r,p+1,cur->flags,cur->p1,cur->p2) ;
00905 }
00906
00907
00908
00909
00910 if(unlikely((old->t1 - cur->t2) >= 1)) {
00911
00912
00913 merge = 2 ;
00914
00915
00916
00917 break ;
00918 }
00919 else if(unlikely((cur->t1 - old->t2) > 1)) {
00920
00921
00922 cur++ ;
00923 continue ;
00924 }
00925 else {
00926
00927
00928
00929
00930
00931
00932
00933 if(unlikely(cur->flags & FCF_IN_DOUBLE)) {
00934
00935 }
00936 else {
00937 cur->flags |= FCF_IN_DOUBLE ;
00938
00939 cur->f_charge = cur->charge * cur1->g ;
00940 cur->scharge = cur->f_charge ;
00941
00942 cur->f_t_ave = cur->t_ave * cur1->g ;
00943
00944
00945 cur->f_t_ave += cur->f_charge * cur1->t0 ;
00946 cur->p1 = p+1 ;
00947 cur->p_ave = (p+1) * cur->f_charge ;
00948
00949
00950 cur->t_min = cur->t1 ;
00951 cur->t_max = cur->t2 ;
00952
00953 }
00954
00955
00956
00957 if(likely(old->flags & FCF_IN_DOUBLE)) {
00958
00959 }
00960 else {
00961
00962 old->flags |= FCF_IN_DOUBLE ;
00963
00964 old->f_charge = old->charge * old1->g ;
00965 old->scharge = old->f_charge ;
00966
00967 old->f_t_ave = old->t_ave * old1->g ;
00968
00969
00970 old->f_t_ave += old->f_charge * old1->t0 ;
00971
00972 old->t_min = old->t1 ;
00973 old->t_max = old->t2 ;
00974
00975 old->p1 = p ;
00976 old->p_ave = p * old->f_charge ;
00977 }
00978
00979
00980
00981 if(unlikely(old->flags & FCF_FALLING)) {
00982
00983 if(unlikely(old->flags & FCF_ONEPAD)) {
00984 LOG(ERR,"Can't be on a merge!") ;
00985 }
00986 if(unlikely(!(old->flags & FCF_IN_DOUBLE))) {
00987 LOG(ERR,"Can't be on a merge!!!") ;
00988 }
00989
00990
00991 if(unlikely(cur->scharge > (old->scharge + FCF_MIN_ADC_PAD_C))) {
00992
00993
00994 double sc_tmp, sc_p_tmp ;
00995
00996
00997
00998 sc_tmp = old->scharge * 0.5 ;
00999 sc_p_tmp = sc_tmp * (p+1) ;
01000
01001
01002 cur->flags |= FCF_DOUBLE_PAD ;
01003 cur->f_charge += sc_tmp ;
01004 cur->p_ave += sc_p_tmp ;
01005 cur->f_t_ave += ((cur->t1 + cur->t2) * sc_tmp) * 0.5 ;
01006
01007
01008 old->flags |= FCF_DOUBLE_PAD ;
01009 old->f_charge -= sc_tmp ;
01010 old->p_ave -= sc_p_tmp ;
01011 old->f_t_ave -= ((old->t1 + old->t2) * sc_tmp) * 0.5 ;
01012
01013
01014
01015
01016
01017
01018 cur++ ;
01019 merge = 3 ;
01020 break ;
01021 }
01022
01023 cur->flags |= FCF_FALLING ;
01024 }
01025 else {
01026 if(unlikely(cur->scharge < (old->scharge - FCF_MIN_ADC_PAD_C))) {
01027 cur->flags |= FCF_FALLING ;
01028 }
01029 }
01030
01031
01032 merge = 1 ;
01033
01034
01035
01036
01037
01038 if(unlikely(!(cur->flags & FCF_ONEPAD))) {
01039 LOG(ERR,"Can;t be -- here I can have only ONEPADS!!") ;
01040 }
01041 if(unlikely(!(cur->flags & FCF_IN_DOUBLE))) {
01042 LOG(ERR,"Can't be -- I must be in double here!") ;
01043
01044 }
01045
01046
01047 cur->flags |= old->flags ;
01048 cur->flags &= ~FCF_ONEPAD ;
01049
01050 if(unlikely(modes)) {
01051 double qua ;
01052
01053 if(cur->track_id == old->track_id) {
01054 qua = cur->quality * cur->f_charge + old->quality * old->f_charge ;
01055 }
01056 else if(cur->f_charge < old->f_charge) {
01057 cur->track_id = old->track_id ;
01058
01059 qua = old->quality * old->f_charge ;
01060
01061 }
01062 else {
01063 qua = cur->quality * cur->f_charge ;
01064 }
01065 if (cur->f_charge + old->f_charge > 0)
01066 qua /= (cur->f_charge + old->f_charge) ;
01067 else qua = 0;
01068 cur->quality = (u_int )qua ;
01069
01070
01071 if(modes & 2) {
01072 cur->track_id = old->track_id ;
01073 for(int i=0;i<cur->sim_length;i++) {
01074 cur->sim[i].track_id = old->track_id ;
01075 }
01076 }
01077 }
01078
01079
01080
01081 cur->f_charge += old->f_charge ;
01082 cur->f_t_ave += old->f_t_ave ;
01083 cur->p_ave += old->p_ave ;
01084 cur->p1 = old->p1 ;
01085
01086
01087 if(cur->t1 > old->t_min) {
01088 cur->t_min = old->t_min ;
01089 }
01090 else {
01091 cur->t_min = cur->t1 ;
01092 }
01093
01094 if(cur->t2 < old->t_max) {
01095 cur->t_max = old->t_max ;
01096 }
01097 else {
01098 cur->t_max = cur->t2 ;
01099 }
01100
01101
01102
01103 cur++ ;
01104 break ;
01105 }
01106 }
01107
01108
01109
01110
01111
01112 switch(merge) {
01113 case 1 :
01114
01115 break ;
01116 default :
01117 if(old->flags & FCF_ONEPAD) {
01118 if(merge==3) {
01119 LOG(ERR,"Can;t be!") ;
01120 }
01121
01122 old->p2 = p ;
01123
01124 old->p1 = p ;
01125 dump(old,r) ;
01126 }
01127 else {
01128
01129 old->p2 = p ;
01130 dump(old,r) ;
01131 }
01132
01133 break ;
01134 }
01135
01136 old++ ;
01137
01138 }
01139
01140
01141
01142 }
01143
01144
01145 old1 = get_stage1(r,p) ;
01146 old = old1->cl ;
01147
01148
01149
01150
01151
01152
01153 for(c=0;c<old1->count;c++) {
01154
01155 old->p2 = p ;
01156 dump(old,r);
01157
01158 old++ ;
01159 }
01160
01161
01162
01163 if(cur_row_clusters) {
01164 *row_cache = (do_version<<16) | r ;
01165 *clust_count_cache = cur_row_clusters ;
01166
01167 }
01168 else {
01169 loc_buff -= 2 ;
01170 }
01171
01172 }
01173
01174 return loc_buff - (u_int *)outbuff ;
01175 }
01176
01177
01178 void tpxFCF::dump(tpxFCF_cl *cl, int row)
01179 {
01180 u_int fla = cl->flags ;
01181 u_int tmp_p, tmp_fl ;
01182 u_int pad_c ;
01183 int time_c ;
01184 double dp, dt ;
01185 u_int p1, p2 ;
01186 int div_fact ;
01187
01188
01189 switch(run_compatibility) {
01190 case 9 :
01191
01192
01193 if(likely(do_cuts)) {
01194 if(unlikely(fla & FCF_BROKEN_EDGE)) ;
01195 else if((do_cuts == 1) && (fla & (FCF_ROW_EDGE | FCF_DEAD_EDGE))) return ;
01196 }
01197
01198
01199
01200 if((fla & FCF_ONEPAD) && (cl->t1 < 15)) {
01201 if((cl->t2 - cl->t1)<=1) return ;
01202 if(cl->t2 > 30) return ;
01203
01204
01205
01206 return ;
01207 }
01208 else if(likely(do_cuts)) {
01209
01210 if(fla & FCF_BROKEN_EDGE) {
01211 ;
01212 }
01213 else if(fla & FCF_ONEPAD) return ;
01214 else if((cl->t_max - cl->t_min) <= 2) return ;
01215
01216 }
01217
01218
01219
01220
01221
01222
01223
01224 if(!(fla & FCF_IN_DOUBLE)) {
01225 if(fla & FCF_ONEPAD) {
01226 cl->p1 = cl->p2 ;
01227
01228
01229
01230
01231 cl->f_charge = (float)cl->charge * 1.0 ;
01232 cl->p_ave = cl->p1 * cl->f_charge ;
01233 cl->f_t_ave = (float)cl->t_ave * 1.0 ;
01234
01235 }
01236 else {
01237 LOG(WARN,"WTF? not double: row %d: %d-%d, %d-%d (%d-%d): charge %d (%.3f): 0x%X",cur_row,cl->p1,cl->p2,cl->t1,cl->t2,cl->t_min,cl->t_max,cl->charge,cl->f_charge,cl->flags) ;
01238 return ;
01239 }
01240 }
01241
01242 if(cl->f_charge < 1.0) {
01243 if(!(fla & FCF_DEAD_EDGE)) LOG(WARN,"WTF? no charge: row %d: %d-%d, %d-%d (%d-%d): charge %d (%.3f): 0x%X",cur_row,cl->p1,cl->p2,cl->t1,cl->t2,cl->t_min,cl->t_max,cl->charge,cl->f_charge,cl->flags) ;
01244 return ;
01245 }
01246
01247 break ;
01248 default :
01249
01250 if(unlikely(fla & FCF_BROKEN_EDGE)) goto keep ;
01251
01252 if(unlikely(do_cuts == 0)) goto keep ;
01253
01254 if(likely(do_cuts != 2)) {
01255 if(fla & (FCF_DEAD_EDGE | FCF_ROW_EDGE)) return ;
01256 }
01257
01258 if(likely(fla & FCF_IN_DOUBLE)) {
01259 if((cl->t_max - cl->t_min)<=2) return ;
01260 if(cl->f_charge < 10.0) return ;
01261 }
01262 else {
01263
01264 if(likely(fla & FCF_ONEPAD)) ;
01265 else {
01266 LOG(WARN,"WTF? not onebad but not in double!?") ;
01267 }
01268
01269 if((cl->t2 - cl->t1)<=2) return ;
01270 if(cl->charge < 10) return ;
01271
01272
01273 }
01274
01275 keep:;
01276
01277 if(likely(fla & FCF_IN_DOUBLE)) ;
01278 else {
01279
01280 if(likely(fla & FCF_ONEPAD)) ;
01281 else {
01282 LOG(WARN,"WTF? not onebad but not in double!?") ;
01283 }
01284
01285
01286
01287 struct stage1 *gain = get_stage1(row, cl->p2) ;
01288
01289 cl->p1 = cl->p2 ;
01290
01291 cl->f_charge = cl->charge * gain->g ;
01292
01293
01294 cl->f_t_ave = cl->t_ave * gain->g ;
01295
01296
01297 cl->f_t_ave += cl->f_charge * gain->t0 ;
01298
01299 cl->p_ave = cl->p2 * cl->f_charge ;
01300
01301 cl->t_min = cl->t1 ;
01302 cl->t_max = cl->t2 ;
01303
01304 }
01305
01306 }
01307
01308
01309
01310 int cha = (int) (cl->f_charge + 0.5) ;
01311
01312
01313 fla &= (~FCF_FALLING) ;
01314
01315 dt = cl->f_t_ave / cl->f_charge ;
01316 dp = cl->p_ave / cl->f_charge ;
01317
01318
01319 if(do_version == FCF_V_FY08) {
01320 div_fact = 32 ;
01321 }
01322 else {
01323 div_fact = 64 ;
01324
01325 }
01326
01327
01328 time_c = (u_int) (dt * div_fact + 0.5) ;
01329 pad_c = (u_int) (dp * div_fact + 0.5) ;
01330
01331
01332 tmp_p = pad_c / div_fact ;
01333
01334 p1 = tmp_p - cl->p1 ;
01335 p2 = cl->p2 - tmp_p ;
01336
01337 if(p1 > 7) p1 = 7 ;
01338 if(p2 > 7) p2 = 7 ;
01339
01340 tmp_fl = (p1 << 8) | (p2 << 11) ;
01341
01342
01343
01344 tmp_p = time_c / div_fact ;
01345
01346 p1 = tmp_p - cl->t_min ;
01347 p2 = cl->t_max - tmp_p ;
01348
01349 if(p1 > 15) p1 = 15 ;
01350 if(p2 > 15) p2 = 15 ;
01351
01352
01353 tmp_fl |= (p2 << 4) | p1 ;
01354
01355
01356 if(fla & FCF_ONEPAD) time_c |= 0x8000 ;
01357
01358 if(fla & (FCF_DOUBLE_T | FCF_DOUBLE_PAD)) pad_c |= 0x8000 ;
01359 if(fla & FCF_DEAD_EDGE) pad_c |= 0x4000 ;
01360
01361 if(fla & FCF_ROW_EDGE) tmp_fl |= 0x8000 ;
01362 if(fla & FCF_BROKEN_EDGE) tmp_fl |= 0x4000 ;
01363
01364 if(cha > 0x7FFF) cha = 0x8000 | (cha/1024) ;
01365
01366
01367 *loc_buff++ = (time_c << 16) | pad_c ;
01368 *loc_buff++ = (cha << 16) | tmp_fl ;
01369
01370
01371 if(modes) {
01372 *loc_buff++ = (cl->quality << 16) | cl->track_id ;
01373 }
01374
01375
01376 cur_row_clusters++ ;
01377
01378
01379 return ;
01380 }