CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HcalUnpacker.cc
Go to the documentation of this file.
12 
13 //#define DebugLog
14 
15 namespace HcalUnpacker_impl {
16  template <class DigiClass>
17  const HcalQIESample* unpack(const HcalQIESample* startPoint, const HcalQIESample* limit, DigiClass& digi, int presamples, const HcalElectronicsId& eid, int startSample, int endSample, int expectedTime, const HcalHTRData& hhd) {
18  // set parameters
19  digi.setPresamples(presamples);
20  digi.setReadoutIds(eid);
21 
22  int fiber=startPoint->fiber();
23  int fiberchan=startPoint->fiberChan();
24  uint32_t zsmask=hhd.zsBunchMask()>>startSample;
25  digi.setZSInfo(hhd.isUnsuppressed(),hhd.wasMarkAndPassZS(fiber,fiberchan),zsmask);
26 
27  if (expectedTime>=0 && !hhd.isUnsuppressed()) {
28 #ifdef DebugLog
29  std::cout << hhd.getFibOrbMsgBCN(fiber) << " " << expectedTime << std::endl;
30 #endif
31  digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber)-expectedTime);
32  }
33 
34  // what is my sample number?
35  int myFiberChan=startPoint->fiberAndChan();
36  int ncurr=0,ntaken=0;
37  const HcalQIESample* qie_work=startPoint;
38  while (qie_work!=limit && qie_work->fiberAndChan()==myFiberChan) {
39  if (ncurr>=startSample && ncurr<=endSample) {
40  digi.setSample(ntaken,*qie_work);
41  ++ntaken;
42  }
43  ncurr++;
44  qie_work++;
45  }
46  digi.setSize(ntaken);
47  return qie_work;
48  }
49 
50 
51  template <class DigiClass>
52  const unsigned short* unpack_compact(const unsigned short* startPoint, const unsigned short* limit, DigiClass& digi,
53  int presamples, const HcalElectronicsId& eid, int startSample, int endSample,
54  int expectedTime, const HcalHTRData& hhd) {
55  // set parameters
56  digi.setPresamples(presamples);
57  digi.setReadoutIds(eid);
58  int flavor, error_flags, capid0, channelid;
59 
60  HcalHTRData::unpack_per_channel_header(*startPoint,flavor,error_flags,capid0,channelid);
61  bool isCapRotating=!(error_flags&0x1);
62  bool fiberErr=(error_flags&0x2);
63  bool dataValid=!(error_flags&0x2);
64  int fiberchan=channelid&0x3;
65  int fiber=((channelid>>2)&0x7)+1;
66 
67  uint32_t zsmask=hhd.zsBunchMask()>>startSample;
68  digi.setZSInfo(hhd.isUnsuppressed(),hhd.wasMarkAndPassZS(fiber,fiberchan),zsmask);
69 
70  if (expectedTime>=0 && !hhd.isUnsuppressed()) {
71 #ifdef DebugLog
72  std::cout << hhd.getFibOrbMsgBCN(fiber) << " " << expectedTime << std::endl;
73 #endif
74  digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber)-expectedTime);
75  }
76 
77  // what is my sample number?
78  int ncurr=0,ntaken=0;
79  const unsigned short* qie_work=startPoint;
80  // we branch here between normal (flavor=5) and error mode (flavor=6)
81  if (flavor==5) {
82  for (qie_work++; qie_work!=limit && !HcalHTRData::is_channel_header(*qie_work); qie_work++) {
83  int capidn=(isCapRotating)?((capid0+ncurr)%4):(capid0);
84  int capidn1=(isCapRotating)?((capid0+ncurr+1)%4):(capid0);
85  // two samples in one...
86  HcalQIESample s0((*qie_work)&0x7F,capidn,fiber,fiberchan,dataValid,fiberErr);
87  HcalQIESample s1(((*qie_work)>>8)&0x7F,capidn1,fiber,fiberchan,dataValid,fiberErr);
88 
89  if (ncurr>=startSample && ncurr<=endSample) {
90  digi.setSample(ntaken,s0);
91  ++ntaken;
92  }
93  ncurr++;
94  if (ncurr>=startSample && ncurr<=endSample) {
95  digi.setSample(ntaken,s1);
96  ++ntaken;
97  }
98  ncurr++;
99  }
100  digi.setSize(ntaken);
101  } else if (flavor==6) {
102  for (qie_work++; qie_work!=limit && !HcalHTRData::is_channel_header(*qie_work); qie_work++) {
103  if (ncurr>=startSample && ncurr<=endSample) {
104  HcalQIESample sample((*qie_work)&0x7F,((*qie_work)>>8)&0x3,fiber,fiberchan,((*qie_work)>>10)&0x1,((*qie_work)>>11)&0x1);
105  digi.setSample(ntaken,sample);
106  ++ntaken;
107  }
108  ncurr++;
109  }
110  digi.setSize(ntaken);
111  } else {
112  edm::LogWarning("Bad Data") << "Invalid flavor " << flavor;
113  qie_work=limit;
114  }
115  return qie_work;
116  }
117 
118  template <class DigiClass>
120  int presamples, const HcalElectronicsId& eid, int startSample, int endSample) {
121  // set parameters
122  digi.setPresamples(presamples-startSample);
123  digi.setReadoutIds(eid);
124  int error_flags=i.errFlags();
125  int capid0=i.capid0();
126 
127  bool isCapRotating=!(error_flags&0x1);
128  bool fiberErr=(error_flags&0x2);
129  bool dataValid=!(error_flags&0x2);
130  int fiberchan=i.channelid()&0x3;
131  int fiber=((i.channelid()>>2)&0x7)+1;
132 
133  // digi.setZSInfo(hhd.isUnsuppressed(),hhd.wasMarkAndPassZS(fiber,fiberchan),zsmask);
134 
135  // what is my sample number?
136  int ncurr=0,ntaken=0;
137  for (++i; i!=iend && !i.isHeader(); ++i) {
138  int capidn=(isCapRotating)?((capid0+ncurr)%4):(capid0);
139 
140  HcalQIESample s(i.adc(),capidn,fiber,fiberchan,dataValid,fiberErr);
141 
142  if (ncurr>=startSample && ncurr<=endSample) {
143  digi.setSample(ntaken,s);
144  ++ntaken;
145  }
146  ncurr++;
147  }
148  digi.setSize(ntaken);
149  }
150 }
151 
152 
153 static inline bool isTPGSOI(const HcalTriggerPrimitiveSample& s) {
154  return (s.raw()&0x200)!=0;
155 }
156 
157 
158 struct HOUnrolledTP { // parts of an HO trigger primitive, unpacked
159  bool valid, checked;
161  unsigned int databits;
163  valid=false;
164  checked=false;
165  ieta=0;
166  iphi=0;
167  samples=0;
168  soi=0;
169  databits=0;
170  }
171  void setbit(int i) { databits|=(1<<i); }
172 };
173 
175  Collections& colls, HcalUnpackerReport& report, bool silent) {
176 
177  if (raw.size()<16) {
178  if (!silent) edm::LogWarning("Invalid Data") << "Empty/invalid data, size = " << raw.size();
179  return;
180  }
181 
182  // get the DCC header
183  const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
184 
185  if (dccHeader->BOEshouldBeZeroAlways()==0) // also includes uTCA before the common AMC13XG firmware
186  unpackVME(raw,emap,colls,report,silent);
187  else unpackUTCA(raw,emap,colls,report,silent);
188 }
189 
190 static int slb(uint16_t theSample) { return ((theSample>>13)&0x7); }
191 static int slbChan(uint16_t theSample) { return (theSample>>11)&0x3; }
192 static int slbAndChan(uint16_t theSample) { return (theSample>>11)&0x1F; }
193 
194 
196  Collections& colls, HcalUnpackerReport& report, bool silent) {
197 
198  // get the DCC header
199  const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
200  const HcalDTCHeader* dtcHeader=(const HcalDTCHeader*)(raw.data());
201  bool is_VME_DCC=(dccHeader->getDCCDataFormatVersion()<0x10) || ((mode_&0x1)==0);
202 
203  int dccid=(is_VME_DCC)?(dccHeader->getSourceId()-sourceIdOffset_):(dtcHeader->getSourceId()-sourceIdOffset_);
204 
205  // check the summary status
206 
207  // walk through the HTR data. For the uTCA, use spigot=slot+1
208  HcalHTRData htr;
209  const unsigned short* daq_first, *daq_last, *tp_first, *tp_last;
210  const HcalQIESample* qie_begin, *qie_end, *qie_work;
211  const HcalTriggerPrimitiveSample *tp_begin, *tp_end, *tp_work;
212  for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
213 
214  if (is_VME_DCC) {
215  if (!dccHeader->getSpigotPresent(spigot)) continue;
216 
217  int retval=dccHeader->getSpigotData(spigot,htr,raw.size());
218  if (retval!=0) {
219  if (retval==-1) {
220  if (!silent) edm::LogWarning("Invalid Data") << "Invalid HTR data (data beyond payload size) observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
221  report.countSpigotFormatError();
222  }
223  continue;
224  }
225  // check
226  if (dccHeader->getSpigotCRCError(spigot)) {
227  if (!silent)
228  edm::LogWarning("Invalid Data") << "CRC Error on HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
229  report.countSpigotFormatError();
230  continue;
231  }
232  } else { // is_uTCA (!is_VME_DCC)
233  int slot=spigot+1;
234  if (slot>HcalDTCHeader::MAXIMUM_SLOT) continue;
235 
236  if (!dtcHeader->getSlotPresent(slot)) continue;
237 
238  int retval=dtcHeader->getSlotData(slot,htr,raw.size());
239  if (retval!=0) {
240  if (retval==-1) {
241  if (!silent) edm::LogWarning("Invalid Data") << "Invalid uHTR data (data beyond payload size) observed on slot " << slot << " of DTC with source id " << dtcHeader->getSourceId();
242  report.countSpigotFormatError();
243  }
244  continue;
245  }
246  // check
247  if (dtcHeader->getSlotCRCError(slot)) {
248  if (!silent)
249  edm::LogWarning("Invalid Data") << "CRC Error on uHTR data observed on slot " << slot << " of DTC with source id " << dtcHeader->getSourceId();
250  report.countSpigotFormatError();
251  continue;
252  }
253  }
254 
255 
256  // check for EE
257  if (htr.isEmptyEvent()) {
258  report.countEmptyEventSpigot();
259  }
260  if (htr.isOverflowWarning()) {
261  report.countOFWSpigot();
262  }
263  if (htr.isBusy()) {
264  report.countBusySpigot();
265  }
266  if (!htr.check()) {
267  if (!silent)
268  edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
269  report.countSpigotFormatError();
270  continue;
271  }
272  if (htr.isHistogramEvent()) {
273  if (!silent) edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
274  continue;
275  }
276  if ((htr.getFirmwareFlavor()&0xE0)==0x80) { // some kind of TTP data
277  if (colls.ttp!=0) {
278  HcalTTPUnpacker ttpUnpack;
279  colls.ttp->push_back(HcalTTPDigi());
280  ttpUnpack.unpack(htr,colls.ttp->back());
281  } else {
282  LogDebug("HcalTechTrigProcessor") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is from the TechTrigProcessor (use separate unpacker!)";
283  }
284  continue;
285  }
286  if (htr.getFirmwareFlavor()>=0x80) {
287  if (!silent) edm::LogWarning("HcalUnpacker") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is of unknown flavor " << htr.getFirmwareFlavor();
288  continue;
289  }
290 
291  // calculate "real" number of presamples
292  int nps=htr.getNPS()-startSample_;
293 
294  // get pointers
295  htr.dataPointers(&daq_first,&daq_last,&tp_first,&tp_last);
296  unsigned int smid=htr.getSubmodule();
297  int htr_tb=smid&0x1;
298  int htr_slot=(smid>>1)&0x1F;
299  int htr_cr=(smid>>6)&0x1F;
300 
301  tp_begin=(HcalTriggerPrimitiveSample*)tp_first;
302  tp_end=(HcalTriggerPrimitiveSample*)(tp_last+1); // one beyond last..
303 
305  int currFiberChan=0x3F; // invalid fiber+channel...
306  int ncurr=0;
307  bool valid=false;
308 
309  bool tpgSOIbitInUse=htr.getFormatVersion()>=3; // version 3 and later
310  bool isHOtpg=htr.getFormatVersion()>=3 && htr.getFirmwareFlavor()==0; // HO is flavor zero
311  int npre=0;
312  /*
313  Unpack the trigger primitives
314  */
315  if (isHOtpg) {
316  HOUnrolledTP unrolled[24];
317  for (tp_work=tp_begin; tp_work!=tp_end; tp_work++) {
318  if (tp_work->raw()==0xFFFF) continue; // filler word
319  int sector=slbChan(tp_work->raw());
320  if (sector>2) continue;
321 
322  for (int ibit=0; ibit<8; ibit++) {
323  int linear=sector*8+ibit;
324  if (!unrolled[linear].checked) {
325  unrolled[linear].checked=true;
326  int fiber=(linear/3)+1;
327  int fc=(linear%3);
328  // electronics id (use precision match for HO TP)
329  HcalElectronicsId eid(fc,fiber,spigot,dccid);
330  eid.setHTR(htr_cr,htr_slot,htr_tb);
331  DetId did=emap.lookup(eid);
332  if (!did.null()) {
333  if (did.det()==DetId::Hcal && ((HcalSubdetector)did.subdetId())==HcalOuter ) {
334  HcalDetId hid(did);
335  unrolled[linear].valid=true;
336  unrolled[linear].ieta=hid.ieta();
337  unrolled[linear].iphi=hid.iphi();
338  }
339  } else {
340  report.countUnmappedTPDigi(eid);
341  }
342  }
343  if (unrolled[linear].valid) {
344  if (isTPGSOI(*tp_work)) unrolled[linear].soi=unrolled[linear].samples;
345  if (tp_work->raw()&(1<<ibit)) unrolled[linear].setbit(unrolled[linear].samples);
346  unrolled[linear].samples++;
347  }
348  }
349  }
350  for (int i=0; i<24; i++) {
351  if (unrolled[i].valid)
352  colls.tphoCont->push_back(HOTriggerPrimitiveDigi(
353  unrolled[i].ieta,
354  unrolled[i].iphi,
355  unrolled[i].samples,
356  unrolled[i].soi,
357  unrolled[i].databits));
358  }
359  } else { // regular TPs (not HO)
360  for (tp_work=tp_begin; tp_work!=tp_end; tp_work++) {
361  if (tp_work->raw()==0xFFFF) continue; // filler word
362  if (slbAndChan(tp_work->raw())!=currFiberChan) { // start new set
363  npre=0;
364  currFiberChan=slbAndChan(tp_work->raw());
365  // lookup the right channel
366  HcalElectronicsId eid(slbChan(tp_work->raw()),slb(tp_work->raw()),spigot,dccid,htr_cr,htr_slot,htr_tb);
367  DetId did=emap.lookupTrigger(eid);
368  if (did.null()) {
369  report.countUnmappedTPDigi(eid);
370  if (unknownIdsTrig_.find(eid)==unknownIdsTrig_.end()) {
371  if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
372  unknownIdsTrig_.insert(eid);
373  }
374  valid=false;
375  continue;
376  } else if (did==HcalTrigTowerDetId::Undefined ||
377  (did.det()==DetId::Hcal && did.subdetId()==0)) {
378  // known to be unmapped
379  valid=false;
380  continue;
381  }
382  HcalTrigTowerDetId id(did);
383  colls.tpCont->push_back(HcalTriggerPrimitiveDigi(id));
384  // set the various bits
385  if (!tpgSOIbitInUse) colls.tpCont->back().setPresamples(nps);
386  colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),htr.wasMarkAndPassZSTP(slb(tp_work->raw()),slbChan(tp_work->raw())));
387 
388  // no hits recorded for current
389  ncurr=0;
390  valid=true;
391  }
392  // add the word (if within settings or recent firmware [recent firmware ignores startSample/endSample])
393  if (valid && ((tpgSOIbitInUse && ncurr<10) || (ncurr>=startSample_ && ncurr<=endSample_))) {
394  colls.tpCont->back().setSample(colls.tpCont->back().size(),*tp_work);
395  colls.tpCont->back().setSize(colls.tpCont->back().size()+1);
396  }
397  // set presamples,if SOI
398  if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
399  colls.tpCont->back().setPresamples(ncurr);
400  }
401  ncurr++;
402  npre++;
403  }
404  }
405 
408 
409  qie_begin=(HcalQIESample*)daq_first;
410  qie_end=(HcalQIESample*)(daq_last+1); // one beyond last..
411 
413  currFiberChan=0x3F; // invalid fiber+channel...
414  ncurr=0;
415  valid=false;
416 
417 
418  for (qie_work=qie_begin; qie_work!=qie_end; ) {
419  if (qie_work->raw()==0xFFFF) {
420  qie_work++;
421  continue; // filler word
422  }
423  // always at the beginning ...
424  currFiberChan=qie_work->fiberAndChan();
425 
426  // lookup the right channel
427  HcalElectronicsId eid(qie_work->fiberChan(),qie_work->fiber(),spigot,dccid);
428  eid.setHTR(htr_cr,htr_slot,htr_tb);
429  DetId did=emap.lookup(eid);
430 
431  if (!did.null()) {
432  if (did.det()==DetId::Calo && did.subdetId()==HcalZDCDetId::SubdetectorId) {
433  colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
434  qie_work=HcalUnpacker_impl::unpack<ZDCDataFrame>(qie_work, qie_end, colls.zdcCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
435  } else if (did.det()==DetId::Hcal) {
436  switch (((HcalSubdetector)did.subdetId())) {
437  case (HcalBarrel):
438  case (HcalEndcap): {
439  colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
440  qie_work=HcalUnpacker_impl::unpack<HBHEDataFrame>(qie_work, qie_end, colls.hbheCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
441  } break;
442  case (HcalOuter): {
443  colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
444  qie_work=HcalUnpacker_impl::unpack<HODataFrame>(qie_work, qie_end, colls.hoCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
445  } break;
446  case (HcalForward): {
447  colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
448  qie_work=HcalUnpacker_impl::unpack<HFDataFrame>(qie_work, qie_end, colls.hfCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
449  } break;
450  case (HcalOther) : {
451  HcalOtherDetId odid(did);
452  if (odid.subdet()==HcalCalibration) {
453  colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
454  qie_work=HcalUnpacker_impl::unpack<HcalCalibDataFrame>(qie_work, qie_end, colls.calibCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
455  }
456  } break;
457  case (HcalEmpty):
458  default: {
459  for (int fiberC=qie_work->fiberAndChan();
460  qie_work!=qie_end && qie_work->fiberAndChan()==fiberC;
461  qie_work++);
462  }
463  break;
464  }
465  }
466  } else {
467  report.countUnmappedDigi(eid);
468  if (unknownIds_.find(eid)==unknownIds_.end()) {
469  if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
470  unknownIds_.insert(eid);
471  }
472  for (int fiberC=qie_work->fiberAndChan();
473  qie_work!=qie_end && qie_work->fiberAndChan()==fiberC;
474  qie_work++);
475  }
476  }
477  } else {
478  // this is the branch for unpacking the compact data format with per-channel headers
479  const unsigned short* ptr_header=daq_first;
480  const unsigned short* ptr_end=daq_last+1;
481  int flavor, error_flags, capid0, channelid;
482 
483  while (ptr_header!=ptr_end) {
484  if (*ptr_header==0xFFFF) { // impossible filler word
485  ptr_header++;
486  continue;
487  }
488  // unpack the header word
489  bool isheader=HcalHTRData::unpack_per_channel_header(*ptr_header,flavor,error_flags,capid0,channelid);
490  if (!isheader) {
491  ptr_header++;
492  continue;
493  }
494 
495  int fiberchan=channelid&0x3;
496  int fiber=((channelid>>2)&0x7)+1;
497 
498  // lookup the right channel
499  HcalElectronicsId eid(fiberchan,fiber,spigot,dccid);
500  eid.setHTR(htr_cr,htr_slot,htr_tb);
501  DetId did=emap.lookup(eid);
502 
503  if (!did.null()) {
504  if (did.det()==DetId::Calo && did.subdetId()==HcalZDCDetId::SubdetectorId) {
505  colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
506  ptr_header=HcalUnpacker_impl::unpack_compact<ZDCDataFrame>(ptr_header, ptr_end, colls.zdcCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
507  } else if (did.det()==DetId::Hcal) {
508  switch (((HcalSubdetector)did.subdetId())) {
509  case (HcalBarrel):
510  case (HcalEndcap): {
511  colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
512  ptr_header=HcalUnpacker_impl::unpack_compact<HBHEDataFrame>(ptr_header, ptr_end, colls.hbheCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
513  } break;
514  case (HcalOuter): {
515  colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
516  ptr_header=HcalUnpacker_impl::unpack_compact<HODataFrame>(ptr_header, ptr_end, colls.hoCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
517  } break;
518  case (HcalForward): {
519  colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
520  ptr_header=HcalUnpacker_impl::unpack_compact<HFDataFrame>(ptr_header, ptr_end, colls.hfCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
521  } break;
522  case (HcalOther) : {
523  HcalOtherDetId odid(did);
524  if (odid.subdet()==HcalCalibration) {
525  colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
526  ptr_header=HcalUnpacker_impl::unpack_compact<HcalCalibDataFrame>(ptr_header, ptr_end, colls.calibCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
527  }
528  } break;
529  case (HcalEmpty):
530  default: {
531  for (ptr_header++;
532  ptr_header!=ptr_end && !HcalHTRData::is_channel_header(*ptr_header);
533  ptr_header++);
534  }
535  break;
536  }
537  }
538  } else {
539  report.countUnmappedDigi(eid);
540  if (unknownIds_.find(eid)==unknownIds_.end()) {
541  if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
542  unknownIds_.insert(eid);
543  }
544  for (ptr_header++;
545  ptr_header!=ptr_end && !HcalHTRData::is_channel_header(*ptr_header);
546  ptr_header++);
547  }
548  }
549 
550  }
551  }
552 }
553 
555  Collections& colls, HcalUnpackerReport& report, bool silent) {
556 
557  const hcal::AMC13Header* amc13=(const hcal::AMC13Header*)(raw.data());
558 
559  // how many AMC in this packet
560  int namc=amc13->NAMC();
561  for (int iamc=0; iamc<namc; iamc++) {
562  // if not enabled, ignore
563  if (!amc13->AMCEnabled(iamc)) continue;
564 
565  if (!amc13->AMCDataPresent(iamc)) {
566  if (!silent)
567  edm::LogWarning("Invalid Data") << "Missing data observed on iamc " << iamc << " of AMC13 with source id " << amc13->sourceId();
568  report.countSpigotFormatError();
569  continue;
570  }
571  if (!amc13->AMCCRCOk(iamc)) {
572  if (!silent)
573  edm::LogWarning("Invalid Data") << "CRC Error on uHTR data observed on iamc " << iamc << " of AMC13 with source id " << amc13->sourceId();
574  report.countSpigotFormatError();
575  // continue;
576  }
577  // this unpacker cannot handle segmented data!
578  if (amc13->AMCSegmented(iamc)) {
579  if (!silent)
580  edm::LogWarning("Invalid Data") << "Unpacker cannot handle segmented data observed on iamc " << iamc << " of AMC13 with source id " << amc13->sourceId();
581  report.countSpigotFormatError();
582  continue;
583  }
584 
585  // ok, now we're work-able
586  int slot=amc13->AMCSlot(iamc);
587  int crate=amc13->AMCId(iamc)&0xFF;
588  // this is used only for the 1.6 Gbps link data
589  int nps=(amc13->AMCId(iamc)>>12)&0xF;
590 
591  HcalUHTRData uhtr(amc13->AMCPayload(iamc),amc13->AMCSize(iamc));
592  //Check to make sure uMNio is not unpacked here
593  if(uhtr.getFormatVersion() != 1) {
594  unpackUMNio(raw, slot, colls);
595  }
596 #ifdef DebugLog
597  //debug printouts
598  int nwords=uhtr.getRawLengthBytes()/2;
599  for (int iw=0; iw<nwords; iw++)
600  printf("%04d %04x\n",iw,uhtr.getRawData16()[iw]);
601 #endif
602 
603  HcalUHTRData::const_iterator i=uhtr.begin(), iend=uhtr.end();
604  while (i!=iend) {
605 #ifdef DebugLog
606  std::cout << "This data is flavored:" << i.flavor() << std::endl;
607 #endif
608 
609  if (!i.isHeader()) {
610  ++i;
611 #ifdef DebugLog
612  std::cout << "its not a header" << std::endl;
613 #endif
614  continue;
615  }
617  if (i.flavor() == 1 || i.flavor() == 0) {
618  int ifiber=((i.channelid()>>3)&0x1F);
619  int ichan=(i.channelid()&0x7);
620  HcalElectronicsId eid(crate,slot,ifiber,ichan, false);
621  DetId did=emap.lookup(eid);
622  // Count from current position to next header, or equal to end
623  const uint16_t* head_pos = i.raw();
624  int ns = 0;
625  for (++i; i != iend && !i.isHeader(); ++i) {
626  ns++;
627  }
628  // Check QEI11 container exists
629  if (colls.qie11 == 0) {
630  colls.qie11 = new QIE11DigiCollection(ns);
631  }
632  else if (colls.qie11->samples() != ns) {
633  // This is horrible
634  edm::LogError("Invalid Data") << "Collection has " << colls.qie11->samples() << " samples per digi, raw data has " << ns << "!";
635  return;
636  }
637 
638  // Insert data
640  if (!did.null()) { // unpack and store...
641  colls.qie11->addDataFrame(did, head_pos);
642  } else {
643  report.countUnmappedDigi(eid);
644  if (unknownIds_.find(eid)==unknownIds_.end()) {
645  if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
646  unknownIds_.insert(eid);
647 #ifdef DebugLog
648  std::cout << "HcalUnpacker: No match found for electronics id :" << eid << std::endl;
649 #endif
650  }
651 #ifdef DebugLog
652  std::cout << "OH NO! detector id is null!" << std::endl;
653 #endif
654  }
655  } else if (i.flavor() == 2){
657 
658  int ifiber=((i.channelid()>>3)&0x1F);
659  int ichan=(i.channelid()&0x7);
660  HcalElectronicsId eid(crate,slot,ifiber,ichan, false);
661  DetId did=emap.lookup(eid);
662 
663  // Count from current position to next header, or equal to end
664  const uint16_t* head_pos = i.raw();
665  int ns = 0;
666  for (++i; i != iend && !i.isHeader(); ++i) {
667  ns++;
668  }
669 
670  // Check QEI10 container exists
671  if (colls.qie10ZDC == 0) {
672  colls.qie10ZDC = new QIE10DigiCollection(ns);
673  }
674  else if (colls.qie10ZDC->samples() != ns) {
675  // This is horrible
676  edm::LogError("Invalid Data") << "Collection has " << colls.qie10ZDC->samples() << " samples per digi, raw data has " << ns << "!";
677  return;
678  }
679 
680  if (colls.qie10 == 0) {
681  colls.qie10 = new QIE10DigiCollection(ns);
682  }
683  else if (colls.qie10->samples() != ns) {
684  // This is horrible
685  edm::LogError("Invalid Data") << "Collection has " << colls.qie10->samples() << " samples per digi, raw data has " << ns << "!";
686  return;
687  }
688 
689  // Insert data
691  if (!did.null() && did.det()==DetId::Calo && did.subdetId()==HcalZDCDetId::SubdetectorId) { // unpack and store...
692  colls.qie10ZDC->addDataFrame(did, head_pos);
693  }
694  else if (!did.null()) { // unpack and store...
695  colls.qie10->addDataFrame(did, head_pos);
696  } else {
697  report.countUnmappedDigi(eid);
698  if (unknownIds_.find(eid)==unknownIds_.end()) {
699  if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
700  unknownIds_.insert(eid);
701 #ifdef DebugLog
702  std::cout << "HcalUnpacker: No match found for electronics id :" << eid << std::endl;
703 #endif
704  }
705 #ifdef DebugLog
706  std::cout << "OH NO! HcalUnpacker: No match found for electronics id :" << eid << std::endl;
707 #endif
708  }
709  }
710  else if (i.flavor()==0x5) { // Old-style digis
711  int ifiber=((i.channelid()>>2)&0x1F);
712  int ichan=(i.channelid()&0x3);
713  HcalElectronicsId eid(crate,slot,ifiber,ichan, false);
714  DetId did=emap.lookup(eid);
715 
716  if (!did.null()) { // unpack and store...
717  if (did.det()==DetId::Calo && did.subdetId()==HcalZDCDetId::SubdetectorId) {
718  colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
719  HcalUnpacker_impl::unpack_compact<ZDCDataFrame>(i,iend, colls.zdcCont->back(), nps, eid, startSample_, endSample_);
720  } else if (did.det()==DetId::Hcal) {
721  switch (((HcalSubdetector)did.subdetId())) {
722  case (HcalBarrel):
723  case (HcalEndcap): {
724  colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
725  HcalUnpacker_impl::unpack_compact<HBHEDataFrame>(i, iend, colls.hbheCont->back(), nps, eid, startSample_, endSample_);
726  } break;
727  case (HcalOuter): {
728  colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
729  HcalUnpacker_impl::unpack_compact<HODataFrame>(i, iend, colls.hoCont->back(), nps, eid, startSample_, endSample_);
730  } break;
731  case (HcalForward): {
732  colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
733  HcalUnpacker_impl::unpack_compact<HFDataFrame>(i, iend, colls.hfCont->back(), nps, eid, startSample_, endSample_);
734  } break;
735  case (HcalOther) : {
736  HcalOtherDetId odid(did);
737  if (odid.subdet()==HcalCalibration) {
738  colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
739  HcalUnpacker_impl::unpack_compact<HcalCalibDataFrame>(i, iend, colls.calibCont->back(), nps, eid, startSample_, endSample_);
740  }
741  } break;
742  case (HcalEmpty):
743  default: {
744  for (++i;
745  i!=iend && !i.isHeader();
746  ++i);
747  }
748  break;
749  }
750  }
751  } else {
752  report.countUnmappedDigi(eid);
753  if (unknownIds_.find(eid)==unknownIds_.end()) {
754  if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
755  unknownIds_.insert(eid);
756  }
757  for (++i;
758  i!=iend && !i.isHeader();
759  ++i);
760  }
761  } else if (i.flavor()==0x4) { // TP digis
762  int ilink=((i.channelid()>>4)&0xF);
763  int itower=(i.channelid()&0xF);
764  HcalElectronicsId eid(crate,slot,ilink,itower,true);
765  DetId did=emap.lookupTrigger(eid);
766 #ifdef DebugLog
767  std::cout << "Unpacking " << eid << " " << i.channelid() << std::endl;
768 #endif
769  if (did.null()) {
770  report.countUnmappedTPDigi(eid);
771  if (unknownIdsTrig_.find(eid)==unknownIdsTrig_.end()) {
772  if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
773  unknownIdsTrig_.insert(eid);
774  }
775  // Skip it
776  for (++i; i!=iend && !i.isHeader(); ++i);
777  } else if (did==HcalTrigTowerDetId::Undefined ||
778  (did.det()==DetId::Hcal && did.subdetId()==0)) {
779  for (++i; i!=iend && !i.isHeader(); ++i);
780  } else {
781  HcalTrigTowerDetId id(did);
782 #ifdef DebugLog
783  std::cout << "Unpacking " << id << std::endl;
784 #endif
785  colls.tpCont->push_back(HcalTriggerPrimitiveDigi(id));
786  int j=0;
787  for (++i; i!=iend && !i.isHeader(); ++i) {
788  colls.tpCont->back().setSample(j,i.value());
789  if (i.soi()) colls.tpCont->back().setPresamples(j);
790  j++;
791  }
792  colls.tpCont->back().setSize(j);
793  }
794  } else {
795  // consume any not-understood channel data
796  for (++i;
797  i!=iend && !i.isHeader();
798  ++i);
799  }
800  }
801  }
802 }
803 
805  hbheCont=0;
806  hoCont=0;
807  hfCont=0;
808  tpCont=0;
809  zdcCont=0;
810  calibCont=0;
811  ttp=0;
812  qie10=0;
813  qie10ZDC=0;
814  qie11=0;
815  umnio=0;
816 }
817 
818 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HcalHistogramDigi>& histoDigis) {
819 
820  // get the DCC header
821  const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
822  int dccid=dccHeader->getSourceId()-sourceIdOffset_;
823 
824  // check the summary status
825 
826  // walk through the HTR data...
827  HcalHTRData htr;
828  for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
829  if (!dccHeader->getSpigotPresent(spigot)) continue;
830 
831  int retval=dccHeader->getSpigotData(spigot,htr,raw.size());
832  // check
833  if (retval || !htr.check()) {
834  edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
835  continue;
836  }
837  if (!htr.isHistogramEvent()) {
838  edm::LogWarning("Invalid Data") << "Non-histogram data passed to histogram unpacker on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
839  continue;
840  }
841 
842  unsigned int smid=htr.getSubmodule();
843  int htr_tb=smid&0x1;
844  int htr_slot=(smid>>1)&0x1F;
845  int htr_cr=(smid>>6)&0x1F;
846 
847  // find out the fibers
848  int f[2],fc;
849  htr.getHistogramFibers(f[0],f[1]);
850 
851  for (int nf=0; nf<2; nf++) {
852  if (f[nf]<0 || (nf==1 && f[0]==f[1])) continue; // skip if invalid or the same
853  for (fc=0; fc<=2; fc++) {
854  HcalElectronicsId eid(fc,f[nf],spigot,dccid);
855  eid.setHTR(htr_cr,htr_slot,htr_tb);
856  DetId did=emap.lookup(eid);
857 
858  if (did.null() || did.det()!=DetId::Hcal || did.subdetId()==0) {
859  if (unknownIds_.find(eid)==unknownIds_.end()) {
860  edm::LogWarning("HCAL") << "HcalHistogramUnpacker: No match found for electronics id :" << eid;
861  unknownIds_.insert(eid);
862  }
863  continue;
864  }
865  histoDigis.push_back(HcalHistogramDigi(HcalDetId(did))); // add it!
866  HcalHistogramDigi& digi=histoDigis.back();
867 
868  // unpack the four capids
869  for (int capid=0; capid<4; capid++)
870  htr.unpackHistogram(f[nf],fc,capid,digi.getArray(capid));
871 
872  }
873  }
874  }
875 }
876 // Method to unpack uMNio data
877 void HcalUnpacker::unpackUMNio(const FEDRawData& raw, int slot, Collections& colls) {
878  const hcal::AMC13Header* amc13=(const hcal::AMC13Header*)(raw.data());
879  int namc=amc13->NAMC();
880  //Find AMC corresponding to uMNio slot
881  for (int iamc=0; iamc<namc; iamc++) {
882  if (amc13->AMCSlot(iamc) == slot) namc = iamc;
883  }
884  if (namc==amc13->NAMC()) {
885  return;
886  }
887  const uint16_t* data = (const uint16_t*)(amc13->AMCPayload(namc));
888  size_t nwords = amc13->AMCSize(namc) * ( sizeof(uint64_t) / sizeof(uint16_t) );
889  *(colls.umnio) = HcalUMNioDigi(data, nwords);
890 
891 }
#define LogDebug(id)
int getSourceId() const
Definition: HcalDTCHeader.h:35
int i
Definition: DBlmapReader.cc:9
std::set< HcalElectronicsId > unknownIds_
Definition: HcalUnpacker.h:60
int sourceIdOffset_
number to subtract from the source id to get the dcc id
Definition: HcalUnpacker.h:55
int endSample_
last sample from fed raw data to copy (if present)
Definition: HcalUnpacker.h:57
int startSample_
first sample from fed raw data to copy
Definition: HcalUnpacker.h:56
uint16_t raw() const
get the raw word
Definition: HcalQIESample.h:20
bool check() const
Check for a good event Requires a minimum length, matching wordcount and length, not an empty event...
Definition: HcalHTRData.cc:62
static int slbAndChan(uint16_t theSample)
void unpackUTCA(const FEDRawData &raw, const HcalElectronicsMap &emap, Collections &conts, HcalUnpackerReport &report, bool silent=false)
std::vector< HcalTTPDigi > * ttp
Definition: HcalUnpacker.h:33
std::vector< HFDataFrame > * hfCont
Definition: HcalUnpacker.h:28
int fiberAndChan() const
get the id channel
Definition: HcalQIESample.h:36
HcalUMNioDigi * umnio
Definition: HcalUnpacker.h:37
int fiberChan() const
get the fiber channel number
Definition: HcalQIESample.h:34
bool getSpigotCRCError(unsigned int nspigot) const
Read the &quot;CRC-Mismatch&quot; bit for this spigot.
void addDataFrame(DetId detid, const uint16_t *data)
uint16_t value() const
Definition: HcalUHTRData.h:50
static bool isTPGSOI(const HcalTriggerPrimitiveSample &s)
const unsigned short * unpack_compact(const unsigned short *startPoint, const unsigned short *limit, DigiClass &digi, int presamples, const HcalElectronicsId &eid, int startSample, int endSample, int expectedTime, const HcalHTRData &hhd)
Definition: HcalUnpacker.cc:52
std::vector< HBHEDataFrame > * hbheCont
Definition: HcalUnpacker.h:26
std::vector< HOTriggerPrimitiveDigi > * tphoCont
Definition: HcalUnpacker.h:32
bool wasMarkAndPassZS(int fiber, int fiberchan) const
Was this channel passed as part of Mark&amp;Pass ZS?
Definition: HcalHTRData.cc:356
unsigned int getFibOrbMsgBCN(int fiber) const
Get the BCN of the Fiber Orbit Messages.
Definition: HcalHTRData.h:178
static bool unpack_per_channel_header(unsigned short, int &flav, int &error_flags, int &capid0, int &channelid)
Unpack a per-channel header word (compact format)
Definition: HcalHTRData.cc:433
void getHistogramFibers(int &a, int &b) const
Get the fiber numbers for the data present in this event (only in histogram mode!) ...
Definition: HcalHTRData.cc:413
int getSpigotData(int nspigot, HcalHTRData &decodeTool, int validSize) const
int getFormatVersion() const
Get the version number of this event.
Definition: HcalHTRData.h:33
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:47
int AMCSize(int i) const
Definition: AMC13Header.h:37
HcalDataFrameContainer< QIE10DataFrame > QIE10DigiCollection
bool isUnsuppressed() const
Is this event an unsuppresed event?
Definition: HcalHTRData.cc:353
tuple report
Definition: zeeHLT_cff.py:9
bool isOverflowWarning() const
Definition: HcalHTRData.cc:109
bool unpackHistogram(int fiber, int fiberchan, int capid, unsigned short *histogram) const
Unpack special histogramming mode data.
Definition: HcalHTRData.cc:441
static bool is_channel_header(unsigned short value)
check top bit to see if this is a compact format channel header word
Definition: HcalHTRData.h:90
QIE10DigiCollection * qie10ZDC
Definition: HcalUnpacker.h:35
int expectedOrbitMessageTime_
Expected orbit bunch time (needed to evaluate time differences)
Definition: HcalUnpacker.h:58
bool isEmptyEvent() const
Definition: HcalHTRData.cc:100
bool AMCDataPresent(int i) const
Definition: AMC13Header.h:47
int ieta() const
get the cell ieta
Definition: HcalDetId.h:56
HcalSubdetector
Definition: HcalAssistant.h:31
uint16_t raw() const
get the raw word
int j
Definition: DBlmapReader.cc:9
void unpackVME(const FEDRawData &raw, const HcalElectronicsMap &emap, Collections &conts, HcalUnpackerReport &report, bool silent=false)
double f[11][100]
std::vector< HcalTriggerPrimitiveDigi > * tpCont
Definition: HcalUnpacker.h:31
int fiber() const
get the fiber number
Definition: HcalQIESample.h:32
bool getSpigotPresent(unsigned int nspigot) const
Read the &quot;PRESENT&quot; bit for this spigot.
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
bool getSlotPresent(unsigned int nslot) const
Read the &quot;PRESENT&quot; bit for this slot.
Definition: HcalDTCHeader.h:80
std::set< HcalElectronicsId > unknownIdsTrig_
Recorded to limit number of times a log message is generated.
Definition: HcalUnpacker.h:60
HcalDataFrameContainer< QIE11DataFrame > QIE11DigiCollection
int getSourceId() const
Definition: HcalDCCHeader.h:32
int iphi() const
get the cell iphi
Definition: HcalDetId.cc:124
unsigned int databits
Definition: DetId.h:18
void setHTR(int crate, int slot, int tb)
void unpack(const FEDRawData &raw, const HcalElectronicsMap &emap, std::vector< HcalHistogramDigi > &histoDigis)
static const int SubdetectorId
Definition: HcalZDCDetId.h:25
std::vector< HcalCalibDataFrame > * calibCont
Definition: HcalUnpacker.h:29
static int slb(uint16_t theSample)
unsigned long long uint64_t
Definition: Time.h:15
HcalOtherSubdetector subdet() const
get the category
void dataPointers(const unsigned short **daq_first, const unsigned short **daq_last, const unsigned short **tp_first, const unsigned short **tp_last) const
Obtain the starting and ending pointers for external unpacking of the data.
Definition: HcalHTRData.cc:153
bool unpack(const HcalHTRData &data, HcalTTPDigi &digi)
int sourceId() const
Definition: AMC13Header.h:15
bool null() const
is this a null id ?
Definition: DetId.h:45
std::vector< HODataFrame > * hoCont
Definition: HcalUnpacker.h:27
QIE11DigiCollection * qie11
Definition: HcalUnpacker.h:36
void setbit(int i)
short BOEshouldBeZeroAlways() const
Definition: HcalDCCHeader.h:50
int getNPS() const
Get the number of presamples in daq data.
Definition: HcalHTRData.cc:400
static const HcalTrigTowerDetId Undefined
bool AMCSegmented(int i) const
Definition: AMC13Header.h:41
static const int FORMAT_VERSION_COMPACT_DATA
Definition: HcalHTRData.h:20
int getFirmwareFlavor() const
Get the HTR firmware flavor.
Definition: HcalHTRData.cc:409
int NAMC() const
Definition: AMC13Header.h:25
static const int SPIGOT_COUNT
Definition: HcalDCCHeader.h:19
int AMCSlot(int i) const
Definition: AMC13Header.h:33
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
const uint64_t * AMCPayload(int i) const
Definition: AMC13Header.cc:4
int getSlotData(int nslot, HcalHTRData &decodeTool, int validSize) const
bool wasMarkAndPassZSTP(int slb, int slbchan) const
Was this channel passed as part of Mark&amp;Pass ZS?
Definition: HcalHTRData.cc:364
uint16_t * getArray(int capid)
get the array for the specified capid
uint32_t zsBunchMask() const
ZS Bunch Mask (if available)
Definition: HcalHTRData.cc:373
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:28
QIE10DigiCollection * qie10
Definition: HcalUnpacker.h:34
std::vector< ZDCDataFrame > * zdcCont
Definition: HcalUnpacker.h:30
bool AMCCRCOk(int i) const
Definition: AMC13Header.h:45
const DetId lookupTrigger(HcalElectronicsId fId) const
brief lookup the trigger logical detid associated with the given electronics id
tuple cout
Definition: gather_cfg.py:145
short getDCCDataFormatVersion() const
Definition: HcalDCCHeader.h:57
unsigned int getSubmodule() const
Get the HTR submodule number.
Definition: HcalHTRData.cc:331
bool AMCEnabled(int i) const
Definition: AMC13Header.h:51
bool isBusy() const
Definition: HcalHTRData.cc:117
float linear(float x)
void unpackUMNio(const FEDRawData &raw, int slot, Collections &colls)
uint16_t AMCId(int i) const
Definition: AMC13Header.h:31
Detector det() const
get the detector field from this detid
Definition: DetId.h:35
const uint16_t * raw() const
Definition: HcalUHTRData.h:66
Readout chain identification for Hcal.
const DetId lookup(HcalElectronicsId fId) const
lookup the logical detid associated with the given electronics id
bool isHistogramEvent() const
Is this event a histogram event? (do not call standard unpack in this case!!!!!)
Definition: HcalHTRData.cc:385
static const int MAXIMUM_SLOT
Definition: HcalDTCHeader.h:22
const HcalQIESample * unpack(const HcalQIESample *startPoint, const HcalQIESample *limit, DigiClass &digi, int presamples, const HcalElectronicsId &eid, int startSample, int endSample, int expectedTime, const HcalHTRData &hhd)
Definition: HcalUnpacker.cc:17
bool getSlotCRCError(unsigned int nslot) const
Read the &quot;CRC-Mismatch&quot; bit for this slot.
Definition: HcalDTCHeader.h:84
static int slbChan(uint16_t theSample)