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