00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <arpa/inet.h>
00004
00005 #include <daqFormats.h>
00006 #include <rtsSystems.h>
00007 #include <rtsLog.h>
00008 #include <rts.h>
00009
00010 #include <DAQ_READER/daq_det.h>
00011
00012
00013 #include <SVT/key_map.h>
00014
00015
00016
00017
00018
00019
00020
00021 #include "daq_svt.h"
00022
00023
00024
00025 static int unpackRaw(int sec, int what, struct SVTANODK *padk, struct TPCCPPR_l *cppr, char *mem, svt_t *svt) ;
00026
00027
00028
00029
00030
00031
00032 int svt_reader(char *m, struct svt_t *svt, u_int driver)
00033 {
00034 int sec, i ;
00035 int rb, mz ;
00036 int len ;
00037 u_int off ;
00038 static int first = 1 ;
00039
00040 struct DATAP *datap ;
00041 struct TPCP *svtp ;
00042 struct TPCSECP *secp ;
00043 struct TPCRBP *rbp ;
00044 struct TPCMZP *mzp ;
00045 struct TPCSEQD *seqd ;
00046 struct TPCADCD *adcd ;
00047 struct SVTANODK *padk ;
00048 struct TPCADCR_l *adcr ;
00049 struct TPCCPPR_l *cppr ;
00050 struct TPCPEDR *pedr ;
00051 struct TPCRMSR *rmsr ;
00052
00053
00054 svt->channels = 0 ;
00055
00056
00057 svt->mode = 0 ;
00058
00059
00060 if(m==NULL) return 0 ;
00061
00062 datap = (struct DATAP *) m ;
00063
00064 len = ntohl(datap->det[SVT_ID].len) ;
00065 if(len == 0) return 0 ;
00066 len *= 4 ;
00067
00068 off = ntohl(datap->det[SVT_ID].off) ;
00069 if(off == 0) return 0 ;
00070
00071 svtp = (struct TPCP *)((u_int *)m+off) ;
00072 if(checkBank((char *)svtp,"SVTP") < 0) return -1 ;
00073
00074
00075
00076 {
00077 int j, k ;
00078
00079 svt->max_channels = 24*3*6*240*128 ;
00080
00081
00082 for(i=0;i<24;i++) {
00083 for(j=0;j<3;j++) {
00084 for(k=0;k<6;k++) {
00085 svt->B[i][j][k] = (svt_pad_key[i][j][k] & 0xFF000000) >> 24 ;
00086 svt->L[i][j][k] = (svt_pad_key[i][j][k] & 0x00FF0000) >> 16 ;
00087 svt->W[i][j][k] = (svt_pad_key[i][j][k] & 0x00000F00) >> 8 ;
00088 svt->H[i][j][k] = (svt_pad_key[i][j][k] & 0x0000F000) >> 12 ;
00089 }
00090 }
00091 }
00092
00093 first = 0 ;
00094 }
00095
00096
00097
00098 memset((char *)svt->counts,0,sizeof(svt->counts)) ;
00099
00100 for(sec=0;sec<4;sec++) {
00101 int last ;
00102
00103 if((b2h32(svtp->bh.format_number)==1) && (sec%2)) continue ;
00104
00105 if(svtp->sb[sec].len == 0) continue ;
00106
00107 LOG(DBG,"SVT sector %d: len %d, off %d",sec+1,svtp->sb[sec].len,svtp->sb[sec].off) ;
00108
00109 secp = (struct TPCSECP *) ((char *)svtp + b2h32(svtp->sb[sec].off)*4) ;
00110 if(checkBank((char *)secp,"SVTSECP") < 0) return -1 ;
00111
00112
00113 if(b2h32(svtp->bh.format_number)==1) {
00114 last = 12 ;
00115 }
00116 else {
00117 last = 6 ;
00118 }
00119
00120 for(rb=0;rb<last;rb++) {
00121 int rsec ;
00122 int rrb ;
00123
00124 if(rb >= 6) {
00125 rsec = sec+1 ;
00126 rrb = rsec*6 + (rb - 6) ;
00127 }
00128 else {
00129 rsec = sec ;
00130 rrb = rsec*6 + rb ;
00131 }
00132
00133 if(secp->rb[rb].len == 0) continue ;
00134
00135 rbp = (struct TPCRBP *) ((char *)secp + b2h32(secp->rb[rb].off)*4) ;
00136 if(checkBank((char *)rbp,"SVTRBP") < 0) return -1 ;
00137
00138
00139
00140 for(mz=0;mz<3;mz++) {
00141 if(rbp->mz[mz].len == 0) continue ;
00142
00143 mzp = (struct TPCMZP *)((char *)rbp + l2h32(rbp->mz[mz].off)*4) ;
00144 if(checkBank((char *)mzp,"SVTMZP") < 0) return -1 ;
00145
00146
00147
00148 if((mzp->banks[TPC_ADCD].len != 0) && (svt->mode==0)) {
00149
00150
00151
00152
00153 seqd = (struct TPCSEQD *)((char *)mzp + l2h32(mzp->banks[TPC_SEQD].off)*4) ;
00154 adcd = (struct TPCADCD *)((char *)mzp + l2h32(mzp->banks[TPC_ADCD].off)*4) ;
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 if(checkBank((char *)seqd,"SVTSEQD") < 0) return -1 ;
00178 if(checkBank((char *)adcd,"SVTADCD") < 0) return -1 ;
00179
00180 int len = l2h32(seqd->bh.length) - 10 ;
00181 len *= 2 ;
00182
00183 int adccou = 0 ;
00184 int jj ;
00185
00186
00187
00188 for(jj=0;jj<len;jj++) {
00189 int start, last, length, stop ;
00190 u_short ss, f8 ;
00191 u_int rr, pp, hy ;
00192 int tbin ;
00193 int k ;
00194
00195 ss = l2h16(seqd->seq[jj]) ;
00196 f8 = (ss & 0x8000) ? 1 : 0 ;
00197
00198
00199 if(f8) {
00200 pp = (ss & 0x7FFF) % 256 ;
00201 hy = (ss & 0x7FFF) / 256 ;
00202
00203 last = 0 ;
00204
00205 rr = 0 ;
00206
00207 for(k=0;k<6;k++) {
00208 if((svt_pad_key[rrb][mz][k] & 0x7F) == hy) {
00209 rr = k + 1 ;
00210 break ;
00211 }
00212 }
00213
00214
00215
00216 if(rr == 0) {
00217 if(hy == 0) {
00218 LOG(DBG,"Hybrid 0: 0x%04X, seq %d of %d",
00219 ss,jj,len,0,0) ;
00220 break ;
00221 }
00222 LOG(ERR,"Can't find hybrid 0x%02X in the svt_key for RB %d, MZ %d (seq %d of %d)!",
00223 hy,rrb+1,mz+1,jj,len) ;
00224 break ;
00225 }
00226
00227 LOG(DBG,"Hy %d %d %d 0x%02X %d",rrb+1,mz+1,rr,hy,pp) ;
00228
00229 if(pp == 0xFF) {
00230 LOG(WARN,"Anode is 0xFF!",0,0,0,0,0) ;
00231 continue ;
00232 }
00233
00234 }
00235 else {
00236 last = (ss & 0x0020) ? 1 : 0 ;
00237 length = ss & 0x1F ;
00238 start = (ss & 0x7FC0) >> 6 ;
00239 stop = start + length ;
00240
00241 if(pp == 1) {
00242
00243
00244 }
00245
00246 for(tbin=start;tbin<stop;tbin++) {
00247 u_char val ;
00248 val = adcd->adc[adccou++] ;
00249
00250 int counter = svt->counts[rrb][mz][rr-1][pp-1] ;
00251 svt->adc[rrb][mz][rr-1][pp-1][counter] = val ;
00252 svt->timebin[rrb][mz][rr-1][pp-1][counter] = tbin ;
00253 svt->counts[rrb][mz][rr-1][pp-1] += 1 ;
00254 svt->channels++ ;
00255 }
00256 }
00257
00258 if(last) {
00259 pp++ ;
00260 }
00261 }
00262
00263
00264 continue ;
00265 }
00266
00267 padk = NULL ;
00268 if(mzp->banks[SVT_ANODK].len != 0) {
00269 padk = (struct SVTANODK *)((char *)mzp + l2h32(mzp->banks[SVT_ANODK].off)*4) ;
00270
00271 if(checkBank((char *)padk,"SVTANODK") < 0) return -1 ;
00272 }
00273
00274
00275 cppr = NULL ;
00276 if(mzp->banks[TPC_CPPR].len != 0) {
00277
00278 cppr = (struct TPCCPPR_l *)((char *)mzp + l2h32(mzp->banks[TPC_CPPR].off)*4) ;
00279 if(checkBank((char *)cppr,"SVTCPPR") < 0) return -1 ;
00280 }
00281
00282
00283 if((mzp->banks[TPC_ADCR].len != 0) && (svt->mode==0)) {
00284 adcr = (struct TPCADCR_l *)((char *)mzp + l2h32(mzp->banks[TPC_ADCR].off)*4) ;
00285
00286 if(checkBank((char *)adcr,"SVTADCR") < 0) return -1 ;
00287
00288
00289
00290 if(unpackRaw(rrb*3+mz, 0, padk, cppr, (char *)adcr, svt) < 0) {
00291 LOG(ERR,"Problems in RAW data in sector %d, RB %d, MZ %d - skipping...",
00292 rsec+1,rrb+1,mz+1,0,0) ;
00293 }
00294
00295 LOG(DBG,"SVT Raw data bank in sector %d, RB %d, MZ %d [sec %d, rb %d]!",
00296 rsec+1,rrb+1,mz+1,sec,rb) ;
00297 continue ;
00298 }
00299
00300 if(mzp->banks[TPC_PEDR].len != 0) {
00301 pedr = (struct TPCPEDR *)((char *)mzp + l2h32(mzp->banks[TPC_PEDR].off)*4) ;
00302
00303 if(checkBank((char *)pedr,"SVTPEDR") < 0) return -1 ;
00304
00305 unpackRaw(rrb*3+mz, 1, padk, cppr, (char *)pedr, svt) ;
00306 svt->mode = 1 ;
00307
00308 }
00309
00310 if(mzp->banks[TPC_RMSR].len != 0) {
00311 rmsr = (struct TPCRMSR *)((char *)mzp + l2h32(mzp->banks[TPC_RMSR].off)*4) ;
00312
00313 if(checkBank((char *)rmsr,"SVTRMSR") < 0) return -1 ;
00314
00315 unpackRaw(rrb*3+mz, 2, padk, cppr, (char *)rmsr, svt) ;
00316 svt->mode = 1 ;
00317
00318 }
00319
00320
00321 }
00322
00323 }
00324
00325 }
00326
00327
00328
00329 return len ;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338 static int unpackRaw(int sec, int what, struct SVTANODK *padk, struct TPCCPPR_l *cppr, char *mem, svt_t *svt)
00339 {
00340 int i, j, t ;
00341 u_char pad ;
00342 u_short *cppseq ;
00343 u_char *adcseq ;
00344 u_char *adcdata ;
00345 u_short *cppdata ;
00346 int rb, mz ;
00347 static u_char svtindex[128] ;
00348 int timebins, cpps ;
00349
00350 timebins = 128 ;
00351 cpps = 8 ;
00352
00353 if(padk == NULL) {
00354 LOG(WARN,"No ANODK? - skipping...",0,0,0,0,0) ;
00355 return -1 ;
00356 }
00357 if(mem == NULL) {
00358 LOG(WARN,"No DATA? - skipping...",0,0,0,0,0) ;
00359 return -1 ;
00360 }
00361
00362 adcdata = NULL ;
00363 cppdata = NULL ;
00364
00365
00366 int ver = l2h32((((struct TPCRMSR *)mem)->bh.format_number)) ;
00367
00368 if(ver != 2) {
00369 LOG(WARN,"Can't work with pre-2001 data - sorry (ver %d)",ver,0,0,0,0) ;
00370 return -1 ;
00371 }
00372
00373
00374 svt->pre = l2h32(padk->pre) ;
00375 svt->post = l2h32(padk->post) ;
00376 svt->pedoffset = l2h32(padk->pedOff) ;
00377
00378 LOG(DBG,"SVT: pre %d, post %d, pedOff %d",svt->pre,svt->post,svt->pedoffset) ;
00379
00380
00381
00382
00383
00384
00385 switch(what) {
00386 case 0 :
00387 adcdata = (u_char *) mem + sizeof(struct TPCADCR_l);
00388
00389 if(cppr == NULL) {
00390 LOG(WARN,"No CPPR? - skipping...",0,0,0,0,0) ;
00391 return -1 ;
00392 }
00393
00394 cppdata = (u_short *)((char *)cppr + sizeof(struct TPCCPPR_l)) ;
00395 break ;
00396 case 1 :
00397 adcdata = ((struct TPCPEDR *)mem)->ped ;
00398 break ;
00399 case 2 :
00400 adcdata = ((struct TPCRMSR *)mem)->rms ;
00401 break ;
00402 }
00403
00404
00405 mz = sec % 3 ;
00406 rb = sec / 3 ;
00407
00408
00409 for(i=0;i<6;i++) {
00410
00411 for(pad=0;pad<240;pad++) {
00412
00413
00414
00415 u_int anode_offset = (pad % 0x40) * 128 * 4 + (pad/64) ;
00416
00417 adcseq = (u_char *) adcdata + i*0x8000 + anode_offset ;
00418
00419 switch(what) {
00420 case 0 :
00421 cppseq = (u_short *)((char *) cppdata + 2*2*8*(i*256+pad)) ;
00422
00423
00424 memset(svtindex,0,sizeof(svtindex)) ;
00425
00426 for(j=0;j<cpps;j++) {
00427 u_short start, stop ;
00428 int pre, post ;
00429
00430
00431 start = l2h16(*cppseq++) ;
00432 stop = l2h16(*cppseq++) ;
00433
00434
00435
00436 if(start & 0xFE00) break ;
00437
00438 if(j==7) stop &= 0x7F ;
00439 if(start == 127) stop = 127 ;
00440
00441 if((stop < start) || (stop >= timebins)) {
00442 LOG(WARN,"Bad data stop<start %d<%d, cpp %d - skipping",stop,start,j,0,0) ;
00443 return -1 ;
00444 }
00445
00446 pre = (int)start - svt->pre ;
00447 if(pre < 0) start = 0 ;
00448 else start = pre ;
00449
00450 post = stop + svt->post ;
00451 if(post > 127) stop = 127 ;
00452 else stop = post ;
00453
00454 for(t=start;t<=stop;t++) {
00455 svtindex[t] = 1 ;
00456 }
00457 }
00458
00459 for(t=0;t<128;t++) {
00460 u_char val ;
00461 int counter ;
00462
00463 if(svtindex[t]) {
00464
00465 val = *(adcseq + t*4) ;
00466
00467 if(val == 0) {
00468
00469
00470 }
00471
00472 counter = svt->counts[rb][mz][i][pad] ;
00473 svt->adc[rb][mz][i][pad][counter] = val ;
00474 svt->timebin[rb][mz][i][pad][counter] = t ;
00475 svt->counts[rb][mz][i][pad]++ ;
00476
00477 svt->channels++ ;
00478 }
00479 }
00480
00481 break ;
00482 case 1 :
00483 for(j=0;j<timebins;j++) {
00484 svt->adc[rb][mz][i][pad][j] = *(adcseq + j*4) ;
00485 svt->channels++ ;
00486 }
00487 break ;
00488 case 2 :
00489 for(j=0;j<timebins;j++) {
00490 svt->timebin[rb][mz][i][pad][j] = *(adcseq + j*4) ;
00491 }
00492 break ;
00493 }
00494 }
00495
00496 }
00497
00498
00499 return 0 ;
00500
00501 }