11 #include <TPC/rowlen.h>
13 #include <TPX/tpx_altro_to_pad.h>
14 #include <SFS/sfs_index.h>
20 static const u_int MIN_EVENTS = 500 ;
21 #define TPX_PED_FILENAME "/RTScache/pedestals"
29 memset(evts,0,
sizeof(evts)) ;
30 memset(valid_evts,0,
sizeof(valid_evts)) ;
37 memset(ped_rdo_store,0,
sizeof(ped_rdo_store)) ;
55 for(
int r=0;r<6;r++) {
56 if(ped_rdo_store[r].peds) {
57 free(ped_rdo_store[r].peds) ;
58 ped_rdo_store[r].peds = 0 ;
67 void tpxPed::init(
int sec,
int active_rbs)
73 memset(evts,0,
sizeof(evts)) ;
74 memset(valid_evts,0,
sizeof(valid_evts)) ;
76 rb_mask = active_rbs ;
81 for(
int r=0;r<6;r++) {
82 if(rb_mask & (1<<r)) ;
88 tpx36_to_real(sector,r+1,s_real,r_real) ;
90 ped_rdo_store[r].r_real = r_real ;
91 ped_rdo_store[r].s_real = s_real ;
93 ped_rdo_store[r].peds = (
struct peds *) malloc(
sizeof(
struct peds)*1152) ;
94 memset(ped_rdo_store[r].peds,0,
sizeof(
struct peds)*1152) ;
96 memset(ped_rdo_store[r].ix,0xFF,
sizeof(ped_rdo_store[r].ix)) ;
99 for(
int a=0;a<256;a++) {
100 for(
int c=0;c<16;c++) {
103 tpx_from_altro(r_real-1,a,c,row,pad) ;
104 if(row==255) continue ;
107 ped_rdo_store[r].peds[cou].row = row ;
108 ped_rdo_store[r].peds[cou].pad = pad ;
109 ped_rdo_store[r].ix[row][pad] = cou ;
114 LOG(TERR,
"peds_inited: sector %d, RDO real %d: %d",s_real,r_real,cou) ;
123 void tpxPed::accum(
char *evbuff,
int bytes)
131 t = tpx_get_start(evbuff, bytes/4, &rdo, 0) ;
137 a.what = TPX_ALTRO_DO_ADC ;
138 a.rdo = rdo.rdo - 1 ;
140 a.sector = rdo.sector ;
143 r0_logical = tpx36_from_real(sector,rdo.sector,rdo.rdo) - 1 ;
149 if(evts[r0_logical] <= 3) {
150 LOG(NOTE,
"RDO %d: skipping event %d < 3",rdo.rdo,evts[r0_logical]) ;
155 if(
tpx_rdo_dbg[a.sector-1][a.rdo].delta < 200000) {
156 LOG(WARN,
"RDO %d: skipping event %d: delta %u too small",rdo.rdo,evts[r0_logical],
tpx_rdo_dbg[a.sector-1][a.rdo].delta) ;
161 valid_evts[r0_logical]++ ;
163 LOG(NOTE,
"RDO %d: event %d: delta %u OK",rdo.rdo,evts[r0_logical],
tpx_rdo_dbg[a.sector-1][a.rdo].delta) ;
165 data_end = rdo.data_end ;
168 data_end = tpx_scan_to_next(data_end, rdo.data_start, &a) ;
170 }
while(data_end && (data_end > rdo.data_start)) ;
184 r0_logical = tpx36_from_real(sector, a->sector, a->rdo+1) ;
191 LOG(TERR,
"RDO0 %d, RP %d:%d, AID %d:%d",r0_logical,row,pad,a->id,a->ch) ;
194 p =
get(r0_logical,row, pad) ;
197 LOG(ERR,
"ped::accum for row %d, pad %d, A %d:%d bad (real RDO %d)?",row,pad,a->id,a->ch,a->rdo+1) ;
198 LOG(ERR,
"Slog %d:%d, Shw %d:%d",sector,r0_logical+1,a->sector,a->rdo+1) ;
203 if(p->cou[20] > max_events) return ;
206 LOG(DBG,
"count %d",a->count) ;
207 for(i=0;i<a->count;i++) {
213 p->ped[tb] += (double) adc ;
214 p->rms[tb] += (double) (adc*adc) ;
229 LOG(NOTE,
"Calculating pedestals for sector %2d",sector) ;
233 for(rl0=0;rl0<6;rl0++) {
235 for(p=0;p<=182;p++) {
236 struct peds *ped =
get(rl0,r,p) ;
237 if(ped==0) continue ;
240 if(ped->cou[t] == 0) {
241 ped->ped[t] = 1023.0 ;
242 ped->rms[t] = 9.999 ;
247 pp = ped->ped[t] / (double) ped->cou[t] ;
248 rr = ped->rms[t] / (
double) ped->cou[t] ;
251 if(rr < (pp*pp)) rr = 0.0 ;
252 else rr = sqrt(rr - pp*pp) ;
263 if(rb_mask & (1<<r)) {
264 if(valid_evts[r] < MIN_EVENTS) {
266 LOG(ERR,
"RDO %d: not enough valid events (%d < %d) [%d]",r+1,valid_evts[r],MIN_EVENTS,evts[r]) ;
276 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]) ;
279 LOG(ERR,
"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]) ;
286 int tpxPed::to_altro(
char *buff,
int rb,
int timebins)
297 sprintf(fname,
"/RTScache/altro_ped_%d_%03d.txt",rb+1,timebins) ;
299 fff = fopen(fname,
"w") ;
301 LOG(WARN,
"Can't open \"%s\"",fname) ;
307 if(!valid || !smoothed) {
308 LOG(ERR,
"ped::to_altro peds are bad: RDO %d: valid %d, smoothed %d",rb+1,valid,smoothed) ;
313 tpx36_to_real(sector,rb+1,s_real,r_real) ;
315 LOG(TERR,
"Preparing pedestals for Slo%02d:%d (Shw%02d:%d)...",sector,rb+1,s_real,r_real) ;
318 for(ch=0;ch<16;ch++) {
320 tpx_from_altro(r_real-1,a,ch,row,pad) ;
322 if(row > 45) continue ;
326 u_int *addr = (u_int *) rbuff ;
330 u_short *ptr = (u_short *) rbuff ;
336 struct peds *ped =
get(rb,row,pad) ;
338 LOG(ERR,
"RDO %d (real %d): row %d, pad %d",rb+1,r_real,row,pad) ;
342 for(t=0;t<timebins+15;t++) {
343 if(fff) fprintf(fff,
"%d %d %d %d %d %d\n",row,pad,a,ch,t,(u_short)ped->ped[t]) ;
348 for(t=15;t<509;t++) {
349 *ptr++ = (u_short) ped->ped[t] ;
354 *ptr++ = (u_short) ped->ped[t] ;
363 for(t=15;t<timebins+15;t++) {
364 *ptr++ = (u_short) ped->ped[t] ;
365 if((row==42)&&(pad==140)) {
374 for(;t<(TPX_MAX_TB+15);t++) {
375 u_short val = (u_short) 1023 ;
378 if((row==42)&&(pad==140)) {
391 u_short val = (u_short) ped->ped[t] ;
393 if((row==42)&&(pad==140)) {
401 u_short val = (u_short) ped->ped[0] ;
403 if((row==42)&&(pad==140)) {
415 *ptr++ = (u_short) ped->ped[t] ;
440 LOG(WARN,
"tcou %d is odd, adding ped of tb %d?",tcou,t) ;
441 *ptr++ = (u_short) ped->ped[0];
446 for(
int i=0;i<tpx_fee_override_cou;i++) {
447 if(s_real == tpx_fee_override[i].sector) {
448 if(r_real == (tpx_fee_override[i].rdo)) {
450 if(fee == tpx_fee_override[i].orig_altro) {
453 aid = tpx_fee_override[i].curr_altro | 1 ;
457 aid = tpx_fee_override[i].curr_altro ;
460 LOG(NOTE,
"Sector %2d, RDO %d: overriding ALTRO from %3d to %3d",sector,rb+1,a,aid) ;
466 *addr = (aid << 24) | (ch << 16) | tcou ;
474 if(fff) fclose(fff) ;
476 LOG(NOTE,
"Pedestals prepared for RDO %d, bytes %d",rb+1,rbuff-buff) ;
477 return rbuff - buff ;
480 int tpxPed::to_evb(
char *buff)
487 if(!valid || !smoothed) {
489 LOG(ERR,
"ped::to_evb peds are bad: valid %d, smoothed %d",valid,smoothed) ;
492 LOG(NOTE,
"Preparing pedestals for later EVB...") ;
494 for(
int rl0=0;rl0<4;rl0++) {
498 tpx36_to_real(sector,rl0+1,s_real,r_real) ;
500 sprintf(sname,
"sec%02d/rb%02d/pedrms",s_real,r_real) ;
501 char *save_rbuff = rbuff ;
502 int h_bytes = sfs.putfileheader(save_rbuff,sname,0) ;
506 u_short *addr = (u_short *) rbuff ;
509 for(p=1;p<=tpc_rowlen[r];p++) {
510 struct peds *ped =
get(rl0,r, p) ;
511 if(ped==0) continue ;
513 addr = (u_short *) rbuff ;
514 *(addr+1) = (r<<8) | p ;
516 u_short *ptr = addr + 2;
519 double rms = (ped->rms[t] * 16.0) ;
522 if((u_short)rms > 0x3F) val = 0x3F ;
523 else val = (u_short) rms ;
526 if(ped->ped[t] == 0) {
527 LOG(WARN,
"WTF? ped 0 in rp %d:%d, tb %d",r,p,t) ;
530 *ptr++ = (val << 10) | (u_short)ped->ped[t] ;
534 rbuff = (
char *) ptr ;
537 sfs.putfileheader(save_rbuff,sname,rbuff-save_rbuff-h_bytes) ;
544 LOG(TERR,
"Pedestals prepared for later EVB, sector %2d: %d bytes",sector,rbuff-buff) ;
545 return (rbuff-buff) ;
548 int tpxPed::from_cache(
char *fname, u_int rb_msk)
559 pn =
"/RTScache/pedestals" ;
565 for(
int rdo=1;rdo<=6;rdo++) {
566 if(rb_mask & (1<<(rdo-1))) ;
571 tpx36_to_real(sector,rdo,s_real,r_real) ;
573 sprintf(fn,
"%s_s%02d_r%d.txt",pn,s_real,r_real) ;
577 LOG(ERR,
"ped::from_cache can't open output file \"%s\" [%s]",fn,strerror(errno)) ;
583 LOG(NOTE,
"Loading pedestals from cache \"%s\"...",fn) ;
590 if(fgets(buff,
sizeof(buff),f)==0) continue ;
598 int ret = sscanf(buff,
"%d %d %d %f %f",&r,&p,&t,&pp,&rr) ;
599 if(ret != 5) continue ;
601 struct peds *peds =
get(rdo-1,r,p) ;
614 LOG(TERR,
"Pedestals loaded from cache (last was \"%s\"): sector %2d [0x%02X].",fn,sector,rb_mask) ;
618 LOG(ERR,
"Pedestals failed from cache (last was \"%s\"): sector %2d [0x%02X].",fn,sector,rb_mask) ;
628 int tpxPed::to_cache(
char *fname, u_int run)
637 static float old_sum[46][183] ;
640 if(!valid || smoothed) {
641 LOG(ERR,
"ped::to_cache peds are bad: valid %d, smoothed %d -- not caching",valid,smoothed) ;
646 time_t tm = time(0) ;
647 asc_date = ctime(&tm) ;
653 pn =
"/RTScache/pedestals" ;
658 for(
int rdo=1;rdo<=6;rdo++) {
661 if(rb_mask & (1<<(rdo-1))) ;
665 tpx36_to_real(sector,rdo,s_real,r_real) ;
668 if(valid_evts[rdo-1] < MIN_EVENTS) {
669 LOG(ERR,
"Sector %2d, RDO %d has %d events -- not caching!",sector,rdo,valid_evts[rdo-1]) ;
673 sprintf(fn,
"%s_s%02d_r%d.txt",pn,s_real,r_real) ;
677 memset(old_sum,0,
sizeof(old_sum)) ;
681 LOG(ERR,
"ped::to_cache can't open input file \"%s\" [%s]",fn,strerror(errno)) ;
689 if(fgets(buff,
sizeof(buff),f)==0) continue ;
697 int ret = sscanf(buff,
"%d %d %d %f %f",&r,&p,&t,&fped,&frms) ;
698 if(ret != 5) continue ;
701 old_sum[r][p] += fped ;
706 for(p=1;p<=tpc_rowlen[r];p++) {
707 old_sum[r][p] /= 22.0 ;
717 LOG(ERR,
"ped::to_cache can't open output file \"%s\" [%s]",fn,strerror(errno)) ;
724 sprintf(f_sum_name,
"/RTScache/ped_sum_s%02d_r%d_%u_%d.txt",s_real,r_real,(u_int)time(NULL),clock_source) ;
727 sprintf(f_sum_name,
"/RTScache/ped_sum_s%02d_r%d_%08u_%d.txt",s_real,r_real,run,clock_source) ;
730 f_sum = fopen(f_sum_name,
"w") ;
732 LOG(ERR,
"ped::to_cache can't open trace file \"%s\" [%s]",f_sum_name,strerror(errno)) ;
737 LOG(NOTE,
"Writing pedestals to cache \"%s\"...",fn) ;
740 fprintf(f,
"# Detector %s\n",
"TPX") ;
741 fprintf(f,
"# Run %08u\n",run) ;
742 fprintf(f,
"# Date %s",asc_date) ;
743 fprintf(f,
"# Logical sector %d, logical RDO %d\n",sector,rdo) ;
744 fprintf(f,
"# Hardware sector %d, hardware RDO %d\n",s_real, r_real) ;
751 for(p=1;p<=tpc_rowlen[r];p++) {
752 int t_rdo, t_a, t_ch ;
754 tpx_to_altro(r,p,t_rdo,t_a,t_ch) ;
755 if(t_rdo != r_real) {
760 struct peds *peds =
get(rdo-1,r, p) ;
762 LOG(WARN,
"Shouldnt %d %d %d %d",r_real,t_rdo,r,p) ;
770 sum += peds->ped[t] ;
776 double p_diff = sum - old_sum[r][p] ;
777 if(fabs(p_diff)>1.0) {
778 LOG(WARN,
"RDO %d (S%02d:%d): ped_compare r:p %d:%d = %.1f",rdo,s_real,r_real,r,p,p_diff) ;
782 if(f_sum) fprintf(f_sum,
"%d %d %.5f\n",r,p,sum) ;
787 fprintf(f,
"%d %d %d %.3f %.3f\n",r,p,t,peds->ped[t],peds->rms[t]) ;
793 if(f_sum) fclose(f_sum) ;
796 LOG(TERR,
"Pedestals written to cache \"%s\", for sector %2d...",fn,sector) ;
801 int tpxPed::hlt_debug_setup(
int param)
803 int delta_tb = param % 100 ;
804 int delta_pad = param / 100 ;
807 if(delta_tb < 6) delta_tb = 6 ;
808 if(delta_pad < 3) delta_pad = 3 ;
812 for(
int rl0=0;rl0<4;rl0++) {
814 for(
int r=1;r<=45;r++) {
816 for(
int p=3;p<=(tpc_rowlen[r]-delta_pad-2);p+=delta_pad) {
818 for(
int pd=0;pd<2;pd++) {
819 struct peds *ped =
get(rl0,r,p+pd) ;
820 if(ped==0) continue ;
822 for(
int t=15;t<400;t+=delta_tb) {
827 for(
int td=0;td<5;td++) {
828 double val = ped->ped[t+td] ;
830 if(val < 10.0) val = 0.0 ;
833 ped->ped[t+td] = val ;
841 LOG(TERR,
"param %u: delta pad %d,time %d: %d hits",param,delta_pad,delta_tb,hits/2) ;
849 int tpxPed::special_setup(
int run_type,
int sub_type)
855 case RUN_TYPE_PULSER_A :
856 case RUN_TYPE_PULSER :
857 case RUN_TYPE_PED_A :
858 case RUN_TYPE_PED_B :
861 case RUN_TYPE_HLT_DEBUG :
862 LOG(WARN,
"Special Pedestal setup: %d, %d",run_type, sub_type) ;
863 hlt_debug_setup(sub_type) ;
865 case RUN_TYPE_LASER :
879 LOG(ERR,
"Special Pedestal setup: %d, %d (just a warning)",run_type, sub_type) ;
881 for(
int rl0=0;rl0<4;rl0++) {
883 for(p=0;p<=182;p++) {
884 struct peds *ped =
get(rl0,r,p) ;
885 if(ped==0) continue ;
889 for(t=100;t<(100+sub_type);t++) {
893 case RUN_TYPE_PULSER_A :
895 for(t=100;t<110;t++) ped->ped[t] = 0.0 ;
897 for(t=400;t<415;t++) ped->ped[t] = 0.0 ;
899 case RUN_TYPE_PULSER :
900 for(t=TPX_PULSER_PED_START;t<=TPX_PULSER_PED_STOP;t++) ped->ped[t] = 0.0 ;
902 case RUN_TYPE_HLT_DEBUG :
905 case RUN_TYPE_PED_A :
924 for(t=390;t<512;t++) ped->ped[t] = 20 ;
927 case RUN_TYPE_PED_B :
943 for(t=1;t<512;t++) ped->ped[t] = ped->ped[0] ;
946 case RUN_TYPE_LASER :
947 for(t=368;t<=383;t++) ped->ped[t] = 0.0 ;
951 for(t=0;t<512;t++) ped->ped[t] = 1023.0 ;
952 for(t=p;t<(p+10);t++) ped->ped[t] = 0 ;
967 void tpxPed::smooth(
int mode)
974 if(smoothed || !valid) {
975 LOG(ERR,
"ped::smooth sector %2d invalid: smoothed %d, valid %d",sector,smoothed,valid) ;
979 #define TPX_GG_START 20 // depends on TCD!
980 #define TPX_START_OF_RIPPLE 32 // doesn't depend on TCD
981 #define TPX_START_CORRECTION 34
982 #define TPX_USE_DATA 298
983 #define TPX_GG_DOWN 420
986 LOG(NOTE,
"Smoothing pedestals...") ;
988 for(
int rl0=0;rl0<4;rl0++) {
990 for(p=0;p<=182;p++) {
991 struct peds *ped =
get(rl0,r,p) ;
992 if(ped==0) continue ;
994 double smoother[513] ;
1000 smoother[t] = ped->ped[t] ;
1007 for(t=0;t<TPX_GG_START;t++) {
1008 mean += smoother[t] ;
1011 mean /= (double)cou ;
1013 for(t=0;t<TPX_GG_START;t++) {
1014 smoother[t] = mean ;
1022 for(t=TPX_USE_DATA;t<(TPX_USE_DATA+8);t++) {
1023 mean += smoother[t] ;
1027 mean /= (double) cou ;
1030 for(t=TPX_USE_DATA;t<(TPX_USE_DATA+8);t++) {
1031 ripple[t-TPX_USE_DATA] = smoother[t] - mean ;
1035 smoother[TPX_START_OF_RIPPLE] -= ripple[2] * 0.6 ;
1038 for(t=TPX_START_CORRECTION;t<512;t+=8) {
1039 for(
int i=0;i<8;i++) {
1040 if((t+i)>434)
continue ;
1041 smoother[t+i] -= ripple[i] ;
1047 for(t=0;t<512;t++) {
1048 ped->ped[t] = (double) ((u_short) (smoother[t]+0.5)) ;
1050 if(t>=18 && t<=20) {
1051 ped->ped[t] = 1023.0 ;
1055 if(t>=18 && t<=20) {
1056 ped->ped[t] += 5.0 ;
1057 if(ped->ped[t]>1023.0) ped->ped[t] = 1023.0 ;
1070 LOG(TERR,
"Pedestals smoothed: sector %2d, mode %d",sector,mode) ;
1077 int tpxPed::kill_bad(
int r0_logical,
int row,
int pad)
1081 p =
get(r0_logical,row, pad) ;
1084 for(
int t=0;t<512;t++) {
1085 p->ped[t] = 1023.0 ;