00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <errno.h>
00004 #include <math.h>
00005 #include <stdlib.h>
00006 #include <sys/stat.h>
00007 #include <unistd.h>
00008 #include <time.h>
00009
00010 #include <rtsLog.h>
00011 #include <daqModes.h>
00012
00013 #include <TPC/rowlen.h>
00014
00015 #include <TPX/tpx_altro_to_pad.h>
00016
00017 #include "tpxCore.h"
00018 #include "tpxGain.h"
00019
00020
00021
00022
00023 struct tpx_odd_fee_t tpx_odd_fee[256] ;
00024 int tpx_odd_fee_count = 0 ;
00025
00026
00027 static u_int histo_data[2000] ;
00028 static void histo_init()
00029 {
00030 memset(histo_data,0,sizeof(histo_data)) ;
00031 }
00032
00033 static void histo_fill(double gain)
00034 {
00035 int i_gain = (int) gain ;
00036
00037 if((i_gain>=0) && (i_gain<2000)) histo_data[i_gain]++ ;
00038
00039 return ;
00040 }
00041
00042 static double histo_peak()
00043 {
00044 int max_sum, sum ;
00045 int start_i = 0;
00046 double peak ;
00047
00048 max_sum = 0 ;
00049 for(int i=0;i<(2000-10);i++) {
00050 sum = 0 ;
00051 for(int j=0;j<10;j++) {
00052 sum += histo_data[i+j] ;
00053 }
00054 if(sum > max_sum) {
00055 max_sum = sum ;
00056 start_i = i ;
00057 }
00058 }
00059
00060 sum = 0 ;
00061 peak = 0.0 ;
00062
00063 for(int i=start_i;i<(start_i+10);i++) {
00064 sum += histo_data[i] ;
00065 peak += i*histo_data[i] ;
00066 }
00067
00068
00069 if(sum) {
00070 peak /= sum ;
00071 peak += 0.5 ;
00072 }
00073
00074 return peak ;
00075 }
00076
00077
00078
00079 tpxGain::tpxGain()
00080 {
00081 events = 0 ;
00082 load_time = 0 ;
00083 sector = 0 ;
00084 c_run = c_date = c_time = 0 ;
00085
00086
00087 raw_gains_fname = 0 ;
00088
00089
00090 aux = 0 ;
00091 means = 0 ;
00092 fee_found = 0 ;
00093 memset(gains,0,sizeof(gains)) ;
00094
00095 dummy_gain.g = 1.0 ;
00096 dummy_gain.t0 = 0.0 ;
00097
00098
00099 memset(bad_fee,0,sizeof(bad_fee)) ;
00100 tpx_odd_fee_count = 0 ;
00101
00102 memset(bad_rdo_mask,0,sizeof(bad_rdo_mask)) ;
00103
00104 pulser_ped = TPX_PULSER_PED_START ;
00105
00106 pulser_ped_stop = TPX_TCU_LOC_PED_STOP ;
00107 pulser_start = TPX_TCU_LOC_START ;
00108 pulser_stop = TPX_TCU_LOC_STOP ;
00109 pulser_time_0 = TPX_TCU_LOC_TIME_0 ;
00110
00111 clock_mode = TPX_CLOCK_TCU_LOC ;
00112
00113 return ;
00114 }
00115
00116 tpxGain::~tpxGain()
00117 {
00118 free_store() ;
00119
00120 return ;
00121 }
00122
00123 void tpxGain::set_clock_mode(int mode)
00124 {
00125 clock_mode = mode ;
00126
00127 switch(mode) {
00128 default:
00129 case TPX_CLOCK_TCU_LOC :
00130 pulser_ped_stop = TPX_TCU_LOC_PED_STOP ;
00131 pulser_start = TPX_TCU_LOC_START ;
00132 pulser_stop = TPX_TCU_LOC_STOP ;
00133 pulser_time_0 = TPX_TCU_LOC_TIME_0 ;
00134 break ;
00135 case TPX_CLOCK_TCD :
00136 pulser_ped_stop = TPX_TCD_PED_STOP ;
00137 pulser_start = TPX_TCD_START ;
00138 pulser_stop = TPX_TCD_STOP ;
00139 pulser_time_0 = TPX_TCD_TIME_0 ;
00140 break ;
00141 case TPX_CLOCK_TCU_RHIC :
00142 pulser_ped_stop = TPX_TCU_RHIC_PED_STOP ;
00143 pulser_start = TPX_TCU_RHIC_START ;
00144 pulser_stop = TPX_TCU_RHIC_STOP ;
00145 pulser_time_0 = TPX_TCU_RHIC_TIME_0 ;
00146 break ;
00147 }
00148
00149
00150 return ;
00151 }
00152
00153
00154 void tpxGain::free_store()
00155 {
00156 if(aux) {
00157 free(aux) ;
00158 aux = 0 ;
00159 }
00160
00161 if(means) {
00162 free(means) ;
00163 means = 0 ;
00164 }
00165
00166 if(fee_found) {
00167 free(fee_found) ;
00168 fee_found = 0 ;
00169 }
00170
00171 for(int i=0;i<24;i++) {
00172 if(gains[i]) {
00173 free(gains[i]) ;
00174 gains[i] = 0 ;
00175 }
00176 }
00177
00178 return ;
00179 }
00180
00181
00182
00183
00184 void tpxGain::init(int sec)
00185 {
00186 int bytes ;
00187
00188 events = 0 ;
00189 load_time = 0 ;
00190 sector = sec ;
00191
00192
00193
00194 bytes = sizeof(struct means) * 24 * 46 ;
00195 if(means==0) {
00196 means = (struct means *) malloc(bytes) ;
00197 }
00198 memset(means,0,bytes) ;
00199
00200 bytes = sizeof(struct aux) * 24 * 46 * 182 ;
00201 if(aux==0) {
00202 aux = (struct aux *) malloc(bytes) ;
00203 }
00204 memset(aux,0,bytes) ;
00205
00206 bytes = sizeof(struct fee_found_t) * 25 * 7 ;
00207 if(fee_found == 0) {
00208 fee_found = (struct fee_found_t *) malloc(bytes) ;
00209
00210 }
00211 memset(fee_found,0,bytes) ;
00212
00213 for(int i=0;i<24;i++) {
00214 bytes = sizeof(struct gains) * 46 * 182 ;
00215 if(gains[i]==0) {
00216 gains[i] = (struct gains *) malloc(bytes) ;
00217 }
00218 memset(gains[i],0,bytes) ;
00219 }
00220
00221
00222
00223 memset(tpx_pulser_peak,0,sizeof(tpx_pulser_peak)) ;
00224
00225
00226
00227
00228 #if 0
00229
00230 tb_start = 179 ;
00231 tb_stop = 188 ;
00232 #endif
00233
00234 memset(bad_rdo_mask,0,sizeof(bad_rdo_mask)) ;
00235
00236 return ;
00237 }
00238
00239
00240
00241
00242
00243 void tpxGain::ev_done()
00244 {
00245 if(events==0) {
00246 LOG(WARN,"Using hardcoded tb range: ped at [%3d:%3d], peak at [%3d:%3d], T0 at %f!",pulser_ped, pulser_ped_stop, pulser_start,pulser_stop,pulser_time_0) ;
00247 }
00248
00249 events++ ;
00250 LOG(NOTE,"After event %d",events) ;
00251
00252 return ;
00253 }
00254
00255
00256
00257
00258
00259 void tpxGain::accum(char *evbuff, int bytes)
00260 {
00261 int t ;
00262 int i ;
00263 u_int *data_end ;
00264 int sec ;
00265 tpx_rdo_event rdo ;
00266 tpx_altro_struct a ;
00267 struct gains *gs ;
00268 struct aux *as ;
00269
00270
00271 t = tpx_get_start(evbuff, bytes/4, &rdo, 0) ;
00272
00273 LOG(NOTE,"RDO %d: %d bytes,token %d",rdo.rdo,bytes,t) ;
00274
00275 if(t <= 0) return ;
00276
00277
00278 sec = rdo.sector ;
00279 data_end = rdo.data_end ;
00280 a.rdo = rdo.rdo - 1 ;
00281 a.what = TPX_ALTRO_DO_ADC ;
00282 a.t = rdo.token ;
00283 a.sector = rdo.sector ;
00284 a.log_err = 0 ;
00285
00286
00287 struct fee_found_t *fee_f = get_fee_found(sec,rdo.rdo) ;
00288 fee_f->got_one++ ;
00289
00290 LOG(DBG,"gain: evt %d (got_one %d), sector %d, rdo %d",events, fee_f->got_one,rdo.sector, rdo.rdo) ;
00291
00292 do {
00293
00294 data_end = tpx_scan_to_next(data_end, rdo.data_start, &a) ;
00295
00296 fee_f->ch_count[a.id][a.ch]++ ;
00297
00298 if((a.row>45) || (a.pad>182)) {
00299 LOG(TERR,"Should not be here! row %d, pad %d, aid %3d:%02d",a.row,a.pad, a.id, a.ch) ;
00300 continue ;
00301 }
00302
00303 gs = get_gains(sec,a.row,a.pad) ;
00304 as = get_aux(sec,a.row,a.pad) ;
00305
00306
00307 double cou, noise ;
00308
00309 cou = 0.0 ;
00310 noise = 0.0 ;
00311
00312
00313 if(a.count) as->cou++ ;
00314
00315 for(i=0;i<a.count;i++) {
00316 if(a.adc[i] == 0) continue ;
00317
00318 int adc_i = a.adc[i] ;
00319 int tb_i = a.tb[i] ;
00320
00321
00322 if((tb_i>=pulser_ped) && (tb_i<=pulser_stop)) {
00323 as->adc_store[tb_i - pulser_ped] += adc_i ;
00324 }
00325 else if(tb_i < pulser_ped) {
00326 noise += adc_i ;
00327 cou++ ;
00328 }
00329 }
00330
00331 if(cou) noise /= cou ;
00332
00333
00334 if((noise > 40.0) || (cou>20)) {
00335 as->noise++ ;
00336 }
00337
00338 } while(data_end && (data_end > rdo.data_start)) ;
00339
00340
00341 return ;
00342
00343 }
00344
00345
00346
00347
00348
00349
00350
00351 void tpxGain::if_file()
00352 {
00353 memset(bad_rdo_mask, 0, sizeof(bad_rdo_mask)) ;
00354
00355 for(int s=1;s<=24;s++) {
00356 for(int r=1;r<=6;r++) {
00357 struct fee_found_t *fee_f = get_fee_found(s,r) ;
00358
00359 if(fee_f->got_one) {
00360 for(int a=0;a<256;a+=2) {
00361 int not_bad ;
00362
00363 if(tpx_altro_to_fee(r,a)<0) continue ;
00364
00365 not_bad = 0 ;
00366
00367 for(int w=a;w<(a+2);w++) {
00368 for(int c=0;c<16;c++) {
00369 if(fee_f->ch_count[w][c]) {
00370 not_bad = 1 ;
00371 break ;
00372 }
00373 }
00374 if(not_bad) break ;
00375 }
00376
00377 if(!not_bad) {
00378 int c = bad_fee[s][r][0] ;
00379
00380 bad_fee[s][r][c+1] = a ;
00381 bad_fee[s][r][0]++ ;
00382
00383 int fee = tpx_altro_to_fee(r,a) ;
00384
00385 LOG(WARN,"Possible bad FEE %3d (ALTRO %3d) on sector %2d, RDO %d",fee,a,s,r) ;
00386 LOG(WARN," to tpx_gains.txt: %d %d %d 0.000 0.000",-s,r,fee) ;
00387 }
00388 }
00389 }
00390 else {
00391 bad_rdo_mask[s] |= (1<<(r-1)) ;
00392 LOG(WARN,"Possible masked RDO %d on sector %2d",r,s) ;
00393 }
00394
00395 }
00396
00397
00398 }
00399
00400
00401 return ;
00402
00403 }
00404
00405
00406
00407
00408
00409 void tpxGain::calc()
00410 {
00411 int s, r, p ;
00412 int c ;
00413 double g_rms, t0_rms, c_rms ;
00414 int t0_mean_count[25] ;
00415 double t0_mean[25] ;
00416
00417 memset(t0_mean_count,0,sizeof(t0_mean_count)) ;
00418 memset(t0_mean,0,sizeof(t0_mean)) ;
00419
00420 g_rms = t0_rms = c_rms = 0 ;
00421
00422
00423
00424
00425
00426 LOG(DBG,"gain_calc: doing calculation with %d events",events) ;
00427
00428
00429
00430
00431
00432 int s_start, s_stop ;
00433
00434 if(sector==0) {
00435 s_start = 1 ;
00436 s_stop = 24 ;
00437 }
00438 else {
00439 s_start = sector ;
00440 s_stop = sector ;
00441 }
00442
00443
00444 char fname[128];
00445 FILE *ofile = 0 ;
00446 if(raw_gains_fname) {
00447 sprintf(fname,"%s_%02d",raw_gains_fname,sector) ;
00448 ofile = fopen(fname,"w") ;
00449 }
00450
00451
00452 for(s=s_start;s<=s_stop;s++) {
00453
00454
00455 for(r=1;r<=45;r++) {
00456
00457
00458 if(get_means(s,r)->g || get_means(s,r)->t0) {
00459 LOG(ERR,"%f %f",get_means(s,r)->g,get_means(s,r)->t0) ;
00460 }
00461
00462
00463 for(p=1;p<=tpc_rowlen[r];p++) {
00464 c = get_aux(s,r,p)->cou ;
00465
00466 if(!c) {
00467 get_gains(s,r,p)->g = 0.0 ;
00468 get_gains(s,r,p)->t0 = 9.999 ;
00469
00470 int aa,cc,rdo ;
00471 tpx_to_altro(r,p,rdo,aa,cc) ;
00472 rdo-- ;
00473 if(bad_rdo_mask[s] & (1<<rdo)) {
00474
00475
00476 get_gains(s,r,p)->t0 = -9.990 ;
00477
00478 }
00479
00480
00481 rdo++ ;
00482 int c = bad_fee[s][rdo][0] ;
00483
00484 for(int i=0;i<c;i++) {
00485 int al=bad_fee[s][rdo][i+1];
00486 for(int j=0;j<2;j++) {
00487
00488 if(aa == (int)al) {
00489
00490 get_gains(s,r,p)->t0 = -9.900 ;
00491 }
00492 al++ ;
00493 }
00494 }
00495
00496 }
00497 else {
00498 int ped_cou = 0 ;
00499 double ped = 0.0 ;
00500
00501 struct aux *as = get_aux(s,r,p) ;
00502
00503
00504 for(int i=pulser_ped;i<=pulser_ped_stop;i++) {
00505 ped += (double) as->adc_store[i-pulser_ped] / (double) c ;
00506 ped_cou++ ;
00507 }
00508
00509 ped /= ped_cou ;
00510
00511 double charge, t0 ;
00512 charge = t0 = 0.0 ;
00513
00514
00515 for(int i=pulser_start;i<=pulser_stop;i++) {
00516 double val = (double) as->adc_store[i-pulser_ped] / (double) c - ped ;
00517 charge += val ;
00518 t0 += i * val ;
00519 }
00520
00521
00522
00523 get_gains(s,r,p)->g = charge ;
00524
00525 if(charge) {
00526 get_gains(s,r,p)->t0 = t0/charge ;
00527 }
00528 else {
00529 get_gains(s,r,p)->t0 = 0.0 ;
00530 }
00531
00532 }
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 for(p=1;p<=tpc_rowlen[r];p++) {
00547 struct aux *aux = get_aux(s,r,p) ;
00548
00549 if(events) {
00550 aux->low_pulse = (100 * aux->low_pulse) / events ;
00551 aux->high_pulse = (100 * aux->high_pulse) / events ;
00552 aux->noise = (100 * aux->noise) / events ;
00553 }
00554 }
00555
00556 histo_init() ;
00557
00558 c = 0 ;
00559
00560 for(p=1;p<=tpc_rowlen[r];p++) {
00561 struct aux *aux = get_aux(s,r,p) ;
00562 int fired = aux->cou ;
00563
00564
00565 if(fired) ;
00566 else aux->low_pulse = 100 ;
00567
00568
00569
00570 if(get_gains(s,r,p)->g < 100.0) aux->low_pulse = 100 ;
00571 if(get_gains(s,r,p)->g > 2000.0) aux->high_pulse = 100 ;
00572
00573
00574 if((aux->low_pulse > 10) || (aux->noise > 10) || (aux->high_pulse > 10)) {
00575 if(r != 0) LOG(NOTE,"ROW %d, pad %d: lo %d, noise %d, hi %d -- skipping",r,p,
00576 aux->low_pulse, aux->noise, aux->high_pulse) ;
00577 continue ;
00578 }
00579
00580
00581 if((p>=4) && (p<=(tpc_rowlen[r]-3))) {
00582 histo_fill(get_gains(s,r,p)->g) ;
00583 c++ ;
00584 }
00585 }
00586
00587 int accepted_pads_cou = c ;
00588
00589 double row_means = histo_peak() ;
00590
00591
00592
00593
00594
00595
00596 c = 0 ;
00597 int tot_pads_cou ;
00598 int good_pads_cou ;
00599
00600 tot_pads_cou = good_pads_cou = 0 ;
00601
00602 for(p=4;p<=(tpc_rowlen[r]-3);p++) {
00603 double g = get_gains(s,r,p)->g ;
00604
00605
00606 if( (g>(row_means*0.9)) && (g<(row_means*1.1))) {
00607
00608 get_means(s,r)->g += g ;
00609 get_means(s,r)->g_rms += g * g ;
00610
00611 get_means(s,r)->t0 += get_gains(s,r,p)->t0 ;
00612 get_means(s,r)->t0_rms += get_gains(s,r,p)->t0 * get_gains(s,r,p)->t0 ;
00613 c++ ;
00614 }
00615
00616 tot_pads_cou++ ;
00617 }
00618
00619 good_pads_cou = c ;
00620
00621
00622 if(c==0) {
00623
00624 get_means(s,r)->t0 = tb_stop ;
00625 }
00626 else {
00627 get_means(s,r)->g /= c ;
00628 get_means(s,r)->g_rms /= c ;
00629
00630 get_means(s,r)->g_rms = sqrt(get_means(s,r)->g_rms - get_means(s,r)->g * get_means(s,r)->g) ;
00631
00632 get_means(s,r)->t0 /= c ;
00633 get_means(s,r)->t0_rms /= c ;
00634
00635 get_means(s,r)->t0_rms = sqrt(get_means(s,r)->t0_rms - get_means(s,r)->t0 * get_means(s,r)->t0) ;
00636 }
00637
00638
00639 #if 0
00640
00641 printf("%2d %2d %f %f %f %f\n",s,r,
00642 get_means(s,r)->g, get_means(s,r)->g_rms,
00643 get_means(s,r)->t0, get_means(s,r)->t0_rms) ;
00644 #endif
00645
00646
00647
00648
00649
00650
00651 for(p=1;p<=tpc_rowlen[r];p++) {
00652
00653 if(ofile) fprintf(ofile,"%d %d %d %.3f %.3f ",s,r,p,get_gains(s,r,p)->g,get_gains(s,r,p)->t0) ;
00654
00655 if(get_gains(s,r,p)->g) {
00656
00657 get_gains(s,r,p)->g = get_means(s,r)->g / get_gains(s,r,p)->g ;
00658
00659 if((p==1) || (p==2) || (p==tpc_rowlen[r]) || (p==(tpc_rowlen[r]-1))) ;
00660 else {
00661 t0_mean[s] += get_gains(s,r,p)->t0 ;
00662 t0_mean_count[s]++ ;
00663 }
00664
00665
00666 }
00667
00668 if(ofile) fprintf(ofile,"%.3f %.3f\n",get_gains(s,r,p)->g, get_gains(s,r,p)->t0) ;
00669 }
00670
00671
00672 if(get_means(s,r)->g != 0.0) {
00673 LOG(NOTE,"Sector %2d, row %2d: charge %.3f +- %.3f; t0 %.3f +- %.3f; rough mean %.3f; good/acc/all pads %d/%d/%d",
00674 s,r,
00675 get_means(s,r)->g, get_means(s,r)->g_rms,
00676 get_means(s,r)->t0, get_means(s,r)->t0_rms,
00677 row_means,good_pads_cou, accepted_pads_cou, tot_pads_cou) ;
00678 }
00679 else {
00680 LOG(WARN,"Sector %2d, row %2d: charge %f +- %f; t0 %f +- %f; rough_mean %.1f; good/acc/all pads %d/%d/%d",
00681 s,r,
00682 get_means(s,r)->g, get_means(s,r)->g_rms,
00683 get_means(s,r)->t0, get_means(s,r)->t0_rms,
00684 row_means,good_pads_cou, accepted_pads_cou, tot_pads_cou) ;
00685 }
00686
00687
00688
00689 if(get_means(s,r)->g) {
00690
00691
00692
00693
00694
00695 g_rms += get_means(s,r)->g_rms ;
00696 t0_rms += get_means(s,r)->t0_rms ;
00697 c_rms++ ;
00698 }
00699
00700
00701
00702 }
00703 }
00704
00705
00706
00707 g_rms /= c_rms ;
00708 t0_rms /= c_rms ;
00709
00710 if(ofile) fclose(ofile) ;
00711
00712 double t0_all_mean = 0.0 ;
00713 int t0_all_mean_count = 0 ;
00714 for(int s=s_start;s<=s_stop;s++) {
00715 if(t0_mean_count[s]) {
00716 t0_mean[s] /= (double) t0_mean_count[s] ;
00717 if(s!=16) {
00718 t0_all_mean += t0_mean[s] ;
00719 t0_all_mean_count++ ;
00720 }
00721
00722 }
00723 }
00724
00725
00726 if((s_start==16) && (s_stop==16)) {
00727 LOG(WARN,"Sector 16 -- special case") ;
00728 t0_all_mean += t0_mean[16] ;
00729 t0_all_mean_count = 1 ;
00730 }
00731
00732 if(t0_all_mean_count) t0_all_mean /= (double) t0_all_mean_count ;
00733
00734
00735
00736 for(int s=s_start;s<=s_stop;s++) {
00737 for(int r=1;r<=45;r++) {
00738 for(int p=1;p<=tpc_rowlen[r];p++) {
00739 double t0 = get_gains(s,r,p)->t0 ;
00740
00741 if(get_gains(s,r,p)->g) {
00742 get_gains(s,r,p)->t0 = t0_all_mean - t0 ;
00743 }
00744
00745 }
00746 }
00747 }
00748
00749 LOG(TERR,"gain_calc: sectors [%d:%d]: %d events used: Mean RMS: %f gain; T0 %f +- %f, diff from canonical %f",
00750 s_start,s_stop,
00751 events,
00752 g_rms,
00753 t0_all_mean, t0_rms,
00754 pulser_time_0-t0_all_mean) ;
00755
00756
00757 return ;
00758 }
00759
00760 void tpxGain::do_default(int sector)
00761 {
00762 int s, r, p ;
00763
00764
00765
00766 memset(bad_fee,0,sizeof(bad_fee)) ;
00767 tpx_odd_fee_count = 0 ;
00768
00769 if(sector) {
00770 if(gains[sector-1] == 0) {
00771 gains[sector-1] = (struct gains *) malloc(sizeof(struct gains) * 46 * 182) ;
00772 }
00773 }
00774 else {
00775 for(int i=0;i<24;i++) {
00776 if(gains[i] == 0) {
00777 gains[i] = (struct gains *) malloc(sizeof(struct gains) * 46 * 182) ;
00778 }
00779 }
00780 }
00781
00782
00783 for(s=1;s<=24;s++) {
00784 if(gains[s-1]) {
00785 memset(gains[s-1],0,sizeof(struct gains) * 46 * 182) ;
00786 }
00787 else {
00788 continue ;
00789 }
00790
00791 for(r=1;r<=45;r++) {
00792 for(p=1;p<=tpc_rowlen[r];p++) {
00793 set_gains(s,r,p,1.0,0.0) ;
00794 }
00795 }
00796 }
00797
00798
00799 return ;
00800 }
00801
00802 int tpxGain::from_file(char *fname, int sec)
00803 {
00804 FILE *f ;
00805 int s, r, p ;
00806 float g, t0 ;
00807 struct stat buff ;
00808
00809
00810 sector = sec ;
00811
00812 f = fopen(fname,"r") ;
00813
00814 if(f==0) {
00815 LOG(WARN,"from_file: error in fopen \"%s\" [%s]",fname,strerror(errno)) ;
00816 do_default(sector) ;
00817 return -1 ;
00818 }
00819
00820
00821
00822 stat(fname, &buff) ;
00823
00824 LOG(DBG,"After stat %s %d %d",fname,buff.st_mtime,load_time) ;
00825
00826 if(load_time < buff.st_mtime) {
00827 LOG(DBG,"Will reload...") ;
00828 LOG(INFO,"Reloading \"%s\"",fname) ;
00829 }
00830 else {
00831 LOG(DBG,"Wont relaod") ;
00832 LOG(INFO,"Keeping cached copy of gains...") ;
00833 return 0 ;
00834 }
00835
00836
00837 c_run = 0 ;
00838 c_date = 0 ;
00839 c_time = 0 ;
00840
00841 u_int f_date, f_time ;
00842
00843 struct tm tm ;
00844 localtime_r(&buff.st_mtime, &tm) ;
00845
00846 f_date = (tm.tm_year+1900) * 10000 + (tm.tm_mon+1) * 100 + tm.tm_mday ;
00847 f_time = tm.tm_hour * 10000 + tm.tm_min * 100 + tm.tm_sec ;
00848
00849
00850
00851 load_time = time(NULL) ;
00852 do_default(sector) ;
00853
00854 LOG(TERR,"reading gains from \"%s\" for sector %d...",fname, sector) ;
00855
00856
00857
00858 while(!feof(f)) {
00859 char str[1024] ;
00860
00861 if(fgets(str,sizeof(str)-1,f)==0) continue ;
00862
00863 if(strlen(str)==0) continue ;
00864
00865 if((str[0]=='#') || (str[0]=='/')) {
00866 char *cix ;
00867 if((cix = strstr(str,"Run "))) {
00868 sscanf(cix+4,"%u",&c_run) ;
00869 }
00870 else if((cix = strstr(str,"Date "))) {
00871 sscanf(cix+5,"%u",&c_date) ;
00872 }
00873 else if((cix = strstr(str,"Time "))) {
00874 sscanf(cix+5,"%u",&c_time) ;
00875 }
00876 else {
00877 continue ;
00878 }
00879 }
00880
00881 int ret = sscanf(str,"%d %d %d %f %f\n",&s,&r,&p,&g,&t0) ;
00882
00883 if(ret != 5) continue ;
00884
00885
00886 if(s < 0) {
00887 s *= -1 ;
00888
00889 if(sector && (s != sector)) continue ;
00890
00891 int altro ;
00892
00893
00894 int c = bad_fee[s][r][0] ;
00895
00896
00897
00898
00899 altro = (p<<1) & 0xFF ;
00900 bad_fee[s][r][c+1] = altro ;
00901
00902 bad_fee[s][r][0]++ ;
00903
00904
00905 c = tpx_odd_fee_count ;
00906 tpx_odd_fee[c].sector = s ;
00907 tpx_odd_fee[c].rdo = r ;
00908 tpx_odd_fee[c].status = 2 ;
00909 tpx_odd_fee[c].tpc_fee_padplane = p ;
00910 tpx_odd_fee[c].altro_id_padplane = altro ;
00911
00912 tpx_odd_fee_count++ ;
00913
00914 LOG(INFO,"Bad FEE %d: sector %2d, RB %d, ALTRO %3d (TPC-FEE %3d)",bad_fee[s][r][0],s,r,altro,p) ;
00915
00916 continue ;
00917 }
00918
00919
00920 if(sector && (s != sector)) continue ;
00921
00922 set_gains(s,r,p,g,t0) ;
00923
00924 }
00925 fclose(f) ;
00926
00927
00928 for(s=1;s<=24;s++) {
00929
00930 if(sector && (s != sector)) continue ;
00931
00932 for(r=1;r<=6;r++) {
00933
00934 for(u_int c=0;c<bad_fee[s][r][0];c++) {
00935 int fee ;
00936
00937 fee = bad_fee[s][r][c+1] ;
00938
00939 for(int i=0;i<2;i++) {
00940 for(int ch=0;ch<16;ch++) {
00941 int row, pad ;
00942
00943 tpx_from_altro(r-1,fee+i,ch, row, pad) ;
00944
00945 if(row>45) {
00946 LOG(ERR,"What????") ;
00947 continue ;
00948 }
00949
00950 set_gains(s,row,pad,0.0,-9.900) ;
00951
00952
00953 LOG(DBG,"Killing rp %d:%d for bad FEE %3d in sector %2d",row,pad,fee,s) ;
00954 }
00955 }
00956
00957 }
00958 }
00959 }
00960
00961 LOG(TERR,"Gains read: run %08u, date %08u [%08u], time %06u [%06u]",c_run,c_date,f_date,c_time,f_time) ;
00962 return 1 ;
00963 }
00964
00965
00966 int tpxGain::to_file(char *fname)
00967 {
00968
00969 FILE *f ;
00970 int s, r, p ;
00971
00972 time_t tim = time(NULL) ;
00973
00974 if(strcmp(fname,"stdout")==0) f = stdout ;
00975 else {
00976 f = fopen(fname,"w") ;
00977 }
00978
00979 if(f==0) {
00980 LOG(ERR,"gains: fopen \"%s\" [%s]",fname,strerror(errno)) ;
00981 return -1 ;
00982 }
00983
00984
00985
00986 int s_start, s_stop ;
00987 if(sector>0) {
00988 s_start = sector ;
00989 s_stop = sector ;
00990 }
00991 else {
00992 s_start = 1 ;
00993 s_stop = 24 ;
00994 }
00995
00996
00997 struct tm tm ;
00998 localtime_r(&tim, &tm) ;
00999
01000 c_date = (tm.tm_year+1900) * 10000 + (tm.tm_mon+1) * 100 + tm.tm_mday ;
01001 c_time = tm.tm_hour * 10000 + tm.tm_min * 100 + tm.tm_sec ;
01002
01003 LOG(TERR,"gains: writing to file \"%s\" for sectors %d..%d: run %u, date %u, time %u",fname,
01004 s_start,s_stop,
01005 c_run, c_date, c_time) ;
01006
01007 fprintf(f,"# $Id: tpxGain.cxx,v 1.29 2012/04/27 09:15:15 tonko Exp $\n") ;
01008 fprintf(f,"# Run %u\n",c_run) ;
01009
01010 for(s=s_start;s<=s_stop;s++) {
01011
01012 if(bad_rdo_mask[s]) {
01013 LOG(WARN,"Sector %02d: bad rdo mask 0x%02X",s,bad_rdo_mask[s]) ;
01014 }
01015
01016
01017 for(r=1;r<=45;r++) {
01018 for(p=1;p<=tpc_rowlen[r];p++) {
01019 float t0 = get_gains(s,r,p)->t0 ;
01020 float gg = get_gains(s,r,p)->g ;
01021
01022 fprintf(f,"%d %d %d %.3f %6.3f",s,r,p,
01023 gg,
01024 t0) ;
01025
01026 if(t0 < -9.9) {
01027 fprintf(f," # RDO missing\n") ;
01028 }
01029 else if(t0 < -9.0) {
01030 fprintf(f," # FEE missing\n") ;
01031 }
01032 else {
01033 fprintf(f,"\n") ;
01034 }
01035 }
01036 }
01037 }
01038
01039
01040 fprintf(f,"# Date %u\n",c_date) ;
01041 fprintf(f,"# Time %u\n",c_time) ;
01042
01043 if(f != stdout) fclose(f) ;
01044
01045 LOG(TERR,"gains: written.") ;
01046
01047 return 0 ;
01048 }
01049
01050 void tpxGain::compare(char *fname, int mysec)
01051 {
01052 FILE *f ;
01053 int s, r, p ;
01054 float g, t0 ;
01055 double dg_mean, dg_rms ;
01056 double dt_mean, dt_rms ;
01057 int dg_count ;
01058
01059 int both, old_only, new_only ;
01060
01061 old_only = new_only = both = 0 ;
01062
01063 f = fopen(fname,"r") ;
01064
01065 if(f==0) {
01066 LOG(ERR,"from_file: error in fopen \"%s\" [%s]",fname,strerror(errno)) ;
01067 return ;
01068 }
01069
01070 dg_mean = dg_rms = dt_mean = dt_rms = 0.0 ;
01071 dg_count = 0 ;
01072
01073
01074 char (*f_bad)[46][183] = (char (*)[46][183]) malloc(25*46*183) ;
01075
01076 if(f_bad == 0) {
01077 LOG(ERR,"Malloc failed? Wha? [%s]",strerror(errno)) ;
01078 return ;
01079 }
01080
01081 while(!feof(f)) {
01082 char str[1024] ;
01083
01084 if(fgets(str,sizeof(str)-1,f)==0) continue ;
01085
01086 if(strlen(str)==0) continue ;
01087 if((str[0]=='#') || (str[0]=='/')) continue ;
01088
01089
01090 int ret = sscanf(str,"%d %d %d %f %f\n",&s,&r,&p,&g,&t0) ;
01091
01092 if(ret != 5) continue ;
01093 if(s < 0) continue ;
01094
01095 if(mysec && (s != mysec)) continue ;
01096
01097 if(r==0) continue ;
01098
01099
01100
01101
01102 if((p==1) || (p==2)) continue ;
01103 if((p==tpc_rowlen[r]) || (p==(tpc_rowlen[r]-1))) continue ;
01104
01105 if(g==0.0) f_bad[s][r][p] = 1 ;
01106 else f_bad[s][r][p] = 0 ;
01107 }
01108
01109 fclose(f) ;
01110
01111 for(int s=1;s<=24;s++) {
01112 if(mysec && (s != mysec)) continue ;
01113
01114 for(int r=1;r<=45;r++) {
01115 for(int p=1;p<=tpc_rowlen[r];p++) {
01116
01117
01118 if((p==1) || (p==2)) continue ;
01119 if((p==tpc_rowlen[r]) || (p==(tpc_rowlen[r]-1))) continue ;
01120
01121
01122
01123 if(f_bad[s][r][p]) {
01124 if(get_gains(s,r,p)->g == 0.0) both++ ;
01125 else old_only++ ;
01126 }
01127 else {
01128
01129
01130 if(get_gains(s,r,p)->g == 0.0) {
01131 if(get_gains(s,r,p)->t0 < -9.0) {
01132 LOG(DBG,"FEE/RDO was marked as bad (%d,%d,%d) -- skipping",s,r,p) ;
01133 }
01134 else {
01135
01136 new_only++ ;
01137 }
01138 }
01139 else {
01140 double dg = get_gains(s,r,p)->g / g ;
01141 double dt0 = get_gains(s,r,p)->t0 - t0 ;
01142
01143 dg_mean += dg ;
01144 dg_rms += dg * dg ;
01145
01146 dt_mean += dt0 ;
01147 dt_rms += dt0 * dt0 ;
01148
01149 dg_count++ ;
01150 }
01151 }
01152 }
01153 }
01154 }
01155
01156
01157 free(f_bad) ;
01158
01159
01160
01161 if(dg_count) {
01162 dg_mean /= (double) dg_count ;
01163 dg_rms /= (double) dg_count ;
01164 dt_mean /= (double) dg_count ;
01165 dt_rms /= (double) dg_count ;
01166
01167 dg_rms = sqrt(dg_rms - dg_mean * dg_mean) ;
01168 dt_rms = sqrt(dt_rms - dt_mean * dt_mean) ;
01169 }
01170
01171 int max_allowed = 2 ;
01172 if(mysec == 0) {
01173 max_allowed *= 24 ;
01174 }
01175
01176 if(new_only>max_allowed) {
01177 LOG(ERR, "gain_compare to %s: sector %d: seems to have new bad pads: both %3d, new_only %3d, old_only %d",
01178 fname,
01179 mysec,both,new_only,old_only) ;
01180 }
01181 else {
01182 LOG(INFO,"gain_compare to %s: sector %d: both %3d, new_only %3d, old_only %d",
01183 fname,mysec,both,new_only,old_only) ;
01184 }
01185
01186
01187
01188 return ;
01189 }
01190
01191 int tpxGain::summarize(char *fname, FILE *log, int gain_mode)
01192 {
01193 int s, r, a ;
01194 char reason[1024] ;
01195 u_int good, bad ;
01196 FILE *ofile ;
01197 int notes = 0 ;
01198
01199 good = bad = 0 ;
01200 reason[0] = 0 ;
01201
01202 if(fname==0) ofile = 0 ;
01203 else if(strcmp(fname,"stdout")==0) ofile = stdout ;
01204 else {
01205 ofile = fopen(fname,"w") ;
01206 if(ofile==0) {
01207 getcwd(reason,100) ;
01208 LOG(ERR,"summarize: error in fopen %s\"%s\" [%s] ",reason,fname,strerror(errno)) ;
01209 return notes ;
01210 }
01211 }
01212
01213 LOG(TERR,"fname %s, logfile %p, gain_mode %d",fname,log,gain_mode) ;
01214
01215
01216 int s_start, s_stop ;
01217 if(sector) {
01218 s_start = s_stop = sector ;
01219 }
01220 else {
01221 s_start = 1 ;
01222 s_stop = 24 ;
01223 }
01224
01225
01226
01227 for(s=s_start;s<=s_stop;s++) {
01228 for(r=1;r<=6;r++) {
01229 struct fee_found_t *fee_f = get_fee_found(s,r) ;
01230
01231 if(fee_f->got_one == 0) continue ;
01232
01233 if(events != (int)fee_f->got_one) {
01234 LOG(WARN,"Run had sector %d, RB %d: expect %u events, got %u",s,r,events,fee_f->got_one) ;
01235 }
01236 else {
01237 LOG(NOTE,"Run had sector %d, RB %d: expect %u events, got %u",s,r,events,fee_f->got_one) ;
01238 }
01239
01240 for(int i=0;i<36;i++) {
01241 int fee = tpx_rdo_fees(r,i) ;
01242 if(fee == 255) continue ;
01243
01244 for(int fch=0;fch<32;fch++) {
01245
01246 int ch = tpx_old_to_new_ch[fch] ;
01247
01248 if(ch > 15) {
01249 ch -= 16 ;
01250 a = ((fee << 1) | 1) & 0xFF ;
01251 }
01252 else {
01253 a = (fee << 1) & 0xFF ;
01254 }
01255
01256 int err = 0 ;
01257
01258 int seen = fee_f->ch_count[a][ch] ;
01259
01260 int row = tpx_altro_to_pad[r-1][a][ch].row ;
01261 int pad = tpx_altro_to_pad[r-1][a][ch].pad ;
01262
01263
01264 double g = get_gains(s,row,pad)->g ;
01265 double t0 = get_gains(s,row,pad)->t0 ;
01266
01267 struct aux *aux = get_aux(s,row,pad) ;
01268
01269 reason[0] = 0 ;
01270
01271 if(seen != events) {
01272
01273 if(seen == 0) {
01274 err = 3 ;
01275 sprintf(reason+strlen(reason),"[Bad - Missing]") ;
01276 }
01277 else {
01278 if(seen>events) {
01279 err = 3 ;
01280 sprintf(reason+strlen(reason),"[Bad - Flaky readout: seen %d times in %d events]",seen,events) ;
01281 }
01282 }
01283
01284 }
01285
01286
01287 int bad_t0, bad_gain, bad_noise, bad_low ;
01288 bad_t0 = bad_gain = bad_noise = bad_low = 0 ;
01289
01290 if(row != 0) {
01291
01292 if((g<0.9) || (g>1.1)) {
01293 bad_gain = 1 ;
01294
01295
01296
01297 if((pad<=2) || (pad>=(tpc_rowlen[row]-1))) {
01298 if(err<1) err = 1 ;
01299 }
01300 else {
01301 if(err<2) err = 2 ;
01302 }
01303 }
01304
01305 if((t0<-0.30) || (t0>0.30)) {
01306 bad_t0 = 1 ;
01307
01308
01309
01310 if((pad<=2) || (pad>=(tpc_rowlen[row]-1))) {
01311 if(err<1) err = 1 ;
01312 }
01313 else {
01314 if(err<2) err = 2 ;
01315 }
01316 }
01317
01318
01319 if(aux->noise > 10) {
01320 bad_noise = aux->noise ;
01321
01322
01323 if((pad<=2) || (pad>=(tpc_rowlen[row]-1))) {
01324 if(err<1) err = 1 ;
01325 }
01326 else {
01327 if(err<2) err = 2 ;
01328 }
01329 }
01330
01331 if(aux->low_pulse > 1) {
01332 bad_low = aux->low_pulse ;
01333
01334
01335 if((pad<=2) || (pad>=(tpc_rowlen[row]-1))) {
01336 if(err<1) err = 1 ;
01337 }
01338 else {
01339 if(err<2) err = 2 ;
01340 }
01341 }
01342
01343 }
01344
01345
01346
01347
01348 u_char j1 = tpx_altro_to_j1[a&1][ch] ;
01349
01350 if(err > 1) {
01351 if(row && bad_gain) sprintf(reason+strlen(reason),"[Bad gain %.1f]",g) ;
01352 if(row && bad_t0) sprintf(reason+strlen(reason),"[Bad t0 %.1f]",t0) ;
01353 if(row && bad_noise) {
01354 if(gain_mode != GAIN_MODE_CORRECTED) {
01355 sprintf(reason+strlen(reason),"[Bad noise %d%%]",bad_noise) ;
01356 }
01357 else {
01358 sprintf(reason+strlen(reason),"[JUST NOISE %d%%]",bad_noise) ;
01359 }
01360 }
01361 if(row && bad_low) sprintf(reason+strlen(reason),"[Bad low %d%%]",bad_low) ;
01362
01363
01364
01365 notes++ ;
01366 if(log) {
01367 if(gain_mode != GAIN_MODE_CORRECTED) {
01368 fprintf(log,"%2d %d %3d %2d %3d %2d %2d %3d %.3f %6.3f %d %s\n",s,r,fee,j1,a,ch,row,pad,
01369 g,t0,err,reason) ;
01370 }
01371 else if(row && bad_noise) {
01372 fprintf(log,"%2d %d %3d %2d %3d %2d %2d %3d %.3f %6.3f %d %s\n",s,r,fee,j1,a,ch,row,pad,
01373 g,t0,err,reason) ;
01374 }
01375 }
01376 }
01377
01378 if(gain_mode != GAIN_MODE_CORRECTED) {
01379 if((err>1) || bad_gain || bad_t0 || bad_noise || bad_low) {
01380 g = 0.0 ;
01381 get_gains(s,row,pad)->g = 0.0 ;
01382 }
01383
01384 if(ofile) fprintf(ofile,"%2d %d %3d %2d %3d %2d %2d %3d %.3f %6.3f %d %s\n",s,r,fee,j1,a,ch,row,pad,
01385 g,t0,err,reason) ;
01386 }
01387 else {
01388 if(bad_noise) {
01389
01390
01391 g = 0.0 ;
01392 t0 = 0.0 ;
01393 get_gains(s,row,pad)->g = 0.0 ;
01394 get_gains(s,row,pad)->t0 = 0.0 ;
01395
01396 if(ofile) {
01397 fprintf(ofile,"%2d %d %3d %2d %3d %2d %2d %3d %.3f %6.3f %d %s\n",s,r,fee,j1,a,ch,row,pad,
01398 g,t0,err,reason) ;
01399 fprintf(ofile,"%d %d %d 0.000 0.000 # ONLY NOISY\n",s,row,pad) ;
01400 }
01401 }
01402 else {
01403
01404 get_gains(s,row,pad)->g = 1.0 ;
01405 get_gains(s,row,pad)->t0 = -10.0 ;
01406 }
01407
01408 }
01409 fee_f->ch_count[a][ch] *= -1 ;
01410 }
01411 }
01412
01413 for(a=0;a<256;a++) {
01414 for(int ch=0;ch<16;ch++) {
01415 u_char j1 = tpx_altro_to_j1[a&1][ch] ;
01416 if(fee_f->ch_count[a][ch] > 0) {
01417 int fee = tpx_altro_to_fee(r,a) ;
01418 notes++ ;
01419 if(log) {
01420 fprintf(log,"%2d %d %3d %2d %3d %2d %2d %3d %.3f %6.3f %d %s\n",s,r,fee,j1,a,ch,-1,-1,
01421 0.0,0.0,3,"[Bad - Spurious channel]") ;
01422
01423 }
01424 if(ofile) fprintf(ofile,"%2d %d %3d %2d %3d %2d %2d %3d %.3f %6.3f %d %s\n",s,r,fee,j1,a,ch,-1,-1,
01425 0.0,0.0,3,"[Bad - Spurious channel]") ;
01426 }
01427 }
01428 }
01429
01430
01431
01432 }
01433 }
01434
01435 if(ofile && (ofile != stdout)) fclose(ofile) ;
01436
01437 return notes ;
01438 }
01439