00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <assert.h>
00004 #include <arpa/inet.h>
00005
00006
00007 #include "rtsSystems.h"
00008 #include "daqFormats.h"
00009
00010
00011 #include "evpSupport.h"
00012 #include "emcReader.h"
00013
00014 #include "TString.h"
00015 #include "StMessMgr.h"
00016 #include <algorithm>
00017
00018 using namespace OLDEVP;
00019 namespace OLDEVP {
00020 struct emc_t emc ;
00021 }
00022 #define SWAP32(bk,x) ((bk->bh.byte_order==0x4030201)?(bk->x):swap32(bk->x))
00023
00024
00025
00026 #ifdef __linux__
00027
00028 #include <byteswap.h>
00029
00030 #define swap16(x) bswap_16(x)
00031 #define swap32(x) bswap_32(x)
00032
00033 #else
00034
00035 extern inline unsigned short swap16(unsigned short x)
00036 {
00037 return ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) ;
00038 }
00039
00040 extern inline unsigned int swap32(unsigned int x)
00041 {
00042 return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
00043 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) ;
00044 }
00045
00046 #endif
00047
00048 #define qswap16(test,x) ((test)?swap16(x):(x))
00049 #define qswap32(test,x) ((test)?swap32(x):(x))
00050
00051 static inline unsigned int bswap(unsigned int x)
00052 {
00053 return swap32(x);
00054 }
00055
00056
00057 emc_t::emc_t()
00058 {
00059 memset(this,0,sizeof(emc_t));
00060 fenceA=fenceB=fenceC=fenceD=fenceE=fenceF=fenceG=fenceH=1946;
00061 fenceZ=1946;
00062 btow_max_ch = 4800 ;
00063 bsmd_max_ch = EMC_FIBER_NUM*4800 ;
00064
00065
00066
00067 etow_max_ch = ETOW_MAXFEE*ETOW_DATSIZE ;
00068 esmd_max_ch = ESMD_MAXFEE*ESMD_DATSIZE ;
00069 }
00070
00071 void emc_t::reset()
00072 {
00073 btow_ch = 0 ;
00074 bsmd_ch = 0 ;
00075
00076
00077 etow_ch = 0 ;
00078 esmd_ch = 0 ;
00079 btow_in = 0 ;
00080 bsmd_in = 0 ;
00081
00082 etow_in = 0 ;
00083 esmd_in = 0 ;
00084 btow_raw = 0 ;
00085 etow_raw = 0 ;
00086 }
00087
00088 int emc_t::check()
00089 {
00090 assert(fenceA==1946);
00091 assert(fenceB==1946);
00092 assert(fenceC==1946);
00093 assert(fenceD==1946);
00094 assert(fenceE==1946);
00095 assert(fenceF==1946);
00096 assert(fenceG==1946);
00097 assert(fenceH==1946);
00098 assert(fenceZ==1946);
00099 return 0;
00100 }
00101
00102 static char *id2char(int id)
00103 {
00104 switch(id) {
00105 case BTOW_ID :
00106 return "BARREL" ;
00107 case ETOW_ID :
00108 return "ENDCAP" ;
00109 default :
00110 return "unknown" ;
00111 }
00112 }
00113
00114 static char *inst2char(int inst)
00115 {
00116 switch(inst) {
00117 case 1 :
00118 return "TOWER" ;
00119 case 2 :
00120 return "SMD" ;
00121 default :
00122 return "UNKNOWN" ;
00123 }
00124
00125 }
00126
00127 namespace OLDEVP {
00128 char *getEmcTrgData(DATAP *datap,int index);
00129 int readBTOW(u_short *_data, int token);
00130 int readETOW(u_short *_data, int token);
00131 int DAQemcReader(char *m);
00132 }
00133 int OLDEVP::emcReader(char *m)
00134 {
00135 if (m == NULL) return EVP_DATA_ERR;
00136 return DAQemcReader(m);
00137 }
00138
00139 int OLDEVP::DAQemcReader(char *m)
00140 {
00141 struct DATAP *datap = (struct DATAP *)m ;
00142 struct DATAPX *datapx ;
00143 struct EMCP *emcp;
00144 struct EMCSECP *emcsecp ;
00145 struct EMCRBP *emcrbp ;
00146 struct DUMMYDATA *emcadcr, *emcadcd ;
00147 char *p, *secp, *rbp, *adcr, *adcd ;
00148 u_int local_token, token ;
00149
00150 int len, off ;
00151 int i, j, k ;
00152 int cou, cou2 ;
00153 int instance = 0 ;
00154 int type, id ;
00155
00156 int bytes ;
00157
00158 int swapdatap = 0;
00159 int swapdatapx = 0;
00160 int swapemcp = 0;
00161
00162 if(datap->bh.byte_order != DAQ_RAW_FORMAT_ORDER) swapdatap = 1;
00163
00164 token = qswap32(swapdatap, datap->bh.token);
00165
00166 emc.btow_max_ch = 4800 ;
00167 emc.bsmd_max_ch = 12*4800 ;
00168
00169
00170
00171 emc.etow_max_ch = ETOW_MAXFEE*ETOW_DATSIZE ;
00172 emc.esmd_max_ch = ESMD_MAXFEE*ESMD_DATSIZE ;
00173
00174
00175 emc.btow_ch = 0 ;
00176 emc.bsmd_ch = 0 ;
00177
00178
00179 emc.etow_ch = 0 ;
00180 emc.esmd_ch = 0 ;
00181
00182
00183 emc.btow_in = emc.bsmd_in = 0 ;
00184
00185 emc.etow_in = emc.esmd_in = 0 ;
00186
00187
00188 emc.btow_raw = 0 ;
00189 emc.etow_raw = 0 ;
00190
00191 if(datap == NULL) return 0 ;
00192
00193
00194 bytes = 0 ;
00195
00196
00197
00198 char *trg_btow_data = 0;
00199 if(trg_btow_data) {
00200 LOG_INFO << "Getting BTOW data from trigger banks..." << endm;
00201 readBTOW((u_short *)(trg_btow_data), token);
00202 bytes += (64 + 2 + 30 * 164) * 2;
00203 }
00204
00205
00206 char *trg_etow_data = getEmcTrgData(datap, y8ETOW_INDEX);
00207 if(trg_etow_data) {
00208 LOG_INFO << "Getting ETOW data from trigger banks..." << endm;
00209 readETOW((u_short *)(trg_etow_data), token);
00210 bytes += (64 + 2 + 6 * 164) * 2;
00211 }
00212
00213
00214
00215 for(type=0;type<2;type++) {
00216 if(type==0) {
00217 continue;
00218 id = BTOW_ID ;
00219 p = "EMCP" ;
00220 secp = "EMCSECP" ;
00221 rbp = "EMCRBP" ;
00222 adcr= "EMCADCR" ;
00223 adcd = "EMCADCD" ;
00224
00225 len = qswap32(swapdatap, datap->det[id].len) * 4 ;
00226 off = qswap32(swapdatap, datap->det[id].off) ;
00227 if((len == 0) || (off == 0)) {
00228 continue;
00229 }
00230 }
00231 else {
00232 id = ETOW_ID ;
00233 p = "EECP" ;
00234 secp = "EECSECP" ;
00235 rbp = "EECRBP" ;
00236 adcr= "EECADCR" ;
00237 adcd = "EECADCD" ;
00238
00239
00240 len = qswap32(swapdatap, datap->det[EXT_ID].len) ;
00241 off = qswap32(swapdatap, datap->det[EXT_ID].off) ;
00242 if((len == 0) || (off == 0)) {
00243 continue;
00244 }
00245
00246 datapx = (struct DATAPX *)(m + off*4) ;
00247
00248
00249 if(checkBank(datapx->bh.bank_type, CHAR_DATAPX) < 0) {
00250 continue ;
00251 }
00252
00253 if(datapx->bh.byte_order != DAQ_RAW_FORMAT_ORDER) swapdatapx = 1;
00254
00255 len = qswap32(swapdatapx, datapx->det[id-10].len) * 4 ;
00256 off = qswap32(swapdatapx, datapx->det[id-10].off) ;
00257 if((len == 0) || (off == 0)) {
00258 continue;
00259 }
00260
00261
00262 m = (char *)datapx ;
00263 }
00264
00265
00266
00267 LOG_DEBUG << Form("EMC %s: bytes %d, off %d",id2char(id),len,off) << endm;
00268
00269 bytes += len ;
00270
00271 emcp = (struct EMCP *)((u_int *)m + off) ;
00272
00273 if(checkBank(emcp->bh.bank_type,p) < 0) {
00274 return -1 ;
00275 }
00276
00277 if(emcp->bh.byte_order != DAQ_RAW_FORMAT_ORDER) swapemcp = 1;
00278
00279 token = qswap32(swapemcp, emcp->bh.token) ;
00280
00281
00282
00283
00284 for(i=0;i<3;i++) {
00285
00286 len = qswap32(swapemcp, emcp->sec[i].len) ;
00287 if(len == 0) continue ;
00288
00289 instance = i + 1 ;
00290
00291 off = qswap32(swapemcp, emcp->sec[i].off) ;
00292
00293 emcsecp = (struct EMCSECP *)((u_int *)emcp + off) ;
00294
00295 if(checkBank(emcsecp->bh.bank_type,secp) < 0) {
00296 continue ;
00297 }
00298
00299 cou = (b2h32(emcsecp->bh.length) - 10) / 2 ;
00300
00301
00302 LOG_DEBUG << Form("EMC %s: instance %s: %d fibers possible",id2char(id),inst2char(instance),cou) << endm;
00303
00304 for(j=0;j<cou;j++) {
00305 len = b2h32(emcsecp->fiber[j].len) ;
00306
00307 if(len == 0) continue ;
00308
00309 off = b2h32(emcsecp->fiber[j].off) ;
00310
00311 emcrbp = (struct EMCRBP *)((u_int *)emcsecp + off) ;
00312
00313 LOG_DEBUG << Form("EMC %s: instance %s: fiber %d: len %d, off %d",id2char(id),inst2char(instance),j+1,len,off) << endm;
00314
00315 if(checkBank(emcrbp->bh.bank_type,rbp) < 0) {
00316 continue ;
00317 }
00318
00319
00320 cou2 = (b2h32(emcrbp->bh.length) - 10) /2 ;
00321
00322 LOG_DEBUG << Form("EMC %s: instance %s: fiber %d: %d banks used",id2char(id),inst2char(instance),j+1,cou2) << endm;
00323
00324 emcadcr = emcadcd = NULL ;
00325
00326 for(k=0;k<cou2;k++) {
00327 len = b2h32(emcrbp->banks[k].len) ;
00328
00329 if(len == 0) continue ;
00330
00331 off = b2h32(emcrbp->banks[k].off) ;
00332
00333 emcadcr = NULL ;
00334
00335 switch(k) {
00336 case 0 :
00337 emcadcr = (struct DUMMYDATA *)((u_int *)emcrbp + off) ;
00338 if(checkBank(emcadcr->bh.bank_type,adcr) < 0) {
00339 continue ;
00340 }
00341
00342 break ;
00343 case 1 :
00344 emcadcd = (struct DUMMYDATA *)((u_int *)emcrbp + off) ;
00345 if(checkBank(emcadcr->bh.bank_type,adcd) < 0) {
00346 continue ;
00347 }
00348
00349 break ;
00350 default :
00351 LOG_ERROR << Form("Unknown subbank %d in EMCRBP!",k) << endm;
00352 continue ;
00353 }
00354
00355
00356 if(emcadcr == NULL) {
00357 LOG_WARN << Form("EMC %d: instance %d, format %d is not implemented yet!",
00358 id2char(id),inst2char(instance), k) << endm;
00359 continue ;
00360 }
00361
00362
00363 if((type==0) && (i == EMC_B_TOW)) {
00364 if(trg_btow_data) {
00365 LOG_ERROR << "Reading BTOW data from DAQ banks but already read it from trigger banks" << endm;
00366 }
00367 readBTOW((u_short *)((char *)emcadcr + 40), token);
00368 }
00369 else if((type==0) && (i == EMC_B_SMD)) {
00370
00371 u_short *data ;
00372 int l ;
00373
00374 emc.bsmd_in = 1;
00375
00376
00377 data = (u_short *) ((char *) emcadcr + 40 + 4 + 256) ;
00378
00379
00380 emc.bsmd_cap[j] = *(u_char *)((char *)emcadcr + 40 + 4 + 4*16) ;
00381 for(l=0;l<4800;l++) {
00382 emc.bsmd[j][l] = l2h16(*data++) ;
00383 if(emc.bsmd[j][l] > 0) emc.bsmd_ch++ ;
00384 LOG_DEBUG << Form("BSMD %d: %d",l,emc.bsmd[j][l]) << endm;
00385 }
00386
00387 }
00388 else if((type == 1) && (i == EMC_B_TOW)) {
00389
00390 if(trg_etow_data) {
00391 LOG_ERROR << "Reading ETOW data in the DAQ banks, but already read it from the trigger banks." << endm;
00392 }
00393
00394 readETOW((u_short *)((char*)emcadcr + 40), token);
00395 }
00396 else if((type==1) && (i == EMC_B_SMD)) {
00397
00398 u_short *data ;
00399 u_int tlo, thi ;
00400 int l, m ;
00401
00402 emc.esmd_in = 1;
00403
00404
00405
00406
00407 data = (u_short *) ((char*) emcadcr + 40 + 4 + 4) ;
00408 thi = l2h16(*data) ;
00409 data = (u_short *) ((char*) emcadcr + 40 + 4 + 6) ;
00410 tlo = l2h16(*data) ;
00411
00412 local_token = thi * 256 + tlo ;
00413
00414 if(token != local_token) {
00415 LOG_ERROR << Form("ESMD: Token in bank %d different from token in data %d",token,local_token) << endm;
00416 }
00417
00418 data = (u_short *) ((char*) emcadcr + 40 + 4 + 128) ;
00419
00420 emc.esmd_raw = data ;
00421
00422
00423 if(l2h32(emcadcr->bh.length) < 3000) {
00424 emc.esmd_max_fee = 30 ;
00425 }
00426 else {
00427 emc.esmd_max_fee = 48 ;
00428 }
00429
00430 emc.esmd_max_ch = emc.esmd_max_fee*ETOW_DATSIZE ;
00431
00432
00433
00434 for(m=0;m<ESMD_PRESIZE;m++) {
00435 for(l=0;l<emc.esmd_max_fee;l++) {
00436 emc.esmd_pre[l][m] = l2h16(*data++) ;
00437 }
00438 }
00439
00440 for(m=0;m<ESMD_DATSIZE;m++) {
00441 for(l=0;l<emc.esmd_max_fee;l++) {
00442 emc.esmd[l][m] = l2h16(*data++) ;
00443 if(emc.esmd[l][m] > 0) emc.esmd_ch++ ;
00444 }
00445 }
00446 }
00447 }
00448 }
00449 }
00450 }
00451
00452
00453 return bytes ;
00454
00455 }
00456
00457
00458
00459
00460
00461
00462 int OLDEVP::readBTOW(u_short *_data, int token)
00463 {
00464 u_short *data ;
00465 int l, m ;
00466 int thi, tlo, local_token;
00467
00468 emc.btow_in = 1;
00469
00470
00471 data = (u_short *)((char*)_data + 4 + 4);
00472 thi = l2h16(*data);
00473 data = (u_short *)((char*)_data + 4 + 6);
00474 tlo = l2h16(*data);
00475 data = (u_short *)((char*)_data + 4 + 128);
00476
00477 local_token = thi * 256 + tlo ;
00478
00479 if(token != local_token) {
00480 LOG_ERROR << Form("BTOW: Event token different from token in BTOW data %d vs %d (%d,%d)",token,local_token,thi,tlo) << endm;
00481 }
00482
00483
00484
00485 data = (u_short *)((char*)_data + 4 + 128);
00486 emc.btow_raw = data ;
00487
00488
00489 for(m=0;m<BTOW_PRESIZE;m++) {
00490 for(l=0;l<BTOW_MAXFEE;l++) {
00491 emc.btow_pre[l][m] = l2h16(*data++) ;;
00492 }
00493 }
00494
00495
00496 for(m=0;m<BTOW_DATSIZE;m++) {
00497 for(l=0;l<BTOW_MAXFEE;l++) {
00498 emc.btow_new[l][m] = l2h16(*data++) ;
00499 }
00500 }
00501
00502
00503 data = emc.btow_raw ;
00504 data += 120 ;
00505
00506 for(l=0;l<4800;l++) {
00507 emc.btow[l] = l2h16(*data++) ;
00508 if(emc.btow[l] > 0) emc.btow_ch++ ;
00509 }
00510
00511 return 0;
00512 }
00513
00514
00515
00516
00517
00518
00519
00520
00521 int OLDEVP::readETOW(u_short *_data, int token) {
00522 u_short *data ;
00523 u_int tlo, thi ;
00524 int local_token;
00525
00526 int l,m ;
00527
00528 emc.etow_in = 1;
00529
00530
00531
00532
00533
00534 data = (u_short *)((char*)_data + 4 + 4);
00535 thi = l2h16(*data);
00536 data = (u_short *)((char*)_data + 4 + 6);
00537 tlo = l2h16(*data);
00538 data = (u_short *)((char*)_data + 4 + 128);
00539
00540 local_token = thi * 256 + tlo ;
00541
00542 if(token != local_token) {
00543 LOG_ERROR << Form("ETOW: Event token different from token in ETOW data %d vs %d (%d,%d)",token,local_token,thi,tlo) << endm;
00544 }
00545
00546 emc.etow_raw = data ;
00547
00548
00549 for(m=0;m<ETOW_PRESIZE;m++) {
00550 for(l=0;l<ETOW_MAXFEE;l++) {
00551 emc.etow_pre[l][m] = l2h16(*data++) ;;
00552 }
00553 }
00554
00555
00556 for(m=0;m<ETOW_DATSIZE;m++) {
00557 for(l=0;l<ETOW_MAXFEE;l++) {
00558 emc.etow[l][m] = l2h16(*data++) ;
00559 if(emc.etow[l][m] > 0) emc.etow_ch++ ;
00560 }
00561 }
00562
00563
00564
00565
00566 return 0;
00567 }
00568
00569 char* OLDEVP::getEmcTrgData(DATAP* datap, int index)
00570 {
00571 LOG_INFO << "Starting EMC reader..." << endm;
00572
00573
00574 LOG_INFO << Form("DATAP=08x%x, byte order=0x%08x", datap, datap->bh.byte_order) << endm;
00575 if (!(datap->det[TRG_ID].off && datap->det[TRG_ID].len)) return 0;
00576 bool swapdatap = datap->bh.byte_order != DAQ_RAW_FORMAT_ORDER;
00577 int off = qswap32(swapdatap, datap->det[TRG_ID].off);
00578
00579
00580 TRGP* trgp = (TRGP*)((int*)datap + off) ;
00581 LOG_INFO << Form("TRGP=0x%08x, byte order=0x%08x", trgp, trgp->bh.byte_order) << endm;
00582 if (checkBank(trgp->bh.bank_type, "TRGP") < 0) return 0;
00583
00584 if (!trgp->bh.token) {
00585 LOG_INFO << "Token 0 - skipping..." << endm;
00586 return 0;
00587 }
00588
00589 if (!(trgp->trgData.off && trgp->trgData.len)) return 0;
00590
00591 bool swaptrgp = trgp->bh.byte_order != DAQ_RAW_FORMAT_ORDER;
00592 off = qswap32(swaptrgp, trgp->trgData.off);
00593
00594
00595 TRGD* trgd = (TRGD*)((int*)trgp + off);
00596 LOG_INFO << Form("TRGD=0x%08x, byte order=0x%08x", trgd, trgd->bh.byte_order) << endm;
00597
00598
00599 if (checkBank(trgd->bh.bank_type, "TRGD") < 0) return 0;
00600
00601 bool swaptrgd = trgd->bh.byte_order != DAQ_RAW_FORMAT_ORDER;
00602 int len = qswap32(swaptrgd, trgd->bh.length);
00603
00604 if (len == 10) return 0;
00605
00606
00607 if (swaptrgd) {
00608 const size_t SIZE = sizeof(TrgTowerTrnfer2008) / 4;
00609 unsigned int* p = (unsigned int*)&trgd->tow;
00610 std::transform(p, p + SIZE, p, bswap);
00611 }
00612
00613 TrgTowerTrnfer2008* trgtowertrnfer = &trgd->tow;
00614 unsigned int byteCount_Version = qswap32(swaptrgd, trgtowertrnfer->byteCount_Version);
00615 unsigned int byteCount = byteCount_Version >> 8 & 0xffffff;
00616 unsigned char version = byteCount_Version & 0xff;
00617
00618 switch (version) {
00619 case y8TRANSFER_VERSION: {
00620 int offset = qswap32(swaptrgd, trgtowertrnfer->OffsetBlock[index].offset);
00621 int length = qswap32(swaptrgd, trgtowertrnfer->OffsetBlock[index].length);
00622
00623 if (!(offset && length)) return 0;
00624
00625 LOG_INFO << Form("TrgTowerTrnfer2008: byte count=%d, version=0x%02x, index=%d, offset=%d, length=%d",
00626 byteCount, version, index, offset, length) << endm;
00627
00628 switch (index) {
00629 case y8BTOW_INDEX:
00630 if (length != (64 + 2 + 30 * 164) * 2) {
00631 LOG_ERROR << Form("Have BTOW in event, but data length incorrect: length=%d, not %d. Ignoring data...",
00632 length, (64 + 2 + 30 * 164) * 2) << endm;
00633 return 0;
00634 }
00635
00636 LOG_INFO << Form("Have BTOW data in trigger banks: offset=%d, length=%d", offset, length) << endm;
00637 break;
00638
00639 case y8ETOW_INDEX:
00640 if (length != (64 + 2 + 6 * 164) * 2) {
00641 LOG_ERROR << Form("Have ETOW in event, but data length incorrect: length=%d, not %d. Ignoring data...",
00642 length, (64 + 2 + 6 * 164) * 2) << endm;
00643 return 0;
00644 }
00645
00646 LOG_INFO << Form("Have ETOW data in trigger banks: offset=%d, length=%d", offset, length) << endm;
00647 break;
00648
00649 default:
00650 LOG_ERROR << Form("Unknown transfer data index=%d", index) << endm;
00651 return 0;
00652 }
00653
00654 return (char*)trgtowertrnfer + offset;
00655 }
00656
00657 default :
00658 LOG_INFO << Form("Trigger transfer version 0x%02x. No EMC data in trigger banks.", version) << endm;
00659 return 0;
00660 }
00661
00662 return 0;
00663 }
00664