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