00001 #include <stdio.h>
00002 #include <sys/types.h>
00003 #include <math.h>
00004 #include <stdlib.h>
00005 #include <string.h>
00006 #include <errno.h>
00007 #include <time.h>
00008 #include <unistd.h>
00009
00010 #include <rtsLog.h>
00011 #include <daqModes.h>
00012
00013 #include "bsmdPed.h"
00014
00015
00016 bsmdPed::bsmdPed()
00017 {
00018 valid = 0 ;
00019 rb_mask = 0x3F ;
00020
00021 memset(evts,0,sizeof(evts)) ;
00022 memset(valid_evts,0,sizeof(valid_evts)) ;
00023
00024 sizeof_ped = sizeof(struct peds) * 6 ;
00025
00026 ped_store = 0 ;
00027
00028 sector = -1 ;
00029 return ;
00030 }
00031
00032
00033 bsmdPed::~bsmdPed()
00034 {
00035 if(ped_store) free(ped_store) ;
00036
00037 return ;
00038 }
00039
00040
00041 void bsmdPed::init(int active_rbs)
00042 {
00043 valid = 0 ;
00044
00045 memset(evts,0,sizeof(evts)) ;
00046 memset(valid_evts,0,sizeof(valid_evts)) ;
00047
00048 rb_mask = active_rbs ;
00049
00050 if(ped_store == 0) {
00051 ped_store = (struct peds *) malloc(sizeof_ped) ;
00052 }
00053
00054 memset(ped_store,0,sizeof_ped) ;
00055
00056 LOG(TERR,"Pedestals zapped: sector %2d, rb_mask 0x%02X.", sector, rb_mask) ;
00057 }
00058
00059
00060 int bsmdPed::do_zs(char *src, int in_bytes, char *dst, int rdo1)
00061 {
00062 u_short *d_out = (u_short *) dst ;
00063 int fiber ;
00064 u_short cap ;
00065 u_short *d ;
00066 u_int *d32 = (u_int *) src ;
00067
00068 LOG(NOTE,"BSMD ZS: rdo %d: in bytes %d",rdo1,in_bytes) ;
00069
00070 d = (u_short *)(src + 10*4) ;
00071
00072 cap = (u_short) (d32[8] & 0x7F) ;
00073
00074 fiber = (sector-1)*2 + (rdo1 - 1) ;
00075
00076 *d_out++ = 0x0002 ;
00077 u_short *count = d_out++ ;
00078 *d_out++ = d32[8] & 0xFFFF ;
00079 *d_out++ = fiber ;
00080
00081 u_short *tmp = d_out ;
00082
00083 double *ped = (ped_store + rdo1 - 1)->ped[cap] ;
00084 u_short *thr = (ped_store + rdo1 - 1)->thr[cap] ;
00085
00086 for(int ii=0;ii<4800;ii++) {
00087 u_short dta = *d ;
00088 if(dta > *thr) {
00089 *d_out++ = ii ;
00090 *d_out++ = dta - (int)(*ped + 0.5) ;
00091 }
00092 d++ ;
00093 thr++ ;
00094 ped++ ;
00095 }
00096 *count = (d_out - tmp)/2 ;
00097
00098 int out_bytes = (char *)d_out - dst ;
00099
00100 if(out_bytes > in_bytes) {
00101 valid_evts[rdo1-1]++ ;
00102 LOG(NOTE,"BSMD ZS: rdo %d: in bytes %d, out bytes %d",rdo1,in_bytes,out_bytes) ;
00103 }
00104 else {
00105 LOG(NOTE,"BSMD ZS: rdo %d: in bytes %d, out bytes %d",rdo1,in_bytes,out_bytes) ;
00106 }
00107
00108 evts[rdo1-1]++ ;
00109 return out_bytes ;
00110 }
00111
00112
00113
00114
00115
00116
00117 void bsmdPed::accum(char *evbuff, int bytes, int rdo1)
00118 {
00119 int cap ;
00120 u_short *d_in ;
00121 u_int *d32 ;
00122 int rdo = rdo1 - 1 ;
00123
00124 d_in = (u_short *) evbuff ;
00125 d32 = (u_int *) evbuff ;
00126
00127
00128 cap = d32[8] & 0x7F ;
00129
00130
00131 evts[rdo]++ ;
00132
00133
00134
00135 if(evts[rdo] <= 3) {
00136 LOG(NOTE,"RDO %d: skipping event %d < 3",rdo,evts[rdo]) ;
00137 return ;
00138 }
00139
00140
00141
00142 valid_evts[rdo]++ ;
00143
00144 LOG(NOTE,"RDO %d: event %d",rdo,evts[rdo]) ;
00145
00146 struct peds *p = ped_store + rdo ;
00147
00148 if(p->cou[cap] > 0xFFF0) return ;
00149 p->cou[cap]++ ;
00150
00151
00152 d_in = (u_short *)(evbuff + 10*4) ;
00153
00154 for(int j=0;j<4800;j++) {
00155
00156 int adc = d_in[j] ;
00157
00158 p->ped[cap][j] += (double) adc ;
00159 p->rms[cap][j] += (double) (adc*adc) ;
00160
00161 }
00162
00163
00164
00165 return ;
00166
00167 }
00168
00169 void bsmdPed::do_thresh(double thr_sm, double thr_pre)
00170 {
00171 double n_sigma ;
00172
00173 if(!ped_store || !valid) {
00174 LOG(ERR,"bsmd:do_thresh invalid") ;
00175 return ;
00176 }
00177
00178
00179 for(int r=0;r<6;r++) {
00180 if((sector==2) && (r>2)) n_sigma = thr_pre ;
00181 else n_sigma = thr_sm ;
00182
00183 struct peds *p = ped_store + r ;
00184 for(int c=0;c<128;c++) {
00185 for(int t=0;t<4800;t++) {
00186 p->thr[c][t] = (u_short) (p->ped[c][t] + p->rms[c][t] * n_sigma + 0.5) ;
00187 }
00188 }
00189 }
00190
00191 return ;
00192
00193 }
00194
00195 void bsmdPed::calc()
00196 {
00197 int r, cap, ch ;
00198 int bad ;
00199 const u_int MIN_EVENTS = 20 ;
00200
00201
00202 LOG(NOTE,"Calculating pedestals for sector %2d",sector) ;
00203
00204
00205 for(r=0;r<6;r++) {
00206 if(rb_mask & (1<<r)) ;
00207 else continue ;
00208
00209 struct peds *ped = ped_store + r ;
00210
00211 for(cap=0;cap<128;cap++) {
00212 for(ch=0;ch<4800;ch++) {
00213
00214 if(ped->cou[cap] == 0) {
00215 ped->ped[cap][ch] = 0xFFFF ;
00216 ped->rms[cap][ch] = 9.999 ;
00217 }
00218 else {
00219 double pp, rr ;
00220
00221 pp = ped->ped[cap][ch] / (double) ped->cou[cap] ;
00222 rr = ped->rms[cap][ch] / (double) ped->cou[cap] ;
00223
00224
00225 if(rr < (pp*pp)) rr = 0.0 ;
00226 else rr = sqrt(rr - pp*pp) ;
00227
00228 ped->ped[cap][ch] = pp ;
00229 ped->rms[cap][ch] = rr ;
00230 }
00231 }
00232 }
00233 }
00234
00235
00236 bad = 0 ;
00237 int real_bad = 0 ;
00238
00239 for(r=0;r<6;r++) {
00240 if(rb_mask & (1<<r)) ;
00241 else continue ;
00242
00243 struct peds *ped = ped_store + r ;
00244
00245 for(cap=0;cap<128;cap++) {
00246 if(ped->cou[cap] < MIN_EVENTS) {
00247 bad++ ;
00248
00249 if(bad<50) {
00250 LOG(WARN,"RDO %d: cap %3d: only %d events!",r+1,cap,ped->cou[cap]) ;
00251 }
00252 else if(bad==50) {
00253 LOG(WARN,"Stopping detailed bad cap logging...") ;
00254 }
00255
00256 if(ped->cou[cap] == 0) real_bad++ ;
00257 }
00258
00259 }
00260 }
00261
00262 LOG(TERR,"Pedestals calculated. RDO counts: %u %u %u %u %u %u",valid_evts[0],valid_evts[1],valid_evts[2],valid_evts[3],valid_evts[4],valid_evts[5]) ;
00263
00264 valid = ! bad ;
00265
00266 if(valid) {
00267
00268 }
00269 else {
00270 LOG(ERR,"BSMD pedestals not good (%d caps not good, %d missing)",bad,real_bad) ;
00271 if(!real_bad) {
00272 LOG(WARN,"But since no real bad I will allow it!") ;
00273 valid = 1 ;
00274 }
00275 }
00276
00277 return ;
00278 }
00279
00280
00281 int bsmdPed::to_evb(char *buff)
00282 {
00283 int r, p, t ;
00284 int fiber ;
00285
00286 u_short *dta = (u_short *) buff ;
00287
00288
00289
00290 if(!valid) {
00291
00292 LOG(WARN,"ped::to_evb peds are bad: valid %d",valid) ;
00293 }
00294
00295 LOG(NOTE,"Preparing pedestals for later EVB...") ;
00296
00297 for(r=0;r<6;r++) {
00298 struct peds *ped = ped_store + r ;
00299
00300 fiber = (sector-1)*6 + r ;
00301
00302 *dta++ = 0x0002 ;
00303 *dta++ = 4800 ;
00304 *dta++ = 128 ;
00305 *dta++ = fiber ;
00306
00307 for(p=0;p<128;p++) {
00308 for(t=0;t<4800;t++) {
00309
00310 u_int rr, pp ;
00311
00312 rr = (u_int)(ped->rms[p][t] * 8.0 + 0.5) ;
00313 if(rr > 0x3F) rr = 0x3F ;
00314
00315
00316 pp = (u_int)(ped->ped[p][t] + 0.5) ;
00317 if(pp > 0x3FF) pp = 0x3FF ;
00318
00319 *dta++ = (rr<<10)|pp ;
00320
00321 }
00322
00323 }
00324
00325 }
00326
00327 LOG(TERR,"Pedestals prepared for later EVB, sector %2d: %d bytes",sector,(char *)dta-buff) ;
00328 return ((char *)dta-buff) ;
00329 }
00330
00331 int bsmdPed::from_cache(char *fname)
00332 {
00333 FILE *f ;
00334 char *fn ;
00335
00336 init(0x3F) ;
00337
00338
00339 if(fname) {
00340 fn = fname ;
00341 f = fopen(fname,"r") ;
00342 }
00343 else {
00344 fn = "/RTScache/pedestals.txt" ;
00345 f = fopen(fn,"r") ;
00346 }
00347
00348 if(f==0) {
00349 LOG(ERR,"ped::from_cache can't open input file \"%s\" [%s]",fn,strerror(errno)) ;
00350 return -1 ;
00351 }
00352
00353
00354 LOG(NOTE,"Loading pedestals from cache \"%s\"...",fn) ;
00355
00356 while(!feof(f)) {
00357 int r, p , t ;
00358 float pp, rr ;
00359
00360 int ret = fscanf(f,"%d %d %d %f %f",&r,&p,&t,&pp,&rr) ;
00361 if(ret != 5) continue ;
00362
00363 struct peds *peds = ped_store + (r-1) ;
00364
00365 peds->ped[p][t] = pp ;
00366 peds->rms[p][t] = rr ;
00367 }
00368
00369 fclose(f) ;
00370 LOG(TERR,"Pedestals loaded from cache \"%s\": sector %2d.",fn,sector) ;
00371
00372
00373 valid = 1 ;
00374
00375 return valid ;
00376 }
00377
00378 int bsmdPed::to_cache(char *fname, u_int run)
00379 {
00380 FILE *f ;
00381 int r, p, t ;
00382 char *fn ;
00383
00384
00385 if(!valid) {
00386 LOG(ERR,"ped::to_cache peds are bad: valid %d -- not caching",valid) ;
00387 return -1 ;
00388 }
00389
00390 if(fname) {
00391 fn = fname ;
00392 }
00393 else {
00394 fn = "/RTScache/pedestals.txt" ;
00395 }
00396
00397
00398 f = fopen(fn,"w") ;
00399 if(f==0) {
00400 LOG(ERR,"ped::to_cache can't open output file \"%s\" [%s]",fn,strerror(errno)) ;
00401 return -1 ;
00402 }
00403
00404
00405 LOG(NOTE,"Writing pedestals to cache \"%s\"...",fn) ;
00406
00407 for(r=0;r<6;r++) {
00408 struct peds *peds = ped_store + r ;
00409
00410 for(p=0;p<128;p++) {
00411 for(t=0;t<4800;t++) {
00412 fprintf(f,"%d %d %d %8.3f %.3f\n",r+1,p,t,peds->ped[p][t],peds->rms[p][t]) ;
00413 }
00414 }
00415 }
00416
00417 fclose(f) ;
00418
00419 LOG(TERR,"Pedestals written to cache \"%s\", for sector %2d...",fn,sector) ;
00420
00421 return 1 ;
00422 }
00423
00424 int bsmdPed::special_setup(int run_type, int sub_type)
00425 {
00426 int r, p, t ;
00427 int m ;
00428
00429 switch(run_type) {
00430 case RUN_TYPE_PULSER_A :
00431 case RUN_TYPE_PED_A :
00432 case RUN_TYPE_PED_B :
00433 LOG(WARN,"Special Pedestal setup: %d, %d",run_type, sub_type) ;
00434 break ;
00435 default :
00436 return 1 ;
00437 }
00438
00439 for(r=0;r<6;r++) {
00440 struct peds *ped = ped_store + r ;
00441 for(p=0;p<128;p++) {
00442
00443 switch(run_type) {
00444 case RUN_TYPE_PULSER_A :
00445 for(t=100;t<110;t++) ped->ped[p][t] = 0.0 ;
00446 for(t=400;t<415;t++) ped->ped[p][t] = 0.0 ;
00447 break ;
00448 case RUN_TYPE_PED_A :
00449 m = 0 ;
00450 for(t=0;t<512;) {
00451 for(int i=0;i<16;i++) {
00452 ped->ped[p][t+i] = m * 1023.0 ;
00453 }
00454 if(m==0) m = 1 ;
00455 else m = 0 ;
00456 t += 16 ;
00457 }
00458 break ;
00459 case RUN_TYPE_PED_B :
00460 m = 1 ;
00461 for(t=0;t<512;) {
00462 for(int i=0;i<16;i++) {
00463 ped->ped[p][t+i] = m * 1023.0 ;
00464 }
00465 if(m==0) m = 1 ;
00466 else m = 0 ;
00467 t += 16 ;
00468 }
00469 break ;
00470 default :
00471 for(t=0;t<512;t++) ped->ped[p][t] = 1023.0 ;
00472 for(t=p;t<(p+10);t++) ped->ped[p][t] = 0 ;
00473 break ;
00474 }
00475 }
00476
00477 }
00478
00479
00480 valid = 1 ;
00481
00482 return 1 ;
00483 }
00484
00485
00486