00001 #include <math.h>
00002 #include <string.h>
00003 #include <stdio.h>
00004
00005 #include <rtsLog.h>
00006 #include <daqModes.h>
00007
00008 #include <TPX/tpx_altro_to_pad.h>
00009
00010 #include "tpxCore.h"
00011 #include "tpxStat.h"
00012
00013
00014
00015 #define TLOG()
00016
00017
00018 #define QA_TB_START 147
00019 #define QA_TB_STOP 153
00020
00021 #define QA_CHARGE 640.0
00022
00023 static const int fee_check[] = {
00024
00025
00026
00027
00028
00029 107,
00030 108,
00031 109,
00032 110,
00033 111,
00034 114,
00035 115,
00036 116,
00037 117,
00038 118,
00039
00040
00041
00042
00043 } ;
00044
00045 static const int fee_check_count = sizeof(fee_check)/sizeof(fee_check[0]) ;
00046
00047 static FILE *stripes_f ;
00048
00049 void tpxStat::run_start(u_int rb_mask, int r_type)
00050 {
00051
00052 run_type = r_type ;
00053
00054 memset(r,0,sizeof(r)) ;
00055
00056 stripes = 0 ;
00057
00058 stripes_f = 0 ;
00059 if(run_type != RUN_TYPE_PED) {
00060
00061 }
00062
00063 if((run_type == RUN_TYPE_DAQCHECK) && (rb_mask==4)) {
00064 fee_check_on = 1 ;
00065 memset(fee_check_altros,0,sizeof(fee_check_altros)) ;
00066 memset(fee_check_data,0,sizeof(fee_check_data)) ;
00067 }
00068 else fee_check_on = 0 ;
00069
00070 for(int i=0;i<6;i++) {
00071 if(rb_mask & (1<<i)) {
00072 int a, c ;
00073
00074
00075 r[i].should = 1 ;
00076
00077 if(fee_check_on) {
00078
00079 for(int j=0;j<fee_check_count;j++) {
00080
00081 a = (fee_check[j]<<1) & 0xFF ;
00082
00083 fee_check_altros[a] = 1 ;
00084 fee_check_altros[a|1] = 1 ;
00085
00086 r[i].a[a].should = 1;
00087 r[i].a[a|1].should = 1 ;
00088
00089 for(c=0;c<16;c++) {
00090 r[i].a[a].c[c].min_adc = 0xFFFF ;
00091 r[i].a[a|1].c[c].min_adc = 0xFFFF ;
00092
00093 fee_check_data[j*2][c].aid = a ;
00094 fee_check_data[j*2+1][c].aid = a|1 ;
00095 }
00096
00097 }
00098 }
00099 else {
00100
00101 for(a=0;a<256;a++) {
00102 for(c=0;c<16;c++) {
00103 int row, pad ;
00104
00105 tpx_from_altro(i,a,c,row,pad) ;
00106
00107 if(row <= 45) {
00108 r[i].a[a].should = 1 ;
00109
00110
00111 }
00112 r[i].a[a].c[c].min_adc = 0xFFFF ;
00113 }
00114 }
00115
00116 }
00117 }
00118 }
00119
00120 return ;
00121 }
00122
00123 int tpxStat::run_stop(FILE *ofile, u_int rb_mask, int run_type, char *fname)
00124 {
00125
00126 int should ;
00127 int err = 0 ;
00128 int str_cou = 0 ;
00129
00130 if(ofile==0) return 0 ;
00131
00132 if(stripes_f) fclose(stripes_f) ;
00133 stripes_f = 0 ;
00134
00135 if(stripes && (run_type != RUN_TYPE_PED)) {
00136 LOG(NOTE,"saw %d occurences of more than 400 timebins",stripes) ;
00137 for(int i=0;i<6;i++) {
00138 for(int a=0;a<256;a++) {
00139 for(int c=0;c<16;c++) {
00140 if(r[i].a[a].c[c].stripes) {
00141 int row, pad ;
00142
00143 str_cou++ ;
00144
00145 if(str_cou > 4) continue ;
00146
00147 tpx_from_altro(i,a,c,row,pad) ;
00148 LOG(WARN,"Stripes %d/%d: RDO %d: AID %3d:%02d, r:p %2d:%03d",
00149 r[i].a[a].c[c].stripes,r[i].a[a].c[c].count,i+1,a,c,row,pad) ;
00150
00151 if(str_cou == 4) {
00152 LOG(WARN,"Stripes logging stopped, stripes %d",stripes) ;
00153 }
00154 }
00155 }
00156 }
00157 }
00158 }
00159
00160 for(int i=0;i<6;i++) {
00161 int a, c ;
00162
00163 if(rb_mask & (1<<i)) should = 1 ;
00164 else should = 0 ;
00165
00166
00167 if(r[i].errs) {
00168 LOG(WARN,"[RDO %d] had %d ALTRO errors",i+1,r[i].errs) ;
00169 }
00170
00171 if(r[i].should != should) {
00172 err++ ;
00173 fprintf(ofile,"%sERROR: [RDO %d] in_RC %d, in_data %d -- MISMATCH\n%s",ANSI_RED,i+1,should,r[i].should,ANSI_RESET) ;
00174 LOG(ERR,"[RDO %d] in_RC %d, in_data %d -- MISMATCH",i+1,should,r[i].should) ;
00175 }
00176
00177
00178 if(r[i].count==0) {
00179 if(r[i].should) {
00180 err++ ;
00181 fprintf(ofile,"%sERROR: [RDO %d] expect data, found none!\n%s",ANSI_RED,i+1,ANSI_RESET) ;
00182 LOG(WARN,"[RDO %d] expect data, found none!",i+1) ;
00183 }
00184 continue ;
00185 }
00186 else {
00187 if(!r[i].should) {
00188 err++ ;
00189 fprintf(ofile,"%sERROR: [RDO %d] expect none, found events %u\n%s",ANSI_RED,i+1,r[i].count,ANSI_RESET) ;
00190 LOG(ERR,"[RDO %d] expect none, found events %u",i+1,r[i].count) ;
00191 }
00192 else {
00193
00194 }
00195 }
00196
00197
00198 for(a=0;a<256;a++) {
00199 int a_err = 0 ;
00200 for(c=0;c<16;c++) {
00201 u_int have, expect ;
00202
00203 int warn = 0 ;
00204 int p_err = 0 ;
00205
00206 have = r[i].a[a].c[c].count ;
00207 if(r[i].a[a].should) {
00208 expect = r[i].count ;
00209 }
00210 else {
00211 expect = 0 ;
00212 }
00213
00214 int row ;
00215 int pad ;
00216
00217 tpx_from_altro(i,a,c,row,pad) ;
00218
00219 for(int j=0;j<tpx_odd_fee_count;j++) {
00220
00221 if((tpx_odd_fee[j].sector != sector) || (tpx_odd_fee[j].rdo != (i+1))) continue ;
00222
00223 for(int k=0;k<2;k++) {
00224 int aid = tpx_odd_fee[j].altro_id_padplane ;
00225
00226 if(a == (aid+k)) {
00227 expect = 0 ;
00228 if(c==0) {
00229 LOG(WARN,"[RDO %d] altro %3d was marked odd in the gain file...",i+1,a) ;
00230 }
00231 }
00232 }
00233 }
00234
00235 if(have != expect) {
00236 warn = 1 ;
00237 a_err = 1 ;
00238 p_err = 1 ;
00239
00240 LOG(WARN,"[RDO %d] AID %3d:%2d (r:p %d:%d): expect %d counts, have %d",i+1,a,c,
00241 row,pad,
00242 expect,have) ;
00243 }
00244
00245
00246 if(have && expect) {
00247 int ped_warn = 0 ;
00248 if(run_type == RUN_TYPE_PED) {
00249 if(r[i].a[a].c[c].min_adc < 10) ped_warn = 1 ;
00250 if(r[i].a[a].c[c].max_adc > 200) ped_warn = 1 ;
00251 }
00252
00253 if(ped_warn) {
00254 LOG(WARN,"[RDO %d] AID %3d:%2d (r:p %d:%d) pedestal: min adc %3d, max adx %4d",
00255 i+1,a,c,row,pad,
00256 r[i].a[a].c[c].min_adc,
00257 r[i].a[a].c[c].max_adc) ;
00258 warn = 1 ;
00259 }
00260
00261
00262 }
00263
00264
00265 if(warn) {
00266 if(p_err) fprintf(ofile,"\t%sERROR: ",ANSI_RED) ;
00267 else fprintf(ofile,"\t%sWARN: ",ANSI_CYAN) ;
00268
00269 err++ ;
00270 fprintf(ofile,"AID %3d:%2d: expect %d counts, have %d; min %4u, max %4u\n%s",a,c,expect,have,
00271 r[i].a[a].c[c].min_adc,
00272 r[i].a[a].c[c].max_adc,ANSI_RESET) ;
00273 }
00274
00275 }
00276 if(r[i].a[a].should && (a_err==0)) {
00277 #ifdef TEST_RDO
00278 fprintf(ofile,"\tAID %3d OK...\n",a) ;
00279 #endif
00280 }
00281 }
00282
00283 }
00284
00285 fflush(ofile) ;
00286
00287 if(fee_check_on) {
00288 FILE *f = fopen(fname,"w") ;
00289
00290 for(int i=0;i<fee_check_count;i++) {
00291 int fee = fee_check[i] ;
00292
00293 for(int j=0;j<2;j++) {
00294 int ix = 2*i + j ;
00295
00296
00297 for(int ch=0;ch<16;ch++) {
00298 int err ;
00299 char errstr[1024] ;
00300 errstr[0] = 0 ;
00301 err = 0 ;
00302
00303 double cou = fee_check_data[ix][ch].count ;
00304 int aid = fee_check_data[ix][ch].aid ;
00305 int row, pad ;
00306
00307 u_char j1 ;
00308
00309 tpx_from_altro(2,aid,ch,row,pad) ;
00310
00311 j1 = tpx_altro_to_j1[aid&1][ch] ;
00312
00313 if(cou == 0.0) {
00314 LOG(DBG," ALTRO %3d:%02d: %4d counts",aid,ch,(int)fee_check_data[ix][ch].count) ;
00315 fprintf(f,"%2d %d %3d %2d %3d %2d %2d %3d %.3f %6.3f %d %s\n",24,3,fee,j1,aid,ch,row,pad,
00316 0.0,0.0,3,"No data") ;
00317
00318 continue ;
00319 }
00320
00321 fee_check_data[ix][ch].ped /= cou ;
00322 fee_check_data[ix][ch].rms /= cou ;
00323 fee_check_data[ix][ch].charge /= cou ;
00324 fee_check_data[ix][ch].t0 /= cou ;
00325
00326 fee_check_data[ix][ch].ped_sigma /= cou ;
00327 fee_check_data[ix][ch].rms_sigma /= cou ;
00328 fee_check_data[ix][ch].charge_sigma /= cou ;
00329 fee_check_data[ix][ch].t0_sigma /= cou ;
00330
00331 fee_check_data[ix][ch].ped_sigma = sqrt(fee_check_data[ix][ch].ped_sigma - fee_check_data[ix][ch].ped*fee_check_data[ix][ch].ped) ;
00332 fee_check_data[ix][ch].rms_sigma = sqrt(fee_check_data[ix][ch].rms_sigma - fee_check_data[ix][ch].rms*fee_check_data[ix][ch].rms) ;
00333 fee_check_data[ix][ch].charge_sigma = sqrt(fee_check_data[ix][ch].charge_sigma - fee_check_data[ix][ch].charge*fee_check_data[ix][ch].charge) ;
00334 fee_check_data[ix][ch].t0_sigma = sqrt(fee_check_data[ix][ch].t0_sigma - fee_check_data[ix][ch].t0*fee_check_data[ix][ch].t0) ;
00335
00336
00337 LOG(TERR," A %3d:%02d: %4d cou: ped %.2f +- %.2f, rms %.2f +- %.2f, cha %.2f +- %.2f, t0 %.2f +- %.2f",aid,ch,(int)cou,
00338 fee_check_data[ix][ch].ped, fee_check_data[ix][ch].ped_sigma,
00339 fee_check_data[ix][ch].rms, fee_check_data[ix][ch].rms_sigma,
00340 fee_check_data[ix][ch].charge, fee_check_data[ix][ch].charge_sigma,
00341 fee_check_data[ix][ch].t0, fee_check_data[ix][ch].t0_sigma) ;
00342
00343 double gain = fee_check_data[ix][ch].charge / QA_CHARGE ;
00344 if((gain<0.9) || (gain>1.1)) {
00345 strcat(errstr,"Bad gain,") ;
00346 err = 1 ;
00347 }
00348
00349 double tmp = fee_check_data[ix][ch].ped ;
00350 if((tmp > 100.0) || (tmp<5.0)) {
00351 strcat(errstr,"Bad pedestal,") ;
00352 err = 2 ;
00353 }
00354
00355 tmp = fee_check_data[ix][ch].rms ;
00356 if((tmp < 0.4) || (tmp>1.2)) {
00357 strcat(errstr,"Noisy,") ;
00358 err = 2 ;
00359 }
00360
00361 if(r[2].count != cou) {
00362 strcat(errstr,"Flaky readout,") ;
00363 err = 3 ;
00364 }
00365
00366 fprintf(f,"%2d %d %3d %2d %3d %2d %2d %3d %.3f %6.3f %d %s\n",24,3,fee,j1,aid,ch,row,pad,
00367 gain,
00368 fee_check_data[ix][ch].t0,
00369 err,errstr) ;
00370
00371
00372 }
00373 }
00374 }
00375
00376 fclose(f) ;
00377 }
00378
00379 return err ;
00380 }
00381
00382 void tpxStat::accum(char *rdobuff, int bytes)
00383 {
00384 int t ;
00385 u_int *data_end ;
00386 tpx_rdo_event rdo ;
00387 tpx_altro_struct a ;
00388 int errors = 0 ;
00389 const u_int MAX_ERRORS = 10 ;
00390
00391 TLOG() ;
00392 t = tpx_get_start(rdobuff, bytes/4, &rdo, 0) ;
00393
00394 if(t <= 0) return ;
00395
00396
00397 if(sector && (rdo.sector != sector)) {
00398 LOG(ERR,"sector mismatch: expect %d, in data %d",sector,rdo.sector) ;
00399 return ;
00400 }
00401
00402
00403
00404 if(rdo.rdo > 6) {
00405 LOG(ERR,"rdo error: %d",rdo.rdo) ;
00406 return ;
00407 }
00408
00409 a.what = TPX_ALTRO_DO_ADC ;
00410 a.rdo = rdo.rdo - 1 ;
00411 a.t = t ;
00412 a.sector = rdo.sector ;
00413 a.ch = 0 ;
00414
00415
00416 if(r[a.rdo].errs >= MAX_ERRORS) {
00417 a.log_err = 0 ;
00418 }
00419 else {
00420 a.log_err = 1 ;
00421 }
00422
00423 r[a.rdo].count++ ;
00424
00425 data_end = rdo.data_end ;
00426
00427 TLOG() ;
00428
00429 do {
00430 TLOG() ;
00431 data_end = tpx_scan_to_next(data_end, rdo.data_start, &a) ;
00432 TLOG() ;
00433 if(a.err || (data_end==0)) {
00434
00435 errors = 1 ;
00436 }
00437 else {
00438 TLOG() ;
00439 if((a.rdo >= 6) || (a.ch >= 16)) {
00440 LOG(ERR,"What !? %d %d",a.rdo,a.ch) ;
00441 }
00442 TLOG() ;
00443 if(a.count >= 400) {
00444 TLOG() ;
00445 stripes++ ;
00446 TLOG() ;
00447 r[a.rdo].a[a.id].c[a.ch].stripes++ ;
00448 if((stripes % 100)==0) {
00449 LOG(NOTE,"A lot of stripes: %d",stripes) ;
00450 }
00451
00452 TLOG() ;
00453 if(stripes_f) {
00454 fprintf(stripes_f,"==> RDO %d, cou %d: %d %d\n",a.rdo,r[a.rdo].count,a.row,a.pad) ;
00455 for(int i=0;i<a.count;i++) {
00456 fprintf(stripes_f,"%d %d\n",a.tb[i],a.adc[i]) ;
00457 }
00458 }
00459
00460 }
00461 TLOG() ;
00462 }
00463
00464
00465
00466 if((data_end==0) || (a.ch>15) || (a.rdo >= 6)) {
00467 LOG(ERR,"Bad boy: rdo %d, AID %d:%d -- %p",a.rdo,a.id,a.ch,data_end) ;
00468 continue ;
00469 }
00470
00471 r[a.rdo].a[a.id].c[a.ch].count++ ;
00472
00473 TLOG() ;
00474 if(run_type == RUN_TYPE_PED) {
00475 for(int i=0;i<a.count;i++) {
00476 if(a.adc[i] > r[a.rdo].a[a.id].c[a.ch].max_adc) {
00477 r[a.rdo].a[a.id].c[a.ch].max_adc = a.adc[i] ;
00478 }
00479 if(a.adc[i] < r[a.rdo].a[a.id].c[a.ch].min_adc) {
00480 r[a.rdo].a[a.id].c[a.ch].min_adc = a.adc[i] ;
00481 }
00482
00483 }
00484 }
00485
00486 if(fee_check_on) {
00487
00488 int a_ok = -1 ;
00489 for(int i=0;i<fee_check_count*2;i++) {
00490 int a0 ;
00491 a0 = fee_check_data[i][0].aid ;
00492 if(a.id==a0) {
00493 a_ok = i ;
00494 break ;
00495 }
00496 }
00497
00498 if(a_ok <0) {
00499 LOG(WARN,"RDO %d: spurious ALTRO %3d",rdo.rdo,a.id) ;
00500 continue ;
00501 }
00502
00503 fee_check_data[a_ok][a.ch].count++ ;
00504
00505 double ped, rms, cou ;
00506 ped = rms = cou = 0.0 ;
00507 for(int i=0;i<a.count;i++) {
00508 if(a.tb[i] < 100) {
00509 ped += a.adc[i] ;
00510 rms += a.adc[i] * a.adc[i];
00511 cou++ ;
00512 }
00513 }
00514
00515 if(cou == 0.0) cou = 1.0 ;
00516
00517 ped /= cou ;
00518 rms /= cou ;
00519 rms = sqrt(rms - ped*ped) ;
00520
00521 fee_check_data[a_ok][a.ch].ped += ped ;
00522 fee_check_data[a_ok][a.ch].ped_sigma += ped*ped ;
00523
00524 fee_check_data[a_ok][a.ch].rms += rms ;
00525 fee_check_data[a_ok][a.ch].rms_sigma += rms*rms ;
00526
00527 double d_sum, d_t0 ;
00528 d_sum = d_t0 = 0.0 ;
00529 for(int i=0;i<a.count;i++) {
00530 if((a.tb[i] >= QA_TB_START) && (a.tb[i] <= QA_TB_STOP)) {
00531 double d = a.adc[i] - ped ;
00532
00533 d_sum += d ;
00534 d_t0 += d*a.tb[i] ;
00535 }
00536 }
00537
00538 fee_check_data[a_ok][a.ch].charge += d_sum ;
00539 fee_check_data[a_ok][a.ch].charge_sigma += d_sum*d_sum ;
00540
00541 if(d_sum == 0.0) d_t0 = 100.0 ;
00542 else d_t0 /= d_sum ;
00543
00544 fee_check_data[a_ok][a.ch].t0 += d_t0 ;
00545 fee_check_data[a_ok][a.ch].t0_sigma += d_t0*d_t0 ;
00546
00547
00548
00549
00550 }
00551
00552 if(data_end == rdo.data_start) {
00553 LOG(WARN,"Data end == data start...") ;
00554 }
00555
00556 } while(data_end && (data_end > rdo.data_start)) ;
00557
00558 TLOG() ;
00559
00560 if(errors) {
00561 r[a.rdo].errs++ ;
00562 if(r[a.rdo].errs == MAX_ERRORS) {
00563 LOG(WARN,"RDO %d has %d errors -- stopping logging",a.rdo+1,r[a.rdo].errs) ;
00564 }
00565 } ;
00566
00567 return ;
00568
00569 }