StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
emcReader.cxx
1 #include <stdio.h>
2 #include <string.h>
3 #include <assert.h>
4 #include <arpa/inet.h>
5 
6 //VP#include "rtsLog.h"
7 #include "rtsSystems.h"
8 #include "daqFormats.h"
9 
10 //VP#include "evpReader.hh"
11 #include "evpSupport.h"
12 #include "emcReader.h"
13 
14 #include "TString.h" // Form()
15 #include "StMessMgr.h" // LOG_INFO, LOG_WARN, LOG_ERROR, LOG_DEBUG, etc.
16 #include <algorithm>
17 
18 using namespace OLDEVP;
19 namespace OLDEVP {
20 struct emc_t emc ;
21 }
22 #define SWAP32(bk,x) ((bk->bh.byte_order==0x4030201)?(bk->x):swap32(bk->x))
23 
24 /*********************** BYTESWAPPING STUFF ***********************/
25 /* online/RTS/include/rts.h */
26 #ifdef __linux__
27 /* linux has its own (fast) swaps */
28 #include <byteswap.h>
29 
30 #define swap16(x) bswap_16(x)
31 #define swap32(x) bswap_32(x)
32 
33 #else /* non-linux stuff */
34 
35 extern inline unsigned short swap16(unsigned short x)
36 {
37  return ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) ;
38 }
39 
40 extern inline unsigned int swap32(unsigned int x)
41 {
42  return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
43  (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) ;
44 }
45 
46 #endif /* BYTESWAP */
47 
48 #define qswap16(test,x) ((test)?swap16(x):(x))
49 #define qswap32(test,x) ((test)?swap32(x):(x))
50 
51 static inline unsigned int bswap(unsigned int x)
52 {
53  return swap32(x);
54 }
55 
56 //________________________________________________________________________________
57 emc_t::emc_t()
58 {
59  memset(this,0,sizeof(emc_t));
60  fenceA=fenceB=fenceC=fenceD=fenceE=fenceF=fenceG=fenceH=1946;
61  fenceZ=1946;
62  btow_max_ch = 4800 ;
63  bsmd_max_ch = EMC_FIBER_NUM*4800 ; // extended with BPRE
64 
65 // bpre_max_ch = 4800 ; // unknown...
66 
67  etow_max_ch = ETOW_MAXFEE*ETOW_DATSIZE ;
68  esmd_max_ch = ESMD_MAXFEE*ESMD_DATSIZE ; // unknown...
69 }
70 //________________________________________________________________________________
71 void emc_t::reset()
72 {
73  btow_ch = 0 ;
74  bsmd_ch = 0 ;
75 // bpre_ch = 0 ;
76 
77  etow_ch = 0 ;
78  esmd_ch = 0 ;
79  btow_in = 0 ;
80  bsmd_in = 0 ;
81 // bpre_in = 0 ;
82  etow_in = 0 ;
83  esmd_in = 0 ;
84  btow_raw = 0 ;
85  etow_raw = 0 ;
86 }
87 //________________________________________________________________________________
88 int emc_t::check()
89 {
90  assert(fenceA==1946);
91  assert(fenceB==1946);
92  assert(fenceC==1946);
93  assert(fenceD==1946);
94  assert(fenceE==1946);
95  assert(fenceF==1946);
96  assert(fenceG==1946);
97  assert(fenceH==1946);
98  assert(fenceZ==1946);
99  return 0;
100 }
101 //________________________________________________________________________________
102 static const char *id2char(int id)
103 {
104  switch(id) {
105  case BTOW_ID :
106  return "BARREL" ;
107  case ETOW_ID :
108  return "ENDCAP" ;
109  default :
110  return "unknown" ;
111  }
112 }
113 
114 static const char *inst2char(int inst)
115 {
116  switch(inst) {
117  case 1 :
118  return "TOWER" ;
119  case 2 :
120  return "SMD" ;
121  default :
122  return "UNKNOWN" ;
123  }
124 
125 }
126 
127 namespace OLDEVP {
128 char *getEmcTrgData(DATAP *datap,int index);
129 int readBTOW(u_short *_data, int token);
130 int readETOW(u_short *_data, int token);
131 int DAQemcReader(char *m);
132 }
133 int OLDEVP::emcReader(char *m)
134 {
135  if (m == NULL) return EVP_DATA_ERR; // error
136  return DAQemcReader(m);
137 }
138 
139 int OLDEVP::DAQemcReader(char *m)
140 {
141  struct DATAP *datap = (struct DATAP *)m ;
142  struct DATAPX *datapx ;
143  struct EMCP *emcp;
144  struct EMCSECP *emcsecp ;
145  struct EMCRBP *emcrbp ;
146  struct DUMMYDATA *emcadcr, *emcadcd ;
147  const char *p, *secp, *rbp, *adcr, *adcd ;
148  u_int local_token, token ;
149 
150  int len, off ;
151  int i, j, k ;
152  int cou, cou2 ;
153  int instance = 0 ;
154  int type, id ;
155 
156  int bytes ;
157 
158  int swapdatap = 0;
159  int swapdatapx = 0;
160  int swapemcp = 0;
161 
162  if(datap->bh.byte_order != DAQ_RAW_FORMAT_ORDER) swapdatap = 1;
163 
164  token = qswap32(swapdatap, datap->bh.token);
165 
166  emc.btow_max_ch = 4800 ;
167  emc.bsmd_max_ch = 12*4800 ; // extended with BPRE
168 
169 // emc.bpre_max_ch = 4800 ; // unknown...
170 
171  emc.etow_max_ch = ETOW_MAXFEE*ETOW_DATSIZE ;
172  emc.esmd_max_ch = ESMD_MAXFEE*ESMD_DATSIZE ; // unknown...
173 
174 
175  emc.btow_ch = 0 ;
176  emc.bsmd_ch = 0 ;
177 // emc.bpre_ch = 0 ;
178 
179  emc.etow_ch = 0 ;
180  emc.esmd_ch = 0 ;
181 
182 
183  emc.btow_in = emc.bsmd_in = 0 ;
184 // emc.bpre_in = 0 ;
185  emc.etow_in = emc.esmd_in = 0 ;
186 
187 
188  emc.btow_raw = 0 ;
189  emc.etow_raw = 0 ;
190 
191  if(datap == NULL) return 0 ;
192 
193 
194  bytes = 0 ;
195 
196  // Now read the emc banks...
197  //char *trg_btow_data = getEmcTrgData(datap, y8BTOW_INDEX);
198  char *trg_btow_data = 0; // BTOW data read elsewhere
199  if(trg_btow_data) {
200  LOG_INFO << "Getting BTOW data from trigger banks..." << endm;
201  readBTOW((u_short *)(trg_btow_data), token);
202  bytes += (64 + 2 + 30 * 164) * 2;
203  }
204 
205 
206  char *trg_etow_data = getEmcTrgData(datap, y8ETOW_INDEX);
207  if(trg_etow_data) {
208  LOG_INFO << "Getting ETOW data from trigger banks..." << endm;
209  readETOW((u_short *)(trg_etow_data), token);
210  bytes += (64 + 2 + 6 * 164) * 2;
211  }
212 
213 
214  // let's first do the Barrel Tower
215  for(type=0;type<2;type++) { // 0 - Barrel, 1 - Endcap
216  if(type==0) {
217  continue; // BTOW data read elsewhere
218  id = BTOW_ID ;
219  p = "EMCP" ;
220  secp = "EMCSECP" ;
221  rbp = "EMCRBP" ;
222  adcr= "EMCADCR" ;
223  adcd = "EMCADCD" ;
224 
225  len = qswap32(swapdatap, datap->det[id].len) * 4 ;
226  off = qswap32(swapdatap, datap->det[id].off) ;
227  if((len == 0) || (off == 0)) {
228  continue;
229  }
230  }
231  else {
232  id = ETOW_ID ;
233  p = "EECP" ;
234  secp = "EECSECP" ;
235  rbp = "EECRBP" ;
236  adcr= "EECADCR" ;
237  adcd = "EECADCD" ;
238 
239  // EEC is in DATAPX...
240  len = qswap32(swapdatap, datap->det[EXT_ID].len) ;
241  off = qswap32(swapdatap, datap->det[EXT_ID].off) ;
242  if((len == 0) || (off == 0)) {
243  continue;
244  }
245 
246  datapx = (struct DATAPX *)(m + off*4) ;
247 
248  // verify bank
249  if(checkBank(datapx->bh.bank_type, CHAR_DATAPX) < 0) {
250  continue ;
251  }
252 
253  if(datapx->bh.byte_order != DAQ_RAW_FORMAT_ORDER) swapdatapx = 1;
254 
255  len = qswap32(swapdatapx, datapx->det[id-10].len) * 4 ;
256  off = qswap32(swapdatapx, datapx->det[id-10].off) ;
257  if((len == 0) || (off == 0)) {
258  continue;
259  }
260 
261  // override "m"
262  m = (char *)datapx ;
263  }
264 
265 
266 
267  LOG_DEBUG << Form("EMC %s: bytes %d, off %d",id2char(id),len,off) << endm;
268 
269  bytes += len ; // save
270 
271  emcp = (struct EMCP *)((u_int *)m + off) ;
272 
273  if(checkBank(emcp->bh.bank_type,p) < 0) {
274  return -1 ;
275  }
276 
277  if(emcp->bh.byte_order != DAQ_RAW_FORMAT_ORDER) swapemcp = 1;
278 
279  token = qswap32(swapemcp, emcp->bh.token) ;
280 
281 
282  // let's see how many contributions (subdetectors) does this event have
283 
284  for(i=0;i<3;i++) { // go through subdets
285 
286  len = qswap32(swapemcp, emcp->sec[i].len) ;
287  if(len == 0) continue ;
288 
289  instance = i + 1 ; // EMC subinstances star from 1...
290 
291  off = qswap32(swapemcp, emcp->sec[i].off) ;
292 
293  emcsecp = (struct EMCSECP *)((u_int *)emcp + off) ;
294 
295  if(checkBank(emcsecp->bh.bank_type,secp) < 0) {
296  continue ;
297  }
298 
299  cou = (b2h32(emcsecp->bh.length) - 10) / 2 ; // contributions!
300 
301 
302  LOG_DEBUG << Form("EMC %s: instance %s: %d fibers possible",id2char(id),inst2char(instance),cou) << endm;
303 
304  for(j=0;j<cou;j++) {
305  len = b2h32(emcsecp->fiber[j].len) ;
306 
307  if(len == 0) continue ;
308 
309  off = b2h32(emcsecp->fiber[j].off) ;
310 
311  emcrbp = (struct EMCRBP *)((u_int *)emcsecp + off) ;
312 
313  LOG_DEBUG << Form("EMC %s: instance %s: fiber %d: len %d, off %d",id2char(id),inst2char(instance),j+1,len,off) << endm;
314 
315  if(checkBank(emcrbp->bh.bank_type,rbp) < 0) {
316  continue ;
317  }
318 
319 
320  cou2 = (b2h32(emcrbp->bh.length) - 10) /2 ;
321 
322  LOG_DEBUG << Form("EMC %s: instance %s: fiber %d: %d banks used",id2char(id),inst2char(instance),j+1,cou2) << endm;
323 
324  emcadcr = emcadcd = NULL ;
325 
326  for(k=0;k<cou2;k++) {
327  len = b2h32(emcrbp->banks[k].len) ;
328 
329  if(len == 0) continue ;
330 
331  off = b2h32(emcrbp->banks[k].off) ;
332 
333  emcadcr = NULL ;
334 
335  switch(k) {
336  case 0 : // Raw, ADCR
337  emcadcr = (struct DUMMYDATA *)((u_int *)emcrbp + off) ;
338  if(checkBank(emcadcr->bh.bank_type,adcr) < 0) {
339  continue ;
340  }
341 
342  break ;
343  case 1 : // zero-suppressed...
344  emcadcd = (struct DUMMYDATA *)((u_int *)emcrbp + off) ;
345  if(checkBank(emcadcr->bh.bank_type,adcd) < 0) {
346  continue ;
347  }
348 
349  break ;
350  default :
351  LOG_ERROR << Form("Unknown subbank %d in EMCRBP!",k) << endm;
352  continue ;
353  }
354 
355  // I currently only know about RAW data
356  if(emcadcr == NULL) {
357  LOG_WARN << Form("EMC %d: instance %d, format %d is not implemented yet!",
358  id2char(id),inst2char(instance), k) << endm;
359  continue ;
360  }
361 
362 
363  if((type==0) && (i == EMC_B_TOW)) { // barrel tower
364  if(trg_btow_data) {
365  LOG_ERROR << "Reading BTOW data from DAQ banks but already read it from trigger banks" << endm;
366  }
367  readBTOW((u_short *)((char *)emcadcr + 40), token);
368  }
369  else if((type==0) && (i == EMC_B_SMD)) { // barrel SMD
370 
371  u_short *data ;
372  int l ;
373 
374  emc.bsmd_in = 1;
375  // get to the data: 40 bytes bank header, 4 bytes dummy,
376  // 256 bytes fiber header...
377  data = (u_short *) ((char *) emcadcr + 40 + 4 + 256) ;
378 
379 
380  emc.bsmd_cap[j] = *(u_char *)((char *)emcadcr + 40 + 4 + 4*16) ;
381  for(l=0;l<4800;l++) {
382  emc.bsmd[j][l] = l2h16(*data++) ;
383  if(emc.bsmd[j][l] > 0) emc.bsmd_ch++ ;
384  LOG_DEBUG << Form("BSMD %d: %d",l,emc.bsmd[j][l]) << endm;
385  }
386 
387  }
388  else if((type == 1) && (i == EMC_B_TOW)) { // endcap tower
389 
390  if(trg_etow_data) {
391  LOG_ERROR << "Reading ETOW data in the DAQ banks, but already read it from the trigger banks." << endm;
392  }
393 
394  readETOW((u_short *)((char*)emcadcr + 40), token);
395  }
396  else if((type==1) && (i == EMC_B_SMD)) { // endcap SMD
397 
398  u_short *data ;
399  u_int tlo, thi ;
400  int l, m ;
401 
402  emc.esmd_in = 1;
403 
404  // get to the data: 40 bytes bank header, 4 bytes dummy,
405  // 128 bytes fiber header...
406  // ...but first grab the token from the header...
407  data = (u_short *) ((char*) emcadcr + 40 + 4 + 4) ;
408  thi = l2h16(*data) ;
409  data = (u_short *) ((char*) emcadcr + 40 + 4 + 6) ;
410  tlo = l2h16(*data) ;
411 
412  local_token = thi * 256 + tlo ;
413 
414  if(token != local_token) {
415  LOG_ERROR << Form("ESMD: Token in bank %d different from token in data %d",token,local_token) << endm;
416  }
417 
418  data = (u_short *) ((char*) emcadcr + 40 + 4 + 128) ;
419 
420  emc.esmd_raw = data ;
421 
422  // get the header size...
423  if(l2h32(emcadcr->bh.length) < 3000) { // FY04 data
424  emc.esmd_max_fee = 30 ;
425  }
426  else {
427  emc.esmd_max_fee = 48 ;
428  }
429 
430  emc.esmd_max_ch = emc.esmd_max_fee*ETOW_DATSIZE ;
431 
432 
433  // get the preamble
434  for(m=0;m<ESMD_PRESIZE;m++) {
435  for(l=0;l<emc.esmd_max_fee;l++) {
436  emc.esmd_pre[l][m] = l2h16(*data++) ;
437  }
438  }
439 
440  for(m=0;m<ESMD_DATSIZE;m++) {
441  for(l=0;l<emc.esmd_max_fee;l++) {
442  emc.esmd[l][m] = l2h16(*data++) ;
443  if(emc.esmd[l][m] > 0) emc.esmd_ch++ ;
444  }
445  }
446  }
447  }
448  }
449  }
450  }
451 
452 
453  return bytes ;
454 
455 }
456 
457 // Starts from after the EMCADCR bankHeader...
458 //
459 // ie... data = (char*)emcadcr + 40
460 // = (u_int)trg_btow_data
461 //
462 int OLDEVP::readBTOW(u_short *_data, int token)
463 {
464  u_short *data ;
465  int l, m ;
466  int thi, tlo, local_token;
467 
468  emc.btow_in = 1;
469 
470 
471  data = (u_short *)((char*)_data + 4 + 4);
472  thi = l2h16(*data);
473  data = (u_short *)((char*)_data + 4 + 6);
474  tlo = l2h16(*data);
475  data = (u_short *)((char*)_data + 4 + 128);
476 
477  local_token = thi * 256 + tlo ;
478 
479  if(token != local_token) {
480  LOG_ERROR << Form("BTOW: Event token different from token in BTOW data %d vs %d (%d,%d)",token,local_token,thi,tlo) << endm;
481  }
482 
483 
484  // 4 bytes dummy, 128 bytes fiber header...
485  data = (u_short *)((char*)_data + 4 + 128);
486  emc.btow_raw = data ;
487 
488  // get the preamble
489  for(m=0;m<BTOW_PRESIZE;m++) {
490  for(l=0;l<BTOW_MAXFEE;l++) {
491  emc.btow_pre[l][m] = l2h16(*data++) ;;
492  }
493  }
494 
495 
496  for(m=0;m<BTOW_DATSIZE;m++) {
497  for(l=0;l<BTOW_MAXFEE;l++) {
498  emc.btow_new[l][m] = l2h16(*data++) ;
499  }
500  }
501 
502  // roll back
503  data = emc.btow_raw ;
504  data += 120 ; // skip the preamble of 4X30 shorts
505 
506  for(l=0;l<4800;l++) {
507  emc.btow[l] = l2h16(*data++) ;
508  if(emc.btow[l] > 0) emc.btow_ch++ ;
509  }
510 
511  return 0;
512 }
513 
514 
515 
516 // Starts from after the bankHeader...
517 //
518 // ie... data = (char*)emcadcr + 40
519 // = (u_int)trg_btow_data + 136
520 //
521 int OLDEVP::readETOW(u_short *_data, int token) {
522  u_short *data ;
523  u_int tlo, thi ;
524  int local_token;
525 
526  int l,m ;
527 
528  emc.etow_in = 1;
529  // get to the data: 40 bytes bank header, 4 bytes dummy,
530  // 128 bytes fiber header...
531  // ...but first grab the token from the header...
532 
533 
534  data = (u_short *)((char*)_data + 4 + 4);
535  thi = l2h16(*data);
536  data = (u_short *)((char*)_data + 4 + 6);
537  tlo = l2h16(*data);
538  data = (u_short *)((char*)_data + 4 + 128);
539 
540  local_token = thi * 256 + tlo ;
541 
542  if(token != local_token) {
543  LOG_ERROR << Form("ETOW: Event token different from token in ETOW data %d vs %d (%d,%d)",token,local_token,thi,tlo) << endm;
544  }
545 
546  emc.etow_raw = data ;
547 
548  // get the preamble
549  for(m=0;m<ETOW_PRESIZE;m++) {
550  for(l=0;l<ETOW_MAXFEE;l++) {
551  emc.etow_pre[l][m] = l2h16(*data++) ;;
552  }
553  }
554 
555 
556  for(m=0;m<ETOW_DATSIZE;m++) {
557  for(l=0;l<ETOW_MAXFEE;l++) {
558  emc.etow[l][m] = l2h16(*data++) ;
559  if(emc.etow[l][m] > 0) emc.etow_ch++ ;
560  }
561  }
562 
563  // hack!
564  //emc.etow[0][0] = local_token ;
565 
566  return 0;
567 }
568 
569 char* OLDEVP::getEmcTrgData(DATAP* datap, int index)
570 {
571  LOG_INFO << "Starting EMC reader..." << endm;
572 
573  // DATA pointer bank
574  LOG_INFO << Form("DATAP=08x%x, byte order=0x%08x", datap, datap->bh.byte_order) << endm;
575  if (!(datap->det[TRG_ID].off && datap->det[TRG_ID].len)) return 0;
576  bool swapdatap = datap->bh.byte_order != DAQ_RAW_FORMAT_ORDER;
577  int off = qswap32(swapdatap, datap->det[TRG_ID].off);
578 
579  // TRG pointer bank
580  TRGP* trgp = (TRGP*)((int*)datap + off) ;
581  LOG_INFO << Form("TRGP=0x%08x, byte order=0x%08x", trgp, trgp->bh.byte_order) << endm;
582  if (checkBank(trgp->bh.bank_type, "TRGP") < 0) return 0; // Wrong bank!
583 
584  if (!trgp->bh.token) {
585  LOG_INFO << "Token 0 - skipping..." << endm;
586  return 0;
587  }
588 
589  if (!(trgp->trgData.off && trgp->trgData.len)) return 0;
590 
591  bool swaptrgp = trgp->bh.byte_order != DAQ_RAW_FORMAT_ORDER;
592  off = qswap32(swaptrgp, trgp->trgData.off);
593 
594  // TRG data bank
595  TRGD* trgd = (TRGD*)((int*)trgp + off);
596  LOG_INFO << Form("TRGD=0x%08x, byte order=0x%08x", trgd, trgd->bh.byte_order) << endm;
597 
598  // Check miscellanious things
599  if (checkBank(trgd->bh.bank_type, "TRGD") < 0) return 0; // Wrong bank!
600 
601  bool swaptrgd = trgd->bh.byte_order != DAQ_RAW_FORMAT_ORDER;
602  int len = qswap32(swaptrgd, trgd->bh.length);
603 
604  if (len == 10) return 0; // No trigger data, just bank header
605 
606  // Swap TrgTowerTrnfer2008
607  if (swaptrgd) {
608  const size_t SIZE = sizeof(TrgTowerTrnfer2008) / 4;
609  unsigned int* p = (unsigned int*)&trgd->tow;
610  std::transform(p, p + SIZE, p, bswap);
611  }
612 
613  TrgTowerTrnfer2008* trgtowertrnfer = &trgd->tow;
614  unsigned int byteCount_Version = qswap32(swaptrgd, trgtowertrnfer->byteCount_Version);
615  unsigned int byteCount = byteCount_Version >> 8 & 0xffffff;
616  unsigned char version = byteCount_Version & 0xff;
617 
618  switch (version) {
619  case y8TRANSFER_VERSION: {
620  int offset = qswap32(swaptrgd, trgtowertrnfer->OffsetBlock[index].offset);
621  int length = qswap32(swaptrgd, trgtowertrnfer->OffsetBlock[index].length);
622 
623  if (!(offset && length)) return 0;
624 
625  LOG_INFO << Form("TrgTowerTrnfer2008: byte count=%d, version=0x%02x, index=%d, offset=%d, length=%d",
626  byteCount, version, index, offset, length) << endm;
627 
628  switch (index) {
629  case y8BTOW_INDEX:
630  if (length != (64 + 2 + 30 * 164) * 2) {
631  LOG_ERROR << Form("Have BTOW in event, but data length incorrect: length=%d, not %d. Ignoring data...",
632  length, (64 + 2 + 30 * 164) * 2) << endm;
633  return 0;
634  }
635 
636  LOG_INFO << Form("Have BTOW data in trigger banks: offset=%d, length=%d", offset, length) << endm;
637  break;
638 
639  case y8ETOW_INDEX:
640  if (length != (64 + 2 + 6 * 164) * 2) {
641  LOG_ERROR << Form("Have ETOW in event, but data length incorrect: length=%d, not %d. Ignoring data...",
642  length, (64 + 2 + 6 * 164) * 2) << endm;
643  return 0;
644  }
645 
646  LOG_INFO << Form("Have ETOW data in trigger banks: offset=%d, length=%d", offset, length) << endm;
647  break;
648 
649  default:
650  LOG_ERROR << Form("Unknown transfer data index=%d", index) << endm;
651  return 0;
652  }
653 
654  return (char*)trgtowertrnfer + offset;
655  }
656 
657  default :
658  LOG_INFO << Form("Trigger transfer version 0x%02x. No EMC data in trigger banks.", version) << endm;
659  return 0;
660  }
661 
662  return 0;
663 }
664 
void version(std::ostream &os=std::cout)
print HepMC version
Definition: Version.h:27
Definition: daq_emc.h:52
u_short * esmd_raw
ESMD preamble.
Definition: daq_emc.h:96
u_short esmd_pre[ESMD_MAXFEE][ESMD_PRESIZE]
ADC data.
Definition: daq_emc.h:95