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